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