xref: /illumos-gate/usr/src/uts/common/io/arn/arn_eeprom.c (revision fd7c59804fad02c3863ef57c544fa7af0fd35068)
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 
59 static void
ath9k_hw_analog_shift_rmw(struct ath_hal * ah,uint32_t reg,uint32_t mask,uint32_t shift,uint32_t val)60 ath9k_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 
75 static inline uint16_t
ath9k_hw_fbin2freq(uint8_t fbin,boolean_t is2GHz)76 ath9k_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 
85 static inline int16_t
ath9k_hw_interpolate(uint16_t target,uint16_t srcLeft,uint16_t srcRight,int16_t targetLeft,int16_t targetRight)86 ath9k_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 
101 static inline boolean_t
ath9k_hw_get_lower_upper_index(uint8_t target,uint8_t * pList,uint16_t listSize,uint16_t * indexL,uint16_t * indexR)102 ath9k_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 
130 static boolean_t
ath9k_hw_eeprom_read(struct ath_hal * ah,uint32_t off,uint16_t * data)131 ath9k_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 */
148 static int
ath9k_hw_flash_map(struct ath_hal * ah)149 ath9k_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 
157 static boolean_t
ath9k_hw_flash_read(struct ath_hal * ah,uint32_t off,uint16_t * data)158 ath9k_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 
165 static inline boolean_t
ath9k_hw_nvram_read(struct ath_hal * ah,uint32_t off,uint16_t * data)166 ath9k_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 
174 static boolean_t
ath9k_hw_fill_4k_eeprom(struct ath_hal * ah)175 ath9k_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 
204 static boolean_t
ath9k_hw_fill_def_eeprom(struct ath_hal * ah)205 ath9k_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 
228 static boolean_t (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
229 	ath9k_hw_fill_def_eeprom,
230 	ath9k_hw_fill_4k_eeprom
231 };
232 
233 static inline boolean_t
ath9k_hw_fill_eeprom(struct ath_hal * ah)234 ath9k_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 
241 static int
ath9k_hw_check_def_eeprom(struct ath_hal * ah)242 ath9k_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 
370 static int
ath9k_hw_check_4k_eeprom(struct ath_hal * ah)371 ath9k_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_EEP4K_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 
497 static int
498 (*ath9k_check_eeprom[]) (struct ath_hal *) = {
499     ath9k_hw_check_def_eeprom,
500     ath9k_hw_check_4k_eeprom
501 };
502 
503 static inline int
ath9k_hw_check_eeprom(struct ath_hal * ah)504 ath9k_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 
511 static inline boolean_t
ath9k_hw_fill_vpd_table(uint8_t pwrMin,uint8_t pwrMax,uint8_t * pPwrList,uint8_t * pVpdList,uint16_t numIntercepts,uint8_t * pRetVpdList)512 ath9k_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 
540 static void
ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal * ah,struct ath9k_channel * chan,struct cal_data_per_freq_4k * pRawDataSet,uint8_t * bChans,uint16_t availPiers,uint16_t tPdGainOverlap,int16_t * pMinCalPower,uint16_t * pPdGainBoundaries,uint8_t * pPDADCValues,uint16_t numXpdGains)541 ath9k_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 
711 static void
ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal * ah,struct ath9k_channel * chan,struct cal_data_per_freq * pRawDataSet,uint8_t * bChans,uint16_t availPiers,uint16_t tPdGainOverlap,int16_t * pMinCalPower,uint16_t * pPdGainBoundaries,uint8_t * pPDADCValues,uint16_t numXpdGains)712 ath9k_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 
880 static void
ath9k_hw_get_legacy_target_powers(struct ath_hal * ah,struct ath9k_channel * chan,struct cal_target_power_leg * powInfo,uint16_t numChannels,struct cal_target_power_leg * pNewPower,uint16_t numRates,boolean_t isExtTarget)881 ath9k_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 
937 static void
ath9k_hw_get_target_powers(struct ath_hal * ah,struct ath9k_channel * chan,struct cal_target_power_ht * powInfo,uint16_t numChannels,struct cal_target_power_ht * pNewPower,uint16_t numRates,boolean_t isHt40Target)938 ath9k_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 
997 static uint16_t
ath9k_hw_get_max_edge_power(uint16_t freq,struct cal_ctl_edges * pRdEdgesPower,boolean_t is2GHz,int num_band_edges)998 ath9k_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 
1027 static boolean_t
ath9k_hw_set_def_power_cal_table(struct ath_hal * ah,struct ath9k_channel * chan,int16_t * pTxPowerIndexOffset)1028 ath9k_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 
1155 static boolean_t
ath9k_hw_set_4k_power_cal_table(struct ath_hal * ah,struct ath9k_channel * chan,int16_t * pTxPowerIndexOffset)1156 ath9k_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 
1272 static boolean_t
ath9k_hw_set_def_power_per_rate_table(struct ath_hal * ah,struct ath9k_channel * chan,int16_t * ratesArray,uint16_t cfgCtl,uint16_t AntennaReduction,uint16_t twiceMaxRegulatoryPower,uint16_t powerLimit)1273 ath9k_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 
1577 static boolean_t
ath9k_hw_set_4k_power_per_rate_table(struct ath_hal * ah,struct ath9k_channel * chan,int16_t * ratesArray,uint16_t cfgCtl,uint16_t AntennaReduction,uint16_t twiceMaxRegulatoryPower,uint16_t powerLimit)1578 ath9k_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 
1814 static int
ath9k_hw_def_set_txpower(struct ath_hal * ah,struct ath9k_channel * chan,uint16_t cfgCtl,uint8_t twiceAntennaReduction,uint8_t twiceMaxRegulatoryPower,uint8_t powerLimit)1815 ath9k_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 
1947 static int
ath9k_hw_4k_set_txpower(struct ath_hal * ah,struct ath9k_channel * chan,uint16_t cfgCtl,uint8_t twiceAntennaReduction,uint8_t twiceMaxRegulatoryPower,uint8_t powerLimit)1948 ath9k_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 
2077 int
ath9k_hw_set_txpower(struct ath_hal * ah,struct ath9k_channel * chan,uint16_t cfgCtl,uint8_t twiceAntennaReduction,uint8_t twiceMaxRegulatoryPower,uint8_t powerLimit)2078 ath9k_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 
2099 static void
ath9k_hw_set_def_addac(struct ath_hal * ah,struct ath9k_channel * chan)2100 ath9k_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 */
2160 static void
ath9k_hw_set_4k_addac(struct ath_hal * ah,struct ath9k_channel * chan)2161 ath9k_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 
2184 void
ath9k_hw_set_addac(struct ath_hal * ah,struct ath9k_channel * chan)2185 ath9k_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 */
2196 static boolean_t
ath9k_hw_eeprom_set_def_board_values(struct ath_hal * ah,struct ath9k_channel * chan)2197 ath9k_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 
2428 static boolean_t
ath9k_hw_eeprom_set_4k_board_values(struct ath_hal * ah,struct ath9k_channel * chan)2429 ath9k_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 
2616 boolean_t
ath9k_hw_eeprom_set_board_values(struct ath_hal * ah,struct ath9k_channel * chan)2617 ath9k_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 
2630 static int
ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal * ah,struct ath9k_channel * chan,uint8_t index,uint16_t * config)2631 ath9k_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 */
2663 static int
ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal * ah,struct ath9k_channel * chan,uint8_t index,uint16_t * config)2664 ath9k_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 
2683 int
ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal * ah,struct ath9k_channel * chan,uint8_t index,uint16_t * config)2684 ath9k_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 */
2702 static uint8_t
ath9k_hw_get_4k_num_ant_config(struct ath_hal * ah,enum ath9k_band freq_band)2703 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
2704     enum ath9k_band freq_band)
2705 {
2706 	return (1);
2707 }
2708 
2709 static uint8_t
ath9k_hw_get_def_num_ant_config(struct ath_hal * ah,enum ath9k_band freq_band)2710 ath9k_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 
2730 uint8_t
ath9k_hw_get_num_ant_config(struct ath_hal * ah,enum ath9k_band freq_band)2731 ath9k_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 
2745 uint16_t
ath9k_hw_eeprom_get_spur_chan(struct ath_hal * ah,uint16_t i,boolean_t is2GHz)2746 ath9k_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 
2782 static uint32_t
ath9k_hw_get_eeprom_4k(struct ath_hal * ah,enum eeprom_param param)2783 ath9k_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 
2828 uint32_t
ath9k_hw_get_eeprom_def(struct ath_hal * ah,enum eeprom_param param)2829 ath9k_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 
2902 uint32_t
ath9k_hw_get_eeprom(struct ath_hal * ah,enum eeprom_param param)2903 ath9k_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 
2916 int
ath9k_hw_eeprom_attach(struct ath_hal * ah)2917 ath9k_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