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 int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) 22 { 23 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); 24 } 25 26 static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) 27 { 28 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); 29 } 30 31 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 32 33 static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) 34 { 35 struct ath_common *common = ath9k_hw_common(ah); 36 u16 *eep_data = (u16 *)&ah->eeprom.map4k; 37 int addr, eep_start_loc = 64; 38 39 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { 40 if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { 41 ath_dbg(common, ATH_DBG_EEPROM, 42 "Unable to read eeprom region\n"); 43 return false; 44 } 45 eep_data++; 46 } 47 48 return true; 49 } 50 51 static bool __ath9k_hw_usb_4k_fill_eeprom(struct ath_hw *ah) 52 { 53 u16 *eep_data = (u16 *)&ah->eeprom.map4k; 54 55 ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 64, SIZE_EEPROM_4K); 56 57 return true; 58 } 59 60 static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) 61 { 62 struct ath_common *common = ath9k_hw_common(ah); 63 64 if (!ath9k_hw_use_flash(ah)) { 65 ath_dbg(common, ATH_DBG_EEPROM, 66 "Reading from EEPROM, not flash\n"); 67 } 68 69 if (common->bus_ops->ath_bus_type == ATH_USB) 70 return __ath9k_hw_usb_4k_fill_eeprom(ah); 71 else 72 return __ath9k_hw_4k_fill_eeprom(ah); 73 } 74 75 #undef SIZE_EEPROM_4K 76 77 static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) 78 { 79 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 80 struct ath_common *common = ath9k_hw_common(ah); 81 struct ar5416_eeprom_4k *eep = 82 (struct ar5416_eeprom_4k *) &ah->eeprom.map4k; 83 u16 *eepdata, temp, magic, magic2; 84 u32 sum = 0, el; 85 bool need_swap = false; 86 int i, addr; 87 88 89 if (!ath9k_hw_use_flash(ah)) { 90 if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, 91 &magic)) { 92 ath_err(common, "Reading Magic # failed\n"); 93 return false; 94 } 95 96 ath_dbg(common, ATH_DBG_EEPROM, 97 "Read Magic = 0x%04X\n", magic); 98 99 if (magic != AR5416_EEPROM_MAGIC) { 100 magic2 = swab16(magic); 101 102 if (magic2 == AR5416_EEPROM_MAGIC) { 103 need_swap = true; 104 eepdata = (u16 *) (&ah->eeprom); 105 106 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { 107 temp = swab16(*eepdata); 108 *eepdata = temp; 109 eepdata++; 110 } 111 } else { 112 ath_err(common, 113 "Invalid EEPROM Magic. Endianness mismatch.\n"); 114 return -EINVAL; 115 } 116 } 117 } 118 119 ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", 120 need_swap ? "True" : "False"); 121 122 if (need_swap) 123 el = swab16(ah->eeprom.map4k.baseEepHeader.length); 124 else 125 el = ah->eeprom.map4k.baseEepHeader.length; 126 127 if (el > sizeof(struct ar5416_eeprom_4k)) 128 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); 129 else 130 el = el / sizeof(u16); 131 132 eepdata = (u16 *)(&ah->eeprom); 133 134 for (i = 0; i < el; i++) 135 sum ^= *eepdata++; 136 137 if (need_swap) { 138 u32 integer; 139 u16 word; 140 141 ath_dbg(common, ATH_DBG_EEPROM, 142 "EEPROM Endianness is not native.. Changing\n"); 143 144 word = swab16(eep->baseEepHeader.length); 145 eep->baseEepHeader.length = word; 146 147 word = swab16(eep->baseEepHeader.checksum); 148 eep->baseEepHeader.checksum = word; 149 150 word = swab16(eep->baseEepHeader.version); 151 eep->baseEepHeader.version = word; 152 153 word = swab16(eep->baseEepHeader.regDmn[0]); 154 eep->baseEepHeader.regDmn[0] = word; 155 156 word = swab16(eep->baseEepHeader.regDmn[1]); 157 eep->baseEepHeader.regDmn[1] = word; 158 159 word = swab16(eep->baseEepHeader.rfSilent); 160 eep->baseEepHeader.rfSilent = word; 161 162 word = swab16(eep->baseEepHeader.blueToothOptions); 163 eep->baseEepHeader.blueToothOptions = word; 164 165 word = swab16(eep->baseEepHeader.deviceCap); 166 eep->baseEepHeader.deviceCap = word; 167 168 integer = swab32(eep->modalHeader.antCtrlCommon); 169 eep->modalHeader.antCtrlCommon = integer; 170 171 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 172 integer = swab32(eep->modalHeader.antCtrlChain[i]); 173 eep->modalHeader.antCtrlChain[i] = integer; 174 } 175 176 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 177 word = swab16(eep->modalHeader.spurChans[i].spurChan); 178 eep->modalHeader.spurChans[i].spurChan = word; 179 } 180 } 181 182 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 183 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 184 ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 185 sum, ah->eep_ops->get_eeprom_ver(ah)); 186 return -EINVAL; 187 } 188 189 return 0; 190 #undef EEPROM_4K_SIZE 191 } 192 193 static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, 194 enum eeprom_param param) 195 { 196 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 197 struct modal_eep_4k_header *pModal = &eep->modalHeader; 198 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 199 u16 ver_minor; 200 201 ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK; 202 203 switch (param) { 204 case EEP_NFTHRESH_2: 205 return pModal->noiseFloorThreshCh[0]; 206 case EEP_MAC_LSW: 207 return get_unaligned_be16(pBase->macAddr); 208 case EEP_MAC_MID: 209 return get_unaligned_be16(pBase->macAddr + 2); 210 case EEP_MAC_MSW: 211 return get_unaligned_be16(pBase->macAddr + 4); 212 case EEP_REG_0: 213 return pBase->regDmn[0]; 214 case EEP_REG_1: 215 return pBase->regDmn[1]; 216 case EEP_OP_CAP: 217 return pBase->deviceCap; 218 case EEP_OP_MODE: 219 return pBase->opCapFlags; 220 case EEP_RF_SILENT: 221 return pBase->rfSilent; 222 case EEP_OB_2: 223 return pModal->ob_0; 224 case EEP_DB_2: 225 return pModal->db1_1; 226 case EEP_MINOR_REV: 227 return ver_minor; 228 case EEP_TX_MASK: 229 return pBase->txMask; 230 case EEP_RX_MASK: 231 return pBase->rxMask; 232 case EEP_FRAC_N_5G: 233 return 0; 234 case EEP_PWR_TABLE_OFFSET: 235 return AR5416_PWR_TABLE_OFFSET_DB; 236 case EEP_MODAL_VER: 237 return pModal->version; 238 case EEP_ANT_DIV_CTL1: 239 return pModal->antdiv_ctl1; 240 case EEP_TXGAIN_TYPE: 241 if (ver_minor >= AR5416_EEP_MINOR_VER_19) 242 return pBase->txGainType; 243 else 244 return AR5416_EEP_TXGAIN_ORIGINAL; 245 default: 246 return 0; 247 } 248 } 249 250 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 251 struct ath9k_channel *chan, 252 int16_t *pTxPowerIndexOffset) 253 { 254 struct ath_common *common = ath9k_hw_common(ah); 255 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 256 struct cal_data_per_freq_4k *pRawDataset; 257 u8 *pCalBChans = NULL; 258 u16 pdGainOverlap_t2; 259 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 260 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 261 u16 numPiers, i, j; 262 u16 numXpdGain, xpdMask; 263 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; 264 u32 reg32, regOffset, regChainOffset; 265 266 xpdMask = pEepData->modalHeader.xpdGain; 267 268 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 269 AR5416_EEP_MINOR_VER_2) { 270 pdGainOverlap_t2 = 271 pEepData->modalHeader.pdGainOverlap; 272 } else { 273 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 274 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 275 } 276 277 pCalBChans = pEepData->calFreqPier2G; 278 numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS; 279 280 numXpdGain = 0; 281 282 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 283 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 284 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS) 285 break; 286 xpdGainValues[numXpdGain] = 287 (u16)(AR5416_PD_GAINS_IN_MASK - i); 288 numXpdGain++; 289 } 290 } 291 292 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 293 (numXpdGain - 1) & 0x3); 294 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 295 xpdGainValues[0]); 296 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 297 xpdGainValues[1]); 298 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); 299 300 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 301 if (AR_SREV_5416_20_OR_LATER(ah) && 302 (ah->rxchainmask == 5 || ah->txchainmask == 5) && 303 (i != 0)) { 304 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 305 } else 306 regChainOffset = i * 0x1000; 307 308 if (pEepData->baseEepHeader.txMask & (1 << i)) { 309 pRawDataset = pEepData->calPierData2G[i]; 310 311 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan, 312 pRawDataset, pCalBChans, 313 numPiers, pdGainOverlap_t2, 314 gainBoundaries, 315 pdadcValues, numXpdGain); 316 317 ENABLE_REGWRITE_BUFFER(ah); 318 319 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 320 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 321 SM(pdGainOverlap_t2, 322 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) 323 | SM(gainBoundaries[0], 324 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) 325 | SM(gainBoundaries[1], 326 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) 327 | SM(gainBoundaries[2], 328 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) 329 | SM(gainBoundaries[3], 330 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 331 } 332 333 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 334 for (j = 0; j < 32; j++) { 335 reg32 = get_unaligned_le32(&pdadcValues[4 * j]); 336 REG_WRITE(ah, regOffset, reg32); 337 338 ath_dbg(common, ATH_DBG_EEPROM, 339 "PDADC (%d,%4x): %4.4x %8.8x\n", 340 i, regChainOffset, regOffset, 341 reg32); 342 ath_dbg(common, ATH_DBG_EEPROM, 343 "PDADC: Chain %d | " 344 "PDADC %3d Value %3d | " 345 "PDADC %3d Value %3d | " 346 "PDADC %3d Value %3d | " 347 "PDADC %3d Value %3d |\n", 348 i, 4 * j, pdadcValues[4 * j], 349 4 * j + 1, pdadcValues[4 * j + 1], 350 4 * j + 2, pdadcValues[4 * j + 2], 351 4 * j + 3, pdadcValues[4 * j + 3]); 352 353 regOffset += 4; 354 } 355 356 REGWRITE_BUFFER_FLUSH(ah); 357 } 358 } 359 360 *pTxPowerIndexOffset = 0; 361 } 362 363 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 364 struct ath9k_channel *chan, 365 int16_t *ratesArray, 366 u16 cfgCtl, 367 u16 AntennaReduction, 368 u16 twiceMaxRegulatoryPower, 369 u16 powerLimit) 370 { 371 #define CMP_TEST_GRP \ 372 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 373 pEepData->ctlIndex[i]) \ 374 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 375 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) 376 377 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 378 int i; 379 int16_t twiceLargestAntenna; 380 u16 twiceMinEdgePower; 381 u16 twiceMaxEdgePower = MAX_RATE_POWER; 382 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 383 u16 numCtlModes; 384 const u16 *pCtlMode; 385 u16 ctlMode, freq; 386 struct chan_centers centers; 387 struct cal_ctl_data_4k *rep; 388 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 389 static const u16 tpScaleReductionTable[5] = 390 { 0, 3, 6, 9, MAX_RATE_POWER }; 391 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 392 0, { 0, 0, 0, 0} 393 }; 394 struct cal_target_power_leg targetPowerOfdmExt = { 395 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 396 0, { 0, 0, 0, 0 } 397 }; 398 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 399 0, {0, 0, 0, 0} 400 }; 401 static const u16 ctlModesFor11g[] = { 402 CTL_11B, CTL_11G, CTL_2GHT20, 403 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 404 }; 405 406 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 407 408 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; 409 twiceLargestAntenna = (int16_t)min(AntennaReduction - 410 twiceLargestAntenna, 0); 411 412 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 413 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { 414 maxRegAllowedPower -= 415 (tpScaleReductionTable[(regulatory->tp_scale)] * 2); 416 } 417 418 scaledPower = min(powerLimit, maxRegAllowedPower); 419 scaledPower = max((u16)0, scaledPower); 420 421 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 422 pCtlMode = ctlModesFor11g; 423 424 ath9k_hw_get_legacy_target_powers(ah, chan, 425 pEepData->calTargetPowerCck, 426 AR5416_NUM_2G_CCK_TARGET_POWERS, 427 &targetPowerCck, 4, false); 428 ath9k_hw_get_legacy_target_powers(ah, chan, 429 pEepData->calTargetPower2G, 430 AR5416_NUM_2G_20_TARGET_POWERS, 431 &targetPowerOfdm, 4, false); 432 ath9k_hw_get_target_powers(ah, chan, 433 pEepData->calTargetPower2GHT20, 434 AR5416_NUM_2G_20_TARGET_POWERS, 435 &targetPowerHt20, 8, false); 436 437 if (IS_CHAN_HT40(chan)) { 438 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 439 ath9k_hw_get_target_powers(ah, chan, 440 pEepData->calTargetPower2GHT40, 441 AR5416_NUM_2G_40_TARGET_POWERS, 442 &targetPowerHt40, 8, true); 443 ath9k_hw_get_legacy_target_powers(ah, chan, 444 pEepData->calTargetPowerCck, 445 AR5416_NUM_2G_CCK_TARGET_POWERS, 446 &targetPowerCckExt, 4, true); 447 ath9k_hw_get_legacy_target_powers(ah, chan, 448 pEepData->calTargetPower2G, 449 AR5416_NUM_2G_20_TARGET_POWERS, 450 &targetPowerOfdmExt, 4, true); 451 } 452 453 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 454 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 455 (pCtlMode[ctlMode] == CTL_2GHT40); 456 457 if (isHt40CtlMode) 458 freq = centers.synth_center; 459 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 460 freq = centers.ext_center; 461 else 462 freq = centers.ctl_center; 463 464 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 465 ah->eep_ops->get_eeprom_rev(ah) <= 2) 466 twiceMaxEdgePower = MAX_RATE_POWER; 467 468 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && 469 pEepData->ctlIndex[i]; i++) { 470 471 if (CMP_TEST_GRP) { 472 rep = &(pEepData->ctlData[i]); 473 474 twiceMinEdgePower = ath9k_hw_get_max_edge_power( 475 freq, 476 rep->ctlEdges[ 477 ar5416_get_ntxchains(ah->txchainmask) - 1], 478 IS_CHAN_2GHZ(chan), 479 AR5416_EEP4K_NUM_BAND_EDGES); 480 481 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 482 twiceMaxEdgePower = 483 min(twiceMaxEdgePower, 484 twiceMinEdgePower); 485 } else { 486 twiceMaxEdgePower = twiceMinEdgePower; 487 break; 488 } 489 } 490 } 491 492 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 493 494 switch (pCtlMode[ctlMode]) { 495 case CTL_11B: 496 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { 497 targetPowerCck.tPow2x[i] = 498 min((u16)targetPowerCck.tPow2x[i], 499 minCtlPower); 500 } 501 break; 502 case CTL_11G: 503 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { 504 targetPowerOfdm.tPow2x[i] = 505 min((u16)targetPowerOfdm.tPow2x[i], 506 minCtlPower); 507 } 508 break; 509 case CTL_2GHT20: 510 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { 511 targetPowerHt20.tPow2x[i] = 512 min((u16)targetPowerHt20.tPow2x[i], 513 minCtlPower); 514 } 515 break; 516 case CTL_11B_EXT: 517 targetPowerCckExt.tPow2x[0] = 518 min((u16)targetPowerCckExt.tPow2x[0], 519 minCtlPower); 520 break; 521 case CTL_11G_EXT: 522 targetPowerOfdmExt.tPow2x[0] = 523 min((u16)targetPowerOfdmExt.tPow2x[0], 524 minCtlPower); 525 break; 526 case CTL_2GHT40: 527 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 528 targetPowerHt40.tPow2x[i] = 529 min((u16)targetPowerHt40.tPow2x[i], 530 minCtlPower); 531 } 532 break; 533 default: 534 break; 535 } 536 } 537 538 ratesArray[rate6mb] = 539 ratesArray[rate9mb] = 540 ratesArray[rate12mb] = 541 ratesArray[rate18mb] = 542 ratesArray[rate24mb] = 543 targetPowerOfdm.tPow2x[0]; 544 545 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 546 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 547 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 548 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 549 550 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 551 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 552 553 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 554 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 555 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 556 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 557 558 if (IS_CHAN_HT40(chan)) { 559 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 560 ratesArray[rateHt40_0 + i] = 561 targetPowerHt40.tPow2x[i]; 562 } 563 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 564 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 565 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 566 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 567 } 568 569 #undef CMP_TEST_GRP 570 } 571 572 static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, 573 struct ath9k_channel *chan, 574 u16 cfgCtl, 575 u8 twiceAntennaReduction, 576 u8 twiceMaxRegulatoryPower, 577 u8 powerLimit, bool test) 578 { 579 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 580 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 581 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 582 int16_t ratesArray[Ar5416RateSize]; 583 int16_t txPowerIndexOffset = 0; 584 u8 ht40PowerIncForPdadc = 2; 585 int i; 586 587 memset(ratesArray, 0, sizeof(ratesArray)); 588 589 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 590 AR5416_EEP_MINOR_VER_2) { 591 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 592 } 593 594 ath9k_hw_set_4k_power_per_rate_table(ah, chan, 595 &ratesArray[0], cfgCtl, 596 twiceAntennaReduction, 597 twiceMaxRegulatoryPower, 598 powerLimit); 599 600 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset); 601 602 regulatory->max_power_level = 0; 603 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 604 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 605 if (ratesArray[i] > MAX_RATE_POWER) 606 ratesArray[i] = MAX_RATE_POWER; 607 608 if (ratesArray[i] > regulatory->max_power_level) 609 regulatory->max_power_level = ratesArray[i]; 610 } 611 612 if (test) 613 return; 614 615 /* Update regulatory */ 616 i = rate6mb; 617 if (IS_CHAN_HT40(chan)) 618 i = rateHt40_0; 619 else if (IS_CHAN_HT20(chan)) 620 i = rateHt20_0; 621 622 regulatory->max_power_level = ratesArray[i]; 623 624 if (AR_SREV_9280_20_OR_LATER(ah)) { 625 for (i = 0; i < Ar5416RateSize; i++) 626 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; 627 } 628 629 ENABLE_REGWRITE_BUFFER(ah); 630 631 /* OFDM power per rate */ 632 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 633 ATH9K_POW_SM(ratesArray[rate18mb], 24) 634 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 635 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 636 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 637 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 638 ATH9K_POW_SM(ratesArray[rate54mb], 24) 639 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 640 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 641 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 642 643 /* CCK power per rate */ 644 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 645 ATH9K_POW_SM(ratesArray[rate2s], 24) 646 | ATH9K_POW_SM(ratesArray[rate2l], 16) 647 | ATH9K_POW_SM(ratesArray[rateXr], 8) 648 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 649 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 650 ATH9K_POW_SM(ratesArray[rate11s], 24) 651 | ATH9K_POW_SM(ratesArray[rate11l], 16) 652 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 653 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 654 655 /* HT20 power per rate */ 656 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 657 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 658 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 659 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 660 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 661 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 662 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 663 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 664 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 665 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 666 667 /* HT40 power per rate */ 668 if (IS_CHAN_HT40(chan)) { 669 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 670 ATH9K_POW_SM(ratesArray[rateHt40_3] + 671 ht40PowerIncForPdadc, 24) 672 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 673 ht40PowerIncForPdadc, 16) 674 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 675 ht40PowerIncForPdadc, 8) 676 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 677 ht40PowerIncForPdadc, 0)); 678 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 679 ATH9K_POW_SM(ratesArray[rateHt40_7] + 680 ht40PowerIncForPdadc, 24) 681 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 682 ht40PowerIncForPdadc, 16) 683 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 684 ht40PowerIncForPdadc, 8) 685 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 686 ht40PowerIncForPdadc, 0)); 687 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 688 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 689 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 690 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 691 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 692 } 693 694 REGWRITE_BUFFER_FLUSH(ah); 695 } 696 697 static void ath9k_hw_4k_set_addac(struct ath_hw *ah, 698 struct ath9k_channel *chan) 699 { 700 struct modal_eep_4k_header *pModal; 701 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 702 u8 biaslevel; 703 704 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 705 return; 706 707 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) 708 return; 709 710 pModal = &eep->modalHeader; 711 712 if (pModal->xpaBiasLvl != 0xff) { 713 biaslevel = pModal->xpaBiasLvl; 714 INI_RA(&ah->iniAddac, 7, 1) = 715 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; 716 } 717 } 718 719 static void ath9k_hw_4k_set_gain(struct ath_hw *ah, 720 struct modal_eep_4k_header *pModal, 721 struct ar5416_eeprom_4k *eep, 722 u8 txRxAttenLocal) 723 { 724 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0, 725 pModal->antCtrlChain[0]); 726 727 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), 728 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & 729 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 730 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 731 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 732 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 733 734 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 735 AR5416_EEP_MINOR_VER_3) { 736 txRxAttenLocal = pModal->txRxAttenCh[0]; 737 738 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 739 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); 740 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 741 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 742 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 743 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 744 pModal->xatten2Margin[0]); 745 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 746 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 747 748 /* Set the block 1 value to block 0 value */ 749 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 750 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 751 pModal->bswMargin[0]); 752 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 753 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 754 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 755 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 756 pModal->xatten2Margin[0]); 757 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 758 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 759 pModal->xatten2Db[0]); 760 } 761 762 REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 763 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 764 REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 765 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 766 767 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 768 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 769 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 770 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 771 } 772 773 /* 774 * Read EEPROM header info and program the device for correct operation 775 * given the channel value. 776 */ 777 static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 778 struct ath9k_channel *chan) 779 { 780 struct modal_eep_4k_header *pModal; 781 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 782 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 783 u8 txRxAttenLocal; 784 u8 ob[5], db1[5], db2[5]; 785 u8 ant_div_control1, ant_div_control2; 786 u32 regVal; 787 788 pModal = &eep->modalHeader; 789 txRxAttenLocal = 23; 790 791 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 792 793 /* Single chain for 4K EEPROM*/ 794 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal); 795 796 /* Initialize Ant Diversity settings from EEPROM */ 797 if (pModal->version >= 3) { 798 ant_div_control1 = pModal->antdiv_ctl1; 799 ant_div_control2 = pModal->antdiv_ctl2; 800 801 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 802 regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL)); 803 804 regVal |= SM(ant_div_control1, 805 AR_PHY_9285_ANT_DIV_CTL); 806 regVal |= SM(ant_div_control2, 807 AR_PHY_9285_ANT_DIV_ALT_LNACONF); 808 regVal |= SM((ant_div_control2 >> 2), 809 AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 810 regVal |= SM((ant_div_control1 >> 1), 811 AR_PHY_9285_ANT_DIV_ALT_GAINTB); 812 regVal |= SM((ant_div_control1 >> 2), 813 AR_PHY_9285_ANT_DIV_MAIN_GAINTB); 814 815 816 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal); 817 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 818 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 819 regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 820 regVal |= SM((ant_div_control1 >> 3), 821 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 822 823 REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal); 824 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 825 } 826 827 if (pModal->version >= 2) { 828 ob[0] = pModal->ob_0; 829 ob[1] = pModal->ob_1; 830 ob[2] = pModal->ob_2; 831 ob[3] = pModal->ob_3; 832 ob[4] = pModal->ob_4; 833 834 db1[0] = pModal->db1_0; 835 db1[1] = pModal->db1_1; 836 db1[2] = pModal->db1_2; 837 db1[3] = pModal->db1_3; 838 db1[4] = pModal->db1_4; 839 840 db2[0] = pModal->db2_0; 841 db2[1] = pModal->db2_1; 842 db2[2] = pModal->db2_2; 843 db2[3] = pModal->db2_3; 844 db2[4] = pModal->db2_4; 845 } else if (pModal->version == 1) { 846 ob[0] = pModal->ob_0; 847 ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1; 848 db1[0] = pModal->db1_0; 849 db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1; 850 db2[0] = pModal->db2_0; 851 db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1; 852 } else { 853 int i; 854 855 for (i = 0; i < 5; i++) { 856 ob[i] = pModal->ob_0; 857 db1[i] = pModal->db1_0; 858 db2[i] = pModal->db1_0; 859 } 860 } 861 862 if (AR_SREV_9271(ah)) { 863 ath9k_hw_analog_shift_rmw(ah, 864 AR9285_AN_RF2G3, 865 AR9271_AN_RF2G3_OB_cck, 866 AR9271_AN_RF2G3_OB_cck_S, 867 ob[0]); 868 ath9k_hw_analog_shift_rmw(ah, 869 AR9285_AN_RF2G3, 870 AR9271_AN_RF2G3_OB_psk, 871 AR9271_AN_RF2G3_OB_psk_S, 872 ob[1]); 873 ath9k_hw_analog_shift_rmw(ah, 874 AR9285_AN_RF2G3, 875 AR9271_AN_RF2G3_OB_qam, 876 AR9271_AN_RF2G3_OB_qam_S, 877 ob[2]); 878 ath9k_hw_analog_shift_rmw(ah, 879 AR9285_AN_RF2G3, 880 AR9271_AN_RF2G3_DB_1, 881 AR9271_AN_RF2G3_DB_1_S, 882 db1[0]); 883 ath9k_hw_analog_shift_rmw(ah, 884 AR9285_AN_RF2G4, 885 AR9271_AN_RF2G4_DB_2, 886 AR9271_AN_RF2G4_DB_2_S, 887 db2[0]); 888 } else { 889 ath9k_hw_analog_shift_rmw(ah, 890 AR9285_AN_RF2G3, 891 AR9285_AN_RF2G3_OB_0, 892 AR9285_AN_RF2G3_OB_0_S, 893 ob[0]); 894 ath9k_hw_analog_shift_rmw(ah, 895 AR9285_AN_RF2G3, 896 AR9285_AN_RF2G3_OB_1, 897 AR9285_AN_RF2G3_OB_1_S, 898 ob[1]); 899 ath9k_hw_analog_shift_rmw(ah, 900 AR9285_AN_RF2G3, 901 AR9285_AN_RF2G3_OB_2, 902 AR9285_AN_RF2G3_OB_2_S, 903 ob[2]); 904 ath9k_hw_analog_shift_rmw(ah, 905 AR9285_AN_RF2G3, 906 AR9285_AN_RF2G3_OB_3, 907 AR9285_AN_RF2G3_OB_3_S, 908 ob[3]); 909 ath9k_hw_analog_shift_rmw(ah, 910 AR9285_AN_RF2G3, 911 AR9285_AN_RF2G3_OB_4, 912 AR9285_AN_RF2G3_OB_4_S, 913 ob[4]); 914 915 ath9k_hw_analog_shift_rmw(ah, 916 AR9285_AN_RF2G3, 917 AR9285_AN_RF2G3_DB1_0, 918 AR9285_AN_RF2G3_DB1_0_S, 919 db1[0]); 920 ath9k_hw_analog_shift_rmw(ah, 921 AR9285_AN_RF2G3, 922 AR9285_AN_RF2G3_DB1_1, 923 AR9285_AN_RF2G3_DB1_1_S, 924 db1[1]); 925 ath9k_hw_analog_shift_rmw(ah, 926 AR9285_AN_RF2G3, 927 AR9285_AN_RF2G3_DB1_2, 928 AR9285_AN_RF2G3_DB1_2_S, 929 db1[2]); 930 ath9k_hw_analog_shift_rmw(ah, 931 AR9285_AN_RF2G4, 932 AR9285_AN_RF2G4_DB1_3, 933 AR9285_AN_RF2G4_DB1_3_S, 934 db1[3]); 935 ath9k_hw_analog_shift_rmw(ah, 936 AR9285_AN_RF2G4, 937 AR9285_AN_RF2G4_DB1_4, 938 AR9285_AN_RF2G4_DB1_4_S, db1[4]); 939 940 ath9k_hw_analog_shift_rmw(ah, 941 AR9285_AN_RF2G4, 942 AR9285_AN_RF2G4_DB2_0, 943 AR9285_AN_RF2G4_DB2_0_S, 944 db2[0]); 945 ath9k_hw_analog_shift_rmw(ah, 946 AR9285_AN_RF2G4, 947 AR9285_AN_RF2G4_DB2_1, 948 AR9285_AN_RF2G4_DB2_1_S, 949 db2[1]); 950 ath9k_hw_analog_shift_rmw(ah, 951 AR9285_AN_RF2G4, 952 AR9285_AN_RF2G4_DB2_2, 953 AR9285_AN_RF2G4_DB2_2_S, 954 db2[2]); 955 ath9k_hw_analog_shift_rmw(ah, 956 AR9285_AN_RF2G4, 957 AR9285_AN_RF2G4_DB2_3, 958 AR9285_AN_RF2G4_DB2_3_S, 959 db2[3]); 960 ath9k_hw_analog_shift_rmw(ah, 961 AR9285_AN_RF2G4, 962 AR9285_AN_RF2G4_DB2_4, 963 AR9285_AN_RF2G4_DB2_4_S, 964 db2[4]); 965 } 966 967 968 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 969 pModal->switchSettling); 970 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 971 pModal->adcDesiredSize); 972 973 REG_WRITE(ah, AR_PHY_RF_CTL4, 974 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 975 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 976 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 977 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 978 979 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 980 pModal->txEndToRxOn); 981 982 if (AR_SREV_9271_10(ah)) 983 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 984 pModal->txEndToRxOn); 985 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 986 pModal->thresh62); 987 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 988 pModal->thresh62); 989 990 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 991 AR5416_EEP_MINOR_VER_2) { 992 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, 993 pModal->txFrameToDataStart); 994 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 995 pModal->txFrameToPaOn); 996 } 997 998 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 999 AR5416_EEP_MINOR_VER_3) { 1000 if (IS_CHAN_HT40(chan)) 1001 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1002 AR_PHY_SETTLING_SWITCH, 1003 pModal->swSettleHt40); 1004 } 1005 if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { 1006 u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & 1007 EEP_4K_BB_DESIRED_SCALE_MASK); 1008 if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { 1009 u32 pwrctrl, mask, clr; 1010 1011 mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); 1012 pwrctrl = mask * bb_desired_scale; 1013 clr = mask * 0x1f; 1014 REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); 1015 REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); 1016 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); 1017 1018 mask = BIT(0)|BIT(5)|BIT(15); 1019 pwrctrl = mask * bb_desired_scale; 1020 clr = mask * 0x1f; 1021 REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); 1022 1023 mask = BIT(0)|BIT(5); 1024 pwrctrl = mask * bb_desired_scale; 1025 clr = mask * 0x1f; 1026 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); 1027 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); 1028 } 1029 } 1030 } 1031 1032 static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1033 { 1034 #define EEP_MAP4K_SPURCHAN \ 1035 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan) 1036 struct ath_common *common = ath9k_hw_common(ah); 1037 1038 u16 spur_val = AR_NO_SPUR; 1039 1040 ath_dbg(common, ATH_DBG_ANI, 1041 "Getting spur idx:%d is2Ghz:%d val:%x\n", 1042 i, is2GHz, ah->config.spurchans[i][is2GHz]); 1043 1044 switch (ah->config.spurmode) { 1045 case SPUR_DISABLE: 1046 break; 1047 case SPUR_ENABLE_IOCTL: 1048 spur_val = ah->config.spurchans[i][is2GHz]; 1049 ath_dbg(common, ATH_DBG_ANI, 1050 "Getting spur val from new loc. %d\n", spur_val); 1051 break; 1052 case SPUR_ENABLE_EEPROM: 1053 spur_val = EEP_MAP4K_SPURCHAN; 1054 break; 1055 } 1056 1057 return spur_val; 1058 1059 #undef EEP_MAP4K_SPURCHAN 1060 } 1061 1062 const struct eeprom_ops eep_4k_ops = { 1063 .check_eeprom = ath9k_hw_4k_check_eeprom, 1064 .get_eeprom = ath9k_hw_4k_get_eeprom, 1065 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1066 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1067 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1068 .set_board_values = ath9k_hw_4k_set_board_values, 1069 .set_addac = ath9k_hw_4k_set_addac, 1070 .set_txpower = ath9k_hw_4k_set_txpower, 1071 .get_spur_channel = ath9k_hw_4k_get_spur_channel 1072 }; 1073