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
;
752 REG_CLR_BIT(ah
, AR_PHY_TIMING4
,
753 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT
);
756 caldata
->done_txiqcal_once
= false;
757 caldata
->done_txclcal_once
= false;
758 caldata
->rtt_done
= false;
761 if (!ath9k_hw_init_cal(ah
, chan
))
764 REG_SET_BIT(ah
, AR_PHY_TIMING4
,
765 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT
);
768 ar9003_mci_enable_interrupt(ah
);
772 static void ar9003_mci_mute_bt(struct ath_hw
*ah
)
774 /* disable all MCI messages */
775 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
, 0xffff0000);
776 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
778 /* wait pending HW messages to flush out */
782 * Send LNA_TAKE and SYS_SLEEPING when
783 * 1. reset not after resuming from full sleep
784 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
786 ar9003_mci_send_lna_take(ah
, true);
790 ar9003_mci_send_sys_sleeping(ah
, true);
793 static void ar9003_mci_osla_setup(struct ath_hw
*ah
, bool enable
)
795 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
799 REG_CLR_BIT(ah
, AR_BTCOEX_CTRL
,
800 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
803 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
, AR_MCI_SCHD_TABLE_2_HW_BASED
, 1);
804 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
,
805 AR_MCI_SCHD_TABLE_2_MEM_BASED
, 1);
807 if (AR_SREV_9565(ah
))
808 REG_RMW_FIELD(ah
, AR_MCI_MISC
, AR_MCI_MISC_HW_FIX_EN
, 1);
810 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_AGGR_THRESH
)) {
811 thresh
= MS(mci
->config
, ATH_MCI_CONFIG_AGGR_THRESH
);
812 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
813 AR_BTCOEX_CTRL_AGGR_THRESH
, thresh
);
814 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
815 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 1);
817 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
818 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 0);
820 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
821 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
, 1);
824 int ar9003_mci_reset(struct ath_hw
*ah
, bool en_int
, bool is_2g
,
827 struct ath_common
*common
= ath9k_hw_common(ah
);
828 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
831 ath_dbg(common
, MCI
, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
832 is_full_sleep
, is_2g
);
834 if (!mci
->gpm_addr
&& !mci
->sched_addr
) {
835 ath_err(common
, "MCI GPM and schedule buffers are not allocated\n");
839 if (REG_READ(ah
, AR_BTCOEX_CTRL
) == 0xdeadbeef) {
840 ath_err(common
, "BTCOEX control register is dead\n");
844 /* Program MCI DMA related registers */
845 REG_WRITE(ah
, AR_MCI_GPM_0
, mci
->gpm_addr
);
846 REG_WRITE(ah
, AR_MCI_GPM_1
, mci
->gpm_len
);
847 REG_WRITE(ah
, AR_MCI_SCHD_TABLE_0
, mci
->sched_addr
);
850 * To avoid MCI state machine be affected by incoming remote MCI msgs,
851 * MCI mode will be enabled later, right before reset the MCI TX and RX.
854 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
855 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
856 SM(1, AR_BTCOEX_CTRL_PA_SHARED
) |
857 SM(1, AR_BTCOEX_CTRL_LNA_SHARED
) |
858 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
859 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
860 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
861 if (AR_SREV_9565(ah
)) {
862 regval
|= SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
863 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK
);
864 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
865 AR_BTCOEX_CTRL2_TX_CHAIN_MASK
, 0x1);
867 regval
|= SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
868 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK
);
871 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
873 if (is_2g
&& !(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
874 ar9003_mci_osla_setup(ah
, true);
876 ar9003_mci_osla_setup(ah
, false);
878 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
879 AR_BTCOEX_CTRL_SPDT_ENABLE
);
880 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL3
,
881 AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT
, 20);
883 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_RX_DEWEIGHT
, 0);
884 REG_RMW_FIELD(ah
, AR_PCU_MISC
, AR_PCU_BT_ANT_PREVENT_RX
, 0);
886 /* Set the time out to 3.125ms (5 BT slots) */
887 REG_RMW_FIELD(ah
, AR_BTCOEX_WL_LNA
, AR_BTCOEX_WL_LNA_TIMEOUT
, 0x3D090);
889 /* concurrent tx priority */
890 if (mci
->config
& ATH_MCI_CONFIG_CONCUR_TX
) {
891 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
892 AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE
, 0);
893 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
894 AR_BTCOEX_CTRL2_TXPWR_THRESH
, 0x7f);
895 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
896 AR_BTCOEX_CTRL_REDUCE_TXPWR
, 0);
897 for (i
= 0; i
< 8; i
++)
898 REG_WRITE(ah
, AR_BTCOEX_MAX_TXPWR(i
), 0x7f7f7f7f);
901 regval
= MS(mci
->config
, ATH_MCI_CONFIG_CLK_DIV
);
902 REG_RMW_FIELD(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_CLK_DIV
, regval
);
903 REG_SET_BIT(ah
, AR_BTCOEX_CTRL
, AR_BTCOEX_CTRL_MCI_MODE_EN
);
905 /* Resetting the Rx and Tx paths of MCI */
906 regval
= REG_READ(ah
, AR_MCI_COMMAND2
);
907 regval
|= SM(1, AR_MCI_COMMAND2_RESET_TX
);
908 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
912 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_TX
);
913 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
916 ar9003_mci_mute_bt(ah
);
920 /* Check pending GPM msg before MCI Reset Rx */
921 ar9003_mci_check_gpm_offset(ah
);
923 regval
|= SM(1, AR_MCI_COMMAND2_RESET_RX
);
924 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
926 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_RX
);
927 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
929 ar9003_mci_get_next_gpm_offset(ah
, true, NULL
);
931 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
,
932 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR
) |
933 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM
)));
935 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
936 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
938 ar9003_mci_observation_set_up(ah
);
941 ar9003_mci_prep_interface(ah
);
943 if (AR_SREV_9565(ah
))
944 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
945 AR_MCI_DBG_CNT_CTRL_ENABLE
, 0);
947 ar9003_mci_enable_interrupt(ah
);
952 void ar9003_mci_stop_bt(struct ath_hw
*ah
, bool save_fullsleep
)
954 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
956 ar9003_mci_disable_interrupt(ah
);
958 if (mci_hw
->ready
&& !save_fullsleep
) {
959 ar9003_mci_mute_bt(ah
);
961 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0);
964 mci_hw
->bt_state
= MCI_BT_SLEEP
;
965 mci_hw
->ready
= false;
968 static void ar9003_mci_send_2g5g_status(struct ath_hw
*ah
, bool wait_done
)
970 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
971 u32 new_flags
, to_set
, to_clear
;
973 if (!mci
->update_2g5g
|| (mci
->bt_state
== MCI_BT_SLEEP
))
977 new_flags
= MCI_2G_FLAGS
;
978 to_clear
= MCI_2G_FLAGS_CLEAR_MASK
;
979 to_set
= MCI_2G_FLAGS_SET_MASK
;
981 new_flags
= MCI_5G_FLAGS
;
982 to_clear
= MCI_5G_FLAGS_CLEAR_MASK
;
983 to_set
= MCI_5G_FLAGS_SET_MASK
;
987 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
988 MCI_GPM_COEX_BT_FLAGS_CLEAR
,
991 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
992 MCI_GPM_COEX_BT_FLAGS_SET
,
996 static void ar9003_mci_queue_unsent_gpm(struct ath_hw
*ah
, u8 header
,
997 u32
*payload
, bool queue
)
999 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1002 /* check if the message is to be queued */
1003 if (header
!= MCI_GPM
)
1006 type
= MCI_GPM_TYPE(payload
);
1007 opcode
= MCI_GPM_OPCODE(payload
);
1009 if (type
!= MCI_GPM_COEX_AGENT
)
1013 case MCI_GPM_COEX_BT_UPDATE_FLAGS
:
1014 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) ==
1015 MCI_GPM_COEX_BT_FLAGS_READ
)
1018 mci
->update_2g5g
= queue
;
1021 case MCI_GPM_COEX_WLAN_CHANNELS
:
1022 mci
->wlan_channels_update
= queue
;
1024 case MCI_GPM_COEX_HALT_BT_GPM
:
1025 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
1026 MCI_GPM_COEX_BT_GPM_UNHALT
) {
1027 mci
->unhalt_bt_gpm
= queue
;
1030 mci
->halted_bt_gpm
= false;
1033 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
1034 MCI_GPM_COEX_BT_GPM_HALT
) {
1036 mci
->halted_bt_gpm
= !queue
;
1045 void ar9003_mci_2g5g_switch(struct ath_hw
*ah
, bool force
)
1047 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1049 if (!mci
->update_2g5g
&& !force
)
1053 ar9003_mci_send_2g5g_status(ah
, true);
1054 ar9003_mci_send_lna_transfer(ah
, true);
1057 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
1058 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1059 REG_CLR_BIT(ah
, AR_PHY_GLB_CONTROL
,
1060 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1062 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
1063 ar9003_mci_osla_setup(ah
, true);
1065 if (AR_SREV_9462(ah
))
1066 REG_WRITE(ah
, AR_SELFGEN_MASK
, 0x02);
1068 ar9003_mci_send_lna_take(ah
, true);
1071 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
1072 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1073 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
1074 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1076 ar9003_mci_osla_setup(ah
, false);
1077 ar9003_mci_send_2g5g_status(ah
, true);
1081 bool ar9003_mci_send_message(struct ath_hw
*ah
, u8 header
, u32 flag
,
1082 u32
*payload
, u8 len
, bool wait_done
,
1085 struct ath_common
*common
= ath9k_hw_common(ah
);
1086 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1087 bool msg_sent
= false;
1089 u32 saved_mci_int_en
;
1092 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
1093 regval
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1095 if ((regval
== 0xdeadbeef) || !(regval
& AR_BTCOEX_CTRL_MCI_MODE_EN
)) {
1096 ath_dbg(common
, MCI
,
1097 "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
1098 header
, (ah
->power_mode
== ATH9K_PM_FULL_SLEEP
) ? 1 : 0);
1099 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1101 } else if (check_bt
&& (mci
->bt_state
== MCI_BT_SLEEP
)) {
1102 ath_dbg(common
, MCI
,
1103 "MCI Don't send message 0x%x. BT is in sleep state\n",
1105 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1110 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
1112 /* Need to clear SW_MSG_DONE raw bit before wait */
1114 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
1115 (AR_MCI_INTERRUPT_SW_MSG_DONE
|
1116 AR_MCI_INTERRUPT_MSG_FAIL_MASK
));
1119 for (i
= 0; (i
* 4) < len
; i
++)
1120 REG_WRITE(ah
, (AR_MCI_TX_PAYLOAD0
+ i
* 4),
1124 REG_WRITE(ah
, AR_MCI_COMMAND0
,
1125 (SM((flag
& MCI_FLAG_DISABLE_TIMESTAMP
),
1126 AR_MCI_COMMAND0_DISABLE_TIMESTAMP
) |
1127 SM(len
, AR_MCI_COMMAND0_LEN
) |
1128 SM(header
, AR_MCI_COMMAND0_HEADER
)));
1131 !(ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RAW
,
1132 AR_MCI_INTERRUPT_SW_MSG_DONE
, 500)))
1133 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1135 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, false);
1140 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
1144 EXPORT_SYMBOL(ar9003_mci_send_message
);
1146 void ar9003_mci_init_cal_req(struct ath_hw
*ah
, bool *is_reusable
)
1148 struct ath_common
*common
= ath9k_hw_common(ah
);
1149 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1150 u32 pld
[4] = {0, 0, 0, 0};
1152 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1153 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1156 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_REQ
);
1157 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_seq
++;
1159 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1161 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_GRANT
, 0, 50000)) {
1162 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT received\n");
1164 *is_reusable
= false;
1165 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT not received\n");
1169 void ar9003_mci_init_cal_done(struct ath_hw
*ah
)
1171 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1172 u32 pld
[4] = {0, 0, 0, 0};
1174 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1175 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1178 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_DONE
);
1179 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_done
++;
1180 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1183 int ar9003_mci_setup(struct ath_hw
*ah
, u32 gpm_addr
, void *gpm_buf
,
1184 u16 len
, u32 sched_addr
)
1186 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1188 mci
->gpm_addr
= gpm_addr
;
1189 mci
->gpm_buf
= gpm_buf
;
1191 mci
->sched_addr
= sched_addr
;
1193 return ar9003_mci_reset(ah
, true, true, true);
1195 EXPORT_SYMBOL(ar9003_mci_setup
);
1197 void ar9003_mci_cleanup(struct ath_hw
*ah
)
1199 /* Turn off MCI and Jupiter mode. */
1200 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0x00);
1201 ar9003_mci_disable_interrupt(ah
);
1203 EXPORT_SYMBOL(ar9003_mci_cleanup
);
1205 u32
ar9003_mci_state(struct ath_hw
*ah
, u32 state_type
)
1207 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1211 switch (state_type
) {
1212 case MCI_STATE_ENABLE
:
1214 value
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1216 if ((value
== 0xdeadbeef) || (value
== 0xffffffff))
1219 value
&= AR_BTCOEX_CTRL_MCI_MODE_EN
;
1221 case MCI_STATE_LAST_SCHD_MSG_OFFSET
:
1222 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1223 AR_MCI_RX_LAST_SCHD_MSG_INDEX
);
1224 /* Make it in bytes */
1227 case MCI_STATE_REMOTE_SLEEP
:
1228 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1229 AR_MCI_RX_REMOTE_SLEEP
) ?
1230 MCI_BT_SLEEP
: MCI_BT_AWAKE
;
1232 case MCI_STATE_SET_BT_AWAKE
:
1233 mci
->bt_state
= MCI_BT_AWAKE
;
1234 ar9003_mci_send_coex_version_query(ah
, true);
1235 ar9003_mci_send_coex_wlan_channels(ah
, true);
1237 if (mci
->unhalt_bt_gpm
)
1238 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
1240 ar9003_mci_2g5g_switch(ah
, false);
1242 case MCI_STATE_RESET_REQ_WAKE
:
1243 ar9003_mci_reset_req_wakeup(ah
);
1244 mci
->update_2g5g
= true;
1246 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MASK
) {
1247 /* Check if we still have control of the GPIOs */
1248 if ((REG_READ(ah
, AR_GLB_GPIO_CONTROL
) &
1249 ATH_MCI_CONFIG_MCI_OBS_GPIO
) !=
1250 ATH_MCI_CONFIG_MCI_OBS_GPIO
) {
1251 ar9003_mci_observation_set_up(ah
);
1255 case MCI_STATE_SEND_WLAN_COEX_VERSION
:
1256 ar9003_mci_send_coex_version_response(ah
, true);
1258 case MCI_STATE_SEND_VERSION_QUERY
:
1259 ar9003_mci_send_coex_version_query(ah
, true);
1261 case MCI_STATE_SEND_STATUS_QUERY
:
1262 query_type
= MCI_GPM_COEX_QUERY_BT_TOPOLOGY
;
1263 ar9003_mci_send_coex_bt_status_query(ah
, true, query_type
);
1265 case MCI_STATE_RECOVER_RX
:
1266 tsf
= ath9k_hw_gettsf32(ah
);
1267 if ((tsf
- mci
->last_recovery
) <= MCI_RECOVERY_DUR_TSF
) {
1268 ath_dbg(ath9k_hw_common(ah
), MCI
,
1269 "(MCI) ignore Rx recovery\n");
1272 ath_dbg(ath9k_hw_common(ah
), MCI
, "(MCI) RECOVER RX\n");
1273 mci
->last_recovery
= tsf
;
1274 ar9003_mci_prep_interface(ah
);
1275 mci
->query_bt
= true;
1276 mci
->need_flush_btinfo
= true;
1277 ar9003_mci_send_coex_wlan_channels(ah
, true);
1278 ar9003_mci_2g5g_switch(ah
, false);
1280 case MCI_STATE_NEED_FTP_STOMP
:
1281 value
= !(mci
->config
& ATH_MCI_CONFIG_DISABLE_FTP_STOMP
);
1283 case MCI_STATE_NEED_FLUSH_BT_INFO
:
1284 value
= (!mci
->unhalt_bt_gpm
&& mci
->need_flush_btinfo
) ? 1 : 0;
1285 mci
->need_flush_btinfo
= false;
1293 EXPORT_SYMBOL(ar9003_mci_state
);
1295 void ar9003_mci_bt_gain_ctrl(struct ath_hw
*ah
)
1297 struct ath_common
*common
= ath9k_hw_common(ah
);
1298 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1300 ath_dbg(common
, MCI
, "Give LNA and SPDT control to BT\n");
1302 ar9003_mci_send_lna_take(ah
, true);
1305 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1307 mci
->update_2g5g
= true;
1308 ar9003_mci_send_2g5g_status(ah
, true);
1310 /* Force another 2g5g update at next scanning */
1311 mci
->update_2g5g
= true;
1314 void ar9003_mci_set_power_awake(struct ath_hw
*ah
)
1316 u32 btcoex_ctrl2
, diag_sw
;
1318 u8 lna_ctrl
, bt_sleep
;
1320 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1321 btcoex_ctrl2
= REG_READ(ah
, AR_BTCOEX_CTRL2
);
1322 if (btcoex_ctrl2
!= 0xdeadbeef)
1324 udelay(AH_TIME_QUANTUM
);
1326 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, (btcoex_ctrl2
| BIT(23)));
1328 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1329 diag_sw
= REG_READ(ah
, AR_DIAG_SW
);
1330 if (diag_sw
!= 0xdeadbeef)
1332 udelay(AH_TIME_QUANTUM
);
1334 REG_WRITE(ah
, AR_DIAG_SW
, (diag_sw
| BIT(27) | BIT(19) | BIT(18)));
1335 lna_ctrl
= REG_READ(ah
, AR_OBS_BUS_CTRL
) & 0x3;
1336 bt_sleep
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
), AR_MCI_RX_REMOTE_SLEEP
);
1338 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, btcoex_ctrl2
);
1339 REG_WRITE(ah
, AR_DIAG_SW
, diag_sw
);
1341 if (bt_sleep
&& (lna_ctrl
== 2)) {
1342 REG_SET_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1343 REG_CLR_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1348 void ar9003_mci_check_gpm_offset(struct ath_hw
*ah
)
1350 struct ath_common
*common
= ath9k_hw_common(ah
);
1351 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1355 * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
1357 offset
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1358 if (mci
->gpm_idx
== offset
)
1360 ath_dbg(common
, MCI
, "GPM cached write pointer mismatch %d %d\n",
1361 mci
->gpm_idx
, offset
);
1362 mci
->query_bt
= true;
1363 mci
->need_flush_btinfo
= true;
1367 u32
ar9003_mci_get_next_gpm_offset(struct ath_hw
*ah
, bool first
, u32
*more
)
1369 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1370 u32 offset
, more_gpm
= 0, gpm_ptr
;
1373 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1375 if (gpm_ptr
>= mci
->gpm_len
)
1378 mci
->gpm_idx
= gpm_ptr
;
1383 * This could be useful to avoid new GPM message interrupt which
1384 * may lead to spurious interrupt after power sleep, or multiple
1385 * entry of ath_mci_intr().
1386 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1387 * alleviate this effect, but clearing GPM RX interrupt bit is
1388 * safe, because whether this is called from hw or driver code
1389 * there must be an interrupt bit set/triggered initially
1391 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
1392 AR_MCI_INTERRUPT_RX_MSG_GPM
);
1394 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1398 offset
= mci
->gpm_len
- 1;
1399 else if (offset
>= mci
->gpm_len
) {
1400 if (offset
!= 0xFFFF)
1406 if ((offset
== 0xFFFF) || (gpm_ptr
== mci
->gpm_idx
)) {
1407 offset
= MCI_GPM_INVALID
;
1408 more_gpm
= MCI_GPM_NOMORE
;
1414 /* skip reserved GPM if any */
1416 if (offset
!= mci
->gpm_idx
)
1417 more_gpm
= MCI_GPM_MORE
;
1419 more_gpm
= MCI_GPM_NOMORE
;
1421 temp_index
= mci
->gpm_idx
;
1423 if (temp_index
>= mci
->gpm_len
)
1428 if (mci
->gpm_idx
>= mci
->gpm_len
)
1431 if (ar9003_mci_is_gpm_valid(ah
, temp_index
)) {
1432 offset
= temp_index
;
1436 if (more_gpm
== MCI_GPM_NOMORE
) {
1437 offset
= MCI_GPM_INVALID
;
1442 if (offset
!= MCI_GPM_INVALID
)
1450 EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset
);
1452 void ar9003_mci_set_bt_version(struct ath_hw
*ah
, u8 major
, u8 minor
)
1454 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1456 mci
->bt_ver_major
= major
;
1457 mci
->bt_ver_minor
= minor
;
1458 mci
->bt_version_known
= true;
1459 ath_dbg(ath9k_hw_common(ah
), MCI
, "MCI BT version set: %d.%d\n",
1460 mci
->bt_ver_major
, mci
->bt_ver_minor
);
1462 EXPORT_SYMBOL(ar9003_mci_set_bt_version
);
1464 void ar9003_mci_send_wlan_channels(struct ath_hw
*ah
)
1466 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1468 mci
->wlan_channels_update
= true;
1469 ar9003_mci_send_coex_wlan_channels(ah
, true);
1471 EXPORT_SYMBOL(ar9003_mci_send_wlan_channels
);
1473 u16
ar9003_mci_get_max_txpower(struct ath_hw
*ah
, u8 ctlmode
)
1475 if (!ah
->btcoex_hw
.mci
.concur_tx
)
1478 if (ctlmode
== CTL_2GHT20
)
1479 return ATH_BTCOEX_HT20_MAX_TXPOWER
;
1480 else if (ctlmode
== CTL_2GHT40
)
1481 return ATH_BTCOEX_HT40_MAX_TXPOWER
;