ar2133.c revision 187831
1185377Ssam/* 2187831Ssam * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3185377Ssam * Copyright (c) 2002-2008 Atheros Communications, Inc. 4185377Ssam * 5185377Ssam * Permission to use, copy, modify, and/or distribute this software for any 6185377Ssam * purpose with or without fee is hereby granted, provided that the above 7185377Ssam * copyright notice and this permission notice appear in all copies. 8185377Ssam * 9185377Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10185377Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11185377Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12185377Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13185377Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14185377Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15185377Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16185377Ssam * 17187831Ssam * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar2133.c 187831 2009-01-28 18:00:22Z sam $ 18185377Ssam */ 19185377Ssam#include "opt_ah.h" 20185377Ssam 21185377Ssam#include "ah.h" 22185377Ssam#include "ah_internal.h" 23185377Ssam 24185377Ssam#include "ah_eeprom_v14.h" 25185377Ssam 26185377Ssam#include "ar5416/ar5416.h" 27185377Ssam#include "ar5416/ar5416reg.h" 28185377Ssam#include "ar5416/ar5416phy.h" 29185377Ssam 30185377Ssam#define N(a) (sizeof(a)/sizeof(a[0])) 31185377Ssam 32185377Ssamstruct ar2133State { 33185377Ssam RF_HAL_FUNCS base; /* public state, must be first */ 34185377Ssam uint16_t pcdacTable[1]; 35185377Ssam 36185377Ssam uint32_t *Bank0Data; 37185377Ssam uint32_t *Bank1Data; 38185377Ssam uint32_t *Bank2Data; 39185377Ssam uint32_t *Bank3Data; 40185377Ssam uint32_t *Bank6Data; 41185377Ssam uint32_t *Bank7Data; 42185377Ssam 43185377Ssam /* NB: Bank*Data storage follows */ 44185377Ssam}; 45185377Ssam#define AR2133(ah) ((struct ar2133State *) AH5212(ah)->ah_rfHal) 46185377Ssam 47185377Ssam#define ar5416ModifyRfBuffer ar5212ModifyRfBuffer /*XXX*/ 48185377Ssam 49187831Ssamvoid ar5416ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, 50187831Ssam uint32_t numBits, uint32_t firstBit, uint32_t column); 51185377Ssam 52185377Ssamstatic void 53185377Ssamar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, 54185377Ssam int writes) 55185377Ssam{ 56185377Ssam (void) ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_bb_rfgain, 57185377Ssam freqIndex, writes); 58185377Ssam} 59185377Ssam 60185377Ssam/* 61185377Ssam * Take the MHz channel value and set the Channel value 62185377Ssam * 63185377Ssam * ASSUMES: Writes enabled to analog bus 64185377Ssam */ 65185377Ssamstatic HAL_BOOL 66187831Ssamar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan) 67185377Ssam{ 68185377Ssam uint32_t channelSel = 0; 69185377Ssam uint32_t bModeSynth = 0; 70185377Ssam uint32_t aModeRefSel = 0; 71185377Ssam uint32_t reg32 = 0; 72185377Ssam uint16_t freq; 73185377Ssam CHAN_CENTERS centers; 74185377Ssam 75187831Ssam OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq); 76185377Ssam 77187831Ssam ar5416GetChannelCenters(ah, chan, ¢ers); 78185377Ssam freq = centers.synth_center; 79185377Ssam 80185377Ssam if (freq < 4800) { 81185377Ssam uint32_t txctl; 82185377Ssam 83185377Ssam if (((freq - 2192) % 5) == 0) { 84185377Ssam channelSel = ((freq - 672) * 2 - 3040)/10; 85185377Ssam bModeSynth = 0; 86185377Ssam } else if (((freq - 2224) % 5) == 0) { 87185377Ssam channelSel = ((freq - 704) * 2 - 3040) / 10; 88185377Ssam bModeSynth = 1; 89185377Ssam } else { 90185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 91185377Ssam "%s: invalid channel %u MHz\n", __func__, freq); 92185377Ssam return AH_FALSE; 93185377Ssam } 94185377Ssam 95185377Ssam channelSel = (channelSel << 2) & 0xff; 96185377Ssam channelSel = ath_hal_reverseBits(channelSel, 8); 97185377Ssam 98185377Ssam txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL); 99185377Ssam if (freq == 2484) { 100185377Ssam /* Enable channel spreading for channel 14 */ 101185377Ssam OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 102185377Ssam txctl | AR_PHY_CCK_TX_CTRL_JAPAN); 103185377Ssam } else { 104185377Ssam OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 105185377Ssam txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN); 106185377Ssam } 107185377Ssam } else if ((freq % 20) == 0 && freq >= 5120) { 108185377Ssam channelSel = ath_hal_reverseBits(((freq - 4800) / 20 << 2), 8); 109185377Ssam if (AR_SREV_SOWL_10_OR_LATER(ah)) 110185377Ssam aModeRefSel = ath_hal_reverseBits(3, 2); 111185377Ssam else 112185377Ssam aModeRefSel = ath_hal_reverseBits(1, 2); 113185377Ssam } else if ((freq % 10) == 0) { 114185377Ssam channelSel = ath_hal_reverseBits(((freq - 4800) / 10 << 1), 8); 115185377Ssam if (AR_SREV_SOWL_10_OR_LATER(ah)) 116185377Ssam aModeRefSel = ath_hal_reverseBits(2, 2); 117185377Ssam else 118185377Ssam aModeRefSel = ath_hal_reverseBits(1, 2); 119185377Ssam } else if ((freq % 5) == 0) { 120185377Ssam channelSel = ath_hal_reverseBits((freq - 4800) / 5, 8); 121185377Ssam aModeRefSel = ath_hal_reverseBits(1, 2); 122185377Ssam } else { 123185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n", 124185377Ssam __func__, freq); 125185377Ssam return AH_FALSE; 126185377Ssam } 127185377Ssam 128185377Ssam reg32 = (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | 129185377Ssam (1 << 5) | 0x1; 130185377Ssam 131185377Ssam OS_REG_WRITE(ah, AR_PHY(0x37), reg32); 132185377Ssam 133185377Ssam AH_PRIVATE(ah)->ah_curchan = chan; 134185377Ssam return AH_TRUE; 135185377Ssam 136185377Ssam} 137185377Ssam 138185377Ssam/* 139185377Ssam * Return a reference to the requested RF Bank. 140185377Ssam */ 141185377Ssamstatic uint32_t * 142185377Ssamar2133GetRfBank(struct ath_hal *ah, int bank) 143185377Ssam{ 144185377Ssam struct ar2133State *priv = AR2133(ah); 145185377Ssam 146185377Ssam HALASSERT(priv != AH_NULL); 147185377Ssam switch (bank) { 148185377Ssam case 1: return priv->Bank1Data; 149185377Ssam case 2: return priv->Bank2Data; 150185377Ssam case 3: return priv->Bank3Data; 151185377Ssam case 6: return priv->Bank6Data; 152185377Ssam case 7: return priv->Bank7Data; 153185377Ssam } 154185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n", 155185377Ssam __func__, bank); 156185377Ssam return AH_NULL; 157185377Ssam} 158185377Ssam 159185377Ssam/* 160185377Ssam * Reads EEPROM header info from device structure and programs 161185377Ssam * all rf registers 162185377Ssam * 163185377Ssam * REQUIRES: Access to the analog rf device 164185377Ssam */ 165185377Ssamstatic HAL_BOOL 166187831Ssamar2133SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan, 167185377Ssam uint16_t modesIndex, uint16_t *rfXpdGain) 168185377Ssam{ 169185377Ssam struct ar2133State *priv = AR2133(ah); 170185377Ssam int writes; 171185377Ssam 172185377Ssam HALASSERT(priv); 173185377Ssam 174185377Ssam /* Setup Bank 0 Write */ 175185377Ssam ath_hal_ini_bank_setup(priv->Bank0Data, &AH5416(ah)->ah_ini_bank0, 1); 176185377Ssam 177185377Ssam /* Setup Bank 1 Write */ 178185377Ssam ath_hal_ini_bank_setup(priv->Bank1Data, &AH5416(ah)->ah_ini_bank1, 1); 179185377Ssam 180185377Ssam /* Setup Bank 2 Write */ 181185377Ssam ath_hal_ini_bank_setup(priv->Bank2Data, &AH5416(ah)->ah_ini_bank2, 1); 182185377Ssam 183185377Ssam /* Setup Bank 3 Write */ 184185377Ssam ath_hal_ini_bank_setup(priv->Bank3Data, &AH5416(ah)->ah_ini_bank3, modesIndex); 185185377Ssam 186185377Ssam /* Setup Bank 6 Write */ 187185377Ssam ath_hal_ini_bank_setup(priv->Bank6Data, &AH5416(ah)->ah_ini_bank6, modesIndex); 188185377Ssam 189185377Ssam /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ 190187831Ssam if (IEEE80211_IS_CHAN_2GHZ(chan)) { 191185377Ssam ar5416ModifyRfBuffer(priv->Bank6Data, 192185377Ssam ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 3, 197, 0); 193185377Ssam ar5416ModifyRfBuffer(priv->Bank6Data, 194185377Ssam ath_hal_eepromGet(ah, AR_EEP_DB_2, AH_NULL), 3, 194, 0); 195185377Ssam } else { 196185377Ssam ar5416ModifyRfBuffer(priv->Bank6Data, 197185377Ssam ath_hal_eepromGet(ah, AR_EEP_OB_5, AH_NULL), 3, 203, 0); 198185377Ssam ar5416ModifyRfBuffer(priv->Bank6Data, 199185377Ssam ath_hal_eepromGet(ah, AR_EEP_DB_5, AH_NULL), 3, 200, 0); 200185377Ssam } 201185377Ssam /* Setup Bank 7 Setup */ 202185377Ssam ath_hal_ini_bank_setup(priv->Bank7Data, &AH5416(ah)->ah_ini_bank7, 1); 203185377Ssam 204185377Ssam /* Write Analog registers */ 205185377Ssam writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank0, 206185377Ssam priv->Bank0Data, 0); 207185377Ssam writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank1, 208185377Ssam priv->Bank1Data, writes); 209185377Ssam writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank2, 210185377Ssam priv->Bank2Data, writes); 211185377Ssam writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank3, 212185377Ssam priv->Bank3Data, writes); 213185377Ssam writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank6, 214185377Ssam priv->Bank6Data, writes); 215185377Ssam (void) ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank7, 216185377Ssam priv->Bank7Data, writes); 217185377Ssam 218185377Ssam return AH_TRUE; 219185377Ssam#undef RF_BANK_SETUP 220185377Ssam} 221185377Ssam 222185377Ssam/* 223185377Ssam * Read the transmit power levels from the structures taken from EEPROM 224185377Ssam * Interpolate read transmit power values for this channel 225185377Ssam * Organize the transmit power values into a table for writing into the hardware 226185377Ssam */ 227185377Ssam 228185377Ssamstatic HAL_BOOL 229185377Ssamar2133SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax, 230187831Ssam const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 231185377Ssam{ 232185377Ssam return AH_TRUE; 233185377Ssam} 234185377Ssam 235185377Ssam#if 0 236185377Ssamstatic int16_t 237185377Ssamar2133GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data) 238185377Ssam{ 239185377Ssam int i, minIndex; 240185377Ssam int16_t minGain,minPwr,minPcdac,retVal; 241185377Ssam 242185377Ssam /* Assume NUM_POINTS_XPD0 > 0 */ 243185377Ssam minGain = data->pDataPerXPD[0].xpd_gain; 244185377Ssam for (minIndex=0,i=1; i<NUM_XPD_PER_CHANNEL; i++) { 245185377Ssam if (data->pDataPerXPD[i].xpd_gain < minGain) { 246185377Ssam minIndex = i; 247185377Ssam minGain = data->pDataPerXPD[i].xpd_gain; 248185377Ssam } 249185377Ssam } 250185377Ssam minPwr = data->pDataPerXPD[minIndex].pwr_t4[0]; 251185377Ssam minPcdac = data->pDataPerXPD[minIndex].pcdac[0]; 252185377Ssam for (i=1; i<NUM_POINTS_XPD0; i++) { 253185377Ssam if (data->pDataPerXPD[minIndex].pwr_t4[i] < minPwr) { 254185377Ssam minPwr = data->pDataPerXPD[minIndex].pwr_t4[i]; 255185377Ssam minPcdac = data->pDataPerXPD[minIndex].pcdac[i]; 256185377Ssam } 257185377Ssam } 258185377Ssam retVal = minPwr - (minPcdac*2); 259185377Ssam return(retVal); 260185377Ssam} 261185377Ssam#endif 262185377Ssam 263185377Ssamstatic HAL_BOOL 264187831Ssamar2133GetChannelMaxMinPower(struct ath_hal *ah, 265187831Ssam const struct ieee80211_channel *chan, 266187831Ssam int16_t *maxPow, int16_t *minPow) 267185377Ssam{ 268185377Ssam#if 0 269185377Ssam struct ath_hal_5212 *ahp = AH5212(ah); 270185377Ssam int numChannels=0,i,last; 271185377Ssam int totalD, totalF,totalMin; 272185377Ssam EXPN_DATA_PER_CHANNEL_5112 *data=AH_NULL; 273185377Ssam EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL; 274185377Ssam 275185377Ssam *maxPow = 0; 276185377Ssam if (IS_CHAN_A(chan)) { 277185377Ssam powerArray = ahp->ah_modePowerArray5112; 278185377Ssam data = powerArray[headerInfo11A].pDataPerChannel; 279185377Ssam numChannels = powerArray[headerInfo11A].numChannels; 280185377Ssam } else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) { 281185377Ssam /* XXX - is this correct? Should we also use the same power for turbo G? */ 282185377Ssam powerArray = ahp->ah_modePowerArray5112; 283185377Ssam data = powerArray[headerInfo11G].pDataPerChannel; 284185377Ssam numChannels = powerArray[headerInfo11G].numChannels; 285185377Ssam } else if (IS_CHAN_B(chan)) { 286185377Ssam powerArray = ahp->ah_modePowerArray5112; 287185377Ssam data = powerArray[headerInfo11B].pDataPerChannel; 288185377Ssam numChannels = powerArray[headerInfo11B].numChannels; 289185377Ssam } else { 290185377Ssam return (AH_TRUE); 291185377Ssam } 292185377Ssam /* Make sure the channel is in the range of the TP values 293185377Ssam * (freq piers) 294185377Ssam */ 295185377Ssam if ((numChannels < 1) || 296185377Ssam (chan->channel < data[0].channelValue) || 297185377Ssam (chan->channel > data[numChannels-1].channelValue)) 298185377Ssam return(AH_FALSE); 299185377Ssam 300185377Ssam /* Linearly interpolate the power value now */ 301185377Ssam for (last=0,i=0; 302185377Ssam (i<numChannels) && (chan->channel > data[i].channelValue); 303185377Ssam last=i++); 304185377Ssam totalD = data[i].channelValue - data[last].channelValue; 305185377Ssam if (totalD > 0) { 306185377Ssam totalF = data[i].maxPower_t4 - data[last].maxPower_t4; 307185377Ssam *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD); 308185377Ssam 309185377Ssam totalMin = ar2133GetMinPower(ah,&data[i]) - ar2133GetMinPower(ah, &data[last]); 310185377Ssam *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar2133GetMinPower(ah, &data[last])*totalD)/totalD); 311185377Ssam return (AH_TRUE); 312185377Ssam } else { 313185377Ssam if (chan->channel == data[i].channelValue) { 314185377Ssam *maxPow = data[i].maxPower_t4; 315185377Ssam *minPow = ar2133GetMinPower(ah, &data[i]); 316185377Ssam return(AH_TRUE); 317185377Ssam } else 318185377Ssam return(AH_FALSE); 319185377Ssam } 320185377Ssam#else 321185377Ssam *maxPow = *minPow = 0; 322185377Ssam return AH_FALSE; 323185377Ssam#endif 324185377Ssam} 325185377Ssam 326185380Ssamstatic void 327185380Ssamar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) 328185380Ssam{ 329185380Ssam struct ath_hal_5416 *ahp = AH5416(ah); 330185380Ssam int16_t nf; 331185380Ssam 332185380Ssam switch (ahp->ah_rx_chainmask) { 333185380Ssam case 0x7: 334185380Ssam nf = MS(OS_REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); 335185380Ssam if (nf & 0x100) 336185380Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 337185380Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 338185380Ssam "NF calibrated [ctl] [chain 2] is %d\n", nf); 339185380Ssam nfarray[4] = nf; 340185380Ssam 341185380Ssam nf = MS(OS_REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); 342185380Ssam if (nf & 0x100) 343185380Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 344185380Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 345185380Ssam "NF calibrated [ext] [chain 2] is %d\n", nf); 346185380Ssam nfarray[5] = nf; 347185380Ssam /* fall thru... */ 348185380Ssam case 0x3: 349185380Ssam case 0x5: 350185380Ssam nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); 351185380Ssam if (nf & 0x100) 352185380Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 353185380Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 354185380Ssam "NF calibrated [ctl] [chain 1] is %d\n", nf); 355185380Ssam nfarray[2] = nf; 356185380Ssam 357185380Ssam 358185380Ssam nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); 359185380Ssam if (nf & 0x100) 360185380Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 361185380Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 362185380Ssam "NF calibrated [ext] [chain 1] is %d\n", nf); 363185380Ssam nfarray[3] = nf; 364185380Ssam /* fall thru... */ 365185380Ssam case 0x1: 366185380Ssam nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); 367185380Ssam if (nf & 0x100) 368185380Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 369185380Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 370185380Ssam "NF calibrated [ctl] [chain 0] is %d\n", nf); 371185380Ssam nfarray[0] = nf; 372185380Ssam 373185380Ssam nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 374185380Ssam if (nf & 0x100) 375185380Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 376185380Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 377185380Ssam "NF calibrated [ext] [chain 0] is %d\n", nf); 378185380Ssam nfarray[1] = nf; 379185380Ssam 380185380Ssam break; 381185380Ssam } 382185380Ssam} 383185380Ssam 384185377Ssam/* 385185377Ssam * Adjust NF based on statistical values for 5GHz frequencies. 386185377Ssam * Stubbed:Not used by Fowl 387185377Ssam */ 388187831Ssamstatic int16_t 389185377Ssamar2133GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c) 390185377Ssam{ 391185377Ssam return 0; 392185377Ssam} 393185377Ssam 394185377Ssam/* 395185377Ssam * Free memory for analog bank scratch buffers 396185377Ssam */ 397185377Ssamstatic void 398185377Ssamar2133RfDetach(struct ath_hal *ah) 399185377Ssam{ 400185377Ssam struct ath_hal_5212 *ahp = AH5212(ah); 401185377Ssam 402185377Ssam HALASSERT(ahp->ah_rfHal != AH_NULL); 403185377Ssam ath_hal_free(ahp->ah_rfHal); 404185377Ssam ahp->ah_rfHal = AH_NULL; 405185377Ssam} 406185377Ssam 407185377Ssam/* 408185377Ssam * Allocate memory for analog bank scratch buffers 409185377Ssam * Scratch Buffer will be reinitialized every reset so no need to zero now 410185377Ssam */ 411185377SsamHAL_BOOL 412185377Ssamar2133RfAttach(struct ath_hal *ah, HAL_STATUS *status) 413185377Ssam{ 414185377Ssam struct ath_hal_5212 *ahp = AH5212(ah); 415185377Ssam struct ar2133State *priv; 416185377Ssam uint32_t *bankData; 417185377Ssam 418185377Ssam HALASSERT(ahp->ah_rfHal == AH_NULL); 419185377Ssam priv = ath_hal_malloc(sizeof(struct ar2133State) 420185377Ssam + AH5416(ah)->ah_ini_bank0.rows * sizeof(uint32_t) 421185377Ssam + AH5416(ah)->ah_ini_bank1.rows * sizeof(uint32_t) 422185377Ssam + AH5416(ah)->ah_ini_bank2.rows * sizeof(uint32_t) 423185377Ssam + AH5416(ah)->ah_ini_bank3.rows * sizeof(uint32_t) 424185377Ssam + AH5416(ah)->ah_ini_bank6.rows * sizeof(uint32_t) 425185377Ssam + AH5416(ah)->ah_ini_bank7.rows * sizeof(uint32_t) 426185377Ssam ); 427185377Ssam if (priv == AH_NULL) { 428185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 429185377Ssam "%s: cannot allocate private state\n", __func__); 430185377Ssam *status = HAL_ENOMEM; /* XXX */ 431185377Ssam return AH_FALSE; 432185377Ssam } 433185377Ssam priv->base.rfDetach = ar2133RfDetach; 434185377Ssam priv->base.writeRegs = ar2133WriteRegs; 435185377Ssam priv->base.getRfBank = ar2133GetRfBank; 436185377Ssam priv->base.setChannel = ar2133SetChannel; 437185377Ssam priv->base.setRfRegs = ar2133SetRfRegs; 438185377Ssam priv->base.setPowerTable = ar2133SetPowerTable; 439185377Ssam priv->base.getChannelMaxMinPower = ar2133GetChannelMaxMinPower; 440185377Ssam priv->base.getNfAdjust = ar2133GetNfAdjust; 441185377Ssam 442185377Ssam bankData = (uint32_t *) &priv[1]; 443185377Ssam priv->Bank0Data = bankData, bankData += AH5416(ah)->ah_ini_bank0.rows; 444185377Ssam priv->Bank1Data = bankData, bankData += AH5416(ah)->ah_ini_bank1.rows; 445185377Ssam priv->Bank2Data = bankData, bankData += AH5416(ah)->ah_ini_bank2.rows; 446185377Ssam priv->Bank3Data = bankData, bankData += AH5416(ah)->ah_ini_bank3.rows; 447185377Ssam priv->Bank6Data = bankData, bankData += AH5416(ah)->ah_ini_bank6.rows; 448185377Ssam priv->Bank7Data = bankData, bankData += AH5416(ah)->ah_ini_bank7.rows; 449185377Ssam 450185377Ssam ahp->ah_pcdacTable = priv->pcdacTable; 451185377Ssam ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable); 452185377Ssam ahp->ah_rfHal = &priv->base; 453185377Ssam /* 454185377Ssam * Set noise floor adjust method; we arrange a 455185377Ssam * direct call instead of thunking. 456185377Ssam */ 457185377Ssam AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust; 458185380Ssam AH_PRIVATE(ah)->ah_getNoiseFloor = ar2133GetNoiseFloor; 459185377Ssam 460185377Ssam return AH_TRUE; 461185377Ssam} 462