ar9280_olc.c revision 221574
1219393Sadrian/* 2219393Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. 3219393Sadrian * 4219393Sadrian * Redistribution and use in source and binary forms, with or without 5219393Sadrian * modification, are permitted provided that the following conditions 6219393Sadrian * are met: 7219393Sadrian * 1. Redistributions of source code must retain the above copyright 8219393Sadrian * notice, this list of conditions and the following disclaimer. 9219393Sadrian * 2. Redistributions in binary form must reproduce the above copyright 10219393Sadrian * notice, this list of conditions and the following disclaimer in the 11219393Sadrian * documentation and/or other materials provided with the distribution. 12219393Sadrian * 13219393Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14219393Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15219393Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16219393Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17219393Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18219393Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19219393Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20219393Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21219393Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22219393Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23219393Sadrian * SUCH DAMAGE. 24219393Sadrian * 25219393Sadrian * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c 221574 2011-05-07 02:59:24Z adrian $ 26219393Sadrian */ 27219393Sadrian#include "opt_ah.h" 28219393Sadrian 29219393Sadrian#include "ah.h" 30219393Sadrian#include "ah_internal.h" 31219393Sadrian 32219393Sadrian#include "ah_eeprom_v14.h" 33219393Sadrian 34219393Sadrian#include "ar9002/ar9280.h" 35219393Sadrian#include "ar5416/ar5416reg.h" 36219393Sadrian#include "ar5416/ar5416phy.h" 37219393Sadrian#include "ar9002/ar9002phy.h" 38219393Sadrian 39219393Sadrian#include "ar9002/ar9280_olc.h" 40219393Sadrian 41219393Sadrianvoid 42219393Sadrianar9280olcInit(struct ath_hal *ah) 43219393Sadrian{ 44219393Sadrian uint32_t i; 45219393Sadrian 46219393Sadrian for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) 47219393Sadrian AH9280(ah)->originalGain[i] = MS(OS_REG_READ(ah, 48219393Sadrian AR_PHY_TX_GAIN_TBL1 + i * 4), AR_PHY_TX_GAIN); 49219393Sadrian 50219393Sadrian AH9280(ah)->PDADCdelta = 0; 51219393Sadrian} 52219393Sadrian 53219393Sadrianvoid 54219393Sadrianar9280olcGetTxGainIndex(struct ath_hal *ah, 55219393Sadrian const struct ieee80211_channel *chan, 56219393Sadrian struct calDataPerFreqOpLoop *rawDatasetOpLoop, 57219393Sadrian uint8_t *calChans, uint16_t availPiers, uint8_t *pwr, uint8_t *pcdacIdx) 58219393Sadrian{ 59219393Sadrian uint8_t pcdac, i = 0; 60219393Sadrian uint16_t idxL = 0, idxR = 0, numPiers; 61219393Sadrian HAL_BOOL match; 62219393Sadrian CHAN_CENTERS centers; 63219393Sadrian 64219393Sadrian ar5416GetChannelCenters(ah, chan, ¢ers); 65219393Sadrian 66219393Sadrian for (numPiers = 0; numPiers < availPiers; numPiers++) 67219393Sadrian if (calChans[numPiers] == AR5416_BCHAN_UNUSED) 68219393Sadrian break; 69219393Sadrian 70219586Sadrian match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, 71219393Sadrian IEEE80211_IS_CHAN_2GHZ(chan)), calChans, numPiers, 72219393Sadrian &idxL, &idxR); 73219393Sadrian if (match) { 74219393Sadrian pcdac = rawDatasetOpLoop[idxL].pcdac[0][0]; 75219393Sadrian *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0]; 76219393Sadrian } else { 77219393Sadrian pcdac = rawDatasetOpLoop[idxR].pcdac[0][0]; 78219393Sadrian *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] + 79219393Sadrian rawDatasetOpLoop[idxR].pwrPdg[0][0])/2; 80219393Sadrian } 81219393Sadrian while (pcdac > AH9280(ah)->originalGain[i] && 82219393Sadrian i < (AR9280_TX_GAIN_TABLE_SIZE - 1)) 83219393Sadrian i++; 84219393Sadrian 85219393Sadrian *pcdacIdx = i; 86219393Sadrian} 87219393Sadrian 88219393Sadrian/* 89219393Sadrian * XXX txPower here is likely not the target txPower in the traditional 90219393Sadrian * XXX sense, but is set by a call to ar9280olcGetTxGainIndex(). 91219393Sadrian * XXX Thus, be careful if you're trying to use this routine yourself. 92219393Sadrian */ 93219393Sadrianvoid 94219393Sadrianar9280olcGetPDADCs(struct ath_hal *ah, uint32_t initTxGain, int txPower, 95219393Sadrian uint8_t *pPDADCValues) 96219393Sadrian{ 97219393Sadrian uint32_t i; 98219393Sadrian uint32_t offset; 99219393Sadrian 100219393Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 101219393Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 102219393Sadrian 103219393Sadrian OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain); 104219393Sadrian 105219393Sadrian offset = txPower; 106219393Sadrian for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++) 107219393Sadrian if (i < offset) 108219393Sadrian pPDADCValues[i] = 0x0; 109219393Sadrian else 110219393Sadrian pPDADCValues[i] = 0xFF; 111219393Sadrian} 112219393Sadrian 113219393Sadrian/* 114219393Sadrian * Run temperature compensation calibration. 115219393Sadrian * 116219393Sadrian * The TX gain table is adjusted depending upon the difference 117219393Sadrian * between the initial PDADC value and the currently read 118219393Sadrian * average TX power sample value. This value is only valid if 119219393Sadrian * frames have been transmitted, so currPDADC will be 0 if 120219393Sadrian * no frames have yet been transmitted. 121219393Sadrian */ 122219393Sadrianvoid 123219393Sadrianar9280olcTemperatureCompensation(struct ath_hal *ah) 124219393Sadrian{ 125219393Sadrian uint32_t rddata, i; 126219393Sadrian int delta, currPDADC, regval; 127219393Sadrian uint8_t hpwr_5g = 0; 128219393Sadrian 129219393Sadrian rddata = OS_REG_READ(ah, AR_PHY_TX_PWRCTRL4); 130219393Sadrian currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); 131219393Sadrian 132219393Sadrian HALDEBUG(ah, HAL_DEBUG_PERCAL, 133219393Sadrian "%s: called: initPDADC=%d, currPDADC=%d\n", 134219393Sadrian __func__, AH5416(ah)->initPDADC, currPDADC); 135219393Sadrian 136219393Sadrian if (AH5416(ah)->initPDADC == 0 || currPDADC == 0) 137219393Sadrian return; 138219393Sadrian 139219393Sadrian (void) (ath_hal_eepromGet(ah, AR_EEP_DAC_HPWR_5G, &hpwr_5g)); 140219393Sadrian 141219393Sadrian if (hpwr_5g) 142219393Sadrian delta = (currPDADC - AH5416(ah)->initPDADC + 4) / 8; 143219393Sadrian else 144219393Sadrian delta = (currPDADC - AH5416(ah)->initPDADC + 5) / 10; 145219393Sadrian 146219393Sadrian HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: delta=%d, PDADCdelta=%d\n", 147219393Sadrian __func__, delta, AH9280(ah)->PDADCdelta); 148219393Sadrian 149219393Sadrian if (delta != AH9280(ah)->PDADCdelta) { 150219393Sadrian AH9280(ah)->PDADCdelta = delta; 151219393Sadrian for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { 152219393Sadrian regval = AH9280(ah)->originalGain[i] - delta; 153219393Sadrian if (regval < 0) 154219393Sadrian regval = 0; 155219393Sadrian 156219393Sadrian OS_REG_RMW_FIELD(ah, 157219393Sadrian AR_PHY_TX_GAIN_TBL1 + i * 4, 158219393Sadrian AR_PHY_TX_GAIN, regval); 159219393Sadrian } 160219393Sadrian } 161219393Sadrian} 162219393Sadrian 163219444Sadrian 164219444Sadrianstatic int16_t 165219444Sadrianar9280ChangeGainBoundarySettings(struct ath_hal *ah, uint16_t *gb, 166219444Sadrian uint16_t numXpdGain, uint16_t pdGainOverlap_t2, int8_t pwr_table_offset, 167219444Sadrian int16_t *diff) 168219444Sadrian{ 169219444Sadrian uint16_t k; 170219444Sadrian 171219444Sadrian /* Prior to writing the boundaries or the pdadc vs. power table 172219444Sadrian * into the chip registers the default starting point on the pdadc 173219444Sadrian * vs. power table needs to be checked and the curve boundaries 174219444Sadrian * adjusted accordingly 175219444Sadrian */ 176219444Sadrian if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 177219444Sadrian uint16_t gb_limit; 178219444Sadrian 179219444Sadrian if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) { 180219444Sadrian /* get the difference in dB */ 181219444Sadrian *diff = (uint16_t)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB); 182219444Sadrian /* get the number of half dB steps */ 183219444Sadrian *diff *= 2; 184219444Sadrian /* change the original gain boundary settings 185219444Sadrian * by the number of half dB steps 186219444Sadrian */ 187219444Sadrian for (k = 0; k < numXpdGain; k++) 188219444Sadrian gb[k] = (uint16_t)(gb[k] - *diff); 189219444Sadrian } 190219444Sadrian /* Because of a hardware limitation, ensure the gain boundary 191219444Sadrian * is not larger than (63 - overlap) 192219444Sadrian */ 193219444Sadrian gb_limit = (uint16_t)(AR5416_MAX_RATE_POWER - pdGainOverlap_t2); 194219444Sadrian 195219444Sadrian for (k = 0; k < numXpdGain; k++) 196219444Sadrian gb[k] = (uint16_t)min(gb_limit, gb[k]); 197219444Sadrian } 198219444Sadrian 199219444Sadrian return *diff; 200219444Sadrian} 201219444Sadrian 202219444Sadrianstatic void 203219444Sadrianar9280AdjustPDADCValues(struct ath_hal *ah, int8_t pwr_table_offset, 204219444Sadrian int16_t diff, uint8_t *pdadcValues) 205219444Sadrian{ 206219444Sadrian#define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff) 207219444Sadrian uint16_t k; 208219444Sadrian 209219444Sadrian /* If this is a board that has a pwrTableOffset that differs from 210219444Sadrian * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the 211219444Sadrian * pdadc vs pwr table needs to be adjusted prior to writing to the 212219444Sadrian * chip. 213219444Sadrian */ 214219444Sadrian if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 215219444Sadrian if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) { 216219444Sadrian /* shift the table to start at the new offset */ 217219444Sadrian for (k = 0; k < (uint16_t)NUM_PDADC(diff); k++ ) { 218219444Sadrian pdadcValues[k] = pdadcValues[k + diff]; 219219444Sadrian } 220219444Sadrian 221219444Sadrian /* fill the back of the table */ 222219444Sadrian for (k = (uint16_t)NUM_PDADC(diff); k < NUM_PDADC(0); k++) { 223219444Sadrian pdadcValues[k] = pdadcValues[NUM_PDADC(diff)]; 224219444Sadrian } 225219444Sadrian } 226219444Sadrian } 227219444Sadrian#undef NUM_PDADC 228219444Sadrian} 229219393Sadrian/* 230219393Sadrian * This effectively disables the gain boundaries leaving it 231219393Sadrian * to the open-loop TX power control. 232219393Sadrian */ 233219393Sadrianstatic void 234219585Sadrianar9280SetGainBoundariesOpenLoop(struct ath_hal *ah, int i, 235219393Sadrian uint16_t pdGainOverlap_t2, uint16_t gainBoundaries[]) 236219393Sadrian{ 237219585Sadrian int regChainOffset; 238219585Sadrian 239219585Sadrian regChainOffset = ar5416GetRegChainOffset(ah, i); 240219585Sadrian 241219393Sadrian /* These are unused for OLC */ 242219393Sadrian (void) pdGainOverlap_t2; 243219393Sadrian (void) gainBoundaries; 244219393Sadrian 245219585Sadrian HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: chain %d: writing closed loop values\n", 246219585Sadrian __func__, i); 247219585Sadrian 248219393Sadrian OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 249219393Sadrian SM(0x6, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 250219393Sadrian SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 251219393Sadrian SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 252219393Sadrian SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 253219393Sadrian SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 254219393Sadrian} 255219393Sadrian 256219393Sadrian/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 257219393Sadrian/* XXX shouldn't be here! */ 258219393Sadrian#define EEP_MINOR(_ah) \ 259219393Sadrian (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) 260219393Sadrian#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) 261219393Sadrian#define IS_EEP_MINOR_V3(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3) 262219393Sadrian 263219393Sadrian/************************************************************** 264219393Sadrian * ar9280SetPowerCalTable 265219393Sadrian * 266219393Sadrian * Pull the PDADC piers from cal data and interpolate them across the given 267219393Sadrian * points as well as from the nearest pier(s) to get a power detector 268219393Sadrian * linear voltage to power level table. 269219393Sadrian * 270219393Sadrian * Handle OLC for Merlin where required. 271219393Sadrian */ 272219393SadrianHAL_BOOL 273219393Sadrianar9280SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 274219393Sadrian const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset) 275219393Sadrian{ 276219393Sadrian CAL_DATA_PER_FREQ *pRawDataset; 277219393Sadrian uint8_t *pCalBChans = AH_NULL; 278219393Sadrian uint16_t pdGainOverlap_t2; 279219393Sadrian static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES]; 280219393Sadrian uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 281219393Sadrian uint16_t numPiers, i; 282219393Sadrian int16_t tMinCalPower; 283219393Sadrian uint16_t numXpdGain, xpdMask; 284219393Sadrian uint16_t xpdGainValues[AR5416_NUM_PD_GAINS]; 285219393Sadrian uint32_t regChainOffset; 286219444Sadrian int8_t pwr_table_offset; 287219393Sadrian 288219393Sadrian OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues)); 289219393Sadrian 290219393Sadrian xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain; 291219393Sadrian 292219444Sadrian (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset); 293219444Sadrian 294219444Sadrian 295219393Sadrian if (IS_EEP_MINOR_V2(ah)) { 296219393Sadrian pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap; 297219393Sadrian } else { 298219393Sadrian pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 299219393Sadrian } 300219393Sadrian 301219393Sadrian if (IEEE80211_IS_CHAN_2GHZ(chan)) { 302219393Sadrian pCalBChans = pEepData->calFreqPier2G; 303219393Sadrian numPiers = AR5416_NUM_2G_CAL_PIERS; 304219393Sadrian } else { 305219393Sadrian pCalBChans = pEepData->calFreqPier5G; 306219393Sadrian numPiers = AR5416_NUM_5G_CAL_PIERS; 307219393Sadrian } 308219393Sadrian 309219393Sadrian /* If OLC is being done, set the init PDADC value appropriately */ 310219393Sadrian if (IEEE80211_IS_CHAN_2GHZ(chan) && AR_SREV_MERLIN_20_OR_LATER(ah) && 311219393Sadrian ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 312219393Sadrian struct calDataPerFreq *pRawDataset = pEepData->calPierData2G[0]; 313219393Sadrian AH5416(ah)->initPDADC = ((struct calDataPerFreqOpLoop *) pRawDataset)->vpdPdg[0][0]; 314219393Sadrian } else { 315219393Sadrian /* 316219393Sadrian * XXX ath9k doesn't clear this for 5ghz mode if 317219393Sadrian * it were set in 2ghz mode before! 318219393Sadrian * The Merlin OLC temperature compensation code 319219393Sadrian * uses this to calculate the PDADC delta during 320219393Sadrian * calibration ; 0 here effectively stops the 321219393Sadrian * temperature compensation calibration from 322219393Sadrian * occuring. 323219393Sadrian */ 324219393Sadrian AH5416(ah)->initPDADC = 0; 325219393Sadrian } 326219393Sadrian 327219393Sadrian /* Calculate the value of xpdgains from the xpdGain Mask */ 328219393Sadrian numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues); 329219393Sadrian 330219393Sadrian /* Write the detector gain biases and their number */ 331219393Sadrian ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues); 332219393Sadrian 333219393Sadrian for (i = 0; i < AR5416_MAX_CHAINS; i++) { 334219393Sadrian regChainOffset = ar5416GetRegChainOffset(ah, i); 335219393Sadrian if (pEepData->baseEepHeader.txMask & (1 << i)) { 336219444Sadrian uint16_t diff; 337219444Sadrian 338219393Sadrian if (IEEE80211_IS_CHAN_2GHZ(chan)) { 339219393Sadrian pRawDataset = pEepData->calPierData2G[i]; 340219393Sadrian } else { 341219393Sadrian pRawDataset = pEepData->calPierData5G[i]; 342219393Sadrian } 343219393Sadrian 344219393Sadrian /* Fetch the gain boundaries and the PDADC values */ 345219393Sadrian if (AR_SREV_MERLIN_20_OR_LATER(ah) && 346219393Sadrian ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 347219393Sadrian uint8_t pcdacIdx; 348219393Sadrian uint8_t txPower; 349219393Sadrian 350219393Sadrian ar9280olcGetTxGainIndex(ah, chan, 351219393Sadrian (struct calDataPerFreqOpLoop *) pRawDataset, 352219393Sadrian pCalBChans, numPiers, &txPower, &pcdacIdx); 353219393Sadrian ar9280olcGetPDADCs(ah, pcdacIdx, txPower / 2, pdadcValues); 354219393Sadrian } else { 355219393Sadrian ar5416GetGainBoundariesAndPdadcs(ah, chan, 356219393Sadrian pRawDataset, pCalBChans, numPiers, 357219393Sadrian pdGainOverlap_t2, &tMinCalPower, 358219393Sadrian gainBoundaries, pdadcValues, numXpdGain); 359219393Sadrian } 360219393Sadrian 361219393Sadrian /* 362219393Sadrian * Prior to writing the boundaries or the pdadc vs. power table 363219393Sadrian * into the chip registers the default starting point on the pdadc 364219393Sadrian * vs. power table needs to be checked and the curve boundaries 365219393Sadrian * adjusted accordingly 366219393Sadrian */ 367219444Sadrian diff = ar9280ChangeGainBoundarySettings(ah, 368219444Sadrian gainBoundaries, numXpdGain, pdGainOverlap_t2, 369219444Sadrian pwr_table_offset, &diff); 370219393Sadrian 371221574Sadrian if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { 372219393Sadrian /* Set gain boundaries for either open- or closed-loop TPC */ 373219393Sadrian if (AR_SREV_MERLIN_20_OR_LATER(ah) && 374219393Sadrian ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) 375219393Sadrian ar9280SetGainBoundariesOpenLoop(ah, 376219585Sadrian i, pdGainOverlap_t2, 377219393Sadrian gainBoundaries); 378219393Sadrian else 379219393Sadrian ar5416SetGainBoundariesClosedLoop(ah, 380219585Sadrian i, pdGainOverlap_t2, 381219393Sadrian gainBoundaries); 382219393Sadrian } 383219393Sadrian 384219393Sadrian /* 385219393Sadrian * If this is a board that has a pwrTableOffset that differs from 386219393Sadrian * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the 387219393Sadrian * pdadc vs pwr table needs to be adjusted prior to writing to the 388219393Sadrian * chip. 389219393Sadrian */ 390219444Sadrian ar9280AdjustPDADCValues(ah, pwr_table_offset, diff, pdadcValues); 391219393Sadrian 392219393Sadrian /* Write the power values into the baseband power table */ 393219585Sadrian ar5416WritePdadcValues(ah, i, pdadcValues); 394219393Sadrian } 395219393Sadrian } 396219393Sadrian *pTxPowerIndexOffset = 0; 397219393Sadrian 398219393Sadrian return AH_TRUE; 399219393Sadrian} 400