Path: blob/main/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c
39566 views
/*-1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting4* Copyright (c) 2002-2005 Atheros Communications, Inc.5* Copyright (c) 2008-2010, Atheros Communications Inc.6*7* Permission to use, copy, modify, and/or distribute this software for any8* purpose with or without fee is hereby granted, provided that the above9* copyright notice and this permission notice appear in all copies.10*11* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES12* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF13* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR14* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES15* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN16* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF17* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.18*/1920#include "opt_ah.h"2122#include "ah.h"23#include "ah_internal.h"24#include "ah_devid.h"25#ifdef AH_DEBUG26#include "ah_desc.h" /* NB: for HAL_PHYERR* */27#endif2829#include "ar5416/ar5416.h"30#include "ar5416/ar5416reg.h"31#include "ar5416/ar5416phy.h"32#include "ar5416/ar5416desc.h" /* AR5416_CONTTXMODE */3334#include "ar9002/ar9285phy.h"35#include "ar9002/ar9285.h"3637/*38* This is specific to Kite.39*40* Kiwi and others don't have antenna diversity like this.41*/42void43ar9285BTCoexAntennaDiversity(struct ath_hal *ah)44{45struct ath_hal_5416 *ahp = AH5416(ah);46u_int32_t regVal;47u_int8_t ant_div_control1, ant_div_control2;4849HALDEBUG(ah, HAL_DEBUG_BT_COEX,50"%s: btCoexFlag: ALLOW=%d, ENABLE=%d\n",51__func__,52!! (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW),53!! (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE));5455if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW) ||56(AH5212(ah)->ah_diversity == AH_TRUE)) {57if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE) &&58(AH5212(ah)->ah_antControl == HAL_ANT_VARIABLE)) {59/* Enable antenna diversity */60ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_ENABLE;61ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_ENABLE;6263/* Don't disable BT ant to allow BB to control SWCOM */64ahp->ah_btCoexMode2 &= (~(AR_BT_DISABLE_BT_ANT));65OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);6667/* Program the correct SWCOM table */68OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,69HAL_BT_COEX_ANT_DIV_SWITCH_COM);70OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);71} else if (AH5212(ah)->ah_antControl == HAL_ANT_FIXED_B) {72/* Disable antenna diversity. Use antenna B(LNA2) only. */73ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_B;74ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_B;7576/* Disable BT ant to allow concurrent BT and WLAN receive */77ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;78OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);7980/*81* Program SWCOM table to make sure RF switch always parks82* at WLAN side83*/84OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,85HAL_BT_COEX_ANT_DIV_SWITCH_COM);86OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0x60000000, 0xf0000000);87} else {88/* Disable antenna diversity. Use antenna A(LNA1) only */89ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_A;90ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_A;9192/* Disable BT ant to allow concurrent BT and WLAN receive */93ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;94OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);9596/*97* Program SWCOM table to make sure RF switch always98* parks at BT side99*/100OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0);101OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);102}103104regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);105regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));106/*107* Clear ant_fast_div_bias [14:9] since for Janus the main LNA is108* always LNA1.109*/110regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));111112regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL);113regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);114regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);115regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);116regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);117OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);118119regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT);120regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);121regVal |= SM((ant_div_control1 >> 3),122AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);123OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);124}125}126127void128ar9285BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value)129{130struct ath_hal_5416 *ahp = AH5416(ah);131132switch (type) {133case HAL_BT_COEX_ANTENNA_DIVERSITY:134if (AR_SREV_KITE(ah)) {135ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_ANT_DIV_ALLOW;136if (value)137ahp->ah_btCoexFlag |=138HAL_BT_COEX_FLAG_ANT_DIV_ENABLE;139else140ahp->ah_btCoexFlag &=141~HAL_BT_COEX_FLAG_ANT_DIV_ENABLE;142ar9285BTCoexAntennaDiversity(ah);143}144break;145default:146ar5416BTCoexSetParameter(ah, type, value);147break;148}149}150151152