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, ¢ers);
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, ¢ers);
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, ¢ers);
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, ¢ers);
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, ¢ers);
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, ¢ers);
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, ¢ers);
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