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 int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
0022 {
0023     u16 version = le16_to_cpu(ah->eeprom.map4k.baseEepHeader.version);
0024 
0025     return (version & AR5416_EEP_VER_MAJOR_MASK) >>
0026         AR5416_EEP_VER_MAJOR_SHIFT;
0027 }
0028 
0029 static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
0030 {
0031     u16 version = le16_to_cpu(ah->eeprom.map4k.baseEepHeader.version);
0032 
0033     return version & AR5416_EEP_VER_MINOR_MASK;
0034 }
0035 
0036 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
0037 
0038 static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
0039 {
0040     u16 *eep_data = (u16 *)&ah->eeprom.map4k;
0041     int addr, eep_start_loc = 64;
0042 
0043     for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
0044         if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data))
0045             return false;
0046         eep_data++;
0047     }
0048 
0049     return true;
0050 }
0051 
0052 static bool __ath9k_hw_usb_4k_fill_eeprom(struct ath_hw *ah)
0053 {
0054     u16 *eep_data = (u16 *)&ah->eeprom.map4k;
0055 
0056     ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 64, SIZE_EEPROM_4K);
0057 
0058     return true;
0059 }
0060 
0061 static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
0062 {
0063     struct ath_common *common = ath9k_hw_common(ah);
0064 
0065     if (!ath9k_hw_use_flash(ah)) {
0066         ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
0067     }
0068 
0069     if (common->bus_ops->ath_bus_type == ATH_USB)
0070         return __ath9k_hw_usb_4k_fill_eeprom(ah);
0071     else
0072         return __ath9k_hw_4k_fill_eeprom(ah);
0073 }
0074 
0075 #ifdef CONFIG_ATH9K_COMMON_DEBUG
0076 static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
0077                       struct modal_eep_4k_header *modal_hdr)
0078 {
0079     PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
0080     PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
0081     PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
0082     PR_EEP("Switch Settle", modal_hdr->switchSettling);
0083     PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
0084     PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
0085     PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
0086     PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
0087     PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
0088     PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
0089     PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
0090     PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
0091     PR_EEP("CCA Threshold)", modal_hdr->thresh62);
0092     PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
0093     PR_EEP("xpdGain", modal_hdr->xpdGain);
0094     PR_EEP("External PD", modal_hdr->xpd);
0095     PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
0096     PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
0097     PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
0098     PR_EEP("O/D Bias Version", modal_hdr->version);
0099     PR_EEP("CCK OutputBias", modal_hdr->ob_0);
0100     PR_EEP("BPSK OutputBias", modal_hdr->ob_1);
0101     PR_EEP("QPSK OutputBias", modal_hdr->ob_2);
0102     PR_EEP("16QAM OutputBias", modal_hdr->ob_3);
0103     PR_EEP("64QAM OutputBias", modal_hdr->ob_4);
0104     PR_EEP("CCK Driver1_Bias", modal_hdr->db1_0);
0105     PR_EEP("BPSK Driver1_Bias", modal_hdr->db1_1);
0106     PR_EEP("QPSK Driver1_Bias", modal_hdr->db1_2);
0107     PR_EEP("16QAM Driver1_Bias", modal_hdr->db1_3);
0108     PR_EEP("64QAM Driver1_Bias", modal_hdr->db1_4);
0109     PR_EEP("CCK Driver2_Bias", modal_hdr->db2_0);
0110     PR_EEP("BPSK Driver2_Bias", modal_hdr->db2_1);
0111     PR_EEP("QPSK Driver2_Bias", modal_hdr->db2_2);
0112     PR_EEP("16QAM Driver2_Bias", modal_hdr->db2_3);
0113     PR_EEP("64QAM Driver2_Bias", modal_hdr->db2_4);
0114     PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
0115     PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
0116     PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
0117     PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
0118     PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
0119     PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
0120     PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
0121     PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
0122     PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
0123     PR_EEP("Ant. Diversity ctl1", modal_hdr->antdiv_ctl1);
0124     PR_EEP("Ant. Diversity ctl2", modal_hdr->antdiv_ctl2);
0125     PR_EEP("TX Diversity", modal_hdr->tx_diversity);
0126 
0127     return len;
0128 }
0129 
0130 static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
0131                        u8 *buf, u32 len, u32 size)
0132 {
0133     struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
0134     struct base_eep_header_4k *pBase = &eep->baseEepHeader;
0135     u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber);
0136 
0137     if (!dump_base_hdr) {
0138         len += scnprintf(buf + len, size - len,
0139                  "%20s :\n", "2GHz modal Header");
0140         len = ath9k_dump_4k_modal_eeprom(buf, len, size,
0141                          &eep->modalHeader);
0142         goto out;
0143     }
0144 
0145     PR_EEP("Major Version", ath9k_hw_4k_get_eeprom_ver(ah));
0146     PR_EEP("Minor Version", ath9k_hw_4k_get_eeprom_rev(ah));
0147     PR_EEP("Checksum", le16_to_cpu(pBase->checksum));
0148     PR_EEP("Length", le16_to_cpu(pBase->length));
0149     PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
0150     PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
0151     PR_EEP("TX Mask", pBase->txMask);
0152     PR_EEP("RX Mask", pBase->rxMask);
0153     PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
0154     PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
0155     PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
0156                     AR5416_OPFLAGS_N_2G_HT20));
0157     PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
0158                     AR5416_OPFLAGS_N_2G_HT40));
0159     PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
0160                     AR5416_OPFLAGS_N_5G_HT20));
0161     PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
0162                     AR5416_OPFLAGS_N_5G_HT40));
0163     PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN));
0164     PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF);
0165     PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF);
0166     PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF);
0167     PR_EEP("TX Gain type", pBase->txGainType);
0168 
0169     len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
0170              pBase->macAddr);
0171 
0172 out:
0173     if (len > size)
0174         len = size;
0175 
0176     return len;
0177 }
0178 #else
0179 static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
0180                        u8 *buf, u32 len, u32 size)
0181 {
0182     return 0;
0183 }
0184 #endif
0185 
0186 static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
0187 {
0188     struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
0189     u32 el;
0190     bool need_swap;
0191     int i, err;
0192 
0193     err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_4K);
0194     if (err)
0195         return err;
0196 
0197     if (need_swap)
0198         el = swab16((__force u16)eep->baseEepHeader.length);
0199     else
0200         el = le16_to_cpu(eep->baseEepHeader.length);
0201 
0202     el = min(el / sizeof(u16), SIZE_EEPROM_4K);
0203     if (!ath9k_hw_nvram_validate_checksum(ah, el))
0204         return -EINVAL;
0205 
0206     if (need_swap) {
0207         EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
0208         EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
0209         EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
0210         EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]);
0211         EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]);
0212         EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent);
0213         EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
0214         EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
0215         EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon);
0216 
0217         for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++)
0218             EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
0219 
0220         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
0221             EEPROM_FIELD_SWAB16(
0222                 eep->modalHeader.spurChans[i].spurChan);
0223     }
0224 
0225     if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER,
0226         AR5416_EEP_NO_BACK_VER))
0227         return -EINVAL;
0228 
0229     return 0;
0230 }
0231 
0232 #undef SIZE_EEPROM_4K
0233 
0234 static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
0235                   enum eeprom_param param)
0236 {
0237     struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
0238     struct modal_eep_4k_header *pModal = &eep->modalHeader;
0239     struct base_eep_header_4k *pBase = &eep->baseEepHeader;
0240 
0241     switch (param) {
0242     case EEP_NFTHRESH_2:
0243         return pModal->noiseFloorThreshCh[0];
0244     case EEP_MAC_LSW:
0245         return get_unaligned_be16(pBase->macAddr);
0246     case EEP_MAC_MID:
0247         return get_unaligned_be16(pBase->macAddr + 2);
0248     case EEP_MAC_MSW:
0249         return get_unaligned_be16(pBase->macAddr + 4);
0250     case EEP_REG_0:
0251         return le16_to_cpu(pBase->regDmn[0]);
0252     case EEP_OP_CAP:
0253         return le16_to_cpu(pBase->deviceCap);
0254     case EEP_OP_MODE:
0255         return pBase->opCapFlags;
0256     case EEP_RF_SILENT:
0257         return le16_to_cpu(pBase->rfSilent);
0258     case EEP_OB_2:
0259         return pModal->ob_0;
0260     case EEP_DB_2:
0261         return pModal->db1_1;
0262     case EEP_TX_MASK:
0263         return pBase->txMask;
0264     case EEP_RX_MASK:
0265         return pBase->rxMask;
0266     case EEP_FRAC_N_5G:
0267         return 0;
0268     case EEP_PWR_TABLE_OFFSET:
0269         return AR5416_PWR_TABLE_OFFSET_DB;
0270     case EEP_MODAL_VER:
0271         return pModal->version;
0272     case EEP_ANT_DIV_CTL1:
0273         return pModal->antdiv_ctl1;
0274     case EEP_TXGAIN_TYPE:
0275         return pBase->txGainType;
0276     case EEP_ANTENNA_GAIN_2G:
0277         return pModal->antennaGainCh[0];
0278     default:
0279         return 0;
0280     }
0281 }
0282 
0283 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
0284                   struct ath9k_channel *chan)
0285 {
0286     struct ath_common *common = ath9k_hw_common(ah);
0287     struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
0288     struct cal_data_per_freq_4k *pRawDataset;
0289     u8 *pCalBChans = NULL;
0290     u16 pdGainOverlap_t2;
0291     static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
0292     u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
0293     u16 numPiers, i, j;
0294     u16 numXpdGain, xpdMask;
0295     u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
0296     u32 reg32, regOffset, regChainOffset;
0297 
0298     xpdMask = pEepData->modalHeader.xpdGain;
0299 
0300     if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2)
0301         pdGainOverlap_t2 =
0302             pEepData->modalHeader.pdGainOverlap;
0303     else
0304         pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
0305                         AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
0306 
0307     pCalBChans = pEepData->calFreqPier2G;
0308     numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
0309 
0310     numXpdGain = 0;
0311 
0312     for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
0313         if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
0314             if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
0315                 break;
0316             xpdGainValues[numXpdGain] =
0317                 (u16)(AR5416_PD_GAINS_IN_MASK - i);
0318             numXpdGain++;
0319         }
0320     }
0321 
0322     ENABLE_REG_RMW_BUFFER(ah);
0323     REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
0324               (numXpdGain - 1) & 0x3);
0325     REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
0326               xpdGainValues[0]);
0327     REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
0328               xpdGainValues[1]);
0329     REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
0330     REG_RMW_BUFFER_FLUSH(ah);
0331 
0332     for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
0333         regChainOffset = i * 0x1000;
0334 
0335         if (pEepData->baseEepHeader.txMask & (1 << i)) {
0336             pRawDataset = pEepData->calPierData2G[i];
0337 
0338             ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
0339                         pRawDataset, pCalBChans,
0340                         numPiers, pdGainOverlap_t2,
0341                         gainBoundaries,
0342                         pdadcValues, numXpdGain);
0343 
0344             ENABLE_REGWRITE_BUFFER(ah);
0345 
0346             REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
0347                   SM(pdGainOverlap_t2,
0348                      AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
0349                   | SM(gainBoundaries[0],
0350                        AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
0351                   | SM(gainBoundaries[1],
0352                        AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
0353                   | SM(gainBoundaries[2],
0354                        AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
0355                   | SM(gainBoundaries[3],
0356                    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
0357 
0358             regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
0359             for (j = 0; j < 32; j++) {
0360                 reg32 = get_unaligned_le32(&pdadcValues[4 * j]);
0361                 REG_WRITE(ah, regOffset, reg32);
0362 
0363                 ath_dbg(common, EEPROM,
0364                     "PDADC (%d,%4x): %4.4x %8.8x\n",
0365                     i, regChainOffset, regOffset,
0366                     reg32);
0367                 ath_dbg(common, EEPROM,
0368                     "PDADC: Chain %d | "
0369                     "PDADC %3d Value %3d | "
0370                     "PDADC %3d Value %3d | "
0371                     "PDADC %3d Value %3d | "
0372                     "PDADC %3d Value %3d |\n",
0373                     i, 4 * j, pdadcValues[4 * j],
0374                     4 * j + 1, pdadcValues[4 * j + 1],
0375                     4 * j + 2, pdadcValues[4 * j + 2],
0376                     4 * j + 3, pdadcValues[4 * j + 3]);
0377 
0378                 regOffset += 4;
0379             }
0380 
0381             REGWRITE_BUFFER_FLUSH(ah);
0382         }
0383     }
0384 }
0385 
0386 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
0387                          struct ath9k_channel *chan,
0388                          int16_t *ratesArray,
0389                          u16 cfgCtl,
0390                          u16 antenna_reduction,
0391                          u16 powerLimit)
0392 {
0393 #define CMP_TEST_GRP \
0394     (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) ==  \
0395      pEepData->ctlIndex[i])                     \
0396     || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
0397         ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
0398 
0399     int i;
0400     u16 twiceMinEdgePower;
0401     u16 twiceMaxEdgePower;
0402     u16 scaledPower = 0, minCtlPower;
0403     u16 numCtlModes;
0404     const u16 *pCtlMode;
0405     u16 ctlMode, freq;
0406     struct chan_centers centers;
0407     struct cal_ctl_data_4k *rep;
0408     struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
0409     struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
0410         0, { 0, 0, 0, 0}
0411     };
0412     struct cal_target_power_leg targetPowerOfdmExt = {
0413         0, { 0, 0, 0, 0} }, targetPowerCckExt = {
0414         0, { 0, 0, 0, 0 }
0415     };
0416     struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
0417         0, {0, 0, 0, 0}
0418     };
0419     static const u16 ctlModesFor11g[] = {
0420         CTL_11B, CTL_11G, CTL_2GHT20,
0421         CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
0422     };
0423 
0424     ath9k_hw_get_channel_centers(ah, chan, &centers);
0425 
0426     scaledPower = powerLimit - antenna_reduction;
0427     scaledPower = min_t(u16, scaledPower, MAX_RATE_POWER);
0428     numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
0429     pCtlMode = ctlModesFor11g;
0430 
0431     ath9k_hw_get_legacy_target_powers(ah, chan,
0432             pEepData->calTargetPowerCck,
0433             AR5416_NUM_2G_CCK_TARGET_POWERS,
0434             &targetPowerCck, 4, false);
0435     ath9k_hw_get_legacy_target_powers(ah, chan,
0436             pEepData->calTargetPower2G,
0437             AR5416_NUM_2G_20_TARGET_POWERS,
0438             &targetPowerOfdm, 4, false);
0439     ath9k_hw_get_target_powers(ah, chan,
0440             pEepData->calTargetPower2GHT20,
0441             AR5416_NUM_2G_20_TARGET_POWERS,
0442             &targetPowerHt20, 8, false);
0443 
0444     if (IS_CHAN_HT40(chan)) {
0445         numCtlModes = ARRAY_SIZE(ctlModesFor11g);
0446         ath9k_hw_get_target_powers(ah, chan,
0447                 pEepData->calTargetPower2GHT40,
0448                 AR5416_NUM_2G_40_TARGET_POWERS,
0449                 &targetPowerHt40, 8, true);
0450         ath9k_hw_get_legacy_target_powers(ah, chan,
0451                 pEepData->calTargetPowerCck,
0452                 AR5416_NUM_2G_CCK_TARGET_POWERS,
0453                 &targetPowerCckExt, 4, true);
0454         ath9k_hw_get_legacy_target_powers(ah, chan,
0455                 pEepData->calTargetPower2G,
0456                 AR5416_NUM_2G_20_TARGET_POWERS,
0457                 &targetPowerOfdmExt, 4, true);
0458     }
0459 
0460     for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
0461         bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
0462             (pCtlMode[ctlMode] == CTL_2GHT40);
0463 
0464         if (isHt40CtlMode)
0465             freq = centers.synth_center;
0466         else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
0467             freq = centers.ext_center;
0468         else
0469             freq = centers.ctl_center;
0470 
0471         twiceMaxEdgePower = MAX_RATE_POWER;
0472 
0473         for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
0474                  pEepData->ctlIndex[i]; i++) {
0475 
0476             if (CMP_TEST_GRP) {
0477                 rep = &(pEepData->ctlData[i]);
0478 
0479                 twiceMinEdgePower = ath9k_hw_get_max_edge_power(
0480                     freq,
0481                     rep->ctlEdges[
0482                     ar5416_get_ntxchains(ah->txchainmask) - 1],
0483                     IS_CHAN_2GHZ(chan),
0484                     AR5416_EEP4K_NUM_BAND_EDGES);
0485 
0486                 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
0487                     twiceMaxEdgePower =
0488                         min(twiceMaxEdgePower,
0489                             twiceMinEdgePower);
0490                 } else {
0491                     twiceMaxEdgePower = twiceMinEdgePower;
0492                     break;
0493                 }
0494             }
0495         }
0496 
0497         minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
0498 
0499         switch (pCtlMode[ctlMode]) {
0500         case CTL_11B:
0501             for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
0502                 targetPowerCck.tPow2x[i] =
0503                     min((u16)targetPowerCck.tPow2x[i],
0504                         minCtlPower);
0505             }
0506             break;
0507         case CTL_11G:
0508             for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
0509                 targetPowerOfdm.tPow2x[i] =
0510                     min((u16)targetPowerOfdm.tPow2x[i],
0511                         minCtlPower);
0512             }
0513             break;
0514         case CTL_2GHT20:
0515             for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
0516                 targetPowerHt20.tPow2x[i] =
0517                     min((u16)targetPowerHt20.tPow2x[i],
0518                         minCtlPower);
0519             }
0520             break;
0521         case CTL_11B_EXT:
0522             targetPowerCckExt.tPow2x[0] =
0523                 min((u16)targetPowerCckExt.tPow2x[0],
0524                     minCtlPower);
0525             break;
0526         case CTL_11G_EXT:
0527             targetPowerOfdmExt.tPow2x[0] =
0528                 min((u16)targetPowerOfdmExt.tPow2x[0],
0529                     minCtlPower);
0530             break;
0531         case CTL_2GHT40:
0532             for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
0533                 targetPowerHt40.tPow2x[i] =
0534                     min((u16)targetPowerHt40.tPow2x[i],
0535                         minCtlPower);
0536             }
0537             break;
0538         default:
0539             break;
0540         }
0541     }
0542 
0543     ratesArray[rate6mb] =
0544     ratesArray[rate9mb] =
0545     ratesArray[rate12mb] =
0546     ratesArray[rate18mb] =
0547     ratesArray[rate24mb] =
0548     targetPowerOfdm.tPow2x[0];
0549 
0550     ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
0551     ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
0552     ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
0553     ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
0554 
0555     for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
0556         ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
0557 
0558     ratesArray[rate1l] = targetPowerCck.tPow2x[0];
0559     ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
0560     ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
0561     ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
0562 
0563     if (IS_CHAN_HT40(chan)) {
0564         for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
0565             ratesArray[rateHt40_0 + i] =
0566                 targetPowerHt40.tPow2x[i];
0567         }
0568         ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
0569         ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
0570         ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
0571         ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
0572     }
0573 
0574 #undef CMP_TEST_GRP
0575 }
0576 
0577 static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
0578                     struct ath9k_channel *chan,
0579                     u16 cfgCtl,
0580                     u8 twiceAntennaReduction,
0581                     u8 powerLimit, bool test)
0582 {
0583     struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
0584     struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
0585     struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
0586     int16_t ratesArray[Ar5416RateSize];
0587     u8 ht40PowerIncForPdadc = 2;
0588     int i;
0589 
0590     memset(ratesArray, 0, sizeof(ratesArray));
0591 
0592     if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2)
0593         ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
0594 
0595     ath9k_hw_set_4k_power_per_rate_table(ah, chan,
0596                          &ratesArray[0], cfgCtl,
0597                          twiceAntennaReduction,
0598                          powerLimit);
0599 
0600     ath9k_hw_set_4k_power_cal_table(ah, chan);
0601 
0602     regulatory->max_power_level = 0;
0603     for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
0604         if (ratesArray[i] > MAX_RATE_POWER)
0605             ratesArray[i] = MAX_RATE_POWER;
0606 
0607         if (ratesArray[i] > regulatory->max_power_level)
0608             regulatory->max_power_level = ratesArray[i];
0609     }
0610 
0611     if (test)
0612         return;
0613 
0614     for (i = 0; i < Ar5416RateSize; i++)
0615         ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
0616 
0617     ENABLE_REGWRITE_BUFFER(ah);
0618 
0619     /* OFDM power per rate */
0620     REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
0621           ATH9K_POW_SM(ratesArray[rate18mb], 24)
0622           | ATH9K_POW_SM(ratesArray[rate12mb], 16)
0623           | ATH9K_POW_SM(ratesArray[rate9mb], 8)
0624           | ATH9K_POW_SM(ratesArray[rate6mb], 0));
0625     REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
0626           ATH9K_POW_SM(ratesArray[rate54mb], 24)
0627           | ATH9K_POW_SM(ratesArray[rate48mb], 16)
0628           | ATH9K_POW_SM(ratesArray[rate36mb], 8)
0629           | ATH9K_POW_SM(ratesArray[rate24mb], 0));
0630 
0631     /* CCK power per rate */
0632     REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
0633           ATH9K_POW_SM(ratesArray[rate2s], 24)
0634           | ATH9K_POW_SM(ratesArray[rate2l], 16)
0635           | ATH9K_POW_SM(ratesArray[rateXr], 8)
0636           | ATH9K_POW_SM(ratesArray[rate1l], 0));
0637     REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
0638           ATH9K_POW_SM(ratesArray[rate11s], 24)
0639           | ATH9K_POW_SM(ratesArray[rate11l], 16)
0640           | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
0641           | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
0642 
0643     /* HT20 power per rate */
0644     REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
0645           ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
0646           | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
0647           | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
0648           | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
0649     REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
0650           ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
0651           | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
0652           | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
0653           | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
0654 
0655     /* HT40 power per rate */
0656     if (IS_CHAN_HT40(chan)) {
0657         REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
0658               ATH9K_POW_SM(ratesArray[rateHt40_3] +
0659                        ht40PowerIncForPdadc, 24)
0660               | ATH9K_POW_SM(ratesArray[rateHt40_2] +
0661                      ht40PowerIncForPdadc, 16)
0662               | ATH9K_POW_SM(ratesArray[rateHt40_1] +
0663                      ht40PowerIncForPdadc, 8)
0664               | ATH9K_POW_SM(ratesArray[rateHt40_0] +
0665                      ht40PowerIncForPdadc, 0));
0666         REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
0667               ATH9K_POW_SM(ratesArray[rateHt40_7] +
0668                        ht40PowerIncForPdadc, 24)
0669               | ATH9K_POW_SM(ratesArray[rateHt40_6] +
0670                      ht40PowerIncForPdadc, 16)
0671               | ATH9K_POW_SM(ratesArray[rateHt40_5] +
0672                      ht40PowerIncForPdadc, 8)
0673               | ATH9K_POW_SM(ratesArray[rateHt40_4] +
0674                      ht40PowerIncForPdadc, 0));
0675         REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
0676               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
0677               | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
0678               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
0679               | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
0680     }
0681 
0682     /* TPC initializations */
0683     if (ah->tpc_enabled) {
0684         int ht40_delta;
0685 
0686         ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
0687         ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
0688         /* Enable TPC */
0689         REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
0690             MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
0691     } else {
0692         /* Disable TPC */
0693         REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
0694     }
0695 
0696     REGWRITE_BUFFER_FLUSH(ah);
0697 }
0698 
0699 static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
0700                  struct modal_eep_4k_header *pModal,
0701                  struct ar5416_eeprom_4k *eep,
0702                  u8 txRxAttenLocal)
0703 {
0704     ENABLE_REG_RMW_BUFFER(ah);
0705     REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
0706         le32_to_cpu(pModal->antCtrlChain[0]), 0);
0707 
0708     REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
0709         SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
0710         SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF),
0711         AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF);
0712 
0713     if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
0714         txRxAttenLocal = pModal->txRxAttenCh[0];
0715 
0716         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
0717                   AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
0718         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
0719                   AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
0720         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
0721                   AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
0722                   pModal->xatten2Margin[0]);
0723         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
0724                   AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
0725 
0726         /* Set the block 1 value to block 0 value */
0727         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
0728                   AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
0729                   pModal->bswMargin[0]);
0730         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
0731                   AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
0732         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
0733                   AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
0734                   pModal->xatten2Margin[0]);
0735         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
0736                   AR_PHY_GAIN_2GHZ_XATTEN2_DB,
0737                   pModal->xatten2Db[0]);
0738     }
0739 
0740     REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
0741               AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
0742     REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
0743               AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
0744 
0745     REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
0746               AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
0747     REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
0748               AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
0749     REG_RMW_BUFFER_FLUSH(ah);
0750 }
0751 
0752 /*
0753  * Read EEPROM header info and program the device for correct operation
0754  * given the channel value.
0755  */
0756 static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
0757                      struct ath9k_channel *chan)
0758 {
0759     struct ath9k_hw_capabilities *pCap = &ah->caps;
0760     struct modal_eep_4k_header *pModal;
0761     struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
0762     struct base_eep_header_4k *pBase = &eep->baseEepHeader;
0763     u8 txRxAttenLocal;
0764     u8 ob[5], db1[5], db2[5];
0765     u8 ant_div_control1, ant_div_control2;
0766     u8 bb_desired_scale;
0767     u32 regVal;
0768 
0769     pModal = &eep->modalHeader;
0770     txRxAttenLocal = 23;
0771 
0772     REG_WRITE(ah, AR_PHY_SWITCH_COM, le32_to_cpu(pModal->antCtrlCommon));
0773 
0774     /* Single chain for 4K EEPROM*/
0775     ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
0776 
0777     /* Initialize Ant Diversity settings from EEPROM */
0778     if (pModal->version >= 3) {
0779         ant_div_control1 = pModal->antdiv_ctl1;
0780         ant_div_control2 = pModal->antdiv_ctl2;
0781 
0782         regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
0783         regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
0784 
0785         regVal |= SM(ant_div_control1,
0786                  AR_PHY_9285_ANT_DIV_CTL);
0787         regVal |= SM(ant_div_control2,
0788                  AR_PHY_9285_ANT_DIV_ALT_LNACONF);
0789         regVal |= SM((ant_div_control2 >> 2),
0790                  AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
0791         regVal |= SM((ant_div_control1 >> 1),
0792                  AR_PHY_9285_ANT_DIV_ALT_GAINTB);
0793         regVal |= SM((ant_div_control1 >> 2),
0794                  AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
0795 
0796 
0797         REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
0798         regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
0799         regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
0800         regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
0801         regVal |= SM((ant_div_control1 >> 3),
0802                  AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
0803 
0804         REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
0805         regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
0806 
0807         if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
0808             /*
0809              * If diversity combining is enabled,
0810              * set MAIN to LNA1 and ALT to LNA2 initially.
0811              */
0812             regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
0813             regVal &= (~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
0814                      AR_PHY_9285_ANT_DIV_ALT_LNACONF));
0815 
0816             regVal |= (ATH_ANT_DIV_COMB_LNA1 <<
0817                    AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S);
0818             regVal |= (ATH_ANT_DIV_COMB_LNA2 <<
0819                    AR_PHY_9285_ANT_DIV_ALT_LNACONF_S);
0820             regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));
0821             regVal |= (0 << AR_PHY_9285_FAST_DIV_BIAS_S);
0822             REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
0823         }
0824     }
0825 
0826     if (pModal->version >= 2) {
0827         ob[0] = pModal->ob_0;
0828         ob[1] = pModal->ob_1;
0829         ob[2] = pModal->ob_2;
0830         ob[3] = pModal->ob_3;
0831         ob[4] = pModal->ob_4;
0832 
0833         db1[0] = pModal->db1_0;
0834         db1[1] = pModal->db1_1;
0835         db1[2] = pModal->db1_2;
0836         db1[3] = pModal->db1_3;
0837         db1[4] = pModal->db1_4;
0838 
0839         db2[0] = pModal->db2_0;
0840         db2[1] = pModal->db2_1;
0841         db2[2] = pModal->db2_2;
0842         db2[3] = pModal->db2_3;
0843         db2[4] = pModal->db2_4;
0844     } else if (pModal->version == 1) {
0845         ob[0] = pModal->ob_0;
0846         ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1;
0847         db1[0] = pModal->db1_0;
0848         db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1;
0849         db2[0] = pModal->db2_0;
0850         db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1;
0851     } else {
0852         int i;
0853 
0854         for (i = 0; i < 5; i++) {
0855             ob[i] = pModal->ob_0;
0856             db1[i] = pModal->db1_0;
0857             db2[i] = pModal->db1_0;
0858         }
0859     }
0860 
0861     ENABLE_REG_RMW_BUFFER(ah);
0862     if (AR_SREV_9271(ah)) {
0863         ath9k_hw_analog_shift_rmw(ah,
0864                       AR9285_AN_RF2G3,
0865                       AR9271_AN_RF2G3_OB_cck,
0866                       AR9271_AN_RF2G3_OB_cck_S,
0867                       ob[0]);
0868         ath9k_hw_analog_shift_rmw(ah,
0869                       AR9285_AN_RF2G3,
0870                       AR9271_AN_RF2G3_OB_psk,
0871                       AR9271_AN_RF2G3_OB_psk_S,
0872                       ob[1]);
0873         ath9k_hw_analog_shift_rmw(ah,
0874                       AR9285_AN_RF2G3,
0875                       AR9271_AN_RF2G3_OB_qam,
0876                       AR9271_AN_RF2G3_OB_qam_S,
0877                       ob[2]);
0878         ath9k_hw_analog_shift_rmw(ah,
0879                       AR9285_AN_RF2G3,
0880                       AR9271_AN_RF2G3_DB_1,
0881                       AR9271_AN_RF2G3_DB_1_S,
0882                       db1[0]);
0883         ath9k_hw_analog_shift_rmw(ah,
0884                       AR9285_AN_RF2G4,
0885                       AR9271_AN_RF2G4_DB_2,
0886                       AR9271_AN_RF2G4_DB_2_S,
0887                       db2[0]);
0888     } else {
0889         ath9k_hw_analog_shift_rmw(ah,
0890                       AR9285_AN_RF2G3,
0891                       AR9285_AN_RF2G3_OB_0,
0892                       AR9285_AN_RF2G3_OB_0_S,
0893                       ob[0]);
0894         ath9k_hw_analog_shift_rmw(ah,
0895                       AR9285_AN_RF2G3,
0896                       AR9285_AN_RF2G3_OB_1,
0897                       AR9285_AN_RF2G3_OB_1_S,
0898                       ob[1]);
0899         ath9k_hw_analog_shift_rmw(ah,
0900                       AR9285_AN_RF2G3,
0901                       AR9285_AN_RF2G3_OB_2,
0902                       AR9285_AN_RF2G3_OB_2_S,
0903                       ob[2]);
0904         ath9k_hw_analog_shift_rmw(ah,
0905                       AR9285_AN_RF2G3,
0906                       AR9285_AN_RF2G3_OB_3,
0907                       AR9285_AN_RF2G3_OB_3_S,
0908                       ob[3]);
0909         ath9k_hw_analog_shift_rmw(ah,
0910                       AR9285_AN_RF2G3,
0911                       AR9285_AN_RF2G3_OB_4,
0912                       AR9285_AN_RF2G3_OB_4_S,
0913                       ob[4]);
0914 
0915         ath9k_hw_analog_shift_rmw(ah,
0916                       AR9285_AN_RF2G3,
0917                       AR9285_AN_RF2G3_DB1_0,
0918                       AR9285_AN_RF2G3_DB1_0_S,
0919                       db1[0]);
0920         ath9k_hw_analog_shift_rmw(ah,
0921                       AR9285_AN_RF2G3,
0922                       AR9285_AN_RF2G3_DB1_1,
0923                       AR9285_AN_RF2G3_DB1_1_S,
0924                       db1[1]);
0925         ath9k_hw_analog_shift_rmw(ah,
0926                       AR9285_AN_RF2G3,
0927                       AR9285_AN_RF2G3_DB1_2,
0928                       AR9285_AN_RF2G3_DB1_2_S,
0929                       db1[2]);
0930         ath9k_hw_analog_shift_rmw(ah,
0931                       AR9285_AN_RF2G4,
0932                       AR9285_AN_RF2G4_DB1_3,
0933                       AR9285_AN_RF2G4_DB1_3_S,
0934                       db1[3]);
0935         ath9k_hw_analog_shift_rmw(ah,
0936                       AR9285_AN_RF2G4,
0937                       AR9285_AN_RF2G4_DB1_4,
0938                       AR9285_AN_RF2G4_DB1_4_S, db1[4]);
0939 
0940         ath9k_hw_analog_shift_rmw(ah,
0941                       AR9285_AN_RF2G4,
0942                       AR9285_AN_RF2G4_DB2_0,
0943                       AR9285_AN_RF2G4_DB2_0_S,
0944                       db2[0]);
0945         ath9k_hw_analog_shift_rmw(ah,
0946                       AR9285_AN_RF2G4,
0947                       AR9285_AN_RF2G4_DB2_1,
0948                       AR9285_AN_RF2G4_DB2_1_S,
0949                       db2[1]);
0950         ath9k_hw_analog_shift_rmw(ah,
0951                       AR9285_AN_RF2G4,
0952                       AR9285_AN_RF2G4_DB2_2,
0953                       AR9285_AN_RF2G4_DB2_2_S,
0954                       db2[2]);
0955         ath9k_hw_analog_shift_rmw(ah,
0956                       AR9285_AN_RF2G4,
0957                       AR9285_AN_RF2G4_DB2_3,
0958                       AR9285_AN_RF2G4_DB2_3_S,
0959                       db2[3]);
0960         ath9k_hw_analog_shift_rmw(ah,
0961                       AR9285_AN_RF2G4,
0962                       AR9285_AN_RF2G4_DB2_4,
0963                       AR9285_AN_RF2G4_DB2_4_S,
0964                       db2[4]);
0965     }
0966     REG_RMW_BUFFER_FLUSH(ah);
0967 
0968     ENABLE_REG_RMW_BUFFER(ah);
0969     REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
0970               pModal->switchSettling);
0971     REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
0972               pModal->adcDesiredSize);
0973 
0974     REG_RMW(ah, AR_PHY_RF_CTL4,
0975         SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
0976         SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
0977         SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
0978         SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON), 0);
0979 
0980     REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
0981               pModal->txEndToRxOn);
0982 
0983     if (AR_SREV_9271_10(ah))
0984         REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
0985                   pModal->txEndToRxOn);
0986     REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
0987               pModal->thresh62);
0988     REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
0989               pModal->thresh62);
0990 
0991     if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {
0992         REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
0993                   pModal->txFrameToDataStart);
0994         REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
0995                   pModal->txFrameToPaOn);
0996     }
0997 
0998     if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
0999         if (IS_CHAN_HT40(chan))
1000             REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1001                       AR_PHY_SETTLING_SWITCH,
1002                       pModal->swSettleHt40);
1003     }
1004 
1005     REG_RMW_BUFFER_FLUSH(ah);
1006 
1007     bb_desired_scale = (pModal->bb_scale_smrt_antenna &
1008             EEP_4K_BB_DESIRED_SCALE_MASK);
1009     if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
1010         u32 pwrctrl, mask, clr;
1011 
1012         mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
1013         pwrctrl = mask * bb_desired_scale;
1014         clr = mask * 0x1f;
1015         ENABLE_REG_RMW_BUFFER(ah);
1016         REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
1017         REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
1018         REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
1019 
1020         mask = BIT(0)|BIT(5)|BIT(15);
1021         pwrctrl = mask * bb_desired_scale;
1022         clr = mask * 0x1f;
1023         REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
1024 
1025         mask = BIT(0)|BIT(5);
1026         pwrctrl = mask * bb_desired_scale;
1027         clr = mask * 0x1f;
1028         REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
1029         REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
1030         REG_RMW_BUFFER_FLUSH(ah);
1031     }
1032 }
1033 
1034 static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1035 {
1036     return le16_to_cpu(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan);
1037 }
1038 
1039 static u8 ath9k_hw_4k_get_eepmisc(struct ath_hw *ah)
1040 {
1041     return ah->eeprom.map4k.baseEepHeader.eepMisc;
1042 }
1043 
1044 const struct eeprom_ops eep_4k_ops = {
1045     .check_eeprom       = ath9k_hw_4k_check_eeprom,
1046     .get_eeprom     = ath9k_hw_4k_get_eeprom,
1047     .fill_eeprom        = ath9k_hw_4k_fill_eeprom,
1048     .dump_eeprom        = ath9k_hw_4k_dump_eeprom,
1049     .get_eeprom_ver     = ath9k_hw_4k_get_eeprom_ver,
1050     .get_eeprom_rev     = ath9k_hw_4k_get_eeprom_rev,
1051     .set_board_values   = ath9k_hw_4k_set_board_values,
1052     .set_txpower        = ath9k_hw_4k_set_txpower,
1053     .get_spur_channel   = ath9k_hw_4k_get_spur_channel,
1054     .get_eepmisc        = ath9k_hw_4k_get_eepmisc
1055 };