The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: a059b05aa699f378a0ce75f9b22ce504


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.