cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

eeprom_4k.c (32804B)


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