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