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