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