xref: /linux/drivers/net/wireless/ath/ath9k/ar9003_mci.c (revision b43ab901d671e3e3cad425ea5e9a3c74e266dcdd)
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 
22 static 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 
34 static 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 
84 void 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 
96 void 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 
107 static 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 
114 void 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 
123 static 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 
131 static 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 
138 static 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 
155 static 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 
172 static 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 
188 static 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 
225 void 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 
256 static 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 
387 void 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 
396 void 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 
406 bool 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 
417 void 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 }
432 EXPORT_SYMBOL(ar9003_mci_get_interrupt);
433 
434 void 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 
448 static 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 
471 static 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 
522 static 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 
547 void 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 
679 void 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 
712 void 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 
742 static 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 
779 static 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 
878 void 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 
926 bool 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 }
998 EXPORT_SYMBOL(ar9003_mci_send_message);
999 
1000 void 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 }
1017 EXPORT_SYMBOL(ar9003_mci_setup);
1018 
1019 void 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 }
1031 EXPORT_SYMBOL(ar9003_mci_cleanup);
1032 
1033 static 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 
1080 u32 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 
1215 u32 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 }
1493 EXPORT_SYMBOL(ar9003_mci_state);
1494