2 * Copyright (c) 2008-2009 Atheros Communications Inc.
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.
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.
18 #include "ar9002_phy.h"
20 static void ath9k_get_txgain_index(struct ath_hw
*ah
,
21 struct ath9k_channel
*chan
,
22 struct calDataPerFreqOpLoop
*rawDatasetOpLoop
,
23 u8
*calChans
, u16 availPiers
, u8
*pwr
, u8
*pcdacIdx
)
26 u16 idxL
= 0, idxR
= 0, numPiers
;
28 struct chan_centers centers
;
30 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
32 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++)
33 if (calChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
36 match
= ath9k_hw_get_lower_upper_index(
37 (u8
)FREQ2FBIN(centers
.synth_center
, IS_CHAN_2GHZ(chan
)),
38 calChans
, numPiers
, &idxL
, &idxR
);
40 pcdac
= rawDatasetOpLoop
[idxL
].pcdac
[0][0];
41 *pwr
= rawDatasetOpLoop
[idxL
].pwrPdg
[0][0];
43 pcdac
= rawDatasetOpLoop
[idxR
].pcdac
[0][0];
44 *pwr
= (rawDatasetOpLoop
[idxL
].pwrPdg
[0][0] +
45 rawDatasetOpLoop
[idxR
].pwrPdg
[0][0])/2;
48 while (pcdac
> ah
->originalGain
[i
] &&
49 i
< (AR9280_TX_GAIN_TABLE_SIZE
- 1))
55 static void ath9k_olc_get_pdadcs(struct ath_hw
*ah
,
63 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL6_0
,
64 AR_PHY_TX_PWRCTRL_ERR_EST_MODE
, 3);
65 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL6_1
,
66 AR_PHY_TX_PWRCTRL_ERR_EST_MODE
, 3);
68 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL7
,
69 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN
, initTxGain
);
72 for (i
= 0; i
< AR5416_NUM_PDADC_VALUES
; i
++)
74 pPDADCValues
[i
] = 0x0;
76 pPDADCValues
[i
] = 0xFF;
79 static int ath9k_hw_def_get_eeprom_ver(struct ath_hw
*ah
)
81 return ((ah
->eeprom
.def
.baseEepHeader
.version
>> 12) & 0xF);
84 static int ath9k_hw_def_get_eeprom_rev(struct ath_hw
*ah
)
86 return ((ah
->eeprom
.def
.baseEepHeader
.version
) & 0xFFF);
89 static bool ath9k_hw_def_fill_eeprom(struct ath_hw
*ah
)
91 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
92 struct ath_common
*common
= ath9k_hw_common(ah
);
93 u16
*eep_data
= (u16
*)&ah
->eeprom
.def
;
94 int addr
, ar5416_eep_start_loc
= 0x100;
96 for (addr
= 0; addr
< SIZE_EEPROM_DEF
; addr
++) {
97 if (!ath9k_hw_nvram_read(common
, addr
+ ar5416_eep_start_loc
,
99 ath_err(ath9k_hw_common(ah
),
100 "Unable to read eeprom region\n");
106 #undef SIZE_EEPROM_DEF
109 static int ath9k_hw_def_check_eeprom(struct ath_hw
*ah
)
111 struct ar5416_eeprom_def
*eep
=
112 (struct ar5416_eeprom_def
*) &ah
->eeprom
.def
;
113 struct ath_common
*common
= ath9k_hw_common(ah
);
114 u16
*eepdata
, temp
, magic
, magic2
;
116 bool need_swap
= false;
119 if (!ath9k_hw_nvram_read(common
, AR5416_EEPROM_MAGIC_OFFSET
, &magic
)) {
120 ath_err(common
, "Reading Magic # failed\n");
124 if (!ath9k_hw_use_flash(ah
)) {
125 ath_dbg(common
, ATH_DBG_EEPROM
,
126 "Read Magic = 0x%04X\n", magic
);
128 if (magic
!= AR5416_EEPROM_MAGIC
) {
129 magic2
= swab16(magic
);
131 if (magic2
== AR5416_EEPROM_MAGIC
) {
132 size
= sizeof(struct ar5416_eeprom_def
);
134 eepdata
= (u16
*) (&ah
->eeprom
);
136 for (addr
= 0; addr
< size
/ sizeof(u16
); addr
++) {
137 temp
= swab16(*eepdata
);
143 "Invalid EEPROM Magic. Endianness mismatch.\n");
149 ath_dbg(common
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
150 need_swap
? "True" : "False");
153 el
= swab16(ah
->eeprom
.def
.baseEepHeader
.length
);
155 el
= ah
->eeprom
.def
.baseEepHeader
.length
;
157 if (el
> sizeof(struct ar5416_eeprom_def
))
158 el
= sizeof(struct ar5416_eeprom_def
) / sizeof(u16
);
160 el
= el
/ sizeof(u16
);
162 eepdata
= (u16
*)(&ah
->eeprom
);
164 for (i
= 0; i
< el
; i
++)
171 ath_dbg(common
, ATH_DBG_EEPROM
,
172 "EEPROM Endianness is not native.. Changing.\n");
174 word
= swab16(eep
->baseEepHeader
.length
);
175 eep
->baseEepHeader
.length
= word
;
177 word
= swab16(eep
->baseEepHeader
.checksum
);
178 eep
->baseEepHeader
.checksum
= word
;
180 word
= swab16(eep
->baseEepHeader
.version
);
181 eep
->baseEepHeader
.version
= word
;
183 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
184 eep
->baseEepHeader
.regDmn
[0] = word
;
186 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
187 eep
->baseEepHeader
.regDmn
[1] = word
;
189 word
= swab16(eep
->baseEepHeader
.rfSilent
);
190 eep
->baseEepHeader
.rfSilent
= word
;
192 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
193 eep
->baseEepHeader
.blueToothOptions
= word
;
195 word
= swab16(eep
->baseEepHeader
.deviceCap
);
196 eep
->baseEepHeader
.deviceCap
= word
;
198 for (j
= 0; j
< ARRAY_SIZE(eep
->modalHeader
); j
++) {
199 struct modal_eep_header
*pModal
=
200 &eep
->modalHeader
[j
];
201 integer
= swab32(pModal
->antCtrlCommon
);
202 pModal
->antCtrlCommon
= integer
;
204 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
205 integer
= swab32(pModal
->antCtrlChain
[i
]);
206 pModal
->antCtrlChain
[i
] = integer
;
209 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
210 word
= swab16(pModal
->spurChans
[i
].spurChan
);
211 pModal
->spurChans
[i
].spurChan
= word
;
216 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR5416_EEP_VER
||
217 ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
218 ath_err(common
, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
219 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
223 /* Enable fixup for AR_AN_TOP2 if necessary */
224 if (AR_SREV_9280_20_OR_LATER(ah
) &&
225 (eep
->baseEepHeader
.version
& 0xff) > 0x0a &&
226 eep
->baseEepHeader
.pwdclkind
== 0)
227 ah
->need_an_top2_fixup
= 1;
232 static u32
ath9k_hw_def_get_eeprom(struct ath_hw
*ah
,
233 enum eeprom_param param
)
235 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
236 struct modal_eep_header
*pModal
= eep
->modalHeader
;
237 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
241 return pModal
[0].noiseFloorThreshCh
[0];
243 return pModal
[1].noiseFloorThreshCh
[0];
245 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
247 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
249 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
251 return pBase
->regDmn
[0];
253 return pBase
->regDmn
[1];
255 return pBase
->deviceCap
;
257 return pBase
->opCapFlags
;
259 return pBase
->rfSilent
;
269 return AR5416_VER_MASK
;
271 return pBase
->txMask
;
273 return pBase
->rxMask
;
275 return pBase
->fastClk5g
;
276 case EEP_RXGAIN_TYPE
:
277 return pBase
->rxGainType
;
278 case EEP_TXGAIN_TYPE
:
279 return pBase
->txGainType
;
281 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
282 return pBase
->openLoopPwrCntl
? true : false;
285 case EEP_RC_CHAIN_MASK
:
286 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
287 return pBase
->rcChainMask
;
290 case EEP_DAC_HPWR_5G
:
291 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_20
)
292 return pBase
->dacHiPwrMode_5G
;
296 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_22
)
297 return pBase
->frac_n_5g
;
300 case EEP_PWR_TABLE_OFFSET
:
301 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_21
)
302 return pBase
->pwr_table_offset
;
304 return AR5416_PWR_TABLE_OFFSET_DB
;
310 static void ath9k_hw_def_set_gain(struct ath_hw
*ah
,
311 struct modal_eep_header
*pModal
,
312 struct ar5416_eeprom_def
*eep
,
313 u8 txRxAttenLocal
, int regChainOffset
, int i
)
315 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_3
) {
316 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
318 if (AR_SREV_9280_20_OR_LATER(ah
)) {
319 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
320 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
321 pModal
->bswMargin
[i
]);
322 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
323 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
324 pModal
->bswAtten
[i
]);
325 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
326 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
327 pModal
->xatten2Margin
[i
]);
328 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
329 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
330 pModal
->xatten2Db
[i
]);
332 REG_WRITE(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
333 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
334 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN
)
335 | SM(pModal
-> bswMargin
[i
],
336 AR_PHY_GAIN_2GHZ_BSW_MARGIN
));
337 REG_WRITE(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
338 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
339 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN
)
340 | SM(pModal
->bswAtten
[i
],
341 AR_PHY_GAIN_2GHZ_BSW_ATTEN
));
345 if (AR_SREV_9280_20_OR_LATER(ah
)) {
347 AR_PHY_RXGAIN
+ regChainOffset
,
348 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
350 AR_PHY_RXGAIN
+ regChainOffset
,
351 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[i
]);
354 AR_PHY_RXGAIN
+ regChainOffset
,
355 (REG_READ(ah
, AR_PHY_RXGAIN
+ regChainOffset
) &
356 ~AR_PHY_RXGAIN_TXRX_ATTEN
)
357 | SM(txRxAttenLocal
, AR_PHY_RXGAIN_TXRX_ATTEN
));
359 AR_PHY_GAIN_2GHZ
+ regChainOffset
,
360 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
361 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN
) |
362 SM(pModal
->rxTxMarginCh
[i
], AR_PHY_GAIN_2GHZ_RXTX_MARGIN
));
366 static void ath9k_hw_def_set_board_values(struct ath_hw
*ah
,
367 struct ath9k_channel
*chan
)
369 struct modal_eep_header
*pModal
;
370 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
371 int i
, regChainOffset
;
374 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
375 txRxAttenLocal
= IS_CHAN_2GHZ(chan
) ? 23 : 44;
377 REG_WRITE(ah
, AR_PHY_SWITCH_COM
, pModal
->antCtrlCommon
& 0xffff);
379 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
380 if (AR_SREV_9280(ah
)) {
385 if (AR_SREV_5416_20_OR_LATER(ah
) &&
386 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) && (i
!= 0))
387 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
389 regChainOffset
= i
* 0x1000;
391 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
392 pModal
->antCtrlChain
[i
]);
394 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
395 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
) &
396 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
397 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
398 SM(pModal
->iqCalICh
[i
],
399 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
400 SM(pModal
->iqCalQCh
[i
],
401 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
403 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
))
404 ath9k_hw_def_set_gain(ah
, pModal
, eep
, txRxAttenLocal
,
408 if (AR_SREV_9280_20_OR_LATER(ah
)) {
409 if (IS_CHAN_2GHZ(chan
)) {
410 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
412 AR_AN_RF2G1_CH0_OB_S
,
414 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
416 AR_AN_RF2G1_CH0_DB_S
,
418 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
420 AR_AN_RF2G1_CH1_OB_S
,
422 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
424 AR_AN_RF2G1_CH1_DB_S
,
427 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
429 AR_AN_RF5G1_CH0_OB5_S
,
431 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
433 AR_AN_RF5G1_CH0_DB5_S
,
435 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
437 AR_AN_RF5G1_CH1_OB5_S
,
439 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
441 AR_AN_RF5G1_CH1_DB5_S
,
444 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
445 AR_AN_TOP2_XPABIAS_LVL
,
446 AR_AN_TOP2_XPABIAS_LVL_S
,
448 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
449 AR_AN_TOP2_LOCALBIAS
,
450 AR_AN_TOP2_LOCALBIAS_S
,
452 LNA_CTL_LOCAL_BIAS
));
453 REG_RMW_FIELD(ah
, AR_PHY_XPA_CFG
, AR_PHY_FORCE_XPA_CFG
,
454 !!(pModal
->lna_ctl
& LNA_CTL_FORCE_XPA
));
457 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
458 pModal
->switchSettling
);
459 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
460 pModal
->adcDesiredSize
);
462 if (!AR_SREV_9280_20_OR_LATER(ah
))
463 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
464 AR_PHY_DESIRED_SZ_PGA
,
465 pModal
->pgaDesiredSize
);
467 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
468 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
469 | SM(pModal
->txEndToXpaOff
,
470 AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
471 | SM(pModal
->txFrameToXpaOn
,
472 AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
473 | SM(pModal
->txFrameToXpaOn
,
474 AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
476 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
477 pModal
->txEndToRxOn
);
479 if (AR_SREV_9280_20_OR_LATER(ah
)) {
480 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
482 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
483 AR_PHY_EXT_CCA0_THRESH62
,
486 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR_PHY_CCA_THRESH62
,
488 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA
,
489 AR_PHY_EXT_CCA_THRESH62
,
493 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_2
) {
494 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
495 AR_PHY_TX_END_DATA_START
,
496 pModal
->txFrameToDataStart
);
497 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
498 pModal
->txFrameToPaOn
);
501 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_3
) {
502 if (IS_CHAN_HT40(chan
))
503 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
504 AR_PHY_SETTLING_SWITCH
,
505 pModal
->swSettleHt40
);
508 if (AR_SREV_9280_20_OR_LATER(ah
) &&
509 AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
510 REG_RMW_FIELD(ah
, AR_PHY_CCK_TX_CTRL
,
511 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK
,
515 if (AR_SREV_9280_20(ah
) && AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_20
) {
516 if (IS_CHAN_2GHZ(chan
))
517 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
,
518 eep
->baseEepHeader
.dacLpMode
);
519 else if (eep
->baseEepHeader
.dacHiPwrMode_5G
)
520 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
, 0);
522 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
,
523 eep
->baseEepHeader
.dacLpMode
);
527 REG_RMW_FIELD(ah
, AR_PHY_FRAME_CTL
, AR_PHY_FRAME_CTL_TX_CLIP
,
528 pModal
->miscBits
>> 2);
530 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL9
,
531 AR_PHY_TX_DESIRED_SCALE_CCK
,
532 eep
->baseEepHeader
.desiredScaleCCK
);
536 static void ath9k_hw_def_set_addac(struct ath_hw
*ah
,
537 struct ath9k_channel
*chan
)
539 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
540 struct modal_eep_header
*pModal
;
541 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
544 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
547 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
550 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
552 if (pModal
->xpaBiasLvl
!= 0xff) {
553 biaslevel
= pModal
->xpaBiasLvl
;
555 u16 resetFreqBin
, freqBin
, freqCount
= 0;
556 struct chan_centers centers
;
558 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
560 resetFreqBin
= FREQ2FBIN(centers
.synth_center
,
562 freqBin
= XPA_LVL_FREQ(0) & 0xff;
563 biaslevel
= (u8
) (XPA_LVL_FREQ(0) >> 14);
567 while (freqCount
< 3) {
568 if (XPA_LVL_FREQ(freqCount
) == 0x0)
571 freqBin
= XPA_LVL_FREQ(freqCount
) & 0xff;
572 if (resetFreqBin
>= freqBin
)
573 biaslevel
= (u8
)(XPA_LVL_FREQ(freqCount
) >> 14);
580 if (IS_CHAN_2GHZ(chan
)) {
581 INI_RA(&ah
->iniAddac
, 7, 1) = (INI_RA(&ah
->iniAddac
,
582 7, 1) & (~0x18)) | biaslevel
<< 3;
584 INI_RA(&ah
->iniAddac
, 6, 1) = (INI_RA(&ah
->iniAddac
,
585 6, 1) & (~0xc0)) | biaslevel
<< 6;
590 static int16_t ath9k_change_gain_boundary_setting(struct ath_hw
*ah
,
593 u16 pdGainOverlap_t2
,
594 int8_t pwr_table_offset
,
600 /* Prior to writing the boundaries or the pdadc vs. power table
601 * into the chip registers the default starting point on the pdadc
602 * vs. power table needs to be checked and the curve boundaries
603 * adjusted accordingly
605 if (AR_SREV_9280_20_OR_LATER(ah
)) {
608 if (AR5416_PWR_TABLE_OFFSET_DB
!= pwr_table_offset
) {
609 /* get the difference in dB */
610 *diff
= (u16
)(pwr_table_offset
- AR5416_PWR_TABLE_OFFSET_DB
);
611 /* get the number of half dB steps */
613 /* change the original gain boundary settings
614 * by the number of half dB steps
616 for (k
= 0; k
< numXpdGain
; k
++)
617 gb
[k
] = (u16
)(gb
[k
] - *diff
);
619 /* Because of a hardware limitation, ensure the gain boundary
620 * is not larger than (63 - overlap)
622 gb_limit
= (u16
)(MAX_RATE_POWER
- pdGainOverlap_t2
);
624 for (k
= 0; k
< numXpdGain
; k
++)
625 gb
[k
] = (u16
)min(gb_limit
, gb
[k
]);
631 static void ath9k_adjust_pdadc_values(struct ath_hw
*ah
,
632 int8_t pwr_table_offset
,
636 #define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
639 /* If this is a board that has a pwrTableOffset that differs from
640 * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
641 * pdadc vs pwr table needs to be adjusted prior to writing to the
644 if (AR_SREV_9280_20_OR_LATER(ah
)) {
645 if (AR5416_PWR_TABLE_OFFSET_DB
!= pwr_table_offset
) {
646 /* shift the table to start at the new offset */
647 for (k
= 0; k
< (u16
)NUM_PDADC(diff
); k
++ ) {
648 pdadcValues
[k
] = pdadcValues
[k
+ diff
];
651 /* fill the back of the table */
652 for (k
= (u16
)NUM_PDADC(diff
); k
< NUM_PDADC(0); k
++) {
653 pdadcValues
[k
] = pdadcValues
[NUM_PDADC(diff
)];
660 static void ath9k_hw_set_def_power_cal_table(struct ath_hw
*ah
,
661 struct ath9k_channel
*chan
,
662 int16_t *pTxPowerIndexOffset
)
664 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
665 #define SM_PDGAIN_B(x, y) \
666 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
667 struct ath_common
*common
= ath9k_hw_common(ah
);
668 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
669 struct cal_data_per_freq
*pRawDataset
;
670 u8
*pCalBChans
= NULL
;
671 u16 pdGainOverlap_t2
;
672 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
673 u16 gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
676 u16 numXpdGain
, xpdMask
;
677 u16 xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
678 u32 reg32
, regOffset
, regChainOffset
;
680 int8_t pwr_table_offset
;
682 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
683 xpdMask
= pEepData
->modalHeader
[modalIdx
].xpdGain
;
685 pwr_table_offset
= ah
->eep_ops
->get_eeprom(ah
, EEP_PWR_TABLE_OFFSET
);
687 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
688 AR5416_EEP_MINOR_VER_2
) {
690 pEepData
->modalHeader
[modalIdx
].pdGainOverlap
;
692 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
693 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
696 if (IS_CHAN_2GHZ(chan
)) {
697 pCalBChans
= pEepData
->calFreqPier2G
;
698 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
700 pCalBChans
= pEepData
->calFreqPier5G
;
701 numPiers
= AR5416_NUM_5G_CAL_PIERS
;
704 if (OLC_FOR_AR9280_20_LATER
&& IS_CHAN_2GHZ(chan
)) {
705 pRawDataset
= pEepData
->calPierData2G
[0];
706 ah
->initPDADC
= ((struct calDataPerFreqOpLoop
*)
707 pRawDataset
)->vpdPdg
[0][0];
712 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
713 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
714 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
716 xpdGainValues
[numXpdGain
] =
717 (u16
)(AR5416_PD_GAINS_IN_MASK
- i
);
722 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
723 (numXpdGain
- 1) & 0x3);
724 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
726 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
728 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
731 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
732 if (AR_SREV_5416_20_OR_LATER(ah
) &&
733 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
735 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
737 regChainOffset
= i
* 0x1000;
739 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
740 if (IS_CHAN_2GHZ(chan
))
741 pRawDataset
= pEepData
->calPierData2G
[i
];
743 pRawDataset
= pEepData
->calPierData5G
[i
];
746 if (OLC_FOR_AR9280_20_LATER
) {
750 ath9k_get_txgain_index(ah
, chan
,
751 (struct calDataPerFreqOpLoop
*)pRawDataset
,
752 pCalBChans
, numPiers
, &txPower
, &pcdacIdx
);
753 ath9k_olc_get_pdadcs(ah
, pcdacIdx
,
754 txPower
/2, pdadcValues
);
756 ath9k_hw_get_gain_boundaries_pdadcs(ah
,
758 pCalBChans
, numPiers
,
765 diff
= ath9k_change_gain_boundary_setting(ah
,
772 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
773 if (OLC_FOR_AR9280_20_LATER
) {
775 AR_PHY_TPCRG5
+ regChainOffset
,
777 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
) |
778 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
779 SM_PD_GAIN(3) | SM_PD_GAIN(4));
782 AR_PHY_TPCRG5
+ regChainOffset
,
784 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)|
793 ath9k_adjust_pdadc_values(ah
, pwr_table_offset
,
796 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
797 for (j
= 0; j
< 32; j
++) {
798 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
799 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
800 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
801 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
802 REG_WRITE(ah
, regOffset
, reg32
);
804 ath_dbg(common
, ATH_DBG_EEPROM
,
805 "PDADC (%d,%4x): %4.4x %8.8x\n",
806 i
, regChainOffset
, regOffset
,
808 ath_dbg(common
, ATH_DBG_EEPROM
,
809 "PDADC: Chain %d | PDADC %3d "
810 "Value %3d | PDADC %3d Value %3d | "
811 "PDADC %3d Value %3d | PDADC %3d "
813 i
, 4 * j
, pdadcValues
[4 * j
],
814 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
815 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
816 4 * j
+ 3, pdadcValues
[4 * j
+ 3]);
823 *pTxPowerIndexOffset
= 0;
828 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw
*ah
,
829 struct ath9k_channel
*chan
,
832 u16 AntennaReduction
,
833 u16 twiceMaxRegulatoryPower
,
836 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
837 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
839 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
840 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
841 u16 twiceMaxEdgePower
= MAX_RATE_POWER
;
842 static const u16 tpScaleReductionTable
[5] =
843 { 0, 3, 6, 9, MAX_RATE_POWER
};
846 int16_t twiceLargestAntenna
;
847 struct cal_ctl_data
*rep
;
848 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
851 struct cal_target_power_leg targetPowerOfdmExt
= {
852 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
855 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
858 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
859 static const u16 ctlModesFor11a
[] = {
860 CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
862 static const u16 ctlModesFor11g
[] = {
863 CTL_11B
, CTL_11G
, CTL_2GHT20
,
864 CTL_11B_EXT
, CTL_11G_EXT
, CTL_2GHT40
869 struct chan_centers centers
;
871 u16 twiceMinEdgePower
;
873 tx_chainmask
= ah
->txchainmask
;
875 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
877 twiceLargestAntenna
= max(
878 pEepData
->modalHeader
879 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[0],
880 pEepData
->modalHeader
881 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[1]);
883 twiceLargestAntenna
= max((u8
)twiceLargestAntenna
,
884 pEepData
->modalHeader
885 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[2]);
887 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
888 twiceLargestAntenna
, 0);
890 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
892 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
893 maxRegAllowedPower
-=
894 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
897 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
899 switch (ar5416_get_ntxchains(tx_chainmask
)) {
903 if (scaledPower
> REDUCE_SCALED_POWER_BY_TWO_CHAIN
)
904 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
909 if (scaledPower
> REDUCE_SCALED_POWER_BY_THREE_CHAIN
)
910 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
916 if (IS_CHAN_2GHZ(chan
)) {
917 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) -
918 SUB_NUM_CTL_MODES_AT_2G_40
;
919 pCtlMode
= ctlModesFor11g
;
921 ath9k_hw_get_legacy_target_powers(ah
, chan
,
922 pEepData
->calTargetPowerCck
,
923 AR5416_NUM_2G_CCK_TARGET_POWERS
,
924 &targetPowerCck
, 4, false);
925 ath9k_hw_get_legacy_target_powers(ah
, chan
,
926 pEepData
->calTargetPower2G
,
927 AR5416_NUM_2G_20_TARGET_POWERS
,
928 &targetPowerOfdm
, 4, false);
929 ath9k_hw_get_target_powers(ah
, chan
,
930 pEepData
->calTargetPower2GHT20
,
931 AR5416_NUM_2G_20_TARGET_POWERS
,
932 &targetPowerHt20
, 8, false);
934 if (IS_CHAN_HT40(chan
)) {
935 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
936 ath9k_hw_get_target_powers(ah
, chan
,
937 pEepData
->calTargetPower2GHT40
,
938 AR5416_NUM_2G_40_TARGET_POWERS
,
939 &targetPowerHt40
, 8, true);
940 ath9k_hw_get_legacy_target_powers(ah
, chan
,
941 pEepData
->calTargetPowerCck
,
942 AR5416_NUM_2G_CCK_TARGET_POWERS
,
943 &targetPowerCckExt
, 4, true);
944 ath9k_hw_get_legacy_target_powers(ah
, chan
,
945 pEepData
->calTargetPower2G
,
946 AR5416_NUM_2G_20_TARGET_POWERS
,
947 &targetPowerOfdmExt
, 4, true);
950 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
) -
951 SUB_NUM_CTL_MODES_AT_5G_40
;
952 pCtlMode
= ctlModesFor11a
;
954 ath9k_hw_get_legacy_target_powers(ah
, chan
,
955 pEepData
->calTargetPower5G
,
956 AR5416_NUM_5G_20_TARGET_POWERS
,
957 &targetPowerOfdm
, 4, false);
958 ath9k_hw_get_target_powers(ah
, chan
,
959 pEepData
->calTargetPower5GHT20
,
960 AR5416_NUM_5G_20_TARGET_POWERS
,
961 &targetPowerHt20
, 8, false);
963 if (IS_CHAN_HT40(chan
)) {
964 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
965 ath9k_hw_get_target_powers(ah
, chan
,
966 pEepData
->calTargetPower5GHT40
,
967 AR5416_NUM_5G_40_TARGET_POWERS
,
968 &targetPowerHt40
, 8, true);
969 ath9k_hw_get_legacy_target_powers(ah
, chan
,
970 pEepData
->calTargetPower5G
,
971 AR5416_NUM_5G_20_TARGET_POWERS
,
972 &targetPowerOfdmExt
, 4, true);
976 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
977 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
978 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
980 freq
= centers
.synth_center
;
981 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
982 freq
= centers
.ext_center
;
984 freq
= centers
.ctl_center
;
986 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
987 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
988 twiceMaxEdgePower
= MAX_RATE_POWER
;
990 for (i
= 0; (i
< AR5416_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
991 if ((((cfgCtl
& ~CTL_MODE_M
) |
992 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
993 pEepData
->ctlIndex
[i
]) ||
994 (((cfgCtl
& ~CTL_MODE_M
) |
995 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
996 ((pEepData
->ctlIndex
[i
] & CTL_MODE_M
) | SD_NO_CTL
))) {
997 rep
= &(pEepData
->ctlData
[i
]);
999 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(freq
,
1000 rep
->ctlEdges
[ar5416_get_ntxchains(tx_chainmask
) - 1],
1001 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
1003 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
1004 twiceMaxEdgePower
= min(twiceMaxEdgePower
,
1007 twiceMaxEdgePower
= twiceMinEdgePower
;
1013 minCtlPower
= min(twiceMaxEdgePower
, scaledPower
);
1015 switch (pCtlMode
[ctlMode
]) {
1017 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
1018 targetPowerCck
.tPow2x
[i
] =
1019 min((u16
)targetPowerCck
.tPow2x
[i
],
1025 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
1026 targetPowerOfdm
.tPow2x
[i
] =
1027 min((u16
)targetPowerOfdm
.tPow2x
[i
],
1033 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
1034 targetPowerHt20
.tPow2x
[i
] =
1035 min((u16
)targetPowerHt20
.tPow2x
[i
],
1040 targetPowerCckExt
.tPow2x
[0] = min((u16
)
1041 targetPowerCckExt
.tPow2x
[0],
1046 targetPowerOfdmExt
.tPow2x
[0] = min((u16
)
1047 targetPowerOfdmExt
.tPow2x
[0],
1052 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1053 targetPowerHt40
.tPow2x
[i
] =
1054 min((u16
)targetPowerHt40
.tPow2x
[i
],
1063 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
1064 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
1065 targetPowerOfdm
.tPow2x
[0];
1066 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
1067 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
1068 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
1069 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
1071 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
1072 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
1074 if (IS_CHAN_2GHZ(chan
)) {
1075 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
1076 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
1077 targetPowerCck
.tPow2x
[1];
1078 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
1079 targetPowerCck
.tPow2x
[2];
1080 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
1081 targetPowerCck
.tPow2x
[3];
1083 if (IS_CHAN_HT40(chan
)) {
1084 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1085 ratesArray
[rateHt40_0
+ i
] =
1086 targetPowerHt40
.tPow2x
[i
];
1088 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
1089 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
1090 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
1091 if (IS_CHAN_2GHZ(chan
)) {
1092 ratesArray
[rateExtCck
] =
1093 targetPowerCckExt
.tPow2x
[0];
1098 static void ath9k_hw_def_set_txpower(struct ath_hw
*ah
,
1099 struct ath9k_channel
*chan
,
1101 u8 twiceAntennaReduction
,
1102 u8 twiceMaxRegulatoryPower
,
1103 u8 powerLimit
, bool test
)
1105 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1106 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
1107 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
1108 struct modal_eep_header
*pModal
=
1109 &(pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1110 int16_t ratesArray
[Ar5416RateSize
];
1111 int16_t txPowerIndexOffset
= 0;
1112 u8 ht40PowerIncForPdadc
= 2;
1113 int i
, cck_ofdm_delta
= 0;
1115 memset(ratesArray
, 0, sizeof(ratesArray
));
1117 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1118 AR5416_EEP_MINOR_VER_2
) {
1119 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
1122 ath9k_hw_set_def_power_per_rate_table(ah
, chan
,
1123 &ratesArray
[0], cfgCtl
,
1124 twiceAntennaReduction
,
1125 twiceMaxRegulatoryPower
,
1128 ath9k_hw_set_def_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
1130 regulatory
->max_power_level
= 0;
1131 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
1132 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
1133 if (ratesArray
[i
] > MAX_RATE_POWER
)
1134 ratesArray
[i
] = MAX_RATE_POWER
;
1135 if (ratesArray
[i
] > regulatory
->max_power_level
)
1136 regulatory
->max_power_level
= ratesArray
[i
];
1142 if (IS_CHAN_HT40(chan
))
1144 else if (IS_CHAN_HT20(chan
))
1147 regulatory
->max_power_level
= ratesArray
[i
];
1150 switch(ar5416_get_ntxchains(ah
->txchainmask
)) {
1154 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_TWO_CHAIN
;
1157 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_THREE_CHAIN
;
1160 ath_dbg(ath9k_hw_common(ah
), ATH_DBG_EEPROM
,
1161 "Invalid chainmask configuration\n");
1168 if (AR_SREV_9280_20_OR_LATER(ah
)) {
1169 for (i
= 0; i
< Ar5416RateSize
; i
++) {
1170 int8_t pwr_table_offset
;
1172 pwr_table_offset
= ah
->eep_ops
->get_eeprom(ah
,
1173 EEP_PWR_TABLE_OFFSET
);
1174 ratesArray
[i
] -= pwr_table_offset
* 2;
1178 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
1179 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
1180 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
1181 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
1182 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
1183 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
1184 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
1185 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
1186 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
1187 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
1189 if (IS_CHAN_2GHZ(chan
)) {
1190 if (OLC_FOR_AR9280_20_LATER
) {
1192 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1193 ATH9K_POW_SM(RT_AR_DELTA(rate2s
), 24)
1194 | ATH9K_POW_SM(RT_AR_DELTA(rate2l
), 16)
1195 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1196 | ATH9K_POW_SM(RT_AR_DELTA(rate1l
), 0));
1197 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1198 ATH9K_POW_SM(RT_AR_DELTA(rate11s
), 24)
1199 | ATH9K_POW_SM(RT_AR_DELTA(rate11l
), 16)
1200 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s
), 8)
1201 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l
), 0));
1203 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1204 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
1205 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
1206 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1207 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
1208 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1209 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
1210 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
1211 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
1212 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
1216 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
1217 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
1218 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
1219 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
1220 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
1221 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
1222 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
1223 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
1224 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
1225 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
1227 if (IS_CHAN_HT40(chan
)) {
1228 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
1229 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
1230 ht40PowerIncForPdadc
, 24)
1231 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
1232 ht40PowerIncForPdadc
, 16)
1233 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
1234 ht40PowerIncForPdadc
, 8)
1235 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
1236 ht40PowerIncForPdadc
, 0));
1237 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
1238 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
1239 ht40PowerIncForPdadc
, 24)
1240 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
1241 ht40PowerIncForPdadc
, 16)
1242 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
1243 ht40PowerIncForPdadc
, 8)
1244 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
1245 ht40PowerIncForPdadc
, 0));
1246 if (OLC_FOR_AR9280_20_LATER
) {
1247 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1248 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1249 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck
), 16)
1250 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1251 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck
), 0));
1253 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1254 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1255 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
1256 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1257 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
1261 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
1262 ATH9K_POW_SM(pModal
->pwrDecreaseFor3Chain
, 6)
1263 | ATH9K_POW_SM(pModal
->pwrDecreaseFor2Chain
, 0));
1266 static u16
ath9k_hw_def_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1268 #define EEP_DEF_SPURCHAN \
1269 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1270 struct ath_common
*common
= ath9k_hw_common(ah
);
1272 u16 spur_val
= AR_NO_SPUR
;
1274 ath_dbg(common
, ATH_DBG_ANI
,
1275 "Getting spur idx:%d is2Ghz:%d val:%x\n",
1276 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1278 switch (ah
->config
.spurmode
) {
1281 case SPUR_ENABLE_IOCTL
:
1282 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1283 ath_dbg(common
, ATH_DBG_ANI
,
1284 "Getting spur val from new loc. %d\n", spur_val
);
1286 case SPUR_ENABLE_EEPROM
:
1287 spur_val
= EEP_DEF_SPURCHAN
;
1293 #undef EEP_DEF_SPURCHAN
1296 const struct eeprom_ops eep_def_ops
= {
1297 .check_eeprom
= ath9k_hw_def_check_eeprom
,
1298 .get_eeprom
= ath9k_hw_def_get_eeprom
,
1299 .fill_eeprom
= ath9k_hw_def_fill_eeprom
,
1300 .get_eeprom_ver
= ath9k_hw_def_get_eeprom_ver
,
1301 .get_eeprom_rev
= ath9k_hw_def_get_eeprom_rev
,
1302 .set_board_values
= ath9k_hw_def_set_board_values
,
1303 .set_addac
= ath9k_hw_def_set_addac
,
1304 .set_txpower
= ath9k_hw_def_set_txpower
,
1305 .get_spur_channel
= ath9k_hw_def_get_spur_channel