eeprom_def.c revision cfe8cba982cda73d4970dab712411bebdcc3b9cd
1/*
2 * Copyright (c) 2008-2009 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 "hw.h"
18
19static void ath9k_get_txgain_index(struct ath_hw *ah,
20		struct ath9k_channel *chan,
21		struct calDataPerFreqOpLoop *rawDatasetOpLoop,
22		u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
23{
24	u8 pcdac, i = 0;
25	u16 idxL = 0, idxR = 0, numPiers;
26	bool match;
27	struct chan_centers centers;
28
29	ath9k_hw_get_channel_centers(ah, chan, &centers);
30
31	for (numPiers = 0; numPiers < availPiers; numPiers++)
32		if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
33			break;
34
35	match = ath9k_hw_get_lower_upper_index(
36			(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
37			calChans, numPiers, &idxL, &idxR);
38	if (match) {
39		pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
40		*pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
41	} else {
42		pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
43		*pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
44				rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
45	}
46
47	while (pcdac > ah->originalGain[i] &&
48			i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
49		i++;
50
51	*pcdacIdx = i;
52	return;
53}
54
55static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
56				u32 initTxGain,
57				int txPower,
58				u8 *pPDADCValues)
59{
60	u32 i;
61	u32 offset;
62
63	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
64			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
65	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
66			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
67
68	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
69			AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
70
71	offset = txPower;
72	for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
73		if (i < offset)
74			pPDADCValues[i] = 0x0;
75		else
76			pPDADCValues[i] = 0xFF;
77}
78
79static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
80{
81	return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
82}
83
84static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
85{
86	return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
87}
88
89static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
90{
91#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
92	u16 *eep_data = (u16 *)&ah->eeprom.def;
93	int addr, ar5416_eep_start_loc = 0x100;
94
95	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
96		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
97					 eep_data)) {
98			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
99				  "Unable to read eeprom region\n");
100			return false;
101		}
102		eep_data++;
103	}
104	return true;
105#undef SIZE_EEPROM_DEF
106}
107
108static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
109{
110	struct ar5416_eeprom_def *eep =
111		(struct ar5416_eeprom_def *) &ah->eeprom.def;
112	struct ath_common *common = ath9k_hw_common(ah);
113	u16 *eepdata, temp, magic, magic2;
114	u32 sum = 0, el;
115	bool need_swap = false;
116	int i, addr, size;
117
118	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
119		ath_print(common, ATH_DBG_FATAL, "Reading Magic # failed\n");
120		return false;
121	}
122
123	if (!ath9k_hw_use_flash(ah)) {
124		ath_print(common, ATH_DBG_EEPROM,
125			  "Read Magic = 0x%04X\n", magic);
126
127		if (magic != AR5416_EEPROM_MAGIC) {
128			magic2 = swab16(magic);
129
130			if (magic2 == AR5416_EEPROM_MAGIC) {
131				size = sizeof(struct ar5416_eeprom_def);
132				need_swap = true;
133				eepdata = (u16 *) (&ah->eeprom);
134
135				for (addr = 0; addr < size / sizeof(u16); addr++) {
136					temp = swab16(*eepdata);
137					*eepdata = temp;
138					eepdata++;
139				}
140			} else {
141				ath_print(common, ATH_DBG_FATAL,
142					  "Invalid EEPROM Magic. "
143					  "Endianness mismatch.\n");
144				return -EINVAL;
145			}
146		}
147	}
148
149	ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
150		  need_swap ? "True" : "False");
151
152	if (need_swap)
153		el = swab16(ah->eeprom.def.baseEepHeader.length);
154	else
155		el = ah->eeprom.def.baseEepHeader.length;
156
157	if (el > sizeof(struct ar5416_eeprom_def))
158		el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
159	else
160		el = el / sizeof(u16);
161
162	eepdata = (u16 *)(&ah->eeprom);
163
164	for (i = 0; i < el; i++)
165		sum ^= *eepdata++;
166
167	if (need_swap) {
168		u32 integer, j;
169		u16 word;
170
171		ath_print(common, ATH_DBG_EEPROM,
172			  "EEPROM Endianness is not native.. Changing.\n");
173
174		word = swab16(eep->baseEepHeader.length);
175		eep->baseEepHeader.length = word;
176
177		word = swab16(eep->baseEepHeader.checksum);
178		eep->baseEepHeader.checksum = word;
179
180		word = swab16(eep->baseEepHeader.version);
181		eep->baseEepHeader.version = word;
182
183		word = swab16(eep->baseEepHeader.regDmn[0]);
184		eep->baseEepHeader.regDmn[0] = word;
185
186		word = swab16(eep->baseEepHeader.regDmn[1]);
187		eep->baseEepHeader.regDmn[1] = word;
188
189		word = swab16(eep->baseEepHeader.rfSilent);
190		eep->baseEepHeader.rfSilent = word;
191
192		word = swab16(eep->baseEepHeader.blueToothOptions);
193		eep->baseEepHeader.blueToothOptions = word;
194
195		word = swab16(eep->baseEepHeader.deviceCap);
196		eep->baseEepHeader.deviceCap = word;
197
198		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
199			struct modal_eep_header *pModal =
200				&eep->modalHeader[j];
201			integer = swab32(pModal->antCtrlCommon);
202			pModal->antCtrlCommon = integer;
203
204			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
205				integer = swab32(pModal->antCtrlChain[i]);
206				pModal->antCtrlChain[i] = integer;
207			}
208
209			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
210				word = swab16(pModal->spurChans[i].spurChan);
211				pModal->spurChans[i].spurChan = word;
212			}
213		}
214	}
215
216	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
217	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
218		ath_print(common, ATH_DBG_FATAL,
219			  "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
220			sum, ah->eep_ops->get_eeprom_ver(ah));
221		return -EINVAL;
222	}
223
224	return 0;
225}
226
227static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
228				   enum eeprom_param param)
229{
230	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
231	struct modal_eep_header *pModal = eep->modalHeader;
232	struct base_eep_header *pBase = &eep->baseEepHeader;
233
234	switch (param) {
235	case EEP_NFTHRESH_5:
236		return pModal[0].noiseFloorThreshCh[0];
237	case EEP_NFTHRESH_2:
238		return pModal[1].noiseFloorThreshCh[0];
239	case AR_EEPROM_MAC(0):
240		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
241	case AR_EEPROM_MAC(1):
242		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
243	case AR_EEPROM_MAC(2):
244		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
245	case EEP_REG_0:
246		return pBase->regDmn[0];
247	case EEP_REG_1:
248		return pBase->regDmn[1];
249	case EEP_OP_CAP:
250		return pBase->deviceCap;
251	case EEP_OP_MODE:
252		return pBase->opCapFlags;
253	case EEP_RF_SILENT:
254		return pBase->rfSilent;
255	case EEP_OB_5:
256		return pModal[0].ob;
257	case EEP_DB_5:
258		return pModal[0].db;
259	case EEP_OB_2:
260		return pModal[1].ob;
261	case EEP_DB_2:
262		return pModal[1].db;
263	case EEP_MINOR_REV:
264		return AR5416_VER_MASK;
265	case EEP_TX_MASK:
266		return pBase->txMask;
267	case EEP_RX_MASK:
268		return pBase->rxMask;
269	case EEP_RXGAIN_TYPE:
270		return pBase->rxGainType;
271	case EEP_TXGAIN_TYPE:
272		return pBase->txGainType;
273	case EEP_OL_PWRCTRL:
274		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
275			return pBase->openLoopPwrCntl ? true : false;
276		else
277			return false;
278	case EEP_RC_CHAIN_MASK:
279		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
280			return pBase->rcChainMask;
281		else
282			return 0;
283	case EEP_DAC_HPWR_5G:
284		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
285			return pBase->dacHiPwrMode_5G;
286		else
287			return 0;
288	case EEP_FRAC_N_5G:
289		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
290			return pBase->frac_n_5g;
291		else
292			return 0;
293	default:
294		return 0;
295	}
296}
297
298static void ath9k_hw_def_set_gain(struct ath_hw *ah,
299				  struct modal_eep_header *pModal,
300				  struct ar5416_eeprom_def *eep,
301				  u8 txRxAttenLocal, int regChainOffset, int i)
302{
303	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
304		txRxAttenLocal = pModal->txRxAttenCh[i];
305
306		if (AR_SREV_9280_10_OR_LATER(ah)) {
307			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
308			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
309			      pModal->bswMargin[i]);
310			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
311			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,
312			      pModal->bswAtten[i]);
313			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
314			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
315			      pModal->xatten2Margin[i]);
316			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
317			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
318			      pModal->xatten2Db[i]);
319		} else {
320			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
321			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
322			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
323			  | SM(pModal-> bswMargin[i],
324			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
325			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
326			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
327			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
328			  | SM(pModal->bswAtten[i],
329			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
330		}
331	}
332
333	if (AR_SREV_9280_10_OR_LATER(ah)) {
334		REG_RMW_FIELD(ah,
335		      AR_PHY_RXGAIN + regChainOffset,
336		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
337		REG_RMW_FIELD(ah,
338		      AR_PHY_RXGAIN + regChainOffset,
339		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
340	} else {
341		REG_WRITE(ah,
342			  AR_PHY_RXGAIN + regChainOffset,
343			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
344			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
345			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
346		REG_WRITE(ah,
347			  AR_PHY_GAIN_2GHZ + regChainOffset,
348			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
349			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
350			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
351	}
352}
353
354static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
355					  struct ath9k_channel *chan)
356{
357	struct modal_eep_header *pModal;
358	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
359	int i, regChainOffset;
360	u8 txRxAttenLocal;
361
362	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
363	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
364
365	REG_WRITE(ah, AR_PHY_SWITCH_COM,
366		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
367
368	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
369		if (AR_SREV_9280(ah)) {
370			if (i >= 2)
371				break;
372		}
373
374		if (AR_SREV_5416_20_OR_LATER(ah) &&
375		    (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
376			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
377		else
378			regChainOffset = i * 0x1000;
379
380		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
381			  pModal->antCtrlChain[i]);
382
383		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
384			  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
385			   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
386			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
387			  SM(pModal->iqCalICh[i],
388			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
389			  SM(pModal->iqCalQCh[i],
390			     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
391
392		if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
393			ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
394					      regChainOffset, i);
395	}
396
397	if (AR_SREV_9280_10_OR_LATER(ah)) {
398		if (IS_CHAN_2GHZ(chan)) {
399			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
400						  AR_AN_RF2G1_CH0_OB,
401						  AR_AN_RF2G1_CH0_OB_S,
402						  pModal->ob);
403			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
404						  AR_AN_RF2G1_CH0_DB,
405						  AR_AN_RF2G1_CH0_DB_S,
406						  pModal->db);
407			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
408						  AR_AN_RF2G1_CH1_OB,
409						  AR_AN_RF2G1_CH1_OB_S,
410						  pModal->ob_ch1);
411			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
412						  AR_AN_RF2G1_CH1_DB,
413						  AR_AN_RF2G1_CH1_DB_S,
414						  pModal->db_ch1);
415		} else {
416			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
417						  AR_AN_RF5G1_CH0_OB5,
418						  AR_AN_RF5G1_CH0_OB5_S,
419						  pModal->ob);
420			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
421						  AR_AN_RF5G1_CH0_DB5,
422						  AR_AN_RF5G1_CH0_DB5_S,
423						  pModal->db);
424			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
425						  AR_AN_RF5G1_CH1_OB5,
426						  AR_AN_RF5G1_CH1_OB5_S,
427						  pModal->ob_ch1);
428			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
429						  AR_AN_RF5G1_CH1_DB5,
430						  AR_AN_RF5G1_CH1_DB5_S,
431						  pModal->db_ch1);
432		}
433		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
434					  AR_AN_TOP2_XPABIAS_LVL,
435					  AR_AN_TOP2_XPABIAS_LVL_S,
436					  pModal->xpaBiasLvl);
437		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
438					  AR_AN_TOP2_LOCALBIAS,
439					  AR_AN_TOP2_LOCALBIAS_S,
440					  pModal->local_bias);
441		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
442			      pModal->force_xpaon);
443	}
444
445	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
446		      pModal->switchSettling);
447	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
448		      pModal->adcDesiredSize);
449
450	if (!AR_SREV_9280_10_OR_LATER(ah))
451		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
452			      AR_PHY_DESIRED_SZ_PGA,
453			      pModal->pgaDesiredSize);
454
455	REG_WRITE(ah, AR_PHY_RF_CTL4,
456		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
457		  | SM(pModal->txEndToXpaOff,
458		       AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
459		  | SM(pModal->txFrameToXpaOn,
460		       AR_PHY_RF_CTL4_FRAME_XPAA_ON)
461		  | SM(pModal->txFrameToXpaOn,
462		       AR_PHY_RF_CTL4_FRAME_XPAB_ON));
463
464	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
465		      pModal->txEndToRxOn);
466
467	if (AR_SREV_9280_10_OR_LATER(ah)) {
468		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
469			      pModal->thresh62);
470		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
471			      AR_PHY_EXT_CCA0_THRESH62,
472			      pModal->thresh62);
473	} else {
474		REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
475			      pModal->thresh62);
476		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
477			      AR_PHY_EXT_CCA_THRESH62,
478			      pModal->thresh62);
479	}
480
481	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
482		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
483			      AR_PHY_TX_END_DATA_START,
484			      pModal->txFrameToDataStart);
485		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
486			      pModal->txFrameToPaOn);
487	}
488
489	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
490		if (IS_CHAN_HT40(chan))
491			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
492				      AR_PHY_SETTLING_SWITCH,
493				      pModal->swSettleHt40);
494	}
495
496	if (AR_SREV_9280_20_OR_LATER(ah) &&
497	    AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
498		REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
499			      AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
500			      pModal->miscBits);
501
502
503	if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
504		if (IS_CHAN_2GHZ(chan))
505			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
506					eep->baseEepHeader.dacLpMode);
507		else if (eep->baseEepHeader.dacHiPwrMode_5G)
508			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
509		else
510			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
511				      eep->baseEepHeader.dacLpMode);
512
513		udelay(100);
514
515		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
516			      pModal->miscBits >> 2);
517
518		REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
519			      AR_PHY_TX_DESIRED_SCALE_CCK,
520			      eep->baseEepHeader.desiredScaleCCK);
521	}
522}
523
524static void ath9k_hw_def_set_addac(struct ath_hw *ah,
525				   struct ath9k_channel *chan)
526{
527#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
528	struct modal_eep_header *pModal;
529	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
530	u8 biaslevel;
531
532	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
533		return;
534
535	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
536		return;
537
538	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
539
540	if (pModal->xpaBiasLvl != 0xff) {
541		biaslevel = pModal->xpaBiasLvl;
542	} else {
543		u16 resetFreqBin, freqBin, freqCount = 0;
544		struct chan_centers centers;
545
546		ath9k_hw_get_channel_centers(ah, chan, &centers);
547
548		resetFreqBin = FREQ2FBIN(centers.synth_center,
549					 IS_CHAN_2GHZ(chan));
550		freqBin = XPA_LVL_FREQ(0) & 0xff;
551		biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
552
553		freqCount++;
554
555		while (freqCount < 3) {
556			if (XPA_LVL_FREQ(freqCount) == 0x0)
557				break;
558
559			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
560			if (resetFreqBin >= freqBin)
561				biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
562			else
563				break;
564			freqCount++;
565		}
566	}
567
568	if (IS_CHAN_2GHZ(chan)) {
569		INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
570					7, 1) & (~0x18)) | biaslevel << 3;
571	} else {
572		INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
573					6, 1) & (~0xc0)) | biaslevel << 6;
574	}
575#undef XPA_LVL_FREQ
576}
577
578static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
579				struct ath9k_channel *chan,
580				struct cal_data_per_freq *pRawDataSet,
581				u8 *bChans, u16 availPiers,
582				u16 tPdGainOverlap, int16_t *pMinCalPower,
583				u16 *pPdGainBoundaries, u8 *pPDADCValues,
584				u16 numXpdGains)
585{
586	int i, j, k;
587	int16_t ss;
588	u16 idxL = 0, idxR = 0, numPiers;
589	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
590		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
591	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
592		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
593	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
594		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
595
596	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
597	u8 minPwrT4[AR5416_NUM_PD_GAINS];
598	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
599	int16_t vpdStep;
600	int16_t tmpVal;
601	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
602	bool match;
603	int16_t minDelta = 0;
604	struct chan_centers centers;
605
606	ath9k_hw_get_channel_centers(ah, chan, &centers);
607
608	for (numPiers = 0; numPiers < availPiers; numPiers++) {
609		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
610			break;
611	}
612
613	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
614							     IS_CHAN_2GHZ(chan)),
615					       bChans, numPiers, &idxL, &idxR);
616
617	if (match) {
618		for (i = 0; i < numXpdGains; i++) {
619			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
620			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
621			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
622					pRawDataSet[idxL].pwrPdg[i],
623					pRawDataSet[idxL].vpdPdg[i],
624					AR5416_PD_GAIN_ICEPTS,
625					vpdTableI[i]);
626		}
627	} else {
628		for (i = 0; i < numXpdGains; i++) {
629			pVpdL = pRawDataSet[idxL].vpdPdg[i];
630			pPwrL = pRawDataSet[idxL].pwrPdg[i];
631			pVpdR = pRawDataSet[idxR].vpdPdg[i];
632			pPwrR = pRawDataSet[idxR].pwrPdg[i];
633
634			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
635
636			maxPwrT4[i] =
637				min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
638				    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
639
640
641			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
642						pPwrL, pVpdL,
643						AR5416_PD_GAIN_ICEPTS,
644						vpdTableL[i]);
645			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
646						pPwrR, pVpdR,
647						AR5416_PD_GAIN_ICEPTS,
648						vpdTableR[i]);
649
650			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
651				vpdTableI[i][j] =
652					(u8)(ath9k_hw_interpolate((u16)
653					     FREQ2FBIN(centers.
654						       synth_center,
655						       IS_CHAN_2GHZ
656						       (chan)),
657					     bChans[idxL], bChans[idxR],
658					     vpdTableL[i][j], vpdTableR[i][j]));
659			}
660		}
661	}
662
663	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
664
665	k = 0;
666
667	for (i = 0; i < numXpdGains; i++) {
668		if (i == (numXpdGains - 1))
669			pPdGainBoundaries[i] =
670				(u16)(maxPwrT4[i] / 2);
671		else
672			pPdGainBoundaries[i] =
673				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
674
675		pPdGainBoundaries[i] =
676			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
677
678		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
679			minDelta = pPdGainBoundaries[0] - 23;
680			pPdGainBoundaries[0] = 23;
681		} else {
682			minDelta = 0;
683		}
684
685		if (i == 0) {
686			if (AR_SREV_9280_10_OR_LATER(ah))
687				ss = (int16_t)(0 - (minPwrT4[i] / 2));
688			else
689				ss = 0;
690		} else {
691			ss = (int16_t)((pPdGainBoundaries[i - 1] -
692					(minPwrT4[i] / 2)) -
693				       tPdGainOverlap + 1 + minDelta);
694		}
695		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
696		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
697
698		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
699			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
700			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
701			ss++;
702		}
703
704		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
705		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
706				(minPwrT4[i] / 2));
707		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
708			tgtIndex : sizeCurrVpdTable;
709
710		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
711			pPDADCValues[k++] = vpdTableI[i][ss++];
712		}
713
714		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
715				    vpdTableI[i][sizeCurrVpdTable - 2]);
716		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
717
718		if (tgtIndex > maxIndex) {
719			while ((ss <= tgtIndex) &&
720			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
721				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
722						    (ss - maxIndex + 1) * vpdStep));
723				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
724							 255 : tmpVal);
725				ss++;
726			}
727		}
728	}
729
730	while (i < AR5416_PD_GAINS_IN_MASK) {
731		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
732		i++;
733	}
734
735	while (k < AR5416_NUM_PDADC_VALUES) {
736		pPDADCValues[k] = pPDADCValues[k - 1];
737		k++;
738	}
739
740	return;
741}
742
743static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
744				  struct ath9k_channel *chan,
745				  int16_t *pTxPowerIndexOffset)
746{
747#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
748#define SM_PDGAIN_B(x, y) \
749		SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
750	struct ath_common *common = ath9k_hw_common(ah);
751	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
752	struct cal_data_per_freq *pRawDataset;
753	u8 *pCalBChans = NULL;
754	u16 pdGainOverlap_t2;
755	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
756	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
757	u16 numPiers, i, j;
758	int16_t tMinCalPower;
759	u16 numXpdGain, xpdMask;
760	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
761	u32 reg32, regOffset, regChainOffset;
762	int16_t modalIdx;
763
764	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
765	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
766
767	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
768	    AR5416_EEP_MINOR_VER_2) {
769		pdGainOverlap_t2 =
770			pEepData->modalHeader[modalIdx].pdGainOverlap;
771	} else {
772		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
773					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
774	}
775
776	if (IS_CHAN_2GHZ(chan)) {
777		pCalBChans = pEepData->calFreqPier2G;
778		numPiers = AR5416_NUM_2G_CAL_PIERS;
779	} else {
780		pCalBChans = pEepData->calFreqPier5G;
781		numPiers = AR5416_NUM_5G_CAL_PIERS;
782	}
783
784	if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
785		pRawDataset = pEepData->calPierData2G[0];
786		ah->initPDADC = ((struct calDataPerFreqOpLoop *)
787				 pRawDataset)->vpdPdg[0][0];
788	}
789
790	numXpdGain = 0;
791
792	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
793		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
794			if (numXpdGain >= AR5416_NUM_PD_GAINS)
795				break;
796			xpdGainValues[numXpdGain] =
797				(u16)(AR5416_PD_GAINS_IN_MASK - i);
798			numXpdGain++;
799		}
800	}
801
802	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
803		      (numXpdGain - 1) & 0x3);
804	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
805		      xpdGainValues[0]);
806	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
807		      xpdGainValues[1]);
808	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
809		      xpdGainValues[2]);
810
811	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
812		if (AR_SREV_5416_20_OR_LATER(ah) &&
813		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
814		    (i != 0)) {
815			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
816		} else
817			regChainOffset = i * 0x1000;
818
819		if (pEepData->baseEepHeader.txMask & (1 << i)) {
820			if (IS_CHAN_2GHZ(chan))
821				pRawDataset = pEepData->calPierData2G[i];
822			else
823				pRawDataset = pEepData->calPierData5G[i];
824
825
826			if (OLC_FOR_AR9280_20_LATER) {
827				u8 pcdacIdx;
828				u8 txPower;
829
830				ath9k_get_txgain_index(ah, chan,
831				(struct calDataPerFreqOpLoop *)pRawDataset,
832				pCalBChans, numPiers, &txPower, &pcdacIdx);
833				ath9k_olc_get_pdadcs(ah, pcdacIdx,
834						     txPower/2, pdadcValues);
835			} else {
836				ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
837							chan, pRawDataset,
838							pCalBChans, numPiers,
839							pdGainOverlap_t2,
840							&tMinCalPower,
841							gainBoundaries,
842							pdadcValues,
843							numXpdGain);
844			}
845
846			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
847				if (OLC_FOR_AR9280_20_LATER) {
848					REG_WRITE(ah,
849						AR_PHY_TPCRG5 + regChainOffset,
850						SM(0x6,
851						AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
852						SM_PD_GAIN(1) | SM_PD_GAIN(2) |
853						SM_PD_GAIN(3) | SM_PD_GAIN(4));
854				} else {
855					REG_WRITE(ah,
856						AR_PHY_TPCRG5 + regChainOffset,
857						SM(pdGainOverlap_t2,
858						AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
859						SM_PDGAIN_B(0, 1) |
860						SM_PDGAIN_B(1, 2) |
861						SM_PDGAIN_B(2, 3) |
862						SM_PDGAIN_B(3, 4));
863				}
864			}
865
866			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
867			for (j = 0; j < 32; j++) {
868				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
869					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
870					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
871					((pdadcValues[4 * j + 3] & 0xFF) << 24);
872				REG_WRITE(ah, regOffset, reg32);
873
874				ath_print(common, ATH_DBG_EEPROM,
875					  "PDADC (%d,%4x): %4.4x %8.8x\n",
876					  i, regChainOffset, regOffset,
877					  reg32);
878				ath_print(common, ATH_DBG_EEPROM,
879					  "PDADC: Chain %d | PDADC %3d "
880					  "Value %3d | PDADC %3d Value %3d | "
881					  "PDADC %3d Value %3d | PDADC %3d "
882					  "Value %3d |\n",
883					  i, 4 * j, pdadcValues[4 * j],
884					  4 * j + 1, pdadcValues[4 * j + 1],
885					  4 * j + 2, pdadcValues[4 * j + 2],
886					  4 * j + 3,
887					  pdadcValues[4 * j + 3]);
888
889				regOffset += 4;
890			}
891		}
892	}
893
894	*pTxPowerIndexOffset = 0;
895#undef SM_PD_GAIN
896#undef SM_PDGAIN_B
897}
898
899static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
900						  struct ath9k_channel *chan,
901						  int16_t *ratesArray,
902						  u16 cfgCtl,
903						  u16 AntennaReduction,
904						  u16 twiceMaxRegulatoryPower,
905						  u16 powerLimit)
906{
907#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
908#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   9 /* 10*log10(3)*2 */
909
910	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
911	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
912	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
913	static const u16 tpScaleReductionTable[5] =
914		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
915
916	int i;
917	int16_t twiceLargestAntenna;
918	struct cal_ctl_data *rep;
919	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
920		0, { 0, 0, 0, 0}
921	};
922	struct cal_target_power_leg targetPowerOfdmExt = {
923		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
924		0, { 0, 0, 0, 0 }
925	};
926	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
927		0, {0, 0, 0, 0}
928	};
929	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
930	u16 ctlModesFor11a[] =
931		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
932	u16 ctlModesFor11g[] =
933		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
934		  CTL_2GHT40
935		};
936	u16 numCtlModes, *pCtlMode, ctlMode, freq;
937	struct chan_centers centers;
938	int tx_chainmask;
939	u16 twiceMinEdgePower;
940
941	tx_chainmask = ah->txchainmask;
942
943	ath9k_hw_get_channel_centers(ah, chan, &centers);
944
945	twiceLargestAntenna = max(
946		pEepData->modalHeader
947			[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
948		pEepData->modalHeader
949			[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
950
951	twiceLargestAntenna = max((u8)twiceLargestAntenna,
952				  pEepData->modalHeader
953				  [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
954
955	twiceLargestAntenna = (int16_t)min(AntennaReduction -
956					   twiceLargestAntenna, 0);
957
958	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
959
960	if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
961		maxRegAllowedPower -=
962			(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
963	}
964
965	scaledPower = min(powerLimit, maxRegAllowedPower);
966
967	switch (ar5416_get_ntxchains(tx_chainmask)) {
968	case 1:
969		break;
970	case 2:
971		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
972		break;
973	case 3:
974		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
975		break;
976	}
977
978	scaledPower = max((u16)0, scaledPower);
979
980	if (IS_CHAN_2GHZ(chan)) {
981		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
982			SUB_NUM_CTL_MODES_AT_2G_40;
983		pCtlMode = ctlModesFor11g;
984
985		ath9k_hw_get_legacy_target_powers(ah, chan,
986			pEepData->calTargetPowerCck,
987			AR5416_NUM_2G_CCK_TARGET_POWERS,
988			&targetPowerCck, 4, false);
989		ath9k_hw_get_legacy_target_powers(ah, chan,
990			pEepData->calTargetPower2G,
991			AR5416_NUM_2G_20_TARGET_POWERS,
992			&targetPowerOfdm, 4, false);
993		ath9k_hw_get_target_powers(ah, chan,
994			pEepData->calTargetPower2GHT20,
995			AR5416_NUM_2G_20_TARGET_POWERS,
996			&targetPowerHt20, 8, false);
997
998		if (IS_CHAN_HT40(chan)) {
999			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1000			ath9k_hw_get_target_powers(ah, chan,
1001				pEepData->calTargetPower2GHT40,
1002				AR5416_NUM_2G_40_TARGET_POWERS,
1003				&targetPowerHt40, 8, true);
1004			ath9k_hw_get_legacy_target_powers(ah, chan,
1005				pEepData->calTargetPowerCck,
1006				AR5416_NUM_2G_CCK_TARGET_POWERS,
1007				&targetPowerCckExt, 4, true);
1008			ath9k_hw_get_legacy_target_powers(ah, chan,
1009				pEepData->calTargetPower2G,
1010				AR5416_NUM_2G_20_TARGET_POWERS,
1011				&targetPowerOfdmExt, 4, true);
1012		}
1013	} else {
1014		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1015			SUB_NUM_CTL_MODES_AT_5G_40;
1016		pCtlMode = ctlModesFor11a;
1017
1018		ath9k_hw_get_legacy_target_powers(ah, chan,
1019			pEepData->calTargetPower5G,
1020			AR5416_NUM_5G_20_TARGET_POWERS,
1021			&targetPowerOfdm, 4, false);
1022		ath9k_hw_get_target_powers(ah, chan,
1023			pEepData->calTargetPower5GHT20,
1024			AR5416_NUM_5G_20_TARGET_POWERS,
1025			&targetPowerHt20, 8, false);
1026
1027		if (IS_CHAN_HT40(chan)) {
1028			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1029			ath9k_hw_get_target_powers(ah, chan,
1030				pEepData->calTargetPower5GHT40,
1031				AR5416_NUM_5G_40_TARGET_POWERS,
1032				&targetPowerHt40, 8, true);
1033			ath9k_hw_get_legacy_target_powers(ah, chan,
1034				pEepData->calTargetPower5G,
1035				AR5416_NUM_5G_20_TARGET_POWERS,
1036				&targetPowerOfdmExt, 4, true);
1037		}
1038	}
1039
1040	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1041		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1042			(pCtlMode[ctlMode] == CTL_2GHT40);
1043		if (isHt40CtlMode)
1044			freq = centers.synth_center;
1045		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1046			freq = centers.ext_center;
1047		else
1048			freq = centers.ctl_center;
1049
1050		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
1051		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
1052			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1053
1054		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1055			if ((((cfgCtl & ~CTL_MODE_M) |
1056			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1057			     pEepData->ctlIndex[i]) ||
1058			    (((cfgCtl & ~CTL_MODE_M) |
1059			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1060			     ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1061				rep = &(pEepData->ctlData[i]);
1062
1063				twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1064				rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1065				IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1066
1067				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1068					twiceMaxEdgePower = min(twiceMaxEdgePower,
1069								twiceMinEdgePower);
1070				} else {
1071					twiceMaxEdgePower = twiceMinEdgePower;
1072					break;
1073				}
1074			}
1075		}
1076
1077		minCtlPower = min(twiceMaxEdgePower, scaledPower);
1078
1079		switch (pCtlMode[ctlMode]) {
1080		case CTL_11B:
1081			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1082				targetPowerCck.tPow2x[i] =
1083					min((u16)targetPowerCck.tPow2x[i],
1084					    minCtlPower);
1085			}
1086			break;
1087		case CTL_11A:
1088		case CTL_11G:
1089			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1090				targetPowerOfdm.tPow2x[i] =
1091					min((u16)targetPowerOfdm.tPow2x[i],
1092					    minCtlPower);
1093			}
1094			break;
1095		case CTL_5GHT20:
1096		case CTL_2GHT20:
1097			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1098				targetPowerHt20.tPow2x[i] =
1099					min((u16)targetPowerHt20.tPow2x[i],
1100					    minCtlPower);
1101			}
1102			break;
1103		case CTL_11B_EXT:
1104			targetPowerCckExt.tPow2x[0] = min((u16)
1105					targetPowerCckExt.tPow2x[0],
1106					minCtlPower);
1107			break;
1108		case CTL_11A_EXT:
1109		case CTL_11G_EXT:
1110			targetPowerOfdmExt.tPow2x[0] = min((u16)
1111					targetPowerOfdmExt.tPow2x[0],
1112					minCtlPower);
1113			break;
1114		case CTL_5GHT40:
1115		case CTL_2GHT40:
1116			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1117				targetPowerHt40.tPow2x[i] =
1118					min((u16)targetPowerHt40.tPow2x[i],
1119					    minCtlPower);
1120			}
1121			break;
1122		default:
1123			break;
1124		}
1125	}
1126
1127	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1128		ratesArray[rate18mb] = ratesArray[rate24mb] =
1129		targetPowerOfdm.tPow2x[0];
1130	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1131	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1132	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1133	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1134
1135	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1136		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1137
1138	if (IS_CHAN_2GHZ(chan)) {
1139		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1140		ratesArray[rate2s] = ratesArray[rate2l] =
1141			targetPowerCck.tPow2x[1];
1142		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1143			targetPowerCck.tPow2x[2];
1144		ratesArray[rate11s] = ratesArray[rate11l] =
1145			targetPowerCck.tPow2x[3];
1146	}
1147	if (IS_CHAN_HT40(chan)) {
1148		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1149			ratesArray[rateHt40_0 + i] =
1150				targetPowerHt40.tPow2x[i];
1151		}
1152		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1153		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1154		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1155		if (IS_CHAN_2GHZ(chan)) {
1156			ratesArray[rateExtCck] =
1157				targetPowerCckExt.tPow2x[0];
1158		}
1159	}
1160}
1161
1162static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1163				    struct ath9k_channel *chan,
1164				    u16 cfgCtl,
1165				    u8 twiceAntennaReduction,
1166				    u8 twiceMaxRegulatoryPower,
1167				    u8 powerLimit)
1168{
1169#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1170	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1171	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1172	struct modal_eep_header *pModal =
1173		&(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1174	int16_t ratesArray[Ar5416RateSize];
1175	int16_t txPowerIndexOffset = 0;
1176	u8 ht40PowerIncForPdadc = 2;
1177	int i, cck_ofdm_delta = 0;
1178
1179	memset(ratesArray, 0, sizeof(ratesArray));
1180
1181	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1182	    AR5416_EEP_MINOR_VER_2) {
1183		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1184	}
1185
1186	ath9k_hw_set_def_power_per_rate_table(ah, chan,
1187					       &ratesArray[0], cfgCtl,
1188					       twiceAntennaReduction,
1189					       twiceMaxRegulatoryPower,
1190					       powerLimit);
1191
1192	ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
1193
1194	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1195		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
1196		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1197			ratesArray[i] = AR5416_MAX_RATE_POWER;
1198	}
1199
1200	if (AR_SREV_9280_10_OR_LATER(ah)) {
1201		for (i = 0; i < Ar5416RateSize; i++)
1202			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
1203	}
1204
1205	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1206		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
1207		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1208		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1209		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1210	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1211		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
1212		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1213		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1214		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1215
1216	if (IS_CHAN_2GHZ(chan)) {
1217		if (OLC_FOR_AR9280_20_LATER) {
1218			cck_ofdm_delta = 2;
1219			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1220				ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
1221				| ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
1222				| ATH9K_POW_SM(ratesArray[rateXr], 8)
1223				| ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
1224			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1225				ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
1226				| ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
1227				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
1228				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
1229		} else {
1230			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1231				ATH9K_POW_SM(ratesArray[rate2s], 24)
1232				| ATH9K_POW_SM(ratesArray[rate2l], 16)
1233				| ATH9K_POW_SM(ratesArray[rateXr], 8)
1234				| ATH9K_POW_SM(ratesArray[rate1l], 0));
1235			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1236				ATH9K_POW_SM(ratesArray[rate11s], 24)
1237				| ATH9K_POW_SM(ratesArray[rate11l], 16)
1238				| ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1239				| ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1240		}
1241	}
1242
1243	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1244		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
1245		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1246		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1247		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1248	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1249		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1250		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1251		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1252		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1253
1254	if (IS_CHAN_HT40(chan)) {
1255		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1256			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
1257				       ht40PowerIncForPdadc, 24)
1258			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
1259					 ht40PowerIncForPdadc, 16)
1260			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1261					 ht40PowerIncForPdadc, 8)
1262			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1263					 ht40PowerIncForPdadc, 0));
1264		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1265			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
1266				       ht40PowerIncForPdadc, 24)
1267			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1268					 ht40PowerIncForPdadc, 16)
1269			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1270					 ht40PowerIncForPdadc, 8)
1271			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1272					 ht40PowerIncForPdadc, 0));
1273		if (OLC_FOR_AR9280_20_LATER) {
1274			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1275				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1276				| ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
1277				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1278				| ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
1279		} else {
1280			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1281				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1282				| ATH9K_POW_SM(ratesArray[rateExtCck], 16)
1283				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1284				| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1285		}
1286	}
1287
1288	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1289		  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1290		  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1291
1292	i = rate6mb;
1293
1294	if (IS_CHAN_HT40(chan))
1295		i = rateHt40_0;
1296	else if (IS_CHAN_HT20(chan))
1297		i = rateHt20_0;
1298
1299	if (AR_SREV_9280_10_OR_LATER(ah))
1300		regulatory->max_power_level =
1301			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
1302	else
1303		regulatory->max_power_level = ratesArray[i];
1304
1305	switch(ar5416_get_ntxchains(ah->txchainmask)) {
1306	case 1:
1307		break;
1308	case 2:
1309		regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1310		break;
1311	case 3:
1312		regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1313		break;
1314	default:
1315		ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM,
1316			  "Invalid chainmask configuration\n");
1317		break;
1318	}
1319}
1320
1321static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
1322					  enum ieee80211_band freq_band)
1323{
1324	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1325	struct modal_eep_header *pModal =
1326		&(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
1327	struct base_eep_header *pBase = &eep->baseEepHeader;
1328	u8 num_ant_config;
1329
1330	num_ant_config = 1;
1331
1332	if (pBase->version >= 0x0E0D)
1333		if (pModal->useAnt1)
1334			num_ant_config += 1;
1335
1336	return num_ant_config;
1337}
1338
1339static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
1340					       struct ath9k_channel *chan)
1341{
1342	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1343	struct modal_eep_header *pModal =
1344		&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
1345
1346	return pModal->antCtrlCommon & 0xFFFF;
1347}
1348
1349static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1350{
1351#define EEP_DEF_SPURCHAN \
1352	(ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1353	struct ath_common *common = ath9k_hw_common(ah);
1354
1355	u16 spur_val = AR_NO_SPUR;
1356
1357	ath_print(common, ATH_DBG_ANI,
1358		  "Getting spur idx %d is2Ghz. %d val %x\n",
1359		  i, is2GHz, ah->config.spurchans[i][is2GHz]);
1360
1361	switch (ah->config.spurmode) {
1362	case SPUR_DISABLE:
1363		break;
1364	case SPUR_ENABLE_IOCTL:
1365		spur_val = ah->config.spurchans[i][is2GHz];
1366		ath_print(common, ATH_DBG_ANI,
1367			  "Getting spur val from new loc. %d\n", spur_val);
1368		break;
1369	case SPUR_ENABLE_EEPROM:
1370		spur_val = EEP_DEF_SPURCHAN;
1371		break;
1372	}
1373
1374	return spur_val;
1375
1376#undef EEP_DEF_SPURCHAN
1377}
1378
1379const struct eeprom_ops eep_def_ops = {
1380	.check_eeprom		= ath9k_hw_def_check_eeprom,
1381	.get_eeprom		= ath9k_hw_def_get_eeprom,
1382	.fill_eeprom		= ath9k_hw_def_fill_eeprom,
1383	.get_eeprom_ver		= ath9k_hw_def_get_eeprom_ver,
1384	.get_eeprom_rev		= ath9k_hw_def_get_eeprom_rev,
1385	.get_num_ant_config	= ath9k_hw_def_get_num_ant_config,
1386	.get_eeprom_antenna_cfg	= ath9k_hw_def_get_eeprom_antenna_cfg,
1387	.set_board_values	= ath9k_hw_def_set_board_values,
1388	.set_addac		= ath9k_hw_def_set_addac,
1389	.set_txpower		= ath9k_hw_def_set_txpower,
1390	.get_spur_channel	= ath9k_hw_def_get_spur_channel
1391};
1392