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"
23 static void ar9003_mci_reset_req_wakeup(struct ath_hw
*ah
)
25 REG_RMW_FIELD(ah
, AR_MCI_COMMAND2
,
26 AR_MCI_COMMAND2_RESET_REQ_WAKEUP
, 1);
28 REG_RMW_FIELD(ah
, AR_MCI_COMMAND2
,
29 AR_MCI_COMMAND2_RESET_REQ_WAKEUP
, 0);
32 static int ar9003_mci_wait_for_interrupt(struct ath_hw
*ah
, u32 address
,
33 u32 bit_position
, int time_out
)
35 struct ath_common
*common
= ath9k_hw_common(ah
);
38 if (!(REG_READ(ah
, address
) & bit_position
)) {
47 REG_WRITE(ah
, address
, bit_position
);
49 if (address
!= AR_MCI_INTERRUPT_RX_MSG_RAW
)
52 if (bit_position
& AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
)
53 ar9003_mci_reset_req_wakeup(ah
);
55 if (bit_position
& (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING
|
56 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
))
57 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
58 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE
);
60 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
, AR_MCI_INTERRUPT_RX_MSG
);
66 "MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
67 address
, bit_position
);
69 "MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",
70 REG_READ(ah
, AR_MCI_INTERRUPT_RAW
),
71 REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
));
78 static void ar9003_mci_remote_reset(struct ath_hw
*ah
, bool wait_done
)
80 u32 payload
[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
82 ar9003_mci_send_message(ah
, MCI_REMOTE_RESET
, 0, payload
, 16,
87 static void ar9003_mci_send_lna_transfer(struct ath_hw
*ah
, bool wait_done
)
89 u32 payload
= 0x00000000;
91 ar9003_mci_send_message(ah
, MCI_LNA_TRANS
, 0, &payload
, 1,
95 static void ar9003_mci_send_req_wake(struct ath_hw
*ah
, bool wait_done
)
97 ar9003_mci_send_message(ah
, MCI_REQ_WAKE
, MCI_FLAG_DISABLE_TIMESTAMP
,
98 NULL
, 0, wait_done
, false);
102 static void ar9003_mci_send_sys_waking(struct ath_hw
*ah
, bool wait_done
)
104 ar9003_mci_send_message(ah
, MCI_SYS_WAKING
, MCI_FLAG_DISABLE_TIMESTAMP
,
105 NULL
, 0, wait_done
, false);
108 static void ar9003_mci_send_lna_take(struct ath_hw
*ah
, bool wait_done
)
110 u32 payload
= 0x70000000;
112 ar9003_mci_send_message(ah
, MCI_LNA_TAKE
, 0, &payload
, 1,
116 static void ar9003_mci_send_sys_sleeping(struct ath_hw
*ah
, bool wait_done
)
118 ar9003_mci_send_message(ah
, MCI_SYS_SLEEPING
,
119 MCI_FLAG_DISABLE_TIMESTAMP
,
120 NULL
, 0, wait_done
, false);
123 static void ar9003_mci_send_coex_version_query(struct ath_hw
*ah
,
126 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
127 u32 payload
[4] = {0, 0, 0, 0};
129 if (mci
->bt_version_known
||
130 (mci
->bt_state
== MCI_BT_SLEEP
))
133 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
134 MCI_GPM_COEX_VERSION_QUERY
);
135 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
138 static void ar9003_mci_send_coex_version_response(struct ath_hw
*ah
,
141 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
142 u32 payload
[4] = {0, 0, 0, 0};
144 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
145 MCI_GPM_COEX_VERSION_RESPONSE
);
146 *(((u8
*)payload
) + MCI_GPM_COEX_B_MAJOR_VERSION
) =
148 *(((u8
*)payload
) + MCI_GPM_COEX_B_MINOR_VERSION
) =
150 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
153 static void ar9003_mci_send_coex_wlan_channels(struct ath_hw
*ah
,
156 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
157 u32
*payload
= &mci
->wlan_channels
[0];
159 if (!mci
->wlan_channels_update
||
160 (mci
->bt_state
== MCI_BT_SLEEP
))
163 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
164 MCI_GPM_COEX_WLAN_CHANNELS
);
165 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
166 MCI_GPM_SET_TYPE_OPCODE(payload
, 0xff, 0xff);
169 static void ar9003_mci_send_coex_bt_status_query(struct ath_hw
*ah
,
170 bool wait_done
, u8 query_type
)
172 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
173 u32 payload
[4] = {0, 0, 0, 0};
176 if (mci
->bt_state
== MCI_BT_SLEEP
)
179 query_btinfo
= !!(query_type
& (MCI_GPM_COEX_QUERY_BT_ALL_INFO
|
180 MCI_GPM_COEX_QUERY_BT_TOPOLOGY
));
181 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
182 MCI_GPM_COEX_STATUS_QUERY
);
184 *(((u8
*)payload
) + MCI_GPM_COEX_B_BT_BITMAP
) = query_type
;
187 * If bt_status_query message is not sent successfully,
188 * then need_flush_btinfo should be set again.
190 if (!ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
193 mci
->need_flush_btinfo
= true;
197 mci
->query_bt
= false;
200 static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw
*ah
, bool halt
,
203 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
204 u32 payload
[4] = {0, 0, 0, 0};
206 MCI_GPM_SET_TYPE_OPCODE(payload
, MCI_GPM_COEX_AGENT
,
207 MCI_GPM_COEX_HALT_BT_GPM
);
210 mci
->query_bt
= true;
211 /* Send next unhalt no matter halt sent or not */
212 mci
->unhalt_bt_gpm
= true;
213 mci
->need_flush_btinfo
= true;
214 *(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) =
215 MCI_GPM_COEX_BT_GPM_HALT
;
217 *(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) =
218 MCI_GPM_COEX_BT_GPM_UNHALT
;
220 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16, wait_done
, true);
223 static void ar9003_mci_prep_interface(struct ath_hw
*ah
)
225 struct ath_common
*common
= ath9k_hw_common(ah
);
226 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
227 u32 saved_mci_int_en
;
228 u32 mci_timeout
= 150;
230 mci
->bt_state
= MCI_BT_SLEEP
;
231 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
233 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
234 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
235 REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
));
236 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
237 REG_READ(ah
, AR_MCI_INTERRUPT_RAW
));
239 ar9003_mci_remote_reset(ah
, true);
240 ar9003_mci_send_req_wake(ah
, true);
242 if (!ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
243 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
, 500))
246 mci
->bt_state
= MCI_BT_AWAKE
;
249 * we don't need to send more remote_reset at this moment.
250 * If BT receive first remote_reset, then BT HW will
251 * be cleaned up and will be able to receive req_wake
252 * and BT HW will respond sys_waking.
253 * In this case, WLAN will receive BT's HW sys_waking.
254 * Otherwise, if BT SW missed initial remote_reset,
255 * that remote_reset will still clean up BT MCI RX,
256 * and the req_wake will wake BT up,
257 * and BT SW will respond this req_wake with a remote_reset and
258 * sys_waking. In this case, WLAN will receive BT's SW
259 * sys_waking. In either case, BT's RX is cleaned up. So we
260 * don't need to reply BT's remote_reset now, if any.
261 * Similarly, if in any case, WLAN can receive BT's sys_waking,
262 * that means WLAN's RX is also fine.
264 ar9003_mci_send_sys_waking(ah
, true);
268 * Set BT priority interrupt value to be 0xff to
269 * avoid having too many BT PRIORITY interrupts.
271 REG_WRITE(ah
, AR_MCI_BT_PRI0
, 0xFFFFFFFF);
272 REG_WRITE(ah
, AR_MCI_BT_PRI1
, 0xFFFFFFFF);
273 REG_WRITE(ah
, AR_MCI_BT_PRI2
, 0xFFFFFFFF);
274 REG_WRITE(ah
, AR_MCI_BT_PRI3
, 0xFFFFFFFF);
275 REG_WRITE(ah
, AR_MCI_BT_PRI
, 0X000000FF);
278 * A contention reset will be received after send out
279 * sys_waking. Also BT priority interrupt bits will be set.
280 * Clear those bits before the next step.
283 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
284 AR_MCI_INTERRUPT_RX_MSG_CONT_RST
);
285 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
, AR_MCI_INTERRUPT_BT_PRI
);
288 ar9003_mci_send_lna_transfer(ah
, true);
292 if ((mci
->is_2g
&& !mci
->update_2g5g
)) {
293 if (ar9003_mci_wait_for_interrupt(ah
,
294 AR_MCI_INTERRUPT_RX_MSG_RAW
,
295 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO
,
298 "MCI WLAN has control over the LNA & BT obeys it\n");
301 "MCI BT didn't respond to LNA_TRANS\n");
305 /* Clear the extra redundant SYS_WAKING from BT */
306 if ((mci
->bt_state
== MCI_BT_AWAKE
) &&
307 (REG_READ_FIELD(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
308 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
)) &&
309 (REG_READ_FIELD(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
310 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING
) == 0)) {
311 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
312 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING
);
313 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
314 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE
);
317 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
320 void ar9003_mci_set_full_sleep(struct ath_hw
*ah
)
322 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
324 if (ar9003_mci_state(ah
, MCI_STATE_ENABLE
) &&
325 (mci
->bt_state
!= MCI_BT_SLEEP
) &&
326 !mci
->halted_bt_gpm
) {
327 ar9003_mci_send_coex_halt_bt_gpm(ah
, true, true);
333 static void ar9003_mci_disable_interrupt(struct ath_hw
*ah
)
335 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
336 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_EN
, 0);
339 static void ar9003_mci_enable_interrupt(struct ath_hw
*ah
)
341 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, AR_MCI_INTERRUPT_DEFAULT
);
342 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_EN
,
343 AR_MCI_INTERRUPT_RX_MSG_DEFAULT
);
346 static bool ar9003_mci_check_int(struct ath_hw
*ah
, u32 ints
)
350 intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
);
351 return ((intr
& ints
) == ints
);
354 void ar9003_mci_get_interrupt(struct ath_hw
*ah
, u32
*raw_intr
,
357 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
359 *raw_intr
= mci
->raw_intr
;
360 *rx_msg_intr
= mci
->rx_msg_intr
;
362 /* Clean int bits after the values are read. */
364 mci
->rx_msg_intr
= 0;
366 EXPORT_SYMBOL(ar9003_mci_get_interrupt
);
368 void ar9003_mci_get_isr(struct ath_hw
*ah
, enum ath9k_int
*masked
)
370 struct ath_common
*common
= ath9k_hw_common(ah
);
371 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
372 u32 raw_intr
, rx_msg_intr
;
374 rx_msg_intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
);
375 raw_intr
= REG_READ(ah
, AR_MCI_INTERRUPT_RAW
);
377 if ((raw_intr
== 0xdeadbeef) || (rx_msg_intr
== 0xdeadbeef)) {
379 "MCI gets 0xdeadbeef during int processing\n");
381 mci
->rx_msg_intr
|= rx_msg_intr
;
382 mci
->raw_intr
|= raw_intr
;
383 *masked
|= ATH9K_INT_MCI
;
385 if (rx_msg_intr
& AR_MCI_INTERRUPT_RX_MSG_CONT_INFO
)
386 mci
->cont_status
= REG_READ(ah
, AR_MCI_CONT_STATUS
);
388 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
, rx_msg_intr
);
389 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
, raw_intr
);
393 static void ar9003_mci_2g5g_changed(struct ath_hw
*ah
, bool is_2g
)
395 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
397 if (!mci
->update_2g5g
&&
398 (mci
->is_2g
!= is_2g
))
399 mci
->update_2g5g
= true;
404 static bool ar9003_mci_is_gpm_valid(struct ath_hw
*ah
, u32 msg_index
)
406 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
408 u32 recv_type
, offset
;
410 if (msg_index
== MCI_GPM_INVALID
)
413 offset
= msg_index
<< 4;
415 payload
= (u32
*)(mci
->gpm_buf
+ offset
);
416 recv_type
= MCI_GPM_TYPE(payload
);
418 if (recv_type
== MCI_GPM_RSVD_PATTERN
)
424 static void ar9003_mci_observation_set_up(struct ath_hw
*ah
)
426 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
428 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MCI
) {
429 ath9k_hw_cfg_output(ah
, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA
);
430 ath9k_hw_cfg_output(ah
, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK
);
431 ath9k_hw_cfg_output(ah
, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA
);
432 ath9k_hw_cfg_output(ah
, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK
);
433 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_TXRX
) {
434 ath9k_hw_cfg_output(ah
, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX
);
435 ath9k_hw_cfg_output(ah
, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX
);
436 ath9k_hw_cfg_output(ah
, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX
);
437 ath9k_hw_cfg_output(ah
, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX
);
438 ath9k_hw_cfg_output(ah
, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT
);
439 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_BT
) {
440 ath9k_hw_cfg_output(ah
, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX
);
441 ath9k_hw_cfg_output(ah
, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX
);
442 ath9k_hw_cfg_output(ah
, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA
);
443 ath9k_hw_cfg_output(ah
, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK
);
447 REG_SET_BIT(ah
, AR_GPIO_INPUT_EN_VAL
, AR_GPIO_JTAG_DISABLE
);
449 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
, AR_GLB_DS_JTAG_DISABLE
, 1);
450 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
, AR_GLB_WLAN_UART_INTF_EN
, 0);
451 REG_SET_BIT(ah
, AR_GLB_GPIO_CONTROL
, ATH_MCI_CONFIG_MCI_OBS_GPIO
);
453 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_GPIO_OBS_SEL
, 0);
454 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL
, 1);
455 REG_WRITE(ah
, AR_OBS
, 0x4b);
456 REG_RMW_FIELD(ah
, AR_DIAG_SW
, AR_DIAG_OBS_PT_SEL1
, 0x03);
457 REG_RMW_FIELD(ah
, AR_DIAG_SW
, AR_DIAG_OBS_PT_SEL2
, 0x01);
458 REG_RMW_FIELD(ah
, AR_MACMISC
, AR_MACMISC_MISC_OBS_BUS_LSB
, 0x02);
459 REG_RMW_FIELD(ah
, AR_MACMISC
, AR_MACMISC_MISC_OBS_BUS_MSB
, 0x03);
460 REG_RMW_FIELD(ah
, AR_PHY_TEST_CTL_STATUS
,
461 AR_PHY_TEST_CTL_DEBUGPORT_SEL
, 0x07);
464 static bool ar9003_mci_send_coex_bt_flags(struct ath_hw
*ah
, bool wait_done
,
465 u8 opcode
, u32 bt_flags
)
467 u32 pld
[4] = {0, 0, 0, 0};
469 MCI_GPM_SET_TYPE_OPCODE(pld
, MCI_GPM_COEX_AGENT
,
470 MCI_GPM_COEX_BT_UPDATE_FLAGS
);
472 *(((u8
*)pld
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) = opcode
;
473 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 0) = bt_flags
& 0xFF;
474 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 1) = (bt_flags
>> 8) & 0xFF;
475 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 2) = (bt_flags
>> 16) & 0xFF;
476 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 3) = (bt_flags
>> 24) & 0xFF;
478 return ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16,
482 static void ar9003_mci_sync_bt_state(struct ath_hw
*ah
)
484 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
487 cur_bt_state
= ar9003_mci_state(ah
, MCI_STATE_REMOTE_SLEEP
);
489 if (mci
->bt_state
!= cur_bt_state
)
490 mci
->bt_state
= cur_bt_state
;
492 if (mci
->bt_state
!= MCI_BT_SLEEP
) {
494 ar9003_mci_send_coex_version_query(ah
, true);
495 ar9003_mci_send_coex_wlan_channels(ah
, true);
497 if (mci
->unhalt_bt_gpm
== true)
498 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
502 void ar9003_mci_check_bt(struct ath_hw
*ah
)
504 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
510 * check BT state again to make
511 * sure it's not changed.
513 ar9003_mci_sync_bt_state(ah
);
514 ar9003_mci_2g5g_switch(ah
, true);
516 if ((mci_hw
->bt_state
== MCI_BT_AWAKE
) &&
517 (mci_hw
->query_bt
== true)) {
518 mci_hw
->need_flush_btinfo
= true;
522 static void ar9003_mci_process_gpm_extra(struct ath_hw
*ah
, u8 gpm_type
,
523 u8 gpm_opcode
, u32
*p_gpm
)
525 struct ath_common
*common
= ath9k_hw_common(ah
);
526 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
527 u8
*p_data
= (u8
*) p_gpm
;
529 if (gpm_type
!= MCI_GPM_COEX_AGENT
)
532 switch (gpm_opcode
) {
533 case MCI_GPM_COEX_VERSION_QUERY
:
534 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Query\n");
535 ar9003_mci_send_coex_version_response(ah
, true);
537 case MCI_GPM_COEX_VERSION_RESPONSE
:
538 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Response\n");
540 *(p_data
+ MCI_GPM_COEX_B_MAJOR_VERSION
);
542 *(p_data
+ MCI_GPM_COEX_B_MINOR_VERSION
);
543 mci
->bt_version_known
= true;
544 ath_dbg(common
, MCI
, "MCI BT Coex version: %d.%d\n",
545 mci
->bt_ver_major
, mci
->bt_ver_minor
);
547 case MCI_GPM_COEX_STATUS_QUERY
:
549 "MCI Recv GPM COEX Status Query = 0x%02X\n",
550 *(p_data
+ MCI_GPM_COEX_B_WLAN_BITMAP
));
551 mci
->wlan_channels_update
= true;
552 ar9003_mci_send_coex_wlan_channels(ah
, true);
554 case MCI_GPM_COEX_BT_PROFILE_INFO
:
555 mci
->query_bt
= true;
556 ath_dbg(common
, MCI
, "MCI Recv GPM COEX BT_Profile_Info\n");
558 case MCI_GPM_COEX_BT_STATUS_UPDATE
:
559 mci
->query_bt
= true;
561 "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
569 static u32
ar9003_mci_wait_for_gpm(struct ath_hw
*ah
, u8 gpm_type
,
570 u8 gpm_opcode
, int time_out
)
572 struct ath_common
*common
= ath9k_hw_common(ah
);
573 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
574 u32
*p_gpm
= NULL
, mismatch
= 0, more_data
;
576 u8 recv_type
= 0, recv_opcode
= 0;
577 bool b_is_bt_cal_done
= (gpm_type
== MCI_GPM_BT_CAL_DONE
);
579 more_data
= time_out
? MCI_GPM_NOMORE
: MCI_GPM_MORE
;
581 while (time_out
> 0) {
583 MCI_GPM_RECYCLE(p_gpm
);
587 if (more_data
!= MCI_GPM_MORE
)
588 time_out
= ar9003_mci_wait_for_interrupt(ah
,
589 AR_MCI_INTERRUPT_RX_MSG_RAW
,
590 AR_MCI_INTERRUPT_RX_MSG_GPM
,
596 offset
= ar9003_mci_get_next_gpm_offset(ah
, false, &more_data
);
598 if (offset
== MCI_GPM_INVALID
)
601 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
602 recv_type
= MCI_GPM_TYPE(p_gpm
);
603 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
605 if (MCI_GPM_IS_CAL_TYPE(recv_type
)) {
606 if (recv_type
== gpm_type
) {
607 if ((gpm_type
== MCI_GPM_BT_CAL_DONE
) &&
609 gpm_type
= MCI_GPM_BT_CAL_GRANT
;
614 } else if ((recv_type
== gpm_type
) &&
615 (recv_opcode
== gpm_opcode
))
619 * check if it's cal_grant
621 * When we're waiting for cal_grant in reset routine,
622 * it's possible that BT sends out cal_request at the
623 * same time. Since BT's calibration doesn't happen
624 * that often, we'll let BT completes calibration then
625 * we continue to wait for cal_grant from BT.
626 * Orginal: Wait BT_CAL_GRANT.
627 * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
628 * BT_CAL_DONE -> Wait BT_CAL_GRANT.
631 if ((gpm_type
== MCI_GPM_BT_CAL_GRANT
) &&
632 (recv_type
== MCI_GPM_BT_CAL_REQ
)) {
634 u32 payload
[4] = {0, 0, 0, 0};
636 gpm_type
= MCI_GPM_BT_CAL_DONE
;
637 MCI_GPM_SET_CAL_TYPE(payload
,
638 MCI_GPM_WLAN_CAL_GRANT
);
639 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
643 ath_dbg(common
, MCI
, "MCI GPM subtype not match 0x%x\n",
646 ar9003_mci_process_gpm_extra(ah
, recv_type
,
652 MCI_GPM_RECYCLE(p_gpm
);
659 while (more_data
== MCI_GPM_MORE
) {
660 offset
= ar9003_mci_get_next_gpm_offset(ah
, false, &more_data
);
661 if (offset
== MCI_GPM_INVALID
)
664 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
665 recv_type
= MCI_GPM_TYPE(p_gpm
);
666 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
668 if (!MCI_GPM_IS_CAL_TYPE(recv_type
))
669 ar9003_mci_process_gpm_extra(ah
, recv_type
,
672 MCI_GPM_RECYCLE(p_gpm
);
678 bool ar9003_mci_start_reset(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
680 struct ath_common
*common
= ath9k_hw_common(ah
);
681 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
682 u32 payload
[4] = {0, 0, 0, 0};
684 ar9003_mci_2g5g_changed(ah
, IS_CHAN_2GHZ(chan
));
686 if (mci_hw
->bt_state
!= MCI_BT_CAL_START
)
689 mci_hw
->bt_state
= MCI_BT_CAL
;
692 * MCI FIX: disable mci interrupt here. This is to avoid
693 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
694 * lead to mci_intr reentry.
696 ar9003_mci_disable_interrupt(ah
);
698 MCI_GPM_SET_CAL_TYPE(payload
, MCI_GPM_WLAN_CAL_GRANT
);
699 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
,
702 /* Wait BT calibration to be completed for 25ms */
704 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_DONE
,
706 ath_dbg(common
, MCI
, "MCI BT_CAL_DONE received\n");
709 "MCI BT_CAL_DONE not received\n");
711 mci_hw
->bt_state
= MCI_BT_AWAKE
;
712 /* MCI FIX: enable mci interrupt here */
713 ar9003_mci_enable_interrupt(ah
);
718 int ar9003_mci_end_reset(struct ath_hw
*ah
, struct ath9k_channel
*chan
,
719 struct ath9k_hw_cal_data
*caldata
)
721 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
726 if (!IS_CHAN_2GHZ(chan
) || (mci_hw
->bt_state
!= MCI_BT_SLEEP
))
729 if (!ar9003_mci_check_int(ah
, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET
) &&
730 !ar9003_mci_check_int(ah
, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
))
734 * BT is sleeping. Check if BT wakes up during
735 * WLAN calibration. If BT wakes up during
736 * WLAN calibration, need to go through all
737 * message exchanges again and recal.
739 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
740 (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET
|
741 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
));
743 ar9003_mci_remote_reset(ah
, true);
744 ar9003_mci_send_sys_waking(ah
, true);
747 if (IS_CHAN_2GHZ(chan
))
748 ar9003_mci_send_lna_transfer(ah
, true);
750 mci_hw
->bt_state
= MCI_BT_AWAKE
;
753 caldata
->done_txiqcal_once
= false;
754 caldata
->done_txclcal_once
= false;
755 caldata
->rtt_done
= false;
758 if (!ath9k_hw_init_cal(ah
, chan
))
762 ar9003_mci_enable_interrupt(ah
);
766 static void ar9003_mci_mute_bt(struct ath_hw
*ah
)
768 /* disable all MCI messages */
769 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
, 0xffff0000);
770 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
772 /* wait pending HW messages to flush out */
776 * Send LNA_TAKE and SYS_SLEEPING when
777 * 1. reset not after resuming from full sleep
778 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
780 ar9003_mci_send_lna_take(ah
, true);
784 ar9003_mci_send_sys_sleeping(ah
, true);
787 static void ar9003_mci_osla_setup(struct ath_hw
*ah
, bool enable
)
789 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
793 REG_CLR_BIT(ah
, AR_BTCOEX_CTRL
,
794 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
797 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
, AR_MCI_SCHD_TABLE_2_HW_BASED
, 1);
798 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
,
799 AR_MCI_SCHD_TABLE_2_MEM_BASED
, 1);
801 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_AGGR_THRESH
)) {
802 thresh
= MS(mci
->config
, ATH_MCI_CONFIG_AGGR_THRESH
);
803 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
804 AR_BTCOEX_CTRL_AGGR_THRESH
, thresh
);
805 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
806 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 1);
808 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
809 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 0);
811 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
812 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
, 1);
815 void ar9003_mci_reset(struct ath_hw
*ah
, bool en_int
, bool is_2g
,
818 struct ath_common
*common
= ath9k_hw_common(ah
);
819 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
822 ath_dbg(common
, MCI
, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
823 is_full_sleep
, is_2g
);
825 if (!mci
->gpm_addr
&& !mci
->sched_addr
) {
827 "MCI GPM and schedule buffers are not allocated\n");
831 if (REG_READ(ah
, AR_BTCOEX_CTRL
) == 0xdeadbeef) {
832 ath_dbg(common
, MCI
, "BTCOEX control register is dead\n");
836 /* Program MCI DMA related registers */
837 REG_WRITE(ah
, AR_MCI_GPM_0
, mci
->gpm_addr
);
838 REG_WRITE(ah
, AR_MCI_GPM_1
, mci
->gpm_len
);
839 REG_WRITE(ah
, AR_MCI_SCHD_TABLE_0
, mci
->sched_addr
);
842 * To avoid MCI state machine be affected by incoming remote MCI msgs,
843 * MCI mode will be enabled later, right before reset the MCI TX and RX.
846 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
847 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
848 SM(1, AR_BTCOEX_CTRL_PA_SHARED
) |
849 SM(1, AR_BTCOEX_CTRL_LNA_SHARED
) |
850 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
851 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
852 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
853 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
854 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
856 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
858 if (is_2g
&& !(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
859 ar9003_mci_osla_setup(ah
, true);
861 ar9003_mci_osla_setup(ah
, false);
863 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
864 AR_BTCOEX_CTRL_SPDT_ENABLE
);
865 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL3
,
866 AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT
, 20);
868 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_RX_DEWEIGHT
, 1);
869 REG_RMW_FIELD(ah
, AR_PCU_MISC
, AR_PCU_BT_ANT_PREVENT_RX
, 0);
871 regval
= MS(mci
->config
, ATH_MCI_CONFIG_CLK_DIV
);
872 REG_RMW_FIELD(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_CLK_DIV
, regval
);
873 REG_SET_BIT(ah
, AR_BTCOEX_CTRL
, AR_BTCOEX_CTRL_MCI_MODE_EN
);
875 /* Resetting the Rx and Tx paths of MCI */
876 regval
= REG_READ(ah
, AR_MCI_COMMAND2
);
877 regval
|= SM(1, AR_MCI_COMMAND2_RESET_TX
);
878 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
882 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_TX
);
883 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
886 ar9003_mci_mute_bt(ah
);
890 /* Check pending GPM msg before MCI Reset Rx */
891 ar9003_mci_check_gpm_offset(ah
);
893 regval
|= SM(1, AR_MCI_COMMAND2_RESET_RX
);
894 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
896 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_RX
);
897 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
899 ar9003_mci_get_next_gpm_offset(ah
, true, NULL
);
901 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
,
902 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR
) |
903 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM
)));
905 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
906 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
908 ar9003_mci_observation_set_up(ah
);
911 ar9003_mci_prep_interface(ah
);
914 ar9003_mci_enable_interrupt(ah
);
917 void ar9003_mci_stop_bt(struct ath_hw
*ah
, bool save_fullsleep
)
919 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
921 ar9003_mci_disable_interrupt(ah
);
923 if (mci_hw
->ready
&& !save_fullsleep
) {
924 ar9003_mci_mute_bt(ah
);
926 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0);
929 mci_hw
->bt_state
= MCI_BT_SLEEP
;
930 mci_hw
->ready
= false;
933 static void ar9003_mci_send_2g5g_status(struct ath_hw
*ah
, bool wait_done
)
935 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
936 u32 new_flags
, to_set
, to_clear
;
938 if (!mci
->update_2g5g
|| (mci
->bt_state
== MCI_BT_SLEEP
))
942 new_flags
= MCI_2G_FLAGS
;
943 to_clear
= MCI_2G_FLAGS_CLEAR_MASK
;
944 to_set
= MCI_2G_FLAGS_SET_MASK
;
946 new_flags
= MCI_5G_FLAGS
;
947 to_clear
= MCI_5G_FLAGS_CLEAR_MASK
;
948 to_set
= MCI_5G_FLAGS_SET_MASK
;
952 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
953 MCI_GPM_COEX_BT_FLAGS_CLEAR
,
956 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
957 MCI_GPM_COEX_BT_FLAGS_SET
,
961 static void ar9003_mci_queue_unsent_gpm(struct ath_hw
*ah
, u8 header
,
962 u32
*payload
, bool queue
)
964 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
967 /* check if the message is to be queued */
968 if (header
!= MCI_GPM
)
971 type
= MCI_GPM_TYPE(payload
);
972 opcode
= MCI_GPM_OPCODE(payload
);
974 if (type
!= MCI_GPM_COEX_AGENT
)
978 case MCI_GPM_COEX_BT_UPDATE_FLAGS
:
979 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) ==
980 MCI_GPM_COEX_BT_FLAGS_READ
)
983 mci
->update_2g5g
= queue
;
986 case MCI_GPM_COEX_WLAN_CHANNELS
:
987 mci
->wlan_channels_update
= queue
;
989 case MCI_GPM_COEX_HALT_BT_GPM
:
990 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
991 MCI_GPM_COEX_BT_GPM_UNHALT
) {
992 mci
->unhalt_bt_gpm
= queue
;
995 mci
->halted_bt_gpm
= false;
998 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
999 MCI_GPM_COEX_BT_GPM_HALT
) {
1001 mci
->halted_bt_gpm
= !queue
;
1010 void ar9003_mci_2g5g_switch(struct ath_hw
*ah
, bool force
)
1012 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1014 if (!mci
->update_2g5g
&& !force
)
1018 ar9003_mci_send_2g5g_status(ah
, true);
1019 ar9003_mci_send_lna_transfer(ah
, true);
1022 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
1023 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1024 REG_CLR_BIT(ah
, AR_PHY_GLB_CONTROL
,
1025 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1027 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
1028 ar9003_mci_osla_setup(ah
, true);
1030 ar9003_mci_send_lna_take(ah
, true);
1033 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
1034 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1035 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
1036 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1038 ar9003_mci_osla_setup(ah
, false);
1039 ar9003_mci_send_2g5g_status(ah
, true);
1043 bool ar9003_mci_send_message(struct ath_hw
*ah
, u8 header
, u32 flag
,
1044 u32
*payload
, u8 len
, bool wait_done
,
1047 struct ath_common
*common
= ath9k_hw_common(ah
);
1048 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1049 bool msg_sent
= false;
1051 u32 saved_mci_int_en
;
1054 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
1055 regval
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1057 if ((regval
== 0xdeadbeef) || !(regval
& AR_BTCOEX_CTRL_MCI_MODE_EN
)) {
1058 ath_dbg(common
, MCI
,
1059 "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
1060 header
, (ah
->power_mode
== ATH9K_PM_FULL_SLEEP
) ? 1 : 0);
1061 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1063 } else if (check_bt
&& (mci
->bt_state
== MCI_BT_SLEEP
)) {
1064 ath_dbg(common
, MCI
,
1065 "MCI Don't send message 0x%x. BT is in sleep state\n",
1067 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1072 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
1074 /* Need to clear SW_MSG_DONE raw bit before wait */
1076 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
1077 (AR_MCI_INTERRUPT_SW_MSG_DONE
|
1078 AR_MCI_INTERRUPT_MSG_FAIL_MASK
));
1081 for (i
= 0; (i
* 4) < len
; i
++)
1082 REG_WRITE(ah
, (AR_MCI_TX_PAYLOAD0
+ i
* 4),
1086 REG_WRITE(ah
, AR_MCI_COMMAND0
,
1087 (SM((flag
& MCI_FLAG_DISABLE_TIMESTAMP
),
1088 AR_MCI_COMMAND0_DISABLE_TIMESTAMP
) |
1089 SM(len
, AR_MCI_COMMAND0_LEN
) |
1090 SM(header
, AR_MCI_COMMAND0_HEADER
)));
1093 !(ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RAW
,
1094 AR_MCI_INTERRUPT_SW_MSG_DONE
, 500)))
1095 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1097 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, false);
1102 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
1106 EXPORT_SYMBOL(ar9003_mci_send_message
);
1108 void ar9003_mci_init_cal_req(struct ath_hw
*ah
, bool *is_reusable
)
1110 struct ath_common
*common
= ath9k_hw_common(ah
);
1111 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1112 u32 pld
[4] = {0, 0, 0, 0};
1114 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1115 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1118 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_REQ
);
1119 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_seq
++;
1121 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1123 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_GRANT
, 0, 50000)) {
1124 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT received\n");
1126 *is_reusable
= false;
1127 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT not received\n");
1131 void ar9003_mci_init_cal_done(struct ath_hw
*ah
)
1133 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1134 u32 pld
[4] = {0, 0, 0, 0};
1136 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1137 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1140 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_DONE
);
1141 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_done
++;
1142 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1145 void ar9003_mci_setup(struct ath_hw
*ah
, u32 gpm_addr
, void *gpm_buf
,
1146 u16 len
, u32 sched_addr
)
1148 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1150 mci
->gpm_addr
= gpm_addr
;
1151 mci
->gpm_buf
= gpm_buf
;
1153 mci
->sched_addr
= sched_addr
;
1155 ar9003_mci_reset(ah
, true, true, true);
1157 EXPORT_SYMBOL(ar9003_mci_setup
);
1159 void ar9003_mci_cleanup(struct ath_hw
*ah
)
1161 /* Turn off MCI and Jupiter mode. */
1162 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0x00);
1163 ar9003_mci_disable_interrupt(ah
);
1165 EXPORT_SYMBOL(ar9003_mci_cleanup
);
1167 u32
ar9003_mci_state(struct ath_hw
*ah
, u32 state_type
)
1169 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1173 switch (state_type
) {
1174 case MCI_STATE_ENABLE
:
1176 value
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1178 if ((value
== 0xdeadbeef) || (value
== 0xffffffff))
1181 value
&= AR_BTCOEX_CTRL_MCI_MODE_EN
;
1183 case MCI_STATE_LAST_SCHD_MSG_OFFSET
:
1184 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1185 AR_MCI_RX_LAST_SCHD_MSG_INDEX
);
1186 /* Make it in bytes */
1189 case MCI_STATE_REMOTE_SLEEP
:
1190 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1191 AR_MCI_RX_REMOTE_SLEEP
) ?
1192 MCI_BT_SLEEP
: MCI_BT_AWAKE
;
1194 case MCI_STATE_SET_BT_AWAKE
:
1195 mci
->bt_state
= MCI_BT_AWAKE
;
1196 ar9003_mci_send_coex_version_query(ah
, true);
1197 ar9003_mci_send_coex_wlan_channels(ah
, true);
1199 if (mci
->unhalt_bt_gpm
)
1200 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
1202 ar9003_mci_2g5g_switch(ah
, false);
1204 case MCI_STATE_SET_BT_CAL_START
:
1205 mci
->bt_state
= MCI_BT_CAL_START
;
1207 case MCI_STATE_SET_BT_CAL
:
1208 mci
->bt_state
= MCI_BT_CAL
;
1210 case MCI_STATE_RESET_REQ_WAKE
:
1211 ar9003_mci_reset_req_wakeup(ah
);
1212 mci
->update_2g5g
= true;
1214 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MASK
) {
1215 /* Check if we still have control of the GPIOs */
1216 if ((REG_READ(ah
, AR_GLB_GPIO_CONTROL
) &
1217 ATH_MCI_CONFIG_MCI_OBS_GPIO
) !=
1218 ATH_MCI_CONFIG_MCI_OBS_GPIO
) {
1219 ar9003_mci_observation_set_up(ah
);
1223 case MCI_STATE_SEND_WLAN_COEX_VERSION
:
1224 ar9003_mci_send_coex_version_response(ah
, true);
1226 case MCI_STATE_SEND_VERSION_QUERY
:
1227 ar9003_mci_send_coex_version_query(ah
, true);
1229 case MCI_STATE_SEND_STATUS_QUERY
:
1230 query_type
= MCI_GPM_COEX_QUERY_BT_TOPOLOGY
;
1231 ar9003_mci_send_coex_bt_status_query(ah
, true, query_type
);
1233 case MCI_STATE_RECOVER_RX
:
1234 ar9003_mci_prep_interface(ah
);
1235 mci
->query_bt
= true;
1236 mci
->need_flush_btinfo
= true;
1237 ar9003_mci_send_coex_wlan_channels(ah
, true);
1238 ar9003_mci_2g5g_switch(ah
, false);
1240 case MCI_STATE_NEED_FTP_STOMP
:
1241 value
= !(mci
->config
& ATH_MCI_CONFIG_DISABLE_FTP_STOMP
);
1249 EXPORT_SYMBOL(ar9003_mci_state
);
1251 void ar9003_mci_bt_gain_ctrl(struct ath_hw
*ah
)
1253 struct ath_common
*common
= ath9k_hw_common(ah
);
1254 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1256 ath_dbg(common
, MCI
, "Give LNA and SPDT control to BT\n");
1258 ar9003_mci_send_lna_take(ah
, true);
1261 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1263 mci
->update_2g5g
= true;
1264 ar9003_mci_send_2g5g_status(ah
, true);
1266 /* Force another 2g5g update at next scanning */
1267 mci
->update_2g5g
= true;
1270 void ar9003_mci_set_power_awake(struct ath_hw
*ah
)
1272 u32 btcoex_ctrl2
, diag_sw
;
1274 u8 lna_ctrl
, bt_sleep
;
1276 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1277 btcoex_ctrl2
= REG_READ(ah
, AR_BTCOEX_CTRL2
);
1278 if (btcoex_ctrl2
!= 0xdeadbeef)
1280 udelay(AH_TIME_QUANTUM
);
1282 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, (btcoex_ctrl2
| BIT(23)));
1284 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1285 diag_sw
= REG_READ(ah
, AR_DIAG_SW
);
1286 if (diag_sw
!= 0xdeadbeef)
1288 udelay(AH_TIME_QUANTUM
);
1290 REG_WRITE(ah
, AR_DIAG_SW
, (diag_sw
| BIT(27) | BIT(19) | BIT(18)));
1291 lna_ctrl
= REG_READ(ah
, AR_OBS_BUS_CTRL
) & 0x3;
1292 bt_sleep
= REG_READ(ah
, AR_MCI_RX_STATUS
) & AR_MCI_RX_REMOTE_SLEEP
;
1294 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, btcoex_ctrl2
);
1295 REG_WRITE(ah
, AR_DIAG_SW
, diag_sw
);
1297 if (bt_sleep
&& (lna_ctrl
== 2)) {
1298 REG_SET_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1299 REG_CLR_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1304 void ar9003_mci_check_gpm_offset(struct ath_hw
*ah
)
1306 struct ath_common
*common
= ath9k_hw_common(ah
);
1307 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1311 * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
1313 offset
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1314 if (mci
->gpm_idx
== offset
)
1316 ath_dbg(common
, MCI
, "GPM cached write pointer mismatch %d %d\n",
1317 mci
->gpm_idx
, offset
);
1318 mci
->query_bt
= true;
1319 mci
->need_flush_btinfo
= true;
1323 u32
ar9003_mci_get_next_gpm_offset(struct ath_hw
*ah
, bool first
, u32
*more
)
1325 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1326 u32 offset
, more_gpm
= 0, gpm_ptr
;
1329 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1330 mci
->gpm_idx
= gpm_ptr
;
1335 * This could be useful to avoid new GPM message interrupt which
1336 * may lead to spurious interrupt after power sleep, or multiple
1337 * entry of ath_mci_intr().
1338 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1339 * alleviate this effect, but clearing GPM RX interrupt bit is
1340 * safe, because whether this is called from hw or driver code
1341 * there must be an interrupt bit set/triggered initially
1343 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
1344 AR_MCI_INTERRUPT_RX_MSG_GPM
);
1346 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1350 offset
= mci
->gpm_len
- 1;
1351 else if (offset
>= mci
->gpm_len
) {
1352 if (offset
!= 0xFFFF)
1358 if ((offset
== 0xFFFF) || (gpm_ptr
== mci
->gpm_idx
)) {
1359 offset
= MCI_GPM_INVALID
;
1360 more_gpm
= MCI_GPM_NOMORE
;
1366 /* skip reserved GPM if any */
1368 if (offset
!= mci
->gpm_idx
)
1369 more_gpm
= MCI_GPM_MORE
;
1371 more_gpm
= MCI_GPM_NOMORE
;
1373 temp_index
= mci
->gpm_idx
;
1376 if (mci
->gpm_idx
>= mci
->gpm_len
)
1379 if (ar9003_mci_is_gpm_valid(ah
, temp_index
)) {
1380 offset
= temp_index
;
1384 if (more_gpm
== MCI_GPM_NOMORE
) {
1385 offset
= MCI_GPM_INVALID
;
1390 if (offset
!= MCI_GPM_INVALID
)
1398 EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset
);
1400 void ar9003_mci_set_bt_version(struct ath_hw
*ah
, u8 major
, u8 minor
)
1402 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1404 mci
->bt_ver_major
= major
;
1405 mci
->bt_ver_minor
= minor
;
1406 mci
->bt_version_known
= true;
1407 ath_dbg(ath9k_hw_common(ah
), MCI
, "MCI BT version set: %d.%d\n",
1408 mci
->bt_ver_major
, mci
->bt_ver_minor
);
1410 EXPORT_SYMBOL(ar9003_mci_set_bt_version
);
1412 void ar9003_mci_send_wlan_channels(struct ath_hw
*ah
)
1414 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1416 mci
->wlan_channels_update
= true;
1417 ar9003_mci_send_coex_wlan_channels(ah
, true);
1419 EXPORT_SYMBOL(ar9003_mci_send_wlan_channels
);