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