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