Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2008-2011 Atheros Communications Inc.
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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, &centers);
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     /* Enable fixup for AR_AN_TOP2 if necessary */
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, &centers);
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     /* Prior to writing the boundaries or the pdadc vs. power table
0702      * into the chip registers the default starting point on the pdadc
0703      * vs. power table needs to be checked and the curve boundaries
0704      * adjusted accordingly
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             /* get the difference in dB */
0711             *diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);
0712             /* get the number of half dB steps */
0713             *diff *= 2;
0714             /* change the original gain boundary settings
0715              * by the number of half dB steps
0716              */
0717             for (k = 0; k < numXpdGain; k++)
0718                 gb[k] = (u16)(gb[k] - *diff);
0719         }
0720         /* Because of a hardware limitation, ensure the gain boundary
0721          * is not larger than (63 - overlap)
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     /* If this is a board that has a pwrTableOffset that differs from
0741      * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
0742      * pdadc vs pwr table needs to be adjusted prior to writing to the
0743      * chip.
0744      */
0745     if (AR_SREV_9280_20_OR_LATER(ah)) {
0746         if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
0747             /* shift the table to start at the new offset */
0748             for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {
0749                 pdadcValues[k] = pdadcValues[k + diff];
0750             }
0751 
0752             /* fill the back of the table */
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, &centers);
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     /* TPC initializations */
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         /* Enable TPC */
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         /* Disable TPC */
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 };