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
);
514 REG_RMW_FIELD(ah
, AR_PHY_FRAME_CTL
, AR_PHY_FRAME_CTL_TX_CLIP
,
515 pModal
->miscBits
>> 2);
517 REG_RMW_FIELD(ah
, AR_PHY_TX_PWRCTRL9
,
518 AR_PHY_TX_DESIRED_SCALE_CCK
,
519 eep
->baseEepHeader
.desiredScaleCCK
);
523 static void ath9k_hw_def_set_addac(struct ath_hw
*ah
,
524 struct ath9k_channel
*chan
)
526 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
527 struct modal_eep_header
*pModal
;
528 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
531 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
534 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
537 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
539 if (pModal
->xpaBiasLvl
!= 0xff) {
540 biaslevel
= pModal
->xpaBiasLvl
;
542 u16 resetFreqBin
, freqBin
, freqCount
= 0;
543 struct chan_centers centers
;
545 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
547 resetFreqBin
= FREQ2FBIN(centers
.synth_center
,
549 freqBin
= XPA_LVL_FREQ(0) & 0xff;
550 biaslevel
= (u8
) (XPA_LVL_FREQ(0) >> 14);
554 while (freqCount
< 3) {
555 if (XPA_LVL_FREQ(freqCount
) == 0x0)
558 freqBin
= XPA_LVL_FREQ(freqCount
) & 0xff;
559 if (resetFreqBin
>= freqBin
)
560 biaslevel
= (u8
)(XPA_LVL_FREQ(freqCount
) >> 14);
567 if (IS_CHAN_2GHZ(chan
)) {
568 INI_RA(&ah
->iniAddac
, 7, 1) = (INI_RA(&ah
->iniAddac
,
569 7, 1) & (~0x18)) | biaslevel
<< 3;
571 INI_RA(&ah
->iniAddac
, 6, 1) = (INI_RA(&ah
->iniAddac
,
572 6, 1) & (~0xc0)) | biaslevel
<< 6;
577 static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw
*ah
,
578 struct ath9k_channel
*chan
,
579 struct cal_data_per_freq
*pRawDataSet
,
580 u8
*bChans
, u16 availPiers
,
581 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
582 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
587 u16 idxL
= 0, idxR
= 0, numPiers
;
588 static u8 vpdTableL
[AR5416_NUM_PD_GAINS
]
589 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
590 static u8 vpdTableR
[AR5416_NUM_PD_GAINS
]
591 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
592 static u8 vpdTableI
[AR5416_NUM_PD_GAINS
]
593 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
595 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
596 u8 minPwrT4
[AR5416_NUM_PD_GAINS
];
597 u8 maxPwrT4
[AR5416_NUM_PD_GAINS
];
600 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
602 int16_t minDelta
= 0;
603 struct chan_centers centers
;
605 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
607 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
608 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
612 match
= ath9k_hw_get_lower_upper_index((u8
)FREQ2FBIN(centers
.synth_center
,
614 bChans
, numPiers
, &idxL
, &idxR
);
617 for (i
= 0; i
< numXpdGains
; i
++) {
618 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
619 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
620 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
621 pRawDataSet
[idxL
].pwrPdg
[i
],
622 pRawDataSet
[idxL
].vpdPdg
[i
],
623 AR5416_PD_GAIN_ICEPTS
,
627 for (i
= 0; i
< numXpdGains
; i
++) {
628 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
629 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
630 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
631 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
633 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
636 min(pPwrL
[AR5416_PD_GAIN_ICEPTS
- 1],
637 pPwrR
[AR5416_PD_GAIN_ICEPTS
- 1]);
640 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
642 AR5416_PD_GAIN_ICEPTS
,
644 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
646 AR5416_PD_GAIN_ICEPTS
,
649 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
651 (u8
)(ath9k_hw_interpolate((u16
)
656 bChans
[idxL
], bChans
[idxR
],
657 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
662 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
666 for (i
= 0; i
< numXpdGains
; i
++) {
667 if (i
== (numXpdGains
- 1))
668 pPdGainBoundaries
[i
] =
669 (u16
)(maxPwrT4
[i
] / 2);
671 pPdGainBoundaries
[i
] =
672 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
674 pPdGainBoundaries
[i
] =
675 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
677 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
678 minDelta
= pPdGainBoundaries
[0] - 23;
679 pPdGainBoundaries
[0] = 23;
685 if (AR_SREV_9280_10_OR_LATER(ah
))
686 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
690 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
692 tPdGainOverlap
+ 1 + minDelta
);
694 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
695 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
697 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
698 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
699 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
703 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
704 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
706 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
707 tgtIndex
: sizeCurrVpdTable
;
709 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
710 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
713 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
714 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
715 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
717 if (tgtIndex
> maxIndex
) {
718 while ((ss
<= tgtIndex
) &&
719 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
720 tmpVal
= (int16_t)((vpdTableI
[i
][sizeCurrVpdTable
- 1] +
721 (ss
- maxIndex
+ 1) * vpdStep
));
722 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
729 while (i
< AR5416_PD_GAINS_IN_MASK
) {
730 pPdGainBoundaries
[i
] = pPdGainBoundaries
[i
- 1];
734 while (k
< AR5416_NUM_PDADC_VALUES
) {
735 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
742 static void ath9k_hw_set_def_power_cal_table(struct ath_hw
*ah
,
743 struct ath9k_channel
*chan
,
744 int16_t *pTxPowerIndexOffset
)
746 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
747 #define SM_PDGAIN_B(x, y) \
748 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
750 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
751 struct cal_data_per_freq
*pRawDataset
;
752 u8
*pCalBChans
= NULL
;
753 u16 pdGainOverlap_t2
;
754 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
755 u16 gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
757 int16_t tMinCalPower
;
758 u16 numXpdGain
, xpdMask
;
759 u16 xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
760 u32 reg32
, regOffset
, regChainOffset
;
763 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
764 xpdMask
= pEepData
->modalHeader
[modalIdx
].xpdGain
;
766 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
767 AR5416_EEP_MINOR_VER_2
) {
769 pEepData
->modalHeader
[modalIdx
].pdGainOverlap
;
771 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
772 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
775 if (IS_CHAN_2GHZ(chan
)) {
776 pCalBChans
= pEepData
->calFreqPier2G
;
777 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
779 pCalBChans
= pEepData
->calFreqPier5G
;
780 numPiers
= AR5416_NUM_5G_CAL_PIERS
;
783 if (OLC_FOR_AR9280_20_LATER
&& IS_CHAN_2GHZ(chan
)) {
784 pRawDataset
= pEepData
->calPierData2G
[0];
785 ah
->initPDADC
= ((struct calDataPerFreqOpLoop
*)
786 pRawDataset
)->vpdPdg
[0][0];
791 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
792 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
793 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
795 xpdGainValues
[numXpdGain
] =
796 (u16
)(AR5416_PD_GAINS_IN_MASK
- i
);
801 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
802 (numXpdGain
- 1) & 0x3);
803 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
805 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
807 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
810 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
811 if (AR_SREV_5416_20_OR_LATER(ah
) &&
812 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
814 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
816 regChainOffset
= i
* 0x1000;
818 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
819 if (IS_CHAN_2GHZ(chan
))
820 pRawDataset
= pEepData
->calPierData2G
[i
];
822 pRawDataset
= pEepData
->calPierData5G
[i
];
825 if (OLC_FOR_AR9280_20_LATER
) {
829 ath9k_get_txgain_index(ah
, chan
,
830 (struct calDataPerFreqOpLoop
*)pRawDataset
,
831 pCalBChans
, numPiers
, &txPower
, &pcdacIdx
);
832 ath9k_olc_get_pdadcs(ah
, pcdacIdx
,
833 txPower
/2, pdadcValues
);
835 ath9k_hw_get_def_gain_boundaries_pdadcs(ah
,
837 pCalBChans
, numPiers
,
845 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
846 if (OLC_FOR_AR9280_20_LATER
) {
848 AR_PHY_TPCRG5
+ regChainOffset
,
850 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
) |
851 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
852 SM_PD_GAIN(3) | SM_PD_GAIN(4));
855 AR_PHY_TPCRG5
+ regChainOffset
,
857 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)|
865 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
866 for (j
= 0; j
< 32; j
++) {
867 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
868 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
869 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
870 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
871 REG_WRITE(ah
, regOffset
, reg32
);
873 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
874 "PDADC (%d,%4x): %4.4x %8.8x\n",
875 i
, regChainOffset
, regOffset
,
877 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
878 "PDADC: Chain %d | PDADC %3d "
879 "Value %3d | PDADC %3d Value %3d | "
880 "PDADC %3d Value %3d | PDADC %3d "
882 i
, 4 * j
, pdadcValues
[4 * j
],
883 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
884 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
886 pdadcValues
[4 * j
+ 3]);
893 *pTxPowerIndexOffset
= 0;
898 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw
*ah
,
899 struct ath9k_channel
*chan
,
902 u16 AntennaReduction
,
903 u16 twiceMaxRegulatoryPower
,
906 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
907 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
909 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
910 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
911 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
912 static const u16 tpScaleReductionTable
[5] =
913 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
916 int16_t twiceLargestAntenna
;
917 struct cal_ctl_data
*rep
;
918 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
921 struct cal_target_power_leg targetPowerOfdmExt
= {
922 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
925 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
928 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
929 u16 ctlModesFor11a
[] =
930 { CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
};
931 u16 ctlModesFor11g
[] =
932 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
935 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
936 struct chan_centers centers
;
938 u16 twiceMinEdgePower
;
940 tx_chainmask
= ah
->txchainmask
;
942 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
944 twiceLargestAntenna
= max(
945 pEepData
->modalHeader
946 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[0],
947 pEepData
->modalHeader
948 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[1]);
950 twiceLargestAntenna
= max((u8
)twiceLargestAntenna
,
951 pEepData
->modalHeader
952 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[2]);
954 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
955 twiceLargestAntenna
, 0);
957 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
959 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
960 maxRegAllowedPower
-=
961 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
964 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
966 switch (ar5416_get_ntxchains(tx_chainmask
)) {
970 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
973 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
977 scaledPower
= max((u16
)0, scaledPower
);
979 if (IS_CHAN_2GHZ(chan
)) {
980 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) -
981 SUB_NUM_CTL_MODES_AT_2G_40
;
982 pCtlMode
= ctlModesFor11g
;
984 ath9k_hw_get_legacy_target_powers(ah
, chan
,
985 pEepData
->calTargetPowerCck
,
986 AR5416_NUM_2G_CCK_TARGET_POWERS
,
987 &targetPowerCck
, 4, false);
988 ath9k_hw_get_legacy_target_powers(ah
, chan
,
989 pEepData
->calTargetPower2G
,
990 AR5416_NUM_2G_20_TARGET_POWERS
,
991 &targetPowerOfdm
, 4, false);
992 ath9k_hw_get_target_powers(ah
, chan
,
993 pEepData
->calTargetPower2GHT20
,
994 AR5416_NUM_2G_20_TARGET_POWERS
,
995 &targetPowerHt20
, 8, false);
997 if (IS_CHAN_HT40(chan
)) {
998 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
999 ath9k_hw_get_target_powers(ah
, chan
,
1000 pEepData
->calTargetPower2GHT40
,
1001 AR5416_NUM_2G_40_TARGET_POWERS
,
1002 &targetPowerHt40
, 8, true);
1003 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1004 pEepData
->calTargetPowerCck
,
1005 AR5416_NUM_2G_CCK_TARGET_POWERS
,
1006 &targetPowerCckExt
, 4, true);
1007 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1008 pEepData
->calTargetPower2G
,
1009 AR5416_NUM_2G_20_TARGET_POWERS
,
1010 &targetPowerOfdmExt
, 4, true);
1013 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
) -
1014 SUB_NUM_CTL_MODES_AT_5G_40
;
1015 pCtlMode
= ctlModesFor11a
;
1017 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1018 pEepData
->calTargetPower5G
,
1019 AR5416_NUM_5G_20_TARGET_POWERS
,
1020 &targetPowerOfdm
, 4, false);
1021 ath9k_hw_get_target_powers(ah
, chan
,
1022 pEepData
->calTargetPower5GHT20
,
1023 AR5416_NUM_5G_20_TARGET_POWERS
,
1024 &targetPowerHt20
, 8, false);
1026 if (IS_CHAN_HT40(chan
)) {
1027 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
1028 ath9k_hw_get_target_powers(ah
, chan
,
1029 pEepData
->calTargetPower5GHT40
,
1030 AR5416_NUM_5G_40_TARGET_POWERS
,
1031 &targetPowerHt40
, 8, true);
1032 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1033 pEepData
->calTargetPower5G
,
1034 AR5416_NUM_5G_20_TARGET_POWERS
,
1035 &targetPowerOfdmExt
, 4, true);
1039 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
1040 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
1041 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
1043 freq
= centers
.synth_center
;
1044 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
1045 freq
= centers
.ext_center
;
1047 freq
= centers
.ctl_center
;
1049 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
1050 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
1051 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
1053 for (i
= 0; (i
< AR5416_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
1054 if ((((cfgCtl
& ~CTL_MODE_M
) |
1055 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1056 pEepData
->ctlIndex
[i
]) ||
1057 (((cfgCtl
& ~CTL_MODE_M
) |
1058 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1059 ((pEepData
->ctlIndex
[i
] & CTL_MODE_M
) | SD_NO_CTL
))) {
1060 rep
= &(pEepData
->ctlData
[i
]);
1062 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(freq
,
1063 rep
->ctlEdges
[ar5416_get_ntxchains(tx_chainmask
) - 1],
1064 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
1066 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
1067 twiceMaxEdgePower
= min(twiceMaxEdgePower
,
1070 twiceMaxEdgePower
= twiceMinEdgePower
;
1076 minCtlPower
= min(twiceMaxEdgePower
, scaledPower
);
1078 switch (pCtlMode
[ctlMode
]) {
1080 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
1081 targetPowerCck
.tPow2x
[i
] =
1082 min((u16
)targetPowerCck
.tPow2x
[i
],
1088 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
1089 targetPowerOfdm
.tPow2x
[i
] =
1090 min((u16
)targetPowerOfdm
.tPow2x
[i
],
1096 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
1097 targetPowerHt20
.tPow2x
[i
] =
1098 min((u16
)targetPowerHt20
.tPow2x
[i
],
1103 targetPowerCckExt
.tPow2x
[0] = min((u16
)
1104 targetPowerCckExt
.tPow2x
[0],
1109 targetPowerOfdmExt
.tPow2x
[0] = min((u16
)
1110 targetPowerOfdmExt
.tPow2x
[0],
1115 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1116 targetPowerHt40
.tPow2x
[i
] =
1117 min((u16
)targetPowerHt40
.tPow2x
[i
],
1126 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
1127 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
1128 targetPowerOfdm
.tPow2x
[0];
1129 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
1130 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
1131 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
1132 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
1134 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
1135 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
1137 if (IS_CHAN_2GHZ(chan
)) {
1138 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
1139 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
1140 targetPowerCck
.tPow2x
[1];
1141 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
1142 targetPowerCck
.tPow2x
[2];
1143 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
1144 targetPowerCck
.tPow2x
[3];
1146 if (IS_CHAN_HT40(chan
)) {
1147 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1148 ratesArray
[rateHt40_0
+ i
] =
1149 targetPowerHt40
.tPow2x
[i
];
1151 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
1152 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
1153 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
1154 if (IS_CHAN_2GHZ(chan
)) {
1155 ratesArray
[rateExtCck
] =
1156 targetPowerCckExt
.tPow2x
[0];
1161 static void ath9k_hw_def_set_txpower(struct ath_hw
*ah
,
1162 struct ath9k_channel
*chan
,
1164 u8 twiceAntennaReduction
,
1165 u8 twiceMaxRegulatoryPower
,
1168 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1169 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
1170 struct ar5416_eeprom_def
*pEepData
= &ah
->eeprom
.def
;
1171 struct modal_eep_header
*pModal
=
1172 &(pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1173 int16_t ratesArray
[Ar5416RateSize
];
1174 int16_t txPowerIndexOffset
= 0;
1175 u8 ht40PowerIncForPdadc
= 2;
1176 int i
, cck_ofdm_delta
= 0;
1178 memset(ratesArray
, 0, sizeof(ratesArray
));
1180 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1181 AR5416_EEP_MINOR_VER_2
) {
1182 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
1185 ath9k_hw_set_def_power_per_rate_table(ah
, chan
,
1186 &ratesArray
[0], cfgCtl
,
1187 twiceAntennaReduction
,
1188 twiceMaxRegulatoryPower
,
1191 ath9k_hw_set_def_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
1193 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
1194 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
1195 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
1196 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
1199 if (AR_SREV_9280_10_OR_LATER(ah
)) {
1200 for (i
= 0; i
< Ar5416RateSize
; i
++)
1201 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET
* 2;
1204 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
1205 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
1206 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
1207 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
1208 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
1209 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
1210 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
1211 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
1212 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
1213 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
1215 if (IS_CHAN_2GHZ(chan
)) {
1216 if (OLC_FOR_AR9280_20_LATER
) {
1218 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1219 ATH9K_POW_SM(RT_AR_DELTA(rate2s
), 24)
1220 | ATH9K_POW_SM(RT_AR_DELTA(rate2l
), 16)
1221 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1222 | ATH9K_POW_SM(RT_AR_DELTA(rate1l
), 0));
1223 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1224 ATH9K_POW_SM(RT_AR_DELTA(rate11s
), 24)
1225 | ATH9K_POW_SM(RT_AR_DELTA(rate11l
), 16)
1226 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s
), 8)
1227 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l
), 0));
1229 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1230 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
1231 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
1232 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1233 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
1234 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1235 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
1236 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
1237 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
1238 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
1242 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
1243 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
1244 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
1245 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
1246 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
1247 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
1248 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
1249 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
1250 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
1251 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
1253 if (IS_CHAN_HT40(chan
)) {
1254 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
1255 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
1256 ht40PowerIncForPdadc
, 24)
1257 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
1258 ht40PowerIncForPdadc
, 16)
1259 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
1260 ht40PowerIncForPdadc
, 8)
1261 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
1262 ht40PowerIncForPdadc
, 0));
1263 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
1264 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
1265 ht40PowerIncForPdadc
, 24)
1266 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
1267 ht40PowerIncForPdadc
, 16)
1268 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
1269 ht40PowerIncForPdadc
, 8)
1270 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
1271 ht40PowerIncForPdadc
, 0));
1272 if (OLC_FOR_AR9280_20_LATER
) {
1273 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1274 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1275 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck
), 16)
1276 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1277 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck
), 0));
1279 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1280 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1281 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
1282 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1283 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
1287 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
1288 ATH9K_POW_SM(pModal
->pwrDecreaseFor3Chain
, 6)
1289 | ATH9K_POW_SM(pModal
->pwrDecreaseFor2Chain
, 0));
1293 if (IS_CHAN_HT40(chan
))
1295 else if (IS_CHAN_HT20(chan
))
1298 if (AR_SREV_9280_10_OR_LATER(ah
))
1299 regulatory
->max_power_level
=
1300 ratesArray
[i
] + AR5416_PWR_TABLE_OFFSET
* 2;
1302 regulatory
->max_power_level
= ratesArray
[i
];
1304 switch(ar5416_get_ntxchains(ah
->txchainmask
)) {
1308 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_TWO_CHAIN
;
1311 regulatory
->max_power_level
+= INCREASE_MAXPOW_BY_THREE_CHAIN
;
1314 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1315 "Invalid chainmask configuration\n");
1320 static u8
ath9k_hw_def_get_num_ant_config(struct ath_hw
*ah
,
1321 enum ieee80211_band freq_band
)
1323 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
1324 struct modal_eep_header
*pModal
=
1325 &(eep
->modalHeader
[ATH9K_HAL_FREQ_BAND_2GHZ
== freq_band
]);
1326 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
1331 if (pBase
->version
>= 0x0E0D)
1332 if (pModal
->useAnt1
)
1333 num_ant_config
+= 1;
1335 return num_ant_config
;
1338 static u16
ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1339 struct ath9k_channel
*chan
)
1341 struct ar5416_eeprom_def
*eep
= &ah
->eeprom
.def
;
1342 struct modal_eep_header
*pModal
=
1343 &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1345 return pModal
->antCtrlCommon
& 0xFFFF;
1348 static u16
ath9k_hw_def_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1350 #define EEP_DEF_SPURCHAN \
1351 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1353 u16 spur_val
= AR_NO_SPUR
;
1355 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1356 "Getting spur idx %d is2Ghz. %d val %x\n",
1357 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1359 switch (ah
->config
.spurmode
) {
1362 case SPUR_ENABLE_IOCTL
:
1363 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1364 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1365 "Getting spur val from new loc. %d\n", spur_val
);
1367 case SPUR_ENABLE_EEPROM
:
1368 spur_val
= EEP_DEF_SPURCHAN
;
1374 #undef EEP_DEF_SPURCHAN
1377 const struct eeprom_ops eep_def_ops
= {
1378 .check_eeprom
= ath9k_hw_def_check_eeprom
,
1379 .get_eeprom
= ath9k_hw_def_get_eeprom
,
1380 .fill_eeprom
= ath9k_hw_def_fill_eeprom
,
1381 .get_eeprom_ver
= ath9k_hw_def_get_eeprom_ver
,
1382 .get_eeprom_rev
= ath9k_hw_def_get_eeprom_rev
,
1383 .get_num_ant_config
= ath9k_hw_def_get_num_ant_config
,
1384 .get_eeprom_antenna_cfg
= ath9k_hw_def_get_eeprom_antenna_cfg
,
1385 .set_board_values
= ath9k_hw_def_set_board_values
,
1386 .set_addac
= ath9k_hw_def_set_addac
,
1387 .set_txpower
= ath9k_hw_def_set_txpower
,
1388 .get_spur_channel
= ath9k_hw_def_get_spur_channel