2 * Copyright (c) 2008-2011 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.
17 #include <asm/unaligned.h>
19 #include "ar9002_phy.h"
21 static void ath9k_get_txgain_index(struct ath_hw
*ah
,
22 struct ath9k_channel
*chan
,
23 struct calDataPerFreqOpLoop
*rawDatasetOpLoop
,
24 u8
*calChans
, u16 availPiers
, u8
*pwr
, u8
*pcdacIdx
)
27 u16 idxL
= 0, idxR
= 0, numPiers
;
29 struct chan_centers centers
;
31 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
33 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++)
34 if (calChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
37 match
= ath9k_hw_get_lower_upper_index(
38 (u8
)FREQ2FBIN(centers
.synth_center
, IS_CHAN_2GHZ(chan
)),
39 calChans
, numPiers
, &idxL
, &idxR
);
41 pcdac
= rawDatasetOpLoop
[idxL
].pcdac
[0][0];
42 *pwr
= rawDatasetOpLoop
[idxL
].pwrPdg
[0][0];
44 pcdac
= rawDatasetOpLoop
[idxR
].pcdac
[0][0];
45 *pwr
= (rawDatasetOpLoop
[idxL
].pwrPdg
[0][0] +
46 rawDatasetOpLoop
[idxR
].pwrPdg
[0][0])/2;
49 while (pcdac
> ah
->originalGain
[i
] &&
50 i
< (AR9280_TX_GAIN_TABLE_SIZE
- 1))
56 static void ath9k_olc_get_pdadcs(struct ath_hw
*ah
,
64 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL6_0
,
65 AR_PHY_TX_PWRCTRL_ERR_EST_MODE
, 3);
66 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL6_1
,
67 AR_PHY_TX_PWRCTRL_ERR_EST_MODE
, 3);
69 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL7
,
70 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN
, initTxGain
);
73 for (i
= 0; i
< AR5416_NUM_PDADC_VALUES
; i
++)
75 pPDADCValues
[i
] = 0x0;
77 pPDADCValues
[i
] = 0xFF;
80 static int ath9k_hw_def_get_eeprom_ver(struct ath_hw
*ah
)
82 return ((ah
->eeprom
.def
.baseEepHeader
.version
>> 12) & 0xF);
85 static int ath9k_hw_def_get_eeprom_rev(struct ath_hw
*ah
)
87 return ((ah
->eeprom
.def
.baseEepHeader
.version
) & 0xFFF);
90 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
92 static bool __ath9k_hw_def_fill_eeprom(struct ath_hw
*ah
)
94 struct ath_common
*common
= ath9k_hw_common(ah
);
95 u16
*eep_data
= (u16
*)&ah
->eeprom
.def
;
96 int addr
, ar5416_eep_start_loc
= 0x100;
98 for (addr
= 0; addr
< SIZE_EEPROM_DEF
; addr
++) {
99 if (!ath9k_hw_nvram_read(common
, addr
+ ar5416_eep_start_loc
,
101 ath_err(ath9k_hw_common(ah
),
102 "Unable to read eeprom region\n");
110 static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw
*ah
)
112 u16
*eep_data
= (u16
*)&ah
->eeprom
.def
;
114 ath9k_hw_usb_gen_fill_eeprom(ah
, eep_data
,
115 0x100, SIZE_EEPROM_DEF
);
119 static bool ath9k_hw_def_fill_eeprom(struct ath_hw
*ah
)
121 struct ath_common
*common
= ath9k_hw_common(ah
);
123 if (!ath9k_hw_use_flash(ah
)) {
124 ath_dbg(common
, ATH_DBG_EEPROM
,
125 "Reading from EEPROM, not flash\n");
128 if (common
->bus_ops
->ath_bus_type
== ATH_USB
)
129 return __ath9k_hw_usb_def_fill_eeprom(ah
);
131 return __ath9k_hw_def_fill_eeprom(ah
);
134 #undef SIZE_EEPROM_DEF
136 static int ath9k_hw_def_check_eeprom(struct ath_hw
*ah
)
138 struct ar5416_eeprom_def
*eep
=
139 (struct ar5416_eeprom_def
*) &ah
->eeprom
.def
;
140 struct ath_common
*common
= ath9k_hw_common(ah
);
141 u16
*eepdata
, temp
, magic
, magic2
;
143 bool need_swap
= false;
146 if (!ath9k_hw_nvram_read(common
, AR5416_EEPROM_MAGIC_OFFSET
, &magic
)) {
147 ath_err(common
, "Reading Magic # failed\n");
151 if (!ath9k_hw_use_flash(ah
)) {
152 ath_dbg(common
, ATH_DBG_EEPROM
,
153 "Read Magic = 0x%04X\n", magic
);
155 if (magic
!= AR5416_EEPROM_MAGIC
) {
156 magic2
= swab16(magic
);
158 if (magic2
== AR5416_EEPROM_MAGIC
) {
159 size
= sizeof(struct ar5416_eeprom_def
);
161 eepdata
= (u16
*) (&ah
->eeprom
);
163 for (addr
= 0; addr
< size
/ sizeof(u16
); addr
++) {
164 temp
= swab16(*eepdata
);
170 "Invalid EEPROM Magic. Endianness mismatch.\n");
176 ath_dbg(common
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
177 need_swap
? "True" : "False");
180 el
= swab16(ah
->eeprom
.def
.baseEepHeader
.length
);
182 el
= ah
->eeprom
.def
.baseEepHeader
.length
;
184 if (el
> sizeof(struct ar5416_eeprom_def
))
185 el
= sizeof(struct ar5416_eeprom_def
) / sizeof(u16
);
187 el
= el
/ sizeof(u16
);
189 eepdata
= (u16
*)(&ah
->eeprom
);
191 for (i
= 0; i
< el
; i
++)
198 ath_dbg(common
, ATH_DBG_EEPROM
,
199 "EEPROM Endianness is not native.. Changing.\n");
201 word
= swab16(eep
->baseEepHeader
.length
);
202 eep
->baseEepHeader
.length
= word
;
204 word
= swab16(eep
->baseEepHeader
.checksum
);
205 eep
->baseEepHeader
.checksum
= word
;
207 word
= swab16(eep
->baseEepHeader
.version
);
208 eep
->baseEepHeader
.version
= word
;
210 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
211 eep
->baseEepHeader
.regDmn
[0] = word
;
213 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
214 eep
->baseEepHeader
.regDmn
[1] = word
;
216 word
= swab16(eep
->baseEepHeader
.rfSilent
);
217 eep
->baseEepHeader
.rfSilent
= word
;
219 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
220 eep
->baseEepHeader
.blueToothOptions
= word
;
222 word
= swab16(eep
->baseEepHeader
.deviceCap
);
223 eep
->baseEepHeader
.deviceCap
= word
;
225 for (j
= 0; j
< ARRAY_SIZE(eep
->modalHeader
); j
++) {
226 struct modal_eep_header
*pModal
=
227 &eep
->modalHeader
[j
];
228 integer
= swab32(pModal
->antCtrlCommon
);
229 pModal
->antCtrlCommon
= integer
;
231 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
232 integer
= swab32(pModal
->antCtrlChain
[i
]);
233 pModal
->antCtrlChain
[i
] = integer
;
235 for (i
= 0; i
< 3; i
++) {
236 word
= swab16(pModal
->xpaBiasLvlFreq
[i
]);
237 pModal
->xpaBiasLvlFreq
[i
] = word
;
240 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
241 word
= swab16(pModal
->spurChans
[i
].spurChan
);
242 pModal
->spurChans
[i
].spurChan
= word
;
247 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR5416_EEP_VER
||
248 ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
249 ath_err(common
, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
250 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
254 /* Enable fixup for AR_AN_TOP2 if necessary */
255 if ((ah
->hw_version
.devid
== AR9280_DEVID_PCI
) &&
256 ((eep
->baseEepHeader
.version
& 0xff) > 0x0a) &&
257 (eep
->baseEepHeader
.pwdclkind
== 0))
258 ah
->need_an_top2_fixup
= 1;
260 if ((common
->bus_ops
->ath_bus_type
== ATH_USB
) &&
262 eep
->modalHeader
[0].xpaBiasLvl
= 0;
267 static u32
ath9k_hw_def_get_eeprom(struct ath_hw
*ah
,
268 enum eeprom_param param
)
270 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
271 struct modal_eep_header
*pModal
= eep
->modalHeader
;
272 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
276 return pModal
[0].noiseFloorThreshCh
[0];
278 return pModal
[1].noiseFloorThreshCh
[0];
280 return get_unaligned_be16(pBase
->macAddr
);
282 return get_unaligned_be16(pBase
->macAddr
+ 2);
284 return get_unaligned_be16(pBase
->macAddr
+ 4);
286 return pBase
->regDmn
[0];
288 return pBase
->regDmn
[1];
290 return pBase
->deviceCap
;
292 return pBase
->opCapFlags
;
294 return pBase
->rfSilent
;
304 return AR5416_VER_MASK
;
306 return pBase
->txMask
;
308 return pBase
->rxMask
;
310 return pBase
->fastClk5g
;
311 case EEP_RXGAIN_TYPE
:
312 return pBase
->rxGainType
;
313 case EEP_TXGAIN_TYPE
:
314 return pBase
->txGainType
;
316 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
317 return pBase
->openLoopPwrCntl
? true : false;
320 case EEP_RC_CHAIN_MASK
:
321 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
322 return pBase
->rcChainMask
;
325 case EEP_DAC_HPWR_5G
:
326 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_20
)
327 return pBase
->dacHiPwrMode_5G
;
331 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_22
)
332 return pBase
->frac_n_5g
;
335 case EEP_PWR_TABLE_OFFSET
:
336 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_21
)
337 return pBase
->pwr_table_offset
;
339 return AR5416_PWR_TABLE_OFFSET_DB
;
345 static void ath9k_hw_def_set_gain(struct ath_hw
*ah
,
346 struct modal_eep_header
*pModal
,
347 struct ar5416_eeprom_def
*eep
,
348 u8 txRxAttenLocal
, int regChainOffset
, int i
)
350 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_3
) {
351 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
353 if (AR_SREV_9280_20_OR_LATER(ah
)) {
354 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
355 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
356 pModal
->bswMargin
[i
]);
357 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
358 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
359 pModal
->bswAtten
[i
]);
360 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
361 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
362 pModal
->xatten2Margin
[i
]);
363 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
364 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
365 pModal
->xatten2Db
[i
]);
367 REG_WRITE(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
368 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
369 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN
)
370 | SM(pModal
-> bswMargin
[i
],
371 AR_PHY_GAIN_2GHZ_BSW_MARGIN
));
372 REG_WRITE(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
373 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
374 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN
)
375 | SM(pModal
->bswAtten
[i
],
376 AR_PHY_GAIN_2GHZ_BSW_ATTEN
));
380 if (AR_SREV_9280_20_OR_LATER(ah
)) {
382 AR_PHY_RXGAIN
+ regChainOffset
,
383 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
385 AR_PHY_RXGAIN
+ regChainOffset
,
386 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[i
]);
389 AR_PHY_RXGAIN
+ regChainOffset
,
390 (REG_READ(ah
, AR_PHY_RXGAIN
+ regChainOffset
) &
391 ~AR_PHY_RXGAIN_TXRX_ATTEN
)
392 | SM(txRxAttenLocal
, AR_PHY_RXGAIN_TXRX_ATTEN
));
394 AR_PHY_GAIN_2GHZ
+ regChainOffset
,
395 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
396 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN
) |
397 SM(pModal
->rxTxMarginCh
[i
], AR_PHY_GAIN_2GHZ_RXTX_MARGIN
));
401 static void ath9k_hw_def_set_board_values(struct ath_hw
*ah
,
402 struct ath9k_channel
*chan
)
404 struct modal_eep_header
*pModal
;
405 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
406 int i
, regChainOffset
;
409 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
410 txRxAttenLocal
= IS_CHAN_2GHZ(chan
) ? 23 : 44;
412 REG_WRITE(ah
, AR_PHY_SWITCH_COM
, pModal
->antCtrlCommon
& 0xffff);
414 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
415 if (AR_SREV_9280(ah
)) {
420 if (AR_SREV_5416_20_OR_LATER(ah
) &&
421 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) && (i
!= 0))
422 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
424 regChainOffset
= i
* 0x1000;
426 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
427 pModal
->antCtrlChain
[i
]);
429 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
430 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
) &
431 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
432 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
433 SM(pModal
->iqCalICh
[i
],
434 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
435 SM(pModal
->iqCalQCh
[i
],
436 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
438 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
))
439 ath9k_hw_def_set_gain(ah
, pModal
, eep
, txRxAttenLocal
,
443 if (AR_SREV_9280_20_OR_LATER(ah
)) {
444 if (IS_CHAN_2GHZ(chan
)) {
445 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
447 AR_AN_RF2G1_CH0_OB_S
,
449 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
451 AR_AN_RF2G1_CH0_DB_S
,
453 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
455 AR_AN_RF2G1_CH1_OB_S
,
457 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
459 AR_AN_RF2G1_CH1_DB_S
,
462 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
464 AR_AN_RF5G1_CH0_OB5_S
,
466 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
468 AR_AN_RF5G1_CH0_DB5_S
,
470 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
472 AR_AN_RF5G1_CH1_OB5_S
,
474 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
476 AR_AN_RF5G1_CH1_DB5_S
,
479 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
480 AR_AN_TOP2_XPABIAS_LVL
,
481 AR_AN_TOP2_XPABIAS_LVL_S
,
483 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
484 AR_AN_TOP2_LOCALBIAS
,
485 AR_AN_TOP2_LOCALBIAS_S
,
487 LNA_CTL_LOCAL_BIAS
));
488 REG_RMW_FIELD(ah
, AR_PHY_XPA_CFG
, AR_PHY_FORCE_XPA_CFG
,
489 !!(pModal
->lna_ctl
& LNA_CTL_FORCE_XPA
));
492 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
493 pModal
->switchSettling
);
494 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
495 pModal
->adcDesiredSize
);
497 if (!AR_SREV_9280_20_OR_LATER(ah
))
498 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
499 AR_PHY_DESIRED_SZ_PGA
,
500 pModal
->pgaDesiredSize
);
502 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
503 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
504 | SM(pModal
->txEndToXpaOff
,
505 AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
506 | SM(pModal
->txFrameToXpaOn
,
507 AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
508 | SM(pModal
->txFrameToXpaOn
,
509 AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
511 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
512 pModal
->txEndToRxOn
);
514 if (AR_SREV_9280_20_OR_LATER(ah
)) {
515 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
517 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
518 AR_PHY_EXT_CCA0_THRESH62
,
521 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR_PHY_CCA_THRESH62
,
523 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA
,
524 AR_PHY_EXT_CCA_THRESH62
,
528 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_2
) {
529 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
530 AR_PHY_TX_END_DATA_START
,
531 pModal
->txFrameToDataStart
);
532 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
533 pModal
->txFrameToPaOn
);
536 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_3
) {
537 if (IS_CHAN_HT40(chan
))
538 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
539 AR_PHY_SETTLING_SWITCH
,
540 pModal
->swSettleHt40
);
543 if (AR_SREV_9280_20_OR_LATER(ah
) &&
544 AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
545 REG_RMW_FIELD(ah
, AR_PHY_CCK_TX_CTRL
,
546 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK
,
550 if (AR_SREV_9280_20(ah
) && AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_20
) {
551 if (IS_CHAN_2GHZ(chan
))
552 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
,
553 eep
->baseEepHeader
.dacLpMode
);
554 else if (eep
->baseEepHeader
.dacHiPwrMode_5G
)
555 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
, 0);
557 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
,
558 eep
->baseEepHeader
.dacLpMode
);
562 REG_RMW_FIELD(ah
, AR_PHY_FRAME_CTL
, AR_PHY_FRAME_CTL_TX_CLIP
,
563 pModal
->miscBits
>> 2);
565 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL9
,
566 AR_PHY_TX_DESIRED_SCALE_CCK
,
567 eep
->baseEepHeader
.desiredScaleCCK
);
571 static void ath9k_hw_def_set_addac(struct ath_hw
*ah
,
572 struct ath9k_channel
*chan
)
574 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
575 struct modal_eep_header
*pModal
;
576 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
579 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
582 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
585 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
587 if (pModal
->xpaBiasLvl
!= 0xff) {
588 biaslevel
= pModal
->xpaBiasLvl
;
590 u16 resetFreqBin
, freqBin
, freqCount
= 0;
591 struct chan_centers centers
;
593 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
595 resetFreqBin
= FREQ2FBIN(centers
.synth_center
,
597 freqBin
= XPA_LVL_FREQ(0) & 0xff;
598 biaslevel
= (u8
) (XPA_LVL_FREQ(0) >> 14);
602 while (freqCount
< 3) {
603 if (XPA_LVL_FREQ(freqCount
) == 0x0)
606 freqBin
= XPA_LVL_FREQ(freqCount
) & 0xff;
607 if (resetFreqBin
>= freqBin
)
608 biaslevel
= (u8
)(XPA_LVL_FREQ(freqCount
) >> 14);
615 if (IS_CHAN_2GHZ(chan
)) {
616 INI_RA(&ah
->iniAddac
, 7, 1) = (INI_RA(&ah
->iniAddac
,
617 7, 1) & (~0x18)) | biaslevel
<< 3;
619 INI_RA(&ah
->iniAddac
, 6, 1) = (INI_RA(&ah
->iniAddac
,
620 6, 1) & (~0xc0)) | biaslevel
<< 6;
625 static int16_t ath9k_change_gain_boundary_setting(struct ath_hw
*ah
,
628 u16 pdGainOverlap_t2
,
629 int8_t pwr_table_offset
,
635 /* Prior to writing the boundaries or the pdadc vs. power table
636 * into the chip registers the default starting point on the pdadc
637 * vs. power table needs to be checked and the curve boundaries
638 * adjusted accordingly
640 if (AR_SREV_9280_20_OR_LATER(ah
)) {
643 if (AR5416_PWR_TABLE_OFFSET_DB
!= pwr_table_offset
) {
644 /* get the difference in dB */
645 *diff
= (u16
)(pwr_table_offset
- AR5416_PWR_TABLE_OFFSET_DB
);
646 /* get the number of half dB steps */
648 /* change the original gain boundary settings
649 * by the number of half dB steps
651 for (k
= 0; k
< numXpdGain
; k
++)
652 gb
[k
] = (u16
)(gb
[k
] - *diff
);
654 /* Because of a hardware limitation, ensure the gain boundary
655 * is not larger than (63 - overlap)
657 gb_limit
= (u16
)(MAX_RATE_POWER
- pdGainOverlap_t2
);
659 for (k
= 0; k
< numXpdGain
; k
++)
660 gb
[k
] = (u16
)min(gb_limit
, gb
[k
]);
666 static void ath9k_adjust_pdadc_values(struct ath_hw
*ah
,
667 int8_t pwr_table_offset
,
671 #define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
674 /* If this is a board that has a pwrTableOffset that differs from
675 * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
676 * pdadc vs pwr table needs to be adjusted prior to writing to the
679 if (AR_SREV_9280_20_OR_LATER(ah
)) {
680 if (AR5416_PWR_TABLE_OFFSET_DB
!= pwr_table_offset
) {
681 /* shift the table to start at the new offset */
682 for (k
= 0; k
< (u16
)NUM_PDADC(diff
); k
++ ) {
683 pdadcValues
[k
] = pdadcValues
[k
+ diff
];
686 /* fill the back of the table */
687 for (k
= (u16
)NUM_PDADC(diff
); k
< NUM_PDADC(0); k
++) {
688 pdadcValues
[k
] = pdadcValues
[NUM_PDADC(diff
)];
695 static void ath9k_hw_set_def_power_cal_table(struct ath_hw
*ah
,
696 struct ath9k_channel
*chan
,
697 int16_t *pTxPowerIndexOffset
)
699 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
700 #define SM_PDGAIN_B(x, y) \
701 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
702 struct ath_common
*common
= ath9k_hw_common(ah
);
703 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
704 struct cal_data_per_freq
*pRawDataset
;
705 u8
*pCalBChans
= NULL
;
706 u16 pdGainOverlap_t2
;
707 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
708 u16 gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
711 u16 numXpdGain
, xpdMask
;
712 u16 xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
713 u32 reg32
, regOffset
, regChainOffset
;
715 int8_t pwr_table_offset
;
717 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
718 xpdMask
= pEepData
->modalHeader
[modalIdx
].xpdGain
;
720 pwr_table_offset
= ah
->eep_ops
->get_eeprom(ah
, EEP_PWR_TABLE_OFFSET
);
722 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
723 AR5416_EEP_MINOR_VER_2
) {
725 pEepData
->modalHeader
[modalIdx
].pdGainOverlap
;
727 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
728 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
731 if (IS_CHAN_2GHZ(chan
)) {
732 pCalBChans
= pEepData
->calFreqPier2G
;
733 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
735 pCalBChans
= pEepData
->calFreqPier5G
;
736 numPiers
= AR5416_NUM_5G_CAL_PIERS
;
739 if (OLC_FOR_AR9280_20_LATER
&& IS_CHAN_2GHZ(chan
)) {
740 pRawDataset
= pEepData
->calPierData2G
[0];
741 ah
->initPDADC
= ((struct calDataPerFreqOpLoop
*)
742 pRawDataset
)->vpdPdg
[0][0];
747 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
748 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
749 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
751 xpdGainValues
[numXpdGain
] =
752 (u16
)(AR5416_PD_GAINS_IN_MASK
- i
);
757 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
758 (numXpdGain
- 1) & 0x3);
759 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
761 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
763 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
766 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
767 if (AR_SREV_5416_20_OR_LATER(ah
) &&
768 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
770 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
772 regChainOffset
= i
* 0x1000;
774 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
775 if (IS_CHAN_2GHZ(chan
))
776 pRawDataset
= pEepData
->calPierData2G
[i
];
778 pRawDataset
= pEepData
->calPierData5G
[i
];
781 if (OLC_FOR_AR9280_20_LATER
) {
785 ath9k_get_txgain_index(ah
, chan
,
786 (struct calDataPerFreqOpLoop
*)pRawDataset
,
787 pCalBChans
, numPiers
, &txPower
, &pcdacIdx
);
788 ath9k_olc_get_pdadcs(ah
, pcdacIdx
,
789 txPower
/2, pdadcValues
);
791 ath9k_hw_get_gain_boundaries_pdadcs(ah
,
793 pCalBChans
, numPiers
,
800 diff
= ath9k_change_gain_boundary_setting(ah
,
807 ENABLE_REGWRITE_BUFFER(ah
);
809 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
810 if (OLC_FOR_AR9280_20_LATER
) {
812 AR_PHY_TPCRG5
+ regChainOffset
,
814 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
) |
815 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
816 SM_PD_GAIN(3) | SM_PD_GAIN(4));
819 AR_PHY_TPCRG5
+ regChainOffset
,
821 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)|
830 ath9k_adjust_pdadc_values(ah
, pwr_table_offset
,
833 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
834 for (j
= 0; j
< 32; j
++) {
835 reg32
= get_unaligned_le32(&pdadcValues
[4 * j
]);
836 REG_WRITE(ah
, regOffset
, reg32
);
838 ath_dbg(common
, ATH_DBG_EEPROM
,
839 "PDADC (%d,%4x): %4.4x %8.8x\n",
840 i
, regChainOffset
, regOffset
,
842 ath_dbg(common
, ATH_DBG_EEPROM
,
843 "PDADC: Chain %d | PDADC %3d "
844 "Value %3d | PDADC %3d Value %3d | "
845 "PDADC %3d Value %3d | PDADC %3d "
847 i
, 4 * j
, pdadcValues
[4 * j
],
848 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
849 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
850 4 * j
+ 3, pdadcValues
[4 * j
+ 3]);
854 REGWRITE_BUFFER_FLUSH(ah
);
858 *pTxPowerIndexOffset
= 0;
863 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw
*ah
,
864 struct ath9k_channel
*chan
,
867 u16 AntennaReduction
,
868 u16 twiceMaxRegulatoryPower
,
871 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
872 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
874 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
875 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
876 u16 twiceMaxEdgePower
= MAX_RATE_POWER
;
877 static const u16 tpScaleReductionTable
[5] =
878 { 0, 3, 6, 9, MAX_RATE_POWER
};
881 int16_t twiceLargestAntenna
;
882 struct cal_ctl_data
*rep
;
883 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
886 struct cal_target_power_leg targetPowerOfdmExt
= {
887 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
890 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
893 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
894 static const u16 ctlModesFor11a
[] = {
895 CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
897 static const u16 ctlModesFor11g
[] = {
898 CTL_11B
, CTL_11G
, CTL_2GHT20
,
899 CTL_11B_EXT
, CTL_11G_EXT
, CTL_2GHT40
904 struct chan_centers centers
;
906 u16 twiceMinEdgePower
;
908 tx_chainmask
= ah
->txchainmask
;
910 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
912 twiceLargestAntenna
= max(
913 pEepData
->modalHeader
914 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[0],
915 pEepData
->modalHeader
916 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[1]);
918 twiceLargestAntenna
= max((u8
)twiceLargestAntenna
,
919 pEepData
->modalHeader
920 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[2]);
922 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
923 twiceLargestAntenna
, 0);
925 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
927 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
928 maxRegAllowedPower
-=
929 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
932 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
934 switch (ar5416_get_ntxchains(tx_chainmask
)) {
938 if (scaledPower
> REDUCE_SCALED_POWER_BY_TWO_CHAIN
)
939 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
944 if (scaledPower
> REDUCE_SCALED_POWER_BY_THREE_CHAIN
)
945 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
951 if (IS_CHAN_2GHZ(chan
)) {
952 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) -
953 SUB_NUM_CTL_MODES_AT_2G_40
;
954 pCtlMode
= ctlModesFor11g
;
956 ath9k_hw_get_legacy_target_powers(ah
, chan
,
957 pEepData
->calTargetPowerCck
,
958 AR5416_NUM_2G_CCK_TARGET_POWERS
,
959 &targetPowerCck
, 4, false);
960 ath9k_hw_get_legacy_target_powers(ah
, chan
,
961 pEepData
->calTargetPower2G
,
962 AR5416_NUM_2G_20_TARGET_POWERS
,
963 &targetPowerOfdm
, 4, false);
964 ath9k_hw_get_target_powers(ah
, chan
,
965 pEepData
->calTargetPower2GHT20
,
966 AR5416_NUM_2G_20_TARGET_POWERS
,
967 &targetPowerHt20
, 8, false);
969 if (IS_CHAN_HT40(chan
)) {
970 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
971 ath9k_hw_get_target_powers(ah
, chan
,
972 pEepData
->calTargetPower2GHT40
,
973 AR5416_NUM_2G_40_TARGET_POWERS
,
974 &targetPowerHt40
, 8, true);
975 ath9k_hw_get_legacy_target_powers(ah
, chan
,
976 pEepData
->calTargetPowerCck
,
977 AR5416_NUM_2G_CCK_TARGET_POWERS
,
978 &targetPowerCckExt
, 4, true);
979 ath9k_hw_get_legacy_target_powers(ah
, chan
,
980 pEepData
->calTargetPower2G
,
981 AR5416_NUM_2G_20_TARGET_POWERS
,
982 &targetPowerOfdmExt
, 4, true);
985 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
) -
986 SUB_NUM_CTL_MODES_AT_5G_40
;
987 pCtlMode
= ctlModesFor11a
;
989 ath9k_hw_get_legacy_target_powers(ah
, chan
,
990 pEepData
->calTargetPower5G
,
991 AR5416_NUM_5G_20_TARGET_POWERS
,
992 &targetPowerOfdm
, 4, false);
993 ath9k_hw_get_target_powers(ah
, chan
,
994 pEepData
->calTargetPower5GHT20
,
995 AR5416_NUM_5G_20_TARGET_POWERS
,
996 &targetPowerHt20
, 8, false);
998 if (IS_CHAN_HT40(chan
)) {
999 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
1000 ath9k_hw_get_target_powers(ah
, chan
,
1001 pEepData
->calTargetPower5GHT40
,
1002 AR5416_NUM_5G_40_TARGET_POWERS
,
1003 &targetPowerHt40
, 8, true);
1004 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1005 pEepData
->calTargetPower5G
,
1006 AR5416_NUM_5G_20_TARGET_POWERS
,
1007 &targetPowerOfdmExt
, 4, true);
1011 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
1012 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
1013 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
1015 freq
= centers
.synth_center
;
1016 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
1017 freq
= centers
.ext_center
;
1019 freq
= centers
.ctl_center
;
1021 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
1022 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
1023 twiceMaxEdgePower
= MAX_RATE_POWER
;
1025 for (i
= 0; (i
< AR5416_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
1026 if ((((cfgCtl
& ~CTL_MODE_M
) |
1027 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1028 pEepData
->ctlIndex
[i
]) ||
1029 (((cfgCtl
& ~CTL_MODE_M
) |
1030 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1031 ((pEepData
->ctlIndex
[i
] & CTL_MODE_M
) | SD_NO_CTL
))) {
1032 rep
= &(pEepData
->ctlData
[i
]);
1034 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(freq
,
1035 rep
->ctlEdges
[ar5416_get_ntxchains(tx_chainmask
) - 1],
1036 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
1038 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
1039 twiceMaxEdgePower
= min(twiceMaxEdgePower
,
1042 twiceMaxEdgePower
= twiceMinEdgePower
;
1048 minCtlPower
= min(twiceMaxEdgePower
, scaledPower
);
1050 switch (pCtlMode
[ctlMode
]) {
1052 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
1053 targetPowerCck
.tPow2x
[i
] =
1054 min((u16
)targetPowerCck
.tPow2x
[i
],
1060 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
1061 targetPowerOfdm
.tPow2x
[i
] =
1062 min((u16
)targetPowerOfdm
.tPow2x
[i
],
1068 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
1069 targetPowerHt20
.tPow2x
[i
] =
1070 min((u16
)targetPowerHt20
.tPow2x
[i
],
1075 targetPowerCckExt
.tPow2x
[0] = min((u16
)
1076 targetPowerCckExt
.tPow2x
[0],
1081 targetPowerOfdmExt
.tPow2x
[0] = min((u16
)
1082 targetPowerOfdmExt
.tPow2x
[0],
1087 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1088 targetPowerHt40
.tPow2x
[i
] =
1089 min((u16
)targetPowerHt40
.tPow2x
[i
],
1098 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
1099 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
1100 targetPowerOfdm
.tPow2x
[0];
1101 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
1102 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
1103 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
1104 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
1106 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
1107 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
1109 if (IS_CHAN_2GHZ(chan
)) {
1110 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
1111 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
1112 targetPowerCck
.tPow2x
[1];
1113 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
1114 targetPowerCck
.tPow2x
[2];
1115 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
1116 targetPowerCck
.tPow2x
[3];
1118 if (IS_CHAN_HT40(chan
)) {
1119 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1120 ratesArray
[rateHt40_0
+ i
] =
1121 targetPowerHt40
.tPow2x
[i
];
1123 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
1124 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
1125 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
1126 if (IS_CHAN_2GHZ(chan
)) {
1127 ratesArray
[rateExtCck
] =
1128 targetPowerCckExt
.tPow2x
[0];
1133 static void ath9k_hw_def_set_txpower(struct ath_hw
*ah
,
1134 struct ath9k_channel
*chan
,
1136 u8 twiceAntennaReduction
,
1137 u8 twiceMaxRegulatoryPower
,
1138 u8 powerLimit
, bool test
)
1140 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1141 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
1142 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
1143 struct modal_eep_header
*pModal
=
1144 &(pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1145 int16_t ratesArray
[Ar5416RateSize
];
1146 int16_t txPowerIndexOffset
= 0;
1147 u8 ht40PowerIncForPdadc
= 2;
1148 int i
, cck_ofdm_delta
= 0;
1150 memset(ratesArray
, 0, sizeof(ratesArray
));
1152 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1153 AR5416_EEP_MINOR_VER_2
) {
1154 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
1157 ath9k_hw_set_def_power_per_rate_table(ah
, chan
,
1158 &ratesArray
[0], cfgCtl
,
1159 twiceAntennaReduction
,
1160 twiceMaxRegulatoryPower
,
1163 ath9k_hw_set_def_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
1165 regulatory
->max_power_level
= 0;
1166 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
1167 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
1168 if (ratesArray
[i
] > MAX_RATE_POWER
)
1169 ratesArray
[i
] = MAX_RATE_POWER
;
1170 if (ratesArray
[i
] > regulatory
->max_power_level
)
1171 regulatory
->max_power_level
= ratesArray
[i
];
1177 if (IS_CHAN_HT40(chan
))
1179 else if (IS_CHAN_HT20(chan
))
1182 regulatory
->max_power_level
= ratesArray
[i
];
1185 switch(ar5416_get_ntxchains(ah
->txchainmask
)) {
1189 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_TWO_CHAIN
;
1192 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_THREE_CHAIN
;
1195 ath_dbg(ath9k_hw_common(ah
), ATH_DBG_EEPROM
,
1196 "Invalid chainmask configuration\n");
1203 if (AR_SREV_9280_20_OR_LATER(ah
)) {
1204 for (i
= 0; i
< Ar5416RateSize
; i
++) {
1205 int8_t pwr_table_offset
;
1207 pwr_table_offset
= ah
->eep_ops
->get_eeprom(ah
,
1208 EEP_PWR_TABLE_OFFSET
);
1209 ratesArray
[i
] -= pwr_table_offset
* 2;
1213 ENABLE_REGWRITE_BUFFER(ah
);
1215 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
1216 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
1217 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
1218 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
1219 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
1220 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
1221 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
1222 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
1223 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
1224 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
1226 if (IS_CHAN_2GHZ(chan
)) {
1227 if (OLC_FOR_AR9280_20_LATER
) {
1229 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1230 ATH9K_POW_SM(RT_AR_DELTA(rate2s
), 24)
1231 | ATH9K_POW_SM(RT_AR_DELTA(rate2l
), 16)
1232 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1233 | ATH9K_POW_SM(RT_AR_DELTA(rate1l
), 0));
1234 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1235 ATH9K_POW_SM(RT_AR_DELTA(rate11s
), 24)
1236 | ATH9K_POW_SM(RT_AR_DELTA(rate11l
), 16)
1237 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s
), 8)
1238 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l
), 0));
1240 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1241 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
1242 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
1243 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1244 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
1245 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1246 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
1247 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
1248 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
1249 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
1253 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
1254 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
1255 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
1256 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
1257 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
1258 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
1259 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
1260 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
1261 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
1262 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
1264 if (IS_CHAN_HT40(chan
)) {
1265 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
1266 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
1267 ht40PowerIncForPdadc
, 24)
1268 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
1269 ht40PowerIncForPdadc
, 16)
1270 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
1271 ht40PowerIncForPdadc
, 8)
1272 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
1273 ht40PowerIncForPdadc
, 0));
1274 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
1275 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
1276 ht40PowerIncForPdadc
, 24)
1277 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
1278 ht40PowerIncForPdadc
, 16)
1279 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
1280 ht40PowerIncForPdadc
, 8)
1281 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
1282 ht40PowerIncForPdadc
, 0));
1283 if (OLC_FOR_AR9280_20_LATER
) {
1284 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1285 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1286 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck
), 16)
1287 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1288 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck
), 0));
1290 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1291 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1292 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
1293 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1294 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
1298 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
1299 ATH9K_POW_SM(pModal
->pwrDecreaseFor3Chain
, 6)
1300 | ATH9K_POW_SM(pModal
->pwrDecreaseFor2Chain
, 0));
1302 REGWRITE_BUFFER_FLUSH(ah
);
1305 static u16
ath9k_hw_def_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1307 #define EEP_DEF_SPURCHAN \
1308 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1309 struct ath_common
*common
= ath9k_hw_common(ah
);
1311 u16 spur_val
= AR_NO_SPUR
;
1313 ath_dbg(common
, ATH_DBG_ANI
,
1314 "Getting spur idx:%d is2Ghz:%d val:%x\n",
1315 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1317 switch (ah
->config
.spurmode
) {
1320 case SPUR_ENABLE_IOCTL
:
1321 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1322 ath_dbg(common
, ATH_DBG_ANI
,
1323 "Getting spur val from new loc. %d\n", spur_val
);
1325 case SPUR_ENABLE_EEPROM
:
1326 spur_val
= EEP_DEF_SPURCHAN
;
1332 #undef EEP_DEF_SPURCHAN
1335 const struct eeprom_ops eep_def_ops
= {
1336 .check_eeprom
= ath9k_hw_def_check_eeprom
,
1337 .get_eeprom
= ath9k_hw_def_get_eeprom
,
1338 .fill_eeprom
= ath9k_hw_def_fill_eeprom
,
1339 .get_eeprom_ver
= ath9k_hw_def_get_eeprom_ver
,
1340 .get_eeprom_rev
= ath9k_hw_def_get_eeprom_rev
,
1341 .set_board_values
= ath9k_hw_def_set_board_values
,
1342 .set_addac
= ath9k_hw_def_set_addac
,
1343 .set_txpower
= ath9k_hw_def_set_txpower
,
1344 .get_spur_channel
= ath9k_hw_def_get_spur_channel