2 * Copyright (c) 2008-2011 Atheros Communications Inc.
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.
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.
17 #include <linux/export.h>
19 #include "ar9003_phy.h"
20 #include "ar9003_mci.h"
22 static void ar9003_mci_reset_req_wakeup(struct ath_hw
*ah
)
24 if (!AR_SREV_9462_20(ah
))
27 REG_RMW_FIELD(ah
, AR_MCI_COMMAND2
,
28 AR_MCI_COMMAND2_RESET_REQ_WAKEUP
, 1);
30 REG_RMW_FIELD(ah
, AR_MCI_COMMAND2
,
31 AR_MCI_COMMAND2_RESET_REQ_WAKEUP
, 0);
34 static int ar9003_mci_wait_for_interrupt(struct ath_hw
*ah
, u32 address
,
35 u32 bit_position
, int time_out
)
37 struct ath_common
*common
= ath9k_hw_common(ah
);
41 if (REG_READ(ah
, address
) & bit_position
) {
43 REG_WRITE(ah
, address
, bit_position
);
45 if (address
== AR_MCI_INTERRUPT_RX_MSG_RAW
) {
48 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
)
49 ar9003_mci_reset_req_wakeup(ah
);
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
);
57 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
58 AR_MCI_INTERRUPT_RX_MSG
);
72 "MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
73 address
, bit_position
);
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
));
84 void ar9003_mci_remote_reset(struct ath_hw
*ah
, bool wait_done
)
86 u32 payload
[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
88 if (!ATH9K_HW_CAP_MCI
)
91 ar9003_mci_send_message(ah
, MCI_REMOTE_RESET
, 0, payload
, 16,
96 void ar9003_mci_send_lna_transfer(struct ath_hw
*ah
, bool wait_done
)
98 u32 payload
= 0x00000000;
100 if (!ATH9K_HW_CAP_MCI
)
103 ar9003_mci_send_message(ah
, MCI_LNA_TRANS
, 0, &payload
, 1,
107 static void ar9003_mci_send_req_wake(struct ath_hw
*ah
, bool wait_done
)
109 ar9003_mci_send_message(ah
, MCI_REQ_WAKE
, MCI_FLAG_DISABLE_TIMESTAMP
,
110 NULL
, 0, wait_done
, false);
114 void ar9003_mci_send_sys_waking(struct ath_hw
*ah
, bool wait_done
)
116 if (!ATH9K_HW_CAP_MCI
)
119 ar9003_mci_send_message(ah
, MCI_SYS_WAKING
, MCI_FLAG_DISABLE_TIMESTAMP
,
120 NULL
, 0, wait_done
, false);
123 static void ar9003_mci_send_lna_take(struct ath_hw
*ah
, bool wait_done
)
125 u32 payload
= 0x70000000;
127 ar9003_mci_send_message(ah
, MCI_LNA_TAKE
, 0, &payload
, 1,
131 static void ar9003_mci_send_sys_sleeping(struct ath_hw
*ah
, bool wait_done
)
133 ar9003_mci_send_message(ah
, MCI_SYS_SLEEPING
,
134 MCI_FLAG_DISABLE_TIMESTAMP
,
135 NULL
, 0, wait_done
, false);
138 static void ar9003_mci_send_coex_version_query(struct ath_hw
*ah
,
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};
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,
155 static void ar9003_mci_send_coex_version_response(struct ath_hw
*ah
,
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};
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
) =
167 *(((u8
*)payload
) + MCI_GPM_COEX_B_MINOR_VERSION
) =
169 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
172 static void ar9003_mci_send_coex_wlan_channels(struct ath_hw
*ah
,
175 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
176 u32
*payload
= &mci
->wlan_channels
[0];
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,
184 MCI_GPM_SET_TYPE_OPCODE(payload
, 0xff, 0xff);
188 static void ar9003_mci_send_coex_bt_status_query(struct ath_hw
*ah
,
189 bool wait_done
, u8 query_type
)
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
));
197 if (mci
->bt_state
!= MCI_BT_SLEEP
) {
199 ath_dbg(common
, MCI
, "MCI Send Coex BT Status Query 0x%02X\n",
202 MCI_GPM_SET_TYPE_OPCODE(payload
,
203 MCI_GPM_COEX_AGENT
, MCI_GPM_COEX_STATUS_QUERY
);
205 *(((u8
*)payload
) + MCI_GPM_COEX_B_BT_BITMAP
) = query_type
;
207 * If bt_status_query message is not sent successfully,
208 * then need_flush_btinfo should be set again.
210 if (!ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
213 mci
->need_flush_btinfo
= true;
216 "MCI send bt_status_query fail, set flush flag again\n");
221 mci
->query_bt
= false;
225 void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw
*ah
, bool halt
,
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};
232 if (!ATH9K_HW_CAP_MCI
)
235 ath_dbg(common
, MCI
, "MCI Send Coex %s BT GPM\n",
236 (halt
) ? "halt" : "unhalt");
238 MCI_GPM_SET_TYPE_OPCODE(payload
,
239 MCI_GPM_COEX_AGENT
, MCI_GPM_COEX_HALT_BT_GPM
);
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
;
249 *(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) =
250 MCI_GPM_COEX_BT_GPM_UNHALT
;
252 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
256 static void ar9003_mci_prep_interface(struct ath_hw
*ah
)
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;
263 mci
->bt_state
= MCI_BT_SLEEP
;
264 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
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
));
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);
278 * This delay is required for the reset delay worst case value 255 in
279 * MCI_COMMAND2 register
282 if (AR_SREV_9462_10(ah
))
285 ath_dbg(common
, MCI
, "MCI Send REQ_WAKE to remoter(BT)\n");
286 ar9003_mci_send_req_wake(ah
, true);
288 if (ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
289 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
, 500)) {
291 ath_dbg(common
, MCI
, "MCI SYS_WAKING from remote(BT)\n");
292 mci
->bt_state
= MCI_BT_AWAKE
;
294 if (AR_SREV_9462_10(ah
))
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.
313 /* Send SYS_WAKING to BT */
315 ath_dbg(common
, MCI
, "MCI send SW SYS_WAKING to remote BT\n");
317 ar9003_mci_send_sys_waking(ah
, true);
321 * Set BT priority interrupt value to be 0xff to
322 * avoid having too many BT PRIORITY interrupts.
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);
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.
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
);
342 if (AR_SREV_9462_10(ah
) || mci
->is_2g
) {
344 ath_dbg(common
, MCI
, "MCI send LNA_TRANS to BT\n");
345 ar9003_mci_send_lna_transfer(ah
, true);
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
,
356 "MCI WLAN has control over the LNA & BT obeys it\n");
359 "MCI BT didn't respond to LNA_TRANS\n");
362 if (AR_SREV_9462_10(ah
)) {
363 /* Send another remote_reset to deassert BT clk_req. */
365 "MCI another remote_reset to deassert clk_req\n");
366 ar9003_mci_remote_reset(ah
, true);
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)) {
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
);
384 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
387 void ar9003_mci_disable_interrupt(struct ath_hw
*ah
)
389 if (!ATH9K_HW_CAP_MCI
)
392 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
393 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_EN
, 0);
396 void ar9003_mci_enable_interrupt(struct ath_hw
*ah
)
398 if (!ATH9K_HW_CAP_MCI
)
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
);
406 bool ar9003_mci_check_int(struct ath_hw
*ah
, u32 ints
)
410 if (!ATH9K_HW_CAP_MCI
)
413 intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
);
414 return ((intr
& ints
) == ints
);
417 void ar9003_mci_get_interrupt(struct ath_hw
*ah
, u32
*raw_intr
,
420 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
422 if (!ATH9K_HW_CAP_MCI
)
425 *raw_intr
= mci
->raw_intr
;
426 *rx_msg_intr
= mci
->rx_msg_intr
;
428 /* Clean int bits after the values are read. */
430 mci
->rx_msg_intr
= 0;
432 EXPORT_SYMBOL(ar9003_mci_get_interrupt
);
434 void ar9003_mci_2g5g_changed(struct ath_hw
*ah
, bool is_2g
)
436 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
438 if (!ATH9K_HW_CAP_MCI
)
441 if (!mci
->update_2g5g
&&
442 (mci
->is_2g
!= is_2g
))
443 mci
->update_2g5g
= true;
448 static bool ar9003_mci_is_gpm_valid(struct ath_hw
*ah
, u32 msg_index
)
450 struct ath_common
*common
= ath9k_hw_common(ah
);
451 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
453 u32 recv_type
, offset
;
455 if (msg_index
== MCI_GPM_INVALID
)
458 offset
= msg_index
<< 4;
460 payload
= (u32
*)(mci
->gpm_buf
+ offset
);
461 recv_type
= MCI_GPM_TYPE(payload
);
463 if (recv_type
== MCI_GPM_RSVD_PATTERN
) {
464 ath_dbg(common
, MCI
, "MCI Skip RSVD GPM\n");
471 static void ar9003_mci_observation_set_up(struct ath_hw
*ah
)
473 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
474 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MCI
) {
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
);
482 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_TXRX
) {
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
);
490 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_BT
) {
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
);
500 REG_SET_BIT(ah
, AR_GPIO_INPUT_EN_VAL
, AR_GPIO_JTAG_DISABLE
);
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
);
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);
522 static bool ar9003_mci_send_coex_bt_flags(struct ath_hw
*ah
, bool wait_done
,
523 u8 opcode
, u32 bt_flags
)
525 struct ath_common
*common
= ath9k_hw_common(ah
);
526 u32 pld
[4] = {0, 0, 0, 0};
528 MCI_GPM_SET_TYPE_OPCODE(pld
,
529 MCI_GPM_COEX_AGENT
, MCI_GPM_COEX_BT_UPDATE_FLAGS
);
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;
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",
543 return ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16,
547 void ar9003_mci_reset(struct ath_hw
*ah
, bool en_int
, bool is_2g
,
550 struct ath_common
*common
= ath9k_hw_common(ah
);
551 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
554 if (!ATH9K_HW_CAP_MCI
)
557 ath_dbg(common
, MCI
, "MCI full_sleep = %d, is_2g = %d\n",
558 is_full_sleep
, is_2g
);
561 * GPM buffer and scheduling message buffer are not allocated
564 if (!mci
->gpm_addr
&& !mci
->sched_addr
) {
566 "MCI GPM and schedule buffers are not allocated\n");
570 if (REG_READ(ah
, AR_BTCOEX_CTRL
) == 0xdeadbeef) {
571 ath_dbg(common
, MCI
, "MCI it's deadbeef, quit mci_reset\n");
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
);
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.
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
);
595 if (is_2g
&& (AR_SREV_9462_20(ah
)) &&
596 !(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
)) {
598 regval
|= SM(1, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
599 ath_dbg(common
, MCI
, "MCI sched one step look ahead\n");
602 ATH_MCI_CONFIG_DISABLE_AGGR_THRESH
)) {
604 thresh
= MS(mci
->config
,
605 ATH_MCI_CONFIG_AGGR_THRESH
);
608 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
);
609 regval
|= SM(thresh
, AR_BTCOEX_CTRL_AGGR_THRESH
);
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);
617 ath_dbg(common
, MCI
, "MCI sched aggr thresh: off\n");
619 ath_dbg(common
, MCI
, "MCI SCHED one step look ahead off\n");
621 if (AR_SREV_9462_10(ah
))
622 regval
|= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10
);
624 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
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);
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);
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
);
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
);
647 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_TX
);
648 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
651 ar9003_mci_mute_bt(ah
);
655 regval
|= SM(1, AR_MCI_COMMAND2_RESET_RX
);
656 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
658 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_RX
);
659 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
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
)));
666 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
667 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
669 if (AR_SREV_9462_20_OR_LATER(ah
))
670 ar9003_mci_observation_set_up(ah
);
673 ar9003_mci_prep_interface(ah
);
676 ar9003_mci_enable_interrupt(ah
);
679 void ar9003_mci_mute_bt(struct ath_hw
*ah
)
681 struct ath_common
*common
= ath9k_hw_common(ah
);
683 if (!ATH9K_HW_CAP_MCI
)
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
);
694 /* wait pending HW messages to flush out */
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
703 ath_dbg(common
, MCI
, "MCI Send LNA take\n");
704 ar9003_mci_send_lna_take(ah
, true);
708 ath_dbg(common
, MCI
, "MCI Send sys sleeping\n");
709 ar9003_mci_send_sys_sleeping(ah
, true);
712 void ar9003_mci_sync_bt_state(struct ath_hw
*ah
)
714 struct ath_common
*common
= ath9k_hw_common(ah
);
715 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
718 if (!ATH9K_HW_CAP_MCI
)
721 cur_bt_state
= ar9003_mci_state(ah
, MCI_STATE_REMOTE_SLEEP
, NULL
);
723 if (mci
->bt_state
!= cur_bt_state
) {
725 "MCI BT state mismatches. old: %d, new: %d\n",
726 mci
->bt_state
, cur_bt_state
);
727 mci
->bt_state
= cur_bt_state
;
730 if (mci
->bt_state
!= MCI_BT_SLEEP
) {
732 ar9003_mci_send_coex_version_query(ah
, true);
733 ar9003_mci_send_coex_wlan_channels(ah
, true);
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);
742 static void ar9003_mci_send_2g5g_status(struct ath_hw
*ah
, bool wait_done
)
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
;
748 if (AR_SREV_9462_20(ah
) &&
750 (mci
->bt_state
!= MCI_BT_SLEEP
)) {
753 new_flags
= MCI_2G_FLAGS
;
754 to_clear
= MCI_2G_FLAGS_CLEAR_MASK
;
755 to_set
= MCI_2G_FLAGS_SET_MASK
;
757 new_flags
= MCI_5G_FLAGS
;
758 to_clear
= MCI_5G_FLAGS_CLEAR_MASK
;
759 to_set
= MCI_5G_FLAGS_SET_MASK
;
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
);
767 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
768 MCI_GPM_COEX_BT_FLAGS_CLEAR
, to_clear
);
771 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
772 MCI_GPM_COEX_BT_FLAGS_SET
, to_set
);
775 if (AR_SREV_9462_10(ah
) && (mci
->bt_state
!= MCI_BT_SLEEP
))
776 mci
->update_2g5g
= false;
779 static void ar9003_mci_queue_unsent_gpm(struct ath_hw
*ah
, u8 header
,
780 u32
*payload
, bool queue
)
782 struct ath_common
*common
= ath9k_hw_common(ah
);
783 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
790 "MCI ERROR: Send fail: %02x: %02x %02x %02x\n",
792 *(((u8
*)payload
) + 4),
793 *(((u8
*)payload
) + 5),
794 *(((u8
*)payload
) + 6));
796 ath_dbg(common
, MCI
, "MCI ERROR: Send fail: %02x\n",
800 /* check if the message is to be queued */
801 if (header
!= MCI_GPM
)
804 type
= MCI_GPM_TYPE(payload
);
805 opcode
= MCI_GPM_OPCODE(payload
);
807 if (type
!= MCI_GPM_COEX_AGENT
)
811 case MCI_GPM_COEX_BT_UPDATE_FLAGS
:
813 if (AR_SREV_9462_10(ah
))
816 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) ==
817 MCI_GPM_COEX_BT_FLAGS_READ
)
820 mci
->update_2g5g
= queue
;
824 "MCI BT_MCI_FLAGS: 2G5G status <queued> %s\n",
825 mci
->is_2g
? "2G" : "5G");
828 "MCI BT_MCI_FLAGS: 2G5G status <sent> %s\n",
829 mci
->is_2g
? "2G" : "5G");
833 case MCI_GPM_COEX_WLAN_CHANNELS
:
835 mci
->wlan_channels_update
= queue
;
837 ath_dbg(common
, MCI
, "MCI WLAN channel map <queued>\n");
839 ath_dbg(common
, MCI
, "MCI WLAN channel map <sent>\n");
842 case MCI_GPM_COEX_HALT_BT_GPM
:
844 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
845 MCI_GPM_COEX_BT_GPM_UNHALT
) {
847 mci
->unhalt_bt_gpm
= queue
;
851 "MCI UNHALT BT GPM <queued>\n");
853 mci
->halted_bt_gpm
= false;
855 "MCI UNHALT BT GPM <sent>\n");
859 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
860 MCI_GPM_COEX_BT_GPM_HALT
) {
862 mci
->halted_bt_gpm
= !queue
;
866 "MCI HALT BT GPM <not sent>\n");
869 "MCI UNHALT BT GPM <sent>\n");
878 void ar9003_mci_2g5g_switch(struct ath_hw
*ah
, bool wait_done
)
880 struct ath_common
*common
= ath9k_hw_common(ah
);
881 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
883 if (!ATH9K_HW_CAP_MCI
)
886 if (mci
->update_2g5g
) {
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);
894 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
895 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
897 if (AR_SREV_9462_20(ah
)) {
898 REG_CLR_BIT(ah
, AR_PHY_GLB_CONTROL
,
899 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
901 ATH_MCI_CONFIG_DISABLE_OSLA
)) {
902 REG_SET_BIT(ah
, AR_BTCOEX_CTRL
,
903 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
907 ath_dbg(common
, MCI
, "MCI Send LNA take\n");
908 ar9003_mci_send_lna_take(ah
, true);
911 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
912 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
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
);
921 ar9003_mci_send_2g5g_status(ah
, true);
926 bool ar9003_mci_send_message(struct ath_hw
*ah
, u8 header
, u32 flag
,
927 u32
*payload
, u8 len
, bool wait_done
,
930 struct ath_common
*common
= ath9k_hw_common(ah
);
931 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
932 bool msg_sent
= false;
934 u32 saved_mci_int_en
;
937 if (!ATH9K_HW_CAP_MCI
)
940 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
941 regval
= REG_READ(ah
, AR_BTCOEX_CTRL
);
943 if ((regval
== 0xdeadbeef) || !(regval
& AR_BTCOEX_CTRL_MCI_MODE_EN
)) {
946 "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
948 (ah
->power_mode
== ATH9K_PM_FULL_SLEEP
) ? 1 : 0);
950 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
953 } else if (check_bt
&& (mci
->bt_state
== MCI_BT_SLEEP
)) {
956 "MCI Don't send message 0x%x. BT is in sleep state\n",
959 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
964 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
966 /* Need to clear SW_MSG_DONE raw bit before wait */
968 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
969 (AR_MCI_INTERRUPT_SW_MSG_DONE
|
970 AR_MCI_INTERRUPT_MSG_FAIL_MASK
));
973 for (i
= 0; (i
* 4) < len
; i
++)
974 REG_WRITE(ah
, (AR_MCI_TX_PAYLOAD0
+ i
* 4),
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
)));
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);
989 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, false);
994 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
998 EXPORT_SYMBOL(ar9003_mci_send_message
);
1000 void ar9003_mci_setup(struct ath_hw
*ah
, u32 gpm_addr
, void *gpm_buf
,
1001 u16 len
, u32 sched_addr
)
1003 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1004 void *sched_buf
= (void *)((char *) gpm_buf
+ (sched_addr
- gpm_addr
));
1006 if (!ATH9K_HW_CAP_MCI
)
1009 mci
->gpm_addr
= gpm_addr
;
1010 mci
->gpm_buf
= gpm_buf
;
1012 mci
->sched_addr
= sched_addr
;
1013 mci
->sched_buf
= sched_buf
;
1015 ar9003_mci_reset(ah
, true, true, true);
1017 EXPORT_SYMBOL(ar9003_mci_setup
);
1019 void ar9003_mci_cleanup(struct ath_hw
*ah
)
1021 struct ath_common
*common
= ath9k_hw_common(ah
);
1023 if (!ATH9K_HW_CAP_MCI
)
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
);
1031 EXPORT_SYMBOL(ar9003_mci_cleanup
);
1033 static void ar9003_mci_process_gpm_extra(struct ath_hw
*ah
, u8 gpm_type
,
1034 u8 gpm_opcode
, u32
*p_gpm
)
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
;
1040 if (gpm_type
!= MCI_GPM_COEX_AGENT
)
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);
1048 case MCI_GPM_COEX_VERSION_RESPONSE
:
1049 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Response\n");
1051 *(p_data
+ MCI_GPM_COEX_B_MAJOR_VERSION
);
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
);
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);
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");
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",
1080 u32
ar9003_mci_wait_for_gpm(struct ath_hw
*ah
, u8 gpm_type
,
1081 u8 gpm_opcode
, int time_out
)
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
;
1087 u8 recv_type
= 0, recv_opcode
= 0;
1088 bool b_is_bt_cal_done
= (gpm_type
== MCI_GPM_BT_CAL_DONE
);
1090 if (!ATH9K_HW_CAP_MCI
)
1093 more_data
= time_out
? MCI_GPM_NOMORE
: MCI_GPM_MORE
;
1095 while (time_out
> 0) {
1097 MCI_GPM_RECYCLE(p_gpm
);
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
,
1110 offset
= ar9003_mci_state(ah
,
1111 MCI_STATE_NEXT_GPM_OFFSET
, &more_data
);
1113 if (offset
== MCI_GPM_INVALID
)
1116 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
1117 recv_type
= MCI_GPM_TYPE(p_gpm
);
1118 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
1120 if (MCI_GPM_IS_CAL_TYPE(recv_type
)) {
1122 if (recv_type
== gpm_type
) {
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");
1134 } else if ((recv_type
== gpm_type
) &&
1135 (recv_opcode
== gpm_opcode
))
1138 /* not expected message */
1141 * check if it's cal_grant
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.
1153 if ((gpm_type
== MCI_GPM_BT_CAL_GRANT
) &&
1154 (recv_type
== MCI_GPM_BT_CAL_REQ
)) {
1156 u32 payload
[4] = {0, 0, 0, 0};
1158 gpm_type
= MCI_GPM_BT_CAL_DONE
;
1159 ath_dbg(common
, MCI
,
1160 "MCI Rcv BT_CAL_REQ, send WLAN_CAL_GRANT\n");
1162 MCI_GPM_SET_CAL_TYPE(payload
,
1163 MCI_GPM_WLAN_CAL_GRANT
);
1165 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
1168 ath_dbg(common
, MCI
, "MCI now wait for BT_CAL_DONE\n");
1172 ath_dbg(common
, MCI
, "MCI GPM subtype not match 0x%x\n",
1175 ar9003_mci_process_gpm_extra(ah
, recv_type
,
1176 recv_opcode
, p_gpm
);
1180 MCI_GPM_RECYCLE(p_gpm
);
1184 if (time_out
<= 0) {
1186 ath_dbg(common
, MCI
,
1187 "MCI GPM received timeout, mismatch = %d\n", mismatch
);
1189 ath_dbg(common
, MCI
, "MCI Receive GPM type=0x%x, code=0x%x\n",
1190 gpm_type
, gpm_opcode
);
1192 while (more_data
== MCI_GPM_MORE
) {
1194 ath_dbg(common
, MCI
, "MCI discard remaining GPM\n");
1195 offset
= ar9003_mci_state(ah
, MCI_STATE_NEXT_GPM_OFFSET
,
1198 if (offset
== MCI_GPM_INVALID
)
1201 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
1202 recv_type
= MCI_GPM_TYPE(p_gpm
);
1203 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
1205 if (!MCI_GPM_IS_CAL_TYPE(recv_type
))
1206 ar9003_mci_process_gpm_extra(ah
, recv_type
,
1207 recv_opcode
, p_gpm
);
1209 MCI_GPM_RECYCLE(p_gpm
);
1215 u32
ar9003_mci_state(struct ath_hw
*ah
, u32 state_type
, u32
*p_data
)
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
;
1222 if (!ATH9K_HW_CAP_MCI
)
1225 switch (state_type
) {
1226 case MCI_STATE_ENABLE
:
1229 value
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1231 if ((value
== 0xdeadbeef) || (value
== 0xffffffff))
1234 value
&= AR_BTCOEX_CTRL_MCI_MODE_EN
;
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
;
1241 case MCI_STATE_NEXT_GPM_OFFSET
:
1242 case MCI_STATE_LAST_GPM_OFFSET
:
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
1252 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
1253 AR_MCI_INTERRUPT_RX_MSG_GPM
);
1255 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1259 value
= mci
->gpm_len
- 1;
1260 else if (value
>= mci
->gpm_len
) {
1261 if (value
!= 0xFFFF) {
1263 ath_dbg(common
, MCI
,
1264 "MCI GPM offset out of range\n");
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",
1275 } else if (state_type
== MCI_STATE_NEXT_GPM_OFFSET
) {
1277 if (gpm_ptr
== mci
->gpm_idx
) {
1278 value
= MCI_GPM_INVALID
;
1279 more_gpm
= MCI_GPM_NOMORE
;
1281 ath_dbg(common
, MCI
,
1282 "MCI GPM message not available @ptr=%d, @offset=%d, more=GPM_NOMORE\n",
1289 /* skip reserved GPM if any */
1291 if (value
!= mci
->gpm_idx
)
1292 more_gpm
= MCI_GPM_MORE
;
1294 more_gpm
= MCI_GPM_NOMORE
;
1296 temp_index
= mci
->gpm_idx
;
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
));
1308 if (ar9003_mci_is_gpm_valid(ah
,
1314 if (more_gpm
== MCI_GPM_NOMORE
) {
1315 value
= MCI_GPM_INVALID
;
1324 if (value
!= MCI_GPM_INVALID
)
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 */
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
;
1341 case MCI_STATE_CONT_RSSI_POWER
:
1342 value
= MS(mci
->cont_status
, AR_MCI_CONT_RSSI_POWER
);
1345 case MCI_STATE_CONT_PRIORITY
:
1346 value
= MS(mci
->cont_status
, AR_MCI_CONT_RRIORITY
);
1349 case MCI_STATE_CONT_TXRX
:
1350 value
= MS(mci
->cont_status
, AR_MCI_CONT_TXRX
);
1354 value
= mci
->bt_state
;
1357 case MCI_STATE_SET_BT_SLEEP
:
1358 mci
->bt_state
= MCI_BT_SLEEP
;
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);
1366 if (mci
->unhalt_bt_gpm
) {
1368 ath_dbg(common
, MCI
, "MCI unhalt BT GPM\n");
1369 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
1372 ar9003_mci_2g5g_switch(ah
, true);
1375 case MCI_STATE_SET_BT_CAL_START
:
1376 mci
->bt_state
= MCI_BT_CAL_START
;
1379 case MCI_STATE_SET_BT_CAL
:
1380 mci
->bt_state
= MCI_BT_CAL
;
1383 case MCI_STATE_RESET_REQ_WAKE
:
1384 ar9003_mci_reset_req_wakeup(ah
);
1385 mci
->update_2g5g
= true;
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
) {
1394 ath_dbg(common
, MCI
,
1395 "MCI reconfigure observation\n");
1396 ar9003_mci_observation_set_up(ah
);
1401 case MCI_STATE_SEND_WLAN_COEX_VERSION
:
1402 ar9003_mci_send_coex_version_response(ah
, true);
1405 case MCI_STATE_SET_BT_COEX_VERSION
:
1408 ath_dbg(common
, MCI
,
1409 "MCI Set BT Coex version with NULL data!!\n");
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
);
1419 case MCI_STATE_SEND_WLAN_CHANNELS
:
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)))
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
++;
1432 mci
->wlan_channels_update
= true;
1433 ar9003_mci_send_coex_wlan_channels(ah
, true);
1436 case MCI_STATE_SEND_VERSION_QUERY
:
1437 ar9003_mci_send_coex_version_query(ah
, true);
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
;
1445 ar9003_mci_send_coex_bt_status_query(ah
, true, query_type
);
1448 case MCI_STATE_NEED_FLUSH_BT_INFO
:
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
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.
1461 value
= (!mci
->unhalt_bt_gpm
&&
1462 mci
->need_flush_btinfo
) ? 1 : 0;
1464 mci
->need_flush_btinfo
=
1465 (*p_data
!= 0) ? true : false;
1468 case MCI_STATE_RECOVER_RX
:
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);
1478 case MCI_STATE_NEED_FTP_STOMP
:
1479 value
= !(mci
->config
& ATH_MCI_CONFIG_DISABLE_FTP_STOMP
);
1482 case MCI_STATE_NEED_TUNING
:
1483 value
= !(mci
->config
& ATH_MCI_CONFIG_DISABLE_TUNING
);
1493 EXPORT_SYMBOL(ar9003_mci_state
);