1/*
2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/export.h>
18#include "hw.h"
19#include "ar9003_phy.h"
20#include "ar9003_mci.h"
21
22static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah)
23{
24	if (!AR_SREV_9462_20(ah))
25		return;
26
27	REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
28		      AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);
29	udelay(1);
30	REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
31		      AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0);
32}
33
34static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address,
35					u32 bit_position, int time_out)
36{
37	struct ath_common *common = ath9k_hw_common(ah);
38
39	while (time_out) {
40
41		if (REG_READ(ah, address) & bit_position) {
42
43			REG_WRITE(ah, address, bit_position);
44
45			if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) {
46
47				if (bit_position &
48				    AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
49					ar9003_mci_reset_req_wakeup(ah);
50
51				if (bit_position &
52				    (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING |
53				     AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING))
54					REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
55					AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
56
57				REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
58					  AR_MCI_INTERRUPT_RX_MSG);
59			}
60			break;
61		}
62
63		udelay(10);
64		time_out -= 10;
65
66		if (time_out < 0)
67			break;
68	}
69
70	if (time_out <= 0) {
71		ath_dbg(common, MCI,
72			"MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
73			address, bit_position);
74		ath_dbg(common, MCI,
75			"MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",
76			REG_READ(ah, AR_MCI_INTERRUPT_RAW),
77			REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
78		time_out = 0;
79	}
80
81	return time_out;
82}
83
84void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done)
85{
86	u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
87
88	if (!ATH9K_HW_CAP_MCI)
89		return;
90
91	ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
92				wait_done, false);
93	udelay(5);
94}
95
96void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done)
97{
98	u32 payload = 0x00000000;
99
100	if (!ATH9K_HW_CAP_MCI)
101		return;
102
103	ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
104				wait_done, false);
105}
106
107static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done)
108{
109	ar9003_mci_send_message(ah, MCI_REQ_WAKE, MCI_FLAG_DISABLE_TIMESTAMP,
110				NULL, 0, wait_done, false);
111	udelay(5);
112}
113
114void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
115{
116	if (!ATH9K_HW_CAP_MCI)
117		return;
118
119	ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP,
120				NULL, 0, wait_done, false);
121}
122
123static void ar9003_mci_send_lna_take(struct ath_hw *ah, bool wait_done)
124{
125	u32 payload = 0x70000000;
126
127	ar9003_mci_send_message(ah, MCI_LNA_TAKE, 0, &payload, 1,
128				wait_done, false);
129}
130
131static void ar9003_mci_send_sys_sleeping(struct ath_hw *ah, bool wait_done)
132{
133	ar9003_mci_send_message(ah, MCI_SYS_SLEEPING,
134				MCI_FLAG_DISABLE_TIMESTAMP,
135				NULL, 0, wait_done, false);
136}
137
138static void ar9003_mci_send_coex_version_query(struct ath_hw *ah,
139					       bool wait_done)
140{
141	struct ath_common *common = ath9k_hw_common(ah);
142	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
143	u32 payload[4] = {0, 0, 0, 0};
144
145	if (!mci->bt_version_known &&
146			(mci->bt_state != MCI_BT_SLEEP)) {
147		ath_dbg(common, MCI, "MCI Send Coex version query\n");
148		MCI_GPM_SET_TYPE_OPCODE(payload,
149				MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY);
150		ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
151				wait_done, true);
152	}
153}
154
155static void ar9003_mci_send_coex_version_response(struct ath_hw *ah,
156						     bool wait_done)
157{
158	struct ath_common *common = ath9k_hw_common(ah);
159	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
160	u32 payload[4] = {0, 0, 0, 0};
161
162	ath_dbg(common, MCI, "MCI Send Coex version response\n");
163	MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
164			MCI_GPM_COEX_VERSION_RESPONSE);
165	*(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =
166		mci->wlan_ver_major;
167	*(((u8 *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =
168		mci->wlan_ver_minor;
169	ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
170}
171
172static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah,
173						  bool wait_done)
174{
175	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
176	u32 *payload = &mci->wlan_channels[0];
177
178	if ((mci->wlan_channels_update == true) &&
179			(mci->bt_state != MCI_BT_SLEEP)) {
180		MCI_GPM_SET_TYPE_OPCODE(payload,
181		MCI_GPM_COEX_AGENT, MCI_GPM_COEX_WLAN_CHANNELS);
182		ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
183					wait_done, true);
184		MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);
185	}
186}
187
188static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
189						bool wait_done, u8 query_type)
190{
191	struct ath_common *common = ath9k_hw_common(ah);
192	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
193	u32 payload[4] = {0, 0, 0, 0};
194	bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO |
195					     MCI_GPM_COEX_QUERY_BT_TOPOLOGY));
196
197	if (mci->bt_state != MCI_BT_SLEEP) {
198
199		ath_dbg(common, MCI, "MCI Send Coex BT Status Query 0x%02X\n",
200			query_type);
201
202		MCI_GPM_SET_TYPE_OPCODE(payload,
203				MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY);
204
205		*(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;
206		/*
207		 * If bt_status_query message is  not sent successfully,
208		 * then need_flush_btinfo should be set again.
209		 */
210		if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
211					     wait_done, true)) {
212			if (query_btinfo) {
213				mci->need_flush_btinfo = true;
214
215				ath_dbg(common, MCI,
216					"MCI send bt_status_query fail, set flush flag again\n");
217			}
218		}
219
220		if (query_btinfo)
221			mci->query_bt = false;
222	}
223}
224
225void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
226				      bool wait_done)
227{
228	struct ath_common *common = ath9k_hw_common(ah);
229	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
230	u32 payload[4] = {0, 0, 0, 0};
231
232	if (!ATH9K_HW_CAP_MCI)
233		return;
234
235	ath_dbg(common, MCI, "MCI Send Coex %s BT GPM\n",
236		(halt) ? "halt" : "unhalt");
237
238	MCI_GPM_SET_TYPE_OPCODE(payload,
239				MCI_GPM_COEX_AGENT, MCI_GPM_COEX_HALT_BT_GPM);
240
241	if (halt) {
242		mci->query_bt = true;
243		/* Send next unhalt no matter halt sent or not */
244		mci->unhalt_bt_gpm = true;
245		mci->need_flush_btinfo = true;
246		*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
247			MCI_GPM_COEX_BT_GPM_HALT;
248	} else
249		*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
250			MCI_GPM_COEX_BT_GPM_UNHALT;
251
252	ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
253}
254
255
256static void ar9003_mci_prep_interface(struct ath_hw *ah)
257{
258	struct ath_common *common = ath9k_hw_common(ah);
259	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
260	u32 saved_mci_int_en;
261	u32 mci_timeout = 150;
262
263	mci->bt_state = MCI_BT_SLEEP;
264	saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
265
266	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
267	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
268		  REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
269	REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
270		  REG_READ(ah, AR_MCI_INTERRUPT_RAW));
271
272	/* Remote Reset */
273	ath_dbg(common, MCI, "MCI Reset sequence start\n");
274	ath_dbg(common, MCI, "MCI send REMOTE_RESET\n");
275	ar9003_mci_remote_reset(ah, true);
276
277	/*
278	 * This delay is required for the reset delay worst case value 255 in
279	 * MCI_COMMAND2 register
280	 */
281
282	if (AR_SREV_9462_10(ah))
283		udelay(252);
284
285	ath_dbg(common, MCI, "MCI Send REQ_WAKE to remoter(BT)\n");
286	ar9003_mci_send_req_wake(ah, true);
287
288	if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
289				AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) {
290
291		ath_dbg(common, MCI, "MCI SYS_WAKING from remote(BT)\n");
292		mci->bt_state = MCI_BT_AWAKE;
293
294		if (AR_SREV_9462_10(ah))
295			udelay(10);
296		/*
297		 * we don't need to send more remote_reset at this moment.
298		 * If BT receive first remote_reset, then BT HW will
299		 * be cleaned up and will be able to receive req_wake
300		 * and BT HW will respond sys_waking.
301		 * In this case, WLAN will receive BT's HW sys_waking.
302		 * Otherwise, if BT SW missed initial remote_reset,
303		 * that remote_reset will still clean up BT MCI RX,
304		 * and the req_wake will wake BT up,
305		 * and BT SW will respond this req_wake with a remote_reset and
306		 * sys_waking. In this case, WLAN will receive BT's SW
307		 * sys_waking. In either case, BT's RX is cleaned up. So we
308		 * don't need to reply BT's remote_reset now, if any.
309		 * Similarly, if in any case, WLAN can receive BT's sys_waking,
310		 * that means WLAN's RX is also fine.
311		 */
312
313		/* Send SYS_WAKING to BT */
314
315		ath_dbg(common, MCI, "MCI send SW SYS_WAKING to remote BT\n");
316
317		ar9003_mci_send_sys_waking(ah, true);
318		udelay(10);
319
320		/*
321		 * Set BT priority interrupt value to be 0xff to
322		 * avoid having too many BT PRIORITY interrupts.
323		 */
324
325		REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);
326		REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);
327		REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);
328		REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF);
329		REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF);
330
331		/*
332		 * A contention reset will be received after send out
333		 * sys_waking. Also BT priority interrupt bits will be set.
334		 * Clear those bits before the next step.
335		 */
336
337		REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
338			  AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
339		REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
340			  AR_MCI_INTERRUPT_BT_PRI);
341
342		if (AR_SREV_9462_10(ah) || mci->is_2g) {
343			/* Send LNA_TRANS */
344			ath_dbg(common, MCI, "MCI send LNA_TRANS to BT\n");
345			ar9003_mci_send_lna_transfer(ah, true);
346			udelay(5);
347		}
348
349		if (AR_SREV_9462_10(ah) || (mci->is_2g &&
350					    !mci->update_2g5g)) {
351			if (ar9003_mci_wait_for_interrupt(ah,
352				AR_MCI_INTERRUPT_RX_MSG_RAW,
353				AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
354				mci_timeout))
355				ath_dbg(common, MCI,
356					"MCI WLAN has control over the LNA & BT obeys it\n");
357			else
358				ath_dbg(common, MCI,
359					"MCI BT didn't respond to LNA_TRANS\n");
360		}
361
362		if (AR_SREV_9462_10(ah)) {
363			/* Send another remote_reset to deassert BT clk_req. */
364			ath_dbg(common, MCI,
365				"MCI another remote_reset to deassert clk_req\n");
366			ar9003_mci_remote_reset(ah, true);
367			udelay(252);
368		}
369	}
370
371	/* Clear the extra redundant SYS_WAKING from BT */
372	if ((mci->bt_state == MCI_BT_AWAKE) &&
373		(REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
374				AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&
375		(REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
376				AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) {
377
378			REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
379				  AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
380			REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
381				  AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
382	}
383
384	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
385}
386
387void ar9003_mci_disable_interrupt(struct ath_hw *ah)
388{
389	if (!ATH9K_HW_CAP_MCI)
390		return;
391
392	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
393	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
394}
395
396void ar9003_mci_enable_interrupt(struct ath_hw *ah)
397{
398	if (!ATH9K_HW_CAP_MCI)
399		return;
400
401	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
402	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
403		  AR_MCI_INTERRUPT_RX_MSG_DEFAULT);
404}
405
406bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints)
407{
408	u32 intr;
409
410	if (!ATH9K_HW_CAP_MCI)
411		return false;
412
413	intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
414	return ((intr & ints) == ints);
415}
416
417void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
418			      u32 *rx_msg_intr)
419{
420	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
421
422	if (!ATH9K_HW_CAP_MCI)
423		return;
424
425	*raw_intr = mci->raw_intr;
426	*rx_msg_intr = mci->rx_msg_intr;
427
428	/* Clean int bits after the values are read. */
429	mci->raw_intr = 0;
430	mci->rx_msg_intr = 0;
431}
432EXPORT_SYMBOL(ar9003_mci_get_interrupt);
433
434void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
435{
436	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
437
438	if (!ATH9K_HW_CAP_MCI)
439		return;
440
441	if (!mci->update_2g5g &&
442	    (mci->is_2g != is_2g))
443		mci->update_2g5g = true;
444
445	mci->is_2g = is_2g;
446}
447
448static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
449{
450	struct ath_common *common = ath9k_hw_common(ah);
451	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
452	u32 *payload;
453	u32 recv_type, offset;
454
455	if (msg_index == MCI_GPM_INVALID)
456		return false;
457
458	offset = msg_index << 4;
459
460	payload = (u32 *)(mci->gpm_buf + offset);
461	recv_type = MCI_GPM_TYPE(payload);
462
463	if (recv_type == MCI_GPM_RSVD_PATTERN) {
464		ath_dbg(common, MCI, "MCI Skip RSVD GPM\n");
465		return false;
466	}
467
468	return true;
469}
470
471static void ar9003_mci_observation_set_up(struct ath_hw *ah)
472{
473	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
474	if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
475
476		ath9k_hw_cfg_output(ah, 3,
477					AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
478		ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
479		ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
480		ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
481
482	} else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) {
483
484		ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
485		ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
486		ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
487		ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
488		ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
489
490	} else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) {
491
492		ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
493		ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
494		ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
495		ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
496
497	} else
498		return;
499
500	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
501
502	if (AR_SREV_9462_20_OR_LATER(ah)) {
503		REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
504			      AR_GLB_DS_JTAG_DISABLE, 1);
505		REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
506			      AR_GLB_WLAN_UART_INTF_EN, 0);
507		REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL,
508			    ATH_MCI_CONFIG_MCI_OBS_GPIO);
509	}
510
511	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);
512	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);
513	REG_WRITE(ah, AR_OBS, 0x4b);
514	REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03);
515	REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01);
516	REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02);
517	REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03);
518	REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS,
519		      AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07);
520}
521
522static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
523						u8 opcode, u32 bt_flags)
524{
525	struct ath_common *common = ath9k_hw_common(ah);
526	u32 pld[4] = {0, 0, 0, 0};
527
528	MCI_GPM_SET_TYPE_OPCODE(pld,
529			MCI_GPM_COEX_AGENT, MCI_GPM_COEX_BT_UPDATE_FLAGS);
530
531	*(((u8 *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP)  = opcode;
532	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;
533	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) = (bt_flags >> 8) & 0xFF;
534	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF;
535	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF;
536
537	ath_dbg(common, MCI,
538		"MCI BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n",
539		opcode == MCI_GPM_COEX_BT_FLAGS_READ ? "READ" :
540		opcode == MCI_GPM_COEX_BT_FLAGS_SET ? "SET" : "CLEAR",
541		bt_flags);
542
543	return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16,
544							wait_done, true);
545}
546
547void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
548		      bool is_full_sleep)
549{
550	struct ath_common *common = ath9k_hw_common(ah);
551	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
552	u32 regval, thresh;
553
554	if (!ATH9K_HW_CAP_MCI)
555		return;
556
557	ath_dbg(common, MCI, "MCI full_sleep = %d, is_2g = %d\n",
558		is_full_sleep, is_2g);
559
560	/*
561	 * GPM buffer and scheduling message buffer are not allocated
562	 */
563
564	if (!mci->gpm_addr && !mci->sched_addr) {
565		ath_dbg(common, MCI,
566			"MCI GPM and schedule buffers are not allocated\n");
567		return;
568	}
569
570	if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
571		ath_dbg(common, MCI, "MCI it's deadbeef, quit mci_reset\n");
572		return;
573	}
574
575	/* Program MCI DMA related registers */
576	REG_WRITE(ah, AR_MCI_GPM_0, mci->gpm_addr);
577	REG_WRITE(ah, AR_MCI_GPM_1, mci->gpm_len);
578	REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, mci->sched_addr);
579
580	/*
581	* To avoid MCI state machine be affected by incoming remote MCI msgs,
582	* MCI mode will be enabled later, right before reset the MCI TX and RX.
583	*/
584
585	regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
586		 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
587		 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
588		 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
589		 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
590		 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
591		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
592		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
593		 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
594
595	if (is_2g && (AR_SREV_9462_20(ah)) &&
596		!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) {
597
598		regval |= SM(1, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
599		ath_dbg(common, MCI, "MCI sched one step look ahead\n");
600
601		if (!(mci->config &
602		      ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) {
603
604			thresh = MS(mci->config,
605				    ATH_MCI_CONFIG_AGGR_THRESH);
606			thresh &= 7;
607			regval |= SM(1,
608				     AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN);
609			regval |= SM(thresh, AR_BTCOEX_CTRL_AGGR_THRESH);
610
611			REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
612				      AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
613			REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
614				      AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);
615
616		} else
617			ath_dbg(common, MCI, "MCI sched aggr thresh: off\n");
618	} else
619		ath_dbg(common, MCI, "MCI SCHED one step look ahead off\n");
620
621	if (AR_SREV_9462_10(ah))
622		regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10);
623
624	REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
625
626	if (AR_SREV_9462_20(ah)) {
627		REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
628			    AR_BTCOEX_CTRL_SPDT_ENABLE);
629		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
630			      AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);
631	}
632
633	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1);
634	REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
635
636	thresh = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV);
637	REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, thresh);
638	REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);
639
640	/* Resetting the Rx and Tx paths of MCI */
641	regval = REG_READ(ah, AR_MCI_COMMAND2);
642	regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
643	REG_WRITE(ah, AR_MCI_COMMAND2, regval);
644
645	udelay(1);
646
647	regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
648	REG_WRITE(ah, AR_MCI_COMMAND2, regval);
649
650	if (is_full_sleep) {
651		ar9003_mci_mute_bt(ah);
652		udelay(100);
653	}
654
655	regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
656	REG_WRITE(ah, AR_MCI_COMMAND2, regval);
657	udelay(1);
658	regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
659	REG_WRITE(ah, AR_MCI_COMMAND2, regval);
660
661	ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
662	REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
663		  (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
664		   SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
665
666	REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
667			AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
668
669	if (AR_SREV_9462_20_OR_LATER(ah))
670		ar9003_mci_observation_set_up(ah);
671
672	mci->ready = true;
673	ar9003_mci_prep_interface(ah);
674
675	if (en_int)
676		ar9003_mci_enable_interrupt(ah);
677}
678
679void ar9003_mci_mute_bt(struct ath_hw *ah)
680{
681	struct ath_common *common = ath9k_hw_common(ah);
682
683	if (!ATH9K_HW_CAP_MCI)
684		return;
685
686	/* disable all MCI messages */
687	REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
688	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
689	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
690	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
691	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
692	REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
693
694	/* wait pending HW messages to flush out */
695	udelay(10);
696
697	/*
698	 * Send LNA_TAKE and SYS_SLEEPING when
699	 * 1. reset not after resuming from full sleep
700	 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
701	 */
702
703	ath_dbg(common, MCI, "MCI Send LNA take\n");
704	ar9003_mci_send_lna_take(ah, true);
705
706	udelay(5);
707
708	ath_dbg(common, MCI, "MCI Send sys sleeping\n");
709	ar9003_mci_send_sys_sleeping(ah, true);
710}
711
712void ar9003_mci_sync_bt_state(struct ath_hw *ah)
713{
714	struct ath_common *common = ath9k_hw_common(ah);
715	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
716	u32 cur_bt_state;
717
718	if (!ATH9K_HW_CAP_MCI)
719		return;
720
721	cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL);
722
723	if (mci->bt_state != cur_bt_state) {
724		ath_dbg(common, MCI,
725			"MCI BT state mismatches. old: %d, new: %d\n",
726			mci->bt_state, cur_bt_state);
727		mci->bt_state = cur_bt_state;
728	}
729
730	if (mci->bt_state != MCI_BT_SLEEP) {
731
732		ar9003_mci_send_coex_version_query(ah, true);
733		ar9003_mci_send_coex_wlan_channels(ah, true);
734
735		if (mci->unhalt_bt_gpm == true) {
736			ath_dbg(common, MCI, "MCI unhalt BT GPM\n");
737			ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
738		}
739	}
740}
741
742static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
743{
744	struct ath_common *common = ath9k_hw_common(ah);
745	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
746	u32 new_flags, to_set, to_clear;
747
748	if (AR_SREV_9462_20(ah) &&
749	    mci->update_2g5g &&
750	    (mci->bt_state != MCI_BT_SLEEP)) {
751
752		if (mci->is_2g) {
753			new_flags = MCI_2G_FLAGS;
754			to_clear = MCI_2G_FLAGS_CLEAR_MASK;
755			to_set = MCI_2G_FLAGS_SET_MASK;
756		} else {
757			new_flags = MCI_5G_FLAGS;
758			to_clear = MCI_5G_FLAGS_CLEAR_MASK;
759			to_set = MCI_5G_FLAGS_SET_MASK;
760		}
761
762		ath_dbg(common, MCI,
763			"MCI BT_MCI_FLAGS: %s 0x%08x clr=0x%08x, set=0x%08x\n",
764		mci->is_2g ? "2G" : "5G", new_flags, to_clear, to_set);
765
766		if (to_clear)
767			ar9003_mci_send_coex_bt_flags(ah, wait_done,
768					MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear);
769
770		if (to_set)
771			ar9003_mci_send_coex_bt_flags(ah, wait_done,
772					MCI_GPM_COEX_BT_FLAGS_SET, to_set);
773	}
774
775	if (AR_SREV_9462_10(ah) && (mci->bt_state != MCI_BT_SLEEP))
776		mci->update_2g5g = false;
777}
778
779static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
780					u32 *payload, bool queue)
781{
782	struct ath_common *common = ath9k_hw_common(ah);
783	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
784	u8 type, opcode;
785
786	if (queue) {
787
788		if (payload)
789			ath_dbg(common, MCI,
790				"MCI ERROR: Send fail: %02x: %02x %02x %02x\n",
791				header,
792				*(((u8 *)payload) + 4),
793				*(((u8 *)payload) + 5),
794				*(((u8 *)payload) + 6));
795		else
796			ath_dbg(common, MCI, "MCI ERROR: Send fail: %02x\n",
797				header);
798	}
799
800	/* check if the message is to be queued */
801	if (header != MCI_GPM)
802		return;
803
804	type = MCI_GPM_TYPE(payload);
805	opcode = MCI_GPM_OPCODE(payload);
806
807	if (type != MCI_GPM_COEX_AGENT)
808		return;
809
810	switch (opcode) {
811	case MCI_GPM_COEX_BT_UPDATE_FLAGS:
812
813		if (AR_SREV_9462_10(ah))
814			break;
815
816		if (*(((u8 *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==
817				MCI_GPM_COEX_BT_FLAGS_READ)
818			break;
819
820		mci->update_2g5g = queue;
821
822		if (queue)
823			ath_dbg(common, MCI,
824				"MCI BT_MCI_FLAGS: 2G5G status <queued> %s\n",
825				mci->is_2g ? "2G" : "5G");
826		else
827			ath_dbg(common, MCI,
828				"MCI BT_MCI_FLAGS: 2G5G status <sent> %s\n",
829				mci->is_2g ? "2G" : "5G");
830
831		break;
832
833	case MCI_GPM_COEX_WLAN_CHANNELS:
834
835		mci->wlan_channels_update = queue;
836		if (queue)
837			ath_dbg(common, MCI, "MCI WLAN channel map <queued>\n");
838		else
839			ath_dbg(common, MCI, "MCI WLAN channel map <sent>\n");
840		break;
841
842	case MCI_GPM_COEX_HALT_BT_GPM:
843
844		if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
845				MCI_GPM_COEX_BT_GPM_UNHALT) {
846
847			mci->unhalt_bt_gpm = queue;
848
849			if (queue)
850				ath_dbg(common, MCI,
851					"MCI UNHALT BT GPM <queued>\n");
852			else {
853				mci->halted_bt_gpm = false;
854				ath_dbg(common, MCI,
855					"MCI UNHALT BT GPM <sent>\n");
856			}
857		}
858
859		if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
860				MCI_GPM_COEX_BT_GPM_HALT) {
861
862			mci->halted_bt_gpm = !queue;
863
864			if (queue)
865				ath_dbg(common, MCI,
866					"MCI HALT BT GPM <not sent>\n");
867			else
868				ath_dbg(common, MCI,
869					"MCI UNHALT BT GPM <sent>\n");
870		}
871
872		break;
873	default:
874		break;
875	}
876}
877
878void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done)
879{
880	struct ath_common *common = ath9k_hw_common(ah);
881	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
882
883	if (!ATH9K_HW_CAP_MCI)
884		return;
885
886	if (mci->update_2g5g) {
887		if (mci->is_2g) {
888
889			ar9003_mci_send_2g5g_status(ah, true);
890			ath_dbg(common, MCI, "MCI Send LNA trans\n");
891			ar9003_mci_send_lna_transfer(ah, true);
892			udelay(5);
893
894			REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
895				    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
896
897			if (AR_SREV_9462_20(ah)) {
898				REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
899					    AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
900				if (!(mci->config &
901				      ATH_MCI_CONFIG_DISABLE_OSLA)) {
902					REG_SET_BIT(ah, AR_BTCOEX_CTRL,
903					AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
904				}
905			}
906		} else {
907			ath_dbg(common, MCI, "MCI Send LNA take\n");
908			ar9003_mci_send_lna_take(ah, true);
909			udelay(5);
910
911			REG_SET_BIT(ah, AR_MCI_TX_CTRL,
912				    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
913
914			if (AR_SREV_9462_20(ah)) {
915				REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
916					    AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
917				REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
918					AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
919			}
920
921			ar9003_mci_send_2g5g_status(ah, true);
922		}
923	}
924}
925
926bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
927			     u32 *payload, u8 len, bool wait_done,
928			     bool check_bt)
929{
930	struct ath_common *common = ath9k_hw_common(ah);
931	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
932	bool msg_sent = false;
933	u32 regval;
934	u32 saved_mci_int_en;
935	int i;
936
937	if (!ATH9K_HW_CAP_MCI)
938		return false;
939
940	saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
941	regval = REG_READ(ah, AR_BTCOEX_CTRL);
942
943	if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {
944
945		ath_dbg(common, MCI,
946			"MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
947			header,
948			(ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0);
949
950		ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
951		return false;
952
953	} else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) {
954
955		ath_dbg(common, MCI,
956			"MCI Don't send message 0x%x. BT is in sleep state\n",
957			header);
958
959		ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
960		return false;
961	}
962
963	if (wait_done)
964		REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
965
966	/* Need to clear SW_MSG_DONE raw bit before wait */
967
968	REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
969		  (AR_MCI_INTERRUPT_SW_MSG_DONE |
970		   AR_MCI_INTERRUPT_MSG_FAIL_MASK));
971
972	if (payload) {
973		for (i = 0; (i * 4) < len; i++)
974			REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i * 4),
975				  *(payload + i));
976	}
977
978	REG_WRITE(ah, AR_MCI_COMMAND0,
979		  (SM((flag & MCI_FLAG_DISABLE_TIMESTAMP),
980		      AR_MCI_COMMAND0_DISABLE_TIMESTAMP) |
981		   SM(len, AR_MCI_COMMAND0_LEN) |
982		   SM(header, AR_MCI_COMMAND0_HEADER)));
983
984	if (wait_done &&
985	    !(ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,
986					AR_MCI_INTERRUPT_SW_MSG_DONE, 500)))
987		ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
988	else {
989		ar9003_mci_queue_unsent_gpm(ah, header, payload, false);
990		msg_sent = true;
991	}
992
993	if (wait_done)
994		REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
995
996	return msg_sent;
997}
998EXPORT_SYMBOL(ar9003_mci_send_message);
999
1000void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
1001		      u16 len, u32 sched_addr)
1002{
1003	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1004	void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr));
1005
1006	if (!ATH9K_HW_CAP_MCI)
1007		return;
1008
1009	mci->gpm_addr = gpm_addr;
1010	mci->gpm_buf = gpm_buf;
1011	mci->gpm_len = len;
1012	mci->sched_addr = sched_addr;
1013	mci->sched_buf = sched_buf;
1014
1015	ar9003_mci_reset(ah, true, true, true);
1016}
1017EXPORT_SYMBOL(ar9003_mci_setup);
1018
1019void ar9003_mci_cleanup(struct ath_hw *ah)
1020{
1021	struct ath_common *common = ath9k_hw_common(ah);
1022
1023	if (!ATH9K_HW_CAP_MCI)
1024		return;
1025
1026	/* Turn off MCI and Jupiter mode. */
1027	REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
1028	ath_dbg(common, MCI, "MCI ar9003_mci_cleanup\n");
1029	ar9003_mci_disable_interrupt(ah);
1030}
1031EXPORT_SYMBOL(ar9003_mci_cleanup);
1032
1033static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type,
1034					 u8 gpm_opcode, u32 *p_gpm)
1035{
1036	struct ath_common *common = ath9k_hw_common(ah);
1037	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1038	u8 *p_data = (u8 *) p_gpm;
1039
1040	if (gpm_type != MCI_GPM_COEX_AGENT)
1041		return;
1042
1043	switch (gpm_opcode) {
1044	case MCI_GPM_COEX_VERSION_QUERY:
1045		ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
1046		ar9003_mci_send_coex_version_response(ah, true);
1047		break;
1048	case MCI_GPM_COEX_VERSION_RESPONSE:
1049		ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
1050		mci->bt_ver_major =
1051			*(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
1052		mci->bt_ver_minor =
1053			*(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
1054		mci->bt_version_known = true;
1055		ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
1056			mci->bt_ver_major, mci->bt_ver_minor);
1057		break;
1058	case MCI_GPM_COEX_STATUS_QUERY:
1059		ath_dbg(common, MCI,
1060			"MCI Recv GPM COEX Status Query = 0x%02X\n",
1061			*(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
1062		mci->wlan_channels_update = true;
1063		ar9003_mci_send_coex_wlan_channels(ah, true);
1064		break;
1065	case MCI_GPM_COEX_BT_PROFILE_INFO:
1066		mci->query_bt = true;
1067		ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n");
1068		break;
1069	case MCI_GPM_COEX_BT_STATUS_UPDATE:
1070		mci->query_bt = true;
1071		ath_dbg(common, MCI,
1072			"MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
1073			*(p_gpm + 3));
1074		break;
1075	default:
1076		break;
1077	}
1078}
1079
1080u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
1081			    u8 gpm_opcode, int time_out)
1082{
1083	struct ath_common *common = ath9k_hw_common(ah);
1084	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1085	u32 *p_gpm = NULL, mismatch = 0, more_data;
1086	u32 offset;
1087	u8 recv_type = 0, recv_opcode = 0;
1088	bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
1089
1090	if (!ATH9K_HW_CAP_MCI)
1091		return 0;
1092
1093	more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;
1094
1095	while (time_out > 0) {
1096		if (p_gpm) {
1097			MCI_GPM_RECYCLE(p_gpm);
1098			p_gpm = NULL;
1099		}
1100
1101		if (more_data != MCI_GPM_MORE)
1102			time_out = ar9003_mci_wait_for_interrupt(ah,
1103					AR_MCI_INTERRUPT_RX_MSG_RAW,
1104					AR_MCI_INTERRUPT_RX_MSG_GPM,
1105					time_out);
1106
1107		if (!time_out)
1108			break;
1109
1110		offset = ar9003_mci_state(ah,
1111				MCI_STATE_NEXT_GPM_OFFSET, &more_data);
1112
1113		if (offset == MCI_GPM_INVALID)
1114			continue;
1115
1116		p_gpm = (u32 *) (mci->gpm_buf + offset);
1117		recv_type = MCI_GPM_TYPE(p_gpm);
1118		recv_opcode = MCI_GPM_OPCODE(p_gpm);
1119
1120		if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
1121
1122			if (recv_type == gpm_type) {
1123
1124				if ((gpm_type == MCI_GPM_BT_CAL_DONE) &&
1125				    !b_is_bt_cal_done) {
1126					gpm_type = MCI_GPM_BT_CAL_GRANT;
1127					ath_dbg(common, MCI,
1128						"MCI Recv BT_CAL_DONE wait BT_CAL_GRANT\n");
1129					continue;
1130				}
1131
1132				break;
1133			}
1134		} else if ((recv_type == gpm_type) &&
1135			   (recv_opcode == gpm_opcode))
1136			break;
1137
1138		/* not expected message */
1139
1140		/*
1141		 * check if it's cal_grant
1142		 *
1143		 * When we're waiting for cal_grant in reset routine,
1144		 * it's possible that BT sends out cal_request at the
1145		 * same time. Since BT's calibration doesn't happen
1146		 * that often, we'll let BT completes calibration then
1147		 * we continue to wait for cal_grant from BT.
1148		 * Orginal: Wait BT_CAL_GRANT.
1149		 * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
1150		 * BT_CAL_DONE -> Wait BT_CAL_GRANT.
1151		 */
1152
1153		if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
1154		    (recv_type == MCI_GPM_BT_CAL_REQ)) {
1155
1156			u32 payload[4] = {0, 0, 0, 0};
1157
1158			gpm_type = MCI_GPM_BT_CAL_DONE;
1159			ath_dbg(common, MCI,
1160				"MCI Rcv BT_CAL_REQ, send WLAN_CAL_GRANT\n");
1161
1162			MCI_GPM_SET_CAL_TYPE(payload,
1163					MCI_GPM_WLAN_CAL_GRANT);
1164
1165			ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
1166						false, false);
1167
1168			ath_dbg(common, MCI, "MCI now wait for BT_CAL_DONE\n");
1169
1170			continue;
1171		} else {
1172			ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n",
1173				*(p_gpm + 1));
1174			mismatch++;
1175			ar9003_mci_process_gpm_extra(ah, recv_type,
1176					recv_opcode, p_gpm);
1177		}
1178	}
1179	if (p_gpm) {
1180		MCI_GPM_RECYCLE(p_gpm);
1181		p_gpm = NULL;
1182	}
1183
1184	if (time_out <= 0) {
1185		time_out = 0;
1186		ath_dbg(common, MCI,
1187			"MCI GPM received timeout, mismatch = %d\n", mismatch);
1188	} else
1189		ath_dbg(common, MCI, "MCI Receive GPM type=0x%x, code=0x%x\n",
1190			gpm_type, gpm_opcode);
1191
1192	while (more_data == MCI_GPM_MORE) {
1193
1194		ath_dbg(common, MCI, "MCI discard remaining GPM\n");
1195		offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
1196					  &more_data);
1197
1198		if (offset == MCI_GPM_INVALID)
1199			break;
1200
1201		p_gpm = (u32 *) (mci->gpm_buf + offset);
1202		recv_type = MCI_GPM_TYPE(p_gpm);
1203		recv_opcode = MCI_GPM_OPCODE(p_gpm);
1204
1205		if (!MCI_GPM_IS_CAL_TYPE(recv_type))
1206			ar9003_mci_process_gpm_extra(ah, recv_type,
1207						     recv_opcode, p_gpm);
1208
1209		MCI_GPM_RECYCLE(p_gpm);
1210	}
1211
1212	return time_out;
1213}
1214
1215u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
1216{
1217	struct ath_common *common = ath9k_hw_common(ah);
1218	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1219	u32 value = 0, more_gpm = 0, gpm_ptr;
1220	u8 query_type;
1221
1222	if (!ATH9K_HW_CAP_MCI)
1223		return 0;
1224
1225	switch (state_type) {
1226	case MCI_STATE_ENABLE:
1227		if (mci->ready) {
1228
1229			value = REG_READ(ah, AR_BTCOEX_CTRL);
1230
1231			if ((value == 0xdeadbeef) || (value == 0xffffffff))
1232				value = 0;
1233		}
1234		value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
1235		break;
1236	case MCI_STATE_INIT_GPM_OFFSET:
1237		value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1238		ath_dbg(common, MCI, "MCI GPM initial WRITE_PTR=%d\n", value);
1239		mci->gpm_idx = value;
1240		break;
1241	case MCI_STATE_NEXT_GPM_OFFSET:
1242	case MCI_STATE_LAST_GPM_OFFSET:
1243		/*
1244		* This could be useful to avoid new GPM message interrupt which
1245		* may lead to spurious interrupt after power sleep, or multiple
1246		* entry of ath_mci_intr().
1247		* Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1248		* alleviate this effect, but clearing GPM RX interrupt bit is
1249		* safe, because whether this is called from hw or driver code
1250		* there must be an interrupt bit set/triggered initially
1251		*/
1252		REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
1253			  AR_MCI_INTERRUPT_RX_MSG_GPM);
1254
1255		gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1256		value = gpm_ptr;
1257
1258		if (value == 0)
1259			value = mci->gpm_len - 1;
1260		else if (value >= mci->gpm_len) {
1261			if (value != 0xFFFF) {
1262				value = 0;
1263				ath_dbg(common, MCI,
1264					"MCI GPM offset out of range\n");
1265			}
1266		} else
1267			value--;
1268
1269		if (value == 0xFFFF) {
1270			value = MCI_GPM_INVALID;
1271			more_gpm = MCI_GPM_NOMORE;
1272			ath_dbg(common, MCI,
1273				"MCI GPM ptr invalid @ptr=%d, offset=%d, more=GPM_NOMORE\n",
1274				gpm_ptr, value);
1275		} else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) {
1276
1277			if (gpm_ptr == mci->gpm_idx) {
1278				value = MCI_GPM_INVALID;
1279				more_gpm = MCI_GPM_NOMORE;
1280
1281				ath_dbg(common, MCI,
1282					"MCI GPM message not available @ptr=%d, @offset=%d, more=GPM_NOMORE\n",
1283					gpm_ptr, value);
1284			} else {
1285				for (;;) {
1286
1287					u32 temp_index;
1288
1289					/* skip reserved GPM if any */
1290
1291					if (value != mci->gpm_idx)
1292						more_gpm = MCI_GPM_MORE;
1293					else
1294						more_gpm = MCI_GPM_NOMORE;
1295
1296					temp_index = mci->gpm_idx;
1297					mci->gpm_idx++;
1298
1299					if (mci->gpm_idx >=
1300					    mci->gpm_len)
1301						mci->gpm_idx = 0;
1302
1303					ath_dbg(common, MCI,
1304						"MCI GPM message got ptr=%d, @offset=%d, more=%d\n",
1305						gpm_ptr, temp_index,
1306						(more_gpm == MCI_GPM_MORE));
1307
1308					if (ar9003_mci_is_gpm_valid(ah,
1309								temp_index)) {
1310						value = temp_index;
1311						break;
1312					}
1313
1314					if (more_gpm == MCI_GPM_NOMORE) {
1315						value = MCI_GPM_INVALID;
1316						break;
1317					}
1318				}
1319			}
1320			if (p_data)
1321				*p_data = more_gpm;
1322			}
1323
1324			if (value != MCI_GPM_INVALID)
1325				value <<= 4;
1326
1327			break;
1328	case MCI_STATE_LAST_SCHD_MSG_OFFSET:
1329		value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
1330				    AR_MCI_RX_LAST_SCHD_MSG_INDEX);
1331		/* Make it in bytes */
1332		value <<= 4;
1333		break;
1334
1335	case MCI_STATE_REMOTE_SLEEP:
1336		value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
1337			   AR_MCI_RX_REMOTE_SLEEP) ?
1338			MCI_BT_SLEEP : MCI_BT_AWAKE;
1339		break;
1340
1341	case MCI_STATE_CONT_RSSI_POWER:
1342		value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER);
1343			break;
1344
1345	case MCI_STATE_CONT_PRIORITY:
1346		value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY);
1347		break;
1348
1349	case MCI_STATE_CONT_TXRX:
1350		value = MS(mci->cont_status, AR_MCI_CONT_TXRX);
1351		break;
1352
1353	case MCI_STATE_BT:
1354		value = mci->bt_state;
1355		break;
1356
1357	case MCI_STATE_SET_BT_SLEEP:
1358		mci->bt_state = MCI_BT_SLEEP;
1359		break;
1360
1361	case MCI_STATE_SET_BT_AWAKE:
1362		mci->bt_state = MCI_BT_AWAKE;
1363		ar9003_mci_send_coex_version_query(ah, true);
1364		ar9003_mci_send_coex_wlan_channels(ah, true);
1365
1366		if (mci->unhalt_bt_gpm) {
1367
1368			ath_dbg(common, MCI, "MCI unhalt BT GPM\n");
1369			ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
1370		}
1371
1372		ar9003_mci_2g5g_switch(ah, true);
1373		break;
1374
1375	case MCI_STATE_SET_BT_CAL_START:
1376		mci->bt_state = MCI_BT_CAL_START;
1377		break;
1378
1379	case MCI_STATE_SET_BT_CAL:
1380		mci->bt_state = MCI_BT_CAL;
1381		break;
1382
1383	case MCI_STATE_RESET_REQ_WAKE:
1384		ar9003_mci_reset_req_wakeup(ah);
1385		mci->update_2g5g = true;
1386
1387		if ((AR_SREV_9462_20_OR_LATER(ah)) &&
1388		    (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK)) {
1389			/* Check if we still have control of the GPIOs */
1390			if ((REG_READ(ah, AR_GLB_GPIO_CONTROL) &
1391				      ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
1392					ATH_MCI_CONFIG_MCI_OBS_GPIO) {
1393
1394				ath_dbg(common, MCI,
1395					"MCI reconfigure observation\n");
1396				ar9003_mci_observation_set_up(ah);
1397			}
1398		}
1399		break;
1400
1401	case MCI_STATE_SEND_WLAN_COEX_VERSION:
1402		ar9003_mci_send_coex_version_response(ah, true);
1403		break;
1404
1405	case MCI_STATE_SET_BT_COEX_VERSION:
1406
1407		if (!p_data)
1408			ath_dbg(common, MCI,
1409				"MCI Set BT Coex version with NULL data!!\n");
1410		else {
1411			mci->bt_ver_major = (*p_data >> 8) & 0xff;
1412			mci->bt_ver_minor = (*p_data) & 0xff;
1413			mci->bt_version_known = true;
1414			ath_dbg(common, MCI, "MCI BT version set: %d.%d\n",
1415				mci->bt_ver_major, mci->bt_ver_minor);
1416		}
1417		break;
1418
1419	case MCI_STATE_SEND_WLAN_CHANNELS:
1420		if (p_data) {
1421			if (((mci->wlan_channels[1] & 0xffff0000) ==
1422			     (*(p_data + 1) & 0xffff0000)) &&
1423			    (mci->wlan_channels[2] == *(p_data + 2)) &&
1424			    (mci->wlan_channels[3] == *(p_data + 3)))
1425				break;
1426
1427			mci->wlan_channels[0] = *p_data++;
1428			mci->wlan_channels[1] = *p_data++;
1429			mci->wlan_channels[2] = *p_data++;
1430			mci->wlan_channels[3] = *p_data++;
1431		}
1432		mci->wlan_channels_update = true;
1433		ar9003_mci_send_coex_wlan_channels(ah, true);
1434		break;
1435
1436	case MCI_STATE_SEND_VERSION_QUERY:
1437		ar9003_mci_send_coex_version_query(ah, true);
1438		break;
1439
1440	case MCI_STATE_SEND_STATUS_QUERY:
1441		query_type = (AR_SREV_9462_10(ah)) ?
1442				MCI_GPM_COEX_QUERY_BT_ALL_INFO :
1443				MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
1444
1445		ar9003_mci_send_coex_bt_status_query(ah, true, query_type);
1446		break;
1447
1448	case MCI_STATE_NEED_FLUSH_BT_INFO:
1449			/*
1450			 * btcoex_hw.mci.unhalt_bt_gpm means whether it's
1451			 * needed to send UNHALT message. It's set whenever
1452			 * there's a request to send HALT message.
1453			 * mci_halted_bt_gpm means whether HALT message is sent
1454			 * out successfully.
1455			 *
1456			 * Checking (mci_unhalt_bt_gpm == false) instead of
1457			 * checking (ah->mci_halted_bt_gpm == false) will make
1458			 * sure currently is in UNHALT-ed mode and BT can
1459			 * respond to status query.
1460			 */
1461			value = (!mci->unhalt_bt_gpm &&
1462				 mci->need_flush_btinfo) ? 1 : 0;
1463			if (p_data)
1464				mci->need_flush_btinfo =
1465					(*p_data != 0) ? true : false;
1466			break;
1467
1468	case MCI_STATE_RECOVER_RX:
1469
1470		ath_dbg(common, MCI, "MCI hw RECOVER_RX\n");
1471		ar9003_mci_prep_interface(ah);
1472		mci->query_bt = true;
1473		mci->need_flush_btinfo = true;
1474		ar9003_mci_send_coex_wlan_channels(ah, true);
1475		ar9003_mci_2g5g_switch(ah, true);
1476		break;
1477
1478	case MCI_STATE_NEED_FTP_STOMP:
1479		value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP);
1480		break;
1481
1482	case MCI_STATE_NEED_TUNING:
1483		value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING);
1484		break;
1485
1486	default:
1487		break;
1488
1489	}
1490
1491	return value;
1492}
1493EXPORT_SYMBOL(ar9003_mci_state);
1494