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