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