Path: blob/main/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c
48526 views
/*1* Copyright (c) 2013 Qualcomm Atheros, Inc.2*3* Permission to use, copy, modify, and/or distribute this software for any4* purpose with or without fee is hereby granted, provided that the above5* copyright notice and this permission notice appear in all copies.6*7* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH8* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY9* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,10* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM11* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR12* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR13* PERFORMANCE OF THIS SOFTWARE.14*/151617#include "opt_ah.h"1819#include "ah.h"20#include "ah_internal.h"2122#include "ar9300/ar9300.h"23#include "ar9300/ar9300reg.h"24#include "ar9300/ar9300phy.h"2526#if ATH_SUPPORT_MCI2728#define AH_MCI_REMOTE_RESET_INTERVAL_US 50029#define AH_MCI_DEBUG_PRINT_SCHED 03031static void ar9300_mci_print_msg(struct ath_hal *ah, HAL_BOOL send,u_int8_t hdr,32int len, u_int32_t *pl)33{34#if 035char s[128];36char *p = s;37int i;38u_int8_t *p_data = (u_int8_t *) pl;3940if (send) {41p += snprintf(s, 60,42"(MCI) >>>>> Hdr: %02X, Len: %d, Payload:", hdr, len);43}44else {45p += snprintf(s, 60,46"(MCI) <<<<< Hdr: %02X, Len: %d, Payload:", hdr, len);47}48for ( i=0; i<len; i++)49{50p += snprintf(p, 60, " %02x", *(p_data + i));51}52HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s\n", s);53/*54for ( i=0; i<(len + 3)/4; i++)55{56HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) 0x%08x\n", *(pl + i));57}58*/59#endif60}6162static63void ar9300_mci_osla_setup(struct ath_hal *ah, HAL_BOOL enable)64{65// struct ath_hal_9300 *ahp = AH9300(ah);66u_int32_t thresh;6768if (enable) {69OS_REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1);70OS_REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);7172if (!(ah->ah_config.ath_hal_mci_config &73ATH_MCI_CONFIG_DISABLE_AGGR_THRESH))74{7576if (AR_SREV_APHRODITE(ah))77OS_REG_RMW_FIELD(ah, AR_MCI_MISC, AR_MCI_MISC_HW_FIX_EN, 1);7879thresh = MS(ah->ah_config.ath_hal_mci_config,80ATH_MCI_CONFIG_AGGR_THRESH);81OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,82AR_BTCOEX_CTRL_AGGR_THRESH, thresh);83OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,84AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1);85HALDEBUG(ah, HAL_DEBUG_BT_COEX,86"(MCI) SCHED aggr thresh: on, thresh=%d (%d.%d%%)\n",87thresh, (thresh + 1)*125/10, (thresh + 1)*125%10);8889}90else {91OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,92AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0);93HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED aggr thresh: off\n");94}95OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,96AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);97HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED one step look ahead: on\n");98}99else {100OS_REG_CLR_BIT(ah, AR_BTCOEX_CTRL,101AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);102HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED one step look ahead: off\n");103}104}105106static void ar9300_mci_reset_req_wakeup(struct ath_hal *ah)107{108/* to be tested in emulation */109if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {110OS_REG_RMW_FIELD(ah, AR_MCI_COMMAND2,111AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);112OS_DELAY(1);113OS_REG_RMW_FIELD(ah, AR_MCI_COMMAND2,114AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0);115}116}117118static int32_t ar9300_mci_wait_for_interrupt(struct ath_hal *ah,119u_int32_t address,120u_int32_t bit_position,121int32_t time_out)122{123int data; //, loop;124125while (time_out) {126data = OS_REG_READ(ah, address);127128if (data & bit_position) {129OS_REG_WRITE(ah, address, bit_position);130if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) {131if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) {132ar9300_mci_reset_req_wakeup(ah);133}134if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING |135AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING))136{137OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,138AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);139}140OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG);141}142break;143}144145OS_DELAY(10);146time_out -= 10;147if (time_out < 0) {148break;149}150}151152if (time_out <= 0) {153HALDEBUG(ah, HAL_DEBUG_BT_COEX,154"(MCI) %s: Wait for Reg0x%08x = 0x%08x timeout.\n",155__func__, address, bit_position);156HALDEBUG(ah, HAL_DEBUG_BT_COEX,157"(MCI) INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",158OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW),159OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));160time_out = 0;161}162return time_out;163}164165void ar9300_mci_remote_reset(struct ath_hal *ah, HAL_BOOL wait_done)166{167u_int32_t payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};168169ar9300_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,170wait_done, AH_FALSE);171172OS_DELAY(5);173}174175void ar9300_mci_send_lna_transfer(struct ath_hal *ah, HAL_BOOL wait_done)176{177u_int32_t payload = 0x00000000;178179ar9300_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,180wait_done, AH_FALSE);181}182183static void ar9300_mci_send_req_wake(struct ath_hal *ah, HAL_BOOL wait_done)184{185ar9300_mci_send_message(ah, MCI_REQ_WAKE,186HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE);187188OS_DELAY(5);189}190191void ar9300_mci_send_sys_waking(struct ath_hal *ah, HAL_BOOL wait_done)192{193ar9300_mci_send_message(ah, MCI_SYS_WAKING,194HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE);195}196197static void ar9300_mci_send_lna_take(struct ath_hal *ah, HAL_BOOL wait_done)198{199u_int32_t payload = 0x70000000;200201/* LNA gain index is set to 7. */202ar9300_mci_send_message(ah, MCI_LNA_TAKE,203HAL_MCI_FLAG_DISABLE_TIMESTAMP, &payload, 1, wait_done, AH_FALSE);204}205206static void ar9300_mci_send_sys_sleeping(struct ath_hal *ah, HAL_BOOL wait_done)207{208ar9300_mci_send_message(ah, MCI_SYS_SLEEPING,209HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE);210}211212static void213ar9300_mci_send_coex_version_query(struct ath_hal *ah, HAL_BOOL wait_done)214{215struct ath_hal_9300 *ahp = AH9300(ah);216u_int32_t payload[4] = {0, 0, 0, 0};217218if ((ahp->ah_mci_coex_bt_version_known == AH_FALSE) &&219(ahp->ah_mci_bt_state != MCI_BT_SLEEP)) {220HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send Coex version query.\n");221MCI_GPM_SET_TYPE_OPCODE(payload,222MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY);223ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);224}225}226227static void228ar9300_mci_send_coex_version_response(struct ath_hal *ah, HAL_BOOL wait_done)229{230struct ath_hal_9300 *ahp = AH9300(ah);231u_int32_t payload[4] = {0, 0, 0, 0};232233HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send Coex version response.\n");234MCI_GPM_SET_TYPE_OPCODE(payload,235MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_RESPONSE);236*(((u_int8_t *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =237ahp->ah_mci_coex_major_version_wlan;238*(((u_int8_t *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =239ahp->ah_mci_coex_minor_version_wlan;240ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);241}242243static void244ar9300_mci_send_coex_wlan_channels(struct ath_hal *ah, HAL_BOOL wait_done)245{246struct ath_hal_9300 *ahp = AH9300(ah);247u_int32_t *payload = &ahp->ah_mci_coex_wlan_channels[0];248249if ((ahp->ah_mci_coex_wlan_channels_update == AH_TRUE) &&250(ahp->ah_mci_bt_state != MCI_BT_SLEEP))251{252MCI_GPM_SET_TYPE_OPCODE(payload,253MCI_GPM_COEX_AGENT, MCI_GPM_COEX_WLAN_CHANNELS);254ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);255MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);256}257}258259static void ar9300_mci_send_coex_bt_status_query(struct ath_hal *ah,260HAL_BOOL wait_done, u_int8_t query_type)261{262struct ath_hal_9300 *ahp = AH9300(ah);263u_int32_t pld[4] = {0, 0, 0, 0};264HAL_BOOL query_btinfo = query_type &265(MCI_GPM_COEX_QUERY_BT_ALL_INFO | MCI_GPM_COEX_QUERY_BT_TOPOLOGY);266267if (ahp->ah_mci_bt_state != MCI_BT_SLEEP) {268HALDEBUG(ah, HAL_DEBUG_BT_COEX,269"(MCI) Send Coex BT Status Query 0x%02X\n", query_type);270MCI_GPM_SET_TYPE_OPCODE(pld,271MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY);272*(((u_int8_t *)pld) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;273/*274* If bt_status_query message is thought not sent successfully,275* then ah_mci_need_flush_btinfo should be set again.276*/277if (!ar9300_mci_send_message(ah, MCI_GPM, 0, pld, 16, wait_done, AH_TRUE))278{279if (query_btinfo) {280ahp->ah_mci_need_flush_btinfo = AH_TRUE;281HALDEBUG(ah, HAL_DEBUG_BT_COEX,282"(MCI) send bt_status_query fail, set flush flag again\n");283}284}285if (query_btinfo) {286ahp->ah_mci_query_bt = AH_FALSE;287}288}289}290291void ar9300_mci_send_coex_halt_bt_gpm(struct ath_hal *ah,292HAL_BOOL halt, HAL_BOOL wait_done)293{294struct ath_hal_9300 *ahp = AH9300(ah);295u_int32_t payload[4] = {0, 0, 0, 0};296297HALDEBUG(ah, HAL_DEBUG_BT_COEX,298"(MCI) Send Coex %s BT GPM.\n", (halt == AH_TRUE)?"HALT":"UNHALT");299300MCI_GPM_SET_TYPE_OPCODE(payload,301MCI_GPM_COEX_AGENT, MCI_GPM_COEX_HALT_BT_GPM);302if (halt == AH_TRUE) {303ahp->ah_mci_query_bt = AH_TRUE;304/* Send next UNHALT no matter HALT sent or not */305ahp->ah_mci_unhalt_bt_gpm = AH_TRUE;306ahp->ah_mci_need_flush_btinfo = AH_TRUE;307*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) =308MCI_GPM_COEX_BT_GPM_HALT;309}310else {311*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) =312MCI_GPM_COEX_BT_GPM_UNHALT;313}314ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE);315}316317static HAL_BOOL ar9300_mci_send_coex_bt_flags(struct ath_hal *ah, HAL_BOOL wait_done,318u_int8_t opcode, u_int32_t bt_flags)319{320// struct ath_hal_9300 *ahp = AH9300(ah);321u_int32_t pld[4] = {0, 0, 0, 0};322323MCI_GPM_SET_TYPE_OPCODE(pld,324MCI_GPM_COEX_AGENT, MCI_GPM_COEX_BT_UPDATE_FLAGS);325326*(((u_int8_t *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP) = opcode;327*(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;328*(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) =329(bt_flags >> 8) & 0xFF;330*(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) =331(bt_flags >> 16) & 0xFF;332*(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) =333(bt_flags >> 24) & 0xFF;334335HALDEBUG(ah, HAL_DEBUG_BT_COEX,336"(MCI) BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n",337(opcode == MCI_GPM_COEX_BT_FLAGS_READ)?"READ":338((opcode == MCI_GPM_COEX_BT_FLAGS_SET)?"SET":"CLEAR"),339bt_flags);340341return ar9300_mci_send_message(ah, MCI_GPM, 0, pld, 16, wait_done, AH_TRUE);342}343344void ar9300_mci_2g5g_changed(struct ath_hal *ah, HAL_BOOL is_2g)345{346struct ath_hal_9300 *ahp = AH9300(ah);347348if (ahp->ah_mci_coex_2g5g_update == AH_FALSE) {349if (ahp->ah_mci_coex_is_2g == is_2g) {350//HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: not changed\n");351} else {352ahp->ah_mci_coex_2g5g_update = AH_TRUE;353HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: changed\n");354}355} else {356HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: force send\n");357}358ahp->ah_mci_coex_is_2g = is_2g;359}360361static void ar9300_mci_send_2g5g_status(struct ath_hal *ah, HAL_BOOL wait_done)362{363struct ath_hal_9300 *ahp = AH9300(ah);364u_int32_t new_flags, to_set, to_clear;365366if ((AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) &&367(ahp->ah_mci_coex_2g5g_update == AH_TRUE) &&368(ahp->ah_mci_bt_state != MCI_BT_SLEEP))369{370if (ahp->ah_mci_coex_is_2g) {371new_flags = HAL_MCI_2G_FLAGS;372to_clear = HAL_MCI_2G_FLAGS_CLEAR_MASK;373to_set = HAL_MCI_2G_FLAGS_SET_MASK;374} else {375new_flags = HAL_MCI_5G_FLAGS;376to_clear = HAL_MCI_5G_FLAGS_CLEAR_MASK;377to_set = HAL_MCI_5G_FLAGS_SET_MASK;378}379HALDEBUG(ah, HAL_DEBUG_BT_COEX,380"(MCI) BT_MCI_FLAGS: %s (0x%08x) clr=0x%08x, set=0x%08x\n",381ahp->ah_mci_coex_is_2g?"2G":"5G", new_flags, to_clear, to_set);382if (to_clear) {383ar9300_mci_send_coex_bt_flags(ah, wait_done,384MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear);385}386if (to_set) {387ar9300_mci_send_coex_bt_flags(ah, wait_done,388MCI_GPM_COEX_BT_FLAGS_SET, to_set);389}390}391if (AR_SREV_JUPITER_10(ah) && (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) {392ahp->ah_mci_coex_2g5g_update = AH_FALSE;393}394}395396void ar9300_mci_2g5g_switch(struct ath_hal *ah, HAL_BOOL wait_done)397{398struct ath_hal_9300 *ahp = AH9300(ah);399400if (ahp->ah_mci_coex_2g5g_update)401{402if (ahp->ah_mci_coex_is_2g) {403ar9300_mci_send_2g5g_status(ah, AH_TRUE);404405HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA trans\n");406ar9300_mci_send_lna_transfer(ah, AH_TRUE);407OS_DELAY(5);408409OS_REG_CLR_BIT(ah, AR_MCI_TX_CTRL,410AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);411if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {412OS_REG_CLR_BIT(ah, AR_GLB_CONTROL,413AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);414if (!(ah->ah_config.ath_hal_mci_config &415ATH_MCI_CONFIG_DISABLE_OSLA))416{417ar9300_mci_osla_setup(ah, AH_TRUE);418}419}420} else {421HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA take\n");422ar9300_mci_send_lna_take(ah, AH_TRUE);423OS_DELAY(5);424425OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL,426AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);427if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {428OS_REG_SET_BIT(ah, AR_GLB_CONTROL,429AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);430ar9300_mci_osla_setup(ah, AH_FALSE);431}432433ar9300_mci_send_2g5g_status(ah, AH_TRUE);434}435}436437/*438* Update self gen chain mask. Also set basic set for439* txbf.440*/441if (AR_SREV_JUPITER(ah)) {442if (ahp->ah_mci_coex_is_2g) {443ahp->ah_reduced_self_gen_mask = AH_TRUE;444OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x02);445ar9300_txbf_set_basic_set(ah);446}447else {448ahp->ah_reduced_self_gen_mask = AH_FALSE;449ar9300_txbf_set_basic_set(ah);450}451}452}453454void ar9300_mci_mute_bt(struct ath_hal *ah)455{456457HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__);458459/* disable all MCI messages */460OS_REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xFFFF0000);461OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xFFFFFFFF);462OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xFFFFFFFF);463OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xFFFFFFFF);464OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xFFFFFFFF);465OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);466/* wait pending HW messages to flush out */467OS_DELAY(10);468469/*470* Send LNA_TAKE and SYS_SLEEPING when471* 1. reset not after resuming from full sleep472* 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment473*/474if (MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config)) {475HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA take\n");476ar9300_mci_send_lna_take(ah, AH_TRUE);477OS_DELAY(5);478}479HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send sys sleeping\n");480ar9300_mci_send_sys_sleeping(ah, AH_TRUE);481}482483static void ar9300_mci_observation_set_up(struct ath_hal *ah)484{485/*486* Set up the observation bus in order to monitor MCI bus487* through GPIOs (0, 1, 2, and 3).488*/489/*490OS_REG_WRITE(ah, AR_GPIO_INTR_POL, 0x00420000);491OS_REG_WRITE(ah, AR_GPIO_OE_OUT, 0x000000ff); // 4050492OS_REG_WRITE(ah, AR_GPIO_OUTPUT_MUX1, 0x000bdab4); // 4068493OS_REG_WRITE(ah, AR_OBS, 0x0000004b); // 4088494OS_REG_WRITE(ah, AR_DIAG_SW, 0x080c0000);495OS_REG_WRITE(ah, AR_MACMISC, 0x0001a000);496OS_REG_WRITE(ah, AR_PHY_TEST, 0x00080000); // a360497OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, 0xe0000000); // a364498*/499HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called; config=0x%08x\n",500__func__, ah->ah_config.ath_hal_mci_config);501502if (ah->ah_config.ath_hal_mci_config &503ATH_MCI_CONFIG_MCI_OBS_MCI)504{505HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: CONFIG_MCI_OBS_MCI\n", __func__);506ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);507ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);508ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);509ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);510}511else if (ah->ah_config.ath_hal_mci_config &512ATH_MCI_CONFIG_MCI_OBS_TXRX)513{514HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: CONFIG_MCI_OBS_TXRX\n", __func__);515ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX);516ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX);517ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX);518ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX);519ar9300_gpio_cfg_output(ah, 5, HAL_GPIO_OUTPUT_MUX_AS_OUTPUT);520}521else if (ah->ah_config.ath_hal_mci_config &522ATH_MCI_CONFIG_MCI_OBS_BT)523{524HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: CONFIG_MCI_OBS_BT\n", __func__);525ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX);526ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX);527ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);528ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);529}530else {531return;532}533534OS_REG_SET_BIT(ah,535AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);536537if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {538OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1);539OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0);540OS_REG_WRITE(ah, AR_GLB_GPIO_CONTROL,541(OS_REG_READ(ah, AR_GLB_GPIO_CONTROL) |542ATH_MCI_CONFIG_MCI_OBS_GPIO));543}544545OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);546OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);547OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 0x4b);548OS_REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03);549OS_REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01);550OS_REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02);551OS_REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03);552//OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 0x01);553OS_REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS,554AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07);555}556557static void ar9300_mci_process_gpm_extra(struct ath_hal *ah,558u_int8_t gpm_type, u_int8_t gpm_opcode, u_int32_t *p_gpm)559{560struct ath_hal_9300 *ahp = AH9300(ah);561u_int8_t *p_data = (u_int8_t *) p_gpm;562563switch (gpm_type)564{565case MCI_GPM_COEX_AGENT:566switch (gpm_opcode)567{568case MCI_GPM_COEX_VERSION_QUERY:569HALDEBUG(ah, HAL_DEBUG_BT_COEX,570"(MCI) Recv GPM COEX Version Query.\n");571ar9300_mci_send_coex_version_response(ah, AH_TRUE);572break;573574case MCI_GPM_COEX_VERSION_RESPONSE:575HALDEBUG(ah, HAL_DEBUG_BT_COEX,576"(MCI) Recv GPM COEX Version Response.\n");577ahp->ah_mci_coex_major_version_bt =578*(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);579ahp->ah_mci_coex_minor_version_bt =580*(p_data + MCI_GPM_COEX_B_MINOR_VERSION);581ahp->ah_mci_coex_bt_version_known = AH_TRUE;582HALDEBUG(ah, HAL_DEBUG_BT_COEX,583"(MCI) BT Coex version: %d.%d\n",584ahp->ah_mci_coex_major_version_bt,585ahp->ah_mci_coex_minor_version_bt);586break;587588case MCI_GPM_COEX_STATUS_QUERY:589HALDEBUG(ah, HAL_DEBUG_BT_COEX,590"(MCI) Recv GPM COEX Status Query = 0x%02X.\n",591*(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));592//if ((*(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)) &593// MCI_GPM_COEX_QUERY_WLAN_ALL_INFO)594{595ahp->ah_mci_coex_wlan_channels_update = AH_TRUE;596ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);597}598break;599600case MCI_GPM_COEX_BT_PROFILE_INFO:601ahp->ah_mci_query_bt = AH_TRUE;602HALDEBUG(ah, HAL_DEBUG_BT_COEX,603"(MCI) Recv GPM COEX BT_Profile_Info (drop&query)\n");604break;605606case MCI_GPM_COEX_BT_STATUS_UPDATE:607ahp->ah_mci_query_bt = AH_TRUE;608HALDEBUG(ah, HAL_DEBUG_BT_COEX,609"(MCI) Recv GPM COEX BT_Status_Update "610"SEQ=%d (drop&query)\n",611*(p_gpm + 3));612break;613614default:615break;616}617default:618break;619}620}621622u_int32_t ar9300_mci_wait_for_gpm(struct ath_hal *ah, u_int8_t gpm_type,623u_int8_t gpm_opcode, int32_t time_out)624{625u_int32_t *p_gpm = NULL, mismatch = 0, more_data = HAL_MCI_GPM_NOMORE;626struct ath_hal_9300 *ahp = AH9300(ah);627HAL_BOOL b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);628u_int32_t offset;629u_int8_t recv_type = 0, recv_opcode = 0;630631if (time_out == 0) {632more_data = HAL_MCI_GPM_MORE;633}634635while (time_out > 0)636{637if (p_gpm != NULL) {638MCI_GPM_RECYCLE(p_gpm);639p_gpm = NULL;640}641642if (more_data != HAL_MCI_GPM_MORE) {643time_out = ar9300_mci_wait_for_interrupt(ah,644AR_MCI_INTERRUPT_RX_MSG_RAW,645AR_MCI_INTERRUPT_RX_MSG_GPM,646time_out);647}648649if (time_out) {650offset = ar9300_mci_state(ah,651HAL_MCI_STATE_NEXT_GPM_OFFSET, &more_data);652653if (offset == HAL_MCI_GPM_INVALID) {654continue;655}656p_gpm = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset);657ar9300_mci_print_msg(ah, AH_FALSE, MCI_GPM, 16, p_gpm);658659recv_type = MCI_GPM_TYPE(p_gpm);660recv_opcode = MCI_GPM_OPCODE(p_gpm);661662if (MCI_GPM_IS_CAL_TYPE(recv_type)) {663if (recv_type == gpm_type) {664if ((gpm_type == MCI_GPM_BT_CAL_DONE) && !b_is_bt_cal_done)665{666gpm_type = MCI_GPM_BT_CAL_GRANT;667HALDEBUG(ah, HAL_DEBUG_BT_COEX,668"(MCI) Rcv BT_CAL_DONE. Now Wait BT_CAL_GRANT\n");669continue;670}671if (gpm_type == MCI_GPM_BT_CAL_GRANT) {672HALDEBUG(ah, HAL_DEBUG_BT_COEX,673"(MCI) BT_CAL_GRANT seq=%d, req_count=%d\n",674*(p_gpm + 2), *(p_gpm + 3));675}676break;677}678}679else {680if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) {681break;682}683}684685/* not expected message */686687/*688* Check if it's cal_grant689*690* When we're waiting for cal_grant in reset routine, it's691* possible that BT sends out cal_request at the same time.692* Since BT's calibration doesn't happen that often, we'll693* let BT completes calibration then we continue to wait694* for cal_grant from BT.695* Orginal: Wait BT_CAL_GRANT.696* New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT -> wait697* BT_CAL_DONE -> Wait BT_CAL_GRANT.698*/699if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&700(recv_type == MCI_GPM_BT_CAL_REQ))701{702u_int32_t payload[4] = {0, 0, 0, 0};703704gpm_type = MCI_GPM_BT_CAL_DONE;705HALDEBUG(ah, HAL_DEBUG_BT_COEX,706"(MCI) Rcv BT_CAL_REQ. Send WLAN_CAL_GRANT.\n");707708MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);709ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16,710AH_FALSE, AH_FALSE);711712HALDEBUG(ah, HAL_DEBUG_BT_COEX,713"(MCI) Now wait for BT_CAL_DONE.\n");714continue;715}716else {717HALDEBUG(ah, HAL_DEBUG_BT_COEX,718"(MCI) GPM subtype not match 0x%x\n", *(p_gpm + 1));719mismatch++;720ar9300_mci_process_gpm_extra(ah, recv_type, recv_opcode, p_gpm);721}722}723}724if (p_gpm != NULL) {725MCI_GPM_RECYCLE(p_gpm);726p_gpm = NULL;727}728729if (time_out <= 0) {730time_out = 0;731HALDEBUG(ah, HAL_DEBUG_BT_COEX,732"(MCI) GPM receiving timeout, mismatch = %d\n", mismatch);733} else {734HALDEBUG(ah, HAL_DEBUG_BT_COEX,735"(MCI) Receive GPM type=0x%x, code=0x%x\n", gpm_type, gpm_opcode);736}737738while (more_data == HAL_MCI_GPM_MORE) {739HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) discard remaining GPM\n");740offset = ar9300_mci_state(ah,741HAL_MCI_STATE_NEXT_GPM_OFFSET, &more_data);742743if (offset == HAL_MCI_GPM_INVALID) {744break;745}746p_gpm = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset);747ar9300_mci_print_msg(ah, AH_FALSE, MCI_GPM, 16, p_gpm);748recv_type = MCI_GPM_TYPE(p_gpm);749recv_opcode = MCI_GPM_OPCODE(p_gpm);750if (!MCI_GPM_IS_CAL_TYPE(recv_type)) {751ar9300_mci_process_gpm_extra(ah, recv_type, recv_opcode, p_gpm);752}753MCI_GPM_RECYCLE(p_gpm);754}755756return time_out;757}758759static void ar9300_mci_prep_interface(struct ath_hal *ah)760{761struct ath_hal_9300 *ahp = AH9300(ah);762u_int32_t saved_mci_int_en;763u_int32_t mci_timeout = 150;764765ahp->ah_mci_bt_state = MCI_BT_SLEEP;766767saved_mci_int_en = OS_REG_READ(ah, AR_MCI_INTERRUPT_EN);768OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);769770OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,771OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));772OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,773OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW));774775/* Remote Reset */776HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Reset sequence start\n", __func__);777HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");778ar9300_mci_remote_reset(ah, AH_TRUE);779780/*781* This delay is required for the reset delay worst case value 255 in782* MCI_COMMAND2 register783*/784if (AR_SREV_JUPITER_10(ah)) {785OS_DELAY(252);786}787788/* Send REQ_WAKE to BT */789HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send REQ_WAKE to remote(BT)\n",790__func__);791792ar9300_mci_send_req_wake(ah, AH_TRUE);793794if (ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,795AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500))796{797HALDEBUG(ah, HAL_DEBUG_BT_COEX,798"(MCI) %s: Saw SYS_WAKING from remote(BT)\n", __func__);799ahp->ah_mci_bt_state = MCI_BT_AWAKE;800801if (AR_SREV_JUPITER_10(ah)) {802OS_DELAY(10);803}804/*805* We don't need to send more remote_reset at this moment.806*807* If BT receive first remote_reset, then BT HW will be cleaned up and808* will be able to receive req_wake and BT HW will respond sys_waking.809* In this case, WLAN will receive BT's HW sys_waking.810*811* Otherwise, if BT SW missed initial remote_reset, that remote_reset812* will still clean up BT MCI RX, and the req_wake will wake BT up,813* and BT SW will respond this req_wake with a remote_reset and814* sys_waking. In this case, WLAN will receive BT's SW sys_waking.815*816* In either case, BT's RX is cleaned up. So we don't need to reply817* BT's remote_reset now, if any.818*819* Similarly, if in any case, WLAN can receive BT's sys_waking, that820* means WLAN's RX is also fine.821*/822823/* Send SYS_WAKING to BT */824HALDEBUG(ah, HAL_DEBUG_BT_COEX,825"(MCI) %s: Send SW SYS_WAKING to remot(BT)\n", __func__);826ar9300_mci_send_sys_waking(ah, AH_TRUE);827828OS_DELAY(10);829830/*831* Set BT priority interrupt value to be 0xff to832* avoid having too many BT PRIORITY interrupts.833*/834835OS_REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);836OS_REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);837OS_REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);838OS_REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF);839OS_REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF);840841/*842* A contention reset will be received after send out sys_waking.843* Also BT priority interrupt bits will be set. Clear those bits844* before the next step.845*/846OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,847AR_MCI_INTERRUPT_RX_MSG_CONT_RST);848OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI);849850if (AR_SREV_JUPITER_10(ah) ||851(ahp->ah_mci_coex_is_2g &&852MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config))) {853/* Send LNA_TRANS */854HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send LNA_TRANS to BT\n",855__func__);856ar9300_mci_send_lna_transfer(ah, AH_TRUE);857858OS_DELAY(5);859}860861if (AR_SREV_JUPITER_10(ah) ||862(ahp->ah_mci_coex_is_2g && !ahp->ah_mci_coex_2g5g_update &&863MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config))) {864if (ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,865AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, mci_timeout)) {866HALDEBUG(ah, HAL_DEBUG_BT_COEX,867"(MCI) %s: WLAN has control over the LNA & BT obeys it\n",868__func__);869} else {870HALDEBUG(ah, HAL_DEBUG_BT_COEX,871"(MCI) %s: BT did not respond to LNA_TRANS!\n", __func__);872//ahp->ah_mci_bt_state = MCI_BT_SLEEP;873}874}875876if (AR_SREV_JUPITER_10(ah)) {877/* Send another remote_reset to deassert BT clk_req. */878HALDEBUG(ah, HAL_DEBUG_BT_COEX,879"(MCI) %s: Another remote_reset to deassert clk_req.\n",880__func__);881ar9300_mci_remote_reset(ah, AH_TRUE);882OS_DELAY(252);883}884}885886/* Clear the extra redundant SYS_WAKING from BT */887if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&888(OS_REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,889AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&890(OS_REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,891AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0))892{893OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,894AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);895OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,896AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);897}898899OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);900}901902void ar9300_mci_setup(struct ath_hal *ah, u_int32_t gpm_addr,903void *gpm_buf, u_int16_t len,904u_int32_t sched_addr)905{906struct ath_hal_9300 *ahp = AH9300(ah);907void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr));908909ahp->ah_mci_gpm_addr = gpm_addr;910ahp->ah_mci_gpm_buf = gpm_buf;911ahp->ah_mci_gpm_len = len;912ahp->ah_mci_sched_addr = sched_addr;913ahp->ah_mci_sched_buf = sched_buf;914915ar9300_mci_reset(ah, AH_TRUE, AH_TRUE, AH_TRUE);916}917918void ar9300_mci_disable_interrupt(struct ath_hal *ah)919{920OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);921OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);922}923924void ar9300_mci_enable_interrupt(struct ath_hal *ah)925{926OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);927OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,928AR_MCI_INTERRUPT_RX_MSG_DEFAULT);929}930931static void ar9300_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hal *ah)932{933uint32_t regval;934935HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__);936regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) |937SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |938SM(1, AR_BTCOEX_CTRL_PA_SHARED) |939SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |940SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) |941SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |942SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |943SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |944SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);945946OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,947AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1);948OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval);949}950951static void ar9300_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hal *ah)952{953uint32_t regval;954955HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__);956regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) |957SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |958SM(0, AR_BTCOEX_CTRL_PA_SHARED) |959SM(0, AR_BTCOEX_CTRL_LNA_SHARED) |960SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |961SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |962SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |963SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |964SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);965966OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,967AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x0);968OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval);969}970971static void ar9300_mci_set_btcoex_ctrl_9462(struct ath_hal *ah)972{973uint32_t regval;974975HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__);976regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) |977SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |978SM(1, AR_BTCOEX_CTRL_PA_SHARED) |979SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |980SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |981SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |982SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |983SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |984SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);985986if (AR_SREV_JUPITER_10(ah)) {987regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10);988}989990OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval);991}992993void ar9300_mci_reset(struct ath_hal *ah, HAL_BOOL en_int, HAL_BOOL is_2g,994HAL_BOOL is_full_sleep)995{996struct ath_hal_9300 *ahp = AH9300(ah);997// struct ath_hal_private *ahpriv = AH_PRIVATE(ah);998u_int32_t regval;9991000HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: full_sleep = %d, is_2g = %d\n",1001__func__, is_full_sleep, is_2g);10021003if (!ahp->ah_mci_gpm_addr && !ahp->ah_mci_sched_addr) {1004/* GPM buffer and scheduling message buffer are not allocated */1005HALDEBUG(ah, HAL_DEBUG_BT_COEX,1006"(MCI) GPM and SCHEDULE buffers not allocated\n");1007return;1008}10091010if (OS_REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {1011HALDEBUG(ah, HAL_DEBUG_BT_COEX,1012"(MCI) %s: ### It's deadbeef, quit mcireset()\n", __func__);1013return;1014}10151016/* Program MCI DMA related registers */1017OS_REG_WRITE(ah, AR_MCI_GPM_0, ahp->ah_mci_gpm_addr);1018OS_REG_WRITE(ah, AR_MCI_GPM_1, ahp->ah_mci_gpm_len);1019OS_REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, ahp->ah_mci_sched_addr);10201021/*1022* To avoid MCI state machine be affected by incoming remote MCI messages,1023* MCI mode will be enabled later, right before reset the MCI TX and RX.1024*/1025if (AR_SREV_APHRODITE(ah)) {1026uint8_t ant = MS(ah->ah_config.ath_hal_mci_config,1027ATH_MCI_CONFIG_ANT_ARCH);1028if (ant == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED)1029ar9300_mci_set_btcoex_ctrl_9565_1ANT(ah);1030else1031ar9300_mci_set_btcoex_ctrl_9565_2ANT(ah);1032} else {1033ar9300_mci_set_btcoex_ctrl_9462(ah);1034}103510361037if (is_2g && (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) &&1038!(ah->ah_config.ath_hal_mci_config &1039ATH_MCI_CONFIG_DISABLE_OSLA))1040{1041ar9300_mci_osla_setup(ah, AH_TRUE);1042}1043else {1044ar9300_mci_osla_setup(ah, AH_FALSE);1045}10461047if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {1048OS_REG_SET_BIT(ah, AR_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);10491050OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,1051AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);1052}10531054OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0);10551056OS_REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);10571058/* Set the time out to 3.125ms (5 BT slots) */1059OS_REG_RMW_FIELD(ah, AR_BTCOEX_WL_LNA, AR_BTCOEX_WL_LNA_TIMEOUT, 0x3D090);10601061if (ah->ah_config.ath_hal_mci_config & ATH_MCI_CONFIG_CONCUR_TX) {1062u_int8_t i;1063u_int32_t const *pmax_tx_pwr;10641065if ((ah->ah_config.ath_hal_mci_config &1066ATH_MCI_CONFIG_CONCUR_TX) == ATH_MCI_CONCUR_TX_SHARED_CHN)1067{1068ahp->ah_mci_concur_tx_en = (ahp->ah_bt_coex_flag &1069HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) ? AH_TRUE : AH_FALSE;10701071HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) concur_tx_en = %d\n",1072ahp->ah_mci_concur_tx_en);1073/*1074* We're not relying on HW to reduce WLAN tx power.1075* Set the max tx power table to 0x7f for all.1076*/1077#if 01078if (AH_PRIVATE(ah)->ah_curchan) {1079chan_flags = AH_PRIVATE(ah)->ah_curchan->channel_flags;1080}1081if (chan_flags == CHANNEL_G_HT20) {1082pmax_tx_pwr = &mci_concur_tx_max_pwr[2][0];1083}1084else if (chan_flags == CHANNEL_G) {1085pmax_tx_pwr = &mci_concur_tx_max_pwr[1][0];1086}1087else if ((chan_flags == CHANNEL_G_HT40PLUS) ||1088(chan_flags == CHANNEL_G_HT40MINUS))1089{1090pmax_tx_pwr = &mci_concur_tx_max_pwr[3][0];1091}1092else {1093pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];1094}10951096if (ahp->ah_mci_concur_tx_en) {1097HALDEBUG(ah, HAL_DEBUG_BT_COEX,1098"(MCI) chan flags = 0x%x, max_tx_pwr = %d dBm\n",1099chan_flags,1100(MS(pmax_tx_pwr[2],1101ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK) >> 1));1102}1103#else1104pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];1105#endif1106}1107else if ((ah->ah_config.ath_hal_mci_config &1108ATH_MCI_CONFIG_CONCUR_TX) == ATH_MCI_CONCUR_TX_UNSHARED_CHN)1109{1110pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];1111ahp->ah_mci_concur_tx_en = AH_TRUE;1112}1113else {1114pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0];1115ahp->ah_mci_concur_tx_en = AH_TRUE;1116}11171118/* Default is using rate based TPC. */1119OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,1120AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0);1121OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,1122AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f);1123OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,1124AR_BTCOEX_CTRL_REDUCE_TXPWR, 0);1125for (i = 0; i < 8; i++) {1126OS_REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), pmax_tx_pwr[i]);1127}1128}11291130regval = MS(ah->ah_config.ath_hal_mci_config,1131ATH_MCI_CONFIG_CLK_DIV);1132OS_REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval);11331134OS_REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);11351136/* Resetting the Rx and Tx paths of MCI */1137regval = OS_REG_READ(ah, AR_MCI_COMMAND2);1138regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);1139OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);1140OS_DELAY(1);1141regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);1142OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);11431144if (is_full_sleep) {1145ar9300_mci_mute_bt(ah);1146OS_DELAY(100);1147}11481149regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);1150OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);1151OS_DELAY(1);1152regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);1153OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval);11541155ar9300_mci_state(ah, HAL_MCI_STATE_INIT_GPM_OFFSET, NULL);1156OS_REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,1157(SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |1158SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));1159if (MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config)) {1160OS_REG_CLR_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);1161} else {1162OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);1163}11641165if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {1166ar9300_mci_observation_set_up(ah);1167}11681169ahp->ah_mci_ready = AH_TRUE;1170ar9300_mci_prep_interface(ah);11711172if (en_int) {1173ar9300_mci_enable_interrupt(ah);1174}11751176#if ATH_SUPPORT_AIC1177if (ahp->ah_aic_enabled) {1178ar9300_aic_start_normal(ah);1179}1180#endif1181}11821183static void ar9300_mci_queue_unsent_gpm(struct ath_hal *ah, u_int8_t header,1184u_int32_t *payload, HAL_BOOL queue)1185{1186struct ath_hal_9300 *ahp = AH9300(ah);1187u_int8_t type, opcode;11881189if (queue == AH_TRUE) {1190if (payload != NULL) {1191HALDEBUG(ah, HAL_DEBUG_BT_COEX,1192"(MCI) ERROR: Send fail: %02x: %02x %02x %02x\n",1193header,1194*(((u_int8_t *)payload) + 4),1195*(((u_int8_t *)payload) + 5),1196*(((u_int8_t *)payload) + 6));1197} else {1198HALDEBUG(ah, HAL_DEBUG_BT_COEX,1199"(MCI) ERROR: Send fail: %02x\n", header);1200}1201}1202/* check if the message is to be queued */1203if (header == MCI_GPM) {1204type = MCI_GPM_TYPE(payload);1205opcode = MCI_GPM_OPCODE(payload);12061207if (type == MCI_GPM_COEX_AGENT) {1208switch (opcode)1209{1210case MCI_GPM_COEX_BT_UPDATE_FLAGS:1211if (AR_SREV_JUPITER_10(ah)) {1212break;1213}1214if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==1215MCI_GPM_COEX_BT_FLAGS_READ)1216{1217break;1218}1219ahp->ah_mci_coex_2g5g_update = queue;1220if (queue == AH_TRUE) {1221HALDEBUG(ah, HAL_DEBUG_BT_COEX,1222"(MCI) BT_MCI_FLAGS: 2G5G status <queued> %s.\n",1223ahp->ah_mci_coex_is_2g?"2G":"5G");1224}1225else {1226HALDEBUG(ah, HAL_DEBUG_BT_COEX,1227"(MCI) BT_MCI_FLAGS: 2G5G status <sent> %s.\n",1228ahp->ah_mci_coex_is_2g?"2G":"5G");1229}1230break;12311232case MCI_GPM_COEX_WLAN_CHANNELS:1233ahp->ah_mci_coex_wlan_channels_update = queue;1234if (queue == AH_TRUE) {1235HALDEBUG(ah, HAL_DEBUG_BT_COEX,1236"(MCI) WLAN channel map <queued>.\n");1237}1238else {1239HALDEBUG(ah, HAL_DEBUG_BT_COEX,1240"(MCI) WLAN channel map <sent>.\n");1241}1242break;12431244case MCI_GPM_COEX_HALT_BT_GPM:1245if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==1246MCI_GPM_COEX_BT_GPM_UNHALT)1247{1248ahp->ah_mci_unhalt_bt_gpm = queue;1249if (queue == AH_TRUE) {1250HALDEBUG(ah, HAL_DEBUG_BT_COEX,1251"(MCI) UNHALT BT GPM <queued>.\n");1252}1253else {1254ahp->ah_mci_halted_bt_gpm = AH_FALSE;1255HALDEBUG(ah, HAL_DEBUG_BT_COEX,1256"(MCI) UNHALT BT GPM <sent>.\n");1257}1258}1259if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==1260MCI_GPM_COEX_BT_GPM_HALT)1261{1262ahp->ah_mci_halted_bt_gpm = !queue;1263if (queue == AH_TRUE) {1264HALDEBUG(ah, HAL_DEBUG_BT_COEX,1265"(MCI) HALT BT GPM <not sent>.\n");1266}1267else {1268HALDEBUG(ah, HAL_DEBUG_BT_COEX,1269"(MCI) HALT BT GPM <sent>.\n");1270}1271}1272break;12731274default:1275break;1276}1277}1278}1279}12801281HAL_BOOL ar9300_mci_send_message(struct ath_hal *ah, u_int8_t header,1282u_int32_t flag, u_int32_t *payload,1283u_int8_t len, HAL_BOOL wait_done, HAL_BOOL check_bt)1284{1285int i;1286struct ath_hal_9300 *ahp = AH9300(ah);1287HAL_BOOL msg_sent = AH_FALSE;1288u_int32_t regval;1289u_int32_t saved_mci_int_en = OS_REG_READ(ah, AR_MCI_INTERRUPT_EN);12901291regval = OS_REG_READ(ah, AR_BTCOEX_CTRL);1292if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {1293HALDEBUG(ah, HAL_DEBUG_BT_COEX,1294"(MCI) %s: Not send 0x%x. MCI is not enabled. full_sleep = %d\n",1295__func__, header, ahp->ah_chip_full_sleep);1296ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE);1297return AH_FALSE;1298}1299else if (check_bt && (ahp->ah_mci_bt_state == MCI_BT_SLEEP)) {1300HALDEBUG(ah, HAL_DEBUG_BT_COEX,1301"(MCI) %s: Don't send message(0x%x). BT is in sleep state\n",1302__func__, header);1303ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE);1304return AH_FALSE;1305}13061307if (wait_done) {1308OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);1309}13101311/* Need to clear SW_MSG_DONE raw bit before wait */1312OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,1313AR_MCI_INTERRUPT_SW_MSG_DONE | AR_MCI_INTERRUPT_MSG_FAIL_MASK);13141315if (payload != AH_NULL) {1316for (i = 0; (i*4) < len; i++) {1317OS_REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i*4), *(payload + i));1318}1319}1320ar9300_mci_print_msg(ah, AH_TRUE, header, len, payload);13211322OS_REG_WRITE(ah, AR_MCI_COMMAND0,1323(SM((flag & HAL_MCI_FLAG_DISABLE_TIMESTAMP),1324AR_MCI_COMMAND0_DISABLE_TIMESTAMP) |1325SM(len, AR_MCI_COMMAND0_LEN) |1326SM(header, AR_MCI_COMMAND0_HEADER)));13271328if (wait_done &&1329ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,1330AR_MCI_INTERRUPT_SW_MSG_DONE, 500) == 0)1331{1332ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE);1333}1334else {1335ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_FALSE);1336msg_sent = AH_TRUE;1337}13381339if (wait_done) {1340OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);1341}13421343return msg_sent;1344}13451346u_int32_t ar9300_mci_get_interrupt(struct ath_hal *ah, u_int32_t *mci_int,1347u_int32_t *mci_int_rx_msg)1348{1349struct ath_hal_9300 *ahp = AH9300(ah);13501351*mci_int = ahp->ah_mci_int_raw;1352*mci_int_rx_msg = ahp->ah_mci_int_rx_msg;13531354/* Clean int bits after the values are read. */1355ahp->ah_mci_int_raw = 0;1356ahp->ah_mci_int_rx_msg = 0;13571358return 0;1359}13601361u_int32_t ar9300_mci_check_int(struct ath_hal *ah, u_int32_t ints)1362{1363u_int32_t reg;13641365reg = OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);1366return ((reg & ints) == ints);1367}13681369void ar9300_mci_sync_bt_state(struct ath_hal *ah)1370{1371struct ath_hal_9300 *ahp = AH9300(ah);1372u_int32_t cur_bt_state;13731374cur_bt_state = ar9300_mci_state(ah, HAL_MCI_STATE_REMOTE_SLEEP, NULL);1375if (ahp->ah_mci_bt_state != cur_bt_state) {1376HALDEBUG(ah, HAL_DEBUG_BT_COEX,1377"(MCI) %s: BT state mismatches. old: %d, new: %d\n",1378__func__, ahp->ah_mci_bt_state, cur_bt_state);1379ahp->ah_mci_bt_state = cur_bt_state;1380}1381if (ahp->ah_mci_bt_state != MCI_BT_SLEEP) {1382#if MCI_QUERY_BT_VERSION_VERBOSE1383ar9300_mci_send_coex_version_query(ah, AH_TRUE);1384#endif1385ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);1386if (ahp->ah_mci_unhalt_bt_gpm == AH_TRUE) {1387HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: UNHALT BT GPM\n", __func__);1388ar9300_mci_send_coex_halt_bt_gpm(ah, AH_FALSE, AH_TRUE);1389}1390}1391}13921393static HAL_BOOL ar9300_mci_is_gpm_valid(struct ath_hal *ah, u_int32_t msg_index)1394{1395struct ath_hal_9300 *ahp = AH9300(ah);1396u_int32_t *payload;1397u_int32_t recv_type, offset = msg_index << 4;13981399if (msg_index == HAL_MCI_GPM_INVALID) {1400return AH_FALSE;1401}14021403payload = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset);1404recv_type = MCI_GPM_TYPE(payload);14051406if (recv_type == MCI_GPM_RSVD_PATTERN) {1407HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Skip RSVD GPM\n");1408return AH_FALSE;1409}14101411return AH_TRUE;1412}14131414u_int32_t1415ar9300_mci_state(struct ath_hal *ah, u_int32_t state_type, u_int32_t *p_data)1416{1417u_int32_t value = 0, more_gpm = 0, gpm_ptr;1418struct ath_hal_9300 *ahp = AH9300(ah);14191420switch (state_type) {1421case HAL_MCI_STATE_ENABLE:1422if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {1423value = OS_REG_READ(ah, AR_BTCOEX_CTRL);1424if ((value == 0xdeadbeef) || (value == 0xffffffff)) {1425HALDEBUG(ah, HAL_DEBUG_BT_COEX,1426"(MCI) BTCOEX_CTRL = 0xdeadbeef\n");1427value = 0;1428}1429}1430value &= AR_BTCOEX_CTRL_MCI_MODE_EN;1431break;14321433case HAL_MCI_STATE_INIT_GPM_OFFSET:1434value = MS(OS_REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);1435HALDEBUG(ah, HAL_DEBUG_BT_COEX,1436"(MCI) %s: GPM initial WRITE_PTR=%d.\n", __func__, value);1437ahp->ah_mci_gpm_idx = value;1438break;14391440case HAL_MCI_STATE_NEXT_GPM_OFFSET:1441case HAL_MCI_STATE_LAST_GPM_OFFSET:1442/*1443* This could be useful to avoid new GPM message interrupt which1444* may lead to spurious interrupt after power sleep, or multiple1445* entry of ath_coex_mci_intr().1446* Adding empty GPM check by returning HAL_MCI_GPM_INVALID can1447* alleviate this effect, but clearing GPM RX interrupt bit is1448* safe, because whether this is called from HAL or LMAC, there1449* must be an interrupt bit set/triggered initially.1450*/1451OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,1452AR_MCI_INTERRUPT_RX_MSG_GPM);14531454gpm_ptr = MS(OS_REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);1455value = gpm_ptr;14561457if (value == 0) {1458value = ahp->ah_mci_gpm_len - 1;1459}1460else if (value >= ahp->ah_mci_gpm_len) {1461if (value != 0xFFFF) {1462value = 0;1463HALDEBUG(ah, HAL_DEBUG_BT_COEX,1464"(MCI) %s: GPM offset out of range.\n", __func__);1465}1466}1467else {1468value--;1469}14701471if (value == 0xFFFF) {1472value = HAL_MCI_GPM_INVALID;1473more_gpm = HAL_MCI_GPM_NOMORE;1474HALDEBUG(ah, HAL_DEBUG_BT_COEX,1475"(MCI) %s: GPM ptr invalid "1476"@ptr=%d, @offset=%d, more=NOMORE.\n",1477__func__, gpm_ptr, value);1478}1479else if (state_type == HAL_MCI_STATE_NEXT_GPM_OFFSET) {1480if (gpm_ptr == ahp->ah_mci_gpm_idx) {1481value = HAL_MCI_GPM_INVALID;1482more_gpm = HAL_MCI_GPM_NOMORE;1483HALDEBUG(ah, HAL_DEBUG_BT_COEX,1484"(MCI) %s: GPM message not available "1485"@ptr=%d, @offset=%d, more=NOMORE.\n",1486__func__, gpm_ptr, value);1487}1488else {1489while (1) {1490u_int32_t temp_index;14911492/* skip reserved GPM if any */1493if (value != ahp->ah_mci_gpm_idx) {1494more_gpm = HAL_MCI_GPM_MORE;1495}1496else {1497more_gpm = HAL_MCI_GPM_NOMORE;1498}1499temp_index = ahp->ah_mci_gpm_idx;1500ahp->ah_mci_gpm_idx++;1501if (ahp->ah_mci_gpm_idx >= ahp->ah_mci_gpm_len) {1502ahp->ah_mci_gpm_idx = 0;1503}1504HALDEBUG(ah, HAL_DEBUG_BT_COEX,1505"(MCI) %s: GPM message got "1506"@ptr=%d, @offset=%d, more=%s.\n",1507__func__, gpm_ptr, temp_index,1508(more_gpm == HAL_MCI_GPM_MORE)?"MORE":"NOMORE");1509if (ar9300_mci_is_gpm_valid(ah, temp_index)) {1510value = temp_index;1511break;1512}1513if (more_gpm == HAL_MCI_GPM_NOMORE) {1514value = HAL_MCI_GPM_INVALID;1515break;1516}1517}1518}1519if (p_data != NULL) {1520*p_data = more_gpm;1521}1522}1523if (value != HAL_MCI_GPM_INVALID) {1524value <<= 4;1525}1526break;15271528case HAL_MCI_STATE_LAST_SCHD_MSG_OFFSET:1529value = MS(OS_REG_READ(ah, AR_MCI_RX_STATUS),1530AR_MCI_RX_LAST_SCHD_MSG_INDEX);15311532#if AH_MCI_DEBUG_PRINT_SCHED1533{1534u_int32_t index = value;1535u_int32_t prev_index, sched_idx;1536u_int32_t *pld;1537u_int8_t *pld8;1538u_int32_t wbtimer = OS_REG_READ(ah, AR_BTCOEX_WBTIMER);1539u_int32_t schd_ctl = OS_REG_READ(ah, AR_MCI_HW_SCHD_TBL_CTL);15401541if (index > 0) {1542prev_index = index - 1;1543} else {1544prev_index = index;1545}15461547HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED\n");1548HALDEBUG(ah, HAL_DEBUG_BT_COEX,1549"(MCI) SCHED SCHD_TBL_CTRL=0x%08x, WBTIMER=0x%08x (%d)\n",1550schd_ctl, wbtimer, wbtimer);1551for (sched_idx = prev_index; sched_idx <= index; sched_idx++) {1552pld = (u_int32_t *) (ahp->ah_mci_sched_buf + (sched_idx << 4));1553pld8 = (u_int8_t *) pld;15541555ar9300_mci_print_msg(ah, AH_FALSE, MCI_SCHD_INFO, 16, pld);1556HALDEBUG(ah, HAL_DEBUG_BT_COEX,1557"(MCI) SCHED idx=%d, T1=0x%08x (%d), T2=0x%08x (%d)\n",1558sched_idx,1559pld[0], pld[0], pld[1], pld[1]);1560HALDEBUG(ah, HAL_DEBUG_BT_COEX,1561"(MCI) SCHED addr=%d %s pwr=%d prio=%d %s link=%d\n",1562pld8[11] >> 4,1563(pld8[11] & 0x08)?"TX":"RX",1564(int8_t) (((pld8[11] & 0x07) << 5) | (pld8[10] >> 3)),1565(((pld8[10] & 0x07) << 5) | (pld8[9] >> 3)),1566(pld8[9] & 0x04)?"LE":"BR/EDR",1567(((pld8[9] & 0x03) << 2) | (pld8[8] >> 6)));1568}1569}1570#endif /* AH_MCI_DEBUG_PRINT_SCHED */15711572/* Make it in bytes */1573value <<= 4;1574break;15751576case HAL_MCI_STATE_REMOTE_SLEEP:1577value = MS(OS_REG_READ(ah, AR_MCI_RX_STATUS),1578AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE;1579break;15801581case HAL_MCI_STATE_CONT_RSSI_POWER:1582value = MS(ahp->ah_mci_cont_status,1583AR_MCI_CONT_RSSI_POWER);1584break;15851586case HAL_MCI_STATE_CONT_PRIORITY:1587value = MS(ahp->ah_mci_cont_status,1588AR_MCI_CONT_RRIORITY);1589break;15901591case HAL_MCI_STATE_CONT_TXRX:1592value = MS(ahp->ah_mci_cont_status,1593AR_MCI_CONT_TXRX);1594break;15951596case HAL_MCI_STATE_BT:1597value = ahp->ah_mci_bt_state;1598break;15991600case HAL_MCI_STATE_SET_BT_SLEEP:1601ahp->ah_mci_bt_state = MCI_BT_SLEEP;1602break;16031604case HAL_MCI_STATE_SET_BT_AWAKE:1605ahp->ah_mci_bt_state = MCI_BT_AWAKE;1606ar9300_mci_send_coex_version_query(ah, AH_TRUE);1607ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);1608if (ahp->ah_mci_unhalt_bt_gpm == AH_TRUE) {1609HALDEBUG(ah, HAL_DEBUG_BT_COEX,1610"(MCI) %s: UNHALT BT GPM\n", __func__);1611ar9300_mci_send_coex_halt_bt_gpm(ah, AH_FALSE, AH_TRUE);1612}1613ar9300_mci_2g5g_switch(ah, AH_TRUE);1614break;16151616case HAL_MCI_STATE_SET_BT_CAL_START:1617ahp->ah_mci_bt_state = MCI_BT_CAL_START;1618break;16191620case HAL_MCI_STATE_SET_BT_CAL:1621ahp->ah_mci_bt_state = MCI_BT_CAL;1622break;16231624case HAL_MCI_STATE_RESET_REQ_WAKE:1625ar9300_mci_reset_req_wakeup(ah);1626ahp->ah_mci_coex_2g5g_update = AH_TRUE;16271628if ((AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) &&1629(ah->ah_config.ath_hal_mci_config &1630ATH_MCI_CONFIG_MCI_OBS_MASK))1631{1632/* Check if we still have control of the GPIOs */1633if ((OS_REG_READ(ah, AR_GLB_GPIO_CONTROL) &1634ATH_MCI_CONFIG_MCI_OBS_GPIO) !=1635ATH_MCI_CONFIG_MCI_OBS_GPIO)1636{1637HALDEBUG(ah, HAL_DEBUG_BT_COEX,1638"(MCI) Reconfigure observation\n");1639ar9300_mci_observation_set_up(ah);1640}1641}16421643break;16441645case HAL_MCI_STATE_SEND_WLAN_COEX_VERSION:1646ar9300_mci_send_coex_version_response(ah, AH_TRUE);1647break;16481649case HAL_MCI_STATE_SET_BT_COEX_VERSION:1650if (p_data == NULL) {1651HALDEBUG(ah, HAL_DEBUG_BT_COEX,1652"(MCI) Error: Set BT Coex version with NULL data !!!\n");1653}1654else {1655ahp->ah_mci_coex_major_version_bt = (*p_data >> 8) & 0xff;1656ahp->ah_mci_coex_minor_version_bt = (*p_data) & 0xff;1657ahp->ah_mci_coex_bt_version_known = AH_TRUE;1658HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT version set: %d.%d\n",1659ahp->ah_mci_coex_major_version_bt,1660ahp->ah_mci_coex_minor_version_bt);1661}1662break;16631664case HAL_MCI_STATE_SEND_WLAN_CHANNELS:1665if (p_data != NULL)1666{1667if (((ahp->ah_mci_coex_wlan_channels[1] & 0xffff0000) ==1668(*(p_data + 1) & 0xffff0000)) &&1669(ahp->ah_mci_coex_wlan_channels[2] == *(p_data + 2)) &&1670(ahp->ah_mci_coex_wlan_channels[3] == *(p_data + 3)))1671{1672break;1673}1674ahp->ah_mci_coex_wlan_channels[0] = *p_data++;1675ahp->ah_mci_coex_wlan_channels[1] = *p_data++;1676ahp->ah_mci_coex_wlan_channels[2] = *p_data++;1677ahp->ah_mci_coex_wlan_channels[3] = *p_data++;1678}1679ahp->ah_mci_coex_wlan_channels_update = AH_TRUE;1680ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);1681break;16821683case HAL_MCI_STATE_SEND_VERSION_QUERY:1684ar9300_mci_send_coex_version_query(ah, AH_TRUE);1685break;16861687case HAL_MCI_STATE_SEND_STATUS_QUERY:1688if (AR_SREV_JUPITER_10(ah)) {1689ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE,1690MCI_GPM_COEX_QUERY_BT_ALL_INFO);1691} else {1692ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE,1693MCI_GPM_COEX_QUERY_BT_TOPOLOGY);1694}1695break;16961697case HAL_MCI_STATE_NEED_FLUSH_BT_INFO:1698/*1699* ah_mci_unhalt_bt_gpm means whether it's needed to send1700* UNHALT message. It's set whenever there's a request to send HALT1701* message. ah_mci_halted_bt_gpm means whether HALT message is sent1702* out successfully.1703*1704* Checking (ah_mci_unhalt_bt_gpm == AH_FALSE) instead of checking1705* (ahp->ah_mci_halted_bt_gpm == AH_FALSE) will make sure currently is1706* in UNHALT-ed mode and BT can respond to status query.1707*/1708if ((ahp->ah_mci_unhalt_bt_gpm == AH_FALSE) &&1709(ahp->ah_mci_need_flush_btinfo == AH_TRUE))1710{1711value = 1;1712}1713else {1714value = 0;1715}1716if (p_data != NULL) {1717ahp->ah_mci_need_flush_btinfo = (*p_data != 0)? AH_TRUE : AH_FALSE;1718}1719break;17201721case HAL_MCI_STATE_SET_CONCUR_TX_PRI:1722if (p_data) {1723ahp->ah_mci_stomp_none_tx_pri = *p_data & 0xff;1724ahp->ah_mci_stomp_low_tx_pri = (*p_data >> 8) & 0xff;1725ahp->ah_mci_stomp_all_tx_pri = (*p_data >> 16) & 0xff;1726}1727break;17281729case HAL_MCI_STATE_RECOVER_RX:1730HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) hal RECOVER_RX\n");1731ar9300_mci_prep_interface(ah);1732ahp->ah_mci_query_bt = AH_TRUE;1733ahp->ah_mci_need_flush_btinfo = AH_TRUE;1734ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE);1735ar9300_mci_2g5g_switch(ah, AH_TRUE);1736break;17371738case HAL_MCI_STATE_DEBUG:1739if (p_data != NULL) {1740if (*p_data == HAL_MCI_STATE_DEBUG_REQ_BT_DEBUG) {1741HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) QUERY_BT_DEBUG\n");1742ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE,1743MCI_GPM_COEX_QUERY_BT_DEBUG);1744OS_DELAY(10);1745if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {1746ar9300_mci_send_coex_bt_flags(ah, AH_TRUE,1747MCI_GPM_COEX_BT_FLAGS_READ, 0);1748}1749}1750}1751break;17521753case HAL_MCI_STATE_NEED_FTP_STOMP:1754value = (ah->ah_config.ath_hal_mci_config &1755ATH_MCI_CONFIG_DISABLE_FTP_STOMP) ? 0 : 1;1756break;17571758case HAL_MCI_STATE_NEED_TUNING:1759value = (ah->ah_config.ath_hal_mci_config &1760ATH_MCI_CONFIG_DISABLE_TUNING) ? 0 : 1;1761break;17621763case HAL_MCI_STATE_SHARED_CHAIN_CONCUR_TX:1764value = ((ah->ah_config.ath_hal_mci_config &1765ATH_MCI_CONFIG_CONCUR_TX) ==1766ATH_MCI_CONCUR_TX_SHARED_CHN)? 1 : 0;1767break;17681769default:1770break;1771}1772return value;1773}17741775void ar9300_mci_detach(struct ath_hal *ah)1776{1777/* Turn off MCI and Jupiter mode. */1778OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);1779HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) ar9300_mci_detach\n");1780ar9300_mci_disable_interrupt(ah);1781}17821783/*1784* Low priority BT: 0 - 59(0x3b)1785* High priority BT: 60 - 125(0x7d)1786* Critical BT: 126 - 25517871788BTCOEX_WL_WEIGHTS0_VALUE0 ; // wl_idle1789BTCOEX_WL_WEIGHTS0_VALUE1 ; // sw_ctrl[3] - all_stomp1790BTCOEX_WL_WEIGHTS0_VALUE2 ; // sw_ctrl[2] - all_not_stomp1791BTCOEX_WL_WEIGHTS0_VALUE3 ; // sw_ctrl[1] - pa_pre_distortion1792BTCOEX_WL_WEIGHTS1_VALUE0 ; // sw_ctrl[0] - general purpose1793BTCOEX_WL_WEIGHTS1_VALUE1 ; // tm_wl_wait_beacon1794BTCOEX_WL_WEIGHTS1_VALUE2 ; // ts_state_wait_ack_cts1795BTCOEX_WL_WEIGHTS1_VALUE3 ; // self_gen1796BTCOEX_WL_WEIGHTS2_VALUE0 ; // idle1797BTCOEX_WL_WEIGHTS2_VALUE1 ; // rx1798BTCOEX_WL_WEIGHTS2_VALUE2 ; // tx1799BTCOEX_WL_WEIGHTS2_VALUE3 ; // rx + tx1800BTCOEX_WL_WEIGHTS3_VALUE0 ; // tx1801BTCOEX_WL_WEIGHTS3_VALUE1 ; // rx1802BTCOEX_WL_WEIGHTS3_VALUE2 ; // tx1803BTCOEX_WL_WEIGHTS3_VALUE3 ; // rx + tx18041805Stomp all:1806ah_bt_coex_wlan_weight[0] = 0x00007d001807ah_bt_coex_wlan_weight[1] = 0x7d7d7d001808ah_bt_coex_wlan_weight[2] = 0x7d7d7d001809ah_bt_coex_wlan_weight[3] = 0x7d7d7d7d1810Stomp low:1811ah_bt_coex_wlan_weight[0] = 0x00007d001812ah_bt_coex_wlan_weight[1] = 0x7d3b3b001813ah_bt_coex_wlan_weight[2] = 0x3b3b3b001814ah_bt_coex_wlan_weight[3] = 0x3b3b3b3b1815Stomp none:1816ah_bt_coex_wlan_weight[0] = 0x00007d001817ah_bt_coex_wlan_weight[1] = 0x7d0000001818ah_bt_coex_wlan_weight[2] = 0x000000001819ah_bt_coex_wlan_weight[3] = 0x000000001820*/18211822void ar9300_mci_bt_coex_set_weights(struct ath_hal *ah, u_int32_t stomp_type)1823{1824struct ath_hal_9300 *ahp = AH9300(ah);1825// struct ath_hal_private *ahpriv = AH_PRIVATE(ah);1826u_int32_t tx_priority = 0;18271828HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: stomp_type=%d\n", __func__, stomp_type);18291830switch (stomp_type) {1831case HAL_BT_COEX_STOMP_ALL:1832ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_ALL_WLAN_WGHT0;1833ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_ALL_WLAN_WGHT1;1834ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_ALL_WLAN_WGHT2;1835ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_ALL_WLAN_WGHT3;1836if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_all_tx_pri) {1837tx_priority = ahp->ah_mci_stomp_all_tx_pri;1838}1839break;1840case HAL_BT_COEX_STOMP_LOW:1841if (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_MCI_FTP_STOMP_RX) {1842ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT0;1843ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT1;1844ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT2;1845ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT3;1846}1847else {1848ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_WLAN_WGHT0;1849ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_WLAN_WGHT1;1850ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_WLAN_WGHT2;1851ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_WLAN_WGHT3;1852}1853if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_low_tx_pri) {1854tx_priority = ahp->ah_mci_stomp_low_tx_pri;1855}1856if (ah->ah_config.ath_hal_mci_config &1857ATH_MCI_CONFIG_MCI_OBS_TXRX)1858{1859ar9300_gpio_set(ah, 5, 1);1860}1861break;1862case HAL_BT_COEX_STOMP_ALL_FORCE:1863ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT0;1864ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT1;1865ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT2;1866ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT3;1867break;1868case HAL_BT_COEX_STOMP_LOW_FORCE:1869ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT0;1870ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT1;1871ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT2;1872ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT3;1873if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_low_tx_pri) {1874tx_priority = ahp->ah_mci_stomp_low_tx_pri;1875}1876break;1877case HAL_BT_COEX_STOMP_NONE:1878case HAL_BT_COEX_NO_STOMP:1879ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_NONE_WLAN_WGHT0;1880ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_NONE_WLAN_WGHT1;1881ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_NONE_WLAN_WGHT2;1882ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_NONE_WLAN_WGHT3;1883if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_none_tx_pri) {1884tx_priority = ahp->ah_mci_stomp_none_tx_pri;1885}1886if (ah->ah_config.ath_hal_mci_config &1887ATH_MCI_CONFIG_MCI_OBS_TXRX)1888{1889ar9300_gpio_set(ah, 5, 0);1890}1891break;1892case HAL_BT_COEX_STOMP_AUDIO:1893ahp->ah_bt_coex_wlan_weight[0] = 0xffffff01;1894ahp->ah_bt_coex_wlan_weight[1] = 0xffffffff;1895ahp->ah_bt_coex_wlan_weight[2] = 0xffffff01;1896ahp->ah_bt_coex_wlan_weight[3] = 0xffffffff;1897break;1898default:1899/* There is a forceWeight from registry */1900ahp->ah_bt_coex_wlan_weight[0] = stomp_type;1901ahp->ah_bt_coex_wlan_weight[1] = stomp_type;1902break;1903}19041905if (ahp->ah_mci_concur_tx_en && tx_priority) {1906ahp->ah_bt_coex_wlan_weight[1] &= ~MCI_CONCUR_TX_WLAN_WGHT1_MASK;1907ahp->ah_bt_coex_wlan_weight[1] |=1908SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT1_MASK);1909ahp->ah_bt_coex_wlan_weight[2] &= ~MCI_CONCUR_TX_WLAN_WGHT2_MASK;1910ahp->ah_bt_coex_wlan_weight[2] |=1911SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT2_MASK);1912ahp->ah_bt_coex_wlan_weight[3] &= ~MCI_CONCUR_TX_WLAN_WGHT3_MASK;1913ahp->ah_bt_coex_wlan_weight[3] |=1914SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT3_MASK);1915ahp->ah_bt_coex_wlan_weight[3] &= ~MCI_CONCUR_TX_WLAN_WGHT3_MASK2;1916ahp->ah_bt_coex_wlan_weight[3] |=1917SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT3_MASK2);1918}1919// if (ah->ah_config.ath_hal_mci_config &1920// ATH_MCI_CONFIG_MCI_WEIGHT_DBG)1921// {1922HALDEBUG(ah, HAL_DEBUG_BT_COEX,1923"(MCI) Set weights: 0x%08x 0x%08x 0x%08x 0x%08x\n",1924ahp->ah_bt_coex_wlan_weight[0],1925ahp->ah_bt_coex_wlan_weight[1],1926ahp->ah_bt_coex_wlan_weight[2],1927ahp->ah_bt_coex_wlan_weight[3]);1928// }1929}19301931void ar9300_mci_bt_coex_disable(struct ath_hal *ah)1932{1933struct ath_hal_9300 *ahp = AH9300(ah);19341935HALDEBUG(ah, HAL_DEBUG_BT_COEX,1936"(MCI) %s: Set weight to stomp none.\n", __func__);19371938ar9300_mci_bt_coex_set_weights(ah, HAL_BT_COEX_STOMP_NONE);19391940/*1941* In Jupiter, when coex is disabled, we just set weight1942* table to be in favor of WLAN.1943*/1944OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, ahp->ah_bt_coex_wlan_weight[0]);1945OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, ahp->ah_bt_coex_wlan_weight[1]);1946OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, ahp->ah_bt_coex_wlan_weight[2]);1947OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, ahp->ah_bt_coex_wlan_weight[3]);19481949ahp->ah_bt_coex_enabled = AH_FALSE;1950}19511952int ar9300_mci_bt_coex_enable(struct ath_hal *ah)1953{1954struct ath_hal_9300 *ahp = AH9300(ah);19551956HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: called\n", __func__);19571958HALDEBUG(ah, HAL_DEBUG_BT_COEX,1959"(MCI) Write weights: 0x%08x 0x%08x 0x%08x 0x%08x\n",1960ahp->ah_bt_coex_wlan_weight[0],1961ahp->ah_bt_coex_wlan_weight[1],1962ahp->ah_bt_coex_wlan_weight[2],1963ahp->ah_bt_coex_wlan_weight[3]);196419651966/* Mainly change the WLAN weight table */1967OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, ahp->ah_bt_coex_wlan_weight[0]);1968OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, ahp->ah_bt_coex_wlan_weight[1]);1969OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, ahp->ah_bt_coex_wlan_weight[2]);1970OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, ahp->ah_bt_coex_wlan_weight[3]);19711972/* Send ACK even when BT has higher priority. */1973OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);19741975if (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOW_ACK_PWR) {1976OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_LOW_ACK_POWER);1977}1978else {1979OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_HIGH_ACK_POWER);1980}19811982ahp->ah_bt_coex_enabled = AH_TRUE;19831984return 0;1985}19861987#endif /* ATH_SUPPORT_MCI */198819891990