ar9287_reset.c revision 222310
1222301Sadrian/* 2222301Sadrian * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3222301Sadrian * Copyright (c) 2002-2008 Atheros Communications, Inc. 4222301Sadrian * 5222301Sadrian * Permission to use, copy, modify, and/or distribute this software for any 6222301Sadrian * purpose with or without fee is hereby granted, provided that the above 7222301Sadrian * copyright notice and this permission notice appear in all copies. 8222301Sadrian * 9222301Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10222301Sadrian * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11222301Sadrian * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12222301Sadrian * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13222301Sadrian * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14222301Sadrian * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15222301Sadrian * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16222301Sadrian * 17222301Sadrian * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c 222310 2011-05-26 15:01:37Z adrian $ 18222301Sadrian */ 19222301Sadrian 20222301Sadrian#include "opt_ah.h" 21222301Sadrian 22222301Sadrian#include "ah.h" 23222301Sadrian#include "ah_internal.h" 24222301Sadrian#include "ah_devid.h" 25222301Sadrian 26222301Sadrian#include "ah_eeprom_v14.h" 27222301Sadrian#include "ah_eeprom_9287.h" 28222301Sadrian 29222301Sadrian#include "ar5416/ar5416.h" 30222301Sadrian#include "ar5416/ar5416reg.h" 31222301Sadrian#include "ar5416/ar5416phy.h" 32222301Sadrian 33222301Sadrian#include "ar9002/ar9287phy.h" 34222301Sadrian#include "ar9002/ar9287an.h" 35222301Sadrian 36222308Sadrian#include "ar9002/ar9287_olc.h" 37222301Sadrian#include "ar9002/ar9287_reset.h" 38222301Sadrian 39222308Sadrian/* 40222308Sadrian * Set the TX power calibration table per-chain. 41222308Sadrian * 42222308Sadrian * This only supports open-loop TX power control for the AR9287. 43222308Sadrian */ 44222308Sadrianstatic void 45222308Sadrianar9287SetPowerCalTable(struct ath_hal *ah, 46222308Sadrian const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset) 47222308Sadrian{ 48222308Sadrian struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; 49222308Sadrian uint8_t *pCalBChans = NULL; 50222308Sadrian uint16_t pdGainOverlap_t2; 51222308Sadrian uint16_t numPiers = 0, i; 52222308Sadrian uint16_t numXpdGain, xpdMask; 53222308Sadrian uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; 54222308Sadrian uint32_t regChainOffset; 55222308Sadrian HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom; 56222308Sadrian struct ar9287_eeprom *pEepData = &ee->ee_base; 57222308Sadrian 58222308Sadrian xpdMask = pEepData->modalHeader.xpdGain; 59222308Sadrian 60222308Sadrian if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= 61222308Sadrian AR9287_EEP_MINOR_VER_2) 62222308Sadrian pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; 63222308Sadrian else 64222308Sadrian pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), 65222308Sadrian AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 66222308Sadrian 67222308Sadrian /* Note: Kiwi should only be 2ghz.. */ 68222308Sadrian if (IEEE80211_IS_CHAN_2GHZ(chan)) { 69222308Sadrian pCalBChans = pEepData->calFreqPier2G; 70222308Sadrian numPiers = AR9287_NUM_2G_CAL_PIERS; 71222308Sadrian pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0]; 72222308Sadrian AH5416(ah)->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0]; 73222308Sadrian } 74222308Sadrian numXpdGain = 0; 75222308Sadrian 76222308Sadrian /* Calculate the value of xpdgains from the xpdGain Mask */ 77222308Sadrian for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 78222308Sadrian if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 79222308Sadrian if (numXpdGain >= AR5416_NUM_PD_GAINS) 80222308Sadrian break; 81222308Sadrian xpdGainValues[numXpdGain] = 82222308Sadrian (uint16_t)(AR5416_PD_GAINS_IN_MASK-i); 83222308Sadrian numXpdGain++; 84222308Sadrian } 85222308Sadrian } 86222308Sadrian 87222308Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 88222308Sadrian (numXpdGain - 1) & 0x3); 89222308Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 90222308Sadrian xpdGainValues[0]); 91222308Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 92222308Sadrian xpdGainValues[1]); 93222308Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 94222308Sadrian xpdGainValues[2]); 95222308Sadrian 96222308Sadrian for (i = 0; i < AR9287_MAX_CHAINS; i++) { 97222308Sadrian regChainOffset = i * 0x1000; 98222308Sadrian 99222308Sadrian if (pEepData->baseEepHeader.txMask & (1 << i)) { 100222308Sadrian int8_t txPower; 101222308Sadrian pRawDatasetOpenLoop = 102222308Sadrian (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i]; 103222308Sadrian ar9287olcGetTxGainIndex(ah, chan, 104222308Sadrian pRawDatasetOpenLoop, 105222308Sadrian pCalBChans, numPiers, 106222308Sadrian &txPower); 107222308Sadrian ar9287olcSetPDADCs(ah, txPower, i); 108222308Sadrian } 109222308Sadrian } 110222308Sadrian 111222308Sadrian *pTxPowerIndexOffset = 0; 112222308Sadrian} 113222308Sadrian 114222310Sadrian/* 115222310Sadrian * Fetch the maximum TX power per rate. 116222310Sadrian * 117222310Sadrian * For now, this is hard-coded at 5dBm until this code has been ported 118222310Sadrian * from Atheros/ath9k and tested. 119222310Sadrian */ 120222310Sadrianstatic HAL_BOOL 121222310Sadrianar9285SetPowerPerRateTable(struct ath_hal *ah, 122222310Sadrian struct ar9287_eeprom *pEepData, 123222310Sadrian const struct ieee80211_channel *chan, 124222310Sadrian int16_t *ratesArray, uint16_t cfgCtl, 125222310Sadrian uint16_t AntennaReduction, 126222310Sadrian uint16_t twiceMaxRegulatoryPower, 127222310Sadrian uint16_t powerLimit) 128222310Sadrian{ 129222310Sadrian int i; 130222310Sadrian 131222310Sadrian /* For now, set all tx power rates to 5 dBm */ 132222310Sadrian for (i = 0; i < Ar5416RateSize; i++) 133222310Sadrian ratesArray[i] = 10; 134222310Sadrian 135222310Sadrian return AH_TRUE; 136222310Sadrian} 137222310Sadrian 138222310Sadrian/* 139222310Sadrian * This is based off of the AR5416/AR9285 code and likely could 140222310Sadrian * be unified in the future. 141222310Sadrian */ 142222301SadrianHAL_BOOL 143222301Sadrianar9287SetTransmitPower(struct ath_hal *ah, 144222301Sadrian const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 145222301Sadrian{ 146222310Sadrian#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 147222310Sadrian#define N(a) (sizeof (a) / sizeof (a[0])) 148222308Sadrian 149222310Sadrian const struct modal_eep_ar9287_header *pModal; 150222310Sadrian struct ath_hal_5212 *ahp = AH5212(ah); 151222310Sadrian int16_t ratesArray[Ar5416RateSize]; 152222310Sadrian int16_t txPowerIndexOffset = 0; 153222310Sadrian uint8_t ht40PowerIncForPdadc = 2; 154222310Sadrian int i; 155222308Sadrian 156222310Sadrian uint16_t cfgCtl; 157222310Sadrian uint16_t powerLimit; 158222310Sadrian uint16_t twiceAntennaReduction; 159222310Sadrian uint16_t twiceMaxRegulatoryPower; 160222310Sadrian int16_t maxPower; 161222310Sadrian HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom; 162222310Sadrian struct ar9287_eeprom *pEepData = &ee->ee_base; 163222310Sadrian 164222310Sadrian /* Setup info for the actual eeprom */ 165222310Sadrian OS_MEMZERO(ratesArray, sizeof(ratesArray)); 166222310Sadrian cfgCtl = ath_hal_getctl(ah, chan); 167222310Sadrian powerLimit = chan->ic_maxregpower * 2; 168222310Sadrian twiceAntennaReduction = chan->ic_maxantgain; 169222310Sadrian twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 170222310Sadrian pModal = &pEepData->modalHeader; 171222310Sadrian HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", 172222310Sadrian __func__,chan->ic_freq, cfgCtl ); 173222310Sadrian 174222310Sadrian /* XXX Assume Minor is v2 or later */ 175222310Sadrian ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 176222310Sadrian 177222308Sadrian /* Fetch per-rate power table for the given channel */ 178222310Sadrian if (!ar9285SetPowerPerRateTable(ah, pEepData, chan, 179222310Sadrian &ratesArray[0],cfgCtl, 180222310Sadrian twiceAntennaReduction, 181222310Sadrian twiceMaxRegulatoryPower, powerLimit)) { 182222310Sadrian HALDEBUG(ah, HAL_DEBUG_ANY, 183222310Sadrian "%s: unable to set tx power per rate table\n", __func__); 184222310Sadrian return AH_FALSE; 185222310Sadrian } 186222308Sadrian 187222310Sadrian /* Set TX power control calibration curves for each TX chain */ 188222308Sadrian ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset); 189222308Sadrian 190222310Sadrian /* Calculate maximum power level */ 191222310Sadrian maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); 192222310Sadrian maxPower = AH_MAX(maxPower, ratesArray[rate1l]); 193222308Sadrian 194222310Sadrian if (IEEE80211_IS_CHAN_HT40(chan)) 195222310Sadrian maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); 196222308Sadrian 197222310Sadrian ahp->ah_tx6PowerInHalfDbm = maxPower; 198222310Sadrian AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; 199222310Sadrian ahp->ah_txPowerIndexOffset = txPowerIndexOffset; 200222308Sadrian 201222310Sadrian /* 202222310Sadrian * txPowerIndexOffset is set by the SetPowerTable() call - 203222310Sadrian * adjust the rate table (0 offset if rates EEPROM not loaded) 204222310Sadrian */ 205222310Sadrian /* XXX what about the pwrTableOffset? */ 206222310Sadrian for (i = 0; i < N(ratesArray); i++) { 207222310Sadrian ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 208222310Sadrian /* -5 dBm offset for Merlin and later; this includes Kiwi */ 209222310Sadrian ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; 210222310Sadrian if (ratesArray[i] > AR5416_MAX_RATE_POWER) 211222310Sadrian ratesArray[i] = AR5416_MAX_RATE_POWER; 212222310Sadrian if (ratesArray[i] < 0) 213222310Sadrian ratesArray[i] = 0; 214222310Sadrian } 215222310Sadrian 216222310Sadrian#ifdef AH_EEPROM_DUMP 217222310Sadrian ar5416PrintPowerPerRate(ah, ratesArray); 218222310Sadrian#endif 219222310Sadrian 220222310Sadrian /* 221222310Sadrian * Adjust the HT40 power to meet the correct target TX power 222222310Sadrian * for 40MHz mode, based on TX power curves that are established 223222310Sadrian * for 20MHz mode. 224222310Sadrian * 225222310Sadrian * XXX handle overflow/too high power level? 226222310Sadrian */ 227222310Sadrian if (IEEE80211_IS_CHAN_HT40(chan)) { 228222310Sadrian ratesArray[rateHt40_0] += ht40PowerIncForPdadc; 229222310Sadrian ratesArray[rateHt40_1] += ht40PowerIncForPdadc; 230222310Sadrian ratesArray[rateHt40_2] += ht40PowerIncForPdadc; 231222310Sadrian ratesArray[rateHt40_3] += ht40PowerIncForPdadc; 232222310Sadrian ratesArray[rateHt40_4] += ht40PowerIncForPdadc; 233222310Sadrian ratesArray[rateHt40_5] += ht40PowerIncForPdadc; 234222310Sadrian ratesArray[rateHt40_6] += ht40PowerIncForPdadc; 235222310Sadrian ratesArray[rateHt40_7] += ht40PowerIncForPdadc; 236222310Sadrian } 237222310Sadrian 238222310Sadrian /* Write the TX power rate registers */ 239222310Sadrian ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray); 240222310Sadrian 241222301Sadrian return AH_TRUE; 242222310Sadrian#undef POW_SM 243222310Sadrian#undef N 244222301Sadrian} 245222301Sadrian 246222301Sadrian/* 247222301Sadrian * Read EEPROM header info and program the device for correct operation 248222301Sadrian * given the channel value. 249222301Sadrian */ 250222301SadrianHAL_BOOL 251222301Sadrianar9287SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) 252222301Sadrian{ 253222301Sadrian const HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom; 254222301Sadrian const struct ar9287_eeprom *eep = &ee->ee_base; 255222301Sadrian const struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 256222301Sadrian uint16_t antWrites[AR9287_ANT_16S]; 257222301Sadrian uint32_t regChainOffset, regval; 258222301Sadrian uint8_t txRxAttenLocal; 259222301Sadrian int i, j, offset_num; 260222301Sadrian 261222301Sadrian pModal = &eep->modalHeader; 262222301Sadrian 263222301Sadrian antWrites[0] = (uint16_t)((pModal->antCtrlCommon >> 28) & 0xF); 264222301Sadrian antWrites[1] = (uint16_t)((pModal->antCtrlCommon >> 24) & 0xF); 265222301Sadrian antWrites[2] = (uint16_t)((pModal->antCtrlCommon >> 20) & 0xF); 266222301Sadrian antWrites[3] = (uint16_t)((pModal->antCtrlCommon >> 16) & 0xF); 267222301Sadrian antWrites[4] = (uint16_t)((pModal->antCtrlCommon >> 12) & 0xF); 268222301Sadrian antWrites[5] = (uint16_t)((pModal->antCtrlCommon >> 8) & 0xF); 269222301Sadrian antWrites[6] = (uint16_t)((pModal->antCtrlCommon >> 4) & 0xF); 270222301Sadrian antWrites[7] = (uint16_t)(pModal->antCtrlCommon & 0xF); 271222301Sadrian 272222301Sadrian offset_num = 8; 273222301Sadrian 274222301Sadrian for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { 275222301Sadrian antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 28) & 0xf); 276222301Sadrian antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 10) & 0x3); 277222301Sadrian antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 8) & 0x3); 278222301Sadrian antWrites[j++] = 0; 279222301Sadrian antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 6) & 0x3); 280222301Sadrian antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 4) & 0x3); 281222301Sadrian antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 2) & 0x3); 282222301Sadrian antWrites[j++] = (uint16_t)(pModal->antCtrlChain[i] & 0x3); 283222301Sadrian } 284222301Sadrian 285222301Sadrian OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 286222301Sadrian 287222301Sadrian for (i = 0; i < AR9287_MAX_CHAINS; i++) { 288222301Sadrian regChainOffset = i * 0x1000; 289222301Sadrian 290222301Sadrian OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 291222301Sadrian pModal->antCtrlChain[i]); 292222301Sadrian 293222301Sadrian OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset, 294222301Sadrian (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset) 295222301Sadrian & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 296222301Sadrian AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 297222301Sadrian SM(pModal->iqCalICh[i], 298222301Sadrian AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 299222301Sadrian SM(pModal->iqCalQCh[i], 300222301Sadrian AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 301222301Sadrian 302222301Sadrian txRxAttenLocal = pModal->txRxAttenCh[i]; 303222301Sadrian 304222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 305222301Sadrian AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 306222301Sadrian pModal->bswMargin[i]); 307222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 308222301Sadrian AR_PHY_GAIN_2GHZ_XATTEN1_DB, 309222301Sadrian pModal->bswAtten[i]); 310222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 311222301Sadrian AR9280_PHY_RXGAIN_TXRX_ATTEN, 312222301Sadrian txRxAttenLocal); 313222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 314222301Sadrian AR9280_PHY_RXGAIN_TXRX_MARGIN, 315222301Sadrian pModal->rxTxMarginCh[i]); 316222301Sadrian } 317222301Sadrian 318222301Sadrian 319222301Sadrian if (IEEE80211_IS_CHAN_HT40(chan)) 320222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, 321222301Sadrian AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 322222301Sadrian else 323222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, 324222301Sadrian AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 325222301Sadrian 326222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 327222301Sadrian AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 328222301Sadrian 329222301Sadrian OS_REG_WRITE(ah, AR_PHY_RF_CTL4, 330222301Sadrian SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 331222301Sadrian | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 332222301Sadrian | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 333222301Sadrian | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 334222301Sadrian 335222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, 336222301Sadrian AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 337222301Sadrian 338222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_CCA, 339222301Sadrian AR9280_PHY_CCA_THRESH62, pModal->thresh62); 340222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, 341222301Sadrian AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); 342222301Sadrian 343222301Sadrian regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH0); 344222301Sadrian regval &= ~(AR9287_AN_RF2G3_DB1 | 345222301Sadrian AR9287_AN_RF2G3_DB2 | 346222301Sadrian AR9287_AN_RF2G3_OB_CCK | 347222301Sadrian AR9287_AN_RF2G3_OB_PSK | 348222301Sadrian AR9287_AN_RF2G3_OB_QAM | 349222301Sadrian AR9287_AN_RF2G3_OB_PAL_OFF); 350222301Sadrian regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | 351222301Sadrian SM(pModal->db2, AR9287_AN_RF2G3_DB2) | 352222301Sadrian SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | 353222301Sadrian SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | 354222301Sadrian SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | 355222301Sadrian SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); 356222301Sadrian 357222301Sadrian OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH0, regval); 358222301Sadrian OS_DELAY(100); /* analog write */ 359222301Sadrian 360222301Sadrian regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH1); 361222301Sadrian regval &= ~(AR9287_AN_RF2G3_DB1 | 362222301Sadrian AR9287_AN_RF2G3_DB2 | 363222301Sadrian AR9287_AN_RF2G3_OB_CCK | 364222301Sadrian AR9287_AN_RF2G3_OB_PSK | 365222301Sadrian AR9287_AN_RF2G3_OB_QAM | 366222301Sadrian AR9287_AN_RF2G3_OB_PAL_OFF); 367222301Sadrian regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | 368222301Sadrian SM(pModal->db2, AR9287_AN_RF2G3_DB2) | 369222301Sadrian SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | 370222301Sadrian SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | 371222301Sadrian SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | 372222301Sadrian SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); 373222301Sadrian 374222301Sadrian OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH1, regval); 375222301Sadrian OS_DELAY(100); /* analog write */ 376222301Sadrian 377222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 378222301Sadrian AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); 379222301Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 380222301Sadrian AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); 381222301Sadrian 382222301Sadrian OS_A_REG_RMW_FIELD(ah, AR9287_AN_TOP2, 383222301Sadrian AR9287_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl); 384222301Sadrian 385222301Sadrian return AH_TRUE; 386222301Sadrian} 387