0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <asm/unaligned.h>
0018 #include "hw.h"
0019 #include "ar9002_phy.h"
0020
0021 static void ath9k_get_txgain_index(struct ath_hw *ah,
0022 struct ath9k_channel *chan,
0023 struct calDataPerFreqOpLoop *rawDatasetOpLoop,
0024 u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx)
0025 {
0026 u8 pcdac, i = 0;
0027 u16 idxL = 0, idxR = 0, numPiers;
0028 bool match;
0029 struct chan_centers centers;
0030
0031 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
0032
0033 for (numPiers = 0; numPiers < availPiers; numPiers++)
0034 if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
0035 break;
0036
0037 match = ath9k_hw_get_lower_upper_index(
0038 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
0039 calChans, numPiers, &idxL, &idxR);
0040 if (match) {
0041 pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
0042 *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
0043 } else {
0044 pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
0045 *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
0046 rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
0047 }
0048
0049 while (pcdac > ah->originalGain[i] &&
0050 i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
0051 i++;
0052
0053 *pcdacIdx = i;
0054 }
0055
0056 static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
0057 u32 initTxGain,
0058 int txPower,
0059 u8 *pPDADCValues)
0060 {
0061 u32 i;
0062 u32 offset;
0063
0064 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
0065 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
0066 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
0067 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
0068
0069 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
0070 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
0071
0072 offset = txPower;
0073 for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
0074 if (i < offset)
0075 pPDADCValues[i] = 0x0;
0076 else
0077 pPDADCValues[i] = 0xFF;
0078 }
0079
0080 static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
0081 {
0082 u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version);
0083
0084 return (version & AR5416_EEP_VER_MAJOR_MASK) >>
0085 AR5416_EEP_VER_MAJOR_SHIFT;
0086 }
0087
0088 static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
0089 {
0090 u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version);
0091
0092 return version & AR5416_EEP_VER_MINOR_MASK;
0093 }
0094
0095 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
0096
0097 static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
0098 {
0099 u16 *eep_data = (u16 *)&ah->eeprom.def;
0100 int addr, ar5416_eep_start_loc = 0x100;
0101
0102 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
0103 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
0104 eep_data))
0105 return false;
0106 eep_data++;
0107 }
0108 return true;
0109 }
0110
0111 static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah)
0112 {
0113 u16 *eep_data = (u16 *)&ah->eeprom.def;
0114
0115 ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
0116 0x100, SIZE_EEPROM_DEF);
0117 return true;
0118 }
0119
0120 static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
0121 {
0122 struct ath_common *common = ath9k_hw_common(ah);
0123
0124 if (!ath9k_hw_use_flash(ah)) {
0125 ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
0126 }
0127
0128 if (common->bus_ops->ath_bus_type == ATH_USB)
0129 return __ath9k_hw_usb_def_fill_eeprom(ah);
0130 else
0131 return __ath9k_hw_def_fill_eeprom(ah);
0132 }
0133
0134 #ifdef CONFIG_ATH9K_COMMON_DEBUG
0135 static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
0136 struct modal_eep_header *modal_hdr)
0137 {
0138 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
0139 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
0140 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
0141 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
0142 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
0143 PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
0144 PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]);
0145 PR_EEP("Switch Settle", modal_hdr->switchSettling);
0146 PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
0147 PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);
0148 PR_EEP("Chain2 TxRxAtten", modal_hdr->txRxAttenCh[2]);
0149 PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
0150 PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);
0151 PR_EEP("Chain2 RxTxMargin", modal_hdr->rxTxMarginCh[2]);
0152 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
0153 PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
0154 PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
0155 PR_EEP("Chain1 xlna Gain", modal_hdr->xlnaGainCh[1]);
0156 PR_EEP("Chain2 xlna Gain", modal_hdr->xlnaGainCh[2]);
0157 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
0158 PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
0159 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
0160 PR_EEP("CCA Threshold)", modal_hdr->thresh62);
0161 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
0162 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
0163 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
0164 PR_EEP("xpdGain", modal_hdr->xpdGain);
0165 PR_EEP("External PD", modal_hdr->xpd);
0166 PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
0167 PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);
0168 PR_EEP("Chain2 I Coefficient", modal_hdr->iqCalICh[2]);
0169 PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
0170 PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);
0171 PR_EEP("Chain2 Q Coefficient", modal_hdr->iqCalQCh[2]);
0172 PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
0173 PR_EEP("Chain0 OutputBias", modal_hdr->ob);
0174 PR_EEP("Chain0 DriverBias", modal_hdr->db);
0175 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
0176 PR_EEP("2chain pwr decrease", modal_hdr->pwrDecreaseFor2Chain);
0177 PR_EEP("3chain pwr decrease", modal_hdr->pwrDecreaseFor3Chain);
0178 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
0179 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
0180 PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
0181 PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
0182 PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);
0183 PR_EEP("Chain2 bswAtten", modal_hdr->bswAtten[2]);
0184 PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
0185 PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);
0186 PR_EEP("Chain2 bswMargin", modal_hdr->bswMargin[2]);
0187 PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
0188 PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
0189 PR_EEP("Chain1 xatten2Db", modal_hdr->xatten2Db[1]);
0190 PR_EEP("Chain2 xatten2Db", modal_hdr->xatten2Db[2]);
0191 PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
0192 PR_EEP("Chain1 xatten2Margin", modal_hdr->xatten2Margin[1]);
0193 PR_EEP("Chain2 xatten2Margin", modal_hdr->xatten2Margin[2]);
0194 PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1);
0195 PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1);
0196 PR_EEP("LNA Control", modal_hdr->lna_ctl);
0197 PR_EEP("XPA Bias Freq0", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[0]));
0198 PR_EEP("XPA Bias Freq1", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[1]));
0199 PR_EEP("XPA Bias Freq2", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[2]));
0200
0201 return len;
0202 }
0203
0204 static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
0205 u8 *buf, u32 len, u32 size)
0206 {
0207 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
0208 struct base_eep_header *pBase = &eep->baseEepHeader;
0209 u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber);
0210
0211 if (!dump_base_hdr) {
0212 len += scnprintf(buf + len, size - len,
0213 "%20s :\n", "2GHz modal Header");
0214 len = ath9k_def_dump_modal_eeprom(buf, len, size,
0215 &eep->modalHeader[0]);
0216 len += scnprintf(buf + len, size - len,
0217 "%20s :\n", "5GHz modal Header");
0218 len = ath9k_def_dump_modal_eeprom(buf, len, size,
0219 &eep->modalHeader[1]);
0220 goto out;
0221 }
0222
0223 PR_EEP("Major Version", ath9k_hw_def_get_eeprom_ver(ah));
0224 PR_EEP("Minor Version", ath9k_hw_def_get_eeprom_rev(ah));
0225 PR_EEP("Checksum", le16_to_cpu(pBase->checksum));
0226 PR_EEP("Length", le16_to_cpu(pBase->length));
0227 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
0228 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
0229 PR_EEP("TX Mask", pBase->txMask);
0230 PR_EEP("RX Mask", pBase->rxMask);
0231 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
0232 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
0233 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
0234 AR5416_OPFLAGS_N_2G_HT20));
0235 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
0236 AR5416_OPFLAGS_N_2G_HT40));
0237 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
0238 AR5416_OPFLAGS_N_5G_HT20));
0239 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
0240 AR5416_OPFLAGS_N_5G_HT40));
0241 PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN));
0242 PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF);
0243 PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF);
0244 PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF);
0245 PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
0246
0247 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
0248 pBase->macAddr);
0249
0250 out:
0251 if (len > size)
0252 len = size;
0253
0254 return len;
0255 }
0256 #else
0257 static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
0258 u8 *buf, u32 len, u32 size)
0259 {
0260 return 0;
0261 }
0262 #endif
0263
0264 static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
0265 {
0266 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
0267 struct ath_common *common = ath9k_hw_common(ah);
0268 u32 el;
0269 bool need_swap;
0270 int i, err;
0271
0272 err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_DEF);
0273 if (err)
0274 return err;
0275
0276 if (need_swap)
0277 el = swab16((__force u16)eep->baseEepHeader.length);
0278 else
0279 el = le16_to_cpu(eep->baseEepHeader.length);
0280
0281 el = min(el / sizeof(u16), SIZE_EEPROM_DEF);
0282 if (!ath9k_hw_nvram_validate_checksum(ah, el))
0283 return -EINVAL;
0284
0285 if (need_swap) {
0286 u32 j;
0287
0288 EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
0289 EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
0290 EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
0291 EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]);
0292 EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]);
0293 EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent);
0294 EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
0295 EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
0296
0297 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
0298 struct modal_eep_header *pModal =
0299 &eep->modalHeader[j];
0300 EEPROM_FIELD_SWAB32(pModal->antCtrlCommon);
0301
0302 for (i = 0; i < AR5416_MAX_CHAINS; i++)
0303 EEPROM_FIELD_SWAB32(pModal->antCtrlChain[i]);
0304
0305 for (i = 0; i < 3; i++)
0306 EEPROM_FIELD_SWAB16(pModal->xpaBiasLvlFreq[i]);
0307
0308 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
0309 EEPROM_FIELD_SWAB16(
0310 pModal->spurChans[i].spurChan);
0311 }
0312 }
0313
0314 if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER,
0315 AR5416_EEP_NO_BACK_VER))
0316 return -EINVAL;
0317
0318
0319 if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
0320 ((le16_to_cpu(eep->baseEepHeader.version) & 0xff) > 0x0a) &&
0321 (eep->baseEepHeader.pwdclkind == 0))
0322 ah->need_an_top2_fixup = true;
0323
0324 if ((common->bus_ops->ath_bus_type == ATH_USB) &&
0325 (AR_SREV_9280(ah)))
0326 eep->modalHeader[0].xpaBiasLvl = 0;
0327
0328 return 0;
0329 }
0330
0331 #undef SIZE_EEPROM_DEF
0332
0333 static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
0334 enum eeprom_param param)
0335 {
0336 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
0337 struct modal_eep_header *pModal = eep->modalHeader;
0338 struct base_eep_header *pBase = &eep->baseEepHeader;
0339 int band = 0;
0340
0341 switch (param) {
0342 case EEP_NFTHRESH_5:
0343 return pModal[0].noiseFloorThreshCh[0];
0344 case EEP_NFTHRESH_2:
0345 return pModal[1].noiseFloorThreshCh[0];
0346 case EEP_MAC_LSW:
0347 return get_unaligned_be16(pBase->macAddr);
0348 case EEP_MAC_MID:
0349 return get_unaligned_be16(pBase->macAddr + 2);
0350 case EEP_MAC_MSW:
0351 return get_unaligned_be16(pBase->macAddr + 4);
0352 case EEP_REG_0:
0353 return le16_to_cpu(pBase->regDmn[0]);
0354 case EEP_OP_CAP:
0355 return le16_to_cpu(pBase->deviceCap);
0356 case EEP_OP_MODE:
0357 return pBase->opCapFlags;
0358 case EEP_RF_SILENT:
0359 return le16_to_cpu(pBase->rfSilent);
0360 case EEP_OB_5:
0361 return pModal[0].ob;
0362 case EEP_DB_5:
0363 return pModal[0].db;
0364 case EEP_OB_2:
0365 return pModal[1].ob;
0366 case EEP_DB_2:
0367 return pModal[1].db;
0368 case EEP_TX_MASK:
0369 return pBase->txMask;
0370 case EEP_RX_MASK:
0371 return pBase->rxMask;
0372 case EEP_FSTCLK_5G:
0373 return pBase->fastClk5g;
0374 case EEP_RXGAIN_TYPE:
0375 return pBase->rxGainType;
0376 case EEP_TXGAIN_TYPE:
0377 return pBase->txGainType;
0378 case EEP_OL_PWRCTRL:
0379 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)
0380 return pBase->openLoopPwrCntl ? true : false;
0381 else
0382 return false;
0383 case EEP_RC_CHAIN_MASK:
0384 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)
0385 return pBase->rcChainMask;
0386 else
0387 return 0;
0388 case EEP_DAC_HPWR_5G:
0389 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20)
0390 return pBase->dacHiPwrMode_5G;
0391 else
0392 return 0;
0393 case EEP_FRAC_N_5G:
0394 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_22)
0395 return pBase->frac_n_5g;
0396 else
0397 return 0;
0398 case EEP_PWR_TABLE_OFFSET:
0399 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_21)
0400 return pBase->pwr_table_offset;
0401 else
0402 return AR5416_PWR_TABLE_OFFSET_DB;
0403 case EEP_ANTENNA_GAIN_2G:
0404 band = 1;
0405 fallthrough;
0406 case EEP_ANTENNA_GAIN_5G:
0407 return max_t(u8, max_t(u8,
0408 pModal[band].antennaGainCh[0],
0409 pModal[band].antennaGainCh[1]),
0410 pModal[band].antennaGainCh[2]);
0411 default:
0412 return 0;
0413 }
0414 }
0415
0416 static void ath9k_hw_def_set_gain(struct ath_hw *ah,
0417 struct modal_eep_header *pModal,
0418 struct ar5416_eeprom_def *eep,
0419 u8 txRxAttenLocal, int regChainOffset, int i)
0420 {
0421 ENABLE_REG_RMW_BUFFER(ah);
0422 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
0423 txRxAttenLocal = pModal->txRxAttenCh[i];
0424
0425 if (AR_SREV_9280_20_OR_LATER(ah)) {
0426 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0427 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
0428 pModal->bswMargin[i]);
0429 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0430 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
0431 pModal->bswAtten[i]);
0432 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0433 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
0434 pModal->xatten2Margin[i]);
0435 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0436 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
0437 pModal->xatten2Db[i]);
0438 } else {
0439 REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0440 SM(pModal-> bswMargin[i], AR_PHY_GAIN_2GHZ_BSW_MARGIN),
0441 AR_PHY_GAIN_2GHZ_BSW_MARGIN);
0442 REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0443 SM(pModal->bswAtten[i], AR_PHY_GAIN_2GHZ_BSW_ATTEN),
0444 AR_PHY_GAIN_2GHZ_BSW_ATTEN);
0445 }
0446 }
0447
0448 if (AR_SREV_9280_20_OR_LATER(ah)) {
0449 REG_RMW_FIELD(ah,
0450 AR_PHY_RXGAIN + regChainOffset,
0451 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
0452 REG_RMW_FIELD(ah,
0453 AR_PHY_RXGAIN + regChainOffset,
0454 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
0455 } else {
0456 REG_RMW(ah, AR_PHY_RXGAIN + regChainOffset,
0457 SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN),
0458 AR_PHY_RXGAIN_TXRX_ATTEN);
0459 REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
0460 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN),
0461 AR_PHY_GAIN_2GHZ_RXTX_MARGIN);
0462 }
0463 REG_RMW_BUFFER_FLUSH(ah);
0464 }
0465
0466 static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
0467 struct ath9k_channel *chan)
0468 {
0469 struct modal_eep_header *pModal;
0470 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
0471 int i, regChainOffset;
0472 u8 txRxAttenLocal;
0473 u32 antCtrlCommon;
0474
0475 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
0476 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
0477 antCtrlCommon = le32_to_cpu(pModal->antCtrlCommon);
0478
0479 REG_WRITE(ah, AR_PHY_SWITCH_COM, antCtrlCommon & 0xffff);
0480
0481 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
0482 if (AR_SREV_9280(ah)) {
0483 if (i >= 2)
0484 break;
0485 }
0486
0487 if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
0488 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
0489 else
0490 regChainOffset = i * 0x1000;
0491
0492 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
0493 le32_to_cpu(pModal->antCtrlChain[i]));
0494
0495 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
0496 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
0497 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
0498 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
0499 SM(pModal->iqCalICh[i],
0500 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
0501 SM(pModal->iqCalQCh[i],
0502 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
0503
0504 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
0505 regChainOffset, i);
0506 }
0507
0508 if (AR_SREV_9280_20_OR_LATER(ah)) {
0509 if (IS_CHAN_2GHZ(chan)) {
0510 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
0511 AR_AN_RF2G1_CH0_OB,
0512 AR_AN_RF2G1_CH0_OB_S,
0513 pModal->ob);
0514 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
0515 AR_AN_RF2G1_CH0_DB,
0516 AR_AN_RF2G1_CH0_DB_S,
0517 pModal->db);
0518 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
0519 AR_AN_RF2G1_CH1_OB,
0520 AR_AN_RF2G1_CH1_OB_S,
0521 pModal->ob_ch1);
0522 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
0523 AR_AN_RF2G1_CH1_DB,
0524 AR_AN_RF2G1_CH1_DB_S,
0525 pModal->db_ch1);
0526 } else {
0527 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
0528 AR_AN_RF5G1_CH0_OB5,
0529 AR_AN_RF5G1_CH0_OB5_S,
0530 pModal->ob);
0531 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
0532 AR_AN_RF5G1_CH0_DB5,
0533 AR_AN_RF5G1_CH0_DB5_S,
0534 pModal->db);
0535 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
0536 AR_AN_RF5G1_CH1_OB5,
0537 AR_AN_RF5G1_CH1_OB5_S,
0538 pModal->ob_ch1);
0539 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
0540 AR_AN_RF5G1_CH1_DB5,
0541 AR_AN_RF5G1_CH1_DB5_S,
0542 pModal->db_ch1);
0543 }
0544 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
0545 AR_AN_TOP2_XPABIAS_LVL,
0546 AR_AN_TOP2_XPABIAS_LVL_S,
0547 pModal->xpaBiasLvl);
0548 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
0549 AR_AN_TOP2_LOCALBIAS,
0550 AR_AN_TOP2_LOCALBIAS_S,
0551 !!(pModal->lna_ctl &
0552 LNA_CTL_LOCAL_BIAS));
0553 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
0554 !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
0555 }
0556
0557 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
0558 pModal->switchSettling);
0559 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
0560 pModal->adcDesiredSize);
0561
0562 if (!AR_SREV_9280_20_OR_LATER(ah))
0563 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
0564 AR_PHY_DESIRED_SZ_PGA,
0565 pModal->pgaDesiredSize);
0566
0567 REG_WRITE(ah, AR_PHY_RF_CTL4,
0568 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
0569 | SM(pModal->txEndToXpaOff,
0570 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
0571 | SM(pModal->txFrameToXpaOn,
0572 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
0573 | SM(pModal->txFrameToXpaOn,
0574 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
0575
0576 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
0577 pModal->txEndToRxOn);
0578
0579 if (AR_SREV_9280_20_OR_LATER(ah)) {
0580 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
0581 pModal->thresh62);
0582 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
0583 AR_PHY_EXT_CCA0_THRESH62,
0584 pModal->thresh62);
0585 } else {
0586 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
0587 pModal->thresh62);
0588 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
0589 AR_PHY_EXT_CCA_THRESH62,
0590 pModal->thresh62);
0591 }
0592
0593 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {
0594 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
0595 AR_PHY_TX_END_DATA_START,
0596 pModal->txFrameToDataStart);
0597 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
0598 pModal->txFrameToPaOn);
0599 }
0600
0601 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
0602 if (IS_CHAN_HT40(chan))
0603 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
0604 AR_PHY_SETTLING_SWITCH,
0605 pModal->swSettleHt40);
0606 }
0607
0608 if (AR_SREV_9280_20_OR_LATER(ah) &&
0609 ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)
0610 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
0611 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
0612 pModal->miscBits);
0613
0614
0615 if (AR_SREV_9280_20(ah) &&
0616 ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20) {
0617 if (IS_CHAN_2GHZ(chan))
0618 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
0619 eep->baseEepHeader.dacLpMode);
0620 else if (eep->baseEepHeader.dacHiPwrMode_5G)
0621 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
0622 else
0623 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
0624 eep->baseEepHeader.dacLpMode);
0625
0626 udelay(100);
0627
0628 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
0629 pModal->miscBits >> 2);
0630
0631 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
0632 AR_PHY_TX_DESIRED_SCALE_CCK,
0633 eep->baseEepHeader.desiredScaleCCK);
0634 }
0635 }
0636
0637 static void ath9k_hw_def_set_addac(struct ath_hw *ah,
0638 struct ath9k_channel *chan)
0639 {
0640 #define XPA_LVL_FREQ(cnt) (le16_to_cpu(pModal->xpaBiasLvlFreq[cnt]))
0641 struct modal_eep_header *pModal;
0642 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
0643 u8 biaslevel;
0644
0645 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
0646 return;
0647
0648 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
0649 return;
0650
0651 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
0652
0653 if (pModal->xpaBiasLvl != 0xff) {
0654 biaslevel = pModal->xpaBiasLvl;
0655 } else {
0656 u16 resetFreqBin, freqBin, freqCount = 0;
0657 struct chan_centers centers;
0658
0659 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
0660
0661 resetFreqBin = FREQ2FBIN(centers.synth_center,
0662 IS_CHAN_2GHZ(chan));
0663 freqBin = XPA_LVL_FREQ(0) & 0xff;
0664 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
0665
0666 freqCount++;
0667
0668 while (freqCount < 3) {
0669 if (XPA_LVL_FREQ(freqCount) == 0x0)
0670 break;
0671
0672 freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
0673 if (resetFreqBin >= freqBin)
0674 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
0675 else
0676 break;
0677 freqCount++;
0678 }
0679 }
0680
0681 if (IS_CHAN_2GHZ(chan)) {
0682 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
0683 7, 1) & (~0x18)) | biaslevel << 3;
0684 } else {
0685 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
0686 6, 1) & (~0xc0)) | biaslevel << 6;
0687 }
0688 #undef XPA_LVL_FREQ
0689 }
0690
0691 static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
0692 u16 *gb,
0693 u16 numXpdGain,
0694 u16 pdGainOverlap_t2,
0695 int8_t pwr_table_offset,
0696 int16_t *diff)
0697
0698 {
0699 u16 k;
0700
0701
0702
0703
0704
0705
0706 if (AR_SREV_9280_20_OR_LATER(ah)) {
0707 u16 gb_limit;
0708
0709 if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
0710
0711 *diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);
0712
0713 *diff *= 2;
0714
0715
0716
0717 for (k = 0; k < numXpdGain; k++)
0718 gb[k] = (u16)(gb[k] - *diff);
0719 }
0720
0721
0722
0723 gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
0724
0725 for (k = 0; k < numXpdGain; k++)
0726 gb[k] = (u16)min(gb_limit, gb[k]);
0727 }
0728
0729 return *diff;
0730 }
0731
0732 static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
0733 int8_t pwr_table_offset,
0734 int16_t diff,
0735 u8 *pdadcValues)
0736 {
0737 #define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
0738 u16 k;
0739
0740
0741
0742
0743
0744
0745 if (AR_SREV_9280_20_OR_LATER(ah)) {
0746 if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
0747
0748 for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {
0749 pdadcValues[k] = pdadcValues[k + diff];
0750 }
0751
0752
0753 for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) {
0754 pdadcValues[k] = pdadcValues[NUM_PDADC(diff)];
0755 }
0756 }
0757 }
0758 #undef NUM_PDADC
0759 }
0760
0761 static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
0762 struct ath9k_channel *chan)
0763 {
0764 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
0765 #define SM_PDGAIN_B(x, y) \
0766 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
0767 struct ath_common *common = ath9k_hw_common(ah);
0768 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
0769 struct cal_data_per_freq *pRawDataset;
0770 u8 *pCalBChans = NULL;
0771 u16 pdGainOverlap_t2;
0772 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
0773 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
0774 u16 numPiers, i, j;
0775 int16_t diff = 0;
0776 u16 numXpdGain, xpdMask;
0777 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
0778 u32 reg32, regOffset, regChainOffset;
0779 int16_t modalIdx;
0780 int8_t pwr_table_offset;
0781
0782 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
0783 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
0784
0785 pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);
0786
0787 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {
0788 pdGainOverlap_t2 =
0789 pEepData->modalHeader[modalIdx].pdGainOverlap;
0790 } else {
0791 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
0792 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
0793 }
0794
0795 if (IS_CHAN_2GHZ(chan)) {
0796 pCalBChans = pEepData->calFreqPier2G;
0797 numPiers = AR5416_NUM_2G_CAL_PIERS;
0798 } else {
0799 pCalBChans = pEepData->calFreqPier5G;
0800 numPiers = AR5416_NUM_5G_CAL_PIERS;
0801 }
0802
0803 if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
0804 pRawDataset = pEepData->calPierData2G[0];
0805 ah->initPDADC = ((struct calDataPerFreqOpLoop *)
0806 pRawDataset)->vpdPdg[0][0];
0807 }
0808
0809 numXpdGain = 0;
0810
0811 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
0812 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
0813 if (numXpdGain >= AR5416_NUM_PD_GAINS)
0814 break;
0815 xpdGainValues[numXpdGain] =
0816 (u16)(AR5416_PD_GAINS_IN_MASK - i);
0817 numXpdGain++;
0818 }
0819 }
0820
0821 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
0822 (numXpdGain - 1) & 0x3);
0823 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
0824 xpdGainValues[0]);
0825 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
0826 xpdGainValues[1]);
0827 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
0828 xpdGainValues[2]);
0829
0830 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
0831 if ((ah->rxchainmask == 5 || ah->txchainmask == 5) &&
0832 (i != 0)) {
0833 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
0834 } else
0835 regChainOffset = i * 0x1000;
0836
0837 if (pEepData->baseEepHeader.txMask & (1 << i)) {
0838 if (IS_CHAN_2GHZ(chan))
0839 pRawDataset = pEepData->calPierData2G[i];
0840 else
0841 pRawDataset = pEepData->calPierData5G[i];
0842
0843
0844 if (OLC_FOR_AR9280_20_LATER) {
0845 u8 pcdacIdx;
0846 u8 txPower;
0847
0848 ath9k_get_txgain_index(ah, chan,
0849 (struct calDataPerFreqOpLoop *)pRawDataset,
0850 pCalBChans, numPiers, &txPower, &pcdacIdx);
0851 ath9k_olc_get_pdadcs(ah, pcdacIdx,
0852 txPower/2, pdadcValues);
0853 } else {
0854 ath9k_hw_get_gain_boundaries_pdadcs(ah,
0855 chan, pRawDataset,
0856 pCalBChans, numPiers,
0857 pdGainOverlap_t2,
0858 gainBoundaries,
0859 pdadcValues,
0860 numXpdGain);
0861 }
0862
0863 diff = ath9k_change_gain_boundary_setting(ah,
0864 gainBoundaries,
0865 numXpdGain,
0866 pdGainOverlap_t2,
0867 pwr_table_offset,
0868 &diff);
0869
0870 ENABLE_REGWRITE_BUFFER(ah);
0871
0872 if (OLC_FOR_AR9280_20_LATER) {
0873 REG_WRITE(ah,
0874 AR_PHY_TPCRG5 + regChainOffset,
0875 SM(0x6,
0876 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
0877 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
0878 SM_PD_GAIN(3) | SM_PD_GAIN(4));
0879 } else {
0880 REG_WRITE(ah,
0881 AR_PHY_TPCRG5 + regChainOffset,
0882 SM(pdGainOverlap_t2,
0883 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
0884 SM_PDGAIN_B(0, 1) |
0885 SM_PDGAIN_B(1, 2) |
0886 SM_PDGAIN_B(2, 3) |
0887 SM_PDGAIN_B(3, 4));
0888 }
0889
0890 ath9k_adjust_pdadc_values(ah, pwr_table_offset,
0891 diff, pdadcValues);
0892
0893 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
0894 for (j = 0; j < 32; j++) {
0895 reg32 = get_unaligned_le32(&pdadcValues[4 * j]);
0896 REG_WRITE(ah, regOffset, reg32);
0897
0898 ath_dbg(common, EEPROM,
0899 "PDADC (%d,%4x): %4.4x %8.8x\n",
0900 i, regChainOffset, regOffset,
0901 reg32);
0902 ath_dbg(common, EEPROM,
0903 "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
0904 i, 4 * j, pdadcValues[4 * j],
0905 4 * j + 1, pdadcValues[4 * j + 1],
0906 4 * j + 2, pdadcValues[4 * j + 2],
0907 4 * j + 3, pdadcValues[4 * j + 3]);
0908
0909 regOffset += 4;
0910 }
0911 REGWRITE_BUFFER_FLUSH(ah);
0912 }
0913 }
0914
0915 #undef SM_PD_GAIN
0916 #undef SM_PDGAIN_B
0917 }
0918
0919 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
0920 struct ath9k_channel *chan,
0921 int16_t *ratesArray,
0922 u16 cfgCtl,
0923 u16 antenna_reduction,
0924 u16 powerLimit)
0925 {
0926 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
0927 u16 twiceMaxEdgePower;
0928 int i;
0929 struct cal_ctl_data *rep;
0930 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
0931 0, { 0, 0, 0, 0}
0932 };
0933 struct cal_target_power_leg targetPowerOfdmExt = {
0934 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
0935 0, { 0, 0, 0, 0 }
0936 };
0937 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
0938 0, {0, 0, 0, 0}
0939 };
0940 u16 scaledPower = 0, minCtlPower;
0941 static const u16 ctlModesFor11a[] = {
0942 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
0943 };
0944 static const u16 ctlModesFor11g[] = {
0945 CTL_11B, CTL_11G, CTL_2GHT20,
0946 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
0947 };
0948 u16 numCtlModes;
0949 const u16 *pCtlMode;
0950 u16 ctlMode, freq;
0951 struct chan_centers centers;
0952 int tx_chainmask;
0953 u16 twiceMinEdgePower;
0954
0955 tx_chainmask = ah->txchainmask;
0956
0957 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
0958
0959 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
0960 antenna_reduction);
0961
0962 if (IS_CHAN_2GHZ(chan)) {
0963 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
0964 SUB_NUM_CTL_MODES_AT_2G_40;
0965 pCtlMode = ctlModesFor11g;
0966
0967 ath9k_hw_get_legacy_target_powers(ah, chan,
0968 pEepData->calTargetPowerCck,
0969 AR5416_NUM_2G_CCK_TARGET_POWERS,
0970 &targetPowerCck, 4, false);
0971 ath9k_hw_get_legacy_target_powers(ah, chan,
0972 pEepData->calTargetPower2G,
0973 AR5416_NUM_2G_20_TARGET_POWERS,
0974 &targetPowerOfdm, 4, false);
0975 ath9k_hw_get_target_powers(ah, chan,
0976 pEepData->calTargetPower2GHT20,
0977 AR5416_NUM_2G_20_TARGET_POWERS,
0978 &targetPowerHt20, 8, false);
0979
0980 if (IS_CHAN_HT40(chan)) {
0981 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
0982 ath9k_hw_get_target_powers(ah, chan,
0983 pEepData->calTargetPower2GHT40,
0984 AR5416_NUM_2G_40_TARGET_POWERS,
0985 &targetPowerHt40, 8, true);
0986 ath9k_hw_get_legacy_target_powers(ah, chan,
0987 pEepData->calTargetPowerCck,
0988 AR5416_NUM_2G_CCK_TARGET_POWERS,
0989 &targetPowerCckExt, 4, true);
0990 ath9k_hw_get_legacy_target_powers(ah, chan,
0991 pEepData->calTargetPower2G,
0992 AR5416_NUM_2G_20_TARGET_POWERS,
0993 &targetPowerOfdmExt, 4, true);
0994 }
0995 } else {
0996 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
0997 SUB_NUM_CTL_MODES_AT_5G_40;
0998 pCtlMode = ctlModesFor11a;
0999
1000 ath9k_hw_get_legacy_target_powers(ah, chan,
1001 pEepData->calTargetPower5G,
1002 AR5416_NUM_5G_20_TARGET_POWERS,
1003 &targetPowerOfdm, 4, false);
1004 ath9k_hw_get_target_powers(ah, chan,
1005 pEepData->calTargetPower5GHT20,
1006 AR5416_NUM_5G_20_TARGET_POWERS,
1007 &targetPowerHt20, 8, false);
1008
1009 if (IS_CHAN_HT40(chan)) {
1010 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1011 ath9k_hw_get_target_powers(ah, chan,
1012 pEepData->calTargetPower5GHT40,
1013 AR5416_NUM_5G_40_TARGET_POWERS,
1014 &targetPowerHt40, 8, true);
1015 ath9k_hw_get_legacy_target_powers(ah, chan,
1016 pEepData->calTargetPower5G,
1017 AR5416_NUM_5G_20_TARGET_POWERS,
1018 &targetPowerOfdmExt, 4, true);
1019 }
1020 }
1021
1022 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1023 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1024 (pCtlMode[ctlMode] == CTL_2GHT40);
1025 if (isHt40CtlMode)
1026 freq = centers.synth_center;
1027 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1028 freq = centers.ext_center;
1029 else
1030 freq = centers.ctl_center;
1031
1032 twiceMaxEdgePower = MAX_RATE_POWER;
1033
1034 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1035 if ((((cfgCtl & ~CTL_MODE_M) |
1036 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1037 pEepData->ctlIndex[i]) ||
1038 (((cfgCtl & ~CTL_MODE_M) |
1039 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1040 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1041 rep = &(pEepData->ctlData[i]);
1042
1043 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1044 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1045 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1046
1047 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1048 twiceMaxEdgePower = min(twiceMaxEdgePower,
1049 twiceMinEdgePower);
1050 } else {
1051 twiceMaxEdgePower = twiceMinEdgePower;
1052 break;
1053 }
1054 }
1055 }
1056
1057 minCtlPower = min(twiceMaxEdgePower, scaledPower);
1058
1059 switch (pCtlMode[ctlMode]) {
1060 case CTL_11B:
1061 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1062 targetPowerCck.tPow2x[i] =
1063 min((u16)targetPowerCck.tPow2x[i],
1064 minCtlPower);
1065 }
1066 break;
1067 case CTL_11A:
1068 case CTL_11G:
1069 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1070 targetPowerOfdm.tPow2x[i] =
1071 min((u16)targetPowerOfdm.tPow2x[i],
1072 minCtlPower);
1073 }
1074 break;
1075 case CTL_5GHT20:
1076 case CTL_2GHT20:
1077 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1078 targetPowerHt20.tPow2x[i] =
1079 min((u16)targetPowerHt20.tPow2x[i],
1080 minCtlPower);
1081 }
1082 break;
1083 case CTL_11B_EXT:
1084 targetPowerCckExt.tPow2x[0] = min((u16)
1085 targetPowerCckExt.tPow2x[0],
1086 minCtlPower);
1087 break;
1088 case CTL_11A_EXT:
1089 case CTL_11G_EXT:
1090 targetPowerOfdmExt.tPow2x[0] = min((u16)
1091 targetPowerOfdmExt.tPow2x[0],
1092 minCtlPower);
1093 break;
1094 case CTL_5GHT40:
1095 case CTL_2GHT40:
1096 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1097 targetPowerHt40.tPow2x[i] =
1098 min((u16)targetPowerHt40.tPow2x[i],
1099 minCtlPower);
1100 }
1101 break;
1102 default:
1103 break;
1104 }
1105 }
1106
1107 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1108 ratesArray[rate18mb] = ratesArray[rate24mb] =
1109 targetPowerOfdm.tPow2x[0];
1110 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1111 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1112 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1113 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1114
1115 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1116 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1117
1118 if (IS_CHAN_2GHZ(chan)) {
1119 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1120 ratesArray[rate2s] = ratesArray[rate2l] =
1121 targetPowerCck.tPow2x[1];
1122 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1123 targetPowerCck.tPow2x[2];
1124 ratesArray[rate11s] = ratesArray[rate11l] =
1125 targetPowerCck.tPow2x[3];
1126 }
1127 if (IS_CHAN_HT40(chan)) {
1128 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1129 ratesArray[rateHt40_0 + i] =
1130 targetPowerHt40.tPow2x[i];
1131 }
1132 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1133 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1134 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1135 if (IS_CHAN_2GHZ(chan)) {
1136 ratesArray[rateExtCck] =
1137 targetPowerCckExt.tPow2x[0];
1138 }
1139 }
1140 }
1141
1142 static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1143 struct ath9k_channel *chan,
1144 u16 cfgCtl,
1145 u8 twiceAntennaReduction,
1146 u8 powerLimit, bool test)
1147 {
1148 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1149 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1150 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1151 struct modal_eep_header *pModal =
1152 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1153 int16_t ratesArray[Ar5416RateSize];
1154 u8 ht40PowerIncForPdadc = 2;
1155 int i, cck_ofdm_delta = 0;
1156
1157 memset(ratesArray, 0, sizeof(ratesArray));
1158
1159 if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2)
1160 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1161
1162 ath9k_hw_set_def_power_per_rate_table(ah, chan,
1163 &ratesArray[0], cfgCtl,
1164 twiceAntennaReduction,
1165 powerLimit);
1166
1167 ath9k_hw_set_def_power_cal_table(ah, chan);
1168
1169 regulatory->max_power_level = 0;
1170 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1171 if (ratesArray[i] > MAX_RATE_POWER)
1172 ratesArray[i] = MAX_RATE_POWER;
1173 if (ratesArray[i] > regulatory->max_power_level)
1174 regulatory->max_power_level = ratesArray[i];
1175 }
1176
1177 ath9k_hw_update_regulatory_maxpower(ah);
1178
1179 if (test)
1180 return;
1181
1182 if (AR_SREV_9280_20_OR_LATER(ah)) {
1183 for (i = 0; i < Ar5416RateSize; i++) {
1184 int8_t pwr_table_offset;
1185
1186 pwr_table_offset = ah->eep_ops->get_eeprom(ah,
1187 EEP_PWR_TABLE_OFFSET);
1188 ratesArray[i] -= pwr_table_offset * 2;
1189 }
1190 }
1191
1192 ENABLE_REGWRITE_BUFFER(ah);
1193
1194 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1195 ATH9K_POW_SM(ratesArray[rate18mb], 24)
1196 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1197 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1198 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1199 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1200 ATH9K_POW_SM(ratesArray[rate54mb], 24)
1201 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1202 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1203 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1204
1205 if (IS_CHAN_2GHZ(chan)) {
1206 if (OLC_FOR_AR9280_20_LATER) {
1207 cck_ofdm_delta = 2;
1208 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1209 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
1210 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
1211 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1212 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
1213 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1214 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
1215 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
1216 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
1217 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
1218 } else {
1219 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1220 ATH9K_POW_SM(ratesArray[rate2s], 24)
1221 | ATH9K_POW_SM(ratesArray[rate2l], 16)
1222 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1223 | ATH9K_POW_SM(ratesArray[rate1l], 0));
1224 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1225 ATH9K_POW_SM(ratesArray[rate11s], 24)
1226 | ATH9K_POW_SM(ratesArray[rate11l], 16)
1227 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1228 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1229 }
1230 }
1231
1232 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1233 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
1234 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1235 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1236 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1237 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1238 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1239 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1240 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1241 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1242
1243 if (IS_CHAN_HT40(chan)) {
1244 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1245 ATH9K_POW_SM(ratesArray[rateHt40_3] +
1246 ht40PowerIncForPdadc, 24)
1247 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
1248 ht40PowerIncForPdadc, 16)
1249 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1250 ht40PowerIncForPdadc, 8)
1251 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1252 ht40PowerIncForPdadc, 0));
1253 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1254 ATH9K_POW_SM(ratesArray[rateHt40_7] +
1255 ht40PowerIncForPdadc, 24)
1256 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1257 ht40PowerIncForPdadc, 16)
1258 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1259 ht40PowerIncForPdadc, 8)
1260 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1261 ht40PowerIncForPdadc, 0));
1262 if (OLC_FOR_AR9280_20_LATER) {
1263 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1264 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1265 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
1266 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1267 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
1268 } else {
1269 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1270 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1271 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
1272 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1273 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1274 }
1275 }
1276
1277 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1278 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1279 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1280
1281
1282 if (ah->tpc_enabled) {
1283 int ht40_delta;
1284
1285 ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
1286 ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
1287
1288 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
1289 MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
1290 } else {
1291
1292 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
1293 }
1294
1295 REGWRITE_BUFFER_FLUSH(ah);
1296 }
1297
1298 static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1299 {
1300 __le16 spch = ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan;
1301
1302 return le16_to_cpu(spch);
1303 }
1304
1305 static u8 ath9k_hw_def_get_eepmisc(struct ath_hw *ah)
1306 {
1307 return ah->eeprom.def.baseEepHeader.eepMisc;
1308 }
1309
1310 const struct eeprom_ops eep_def_ops = {
1311 .check_eeprom = ath9k_hw_def_check_eeprom,
1312 .get_eeprom = ath9k_hw_def_get_eeprom,
1313 .fill_eeprom = ath9k_hw_def_fill_eeprom,
1314 .dump_eeprom = ath9k_hw_def_dump_eeprom,
1315 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
1316 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
1317 .set_board_values = ath9k_hw_def_set_board_values,
1318 .set_addac = ath9k_hw_def_set_addac,
1319 .set_txpower = ath9k_hw_def_set_txpower,
1320 .get_spur_channel = ath9k_hw_def_get_spur_channel,
1321 .get_eepmisc = ath9k_hw_def_get_eepmisc
1322 };