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