xref: /freebsd/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c (revision 39ee7a7a6bdd1557b1c3532abf60d139798ac88b)
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  *
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.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 
18 #include "opt_ah.h"
19 
20 #include "ah.h"
21 #include "ah_internal.h"
22 
23 #include "ar9300/ar9300.h"
24 #include "ar9300/ar9300reg.h"
25 #include "ar9300/ar9300phy.h"
26 
27 #if ATH_SUPPORT_MCI
28 
29 #define AH_MCI_REMOTE_RESET_INTERVAL_US     500
30 #define AH_MCI_DEBUG_PRINT_SCHED    0
31 
32 static void ar9300_mci_print_msg(struct ath_hal *ah, HAL_BOOL send,u_int8_t hdr,
33                                  int len, u_int32_t *pl)
34 {
35 #if 0
36     char s[128];
37     char *p = s;
38     int i;
39     u_int8_t *p_data = (u_int8_t *) pl;
40 
41     if (send) {
42         p += snprintf(s, 60,
43                       "(MCI) >>>>> Hdr: %02X, Len: %d, Payload:", hdr, len);
44     }
45     else {
46         p += snprintf(s, 60,
47                       "(MCI) <<<<< Hdr: %02X, Len: %d, Payload:", hdr, len);
48     }
49     for ( i=0; i<len; i++)
50     {
51         p += snprintf(p, 60, " %02x", *(p_data + i));
52     }
53     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s\n", s);
54 /*
55     for ( i=0; i<(len + 3)/4; i++)
56     {
57         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI)   0x%08x\n", *(pl + i));
58     }
59 */
60 #endif
61 }
62 
63 static
64 void ar9300_mci_osla_setup(struct ath_hal *ah, HAL_BOOL enable)
65 {
66 //    struct ath_hal_9300 *ahp = AH9300(ah);
67     u_int32_t thresh;
68 
69     if (enable) {
70         OS_REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
71         OS_REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);
72 
73         if (!(ah->ah_config.ath_hal_mci_config &
74             ATH_MCI_CONFIG_DISABLE_AGGR_THRESH))
75         {
76             thresh = MS(ah->ah_config.ath_hal_mci_config,
77                         ATH_MCI_CONFIG_AGGR_THRESH);
78             OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
79                              AR_BTCOEX_CTRL_AGGR_THRESH, thresh);
80             OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
81                              AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1);
82             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
83                 "(MCI) SCHED aggr thresh: on, thresh=%d (%d.%d%%)\n",
84                 thresh, (thresh + 1)*125/10, (thresh + 1)*125%10);
85 
86         }
87         else {
88             OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
89                              AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0);
90             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED aggr thresh: off\n");
91         }
92         OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
93                          AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
94         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED one step look ahead: on\n");
95     }
96     else {
97         OS_REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
98             AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
99         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED one step look ahead: off\n");
100     }
101 }
102 
103 static void ar9300_mci_reset_req_wakeup(struct ath_hal *ah)
104 {
105     /* to be tested in emulation */
106     if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
107         OS_REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
108             AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);
109         OS_DELAY(1);
110         OS_REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
111             AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0);
112     }
113 }
114 
115 static int32_t ar9300_mci_wait_for_interrupt(struct ath_hal *ah,
116                                              u_int32_t address,
117                                              u_int32_t bit_position,
118                                              int32_t time_out)
119 {
120     int data; //, loop;
121 
122     while (time_out) {
123         data = OS_REG_READ(ah, address);
124 
125         if (data & bit_position) {
126             OS_REG_WRITE(ah, address, bit_position);
127             if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) {
128                 if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) {
129                     ar9300_mci_reset_req_wakeup(ah);
130                 }
131                 if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING |
132                                     AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING))
133                 {
134                     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
135                         AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
136                 }
137                 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG);
138             }
139             break;
140         }
141 
142         OS_DELAY(10);
143         time_out -= 10;
144         if (time_out < 0) {
145             break;
146         }
147     }
148 
149     if (time_out <= 0) {
150         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
151             "(MCI) %s: Wait for Reg0x%08x = 0x%08x timeout.\n",
152             __func__, address, bit_position);
153         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
154             "(MCI) INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x",
155             OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW),
156             OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
157         time_out = 0;
158     }
159     return time_out;
160 }
161 
162 void ar9300_mci_remote_reset(struct ath_hal *ah, HAL_BOOL wait_done)
163 {
164     u_int32_t payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
165 
166     ar9300_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
167         wait_done, AH_FALSE);
168 
169     OS_DELAY(5);
170 }
171 
172 void ar9300_mci_send_lna_transfer(struct ath_hal *ah, HAL_BOOL wait_done)
173 {
174     u_int32_t payload = 0x00000000;
175 
176     ar9300_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
177         wait_done, AH_FALSE);
178 }
179 
180 static void ar9300_mci_send_req_wake(struct ath_hal *ah, HAL_BOOL wait_done)
181 {
182     ar9300_mci_send_message(ah, MCI_REQ_WAKE,
183         HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE);
184 
185     OS_DELAY(5);
186 }
187 
188 void ar9300_mci_send_sys_waking(struct ath_hal *ah, HAL_BOOL wait_done)
189 {
190     ar9300_mci_send_message(ah, MCI_SYS_WAKING,
191         HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE);
192 }
193 
194 static void ar9300_mci_send_lna_take(struct ath_hal *ah, HAL_BOOL wait_done)
195 {
196     u_int32_t payload = 0x70000000;
197 
198     /* LNA gain index is set to 7. */
199     ar9300_mci_send_message(ah, MCI_LNA_TAKE,
200         HAL_MCI_FLAG_DISABLE_TIMESTAMP, &payload, 1, wait_done, AH_FALSE);
201 }
202 
203 static void ar9300_mci_send_sys_sleeping(struct ath_hal *ah, HAL_BOOL wait_done)
204 {
205     ar9300_mci_send_message(ah, MCI_SYS_SLEEPING,
206         HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE);
207 }
208 
209 static void
210 ar9300_mci_send_coex_version_query(struct ath_hal *ah, HAL_BOOL wait_done)
211 {
212     struct ath_hal_9300 *ahp = AH9300(ah);
213     u_int32_t payload[4] = {0, 0, 0, 0};
214 
215     if ((ahp->ah_mci_coex_bt_version_known == AH_FALSE) &&
216         (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) {
217         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send Coex version query.\n");
218         MCI_GPM_SET_TYPE_OPCODE(payload,
219             MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY);
220         ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);
221     }
222 }
223 
224 static void
225 ar9300_mci_send_coex_version_response(struct ath_hal *ah, HAL_BOOL wait_done)
226 {
227     struct ath_hal_9300 *ahp = AH9300(ah);
228     u_int32_t payload[4] = {0, 0, 0, 0};
229 
230     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send Coex version response.\n");
231     MCI_GPM_SET_TYPE_OPCODE(payload,
232         MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_RESPONSE);
233     *(((u_int8_t *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =
234         ahp->ah_mci_coex_major_version_wlan;
235     *(((u_int8_t *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =
236         ahp->ah_mci_coex_minor_version_wlan;
237     ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);
238 }
239 
240 static void
241 ar9300_mci_send_coex_wlan_channels(struct ath_hal *ah, HAL_BOOL wait_done)
242 {
243     struct ath_hal_9300 *ahp = AH9300(ah);
244     u_int32_t *payload = &ahp->ah_mci_coex_wlan_channels[0];
245 
246     if ((ahp->ah_mci_coex_wlan_channels_update == AH_TRUE) &&
247         (ahp->ah_mci_bt_state != MCI_BT_SLEEP))
248     {
249         MCI_GPM_SET_TYPE_OPCODE(payload,
250             MCI_GPM_COEX_AGENT, MCI_GPM_COEX_WLAN_CHANNELS);
251         ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);
252         MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);
253     }
254 }
255 
256 static void ar9300_mci_send_coex_bt_status_query(struct ath_hal *ah,
257                                     HAL_BOOL wait_done, u_int8_t query_type)
258 {
259     struct ath_hal_9300 *ahp = AH9300(ah);
260     u_int32_t pld[4] = {0, 0, 0, 0};
261     HAL_BOOL query_btinfo = query_type &
262             (MCI_GPM_COEX_QUERY_BT_ALL_INFO | MCI_GPM_COEX_QUERY_BT_TOPOLOGY);
263 
264     if (ahp->ah_mci_bt_state != MCI_BT_SLEEP) {
265         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
266             "(MCI) Send Coex BT Status Query 0x%02X\n", query_type);
267         MCI_GPM_SET_TYPE_OPCODE(pld,
268             MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY);
269         *(((u_int8_t *)pld) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;
270         /*
271          * If bt_status_query message is thought not sent successfully,
272          * then ah_mci_need_flush_btinfo should be set again.
273          */
274         if (!ar9300_mci_send_message(ah, MCI_GPM, 0, pld, 16, wait_done, AH_TRUE))
275         {
276             if (query_btinfo) {
277                 ahp->ah_mci_need_flush_btinfo = AH_TRUE;
278                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
279                     "(MCI) send bt_status_query fail, set flush flag again\n");
280             }
281         }
282         if (query_btinfo) {
283             ahp->ah_mci_query_bt = AH_FALSE;
284         }
285     }
286 }
287 
288 void ar9300_mci_send_coex_halt_bt_gpm(struct ath_hal *ah,
289                                       HAL_BOOL halt, HAL_BOOL wait_done)
290 {
291     struct ath_hal_9300 *ahp = AH9300(ah);
292     u_int32_t payload[4] = {0, 0, 0, 0};
293 
294     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
295         "(MCI) Send Coex %s BT GPM.\n", (halt == AH_TRUE)?"HALT":"UNHALT");
296 
297     MCI_GPM_SET_TYPE_OPCODE(payload,
298         MCI_GPM_COEX_AGENT, MCI_GPM_COEX_HALT_BT_GPM);
299     if (halt == AH_TRUE) {
300         ahp->ah_mci_query_bt = AH_TRUE;
301         /* Send next UNHALT no matter HALT sent or not */
302         ahp->ah_mci_unhalt_bt_gpm = AH_TRUE;
303         ahp->ah_mci_need_flush_btinfo = AH_TRUE;
304         *(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
305             MCI_GPM_COEX_BT_GPM_HALT;
306     }
307     else {
308         *(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
309             MCI_GPM_COEX_BT_GPM_UNHALT;
310     }
311     ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);
312 }
313 
314 static HAL_BOOL ar9300_mci_send_coex_bt_flags(struct ath_hal *ah, HAL_BOOL wait_done,
315                                           u_int8_t opcode, u_int32_t bt_flags)
316 {
317 //    struct ath_hal_9300 *ahp = AH9300(ah);
318     u_int32_t pld[4] = {0, 0, 0, 0};
319 
320     MCI_GPM_SET_TYPE_OPCODE(pld,
321         MCI_GPM_COEX_AGENT, MCI_GPM_COEX_BT_UPDATE_FLAGS);
322 
323     *(((u_int8_t *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP)  = opcode;
324     *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;
325     *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) =
326         (bt_flags >> 8) & 0xFF;
327     *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) =
328         (bt_flags >> 16) & 0xFF;
329     *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) =
330         (bt_flags >> 24) & 0xFF;
331 
332     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
333         "(MCI) BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n",
334             (opcode == MCI_GPM_COEX_BT_FLAGS_READ)?"READ":
335             ((opcode == MCI_GPM_COEX_BT_FLAGS_SET)?"SET":"CLEAR"),
336             bt_flags);
337 
338     return ar9300_mci_send_message(ah, MCI_GPM, 0, pld, 16, wait_done, AH_TRUE);
339 }
340 
341 void ar9300_mci_2g5g_changed(struct ath_hal *ah, HAL_BOOL is_2g)
342 {
343     struct ath_hal_9300 *ahp = AH9300(ah);
344 
345     if (ahp->ah_mci_coex_2g5g_update == AH_FALSE) {
346         if (ahp->ah_mci_coex_is_2g == is_2g) {
347             //HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: not changed\n");
348         } else {
349             ahp->ah_mci_coex_2g5g_update = AH_TRUE;
350             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: changed\n");
351         }
352     } else {
353         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: force send\n");
354     }
355     ahp->ah_mci_coex_is_2g = is_2g;
356 }
357 
358 static void ar9300_mci_send_2g5g_status(struct ath_hal *ah, HAL_BOOL wait_done)
359 {
360     struct ath_hal_9300 *ahp = AH9300(ah);
361     u_int32_t new_flags, to_set, to_clear;
362 
363     if ((AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) &&
364         (ahp->ah_mci_coex_2g5g_update == AH_TRUE) &&
365         (ahp->ah_mci_bt_state != MCI_BT_SLEEP))
366     {
367         if (ahp->ah_mci_coex_is_2g) {
368             new_flags = HAL_MCI_2G_FLAGS;
369             to_clear = HAL_MCI_2G_FLAGS_CLEAR_MASK;
370             to_set = HAL_MCI_2G_FLAGS_SET_MASK;
371         } else {
372             new_flags = HAL_MCI_5G_FLAGS;
373             to_clear = HAL_MCI_5G_FLAGS_CLEAR_MASK;
374             to_set = HAL_MCI_5G_FLAGS_SET_MASK;
375         }
376         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
377             "(MCI) BT_MCI_FLAGS: %s (0x%08x) clr=0x%08x, set=0x%08x\n",
378             ahp->ah_mci_coex_is_2g?"2G":"5G", new_flags, to_clear, to_set);
379         if (to_clear) {
380             ar9300_mci_send_coex_bt_flags(ah, wait_done,
381                 MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear);
382         }
383         if (to_set) {
384             ar9300_mci_send_coex_bt_flags(ah, wait_done,
385                 MCI_GPM_COEX_BT_FLAGS_SET, to_set);
386         }
387     }
388     if (AR_SREV_JUPITER_10(ah) && (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) {
389         ahp->ah_mci_coex_2g5g_update = AH_FALSE;
390     }
391 }
392 
393 void ar9300_mci_2g5g_switch(struct ath_hal *ah, HAL_BOOL wait_done)
394 {
395     struct ath_hal_9300 *ahp = AH9300(ah);
396 
397     if (ahp->ah_mci_coex_2g5g_update)
398     {
399         if (ahp->ah_mci_coex_is_2g) {
400             ar9300_mci_send_2g5g_status(ah, AH_TRUE);
401 
402             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA trans\n");
403             ar9300_mci_send_lna_transfer(ah, AH_TRUE);
404             OS_DELAY(5);
405 
406             OS_REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
407                 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
408             if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
409                 OS_REG_CLR_BIT(ah, AR_GLB_CONTROL,
410                     AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
411                 if (!(ah->ah_config.ath_hal_mci_config &
412                     ATH_MCI_CONFIG_DISABLE_OSLA))
413                 {
414                     ar9300_mci_osla_setup(ah, AH_TRUE);
415                 }
416             }
417         } else {
418             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA take\n");
419             ar9300_mci_send_lna_take(ah, AH_TRUE);
420             OS_DELAY(5);
421 
422             OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL,
423                 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
424             if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
425                 OS_REG_SET_BIT(ah, AR_GLB_CONTROL,
426                     AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
427                 ar9300_mci_osla_setup(ah, AH_FALSE);
428             }
429 
430             ar9300_mci_send_2g5g_status(ah, AH_TRUE);
431         }
432     }
433 
434     /*
435      * Update self gen chain mask. Also set basic set for
436      * txbf.
437      */
438     if (AR_SREV_JUPITER(ah)) {
439         if (ahp->ah_mci_coex_is_2g) {
440             ahp->ah_reduced_self_gen_mask = AH_TRUE;
441             OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x02);
442             ar9300_txbf_set_basic_set(ah);
443         }
444         else {
445             ahp->ah_reduced_self_gen_mask = AH_FALSE;
446             ar9300_txbf_set_basic_set(ah);
447         }
448     }
449 }
450 
451 void ar9300_mci_mute_bt(struct ath_hal *ah)
452 {
453     /* disable all MCI messages */
454     OS_REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xFFFF0000);
455     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xFFFFFFFF);
456     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xFFFFFFFF);
457     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xFFFFFFFF);
458     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xFFFFFFFF);
459     OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
460     /* wait pending HW messages to flush out */
461     OS_DELAY(10);
462 
463     /*
464      * Send LNA_TAKE and SYS_SLEEPING when
465      * 1. reset not after resuming from full sleep
466      * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
467      */
468     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA take\n");
469     ar9300_mci_send_lna_take(ah, AH_TRUE);
470     OS_DELAY(5);
471     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send sys sleeping\n");
472     ar9300_mci_send_sys_sleeping(ah, AH_TRUE);
473 }
474 
475 static void ar9300_mci_observation_set_up(struct ath_hal *ah)
476 {
477     /*
478      * Set up the observation bus in order to monitor MCI bus
479      * through GPIOs (0, 1, 2, and 3).
480      */
481     /*
482     OS_REG_WRITE(ah, AR_GPIO_INTR_POL, 0x00420000);
483     OS_REG_WRITE(ah, AR_GPIO_OE_OUT, 0x000000ff); // 4050
484     OS_REG_WRITE(ah, AR_GPIO_OUTPUT_MUX1, 0x000bdab4); // 4068
485     OS_REG_WRITE(ah, AR_OBS, 0x0000004b); // 4088
486     OS_REG_WRITE(ah, AR_DIAG_SW, 0x080c0000);
487     OS_REG_WRITE(ah, AR_MACMISC, 0x0001a000);
488     OS_REG_WRITE(ah, AR_PHY_TEST, 0x00080000); // a360
489     OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, 0xe0000000); // a364
490     */
491 
492     if (ah->ah_config.ath_hal_mci_config &
493         ATH_MCI_CONFIG_MCI_OBS_MCI)
494     {
495         ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
496         ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
497         ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
498         ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
499     }
500     else if (ah->ah_config.ath_hal_mci_config &
501         ATH_MCI_CONFIG_MCI_OBS_TXRX)
502     {
503         ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
504         ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
505         ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
506         ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
507         ar9300_gpio_cfg_output(ah, 5, HAL_GPIO_OUTPUT_MUX_AS_OUTPUT);
508     }
509     else if (ah->ah_config.ath_hal_mci_config &
510         ATH_MCI_CONFIG_MCI_OBS_BT)
511     {
512         ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
513         ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
514         ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
515         ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
516     }
517     else {
518         return;
519     }
520 
521     OS_REG_SET_BIT(ah,
522         AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
523 
524     if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
525         OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1);
526         OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0);
527         OS_REG_WRITE(ah, AR_GLB_GPIO_CONTROL,
528                      (OS_REG_READ(ah, AR_GLB_GPIO_CONTROL) |
529                       ATH_MCI_CONFIG_MCI_OBS_GPIO));
530     }
531 
532     OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);
533     OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);
534     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 0x4b);
535     OS_REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03);
536     OS_REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01);
537     OS_REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02);
538     OS_REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03);
539     //OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 0x01);
540     OS_REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS,
541         AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07);
542 }
543 
544 static void ar9300_mci_process_gpm_extra(struct ath_hal *ah,
545                     u_int8_t gpm_type, u_int8_t gpm_opcode, u_int32_t *p_gpm)
546 {
547     struct ath_hal_9300 *ahp = AH9300(ah);
548     u_int8_t *p_data = (u_int8_t *) p_gpm;
549 
550     switch (gpm_type)
551     {
552         case MCI_GPM_COEX_AGENT:
553             switch (gpm_opcode)
554             {
555                 case MCI_GPM_COEX_VERSION_QUERY:
556                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
557                         "(MCI) Recv GPM COEX Version Query.\n");
558                     ar9300_mci_send_coex_version_response(ah, AH_TRUE);
559                     break;
560 
561                 case MCI_GPM_COEX_VERSION_RESPONSE:
562                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
563                         "(MCI) Recv GPM COEX Version Response.\n");
564                     ahp->ah_mci_coex_major_version_bt =
565                         *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
566                     ahp->ah_mci_coex_minor_version_bt =
567                         *(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
568                     ahp->ah_mci_coex_bt_version_known = AH_TRUE;
569                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
570                         "(MCI) BT Coex version: %d.%d\n",
571                         ahp->ah_mci_coex_major_version_bt,
572                         ahp->ah_mci_coex_minor_version_bt);
573                     break;
574 
575                 case MCI_GPM_COEX_STATUS_QUERY:
576                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
577                         "(MCI) Recv GPM COEX Status Query = 0x%02X.\n",
578                         *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
579                     //if ((*(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)) &
580                     //    MCI_GPM_COEX_QUERY_WLAN_ALL_INFO)
581                     {
582                         ahp->ah_mci_coex_wlan_channels_update = AH_TRUE;
583                         ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);
584                     }
585                     break;
586 
587                 case MCI_GPM_COEX_BT_PROFILE_INFO:
588                     ahp->ah_mci_query_bt = AH_TRUE;
589                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
590                         "(MCI) Recv GPM COEX BT_Profile_Info (drop&query)\n");
591                     break;
592 
593                 case MCI_GPM_COEX_BT_STATUS_UPDATE:
594                     ahp->ah_mci_query_bt = AH_TRUE;
595                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
596                         "(MCI) Recv GPM COEX BT_Status_Update "
597                         "SEQ=%d (drop&query)\n",
598                         *(p_gpm + 3));
599                     break;
600 
601                 default:
602                     break;
603             }
604         default:
605             break;
606     }
607 }
608 
609 u_int32_t ar9300_mci_wait_for_gpm(struct ath_hal *ah, u_int8_t gpm_type,
610                                   u_int8_t gpm_opcode, int32_t time_out)
611 {
612     u_int32_t *p_gpm = NULL, mismatch = 0, more_data = HAL_MCI_GPM_NOMORE;
613     struct ath_hal_9300 *ahp = AH9300(ah);
614     HAL_BOOL b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
615     u_int32_t offset;
616     u_int8_t recv_type = 0, recv_opcode = 0;
617 
618     if (time_out == 0) {
619         more_data = HAL_MCI_GPM_MORE;
620     }
621 
622     while (time_out > 0)
623     {
624         if (p_gpm != NULL) {
625             MCI_GPM_RECYCLE(p_gpm);
626             p_gpm = NULL;
627         }
628 
629         if (more_data != HAL_MCI_GPM_MORE) {
630             time_out = ar9300_mci_wait_for_interrupt(ah,
631                 AR_MCI_INTERRUPT_RX_MSG_RAW,
632                 AR_MCI_INTERRUPT_RX_MSG_GPM,
633                 time_out);
634         }
635 
636         if (time_out) {
637             offset = ar9300_mci_state(ah,
638                 HAL_MCI_STATE_NEXT_GPM_OFFSET, &more_data);
639 
640             if (offset == HAL_MCI_GPM_INVALID) {
641                 continue;
642             }
643             p_gpm = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset);
644             ar9300_mci_print_msg(ah, AH_FALSE, MCI_GPM, 16, p_gpm);
645 
646             recv_type = MCI_GPM_TYPE(p_gpm);
647             recv_opcode = MCI_GPM_OPCODE(p_gpm);
648 
649             if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
650                 if (recv_type == gpm_type) {
651                     if ((gpm_type == MCI_GPM_BT_CAL_DONE) && !b_is_bt_cal_done)
652                     {
653                         gpm_type = MCI_GPM_BT_CAL_GRANT;
654                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
655                             "(MCI) Rcv BT_CAL_DONE. Now Wait BT_CAL_GRANT\n");
656                         continue;
657                     }
658                     if (gpm_type == MCI_GPM_BT_CAL_GRANT) {
659                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
660                             "(MCI) BT_CAL_GRANT seq=%d, req_count=%d\n",
661                             *(p_gpm + 2), *(p_gpm + 3));
662                     }
663                     break;
664                 }
665             }
666             else {
667                 if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) {
668                     break;
669                 }
670             }
671 
672             /* not expected message */
673 
674             /*
675              * Check if it's cal_grant
676              *
677              * When we're waiting for cal_grant in reset routine, it's
678              * possible that BT sends out cal_request at the same time.
679              * Since BT's calibration doesn't happen that often, we'll
680              * let BT completes calibration then we continue to wait
681              * for cal_grant from BT.
682              * Orginal: Wait BT_CAL_GRANT.
683              * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT -> wait
684              * BT_CAL_DONE -> Wait BT_CAL_GRANT.
685              */
686             if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
687                 (recv_type == MCI_GPM_BT_CAL_REQ))
688             {
689                 u_int32_t payload[4] = {0, 0, 0, 0};
690 
691                 gpm_type = MCI_GPM_BT_CAL_DONE;
692                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
693                     "(MCI) Rcv BT_CAL_REQ. Send WLAN_CAL_GRANT.\n");
694 
695                 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
696                 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16,
697                     AH_FALSE, AH_FALSE);
698 
699                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
700                     "(MCI) Now wait for BT_CAL_DONE.\n");
701                 continue;
702             }
703             else {
704                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
705                     "(MCI) GPM subtype not match 0x%x\n", *(p_gpm + 1));
706                 mismatch++;
707                 ar9300_mci_process_gpm_extra(ah, recv_type, recv_opcode, p_gpm);
708             }
709         }
710     }
711     if (p_gpm != NULL) {
712         MCI_GPM_RECYCLE(p_gpm);
713         p_gpm = NULL;
714     }
715 
716     if (time_out <= 0) {
717         time_out = 0;
718         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
719             "(MCI) GPM receiving timeout, mismatch = %d\n", mismatch);
720     } else {
721         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
722             "(MCI) Receive GPM type=0x%x, code=0x%x\n", gpm_type, gpm_opcode);
723     }
724 
725     while (more_data == HAL_MCI_GPM_MORE) {
726         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) discard remaining GPM\n");
727         offset = ar9300_mci_state(ah,
728             HAL_MCI_STATE_NEXT_GPM_OFFSET, &more_data);
729 
730         if (offset == HAL_MCI_GPM_INVALID) {
731             break;
732         }
733         p_gpm = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset);
734         ar9300_mci_print_msg(ah, AH_FALSE, MCI_GPM, 16, p_gpm);
735         recv_type = MCI_GPM_TYPE(p_gpm);
736         recv_opcode = MCI_GPM_OPCODE(p_gpm);
737         if (!MCI_GPM_IS_CAL_TYPE(recv_type)) {
738             ar9300_mci_process_gpm_extra(ah, recv_type, recv_opcode, p_gpm);
739         }
740         MCI_GPM_RECYCLE(p_gpm);
741     }
742 
743     return time_out;
744 }
745 
746 static void ar9300_mci_prep_interface(struct ath_hal *ah)
747 {
748     struct ath_hal_9300 *ahp = AH9300(ah);
749     u_int32_t saved_mci_int_en;
750     u_int32_t mci_timeout = 150;
751 
752     ahp->ah_mci_bt_state = MCI_BT_SLEEP;
753 
754     saved_mci_int_en = OS_REG_READ(ah, AR_MCI_INTERRUPT_EN);
755     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
756 
757     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
758         OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
759     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
760         OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW));
761 
762     /* Remote Reset */
763     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Reset sequence start\n", __func__);
764     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
765     ar9300_mci_remote_reset(ah, AH_TRUE);
766 
767     /*
768      * This delay is required for the reset delay worst case value 255 in
769      * MCI_COMMAND2 register
770      */
771     if (AR_SREV_JUPITER_10(ah)) {
772         OS_DELAY(252);
773     }
774 
775     /* Send REQ_WAKE to BT */
776     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send REQ_WAKE to remote(BT)\n",
777         __func__);
778 
779     ar9300_mci_send_req_wake(ah, AH_TRUE);
780 
781     if (ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
782         AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500))
783     {
784         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
785             "(MCI) %s: Saw SYS_WAKING from remote(BT)\n", __func__);
786         ahp->ah_mci_bt_state = MCI_BT_AWAKE;
787 
788         if (AR_SREV_JUPITER_10(ah)) {
789             OS_DELAY(10);
790         }
791         /*
792          * We don't need to send more remote_reset at this moment.
793          *
794          * If BT receive first remote_reset, then BT HW will be cleaned up and
795          * will be able to receive req_wake and BT HW will respond sys_waking.
796          * In this case, WLAN will receive BT's HW sys_waking.
797          *
798          * Otherwise, if BT SW missed initial remote_reset, that remote_reset
799          * will still clean up BT MCI RX, and the req_wake will wake BT up,
800          * and BT SW will respond this req_wake with a remote_reset and
801          * sys_waking. In this case, WLAN will receive BT's SW sys_waking.
802          *
803          * In either case, BT's RX is cleaned up. So we don't need to reply
804          * BT's remote_reset now, if any.
805          *
806          * Similarly, if in any case, WLAN can receive BT's sys_waking, that
807          * means WLAN's RX is also fine.
808          */
809 
810         /* Send SYS_WAKING to BT */
811         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
812             "(MCI) %s: Send SW SYS_WAKING to remot(BT)\n", __func__);
813         ar9300_mci_send_sys_waking(ah, AH_TRUE);
814 
815         OS_DELAY(10);
816 
817         /*
818          * Set BT priority interrupt value to be 0xff to
819          * avoid having too many BT PRIORITY interrupts.
820          */
821 
822         OS_REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);
823         OS_REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);
824         OS_REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);
825         OS_REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF);
826         OS_REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF);
827 
828         /*
829          * A contention reset will be received after send out sys_waking.
830          * Also BT priority interrupt bits will be set. Clear those bits
831          * before the next step.
832          */
833         OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
834             AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
835         OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI);
836 
837         if (AR_SREV_JUPITER_10(ah) || ahp->ah_mci_coex_is_2g) {
838             /* Send LNA_TRANS */
839             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send LNA_TRANS to BT\n",
840                 __func__);
841             ar9300_mci_send_lna_transfer(ah, AH_TRUE);
842 
843             OS_DELAY(5);
844         }
845 
846         if (AR_SREV_JUPITER_10(ah) ||
847             (ahp->ah_mci_coex_is_2g && !ahp->ah_mci_coex_2g5g_update))
848         {
849             if (ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
850                 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, mci_timeout)) {
851                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
852                     "(MCI) %s: WLAN has control over the LNA & BT obeys it\n",
853                     __func__);
854             } else {
855                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
856                     "(MCI) %s: BT did not respond to LNA_TRANS!\n", __func__);
857                 //ahp->ah_mci_bt_state = MCI_BT_SLEEP;
858             }
859         }
860 
861         if (AR_SREV_JUPITER_10(ah)) {
862             /* Send another remote_reset to deassert BT clk_req. */
863             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
864                 "(MCI) %s: Another remote_reset to deassert clk_req.\n",
865                 __func__);
866             ar9300_mci_remote_reset(ah, AH_TRUE);
867             OS_DELAY(252);
868         }
869     }
870 
871     /* Clear the extra redundant SYS_WAKING from BT */
872     if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
873         (OS_REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
874             AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&
875         (OS_REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
876             AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0))
877     {
878         OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
879             AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
880         OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
881             AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
882     }
883 
884     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
885 }
886 
887 void ar9300_mci_setup(struct ath_hal *ah, u_int32_t gpm_addr,
888                       void *gpm_buf, u_int16_t len,
889                       u_int32_t sched_addr)
890 {
891     struct ath_hal_9300 *ahp = AH9300(ah);
892     void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr));
893 
894     ahp->ah_mci_gpm_addr = gpm_addr;
895     ahp->ah_mci_gpm_buf = gpm_buf;
896     ahp->ah_mci_gpm_len = len;
897     ahp->ah_mci_sched_addr = sched_addr;
898     ahp->ah_mci_sched_buf = sched_buf;
899 
900     ar9300_mci_reset(ah, AH_TRUE, AH_TRUE, AH_TRUE);
901 }
902 
903 void ar9300_mci_disable_interrupt(struct ath_hal *ah)
904 {
905     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
906     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
907 }
908 
909 void ar9300_mci_enable_interrupt(struct ath_hal *ah)
910 {
911     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
912     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
913         AR_MCI_INTERRUPT_RX_MSG_DEFAULT);
914 }
915 
916 void ar9300_mci_reset(struct ath_hal *ah, HAL_BOOL en_int, HAL_BOOL is_2g,
917                       HAL_BOOL is_full_sleep)
918 {
919     struct ath_hal_9300 *ahp = AH9300(ah);
920 //    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
921     u_int32_t regval;
922 
923     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: full_sleep = %d, is_2g = %d\n",
924         __func__, is_full_sleep, is_2g);
925 
926     if (!ahp->ah_mci_gpm_addr && !ahp->ah_mci_sched_addr) {
927         /* GPM buffer and scheduling message buffer are not allocated */
928         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
929             "(MCI) GPM and SCHEDULE buffers not allocated\n");
930         return;
931     }
932 
933     if (OS_REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
934         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
935             "(MCI) %s: ### It's deadbeef, quit mcireset()\n", __func__);
936         return;
937     }
938 
939     /* Program MCI DMA related registers */
940     OS_REG_WRITE(ah, AR_MCI_GPM_0, ahp->ah_mci_gpm_addr);
941     OS_REG_WRITE(ah, AR_MCI_GPM_1, ahp->ah_mci_gpm_len);
942     OS_REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, ahp->ah_mci_sched_addr);
943 
944     /*
945      * To avoid MCI state machine be affected by incoming remote MCI messages,
946      * MCI mode will be enabled later, right before reset the MCI TX and RX.
947      */
948     regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) |
949              SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
950              SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
951              SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
952              SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
953              SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
954              SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
955              SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
956              SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
957 
958     if (AR_SREV_JUPITER_10(ah)) {
959         regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10);
960     }
961 
962     OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
963 
964     if (is_2g && (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) &&
965          !(ah->ah_config.ath_hal_mci_config &
966            ATH_MCI_CONFIG_DISABLE_OSLA))
967     {
968         ar9300_mci_osla_setup(ah, AH_TRUE);
969     }
970     else {
971         ar9300_mci_osla_setup(ah, AH_FALSE);
972     }
973 
974     if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
975         OS_REG_SET_BIT(ah, AR_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
976 
977         OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
978                          AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);
979     }
980 
981     OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0);
982 
983     OS_REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
984 
985     if (ah->ah_config.ath_hal_mci_config & ATH_MCI_CONFIG_CONCUR_TX) {
986         u_int8_t i;
987         u_int32_t const *pmax_tx_pwr;
988 
989         if ((ah->ah_config.ath_hal_mci_config &
990              ATH_MCI_CONFIG_CONCUR_TX) == ATH_MCI_CONCUR_TX_SHARED_CHN)
991         {
992             ahp->ah_mci_concur_tx_en = (ahp->ah_bt_coex_flag &
993                 HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) ? AH_TRUE : AH_FALSE;
994 
995             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) concur_tx_en = %d\n",
996                      ahp->ah_mci_concur_tx_en);
997             /*
998              * We're not relying on HW to reduce WLAN tx power.
999              * Set the max tx power table to 0x7f for all.
1000              */
1001 #if 0
1002             if (AH_PRIVATE(ah)->ah_curchan) {
1003                 chan_flags = AH_PRIVATE(ah)->ah_curchan->channel_flags;
1004             }
1005             if (chan_flags == CHANNEL_G_HT20) {
1006                 pmax_tx_pwr = &mci_concur_tx_max_pwr[2][0];
1007             }
1008             else if (chan_flags == CHANNEL_G) {
1009                 pmax_tx_pwr = &mci_concur_tx_max_pwr[1][0];
1010             }
1011             else if ((chan_flags == CHANNEL_G_HT40PLUS) ||
1012                      (chan_flags == CHANNEL_G_HT40MINUS))
1013             {
1014                 pmax_tx_pwr = &mci_concur_tx_max_pwr[3][0];
1015             }
1016             else {
1017                 pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];
1018             }
1019 
1020             if (ahp->ah_mci_concur_tx_en) {
1021                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1022                         "(MCI) chan flags = 0x%x, max_tx_pwr = %d dBm\n",
1023                         chan_flags,
1024                         (MS(pmax_tx_pwr[2],
1025                          ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK) >> 1));
1026             }
1027 #else
1028             pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];
1029 #endif
1030         }
1031         else if ((ah->ah_config.ath_hal_mci_config &
1032                   ATH_MCI_CONFIG_CONCUR_TX) == ATH_MCI_CONCUR_TX_UNSHARED_CHN)
1033         {
1034             pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];
1035             ahp->ah_mci_concur_tx_en = AH_TRUE;
1036         }
1037         else {
1038             pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];
1039             ahp->ah_mci_concur_tx_en = AH_TRUE;
1040         }
1041 
1042     	/* Default is using rate based TPC. */
1043         OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
1044                          AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0);
1045         OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
1046                          AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f);
1047         OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
1048                          AR_BTCOEX_CTRL_REDUCE_TXPWR, 0);
1049         for (i = 0; i < 8; i++) {
1050             OS_REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), pmax_tx_pwr[i]);
1051         }
1052     }
1053 
1054     regval = MS(ah->ah_config.ath_hal_mci_config,
1055                 ATH_MCI_CONFIG_CLK_DIV);
1056     OS_REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval);
1057 
1058     OS_REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);
1059 
1060     /* Resetting the Rx and Tx paths of MCI */
1061     regval = OS_REG_READ(ah, AR_MCI_COMMAND2);
1062     regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
1063     OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);
1064     OS_DELAY(1);
1065     regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
1066     OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);
1067 
1068     if (is_full_sleep) {
1069         ar9300_mci_mute_bt(ah);
1070         OS_DELAY(100);
1071     }
1072 
1073     regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
1074     OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);
1075     OS_DELAY(1);
1076     regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
1077     OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);
1078 
1079     ar9300_mci_state(ah, HAL_MCI_STATE_INIT_GPM_OFFSET, NULL);
1080     OS_REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
1081              (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
1082               SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
1083     OS_REG_CLR_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
1084 
1085     if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
1086         ar9300_mci_observation_set_up(ah);
1087     }
1088 
1089     ahp->ah_mci_ready = AH_TRUE;
1090     ar9300_mci_prep_interface(ah);
1091 
1092     if (en_int) {
1093         ar9300_mci_enable_interrupt(ah);
1094     }
1095 
1096 #if ATH_SUPPORT_AIC
1097     if (ahp->ah_aic_enabled) {
1098         ar9300_aic_start_normal(ah);
1099     }
1100 #endif
1101 }
1102 
1103 static void ar9300_mci_queue_unsent_gpm(struct ath_hal *ah, u_int8_t header,
1104                                         u_int32_t *payload, HAL_BOOL queue)
1105 {
1106     struct ath_hal_9300 *ahp = AH9300(ah);
1107     u_int8_t type, opcode;
1108 
1109     if (queue == AH_TRUE) {
1110         if (payload != NULL) {
1111             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1112                 "(MCI) ERROR: Send fail: %02x: %02x %02x %02x\n",
1113                 header,
1114                 *(((u_int8_t *)payload) + 4),
1115                 *(((u_int8_t *)payload) + 5),
1116                 *(((u_int8_t *)payload) + 6));
1117         } else {
1118             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1119                 "(MCI) ERROR: Send fail: %02x\n", header);
1120         }
1121     }
1122     /* check if the message is to be queued */
1123     if (header == MCI_GPM) {
1124         type = MCI_GPM_TYPE(payload);
1125         opcode = MCI_GPM_OPCODE(payload);
1126 
1127         if (type == MCI_GPM_COEX_AGENT) {
1128             switch (opcode)
1129             {
1130                 case MCI_GPM_COEX_BT_UPDATE_FLAGS:
1131                     if (AR_SREV_JUPITER_10(ah)) {
1132                         break;
1133                     }
1134                     if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==
1135                         MCI_GPM_COEX_BT_FLAGS_READ)
1136                     {
1137                         break;
1138                     }
1139                     ahp->ah_mci_coex_2g5g_update = queue;
1140                     if (queue == AH_TRUE) {
1141                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1142                             "(MCI) BT_MCI_FLAGS: 2G5G status <queued> %s.\n",
1143                             ahp->ah_mci_coex_is_2g?"2G":"5G");
1144                     }
1145                     else {
1146                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1147                             "(MCI) BT_MCI_FLAGS: 2G5G status <sent> %s.\n",
1148                             ahp->ah_mci_coex_is_2g?"2G":"5G");
1149                     }
1150                     break;
1151 
1152                 case MCI_GPM_COEX_WLAN_CHANNELS:
1153                     ahp->ah_mci_coex_wlan_channels_update = queue;
1154                     if (queue == AH_TRUE) {
1155                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1156                             "(MCI) WLAN channel map <queued>.\n");
1157                     }
1158                     else {
1159                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1160                             "(MCI) WLAN channel map <sent>.\n");
1161                     }
1162                     break;
1163 
1164                 case MCI_GPM_COEX_HALT_BT_GPM:
1165                     if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
1166                         MCI_GPM_COEX_BT_GPM_UNHALT)
1167                     {
1168                         ahp->ah_mci_unhalt_bt_gpm = queue;
1169                         if (queue == AH_TRUE) {
1170                             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1171                                 "(MCI) UNHALT BT GPM <queued>.\n");
1172                         }
1173                         else {
1174                             ahp->ah_mci_halted_bt_gpm = AH_FALSE;
1175                             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1176                                 "(MCI) UNHALT BT GPM <sent>.\n");
1177                         }
1178                     }
1179                     if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
1180                         MCI_GPM_COEX_BT_GPM_HALT)
1181                     {
1182                         ahp->ah_mci_halted_bt_gpm = !queue;
1183                         if (queue == AH_TRUE) {
1184                             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1185                                 "(MCI) HALT BT GPM <not sent>.\n");
1186                         }
1187                         else {
1188                             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1189                                 "(MCI) HALT BT GPM <sent>.\n");
1190                         }
1191                     }
1192                     break;
1193 
1194                 default:
1195                     break;
1196             }
1197         }
1198     }
1199 }
1200 
1201 HAL_BOOL ar9300_mci_send_message(struct ath_hal *ah, u_int8_t header,
1202                               u_int32_t flag, u_int32_t *payload,
1203                               u_int8_t len, HAL_BOOL wait_done, HAL_BOOL check_bt)
1204 {
1205     int i;
1206     struct ath_hal_9300 *ahp = AH9300(ah);
1207     HAL_BOOL msg_sent = AH_FALSE;
1208     u_int32_t regval;
1209     u_int32_t saved_mci_int_en = OS_REG_READ(ah, AR_MCI_INTERRUPT_EN);
1210 
1211     regval = OS_REG_READ(ah, AR_BTCOEX_CTRL);
1212     if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {
1213         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1214             "(MCI) %s: Not send 0x%x. MCI is not enabled. full_sleep = %d\n",
1215             __func__, header, ahp->ah_chip_full_sleep);
1216         ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE);
1217         return AH_FALSE;
1218     }
1219     else if (check_bt && (ahp->ah_mci_bt_state == MCI_BT_SLEEP)) {
1220         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1221             "(MCI) %s: Don't send message(0x%x). BT is in sleep state\n",
1222             __func__, header);
1223         ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE);
1224         return AH_FALSE;
1225     }
1226 
1227     if (wait_done) {
1228         OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
1229     }
1230 
1231     /* Need to clear SW_MSG_DONE raw bit before wait */
1232     OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
1233         AR_MCI_INTERRUPT_SW_MSG_DONE | AR_MCI_INTERRUPT_MSG_FAIL_MASK);
1234 
1235     if (payload != AH_NULL) {
1236         for (i = 0; (i*4) < len; i++) {
1237             OS_REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i*4), *(payload + i));
1238         }
1239     }
1240     ar9300_mci_print_msg(ah, AH_TRUE, header, len, payload);
1241 
1242     OS_REG_WRITE(ah, AR_MCI_COMMAND0,
1243                 (SM((flag & HAL_MCI_FLAG_DISABLE_TIMESTAMP),
1244                  AR_MCI_COMMAND0_DISABLE_TIMESTAMP) |
1245                  SM(len, AR_MCI_COMMAND0_LEN) |
1246                  SM(header, AR_MCI_COMMAND0_HEADER)));
1247 
1248     if (wait_done &&
1249         ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,
1250                                     AR_MCI_INTERRUPT_SW_MSG_DONE, 500) == 0)
1251     {
1252         ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE);
1253     }
1254     else {
1255         ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_FALSE);
1256         msg_sent = AH_TRUE;
1257     }
1258 
1259     if (wait_done) {
1260         OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
1261     }
1262 
1263     return msg_sent;
1264 }
1265 
1266 u_int32_t ar9300_mci_get_interrupt(struct ath_hal *ah, u_int32_t *mci_int,
1267                                    u_int32_t *mci_int_rx_msg)
1268 {
1269     struct ath_hal_9300 *ahp = AH9300(ah);
1270 
1271     *mci_int = ahp->ah_mci_int_raw;
1272     *mci_int_rx_msg = ahp->ah_mci_int_rx_msg;
1273 
1274     /* Clean int bits after the values are read. */
1275     ahp->ah_mci_int_raw = 0;
1276     ahp->ah_mci_int_rx_msg = 0;
1277 
1278     return 0;
1279 }
1280 
1281 u_int32_t ar9300_mci_check_int(struct ath_hal *ah, u_int32_t ints)
1282 {
1283     u_int32_t reg;
1284 
1285     reg = OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
1286     return ((reg & ints) == ints);
1287 }
1288 
1289 void ar9300_mci_sync_bt_state(struct ath_hal *ah)
1290 {
1291     struct ath_hal_9300 *ahp = AH9300(ah);
1292     u_int32_t cur_bt_state;
1293 
1294     cur_bt_state = ar9300_mci_state(ah, HAL_MCI_STATE_REMOTE_SLEEP, NULL);
1295     if (ahp->ah_mci_bt_state != cur_bt_state) {
1296         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1297             "(MCI) %s: BT state mismatches. old: %d, new: %d\n",
1298             __func__, ahp->ah_mci_bt_state, cur_bt_state);
1299         ahp->ah_mci_bt_state = cur_bt_state;
1300     }
1301     if (ahp->ah_mci_bt_state != MCI_BT_SLEEP) {
1302 #if MCI_QUERY_BT_VERSION_VERBOSE
1303         ar9300_mci_send_coex_version_query(ah, AH_TRUE);
1304 #endif
1305         ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);
1306         if (ahp->ah_mci_unhalt_bt_gpm == AH_TRUE) {
1307             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: UNHALT BT GPM\n", __func__);
1308             ar9300_mci_send_coex_halt_bt_gpm(ah, AH_FALSE, AH_TRUE);
1309         }
1310     }
1311 }
1312 
1313 static HAL_BOOL ar9300_mci_is_gpm_valid(struct ath_hal *ah, u_int32_t msg_index)
1314 {
1315     struct ath_hal_9300 *ahp = AH9300(ah);
1316     u_int32_t *payload;
1317     u_int32_t recv_type, offset = msg_index << 4;
1318 
1319     if (msg_index == HAL_MCI_GPM_INVALID) {
1320         return AH_FALSE;
1321     }
1322 
1323     payload = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset);
1324     recv_type = MCI_GPM_TYPE(payload);
1325 
1326     if (recv_type == MCI_GPM_RSVD_PATTERN) {
1327         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Skip RSVD GPM\n");
1328         return AH_FALSE;
1329     }
1330 
1331     return AH_TRUE;
1332 }
1333 
1334 u_int32_t
1335 ar9300_mci_state(struct ath_hal *ah, u_int32_t state_type, u_int32_t *p_data)
1336 {
1337     u_int32_t   value = 0, more_gpm = 0, gpm_ptr;
1338     struct ath_hal_9300 *ahp = AH9300(ah);
1339 
1340     switch (state_type) {
1341         case HAL_MCI_STATE_ENABLE:
1342             if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
1343                 value = OS_REG_READ(ah, AR_BTCOEX_CTRL);
1344                 if ((value == 0xdeadbeef) || (value == 0xffffffff)) {
1345                     //    HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1346                     //        "(MCI) BTCOEX_CTRL = 0xdeadbeef\n");
1347                     value = 0;
1348                 }
1349             }
1350             value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
1351             break;
1352 
1353         case HAL_MCI_STATE_INIT_GPM_OFFSET:
1354             value = MS(OS_REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1355             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1356                     "(MCI) %s: GPM initial WRITE_PTR=%d.\n", __func__, value);
1357             ahp->ah_mci_gpm_idx = value;
1358             break;
1359 
1360         case HAL_MCI_STATE_NEXT_GPM_OFFSET:
1361         case HAL_MCI_STATE_LAST_GPM_OFFSET:
1362             /*
1363              * This could be useful to avoid new GPM message interrupt which
1364              * may lead to spurious interrupt after power sleep, or multiple
1365              * entry of ath_coex_mci_intr().
1366              * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1367              * alleviate this effect, but clearing GPM RX interrupt bit is
1368              * safe, because whether this is called from HAL or LMAC, there
1369              * must be an interrupt bit set/triggered initially.
1370              */
1371             OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
1372                          AR_MCI_INTERRUPT_RX_MSG_GPM);
1373 
1374             gpm_ptr = MS(OS_REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1375             value = gpm_ptr;
1376 
1377             if (value == 0) {
1378                 value = ahp->ah_mci_gpm_len - 1;
1379             }
1380             else if (value >= ahp->ah_mci_gpm_len) {
1381                 if (value != 0xFFFF) {
1382                     value = 0;
1383                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1384                         "(MCI) %s: GPM offset out of range.\n", __func__);
1385                 }
1386             }
1387             else {
1388                 value--;
1389             }
1390 
1391             if (value == 0xFFFF) {
1392                 value = HAL_MCI_GPM_INVALID;
1393                 more_gpm = HAL_MCI_GPM_NOMORE;
1394                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1395                         "(MCI) %s: GPM ptr invalid "
1396                         "@ptr=%d, @offset=%d, more=NOMORE.\n",
1397                         __func__, gpm_ptr, value);
1398             }
1399             else if (state_type == HAL_MCI_STATE_NEXT_GPM_OFFSET) {
1400                 if (gpm_ptr == ahp->ah_mci_gpm_idx) {
1401                     value = HAL_MCI_GPM_INVALID;
1402                     more_gpm = HAL_MCI_GPM_NOMORE;
1403                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1404                             "(MCI) %s: GPM message not available "
1405                             "@ptr=%d, @offset=%d, more=NOMORE.\n",
1406                             __func__, gpm_ptr, value);
1407                 }
1408                 else {
1409                     while (1) {
1410                         u_int32_t temp_index;
1411 
1412                         /* skip reserved GPM if any */
1413                         if (value != ahp->ah_mci_gpm_idx) {
1414                             more_gpm = HAL_MCI_GPM_MORE;
1415                         }
1416                         else {
1417                             more_gpm = HAL_MCI_GPM_NOMORE;
1418                         }
1419                         temp_index = ahp->ah_mci_gpm_idx;
1420                         ahp->ah_mci_gpm_idx++;
1421                         if (ahp->ah_mci_gpm_idx >= ahp->ah_mci_gpm_len) {
1422                             ahp->ah_mci_gpm_idx = 0;
1423                         }
1424                         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1425                                 "(MCI) %s: GPM message got "
1426                                 "@ptr=%d, @offset=%d, more=%s.\n",
1427                                 __func__, gpm_ptr, temp_index,
1428                                 (more_gpm == HAL_MCI_GPM_MORE)?"MORE":"NOMORE");
1429                         if (ar9300_mci_is_gpm_valid(ah, temp_index)) {
1430                             value = temp_index;
1431                             break;
1432                         }
1433                         if (more_gpm == HAL_MCI_GPM_NOMORE) {
1434                             value = HAL_MCI_GPM_INVALID;
1435                             break;
1436                         }
1437                     }
1438                 }
1439                 if (p_data != NULL) {
1440                     *p_data = more_gpm;
1441                 }
1442             }
1443             if (value != HAL_MCI_GPM_INVALID) {
1444                 value <<= 4;
1445             }
1446             break;
1447 
1448     case HAL_MCI_STATE_LAST_SCHD_MSG_OFFSET:
1449         value = MS(OS_REG_READ(ah, AR_MCI_RX_STATUS),
1450             AR_MCI_RX_LAST_SCHD_MSG_INDEX);
1451 
1452 #if AH_MCI_DEBUG_PRINT_SCHED
1453         {
1454             u_int32_t index = value;
1455             u_int32_t prev_index, sched_idx;
1456             u_int32_t *pld;
1457             u_int8_t  *pld8;
1458             u_int32_t wbtimer = OS_REG_READ(ah, AR_BTCOEX_WBTIMER);
1459             u_int32_t schd_ctl = OS_REG_READ(ah, AR_MCI_HW_SCHD_TBL_CTL);
1460 
1461             if (index > 0) {
1462                 prev_index = index - 1;
1463             } else {
1464                 prev_index = index;
1465             }
1466 
1467             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED\n");
1468             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1469                 "(MCI) SCHED SCHD_TBL_CTRL=0x%08x, WBTIMER=0x%08x (%d)\n",
1470                 schd_ctl, wbtimer, wbtimer);
1471             for (sched_idx = prev_index; sched_idx <= index; sched_idx++) {
1472                 pld = (u_int32_t *) (ahp->ah_mci_sched_buf + (sched_idx << 4));
1473                 pld8 = (u_int8_t *) pld;
1474 
1475                 ar9300_mci_print_msg(ah, AH_FALSE, MCI_SCHD_INFO, 16, pld);
1476                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1477                     "(MCI) SCHED    idx=%d, T1=0x%08x (%d), T2=0x%08x (%d)\n",
1478                     sched_idx,
1479                     pld[0], pld[0], pld[1], pld[1]);
1480                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1481                     "(MCI) SCHED    addr=%d %s pwr=%d prio=%d %s link=%d\n",
1482                     pld8[11] >> 4,
1483                     (pld8[11] & 0x08)?"TX":"RX",
1484                     (int8_t) (((pld8[11] & 0x07) << 5) | (pld8[10] >> 3)),
1485                     (((pld8[10] & 0x07) << 5) | (pld8[9] >> 3)),
1486                     (pld8[9] & 0x04)?"LE":"BR/EDR",
1487                     (((pld8[9] & 0x03) << 2) | (pld8[8] >> 6)));
1488             }
1489         }
1490 #endif /* AH_MCI_DEBUG_PRINT_SCHED */
1491 
1492         /* Make it in bytes */
1493         value <<= 4;
1494         break;
1495 
1496     case HAL_MCI_STATE_REMOTE_SLEEP:
1497         value = MS(OS_REG_READ(ah, AR_MCI_RX_STATUS),
1498             AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE;
1499         break;
1500 
1501         case HAL_MCI_STATE_CONT_RSSI_POWER:
1502             value = MS(ahp->ah_mci_cont_status,
1503                 AR_MCI_CONT_RSSI_POWER);
1504             break;
1505 
1506         case HAL_MCI_STATE_CONT_PRIORITY:
1507             value = MS(ahp->ah_mci_cont_status,
1508                 AR_MCI_CONT_RRIORITY);
1509             break;
1510 
1511         case HAL_MCI_STATE_CONT_TXRX:
1512             value = MS(ahp->ah_mci_cont_status,
1513                 AR_MCI_CONT_TXRX);
1514             break;
1515 
1516         case HAL_MCI_STATE_BT:
1517             value = ahp->ah_mci_bt_state;
1518             break;
1519 
1520         case HAL_MCI_STATE_SET_BT_SLEEP:
1521             ahp->ah_mci_bt_state = MCI_BT_SLEEP;
1522             break;
1523 
1524         case HAL_MCI_STATE_SET_BT_AWAKE:
1525             ahp->ah_mci_bt_state = MCI_BT_AWAKE;
1526             ar9300_mci_send_coex_version_query(ah, AH_TRUE);
1527             ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);
1528             if (ahp->ah_mci_unhalt_bt_gpm == AH_TRUE) {
1529                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1530                     "(MCI) %s: UNHALT BT GPM\n", __func__);
1531                 ar9300_mci_send_coex_halt_bt_gpm(ah, AH_FALSE, AH_TRUE);
1532             }
1533             ar9300_mci_2g5g_switch(ah, AH_TRUE);
1534             break;
1535 
1536         case HAL_MCI_STATE_SET_BT_CAL_START:
1537             ahp->ah_mci_bt_state = MCI_BT_CAL_START;
1538             break;
1539 
1540         case HAL_MCI_STATE_SET_BT_CAL:
1541             ahp->ah_mci_bt_state = MCI_BT_CAL;
1542             break;
1543 
1544         case HAL_MCI_STATE_RESET_REQ_WAKE:
1545             ar9300_mci_reset_req_wakeup(ah);
1546             ahp->ah_mci_coex_2g5g_update = AH_TRUE;
1547 
1548             if ((AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) &&
1549                 (ah->ah_config.ath_hal_mci_config &
1550                  ATH_MCI_CONFIG_MCI_OBS_MASK))
1551             {
1552                 /* Check if we still have control of the GPIOs */
1553                 if ((OS_REG_READ(ah, AR_GLB_GPIO_CONTROL) &
1554                      ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
1555                      ATH_MCI_CONFIG_MCI_OBS_GPIO)
1556                  {
1557                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1558                         "(MCI) Reconfigure observation\n");
1559                     ar9300_mci_observation_set_up(ah);
1560                  }
1561             }
1562 
1563             break;
1564 
1565         case HAL_MCI_STATE_SEND_WLAN_COEX_VERSION:
1566             ar9300_mci_send_coex_version_response(ah, AH_TRUE);
1567             break;
1568 
1569         case HAL_MCI_STATE_SET_BT_COEX_VERSION:
1570             if (p_data == NULL) {
1571                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1572                     "(MCI) Error: Set BT Coex version with NULL data !!!\n");
1573             }
1574             else {
1575                 ahp->ah_mci_coex_major_version_bt = (*p_data >> 8) & 0xff;
1576                 ahp->ah_mci_coex_minor_version_bt = (*p_data) & 0xff;
1577                 ahp->ah_mci_coex_bt_version_known = AH_TRUE;
1578                 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT version set: %d.%d\n",
1579                         ahp->ah_mci_coex_major_version_bt,
1580                         ahp->ah_mci_coex_minor_version_bt);
1581             }
1582             break;
1583 
1584         case HAL_MCI_STATE_SEND_WLAN_CHANNELS:
1585             if (p_data != NULL)
1586             {
1587                 if (((ahp->ah_mci_coex_wlan_channels[1] & 0xffff0000) ==
1588                     (*(p_data + 1) & 0xffff0000)) &&
1589                     (ahp->ah_mci_coex_wlan_channels[2] == *(p_data + 2)) &&
1590                     (ahp->ah_mci_coex_wlan_channels[3] == *(p_data + 3)))
1591                 {
1592                     break;
1593                 }
1594                 ahp->ah_mci_coex_wlan_channels[0] = *p_data++;
1595                 ahp->ah_mci_coex_wlan_channels[1] = *p_data++;
1596                 ahp->ah_mci_coex_wlan_channels[2] = *p_data++;
1597                 ahp->ah_mci_coex_wlan_channels[3] = *p_data++;
1598             }
1599             ahp->ah_mci_coex_wlan_channels_update = AH_TRUE;
1600             ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);
1601             break;
1602 
1603         case HAL_MCI_STATE_SEND_VERSION_QUERY:
1604             ar9300_mci_send_coex_version_query(ah, AH_TRUE);
1605             break;
1606 
1607         case HAL_MCI_STATE_SEND_STATUS_QUERY:
1608             if (AR_SREV_JUPITER_10(ah)) {
1609                 ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE,
1610                         MCI_GPM_COEX_QUERY_BT_ALL_INFO);
1611             } else {
1612                 ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE,
1613                         MCI_GPM_COEX_QUERY_BT_TOPOLOGY);
1614             }
1615             break;
1616 
1617         case HAL_MCI_STATE_NEED_FLUSH_BT_INFO:
1618             /*
1619              * ah_mci_unhalt_bt_gpm means whether it's needed to send
1620              * UNHALT message. It's set whenever there's a request to send HALT
1621              * message. ah_mci_halted_bt_gpm means whether HALT message is sent
1622              * out successfully.
1623              *
1624              * Checking (ah_mci_unhalt_bt_gpm == AH_FALSE) instead of checking
1625              * (ahp->ah_mci_halted_bt_gpm == AH_FALSE) will make sure currently is
1626              * in UNHALT-ed mode and BT can respond to status query.
1627              */
1628             if ((ahp->ah_mci_unhalt_bt_gpm == AH_FALSE) &&
1629                 (ahp->ah_mci_need_flush_btinfo == AH_TRUE))
1630             {
1631                 value = 1;
1632             }
1633             else {
1634                 value = 0;
1635             }
1636             if (p_data != NULL) {
1637                 ahp->ah_mci_need_flush_btinfo = (*p_data != 0)? AH_TRUE : AH_FALSE;
1638             }
1639             break;
1640 
1641         case HAL_MCI_STATE_SET_CONCUR_TX_PRI:
1642             if (p_data) {
1643                 ahp->ah_mci_stomp_none_tx_pri = *p_data & 0xff;
1644                 ahp->ah_mci_stomp_low_tx_pri = (*p_data >> 8) & 0xff;
1645                 ahp->ah_mci_stomp_all_tx_pri = (*p_data >> 16) & 0xff;
1646             }
1647             break;
1648 
1649         case HAL_MCI_STATE_RECOVER_RX:
1650             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) hal RECOVER_RX\n");
1651             ar9300_mci_prep_interface(ah);
1652             ahp->ah_mci_query_bt = AH_TRUE;
1653             ahp->ah_mci_need_flush_btinfo = AH_TRUE;
1654             ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);
1655             ar9300_mci_2g5g_switch(ah, AH_TRUE);
1656             break;
1657 
1658         case HAL_MCI_STATE_DEBUG:
1659             if (p_data != NULL) {
1660                 if (*p_data == HAL_MCI_STATE_DEBUG_REQ_BT_DEBUG) {
1661                     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) QUERY_BT_DEBUG\n");
1662                     ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE,
1663                         MCI_GPM_COEX_QUERY_BT_DEBUG);
1664                     OS_DELAY(10);
1665                     if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
1666                         ar9300_mci_send_coex_bt_flags(ah, AH_TRUE,
1667                             MCI_GPM_COEX_BT_FLAGS_READ, 0);
1668                     }
1669                 }
1670             }
1671             break;
1672 
1673         case HAL_MCI_STATE_NEED_FTP_STOMP:
1674             value = (ah->ah_config.ath_hal_mci_config &
1675                      ATH_MCI_CONFIG_DISABLE_FTP_STOMP) ? 0 : 1;
1676             break;
1677 
1678         case HAL_MCI_STATE_NEED_TUNING:
1679             value = (ah->ah_config.ath_hal_mci_config &
1680                      ATH_MCI_CONFIG_DISABLE_TUNING) ? 0 : 1;
1681             break;
1682 
1683         case HAL_MCI_STATE_SHARED_CHAIN_CONCUR_TX:
1684             value = ((ah->ah_config.ath_hal_mci_config &
1685                      ATH_MCI_CONFIG_CONCUR_TX) ==
1686                      ATH_MCI_CONCUR_TX_SHARED_CHN)? 1 : 0;
1687             break;
1688 
1689         default:
1690             break;
1691     }
1692     return value;
1693 }
1694 
1695 void ar9300_mci_detach(struct ath_hal *ah)
1696 {
1697     /* Turn off MCI and Jupiter mode. */
1698     OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
1699     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) ar9300_mci_detach\n");
1700     ar9300_mci_disable_interrupt(ah);
1701 }
1702 
1703 /*
1704  * Low priority BT: 0 - 59(0x3b)
1705  * High priority BT: 60 - 125(0x7d)
1706  * Critical BT: 126 - 255
1707 
1708     BTCOEX_WL_WEIGHTS0_VALUE0 ; // wl_idle
1709     BTCOEX_WL_WEIGHTS0_VALUE1 ; // sw_ctrl[3] - all_stomp
1710     BTCOEX_WL_WEIGHTS0_VALUE2 ; // sw_ctrl[2] - all_not_stomp
1711     BTCOEX_WL_WEIGHTS0_VALUE3 ; // sw_ctrl[1] - pa_pre_distortion
1712     BTCOEX_WL_WEIGHTS1_VALUE0 ; // sw_ctrl[0] - general purpose
1713     BTCOEX_WL_WEIGHTS1_VALUE1 ; // tm_wl_wait_beacon
1714     BTCOEX_WL_WEIGHTS1_VALUE2 ; // ts_state_wait_ack_cts
1715     BTCOEX_WL_WEIGHTS1_VALUE3 ; // self_gen
1716     BTCOEX_WL_WEIGHTS2_VALUE0 ; // idle
1717     BTCOEX_WL_WEIGHTS2_VALUE1 ; // rx
1718     BTCOEX_WL_WEIGHTS2_VALUE2 ; // tx
1719     BTCOEX_WL_WEIGHTS2_VALUE3 ; // rx + tx
1720     BTCOEX_WL_WEIGHTS3_VALUE0 ; // tx
1721     BTCOEX_WL_WEIGHTS3_VALUE1 ; // rx
1722     BTCOEX_WL_WEIGHTS3_VALUE2 ; // tx
1723     BTCOEX_WL_WEIGHTS3_VALUE3 ; // rx + tx
1724 
1725     Stomp all:
1726     ah_bt_coex_wlan_weight[0] = 0x00007d00
1727     ah_bt_coex_wlan_weight[1] = 0x7d7d7d00
1728     ah_bt_coex_wlan_weight[2] = 0x7d7d7d00
1729     ah_bt_coex_wlan_weight[3] = 0x7d7d7d7d
1730     Stomp low:
1731     ah_bt_coex_wlan_weight[0] = 0x00007d00
1732     ah_bt_coex_wlan_weight[1] = 0x7d3b3b00
1733     ah_bt_coex_wlan_weight[2] = 0x3b3b3b00
1734     ah_bt_coex_wlan_weight[3] = 0x3b3b3b3b
1735     Stomp none:
1736     ah_bt_coex_wlan_weight[0] = 0x00007d00
1737     ah_bt_coex_wlan_weight[1] = 0x7d000000
1738     ah_bt_coex_wlan_weight[2] = 0x00000000
1739     ah_bt_coex_wlan_weight[3] = 0x00000000
1740 */
1741 
1742 void ar9300_mci_bt_coex_set_weights(struct ath_hal *ah, u_int32_t stomp_type)
1743 {
1744     struct ath_hal_9300 *ahp = AH9300(ah);
1745 //    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
1746     u_int32_t tx_priority = 0;
1747 
1748     switch (stomp_type) {
1749     case HAL_BT_COEX_STOMP_ALL:
1750         ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_ALL_WLAN_WGHT0;
1751         ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_ALL_WLAN_WGHT1;
1752         ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_ALL_WLAN_WGHT2;
1753         ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_ALL_WLAN_WGHT3;
1754         if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_all_tx_pri) {
1755             tx_priority = ahp->ah_mci_stomp_all_tx_pri;
1756         }
1757         break;
1758     case HAL_BT_COEX_STOMP_LOW:
1759         if (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_MCI_FTP_STOMP_RX) {
1760             ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT0;
1761             ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT1;
1762             ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT2;
1763             ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT3;
1764         }
1765         else {
1766             ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_WLAN_WGHT0;
1767             ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_WLAN_WGHT1;
1768             ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_WLAN_WGHT2;
1769             ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_WLAN_WGHT3;
1770         }
1771         if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_low_tx_pri) {
1772             tx_priority = ahp->ah_mci_stomp_low_tx_pri;
1773         }
1774         if (ah->ah_config.ath_hal_mci_config &
1775             ATH_MCI_CONFIG_MCI_OBS_TXRX)
1776         {
1777             ar9300_gpio_set(ah, 5, 1);
1778         }
1779         break;
1780     case HAL_BT_COEX_STOMP_ALL_FORCE:
1781         ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT0;
1782         ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT1;
1783         ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT2;
1784         ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT3;
1785         break;
1786     case HAL_BT_COEX_STOMP_LOW_FORCE:
1787         ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT0;
1788         ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT1;
1789         ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT2;
1790         ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT3;
1791         if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_low_tx_pri) {
1792             tx_priority = ahp->ah_mci_stomp_low_tx_pri;
1793         }
1794         break;
1795     case HAL_BT_COEX_STOMP_NONE:
1796     case HAL_BT_COEX_NO_STOMP:
1797         ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_NONE_WLAN_WGHT0;
1798         ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_NONE_WLAN_WGHT1;
1799         ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_NONE_WLAN_WGHT2;
1800         ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_NONE_WLAN_WGHT3;
1801         if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_none_tx_pri) {
1802             tx_priority = ahp->ah_mci_stomp_none_tx_pri;
1803         }
1804         if (ah->ah_config.ath_hal_mci_config &
1805             ATH_MCI_CONFIG_MCI_OBS_TXRX)
1806         {
1807             ar9300_gpio_set(ah, 5, 0);
1808         }
1809         break;
1810     default:
1811         /* There is a forceWeight from registry */
1812         ahp->ah_bt_coex_wlan_weight[0] = stomp_type;
1813         ahp->ah_bt_coex_wlan_weight[1] = stomp_type;
1814         break;
1815     }
1816 
1817     if (ahp->ah_mci_concur_tx_en && tx_priority) {
1818         ahp->ah_bt_coex_wlan_weight[1] &= ~MCI_CONCUR_TX_WLAN_WGHT1_MASK;
1819         ahp->ah_bt_coex_wlan_weight[1] |=
1820             SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT1_MASK);
1821         ahp->ah_bt_coex_wlan_weight[2] &= ~MCI_CONCUR_TX_WLAN_WGHT2_MASK;
1822         ahp->ah_bt_coex_wlan_weight[2] |=
1823             SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT2_MASK);
1824         ahp->ah_bt_coex_wlan_weight[3] &= ~MCI_CONCUR_TX_WLAN_WGHT3_MASK;
1825         ahp->ah_bt_coex_wlan_weight[3] |=
1826             SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT3_MASK);
1827         ahp->ah_bt_coex_wlan_weight[3] &= ~MCI_CONCUR_TX_WLAN_WGHT3_MASK2;
1828         ahp->ah_bt_coex_wlan_weight[3] |=
1829             SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT3_MASK2);
1830     }
1831     if (ah->ah_config.ath_hal_mci_config &
1832         ATH_MCI_CONFIG_MCI_WEIGHT_DBG)
1833     {
1834         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1835                 "(MCI) Set weights: 0x%08x 0x%08x 0x%08x 0x%08x\n",
1836                 ahp->ah_bt_coex_wlan_weight[0],
1837                 ahp->ah_bt_coex_wlan_weight[1],
1838                 ahp->ah_bt_coex_wlan_weight[2],
1839                 ahp->ah_bt_coex_wlan_weight[3]);
1840     }
1841 }
1842 
1843 void ar9300_mci_bt_coex_disable(struct ath_hal *ah)
1844 {
1845     struct ath_hal_9300 *ahp = AH9300(ah);
1846 
1847     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
1848         "(MCI) %s: Set weight to stomp none.\n", __func__);
1849 
1850     ar9300_mci_bt_coex_set_weights(ah, HAL_BT_COEX_STOMP_NONE);
1851 
1852     /*
1853      * In Jupiter, when coex is disabled, we just set weight
1854      * table to be in favor of WLAN.
1855      */
1856     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, ahp->ah_bt_coex_wlan_weight[0]);
1857     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, ahp->ah_bt_coex_wlan_weight[1]);
1858     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, ahp->ah_bt_coex_wlan_weight[2]);
1859     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, ahp->ah_bt_coex_wlan_weight[3]);
1860 
1861     ahp->ah_bt_coex_enabled = AH_FALSE;
1862 }
1863 
1864 int ar9300_mci_bt_coex_enable(struct ath_hal *ah)
1865 {
1866     struct ath_hal_9300 *ahp = AH9300(ah);
1867 
1868     /* Mainly change the WLAN weight table */
1869     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, ahp->ah_bt_coex_wlan_weight[0]);
1870     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, ahp->ah_bt_coex_wlan_weight[1]);
1871     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, ahp->ah_bt_coex_wlan_weight[2]);
1872     OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, ahp->ah_bt_coex_wlan_weight[3]);
1873 
1874     /* Send ACK even when BT has higher priority. */
1875     OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
1876 
1877     if (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOW_ACK_PWR) {
1878         OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_LOW_ACK_POWER);
1879     }
1880     else {
1881         OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_HIGH_ACK_POWER);
1882     }
1883 
1884     ahp->ah_bt_coex_enabled = AH_TRUE;
1885 
1886     return 0;
1887 }
1888 
1889 #endif /* ATH_SUPPORT_MCI */
1890