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