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
32static 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
63static
64void 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
103static 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
115static 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
162void 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
172void 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
180static 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
188void 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
194static 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
203static 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
209static void
210ar9300_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
224static void
225ar9300_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
240static void
241ar9300_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
256static 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
288void 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
314static 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
341void 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
358static 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
393void 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
451void 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
475static 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
544static 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
609u_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
746static 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
887void 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
903void 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
909void 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
916void 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
1103static 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
1201HAL_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
1266u_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
1281u_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
1289void 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
1313static 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
1334u_int32_t
1335ar9300_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
1695void 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
1742void 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
1843void 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
1864int 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