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
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
107static 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
119static 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
166void 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
176void 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
184static 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
192void 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
198static 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
207static 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
213static void
214ar9300_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
228static void
229ar9300_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
244static void
245ar9300_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
260static 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
292void 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
318static 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
345void 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
362static 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
397void 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
455void 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
484static 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
558static 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
623u_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
760static 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
903void 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
919void 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
925void 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
932static 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
952static 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
972static 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
994void 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
1184static 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
1282HAL_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
1347u_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
1362u_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
1370void 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
1394static 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
1415u_int32_t
1416ar9300_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
1776void 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
1823void 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
1932void 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
1953int 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