brintos

brintos / linux-shallow public Read only

0
0
Text · 40.0 KiB · 5ba467c Raw
1323 lines · c
1/*2 * Copyright (c) 2008-2011 Atheros Communications Inc.3 *4 * Permission to use, copy, modify, and/or distribute this software for any5 * purpose with or without fee is hereby granted, provided that the above6 * copyright notice and this permission notice appear in all copies.7 *8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.15 */16 17#include <linux/unaligned.h>18#include "hw.h"19#include "ar9002_phy.h"20 21static void ath9k_get_txgain_index(struct ath_hw *ah,22		struct ath9k_channel *chan,23		struct calDataPerFreqOpLoop *rawDatasetOpLoop,24		u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)25{26	u8 pcdac, i = 0;27	u16 idxL = 0, idxR = 0, numPiers;28	bool match;29	struct chan_centers centers;30 31	ath9k_hw_get_channel_centers(ah, chan, &centers);32 33	for (numPiers = 0; numPiers < availPiers; numPiers++)34		if (calChans[numPiers] == AR5416_BCHAN_UNUSED)35			break;36 37	match = ath9k_hw_get_lower_upper_index(38			(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),39			calChans, numPiers, &idxL, &idxR);40	if (match) {41		pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];42		*pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];43	} else {44		pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];45		*pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +46				rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;47	}48 49	while (pcdac > ah->originalGain[i] &&50			i < (AR9280_TX_GAIN_TABLE_SIZE - 1))51		i++;52 53	*pcdacIdx = i;54}55 56static void ath9k_olc_get_pdadcs(struct ath_hw *ah,57				u32 initTxGain,58				int txPower,59				u8 *pPDADCValues)60{61	u32 i;62	u32 offset;63 64	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,65			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);66	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,67			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);68 69	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,70			AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);71 72	offset = txPower;73	for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)74		if (i < offset)75			pPDADCValues[i] = 0x0;76		else77			pPDADCValues[i] = 0xFF;78}79 80static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)81{82	u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version);83 84	return (version & AR5416_EEP_VER_MAJOR_MASK) >>85		AR5416_EEP_VER_MAJOR_SHIFT;86}87 88static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)89{90	u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version);91 92	return version & AR5416_EEP_VER_MINOR_MASK;93}94 95#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))96 97static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)98{99	u16 *eep_data = (u16 *)&ah->eeprom.def;100	int addr, ar5416_eep_start_loc = 0x100;101 102	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {103		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,104					 eep_data))105			return false;106		eep_data++;107	}108	return true;109}110 111static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah)112{113	u16 *eep_data = (u16 *)&ah->eeprom.def;114 115	ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,116				     0x100, SIZE_EEPROM_DEF);117	return true;118}119 120static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)121{122	struct ath_common *common = ath9k_hw_common(ah);123 124	if (!ath9k_hw_use_flash(ah)) {125		ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");126	}127 128	if (common->bus_ops->ath_bus_type == ATH_USB)129		return __ath9k_hw_usb_def_fill_eeprom(ah);130	else131		return __ath9k_hw_def_fill_eeprom(ah);132}133 134#ifdef CONFIG_ATH9K_COMMON_DEBUG135static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,136				       struct modal_eep_header *modal_hdr)137{138	PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0]));139	PR_EEP("Chain1 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[1]));140	PR_EEP("Chain2 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[2]));141	PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));142	PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);143	PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);144	PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]);145	PR_EEP("Switch Settle", modal_hdr->switchSettling);146	PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);147	PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);148	PR_EEP("Chain2 TxRxAtten", modal_hdr->txRxAttenCh[2]);149	PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);150	PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);151	PR_EEP("Chain2 RxTxMargin", modal_hdr->rxTxMarginCh[2]);152	PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);153	PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);154	PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);155	PR_EEP("Chain1 xlna Gain", modal_hdr->xlnaGainCh[1]);156	PR_EEP("Chain2 xlna Gain", modal_hdr->xlnaGainCh[2]);157	PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);158	PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);159	PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);160	PR_EEP("CCA Threshold)", modal_hdr->thresh62);161	PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);162	PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);163	PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);164	PR_EEP("xpdGain", modal_hdr->xpdGain);165	PR_EEP("External PD", modal_hdr->xpd);166	PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);167	PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);168	PR_EEP("Chain2 I Coefficient", modal_hdr->iqCalICh[2]);169	PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);170	PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);171	PR_EEP("Chain2 Q Coefficient", modal_hdr->iqCalQCh[2]);172	PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);173	PR_EEP("Chain0 OutputBias", modal_hdr->ob);174	PR_EEP("Chain0 DriverBias", modal_hdr->db);175	PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);176	PR_EEP("2chain pwr decrease", modal_hdr->pwrDecreaseFor2Chain);177	PR_EEP("3chain pwr decrease", modal_hdr->pwrDecreaseFor3Chain);178	PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);179	PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);180	PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);181	PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);182	PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);183	PR_EEP("Chain2 bswAtten", modal_hdr->bswAtten[2]);184	PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);185	PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);186	PR_EEP("Chain2 bswMargin", modal_hdr->bswMargin[2]);187	PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);188	PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);189	PR_EEP("Chain1 xatten2Db", modal_hdr->xatten2Db[1]);190	PR_EEP("Chain2 xatten2Db", modal_hdr->xatten2Db[2]);191	PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);192	PR_EEP("Chain1 xatten2Margin", modal_hdr->xatten2Margin[1]);193	PR_EEP("Chain2 xatten2Margin", modal_hdr->xatten2Margin[2]);194	PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1);195	PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1);196	PR_EEP("LNA Control", modal_hdr->lna_ctl);197	PR_EEP("XPA Bias Freq0", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[0]));198	PR_EEP("XPA Bias Freq1", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[1]));199	PR_EEP("XPA Bias Freq2", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[2]));200 201	return len;202}203 204static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,205				    u8 *buf, u32 len, u32 size)206{207	struct ar5416_eeprom_def *eep = &ah->eeprom.def;208	struct base_eep_header *pBase = &eep->baseEepHeader;209	u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber);210 211	if (!dump_base_hdr) {212		len += scnprintf(buf + len, size - len,213				 "%20s :\n", "2GHz modal Header");214		len = ath9k_def_dump_modal_eeprom(buf, len, size,215						   &eep->modalHeader[0]);216		len += scnprintf(buf + len, size - len,217				 "%20s :\n", "5GHz modal Header");218		len = ath9k_def_dump_modal_eeprom(buf, len, size,219						   &eep->modalHeader[1]);220		goto out;221	}222 223	PR_EEP("Major Version", ath9k_hw_def_get_eeprom_ver(ah));224	PR_EEP("Minor Version", ath9k_hw_def_get_eeprom_rev(ah));225	PR_EEP("Checksum", le16_to_cpu(pBase->checksum));226	PR_EEP("Length", le16_to_cpu(pBase->length));227	PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));228	PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));229	PR_EEP("TX Mask", pBase->txMask);230	PR_EEP("RX Mask", pBase->rxMask);231	PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));232	PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));233	PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &234					AR5416_OPFLAGS_N_2G_HT20));235	PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &236					AR5416_OPFLAGS_N_2G_HT40));237	PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &238					AR5416_OPFLAGS_N_5G_HT20));239	PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &240					AR5416_OPFLAGS_N_5G_HT40));241	PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN));242	PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF);243	PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF);244	PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF);245	PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);246 247	len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",248			 pBase->macAddr);249 250out:251	if (len > size)252		len = size;253 254	return len;255}256#else257static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,258				    u8 *buf, u32 len, u32 size)259{260	return 0;261}262#endif263 264static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)265{266	struct ar5416_eeprom_def *eep = &ah->eeprom.def;267	struct ath_common *common = ath9k_hw_common(ah);268	u32 el;269	bool need_swap;270	int i, err;271 272	err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_DEF);273	if (err)274		return err;275 276	if (need_swap)277		el = swab16((__force u16)eep->baseEepHeader.length);278	else279		el = le16_to_cpu(eep->baseEepHeader.length);280 281	el = min(el / sizeof(u16), SIZE_EEPROM_DEF);282	if (!ath9k_hw_nvram_validate_checksum(ah, el))283		return -EINVAL;284 285	if (need_swap) {286		u32 j;287 288		EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);289		EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);290		EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);291		EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]);292		EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]);293		EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent);294		EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);295		EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);296 297		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {298			struct modal_eep_header *pModal =299				&eep->modalHeader[j];300			EEPROM_FIELD_SWAB32(pModal->antCtrlCommon);301 302			for (i = 0; i < AR5416_MAX_CHAINS; i++)303				EEPROM_FIELD_SWAB32(pModal->antCtrlChain[i]);304 305			for (i = 0; i < 3; i++)306				EEPROM_FIELD_SWAB16(pModal->xpaBiasLvlFreq[i]);307 308			for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)309				EEPROM_FIELD_SWAB16(310					pModal->spurChans[i].spurChan);311		}312	}313 314	if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER,315	    AR5416_EEP_NO_BACK_VER))316		return -EINVAL;317 318	/* Enable fixup for AR_AN_TOP2 if necessary */319	if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&320	    ((le16_to_cpu(eep->baseEepHeader.version) & 0xff) > 0x0a) &&321	    (eep->baseEepHeader.pwdclkind == 0))322		ah->need_an_top2_fixup = true;323 324	if ((common->bus_ops->ath_bus_type == ATH_USB) &&325	    (AR_SREV_9280(ah)))326		eep->modalHeader[0].xpaBiasLvl = 0;327 328	return 0;329}330 331#undef SIZE_EEPROM_DEF332 333static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,334				   enum eeprom_param param)335{336	struct ar5416_eeprom_def *eep = &ah->eeprom.def;337	struct modal_eep_header *pModal = eep->modalHeader;338	struct base_eep_header *pBase = &eep->baseEepHeader;339	int band = 0;340 341	switch (param) {342	case EEP_NFTHRESH_5:343		return pModal[0].noiseFloorThreshCh[0];344	case EEP_NFTHRESH_2:345		return pModal[1].noiseFloorThreshCh[0];346	case EEP_MAC_LSW:347		return get_unaligned_be16(pBase->macAddr);348	case EEP_MAC_MID:349		return get_unaligned_be16(pBase->macAddr + 2);350	case EEP_MAC_MSW:351		return get_unaligned_be16(pBase->macAddr + 4);352	case EEP_REG_0:353		return le16_to_cpu(pBase->regDmn[0]);354	case EEP_OP_CAP:355		return le16_to_cpu(pBase->deviceCap);356	case EEP_OP_MODE:357		return pBase->opCapFlags;358	case EEP_RF_SILENT:359		return le16_to_cpu(pBase->rfSilent);360	case EEP_OB_5:361		return pModal[0].ob;362	case EEP_DB_5:363		return pModal[0].db;364	case EEP_OB_2:365		return pModal[1].ob;366	case EEP_DB_2:367		return pModal[1].db;368	case EEP_TX_MASK:369		return pBase->txMask;370	case EEP_RX_MASK:371		return pBase->rxMask;372	case EEP_FSTCLK_5G:373		return pBase->fastClk5g;374	case EEP_RXGAIN_TYPE:375		return pBase->rxGainType;376	case EEP_TXGAIN_TYPE:377		return pBase->txGainType;378	case EEP_OL_PWRCTRL:379		if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)380			return pBase->openLoopPwrCntl ? true : false;381		else382			return false;383	case EEP_RC_CHAIN_MASK:384		if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)385			return pBase->rcChainMask;386		else387			return 0;388	case EEP_DAC_HPWR_5G:389		if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20)390			return pBase->dacHiPwrMode_5G;391		else392			return 0;393	case EEP_FRAC_N_5G:394		if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_22)395			return pBase->frac_n_5g;396		else397			return 0;398	case EEP_PWR_TABLE_OFFSET:399		if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_21)400			return pBase->pwr_table_offset;401		else402			return AR5416_PWR_TABLE_OFFSET_DB;403	case EEP_ANTENNA_GAIN_2G:404		band = 1;405		fallthrough;406	case EEP_ANTENNA_GAIN_5G:407		return max_t(u8, max_t(u8,408			pModal[band].antennaGainCh[0],409			pModal[band].antennaGainCh[1]),410			pModal[band].antennaGainCh[2]);411	default:412		return 0;413	}414}415 416static void ath9k_hw_def_set_gain(struct ath_hw *ah,417				  struct modal_eep_header *pModal,418				  struct ar5416_eeprom_def *eep,419				  u8 txRxAttenLocal, int regChainOffset, int i)420{421	ENABLE_REG_RMW_BUFFER(ah);422	if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {423		txRxAttenLocal = pModal->txRxAttenCh[i];424 425		if (AR_SREV_9280_20_OR_LATER(ah)) {426			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,427			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,428			      pModal->bswMargin[i]);429			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,430			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,431			      pModal->bswAtten[i]);432			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,433			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,434			      pModal->xatten2Margin[i]);435			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,436			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,437			      pModal->xatten2Db[i]);438		} else {439			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,440				SM(pModal-> bswMargin[i], AR_PHY_GAIN_2GHZ_BSW_MARGIN),441				AR_PHY_GAIN_2GHZ_BSW_MARGIN);442			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,443				SM(pModal->bswAtten[i], AR_PHY_GAIN_2GHZ_BSW_ATTEN),444				AR_PHY_GAIN_2GHZ_BSW_ATTEN);445		}446	}447 448	if (AR_SREV_9280_20_OR_LATER(ah)) {449		REG_RMW_FIELD(ah,450		      AR_PHY_RXGAIN + regChainOffset,451		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);452		REG_RMW_FIELD(ah,453		      AR_PHY_RXGAIN + regChainOffset,454		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);455	} else {456		REG_RMW(ah, AR_PHY_RXGAIN + regChainOffset,457			SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN),458			AR_PHY_RXGAIN_TXRX_ATTEN);459		REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,460			SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN),461			AR_PHY_GAIN_2GHZ_RXTX_MARGIN);462	}463	REG_RMW_BUFFER_FLUSH(ah);464}465 466static void ath9k_hw_def_set_board_values(struct ath_hw *ah,467					  struct ath9k_channel *chan)468{469	struct modal_eep_header *pModal;470	struct ar5416_eeprom_def *eep = &ah->eeprom.def;471	int i, regChainOffset;472	u8 txRxAttenLocal;473	u32 antCtrlCommon;474 475	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);476	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;477	antCtrlCommon = le32_to_cpu(pModal->antCtrlCommon);478 479	REG_WRITE(ah, AR_PHY_SWITCH_COM, antCtrlCommon & 0xffff);480 481	for (i = 0; i < AR5416_MAX_CHAINS; i++) {482		if (AR_SREV_9280(ah)) {483			if (i >= 2)484				break;485		}486 487		if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))488			regChainOffset = (i == 1) ? 0x2000 : 0x1000;489		else490			regChainOffset = i * 0x1000;491 492		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,493			  le32_to_cpu(pModal->antCtrlChain[i]));494 495		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,496			  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &497			   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |498			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |499			  SM(pModal->iqCalICh[i],500			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |501			  SM(pModal->iqCalQCh[i],502			     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));503 504		ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,505				      regChainOffset, i);506	}507 508	if (AR_SREV_9280_20_OR_LATER(ah)) {509		if (IS_CHAN_2GHZ(chan)) {510			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,511						  AR_AN_RF2G1_CH0_OB,512						  AR_AN_RF2G1_CH0_OB_S,513						  pModal->ob);514			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,515						  AR_AN_RF2G1_CH0_DB,516						  AR_AN_RF2G1_CH0_DB_S,517						  pModal->db);518			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,519						  AR_AN_RF2G1_CH1_OB,520						  AR_AN_RF2G1_CH1_OB_S,521						  pModal->ob_ch1);522			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,523						  AR_AN_RF2G1_CH1_DB,524						  AR_AN_RF2G1_CH1_DB_S,525						  pModal->db_ch1);526		} else {527			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,528						  AR_AN_RF5G1_CH0_OB5,529						  AR_AN_RF5G1_CH0_OB5_S,530						  pModal->ob);531			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,532						  AR_AN_RF5G1_CH0_DB5,533						  AR_AN_RF5G1_CH0_DB5_S,534						  pModal->db);535			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,536						  AR_AN_RF5G1_CH1_OB5,537						  AR_AN_RF5G1_CH1_OB5_S,538						  pModal->ob_ch1);539			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,540						  AR_AN_RF5G1_CH1_DB5,541						  AR_AN_RF5G1_CH1_DB5_S,542						  pModal->db_ch1);543		}544		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,545					  AR_AN_TOP2_XPABIAS_LVL,546					  AR_AN_TOP2_XPABIAS_LVL_S,547					  pModal->xpaBiasLvl);548		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,549					  AR_AN_TOP2_LOCALBIAS,550					  AR_AN_TOP2_LOCALBIAS_S,551					  !!(pModal->lna_ctl &552					     LNA_CTL_LOCAL_BIAS));553		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,554			      !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));555	}556 557	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,558		      pModal->switchSettling);559	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,560		      pModal->adcDesiredSize);561 562	if (!AR_SREV_9280_20_OR_LATER(ah))563		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,564			      AR_PHY_DESIRED_SZ_PGA,565			      pModal->pgaDesiredSize);566 567	REG_WRITE(ah, AR_PHY_RF_CTL4,568		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)569		  | SM(pModal->txEndToXpaOff,570		       AR_PHY_RF_CTL4_TX_END_XPAB_OFF)571		  | SM(pModal->txFrameToXpaOn,572		       AR_PHY_RF_CTL4_FRAME_XPAA_ON)573		  | SM(pModal->txFrameToXpaOn,574		       AR_PHY_RF_CTL4_FRAME_XPAB_ON));575 576	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,577		      pModal->txEndToRxOn);578 579	if (AR_SREV_9280_20_OR_LATER(ah)) {580		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,581			      pModal->thresh62);582		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,583			      AR_PHY_EXT_CCA0_THRESH62,584			      pModal->thresh62);585	} else {586		REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,587			      pModal->thresh62);588		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,589			      AR_PHY_EXT_CCA_THRESH62,590			      pModal->thresh62);591	}592 593	if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {594		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,595			      AR_PHY_TX_END_DATA_START,596			      pModal->txFrameToDataStart);597		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,598			      pModal->txFrameToPaOn);599	}600 601	if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {602		if (IS_CHAN_HT40(chan))603			REG_RMW_FIELD(ah, AR_PHY_SETTLING,604				      AR_PHY_SETTLING_SWITCH,605				      pModal->swSettleHt40);606	}607 608	if (AR_SREV_9280_20_OR_LATER(ah) &&609	    ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)610		REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,611			      AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,612			      pModal->miscBits);613 614 615	if (AR_SREV_9280_20(ah) &&616	    ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20) {617		if (IS_CHAN_2GHZ(chan))618			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,619					eep->baseEepHeader.dacLpMode);620		else if (eep->baseEepHeader.dacHiPwrMode_5G)621			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);622		else623			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,624				      eep->baseEepHeader.dacLpMode);625 626		udelay(100);627 628		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,629			      pModal->miscBits >> 2);630 631		REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,632			      AR_PHY_TX_DESIRED_SCALE_CCK,633			      eep->baseEepHeader.desiredScaleCCK);634	}635}636 637static void ath9k_hw_def_set_addac(struct ath_hw *ah,638				   struct ath9k_channel *chan)639{640#define XPA_LVL_FREQ(cnt) (le16_to_cpu(pModal->xpaBiasLvlFreq[cnt]))641	struct modal_eep_header *pModal;642	struct ar5416_eeprom_def *eep = &ah->eeprom.def;643	u8 biaslevel;644 645	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)646		return;647 648	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)649		return;650 651	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);652 653	if (pModal->xpaBiasLvl != 0xff) {654		biaslevel = pModal->xpaBiasLvl;655	} else {656		u16 resetFreqBin, freqBin, freqCount = 0;657		struct chan_centers centers;658 659		ath9k_hw_get_channel_centers(ah, chan, &centers);660 661		resetFreqBin = FREQ2FBIN(centers.synth_center,662					 IS_CHAN_2GHZ(chan));663		freqBin = XPA_LVL_FREQ(0) & 0xff;664		biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);665 666		freqCount++;667 668		while (freqCount < 3) {669			if (XPA_LVL_FREQ(freqCount) == 0x0)670				break;671 672			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;673			if (resetFreqBin >= freqBin)674				biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);675			else676				break;677			freqCount++;678		}679	}680 681	if (IS_CHAN_2GHZ(chan)) {682		INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,683					7, 1) & (~0x18)) | biaslevel << 3;684	} else {685		INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,686					6, 1) & (~0xc0)) | biaslevel << 6;687	}688#undef XPA_LVL_FREQ689}690 691static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,692				u16 *gb,693				u16 numXpdGain,694				u16 pdGainOverlap_t2,695				int8_t pwr_table_offset,696				int16_t *diff)697 698{699	u16 k;700 701	/* Prior to writing the boundaries or the pdadc vs. power table702	 * into the chip registers the default starting point on the pdadc703	 * vs. power table needs to be checked and the curve boundaries704	 * adjusted accordingly705	 */706	if (AR_SREV_9280_20_OR_LATER(ah)) {707		u16 gb_limit;708 709		if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {710			/* get the difference in dB */711			*diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);712			/* get the number of half dB steps */713			*diff *= 2;714			/* change the original gain boundary settings715			 * by the number of half dB steps716			 */717			for (k = 0; k < numXpdGain; k++)718				gb[k] = (u16)(gb[k] - *diff);719		}720		/* Because of a hardware limitation, ensure the gain boundary721		 * is not larger than (63 - overlap)722		 */723		gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);724 725		for (k = 0; k < numXpdGain; k++)726			gb[k] = (u16)min(gb_limit, gb[k]);727	}728 729	return *diff;730}731 732static void ath9k_adjust_pdadc_values(struct ath_hw *ah,733				      int8_t pwr_table_offset,734				      int16_t diff,735				      u8 *pdadcValues)736{737#define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)738	u16 k;739 740	/* If this is a board that has a pwrTableOffset that differs from741	 * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the742	 * pdadc vs pwr table needs to be adjusted prior to writing to the743	 * chip.744	 */745	if (AR_SREV_9280_20_OR_LATER(ah)) {746		if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {747			/* shift the table to start at the new offset */748			for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {749				pdadcValues[k] = pdadcValues[k + diff];750			}751 752			/* fill the back of the table */753			for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) {754				pdadcValues[k] = pdadcValues[NUM_PDADC(diff)];755			}756		}757	}758#undef NUM_PDADC759}760 761static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,762				  struct ath9k_channel *chan)763{764#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)765#define SM_PDGAIN_B(x, y) \766		SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)767	struct ath_common *common = ath9k_hw_common(ah);768	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;769	struct cal_data_per_freq *pRawDataset;770	u8 *pCalBChans = NULL;771	u16 pdGainOverlap_t2;772	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];773	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];774	u16 numPiers, i, j;775	int16_t diff = 0;776	u16 numXpdGain, xpdMask;777	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };778	u32 reg32, regOffset, regChainOffset;779	int16_t modalIdx;780	int8_t pwr_table_offset;781 782	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;783	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;784 785	pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);786 787	if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {788		pdGainOverlap_t2 =789			pEepData->modalHeader[modalIdx].pdGainOverlap;790	} else {791		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),792					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));793	}794 795	if (IS_CHAN_2GHZ(chan)) {796		pCalBChans = pEepData->calFreqPier2G;797		numPiers = AR5416_NUM_2G_CAL_PIERS;798	} else {799		pCalBChans = pEepData->calFreqPier5G;800		numPiers = AR5416_NUM_5G_CAL_PIERS;801	}802 803	if (OLC_FOR_AR9280_20_LATER(ah) && IS_CHAN_2GHZ(chan)) {804		pRawDataset = pEepData->calPierData2G[0];805		ah->initPDADC = ((struct calDataPerFreqOpLoop *)806				 pRawDataset)->vpdPdg[0][0];807	}808 809	numXpdGain = 0;810 811	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {812		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {813			if (numXpdGain >= AR5416_NUM_PD_GAINS)814				break;815			xpdGainValues[numXpdGain] =816				(u16)(AR5416_PD_GAINS_IN_MASK - i);817			numXpdGain++;818		}819	}820 821	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,822		      (numXpdGain - 1) & 0x3);823	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,824		      xpdGainValues[0]);825	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,826		      xpdGainValues[1]);827	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,828		      xpdGainValues[2]);829 830	for (i = 0; i < AR5416_MAX_CHAINS; i++) {831		if ((ah->rxchainmask == 5 || ah->txchainmask == 5) &&832		    (i != 0)) {833			regChainOffset = (i == 1) ? 0x2000 : 0x1000;834		} else835			regChainOffset = i * 0x1000;836 837		if (pEepData->baseEepHeader.txMask & (1 << i)) {838			if (IS_CHAN_2GHZ(chan))839				pRawDataset = pEepData->calPierData2G[i];840			else841				pRawDataset = pEepData->calPierData5G[i];842 843 844			if (OLC_FOR_AR9280_20_LATER(ah)) {845				u8 pcdacIdx;846				u8 txPower;847 848				ath9k_get_txgain_index(ah, chan,849				(struct calDataPerFreqOpLoop *)pRawDataset,850				pCalBChans, numPiers, &txPower, &pcdacIdx);851				ath9k_olc_get_pdadcs(ah, pcdacIdx,852						     txPower/2, pdadcValues);853			} else {854				ath9k_hw_get_gain_boundaries_pdadcs(ah,855							chan, pRawDataset,856							pCalBChans, numPiers,857							pdGainOverlap_t2,858							gainBoundaries,859							pdadcValues,860							numXpdGain);861			}862 863			diff = ath9k_change_gain_boundary_setting(ah,864							   gainBoundaries,865							   numXpdGain,866							   pdGainOverlap_t2,867							   pwr_table_offset,868							   &diff);869 870			ENABLE_REGWRITE_BUFFER(ah);871 872			if (OLC_FOR_AR9280_20_LATER(ah)) {873				REG_WRITE(ah,874					AR_PHY_TPCRG5 + regChainOffset,875					SM(0x6,876					AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |877					SM_PD_GAIN(1) | SM_PD_GAIN(2) |878					SM_PD_GAIN(3) | SM_PD_GAIN(4));879			} else {880				REG_WRITE(ah,881					AR_PHY_TPCRG5 + regChainOffset,882					SM(pdGainOverlap_t2,883					AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|884					SM_PDGAIN_B(0, 1) |885					SM_PDGAIN_B(1, 2) |886					SM_PDGAIN_B(2, 3) |887					SM_PDGAIN_B(3, 4));888			}889 890			ath9k_adjust_pdadc_values(ah, pwr_table_offset,891						  diff, pdadcValues);892 893			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;894			for (j = 0; j < 32; j++) {895				reg32 = get_unaligned_le32(&pdadcValues[4 * j]);896				REG_WRITE(ah, regOffset, reg32);897 898				ath_dbg(common, EEPROM,899					"PDADC (%d,%4x): %4.4x %8.8x\n",900					i, regChainOffset, regOffset,901					reg32);902				ath_dbg(common, EEPROM,903					"PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",904					i, 4 * j, pdadcValues[4 * j],905					4 * j + 1, pdadcValues[4 * j + 1],906					4 * j + 2, pdadcValues[4 * j + 2],907					4 * j + 3, pdadcValues[4 * j + 3]);908 909				regOffset += 4;910			}911			REGWRITE_BUFFER_FLUSH(ah);912		}913	}914 915#undef SM_PD_GAIN916#undef SM_PDGAIN_B917}918 919static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,920						  struct ath9k_channel *chan,921						  int16_t *ratesArray,922						  u16 cfgCtl,923						  u16 antenna_reduction,924						  u16 powerLimit)925{926	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;927	u16 twiceMaxEdgePower;928	int i;929	struct cal_ctl_data *rep;930	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {931		0, { 0, 0, 0, 0}932	};933	struct cal_target_power_leg targetPowerOfdmExt = {934		0, { 0, 0, 0, 0} }, targetPowerCckExt = {935		0, { 0, 0, 0, 0 }936	};937	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {938		0, {0, 0, 0, 0}939	};940	u16 scaledPower = 0, minCtlPower;941	static const u16 ctlModesFor11a[] = {942		CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40943	};944	static const u16 ctlModesFor11g[] = {945		CTL_11B, CTL_11G, CTL_2GHT20,946		CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40947	};948	u16 numCtlModes;949	const u16 *pCtlMode;950	u16 ctlMode, freq;951	struct chan_centers centers;952	int tx_chainmask;953	u16 twiceMinEdgePower;954 955	tx_chainmask = ah->txchainmask;956 957	ath9k_hw_get_channel_centers(ah, chan, &centers);958 959	scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,960						antenna_reduction);961 962	if (IS_CHAN_2GHZ(chan)) {963		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -964			SUB_NUM_CTL_MODES_AT_2G_40;965		pCtlMode = ctlModesFor11g;966 967		ath9k_hw_get_legacy_target_powers(ah, chan,968			pEepData->calTargetPowerCck,969			AR5416_NUM_2G_CCK_TARGET_POWERS,970			&targetPowerCck, 4, false);971		ath9k_hw_get_legacy_target_powers(ah, chan,972			pEepData->calTargetPower2G,973			AR5416_NUM_2G_20_TARGET_POWERS,974			&targetPowerOfdm, 4, false);975		ath9k_hw_get_target_powers(ah, chan,976			pEepData->calTargetPower2GHT20,977			AR5416_NUM_2G_20_TARGET_POWERS,978			&targetPowerHt20, 8, false);979 980		if (IS_CHAN_HT40(chan)) {981			numCtlModes = ARRAY_SIZE(ctlModesFor11g);982			ath9k_hw_get_target_powers(ah, chan,983				pEepData->calTargetPower2GHT40,984				AR5416_NUM_2G_40_TARGET_POWERS,985				&targetPowerHt40, 8, true);986			ath9k_hw_get_legacy_target_powers(ah, chan,987				pEepData->calTargetPowerCck,988				AR5416_NUM_2G_CCK_TARGET_POWERS,989				&targetPowerCckExt, 4, true);990			ath9k_hw_get_legacy_target_powers(ah, chan,991				pEepData->calTargetPower2G,992				AR5416_NUM_2G_20_TARGET_POWERS,993				&targetPowerOfdmExt, 4, true);994		}995	} else {996		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -997			SUB_NUM_CTL_MODES_AT_5G_40;998		pCtlMode = ctlModesFor11a;999 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		else1030			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 1142static 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(ah)) {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(ah)) {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 1298static 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 1305static u8 ath9k_hw_def_get_eepmisc(struct ath_hw *ah)1306{1307	return ah->eeprom.def.baseEepHeader.eepMisc;1308}1309 1310const 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_eepmisc1322};1323