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.
18 #include <asm/unaligned.h>
26 static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
27 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
28 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
29 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
31 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
32 static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
35 static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
36 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
38 static const struct hal_percal_data iq_cal_multi_sample = {
42 ath9k_hw_iqcal_collect,
45 static const struct hal_percal_data iq_cal_single_sample = {
49 ath9k_hw_iqcal_collect,
52 static const struct hal_percal_data adc_gain_cal_multi_sample = {
56 ath9k_hw_adc_gaincal_collect,
57 ath9k_hw_adc_gaincal_calibrate
59 static const struct hal_percal_data adc_gain_cal_single_sample = {
63 ath9k_hw_adc_gaincal_collect,
64 ath9k_hw_adc_gaincal_calibrate
66 static const struct hal_percal_data adc_dc_cal_multi_sample = {
70 ath9k_hw_adc_dccal_collect,
71 ath9k_hw_adc_dccal_calibrate
73 static const struct hal_percal_data adc_dc_cal_single_sample = {
77 ath9k_hw_adc_dccal_collect,
78 ath9k_hw_adc_dccal_calibrate
80 static const struct hal_percal_data adc_init_dc_cal = {
84 ath9k_hw_adc_dccal_collect,
85 ath9k_hw_adc_dccal_calibrate
88 static const struct ath_hal ar5416hal = {
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,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 static struct ath9k_rate_table ar5416_11a_table = {
115 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
116 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
117 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
118 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
119 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
120 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
121 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
122 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
126 static struct ath9k_rate_table ar5416_11b_table = {
130 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
131 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
132 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
133 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
137 static struct ath9k_rate_table ar5416_11g_table = {
141 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
142 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
143 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
144 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
146 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
147 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
148 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
149 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
150 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
151 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
152 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
153 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
157 static struct ath9k_rate_table ar5416_11ng_table = {
161 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
162 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
163 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
164 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
166 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
167 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
168 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
169 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
170 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
171 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
172 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
173 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
174 {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
175 {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
176 {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
177 {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
178 {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
179 {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
180 {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
181 {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
182 {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
183 {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
184 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
185 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
186 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
187 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
188 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
189 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
193 static struct ath9k_rate_table ar5416_11na_table = {
197 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
198 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
199 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
200 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
201 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
202 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
203 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
204 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
205 {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
206 {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
207 {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
208 {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
209 {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
210 {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
211 {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
212 {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
213 {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
214 {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
215 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
216 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
217 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
218 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
219 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
220 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
224 static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
225 const struct ath9k_channel *chan)
227 if (IS_CHAN_CCK(chan))
228 return WIRELESS_MODE_11b;
230 return WIRELESS_MODE_11g;
231 return WIRELESS_MODE_11a;
234 static bool ath9k_hw_wait(struct ath_hal *ah,
241 for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
242 if ((REG_READ(ah, reg) & mask) == val)
245 udelay(AH_TIME_QUANTUM);
247 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
248 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
249 __func__, reg, REG_READ(ah, reg), mask, val);
253 static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
256 (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
258 if (!ath9k_hw_wait(ah,
259 AR_EEPROM_STATUS_DATA,
260 AR_EEPROM_STATUS_DATA_BUSY |
261 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
265 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
266 AR_EEPROM_STATUS_DATA_VAL);
271 static int ath9k_hw_flash_map(struct ath_hal *ah)
273 struct ath_hal_5416 *ahp = AH5416(ah);
275 ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
277 if (!ahp->ah_cal_mem) {
278 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
279 "%s: cannot remap eeprom region \n", __func__);
286 static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
289 struct ath_hal_5416 *ahp = AH5416(ah);
291 *data = ioread16(ahp->ah_cal_mem + off);
295 static void ath9k_hw_read_revisions(struct ath_hal *ah)
299 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
302 val = REG_READ(ah, AR_SREV);
305 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
307 ah->ah_macRev = MS(val, AR_SREV_REVISION2);
308 ah->ah_isPciExpress =
309 (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
312 if (!AR_SREV_9100(ah))
313 ah->ah_macVersion = MS(val, AR_SREV_VERSION);
315 ah->ah_macRev = val & AR_SREV_REVISION;
317 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
318 ah->ah_isPciExpress = true;
322 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
327 for (i = 0, retval = 0; i < n; i++) {
328 retval = (retval << 1) | (val & 1);
334 static void ath9k_hw_set_defaults(struct ath_hal *ah)
338 ah->ah_config.ath_hal_dma_beacon_response_time = 2;
339 ah->ah_config.ath_hal_sw_beacon_response_time = 10;
340 ah->ah_config.ath_hal_additional_swba_backoff = 0;
341 ah->ah_config.ath_hal_6mb_ack = 0x0;
342 ah->ah_config.ath_hal_cwmIgnoreExtCCA = 0;
343 ah->ah_config.ath_hal_pciePowerSaveEnable = 0;
344 ah->ah_config.ath_hal_pcieL1SKPEnable = 0;
345 ah->ah_config.ath_hal_pcieClockReq = 0;
346 ah->ah_config.ath_hal_pciePowerReset = 0x100;
347 ah->ah_config.ath_hal_pcieRestore = 0;
348 ah->ah_config.ath_hal_pcieWaen = 0;
349 ah->ah_config.ath_hal_analogShiftReg = 1;
350 ah->ah_config.ath_hal_htEnable = 1;
351 ah->ah_config.ath_hal_ofdmTrigLow = 200;
352 ah->ah_config.ath_hal_ofdmTrigHigh = 500;
353 ah->ah_config.ath_hal_cckTrigHigh = 200;
354 ah->ah_config.ath_hal_cckTrigLow = 100;
355 ah->ah_config.ath_hal_enableANI = 0;
356 ah->ah_config.ath_hal_noiseImmunityLvl = 4;
357 ah->ah_config.ath_hal_ofdmWeakSigDet = 1;
358 ah->ah_config.ath_hal_cckWeakSigThr = 0;
359 ah->ah_config.ath_hal_spurImmunityLvl = 2;
360 ah->ah_config.ath_hal_firStepLvl = 0;
361 ah->ah_config.ath_hal_rssiThrHigh = 40;
362 ah->ah_config.ath_hal_rssiThrLow = 7;
363 ah->ah_config.ath_hal_diversityControl = 0;
364 ah->ah_config.ath_hal_antennaSwitchSwap = 0;
366 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
367 ah->ah_config.ath_hal_spurChans[i][0] = AR_NO_SPUR;
368 ah->ah_config.ath_hal_spurChans[i][1] = AR_NO_SPUR;
371 ah->ah_config.ath_hal_intrMitigation = 0;
374 static inline void ath9k_hw_override_ini(struct ath_hal *ah,
375 struct ath9k_channel *chan)
377 if (!AR_SREV_5416_V20_OR_LATER(ah)
378 || AR_SREV_9280_10_OR_LATER(ah))
381 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
384 static inline void ath9k_hw_init_bb(struct ath_hal *ah,
385 struct ath9k_channel *chan)
389 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
390 if (IS_CHAN_CCK(chan))
391 synthDelay = (4 * synthDelay) / 22;
395 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
397 udelay(synthDelay + BASE_ACTIVATE_DELAY);
400 static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
401 enum ath9k_opmode opmode)
403 struct ath_hal_5416 *ahp = AH5416(ah);
405 ahp->ah_maskReg = AR_IMR_TXERR |
411 if (ahp->ah_intrMitigation)
412 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
414 ahp->ah_maskReg |= AR_IMR_RXOK;
416 ahp->ah_maskReg |= AR_IMR_TXOK;
418 if (opmode == ATH9K_M_HOSTAP)
419 ahp->ah_maskReg |= AR_IMR_MIB;
421 REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
422 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
424 if (!AR_SREV_9100(ah)) {
425 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
426 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
427 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
431 static inline void ath9k_hw_init_qos(struct ath_hal *ah)
433 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
434 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
436 REG_WRITE(ah, AR_QOS_NO_ACK,
437 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
438 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
439 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
441 REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
442 REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
443 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
444 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
445 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
448 static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
456 regVal = REG_READ(ah, reg) & ~mask;
457 regVal |= (val << shift) & mask;
459 REG_WRITE(ah, reg, regVal);
461 if (ah->ah_config.ath_hal_analogShiftReg)
467 static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
468 enum hal_freq_band freq_band)
470 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471 struct modal_eep_header *pModal =
472 &(eep->modalHeader[HAL_FREQ_BAND_2GHZ == freq_band]);
473 struct base_eep_header *pBase = &eep->baseEepHeader;
478 if (pBase->version >= 0x0E0D)
482 return num_ant_config;
486 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
487 struct ath9k_channel *chan,
491 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
492 struct modal_eep_header *pModal =
493 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
494 struct base_eep_header *pBase = &eep->baseEepHeader;
498 *config = pModal->antCtrlCommon & 0xFFFF;
501 if (pBase->version >= 0x0E0D) {
502 if (pModal->useAnt1) {
504 ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
516 static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
520 if (ath9k_hw_use_flash(ah))
521 return ath9k_hw_flash_read(ah, off, data);
523 return ath9k_hw_eeprom_read(ah, off, data);
526 static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
528 struct ath_hal_5416 *ahp = AH5416(ah);
529 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
531 int addr, ar5416_eep_start_loc = 0;
533 if (!ath9k_hw_use_flash(ah)) {
534 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
535 "%s: Reading from EEPROM, not flash\n", __func__);
536 ar5416_eep_start_loc = 256;
538 if (AR_SREV_9100(ah))
539 ar5416_eep_start_loc = 256;
541 eep_data = (u16 *) eep;
543 addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
545 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
547 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
548 "%s: Unable to read eeprom region \n",
557 /* XXX: Clean me up, make me more legible */
559 ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
560 struct ath9k_channel *chan)
562 struct modal_eep_header *pModal;
563 int i, regChainOffset;
564 struct ath_hal_5416 *ahp = AH5416(ah);
565 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
569 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
571 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
573 ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
574 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
576 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
577 if (AR_SREV_9280(ah)) {
582 if (AR_SREV_5416_V20_OR_LATER(ah) &&
583 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
585 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
587 regChainOffset = i * 0x1000;
589 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
590 pModal->antCtrlChain[i]);
592 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
594 AR_PHY_TIMING_CTRL4(0) +
596 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
597 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
598 SM(pModal->iqCalICh[i],
599 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
600 SM(pModal->iqCalQCh[i],
601 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
603 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
604 if ((eep->baseEepHeader.version &
605 AR5416_EEP_VER_MINOR_MASK) >=
606 AR5416_EEP_MINOR_VER_3) {
607 txRxAttenLocal = pModal->txRxAttenCh[i];
608 if (AR_SREV_9280_10_OR_LATER(ah)) {
612 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
618 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
624 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
630 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
640 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
643 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
650 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
651 | SM(pModal->bswAtten[i],
652 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
655 if (AR_SREV_9280_10_OR_LATER(ah)) {
659 AR9280_PHY_RXGAIN_TXRX_ATTEN,
664 AR9280_PHY_RXGAIN_TXRX_MARGIN,
665 pModal->rxTxMarginCh[i]);
668 AR_PHY_RXGAIN + regChainOffset,
672 ~AR_PHY_RXGAIN_TXRX_ATTEN) |
674 AR_PHY_RXGAIN_TXRX_ATTEN));
681 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
682 SM(pModal->rxTxMarginCh[i],
683 AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
688 if (AR_SREV_9280_10_OR_LATER(ah)) {
689 if (IS_CHAN_2GHZ(chan)) {
690 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
692 AR_AN_RF2G1_CH0_OB_S,
694 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
696 AR_AN_RF2G1_CH0_DB_S,
698 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
700 AR_AN_RF2G1_CH1_OB_S,
702 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
704 AR_AN_RF2G1_CH1_DB_S,
707 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
709 AR_AN_RF5G1_CH0_OB5_S,
711 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
713 AR_AN_RF5G1_CH0_DB5_S,
715 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
717 AR_AN_RF5G1_CH1_OB5_S,
719 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
721 AR_AN_RF5G1_CH1_DB5_S,
724 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
725 AR_AN_TOP2_XPABIAS_LVL,
726 AR_AN_TOP2_XPABIAS_LVL_S,
728 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
729 AR_AN_TOP2_LOCALBIAS,
730 AR_AN_TOP2_LOCALBIAS_S,
732 DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
733 pModal->force_xpaon);
734 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
735 pModal->force_xpaon);
738 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
739 pModal->switchSettling);
740 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
741 pModal->adcDesiredSize);
743 if (!AR_SREV_9280_10_OR_LATER(ah))
744 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
745 AR_PHY_DESIRED_SZ_PGA,
746 pModal->pgaDesiredSize);
748 REG_WRITE(ah, AR_PHY_RF_CTL4,
749 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
750 | SM(pModal->txEndToXpaOff,
751 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
752 | SM(pModal->txFrameToXpaOn,
753 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
754 | SM(pModal->txFrameToXpaOn,
755 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
757 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
758 pModal->txEndToRxOn);
759 if (AR_SREV_9280_10_OR_LATER(ah)) {
760 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
762 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
763 AR_PHY_EXT_CCA0_THRESH62,
766 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
768 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
769 AR_PHY_EXT_CCA_THRESH62,
773 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
774 AR5416_EEP_MINOR_VER_2) {
775 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
776 AR_PHY_TX_END_DATA_START,
777 pModal->txFrameToDataStart);
778 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
779 pModal->txFrameToPaOn);
782 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
783 AR5416_EEP_MINOR_VER_3) {
784 if (IS_CHAN_HT40(chan))
785 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
786 AR_PHY_SETTLING_SWITCH,
787 pModal->swSettleHt40);
793 static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
798 struct ath_hal_5416 *ahp = AH5416(ah);
799 bool need_swap = false;
800 struct ar5416_eeprom *eep =
801 (struct ar5416_eeprom *) &ahp->ah_eeprom;
803 if (!ath9k_hw_use_flash(ah)) {
807 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
809 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
810 "%s: Reading Magic # failed\n", __func__);
813 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
816 if (magic != AR5416_EEPROM_MAGIC) {
817 magic2 = swab16(magic);
819 if (magic2 == AR5416_EEPROM_MAGIC) {
821 eepdata = (u16 *) (&ahp->ah_eeprom);
825 sizeof(struct ar5416_eeprom) /
826 sizeof(u16); addr++) {
829 temp = swab16(*eepdata);
833 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
834 "0x%04X ", *eepdata);
835 if (((addr + 1) % 6) == 0)
841 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
842 "Invalid EEPROM Magic. "
843 "endianness missmatch.\n");
848 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
849 need_swap ? "True" : "False");
852 el = swab16(ahp->ah_eeprom.baseEepHeader.length);
854 el = ahp->ah_eeprom.baseEepHeader.length;
856 if (el > sizeof(struct ar5416_eeprom))
857 el = sizeof(struct ar5416_eeprom) / sizeof(u16);
859 el = el / sizeof(u16);
861 eepdata = (u16 *) (&ahp->ah_eeprom);
863 for (i = 0; i < el; i++)
870 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
871 "EEPROM Endianness is not native.. Changing \n");
873 word = swab16(eep->baseEepHeader.length);
874 eep->baseEepHeader.length = word;
876 word = swab16(eep->baseEepHeader.checksum);
877 eep->baseEepHeader.checksum = word;
879 word = swab16(eep->baseEepHeader.version);
880 eep->baseEepHeader.version = word;
882 word = swab16(eep->baseEepHeader.regDmn[0]);
883 eep->baseEepHeader.regDmn[0] = word;
885 word = swab16(eep->baseEepHeader.regDmn[1]);
886 eep->baseEepHeader.regDmn[1] = word;
888 word = swab16(eep->baseEepHeader.rfSilent);
889 eep->baseEepHeader.rfSilent = word;
891 word = swab16(eep->baseEepHeader.blueToothOptions);
892 eep->baseEepHeader.blueToothOptions = word;
894 word = swab16(eep->baseEepHeader.deviceCap);
895 eep->baseEepHeader.deviceCap = word;
897 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
898 struct modal_eep_header *pModal =
899 &eep->modalHeader[j];
900 integer = swab32(pModal->antCtrlCommon);
901 pModal->antCtrlCommon = integer;
903 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
904 integer = swab32(pModal->antCtrlChain[i]);
905 pModal->antCtrlChain[i] = integer;
908 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
909 word = swab16(pModal->spurChans[i].spurChan);
910 pModal->spurChans[i].spurChan = word;
915 if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
916 ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
917 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
918 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
919 sum, ar5416_get_eep_ver(ahp));
926 static bool ath9k_hw_chip_test(struct ath_hal *ah)
928 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
930 u32 patternData[4] = { 0x55555555,
936 for (i = 0; i < 2; i++) {
937 u32 addr = regAddr[i];
940 regHold[i] = REG_READ(ah, addr);
941 for (j = 0; j < 0x100; j++) {
942 wrData = (j << 16) | j;
943 REG_WRITE(ah, addr, wrData);
944 rdData = REG_READ(ah, addr);
945 if (rdData != wrData) {
946 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
947 "%s: address test failed "
948 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
949 __func__, addr, wrData, rdData);
953 for (j = 0; j < 4; j++) {
954 wrData = patternData[j];
955 REG_WRITE(ah, addr, wrData);
956 rdData = REG_READ(ah, addr);
957 if (wrData != rdData) {
958 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
959 "%s: address test failed "
960 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
961 __func__, addr, wrData, rdData);
965 REG_WRITE(ah, regAddr[i], regHold[i]);
971 u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
973 u32 bits = REG_READ(ah, AR_RX_FILTER);
974 u32 phybits = REG_READ(ah, AR_PHY_ERR);
976 if (phybits & AR_PHY_ERR_RADAR)
977 bits |= ATH9K_RX_FILTER_PHYRADAR;
978 if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
979 bits |= ATH9K_RX_FILTER_PHYERR;
983 void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
987 REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
989 if (bits & ATH9K_RX_FILTER_PHYRADAR)
990 phybits |= AR_PHY_ERR_RADAR;
991 if (bits & ATH9K_RX_FILTER_PHYERR)
992 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
993 REG_WRITE(ah, AR_PHY_ERR, phybits);
996 REG_WRITE(ah, AR_RXCFG,
997 REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
999 REG_WRITE(ah, AR_RXCFG,
1000 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
1003 bool ath9k_hw_setcapability(struct ath_hal *ah,
1004 enum hal_capability_type type,
1009 struct ath_hal_5416 *ahp = AH5416(ah);
1013 case HAL_CAP_TKIP_MIC:
1015 ahp->ah_staId1Defaults |=
1016 AR_STA_ID1_CRPT_MIC_ENABLE;
1018 ahp->ah_staId1Defaults &=
1019 ~AR_STA_ID1_CRPT_MIC_ENABLE;
1021 case HAL_CAP_DIVERSITY:
1022 v = REG_READ(ah, AR_PHY_CCK_DETECT);
1024 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1026 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1027 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
1029 case HAL_CAP_MCAST_KEYSRCH:
1031 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1033 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1035 case HAL_CAP_TSF_ADJUST:
1037 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
1039 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
1046 void ath9k_hw_dmaRegDump(struct ath_hal *ah)
1048 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
1049 int qcuOffset = 0, dcuOffset = 0;
1050 u32 *qcuBase = &val[0], *dcuBase = &val[4];
1053 REG_WRITE(ah, AR_MACMISC,
1054 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1055 (AR_MACMISC_MISC_OBS_BUS_1 <<
1056 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1058 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
1059 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
1061 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1063 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
1064 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
1067 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
1068 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1069 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1071 for (i = 0; i < ATH9K_NUM_QUEUES;
1072 i++, qcuOffset += 4, dcuOffset += 5) {
1083 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1084 "%2d %2x %1x %2x %2x\n",
1085 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1086 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
1088 val[2] & (0x7 << (i * 3)) >> (i * 3),
1089 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1092 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1093 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1094 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
1095 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
1096 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1097 "qcu_complete state: %2x dcu_complete state: %2x\n",
1098 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
1099 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1100 "dcu_arb state: %2x dcu_fp state: %2x\n",
1101 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
1102 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1103 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
1104 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
1105 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1106 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
1107 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
1108 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1109 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
1110 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
1112 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
1113 REG_READ(ah, AR_OBS_BUS_1));
1114 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1115 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
1118 u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1123 static u32 cycles, rx_clear, rx_frame, tx_frame;
1126 u32 rc = REG_READ(ah, AR_RCCNT);
1127 u32 rf = REG_READ(ah, AR_RFCNT);
1128 u32 tf = REG_READ(ah, AR_TFCNT);
1129 u32 cc = REG_READ(ah, AR_CCCNT);
1131 if (cycles == 0 || cycles > cc) {
1132 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1133 "%s: cycle counter wrap. ExtBusy = 0\n",
1137 u32 cc_d = cc - cycles;
1138 u32 rc_d = rc - rx_clear;
1139 u32 rf_d = rf - rx_frame;
1140 u32 tf_d = tf - tx_frame;
1143 *rxc_pcnt = rc_d * 100 / cc_d;
1144 *rxf_pcnt = rf_d * 100 / cc_d;
1145 *txf_pcnt = tf_d * 100 / cc_d;
1159 void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
1163 if (mode == ATH9K_HT_MACMODE_2040 &&
1164 !ah->ah_config.ath_hal_cwmIgnoreExtCCA)
1165 macmode = AR_2040_JOINED_RX_CLEAR;
1169 REG_WRITE(ah, AR_2040_MODE, macmode);
1172 static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
1174 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1178 static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1179 struct ath_softc *sc,
1183 static const u8 defbssidmask[ETH_ALEN] =
1184 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1185 struct ath_hal_5416 *ahp;
1188 ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
1190 DPRINTF(sc, ATH_DBG_FATAL,
1191 "%s: cannot allocate memory for state block\n",
1199 memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1204 ah->ah_devid = devid;
1205 ah->ah_subvendorid = 0;
1208 if ((devid == AR5416_AR9100_DEVID))
1209 ah->ah_macVersion = AR_SREV_VERSION_9100;
1210 if (!AR_SREV_9100(ah))
1211 ah->ah_flags = AH_USE_EEPROM;
1213 ah->ah_powerLimit = MAX_RATE_POWER;
1214 ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
1216 ahp->ah_atimWindow = 0;
1217 ahp->ah_diversityControl = ah->ah_config.ath_hal_diversityControl;
1218 ahp->ah_antennaSwitchSwap =
1219 ah->ah_config.ath_hal_antennaSwitchSwap;
1221 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
1222 ahp->ah_beaconInterval = 100;
1223 ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
1224 ahp->ah_slottime = (u32) -1;
1225 ahp->ah_acktimeout = (u32) -1;
1226 ahp->ah_ctstimeout = (u32) -1;
1227 ahp->ah_globaltxtimeout = (u32) -1;
1228 memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
1230 ahp->ah_gBeaconRate = 0;
1235 static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
1239 if (ath9k_hw_use_flash(ah))
1240 ath9k_hw_flash_map(ah);
1242 if (!ath9k_hw_fill_eeprom(ah))
1245 status = ath9k_hw_check_eeprom(ah);
1250 u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1251 enum eeprom_param param)
1253 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
1254 struct modal_eep_header *pModal = eep->modalHeader;
1255 struct base_eep_header *pBase = &eep->baseEepHeader;
1258 case EEP_NFTHRESH_5:
1259 return -pModal[0].noiseFloorThreshCh[0];
1260 case EEP_NFTHRESH_2:
1261 return -pModal[1].noiseFloorThreshCh[0];
1262 case AR_EEPROM_MAC(0):
1263 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1264 case AR_EEPROM_MAC(1):
1265 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1266 case AR_EEPROM_MAC(2):
1267 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1269 return pBase->regDmn[0];
1271 return pBase->regDmn[1];
1273 return pBase->deviceCap;
1275 return pBase->opCapFlags;
1277 return pBase->rfSilent;
1279 return pModal[0].ob;
1281 return pModal[0].db;
1283 return pModal[1].ob;
1285 return pModal[1].db;
1287 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
1289 return pBase->txMask;
1291 return pBase->rxMask;
1297 static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1302 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
1303 for (i = 0; i < 8; i++)
1304 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
1305 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
1306 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
1307 return ath9k_hw_reverse_bits(val, 8);
1310 static inline int ath9k_hw_init_macaddr(struct ath_hal *ah)
1315 struct ath_hal_5416 *ahp = AH5416(ah);
1316 DECLARE_MAC_BUF(mac);
1319 for (i = 0; i < 3; i++) {
1320 eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
1322 ahp->ah_macaddr[2 * i] = eeval >> 8;
1323 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
1325 if (sum == 0 || sum == 0xffff * 3) {
1326 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1327 "%s: mac address read failed: %s\n", __func__,
1328 print_mac(mac, ahp->ah_macaddr));
1329 return -EADDRNOTAVAIL;
1335 static inline int16_t ath9k_hw_interpolate(u16 target,
1339 int16_t targetRight)
1343 if (srcRight == srcLeft) {
1346 rv = (int16_t) (((target - srcLeft) * targetRight +
1347 (srcRight - target) * targetLeft) /
1348 (srcRight - srcLeft));
1353 static inline u16 ath9k_hw_fbin2freq(u8 fbin,
1357 if (fbin == AR5416_BCHAN_UNUSED)
1360 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1363 static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1367 struct ath_hal_5416 *ahp = AH5416(ah);
1368 struct ar5416_eeprom *eep =
1369 (struct ar5416_eeprom *) &ahp->ah_eeprom;
1370 u16 spur_val = AR_NO_SPUR;
1372 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1373 "Getting spur idx %d is2Ghz. %d val %x\n",
1374 i, is2GHz, ah->ah_config.ath_hal_spurChans[i][is2GHz]);
1376 switch (ah->ah_config.ath_hal_spurMode) {
1379 case SPUR_ENABLE_IOCTL:
1380 spur_val = ah->ah_config.ath_hal_spurChans[i][is2GHz];
1381 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1382 "Getting spur val from new loc. %d\n", spur_val);
1384 case SPUR_ENABLE_EEPROM:
1385 spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
1392 static inline int ath9k_hw_rfattach(struct ath_hal *ah)
1394 bool rfStatus = false;
1397 rfStatus = ath9k_hw_init_rf(ah, &ecode);
1399 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1400 "%s: RF setup failed, status %u\n", __func__,
1408 static int ath9k_hw_rf_claim(struct ath_hal *ah)
1412 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1414 val = ath9k_hw_get_radiorev(ah);
1415 switch (val & AR_RADIO_SREV_MAJOR) {
1417 val = AR_RAD5133_SREV_MAJOR;
1419 case AR_RAD5133_SREV_MAJOR:
1420 case AR_RAD5122_SREV_MAJOR:
1421 case AR_RAD2133_SREV_MAJOR:
1422 case AR_RAD2122_SREV_MAJOR:
1425 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1426 "%s: 5G Radio Chip Rev 0x%02X is not "
1427 "supported by this driver\n",
1428 __func__, ah->ah_analog5GhzRev);
1432 ah->ah_analog5GhzRev = val;
1437 static inline void ath9k_hw_init_pll(struct ath_hal *ah,
1438 struct ath9k_channel *chan)
1442 if (AR_SREV_9100(ah)) {
1443 if (chan && IS_CHAN_5GHZ(chan))
1448 if (AR_SREV_9280_10_OR_LATER(ah)) {
1449 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1451 if (chan && IS_CHAN_HALF_RATE(chan))
1452 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1453 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1454 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1456 if (chan && IS_CHAN_5GHZ(chan)) {
1457 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1460 if (AR_SREV_9280_20(ah)) {
1461 if (((chan->channel % 20) == 0)
1462 || ((chan->channel % 10) == 0))
1468 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1471 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1473 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1475 if (chan && IS_CHAN_HALF_RATE(chan))
1476 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1477 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1478 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1480 if (chan && IS_CHAN_5GHZ(chan))
1481 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1483 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1485 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1487 if (chan && IS_CHAN_HALF_RATE(chan))
1488 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1489 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1490 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1492 if (chan && IS_CHAN_5GHZ(chan))
1493 pll |= SM(0xa, AR_RTC_PLL_DIV);
1495 pll |= SM(0xb, AR_RTC_PLL_DIV);
1498 REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
1500 udelay(RTC_PLL_SETTLE_DELAY);
1502 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1505 static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1506 enum ath9k_ht_macmode macmode)
1509 struct ath_hal_5416 *ahp = AH5416(ah);
1511 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1512 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
1514 if (IS_CHAN_HT40(chan)) {
1515 phymode |= AR_PHY_FC_DYN2040_EN;
1517 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1518 (chan->chanmode == CHANNEL_G_HT40PLUS))
1519 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1521 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1522 phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1524 REG_WRITE(ah, AR_PHY_TURBO, phymode);
1526 ath9k_hw_set11nmac2040(ah, macmode);
1528 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1529 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1532 static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1536 val = REG_READ(ah, AR_STA_ID1);
1537 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1539 case ATH9K_M_HOSTAP:
1540 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
1541 | AR_STA_ID1_KSRCH_MODE);
1542 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1545 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1546 | AR_STA_ID1_KSRCH_MODE);
1547 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1550 case ATH9K_M_MONITOR:
1551 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1557 ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1564 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1565 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1567 if (!AR_SREV_9280_10_OR_LATER(ah))
1568 rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
1571 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1572 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1574 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1577 static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1582 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1583 AR_RTC_FORCE_WAKE_ON_INT);
1585 if (AR_SREV_9100(ah)) {
1586 rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1587 AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1589 tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1591 (AR_INTR_SYNC_LOCAL_TIMEOUT |
1592 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1593 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1594 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
1596 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1599 rst_flags = AR_RTC_RC_MAC_WARM;
1600 if (type == ATH9K_RESET_COLD)
1601 rst_flags |= AR_RTC_RC_MAC_COLD;
1604 REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
1607 REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
1608 if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
1609 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1610 "%s: RTC stuck in MAC reset\n",
1615 if (!AR_SREV_9100(ah))
1616 REG_WRITE(ah, AR_RC, 0);
1618 ath9k_hw_init_pll(ah, NULL);
1620 if (AR_SREV_9100(ah))
1626 static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1628 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1629 AR_RTC_FORCE_WAKE_ON_INT);
1631 REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
1632 REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
1634 if (!ath9k_hw_wait(ah,
1637 AR_RTC_STATUS_ON)) {
1638 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
1643 ath9k_hw_read_revisions(ah);
1645 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1648 static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1651 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1652 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1655 case ATH9K_RESET_POWER_ON:
1656 return ath9k_hw_set_reset_power_on(ah);
1658 case ATH9K_RESET_WARM:
1659 case ATH9K_RESET_COLD:
1660 return ath9k_hw_set_reset(ah, type);
1668 struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1669 struct ath9k_channel *chan)
1671 if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
1672 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1673 "%s: invalid channel %u/0x%x; not marked as "
1674 "2GHz or 5GHz\n", __func__, chan->channel,
1675 chan->channelFlags);
1679 if (!IS_CHAN_OFDM(chan) &&
1680 !IS_CHAN_CCK(chan) &&
1681 !IS_CHAN_HT20(chan) &&
1682 !IS_CHAN_HT40(chan)) {
1683 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1684 "%s: invalid channel %u/0x%x; not marked as "
1685 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1686 __func__, chan->channel, chan->channelFlags);
1690 return ath9k_regd_check_channel(ah, chan);
1694 ath9k_hw_get_lower_upper_index(u8 target,
1702 if (target <= pList[0]) {
1703 *indexL = *indexR = 0;
1706 if (target >= pList[listSize - 1]) {
1707 *indexL = *indexR = (u16) (listSize - 1);
1711 for (i = 0; i < listSize - 1; i++) {
1712 if (pList[i] == target) {
1713 *indexL = *indexR = i;
1716 if (target < pList[i + 1]) {
1718 *indexR = (u16) (i + 1);
1725 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
1728 int16_t sort[ATH9K_NF_CAL_HIST_MAX];
1731 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
1732 sort[i] = nfCalBuffer[i];
1734 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
1735 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
1736 if (sort[j] > sort[j - 1]) {
1738 sort[j] = sort[j - 1];
1739 sort[j - 1] = nfval;
1743 nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
1748 static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
1753 for (i = 0; i < NUM_NF_READINGS; i++) {
1754 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
1756 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
1759 if (h[i].invalidNFcount > 0) {
1760 if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
1761 || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
1762 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
1764 h[i].invalidNFcount--;
1765 h[i].privNF = nfarray[i];
1769 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
1775 static void ar5416GetNoiseFloor(struct ath_hal *ah,
1776 int16_t nfarray[NUM_NF_READINGS])
1780 if (AR_SREV_9280_10_OR_LATER(ah))
1781 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
1783 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1786 nf = 0 - ((nf ^ 0x1ff) + 1);
1787 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1788 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1791 if (AR_SREV_9280_10_OR_LATER(ah))
1792 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1793 AR9280_PHY_CH1_MINCCA_PWR);
1795 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1796 AR_PHY_CH1_MINCCA_PWR);
1799 nf = 0 - ((nf ^ 0x1ff) + 1);
1800 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1801 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1804 if (!AR_SREV_9280(ah)) {
1805 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
1806 AR_PHY_CH2_MINCCA_PWR);
1808 nf = 0 - ((nf ^ 0x1ff) + 1);
1809 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1810 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1814 if (AR_SREV_9280_10_OR_LATER(ah))
1815 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1816 AR9280_PHY_EXT_MINCCA_PWR);
1818 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1819 AR_PHY_EXT_MINCCA_PWR);
1822 nf = 0 - ((nf ^ 0x1ff) + 1);
1823 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1824 "NF calibrated [ext] [chain 0] is %d\n", nf);
1827 if (AR_SREV_9280_10_OR_LATER(ah))
1828 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1829 AR9280_PHY_CH1_EXT_MINCCA_PWR);
1831 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1832 AR_PHY_CH1_EXT_MINCCA_PWR);
1835 nf = 0 - ((nf ^ 0x1ff) + 1);
1836 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1837 "NF calibrated [ext] [chain 1] is %d\n", nf);
1840 if (!AR_SREV_9280(ah)) {
1841 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
1842 AR_PHY_CH2_EXT_MINCCA_PWR);
1844 nf = 0 - ((nf ^ 0x1ff) + 1);
1845 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1846 "NF calibrated [ext] [chain 2] is %d\n", nf);
1852 getNoiseFloorThresh(struct ath_hal *ah,
1853 const struct ath9k_channel *chan,
1856 struct ath_hal_5416 *ahp = AH5416(ah);
1858 switch (chan->chanmode) {
1860 case CHANNEL_A_HT20:
1861 case CHANNEL_A_HT40PLUS:
1862 case CHANNEL_A_HT40MINUS:
1863 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
1867 case CHANNEL_G_HT20:
1868 case CHANNEL_G_HT40PLUS:
1869 case CHANNEL_G_HT40MINUS:
1870 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
1873 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1874 "%s: invalid channel flags 0x%x\n", __func__,
1875 chan->channelFlags);
1881 static void ath9k_hw_start_nfcal(struct ath_hal *ah)
1883 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1884 AR_PHY_AGC_CONTROL_ENABLE_NF);
1885 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1886 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1887 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1891 ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
1893 struct ath9k_nfcal_hist *h;
1896 const u32 ar5416_cca_regs[6] = {
1906 if (AR_SREV_9280(ah))
1911 #ifdef ATH_NF_PER_CHAN
1912 h = chan->nfCalHist;
1917 for (i = 0; i < NUM_NF_READINGS; i++) {
1918 if (chainmask & (1 << i)) {
1919 val = REG_READ(ah, ar5416_cca_regs[i]);
1921 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1922 REG_WRITE(ah, ar5416_cca_regs[i], val);
1926 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1927 AR_PHY_AGC_CONTROL_ENABLE_NF);
1928 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1929 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1930 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1932 for (j = 0; j < 1000; j++) {
1933 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1934 AR_PHY_AGC_CONTROL_NF) == 0)
1939 for (i = 0; i < NUM_NF_READINGS; i++) {
1940 if (chainmask & (1 << i)) {
1941 val = REG_READ(ah, ar5416_cca_regs[i]);
1943 val |= (((u32) (-50) << 1) & 0x1ff);
1944 REG_WRITE(ah, ar5416_cca_regs[i], val);
1949 static int16_t ath9k_hw_getnf(struct ath_hal *ah,
1950 struct ath9k_channel *chan)
1952 int16_t nf, nfThresh;
1953 int16_t nfarray[NUM_NF_READINGS] = { 0 };
1954 struct ath9k_nfcal_hist *h;
1957 if (AR_SREV_9280(ah))
1962 chan->channelFlags &= (~CHANNEL_CW_INT);
1963 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1964 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1965 "%s: NF did not complete in calibration window\n",
1968 chan->rawNoiseFloor = nf;
1969 return chan->rawNoiseFloor;
1971 ar5416GetNoiseFloor(ah, nfarray);
1973 if (getNoiseFloorThresh(ah, chan, &nfThresh)
1975 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1976 "%s: noise floor failed detected; "
1977 "detected %d, threshold %d\n", __func__,
1979 chan->channelFlags |= CHANNEL_CW_INT;
1983 #ifdef ATH_NF_PER_CHAN
1984 h = chan->nfCalHist;
1989 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
1990 chan->rawNoiseFloor = h[0].privNF;
1992 return chan->rawNoiseFloor;
1995 static void ath9k_hw_update_mibstats(struct ath_hal *ah,
1996 struct ath9k_mib_stats *stats)
1998 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
1999 stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
2000 stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
2001 stats->rts_good += REG_READ(ah, AR_RTS_OK);
2002 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
2005 static void ath9k_enable_mib_counters(struct ath_hal *ah)
2007 struct ath_hal_5416 *ahp = AH5416(ah);
2009 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
2011 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2013 REG_WRITE(ah, AR_FILT_OFDM, 0);
2014 REG_WRITE(ah, AR_FILT_CCK, 0);
2015 REG_WRITE(ah, AR_MIBC,
2016 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
2018 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2019 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2022 static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
2024 struct ath_hal_5416 *ahp = AH5416(ah);
2026 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
2028 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
2030 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2032 REG_WRITE(ah, AR_FILT_OFDM, 0);
2033 REG_WRITE(ah, AR_FILT_CCK, 0);
2036 static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
2037 struct ath9k_channel *chan)
2039 struct ath_hal_5416 *ahp = AH5416(ah);
2042 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2043 if (ahp->ah_ani[i].c.channel == chan->channel)
2045 if (ahp->ah_ani[i].c.channel == 0) {
2046 ahp->ah_ani[i].c.channel = chan->channel;
2047 ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
2052 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2053 "No more channel states left. Using channel 0\n");
2057 static void ath9k_hw_ani_attach(struct ath_hal *ah)
2059 struct ath_hal_5416 *ahp = AH5416(ah);
2062 ahp->ah_hasHwPhyCounters = 1;
2064 memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
2065 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2066 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
2067 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
2068 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
2069 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
2070 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
2071 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
2072 ahp->ah_ani[i].ofdmWeakSigDetectOff =
2073 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
2074 ahp->ah_ani[i].cckWeakSigThreshold =
2075 ATH9K_ANI_CCK_WEAK_SIG_THR;
2076 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
2077 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
2078 if (ahp->ah_hasHwPhyCounters) {
2079 ahp->ah_ani[i].ofdmPhyErrBase =
2080 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
2081 ahp->ah_ani[i].cckPhyErrBase =
2082 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
2085 if (ahp->ah_hasHwPhyCounters) {
2086 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2087 "Setting OfdmErrBase = 0x%08x\n",
2088 ahp->ah_ani[0].ofdmPhyErrBase);
2089 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
2090 ahp->ah_ani[0].cckPhyErrBase);
2092 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
2093 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
2094 ath9k_enable_mib_counters(ah);
2096 ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
2097 if (ah->ah_config.ath_hal_enableANI)
2098 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2101 static inline void ath9k_hw_ani_setup(struct ath_hal *ah)
2103 struct ath_hal_5416 *ahp = AH5416(ah);
2106 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
2107 const int coarseHigh[] = { -14, -14, -14, -14, -12 };
2108 const int coarseLow[] = { -64, -64, -64, -64, -70 };
2109 const int firpwr[] = { -78, -78, -78, -78, -80 };
2111 for (i = 0; i < 5; i++) {
2112 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
2113 ahp->ah_coarseHigh[i] = coarseHigh[i];
2114 ahp->ah_coarseLow[i] = coarseLow[i];
2115 ahp->ah_firpwr[i] = firpwr[i];
2119 static void ath9k_hw_ani_detach(struct ath_hal *ah)
2121 struct ath_hal_5416 *ahp = AH5416(ah);
2123 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
2124 if (ahp->ah_hasHwPhyCounters) {
2125 ath9k_hw_disable_mib_counters(ah);
2126 REG_WRITE(ah, AR_PHY_ERR_1, 0);
2127 REG_WRITE(ah, AR_PHY_ERR_2, 0);
2132 static bool ath9k_hw_ani_control(struct ath_hal *ah,
2133 enum ath9k_ani_cmd cmd, int param)
2135 struct ath_hal_5416 *ahp = AH5416(ah);
2136 struct ar5416AniState *aniState = ahp->ah_curani;
2138 switch (cmd & ahp->ah_ani_function) {
2139 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
2142 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
2143 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2144 "%s: level out of range (%u > %u)\n",
2146 (unsigned) ARRAY_SIZE(ahp->
2147 ah_totalSizeDesired));
2151 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2152 AR_PHY_DESIRED_SZ_TOT_DES,
2153 ahp->ah_totalSizeDesired[level]);
2154 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2155 AR_PHY_AGC_CTL1_COARSE_LOW,
2156 ahp->ah_coarseLow[level]);
2157 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2158 AR_PHY_AGC_CTL1_COARSE_HIGH,
2159 ahp->ah_coarseHigh[level]);
2160 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2161 AR_PHY_FIND_SIG_FIRPWR,
2162 ahp->ah_firpwr[level]);
2164 if (level > aniState->noiseImmunityLevel)
2165 ahp->ah_stats.ast_ani_niup++;
2166 else if (level < aniState->noiseImmunityLevel)
2167 ahp->ah_stats.ast_ani_nidown++;
2168 aniState->noiseImmunityLevel = level;
2171 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
2172 const int m1ThreshLow[] = { 127, 50 };
2173 const int m2ThreshLow[] = { 127, 40 };
2174 const int m1Thresh[] = { 127, 0x4d };
2175 const int m2Thresh[] = { 127, 0x40 };
2176 const int m2CountThr[] = { 31, 16 };
2177 const int m2CountThrLow[] = { 63, 48 };
2178 u32 on = param ? 1 : 0;
2180 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2181 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
2183 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2184 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
2186 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2187 AR_PHY_SFCORR_M1_THRESH,
2189 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2190 AR_PHY_SFCORR_M2_THRESH,
2192 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2193 AR_PHY_SFCORR_M2COUNT_THR,
2195 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2196 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
2199 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2200 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
2202 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2203 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
2205 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2206 AR_PHY_SFCORR_EXT_M1_THRESH,
2208 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2209 AR_PHY_SFCORR_EXT_M2_THRESH,
2213 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
2214 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2216 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
2217 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2219 if (!on != aniState->ofdmWeakSigDetectOff) {
2221 ahp->ah_stats.ast_ani_ofdmon++;
2223 ahp->ah_stats.ast_ani_ofdmoff++;
2224 aniState->ofdmWeakSigDetectOff = !on;
2228 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
2229 const int weakSigThrCck[] = { 8, 6 };
2230 u32 high = param ? 1 : 0;
2232 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
2233 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
2234 weakSigThrCck[high]);
2235 if (high != aniState->cckWeakSigThreshold) {
2237 ahp->ah_stats.ast_ani_cckhigh++;
2239 ahp->ah_stats.ast_ani_ccklow++;
2240 aniState->cckWeakSigThreshold = high;
2244 case ATH9K_ANI_FIRSTEP_LEVEL:{
2245 const int firstep[] = { 0, 4, 8 };
2248 if (level >= ARRAY_SIZE(firstep)) {
2249 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2250 "%s: level out of range (%u > %u)\n",
2252 (unsigned) ARRAY_SIZE(firstep));
2255 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2256 AR_PHY_FIND_SIG_FIRSTEP,
2258 if (level > aniState->firstepLevel)
2259 ahp->ah_stats.ast_ani_stepup++;
2260 else if (level < aniState->firstepLevel)
2261 ahp->ah_stats.ast_ani_stepdown++;
2262 aniState->firstepLevel = level;
2265 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
2266 const int cycpwrThr1[] =
2267 { 2, 4, 6, 8, 10, 12, 14, 16 };
2270 if (level >= ARRAY_SIZE(cycpwrThr1)) {
2271 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2272 "%s: level out of range (%u > %u)\n",
2275 ARRAY_SIZE(cycpwrThr1));
2278 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
2279 AR_PHY_TIMING5_CYCPWR_THR1,
2281 if (level > aniState->spurImmunityLevel)
2282 ahp->ah_stats.ast_ani_spurup++;
2283 else if (level < aniState->spurImmunityLevel)
2284 ahp->ah_stats.ast_ani_spurdown++;
2285 aniState->spurImmunityLevel = level;
2288 case ATH9K_ANI_PRESENT:
2291 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2292 "%s: invalid cmd %u\n", __func__, cmd);
2296 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
2297 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2298 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2299 "ofdmWeakSigDetectOff=%d\n",
2300 aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
2301 !aniState->ofdmWeakSigDetectOff);
2302 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2303 "cckWeakSigThreshold=%d, "
2304 "firstepLevel=%d, listenTime=%d\n",
2305 aniState->cckWeakSigThreshold, aniState->firstepLevel,
2306 aniState->listenTime);
2307 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2308 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2309 aniState->cycleCount, aniState->ofdmPhyErrCount,
2310 aniState->cckPhyErrCount);
2314 static void ath9k_ani_restart(struct ath_hal *ah)
2316 struct ath_hal_5416 *ahp = AH5416(ah);
2317 struct ar5416AniState *aniState;
2322 aniState = ahp->ah_curani;
2324 aniState->listenTime = 0;
2325 if (ahp->ah_hasHwPhyCounters) {
2326 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
2327 aniState->ofdmPhyErrBase = 0;
2328 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2329 "OFDM Trigger is too high for hw counters\n");
2331 aniState->ofdmPhyErrBase =
2332 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
2334 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
2335 aniState->cckPhyErrBase = 0;
2336 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2337 "CCK Trigger is too high for hw counters\n");
2339 aniState->cckPhyErrBase =
2340 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
2342 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2343 "%s: Writing ofdmbase=%u cckbase=%u\n",
2344 __func__, aniState->ofdmPhyErrBase,
2345 aniState->cckPhyErrBase);
2346 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
2347 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
2348 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2349 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2351 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2353 aniState->ofdmPhyErrCount = 0;
2354 aniState->cckPhyErrCount = 0;
2357 static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2359 struct ath_hal_5416 *ahp = AH5416(ah);
2360 struct ath9k_channel *chan = ah->ah_curchan;
2361 struct ar5416AniState *aniState;
2362 enum wireless_mode mode;
2368 aniState = ahp->ah_curani;
2370 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2371 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2372 aniState->noiseImmunityLevel + 1)) {
2377 if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
2378 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2379 aniState->spurImmunityLevel + 1)) {
2384 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2385 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2386 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2387 aniState->firstepLevel + 1);
2391 rssi = BEACON_RSSI(ahp);
2392 if (rssi > aniState->rssiThrHigh) {
2393 if (!aniState->ofdmWeakSigDetectOff) {
2394 if (ath9k_hw_ani_control(ah,
2395 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2397 ath9k_hw_ani_control(ah,
2398 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2403 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2404 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2405 aniState->firstepLevel + 1);
2408 } else if (rssi > aniState->rssiThrLow) {
2409 if (aniState->ofdmWeakSigDetectOff)
2410 ath9k_hw_ani_control(ah,
2411 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2413 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2414 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2415 aniState->firstepLevel + 1);
2418 mode = ath9k_hw_chan2wmode(ah, chan);
2419 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2420 if (!aniState->ofdmWeakSigDetectOff)
2421 ath9k_hw_ani_control(ah,
2422 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2424 if (aniState->firstepLevel > 0)
2425 ath9k_hw_ani_control(ah,
2426 ATH9K_ANI_FIRSTEP_LEVEL,
2433 static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2435 struct ath_hal_5416 *ahp = AH5416(ah);
2436 struct ath9k_channel *chan = ah->ah_curchan;
2437 struct ar5416AniState *aniState;
2438 enum wireless_mode mode;
2444 aniState = ahp->ah_curani;
2445 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2446 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2447 aniState->noiseImmunityLevel + 1)) {
2451 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2452 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2453 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2454 aniState->firstepLevel + 1);
2458 rssi = BEACON_RSSI(ahp);
2459 if (rssi > aniState->rssiThrLow) {
2460 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2461 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2462 aniState->firstepLevel + 1);
2464 mode = ath9k_hw_chan2wmode(ah, chan);
2465 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2466 if (aniState->firstepLevel > 0)
2467 ath9k_hw_ani_control(ah,
2468 ATH9K_ANI_FIRSTEP_LEVEL,
2474 static void ath9k_ani_reset(struct ath_hal *ah)
2476 struct ath_hal_5416 *ahp = AH5416(ah);
2477 struct ar5416AniState *aniState;
2478 struct ath9k_channel *chan = ah->ah_curchan;
2484 index = ath9k_hw_get_ani_channel_idx(ah, chan);
2485 aniState = &ahp->ah_ani[index];
2486 ahp->ah_curani = aniState;
2488 if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
2489 && ah->ah_opmode != ATH9K_M_IBSS) {
2490 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2491 "%s: Reset ANI state opmode %u\n", __func__,
2493 ahp->ah_stats.ast_ani_reset++;
2494 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
2495 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
2496 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
2497 ath9k_hw_ani_control(ah,
2498 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2499 !ATH9K_ANI_USE_OFDM_WEAK_SIG);
2500 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2501 ATH9K_ANI_CCK_WEAK_SIG_THR);
2502 ath9k_hw_setrxfilter(ah,
2503 ath9k_hw_getrxfilter(ah) |
2504 ATH9K_RX_FILTER_PHYERR);
2505 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2506 ahp->ah_curani->ofdmTrigHigh =
2507 ah->ah_config.ath_hal_ofdmTrigHigh;
2508 ahp->ah_curani->ofdmTrigLow =
2509 ah->ah_config.ath_hal_ofdmTrigLow;
2510 ahp->ah_curani->cckTrigHigh =
2511 ah->ah_config.ath_hal_cckTrigHigh;
2512 ahp->ah_curani->cckTrigLow =
2513 ah->ah_config.ath_hal_cckTrigLow;
2515 ath9k_ani_restart(ah);
2519 if (aniState->noiseImmunityLevel != 0)
2520 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2521 aniState->noiseImmunityLevel);
2522 if (aniState->spurImmunityLevel != 0)
2523 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2524 aniState->spurImmunityLevel);
2525 if (aniState->ofdmWeakSigDetectOff)
2526 ath9k_hw_ani_control(ah,
2527 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2528 !aniState->ofdmWeakSigDetectOff);
2529 if (aniState->cckWeakSigThreshold)
2530 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2531 aniState->cckWeakSigThreshold);
2532 if (aniState->firstepLevel != 0)
2533 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2534 aniState->firstepLevel);
2535 if (ahp->ah_hasHwPhyCounters) {
2536 ath9k_hw_setrxfilter(ah,
2537 ath9k_hw_getrxfilter(ah) &
2538 ~ATH9K_RX_FILTER_PHYERR);
2539 ath9k_ani_restart(ah);
2540 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2541 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2544 ath9k_ani_restart(ah);
2545 ath9k_hw_setrxfilter(ah,
2546 ath9k_hw_getrxfilter(ah) |
2547 ATH9K_RX_FILTER_PHYERR);
2551 void ath9k_hw_procmibevent(struct ath_hal *ah,
2552 const struct ath9k_node_stats *stats)
2554 struct ath_hal_5416 *ahp = AH5416(ah);
2555 u32 phyCnt1, phyCnt2;
2557 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
2559 REG_WRITE(ah, AR_FILT_OFDM, 0);
2560 REG_WRITE(ah, AR_FILT_CCK, 0);
2561 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
2562 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
2564 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2565 ahp->ah_stats.ast_nodestats = *stats;
2570 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2571 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2572 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
2573 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
2574 struct ar5416AniState *aniState = ahp->ah_curani;
2575 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2577 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2578 ahp->ah_stats.ast_ani_ofdmerrs +=
2579 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2580 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2582 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2583 ahp->ah_stats.ast_ani_cckerrs +=
2584 cckPhyErrCnt - aniState->cckPhyErrCount;
2585 aniState->cckPhyErrCount = cckPhyErrCnt;
2587 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
2588 ath9k_hw_ani_ofdm_err_trigger(ah);
2589 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
2590 ath9k_hw_ani_cck_err_trigger(ah);
2592 ath9k_ani_restart(ah);
2596 static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
2598 struct ath_hal_5416 *ahp = AH5416(ah);
2599 struct ar5416AniState *aniState;
2602 aniState = ahp->ah_curani;
2604 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2605 if (aniState->firstepLevel > 0) {
2606 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2607 aniState->firstepLevel - 1)) {
2612 rssi = BEACON_RSSI(ahp);
2613 if (rssi > aniState->rssiThrHigh) {
2614 /* XXX: Handle me */
2615 } else if (rssi > aniState->rssiThrLow) {
2616 if (aniState->ofdmWeakSigDetectOff) {
2617 if (ath9k_hw_ani_control(ah,
2618 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2624 if (aniState->firstepLevel > 0) {
2625 if (ath9k_hw_ani_control
2626 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2627 aniState->firstepLevel - 1) ==
2633 if (aniState->firstepLevel > 0) {
2634 if (ath9k_hw_ani_control
2635 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2636 aniState->firstepLevel - 1) ==
2644 if (aniState->spurImmunityLevel > 0) {
2645 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2646 aniState->spurImmunityLevel - 1)) {
2651 if (aniState->noiseImmunityLevel > 0) {
2652 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2653 aniState->noiseImmunityLevel - 1);
2658 static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
2660 struct ath_hal_5416 *ahp = AH5416(ah);
2661 struct ar5416AniState *aniState;
2662 u32 txFrameCount, rxFrameCount, cycleCount;
2665 txFrameCount = REG_READ(ah, AR_TFCNT);
2666 rxFrameCount = REG_READ(ah, AR_RFCNT);
2667 cycleCount = REG_READ(ah, AR_CCCNT);
2669 aniState = ahp->ah_curani;
2670 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
2673 ahp->ah_stats.ast_ani_lzero++;
2675 int32_t ccdelta = cycleCount - aniState->cycleCount;
2676 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
2677 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
2678 listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
2680 aniState->cycleCount = cycleCount;
2681 aniState->txFrameCount = txFrameCount;
2682 aniState->rxFrameCount = rxFrameCount;
2687 void ath9k_hw_ani_monitor(struct ath_hal *ah,
2688 const struct ath9k_node_stats *stats,
2689 struct ath9k_channel *chan)
2691 struct ath_hal_5416 *ahp = AH5416(ah);
2692 struct ar5416AniState *aniState;
2695 aniState = ahp->ah_curani;
2696 ahp->ah_stats.ast_nodestats = *stats;
2698 listenTime = ath9k_hw_ani_get_listen_time(ah);
2699 if (listenTime < 0) {
2700 ahp->ah_stats.ast_ani_lneg++;
2701 ath9k_ani_restart(ah);
2705 aniState->listenTime += listenTime;
2707 if (ahp->ah_hasHwPhyCounters) {
2708 u32 phyCnt1, phyCnt2;
2709 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2711 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2713 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2714 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2716 if (phyCnt1 < aniState->ofdmPhyErrBase ||
2717 phyCnt2 < aniState->cckPhyErrBase) {
2718 if (phyCnt1 < aniState->ofdmPhyErrBase) {
2719 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2720 "%s: phyCnt1 0x%x, resetting "
2721 "counter value to 0x%x\n",
2723 aniState->ofdmPhyErrBase);
2724 REG_WRITE(ah, AR_PHY_ERR_1,
2725 aniState->ofdmPhyErrBase);
2726 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
2727 AR_PHY_ERR_OFDM_TIMING);
2729 if (phyCnt2 < aniState->cckPhyErrBase) {
2730 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2731 "%s: phyCnt2 0x%x, resetting "
2732 "counter value to 0x%x\n",
2734 aniState->cckPhyErrBase);
2735 REG_WRITE(ah, AR_PHY_ERR_2,
2736 aniState->cckPhyErrBase);
2737 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
2738 AR_PHY_ERR_CCK_TIMING);
2743 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2744 ahp->ah_stats.ast_ani_ofdmerrs +=
2745 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2746 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2748 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2749 ahp->ah_stats.ast_ani_cckerrs +=
2750 cckPhyErrCnt - aniState->cckPhyErrCount;
2751 aniState->cckPhyErrCount = cckPhyErrCnt;
2757 if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
2758 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
2759 aniState->ofdmTrigLow / 1000 &&
2760 aniState->cckPhyErrCount <= aniState->listenTime *
2761 aniState->cckTrigLow / 1000)
2762 ath9k_hw_ani_lower_immunity(ah);
2763 ath9k_ani_restart(ah);
2764 } else if (aniState->listenTime > ahp->ah_aniPeriod) {
2765 if (aniState->ofdmPhyErrCount > aniState->listenTime *
2766 aniState->ofdmTrigHigh / 1000) {
2767 ath9k_hw_ani_ofdm_err_trigger(ah);
2768 ath9k_ani_restart(ah);
2769 } else if (aniState->cckPhyErrCount >
2770 aniState->listenTime * aniState->cckTrigHigh /
2772 ath9k_hw_ani_cck_err_trigger(ah);
2773 ath9k_ani_restart(ah);
2778 #ifndef ATH_NF_PER_CHAN
2779 static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
2783 for (i = 0; i < NUM_NF_READINGS; i++) {
2784 ah->nfCalHist[i].currIndex = 0;
2785 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
2786 ah->nfCalHist[i].invalidNFcount =
2787 AR_PHY_CCA_FILTERWINDOW_LENGTH;
2788 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
2789 ah->nfCalHist[i].nfCalBuffer[j] =
2790 AR_PHY_CCA_MAX_GOOD_VALUE;
2797 static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2801 u32 gpio_shift, tmp;
2804 addr = AR_GPIO_OUTPUT_MUX3;
2806 addr = AR_GPIO_OUTPUT_MUX2;
2808 addr = AR_GPIO_OUTPUT_MUX1;
2810 gpio_shift = (gpio % 6) * 5;
2812 if (AR_SREV_9280_20_OR_LATER(ah)
2813 || (addr != AR_GPIO_OUTPUT_MUX1)) {
2814 REG_RMW(ah, addr, (type << gpio_shift),
2815 (0x1f << gpio_shift));
2817 tmp = REG_READ(ah, addr);
2818 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
2819 tmp &= ~(0x1f << gpio_shift);
2820 tmp |= (type << gpio_shift);
2821 REG_WRITE(ah, addr, tmp);
2825 static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2826 enum ath9k_gpio_output_mux_type
2832 static u32 MuxSignalConversionTable[] = {
2834 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2836 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2838 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2840 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2842 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2845 if ((halSignalType >= 0)
2846 && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2847 ah_signal_type = MuxSignalConversionTable[halSignalType];
2851 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2853 gpio_shift = 2 * gpio;
2857 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2858 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2863 static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio,
2866 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2871 static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2873 if (gpio >= ah->ah_caps.halNumGpioPins)
2876 if (AR_SREV_9280_10_OR_LATER(ah)) {
2878 (REG_READ(ah, AR_GPIO_IN_OUT),
2879 AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
2881 return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
2882 AR_GPIO_BIT(gpio)) != 0;
2886 static inline int ath9k_hw_post_attach(struct ath_hal *ah)
2890 if (!ath9k_hw_chip_test(ah)) {
2891 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2892 "%s: hardware self-test failed\n", __func__);
2896 ecode = ath9k_hw_rf_claim(ah);
2900 ecode = ath9k_hw_eeprom_attach(ah);
2903 ecode = ath9k_hw_rfattach(ah);
2907 if (!AR_SREV_9100(ah)) {
2908 ath9k_hw_ani_setup(ah);
2909 ath9k_hw_ani_attach(ah);
2914 static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
2915 struct ar5416_eeprom *pEepData,
2918 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
2920 switch (ah->ah_devid) {
2921 case AR9280_DEVID_PCI:
2922 if (reg == 0x7894) {
2923 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2924 "ini VAL: %x EEPROM: %x\n", value,
2925 (pBase->version & 0xff));
2927 if ((pBase->version & 0xff) > 0x0a) {
2928 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2931 value &= ~AR_AN_TOP2_PWDCLKIND;
2932 value |= AR_AN_TOP2_PWDCLKIND & (pBase->
2933 pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
2935 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2936 "PWDCLKIND Earlier Rev\n");
2939 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2940 "final ini VAL: %x\n", value);
2947 static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2949 struct ath_hal_5416 *ahp = AH5416(ah);
2950 struct hal_capabilities *pCap = &ah->ah_caps;
2951 u16 capField = 0, eeval;
2953 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
2955 ah->ah_currentRD = eeval;
2957 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
2958 ah->ah_currentRDExt = eeval;
2960 capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
2962 if (ah->ah_opmode != ATH9K_M_HOSTAP &&
2963 ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2964 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
2965 ah->ah_currentRD += 5;
2966 else if (ah->ah_currentRD == 0x41)
2967 ah->ah_currentRD = 0x43;
2968 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
2969 "%s: regdomain mapped to 0x%x\n", __func__,
2973 pCap->halWirelessModes = 0;
2974 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2976 if (eeval & AR5416_OPFLAGS_11A) {
2977 pCap->halWirelessModes |= ATH9K_MODE_SEL_11A |
2978 ((!ah->ah_config.ath_hal_htEnable
2979 || (eeval & AR5416_OPFLAGS_N_5G_HT20)) ? 0
2980 : (ATH9K_MODE_SEL_11NA_HT20 |
2981 ((eeval & AR5416_OPFLAGS_N_5G_HT40) ? 0
2982 : (ATH9K_MODE_SEL_11NA_HT40PLUS |
2983 ATH9K_MODE_SEL_11NA_HT40MINUS))));
2985 if (eeval & AR5416_OPFLAGS_11G) {
2986 pCap->halWirelessModes |=
2987 ATH9K_MODE_SEL_11B | ATH9K_MODE_SEL_11G |
2988 ((!ah->ah_config.ath_hal_htEnable
2989 || (eeval & AR5416_OPFLAGS_N_2G_HT20)) ? 0
2990 : (ATH9K_MODE_SEL_11NG_HT20 |
2991 ((eeval & AR5416_OPFLAGS_N_2G_HT40) ? 0
2992 : (ATH9K_MODE_SEL_11NG_HT40PLUS |
2993 ATH9K_MODE_SEL_11NG_HT40MINUS))));
2996 pCap->halTxChainMask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
2997 if ((ah->ah_isPciExpress)
2998 || (eeval & AR5416_OPFLAGS_11A)) {
2999 pCap->halRxChainMask =
3000 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3002 pCap->halRxChainMask =
3003 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3006 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3007 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3009 pCap->halLow2GhzChan = 2312;
3010 pCap->halHigh2GhzChan = 2732;
3012 pCap->halLow5GhzChan = 4920;
3013 pCap->halHigh5GhzChan = 6100;
3015 pCap->halCipherCkipSupport = false;
3016 pCap->halCipherTkipSupport = true;
3017 pCap->halCipherAesCcmSupport = true;
3019 pCap->halMicCkipSupport = false;
3020 pCap->halMicTkipSupport = true;
3021 pCap->halMicAesCcmSupport = true;
3023 pCap->halChanSpreadSupport = true;
3025 pCap->halHTSupport =
3026 ah->ah_config.ath_hal_htEnable ? true : false;
3027 pCap->halGTTSupport = true;
3028 pCap->halVEOLSupport = true;
3029 pCap->halBssIdMaskSupport = true;
3030 pCap->halMcastKeySrchSupport = false;
3032 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3033 pCap->halTotalQueues =
3034 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3036 pCap->halTotalQueues = ATH9K_NUM_TX_QUEUES;
3038 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3039 pCap->halKeyCacheSize =
3040 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3042 pCap->halKeyCacheSize = AR_KEYTABLE_SIZE;
3044 pCap->halFastCCSupport = true;
3045 pCap->halNumMRRetries = 4;
3046 pCap->halTxTrigLevelMax = MAX_TX_FIFO_THRESHOLD;
3048 if (AR_SREV_9280_10_OR_LATER(ah))
3049 pCap->halNumGpioPins = AR928X_NUM_GPIO;
3051 pCap->halNumGpioPins = AR_NUM_GPIO;
3053 if (AR_SREV_9280_10_OR_LATER(ah)) {
3054 pCap->halWowSupport = true;
3055 pCap->halWowMatchPatternExact = true;
3057 pCap->halWowSupport = false;
3058 pCap->halWowMatchPatternExact = false;
3061 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3062 pCap->halCSTSupport = true;
3063 pCap->halRtsAggrLimit = ATH_AMPDU_LIMIT_MAX;
3065 pCap->halRtsAggrLimit = (8 * 1024);
3068 pCap->halEnhancedPmSupport = true;
3070 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3071 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3072 ahp->ah_gpioSelect =
3073 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3075 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3077 ath9k_hw_setcapability(ah, HAL_CAP_RFSILENT, 1, true,
3079 pCap->halRfSilentSupport = true;
3082 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3083 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3084 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3085 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3086 (ah->ah_macVersion == AR_SREV_VERSION_9280))
3087 pCap->halAutoSleepSupport = false;
3089 pCap->halAutoSleepSupport = true;
3091 if (AR_SREV_9280(ah))
3092 pCap->hal4kbSplitTransSupport = false;
3094 pCap->hal4kbSplitTransSupport = true;
3096 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3098 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3099 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3100 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3101 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3104 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3105 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3108 pCap->halRegCap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3110 pCap->halNumAntCfg5GHz =
3111 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_5GHZ);
3112 pCap->halNumAntCfg2GHz =
3113 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_2GHZ);
3118 static void ar5416DisablePciePhy(struct ath_hal *ah)
3120 if (!AR_SREV_9100(ah))
3123 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3124 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3125 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3126 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3127 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3128 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3129 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3130 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3131 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3133 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3136 static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3138 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3140 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3141 AR_RTC_FORCE_WAKE_EN);
3142 if (!AR_SREV_9100(ah))
3143 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3145 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3150 static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3152 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3154 struct hal_capabilities *pCap = &ah->ah_caps;
3156 if (!pCap->halAutoSleepSupport) {
3157 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3158 AR_RTC_FORCE_WAKE_ON_INT);
3160 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3161 AR_RTC_FORCE_WAKE_EN);
3166 static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3173 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3174 AR_RTC_STATUS_SHUTDOWN) {
3175 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3180 if (AR_SREV_9100(ah))
3181 REG_SET_BIT(ah, AR_RTC_RESET,
3184 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3185 AR_RTC_FORCE_WAKE_EN);
3188 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3189 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3190 if (val == AR_RTC_STATUS_ON)
3193 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3194 AR_RTC_FORCE_WAKE_EN);
3197 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3198 "%s: Failed to wakeup in %uus\n",
3199 __func__, POWER_UP_TIME / 20);
3204 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3208 bool ath9k_hw_setpower(struct ath_hal *ah,
3209 enum ath9k_power_mode mode)
3211 struct ath_hal_5416 *ahp = AH5416(ah);
3212 static const char *modes[] = {
3218 int status = true, setChip = true;
3220 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3221 modes[ahp->ah_powerMode], modes[mode],
3222 setChip ? "set chip " : "");
3225 case ATH9K_PM_AWAKE:
3226 status = ath9k_hw_set_power_awake(ah, setChip);
3228 case ATH9K_PM_FULL_SLEEP:
3229 ath9k_set_power_sleep(ah, setChip);
3230 ahp->ah_chipFullSleep = true;
3232 case ATH9K_PM_NETWORK_SLEEP:
3233 ath9k_set_power_network_sleep(ah, setChip);
3236 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3237 "%s: unknown power mode %u\n", __func__, mode);
3240 ahp->ah_powerMode = mode;
3244 static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3245 struct ath_softc *sc,
3249 struct ath_hal_5416 *ahp;
3252 #ifndef CONFIG_SLOW_ANT_DIV
3257 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3263 ath9k_hw_set_defaults(ah);
3265 if (ah->ah_config.ath_hal_intrMitigation != 0)
3266 ahp->ah_intrMitigation = true;
3268 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3269 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3275 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3276 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3282 if (ah->ah_config.ath_hal_serializeRegMode == SER_REG_MODE_AUTO) {
3283 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3284 ah->ah_config.ath_hal_serializeRegMode =
3287 ah->ah_config.ath_hal_serializeRegMode =
3291 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3292 "%s: ath_hal_serializeRegMode is %d\n",
3293 __func__, ah->ah_config.ath_hal_serializeRegMode);
3295 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3296 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3297 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3298 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3299 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3300 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3301 "this driver\n", __func__,
3302 ah->ah_macVersion, ah->ah_macRev);
3303 ecode = -EOPNOTSUPP;
3307 if (AR_SREV_9100(ah)) {
3308 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3309 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3310 ah->ah_isPciExpress = false;
3312 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3314 if (AR_SREV_9160_10_OR_LATER(ah)) {
3315 if (AR_SREV_9280_10_OR_LATER(ah)) {
3316 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3317 ahp->ah_adcGainCalData.calData =
3318 &adc_gain_cal_single_sample;
3319 ahp->ah_adcDcCalData.calData =
3320 &adc_dc_cal_single_sample;
3321 ahp->ah_adcDcCalInitData.calData =
3324 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3325 ahp->ah_adcGainCalData.calData =
3326 &adc_gain_cal_multi_sample;
3327 ahp->ah_adcDcCalData.calData =
3328 &adc_dc_cal_multi_sample;
3329 ahp->ah_adcDcCalInitData.calData =
3333 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3336 if (AR_SREV_9160(ah)) {
3337 ah->ah_config.ath_hal_enableANI = 1;
3338 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3339 ATH9K_ANI_FIRSTEP_LEVEL);
3341 ahp->ah_ani_function = ATH9K_ANI_ALL;
3342 if (AR_SREV_9280_10_OR_LATER(ah)) {
3343 ahp->ah_ani_function &=
3344 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3348 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3349 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3350 ah->ah_macVersion, ah->ah_macRev);
3352 if (AR_SREV_9280_20_OR_LATER(ah)) {
3353 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3354 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3355 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3356 ARRAY_SIZE(ar9280Common_9280_2), 2);
3358 if (ah->ah_config.ath_hal_pcieClockReq) {
3359 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3360 ar9280PciePhy_clkreq_off_L1_9280,
3362 (ar9280PciePhy_clkreq_off_L1_9280),
3365 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3366 ar9280PciePhy_clkreq_always_on_L1_9280,
3368 (ar9280PciePhy_clkreq_always_on_L1_9280),
3371 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3372 ar9280Modes_fast_clock_9280_2,
3373 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3375 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3376 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3377 ARRAY_SIZE(ar9280Modes_9280), 6);
3378 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3379 ARRAY_SIZE(ar9280Common_9280), 2);
3380 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3381 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3382 ARRAY_SIZE(ar5416Modes_9160), 6);
3383 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3384 ARRAY_SIZE(ar5416Common_9160), 2);
3385 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3386 ARRAY_SIZE(ar5416Bank0_9160), 2);
3387 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3388 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3389 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3390 ARRAY_SIZE(ar5416Bank1_9160), 2);
3391 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3392 ARRAY_SIZE(ar5416Bank2_9160), 2);
3393 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3394 ARRAY_SIZE(ar5416Bank3_9160), 3);
3395 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3396 ARRAY_SIZE(ar5416Bank6_9160), 3);
3397 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3398 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3399 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3400 ARRAY_SIZE(ar5416Bank7_9160), 2);
3401 if (AR_SREV_9160_11(ah)) {
3402 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3403 ar5416Addac_91601_1,
3404 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3406 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3407 ARRAY_SIZE(ar5416Addac_9160), 2);
3409 } else if (AR_SREV_9100_OR_LATER(ah)) {
3410 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3411 ARRAY_SIZE(ar5416Modes_9100), 6);
3412 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3413 ARRAY_SIZE(ar5416Common_9100), 2);
3414 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3415 ARRAY_SIZE(ar5416Bank0_9100), 2);
3416 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3417 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3418 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3419 ARRAY_SIZE(ar5416Bank1_9100), 2);
3420 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3421 ARRAY_SIZE(ar5416Bank2_9100), 2);
3422 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3423 ARRAY_SIZE(ar5416Bank3_9100), 3);
3424 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3425 ARRAY_SIZE(ar5416Bank6_9100), 3);
3426 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3427 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3428 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3429 ARRAY_SIZE(ar5416Bank7_9100), 2);
3430 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3431 ARRAY_SIZE(ar5416Addac_9100), 2);
3433 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3434 ARRAY_SIZE(ar5416Modes), 6);
3435 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3436 ARRAY_SIZE(ar5416Common), 2);
3437 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3438 ARRAY_SIZE(ar5416Bank0), 2);
3439 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3440 ARRAY_SIZE(ar5416BB_RfGain), 3);
3441 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3442 ARRAY_SIZE(ar5416Bank1), 2);
3443 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3444 ARRAY_SIZE(ar5416Bank2), 2);
3445 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3446 ARRAY_SIZE(ar5416Bank3), 3);
3447 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3448 ARRAY_SIZE(ar5416Bank6), 3);
3449 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3450 ARRAY_SIZE(ar5416Bank6TPC), 3);
3451 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3452 ARRAY_SIZE(ar5416Bank7), 2);
3453 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3454 ARRAY_SIZE(ar5416Addac), 2);
3457 if (ah->ah_isPciExpress)
3458 ath9k_hw_configpcipowersave(ah, 0);
3460 ar5416DisablePciePhy(ah);
3462 ecode = ath9k_hw_post_attach(ah);
3466 #ifndef CONFIG_SLOW_ANT_DIV
3467 if (ah->ah_devid == AR9280_DEVID_PCI) {
3468 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3469 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3471 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3472 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3474 INI_RA(&ahp->ah_iniModes, i, j) =
3475 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3482 if (!ath9k_hw_fill_cap_info(ah)) {
3483 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3484 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3489 ecode = ath9k_hw_init_macaddr(ah);
3491 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3492 "%s: failed initializing mac address\n",
3497 if (AR_SREV_9285(ah))
3498 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3500 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3502 #ifndef ATH_NF_PER_CHAN
3504 ath9k_init_nfcal_hist_buffer(ah);
3511 ath9k_hw_detach((struct ath_hal *) ahp);
3517 void ath9k_hw_detach(struct ath_hal *ah)
3519 if (!AR_SREV_9100(ah))
3520 ath9k_hw_ani_detach(ah);
3521 ath9k_hw_rfdetach(ah);
3523 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3527 bool ath9k_get_channel_edges(struct ath_hal *ah,
3528 u16 flags, u16 *low,
3531 struct hal_capabilities *pCap = &ah->ah_caps;
3533 if (flags & CHANNEL_5GHZ) {
3534 *low = pCap->halLow5GhzChan;
3535 *high = pCap->halHigh5GhzChan;
3538 if ((flags & CHANNEL_2GHZ)) {
3539 *low = pCap->halLow2GhzChan;
3540 *high = pCap->halHigh2GhzChan;
3547 static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3556 u8 currPwr = pwrMin;
3557 u16 idxL = 0, idxR = 0;
3559 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3560 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3561 numIntercepts, &(idxL),
3565 if (idxL == numIntercepts - 1)
3566 idxL = (u16) (numIntercepts - 2);
3567 if (pPwrList[idxL] == pPwrList[idxR])
3570 k = (u16) (((currPwr -
3574 currPwr) * pVpdList[idxL]) /
3577 pRetVpdList[i] = (u8) k;
3585 ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3586 struct ath9k_channel *chan,
3587 struct cal_data_per_freq *pRawDataSet,
3591 int16_t *pMinCalPower,
3592 u16 *pPdGainBoundaries,
3598 u16 idxL = 0, idxR = 0, numPiers;
3599 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3600 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3601 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3602 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3603 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3604 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3606 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3607 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3608 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3611 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3613 int16_t minDelta = 0;
3614 struct chan_centers centers;
3616 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3618 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3619 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3623 match = ath9k_hw_get_lower_upper_index((u8)
3628 numPiers, &idxL, &idxR);
3631 for (i = 0; i < numXpdGains; i++) {
3632 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3633 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3634 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3639 AR5416_PD_GAIN_ICEPTS,
3643 for (i = 0; i < numXpdGains; i++) {
3644 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3645 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3646 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3647 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3649 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3652 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3653 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3656 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3658 AR5416_PD_GAIN_ICEPTS,
3660 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3662 AR5416_PD_GAIN_ICEPTS,
3665 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3667 (u8) (ath9k_hw_interpolate
3674 bChans[idxR], vpdTableL[i]
3681 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3684 for (i = 0; i < numXpdGains; i++) {
3685 if (i == (numXpdGains - 1))
3686 pPdGainBoundaries[i] =
3687 (u16) (maxPwrT4[i] / 2);
3689 pPdGainBoundaries[i] =
3690 (u16) ((maxPwrT4[i] +
3691 minPwrT4[i + 1]) / 4);
3693 pPdGainBoundaries[i] =
3694 min((u16) AR5416_MAX_RATE_POWER,
3695 pPdGainBoundaries[i]);
3697 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3698 minDelta = pPdGainBoundaries[0] - 23;
3699 pPdGainBoundaries[0] = 23;
3705 if (AR_SREV_9280_10_OR_LATER(ah))
3706 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3710 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3711 (minPwrT4[i] / 2)) -
3712 tPdGainOverlap + 1 + minDelta);
3714 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3715 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3717 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3718 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3720 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3725 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3726 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3728 maxIndex = (tgtIndex <
3729 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3731 while ((ss < maxIndex)
3732 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3733 pPDADCValues[k++] = vpdTableI[i][ss++];
3736 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3737 vpdTableI[i][sizeCurrVpdTable - 2]);
3738 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3740 if (tgtIndex > maxIndex) {
3741 while ((ss <= tgtIndex)
3742 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3743 tmpVal = (int16_t) ((vpdTableI[i]
3745 1] + (ss - maxIndex +
3747 pPDADCValues[k++] = (u8) ((tmpVal >
3748 255) ? 255 : tmpVal);
3754 while (i < AR5416_PD_GAINS_IN_MASK) {
3755 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3759 while (k < AR5416_NUM_PDADC_VALUES) {
3760 pPDADCValues[k] = pPDADCValues[k - 1];
3767 ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3768 struct ar5416_eeprom *pEepData,
3769 struct ath9k_channel *chan,
3770 int16_t *pTxPowerIndexOffset)
3772 struct cal_data_per_freq *pRawDataset;
3773 u8 *pCalBChans = NULL;
3774 u16 pdGainOverlap_t2;
3775 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3776 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3778 int16_t tMinCalPower;
3779 u16 numXpdGain, xpdMask;
3780 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3781 u32 reg32, regOffset, regChainOffset;
3783 struct ath_hal_5416 *ahp = AH5416(ah);
3785 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3786 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3788 if ((pEepData->baseEepHeader.
3789 version & AR5416_EEP_VER_MINOR_MASK) >=
3790 AR5416_EEP_MINOR_VER_2) {
3792 pEepData->modalHeader[modalIdx].pdGainOverlap;
3796 (REG_READ(ah, AR_PHY_TPCRG5),
3797 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3800 if (IS_CHAN_2GHZ(chan)) {
3801 pCalBChans = pEepData->calFreqPier2G;
3802 numPiers = AR5416_NUM_2G_CAL_PIERS;
3804 pCalBChans = pEepData->calFreqPier5G;
3805 numPiers = AR5416_NUM_5G_CAL_PIERS;
3810 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3811 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3812 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3814 xpdGainValues[numXpdGain] =
3815 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3820 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3821 (numXpdGain - 1) & 0x3);
3822 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3824 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3826 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3829 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3830 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3831 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3833 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3835 regChainOffset = i * 0x1000;
3836 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3837 if (IS_CHAN_2GHZ(chan))
3838 pRawDataset = pEepData->calPierData2G[i];
3840 pRawDataset = pEepData->calPierData5G[i];
3842 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3852 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3855 AR_PHY_TPCRG5 + regChainOffset,
3856 SM(pdGainOverlap_t2,
3857 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3858 | SM(gainBoundaries[0],
3859 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3860 | SM(gainBoundaries[1],
3861 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3862 | SM(gainBoundaries[2],
3863 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3864 | SM(gainBoundaries[3],
3865 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3869 AR_PHY_BASE + (672 << 2) + regChainOffset;
3870 for (j = 0; j < 32; j++) {
3872 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3873 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3874 8) | ((pdadcValues[4 * j + 2] &
3876 ((pdadcValues[4 * j + 3] & 0xFF) <<
3878 REG_WRITE(ah, regOffset, reg32);
3880 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3881 "PDADC (%d,%4x): %4.4x %8.8x\n",
3882 i, regChainOffset, regOffset,
3884 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3885 "PDADC: Chain %d | PDADC %3d Value %3d | "
3886 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3887 "PDADC %3d Value %3d |\n",
3888 i, 4 * j, pdadcValues[4 * j],
3889 4 * j + 1, pdadcValues[4 * j + 1],
3890 4 * j + 2, pdadcValues[4 * j + 2],
3892 pdadcValues[4 * j + 3]);
3898 *pTxPowerIndexOffset = 0;
3903 void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3905 struct ath_hal_5416 *ahp = AH5416(ah);
3908 if (ah->ah_isPciExpress != true)
3911 if (ah->ah_config.ath_hal_pciePowerSaveEnable == 2)
3917 if (AR_SREV_9280_20_OR_LATER(ah)) {
3918 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3919 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3920 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3923 } else if (AR_SREV_9280(ah)
3924 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3925 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3926 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3928 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3929 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3930 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3932 if (ah->ah_config.ath_hal_pcieClockReq)
3933 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3935 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3937 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3938 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3939 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3941 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3945 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3946 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3947 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3948 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3950 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3954 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3957 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3959 if (ah->ah_config.ath_hal_pcieWaen) {
3960 REG_WRITE(ah, AR_WA, ah->ah_config.ath_hal_pcieWaen);
3962 if (AR_SREV_9280(ah))
3963 REG_WRITE(ah, AR_WA, 0x0040073f);
3965 REG_WRITE(ah, AR_WA, 0x0000073f);
3970 ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3971 struct ath9k_channel *chan,
3972 struct cal_target_power_leg *powInfo,
3974 struct cal_target_power_leg *pNewPower,
3980 int matchIndex = -1, lowIndex = -1;
3982 struct chan_centers centers;
3984 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3985 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
3987 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
3988 IS_CHAN_2GHZ(chan))) {
3991 for (i = 0; (i < numChannels)
3992 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
3994 ath9k_hw_fbin2freq(powInfo[i].bChannel,
3995 IS_CHAN_2GHZ(chan))) {
3999 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4000 IS_CHAN_2GHZ(chan)))
4002 ath9k_hw_fbin2freq(powInfo[i - 1].
4010 if ((matchIndex == -1) && (lowIndex == -1))
4014 if (matchIndex != -1) {
4015 *pNewPower = powInfo[matchIndex];
4017 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4018 IS_CHAN_2GHZ(chan));
4019 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4020 IS_CHAN_2GHZ(chan));
4022 for (i = 0; i < numRates; i++) {
4023 pNewPower->tPow2x[i] =
4024 (u8) ath9k_hw_interpolate(freq, clo, chi,
4036 ath9k_hw_get_target_powers(struct ath_hal *ah,
4037 struct ath9k_channel *chan,
4038 struct cal_target_power_ht *powInfo,
4040 struct cal_target_power_ht *pNewPower,
4046 int matchIndex = -1, lowIndex = -1;
4048 struct chan_centers centers;
4050 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4051 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4054 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4057 for (i = 0; (i < numChannels)
4058 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4060 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4061 IS_CHAN_2GHZ(chan))) {
4066 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4067 IS_CHAN_2GHZ(chan)))
4069 ath9k_hw_fbin2freq(powInfo[i - 1].
4077 if ((matchIndex == -1) && (lowIndex == -1))
4081 if (matchIndex != -1) {
4082 *pNewPower = powInfo[matchIndex];
4084 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4085 IS_CHAN_2GHZ(chan));
4086 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4087 IS_CHAN_2GHZ(chan));
4089 for (i = 0; i < numRates; i++) {
4090 pNewPower->tPow2x[i] =
4091 (u8) ath9k_hw_interpolate(freq, clo, chi,
4103 ath9k_hw_get_max_edge_power(u16 freq,
4104 struct cal_ctl_edges *pRdEdgesPower,
4107 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4110 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4111 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4112 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4114 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4118 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4119 bChannel, is2GHz))) {
4120 if (ath9k_hw_fbin2freq
4121 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4122 && pRdEdgesPower[i - 1].flag) {
4124 pRdEdgesPower[i - 1].tPower;
4129 return twiceMaxEdgePower;
4133 ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4134 struct ar5416_eeprom *pEepData,
4135 struct ath9k_channel *chan,
4136 int16_t *ratesArray,
4138 u8 AntennaReduction,
4139 u8 twiceMaxRegulatoryPower,
4142 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4143 static const u16 tpScaleReductionTable[5] =
4144 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4147 int8_t twiceLargestAntenna;
4148 struct cal_ctl_data *rep;
4149 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4152 struct cal_target_power_leg targetPowerOfdmExt = {
4153 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4156 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4159 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4160 u16 ctlModesFor11a[] =
4161 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4162 u16 ctlModesFor11g[] =
4163 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4166 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4167 struct chan_centers centers;
4169 u8 twiceMinEdgePower;
4170 struct ath_hal_5416 *ahp = AH5416(ah);
4172 tx_chainmask = ahp->ah_txchainmask;
4174 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4176 twiceLargestAntenna = max(
4177 pEepData->modalHeader
4178 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4179 pEepData->modalHeader
4180 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4182 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4183 pEepData->modalHeader
4184 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4186 twiceLargestAntenna =
4187 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4189 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4191 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4192 maxRegAllowedPower -=
4193 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4196 scaledPower = min(powerLimit, maxRegAllowedPower);
4198 switch (ar5416_get_ntxchains(tx_chainmask)) {
4203 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4204 pwrDecreaseFor2Chain;
4208 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4209 pwrDecreaseFor3Chain;
4213 scaledPower = max(0, (int32_t) scaledPower);
4215 if (IS_CHAN_2GHZ(chan)) {
4217 ARRAY_SIZE(ctlModesFor11g) -
4218 SUB_NUM_CTL_MODES_AT_2G_40;
4219 pCtlMode = ctlModesFor11g;
4221 ath9k_hw_get_legacy_target_powers(ah, chan,
4224 AR5416_NUM_2G_CCK_TARGET_POWERS,
4227 ath9k_hw_get_legacy_target_powers(ah, chan,
4230 AR5416_NUM_2G_20_TARGET_POWERS,
4231 &targetPowerOfdm, 4,
4233 ath9k_hw_get_target_powers(ah, chan,
4234 pEepData->calTargetPower2GHT20,
4235 AR5416_NUM_2G_20_TARGET_POWERS,
4236 &targetPowerHt20, 8, false);
4238 if (IS_CHAN_HT40(chan)) {
4239 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4240 ath9k_hw_get_target_powers(ah, chan,
4242 calTargetPower2GHT40,
4243 AR5416_NUM_2G_40_TARGET_POWERS,
4244 &targetPowerHt40, 8,
4246 ath9k_hw_get_legacy_target_powers(ah, chan,
4249 AR5416_NUM_2G_CCK_TARGET_POWERS,
4252 ath9k_hw_get_legacy_target_powers(ah, chan,
4255 AR5416_NUM_2G_20_TARGET_POWERS,
4256 &targetPowerOfdmExt,
4262 ARRAY_SIZE(ctlModesFor11a) -
4263 SUB_NUM_CTL_MODES_AT_5G_40;
4264 pCtlMode = ctlModesFor11a;
4266 ath9k_hw_get_legacy_target_powers(ah, chan,
4269 AR5416_NUM_5G_20_TARGET_POWERS,
4270 &targetPowerOfdm, 4,
4272 ath9k_hw_get_target_powers(ah, chan,
4273 pEepData->calTargetPower5GHT20,
4274 AR5416_NUM_5G_20_TARGET_POWERS,
4275 &targetPowerHt20, 8, false);
4277 if (IS_CHAN_HT40(chan)) {
4278 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4279 ath9k_hw_get_target_powers(ah, chan,
4281 calTargetPower5GHT40,
4282 AR5416_NUM_5G_40_TARGET_POWERS,
4283 &targetPowerHt40, 8,
4285 ath9k_hw_get_legacy_target_powers(ah, chan,
4288 AR5416_NUM_5G_20_TARGET_POWERS,
4289 &targetPowerOfdmExt,
4294 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4295 bool isHt40CtlMode =
4296 (pCtlMode[ctlMode] == CTL_5GHT40)
4297 || (pCtlMode[ctlMode] == CTL_2GHT40);
4299 freq = centers.synth_center;
4300 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4301 freq = centers.ext_center;
4303 freq = centers.ctl_center;
4305 if (ar5416_get_eep_ver(ahp) == 14
4306 && ar5416_get_eep_rev(ahp) <= 2)
4307 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4309 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4310 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4311 "EXT_ADDITIVE %d\n",
4312 ctlMode, numCtlModes, isHt40CtlMode,
4313 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4315 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4317 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4318 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4319 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4321 i, cfgCtl, pCtlMode[ctlMode],
4322 pEepData->ctlIndex[i], chan->channel);
4324 if ((((cfgCtl & ~CTL_MODE_M) |
4325 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4326 pEepData->ctlIndex[i])
4328 (((cfgCtl & ~CTL_MODE_M) |
4329 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4331 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4332 rep = &(pEepData->ctlData[i]);
4335 ath9k_hw_get_max_edge_power(freq,
4338 [ar5416_get_ntxchains
4344 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4345 " MATCH-EE_IDX %d: ch %d is2 %d "
4346 "2xMinEdge %d chainmask %d chains %d\n",
4347 i, freq, IS_CHAN_2GHZ(chan),
4348 twiceMinEdgePower, tx_chainmask,
4349 ar5416_get_ntxchains
4351 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4353 min(twiceMaxEdgePower,
4363 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4365 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4366 " SEL-Min ctlMode %d pCtlMode %d "
4367 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4368 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4369 scaledPower, minCtlPower);
4371 switch (pCtlMode[ctlMode]) {
4373 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4375 targetPowerCck.tPow2x[i] =
4376 min(targetPowerCck.tPow2x[i],
4382 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4384 targetPowerOfdm.tPow2x[i] =
4385 min(targetPowerOfdm.tPow2x[i],
4391 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4393 targetPowerHt20.tPow2x[i] =
4394 min(targetPowerHt20.tPow2x[i],
4399 targetPowerCckExt.tPow2x[0] =
4400 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4404 targetPowerOfdmExt.tPow2x[0] =
4405 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4409 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4411 targetPowerHt40.tPow2x[i] =
4412 min(targetPowerHt40.tPow2x[i],
4421 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4422 ratesArray[rate18mb] = ratesArray[rate24mb] =
4423 targetPowerOfdm.tPow2x[0];
4424 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4425 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4426 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4427 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4429 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4430 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4432 if (IS_CHAN_2GHZ(chan)) {
4433 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4434 ratesArray[rate2s] = ratesArray[rate2l] =
4435 targetPowerCck.tPow2x[1];
4436 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4437 targetPowerCck.tPow2x[2];
4439 ratesArray[rate11s] = ratesArray[rate11l] =
4440 targetPowerCck.tPow2x[3];
4443 if (IS_CHAN_HT40(chan)) {
4444 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4445 ratesArray[rateHt40_0 + i] =
4446 targetPowerHt40.tPow2x[i];
4448 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4449 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4450 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4451 if (IS_CHAN_2GHZ(chan)) {
4452 ratesArray[rateExtCck] =
4453 targetPowerCckExt.tPow2x[0];
4460 ath9k_hw_set_txpower(struct ath_hal *ah,
4461 struct ar5416_eeprom *pEepData,
4462 struct ath9k_channel *chan,
4464 u8 twiceAntennaReduction,
4465 u8 twiceMaxRegulatoryPower,
4468 struct modal_eep_header *pModal =
4469 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4470 int16_t ratesArray[Ar5416RateSize];
4471 int16_t txPowerIndexOffset = 0;
4472 u8 ht40PowerIncForPdadc = 2;
4475 memset(ratesArray, 0, sizeof(ratesArray));
4477 if ((pEepData->baseEepHeader.
4478 version & AR5416_EEP_VER_MINOR_MASK) >=
4479 AR5416_EEP_MINOR_VER_2) {
4480 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4483 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4484 &ratesArray[0], cfgCtl,
4485 twiceAntennaReduction,
4486 twiceMaxRegulatoryPower,
4488 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4489 "ath9k_hw_set_txpower: unable to set "
4490 "tx power per rate table\n");
4494 if (!ath9k_hw_set_power_cal_table
4495 (ah, pEepData, chan, &txPowerIndexOffset)) {
4496 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4497 "ath9k_hw_set_txpower: unable to set power table\n");
4501 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4503 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4504 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4505 ratesArray[i] = AR5416_MAX_RATE_POWER;
4508 if (AR_SREV_9280_10_OR_LATER(ah)) {
4509 for (i = 0; i < Ar5416RateSize; i++)
4510 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4513 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4514 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4515 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4516 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4517 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4519 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4520 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4521 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4522 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4523 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4526 if (IS_CHAN_2GHZ(chan)) {
4527 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4528 ATH9K_POW_SM(ratesArray[rate2s], 24)
4529 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4530 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4531 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4533 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4534 ATH9K_POW_SM(ratesArray[rate11s], 24)
4535 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4536 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4537 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4541 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4542 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4543 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4544 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4545 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4547 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4548 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4549 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4550 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4551 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4554 if (IS_CHAN_HT40(chan)) {
4555 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4556 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4557 ht40PowerIncForPdadc, 24)
4558 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4559 ht40PowerIncForPdadc, 16)
4560 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4561 ht40PowerIncForPdadc, 8)
4562 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4563 ht40PowerIncForPdadc, 0)
4565 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4566 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4567 ht40PowerIncForPdadc, 24)
4568 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4569 ht40PowerIncForPdadc, 16)
4570 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4571 ht40PowerIncForPdadc, 8)
4572 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4573 ht40PowerIncForPdadc, 0)
4576 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4577 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4578 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4579 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4580 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4584 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4585 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4586 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4590 if (IS_CHAN_HT40(chan))
4592 else if (IS_CHAN_HT20(chan))
4595 if (AR_SREV_9280_10_OR_LATER(ah))
4596 ah->ah_maxPowerLevel =
4597 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4599 ah->ah_maxPowerLevel = ratesArray[i];
4604 static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4609 u32 coef_exp, coef_man;
4611 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4612 if ((coef_scaled >> coef_exp) & 0x1)
4615 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4617 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4619 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4620 *coef_exponent = coef_exp - 16;
4624 ath9k_hw_set_delta_slope(struct ath_hal *ah,
4625 struct ath9k_channel *chan)
4627 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4628 u32 clockMhzScaled = 0x64000000;
4629 struct chan_centers centers;
4631 if (IS_CHAN_HALF_RATE(chan))
4632 clockMhzScaled = clockMhzScaled >> 1;
4633 else if (IS_CHAN_QUARTER_RATE(chan))
4634 clockMhzScaled = clockMhzScaled >> 2;
4636 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4637 coef_scaled = clockMhzScaled / centers.synth_center;
4639 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4642 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4643 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4644 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4645 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4647 coef_scaled = (9 * coef_scaled) / 10;
4649 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4652 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4653 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4654 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4655 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4658 static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4659 struct ath9k_channel *chan)
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, chan, ¢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)) {
4805 /* workaround for gcc bug #37014 */
4806 volatile int tmp = abs(cur_vit_mask - bin);
4812 if (cur_vit_mask < 0)
4813 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4815 mask_p[cur_vit_mask / 100] = mask_amt;
4817 cur_vit_mask -= 100;
4820 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4821 | (mask_m[48] << 26) | (mask_m[49] << 24)
4822 | (mask_m[50] << 22) | (mask_m[51] << 20)
4823 | (mask_m[52] << 18) | (mask_m[53] << 16)
4824 | (mask_m[54] << 14) | (mask_m[55] << 12)
4825 | (mask_m[56] << 10) | (mask_m[57] << 8)
4826 | (mask_m[58] << 6) | (mask_m[59] << 4)
4827 | (mask_m[60] << 2) | (mask_m[61] << 0);
4828 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4829 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4831 tmp_mask = (mask_m[31] << 28)
4832 | (mask_m[32] << 26) | (mask_m[33] << 24)
4833 | (mask_m[34] << 22) | (mask_m[35] << 20)
4834 | (mask_m[36] << 18) | (mask_m[37] << 16)
4835 | (mask_m[48] << 14) | (mask_m[39] << 12)
4836 | (mask_m[40] << 10) | (mask_m[41] << 8)
4837 | (mask_m[42] << 6) | (mask_m[43] << 4)
4838 | (mask_m[44] << 2) | (mask_m[45] << 0);
4839 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4840 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4842 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4843 | (mask_m[18] << 26) | (mask_m[18] << 24)
4844 | (mask_m[20] << 22) | (mask_m[20] << 20)
4845 | (mask_m[22] << 18) | (mask_m[22] << 16)
4846 | (mask_m[24] << 14) | (mask_m[24] << 12)
4847 | (mask_m[25] << 10) | (mask_m[26] << 8)
4848 | (mask_m[27] << 6) | (mask_m[28] << 4)
4849 | (mask_m[29] << 2) | (mask_m[30] << 0);
4850 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4851 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4853 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4854 | (mask_m[2] << 26) | (mask_m[3] << 24)
4855 | (mask_m[4] << 22) | (mask_m[5] << 20)
4856 | (mask_m[6] << 18) | (mask_m[7] << 16)
4857 | (mask_m[8] << 14) | (mask_m[9] << 12)
4858 | (mask_m[10] << 10) | (mask_m[11] << 8)
4859 | (mask_m[12] << 6) | (mask_m[13] << 4)
4860 | (mask_m[14] << 2) | (mask_m[15] << 0);
4861 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4862 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4864 tmp_mask = (mask_p[15] << 28)
4865 | (mask_p[14] << 26) | (mask_p[13] << 24)
4866 | (mask_p[12] << 22) | (mask_p[11] << 20)
4867 | (mask_p[10] << 18) | (mask_p[9] << 16)
4868 | (mask_p[8] << 14) | (mask_p[7] << 12)
4869 | (mask_p[6] << 10) | (mask_p[5] << 8)
4870 | (mask_p[4] << 6) | (mask_p[3] << 4)
4871 | (mask_p[2] << 2) | (mask_p[1] << 0);
4872 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4873 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4875 tmp_mask = (mask_p[30] << 28)
4876 | (mask_p[29] << 26) | (mask_p[28] << 24)
4877 | (mask_p[27] << 22) | (mask_p[26] << 20)
4878 | (mask_p[25] << 18) | (mask_p[24] << 16)
4879 | (mask_p[23] << 14) | (mask_p[22] << 12)
4880 | (mask_p[21] << 10) | (mask_p[20] << 8)
4881 | (mask_p[19] << 6) | (mask_p[18] << 4)
4882 | (mask_p[17] << 2) | (mask_p[16] << 0);
4883 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4884 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4886 tmp_mask = (mask_p[45] << 28)
4887 | (mask_p[44] << 26) | (mask_p[43] << 24)
4888 | (mask_p[42] << 22) | (mask_p[41] << 20)
4889 | (mask_p[40] << 18) | (mask_p[39] << 16)
4890 | (mask_p[38] << 14) | (mask_p[37] << 12)
4891 | (mask_p[36] << 10) | (mask_p[35] << 8)
4892 | (mask_p[34] << 6) | (mask_p[33] << 4)
4893 | (mask_p[32] << 2) | (mask_p[31] << 0);
4894 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4895 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4897 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4898 | (mask_p[59] << 26) | (mask_p[58] << 24)
4899 | (mask_p[57] << 22) | (mask_p[56] << 20)
4900 | (mask_p[55] << 18) | (mask_p[54] << 16)
4901 | (mask_p[53] << 14) | (mask_p[52] << 12)
4902 | (mask_p[51] << 10) | (mask_p[50] << 8)
4903 | (mask_p[49] << 6) | (mask_p[48] << 4)
4904 | (mask_p[47] << 2) | (mask_p[46] << 0);
4905 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4906 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4909 static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4910 struct ath9k_channel *chan)
4912 int bb_spur = AR_NO_SPUR;
4915 int spur_delta_phase;
4917 int upper, lower, cur_vit_mask;
4920 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4921 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4923 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4924 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4926 int inc[4] = { 0, 100, 0, 0 };
4933 bool is2GHz = IS_CHAN_2GHZ(chan);
4935 memset(&mask_m, 0, sizeof(int8_t) * 123);
4936 memset(&mask_p, 0, sizeof(int8_t) * 123);
4938 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4939 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4940 if (AR_NO_SPUR == cur_bb_spur)
4942 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4943 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4944 bb_spur = cur_bb_spur;
4949 if (AR_NO_SPUR == bb_spur)
4954 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4955 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4956 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4957 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4958 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4960 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4962 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4963 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4964 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4965 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4966 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4967 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4969 spur_delta_phase = ((bb_spur * 524288) / 100) &
4970 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4972 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4973 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4975 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4976 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4977 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4978 REG_WRITE(ah, AR_PHY_TIMING11, new);
4984 for (i = 0; i < 4; i++) {
4988 for (bp = 0; bp < 30; bp++) {
4989 if ((cur_bin > lower) && (cur_bin < upper)) {
4990 pilot_mask = pilot_mask | 0x1 << bp;
4991 chan_mask = chan_mask | 0x1 << bp;
4996 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4997 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5000 cur_vit_mask = 6100;
5004 for (i = 0; i < 123; i++) {
5005 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5006 if ((abs(cur_vit_mask - bin)) < 75)
5010 if (cur_vit_mask < 0)
5011 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5013 mask_p[cur_vit_mask / 100] = mask_amt;
5015 cur_vit_mask -= 100;
5018 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5019 | (mask_m[48] << 26) | (mask_m[49] << 24)
5020 | (mask_m[50] << 22) | (mask_m[51] << 20)
5021 | (mask_m[52] << 18) | (mask_m[53] << 16)
5022 | (mask_m[54] << 14) | (mask_m[55] << 12)
5023 | (mask_m[56] << 10) | (mask_m[57] << 8)
5024 | (mask_m[58] << 6) | (mask_m[59] << 4)
5025 | (mask_m[60] << 2) | (mask_m[61] << 0);
5026 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5027 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5029 tmp_mask = (mask_m[31] << 28)
5030 | (mask_m[32] << 26) | (mask_m[33] << 24)
5031 | (mask_m[34] << 22) | (mask_m[35] << 20)
5032 | (mask_m[36] << 18) | (mask_m[37] << 16)
5033 | (mask_m[48] << 14) | (mask_m[39] << 12)
5034 | (mask_m[40] << 10) | (mask_m[41] << 8)
5035 | (mask_m[42] << 6) | (mask_m[43] << 4)
5036 | (mask_m[44] << 2) | (mask_m[45] << 0);
5037 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5038 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5040 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5041 | (mask_m[18] << 26) | (mask_m[18] << 24)
5042 | (mask_m[20] << 22) | (mask_m[20] << 20)
5043 | (mask_m[22] << 18) | (mask_m[22] << 16)
5044 | (mask_m[24] << 14) | (mask_m[24] << 12)
5045 | (mask_m[25] << 10) | (mask_m[26] << 8)
5046 | (mask_m[27] << 6) | (mask_m[28] << 4)
5047 | (mask_m[29] << 2) | (mask_m[30] << 0);
5048 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5049 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5051 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5052 | (mask_m[2] << 26) | (mask_m[3] << 24)
5053 | (mask_m[4] << 22) | (mask_m[5] << 20)
5054 | (mask_m[6] << 18) | (mask_m[7] << 16)
5055 | (mask_m[8] << 14) | (mask_m[9] << 12)
5056 | (mask_m[10] << 10) | (mask_m[11] << 8)
5057 | (mask_m[12] << 6) | (mask_m[13] << 4)
5058 | (mask_m[14] << 2) | (mask_m[15] << 0);
5059 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5060 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5062 tmp_mask = (mask_p[15] << 28)
5063 | (mask_p[14] << 26) | (mask_p[13] << 24)
5064 | (mask_p[12] << 22) | (mask_p[11] << 20)
5065 | (mask_p[10] << 18) | (mask_p[9] << 16)
5066 | (mask_p[8] << 14) | (mask_p[7] << 12)
5067 | (mask_p[6] << 10) | (mask_p[5] << 8)
5068 | (mask_p[4] << 6) | (mask_p[3] << 4)
5069 | (mask_p[2] << 2) | (mask_p[1] << 0);
5070 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5071 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5073 tmp_mask = (mask_p[30] << 28)
5074 | (mask_p[29] << 26) | (mask_p[28] << 24)
5075 | (mask_p[27] << 22) | (mask_p[26] << 20)
5076 | (mask_p[25] << 18) | (mask_p[24] << 16)
5077 | (mask_p[23] << 14) | (mask_p[22] << 12)
5078 | (mask_p[21] << 10) | (mask_p[20] << 8)
5079 | (mask_p[19] << 6) | (mask_p[18] << 4)
5080 | (mask_p[17] << 2) | (mask_p[16] << 0);
5081 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5082 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5084 tmp_mask = (mask_p[45] << 28)
5085 | (mask_p[44] << 26) | (mask_p[43] << 24)
5086 | (mask_p[42] << 22) | (mask_p[41] << 20)
5087 | (mask_p[40] << 18) | (mask_p[39] << 16)
5088 | (mask_p[38] << 14) | (mask_p[37] << 12)
5089 | (mask_p[36] << 10) | (mask_p[35] << 8)
5090 | (mask_p[34] << 6) | (mask_p[33] << 4)
5091 | (mask_p[32] << 2) | (mask_p[31] << 0);
5092 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5093 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5095 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5096 | (mask_p[59] << 26) | (mask_p[58] << 24)
5097 | (mask_p[57] << 22) | (mask_p[56] << 20)
5098 | (mask_p[55] << 18) | (mask_p[54] << 16)
5099 | (mask_p[53] << 14) | (mask_p[52] << 12)
5100 | (mask_p[51] << 10) | (mask_p[50] << 8)
5101 | (mask_p[49] << 6) | (mask_p[48] << 4)
5102 | (mask_p[47] << 2) | (mask_p[46] << 0);
5103 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5104 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5107 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5109 struct ath_hal_5416 *ahp = AH5416(ah);
5110 int rx_chainmask, tx_chainmask;
5112 rx_chainmask = ahp->ah_rxchainmask;
5113 tx_chainmask = ahp->ah_txchainmask;
5115 switch (rx_chainmask) {
5117 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5118 AR_PHY_SWAP_ALT_CHAIN);
5120 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5121 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5122 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5127 if (!AR_SREV_9280(ah))
5130 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5131 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5137 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5138 if (tx_chainmask == 0x5) {
5139 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5140 AR_PHY_SWAP_ALT_CHAIN);
5142 if (AR_SREV_9100(ah))
5143 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5144 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5147 static void ath9k_hw_set_addac(struct ath_hal *ah,
5148 struct ath9k_channel *chan)
5150 struct modal_eep_header *pModal;
5151 struct ath_hal_5416 *ahp = AH5416(ah);
5152 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5155 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5158 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5161 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5163 if (pModal->xpaBiasLvl != 0xff) {
5164 biaslevel = pModal->xpaBiasLvl;
5167 u16 resetFreqBin, freqBin, freqCount = 0;
5168 struct chan_centers centers;
5170 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5173 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5174 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5175 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5179 while (freqCount < 3) {
5180 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5183 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5184 if (resetFreqBin >= freqBin) {
5187 xpaBiasLvlFreq[freqCount]
5196 if (IS_CHAN_2GHZ(chan)) {
5197 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5198 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5201 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5202 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5207 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5209 if (ah->ah_curchan != NULL)
5211 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5213 return clks / CLOCK_RATE[WIRELESS_MODE_11b];
5216 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5218 struct ath9k_channel *chan = ah->ah_curchan;
5220 if (chan && IS_CHAN_HT40(chan))
5221 return ath9k_hw_mac_usec(ah, clks) / 2;
5223 return ath9k_hw_mac_usec(ah, clks);
5226 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5228 if (ah->ah_curchan != NULL)
5229 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5232 return usecs * CLOCK_RATE[WIRELESS_MODE_11b];
5235 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5237 struct ath9k_channel *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, u32 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 = (u32) -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, u32 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 = (u32) -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 = (u32) -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, u32 us)
5297 struct ath_hal_5416 *ahp = AH5416(ah);
5299 if (us < ATH9K_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 = (u32) -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 != (u32) -1)
5321 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5322 if (ahp->ah_acktimeout != (u32) -1)
5323 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5324 if (ahp->ah_ctstimeout != (u32) -1)
5325 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5326 if (ahp->ah_globaltxtimeout != (u32) -1)
5327 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5331 ath9k_hw_process_ini(struct ath_hal *ah,
5332 struct ath9k_channel *chan,
5333 enum ath9k_ht_macmode macmode)
5335 int i, regWrites = 0;
5336 struct ath_hal_5416 *ahp = AH5416(ah);
5337 u32 modesIndex, freqIndex;
5340 switch (chan->chanmode) {
5342 case CHANNEL_A_HT20:
5346 case CHANNEL_A_HT40PLUS:
5347 case CHANNEL_A_HT40MINUS:
5352 case CHANNEL_G_HT20:
5357 case CHANNEL_G_HT40PLUS:
5358 case CHANNEL_G_HT40MINUS:
5367 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5369 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5371 ath9k_hw_set_addac(ah, chan);
5373 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5374 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5376 struct ar5416IniArray temp;
5378 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5379 ahp->ah_iniAddac.ia_columns;
5381 memcpy(ahp->ah_addac5416_21,
5382 ahp->ah_iniAddac.ia_array, addacSize);
5384 (ahp->ah_addac5416_21)[31 *
5385 ahp->ah_iniAddac.ia_columns + 1] = 0;
5387 temp.ia_array = ahp->ah_addac5416_21;
5388 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5389 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5390 REG_WRITE_ARRAY(&temp, 1, regWrites);
5392 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5394 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5395 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5396 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5398 #ifdef CONFIG_SLOW_ANT_DIV
5399 if (ah->ah_devid == AR9280_DEVID_PCI)
5400 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5404 REG_WRITE(ah, reg, val);
5406 if (reg >= 0x7800 && reg < 0x78a0
5407 && ah->ah_config.ath_hal_analogShiftReg) {
5411 DO_DELAY(regWrites);
5414 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5415 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5416 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5418 REG_WRITE(ah, reg, val);
5420 if (reg >= 0x7800 && reg < 0x78a0
5421 && ah->ah_config.ath_hal_analogShiftReg) {
5425 DO_DELAY(regWrites);
5428 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5430 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5431 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5435 ath9k_hw_override_ini(ah, chan);
5436 ath9k_hw_set_regs(ah, chan, macmode);
5437 ath9k_hw_init_chain_masks(ah);
5439 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5440 ath9k_regd_get_ctl(ah, chan),
5441 ath9k_regd_get_antenna_allowed(ah,
5443 chan->maxRegTxPower * 2,
5444 min((u32) MAX_RATE_POWER,
5445 (u32) ah->ah_powerLimit));
5447 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5448 "%s: error init'ing transmit power\n", __func__);
5452 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5453 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5454 "%s: ar5416SetRfRegs failed\n", __func__);
5461 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5462 struct hal_cal_list *currCal)
5464 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5465 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5466 currCal->calData->calCountMax);
5468 switch (currCal->calData->calType) {
5469 case IQ_MISMATCH_CAL:
5470 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5471 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5472 "%s: starting IQ Mismatch Calibration\n",
5476 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5477 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5478 "%s: starting ADC Gain Calibration\n", __func__);
5481 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5482 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5483 "%s: starting ADC DC Calibration\n", __func__);
5485 case ADC_DC_INIT_CAL:
5486 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5487 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5488 "%s: starting Init ADC DC Calibration\n",
5493 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5494 AR_PHY_TIMING_CTRL4_DO_CAL);
5497 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5498 struct hal_cal_list *currCal)
5500 struct ath_hal_5416 *ahp = AH5416(ah);
5503 ath9k_hw_setup_calibration(ah, currCal);
5505 currCal->calState = CAL_RUNNING;
5507 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5508 ahp->ah_Meas0.sign[i] = 0;
5509 ahp->ah_Meas1.sign[i] = 0;
5510 ahp->ah_Meas2.sign[i] = 0;
5511 ahp->ah_Meas3.sign[i] = 0;
5514 ahp->ah_CalSamples = 0;
5518 ath9k_hw_per_calibration(struct ath_hal *ah,
5519 struct ath9k_channel *ichan,
5521 struct hal_cal_list *currCal,
5524 struct ath_hal_5416 *ahp = AH5416(ah);
5528 if (currCal->calState == CAL_RUNNING) {
5530 AR_PHY_TIMING_CTRL4(0)) &
5531 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5533 currCal->calData->calCollect(ah);
5535 ahp->ah_CalSamples++;
5537 if (ahp->ah_CalSamples >=
5538 currCal->calData->calNumSamples) {
5539 int i, numChains = 0;
5540 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5541 if (rxchainmask & (1 << i))
5545 currCal->calData->calPostProc(ah,
5549 currCal->calData->calType;
5550 currCal->calState = CAL_DONE;
5553 ath9k_hw_setup_calibration(ah, currCal);
5556 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5557 ath9k_hw_reset_calibration(ah, currCal);
5561 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5564 struct ath_hal_5416 *ahp = AH5416(ah);
5565 struct ath9k_channel ichan;
5567 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5568 const struct hal_percal_data *calData = currCal->calData;
5571 if (currCal == NULL)
5576 for (i = 0; i < init_cal_count; i++) {
5577 ath9k_hw_reset_calibration(ah, currCal);
5579 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5580 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5581 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5582 "%s: Cal %d failed to complete in 100ms.\n",
5583 __func__, calData->calType);
5585 ahp->ah_cal_list = ahp->ah_cal_list_last =
5586 ahp->ah_cal_list_curr = NULL;
5590 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5591 currCal, &isCalDone);
5593 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5594 "%s: Not able to run Init Cal %d.\n",
5595 __func__, calData->calType);
5597 if (currCal->calNext) {
5598 currCal = currCal->calNext;
5599 calData = currCal->calData;
5603 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5608 ath9k_hw_channel_change(struct ath_hal *ah,
5609 struct ath9k_channel *chan,
5610 enum ath9k_ht_macmode macmode)
5612 u32 synthDelay, qnum;
5613 struct ath_hal_5416 *ahp = AH5416(ah);
5615 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5616 if (ath9k_hw_numtxpending(ah, qnum)) {
5617 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5618 "%s: Transmit frames pending on queue %d\n",
5624 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5625 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5626 AR_PHY_RFBUS_GRANT_EN)) {
5627 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5628 "%s: Could not kill baseband RX\n", __func__);
5632 ath9k_hw_set_regs(ah, chan, macmode);
5634 if (AR_SREV_9280_10_OR_LATER(ah)) {
5635 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5636 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5637 "%s: failed to set channel\n", __func__);
5641 if (!(ath9k_hw_set_channel(ah, chan))) {
5642 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5643 "%s: failed to set channel\n", __func__);
5648 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5649 ath9k_regd_get_ctl(ah, chan),
5650 ath9k_regd_get_antenna_allowed(ah, chan),
5651 chan->maxRegTxPower * 2,
5652 min((u32) MAX_RATE_POWER,
5653 (u32) ah->ah_powerLimit)) != 0) {
5654 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5655 "%s: error init'ing transmit power\n", __func__);
5659 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5660 if (IS_CHAN_CCK(chan))
5661 synthDelay = (4 * synthDelay) / 22;
5665 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5667 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5669 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5670 ath9k_hw_set_delta_slope(ah, chan);
5672 if (AR_SREV_9280_10_OR_LATER(ah))
5673 ath9k_hw_9280_spur_mitigate(ah, chan);
5675 ath9k_hw_spur_mitigate(ah, chan);
5677 if (!chan->oneTimeCalsDone)
5678 chan->oneTimeCalsDone = true;
5683 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5684 struct ath9k_channel *chan)
5686 struct ath_hal_5416 *ahp = AH5416(ah);
5688 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5691 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5694 ahp->ah_chipFullSleep = false;
5696 ath9k_hw_init_pll(ah, chan);
5698 ath9k_hw_set_rfmode(ah, chan);
5703 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5707 regval = REG_READ(ah, AR_AHB_MODE);
5708 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5710 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5711 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5713 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5715 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5716 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5718 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5720 if (AR_SREV_9285(ah)) {
5721 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5722 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5724 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5725 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5729 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5731 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5732 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5733 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5734 "%s: dma failed to stop in 10ms\n"
5735 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5737 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5744 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5746 REG_CLR_BIT(ah, AR_DIAG_SW,
5747 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5749 ath9k_enable_mib_counters(ah);
5751 ath9k_ani_reset(ah);
5754 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5756 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5758 ath9k_hw_disable_mib_counters(ah);
5761 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5762 struct ath9k_channel *chan,
5763 enum hal_cal_types calType)
5765 struct ath_hal_5416 *ahp = AH5416(ah);
5766 bool retval = false;
5768 switch (calType & ahp->ah_suppCals) {
5769 case IQ_MISMATCH_CAL:
5770 if (!IS_CHAN_B(chan))
5775 if (!IS_CHAN_B(chan)
5776 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5784 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5785 struct ath9k_channel *chan)
5787 struct ath_hal_5416 *ahp = AH5416(ah);
5788 struct ath9k_channel *ichan =
5789 ath9k_regd_check_channel(ah, chan);
5791 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5792 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5793 AR_PHY_AGC_CONTROL_CAL);
5796 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5797 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5798 "%s: offset calibration failed to complete in 1ms; "
5799 "noisy environment?\n", __func__);
5803 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5804 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5805 AR_PHY_AGC_CONTROL_NF);
5807 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5810 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5811 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5812 INIT_CAL(&ahp->ah_adcGainCalData);
5813 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5814 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5815 "%s: enabling ADC Gain Calibration.\n",
5818 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5819 INIT_CAL(&ahp->ah_adcDcCalData);
5820 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5821 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5822 "%s: enabling ADC DC Calibration.\n",
5825 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5826 INIT_CAL(&ahp->ah_iqCalData);
5827 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5828 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5829 "%s: enabling IQ Calibration.\n",
5833 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5835 if (ahp->ah_cal_list_curr)
5836 ath9k_hw_reset_calibration(ah,
5837 ahp->ah_cal_list_curr);
5840 ichan->CalValid = 0;
5846 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5847 struct ath9k_channel *chan,
5848 enum ath9k_ht_macmode macmode,
5849 u8 txchainmask, u8 rxchainmask,
5850 enum ath9k_ht_extprotspacing extprotspacing,
5851 bool bChannelChange,
5854 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5856 struct ath_hal_5416 *ahp = AH5416(ah);
5857 struct ath9k_channel *curchan = ah->ah_curchan;
5861 int i, rx_chainmask;
5863 ahp->ah_extprotspacing = extprotspacing;
5864 ahp->ah_txchainmask = txchainmask;
5865 ahp->ah_rxchainmask = rxchainmask;
5867 if (AR_SREV_9280(ah)) {
5868 ahp->ah_txchainmask &= 0x3;
5869 ahp->ah_rxchainmask &= 0x3;
5872 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5873 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5874 "%s: invalid channel %u/0x%x; no mapping\n",
5875 __func__, chan->channel, chan->channelFlags);
5879 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5883 ath9k_hw_getnf(ah, curchan);
5885 if (bChannelChange &&
5886 (ahp->ah_chipFullSleep != true) &&
5887 (ah->ah_curchan != NULL) &&
5888 (chan->channel != ah->ah_curchan->channel) &&
5889 ((chan->channelFlags & CHANNEL_ALL) ==
5890 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5891 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5892 !IS_CHAN_A_5MHZ_SPACED(ah->
5895 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5896 ath9k_hw_loadnf(ah, ah->ah_curchan);
5897 ath9k_hw_start_nfcal(ah);
5902 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5903 if (saveDefAntenna == 0)
5906 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5908 saveLedState = REG_READ(ah, AR_CFG_LED) &
5909 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5910 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5912 ath9k_hw_mark_phy_inactive(ah);
5914 if (!ath9k_hw_chip_reset(ah, chan)) {
5915 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5920 if (AR_SREV_9280(ah)) {
5921 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5922 AR_GPIO_JTAG_DISABLE);
5924 if (ah->ah_caps.halWirelessModes & ATH9K_MODE_SEL_11A) {
5925 if (IS_CHAN_5GHZ(chan))
5926 ath9k_hw_set_gpio(ah, 9, 0);
5928 ath9k_hw_set_gpio(ah, 9, 1);
5930 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5933 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5937 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5938 ath9k_hw_set_delta_slope(ah, chan);
5940 if (AR_SREV_9280_10_OR_LATER(ah))
5941 ath9k_hw_9280_spur_mitigate(ah, chan);
5943 ath9k_hw_spur_mitigate(ah, chan);
5945 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5946 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5947 "%s: error setting board options\n", __func__);
5951 ath9k_hw_decrease_chain_power(ah, chan);
5953 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5954 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5956 | AR_STA_ID1_RTS_USE_DEF
5958 ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
5959 | ahp->ah_staId1Defaults);
5960 ath9k_hw_set_operating_mode(ah, opmode);
5962 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5963 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5965 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5967 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5968 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5969 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5971 REG_WRITE(ah, AR_ISR, ~0);
5973 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5975 if (AR_SREV_9280_10_OR_LATER(ah)) {
5976 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5979 if (!(ath9k_hw_set_channel(ah, chan)))
5983 for (i = 0; i < AR_NUM_DCU; i++)
5984 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5986 ahp->ah_intrTxqs = 0;
5987 for (i = 0; i < ah->ah_caps.halTotalQueues; i++)
5988 ath9k_hw_resettxqueue(ah, i);
5990 ath9k_hw_init_interrupt_masks(ah, opmode);
5991 ath9k_hw_init_qos(ah);
5993 ath9k_hw_init_user_settings(ah);
5995 ah->ah_opmode = opmode;
5997 REG_WRITE(ah, AR_STA_ID1,
5998 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6000 ath9k_hw_set_dma(ah);
6002 REG_WRITE(ah, AR_OBS, 8);
6004 if (ahp->ah_intrMitigation) {
6006 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6007 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6010 ath9k_hw_init_bb(ah, chan);
6012 if (!ath9k_hw_init_cal(ah, chan))
6015 rx_chainmask = ahp->ah_rxchainmask;
6016 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6017 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6018 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6021 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6023 if (AR_SREV_9100(ah)) {
6025 mask = REG_READ(ah, AR_CFG);
6026 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6027 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6028 "%s CFG Byte Swap Set 0x%x\n", __func__,
6032 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6033 REG_WRITE(ah, AR_CFG, mask);
6034 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6035 "%s Setting CFG 0x%x\n", __func__,
6036 REG_READ(ah, AR_CFG));
6040 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6052 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6054 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6057 bool ath9k_hw_disable(struct ath_hal *ah)
6059 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6062 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6066 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6067 u8 rxchainmask, bool longcal,
6070 struct ath_hal_5416 *ahp = AH5416(ah);
6071 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6072 struct ath9k_channel *ichan =
6073 ath9k_regd_check_channel(ah, chan);
6077 if (ichan == NULL) {
6078 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6079 "%s: invalid channel %u/0x%x; no mapping\n",
6080 __func__, chan->channel, chan->channelFlags);
6085 (currCal->calState == CAL_RUNNING ||
6086 currCal->calState == CAL_WAITING)) {
6087 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6090 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6092 if (currCal->calState == CAL_WAITING) {
6094 ath9k_hw_reset_calibration(ah, currCal);
6100 ath9k_hw_getnf(ah, ichan);
6101 ath9k_hw_loadnf(ah, ah->ah_curchan);
6102 ath9k_hw_start_nfcal(ah);
6104 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6106 chan->channelFlags |= CHANNEL_CW_INT;
6107 ichan->channelFlags &= ~CHANNEL_CW_INT;
6114 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6116 struct ath_hal_5416 *ahp = AH5416(ah);
6119 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6120 ahp->ah_totalPowerMeasI[i] +=
6121 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6122 ahp->ah_totalPowerMeasQ[i] +=
6123 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6124 ahp->ah_totalIqCorrMeas[i] +=
6125 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6126 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6127 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6128 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6129 ahp->ah_totalPowerMeasQ[i],
6130 ahp->ah_totalIqCorrMeas[i]);
6134 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6136 struct ath_hal_5416 *ahp = AH5416(ah);
6139 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6140 ahp->ah_totalAdcIOddPhase[i] +=
6141 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6142 ahp->ah_totalAdcIEvenPhase[i] +=
6143 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6144 ahp->ah_totalAdcQOddPhase[i] +=
6145 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6146 ahp->ah_totalAdcQEvenPhase[i] +=
6147 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6149 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6150 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6151 "oddq=0x%08x; evenq=0x%08x;\n",
6152 ahp->ah_CalSamples, i,
6153 ahp->ah_totalAdcIOddPhase[i],
6154 ahp->ah_totalAdcIEvenPhase[i],
6155 ahp->ah_totalAdcQOddPhase[i],
6156 ahp->ah_totalAdcQEvenPhase[i]);
6160 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6162 struct ath_hal_5416 *ahp = AH5416(ah);
6165 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6166 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6167 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6168 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6169 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6170 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6171 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6172 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6173 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6175 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6176 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6177 "oddq=0x%08x; evenq=0x%08x;\n",
6178 ahp->ah_CalSamples, i,
6179 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6180 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6181 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6182 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6186 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6188 struct ath_hal_5416 *ahp = AH5416(ah);
6189 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6190 u32 qCoffDenom, iCoffDenom;
6191 int32_t qCoff, iCoff;
6194 for (i = 0; i < numChains; i++) {
6195 powerMeasI = ahp->ah_totalPowerMeasI[i];
6196 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6197 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6199 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6200 "Starting IQ Cal and Correction for Chain %d\n",
6203 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6204 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6205 i, ahp->ah_totalIqCorrMeas[i]);
6210 if (iqCorrMeas > 0x80000000) {
6211 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6215 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6216 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6217 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6219 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6222 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6223 qCoffDenom = powerMeasQ / 64;
6225 if (powerMeasQ != 0) {
6227 iCoff = iqCorrMeas / iCoffDenom;
6228 qCoff = powerMeasI / qCoffDenom - 64;
6229 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6230 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6231 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6232 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6235 iCoff = iCoff & 0x3f;
6236 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6237 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6238 if (iqCorrNeg == 0x0)
6239 iCoff = 0x40 - iCoff;
6243 else if (qCoff <= -16)
6246 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6247 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6250 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6251 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6253 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6254 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6256 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6257 "IQ Cal and Correction done for Chain %d\n",
6262 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6263 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6267 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6269 struct ath_hal_5416 *ahp = AH5416(ah);
6270 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6272 u32 qGainMismatch, iGainMismatch, val, i;
6274 for (i = 0; i < numChains; i++) {
6275 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6276 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6277 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6278 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6280 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6281 "Starting ADC Gain Cal for Chain %d\n", i);
6283 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6284 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6286 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6287 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6289 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6290 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6292 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6293 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6296 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6298 ((iEvenMeasOffset * 32) /
6299 iOddMeasOffset) & 0x3f;
6301 ((qOddMeasOffset * 32) /
6302 qEvenMeasOffset) & 0x3f;
6304 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6305 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6307 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6311 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6313 val |= (qGainMismatch) | (iGainMismatch << 6);
6314 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6316 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6317 "ADC Gain Cal done for Chain %d\n", i);
6321 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6322 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6323 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6327 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6329 struct ath_hal_5416 *ahp = AH5416(ah);
6330 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6331 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6332 const struct hal_percal_data *calData =
6333 ahp->ah_cal_list_curr->calData;
6335 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6337 for (i = 0; i < numChains; i++) {
6338 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6339 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6340 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6341 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6343 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6344 "Starting ADC DC Offset Cal for Chain %d\n", i);
6346 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6347 "Chn %d pwr_meas_odd_i = %d\n", i,
6349 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6350 "Chn %d pwr_meas_even_i = %d\n", i,
6352 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6353 "Chn %d pwr_meas_odd_q = %d\n", i,
6355 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6356 "Chn %d pwr_meas_even_q = %d\n", i,
6359 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6360 numSamples) & 0x1ff;
6361 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6362 numSamples) & 0x1ff;
6364 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6365 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6367 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6371 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6373 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6374 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6376 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6377 "ADC DC Offset Cal done for Chain %d\n", i);
6380 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6381 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6382 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6385 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6387 struct ath_hal_5416 *ahp = AH5416(ah);
6388 struct ath9k_channel *chan = ah->ah_curchan;
6390 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6392 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6393 ath9k_regd_get_ctl(ah, chan),
6394 ath9k_regd_get_antenna_allowed(ah,
6396 chan->maxRegTxPower * 2,
6397 min((u32) MAX_RATE_POWER,
6398 (u32) ah->ah_powerLimit)) != 0)
6405 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6406 struct ath9k_channel *chan,
6407 struct chan_centers *centers)
6410 struct ath_hal_5416 *ahp = AH5416(ah);
6412 if (!IS_CHAN_HT40(chan)) {
6413 centers->ctl_center = centers->ext_center =
6414 centers->synth_center = chan->channel;
6418 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6419 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6420 centers->synth_center =
6421 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6424 centers->synth_center =
6425 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6429 centers->ctl_center = centers->synth_center - (extoff *
6430 HT40_CHANNEL_CENTER_SHIFT);
6431 centers->ext_center = centers->synth_center + (extoff *
6435 ATH9K_HT_EXTPROTSPACING_20)
6437 HT40_CHANNEL_CENTER_SHIFT
6443 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6446 struct ath_hal_5416 *ahp = AH5416(ah);
6447 struct ath9k_channel *ichan =
6448 ath9k_regd_check_channel(ah, chan);
6449 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6453 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6456 if (currCal == NULL)
6459 if (ichan == NULL) {
6460 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6461 "%s: invalid channel %u/0x%x; no mapping\n",
6462 __func__, chan->channel, chan->channelFlags);
6467 if (currCal->calState != CAL_DONE) {
6468 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6469 "%s: Calibration state incorrect, %d\n",
6470 __func__, currCal->calState);
6475 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6478 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6479 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6480 __func__, currCal->calData->calType, chan->channel,
6481 chan->channelFlags);
6483 ichan->CalValid &= ~currCal->calData->calType;
6484 currCal->calState = CAL_WAITING;
6489 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6491 struct ath_hal_5416 *ahp = AH5416(ah);
6493 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6496 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6498 struct ath_hal_5416 *ahp = AH5416(ah);
6500 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6504 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6506 struct ath_hal_5416 *ahp = AH5416(ah);
6508 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6512 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6514 struct ath_hal_5416 *ahp = AH5416(ah);
6516 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6518 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6519 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6524 #ifdef CONFIG_ATH9K_RFKILL
6525 static void ath9k_enable_rfkill(struct ath_hal *ah)
6527 struct ath_hal_5416 *ahp = AH5416(ah);
6529 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6530 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6532 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6533 AR_GPIO_INPUT_MUX2_RFSILENT);
6535 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6536 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6538 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6540 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6543 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6550 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6553 struct ath_hal_5416 *ahp = AH5416(ah);
6555 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6556 ahp->ah_assocId = assocId;
6558 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6559 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6560 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6563 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6567 tsf = REG_READ(ah, AR_TSF_U32);
6568 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6572 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6577 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6580 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6581 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6587 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6590 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6592 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6595 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6597 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6601 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6602 enum ath9k_ant_setting settings,
6603 struct ath9k_channel *chan,
6608 struct ath_hal_5416 *ahp = AH5416(ah);
6609 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6611 if (AR_SREV_9280(ah)) {
6612 if (!tx_chainmask_cfg) {
6614 tx_chainmask_cfg = *tx_chainmask;
6615 rx_chainmask_cfg = *rx_chainmask;
6619 case ATH9K_ANT_FIXED_A:
6620 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6621 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6622 *antenna_cfgd = true;
6624 case ATH9K_ANT_FIXED_B:
6625 if (ah->ah_caps.halTxChainMask >
6626 ATH9K_ANTENNA1_CHAINMASK) {
6627 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6629 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6630 *antenna_cfgd = true;
6632 case ATH9K_ANT_VARIABLE:
6633 *tx_chainmask = tx_chainmask_cfg;
6634 *rx_chainmask = rx_chainmask_cfg;
6635 *antenna_cfgd = true;
6641 ahp->ah_diversityControl = settings;
6647 void ath9k_hw_setopmode(struct ath_hal *ah)
6649 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6653 ath9k_hw_getcapability(struct ath_hal *ah, enum hal_capability_type type,
6654 u32 capability, u32 *result)
6656 struct ath_hal_5416 *ahp = AH5416(ah);
6657 const struct hal_capabilities *pCap = &ah->ah_caps;
6660 case HAL_CAP_CIPHER:
6661 switch (capability) {
6662 case ATH9K_CIPHER_AES_CCM:
6663 case ATH9K_CIPHER_AES_OCB:
6664 case ATH9K_CIPHER_TKIP:
6665 case ATH9K_CIPHER_WEP:
6666 case ATH9K_CIPHER_MIC:
6667 case ATH9K_CIPHER_CLR:
6672 case HAL_CAP_TKIP_MIC:
6673 switch (capability) {
6677 return (ahp->ah_staId1Defaults &
6678 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6681 case HAL_CAP_TKIP_SPLIT:
6682 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6684 case HAL_CAP_WME_TKIPMIC:
6686 case HAL_CAP_PHYCOUNTERS:
6687 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6688 case HAL_CAP_DIVERSITY:
6689 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6690 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6692 case HAL_CAP_PHYDIAG:
6694 case HAL_CAP_MCAST_KEYSRCH:
6695 switch (capability) {
6699 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6702 return (ahp->ah_staId1Defaults &
6703 AR_STA_ID1_MCAST_KSRCH) ? true :
6708 case HAL_CAP_TSF_ADJUST:
6709 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6711 case HAL_CAP_RFSILENT:
6712 if (capability == 3)
6714 case HAL_CAP_ANT_CFG_2GHZ:
6715 *result = pCap->halNumAntCfg2GHz;
6717 case HAL_CAP_ANT_CFG_5GHZ:
6718 *result = pCap->halNumAntCfg5GHz;
6721 switch (capability) {
6725 *result = ah->ah_powerLimit;
6728 *result = ah->ah_maxPowerLevel;
6731 *result = ah->ah_tpScale;
6741 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6743 struct ath_hal_5416 *ahp = AH5416(ah);
6744 struct ath9k_channel *chan = ah->ah_curchan;
6745 const struct hal_capabilities *pCap = &ah->ah_caps;
6747 u32 halNumAntConfig;
6750 IS_CHAN_2GHZ(chan) ? pCap->halNumAntCfg2GHz : pCap->
6753 if (cfg < halNumAntConfig) {
6754 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6755 cfg, &ant_config)) {
6756 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6764 bool ath9k_hw_intrpend(struct ath_hal *ah)
6768 if (AR_SREV_9100(ah))
6771 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6772 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6775 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6776 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6777 && (host_isr != AR_INTR_SPURIOUS))
6783 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6787 struct hal_capabilities *pCap = &ah->ah_caps;
6789 bool fatal_int = false;
6791 if (!AR_SREV_9100(ah)) {
6792 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6793 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6794 == AR_RTC_STATUS_ON) {
6795 isr = REG_READ(ah, AR_ISR);
6801 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6805 if (!isr && !sync_cause)
6809 isr = REG_READ(ah, AR_ISR);
6813 struct ath_hal_5416 *ahp = AH5416(ah);
6815 if (isr & AR_ISR_BCNMISC) {
6817 isr2 = REG_READ(ah, AR_ISR_S2);
6818 if (isr2 & AR_ISR_S2_TIM)
6819 mask2 |= ATH9K_INT_TIM;
6820 if (isr2 & AR_ISR_S2_DTIM)
6821 mask2 |= ATH9K_INT_DTIM;
6822 if (isr2 & AR_ISR_S2_DTIMSYNC)
6823 mask2 |= ATH9K_INT_DTIMSYNC;
6824 if (isr2 & (AR_ISR_S2_CABEND))
6825 mask2 |= ATH9K_INT_CABEND;
6826 if (isr2 & AR_ISR_S2_GTT)
6827 mask2 |= ATH9K_INT_GTT;
6828 if (isr2 & AR_ISR_S2_CST)
6829 mask2 |= ATH9K_INT_CST;
6832 isr = REG_READ(ah, AR_ISR_RAC);
6833 if (isr == 0xffffffff) {
6838 *masked = isr & ATH9K_INT_COMMON;
6840 if (ahp->ah_intrMitigation) {
6842 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6843 *masked |= ATH9K_INT_RX;
6846 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6847 *masked |= ATH9K_INT_RX;
6849 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6853 *masked |= ATH9K_INT_TX;
6855 s0_s = REG_READ(ah, AR_ISR_S0_S);
6856 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6857 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6859 s1_s = REG_READ(ah, AR_ISR_S1_S);
6860 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6861 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6864 if (isr & AR_ISR_RXORN) {
6865 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6866 "%s: receive FIFO overrun interrupt\n",
6870 if (!AR_SREV_9100(ah)) {
6871 if (!pCap->halAutoSleepSupport) {
6872 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6873 if (isr5 & AR_ISR_S5_TIM_TIMER)
6874 *masked |= ATH9K_INT_TIM_TIMER;
6880 if (AR_SREV_9100(ah))
6885 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6889 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6890 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6891 "%s: received PCI FATAL interrupt\n",
6894 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6895 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6896 "%s: received PCI PERR interrupt\n",
6900 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6901 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6902 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6904 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6905 REG_WRITE(ah, AR_RC, 0);
6906 *masked |= ATH9K_INT_FATAL;
6908 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6909 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6910 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6914 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6915 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6920 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6922 return AH5416(ah)->ah_maskReg;
6925 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6927 struct ath_hal_5416 *ahp = AH5416(ah);
6928 u32 omask = ahp->ah_maskReg;
6930 struct hal_capabilities *pCap = &ah->ah_caps;
6932 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6935 if (omask & ATH9K_INT_GLOBAL) {
6936 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6938 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6939 (void) REG_READ(ah, AR_IER);
6940 if (!AR_SREV_9100(ah)) {
6941 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6942 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6944 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6945 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6949 mask = ints & ATH9K_INT_COMMON;
6952 if (ints & ATH9K_INT_TX) {
6953 if (ahp->ah_txOkInterruptMask)
6954 mask |= AR_IMR_TXOK;
6955 if (ahp->ah_txDescInterruptMask)
6956 mask |= AR_IMR_TXDESC;
6957 if (ahp->ah_txErrInterruptMask)
6958 mask |= AR_IMR_TXERR;
6959 if (ahp->ah_txEolInterruptMask)
6960 mask |= AR_IMR_TXEOL;
6962 if (ints & ATH9K_INT_RX) {
6963 mask |= AR_IMR_RXERR;
6964 if (ahp->ah_intrMitigation)
6965 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6967 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6968 if (!pCap->halAutoSleepSupport)
6969 mask |= AR_IMR_GENTMR;
6972 if (ints & (ATH9K_INT_BMISC)) {
6973 mask |= AR_IMR_BCNMISC;
6974 if (ints & ATH9K_INT_TIM)
6975 mask2 |= AR_IMR_S2_TIM;
6976 if (ints & ATH9K_INT_DTIM)
6977 mask2 |= AR_IMR_S2_DTIM;
6978 if (ints & ATH9K_INT_DTIMSYNC)
6979 mask2 |= AR_IMR_S2_DTIMSYNC;
6980 if (ints & ATH9K_INT_CABEND)
6981 mask2 |= (AR_IMR_S2_CABEND);
6984 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6985 mask |= AR_IMR_BCNMISC;
6986 if (ints & ATH9K_INT_GTT)
6987 mask2 |= AR_IMR_S2_GTT;
6988 if (ints & ATH9K_INT_CST)
6989 mask2 |= AR_IMR_S2_CST;
6992 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
6994 REG_WRITE(ah, AR_IMR, mask);
6995 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
6997 AR_IMR_S2_DTIMSYNC |
7001 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7002 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7003 ahp->ah_maskReg = ints;
7005 if (!pCap->halAutoSleepSupport) {
7006 if (ints & ATH9K_INT_TIM_TIMER)
7007 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7009 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7012 if (ints & ATH9K_INT_GLOBAL) {
7013 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7015 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7016 if (!AR_SREV_9100(ah)) {
7017 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7019 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7022 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7023 AR_INTR_SYNC_DEFAULT);
7024 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7025 AR_INTR_SYNC_DEFAULT);
7027 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7028 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7035 ath9k_hw_beaconinit(struct ath_hal *ah,
7036 u32 next_beacon, u32 beacon_period)
7038 struct ath_hal_5416 *ahp = AH5416(ah);
7041 ahp->ah_beaconInterval = beacon_period;
7043 switch (ah->ah_opmode) {
7045 case ATH9K_M_MONITOR:
7046 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7047 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7048 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7049 flags |= AR_TBTT_TIMER_EN;
7052 REG_SET_BIT(ah, AR_TXCFG,
7053 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7054 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7055 TU_TO_USEC(next_beacon +
7056 (ahp->ah_atimWindow ? ahp->
7057 ah_atimWindow : 1)));
7058 flags |= AR_NDP_TIMER_EN;
7059 case ATH9K_M_HOSTAP:
7060 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7061 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7062 TU_TO_USEC(next_beacon -
7064 ath_hal_dma_beacon_response_time));
7065 REG_WRITE(ah, AR_NEXT_SWBA,
7066 TU_TO_USEC(next_beacon -
7068 ath_hal_sw_beacon_response_time));
7070 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7074 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7075 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7076 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7077 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7079 beacon_period &= ~ATH9K_BEACON_ENA;
7080 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7081 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7082 ath9k_hw_reset_tsf(ah);
7085 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7089 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7090 const struct ath9k_beacon_state *bs)
7092 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7093 struct hal_capabilities *pCap = &ah->ah_caps;
7095 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7097 REG_WRITE(ah, AR_BEACON_PERIOD,
7098 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7099 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7100 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7102 REG_RMW_FIELD(ah, AR_RSSI_THR,
7103 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7105 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7107 if (bs->bs_sleepduration > beaconintval)
7108 beaconintval = bs->bs_sleepduration;
7110 dtimperiod = bs->bs_dtimperiod;
7111 if (bs->bs_sleepduration > dtimperiod)
7112 dtimperiod = bs->bs_sleepduration;
7114 if (beaconintval == dtimperiod)
7115 nextTbtt = bs->bs_nextdtim;
7117 nextTbtt = bs->bs_nexttbtt;
7119 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7121 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7123 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7125 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7128 REG_WRITE(ah, AR_NEXT_DTIM,
7129 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7130 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7132 REG_WRITE(ah, AR_SLEEP1,
7133 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7134 | AR_SLEEP1_ASSUME_DTIM);
7136 if (pCap->halAutoSleepSupport)
7137 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7139 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7141 REG_WRITE(ah, AR_SLEEP2,
7142 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7144 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7145 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7147 REG_SET_BIT(ah, AR_TIMER_MODE,
7148 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7153 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7155 if (entry < ah->ah_caps.halKeyCacheSize) {
7156 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7157 if (val & AR_KEYTABLE_VALID)
7163 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7167 if (entry >= ah->ah_caps.halKeyCacheSize) {
7168 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7169 "%s: entry %u out of range\n", __func__, entry);
7172 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7174 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7175 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7176 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7177 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7178 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7179 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7180 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7181 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7183 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7184 u16 micentry = entry + 64;
7186 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7187 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7188 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7189 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7193 if (ah->ah_curchan == NULL)
7200 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7205 if (entry >= ah->ah_caps.halKeyCacheSize) {
7206 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7207 "%s: entry %u out of range\n", __func__, entry);
7212 macHi = (mac[5] << 8) | mac[4];
7213 macLo = (mac[3] << 24) | (mac[2] << 16)
7214 | (mac[1] << 8) | mac[0];
7216 macLo |= (macHi & 1) << 31;
7221 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7222 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7228 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7229 const struct ath9k_keyval *k,
7230 const u8 *mac, int xorKey)
7232 const struct hal_capabilities *pCap = &ah->ah_caps;
7233 u32 key0, key1, key2, key3, key4;
7235 u32 xorMask = xorKey ?
7236 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7237 | ATH9K_KEY_XOR) : 0;
7238 struct ath_hal_5416 *ahp = AH5416(ah);
7240 if (entry >= pCap->halKeyCacheSize) {
7241 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7242 "%s: entry %u out of range\n", __func__, entry);
7245 switch (k->kv_type) {
7246 case ATH9K_CIPHER_AES_OCB:
7247 keyType = AR_KEYTABLE_TYPE_AES;
7249 case ATH9K_CIPHER_AES_CCM:
7250 if (!pCap->halCipherAesCcmSupport) {
7251 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7252 "%s: AES-CCM not supported by "
7253 "mac rev 0x%x\n", __func__,
7257 keyType = AR_KEYTABLE_TYPE_CCM;
7259 case ATH9K_CIPHER_TKIP:
7260 keyType = AR_KEYTABLE_TYPE_TKIP;
7261 if (ATH9K_IS_MIC_ENABLED(ah)
7262 && entry + 64 >= pCap->halKeyCacheSize) {
7263 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7264 "%s: entry %u inappropriate for TKIP\n",
7269 case ATH9K_CIPHER_WEP:
7270 if (k->kv_len < 40 / NBBY) {
7271 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7272 "%s: WEP key length %u too small\n",
7273 __func__, k->kv_len);
7276 if (k->kv_len <= 40 / NBBY)
7277 keyType = AR_KEYTABLE_TYPE_40;
7278 else if (k->kv_len <= 104 / NBBY)
7279 keyType = AR_KEYTABLE_TYPE_104;
7281 keyType = AR_KEYTABLE_TYPE_128;
7283 case ATH9K_CIPHER_CLR:
7284 keyType = AR_KEYTABLE_TYPE_CLR;
7287 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7288 "%s: cipher %u not supported\n", __func__,
7293 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7294 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7295 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7296 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7297 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7298 if (k->kv_len <= 104 / NBBY)
7301 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7302 u16 micentry = entry + 64;
7304 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7305 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7306 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7307 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7308 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7309 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7310 (void) ath9k_hw_keysetmac(ah, entry, mac);
7312 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7313 u32 mic0, mic1, mic2, mic3, mic4;
7315 mic0 = get_unaligned_le32(k->kv_mic + 0);
7316 mic2 = get_unaligned_le32(k->kv_mic + 4);
7317 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7318 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7319 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7320 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7321 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7322 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7323 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7324 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7325 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7326 AR_KEYTABLE_TYPE_CLR);
7331 mic0 = get_unaligned_le32(k->kv_mic + 0);
7332 mic2 = get_unaligned_le32(k->kv_mic + 4);
7333 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7334 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7335 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7336 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7337 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7338 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7339 AR_KEYTABLE_TYPE_CLR);
7341 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7342 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7343 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7344 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7346 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7347 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7348 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7349 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7350 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7351 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7353 (void) ath9k_hw_keysetmac(ah, entry, mac);
7356 if (ah->ah_curchan == NULL)
7363 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7365 struct ath_hal_5416 *ahp = AH5416(ah);
7366 u32 txcfg, curLevel, newLevel;
7367 enum ath9k_int omask;
7369 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7372 omask = ath9k_hw_set_interrupts(ah,
7373 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7375 txcfg = REG_READ(ah, AR_TXCFG);
7376 curLevel = MS(txcfg, AR_FTRIG);
7377 newLevel = curLevel;
7378 if (bIncTrigLevel) {
7379 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7381 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7383 if (newLevel != curLevel)
7384 REG_WRITE(ah, AR_TXCFG,
7385 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7387 ath9k_hw_set_interrupts(ah, omask);
7389 ah->ah_txTrigLevel = newLevel;
7391 return newLevel != curLevel;
7394 static bool ath9k_hw_set_txq_props(struct ath_hal *ah,
7395 struct ath9k_tx_queue_info *qi,
7396 const struct ath9k_txq_info *qInfo)
7400 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7401 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7406 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7408 qi->tqi_ver = qInfo->tqi_ver;
7409 qi->tqi_subtype = qInfo->tqi_subtype;
7410 qi->tqi_qflags = qInfo->tqi_qflags;
7411 qi->tqi_priority = qInfo->tqi_priority;
7412 if (qInfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7413 qi->tqi_aifs = min(qInfo->tqi_aifs, 255U);
7415 qi->tqi_aifs = INIT_AIFS;
7416 if (qInfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7417 cw = min(qInfo->tqi_cwmin, 1024U);
7419 while (qi->tqi_cwmin < cw)
7420 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7422 qi->tqi_cwmin = qInfo->tqi_cwmin;
7423 if (qInfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7424 cw = min(qInfo->tqi_cwmax, 1024U);
7426 while (qi->tqi_cwmax < cw)
7427 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7429 qi->tqi_cwmax = INIT_CWMAX;
7431 if (qInfo->tqi_shretry != 0)
7432 qi->tqi_shretry = min((u32) qInfo->tqi_shretry, 15U);
7434 qi->tqi_shretry = INIT_SH_RETRY;
7435 if (qInfo->tqi_lgretry != 0)
7436 qi->tqi_lgretry = min((u32) qInfo->tqi_lgretry, 15U);
7438 qi->tqi_lgretry = INIT_LG_RETRY;
7439 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
7440 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
7441 qi->tqi_burstTime = qInfo->tqi_burstTime;
7442 qi->tqi_readyTime = qInfo->tqi_readyTime;
7444 switch (qInfo->tqi_subtype) {
7445 case ATH9K_WME_UPSD:
7446 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7447 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7455 bool ath9k_hw_settxqueueprops(struct ath_hal *ah, int q,
7456 const struct ath9k_txq_info *qInfo)
7458 struct ath_hal_5416 *ahp = AH5416(ah);
7459 struct hal_capabilities *pCap = &ah->ah_caps;
7461 if (q >= pCap->halTotalQueues) {
7462 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7466 return ath9k_hw_set_txq_props(ah, &ahp->ah_txq[q], qInfo);
7469 static bool ath9k_hw_get_txq_props(struct ath_hal *ah,
7470 struct ath9k_txq_info *qInfo,
7471 const struct ath9k_tx_queue_info *qi)
7473 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7474 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7479 qInfo->tqi_qflags = qi->tqi_qflags;
7480 qInfo->tqi_ver = qi->tqi_ver;
7481 qInfo->tqi_subtype = qi->tqi_subtype;
7482 qInfo->tqi_qflags = qi->tqi_qflags;
7483 qInfo->tqi_priority = qi->tqi_priority;
7484 qInfo->tqi_aifs = qi->tqi_aifs;
7485 qInfo->tqi_cwmin = qi->tqi_cwmin;
7486 qInfo->tqi_cwmax = qi->tqi_cwmax;
7487 qInfo->tqi_shretry = qi->tqi_shretry;
7488 qInfo->tqi_lgretry = qi->tqi_lgretry;
7489 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7490 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7491 qInfo->tqi_burstTime = qi->tqi_burstTime;
7492 qInfo->tqi_readyTime = qi->tqi_readyTime;
7498 ath9k_hw_gettxqueueprops(struct ath_hal *ah, int q,
7499 struct ath9k_txq_info *qInfo)
7501 struct ath_hal_5416 *ahp = AH5416(ah);
7502 struct hal_capabilities *pCap = &ah->ah_caps;
7504 if (q >= pCap->halTotalQueues) {
7505 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7509 return ath9k_hw_get_txq_props(ah, qInfo, &ahp->ah_txq[q]);
7513 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7514 const struct ath9k_txq_info *qInfo)
7516 struct ath_hal_5416 *ahp = AH5416(ah);
7517 struct ath9k_tx_queue_info *qi;
7518 struct hal_capabilities *pCap = &ah->ah_caps;
7522 case ATH9K_TX_QUEUE_BEACON:
7523 q = pCap->halTotalQueues - 1;
7525 case ATH9K_TX_QUEUE_CAB:
7526 q = pCap->halTotalQueues - 2;
7528 case ATH9K_TX_QUEUE_PSPOLL:
7531 case ATH9K_TX_QUEUE_UAPSD:
7532 q = pCap->halTotalQueues - 3;
7534 case ATH9K_TX_QUEUE_DATA:
7535 for (q = 0; q < pCap->halTotalQueues; q++)
7536 if (ahp->ah_txq[q].tqi_type ==
7537 ATH9K_TX_QUEUE_INACTIVE)
7539 if (q == pCap->halTotalQueues) {
7540 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7541 "%s: no available tx queue\n", __func__);
7546 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7551 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7553 qi = &ahp->ah_txq[q];
7554 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7555 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7556 "%s: tx queue %u already active\n", __func__, q);
7559 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7560 qi->tqi_type = type;
7561 if (qInfo == NULL) {
7563 TXQ_FLAG_TXOKINT_ENABLE
7564 | TXQ_FLAG_TXERRINT_ENABLE
7565 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7566 qi->tqi_aifs = INIT_AIFS;
7567 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7568 qi->tqi_cwmax = INIT_CWMAX;
7569 qi->tqi_shretry = INIT_SH_RETRY;
7570 qi->tqi_lgretry = INIT_LG_RETRY;
7571 qi->tqi_physCompBuf = 0;
7573 qi->tqi_physCompBuf = qInfo->tqi_compBuf;
7574 (void) ath9k_hw_settxqueueprops(ah, q, qInfo);
7581 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7582 struct ath9k_tx_queue_info *qi)
7584 struct ath_hal_5416 *ahp = AH5416(ah);
7586 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7587 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7588 __func__, ahp->ah_txOkInterruptMask,
7589 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7590 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7592 REG_WRITE(ah, AR_IMR_S0,
7593 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7594 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7595 REG_WRITE(ah, AR_IMR_S1,
7596 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7597 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7598 REG_RMW_FIELD(ah, AR_IMR_S2,
7599 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7602 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7604 struct ath_hal_5416 *ahp = AH5416(ah);
7605 struct hal_capabilities *pCap = &ah->ah_caps;
7606 struct ath9k_tx_queue_info *qi;
7608 if (q >= pCap->halTotalQueues) {
7609 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7613 qi = &ahp->ah_txq[q];
7614 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7615 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7620 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7623 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7624 ahp->ah_txOkInterruptMask &= ~(1 << q);
7625 ahp->ah_txErrInterruptMask &= ~(1 << q);
7626 ahp->ah_txDescInterruptMask &= ~(1 << q);
7627 ahp->ah_txEolInterruptMask &= ~(1 << q);
7628 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7629 ath9k_hw_set_txq_interrupts(ah, qi);
7634 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7636 struct ath_hal_5416 *ahp = AH5416(ah);
7637 struct hal_capabilities *pCap = &ah->ah_caps;
7638 struct ath9k_channel *chan = ah->ah_curchan;
7639 struct ath9k_tx_queue_info *qi;
7640 u32 cwMin, chanCwMin, value;
7642 if (q >= pCap->halTotalQueues) {
7643 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7647 qi = &ahp->ah_txq[q];
7648 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7649 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7654 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7656 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7657 if (chan && IS_CHAN_B(chan))
7658 chanCwMin = INIT_CWMIN_11B;
7660 chanCwMin = INIT_CWMIN;
7662 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7664 cwMin = qi->tqi_cwmin;
7666 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7667 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7668 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7670 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7671 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7672 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7673 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7676 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7677 REG_WRITE(ah, AR_DMISC(q),
7678 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7680 if (qi->tqi_cbrPeriod) {
7681 REG_WRITE(ah, AR_QCBRCFG(q),
7682 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7683 | SM(qi->tqi_cbrOverflowLimit,
7684 AR_Q_CBRCFG_OVF_THRESH));
7685 REG_WRITE(ah, AR_QMISC(q),
7687 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7688 tqi_cbrOverflowLimit
7690 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7694 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7695 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7696 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7697 AR_Q_RDYTIMECFG_EN);
7700 REG_WRITE(ah, AR_DCHNTIME(q),
7701 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7702 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7704 if (qi->tqi_burstTime
7705 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7706 REG_WRITE(ah, AR_QMISC(q),
7709 AR_Q_MISC_RDYTIME_EXP_POLICY);
7713 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7714 REG_WRITE(ah, AR_DMISC(q),
7715 REG_READ(ah, AR_DMISC(q)) |
7716 AR_D_MISC_POST_FR_BKOFF_DIS);
7718 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7719 REG_WRITE(ah, AR_DMISC(q),
7720 REG_READ(ah, AR_DMISC(q)) |
7721 AR_D_MISC_FRAG_BKOFF_EN);
7723 switch (qi->tqi_type) {
7724 case ATH9K_TX_QUEUE_BEACON:
7725 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7726 | AR_Q_MISC_FSP_DBA_GATED
7727 | AR_Q_MISC_BEACON_USE
7728 | AR_Q_MISC_CBR_INCR_DIS1);
7730 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7731 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7732 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7733 | AR_D_MISC_BEACON_USE
7734 | AR_D_MISC_POST_FR_BKOFF_DIS);
7736 case ATH9K_TX_QUEUE_CAB:
7737 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7738 | AR_Q_MISC_FSP_DBA_GATED
7739 | AR_Q_MISC_CBR_INCR_DIS1
7740 | AR_Q_MISC_CBR_INCR_DIS0);
7741 value = (qi->tqi_readyTime
7742 - (ah->ah_config.ath_hal_sw_beacon_response_time -
7743 ah->ah_config.ath_hal_dma_beacon_response_time)
7745 ah->ah_config.ath_hal_additional_swba_backoff) *
7747 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7748 value | AR_Q_RDYTIMECFG_EN);
7749 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7750 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7751 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7753 case ATH9K_TX_QUEUE_PSPOLL:
7754 REG_WRITE(ah, AR_QMISC(q),
7756 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7758 case ATH9K_TX_QUEUE_UAPSD:
7759 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7760 | AR_D_MISC_POST_FR_BKOFF_DIS);
7766 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7767 REG_WRITE(ah, AR_DMISC(q),
7768 REG_READ(ah, AR_DMISC(q)) |
7769 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7770 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7771 AR_D_MISC_POST_FR_BKOFF_DIS);
7774 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7775 ahp->ah_txOkInterruptMask |= 1 << q;
7777 ahp->ah_txOkInterruptMask &= ~(1 << q);
7778 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7779 ahp->ah_txErrInterruptMask |= 1 << q;
7781 ahp->ah_txErrInterruptMask &= ~(1 << q);
7782 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7783 ahp->ah_txDescInterruptMask |= 1 << q;
7785 ahp->ah_txDescInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7787 ahp->ah_txEolInterruptMask |= 1 << q;
7789 ahp->ah_txEolInterruptMask &= ~(1 << q);
7790 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7791 ahp->ah_txUrnInterruptMask |= 1 << q;
7793 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7794 ath9k_hw_set_txq_interrupts(ah, qi);
7799 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7801 struct ath_hal_5416 *ahp = AH5416(ah);
7802 *txqs &= ahp->ah_intrTxqs;
7803 ahp->ah_intrTxqs &= ~(*txqs);
7807 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7808 u32 segLen, bool firstSeg,
7809 bool lastSeg, const struct ath_desc *ds0)
7811 struct ar5416_desc *ads = AR5416DESC(ds);
7814 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7815 } else if (lastSeg) {
7817 ads->ds_ctl1 = segLen;
7818 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7819 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7822 ads->ds_ctl1 = segLen | AR_TxMore;
7826 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7827 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7828 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7829 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7830 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7834 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7836 struct ar5416_desc *ads = AR5416DESC(ds);
7838 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7839 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7840 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7841 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7842 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7846 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7848 struct ar5416_desc *ads = AR5416DESC(ds);
7850 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7851 return -EINPROGRESS;
7853 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7854 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7855 ds->ds_txstat.ts_status = 0;
7856 ds->ds_txstat.ts_flags = 0;
7858 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7859 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7860 if (ads->ds_txstatus1 & AR_Filtered)
7861 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7862 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7863 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7864 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7865 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7866 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7867 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7869 if (ads->ds_txstatus1 & AR_DescCfgErr)
7870 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7871 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7872 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7873 ath9k_hw_updatetxtriglevel(ah, true);
7875 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7876 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7877 ath9k_hw_updatetxtriglevel(ah, true);
7879 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7880 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7881 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7882 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7885 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7886 switch (ds->ds_txstat.ts_rateindex) {
7888 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7891 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7894 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7897 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7901 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7902 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7903 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7904 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7905 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7906 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7907 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7908 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7909 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7910 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7911 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7912 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7913 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7914 ds->ds_txstat.ts_antenna = 1;
7920 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7921 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7922 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7924 struct ar5416_desc *ads = AR5416DESC(ds);
7925 struct ath_hal_5416 *ahp = AH5416(ah);
7927 txPower += ahp->ah_txPowerIndexOffset;
7931 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7932 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7933 | SM(txPower, AR_XmitPower)
7934 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7935 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7936 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7937 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7940 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7941 | SM(type, AR_FrameType)
7942 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7943 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7944 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7946 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7948 if (AR_SREV_9285(ah)) {
7958 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7959 struct ath_desc *lastds,
7960 u32 durUpdateEn, u32 rtsctsRate,
7962 struct ath9k_11n_rate_series series[],
7963 u32 nseries, u32 flags)
7965 struct ar5416_desc *ads = AR5416DESC(ds);
7966 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7970 (void) rtsctsDuration;
7972 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7973 ds_ctl0 = ads->ds_ctl0;
7975 if (flags & ATH9K_TXDESC_RTSENA) {
7976 ds_ctl0 &= ~AR_CTSEnable;
7977 ds_ctl0 |= AR_RTSEnable;
7979 ds_ctl0 &= ~AR_RTSEnable;
7980 ds_ctl0 |= AR_CTSEnable;
7983 ads->ds_ctl0 = ds_ctl0;
7986 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7989 ads->ds_ctl2 = set11nTries(series, 0)
7990 | set11nTries(series, 1)
7991 | set11nTries(series, 2)
7992 | set11nTries(series, 3)
7993 | (durUpdateEn ? AR_DurUpdateEna : 0)
7994 | SM(0, AR_BurstDur);
7996 ads->ds_ctl3 = set11nRate(series, 0)
7997 | set11nRate(series, 1)
7998 | set11nRate(series, 2)
7999 | set11nRate(series, 3);
8001 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8002 | set11nPktDurRTSCTS(series, 1);
8004 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8005 | set11nPktDurRTSCTS(series, 3);
8007 ads->ds_ctl7 = set11nRateFlags(series, 0)
8008 | set11nRateFlags(series, 1)
8009 | set11nRateFlags(series, 2)
8010 | set11nRateFlags(series, 3)
8011 | SM(rtsctsRate, AR_RTSCTSRate);
8012 last_ads->ds_ctl2 = ads->ds_ctl2;
8013 last_ads->ds_ctl3 = ads->ds_ctl3;
8017 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8020 struct ar5416_desc *ads = AR5416DESC(ds);
8022 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8024 ads->ds_ctl6 &= ~AR_AggrLen;
8025 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8029 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8032 struct ar5416_desc *ads = AR5416DESC(ds);
8035 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8037 ctl6 = ads->ds_ctl6;
8038 ctl6 &= ~AR_PadDelim;
8039 ctl6 |= SM(numDelims, AR_PadDelim);
8040 ads->ds_ctl6 = ctl6;
8043 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8045 struct ar5416_desc *ads = AR5416DESC(ds);
8047 ads->ds_ctl1 |= AR_IsAggr;
8048 ads->ds_ctl1 &= ~AR_MoreAggr;
8049 ads->ds_ctl6 &= ~AR_PadDelim;
8052 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8054 struct ar5416_desc *ads = AR5416DESC(ds);
8056 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8060 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8063 struct ar5416_desc *ads = AR5416DESC(ds);
8065 ads->ds_ctl2 &= ~AR_BurstDur;
8066 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8070 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8073 struct ar5416_desc *ads = AR5416DESC(ds);
8076 ads->ds_ctl0 |= AR_VirtMoreFrag;
8078 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8081 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8083 REG_WRITE(ah, AR_RXDP, rxdp);
8086 void ath9k_hw_rxena(struct ath_hal *ah)
8088 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8091 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8095 REG_SET_BIT(ah, AR_DIAG_SW,
8096 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8099 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8102 REG_CLR_BIT(ah, AR_DIAG_SW,
8106 reg = REG_READ(ah, AR_OBS_BUS_1);
8107 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8108 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8114 REG_CLR_BIT(ah, AR_DIAG_SW,
8115 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8122 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8125 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8126 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8130 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8131 u32 size, u32 flags)
8133 struct ar5416_desc *ads = AR5416DESC(ds);
8134 struct hal_capabilities *pCap = &ah->ah_caps;
8136 ads->ds_ctl1 = size & AR_BufLen;
8137 if (flags & ATH9K_RXDESC_INTREQ)
8138 ads->ds_ctl1 |= AR_RxIntrReq;
8140 ads->ds_rxstatus8 &= ~AR_RxDone;
8141 if (!pCap->halAutoSleepSupport)
8142 memset(&(ads->u), 0, sizeof(ads->u));
8147 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8148 u32 pa, struct ath_desc *nds, u64 tsf)
8150 struct ar5416_desc ads;
8151 struct ar5416_desc *adsp = AR5416DESC(ds);
8153 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8154 return -EINPROGRESS;
8156 ads.u.rx = adsp->u.rx;
8158 ds->ds_rxstat.rs_status = 0;
8159 ds->ds_rxstat.rs_flags = 0;
8161 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8162 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8164 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8165 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8166 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8167 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8168 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8169 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8170 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8171 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8172 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8174 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8176 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8177 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8179 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8180 ds->ds_rxstat.rs_moreaggr =
8181 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8182 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8183 ds->ds_rxstat.rs_flags =
8184 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8185 ds->ds_rxstat.rs_flags |=
8186 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8188 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8189 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8190 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8191 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8192 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8193 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8195 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8197 if (ads.ds_rxstatus8 & AR_CRCErr)
8198 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8199 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8202 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8203 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8204 ds->ds_rxstat.rs_phyerr = phyerr;
8205 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8206 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8207 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8208 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8214 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8215 struct ath9k_rate_table *rt)
8219 if (rt->rateCodeToIndex[0] != 0)
8221 for (i = 0; i < 256; i++)
8222 rt->rateCodeToIndex[i] = (u8) -1;
8223 for (i = 0; i < rt->rateCount; i++) {
8224 u8 code = rt->info[i].rateCode;
8225 u8 cix = rt->info[i].controlRate;
8227 rt->rateCodeToIndex[code] = i;
8228 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8230 rt->info[i].lpAckDuration =
8231 ath9k_hw_computetxtime(ah, rt,
8232 WLAN_CTRL_FRAME_SIZE,
8235 rt->info[i].spAckDuration =
8236 ath9k_hw_computetxtime(ah, rt,
8237 WLAN_CTRL_FRAME_SIZE,
8243 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8246 struct ath9k_rate_table *rt;
8248 case ATH9K_MODE_SEL_11A:
8249 rt = &ar5416_11a_table;
8251 case ATH9K_MODE_SEL_11B:
8252 rt = &ar5416_11b_table;
8254 case ATH9K_MODE_SEL_11G:
8255 rt = &ar5416_11g_table;
8257 case ATH9K_MODE_SEL_11NG_HT20:
8258 case ATH9K_MODE_SEL_11NG_HT40PLUS:
8259 case ATH9K_MODE_SEL_11NG_HT40MINUS:
8260 rt = &ar5416_11ng_table;
8262 case ATH9K_MODE_SEL_11NA_HT20:
8263 case ATH9K_MODE_SEL_11NA_HT40PLUS:
8264 case ATH9K_MODE_SEL_11NA_HT40MINUS:
8265 rt = &ar5416_11na_table;
8268 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8272 ath9k_hw_setup_rate_table(ah, rt);
8276 static const char *ath9k_hw_devname(u16 devid)
8279 case AR5416_DEVID_PCI:
8280 case AR5416_DEVID_PCIE:
8281 return "Atheros 5416";
8282 case AR9160_DEVID_PCI:
8283 return "Atheros 9160";
8284 case AR9280_DEVID_PCI:
8285 case AR9280_DEVID_PCIE:
8286 return "Atheros 9280";
8291 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8293 return vendorid == ATHEROS_VENDOR_ID ?
8294 ath9k_hw_devname(devid) : NULL;
8297 struct ath_hal *ath9k_hw_attach(u16 devid,
8298 struct ath_softc *sc,
8302 struct ath_hal *ah = NULL;
8305 case AR5416_DEVID_PCI:
8306 case AR5416_DEVID_PCIE:
8307 case AR9160_DEVID_PCI:
8308 case AR9280_DEVID_PCI:
8309 case AR9280_DEVID_PCIE:
8310 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8313 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8314 "devid=0x%x not supported.\n", devid);
8320 ah->ah_devid = ah->ah_devid;
8321 ah->ah_subvendorid = ah->ah_subvendorid;
8322 ah->ah_macVersion = ah->ah_macVersion;
8323 ah->ah_macRev = ah->ah_macRev;
8324 ah->ah_phyRev = ah->ah_phyRev;
8325 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8326 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8332 ath9k_hw_computetxtime(struct ath_hal *ah,
8333 const struct ath9k_rate_table *rates,
8334 u32 frameLen, u16 rateix,
8337 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8340 kbps = rates->info[rateix].rateKbps;
8344 switch (rates->info[rateix].phy) {
8347 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8348 if (shortPreamble && rates->info[rateix].shortPreamble)
8350 numBits = frameLen << 3;
8351 txTime = CCK_SIFS_TIME + phyTime
8352 + ((numBits * 1000) / kbps);
8355 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8357 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8359 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8360 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8361 txTime = OFDM_SIFS_TIME_QUARTER
8362 + OFDM_PREAMBLE_TIME_QUARTER
8363 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8364 } else if (ah->ah_curchan &&
8365 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8367 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8369 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8370 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8371 txTime = OFDM_SIFS_TIME_HALF +
8372 OFDM_PREAMBLE_TIME_HALF
8373 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8375 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8377 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8378 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8379 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8380 + (numSymbols * OFDM_SYMBOL_TIME);
8385 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8386 "%s: unknown phy %u (rate ix %u)\n", __func__,
8387 rates->info[rateix].phy, rateix);
8394 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8396 if (flags & CHANNEL_2GHZ) {
8400 return (freq - 2407) / 5;
8402 return 15 + ((freq - 2512) / 20);
8403 } else if (flags & CHANNEL_5GHZ) {
8404 if (ath9k_regd_is_public_safety_sku(ah) &&
8405 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8406 return ((freq * 10) +
8407 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8408 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8409 return (freq - 4000) / 5;
8411 return (freq - 5000) / 5;
8417 return (freq - 2407) / 5;
8419 if (ath9k_regd_is_public_safety_sku(ah)
8420 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8421 return ((freq * 10) +
8423 2) ? 5 : 0) - 49400) / 5;
8424 } else if (freq > 4900) {
8425 return (freq - 4000) / 5;
8427 return 15 + ((freq - 2512) / 20);
8430 return (freq - 5000) / 5;
8435 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8437 struct ath9k_channel *ichan;
8439 ichan = ath9k_regd_check_channel(ah, chan);
8440 if (ichan == NULL) {
8441 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8442 "%s: invalid channel %u/0x%x; no mapping\n",
8443 __func__, chan->channel, chan->channelFlags);
8446 if (ichan->rawNoiseFloor == 0) {
8447 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8448 return NOISE_FLOOR[mode];
8450 return ichan->rawNoiseFloor;
8453 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8455 struct ath_hal_5416 *ahp = AH5416(ah);
8458 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8460 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8464 bool ath9k_hw_phycounters(struct ath_hal *ah)
8466 struct ath_hal_5416 *ahp = AH5416(ah);
8468 return ahp->ah_hasHwPhyCounters ? true : false;
8471 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8473 return REG_READ(ah, AR_QTXDP(q));
8476 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8479 REG_WRITE(ah, AR_QTXDP(q), txdp);
8484 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8486 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8488 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8493 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8497 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8500 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8506 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8510 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8512 for (wait = 1000; wait != 0; wait--) {
8513 if (ath9k_hw_numtxpending(ah, q) == 0)
8518 if (ath9k_hw_numtxpending(ah, q)) {
8521 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8522 "%s: Num of pending TX Frames %d on Q %d\n",
8523 __func__, ath9k_hw_numtxpending(ah, q), q);
8525 for (j = 0; j < 2; j++) {
8526 tsfLow = REG_READ(ah, AR_TSF_L32);
8527 REG_WRITE(ah, AR_QUIET2,
8528 SM(10, AR_QUIET2_QUIET_DUR));
8529 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8530 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8531 REG_SET_BIT(ah, AR_TIMER_MODE,
8534 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8538 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8539 "%s: TSF have moved while trying to set "
8540 "quiet time TSF: 0x%08x\n",
8544 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8547 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8551 while (ath9k_hw_numtxpending(ah, q)) {
8552 if ((--wait) == 0) {
8553 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8554 "%s: Failed to stop Tx DMA in 100 "
8555 "msec after killing last frame\n",
8562 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8565 REG_WRITE(ah, AR_Q_TXD, 0);