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 
19 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
20 {
21 	return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
22 }
23 
24 static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
25 {
26 	return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
27 }
28 
29 static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
30 {
31 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
32 	struct ath_common *common = ath9k_hw_common(ah);
33 	u16 *eep_data = (u16 *)&ah->eeprom.map4k;
34 	int addr, eep_start_loc = 0;
35 
36 	eep_start_loc = 64;
37 
38 	if (!ath9k_hw_use_flash(ah)) {
39 		ath_print(common, ATH_DBG_EEPROM,
40 			  "Reading from EEPROM, not flash\n");
41 	}
42 
43 	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
44 		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
45 			ath_print(common, ATH_DBG_EEPROM,
46 				  "Unable to read eeprom region \n");
47 			return false;
48 		}
49 		eep_data++;
50 	}
51 
52 	return true;
53 #undef SIZE_EEPROM_4K
54 }
55 
56 static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
57 {
58 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
59 	struct ath_common *common = ath9k_hw_common(ah);
60 	struct ar5416_eeprom_4k *eep =
61 		(struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
62 	u16 *eepdata, temp, magic, magic2;
63 	u32 sum = 0, el;
64 	bool need_swap = false;
65 	int i, addr;
66 
67 
68 	if (!ath9k_hw_use_flash(ah)) {
69 		if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
70 					 &magic)) {
71 			ath_print(common, ATH_DBG_FATAL,
72 				  "Reading Magic # failed\n");
73 			return false;
74 		}
75 
76 		ath_print(common, ATH_DBG_EEPROM,
77 			  "Read Magic = 0x%04X\n", magic);
78 
79 		if (magic != AR5416_EEPROM_MAGIC) {
80 			magic2 = swab16(magic);
81 
82 			if (magic2 == AR5416_EEPROM_MAGIC) {
83 				need_swap = true;
84 				eepdata = (u16 *) (&ah->eeprom);
85 
86 				for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
87 					temp = swab16(*eepdata);
88 					*eepdata = temp;
89 					eepdata++;
90 				}
91 			} else {
92 				ath_print(common, ATH_DBG_FATAL,
93 					  "Invalid EEPROM Magic. "
94 					  "endianness mismatch.\n");
95 				return -EINVAL;
96 			}
97 		}
98 	}
99 
100 	ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
101 		  need_swap ? "True" : "False");
102 
103 	if (need_swap)
104 		el = swab16(ah->eeprom.map4k.baseEepHeader.length);
105 	else
106 		el = ah->eeprom.map4k.baseEepHeader.length;
107 
108 	if (el > sizeof(struct ar5416_eeprom_4k))
109 		el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
110 	else
111 		el = el / sizeof(u16);
112 
113 	eepdata = (u16 *)(&ah->eeprom);
114 
115 	for (i = 0; i < el; i++)
116 		sum ^= *eepdata++;
117 
118 	if (need_swap) {
119 		u32 integer;
120 		u16 word;
121 
122 		ath_print(common, ATH_DBG_EEPROM,
123 			  "EEPROM Endianness is not native.. Changing\n");
124 
125 		word = swab16(eep->baseEepHeader.length);
126 		eep->baseEepHeader.length = word;
127 
128 		word = swab16(eep->baseEepHeader.checksum);
129 		eep->baseEepHeader.checksum = word;
130 
131 		word = swab16(eep->baseEepHeader.version);
132 		eep->baseEepHeader.version = word;
133 
134 		word = swab16(eep->baseEepHeader.regDmn[0]);
135 		eep->baseEepHeader.regDmn[0] = word;
136 
137 		word = swab16(eep->baseEepHeader.regDmn[1]);
138 		eep->baseEepHeader.regDmn[1] = word;
139 
140 		word = swab16(eep->baseEepHeader.rfSilent);
141 		eep->baseEepHeader.rfSilent = word;
142 
143 		word = swab16(eep->baseEepHeader.blueToothOptions);
144 		eep->baseEepHeader.blueToothOptions = word;
145 
146 		word = swab16(eep->baseEepHeader.deviceCap);
147 		eep->baseEepHeader.deviceCap = word;
148 
149 		integer = swab32(eep->modalHeader.antCtrlCommon);
150 		eep->modalHeader.antCtrlCommon = integer;
151 
152 		for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
153 			integer = swab32(eep->modalHeader.antCtrlChain[i]);
154 			eep->modalHeader.antCtrlChain[i] = integer;
155 		}
156 
157 		for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
158 			word = swab16(eep->modalHeader.spurChans[i].spurChan);
159 			eep->modalHeader.spurChans[i].spurChan = word;
160 		}
161 	}
162 
163 	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
164 	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
165 		ath_print(common, ATH_DBG_FATAL,
166 			  "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
167 			  sum, ah->eep_ops->get_eeprom_ver(ah));
168 		return -EINVAL;
169 	}
170 
171 	return 0;
172 #undef EEPROM_4K_SIZE
173 }
174 
175 static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
176 				  enum eeprom_param param)
177 {
178 	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
179 	struct modal_eep_4k_header *pModal = &eep->modalHeader;
180 	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
181 
182 	switch (param) {
183 	case EEP_NFTHRESH_2:
184 		return pModal->noiseFloorThreshCh[0];
185 	case AR_EEPROM_MAC(0):
186 		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
187 	case AR_EEPROM_MAC(1):
188 		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
189 	case AR_EEPROM_MAC(2):
190 		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
191 	case EEP_REG_0:
192 		return pBase->regDmn[0];
193 	case EEP_REG_1:
194 		return pBase->regDmn[1];
195 	case EEP_OP_CAP:
196 		return pBase->deviceCap;
197 	case EEP_OP_MODE:
198 		return pBase->opCapFlags;
199 	case EEP_RF_SILENT:
200 		return pBase->rfSilent;
201 	case EEP_OB_2:
202 		return pModal->ob_0;
203 	case EEP_DB_2:
204 		return pModal->db1_1;
205 	case EEP_MINOR_REV:
206 		return pBase->version & AR5416_EEP_VER_MINOR_MASK;
207 	case EEP_TX_MASK:
208 		return pBase->txMask;
209 	case EEP_RX_MASK:
210 		return pBase->rxMask;
211 	case EEP_FRAC_N_5G:
212 		return 0;
213 	case EEP_PWR_TABLE_OFFSET:
214 		return AR5416_PWR_TABLE_OFFSET_DB;
215 	default:
216 		return 0;
217 	}
218 }
219 
220 static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
221 				struct ath9k_channel *chan,
222 				struct cal_data_per_freq_4k *pRawDataSet,
223 				u8 *bChans, u16 availPiers,
224 				u16 tPdGainOverlap, int16_t *pMinCalPower,
225 				u16 *pPdGainBoundaries, u8 *pPDADCValues,
226 				u16 numXpdGains)
227 {
228 #define TMP_VAL_VPD_TABLE \
229 	((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
230 	int i, j, k;
231 	int16_t ss;
232 	u16 idxL = 0, idxR = 0, numPiers;
233 	static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
234 		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
235 	static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
236 		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
237 	static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
238 		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
239 
240 	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
241 	u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
242 	u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
243 	int16_t vpdStep;
244 	int16_t tmpVal;
245 	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
246 	bool match;
247 	int16_t minDelta = 0;
248 	struct chan_centers centers;
249 #define PD_GAIN_BOUNDARY_DEFAULT 58;
250 
251 	ath9k_hw_get_channel_centers(ah, chan, &centers);
252 
253 	for (numPiers = 0; numPiers < availPiers; numPiers++) {
254 		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
255 			break;
256 	}
257 
258 	match = ath9k_hw_get_lower_upper_index(
259 					(u8)FREQ2FBIN(centers.synth_center,
260 					IS_CHAN_2GHZ(chan)), bChans, numPiers,
261 					&idxL, &idxR);
262 
263 	if (match) {
264 		for (i = 0; i < numXpdGains; i++) {
265 			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
266 			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
267 			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
268 					pRawDataSet[idxL].pwrPdg[i],
269 					pRawDataSet[idxL].vpdPdg[i],
270 					AR5416_EEP4K_PD_GAIN_ICEPTS,
271 					vpdTableI[i]);
272 		}
273 	} else {
274 		for (i = 0; i < numXpdGains; i++) {
275 			pVpdL = pRawDataSet[idxL].vpdPdg[i];
276 			pPwrL = pRawDataSet[idxL].pwrPdg[i];
277 			pVpdR = pRawDataSet[idxR].vpdPdg[i];
278 			pPwrR = pRawDataSet[idxR].pwrPdg[i];
279 
280 			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
281 
282 			maxPwrT4[i] =
283 				min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
284 				    pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
285 
286 
287 			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
288 						pPwrL, pVpdL,
289 						AR5416_EEP4K_PD_GAIN_ICEPTS,
290 						vpdTableL[i]);
291 			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
292 						pPwrR, pVpdR,
293 						AR5416_EEP4K_PD_GAIN_ICEPTS,
294 						vpdTableR[i]);
295 
296 			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
297 				vpdTableI[i][j] =
298 					(u8)(ath9k_hw_interpolate((u16)
299 					     FREQ2FBIN(centers.
300 						       synth_center,
301 						       IS_CHAN_2GHZ
302 						       (chan)),
303 					     bChans[idxL], bChans[idxR],
304 					     vpdTableL[i][j], vpdTableR[i][j]));
305 			}
306 		}
307 	}
308 
309 	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
310 
311 	k = 0;
312 
313 	for (i = 0; i < numXpdGains; i++) {
314 		if (i == (numXpdGains - 1))
315 			pPdGainBoundaries[i] =
316 				(u16)(maxPwrT4[i] / 2);
317 		else
318 			pPdGainBoundaries[i] =
319 				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
320 
321 		pPdGainBoundaries[i] =
322 			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
323 
324 		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
325 			minDelta = pPdGainBoundaries[0] - 23;
326 			pPdGainBoundaries[0] = 23;
327 		} else {
328 			minDelta = 0;
329 		}
330 
331 		if (i == 0) {
332 			if (AR_SREV_9280_10_OR_LATER(ah))
333 				ss = (int16_t)(0 - (minPwrT4[i] / 2));
334 			else
335 				ss = 0;
336 		} else {
337 			ss = (int16_t)((pPdGainBoundaries[i - 1] -
338 					(minPwrT4[i] / 2)) -
339 				       tPdGainOverlap + 1 + minDelta);
340 		}
341 		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
342 		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
343 
344 		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
345 			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
346 			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
347 			ss++;
348 		}
349 
350 		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
351 		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
352 				(minPwrT4[i] / 2));
353 		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
354 			tgtIndex : sizeCurrVpdTable;
355 
356 		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
357 			pPDADCValues[k++] = vpdTableI[i][ss++];
358 
359 		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
360 				    vpdTableI[i][sizeCurrVpdTable - 2]);
361 		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
362 
363 		if (tgtIndex >= maxIndex) {
364 			while ((ss <= tgtIndex) &&
365 			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
366 				tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
367 				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
368 							 255 : tmpVal);
369 				ss++;
370 			}
371 		}
372 	}
373 
374 	while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
375 		pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
376 		i++;
377 	}
378 
379 	while (k < AR5416_NUM_PDADC_VALUES) {
380 		pPDADCValues[k] = pPDADCValues[k - 1];
381 		k++;
382 	}
383 
384 	return;
385 #undef TMP_VAL_VPD_TABLE
386 }
387 
388 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
389 				  struct ath9k_channel *chan,
390 				  int16_t *pTxPowerIndexOffset)
391 {
392 	struct ath_common *common = ath9k_hw_common(ah);
393 	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
394 	struct cal_data_per_freq_4k *pRawDataset;
395 	u8 *pCalBChans = NULL;
396 	u16 pdGainOverlap_t2;
397 	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
398 	u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
399 	u16 numPiers, i, j;
400 	int16_t tMinCalPower;
401 	u16 numXpdGain, xpdMask;
402 	u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
403 	u32 reg32, regOffset, regChainOffset;
404 
405 	xpdMask = pEepData->modalHeader.xpdGain;
406 
407 	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
408 	    AR5416_EEP_MINOR_VER_2) {
409 		pdGainOverlap_t2 =
410 			pEepData->modalHeader.pdGainOverlap;
411 	} else {
412 		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
413 					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
414 	}
415 
416 	pCalBChans = pEepData->calFreqPier2G;
417 	numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
418 
419 	numXpdGain = 0;
420 
421 	for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
422 		if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
423 			if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
424 				break;
425 			xpdGainValues[numXpdGain] =
426 				(u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
427 			numXpdGain++;
428 		}
429 	}
430 
431 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
432 		      (numXpdGain - 1) & 0x3);
433 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
434 		      xpdGainValues[0]);
435 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
436 		      xpdGainValues[1]);
437 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
438 
439 	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
440 		if (AR_SREV_5416_20_OR_LATER(ah) &&
441 		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
442 		    (i != 0)) {
443 			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
444 		} else
445 			regChainOffset = i * 0x1000;
446 
447 		if (pEepData->baseEepHeader.txMask & (1 << i)) {
448 			pRawDataset = pEepData->calPierData2G[i];
449 
450 			ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
451 					    pRawDataset, pCalBChans,
452 					    numPiers, pdGainOverlap_t2,
453 					    &tMinCalPower, gainBoundaries,
454 					    pdadcValues, numXpdGain);
455 
456 			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
457 				REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
458 					  SM(pdGainOverlap_t2,
459 					     AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
460 					  | SM(gainBoundaries[0],
461 					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
462 					  | SM(gainBoundaries[1],
463 					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
464 					  | SM(gainBoundaries[2],
465 					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
466 					  | SM(gainBoundaries[3],
467 				       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
468 			}
469 
470 			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
471 			for (j = 0; j < 32; j++) {
472 				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
473 					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
474 					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
475 					((pdadcValues[4 * j + 3] & 0xFF) << 24);
476 				REG_WRITE(ah, regOffset, reg32);
477 
478 				ath_print(common, ATH_DBG_EEPROM,
479 					  "PDADC (%d,%4x): %4.4x %8.8x\n",
480 					  i, regChainOffset, regOffset,
481 					  reg32);
482 				ath_print(common, ATH_DBG_EEPROM,
483 					  "PDADC: Chain %d | "
484 					  "PDADC %3d Value %3d | "
485 					  "PDADC %3d Value %3d | "
486 					  "PDADC %3d Value %3d | "
487 					  "PDADC %3d Value %3d |\n",
488 					  i, 4 * j, pdadcValues[4 * j],
489 					  4 * j + 1, pdadcValues[4 * j + 1],
490 					  4 * j + 2, pdadcValues[4 * j + 2],
491 					  4 * j + 3,
492 					  pdadcValues[4 * j + 3]);
493 
494 				regOffset += 4;
495 			}
496 		}
497 	}
498 
499 	*pTxPowerIndexOffset = 0;
500 }
501 
502 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
503 						 struct ath9k_channel *chan,
504 						 int16_t *ratesArray,
505 						 u16 cfgCtl,
506 						 u16 AntennaReduction,
507 						 u16 twiceMaxRegulatoryPower,
508 						 u16 powerLimit)
509 {
510 #define CMP_TEST_GRP \
511 	(((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) ==	\
512 	 pEepData->ctlIndex[i])						\
513 	|| (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
514 	    ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
515 
516 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
517 	int i;
518 	int16_t twiceLargestAntenna;
519 	u16 twiceMinEdgePower;
520 	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
521 	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
522 	u16 numCtlModes, *pCtlMode, ctlMode, freq;
523 	struct chan_centers centers;
524 	struct cal_ctl_data_4k *rep;
525 	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
526 	static const u16 tpScaleReductionTable[5] =
527 		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
528 	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
529 		0, { 0, 0, 0, 0}
530 	};
531 	struct cal_target_power_leg targetPowerOfdmExt = {
532 		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
533 		0, { 0, 0, 0, 0 }
534 	};
535 	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
536 		0, {0, 0, 0, 0}
537 	};
538 	u16 ctlModesFor11g[] =
539 		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
540 		  CTL_2GHT40
541 		};
542 
543 	ath9k_hw_get_channel_centers(ah, chan, &centers);
544 
545 	twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
546 	twiceLargestAntenna = (int16_t)min(AntennaReduction -
547 					   twiceLargestAntenna, 0);
548 
549 	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
550 	if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
551 		maxRegAllowedPower -=
552 			(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
553 	}
554 
555 	scaledPower = min(powerLimit, maxRegAllowedPower);
556 	scaledPower = max((u16)0, scaledPower);
557 
558 	numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
559 	pCtlMode = ctlModesFor11g;
560 
561 	ath9k_hw_get_legacy_target_powers(ah, chan,
562 			pEepData->calTargetPowerCck,
563 			AR5416_NUM_2G_CCK_TARGET_POWERS,
564 			&targetPowerCck, 4, false);
565 	ath9k_hw_get_legacy_target_powers(ah, chan,
566 			pEepData->calTargetPower2G,
567 			AR5416_NUM_2G_20_TARGET_POWERS,
568 			&targetPowerOfdm, 4, false);
569 	ath9k_hw_get_target_powers(ah, chan,
570 			pEepData->calTargetPower2GHT20,
571 			AR5416_NUM_2G_20_TARGET_POWERS,
572 			&targetPowerHt20, 8, false);
573 
574 	if (IS_CHAN_HT40(chan)) {
575 		numCtlModes = ARRAY_SIZE(ctlModesFor11g);
576 		ath9k_hw_get_target_powers(ah, chan,
577 				pEepData->calTargetPower2GHT40,
578 				AR5416_NUM_2G_40_TARGET_POWERS,
579 				&targetPowerHt40, 8, true);
580 		ath9k_hw_get_legacy_target_powers(ah, chan,
581 				pEepData->calTargetPowerCck,
582 				AR5416_NUM_2G_CCK_TARGET_POWERS,
583 				&targetPowerCckExt, 4, true);
584 		ath9k_hw_get_legacy_target_powers(ah, chan,
585 				pEepData->calTargetPower2G,
586 				AR5416_NUM_2G_20_TARGET_POWERS,
587 				&targetPowerOfdmExt, 4, true);
588 	}
589 
590 	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
591 		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
592 			(pCtlMode[ctlMode] == CTL_2GHT40);
593 
594 		if (isHt40CtlMode)
595 			freq = centers.synth_center;
596 		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
597 			freq = centers.ext_center;
598 		else
599 			freq = centers.ctl_center;
600 
601 		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
602 		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
603 			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
604 
605 		for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
606 			     pEepData->ctlIndex[i]; i++) {
607 
608 			if (CMP_TEST_GRP) {
609 				rep = &(pEepData->ctlData[i]);
610 
611 				twiceMinEdgePower = ath9k_hw_get_max_edge_power(
612 					freq,
613 					rep->ctlEdges[
614 					ar5416_get_ntxchains(ah->txchainmask) - 1],
615 					IS_CHAN_2GHZ(chan),
616 					AR5416_EEP4K_NUM_BAND_EDGES);
617 
618 				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
619 					twiceMaxEdgePower =
620 						min(twiceMaxEdgePower,
621 						    twiceMinEdgePower);
622 				} else {
623 					twiceMaxEdgePower = twiceMinEdgePower;
624 					break;
625 				}
626 			}
627 		}
628 
629 		minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
630 
631 		switch (pCtlMode[ctlMode]) {
632 		case CTL_11B:
633 			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
634 				targetPowerCck.tPow2x[i] =
635 					min((u16)targetPowerCck.tPow2x[i],
636 					    minCtlPower);
637 			}
638 			break;
639 		case CTL_11G:
640 			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
641 				targetPowerOfdm.tPow2x[i] =
642 					min((u16)targetPowerOfdm.tPow2x[i],
643 					    minCtlPower);
644 			}
645 			break;
646 		case CTL_2GHT20:
647 			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
648 				targetPowerHt20.tPow2x[i] =
649 					min((u16)targetPowerHt20.tPow2x[i],
650 					    minCtlPower);
651 			}
652 			break;
653 		case CTL_11B_EXT:
654 			targetPowerCckExt.tPow2x[0] =
655 				min((u16)targetPowerCckExt.tPow2x[0],
656 				    minCtlPower);
657 			break;
658 		case CTL_11G_EXT:
659 			targetPowerOfdmExt.tPow2x[0] =
660 				min((u16)targetPowerOfdmExt.tPow2x[0],
661 				    minCtlPower);
662 			break;
663 		case CTL_2GHT40:
664 			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
665 				targetPowerHt40.tPow2x[i] =
666 					min((u16)targetPowerHt40.tPow2x[i],
667 					    minCtlPower);
668 			}
669 			break;
670 		default:
671 			break;
672 		}
673 	}
674 
675 	ratesArray[rate6mb] =
676 	ratesArray[rate9mb] =
677 	ratesArray[rate12mb] =
678 	ratesArray[rate18mb] =
679 	ratesArray[rate24mb] =
680 	targetPowerOfdm.tPow2x[0];
681 
682 	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
683 	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
684 	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
685 	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
686 
687 	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
688 		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
689 
690 	ratesArray[rate1l] = targetPowerCck.tPow2x[0];
691 	ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
692 	ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
693 	ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
694 
695 	if (IS_CHAN_HT40(chan)) {
696 		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
697 			ratesArray[rateHt40_0 + i] =
698 				targetPowerHt40.tPow2x[i];
699 		}
700 		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
701 		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
702 		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
703 		ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
704 	}
705 
706 #undef CMP_TEST_GRP
707 }
708 
709 static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
710 				    struct ath9k_channel *chan,
711 				    u16 cfgCtl,
712 				    u8 twiceAntennaReduction,
713 				    u8 twiceMaxRegulatoryPower,
714 				    u8 powerLimit)
715 {
716 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
717 	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
718 	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
719 	int16_t ratesArray[Ar5416RateSize];
720 	int16_t txPowerIndexOffset = 0;
721 	u8 ht40PowerIncForPdadc = 2;
722 	int i;
723 
724 	memset(ratesArray, 0, sizeof(ratesArray));
725 
726 	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
727 	    AR5416_EEP_MINOR_VER_2) {
728 		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
729 	}
730 
731 	ath9k_hw_set_4k_power_per_rate_table(ah, chan,
732 					     &ratesArray[0], cfgCtl,
733 					     twiceAntennaReduction,
734 					     twiceMaxRegulatoryPower,
735 					     powerLimit);
736 
737 	ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
738 
739 	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
740 		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
741 		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
742 			ratesArray[i] = AR5416_MAX_RATE_POWER;
743 	}
744 
745 
746 	/* Update regulatory */
747 
748 	i = rate6mb;
749 	if (IS_CHAN_HT40(chan))
750 		i = rateHt40_0;
751 	else if (IS_CHAN_HT20(chan))
752 		i = rateHt20_0;
753 
754 	regulatory->max_power_level = ratesArray[i];
755 
756 	if (AR_SREV_9280_10_OR_LATER(ah)) {
757 		for (i = 0; i < Ar5416RateSize; i++)
758 			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
759 	}
760 
761 	/* OFDM power per rate */
762 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
763 		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
764 		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
765 		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
766 		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
767 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
768 		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
769 		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
770 		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
771 		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
772 
773 	/* CCK power per rate */
774 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
775 		  ATH9K_POW_SM(ratesArray[rate2s], 24)
776 		  | ATH9K_POW_SM(ratesArray[rate2l], 16)
777 		  | ATH9K_POW_SM(ratesArray[rateXr], 8)
778 		  | ATH9K_POW_SM(ratesArray[rate1l], 0));
779 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
780 		  ATH9K_POW_SM(ratesArray[rate11s], 24)
781 		  | ATH9K_POW_SM(ratesArray[rate11l], 16)
782 		  | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
783 		  | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
784 
785 	/* HT20 power per rate */
786 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
787 		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
788 		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
789 		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
790 		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
791 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
792 		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
793 		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
794 		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
795 		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
796 
797 	/* HT40 power per rate */
798 	if (IS_CHAN_HT40(chan)) {
799 		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
800 			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
801 				       ht40PowerIncForPdadc, 24)
802 			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
803 					 ht40PowerIncForPdadc, 16)
804 			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
805 					 ht40PowerIncForPdadc, 8)
806 			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
807 					 ht40PowerIncForPdadc, 0));
808 		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
809 			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
810 				       ht40PowerIncForPdadc, 24)
811 			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
812 					 ht40PowerIncForPdadc, 16)
813 			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
814 					 ht40PowerIncForPdadc, 8)
815 			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
816 					 ht40PowerIncForPdadc, 0));
817 		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
818 			  ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
819 			  | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
820 			  | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
821 			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
822 	}
823 }
824 
825 static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
826 				  struct ath9k_channel *chan)
827 {
828 	struct modal_eep_4k_header *pModal;
829 	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
830 	u8 biaslevel;
831 
832 	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
833 		return;
834 
835 	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
836 		return;
837 
838 	pModal = &eep->modalHeader;
839 
840 	if (pModal->xpaBiasLvl != 0xff) {
841 		biaslevel = pModal->xpaBiasLvl;
842 		INI_RA(&ah->iniAddac, 7, 1) =
843 		  (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
844 	}
845 }
846 
847 static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
848 				 struct modal_eep_4k_header *pModal,
849 				 struct ar5416_eeprom_4k *eep,
850 				 u8 txRxAttenLocal)
851 {
852 	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
853 		  pModal->antCtrlChain[0]);
854 
855 	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
856 		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
857 		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
858 		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
859 		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
860 		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
861 
862 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
863 	    AR5416_EEP_MINOR_VER_3) {
864 		txRxAttenLocal = pModal->txRxAttenCh[0];
865 
866 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
867 			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
868 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
869 			      AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
870 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
871 			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
872 			      pModal->xatten2Margin[0]);
873 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
874 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
875 
876 		/* Set the block 1 value to block 0 value */
877 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
878 			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
879 			      pModal->bswMargin[0]);
880 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
881 			      AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
882 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
883 			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
884 			      pModal->xatten2Margin[0]);
885 		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
886 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
887 			      pModal->xatten2Db[0]);
888 	}
889 
890 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
891 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
892 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
893 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
894 
895 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
896 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
897 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
898 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
899 
900 	if (AR_SREV_9285_11(ah))
901 		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
902 }
903 
904 /*
905  * Read EEPROM header info and program the device for correct operation
906  * given the channel value.
907  */
908 static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
909 					 struct ath9k_channel *chan)
910 {
911 	struct modal_eep_4k_header *pModal;
912 	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
913 	u8 txRxAttenLocal;
914 	u8 ob[5], db1[5], db2[5];
915 	u8 ant_div_control1, ant_div_control2;
916 	u32 regVal;
917 
918 	pModal = &eep->modalHeader;
919 	txRxAttenLocal = 23;
920 
921 	REG_WRITE(ah, AR_PHY_SWITCH_COM,
922 		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
923 
924 	/* Single chain for 4K EEPROM*/
925 	ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
926 
927 	/* Initialize Ant Diversity settings from EEPROM */
928 	if (pModal->version >= 3) {
929 		ant_div_control1 = pModal->antdiv_ctl1;
930 		ant_div_control2 = pModal->antdiv_ctl2;
931 
932 		regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
933 		regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
934 
935 		regVal |= SM(ant_div_control1,
936 			     AR_PHY_9285_ANT_DIV_CTL);
937 		regVal |= SM(ant_div_control2,
938 			     AR_PHY_9285_ANT_DIV_ALT_LNACONF);
939 		regVal |= SM((ant_div_control2 >> 2),
940 			     AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
941 		regVal |= SM((ant_div_control1 >> 1),
942 			     AR_PHY_9285_ANT_DIV_ALT_GAINTB);
943 		regVal |= SM((ant_div_control1 >> 2),
944 			     AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
945 
946 
947 		REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
948 		regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
949 		regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
950 		regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
951 		regVal |= SM((ant_div_control1 >> 3),
952 			     AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
953 
954 		REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
955 		regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
956 	}
957 
958 	if (pModal->version >= 2) {
959 		ob[0] = pModal->ob_0;
960 		ob[1] = pModal->ob_1;
961 		ob[2] = pModal->ob_2;
962 		ob[3] = pModal->ob_3;
963 		ob[4] = pModal->ob_4;
964 
965 		db1[0] = pModal->db1_0;
966 		db1[1] = pModal->db1_1;
967 		db1[2] = pModal->db1_2;
968 		db1[3] = pModal->db1_3;
969 		db1[4] = pModal->db1_4;
970 
971 		db2[0] = pModal->db2_0;
972 		db2[1] = pModal->db2_1;
973 		db2[2] = pModal->db2_2;
974 		db2[3] = pModal->db2_3;
975 		db2[4] = pModal->db2_4;
976 	} else if (pModal->version == 1) {
977 		ob[0] = pModal->ob_0;
978 		ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1;
979 		db1[0] = pModal->db1_0;
980 		db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1;
981 		db2[0] = pModal->db2_0;
982 		db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1;
983 	} else {
984 		int i;
985 
986 		for (i = 0; i < 5; i++) {
987 			ob[i] = pModal->ob_0;
988 			db1[i] = pModal->db1_0;
989 			db2[i] = pModal->db1_0;
990 		}
991 	}
992 
993 	if (AR_SREV_9271(ah)) {
994 		ath9k_hw_analog_shift_rmw(ah,
995 					  AR9285_AN_RF2G3,
996 					  AR9271_AN_RF2G3_OB_cck,
997 					  AR9271_AN_RF2G3_OB_cck_S,
998 					  ob[0]);
999 		ath9k_hw_analog_shift_rmw(ah,
1000 					  AR9285_AN_RF2G3,
1001 					  AR9271_AN_RF2G3_OB_psk,
1002 					  AR9271_AN_RF2G3_OB_psk_S,
1003 					  ob[1]);
1004 		ath9k_hw_analog_shift_rmw(ah,
1005 					  AR9285_AN_RF2G3,
1006 					  AR9271_AN_RF2G3_OB_qam,
1007 					  AR9271_AN_RF2G3_OB_qam_S,
1008 					  ob[2]);
1009 		ath9k_hw_analog_shift_rmw(ah,
1010 					  AR9285_AN_RF2G3,
1011 					  AR9271_AN_RF2G3_DB_1,
1012 					  AR9271_AN_RF2G3_DB_1_S,
1013 					  db1[0]);
1014 		ath9k_hw_analog_shift_rmw(ah,
1015 					  AR9285_AN_RF2G4,
1016 					  AR9271_AN_RF2G4_DB_2,
1017 					  AR9271_AN_RF2G4_DB_2_S,
1018 					  db2[0]);
1019 	} else {
1020 		ath9k_hw_analog_shift_rmw(ah,
1021 					  AR9285_AN_RF2G3,
1022 					  AR9285_AN_RF2G3_OB_0,
1023 					  AR9285_AN_RF2G3_OB_0_S,
1024 					  ob[0]);
1025 		ath9k_hw_analog_shift_rmw(ah,
1026 					  AR9285_AN_RF2G3,
1027 					  AR9285_AN_RF2G3_OB_1,
1028 					  AR9285_AN_RF2G3_OB_1_S,
1029 					  ob[1]);
1030 		ath9k_hw_analog_shift_rmw(ah,
1031 					  AR9285_AN_RF2G3,
1032 					  AR9285_AN_RF2G3_OB_2,
1033 					  AR9285_AN_RF2G3_OB_2_S,
1034 					  ob[2]);
1035 		ath9k_hw_analog_shift_rmw(ah,
1036 					  AR9285_AN_RF2G3,
1037 					  AR9285_AN_RF2G3_OB_3,
1038 					  AR9285_AN_RF2G3_OB_3_S,
1039 					  ob[3]);
1040 		ath9k_hw_analog_shift_rmw(ah,
1041 					  AR9285_AN_RF2G3,
1042 					  AR9285_AN_RF2G3_OB_4,
1043 					  AR9285_AN_RF2G3_OB_4_S,
1044 					  ob[4]);
1045 
1046 		ath9k_hw_analog_shift_rmw(ah,
1047 					  AR9285_AN_RF2G3,
1048 					  AR9285_AN_RF2G3_DB1_0,
1049 					  AR9285_AN_RF2G3_DB1_0_S,
1050 					  db1[0]);
1051 		ath9k_hw_analog_shift_rmw(ah,
1052 					  AR9285_AN_RF2G3,
1053 					  AR9285_AN_RF2G3_DB1_1,
1054 					  AR9285_AN_RF2G3_DB1_1_S,
1055 					  db1[1]);
1056 		ath9k_hw_analog_shift_rmw(ah,
1057 					  AR9285_AN_RF2G3,
1058 					  AR9285_AN_RF2G3_DB1_2,
1059 					  AR9285_AN_RF2G3_DB1_2_S,
1060 					  db1[2]);
1061 		ath9k_hw_analog_shift_rmw(ah,
1062 					  AR9285_AN_RF2G4,
1063 					  AR9285_AN_RF2G4_DB1_3,
1064 					  AR9285_AN_RF2G4_DB1_3_S,
1065 					  db1[3]);
1066 		ath9k_hw_analog_shift_rmw(ah,
1067 					  AR9285_AN_RF2G4,
1068 					  AR9285_AN_RF2G4_DB1_4,
1069 					  AR9285_AN_RF2G4_DB1_4_S, db1[4]);
1070 
1071 		ath9k_hw_analog_shift_rmw(ah,
1072 					  AR9285_AN_RF2G4,
1073 					  AR9285_AN_RF2G4_DB2_0,
1074 					  AR9285_AN_RF2G4_DB2_0_S,
1075 					  db2[0]);
1076 		ath9k_hw_analog_shift_rmw(ah,
1077 					  AR9285_AN_RF2G4,
1078 					  AR9285_AN_RF2G4_DB2_1,
1079 					  AR9285_AN_RF2G4_DB2_1_S,
1080 					  db2[1]);
1081 		ath9k_hw_analog_shift_rmw(ah,
1082 					  AR9285_AN_RF2G4,
1083 					  AR9285_AN_RF2G4_DB2_2,
1084 					  AR9285_AN_RF2G4_DB2_2_S,
1085 					  db2[2]);
1086 		ath9k_hw_analog_shift_rmw(ah,
1087 					  AR9285_AN_RF2G4,
1088 					  AR9285_AN_RF2G4_DB2_3,
1089 					  AR9285_AN_RF2G4_DB2_3_S,
1090 					  db2[3]);
1091 		ath9k_hw_analog_shift_rmw(ah,
1092 					  AR9285_AN_RF2G4,
1093 					  AR9285_AN_RF2G4_DB2_4,
1094 					  AR9285_AN_RF2G4_DB2_4_S,
1095 					  db2[4]);
1096 	}
1097 
1098 
1099 	if (AR_SREV_9285_11(ah))
1100 		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1101 
1102 	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1103 		      pModal->switchSettling);
1104 	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1105 		      pModal->adcDesiredSize);
1106 
1107 	REG_WRITE(ah, AR_PHY_RF_CTL4,
1108 		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
1109 		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
1110 		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
1111 		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1112 
1113 	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1114 		      pModal->txEndToRxOn);
1115 
1116 	if (AR_SREV_9271_10(ah))
1117 		REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1118 			      pModal->txEndToRxOn);
1119 	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1120 		      pModal->thresh62);
1121 	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1122 		      pModal->thresh62);
1123 
1124 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1125 						AR5416_EEP_MINOR_VER_2) {
1126 		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
1127 			      pModal->txFrameToDataStart);
1128 		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
1129 			      pModal->txFrameToPaOn);
1130 	}
1131 
1132 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1133 						AR5416_EEP_MINOR_VER_3) {
1134 		if (IS_CHAN_HT40(chan))
1135 			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1136 				      AR_PHY_SETTLING_SWITCH,
1137 				      pModal->swSettleHt40);
1138 	}
1139 }
1140 
1141 static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
1142 					      struct ath9k_channel *chan)
1143 {
1144 	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1145 	struct modal_eep_4k_header *pModal = &eep->modalHeader;
1146 
1147 	return pModal->antCtrlCommon & 0xFFFF;
1148 }
1149 
1150 static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
1151 					 enum ieee80211_band freq_band)
1152 {
1153 	return 1;
1154 }
1155 
1156 static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1157 {
1158 #define EEP_MAP4K_SPURCHAN \
1159 	(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1160 	struct ath_common *common = ath9k_hw_common(ah);
1161 
1162 	u16 spur_val = AR_NO_SPUR;
1163 
1164 	ath_print(common, ATH_DBG_ANI,
1165 		  "Getting spur idx %d is2Ghz. %d val %x\n",
1166 		  i, is2GHz, ah->config.spurchans[i][is2GHz]);
1167 
1168 	switch (ah->config.spurmode) {
1169 	case SPUR_DISABLE:
1170 		break;
1171 	case SPUR_ENABLE_IOCTL:
1172 		spur_val = ah->config.spurchans[i][is2GHz];
1173 		ath_print(common, ATH_DBG_ANI,
1174 			  "Getting spur val from new loc. %d\n", spur_val);
1175 		break;
1176 	case SPUR_ENABLE_EEPROM:
1177 		spur_val = EEP_MAP4K_SPURCHAN;
1178 		break;
1179 	}
1180 
1181 	return spur_val;
1182 
1183 #undef EEP_MAP4K_SPURCHAN
1184 }
1185 
1186 const struct eeprom_ops eep_4k_ops = {
1187 	.check_eeprom		= ath9k_hw_4k_check_eeprom,
1188 	.get_eeprom		= ath9k_hw_4k_get_eeprom,
1189 	.fill_eeprom		= ath9k_hw_4k_fill_eeprom,
1190 	.get_eeprom_ver		= ath9k_hw_4k_get_eeprom_ver,
1191 	.get_eeprom_rev		= ath9k_hw_4k_get_eeprom_rev,
1192 	.get_num_ant_config	= ath9k_hw_4k_get_num_ant_config,
1193 	.get_eeprom_antenna_cfg	= ath9k_hw_4k_get_eeprom_antenna_cfg,
1194 	.set_board_values	= ath9k_hw_4k_set_board_values,
1195 	.set_addac		= ath9k_hw_4k_set_addac,
1196 	.set_txpower		= ath9k_hw_4k_set_txpower,
1197 	.get_spur_channel	= ath9k_hw_4k_get_spur_channel
1198 };
1199