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