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_gpio_request_out(ah
, 3, NULL
,
431 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA
);
432 ath9k_hw_gpio_request_out(ah
, 2, NULL
,
433 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK
);
434 ath9k_hw_gpio_request_out(ah
, 1, NULL
,
435 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA
);
436 ath9k_hw_gpio_request_out(ah
, 0, NULL
,
437 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK
);
438 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_TXRX
) {
439 ath9k_hw_gpio_request_out(ah
, 3, NULL
,
440 AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX
);
441 ath9k_hw_gpio_request_out(ah
, 2, NULL
,
442 AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX
);
443 ath9k_hw_gpio_request_out(ah
, 1, NULL
,
444 AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX
);
445 ath9k_hw_gpio_request_out(ah
, 0, NULL
,
446 AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX
);
447 ath9k_hw_gpio_request_out(ah
, 5, NULL
,
448 AR_GPIO_OUTPUT_MUX_AS_OUTPUT
);
449 } else if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_BT
) {
450 ath9k_hw_gpio_request_out(ah
, 3, NULL
,
451 AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX
);
452 ath9k_hw_gpio_request_out(ah
, 2, NULL
,
453 AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX
);
454 ath9k_hw_gpio_request_out(ah
, 1, NULL
,
455 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA
);
456 ath9k_hw_gpio_request_out(ah
, 0, NULL
,
457 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK
);
461 REG_SET_BIT(ah
, AR_GPIO_INPUT_EN_VAL
, AR_GPIO_JTAG_DISABLE
);
463 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
, AR_GLB_DS_JTAG_DISABLE
, 1);
464 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
, AR_GLB_WLAN_UART_INTF_EN
, 0);
465 REG_SET_BIT(ah
, AR_GLB_GPIO_CONTROL
, ATH_MCI_CONFIG_MCI_OBS_GPIO
);
467 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_GPIO_OBS_SEL
, 0);
468 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL
, 1);
469 REG_WRITE(ah
, AR_OBS
, 0x4b);
470 REG_RMW_FIELD(ah
, AR_DIAG_SW
, AR_DIAG_OBS_PT_SEL1
, 0x03);
471 REG_RMW_FIELD(ah
, AR_DIAG_SW
, AR_DIAG_OBS_PT_SEL2
, 0x01);
472 REG_RMW_FIELD(ah
, AR_MACMISC
, AR_MACMISC_MISC_OBS_BUS_LSB
, 0x02);
473 REG_RMW_FIELD(ah
, AR_MACMISC
, AR_MACMISC_MISC_OBS_BUS_MSB
, 0x03);
474 REG_RMW_FIELD(ah
, AR_PHY_TEST_CTL_STATUS
,
475 AR_PHY_TEST_CTL_DEBUGPORT_SEL
, 0x07);
478 static bool ar9003_mci_send_coex_bt_flags(struct ath_hw
*ah
, bool wait_done
,
479 u8 opcode
, u32 bt_flags
)
481 u32 pld
[4] = {0, 0, 0, 0};
483 MCI_GPM_SET_TYPE_OPCODE(pld
, MCI_GPM_COEX_AGENT
,
484 MCI_GPM_COEX_BT_UPDATE_FLAGS
);
486 *(((u8
*)pld
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) = opcode
;
487 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 0) = bt_flags
& 0xFF;
488 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 1) = (bt_flags
>> 8) & 0xFF;
489 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 2) = (bt_flags
>> 16) & 0xFF;
490 *(((u8
*)pld
) + MCI_GPM_COEX_W_BT_FLAGS
+ 3) = (bt_flags
>> 24) & 0xFF;
492 return ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16,
496 static void ar9003_mci_sync_bt_state(struct ath_hw
*ah
)
498 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
501 cur_bt_state
= ar9003_mci_state(ah
, MCI_STATE_REMOTE_SLEEP
);
503 if (mci
->bt_state
!= cur_bt_state
)
504 mci
->bt_state
= cur_bt_state
;
506 if (mci
->bt_state
!= MCI_BT_SLEEP
) {
508 ar9003_mci_send_coex_version_query(ah
, true);
509 ar9003_mci_send_coex_wlan_channels(ah
, true);
511 if (mci
->unhalt_bt_gpm
== true)
512 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
516 void ar9003_mci_check_bt(struct ath_hw
*ah
)
518 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
524 * check BT state again to make
525 * sure it's not changed.
527 ar9003_mci_sync_bt_state(ah
);
528 ar9003_mci_2g5g_switch(ah
, true);
530 if ((mci_hw
->bt_state
== MCI_BT_AWAKE
) &&
531 (mci_hw
->query_bt
== true)) {
532 mci_hw
->need_flush_btinfo
= true;
536 static void ar9003_mci_process_gpm_extra(struct ath_hw
*ah
, u8 gpm_type
,
537 u8 gpm_opcode
, u32
*p_gpm
)
539 struct ath_common
*common
= ath9k_hw_common(ah
);
540 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
541 u8
*p_data
= (u8
*) p_gpm
;
543 if (gpm_type
!= MCI_GPM_COEX_AGENT
)
546 switch (gpm_opcode
) {
547 case MCI_GPM_COEX_VERSION_QUERY
:
548 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Query\n");
549 ar9003_mci_send_coex_version_response(ah
, true);
551 case MCI_GPM_COEX_VERSION_RESPONSE
:
552 ath_dbg(common
, MCI
, "MCI Recv GPM COEX Version Response\n");
554 *(p_data
+ MCI_GPM_COEX_B_MAJOR_VERSION
);
556 *(p_data
+ MCI_GPM_COEX_B_MINOR_VERSION
);
557 mci
->bt_version_known
= true;
558 ath_dbg(common
, MCI
, "MCI BT Coex version: %d.%d\n",
559 mci
->bt_ver_major
, mci
->bt_ver_minor
);
561 case MCI_GPM_COEX_STATUS_QUERY
:
563 "MCI Recv GPM COEX Status Query = 0x%02X\n",
564 *(p_data
+ MCI_GPM_COEX_B_WLAN_BITMAP
));
565 mci
->wlan_channels_update
= true;
566 ar9003_mci_send_coex_wlan_channels(ah
, true);
568 case MCI_GPM_COEX_BT_PROFILE_INFO
:
569 mci
->query_bt
= true;
570 ath_dbg(common
, MCI
, "MCI Recv GPM COEX BT_Profile_Info\n");
572 case MCI_GPM_COEX_BT_STATUS_UPDATE
:
573 mci
->query_bt
= true;
575 "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
583 static u32
ar9003_mci_wait_for_gpm(struct ath_hw
*ah
, u8 gpm_type
,
584 u8 gpm_opcode
, int time_out
)
586 struct ath_common
*common
= ath9k_hw_common(ah
);
587 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
588 u32
*p_gpm
= NULL
, mismatch
= 0, more_data
;
590 u8 recv_type
= 0, recv_opcode
= 0;
591 bool b_is_bt_cal_done
= (gpm_type
== MCI_GPM_BT_CAL_DONE
);
593 more_data
= time_out
? MCI_GPM_NOMORE
: MCI_GPM_MORE
;
595 while (time_out
> 0) {
597 MCI_GPM_RECYCLE(p_gpm
);
601 if (more_data
!= MCI_GPM_MORE
)
602 time_out
= ar9003_mci_wait_for_interrupt(ah
,
603 AR_MCI_INTERRUPT_RX_MSG_RAW
,
604 AR_MCI_INTERRUPT_RX_MSG_GPM
,
610 offset
= ar9003_mci_get_next_gpm_offset(ah
, &more_data
);
612 if (offset
== MCI_GPM_INVALID
)
615 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
616 recv_type
= MCI_GPM_TYPE(p_gpm
);
617 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
619 if (MCI_GPM_IS_CAL_TYPE(recv_type
)) {
620 if (recv_type
== gpm_type
) {
621 if ((gpm_type
== MCI_GPM_BT_CAL_DONE
) &&
623 gpm_type
= MCI_GPM_BT_CAL_GRANT
;
628 } else if ((recv_type
== gpm_type
) &&
629 (recv_opcode
== gpm_opcode
))
633 * check if it's cal_grant
635 * When we're waiting for cal_grant in reset routine,
636 * it's possible that BT sends out cal_request at the
637 * same time. Since BT's calibration doesn't happen
638 * that often, we'll let BT completes calibration then
639 * we continue to wait for cal_grant from BT.
640 * Orginal: Wait BT_CAL_GRANT.
641 * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
642 * BT_CAL_DONE -> Wait BT_CAL_GRANT.
645 if ((gpm_type
== MCI_GPM_BT_CAL_GRANT
) &&
646 (recv_type
== MCI_GPM_BT_CAL_REQ
)) {
648 u32 payload
[4] = {0, 0, 0, 0};
650 gpm_type
= MCI_GPM_BT_CAL_DONE
;
651 MCI_GPM_SET_CAL_TYPE(payload
,
652 MCI_GPM_WLAN_CAL_GRANT
);
653 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
, 16,
657 ath_dbg(common
, MCI
, "MCI GPM subtype not match 0x%x\n",
660 ar9003_mci_process_gpm_extra(ah
, recv_type
,
666 MCI_GPM_RECYCLE(p_gpm
);
673 while (more_data
== MCI_GPM_MORE
) {
674 offset
= ar9003_mci_get_next_gpm_offset(ah
, &more_data
);
675 if (offset
== MCI_GPM_INVALID
)
678 p_gpm
= (u32
*) (mci
->gpm_buf
+ offset
);
679 recv_type
= MCI_GPM_TYPE(p_gpm
);
680 recv_opcode
= MCI_GPM_OPCODE(p_gpm
);
682 if (!MCI_GPM_IS_CAL_TYPE(recv_type
))
683 ar9003_mci_process_gpm_extra(ah
, recv_type
,
686 MCI_GPM_RECYCLE(p_gpm
);
692 bool ar9003_mci_start_reset(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
694 struct ath_common
*common
= ath9k_hw_common(ah
);
695 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
696 u32 payload
[4] = {0, 0, 0, 0};
698 ar9003_mci_2g5g_changed(ah
, IS_CHAN_2GHZ(chan
));
700 if (mci_hw
->bt_state
!= MCI_BT_CAL_START
)
703 mci_hw
->bt_state
= MCI_BT_CAL
;
706 * MCI FIX: disable mci interrupt here. This is to avoid
707 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
708 * lead to mci_intr reentry.
710 ar9003_mci_disable_interrupt(ah
);
712 MCI_GPM_SET_CAL_TYPE(payload
, MCI_GPM_WLAN_CAL_GRANT
);
713 ar9003_mci_send_message(ah
, MCI_GPM
, 0, payload
,
716 /* Wait BT calibration to be completed for 25ms */
718 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_DONE
,
720 ath_dbg(common
, MCI
, "MCI BT_CAL_DONE received\n");
723 "MCI BT_CAL_DONE not received\n");
725 mci_hw
->bt_state
= MCI_BT_AWAKE
;
726 /* MCI FIX: enable mci interrupt here */
727 ar9003_mci_enable_interrupt(ah
);
732 int ar9003_mci_end_reset(struct ath_hw
*ah
, struct ath9k_channel
*chan
,
733 struct ath9k_hw_cal_data
*caldata
)
735 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
740 if (!IS_CHAN_2GHZ(chan
) || (mci_hw
->bt_state
!= MCI_BT_SLEEP
))
743 if (!ar9003_mci_check_int(ah
, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET
) &&
744 !ar9003_mci_check_int(ah
, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
))
748 * BT is sleeping. Check if BT wakes up during
749 * WLAN calibration. If BT wakes up during
750 * WLAN calibration, need to go through all
751 * message exchanges again and recal.
753 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
754 (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET
|
755 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE
));
757 ar9003_mci_remote_reset(ah
, true);
758 ar9003_mci_send_sys_waking(ah
, true);
761 if (IS_CHAN_2GHZ(chan
))
762 ar9003_mci_send_lna_transfer(ah
, true);
764 mci_hw
->bt_state
= MCI_BT_AWAKE
;
766 REG_CLR_BIT(ah
, AR_PHY_TIMING4
,
767 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT
);
770 clear_bit(TXIQCAL_DONE
, &caldata
->cal_flags
);
771 clear_bit(TXCLCAL_DONE
, &caldata
->cal_flags
);
772 clear_bit(RTT_DONE
, &caldata
->cal_flags
);
775 if (!ath9k_hw_init_cal(ah
, chan
))
778 REG_SET_BIT(ah
, AR_PHY_TIMING4
,
779 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT
);
782 ar9003_mci_enable_interrupt(ah
);
786 static void ar9003_mci_mute_bt(struct ath_hw
*ah
)
788 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
790 /* disable all MCI messages */
791 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
, 0xffff0000);
792 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS0
, 0xffffffff);
793 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS1
, 0xffffffff);
794 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS2
, 0xffffffff);
795 REG_WRITE(ah
, AR_BTCOEX_WL_WEIGHTS3
, 0xffffffff);
796 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
798 /* wait pending HW messages to flush out */
802 * Send LNA_TAKE and SYS_SLEEPING when
803 * 1. reset not after resuming from full sleep
804 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
806 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci
)) {
807 ar9003_mci_send_lna_take(ah
, true);
811 ar9003_mci_send_sys_sleeping(ah
, true);
814 static void ar9003_mci_osla_setup(struct ath_hw
*ah
, bool enable
)
816 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
820 REG_CLR_BIT(ah
, AR_BTCOEX_CTRL
,
821 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
824 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
, AR_MCI_SCHD_TABLE_2_HW_BASED
, 1);
825 REG_RMW_FIELD(ah
, AR_MCI_SCHD_TABLE_2
,
826 AR_MCI_SCHD_TABLE_2_MEM_BASED
, 1);
828 if (AR_SREV_9565(ah
))
829 REG_RMW_FIELD(ah
, AR_MCI_MISC
, AR_MCI_MISC_HW_FIX_EN
, 1);
831 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_AGGR_THRESH
)) {
832 thresh
= MS(mci
->config
, ATH_MCI_CONFIG_AGGR_THRESH
);
833 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
834 AR_BTCOEX_CTRL_AGGR_THRESH
, thresh
);
835 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
836 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 1);
838 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
839 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN
, 0);
841 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
842 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
, 1);
845 static void ar9003_mci_stat_setup(struct ath_hw
*ah
)
847 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
849 if (!AR_SREV_9565(ah
))
852 if (mci
->config
& ATH_MCI_CONFIG_MCI_STAT_DBG
) {
853 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
854 AR_MCI_DBG_CNT_CTRL_ENABLE
, 1);
855 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
856 AR_MCI_DBG_CNT_CTRL_BT_LINKID
,
857 MCI_STAT_ALL_BT_LINKID
);
859 REG_RMW_FIELD(ah
, AR_MCI_DBG_CNT_CTRL
,
860 AR_MCI_DBG_CNT_CTRL_ENABLE
, 0);
864 static void ar9003_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hw
*ah
)
868 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
869 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
870 SM(1, AR_BTCOEX_CTRL_PA_SHARED
) |
871 SM(1, AR_BTCOEX_CTRL_LNA_SHARED
) |
872 SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
873 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
874 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
875 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
876 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
878 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
879 AR_BTCOEX_CTRL2_TX_CHAIN_MASK
, 0x1);
880 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
883 static void ar9003_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hw
*ah
)
887 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
888 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
889 SM(0, AR_BTCOEX_CTRL_PA_SHARED
) |
890 SM(0, AR_BTCOEX_CTRL_LNA_SHARED
) |
891 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
892 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
893 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
894 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
895 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
897 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
898 AR_BTCOEX_CTRL2_TX_CHAIN_MASK
, 0x0);
899 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
902 static void ar9003_mci_set_btcoex_ctrl_9462(struct ath_hw
*ah
)
906 regval
= SM(1, AR_BTCOEX_CTRL_AR9462_MODE
) |
907 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN
) |
908 SM(1, AR_BTCOEX_CTRL_PA_SHARED
) |
909 SM(1, AR_BTCOEX_CTRL_LNA_SHARED
) |
910 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS
) |
911 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK
) |
912 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK
) |
913 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN
) |
914 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN
);
916 REG_WRITE(ah
, AR_BTCOEX_CTRL
, regval
);
919 int ar9003_mci_reset(struct ath_hw
*ah
, bool en_int
, bool is_2g
,
922 struct ath_common
*common
= ath9k_hw_common(ah
);
923 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
926 ath_dbg(common
, MCI
, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
927 is_full_sleep
, is_2g
);
929 if (REG_READ(ah
, AR_BTCOEX_CTRL
) == 0xdeadbeef) {
930 ath_err(common
, "BTCOEX control register is dead\n");
934 /* Program MCI DMA related registers */
935 REG_WRITE(ah
, AR_MCI_GPM_0
, mci
->gpm_addr
);
936 REG_WRITE(ah
, AR_MCI_GPM_1
, mci
->gpm_len
);
937 REG_WRITE(ah
, AR_MCI_SCHD_TABLE_0
, mci
->sched_addr
);
940 * To avoid MCI state machine be affected by incoming remote MCI msgs,
941 * MCI mode will be enabled later, right before reset the MCI TX and RX.
943 if (AR_SREV_9565(ah
)) {
944 u8 ant
= MS(mci
->config
, ATH_MCI_CONFIG_ANT_ARCH
);
946 if (ant
== ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED
)
947 ar9003_mci_set_btcoex_ctrl_9565_1ANT(ah
);
949 ar9003_mci_set_btcoex_ctrl_9565_2ANT(ah
);
951 ar9003_mci_set_btcoex_ctrl_9462(ah
);
954 if (is_2g
&& !(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
955 ar9003_mci_osla_setup(ah
, true);
957 ar9003_mci_osla_setup(ah
, false);
959 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
960 AR_BTCOEX_CTRL_SPDT_ENABLE
);
961 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL3
,
962 AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT
, 20);
964 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
, AR_BTCOEX_CTRL2_RX_DEWEIGHT
, 0);
965 REG_RMW_FIELD(ah
, AR_PCU_MISC
, AR_PCU_BT_ANT_PREVENT_RX
, 0);
967 /* Set the time out to 3.125ms (5 BT slots) */
968 REG_RMW_FIELD(ah
, AR_BTCOEX_WL_LNA
, AR_BTCOEX_WL_LNA_TIMEOUT
, 0x3D090);
970 /* concurrent tx priority */
971 if (mci
->config
& ATH_MCI_CONFIG_CONCUR_TX
) {
972 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
973 AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE
, 0);
974 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL2
,
975 AR_BTCOEX_CTRL2_TXPWR_THRESH
, 0x7f);
976 REG_RMW_FIELD(ah
, AR_BTCOEX_CTRL
,
977 AR_BTCOEX_CTRL_REDUCE_TXPWR
, 0);
978 for (i
= 0; i
< 8; i
++)
979 REG_WRITE(ah
, AR_BTCOEX_MAX_TXPWR(i
), 0x7f7f7f7f);
982 regval
= MS(mci
->config
, ATH_MCI_CONFIG_CLK_DIV
);
983 REG_RMW_FIELD(ah
, AR_MCI_TX_CTRL
, AR_MCI_TX_CTRL_CLK_DIV
, regval
);
984 REG_SET_BIT(ah
, AR_BTCOEX_CTRL
, AR_BTCOEX_CTRL_MCI_MODE_EN
);
986 /* Resetting the Rx and Tx paths of MCI */
987 regval
= REG_READ(ah
, AR_MCI_COMMAND2
);
988 regval
|= SM(1, AR_MCI_COMMAND2_RESET_TX
);
989 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
993 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_TX
);
994 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
997 ar9003_mci_mute_bt(ah
);
1001 /* Check pending GPM msg before MCI Reset Rx */
1002 ar9003_mci_check_gpm_offset(ah
);
1004 regval
|= SM(1, AR_MCI_COMMAND2_RESET_RX
);
1005 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
1007 regval
&= ~SM(1, AR_MCI_COMMAND2_RESET_RX
);
1008 REG_WRITE(ah
, AR_MCI_COMMAND2
, regval
);
1010 /* Init GPM offset after MCI Reset Rx */
1011 ar9003_mci_state(ah
, MCI_STATE_INIT_GPM_OFFSET
);
1013 REG_WRITE(ah
, AR_MCI_MSG_ATTRIBUTES_TABLE
,
1014 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR
) |
1015 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM
)));
1017 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci
))
1018 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
1019 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1021 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
1022 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1024 ar9003_mci_observation_set_up(ah
);
1027 ar9003_mci_prep_interface(ah
);
1028 ar9003_mci_stat_setup(ah
);
1031 ar9003_mci_enable_interrupt(ah
);
1033 if (ath9k_hw_is_aic_enabled(ah
))
1034 ar9003_aic_start_normal(ah
);
1039 void ar9003_mci_stop_bt(struct ath_hw
*ah
, bool save_fullsleep
)
1041 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1043 ar9003_mci_disable_interrupt(ah
);
1045 if (mci_hw
->ready
&& !save_fullsleep
) {
1046 ar9003_mci_mute_bt(ah
);
1048 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0);
1051 mci_hw
->bt_state
= MCI_BT_SLEEP
;
1052 mci_hw
->ready
= false;
1055 static void ar9003_mci_send_2g5g_status(struct ath_hw
*ah
, bool wait_done
)
1057 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1058 u32 to_set
, to_clear
;
1060 if (!mci
->update_2g5g
|| (mci
->bt_state
== MCI_BT_SLEEP
))
1064 to_clear
= MCI_2G_FLAGS_CLEAR_MASK
;
1065 to_set
= MCI_2G_FLAGS_SET_MASK
;
1067 to_clear
= MCI_5G_FLAGS_CLEAR_MASK
;
1068 to_set
= MCI_5G_FLAGS_SET_MASK
;
1072 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
1073 MCI_GPM_COEX_BT_FLAGS_CLEAR
,
1076 ar9003_mci_send_coex_bt_flags(ah
, wait_done
,
1077 MCI_GPM_COEX_BT_FLAGS_SET
,
1081 static void ar9003_mci_queue_unsent_gpm(struct ath_hw
*ah
, u8 header
,
1082 u32
*payload
, bool queue
)
1084 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1087 /* check if the message is to be queued */
1088 if (header
!= MCI_GPM
)
1091 type
= MCI_GPM_TYPE(payload
);
1092 opcode
= MCI_GPM_OPCODE(payload
);
1094 if (type
!= MCI_GPM_COEX_AGENT
)
1098 case MCI_GPM_COEX_BT_UPDATE_FLAGS
:
1099 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_BT_FLAGS_OP
) ==
1100 MCI_GPM_COEX_BT_FLAGS_READ
)
1103 mci
->update_2g5g
= queue
;
1106 case MCI_GPM_COEX_WLAN_CHANNELS
:
1107 mci
->wlan_channels_update
= queue
;
1109 case MCI_GPM_COEX_HALT_BT_GPM
:
1110 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
1111 MCI_GPM_COEX_BT_GPM_UNHALT
) {
1112 mci
->unhalt_bt_gpm
= queue
;
1115 mci
->halted_bt_gpm
= false;
1118 if (*(((u8
*)payload
) + MCI_GPM_COEX_B_HALT_STATE
) ==
1119 MCI_GPM_COEX_BT_GPM_HALT
) {
1121 mci
->halted_bt_gpm
= !queue
;
1130 void ar9003_mci_2g5g_switch(struct ath_hw
*ah
, bool force
)
1132 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1134 if (!mci
->update_2g5g
&& !force
)
1138 ar9003_mci_send_2g5g_status(ah
, true);
1139 ar9003_mci_send_lna_transfer(ah
, true);
1142 REG_CLR_BIT(ah
, AR_MCI_TX_CTRL
,
1143 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1144 REG_CLR_BIT(ah
, AR_PHY_GLB_CONTROL
,
1145 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1147 if (!(mci
->config
& ATH_MCI_CONFIG_DISABLE_OSLA
))
1148 ar9003_mci_osla_setup(ah
, true);
1150 if (AR_SREV_9462(ah
))
1151 REG_WRITE(ah
, AR_SELFGEN_MASK
, 0x02);
1153 ar9003_mci_send_lna_take(ah
, true);
1156 REG_SET_BIT(ah
, AR_MCI_TX_CTRL
,
1157 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE
);
1158 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
,
1159 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1161 ar9003_mci_osla_setup(ah
, false);
1162 ar9003_mci_send_2g5g_status(ah
, true);
1166 bool ar9003_mci_send_message(struct ath_hw
*ah
, u8 header
, u32 flag
,
1167 u32
*payload
, u8 len
, bool wait_done
,
1170 struct ath_common
*common
= ath9k_hw_common(ah
);
1171 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1172 bool msg_sent
= false;
1174 u32 saved_mci_int_en
;
1177 saved_mci_int_en
= REG_READ(ah
, AR_MCI_INTERRUPT_EN
);
1178 regval
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1180 if ((regval
== 0xdeadbeef) || !(regval
& AR_BTCOEX_CTRL_MCI_MODE_EN
)) {
1181 ath_dbg(common
, MCI
,
1182 "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
1183 header
, (ah
->power_mode
== ATH9K_PM_FULL_SLEEP
) ? 1 : 0);
1184 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1186 } else if (check_bt
&& (mci
->bt_state
== MCI_BT_SLEEP
)) {
1187 ath_dbg(common
, MCI
,
1188 "MCI Don't send message 0x%x. BT is in sleep state\n",
1190 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1195 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, 0);
1197 /* Need to clear SW_MSG_DONE raw bit before wait */
1199 REG_WRITE(ah
, AR_MCI_INTERRUPT_RAW
,
1200 (AR_MCI_INTERRUPT_SW_MSG_DONE
|
1201 AR_MCI_INTERRUPT_MSG_FAIL_MASK
));
1204 for (i
= 0; (i
* 4) < len
; i
++)
1205 REG_WRITE(ah
, (AR_MCI_TX_PAYLOAD0
+ i
* 4),
1209 REG_WRITE(ah
, AR_MCI_COMMAND0
,
1210 (SM((flag
& MCI_FLAG_DISABLE_TIMESTAMP
),
1211 AR_MCI_COMMAND0_DISABLE_TIMESTAMP
) |
1212 SM(len
, AR_MCI_COMMAND0_LEN
) |
1213 SM(header
, AR_MCI_COMMAND0_HEADER
)));
1216 !(ar9003_mci_wait_for_interrupt(ah
, AR_MCI_INTERRUPT_RAW
,
1217 AR_MCI_INTERRUPT_SW_MSG_DONE
, 500)))
1218 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, true);
1220 ar9003_mci_queue_unsent_gpm(ah
, header
, payload
, false);
1225 REG_WRITE(ah
, AR_MCI_INTERRUPT_EN
, saved_mci_int_en
);
1229 EXPORT_SYMBOL(ar9003_mci_send_message
);
1231 void ar9003_mci_init_cal_req(struct ath_hw
*ah
, bool *is_reusable
)
1233 struct ath_common
*common
= ath9k_hw_common(ah
);
1234 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1235 u32 pld
[4] = {0, 0, 0, 0};
1237 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1238 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1241 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_REQ
);
1242 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_seq
++;
1244 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1246 if (ar9003_mci_wait_for_gpm(ah
, MCI_GPM_BT_CAL_GRANT
, 0, 50000)) {
1247 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT received\n");
1249 *is_reusable
= false;
1250 ath_dbg(common
, MCI
, "MCI BT_CAL_GRANT not received\n");
1254 void ar9003_mci_init_cal_done(struct ath_hw
*ah
)
1256 struct ath9k_hw_mci
*mci_hw
= &ah
->btcoex_hw
.mci
;
1257 u32 pld
[4] = {0, 0, 0, 0};
1259 if ((mci_hw
->bt_state
!= MCI_BT_AWAKE
) ||
1260 (mci_hw
->config
& ATH_MCI_CONFIG_DISABLE_MCI_CAL
))
1263 MCI_GPM_SET_CAL_TYPE(pld
, MCI_GPM_WLAN_CAL_DONE
);
1264 pld
[MCI_GPM_WLAN_CAL_W_SEQUENCE
] = mci_hw
->wlan_cal_done
++;
1265 ar9003_mci_send_message(ah
, MCI_GPM
, 0, pld
, 16, true, false);
1268 int ar9003_mci_setup(struct ath_hw
*ah
, u32 gpm_addr
, void *gpm_buf
,
1269 u16 len
, u32 sched_addr
)
1271 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1273 mci
->gpm_addr
= gpm_addr
;
1274 mci
->gpm_buf
= gpm_buf
;
1276 mci
->sched_addr
= sched_addr
;
1278 return ar9003_mci_reset(ah
, true, true, true);
1280 EXPORT_SYMBOL(ar9003_mci_setup
);
1282 void ar9003_mci_cleanup(struct ath_hw
*ah
)
1284 /* Turn off MCI and Jupiter mode. */
1285 REG_WRITE(ah
, AR_BTCOEX_CTRL
, 0x00);
1286 ar9003_mci_disable_interrupt(ah
);
1288 EXPORT_SYMBOL(ar9003_mci_cleanup
);
1290 u32
ar9003_mci_state(struct ath_hw
*ah
, u32 state_type
)
1292 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1296 switch (state_type
) {
1297 case MCI_STATE_ENABLE
:
1299 value
= REG_READ(ah
, AR_BTCOEX_CTRL
);
1301 if ((value
== 0xdeadbeef) || (value
== 0xffffffff))
1304 value
&= AR_BTCOEX_CTRL_MCI_MODE_EN
;
1306 case MCI_STATE_INIT_GPM_OFFSET
:
1307 value
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1309 if (value
< mci
->gpm_len
)
1310 mci
->gpm_idx
= value
;
1314 case MCI_STATE_LAST_SCHD_MSG_OFFSET
:
1315 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1316 AR_MCI_RX_LAST_SCHD_MSG_INDEX
);
1317 /* Make it in bytes */
1320 case MCI_STATE_REMOTE_SLEEP
:
1321 value
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
),
1322 AR_MCI_RX_REMOTE_SLEEP
) ?
1323 MCI_BT_SLEEP
: MCI_BT_AWAKE
;
1325 case MCI_STATE_SET_BT_AWAKE
:
1326 mci
->bt_state
= MCI_BT_AWAKE
;
1327 ar9003_mci_send_coex_version_query(ah
, true);
1328 ar9003_mci_send_coex_wlan_channels(ah
, true);
1330 if (mci
->unhalt_bt_gpm
)
1331 ar9003_mci_send_coex_halt_bt_gpm(ah
, false, true);
1333 ar9003_mci_2g5g_switch(ah
, false);
1335 case MCI_STATE_RESET_REQ_WAKE
:
1336 ar9003_mci_reset_req_wakeup(ah
);
1337 mci
->update_2g5g
= true;
1339 if (mci
->config
& ATH_MCI_CONFIG_MCI_OBS_MASK
) {
1340 /* Check if we still have control of the GPIOs */
1341 if ((REG_READ(ah
, AR_GLB_GPIO_CONTROL
) &
1342 ATH_MCI_CONFIG_MCI_OBS_GPIO
) !=
1343 ATH_MCI_CONFIG_MCI_OBS_GPIO
) {
1344 ar9003_mci_observation_set_up(ah
);
1348 case MCI_STATE_SEND_WLAN_COEX_VERSION
:
1349 ar9003_mci_send_coex_version_response(ah
, true);
1351 case MCI_STATE_SEND_VERSION_QUERY
:
1352 ar9003_mci_send_coex_version_query(ah
, true);
1354 case MCI_STATE_SEND_STATUS_QUERY
:
1355 query_type
= MCI_GPM_COEX_QUERY_BT_TOPOLOGY
;
1356 ar9003_mci_send_coex_bt_status_query(ah
, true, query_type
);
1358 case MCI_STATE_RECOVER_RX
:
1359 tsf
= ath9k_hw_gettsf32(ah
);
1360 if ((tsf
- mci
->last_recovery
) <= MCI_RECOVERY_DUR_TSF
) {
1361 ath_dbg(ath9k_hw_common(ah
), MCI
,
1362 "(MCI) ignore Rx recovery\n");
1365 ath_dbg(ath9k_hw_common(ah
), MCI
, "(MCI) RECOVER RX\n");
1366 mci
->last_recovery
= tsf
;
1367 ar9003_mci_prep_interface(ah
);
1368 mci
->query_bt
= true;
1369 mci
->need_flush_btinfo
= true;
1370 ar9003_mci_send_coex_wlan_channels(ah
, true);
1371 ar9003_mci_2g5g_switch(ah
, false);
1373 case MCI_STATE_NEED_FTP_STOMP
:
1374 value
= !(mci
->config
& ATH_MCI_CONFIG_DISABLE_FTP_STOMP
);
1376 case MCI_STATE_NEED_FLUSH_BT_INFO
:
1377 value
= (!mci
->unhalt_bt_gpm
&& mci
->need_flush_btinfo
) ? 1 : 0;
1378 mci
->need_flush_btinfo
= false;
1380 case MCI_STATE_AIC_CAL
:
1381 if (ath9k_hw_is_aic_enabled(ah
))
1382 value
= ar9003_aic_calibration(ah
);
1384 case MCI_STATE_AIC_START
:
1385 if (ath9k_hw_is_aic_enabled(ah
))
1386 ar9003_aic_start_normal(ah
);
1388 case MCI_STATE_AIC_CAL_RESET
:
1389 if (ath9k_hw_is_aic_enabled(ah
))
1390 value
= ar9003_aic_cal_reset(ah
);
1392 case MCI_STATE_AIC_CAL_SINGLE
:
1393 if (ath9k_hw_is_aic_enabled(ah
))
1394 value
= ar9003_aic_calibration_single(ah
);
1402 EXPORT_SYMBOL(ar9003_mci_state
);
1404 void ar9003_mci_bt_gain_ctrl(struct ath_hw
*ah
)
1406 struct ath_common
*common
= ath9k_hw_common(ah
);
1407 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1409 ath_dbg(common
, MCI
, "Give LNA and SPDT control to BT\n");
1411 ar9003_mci_send_lna_take(ah
, true);
1414 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL
);
1416 mci
->update_2g5g
= true;
1417 ar9003_mci_send_2g5g_status(ah
, true);
1419 /* Force another 2g5g update at next scanning */
1420 mci
->update_2g5g
= true;
1423 void ar9003_mci_set_power_awake(struct ath_hw
*ah
)
1425 u32 btcoex_ctrl2
, diag_sw
;
1427 u8 lna_ctrl
, bt_sleep
;
1429 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1430 btcoex_ctrl2
= REG_READ(ah
, AR_BTCOEX_CTRL2
);
1431 if (btcoex_ctrl2
!= 0xdeadbeef)
1433 udelay(AH_TIME_QUANTUM
);
1435 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, (btcoex_ctrl2
| BIT(23)));
1437 for (i
= 0; i
< AH_WAIT_TIMEOUT
; i
++) {
1438 diag_sw
= REG_READ(ah
, AR_DIAG_SW
);
1439 if (diag_sw
!= 0xdeadbeef)
1441 udelay(AH_TIME_QUANTUM
);
1443 REG_WRITE(ah
, AR_DIAG_SW
, (diag_sw
| BIT(27) | BIT(19) | BIT(18)));
1444 lna_ctrl
= REG_READ(ah
, AR_OBS_BUS_CTRL
) & 0x3;
1445 bt_sleep
= MS(REG_READ(ah
, AR_MCI_RX_STATUS
), AR_MCI_RX_REMOTE_SLEEP
);
1447 REG_WRITE(ah
, AR_BTCOEX_CTRL2
, btcoex_ctrl2
);
1448 REG_WRITE(ah
, AR_DIAG_SW
, diag_sw
);
1450 if (bt_sleep
&& (lna_ctrl
== 2)) {
1451 REG_SET_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1452 REG_CLR_BIT(ah
, AR_BTCOEX_RC
, 0x1);
1457 void ar9003_mci_check_gpm_offset(struct ath_hw
*ah
)
1459 struct ath_common
*common
= ath9k_hw_common(ah
);
1460 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1464 * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
1466 offset
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1467 if (mci
->gpm_idx
== offset
)
1469 ath_dbg(common
, MCI
, "GPM cached write pointer mismatch %d %d\n",
1470 mci
->gpm_idx
, offset
);
1471 mci
->query_bt
= true;
1472 mci
->need_flush_btinfo
= true;
1476 u32
ar9003_mci_get_next_gpm_offset(struct ath_hw
*ah
, u32
*more
)
1478 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1479 u32 offset
, more_gpm
= 0, gpm_ptr
;
1482 * This could be useful to avoid new GPM message interrupt which
1483 * may lead to spurious interrupt after power sleep, or multiple
1484 * entry of ath_mci_intr().
1485 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1486 * alleviate this effect, but clearing GPM RX interrupt bit is
1487 * safe, because whether this is called from hw or driver code
1488 * there must be an interrupt bit set/triggered initially
1490 REG_WRITE(ah
, AR_MCI_INTERRUPT_RX_MSG_RAW
,
1491 AR_MCI_INTERRUPT_RX_MSG_GPM
);
1493 gpm_ptr
= MS(REG_READ(ah
, AR_MCI_GPM_1
), AR_MCI_GPM_WRITE_PTR
);
1497 offset
= mci
->gpm_len
- 1;
1498 else if (offset
>= mci
->gpm_len
) {
1499 if (offset
!= 0xFFFF)
1505 if ((offset
== 0xFFFF) || (gpm_ptr
== mci
->gpm_idx
)) {
1506 offset
= MCI_GPM_INVALID
;
1507 more_gpm
= MCI_GPM_NOMORE
;
1513 /* skip reserved GPM if any */
1515 if (offset
!= mci
->gpm_idx
)
1516 more_gpm
= MCI_GPM_MORE
;
1518 more_gpm
= MCI_GPM_NOMORE
;
1520 temp_index
= mci
->gpm_idx
;
1522 if (temp_index
>= mci
->gpm_len
)
1527 if (mci
->gpm_idx
>= mci
->gpm_len
)
1530 if (ar9003_mci_is_gpm_valid(ah
, temp_index
)) {
1531 offset
= temp_index
;
1535 if (more_gpm
== MCI_GPM_NOMORE
) {
1536 offset
= MCI_GPM_INVALID
;
1541 if (offset
!= MCI_GPM_INVALID
)
1549 EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset
);
1551 void ar9003_mci_set_bt_version(struct ath_hw
*ah
, u8 major
, u8 minor
)
1553 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1555 mci
->bt_ver_major
= major
;
1556 mci
->bt_ver_minor
= minor
;
1557 mci
->bt_version_known
= true;
1558 ath_dbg(ath9k_hw_common(ah
), MCI
, "MCI BT version set: %d.%d\n",
1559 mci
->bt_ver_major
, mci
->bt_ver_minor
);
1561 EXPORT_SYMBOL(ar9003_mci_set_bt_version
);
1563 void ar9003_mci_send_wlan_channels(struct ath_hw
*ah
)
1565 struct ath9k_hw_mci
*mci
= &ah
->btcoex_hw
.mci
;
1567 mci
->wlan_channels_update
= true;
1568 ar9003_mci_send_coex_wlan_channels(ah
, true);
1570 EXPORT_SYMBOL(ar9003_mci_send_wlan_channels
);
1572 u16
ar9003_mci_get_max_txpower(struct ath_hw
*ah
, u8 ctlmode
)
1574 if (!ah
->btcoex_hw
.mci
.concur_tx
)
1577 if (ctlmode
== CTL_2GHT20
)
1578 return ATH_BTCOEX_HT20_MAX_TXPOWER
;
1579 else if (ctlmode
== CTL_2GHT40
)
1580 return ATH_BTCOEX_HT40_MAX_TXPOWER
;