1/*
2 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6/*
7 * Copyright (c) 2008 Atheros Communications Inc.
8 *
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/param.h>
23#include <sys/types.h>
24#include <sys/signal.h>
25#include <sys/stream.h>
26#include <sys/termio.h>
27#include <sys/errno.h>
28#include <sys/file.h>
29#include <sys/cmn_err.h>
30#include <sys/stropts.h>
31#include <sys/strsubr.h>
32#include <sys/strtty.h>
33#include <sys/kbio.h>
34#include <sys/cred.h>
35#include <sys/stat.h>
36#include <sys/consdev.h>
37#include <sys/kmem.h>
38#include <sys/modctl.h>
39#include <sys/ddi.h>
40#include <sys/sunddi.h>
41#include <sys/pci.h>
42#include <sys/errno.h>
43#include <sys/gld.h>
44#include <sys/dlpi.h>
45#include <sys/ethernet.h>
46#include <sys/list.h>
47#include <sys/byteorder.h>
48#include <sys/strsun.h>
49#include <inet/common.h>
50#include <inet/nd.h>
51#include <inet/mi.h>
52#include <inet/wifi_ioctl.h>
53
54#include "arn_core.h"
55#include "arn_hw.h"
56#include "arn_reg.h"
57#include "arn_phy.h"
58
59static void
60ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
61    uint32_t reg, uint32_t mask,
62    uint32_t shift, uint32_t val)
63{
64	uint32_t regVal;
65
66	regVal = REG_READ(ah, reg) & ~mask;
67	regVal |= (val << shift) & mask;
68
69	REG_WRITE(ah, reg, regVal);
70
71	if (ah->ah_config.analog_shiftreg)
72		drv_usecwait(100);
73}
74
75static inline uint16_t
76ath9k_hw_fbin2freq(uint8_t fbin, boolean_t is2GHz)
77{
78
79	if (fbin == AR5416_BCHAN_UNUSED)
80		return (fbin);
81
82	return ((uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)));
83}
84
85static inline int16_t
86ath9k_hw_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
87    int16_t targetLeft, int16_t targetRight)
88{
89	int16_t rv;
90
91	if (srcRight == srcLeft) {
92		rv = targetLeft;
93	} else {
94		rv = (int16_t)(((target - srcLeft) * targetRight +
95		    (srcRight - target) * targetLeft) /
96		    (srcRight - srcLeft));
97	}
98	return (rv);
99}
100
101static inline boolean_t
102ath9k_hw_get_lower_upper_index(uint8_t target, uint8_t *pList,
103    uint16_t listSize, uint16_t *indexL, uint16_t *indexR)
104{
105	uint16_t i;
106
107	if (target <= pList[0]) {
108		*indexL = *indexR = 0;
109		return (B_TRUE);
110	}
111	if (target >= pList[listSize - 1]) {
112		*indexL = *indexR = (uint16_t)(listSize - 1);
113		return (B_TRUE);
114	}
115
116	for (i = 0; i < listSize - 1; i++) {
117		if (pList[i] == target) {
118			*indexL = *indexR = i;
119			return (B_TRUE);
120		}
121		if (target < pList[i + 1]) {
122			*indexL = i;
123			*indexR = (uint16_t)(i + 1);
124			return (B_FALSE);
125		}
126	}
127	return (B_FALSE);
128}
129
130static boolean_t
131ath9k_hw_eeprom_read(struct ath_hal *ah, uint32_t off, uint16_t *data)
132{
133	(void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
134
135	if (!ath9k_hw_wait(ah, AR_EEPROM_STATUS_DATA,
136	    AR_EEPROM_STATUS_DATA_BUSY |
137	    AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
138		return (B_FALSE);
139	}
140
141	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
142	    AR_EEPROM_STATUS_DATA_VAL);
143
144	return (B_TRUE);
145}
146
147/* ARGSUSED */
148static int
149ath9k_hw_flash_map(struct ath_hal *ah)
150{
151	ARN_DBG((ARN_DBG_EEPROM, "arn: ath9k_hw_flash_map(): "
152	    "using flash but eepom\n"));
153
154	return (0);
155}
156
157static boolean_t
158ath9k_hw_flash_read(struct ath_hal *ah, uint32_t off, uint16_t *data)
159{
160	*data = FLASH_READ(ah, off);
161
162	return (B_TRUE);
163}
164
165static inline boolean_t
166ath9k_hw_nvram_read(struct ath_hal *ah, uint32_t off, uint16_t *data)
167{
168	if (ath9k_hw_use_flash(ah))
169		return (ath9k_hw_flash_read(ah, off, data));
170	else
171		return (ath9k_hw_eeprom_read(ah, off, data));
172}
173
174static boolean_t
175ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
176{
177#define	SIZE_EEPROM_4K	(sizeof (struct ar5416_eeprom_4k) / sizeof (uint16_t))
178	struct ath_hal_5416 *ahp = AH5416(ah);
179	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
180	uint16_t *eep_data;
181	int addr, eep_start_loc = 0;
182
183	eep_start_loc = 64;
184
185	if (!ath9k_hw_use_flash(ah)) {
186		ARN_DBG((ARN_DBG_EEPROM,
187		    "Reading from EEPROM, not flash\n"));
188	}
189
190	eep_data = (uint16_t *)eep;
191
192	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
193		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
194			ARN_DBG((ARN_DBG_EEPROM,
195			    "Unable to read eeprom region \n"));
196			return (B_FALSE);
197		}
198		eep_data++;
199	}
200	return (B_TRUE);
201#undef SIZE_EEPROM_4K
202}
203
204static boolean_t
205ath9k_hw_fill_def_eeprom(struct ath_hal *ah)
206{
207#define	SIZE_EEPROM_DEF	(sizeof (struct ar5416_eeprom_def) / sizeof (uint16_t))
208	struct ath_hal_5416 *ahp = AH5416(ah);
209	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
210	uint16_t *eep_data;
211	int addr, ar5416_eep_start_loc = 0x100;
212
213	eep_data = (uint16_t *)eep;
214
215	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
216		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
217		    eep_data)) {
218			ARN_DBG((ARN_DBG_EEPROM,
219			    "Unable to read eeprom region\n"));
220			return (B_FALSE);
221		}
222		eep_data++;
223	}
224	return (B_TRUE);
225#undef SIZE_EEPROM_DEF
226}
227
228static boolean_t (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
229	ath9k_hw_fill_def_eeprom,
230	ath9k_hw_fill_4k_eeprom
231};
232
233static inline boolean_t
234ath9k_hw_fill_eeprom(struct ath_hal *ah)
235{
236	struct ath_hal_5416 *ahp = AH5416(ah);
237
238	return (ath9k_fill_eeprom[ahp->ah_eep_map](ah));
239}
240
241static int
242ath9k_hw_check_def_eeprom(struct ath_hal *ah)
243{
244	struct ath_hal_5416 *ahp = AH5416(ah);
245	struct ar5416_eeprom_def *eep =
246	    (struct ar5416_eeprom_def *)&ahp->ah_eeprom.def;
247	uint16_t *eepdata, temp, magic, magic2;
248	uint32_t sum = 0, el;
249	boolean_t need_swap = B_FALSE;
250	int i, addr, size;
251	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
252		ARN_DBG((ARN_DBG_EEPROM, "arn: "
253		    "%s: Reading Magic # failed\n", __func__));
254		return (B_FALSE);
255	}
256
257	if (!ath9k_hw_use_flash(ah)) {
258		ARN_DBG((ARN_DBG_EEPROM, "ath9k: "
259		    "%s: Read Magic = 0x%04X\n", __func__, magic));
260
261		if (magic != AR5416_EEPROM_MAGIC) {
262			magic2 = swab16(magic);
263
264			if (magic2 == AR5416_EEPROM_MAGIC) {
265				size = sizeof (struct ar5416_eeprom_def);
266				need_swap = B_TRUE;
267				eepdata = (uint16_t *)(&ahp->ah_eeprom);
268
269				for (addr = 0; addr < size / sizeof (uint16_t);
270				    addr++) {
271					temp = swab16(*eepdata);
272					*eepdata = temp;
273					eepdata++;
274
275					ARN_DBG((ARN_DBG_EEPROM,
276					    "0x%04X  ", *eepdata));
277
278					if (((addr + 1) % 6) == 0)
279						ARN_DBG((ARN_DBG_EEPROM,
280						    "arn: "
281						    "%s\n", __func__));
282				}
283			} else {
284				ARN_DBG((ARN_DBG_EEPROM,
285				    "Invalid EEPROM Magic. "
286				    "endianness mismatch.\n"));
287				return (EINVAL);
288			}
289		}
290	}
291
292	ARN_DBG((ARN_DBG_EEPROM, "need_swap = %s.\n",
293	    need_swap ? "TRUE" : "FALSE"));
294
295	if (need_swap)
296		el = swab16(ahp->ah_eeprom.def.baseEepHeader.length);
297	else
298		el = ahp->ah_eeprom.def.baseEepHeader.length;
299
300	if (el > sizeof (struct ar5416_eeprom_def))
301		el = sizeof (struct ar5416_eeprom_def) / sizeof (uint16_t);
302	else
303		el = el / sizeof (uint16_t);
304
305	eepdata = (uint16_t *)(&ahp->ah_eeprom);
306
307	for (i = 0; i < el; i++)
308		sum ^= *eepdata++;
309
310	if (need_swap) {
311		uint32_t integer, j;
312		uint16_t word;
313
314		ARN_DBG((ARN_DBG_EEPROM,
315		    "EEPROM Endianness is not native.. Changing \n"));
316
317		word = swab16(eep->baseEepHeader.length);
318		eep->baseEepHeader.length = word;
319
320		word = swab16(eep->baseEepHeader.checksum);
321		eep->baseEepHeader.checksum = word;
322
323		word = swab16(eep->baseEepHeader.version);
324		eep->baseEepHeader.version = word;
325
326		word = swab16(eep->baseEepHeader.regDmn[0]);
327		eep->baseEepHeader.regDmn[0] = word;
328
329		word = swab16(eep->baseEepHeader.regDmn[1]);
330		eep->baseEepHeader.regDmn[1] = word;
331
332		word = swab16(eep->baseEepHeader.rfSilent);
333		eep->baseEepHeader.rfSilent = word;
334
335		word = swab16(eep->baseEepHeader.blueToothOptions);
336		eep->baseEepHeader.blueToothOptions = word;
337
338		word = swab16(eep->baseEepHeader.deviceCap);
339		eep->baseEepHeader.deviceCap = word;
340
341		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
342			struct modal_eep_header *pModal =
343			    &eep->modalHeader[j];
344			integer = swab32(pModal->antCtrlCommon);
345			pModal->antCtrlCommon = integer;
346
347			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
348				integer = swab32(pModal->antCtrlChain[i]);
349				pModal->antCtrlChain[i] = integer;
350			}
351
352			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
353				word = swab16(pModal->spurChans[i].spurChan);
354				pModal->spurChans[i].spurChan = word;
355			}
356		}
357	}
358
359	if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
360	    ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
361		ARN_DBG((ARN_DBG_EEPROM,
362		    "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
363		    sum, ar5416_get_eep_ver(ahp)));
364		return (EINVAL);
365	}
366
367	return (0);
368}
369
370static int
371ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
372{
373#define	EEPROM_4K_SIZE	(sizeof (struct ar5416_eeprom_4k) / sizeof (uint16_t))
374	struct ath_hal_5416 *ahp = AH5416(ah);
375	struct ar5416_eeprom_4k *eep =
376	    (struct ar5416_eeprom_4k *)&ahp->ah_eeprom.map4k;
377	uint16_t *eepdata, temp, magic, magic2;
378	uint32_t sum = 0, el;
379	boolean_t need_swap = B_FALSE;
380	int i, addr;
381
382
383	if (!ath9k_hw_use_flash(ah)) {
384
385		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
386		    &magic)) {
387			ARN_DBG((ARN_DBG_EEPROM,
388			    "Reading Magic # failed\n"));
389			return (B_FALSE);
390		}
391
392		ARN_DBG((ARN_DBG_EEPROM,
393		    "Read Magic = 0x%04X\n", magic));
394
395		if (magic != AR5416_EEPROM_MAGIC) {
396			magic2 = swab16(magic);
397
398			if (magic2 == AR5416_EEPROM_MAGIC) {
399				need_swap = B_TRUE;
400				eepdata = (uint16_t *)(&ahp->ah_eeprom);
401
402				for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
403					temp = swab16(*eepdata);
404					*eepdata = temp;
405					eepdata++;
406
407					ARN_DBG((ARN_DBG_EEPROM,
408					    "0x%04X  ", *eepdata));
409
410					if (((addr + 1) % 6) == 0)
411						ARN_DBG((ARN_DBG_EEPROM, "\n"));
412				}
413			} else {
414				ARN_DBG((ARN_DBG_EEPROM,
415				    "Invalid EEPROM Magic. "
416				    "endianness mismatch.\n"));
417				return (EINVAL);
418			}
419		}
420	}
421
422	ARN_DBG((ARN_DBG_EEPROM, "need_swap = %s.\n",
423	    need_swap ? "True" : "False"));
424
425	if (need_swap)
426		el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length);
427	else
428		el = ahp->ah_eeprom.map4k.baseEepHeader.length;
429
430	if (el > sizeof (struct ar5416_eeprom_def))
431		el = sizeof (struct ar5416_eeprom_4k) / sizeof (uint16_t);
432	else
433		el = el / sizeof (uint16_t);
434
435	eepdata = (uint16_t *)(&ahp->ah_eeprom);
436
437	for (i = 0; i < el; i++)
438		sum ^= *eepdata++;
439
440	if (need_swap) {
441		uint32_t integer;
442		uint16_t word;
443
444		ARN_DBG((ARN_DBG_EEPROM,
445		    "EEPROM Endianness is not native.. Changing \n"));
446
447		word = swab16(eep->baseEepHeader.length);
448		eep->baseEepHeader.length = word;
449
450		word = swab16(eep->baseEepHeader.checksum);
451		eep->baseEepHeader.checksum = word;
452
453		word = swab16(eep->baseEepHeader.version);
454		eep->baseEepHeader.version = word;
455
456		word = swab16(eep->baseEepHeader.regDmn[0]);
457		eep->baseEepHeader.regDmn[0] = word;
458
459		word = swab16(eep->baseEepHeader.regDmn[1]);
460		eep->baseEepHeader.regDmn[1] = word;
461
462		word = swab16(eep->baseEepHeader.rfSilent);
463		eep->baseEepHeader.rfSilent = word;
464
465		word = swab16(eep->baseEepHeader.blueToothOptions);
466		eep->baseEepHeader.blueToothOptions = word;
467
468		word = swab16(eep->baseEepHeader.deviceCap);
469		eep->baseEepHeader.deviceCap = word;
470
471		integer = swab32(eep->modalHeader.antCtrlCommon);
472		eep->modalHeader.antCtrlCommon = integer;
473
474		for (i = 0; i < AR5416_MAX_CHAINS; i++) {
475			integer = swab32(eep->modalHeader.antCtrlChain[i]);
476			eep->modalHeader.antCtrlChain[i] = integer;
477		}
478
479		for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
480			word = swab16(eep->modalHeader.spurChans[i].spurChan);
481			eep->modalHeader.spurChans[i].spurChan = word;
482		}
483	}
484
485	if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER ||
486	    ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
487		ARN_DBG((ARN_DBG_EEPROM,
488		    "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
489		    sum, ar5416_get_eep4k_ver(ahp)));
490		return (EINVAL);
491	}
492
493	return (0);
494#undef EEPROM_4K_SIZE
495}
496
497static int
498(*ath9k_check_eeprom[]) (struct ath_hal *) = {
499    ath9k_hw_check_def_eeprom,
500    ath9k_hw_check_4k_eeprom
501};
502
503static inline int
504ath9k_hw_check_eeprom(struct ath_hal *ah)
505{
506	struct ath_hal_5416 *ahp = AH5416(ah);
507
508	return (ath9k_check_eeprom[ahp->ah_eep_map](ah));
509}
510
511static inline boolean_t
512ath9k_hw_fill_vpd_table(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
513    uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
514{
515	uint16_t i, k;
516	uint8_t currPwr = pwrMin;
517	uint16_t idxL = 0, idxR = 0;
518
519	for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
520		(void) ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
521		    numIntercepts, &(idxL), &(idxR));
522		if (idxR < 1)
523			idxR = 1;
524		if (idxL == numIntercepts - 1)
525			idxL = (uint16_t)(numIntercepts - 2);
526		if (pPwrList[idxL] == pPwrList[idxR])
527			k = pVpdList[idxL];
528		else
529			k = (uint16_t)
530			    (((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
531			    (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
532			    (pPwrList[idxR] - pPwrList[idxL]));
533		pRetVpdList[i] = (uint8_t)k;
534		currPwr += 2;
535	}
536
537	return (B_TRUE);
538}
539
540static void
541ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
542    struct ath9k_channel *chan,
543    struct cal_data_per_freq_4k *pRawDataSet,
544    uint8_t *bChans, uint16_t availPiers,
545    uint16_t tPdGainOverlap, int16_t *pMinCalPower,
546    uint16_t *pPdGainBoundaries, uint8_t *pPDADCValues,
547    uint16_t numXpdGains)
548{
549#define	TMP_VAL_VPD_TABLE \
550	((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
551	int i, j, k;
552	int16_t ss;
553	uint16_t idxL = 0, idxR = 0, numPiers;
554	static uint8_t vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
555	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
556	static uint8_t vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
557	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
558	static uint8_t vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
559	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
560
561	uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR;
562	uint8_t minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
563	uint8_t maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
564	int16_t vpdStep;
565	int16_t tmpVal;
566	uint16_t sizeCurrVpdTable, maxIndex, tgtIndex;
567	boolean_t match;
568	int16_t minDelta = 0;
569	struct chan_centers centers;
570#define	PD_GAIN_BOUNDARY_DEFAULT	58;
571
572	ath9k_hw_get_channel_centers(ah, chan, &centers);
573
574	for (numPiers = 0; numPiers < availPiers; numPiers++) {
575		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
576			break;
577	}
578
579	match = ath9k_hw_get_lower_upper_index(
580	    (uint8_t)FREQ2FBIN(centers.synth_center,
581	    IS_CHAN_2GHZ(chan)), bChans, numPiers,
582	    &idxL, &idxR);
583
584	if (match) {
585		for (i = 0; i < numXpdGains; i++) {
586			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
587			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
588			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
589			    pRawDataSet[idxL].pwrPdg[i],
590			    pRawDataSet[idxL].vpdPdg[i],
591			    AR5416_EEP4K_PD_GAIN_ICEPTS,
592			    vpdTableI[i]);
593		}
594	} else {
595		for (i = 0; i < numXpdGains; i++) {
596			pVpdL = pRawDataSet[idxL].vpdPdg[i];
597			pPwrL = pRawDataSet[idxL].pwrPdg[i];
598			pVpdR = pRawDataSet[idxR].vpdPdg[i];
599			pPwrR = pRawDataSet[idxR].pwrPdg[i];
600
601			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
602
603			maxPwrT4[i] =
604			    min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
605			    pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
606
607
608			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
609			    pPwrL, pVpdL,
610			    AR5416_EEP4K_PD_GAIN_ICEPTS,
611			    vpdTableL[i]);
612			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
613			    pPwrR, pVpdR,
614			    AR5416_EEP4K_PD_GAIN_ICEPTS,
615			    vpdTableR[i]);
616
617			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
618				vpdTableI[i][j] =
619				    (uint8_t)(ath9k_hw_interpolate((uint16_t)
620				    FREQ2FBIN(centers.
621				    synth_center,
622				    IS_CHAN_2GHZ
623				    (chan)),
624				    bChans[idxL], bChans[idxR],
625				    vpdTableL[i][j], vpdTableR[i][j]));
626			}
627		}
628	}
629
630	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
631
632	k = 0;
633
634	for (i = 0; i < numXpdGains; i++) {
635		if (i == (numXpdGains - 1))
636			pPdGainBoundaries[i] =
637			    (uint16_t)(maxPwrT4[i] / 2);
638		else
639			pPdGainBoundaries[i] =
640			    (uint16_t)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
641
642		pPdGainBoundaries[i] =
643		    min((uint16_t)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
644
645		if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
646			minDelta = pPdGainBoundaries[0] - 23;
647			pPdGainBoundaries[0] = 23;
648		} else {
649			minDelta = 0;
650		}
651
652		if (i == 0) {
653			if (AR_SREV_9280_10_OR_LATER(ah))
654				ss = (int16_t)(0 - (minPwrT4[i] / 2));
655			else
656				ss = 0;
657		} else {
658			ss = (int16_t)((pPdGainBoundaries[i - 1] -
659			    (minPwrT4[i] / 2)) -
660			    tPdGainOverlap + 1 + minDelta);
661		}
662		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
663		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
664
665		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
666			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
667			pPDADCValues[k++] =
668			    (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
669			ss++;
670		}
671
672		sizeCurrVpdTable =
673		    (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
674		tgtIndex = (uint8_t)
675		    (pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));
676		maxIndex =
677		    (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
678
679		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
680			pPDADCValues[k++] = vpdTableI[i][ss++];
681
682		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
683		    vpdTableI[i][sizeCurrVpdTable - 2]);
684		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
685
686		if (tgtIndex > maxIndex) {
687			while ((ss <= tgtIndex) &&
688			    (k < (AR5416_NUM_PDADC_VALUES - 1))) {
689				tmpVal = (int16_t)TMP_VAL_VPD_TABLE;
690				pPDADCValues[k++] = (uint8_t)
691				    ((tmpVal > 255) ? 255 : tmpVal);
692				ss++;
693			}
694		}
695	}
696
697	while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
698		pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
699		i++;
700	}
701
702	while (k < AR5416_NUM_PDADC_VALUES) {
703		pPDADCValues[k] = pPDADCValues[k - 1];
704		k++;
705	}
706
707	return;
708#undef TMP_VAL_VPD_TABLE
709}
710
711static void
712ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah,
713    struct ath9k_channel *chan,
714    struct cal_data_per_freq *pRawDataSet,
715    uint8_t *bChans, uint16_t availPiers,
716    uint16_t tPdGainOverlap, int16_t *pMinCalPower,
717    uint16_t *pPdGainBoundaries, uint8_t *pPDADCValues,
718    uint16_t numXpdGains)
719{
720	int i, j, k;
721	int16_t ss;
722	uint16_t idxL = 0, idxR = 0, numPiers;
723	static uint8_t vpdTableL[AR5416_NUM_PD_GAINS]
724	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
725	static uint8_t vpdTableR[AR5416_NUM_PD_GAINS]
726	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
727	static uint8_t vpdTableI[AR5416_NUM_PD_GAINS]
728	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
729
730	uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR;
731	uint8_t minPwrT4[AR5416_NUM_PD_GAINS];
732	uint8_t maxPwrT4[AR5416_NUM_PD_GAINS];
733	int16_t vpdStep;
734	int16_t tmpVal;
735	uint16_t sizeCurrVpdTable, maxIndex, tgtIndex;
736	boolean_t match;
737	int16_t minDelta = 0;
738	struct chan_centers centers;
739
740	ath9k_hw_get_channel_centers(ah, chan, &centers);
741
742	for (numPiers = 0; numPiers < availPiers; numPiers++) {
743		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
744			break;
745	}
746
747	match =
748	    ath9k_hw_get_lower_upper_index(
749	    (uint8_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
750	    bChans, numPiers, &idxL, &idxR);
751
752	if (match) {
753		for (i = 0; i < numXpdGains; i++) {
754			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
755			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
756			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
757			    pRawDataSet[idxL].pwrPdg[i],
758			    pRawDataSet[idxL].vpdPdg[i],
759			    AR5416_PD_GAIN_ICEPTS,
760			    vpdTableI[i]);
761		}
762	} else {
763		for (i = 0; i < numXpdGains; i++) {
764			pVpdL = pRawDataSet[idxL].vpdPdg[i];
765			pPwrL = pRawDataSet[idxL].pwrPdg[i];
766			pVpdR = pRawDataSet[idxR].vpdPdg[i];
767			pPwrR = pRawDataSet[idxR].pwrPdg[i];
768
769			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
770
771			maxPwrT4[i] =
772			    min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
773			    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
774
775
776			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
777			    pPwrL, pVpdL,
778			    AR5416_PD_GAIN_ICEPTS,
779			    vpdTableL[i]);
780			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
781			    pPwrR, pVpdR,
782			    AR5416_PD_GAIN_ICEPTS,
783			    vpdTableR[i]);
784
785			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
786				vpdTableI[i][j] =
787				    (uint8_t)(ath9k_hw_interpolate((uint16_t)
788				    FREQ2FBIN(centers.
789				    synth_center,
790				    IS_CHAN_2GHZ
791				    (chan)),
792				    bChans[idxL], bChans[idxR],
793				    vpdTableL[i][j], vpdTableR[i][j]));
794			}
795		}
796	}
797
798	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
799
800	k = 0;
801
802	for (i = 0; i < numXpdGains; i++) {
803		if (i == (numXpdGains - 1))
804			pPdGainBoundaries[i] =
805			    (uint16_t)(maxPwrT4[i] / 2);
806		else
807			pPdGainBoundaries[i] =
808			    (uint16_t)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
809
810		pPdGainBoundaries[i] =
811		    min((uint16_t)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
812
813		if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
814			minDelta = pPdGainBoundaries[0] - 23;
815			pPdGainBoundaries[0] = 23;
816		} else {
817			minDelta = 0;
818		}
819
820		if (i == 0) {
821			if (AR_SREV_9280_10_OR_LATER(ah))
822				ss = (int16_t)(0 - (minPwrT4[i] / 2));
823			else
824				ss = 0;
825		} else {
826			ss = (int16_t)((pPdGainBoundaries[i - 1] -
827			    (minPwrT4[i] / 2)) -
828			    tPdGainOverlap + 1 + minDelta);
829		}
830		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
831		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
832
833		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
834			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
835			pPDADCValues[k++] =
836			    (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
837			ss++;
838		}
839
840		sizeCurrVpdTable =
841		    (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
842		tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap -
843		    (minPwrT4[i] / 2));
844		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
845		    tgtIndex : sizeCurrVpdTable;
846
847		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
848			pPDADCValues[k++] = vpdTableI[i][ss++];
849		}
850
851		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
852		    vpdTableI[i][sizeCurrVpdTable - 2]);
853		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
854
855		if (tgtIndex > maxIndex) {
856			while ((ss <= tgtIndex) &&
857			    (k < (AR5416_NUM_PDADC_VALUES - 1))) {
858				tmpVal =
859				    (int16_t)
860				    ((vpdTableI[i][sizeCurrVpdTable - 1] +
861				    (ss - maxIndex + 1) * vpdStep));
862				pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ?
863				    255 : tmpVal);
864				ss++;
865			}
866		}
867	}
868
869	while (i < AR5416_PD_GAINS_IN_MASK) {
870		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
871		i++;
872	}
873
874	while (k < AR5416_NUM_PDADC_VALUES) {
875		pPDADCValues[k] = pPDADCValues[k - 1];
876		k++;
877	}
878}
879
880static void
881ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
882    struct ath9k_channel *chan,
883    struct cal_target_power_leg *powInfo,
884    uint16_t numChannels,
885    struct cal_target_power_leg *pNewPower,
886    uint16_t numRates, boolean_t isExtTarget)
887{
888	struct chan_centers centers;
889	uint16_t clo, chi;
890	int i;
891	int matchIndex = -1, lowIndex = -1;
892	uint16_t freq;
893
894	ath9k_hw_get_channel_centers(ah, chan, &centers);
895	freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
896
897	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
898	    IS_CHAN_2GHZ(chan))) {
899		matchIndex = 0;
900	} else {
901		for (i = 0; (i < numChannels) &&
902		    (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
903			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
904			    IS_CHAN_2GHZ(chan))) {
905				matchIndex = i;
906				break;
907			} else if ((freq <
908			    ath9k_hw_fbin2freq(powInfo[i].bChannel,
909			    IS_CHAN_2GHZ(chan))) &&
910			    (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
911			    IS_CHAN_2GHZ(chan)))) {
912				lowIndex = i - 1;
913				break;
914			}
915		}
916		if ((matchIndex == -1) && (lowIndex == -1))
917			matchIndex = i - 1;
918	}
919
920	if (matchIndex != -1) {
921		*pNewPower = powInfo[matchIndex];
922	} else {
923		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
924		    IS_CHAN_2GHZ(chan));
925		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
926		    IS_CHAN_2GHZ(chan));
927
928		for (i = 0; i < numRates; i++) {
929			pNewPower->tPow2x[i] =
930			    (uint8_t)ath9k_hw_interpolate(freq, clo, chi,
931			    powInfo[lowIndex].tPow2x[i],
932			    powInfo[lowIndex + 1].tPow2x[i]);
933		}
934	}
935}
936
937static void
938ath9k_hw_get_target_powers(struct ath_hal *ah,
939    struct ath9k_channel *chan,
940    struct cal_target_power_ht *powInfo,
941    uint16_t numChannels,
942    struct cal_target_power_ht *pNewPower,
943    uint16_t numRates, boolean_t isHt40Target)
944{
945	struct chan_centers centers;
946	uint16_t clo, chi;
947	int i;
948	int matchIndex = -1, lowIndex = -1;
949	uint16_t freq;
950
951	ath9k_hw_get_channel_centers(ah, chan, &centers);
952	freq = isHt40Target ? centers.synth_center : centers.ctl_center;
953
954	if (freq <=
955	    ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
956		matchIndex = 0;
957	} else {
958		for (i = 0; (i < numChannels) &&
959		    (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
960			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
961			    IS_CHAN_2GHZ(chan))) {
962				matchIndex = i;
963				break;
964			} else
965				if ((freq <
966				    ath9k_hw_fbin2freq(powInfo[i].bChannel,
967				    IS_CHAN_2GHZ(chan))) &&
968				    (freq > ath9k_hw_fbin2freq
969				    (powInfo[i - 1].bChannel,
970				    IS_CHAN_2GHZ(chan)))) {
971					lowIndex = i - 1;
972					break;
973				}
974		}
975		if ((matchIndex == -1) && (lowIndex == -1))
976			matchIndex = i - 1;
977	}
978
979	if (matchIndex != -1) {
980		*pNewPower = powInfo[matchIndex];
981	} else {
982		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
983		    IS_CHAN_2GHZ(chan));
984		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
985		    IS_CHAN_2GHZ(chan));
986
987		for (i = 0; i < numRates; i++) {
988			pNewPower->tPow2x[i] =
989			    (uint8_t)ath9k_hw_interpolate(freq,
990			    clo, chi,
991			    powInfo[lowIndex].tPow2x[i],
992			    powInfo[lowIndex + 1].tPow2x[i]);
993		}
994	}
995}
996
997static uint16_t
998ath9k_hw_get_max_edge_power(uint16_t freq,
999    struct cal_ctl_edges *pRdEdgesPower,
1000    boolean_t is2GHz, int num_band_edges)
1001{
1002	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1003	int i;
1004
1005	for (i = 0; (i < num_band_edges) &&
1006	    (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
1007		if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
1008		    is2GHz)) {
1009			twiceMaxEdgePower = pRdEdgesPower[i].tPower;
1010			break;
1011		} else if ((i > 0) &&
1012		    (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
1013		    is2GHz))) {
1014			if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
1015			    is2GHz) < freq &&
1016			    pRdEdgesPower[i - 1].flag) {
1017				twiceMaxEdgePower =
1018				    pRdEdgesPower[i - 1].tPower;
1019			}
1020			break;
1021		}
1022	}
1023
1024	return (twiceMaxEdgePower);
1025}
1026
1027static boolean_t
1028ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
1029    struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset)
1030{
1031	struct ath_hal_5416 *ahp = AH5416(ah);
1032	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
1033	struct cal_data_per_freq *pRawDataset;
1034	uint8_t *pCalBChans = NULL;
1035	uint16_t pdGainOverlap_t2;
1036	static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES];
1037	uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
1038	uint16_t numPiers, i, j;
1039	int16_t tMinCalPower;
1040	uint16_t numXpdGain, xpdMask;
1041	uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
1042	uint32_t reg32, regOffset, regChainOffset;
1043	int16_t modalIdx;
1044
1045	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
1046	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
1047
1048	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1049	    AR5416_EEP_MINOR_VER_2) {
1050		pdGainOverlap_t2 =
1051		    pEepData->modalHeader[modalIdx].pdGainOverlap;
1052	} else {
1053		pdGainOverlap_t2 =
1054		    (uint16_t)(MS(REG_READ(ah, AR_PHY_TPCRG5),
1055		    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
1056	}
1057
1058	if (IS_CHAN_2GHZ(chan)) {
1059		pCalBChans = pEepData->calFreqPier2G;
1060		numPiers = AR5416_NUM_2G_CAL_PIERS;
1061	} else {
1062		pCalBChans = pEepData->calFreqPier5G;
1063		numPiers = AR5416_NUM_5G_CAL_PIERS;
1064	}
1065
1066	numXpdGain = 0;
1067
1068	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
1069		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
1070			if (numXpdGain >= AR5416_NUM_PD_GAINS)
1071				break;
1072			xpdGainValues[numXpdGain] =
1073			    (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
1074			numXpdGain++;
1075		}
1076	}
1077
1078	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
1079	    (numXpdGain - 1) & 0x3);
1080	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
1081	    xpdGainValues[0]);
1082	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
1083	    xpdGainValues[1]);
1084	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
1085	    xpdGainValues[2]);
1086
1087	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1088		if (AR_SREV_5416_V20_OR_LATER(ah) &&
1089		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
1090		    (i != 0)) {
1091			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1092		} else
1093			regChainOffset = i * 0x1000;
1094
1095		if (pEepData->baseEepHeader.txMask & (1 << i)) {
1096			if (IS_CHAN_2GHZ(chan))
1097				pRawDataset = pEepData->calPierData2G[i];
1098			else
1099				pRawDataset = pEepData->calPierData5G[i];
1100
1101			ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
1102			    pRawDataset, pCalBChans,
1103			    numPiers, pdGainOverlap_t2,
1104			    &tMinCalPower, gainBoundaries,
1105			    pdadcValues, numXpdGain);
1106
1107			if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
1108				REG_WRITE(ah,
1109				    AR_PHY_TPCRG5 + regChainOffset,
1110				    SM(pdGainOverlap_t2,
1111				    AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
1112				    SM(gainBoundaries[0],
1113				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |
1114				    SM(gainBoundaries[1],
1115				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |
1116				    SM(gainBoundaries[2],
1117				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |
1118				    SM(gainBoundaries[3],
1119				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
1120			}
1121
1122			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
1123			for (j = 0; j < 32; j++) {
1124				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
1125				    ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
1126				    ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
1127				    ((pdadcValues[4 * j + 3] & 0xFF) << 24);
1128				REG_WRITE(ah, regOffset, reg32);
1129
1130				ARN_DBG((ARN_DBG_REG_IO,
1131				    "PDADC (%d,%4x): %4.4x %8.8x\n",
1132				    i, regChainOffset, regOffset,
1133				    reg32));
1134				ARN_DBG((ARN_DBG_REG_IO,
1135				    "PDADC: Chain %d | PDADC %3d "
1136				    "Value %3d | PDADC %3d Value %3d | "
1137				    "PDADC %3d Value %3d | PDADC %3d "
1138				    "Value %3d |\n",
1139				    i, 4 * j, pdadcValues[4 * j],
1140				    4 * j + 1, pdadcValues[4 * j + 1],
1141				    4 * j + 2, pdadcValues[4 * j + 2],
1142				    4 * j + 3,
1143				    pdadcValues[4 * j + 3]));
1144
1145				regOffset += 4;
1146			}
1147		}
1148	}
1149
1150	*pTxPowerIndexOffset = 0;
1151
1152	return (B_TRUE);
1153}
1154
1155static boolean_t
1156ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
1157    struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset)
1158{
1159	struct ath_hal_5416 *ahp = AH5416(ah);
1160	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
1161	struct cal_data_per_freq_4k *pRawDataset;
1162	uint8_t *pCalBChans = NULL;
1163	uint16_t pdGainOverlap_t2;
1164	static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES];
1165	uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
1166	uint16_t numPiers, i, j;
1167	int16_t tMinCalPower;
1168	uint16_t numXpdGain, xpdMask;
1169	uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
1170	uint32_t reg32, regOffset, regChainOffset;
1171
1172	xpdMask = pEepData->modalHeader.xpdGain;
1173
1174	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1175	    AR5416_EEP_MINOR_VER_2) {
1176		pdGainOverlap_t2 =
1177		    pEepData->modalHeader.pdGainOverlap;
1178	} else {
1179		pdGainOverlap_t2 = (uint16_t)(MS(REG_READ(ah, AR_PHY_TPCRG5),
1180		    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
1181	}
1182
1183	pCalBChans = pEepData->calFreqPier2G;
1184	numPiers = AR5416_NUM_2G_CAL_PIERS;
1185
1186	numXpdGain = 0;
1187
1188	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
1189		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
1190			if (numXpdGain >= AR5416_NUM_PD_GAINS)
1191				break;
1192			xpdGainValues[numXpdGain] =
1193			    (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
1194			numXpdGain++;
1195		}
1196	}
1197
1198	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
1199	    (numXpdGain - 1) & 0x3);
1200	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
1201	    xpdGainValues[0]);
1202	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
1203	    xpdGainValues[1]);
1204	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
1205	    xpdGainValues[2]);
1206
1207	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1208		if (AR_SREV_5416_V20_OR_LATER(ah) &&
1209		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
1210		    (i != 0)) {
1211			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1212		} else
1213			regChainOffset = i * 0x1000;
1214
1215		if (pEepData->baseEepHeader.txMask & (1 << i)) {
1216			pRawDataset = pEepData->calPierData2G[i];
1217
1218			ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
1219			    pRawDataset, pCalBChans,
1220			    numPiers, pdGainOverlap_t2,
1221			    &tMinCalPower, gainBoundaries,
1222			    pdadcValues, numXpdGain);
1223
1224			if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
1225				REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
1226				    SM(pdGainOverlap_t2,
1227				    AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
1228				    SM(gainBoundaries[0],
1229				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |
1230				    SM(gainBoundaries[1],
1231				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |
1232				    SM(gainBoundaries[2],
1233				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |
1234				    SM(gainBoundaries[3],
1235				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
1236			}
1237
1238			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
1239			for (j = 0; j < 32; j++) {
1240				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
1241				    ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
1242				    ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
1243				    ((pdadcValues[4 * j + 3] & 0xFF) << 24);
1244				REG_WRITE(ah, regOffset, reg32);
1245
1246				ARN_DBG((ARN_DBG_REG_IO,
1247				    "PDADC (%d,%4x): %4.4x %8.8x\n",
1248				    i, regChainOffset, regOffset,
1249				    reg32));
1250				ARN_DBG((ARN_DBG_REG_IO,
1251				    "PDADC: Chain %d | "
1252				    "PDADC %3d Value %3d | "
1253				    "PDADC %3d Value %3d | "
1254				    "PDADC %3d Value %3d | "
1255				    "PDADC %3d Value %3d |\n",
1256				    i, 4 * j, pdadcValues[4 * j],
1257				    4 * j + 1, pdadcValues[4 * j + 1],
1258				    4 * j + 2, pdadcValues[4 * j + 2],
1259				    4 * j + 3,
1260				    pdadcValues[4 * j + 3]));
1261
1262				regOffset += 4;
1263			}
1264		}
1265	}
1266
1267	*pTxPowerIndexOffset = 0;
1268
1269	return (B_TRUE);
1270}
1271
1272static boolean_t
1273ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah,
1274    struct ath9k_channel *chan,
1275    int16_t *ratesArray,
1276    uint16_t cfgCtl,
1277    uint16_t AntennaReduction,
1278    uint16_t twiceMaxRegulatoryPower,
1279    uint16_t powerLimit)
1280{
1281#define	REDUCE_SCALED_POWER_BY_TWO_CHAIN	6  /* 10*log10(2)*2 */
1282#define	REDUCE_SCALED_POWER_BY_THREE_CHAIN	10 /* 10*log10(3)*2 */
1283	struct ath_hal_5416 *ahp = AH5416(ah);
1284	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
1285	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1286	static const uint16_t tpScaleReductionTable[5] =
1287	    { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
1288
1289	int i;
1290	int8_t twiceLargestAntenna;
1291	struct cal_ctl_data *rep;
1292	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
1293		0, { 0, 0, 0, 0}
1294	};
1295	struct cal_target_power_leg targetPowerOfdmExt = {
1296		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
1297		0, { 0, 0, 0, 0 }
1298	};
1299	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1300		0, {0, 0, 0, 0}
1301	};
1302	uint16_t scaledPower = 0, minCtlPower, maxRegAllowedPower;
1303	uint16_t ctlModesFor11a[] =
1304		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
1305	uint16_t ctlModesFor11g[] =
1306		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
1307		    CTL_2GHT40
1308		};
1309	uint16_t numCtlModes, *pCtlMode, ctlMode, freq;
1310	struct chan_centers centers;
1311	int tx_chainmask;
1312	uint16_t twiceMinEdgePower;
1313
1314	tx_chainmask = ahp->ah_txchainmask;
1315
1316	ath9k_hw_get_channel_centers(ah, chan, &centers);
1317
1318	twiceLargestAntenna = max(
1319	    pEepData->modalHeader
1320	    [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1321	    pEepData->modalHeader
1322	    [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1323
1324	twiceLargestAntenna =
1325	    max((uint8_t)twiceLargestAntenna,
1326	    pEepData->modalHeader
1327	    [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1328
1329	twiceLargestAntenna =
1330	    (int16_t)min(AntennaReduction - twiceLargestAntenna, 0);
1331
1332	maxRegAllowedPower =
1333	    twiceMaxRegulatoryPower + twiceLargestAntenna;
1334
1335	if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
1336		maxRegAllowedPower -=
1337		    (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
1338	}
1339
1340	scaledPower = min(powerLimit, maxRegAllowedPower);
1341
1342	switch (ar5416_get_ntxchains(tx_chainmask)) {
1343	case 1:
1344		break;
1345	case 2:
1346		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1347		break;
1348	case 3:
1349		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1350		break;
1351	}
1352
1353	scaledPower = max((uint16_t)0, scaledPower);
1354
1355	if (IS_CHAN_2GHZ(chan)) {
1356		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
1357		    SUB_NUM_CTL_MODES_AT_2G_40;
1358		pCtlMode = ctlModesFor11g;
1359
1360		ath9k_hw_get_legacy_target_powers(ah, chan,
1361		    pEepData->calTargetPowerCck,
1362		    AR5416_NUM_2G_CCK_TARGET_POWERS,
1363		    &targetPowerCck, 4, B_FALSE);
1364		ath9k_hw_get_legacy_target_powers(ah, chan,
1365		    pEepData->calTargetPower2G,
1366		    AR5416_NUM_2G_20_TARGET_POWERS,
1367		    &targetPowerOfdm, 4, B_FALSE);
1368		ath9k_hw_get_target_powers(ah, chan,
1369		    pEepData->calTargetPower2GHT20,
1370		    AR5416_NUM_2G_20_TARGET_POWERS,
1371		    &targetPowerHt20, 8, B_FALSE);
1372
1373		if (IS_CHAN_HT40(chan)) {
1374			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1375			ath9k_hw_get_target_powers(ah, chan,
1376			    pEepData->calTargetPower2GHT40,
1377			    AR5416_NUM_2G_40_TARGET_POWERS,
1378			    &targetPowerHt40, 8, B_TRUE);
1379			ath9k_hw_get_legacy_target_powers(ah, chan,
1380			    pEepData->calTargetPowerCck,
1381			    AR5416_NUM_2G_CCK_TARGET_POWERS,
1382			    &targetPowerCckExt, 4, B_TRUE);
1383			ath9k_hw_get_legacy_target_powers(ah, chan,
1384			    pEepData->calTargetPower2G,
1385			    AR5416_NUM_2G_20_TARGET_POWERS,
1386			    &targetPowerOfdmExt, 4, B_TRUE);
1387		}
1388	} else {
1389		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1390		    SUB_NUM_CTL_MODES_AT_5G_40;
1391		pCtlMode = ctlModesFor11a;
1392
1393		ath9k_hw_get_legacy_target_powers(ah, chan,
1394		    pEepData->calTargetPower5G,
1395		    AR5416_NUM_5G_20_TARGET_POWERS,
1396		    &targetPowerOfdm, 4, B_FALSE);
1397		ath9k_hw_get_target_powers(ah, chan,
1398		    pEepData->calTargetPower5GHT20,
1399		    AR5416_NUM_5G_20_TARGET_POWERS,
1400		    &targetPowerHt20, 8, B_FALSE);
1401
1402		if (IS_CHAN_HT40(chan)) {
1403			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1404			ath9k_hw_get_target_powers(ah, chan,
1405			    pEepData->calTargetPower5GHT40,
1406			    AR5416_NUM_5G_40_TARGET_POWERS,
1407			    &targetPowerHt40, 8, B_TRUE);
1408			ath9k_hw_get_legacy_target_powers(ah, chan,
1409			    pEepData->calTargetPower5G,
1410			    AR5416_NUM_5G_20_TARGET_POWERS,
1411			    &targetPowerOfdmExt, 4, B_TRUE);
1412		}
1413	}
1414
1415	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1416		boolean_t isHt40CtlMode =
1417		    (pCtlMode[ctlMode] == CTL_5GHT40) ||
1418		    (pCtlMode[ctlMode] == CTL_2GHT40);
1419		if (isHt40CtlMode)
1420			freq = centers.synth_center;
1421		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1422			freq = centers.ext_center;
1423		else
1424			freq = centers.ctl_center;
1425
1426		if (ar5416_get_eep_ver(ahp) == 14 &&
1427		    ar5416_get_eep_rev(ahp) <= 2)
1428			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1429
1430		ARN_DBG((ARN_DBG_EEPROM, "arn: "
1431		    "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
1432		    "EXT_ADDITIVE %d\n",
1433		    ctlMode, numCtlModes, isHt40CtlMode,
1434		    (pCtlMode[ctlMode] & EXT_ADDITIVE)));
1435
1436		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
1437		    i++) {
1438
1439			ARN_DBG((ARN_DBG_EEPROM, "arn: "
1440			    "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
1441			    "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
1442			    "chan %d\n",
1443			    i, cfgCtl, pCtlMode[ctlMode],
1444			    pEepData->ctlIndex[i], chan->channel));
1445
1446			if ((((cfgCtl & ~CTL_MODE_M) |
1447			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1448			    pEepData->ctlIndex[i]) ||
1449			    (((cfgCtl & ~CTL_MODE_M) |
1450			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1451			    ((pEepData->ctlIndex[i] & CTL_MODE_M) |
1452			    SD_NO_CTL))) {
1453				rep = &(pEepData->ctlData[i]);
1454
1455				twiceMinEdgePower =
1456				    ath9k_hw_get_max_edge_power(freq,
1457				    rep->ctlEdges[ar5416_get_ntxchains
1458				    (tx_chainmask) - 1],
1459				    IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1460
1461				ARN_DBG((ARN_DBG_EEPROM, "arn: "
1462				    "MATCH-EE_IDX %d: ch %d is2 %d "
1463				    "2xMinEdge %d chainmask %d chains %d\n",
1464				    i, freq, IS_CHAN_2GHZ(chan),
1465				    twiceMinEdgePower, tx_chainmask,
1466				    ar5416_get_ntxchains(tx_chainmask)));
1467
1468				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1469					twiceMaxEdgePower =
1470					    min(twiceMaxEdgePower,
1471					    twiceMinEdgePower);
1472				} else {
1473					twiceMaxEdgePower = twiceMinEdgePower;
1474					break;
1475				}
1476			}
1477		}
1478
1479		minCtlPower = min(twiceMaxEdgePower, scaledPower);
1480
1481		ARN_DBG((ARN_DBG_EEPROM, "arn: "
1482		    "SEL-Min ctlMode %d pCtlMode %d "
1483		    "2xMaxEdge %d sP %d minCtlPwr %d\n",
1484		    ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
1485		    scaledPower, minCtlPower));
1486
1487		switch (pCtlMode[ctlMode]) {
1488		case CTL_11B:
1489			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
1490			    i++) {
1491				targetPowerCck.tPow2x[i] =
1492				    min((uint16_t)targetPowerCck.tPow2x[i],
1493				    minCtlPower);
1494			}
1495			break;
1496		case CTL_11A:
1497		case CTL_11G:
1498			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
1499			    i++) {
1500				targetPowerOfdm.tPow2x[i] =
1501				    min((uint16_t)targetPowerOfdm.tPow2x[i],
1502				    minCtlPower);
1503			}
1504			break;
1505		case CTL_5GHT20:
1506		case CTL_2GHT20:
1507			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
1508			    i++) {
1509				targetPowerHt20.tPow2x[i] =
1510				    min((uint16_t)targetPowerHt20.tPow2x[i],
1511				    minCtlPower);
1512			}
1513			break;
1514		case CTL_11B_EXT:
1515			targetPowerCckExt.tPow2x[0] =
1516			    min((uint16_t)targetPowerCckExt.tPow2x[0],
1517			    minCtlPower);
1518			break;
1519		case CTL_11A_EXT:
1520		case CTL_11G_EXT:
1521			targetPowerOfdmExt.tPow2x[0] =
1522			    min((uint16_t)targetPowerOfdmExt.tPow2x[0],
1523			    minCtlPower);
1524			break;
1525		case CTL_5GHT40:
1526		case CTL_2GHT40:
1527			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
1528			    i++) {
1529				targetPowerHt40.tPow2x[i] =
1530				    min((uint16_t)targetPowerHt40.tPow2x[i],
1531				    minCtlPower);
1532			}
1533			break;
1534		default:
1535			break;
1536		}
1537	}
1538
1539	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1540	    ratesArray[rate18mb] = ratesArray[rate24mb] =
1541	    targetPowerOfdm.tPow2x[0];
1542	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1543	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1544	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1545	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1546
1547	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1548		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1549
1550	if (IS_CHAN_2GHZ(chan)) {
1551		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1552		ratesArray[rate2s] = ratesArray[rate2l] =
1553		    targetPowerCck.tPow2x[1];
1554		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1555		    targetPowerCck.tPow2x[2];
1556		;
1557		ratesArray[rate11s] = ratesArray[rate11l] =
1558		    targetPowerCck.tPow2x[3];
1559		;
1560	}
1561	if (IS_CHAN_HT40(chan)) {
1562		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1563			ratesArray[rateHt40_0 + i] =
1564			    targetPowerHt40.tPow2x[i];
1565		}
1566		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1567		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1568		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1569		if (IS_CHAN_2GHZ(chan)) {
1570			ratesArray[rateExtCck] =
1571			    targetPowerCckExt.tPow2x[0];
1572		}
1573	}
1574	return (B_TRUE);
1575}
1576
1577static boolean_t
1578ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1579    struct ath9k_channel *chan,
1580    int16_t *ratesArray,
1581    uint16_t cfgCtl,
1582    uint16_t AntennaReduction,
1583    uint16_t twiceMaxRegulatoryPower,
1584    uint16_t powerLimit)
1585{
1586	struct ath_hal_5416 *ahp = AH5416(ah);
1587	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
1588	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1589	static const uint16_t tpScaleReductionTable[5] =
1590		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
1591
1592	int i;
1593	int16_t twiceLargestAntenna;
1594	struct cal_ctl_data_4k *rep;
1595	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
1596		0, { 0, 0, 0, 0}
1597	};
1598	struct cal_target_power_leg targetPowerOfdmExt = {
1599		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
1600		0, { 0, 0, 0, 0 }
1601	};
1602	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1603		0, {0, 0, 0, 0}
1604	};
1605	uint16_t scaledPower = 0, minCtlPower, maxRegAllowedPower;
1606	uint16_t ctlModesFor11g[] =
1607	    { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
1608	    CTL_2GHT40
1609	    };
1610	uint16_t numCtlModes, *pCtlMode, ctlMode, freq;
1611	struct chan_centers centers;
1612	int tx_chainmask;
1613	uint16_t twiceMinEdgePower;
1614
1615	tx_chainmask = ahp->ah_txchainmask;
1616
1617	ath9k_hw_get_channel_centers(ah, chan, &centers);
1618
1619	twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
1620
1621	twiceLargestAntenna =
1622	    (int16_t)min(AntennaReduction - twiceLargestAntenna, 0);
1623
1624	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1625
1626	if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
1627		maxRegAllowedPower -=
1628		    (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
1629	}
1630
1631	scaledPower = min(powerLimit, maxRegAllowedPower);
1632	scaledPower = max((uint16_t)0, scaledPower);
1633
1634	numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
1635	pCtlMode = ctlModesFor11g;
1636
1637	ath9k_hw_get_legacy_target_powers(ah, chan,
1638	    pEepData->calTargetPowerCck,
1639	    AR5416_NUM_2G_CCK_TARGET_POWERS,
1640	    &targetPowerCck, 4, B_FALSE);
1641	ath9k_hw_get_legacy_target_powers(ah, chan,
1642	    pEepData->calTargetPower2G,
1643	    AR5416_NUM_2G_20_TARGET_POWERS,
1644	    &targetPowerOfdm, 4, B_FALSE);
1645	ath9k_hw_get_target_powers(ah, chan,
1646	    pEepData->calTargetPower2GHT20,
1647	    AR5416_NUM_2G_20_TARGET_POWERS,
1648	    &targetPowerHt20, 8, B_FALSE);
1649
1650	if (IS_CHAN_HT40(chan)) {
1651		numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1652		ath9k_hw_get_target_powers(ah, chan,
1653		    pEepData->calTargetPower2GHT40,
1654		    AR5416_NUM_2G_40_TARGET_POWERS,
1655		    &targetPowerHt40, 8, B_TRUE);
1656		ath9k_hw_get_legacy_target_powers(ah, chan,
1657		    pEepData->calTargetPowerCck,
1658		    AR5416_NUM_2G_CCK_TARGET_POWERS,
1659		    &targetPowerCckExt, 4, B_TRUE);
1660		ath9k_hw_get_legacy_target_powers(ah, chan,
1661		    pEepData->calTargetPower2G,
1662		    AR5416_NUM_2G_20_TARGET_POWERS,
1663		    &targetPowerOfdmExt, 4, B_TRUE);
1664	}
1665
1666	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1667		boolean_t isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1668		    (pCtlMode[ctlMode] == CTL_2GHT40);
1669		if (isHt40CtlMode)
1670			freq = centers.synth_center;
1671		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1672			freq = centers.ext_center;
1673		else
1674			freq = centers.ctl_center;
1675
1676		if (ar5416_get_eep_ver(ahp) == 14 &&
1677		    ar5416_get_eep_rev(ahp) <= 2)
1678			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1679
1680		ARN_DBG((ARN_DBG_POWER_MGMT,
1681		    "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
1682		    "EXT_ADDITIVE %d\n",
1683		    ctlMode, numCtlModes, isHt40CtlMode,
1684		    (pCtlMode[ctlMode] & EXT_ADDITIVE)));
1685
1686		for (i = 0; (i < AR5416_NUM_CTLS) &&
1687		    pEepData->ctlIndex[i]; i++) {
1688			ARN_DBG((ARN_DBG_POWER_MGMT,
1689			    "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
1690			    "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
1691			    "chan %d\n",
1692			    i, cfgCtl, pCtlMode[ctlMode],
1693			    pEepData->ctlIndex[i], chan->channel));
1694
1695			if ((((cfgCtl & ~CTL_MODE_M) |
1696			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1697			    pEepData->ctlIndex[i]) ||
1698			    (((cfgCtl & ~CTL_MODE_M) |
1699			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1700			    ((pEepData->ctlIndex[i] & CTL_MODE_M) |
1701			    SD_NO_CTL))) {
1702				rep = &(pEepData->ctlData[i]);
1703
1704				twiceMinEdgePower =
1705				    ath9k_hw_get_max_edge_power(freq,
1706				    rep->ctlEdges[ar5416_get_ntxchains
1707				    (tx_chainmask) - 1],
1708				    IS_CHAN_2GHZ(chan),
1709				    AR5416_EEP4K_NUM_BAND_EDGES);
1710
1711				ARN_DBG((ARN_DBG_POWER_MGMT,
1712				    "   MATCH-EE_IDX %d: ch %d is2 %d "
1713				    "2xMinEdge %d chainmask %d chains %d\n",
1714				    i, freq, IS_CHAN_2GHZ(chan),
1715				    twiceMinEdgePower, tx_chainmask,
1716				    ar5416_get_ntxchains
1717				    (tx_chainmask)));
1718				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1719					twiceMaxEdgePower =
1720					    min(twiceMaxEdgePower,
1721					    twiceMinEdgePower);
1722				} else {
1723					twiceMaxEdgePower = twiceMinEdgePower;
1724					break;
1725				}
1726			}
1727		}
1728
1729		minCtlPower = (uint8_t)min(twiceMaxEdgePower, scaledPower);
1730
1731		ARN_DBG((ARN_DBG_POWER_MGMT,
1732		    "    SEL-Min ctlMode %d pCtlMode %d "
1733		    "2xMaxEdge %d sP %d minCtlPwr %d\n",
1734		    ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
1735		    scaledPower, minCtlPower));
1736
1737		switch (pCtlMode[ctlMode]) {
1738		case CTL_11B:
1739			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
1740			    i++) {
1741				targetPowerCck.tPow2x[i] =
1742				    min((uint16_t)targetPowerCck.tPow2x[i],
1743				    minCtlPower);
1744			}
1745			break;
1746		case CTL_11G:
1747			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
1748			    i++) {
1749				targetPowerOfdm.tPow2x[i] =
1750				    min((uint16_t)targetPowerOfdm.tPow2x[i],
1751				    minCtlPower);
1752			}
1753			break;
1754		case CTL_2GHT20:
1755			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
1756			    i++) {
1757				targetPowerHt20.tPow2x[i] =
1758				    min((uint16_t)targetPowerHt20.tPow2x[i],
1759				    minCtlPower);
1760			}
1761			break;
1762		case CTL_11B_EXT:
1763			targetPowerCckExt.tPow2x[0] = min((uint16_t)
1764			    targetPowerCckExt.tPow2x[0],
1765			    minCtlPower);
1766			break;
1767		case CTL_11G_EXT:
1768			targetPowerOfdmExt.tPow2x[0] = min((uint16_t)
1769			    targetPowerOfdmExt.tPow2x[0],
1770			    minCtlPower);
1771			break;
1772		case CTL_2GHT40:
1773			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
1774			    i++) {
1775				targetPowerHt40.tPow2x[i] =
1776				    min((uint16_t)targetPowerHt40.tPow2x[i],
1777				    minCtlPower);
1778			}
1779			break;
1780		default:
1781			break;
1782		}
1783	}
1784
1785	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1786	    ratesArray[rate18mb] = ratesArray[rate24mb] =
1787	    targetPowerOfdm.tPow2x[0];
1788	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1789	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1790	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1791	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1792
1793	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1794		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1795
1796	ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1797	ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
1798	ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
1799	ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
1800
1801	if (IS_CHAN_HT40(chan)) {
1802		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1803			ratesArray[rateHt40_0 + i] =
1804			    targetPowerHt40.tPow2x[i];
1805		}
1806		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1807		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1808		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1809		ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
1810	}
1811	return (B_TRUE);
1812}
1813
1814static int
1815ath9k_hw_def_set_txpower(struct ath_hal *ah, struct ath9k_channel *chan,
1816    uint16_t cfgCtl, uint8_t twiceAntennaReduction,
1817    uint8_t twiceMaxRegulatoryPower, uint8_t powerLimit)
1818{
1819	struct ath_hal_5416 *ahp = AH5416(ah);
1820	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
1821	struct modal_eep_header *pModal =
1822	    &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1823	int16_t ratesArray[Ar5416RateSize];
1824	int16_t txPowerIndexOffset = 0;
1825	uint8_t ht40PowerIncForPdadc = 2;
1826	int i;
1827
1828	(void) memset(ratesArray, 0, sizeof (ratesArray));
1829
1830	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1831	    AR5416_EEP_MINOR_VER_2) {
1832		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1833	}
1834
1835	if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
1836	    &ratesArray[0], cfgCtl,
1837	    twiceAntennaReduction,
1838	    twiceMaxRegulatoryPower,
1839	    powerLimit)) {
1840
1841		ARN_DBG((ARN_DBG_EEPROM,
1842		    "ath9k_hw_set_txpower: unable to set "
1843		    "tx power per rate table\n"));
1844
1845		return (EIO);
1846	}
1847
1848	if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
1849		ARN_DBG((ARN_DBG_EEPROM, "ath9k: "
1850		    "ath9k_hw_set_txpower: unable to set power table\n"));
1851		return (EIO);
1852	}
1853
1854	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1855		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
1856		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1857			ratesArray[i] = AR5416_MAX_RATE_POWER;
1858	}
1859
1860	if (AR_SREV_9280_10_OR_LATER(ah)) {
1861		for (i = 0; i < Ar5416RateSize; i++)
1862			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
1863	}
1864
1865	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1866	    ATH9K_POW_SM(ratesArray[rate18mb], 24) |
1867	    ATH9K_POW_SM(ratesArray[rate12mb], 16) |
1868	    ATH9K_POW_SM(ratesArray[rate9mb], 8) |
1869	    ATH9K_POW_SM(ratesArray[rate6mb], 0));
1870	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1871	    ATH9K_POW_SM(ratesArray[rate54mb], 24) |
1872	    ATH9K_POW_SM(ratesArray[rate48mb], 16) |
1873	    ATH9K_POW_SM(ratesArray[rate36mb], 8) |
1874	    ATH9K_POW_SM(ratesArray[rate24mb], 0));
1875
1876	if (IS_CHAN_2GHZ(chan)) {
1877		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1878		    ATH9K_POW_SM(ratesArray[rate2s], 24) |
1879		    ATH9K_POW_SM(ratesArray[rate2l], 16) |
1880		    ATH9K_POW_SM(ratesArray[rateXr], 8) |
1881		    ATH9K_POW_SM(ratesArray[rate1l], 0));
1882		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1883		    ATH9K_POW_SM(ratesArray[rate11s], 24) |
1884		    ATH9K_POW_SM(ratesArray[rate11l], 16) |
1885		    ATH9K_POW_SM(ratesArray[rate5_5s], 8) |
1886		    ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1887	}
1888
1889	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1890	    ATH9K_POW_SM(ratesArray[rateHt20_3], 24) |
1891	    ATH9K_POW_SM(ratesArray[rateHt20_2], 16) |
1892	    ATH9K_POW_SM(ratesArray[rateHt20_1], 8) |
1893	    ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1894	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1895	    ATH9K_POW_SM(ratesArray[rateHt20_7], 24) |
1896	    ATH9K_POW_SM(ratesArray[rateHt20_6], 16) |
1897	    ATH9K_POW_SM(ratesArray[rateHt20_5], 8) |
1898	    ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1899
1900	if (IS_CHAN_HT40(chan)) {
1901		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1902		    ATH9K_POW_SM(ratesArray[rateHt40_3] +
1903		    ht40PowerIncForPdadc, 24) |
1904		    ATH9K_POW_SM(ratesArray[rateHt40_2] +
1905		    ht40PowerIncForPdadc, 16) |
1906		    ATH9K_POW_SM(ratesArray[rateHt40_1] +
1907		    ht40PowerIncForPdadc, 8) |
1908		    ATH9K_POW_SM(ratesArray[rateHt40_0] +
1909		    ht40PowerIncForPdadc, 0));
1910		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1911		    ATH9K_POW_SM(ratesArray[rateHt40_7] +
1912		    ht40PowerIncForPdadc, 24) |
1913		    ATH9K_POW_SM(ratesArray[rateHt40_6] +
1914		    ht40PowerIncForPdadc, 16) |
1915		    ATH9K_POW_SM(ratesArray[rateHt40_5] +
1916		    ht40PowerIncForPdadc, 8) |
1917		    ATH9K_POW_SM(ratesArray[rateHt40_4] +
1918		    ht40PowerIncForPdadc, 0));
1919
1920		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1921		    ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) |
1922		    ATH9K_POW_SM(ratesArray[rateExtCck], 16) |
1923		    ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) |
1924		    ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1925	}
1926
1927	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1928	    ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) |
1929	    ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1930
1931	i = rate6mb;
1932
1933	if (IS_CHAN_HT40(chan))
1934		i = rateHt40_0;
1935	else if (IS_CHAN_HT20(chan))
1936		i = rateHt20_0;
1937
1938	if (AR_SREV_9280_10_OR_LATER(ah))
1939		ah->ah_maxPowerLevel =
1940		    ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
1941	else
1942		ah->ah_maxPowerLevel = ratesArray[i];
1943
1944	return (0);
1945}
1946
1947static int
1948ath9k_hw_4k_set_txpower(struct ath_hal *ah,
1949    struct ath9k_channel *chan,
1950    uint16_t cfgCtl,
1951    uint8_t twiceAntennaReduction,
1952    uint8_t twiceMaxRegulatoryPower,
1953    uint8_t powerLimit)
1954{
1955	struct ath_hal_5416 *ahp = AH5416(ah);
1956	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
1957	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
1958	int16_t ratesArray[Ar5416RateSize];
1959	int16_t txPowerIndexOffset = 0;
1960	uint8_t ht40PowerIncForPdadc = 2;
1961	int i;
1962
1963	(void) memset(ratesArray, 0, sizeof (ratesArray));
1964
1965	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1966	    AR5416_EEP_MINOR_VER_2) {
1967		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1968	}
1969
1970	if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
1971	    &ratesArray[0], cfgCtl,
1972	    twiceAntennaReduction,
1973	    twiceMaxRegulatoryPower,
1974	    powerLimit)) {
1975		ARN_DBG((ARN_DBG_EEPROM,
1976		    "ath9k_hw_set_txpower: unable to set "
1977		    "tx power per rate table\n"));
1978		return (EIO);
1979	}
1980
1981	if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
1982		ARN_DBG((ARN_DBG_EEPROM,
1983		    "ath9k_hw_set_txpower: unable to set power table\n"));
1984		return (EIO);
1985	}
1986
1987	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1988		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
1989		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1990			ratesArray[i] = AR5416_MAX_RATE_POWER;
1991	}
1992
1993	if (AR_SREV_9280_10_OR_LATER(ah)) {
1994		for (i = 0; i < Ar5416RateSize; i++)
1995			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
1996	}
1997
1998	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1999	    ATH9K_POW_SM(ratesArray[rate18mb], 24) |
2000	    ATH9K_POW_SM(ratesArray[rate12mb], 16) |
2001	    ATH9K_POW_SM(ratesArray[rate9mb], 8) |
2002	    ATH9K_POW_SM(ratesArray[rate6mb], 0));
2003	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
2004	    ATH9K_POW_SM(ratesArray[rate54mb], 24) |
2005	    ATH9K_POW_SM(ratesArray[rate48mb], 16) |
2006	    ATH9K_POW_SM(ratesArray[rate36mb], 8) |
2007	    ATH9K_POW_SM(ratesArray[rate24mb], 0));
2008
2009	if (IS_CHAN_2GHZ(chan)) {
2010		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
2011		    ATH9K_POW_SM(ratesArray[rate2s], 24) |
2012		    ATH9K_POW_SM(ratesArray[rate2l], 16) |
2013		    ATH9K_POW_SM(ratesArray[rateXr], 8) |
2014		    ATH9K_POW_SM(ratesArray[rate1l], 0));
2015		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
2016		    ATH9K_POW_SM(ratesArray[rate11s], 24) |
2017		    ATH9K_POW_SM(ratesArray[rate11l], 16) |
2018		    ATH9K_POW_SM(ratesArray[rate5_5s], 8) |
2019		    ATH9K_POW_SM(ratesArray[rate5_5l], 0));
2020	}
2021
2022	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
2023	    ATH9K_POW_SM(ratesArray[rateHt20_3], 24) |
2024	    ATH9K_POW_SM(ratesArray[rateHt20_2], 16) |
2025	    ATH9K_POW_SM(ratesArray[rateHt20_1], 8) |
2026	    ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
2027	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
2028	    ATH9K_POW_SM(ratesArray[rateHt20_7], 24) |
2029	    ATH9K_POW_SM(ratesArray[rateHt20_6], 16) |
2030	    ATH9K_POW_SM(ratesArray[rateHt20_5], 8) |
2031	    ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
2032
2033	if (IS_CHAN_HT40(chan)) {
2034		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
2035		    ATH9K_POW_SM(ratesArray[rateHt40_3] +
2036		    ht40PowerIncForPdadc, 24) |
2037		    ATH9K_POW_SM(ratesArray[rateHt40_2] +
2038		    ht40PowerIncForPdadc, 16) |
2039		    ATH9K_POW_SM(ratesArray[rateHt40_1] +
2040		    ht40PowerIncForPdadc, 8) |
2041		    ATH9K_POW_SM(ratesArray[rateHt40_0] +
2042		    ht40PowerIncForPdadc, 0));
2043
2044		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
2045		    ATH9K_POW_SM(ratesArray[rateHt40_7] +
2046		    ht40PowerIncForPdadc, 24) |
2047		    ATH9K_POW_SM(ratesArray[rateHt40_6] +
2048		    ht40PowerIncForPdadc, 16) |
2049		    ATH9K_POW_SM(ratesArray[rateHt40_5] +
2050		    ht40PowerIncForPdadc, 8) |
2051		    ATH9K_POW_SM(ratesArray[rateHt40_4] +
2052		    ht40PowerIncForPdadc, 0));
2053
2054		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
2055		    ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) |
2056		    ATH9K_POW_SM(ratesArray[rateExtCck], 16) |
2057		    ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) |
2058		    ATH9K_POW_SM(ratesArray[rateDupCck], 0));
2059	}
2060
2061	i = rate6mb;
2062
2063	if (IS_CHAN_HT40(chan))
2064		i = rateHt40_0;
2065	else if (IS_CHAN_HT20(chan))
2066		i = rateHt20_0;
2067
2068	if (AR_SREV_9280_10_OR_LATER(ah))
2069		ah->ah_maxPowerLevel =
2070		    ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
2071	else
2072		ah->ah_maxPowerLevel = ratesArray[i];
2073
2074	return (0);
2075}
2076
2077int
2078ath9k_hw_set_txpower(struct ath_hal *ah,
2079    struct ath9k_channel *chan,
2080    uint16_t cfgCtl,
2081    uint8_t twiceAntennaReduction,
2082    uint8_t twiceMaxRegulatoryPower,
2083    uint8_t powerLimit)
2084{
2085	struct ath_hal_5416 *ahp = AH5416(ah);
2086	int val;
2087
2088	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
2089		val = ath9k_hw_def_set_txpower(ah, chan, cfgCtl,
2090		    twiceAntennaReduction, twiceMaxRegulatoryPower,
2091		    powerLimit);
2092	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2093		val = ath9k_hw_4k_set_txpower(ah, chan, cfgCtl,
2094		    twiceAntennaReduction, twiceMaxRegulatoryPower,
2095		    powerLimit);
2096	return (val);
2097}
2098
2099static void
2100ath9k_hw_set_def_addac(struct ath_hal *ah, struct ath9k_channel *chan)
2101{
2102#define	XPA_LVL_FREQ(cnt)	(pModal->xpaBiasLvlFreq[cnt])
2103	struct modal_eep_header *pModal;
2104	struct ath_hal_5416 *ahp = AH5416(ah);
2105	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2106	uint8_t biaslevel;
2107
2108	if (ah->ah_macVersion != AR_SREV_VERSION_9160)
2109		return;
2110
2111	if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
2112		return;
2113
2114	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2115
2116	if (pModal->xpaBiasLvl != 0xff) {
2117		biaslevel = pModal->xpaBiasLvl;
2118	} else {
2119		uint16_t resetFreqBin, freqBin, freqCount = 0;
2120		struct chan_centers centers;
2121
2122		ath9k_hw_get_channel_centers(ah, chan, &centers);
2123
2124		resetFreqBin =
2125		    FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
2126		freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
2127		biaslevel = (uint8_t)(XPA_LVL_FREQ(0) >> 14);
2128
2129		freqCount++;
2130
2131		while (freqCount < 3) {
2132			if (XPA_LVL_FREQ(freqCount) == 0x0)
2133				break;
2134
2135			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
2136			if (resetFreqBin >= freqBin) {
2137				biaslevel =
2138				    (uint8_t)
2139				    (XPA_LVL_FREQ(freqCount) >> 14);
2140			} else {
2141				break;
2142			}
2143			freqCount++;
2144		}
2145	}
2146
2147	if (IS_CHAN_2GHZ(chan)) {
2148		INI_RA(&ahp->ah_iniAddac, 7, 1) =
2149		    (INI_RA(&ahp->ah_iniAddac, 7, 1) &
2150		    (~0x18)) | biaslevel << 3;
2151	} else {
2152		INI_RA(&ahp->ah_iniAddac, 6, 1) =
2153		    (INI_RA(&ahp->ah_iniAddac, 6, 1) &
2154		    (~0xc0)) | biaslevel << 6;
2155	}
2156#undef XPA_LVL_FREQ
2157}
2158
2159/* ARGSUSED */
2160static void
2161ath9k_hw_set_4k_addac(struct ath_hal *ah, struct ath9k_channel *chan)
2162{
2163	struct modal_eep_4k_header *pModal;
2164	struct ath_hal_5416 *ahp = AH5416(ah);
2165	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
2166	uint8_t biaslevel;
2167
2168	if (ah->ah_macVersion != AR_SREV_VERSION_9160)
2169		return;
2170
2171	if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
2172		return;
2173
2174	pModal = &eep->modalHeader;
2175
2176	if (pModal->xpaBiasLvl != 0xff) {
2177		biaslevel = pModal->xpaBiasLvl;
2178		INI_RA(&ahp->ah_iniAddac, 7, 1) =
2179		    (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) |
2180		    biaslevel << 3;
2181	}
2182}
2183
2184void
2185ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
2186{
2187	struct ath_hal_5416 *ahp = AH5416(ah);
2188
2189	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
2190		ath9k_hw_set_def_addac(ah, chan);
2191	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2192		ath9k_hw_set_4k_addac(ah, chan);
2193}
2194
2195/* XXX: Clean me up, make me more legible */
2196static boolean_t
2197ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
2198    struct ath9k_channel *chan)
2199{
2200	struct modal_eep_header *pModal;
2201	struct ath_hal_5416 *ahp = AH5416(ah);
2202	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2203	int i, regChainOffset;
2204	uint8_t txRxAttenLocal;
2205	uint16_t ant_config;
2206
2207	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2208
2209	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
2210
2211	(void) ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
2212	REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
2213
2214	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2215		if (AR_SREV_9280(ah)) {
2216			if (i >= 2)
2217				break;
2218		}
2219
2220		if (AR_SREV_5416_V20_OR_LATER(ah) &&
2221		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
2222		    (i != 0))
2223			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
2224		else
2225			regChainOffset = i * 0x1000;
2226
2227		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
2228		    pModal->antCtrlChain[i]);
2229
2230		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
2231		    (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
2232		    ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
2233		    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
2234		    SM(pModal->iqCalICh[i],
2235		    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
2236		    SM(pModal->iqCalQCh[i],
2237		    AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
2238
2239		if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
2240			if ((eep->baseEepHeader.version &
2241			    AR5416_EEP_VER_MINOR_MASK) >=
2242			    AR5416_EEP_MINOR_VER_3) {
2243				txRxAttenLocal = pModal->txRxAttenCh[i];
2244				if (AR_SREV_9280_10_OR_LATER(ah)) {
2245					REG_RMW_FIELD(ah,
2246					    AR_PHY_GAIN_2GHZ +
2247					    regChainOffset,
2248					    AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
2249					    pModal->
2250					    bswMargin[i]);
2251					REG_RMW_FIELD(ah,
2252					    AR_PHY_GAIN_2GHZ +
2253					    regChainOffset,
2254					    AR_PHY_GAIN_2GHZ_XATTEN1_DB,
2255					    pModal->
2256					    bswAtten[i]);
2257					REG_RMW_FIELD(ah,
2258					    AR_PHY_GAIN_2GHZ +
2259					    regChainOffset,
2260					    AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
2261					    pModal->
2262					    xatten2Margin[i]);
2263					REG_RMW_FIELD(ah,
2264					    AR_PHY_GAIN_2GHZ +
2265					    regChainOffset,
2266					    AR_PHY_GAIN_2GHZ_XATTEN2_DB,
2267					    pModal->
2268					    xatten2Db[i]);
2269				} else {
2270					REG_WRITE(ah,
2271					    AR_PHY_GAIN_2GHZ +
2272					    regChainOffset,
2273					    (REG_READ(ah,
2274					    AR_PHY_GAIN_2GHZ +
2275					    regChainOffset) &
2276					    ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
2277					    | SM(pModal->
2278					    bswMargin[i],
2279					    AR_PHY_GAIN_2GHZ_BSW_MARGIN));
2280					REG_WRITE(ah,
2281					    AR_PHY_GAIN_2GHZ +
2282					    regChainOffset,
2283					    (REG_READ(ah,
2284					    AR_PHY_GAIN_2GHZ +
2285					    regChainOffset) &
2286					    ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
2287					    | SM(pModal->bswAtten[i],
2288					    AR_PHY_GAIN_2GHZ_BSW_ATTEN));
2289				}
2290			}
2291			if (AR_SREV_9280_10_OR_LATER(ah)) {
2292				REG_RMW_FIELD(ah,
2293				    AR_PHY_RXGAIN +
2294				    regChainOffset,
2295				    AR9280_PHY_RXGAIN_TXRX_ATTEN,
2296				    txRxAttenLocal);
2297				REG_RMW_FIELD(ah,
2298				    AR_PHY_RXGAIN +
2299				    regChainOffset,
2300				    AR9280_PHY_RXGAIN_TXRX_MARGIN,
2301				    pModal->rxTxMarginCh[i]);
2302			} else {
2303				REG_WRITE(ah,
2304				    AR_PHY_RXGAIN + regChainOffset,
2305				    (REG_READ(ah,
2306				    AR_PHY_RXGAIN +
2307				    regChainOffset) &
2308				    ~AR_PHY_RXGAIN_TXRX_ATTEN) |
2309				    SM(txRxAttenLocal,
2310				    AR_PHY_RXGAIN_TXRX_ATTEN));
2311				REG_WRITE(ah,
2312				    AR_PHY_GAIN_2GHZ +
2313				    regChainOffset,
2314				    (REG_READ(ah,
2315				    AR_PHY_GAIN_2GHZ +
2316				    regChainOffset) &
2317				    ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
2318				    SM(pModal->rxTxMarginCh[i],
2319				    AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
2320			}
2321		}
2322	}
2323
2324	if (AR_SREV_9280_10_OR_LATER(ah)) {
2325		if (IS_CHAN_2GHZ(chan)) {
2326			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
2327			    AR_AN_RF2G1_CH0_OB,
2328			    AR_AN_RF2G1_CH0_OB_S,
2329			    pModal->ob);
2330			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
2331			    AR_AN_RF2G1_CH0_DB,
2332			    AR_AN_RF2G1_CH0_DB_S,
2333			    pModal->db);
2334			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
2335			    AR_AN_RF2G1_CH1_OB,
2336			    AR_AN_RF2G1_CH1_OB_S,
2337			    pModal->ob_ch1);
2338			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
2339			    AR_AN_RF2G1_CH1_DB,
2340			    AR_AN_RF2G1_CH1_DB_S,
2341			    pModal->db_ch1);
2342		} else {
2343			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
2344			    AR_AN_RF5G1_CH0_OB5,
2345			    AR_AN_RF5G1_CH0_OB5_S,
2346			    pModal->ob);
2347			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
2348			    AR_AN_RF5G1_CH0_DB5,
2349			    AR_AN_RF5G1_CH0_DB5_S,
2350			    pModal->db);
2351			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
2352			    AR_AN_RF5G1_CH1_OB5,
2353			    AR_AN_RF5G1_CH1_OB5_S,
2354			    pModal->ob_ch1);
2355			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
2356			    AR_AN_RF5G1_CH1_DB5,
2357			    AR_AN_RF5G1_CH1_DB5_S,
2358			    pModal->db_ch1);
2359		}
2360		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
2361		    AR_AN_TOP2_XPABIAS_LVL,
2362		    AR_AN_TOP2_XPABIAS_LVL_S,
2363		    pModal->xpaBiasLvl);
2364		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
2365		    AR_AN_TOP2_LOCALBIAS,
2366		    AR_AN_TOP2_LOCALBIAS_S,
2367		    pModal->local_bias);
2368
2369		ARN_DBG((ARN_DBG_EEPROM, "arn: "
2370		    "ForceXPAon: %d\n", pModal->force_xpaon));
2371
2372		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
2373		    pModal->force_xpaon);
2374	}
2375
2376	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
2377	    pModal->switchSettling);
2378	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
2379	    pModal->adcDesiredSize);
2380
2381	if (!AR_SREV_9280_10_OR_LATER(ah))
2382		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2383		    AR_PHY_DESIRED_SZ_PGA,
2384		    pModal->pgaDesiredSize);
2385
2386	REG_WRITE(ah, AR_PHY_RF_CTL4,
2387	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
2388	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
2389	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
2390	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
2391
2392	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
2393	    pModal->txEndToRxOn);
2394	if (AR_SREV_9280_10_OR_LATER(ah)) {
2395		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
2396		    pModal->thresh62);
2397		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
2398		    AR_PHY_EXT_CCA0_THRESH62,
2399		    pModal->thresh62);
2400	} else {
2401		REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
2402		    pModal->thresh62);
2403		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
2404		    AR_PHY_EXT_CCA_THRESH62,
2405		    pModal->thresh62);
2406	}
2407
2408	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2409	    AR5416_EEP_MINOR_VER_2) {
2410		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
2411		    AR_PHY_TX_END_DATA_START,
2412		    pModal->txFrameToDataStart);
2413		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
2414		    pModal->txFrameToPaOn);
2415	}
2416
2417	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2418	    AR5416_EEP_MINOR_VER_3) {
2419		if (IS_CHAN_HT40(chan))
2420			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
2421			    AR_PHY_SETTLING_SWITCH,
2422			    pModal->swSettleHt40);
2423	}
2424
2425	return (B_TRUE);
2426}
2427
2428static boolean_t
2429ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah,
2430    struct ath9k_channel *chan)
2431{
2432	struct modal_eep_4k_header *pModal;
2433	struct ath_hal_5416 *ahp = AH5416(ah);
2434	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
2435	int regChainOffset;
2436	uint8_t txRxAttenLocal;
2437	uint16_t ant_config = 0;
2438	uint8_t ob[5], db1[5], db2[5];
2439	uint8_t ant_div_control1, ant_div_control2;
2440	uint32_t regVal;
2441
2442
2443	pModal = &eep->modalHeader;
2444
2445	txRxAttenLocal = 23;
2446
2447	(void) ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
2448	REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
2449
2450	regChainOffset = 0;
2451	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
2452	    pModal->antCtrlChain[0]);
2453
2454	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
2455	    (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
2456	    ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
2457	    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
2458	    SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
2459	    SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
2460
2461	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2462	    AR5416_EEP_MINOR_VER_3) {
2463		txRxAttenLocal = pModal->txRxAttenCh[0];
2464		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2465		    AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
2466		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2467		    AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
2468		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2469		    AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
2470		    pModal->xatten2Margin[0]);
2471		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2472		    AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
2473	}
2474
2475	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
2476	    AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
2477	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
2478	    AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
2479
2480	if (AR_SREV_9285_11(ah))
2481		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
2482
2483	/* Initialize Ant Diversity settings from EEPROM */
2484	if (pModal->version == 3) {
2485		ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
2486		ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
2487		regVal = REG_READ(ah, 0x99ac);
2488		regVal &= (~(0x7f000000));
2489		regVal |= ((ant_div_control1 & 0x1) << 24);
2490		regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
2491		regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
2492		regVal |= ((ant_div_control2 & 0x3) << 25);
2493		regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
2494		REG_WRITE(ah, 0x99ac, regVal);
2495		regVal = REG_READ(ah, 0x99ac);
2496		regVal = REG_READ(ah, 0xa208);
2497		regVal &= (~(0x1 << 13));
2498		regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
2499		REG_WRITE(ah, 0xa208, regVal);
2500		regVal = REG_READ(ah, 0xa208);
2501	}
2502
2503	if (pModal->version >= 2) {
2504		ob[0] = (pModal->ob_01 & 0xf);
2505		ob[1] = (pModal->ob_01 >> 4) & 0xf;
2506		ob[2] = (pModal->ob_234 & 0xf);
2507		ob[3] = ((pModal->ob_234 >> 4) & 0xf);
2508		ob[4] = ((pModal->ob_234 >> 8) & 0xf);
2509
2510		db1[0] = (pModal->db1_01 & 0xf);
2511		db1[1] = ((pModal->db1_01 >> 4) & 0xf);
2512		db1[2] = (pModal->db1_234 & 0xf);
2513		db1[3] = ((pModal->db1_234 >> 4) & 0xf);
2514		db1[4] = ((pModal->db1_234 >> 8) & 0xf);
2515
2516		db2[0] = (pModal->db2_01 & 0xf);
2517		db2[1] = ((pModal->db2_01 >> 4) & 0xf);
2518		db2[2] = (pModal->db2_234 & 0xf);
2519		db2[3] = ((pModal->db2_234 >> 4) & 0xf);
2520		db2[4] = ((pModal->db2_234 >> 8) & 0xf);
2521
2522	} else if (pModal->version == 1) {
2523
2524		ARN_DBG((ARN_DBG_EEPROM,
2525		    "EEPROM Model version is set to 1 \n"));
2526		ob[0] = (pModal->ob_01 & 0xf);
2527		ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
2528		db1[0] = (pModal->db1_01 & 0xf);
2529		db1[1] = db1[2] = db1[3] = db1[4] =
2530		    ((pModal->db1_01 >> 4) & 0xf);
2531		db2[0] = (pModal->db2_01 & 0xf);
2532		db2[1] = db2[2] = db2[3] = db2[4] =
2533		    ((pModal->db2_01 >> 4) & 0xf);
2534	} else {
2535		int i;
2536		for (i = 0; i < 5; i++) {
2537			ob[i] = pModal->ob_01;
2538			db1[i] = pModal->db1_01;
2539			db2[i] = pModal->db1_01;
2540		}
2541	}
2542
2543	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2544	    AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
2545	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2546	    AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
2547	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2548	    AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
2549	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2550	    AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
2551	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2552	    AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
2553
2554	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2555	    AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
2556	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2557	    AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
2558	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2559	    AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
2560	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2561	    AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
2562	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2563	    AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
2564
2565	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2566	    AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
2567	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2568	    AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
2569	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2570	    AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
2571	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2572	    AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
2573	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2574	    AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
2575
2576
2577	if (AR_SREV_9285_11(ah))
2578		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
2579
2580	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
2581	    pModal->switchSettling);
2582	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
2583	    pModal->adcDesiredSize);
2584
2585	REG_WRITE(ah, AR_PHY_RF_CTL4,
2586	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
2587	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
2588	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
2589	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
2590
2591	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
2592	    pModal->txEndToRxOn);
2593	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
2594	    pModal->thresh62);
2595	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
2596	    pModal->thresh62);
2597
2598	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2599	    AR5416_EEP_MINOR_VER_2) {
2600		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
2601		    pModal->txFrameToDataStart);
2602		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
2603		    pModal->txFrameToPaOn);
2604	}
2605
2606	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2607	    AR5416_EEP_MINOR_VER_3) {
2608		if (IS_CHAN_HT40(chan))
2609			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
2610			    AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
2611	}
2612
2613	return (B_TRUE);
2614}
2615
2616boolean_t
2617ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, struct ath9k_channel *chan)
2618{
2619	struct ath_hal_5416 *ahp = AH5416(ah);
2620	boolean_t val;
2621
2622	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
2623		val = ath9k_hw_eeprom_set_def_board_values(ah, chan);
2624	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2625		val = ath9k_hw_eeprom_set_4k_board_values(ah, chan);
2626
2627	return (val);
2628}
2629
2630static int
2631ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah,
2632    struct ath9k_channel *chan,
2633    uint8_t index, uint16_t *config)
2634{
2635	struct ath_hal_5416 *ahp = AH5416(ah);
2636	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2637	struct modal_eep_header *pModal =
2638	    &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2639	struct base_eep_header *pBase = &eep->baseEepHeader;
2640
2641	switch (index) {
2642	case 0:
2643		*config = pModal->antCtrlCommon & 0xFFFF;
2644		return (0);
2645	case 1:
2646		if (pBase->version >= 0x0E0D) {
2647			if (pModal->useAnt1) {
2648				*config =
2649				    ((pModal->antCtrlCommon & 0xFFFF0000)
2650				    >> 16);
2651				return (0);
2652			}
2653		}
2654		break;
2655	default:
2656		break;
2657	}
2658
2659	return (-EINVAL);
2660}
2661
2662/* ARGSUSED */
2663static int
2664ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah,
2665    struct ath9k_channel *chan,
2666    uint8_t index, uint16_t *config)
2667{
2668	struct ath_hal_5416 *ahp = AH5416(ah);
2669	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
2670	struct modal_eep_4k_header *pModal = &eep->modalHeader;
2671
2672	switch (index) {
2673	case 0:
2674		*config = pModal->antCtrlCommon & 0xFFFF;
2675		return (0);
2676	default:
2677		break;
2678	}
2679
2680	return (EINVAL);
2681}
2682
2683int
2684ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
2685    struct ath9k_channel *chan,
2686    uint8_t index, uint16_t *config)
2687{
2688	struct ath_hal_5416 *ahp = AH5416(ah);
2689	int val;
2690
2691	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
2692		val = ath9k_hw_get_def_eeprom_antenna_cfg(ah, chan,
2693		    index, config);
2694	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2695		val = ath9k_hw_get_4k_eeprom_antenna_cfg(ah, chan,
2696		    index, config);
2697
2698	return (val);
2699}
2700
2701/* ARGSUSED */
2702static uint8_t
2703ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
2704    enum ath9k_band freq_band)
2705{
2706	return (1);
2707}
2708
2709static uint8_t
2710ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
2711    enum ath9k_band freq_band)
2712{
2713	struct ath_hal_5416 *ahp = AH5416(ah);
2714	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2715
2716	struct modal_eep_header *pModal =
2717	    &(eep->modalHeader[ATH9K_BAND_5GHZ == freq_band]);
2718	struct base_eep_header *pBase = &eep->baseEepHeader;
2719	uint8_t num_ant_config;
2720
2721	num_ant_config = 1;
2722
2723	if (pBase->version >= 0x0E0D)
2724		if (pModal->useAnt1)
2725			num_ant_config += 1;
2726
2727	return (num_ant_config);
2728}
2729
2730uint8_t
2731ath9k_hw_get_num_ant_config(struct ath_hal *ah,
2732    enum ath9k_band freq_band)
2733{
2734	struct ath_hal_5416 *ahp = AH5416(ah);
2735	uint8_t val;
2736
2737	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
2738		val = ath9k_hw_get_def_num_ant_config(ah, freq_band);
2739	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2740		val = ath9k_hw_get_4k_num_ant_config(ah, freq_band);
2741
2742	return (val);
2743}
2744
2745uint16_t
2746ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, uint16_t i, boolean_t is2GHz)
2747{
2748#define	EEP_MAP4K_SPURCHAN \
2749	(ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
2750#define	EEP_DEF_SPURCHAN \
2751	(ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
2752
2753	struct ath_hal_5416 *ahp = AH5416(ah);
2754	uint16_t spur_val = AR_NO_SPUR;
2755
2756	ARN_DBG((ARN_DBG_ANI, "arn: "
2757	    "Getting spur idx %d is2Ghz. %d val %x\n",
2758	    i, is2GHz, ah->ah_config.spurchans[i][is2GHz]));
2759
2760	switch (ah->ah_config.spurmode) {
2761	case SPUR_DISABLE:
2762		break;
2763	case SPUR_ENABLE_IOCTL:
2764		spur_val = ah->ah_config.spurchans[i][is2GHz];
2765		ARN_DBG((ARN_DBG_ANI, "arn: "
2766		    "Getting spur val from new loc. %d\n", spur_val));
2767		break;
2768	case SPUR_ENABLE_EEPROM:
2769		if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2770			spur_val = EEP_MAP4K_SPURCHAN;
2771		else
2772			spur_val = EEP_DEF_SPURCHAN;
2773		break;
2774
2775	}
2776
2777	return (spur_val);
2778#undef EEP_DEF_SPURCHAN
2779#undef EEP_MAP4K_SPURCHAN
2780}
2781
2782static uint32_t
2783ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
2784    enum eeprom_param param)
2785{
2786	struct ath_hal_5416 *ahp = AH5416(ah);
2787	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
2788	struct modal_eep_4k_header *pModal = &eep->modalHeader;
2789	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
2790
2791	switch (param) {
2792	case EEP_NFTHRESH_2:
2793		return (pModal[1].noiseFloorThreshCh[0]);
2794	case AR_EEPROM_MAC(0):
2795		return (pBase->macAddr[0] << 8 | pBase->macAddr[1]);
2796	case AR_EEPROM_MAC(1):
2797		return (pBase->macAddr[2] << 8 | pBase->macAddr[3]);
2798	case AR_EEPROM_MAC(2):
2799		return (pBase->macAddr[4] << 8 | pBase->macAddr[5]);
2800	case EEP_REG_0:
2801		return (pBase->regDmn[0]);
2802	case EEP_REG_1:
2803		return (pBase->regDmn[1]);
2804	case EEP_OP_CAP:
2805		return (pBase->deviceCap);
2806	case EEP_OP_MODE:
2807		return (pBase->opCapFlags);
2808	case EEP_RF_SILENT:
2809		return (pBase->rfSilent);
2810	case EEP_OB_2:
2811		return (pModal->ob_01);
2812	case EEP_DB_2:
2813		return (pModal->db1_01);
2814	case EEP_MINOR_REV:
2815		return (pBase->version & AR5416_EEP_VER_MINOR_MASK);
2816	case EEP_TX_MASK:
2817		return (pBase->txMask);
2818	case EEP_RX_MASK:
2819		return (pBase->rxMask);
2820	/* 2.6.30 */
2821	case EEP_FRAC_N_5G:
2822		return (0);
2823	default:
2824		return (0);
2825	}
2826}
2827
2828uint32_t
2829ath9k_hw_get_eeprom_def(struct ath_hal *ah, enum eeprom_param param)
2830{
2831	struct ath_hal_5416 	*ahp = AH5416(ah);
2832	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2833	struct modal_eep_header *pModal = eep->modalHeader;
2834	struct base_eep_header 	*pBase = &eep->baseEepHeader;
2835
2836	switch (param) {
2837	case EEP_NFTHRESH_5:
2838		return (pModal[0].noiseFloorThreshCh[0]);
2839	case EEP_NFTHRESH_2:
2840		return (pModal[1].noiseFloorThreshCh[0]);
2841	case AR_EEPROM_MAC(0):
2842		return (pBase->macAddr[0] << 8 | pBase->macAddr[1]);
2843	case AR_EEPROM_MAC(1):
2844		return (pBase->macAddr[2] << 8 | pBase->macAddr[3]);
2845	case AR_EEPROM_MAC(2):
2846		return (pBase->macAddr[4] << 8 | pBase->macAddr[5]);
2847	case EEP_REG_0:
2848		return (pBase->regDmn[0]);
2849	case EEP_REG_1:
2850		return (pBase->regDmn[1]);
2851	case EEP_OP_CAP:
2852		return (pBase->deviceCap);
2853	case EEP_OP_MODE:
2854		return (pBase->opCapFlags);
2855	case EEP_RF_SILENT:
2856		return (pBase->rfSilent);
2857	case EEP_OB_5:
2858		return (pModal[0].ob);
2859	case EEP_DB_5:
2860		return (pModal[0].db);
2861	case EEP_OB_2:
2862		return (pModal[1].ob);
2863	case EEP_DB_2:
2864		return (pModal[1].db);
2865	case EEP_MINOR_REV:
2866		return (pBase->version & AR5416_EEP_VER_MINOR_MASK);
2867	case EEP_TX_MASK:
2868		return (pBase->txMask);
2869	case EEP_RX_MASK:
2870		return (pBase->rxMask);
2871	case EEP_RXGAIN_TYPE:
2872		return (pBase->rxGainType);
2873	case EEP_TXGAIN_TYPE:
2874		return (pBase->txGainType);
2875	/* 2.6.30 */
2876	case EEP_OL_PWRCTRL:
2877		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
2878			return (pBase->openLoopPwrCntl ? B_TRUE: B_FALSE);
2879		else
2880			return (B_FALSE);
2881	case EEP_RC_CHAIN_MASK:
2882		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
2883			return (pBase->rcChainMask);
2884		else
2885			return (0);
2886	case EEP_DAC_HPWR_5G:
2887		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
2888			return (pBase->dacHiPwrMode_5G);
2889		else
2890			return (0);
2891	case EEP_FRAC_N_5G:
2892		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
2893			return (pBase->frac_n_5g);
2894		else
2895			return (0);
2896
2897	default:
2898		return (0);
2899	}
2900}
2901
2902uint32_t
2903ath9k_hw_get_eeprom(struct ath_hal *ah, enum eeprom_param param)
2904{
2905	struct ath_hal_5416 *ahp = AH5416(ah);
2906	uint32_t val;
2907
2908	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
2909		val = ath9k_hw_get_eeprom_def(ah, param);
2910	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
2911		val = ath9k_hw_get_eeprom_4k(ah, param);
2912
2913	return (val);
2914}
2915
2916int
2917ath9k_hw_eeprom_attach(struct ath_hal *ah)
2918{
2919	int status;
2920	struct ath_hal_5416 *ahp = AH5416(ah);
2921
2922	if (ath9k_hw_use_flash(ah))
2923		(void) ath9k_hw_flash_map(ah);
2924
2925	if (AR_SREV_9285(ah))
2926		ahp->ah_eep_map = EEP_MAP_4KBITS;
2927	else
2928		ahp->ah_eep_map = EEP_MAP_DEFAULT;
2929
2930	if (!ath9k_hw_fill_eeprom(ah))
2931		return (EIO);
2932
2933	status = ath9k_hw_check_eeprom(ah);
2934
2935	return (status);
2936}
2937