2 * Copyright (c) 2008 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.
25 static void ath9k_hw_iqcal_collect(struct ath_hal
*ah
);
26 static void ath9k_hw_iqcalibrate(struct ath_hal
*ah
, u_int8_t numChains
);
27 static void ath9k_hw_adc_gaincal_collect(struct ath_hal
*ah
);
28 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal
*ah
,
30 static void ath9k_hw_adc_dccal_collect(struct ath_hal
*ah
);
31 static void ath9k_hw_adc_dccal_calibrate(struct ath_hal
*ah
,
34 static const u_int8_t CLOCK_RATE
[] = { 40, 80, 22, 44, 88, 40 };
35 static const int16_t NOISE_FLOOR
[] = { -96, -93, -98, -96, -93, -96 };
37 static const struct hal_percal_data iq_cal_multi_sample
= {
41 ath9k_hw_iqcal_collect
,
44 static const struct hal_percal_data iq_cal_single_sample
= {
48 ath9k_hw_iqcal_collect
,
51 static const struct hal_percal_data adc_gain_cal_multi_sample
= {
55 ath9k_hw_adc_gaincal_collect
,
56 ath9k_hw_adc_gaincal_calibrate
58 static const struct hal_percal_data adc_gain_cal_single_sample
= {
62 ath9k_hw_adc_gaincal_collect
,
63 ath9k_hw_adc_gaincal_calibrate
65 static const struct hal_percal_data adc_dc_cal_multi_sample
= {
69 ath9k_hw_adc_dccal_collect
,
70 ath9k_hw_adc_dccal_calibrate
72 static const struct hal_percal_data adc_dc_cal_single_sample
= {
76 ath9k_hw_adc_dccal_collect
,
77 ath9k_hw_adc_dccal_calibrate
79 static const struct hal_percal_data adc_init_dc_cal
= {
83 ath9k_hw_adc_dccal_collect
,
84 ath9k_hw_adc_dccal_calibrate
87 static const struct ath_hal ar5416hal
= {
99 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 static struct hal_rate_table ar5416_11a_table
= {
114 {true, PHY_OFDM
, 6000, 0x0b, 0x00, (0x80 | 12), 0},
115 {true, PHY_OFDM
, 9000, 0x0f, 0x00, 18, 0},
116 {true, PHY_OFDM
, 12000, 0x0a, 0x00, (0x80 | 24), 2},
117 {true, PHY_OFDM
, 18000, 0x0e, 0x00, 36, 2},
118 {true, PHY_OFDM
, 24000, 0x09, 0x00, (0x80 | 48), 4},
119 {true, PHY_OFDM
, 36000, 0x0d, 0x00, 72, 4},
120 {true, PHY_OFDM
, 48000, 0x08, 0x00, 96, 4},
121 {true, PHY_OFDM
, 54000, 0x0c, 0x00, 108, 4}
125 static struct hal_rate_table ar5416_11b_table
= {
129 {true, PHY_CCK
, 1000, 0x1b, 0x00, (0x80 | 2), 0},
130 {true, PHY_CCK
, 2000, 0x1a, 0x04, (0x80 | 4), 1},
131 {true, PHY_CCK
, 5500, 0x19, 0x04, (0x80 | 11), 1},
132 {true, PHY_CCK
, 11000, 0x18, 0x04, (0x80 | 22), 1}
136 static struct hal_rate_table ar5416_11g_table
= {
140 {true, PHY_CCK
, 1000, 0x1b, 0x00, (0x80 | 2), 0},
141 {true, PHY_CCK
, 2000, 0x1a, 0x04, (0x80 | 4), 1},
142 {true, PHY_CCK
, 5500, 0x19, 0x04, (0x80 | 11), 2},
143 {true, PHY_CCK
, 11000, 0x18, 0x04, (0x80 | 22), 3},
145 {false, PHY_OFDM
, 6000, 0x0b, 0x00, 12, 4},
146 {false, PHY_OFDM
, 9000, 0x0f, 0x00, 18, 4},
147 {true, PHY_OFDM
, 12000, 0x0a, 0x00, 24, 6},
148 {true, PHY_OFDM
, 18000, 0x0e, 0x00, 36, 6},
149 {true, PHY_OFDM
, 24000, 0x09, 0x00, 48, 8},
150 {true, PHY_OFDM
, 36000, 0x0d, 0x00, 72, 8},
151 {true, PHY_OFDM
, 48000, 0x08, 0x00, 96, 8},
152 {true, PHY_OFDM
, 54000, 0x0c, 0x00, 108, 8}
156 static struct hal_rate_table ar5416_11ng_table
= {
160 {true, PHY_CCK
, 1000, 0x1b, 0x00, (0x80 | 2), 0},
161 {true, PHY_CCK
, 2000, 0x1a, 0x04, (0x80 | 4), 1},
162 {true, PHY_CCK
, 5500, 0x19, 0x04, (0x80 | 11), 2},
163 {true, PHY_CCK
, 11000, 0x18, 0x04, (0x80 | 22), 3},
165 {false, PHY_OFDM
, 6000, 0x0b, 0x00, 12, 4},
166 {false, PHY_OFDM
, 9000, 0x0f, 0x00, 18, 4},
167 {true, PHY_OFDM
, 12000, 0x0a, 0x00, 24, 6},
168 {true, PHY_OFDM
, 18000, 0x0e, 0x00, 36, 6},
169 {true, PHY_OFDM
, 24000, 0x09, 0x00, 48, 8},
170 {true, PHY_OFDM
, 36000, 0x0d, 0x00, 72, 8},
171 {true, PHY_OFDM
, 48000, 0x08, 0x00, 96, 8},
172 {true, PHY_OFDM
, 54000, 0x0c, 0x00, 108, 8},
173 {true, PHY_HT
, 6500, 0x80, 0x00, 0, 4},
174 {true, PHY_HT
, 13000, 0x81, 0x00, 1, 6},
175 {true, PHY_HT
, 19500, 0x82, 0x00, 2, 6},
176 {true, PHY_HT
, 26000, 0x83, 0x00, 3, 8},
177 {true, PHY_HT
, 39000, 0x84, 0x00, 4, 8},
178 {true, PHY_HT
, 52000, 0x85, 0x00, 5, 8},
179 {true, PHY_HT
, 58500, 0x86, 0x00, 6, 8},
180 {true, PHY_HT
, 65000, 0x87, 0x00, 7, 8},
181 {true, PHY_HT
, 13000, 0x88, 0x00, 8, 4},
182 {true, PHY_HT
, 26000, 0x89, 0x00, 9, 6},
183 {true, PHY_HT
, 39000, 0x8a, 0x00, 10, 6},
184 {true, PHY_HT
, 52000, 0x8b, 0x00, 11, 8},
185 {true, PHY_HT
, 78000, 0x8c, 0x00, 12, 8},
186 {true, PHY_HT
, 104000, 0x8d, 0x00, 13, 8},
187 {true, PHY_HT
, 117000, 0x8e, 0x00, 14, 8},
188 {true, PHY_HT
, 130000, 0x8f, 0x00, 15, 8},
192 static struct hal_rate_table ar5416_11na_table
= {
196 {true, PHY_OFDM
, 6000, 0x0b, 0x00, (0x80 | 12), 0},
197 {true, PHY_OFDM
, 9000, 0x0f, 0x00, 18, 0},
198 {true, PHY_OFDM
, 12000, 0x0a, 0x00, (0x80 | 24), 2},
199 {true, PHY_OFDM
, 18000, 0x0e, 0x00, 36, 2},
200 {true, PHY_OFDM
, 24000, 0x09, 0x00, (0x80 | 48), 4},
201 {true, PHY_OFDM
, 36000, 0x0d, 0x00, 72, 4},
202 {true, PHY_OFDM
, 48000, 0x08, 0x00, 96, 4},
203 {true, PHY_OFDM
, 54000, 0x0c, 0x00, 108, 4},
204 {true, PHY_HT
, 6500, 0x80, 0x00, 0, 0},
205 {true, PHY_HT
, 13000, 0x81, 0x00, 1, 2},
206 {true, PHY_HT
, 19500, 0x82, 0x00, 2, 2},
207 {true, PHY_HT
, 26000, 0x83, 0x00, 3, 4},
208 {true, PHY_HT
, 39000, 0x84, 0x00, 4, 4},
209 {true, PHY_HT
, 52000, 0x85, 0x00, 5, 4},
210 {true, PHY_HT
, 58500, 0x86, 0x00, 6, 4},
211 {true, PHY_HT
, 65000, 0x87, 0x00, 7, 4},
212 {true, PHY_HT
, 13000, 0x88, 0x00, 8, 0},
213 {true, PHY_HT
, 26000, 0x89, 0x00, 9, 2},
214 {true, PHY_HT
, 39000, 0x8a, 0x00, 10, 2},
215 {true, PHY_HT
, 52000, 0x8b, 0x00, 11, 4},
216 {true, PHY_HT
, 78000, 0x8c, 0x00, 12, 4},
217 {true, PHY_HT
, 104000, 0x8d, 0x00, 13, 4},
218 {true, PHY_HT
, 117000, 0x8e, 0x00, 14, 4},
219 {true, PHY_HT
, 130000, 0x8f, 0x00, 15, 4},
223 static enum wireless_mode
ath9k_hw_chan2wmode(struct ath_hal
*ah
,
224 const struct hal_channel
*chan
)
226 if (IS_CHAN_CCK(chan
))
227 return WIRELESS_MODE_11b
;
229 return WIRELESS_MODE_11g
;
230 return WIRELESS_MODE_11a
;
233 static bool ath9k_hw_wait(struct ath_hal
*ah
,
240 for (i
= 0; i
< (AH_TIMEOUT
/ AH_TIME_QUANTUM
); i
++) {
241 if ((REG_READ(ah
, reg
) & mask
) == val
)
244 udelay(AH_TIME_QUANTUM
);
246 DPRINTF(ah
->ah_sc
, ATH_DBG_PHY_IO
,
247 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
248 __func__
, reg
, REG_READ(ah
, reg
), mask
, val
);
252 static bool ath9k_hw_eeprom_read(struct ath_hal
*ah
, u_int off
,
255 (void) REG_READ(ah
, AR5416_EEPROM_OFFSET
+ (off
<< AR5416_EEPROM_S
));
257 if (!ath9k_hw_wait(ah
,
258 AR_EEPROM_STATUS_DATA
,
259 AR_EEPROM_STATUS_DATA_BUSY
|
260 AR_EEPROM_STATUS_DATA_PROT_ACCESS
, 0)) {
264 *data
= MS(REG_READ(ah
, AR_EEPROM_STATUS_DATA
),
265 AR_EEPROM_STATUS_DATA_VAL
);
270 static enum hal_status
ath9k_hw_flash_map(struct ath_hal
*ah
)
272 struct ath_hal_5416
*ahp
= AH5416(ah
);
274 ahp
->ah_cal_mem
= ioremap(AR5416_EEPROM_START_ADDR
, AR5416_EEPROM_MAX
);
276 if (!ahp
->ah_cal_mem
) {
277 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
278 "%s: cannot remap eeprom region \n", __func__
);
285 static bool ath9k_hw_flash_read(struct ath_hal
*ah
, u_int off
,
288 struct ath_hal_5416
*ahp
= AH5416(ah
);
290 *data
= ioread16(ahp
->ah_cal_mem
+ off
);
294 static void ath9k_hw_read_revisions(struct ath_hal
*ah
)
298 val
= REG_READ(ah
, AR_SREV
) & AR_SREV_ID
;
301 val
= REG_READ(ah
, AR_SREV
);
304 (val
& AR_SREV_VERSION2
) >> AR_SREV_TYPE2_S
;
306 ah
->ah_macRev
= MS(val
, AR_SREV_REVISION2
);
307 ah
->ah_isPciExpress
=
308 (val
& AR_SREV_TYPE2_HOST_MODE
) ? 0 : 1;
311 if (!AR_SREV_9100(ah
))
312 ah
->ah_macVersion
= MS(val
, AR_SREV_VERSION
);
314 ah
->ah_macRev
= val
& AR_SREV_REVISION
;
316 if (ah
->ah_macVersion
== AR_SREV_VERSION_5416_PCIE
)
317 ah
->ah_isPciExpress
= true;
321 u_int32_t
ath9k_hw_reverse_bits(u_int32_t val
, u_int32_t n
)
326 for (i
= 0, retval
= 0; i
< n
; i
++) {
327 retval
= (retval
<< 1) | (val
& 1);
333 static void ath9k_hw_set_defaults(struct ath_hal
*ah
)
337 ah
->ah_config
.ath_hal_dma_beacon_response_time
= 2;
338 ah
->ah_config
.ath_hal_sw_beacon_response_time
= 10;
339 ah
->ah_config
.ath_hal_additional_swba_backoff
= 0;
340 ah
->ah_config
.ath_hal_6mb_ack
= 0x0;
341 ah
->ah_config
.ath_hal_cwmIgnoreExtCCA
= 0;
342 ah
->ah_config
.ath_hal_pciePowerSaveEnable
= 0;
343 ah
->ah_config
.ath_hal_pcieL1SKPEnable
= 0;
344 ah
->ah_config
.ath_hal_pcieClockReq
= 0;
345 ah
->ah_config
.ath_hal_pciePowerReset
= 0x100;
346 ah
->ah_config
.ath_hal_pcieRestore
= 0;
347 ah
->ah_config
.ath_hal_pcieWaen
= 0;
348 ah
->ah_config
.ath_hal_analogShiftReg
= 1;
349 ah
->ah_config
.ath_hal_htEnable
= 1;
350 ah
->ah_config
.ath_hal_ofdmTrigLow
= 200;
351 ah
->ah_config
.ath_hal_ofdmTrigHigh
= 500;
352 ah
->ah_config
.ath_hal_cckTrigHigh
= 200;
353 ah
->ah_config
.ath_hal_cckTrigLow
= 100;
354 ah
->ah_config
.ath_hal_enableANI
= 0;
355 ah
->ah_config
.ath_hal_noiseImmunityLvl
= 4;
356 ah
->ah_config
.ath_hal_ofdmWeakSigDet
= 1;
357 ah
->ah_config
.ath_hal_cckWeakSigThr
= 0;
358 ah
->ah_config
.ath_hal_spurImmunityLvl
= 2;
359 ah
->ah_config
.ath_hal_firStepLvl
= 0;
360 ah
->ah_config
.ath_hal_rssiThrHigh
= 40;
361 ah
->ah_config
.ath_hal_rssiThrLow
= 7;
362 ah
->ah_config
.ath_hal_diversityControl
= 0;
363 ah
->ah_config
.ath_hal_antennaSwitchSwap
= 0;
365 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
366 ah
->ah_config
.ath_hal_spurChans
[i
][0] = AR_NO_SPUR
;
367 ah
->ah_config
.ath_hal_spurChans
[i
][1] = AR_NO_SPUR
;
370 ah
->ah_config
.ath_hal_intrMitigation
= 0;
373 static inline void ath9k_hw_override_ini(struct ath_hal
*ah
,
374 struct hal_channel
*chan
)
376 if (!AR_SREV_5416_V20_OR_LATER(ah
)
377 || AR_SREV_9280_10_OR_LATER(ah
))
380 REG_WRITE(ah
, 0x9800 + (651 << 2), 0x11);
383 static inline void ath9k_hw_init_bb(struct ath_hal
*ah
,
384 struct hal_channel
*chan
)
386 u_int32_t synthDelay
;
388 synthDelay
= REG_READ(ah
, AR_PHY_RX_DELAY
) & AR_PHY_RX_DELAY_DELAY
;
389 if (IS_CHAN_CCK(chan
))
390 synthDelay
= (4 * synthDelay
) / 22;
394 REG_WRITE(ah
, AR_PHY_ACTIVE
, AR_PHY_ACTIVE_EN
);
396 udelay(synthDelay
+ BASE_ACTIVATE_DELAY
);
399 static inline void ath9k_hw_init_interrupt_masks(struct ath_hal
*ah
,
400 enum hal_opmode opmode
)
402 struct ath_hal_5416
*ahp
= AH5416(ah
);
404 ahp
->ah_maskReg
= AR_IMR_TXERR
|
410 if (ahp
->ah_intrMitigation
)
411 ahp
->ah_maskReg
|= AR_IMR_RXINTM
| AR_IMR_RXMINTR
;
413 ahp
->ah_maskReg
|= AR_IMR_RXOK
;
415 ahp
->ah_maskReg
|= AR_IMR_TXOK
;
417 if (opmode
== HAL_M_HOSTAP
)
418 ahp
->ah_maskReg
|= AR_IMR_MIB
;
420 REG_WRITE(ah
, AR_IMR
, ahp
->ah_maskReg
);
421 REG_WRITE(ah
, AR_IMR_S2
, REG_READ(ah
, AR_IMR_S2
) | AR_IMR_S2_GTT
);
423 if (!AR_SREV_9100(ah
)) {
424 REG_WRITE(ah
, AR_INTR_SYNC_CAUSE
, 0xFFFFFFFF);
425 REG_WRITE(ah
, AR_INTR_SYNC_ENABLE
, AR_INTR_SYNC_DEFAULT
);
426 REG_WRITE(ah
, AR_INTR_SYNC_MASK
, 0);
430 static inline void ath9k_hw_init_qos(struct ath_hal
*ah
)
432 REG_WRITE(ah
, AR_MIC_QOS_CONTROL
, 0x100aa);
433 REG_WRITE(ah
, AR_MIC_QOS_SELECT
, 0x3210);
435 REG_WRITE(ah
, AR_QOS_NO_ACK
,
436 SM(2, AR_QOS_NO_ACK_TWO_BIT
) |
437 SM(5, AR_QOS_NO_ACK_BIT_OFF
) |
438 SM(0, AR_QOS_NO_ACK_BYTE_OFF
));
440 REG_WRITE(ah
, AR_TXOP_X
, AR_TXOP_X_VAL
);
441 REG_WRITE(ah
, AR_TXOP_0_3
, 0xFFFFFFFF);
442 REG_WRITE(ah
, AR_TXOP_4_7
, 0xFFFFFFFF);
443 REG_WRITE(ah
, AR_TXOP_8_11
, 0xFFFFFFFF);
444 REG_WRITE(ah
, AR_TXOP_12_15
, 0xFFFFFFFF);
447 static void ath9k_hw_analog_shift_rmw(struct ath_hal
*ah
,
455 regVal
= REG_READ(ah
, reg
) & ~mask
;
456 regVal
|= (val
<< shift
) & mask
;
458 REG_WRITE(ah
, reg
, regVal
);
460 if (ah
->ah_config
.ath_hal_analogShiftReg
)
466 static u_int8_t
ath9k_hw_get_num_ant_config(struct ath_hal_5416
*ahp
,
467 enum hal_freq_band freq_band
)
469 struct ar5416_eeprom
*eep
= &ahp
->ah_eeprom
;
470 struct modal_eep_header
*pModal
=
471 &(eep
->modalHeader
[HAL_FREQ_BAND_2GHZ
== freq_band
]);
472 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
473 u_int8_t num_ant_config
;
477 if (pBase
->version
>= 0x0E0D)
481 return num_ant_config
;
484 static enum hal_status
485 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416
*ahp
,
486 struct hal_channel_internal
*chan
,
490 struct ar5416_eeprom
*eep
= &ahp
->ah_eeprom
;
491 struct modal_eep_header
*pModal
=
492 &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
493 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
497 *config
= pModal
->antCtrlCommon
& 0xFFFF;
500 if (pBase
->version
>= 0x0E0D) {
501 if (pModal
->useAnt1
) {
503 ((pModal
->antCtrlCommon
& 0xFFFF0000) >> 16);
515 static inline bool ath9k_hw_nvram_read(struct ath_hal
*ah
,
519 if (ath9k_hw_use_flash(ah
))
520 return ath9k_hw_flash_read(ah
, off
, data
);
522 return ath9k_hw_eeprom_read(ah
, off
, data
);
525 static inline bool ath9k_hw_fill_eeprom(struct ath_hal
*ah
)
527 struct ath_hal_5416
*ahp
= AH5416(ah
);
528 struct ar5416_eeprom
*eep
= &ahp
->ah_eeprom
;
530 int addr
, ar5416_eep_start_loc
= 0;
532 if (!ath9k_hw_use_flash(ah
)) {
533 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
534 "%s: Reading from EEPROM, not flash\n", __func__
);
535 ar5416_eep_start_loc
= 256;
537 if (AR_SREV_9100(ah
))
538 ar5416_eep_start_loc
= 256;
540 eep_data
= (u_int16_t
*) eep
;
542 addr
< sizeof(struct ar5416_eeprom
) / sizeof(u_int16_t
);
544 if (!ath9k_hw_nvram_read(ah
, addr
+ ar5416_eep_start_loc
,
546 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
547 "%s: Unable to read eeprom region \n",
556 /* XXX: Clean me up, make me more legible */
558 ath9k_hw_eeprom_set_board_values(struct ath_hal
*ah
,
559 struct hal_channel_internal
*chan
)
561 struct modal_eep_header
*pModal
;
562 int i
, regChainOffset
;
563 struct ath_hal_5416
*ahp
= AH5416(ah
);
564 struct ar5416_eeprom
*eep
= &ahp
->ah_eeprom
;
565 u_int8_t txRxAttenLocal
;
566 u_int16_t ant_config
;
568 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
570 txRxAttenLocal
= IS_CHAN_2GHZ(chan
) ? 23 : 44;
572 ath9k_hw_get_eeprom_antenna_cfg(ahp
, chan
, 1, &ant_config
);
573 REG_WRITE(ah
, AR_PHY_SWITCH_COM
, ant_config
);
575 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
576 if (AR_SREV_9280(ah
)) {
581 if (AR_SREV_5416_V20_OR_LATER(ah
) &&
582 (ahp
->ah_rxchainmask
== 5 || ahp
->ah_txchainmask
== 5)
584 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
586 regChainOffset
= i
* 0x1000;
588 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
589 pModal
->antCtrlChain
[i
]);
591 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
593 AR_PHY_TIMING_CTRL4(0) +
595 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
596 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
597 SM(pModal
->iqCalICh
[i
],
598 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
599 SM(pModal
->iqCalQCh
[i
],
600 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
602 if ((i
== 0) || AR_SREV_5416_V20_OR_LATER(ah
)) {
603 if ((eep
->baseEepHeader
.version
&
604 AR5416_EEP_VER_MINOR_MASK
) >=
605 AR5416_EEP_MINOR_VER_3
) {
606 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
607 if (AR_SREV_9280_10_OR_LATER(ah
)) {
611 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
617 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
623 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
629 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
639 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN
)
642 AR_PHY_GAIN_2GHZ_BSW_MARGIN
));
649 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN
)
650 | SM(pModal
->bswAtten
[i
],
651 AR_PHY_GAIN_2GHZ_BSW_ATTEN
));
654 if (AR_SREV_9280_10_OR_LATER(ah
)) {
658 AR9280_PHY_RXGAIN_TXRX_ATTEN
,
663 AR9280_PHY_RXGAIN_TXRX_MARGIN
,
664 pModal
->rxTxMarginCh
[i
]);
667 AR_PHY_RXGAIN
+ regChainOffset
,
671 ~AR_PHY_RXGAIN_TXRX_ATTEN
) |
673 AR_PHY_RXGAIN_TXRX_ATTEN
));
680 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN
) |
681 SM(pModal
->rxTxMarginCh
[i
],
682 AR_PHY_GAIN_2GHZ_RXTX_MARGIN
));
687 if (AR_SREV_9280_10_OR_LATER(ah
)) {
688 if (IS_CHAN_2GHZ(chan
)) {
689 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
691 AR_AN_RF2G1_CH0_OB_S
,
693 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
695 AR_AN_RF2G1_CH0_DB_S
,
697 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
699 AR_AN_RF2G1_CH1_OB_S
,
701 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
703 AR_AN_RF2G1_CH1_DB_S
,
706 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
708 AR_AN_RF5G1_CH0_OB5_S
,
710 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
712 AR_AN_RF5G1_CH0_DB5_S
,
714 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
716 AR_AN_RF5G1_CH1_OB5_S
,
718 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
720 AR_AN_RF5G1_CH1_DB5_S
,
723 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
724 AR_AN_TOP2_XPABIAS_LVL
,
725 AR_AN_TOP2_XPABIAS_LVL_S
,
727 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
728 AR_AN_TOP2_LOCALBIAS
,
729 AR_AN_TOP2_LOCALBIAS_S
,
731 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
, "ForceXPAon: %d\n",
732 pModal
->force_xpaon
);
733 REG_RMW_FIELD(ah
, AR_PHY_XPA_CFG
, AR_PHY_FORCE_XPA_CFG
,
734 pModal
->force_xpaon
);
737 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
738 pModal
->switchSettling
);
739 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
740 pModal
->adcDesiredSize
);
742 if (!AR_SREV_9280_10_OR_LATER(ah
))
743 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
744 AR_PHY_DESIRED_SZ_PGA
,
745 pModal
->pgaDesiredSize
);
747 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
748 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
749 | SM(pModal
->txEndToXpaOff
,
750 AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
751 | SM(pModal
->txFrameToXpaOn
,
752 AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
753 | SM(pModal
->txFrameToXpaOn
,
754 AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
756 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
757 pModal
->txEndToRxOn
);
758 if (AR_SREV_9280_10_OR_LATER(ah
)) {
759 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
761 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
762 AR_PHY_EXT_CCA0_THRESH62
,
765 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR_PHY_CCA_THRESH62
,
767 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA
,
768 AR_PHY_EXT_CCA_THRESH62
,
772 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
773 AR5416_EEP_MINOR_VER_2
) {
774 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
775 AR_PHY_TX_END_DATA_START
,
776 pModal
->txFrameToDataStart
);
777 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
778 pModal
->txFrameToPaOn
);
781 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
782 AR5416_EEP_MINOR_VER_3
) {
783 if (IS_CHAN_HT40(chan
))
784 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
785 AR_PHY_SETTLING_SWITCH
,
786 pModal
->swSettleHt40
);
792 static inline enum hal_status
ath9k_hw_check_eeprom(struct ath_hal
*ah
)
794 u_int32_t sum
= 0, el
;
797 struct ath_hal_5416
*ahp
= AH5416(ah
);
798 bool need_swap
= false;
799 struct ar5416_eeprom
*eep
=
800 (struct ar5416_eeprom
*) &ahp
->ah_eeprom
;
802 if (!ath9k_hw_use_flash(ah
)) {
803 u_int16_t magic
, magic2
;
806 if (!ath9k_hw_nvram_read(ah
, AR5416_EEPROM_MAGIC_OFFSET
,
808 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
809 "%s: Reading Magic # failed\n", __func__
);
812 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "%s: Read Magic = 0x%04X\n",
815 if (magic
!= AR5416_EEPROM_MAGIC
) {
816 magic2
= swab16(magic
);
818 if (magic2
== AR5416_EEPROM_MAGIC
) {
820 eepdata
= (u_int16_t
*) (&ahp
->ah_eeprom
);
824 sizeof(struct ar5416_eeprom
) /
825 sizeof(u_int16_t
); addr
++) {
828 temp
= swab16(*eepdata
);
832 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
833 "0x%04X ", *eepdata
);
834 if (((addr
+ 1) % 6) == 0)
840 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
841 "Invalid EEPROM Magic. "
842 "endianness missmatch.\n");
847 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
848 need_swap
? "True" : "False");
851 el
= swab16(ahp
->ah_eeprom
.baseEepHeader
.length
);
853 el
= ahp
->ah_eeprom
.baseEepHeader
.length
;
855 if (el
> sizeof(struct ar5416_eeprom
))
856 el
= sizeof(struct ar5416_eeprom
) / sizeof(u_int16_t
);
858 el
= el
/ sizeof(u_int16_t
);
860 eepdata
= (u_int16_t
*) (&ahp
->ah_eeprom
);
862 for (i
= 0; i
< el
; i
++)
866 u_int32_t integer
, j
;
869 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
870 "EEPROM Endianness is not native.. Changing \n");
872 word
= swab16(eep
->baseEepHeader
.length
);
873 eep
->baseEepHeader
.length
= word
;
875 word
= swab16(eep
->baseEepHeader
.checksum
);
876 eep
->baseEepHeader
.checksum
= word
;
878 word
= swab16(eep
->baseEepHeader
.version
);
879 eep
->baseEepHeader
.version
= word
;
881 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
882 eep
->baseEepHeader
.regDmn
[0] = word
;
884 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
885 eep
->baseEepHeader
.regDmn
[1] = word
;
887 word
= swab16(eep
->baseEepHeader
.rfSilent
);
888 eep
->baseEepHeader
.rfSilent
= word
;
890 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
891 eep
->baseEepHeader
.blueToothOptions
= word
;
893 word
= swab16(eep
->baseEepHeader
.deviceCap
);
894 eep
->baseEepHeader
.deviceCap
= word
;
896 for (j
= 0; j
< ARRAY_SIZE(eep
->modalHeader
); j
++) {
897 struct modal_eep_header
*pModal
=
898 &eep
->modalHeader
[j
];
899 integer
= swab32(pModal
->antCtrlCommon
);
900 pModal
->antCtrlCommon
= integer
;
902 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
903 integer
= swab32(pModal
->antCtrlChain
[i
]);
904 pModal
->antCtrlChain
[i
] = integer
;
907 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
908 word
= swab16(pModal
->spurChans
[i
].spurChan
);
909 pModal
->spurChans
[i
].spurChan
= word
;
914 if (sum
!= 0xffff || ar5416_get_eep_ver(ahp
) != AR5416_EEP_VER
||
915 ar5416_get_eep_rev(ahp
) < AR5416_EEP_NO_BACK_VER
) {
916 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
917 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
918 sum
, ar5416_get_eep_ver(ahp
));
925 static bool ath9k_hw_chip_test(struct ath_hal
*ah
)
927 u_int32_t regAddr
[2] = { AR_STA_ID0
, AR_PHY_BASE
+ (8 << 2) };
928 u_int32_t regHold
[2];
929 u_int32_t patternData
[4] = { 0x55555555,
935 for (i
= 0; i
< 2; i
++) {
936 u_int32_t addr
= regAddr
[i
];
937 u_int32_t wrData
, rdData
;
939 regHold
[i
] = REG_READ(ah
, addr
);
940 for (j
= 0; j
< 0x100; j
++) {
941 wrData
= (j
<< 16) | j
;
942 REG_WRITE(ah
, addr
, wrData
);
943 rdData
= REG_READ(ah
, addr
);
944 if (rdData
!= wrData
) {
945 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
946 "%s: address test failed "
947 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
948 __func__
, addr
, wrData
, rdData
);
952 for (j
= 0; j
< 4; j
++) {
953 wrData
= patternData
[j
];
954 REG_WRITE(ah
, addr
, wrData
);
955 rdData
= REG_READ(ah
, addr
);
956 if (wrData
!= rdData
) {
957 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
958 "%s: address test failed "
959 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
960 __func__
, addr
, wrData
, rdData
);
964 REG_WRITE(ah
, regAddr
[i
], regHold
[i
]);
970 u_int32_t
ath9k_hw_getrxfilter(struct ath_hal
*ah
)
972 u_int32_t bits
= REG_READ(ah
, AR_RX_FILTER
);
973 u_int32_t phybits
= REG_READ(ah
, AR_PHY_ERR
);
975 if (phybits
& AR_PHY_ERR_RADAR
)
976 bits
|= HAL_RX_FILTER_PHYRADAR
;
977 if (phybits
& (AR_PHY_ERR_OFDM_TIMING
| AR_PHY_ERR_CCK_TIMING
))
978 bits
|= HAL_RX_FILTER_PHYERR
;
982 void ath9k_hw_setrxfilter(struct ath_hal
*ah
, u_int32_t bits
)
986 REG_WRITE(ah
, AR_RX_FILTER
, (bits
& 0xffff) | AR_RX_COMPR_BAR
);
988 if (bits
& HAL_RX_FILTER_PHYRADAR
)
989 phybits
|= AR_PHY_ERR_RADAR
;
990 if (bits
& HAL_RX_FILTER_PHYERR
)
991 phybits
|= AR_PHY_ERR_OFDM_TIMING
| AR_PHY_ERR_CCK_TIMING
;
992 REG_WRITE(ah
, AR_PHY_ERR
, phybits
);
995 REG_WRITE(ah
, AR_RXCFG
,
996 REG_READ(ah
, AR_RXCFG
) | AR_RXCFG_ZLFDMA
);
998 REG_WRITE(ah
, AR_RXCFG
,
999 REG_READ(ah
, AR_RXCFG
) & ~AR_RXCFG_ZLFDMA
);
1002 bool ath9k_hw_setcapability(struct ath_hal
*ah
,
1003 enum hal_capability_type type
,
1004 u_int32_t capability
,
1006 enum hal_status
*status
)
1008 struct ath_hal_5416
*ahp
= AH5416(ah
);
1012 case HAL_CAP_TKIP_MIC
:
1014 ahp
->ah_staId1Defaults
|=
1015 AR_STA_ID1_CRPT_MIC_ENABLE
;
1017 ahp
->ah_staId1Defaults
&=
1018 ~AR_STA_ID1_CRPT_MIC_ENABLE
;
1020 case HAL_CAP_DIVERSITY
:
1021 v
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
1023 v
|= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
;
1025 v
&= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
;
1026 REG_WRITE(ah
, AR_PHY_CCK_DETECT
, v
);
1028 case HAL_CAP_MCAST_KEYSRCH
:
1030 ahp
->ah_staId1Defaults
|= AR_STA_ID1_MCAST_KSRCH
;
1032 ahp
->ah_staId1Defaults
&= ~AR_STA_ID1_MCAST_KSRCH
;
1034 case HAL_CAP_TSF_ADJUST
:
1036 ahp
->ah_miscMode
|= AR_PCU_TX_ADD_TSF
;
1038 ahp
->ah_miscMode
&= ~AR_PCU_TX_ADD_TSF
;
1045 void ath9k_hw_dmaRegDump(struct ath_hal
*ah
)
1047 u_int32_t val
[ATH9K_NUM_DMA_DEBUG_REGS
];
1048 int qcuOffset
= 0, dcuOffset
= 0;
1049 u_int32_t
*qcuBase
= &val
[0], *dcuBase
= &val
[4];
1052 REG_WRITE(ah
, AR_MACMISC
,
1053 ((AR_MACMISC_DMA_OBS_LINE_8
<< AR_MACMISC_DMA_OBS_S
) |
1054 (AR_MACMISC_MISC_OBS_BUS_1
<<
1055 AR_MACMISC_MISC_OBS_BUS_MSB_S
)));
1057 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
, "Raw DMA Debug values:\n");
1058 for (i
= 0; i
< ATH9K_NUM_DMA_DEBUG_REGS
; i
++) {
1060 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
, "\n");
1062 val
[i
] = REG_READ(ah
, AR_DMADBG_0
+ (i
* sizeof(u_int32_t
)));
1063 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
, "%d: %08x ", i
, val
[i
]);
1066 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
, "\n\n");
1067 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1068 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1070 for (i
= 0; i
< ATH9K_NUM_QUEUES
;
1071 i
++, qcuOffset
+= 4, dcuOffset
+= 5) {
1082 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1083 "%2d %2x %1x %2x %2x\n",
1084 i
, (*qcuBase
& (0x7 << qcuOffset
)) >> qcuOffset
,
1085 (*qcuBase
& (0x8 << qcuOffset
)) >> (qcuOffset
+
1087 val
[2] & (0x7 << (i
* 3)) >> (i
* 3),
1088 (*dcuBase
& (0x1f << dcuOffset
)) >> dcuOffset
);
1091 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
, "\n");
1092 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1093 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
1094 (val
[3] & 0x003c0000) >> 18, (val
[3] & 0x03c00000) >> 22);
1095 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1096 "qcu_complete state: %2x dcu_complete state: %2x\n",
1097 (val
[3] & 0x1c000000) >> 26, (val
[6] & 0x3));
1098 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1099 "dcu_arb state: %2x dcu_fp state: %2x\n",
1100 (val
[5] & 0x06000000) >> 25, (val
[5] & 0x38000000) >> 27);
1101 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1102 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
1103 (val
[6] & 0x000003fc) >> 2, (val
[6] & 0x00000400) >> 10);
1104 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1105 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
1106 (val
[6] & 0x00000800) >> 11, (val
[6] & 0x00001000) >> 12);
1107 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1108 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
1109 (val
[6] & 0x0001e000) >> 13, (val
[6] & 0x001e0000) >> 17);
1111 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
, "pcu observe 0x%x \n",
1112 REG_READ(ah
, AR_OBS_BUS_1
));
1113 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1114 "AR_CR 0x%x \n", REG_READ(ah
, AR_CR
));
1117 u_int32_t
ath9k_hw_GetMibCycleCountsPct(struct ath_hal
*ah
,
1118 u_int32_t
*rxc_pcnt
,
1119 u_int32_t
*rxf_pcnt
,
1120 u_int32_t
*txf_pcnt
)
1122 static u_int32_t cycles
, rx_clear
, rx_frame
, tx_frame
;
1125 u_int32_t rc
= REG_READ(ah
, AR_RCCNT
);
1126 u_int32_t rf
= REG_READ(ah
, AR_RFCNT
);
1127 u_int32_t tf
= REG_READ(ah
, AR_TFCNT
);
1128 u_int32_t cc
= REG_READ(ah
, AR_CCCNT
);
1130 if (cycles
== 0 || cycles
> cc
) {
1131 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
1132 "%s: cycle counter wrap. ExtBusy = 0\n",
1136 u_int32_t cc_d
= cc
- cycles
;
1137 u_int32_t rc_d
= rc
- rx_clear
;
1138 u_int32_t rf_d
= rf
- rx_frame
;
1139 u_int32_t tf_d
= tf
- tx_frame
;
1142 *rxc_pcnt
= rc_d
* 100 / cc_d
;
1143 *rxf_pcnt
= rf_d
* 100 / cc_d
;
1144 *txf_pcnt
= tf_d
* 100 / cc_d
;
1158 void ath9k_hw_set11nmac2040(struct ath_hal
*ah
, enum hal_ht_macmode mode
)
1162 if (mode
== HAL_HT_MACMODE_2040
&&
1163 !ah
->ah_config
.ath_hal_cwmIgnoreExtCCA
)
1164 macmode
= AR_2040_JOINED_RX_CLEAR
;
1168 REG_WRITE(ah
, AR_2040_MODE
, macmode
);
1171 static void ath9k_hw_mark_phy_inactive(struct ath_hal
*ah
)
1173 REG_WRITE(ah
, AR_PHY_ACTIVE
, AR_PHY_ACTIVE_DIS
);
1177 static struct ath_hal_5416
*ath9k_hw_newstate(u_int16_t devid
,
1178 struct ath_softc
*sc
,
1180 enum hal_status
*status
)
1182 static const u_int8_t defbssidmask
[ETH_ALEN
] =
1183 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1184 struct ath_hal_5416
*ahp
;
1187 ahp
= kzalloc(sizeof(struct ath_hal_5416
), GFP_KERNEL
);
1189 DPRINTF(sc
, ATH_DBG_FATAL
,
1190 "%s: cannot allocate memory for state block\n",
1192 *status
= HAL_ENOMEM
;
1198 memcpy(&ahp
->ah
, &ar5416hal
, sizeof(struct ath_hal
));
1203 ah
->ah_devid
= devid
;
1204 ah
->ah_subvendorid
= 0;
1207 if ((devid
== AR5416_AR9100_DEVID
))
1208 ah
->ah_macVersion
= AR_SREV_VERSION_9100
;
1209 if (!AR_SREV_9100(ah
))
1210 ah
->ah_flags
= AH_USE_EEPROM
;
1212 ah
->ah_powerLimit
= MAX_RATE_POWER
;
1213 ah
->ah_tpScale
= HAL_TP_SCALE_MAX
;
1215 ahp
->ah_atimWindow
= 0;
1216 ahp
->ah_diversityControl
= ah
->ah_config
.ath_hal_diversityControl
;
1217 ahp
->ah_antennaSwitchSwap
=
1218 ah
->ah_config
.ath_hal_antennaSwitchSwap
;
1220 ahp
->ah_staId1Defaults
= AR_STA_ID1_CRPT_MIC_ENABLE
;
1221 ahp
->ah_beaconInterval
= 100;
1222 ahp
->ah_enable32kHzClock
= DONT_USE_32KHZ
;
1223 ahp
->ah_slottime
= (u_int
) -1;
1224 ahp
->ah_acktimeout
= (u_int
) -1;
1225 ahp
->ah_ctstimeout
= (u_int
) -1;
1226 ahp
->ah_globaltxtimeout
= (u_int
) -1;
1227 memcpy(&ahp
->ah_bssidmask
, defbssidmask
, ETH_ALEN
);
1229 ahp
->ah_gBeaconRate
= 0;
1234 static enum hal_status
ath9k_hw_eeprom_attach(struct ath_hal
*ah
)
1236 enum hal_status status
;
1238 if (ath9k_hw_use_flash(ah
))
1239 ath9k_hw_flash_map(ah
);
1241 if (!ath9k_hw_fill_eeprom(ah
))
1244 status
= ath9k_hw_check_eeprom(ah
);
1249 u_int32_t
ath9k_hw_get_eeprom(struct ath_hal_5416
*ahp
,
1250 enum eeprom_param param
)
1252 struct ar5416_eeprom
*eep
= &ahp
->ah_eeprom
;
1253 struct modal_eep_header
*pModal
= eep
->modalHeader
;
1254 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
1257 case EEP_NFTHRESH_5
:
1258 return -pModal
[0].noiseFloorThreshCh
[0];
1259 case EEP_NFTHRESH_2
:
1260 return -pModal
[1].noiseFloorThreshCh
[0];
1261 case AR_EEPROM_MAC(0):
1262 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
1263 case AR_EEPROM_MAC(1):
1264 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
1265 case AR_EEPROM_MAC(2):
1266 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
1268 return pBase
->regDmn
[0];
1270 return pBase
->regDmn
[1];
1272 return pBase
->deviceCap
;
1274 return pBase
->opCapFlags
;
1276 return pBase
->rfSilent
;
1278 return pModal
[0].ob
;
1280 return pModal
[0].db
;
1282 return pModal
[1].ob
;
1284 return pModal
[1].db
;
1286 return pBase
->version
& AR5416_EEP_VER_MINOR_MASK
;
1288 return pBase
->txMask
;
1290 return pBase
->rxMask
;
1296 static inline int ath9k_hw_get_radiorev(struct ath_hal
*ah
)
1301 REG_WRITE(ah
, AR_PHY(0x36), 0x00007058);
1302 for (i
= 0; i
< 8; i
++)
1303 REG_WRITE(ah
, AR_PHY(0x20), 0x00010000);
1304 val
= (REG_READ(ah
, AR_PHY(256)) >> 24) & 0xff;
1305 val
= ((val
& 0xf0) >> 4) | ((val
& 0x0f) << 4);
1306 return ath9k_hw_reverse_bits(val
, 8);
1309 static inline enum hal_status
ath9k_hw_init_macaddr(struct ath_hal
*ah
)
1314 struct ath_hal_5416
*ahp
= AH5416(ah
);
1315 DECLARE_MAC_BUF(mac
);
1318 for (i
= 0; i
< 3; i
++) {
1319 eeval
= ath9k_hw_get_eeprom(ahp
, AR_EEPROM_MAC(i
));
1321 ahp
->ah_macaddr
[2 * i
] = eeval
>> 8;
1322 ahp
->ah_macaddr
[2 * i
+ 1] = eeval
& 0xff;
1324 if (sum
== 0 || sum
== 0xffff * 3) {
1325 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1326 "%s: mac address read failed: %s\n", __func__
,
1327 print_mac(mac
, ahp
->ah_macaddr
));
1328 return HAL_EEBADMAC
;
1334 static inline int16_t ath9k_hw_interpolate(u_int16_t target
,
1338 int16_t targetRight
)
1342 if (srcRight
== srcLeft
) {
1345 rv
= (int16_t) (((target
- srcLeft
) * targetRight
+
1346 (srcRight
- target
) * targetLeft
) /
1347 (srcRight
- srcLeft
));
1352 static inline u_int16_t
ath9k_hw_fbin2freq(u_int8_t fbin
,
1356 if (fbin
== AR5416_BCHAN_UNUSED
)
1359 return (u_int16_t
) ((is2GHz
) ? (2300 + fbin
) : (4800 + 5 * fbin
));
1362 static u_int16_t
ath9k_hw_eeprom_get_spur_chan(struct ath_hal
*ah
,
1366 struct ath_hal_5416
*ahp
= AH5416(ah
);
1367 struct ar5416_eeprom
*eep
=
1368 (struct ar5416_eeprom
*) &ahp
->ah_eeprom
;
1369 u_int16_t spur_val
= AR_NO_SPUR
;
1371 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1372 "Getting spur idx %d is2Ghz. %d val %x\n",
1373 i
, is2GHz
, ah
->ah_config
.ath_hal_spurChans
[i
][is2GHz
]);
1375 switch (ah
->ah_config
.ath_hal_spurMode
) {
1378 case SPUR_ENABLE_IOCTL
:
1379 spur_val
= ah
->ah_config
.ath_hal_spurChans
[i
][is2GHz
];
1380 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1381 "Getting spur val from new loc. %d\n", spur_val
);
1383 case SPUR_ENABLE_EEPROM
:
1384 spur_val
= eep
->modalHeader
[is2GHz
].spurChans
[i
].spurChan
;
1391 static inline enum hal_status
ath9k_hw_rfattach(struct ath_hal
*ah
)
1393 bool rfStatus
= false;
1394 enum hal_status ecode
= HAL_OK
;
1396 rfStatus
= ath9k_hw_init_rf(ah
, &ecode
);
1398 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
1399 "%s: RF setup failed, status %u\n", __func__
,
1407 static enum hal_status
ath9k_hw_rf_claim(struct ath_hal
*ah
)
1411 REG_WRITE(ah
, AR_PHY(0), 0x00000007);
1413 val
= ath9k_hw_get_radiorev(ah
);
1414 switch (val
& AR_RADIO_SREV_MAJOR
) {
1416 val
= AR_RAD5133_SREV_MAJOR
;
1418 case AR_RAD5133_SREV_MAJOR
:
1419 case AR_RAD5122_SREV_MAJOR
:
1420 case AR_RAD2133_SREV_MAJOR
:
1421 case AR_RAD2122_SREV_MAJOR
:
1424 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
1425 "%s: 5G Radio Chip Rev 0x%02X is not "
1426 "supported by this driver\n",
1427 __func__
, ah
->ah_analog5GhzRev
);
1428 return HAL_ENOTSUPP
;
1431 ah
->ah_analog5GhzRev
= val
;
1436 static inline void ath9k_hw_init_pll(struct ath_hal
*ah
,
1437 struct hal_channel
*chan
)
1441 if (AR_SREV_9100(ah
)) {
1442 if (chan
&& IS_CHAN_5GHZ(chan
))
1447 if (AR_SREV_9280_10_OR_LATER(ah
)) {
1448 pll
= SM(0x5, AR_RTC_9160_PLL_REFDIV
);
1450 if (chan
&& IS_CHAN_HALF_RATE(chan
))
1451 pll
|= SM(0x1, AR_RTC_9160_PLL_CLKSEL
);
1452 else if (chan
&& IS_CHAN_QUARTER_RATE(chan
))
1453 pll
|= SM(0x2, AR_RTC_9160_PLL_CLKSEL
);
1455 if (chan
&& IS_CHAN_5GHZ(chan
)) {
1456 pll
|= SM(0x28, AR_RTC_9160_PLL_DIV
);
1459 if (AR_SREV_9280_20(ah
)) {
1460 if (((chan
->channel
% 20) == 0)
1461 || ((chan
->channel
% 10) == 0))
1467 pll
|= SM(0x2c, AR_RTC_9160_PLL_DIV
);
1470 } else if (AR_SREV_9160_10_OR_LATER(ah
)) {
1472 pll
= SM(0x5, AR_RTC_9160_PLL_REFDIV
);
1474 if (chan
&& IS_CHAN_HALF_RATE(chan
))
1475 pll
|= SM(0x1, AR_RTC_9160_PLL_CLKSEL
);
1476 else if (chan
&& IS_CHAN_QUARTER_RATE(chan
))
1477 pll
|= SM(0x2, AR_RTC_9160_PLL_CLKSEL
);
1479 if (chan
&& IS_CHAN_5GHZ(chan
))
1480 pll
|= SM(0x50, AR_RTC_9160_PLL_DIV
);
1482 pll
|= SM(0x58, AR_RTC_9160_PLL_DIV
);
1484 pll
= AR_RTC_PLL_REFDIV_5
| AR_RTC_PLL_DIV2
;
1486 if (chan
&& IS_CHAN_HALF_RATE(chan
))
1487 pll
|= SM(0x1, AR_RTC_PLL_CLKSEL
);
1488 else if (chan
&& IS_CHAN_QUARTER_RATE(chan
))
1489 pll
|= SM(0x2, AR_RTC_PLL_CLKSEL
);
1491 if (chan
&& IS_CHAN_5GHZ(chan
))
1492 pll
|= SM(0xa, AR_RTC_PLL_DIV
);
1494 pll
|= SM(0xb, AR_RTC_PLL_DIV
);
1497 REG_WRITE(ah
, (u_int16_t
) (AR_RTC_PLL_CONTROL
), pll
);
1499 udelay(RTC_PLL_SETTLE_DELAY
);
1501 REG_WRITE(ah
, AR_RTC_SLEEP_CLK
, AR_RTC_FORCE_DERIVED_CLK
);
1504 static void ath9k_hw_set_regs(struct ath_hal
*ah
, struct hal_channel
*chan
,
1505 enum hal_ht_macmode macmode
)
1508 struct ath_hal_5416
*ahp
= AH5416(ah
);
1510 phymode
= AR_PHY_FC_HT_EN
| AR_PHY_FC_SHORT_GI_40
1511 | AR_PHY_FC_SINGLE_HT_LTF1
| AR_PHY_FC_WALSH
;
1513 if (IS_CHAN_HT40(chan
)) {
1514 phymode
|= AR_PHY_FC_DYN2040_EN
;
1516 if (chan
->channelFlags
& CHANNEL_HT40PLUS
)
1517 phymode
|= AR_PHY_FC_DYN2040_PRI_CH
;
1519 if (ahp
->ah_extprotspacing
== HAL_HT_EXTPROTSPACING_25
)
1520 phymode
|= AR_PHY_FC_DYN2040_EXT_CH
;
1522 REG_WRITE(ah
, AR_PHY_TURBO
, phymode
);
1524 ath9k_hw_set11nmac2040(ah
, macmode
);
1526 REG_WRITE(ah
, AR_GTXTO
, 25 << AR_GTXTO_TIMEOUT_LIMIT_S
);
1527 REG_WRITE(ah
, AR_CST
, 0xF << AR_CST_TIMEOUT_LIMIT_S
);
1530 static void ath9k_hw_set_operating_mode(struct ath_hal
*ah
, int opmode
)
1534 val
= REG_READ(ah
, AR_STA_ID1
);
1535 val
&= ~(AR_STA_ID1_STA_AP
| AR_STA_ID1_ADHOC
);
1538 REG_WRITE(ah
, AR_STA_ID1
, val
| AR_STA_ID1_STA_AP
1539 | AR_STA_ID1_KSRCH_MODE
);
1540 REG_CLR_BIT(ah
, AR_CFG
, AR_CFG_AP_ADHOC_INDICATION
);
1543 REG_WRITE(ah
, AR_STA_ID1
, val
| AR_STA_ID1_ADHOC
1544 | AR_STA_ID1_KSRCH_MODE
);
1545 REG_SET_BIT(ah
, AR_CFG
, AR_CFG_AP_ADHOC_INDICATION
);
1549 REG_WRITE(ah
, AR_STA_ID1
, val
| AR_STA_ID1_KSRCH_MODE
);
1555 ath9k_hw_set_rfmode(struct ath_hal
*ah
, struct hal_channel
*chan
)
1557 u_int32_t rfMode
= 0;
1562 rfMode
|= (IS_CHAN_B(chan
) || IS_CHAN_G(chan
))
1563 ? AR_PHY_MODE_DYNAMIC
: AR_PHY_MODE_OFDM
;
1565 if (!AR_SREV_9280_10_OR_LATER(ah
))
1566 rfMode
|= (IS_CHAN_5GHZ(chan
)) ? AR_PHY_MODE_RF5GHZ
:
1569 if (AR_SREV_9280_20(ah
) && IS_CHAN_A_5MHZ_SPACED(chan
))
1570 rfMode
|= (AR_PHY_MODE_DYNAMIC
| AR_PHY_MODE_DYN_CCK_DISABLE
);
1572 REG_WRITE(ah
, AR_PHY_MODE
, rfMode
);
1575 static bool ath9k_hw_set_reset(struct ath_hal
*ah
, int type
)
1577 u_int32_t rst_flags
;
1580 REG_WRITE(ah
, AR_RTC_FORCE_WAKE
, AR_RTC_FORCE_WAKE_EN
|
1581 AR_RTC_FORCE_WAKE_ON_INT
);
1583 if (AR_SREV_9100(ah
)) {
1584 rst_flags
= AR_RTC_RC_MAC_WARM
| AR_RTC_RC_MAC_COLD
|
1585 AR_RTC_RC_COLD_RESET
| AR_RTC_RC_WARM_RESET
;
1587 tmpReg
= REG_READ(ah
, AR_INTR_SYNC_CAUSE
);
1589 (AR_INTR_SYNC_LOCAL_TIMEOUT
|
1590 AR_INTR_SYNC_RADM_CPL_TIMEOUT
)) {
1591 REG_WRITE(ah
, AR_INTR_SYNC_ENABLE
, 0);
1592 REG_WRITE(ah
, AR_RC
, AR_RC_AHB
| AR_RC_HOSTIF
);
1594 REG_WRITE(ah
, AR_RC
, AR_RC_AHB
);
1597 rst_flags
= AR_RTC_RC_MAC_WARM
;
1598 if (type
== HAL_RESET_COLD
)
1599 rst_flags
|= AR_RTC_RC_MAC_COLD
;
1602 REG_WRITE(ah
, (u_int16_t
) (AR_RTC_RC
), rst_flags
);
1605 REG_WRITE(ah
, (u_int16_t
) (AR_RTC_RC
), 0);
1606 if (!ath9k_hw_wait(ah
, (u_int16_t
) (AR_RTC_RC
), AR_RTC_RC_M
, 0)) {
1607 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
1608 "%s: RTC stuck in MAC reset\n",
1613 if (!AR_SREV_9100(ah
))
1614 REG_WRITE(ah
, AR_RC
, 0);
1616 ath9k_hw_init_pll(ah
, NULL
);
1618 if (AR_SREV_9100(ah
))
1624 static inline bool ath9k_hw_set_reset_power_on(struct ath_hal
*ah
)
1626 REG_WRITE(ah
, AR_RTC_FORCE_WAKE
, AR_RTC_FORCE_WAKE_EN
|
1627 AR_RTC_FORCE_WAKE_ON_INT
);
1629 REG_WRITE(ah
, (u_int16_t
) (AR_RTC_RESET
), 0);
1630 REG_WRITE(ah
, (u_int16_t
) (AR_RTC_RESET
), 1);
1632 if (!ath9k_hw_wait(ah
,
1635 AR_RTC_STATUS_ON
)) {
1636 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: RTC not waking up\n",
1641 ath9k_hw_read_revisions(ah
);
1643 return ath9k_hw_set_reset(ah
, HAL_RESET_WARM
);
1646 static bool ath9k_hw_set_reset_reg(struct ath_hal
*ah
,
1649 REG_WRITE(ah
, AR_RTC_FORCE_WAKE
,
1650 AR_RTC_FORCE_WAKE_EN
| AR_RTC_FORCE_WAKE_ON_INT
);
1653 case HAL_RESET_POWER_ON
:
1654 return ath9k_hw_set_reset_power_on(ah
);
1656 case HAL_RESET_WARM
:
1657 case HAL_RESET_COLD
:
1658 return ath9k_hw_set_reset(ah
, type
);
1665 static inline struct hal_channel_internal
*ath9k_hw_check_chan(
1666 struct ath_hal
*ah
, struct hal_channel
*chan
)
1668 if ((IS(chan
, CHANNEL_2GHZ
) ^ IS(chan
, CHANNEL_5GHZ
)) == 0) {
1669 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
1670 "%s: invalid channel %u/0x%x; not marked as "
1671 "2GHz or 5GHz\n", __func__
, chan
->channel
,
1672 chan
->channelFlags
);
1676 if ((IS(chan
, CHANNEL_OFDM
)
1677 ^ IS(chan
, CHANNEL_CCK
)
1678 ^ IS(chan
, CHANNEL_HT20
)
1679 ^ IS(chan
, CHANNEL_HT40PLUS
)
1680 ^ IS(chan
, CHANNEL_HT40MINUS
)) == 0) {
1681 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
1682 "%s: invalid channel %u/0x%x; not marked as "
1683 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1684 __func__
, chan
->channel
, chan
->channelFlags
);
1688 return ath9k_regd_check_channel(ah
, chan
);
1692 ath9k_hw_get_lower_upper_index(u_int8_t target
,
1700 if (target
<= pList
[0]) {
1701 *indexL
= *indexR
= 0;
1704 if (target
>= pList
[listSize
- 1]) {
1705 *indexL
= *indexR
= (u_int16_t
) (listSize
- 1);
1709 for (i
= 0; i
< listSize
- 1; i
++) {
1710 if (pList
[i
] == target
) {
1711 *indexL
= *indexR
= i
;
1714 if (target
< pList
[i
+ 1]) {
1716 *indexR
= (u_int16_t
) (i
+ 1);
1723 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer
)
1726 int16_t sort
[HAL_NF_CAL_HIST_MAX
];
1729 for (i
= 0; i
< HAL_NF_CAL_HIST_MAX
; i
++)
1730 sort
[i
] = nfCalBuffer
[i
];
1732 for (i
= 0; i
< HAL_NF_CAL_HIST_MAX
- 1; i
++) {
1733 for (j
= 1; j
< HAL_NF_CAL_HIST_MAX
- i
; j
++) {
1734 if (sort
[j
] > sort
[j
- 1]) {
1736 sort
[j
] = sort
[j
- 1];
1737 sort
[j
- 1] = nfval
;
1741 nfval
= sort
[(HAL_NF_CAL_HIST_MAX
- 1) >> 1];
1746 static void ath9k_hw_update_nfcal_hist_buffer(struct hal_nfcal_hist
*h
,
1751 for (i
= 0; i
< NUM_NF_READINGS
; i
++) {
1752 h
[i
].nfCalBuffer
[h
[i
].currIndex
] = nfarray
[i
];
1754 if (++h
[i
].currIndex
>= HAL_NF_CAL_HIST_MAX
)
1757 if (h
[i
].invalidNFcount
> 0) {
1758 if (nfarray
[i
] < AR_PHY_CCA_MIN_BAD_VALUE
1759 || nfarray
[i
] > AR_PHY_CCA_MAX_HIGH_VALUE
) {
1760 h
[i
].invalidNFcount
= HAL_NF_CAL_HIST_MAX
;
1762 h
[i
].invalidNFcount
--;
1763 h
[i
].privNF
= nfarray
[i
];
1767 ath9k_hw_get_nf_hist_mid(h
[i
].nfCalBuffer
);
1773 static void ar5416GetNoiseFloor(struct ath_hal
*ah
,
1774 int16_t nfarray
[NUM_NF_READINGS
])
1778 if (AR_SREV_9280_10_OR_LATER(ah
))
1779 nf
= MS(REG_READ(ah
, AR_PHY_CCA
), AR9280_PHY_MINCCA_PWR
);
1781 nf
= MS(REG_READ(ah
, AR_PHY_CCA
), AR_PHY_MINCCA_PWR
);
1784 nf
= 0 - ((nf
^ 0x1ff) + 1);
1785 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
1786 "NF calibrated [ctl] [chain 0] is %d\n", nf
);
1789 if (AR_SREV_9280_10_OR_LATER(ah
))
1790 nf
= MS(REG_READ(ah
, AR_PHY_CH1_CCA
),
1791 AR9280_PHY_CH1_MINCCA_PWR
);
1793 nf
= MS(REG_READ(ah
, AR_PHY_CH1_CCA
),
1794 AR_PHY_CH1_MINCCA_PWR
);
1797 nf
= 0 - ((nf
^ 0x1ff) + 1);
1798 DPRINTF(ah
->ah_sc
, ATH_DBG_NF_CAL
,
1799 "NF calibrated [ctl] [chain 1] is %d\n", nf
);
1802 if (!AR_SREV_9280(ah
)) {
1803 nf
= MS(REG_READ(ah
, AR_PHY_CH2_CCA
),
1804 AR_PHY_CH2_MINCCA_PWR
);
1806 nf
= 0 - ((nf
^ 0x1ff) + 1);
1807 DPRINTF(ah
->ah_sc
, ATH_DBG_NF_CAL
,
1808 "NF calibrated [ctl] [chain 2] is %d\n", nf
);
1812 if (AR_SREV_9280_10_OR_LATER(ah
))
1813 nf
= MS(REG_READ(ah
, AR_PHY_EXT_CCA
),
1814 AR9280_PHY_EXT_MINCCA_PWR
);
1816 nf
= MS(REG_READ(ah
, AR_PHY_EXT_CCA
),
1817 AR_PHY_EXT_MINCCA_PWR
);
1820 nf
= 0 - ((nf
^ 0x1ff) + 1);
1821 DPRINTF(ah
->ah_sc
, ATH_DBG_NF_CAL
,
1822 "NF calibrated [ext] [chain 0] is %d\n", nf
);
1825 if (AR_SREV_9280_10_OR_LATER(ah
))
1826 nf
= MS(REG_READ(ah
, AR_PHY_CH1_EXT_CCA
),
1827 AR9280_PHY_CH1_EXT_MINCCA_PWR
);
1829 nf
= MS(REG_READ(ah
, AR_PHY_CH1_EXT_CCA
),
1830 AR_PHY_CH1_EXT_MINCCA_PWR
);
1833 nf
= 0 - ((nf
^ 0x1ff) + 1);
1834 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
1835 "NF calibrated [ext] [chain 1] is %d\n", nf
);
1838 if (!AR_SREV_9280(ah
)) {
1839 nf
= MS(REG_READ(ah
, AR_PHY_CH2_EXT_CCA
),
1840 AR_PHY_CH2_EXT_MINCCA_PWR
);
1842 nf
= 0 - ((nf
^ 0x1ff) + 1);
1843 DPRINTF(ah
->ah_sc
, ATH_DBG_NF_CAL
,
1844 "NF calibrated [ext] [chain 2] is %d\n", nf
);
1850 getNoiseFloorThresh(struct ath_hal
*ah
,
1851 const struct hal_channel_internal
*chan
,
1854 struct ath_hal_5416
*ahp
= AH5416(ah
);
1856 switch (chan
->channelFlags
& CHANNEL_ALL
) {
1858 case CHANNEL_A_HT20
:
1859 case CHANNEL_A_HT40PLUS
:
1860 case CHANNEL_A_HT40MINUS
:
1861 *nft
= (int16_t) ath9k_hw_get_eeprom(ahp
, EEP_NFTHRESH_5
);
1865 case CHANNEL_G_HT20
:
1866 case CHANNEL_G_HT40PLUS
:
1867 case CHANNEL_G_HT40MINUS
:
1868 *nft
= (int16_t) ath9k_hw_get_eeprom(ahp
, EEP_NFTHRESH_2
);
1871 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
1872 "%s: invalid channel flags 0x%x\n", __func__
,
1873 chan
->channelFlags
);
1879 static void ath9k_hw_start_nfcal(struct ath_hal
*ah
)
1881 REG_SET_BIT(ah
, AR_PHY_AGC_CONTROL
,
1882 AR_PHY_AGC_CONTROL_ENABLE_NF
);
1883 REG_SET_BIT(ah
, AR_PHY_AGC_CONTROL
,
1884 AR_PHY_AGC_CONTROL_NO_UPDATE_NF
);
1885 REG_SET_BIT(ah
, AR_PHY_AGC_CONTROL
, AR_PHY_AGC_CONTROL_NF
);
1889 ath9k_hw_loadnf(struct ath_hal
*ah
, struct hal_channel_internal
*chan
)
1891 struct hal_nfcal_hist
*h
;
1894 const u_int32_t ar5416_cca_regs
[6] = {
1904 if (AR_SREV_9280(ah
))
1909 #ifdef ATH_NF_PER_CHAN
1910 h
= chan
->nfCalHist
;
1915 for (i
= 0; i
< NUM_NF_READINGS
; i
++) {
1916 if (chainmask
& (1 << i
)) {
1917 val
= REG_READ(ah
, ar5416_cca_regs
[i
]);
1919 val
|= (((u_int32_t
) (h
[i
].privNF
) << 1) & 0x1ff);
1920 REG_WRITE(ah
, ar5416_cca_regs
[i
], val
);
1924 REG_CLR_BIT(ah
, AR_PHY_AGC_CONTROL
,
1925 AR_PHY_AGC_CONTROL_ENABLE_NF
);
1926 REG_CLR_BIT(ah
, AR_PHY_AGC_CONTROL
,
1927 AR_PHY_AGC_CONTROL_NO_UPDATE_NF
);
1928 REG_SET_BIT(ah
, AR_PHY_AGC_CONTROL
, AR_PHY_AGC_CONTROL_NF
);
1930 for (j
= 0; j
< 1000; j
++) {
1931 if ((REG_READ(ah
, AR_PHY_AGC_CONTROL
) &
1932 AR_PHY_AGC_CONTROL_NF
) == 0)
1937 for (i
= 0; i
< NUM_NF_READINGS
; i
++) {
1938 if (chainmask
& (1 << i
)) {
1939 val
= REG_READ(ah
, ar5416_cca_regs
[i
]);
1941 val
|= (((u_int32_t
) (-50) << 1) & 0x1ff);
1942 REG_WRITE(ah
, ar5416_cca_regs
[i
], val
);
1947 static int16_t ath9k_hw_getnf(struct ath_hal
*ah
,
1948 struct hal_channel_internal
*chan
)
1950 int16_t nf
, nfThresh
;
1951 int16_t nfarray
[NUM_NF_READINGS
] = { 0 };
1952 struct hal_nfcal_hist
*h
;
1955 if (AR_SREV_9280(ah
))
1960 chan
->channelFlags
&= (~CHANNEL_CW_INT
);
1961 if (REG_READ(ah
, AR_PHY_AGC_CONTROL
) & AR_PHY_AGC_CONTROL_NF
) {
1962 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
1963 "%s: NF did not complete in calibration window\n",
1966 chan
->rawNoiseFloor
= nf
;
1967 return chan
->rawNoiseFloor
;
1969 ar5416GetNoiseFloor(ah
, nfarray
);
1971 if (getNoiseFloorThresh(ah
, chan
, &nfThresh
)
1973 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
1974 "%s: noise floor failed detected; "
1975 "detected %d, threshold %d\n", __func__
,
1977 chan
->channelFlags
|= CHANNEL_CW_INT
;
1981 #ifdef ATH_NF_PER_CHAN
1982 h
= chan
->nfCalHist
;
1987 ath9k_hw_update_nfcal_hist_buffer(h
, nfarray
);
1988 chan
->rawNoiseFloor
= h
[0].privNF
;
1990 return chan
->rawNoiseFloor
;
1993 static void ath9k_hw_update_mibstats(struct ath_hal
*ah
,
1994 struct hal_mib_stats
*stats
)
1996 stats
->ackrcv_bad
+= REG_READ(ah
, AR_ACK_FAIL
);
1997 stats
->rts_bad
+= REG_READ(ah
, AR_RTS_FAIL
);
1998 stats
->fcs_bad
+= REG_READ(ah
, AR_FCS_FAIL
);
1999 stats
->rts_good
+= REG_READ(ah
, AR_RTS_OK
);
2000 stats
->beacons
+= REG_READ(ah
, AR_BEACON_CNT
);
2003 static void ath9k_enable_mib_counters(struct ath_hal
*ah
)
2005 struct ath_hal_5416
*ahp
= AH5416(ah
);
2007 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
, "Enable mib counters\n");
2009 ath9k_hw_update_mibstats(ah
, &ahp
->ah_mibStats
);
2011 REG_WRITE(ah
, AR_FILT_OFDM
, 0);
2012 REG_WRITE(ah
, AR_FILT_CCK
, 0);
2013 REG_WRITE(ah
, AR_MIBC
,
2014 ~(AR_MIBC_COW
| AR_MIBC_FMC
| AR_MIBC_CMC
| AR_MIBC_MCS
)
2016 REG_WRITE(ah
, AR_PHY_ERR_MASK_1
, AR_PHY_ERR_OFDM_TIMING
);
2017 REG_WRITE(ah
, AR_PHY_ERR_MASK_2
, AR_PHY_ERR_CCK_TIMING
);
2020 static void ath9k_hw_disable_mib_counters(struct ath_hal
*ah
)
2022 struct ath_hal_5416
*ahp
= AH5416(ah
);
2024 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
, "Disabling MIB counters\n");
2026 REG_WRITE(ah
, AR_MIBC
, AR_MIBC_FMC
| AR_MIBC_CMC
);
2028 ath9k_hw_update_mibstats(ah
, &ahp
->ah_mibStats
);
2030 REG_WRITE(ah
, AR_FILT_OFDM
, 0);
2031 REG_WRITE(ah
, AR_FILT_CCK
, 0);
2034 static int ath9k_hw_get_ani_channel_idx(struct ath_hal
*ah
,
2035 struct hal_channel_internal
*chan
)
2037 struct ath_hal_5416
*ahp
= AH5416(ah
);
2040 for (i
= 0; i
< ARRAY_SIZE(ahp
->ah_ani
); i
++) {
2041 if (ahp
->ah_ani
[i
].c
.channel
== chan
->channel
)
2043 if (ahp
->ah_ani
[i
].c
.channel
== 0) {
2044 ahp
->ah_ani
[i
].c
.channel
= chan
->channel
;
2045 ahp
->ah_ani
[i
].c
.channelFlags
= chan
->channelFlags
;
2050 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2051 "No more channel states left. Using channel 0\n");
2055 static void ath9k_hw_ani_attach(struct ath_hal
*ah
)
2057 struct ath_hal_5416
*ahp
= AH5416(ah
);
2060 ahp
->ah_hasHwPhyCounters
= 1;
2062 memset(ahp
->ah_ani
, 0, sizeof(ahp
->ah_ani
));
2063 for (i
= 0; i
< ARRAY_SIZE(ahp
->ah_ani
); i
++) {
2064 ahp
->ah_ani
[i
].ofdmTrigHigh
= HAL_ANI_OFDM_TRIG_HIGH
;
2065 ahp
->ah_ani
[i
].ofdmTrigLow
= HAL_ANI_OFDM_TRIG_LOW
;
2066 ahp
->ah_ani
[i
].cckTrigHigh
= HAL_ANI_CCK_TRIG_HIGH
;
2067 ahp
->ah_ani
[i
].cckTrigLow
= HAL_ANI_CCK_TRIG_LOW
;
2068 ahp
->ah_ani
[i
].rssiThrHigh
= HAL_ANI_RSSI_THR_HIGH
;
2069 ahp
->ah_ani
[i
].rssiThrLow
= HAL_ANI_RSSI_THR_LOW
;
2070 ahp
->ah_ani
[i
].ofdmWeakSigDetectOff
=
2071 !HAL_ANI_USE_OFDM_WEAK_SIG
;
2072 ahp
->ah_ani
[i
].cckWeakSigThreshold
=
2073 HAL_ANI_CCK_WEAK_SIG_THR
;
2074 ahp
->ah_ani
[i
].spurImmunityLevel
= HAL_ANI_SPUR_IMMUNE_LVL
;
2075 ahp
->ah_ani
[i
].firstepLevel
= HAL_ANI_FIRSTEP_LVL
;
2076 if (ahp
->ah_hasHwPhyCounters
) {
2077 ahp
->ah_ani
[i
].ofdmPhyErrBase
=
2078 AR_PHY_COUNTMAX
- HAL_ANI_OFDM_TRIG_HIGH
;
2079 ahp
->ah_ani
[i
].cckPhyErrBase
=
2080 AR_PHY_COUNTMAX
- HAL_ANI_CCK_TRIG_HIGH
;
2083 if (ahp
->ah_hasHwPhyCounters
) {
2084 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2085 "Setting OfdmErrBase = 0x%08x\n",
2086 ahp
->ah_ani
[0].ofdmPhyErrBase
);
2087 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
, "Setting cckErrBase = 0x%08x\n",
2088 ahp
->ah_ani
[0].cckPhyErrBase
);
2090 REG_WRITE(ah
, AR_PHY_ERR_1
, ahp
->ah_ani
[0].ofdmPhyErrBase
);
2091 REG_WRITE(ah
, AR_PHY_ERR_2
, ahp
->ah_ani
[0].cckPhyErrBase
);
2092 ath9k_enable_mib_counters(ah
);
2094 ahp
->ah_aniPeriod
= HAL_ANI_PERIOD
;
2095 if (ah
->ah_config
.ath_hal_enableANI
)
2096 ahp
->ah_procPhyErr
|= HAL_PROCESS_ANI
;
2099 static inline void ath9k_hw_ani_setup(struct ath_hal
*ah
)
2101 struct ath_hal_5416
*ahp
= AH5416(ah
);
2104 const int totalSizeDesired
[] = { -55, -55, -55, -55, -62 };
2105 const int coarseHigh
[] = { -14, -14, -14, -14, -12 };
2106 const int coarseLow
[] = { -64, -64, -64, -64, -70 };
2107 const int firpwr
[] = { -78, -78, -78, -78, -80 };
2109 for (i
= 0; i
< 5; i
++) {
2110 ahp
->ah_totalSizeDesired
[i
] = totalSizeDesired
[i
];
2111 ahp
->ah_coarseHigh
[i
] = coarseHigh
[i
];
2112 ahp
->ah_coarseLow
[i
] = coarseLow
[i
];
2113 ahp
->ah_firpwr
[i
] = firpwr
[i
];
2117 static void ath9k_hw_ani_detach(struct ath_hal
*ah
)
2119 struct ath_hal_5416
*ahp
= AH5416(ah
);
2121 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
, "Detaching Ani\n");
2122 if (ahp
->ah_hasHwPhyCounters
) {
2123 ath9k_hw_disable_mib_counters(ah
);
2124 REG_WRITE(ah
, AR_PHY_ERR_1
, 0);
2125 REG_WRITE(ah
, AR_PHY_ERR_2
, 0);
2130 static bool ath9k_hw_ani_control(struct ath_hal
*ah
,
2131 enum hal_ani_cmd cmd
, int param
)
2133 struct ath_hal_5416
*ahp
= AH5416(ah
);
2134 struct ar5416AniState
*aniState
= ahp
->ah_curani
;
2136 switch (cmd
& ahp
->ah_ani_function
) {
2137 case HAL_ANI_NOISE_IMMUNITY_LEVEL
:{
2138 u_int level
= param
;
2140 if (level
>= ARRAY_SIZE(ahp
->ah_totalSizeDesired
)) {
2141 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2142 "%s: level out of range (%u > %u)\n",
2144 (unsigned) ARRAY_SIZE(ahp
->
2145 ah_totalSizeDesired
));
2149 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
2150 AR_PHY_DESIRED_SZ_TOT_DES
,
2151 ahp
->ah_totalSizeDesired
[level
]);
2152 REG_RMW_FIELD(ah
, AR_PHY_AGC_CTL1
,
2153 AR_PHY_AGC_CTL1_COARSE_LOW
,
2154 ahp
->ah_coarseLow
[level
]);
2155 REG_RMW_FIELD(ah
, AR_PHY_AGC_CTL1
,
2156 AR_PHY_AGC_CTL1_COARSE_HIGH
,
2157 ahp
->ah_coarseHigh
[level
]);
2158 REG_RMW_FIELD(ah
, AR_PHY_FIND_SIG
,
2159 AR_PHY_FIND_SIG_FIRPWR
,
2160 ahp
->ah_firpwr
[level
]);
2162 if (level
> aniState
->noiseImmunityLevel
)
2163 ahp
->ah_stats
.ast_ani_niup
++;
2164 else if (level
< aniState
->noiseImmunityLevel
)
2165 ahp
->ah_stats
.ast_ani_nidown
++;
2166 aniState
->noiseImmunityLevel
= level
;
2169 case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
:{
2170 const int m1ThreshLow
[] = { 127, 50 };
2171 const int m2ThreshLow
[] = { 127, 40 };
2172 const int m1Thresh
[] = { 127, 0x4d };
2173 const int m2Thresh
[] = { 127, 0x40 };
2174 const int m2CountThr
[] = { 31, 16 };
2175 const int m2CountThrLow
[] = { 63, 48 };
2176 u_int on
= param
? 1 : 0;
2178 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_LOW
,
2179 AR_PHY_SFCORR_LOW_M1_THRESH_LOW
,
2181 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_LOW
,
2182 AR_PHY_SFCORR_LOW_M2_THRESH_LOW
,
2184 REG_RMW_FIELD(ah
, AR_PHY_SFCORR
,
2185 AR_PHY_SFCORR_M1_THRESH
,
2187 REG_RMW_FIELD(ah
, AR_PHY_SFCORR
,
2188 AR_PHY_SFCORR_M2_THRESH
,
2190 REG_RMW_FIELD(ah
, AR_PHY_SFCORR
,
2191 AR_PHY_SFCORR_M2COUNT_THR
,
2193 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_LOW
,
2194 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW
,
2197 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_EXT
,
2198 AR_PHY_SFCORR_EXT_M1_THRESH_LOW
,
2200 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_EXT
,
2201 AR_PHY_SFCORR_EXT_M2_THRESH_LOW
,
2203 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_EXT
,
2204 AR_PHY_SFCORR_EXT_M1_THRESH
,
2206 REG_RMW_FIELD(ah
, AR_PHY_SFCORR_EXT
,
2207 AR_PHY_SFCORR_EXT_M2_THRESH
,
2211 REG_SET_BIT(ah
, AR_PHY_SFCORR_LOW
,
2212 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW
);
2214 REG_CLR_BIT(ah
, AR_PHY_SFCORR_LOW
,
2215 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW
);
2217 if (!on
!= aniState
->ofdmWeakSigDetectOff
) {
2219 ahp
->ah_stats
.ast_ani_ofdmon
++;
2221 ahp
->ah_stats
.ast_ani_ofdmoff
++;
2222 aniState
->ofdmWeakSigDetectOff
= !on
;
2226 case HAL_ANI_CCK_WEAK_SIGNAL_THR
:{
2227 const int weakSigThrCck
[] = { 8, 6 };
2228 u_int high
= param
? 1 : 0;
2230 REG_RMW_FIELD(ah
, AR_PHY_CCK_DETECT
,
2231 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK
,
2232 weakSigThrCck
[high
]);
2233 if (high
!= aniState
->cckWeakSigThreshold
) {
2235 ahp
->ah_stats
.ast_ani_cckhigh
++;
2237 ahp
->ah_stats
.ast_ani_ccklow
++;
2238 aniState
->cckWeakSigThreshold
= high
;
2242 case HAL_ANI_FIRSTEP_LEVEL
:{
2243 const int firstep
[] = { 0, 4, 8 };
2244 u_int level
= param
;
2246 if (level
>= ARRAY_SIZE(firstep
)) {
2247 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2248 "%s: level out of range (%u > %u)\n",
2250 (unsigned) ARRAY_SIZE(firstep
));
2253 REG_RMW_FIELD(ah
, AR_PHY_FIND_SIG
,
2254 AR_PHY_FIND_SIG_FIRSTEP
,
2256 if (level
> aniState
->firstepLevel
)
2257 ahp
->ah_stats
.ast_ani_stepup
++;
2258 else if (level
< aniState
->firstepLevel
)
2259 ahp
->ah_stats
.ast_ani_stepdown
++;
2260 aniState
->firstepLevel
= level
;
2263 case HAL_ANI_SPUR_IMMUNITY_LEVEL
:{
2264 const int cycpwrThr1
[] =
2265 { 2, 4, 6, 8, 10, 12, 14, 16 };
2266 u_int level
= param
;
2268 if (level
>= ARRAY_SIZE(cycpwrThr1
)) {
2269 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2270 "%s: level out of range (%u > %u)\n",
2273 ARRAY_SIZE(cycpwrThr1
));
2276 REG_RMW_FIELD(ah
, AR_PHY_TIMING5
,
2277 AR_PHY_TIMING5_CYCPWR_THR1
,
2279 if (level
> aniState
->spurImmunityLevel
)
2280 ahp
->ah_stats
.ast_ani_spurup
++;
2281 else if (level
< aniState
->spurImmunityLevel
)
2282 ahp
->ah_stats
.ast_ani_spurdown
++;
2283 aniState
->spurImmunityLevel
= level
;
2286 case HAL_ANI_PRESENT
:
2289 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2290 "%s: invalid cmd %u\n", __func__
, cmd
);
2294 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
, "%s: ANI parameters:\n", __func__
);
2295 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2296 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2297 "ofdmWeakSigDetectOff=%d\n",
2298 aniState
->noiseImmunityLevel
, aniState
->spurImmunityLevel
,
2299 !aniState
->ofdmWeakSigDetectOff
);
2300 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2301 "cckWeakSigThreshold=%d, "
2302 "firstepLevel=%d, listenTime=%d\n",
2303 aniState
->cckWeakSigThreshold
, aniState
->firstepLevel
,
2304 aniState
->listenTime
);
2305 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2306 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2307 aniState
->cycleCount
, aniState
->ofdmPhyErrCount
,
2308 aniState
->cckPhyErrCount
);
2312 static void ath9k_ani_restart(struct ath_hal
*ah
)
2314 struct ath_hal_5416
*ahp
= AH5416(ah
);
2315 struct ar5416AniState
*aniState
;
2320 aniState
= ahp
->ah_curani
;
2322 aniState
->listenTime
= 0;
2323 if (ahp
->ah_hasHwPhyCounters
) {
2324 if (aniState
->ofdmTrigHigh
> AR_PHY_COUNTMAX
) {
2325 aniState
->ofdmPhyErrBase
= 0;
2326 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2327 "OFDM Trigger is too high for hw counters\n");
2329 aniState
->ofdmPhyErrBase
=
2330 AR_PHY_COUNTMAX
- aniState
->ofdmTrigHigh
;
2332 if (aniState
->cckTrigHigh
> AR_PHY_COUNTMAX
) {
2333 aniState
->cckPhyErrBase
= 0;
2334 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2335 "CCK Trigger is too high for hw counters\n");
2337 aniState
->cckPhyErrBase
=
2338 AR_PHY_COUNTMAX
- aniState
->cckTrigHigh
;
2340 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2341 "%s: Writing ofdmbase=%u cckbase=%u\n",
2342 __func__
, aniState
->ofdmPhyErrBase
,
2343 aniState
->cckPhyErrBase
);
2344 REG_WRITE(ah
, AR_PHY_ERR_1
, aniState
->ofdmPhyErrBase
);
2345 REG_WRITE(ah
, AR_PHY_ERR_2
, aniState
->cckPhyErrBase
);
2346 REG_WRITE(ah
, AR_PHY_ERR_MASK_1
, AR_PHY_ERR_OFDM_TIMING
);
2347 REG_WRITE(ah
, AR_PHY_ERR_MASK_2
, AR_PHY_ERR_CCK_TIMING
);
2349 ath9k_hw_update_mibstats(ah
, &ahp
->ah_mibStats
);
2351 aniState
->ofdmPhyErrCount
= 0;
2352 aniState
->cckPhyErrCount
= 0;
2355 static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal
*ah
)
2357 struct ath_hal_5416
*ahp
= AH5416(ah
);
2358 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
2359 struct ar5416AniState
*aniState
;
2360 enum wireless_mode mode
;
2366 aniState
= ahp
->ah_curani
;
2368 if (aniState
->noiseImmunityLevel
< HAL_NOISE_IMMUNE_MAX
) {
2369 if (ath9k_hw_ani_control(ah
, HAL_ANI_NOISE_IMMUNITY_LEVEL
,
2370 aniState
->noiseImmunityLevel
+ 1)) {
2375 if (aniState
->spurImmunityLevel
< HAL_SPUR_IMMUNE_MAX
) {
2376 if (ath9k_hw_ani_control(ah
, HAL_ANI_SPUR_IMMUNITY_LEVEL
,
2377 aniState
->spurImmunityLevel
+ 1)) {
2382 if (ah
->ah_opmode
== HAL_M_HOSTAP
) {
2383 if (aniState
->firstepLevel
< HAL_FIRST_STEP_MAX
) {
2384 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2385 aniState
->firstepLevel
+ 1);
2389 rssi
= BEACON_RSSI(ahp
);
2390 if (rssi
> aniState
->rssiThrHigh
) {
2391 if (!aniState
->ofdmWeakSigDetectOff
) {
2392 if (ath9k_hw_ani_control(ah
,
2393 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
,
2395 ath9k_hw_ani_control(ah
,
2396 HAL_ANI_SPUR_IMMUNITY_LEVEL
,
2401 if (aniState
->firstepLevel
< HAL_FIRST_STEP_MAX
) {
2402 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2403 aniState
->firstepLevel
+ 1);
2406 } else if (rssi
> aniState
->rssiThrLow
) {
2407 if (aniState
->ofdmWeakSigDetectOff
)
2408 ath9k_hw_ani_control(ah
,
2409 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
,
2411 if (aniState
->firstepLevel
< HAL_FIRST_STEP_MAX
)
2412 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2413 aniState
->firstepLevel
+ 1);
2416 mode
= ath9k_hw_chan2wmode(ah
, (struct hal_channel
*) chan
);
2417 if (mode
== WIRELESS_MODE_11g
|| mode
== WIRELESS_MODE_11b
) {
2418 if (!aniState
->ofdmWeakSigDetectOff
)
2419 ath9k_hw_ani_control(ah
,
2420 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
,
2422 if (aniState
->firstepLevel
> 0)
2423 ath9k_hw_ani_control(ah
,
2424 HAL_ANI_FIRSTEP_LEVEL
,
2431 static void ath9k_hw_ani_cck_err_trigger(struct ath_hal
*ah
)
2433 struct ath_hal_5416
*ahp
= AH5416(ah
);
2434 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
2435 struct ar5416AniState
*aniState
;
2436 enum wireless_mode mode
;
2442 aniState
= ahp
->ah_curani
;
2443 if (aniState
->noiseImmunityLevel
< HAL_NOISE_IMMUNE_MAX
) {
2444 if (ath9k_hw_ani_control(ah
, HAL_ANI_NOISE_IMMUNITY_LEVEL
,
2445 aniState
->noiseImmunityLevel
+ 1)) {
2449 if (ah
->ah_opmode
== HAL_M_HOSTAP
) {
2450 if (aniState
->firstepLevel
< HAL_FIRST_STEP_MAX
) {
2451 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2452 aniState
->firstepLevel
+ 1);
2456 rssi
= BEACON_RSSI(ahp
);
2457 if (rssi
> aniState
->rssiThrLow
) {
2458 if (aniState
->firstepLevel
< HAL_FIRST_STEP_MAX
)
2459 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2460 aniState
->firstepLevel
+ 1);
2462 mode
= ath9k_hw_chan2wmode(ah
, (struct hal_channel
*) chan
);
2463 if (mode
== WIRELESS_MODE_11g
|| mode
== WIRELESS_MODE_11b
) {
2464 if (aniState
->firstepLevel
> 0)
2465 ath9k_hw_ani_control(ah
,
2466 HAL_ANI_FIRSTEP_LEVEL
,
2472 static void ath9k_ani_reset(struct ath_hal
*ah
)
2474 struct ath_hal_5416
*ahp
= AH5416(ah
);
2475 struct ar5416AniState
*aniState
;
2476 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
2482 index
= ath9k_hw_get_ani_channel_idx(ah
, chan
);
2483 aniState
= &ahp
->ah_ani
[index
];
2484 ahp
->ah_curani
= aniState
;
2486 if (DO_ANI(ah
) && ah
->ah_opmode
!= HAL_M_STA
2487 && ah
->ah_opmode
!= HAL_M_IBSS
) {
2488 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2489 "%s: Reset ANI state opmode %u\n", __func__
,
2491 ahp
->ah_stats
.ast_ani_reset
++;
2492 ath9k_hw_ani_control(ah
, HAL_ANI_NOISE_IMMUNITY_LEVEL
, 0);
2493 ath9k_hw_ani_control(ah
, HAL_ANI_SPUR_IMMUNITY_LEVEL
, 0);
2494 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
, 0);
2495 ath9k_hw_ani_control(ah
,
2496 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
,
2497 !HAL_ANI_USE_OFDM_WEAK_SIG
);
2498 ath9k_hw_ani_control(ah
, HAL_ANI_CCK_WEAK_SIGNAL_THR
,
2499 HAL_ANI_CCK_WEAK_SIG_THR
);
2500 ath9k_hw_setrxfilter(ah
,
2501 ath9k_hw_getrxfilter(ah
) |
2502 HAL_RX_FILTER_PHYERR
);
2503 if (ah
->ah_opmode
== HAL_M_HOSTAP
) {
2504 ahp
->ah_curani
->ofdmTrigHigh
=
2505 ah
->ah_config
.ath_hal_ofdmTrigHigh
;
2506 ahp
->ah_curani
->ofdmTrigLow
=
2507 ah
->ah_config
.ath_hal_ofdmTrigLow
;
2508 ahp
->ah_curani
->cckTrigHigh
=
2509 ah
->ah_config
.ath_hal_cckTrigHigh
;
2510 ahp
->ah_curani
->cckTrigLow
=
2511 ah
->ah_config
.ath_hal_cckTrigLow
;
2513 ath9k_ani_restart(ah
);
2517 if (aniState
->noiseImmunityLevel
!= 0)
2518 ath9k_hw_ani_control(ah
, HAL_ANI_NOISE_IMMUNITY_LEVEL
,
2519 aniState
->noiseImmunityLevel
);
2520 if (aniState
->spurImmunityLevel
!= 0)
2521 ath9k_hw_ani_control(ah
, HAL_ANI_SPUR_IMMUNITY_LEVEL
,
2522 aniState
->spurImmunityLevel
);
2523 if (aniState
->ofdmWeakSigDetectOff
)
2524 ath9k_hw_ani_control(ah
,
2525 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
,
2526 !aniState
->ofdmWeakSigDetectOff
);
2527 if (aniState
->cckWeakSigThreshold
)
2528 ath9k_hw_ani_control(ah
, HAL_ANI_CCK_WEAK_SIGNAL_THR
,
2529 aniState
->cckWeakSigThreshold
);
2530 if (aniState
->firstepLevel
!= 0)
2531 ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2532 aniState
->firstepLevel
);
2533 if (ahp
->ah_hasHwPhyCounters
) {
2534 ath9k_hw_setrxfilter(ah
,
2535 ath9k_hw_getrxfilter(ah
) &
2536 ~HAL_RX_FILTER_PHYERR
);
2537 ath9k_ani_restart(ah
);
2538 REG_WRITE(ah
, AR_PHY_ERR_MASK_1
, AR_PHY_ERR_OFDM_TIMING
);
2539 REG_WRITE(ah
, AR_PHY_ERR_MASK_2
, AR_PHY_ERR_CCK_TIMING
);
2542 ath9k_ani_restart(ah
);
2543 ath9k_hw_setrxfilter(ah
,
2544 ath9k_hw_getrxfilter(ah
) |
2545 HAL_RX_FILTER_PHYERR
);
2549 void ath9k_hw_procmibevent(struct ath_hal
*ah
,
2550 const struct hal_node_stats
*stats
)
2552 struct ath_hal_5416
*ahp
= AH5416(ah
);
2553 u_int32_t phyCnt1
, phyCnt2
;
2555 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
, "Processing Mib Intr\n");
2557 REG_WRITE(ah
, AR_FILT_OFDM
, 0);
2558 REG_WRITE(ah
, AR_FILT_CCK
, 0);
2559 if (!(REG_READ(ah
, AR_SLP_MIB_CTRL
) & AR_SLP_MIB_PENDING
))
2560 REG_WRITE(ah
, AR_SLP_MIB_CTRL
, AR_SLP_MIB_CLEAR
);
2562 ath9k_hw_update_mibstats(ah
, &ahp
->ah_mibStats
);
2563 ahp
->ah_stats
.ast_nodestats
= *stats
;
2568 phyCnt1
= REG_READ(ah
, AR_PHY_ERR_1
);
2569 phyCnt2
= REG_READ(ah
, AR_PHY_ERR_2
);
2570 if (((phyCnt1
& AR_MIBCNT_INTRMASK
) == AR_MIBCNT_INTRMASK
) ||
2571 ((phyCnt2
& AR_MIBCNT_INTRMASK
) == AR_MIBCNT_INTRMASK
)) {
2572 struct ar5416AniState
*aniState
= ahp
->ah_curani
;
2573 u_int32_t ofdmPhyErrCnt
, cckPhyErrCnt
;
2575 ofdmPhyErrCnt
= phyCnt1
- aniState
->ofdmPhyErrBase
;
2576 ahp
->ah_stats
.ast_ani_ofdmerrs
+=
2577 ofdmPhyErrCnt
- aniState
->ofdmPhyErrCount
;
2578 aniState
->ofdmPhyErrCount
= ofdmPhyErrCnt
;
2580 cckPhyErrCnt
= phyCnt2
- aniState
->cckPhyErrBase
;
2581 ahp
->ah_stats
.ast_ani_cckerrs
+=
2582 cckPhyErrCnt
- aniState
->cckPhyErrCount
;
2583 aniState
->cckPhyErrCount
= cckPhyErrCnt
;
2585 if (aniState
->ofdmPhyErrCount
> aniState
->ofdmTrigHigh
)
2586 ath9k_hw_ani_ofdm_err_trigger(ah
);
2587 if (aniState
->cckPhyErrCount
> aniState
->cckTrigHigh
)
2588 ath9k_hw_ani_cck_err_trigger(ah
);
2590 ath9k_ani_restart(ah
);
2594 static void ath9k_hw_ani_lower_immunity(struct ath_hal
*ah
)
2596 struct ath_hal_5416
*ahp
= AH5416(ah
);
2597 struct ar5416AniState
*aniState
;
2600 aniState
= ahp
->ah_curani
;
2602 if (ah
->ah_opmode
== HAL_M_HOSTAP
) {
2603 if (aniState
->firstepLevel
> 0) {
2604 if (ath9k_hw_ani_control(ah
, HAL_ANI_FIRSTEP_LEVEL
,
2605 aniState
->firstepLevel
- 1)) {
2610 rssi
= BEACON_RSSI(ahp
);
2611 if (rssi
> aniState
->rssiThrHigh
) {
2613 } else if (rssi
> aniState
->rssiThrLow
) {
2614 if (aniState
->ofdmWeakSigDetectOff
) {
2615 if (ath9k_hw_ani_control(ah
,
2616 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
,
2622 if (aniState
->firstepLevel
> 0) {
2623 if (ath9k_hw_ani_control
2624 (ah
, HAL_ANI_FIRSTEP_LEVEL
,
2625 aniState
->firstepLevel
- 1) ==
2631 if (aniState
->firstepLevel
> 0) {
2632 if (ath9k_hw_ani_control
2633 (ah
, HAL_ANI_FIRSTEP_LEVEL
,
2634 aniState
->firstepLevel
- 1) ==
2642 if (aniState
->spurImmunityLevel
> 0) {
2643 if (ath9k_hw_ani_control(ah
, HAL_ANI_SPUR_IMMUNITY_LEVEL
,
2644 aniState
->spurImmunityLevel
- 1)) {
2649 if (aniState
->noiseImmunityLevel
> 0) {
2650 ath9k_hw_ani_control(ah
, HAL_ANI_NOISE_IMMUNITY_LEVEL
,
2651 aniState
->noiseImmunityLevel
- 1);
2656 static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal
*ah
)
2658 struct ath_hal_5416
*ahp
= AH5416(ah
);
2659 struct ar5416AniState
*aniState
;
2660 u_int32_t txFrameCount
, rxFrameCount
, cycleCount
;
2663 txFrameCount
= REG_READ(ah
, AR_TFCNT
);
2664 rxFrameCount
= REG_READ(ah
, AR_RFCNT
);
2665 cycleCount
= REG_READ(ah
, AR_CCCNT
);
2667 aniState
= ahp
->ah_curani
;
2668 if (aniState
->cycleCount
== 0 || aniState
->cycleCount
> cycleCount
) {
2671 ahp
->ah_stats
.ast_ani_lzero
++;
2673 int32_t ccdelta
= cycleCount
- aniState
->cycleCount
;
2674 int32_t rfdelta
= rxFrameCount
- aniState
->rxFrameCount
;
2675 int32_t tfdelta
= txFrameCount
- aniState
->txFrameCount
;
2676 listenTime
= (ccdelta
- rfdelta
- tfdelta
) / 44000;
2678 aniState
->cycleCount
= cycleCount
;
2679 aniState
->txFrameCount
= txFrameCount
;
2680 aniState
->rxFrameCount
= rxFrameCount
;
2685 void ath9k_hw_ani_monitor(struct ath_hal
*ah
,
2686 const struct hal_node_stats
*stats
,
2687 struct hal_channel
*chan
)
2689 struct ath_hal_5416
*ahp
= AH5416(ah
);
2690 struct ar5416AniState
*aniState
;
2693 aniState
= ahp
->ah_curani
;
2694 ahp
->ah_stats
.ast_nodestats
= *stats
;
2696 listenTime
= ath9k_hw_ani_get_listen_time(ah
);
2697 if (listenTime
< 0) {
2698 ahp
->ah_stats
.ast_ani_lneg
++;
2699 ath9k_ani_restart(ah
);
2703 aniState
->listenTime
+= listenTime
;
2705 if (ahp
->ah_hasHwPhyCounters
) {
2706 u_int32_t phyCnt1
, phyCnt2
;
2707 u_int32_t ofdmPhyErrCnt
, cckPhyErrCnt
;
2709 ath9k_hw_update_mibstats(ah
, &ahp
->ah_mibStats
);
2711 phyCnt1
= REG_READ(ah
, AR_PHY_ERR_1
);
2712 phyCnt2
= REG_READ(ah
, AR_PHY_ERR_2
);
2714 if (phyCnt1
< aniState
->ofdmPhyErrBase
||
2715 phyCnt2
< aniState
->cckPhyErrBase
) {
2716 if (phyCnt1
< aniState
->ofdmPhyErrBase
) {
2717 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2718 "%s: phyCnt1 0x%x, resetting "
2719 "counter value to 0x%x\n",
2721 aniState
->ofdmPhyErrBase
);
2722 REG_WRITE(ah
, AR_PHY_ERR_1
,
2723 aniState
->ofdmPhyErrBase
);
2724 REG_WRITE(ah
, AR_PHY_ERR_MASK_1
,
2725 AR_PHY_ERR_OFDM_TIMING
);
2727 if (phyCnt2
< aniState
->cckPhyErrBase
) {
2728 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2729 "%s: phyCnt2 0x%x, resetting "
2730 "counter value to 0x%x\n",
2732 aniState
->cckPhyErrBase
);
2733 REG_WRITE(ah
, AR_PHY_ERR_2
,
2734 aniState
->cckPhyErrBase
);
2735 REG_WRITE(ah
, AR_PHY_ERR_MASK_2
,
2736 AR_PHY_ERR_CCK_TIMING
);
2741 ofdmPhyErrCnt
= phyCnt1
- aniState
->ofdmPhyErrBase
;
2742 ahp
->ah_stats
.ast_ani_ofdmerrs
+=
2743 ofdmPhyErrCnt
- aniState
->ofdmPhyErrCount
;
2744 aniState
->ofdmPhyErrCount
= ofdmPhyErrCnt
;
2746 cckPhyErrCnt
= phyCnt2
- aniState
->cckPhyErrBase
;
2747 ahp
->ah_stats
.ast_ani_cckerrs
+=
2748 cckPhyErrCnt
- aniState
->cckPhyErrCount
;
2749 aniState
->cckPhyErrCount
= cckPhyErrCnt
;
2755 if (aniState
->listenTime
> 5 * ahp
->ah_aniPeriod
) {
2756 if (aniState
->ofdmPhyErrCount
<= aniState
->listenTime
*
2757 aniState
->ofdmTrigLow
/ 1000 &&
2758 aniState
->cckPhyErrCount
<= aniState
->listenTime
*
2759 aniState
->cckTrigLow
/ 1000)
2760 ath9k_hw_ani_lower_immunity(ah
);
2761 ath9k_ani_restart(ah
);
2762 } else if (aniState
->listenTime
> ahp
->ah_aniPeriod
) {
2763 if (aniState
->ofdmPhyErrCount
> aniState
->listenTime
*
2764 aniState
->ofdmTrigHigh
/ 1000) {
2765 ath9k_hw_ani_ofdm_err_trigger(ah
);
2766 ath9k_ani_restart(ah
);
2767 } else if (aniState
->cckPhyErrCount
>
2768 aniState
->listenTime
* aniState
->cckTrigHigh
/
2770 ath9k_hw_ani_cck_err_trigger(ah
);
2771 ath9k_ani_restart(ah
);
2776 #ifndef ATH_NF_PER_CHAN
2777 static void ath9k_init_nfcal_hist_buffer(struct ath_hal
*ah
)
2781 for (i
= 0; i
< NUM_NF_READINGS
; i
++) {
2782 ah
->nfCalHist
[i
].currIndex
= 0;
2783 ah
->nfCalHist
[i
].privNF
= AR_PHY_CCA_MAX_GOOD_VALUE
;
2784 ah
->nfCalHist
[i
].invalidNFcount
=
2785 AR_PHY_CCA_FILTERWINDOW_LENGTH
;
2786 for (j
= 0; j
< HAL_NF_CAL_HIST_MAX
; j
++) {
2787 ah
->nfCalHist
[i
].nfCalBuffer
[j
] =
2788 AR_PHY_CCA_MAX_GOOD_VALUE
;
2795 static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal
*ah
,
2796 u_int32_t gpio
, u_int32_t type
)
2799 u_int32_t gpio_shift
, tmp
;
2802 addr
= AR_GPIO_OUTPUT_MUX3
;
2804 addr
= AR_GPIO_OUTPUT_MUX2
;
2806 addr
= AR_GPIO_OUTPUT_MUX1
;
2808 gpio_shift
= (gpio
% 6) * 5;
2810 if (AR_SREV_9280_20_OR_LATER(ah
)
2811 || (addr
!= AR_GPIO_OUTPUT_MUX1
)) {
2812 REG_RMW(ah
, addr
, (type
<< gpio_shift
),
2813 (0x1f << gpio_shift
));
2815 tmp
= REG_READ(ah
, addr
);
2816 tmp
= ((tmp
& 0x1F0) << 1) | (tmp
& ~0x1F0);
2817 tmp
&= ~(0x1f << gpio_shift
);
2818 tmp
|= (type
<< gpio_shift
);
2819 REG_WRITE(ah
, addr
, tmp
);
2823 static bool ath9k_hw_cfg_output(struct ath_hal
*ah
, u_int32_t gpio
,
2824 enum hal_gpio_output_mux_type
2827 u_int32_t ah_signal_type
;
2828 u_int32_t gpio_shift
;
2830 static u_int32_t MuxSignalConversionTable
[] = {
2832 AR_GPIO_OUTPUT_MUX_AS_OUTPUT
,
2834 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED
,
2836 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED
,
2838 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED
,
2840 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED
,
2843 if ((halSignalType
>= 0)
2844 && (halSignalType
< ARRAY_SIZE(MuxSignalConversionTable
)))
2845 ah_signal_type
= MuxSignalConversionTable
[halSignalType
];
2849 ath9k_hw_gpio_cfg_output_mux(ah
, gpio
, ah_signal_type
);
2851 gpio_shift
= 2 * gpio
;
2855 (AR_GPIO_OE_OUT_DRV_ALL
<< gpio_shift
),
2856 (AR_GPIO_OE_OUT_DRV
<< gpio_shift
));
2861 static bool ath9k_hw_set_gpio(struct ath_hal
*ah
, u_int32_t gpio
,
2864 REG_RMW(ah
, AR_GPIO_IN_OUT
, ((val
& 1) << gpio
),
2869 static u_int32_t
ath9k_hw_gpio_get(struct ath_hal
*ah
, u_int32_t gpio
)
2871 if (gpio
>= ah
->ah_caps
.halNumGpioPins
)
2874 if (AR_SREV_9280_10_OR_LATER(ah
)) {
2876 (REG_READ(ah
, AR_GPIO_IN_OUT
),
2877 AR928X_GPIO_IN_VAL
) & AR_GPIO_BIT(gpio
)) != 0;
2879 return (MS(REG_READ(ah
, AR_GPIO_IN_OUT
), AR_GPIO_IN_VAL
) &
2880 AR_GPIO_BIT(gpio
)) != 0;
2884 static inline enum hal_status
ath9k_hw_post_attach(struct ath_hal
*ah
)
2886 enum hal_status ecode
;
2888 if (!ath9k_hw_chip_test(ah
)) {
2889 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
2890 "%s: hardware self-test failed\n", __func__
);
2891 return HAL_ESELFTEST
;
2894 ecode
= ath9k_hw_rf_claim(ah
);
2895 if (ecode
!= HAL_OK
)
2898 ecode
= ath9k_hw_eeprom_attach(ah
);
2899 if (ecode
!= HAL_OK
)
2901 ecode
= ath9k_hw_rfattach(ah
);
2902 if (ecode
!= HAL_OK
)
2905 if (!AR_SREV_9100(ah
)) {
2906 ath9k_hw_ani_setup(ah
);
2907 ath9k_hw_ani_attach(ah
);
2912 static u_int32_t
ath9k_hw_ini_fixup(struct ath_hal
*ah
,
2913 struct ar5416_eeprom
*pEepData
,
2914 u_int32_t reg
, u_int32_t value
)
2916 struct base_eep_header
*pBase
= &(pEepData
->baseEepHeader
);
2918 switch (ah
->ah_devid
) {
2919 case AR9280_DEVID_PCI
:
2920 if (reg
== 0x7894) {
2921 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
2922 "ini VAL: %x EEPROM: %x\n", value
,
2923 (pBase
->version
& 0xff));
2925 if ((pBase
->version
& 0xff) > 0x0a) {
2926 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
2929 value
&= ~AR_AN_TOP2_PWDCLKIND
;
2930 value
|= AR_AN_TOP2_PWDCLKIND
& (pBase
->
2931 pwdclkind
<< AR_AN_TOP2_PWDCLKIND_S
);
2933 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
2934 "PWDCLKIND Earlier Rev\n");
2937 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
2938 "final ini VAL: %x\n", value
);
2945 static bool ath9k_hw_fill_cap_info(struct ath_hal
*ah
)
2947 struct ath_hal_5416
*ahp
= AH5416(ah
);
2948 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
2949 u_int16_t capField
= 0, eeval
;
2951 eeval
= ath9k_hw_get_eeprom(ahp
, EEP_REG_0
);
2953 ah
->ah_currentRD
= eeval
;
2955 eeval
= ath9k_hw_get_eeprom(ahp
, EEP_REG_1
);
2956 ah
->ah_currentRDExt
= eeval
;
2958 capField
= ath9k_hw_get_eeprom(ahp
, EEP_OP_CAP
);
2960 if (ah
->ah_opmode
!= HAL_M_HOSTAP
&&
2961 ah
->ah_subvendorid
== AR_SUBVENDOR_ID_NEW_A
) {
2962 if (ah
->ah_currentRD
== 0x64 || ah
->ah_currentRD
== 0x65)
2963 ah
->ah_currentRD
+= 5;
2964 else if (ah
->ah_currentRD
== 0x41)
2965 ah
->ah_currentRD
= 0x43;
2966 DPRINTF(ah
->ah_sc
, ATH_DBG_REGULATORY
,
2967 "%s: regdomain mapped to 0x%x\n", __func__
,
2971 pCap
->halWirelessModes
= 0;
2972 eeval
= ath9k_hw_get_eeprom(ahp
, EEP_OP_MODE
);
2974 if (eeval
& AR5416_OPFLAGS_11A
) {
2975 pCap
->halWirelessModes
|= ATH9K_MODE_SEL_11A
|
2976 ((!ah
->ah_config
.ath_hal_htEnable
2977 || (eeval
& AR5416_OPFLAGS_N_5G_HT20
)) ? 0
2978 : (ATH9K_MODE_SEL_11NA_HT20
|
2979 ((eeval
& AR5416_OPFLAGS_N_5G_HT40
) ? 0
2980 : (ATH9K_MODE_SEL_11NA_HT40PLUS
|
2981 ATH9K_MODE_SEL_11NA_HT40MINUS
))));
2983 if (eeval
& AR5416_OPFLAGS_11G
) {
2984 pCap
->halWirelessModes
|=
2985 ATH9K_MODE_SEL_11B
| ATH9K_MODE_SEL_11G
|
2986 ((!ah
->ah_config
.ath_hal_htEnable
2987 || (eeval
& AR5416_OPFLAGS_N_2G_HT20
)) ? 0
2988 : (ATH9K_MODE_SEL_11NG_HT20
|
2989 ((eeval
& AR5416_OPFLAGS_N_2G_HT40
) ? 0
2990 : (ATH9K_MODE_SEL_11NG_HT40PLUS
|
2991 ATH9K_MODE_SEL_11NG_HT40MINUS
))));
2994 pCap
->halTxChainMask
= ath9k_hw_get_eeprom(ahp
, EEP_TX_MASK
);
2995 if ((ah
->ah_isPciExpress
)
2996 || (eeval
& AR5416_OPFLAGS_11A
)) {
2997 pCap
->halRxChainMask
=
2998 ath9k_hw_get_eeprom(ahp
, EEP_RX_MASK
);
3000 pCap
->halRxChainMask
=
3001 (ath9k_hw_gpio_get(ah
, 0)) ? 0x5 : 0x7;
3004 if (!(AR_SREV_9280(ah
) && (ah
->ah_macRev
== 0)))
3005 ahp
->ah_miscMode
|= AR_PCU_MIC_NEW_LOC_ENA
;
3007 pCap
->halLow2GhzChan
= 2312;
3008 pCap
->halHigh2GhzChan
= 2732;
3010 pCap
->halLow5GhzChan
= 4920;
3011 pCap
->halHigh5GhzChan
= 6100;
3013 pCap
->halCipherCkipSupport
= false;
3014 pCap
->halCipherTkipSupport
= true;
3015 pCap
->halCipherAesCcmSupport
= true;
3017 pCap
->halMicCkipSupport
= false;
3018 pCap
->halMicTkipSupport
= true;
3019 pCap
->halMicAesCcmSupport
= true;
3021 pCap
->halChanSpreadSupport
= true;
3023 pCap
->halHTSupport
=
3024 ah
->ah_config
.ath_hal_htEnable
? true : false;
3025 pCap
->halGTTSupport
= true;
3026 pCap
->halVEOLSupport
= true;
3027 pCap
->halBssIdMaskSupport
= true;
3028 pCap
->halMcastKeySrchSupport
= false;
3030 if (capField
& AR_EEPROM_EEPCAP_MAXQCU
)
3031 pCap
->halTotalQueues
=
3032 MS(capField
, AR_EEPROM_EEPCAP_MAXQCU
);
3034 pCap
->halTotalQueues
= HAL_NUM_TX_QUEUES
;
3036 if (capField
& AR_EEPROM_EEPCAP_KC_ENTRIES
)
3037 pCap
->halKeyCacheSize
=
3038 1 << MS(capField
, AR_EEPROM_EEPCAP_KC_ENTRIES
);
3040 pCap
->halKeyCacheSize
= AR_KEYTABLE_SIZE
;
3042 pCap
->halFastCCSupport
= true;
3043 pCap
->halNumMRRetries
= 4;
3044 pCap
->halTxTrigLevelMax
= MAX_TX_FIFO_THRESHOLD
;
3046 if (AR_SREV_9280_10_OR_LATER(ah
))
3047 pCap
->halNumGpioPins
= AR928X_NUM_GPIO
;
3049 pCap
->halNumGpioPins
= AR_NUM_GPIO
;
3051 if (AR_SREV_9280_10_OR_LATER(ah
)) {
3052 pCap
->halWowSupport
= true;
3053 pCap
->halWowMatchPatternExact
= true;
3055 pCap
->halWowSupport
= false;
3056 pCap
->halWowMatchPatternExact
= false;
3059 if (AR_SREV_9160_10_OR_LATER(ah
) || AR_SREV_9100(ah
)) {
3060 pCap
->halCSTSupport
= true;
3061 pCap
->halRtsAggrLimit
= ATH_AMPDU_LIMIT_MAX
;
3063 pCap
->halRtsAggrLimit
= (8 * 1024);
3066 pCap
->halEnhancedPmSupport
= true;
3068 ah
->ah_rfsilent
= ath9k_hw_get_eeprom(ahp
, EEP_RF_SILENT
);
3069 if (ah
->ah_rfsilent
& EEP_RFSILENT_ENABLED
) {
3070 ahp
->ah_gpioSelect
=
3071 MS(ah
->ah_rfsilent
, EEP_RFSILENT_GPIO_SEL
);
3073 MS(ah
->ah_rfsilent
, EEP_RFSILENT_POLARITY
);
3075 ath9k_hw_setcapability(ah
, HAL_CAP_RFSILENT
, 1, true,
3077 pCap
->halRfSilentSupport
= true;
3080 if ((ah
->ah_macVersion
== AR_SREV_VERSION_5416_PCI
) ||
3081 (ah
->ah_macVersion
== AR_SREV_VERSION_5416_PCIE
) ||
3082 (ah
->ah_macVersion
== AR_SREV_VERSION_9160
) ||
3083 (ah
->ah_macVersion
== AR_SREV_VERSION_9100
) ||
3084 (ah
->ah_macVersion
== AR_SREV_VERSION_9280
))
3085 pCap
->halAutoSleepSupport
= false;
3087 pCap
->halAutoSleepSupport
= true;
3089 if (AR_SREV_9280(ah
))
3090 pCap
->hal4kbSplitTransSupport
= false;
3092 pCap
->hal4kbSplitTransSupport
= true;
3094 if (ah
->ah_currentRDExt
& (1 << REG_EXT_JAPAN_MIDBAND
)) {
3096 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A
|
3097 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN
|
3098 AR_EEPROM_EEREGCAP_EN_KK_U2
|
3099 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND
;
3102 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A
|
3103 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN
;
3106 pCap
->halRegCap
|= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND
;
3108 pCap
->halNumAntCfg5GHz
=
3109 ath9k_hw_get_num_ant_config(ahp
, HAL_FREQ_BAND_5GHZ
);
3110 pCap
->halNumAntCfg2GHz
=
3111 ath9k_hw_get_num_ant_config(ahp
, HAL_FREQ_BAND_2GHZ
);
3116 static void ar5416DisablePciePhy(struct ath_hal
*ah
)
3118 if (!AR_SREV_9100(ah
))
3121 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x9248fc00);
3122 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x24924924);
3123 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x28000029);
3124 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x57160824);
3125 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x25980579);
3126 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x00000000);
3127 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x1aaabe40);
3128 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xbe105554);
3129 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x000e1007);
3131 REG_WRITE(ah
, AR_PCIE_SERDES2
, 0x00000000);
3134 static void ath9k_set_power_sleep(struct ath_hal
*ah
, int setChip
)
3136 REG_SET_BIT(ah
, AR_STA_ID1
, AR_STA_ID1_PWR_SAV
);
3138 REG_CLR_BIT(ah
, AR_RTC_FORCE_WAKE
,
3139 AR_RTC_FORCE_WAKE_EN
);
3140 if (!AR_SREV_9100(ah
))
3141 REG_WRITE(ah
, AR_RC
, AR_RC_AHB
| AR_RC_HOSTIF
);
3143 REG_CLR_BIT(ah
, (u_int16_t
) (AR_RTC_RESET
),
3148 static void ath9k_set_power_network_sleep(struct ath_hal
*ah
, int setChip
)
3150 REG_SET_BIT(ah
, AR_STA_ID1
, AR_STA_ID1_PWR_SAV
);
3152 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
3154 if (!pCap
->halAutoSleepSupport
) {
3155 REG_WRITE(ah
, AR_RTC_FORCE_WAKE
,
3156 AR_RTC_FORCE_WAKE_ON_INT
);
3158 REG_CLR_BIT(ah
, AR_RTC_FORCE_WAKE
,
3159 AR_RTC_FORCE_WAKE_EN
);
3164 static bool ath9k_hw_set_power_awake(struct ath_hal
*ah
,
3171 if ((REG_READ(ah
, AR_RTC_STATUS
) & AR_RTC_STATUS_M
) ==
3172 AR_RTC_STATUS_SHUTDOWN
) {
3173 if (ath9k_hw_set_reset_reg(ah
, HAL_RESET_POWER_ON
)
3178 if (AR_SREV_9100(ah
))
3179 REG_SET_BIT(ah
, AR_RTC_RESET
,
3182 REG_SET_BIT(ah
, AR_RTC_FORCE_WAKE
,
3183 AR_RTC_FORCE_WAKE_EN
);
3186 for (i
= POWER_UP_TIME
/ 50; i
> 0; i
--) {
3187 val
= REG_READ(ah
, AR_RTC_STATUS
) & AR_RTC_STATUS_M
;
3188 if (val
== AR_RTC_STATUS_ON
)
3191 REG_SET_BIT(ah
, AR_RTC_FORCE_WAKE
,
3192 AR_RTC_FORCE_WAKE_EN
);
3195 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
3196 "%s: Failed to wakeup in %uus\n",
3197 __func__
, POWER_UP_TIME
/ 20);
3202 REG_CLR_BIT(ah
, AR_STA_ID1
, AR_STA_ID1_PWR_SAV
);
3206 bool ath9k_hw_setpower(struct ath_hal
*ah
,
3207 enum hal_power_mode mode
)
3209 struct ath_hal_5416
*ahp
= AH5416(ah
);
3210 static const char *modes
[] = {
3216 int status
= true, setChip
= true;
3218 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
, "%s: %s -> %s (%s)\n", __func__
,
3219 modes
[ahp
->ah_powerMode
], modes
[mode
],
3220 setChip
? "set chip " : "");
3224 status
= ath9k_hw_set_power_awake(ah
, setChip
);
3226 case HAL_PM_FULL_SLEEP
:
3227 ath9k_set_power_sleep(ah
, setChip
);
3228 ahp
->ah_chipFullSleep
= true;
3230 case HAL_PM_NETWORK_SLEEP
:
3231 ath9k_set_power_network_sleep(ah
, setChip
);
3234 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
3235 "%s: unknown power mode %u\n", __func__
, mode
);
3238 ahp
->ah_powerMode
= mode
;
3242 static struct ath_hal
*ath9k_hw_do_attach(u_int16_t devid
,
3243 struct ath_softc
*sc
,
3245 enum hal_status
*status
)
3247 struct ath_hal_5416
*ahp
;
3249 enum hal_status ecode
;
3250 #ifndef CONFIG_SLOW_ANT_DIV
3255 ahp
= ath9k_hw_newstate(devid
, sc
, mem
, status
);
3261 ath9k_hw_set_defaults(ah
);
3263 if (ah
->ah_config
.ath_hal_intrMitigation
!= 0)
3264 ahp
->ah_intrMitigation
= true;
3266 if (!ath9k_hw_set_reset_reg(ah
, HAL_RESET_POWER_ON
)) {
3267 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: couldn't reset chip\n",
3273 if (!ath9k_hw_setpower(ah
, HAL_PM_AWAKE
)) {
3274 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: couldn't wakeup chip\n",
3280 if (ah
->ah_config
.ath_hal_serializeRegMode
== SER_REG_MODE_AUTO
) {
3281 if (ah
->ah_macVersion
== AR_SREV_VERSION_5416_PCI
) {
3282 ah
->ah_config
.ath_hal_serializeRegMode
=
3285 ah
->ah_config
.ath_hal_serializeRegMode
=
3289 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
3290 "%s: ath_hal_serializeRegMode is %d\n",
3291 __func__
, ah
->ah_config
.ath_hal_serializeRegMode
);
3293 if ((ah
->ah_macVersion
!= AR_SREV_VERSION_5416_PCI
) &&
3294 (ah
->ah_macVersion
!= AR_SREV_VERSION_5416_PCIE
) &&
3295 (ah
->ah_macVersion
!= AR_SREV_VERSION_9160
) &&
3296 (!AR_SREV_9100(ah
)) && (!AR_SREV_9280(ah
))) {
3297 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
3298 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3299 "this driver\n", __func__
,
3300 ah
->ah_macVersion
, ah
->ah_macRev
);
3301 ecode
= HAL_ENOTSUPP
;
3305 if (AR_SREV_9100(ah
)) {
3306 ahp
->ah_iqCalData
.calData
= &iq_cal_multi_sample
;
3307 ahp
->ah_suppCals
= IQ_MISMATCH_CAL
;
3308 ah
->ah_isPciExpress
= false;
3310 ah
->ah_phyRev
= REG_READ(ah
, AR_PHY_CHIP_ID
);
3312 if (AR_SREV_9160_10_OR_LATER(ah
)) {
3313 if (AR_SREV_9280_10_OR_LATER(ah
)) {
3314 ahp
->ah_iqCalData
.calData
= &iq_cal_single_sample
;
3315 ahp
->ah_adcGainCalData
.calData
=
3316 &adc_gain_cal_single_sample
;
3317 ahp
->ah_adcDcCalData
.calData
=
3318 &adc_dc_cal_single_sample
;
3319 ahp
->ah_adcDcCalInitData
.calData
=
3322 ahp
->ah_iqCalData
.calData
= &iq_cal_multi_sample
;
3323 ahp
->ah_adcGainCalData
.calData
=
3324 &adc_gain_cal_multi_sample
;
3325 ahp
->ah_adcDcCalData
.calData
=
3326 &adc_dc_cal_multi_sample
;
3327 ahp
->ah_adcDcCalInitData
.calData
=
3331 ADC_GAIN_CAL
| ADC_DC_CAL
| IQ_MISMATCH_CAL
;
3334 if (AR_SREV_9160(ah
)) {
3335 ah
->ah_config
.ath_hal_enableANI
= 1;
3336 ahp
->ah_ani_function
= (HAL_ANI_SPUR_IMMUNITY_LEVEL
|
3337 HAL_ANI_FIRSTEP_LEVEL
);
3339 ahp
->ah_ani_function
= HAL_ANI_ALL
;
3340 if (AR_SREV_9280_10_OR_LATER(ah
)) {
3341 ahp
->ah_ani_function
&=
3342 ~HAL_ANI_NOISE_IMMUNITY_LEVEL
;
3346 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
3347 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__
,
3348 ah
->ah_macVersion
, ah
->ah_macRev
);
3350 if (AR_SREV_9280_20_OR_LATER(ah
)) {
3351 INIT_INI_ARRAY(&ahp
->ah_iniModes
, ar9280Modes_9280_2
,
3352 ARRAY_SIZE(ar9280Modes_9280_2
), 6);
3353 INIT_INI_ARRAY(&ahp
->ah_iniCommon
, ar9280Common_9280_2
,
3354 ARRAY_SIZE(ar9280Common_9280_2
), 2);
3356 if (ah
->ah_config
.ath_hal_pcieClockReq
) {
3357 INIT_INI_ARRAY(&ahp
->ah_iniPcieSerdes
,
3358 ar9280PciePhy_clkreq_off_L1_9280
,
3360 (ar9280PciePhy_clkreq_off_L1_9280
),
3363 INIT_INI_ARRAY(&ahp
->ah_iniPcieSerdes
,
3364 ar9280PciePhy_clkreq_always_on_L1_9280
,
3366 (ar9280PciePhy_clkreq_always_on_L1_9280
),
3369 INIT_INI_ARRAY(&ahp
->ah_iniModesAdditional
,
3370 ar9280Modes_fast_clock_9280_2
,
3371 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2
),
3373 } else if (AR_SREV_9280_10_OR_LATER(ah
)) {
3374 INIT_INI_ARRAY(&ahp
->ah_iniModes
, ar9280Modes_9280
,
3375 ARRAY_SIZE(ar9280Modes_9280
), 6);
3376 INIT_INI_ARRAY(&ahp
->ah_iniCommon
, ar9280Common_9280
,
3377 ARRAY_SIZE(ar9280Common_9280
), 2);
3378 } else if (AR_SREV_9160_10_OR_LATER(ah
)) {
3379 INIT_INI_ARRAY(&ahp
->ah_iniModes
, ar5416Modes_9160
,
3380 ARRAY_SIZE(ar5416Modes_9160
), 6);
3381 INIT_INI_ARRAY(&ahp
->ah_iniCommon
, ar5416Common_9160
,
3382 ARRAY_SIZE(ar5416Common_9160
), 2);
3383 INIT_INI_ARRAY(&ahp
->ah_iniBank0
, ar5416Bank0_9160
,
3384 ARRAY_SIZE(ar5416Bank0_9160
), 2);
3385 INIT_INI_ARRAY(&ahp
->ah_iniBB_RfGain
, ar5416BB_RfGain_9160
,
3386 ARRAY_SIZE(ar5416BB_RfGain_9160
), 3);
3387 INIT_INI_ARRAY(&ahp
->ah_iniBank1
, ar5416Bank1_9160
,
3388 ARRAY_SIZE(ar5416Bank1_9160
), 2);
3389 INIT_INI_ARRAY(&ahp
->ah_iniBank2
, ar5416Bank2_9160
,
3390 ARRAY_SIZE(ar5416Bank2_9160
), 2);
3391 INIT_INI_ARRAY(&ahp
->ah_iniBank3
, ar5416Bank3_9160
,
3392 ARRAY_SIZE(ar5416Bank3_9160
), 3);
3393 INIT_INI_ARRAY(&ahp
->ah_iniBank6
, ar5416Bank6_9160
,
3394 ARRAY_SIZE(ar5416Bank6_9160
), 3);
3395 INIT_INI_ARRAY(&ahp
->ah_iniBank6TPC
, ar5416Bank6TPC_9160
,
3396 ARRAY_SIZE(ar5416Bank6TPC_9160
), 3);
3397 INIT_INI_ARRAY(&ahp
->ah_iniBank7
, ar5416Bank7_9160
,
3398 ARRAY_SIZE(ar5416Bank7_9160
), 2);
3399 if (AR_SREV_9160_11(ah
)) {
3400 INIT_INI_ARRAY(&ahp
->ah_iniAddac
,
3401 ar5416Addac_91601_1
,
3402 ARRAY_SIZE(ar5416Addac_91601_1
), 2);
3404 INIT_INI_ARRAY(&ahp
->ah_iniAddac
, ar5416Addac_9160
,
3405 ARRAY_SIZE(ar5416Addac_9160
), 2);
3407 } else if (AR_SREV_9100_OR_LATER(ah
)) {
3408 INIT_INI_ARRAY(&ahp
->ah_iniModes
, ar5416Modes_9100
,
3409 ARRAY_SIZE(ar5416Modes_9100
), 6);
3410 INIT_INI_ARRAY(&ahp
->ah_iniCommon
, ar5416Common_9100
,
3411 ARRAY_SIZE(ar5416Common_9100
), 2);
3412 INIT_INI_ARRAY(&ahp
->ah_iniBank0
, ar5416Bank0_9100
,
3413 ARRAY_SIZE(ar5416Bank0_9100
), 2);
3414 INIT_INI_ARRAY(&ahp
->ah_iniBB_RfGain
, ar5416BB_RfGain_9100
,
3415 ARRAY_SIZE(ar5416BB_RfGain_9100
), 3);
3416 INIT_INI_ARRAY(&ahp
->ah_iniBank1
, ar5416Bank1_9100
,
3417 ARRAY_SIZE(ar5416Bank1_9100
), 2);
3418 INIT_INI_ARRAY(&ahp
->ah_iniBank2
, ar5416Bank2_9100
,
3419 ARRAY_SIZE(ar5416Bank2_9100
), 2);
3420 INIT_INI_ARRAY(&ahp
->ah_iniBank3
, ar5416Bank3_9100
,
3421 ARRAY_SIZE(ar5416Bank3_9100
), 3);
3422 INIT_INI_ARRAY(&ahp
->ah_iniBank6
, ar5416Bank6_9100
,
3423 ARRAY_SIZE(ar5416Bank6_9100
), 3);
3424 INIT_INI_ARRAY(&ahp
->ah_iniBank6TPC
, ar5416Bank6TPC_9100
,
3425 ARRAY_SIZE(ar5416Bank6TPC_9100
), 3);
3426 INIT_INI_ARRAY(&ahp
->ah_iniBank7
, ar5416Bank7_9100
,
3427 ARRAY_SIZE(ar5416Bank7_9100
), 2);
3428 INIT_INI_ARRAY(&ahp
->ah_iniAddac
, ar5416Addac_9100
,
3429 ARRAY_SIZE(ar5416Addac_9100
), 2);
3431 INIT_INI_ARRAY(&ahp
->ah_iniModes
, ar5416Modes
,
3432 ARRAY_SIZE(ar5416Modes
), 6);
3433 INIT_INI_ARRAY(&ahp
->ah_iniCommon
, ar5416Common
,
3434 ARRAY_SIZE(ar5416Common
), 2);
3435 INIT_INI_ARRAY(&ahp
->ah_iniBank0
, ar5416Bank0
,
3436 ARRAY_SIZE(ar5416Bank0
), 2);
3437 INIT_INI_ARRAY(&ahp
->ah_iniBB_RfGain
, ar5416BB_RfGain
,
3438 ARRAY_SIZE(ar5416BB_RfGain
), 3);
3439 INIT_INI_ARRAY(&ahp
->ah_iniBank1
, ar5416Bank1
,
3440 ARRAY_SIZE(ar5416Bank1
), 2);
3441 INIT_INI_ARRAY(&ahp
->ah_iniBank2
, ar5416Bank2
,
3442 ARRAY_SIZE(ar5416Bank2
), 2);
3443 INIT_INI_ARRAY(&ahp
->ah_iniBank3
, ar5416Bank3
,
3444 ARRAY_SIZE(ar5416Bank3
), 3);
3445 INIT_INI_ARRAY(&ahp
->ah_iniBank6
, ar5416Bank6
,
3446 ARRAY_SIZE(ar5416Bank6
), 3);
3447 INIT_INI_ARRAY(&ahp
->ah_iniBank6TPC
, ar5416Bank6TPC
,
3448 ARRAY_SIZE(ar5416Bank6TPC
), 3);
3449 INIT_INI_ARRAY(&ahp
->ah_iniBank7
, ar5416Bank7
,
3450 ARRAY_SIZE(ar5416Bank7
), 2);
3451 INIT_INI_ARRAY(&ahp
->ah_iniAddac
, ar5416Addac
,
3452 ARRAY_SIZE(ar5416Addac
), 2);
3455 if (ah
->ah_isPciExpress
)
3456 ath9k_hw_configpcipowersave(ah
, 0);
3458 ar5416DisablePciePhy(ah
);
3460 ecode
= ath9k_hw_post_attach(ah
);
3461 if (ecode
!= HAL_OK
)
3464 #ifndef CONFIG_SLOW_ANT_DIV
3465 if (ah
->ah_devid
== AR9280_DEVID_PCI
) {
3466 for (i
= 0; i
< ahp
->ah_iniModes
.ia_rows
; i
++) {
3467 u_int32_t reg
= INI_RA(&ahp
->ah_iniModes
, i
, 0);
3469 for (j
= 1; j
< ahp
->ah_iniModes
.ia_columns
; j
++) {
3470 u_int32_t val
= INI_RA(&ahp
->ah_iniModes
, i
, j
);
3472 INI_RA(&ahp
->ah_iniModes
, i
, j
) =
3473 ath9k_hw_ini_fixup(ah
, &ahp
->ah_eeprom
,
3480 if (!ath9k_hw_fill_cap_info(ah
)) {
3481 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
3482 "%s:failed ath9k_hw_fill_cap_info\n", __func__
);
3487 ecode
= ath9k_hw_init_macaddr(ah
);
3488 if (ecode
!= HAL_OK
) {
3489 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
3490 "%s: failed initializing mac address\n",
3495 if (AR_SREV_9285(ah
))
3496 ah
->ah_txTrigLevel
= (AR_FTRIG_256B
>> AR_FTRIG_S
);
3498 ah
->ah_txTrigLevel
= (AR_FTRIG_512B
>> AR_FTRIG_S
);
3500 #ifndef ATH_NF_PER_CHAN
3502 ath9k_init_nfcal_hist_buffer(ah
);
3509 ath9k_hw_detach((struct ath_hal
*) ahp
);
3515 void ath9k_hw_detach(struct ath_hal
*ah
)
3517 if (!AR_SREV_9100(ah
))
3518 ath9k_hw_ani_detach(ah
);
3519 ath9k_hw_rfdetach(ah
);
3521 ath9k_hw_setpower(ah
, HAL_PM_FULL_SLEEP
);
3525 bool ath9k_get_channel_edges(struct ath_hal
*ah
,
3526 u_int16_t flags
, u_int16_t
*low
,
3529 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
3531 if (flags
& CHANNEL_5GHZ
) {
3532 *low
= pCap
->halLow5GhzChan
;
3533 *high
= pCap
->halHigh5GhzChan
;
3536 if ((flags
& CHANNEL_2GHZ
)) {
3537 *low
= pCap
->halLow2GhzChan
;
3538 *high
= pCap
->halHigh2GhzChan
;
3545 static inline bool ath9k_hw_fill_vpd_table(u_int8_t pwrMin
,
3551 u_int8_t
*pRetVpdList
)
3554 u_int8_t currPwr
= pwrMin
;
3555 u_int16_t idxL
= 0, idxR
= 0;
3557 for (i
= 0; i
<= (pwrMax
- pwrMin
) / 2; i
++) {
3558 ath9k_hw_get_lower_upper_index(currPwr
, pPwrList
,
3559 numIntercepts
, &(idxL
),
3563 if (idxL
== numIntercepts
- 1)
3564 idxL
= (u_int16_t
) (numIntercepts
- 2);
3565 if (pPwrList
[idxL
] == pPwrList
[idxR
])
3568 k
= (u_int16_t
) (((currPwr
-
3572 currPwr
) * pVpdList
[idxL
]) /
3575 pRetVpdList
[i
] = (u_int8_t
) k
;
3583 ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal
*ah
,
3584 struct hal_channel_internal
*chan
,
3585 struct cal_data_per_freq
*pRawDataSet
,
3587 u_int16_t availPiers
,
3588 u_int16_t tPdGainOverlap
,
3589 int16_t *pMinCalPower
,
3590 u_int16_t
*pPdGainBoundaries
,
3591 u_int8_t
*pPDADCValues
,
3592 u_int16_t numXpdGains
)
3596 u_int16_t idxL
= 0, idxR
= 0, numPiers
;
3597 static u_int8_t vpdTableL
[AR5416_NUM_PD_GAINS
]
3598 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
3599 static u_int8_t vpdTableR
[AR5416_NUM_PD_GAINS
]
3600 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
3601 static u_int8_t vpdTableI
[AR5416_NUM_PD_GAINS
]
3602 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
3604 u_int8_t
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
3605 u_int8_t minPwrT4
[AR5416_NUM_PD_GAINS
];
3606 u_int8_t maxPwrT4
[AR5416_NUM_PD_GAINS
];
3609 u_int16_t sizeCurrVpdTable
, maxIndex
, tgtIndex
;
3611 int16_t minDelta
= 0;
3612 struct chan_centers centers
;
3614 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
3616 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
3617 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
3621 match
= ath9k_hw_get_lower_upper_index((u_int8_t
)
3626 numPiers
, &idxL
, &idxR
);
3629 for (i
= 0; i
< numXpdGains
; i
++) {
3630 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
3631 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
3632 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
3637 AR5416_PD_GAIN_ICEPTS
,
3641 for (i
= 0; i
< numXpdGains
; i
++) {
3642 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
3643 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
3644 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
3645 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
3647 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
3650 min(pPwrL
[AR5416_PD_GAIN_ICEPTS
- 1],
3651 pPwrR
[AR5416_PD_GAIN_ICEPTS
- 1]);
3654 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
3656 AR5416_PD_GAIN_ICEPTS
,
3658 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
3660 AR5416_PD_GAIN_ICEPTS
,
3663 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
3665 (u_int8_t
) (ath9k_hw_interpolate
3672 bChans
[idxR
], vpdTableL
[i
]
3679 *pMinCalPower
= (int16_t) (minPwrT4
[0] / 2);
3682 for (i
= 0; i
< numXpdGains
; i
++) {
3683 if (i
== (numXpdGains
- 1))
3684 pPdGainBoundaries
[i
] =
3685 (u_int16_t
) (maxPwrT4
[i
] / 2);
3687 pPdGainBoundaries
[i
] =
3688 (u_int16_t
) ((maxPwrT4
[i
] +
3689 minPwrT4
[i
+ 1]) / 4);
3691 pPdGainBoundaries
[i
] =
3692 min((u_int16_t
) AR5416_MAX_RATE_POWER
,
3693 pPdGainBoundaries
[i
]);
3695 if ((i
== 0) && !AR_SREV_5416_V20_OR_LATER(ah
)) {
3696 minDelta
= pPdGainBoundaries
[0] - 23;
3697 pPdGainBoundaries
[0] = 23;
3703 if (AR_SREV_9280_10_OR_LATER(ah
))
3704 ss
= (int16_t) (0 - (minPwrT4
[i
] / 2));
3708 ss
= (int16_t) ((pPdGainBoundaries
[i
- 1] -
3709 (minPwrT4
[i
] / 2)) -
3710 tPdGainOverlap
+ 1 + minDelta
);
3712 vpdStep
= (int16_t) (vpdTableI
[i
][1] - vpdTableI
[i
][0]);
3713 vpdStep
= (int16_t) ((vpdStep
< 1) ? 1 : vpdStep
);
3715 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
3716 tmpVal
= (int16_t) (vpdTableI
[i
][0] + ss
* vpdStep
);
3718 (u_int8_t
) ((tmpVal
< 0) ? 0 : tmpVal
);
3723 (u_int8_t
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
3724 tgtIndex
= (u_int8_t
) (pPdGainBoundaries
[i
] + tPdGainOverlap
-
3726 maxIndex
= (tgtIndex
<
3727 sizeCurrVpdTable
) ? tgtIndex
: sizeCurrVpdTable
;
3729 while ((ss
< maxIndex
)
3730 && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
3731 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
3734 vpdStep
= (int16_t) (vpdTableI
[i
][sizeCurrVpdTable
- 1] -
3735 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
3736 vpdStep
= (int16_t) ((vpdStep
< 1) ? 1 : vpdStep
);
3738 if (tgtIndex
> maxIndex
) {
3739 while ((ss
<= tgtIndex
)
3740 && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
3741 tmpVal
= (int16_t) ((vpdTableI
[i
]
3743 1] + (ss
- maxIndex
+
3745 pPDADCValues
[k
++] = (u_int8_t
) ((tmpVal
>
3746 255) ? 255 : tmpVal
);
3752 while (i
< AR5416_PD_GAINS_IN_MASK
) {
3753 pPdGainBoundaries
[i
] = pPdGainBoundaries
[i
- 1];
3757 while (k
< AR5416_NUM_PDADC_VALUES
) {
3758 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
3765 ath9k_hw_set_power_cal_table(struct ath_hal
*ah
,
3766 struct ar5416_eeprom
*pEepData
,
3767 struct hal_channel_internal
*chan
,
3768 int16_t *pTxPowerIndexOffset
)
3770 struct cal_data_per_freq
*pRawDataset
;
3771 u_int8_t
*pCalBChans
= NULL
;
3772 u_int16_t pdGainOverlap_t2
;
3773 static u_int8_t pdadcValues
[AR5416_NUM_PDADC_VALUES
];
3774 u_int16_t gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
3775 u_int16_t numPiers
, i
, j
;
3776 int16_t tMinCalPower
;
3777 u_int16_t numXpdGain
, xpdMask
;
3778 u_int16_t xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
3779 u_int32_t reg32
, regOffset
, regChainOffset
;
3781 struct ath_hal_5416
*ahp
= AH5416(ah
);
3783 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
3784 xpdMask
= pEepData
->modalHeader
[modalIdx
].xpdGain
;
3786 if ((pEepData
->baseEepHeader
.
3787 version
& AR5416_EEP_VER_MINOR_MASK
) >=
3788 AR5416_EEP_MINOR_VER_2
) {
3790 pEepData
->modalHeader
[modalIdx
].pdGainOverlap
;
3794 (REG_READ(ah
, AR_PHY_TPCRG5
),
3795 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
3798 if (IS_CHAN_2GHZ(chan
)) {
3799 pCalBChans
= pEepData
->calFreqPier2G
;
3800 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
3802 pCalBChans
= pEepData
->calFreqPier5G
;
3803 numPiers
= AR5416_NUM_5G_CAL_PIERS
;
3808 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
3809 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
3810 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
3812 xpdGainValues
[numXpdGain
] =
3813 (u_int16_t
) (AR5416_PD_GAINS_IN_MASK
- i
);
3818 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
3819 (numXpdGain
- 1) & 0x3);
3820 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
3822 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
3824 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
3827 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
3828 if (AR_SREV_5416_V20_OR_LATER(ah
) &&
3829 (ahp
->ah_rxchainmask
== 5 || ahp
->ah_txchainmask
== 5)
3831 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
3833 regChainOffset
= i
* 0x1000;
3834 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
3835 if (IS_CHAN_2GHZ(chan
))
3836 pRawDataset
= pEepData
->calPierData2G
[i
];
3838 pRawDataset
= pEepData
->calPierData5G
[i
];
3840 ath9k_hw_get_gain_boundaries_pdadcs(ah
, chan
,
3850 if ((i
== 0) || AR_SREV_5416_V20_OR_LATER(ah
)) {
3853 AR_PHY_TPCRG5
+ regChainOffset
,
3854 SM(pdGainOverlap_t2
,
3855 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)
3856 | SM(gainBoundaries
[0],
3857 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
3858 | SM(gainBoundaries
[1],
3859 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
3860 | SM(gainBoundaries
[2],
3861 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
3862 | SM(gainBoundaries
[3],
3863 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
3867 AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
3868 for (j
= 0; j
< 32; j
++) {
3870 ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0)
3871 | ((pdadcValues
[4 * j
+ 1] & 0xFF) <<
3872 8) | ((pdadcValues
[4 * j
+ 2] &
3874 ((pdadcValues
[4 * j
+ 3] & 0xFF) <<
3876 REG_WRITE(ah
, regOffset
, reg32
);
3878 DPRINTF(ah
->ah_sc
, ATH_DBG_PHY_IO
,
3879 "PDADC (%d,%4x): %4.4x %8.8x\n",
3880 i
, regChainOffset
, regOffset
,
3882 DPRINTF(ah
->ah_sc
, ATH_DBG_PHY_IO
,
3883 "PDADC: Chain %d | PDADC %3d Value %3d | "
3884 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3885 "PDADC %3d Value %3d |\n",
3886 i
, 4 * j
, pdadcValues
[4 * j
],
3887 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
3888 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
3890 pdadcValues
[4 * j
+ 3]);
3896 *pTxPowerIndexOffset
= 0;
3901 void ath9k_hw_configpcipowersave(struct ath_hal
*ah
, int restore
)
3903 struct ath_hal_5416
*ahp
= AH5416(ah
);
3906 if (ah
->ah_isPciExpress
!= true)
3909 if (ah
->ah_config
.ath_hal_pciePowerSaveEnable
== 2)
3915 if (AR_SREV_9280_20_OR_LATER(ah
)) {
3916 for (i
= 0; i
< ahp
->ah_iniPcieSerdes
.ia_rows
; i
++) {
3917 REG_WRITE(ah
, INI_RA(&ahp
->ah_iniPcieSerdes
, i
, 0),
3918 INI_RA(&ahp
->ah_iniPcieSerdes
, i
, 1));
3921 } else if (AR_SREV_9280(ah
)
3922 && (ah
->ah_macRev
== AR_SREV_REVISION_9280_10
)) {
3923 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x9248fd00);
3924 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x24924924);
3926 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xa8000019);
3927 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x13160820);
3928 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xe5980560);
3930 if (ah
->ah_config
.ath_hal_pcieClockReq
)
3931 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x401deffc);
3933 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x401deffd);
3935 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x1aaabe40);
3936 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xbe105554);
3937 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x00043007);
3939 REG_WRITE(ah
, AR_PCIE_SERDES2
, 0x00000000);
3943 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x9248fc00);
3944 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x24924924);
3945 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x28000039);
3946 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x53160824);
3947 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xe5980579);
3948 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x001defff);
3949 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x1aaabe40);
3950 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xbe105554);
3951 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x000e3007);
3952 REG_WRITE(ah
, AR_PCIE_SERDES2
, 0x00000000);
3955 REG_SET_BIT(ah
, AR_PCIE_PM_CTRL
, AR_PCIE_PM_CTRL_ENA
);
3957 if (ah
->ah_config
.ath_hal_pcieWaen
) {
3958 REG_WRITE(ah
, AR_WA
, ah
->ah_config
.ath_hal_pcieWaen
);
3960 if (AR_SREV_9280(ah
))
3961 REG_WRITE(ah
, AR_WA
, 0x0040073f);
3963 REG_WRITE(ah
, AR_WA
, 0x0000073f);
3968 ath9k_hw_get_legacy_target_powers(struct ath_hal
*ah
,
3969 struct hal_channel_internal
*chan
,
3970 struct cal_target_power_leg
*powInfo
,
3971 u_int16_t numChannels
,
3972 struct cal_target_power_leg
*pNewPower
,
3978 int matchIndex
= -1, lowIndex
= -1;
3980 struct chan_centers centers
;
3982 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
3983 freq
= (isExtTarget
) ? centers
.ext_center
: centers
.ctl_center
;
3985 if (freq
<= ath9k_hw_fbin2freq(powInfo
[0].bChannel
,
3986 IS_CHAN_2GHZ(chan
))) {
3989 for (i
= 0; (i
< numChannels
)
3990 && (powInfo
[i
].bChannel
!= AR5416_BCHAN_UNUSED
); i
++) {
3992 ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
3993 IS_CHAN_2GHZ(chan
))) {
3997 ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
3998 IS_CHAN_2GHZ(chan
)))
4000 ath9k_hw_fbin2freq(powInfo
[i
- 1].
4008 if ((matchIndex
== -1) && (lowIndex
== -1))
4012 if (matchIndex
!= -1) {
4013 *pNewPower
= powInfo
[matchIndex
];
4015 clo
= ath9k_hw_fbin2freq(powInfo
[lowIndex
].bChannel
,
4016 IS_CHAN_2GHZ(chan
));
4017 chi
= ath9k_hw_fbin2freq(powInfo
[lowIndex
+ 1].bChannel
,
4018 IS_CHAN_2GHZ(chan
));
4020 for (i
= 0; i
< numRates
; i
++) {
4021 pNewPower
->tPow2x
[i
] =
4022 (u_int8_t
) ath9k_hw_interpolate(freq
, clo
, chi
,
4034 ath9k_hw_get_target_powers(struct ath_hal
*ah
,
4035 struct hal_channel_internal
*chan
,
4036 struct cal_target_power_ht
*powInfo
,
4037 u_int16_t numChannels
,
4038 struct cal_target_power_ht
*pNewPower
,
4044 int matchIndex
= -1, lowIndex
= -1;
4046 struct chan_centers centers
;
4048 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
4049 freq
= isHt40Target
? centers
.synth_center
: centers
.ctl_center
;
4052 ath9k_hw_fbin2freq(powInfo
[0].bChannel
, IS_CHAN_2GHZ(chan
))) {
4055 for (i
= 0; (i
< numChannels
)
4056 && (powInfo
[i
].bChannel
!= AR5416_BCHAN_UNUSED
); i
++) {
4058 ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
4059 IS_CHAN_2GHZ(chan
))) {
4064 ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
4065 IS_CHAN_2GHZ(chan
)))
4067 ath9k_hw_fbin2freq(powInfo
[i
- 1].
4075 if ((matchIndex
== -1) && (lowIndex
== -1))
4079 if (matchIndex
!= -1) {
4080 *pNewPower
= powInfo
[matchIndex
];
4082 clo
= ath9k_hw_fbin2freq(powInfo
[lowIndex
].bChannel
,
4083 IS_CHAN_2GHZ(chan
));
4084 chi
= ath9k_hw_fbin2freq(powInfo
[lowIndex
+ 1].bChannel
,
4085 IS_CHAN_2GHZ(chan
));
4087 for (i
= 0; i
< numRates
; i
++) {
4088 pNewPower
->tPow2x
[i
] =
4089 (u_int8_t
) ath9k_hw_interpolate(freq
, clo
, chi
,
4100 static inline u_int16_t
4101 ath9k_hw_get_max_edge_power(u_int16_t freq
,
4102 struct cal_ctl_edges
*pRdEdgesPower
,
4105 u_int16_t twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
4108 for (i
= 0; (i
< AR5416_NUM_BAND_EDGES
)
4109 && (pRdEdgesPower
[i
].bChannel
!= AR5416_BCHAN_UNUSED
); i
++) {
4110 if (freq
== ath9k_hw_fbin2freq(pRdEdgesPower
[i
].bChannel
,
4112 twiceMaxEdgePower
= pRdEdgesPower
[i
].tPower
;
4116 ath9k_hw_fbin2freq(pRdEdgesPower
[i
].
4117 bChannel
, is2GHz
))) {
4118 if (ath9k_hw_fbin2freq
4119 (pRdEdgesPower
[i
- 1].bChannel
, is2GHz
) < freq
4120 && pRdEdgesPower
[i
- 1].flag
) {
4122 pRdEdgesPower
[i
- 1].tPower
;
4127 return twiceMaxEdgePower
;
4131 ath9k_hw_set_power_per_rate_table(struct ath_hal
*ah
,
4132 struct ar5416_eeprom
*pEepData
,
4133 struct hal_channel_internal
*chan
,
4134 int16_t *ratesArray
,
4136 u_int8_t AntennaReduction
,
4137 u_int8_t twiceMaxRegulatoryPower
,
4138 u_int8_t powerLimit
)
4140 u_int8_t twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
4141 static const u_int16_t tpScaleReductionTable
[5] =
4142 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
4145 int8_t twiceLargestAntenna
;
4146 struct cal_ctl_data
*rep
;
4147 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
4150 struct cal_target_power_leg targetPowerOfdmExt
= {
4151 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
4154 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
4157 u_int8_t scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
4158 u_int16_t ctlModesFor11a
[] =
4159 { CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
};
4160 u_int16_t ctlModesFor11g
[] =
4161 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
4164 u_int16_t numCtlModes
, *pCtlMode
, ctlMode
, freq
;
4165 struct chan_centers centers
;
4167 u_int8_t twiceMinEdgePower
;
4168 struct ath_hal_5416
*ahp
= AH5416(ah
);
4170 tx_chainmask
= ahp
->ah_txchainmask
;
4172 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
4174 twiceLargestAntenna
= max(
4175 pEepData
->modalHeader
4176 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[0],
4177 pEepData
->modalHeader
4178 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[1]);
4180 twiceLargestAntenna
= max((u_int8_t
) twiceLargestAntenna
,
4181 pEepData
->modalHeader
4182 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[2]);
4184 twiceLargestAntenna
=
4185 (int8_t) min(AntennaReduction
- twiceLargestAntenna
, 0);
4187 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
4189 if (ah
->ah_tpScale
!= HAL_TP_SCALE_MAX
) {
4190 maxRegAllowedPower
-=
4191 (tpScaleReductionTable
[(ah
->ah_tpScale
)] * 2);
4194 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
4196 switch (ar5416_get_ntxchains(tx_chainmask
)) {
4201 pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)].
4202 pwrDecreaseFor2Chain
;
4206 pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)].
4207 pwrDecreaseFor3Chain
;
4211 scaledPower
= max(0, (int32_t) scaledPower
);
4213 if (IS_CHAN_2GHZ(chan
)) {
4215 ARRAY_SIZE(ctlModesFor11g
) -
4216 SUB_NUM_CTL_MODES_AT_2G_40
;
4217 pCtlMode
= ctlModesFor11g
;
4219 ath9k_hw_get_legacy_target_powers(ah
, chan
,
4222 AR5416_NUM_2G_CCK_TARGET_POWERS
,
4225 ath9k_hw_get_legacy_target_powers(ah
, chan
,
4228 AR5416_NUM_2G_20_TARGET_POWERS
,
4229 &targetPowerOfdm
, 4,
4231 ath9k_hw_get_target_powers(ah
, chan
,
4232 pEepData
->calTargetPower2GHT20
,
4233 AR5416_NUM_2G_20_TARGET_POWERS
,
4234 &targetPowerHt20
, 8, false);
4236 if (IS_CHAN_HT40(chan
)) {
4237 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
4238 ath9k_hw_get_target_powers(ah
, chan
,
4240 calTargetPower2GHT40
,
4241 AR5416_NUM_2G_40_TARGET_POWERS
,
4242 &targetPowerHt40
, 8,
4244 ath9k_hw_get_legacy_target_powers(ah
, chan
,
4247 AR5416_NUM_2G_CCK_TARGET_POWERS
,
4250 ath9k_hw_get_legacy_target_powers(ah
, chan
,
4253 AR5416_NUM_2G_20_TARGET_POWERS
,
4254 &targetPowerOfdmExt
,
4260 ARRAY_SIZE(ctlModesFor11a
) -
4261 SUB_NUM_CTL_MODES_AT_5G_40
;
4262 pCtlMode
= ctlModesFor11a
;
4264 ath9k_hw_get_legacy_target_powers(ah
, chan
,
4267 AR5416_NUM_5G_20_TARGET_POWERS
,
4268 &targetPowerOfdm
, 4,
4270 ath9k_hw_get_target_powers(ah
, chan
,
4271 pEepData
->calTargetPower5GHT20
,
4272 AR5416_NUM_5G_20_TARGET_POWERS
,
4273 &targetPowerHt20
, 8, false);
4275 if (IS_CHAN_HT40(chan
)) {
4276 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
4277 ath9k_hw_get_target_powers(ah
, chan
,
4279 calTargetPower5GHT40
,
4280 AR5416_NUM_5G_40_TARGET_POWERS
,
4281 &targetPowerHt40
, 8,
4283 ath9k_hw_get_legacy_target_powers(ah
, chan
,
4286 AR5416_NUM_5G_20_TARGET_POWERS
,
4287 &targetPowerOfdmExt
,
4292 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
4293 bool isHt40CtlMode
=
4294 (pCtlMode
[ctlMode
] == CTL_5GHT40
)
4295 || (pCtlMode
[ctlMode
] == CTL_2GHT40
);
4297 freq
= centers
.synth_center
;
4298 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
4299 freq
= centers
.ext_center
;
4301 freq
= centers
.ctl_center
;
4303 if (ar5416_get_eep_ver(ahp
) == 14
4304 && ar5416_get_eep_rev(ahp
) <= 2)
4305 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
4307 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
4308 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4309 "EXT_ADDITIVE %d\n",
4310 ctlMode
, numCtlModes
, isHt40CtlMode
,
4311 (pCtlMode
[ctlMode
] & EXT_ADDITIVE
));
4313 for (i
= 0; (i
< AR5416_NUM_CTLS
) && pEepData
->ctlIndex
[i
];
4315 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
4316 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4317 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4318 "chan %d chanctl 0x%x\n",
4319 i
, cfgCtl
, pCtlMode
[ctlMode
],
4320 pEepData
->ctlIndex
[i
], chan
->channel
,
4321 chan
->conformanceTestLimit
);
4323 if ((((cfgCtl
& ~CTL_MODE_M
) |
4324 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
4325 pEepData
->ctlIndex
[i
])
4327 (((cfgCtl
& ~CTL_MODE_M
) |
4328 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
4330 ctlIndex
[i
] & CTL_MODE_M
) | SD_NO_CTL
))) {
4331 rep
= &(pEepData
->ctlData
[i
]);
4334 ath9k_hw_get_max_edge_power(freq
,
4337 [ar5416_get_ntxchains
4343 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
4344 " MATCH-EE_IDX %d: ch %d is2 %d "
4345 "2xMinEdge %d chainmask %d chains %d\n",
4346 i
, freq
, IS_CHAN_2GHZ(chan
),
4347 twiceMinEdgePower
, tx_chainmask
,
4348 ar5416_get_ntxchains
4350 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
4352 min(twiceMaxEdgePower
,
4362 minCtlPower
= min(twiceMaxEdgePower
, scaledPower
);
4364 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
4365 " SEL-Min ctlMode %d pCtlMode %d "
4366 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4367 ctlMode
, pCtlMode
[ctlMode
], twiceMaxEdgePower
,
4368 scaledPower
, minCtlPower
);
4370 switch (pCtlMode
[ctlMode
]) {
4372 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
);
4374 targetPowerCck
.tPow2x
[i
] =
4375 min(targetPowerCck
.tPow2x
[i
],
4381 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
);
4383 targetPowerOfdm
.tPow2x
[i
] =
4384 min(targetPowerOfdm
.tPow2x
[i
],
4390 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
);
4392 targetPowerHt20
.tPow2x
[i
] =
4393 min(targetPowerHt20
.tPow2x
[i
],
4398 targetPowerCckExt
.tPow2x
[0] =
4399 min(targetPowerCckExt
.tPow2x
[0], minCtlPower
);
4403 targetPowerOfdmExt
.tPow2x
[0] =
4404 min(targetPowerOfdmExt
.tPow2x
[0], minCtlPower
);
4408 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
);
4410 targetPowerHt40
.tPow2x
[i
] =
4411 min(targetPowerHt40
.tPow2x
[i
],
4420 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
4421 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
4422 targetPowerOfdm
.tPow2x
[0];
4423 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
4424 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
4425 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
4426 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
4428 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
4429 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
4431 if (IS_CHAN_2GHZ(chan
)) {
4432 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
4433 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
4434 targetPowerCck
.tPow2x
[1];
4435 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
4436 targetPowerCck
.tPow2x
[2];
4438 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
4439 targetPowerCck
.tPow2x
[3];
4442 if (IS_CHAN_HT40(chan
)) {
4443 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
4444 ratesArray
[rateHt40_0
+ i
] =
4445 targetPowerHt40
.tPow2x
[i
];
4447 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
4448 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
4449 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
4450 if (IS_CHAN_2GHZ(chan
)) {
4451 ratesArray
[rateExtCck
] =
4452 targetPowerCckExt
.tPow2x
[0];
4458 static enum hal_status
4459 ath9k_hw_set_txpower(struct ath_hal
*ah
,
4460 struct ar5416_eeprom
*pEepData
,
4461 struct hal_channel_internal
*chan
,
4463 u_int8_t twiceAntennaReduction
,
4464 u_int8_t twiceMaxRegulatoryPower
,
4465 u_int8_t powerLimit
)
4467 struct modal_eep_header
*pModal
=
4468 &(pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
4469 int16_t ratesArray
[Ar5416RateSize
];
4470 int16_t txPowerIndexOffset
= 0;
4471 u_int8_t ht40PowerIncForPdadc
= 2;
4474 memset(ratesArray
, 0, sizeof(ratesArray
));
4476 if ((pEepData
->baseEepHeader
.
4477 version
& AR5416_EEP_VER_MINOR_MASK
) >=
4478 AR5416_EEP_MINOR_VER_2
) {
4479 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
4482 if (!ath9k_hw_set_power_per_rate_table(ah
, pEepData
, chan
,
4483 &ratesArray
[0], cfgCtl
,
4484 twiceAntennaReduction
,
4485 twiceMaxRegulatoryPower
,
4487 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
4488 "ath9k_hw_set_txpower: unable to set "
4489 "tx power per rate table\n");
4493 if (!ath9k_hw_set_power_cal_table
4494 (ah
, pEepData
, chan
, &txPowerIndexOffset
)) {
4495 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
4496 "ath9k_hw_set_txpower: unable to set power table\n");
4500 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
4502 (int16_t) (txPowerIndexOffset
+ ratesArray
[i
]);
4503 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
4504 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
4507 if (AR_SREV_9280_10_OR_LATER(ah
)) {
4508 for (i
= 0; i
< Ar5416RateSize
; i
++)
4509 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET
* 2;
4512 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
4513 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
4514 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
4515 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
4516 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0)
4518 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
4519 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
4520 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
4521 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
4522 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0)
4525 if (IS_CHAN_2GHZ(chan
)) {
4526 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
4527 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
4528 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
4529 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
4530 | ATH9K_POW_SM(ratesArray
[rate1l
], 0)
4532 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
4533 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
4534 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
4535 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
4536 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0)
4540 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
4541 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
4542 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
4543 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
4544 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0)
4546 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
4547 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
4548 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
4549 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
4550 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0)
4553 if (IS_CHAN_HT40(chan
)) {
4554 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
4555 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
4556 ht40PowerIncForPdadc
, 24)
4557 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
4558 ht40PowerIncForPdadc
, 16)
4559 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
4560 ht40PowerIncForPdadc
, 8)
4561 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
4562 ht40PowerIncForPdadc
, 0)
4564 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
4565 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
4566 ht40PowerIncForPdadc
, 24)
4567 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
4568 ht40PowerIncForPdadc
, 16)
4569 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
4570 ht40PowerIncForPdadc
, 8)
4571 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
4572 ht40PowerIncForPdadc
, 0)
4575 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
4576 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
4577 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
4578 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
4579 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0)
4583 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
4584 ATH9K_POW_SM(pModal
->pwrDecreaseFor3Chain
, 6)
4585 | ATH9K_POW_SM(pModal
->pwrDecreaseFor2Chain
, 0)
4589 if (IS_CHAN_HT40(chan
))
4591 else if (IS_CHAN_HT20(chan
))
4594 if (AR_SREV_9280_10_OR_LATER(ah
))
4595 ah
->ah_maxPowerLevel
=
4596 ratesArray
[i
] + AR5416_PWR_TABLE_OFFSET
* 2;
4598 ah
->ah_maxPowerLevel
= ratesArray
[i
];
4603 static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal
*ah
,
4604 u_int32_t coef_scaled
,
4605 u_int32_t
*coef_mantissa
,
4606 u_int32_t
*coef_exponent
)
4608 u_int32_t coef_exp
, coef_man
;
4610 for (coef_exp
= 31; coef_exp
> 0; coef_exp
--)
4611 if ((coef_scaled
>> coef_exp
) & 0x1)
4614 coef_exp
= 14 - (coef_exp
- COEF_SCALE_S
);
4616 coef_man
= coef_scaled
+ (1 << (COEF_SCALE_S
- coef_exp
- 1));
4618 *coef_mantissa
= coef_man
>> (COEF_SCALE_S
- coef_exp
);
4619 *coef_exponent
= coef_exp
- 16;
4623 ath9k_hw_set_delta_slope(struct ath_hal
*ah
,
4624 struct hal_channel_internal
*chan
)
4626 u_int32_t coef_scaled
, ds_coef_exp
, ds_coef_man
;
4627 u_int32_t clockMhzScaled
= 0x64000000;
4628 struct chan_centers centers
;
4630 if (IS_CHAN_HALF_RATE(chan
))
4631 clockMhzScaled
= clockMhzScaled
>> 1;
4632 else if (IS_CHAN_QUARTER_RATE(chan
))
4633 clockMhzScaled
= clockMhzScaled
>> 2;
4635 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
4636 coef_scaled
= clockMhzScaled
/ centers
.synth_center
;
4638 ath9k_hw_get_delta_slope_vals(ah
, coef_scaled
, &ds_coef_man
,
4641 REG_RMW_FIELD(ah
, AR_PHY_TIMING3
,
4642 AR_PHY_TIMING3_DSC_MAN
, ds_coef_man
);
4643 REG_RMW_FIELD(ah
, AR_PHY_TIMING3
,
4644 AR_PHY_TIMING3_DSC_EXP
, ds_coef_exp
);
4646 coef_scaled
= (9 * coef_scaled
) / 10;
4648 ath9k_hw_get_delta_slope_vals(ah
, coef_scaled
, &ds_coef_man
,
4651 REG_RMW_FIELD(ah
, AR_PHY_HALFGI
,
4652 AR_PHY_HALFGI_DSC_MAN
, ds_coef_man
);
4653 REG_RMW_FIELD(ah
, AR_PHY_HALFGI
,
4654 AR_PHY_HALFGI_DSC_EXP
, ds_coef_exp
);
4657 static void ath9k_hw_9280_spur_mitigate(struct ath_hal
*ah
,
4658 struct hal_channel
*chan
,
4659 struct hal_channel_internal
*ichan
)
4661 int bb_spur
= AR_NO_SPUR
;
4664 int bb_spur_off
, spur_subchannel_sd
;
4666 int spur_delta_phase
;
4668 int upper
, lower
, cur_vit_mask
;
4671 int pilot_mask_reg
[4] = { AR_PHY_TIMING7
, AR_PHY_TIMING8
,
4672 AR_PHY_PILOT_MASK_01_30
, AR_PHY_PILOT_MASK_31_60
4674 int chan_mask_reg
[4] = { AR_PHY_TIMING9
, AR_PHY_TIMING10
,
4675 AR_PHY_CHANNEL_MASK_01_30
, AR_PHY_CHANNEL_MASK_31_60
4677 int inc
[4] = { 0, 100, 0, 0 };
4678 struct chan_centers centers
;
4685 bool is2GHz
= IS_CHAN_2GHZ(chan
);
4687 memset(&mask_m
, 0, sizeof(int8_t) * 123);
4688 memset(&mask_p
, 0, sizeof(int8_t) * 123);
4690 ath9k_hw_get_channel_centers(ah
, ichan
, ¢ers
);
4691 freq
= centers
.synth_center
;
4693 ah
->ah_config
.ath_hal_spurMode
= SPUR_ENABLE_EEPROM
;
4694 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
4695 cur_bb_spur
= ath9k_hw_eeprom_get_spur_chan(ah
, i
, is2GHz
);
4698 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_2GHZ
;
4700 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_5GHZ
;
4702 if (AR_NO_SPUR
== cur_bb_spur
)
4704 cur_bb_spur
= cur_bb_spur
- freq
;
4706 if (IS_CHAN_HT40(chan
)) {
4707 if ((cur_bb_spur
> -AR_SPUR_FEEQ_BOUND_HT40
) &&
4708 (cur_bb_spur
< AR_SPUR_FEEQ_BOUND_HT40
)) {
4709 bb_spur
= cur_bb_spur
;
4712 } else if ((cur_bb_spur
> -AR_SPUR_FEEQ_BOUND_HT20
) &&
4713 (cur_bb_spur
< AR_SPUR_FEEQ_BOUND_HT20
)) {
4714 bb_spur
= cur_bb_spur
;
4719 if (AR_NO_SPUR
== bb_spur
) {
4720 REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
,
4721 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
4724 REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
,
4725 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
4728 bin
= bb_spur
* 320;
4730 tmp
= REG_READ(ah
, AR_PHY_TIMING_CTRL4(0));
4732 newVal
= tmp
| (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI
|
4733 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER
|
4734 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK
|
4735 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK
);
4736 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0), newVal
);
4738 newVal
= (AR_PHY_SPUR_REG_MASK_RATE_CNTL
|
4739 AR_PHY_SPUR_REG_ENABLE_MASK_PPM
|
4740 AR_PHY_SPUR_REG_MASK_RATE_SELECT
|
4741 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI
|
4742 SM(SPUR_RSSI_THRESH
, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH
));
4743 REG_WRITE(ah
, AR_PHY_SPUR_REG
, newVal
);
4745 if (IS_CHAN_HT40(chan
)) {
4747 spur_subchannel_sd
= 1;
4748 bb_spur_off
= bb_spur
+ 10;
4750 spur_subchannel_sd
= 0;
4751 bb_spur_off
= bb_spur
- 10;
4754 spur_subchannel_sd
= 0;
4755 bb_spur_off
= bb_spur
;
4758 if (IS_CHAN_HT40(chan
))
4760 ((bb_spur
* 262144) /
4761 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
4764 ((bb_spur
* 524288) /
4765 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
4767 denominator
= IS_CHAN_2GHZ(chan
) ? 44 : 40;
4768 spur_freq_sd
= ((bb_spur_off
* 2048) / denominator
) & 0x3ff;
4770 newVal
= (AR_PHY_TIMING11_USE_SPUR_IN_AGC
|
4771 SM(spur_freq_sd
, AR_PHY_TIMING11_SPUR_FREQ_SD
) |
4772 SM(spur_delta_phase
, AR_PHY_TIMING11_SPUR_DELTA_PHASE
));
4773 REG_WRITE(ah
, AR_PHY_TIMING11
, newVal
);
4775 newVal
= spur_subchannel_sd
<< AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S
;
4776 REG_WRITE(ah
, AR_PHY_SFCORR_EXT
, newVal
);
4782 for (i
= 0; i
< 4; i
++) {
4786 for (bp
= 0; bp
< 30; bp
++) {
4787 if ((cur_bin
> lower
) && (cur_bin
< upper
)) {
4788 pilot_mask
= pilot_mask
| 0x1 << bp
;
4789 chan_mask
= chan_mask
| 0x1 << bp
;
4794 REG_WRITE(ah
, pilot_mask_reg
[i
], pilot_mask
);
4795 REG_WRITE(ah
, chan_mask_reg
[i
], chan_mask
);
4798 cur_vit_mask
= 6100;
4802 for (i
= 0; i
< 123; i
++) {
4803 if ((cur_vit_mask
> lower
) && (cur_vit_mask
< upper
)) {
4804 if ((abs(cur_vit_mask
- bin
)) < 75)
4808 if (cur_vit_mask
< 0)
4809 mask_m
[abs(cur_vit_mask
/ 100)] = mask_amt
;
4811 mask_p
[cur_vit_mask
/ 100] = mask_amt
;
4813 cur_vit_mask
-= 100;
4816 tmp_mask
= (mask_m
[46] << 30) | (mask_m
[47] << 28)
4817 | (mask_m
[48] << 26) | (mask_m
[49] << 24)
4818 | (mask_m
[50] << 22) | (mask_m
[51] << 20)
4819 | (mask_m
[52] << 18) | (mask_m
[53] << 16)
4820 | (mask_m
[54] << 14) | (mask_m
[55] << 12)
4821 | (mask_m
[56] << 10) | (mask_m
[57] << 8)
4822 | (mask_m
[58] << 6) | (mask_m
[59] << 4)
4823 | (mask_m
[60] << 2) | (mask_m
[61] << 0);
4824 REG_WRITE(ah
, AR_PHY_BIN_MASK_1
, tmp_mask
);
4825 REG_WRITE(ah
, AR_PHY_VIT_MASK2_M_46_61
, tmp_mask
);
4827 tmp_mask
= (mask_m
[31] << 28)
4828 | (mask_m
[32] << 26) | (mask_m
[33] << 24)
4829 | (mask_m
[34] << 22) | (mask_m
[35] << 20)
4830 | (mask_m
[36] << 18) | (mask_m
[37] << 16)
4831 | (mask_m
[48] << 14) | (mask_m
[39] << 12)
4832 | (mask_m
[40] << 10) | (mask_m
[41] << 8)
4833 | (mask_m
[42] << 6) | (mask_m
[43] << 4)
4834 | (mask_m
[44] << 2) | (mask_m
[45] << 0);
4835 REG_WRITE(ah
, AR_PHY_BIN_MASK_2
, tmp_mask
);
4836 REG_WRITE(ah
, AR_PHY_MASK2_M_31_45
, tmp_mask
);
4838 tmp_mask
= (mask_m
[16] << 30) | (mask_m
[16] << 28)
4839 | (mask_m
[18] << 26) | (mask_m
[18] << 24)
4840 | (mask_m
[20] << 22) | (mask_m
[20] << 20)
4841 | (mask_m
[22] << 18) | (mask_m
[22] << 16)
4842 | (mask_m
[24] << 14) | (mask_m
[24] << 12)
4843 | (mask_m
[25] << 10) | (mask_m
[26] << 8)
4844 | (mask_m
[27] << 6) | (mask_m
[28] << 4)
4845 | (mask_m
[29] << 2) | (mask_m
[30] << 0);
4846 REG_WRITE(ah
, AR_PHY_BIN_MASK_3
, tmp_mask
);
4847 REG_WRITE(ah
, AR_PHY_MASK2_M_16_30
, tmp_mask
);
4849 tmp_mask
= (mask_m
[0] << 30) | (mask_m
[1] << 28)
4850 | (mask_m
[2] << 26) | (mask_m
[3] << 24)
4851 | (mask_m
[4] << 22) | (mask_m
[5] << 20)
4852 | (mask_m
[6] << 18) | (mask_m
[7] << 16)
4853 | (mask_m
[8] << 14) | (mask_m
[9] << 12)
4854 | (mask_m
[10] << 10) | (mask_m
[11] << 8)
4855 | (mask_m
[12] << 6) | (mask_m
[13] << 4)
4856 | (mask_m
[14] << 2) | (mask_m
[15] << 0);
4857 REG_WRITE(ah
, AR_PHY_MASK_CTL
, tmp_mask
);
4858 REG_WRITE(ah
, AR_PHY_MASK2_M_00_15
, tmp_mask
);
4860 tmp_mask
= (mask_p
[15] << 28)
4861 | (mask_p
[14] << 26) | (mask_p
[13] << 24)
4862 | (mask_p
[12] << 22) | (mask_p
[11] << 20)
4863 | (mask_p
[10] << 18) | (mask_p
[9] << 16)
4864 | (mask_p
[8] << 14) | (mask_p
[7] << 12)
4865 | (mask_p
[6] << 10) | (mask_p
[5] << 8)
4866 | (mask_p
[4] << 6) | (mask_p
[3] << 4)
4867 | (mask_p
[2] << 2) | (mask_p
[1] << 0);
4868 REG_WRITE(ah
, AR_PHY_BIN_MASK2_1
, tmp_mask
);
4869 REG_WRITE(ah
, AR_PHY_MASK2_P_15_01
, tmp_mask
);
4871 tmp_mask
= (mask_p
[30] << 28)
4872 | (mask_p
[29] << 26) | (mask_p
[28] << 24)
4873 | (mask_p
[27] << 22) | (mask_p
[26] << 20)
4874 | (mask_p
[25] << 18) | (mask_p
[24] << 16)
4875 | (mask_p
[23] << 14) | (mask_p
[22] << 12)
4876 | (mask_p
[21] << 10) | (mask_p
[20] << 8)
4877 | (mask_p
[19] << 6) | (mask_p
[18] << 4)
4878 | (mask_p
[17] << 2) | (mask_p
[16] << 0);
4879 REG_WRITE(ah
, AR_PHY_BIN_MASK2_2
, tmp_mask
);
4880 REG_WRITE(ah
, AR_PHY_MASK2_P_30_16
, tmp_mask
);
4882 tmp_mask
= (mask_p
[45] << 28)
4883 | (mask_p
[44] << 26) | (mask_p
[43] << 24)
4884 | (mask_p
[42] << 22) | (mask_p
[41] << 20)
4885 | (mask_p
[40] << 18) | (mask_p
[39] << 16)
4886 | (mask_p
[38] << 14) | (mask_p
[37] << 12)
4887 | (mask_p
[36] << 10) | (mask_p
[35] << 8)
4888 | (mask_p
[34] << 6) | (mask_p
[33] << 4)
4889 | (mask_p
[32] << 2) | (mask_p
[31] << 0);
4890 REG_WRITE(ah
, AR_PHY_BIN_MASK2_3
, tmp_mask
);
4891 REG_WRITE(ah
, AR_PHY_MASK2_P_45_31
, tmp_mask
);
4893 tmp_mask
= (mask_p
[61] << 30) | (mask_p
[60] << 28)
4894 | (mask_p
[59] << 26) | (mask_p
[58] << 24)
4895 | (mask_p
[57] << 22) | (mask_p
[56] << 20)
4896 | (mask_p
[55] << 18) | (mask_p
[54] << 16)
4897 | (mask_p
[53] << 14) | (mask_p
[52] << 12)
4898 | (mask_p
[51] << 10) | (mask_p
[50] << 8)
4899 | (mask_p
[49] << 6) | (mask_p
[48] << 4)
4900 | (mask_p
[47] << 2) | (mask_p
[46] << 0);
4901 REG_WRITE(ah
, AR_PHY_BIN_MASK2_4
, tmp_mask
);
4902 REG_WRITE(ah
, AR_PHY_MASK2_P_61_45
, tmp_mask
);
4905 static void ath9k_hw_spur_mitigate(struct ath_hal
*ah
,
4906 struct hal_channel
*chan
)
4908 int bb_spur
= AR_NO_SPUR
;
4911 int spur_delta_phase
;
4913 int upper
, lower
, cur_vit_mask
;
4916 int pilot_mask_reg
[4] = { AR_PHY_TIMING7
, AR_PHY_TIMING8
,
4917 AR_PHY_PILOT_MASK_01_30
, AR_PHY_PILOT_MASK_31_60
4919 int chan_mask_reg
[4] = { AR_PHY_TIMING9
, AR_PHY_TIMING10
,
4920 AR_PHY_CHANNEL_MASK_01_30
, AR_PHY_CHANNEL_MASK_31_60
4922 int inc
[4] = { 0, 100, 0, 0 };
4929 bool is2GHz
= IS_CHAN_2GHZ(chan
);
4931 memset(&mask_m
, 0, sizeof(int8_t) * 123);
4932 memset(&mask_p
, 0, sizeof(int8_t) * 123);
4934 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
4935 cur_bb_spur
= ath9k_hw_eeprom_get_spur_chan(ah
, i
, is2GHz
);
4936 if (AR_NO_SPUR
== cur_bb_spur
)
4938 cur_bb_spur
= cur_bb_spur
- (chan
->channel
* 10);
4939 if ((cur_bb_spur
> -95) && (cur_bb_spur
< 95)) {
4940 bb_spur
= cur_bb_spur
;
4945 if (AR_NO_SPUR
== bb_spur
)
4950 tmp
= REG_READ(ah
, AR_PHY_TIMING_CTRL4(0));
4951 new = tmp
| (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI
|
4952 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER
|
4953 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK
|
4954 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK
);
4956 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0), new);
4958 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL
|
4959 AR_PHY_SPUR_REG_ENABLE_MASK_PPM
|
4960 AR_PHY_SPUR_REG_MASK_RATE_SELECT
|
4961 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI
|
4962 SM(SPUR_RSSI_THRESH
, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH
));
4963 REG_WRITE(ah
, AR_PHY_SPUR_REG
, new);
4965 spur_delta_phase
= ((bb_spur
* 524288) / 100) &
4966 AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
4968 denominator
= IS_CHAN_2GHZ(chan
) ? 440 : 400;
4969 spur_freq_sd
= ((bb_spur
* 2048) / denominator
) & 0x3ff;
4971 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC
|
4972 SM(spur_freq_sd
, AR_PHY_TIMING11_SPUR_FREQ_SD
) |
4973 SM(spur_delta_phase
, AR_PHY_TIMING11_SPUR_DELTA_PHASE
));
4974 REG_WRITE(ah
, AR_PHY_TIMING11
, new);
4980 for (i
= 0; i
< 4; i
++) {
4984 for (bp
= 0; bp
< 30; bp
++) {
4985 if ((cur_bin
> lower
) && (cur_bin
< upper
)) {
4986 pilot_mask
= pilot_mask
| 0x1 << bp
;
4987 chan_mask
= chan_mask
| 0x1 << bp
;
4992 REG_WRITE(ah
, pilot_mask_reg
[i
], pilot_mask
);
4993 REG_WRITE(ah
, chan_mask_reg
[i
], chan_mask
);
4996 cur_vit_mask
= 6100;
5000 for (i
= 0; i
< 123; i
++) {
5001 if ((cur_vit_mask
> lower
) && (cur_vit_mask
< upper
)) {
5002 if ((abs(cur_vit_mask
- bin
)) < 75)
5006 if (cur_vit_mask
< 0)
5007 mask_m
[abs(cur_vit_mask
/ 100)] = mask_amt
;
5009 mask_p
[cur_vit_mask
/ 100] = mask_amt
;
5011 cur_vit_mask
-= 100;
5014 tmp_mask
= (mask_m
[46] << 30) | (mask_m
[47] << 28)
5015 | (mask_m
[48] << 26) | (mask_m
[49] << 24)
5016 | (mask_m
[50] << 22) | (mask_m
[51] << 20)
5017 | (mask_m
[52] << 18) | (mask_m
[53] << 16)
5018 | (mask_m
[54] << 14) | (mask_m
[55] << 12)
5019 | (mask_m
[56] << 10) | (mask_m
[57] << 8)
5020 | (mask_m
[58] << 6) | (mask_m
[59] << 4)
5021 | (mask_m
[60] << 2) | (mask_m
[61] << 0);
5022 REG_WRITE(ah
, AR_PHY_BIN_MASK_1
, tmp_mask
);
5023 REG_WRITE(ah
, AR_PHY_VIT_MASK2_M_46_61
, tmp_mask
);
5025 tmp_mask
= (mask_m
[31] << 28)
5026 | (mask_m
[32] << 26) | (mask_m
[33] << 24)
5027 | (mask_m
[34] << 22) | (mask_m
[35] << 20)
5028 | (mask_m
[36] << 18) | (mask_m
[37] << 16)
5029 | (mask_m
[48] << 14) | (mask_m
[39] << 12)
5030 | (mask_m
[40] << 10) | (mask_m
[41] << 8)
5031 | (mask_m
[42] << 6) | (mask_m
[43] << 4)
5032 | (mask_m
[44] << 2) | (mask_m
[45] << 0);
5033 REG_WRITE(ah
, AR_PHY_BIN_MASK_2
, tmp_mask
);
5034 REG_WRITE(ah
, AR_PHY_MASK2_M_31_45
, tmp_mask
);
5036 tmp_mask
= (mask_m
[16] << 30) | (mask_m
[16] << 28)
5037 | (mask_m
[18] << 26) | (mask_m
[18] << 24)
5038 | (mask_m
[20] << 22) | (mask_m
[20] << 20)
5039 | (mask_m
[22] << 18) | (mask_m
[22] << 16)
5040 | (mask_m
[24] << 14) | (mask_m
[24] << 12)
5041 | (mask_m
[25] << 10) | (mask_m
[26] << 8)
5042 | (mask_m
[27] << 6) | (mask_m
[28] << 4)
5043 | (mask_m
[29] << 2) | (mask_m
[30] << 0);
5044 REG_WRITE(ah
, AR_PHY_BIN_MASK_3
, tmp_mask
);
5045 REG_WRITE(ah
, AR_PHY_MASK2_M_16_30
, tmp_mask
);
5047 tmp_mask
= (mask_m
[0] << 30) | (mask_m
[1] << 28)
5048 | (mask_m
[2] << 26) | (mask_m
[3] << 24)
5049 | (mask_m
[4] << 22) | (mask_m
[5] << 20)
5050 | (mask_m
[6] << 18) | (mask_m
[7] << 16)
5051 | (mask_m
[8] << 14) | (mask_m
[9] << 12)
5052 | (mask_m
[10] << 10) | (mask_m
[11] << 8)
5053 | (mask_m
[12] << 6) | (mask_m
[13] << 4)
5054 | (mask_m
[14] << 2) | (mask_m
[15] << 0);
5055 REG_WRITE(ah
, AR_PHY_MASK_CTL
, tmp_mask
);
5056 REG_WRITE(ah
, AR_PHY_MASK2_M_00_15
, tmp_mask
);
5058 tmp_mask
= (mask_p
[15] << 28)
5059 | (mask_p
[14] << 26) | (mask_p
[13] << 24)
5060 | (mask_p
[12] << 22) | (mask_p
[11] << 20)
5061 | (mask_p
[10] << 18) | (mask_p
[9] << 16)
5062 | (mask_p
[8] << 14) | (mask_p
[7] << 12)
5063 | (mask_p
[6] << 10) | (mask_p
[5] << 8)
5064 | (mask_p
[4] << 6) | (mask_p
[3] << 4)
5065 | (mask_p
[2] << 2) | (mask_p
[1] << 0);
5066 REG_WRITE(ah
, AR_PHY_BIN_MASK2_1
, tmp_mask
);
5067 REG_WRITE(ah
, AR_PHY_MASK2_P_15_01
, tmp_mask
);
5069 tmp_mask
= (mask_p
[30] << 28)
5070 | (mask_p
[29] << 26) | (mask_p
[28] << 24)
5071 | (mask_p
[27] << 22) | (mask_p
[26] << 20)
5072 | (mask_p
[25] << 18) | (mask_p
[24] << 16)
5073 | (mask_p
[23] << 14) | (mask_p
[22] << 12)
5074 | (mask_p
[21] << 10) | (mask_p
[20] << 8)
5075 | (mask_p
[19] << 6) | (mask_p
[18] << 4)
5076 | (mask_p
[17] << 2) | (mask_p
[16] << 0);
5077 REG_WRITE(ah
, AR_PHY_BIN_MASK2_2
, tmp_mask
);
5078 REG_WRITE(ah
, AR_PHY_MASK2_P_30_16
, tmp_mask
);
5080 tmp_mask
= (mask_p
[45] << 28)
5081 | (mask_p
[44] << 26) | (mask_p
[43] << 24)
5082 | (mask_p
[42] << 22) | (mask_p
[41] << 20)
5083 | (mask_p
[40] << 18) | (mask_p
[39] << 16)
5084 | (mask_p
[38] << 14) | (mask_p
[37] << 12)
5085 | (mask_p
[36] << 10) | (mask_p
[35] << 8)
5086 | (mask_p
[34] << 6) | (mask_p
[33] << 4)
5087 | (mask_p
[32] << 2) | (mask_p
[31] << 0);
5088 REG_WRITE(ah
, AR_PHY_BIN_MASK2_3
, tmp_mask
);
5089 REG_WRITE(ah
, AR_PHY_MASK2_P_45_31
, tmp_mask
);
5091 tmp_mask
= (mask_p
[61] << 30) | (mask_p
[60] << 28)
5092 | (mask_p
[59] << 26) | (mask_p
[58] << 24)
5093 | (mask_p
[57] << 22) | (mask_p
[56] << 20)
5094 | (mask_p
[55] << 18) | (mask_p
[54] << 16)
5095 | (mask_p
[53] << 14) | (mask_p
[52] << 12)
5096 | (mask_p
[51] << 10) | (mask_p
[50] << 8)
5097 | (mask_p
[49] << 6) | (mask_p
[48] << 4)
5098 | (mask_p
[47] << 2) | (mask_p
[46] << 0);
5099 REG_WRITE(ah
, AR_PHY_BIN_MASK2_4
, tmp_mask
);
5100 REG_WRITE(ah
, AR_PHY_MASK2_P_61_45
, tmp_mask
);
5103 static inline void ath9k_hw_init_chain_masks(struct ath_hal
*ah
)
5105 struct ath_hal_5416
*ahp
= AH5416(ah
);
5106 int rx_chainmask
, tx_chainmask
;
5108 rx_chainmask
= ahp
->ah_rxchainmask
;
5109 tx_chainmask
= ahp
->ah_txchainmask
;
5111 switch (rx_chainmask
) {
5113 REG_SET_BIT(ah
, AR_PHY_ANALOG_SWAP
,
5114 AR_PHY_SWAP_ALT_CHAIN
);
5116 if (((ah
)->ah_macVersion
<= AR_SREV_VERSION_9160
)) {
5117 REG_WRITE(ah
, AR_PHY_RX_CHAINMASK
, 0x7);
5118 REG_WRITE(ah
, AR_PHY_CAL_CHAINMASK
, 0x7);
5123 if (!AR_SREV_9280(ah
))
5126 REG_WRITE(ah
, AR_PHY_RX_CHAINMASK
, rx_chainmask
);
5127 REG_WRITE(ah
, AR_PHY_CAL_CHAINMASK
, rx_chainmask
);
5133 REG_WRITE(ah
, AR_SELFGEN_MASK
, tx_chainmask
);
5134 if (tx_chainmask
== 0x5) {
5135 REG_SET_BIT(ah
, AR_PHY_ANALOG_SWAP
,
5136 AR_PHY_SWAP_ALT_CHAIN
);
5138 if (AR_SREV_9100(ah
))
5139 REG_WRITE(ah
, AR_PHY_ANALOG_SWAP
,
5140 REG_READ(ah
, AR_PHY_ANALOG_SWAP
) | 0x00000001);
5143 static void ath9k_hw_set_addac(struct ath_hal
*ah
,
5144 struct hal_channel_internal
*chan
)
5146 struct modal_eep_header
*pModal
;
5147 struct ath_hal_5416
*ahp
= AH5416(ah
);
5148 struct ar5416_eeprom
*eep
= &ahp
->ah_eeprom
;
5151 if (ah
->ah_macVersion
!= AR_SREV_VERSION_9160
)
5154 if (ar5416_get_eep_rev(ahp
) < AR5416_EEP_MINOR_VER_7
)
5157 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
5159 if (pModal
->xpaBiasLvl
!= 0xff) {
5160 biaslevel
= pModal
->xpaBiasLvl
;
5163 u_int16_t resetFreqBin
, freqBin
, freqCount
= 0;
5164 struct chan_centers centers
;
5166 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
5169 FREQ2FBIN(centers
.synth_center
, IS_CHAN_2GHZ(chan
));
5170 freqBin
= pModal
->xpaBiasLvlFreq
[0] & 0xff;
5171 biaslevel
= (u_int8_t
) (pModal
->xpaBiasLvlFreq
[0] >> 14);
5175 while (freqCount
< 3) {
5176 if (pModal
->xpaBiasLvlFreq
[freqCount
] == 0x0)
5179 freqBin
= pModal
->xpaBiasLvlFreq
[freqCount
] & 0xff;
5180 if (resetFreqBin
>= freqBin
) {
5182 (u_int8_t
) (pModal
->
5183 xpaBiasLvlFreq
[freqCount
]
5192 if (IS_CHAN_2GHZ(chan
)) {
5193 INI_RA(&ahp
->ah_iniAddac
, 7, 1) =
5194 (INI_RA(&ahp
->ah_iniAddac
, 7, 1) & (~0x18)) | biaslevel
5197 INI_RA(&ahp
->ah_iniAddac
, 6, 1) =
5198 (INI_RA(&ahp
->ah_iniAddac
, 6, 1) & (~0xc0)) | biaslevel
5203 static u_int
ath9k_hw_mac_usec(struct ath_hal
*ah
, u_int clks
)
5205 const struct hal_channel
*c
=
5206 (const struct hal_channel
*) ah
->ah_curchan
;
5209 return clks
/ CLOCK_RATE
[ath9k_hw_chan2wmode(ah
, c
)];
5211 return clks
/ CLOCK_RATE
[WIRELESS_MODE_11b
];
5214 static u_int
ath9k_hw_mac_to_usec(struct ath_hal
*ah
, u_int clks
)
5216 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
5218 if (chan
&& IS_CHAN_HT40(chan
))
5219 return ath9k_hw_mac_usec(ah
, clks
) / 2;
5221 return ath9k_hw_mac_usec(ah
, clks
);
5224 static u_int
ath9k_hw_mac_clks(struct ath_hal
*ah
, u_int usecs
)
5226 const struct hal_channel
*c
=
5227 (const struct hal_channel
*) ah
->ah_curchan
;
5230 return usecs
* CLOCK_RATE
[ath9k_hw_chan2wmode(ah
, c
)];
5232 return usecs
* CLOCK_RATE
[WIRELESS_MODE_11b
];
5235 static u_int
ath9k_hw_mac_to_clks(struct ath_hal
*ah
, u_int usecs
)
5237 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
5239 if (chan
&& IS_CHAN_HT40(chan
))
5240 return ath9k_hw_mac_clks(ah
, usecs
) * 2;
5242 return ath9k_hw_mac_clks(ah
, usecs
);
5245 static bool ath9k_hw_set_ack_timeout(struct ath_hal
*ah
, u_int us
)
5247 struct ath_hal_5416
*ahp
= AH5416(ah
);
5249 if (us
> ath9k_hw_mac_to_usec(ah
, MS(0xffffffff, AR_TIME_OUT_ACK
))) {
5250 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: bad ack timeout %u\n",
5252 ahp
->ah_acktimeout
= (u_int
) -1;
5255 REG_RMW_FIELD(ah
, AR_TIME_OUT
,
5256 AR_TIME_OUT_ACK
, ath9k_hw_mac_to_clks(ah
, us
));
5257 ahp
->ah_acktimeout
= us
;
5262 static bool ath9k_hw_set_cts_timeout(struct ath_hal
*ah
, u_int us
)
5264 struct ath_hal_5416
*ahp
= AH5416(ah
);
5266 if (us
> ath9k_hw_mac_to_usec(ah
, MS(0xffffffff, AR_TIME_OUT_CTS
))) {
5267 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: bad cts timeout %u\n",
5269 ahp
->ah_ctstimeout
= (u_int
) -1;
5272 REG_RMW_FIELD(ah
, AR_TIME_OUT
,
5273 AR_TIME_OUT_CTS
, ath9k_hw_mac_to_clks(ah
, us
));
5274 ahp
->ah_ctstimeout
= us
;
5278 static bool ath9k_hw_set_global_txtimeout(struct ath_hal
*ah
,
5281 struct ath_hal_5416
*ahp
= AH5416(ah
);
5284 DPRINTF(ah
->ah_sc
, ATH_DBG_XMIT
,
5285 "%s: bad global tx timeout %u\n", __func__
, tu
);
5286 ahp
->ah_globaltxtimeout
= (u_int
) -1;
5289 REG_RMW_FIELD(ah
, AR_GTXTO
, AR_GTXTO_TIMEOUT_LIMIT
, tu
);
5290 ahp
->ah_globaltxtimeout
= tu
;
5295 bool ath9k_hw_setslottime(struct ath_hal
*ah
, u_int us
)
5297 struct ath_hal_5416
*ahp
= AH5416(ah
);
5299 if (us
< HAL_SLOT_TIME_9
|| us
> ath9k_hw_mac_to_usec(ah
, 0xffff)) {
5300 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: bad slot time %u\n",
5302 ahp
->ah_slottime
= (u_int
) -1;
5305 REG_WRITE(ah
, AR_D_GBL_IFS_SLOT
, ath9k_hw_mac_to_clks(ah
, us
));
5306 ahp
->ah_slottime
= us
;
5311 static inline void ath9k_hw_init_user_settings(struct ath_hal
*ah
)
5313 struct ath_hal_5416
*ahp
= AH5416(ah
);
5315 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "--AP %s ahp->ah_miscMode 0x%x\n",
5316 __func__
, ahp
->ah_miscMode
);
5317 if (ahp
->ah_miscMode
!= 0)
5318 REG_WRITE(ah
, AR_PCU_MISC
,
5319 REG_READ(ah
, AR_PCU_MISC
) | ahp
->ah_miscMode
);
5320 if (ahp
->ah_slottime
!= (u_int
) -1)
5321 ath9k_hw_setslottime(ah
, ahp
->ah_slottime
);
5322 if (ahp
->ah_acktimeout
!= (u_int
) -1)
5323 ath9k_hw_set_ack_timeout(ah
, ahp
->ah_acktimeout
);
5324 if (ahp
->ah_ctstimeout
!= (u_int
) -1)
5325 ath9k_hw_set_cts_timeout(ah
, ahp
->ah_ctstimeout
);
5326 if (ahp
->ah_globaltxtimeout
!= (u_int
) -1)
5327 ath9k_hw_set_global_txtimeout(ah
, ahp
->ah_globaltxtimeout
);
5330 static inline enum hal_status
5331 ath9k_hw_process_ini(struct ath_hal
*ah
,
5332 struct hal_channel
*chan
,
5333 struct hal_channel_internal
*ichan
,
5334 enum hal_ht_macmode macmode
)
5336 int i
, regWrites
= 0;
5337 struct ath_hal_5416
*ahp
= AH5416(ah
);
5338 u_int modesIndex
, freqIndex
;
5339 enum hal_status status
;
5341 switch (chan
->channelFlags
& CHANNEL_ALL
) {
5343 case CHANNEL_A_HT20
:
5347 case CHANNEL_A_HT40PLUS
:
5348 case CHANNEL_A_HT40MINUS
:
5353 case CHANNEL_G_HT20
:
5358 case CHANNEL_G_HT40PLUS
:
5359 case CHANNEL_G_HT40MINUS
:
5368 REG_WRITE(ah
, AR_PHY(0), 0x00000007);
5370 REG_WRITE(ah
, AR_PHY_ADC_SERIAL_CTL
, AR_PHY_SEL_EXTERNAL_RADIO
);
5372 ath9k_hw_set_addac(ah
, ichan
);
5374 if (AR_SREV_5416_V22_OR_LATER(ah
)) {
5375 REG_WRITE_ARRAY(&ahp
->ah_iniAddac
, 1, regWrites
);
5377 struct ar5416IniArray temp
;
5378 u_int32_t addacSize
=
5379 sizeof(u_int32_t
) * ahp
->ah_iniAddac
.ia_rows
*
5380 ahp
->ah_iniAddac
.ia_columns
;
5382 memcpy(ahp
->ah_addac5416_21
,
5383 ahp
->ah_iniAddac
.ia_array
, addacSize
);
5385 (ahp
->ah_addac5416_21
)[31 *
5386 ahp
->ah_iniAddac
.ia_columns
+ 1] = 0;
5388 temp
.ia_array
= ahp
->ah_addac5416_21
;
5389 temp
.ia_columns
= ahp
->ah_iniAddac
.ia_columns
;
5390 temp
.ia_rows
= ahp
->ah_iniAddac
.ia_rows
;
5391 REG_WRITE_ARRAY(&temp
, 1, regWrites
);
5393 REG_WRITE(ah
, AR_PHY_ADC_SERIAL_CTL
, AR_PHY_SEL_INTERNAL_ADDAC
);
5395 for (i
= 0; i
< ahp
->ah_iniModes
.ia_rows
; i
++) {
5396 u_int32_t reg
= INI_RA(&ahp
->ah_iniModes
, i
, 0);
5397 u_int32_t val
= INI_RA(&ahp
->ah_iniModes
, i
, modesIndex
);
5399 #ifdef CONFIG_SLOW_ANT_DIV
5400 if (ah
->ah_devid
== AR9280_DEVID_PCI
)
5401 val
= ath9k_hw_ini_fixup(ah
, &ahp
->ah_eeprom
, reg
,
5405 REG_WRITE(ah
, reg
, val
);
5407 if (reg
>= 0x7800 && reg
< 0x78a0
5408 && ah
->ah_config
.ath_hal_analogShiftReg
) {
5412 DO_DELAY(regWrites
);
5415 for (i
= 0; i
< ahp
->ah_iniCommon
.ia_rows
; i
++) {
5416 u_int32_t reg
= INI_RA(&ahp
->ah_iniCommon
, i
, 0);
5417 u_int32_t val
= INI_RA(&ahp
->ah_iniCommon
, i
, 1);
5419 REG_WRITE(ah
, reg
, val
);
5421 if (reg
>= 0x7800 && reg
< 0x78a0
5422 && ah
->ah_config
.ath_hal_analogShiftReg
) {
5426 DO_DELAY(regWrites
);
5429 ath9k_hw_write_regs(ah
, modesIndex
, freqIndex
, regWrites
);
5431 if (AR_SREV_9280_20(ah
) && IS_CHAN_A_5MHZ_SPACED(chan
)) {
5432 REG_WRITE_ARRAY(&ahp
->ah_iniModesAdditional
, modesIndex
,
5436 ath9k_hw_override_ini(ah
, chan
);
5437 ath9k_hw_set_regs(ah
, chan
, macmode
);
5438 ath9k_hw_init_chain_masks(ah
);
5440 status
= ath9k_hw_set_txpower(ah
, &ahp
->ah_eeprom
, ichan
,
5441 ath9k_regd_get_ctl(ah
, chan
),
5442 ath9k_regd_get_antenna_allowed(ah
,
5444 ichan
->maxRegTxPower
* 2,
5445 min((u_int32_t
) MAX_RATE_POWER
,
5446 (u_int32_t
) ah
->ah_powerLimit
));
5447 if (status
!= HAL_OK
) {
5448 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
5449 "%s: error init'ing transmit power\n", __func__
);
5453 if (!ath9k_hw_set_rf_regs(ah
, ichan
, freqIndex
)) {
5454 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
5455 "%s: ar5416SetRfRegs failed\n", __func__
);
5462 static inline void ath9k_hw_setup_calibration(struct ath_hal
*ah
,
5463 struct hal_cal_list
*currCal
)
5465 REG_RMW_FIELD(ah
, AR_PHY_TIMING_CTRL4(0),
5466 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX
,
5467 currCal
->calData
->calCountMax
);
5469 switch (currCal
->calData
->calType
) {
5470 case IQ_MISMATCH_CAL
:
5471 REG_WRITE(ah
, AR_PHY_CALMODE
, AR_PHY_CALMODE_IQ
);
5472 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5473 "%s: starting IQ Mismatch Calibration\n",
5477 REG_WRITE(ah
, AR_PHY_CALMODE
, AR_PHY_CALMODE_ADC_GAIN
);
5478 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5479 "%s: starting ADC Gain Calibration\n", __func__
);
5482 REG_WRITE(ah
, AR_PHY_CALMODE
, AR_PHY_CALMODE_ADC_DC_PER
);
5483 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5484 "%s: starting ADC DC Calibration\n", __func__
);
5486 case ADC_DC_INIT_CAL
:
5487 REG_WRITE(ah
, AR_PHY_CALMODE
, AR_PHY_CALMODE_ADC_DC_INIT
);
5488 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5489 "%s: starting Init ADC DC Calibration\n",
5494 REG_SET_BIT(ah
, AR_PHY_TIMING_CTRL4(0),
5495 AR_PHY_TIMING_CTRL4_DO_CAL
);
5498 static inline void ath9k_hw_reset_calibration(struct ath_hal
*ah
,
5499 struct hal_cal_list
*currCal
)
5501 struct ath_hal_5416
*ahp
= AH5416(ah
);
5504 ath9k_hw_setup_calibration(ah
, currCal
);
5506 currCal
->calState
= CAL_RUNNING
;
5508 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
5509 ahp
->ah_Meas0
.sign
[i
] = 0;
5510 ahp
->ah_Meas1
.sign
[i
] = 0;
5511 ahp
->ah_Meas2
.sign
[i
] = 0;
5512 ahp
->ah_Meas3
.sign
[i
] = 0;
5515 ahp
->ah_CalSamples
= 0;
5519 ath9k_hw_per_calibration(struct ath_hal
*ah
,
5520 struct hal_channel_internal
*ichan
,
5521 u_int8_t rxchainmask
,
5522 struct hal_cal_list
*currCal
,
5525 struct ath_hal_5416
*ahp
= AH5416(ah
);
5529 if (currCal
->calState
== CAL_RUNNING
) {
5531 AR_PHY_TIMING_CTRL4(0)) &
5532 AR_PHY_TIMING_CTRL4_DO_CAL
)) {
5534 currCal
->calData
->calCollect(ah
);
5536 ahp
->ah_CalSamples
++;
5538 if (ahp
->ah_CalSamples
>=
5539 currCal
->calData
->calNumSamples
) {
5540 int i
, numChains
= 0;
5541 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
5542 if (rxchainmask
& (1 << i
))
5546 currCal
->calData
->calPostProc(ah
,
5550 currCal
->calData
->calType
;
5551 currCal
->calState
= CAL_DONE
;
5554 ath9k_hw_setup_calibration(ah
, currCal
);
5557 } else if (!(ichan
->CalValid
& currCal
->calData
->calType
)) {
5558 ath9k_hw_reset_calibration(ah
, currCal
);
5562 static inline bool ath9k_hw_run_init_cals(struct ath_hal
*ah
,
5565 struct ath_hal_5416
*ahp
= AH5416(ah
);
5566 struct hal_channel_internal ichan
;
5568 struct hal_cal_list
*currCal
= ahp
->ah_cal_list_curr
;
5569 const struct hal_percal_data
*calData
= currCal
->calData
;
5572 if (currCal
== NULL
)
5577 for (i
= 0; i
< init_cal_count
; i
++) {
5578 ath9k_hw_reset_calibration(ah
, currCal
);
5580 if (!ath9k_hw_wait(ah
, AR_PHY_TIMING_CTRL4(0),
5581 AR_PHY_TIMING_CTRL4_DO_CAL
, 0)) {
5582 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5583 "%s: Cal %d failed to complete in 100ms.\n",
5584 __func__
, calData
->calType
);
5586 ahp
->ah_cal_list
= ahp
->ah_cal_list_last
=
5587 ahp
->ah_cal_list_curr
= NULL
;
5591 ath9k_hw_per_calibration(ah
, &ichan
, ahp
->ah_rxchainmask
,
5592 currCal
, &isCalDone
);
5594 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5595 "%s: Not able to run Init Cal %d.\n",
5596 __func__
, calData
->calType
);
5598 if (currCal
->calNext
) {
5599 currCal
= currCal
->calNext
;
5600 calData
= currCal
->calData
;
5604 ahp
->ah_cal_list
= ahp
->ah_cal_list_last
= ahp
->ah_cal_list_curr
= NULL
;
5609 ath9k_hw_channel_change(struct ath_hal
*ah
,
5610 struct hal_channel
*chan
,
5611 struct hal_channel_internal
*ichan
,
5612 enum hal_ht_macmode macmode
)
5614 u_int32_t synthDelay
, qnum
;
5615 struct ath_hal_5416
*ahp
= AH5416(ah
);
5617 for (qnum
= 0; qnum
< AR_NUM_QCU
; qnum
++) {
5618 if (ath9k_hw_numtxpending(ah
, qnum
)) {
5619 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
,
5620 "%s: Transmit frames pending on queue %d\n",
5626 REG_WRITE(ah
, AR_PHY_RFBUS_REQ
, AR_PHY_RFBUS_REQ_EN
);
5627 if (!ath9k_hw_wait(ah
, AR_PHY_RFBUS_GRANT
, AR_PHY_RFBUS_GRANT_EN
,
5628 AR_PHY_RFBUS_GRANT_EN
)) {
5629 DPRINTF(ah
->ah_sc
, ATH_DBG_PHY_IO
,
5630 "%s: Could not kill baseband RX\n", __func__
);
5634 ath9k_hw_set_regs(ah
, chan
, macmode
);
5636 if (AR_SREV_9280_10_OR_LATER(ah
)) {
5637 if (!(ath9k_hw_ar9280_set_channel(ah
, ichan
))) {
5638 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
5639 "%s: failed to set channel\n", __func__
);
5643 if (!(ath9k_hw_set_channel(ah
, ichan
))) {
5644 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
5645 "%s: failed to set channel\n", __func__
);
5650 if (ath9k_hw_set_txpower(ah
, &ahp
->ah_eeprom
, ichan
,
5651 ath9k_regd_get_ctl(ah
, chan
),
5652 ath9k_regd_get_antenna_allowed(ah
, chan
),
5653 ichan
->maxRegTxPower
* 2,
5654 min((u_int32_t
) MAX_RATE_POWER
,
5655 (u_int32_t
) ah
->ah_powerLimit
))
5657 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
5658 "%s: error init'ing transmit power\n", __func__
);
5662 synthDelay
= REG_READ(ah
, AR_PHY_RX_DELAY
) & AR_PHY_RX_DELAY_DELAY
;
5663 if (IS_CHAN_CCK(chan
))
5664 synthDelay
= (4 * synthDelay
) / 22;
5668 udelay(synthDelay
+ BASE_ACTIVATE_DELAY
);
5670 REG_WRITE(ah
, AR_PHY_RFBUS_REQ
, 0);
5672 if (IS_CHAN_OFDM(chan
) || IS_CHAN_HT(chan
))
5673 ath9k_hw_set_delta_slope(ah
, ichan
);
5675 if (AR_SREV_9280_10_OR_LATER(ah
))
5676 ath9k_hw_9280_spur_mitigate(ah
, chan
, ichan
);
5678 ath9k_hw_spur_mitigate(ah
, chan
);
5680 if (!ichan
->oneTimeCalsDone
)
5681 ichan
->oneTimeCalsDone
= true;
5686 static bool ath9k_hw_chip_reset(struct ath_hal
*ah
,
5687 struct hal_channel
*chan
)
5689 struct ath_hal_5416
*ahp
= AH5416(ah
);
5691 if (!ath9k_hw_set_reset_reg(ah
, HAL_RESET_WARM
))
5694 if (!ath9k_hw_setpower(ah
, HAL_PM_AWAKE
))
5697 ahp
->ah_chipFullSleep
= false;
5699 ath9k_hw_init_pll(ah
, chan
);
5701 ath9k_hw_set_rfmode(ah
, chan
);
5706 static inline void ath9k_hw_set_dma(struct ath_hal
*ah
)
5710 regval
= REG_READ(ah
, AR_AHB_MODE
);
5711 REG_WRITE(ah
, AR_AHB_MODE
, regval
| AR_AHB_PREFETCH_RD_EN
);
5713 regval
= REG_READ(ah
, AR_TXCFG
) & ~AR_TXCFG_DMASZ_MASK
;
5714 REG_WRITE(ah
, AR_TXCFG
, regval
| AR_TXCFG_DMASZ_128B
);
5716 REG_RMW_FIELD(ah
, AR_TXCFG
, AR_FTRIG
, ah
->ah_txTrigLevel
);
5718 regval
= REG_READ(ah
, AR_RXCFG
) & ~AR_RXCFG_DMASZ_MASK
;
5719 REG_WRITE(ah
, AR_RXCFG
, regval
| AR_RXCFG_DMASZ_128B
);
5721 REG_WRITE(ah
, AR_RXFIFO_CFG
, 0x200);
5723 if (AR_SREV_9285(ah
)) {
5724 REG_WRITE(ah
, AR_PCU_TXBUF_CTRL
,
5725 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE
);
5727 REG_WRITE(ah
, AR_PCU_TXBUF_CTRL
,
5728 AR_PCU_TXBUF_CTRL_USABLE_SIZE
);
5732 bool ath9k_hw_stopdmarecv(struct ath_hal
*ah
)
5734 REG_WRITE(ah
, AR_CR
, AR_CR_RXD
);
5735 if (!ath9k_hw_wait(ah
, AR_CR
, AR_CR_RXE
, 0)) {
5736 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
,
5737 "%s: dma failed to stop in 10ms\n"
5738 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5740 REG_READ(ah
, AR_CR
), REG_READ(ah
, AR_DIAG_SW
));
5747 void ath9k_hw_startpcureceive(struct ath_hal
*ah
)
5749 REG_CLR_BIT(ah
, AR_DIAG_SW
,
5750 (AR_DIAG_RX_DIS
| AR_DIAG_RX_ABORT
));
5752 ath9k_enable_mib_counters(ah
);
5754 ath9k_ani_reset(ah
);
5757 void ath9k_hw_stoppcurecv(struct ath_hal
*ah
)
5759 REG_SET_BIT(ah
, AR_DIAG_SW
, AR_DIAG_RX_DIS
);
5761 ath9k_hw_disable_mib_counters(ah
);
5764 static bool ath9k_hw_iscal_supported(struct ath_hal
*ah
,
5765 struct hal_channel
*chan
,
5766 enum hal_cal_types calType
)
5768 struct ath_hal_5416
*ahp
= AH5416(ah
);
5769 bool retval
= false;
5771 switch (calType
& ahp
->ah_suppCals
) {
5772 case IQ_MISMATCH_CAL
:
5773 if (!IS_CHAN_B(chan
))
5778 if (!IS_CHAN_B(chan
)
5779 && !(IS_CHAN_2GHZ(chan
) && IS_CHAN_HT20(chan
)))
5787 static inline bool ath9k_hw_init_cal(struct ath_hal
*ah
,
5788 struct hal_channel
*chan
)
5790 struct ath_hal_5416
*ahp
= AH5416(ah
);
5791 struct hal_channel_internal
*ichan
=
5792 ath9k_regd_check_channel(ah
, chan
);
5794 REG_WRITE(ah
, AR_PHY_AGC_CONTROL
,
5795 REG_READ(ah
, AR_PHY_AGC_CONTROL
) |
5796 AR_PHY_AGC_CONTROL_CAL
);
5799 (ah
, AR_PHY_AGC_CONTROL
, AR_PHY_AGC_CONTROL_CAL
, 0)) {
5800 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5801 "%s: offset calibration failed to complete in 1ms; "
5802 "noisy environment?\n", __func__
);
5806 REG_WRITE(ah
, AR_PHY_AGC_CONTROL
,
5807 REG_READ(ah
, AR_PHY_AGC_CONTROL
) |
5808 AR_PHY_AGC_CONTROL_NF
);
5810 ahp
->ah_cal_list
= ahp
->ah_cal_list_last
= ahp
->ah_cal_list_curr
=
5813 if (AR_SREV_9100(ah
) || AR_SREV_9160_10_OR_LATER(ah
)) {
5814 if (ath9k_hw_iscal_supported(ah
, chan
, ADC_GAIN_CAL
)) {
5815 INIT_CAL(&ahp
->ah_adcGainCalData
);
5816 INSERT_CAL(ahp
, &ahp
->ah_adcGainCalData
);
5817 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5818 "%s: enabling ADC Gain Calibration.\n",
5821 if (ath9k_hw_iscal_supported(ah
, chan
, ADC_DC_CAL
)) {
5822 INIT_CAL(&ahp
->ah_adcDcCalData
);
5823 INSERT_CAL(ahp
, &ahp
->ah_adcDcCalData
);
5824 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5825 "%s: enabling ADC DC Calibration.\n",
5828 if (ath9k_hw_iscal_supported(ah
, chan
, IQ_MISMATCH_CAL
)) {
5829 INIT_CAL(&ahp
->ah_iqCalData
);
5830 INSERT_CAL(ahp
, &ahp
->ah_iqCalData
);
5831 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
5832 "%s: enabling IQ Calibration.\n",
5836 ahp
->ah_cal_list_curr
= ahp
->ah_cal_list
;
5838 if (ahp
->ah_cal_list_curr
)
5839 ath9k_hw_reset_calibration(ah
,
5840 ahp
->ah_cal_list_curr
);
5843 ichan
->CalValid
= 0;
5849 bool ath9k_hw_reset(struct ath_hal
*ah
, enum hal_opmode opmode
,
5850 struct hal_channel
*chan
,
5851 enum hal_ht_macmode macmode
,
5852 u_int8_t txchainmask
, u_int8_t rxchainmask
,
5853 enum hal_ht_extprotspacing extprotspacing
,
5854 bool bChannelChange
,
5855 enum hal_status
*status
)
5857 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5858 u_int32_t saveLedState
;
5859 struct ath_hal_5416
*ahp
= AH5416(ah
);
5860 struct hal_channel_internal
*ichan
;
5861 struct hal_channel_internal
*curchan
= ah
->ah_curchan
;
5862 u_int32_t saveDefAntenna
;
5863 u_int32_t macStaId1
;
5864 enum hal_status ecode
;
5865 int i
, rx_chainmask
;
5867 ahp
->ah_extprotspacing
= extprotspacing
;
5868 ahp
->ah_txchainmask
= txchainmask
;
5869 ahp
->ah_rxchainmask
= rxchainmask
;
5871 if (AR_SREV_9280(ah
)) {
5872 ahp
->ah_txchainmask
&= 0x3;
5873 ahp
->ah_rxchainmask
&= 0x3;
5876 ichan
= ath9k_hw_check_chan(ah
, chan
);
5877 if (ichan
== NULL
) {
5878 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
5879 "%s: invalid channel %u/0x%x; no mapping\n",
5880 __func__
, chan
->channel
, chan
->channelFlags
);
5884 if (!ath9k_hw_setpower(ah
, HAL_PM_AWAKE
))
5888 ath9k_hw_getnf(ah
, curchan
);
5890 if (bChannelChange
&&
5891 (ahp
->ah_chipFullSleep
!= true) &&
5892 (ah
->ah_curchan
!= NULL
) &&
5893 (chan
->channel
!= ah
->ah_curchan
->channel
) &&
5894 ((chan
->channelFlags
& CHANNEL_ALL
) ==
5895 (ah
->ah_curchan
->channelFlags
& CHANNEL_ALL
)) &&
5896 (!AR_SREV_9280(ah
) || (!IS_CHAN_A_5MHZ_SPACED(chan
) &&
5897 !IS_CHAN_A_5MHZ_SPACED(ah
->
5900 if (ath9k_hw_channel_change(ah
, chan
, ichan
, macmode
)) {
5901 chan
->channelFlags
= ichan
->channelFlags
;
5902 chan
->privFlags
= ichan
->privFlags
;
5904 ath9k_hw_loadnf(ah
, ah
->ah_curchan
);
5906 ath9k_hw_start_nfcal(ah
);
5912 saveDefAntenna
= REG_READ(ah
, AR_DEF_ANTENNA
);
5913 if (saveDefAntenna
== 0)
5916 macStaId1
= REG_READ(ah
, AR_STA_ID1
) & AR_STA_ID1_BASE_RATE_11B
;
5918 saveLedState
= REG_READ(ah
, AR_CFG_LED
) &
5919 (AR_CFG_LED_ASSOC_CTL
| AR_CFG_LED_MODE_SEL
|
5920 AR_CFG_LED_BLINK_THRESH_SEL
| AR_CFG_LED_BLINK_SLOW
);
5922 ath9k_hw_mark_phy_inactive(ah
);
5924 if (!ath9k_hw_chip_reset(ah
, chan
)) {
5925 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
, "%s: chip reset failed\n",
5930 if (AR_SREV_9280(ah
)) {
5931 REG_SET_BIT(ah
, AR_GPIO_INPUT_EN_VAL
,
5932 AR_GPIO_JTAG_DISABLE
);
5934 if (ah
->ah_caps
.halWirelessModes
& ATH9K_MODE_SEL_11A
) {
5935 if (IS_CHAN_5GHZ(chan
))
5936 ath9k_hw_set_gpio(ah
, 9, 0);
5938 ath9k_hw_set_gpio(ah
, 9, 1);
5940 ath9k_hw_cfg_output(ah
, 9, HAL_GPIO_OUTPUT_MUX_AS_OUTPUT
);
5943 ecode
= ath9k_hw_process_ini(ah
, chan
, ichan
, macmode
);
5944 if (ecode
!= HAL_OK
)
5947 if (IS_CHAN_OFDM(chan
) || IS_CHAN_HT(chan
))
5948 ath9k_hw_set_delta_slope(ah
, ichan
);
5950 if (AR_SREV_9280_10_OR_LATER(ah
))
5951 ath9k_hw_9280_spur_mitigate(ah
, chan
, ichan
);
5953 ath9k_hw_spur_mitigate(ah
, chan
);
5955 if (!ath9k_hw_eeprom_set_board_values(ah
, ichan
)) {
5956 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
5957 "%s: error setting board options\n", __func__
);
5961 ath9k_hw_decrease_chain_power(ah
, chan
);
5963 REG_WRITE(ah
, AR_STA_ID0
, LE_READ_4(ahp
->ah_macaddr
));
5964 REG_WRITE(ah
, AR_STA_ID1
, LE_READ_2(ahp
->ah_macaddr
+ 4)
5966 | AR_STA_ID1_RTS_USE_DEF
5968 ath_hal_6mb_ack
? AR_STA_ID1_ACKCTS_6MB
: 0)
5969 | ahp
->ah_staId1Defaults
);
5970 ath9k_hw_set_operating_mode(ah
, opmode
);
5972 REG_WRITE(ah
, AR_BSSMSKL
, LE_READ_4(ahp
->ah_bssidmask
));
5973 REG_WRITE(ah
, AR_BSSMSKU
, LE_READ_2(ahp
->ah_bssidmask
+ 4));
5975 REG_WRITE(ah
, AR_DEF_ANTENNA
, saveDefAntenna
);
5977 REG_WRITE(ah
, AR_BSS_ID0
, LE_READ_4(ahp
->ah_bssid
));
5978 REG_WRITE(ah
, AR_BSS_ID1
, LE_READ_2(ahp
->ah_bssid
+ 4) |
5979 ((ahp
->ah_assocId
& 0x3fff) << AR_BSS_ID1_AID_S
));
5981 REG_WRITE(ah
, AR_ISR
, ~0);
5983 REG_WRITE(ah
, AR_RSSI_THR
, INIT_RSSI_THR
);
5985 if (AR_SREV_9280_10_OR_LATER(ah
)) {
5986 if (!(ath9k_hw_ar9280_set_channel(ah
, ichan
)))
5989 if (!(ath9k_hw_set_channel(ah
, ichan
)))
5993 for (i
= 0; i
< AR_NUM_DCU
; i
++)
5994 REG_WRITE(ah
, AR_DQCUMASK(i
), 1 << i
);
5996 ahp
->ah_intrTxqs
= 0;
5997 for (i
= 0; i
< ah
->ah_caps
.halTotalQueues
; i
++)
5998 ath9k_hw_resettxqueue(ah
, i
);
6000 ath9k_hw_init_interrupt_masks(ah
, opmode
);
6001 ath9k_hw_init_qos(ah
);
6003 ath9k_hw_init_user_settings(ah
);
6005 ah
->ah_opmode
= opmode
;
6007 REG_WRITE(ah
, AR_STA_ID1
,
6008 REG_READ(ah
, AR_STA_ID1
) | AR_STA_ID1_PRESERVE_SEQNUM
);
6010 ath9k_hw_set_dma(ah
);
6012 REG_WRITE(ah
, AR_OBS
, 8);
6014 if (ahp
->ah_intrMitigation
) {
6016 REG_RMW_FIELD(ah
, AR_RIMT
, AR_RIMT_LAST
, 500);
6017 REG_RMW_FIELD(ah
, AR_RIMT
, AR_RIMT_FIRST
, 2000);
6020 ath9k_hw_init_bb(ah
, chan
);
6022 if (!ath9k_hw_init_cal(ah
, chan
))
6023 FAIL(HAL_ESELFTEST
);
6025 rx_chainmask
= ahp
->ah_rxchainmask
;
6026 if ((rx_chainmask
== 0x5) || (rx_chainmask
== 0x3)) {
6027 REG_WRITE(ah
, AR_PHY_RX_CHAINMASK
, rx_chainmask
);
6028 REG_WRITE(ah
, AR_PHY_CAL_CHAINMASK
, rx_chainmask
);
6031 REG_WRITE(ah
, AR_CFG_LED
, saveLedState
| AR_CFG_SCLK_32KHZ
);
6033 if (AR_SREV_9100(ah
)) {
6035 mask
= REG_READ(ah
, AR_CFG
);
6036 if (mask
& (AR_CFG_SWRB
| AR_CFG_SWTB
| AR_CFG_SWRG
)) {
6037 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
6038 "%s CFG Byte Swap Set 0x%x\n", __func__
,
6042 INIT_CONFIG_STATUS
| AR_CFG_SWRB
| AR_CFG_SWTB
;
6043 REG_WRITE(ah
, AR_CFG
, mask
);
6044 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
6045 "%s Setting CFG 0x%x\n", __func__
,
6046 REG_READ(ah
, AR_CFG
));
6050 REG_WRITE(ah
, AR_CFG
, AR_CFG_SWTD
| AR_CFG_SWRD
);
6053 chan
->channelFlags
= ichan
->channelFlags
;
6054 chan
->privFlags
= ichan
->privFlags
;
6063 bool ath9k_hw_phy_disable(struct ath_hal
*ah
)
6065 return ath9k_hw_set_reset_reg(ah
, HAL_RESET_WARM
);
6068 bool ath9k_hw_disable(struct ath_hal
*ah
)
6070 if (!ath9k_hw_setpower(ah
, HAL_PM_AWAKE
))
6073 return ath9k_hw_set_reset_reg(ah
, HAL_RESET_COLD
);
6077 ath9k_hw_calibrate(struct ath_hal
*ah
, struct hal_channel
*chan
,
6078 u_int8_t rxchainmask
, bool longcal
,
6081 struct ath_hal_5416
*ahp
= AH5416(ah
);
6082 struct hal_cal_list
*currCal
= ahp
->ah_cal_list_curr
;
6083 struct hal_channel_internal
*ichan
=
6084 ath9k_regd_check_channel(ah
, chan
);
6088 if (ichan
== NULL
) {
6089 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
,
6090 "%s: invalid channel %u/0x%x; no mapping\n",
6091 __func__
, chan
->channel
, chan
->channelFlags
);
6096 (currCal
->calState
== CAL_RUNNING
||
6097 currCal
->calState
== CAL_WAITING
)) {
6098 ath9k_hw_per_calibration(ah
, ichan
, rxchainmask
, currCal
,
6101 ahp
->ah_cal_list_curr
= currCal
= currCal
->calNext
;
6103 if (currCal
->calState
== CAL_WAITING
) {
6105 ath9k_hw_reset_calibration(ah
, currCal
);
6111 ath9k_hw_getnf(ah
, ichan
);
6112 ath9k_hw_loadnf(ah
, ah
->ah_curchan
);
6113 ath9k_hw_start_nfcal(ah
);
6115 if ((ichan
->channelFlags
& CHANNEL_CW_INT
) != 0) {
6117 chan
->channelFlags
|= CHANNEL_CW_INT
;
6118 ichan
->channelFlags
&= ~CHANNEL_CW_INT
;
6125 static void ath9k_hw_iqcal_collect(struct ath_hal
*ah
)
6127 struct ath_hal_5416
*ahp
= AH5416(ah
);
6130 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
6131 ahp
->ah_totalPowerMeasI
[i
] +=
6132 REG_READ(ah
, AR_PHY_CAL_MEAS_0(i
));
6133 ahp
->ah_totalPowerMeasQ
[i
] +=
6134 REG_READ(ah
, AR_PHY_CAL_MEAS_1(i
));
6135 ahp
->ah_totalIqCorrMeas
[i
] +=
6136 (int32_t) REG_READ(ah
, AR_PHY_CAL_MEAS_2(i
));
6137 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6138 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6139 ahp
->ah_CalSamples
, i
, ahp
->ah_totalPowerMeasI
[i
],
6140 ahp
->ah_totalPowerMeasQ
[i
],
6141 ahp
->ah_totalIqCorrMeas
[i
]);
6145 static void ath9k_hw_adc_gaincal_collect(struct ath_hal
*ah
)
6147 struct ath_hal_5416
*ahp
= AH5416(ah
);
6150 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
6151 ahp
->ah_totalAdcIOddPhase
[i
] +=
6152 REG_READ(ah
, AR_PHY_CAL_MEAS_0(i
));
6153 ahp
->ah_totalAdcIEvenPhase
[i
] +=
6154 REG_READ(ah
, AR_PHY_CAL_MEAS_1(i
));
6155 ahp
->ah_totalAdcQOddPhase
[i
] +=
6156 REG_READ(ah
, AR_PHY_CAL_MEAS_2(i
));
6157 ahp
->ah_totalAdcQEvenPhase
[i
] +=
6158 REG_READ(ah
, AR_PHY_CAL_MEAS_3(i
));
6160 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6161 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6162 "oddq=0x%08x; evenq=0x%08x;\n",
6163 ahp
->ah_CalSamples
, i
,
6164 ahp
->ah_totalAdcIOddPhase
[i
],
6165 ahp
->ah_totalAdcIEvenPhase
[i
],
6166 ahp
->ah_totalAdcQOddPhase
[i
],
6167 ahp
->ah_totalAdcQEvenPhase
[i
]);
6171 static void ath9k_hw_adc_dccal_collect(struct ath_hal
*ah
)
6173 struct ath_hal_5416
*ahp
= AH5416(ah
);
6176 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
6177 ahp
->ah_totalAdcDcOffsetIOddPhase
[i
] +=
6178 (int32_t) REG_READ(ah
, AR_PHY_CAL_MEAS_0(i
));
6179 ahp
->ah_totalAdcDcOffsetIEvenPhase
[i
] +=
6180 (int32_t) REG_READ(ah
, AR_PHY_CAL_MEAS_1(i
));
6181 ahp
->ah_totalAdcDcOffsetQOddPhase
[i
] +=
6182 (int32_t) REG_READ(ah
, AR_PHY_CAL_MEAS_2(i
));
6183 ahp
->ah_totalAdcDcOffsetQEvenPhase
[i
] +=
6184 (int32_t) REG_READ(ah
, AR_PHY_CAL_MEAS_3(i
));
6186 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6187 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6188 "oddq=0x%08x; evenq=0x%08x;\n",
6189 ahp
->ah_CalSamples
, i
,
6190 ahp
->ah_totalAdcDcOffsetIOddPhase
[i
],
6191 ahp
->ah_totalAdcDcOffsetIEvenPhase
[i
],
6192 ahp
->ah_totalAdcDcOffsetQOddPhase
[i
],
6193 ahp
->ah_totalAdcDcOffsetQEvenPhase
[i
]);
6197 static void ath9k_hw_iqcalibrate(struct ath_hal
*ah
, u_int8_t numChains
)
6199 struct ath_hal_5416
*ahp
= AH5416(ah
);
6200 u_int32_t powerMeasQ
, powerMeasI
, iqCorrMeas
;
6201 u_int32_t qCoffDenom
, iCoffDenom
;
6202 int32_t qCoff
, iCoff
;
6205 for (i
= 0; i
< numChains
; i
++) {
6206 powerMeasI
= ahp
->ah_totalPowerMeasI
[i
];
6207 powerMeasQ
= ahp
->ah_totalPowerMeasQ
[i
];
6208 iqCorrMeas
= ahp
->ah_totalIqCorrMeas
[i
];
6210 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6211 "Starting IQ Cal and Correction for Chain %d\n",
6214 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6215 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6216 i
, ahp
->ah_totalIqCorrMeas
[i
]);
6221 if (iqCorrMeas
> 0x80000000) {
6222 iqCorrMeas
= (0xffffffff - iqCorrMeas
) + 1;
6226 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6227 "Chn %d pwr_meas_i = 0x%08x\n", i
, powerMeasI
);
6228 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6229 "Chn %d pwr_meas_q = 0x%08x\n", i
, powerMeasQ
);
6230 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
, "iqCorrNeg is 0x%08x\n",
6233 iCoffDenom
= (powerMeasI
/ 2 + powerMeasQ
/ 2) / 128;
6234 qCoffDenom
= powerMeasQ
/ 64;
6236 if (powerMeasQ
!= 0) {
6238 iCoff
= iqCorrMeas
/ iCoffDenom
;
6239 qCoff
= powerMeasI
/ qCoffDenom
- 64;
6240 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6241 "Chn %d iCoff = 0x%08x\n", i
, iCoff
);
6242 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6243 "Chn %d qCoff = 0x%08x\n", i
, qCoff
);
6246 iCoff
= iCoff
& 0x3f;
6247 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6248 "New: Chn %d iCoff = 0x%08x\n", i
, iCoff
);
6249 if (iqCorrNeg
== 0x0)
6250 iCoff
= 0x40 - iCoff
;
6254 else if (qCoff
<= -16)
6257 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6258 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6261 REG_RMW_FIELD(ah
, AR_PHY_TIMING_CTRL4(i
),
6262 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
,
6264 REG_RMW_FIELD(ah
, AR_PHY_TIMING_CTRL4(i
),
6265 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
,
6267 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6268 "IQ Cal and Correction done for Chain %d\n",
6273 REG_SET_BIT(ah
, AR_PHY_TIMING_CTRL4(0),
6274 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE
);
6278 ath9k_hw_adc_gaincal_calibrate(struct ath_hal
*ah
, u_int8_t numChains
)
6280 struct ath_hal_5416
*ahp
= AH5416(ah
);
6281 u_int32_t iOddMeasOffset
, iEvenMeasOffset
, qOddMeasOffset
,
6283 u_int32_t qGainMismatch
, iGainMismatch
, val
, i
;
6285 for (i
= 0; i
< numChains
; i
++) {
6286 iOddMeasOffset
= ahp
->ah_totalAdcIOddPhase
[i
];
6287 iEvenMeasOffset
= ahp
->ah_totalAdcIEvenPhase
[i
];
6288 qOddMeasOffset
= ahp
->ah_totalAdcQOddPhase
[i
];
6289 qEvenMeasOffset
= ahp
->ah_totalAdcQEvenPhase
[i
];
6291 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6292 "Starting ADC Gain Cal for Chain %d\n", i
);
6294 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6295 "Chn %d pwr_meas_odd_i = 0x%08x\n", i
,
6297 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6298 "Chn %d pwr_meas_even_i = 0x%08x\n", i
,
6300 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6301 "Chn %d pwr_meas_odd_q = 0x%08x\n", i
,
6303 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6304 "Chn %d pwr_meas_even_q = 0x%08x\n", i
,
6307 if (iOddMeasOffset
!= 0 && qEvenMeasOffset
!= 0) {
6309 ((iEvenMeasOffset
* 32) /
6310 iOddMeasOffset
) & 0x3f;
6312 ((qOddMeasOffset
* 32) /
6313 qEvenMeasOffset
) & 0x3f;
6315 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6316 "Chn %d gain_mismatch_i = 0x%08x\n", i
,
6318 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6319 "Chn %d gain_mismatch_q = 0x%08x\n", i
,
6322 val
= REG_READ(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(i
));
6324 val
|= (qGainMismatch
) | (iGainMismatch
<< 6);
6325 REG_WRITE(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(i
), val
);
6327 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6328 "ADC Gain Cal done for Chain %d\n", i
);
6332 REG_WRITE(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6333 REG_READ(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6334 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE
);
6338 ath9k_hw_adc_dccal_calibrate(struct ath_hal
*ah
, u_int8_t numChains
)
6340 struct ath_hal_5416
*ahp
= AH5416(ah
);
6341 u_int32_t iOddMeasOffset
, iEvenMeasOffset
, val
, i
;
6342 int32_t qOddMeasOffset
, qEvenMeasOffset
, qDcMismatch
, iDcMismatch
;
6343 const struct hal_percal_data
*calData
=
6344 ahp
->ah_cal_list_curr
->calData
;
6345 u_int32_t numSamples
=
6346 (1 << (calData
->calCountMax
+ 5)) * calData
->calNumSamples
;
6348 for (i
= 0; i
< numChains
; i
++) {
6349 iOddMeasOffset
= ahp
->ah_totalAdcDcOffsetIOddPhase
[i
];
6350 iEvenMeasOffset
= ahp
->ah_totalAdcDcOffsetIEvenPhase
[i
];
6351 qOddMeasOffset
= ahp
->ah_totalAdcDcOffsetQOddPhase
[i
];
6352 qEvenMeasOffset
= ahp
->ah_totalAdcDcOffsetQEvenPhase
[i
];
6354 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6355 "Starting ADC DC Offset Cal for Chain %d\n", i
);
6357 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6358 "Chn %d pwr_meas_odd_i = %d\n", i
,
6360 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6361 "Chn %d pwr_meas_even_i = %d\n", i
,
6363 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6364 "Chn %d pwr_meas_odd_q = %d\n", i
,
6366 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6367 "Chn %d pwr_meas_even_q = %d\n", i
,
6370 iDcMismatch
= (((iEvenMeasOffset
- iOddMeasOffset
) * 2) /
6371 numSamples
) & 0x1ff;
6372 qDcMismatch
= (((qOddMeasOffset
- qEvenMeasOffset
) * 2) /
6373 numSamples
) & 0x1ff;
6375 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6376 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i
,
6378 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6379 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i
,
6382 val
= REG_READ(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(i
));
6384 val
|= (qDcMismatch
<< 12) | (iDcMismatch
<< 21);
6385 REG_WRITE(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(i
), val
);
6387 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6388 "ADC DC Offset Cal done for Chain %d\n", i
);
6391 REG_WRITE(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6392 REG_READ(ah
, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6393 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE
);
6396 bool ath9k_hw_set_txpowerlimit(struct ath_hal
*ah
, u_int32_t limit
)
6398 struct ath_hal_5416
*ahp
= AH5416(ah
);
6399 struct hal_channel_internal
*ichan
= ah
->ah_curchan
;
6400 struct hal_channel
*chan
= (struct hal_channel
*) ichan
;
6402 ah
->ah_powerLimit
= min(limit
, (u_int32_t
) MAX_RATE_POWER
);
6404 if (ath9k_hw_set_txpower(ah
, &ahp
->ah_eeprom
, ichan
,
6405 ath9k_regd_get_ctl(ah
, chan
),
6406 ath9k_regd_get_antenna_allowed(ah
,
6408 chan
->maxRegTxPower
* 2,
6409 min((u_int32_t
) MAX_RATE_POWER
,
6410 (u_int32_t
) ah
->ah_powerLimit
))
6418 ath9k_hw_get_channel_centers(struct ath_hal
*ah
,
6419 struct hal_channel_internal
*chan
,
6420 struct chan_centers
*centers
)
6423 struct ath_hal_5416
*ahp
= AH5416(ah
);
6425 if (!IS_CHAN_HT40(chan
)) {
6426 centers
->ctl_center
= centers
->ext_center
=
6427 centers
->synth_center
= chan
->channel
;
6431 if (chan
->channelFlags
& CHANNEL_HT40PLUS
) {
6432 centers
->synth_center
=
6433 chan
->channel
+ HT40_CHANNEL_CENTER_SHIFT
;
6436 centers
->synth_center
=
6437 chan
->channel
- HT40_CHANNEL_CENTER_SHIFT
;
6441 centers
->ctl_center
= centers
->synth_center
- (extoff
*
6442 HT40_CHANNEL_CENTER_SHIFT
);
6443 centers
->ext_center
= centers
->synth_center
+ (extoff
*
6447 HAL_HT_EXTPROTSPACING_20
)
6449 HT40_CHANNEL_CENTER_SHIFT
6455 ath9k_hw_reset_calvalid(struct ath_hal
*ah
, struct hal_channel
*chan
,
6458 struct ath_hal_5416
*ahp
= AH5416(ah
);
6459 struct hal_channel_internal
*ichan
=
6460 ath9k_regd_check_channel(ah
, chan
);
6461 struct hal_cal_list
*currCal
= ahp
->ah_cal_list_curr
;
6465 if (!AR_SREV_9100(ah
) && !AR_SREV_9160_10_OR_LATER(ah
))
6468 if (currCal
== NULL
)
6471 if (ichan
== NULL
) {
6472 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6473 "%s: invalid channel %u/0x%x; no mapping\n",
6474 __func__
, chan
->channel
, chan
->channelFlags
);
6479 if (currCal
->calState
!= CAL_DONE
) {
6480 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6481 "%s: Calibration state incorrect, %d\n",
6482 __func__
, currCal
->calState
);
6487 if (!ath9k_hw_iscal_supported(ah
, chan
, currCal
->calData
->calType
)) {
6491 DPRINTF(ah
->ah_sc
, ATH_DBG_CALIBRATE
,
6492 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6493 __func__
, currCal
->calData
->calType
, chan
->channel
,
6494 chan
->channelFlags
);
6496 ichan
->CalValid
&= ~currCal
->calData
->calType
;
6497 currCal
->calState
= CAL_WAITING
;
6502 void ath9k_hw_getmac(struct ath_hal
*ah
, u_int8_t
*mac
)
6504 struct ath_hal_5416
*ahp
= AH5416(ah
);
6506 memcpy(mac
, ahp
->ah_macaddr
, ETH_ALEN
);
6509 bool ath9k_hw_setmac(struct ath_hal
*ah
, const u_int8_t
*mac
)
6511 struct ath_hal_5416
*ahp
= AH5416(ah
);
6513 memcpy(ahp
->ah_macaddr
, mac
, ETH_ALEN
);
6517 void ath9k_hw_getbssidmask(struct ath_hal
*ah
, u_int8_t
*mask
)
6519 struct ath_hal_5416
*ahp
= AH5416(ah
);
6521 memcpy(mask
, ahp
->ah_bssidmask
, ETH_ALEN
);
6525 ath9k_hw_setbssidmask(struct ath_hal
*ah
, const u_int8_t
*mask
)
6527 struct ath_hal_5416
*ahp
= AH5416(ah
);
6529 memcpy(ahp
->ah_bssidmask
, mask
, ETH_ALEN
);
6531 REG_WRITE(ah
, AR_BSSMSKL
, LE_READ_4(ahp
->ah_bssidmask
));
6532 REG_WRITE(ah
, AR_BSSMSKU
, LE_READ_2(ahp
->ah_bssidmask
+ 4));
6537 #ifdef CONFIG_ATH9K_RFKILL
6538 static void ath9k_enable_rfkill(struct ath_hal
*ah
)
6540 struct ath_hal_5416
*ahp
= AH5416(ah
);
6542 REG_SET_BIT(ah
, AR_GPIO_INPUT_EN_VAL
,
6543 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB
);
6545 REG_CLR_BIT(ah
, AR_GPIO_INPUT_MUX2
,
6546 AR_GPIO_INPUT_MUX2_RFSILENT
);
6548 ath9k_hw_cfg_gpio_input(ah
, ahp
->ah_gpioSelect
);
6549 REG_SET_BIT(ah
, AR_PHY_TEST
, RFSILENT_BB
);
6551 if (ahp
->ah_gpioBit
== ath9k_hw_gpio_get(ah
, ahp
->ah_gpioSelect
)) {
6553 ath9k_hw_set_gpio_intr(ah
, ahp
->ah_gpioSelect
,
6556 ath9k_hw_set_gpio_intr(ah
, ahp
->ah_gpioSelect
,
6563 ath9k_hw_write_associd(struct ath_hal
*ah
, const u_int8_t
*bssid
,
6566 struct ath_hal_5416
*ahp
= AH5416(ah
);
6568 memcpy(ahp
->ah_bssid
, bssid
, ETH_ALEN
);
6569 ahp
->ah_assocId
= assocId
;
6571 REG_WRITE(ah
, AR_BSS_ID0
, LE_READ_4(ahp
->ah_bssid
));
6572 REG_WRITE(ah
, AR_BSS_ID1
, LE_READ_2(ahp
->ah_bssid
+ 4) |
6573 ((assocId
& 0x3fff) << AR_BSS_ID1_AID_S
));
6576 u_int64_t
ath9k_hw_gettsf64(struct ath_hal
*ah
)
6580 tsf
= REG_READ(ah
, AR_TSF_U32
);
6581 tsf
= (tsf
<< 32) | REG_READ(ah
, AR_TSF_L32
);
6585 void ath9k_hw_reset_tsf(struct ath_hal
*ah
)
6590 while (REG_READ(ah
, AR_SLP32_MODE
) & AR_SLP32_TSF_WRITE_STATUS
) {
6593 DPRINTF(ah
->ah_sc
, ATH_DBG_RESET
,
6594 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6600 REG_WRITE(ah
, AR_RESET_TSF
, AR_RESET_TSF_ONCE
);
6603 u_int
ath9k_hw_getdefantenna(struct ath_hal
*ah
)
6605 return REG_READ(ah
, AR_DEF_ANTENNA
) & 0x7;
6608 void ath9k_hw_setantenna(struct ath_hal
*ah
, u_int antenna
)
6610 REG_WRITE(ah
, AR_DEF_ANTENNA
, (antenna
& 0x7));
6614 ath9k_hw_setantennaswitch(struct ath_hal
*ah
,
6615 enum hal_ant_setting settings
,
6616 struct hal_channel
*chan
,
6617 u_int8_t
*tx_chainmask
,
6618 u_int8_t
*rx_chainmask
,
6619 u_int8_t
*antenna_cfgd
)
6621 struct ath_hal_5416
*ahp
= AH5416(ah
);
6622 static u_int8_t tx_chainmask_cfg
, rx_chainmask_cfg
;
6624 if (AR_SREV_9280(ah
)) {
6625 if (!tx_chainmask_cfg
) {
6627 tx_chainmask_cfg
= *tx_chainmask
;
6628 rx_chainmask_cfg
= *rx_chainmask
;
6632 case HAL_ANT_FIXED_A
:
6633 *tx_chainmask
= ATH9K_ANTENNA0_CHAINMASK
;
6634 *rx_chainmask
= ATH9K_ANTENNA0_CHAINMASK
;
6635 *antenna_cfgd
= true;
6637 case HAL_ANT_FIXED_B
:
6638 if (ah
->ah_caps
.halTxChainMask
>
6639 ATH9K_ANTENNA1_CHAINMASK
) {
6640 *tx_chainmask
= ATH9K_ANTENNA1_CHAINMASK
;
6642 *rx_chainmask
= ATH9K_ANTENNA1_CHAINMASK
;
6643 *antenna_cfgd
= true;
6645 case HAL_ANT_VARIABLE
:
6646 *tx_chainmask
= tx_chainmask_cfg
;
6647 *rx_chainmask
= rx_chainmask_cfg
;
6648 *antenna_cfgd
= true;
6654 ahp
->ah_diversityControl
= settings
;
6660 void ath9k_hw_setopmode(struct ath_hal
*ah
)
6662 ath9k_hw_set_operating_mode(ah
, ah
->ah_opmode
);
6666 ath9k_hw_getcapability(struct ath_hal
*ah
, enum hal_capability_type type
,
6667 u_int32_t capability
, u_int32_t
*result
)
6669 struct ath_hal_5416
*ahp
= AH5416(ah
);
6670 const struct hal_capabilities
*pCap
= &ah
->ah_caps
;
6673 case HAL_CAP_CIPHER
:
6674 switch (capability
) {
6675 case HAL_CIPHER_AES_CCM
:
6676 case HAL_CIPHER_AES_OCB
:
6677 case HAL_CIPHER_TKIP
:
6678 case HAL_CIPHER_WEP
:
6679 case HAL_CIPHER_MIC
:
6680 case HAL_CIPHER_CLR
:
6685 case HAL_CAP_TKIP_MIC
:
6686 switch (capability
) {
6690 return (ahp
->ah_staId1Defaults
&
6691 AR_STA_ID1_CRPT_MIC_ENABLE
) ? true :
6694 case HAL_CAP_TKIP_SPLIT
:
6695 return (ahp
->ah_miscMode
& AR_PCU_MIC_NEW_LOC_ENA
) ?
6697 case HAL_CAP_WME_TKIPMIC
:
6699 case HAL_CAP_PHYCOUNTERS
:
6700 return ahp
->ah_hasHwPhyCounters
? HAL_OK
: HAL_ENXIO
;
6701 case HAL_CAP_DIVERSITY
:
6702 return (REG_READ(ah
, AR_PHY_CCK_DETECT
) &
6703 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
) ?
6705 case HAL_CAP_PHYDIAG
:
6707 case HAL_CAP_MCAST_KEYSRCH
:
6708 switch (capability
) {
6712 if (REG_READ(ah
, AR_STA_ID1
) & AR_STA_ID1_ADHOC
) {
6715 return (ahp
->ah_staId1Defaults
&
6716 AR_STA_ID1_MCAST_KSRCH
) ? true :
6721 case HAL_CAP_TSF_ADJUST
:
6722 return (ahp
->ah_miscMode
& AR_PCU_TX_ADD_TSF
) ?
6724 case HAL_CAP_RFSILENT
:
6725 if (capability
== 3)
6727 case HAL_CAP_ANT_CFG_2GHZ
:
6728 *result
= pCap
->halNumAntCfg2GHz
;
6730 case HAL_CAP_ANT_CFG_5GHZ
:
6731 *result
= pCap
->halNumAntCfg5GHz
;
6734 switch (capability
) {
6738 *result
= ah
->ah_powerLimit
;
6741 *result
= ah
->ah_maxPowerLevel
;
6744 *result
= ah
->ah_tpScale
;
6754 ath9k_hw_select_antconfig(struct ath_hal
*ah
, u_int32_t cfg
)
6756 struct ath_hal_5416
*ahp
= AH5416(ah
);
6757 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
6758 const struct hal_capabilities
*pCap
= &ah
->ah_caps
;
6759 u_int16_t ant_config
;
6760 u_int32_t halNumAntConfig
;
6763 IS_CHAN_2GHZ(chan
) ? pCap
->halNumAntCfg2GHz
: pCap
->
6766 if (cfg
< halNumAntConfig
) {
6768 ath9k_hw_get_eeprom_antenna_cfg(ahp
, chan
, cfg
,
6770 REG_WRITE(ah
, AR_PHY_SWITCH_COM
, ant_config
);
6778 bool ath9k_hw_intrpend(struct ath_hal
*ah
)
6782 if (AR_SREV_9100(ah
))
6785 host_isr
= REG_READ(ah
, AR_INTR_ASYNC_CAUSE
);
6786 if ((host_isr
& AR_INTR_MAC_IRQ
) && (host_isr
!= AR_INTR_SPURIOUS
))
6789 host_isr
= REG_READ(ah
, AR_INTR_SYNC_CAUSE
);
6790 if ((host_isr
& AR_INTR_SYNC_DEFAULT
)
6791 && (host_isr
!= AR_INTR_SPURIOUS
))
6797 bool ath9k_hw_getisr(struct ath_hal
*ah
, enum hal_int
*masked
)
6800 u_int32_t mask2
= 0;
6801 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
6802 u_int32_t sync_cause
= 0;
6803 bool fatal_int
= false;
6805 if (!AR_SREV_9100(ah
)) {
6806 if (REG_READ(ah
, AR_INTR_ASYNC_CAUSE
) & AR_INTR_MAC_IRQ
) {
6807 if ((REG_READ(ah
, AR_RTC_STATUS
) & AR_RTC_STATUS_M
)
6808 == AR_RTC_STATUS_ON
) {
6809 isr
= REG_READ(ah
, AR_ISR
);
6815 AR_INTR_SYNC_CAUSE
) & AR_INTR_SYNC_DEFAULT
;
6819 if (!isr
&& !sync_cause
)
6823 isr
= REG_READ(ah
, AR_ISR
);
6827 struct ath_hal_5416
*ahp
= AH5416(ah
);
6829 if (isr
& AR_ISR_BCNMISC
) {
6831 isr2
= REG_READ(ah
, AR_ISR_S2
);
6832 if (isr2
& AR_ISR_S2_TIM
)
6833 mask2
|= HAL_INT_TIM
;
6834 if (isr2
& AR_ISR_S2_DTIM
)
6835 mask2
|= HAL_INT_DTIM
;
6836 if (isr2
& AR_ISR_S2_DTIMSYNC
)
6837 mask2
|= HAL_INT_DTIMSYNC
;
6838 if (isr2
& (AR_ISR_S2_CABEND
))
6839 mask2
|= HAL_INT_CABEND
;
6840 if (isr2
& AR_ISR_S2_GTT
)
6841 mask2
|= HAL_INT_GTT
;
6842 if (isr2
& AR_ISR_S2_CST
)
6843 mask2
|= HAL_INT_CST
;
6846 isr
= REG_READ(ah
, AR_ISR_RAC
);
6847 if (isr
== 0xffffffff) {
6852 *masked
= isr
& HAL_INT_COMMON
;
6854 if (ahp
->ah_intrMitigation
) {
6856 if (isr
& (AR_ISR_RXMINTR
| AR_ISR_RXINTM
))
6857 *masked
|= HAL_INT_RX
;
6860 if (isr
& (AR_ISR_RXOK
| AR_ISR_RXERR
))
6861 *masked
|= HAL_INT_RX
;
6863 (AR_ISR_TXOK
| AR_ISR_TXDESC
| AR_ISR_TXERR
|
6865 u_int32_t s0_s
, s1_s
;
6867 *masked
|= HAL_INT_TX
;
6869 s0_s
= REG_READ(ah
, AR_ISR_S0_S
);
6870 ahp
->ah_intrTxqs
|= MS(s0_s
, AR_ISR_S0_QCU_TXOK
);
6871 ahp
->ah_intrTxqs
|= MS(s0_s
, AR_ISR_S0_QCU_TXDESC
);
6873 s1_s
= REG_READ(ah
, AR_ISR_S1_S
);
6874 ahp
->ah_intrTxqs
|= MS(s1_s
, AR_ISR_S1_QCU_TXERR
);
6875 ahp
->ah_intrTxqs
|= MS(s1_s
, AR_ISR_S1_QCU_TXEOL
);
6878 if (isr
& AR_ISR_RXORN
) {
6879 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
,
6880 "%s: receive FIFO overrun interrupt\n",
6884 if (!AR_SREV_9100(ah
)) {
6885 if (!pCap
->halAutoSleepSupport
) {
6886 u_int32_t isr5
= REG_READ(ah
, AR_ISR_S5_S
);
6887 if (isr5
& AR_ISR_S5_TIM_TIMER
)
6888 *masked
|= HAL_INT_TIM_TIMER
;
6894 if (AR_SREV_9100(ah
))
6899 (AR_INTR_SYNC_HOST1_FATAL
| AR_INTR_SYNC_HOST1_PERR
))
6903 if (sync_cause
& AR_INTR_SYNC_HOST1_FATAL
) {
6904 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
6905 "%s: received PCI FATAL interrupt\n",
6908 if (sync_cause
& AR_INTR_SYNC_HOST1_PERR
) {
6909 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
6910 "%s: received PCI PERR interrupt\n",
6914 if (sync_cause
& AR_INTR_SYNC_RADM_CPL_TIMEOUT
) {
6915 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
,
6916 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6918 REG_WRITE(ah
, AR_RC
, AR_RC_HOSTIF
);
6919 REG_WRITE(ah
, AR_RC
, 0);
6920 *masked
|= HAL_INT_FATAL
;
6922 if (sync_cause
& AR_INTR_SYNC_LOCAL_TIMEOUT
) {
6923 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
,
6924 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6928 REG_WRITE(ah
, AR_INTR_SYNC_CAUSE_CLR
, sync_cause
);
6929 (void) REG_READ(ah
, AR_INTR_SYNC_CAUSE_CLR
);
6934 enum hal_int
ath9k_hw_intrget(struct ath_hal
*ah
)
6936 return AH5416(ah
)->ah_maskReg
;
6939 enum hal_int
ath9k_hw_set_interrupts(struct ath_hal
*ah
, enum hal_int ints
)
6941 struct ath_hal_5416
*ahp
= AH5416(ah
);
6942 u_int32_t omask
= ahp
->ah_maskReg
;
6943 u_int32_t mask
, mask2
;
6944 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
6946 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
, "%s: 0x%x => 0x%x\n", __func__
,
6949 if (omask
& HAL_INT_GLOBAL
) {
6950 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
, "%s: disable IER\n",
6952 REG_WRITE(ah
, AR_IER
, AR_IER_DISABLE
);
6953 (void) REG_READ(ah
, AR_IER
);
6954 if (!AR_SREV_9100(ah
)) {
6955 REG_WRITE(ah
, AR_INTR_ASYNC_ENABLE
, 0);
6956 (void) REG_READ(ah
, AR_INTR_ASYNC_ENABLE
);
6958 REG_WRITE(ah
, AR_INTR_SYNC_ENABLE
, 0);
6959 (void) REG_READ(ah
, AR_INTR_SYNC_ENABLE
);
6963 mask
= ints
& HAL_INT_COMMON
;
6966 if (ints
& HAL_INT_TX
) {
6967 if (ahp
->ah_txOkInterruptMask
)
6968 mask
|= AR_IMR_TXOK
;
6969 if (ahp
->ah_txDescInterruptMask
)
6970 mask
|= AR_IMR_TXDESC
;
6971 if (ahp
->ah_txErrInterruptMask
)
6972 mask
|= AR_IMR_TXERR
;
6973 if (ahp
->ah_txEolInterruptMask
)
6974 mask
|= AR_IMR_TXEOL
;
6976 if (ints
& HAL_INT_RX
) {
6977 mask
|= AR_IMR_RXERR
;
6978 if (ahp
->ah_intrMitigation
)
6979 mask
|= AR_IMR_RXMINTR
| AR_IMR_RXINTM
;
6981 mask
|= AR_IMR_RXOK
| AR_IMR_RXDESC
;
6982 if (!pCap
->halAutoSleepSupport
)
6983 mask
|= AR_IMR_GENTMR
;
6986 if (ints
& (HAL_INT_BMISC
)) {
6987 mask
|= AR_IMR_BCNMISC
;
6988 if (ints
& HAL_INT_TIM
)
6989 mask2
|= AR_IMR_S2_TIM
;
6990 if (ints
& HAL_INT_DTIM
)
6991 mask2
|= AR_IMR_S2_DTIM
;
6992 if (ints
& HAL_INT_DTIMSYNC
)
6993 mask2
|= AR_IMR_S2_DTIMSYNC
;
6994 if (ints
& HAL_INT_CABEND
)
6995 mask2
|= (AR_IMR_S2_CABEND
);
6998 if (ints
& (HAL_INT_GTT
| HAL_INT_CST
)) {
6999 mask
|= AR_IMR_BCNMISC
;
7000 if (ints
& HAL_INT_GTT
)
7001 mask2
|= AR_IMR_S2_GTT
;
7002 if (ints
& HAL_INT_CST
)
7003 mask2
|= AR_IMR_S2_CST
;
7006 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
, "%s: new IMR 0x%x\n", __func__
,
7008 REG_WRITE(ah
, AR_IMR
, mask
);
7009 mask
= REG_READ(ah
, AR_IMR_S2
) & ~(AR_IMR_S2_TIM
|
7011 AR_IMR_S2_DTIMSYNC
|
7015 AR_IMR_S2_GTT
| AR_IMR_S2_CST
);
7016 REG_WRITE(ah
, AR_IMR_S2
, mask
| mask2
);
7017 ahp
->ah_maskReg
= ints
;
7019 if (!pCap
->halAutoSleepSupport
) {
7020 if (ints
& HAL_INT_TIM_TIMER
)
7021 REG_SET_BIT(ah
, AR_IMR_S5
, AR_IMR_S5_TIM_TIMER
);
7023 REG_CLR_BIT(ah
, AR_IMR_S5
, AR_IMR_S5_TIM_TIMER
);
7026 if (ints
& HAL_INT_GLOBAL
) {
7027 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
, "%s: enable IER\n",
7029 REG_WRITE(ah
, AR_IER
, AR_IER_ENABLE
);
7030 if (!AR_SREV_9100(ah
)) {
7031 REG_WRITE(ah
, AR_INTR_ASYNC_ENABLE
,
7033 REG_WRITE(ah
, AR_INTR_ASYNC_MASK
, AR_INTR_MAC_IRQ
);
7036 REG_WRITE(ah
, AR_INTR_SYNC_ENABLE
,
7037 AR_INTR_SYNC_DEFAULT
);
7038 REG_WRITE(ah
, AR_INTR_SYNC_MASK
,
7039 AR_INTR_SYNC_DEFAULT
);
7041 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
, "AR_IMR 0x%x IER 0x%x\n",
7042 REG_READ(ah
, AR_IMR
), REG_READ(ah
, AR_IER
));
7049 ath9k_hw_beaconinit(struct ath_hal
*ah
,
7050 u_int32_t next_beacon
, u_int32_t beacon_period
)
7052 struct ath_hal_5416
*ahp
= AH5416(ah
);
7055 ahp
->ah_beaconInterval
= beacon_period
;
7057 switch (ah
->ah_opmode
) {
7060 REG_WRITE(ah
, AR_NEXT_TBTT_TIMER
, TU_TO_USEC(next_beacon
));
7061 REG_WRITE(ah
, AR_NEXT_DMA_BEACON_ALERT
, 0xffff);
7062 REG_WRITE(ah
, AR_NEXT_SWBA
, 0x7ffff);
7063 flags
|= AR_TBTT_TIMER_EN
;
7066 REG_SET_BIT(ah
, AR_TXCFG
,
7067 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY
);
7068 REG_WRITE(ah
, AR_NEXT_NDP_TIMER
,
7069 TU_TO_USEC(next_beacon
+
7070 (ahp
->ah_atimWindow
? ahp
->
7071 ah_atimWindow
: 1)));
7072 flags
|= AR_NDP_TIMER_EN
;
7074 REG_WRITE(ah
, AR_NEXT_TBTT_TIMER
, TU_TO_USEC(next_beacon
));
7075 REG_WRITE(ah
, AR_NEXT_DMA_BEACON_ALERT
,
7076 TU_TO_USEC(next_beacon
-
7078 ath_hal_dma_beacon_response_time
));
7079 REG_WRITE(ah
, AR_NEXT_SWBA
,
7080 TU_TO_USEC(next_beacon
-
7082 ath_hal_sw_beacon_response_time
));
7084 AR_TBTT_TIMER_EN
| AR_DBA_TIMER_EN
| AR_SWBA_TIMER_EN
;
7088 REG_WRITE(ah
, AR_BEACON_PERIOD
, TU_TO_USEC(beacon_period
));
7089 REG_WRITE(ah
, AR_DMA_BEACON_PERIOD
, TU_TO_USEC(beacon_period
));
7090 REG_WRITE(ah
, AR_SWBA_PERIOD
, TU_TO_USEC(beacon_period
));
7091 REG_WRITE(ah
, AR_NDP_PERIOD
, TU_TO_USEC(beacon_period
));
7093 beacon_period
&= ~HAL_BEACON_ENA
;
7094 if (beacon_period
& HAL_BEACON_RESET_TSF
) {
7095 beacon_period
&= ~HAL_BEACON_RESET_TSF
;
7096 ath9k_hw_reset_tsf(ah
);
7099 REG_SET_BIT(ah
, AR_TIMER_MODE
, flags
);
7103 ath9k_hw_set_sta_beacon_timers(struct ath_hal
*ah
,
7104 const struct hal_beacon_state
*bs
)
7106 u_int32_t nextTbtt
, beaconintval
, dtimperiod
, beacontimeout
;
7107 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7109 REG_WRITE(ah
, AR_NEXT_TBTT_TIMER
, TU_TO_USEC(bs
->bs_nexttbtt
));
7111 REG_WRITE(ah
, AR_BEACON_PERIOD
,
7112 TU_TO_USEC(bs
->bs_intval
& HAL_BEACON_PERIOD
));
7113 REG_WRITE(ah
, AR_DMA_BEACON_PERIOD
,
7114 TU_TO_USEC(bs
->bs_intval
& HAL_BEACON_PERIOD
));
7116 REG_RMW_FIELD(ah
, AR_RSSI_THR
,
7117 AR_RSSI_THR_BM_THR
, bs
->bs_bmissthreshold
);
7119 beaconintval
= bs
->bs_intval
& HAL_BEACON_PERIOD
;
7121 if (bs
->bs_sleepduration
> beaconintval
)
7122 beaconintval
= bs
->bs_sleepduration
;
7124 dtimperiod
= bs
->bs_dtimperiod
;
7125 if (bs
->bs_sleepduration
> dtimperiod
)
7126 dtimperiod
= bs
->bs_sleepduration
;
7128 if (beaconintval
== dtimperiod
)
7129 nextTbtt
= bs
->bs_nextdtim
;
7131 nextTbtt
= bs
->bs_nexttbtt
;
7133 DPRINTF(ah
->ah_sc
, ATH_DBG_BEACON
, "%s: next DTIM %d\n", __func__
,
7135 DPRINTF(ah
->ah_sc
, ATH_DBG_BEACON
, "%s: next beacon %d\n", __func__
,
7137 DPRINTF(ah
->ah_sc
, ATH_DBG_BEACON
, "%s: beacon period %d\n", __func__
,
7139 DPRINTF(ah
->ah_sc
, ATH_DBG_BEACON
, "%s: DTIM period %d\n", __func__
,
7142 REG_WRITE(ah
, AR_NEXT_DTIM
,
7143 TU_TO_USEC(bs
->bs_nextdtim
- SLEEP_SLOP
));
7144 REG_WRITE(ah
, AR_NEXT_TIM
, TU_TO_USEC(nextTbtt
- SLEEP_SLOP
));
7146 REG_WRITE(ah
, AR_SLEEP1
,
7147 SM((CAB_TIMEOUT_VAL
<< 3), AR_SLEEP1_CAB_TIMEOUT
)
7148 | AR_SLEEP1_ASSUME_DTIM
);
7150 if (pCap
->halAutoSleepSupport
)
7151 beacontimeout
= (BEACON_TIMEOUT_VAL
<< 3);
7153 beacontimeout
= MIN_BEACON_TIMEOUT_VAL
;
7155 REG_WRITE(ah
, AR_SLEEP2
,
7156 SM(beacontimeout
, AR_SLEEP2_BEACON_TIMEOUT
));
7158 REG_WRITE(ah
, AR_TIM_PERIOD
, TU_TO_USEC(beaconintval
));
7159 REG_WRITE(ah
, AR_DTIM_PERIOD
, TU_TO_USEC(dtimperiod
));
7161 REG_SET_BIT(ah
, AR_TIMER_MODE
,
7162 AR_TBTT_TIMER_EN
| AR_TIM_TIMER_EN
|
7167 bool ath9k_hw_keyisvalid(struct ath_hal
*ah
, u_int16_t entry
)
7169 if (entry
< ah
->ah_caps
.halKeyCacheSize
) {
7170 u_int32_t val
= REG_READ(ah
, AR_KEYTABLE_MAC1(entry
));
7171 if (val
& AR_KEYTABLE_VALID
)
7177 bool ath9k_hw_keyreset(struct ath_hal
*ah
, u_int16_t entry
)
7181 if (entry
>= ah
->ah_caps
.halKeyCacheSize
) {
7182 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7183 "%s: entry %u out of range\n", __func__
, entry
);
7186 keyType
= REG_READ(ah
, AR_KEYTABLE_TYPE(entry
));
7188 REG_WRITE(ah
, AR_KEYTABLE_KEY0(entry
), 0);
7189 REG_WRITE(ah
, AR_KEYTABLE_KEY1(entry
), 0);
7190 REG_WRITE(ah
, AR_KEYTABLE_KEY2(entry
), 0);
7191 REG_WRITE(ah
, AR_KEYTABLE_KEY3(entry
), 0);
7192 REG_WRITE(ah
, AR_KEYTABLE_KEY4(entry
), 0);
7193 REG_WRITE(ah
, AR_KEYTABLE_TYPE(entry
), AR_KEYTABLE_TYPE_CLR
);
7194 REG_WRITE(ah
, AR_KEYTABLE_MAC0(entry
), 0);
7195 REG_WRITE(ah
, AR_KEYTABLE_MAC1(entry
), 0);
7197 if (keyType
== AR_KEYTABLE_TYPE_TKIP
&& ATH9K_IS_MIC_ENABLED(ah
)) {
7198 u_int16_t micentry
= entry
+ 64;
7200 REG_WRITE(ah
, AR_KEYTABLE_KEY0(micentry
), 0);
7201 REG_WRITE(ah
, AR_KEYTABLE_KEY1(micentry
), 0);
7202 REG_WRITE(ah
, AR_KEYTABLE_KEY2(micentry
), 0);
7203 REG_WRITE(ah
, AR_KEYTABLE_KEY3(micentry
), 0);
7207 if (ah
->ah_curchan
== NULL
)
7214 ath9k_hw_keysetmac(struct ath_hal
*ah
, u_int16_t entry
,
7215 const u_int8_t
*mac
)
7217 u_int32_t macHi
, macLo
;
7219 if (entry
>= ah
->ah_caps
.halKeyCacheSize
) {
7220 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7221 "%s: entry %u out of range\n", __func__
, entry
);
7226 macHi
= (mac
[5] << 8) | mac
[4];
7227 macLo
= (mac
[3] << 24) | (mac
[2] << 16)
7228 | (mac
[1] << 8) | mac
[0];
7230 macLo
|= (macHi
& 1) << 31;
7235 REG_WRITE(ah
, AR_KEYTABLE_MAC0(entry
), macLo
);
7236 REG_WRITE(ah
, AR_KEYTABLE_MAC1(entry
), macHi
| AR_KEYTABLE_VALID
);
7242 ath9k_hw_set_keycache_entry(struct ath_hal
*ah
, u_int16_t entry
,
7243 const struct hal_keyval
*k
,
7244 const u_int8_t
*mac
, int xorKey
)
7246 const struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7247 u_int32_t key0
, key1
, key2
, key3
, key4
;
7249 u_int32_t xorMask
= xorKey
?
7250 (ATH9K_KEY_XOR
<< 24 | ATH9K_KEY_XOR
<< 16 | ATH9K_KEY_XOR
<< 8
7251 | ATH9K_KEY_XOR
) : 0;
7252 struct ath_hal_5416
*ahp
= AH5416(ah
);
7254 if (entry
>= pCap
->halKeyCacheSize
) {
7255 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7256 "%s: entry %u out of range\n", __func__
, entry
);
7259 switch (k
->kv_type
) {
7260 case HAL_CIPHER_AES_OCB
:
7261 keyType
= AR_KEYTABLE_TYPE_AES
;
7263 case HAL_CIPHER_AES_CCM
:
7264 if (!pCap
->halCipherAesCcmSupport
) {
7265 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7266 "%s: AES-CCM not supported by "
7267 "mac rev 0x%x\n", __func__
,
7271 keyType
= AR_KEYTABLE_TYPE_CCM
;
7273 case HAL_CIPHER_TKIP
:
7274 keyType
= AR_KEYTABLE_TYPE_TKIP
;
7275 if (ATH9K_IS_MIC_ENABLED(ah
)
7276 && entry
+ 64 >= pCap
->halKeyCacheSize
) {
7277 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7278 "%s: entry %u inappropriate for TKIP\n",
7283 case HAL_CIPHER_WEP
:
7284 if (k
->kv_len
< 40 / NBBY
) {
7285 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7286 "%s: WEP key length %u too small\n",
7287 __func__
, k
->kv_len
);
7290 if (k
->kv_len
<= 40 / NBBY
)
7291 keyType
= AR_KEYTABLE_TYPE_40
;
7292 else if (k
->kv_len
<= 104 / NBBY
)
7293 keyType
= AR_KEYTABLE_TYPE_104
;
7295 keyType
= AR_KEYTABLE_TYPE_128
;
7297 case HAL_CIPHER_CLR
:
7298 keyType
= AR_KEYTABLE_TYPE_CLR
;
7301 DPRINTF(ah
->ah_sc
, ATH_DBG_KEYCACHE
,
7302 "%s: cipher %u not supported\n", __func__
,
7307 key0
= LE_READ_4(k
->kv_val
+ 0) ^ xorMask
;
7308 key1
= (LE_READ_2(k
->kv_val
+ 4) ^ xorMask
) & 0xffff;
7309 key2
= LE_READ_4(k
->kv_val
+ 6) ^ xorMask
;
7310 key3
= (LE_READ_2(k
->kv_val
+ 10) ^ xorMask
) & 0xffff;
7311 key4
= LE_READ_4(k
->kv_val
+ 12) ^ xorMask
;
7312 if (k
->kv_len
<= 104 / NBBY
)
7315 if (keyType
== AR_KEYTABLE_TYPE_TKIP
&& ATH9K_IS_MIC_ENABLED(ah
)) {
7316 u_int16_t micentry
= entry
+ 64;
7318 REG_WRITE(ah
, AR_KEYTABLE_KEY0(entry
), ~key0
);
7319 REG_WRITE(ah
, AR_KEYTABLE_KEY1(entry
), ~key1
);
7320 REG_WRITE(ah
, AR_KEYTABLE_KEY2(entry
), key2
);
7321 REG_WRITE(ah
, AR_KEYTABLE_KEY3(entry
), key3
);
7322 REG_WRITE(ah
, AR_KEYTABLE_KEY4(entry
), key4
);
7323 REG_WRITE(ah
, AR_KEYTABLE_TYPE(entry
), keyType
);
7324 (void) ath9k_hw_keysetmac(ah
, entry
, mac
);
7326 if (ahp
->ah_miscMode
& AR_PCU_MIC_NEW_LOC_ENA
) {
7327 u_int32_t mic0
, mic1
, mic2
, mic3
, mic4
;
7329 mic0
= LE_READ_4(k
->kv_mic
+ 0);
7330 mic2
= LE_READ_4(k
->kv_mic
+ 4);
7331 mic1
= LE_READ_2(k
->kv_txmic
+ 2) & 0xffff;
7332 mic3
= LE_READ_2(k
->kv_txmic
+ 0) & 0xffff;
7333 mic4
= LE_READ_4(k
->kv_txmic
+ 4);
7334 REG_WRITE(ah
, AR_KEYTABLE_KEY0(micentry
), mic0
);
7335 REG_WRITE(ah
, AR_KEYTABLE_KEY1(micentry
), mic1
);
7336 REG_WRITE(ah
, AR_KEYTABLE_KEY2(micentry
), mic2
);
7337 REG_WRITE(ah
, AR_KEYTABLE_KEY3(micentry
), mic3
);
7338 REG_WRITE(ah
, AR_KEYTABLE_KEY4(micentry
), mic4
);
7339 REG_WRITE(ah
, AR_KEYTABLE_TYPE(micentry
),
7340 AR_KEYTABLE_TYPE_CLR
);
7343 u_int32_t mic0
, mic2
;
7345 mic0
= LE_READ_4(k
->kv_mic
+ 0);
7346 mic2
= LE_READ_4(k
->kv_mic
+ 4);
7347 REG_WRITE(ah
, AR_KEYTABLE_KEY0(micentry
), mic0
);
7348 REG_WRITE(ah
, AR_KEYTABLE_KEY1(micentry
), 0);
7349 REG_WRITE(ah
, AR_KEYTABLE_KEY2(micentry
), mic2
);
7350 REG_WRITE(ah
, AR_KEYTABLE_KEY3(micentry
), 0);
7351 REG_WRITE(ah
, AR_KEYTABLE_KEY4(micentry
), 0);
7352 REG_WRITE(ah
, AR_KEYTABLE_TYPE(micentry
),
7353 AR_KEYTABLE_TYPE_CLR
);
7355 REG_WRITE(ah
, AR_KEYTABLE_MAC0(micentry
), 0);
7356 REG_WRITE(ah
, AR_KEYTABLE_MAC1(micentry
), 0);
7357 REG_WRITE(ah
, AR_KEYTABLE_KEY0(entry
), key0
);
7358 REG_WRITE(ah
, AR_KEYTABLE_KEY1(entry
), key1
);
7360 REG_WRITE(ah
, AR_KEYTABLE_KEY0(entry
), key0
);
7361 REG_WRITE(ah
, AR_KEYTABLE_KEY1(entry
), key1
);
7362 REG_WRITE(ah
, AR_KEYTABLE_KEY2(entry
), key2
);
7363 REG_WRITE(ah
, AR_KEYTABLE_KEY3(entry
), key3
);
7364 REG_WRITE(ah
, AR_KEYTABLE_KEY4(entry
), key4
);
7365 REG_WRITE(ah
, AR_KEYTABLE_TYPE(entry
), keyType
);
7367 (void) ath9k_hw_keysetmac(ah
, entry
, mac
);
7370 if (ah
->ah_curchan
== NULL
)
7377 ath9k_hw_updatetxtriglevel(struct ath_hal
*ah
, bool bIncTrigLevel
)
7379 struct ath_hal_5416
*ahp
= AH5416(ah
);
7380 u_int32_t txcfg
, curLevel
, newLevel
;
7383 if (ah
->ah_txTrigLevel
>= MAX_TX_FIFO_THRESHOLD
)
7386 omask
= ath9k_hw_set_interrupts(ah
, ahp
->ah_maskReg
& ~HAL_INT_GLOBAL
);
7388 txcfg
= REG_READ(ah
, AR_TXCFG
);
7389 curLevel
= MS(txcfg
, AR_FTRIG
);
7390 newLevel
= curLevel
;
7391 if (bIncTrigLevel
) {
7392 if (curLevel
< MAX_TX_FIFO_THRESHOLD
)
7394 } else if (curLevel
> MIN_TX_FIFO_THRESHOLD
)
7396 if (newLevel
!= curLevel
)
7397 REG_WRITE(ah
, AR_TXCFG
,
7398 (txcfg
& ~AR_FTRIG
) | SM(newLevel
, AR_FTRIG
));
7400 ath9k_hw_set_interrupts(ah
, omask
);
7402 ah
->ah_txTrigLevel
= newLevel
;
7404 return newLevel
!= curLevel
;
7407 static bool ath9k_hw_set_txq_props(struct ath_hal
*ah
,
7408 struct hal_tx_queue_info
*qi
,
7409 const struct hal_txq_info
*qInfo
)
7413 if (qi
->tqi_type
== HAL_TX_QUEUE_INACTIVE
) {
7414 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: inactive queue\n",
7419 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: queue %p\n", __func__
, qi
);
7421 qi
->tqi_ver
= qInfo
->tqi_ver
;
7422 qi
->tqi_subtype
= qInfo
->tqi_subtype
;
7423 qi
->tqi_qflags
= qInfo
->tqi_qflags
;
7424 qi
->tqi_priority
= qInfo
->tqi_priority
;
7425 if (qInfo
->tqi_aifs
!= HAL_TXQ_USEDEFAULT
)
7426 qi
->tqi_aifs
= min(qInfo
->tqi_aifs
, 255U);
7428 qi
->tqi_aifs
= INIT_AIFS
;
7429 if (qInfo
->tqi_cwmin
!= HAL_TXQ_USEDEFAULT
) {
7430 cw
= min(qInfo
->tqi_cwmin
, 1024U);
7432 while (qi
->tqi_cwmin
< cw
)
7433 qi
->tqi_cwmin
= (qi
->tqi_cwmin
<< 1) | 1;
7435 qi
->tqi_cwmin
= qInfo
->tqi_cwmin
;
7436 if (qInfo
->tqi_cwmax
!= HAL_TXQ_USEDEFAULT
) {
7437 cw
= min(qInfo
->tqi_cwmax
, 1024U);
7439 while (qi
->tqi_cwmax
< cw
)
7440 qi
->tqi_cwmax
= (qi
->tqi_cwmax
<< 1) | 1;
7442 qi
->tqi_cwmax
= INIT_CWMAX
;
7444 if (qInfo
->tqi_shretry
!= 0)
7445 qi
->tqi_shretry
= min((u_int32_t
) qInfo
->tqi_shretry
, 15U);
7447 qi
->tqi_shretry
= INIT_SH_RETRY
;
7448 if (qInfo
->tqi_lgretry
!= 0)
7449 qi
->tqi_lgretry
= min((u_int32_t
) qInfo
->tqi_lgretry
, 15U);
7451 qi
->tqi_lgretry
= INIT_LG_RETRY
;
7452 qi
->tqi_cbrPeriod
= qInfo
->tqi_cbrPeriod
;
7453 qi
->tqi_cbrOverflowLimit
= qInfo
->tqi_cbrOverflowLimit
;
7454 qi
->tqi_burstTime
= qInfo
->tqi_burstTime
;
7455 qi
->tqi_readyTime
= qInfo
->tqi_readyTime
;
7457 switch (qInfo
->tqi_subtype
) {
7459 if (qi
->tqi_type
== HAL_TX_QUEUE_DATA
)
7460 qi
->tqi_intFlags
= HAL_TXQ_USE_LOCKOUT_BKOFF_DIS
;
7468 bool ath9k_hw_settxqueueprops(struct ath_hal
*ah
, int q
,
7469 const struct hal_txq_info
*qInfo
)
7471 struct ath_hal_5416
*ahp
= AH5416(ah
);
7472 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7474 if (q
>= pCap
->halTotalQueues
) {
7475 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: invalid queue num %u\n",
7479 return ath9k_hw_set_txq_props(ah
, &ahp
->ah_txq
[q
], qInfo
);
7482 static bool ath9k_hw_get_txq_props(struct ath_hal
*ah
,
7483 struct hal_txq_info
*qInfo
,
7484 const struct hal_tx_queue_info
*qi
)
7486 if (qi
->tqi_type
== HAL_TX_QUEUE_INACTIVE
) {
7487 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: inactive queue\n",
7492 qInfo
->tqi_qflags
= qi
->tqi_qflags
;
7493 qInfo
->tqi_ver
= qi
->tqi_ver
;
7494 qInfo
->tqi_subtype
= qi
->tqi_subtype
;
7495 qInfo
->tqi_qflags
= qi
->tqi_qflags
;
7496 qInfo
->tqi_priority
= qi
->tqi_priority
;
7497 qInfo
->tqi_aifs
= qi
->tqi_aifs
;
7498 qInfo
->tqi_cwmin
= qi
->tqi_cwmin
;
7499 qInfo
->tqi_cwmax
= qi
->tqi_cwmax
;
7500 qInfo
->tqi_shretry
= qi
->tqi_shretry
;
7501 qInfo
->tqi_lgretry
= qi
->tqi_lgretry
;
7502 qInfo
->tqi_cbrPeriod
= qi
->tqi_cbrPeriod
;
7503 qInfo
->tqi_cbrOverflowLimit
= qi
->tqi_cbrOverflowLimit
;
7504 qInfo
->tqi_burstTime
= qi
->tqi_burstTime
;
7505 qInfo
->tqi_readyTime
= qi
->tqi_readyTime
;
7511 ath9k_hw_gettxqueueprops(struct ath_hal
*ah
, int q
,
7512 struct hal_txq_info
*qInfo
)
7514 struct ath_hal_5416
*ahp
= AH5416(ah
);
7515 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7517 if (q
>= pCap
->halTotalQueues
) {
7518 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: invalid queue num %u\n",
7522 return ath9k_hw_get_txq_props(ah
, qInfo
, &ahp
->ah_txq
[q
]);
7526 ath9k_hw_setuptxqueue(struct ath_hal
*ah
, enum hal_tx_queue type
,
7527 const struct hal_txq_info
*qInfo
)
7529 struct ath_hal_5416
*ahp
= AH5416(ah
);
7530 struct hal_tx_queue_info
*qi
;
7531 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7535 case HAL_TX_QUEUE_BEACON
:
7536 q
= pCap
->halTotalQueues
- 1;
7538 case HAL_TX_QUEUE_CAB
:
7539 q
= pCap
->halTotalQueues
- 2;
7541 case HAL_TX_QUEUE_PSPOLL
:
7544 case HAL_TX_QUEUE_UAPSD
:
7545 q
= pCap
->halTotalQueues
- 3;
7547 case HAL_TX_QUEUE_DATA
:
7548 for (q
= 0; q
< pCap
->halTotalQueues
; q
++)
7549 if (ahp
->ah_txq
[q
].tqi_type
==
7550 HAL_TX_QUEUE_INACTIVE
)
7552 if (q
== pCap
->halTotalQueues
) {
7553 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
,
7554 "%s: no available tx queue\n", __func__
);
7559 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: bad tx queue type %u\n",
7564 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: queue %u\n", __func__
, q
);
7566 qi
= &ahp
->ah_txq
[q
];
7567 if (qi
->tqi_type
!= HAL_TX_QUEUE_INACTIVE
) {
7568 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
,
7569 "%s: tx queue %u already active\n", __func__
, q
);
7572 memset(qi
, 0, sizeof(struct hal_tx_queue_info
));
7573 qi
->tqi_type
= type
;
7574 if (qInfo
== NULL
) {
7576 TXQ_FLAG_TXOKINT_ENABLE
7577 | TXQ_FLAG_TXERRINT_ENABLE
7578 | TXQ_FLAG_TXDESCINT_ENABLE
| TXQ_FLAG_TXURNINT_ENABLE
;
7579 qi
->tqi_aifs
= INIT_AIFS
;
7580 qi
->tqi_cwmin
= HAL_TXQ_USEDEFAULT
;
7581 qi
->tqi_cwmax
= INIT_CWMAX
;
7582 qi
->tqi_shretry
= INIT_SH_RETRY
;
7583 qi
->tqi_lgretry
= INIT_LG_RETRY
;
7584 qi
->tqi_physCompBuf
= 0;
7586 qi
->tqi_physCompBuf
= qInfo
->tqi_compBuf
;
7587 (void) ath9k_hw_settxqueueprops(ah
, q
, qInfo
);
7594 ath9k_hw_set_txq_interrupts(struct ath_hal
*ah
,
7595 struct hal_tx_queue_info
*qi
)
7597 struct ath_hal_5416
*ahp
= AH5416(ah
);
7599 DPRINTF(ah
->ah_sc
, ATH_DBG_INTERRUPT
,
7600 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7601 __func__
, ahp
->ah_txOkInterruptMask
,
7602 ahp
->ah_txErrInterruptMask
, ahp
->ah_txDescInterruptMask
,
7603 ahp
->ah_txEolInterruptMask
, ahp
->ah_txUrnInterruptMask
);
7605 REG_WRITE(ah
, AR_IMR_S0
,
7606 SM(ahp
->ah_txOkInterruptMask
, AR_IMR_S0_QCU_TXOK
)
7607 | SM(ahp
->ah_txDescInterruptMask
, AR_IMR_S0_QCU_TXDESC
));
7608 REG_WRITE(ah
, AR_IMR_S1
,
7609 SM(ahp
->ah_txErrInterruptMask
, AR_IMR_S1_QCU_TXERR
)
7610 | SM(ahp
->ah_txEolInterruptMask
, AR_IMR_S1_QCU_TXEOL
));
7611 REG_RMW_FIELD(ah
, AR_IMR_S2
,
7612 AR_IMR_S2_QCU_TXURN
, ahp
->ah_txUrnInterruptMask
);
7615 bool ath9k_hw_releasetxqueue(struct ath_hal
*ah
, u_int q
)
7617 struct ath_hal_5416
*ahp
= AH5416(ah
);
7618 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7619 struct hal_tx_queue_info
*qi
;
7621 if (q
>= pCap
->halTotalQueues
) {
7622 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: invalid queue num %u\n",
7626 qi
= &ahp
->ah_txq
[q
];
7627 if (qi
->tqi_type
== HAL_TX_QUEUE_INACTIVE
) {
7628 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: inactive queue %u\n",
7633 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: release queue %u\n",
7636 qi
->tqi_type
= HAL_TX_QUEUE_INACTIVE
;
7637 ahp
->ah_txOkInterruptMask
&= ~(1 << q
);
7638 ahp
->ah_txErrInterruptMask
&= ~(1 << q
);
7639 ahp
->ah_txDescInterruptMask
&= ~(1 << q
);
7640 ahp
->ah_txEolInterruptMask
&= ~(1 << q
);
7641 ahp
->ah_txUrnInterruptMask
&= ~(1 << q
);
7642 ath9k_hw_set_txq_interrupts(ah
, qi
);
7647 bool ath9k_hw_resettxqueue(struct ath_hal
*ah
, u_int q
)
7649 struct ath_hal_5416
*ahp
= AH5416(ah
);
7650 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
7651 struct hal_channel_internal
*chan
= ah
->ah_curchan
;
7652 struct hal_tx_queue_info
*qi
;
7653 u_int32_t cwMin
, chanCwMin
, value
;
7655 if (q
>= pCap
->halTotalQueues
) {
7656 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: invalid queue num %u\n",
7660 qi
= &ahp
->ah_txq
[q
];
7661 if (qi
->tqi_type
== HAL_TX_QUEUE_INACTIVE
) {
7662 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: inactive queue %u\n",
7667 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: reset queue %u\n", __func__
, q
);
7669 if (qi
->tqi_cwmin
== HAL_TXQ_USEDEFAULT
) {
7670 if (chan
&& IS_CHAN_B(chan
))
7671 chanCwMin
= INIT_CWMIN_11B
;
7673 chanCwMin
= INIT_CWMIN
;
7675 for (cwMin
= 1; cwMin
< chanCwMin
;
7676 cwMin
= (cwMin
<< 1) | 1);
7678 cwMin
= qi
->tqi_cwmin
;
7680 REG_WRITE(ah
, AR_DLCL_IFS(q
), SM(cwMin
, AR_D_LCL_IFS_CWMIN
)
7681 | SM(qi
->tqi_cwmax
, AR_D_LCL_IFS_CWMAX
)
7682 | SM(qi
->tqi_aifs
, AR_D_LCL_IFS_AIFS
));
7684 REG_WRITE(ah
, AR_DRETRY_LIMIT(q
),
7685 SM(INIT_SSH_RETRY
, AR_D_RETRY_LIMIT_STA_SH
)
7686 | SM(INIT_SLG_RETRY
, AR_D_RETRY_LIMIT_STA_LG
)
7687 | SM(qi
->tqi_shretry
, AR_D_RETRY_LIMIT_FR_SH
)
7690 REG_WRITE(ah
, AR_QMISC(q
), AR_Q_MISC_DCU_EARLY_TERM_REQ
);
7691 REG_WRITE(ah
, AR_DMISC(q
),
7692 AR_D_MISC_CW_BKOFF_EN
| AR_D_MISC_FRAG_WAIT_EN
| 0x2);
7694 if (qi
->tqi_cbrPeriod
) {
7695 REG_WRITE(ah
, AR_QCBRCFG(q
),
7696 SM(qi
->tqi_cbrPeriod
, AR_Q_CBRCFG_INTERVAL
)
7697 | SM(qi
->tqi_cbrOverflowLimit
,
7698 AR_Q_CBRCFG_OVF_THRESH
));
7699 REG_WRITE(ah
, AR_QMISC(q
),
7701 AR_QMISC(q
)) | AR_Q_MISC_FSP_CBR
| (qi
->
7702 tqi_cbrOverflowLimit
7704 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7708 if (qi
->tqi_readyTime
&& (qi
->tqi_type
!= HAL_TX_QUEUE_CAB
)) {
7709 REG_WRITE(ah
, AR_QRDYTIMECFG(q
),
7710 SM(qi
->tqi_readyTime
, AR_Q_RDYTIMECFG_DURATION
) |
7711 AR_Q_RDYTIMECFG_EN
);
7714 REG_WRITE(ah
, AR_DCHNTIME(q
),
7715 SM(qi
->tqi_burstTime
, AR_D_CHNTIME_DUR
) |
7716 (qi
->tqi_burstTime
? AR_D_CHNTIME_EN
: 0));
7718 if (qi
->tqi_burstTime
7719 && (qi
->tqi_qflags
& TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE
)) {
7720 REG_WRITE(ah
, AR_QMISC(q
),
7723 AR_Q_MISC_RDYTIME_EXP_POLICY
);
7727 if (qi
->tqi_qflags
& TXQ_FLAG_BACKOFF_DISABLE
) {
7728 REG_WRITE(ah
, AR_DMISC(q
),
7729 REG_READ(ah
, AR_DMISC(q
)) |
7730 AR_D_MISC_POST_FR_BKOFF_DIS
);
7732 if (qi
->tqi_qflags
& TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE
) {
7733 REG_WRITE(ah
, AR_DMISC(q
),
7734 REG_READ(ah
, AR_DMISC(q
)) |
7735 AR_D_MISC_FRAG_BKOFF_EN
);
7737 switch (qi
->tqi_type
) {
7738 case HAL_TX_QUEUE_BEACON
:
7739 REG_WRITE(ah
, AR_QMISC(q
), REG_READ(ah
, AR_QMISC(q
))
7740 | AR_Q_MISC_FSP_DBA_GATED
7741 | AR_Q_MISC_BEACON_USE
7742 | AR_Q_MISC_CBR_INCR_DIS1
);
7744 REG_WRITE(ah
, AR_DMISC(q
), REG_READ(ah
, AR_DMISC(q
))
7745 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL
<<
7746 AR_D_MISC_ARB_LOCKOUT_CNTRL_S
)
7747 | AR_D_MISC_BEACON_USE
7748 | AR_D_MISC_POST_FR_BKOFF_DIS
);
7750 case HAL_TX_QUEUE_CAB
:
7751 REG_WRITE(ah
, AR_QMISC(q
), REG_READ(ah
, AR_QMISC(q
))
7752 | AR_Q_MISC_FSP_DBA_GATED
7753 | AR_Q_MISC_CBR_INCR_DIS1
7754 | AR_Q_MISC_CBR_INCR_DIS0
);
7755 value
= (qi
->tqi_readyTime
7756 - (ah
->ah_config
.ath_hal_sw_beacon_response_time
-
7757 ah
->ah_config
.ath_hal_dma_beacon_response_time
)
7759 ah
->ah_config
.ath_hal_additional_swba_backoff
) *
7761 REG_WRITE(ah
, AR_QRDYTIMECFG(q
),
7762 value
| AR_Q_RDYTIMECFG_EN
);
7763 REG_WRITE(ah
, AR_DMISC(q
), REG_READ(ah
, AR_DMISC(q
))
7764 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL
<<
7765 AR_D_MISC_ARB_LOCKOUT_CNTRL_S
));
7767 case HAL_TX_QUEUE_PSPOLL
:
7768 REG_WRITE(ah
, AR_QMISC(q
),
7770 AR_QMISC(q
)) | AR_Q_MISC_CBR_INCR_DIS1
);
7772 case HAL_TX_QUEUE_UAPSD
:
7773 REG_WRITE(ah
, AR_DMISC(q
), REG_READ(ah
, AR_DMISC(q
))
7774 | AR_D_MISC_POST_FR_BKOFF_DIS
);
7780 if (qi
->tqi_intFlags
& HAL_TXQ_USE_LOCKOUT_BKOFF_DIS
) {
7781 REG_WRITE(ah
, AR_DMISC(q
),
7782 REG_READ(ah
, AR_DMISC(q
)) |
7783 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL
,
7784 AR_D_MISC_ARB_LOCKOUT_CNTRL
) |
7785 AR_D_MISC_POST_FR_BKOFF_DIS
);
7788 if (qi
->tqi_qflags
& TXQ_FLAG_TXOKINT_ENABLE
)
7789 ahp
->ah_txOkInterruptMask
|= 1 << q
;
7791 ahp
->ah_txOkInterruptMask
&= ~(1 << q
);
7792 if (qi
->tqi_qflags
& TXQ_FLAG_TXERRINT_ENABLE
)
7793 ahp
->ah_txErrInterruptMask
|= 1 << q
;
7795 ahp
->ah_txErrInterruptMask
&= ~(1 << q
);
7796 if (qi
->tqi_qflags
& TXQ_FLAG_TXDESCINT_ENABLE
)
7797 ahp
->ah_txDescInterruptMask
|= 1 << q
;
7799 ahp
->ah_txDescInterruptMask
&= ~(1 << q
);
7800 if (qi
->tqi_qflags
& TXQ_FLAG_TXEOLINT_ENABLE
)
7801 ahp
->ah_txEolInterruptMask
|= 1 << q
;
7803 ahp
->ah_txEolInterruptMask
&= ~(1 << q
);
7804 if (qi
->tqi_qflags
& TXQ_FLAG_TXURNINT_ENABLE
)
7805 ahp
->ah_txUrnInterruptMask
|= 1 << q
;
7807 ahp
->ah_txUrnInterruptMask
&= ~(1 << q
);
7808 ath9k_hw_set_txq_interrupts(ah
, qi
);
7813 void ath9k_hw_gettxintrtxqs(struct ath_hal
*ah
, u_int32_t
*txqs
)
7815 struct ath_hal_5416
*ahp
= AH5416(ah
);
7816 *txqs
&= ahp
->ah_intrTxqs
;
7817 ahp
->ah_intrTxqs
&= ~(*txqs
);
7821 ath9k_hw_filltxdesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
7822 u_int segLen
, bool firstSeg
,
7823 bool lastSeg
, const struct ath_desc
*ds0
)
7825 struct ar5416_desc
*ads
= AR5416DESC(ds
);
7828 ads
->ds_ctl1
|= segLen
| (lastSeg
? 0 : AR_TxMore
);
7829 } else if (lastSeg
) {
7831 ads
->ds_ctl1
= segLen
;
7832 ads
->ds_ctl2
= AR5416DESC_CONST(ds0
)->ds_ctl2
;
7833 ads
->ds_ctl3
= AR5416DESC_CONST(ds0
)->ds_ctl3
;
7836 ads
->ds_ctl1
= segLen
| AR_TxMore
;
7840 ads
->ds_txstatus0
= ads
->ds_txstatus1
= 0;
7841 ads
->ds_txstatus2
= ads
->ds_txstatus3
= 0;
7842 ads
->ds_txstatus4
= ads
->ds_txstatus5
= 0;
7843 ads
->ds_txstatus6
= ads
->ds_txstatus7
= 0;
7844 ads
->ds_txstatus8
= ads
->ds_txstatus9
= 0;
7848 void ath9k_hw_cleartxdesc(struct ath_hal
*ah
, struct ath_desc
*ds
)
7850 struct ar5416_desc
*ads
= AR5416DESC(ds
);
7852 ads
->ds_txstatus0
= ads
->ds_txstatus1
= 0;
7853 ads
->ds_txstatus2
= ads
->ds_txstatus3
= 0;
7854 ads
->ds_txstatus4
= ads
->ds_txstatus5
= 0;
7855 ads
->ds_txstatus6
= ads
->ds_txstatus7
= 0;
7856 ads
->ds_txstatus8
= ads
->ds_txstatus9
= 0;
7860 ath9k_hw_txprocdesc(struct ath_hal
*ah
, struct ath_desc
*ds
)
7862 struct ar5416_desc
*ads
= AR5416DESC(ds
);
7864 if ((ads
->ds_txstatus9
& AR_TxDone
) == 0)
7865 return HAL_EINPROGRESS
;
7867 ds
->ds_txstat
.ts_seqnum
= MS(ads
->ds_txstatus9
, AR_SeqNum
);
7868 ds
->ds_txstat
.ts_tstamp
= ads
->AR_SendTimestamp
;
7869 ds
->ds_txstat
.ts_status
= 0;
7870 ds
->ds_txstat
.ts_flags
= 0;
7872 if (ads
->ds_txstatus1
& AR_ExcessiveRetries
)
7873 ds
->ds_txstat
.ts_status
|= ATH9K_TXERR_XRETRY
;
7874 if (ads
->ds_txstatus1
& AR_Filtered
)
7875 ds
->ds_txstat
.ts_status
|= ATH9K_TXERR_FILT
;
7876 if (ads
->ds_txstatus1
& AR_FIFOUnderrun
)
7877 ds
->ds_txstat
.ts_status
|= ATH9K_TXERR_FIFO
;
7878 if (ads
->ds_txstatus9
& AR_TxOpExceeded
)
7879 ds
->ds_txstat
.ts_status
|= ATH9K_TXERR_XTXOP
;
7880 if (ads
->ds_txstatus1
& AR_TxTimerExpired
)
7881 ds
->ds_txstat
.ts_status
|= ATH9K_TXERR_TIMER_EXPIRED
;
7883 if (ads
->ds_txstatus1
& AR_DescCfgErr
)
7884 ds
->ds_txstat
.ts_flags
|= ATH9K_TX_DESC_CFG_ERR
;
7885 if (ads
->ds_txstatus1
& AR_TxDataUnderrun
) {
7886 ds
->ds_txstat
.ts_flags
|= ATH9K_TX_DATA_UNDERRUN
;
7887 ath9k_hw_updatetxtriglevel(ah
, true);
7889 if (ads
->ds_txstatus1
& AR_TxDelimUnderrun
) {
7890 ds
->ds_txstat
.ts_flags
|= ATH9K_TX_DELIM_UNDERRUN
;
7891 ath9k_hw_updatetxtriglevel(ah
, true);
7893 if (ads
->ds_txstatus0
& AR_TxBaStatus
) {
7894 ds
->ds_txstat
.ts_flags
|= ATH9K_TX_BA
;
7895 ds
->ds_txstat
.ba_low
= ads
->AR_BaBitmapLow
;
7896 ds
->ds_txstat
.ba_high
= ads
->AR_BaBitmapHigh
;
7899 ds
->ds_txstat
.ts_rateindex
= MS(ads
->ds_txstatus9
, AR_FinalTxIdx
);
7900 switch (ds
->ds_txstat
.ts_rateindex
) {
7902 ds
->ds_txstat
.ts_ratecode
= MS(ads
->ds_ctl3
, AR_XmitRate0
);
7905 ds
->ds_txstat
.ts_ratecode
= MS(ads
->ds_ctl3
, AR_XmitRate1
);
7908 ds
->ds_txstat
.ts_ratecode
= MS(ads
->ds_ctl3
, AR_XmitRate2
);
7911 ds
->ds_txstat
.ts_ratecode
= MS(ads
->ds_ctl3
, AR_XmitRate3
);
7915 ds
->ds_txstat
.ts_rssi
= MS(ads
->ds_txstatus5
, AR_TxRSSICombined
);
7916 ds
->ds_txstat
.ts_rssi_ctl0
= MS(ads
->ds_txstatus0
, AR_TxRSSIAnt00
);
7917 ds
->ds_txstat
.ts_rssi_ctl1
= MS(ads
->ds_txstatus0
, AR_TxRSSIAnt01
);
7918 ds
->ds_txstat
.ts_rssi_ctl2
= MS(ads
->ds_txstatus0
, AR_TxRSSIAnt02
);
7919 ds
->ds_txstat
.ts_rssi_ext0
= MS(ads
->ds_txstatus5
, AR_TxRSSIAnt10
);
7920 ds
->ds_txstat
.ts_rssi_ext1
= MS(ads
->ds_txstatus5
, AR_TxRSSIAnt11
);
7921 ds
->ds_txstat
.ts_rssi_ext2
= MS(ads
->ds_txstatus5
, AR_TxRSSIAnt12
);
7922 ds
->ds_txstat
.evm0
= ads
->AR_TxEVM0
;
7923 ds
->ds_txstat
.evm1
= ads
->AR_TxEVM1
;
7924 ds
->ds_txstat
.evm2
= ads
->AR_TxEVM2
;
7925 ds
->ds_txstat
.ts_shortretry
= MS(ads
->ds_txstatus1
, AR_RTSFailCnt
);
7926 ds
->ds_txstat
.ts_longretry
= MS(ads
->ds_txstatus1
, AR_DataFailCnt
);
7927 ds
->ds_txstat
.ts_virtcol
= MS(ads
->ds_txstatus1
, AR_VirtRetryCnt
);
7928 ds
->ds_txstat
.ts_antenna
= 1;
7934 ath9k_hw_set11n_txdesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
7935 u_int pktLen
, enum hal_pkt_type type
, u_int txPower
,
7936 u_int keyIx
, enum hal_key_type keyType
, u_int flags
)
7938 struct ar5416_desc
*ads
= AR5416DESC(ds
);
7939 struct ath_hal_5416
*ahp
= AH5416(ah
);
7941 txPower
+= ahp
->ah_txPowerIndexOffset
;
7945 ads
->ds_ctl0
= (pktLen
& AR_FrameLen
)
7946 | (flags
& HAL_TXDESC_VMF
? AR_VirtMoreFrag
: 0)
7947 | SM(txPower
, AR_XmitPower
)
7948 | (flags
& HAL_TXDESC_VEOL
? AR_VEOL
: 0)
7949 | (flags
& HAL_TXDESC_CLRDMASK
? AR_ClrDestMask
: 0)
7950 | (flags
& HAL_TXDESC_INTREQ
? AR_TxIntrReq
: 0)
7951 | (keyIx
!= HAL_TXKEYIX_INVALID
? AR_DestIdxValid
: 0);
7954 (keyIx
!= HAL_TXKEYIX_INVALID
? SM(keyIx
, AR_DestIdx
) : 0)
7955 | SM(type
, AR_FrameType
)
7956 | (flags
& HAL_TXDESC_NOACK
? AR_NoAck
: 0)
7957 | (flags
& HAL_TXDESC_EXT_ONLY
? AR_ExtOnly
: 0)
7958 | (flags
& HAL_TXDESC_EXT_AND_CTL
? AR_ExtAndCtl
: 0);
7960 ads
->ds_ctl6
= SM(keyType
, AR_EncrType
);
7962 if (AR_SREV_9285(ah
)) {
7972 ath9k_hw_set11n_ratescenario(struct ath_hal
*ah
, struct ath_desc
*ds
,
7973 struct ath_desc
*lastds
,
7974 u_int durUpdateEn
, u_int rtsctsRate
,
7975 u_int rtsctsDuration
,
7976 struct hal_11n_rate_series series
[],
7977 u_int nseries
, u_int flags
)
7979 struct ar5416_desc
*ads
= AR5416DESC(ds
);
7980 struct ar5416_desc
*last_ads
= AR5416DESC(lastds
);
7984 (void) rtsctsDuration
;
7986 if (flags
& (HAL_TXDESC_RTSENA
| HAL_TXDESC_CTSENA
)) {
7987 ds_ctl0
= ads
->ds_ctl0
;
7989 if (flags
& HAL_TXDESC_RTSENA
) {
7990 ds_ctl0
&= ~AR_CTSEnable
;
7991 ds_ctl0
|= AR_RTSEnable
;
7993 ds_ctl0
&= ~AR_RTSEnable
;
7994 ds_ctl0
|= AR_CTSEnable
;
7997 ads
->ds_ctl0
= ds_ctl0
;
8000 (ads
->ds_ctl0
& ~(AR_RTSEnable
| AR_CTSEnable
));
8003 ads
->ds_ctl2
= set11nTries(series
, 0)
8004 | set11nTries(series
, 1)
8005 | set11nTries(series
, 2)
8006 | set11nTries(series
, 3)
8007 | (durUpdateEn
? AR_DurUpdateEna
: 0)
8008 | SM(0, AR_BurstDur
);
8010 ads
->ds_ctl3
= set11nRate(series
, 0)
8011 | set11nRate(series
, 1)
8012 | set11nRate(series
, 2)
8013 | set11nRate(series
, 3);
8015 ads
->ds_ctl4
= set11nPktDurRTSCTS(series
, 0)
8016 | set11nPktDurRTSCTS(series
, 1);
8018 ads
->ds_ctl5
= set11nPktDurRTSCTS(series
, 2)
8019 | set11nPktDurRTSCTS(series
, 3);
8021 ads
->ds_ctl7
= set11nRateFlags(series
, 0)
8022 | set11nRateFlags(series
, 1)
8023 | set11nRateFlags(series
, 2)
8024 | set11nRateFlags(series
, 3)
8025 | SM(rtsctsRate
, AR_RTSCTSRate
);
8026 last_ads
->ds_ctl2
= ads
->ds_ctl2
;
8027 last_ads
->ds_ctl3
= ads
->ds_ctl3
;
8031 ath9k_hw_set11n_aggr_first(struct ath_hal
*ah
, struct ath_desc
*ds
,
8034 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8036 ads
->ds_ctl1
|= (AR_IsAggr
| AR_MoreAggr
);
8038 ads
->ds_ctl6
&= ~AR_AggrLen
;
8039 ads
->ds_ctl6
|= SM(aggrLen
, AR_AggrLen
);
8043 ath9k_hw_set11n_aggr_middle(struct ath_hal
*ah
, struct ath_desc
*ds
,
8046 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8049 ads
->ds_ctl1
|= (AR_IsAggr
| AR_MoreAggr
);
8051 ctl6
= ads
->ds_ctl6
;
8052 ctl6
&= ~AR_PadDelim
;
8053 ctl6
|= SM(numDelims
, AR_PadDelim
);
8054 ads
->ds_ctl6
= ctl6
;
8057 void ath9k_hw_set11n_aggr_last(struct ath_hal
*ah
, struct ath_desc
*ds
)
8059 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8061 ads
->ds_ctl1
|= AR_IsAggr
;
8062 ads
->ds_ctl1
&= ~AR_MoreAggr
;
8063 ads
->ds_ctl6
&= ~AR_PadDelim
;
8066 void ath9k_hw_clr11n_aggr(struct ath_hal
*ah
, struct ath_desc
*ds
)
8068 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8070 ads
->ds_ctl1
&= (~AR_IsAggr
& ~AR_MoreAggr
);
8074 ath9k_hw_set11n_burstduration(struct ath_hal
*ah
, struct ath_desc
*ds
,
8075 u_int burstDuration
)
8077 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8079 ads
->ds_ctl2
&= ~AR_BurstDur
;
8080 ads
->ds_ctl2
|= SM(burstDuration
, AR_BurstDur
);
8084 ath9k_hw_set11n_virtualmorefrag(struct ath_hal
*ah
, struct ath_desc
*ds
,
8087 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8090 ads
->ds_ctl0
|= AR_VirtMoreFrag
;
8092 ads
->ds_ctl0
&= ~AR_VirtMoreFrag
;
8095 void ath9k_hw_putrxbuf(struct ath_hal
*ah
, u_int32_t rxdp
)
8097 REG_WRITE(ah
, AR_RXDP
, rxdp
);
8100 void ath9k_hw_rxena(struct ath_hal
*ah
)
8102 REG_WRITE(ah
, AR_CR
, AR_CR_RXE
);
8105 bool ath9k_hw_setrxabort(struct ath_hal
*ah
, bool set
)
8109 REG_SET_BIT(ah
, AR_DIAG_SW
,
8110 (AR_DIAG_RX_DIS
| AR_DIAG_RX_ABORT
));
8113 (ah
, AR_OBS_BUS_1
, AR_OBS_BUS_1_RX_STATE
, 0)) {
8116 REG_CLR_BIT(ah
, AR_DIAG_SW
,
8120 reg
= REG_READ(ah
, AR_OBS_BUS_1
);
8121 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
8122 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8128 REG_CLR_BIT(ah
, AR_DIAG_SW
,
8129 (AR_DIAG_RX_DIS
| AR_DIAG_RX_ABORT
));
8136 ath9k_hw_setmcastfilter(struct ath_hal
*ah
, u_int32_t filter0
,
8139 REG_WRITE(ah
, AR_MCAST_FIL0
, filter0
);
8140 REG_WRITE(ah
, AR_MCAST_FIL1
, filter1
);
8144 ath9k_hw_setuprxdesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
8145 u_int32_t size
, u_int flags
)
8147 struct ar5416_desc
*ads
= AR5416DESC(ds
);
8148 struct hal_capabilities
*pCap
= &ah
->ah_caps
;
8150 ads
->ds_ctl1
= size
& AR_BufLen
;
8151 if (flags
& HAL_RXDESC_INTREQ
)
8152 ads
->ds_ctl1
|= AR_RxIntrReq
;
8154 ads
->ds_rxstatus8
&= ~AR_RxDone
;
8155 if (!pCap
->halAutoSleepSupport
)
8156 memset(&(ads
->u
), 0, sizeof(ads
->u
));
8161 ath9k_hw_rxprocdesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
8162 u_int32_t pa
, struct ath_desc
*nds
, u_int64_t tsf
)
8164 struct ar5416_desc ads
;
8165 struct ar5416_desc
*adsp
= AR5416DESC(ds
);
8167 if ((adsp
->ds_rxstatus8
& AR_RxDone
) == 0)
8168 return HAL_EINPROGRESS
;
8170 ads
.u
.rx
= adsp
->u
.rx
;
8172 ds
->ds_rxstat
.rs_status
= 0;
8173 ds
->ds_rxstat
.rs_flags
= 0;
8175 ds
->ds_rxstat
.rs_datalen
= ads
.ds_rxstatus1
& AR_DataLen
;
8176 ds
->ds_rxstat
.rs_tstamp
= ads
.AR_RcvTimestamp
;
8178 ds
->ds_rxstat
.rs_rssi
= MS(ads
.ds_rxstatus4
, AR_RxRSSICombined
);
8179 ds
->ds_rxstat
.rs_rssi_ctl0
= MS(ads
.ds_rxstatus0
, AR_RxRSSIAnt00
);
8180 ds
->ds_rxstat
.rs_rssi_ctl1
= MS(ads
.ds_rxstatus0
, AR_RxRSSIAnt01
);
8181 ds
->ds_rxstat
.rs_rssi_ctl2
= MS(ads
.ds_rxstatus0
, AR_RxRSSIAnt02
);
8182 ds
->ds_rxstat
.rs_rssi_ext0
= MS(ads
.ds_rxstatus4
, AR_RxRSSIAnt10
);
8183 ds
->ds_rxstat
.rs_rssi_ext1
= MS(ads
.ds_rxstatus4
, AR_RxRSSIAnt11
);
8184 ds
->ds_rxstat
.rs_rssi_ext2
= MS(ads
.ds_rxstatus4
, AR_RxRSSIAnt12
);
8185 if (ads
.ds_rxstatus8
& AR_RxKeyIdxValid
)
8186 ds
->ds_rxstat
.rs_keyix
= MS(ads
.ds_rxstatus8
, AR_KeyIdx
);
8188 ds
->ds_rxstat
.rs_keyix
= HAL_RXKEYIX_INVALID
;
8190 ds
->ds_rxstat
.rs_rate
= RXSTATUS_RATE(ah
, (&ads
));
8191 ds
->ds_rxstat
.rs_more
= (ads
.ds_rxstatus1
& AR_RxMore
) ? 1 : 0;
8193 ds
->ds_rxstat
.rs_isaggr
= (ads
.ds_rxstatus8
& AR_RxAggr
) ? 1 : 0;
8194 ds
->ds_rxstat
.rs_moreaggr
=
8195 (ads
.ds_rxstatus8
& AR_RxMoreAggr
) ? 1 : 0;
8196 ds
->ds_rxstat
.rs_antenna
= MS(ads
.ds_rxstatus3
, AR_RxAntenna
);
8197 ds
->ds_rxstat
.rs_flags
=
8198 (ads
.ds_rxstatus3
& AR_GI
) ? ATH9K_RX_GI
: 0;
8199 ds
->ds_rxstat
.rs_flags
|=
8200 (ads
.ds_rxstatus3
& AR_2040
) ? ATH9K_RX_2040
: 0;
8202 if (ads
.ds_rxstatus8
& AR_PreDelimCRCErr
)
8203 ds
->ds_rxstat
.rs_flags
|= ATH9K_RX_DELIM_CRC_PRE
;
8204 if (ads
.ds_rxstatus8
& AR_PostDelimCRCErr
)
8205 ds
->ds_rxstat
.rs_flags
|= ATH9K_RX_DELIM_CRC_POST
;
8206 if (ads
.ds_rxstatus8
& AR_DecryptBusyErr
)
8207 ds
->ds_rxstat
.rs_flags
|= ATH9K_RX_DECRYPT_BUSY
;
8209 if ((ads
.ds_rxstatus8
& AR_RxFrameOK
) == 0) {
8211 if (ads
.ds_rxstatus8
& AR_CRCErr
)
8212 ds
->ds_rxstat
.rs_status
|= ATH9K_RXERR_CRC
;
8213 else if (ads
.ds_rxstatus8
& AR_PHYErr
) {
8216 ds
->ds_rxstat
.rs_status
|= ATH9K_RXERR_PHY
;
8217 phyerr
= MS(ads
.ds_rxstatus8
, AR_PHYErrCode
);
8218 ds
->ds_rxstat
.rs_phyerr
= phyerr
;
8219 } else if (ads
.ds_rxstatus8
& AR_DecryptCRCErr
)
8220 ds
->ds_rxstat
.rs_status
|= ATH9K_RXERR_DECRYPT
;
8221 else if (ads
.ds_rxstatus8
& AR_MichaelErr
)
8222 ds
->ds_rxstat
.rs_status
|= ATH9K_RXERR_MIC
;
8228 static void ath9k_hw_setup_rate_table(struct ath_hal
*ah
,
8229 struct hal_rate_table
*rt
)
8233 if (rt
->rateCodeToIndex
[0] != 0)
8235 for (i
= 0; i
< 256; i
++)
8236 rt
->rateCodeToIndex
[i
] = (u_int8_t
) -1;
8237 for (i
= 0; i
< rt
->rateCount
; i
++) {
8238 u_int8_t code
= rt
->info
[i
].rateCode
;
8239 u_int8_t cix
= rt
->info
[i
].controlRate
;
8241 rt
->rateCodeToIndex
[code
] = i
;
8242 rt
->rateCodeToIndex
[code
| rt
->info
[i
].shortPreamble
] = i
;
8244 rt
->info
[i
].lpAckDuration
=
8245 ath9k_hw_computetxtime(ah
, rt
,
8246 WLAN_CTRL_FRAME_SIZE
,
8249 rt
->info
[i
].spAckDuration
=
8250 ath9k_hw_computetxtime(ah
, rt
,
8251 WLAN_CTRL_FRAME_SIZE
,
8257 const struct hal_rate_table
*ath9k_hw_getratetable(struct ath_hal
*ah
,
8260 struct hal_rate_table
*rt
;
8262 case ATH9K_MODE_SEL_11A
:
8263 rt
= &ar5416_11a_table
;
8265 case ATH9K_MODE_SEL_11B
:
8266 rt
= &ar5416_11b_table
;
8268 case ATH9K_MODE_SEL_11G
:
8269 rt
= &ar5416_11g_table
;
8271 case ATH9K_MODE_SEL_11NG_HT20
:
8272 case ATH9K_MODE_SEL_11NG_HT40PLUS
:
8273 case ATH9K_MODE_SEL_11NG_HT40MINUS
:
8274 rt
= &ar5416_11ng_table
;
8276 case ATH9K_MODE_SEL_11NA_HT20
:
8277 case ATH9K_MODE_SEL_11NA_HT40PLUS
:
8278 case ATH9K_MODE_SEL_11NA_HT40MINUS
:
8279 rt
= &ar5416_11na_table
;
8282 DPRINTF(ah
->ah_sc
, ATH_DBG_CHANNEL
, "%s: invalid mode 0x%x\n",
8286 ath9k_hw_setup_rate_table(ah
, rt
);
8290 static const char *ath9k_hw_devname(u_int16_t devid
)
8293 case AR5416_DEVID_PCI
:
8294 case AR5416_DEVID_PCIE
:
8295 return "Atheros 5416";
8296 case AR9160_DEVID_PCI
:
8297 return "Atheros 9160";
8298 case AR9280_DEVID_PCI
:
8299 case AR9280_DEVID_PCIE
:
8300 return "Atheros 9280";
8305 const char *ath9k_hw_probe(u_int16_t vendorid
, u_int16_t devid
)
8307 return vendorid
== ATHEROS_VENDOR_ID
?
8308 ath9k_hw_devname(devid
) : NULL
;
8311 struct ath_hal
*ath9k_hw_attach(u_int16_t devid
,
8312 struct ath_softc
*sc
,
8314 enum hal_status
*error
)
8316 struct ath_hal
*ah
= NULL
;
8319 case AR5416_DEVID_PCI
:
8320 case AR5416_DEVID_PCIE
:
8321 case AR9160_DEVID_PCI
:
8322 case AR9280_DEVID_PCI
:
8323 case AR9280_DEVID_PCIE
:
8324 ah
= ath9k_hw_do_attach(devid
, sc
, mem
, error
);
8327 DPRINTF(ah
->ah_sc
, ATH_DBG_ANY
,
8328 "devid=0x%x not supported.\n", devid
);
8334 ah
->ah_devid
= ah
->ah_devid
;
8335 ah
->ah_subvendorid
= ah
->ah_subvendorid
;
8336 ah
->ah_macVersion
= ah
->ah_macVersion
;
8337 ah
->ah_macRev
= ah
->ah_macRev
;
8338 ah
->ah_phyRev
= ah
->ah_phyRev
;
8339 ah
->ah_analog5GhzRev
= ah
->ah_analog5GhzRev
;
8340 ah
->ah_analog2GhzRev
= ah
->ah_analog2GhzRev
;
8346 ath9k_hw_computetxtime(struct ath_hal
*ah
,
8347 const struct hal_rate_table
*rates
,
8348 u_int32_t frameLen
, u_int16_t rateix
,
8351 u_int32_t bitsPerSymbol
, numBits
, numSymbols
, phyTime
, txTime
;
8354 kbps
= rates
->info
[rateix
].rateKbps
;
8358 switch (rates
->info
[rateix
].phy
) {
8361 phyTime
= CCK_PREAMBLE_BITS
+ CCK_PLCP_BITS
;
8362 if (shortPreamble
&& rates
->info
[rateix
].shortPreamble
)
8364 numBits
= frameLen
<< 3;
8365 txTime
= CCK_SIFS_TIME
+ phyTime
8366 + ((numBits
* 1000) / kbps
);
8369 if (ah
->ah_curchan
&& IS_CHAN_QUARTER_RATE(ah
->ah_curchan
)) {
8371 (kbps
* OFDM_SYMBOL_TIME_QUARTER
) / 1000;
8373 numBits
= OFDM_PLCP_BITS
+ (frameLen
<< 3);
8374 numSymbols
= howmany(numBits
, bitsPerSymbol
);
8375 txTime
= OFDM_SIFS_TIME_QUARTER
8376 + OFDM_PREAMBLE_TIME_QUARTER
8377 + (numSymbols
* OFDM_SYMBOL_TIME_QUARTER
);
8378 } else if (ah
->ah_curchan
&&
8379 IS_CHAN_HALF_RATE(ah
->ah_curchan
)) {
8381 (kbps
* OFDM_SYMBOL_TIME_HALF
) / 1000;
8383 numBits
= OFDM_PLCP_BITS
+ (frameLen
<< 3);
8384 numSymbols
= howmany(numBits
, bitsPerSymbol
);
8385 txTime
= OFDM_SIFS_TIME_HALF
+
8386 OFDM_PREAMBLE_TIME_HALF
8387 + (numSymbols
* OFDM_SYMBOL_TIME_HALF
);
8389 bitsPerSymbol
= (kbps
* OFDM_SYMBOL_TIME
) / 1000;
8391 numBits
= OFDM_PLCP_BITS
+ (frameLen
<< 3);
8392 numSymbols
= howmany(numBits
, bitsPerSymbol
);
8393 txTime
= OFDM_SIFS_TIME
+ OFDM_PREAMBLE_TIME
8394 + (numSymbols
* OFDM_SYMBOL_TIME
);
8399 DPRINTF(ah
->ah_sc
, ATH_DBG_PHY_IO
,
8400 "%s: unknown phy %u (rate ix %u)\n", __func__
,
8401 rates
->info
[rateix
].phy
, rateix
);
8408 u_int
ath9k_hw_mhz2ieee(struct ath_hal
*ah
, u_int freq
, u_int flags
)
8410 if (flags
& CHANNEL_2GHZ
) {
8414 return (freq
- 2407) / 5;
8416 return 15 + ((freq
- 2512) / 20);
8417 } else if (flags
& CHANNEL_5GHZ
) {
8418 if (ath9k_regd_is_public_safety_sku(ah
) &&
8419 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq
)) {
8420 return ((freq
* 10) +
8421 (((freq
% 5) == 2) ? 5 : 0) - 49400) / 5;
8422 } else if ((flags
& CHANNEL_A
) && (freq
<= 5000)) {
8423 return (freq
- 4000) / 5;
8425 return (freq
- 5000) / 5;
8431 return (freq
- 2407) / 5;
8433 if (ath9k_regd_is_public_safety_sku(ah
)
8434 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq
)) {
8435 return ((freq
* 10) +
8437 2) ? 5 : 0) - 49400) / 5;
8438 } else if (freq
> 4900) {
8439 return (freq
- 4000) / 5;
8441 return 15 + ((freq
- 2512) / 20);
8444 return (freq
- 5000) / 5;
8449 ath9k_hw_getchan_noise(struct ath_hal
*ah
, struct hal_channel
*chan
)
8451 struct hal_channel_internal
*ichan
;
8453 ichan
= ath9k_regd_check_channel(ah
, chan
);
8454 if (ichan
== NULL
) {
8455 DPRINTF(ah
->ah_sc
, ATH_DBG_NF_CAL
,
8456 "%s: invalid channel %u/0x%x; no mapping\n",
8457 __func__
, chan
->channel
, chan
->channelFlags
);
8460 if (ichan
->rawNoiseFloor
== 0) {
8461 enum wireless_mode mode
= ath9k_hw_chan2wmode(ah
, chan
);
8462 return NOISE_FLOOR
[mode
];
8464 return ichan
->rawNoiseFloor
;
8467 bool ath9k_hw_set_tsfadjust(struct ath_hal
*ah
, u_int32_t setting
)
8469 struct ath_hal_5416
*ahp
= AH5416(ah
);
8472 ahp
->ah_miscMode
|= AR_PCU_TX_ADD_TSF
;
8474 ahp
->ah_miscMode
&= ~AR_PCU_TX_ADD_TSF
;
8478 bool ath9k_hw_phycounters(struct ath_hal
*ah
)
8480 struct ath_hal_5416
*ahp
= AH5416(ah
);
8482 return ahp
->ah_hasHwPhyCounters
? true : false;
8485 u_int32_t
ath9k_hw_gettxbuf(struct ath_hal
*ah
, u_int q
)
8487 return REG_READ(ah
, AR_QTXDP(q
));
8490 bool ath9k_hw_puttxbuf(struct ath_hal
*ah
, u_int q
,
8493 REG_WRITE(ah
, AR_QTXDP(q
), txdp
);
8498 bool ath9k_hw_txstart(struct ath_hal
*ah
, u_int q
)
8500 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
, "%s: queue %u\n", __func__
, q
);
8502 REG_WRITE(ah
, AR_Q_TXE
, 1 << q
);
8507 u_int32_t
ath9k_hw_numtxpending(struct ath_hal
*ah
, u_int q
)
8511 npend
= REG_READ(ah
, AR_QSTS(q
)) & AR_Q_STS_PEND_FR_CNT
;
8514 if (REG_READ(ah
, AR_Q_TXE
) & (1 << q
))
8520 bool ath9k_hw_stoptxdma(struct ath_hal
*ah
, u_int q
)
8524 REG_WRITE(ah
, AR_Q_TXD
, 1 << q
);
8526 for (wait
= 1000; wait
!= 0; wait
--) {
8527 if (ath9k_hw_numtxpending(ah
, q
) == 0)
8532 if (ath9k_hw_numtxpending(ah
, q
)) {
8533 u_int32_t tsfLow
, j
;
8535 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
,
8536 "%s: Num of pending TX Frames %d on Q %d\n",
8537 __func__
, ath9k_hw_numtxpending(ah
, q
), q
);
8539 for (j
= 0; j
< 2; j
++) {
8540 tsfLow
= REG_READ(ah
, AR_TSF_L32
);
8541 REG_WRITE(ah
, AR_QUIET2
,
8542 SM(10, AR_QUIET2_QUIET_DUR
));
8543 REG_WRITE(ah
, AR_QUIET_PERIOD
, 100);
8544 REG_WRITE(ah
, AR_NEXT_QUIET_TIMER
, tsfLow
>> 10);
8545 REG_SET_BIT(ah
, AR_TIMER_MODE
,
8548 if ((REG_READ(ah
, AR_TSF_L32
) >> 10) ==
8552 DPRINTF(ah
->ah_sc
, ATH_DBG_QUEUE
,
8553 "%s: TSF have moved while trying to set "
8554 "quiet time TSF: 0x%08x\n",
8558 REG_SET_BIT(ah
, AR_DIAG_SW
, AR_DIAG_FORCE_CH_IDLE_HIGH
);
8561 REG_CLR_BIT(ah
, AR_TIMER_MODE
, AR_QUIET_TIMER_EN
);
8565 while (ath9k_hw_numtxpending(ah
, q
)) {
8566 if ((--wait
) == 0) {
8567 DPRINTF(ah
->ah_sc
, ATH_DBG_XMIT
,
8568 "%s: Failed to stop Tx DMA in 100 "
8569 "msec after killing last frame\n",
8576 REG_CLR_BIT(ah
, AR_DIAG_SW
, AR_DIAG_FORCE_CH_IDLE_HIGH
);
8579 REG_WRITE(ah
, AR_Q_TXD
, 0);