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 <linux/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", le32_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 scaledPower = min_t(u16, scaledPower, MAX_RATE_POWER); 428 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 429 pCtlMode = ctlModesFor11g; 430 431 ath9k_hw_get_legacy_target_powers(ah, chan, 432 pEepData->calTargetPowerCck, 433 AR5416_NUM_2G_CCK_TARGET_POWERS, 434 &targetPowerCck, 4, false); 435 ath9k_hw_get_legacy_target_powers(ah, chan, 436 pEepData->calTargetPower2G, 437 AR5416_NUM_2G_20_TARGET_POWERS, 438 &targetPowerOfdm, 4, false); 439 ath9k_hw_get_target_powers(ah, chan, 440 pEepData->calTargetPower2GHT20, 441 AR5416_NUM_2G_20_TARGET_POWERS, 442 &targetPowerHt20, 8, false); 443 444 if (IS_CHAN_HT40(chan)) { 445 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 446 ath9k_hw_get_target_powers(ah, chan, 447 pEepData->calTargetPower2GHT40, 448 AR5416_NUM_2G_40_TARGET_POWERS, 449 &targetPowerHt40, 8, true); 450 ath9k_hw_get_legacy_target_powers(ah, chan, 451 pEepData->calTargetPowerCck, 452 AR5416_NUM_2G_CCK_TARGET_POWERS, 453 &targetPowerCckExt, 4, true); 454 ath9k_hw_get_legacy_target_powers(ah, chan, 455 pEepData->calTargetPower2G, 456 AR5416_NUM_2G_20_TARGET_POWERS, 457 &targetPowerOfdmExt, 4, true); 458 } 459 460 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 461 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 462 (pCtlMode[ctlMode] == CTL_2GHT40); 463 464 if (isHt40CtlMode) 465 freq = centers.synth_center; 466 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 467 freq = centers.ext_center; 468 else 469 freq = centers.ctl_center; 470 471 twiceMaxEdgePower = MAX_RATE_POWER; 472 473 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && 474 pEepData->ctlIndex[i]; i++) { 475 476 if (CMP_TEST_GRP) { 477 rep = &(pEepData->ctlData[i]); 478 479 twiceMinEdgePower = ath9k_hw_get_max_edge_power( 480 freq, 481 rep->ctlEdges[ 482 ar5416_get_ntxchains(ah->txchainmask) - 1], 483 IS_CHAN_2GHZ(chan), 484 AR5416_EEP4K_NUM_BAND_EDGES); 485 486 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 487 twiceMaxEdgePower = 488 min(twiceMaxEdgePower, 489 twiceMinEdgePower); 490 } else { 491 twiceMaxEdgePower = twiceMinEdgePower; 492 break; 493 } 494 } 495 } 496 497 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 498 499 switch (pCtlMode[ctlMode]) { 500 case CTL_11B: 501 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { 502 targetPowerCck.tPow2x[i] = 503 min((u16)targetPowerCck.tPow2x[i], 504 minCtlPower); 505 } 506 break; 507 case CTL_11G: 508 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { 509 targetPowerOfdm.tPow2x[i] = 510 min((u16)targetPowerOfdm.tPow2x[i], 511 minCtlPower); 512 } 513 break; 514 case CTL_2GHT20: 515 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { 516 targetPowerHt20.tPow2x[i] = 517 min((u16)targetPowerHt20.tPow2x[i], 518 minCtlPower); 519 } 520 break; 521 case CTL_11B_EXT: 522 targetPowerCckExt.tPow2x[0] = 523 min((u16)targetPowerCckExt.tPow2x[0], 524 minCtlPower); 525 break; 526 case CTL_11G_EXT: 527 targetPowerOfdmExt.tPow2x[0] = 528 min((u16)targetPowerOfdmExt.tPow2x[0], 529 minCtlPower); 530 break; 531 case CTL_2GHT40: 532 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 533 targetPowerHt40.tPow2x[i] = 534 min((u16)targetPowerHt40.tPow2x[i], 535 minCtlPower); 536 } 537 break; 538 default: 539 break; 540 } 541 } 542 543 ratesArray[rate6mb] = 544 ratesArray[rate9mb] = 545 ratesArray[rate12mb] = 546 ratesArray[rate18mb] = 547 ratesArray[rate24mb] = 548 targetPowerOfdm.tPow2x[0]; 549 550 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 551 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 552 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 553 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 554 555 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 556 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 557 558 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 559 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 560 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 561 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 562 563 if (IS_CHAN_HT40(chan)) { 564 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 565 ratesArray[rateHt40_0 + i] = 566 targetPowerHt40.tPow2x[i]; 567 } 568 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 569 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 570 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 571 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 572 } 573 574 #undef CMP_TEST_GRP 575 } 576 577 static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, 578 struct ath9k_channel *chan, 579 u16 cfgCtl, 580 u8 twiceAntennaReduction, 581 u8 powerLimit, bool test) 582 { 583 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 584 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 585 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 586 int16_t ratesArray[Ar5416RateSize]; 587 u8 ht40PowerIncForPdadc = 2; 588 int i; 589 590 memset(ratesArray, 0, sizeof(ratesArray)); 591 592 if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) 593 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 594 595 ath9k_hw_set_4k_power_per_rate_table(ah, chan, 596 &ratesArray[0], cfgCtl, 597 twiceAntennaReduction, 598 powerLimit); 599 600 ath9k_hw_set_4k_power_cal_table(ah, chan); 601 602 regulatory->max_power_level = 0; 603 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 604 if (ratesArray[i] > MAX_RATE_POWER) 605 ratesArray[i] = MAX_RATE_POWER; 606 607 if (ratesArray[i] > regulatory->max_power_level) 608 regulatory->max_power_level = ratesArray[i]; 609 } 610 611 if (test) 612 return; 613 614 for (i = 0; i < Ar5416RateSize; i++) 615 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; 616 617 ENABLE_REGWRITE_BUFFER(ah); 618 619 /* OFDM power per rate */ 620 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 621 ATH9K_POW_SM(ratesArray[rate18mb], 24) 622 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 623 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 624 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 625 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 626 ATH9K_POW_SM(ratesArray[rate54mb], 24) 627 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 628 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 629 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 630 631 /* CCK power per rate */ 632 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 633 ATH9K_POW_SM(ratesArray[rate2s], 24) 634 | ATH9K_POW_SM(ratesArray[rate2l], 16) 635 | ATH9K_POW_SM(ratesArray[rateXr], 8) 636 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 637 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 638 ATH9K_POW_SM(ratesArray[rate11s], 24) 639 | ATH9K_POW_SM(ratesArray[rate11l], 16) 640 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 641 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 642 643 /* HT20 power per rate */ 644 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 645 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 646 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 647 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 648 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 649 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 650 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 651 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 652 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 653 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 654 655 /* HT40 power per rate */ 656 if (IS_CHAN_HT40(chan)) { 657 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 658 ATH9K_POW_SM(ratesArray[rateHt40_3] + 659 ht40PowerIncForPdadc, 24) 660 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 661 ht40PowerIncForPdadc, 16) 662 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 663 ht40PowerIncForPdadc, 8) 664 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 665 ht40PowerIncForPdadc, 0)); 666 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 667 ATH9K_POW_SM(ratesArray[rateHt40_7] + 668 ht40PowerIncForPdadc, 24) 669 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 670 ht40PowerIncForPdadc, 16) 671 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 672 ht40PowerIncForPdadc, 8) 673 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 674 ht40PowerIncForPdadc, 0)); 675 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 676 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 677 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 678 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 679 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 680 } 681 682 /* TPC initializations */ 683 if (ah->tpc_enabled) { 684 int ht40_delta; 685 686 ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0; 687 ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta); 688 /* Enable TPC */ 689 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, 690 MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE); 691 } else { 692 /* Disable TPC */ 693 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER); 694 } 695 696 REGWRITE_BUFFER_FLUSH(ah); 697 } 698 699 static void ath9k_hw_4k_set_gain(struct ath_hw *ah, 700 struct modal_eep_4k_header *pModal, 701 struct ar5416_eeprom_4k *eep, 702 u8 txRxAttenLocal) 703 { 704 ENABLE_REG_RMW_BUFFER(ah); 705 REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 706 le32_to_cpu(pModal->antCtrlChain[0]), 0); 707 708 REG_RMW(ah, AR_PHY_TIMING_CTRL4(0), 709 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 710 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 711 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF); 712 713 if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) { 714 txRxAttenLocal = pModal->txRxAttenCh[0]; 715 716 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 717 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); 718 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 719 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 720 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 721 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 722 pModal->xatten2Margin[0]); 723 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 724 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 725 726 /* Set the block 1 value to block 0 value */ 727 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 728 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 729 pModal->bswMargin[0]); 730 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 731 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 732 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 733 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 734 pModal->xatten2Margin[0]); 735 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 736 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 737 pModal->xatten2Db[0]); 738 } 739 740 REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 741 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 742 REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 743 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 744 745 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 746 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 747 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 748 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 749 REG_RMW_BUFFER_FLUSH(ah); 750 } 751 752 /* 753 * Read EEPROM header info and program the device for correct operation 754 * given the channel value. 755 */ 756 static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 757 struct ath9k_channel *chan) 758 { 759 struct ath9k_hw_capabilities *pCap = &ah->caps; 760 struct modal_eep_4k_header *pModal; 761 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 762 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 763 u8 txRxAttenLocal; 764 u8 ob[5], db1[5], db2[5]; 765 u8 ant_div_control1, ant_div_control2; 766 u8 bb_desired_scale; 767 u32 regVal; 768 769 pModal = &eep->modalHeader; 770 txRxAttenLocal = 23; 771 772 REG_WRITE(ah, AR_PHY_SWITCH_COM, le32_to_cpu(pModal->antCtrlCommon)); 773 774 /* Single chain for 4K EEPROM*/ 775 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal); 776 777 /* Initialize Ant Diversity settings from EEPROM */ 778 if (pModal->version >= 3) { 779 ant_div_control1 = pModal->antdiv_ctl1; 780 ant_div_control2 = pModal->antdiv_ctl2; 781 782 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 783 regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL)); 784 785 regVal |= SM(ant_div_control1, 786 AR_PHY_9285_ANT_DIV_CTL); 787 regVal |= SM(ant_div_control2, 788 AR_PHY_9285_ANT_DIV_ALT_LNACONF); 789 regVal |= SM((ant_div_control2 >> 2), 790 AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 791 regVal |= SM((ant_div_control1 >> 1), 792 AR_PHY_9285_ANT_DIV_ALT_GAINTB); 793 regVal |= SM((ant_div_control1 >> 2), 794 AR_PHY_9285_ANT_DIV_MAIN_GAINTB); 795 796 797 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal); 798 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 799 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 800 regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 801 regVal |= SM((ant_div_control1 >> 3), 802 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 803 804 REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal); 805 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 806 807 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) { 808 /* 809 * If diversity combining is enabled, 810 * set MAIN to LNA1 and ALT to LNA2 initially. 811 */ 812 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 813 regVal &= (~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF | 814 AR_PHY_9285_ANT_DIV_ALT_LNACONF)); 815 816 regVal |= (ATH_ANT_DIV_COMB_LNA1 << 817 AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S); 818 regVal |= (ATH_ANT_DIV_COMB_LNA2 << 819 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S); 820 regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS)); 821 regVal |= (0 << AR_PHY_9285_FAST_DIV_BIAS_S); 822 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal); 823 } 824 } 825 826 if (pModal->version >= 2) { 827 ob[0] = pModal->ob_0; 828 ob[1] = pModal->ob_1; 829 ob[2] = pModal->ob_2; 830 ob[3] = pModal->ob_3; 831 ob[4] = pModal->ob_4; 832 833 db1[0] = pModal->db1_0; 834 db1[1] = pModal->db1_1; 835 db1[2] = pModal->db1_2; 836 db1[3] = pModal->db1_3; 837 db1[4] = pModal->db1_4; 838 839 db2[0] = pModal->db2_0; 840 db2[1] = pModal->db2_1; 841 db2[2] = pModal->db2_2; 842 db2[3] = pModal->db2_3; 843 db2[4] = pModal->db2_4; 844 } else if (pModal->version == 1) { 845 ob[0] = pModal->ob_0; 846 ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1; 847 db1[0] = pModal->db1_0; 848 db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1; 849 db2[0] = pModal->db2_0; 850 db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1; 851 } else { 852 int i; 853 854 for (i = 0; i < 5; i++) { 855 ob[i] = pModal->ob_0; 856 db1[i] = pModal->db1_0; 857 db2[i] = pModal->db1_0; 858 } 859 } 860 861 ENABLE_REG_RMW_BUFFER(ah); 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 REG_RMW_BUFFER_FLUSH(ah); 967 968 ENABLE_REG_RMW_BUFFER(ah); 969 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 970 pModal->switchSettling); 971 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 972 pModal->adcDesiredSize); 973 974 REG_RMW(ah, AR_PHY_RF_CTL4, 975 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 976 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 977 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 978 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON), 0); 979 980 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 981 pModal->txEndToRxOn); 982 983 if (AR_SREV_9271_10(ah)) 984 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 985 pModal->txEndToRxOn); 986 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 987 pModal->thresh62); 988 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 989 pModal->thresh62); 990 991 if (ath9k_hw_4k_get_eeprom_rev(ah) >= 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 (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) { 999 if (IS_CHAN_HT40(chan)) 1000 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1001 AR_PHY_SETTLING_SWITCH, 1002 pModal->swSettleHt40); 1003 } 1004 1005 REG_RMW_BUFFER_FLUSH(ah); 1006 1007 bb_desired_scale = (pModal->bb_scale_smrt_antenna & 1008 EEP_4K_BB_DESIRED_SCALE_MASK); 1009 if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { 1010 u32 pwrctrl, mask, clr; 1011 1012 mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); 1013 pwrctrl = mask * bb_desired_scale; 1014 clr = mask * 0x1f; 1015 ENABLE_REG_RMW_BUFFER(ah); 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 REG_RMW_BUFFER_FLUSH(ah); 1031 } 1032 } 1033 1034 static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1035 { 1036 return le16_to_cpu(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan); 1037 } 1038 1039 static u8 ath9k_hw_4k_get_eepmisc(struct ath_hw *ah) 1040 { 1041 return ah->eeprom.map4k.baseEepHeader.eepMisc; 1042 } 1043 1044 const struct eeprom_ops eep_4k_ops = { 1045 .check_eeprom = ath9k_hw_4k_check_eeprom, 1046 .get_eeprom = ath9k_hw_4k_get_eeprom, 1047 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1048 .dump_eeprom = ath9k_hw_4k_dump_eeprom, 1049 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1050 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1051 .set_board_values = ath9k_hw_4k_set_board_values, 1052 .set_txpower = ath9k_hw_4k_set_txpower, 1053 .get_spur_channel = ath9k_hw_4k_get_spur_channel, 1054 .get_eepmisc = ath9k_hw_4k_get_eepmisc 1055 }; 1056