1 /* 2 * Copyright (c) 2008-2011 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "hw.h" 18 #include "ar9002_phy.h" 19 20 static void ath9k_get_txgain_index(struct ath_hw *ah, 21 struct ath9k_channel *chan, 22 struct calDataPerFreqOpLoop *rawDatasetOpLoop, 23 u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx) 24 { 25 u8 pcdac, i = 0; 26 u16 idxL = 0, idxR = 0, numPiers; 27 bool match; 28 struct chan_centers centers; 29 30 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 31 32 for (numPiers = 0; numPiers < availPiers; numPiers++) 33 if (calChans[numPiers] == AR5416_BCHAN_UNUSED) 34 break; 35 36 match = ath9k_hw_get_lower_upper_index( 37 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 38 calChans, numPiers, &idxL, &idxR); 39 if (match) { 40 pcdac = rawDatasetOpLoop[idxL].pcdac[0][0]; 41 *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0]; 42 } else { 43 pcdac = rawDatasetOpLoop[idxR].pcdac[0][0]; 44 *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] + 45 rawDatasetOpLoop[idxR].pwrPdg[0][0])/2; 46 } 47 48 while (pcdac > ah->originalGain[i] && 49 i < (AR9280_TX_GAIN_TABLE_SIZE - 1)) 50 i++; 51 52 *pcdacIdx = i; 53 } 54 55 static void ath9k_olc_get_pdadcs(struct ath_hw *ah, 56 u32 initTxGain, 57 int txPower, 58 u8 *pPDADCValues) 59 { 60 u32 i; 61 u32 offset; 62 63 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0, 64 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 65 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1, 66 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 67 68 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7, 69 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain); 70 71 offset = txPower; 72 for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++) 73 if (i < offset) 74 pPDADCValues[i] = 0x0; 75 else 76 pPDADCValues[i] = 0xFF; 77 } 78 79 static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah) 80 { 81 return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF); 82 } 83 84 static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) 85 { 86 return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); 87 } 88 89 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) 90 91 static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah) 92 { 93 struct ath_common *common = ath9k_hw_common(ah); 94 u16 *eep_data = (u16 *)&ah->eeprom.def; 95 int addr, ar5416_eep_start_loc = 0x100; 96 97 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 98 if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc, 99 eep_data)) { 100 ath_err(ath9k_hw_common(ah), 101 "Unable to read eeprom region\n"); 102 return false; 103 } 104 eep_data++; 105 } 106 return true; 107 } 108 109 static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah) 110 { 111 u16 *eep_data = (u16 *)&ah->eeprom.def; 112 113 ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 114 0x100, SIZE_EEPROM_DEF); 115 return true; 116 } 117 118 static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) 119 { 120 struct ath_common *common = ath9k_hw_common(ah); 121 122 if (!ath9k_hw_use_flash(ah)) { 123 ath_dbg(common, ATH_DBG_EEPROM, 124 "Reading from EEPROM, not flash\n"); 125 } 126 127 if (common->bus_ops->ath_bus_type == ATH_USB) 128 return __ath9k_hw_usb_def_fill_eeprom(ah); 129 else 130 return __ath9k_hw_def_fill_eeprom(ah); 131 } 132 133 #undef SIZE_EEPROM_DEF 134 135 static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) 136 { 137 struct ar5416_eeprom_def *eep = 138 (struct ar5416_eeprom_def *) &ah->eeprom.def; 139 struct ath_common *common = ath9k_hw_common(ah); 140 u16 *eepdata, temp, magic, magic2; 141 u32 sum = 0, el; 142 bool need_swap = false; 143 int i, addr, size; 144 145 if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 146 ath_err(common, "Reading Magic # failed\n"); 147 return false; 148 } 149 150 if (!ath9k_hw_use_flash(ah)) { 151 ath_dbg(common, ATH_DBG_EEPROM, 152 "Read Magic = 0x%04X\n", magic); 153 154 if (magic != AR5416_EEPROM_MAGIC) { 155 magic2 = swab16(magic); 156 157 if (magic2 == AR5416_EEPROM_MAGIC) { 158 size = sizeof(struct ar5416_eeprom_def); 159 need_swap = true; 160 eepdata = (u16 *) (&ah->eeprom); 161 162 for (addr = 0; addr < size / sizeof(u16); addr++) { 163 temp = swab16(*eepdata); 164 *eepdata = temp; 165 eepdata++; 166 } 167 } else { 168 ath_err(common, 169 "Invalid EEPROM Magic. Endianness mismatch.\n"); 170 return -EINVAL; 171 } 172 } 173 } 174 175 ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", 176 need_swap ? "True" : "False"); 177 178 if (need_swap) 179 el = swab16(ah->eeprom.def.baseEepHeader.length); 180 else 181 el = ah->eeprom.def.baseEepHeader.length; 182 183 if (el > sizeof(struct ar5416_eeprom_def)) 184 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); 185 else 186 el = el / sizeof(u16); 187 188 eepdata = (u16 *)(&ah->eeprom); 189 190 for (i = 0; i < el; i++) 191 sum ^= *eepdata++; 192 193 if (need_swap) { 194 u32 integer, j; 195 u16 word; 196 197 ath_dbg(common, ATH_DBG_EEPROM, 198 "EEPROM Endianness is not native.. Changing.\n"); 199 200 word = swab16(eep->baseEepHeader.length); 201 eep->baseEepHeader.length = word; 202 203 word = swab16(eep->baseEepHeader.checksum); 204 eep->baseEepHeader.checksum = word; 205 206 word = swab16(eep->baseEepHeader.version); 207 eep->baseEepHeader.version = word; 208 209 word = swab16(eep->baseEepHeader.regDmn[0]); 210 eep->baseEepHeader.regDmn[0] = word; 211 212 word = swab16(eep->baseEepHeader.regDmn[1]); 213 eep->baseEepHeader.regDmn[1] = word; 214 215 word = swab16(eep->baseEepHeader.rfSilent); 216 eep->baseEepHeader.rfSilent = word; 217 218 word = swab16(eep->baseEepHeader.blueToothOptions); 219 eep->baseEepHeader.blueToothOptions = word; 220 221 word = swab16(eep->baseEepHeader.deviceCap); 222 eep->baseEepHeader.deviceCap = word; 223 224 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) { 225 struct modal_eep_header *pModal = 226 &eep->modalHeader[j]; 227 integer = swab32(pModal->antCtrlCommon); 228 pModal->antCtrlCommon = integer; 229 230 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 231 integer = swab32(pModal->antCtrlChain[i]); 232 pModal->antCtrlChain[i] = integer; 233 } 234 for (i = 0; i < 3; i++) { 235 word = swab16(pModal->xpaBiasLvlFreq[i]); 236 pModal->xpaBiasLvlFreq[i] = word; 237 } 238 239 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 240 word = swab16(pModal->spurChans[i].spurChan); 241 pModal->spurChans[i].spurChan = word; 242 } 243 } 244 } 245 246 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 247 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 248 ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 249 sum, ah->eep_ops->get_eeprom_ver(ah)); 250 return -EINVAL; 251 } 252 253 /* Enable fixup for AR_AN_TOP2 if necessary */ 254 if ((ah->hw_version.devid == AR9280_DEVID_PCI) && 255 ((eep->baseEepHeader.version & 0xff) > 0x0a) && 256 (eep->baseEepHeader.pwdclkind == 0)) 257 ah->need_an_top2_fixup = 1; 258 259 if ((common->bus_ops->ath_bus_type == ATH_USB) && 260 (AR_SREV_9280(ah))) 261 eep->modalHeader[0].xpaBiasLvl = 0; 262 263 return 0; 264 } 265 266 static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, 267 enum eeprom_param param) 268 { 269 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 270 struct modal_eep_header *pModal = eep->modalHeader; 271 struct base_eep_header *pBase = &eep->baseEepHeader; 272 273 switch (param) { 274 case EEP_NFTHRESH_5: 275 return pModal[0].noiseFloorThreshCh[0]; 276 case EEP_NFTHRESH_2: 277 return pModal[1].noiseFloorThreshCh[0]; 278 case EEP_MAC_LSW: 279 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 280 case EEP_MAC_MID: 281 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 282 case EEP_MAC_MSW: 283 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 284 case EEP_REG_0: 285 return pBase->regDmn[0]; 286 case EEP_REG_1: 287 return pBase->regDmn[1]; 288 case EEP_OP_CAP: 289 return pBase->deviceCap; 290 case EEP_OP_MODE: 291 return pBase->opCapFlags; 292 case EEP_RF_SILENT: 293 return pBase->rfSilent; 294 case EEP_OB_5: 295 return pModal[0].ob; 296 case EEP_DB_5: 297 return pModal[0].db; 298 case EEP_OB_2: 299 return pModal[1].ob; 300 case EEP_DB_2: 301 return pModal[1].db; 302 case EEP_MINOR_REV: 303 return AR5416_VER_MASK; 304 case EEP_TX_MASK: 305 return pBase->txMask; 306 case EEP_RX_MASK: 307 return pBase->rxMask; 308 case EEP_FSTCLK_5G: 309 return pBase->fastClk5g; 310 case EEP_RXGAIN_TYPE: 311 return pBase->rxGainType; 312 case EEP_TXGAIN_TYPE: 313 return pBase->txGainType; 314 case EEP_OL_PWRCTRL: 315 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 316 return pBase->openLoopPwrCntl ? true : false; 317 else 318 return false; 319 case EEP_RC_CHAIN_MASK: 320 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 321 return pBase->rcChainMask; 322 else 323 return 0; 324 case EEP_DAC_HPWR_5G: 325 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) 326 return pBase->dacHiPwrMode_5G; 327 else 328 return 0; 329 case EEP_FRAC_N_5G: 330 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22) 331 return pBase->frac_n_5g; 332 else 333 return 0; 334 case EEP_PWR_TABLE_OFFSET: 335 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21) 336 return pBase->pwr_table_offset; 337 else 338 return AR5416_PWR_TABLE_OFFSET_DB; 339 default: 340 return 0; 341 } 342 } 343 344 static void ath9k_hw_def_set_gain(struct ath_hw *ah, 345 struct modal_eep_header *pModal, 346 struct ar5416_eeprom_def *eep, 347 u8 txRxAttenLocal, int regChainOffset, int i) 348 { 349 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 350 txRxAttenLocal = pModal->txRxAttenCh[i]; 351 352 if (AR_SREV_9280_20_OR_LATER(ah)) { 353 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 354 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 355 pModal->bswMargin[i]); 356 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 357 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 358 pModal->bswAtten[i]); 359 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 360 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 361 pModal->xatten2Margin[i]); 362 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 363 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 364 pModal->xatten2Db[i]); 365 } else { 366 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 367 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 368 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) 369 | SM(pModal-> bswMargin[i], 370 AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 371 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 372 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 373 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) 374 | SM(pModal->bswAtten[i], 375 AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 376 } 377 } 378 379 if (AR_SREV_9280_20_OR_LATER(ah)) { 380 REG_RMW_FIELD(ah, 381 AR_PHY_RXGAIN + regChainOffset, 382 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 383 REG_RMW_FIELD(ah, 384 AR_PHY_RXGAIN + regChainOffset, 385 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 386 } else { 387 REG_WRITE(ah, 388 AR_PHY_RXGAIN + regChainOffset, 389 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & 390 ~AR_PHY_RXGAIN_TXRX_ATTEN) 391 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); 392 REG_WRITE(ah, 393 AR_PHY_GAIN_2GHZ + regChainOffset, 394 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 395 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 396 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 397 } 398 } 399 400 static void ath9k_hw_def_set_board_values(struct ath_hw *ah, 401 struct ath9k_channel *chan) 402 { 403 struct modal_eep_header *pModal; 404 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 405 int i, regChainOffset; 406 u8 txRxAttenLocal; 407 408 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 409 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 410 411 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff); 412 413 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 414 if (AR_SREV_9280(ah)) { 415 if (i >= 2) 416 break; 417 } 418 419 if (AR_SREV_5416_20_OR_LATER(ah) && 420 (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) 421 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 422 else 423 regChainOffset = i * 0x1000; 424 425 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 426 pModal->antCtrlChain[i]); 427 428 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 429 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 430 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 431 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 432 SM(pModal->iqCalICh[i], 433 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 434 SM(pModal->iqCalQCh[i], 435 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 436 437 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) 438 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, 439 regChainOffset, i); 440 } 441 442 if (AR_SREV_9280_20_OR_LATER(ah)) { 443 if (IS_CHAN_2GHZ(chan)) { 444 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, 445 AR_AN_RF2G1_CH0_OB, 446 AR_AN_RF2G1_CH0_OB_S, 447 pModal->ob); 448 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, 449 AR_AN_RF2G1_CH0_DB, 450 AR_AN_RF2G1_CH0_DB_S, 451 pModal->db); 452 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, 453 AR_AN_RF2G1_CH1_OB, 454 AR_AN_RF2G1_CH1_OB_S, 455 pModal->ob_ch1); 456 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, 457 AR_AN_RF2G1_CH1_DB, 458 AR_AN_RF2G1_CH1_DB_S, 459 pModal->db_ch1); 460 } else { 461 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, 462 AR_AN_RF5G1_CH0_OB5, 463 AR_AN_RF5G1_CH0_OB5_S, 464 pModal->ob); 465 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, 466 AR_AN_RF5G1_CH0_DB5, 467 AR_AN_RF5G1_CH0_DB5_S, 468 pModal->db); 469 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, 470 AR_AN_RF5G1_CH1_OB5, 471 AR_AN_RF5G1_CH1_OB5_S, 472 pModal->ob_ch1); 473 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, 474 AR_AN_RF5G1_CH1_DB5, 475 AR_AN_RF5G1_CH1_DB5_S, 476 pModal->db_ch1); 477 } 478 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, 479 AR_AN_TOP2_XPABIAS_LVL, 480 AR_AN_TOP2_XPABIAS_LVL_S, 481 pModal->xpaBiasLvl); 482 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, 483 AR_AN_TOP2_LOCALBIAS, 484 AR_AN_TOP2_LOCALBIAS_S, 485 !!(pModal->lna_ctl & 486 LNA_CTL_LOCAL_BIAS)); 487 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, 488 !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA)); 489 } 490 491 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 492 pModal->switchSettling); 493 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 494 pModal->adcDesiredSize); 495 496 if (!AR_SREV_9280_20_OR_LATER(ah)) 497 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 498 AR_PHY_DESIRED_SZ_PGA, 499 pModal->pgaDesiredSize); 500 501 REG_WRITE(ah, AR_PHY_RF_CTL4, 502 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 503 | SM(pModal->txEndToXpaOff, 504 AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 505 | SM(pModal->txFrameToXpaOn, 506 AR_PHY_RF_CTL4_FRAME_XPAA_ON) 507 | SM(pModal->txFrameToXpaOn, 508 AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 509 510 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 511 pModal->txEndToRxOn); 512 513 if (AR_SREV_9280_20_OR_LATER(ah)) { 514 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 515 pModal->thresh62); 516 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, 517 AR_PHY_EXT_CCA0_THRESH62, 518 pModal->thresh62); 519 } else { 520 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 521 pModal->thresh62); 522 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, 523 AR_PHY_EXT_CCA_THRESH62, 524 pModal->thresh62); 525 } 526 527 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { 528 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 529 AR_PHY_TX_END_DATA_START, 530 pModal->txFrameToDataStart); 531 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 532 pModal->txFrameToPaOn); 533 } 534 535 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 536 if (IS_CHAN_HT40(chan)) 537 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 538 AR_PHY_SETTLING_SWITCH, 539 pModal->swSettleHt40); 540 } 541 542 if (AR_SREV_9280_20_OR_LATER(ah) && 543 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 544 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, 545 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, 546 pModal->miscBits); 547 548 549 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { 550 if (IS_CHAN_2GHZ(chan)) 551 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 552 eep->baseEepHeader.dacLpMode); 553 else if (eep->baseEepHeader.dacHiPwrMode_5G) 554 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 555 else 556 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 557 eep->baseEepHeader.dacLpMode); 558 559 udelay(100); 560 561 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, 562 pModal->miscBits >> 2); 563 564 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, 565 AR_PHY_TX_DESIRED_SCALE_CCK, 566 eep->baseEepHeader.desiredScaleCCK); 567 } 568 } 569 570 static void ath9k_hw_def_set_addac(struct ath_hw *ah, 571 struct ath9k_channel *chan) 572 { 573 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) 574 struct modal_eep_header *pModal; 575 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 576 u8 biaslevel; 577 578 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 579 return; 580 581 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) 582 return; 583 584 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 585 586 if (pModal->xpaBiasLvl != 0xff) { 587 biaslevel = pModal->xpaBiasLvl; 588 } else { 589 u16 resetFreqBin, freqBin, freqCount = 0; 590 struct chan_centers centers; 591 592 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 593 594 resetFreqBin = FREQ2FBIN(centers.synth_center, 595 IS_CHAN_2GHZ(chan)); 596 freqBin = XPA_LVL_FREQ(0) & 0xff; 597 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14); 598 599 freqCount++; 600 601 while (freqCount < 3) { 602 if (XPA_LVL_FREQ(freqCount) == 0x0) 603 break; 604 605 freqBin = XPA_LVL_FREQ(freqCount) & 0xff; 606 if (resetFreqBin >= freqBin) 607 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); 608 else 609 break; 610 freqCount++; 611 } 612 } 613 614 if (IS_CHAN_2GHZ(chan)) { 615 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac, 616 7, 1) & (~0x18)) | biaslevel << 3; 617 } else { 618 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac, 619 6, 1) & (~0xc0)) | biaslevel << 6; 620 } 621 #undef XPA_LVL_FREQ 622 } 623 624 static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, 625 u16 *gb, 626 u16 numXpdGain, 627 u16 pdGainOverlap_t2, 628 int8_t pwr_table_offset, 629 int16_t *diff) 630 631 { 632 u16 k; 633 634 /* Prior to writing the boundaries or the pdadc vs. power table 635 * into the chip registers the default starting point on the pdadc 636 * vs. power table needs to be checked and the curve boundaries 637 * adjusted accordingly 638 */ 639 if (AR_SREV_9280_20_OR_LATER(ah)) { 640 u16 gb_limit; 641 642 if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) { 643 /* get the difference in dB */ 644 *diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB); 645 /* get the number of half dB steps */ 646 *diff *= 2; 647 /* change the original gain boundary settings 648 * by the number of half dB steps 649 */ 650 for (k = 0; k < numXpdGain; k++) 651 gb[k] = (u16)(gb[k] - *diff); 652 } 653 /* Because of a hardware limitation, ensure the gain boundary 654 * is not larger than (63 - overlap) 655 */ 656 gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2); 657 658 for (k = 0; k < numXpdGain; k++) 659 gb[k] = (u16)min(gb_limit, gb[k]); 660 } 661 662 return *diff; 663 } 664 665 static void ath9k_adjust_pdadc_values(struct ath_hw *ah, 666 int8_t pwr_table_offset, 667 int16_t diff, 668 u8 *pdadcValues) 669 { 670 #define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff) 671 u16 k; 672 673 /* If this is a board that has a pwrTableOffset that differs from 674 * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the 675 * pdadc vs pwr table needs to be adjusted prior to writing to the 676 * chip. 677 */ 678 if (AR_SREV_9280_20_OR_LATER(ah)) { 679 if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) { 680 /* shift the table to start at the new offset */ 681 for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) { 682 pdadcValues[k] = pdadcValues[k + diff]; 683 } 684 685 /* fill the back of the table */ 686 for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) { 687 pdadcValues[k] = pdadcValues[NUM_PDADC(diff)]; 688 } 689 } 690 } 691 #undef NUM_PDADC 692 } 693 694 static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, 695 struct ath9k_channel *chan, 696 int16_t *pTxPowerIndexOffset) 697 { 698 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) 699 #define SM_PDGAIN_B(x, y) \ 700 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y) 701 struct ath_common *common = ath9k_hw_common(ah); 702 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 703 struct cal_data_per_freq *pRawDataset; 704 u8 *pCalBChans = NULL; 705 u16 pdGainOverlap_t2; 706 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 707 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 708 u16 numPiers, i, j; 709 int16_t diff = 0; 710 u16 numXpdGain, xpdMask; 711 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; 712 u32 reg32, regOffset, regChainOffset; 713 int16_t modalIdx; 714 int8_t pwr_table_offset; 715 716 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; 717 xpdMask = pEepData->modalHeader[modalIdx].xpdGain; 718 719 pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET); 720 721 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 722 AR5416_EEP_MINOR_VER_2) { 723 pdGainOverlap_t2 = 724 pEepData->modalHeader[modalIdx].pdGainOverlap; 725 } else { 726 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 727 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 728 } 729 730 if (IS_CHAN_2GHZ(chan)) { 731 pCalBChans = pEepData->calFreqPier2G; 732 numPiers = AR5416_NUM_2G_CAL_PIERS; 733 } else { 734 pCalBChans = pEepData->calFreqPier5G; 735 numPiers = AR5416_NUM_5G_CAL_PIERS; 736 } 737 738 if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) { 739 pRawDataset = pEepData->calPierData2G[0]; 740 ah->initPDADC = ((struct calDataPerFreqOpLoop *) 741 pRawDataset)->vpdPdg[0][0]; 742 } 743 744 numXpdGain = 0; 745 746 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 747 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 748 if (numXpdGain >= AR5416_NUM_PD_GAINS) 749 break; 750 xpdGainValues[numXpdGain] = 751 (u16)(AR5416_PD_GAINS_IN_MASK - i); 752 numXpdGain++; 753 } 754 } 755 756 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 757 (numXpdGain - 1) & 0x3); 758 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 759 xpdGainValues[0]); 760 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 761 xpdGainValues[1]); 762 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 763 xpdGainValues[2]); 764 765 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 766 if (AR_SREV_5416_20_OR_LATER(ah) && 767 (ah->rxchainmask == 5 || ah->txchainmask == 5) && 768 (i != 0)) { 769 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 770 } else 771 regChainOffset = i * 0x1000; 772 773 if (pEepData->baseEepHeader.txMask & (1 << i)) { 774 if (IS_CHAN_2GHZ(chan)) 775 pRawDataset = pEepData->calPierData2G[i]; 776 else 777 pRawDataset = pEepData->calPierData5G[i]; 778 779 780 if (OLC_FOR_AR9280_20_LATER) { 781 u8 pcdacIdx; 782 u8 txPower; 783 784 ath9k_get_txgain_index(ah, chan, 785 (struct calDataPerFreqOpLoop *)pRawDataset, 786 pCalBChans, numPiers, &txPower, &pcdacIdx); 787 ath9k_olc_get_pdadcs(ah, pcdacIdx, 788 txPower/2, pdadcValues); 789 } else { 790 ath9k_hw_get_gain_boundaries_pdadcs(ah, 791 chan, pRawDataset, 792 pCalBChans, numPiers, 793 pdGainOverlap_t2, 794 gainBoundaries, 795 pdadcValues, 796 numXpdGain); 797 } 798 799 diff = ath9k_change_gain_boundary_setting(ah, 800 gainBoundaries, 801 numXpdGain, 802 pdGainOverlap_t2, 803 pwr_table_offset, 804 &diff); 805 806 ENABLE_REGWRITE_BUFFER(ah); 807 808 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 809 if (OLC_FOR_AR9280_20_LATER) { 810 REG_WRITE(ah, 811 AR_PHY_TPCRG5 + regChainOffset, 812 SM(0x6, 813 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 814 SM_PD_GAIN(1) | SM_PD_GAIN(2) | 815 SM_PD_GAIN(3) | SM_PD_GAIN(4)); 816 } else { 817 REG_WRITE(ah, 818 AR_PHY_TPCRG5 + regChainOffset, 819 SM(pdGainOverlap_t2, 820 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| 821 SM_PDGAIN_B(0, 1) | 822 SM_PDGAIN_B(1, 2) | 823 SM_PDGAIN_B(2, 3) | 824 SM_PDGAIN_B(3, 4)); 825 } 826 } 827 828 829 ath9k_adjust_pdadc_values(ah, pwr_table_offset, 830 diff, pdadcValues); 831 832 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 833 for (j = 0; j < 32; j++) { 834 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | 835 ((pdadcValues[4 * j + 1] & 0xFF) << 8) | 836 ((pdadcValues[4 * j + 2] & 0xFF) << 16)| 837 ((pdadcValues[4 * j + 3] & 0xFF) << 24); 838 REG_WRITE(ah, regOffset, reg32); 839 840 ath_dbg(common, ATH_DBG_EEPROM, 841 "PDADC (%d,%4x): %4.4x %8.8x\n", 842 i, regChainOffset, regOffset, 843 reg32); 844 ath_dbg(common, ATH_DBG_EEPROM, 845 "PDADC: Chain %d | PDADC %3d " 846 "Value %3d | PDADC %3d Value %3d | " 847 "PDADC %3d Value %3d | PDADC %3d " 848 "Value %3d |\n", 849 i, 4 * j, pdadcValues[4 * j], 850 4 * j + 1, pdadcValues[4 * j + 1], 851 4 * j + 2, pdadcValues[4 * j + 2], 852 4 * j + 3, pdadcValues[4 * j + 3]); 853 854 regOffset += 4; 855 } 856 REGWRITE_BUFFER_FLUSH(ah); 857 } 858 } 859 860 *pTxPowerIndexOffset = 0; 861 #undef SM_PD_GAIN 862 #undef SM_PDGAIN_B 863 } 864 865 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, 866 struct ath9k_channel *chan, 867 int16_t *ratesArray, 868 u16 cfgCtl, 869 u16 AntennaReduction, 870 u16 twiceMaxRegulatoryPower, 871 u16 powerLimit) 872 { 873 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 874 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ 875 876 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 877 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 878 u16 twiceMaxEdgePower = MAX_RATE_POWER; 879 static const u16 tpScaleReductionTable[5] = 880 { 0, 3, 6, 9, MAX_RATE_POWER }; 881 882 int i; 883 int16_t twiceLargestAntenna; 884 struct cal_ctl_data *rep; 885 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 886 0, { 0, 0, 0, 0} 887 }; 888 struct cal_target_power_leg targetPowerOfdmExt = { 889 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 890 0, { 0, 0, 0, 0 } 891 }; 892 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 893 0, {0, 0, 0, 0} 894 }; 895 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 896 static const u16 ctlModesFor11a[] = { 897 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 898 }; 899 static const u16 ctlModesFor11g[] = { 900 CTL_11B, CTL_11G, CTL_2GHT20, 901 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 902 }; 903 u16 numCtlModes; 904 const u16 *pCtlMode; 905 u16 ctlMode, freq; 906 struct chan_centers centers; 907 int tx_chainmask; 908 u16 twiceMinEdgePower; 909 910 tx_chainmask = ah->txchainmask; 911 912 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 913 914 twiceLargestAntenna = max( 915 pEepData->modalHeader 916 [IS_CHAN_2GHZ(chan)].antennaGainCh[0], 917 pEepData->modalHeader 918 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 919 920 twiceLargestAntenna = max((u8)twiceLargestAntenna, 921 pEepData->modalHeader 922 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 923 924 twiceLargestAntenna = (int16_t)min(AntennaReduction - 925 twiceLargestAntenna, 0); 926 927 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 928 929 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { 930 maxRegAllowedPower -= 931 (tpScaleReductionTable[(regulatory->tp_scale)] * 2); 932 } 933 934 scaledPower = min(powerLimit, maxRegAllowedPower); 935 936 switch (ar5416_get_ntxchains(tx_chainmask)) { 937 case 1: 938 break; 939 case 2: 940 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) 941 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 942 else 943 scaledPower = 0; 944 break; 945 case 3: 946 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) 947 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 948 else 949 scaledPower = 0; 950 break; 951 } 952 953 if (IS_CHAN_2GHZ(chan)) { 954 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - 955 SUB_NUM_CTL_MODES_AT_2G_40; 956 pCtlMode = ctlModesFor11g; 957 958 ath9k_hw_get_legacy_target_powers(ah, chan, 959 pEepData->calTargetPowerCck, 960 AR5416_NUM_2G_CCK_TARGET_POWERS, 961 &targetPowerCck, 4, false); 962 ath9k_hw_get_legacy_target_powers(ah, chan, 963 pEepData->calTargetPower2G, 964 AR5416_NUM_2G_20_TARGET_POWERS, 965 &targetPowerOfdm, 4, false); 966 ath9k_hw_get_target_powers(ah, chan, 967 pEepData->calTargetPower2GHT20, 968 AR5416_NUM_2G_20_TARGET_POWERS, 969 &targetPowerHt20, 8, false); 970 971 if (IS_CHAN_HT40(chan)) { 972 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 973 ath9k_hw_get_target_powers(ah, chan, 974 pEepData->calTargetPower2GHT40, 975 AR5416_NUM_2G_40_TARGET_POWERS, 976 &targetPowerHt40, 8, true); 977 ath9k_hw_get_legacy_target_powers(ah, chan, 978 pEepData->calTargetPowerCck, 979 AR5416_NUM_2G_CCK_TARGET_POWERS, 980 &targetPowerCckExt, 4, true); 981 ath9k_hw_get_legacy_target_powers(ah, chan, 982 pEepData->calTargetPower2G, 983 AR5416_NUM_2G_20_TARGET_POWERS, 984 &targetPowerOfdmExt, 4, true); 985 } 986 } else { 987 numCtlModes = ARRAY_SIZE(ctlModesFor11a) - 988 SUB_NUM_CTL_MODES_AT_5G_40; 989 pCtlMode = ctlModesFor11a; 990 991 ath9k_hw_get_legacy_target_powers(ah, chan, 992 pEepData->calTargetPower5G, 993 AR5416_NUM_5G_20_TARGET_POWERS, 994 &targetPowerOfdm, 4, false); 995 ath9k_hw_get_target_powers(ah, chan, 996 pEepData->calTargetPower5GHT20, 997 AR5416_NUM_5G_20_TARGET_POWERS, 998 &targetPowerHt20, 8, false); 999 1000 if (IS_CHAN_HT40(chan)) { 1001 numCtlModes = ARRAY_SIZE(ctlModesFor11a); 1002 ath9k_hw_get_target_powers(ah, chan, 1003 pEepData->calTargetPower5GHT40, 1004 AR5416_NUM_5G_40_TARGET_POWERS, 1005 &targetPowerHt40, 8, true); 1006 ath9k_hw_get_legacy_target_powers(ah, chan, 1007 pEepData->calTargetPower5G, 1008 AR5416_NUM_5G_20_TARGET_POWERS, 1009 &targetPowerOfdmExt, 4, true); 1010 } 1011 } 1012 1013 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 1014 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 1015 (pCtlMode[ctlMode] == CTL_2GHT40); 1016 if (isHt40CtlMode) 1017 freq = centers.synth_center; 1018 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 1019 freq = centers.ext_center; 1020 else 1021 freq = centers.ctl_center; 1022 1023 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 1024 ah->eep_ops->get_eeprom_rev(ah) <= 2) 1025 twiceMaxEdgePower = MAX_RATE_POWER; 1026 1027 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 1028 if ((((cfgCtl & ~CTL_MODE_M) | 1029 (pCtlMode[ctlMode] & CTL_MODE_M)) == 1030 pEepData->ctlIndex[i]) || 1031 (((cfgCtl & ~CTL_MODE_M) | 1032 (pCtlMode[ctlMode] & CTL_MODE_M)) == 1033 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 1034 rep = &(pEepData->ctlData[i]); 1035 1036 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, 1037 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], 1038 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); 1039 1040 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 1041 twiceMaxEdgePower = min(twiceMaxEdgePower, 1042 twiceMinEdgePower); 1043 } else { 1044 twiceMaxEdgePower = twiceMinEdgePower; 1045 break; 1046 } 1047 } 1048 } 1049 1050 minCtlPower = min(twiceMaxEdgePower, scaledPower); 1051 1052 switch (pCtlMode[ctlMode]) { 1053 case CTL_11B: 1054 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { 1055 targetPowerCck.tPow2x[i] = 1056 min((u16)targetPowerCck.tPow2x[i], 1057 minCtlPower); 1058 } 1059 break; 1060 case CTL_11A: 1061 case CTL_11G: 1062 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { 1063 targetPowerOfdm.tPow2x[i] = 1064 min((u16)targetPowerOfdm.tPow2x[i], 1065 minCtlPower); 1066 } 1067 break; 1068 case CTL_5GHT20: 1069 case CTL_2GHT20: 1070 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { 1071 targetPowerHt20.tPow2x[i] = 1072 min((u16)targetPowerHt20.tPow2x[i], 1073 minCtlPower); 1074 } 1075 break; 1076 case CTL_11B_EXT: 1077 targetPowerCckExt.tPow2x[0] = min((u16) 1078 targetPowerCckExt.tPow2x[0], 1079 minCtlPower); 1080 break; 1081 case CTL_11A_EXT: 1082 case CTL_11G_EXT: 1083 targetPowerOfdmExt.tPow2x[0] = min((u16) 1084 targetPowerOfdmExt.tPow2x[0], 1085 minCtlPower); 1086 break; 1087 case CTL_5GHT40: 1088 case CTL_2GHT40: 1089 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 1090 targetPowerHt40.tPow2x[i] = 1091 min((u16)targetPowerHt40.tPow2x[i], 1092 minCtlPower); 1093 } 1094 break; 1095 default: 1096 break; 1097 } 1098 } 1099 1100 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = 1101 ratesArray[rate18mb] = ratesArray[rate24mb] = 1102 targetPowerOfdm.tPow2x[0]; 1103 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 1104 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 1105 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 1106 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 1107 1108 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 1109 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 1110 1111 if (IS_CHAN_2GHZ(chan)) { 1112 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 1113 ratesArray[rate2s] = ratesArray[rate2l] = 1114 targetPowerCck.tPow2x[1]; 1115 ratesArray[rate5_5s] = ratesArray[rate5_5l] = 1116 targetPowerCck.tPow2x[2]; 1117 ratesArray[rate11s] = ratesArray[rate11l] = 1118 targetPowerCck.tPow2x[3]; 1119 } 1120 if (IS_CHAN_HT40(chan)) { 1121 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 1122 ratesArray[rateHt40_0 + i] = 1123 targetPowerHt40.tPow2x[i]; 1124 } 1125 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 1126 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 1127 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1128 if (IS_CHAN_2GHZ(chan)) { 1129 ratesArray[rateExtCck] = 1130 targetPowerCckExt.tPow2x[0]; 1131 } 1132 } 1133 } 1134 1135 static void ath9k_hw_def_set_txpower(struct ath_hw *ah, 1136 struct ath9k_channel *chan, 1137 u16 cfgCtl, 1138 u8 twiceAntennaReduction, 1139 u8 twiceMaxRegulatoryPower, 1140 u8 powerLimit, bool test) 1141 { 1142 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 1143 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 1144 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 1145 struct modal_eep_header *pModal = 1146 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); 1147 int16_t ratesArray[Ar5416RateSize]; 1148 int16_t txPowerIndexOffset = 0; 1149 u8 ht40PowerIncForPdadc = 2; 1150 int i, cck_ofdm_delta = 0; 1151 1152 memset(ratesArray, 0, sizeof(ratesArray)); 1153 1154 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1155 AR5416_EEP_MINOR_VER_2) { 1156 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1157 } 1158 1159 ath9k_hw_set_def_power_per_rate_table(ah, chan, 1160 &ratesArray[0], cfgCtl, 1161 twiceAntennaReduction, 1162 twiceMaxRegulatoryPower, 1163 powerLimit); 1164 1165 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset); 1166 1167 regulatory->max_power_level = 0; 1168 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1169 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1170 if (ratesArray[i] > MAX_RATE_POWER) 1171 ratesArray[i] = MAX_RATE_POWER; 1172 if (ratesArray[i] > regulatory->max_power_level) 1173 regulatory->max_power_level = ratesArray[i]; 1174 } 1175 1176 if (!test) { 1177 i = rate6mb; 1178 1179 if (IS_CHAN_HT40(chan)) 1180 i = rateHt40_0; 1181 else if (IS_CHAN_HT20(chan)) 1182 i = rateHt20_0; 1183 1184 regulatory->max_power_level = ratesArray[i]; 1185 } 1186 1187 switch(ar5416_get_ntxchains(ah->txchainmask)) { 1188 case 1: 1189 break; 1190 case 2: 1191 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 1192 break; 1193 case 3: 1194 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 1195 break; 1196 default: 1197 ath_dbg(ath9k_hw_common(ah), ATH_DBG_EEPROM, 1198 "Invalid chainmask configuration\n"); 1199 break; 1200 } 1201 1202 if (test) 1203 return; 1204 1205 if (AR_SREV_9280_20_OR_LATER(ah)) { 1206 for (i = 0; i < Ar5416RateSize; i++) { 1207 int8_t pwr_table_offset; 1208 1209 pwr_table_offset = ah->eep_ops->get_eeprom(ah, 1210 EEP_PWR_TABLE_OFFSET); 1211 ratesArray[i] -= pwr_table_offset * 2; 1212 } 1213 } 1214 1215 ENABLE_REGWRITE_BUFFER(ah); 1216 1217 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1218 ATH9K_POW_SM(ratesArray[rate18mb], 24) 1219 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 1220 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 1221 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 1222 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 1223 ATH9K_POW_SM(ratesArray[rate54mb], 24) 1224 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 1225 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 1226 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 1227 1228 if (IS_CHAN_2GHZ(chan)) { 1229 if (OLC_FOR_AR9280_20_LATER) { 1230 cck_ofdm_delta = 2; 1231 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1232 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24) 1233 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16) 1234 | ATH9K_POW_SM(ratesArray[rateXr], 8) 1235 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0)); 1236 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1237 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24) 1238 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16) 1239 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8) 1240 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0)); 1241 } else { 1242 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1243 ATH9K_POW_SM(ratesArray[rate2s], 24) 1244 | ATH9K_POW_SM(ratesArray[rate2l], 16) 1245 | ATH9K_POW_SM(ratesArray[rateXr], 8) 1246 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 1247 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1248 ATH9K_POW_SM(ratesArray[rate11s], 24) 1249 | ATH9K_POW_SM(ratesArray[rate11l], 16) 1250 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 1251 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 1252 } 1253 } 1254 1255 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1256 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 1257 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 1258 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 1259 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 1260 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 1261 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 1262 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 1263 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 1264 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 1265 1266 if (IS_CHAN_HT40(chan)) { 1267 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1268 ATH9K_POW_SM(ratesArray[rateHt40_3] + 1269 ht40PowerIncForPdadc, 24) 1270 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 1271 ht40PowerIncForPdadc, 16) 1272 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 1273 ht40PowerIncForPdadc, 8) 1274 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 1275 ht40PowerIncForPdadc, 0)); 1276 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 1277 ATH9K_POW_SM(ratesArray[rateHt40_7] + 1278 ht40PowerIncForPdadc, 24) 1279 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 1280 ht40PowerIncForPdadc, 16) 1281 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 1282 ht40PowerIncForPdadc, 8) 1283 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 1284 ht40PowerIncForPdadc, 0)); 1285 if (OLC_FOR_AR9280_20_LATER) { 1286 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1287 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 1288 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16) 1289 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 1290 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0)); 1291 } else { 1292 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1293 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 1294 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 1295 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 1296 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 1297 } 1298 } 1299 1300 REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1301 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1302 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 1303 1304 REGWRITE_BUFFER_FLUSH(ah); 1305 } 1306 1307 static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1308 { 1309 #define EEP_DEF_SPURCHAN \ 1310 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) 1311 struct ath_common *common = ath9k_hw_common(ah); 1312 1313 u16 spur_val = AR_NO_SPUR; 1314 1315 ath_dbg(common, ATH_DBG_ANI, 1316 "Getting spur idx:%d is2Ghz:%d val:%x\n", 1317 i, is2GHz, ah->config.spurchans[i][is2GHz]); 1318 1319 switch (ah->config.spurmode) { 1320 case SPUR_DISABLE: 1321 break; 1322 case SPUR_ENABLE_IOCTL: 1323 spur_val = ah->config.spurchans[i][is2GHz]; 1324 ath_dbg(common, ATH_DBG_ANI, 1325 "Getting spur val from new loc. %d\n", spur_val); 1326 break; 1327 case SPUR_ENABLE_EEPROM: 1328 spur_val = EEP_DEF_SPURCHAN; 1329 break; 1330 } 1331 1332 return spur_val; 1333 1334 #undef EEP_DEF_SPURCHAN 1335 } 1336 1337 const struct eeprom_ops eep_def_ops = { 1338 .check_eeprom = ath9k_hw_def_check_eeprom, 1339 .get_eeprom = ath9k_hw_def_get_eeprom, 1340 .fill_eeprom = ath9k_hw_def_fill_eeprom, 1341 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, 1342 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, 1343 .set_board_values = ath9k_hw_def_set_board_values, 1344 .set_addac = ath9k_hw_def_set_addac, 1345 .set_txpower = ath9k_hw_def_set_txpower, 1346 .get_spur_channel = ath9k_hw_def_get_spur_channel 1347 }; 1348