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.
19 static void ath9k_get_txgain_index(struct ath_hw
*ah
,
20 struct ath9k_channel
*chan
,
21 struct calDataPerFreqOpLoop
*rawDatasetOpLoop
,
22 u8
*calChans
, u16 availPiers
, u8
*pwr
, u8
*pcdacIdx
)
25 u16 idxL
= 0, idxR
= 0, numPiers
;
27 struct chan_centers centers
;
29 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
31 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++)
32 if (calChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
35 match
= ath9k_hw_get_lower_upper_index(
36 (u8
)FREQ2FBIN(centers
.synth_center
, IS_CHAN_2GHZ(chan
)),
37 calChans
, numPiers
, &idxL
, &idxR
);
39 pcdac
= rawDatasetOpLoop
[idxL
].pcdac
[0][0];
40 *pwr
= rawDatasetOpLoop
[idxL
].pwrPdg
[0][0];
42 pcdac
= rawDatasetOpLoop
[idxR
].pcdac
[0][0];
43 *pwr
= (rawDatasetOpLoop
[idxL
].pwrPdg
[0][0] +
44 rawDatasetOpLoop
[idxR
].pwrPdg
[0][0])/2;
47 while (pcdac
> ah
->originalGain
[i
] &&
48 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 u16
*eep_data
= (u16
*)&ah
->eeprom
.def
;
93 int addr
, ar5416_eep_start_loc
= 0x100;
95 for (addr
= 0; addr
< SIZE_EEPROM_DEF
; addr
++) {
96 if (!ath9k_hw_nvram_read(ah
, addr
+ ar5416_eep_start_loc
,
98 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
99 "Unable to read eeprom region\n");
105 #undef SIZE_EEPROM_DEF
108 static int ath9k_hw_def_check_eeprom(struct ath_hw
*ah
)
110 struct ar5416_eeprom_def
*eep
=
111 (struct ar5416_eeprom_def
*) &ah
->eeprom
.def
;
112 u16
*eepdata
, temp
, magic
, magic2
;
114 bool need_swap
= false;
117 if (!ath9k_hw_nvram_read(ah
, AR5416_EEPROM_MAGIC_OFFSET
, &magic
)) {
118 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
, "Reading Magic # failed\n");
122 if (!ath9k_hw_use_flash(ah
)) {
123 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
124 "Read Magic = 0x%04X\n", magic
);
126 if (magic
!= AR5416_EEPROM_MAGIC
) {
127 magic2
= swab16(magic
);
129 if (magic2
== AR5416_EEPROM_MAGIC
) {
130 size
= sizeof(struct ar5416_eeprom_def
);
132 eepdata
= (u16
*) (&ah
->eeprom
);
134 for (addr
= 0; addr
< size
/ sizeof(u16
); addr
++) {
135 temp
= swab16(*eepdata
);
140 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
141 "Invalid EEPROM Magic. "
142 "Endianness mismatch.\n");
148 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
149 need_swap
? "True" : "False");
152 el
= swab16(ah
->eeprom
.def
.baseEepHeader
.length
);
154 el
= ah
->eeprom
.def
.baseEepHeader
.length
;
156 if (el
> sizeof(struct ar5416_eeprom_def
))
157 el
= sizeof(struct ar5416_eeprom_def
) / sizeof(u16
);
159 el
= el
/ sizeof(u16
);
161 eepdata
= (u16
*)(&ah
->eeprom
);
163 for (i
= 0; i
< el
; i
++)
170 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
171 "EEPROM Endianness is not native.. Changing.\n");
173 word
= swab16(eep
->baseEepHeader
.length
);
174 eep
->baseEepHeader
.length
= word
;
176 word
= swab16(eep
->baseEepHeader
.checksum
);
177 eep
->baseEepHeader
.checksum
= word
;
179 word
= swab16(eep
->baseEepHeader
.version
);
180 eep
->baseEepHeader
.version
= word
;
182 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
183 eep
->baseEepHeader
.regDmn
[0] = word
;
185 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
186 eep
->baseEepHeader
.regDmn
[1] = word
;
188 word
= swab16(eep
->baseEepHeader
.rfSilent
);
189 eep
->baseEepHeader
.rfSilent
= word
;
191 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
192 eep
->baseEepHeader
.blueToothOptions
= word
;
194 word
= swab16(eep
->baseEepHeader
.deviceCap
);
195 eep
->baseEepHeader
.deviceCap
= word
;
197 for (j
= 0; j
< ARRAY_SIZE(eep
->modalHeader
); j
++) {
198 struct modal_eep_header
*pModal
=
199 &eep
->modalHeader
[j
];
200 integer
= swab32(pModal
->antCtrlCommon
);
201 pModal
->antCtrlCommon
= integer
;
203 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
204 integer
= swab32(pModal
->antCtrlChain
[i
]);
205 pModal
->antCtrlChain
[i
] = integer
;
208 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
209 word
= swab16(pModal
->spurChans
[i
].spurChan
);
210 pModal
->spurChans
[i
].spurChan
= word
;
215 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR5416_EEP_VER
||
216 ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
217 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
218 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
219 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
226 static u32
ath9k_hw_def_get_eeprom(struct ath_hw
*ah
,
227 enum eeprom_param param
)
229 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
230 struct modal_eep_header
*pModal
= eep
->modalHeader
;
231 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
235 return pModal
[0].noiseFloorThreshCh
[0];
237 return pModal
[1].noiseFloorThreshCh
[0];
238 case AR_EEPROM_MAC(0):
239 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
240 case AR_EEPROM_MAC(1):
241 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
242 case AR_EEPROM_MAC(2):
243 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
245 return pBase
->regDmn
[0];
247 return pBase
->regDmn
[1];
249 return pBase
->deviceCap
;
251 return pBase
->opCapFlags
;
253 return pBase
->rfSilent
;
263 return AR5416_VER_MASK
;
265 return pBase
->txMask
;
267 return pBase
->rxMask
;
268 case EEP_RXGAIN_TYPE
:
269 return pBase
->rxGainType
;
270 case EEP_TXGAIN_TYPE
:
271 return pBase
->txGainType
;
273 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
274 return pBase
->openLoopPwrCntl
? true : false;
277 case EEP_RC_CHAIN_MASK
:
278 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
279 return pBase
->rcChainMask
;
282 case EEP_DAC_HPWR_5G
:
283 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_20
)
284 return pBase
->dacHiPwrMode_5G
;
288 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_22
)
289 return pBase
->frac_n_5g
;
297 static void ath9k_hw_def_set_gain(struct ath_hw
*ah
,
298 struct modal_eep_header
*pModal
,
299 struct ar5416_eeprom_def
*eep
,
300 u8 txRxAttenLocal
, int regChainOffset
, int i
)
302 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_3
) {
303 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
305 if (AR_SREV_9280_10_OR_LATER(ah
)) {
306 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
307 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
308 pModal
->bswMargin
[i
]);
309 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
310 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
311 pModal
->bswAtten
[i
]);
312 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
313 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
314 pModal
->xatten2Margin
[i
]);
315 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
316 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
317 pModal
->xatten2Db
[i
]);
319 REG_WRITE(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
320 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
321 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN
)
322 | SM(pModal
-> bswMargin
[i
],
323 AR_PHY_GAIN_2GHZ_BSW_MARGIN
));
324 REG_WRITE(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
325 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
326 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN
)
327 | SM(pModal
->bswAtten
[i
],
328 AR_PHY_GAIN_2GHZ_BSW_ATTEN
));
332 if (AR_SREV_9280_10_OR_LATER(ah
)) {
334 AR_PHY_RXGAIN
+ regChainOffset
,
335 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
337 AR_PHY_RXGAIN
+ regChainOffset
,
338 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[i
]);
341 AR_PHY_RXGAIN
+ regChainOffset
,
342 (REG_READ(ah
, AR_PHY_RXGAIN
+ regChainOffset
) &
343 ~AR_PHY_RXGAIN_TXRX_ATTEN
)
344 | SM(txRxAttenLocal
, AR_PHY_RXGAIN_TXRX_ATTEN
));
346 AR_PHY_GAIN_2GHZ
+ regChainOffset
,
347 (REG_READ(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
) &
348 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN
) |
349 SM(pModal
->rxTxMarginCh
[i
], AR_PHY_GAIN_2GHZ_RXTX_MARGIN
));
353 static void ath9k_hw_def_set_board_values(struct ath_hw
*ah
,
354 struct ath9k_channel
*chan
)
356 struct modal_eep_header
*pModal
;
357 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
358 int i
, regChainOffset
;
361 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
362 txRxAttenLocal
= IS_CHAN_2GHZ(chan
) ? 23 : 44;
364 REG_WRITE(ah
, AR_PHY_SWITCH_COM
,
365 ah
->eep_ops
->get_eeprom_antenna_cfg(ah
, chan
));
367 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
368 if (AR_SREV_9280(ah
)) {
373 if (AR_SREV_5416_20_OR_LATER(ah
) &&
374 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) && (i
!= 0))
375 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
377 regChainOffset
= i
* 0x1000;
379 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
380 pModal
->antCtrlChain
[i
]);
382 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
383 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
) &
384 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
385 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
386 SM(pModal
->iqCalICh
[i
],
387 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
388 SM(pModal
->iqCalQCh
[i
],
389 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
391 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
))
392 ath9k_hw_def_set_gain(ah
, pModal
, eep
, txRxAttenLocal
,
396 if (AR_SREV_9280_10_OR_LATER(ah
)) {
397 if (IS_CHAN_2GHZ(chan
)) {
398 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
400 AR_AN_RF2G1_CH0_OB_S
,
402 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
404 AR_AN_RF2G1_CH0_DB_S
,
406 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
408 AR_AN_RF2G1_CH1_OB_S
,
410 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
412 AR_AN_RF2G1_CH1_DB_S
,
415 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
417 AR_AN_RF5G1_CH0_OB5_S
,
419 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
421 AR_AN_RF5G1_CH0_DB5_S
,
423 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
425 AR_AN_RF5G1_CH1_OB5_S
,
427 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
429 AR_AN_RF5G1_CH1_DB5_S
,
432 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
433 AR_AN_TOP2_XPABIAS_LVL
,
434 AR_AN_TOP2_XPABIAS_LVL_S
,
436 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
437 AR_AN_TOP2_LOCALBIAS
,
438 AR_AN_TOP2_LOCALBIAS_S
,
440 REG_RMW_FIELD(ah
, AR_PHY_XPA_CFG
, AR_PHY_FORCE_XPA_CFG
,
441 pModal
->force_xpaon
);
444 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
445 pModal
->switchSettling
);
446 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
447 pModal
->adcDesiredSize
);
449 if (!AR_SREV_9280_10_OR_LATER(ah
))
450 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
451 AR_PHY_DESIRED_SZ_PGA
,
452 pModal
->pgaDesiredSize
);
454 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
455 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
456 | SM(pModal
->txEndToXpaOff
,
457 AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
458 | SM(pModal
->txFrameToXpaOn
,
459 AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
460 | SM(pModal
->txFrameToXpaOn
,
461 AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
463 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
464 pModal
->txEndToRxOn
);
466 if (AR_SREV_9280_10_OR_LATER(ah
)) {
467 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
469 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
470 AR_PHY_EXT_CCA0_THRESH62
,
473 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR_PHY_CCA_THRESH62
,
475 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA
,
476 AR_PHY_EXT_CCA_THRESH62
,
480 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_2
) {
481 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
482 AR_PHY_TX_END_DATA_START
,
483 pModal
->txFrameToDataStart
);
484 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
485 pModal
->txFrameToPaOn
);
488 if (AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_3
) {
489 if (IS_CHAN_HT40(chan
))
490 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
491 AR_PHY_SETTLING_SWITCH
,
492 pModal
->swSettleHt40
);
495 if (AR_SREV_9280_20_OR_LATER(ah
) &&
496 AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_19
)
497 REG_RMW_FIELD(ah
, AR_PHY_CCK_TX_CTRL
,
498 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK
,
502 if (AR_SREV_9280_20(ah
) && AR5416_VER_MASK
>= AR5416_EEP_MINOR_VER_20
) {
503 if (IS_CHAN_2GHZ(chan
))
504 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
,
505 eep
->baseEepHeader
.dacLpMode
);
506 else if (eep
->baseEepHeader
.dacHiPwrMode_5G
)
507 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
, 0);
509 REG_RMW_FIELD(ah
, AR_AN_TOP1
, AR_AN_TOP1_DACIPMODE
,
510 eep
->baseEepHeader
.dacLpMode
);
512 REG_RMW_FIELD(ah
, AR_PHY_FRAME_CTL
, AR_PHY_FRAME_CTL_TX_CLIP
,
513 pModal
->miscBits
>> 2);
515 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL9
,
516 AR_PHY_TX_DESIRED_SCALE_CCK
,
517 eep
->baseEepHeader
.desiredScaleCCK
);
521 static void ath9k_hw_def_set_addac(struct ath_hw
*ah
,
522 struct ath9k_channel
*chan
)
524 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
525 struct modal_eep_header
*pModal
;
526 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
529 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
532 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
535 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
537 if (pModal
->xpaBiasLvl
!= 0xff) {
538 biaslevel
= pModal
->xpaBiasLvl
;
540 u16 resetFreqBin
, freqBin
, freqCount
= 0;
541 struct chan_centers centers
;
543 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
545 resetFreqBin
= FREQ2FBIN(centers
.synth_center
,
547 freqBin
= XPA_LVL_FREQ(0) & 0xff;
548 biaslevel
= (u8
) (XPA_LVL_FREQ(0) >> 14);
552 while (freqCount
< 3) {
553 if (XPA_LVL_FREQ(freqCount
) == 0x0)
556 freqBin
= XPA_LVL_FREQ(freqCount
) & 0xff;
557 if (resetFreqBin
>= freqBin
)
558 biaslevel
= (u8
)(XPA_LVL_FREQ(freqCount
) >> 14);
565 if (IS_CHAN_2GHZ(chan
)) {
566 INI_RA(&ah
->iniAddac
, 7, 1) = (INI_RA(&ah
->iniAddac
,
567 7, 1) & (~0x18)) | biaslevel
<< 3;
569 INI_RA(&ah
->iniAddac
, 6, 1) = (INI_RA(&ah
->iniAddac
,
570 6, 1) & (~0xc0)) | biaslevel
<< 6;
575 static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw
*ah
,
576 struct ath9k_channel
*chan
,
577 struct cal_data_per_freq
*pRawDataSet
,
578 u8
*bChans
, u16 availPiers
,
579 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
580 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
585 u16 idxL
= 0, idxR
= 0, numPiers
;
586 static u8 vpdTableL
[AR5416_NUM_PD_GAINS
]
587 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
588 static u8 vpdTableR
[AR5416_NUM_PD_GAINS
]
589 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
590 static u8 vpdTableI
[AR5416_NUM_PD_GAINS
]
591 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
593 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
594 u8 minPwrT4
[AR5416_NUM_PD_GAINS
];
595 u8 maxPwrT4
[AR5416_NUM_PD_GAINS
];
598 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
600 int16_t minDelta
= 0;
601 struct chan_centers centers
;
603 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
605 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
606 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
610 match
= ath9k_hw_get_lower_upper_index((u8
)FREQ2FBIN(centers
.synth_center
,
612 bChans
, numPiers
, &idxL
, &idxR
);
615 for (i
= 0; i
< numXpdGains
; i
++) {
616 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
617 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
618 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
619 pRawDataSet
[idxL
].pwrPdg
[i
],
620 pRawDataSet
[idxL
].vpdPdg
[i
],
621 AR5416_PD_GAIN_ICEPTS
,
625 for (i
= 0; i
< numXpdGains
; i
++) {
626 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
627 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
628 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
629 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
631 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
634 min(pPwrL
[AR5416_PD_GAIN_ICEPTS
- 1],
635 pPwrR
[AR5416_PD_GAIN_ICEPTS
- 1]);
638 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
640 AR5416_PD_GAIN_ICEPTS
,
642 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
644 AR5416_PD_GAIN_ICEPTS
,
647 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
649 (u8
)(ath9k_hw_interpolate((u16
)
654 bChans
[idxL
], bChans
[idxR
],
655 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
660 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
664 for (i
= 0; i
< numXpdGains
; i
++) {
665 if (i
== (numXpdGains
- 1))
666 pPdGainBoundaries
[i
] =
667 (u16
)(maxPwrT4
[i
] / 2);
669 pPdGainBoundaries
[i
] =
670 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
672 pPdGainBoundaries
[i
] =
673 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
675 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
676 minDelta
= pPdGainBoundaries
[0] - 23;
677 pPdGainBoundaries
[0] = 23;
683 if (AR_SREV_9280_10_OR_LATER(ah
))
684 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
688 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
690 tPdGainOverlap
+ 1 + minDelta
);
692 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
693 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
695 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
696 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
697 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
701 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
702 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
704 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
705 tgtIndex
: sizeCurrVpdTable
;
707 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
708 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
711 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
712 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
713 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
715 if (tgtIndex
> maxIndex
) {
716 while ((ss
<= tgtIndex
) &&
717 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
718 tmpVal
= (int16_t)((vpdTableI
[i
][sizeCurrVpdTable
- 1] +
719 (ss
- maxIndex
+ 1) * vpdStep
));
720 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
727 while (i
< AR5416_PD_GAINS_IN_MASK
) {
728 pPdGainBoundaries
[i
] = pPdGainBoundaries
[i
- 1];
732 while (k
< AR5416_NUM_PDADC_VALUES
) {
733 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
740 static void ath9k_hw_set_def_power_cal_table(struct ath_hw
*ah
,
741 struct ath9k_channel
*chan
,
742 int16_t *pTxPowerIndexOffset
)
744 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
745 #define SM_PDGAIN_B(x, y) \
746 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
748 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
749 struct cal_data_per_freq
*pRawDataset
;
750 u8
*pCalBChans
= NULL
;
751 u16 pdGainOverlap_t2
;
752 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
753 u16 gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
755 int16_t tMinCalPower
;
756 u16 numXpdGain
, xpdMask
;
757 u16 xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
758 u32 reg32
, regOffset
, regChainOffset
;
761 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
762 xpdMask
= pEepData
->modalHeader
[modalIdx
].xpdGain
;
764 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
765 AR5416_EEP_MINOR_VER_2
) {
767 pEepData
->modalHeader
[modalIdx
].pdGainOverlap
;
769 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
770 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
773 if (IS_CHAN_2GHZ(chan
)) {
774 pCalBChans
= pEepData
->calFreqPier2G
;
775 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
777 pCalBChans
= pEepData
->calFreqPier5G
;
778 numPiers
= AR5416_NUM_5G_CAL_PIERS
;
781 if (OLC_FOR_AR9280_20_LATER
&& IS_CHAN_2GHZ(chan
)) {
782 pRawDataset
= pEepData
->calPierData2G
[0];
783 ah
->initPDADC
= ((struct calDataPerFreqOpLoop
*)
784 pRawDataset
)->vpdPdg
[0][0];
789 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
790 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
791 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
793 xpdGainValues
[numXpdGain
] =
794 (u16
)(AR5416_PD_GAINS_IN_MASK
- i
);
799 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
800 (numXpdGain
- 1) & 0x3);
801 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
803 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
805 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
808 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
809 if (AR_SREV_5416_20_OR_LATER(ah
) &&
810 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
812 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
814 regChainOffset
= i
* 0x1000;
816 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
817 if (IS_CHAN_2GHZ(chan
))
818 pRawDataset
= pEepData
->calPierData2G
[i
];
820 pRawDataset
= pEepData
->calPierData5G
[i
];
823 if (OLC_FOR_AR9280_20_LATER
) {
827 ath9k_get_txgain_index(ah
, chan
,
828 (struct calDataPerFreqOpLoop
*)pRawDataset
,
829 pCalBChans
, numPiers
, &txPower
, &pcdacIdx
);
830 ath9k_olc_get_pdadcs(ah
, pcdacIdx
,
831 txPower
/2, pdadcValues
);
833 ath9k_hw_get_def_gain_boundaries_pdadcs(ah
,
835 pCalBChans
, numPiers
,
843 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
844 if (OLC_FOR_AR9280_20_LATER
) {
846 AR_PHY_TPCRG5
+ regChainOffset
,
848 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
) |
849 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
850 SM_PD_GAIN(3) | SM_PD_GAIN(4));
853 AR_PHY_TPCRG5
+ regChainOffset
,
855 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)|
863 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
864 for (j
= 0; j
< 32; j
++) {
865 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
866 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
867 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
868 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
869 REG_WRITE(ah
, regOffset
, reg32
);
871 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
872 "PDADC (%d,%4x): %4.4x %8.8x\n",
873 i
, regChainOffset
, regOffset
,
875 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
876 "PDADC: Chain %d | PDADC %3d "
877 "Value %3d | PDADC %3d Value %3d | "
878 "PDADC %3d Value %3d | PDADC %3d "
880 i
, 4 * j
, pdadcValues
[4 * j
],
881 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
882 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
884 pdadcValues
[4 * j
+ 3]);
891 *pTxPowerIndexOffset
= 0;
896 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw
*ah
,
897 struct ath9k_channel
*chan
,
900 u16 AntennaReduction
,
901 u16 twiceMaxRegulatoryPower
,
904 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
905 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
907 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
908 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
909 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
910 static const u16 tpScaleReductionTable
[5] =
911 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
914 int16_t twiceLargestAntenna
;
915 struct cal_ctl_data
*rep
;
916 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
919 struct cal_target_power_leg targetPowerOfdmExt
= {
920 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
923 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
926 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
927 u16 ctlModesFor11a
[] =
928 { CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
};
929 u16 ctlModesFor11g
[] =
930 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
933 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
934 struct chan_centers centers
;
936 u16 twiceMinEdgePower
;
938 tx_chainmask
= ah
->txchainmask
;
940 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
942 twiceLargestAntenna
= max(
943 pEepData
->modalHeader
944 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[0],
945 pEepData
->modalHeader
946 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[1]);
948 twiceLargestAntenna
= max((u8
)twiceLargestAntenna
,
949 pEepData
->modalHeader
950 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[2]);
952 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
953 twiceLargestAntenna
, 0);
955 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
957 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
958 maxRegAllowedPower
-=
959 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
962 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
964 switch (ar5416_get_ntxchains(tx_chainmask
)) {
968 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
971 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
975 scaledPower
= max((u16
)0, scaledPower
);
977 if (IS_CHAN_2GHZ(chan
)) {
978 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) -
979 SUB_NUM_CTL_MODES_AT_2G_40
;
980 pCtlMode
= ctlModesFor11g
;
982 ath9k_hw_get_legacy_target_powers(ah
, chan
,
983 pEepData
->calTargetPowerCck
,
984 AR5416_NUM_2G_CCK_TARGET_POWERS
,
985 &targetPowerCck
, 4, false);
986 ath9k_hw_get_legacy_target_powers(ah
, chan
,
987 pEepData
->calTargetPower2G
,
988 AR5416_NUM_2G_20_TARGET_POWERS
,
989 &targetPowerOfdm
, 4, false);
990 ath9k_hw_get_target_powers(ah
, chan
,
991 pEepData
->calTargetPower2GHT20
,
992 AR5416_NUM_2G_20_TARGET_POWERS
,
993 &targetPowerHt20
, 8, false);
995 if (IS_CHAN_HT40(chan
)) {
996 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
997 ath9k_hw_get_target_powers(ah
, chan
,
998 pEepData
->calTargetPower2GHT40
,
999 AR5416_NUM_2G_40_TARGET_POWERS
,
1000 &targetPowerHt40
, 8, true);
1001 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1002 pEepData
->calTargetPowerCck
,
1003 AR5416_NUM_2G_CCK_TARGET_POWERS
,
1004 &targetPowerCckExt
, 4, true);
1005 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1006 pEepData
->calTargetPower2G
,
1007 AR5416_NUM_2G_20_TARGET_POWERS
,
1008 &targetPowerOfdmExt
, 4, true);
1011 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
) -
1012 SUB_NUM_CTL_MODES_AT_5G_40
;
1013 pCtlMode
= ctlModesFor11a
;
1015 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1016 pEepData
->calTargetPower5G
,
1017 AR5416_NUM_5G_20_TARGET_POWERS
,
1018 &targetPowerOfdm
, 4, false);
1019 ath9k_hw_get_target_powers(ah
, chan
,
1020 pEepData
->calTargetPower5GHT20
,
1021 AR5416_NUM_5G_20_TARGET_POWERS
,
1022 &targetPowerHt20
, 8, false);
1024 if (IS_CHAN_HT40(chan
)) {
1025 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
1026 ath9k_hw_get_target_powers(ah
, chan
,
1027 pEepData
->calTargetPower5GHT40
,
1028 AR5416_NUM_5G_40_TARGET_POWERS
,
1029 &targetPowerHt40
, 8, true);
1030 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1031 pEepData
->calTargetPower5G
,
1032 AR5416_NUM_5G_20_TARGET_POWERS
,
1033 &targetPowerOfdmExt
, 4, true);
1037 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
1038 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
1039 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
1041 freq
= centers
.synth_center
;
1042 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
1043 freq
= centers
.ext_center
;
1045 freq
= centers
.ctl_center
;
1047 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
1048 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
1049 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
1051 for (i
= 0; (i
< AR5416_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
1052 if ((((cfgCtl
& ~CTL_MODE_M
) |
1053 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1054 pEepData
->ctlIndex
[i
]) ||
1055 (((cfgCtl
& ~CTL_MODE_M
) |
1056 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1057 ((pEepData
->ctlIndex
[i
] & CTL_MODE_M
) | SD_NO_CTL
))) {
1058 rep
= &(pEepData
->ctlData
[i
]);
1060 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(freq
,
1061 rep
->ctlEdges
[ar5416_get_ntxchains(tx_chainmask
) - 1],
1062 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
1064 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
1065 twiceMaxEdgePower
= min(twiceMaxEdgePower
,
1068 twiceMaxEdgePower
= twiceMinEdgePower
;
1074 minCtlPower
= min(twiceMaxEdgePower
, scaledPower
);
1076 switch (pCtlMode
[ctlMode
]) {
1078 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
1079 targetPowerCck
.tPow2x
[i
] =
1080 min((u16
)targetPowerCck
.tPow2x
[i
],
1086 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
1087 targetPowerOfdm
.tPow2x
[i
] =
1088 min((u16
)targetPowerOfdm
.tPow2x
[i
],
1094 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
1095 targetPowerHt20
.tPow2x
[i
] =
1096 min((u16
)targetPowerHt20
.tPow2x
[i
],
1101 targetPowerCckExt
.tPow2x
[0] = min((u16
)
1102 targetPowerCckExt
.tPow2x
[0],
1107 targetPowerOfdmExt
.tPow2x
[0] = min((u16
)
1108 targetPowerOfdmExt
.tPow2x
[0],
1113 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1114 targetPowerHt40
.tPow2x
[i
] =
1115 min((u16
)targetPowerHt40
.tPow2x
[i
],
1124 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
1125 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
1126 targetPowerOfdm
.tPow2x
[0];
1127 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
1128 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
1129 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
1130 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
1132 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
1133 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
1135 if (IS_CHAN_2GHZ(chan
)) {
1136 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
1137 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
1138 targetPowerCck
.tPow2x
[1];
1139 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
1140 targetPowerCck
.tPow2x
[2];
1141 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
1142 targetPowerCck
.tPow2x
[3];
1144 if (IS_CHAN_HT40(chan
)) {
1145 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1146 ratesArray
[rateHt40_0
+ i
] =
1147 targetPowerHt40
.tPow2x
[i
];
1149 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
1150 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
1151 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
1152 if (IS_CHAN_2GHZ(chan
)) {
1153 ratesArray
[rateExtCck
] =
1154 targetPowerCckExt
.tPow2x
[0];
1159 static void ath9k_hw_def_set_txpower(struct ath_hw
*ah
,
1160 struct ath9k_channel
*chan
,
1162 u8 twiceAntennaReduction
,
1163 u8 twiceMaxRegulatoryPower
,
1166 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1167 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
1168 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
1169 struct modal_eep_header
*pModal
=
1170 &(pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1171 int16_t ratesArray
[Ar5416RateSize
];
1172 int16_t txPowerIndexOffset
= 0;
1173 u8 ht40PowerIncForPdadc
= 2;
1174 int i
, cck_ofdm_delta
= 0;
1176 memset(ratesArray
, 0, sizeof(ratesArray
));
1178 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1179 AR5416_EEP_MINOR_VER_2
) {
1180 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
1183 ath9k_hw_set_def_power_per_rate_table(ah
, chan
,
1184 &ratesArray
[0], cfgCtl
,
1185 twiceAntennaReduction
,
1186 twiceMaxRegulatoryPower
,
1189 ath9k_hw_set_def_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
1191 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
1192 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
1193 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
1194 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
1197 if (AR_SREV_9280_10_OR_LATER(ah
)) {
1198 for (i
= 0; i
< Ar5416RateSize
; i
++)
1199 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET
* 2;
1202 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
1203 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
1204 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
1205 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
1206 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
1207 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
1208 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
1209 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
1210 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
1211 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
1213 if (IS_CHAN_2GHZ(chan
)) {
1214 if (OLC_FOR_AR9280_20_LATER
) {
1216 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1217 ATH9K_POW_SM(RT_AR_DELTA(rate2s
), 24)
1218 | ATH9K_POW_SM(RT_AR_DELTA(rate2l
), 16)
1219 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1220 | ATH9K_POW_SM(RT_AR_DELTA(rate1l
), 0));
1221 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1222 ATH9K_POW_SM(RT_AR_DELTA(rate11s
), 24)
1223 | ATH9K_POW_SM(RT_AR_DELTA(rate11l
), 16)
1224 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s
), 8)
1225 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l
), 0));
1227 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1228 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
1229 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
1230 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1231 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
1232 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1233 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
1234 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
1235 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
1236 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
1240 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
1241 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
1242 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
1243 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
1244 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
1245 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
1246 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
1247 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
1248 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
1249 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
1251 if (IS_CHAN_HT40(chan
)) {
1252 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
1253 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
1254 ht40PowerIncForPdadc
, 24)
1255 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
1256 ht40PowerIncForPdadc
, 16)
1257 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
1258 ht40PowerIncForPdadc
, 8)
1259 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
1260 ht40PowerIncForPdadc
, 0));
1261 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
1262 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
1263 ht40PowerIncForPdadc
, 24)
1264 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
1265 ht40PowerIncForPdadc
, 16)
1266 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
1267 ht40PowerIncForPdadc
, 8)
1268 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
1269 ht40PowerIncForPdadc
, 0));
1270 if (OLC_FOR_AR9280_20_LATER
) {
1271 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1272 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1273 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck
), 16)
1274 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1275 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck
), 0));
1277 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1278 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1279 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
1280 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1281 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
1285 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
1286 ATH9K_POW_SM(pModal
->pwrDecreaseFor3Chain
, 6)
1287 | ATH9K_POW_SM(pModal
->pwrDecreaseFor2Chain
, 0));
1291 if (IS_CHAN_HT40(chan
))
1293 else if (IS_CHAN_HT20(chan
))
1296 if (AR_SREV_9280_10_OR_LATER(ah
))
1297 regulatory
->max_power_level
=
1298 ratesArray
[i
] + AR5416_PWR_TABLE_OFFSET
* 2;
1300 regulatory
->max_power_level
= ratesArray
[i
];
1302 switch(ar5416_get_ntxchains(ah
->txchainmask
)) {
1306 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_TWO_CHAIN
;
1309 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_THREE_CHAIN
;
1312 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1313 "Invalid chainmask configuration\n");
1318 static u8
ath9k_hw_def_get_num_ant_config(struct ath_hw
*ah
,
1319 enum ieee80211_band freq_band
)
1321 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
1322 struct modal_eep_header
*pModal
=
1323 &(eep
->modalHeader
[ATH9K_HAL_FREQ_BAND_2GHZ
== freq_band
]);
1324 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
1329 if (pBase
->version
>= 0x0E0D)
1330 if (pModal
->useAnt1
)
1331 num_ant_config
+= 1;
1333 return num_ant_config
;
1336 static u16
ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1337 struct ath9k_channel
*chan
)
1339 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
1340 struct modal_eep_header
*pModal
=
1341 &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1343 return pModal
->antCtrlCommon
& 0xFFFF;
1346 static u16
ath9k_hw_def_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1348 #define EEP_DEF_SPURCHAN \
1349 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1351 u16 spur_val
= AR_NO_SPUR
;
1353 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1354 "Getting spur idx %d is2Ghz. %d val %x\n",
1355 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1357 switch (ah
->config
.spurmode
) {
1360 case SPUR_ENABLE_IOCTL
:
1361 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1362 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1363 "Getting spur val from new loc. %d\n", spur_val
);
1365 case SPUR_ENABLE_EEPROM
:
1366 spur_val
= EEP_DEF_SPURCHAN
;
1372 #undef EEP_DEF_SPURCHAN
1375 const struct eeprom_ops eep_def_ops
= {
1376 .check_eeprom
= ath9k_hw_def_check_eeprom
,
1377 .get_eeprom
= ath9k_hw_def_get_eeprom
,
1378 .fill_eeprom
= ath9k_hw_def_fill_eeprom
,
1379 .get_eeprom_ver
= ath9k_hw_def_get_eeprom_ver
,
1380 .get_eeprom_rev
= ath9k_hw_def_get_eeprom_rev
,
1381 .get_num_ant_config
= ath9k_hw_def_get_num_ant_config
,
1382 .get_eeprom_antenna_cfg
= ath9k_hw_def_get_eeprom_antenna_cfg
,
1383 .set_board_values
= ath9k_hw_def_set_board_values
,
1384 .set_addac
= ath9k_hw_def_set_addac
,
1385 .set_txpower
= ath9k_hw_def_set_txpower
,
1386 .get_spur_channel
= ath9k_hw_def_get_spur_channel