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)) {
4804 if ((abs(cur_vit_mask - bin)) < 75)
4808 if (cur_vit_mask < 0)
4809 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4811 mask_p[cur_vit_mask / 100] = mask_amt;
4813 cur_vit_mask -= 100;
4816 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4817 | (mask_m[48] << 26) | (mask_m[49] << 24)
4818 | (mask_m[50] << 22) | (mask_m[51] << 20)
4819 | (mask_m[52] << 18) | (mask_m[53] << 16)
4820 | (mask_m[54] << 14) | (mask_m[55] << 12)
4821 | (mask_m[56] << 10) | (mask_m[57] << 8)
4822 | (mask_m[58] << 6) | (mask_m[59] << 4)
4823 | (mask_m[60] << 2) | (mask_m[61] << 0);
4824 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4825 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4827 tmp_mask = (mask_m[31] << 28)
4828 | (mask_m[32] << 26) | (mask_m[33] << 24)
4829 | (mask_m[34] << 22) | (mask_m[35] << 20)
4830 | (mask_m[36] << 18) | (mask_m[37] << 16)
4831 | (mask_m[48] << 14) | (mask_m[39] << 12)
4832 | (mask_m[40] << 10) | (mask_m[41] << 8)
4833 | (mask_m[42] << 6) | (mask_m[43] << 4)
4834 | (mask_m[44] << 2) | (mask_m[45] << 0);
4835 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4836 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4838 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4839 | (mask_m[18] << 26) | (mask_m[18] << 24)
4840 | (mask_m[20] << 22) | (mask_m[20] << 20)
4841 | (mask_m[22] << 18) | (mask_m[22] << 16)
4842 | (mask_m[24] << 14) | (mask_m[24] << 12)
4843 | (mask_m[25] << 10) | (mask_m[26] << 8)
4844 | (mask_m[27] << 6) | (mask_m[28] << 4)
4845 | (mask_m[29] << 2) | (mask_m[30] << 0);
4846 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4847 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4849 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4850 | (mask_m[2] << 26) | (mask_m[3] << 24)
4851 | (mask_m[4] << 22) | (mask_m[5] << 20)
4852 | (mask_m[6] << 18) | (mask_m[7] << 16)
4853 | (mask_m[8] << 14) | (mask_m[9] << 12)
4854 | (mask_m[10] << 10) | (mask_m[11] << 8)
4855 | (mask_m[12] << 6) | (mask_m[13] << 4)
4856 | (mask_m[14] << 2) | (mask_m[15] << 0);
4857 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4858 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4860 tmp_mask = (mask_p[15] << 28)
4861 | (mask_p[14] << 26) | (mask_p[13] << 24)
4862 | (mask_p[12] << 22) | (mask_p[11] << 20)
4863 | (mask_p[10] << 18) | (mask_p[9] << 16)
4864 | (mask_p[8] << 14) | (mask_p[7] << 12)
4865 | (mask_p[6] << 10) | (mask_p[5] << 8)
4866 | (mask_p[4] << 6) | (mask_p[3] << 4)
4867 | (mask_p[2] << 2) | (mask_p[1] << 0);
4868 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4869 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4871 tmp_mask = (mask_p[30] << 28)
4872 | (mask_p[29] << 26) | (mask_p[28] << 24)
4873 | (mask_p[27] << 22) | (mask_p[26] << 20)
4874 | (mask_p[25] << 18) | (mask_p[24] << 16)
4875 | (mask_p[23] << 14) | (mask_p[22] << 12)
4876 | (mask_p[21] << 10) | (mask_p[20] << 8)
4877 | (mask_p[19] << 6) | (mask_p[18] << 4)
4878 | (mask_p[17] << 2) | (mask_p[16] << 0);
4879 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4880 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4882 tmp_mask = (mask_p[45] << 28)
4883 | (mask_p[44] << 26) | (mask_p[43] << 24)
4884 | (mask_p[42] << 22) | (mask_p[41] << 20)
4885 | (mask_p[40] << 18) | (mask_p[39] << 16)
4886 | (mask_p[38] << 14) | (mask_p[37] << 12)
4887 | (mask_p[36] << 10) | (mask_p[35] << 8)
4888 | (mask_p[34] << 6) | (mask_p[33] << 4)
4889 | (mask_p[32] << 2) | (mask_p[31] << 0);
4890 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4891 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4893 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4894 | (mask_p[59] << 26) | (mask_p[58] << 24)
4895 | (mask_p[57] << 22) | (mask_p[56] << 20)
4896 | (mask_p[55] << 18) | (mask_p[54] << 16)
4897 | (mask_p[53] << 14) | (mask_p[52] << 12)
4898 | (mask_p[51] << 10) | (mask_p[50] << 8)
4899 | (mask_p[49] << 6) | (mask_p[48] << 4)
4900 | (mask_p[47] << 2) | (mask_p[46] << 0);
4901 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4902 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4905 static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4906 struct ath9k_channel *chan)
4908 int bb_spur = AR_NO_SPUR;
4911 int spur_delta_phase;
4913 int upper, lower, cur_vit_mask;
4916 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4917 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4919 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4920 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4922 int inc[4] = { 0, 100, 0, 0 };
4929 bool is2GHz = IS_CHAN_2GHZ(chan);
4931 memset(&mask_m, 0, sizeof(int8_t) * 123);
4932 memset(&mask_p, 0, sizeof(int8_t) * 123);
4934 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4935 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4936 if (AR_NO_SPUR == cur_bb_spur)
4938 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4939 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4940 bb_spur = cur_bb_spur;
4945 if (AR_NO_SPUR == bb_spur)
4950 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4951 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4952 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4953 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4954 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4956 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4958 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4959 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4960 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4961 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4962 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4963 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4965 spur_delta_phase = ((bb_spur * 524288) / 100) &
4966 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4968 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4969 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4971 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4972 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4973 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4974 REG_WRITE(ah, AR_PHY_TIMING11, new);
4980 for (i = 0; i < 4; i++) {
4984 for (bp = 0; bp < 30; bp++) {
4985 if ((cur_bin > lower) && (cur_bin < upper)) {
4986 pilot_mask = pilot_mask | 0x1 << bp;
4987 chan_mask = chan_mask | 0x1 << bp;
4992 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4993 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4996 cur_vit_mask = 6100;
5000 for (i = 0; i < 123; i++) {
5001 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5002 if ((abs(cur_vit_mask - bin)) < 75)
5006 if (cur_vit_mask < 0)
5007 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5009 mask_p[cur_vit_mask / 100] = mask_amt;
5011 cur_vit_mask -= 100;
5014 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5015 | (mask_m[48] << 26) | (mask_m[49] << 24)
5016 | (mask_m[50] << 22) | (mask_m[51] << 20)
5017 | (mask_m[52] << 18) | (mask_m[53] << 16)
5018 | (mask_m[54] << 14) | (mask_m[55] << 12)
5019 | (mask_m[56] << 10) | (mask_m[57] << 8)
5020 | (mask_m[58] << 6) | (mask_m[59] << 4)
5021 | (mask_m[60] << 2) | (mask_m[61] << 0);
5022 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5023 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5025 tmp_mask = (mask_m[31] << 28)
5026 | (mask_m[32] << 26) | (mask_m[33] << 24)
5027 | (mask_m[34] << 22) | (mask_m[35] << 20)
5028 | (mask_m[36] << 18) | (mask_m[37] << 16)
5029 | (mask_m[48] << 14) | (mask_m[39] << 12)
5030 | (mask_m[40] << 10) | (mask_m[41] << 8)
5031 | (mask_m[42] << 6) | (mask_m[43] << 4)
5032 | (mask_m[44] << 2) | (mask_m[45] << 0);
5033 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5034 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5036 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5037 | (mask_m[18] << 26) | (mask_m[18] << 24)
5038 | (mask_m[20] << 22) | (mask_m[20] << 20)
5039 | (mask_m[22] << 18) | (mask_m[22] << 16)
5040 | (mask_m[24] << 14) | (mask_m[24] << 12)
5041 | (mask_m[25] << 10) | (mask_m[26] << 8)
5042 | (mask_m[27] << 6) | (mask_m[28] << 4)
5043 | (mask_m[29] << 2) | (mask_m[30] << 0);
5044 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5045 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5047 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5048 | (mask_m[2] << 26) | (mask_m[3] << 24)
5049 | (mask_m[4] << 22) | (mask_m[5] << 20)
5050 | (mask_m[6] << 18) | (mask_m[7] << 16)
5051 | (mask_m[8] << 14) | (mask_m[9] << 12)
5052 | (mask_m[10] << 10) | (mask_m[11] << 8)
5053 | (mask_m[12] << 6) | (mask_m[13] << 4)
5054 | (mask_m[14] << 2) | (mask_m[15] << 0);
5055 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5056 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5058 tmp_mask = (mask_p[15] << 28)
5059 | (mask_p[14] << 26) | (mask_p[13] << 24)
5060 | (mask_p[12] << 22) | (mask_p[11] << 20)
5061 | (mask_p[10] << 18) | (mask_p[9] << 16)
5062 | (mask_p[8] << 14) | (mask_p[7] << 12)
5063 | (mask_p[6] << 10) | (mask_p[5] << 8)
5064 | (mask_p[4] << 6) | (mask_p[3] << 4)
5065 | (mask_p[2] << 2) | (mask_p[1] << 0);
5066 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5067 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5069 tmp_mask = (mask_p[30] << 28)
5070 | (mask_p[29] << 26) | (mask_p[28] << 24)
5071 | (mask_p[27] << 22) | (mask_p[26] << 20)
5072 | (mask_p[25] << 18) | (mask_p[24] << 16)
5073 | (mask_p[23] << 14) | (mask_p[22] << 12)
5074 | (mask_p[21] << 10) | (mask_p[20] << 8)
5075 | (mask_p[19] << 6) | (mask_p[18] << 4)
5076 | (mask_p[17] << 2) | (mask_p[16] << 0);
5077 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5078 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5080 tmp_mask = (mask_p[45] << 28)
5081 | (mask_p[44] << 26) | (mask_p[43] << 24)
5082 | (mask_p[42] << 22) | (mask_p[41] << 20)
5083 | (mask_p[40] << 18) | (mask_p[39] << 16)
5084 | (mask_p[38] << 14) | (mask_p[37] << 12)
5085 | (mask_p[36] << 10) | (mask_p[35] << 8)
5086 | (mask_p[34] << 6) | (mask_p[33] << 4)
5087 | (mask_p[32] << 2) | (mask_p[31] << 0);
5088 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5089 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5091 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5092 | (mask_p[59] << 26) | (mask_p[58] << 24)
5093 | (mask_p[57] << 22) | (mask_p[56] << 20)
5094 | (mask_p[55] << 18) | (mask_p[54] << 16)
5095 | (mask_p[53] << 14) | (mask_p[52] << 12)
5096 | (mask_p[51] << 10) | (mask_p[50] << 8)
5097 | (mask_p[49] << 6) | (mask_p[48] << 4)
5098 | (mask_p[47] << 2) | (mask_p[46] << 0);
5099 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5100 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5103 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5105 struct ath_hal_5416 *ahp = AH5416(ah);
5106 int rx_chainmask, tx_chainmask;
5108 rx_chainmask = ahp->ah_rxchainmask;
5109 tx_chainmask = ahp->ah_txchainmask;
5111 switch (rx_chainmask) {
5113 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5114 AR_PHY_SWAP_ALT_CHAIN);
5116 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5117 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5118 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5123 if (!AR_SREV_9280(ah))
5126 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5127 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5133 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5134 if (tx_chainmask == 0x5) {
5135 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5136 AR_PHY_SWAP_ALT_CHAIN);
5138 if (AR_SREV_9100(ah))
5139 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5140 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5143 static void ath9k_hw_set_addac(struct ath_hal *ah,
5144 struct ath9k_channel *chan)
5146 struct modal_eep_header *pModal;
5147 struct ath_hal_5416 *ahp = AH5416(ah);
5148 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5151 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5154 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5157 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5159 if (pModal->xpaBiasLvl != 0xff) {
5160 biaslevel = pModal->xpaBiasLvl;
5163 u16 resetFreqBin, freqBin, freqCount = 0;
5164 struct chan_centers centers;
5166 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5169 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5170 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5171 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5175 while (freqCount < 3) {
5176 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5179 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5180 if (resetFreqBin >= freqBin) {
5183 xpaBiasLvlFreq[freqCount]
5192 if (IS_CHAN_2GHZ(chan)) {
5193 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5194 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5197 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5198 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5203 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5205 if (ah->ah_curchan != NULL)
5207 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5209 return clks / CLOCK_RATE[WIRELESS_MODE_11b];
5212 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5214 struct ath9k_channel *chan = ah->ah_curchan;
5216 if (chan && IS_CHAN_HT40(chan))
5217 return ath9k_hw_mac_usec(ah, clks) / 2;
5219 return ath9k_hw_mac_usec(ah, clks);
5222 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5224 if (ah->ah_curchan != NULL)
5225 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5228 return usecs * CLOCK_RATE[WIRELESS_MODE_11b];
5231 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5233 struct ath9k_channel *chan = ah->ah_curchan;
5235 if (chan && IS_CHAN_HT40(chan))
5236 return ath9k_hw_mac_clks(ah, usecs) * 2;
5238 return ath9k_hw_mac_clks(ah, usecs);
5241 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5243 struct ath_hal_5416 *ahp = AH5416(ah);
5245 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5246 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5248 ahp->ah_acktimeout = (u32) -1;
5251 REG_RMW_FIELD(ah, AR_TIME_OUT,
5252 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5253 ahp->ah_acktimeout = us;
5258 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5260 struct ath_hal_5416 *ahp = AH5416(ah);
5262 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5263 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5265 ahp->ah_ctstimeout = (u32) -1;
5268 REG_RMW_FIELD(ah, AR_TIME_OUT,
5269 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5270 ahp->ah_ctstimeout = us;
5274 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5277 struct ath_hal_5416 *ahp = AH5416(ah);
5280 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5281 "%s: bad global tx timeout %u\n", __func__, tu);
5282 ahp->ah_globaltxtimeout = (u32) -1;
5285 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5286 ahp->ah_globaltxtimeout = tu;
5291 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5293 struct ath_hal_5416 *ahp = AH5416(ah);
5295 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5296 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5298 ahp->ah_slottime = (u32) -1;
5301 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5302 ahp->ah_slottime = us;
5307 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5309 struct ath_hal_5416 *ahp = AH5416(ah);
5311 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5312 __func__, ahp->ah_miscMode);
5313 if (ahp->ah_miscMode != 0)
5314 REG_WRITE(ah, AR_PCU_MISC,
5315 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5316 if (ahp->ah_slottime != (u32) -1)
5317 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5318 if (ahp->ah_acktimeout != (u32) -1)
5319 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5320 if (ahp->ah_ctstimeout != (u32) -1)
5321 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5322 if (ahp->ah_globaltxtimeout != (u32) -1)
5323 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5327 ath9k_hw_process_ini(struct ath_hal *ah,
5328 struct ath9k_channel *chan,
5329 enum ath9k_ht_macmode macmode)
5331 int i, regWrites = 0;
5332 struct ath_hal_5416 *ahp = AH5416(ah);
5333 u32 modesIndex, freqIndex;
5336 switch (chan->chanmode) {
5338 case CHANNEL_A_HT20:
5342 case CHANNEL_A_HT40PLUS:
5343 case CHANNEL_A_HT40MINUS:
5348 case CHANNEL_G_HT20:
5353 case CHANNEL_G_HT40PLUS:
5354 case CHANNEL_G_HT40MINUS:
5363 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5365 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5367 ath9k_hw_set_addac(ah, chan);
5369 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5370 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5372 struct ar5416IniArray temp;
5374 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5375 ahp->ah_iniAddac.ia_columns;
5377 memcpy(ahp->ah_addac5416_21,
5378 ahp->ah_iniAddac.ia_array, addacSize);
5380 (ahp->ah_addac5416_21)[31 *
5381 ahp->ah_iniAddac.ia_columns + 1] = 0;
5383 temp.ia_array = ahp->ah_addac5416_21;
5384 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5385 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5386 REG_WRITE_ARRAY(&temp, 1, regWrites);
5388 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5390 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5391 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5392 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5394 #ifdef CONFIG_SLOW_ANT_DIV
5395 if (ah->ah_devid == AR9280_DEVID_PCI)
5396 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5400 REG_WRITE(ah, reg, val);
5402 if (reg >= 0x7800 && reg < 0x78a0
5403 && ah->ah_config.ath_hal_analogShiftReg) {
5407 DO_DELAY(regWrites);
5410 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5411 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5412 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5414 REG_WRITE(ah, reg, val);
5416 if (reg >= 0x7800 && reg < 0x78a0
5417 && ah->ah_config.ath_hal_analogShiftReg) {
5421 DO_DELAY(regWrites);
5424 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5426 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5427 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5431 ath9k_hw_override_ini(ah, chan);
5432 ath9k_hw_set_regs(ah, chan, macmode);
5433 ath9k_hw_init_chain_masks(ah);
5435 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5436 ath9k_regd_get_ctl(ah, chan),
5437 ath9k_regd_get_antenna_allowed(ah,
5439 chan->maxRegTxPower * 2,
5440 min((u32) MAX_RATE_POWER,
5441 (u32) ah->ah_powerLimit));
5443 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5444 "%s: error init'ing transmit power\n", __func__);
5448 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5449 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5450 "%s: ar5416SetRfRegs failed\n", __func__);
5457 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5458 struct hal_cal_list *currCal)
5460 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5461 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5462 currCal->calData->calCountMax);
5464 switch (currCal->calData->calType) {
5465 case IQ_MISMATCH_CAL:
5466 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5467 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5468 "%s: starting IQ Mismatch Calibration\n",
5472 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5473 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5474 "%s: starting ADC Gain Calibration\n", __func__);
5477 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5478 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5479 "%s: starting ADC DC Calibration\n", __func__);
5481 case ADC_DC_INIT_CAL:
5482 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5483 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5484 "%s: starting Init ADC DC Calibration\n",
5489 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5490 AR_PHY_TIMING_CTRL4_DO_CAL);
5493 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5494 struct hal_cal_list *currCal)
5496 struct ath_hal_5416 *ahp = AH5416(ah);
5499 ath9k_hw_setup_calibration(ah, currCal);
5501 currCal->calState = CAL_RUNNING;
5503 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5504 ahp->ah_Meas0.sign[i] = 0;
5505 ahp->ah_Meas1.sign[i] = 0;
5506 ahp->ah_Meas2.sign[i] = 0;
5507 ahp->ah_Meas3.sign[i] = 0;
5510 ahp->ah_CalSamples = 0;
5514 ath9k_hw_per_calibration(struct ath_hal *ah,
5515 struct ath9k_channel *ichan,
5517 struct hal_cal_list *currCal,
5520 struct ath_hal_5416 *ahp = AH5416(ah);
5524 if (currCal->calState == CAL_RUNNING) {
5526 AR_PHY_TIMING_CTRL4(0)) &
5527 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5529 currCal->calData->calCollect(ah);
5531 ahp->ah_CalSamples++;
5533 if (ahp->ah_CalSamples >=
5534 currCal->calData->calNumSamples) {
5535 int i, numChains = 0;
5536 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5537 if (rxchainmask & (1 << i))
5541 currCal->calData->calPostProc(ah,
5545 currCal->calData->calType;
5546 currCal->calState = CAL_DONE;
5549 ath9k_hw_setup_calibration(ah, currCal);
5552 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5553 ath9k_hw_reset_calibration(ah, currCal);
5557 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5560 struct ath_hal_5416 *ahp = AH5416(ah);
5561 struct ath9k_channel ichan;
5563 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5564 const struct hal_percal_data *calData = currCal->calData;
5567 if (currCal == NULL)
5572 for (i = 0; i < init_cal_count; i++) {
5573 ath9k_hw_reset_calibration(ah, currCal);
5575 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5576 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5577 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5578 "%s: Cal %d failed to complete in 100ms.\n",
5579 __func__, calData->calType);
5581 ahp->ah_cal_list = ahp->ah_cal_list_last =
5582 ahp->ah_cal_list_curr = NULL;
5586 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5587 currCal, &isCalDone);
5589 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5590 "%s: Not able to run Init Cal %d.\n",
5591 __func__, calData->calType);
5593 if (currCal->calNext) {
5594 currCal = currCal->calNext;
5595 calData = currCal->calData;
5599 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5604 ath9k_hw_channel_change(struct ath_hal *ah,
5605 struct ath9k_channel *chan,
5606 enum ath9k_ht_macmode macmode)
5608 u32 synthDelay, qnum;
5609 struct ath_hal_5416 *ahp = AH5416(ah);
5611 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5612 if (ath9k_hw_numtxpending(ah, qnum)) {
5613 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5614 "%s: Transmit frames pending on queue %d\n",
5620 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5621 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5622 AR_PHY_RFBUS_GRANT_EN)) {
5623 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5624 "%s: Could not kill baseband RX\n", __func__);
5628 ath9k_hw_set_regs(ah, chan, macmode);
5630 if (AR_SREV_9280_10_OR_LATER(ah)) {
5631 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5632 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5633 "%s: failed to set channel\n", __func__);
5637 if (!(ath9k_hw_set_channel(ah, chan))) {
5638 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5639 "%s: failed to set channel\n", __func__);
5644 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5645 ath9k_regd_get_ctl(ah, chan),
5646 ath9k_regd_get_antenna_allowed(ah, chan),
5647 chan->maxRegTxPower * 2,
5648 min((u32) MAX_RATE_POWER,
5649 (u32) ah->ah_powerLimit)) != 0) {
5650 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5651 "%s: error init'ing transmit power\n", __func__);
5655 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5656 if (IS_CHAN_CCK(chan))
5657 synthDelay = (4 * synthDelay) / 22;
5661 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5663 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5665 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5666 ath9k_hw_set_delta_slope(ah, chan);
5668 if (AR_SREV_9280_10_OR_LATER(ah))
5669 ath9k_hw_9280_spur_mitigate(ah, chan);
5671 ath9k_hw_spur_mitigate(ah, chan);
5673 if (!chan->oneTimeCalsDone)
5674 chan->oneTimeCalsDone = true;
5679 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5680 struct ath9k_channel *chan)
5682 struct ath_hal_5416 *ahp = AH5416(ah);
5684 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5687 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5690 ahp->ah_chipFullSleep = false;
5692 ath9k_hw_init_pll(ah, chan);
5694 ath9k_hw_set_rfmode(ah, chan);
5699 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5703 regval = REG_READ(ah, AR_AHB_MODE);
5704 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5706 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5707 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5709 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5711 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5712 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5714 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5716 if (AR_SREV_9285(ah)) {
5717 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5718 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5720 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5721 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5725 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5727 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5728 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5729 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5730 "%s: dma failed to stop in 10ms\n"
5731 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5733 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5740 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5742 REG_CLR_BIT(ah, AR_DIAG_SW,
5743 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5745 ath9k_enable_mib_counters(ah);
5747 ath9k_ani_reset(ah);
5750 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5752 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5754 ath9k_hw_disable_mib_counters(ah);
5757 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5758 struct ath9k_channel *chan,
5759 enum hal_cal_types calType)
5761 struct ath_hal_5416 *ahp = AH5416(ah);
5762 bool retval = false;
5764 switch (calType & ahp->ah_suppCals) {
5765 case IQ_MISMATCH_CAL:
5766 if (!IS_CHAN_B(chan))
5771 if (!IS_CHAN_B(chan)
5772 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5780 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5781 struct ath9k_channel *chan)
5783 struct ath_hal_5416 *ahp = AH5416(ah);
5784 struct ath9k_channel *ichan =
5785 ath9k_regd_check_channel(ah, chan);
5787 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5788 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5789 AR_PHY_AGC_CONTROL_CAL);
5792 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5793 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5794 "%s: offset calibration failed to complete in 1ms; "
5795 "noisy environment?\n", __func__);
5799 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5800 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5801 AR_PHY_AGC_CONTROL_NF);
5803 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5806 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5807 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5808 INIT_CAL(&ahp->ah_adcGainCalData);
5809 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5810 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5811 "%s: enabling ADC Gain Calibration.\n",
5814 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5815 INIT_CAL(&ahp->ah_adcDcCalData);
5816 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5817 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5818 "%s: enabling ADC DC Calibration.\n",
5821 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5822 INIT_CAL(&ahp->ah_iqCalData);
5823 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5824 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5825 "%s: enabling IQ Calibration.\n",
5829 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5831 if (ahp->ah_cal_list_curr)
5832 ath9k_hw_reset_calibration(ah,
5833 ahp->ah_cal_list_curr);
5836 ichan->CalValid = 0;
5842 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5843 struct ath9k_channel *chan,
5844 enum ath9k_ht_macmode macmode,
5845 u8 txchainmask, u8 rxchainmask,
5846 enum ath9k_ht_extprotspacing extprotspacing,
5847 bool bChannelChange,
5850 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5852 struct ath_hal_5416 *ahp = AH5416(ah);
5853 struct ath9k_channel *curchan = ah->ah_curchan;
5857 int i, rx_chainmask;
5859 ahp->ah_extprotspacing = extprotspacing;
5860 ahp->ah_txchainmask = txchainmask;
5861 ahp->ah_rxchainmask = rxchainmask;
5863 if (AR_SREV_9280(ah)) {
5864 ahp->ah_txchainmask &= 0x3;
5865 ahp->ah_rxchainmask &= 0x3;
5868 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5869 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5870 "%s: invalid channel %u/0x%x; no mapping\n",
5871 __func__, chan->channel, chan->channelFlags);
5875 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5879 ath9k_hw_getnf(ah, curchan);
5881 if (bChannelChange &&
5882 (ahp->ah_chipFullSleep != true) &&
5883 (ah->ah_curchan != NULL) &&
5884 (chan->channel != ah->ah_curchan->channel) &&
5885 ((chan->channelFlags & CHANNEL_ALL) ==
5886 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5887 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5888 !IS_CHAN_A_5MHZ_SPACED(ah->
5891 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5892 ath9k_hw_loadnf(ah, ah->ah_curchan);
5893 ath9k_hw_start_nfcal(ah);
5898 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5899 if (saveDefAntenna == 0)
5902 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5904 saveLedState = REG_READ(ah, AR_CFG_LED) &
5905 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5906 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5908 ath9k_hw_mark_phy_inactive(ah);
5910 if (!ath9k_hw_chip_reset(ah, chan)) {
5911 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5916 if (AR_SREV_9280(ah)) {
5917 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5918 AR_GPIO_JTAG_DISABLE);
5920 if (ah->ah_caps.halWirelessModes & ATH9K_MODE_SEL_11A) {
5921 if (IS_CHAN_5GHZ(chan))
5922 ath9k_hw_set_gpio(ah, 9, 0);
5924 ath9k_hw_set_gpio(ah, 9, 1);
5926 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5929 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5933 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5934 ath9k_hw_set_delta_slope(ah, chan);
5936 if (AR_SREV_9280_10_OR_LATER(ah))
5937 ath9k_hw_9280_spur_mitigate(ah, chan);
5939 ath9k_hw_spur_mitigate(ah, chan);
5941 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5942 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5943 "%s: error setting board options\n", __func__);
5947 ath9k_hw_decrease_chain_power(ah, chan);
5949 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5950 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5952 | AR_STA_ID1_RTS_USE_DEF
5954 ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
5955 | ahp->ah_staId1Defaults);
5956 ath9k_hw_set_operating_mode(ah, opmode);
5958 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5959 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5961 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5963 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5964 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5965 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5967 REG_WRITE(ah, AR_ISR, ~0);
5969 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5971 if (AR_SREV_9280_10_OR_LATER(ah)) {
5972 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5975 if (!(ath9k_hw_set_channel(ah, chan)))
5979 for (i = 0; i < AR_NUM_DCU; i++)
5980 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5982 ahp->ah_intrTxqs = 0;
5983 for (i = 0; i < ah->ah_caps.halTotalQueues; i++)
5984 ath9k_hw_resettxqueue(ah, i);
5986 ath9k_hw_init_interrupt_masks(ah, opmode);
5987 ath9k_hw_init_qos(ah);
5989 ath9k_hw_init_user_settings(ah);
5991 ah->ah_opmode = opmode;
5993 REG_WRITE(ah, AR_STA_ID1,
5994 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
5996 ath9k_hw_set_dma(ah);
5998 REG_WRITE(ah, AR_OBS, 8);
6000 if (ahp->ah_intrMitigation) {
6002 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6003 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6006 ath9k_hw_init_bb(ah, chan);
6008 if (!ath9k_hw_init_cal(ah, chan))
6011 rx_chainmask = ahp->ah_rxchainmask;
6012 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6013 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6014 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6017 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6019 if (AR_SREV_9100(ah)) {
6021 mask = REG_READ(ah, AR_CFG);
6022 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6023 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6024 "%s CFG Byte Swap Set 0x%x\n", __func__,
6028 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6029 REG_WRITE(ah, AR_CFG, mask);
6030 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6031 "%s Setting CFG 0x%x\n", __func__,
6032 REG_READ(ah, AR_CFG));
6036 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6048 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6050 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6053 bool ath9k_hw_disable(struct ath_hal *ah)
6055 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6058 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6062 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6063 u8 rxchainmask, bool longcal,
6066 struct ath_hal_5416 *ahp = AH5416(ah);
6067 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6068 struct ath9k_channel *ichan =
6069 ath9k_regd_check_channel(ah, chan);
6073 if (ichan == NULL) {
6074 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6075 "%s: invalid channel %u/0x%x; no mapping\n",
6076 __func__, chan->channel, chan->channelFlags);
6081 (currCal->calState == CAL_RUNNING ||
6082 currCal->calState == CAL_WAITING)) {
6083 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6086 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6088 if (currCal->calState == CAL_WAITING) {
6090 ath9k_hw_reset_calibration(ah, currCal);
6096 ath9k_hw_getnf(ah, ichan);
6097 ath9k_hw_loadnf(ah, ah->ah_curchan);
6098 ath9k_hw_start_nfcal(ah);
6100 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6102 chan->channelFlags |= CHANNEL_CW_INT;
6103 ichan->channelFlags &= ~CHANNEL_CW_INT;
6110 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6112 struct ath_hal_5416 *ahp = AH5416(ah);
6115 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6116 ahp->ah_totalPowerMeasI[i] +=
6117 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6118 ahp->ah_totalPowerMeasQ[i] +=
6119 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6120 ahp->ah_totalIqCorrMeas[i] +=
6121 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6122 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6123 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6124 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6125 ahp->ah_totalPowerMeasQ[i],
6126 ahp->ah_totalIqCorrMeas[i]);
6130 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6132 struct ath_hal_5416 *ahp = AH5416(ah);
6135 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6136 ahp->ah_totalAdcIOddPhase[i] +=
6137 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6138 ahp->ah_totalAdcIEvenPhase[i] +=
6139 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6140 ahp->ah_totalAdcQOddPhase[i] +=
6141 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6142 ahp->ah_totalAdcQEvenPhase[i] +=
6143 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6145 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6146 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6147 "oddq=0x%08x; evenq=0x%08x;\n",
6148 ahp->ah_CalSamples, i,
6149 ahp->ah_totalAdcIOddPhase[i],
6150 ahp->ah_totalAdcIEvenPhase[i],
6151 ahp->ah_totalAdcQOddPhase[i],
6152 ahp->ah_totalAdcQEvenPhase[i]);
6156 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6158 struct ath_hal_5416 *ahp = AH5416(ah);
6161 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6162 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6163 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6164 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6165 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6166 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6167 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6168 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6169 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6171 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6172 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6173 "oddq=0x%08x; evenq=0x%08x;\n",
6174 ahp->ah_CalSamples, i,
6175 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6176 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6177 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6178 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6182 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6184 struct ath_hal_5416 *ahp = AH5416(ah);
6185 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6186 u32 qCoffDenom, iCoffDenom;
6187 int32_t qCoff, iCoff;
6190 for (i = 0; i < numChains; i++) {
6191 powerMeasI = ahp->ah_totalPowerMeasI[i];
6192 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6193 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6195 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6196 "Starting IQ Cal and Correction for Chain %d\n",
6199 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6200 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6201 i, ahp->ah_totalIqCorrMeas[i]);
6206 if (iqCorrMeas > 0x80000000) {
6207 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6211 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6212 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6213 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6214 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6215 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6218 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6219 qCoffDenom = powerMeasQ / 64;
6221 if (powerMeasQ != 0) {
6223 iCoff = iqCorrMeas / iCoffDenom;
6224 qCoff = powerMeasI / qCoffDenom - 64;
6225 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6226 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6227 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6228 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6231 iCoff = iCoff & 0x3f;
6232 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6233 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6234 if (iqCorrNeg == 0x0)
6235 iCoff = 0x40 - iCoff;
6239 else if (qCoff <= -16)
6242 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6243 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6246 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6247 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6249 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6250 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6252 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6253 "IQ Cal and Correction done for Chain %d\n",
6258 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6259 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6263 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6265 struct ath_hal_5416 *ahp = AH5416(ah);
6266 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6268 u32 qGainMismatch, iGainMismatch, val, i;
6270 for (i = 0; i < numChains; i++) {
6271 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6272 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6273 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6274 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6276 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6277 "Starting ADC Gain Cal for Chain %d\n", i);
6279 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6280 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6282 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6283 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6285 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6286 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6288 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6289 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6292 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6294 ((iEvenMeasOffset * 32) /
6295 iOddMeasOffset) & 0x3f;
6297 ((qOddMeasOffset * 32) /
6298 qEvenMeasOffset) & 0x3f;
6300 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6301 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6303 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6304 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6307 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6309 val |= (qGainMismatch) | (iGainMismatch << 6);
6310 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6312 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6313 "ADC Gain Cal done for Chain %d\n", i);
6317 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6318 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6319 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6323 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6325 struct ath_hal_5416 *ahp = AH5416(ah);
6326 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6327 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6328 const struct hal_percal_data *calData =
6329 ahp->ah_cal_list_curr->calData;
6331 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6333 for (i = 0; i < numChains; i++) {
6334 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6335 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6336 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6337 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6339 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6340 "Starting ADC DC Offset Cal for Chain %d\n", i);
6342 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6343 "Chn %d pwr_meas_odd_i = %d\n", i,
6345 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6346 "Chn %d pwr_meas_even_i = %d\n", i,
6348 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6349 "Chn %d pwr_meas_odd_q = %d\n", i,
6351 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6352 "Chn %d pwr_meas_even_q = %d\n", i,
6355 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6356 numSamples) & 0x1ff;
6357 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6358 numSamples) & 0x1ff;
6360 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6361 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6363 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6364 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6367 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6369 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6370 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6372 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6373 "ADC DC Offset Cal done for Chain %d\n", i);
6376 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6377 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6378 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6381 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6383 struct ath_hal_5416 *ahp = AH5416(ah);
6384 struct ath9k_channel *chan = ah->ah_curchan;
6386 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6388 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6389 ath9k_regd_get_ctl(ah, chan),
6390 ath9k_regd_get_antenna_allowed(ah,
6392 chan->maxRegTxPower * 2,
6393 min((u32) MAX_RATE_POWER,
6394 (u32) ah->ah_powerLimit)) != 0)
6401 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6402 struct ath9k_channel *chan,
6403 struct chan_centers *centers)
6406 struct ath_hal_5416 *ahp = AH5416(ah);
6408 if (!IS_CHAN_HT40(chan)) {
6409 centers->ctl_center = centers->ext_center =
6410 centers->synth_center = chan->channel;
6414 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6415 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6416 centers->synth_center =
6417 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6420 centers->synth_center =
6421 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6425 centers->ctl_center = centers->synth_center - (extoff *
6426 HT40_CHANNEL_CENTER_SHIFT);
6427 centers->ext_center = centers->synth_center + (extoff *
6431 ATH9K_HT_EXTPROTSPACING_20)
6433 HT40_CHANNEL_CENTER_SHIFT
6439 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6442 struct ath_hal_5416 *ahp = AH5416(ah);
6443 struct ath9k_channel *ichan =
6444 ath9k_regd_check_channel(ah, chan);
6445 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6449 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6452 if (currCal == NULL)
6455 if (ichan == NULL) {
6456 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6457 "%s: invalid channel %u/0x%x; no mapping\n",
6458 __func__, chan->channel, chan->channelFlags);
6463 if (currCal->calState != CAL_DONE) {
6464 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6465 "%s: Calibration state incorrect, %d\n",
6466 __func__, currCal->calState);
6471 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6474 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6475 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6476 __func__, currCal->calData->calType, chan->channel,
6477 chan->channelFlags);
6479 ichan->CalValid &= ~currCal->calData->calType;
6480 currCal->calState = CAL_WAITING;
6485 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6487 struct ath_hal_5416 *ahp = AH5416(ah);
6489 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6492 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6494 struct ath_hal_5416 *ahp = AH5416(ah);
6496 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6500 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6502 struct ath_hal_5416 *ahp = AH5416(ah);
6504 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6508 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6510 struct ath_hal_5416 *ahp = AH5416(ah);
6512 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6514 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6515 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6520 #ifdef CONFIG_ATH9K_RFKILL
6521 static void ath9k_enable_rfkill(struct ath_hal *ah)
6523 struct ath_hal_5416 *ahp = AH5416(ah);
6525 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6526 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6528 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6529 AR_GPIO_INPUT_MUX2_RFSILENT);
6531 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6532 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6534 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6536 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6539 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6546 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6549 struct ath_hal_5416 *ahp = AH5416(ah);
6551 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6552 ahp->ah_assocId = assocId;
6554 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6555 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6556 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6559 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6563 tsf = REG_READ(ah, AR_TSF_U32);
6564 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6568 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6573 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6576 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6577 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6583 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6586 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6588 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6591 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6593 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6597 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6598 enum ath9k_ant_setting settings,
6599 struct ath9k_channel *chan,
6604 struct ath_hal_5416 *ahp = AH5416(ah);
6605 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6607 if (AR_SREV_9280(ah)) {
6608 if (!tx_chainmask_cfg) {
6610 tx_chainmask_cfg = *tx_chainmask;
6611 rx_chainmask_cfg = *rx_chainmask;
6615 case ATH9K_ANT_FIXED_A:
6616 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6617 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6618 *antenna_cfgd = true;
6620 case ATH9K_ANT_FIXED_B:
6621 if (ah->ah_caps.halTxChainMask >
6622 ATH9K_ANTENNA1_CHAINMASK) {
6623 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6625 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6626 *antenna_cfgd = true;
6628 case ATH9K_ANT_VARIABLE:
6629 *tx_chainmask = tx_chainmask_cfg;
6630 *rx_chainmask = rx_chainmask_cfg;
6631 *antenna_cfgd = true;
6637 ahp->ah_diversityControl = settings;
6643 void ath9k_hw_setopmode(struct ath_hal *ah)
6645 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6649 ath9k_hw_getcapability(struct ath_hal *ah, enum hal_capability_type type,
6650 u32 capability, u32 *result)
6652 struct ath_hal_5416 *ahp = AH5416(ah);
6653 const struct hal_capabilities *pCap = &ah->ah_caps;
6656 case HAL_CAP_CIPHER:
6657 switch (capability) {
6658 case ATH9K_CIPHER_AES_CCM:
6659 case ATH9K_CIPHER_AES_OCB:
6660 case ATH9K_CIPHER_TKIP:
6661 case ATH9K_CIPHER_WEP:
6662 case ATH9K_CIPHER_MIC:
6663 case ATH9K_CIPHER_CLR:
6668 case HAL_CAP_TKIP_MIC:
6669 switch (capability) {
6673 return (ahp->ah_staId1Defaults &
6674 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6677 case HAL_CAP_TKIP_SPLIT:
6678 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6680 case HAL_CAP_WME_TKIPMIC:
6682 case HAL_CAP_PHYCOUNTERS:
6683 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6684 case HAL_CAP_DIVERSITY:
6685 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6686 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6688 case HAL_CAP_PHYDIAG:
6690 case HAL_CAP_MCAST_KEYSRCH:
6691 switch (capability) {
6695 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6698 return (ahp->ah_staId1Defaults &
6699 AR_STA_ID1_MCAST_KSRCH) ? true :
6704 case HAL_CAP_TSF_ADJUST:
6705 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6707 case HAL_CAP_RFSILENT:
6708 if (capability == 3)
6710 case HAL_CAP_ANT_CFG_2GHZ:
6711 *result = pCap->halNumAntCfg2GHz;
6713 case HAL_CAP_ANT_CFG_5GHZ:
6714 *result = pCap->halNumAntCfg5GHz;
6717 switch (capability) {
6721 *result = ah->ah_powerLimit;
6724 *result = ah->ah_maxPowerLevel;
6727 *result = ah->ah_tpScale;
6737 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6739 struct ath_hal_5416 *ahp = AH5416(ah);
6740 struct ath9k_channel *chan = ah->ah_curchan;
6741 const struct hal_capabilities *pCap = &ah->ah_caps;
6743 u32 halNumAntConfig;
6746 IS_CHAN_2GHZ(chan) ? pCap->halNumAntCfg2GHz : pCap->
6749 if (cfg < halNumAntConfig) {
6750 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6751 cfg, &ant_config)) {
6752 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6760 bool ath9k_hw_intrpend(struct ath_hal *ah)
6764 if (AR_SREV_9100(ah))
6767 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6768 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6771 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6772 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6773 && (host_isr != AR_INTR_SPURIOUS))
6779 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6783 struct hal_capabilities *pCap = &ah->ah_caps;
6785 bool fatal_int = false;
6787 if (!AR_SREV_9100(ah)) {
6788 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6789 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6790 == AR_RTC_STATUS_ON) {
6791 isr = REG_READ(ah, AR_ISR);
6797 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6801 if (!isr && !sync_cause)
6805 isr = REG_READ(ah, AR_ISR);
6809 struct ath_hal_5416 *ahp = AH5416(ah);
6811 if (isr & AR_ISR_BCNMISC) {
6813 isr2 = REG_READ(ah, AR_ISR_S2);
6814 if (isr2 & AR_ISR_S2_TIM)
6815 mask2 |= ATH9K_INT_TIM;
6816 if (isr2 & AR_ISR_S2_DTIM)
6817 mask2 |= ATH9K_INT_DTIM;
6818 if (isr2 & AR_ISR_S2_DTIMSYNC)
6819 mask2 |= ATH9K_INT_DTIMSYNC;
6820 if (isr2 & (AR_ISR_S2_CABEND))
6821 mask2 |= ATH9K_INT_CABEND;
6822 if (isr2 & AR_ISR_S2_GTT)
6823 mask2 |= ATH9K_INT_GTT;
6824 if (isr2 & AR_ISR_S2_CST)
6825 mask2 |= ATH9K_INT_CST;
6828 isr = REG_READ(ah, AR_ISR_RAC);
6829 if (isr == 0xffffffff) {
6834 *masked = isr & ATH9K_INT_COMMON;
6836 if (ahp->ah_intrMitigation) {
6838 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6839 *masked |= ATH9K_INT_RX;
6842 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6843 *masked |= ATH9K_INT_RX;
6845 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6849 *masked |= ATH9K_INT_TX;
6851 s0_s = REG_READ(ah, AR_ISR_S0_S);
6852 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6853 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6855 s1_s = REG_READ(ah, AR_ISR_S1_S);
6856 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6857 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6860 if (isr & AR_ISR_RXORN) {
6861 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6862 "%s: receive FIFO overrun interrupt\n",
6866 if (!AR_SREV_9100(ah)) {
6867 if (!pCap->halAutoSleepSupport) {
6868 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6869 if (isr5 & AR_ISR_S5_TIM_TIMER)
6870 *masked |= ATH9K_INT_TIM_TIMER;
6876 if (AR_SREV_9100(ah))
6881 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6885 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6886 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6887 "%s: received PCI FATAL interrupt\n",
6890 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6891 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6892 "%s: received PCI PERR interrupt\n",
6896 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6897 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6898 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6900 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6901 REG_WRITE(ah, AR_RC, 0);
6902 *masked |= ATH9K_INT_FATAL;
6904 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6905 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6906 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6910 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6911 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6916 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6918 return AH5416(ah)->ah_maskReg;
6921 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6923 struct ath_hal_5416 *ahp = AH5416(ah);
6924 u32 omask = ahp->ah_maskReg;
6926 struct hal_capabilities *pCap = &ah->ah_caps;
6928 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6931 if (omask & ATH9K_INT_GLOBAL) {
6932 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6934 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6935 (void) REG_READ(ah, AR_IER);
6936 if (!AR_SREV_9100(ah)) {
6937 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6938 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6940 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6941 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6945 mask = ints & ATH9K_INT_COMMON;
6948 if (ints & ATH9K_INT_TX) {
6949 if (ahp->ah_txOkInterruptMask)
6950 mask |= AR_IMR_TXOK;
6951 if (ahp->ah_txDescInterruptMask)
6952 mask |= AR_IMR_TXDESC;
6953 if (ahp->ah_txErrInterruptMask)
6954 mask |= AR_IMR_TXERR;
6955 if (ahp->ah_txEolInterruptMask)
6956 mask |= AR_IMR_TXEOL;
6958 if (ints & ATH9K_INT_RX) {
6959 mask |= AR_IMR_RXERR;
6960 if (ahp->ah_intrMitigation)
6961 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6963 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6964 if (!pCap->halAutoSleepSupport)
6965 mask |= AR_IMR_GENTMR;
6968 if (ints & (ATH9K_INT_BMISC)) {
6969 mask |= AR_IMR_BCNMISC;
6970 if (ints & ATH9K_INT_TIM)
6971 mask2 |= AR_IMR_S2_TIM;
6972 if (ints & ATH9K_INT_DTIM)
6973 mask2 |= AR_IMR_S2_DTIM;
6974 if (ints & ATH9K_INT_DTIMSYNC)
6975 mask2 |= AR_IMR_S2_DTIMSYNC;
6976 if (ints & ATH9K_INT_CABEND)
6977 mask2 |= (AR_IMR_S2_CABEND);
6980 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6981 mask |= AR_IMR_BCNMISC;
6982 if (ints & ATH9K_INT_GTT)
6983 mask2 |= AR_IMR_S2_GTT;
6984 if (ints & ATH9K_INT_CST)
6985 mask2 |= AR_IMR_S2_CST;
6988 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
6990 REG_WRITE(ah, AR_IMR, mask);
6991 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
6993 AR_IMR_S2_DTIMSYNC |
6997 AR_IMR_S2_GTT | AR_IMR_S2_CST);
6998 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
6999 ahp->ah_maskReg = ints;
7001 if (!pCap->halAutoSleepSupport) {
7002 if (ints & ATH9K_INT_TIM_TIMER)
7003 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7005 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7008 if (ints & ATH9K_INT_GLOBAL) {
7009 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7011 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7012 if (!AR_SREV_9100(ah)) {
7013 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7015 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7018 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7019 AR_INTR_SYNC_DEFAULT);
7020 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7021 AR_INTR_SYNC_DEFAULT);
7023 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7024 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7031 ath9k_hw_beaconinit(struct ath_hal *ah,
7032 u32 next_beacon, u32 beacon_period)
7034 struct ath_hal_5416 *ahp = AH5416(ah);
7037 ahp->ah_beaconInterval = beacon_period;
7039 switch (ah->ah_opmode) {
7041 case ATH9K_M_MONITOR:
7042 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7043 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7044 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7045 flags |= AR_TBTT_TIMER_EN;
7048 REG_SET_BIT(ah, AR_TXCFG,
7049 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7050 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7051 TU_TO_USEC(next_beacon +
7052 (ahp->ah_atimWindow ? ahp->
7053 ah_atimWindow : 1)));
7054 flags |= AR_NDP_TIMER_EN;
7055 case ATH9K_M_HOSTAP:
7056 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7057 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7058 TU_TO_USEC(next_beacon -
7060 ath_hal_dma_beacon_response_time));
7061 REG_WRITE(ah, AR_NEXT_SWBA,
7062 TU_TO_USEC(next_beacon -
7064 ath_hal_sw_beacon_response_time));
7066 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7070 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7071 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7072 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7073 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7075 beacon_period &= ~ATH9K_BEACON_ENA;
7076 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7077 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7078 ath9k_hw_reset_tsf(ah);
7081 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7085 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7086 const struct ath9k_beacon_state *bs)
7088 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7089 struct hal_capabilities *pCap = &ah->ah_caps;
7091 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7093 REG_WRITE(ah, AR_BEACON_PERIOD,
7094 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7095 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7096 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7098 REG_RMW_FIELD(ah, AR_RSSI_THR,
7099 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7101 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7103 if (bs->bs_sleepduration > beaconintval)
7104 beaconintval = bs->bs_sleepduration;
7106 dtimperiod = bs->bs_dtimperiod;
7107 if (bs->bs_sleepduration > dtimperiod)
7108 dtimperiod = bs->bs_sleepduration;
7110 if (beaconintval == dtimperiod)
7111 nextTbtt = bs->bs_nextdtim;
7113 nextTbtt = bs->bs_nexttbtt;
7115 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7117 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7119 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7121 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7124 REG_WRITE(ah, AR_NEXT_DTIM,
7125 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7126 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7128 REG_WRITE(ah, AR_SLEEP1,
7129 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7130 | AR_SLEEP1_ASSUME_DTIM);
7132 if (pCap->halAutoSleepSupport)
7133 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7135 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7137 REG_WRITE(ah, AR_SLEEP2,
7138 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7140 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7141 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7143 REG_SET_BIT(ah, AR_TIMER_MODE,
7144 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7149 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7151 if (entry < ah->ah_caps.halKeyCacheSize) {
7152 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7153 if (val & AR_KEYTABLE_VALID)
7159 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7163 if (entry >= ah->ah_caps.halKeyCacheSize) {
7164 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7165 "%s: entry %u out of range\n", __func__, entry);
7168 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7170 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7171 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7172 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7173 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7174 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7175 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7176 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7177 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7179 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7180 u16 micentry = entry + 64;
7182 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7183 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7184 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7185 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7189 if (ah->ah_curchan == NULL)
7196 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7201 if (entry >= ah->ah_caps.halKeyCacheSize) {
7202 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7203 "%s: entry %u out of range\n", __func__, entry);
7208 macHi = (mac[5] << 8) | mac[4];
7209 macLo = (mac[3] << 24) | (mac[2] << 16)
7210 | (mac[1] << 8) | mac[0];
7212 macLo |= (macHi & 1) << 31;
7217 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7218 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7224 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7225 const struct ath9k_keyval *k,
7226 const u8 *mac, int xorKey)
7228 const struct hal_capabilities *pCap = &ah->ah_caps;
7229 u32 key0, key1, key2, key3, key4;
7231 u32 xorMask = xorKey ?
7232 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7233 | ATH9K_KEY_XOR) : 0;
7234 struct ath_hal_5416 *ahp = AH5416(ah);
7236 if (entry >= pCap->halKeyCacheSize) {
7237 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7238 "%s: entry %u out of range\n", __func__, entry);
7241 switch (k->kv_type) {
7242 case ATH9K_CIPHER_AES_OCB:
7243 keyType = AR_KEYTABLE_TYPE_AES;
7245 case ATH9K_CIPHER_AES_CCM:
7246 if (!pCap->halCipherAesCcmSupport) {
7247 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7248 "%s: AES-CCM not supported by "
7249 "mac rev 0x%x\n", __func__,
7253 keyType = AR_KEYTABLE_TYPE_CCM;
7255 case ATH9K_CIPHER_TKIP:
7256 keyType = AR_KEYTABLE_TYPE_TKIP;
7257 if (ATH9K_IS_MIC_ENABLED(ah)
7258 && entry + 64 >= pCap->halKeyCacheSize) {
7259 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260 "%s: entry %u inappropriate for TKIP\n",
7265 case ATH9K_CIPHER_WEP:
7266 if (k->kv_len < 40 / NBBY) {
7267 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7268 "%s: WEP key length %u too small\n",
7269 __func__, k->kv_len);
7272 if (k->kv_len <= 40 / NBBY)
7273 keyType = AR_KEYTABLE_TYPE_40;
7274 else if (k->kv_len <= 104 / NBBY)
7275 keyType = AR_KEYTABLE_TYPE_104;
7277 keyType = AR_KEYTABLE_TYPE_128;
7279 case ATH9K_CIPHER_CLR:
7280 keyType = AR_KEYTABLE_TYPE_CLR;
7283 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7284 "%s: cipher %u not supported\n", __func__,
7289 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7290 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7291 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7292 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7293 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7294 if (k->kv_len <= 104 / NBBY)
7297 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7298 u16 micentry = entry + 64;
7300 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7301 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7302 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7303 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7304 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7305 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7306 (void) ath9k_hw_keysetmac(ah, entry, mac);
7308 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7309 u32 mic0, mic1, mic2, mic3, mic4;
7311 mic0 = get_unaligned_le32(k->kv_mic + 0);
7312 mic2 = get_unaligned_le32(k->kv_mic + 4);
7313 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7314 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7315 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7316 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7317 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7318 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7319 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7320 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7321 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7322 AR_KEYTABLE_TYPE_CLR);
7327 mic0 = get_unaligned_le32(k->kv_mic + 0);
7328 mic2 = get_unaligned_le32(k->kv_mic + 4);
7329 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7330 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7331 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7332 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7333 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7334 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7335 AR_KEYTABLE_TYPE_CLR);
7337 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7338 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7342 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7343 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7344 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7345 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7346 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7347 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7349 (void) ath9k_hw_keysetmac(ah, entry, mac);
7352 if (ah->ah_curchan == NULL)
7359 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7361 struct ath_hal_5416 *ahp = AH5416(ah);
7362 u32 txcfg, curLevel, newLevel;
7363 enum ath9k_int omask;
7365 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7368 omask = ath9k_hw_set_interrupts(ah,
7369 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7371 txcfg = REG_READ(ah, AR_TXCFG);
7372 curLevel = MS(txcfg, AR_FTRIG);
7373 newLevel = curLevel;
7374 if (bIncTrigLevel) {
7375 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7377 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7379 if (newLevel != curLevel)
7380 REG_WRITE(ah, AR_TXCFG,
7381 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7383 ath9k_hw_set_interrupts(ah, omask);
7385 ah->ah_txTrigLevel = newLevel;
7387 return newLevel != curLevel;
7390 static bool ath9k_hw_set_txq_props(struct ath_hal *ah,
7391 struct ath9k_tx_queue_info *qi,
7392 const struct ath9k_txq_info *qInfo)
7396 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7397 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7402 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7404 qi->tqi_ver = qInfo->tqi_ver;
7405 qi->tqi_subtype = qInfo->tqi_subtype;
7406 qi->tqi_qflags = qInfo->tqi_qflags;
7407 qi->tqi_priority = qInfo->tqi_priority;
7408 if (qInfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7409 qi->tqi_aifs = min(qInfo->tqi_aifs, 255U);
7411 qi->tqi_aifs = INIT_AIFS;
7412 if (qInfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7413 cw = min(qInfo->tqi_cwmin, 1024U);
7415 while (qi->tqi_cwmin < cw)
7416 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7418 qi->tqi_cwmin = qInfo->tqi_cwmin;
7419 if (qInfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7420 cw = min(qInfo->tqi_cwmax, 1024U);
7422 while (qi->tqi_cwmax < cw)
7423 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7425 qi->tqi_cwmax = INIT_CWMAX;
7427 if (qInfo->tqi_shretry != 0)
7428 qi->tqi_shretry = min((u32) qInfo->tqi_shretry, 15U);
7430 qi->tqi_shretry = INIT_SH_RETRY;
7431 if (qInfo->tqi_lgretry != 0)
7432 qi->tqi_lgretry = min((u32) qInfo->tqi_lgretry, 15U);
7434 qi->tqi_lgretry = INIT_LG_RETRY;
7435 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
7436 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
7437 qi->tqi_burstTime = qInfo->tqi_burstTime;
7438 qi->tqi_readyTime = qInfo->tqi_readyTime;
7440 switch (qInfo->tqi_subtype) {
7441 case ATH9K_WME_UPSD:
7442 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7443 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7451 bool ath9k_hw_settxqueueprops(struct ath_hal *ah, int q,
7452 const struct ath9k_txq_info *qInfo)
7454 struct ath_hal_5416 *ahp = AH5416(ah);
7455 struct hal_capabilities *pCap = &ah->ah_caps;
7457 if (q >= pCap->halTotalQueues) {
7458 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7462 return ath9k_hw_set_txq_props(ah, &ahp->ah_txq[q], qInfo);
7465 static bool ath9k_hw_get_txq_props(struct ath_hal *ah,
7466 struct ath9k_txq_info *qInfo,
7467 const struct ath9k_tx_queue_info *qi)
7469 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7470 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7475 qInfo->tqi_qflags = qi->tqi_qflags;
7476 qInfo->tqi_ver = qi->tqi_ver;
7477 qInfo->tqi_subtype = qi->tqi_subtype;
7478 qInfo->tqi_qflags = qi->tqi_qflags;
7479 qInfo->tqi_priority = qi->tqi_priority;
7480 qInfo->tqi_aifs = qi->tqi_aifs;
7481 qInfo->tqi_cwmin = qi->tqi_cwmin;
7482 qInfo->tqi_cwmax = qi->tqi_cwmax;
7483 qInfo->tqi_shretry = qi->tqi_shretry;
7484 qInfo->tqi_lgretry = qi->tqi_lgretry;
7485 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7486 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7487 qInfo->tqi_burstTime = qi->tqi_burstTime;
7488 qInfo->tqi_readyTime = qi->tqi_readyTime;
7494 ath9k_hw_gettxqueueprops(struct ath_hal *ah, int q,
7495 struct ath9k_txq_info *qInfo)
7497 struct ath_hal_5416 *ahp = AH5416(ah);
7498 struct hal_capabilities *pCap = &ah->ah_caps;
7500 if (q >= pCap->halTotalQueues) {
7501 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7505 return ath9k_hw_get_txq_props(ah, qInfo, &ahp->ah_txq[q]);
7509 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7510 const struct ath9k_txq_info *qInfo)
7512 struct ath_hal_5416 *ahp = AH5416(ah);
7513 struct ath9k_tx_queue_info *qi;
7514 struct hal_capabilities *pCap = &ah->ah_caps;
7518 case ATH9K_TX_QUEUE_BEACON:
7519 q = pCap->halTotalQueues - 1;
7521 case ATH9K_TX_QUEUE_CAB:
7522 q = pCap->halTotalQueues - 2;
7524 case ATH9K_TX_QUEUE_PSPOLL:
7527 case ATH9K_TX_QUEUE_UAPSD:
7528 q = pCap->halTotalQueues - 3;
7530 case ATH9K_TX_QUEUE_DATA:
7531 for (q = 0; q < pCap->halTotalQueues; q++)
7532 if (ahp->ah_txq[q].tqi_type ==
7533 ATH9K_TX_QUEUE_INACTIVE)
7535 if (q == pCap->halTotalQueues) {
7536 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7537 "%s: no available tx queue\n", __func__);
7542 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7547 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7549 qi = &ahp->ah_txq[q];
7550 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7551 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7552 "%s: tx queue %u already active\n", __func__, q);
7555 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7556 qi->tqi_type = type;
7557 if (qInfo == NULL) {
7559 TXQ_FLAG_TXOKINT_ENABLE
7560 | TXQ_FLAG_TXERRINT_ENABLE
7561 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7562 qi->tqi_aifs = INIT_AIFS;
7563 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7564 qi->tqi_cwmax = INIT_CWMAX;
7565 qi->tqi_shretry = INIT_SH_RETRY;
7566 qi->tqi_lgretry = INIT_LG_RETRY;
7567 qi->tqi_physCompBuf = 0;
7569 qi->tqi_physCompBuf = qInfo->tqi_compBuf;
7570 (void) ath9k_hw_settxqueueprops(ah, q, qInfo);
7577 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7578 struct ath9k_tx_queue_info *qi)
7580 struct ath_hal_5416 *ahp = AH5416(ah);
7582 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7583 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7584 __func__, ahp->ah_txOkInterruptMask,
7585 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7586 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7588 REG_WRITE(ah, AR_IMR_S0,
7589 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7590 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7591 REG_WRITE(ah, AR_IMR_S1,
7592 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7593 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7594 REG_RMW_FIELD(ah, AR_IMR_S2,
7595 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7598 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7600 struct ath_hal_5416 *ahp = AH5416(ah);
7601 struct hal_capabilities *pCap = &ah->ah_caps;
7602 struct ath9k_tx_queue_info *qi;
7604 if (q >= pCap->halTotalQueues) {
7605 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7609 qi = &ahp->ah_txq[q];
7610 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7611 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7616 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7619 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7620 ahp->ah_txOkInterruptMask &= ~(1 << q);
7621 ahp->ah_txErrInterruptMask &= ~(1 << q);
7622 ahp->ah_txDescInterruptMask &= ~(1 << q);
7623 ahp->ah_txEolInterruptMask &= ~(1 << q);
7624 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7625 ath9k_hw_set_txq_interrupts(ah, qi);
7630 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7632 struct ath_hal_5416 *ahp = AH5416(ah);
7633 struct hal_capabilities *pCap = &ah->ah_caps;
7634 struct ath9k_channel *chan = ah->ah_curchan;
7635 struct ath9k_tx_queue_info *qi;
7636 u32 cwMin, chanCwMin, value;
7638 if (q >= pCap->halTotalQueues) {
7639 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7643 qi = &ahp->ah_txq[q];
7644 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7645 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7650 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7652 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7653 if (chan && IS_CHAN_B(chan))
7654 chanCwMin = INIT_CWMIN_11B;
7656 chanCwMin = INIT_CWMIN;
7658 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7660 cwMin = qi->tqi_cwmin;
7662 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7663 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7664 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7666 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7667 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7668 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7669 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7672 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7673 REG_WRITE(ah, AR_DMISC(q),
7674 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7676 if (qi->tqi_cbrPeriod) {
7677 REG_WRITE(ah, AR_QCBRCFG(q),
7678 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7679 | SM(qi->tqi_cbrOverflowLimit,
7680 AR_Q_CBRCFG_OVF_THRESH));
7681 REG_WRITE(ah, AR_QMISC(q),
7683 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7684 tqi_cbrOverflowLimit
7686 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7690 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7691 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7692 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7693 AR_Q_RDYTIMECFG_EN);
7696 REG_WRITE(ah, AR_DCHNTIME(q),
7697 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7698 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7700 if (qi->tqi_burstTime
7701 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7702 REG_WRITE(ah, AR_QMISC(q),
7705 AR_Q_MISC_RDYTIME_EXP_POLICY);
7709 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7710 REG_WRITE(ah, AR_DMISC(q),
7711 REG_READ(ah, AR_DMISC(q)) |
7712 AR_D_MISC_POST_FR_BKOFF_DIS);
7714 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7715 REG_WRITE(ah, AR_DMISC(q),
7716 REG_READ(ah, AR_DMISC(q)) |
7717 AR_D_MISC_FRAG_BKOFF_EN);
7719 switch (qi->tqi_type) {
7720 case ATH9K_TX_QUEUE_BEACON:
7721 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7722 | AR_Q_MISC_FSP_DBA_GATED
7723 | AR_Q_MISC_BEACON_USE
7724 | AR_Q_MISC_CBR_INCR_DIS1);
7726 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7727 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7728 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7729 | AR_D_MISC_BEACON_USE
7730 | AR_D_MISC_POST_FR_BKOFF_DIS);
7732 case ATH9K_TX_QUEUE_CAB:
7733 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7734 | AR_Q_MISC_FSP_DBA_GATED
7735 | AR_Q_MISC_CBR_INCR_DIS1
7736 | AR_Q_MISC_CBR_INCR_DIS0);
7737 value = (qi->tqi_readyTime
7738 - (ah->ah_config.ath_hal_sw_beacon_response_time -
7739 ah->ah_config.ath_hal_dma_beacon_response_time)
7741 ah->ah_config.ath_hal_additional_swba_backoff) *
7743 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7744 value | AR_Q_RDYTIMECFG_EN);
7745 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7746 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7747 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7749 case ATH9K_TX_QUEUE_PSPOLL:
7750 REG_WRITE(ah, AR_QMISC(q),
7752 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7754 case ATH9K_TX_QUEUE_UAPSD:
7755 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7756 | AR_D_MISC_POST_FR_BKOFF_DIS);
7762 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7763 REG_WRITE(ah, AR_DMISC(q),
7764 REG_READ(ah, AR_DMISC(q)) |
7765 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7766 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7767 AR_D_MISC_POST_FR_BKOFF_DIS);
7770 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7771 ahp->ah_txOkInterruptMask |= 1 << q;
7773 ahp->ah_txOkInterruptMask &= ~(1 << q);
7774 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7775 ahp->ah_txErrInterruptMask |= 1 << q;
7777 ahp->ah_txErrInterruptMask &= ~(1 << q);
7778 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7779 ahp->ah_txDescInterruptMask |= 1 << q;
7781 ahp->ah_txDescInterruptMask &= ~(1 << q);
7782 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7783 ahp->ah_txEolInterruptMask |= 1 << q;
7785 ahp->ah_txEolInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7787 ahp->ah_txUrnInterruptMask |= 1 << q;
7789 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7790 ath9k_hw_set_txq_interrupts(ah, qi);
7795 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7797 struct ath_hal_5416 *ahp = AH5416(ah);
7798 *txqs &= ahp->ah_intrTxqs;
7799 ahp->ah_intrTxqs &= ~(*txqs);
7803 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7804 u32 segLen, bool firstSeg,
7805 bool lastSeg, const struct ath_desc *ds0)
7807 struct ar5416_desc *ads = AR5416DESC(ds);
7810 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7811 } else if (lastSeg) {
7813 ads->ds_ctl1 = segLen;
7814 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7815 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7818 ads->ds_ctl1 = segLen | AR_TxMore;
7822 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7823 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7824 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7825 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7826 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7830 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7832 struct ar5416_desc *ads = AR5416DESC(ds);
7834 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7835 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7836 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7837 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7838 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7842 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7844 struct ar5416_desc *ads = AR5416DESC(ds);
7846 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7847 return -EINPROGRESS;
7849 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7850 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7851 ds->ds_txstat.ts_status = 0;
7852 ds->ds_txstat.ts_flags = 0;
7854 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7855 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7856 if (ads->ds_txstatus1 & AR_Filtered)
7857 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7858 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7859 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7860 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7861 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7862 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7863 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7865 if (ads->ds_txstatus1 & AR_DescCfgErr)
7866 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7867 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7868 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7869 ath9k_hw_updatetxtriglevel(ah, true);
7871 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7872 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7873 ath9k_hw_updatetxtriglevel(ah, true);
7875 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7876 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7877 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7878 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7881 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7882 switch (ds->ds_txstat.ts_rateindex) {
7884 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7887 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7890 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7893 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7897 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7898 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7899 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7900 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7901 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7902 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7903 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7904 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7905 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7906 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7907 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7908 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7909 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7910 ds->ds_txstat.ts_antenna = 1;
7916 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7917 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7918 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7920 struct ar5416_desc *ads = AR5416DESC(ds);
7921 struct ath_hal_5416 *ahp = AH5416(ah);
7923 txPower += ahp->ah_txPowerIndexOffset;
7927 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7928 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7929 | SM(txPower, AR_XmitPower)
7930 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7931 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7932 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7933 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7936 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7937 | SM(type, AR_FrameType)
7938 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7939 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7940 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7942 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7944 if (AR_SREV_9285(ah)) {
7954 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7955 struct ath_desc *lastds,
7956 u32 durUpdateEn, u32 rtsctsRate,
7958 struct ath9k_11n_rate_series series[],
7959 u32 nseries, u32 flags)
7961 struct ar5416_desc *ads = AR5416DESC(ds);
7962 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7966 (void) rtsctsDuration;
7968 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7969 ds_ctl0 = ads->ds_ctl0;
7971 if (flags & ATH9K_TXDESC_RTSENA) {
7972 ds_ctl0 &= ~AR_CTSEnable;
7973 ds_ctl0 |= AR_RTSEnable;
7975 ds_ctl0 &= ~AR_RTSEnable;
7976 ds_ctl0 |= AR_CTSEnable;
7979 ads->ds_ctl0 = ds_ctl0;
7982 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7985 ads->ds_ctl2 = set11nTries(series, 0)
7986 | set11nTries(series, 1)
7987 | set11nTries(series, 2)
7988 | set11nTries(series, 3)
7989 | (durUpdateEn ? AR_DurUpdateEna : 0)
7990 | SM(0, AR_BurstDur);
7992 ads->ds_ctl3 = set11nRate(series, 0)
7993 | set11nRate(series, 1)
7994 | set11nRate(series, 2)
7995 | set11nRate(series, 3);
7997 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
7998 | set11nPktDurRTSCTS(series, 1);
8000 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8001 | set11nPktDurRTSCTS(series, 3);
8003 ads->ds_ctl7 = set11nRateFlags(series, 0)
8004 | set11nRateFlags(series, 1)
8005 | set11nRateFlags(series, 2)
8006 | set11nRateFlags(series, 3)
8007 | SM(rtsctsRate, AR_RTSCTSRate);
8008 last_ads->ds_ctl2 = ads->ds_ctl2;
8009 last_ads->ds_ctl3 = ads->ds_ctl3;
8013 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8016 struct ar5416_desc *ads = AR5416DESC(ds);
8018 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8020 ads->ds_ctl6 &= ~AR_AggrLen;
8021 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8025 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8028 struct ar5416_desc *ads = AR5416DESC(ds);
8031 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8033 ctl6 = ads->ds_ctl6;
8034 ctl6 &= ~AR_PadDelim;
8035 ctl6 |= SM(numDelims, AR_PadDelim);
8036 ads->ds_ctl6 = ctl6;
8039 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8041 struct ar5416_desc *ads = AR5416DESC(ds);
8043 ads->ds_ctl1 |= AR_IsAggr;
8044 ads->ds_ctl1 &= ~AR_MoreAggr;
8045 ads->ds_ctl6 &= ~AR_PadDelim;
8048 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8050 struct ar5416_desc *ads = AR5416DESC(ds);
8052 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8056 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8059 struct ar5416_desc *ads = AR5416DESC(ds);
8061 ads->ds_ctl2 &= ~AR_BurstDur;
8062 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8066 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8069 struct ar5416_desc *ads = AR5416DESC(ds);
8072 ads->ds_ctl0 |= AR_VirtMoreFrag;
8074 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8077 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8079 REG_WRITE(ah, AR_RXDP, rxdp);
8082 void ath9k_hw_rxena(struct ath_hal *ah)
8084 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8087 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8091 REG_SET_BIT(ah, AR_DIAG_SW,
8092 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8095 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8098 REG_CLR_BIT(ah, AR_DIAG_SW,
8102 reg = REG_READ(ah, AR_OBS_BUS_1);
8103 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8104 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8110 REG_CLR_BIT(ah, AR_DIAG_SW,
8111 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8118 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8121 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8122 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8126 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8127 u32 size, u32 flags)
8129 struct ar5416_desc *ads = AR5416DESC(ds);
8130 struct hal_capabilities *pCap = &ah->ah_caps;
8132 ads->ds_ctl1 = size & AR_BufLen;
8133 if (flags & ATH9K_RXDESC_INTREQ)
8134 ads->ds_ctl1 |= AR_RxIntrReq;
8136 ads->ds_rxstatus8 &= ~AR_RxDone;
8137 if (!pCap->halAutoSleepSupport)
8138 memset(&(ads->u), 0, sizeof(ads->u));
8143 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8144 u32 pa, struct ath_desc *nds, u64 tsf)
8146 struct ar5416_desc ads;
8147 struct ar5416_desc *adsp = AR5416DESC(ds);
8149 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8150 return -EINPROGRESS;
8152 ads.u.rx = adsp->u.rx;
8154 ds->ds_rxstat.rs_status = 0;
8155 ds->ds_rxstat.rs_flags = 0;
8157 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8158 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8160 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8161 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8162 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8163 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8164 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8165 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8166 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8167 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8168 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8170 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8172 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8173 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8175 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8176 ds->ds_rxstat.rs_moreaggr =
8177 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8178 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8179 ds->ds_rxstat.rs_flags =
8180 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8181 ds->ds_rxstat.rs_flags |=
8182 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8184 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8185 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8186 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8187 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8188 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8189 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8191 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8193 if (ads.ds_rxstatus8 & AR_CRCErr)
8194 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8195 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8198 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8199 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8200 ds->ds_rxstat.rs_phyerr = phyerr;
8201 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8202 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8203 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8204 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8210 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8211 struct ath9k_rate_table *rt)
8215 if (rt->rateCodeToIndex[0] != 0)
8217 for (i = 0; i < 256; i++)
8218 rt->rateCodeToIndex[i] = (u8) -1;
8219 for (i = 0; i < rt->rateCount; i++) {
8220 u8 code = rt->info[i].rateCode;
8221 u8 cix = rt->info[i].controlRate;
8223 rt->rateCodeToIndex[code] = i;
8224 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8226 rt->info[i].lpAckDuration =
8227 ath9k_hw_computetxtime(ah, rt,
8228 WLAN_CTRL_FRAME_SIZE,
8231 rt->info[i].spAckDuration =
8232 ath9k_hw_computetxtime(ah, rt,
8233 WLAN_CTRL_FRAME_SIZE,
8239 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8242 struct ath9k_rate_table *rt;
8244 case ATH9K_MODE_SEL_11A:
8245 rt = &ar5416_11a_table;
8247 case ATH9K_MODE_SEL_11B:
8248 rt = &ar5416_11b_table;
8250 case ATH9K_MODE_SEL_11G:
8251 rt = &ar5416_11g_table;
8253 case ATH9K_MODE_SEL_11NG_HT20:
8254 case ATH9K_MODE_SEL_11NG_HT40PLUS:
8255 case ATH9K_MODE_SEL_11NG_HT40MINUS:
8256 rt = &ar5416_11ng_table;
8258 case ATH9K_MODE_SEL_11NA_HT20:
8259 case ATH9K_MODE_SEL_11NA_HT40PLUS:
8260 case ATH9K_MODE_SEL_11NA_HT40MINUS:
8261 rt = &ar5416_11na_table;
8264 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8268 ath9k_hw_setup_rate_table(ah, rt);
8272 static const char *ath9k_hw_devname(u16 devid)
8275 case AR5416_DEVID_PCI:
8276 case AR5416_DEVID_PCIE:
8277 return "Atheros 5416";
8278 case AR9160_DEVID_PCI:
8279 return "Atheros 9160";
8280 case AR9280_DEVID_PCI:
8281 case AR9280_DEVID_PCIE:
8282 return "Atheros 9280";
8287 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8289 return vendorid == ATHEROS_VENDOR_ID ?
8290 ath9k_hw_devname(devid) : NULL;
8293 struct ath_hal *ath9k_hw_attach(u16 devid,
8294 struct ath_softc *sc,
8298 struct ath_hal *ah = NULL;
8301 case AR5416_DEVID_PCI:
8302 case AR5416_DEVID_PCIE:
8303 case AR9160_DEVID_PCI:
8304 case AR9280_DEVID_PCI:
8305 case AR9280_DEVID_PCIE:
8306 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8309 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8310 "devid=0x%x not supported.\n", devid);
8316 ah->ah_devid = ah->ah_devid;
8317 ah->ah_subvendorid = ah->ah_subvendorid;
8318 ah->ah_macVersion = ah->ah_macVersion;
8319 ah->ah_macRev = ah->ah_macRev;
8320 ah->ah_phyRev = ah->ah_phyRev;
8321 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8322 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8328 ath9k_hw_computetxtime(struct ath_hal *ah,
8329 const struct ath9k_rate_table *rates,
8330 u32 frameLen, u16 rateix,
8333 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8336 kbps = rates->info[rateix].rateKbps;
8340 switch (rates->info[rateix].phy) {
8343 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8344 if (shortPreamble && rates->info[rateix].shortPreamble)
8346 numBits = frameLen << 3;
8347 txTime = CCK_SIFS_TIME + phyTime
8348 + ((numBits * 1000) / kbps);
8351 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8353 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8355 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8356 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8357 txTime = OFDM_SIFS_TIME_QUARTER
8358 + OFDM_PREAMBLE_TIME_QUARTER
8359 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8360 } else if (ah->ah_curchan &&
8361 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8363 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8365 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8366 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8367 txTime = OFDM_SIFS_TIME_HALF +
8368 OFDM_PREAMBLE_TIME_HALF
8369 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8371 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8373 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8374 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8375 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8376 + (numSymbols * OFDM_SYMBOL_TIME);
8381 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8382 "%s: unknown phy %u (rate ix %u)\n", __func__,
8383 rates->info[rateix].phy, rateix);
8390 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8392 if (flags & CHANNEL_2GHZ) {
8396 return (freq - 2407) / 5;
8398 return 15 + ((freq - 2512) / 20);
8399 } else if (flags & CHANNEL_5GHZ) {
8400 if (ath9k_regd_is_public_safety_sku(ah) &&
8401 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8402 return ((freq * 10) +
8403 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8404 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8405 return (freq - 4000) / 5;
8407 return (freq - 5000) / 5;
8413 return (freq - 2407) / 5;
8415 if (ath9k_regd_is_public_safety_sku(ah)
8416 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8417 return ((freq * 10) +
8419 2) ? 5 : 0) - 49400) / 5;
8420 } else if (freq > 4900) {
8421 return (freq - 4000) / 5;
8423 return 15 + ((freq - 2512) / 20);
8426 return (freq - 5000) / 5;
8431 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8433 struct ath9k_channel *ichan;
8435 ichan = ath9k_regd_check_channel(ah, chan);
8436 if (ichan == NULL) {
8437 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8438 "%s: invalid channel %u/0x%x; no mapping\n",
8439 __func__, chan->channel, chan->channelFlags);
8442 if (ichan->rawNoiseFloor == 0) {
8443 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8444 return NOISE_FLOOR[mode];
8446 return ichan->rawNoiseFloor;
8449 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8451 struct ath_hal_5416 *ahp = AH5416(ah);
8454 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8456 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8460 bool ath9k_hw_phycounters(struct ath_hal *ah)
8462 struct ath_hal_5416 *ahp = AH5416(ah);
8464 return ahp->ah_hasHwPhyCounters ? true : false;
8467 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8469 return REG_READ(ah, AR_QTXDP(q));
8472 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8475 REG_WRITE(ah, AR_QTXDP(q), txdp);
8480 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8482 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8484 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8489 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8493 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8496 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8502 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8506 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8508 for (wait = 1000; wait != 0; wait--) {
8509 if (ath9k_hw_numtxpending(ah, q) == 0)
8514 if (ath9k_hw_numtxpending(ah, q)) {
8517 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8518 "%s: Num of pending TX Frames %d on Q %d\n",
8519 __func__, ath9k_hw_numtxpending(ah, q), q);
8521 for (j = 0; j < 2; j++) {
8522 tsfLow = REG_READ(ah, AR_TSF_L32);
8523 REG_WRITE(ah, AR_QUIET2,
8524 SM(10, AR_QUIET2_QUIET_DUR));
8525 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8526 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8527 REG_SET_BIT(ah, AR_TIMER_MODE,
8530 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8534 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8535 "%s: TSF have moved while trying to set "
8536 "quiet time TSF: 0x%08x\n",
8540 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8543 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8547 while (ath9k_hw_numtxpending(ah, q)) {
8548 if ((--wait) == 0) {
8549 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8550 "%s: Failed to stop Tx DMA in 100 "
8551 "msec after killing last frame\n",
8558 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8561 REG_WRITE(ah, AR_Q_TXD, 0);