OSDN Git Service

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