Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / ath / ath9k / ath9k_eeprom_def.c
1 /*
2  * Copyright (c) 2008-2011 Atheros Communications Inc.
3  *
4  * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5  * Original from Linux kernel 3.0.1
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19
20 #include <ipxe/io.h>
21
22 #include "hw.h"
23 #include "ar9002_phy.h"
24
25 static void ath9k_get_txgain_index(struct ath_hw *ah,
26                 struct ath9k_channel *chan,
27                 struct calDataPerFreqOpLoop *rawDatasetOpLoop,
28                 u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
29 {
30         u8 pcdac, i = 0;
31         u16 idxL = 0, idxR = 0, numPiers;
32         int match;
33         struct chan_centers centers;
34
35         ath9k_hw_get_channel_centers(ah, chan, &centers);
36
37         for (numPiers = 0; numPiers < availPiers; numPiers++)
38                 if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
39                         break;
40
41         match = ath9k_hw_get_lower_upper_index(
42                         (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
43                         calChans, numPiers, &idxL, &idxR);
44         if (match) {
45                 pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
46                 *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
47         } else {
48                 pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
49                 *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
50                                 rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
51         }
52
53         while (pcdac > ah->originalGain[i] &&
54                         i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
55                 i++;
56
57         *pcdacIdx = i;
58 }
59
60 static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
61                                 u32 initTxGain,
62                                 int txPower,
63                                 u8 *pPDADCValues)
64 {
65         u32 i;
66         u32 offset;
67
68         REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
69                         AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
70         REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
71                         AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
72
73         REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
74                         AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
75
76         offset = txPower;
77         for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
78                 if (i < offset)
79                         pPDADCValues[i] = 0x0;
80                 else
81                         pPDADCValues[i] = 0xFF;
82 }
83
84 static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
85 {
86         return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
87 }
88
89 static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
90 {
91         return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
92 }
93
94 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
95
96 static int __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
97 {
98         struct ath_common *common = ath9k_hw_common(ah);
99         u16 *eep_data = (u16 *)&ah->eeprom.def;
100         unsigned int addr;
101         int ar5416_eep_start_loc = 0x100;
102
103         for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
104                 if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
105                                          eep_data)) {
106                         DBG("ath9k: "
107                                 "Unable to read eeprom region\n");
108                         return 0;
109                 }
110                 eep_data++;
111         }
112         return 1;
113 }
114
115 static int __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah)
116 {
117         u16 *eep_data = (u16 *)&ah->eeprom.def;
118
119         ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
120                                      0x100, SIZE_EEPROM_DEF);
121         return 1;
122 }
123
124 static int ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
125 {
126         struct ath_common *common = ath9k_hw_common(ah);
127
128         if (!ath9k_hw_use_flash(ah)) {
129                 DBG2("ath9k: "
130                         "Reading from EEPROM, not flash\n");
131         }
132
133         if (common->bus_ops->ath_bus_type == ATH_USB)
134                 return __ath9k_hw_usb_def_fill_eeprom(ah);
135         else
136                 return __ath9k_hw_def_fill_eeprom(ah);
137 }
138
139 #undef SIZE_EEPROM_DEF
140
141 static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
142 {
143         struct ar5416_eeprom_def *eep =
144                 (struct ar5416_eeprom_def *) &ah->eeprom.def;
145         struct ath_common *common = ath9k_hw_common(ah);
146         u16 *eepdata, temp, magic, magic2;
147         u32 sum = 0, el;
148         int need_swap = 0;
149         unsigned int i, addr, size;
150
151         if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
152                 DBG("ath9k: Reading Magic # failed\n");
153                 return 0;
154         }
155
156         if (!ath9k_hw_use_flash(ah)) {
157                 DBG2("ath9k: "
158                         "Read Magic = 0x%04X\n", magic);
159
160                 if (magic != AR5416_EEPROM_MAGIC) {
161                         magic2 = swab16(magic);
162
163                         if (magic2 == AR5416_EEPROM_MAGIC) {
164                                 size = sizeof(struct ar5416_eeprom_def);
165                                 need_swap = 1;
166                                 eepdata = (u16 *) (&ah->eeprom);
167
168                                 for (addr = 0; addr < size / sizeof(u16); addr++) {
169                                         temp = swab16(*eepdata);
170                                         *eepdata = temp;
171                                         eepdata++;
172                                 }
173                         } else {
174                                 DBG("ath9k: "
175                                         "Invalid EEPROM Magic. Endianness mismatch.\n");
176                                 return -EINVAL;
177                         }
178                 }
179         }
180
181         DBG2("ath9k: need_swap = %s.\n",
182                 need_swap ? "True" : "False");
183
184         if (need_swap)
185                 el = swab16(ah->eeprom.def.baseEepHeader.length);
186         else
187                 el = ah->eeprom.def.baseEepHeader.length;
188
189         if (el > sizeof(struct ar5416_eeprom_def))
190                 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
191         else
192                 el = el / sizeof(u16);
193
194         eepdata = (u16 *)(&ah->eeprom);
195
196         for (i = 0; i < el; i++)
197                 sum ^= *eepdata++;
198
199         if (need_swap) {
200                 u32 integer, j;
201                 u16 word;
202
203                 DBG("ath9k: "
204                         "EEPROM Endianness is not native.. Changing.\n");
205
206                 word = swab16(eep->baseEepHeader.length);
207                 eep->baseEepHeader.length = word;
208
209                 word = swab16(eep->baseEepHeader.checksum);
210                 eep->baseEepHeader.checksum = word;
211
212                 word = swab16(eep->baseEepHeader.version);
213                 eep->baseEepHeader.version = word;
214
215                 word = swab16(eep->baseEepHeader.regDmn[0]);
216                 eep->baseEepHeader.regDmn[0] = word;
217
218                 word = swab16(eep->baseEepHeader.regDmn[1]);
219                 eep->baseEepHeader.regDmn[1] = word;
220
221                 word = swab16(eep->baseEepHeader.rfSilent);
222                 eep->baseEepHeader.rfSilent = word;
223
224                 word = swab16(eep->baseEepHeader.blueToothOptions);
225                 eep->baseEepHeader.blueToothOptions = word;
226
227                 word = swab16(eep->baseEepHeader.deviceCap);
228                 eep->baseEepHeader.deviceCap = word;
229
230                 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
231                         struct modal_eep_header *pModal =
232                                 &eep->modalHeader[j];
233                         integer = swab32(pModal->antCtrlCommon);
234                         pModal->antCtrlCommon = integer;
235
236                         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
237                                 integer = swab32(pModal->antCtrlChain[i]);
238                                 pModal->antCtrlChain[i] = integer;
239                         }
240                         for (i = 0; i < 3; i++) {
241                                 word = swab16(pModal->xpaBiasLvlFreq[i]);
242                                 pModal->xpaBiasLvlFreq[i] = word;
243                         }
244
245                         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
246                                 word = swab16(pModal->spurChans[i].spurChan);
247                                 pModal->spurChans[i].spurChan = word;
248                         }
249                 }
250         }
251
252         if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
253             ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
254                 DBG("ath9k: Bad EEPROM checksum 0x%x or revision 0x%04x\n",
255                         sum, ah->eep_ops->get_eeprom_ver(ah));
256                 return -EINVAL;
257         }
258
259         /* Enable fixup for AR_AN_TOP2 if necessary */
260         if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
261             ((eep->baseEepHeader.version & 0xff) > 0x0a) &&
262             (eep->baseEepHeader.pwdclkind == 0))
263                 ah->need_an_top2_fixup = 1;
264
265         if ((common->bus_ops->ath_bus_type == ATH_USB) &&
266             (AR_SREV_9280(ah)))
267                 eep->modalHeader[0].xpaBiasLvl = 0;
268
269         return 0;
270 }
271
272 static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
273                                    enum eeprom_param param)
274 {
275         struct ar5416_eeprom_def *eep = &ah->eeprom.def;
276         struct modal_eep_header *pModal = eep->modalHeader;
277         struct base_eep_header *pBase = &eep->baseEepHeader;
278
279         switch (param) {
280         case EEP_NFTHRESH_5:
281                 return pModal[0].noiseFloorThreshCh[0];
282         case EEP_NFTHRESH_2:
283                 return pModal[1].noiseFloorThreshCh[0];
284         case EEP_MAC_LSW:
285                 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
286         case EEP_MAC_MID:
287                 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
288         case EEP_MAC_MSW:
289                 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
290         case EEP_REG_0:
291                 return pBase->regDmn[0];
292         case EEP_REG_1:
293                 return pBase->regDmn[1];
294         case EEP_OP_CAP:
295                 return pBase->deviceCap;
296         case EEP_OP_MODE:
297                 return pBase->opCapFlags;
298         case EEP_RF_SILENT:
299                 return pBase->rfSilent;
300         case EEP_OB_5:
301                 return pModal[0].ob;
302         case EEP_DB_5:
303                 return pModal[0].db;
304         case EEP_OB_2:
305                 return pModal[1].ob;
306         case EEP_DB_2:
307                 return pModal[1].db;
308         case EEP_MINOR_REV:
309                 return AR5416_VER_MASK;
310         case EEP_TX_MASK:
311                 return pBase->txMask;
312         case EEP_RX_MASK:
313                 return pBase->rxMask;
314         case EEP_FSTCLK_5G:
315                 return pBase->fastClk5g;
316         case EEP_RXGAIN_TYPE:
317                 return pBase->rxGainType;
318         case EEP_TXGAIN_TYPE:
319                 return pBase->txGainType;
320         case EEP_OL_PWRCTRL:
321                 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
322                         return pBase->openLoopPwrCntl ? 1 : 0;
323                 else
324                         return 0;
325         case EEP_RC_CHAIN_MASK:
326                 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
327                         return pBase->rcChainMask;
328                 else
329                         return 0;
330         case EEP_DAC_HPWR_5G:
331                 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
332                         return pBase->dacHiPwrMode_5G;
333                 else
334                         return 0;
335         case EEP_FRAC_N_5G:
336                 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
337                         return pBase->frac_n_5g;
338                 else
339                         return 0;
340         case EEP_PWR_TABLE_OFFSET:
341                 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21)
342                         return pBase->pwr_table_offset;
343                 else
344                         return AR5416_PWR_TABLE_OFFSET_DB;
345         default:
346                 return 0;
347         }
348 }
349
350 static void ath9k_hw_def_set_gain(struct ath_hw *ah,
351                                   struct modal_eep_header *pModal,
352                                   struct ar5416_eeprom_def *eep,
353                                   u8 txRxAttenLocal, int regChainOffset, int i)
354 {
355         if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
356                 txRxAttenLocal = pModal->txRxAttenCh[i];
357
358                 if (AR_SREV_9280_20_OR_LATER(ah)) {
359                         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
360                               AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
361                               pModal->bswMargin[i]);
362                         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
363                               AR_PHY_GAIN_2GHZ_XATTEN1_DB,
364                               pModal->bswAtten[i]);
365                         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
366                               AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
367                               pModal->xatten2Margin[i]);
368                         REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
369                               AR_PHY_GAIN_2GHZ_XATTEN2_DB,
370                               pModal->xatten2Db[i]);
371                 } else {
372                         REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
373                           (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
374                            ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
375                           | SM(pModal-> bswMargin[i],
376                                AR_PHY_GAIN_2GHZ_BSW_MARGIN));
377                         REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
378                           (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
379                            ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
380                           | SM(pModal->bswAtten[i],
381                                AR_PHY_GAIN_2GHZ_BSW_ATTEN));
382                 }
383         }
384
385         if (AR_SREV_9280_20_OR_LATER(ah)) {
386                 REG_RMW_FIELD(ah,
387                       AR_PHY_RXGAIN + regChainOffset,
388                       AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
389                 REG_RMW_FIELD(ah,
390                       AR_PHY_RXGAIN + regChainOffset,
391                       AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
392         } else {
393                 REG_WRITE(ah,
394                           AR_PHY_RXGAIN + regChainOffset,
395                           (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
396                            ~AR_PHY_RXGAIN_TXRX_ATTEN)
397                           | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
398                 REG_WRITE(ah,
399                           AR_PHY_GAIN_2GHZ + regChainOffset,
400                           (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
401                            ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
402                           SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
403         }
404 }
405
406 static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
407                                           struct ath9k_channel *chan)
408 {
409         struct modal_eep_header *pModal;
410         struct ar5416_eeprom_def *eep = &ah->eeprom.def;
411         int i, regChainOffset;
412         u8 txRxAttenLocal;
413
414         pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
415         txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
416
417         REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
418
419         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
420                 if (AR_SREV_9280(ah)) {
421                         if (i >= 2)
422                                 break;
423                 }
424
425                 if (AR_SREV_5416_20_OR_LATER(ah) &&
426                     (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
427                         regChainOffset = (i == 1) ? 0x2000 : 0x1000;
428                 else
429                         regChainOffset = i * 0x1000;
430
431                 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
432                           pModal->antCtrlChain[i]);
433
434                 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
435                           (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
436                            ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
437                              AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
438                           SM(pModal->iqCalICh[i],
439                              AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
440                           SM(pModal->iqCalQCh[i],
441                              AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
442
443                 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
444                         ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
445                                               regChainOffset, i);
446         }
447
448         if (AR_SREV_9280_20_OR_LATER(ah)) {
449                 if (IS_CHAN_2GHZ(chan)) {
450                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
451                                                   AR_AN_RF2G1_CH0_OB,
452                                                   AR_AN_RF2G1_CH0_OB_S,
453                                                   pModal->ob);
454                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
455                                                   AR_AN_RF2G1_CH0_DB,
456                                                   AR_AN_RF2G1_CH0_DB_S,
457                                                   pModal->db);
458                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
459                                                   AR_AN_RF2G1_CH1_OB,
460                                                   AR_AN_RF2G1_CH1_OB_S,
461                                                   pModal->ob_ch1);
462                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
463                                                   AR_AN_RF2G1_CH1_DB,
464                                                   AR_AN_RF2G1_CH1_DB_S,
465                                                   pModal->db_ch1);
466                 } else {
467                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
468                                                   AR_AN_RF5G1_CH0_OB5,
469                                                   AR_AN_RF5G1_CH0_OB5_S,
470                                                   pModal->ob);
471                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
472                                                   AR_AN_RF5G1_CH0_DB5,
473                                                   AR_AN_RF5G1_CH0_DB5_S,
474                                                   pModal->db);
475                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
476                                                   AR_AN_RF5G1_CH1_OB5,
477                                                   AR_AN_RF5G1_CH1_OB5_S,
478                                                   pModal->ob_ch1);
479                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
480                                                   AR_AN_RF5G1_CH1_DB5,
481                                                   AR_AN_RF5G1_CH1_DB5_S,
482                                                   pModal->db_ch1);
483                 }
484                 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
485                                           AR_AN_TOP2_XPABIAS_LVL,
486                                           AR_AN_TOP2_XPABIAS_LVL_S,
487                                           pModal->xpaBiasLvl);
488                 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
489                                           AR_AN_TOP2_LOCALBIAS,
490                                           AR_AN_TOP2_LOCALBIAS_S,
491                                           !!(pModal->lna_ctl &
492                                              LNA_CTL_LOCAL_BIAS));
493                 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
494                               !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
495         }
496
497         REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
498                       pModal->switchSettling);
499         REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
500                       pModal->adcDesiredSize);
501
502         if (!AR_SREV_9280_20_OR_LATER(ah))
503                 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
504                               AR_PHY_DESIRED_SZ_PGA,
505                               pModal->pgaDesiredSize);
506
507         REG_WRITE(ah, AR_PHY_RF_CTL4,
508                   SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
509                   | SM(pModal->txEndToXpaOff,
510                        AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
511                   | SM(pModal->txFrameToXpaOn,
512                        AR_PHY_RF_CTL4_FRAME_XPAA_ON)
513                   | SM(pModal->txFrameToXpaOn,
514                        AR_PHY_RF_CTL4_FRAME_XPAB_ON));
515
516         REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
517                       pModal->txEndToRxOn);
518
519         if (AR_SREV_9280_20_OR_LATER(ah)) {
520                 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
521                               pModal->thresh62);
522                 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
523                               AR_PHY_EXT_CCA0_THRESH62,
524                               pModal->thresh62);
525         } else {
526                 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
527                               pModal->thresh62);
528                 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
529                               AR_PHY_EXT_CCA_THRESH62,
530                               pModal->thresh62);
531         }
532
533         if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
534                 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
535                               AR_PHY_TX_END_DATA_START,
536                               pModal->txFrameToDataStart);
537                 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
538                               pModal->txFrameToPaOn);
539         }
540
541         if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
542                 if (IS_CHAN_HT40(chan))
543                         REG_RMW_FIELD(ah, AR_PHY_SETTLING,
544                                       AR_PHY_SETTLING_SWITCH,
545                                       pModal->swSettleHt40);
546         }
547
548         if (AR_SREV_9280_20_OR_LATER(ah) &&
549             AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
550                 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
551                               AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
552                               pModal->miscBits);
553
554
555         if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
556                 if (IS_CHAN_2GHZ(chan))
557                         REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
558                                         eep->baseEepHeader.dacLpMode);
559                 else if (eep->baseEepHeader.dacHiPwrMode_5G)
560                         REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
561                 else
562                         REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
563                                       eep->baseEepHeader.dacLpMode);
564
565                 udelay(100);
566
567                 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
568                               pModal->miscBits >> 2);
569
570                 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
571                               AR_PHY_TX_DESIRED_SCALE_CCK,
572                               eep->baseEepHeader.desiredScaleCCK);
573         }
574 }
575
576 static void ath9k_hw_def_set_addac(struct ath_hw *ah,
577                                    struct ath9k_channel *chan)
578 {
579 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
580         struct modal_eep_header *pModal;
581         struct ar5416_eeprom_def *eep = &ah->eeprom.def;
582         u8 biaslevel;
583
584         if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
585                 return;
586
587         if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
588                 return;
589
590         pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
591
592         if (pModal->xpaBiasLvl != 0xff) {
593                 biaslevel = pModal->xpaBiasLvl;
594         } else {
595                 u16 resetFreqBin, freqBin, freqCount = 0;
596                 struct chan_centers centers;
597
598                 ath9k_hw_get_channel_centers(ah, chan, &centers);
599
600                 resetFreqBin = FREQ2FBIN(centers.synth_center,
601                                          IS_CHAN_2GHZ(chan));
602                 freqBin = XPA_LVL_FREQ(0) & 0xff;
603                 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
604
605                 freqCount++;
606
607                 while (freqCount < 3) {
608                         if (XPA_LVL_FREQ(freqCount) == 0x0)
609                                 break;
610
611                         freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
612                         if (resetFreqBin >= freqBin)
613                                 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
614                         else
615                                 break;
616                         freqCount++;
617                 }
618         }
619
620         if (IS_CHAN_2GHZ(chan)) {
621                 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
622                                         7, 1) & (~0x18)) | biaslevel << 3;
623         } else {
624                 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
625                                         6, 1) & (~0xc0)) | biaslevel << 6;
626         }
627 #undef XPA_LVL_FREQ
628 }
629
630 static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
631                                 u16 *gb,
632                                 u16 numXpdGain,
633                                 u16 pdGainOverlap_t2,
634                                 int8_t pwr_table_offset,
635                                 int16_t *diff)
636
637 {
638         u16 k;
639
640         /* Prior to writing the boundaries or the pdadc vs. power table
641          * into the chip registers the default starting point on the pdadc
642          * vs. power table needs to be checked and the curve boundaries
643          * adjusted accordingly
644          */
645         if (AR_SREV_9280_20_OR_LATER(ah)) {
646                 u16 gb_limit;
647
648                 if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
649                         /* get the difference in dB */
650                         *diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);
651                         /* get the number of half dB steps */
652                         *diff *= 2;
653                         /* change the original gain boundary settings
654                          * by the number of half dB steps
655                          */
656                         for (k = 0; k < numXpdGain; k++)
657                                 gb[k] = (u16)(gb[k] - *diff);
658                 }
659                 /* Because of a hardware limitation, ensure the gain boundary
660                  * is not larger than (63 - overlap)
661                  */
662                 gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
663
664                 for (k = 0; k < numXpdGain; k++)
665                         gb[k] = (u16)min(gb_limit, gb[k]);
666         }
667
668         return *diff;
669 }
670
671 static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
672                                       int8_t pwr_table_offset,
673                                       int16_t diff,
674                                       u8 *pdadcValues)
675 {
676 #define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
677         u16 k;
678
679         /* If this is a board that has a pwrTableOffset that differs from
680          * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
681          * pdadc vs pwr table needs to be adjusted prior to writing to the
682          * chip.
683          */
684         if (AR_SREV_9280_20_OR_LATER(ah)) {
685                 if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
686                         /* shift the table to start at the new offset */
687                         for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {
688                                 pdadcValues[k] = pdadcValues[k + diff];
689                         }
690
691                         /* fill the back of the table */
692                         for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) {
693                                 pdadcValues[k] = pdadcValues[NUM_PDADC(diff)];
694                         }
695                 }
696         }
697 #undef NUM_PDADC
698 }
699
700 static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
701                                   struct ath9k_channel *chan,
702                                   int16_t *pTxPowerIndexOffset)
703 {
704 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
705 #define SM_PDGAIN_B(x, y) \
706                 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
707         struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
708         struct cal_data_per_freq *pRawDataset;
709         u8 *pCalBChans = NULL;
710         u16 pdGainOverlap_t2;
711         static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
712         u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
713         u16 numPiers, i, j;
714         int16_t diff = 0;
715         u16 numXpdGain, xpdMask;
716         u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
717         u32 reg32, regOffset, regChainOffset;
718         int16_t modalIdx;
719         int8_t pwr_table_offset;
720
721         modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
722         xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
723
724         pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);
725
726         if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
727             AR5416_EEP_MINOR_VER_2) {
728                 pdGainOverlap_t2 =
729                         pEepData->modalHeader[modalIdx].pdGainOverlap;
730         } else {
731                 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
732                                             AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
733         }
734
735         if (IS_CHAN_2GHZ(chan)) {
736                 pCalBChans = pEepData->calFreqPier2G;
737                 numPiers = AR5416_NUM_2G_CAL_PIERS;
738         } else {
739                 pCalBChans = pEepData->calFreqPier5G;
740                 numPiers = AR5416_NUM_5G_CAL_PIERS;
741         }
742
743         if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
744                 pRawDataset = pEepData->calPierData2G[0];
745                 ah->initPDADC = ((struct calDataPerFreqOpLoop *)
746                                  pRawDataset)->vpdPdg[0][0];
747         }
748
749         numXpdGain = 0;
750
751         for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
752                 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
753                         if (numXpdGain >= AR5416_NUM_PD_GAINS)
754                                 break;
755                         xpdGainValues[numXpdGain] =
756                                 (u16)(AR5416_PD_GAINS_IN_MASK - i);
757                         numXpdGain++;
758                 }
759         }
760
761         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
762                       (numXpdGain - 1) & 0x3);
763         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
764                       xpdGainValues[0]);
765         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
766                       xpdGainValues[1]);
767         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
768                       xpdGainValues[2]);
769
770         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
771                 if (AR_SREV_5416_20_OR_LATER(ah) &&
772                     (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
773                     (i != 0)) {
774                         regChainOffset = (i == 1) ? 0x2000 : 0x1000;
775                 } else
776                         regChainOffset = i * 0x1000;
777
778                 if (pEepData->baseEepHeader.txMask & (1 << i)) {
779                         if (IS_CHAN_2GHZ(chan))
780                                 pRawDataset = pEepData->calPierData2G[i];
781                         else
782                                 pRawDataset = pEepData->calPierData5G[i];
783
784
785                         if (OLC_FOR_AR9280_20_LATER) {
786                                 u8 pcdacIdx;
787                                 u8 txPower;
788
789                                 ath9k_get_txgain_index(ah, chan,
790                                 (struct calDataPerFreqOpLoop *)pRawDataset,
791                                 pCalBChans, numPiers, &txPower, &pcdacIdx);
792                                 ath9k_olc_get_pdadcs(ah, pcdacIdx,
793                                                      txPower/2, pdadcValues);
794                         } else {
795                                 ath9k_hw_get_gain_boundaries_pdadcs(ah,
796                                                         chan, pRawDataset,
797                                                         pCalBChans, numPiers,
798                                                         pdGainOverlap_t2,
799                                                         gainBoundaries,
800                                                         pdadcValues,
801                                                         numXpdGain);
802                         }
803
804                         diff = ath9k_change_gain_boundary_setting(ah,
805                                                            gainBoundaries,
806                                                            numXpdGain,
807                                                            pdGainOverlap_t2,
808                                                            pwr_table_offset,
809                                                            &diff);
810
811                         ENABLE_REGWRITE_BUFFER(ah);
812
813                         if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
814                                 if (OLC_FOR_AR9280_20_LATER) {
815                                         REG_WRITE(ah,
816                                                 AR_PHY_TPCRG5 + regChainOffset,
817                                                 SM(0x6,
818                                                 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
819                                                 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
820                                                 SM_PD_GAIN(3) | SM_PD_GAIN(4));
821                                 } else {
822                                         REG_WRITE(ah,
823                                                 AR_PHY_TPCRG5 + regChainOffset,
824                                                 SM(pdGainOverlap_t2,
825                                                 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
826                                                 SM_PDGAIN_B(0, 1) |
827                                                 SM_PDGAIN_B(1, 2) |
828                                                 SM_PDGAIN_B(2, 3) |
829                                                 SM_PDGAIN_B(3, 4));
830                                 }
831                         }
832
833
834                         ath9k_adjust_pdadc_values(ah, pwr_table_offset,
835                                                   diff, pdadcValues);
836
837                         regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
838                         for (j = 0; j < 32; j++) {
839                                 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
840                                         ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
841                                         ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
842                                         ((pdadcValues[4 * j + 3] & 0xFF) << 24);
843                                 REG_WRITE(ah, regOffset, reg32);
844
845                                 DBG2("ath9k: "
846                                         "PDADC (%d,%4x): %4.4x %8.8x\n",
847                                         i, regChainOffset, regOffset,
848                                         reg32);
849                                 DBG2("ath9k: "
850                                         "PDADC: Chain %d | PDADC %3d "
851                                         "Value %3d | PDADC %3d Value %3d | "
852                                         "PDADC %3d Value %3d | PDADC %3d "
853                                         "Value %3d |\n",
854                                         i, 4 * j, pdadcValues[4 * j],
855                                         4 * j + 1, pdadcValues[4 * j + 1],
856                                         4 * j + 2, pdadcValues[4 * j + 2],
857                                         4 * j + 3, pdadcValues[4 * j + 3]);
858
859                                 regOffset += 4;
860                         }
861                         REGWRITE_BUFFER_FLUSH(ah);
862                 }
863         }
864
865         *pTxPowerIndexOffset = 0;
866 #undef SM_PD_GAIN
867 #undef SM_PDGAIN_B
868 }
869
870 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
871                                                   struct ath9k_channel *chan,
872                                                   int16_t *ratesArray,
873                                                   u16 cfgCtl,
874                                                   u16 AntennaReduction,
875                                                   u16 twiceMaxRegulatoryPower,
876                                                   u16 powerLimit)
877 {
878 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
879 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN   9 /* 10*log10(3)*2 */
880
881         struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
882         struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
883         u16 twiceMaxEdgePower = MAX_RATE_POWER;
884         static const u16 tpScaleReductionTable[5] =
885                 { 0, 3, 6, 9, MAX_RATE_POWER };
886
887         unsigned int i;
888         int16_t twiceLargestAntenna;
889         struct cal_ctl_data *rep;
890         struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
891                 0, { 0, 0, 0, 0}
892         };
893         struct cal_target_power_leg targetPowerOfdmExt = {
894                 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
895                 0, { 0, 0, 0, 0 }
896         };
897         struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
898                 0, {0, 0, 0, 0}
899         };
900         u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
901         static const u16 ctlModesFor11a[] = {
902                 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
903         };
904         static const u16 ctlModesFor11g[] = {
905                 CTL_11B, CTL_11G, CTL_2GHT20,
906                 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
907         };
908         u16 numCtlModes;
909         const u16 *pCtlMode;
910         u16 ctlMode, freq;
911         struct chan_centers centers;
912         int tx_chainmask;
913         u16 twiceMinEdgePower;
914
915         tx_chainmask = ah->txchainmask;
916
917         ath9k_hw_get_channel_centers(ah, chan, &centers);
918
919         twiceLargestAntenna = max(
920                 pEepData->modalHeader
921                         [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
922                 pEepData->modalHeader
923                         [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
924
925         twiceLargestAntenna = max((u8)twiceLargestAntenna,
926                                   pEepData->modalHeader
927                                   [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
928
929         twiceLargestAntenna = (int16_t)min(AntennaReduction -
930                                            twiceLargestAntenna, 0);
931
932         maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
933
934         if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
935                 maxRegAllowedPower -=
936                         (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
937         }
938
939         scaledPower = min(powerLimit, maxRegAllowedPower);
940
941         switch (ar5416_get_ntxchains(tx_chainmask)) {
942         case 1:
943                 break;
944         case 2:
945                 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
946                         scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
947                 else
948                         scaledPower = 0;
949                 break;
950         case 3:
951                 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
952                         scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
953                 else
954                         scaledPower = 0;
955                 break;
956         }
957
958         if (IS_CHAN_2GHZ(chan)) {
959                 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
960                         SUB_NUM_CTL_MODES_AT_2G_40;
961                 pCtlMode = ctlModesFor11g;
962
963                 ath9k_hw_get_legacy_target_powers(ah, chan,
964                         pEepData->calTargetPowerCck,
965                         AR5416_NUM_2G_CCK_TARGET_POWERS,
966                         &targetPowerCck, 4, 0);
967                 ath9k_hw_get_legacy_target_powers(ah, chan,
968                         pEepData->calTargetPower2G,
969                         AR5416_NUM_2G_20_TARGET_POWERS,
970                         &targetPowerOfdm, 4, 0);
971                 ath9k_hw_get_target_powers(ah, chan,
972                         pEepData->calTargetPower2GHT20,
973                         AR5416_NUM_2G_20_TARGET_POWERS,
974                         &targetPowerHt20, 8, 0);
975
976                 if (IS_CHAN_HT40(chan)) {
977                         numCtlModes = ARRAY_SIZE(ctlModesFor11g);
978                         ath9k_hw_get_target_powers(ah, chan,
979                                 pEepData->calTargetPower2GHT40,
980                                 AR5416_NUM_2G_40_TARGET_POWERS,
981                                 &targetPowerHt40, 8, 1);
982                         ath9k_hw_get_legacy_target_powers(ah, chan,
983                                 pEepData->calTargetPowerCck,
984                                 AR5416_NUM_2G_CCK_TARGET_POWERS,
985                                 &targetPowerCckExt, 4, 1);
986                         ath9k_hw_get_legacy_target_powers(ah, chan,
987                                 pEepData->calTargetPower2G,
988                                 AR5416_NUM_2G_20_TARGET_POWERS,
989                                 &targetPowerOfdmExt, 4, 1);
990                 }
991         } else {
992                 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
993                         SUB_NUM_CTL_MODES_AT_5G_40;
994                 pCtlMode = ctlModesFor11a;
995
996                 ath9k_hw_get_legacy_target_powers(ah, chan,
997                         pEepData->calTargetPower5G,
998                         AR5416_NUM_5G_20_TARGET_POWERS,
999                         &targetPowerOfdm, 4, 0);
1000                 ath9k_hw_get_target_powers(ah, chan,
1001                         pEepData->calTargetPower5GHT20,
1002                         AR5416_NUM_5G_20_TARGET_POWERS,
1003                         &targetPowerHt20, 8, 0);
1004
1005                 if (IS_CHAN_HT40(chan)) {
1006                         numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1007                         ath9k_hw_get_target_powers(ah, chan,
1008                                 pEepData->calTargetPower5GHT40,
1009                                 AR5416_NUM_5G_40_TARGET_POWERS,
1010                                 &targetPowerHt40, 8, 1);
1011                         ath9k_hw_get_legacy_target_powers(ah, chan,
1012                                 pEepData->calTargetPower5G,
1013                                 AR5416_NUM_5G_20_TARGET_POWERS,
1014                                 &targetPowerOfdmExt, 4, 1);
1015                 }
1016         }
1017
1018         for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1019                 int isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1020                         (pCtlMode[ctlMode] == CTL_2GHT40);
1021                 if (isHt40CtlMode)
1022                         freq = centers.synth_center;
1023                 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1024                         freq = centers.ext_center;
1025                 else
1026                         freq = centers.ctl_center;
1027
1028                 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
1029                     ah->eep_ops->get_eeprom_rev(ah) <= 2)
1030                         twiceMaxEdgePower = MAX_RATE_POWER;
1031
1032                 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1033                         if ((((cfgCtl & ~CTL_MODE_M) |
1034                               (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1035                              pEepData->ctlIndex[i]) ||
1036                             (((cfgCtl & ~CTL_MODE_M) |
1037                               (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1038                              ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1039                                 rep = &(pEepData->ctlData[i]);
1040
1041                                 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1042                                 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1043                                 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1044
1045                                 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1046                                         twiceMaxEdgePower = min(twiceMaxEdgePower,
1047                                                                 twiceMinEdgePower);
1048                                 } else {
1049                                         twiceMaxEdgePower = twiceMinEdgePower;
1050                                         break;
1051                                 }
1052                         }
1053                 }
1054
1055                 minCtlPower = min(twiceMaxEdgePower, scaledPower);
1056
1057                 switch (pCtlMode[ctlMode]) {
1058                 case CTL_11B:
1059                         for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1060                                 targetPowerCck.tPow2x[i] =
1061                                         min((u16)targetPowerCck.tPow2x[i],
1062                                             minCtlPower);
1063                         }
1064                         break;
1065                 case CTL_11A:
1066                 case CTL_11G:
1067                         for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1068                                 targetPowerOfdm.tPow2x[i] =
1069                                         min((u16)targetPowerOfdm.tPow2x[i],
1070                                             minCtlPower);
1071                         }
1072                         break;
1073                 case CTL_5GHT20:
1074                 case CTL_2GHT20:
1075                         for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1076                                 targetPowerHt20.tPow2x[i] =
1077                                         min((u16)targetPowerHt20.tPow2x[i],
1078                                             minCtlPower);
1079                         }
1080                         break;
1081                 case CTL_11B_EXT:
1082                         targetPowerCckExt.tPow2x[0] = min((u16)
1083                                         targetPowerCckExt.tPow2x[0],
1084                                         minCtlPower);
1085                         break;
1086                 case CTL_11A_EXT:
1087                 case CTL_11G_EXT:
1088                         targetPowerOfdmExt.tPow2x[0] = min((u16)
1089                                         targetPowerOfdmExt.tPow2x[0],
1090                                         minCtlPower);
1091                         break;
1092                 case CTL_5GHT40:
1093                 case CTL_2GHT40:
1094                         for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1095                                 targetPowerHt40.tPow2x[i] =
1096                                         min((u16)targetPowerHt40.tPow2x[i],
1097                                             minCtlPower);
1098                         }
1099                         break;
1100                 default:
1101                         break;
1102                 }
1103         }
1104
1105         ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1106                 ratesArray[rate18mb] = ratesArray[rate24mb] =
1107                 targetPowerOfdm.tPow2x[0];
1108         ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1109         ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1110         ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1111         ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1112
1113         for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1114                 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1115
1116         if (IS_CHAN_2GHZ(chan)) {
1117                 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1118                 ratesArray[rate2s] = ratesArray[rate2l] =
1119                         targetPowerCck.tPow2x[1];
1120                 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1121                         targetPowerCck.tPow2x[2];
1122                 ratesArray[rate11s] = ratesArray[rate11l] =
1123                         targetPowerCck.tPow2x[3];
1124         }
1125         if (IS_CHAN_HT40(chan)) {
1126                 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1127                         ratesArray[rateHt40_0 + i] =
1128                                 targetPowerHt40.tPow2x[i];
1129                 }
1130                 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1131                 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1132                 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1133                 if (IS_CHAN_2GHZ(chan)) {
1134                         ratesArray[rateExtCck] =
1135                                 targetPowerCckExt.tPow2x[0];
1136                 }
1137         }
1138 }
1139
1140 static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1141                                     struct ath9k_channel *chan,
1142                                     u16 cfgCtl,
1143                                     u8 twiceAntennaReduction,
1144                                     u8 twiceMaxRegulatoryPower,
1145                                     u8 powerLimit, int test)
1146 {
1147 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1148         struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1149         struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1150         struct modal_eep_header *pModal =
1151                 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1152         int16_t ratesArray[Ar5416RateSize];
1153         int16_t txPowerIndexOffset = 0;
1154         u8 ht40PowerIncForPdadc = 2;
1155         unsigned int i, cck_ofdm_delta = 0;
1156
1157         memset(ratesArray, 0, sizeof(ratesArray));
1158
1159         if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1160             AR5416_EEP_MINOR_VER_2) {
1161                 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1162         }
1163
1164         ath9k_hw_set_def_power_per_rate_table(ah, chan,
1165                                                &ratesArray[0], cfgCtl,
1166                                                twiceAntennaReduction,
1167                                                twiceMaxRegulatoryPower,
1168                                                powerLimit);
1169
1170         ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
1171
1172         regulatory->max_power_level = 0;
1173         for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1174                 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1175                 if (ratesArray[i] > MAX_RATE_POWER)
1176                         ratesArray[i] = MAX_RATE_POWER;
1177                 if (ratesArray[i] > regulatory->max_power_level)
1178                         regulatory->max_power_level = ratesArray[i];
1179         }
1180
1181         if (!test) {
1182                 i = rate6mb;
1183
1184                 if (IS_CHAN_HT40(chan))
1185                         i = rateHt40_0;
1186                 else if (IS_CHAN_HT20(chan))
1187                         i = rateHt20_0;
1188
1189                 regulatory->max_power_level = ratesArray[i];
1190         }
1191
1192         switch(ar5416_get_ntxchains(ah->txchainmask)) {
1193         case 1:
1194                 break;
1195         case 2:
1196                 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1197                 break;
1198         case 3:
1199                 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1200                 break;
1201         default:
1202                 DBG2("ath9k: "
1203                         "Invalid chainmask configuration\n");
1204                 break;
1205         }
1206
1207         if (test)
1208                 return;
1209
1210         if (AR_SREV_9280_20_OR_LATER(ah)) {
1211                 for (i = 0; i < Ar5416RateSize; i++) {
1212                         int8_t pwr_table_offset;
1213
1214                         pwr_table_offset = ah->eep_ops->get_eeprom(ah,
1215                                                         EEP_PWR_TABLE_OFFSET);
1216                         ratesArray[i] -= pwr_table_offset * 2;
1217                 }
1218         }
1219
1220         ENABLE_REGWRITE_BUFFER(ah);
1221
1222         REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1223                   ATH9K_POW_SM(ratesArray[rate18mb], 24)
1224                   | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1225                   | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1226                   | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1227         REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1228                   ATH9K_POW_SM(ratesArray[rate54mb], 24)
1229                   | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1230                   | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1231                   | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1232
1233         if (IS_CHAN_2GHZ(chan)) {
1234                 if (OLC_FOR_AR9280_20_LATER) {
1235                         cck_ofdm_delta = 2;
1236                         REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1237                                 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
1238                                 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
1239                                 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1240                                 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
1241                         REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1242                                 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
1243                                 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
1244                                 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
1245                                 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
1246                 } else {
1247                         REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1248                                 ATH9K_POW_SM(ratesArray[rate2s], 24)
1249                                 | ATH9K_POW_SM(ratesArray[rate2l], 16)
1250                                 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1251                                 | ATH9K_POW_SM(ratesArray[rate1l], 0));
1252                         REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1253                                 ATH9K_POW_SM(ratesArray[rate11s], 24)
1254                                 | ATH9K_POW_SM(ratesArray[rate11l], 16)
1255                                 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1256                                 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1257                 }
1258         }
1259
1260         REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1261                   ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
1262                   | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1263                   | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1264                   | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1265         REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1266                   ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1267                   | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1268                   | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1269                   | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1270
1271         if (IS_CHAN_HT40(chan)) {
1272                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1273                           ATH9K_POW_SM(ratesArray[rateHt40_3] +
1274                                        ht40PowerIncForPdadc, 24)
1275                           | ATH9K_POW_SM(ratesArray[rateHt40_2] +
1276                                          ht40PowerIncForPdadc, 16)
1277                           | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1278                                          ht40PowerIncForPdadc, 8)
1279                           | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1280                                          ht40PowerIncForPdadc, 0));
1281                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1282                           ATH9K_POW_SM(ratesArray[rateHt40_7] +
1283                                        ht40PowerIncForPdadc, 24)
1284                           | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1285                                          ht40PowerIncForPdadc, 16)
1286                           | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1287                                          ht40PowerIncForPdadc, 8)
1288                           | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1289                                          ht40PowerIncForPdadc, 0));
1290                 if (OLC_FOR_AR9280_20_LATER) {
1291                         REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1292                                 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1293                                 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
1294                                 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1295                                 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
1296                 } else {
1297                         REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1298                                 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1299                                 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
1300                                 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1301                                 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1302                 }
1303         }
1304
1305         REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1306                   ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1307                   | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1308
1309         REGWRITE_BUFFER_FLUSH(ah);
1310 }
1311
1312 static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, int is2GHz)
1313 {
1314 #define EEP_DEF_SPURCHAN \
1315         (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1316
1317         u16 spur_val = AR_NO_SPUR;
1318
1319         DBG2("ath9k: "
1320                 "Getting spur idx:%d is2Ghz:%d val:%x\n",
1321                 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1322
1323         switch (ah->config.spurmode) {
1324         case SPUR_DISABLE:
1325                 break;
1326         case SPUR_ENABLE_IOCTL:
1327                 spur_val = ah->config.spurchans[i][is2GHz];
1328                 DBG2("ath9k: "
1329                         "Getting spur val from new loc. %d\n", spur_val);
1330                 break;
1331         case SPUR_ENABLE_EEPROM:
1332                 spur_val = EEP_DEF_SPURCHAN;
1333                 break;
1334         }
1335
1336         return spur_val;
1337
1338 #undef EEP_DEF_SPURCHAN
1339 }
1340
1341 const struct eeprom_ops eep_def_ops = {
1342         .check_eeprom           = ath9k_hw_def_check_eeprom,
1343         .get_eeprom             = ath9k_hw_def_get_eeprom,
1344         .fill_eeprom            = ath9k_hw_def_fill_eeprom,
1345         .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
1346         .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
1347         .set_board_values       = ath9k_hw_def_set_board_values,
1348         .set_addac              = ath9k_hw_def_set_addac,
1349         .set_txpower            = ath9k_hw_def_set_txpower,
1350         .get_spur_channel       = ath9k_hw_def_get_spur_channel
1351 };