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