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>
20 #include "ar9003_phy.h"
21 #include "ar9003_mci.h"
22 #include "ar9003_aic.h"
24 static void ar9003_mci_reset_req_wakeup(struct ath_hw
*ah
)
26 REG_RMW_FIELD(ah
, AR_MCI_COMMAND2
,
27 AR_MCI_COMMAND2_RESET_REQ_WAKEUP
, 1);
29 REG_RMW_FIELD(ah
, AR_MCI_COMMAND2
,
30 AR_MCI_COMMAND2_RESET_REQ_WAKEUP
, 0);
33 static int ar9003_mci_wait_for_interrupt(struct ath_hw
*ah
, u32 address
,
34 u32 bit_position
, int time_out
)
36 struct ath_common
*common
= ath9k_hw_common(ah
);
39 if (!(REG_READ(ah
, address
) & bit_position
)) {
48 REG_WRITE(ah
, address
, bit_position
);
50 if (address
!= AR_MCI_INTERRUPT_RX_MSG_RAW
)
53 if (bit_position
& AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
)
54 ar9003_mci_reset_req_wakeup(ah
);
56 if (bit_position
& (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING
|
57 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
))
58 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
59 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE
);
61 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
, AR_MCI_INTERRUPT_RX_MSG
);
67 "MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
68 address
, bit_position
);
70 "MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",
71 REG_READ(ah
, AR_MCI_INTERRUPT_RAW
),
72 REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
));
79 static void ar9003_mci_remote_reset(struct ath_hw
*ah
, bool wait_done
)
81 u32 payload
[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
83 ar9003_mci_send_message(ah
, MCI_REMOTE_RESET
, 0, payload
, 16,
88 static void ar9003_mci_send_lna_transfer(struct ath_hw
*ah
, bool wait_done
)
90 u32 payload
= 0x00000000;
92 ar9003_mci_send_message(ah
, MCI_LNA_TRANS
, 0, &payload
, 1,
96 static void ar9003_mci_send_req_wake(struct ath_hw
*ah
, bool wait_done
)
98 ar9003_mci_send_message(ah
, MCI_REQ_WAKE
, MCI_FLAG_DISABLE_TIMESTAMP
,
99 NULL
, 0, wait_done
, false);
103 static void ar9003_mci_send_sys_waking(struct ath_hw
*ah
, bool wait_done
)
105 ar9003_mci_send_message(ah
, MCI_SYS_WAKING
, MCI_FLAG_DISABLE_TIMESTAMP
,
106 NULL
, 0, wait_done
, false);
109 static void ar9003_mci_send_lna_take(struct ath_hw
*ah
, bool wait_done
)
111 u32 payload
= 0x70000000;
113 ar9003_mci_send_message(ah
, MCI_LNA_TAKE
, 0, &payload
, 1,
117 static void ar9003_mci_send_sys_sleeping(struct ath_hw
*ah
, bool wait_done
)
119 ar9003_mci_send_message(ah
, MCI_SYS_SLEEPING
,
120 MCI_FLAG_DISABLE_TIMESTAMP
,
121 NULL
, 0, wait_done
, false);
124 static void ar9003_mci_send_coex_version_query(struct ath_hw
*ah
,
127 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
128 u32 payload
[4] = {0, 0, 0, 0};
130 if (mci
->bt_version_known
||
131 (mci
->bt_state
== MCI_BT_SLEEP
))
134 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
135 MCI_GPM_COEX_VERSION_QUERY
);
136 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
139 static void ar9003_mci_send_coex_version_response(struct ath_hw
*ah
,
142 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
143 u32 payload
[4] = {0, 0, 0, 0};
145 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
146 MCI_GPM_COEX_VERSION_RESPONSE
);
147 *(((u8
*)payload
) + MCI_GPM_COEX_B_MAJOR_VERSION
) =
149 *(((u8
*)payload
) + MCI_GPM_COEX_B_MINOR_VERSION
) =
151 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
154 static void ar9003_mci_send_coex_wlan_channels(struct ath_hw
*ah
,
157 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
158 u32
*payload
= &mci
->wlan_channels
[0];
160 if (!mci
->wlan_channels_update
||
161 (mci
->bt_state
== MCI_BT_SLEEP
))
164 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
165 MCI_GPM_COEX_WLAN_CHANNELS
);
166 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
167 MCI_GPM_SET_TYPE_OPCODE(payload
, 0xff, 0xff);
170 static void ar9003_mci_send_coex_bt_status_query(struct ath_hw
*ah
,
171 bool wait_done
, u8 query_type
)
173 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
174 u32 payload
[4] = {0, 0, 0, 0};
177 if (mci
->bt_state
== MCI_BT_SLEEP
)
180 query_btinfo
= !!(query_type
& (MCI_GPM_COEX_QUERY_BT_ALL_INFO
|
181 MCI_GPM_COEX_QUERY_BT_TOPOLOGY
));
182 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
183 MCI_GPM_COEX_STATUS_QUERY
);
185 *(((u8
*)payload
) + MCI_GPM_COEX_B_BT_BITMAP
) = query_type
;
188 * If bt_status_query message is not sent successfully,
189 * then need_flush_btinfo should be set again.
191 if (!ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
194 mci
->need_flush_btinfo
= true;
198 mci
->query_bt
= false;
201 static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw
*ah
, bool halt
,
204 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
205 u32 payload
[4] = {0, 0, 0, 0};
207 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
208 MCI_GPM_COEX_HALT_BT_GPM
);
211 mci
->query_bt
= true;
212 /* Send next unhalt no matter halt sent or not */
213 mci
->unhalt_bt_gpm
= true;
214 mci
->need_flush_btinfo
= true;
215 *(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) =
216 MCI_GPM_COEX_BT_GPM_HALT
;
218 *(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) =
219 MCI_GPM_COEX_BT_GPM_UNHALT
;
221 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
224 static void ar9003_mci_prep_interface(struct ath_hw
*ah
)
226 struct ath_common
*common
= ath9k_hw_common(ah
);
227 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
228 u32 saved_mci_int_en
;
229 u32 mci_timeout
= 150;
231 mci
->bt_state
= MCI_BT_SLEEP
;
232 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
234 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
235 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
236 REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
));
237 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
238 REG_READ(ah
, AR_MCI_INTERRUPT_RAW
));
240 ar9003_mci_remote_reset(ah
, true);
241 ar9003_mci_send_req_wake(ah
, true);
243 if (!ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
244 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
, 500))
247 mci
->bt_state
= MCI_BT_AWAKE
;
250 * we don't need to send more remote_reset at this moment.
251 * If BT receive first remote_reset, then BT HW will
252 * be cleaned up and will be able to receive req_wake
253 * and BT HW will respond sys_waking.
254 * In this case, WLAN will receive BT's HW sys_waking.
255 * Otherwise, if BT SW missed initial remote_reset,
256 * that remote_reset will still clean up BT MCI RX,
257 * and the req_wake will wake BT up,
258 * and BT SW will respond this req_wake with a remote_reset and
259 * sys_waking. In this case, WLAN will receive BT's SW
260 * sys_waking. In either case, BT's RX is cleaned up. So we
261 * don't need to reply BT's remote_reset now, if any.
262 * Similarly, if in any case, WLAN can receive BT's sys_waking,
263 * that means WLAN's RX is also fine.
265 ar9003_mci_send_sys_waking(ah
, true);
269 * Set BT priority interrupt value to be 0xff to
270 * avoid having too many BT PRIORITY interrupts.
272 REG_WRITE(ah
, AR_MCI_BT_PRI0
, 0xFFFFFFFF);
273 REG_WRITE(ah
, AR_MCI_BT_PRI1
, 0xFFFFFFFF);
274 REG_WRITE(ah
, AR_MCI_BT_PRI2
, 0xFFFFFFFF);
275 REG_WRITE(ah
, AR_MCI_BT_PRI3
, 0xFFFFFFFF);
276 REG_WRITE(ah
, AR_MCI_BT_PRI
, 0X000000FF);
279 * A contention reset will be received after send out
280 * sys_waking. Also BT priority interrupt bits will be set.
281 * Clear those bits before the next step.
284 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
285 AR_MCI_INTERRUPT_RX_MSG_CONT_RST
);
286 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
, AR_MCI_INTERRUPT_BT_PRI
);
288 if (mci
->is_2g
&& MCI_ANT_ARCH_PA_LNA_SHARED(mci
)) {
289 ar9003_mci_send_lna_transfer(ah
, true);
293 if (mci
->is_2g
&& !mci
->update_2g5g
&& MCI_ANT_ARCH_PA_LNA_SHARED(mci
)) {
294 if (ar9003_mci_wait_for_interrupt(ah
,
295 AR_MCI_INTERRUPT_RX_MSG_RAW
,
296 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO
,
299 "MCI WLAN has control over the LNA & BT obeys it\n");
302 "MCI BT didn't respond to LNA_TRANS\n");
306 /* Clear the extra redundant SYS_WAKING from BT */
307 if ((mci
->bt_state
== MCI_BT_AWAKE
) &&
308 (REG_READ_FIELD(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
309 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
)) &&
310 (REG_READ_FIELD(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
311 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING
) == 0)) {
312 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
313 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
);
314 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
315 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE
);
318 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
321 void ar9003_mci_set_full_sleep(struct ath_hw
*ah
)
323 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
325 if (ar9003_mci_state(ah
, MCI_STATE_ENABLE
) &&
326 (mci
->bt_state
!= MCI_BT_SLEEP
) &&
327 !mci
->halted_bt_gpm
) {
328 ar9003_mci_send_coex_halt_bt_gpm(ah
, true, true);
334 static void ar9003_mci_disable_interrupt(struct ath_hw
*ah
)
336 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
337 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_EN
, 0);
340 static void ar9003_mci_enable_interrupt(struct ath_hw
*ah
)
342 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, AR_MCI_INTERRUPT_DEFAULT
);
343 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_EN
,
344 AR_MCI_INTERRUPT_RX_MSG_DEFAULT
);
347 static bool ar9003_mci_check_int(struct ath_hw
*ah
, u32 ints
)
351 intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
);
352 return ((intr
& ints
) == ints
);
355 void ar9003_mci_get_interrupt(struct ath_hw
*ah
, u32
*raw_intr
,
358 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
360 *raw_intr
= mci
->raw_intr
;
361 *rx_msg_intr
= mci
->rx_msg_intr
;
363 /* Clean int bits after the values are read. */
365 mci
->rx_msg_intr
= 0;
367 EXPORT_SYMBOL(ar9003_mci_get_interrupt
);
369 void ar9003_mci_get_isr(struct ath_hw
*ah
, enum ath9k_int
*masked
)
371 struct ath_common
*common
= ath9k_hw_common(ah
);
372 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
373 u32 raw_intr
, rx_msg_intr
;
375 rx_msg_intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
);
376 raw_intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RAW
);
378 if ((raw_intr
== 0xdeadbeef) || (rx_msg_intr
== 0xdeadbeef)) {
380 "MCI gets 0xdeadbeef during int processing\n");
382 mci
->rx_msg_intr
|= rx_msg_intr
;
383 mci
->raw_intr
|= raw_intr
;
384 *masked
|= ATH9K_INT_MCI
;
386 if (rx_msg_intr
& AR_MCI_INTERRUPT_RX_MSG_CONT_INFO
)
387 mci
->cont_status
= REG_READ(ah
, AR_MCI_CONT_STATUS
);
389 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
, rx_msg_intr
);
390 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
, raw_intr
);
394 static void ar9003_mci_2g5g_changed(struct ath_hw
*ah
, bool is_2g
)
396 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
398 if (!mci
->update_2g5g
&&
399 (mci
->is_2g
!= is_2g
))
400 mci
->update_2g5g
= true;
405 static bool ar9003_mci_is_gpm_valid(struct ath_hw
*ah
, u32 msg_index
)
407 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
409 u32 recv_type
, offset
;
411 if (msg_index
== MCI_GPM_INVALID
)
414 offset
= msg_index
<< 4;
416 payload
= (u32
*)(mci
->gpm_buf
+ offset
);
417 recv_type
= MCI_GPM_TYPE(payload
);
419 if (recv_type
== MCI_GPM_RSVD_PATTERN
)
425 static void ar9003_mci_observation_set_up(struct ath_hw
*ah
)
427 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
429 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MCI
) {
430 ath9k_hw_cfg_output(ah
, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA
);
431 ath9k_hw_cfg_output(ah
, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK
);
432 ath9k_hw_cfg_output(ah
, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA
);
433 ath9k_hw_cfg_output(ah
, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK
);
434 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_TXRX
) {
435 ath9k_hw_cfg_output(ah
, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX
);
436 ath9k_hw_cfg_output(ah
, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX
);
437 ath9k_hw_cfg_output(ah
, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX
);
438 ath9k_hw_cfg_output(ah
, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX
);
439 ath9k_hw_cfg_output(ah
, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT
);
440 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_BT
) {
441 ath9k_hw_cfg_output(ah
, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX
);
442 ath9k_hw_cfg_output(ah
, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX
);
443 ath9k_hw_cfg_output(ah
, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA
);
444 ath9k_hw_cfg_output(ah
, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK
);
448 REG_SET_BIT(ah
, AR_GPIO_INPUT_EN_VAL
, AR_GPIO_JTAG_DISABLE
);
450 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
, AR_GLB_DS_JTAG_DISABLE
, 1);
451 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
, AR_GLB_WLAN_UART_INTF_EN
, 0);
452 REG_SET_BIT(ah
, AR_GLB_GPIO_CONTROL
, ATH_MCI_CONFIG_MCI_OBS_GPIO
);
454 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_GPIO_OBS_SEL
, 0);
455 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL
, 1);
456 REG_WRITE(ah
, AR_OBS
, 0x4b);
457 REG_RMW_FIELD(ah
, AR_DIAG_SW
, AR_DIAG_OBS_PT_SEL1
, 0x03);
458 REG_RMW_FIELD(ah
, AR_DIAG_SW
, AR_DIAG_OBS_PT_SEL2
, 0x01);
459 REG_RMW_FIELD(ah
, AR_MACMISC
, AR_MACMISC_MISC_OBS_BUS_LSB
, 0x02);
460 REG_RMW_FIELD(ah
, AR_MACMISC
, AR_MACMISC_MISC_OBS_BUS_MSB
, 0x03);
461 REG_RMW_FIELD(ah
, AR_PHY_TEST_CTL_STATUS
,
462 AR_PHY_TEST_CTL_DEBUGPORT_SEL
, 0x07);
465 static bool ar9003_mci_send_coex_bt_flags(struct ath_hw
*ah
, bool wait_done
,
466 u8 opcode
, u32 bt_flags
)
468 u32 pld
[4] = {0, 0, 0, 0};
470 MCI_GPM_SET_TYPE_OPCODE(pld
, MCI_GPM_COEX_AGENT
,
471 MCI_GPM_COEX_BT_UPDATE_FLAGS
);
473 *(((u8
*)pld
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) = opcode
;
474 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 0) = bt_flags
& 0xFF;
475 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 1) = (bt_flags
>> 8) & 0xFF;
476 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 2) = (bt_flags
>> 16) & 0xFF;
477 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 3) = (bt_flags
>> 24) & 0xFF;
479 return ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16,
483 static void ar9003_mci_sync_bt_state(struct ath_hw
*ah
)
485 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
488 cur_bt_state
= ar9003_mci_state(ah
, MCI_STATE_REMOTE_SLEEP
);
490 if (mci
->bt_state
!= cur_bt_state
)
491 mci
->bt_state
= cur_bt_state
;
493 if (mci
->bt_state
!= MCI_BT_SLEEP
) {
495 ar9003_mci_send_coex_version_query(ah
, true);
496 ar9003_mci_send_coex_wlan_channels(ah
, true);
498 if (mci
->unhalt_bt_gpm
== true)
499 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
503 void ar9003_mci_check_bt(struct ath_hw
*ah
)
505 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
511 * check BT state again to make
512 * sure it's not changed.
514 ar9003_mci_sync_bt_state(ah
);
515 ar9003_mci_2g5g_switch(ah
, true);
517 if ((mci_hw
->bt_state
== MCI_BT_AWAKE
) &&
518 (mci_hw
->query_bt
== true)) {
519 mci_hw
->need_flush_btinfo
= true;
523 static void ar9003_mci_process_gpm_extra(struct ath_hw
*ah
, u8 gpm_type
,
524 u8 gpm_opcode
, u32
*p_gpm
)
526 struct ath_common
*common
= ath9k_hw_common(ah
);
527 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
528 u8
*p_data
= (u8
*) p_gpm
;
530 if (gpm_type
!= MCI_GPM_COEX_AGENT
)
533 switch (gpm_opcode
) {
534 case MCI_GPM_COEX_VERSION_QUERY
:
535 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Query\n");
536 ar9003_mci_send_coex_version_response(ah
, true);
538 case MCI_GPM_COEX_VERSION_RESPONSE
:
539 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Response\n");
541 *(p_data
+ MCI_GPM_COEX_B_MAJOR_VERSION
);
543 *(p_data
+ MCI_GPM_COEX_B_MINOR_VERSION
);
544 mci
->bt_version_known
= true;
545 ath_dbg(common
, MCI
, "MCI BT Coex version: %d.%d\n",
546 mci
->bt_ver_major
, mci
->bt_ver_minor
);
548 case MCI_GPM_COEX_STATUS_QUERY
:
550 "MCI Recv GPM COEX Status Query = 0x%02X\n",
551 *(p_data
+ MCI_GPM_COEX_B_WLAN_BITMAP
));
552 mci
->wlan_channels_update
= true;
553 ar9003_mci_send_coex_wlan_channels(ah
, true);
555 case MCI_GPM_COEX_BT_PROFILE_INFO
:
556 mci
->query_bt
= true;
557 ath_dbg(common
, MCI
, "MCI Recv GPM COEX BT_Profile_Info\n");
559 case MCI_GPM_COEX_BT_STATUS_UPDATE
:
560 mci
->query_bt
= true;
562 "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
570 static u32
ar9003_mci_wait_for_gpm(struct ath_hw
*ah
, u8 gpm_type
,
571 u8 gpm_opcode
, int time_out
)
573 struct ath_common
*common
= ath9k_hw_common(ah
);
574 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
575 u32
*p_gpm
= NULL
, mismatch
= 0, more_data
;
577 u8 recv_type
= 0, recv_opcode
= 0;
578 bool b_is_bt_cal_done
= (gpm_type
== MCI_GPM_BT_CAL_DONE
);
580 more_data
= time_out
? MCI_GPM_NOMORE
: MCI_GPM_MORE
;
582 while (time_out
> 0) {
584 MCI_GPM_RECYCLE(p_gpm
);
588 if (more_data
!= MCI_GPM_MORE
)
589 time_out
= ar9003_mci_wait_for_interrupt(ah
,
590 AR_MCI_INTERRUPT_RX_MSG_RAW
,
591 AR_MCI_INTERRUPT_RX_MSG_GPM
,
597 offset
= ar9003_mci_get_next_gpm_offset(ah
, &more_data
);
599 if (offset
== MCI_GPM_INVALID
)
602 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
603 recv_type
= MCI_GPM_TYPE(p_gpm
);
604 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
606 if (MCI_GPM_IS_CAL_TYPE(recv_type
)) {
607 if (recv_type
== gpm_type
) {
608 if ((gpm_type
== MCI_GPM_BT_CAL_DONE
) &&
610 gpm_type
= MCI_GPM_BT_CAL_GRANT
;
615 } else if ((recv_type
== gpm_type
) &&
616 (recv_opcode
== gpm_opcode
))
620 * check if it's cal_grant
622 * When we're waiting for cal_grant in reset routine,
623 * it's possible that BT sends out cal_request at the
624 * same time. Since BT's calibration doesn't happen
625 * that often, we'll let BT completes calibration then
626 * we continue to wait for cal_grant from BT.
627 * Orginal: Wait BT_CAL_GRANT.
628 * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
629 * BT_CAL_DONE -> Wait BT_CAL_GRANT.
632 if ((gpm_type
== MCI_GPM_BT_CAL_GRANT
) &&
633 (recv_type
== MCI_GPM_BT_CAL_REQ
)) {
635 u32 payload
[4] = {0, 0, 0, 0};
637 gpm_type
= MCI_GPM_BT_CAL_DONE
;
638 MCI_GPM_SET_CAL_TYPE(payload
,
639 MCI_GPM_WLAN_CAL_GRANT
);
640 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
644 ath_dbg(common
, MCI
, "MCI GPM subtype not match 0x%x\n",
647 ar9003_mci_process_gpm_extra(ah
, recv_type
,
653 MCI_GPM_RECYCLE(p_gpm
);
660 while (more_data
== MCI_GPM_MORE
) {
661 offset
= ar9003_mci_get_next_gpm_offset(ah
, &more_data
);
662 if (offset
== MCI_GPM_INVALID
)
665 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
666 recv_type
= MCI_GPM_TYPE(p_gpm
);
667 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
669 if (!MCI_GPM_IS_CAL_TYPE(recv_type
))
670 ar9003_mci_process_gpm_extra(ah
, recv_type
,
673 MCI_GPM_RECYCLE(p_gpm
);
679 bool ar9003_mci_start_reset(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
681 struct ath_common
*common
= ath9k_hw_common(ah
);
682 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
683 u32 payload
[4] = {0, 0, 0, 0};
685 ar9003_mci_2g5g_changed(ah
, IS_CHAN_2GHZ(chan
));
687 if (mci_hw
->bt_state
!= MCI_BT_CAL_START
)
690 mci_hw
->bt_state
= MCI_BT_CAL
;
693 * MCI FIX: disable mci interrupt here. This is to avoid
694 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
695 * lead to mci_intr reentry.
697 ar9003_mci_disable_interrupt(ah
);
699 MCI_GPM_SET_CAL_TYPE(payload
, MCI_GPM_WLAN_CAL_GRANT
);
700 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
,
703 /* Wait BT calibration to be completed for 25ms */
705 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_DONE
,
707 ath_dbg(common
, MCI
, "MCI BT_CAL_DONE received\n");
710 "MCI BT_CAL_DONE not received\n");
712 mci_hw
->bt_state
= MCI_BT_AWAKE
;
713 /* MCI FIX: enable mci interrupt here */
714 ar9003_mci_enable_interrupt(ah
);
719 int ar9003_mci_end_reset(struct ath_hw
*ah
, struct ath9k_channel
*chan
,
720 struct ath9k_hw_cal_data
*caldata
)
722 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
727 if (!IS_CHAN_2GHZ(chan
) || (mci_hw
->bt_state
!= MCI_BT_SLEEP
))
730 if (!ar9003_mci_check_int(ah
, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET
) &&
731 !ar9003_mci_check_int(ah
, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
))
735 * BT is sleeping. Check if BT wakes up during
736 * WLAN calibration. If BT wakes up during
737 * WLAN calibration, need to go through all
738 * message exchanges again and recal.
740 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
741 (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET
|
742 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
));
744 ar9003_mci_remote_reset(ah
, true);
745 ar9003_mci_send_sys_waking(ah
, true);
748 if (IS_CHAN_2GHZ(chan
))
749 ar9003_mci_send_lna_transfer(ah
, true);
751 mci_hw
->bt_state
= MCI_BT_AWAKE
;
753 REG_CLR_BIT(ah
, AR_PHY_TIMING4
,
754 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT
);
757 clear_bit(TXIQCAL_DONE
, &caldata
->cal_flags
);
758 clear_bit(TXCLCAL_DONE
, &caldata
->cal_flags
);
759 clear_bit(RTT_DONE
, &caldata
->cal_flags
);
762 if (!ath9k_hw_init_cal(ah
, chan
))
765 REG_SET_BIT(ah
, AR_PHY_TIMING4
,
766 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT
);
769 ar9003_mci_enable_interrupt(ah
);
773 static void ar9003_mci_mute_bt(struct ath_hw
*ah
)
775 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
777 /* disable all MCI messages */
778 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
, 0xffff0000);
779 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS0
, 0xffffffff);
780 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS1
, 0xffffffff);
781 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS2
, 0xffffffff);
782 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS3
, 0xffffffff);
783 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
785 /* wait pending HW messages to flush out */
789 * Send LNA_TAKE and SYS_SLEEPING when
790 * 1. reset not after resuming from full sleep
791 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
793 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci
)) {
794 ar9003_mci_send_lna_take(ah
, true);
798 ar9003_mci_send_sys_sleeping(ah
, true);
801 static void ar9003_mci_osla_setup(struct ath_hw
*ah
, bool enable
)
803 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
807 REG_CLR_BIT(ah
, AR_BTCOEX_CTRL
,
808 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
811 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
, AR_MCI_SCHD_TABLE_2_HW_BASED
, 1);
812 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
,
813 AR_MCI_SCHD_TABLE_2_MEM_BASED
, 1);
815 if (AR_SREV_9565(ah
))
816 REG_RMW_FIELD(ah
, AR_MCI_MISC
, AR_MCI_MISC_HW_FIX_EN
, 1);
818 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_AGGR_THRESH
)) {
819 thresh
= MS(mci
->config
, ATH_MCI_CONFIG_AGGR_THRESH
);
820 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
821 AR_BTCOEX_CTRL_AGGR_THRESH
, thresh
);
822 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
823 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 1);
825 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
826 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 0);
828 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
829 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
, 1);
832 static void ar9003_mci_stat_setup(struct ath_hw
*ah
)
834 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
836 if (!AR_SREV_9565(ah
))
839 if (mci
->config
& ATH_MCI_CONFIG_MCI_STAT_DBG
) {
840 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
841 AR_MCI_DBG_CNT_CTRL_ENABLE
, 1);
842 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
843 AR_MCI_DBG_CNT_CTRL_BT_LINKID
,
844 MCI_STAT_ALL_BT_LINKID
);
846 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
847 AR_MCI_DBG_CNT_CTRL_ENABLE
, 0);
851 static void ar9003_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hw
*ah
)
855 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
856 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
857 SM(1, AR_BTCOEX_CTRL_PA_SHARED
) |
858 SM(1, AR_BTCOEX_CTRL_LNA_SHARED
) |
859 SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
860 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
861 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
862 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
863 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
865 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
866 AR_BTCOEX_CTRL2_TX_CHAIN_MASK
, 0x1);
867 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
870 static void ar9003_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hw
*ah
)
874 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
875 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
876 SM(0, AR_BTCOEX_CTRL_PA_SHARED
) |
877 SM(0, AR_BTCOEX_CTRL_LNA_SHARED
) |
878 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
879 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
880 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
881 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
882 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
884 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
885 AR_BTCOEX_CTRL2_TX_CHAIN_MASK
, 0x0);
886 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
889 static void ar9003_mci_set_btcoex_ctrl_9462(struct ath_hw
*ah
)
893 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
894 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
895 SM(1, AR_BTCOEX_CTRL_PA_SHARED
) |
896 SM(1, AR_BTCOEX_CTRL_LNA_SHARED
) |
897 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
898 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
899 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
900 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
901 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
903 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
906 int ar9003_mci_reset(struct ath_hw
*ah
, bool en_int
, bool is_2g
,
909 struct ath_common
*common
= ath9k_hw_common(ah
);
910 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
913 ath_dbg(common
, MCI
, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
914 is_full_sleep
, is_2g
);
916 if (REG_READ(ah
, AR_BTCOEX_CTRL
) == 0xdeadbeef) {
917 ath_err(common
, "BTCOEX control register is dead\n");
921 /* Program MCI DMA related registers */
922 REG_WRITE(ah
, AR_MCI_GPM_0
, mci
->gpm_addr
);
923 REG_WRITE(ah
, AR_MCI_GPM_1
, mci
->gpm_len
);
924 REG_WRITE(ah
, AR_MCI_SCHD_TABLE_0
, mci
->sched_addr
);
927 * To avoid MCI state machine be affected by incoming remote MCI msgs,
928 * MCI mode will be enabled later, right before reset the MCI TX and RX.
930 if (AR_SREV_9565(ah
)) {
931 u8 ant
= MS(mci
->config
, ATH_MCI_CONFIG_ANT_ARCH
);
933 if (ant
== ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED
)
934 ar9003_mci_set_btcoex_ctrl_9565_1ANT(ah
);
936 ar9003_mci_set_btcoex_ctrl_9565_2ANT(ah
);
938 ar9003_mci_set_btcoex_ctrl_9462(ah
);
941 if (is_2g
&& !(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
942 ar9003_mci_osla_setup(ah
, true);
944 ar9003_mci_osla_setup(ah
, false);
946 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
947 AR_BTCOEX_CTRL_SPDT_ENABLE
);
948 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL3
,
949 AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT
, 20);
951 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_RX_DEWEIGHT
, 0);
952 REG_RMW_FIELD(ah
, AR_PCU_MISC
, AR_PCU_BT_ANT_PREVENT_RX
, 0);
954 /* Set the time out to 3.125ms (5 BT slots) */
955 REG_RMW_FIELD(ah
, AR_BTCOEX_WL_LNA
, AR_BTCOEX_WL_LNA_TIMEOUT
, 0x3D090);
957 /* concurrent tx priority */
958 if (mci
->config
& ATH_MCI_CONFIG_CONCUR_TX
) {
959 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
960 AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE
, 0);
961 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
962 AR_BTCOEX_CTRL2_TXPWR_THRESH
, 0x7f);
963 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
964 AR_BTCOEX_CTRL_REDUCE_TXPWR
, 0);
965 for (i
= 0; i
< 8; i
++)
966 REG_WRITE(ah
, AR_BTCOEX_MAX_TXPWR(i
), 0x7f7f7f7f);
969 regval
= MS(mci
->config
, ATH_MCI_CONFIG_CLK_DIV
);
970 REG_RMW_FIELD(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_CLK_DIV
, regval
);
971 REG_SET_BIT(ah
, AR_BTCOEX_CTRL
, AR_BTCOEX_CTRL_MCI_MODE_EN
);
973 /* Resetting the Rx and Tx paths of MCI */
974 regval
= REG_READ(ah
, AR_MCI_COMMAND2
);
975 regval
|= SM(1, AR_MCI_COMMAND2_RESET_TX
);
976 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
980 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_TX
);
981 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
984 ar9003_mci_mute_bt(ah
);
988 /* Check pending GPM msg before MCI Reset Rx */
989 ar9003_mci_check_gpm_offset(ah
);
991 regval
|= SM(1, AR_MCI_COMMAND2_RESET_RX
);
992 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
994 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_RX
);
995 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
997 /* Init GPM offset after MCI Reset Rx */
998 ar9003_mci_state(ah
, MCI_STATE_INIT_GPM_OFFSET
);
1000 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
,
1001 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR
) |
1002 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM
)));
1004 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci
))
1005 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
1006 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1008 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
1009 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1011 ar9003_mci_observation_set_up(ah
);
1014 ar9003_mci_prep_interface(ah
);
1015 ar9003_mci_stat_setup(ah
);
1018 ar9003_mci_enable_interrupt(ah
);
1020 if (ath9k_hw_is_aic_enabled(ah
))
1021 ar9003_aic_start_normal(ah
);
1026 void ar9003_mci_stop_bt(struct ath_hw
*ah
, bool save_fullsleep
)
1028 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1030 ar9003_mci_disable_interrupt(ah
);
1032 if (mci_hw
->ready
&& !save_fullsleep
) {
1033 ar9003_mci_mute_bt(ah
);
1035 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0);
1038 mci_hw
->bt_state
= MCI_BT_SLEEP
;
1039 mci_hw
->ready
= false;
1042 static void ar9003_mci_send_2g5g_status(struct ath_hw
*ah
, bool wait_done
)
1044 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1045 u32 new_flags
, to_set
, to_clear
;
1047 if (!mci
->update_2g5g
|| (mci
->bt_state
== MCI_BT_SLEEP
))
1051 new_flags
= MCI_2G_FLAGS
;
1052 to_clear
= MCI_2G_FLAGS_CLEAR_MASK
;
1053 to_set
= MCI_2G_FLAGS_SET_MASK
;
1055 new_flags
= MCI_5G_FLAGS
;
1056 to_clear
= MCI_5G_FLAGS_CLEAR_MASK
;
1057 to_set
= MCI_5G_FLAGS_SET_MASK
;
1061 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
1062 MCI_GPM_COEX_BT_FLAGS_CLEAR
,
1065 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
1066 MCI_GPM_COEX_BT_FLAGS_SET
,
1070 static void ar9003_mci_queue_unsent_gpm(struct ath_hw
*ah
, u8 header
,
1071 u32
*payload
, bool queue
)
1073 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1076 /* check if the message is to be queued */
1077 if (header
!= MCI_GPM
)
1080 type
= MCI_GPM_TYPE(payload
);
1081 opcode
= MCI_GPM_OPCODE(payload
);
1083 if (type
!= MCI_GPM_COEX_AGENT
)
1087 case MCI_GPM_COEX_BT_UPDATE_FLAGS
:
1088 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) ==
1089 MCI_GPM_COEX_BT_FLAGS_READ
)
1092 mci
->update_2g5g
= queue
;
1095 case MCI_GPM_COEX_WLAN_CHANNELS
:
1096 mci
->wlan_channels_update
= queue
;
1098 case MCI_GPM_COEX_HALT_BT_GPM
:
1099 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
1100 MCI_GPM_COEX_BT_GPM_UNHALT
) {
1101 mci
->unhalt_bt_gpm
= queue
;
1104 mci
->halted_bt_gpm
= false;
1107 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
1108 MCI_GPM_COEX_BT_GPM_HALT
) {
1110 mci
->halted_bt_gpm
= !queue
;
1119 void ar9003_mci_2g5g_switch(struct ath_hw
*ah
, bool force
)
1121 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1123 if (!mci
->update_2g5g
&& !force
)
1127 ar9003_mci_send_2g5g_status(ah
, true);
1128 ar9003_mci_send_lna_transfer(ah
, true);
1131 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
1132 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1133 REG_CLR_BIT(ah
, AR_PHY_GLB_CONTROL
,
1134 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1136 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
1137 ar9003_mci_osla_setup(ah
, true);
1139 if (AR_SREV_9462(ah
))
1140 REG_WRITE(ah
, AR_SELFGEN_MASK
, 0x02);
1142 ar9003_mci_send_lna_take(ah
, true);
1145 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
1146 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1147 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
1148 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1150 ar9003_mci_osla_setup(ah
, false);
1151 ar9003_mci_send_2g5g_status(ah
, true);
1155 bool ar9003_mci_send_message(struct ath_hw
*ah
, u8 header
, u32 flag
,
1156 u32
*payload
, u8 len
, bool wait_done
,
1159 struct ath_common
*common
= ath9k_hw_common(ah
);
1160 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1161 bool msg_sent
= false;
1163 u32 saved_mci_int_en
;
1166 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
1167 regval
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1169 if ((regval
== 0xdeadbeef) || !(regval
& AR_BTCOEX_CTRL_MCI_MODE_EN
)) {
1170 ath_dbg(common
, MCI
,
1171 "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
1172 header
, (ah
->power_mode
== ATH9K_PM_FULL_SLEEP
) ? 1 : 0);
1173 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1175 } else if (check_bt
&& (mci
->bt_state
== MCI_BT_SLEEP
)) {
1176 ath_dbg(common
, MCI
,
1177 "MCI Don't send message 0x%x. BT is in sleep state\n",
1179 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1184 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
1186 /* Need to clear SW_MSG_DONE raw bit before wait */
1188 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
1189 (AR_MCI_INTERRUPT_SW_MSG_DONE
|
1190 AR_MCI_INTERRUPT_MSG_FAIL_MASK
));
1193 for (i
= 0; (i
* 4) < len
; i
++)
1194 REG_WRITE(ah
, (AR_MCI_TX_PAYLOAD0
+ i
* 4),
1198 REG_WRITE(ah
, AR_MCI_COMMAND0
,
1199 (SM((flag
& MCI_FLAG_DISABLE_TIMESTAMP
),
1200 AR_MCI_COMMAND0_DISABLE_TIMESTAMP
) |
1201 SM(len
, AR_MCI_COMMAND0_LEN
) |
1202 SM(header
, AR_MCI_COMMAND0_HEADER
)));
1205 !(ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RAW
,
1206 AR_MCI_INTERRUPT_SW_MSG_DONE
, 500)))
1207 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1209 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, false);
1214 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
1218 EXPORT_SYMBOL(ar9003_mci_send_message
);
1220 void ar9003_mci_init_cal_req(struct ath_hw
*ah
, bool *is_reusable
)
1222 struct ath_common
*common
= ath9k_hw_common(ah
);
1223 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1224 u32 pld
[4] = {0, 0, 0, 0};
1226 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1227 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1230 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_REQ
);
1231 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_seq
++;
1233 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1235 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_GRANT
, 0, 50000)) {
1236 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT received\n");
1238 *is_reusable
= false;
1239 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT not received\n");
1243 void ar9003_mci_init_cal_done(struct ath_hw
*ah
)
1245 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1246 u32 pld
[4] = {0, 0, 0, 0};
1248 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1249 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1252 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_DONE
);
1253 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_done
++;
1254 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1257 int ar9003_mci_setup(struct ath_hw
*ah
, u32 gpm_addr
, void *gpm_buf
,
1258 u16 len
, u32 sched_addr
)
1260 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1262 mci
->gpm_addr
= gpm_addr
;
1263 mci
->gpm_buf
= gpm_buf
;
1265 mci
->sched_addr
= sched_addr
;
1267 return ar9003_mci_reset(ah
, true, true, true);
1269 EXPORT_SYMBOL(ar9003_mci_setup
);
1271 void ar9003_mci_cleanup(struct ath_hw
*ah
)
1273 /* Turn off MCI and Jupiter mode. */
1274 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0x00);
1275 ar9003_mci_disable_interrupt(ah
);
1277 EXPORT_SYMBOL(ar9003_mci_cleanup
);
1279 u32
ar9003_mci_state(struct ath_hw
*ah
, u32 state_type
)
1281 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1285 switch (state_type
) {
1286 case MCI_STATE_ENABLE
:
1288 value
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1290 if ((value
== 0xdeadbeef) || (value
== 0xffffffff))
1293 value
&= AR_BTCOEX_CTRL_MCI_MODE_EN
;
1295 case MCI_STATE_INIT_GPM_OFFSET
:
1296 value
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1298 if (value
< mci
->gpm_len
)
1299 mci
->gpm_idx
= value
;
1303 case MCI_STATE_LAST_SCHD_MSG_OFFSET
:
1304 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1305 AR_MCI_RX_LAST_SCHD_MSG_INDEX
);
1306 /* Make it in bytes */
1309 case MCI_STATE_REMOTE_SLEEP
:
1310 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1311 AR_MCI_RX_REMOTE_SLEEP
) ?
1312 MCI_BT_SLEEP
: MCI_BT_AWAKE
;
1314 case MCI_STATE_SET_BT_AWAKE
:
1315 mci
->bt_state
= MCI_BT_AWAKE
;
1316 ar9003_mci_send_coex_version_query(ah
, true);
1317 ar9003_mci_send_coex_wlan_channels(ah
, true);
1319 if (mci
->unhalt_bt_gpm
)
1320 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
1322 ar9003_mci_2g5g_switch(ah
, false);
1324 case MCI_STATE_RESET_REQ_WAKE
:
1325 ar9003_mci_reset_req_wakeup(ah
);
1326 mci
->update_2g5g
= true;
1328 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MASK
) {
1329 /* Check if we still have control of the GPIOs */
1330 if ((REG_READ(ah
, AR_GLB_GPIO_CONTROL
) &
1331 ATH_MCI_CONFIG_MCI_OBS_GPIO
) !=
1332 ATH_MCI_CONFIG_MCI_OBS_GPIO
) {
1333 ar9003_mci_observation_set_up(ah
);
1337 case MCI_STATE_SEND_WLAN_COEX_VERSION
:
1338 ar9003_mci_send_coex_version_response(ah
, true);
1340 case MCI_STATE_SEND_VERSION_QUERY
:
1341 ar9003_mci_send_coex_version_query(ah
, true);
1343 case MCI_STATE_SEND_STATUS_QUERY
:
1344 query_type
= MCI_GPM_COEX_QUERY_BT_TOPOLOGY
;
1345 ar9003_mci_send_coex_bt_status_query(ah
, true, query_type
);
1347 case MCI_STATE_RECOVER_RX
:
1348 tsf
= ath9k_hw_gettsf32(ah
);
1349 if ((tsf
- mci
->last_recovery
) <= MCI_RECOVERY_DUR_TSF
) {
1350 ath_dbg(ath9k_hw_common(ah
), MCI
,
1351 "(MCI) ignore Rx recovery\n");
1354 ath_dbg(ath9k_hw_common(ah
), MCI
, "(MCI) RECOVER RX\n");
1355 mci
->last_recovery
= tsf
;
1356 ar9003_mci_prep_interface(ah
);
1357 mci
->query_bt
= true;
1358 mci
->need_flush_btinfo
= true;
1359 ar9003_mci_send_coex_wlan_channels(ah
, true);
1360 ar9003_mci_2g5g_switch(ah
, false);
1362 case MCI_STATE_NEED_FTP_STOMP
:
1363 value
= !(mci
->config
& ATH_MCI_CONFIG_DISABLE_FTP_STOMP
);
1365 case MCI_STATE_NEED_FLUSH_BT_INFO
:
1366 value
= (!mci
->unhalt_bt_gpm
&& mci
->need_flush_btinfo
) ? 1 : 0;
1367 mci
->need_flush_btinfo
= false;
1369 case MCI_STATE_AIC_CAL
:
1370 if (ath9k_hw_is_aic_enabled(ah
))
1371 value
= ar9003_aic_calibration(ah
);
1373 case MCI_STATE_AIC_START
:
1374 if (ath9k_hw_is_aic_enabled(ah
))
1375 ar9003_aic_start_normal(ah
);
1377 case MCI_STATE_AIC_CAL_RESET
:
1378 if (ath9k_hw_is_aic_enabled(ah
))
1379 value
= ar9003_aic_cal_reset(ah
);
1381 case MCI_STATE_AIC_CAL_SINGLE
:
1382 if (ath9k_hw_is_aic_enabled(ah
))
1383 value
= ar9003_aic_calibration_single(ah
);
1391 EXPORT_SYMBOL(ar9003_mci_state
);
1393 void ar9003_mci_bt_gain_ctrl(struct ath_hw
*ah
)
1395 struct ath_common
*common
= ath9k_hw_common(ah
);
1396 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1398 ath_dbg(common
, MCI
, "Give LNA and SPDT control to BT\n");
1400 ar9003_mci_send_lna_take(ah
, true);
1403 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1405 mci
->update_2g5g
= true;
1406 ar9003_mci_send_2g5g_status(ah
, true);
1408 /* Force another 2g5g update at next scanning */
1409 mci
->update_2g5g
= true;
1412 void ar9003_mci_set_power_awake(struct ath_hw
*ah
)
1414 u32 btcoex_ctrl2
, diag_sw
;
1416 u8 lna_ctrl
, bt_sleep
;
1418 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1419 btcoex_ctrl2
= REG_READ(ah
, AR_BTCOEX_CTRL2
);
1420 if (btcoex_ctrl2
!= 0xdeadbeef)
1422 udelay(AH_TIME_QUANTUM
);
1424 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, (btcoex_ctrl2
| BIT(23)));
1426 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1427 diag_sw
= REG_READ(ah
, AR_DIAG_SW
);
1428 if (diag_sw
!= 0xdeadbeef)
1430 udelay(AH_TIME_QUANTUM
);
1432 REG_WRITE(ah
, AR_DIAG_SW
, (diag_sw
| BIT(27) | BIT(19) | BIT(18)));
1433 lna_ctrl
= REG_READ(ah
, AR_OBS_BUS_CTRL
) & 0x3;
1434 bt_sleep
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
), AR_MCI_RX_REMOTE_SLEEP
);
1436 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, btcoex_ctrl2
);
1437 REG_WRITE(ah
, AR_DIAG_SW
, diag_sw
);
1439 if (bt_sleep
&& (lna_ctrl
== 2)) {
1440 REG_SET_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1441 REG_CLR_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1446 void ar9003_mci_check_gpm_offset(struct ath_hw
*ah
)
1448 struct ath_common
*common
= ath9k_hw_common(ah
);
1449 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1453 * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
1455 offset
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1456 if (mci
->gpm_idx
== offset
)
1458 ath_dbg(common
, MCI
, "GPM cached write pointer mismatch %d %d\n",
1459 mci
->gpm_idx
, offset
);
1460 mci
->query_bt
= true;
1461 mci
->need_flush_btinfo
= true;
1465 u32
ar9003_mci_get_next_gpm_offset(struct ath_hw
*ah
, u32
*more
)
1467 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1468 u32 offset
, more_gpm
= 0, gpm_ptr
;
1471 * This could be useful to avoid new GPM message interrupt which
1472 * may lead to spurious interrupt after power sleep, or multiple
1473 * entry of ath_mci_intr().
1474 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1475 * alleviate this effect, but clearing GPM RX interrupt bit is
1476 * safe, because whether this is called from hw or driver code
1477 * there must be an interrupt bit set/triggered initially
1479 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
1480 AR_MCI_INTERRUPT_RX_MSG_GPM
);
1482 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1486 offset
= mci
->gpm_len
- 1;
1487 else if (offset
>= mci
->gpm_len
) {
1488 if (offset
!= 0xFFFF)
1494 if ((offset
== 0xFFFF) || (gpm_ptr
== mci
->gpm_idx
)) {
1495 offset
= MCI_GPM_INVALID
;
1496 more_gpm
= MCI_GPM_NOMORE
;
1502 /* skip reserved GPM if any */
1504 if (offset
!= mci
->gpm_idx
)
1505 more_gpm
= MCI_GPM_MORE
;
1507 more_gpm
= MCI_GPM_NOMORE
;
1509 temp_index
= mci
->gpm_idx
;
1511 if (temp_index
>= mci
->gpm_len
)
1516 if (mci
->gpm_idx
>= mci
->gpm_len
)
1519 if (ar9003_mci_is_gpm_valid(ah
, temp_index
)) {
1520 offset
= temp_index
;
1524 if (more_gpm
== MCI_GPM_NOMORE
) {
1525 offset
= MCI_GPM_INVALID
;
1530 if (offset
!= MCI_GPM_INVALID
)
1538 EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset
);
1540 void ar9003_mci_set_bt_version(struct ath_hw
*ah
, u8 major
, u8 minor
)
1542 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1544 mci
->bt_ver_major
= major
;
1545 mci
->bt_ver_minor
= minor
;
1546 mci
->bt_version_known
= true;
1547 ath_dbg(ath9k_hw_common(ah
), MCI
, "MCI BT version set: %d.%d\n",
1548 mci
->bt_ver_major
, mci
->bt_ver_minor
);
1550 EXPORT_SYMBOL(ar9003_mci_set_bt_version
);
1552 void ar9003_mci_send_wlan_channels(struct ath_hw
*ah
)
1554 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1556 mci
->wlan_channels_update
= true;
1557 ar9003_mci_send_coex_wlan_channels(ah
, true);
1559 EXPORT_SYMBOL(ar9003_mci_send_wlan_channels
);
1561 u16
ar9003_mci_get_max_txpower(struct ath_hw
*ah
, u8 ctlmode
)
1563 if (!ah
->btcoex_hw
.mci
.concur_tx
)
1566 if (ctlmode
== CTL_2GHT20
)
1567 return ATH_BTCOEX_HT20_MAX_TXPOWER
;
1568 else if (ctlmode
== CTL_2GHT40
)
1569 return ATH_BTCOEX_HT40_MAX_TXPOWER
;