OSDN Git Service

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