1 /*- 2 * SPDX-License-Identifier: ISC 3 * 4 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 5 * Copyright (c) 2002-2008 Atheros Communications, Inc. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * 19 * $FreeBSD$ 20 */ 21 #include "opt_ah.h" 22 23 #include "ah.h" 24 #include "ah_internal.h" 25 26 #include "ah_eeprom_v14.h" 27 28 #include "ar5416/ar5416.h" 29 #include "ar5416/ar5416reg.h" 30 #include "ar5416/ar5416phy.h" 31 32 #define N(a) (sizeof(a)/sizeof(a[0])) 33 34 struct ar2133State { 35 RF_HAL_FUNCS base; /* public state, must be first */ 36 uint16_t pcdacTable[1]; 37 38 uint32_t *Bank0Data; 39 uint32_t *Bank1Data; 40 uint32_t *Bank2Data; 41 uint32_t *Bank3Data; 42 uint32_t *Bank6Data; 43 uint32_t *Bank7Data; 44 45 /* NB: Bank*Data storage follows */ 46 }; 47 #define AR2133(ah) ((struct ar2133State *) AH5212(ah)->ah_rfHal) 48 49 #define ar5416ModifyRfBuffer ar5212ModifyRfBuffer /*XXX*/ 50 51 void ar5416ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, 52 uint32_t numBits, uint32_t firstBit, uint32_t column); 53 54 static void 55 ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, 56 int writes) 57 { 58 (void) ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_bb_rfgain, 59 freqIndex, writes); 60 } 61 62 /* 63 * Fix on 2.4 GHz band for orientation sensitivity issue by increasing 64 * rf_pwd_icsyndiv. 65 * 66 * Theoretical Rules: 67 * if 2 GHz band 68 * if forceBiasAuto 69 * if synth_freq < 2412 70 * bias = 0 71 * else if 2412 <= synth_freq <= 2422 72 * bias = 1 73 * else // synth_freq > 2422 74 * bias = 2 75 * else if forceBias > 0 76 * bias = forceBias & 7 77 * else 78 * no change, use value from ini file 79 * else 80 * no change, invalid band 81 * 82 * 1st Mod: 83 * 2422 also uses value of 2 84 * <approved> 85 * 86 * 2nd Mod: 87 * Less than 2412 uses value of 0, 2412 and above uses value of 2 88 */ 89 static void 90 ar2133ForceBias(struct ath_hal *ah, uint16_t synth_freq) 91 { 92 uint32_t tmp_reg; 93 int reg_writes = 0; 94 uint32_t new_bias = 0; 95 struct ar2133State *priv = AR2133(ah); 96 97 /* XXX this is a bit of a silly check for 2.4ghz channels -adrian */ 98 if (synth_freq >= 3000) 99 return; 100 101 if (synth_freq < 2412) 102 new_bias = 0; 103 else if (synth_freq < 2422) 104 new_bias = 1; 105 else 106 new_bias = 2; 107 108 /* pre-reverse this field */ 109 tmp_reg = ath_hal_reverseBits(new_bias, 3); 110 111 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Force rf_pwd_icsyndiv to %1d on %4d\n", 112 __func__, new_bias, synth_freq); 113 114 /* swizzle rf_pwd_icsyndiv */ 115 ar5416ModifyRfBuffer(priv->Bank6Data, tmp_reg, 3, 181, 3); 116 117 /* write Bank 6 with new params */ 118 ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank6, priv->Bank6Data, reg_writes); 119 } 120 121 /* 122 * Take the MHz channel value and set the Channel value 123 * 124 * ASSUMES: Writes enabled to analog bus 125 */ 126 static HAL_BOOL 127 ar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan) 128 { 129 uint32_t channelSel = 0; 130 uint32_t bModeSynth = 0; 131 uint32_t aModeRefSel = 0; 132 uint32_t reg32 = 0; 133 uint16_t freq; 134 CHAN_CENTERS centers; 135 136 OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq); 137 138 ar5416GetChannelCenters(ah, chan, ¢ers); 139 freq = centers.synth_center; 140 141 if (freq < 4800) { 142 uint32_t txctl; 143 144 if (((freq - 2192) % 5) == 0) { 145 channelSel = ((freq - 672) * 2 - 3040)/10; 146 bModeSynth = 0; 147 } else if (((freq - 2224) % 5) == 0) { 148 channelSel = ((freq - 704) * 2 - 3040) / 10; 149 bModeSynth = 1; 150 } else { 151 HALDEBUG(ah, HAL_DEBUG_ANY, 152 "%s: invalid channel %u MHz\n", __func__, freq); 153 return AH_FALSE; 154 } 155 156 channelSel = (channelSel << 2) & 0xff; 157 channelSel = ath_hal_reverseBits(channelSel, 8); 158 159 txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL); 160 if (freq == 2484) { 161 /* Enable channel spreading for channel 14 */ 162 OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 163 txctl | AR_PHY_CCK_TX_CTRL_JAPAN); 164 } else { 165 OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 166 txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN); 167 } 168 /* 169 * Handle programming the RF synth for odd frequencies in the 170 * 4.9->5GHz range. This matches the programming from the 171 * later model 802.11abg RF synths. 172 * 173 * This interoperates on the quarter rate channels with the 174 * AR5112 and later RF synths. Please note that the synthesiser 175 * isn't able to completely accurately represent these frequencies 176 * (as the resolution in this reference is 2.5MHz) and thus it will 177 * be slightly "off centre." This matches the same slightly 178 * incorrect * centre frequency behaviour that the AR5112 and later 179 * channel selection code has. 180 * 181 * This is disabled because it hasn't been tested for regulatory 182 * compliance and neither have the NICs which would use it. 183 * So if you enable this code, you must first ensure that you've 184 * re-certified the NICs in question beforehand or you will be 185 * violating your local regulatory rules and breaking the law. 186 */ 187 #if 0 188 } else if (((freq % 5) == 2) && (freq <= 5435)) { 189 freq = freq - 2; 190 channelSel = ath_hal_reverseBits( 191 (uint32_t) (((freq - 4800) * 10) / 25 + 1), 8); 192 /* XXX what about for Howl/Sowl? */ 193 aModeRefSel = ath_hal_reverseBits(0, 2); 194 #endif 195 } else if ((freq % 20) == 0 && freq >= 5120) { 196 channelSel = ath_hal_reverseBits(((freq - 4800) / 20 << 2), 8); 197 if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah)) 198 aModeRefSel = ath_hal_reverseBits(3, 2); 199 else 200 aModeRefSel = ath_hal_reverseBits(1, 2); 201 } else if ((freq % 10) == 0) { 202 channelSel = ath_hal_reverseBits(((freq - 4800) / 10 << 1), 8); 203 if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah)) 204 aModeRefSel = ath_hal_reverseBits(2, 2); 205 else 206 aModeRefSel = ath_hal_reverseBits(1, 2); 207 } else if ((freq % 5) == 0) { 208 channelSel = ath_hal_reverseBits((freq - 4800) / 5, 8); 209 aModeRefSel = ath_hal_reverseBits(1, 2); 210 } else { 211 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 212 "%s: invalid channel %u MHz\n", 213 __func__, freq); 214 return AH_FALSE; 215 } 216 217 /* Workaround for hw bug - AR5416 specific */ 218 if (AR_SREV_OWL(ah) && ah->ah_config.ah_ar5416_biasadj) 219 ar2133ForceBias(ah, freq); 220 221 reg32 = (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | 222 (1 << 5) | 0x1; 223 224 OS_REG_WRITE(ah, AR_PHY(0x37), reg32); 225 226 AH_PRIVATE(ah)->ah_curchan = chan; 227 return AH_TRUE; 228 229 } 230 231 /* 232 * Return a reference to the requested RF Bank. 233 */ 234 static uint32_t * 235 ar2133GetRfBank(struct ath_hal *ah, int bank) 236 { 237 struct ar2133State *priv = AR2133(ah); 238 239 HALASSERT(priv != AH_NULL); 240 switch (bank) { 241 case 1: return priv->Bank1Data; 242 case 2: return priv->Bank2Data; 243 case 3: return priv->Bank3Data; 244 case 6: return priv->Bank6Data; 245 case 7: return priv->Bank7Data; 246 } 247 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n", 248 __func__, bank); 249 return AH_NULL; 250 } 251 252 /* 253 * Reads EEPROM header info from device structure and programs 254 * all rf registers 255 * 256 * REQUIRES: Access to the analog rf device 257 */ 258 static HAL_BOOL 259 ar2133SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan, 260 uint16_t modesIndex, uint16_t *rfXpdGain) 261 { 262 struct ar2133State *priv = AR2133(ah); 263 int writes; 264 265 HALASSERT(priv); 266 267 /* Setup Bank 0 Write */ 268 ath_hal_ini_bank_setup(priv->Bank0Data, &AH5416(ah)->ah_ini_bank0, 1); 269 270 /* Setup Bank 1 Write */ 271 ath_hal_ini_bank_setup(priv->Bank1Data, &AH5416(ah)->ah_ini_bank1, 1); 272 273 /* Setup Bank 2 Write */ 274 ath_hal_ini_bank_setup(priv->Bank2Data, &AH5416(ah)->ah_ini_bank2, 1); 275 276 /* Setup Bank 3 Write */ 277 ath_hal_ini_bank_setup(priv->Bank3Data, &AH5416(ah)->ah_ini_bank3, modesIndex); 278 279 /* Setup Bank 6 Write */ 280 ath_hal_ini_bank_setup(priv->Bank6Data, &AH5416(ah)->ah_ini_bank6, modesIndex); 281 282 /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ 283 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 284 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: 2ghz: OB_2:%d, DB_2:%d\n", 285 __func__, 286 ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 287 ath_hal_eepromGet(ah, AR_EEP_DB_2, AH_NULL)); 288 ar5416ModifyRfBuffer(priv->Bank6Data, 289 ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 3, 197, 0); 290 ar5416ModifyRfBuffer(priv->Bank6Data, 291 ath_hal_eepromGet(ah, AR_EEP_DB_2, AH_NULL), 3, 194, 0); 292 } else { 293 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: 5ghz: OB_5:%d, DB_5:%d\n", 294 __func__, 295 ath_hal_eepromGet(ah, AR_EEP_OB_5, AH_NULL), 296 ath_hal_eepromGet(ah, AR_EEP_DB_5, AH_NULL)); 297 ar5416ModifyRfBuffer(priv->Bank6Data, 298 ath_hal_eepromGet(ah, AR_EEP_OB_5, AH_NULL), 3, 203, 0); 299 ar5416ModifyRfBuffer(priv->Bank6Data, 300 ath_hal_eepromGet(ah, AR_EEP_DB_5, AH_NULL), 3, 200, 0); 301 } 302 /* Setup Bank 7 Setup */ 303 ath_hal_ini_bank_setup(priv->Bank7Data, &AH5416(ah)->ah_ini_bank7, 1); 304 305 /* Write Analog registers */ 306 writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank0, 307 priv->Bank0Data, 0); 308 writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank1, 309 priv->Bank1Data, writes); 310 writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank2, 311 priv->Bank2Data, writes); 312 writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank3, 313 priv->Bank3Data, writes); 314 writes = ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank6, 315 priv->Bank6Data, writes); 316 (void) ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank7, 317 priv->Bank7Data, writes); 318 319 return AH_TRUE; 320 #undef RF_BANK_SETUP 321 } 322 323 /* 324 * Read the transmit power levels from the structures taken from EEPROM 325 * Interpolate read transmit power values for this channel 326 * Organize the transmit power values into a table for writing into the hardware 327 */ 328 329 static HAL_BOOL 330 ar2133SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax, 331 const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 332 { 333 return AH_TRUE; 334 } 335 336 #if 0 337 static int16_t 338 ar2133GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data) 339 { 340 int i, minIndex; 341 int16_t minGain,minPwr,minPcdac,retVal; 342 343 /* Assume NUM_POINTS_XPD0 > 0 */ 344 minGain = data->pDataPerXPD[0].xpd_gain; 345 for (minIndex=0,i=1; i<NUM_XPD_PER_CHANNEL; i++) { 346 if (data->pDataPerXPD[i].xpd_gain < minGain) { 347 minIndex = i; 348 minGain = data->pDataPerXPD[i].xpd_gain; 349 } 350 } 351 minPwr = data->pDataPerXPD[minIndex].pwr_t4[0]; 352 minPcdac = data->pDataPerXPD[minIndex].pcdac[0]; 353 for (i=1; i<NUM_POINTS_XPD0; i++) { 354 if (data->pDataPerXPD[minIndex].pwr_t4[i] < minPwr) { 355 minPwr = data->pDataPerXPD[minIndex].pwr_t4[i]; 356 minPcdac = data->pDataPerXPD[minIndex].pcdac[i]; 357 } 358 } 359 retVal = minPwr - (minPcdac*2); 360 return(retVal); 361 } 362 #endif 363 364 static HAL_BOOL 365 ar2133GetChannelMaxMinPower(struct ath_hal *ah, 366 const struct ieee80211_channel *chan, 367 int16_t *maxPow, int16_t *minPow) 368 { 369 #if 0 370 struct ath_hal_5212 *ahp = AH5212(ah); 371 int numChannels=0,i,last; 372 int totalD, totalF,totalMin; 373 EXPN_DATA_PER_CHANNEL_5112 *data=AH_NULL; 374 EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL; 375 376 *maxPow = 0; 377 if (IS_CHAN_A(chan)) { 378 powerArray = ahp->ah_modePowerArray5112; 379 data = powerArray[headerInfo11A].pDataPerChannel; 380 numChannels = powerArray[headerInfo11A].numChannels; 381 } else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) { 382 /* XXX - is this correct? Should we also use the same power for turbo G? */ 383 powerArray = ahp->ah_modePowerArray5112; 384 data = powerArray[headerInfo11G].pDataPerChannel; 385 numChannels = powerArray[headerInfo11G].numChannels; 386 } else if (IS_CHAN_B(chan)) { 387 powerArray = ahp->ah_modePowerArray5112; 388 data = powerArray[headerInfo11B].pDataPerChannel; 389 numChannels = powerArray[headerInfo11B].numChannels; 390 } else { 391 return (AH_TRUE); 392 } 393 /* Make sure the channel is in the range of the TP values 394 * (freq piers) 395 */ 396 if ((numChannels < 1) || 397 (chan->channel < data[0].channelValue) || 398 (chan->channel > data[numChannels-1].channelValue)) 399 return(AH_FALSE); 400 401 /* Linearly interpolate the power value now */ 402 for (last=0,i=0; 403 (i<numChannels) && (chan->channel > data[i].channelValue); 404 last=i++); 405 totalD = data[i].channelValue - data[last].channelValue; 406 if (totalD > 0) { 407 totalF = data[i].maxPower_t4 - data[last].maxPower_t4; 408 *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD); 409 410 totalMin = ar2133GetMinPower(ah,&data[i]) - ar2133GetMinPower(ah, &data[last]); 411 *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar2133GetMinPower(ah, &data[last])*totalD)/totalD); 412 return (AH_TRUE); 413 } else { 414 if (chan->channel == data[i].channelValue) { 415 *maxPow = data[i].maxPower_t4; 416 *minPow = ar2133GetMinPower(ah, &data[i]); 417 return(AH_TRUE); 418 } else 419 return(AH_FALSE); 420 } 421 #else 422 *maxPow = *minPow = 0; 423 return AH_FALSE; 424 #endif 425 } 426 427 /* 428 * The ordering of nfarray is thus: 429 * 430 * nfarray[0]: Chain 0 ctl 431 * nfarray[1]: Chain 1 ctl 432 * nfarray[2]: Chain 2 ctl 433 * nfarray[3]: Chain 0 ext 434 * nfarray[4]: Chain 1 ext 435 * nfarray[5]: Chain 2 ext 436 */ 437 static void 438 ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) 439 { 440 struct ath_hal_5416 *ahp = AH5416(ah); 441 int16_t nf; 442 443 /* 444 * Blank nf array - some chips may only 445 * have one or two RX chainmasks enabled. 446 */ 447 nfarray[0] = nfarray[1] = nfarray[2] = 0; 448 nfarray[3] = nfarray[4] = nfarray[5] = 0; 449 450 switch (ahp->ah_rx_chainmask) { 451 case 0x7: 452 nf = MS(OS_REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); 453 if (nf & 0x100) 454 nf = 0 - ((nf ^ 0x1ff) + 1); 455 HALDEBUG(ah, HAL_DEBUG_NFCAL, 456 "NF calibrated [ctl] [chain 2] is %d\n", nf); 457 nfarray[2] = nf; 458 459 nf = MS(OS_REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); 460 if (nf & 0x100) 461 nf = 0 - ((nf ^ 0x1ff) + 1); 462 HALDEBUG(ah, HAL_DEBUG_NFCAL, 463 "NF calibrated [ext] [chain 2] is %d\n", nf); 464 nfarray[5] = nf; 465 /* fall thru... */ 466 case 0x3: 467 case 0x5: 468 nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); 469 if (nf & 0x100) 470 nf = 0 - ((nf ^ 0x1ff) + 1); 471 HALDEBUG(ah, HAL_DEBUG_NFCAL, 472 "NF calibrated [ctl] [chain 1] is %d\n", nf); 473 nfarray[1] = nf; 474 475 476 nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); 477 if (nf & 0x100) 478 nf = 0 - ((nf ^ 0x1ff) + 1); 479 HALDEBUG(ah, HAL_DEBUG_NFCAL, 480 "NF calibrated [ext] [chain 1] is %d\n", nf); 481 nfarray[4] = nf; 482 /* fall thru... */ 483 case 0x1: 484 nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); 485 if (nf & 0x100) 486 nf = 0 - ((nf ^ 0x1ff) + 1); 487 HALDEBUG(ah, HAL_DEBUG_NFCAL, 488 "NF calibrated [ctl] [chain 0] is %d\n", nf); 489 nfarray[0] = nf; 490 491 nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 492 if (nf & 0x100) 493 nf = 0 - ((nf ^ 0x1ff) + 1); 494 HALDEBUG(ah, HAL_DEBUG_NFCAL, 495 "NF calibrated [ext] [chain 0] is %d\n", nf); 496 nfarray[3] = nf; 497 498 break; 499 } 500 } 501 502 /* 503 * Adjust NF based on statistical values for 5GHz frequencies. 504 * Stubbed:Not used by Fowl 505 */ 506 static int16_t 507 ar2133GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c) 508 { 509 return 0; 510 } 511 512 /* 513 * Free memory for analog bank scratch buffers 514 */ 515 static void 516 ar2133RfDetach(struct ath_hal *ah) 517 { 518 struct ath_hal_5212 *ahp = AH5212(ah); 519 520 HALASSERT(ahp->ah_rfHal != AH_NULL); 521 ath_hal_free(ahp->ah_rfHal); 522 ahp->ah_rfHal = AH_NULL; 523 } 524 525 /* 526 * Allocate memory for analog bank scratch buffers 527 * Scratch Buffer will be reinitialized every reset so no need to zero now 528 */ 529 HAL_BOOL 530 ar2133RfAttach(struct ath_hal *ah, HAL_STATUS *status) 531 { 532 struct ath_hal_5212 *ahp = AH5212(ah); 533 struct ar2133State *priv; 534 uint32_t *bankData; 535 536 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: attach AR2133 radio\n", __func__); 537 538 HALASSERT(ahp->ah_rfHal == AH_NULL); 539 priv = ath_hal_malloc(sizeof(struct ar2133State) 540 + AH5416(ah)->ah_ini_bank0.rows * sizeof(uint32_t) 541 + AH5416(ah)->ah_ini_bank1.rows * sizeof(uint32_t) 542 + AH5416(ah)->ah_ini_bank2.rows * sizeof(uint32_t) 543 + AH5416(ah)->ah_ini_bank3.rows * sizeof(uint32_t) 544 + AH5416(ah)->ah_ini_bank6.rows * sizeof(uint32_t) 545 + AH5416(ah)->ah_ini_bank7.rows * sizeof(uint32_t) 546 ); 547 if (priv == AH_NULL) { 548 HALDEBUG(ah, HAL_DEBUG_ANY, 549 "%s: cannot allocate private state\n", __func__); 550 *status = HAL_ENOMEM; /* XXX */ 551 return AH_FALSE; 552 } 553 priv->base.rfDetach = ar2133RfDetach; 554 priv->base.writeRegs = ar2133WriteRegs; 555 priv->base.getRfBank = ar2133GetRfBank; 556 priv->base.setChannel = ar2133SetChannel; 557 priv->base.setRfRegs = ar2133SetRfRegs; 558 priv->base.setPowerTable = ar2133SetPowerTable; 559 priv->base.getChannelMaxMinPower = ar2133GetChannelMaxMinPower; 560 priv->base.getNfAdjust = ar2133GetNfAdjust; 561 562 bankData = (uint32_t *) &priv[1]; 563 priv->Bank0Data = bankData, bankData += AH5416(ah)->ah_ini_bank0.rows; 564 priv->Bank1Data = bankData, bankData += AH5416(ah)->ah_ini_bank1.rows; 565 priv->Bank2Data = bankData, bankData += AH5416(ah)->ah_ini_bank2.rows; 566 priv->Bank3Data = bankData, bankData += AH5416(ah)->ah_ini_bank3.rows; 567 priv->Bank6Data = bankData, bankData += AH5416(ah)->ah_ini_bank6.rows; 568 priv->Bank7Data = bankData, bankData += AH5416(ah)->ah_ini_bank7.rows; 569 570 ahp->ah_pcdacTable = priv->pcdacTable; 571 ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable); 572 ahp->ah_rfHal = &priv->base; 573 /* 574 * Set noise floor adjust method; we arrange a 575 * direct call instead of thunking. 576 */ 577 AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust; 578 AH_PRIVATE(ah)->ah_getNoiseFloor = ar2133GetNoiseFloor; 579 580 return AH_TRUE; 581 } 582 583 static HAL_BOOL 584 ar2133Probe(struct ath_hal *ah) 585 { 586 return (AR_SREV_OWL(ah) || AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)); 587 } 588 589 AH_RF(RF2133, ar2133Probe, ar2133RfAttach); 590