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