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.dma_beacon_response_time = 2;
339 ah->ah_config.sw_beacon_response_time = 10;
340 ah->ah_config.additional_swba_backoff = 0;
341 ah->ah_config.ack_6mb = 0x0;
342 ah->ah_config.cwm_ignore_extcca = 0;
343 ah->ah_config.pcie_powersave_enable = 0;
344 ah->ah_config.pcie_l1skp_enable = 0;
345 ah->ah_config.pcie_clock_req = 0;
346 ah->ah_config.pcie_power_reset = 0x100;
347 ah->ah_config.pcie_restore = 0;
348 ah->ah_config.pcie_waen = 0;
349 ah->ah_config.analog_shiftreg = 1;
350 ah->ah_config.ht_enable = 1;
351 ah->ah_config.ofdm_trig_low = 200;
352 ah->ah_config.ofdm_trig_high = 500;
353 ah->ah_config.cck_trig_high = 200;
354 ah->ah_config.cck_trig_low = 100;
355 ah->ah_config.enable_ani = 0;
356 ah->ah_config.noise_immunity_level = 4;
357 ah->ah_config.ofdm_weaksignal_det = 1;
358 ah->ah_config.cck_weaksignal_thr = 0;
359 ah->ah_config.spur_immunity_level = 2;
360 ah->ah_config.firstep_level = 0;
361 ah->ah_config.rssi_thr_high = 40;
362 ah->ah_config.rssi_thr_low = 7;
363 ah->ah_config.diversity_control = 0;
364 ah->ah_config.antenna_switch_swap = 0;
366 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
367 ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
368 ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
371 ah->ah_config.intr_mitigation = 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.analog_shiftreg)
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 ath9k_capability_type type,
1009 struct ath_hal_5416 *ahp = AH5416(ah);
1013 case ATH9K_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 ATH9K_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 ATH9K_CAP_MCAST_KEYSRCH:
1031 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1033 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1035 case ATH9K_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.cwm_ignore_extcca)
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.diversity_control;
1218 ahp->ah_antennaSwitchSwap =
1219 ah->ah_config.antenna_switch_swap;
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.spurchans[i][is2GHz]);
1376 switch (ah->ah_config.spurmode) {
1379 case SPUR_ENABLE_IOCTL:
1380 spur_val = ah->ah_config.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.enable_ani)
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.ofdm_trig_high;
2508 ahp->ah_curani->ofdmTrigLow =
2509 ah->ah_config.ofdm_trig_low;
2510 ahp->ah_curani->cckTrigHigh =
2511 ah->ah_config.cck_trig_high;
2512 ahp->ah_curani->cckTrigLow =
2513 ah->ah_config.cck_trig_low;
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.num_gpio_pins)
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 ath9k_hw_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->wireless_modes = 0;
2974 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2976 if (eeval & AR5416_OPFLAGS_11A) {
2977 pCap->wireless_modes |= ATH9K_MODE_SEL_11A |
2978 ((!ah->ah_config.ht_enable
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->wireless_modes |=
2987 ATH9K_MODE_SEL_11B | ATH9K_MODE_SEL_11G |
2988 ((!ah->ah_config.ht_enable
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->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
2997 if ((ah->ah_isPciExpress)
2998 || (eeval & AR5416_OPFLAGS_11A)) {
2999 pCap->rx_chainmask =
3000 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3002 pCap->rx_chainmask =
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->low_2ghz_chan = 2312;
3010 pCap->high_2ghz_chan = 2732;
3012 pCap->low_5ghz_chan = 4920;
3013 pCap->high_5ghz_chan = 6100;
3015 pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
3016 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
3017 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
3019 pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
3020 pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
3021 pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
3023 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
3025 if (ah->ah_config.ht_enable)
3026 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3028 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
3030 pCap->hw_caps |= ATH9K_HW_CAP_GTT;
3031 pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
3032 pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
3033 pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
3035 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3036 pCap->total_queues =
3037 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3039 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
3041 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3042 pCap->keycache_size =
3043 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3045 pCap->keycache_size = AR_KEYTABLE_SIZE;
3047 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3048 pCap->num_mr_retries = 4;
3049 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3051 if (AR_SREV_9280_10_OR_LATER(ah))
3052 pCap->num_gpio_pins = AR928X_NUM_GPIO;
3054 pCap->num_gpio_pins = AR_NUM_GPIO;
3056 if (AR_SREV_9280_10_OR_LATER(ah)) {
3057 pCap->hw_caps |= ATH9K_HW_CAP_WOW;
3058 pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3060 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
3061 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3064 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3065 pCap->hw_caps |= ATH9K_HW_CAP_CST;
3066 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
3068 pCap->rts_aggr_limit = (8 * 1024);
3071 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
3073 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3074 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3075 ahp->ah_gpioSelect =
3076 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3078 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3080 ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true,
3082 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3085 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3086 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3087 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3088 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3089 (ah->ah_macVersion == AR_SREV_VERSION_9280))
3090 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3092 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
3094 if (AR_SREV_9280(ah))
3095 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
3097 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
3099 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3101 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3102 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3103 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3104 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3107 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3108 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3111 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3113 pCap->num_antcfg_5ghz =
3114 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_5GHZ);
3115 pCap->num_antcfg_2ghz =
3116 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_2GHZ);
3121 static void ar5416DisablePciePhy(struct ath_hal *ah)
3123 if (!AR_SREV_9100(ah))
3126 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3127 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3128 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3129 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3130 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3131 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3132 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3133 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3134 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3136 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3139 static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3141 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3143 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3144 AR_RTC_FORCE_WAKE_EN);
3145 if (!AR_SREV_9100(ah))
3146 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3148 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3153 static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3155 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3157 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3159 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
3160 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3161 AR_RTC_FORCE_WAKE_ON_INT);
3163 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3164 AR_RTC_FORCE_WAKE_EN);
3169 static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3176 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3177 AR_RTC_STATUS_SHUTDOWN) {
3178 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3183 if (AR_SREV_9100(ah))
3184 REG_SET_BIT(ah, AR_RTC_RESET,
3187 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3188 AR_RTC_FORCE_WAKE_EN);
3191 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3192 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3193 if (val == AR_RTC_STATUS_ON)
3196 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3197 AR_RTC_FORCE_WAKE_EN);
3200 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3201 "%s: Failed to wakeup in %uus\n",
3202 __func__, POWER_UP_TIME / 20);
3207 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3211 bool ath9k_hw_setpower(struct ath_hal *ah,
3212 enum ath9k_power_mode mode)
3214 struct ath_hal_5416 *ahp = AH5416(ah);
3215 static const char *modes[] = {
3221 int status = true, setChip = true;
3223 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3224 modes[ahp->ah_powerMode], modes[mode],
3225 setChip ? "set chip " : "");
3228 case ATH9K_PM_AWAKE:
3229 status = ath9k_hw_set_power_awake(ah, setChip);
3231 case ATH9K_PM_FULL_SLEEP:
3232 ath9k_set_power_sleep(ah, setChip);
3233 ahp->ah_chipFullSleep = true;
3235 case ATH9K_PM_NETWORK_SLEEP:
3236 ath9k_set_power_network_sleep(ah, setChip);
3239 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3240 "%s: unknown power mode %u\n", __func__, mode);
3243 ahp->ah_powerMode = mode;
3247 static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3248 struct ath_softc *sc,
3252 struct ath_hal_5416 *ahp;
3255 #ifndef CONFIG_SLOW_ANT_DIV
3260 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3266 ath9k_hw_set_defaults(ah);
3268 if (ah->ah_config.intr_mitigation != 0)
3269 ahp->ah_intrMitigation = true;
3271 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3272 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3278 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3279 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3285 if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
3286 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3287 ah->ah_config.serialize_regmode =
3290 ah->ah_config.serialize_regmode =
3294 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3295 "%s: serialize_regmode is %d\n",
3296 __func__, ah->ah_config.serialize_regmode);
3298 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3299 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3300 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3301 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3302 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3303 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3304 "this driver\n", __func__,
3305 ah->ah_macVersion, ah->ah_macRev);
3306 ecode = -EOPNOTSUPP;
3310 if (AR_SREV_9100(ah)) {
3311 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3312 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3313 ah->ah_isPciExpress = false;
3315 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3317 if (AR_SREV_9160_10_OR_LATER(ah)) {
3318 if (AR_SREV_9280_10_OR_LATER(ah)) {
3319 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3320 ahp->ah_adcGainCalData.calData =
3321 &adc_gain_cal_single_sample;
3322 ahp->ah_adcDcCalData.calData =
3323 &adc_dc_cal_single_sample;
3324 ahp->ah_adcDcCalInitData.calData =
3327 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3328 ahp->ah_adcGainCalData.calData =
3329 &adc_gain_cal_multi_sample;
3330 ahp->ah_adcDcCalData.calData =
3331 &adc_dc_cal_multi_sample;
3332 ahp->ah_adcDcCalInitData.calData =
3336 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3339 if (AR_SREV_9160(ah)) {
3340 ah->ah_config.enable_ani = 1;
3341 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3342 ATH9K_ANI_FIRSTEP_LEVEL);
3344 ahp->ah_ani_function = ATH9K_ANI_ALL;
3345 if (AR_SREV_9280_10_OR_LATER(ah)) {
3346 ahp->ah_ani_function &=
3347 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3351 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3352 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3353 ah->ah_macVersion, ah->ah_macRev);
3355 if (AR_SREV_9280_20_OR_LATER(ah)) {
3356 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3357 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3358 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3359 ARRAY_SIZE(ar9280Common_9280_2), 2);
3361 if (ah->ah_config.pcie_clock_req) {
3362 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3363 ar9280PciePhy_clkreq_off_L1_9280,
3365 (ar9280PciePhy_clkreq_off_L1_9280),
3368 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3369 ar9280PciePhy_clkreq_always_on_L1_9280,
3371 (ar9280PciePhy_clkreq_always_on_L1_9280),
3374 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3375 ar9280Modes_fast_clock_9280_2,
3376 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3378 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3379 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3380 ARRAY_SIZE(ar9280Modes_9280), 6);
3381 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3382 ARRAY_SIZE(ar9280Common_9280), 2);
3383 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3384 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3385 ARRAY_SIZE(ar5416Modes_9160), 6);
3386 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3387 ARRAY_SIZE(ar5416Common_9160), 2);
3388 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3389 ARRAY_SIZE(ar5416Bank0_9160), 2);
3390 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3391 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3392 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3393 ARRAY_SIZE(ar5416Bank1_9160), 2);
3394 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3395 ARRAY_SIZE(ar5416Bank2_9160), 2);
3396 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3397 ARRAY_SIZE(ar5416Bank3_9160), 3);
3398 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3399 ARRAY_SIZE(ar5416Bank6_9160), 3);
3400 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3401 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3402 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3403 ARRAY_SIZE(ar5416Bank7_9160), 2);
3404 if (AR_SREV_9160_11(ah)) {
3405 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3406 ar5416Addac_91601_1,
3407 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3409 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3410 ARRAY_SIZE(ar5416Addac_9160), 2);
3412 } else if (AR_SREV_9100_OR_LATER(ah)) {
3413 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3414 ARRAY_SIZE(ar5416Modes_9100), 6);
3415 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3416 ARRAY_SIZE(ar5416Common_9100), 2);
3417 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3418 ARRAY_SIZE(ar5416Bank0_9100), 2);
3419 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3420 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3421 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3422 ARRAY_SIZE(ar5416Bank1_9100), 2);
3423 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3424 ARRAY_SIZE(ar5416Bank2_9100), 2);
3425 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3426 ARRAY_SIZE(ar5416Bank3_9100), 3);
3427 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3428 ARRAY_SIZE(ar5416Bank6_9100), 3);
3429 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3430 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3431 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3432 ARRAY_SIZE(ar5416Bank7_9100), 2);
3433 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3434 ARRAY_SIZE(ar5416Addac_9100), 2);
3436 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3437 ARRAY_SIZE(ar5416Modes), 6);
3438 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3439 ARRAY_SIZE(ar5416Common), 2);
3440 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3441 ARRAY_SIZE(ar5416Bank0), 2);
3442 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3443 ARRAY_SIZE(ar5416BB_RfGain), 3);
3444 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3445 ARRAY_SIZE(ar5416Bank1), 2);
3446 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3447 ARRAY_SIZE(ar5416Bank2), 2);
3448 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3449 ARRAY_SIZE(ar5416Bank3), 3);
3450 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3451 ARRAY_SIZE(ar5416Bank6), 3);
3452 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3453 ARRAY_SIZE(ar5416Bank6TPC), 3);
3454 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3455 ARRAY_SIZE(ar5416Bank7), 2);
3456 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3457 ARRAY_SIZE(ar5416Addac), 2);
3460 if (ah->ah_isPciExpress)
3461 ath9k_hw_configpcipowersave(ah, 0);
3463 ar5416DisablePciePhy(ah);
3465 ecode = ath9k_hw_post_attach(ah);
3469 #ifndef CONFIG_SLOW_ANT_DIV
3470 if (ah->ah_devid == AR9280_DEVID_PCI) {
3471 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3472 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3474 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3475 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3477 INI_RA(&ahp->ah_iniModes, i, j) =
3478 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3485 if (!ath9k_hw_fill_cap_info(ah)) {
3486 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3487 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3492 ecode = ath9k_hw_init_macaddr(ah);
3494 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3495 "%s: failed initializing mac address\n",
3500 if (AR_SREV_9285(ah))
3501 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3503 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3505 #ifndef ATH_NF_PER_CHAN
3507 ath9k_init_nfcal_hist_buffer(ah);
3514 ath9k_hw_detach((struct ath_hal *) ahp);
3520 void ath9k_hw_detach(struct ath_hal *ah)
3522 if (!AR_SREV_9100(ah))
3523 ath9k_hw_ani_detach(ah);
3524 ath9k_hw_rfdetach(ah);
3526 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3530 bool ath9k_get_channel_edges(struct ath_hal *ah,
3531 u16 flags, u16 *low,
3534 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3536 if (flags & CHANNEL_5GHZ) {
3537 *low = pCap->low_5ghz_chan;
3538 *high = pCap->high_5ghz_chan;
3541 if ((flags & CHANNEL_2GHZ)) {
3542 *low = pCap->low_2ghz_chan;
3543 *high = pCap->high_2ghz_chan;
3550 static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3559 u8 currPwr = pwrMin;
3560 u16 idxL = 0, idxR = 0;
3562 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3563 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3564 numIntercepts, &(idxL),
3568 if (idxL == numIntercepts - 1)
3569 idxL = (u16) (numIntercepts - 2);
3570 if (pPwrList[idxL] == pPwrList[idxR])
3573 k = (u16) (((currPwr -
3577 currPwr) * pVpdList[idxL]) /
3580 pRetVpdList[i] = (u8) k;
3588 ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3589 struct ath9k_channel *chan,
3590 struct cal_data_per_freq *pRawDataSet,
3594 int16_t *pMinCalPower,
3595 u16 *pPdGainBoundaries,
3601 u16 idxL = 0, idxR = 0, numPiers;
3602 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3603 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3604 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3605 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3606 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3607 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3609 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3610 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3611 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3614 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3616 int16_t minDelta = 0;
3617 struct chan_centers centers;
3619 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3621 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3622 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3626 match = ath9k_hw_get_lower_upper_index((u8)
3631 numPiers, &idxL, &idxR);
3634 for (i = 0; i < numXpdGains; i++) {
3635 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3636 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3637 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3642 AR5416_PD_GAIN_ICEPTS,
3646 for (i = 0; i < numXpdGains; i++) {
3647 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3648 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3649 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3650 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3652 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3655 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3656 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3659 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3661 AR5416_PD_GAIN_ICEPTS,
3663 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3665 AR5416_PD_GAIN_ICEPTS,
3668 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3670 (u8) (ath9k_hw_interpolate
3677 bChans[idxR], vpdTableL[i]
3684 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3687 for (i = 0; i < numXpdGains; i++) {
3688 if (i == (numXpdGains - 1))
3689 pPdGainBoundaries[i] =
3690 (u16) (maxPwrT4[i] / 2);
3692 pPdGainBoundaries[i] =
3693 (u16) ((maxPwrT4[i] +
3694 minPwrT4[i + 1]) / 4);
3696 pPdGainBoundaries[i] =
3697 min((u16) AR5416_MAX_RATE_POWER,
3698 pPdGainBoundaries[i]);
3700 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3701 minDelta = pPdGainBoundaries[0] - 23;
3702 pPdGainBoundaries[0] = 23;
3708 if (AR_SREV_9280_10_OR_LATER(ah))
3709 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3713 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3714 (minPwrT4[i] / 2)) -
3715 tPdGainOverlap + 1 + minDelta);
3717 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3718 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3720 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3721 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3723 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3728 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3729 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3731 maxIndex = (tgtIndex <
3732 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3734 while ((ss < maxIndex)
3735 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3736 pPDADCValues[k++] = vpdTableI[i][ss++];
3739 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3740 vpdTableI[i][sizeCurrVpdTable - 2]);
3741 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3743 if (tgtIndex > maxIndex) {
3744 while ((ss <= tgtIndex)
3745 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3746 tmpVal = (int16_t) ((vpdTableI[i]
3748 1] + (ss - maxIndex +
3750 pPDADCValues[k++] = (u8) ((tmpVal >
3751 255) ? 255 : tmpVal);
3757 while (i < AR5416_PD_GAINS_IN_MASK) {
3758 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3762 while (k < AR5416_NUM_PDADC_VALUES) {
3763 pPDADCValues[k] = pPDADCValues[k - 1];
3770 ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3771 struct ar5416_eeprom *pEepData,
3772 struct ath9k_channel *chan,
3773 int16_t *pTxPowerIndexOffset)
3775 struct cal_data_per_freq *pRawDataset;
3776 u8 *pCalBChans = NULL;
3777 u16 pdGainOverlap_t2;
3778 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3779 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3781 int16_t tMinCalPower;
3782 u16 numXpdGain, xpdMask;
3783 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3784 u32 reg32, regOffset, regChainOffset;
3786 struct ath_hal_5416 *ahp = AH5416(ah);
3788 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3789 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3791 if ((pEepData->baseEepHeader.
3792 version & AR5416_EEP_VER_MINOR_MASK) >=
3793 AR5416_EEP_MINOR_VER_2) {
3795 pEepData->modalHeader[modalIdx].pdGainOverlap;
3799 (REG_READ(ah, AR_PHY_TPCRG5),
3800 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3803 if (IS_CHAN_2GHZ(chan)) {
3804 pCalBChans = pEepData->calFreqPier2G;
3805 numPiers = AR5416_NUM_2G_CAL_PIERS;
3807 pCalBChans = pEepData->calFreqPier5G;
3808 numPiers = AR5416_NUM_5G_CAL_PIERS;
3813 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3814 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3815 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3817 xpdGainValues[numXpdGain] =
3818 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3823 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3824 (numXpdGain - 1) & 0x3);
3825 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3827 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3829 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3832 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3833 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3834 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3836 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3838 regChainOffset = i * 0x1000;
3839 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3840 if (IS_CHAN_2GHZ(chan))
3841 pRawDataset = pEepData->calPierData2G[i];
3843 pRawDataset = pEepData->calPierData5G[i];
3845 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3855 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3858 AR_PHY_TPCRG5 + regChainOffset,
3859 SM(pdGainOverlap_t2,
3860 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3861 | SM(gainBoundaries[0],
3862 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3863 | SM(gainBoundaries[1],
3864 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3865 | SM(gainBoundaries[2],
3866 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3867 | SM(gainBoundaries[3],
3868 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3872 AR_PHY_BASE + (672 << 2) + regChainOffset;
3873 for (j = 0; j < 32; j++) {
3875 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3876 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3877 8) | ((pdadcValues[4 * j + 2] &
3879 ((pdadcValues[4 * j + 3] & 0xFF) <<
3881 REG_WRITE(ah, regOffset, reg32);
3883 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3884 "PDADC (%d,%4x): %4.4x %8.8x\n",
3885 i, regChainOffset, regOffset,
3887 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3888 "PDADC: Chain %d | PDADC %3d Value %3d | "
3889 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3890 "PDADC %3d Value %3d |\n",
3891 i, 4 * j, pdadcValues[4 * j],
3892 4 * j + 1, pdadcValues[4 * j + 1],
3893 4 * j + 2, pdadcValues[4 * j + 2],
3895 pdadcValues[4 * j + 3]);
3901 *pTxPowerIndexOffset = 0;
3906 void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3908 struct ath_hal_5416 *ahp = AH5416(ah);
3911 if (ah->ah_isPciExpress != true)
3914 if (ah->ah_config.pcie_powersave_enable == 2)
3920 if (AR_SREV_9280_20_OR_LATER(ah)) {
3921 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3922 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3923 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3926 } else if (AR_SREV_9280(ah)
3927 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3928 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3929 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3931 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3932 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3933 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3935 if (ah->ah_config.pcie_clock_req)
3936 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3938 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3940 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3941 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3942 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3944 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3948 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3950 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3954 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3955 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3956 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3957 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3960 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3962 if (ah->ah_config.pcie_waen) {
3963 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
3965 if (AR_SREV_9280(ah))
3966 REG_WRITE(ah, AR_WA, 0x0040073f);
3968 REG_WRITE(ah, AR_WA, 0x0000073f);
3973 ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3974 struct ath9k_channel *chan,
3975 struct cal_target_power_leg *powInfo,
3977 struct cal_target_power_leg *pNewPower,
3983 int matchIndex = -1, lowIndex = -1;
3985 struct chan_centers centers;
3987 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3988 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
3990 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
3991 IS_CHAN_2GHZ(chan))) {
3994 for (i = 0; (i < numChannels)
3995 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
3997 ath9k_hw_fbin2freq(powInfo[i].bChannel,
3998 IS_CHAN_2GHZ(chan))) {
4002 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4003 IS_CHAN_2GHZ(chan)))
4005 ath9k_hw_fbin2freq(powInfo[i - 1].
4013 if ((matchIndex == -1) && (lowIndex == -1))
4017 if (matchIndex != -1) {
4018 *pNewPower = powInfo[matchIndex];
4020 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4021 IS_CHAN_2GHZ(chan));
4022 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4023 IS_CHAN_2GHZ(chan));
4025 for (i = 0; i < numRates; i++) {
4026 pNewPower->tPow2x[i] =
4027 (u8) ath9k_hw_interpolate(freq, clo, chi,
4039 ath9k_hw_get_target_powers(struct ath_hal *ah,
4040 struct ath9k_channel *chan,
4041 struct cal_target_power_ht *powInfo,
4043 struct cal_target_power_ht *pNewPower,
4049 int matchIndex = -1, lowIndex = -1;
4051 struct chan_centers centers;
4053 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4054 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4057 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4060 for (i = 0; (i < numChannels)
4061 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4063 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4064 IS_CHAN_2GHZ(chan))) {
4069 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4070 IS_CHAN_2GHZ(chan)))
4072 ath9k_hw_fbin2freq(powInfo[i - 1].
4080 if ((matchIndex == -1) && (lowIndex == -1))
4084 if (matchIndex != -1) {
4085 *pNewPower = powInfo[matchIndex];
4087 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4088 IS_CHAN_2GHZ(chan));
4089 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4090 IS_CHAN_2GHZ(chan));
4092 for (i = 0; i < numRates; i++) {
4093 pNewPower->tPow2x[i] =
4094 (u8) ath9k_hw_interpolate(freq, clo, chi,
4106 ath9k_hw_get_max_edge_power(u16 freq,
4107 struct cal_ctl_edges *pRdEdgesPower,
4110 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4113 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4114 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4115 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4117 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4121 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4122 bChannel, is2GHz))) {
4123 if (ath9k_hw_fbin2freq
4124 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4125 && pRdEdgesPower[i - 1].flag) {
4127 pRdEdgesPower[i - 1].tPower;
4132 return twiceMaxEdgePower;
4136 ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4137 struct ar5416_eeprom *pEepData,
4138 struct ath9k_channel *chan,
4139 int16_t *ratesArray,
4141 u8 AntennaReduction,
4142 u8 twiceMaxRegulatoryPower,
4145 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4146 static const u16 tpScaleReductionTable[5] =
4147 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4150 int8_t twiceLargestAntenna;
4151 struct cal_ctl_data *rep;
4152 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4155 struct cal_target_power_leg targetPowerOfdmExt = {
4156 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4159 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4162 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4163 u16 ctlModesFor11a[] =
4164 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4165 u16 ctlModesFor11g[] =
4166 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4169 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4170 struct chan_centers centers;
4172 u8 twiceMinEdgePower;
4173 struct ath_hal_5416 *ahp = AH5416(ah);
4175 tx_chainmask = ahp->ah_txchainmask;
4177 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4179 twiceLargestAntenna = max(
4180 pEepData->modalHeader
4181 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4182 pEepData->modalHeader
4183 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4185 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4186 pEepData->modalHeader
4187 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4189 twiceLargestAntenna =
4190 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4192 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4194 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4195 maxRegAllowedPower -=
4196 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4199 scaledPower = min(powerLimit, maxRegAllowedPower);
4201 switch (ar5416_get_ntxchains(tx_chainmask)) {
4206 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4207 pwrDecreaseFor2Chain;
4211 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4212 pwrDecreaseFor3Chain;
4216 scaledPower = max(0, (int32_t) scaledPower);
4218 if (IS_CHAN_2GHZ(chan)) {
4220 ARRAY_SIZE(ctlModesFor11g) -
4221 SUB_NUM_CTL_MODES_AT_2G_40;
4222 pCtlMode = ctlModesFor11g;
4224 ath9k_hw_get_legacy_target_powers(ah, chan,
4227 AR5416_NUM_2G_CCK_TARGET_POWERS,
4230 ath9k_hw_get_legacy_target_powers(ah, chan,
4233 AR5416_NUM_2G_20_TARGET_POWERS,
4234 &targetPowerOfdm, 4,
4236 ath9k_hw_get_target_powers(ah, chan,
4237 pEepData->calTargetPower2GHT20,
4238 AR5416_NUM_2G_20_TARGET_POWERS,
4239 &targetPowerHt20, 8, false);
4241 if (IS_CHAN_HT40(chan)) {
4242 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4243 ath9k_hw_get_target_powers(ah, chan,
4245 calTargetPower2GHT40,
4246 AR5416_NUM_2G_40_TARGET_POWERS,
4247 &targetPowerHt40, 8,
4249 ath9k_hw_get_legacy_target_powers(ah, chan,
4252 AR5416_NUM_2G_CCK_TARGET_POWERS,
4255 ath9k_hw_get_legacy_target_powers(ah, chan,
4258 AR5416_NUM_2G_20_TARGET_POWERS,
4259 &targetPowerOfdmExt,
4265 ARRAY_SIZE(ctlModesFor11a) -
4266 SUB_NUM_CTL_MODES_AT_5G_40;
4267 pCtlMode = ctlModesFor11a;
4269 ath9k_hw_get_legacy_target_powers(ah, chan,
4272 AR5416_NUM_5G_20_TARGET_POWERS,
4273 &targetPowerOfdm, 4,
4275 ath9k_hw_get_target_powers(ah, chan,
4276 pEepData->calTargetPower5GHT20,
4277 AR5416_NUM_5G_20_TARGET_POWERS,
4278 &targetPowerHt20, 8, false);
4280 if (IS_CHAN_HT40(chan)) {
4281 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4282 ath9k_hw_get_target_powers(ah, chan,
4284 calTargetPower5GHT40,
4285 AR5416_NUM_5G_40_TARGET_POWERS,
4286 &targetPowerHt40, 8,
4288 ath9k_hw_get_legacy_target_powers(ah, chan,
4291 AR5416_NUM_5G_20_TARGET_POWERS,
4292 &targetPowerOfdmExt,
4297 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4298 bool isHt40CtlMode =
4299 (pCtlMode[ctlMode] == CTL_5GHT40)
4300 || (pCtlMode[ctlMode] == CTL_2GHT40);
4302 freq = centers.synth_center;
4303 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4304 freq = centers.ext_center;
4306 freq = centers.ctl_center;
4308 if (ar5416_get_eep_ver(ahp) == 14
4309 && ar5416_get_eep_rev(ahp) <= 2)
4310 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4312 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4313 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4314 "EXT_ADDITIVE %d\n",
4315 ctlMode, numCtlModes, isHt40CtlMode,
4316 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4318 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4320 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4321 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4322 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4324 i, cfgCtl, pCtlMode[ctlMode],
4325 pEepData->ctlIndex[i], chan->channel);
4327 if ((((cfgCtl & ~CTL_MODE_M) |
4328 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4329 pEepData->ctlIndex[i])
4331 (((cfgCtl & ~CTL_MODE_M) |
4332 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4334 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4335 rep = &(pEepData->ctlData[i]);
4338 ath9k_hw_get_max_edge_power(freq,
4341 [ar5416_get_ntxchains
4347 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4348 " MATCH-EE_IDX %d: ch %d is2 %d "
4349 "2xMinEdge %d chainmask %d chains %d\n",
4350 i, freq, IS_CHAN_2GHZ(chan),
4351 twiceMinEdgePower, tx_chainmask,
4352 ar5416_get_ntxchains
4354 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4356 min(twiceMaxEdgePower,
4366 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4368 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4369 " SEL-Min ctlMode %d pCtlMode %d "
4370 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4371 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4372 scaledPower, minCtlPower);
4374 switch (pCtlMode[ctlMode]) {
4376 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4378 targetPowerCck.tPow2x[i] =
4379 min(targetPowerCck.tPow2x[i],
4385 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4387 targetPowerOfdm.tPow2x[i] =
4388 min(targetPowerOfdm.tPow2x[i],
4394 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4396 targetPowerHt20.tPow2x[i] =
4397 min(targetPowerHt20.tPow2x[i],
4402 targetPowerCckExt.tPow2x[0] =
4403 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4407 targetPowerOfdmExt.tPow2x[0] =
4408 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4412 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4414 targetPowerHt40.tPow2x[i] =
4415 min(targetPowerHt40.tPow2x[i],
4424 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4425 ratesArray[rate18mb] = ratesArray[rate24mb] =
4426 targetPowerOfdm.tPow2x[0];
4427 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4428 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4429 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4430 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4432 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4433 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4435 if (IS_CHAN_2GHZ(chan)) {
4436 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4437 ratesArray[rate2s] = ratesArray[rate2l] =
4438 targetPowerCck.tPow2x[1];
4439 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4440 targetPowerCck.tPow2x[2];
4442 ratesArray[rate11s] = ratesArray[rate11l] =
4443 targetPowerCck.tPow2x[3];
4446 if (IS_CHAN_HT40(chan)) {
4447 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4448 ratesArray[rateHt40_0 + i] =
4449 targetPowerHt40.tPow2x[i];
4451 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4452 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4453 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4454 if (IS_CHAN_2GHZ(chan)) {
4455 ratesArray[rateExtCck] =
4456 targetPowerCckExt.tPow2x[0];
4463 ath9k_hw_set_txpower(struct ath_hal *ah,
4464 struct ar5416_eeprom *pEepData,
4465 struct ath9k_channel *chan,
4467 u8 twiceAntennaReduction,
4468 u8 twiceMaxRegulatoryPower,
4471 struct modal_eep_header *pModal =
4472 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4473 int16_t ratesArray[Ar5416RateSize];
4474 int16_t txPowerIndexOffset = 0;
4475 u8 ht40PowerIncForPdadc = 2;
4478 memset(ratesArray, 0, sizeof(ratesArray));
4480 if ((pEepData->baseEepHeader.
4481 version & AR5416_EEP_VER_MINOR_MASK) >=
4482 AR5416_EEP_MINOR_VER_2) {
4483 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4486 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4487 &ratesArray[0], cfgCtl,
4488 twiceAntennaReduction,
4489 twiceMaxRegulatoryPower,
4491 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4492 "ath9k_hw_set_txpower: unable to set "
4493 "tx power per rate table\n");
4497 if (!ath9k_hw_set_power_cal_table
4498 (ah, pEepData, chan, &txPowerIndexOffset)) {
4499 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4500 "ath9k_hw_set_txpower: unable to set power table\n");
4504 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4506 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4507 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4508 ratesArray[i] = AR5416_MAX_RATE_POWER;
4511 if (AR_SREV_9280_10_OR_LATER(ah)) {
4512 for (i = 0; i < Ar5416RateSize; i++)
4513 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4516 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4517 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4518 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4519 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4520 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4522 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4523 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4524 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4525 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4526 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4529 if (IS_CHAN_2GHZ(chan)) {
4530 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4531 ATH9K_POW_SM(ratesArray[rate2s], 24)
4532 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4533 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4534 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4536 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4537 ATH9K_POW_SM(ratesArray[rate11s], 24)
4538 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4539 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4540 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4544 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4545 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4546 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4547 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4548 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4550 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4551 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4552 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4553 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4554 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4557 if (IS_CHAN_HT40(chan)) {
4558 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4559 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4560 ht40PowerIncForPdadc, 24)
4561 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4562 ht40PowerIncForPdadc, 16)
4563 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4564 ht40PowerIncForPdadc, 8)
4565 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4566 ht40PowerIncForPdadc, 0)
4568 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4569 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4570 ht40PowerIncForPdadc, 24)
4571 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4572 ht40PowerIncForPdadc, 16)
4573 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4574 ht40PowerIncForPdadc, 8)
4575 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4576 ht40PowerIncForPdadc, 0)
4579 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4580 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4581 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4582 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4583 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4587 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4588 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4589 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4593 if (IS_CHAN_HT40(chan))
4595 else if (IS_CHAN_HT20(chan))
4598 if (AR_SREV_9280_10_OR_LATER(ah))
4599 ah->ah_maxPowerLevel =
4600 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4602 ah->ah_maxPowerLevel = ratesArray[i];
4607 static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4612 u32 coef_exp, coef_man;
4614 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4615 if ((coef_scaled >> coef_exp) & 0x1)
4618 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4620 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4622 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4623 *coef_exponent = coef_exp - 16;
4627 ath9k_hw_set_delta_slope(struct ath_hal *ah,
4628 struct ath9k_channel *chan)
4630 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4631 u32 clockMhzScaled = 0x64000000;
4632 struct chan_centers centers;
4634 if (IS_CHAN_HALF_RATE(chan))
4635 clockMhzScaled = clockMhzScaled >> 1;
4636 else if (IS_CHAN_QUARTER_RATE(chan))
4637 clockMhzScaled = clockMhzScaled >> 2;
4639 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4640 coef_scaled = clockMhzScaled / centers.synth_center;
4642 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4645 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4646 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4647 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4648 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4650 coef_scaled = (9 * coef_scaled) / 10;
4652 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4655 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4656 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4657 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4658 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4661 static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4662 struct ath9k_channel *chan)
4664 int bb_spur = AR_NO_SPUR;
4667 int bb_spur_off, spur_subchannel_sd;
4669 int spur_delta_phase;
4671 int upper, lower, cur_vit_mask;
4674 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4675 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4677 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4678 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4680 int inc[4] = { 0, 100, 0, 0 };
4681 struct chan_centers centers;
4688 bool is2GHz = IS_CHAN_2GHZ(chan);
4690 memset(&mask_m, 0, sizeof(int8_t) * 123);
4691 memset(&mask_p, 0, sizeof(int8_t) * 123);
4693 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4694 freq = centers.synth_center;
4696 ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
4697 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4698 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4701 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4703 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4705 if (AR_NO_SPUR == cur_bb_spur)
4707 cur_bb_spur = cur_bb_spur - freq;
4709 if (IS_CHAN_HT40(chan)) {
4710 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4711 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4712 bb_spur = cur_bb_spur;
4715 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4716 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4717 bb_spur = cur_bb_spur;
4722 if (AR_NO_SPUR == bb_spur) {
4723 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4724 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4727 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4728 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4731 bin = bb_spur * 320;
4733 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4735 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4736 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4737 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4738 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4739 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4741 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4742 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4743 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4744 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4745 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4746 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4748 if (IS_CHAN_HT40(chan)) {
4750 spur_subchannel_sd = 1;
4751 bb_spur_off = bb_spur + 10;
4753 spur_subchannel_sd = 0;
4754 bb_spur_off = bb_spur - 10;
4757 spur_subchannel_sd = 0;
4758 bb_spur_off = bb_spur;
4761 if (IS_CHAN_HT40(chan))
4763 ((bb_spur * 262144) /
4764 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4767 ((bb_spur * 524288) /
4768 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4770 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4771 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4773 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4774 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4775 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4776 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4778 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4779 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4785 for (i = 0; i < 4; i++) {
4789 for (bp = 0; bp < 30; bp++) {
4790 if ((cur_bin > lower) && (cur_bin < upper)) {
4791 pilot_mask = pilot_mask | 0x1 << bp;
4792 chan_mask = chan_mask | 0x1 << bp;
4797 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4798 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4801 cur_vit_mask = 6100;
4805 for (i = 0; i < 123; i++) {
4806 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
4808 /* workaround for gcc bug #37014 */
4809 volatile int tmp = abs(cur_vit_mask - bin);
4815 if (cur_vit_mask < 0)
4816 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4818 mask_p[cur_vit_mask / 100] = mask_amt;
4820 cur_vit_mask -= 100;
4823 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4824 | (mask_m[48] << 26) | (mask_m[49] << 24)
4825 | (mask_m[50] << 22) | (mask_m[51] << 20)
4826 | (mask_m[52] << 18) | (mask_m[53] << 16)
4827 | (mask_m[54] << 14) | (mask_m[55] << 12)
4828 | (mask_m[56] << 10) | (mask_m[57] << 8)
4829 | (mask_m[58] << 6) | (mask_m[59] << 4)
4830 | (mask_m[60] << 2) | (mask_m[61] << 0);
4831 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4832 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4834 tmp_mask = (mask_m[31] << 28)
4835 | (mask_m[32] << 26) | (mask_m[33] << 24)
4836 | (mask_m[34] << 22) | (mask_m[35] << 20)
4837 | (mask_m[36] << 18) | (mask_m[37] << 16)
4838 | (mask_m[48] << 14) | (mask_m[39] << 12)
4839 | (mask_m[40] << 10) | (mask_m[41] << 8)
4840 | (mask_m[42] << 6) | (mask_m[43] << 4)
4841 | (mask_m[44] << 2) | (mask_m[45] << 0);
4842 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4843 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4845 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4846 | (mask_m[18] << 26) | (mask_m[18] << 24)
4847 | (mask_m[20] << 22) | (mask_m[20] << 20)
4848 | (mask_m[22] << 18) | (mask_m[22] << 16)
4849 | (mask_m[24] << 14) | (mask_m[24] << 12)
4850 | (mask_m[25] << 10) | (mask_m[26] << 8)
4851 | (mask_m[27] << 6) | (mask_m[28] << 4)
4852 | (mask_m[29] << 2) | (mask_m[30] << 0);
4853 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4854 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4856 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4857 | (mask_m[2] << 26) | (mask_m[3] << 24)
4858 | (mask_m[4] << 22) | (mask_m[5] << 20)
4859 | (mask_m[6] << 18) | (mask_m[7] << 16)
4860 | (mask_m[8] << 14) | (mask_m[9] << 12)
4861 | (mask_m[10] << 10) | (mask_m[11] << 8)
4862 | (mask_m[12] << 6) | (mask_m[13] << 4)
4863 | (mask_m[14] << 2) | (mask_m[15] << 0);
4864 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4865 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4867 tmp_mask = (mask_p[15] << 28)
4868 | (mask_p[14] << 26) | (mask_p[13] << 24)
4869 | (mask_p[12] << 22) | (mask_p[11] << 20)
4870 | (mask_p[10] << 18) | (mask_p[9] << 16)
4871 | (mask_p[8] << 14) | (mask_p[7] << 12)
4872 | (mask_p[6] << 10) | (mask_p[5] << 8)
4873 | (mask_p[4] << 6) | (mask_p[3] << 4)
4874 | (mask_p[2] << 2) | (mask_p[1] << 0);
4875 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4876 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4878 tmp_mask = (mask_p[30] << 28)
4879 | (mask_p[29] << 26) | (mask_p[28] << 24)
4880 | (mask_p[27] << 22) | (mask_p[26] << 20)
4881 | (mask_p[25] << 18) | (mask_p[24] << 16)
4882 | (mask_p[23] << 14) | (mask_p[22] << 12)
4883 | (mask_p[21] << 10) | (mask_p[20] << 8)
4884 | (mask_p[19] << 6) | (mask_p[18] << 4)
4885 | (mask_p[17] << 2) | (mask_p[16] << 0);
4886 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4887 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4889 tmp_mask = (mask_p[45] << 28)
4890 | (mask_p[44] << 26) | (mask_p[43] << 24)
4891 | (mask_p[42] << 22) | (mask_p[41] << 20)
4892 | (mask_p[40] << 18) | (mask_p[39] << 16)
4893 | (mask_p[38] << 14) | (mask_p[37] << 12)
4894 | (mask_p[36] << 10) | (mask_p[35] << 8)
4895 | (mask_p[34] << 6) | (mask_p[33] << 4)
4896 | (mask_p[32] << 2) | (mask_p[31] << 0);
4897 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4898 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4900 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4901 | (mask_p[59] << 26) | (mask_p[58] << 24)
4902 | (mask_p[57] << 22) | (mask_p[56] << 20)
4903 | (mask_p[55] << 18) | (mask_p[54] << 16)
4904 | (mask_p[53] << 14) | (mask_p[52] << 12)
4905 | (mask_p[51] << 10) | (mask_p[50] << 8)
4906 | (mask_p[49] << 6) | (mask_p[48] << 4)
4907 | (mask_p[47] << 2) | (mask_p[46] << 0);
4908 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4909 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4912 static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4913 struct ath9k_channel *chan)
4915 int bb_spur = AR_NO_SPUR;
4918 int spur_delta_phase;
4920 int upper, lower, cur_vit_mask;
4923 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4924 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4926 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4927 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4929 int inc[4] = { 0, 100, 0, 0 };
4936 bool is2GHz = IS_CHAN_2GHZ(chan);
4938 memset(&mask_m, 0, sizeof(int8_t) * 123);
4939 memset(&mask_p, 0, sizeof(int8_t) * 123);
4941 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4942 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4943 if (AR_NO_SPUR == cur_bb_spur)
4945 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4946 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4947 bb_spur = cur_bb_spur;
4952 if (AR_NO_SPUR == bb_spur)
4957 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4958 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4959 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4960 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4961 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4963 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4965 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4966 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4967 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4968 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4969 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4970 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4972 spur_delta_phase = ((bb_spur * 524288) / 100) &
4973 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4975 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4976 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4978 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4979 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4980 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4981 REG_WRITE(ah, AR_PHY_TIMING11, new);
4987 for (i = 0; i < 4; i++) {
4991 for (bp = 0; bp < 30; bp++) {
4992 if ((cur_bin > lower) && (cur_bin < upper)) {
4993 pilot_mask = pilot_mask | 0x1 << bp;
4994 chan_mask = chan_mask | 0x1 << bp;
4999 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
5000 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5003 cur_vit_mask = 6100;
5007 for (i = 0; i < 123; i++) {
5008 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5009 if ((abs(cur_vit_mask - bin)) < 75)
5013 if (cur_vit_mask < 0)
5014 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5016 mask_p[cur_vit_mask / 100] = mask_amt;
5018 cur_vit_mask -= 100;
5021 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5022 | (mask_m[48] << 26) | (mask_m[49] << 24)
5023 | (mask_m[50] << 22) | (mask_m[51] << 20)
5024 | (mask_m[52] << 18) | (mask_m[53] << 16)
5025 | (mask_m[54] << 14) | (mask_m[55] << 12)
5026 | (mask_m[56] << 10) | (mask_m[57] << 8)
5027 | (mask_m[58] << 6) | (mask_m[59] << 4)
5028 | (mask_m[60] << 2) | (mask_m[61] << 0);
5029 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5030 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5032 tmp_mask = (mask_m[31] << 28)
5033 | (mask_m[32] << 26) | (mask_m[33] << 24)
5034 | (mask_m[34] << 22) | (mask_m[35] << 20)
5035 | (mask_m[36] << 18) | (mask_m[37] << 16)
5036 | (mask_m[48] << 14) | (mask_m[39] << 12)
5037 | (mask_m[40] << 10) | (mask_m[41] << 8)
5038 | (mask_m[42] << 6) | (mask_m[43] << 4)
5039 | (mask_m[44] << 2) | (mask_m[45] << 0);
5040 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5041 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5043 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5044 | (mask_m[18] << 26) | (mask_m[18] << 24)
5045 | (mask_m[20] << 22) | (mask_m[20] << 20)
5046 | (mask_m[22] << 18) | (mask_m[22] << 16)
5047 | (mask_m[24] << 14) | (mask_m[24] << 12)
5048 | (mask_m[25] << 10) | (mask_m[26] << 8)
5049 | (mask_m[27] << 6) | (mask_m[28] << 4)
5050 | (mask_m[29] << 2) | (mask_m[30] << 0);
5051 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5052 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5054 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5055 | (mask_m[2] << 26) | (mask_m[3] << 24)
5056 | (mask_m[4] << 22) | (mask_m[5] << 20)
5057 | (mask_m[6] << 18) | (mask_m[7] << 16)
5058 | (mask_m[8] << 14) | (mask_m[9] << 12)
5059 | (mask_m[10] << 10) | (mask_m[11] << 8)
5060 | (mask_m[12] << 6) | (mask_m[13] << 4)
5061 | (mask_m[14] << 2) | (mask_m[15] << 0);
5062 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5063 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5065 tmp_mask = (mask_p[15] << 28)
5066 | (mask_p[14] << 26) | (mask_p[13] << 24)
5067 | (mask_p[12] << 22) | (mask_p[11] << 20)
5068 | (mask_p[10] << 18) | (mask_p[9] << 16)
5069 | (mask_p[8] << 14) | (mask_p[7] << 12)
5070 | (mask_p[6] << 10) | (mask_p[5] << 8)
5071 | (mask_p[4] << 6) | (mask_p[3] << 4)
5072 | (mask_p[2] << 2) | (mask_p[1] << 0);
5073 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5074 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5076 tmp_mask = (mask_p[30] << 28)
5077 | (mask_p[29] << 26) | (mask_p[28] << 24)
5078 | (mask_p[27] << 22) | (mask_p[26] << 20)
5079 | (mask_p[25] << 18) | (mask_p[24] << 16)
5080 | (mask_p[23] << 14) | (mask_p[22] << 12)
5081 | (mask_p[21] << 10) | (mask_p[20] << 8)
5082 | (mask_p[19] << 6) | (mask_p[18] << 4)
5083 | (mask_p[17] << 2) | (mask_p[16] << 0);
5084 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5085 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5087 tmp_mask = (mask_p[45] << 28)
5088 | (mask_p[44] << 26) | (mask_p[43] << 24)
5089 | (mask_p[42] << 22) | (mask_p[41] << 20)
5090 | (mask_p[40] << 18) | (mask_p[39] << 16)
5091 | (mask_p[38] << 14) | (mask_p[37] << 12)
5092 | (mask_p[36] << 10) | (mask_p[35] << 8)
5093 | (mask_p[34] << 6) | (mask_p[33] << 4)
5094 | (mask_p[32] << 2) | (mask_p[31] << 0);
5095 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5096 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5098 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5099 | (mask_p[59] << 26) | (mask_p[58] << 24)
5100 | (mask_p[57] << 22) | (mask_p[56] << 20)
5101 | (mask_p[55] << 18) | (mask_p[54] << 16)
5102 | (mask_p[53] << 14) | (mask_p[52] << 12)
5103 | (mask_p[51] << 10) | (mask_p[50] << 8)
5104 | (mask_p[49] << 6) | (mask_p[48] << 4)
5105 | (mask_p[47] << 2) | (mask_p[46] << 0);
5106 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5107 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5110 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5112 struct ath_hal_5416 *ahp = AH5416(ah);
5113 int rx_chainmask, tx_chainmask;
5115 rx_chainmask = ahp->ah_rxchainmask;
5116 tx_chainmask = ahp->ah_txchainmask;
5118 switch (rx_chainmask) {
5120 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5121 AR_PHY_SWAP_ALT_CHAIN);
5123 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5124 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5125 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5130 if (!AR_SREV_9280(ah))
5133 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5134 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5140 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5141 if (tx_chainmask == 0x5) {
5142 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5143 AR_PHY_SWAP_ALT_CHAIN);
5145 if (AR_SREV_9100(ah))
5146 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5147 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5150 static void ath9k_hw_set_addac(struct ath_hal *ah,
5151 struct ath9k_channel *chan)
5153 struct modal_eep_header *pModal;
5154 struct ath_hal_5416 *ahp = AH5416(ah);
5155 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5158 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5161 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5164 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5166 if (pModal->xpaBiasLvl != 0xff) {
5167 biaslevel = pModal->xpaBiasLvl;
5170 u16 resetFreqBin, freqBin, freqCount = 0;
5171 struct chan_centers centers;
5173 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5176 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5177 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5178 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5182 while (freqCount < 3) {
5183 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5186 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5187 if (resetFreqBin >= freqBin) {
5190 xpaBiasLvlFreq[freqCount]
5199 if (IS_CHAN_2GHZ(chan)) {
5200 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5201 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5204 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5205 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5210 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5212 if (ah->ah_curchan != NULL)
5214 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5216 return clks / CLOCK_RATE[WIRELESS_MODE_11b];
5219 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5221 struct ath9k_channel *chan = ah->ah_curchan;
5223 if (chan && IS_CHAN_HT40(chan))
5224 return ath9k_hw_mac_usec(ah, clks) / 2;
5226 return ath9k_hw_mac_usec(ah, clks);
5229 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5231 if (ah->ah_curchan != NULL)
5232 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5235 return usecs * CLOCK_RATE[WIRELESS_MODE_11b];
5238 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5240 struct ath9k_channel *chan = ah->ah_curchan;
5242 if (chan && IS_CHAN_HT40(chan))
5243 return ath9k_hw_mac_clks(ah, usecs) * 2;
5245 return ath9k_hw_mac_clks(ah, usecs);
5248 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5250 struct ath_hal_5416 *ahp = AH5416(ah);
5252 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5253 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5255 ahp->ah_acktimeout = (u32) -1;
5258 REG_RMW_FIELD(ah, AR_TIME_OUT,
5259 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5260 ahp->ah_acktimeout = us;
5265 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5267 struct ath_hal_5416 *ahp = AH5416(ah);
5269 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5270 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5272 ahp->ah_ctstimeout = (u32) -1;
5275 REG_RMW_FIELD(ah, AR_TIME_OUT,
5276 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5277 ahp->ah_ctstimeout = us;
5281 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5284 struct ath_hal_5416 *ahp = AH5416(ah);
5287 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5288 "%s: bad global tx timeout %u\n", __func__, tu);
5289 ahp->ah_globaltxtimeout = (u32) -1;
5292 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5293 ahp->ah_globaltxtimeout = tu;
5298 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5300 struct ath_hal_5416 *ahp = AH5416(ah);
5302 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5303 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5305 ahp->ah_slottime = (u32) -1;
5308 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5309 ahp->ah_slottime = us;
5314 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5316 struct ath_hal_5416 *ahp = AH5416(ah);
5318 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5319 __func__, ahp->ah_miscMode);
5320 if (ahp->ah_miscMode != 0)
5321 REG_WRITE(ah, AR_PCU_MISC,
5322 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5323 if (ahp->ah_slottime != (u32) -1)
5324 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5325 if (ahp->ah_acktimeout != (u32) -1)
5326 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5327 if (ahp->ah_ctstimeout != (u32) -1)
5328 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5329 if (ahp->ah_globaltxtimeout != (u32) -1)
5330 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5334 ath9k_hw_process_ini(struct ath_hal *ah,
5335 struct ath9k_channel *chan,
5336 enum ath9k_ht_macmode macmode)
5338 int i, regWrites = 0;
5339 struct ath_hal_5416 *ahp = AH5416(ah);
5340 u32 modesIndex, freqIndex;
5343 switch (chan->chanmode) {
5345 case CHANNEL_A_HT20:
5349 case CHANNEL_A_HT40PLUS:
5350 case CHANNEL_A_HT40MINUS:
5355 case CHANNEL_G_HT20:
5360 case CHANNEL_G_HT40PLUS:
5361 case CHANNEL_G_HT40MINUS:
5370 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5372 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5374 ath9k_hw_set_addac(ah, chan);
5376 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5377 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5379 struct ar5416IniArray temp;
5381 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5382 ahp->ah_iniAddac.ia_columns;
5384 memcpy(ahp->ah_addac5416_21,
5385 ahp->ah_iniAddac.ia_array, addacSize);
5387 (ahp->ah_addac5416_21)[31 *
5388 ahp->ah_iniAddac.ia_columns + 1] = 0;
5390 temp.ia_array = ahp->ah_addac5416_21;
5391 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5392 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5393 REG_WRITE_ARRAY(&temp, 1, regWrites);
5395 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5397 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5398 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5399 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5401 #ifdef CONFIG_SLOW_ANT_DIV
5402 if (ah->ah_devid == AR9280_DEVID_PCI)
5403 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5407 REG_WRITE(ah, reg, val);
5409 if (reg >= 0x7800 && reg < 0x78a0
5410 && ah->ah_config.analog_shiftreg) {
5414 DO_DELAY(regWrites);
5417 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5418 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5419 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5421 REG_WRITE(ah, reg, val);
5423 if (reg >= 0x7800 && reg < 0x78a0
5424 && ah->ah_config.analog_shiftreg) {
5428 DO_DELAY(regWrites);
5431 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5433 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5434 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5438 ath9k_hw_override_ini(ah, chan);
5439 ath9k_hw_set_regs(ah, chan, macmode);
5440 ath9k_hw_init_chain_masks(ah);
5442 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5443 ath9k_regd_get_ctl(ah, chan),
5444 ath9k_regd_get_antenna_allowed(ah,
5446 chan->maxRegTxPower * 2,
5447 min((u32) MAX_RATE_POWER,
5448 (u32) ah->ah_powerLimit));
5450 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5451 "%s: error init'ing transmit power\n", __func__);
5455 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5456 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5457 "%s: ar5416SetRfRegs failed\n", __func__);
5464 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5465 struct hal_cal_list *currCal)
5467 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5468 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5469 currCal->calData->calCountMax);
5471 switch (currCal->calData->calType) {
5472 case IQ_MISMATCH_CAL:
5473 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5474 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5475 "%s: starting IQ Mismatch Calibration\n",
5479 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5480 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5481 "%s: starting ADC Gain Calibration\n", __func__);
5484 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5485 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5486 "%s: starting ADC DC Calibration\n", __func__);
5488 case ADC_DC_INIT_CAL:
5489 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5490 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5491 "%s: starting Init ADC DC Calibration\n",
5496 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5497 AR_PHY_TIMING_CTRL4_DO_CAL);
5500 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5501 struct hal_cal_list *currCal)
5503 struct ath_hal_5416 *ahp = AH5416(ah);
5506 ath9k_hw_setup_calibration(ah, currCal);
5508 currCal->calState = CAL_RUNNING;
5510 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5511 ahp->ah_Meas0.sign[i] = 0;
5512 ahp->ah_Meas1.sign[i] = 0;
5513 ahp->ah_Meas2.sign[i] = 0;
5514 ahp->ah_Meas3.sign[i] = 0;
5517 ahp->ah_CalSamples = 0;
5521 ath9k_hw_per_calibration(struct ath_hal *ah,
5522 struct ath9k_channel *ichan,
5524 struct hal_cal_list *currCal,
5527 struct ath_hal_5416 *ahp = AH5416(ah);
5531 if (currCal->calState == CAL_RUNNING) {
5533 AR_PHY_TIMING_CTRL4(0)) &
5534 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5536 currCal->calData->calCollect(ah);
5538 ahp->ah_CalSamples++;
5540 if (ahp->ah_CalSamples >=
5541 currCal->calData->calNumSamples) {
5542 int i, numChains = 0;
5543 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5544 if (rxchainmask & (1 << i))
5548 currCal->calData->calPostProc(ah,
5552 currCal->calData->calType;
5553 currCal->calState = CAL_DONE;
5556 ath9k_hw_setup_calibration(ah, currCal);
5559 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5560 ath9k_hw_reset_calibration(ah, currCal);
5564 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5567 struct ath_hal_5416 *ahp = AH5416(ah);
5568 struct ath9k_channel ichan;
5570 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5571 const struct hal_percal_data *calData = currCal->calData;
5574 if (currCal == NULL)
5579 for (i = 0; i < init_cal_count; i++) {
5580 ath9k_hw_reset_calibration(ah, currCal);
5582 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5583 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5584 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5585 "%s: Cal %d failed to complete in 100ms.\n",
5586 __func__, calData->calType);
5588 ahp->ah_cal_list = ahp->ah_cal_list_last =
5589 ahp->ah_cal_list_curr = NULL;
5593 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5594 currCal, &isCalDone);
5596 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5597 "%s: Not able to run Init Cal %d.\n",
5598 __func__, calData->calType);
5600 if (currCal->calNext) {
5601 currCal = currCal->calNext;
5602 calData = currCal->calData;
5606 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5611 ath9k_hw_channel_change(struct ath_hal *ah,
5612 struct ath9k_channel *chan,
5613 enum ath9k_ht_macmode macmode)
5615 u32 synthDelay, qnum;
5616 struct ath_hal_5416 *ahp = AH5416(ah);
5618 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5619 if (ath9k_hw_numtxpending(ah, qnum)) {
5620 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5621 "%s: Transmit frames pending on queue %d\n",
5627 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5628 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5629 AR_PHY_RFBUS_GRANT_EN)) {
5630 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5631 "%s: Could not kill baseband RX\n", __func__);
5635 ath9k_hw_set_regs(ah, chan, macmode);
5637 if (AR_SREV_9280_10_OR_LATER(ah)) {
5638 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5639 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5640 "%s: failed to set channel\n", __func__);
5644 if (!(ath9k_hw_set_channel(ah, chan))) {
5645 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5646 "%s: failed to set channel\n", __func__);
5651 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5652 ath9k_regd_get_ctl(ah, chan),
5653 ath9k_regd_get_antenna_allowed(ah, chan),
5654 chan->maxRegTxPower * 2,
5655 min((u32) MAX_RATE_POWER,
5656 (u32) ah->ah_powerLimit)) != 0) {
5657 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5658 "%s: error init'ing transmit power\n", __func__);
5662 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5663 if (IS_CHAN_CCK(chan))
5664 synthDelay = (4 * synthDelay) / 22;
5668 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5670 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5672 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5673 ath9k_hw_set_delta_slope(ah, chan);
5675 if (AR_SREV_9280_10_OR_LATER(ah))
5676 ath9k_hw_9280_spur_mitigate(ah, chan);
5678 ath9k_hw_spur_mitigate(ah, chan);
5680 if (!chan->oneTimeCalsDone)
5681 chan->oneTimeCalsDone = true;
5686 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5687 struct ath9k_channel *chan)
5689 struct ath_hal_5416 *ahp = AH5416(ah);
5691 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5694 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5697 ahp->ah_chipFullSleep = false;
5699 ath9k_hw_init_pll(ah, chan);
5701 ath9k_hw_set_rfmode(ah, chan);
5706 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5710 regval = REG_READ(ah, AR_AHB_MODE);
5711 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5713 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5714 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5716 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5718 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5719 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5721 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5723 if (AR_SREV_9285(ah)) {
5724 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5725 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5727 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5728 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5732 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5734 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5735 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5736 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5737 "%s: dma failed to stop in 10ms\n"
5738 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5740 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5747 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5749 REG_CLR_BIT(ah, AR_DIAG_SW,
5750 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5752 ath9k_enable_mib_counters(ah);
5754 ath9k_ani_reset(ah);
5757 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5759 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5761 ath9k_hw_disable_mib_counters(ah);
5764 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5765 struct ath9k_channel *chan,
5766 enum hal_cal_types calType)
5768 struct ath_hal_5416 *ahp = AH5416(ah);
5769 bool retval = false;
5771 switch (calType & ahp->ah_suppCals) {
5772 case IQ_MISMATCH_CAL:
5773 if (!IS_CHAN_B(chan))
5778 if (!IS_CHAN_B(chan)
5779 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5787 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5788 struct ath9k_channel *chan)
5790 struct ath_hal_5416 *ahp = AH5416(ah);
5791 struct ath9k_channel *ichan =
5792 ath9k_regd_check_channel(ah, chan);
5794 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5795 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5796 AR_PHY_AGC_CONTROL_CAL);
5799 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5800 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5801 "%s: offset calibration failed to complete in 1ms; "
5802 "noisy environment?\n", __func__);
5806 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5807 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5808 AR_PHY_AGC_CONTROL_NF);
5810 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5813 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5814 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5815 INIT_CAL(&ahp->ah_adcGainCalData);
5816 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5817 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5818 "%s: enabling ADC Gain Calibration.\n",
5821 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5822 INIT_CAL(&ahp->ah_adcDcCalData);
5823 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5824 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5825 "%s: enabling ADC DC Calibration.\n",
5828 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5829 INIT_CAL(&ahp->ah_iqCalData);
5830 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5831 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5832 "%s: enabling IQ Calibration.\n",
5836 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5838 if (ahp->ah_cal_list_curr)
5839 ath9k_hw_reset_calibration(ah,
5840 ahp->ah_cal_list_curr);
5843 ichan->CalValid = 0;
5849 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5850 struct ath9k_channel *chan,
5851 enum ath9k_ht_macmode macmode,
5852 u8 txchainmask, u8 rxchainmask,
5853 enum ath9k_ht_extprotspacing extprotspacing,
5854 bool bChannelChange,
5857 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5859 struct ath_hal_5416 *ahp = AH5416(ah);
5860 struct ath9k_channel *curchan = ah->ah_curchan;
5864 int i, rx_chainmask;
5866 ahp->ah_extprotspacing = extprotspacing;
5867 ahp->ah_txchainmask = txchainmask;
5868 ahp->ah_rxchainmask = rxchainmask;
5870 if (AR_SREV_9280(ah)) {
5871 ahp->ah_txchainmask &= 0x3;
5872 ahp->ah_rxchainmask &= 0x3;
5875 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5876 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5877 "%s: invalid channel %u/0x%x; no mapping\n",
5878 __func__, chan->channel, chan->channelFlags);
5882 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5886 ath9k_hw_getnf(ah, curchan);
5888 if (bChannelChange &&
5889 (ahp->ah_chipFullSleep != true) &&
5890 (ah->ah_curchan != NULL) &&
5891 (chan->channel != ah->ah_curchan->channel) &&
5892 ((chan->channelFlags & CHANNEL_ALL) ==
5893 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5894 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5895 !IS_CHAN_A_5MHZ_SPACED(ah->
5898 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5899 ath9k_hw_loadnf(ah, ah->ah_curchan);
5900 ath9k_hw_start_nfcal(ah);
5905 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5906 if (saveDefAntenna == 0)
5909 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5911 saveLedState = REG_READ(ah, AR_CFG_LED) &
5912 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5913 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5915 ath9k_hw_mark_phy_inactive(ah);
5917 if (!ath9k_hw_chip_reset(ah, chan)) {
5918 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5923 if (AR_SREV_9280(ah)) {
5924 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5925 AR_GPIO_JTAG_DISABLE);
5927 if (ah->ah_caps.wireless_modes & ATH9K_MODE_SEL_11A) {
5928 if (IS_CHAN_5GHZ(chan))
5929 ath9k_hw_set_gpio(ah, 9, 0);
5931 ath9k_hw_set_gpio(ah, 9, 1);
5933 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5936 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5940 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5941 ath9k_hw_set_delta_slope(ah, chan);
5943 if (AR_SREV_9280_10_OR_LATER(ah))
5944 ath9k_hw_9280_spur_mitigate(ah, chan);
5946 ath9k_hw_spur_mitigate(ah, chan);
5948 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5949 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5950 "%s: error setting board options\n", __func__);
5954 ath9k_hw_decrease_chain_power(ah, chan);
5956 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5957 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5959 | AR_STA_ID1_RTS_USE_DEF
5961 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5962 | ahp->ah_staId1Defaults);
5963 ath9k_hw_set_operating_mode(ah, opmode);
5965 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5966 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5968 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5970 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5971 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5972 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5974 REG_WRITE(ah, AR_ISR, ~0);
5976 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5978 if (AR_SREV_9280_10_OR_LATER(ah)) {
5979 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5982 if (!(ath9k_hw_set_channel(ah, chan)))
5986 for (i = 0; i < AR_NUM_DCU; i++)
5987 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5989 ahp->ah_intrTxqs = 0;
5990 for (i = 0; i < ah->ah_caps.total_queues; i++)
5991 ath9k_hw_resettxqueue(ah, i);
5993 ath9k_hw_init_interrupt_masks(ah, opmode);
5994 ath9k_hw_init_qos(ah);
5996 ath9k_hw_init_user_settings(ah);
5998 ah->ah_opmode = opmode;
6000 REG_WRITE(ah, AR_STA_ID1,
6001 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6003 ath9k_hw_set_dma(ah);
6005 REG_WRITE(ah, AR_OBS, 8);
6007 if (ahp->ah_intrMitigation) {
6009 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6010 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6013 ath9k_hw_init_bb(ah, chan);
6015 if (!ath9k_hw_init_cal(ah, chan))
6018 rx_chainmask = ahp->ah_rxchainmask;
6019 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6020 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6021 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6024 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6026 if (AR_SREV_9100(ah)) {
6028 mask = REG_READ(ah, AR_CFG);
6029 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6030 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6031 "%s CFG Byte Swap Set 0x%x\n", __func__,
6035 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6036 REG_WRITE(ah, AR_CFG, mask);
6037 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6038 "%s Setting CFG 0x%x\n", __func__,
6039 REG_READ(ah, AR_CFG));
6043 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6055 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6057 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6060 bool ath9k_hw_disable(struct ath_hal *ah)
6062 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6065 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6069 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6070 u8 rxchainmask, bool longcal,
6073 struct ath_hal_5416 *ahp = AH5416(ah);
6074 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6075 struct ath9k_channel *ichan =
6076 ath9k_regd_check_channel(ah, chan);
6080 if (ichan == NULL) {
6081 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6082 "%s: invalid channel %u/0x%x; no mapping\n",
6083 __func__, chan->channel, chan->channelFlags);
6088 (currCal->calState == CAL_RUNNING ||
6089 currCal->calState == CAL_WAITING)) {
6090 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6093 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6095 if (currCal->calState == CAL_WAITING) {
6097 ath9k_hw_reset_calibration(ah, currCal);
6103 ath9k_hw_getnf(ah, ichan);
6104 ath9k_hw_loadnf(ah, ah->ah_curchan);
6105 ath9k_hw_start_nfcal(ah);
6107 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6109 chan->channelFlags |= CHANNEL_CW_INT;
6110 ichan->channelFlags &= ~CHANNEL_CW_INT;
6117 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6119 struct ath_hal_5416 *ahp = AH5416(ah);
6122 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6123 ahp->ah_totalPowerMeasI[i] +=
6124 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6125 ahp->ah_totalPowerMeasQ[i] +=
6126 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6127 ahp->ah_totalIqCorrMeas[i] +=
6128 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6129 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6130 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6131 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6132 ahp->ah_totalPowerMeasQ[i],
6133 ahp->ah_totalIqCorrMeas[i]);
6137 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6139 struct ath_hal_5416 *ahp = AH5416(ah);
6142 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6143 ahp->ah_totalAdcIOddPhase[i] +=
6144 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6145 ahp->ah_totalAdcIEvenPhase[i] +=
6146 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6147 ahp->ah_totalAdcQOddPhase[i] +=
6148 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6149 ahp->ah_totalAdcQEvenPhase[i] +=
6150 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6152 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6153 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6154 "oddq=0x%08x; evenq=0x%08x;\n",
6155 ahp->ah_CalSamples, i,
6156 ahp->ah_totalAdcIOddPhase[i],
6157 ahp->ah_totalAdcIEvenPhase[i],
6158 ahp->ah_totalAdcQOddPhase[i],
6159 ahp->ah_totalAdcQEvenPhase[i]);
6163 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6165 struct ath_hal_5416 *ahp = AH5416(ah);
6168 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6169 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6170 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6171 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6172 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6173 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6174 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6175 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6176 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6178 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6179 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6180 "oddq=0x%08x; evenq=0x%08x;\n",
6181 ahp->ah_CalSamples, i,
6182 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6183 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6184 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6185 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6189 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6191 struct ath_hal_5416 *ahp = AH5416(ah);
6192 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6193 u32 qCoffDenom, iCoffDenom;
6194 int32_t qCoff, iCoff;
6197 for (i = 0; i < numChains; i++) {
6198 powerMeasI = ahp->ah_totalPowerMeasI[i];
6199 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6200 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6202 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6203 "Starting IQ Cal and Correction for Chain %d\n",
6206 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6207 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6208 i, ahp->ah_totalIqCorrMeas[i]);
6213 if (iqCorrMeas > 0x80000000) {
6214 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6218 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6219 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6220 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6221 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6222 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6225 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6226 qCoffDenom = powerMeasQ / 64;
6228 if (powerMeasQ != 0) {
6230 iCoff = iqCorrMeas / iCoffDenom;
6231 qCoff = powerMeasI / qCoffDenom - 64;
6232 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6233 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6234 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6235 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6238 iCoff = iCoff & 0x3f;
6239 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6240 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6241 if (iqCorrNeg == 0x0)
6242 iCoff = 0x40 - iCoff;
6246 else if (qCoff <= -16)
6249 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6250 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6253 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6254 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6256 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6257 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6259 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6260 "IQ Cal and Correction done for Chain %d\n",
6265 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6266 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6270 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6272 struct ath_hal_5416 *ahp = AH5416(ah);
6273 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6275 u32 qGainMismatch, iGainMismatch, val, i;
6277 for (i = 0; i < numChains; i++) {
6278 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6279 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6280 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6281 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6283 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6284 "Starting ADC Gain Cal for Chain %d\n", i);
6286 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6287 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6289 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6290 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6292 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6293 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6295 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6296 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6299 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6301 ((iEvenMeasOffset * 32) /
6302 iOddMeasOffset) & 0x3f;
6304 ((qOddMeasOffset * 32) /
6305 qEvenMeasOffset) & 0x3f;
6307 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6310 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6311 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6314 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6316 val |= (qGainMismatch) | (iGainMismatch << 6);
6317 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6319 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6320 "ADC Gain Cal done for Chain %d\n", i);
6324 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6325 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6326 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6330 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6332 struct ath_hal_5416 *ahp = AH5416(ah);
6333 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6334 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6335 const struct hal_percal_data *calData =
6336 ahp->ah_cal_list_curr->calData;
6338 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6340 for (i = 0; i < numChains; i++) {
6341 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6342 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6343 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6344 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6346 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6347 "Starting ADC DC Offset Cal for Chain %d\n", i);
6349 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6350 "Chn %d pwr_meas_odd_i = %d\n", i,
6352 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6353 "Chn %d pwr_meas_even_i = %d\n", i,
6355 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6356 "Chn %d pwr_meas_odd_q = %d\n", i,
6358 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6359 "Chn %d pwr_meas_even_q = %d\n", i,
6362 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6363 numSamples) & 0x1ff;
6364 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6365 numSamples) & 0x1ff;
6367 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6370 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6371 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6374 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6376 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6377 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6379 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6380 "ADC DC Offset Cal done for Chain %d\n", i);
6383 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6384 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6385 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6388 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6390 struct ath_hal_5416 *ahp = AH5416(ah);
6391 struct ath9k_channel *chan = ah->ah_curchan;
6393 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6395 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6396 ath9k_regd_get_ctl(ah, chan),
6397 ath9k_regd_get_antenna_allowed(ah,
6399 chan->maxRegTxPower * 2,
6400 min((u32) MAX_RATE_POWER,
6401 (u32) ah->ah_powerLimit)) != 0)
6408 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6409 struct ath9k_channel *chan,
6410 struct chan_centers *centers)
6413 struct ath_hal_5416 *ahp = AH5416(ah);
6415 if (!IS_CHAN_HT40(chan)) {
6416 centers->ctl_center = centers->ext_center =
6417 centers->synth_center = chan->channel;
6421 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6422 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6423 centers->synth_center =
6424 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6427 centers->synth_center =
6428 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6432 centers->ctl_center = centers->synth_center - (extoff *
6433 HT40_CHANNEL_CENTER_SHIFT);
6434 centers->ext_center = centers->synth_center + (extoff *
6438 ATH9K_HT_EXTPROTSPACING_20)
6440 HT40_CHANNEL_CENTER_SHIFT
6446 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6449 struct ath_hal_5416 *ahp = AH5416(ah);
6450 struct ath9k_channel *ichan =
6451 ath9k_regd_check_channel(ah, chan);
6452 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6456 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6459 if (currCal == NULL)
6462 if (ichan == NULL) {
6463 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6464 "%s: invalid channel %u/0x%x; no mapping\n",
6465 __func__, chan->channel, chan->channelFlags);
6470 if (currCal->calState != CAL_DONE) {
6471 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6472 "%s: Calibration state incorrect, %d\n",
6473 __func__, currCal->calState);
6478 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6481 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6482 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6483 __func__, currCal->calData->calType, chan->channel,
6484 chan->channelFlags);
6486 ichan->CalValid &= ~currCal->calData->calType;
6487 currCal->calState = CAL_WAITING;
6492 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6494 struct ath_hal_5416 *ahp = AH5416(ah);
6496 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6499 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6501 struct ath_hal_5416 *ahp = AH5416(ah);
6503 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6507 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6509 struct ath_hal_5416 *ahp = AH5416(ah);
6511 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6515 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6517 struct ath_hal_5416 *ahp = AH5416(ah);
6519 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6521 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6522 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6527 #ifdef CONFIG_ATH9K_RFKILL
6528 static void ath9k_enable_rfkill(struct ath_hal *ah)
6530 struct ath_hal_5416 *ahp = AH5416(ah);
6532 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6533 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6535 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6536 AR_GPIO_INPUT_MUX2_RFSILENT);
6538 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6539 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6541 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6543 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6546 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6553 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6556 struct ath_hal_5416 *ahp = AH5416(ah);
6558 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6559 ahp->ah_assocId = assocId;
6561 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6562 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6563 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6566 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6570 tsf = REG_READ(ah, AR_TSF_U32);
6571 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6575 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6580 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6583 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6584 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6590 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6593 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6595 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6598 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6600 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6604 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6605 enum ath9k_ant_setting settings,
6606 struct ath9k_channel *chan,
6611 struct ath_hal_5416 *ahp = AH5416(ah);
6612 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6614 if (AR_SREV_9280(ah)) {
6615 if (!tx_chainmask_cfg) {
6617 tx_chainmask_cfg = *tx_chainmask;
6618 rx_chainmask_cfg = *rx_chainmask;
6622 case ATH9K_ANT_FIXED_A:
6623 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6624 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6625 *antenna_cfgd = true;
6627 case ATH9K_ANT_FIXED_B:
6628 if (ah->ah_caps.tx_chainmask >
6629 ATH9K_ANTENNA1_CHAINMASK) {
6630 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6632 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6633 *antenna_cfgd = true;
6635 case ATH9K_ANT_VARIABLE:
6636 *tx_chainmask = tx_chainmask_cfg;
6637 *rx_chainmask = rx_chainmask_cfg;
6638 *antenna_cfgd = true;
6644 ahp->ah_diversityControl = settings;
6650 void ath9k_hw_setopmode(struct ath_hal *ah)
6652 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6656 ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
6657 u32 capability, u32 *result)
6659 struct ath_hal_5416 *ahp = AH5416(ah);
6660 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6663 case ATH9K_CAP_CIPHER:
6664 switch (capability) {
6665 case ATH9K_CIPHER_AES_CCM:
6666 case ATH9K_CIPHER_AES_OCB:
6667 case ATH9K_CIPHER_TKIP:
6668 case ATH9K_CIPHER_WEP:
6669 case ATH9K_CIPHER_MIC:
6670 case ATH9K_CIPHER_CLR:
6675 case ATH9K_CAP_TKIP_MIC:
6676 switch (capability) {
6680 return (ahp->ah_staId1Defaults &
6681 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6684 case ATH9K_CAP_TKIP_SPLIT:
6685 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6687 case ATH9K_CAP_WME_TKIPMIC:
6689 case ATH9K_CAP_PHYCOUNTERS:
6690 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6691 case ATH9K_CAP_DIVERSITY:
6692 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6693 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6695 case ATH9K_CAP_PHYDIAG:
6697 case ATH9K_CAP_MCAST_KEYSRCH:
6698 switch (capability) {
6702 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6705 return (ahp->ah_staId1Defaults &
6706 AR_STA_ID1_MCAST_KSRCH) ? true :
6711 case ATH9K_CAP_TSF_ADJUST:
6712 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6714 case ATH9K_CAP_RFSILENT:
6715 if (capability == 3)
6717 case ATH9K_CAP_ANT_CFG_2GHZ:
6718 *result = pCap->num_antcfg_2ghz;
6720 case ATH9K_CAP_ANT_CFG_5GHZ:
6721 *result = pCap->num_antcfg_5ghz;
6723 case ATH9K_CAP_TXPOW:
6724 switch (capability) {
6728 *result = ah->ah_powerLimit;
6731 *result = ah->ah_maxPowerLevel;
6734 *result = ah->ah_tpScale;
6744 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6746 struct ath_hal_5416 *ahp = AH5416(ah);
6747 struct ath9k_channel *chan = ah->ah_curchan;
6748 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6750 u32 halNumAntConfig;
6753 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6756 if (cfg < halNumAntConfig) {
6757 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6758 cfg, &ant_config)) {
6759 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6767 bool ath9k_hw_intrpend(struct ath_hal *ah)
6771 if (AR_SREV_9100(ah))
6774 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6775 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6778 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6779 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6780 && (host_isr != AR_INTR_SPURIOUS))
6786 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6790 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6792 bool fatal_int = false;
6794 if (!AR_SREV_9100(ah)) {
6795 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6796 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6797 == AR_RTC_STATUS_ON) {
6798 isr = REG_READ(ah, AR_ISR);
6804 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6808 if (!isr && !sync_cause)
6812 isr = REG_READ(ah, AR_ISR);
6816 struct ath_hal_5416 *ahp = AH5416(ah);
6818 if (isr & AR_ISR_BCNMISC) {
6820 isr2 = REG_READ(ah, AR_ISR_S2);
6821 if (isr2 & AR_ISR_S2_TIM)
6822 mask2 |= ATH9K_INT_TIM;
6823 if (isr2 & AR_ISR_S2_DTIM)
6824 mask2 |= ATH9K_INT_DTIM;
6825 if (isr2 & AR_ISR_S2_DTIMSYNC)
6826 mask2 |= ATH9K_INT_DTIMSYNC;
6827 if (isr2 & (AR_ISR_S2_CABEND))
6828 mask2 |= ATH9K_INT_CABEND;
6829 if (isr2 & AR_ISR_S2_GTT)
6830 mask2 |= ATH9K_INT_GTT;
6831 if (isr2 & AR_ISR_S2_CST)
6832 mask2 |= ATH9K_INT_CST;
6835 isr = REG_READ(ah, AR_ISR_RAC);
6836 if (isr == 0xffffffff) {
6841 *masked = isr & ATH9K_INT_COMMON;
6843 if (ahp->ah_intrMitigation) {
6845 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6846 *masked |= ATH9K_INT_RX;
6849 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6850 *masked |= ATH9K_INT_RX;
6852 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6856 *masked |= ATH9K_INT_TX;
6858 s0_s = REG_READ(ah, AR_ISR_S0_S);
6859 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6860 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6862 s1_s = REG_READ(ah, AR_ISR_S1_S);
6863 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6864 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6867 if (isr & AR_ISR_RXORN) {
6868 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6869 "%s: receive FIFO overrun interrupt\n",
6873 if (!AR_SREV_9100(ah)) {
6874 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
6875 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6876 if (isr5 & AR_ISR_S5_TIM_TIMER)
6877 *masked |= ATH9K_INT_TIM_TIMER;
6883 if (AR_SREV_9100(ah))
6888 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6892 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6893 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6894 "%s: received PCI FATAL interrupt\n",
6897 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6898 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6899 "%s: received PCI PERR interrupt\n",
6903 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6904 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6905 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6907 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6908 REG_WRITE(ah, AR_RC, 0);
6909 *masked |= ATH9K_INT_FATAL;
6911 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6912 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6913 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6917 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6918 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6923 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6925 return AH5416(ah)->ah_maskReg;
6928 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6930 struct ath_hal_5416 *ahp = AH5416(ah);
6931 u32 omask = ahp->ah_maskReg;
6933 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6935 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6938 if (omask & ATH9K_INT_GLOBAL) {
6939 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6941 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6942 (void) REG_READ(ah, AR_IER);
6943 if (!AR_SREV_9100(ah)) {
6944 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6945 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6947 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6948 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6952 mask = ints & ATH9K_INT_COMMON;
6955 if (ints & ATH9K_INT_TX) {
6956 if (ahp->ah_txOkInterruptMask)
6957 mask |= AR_IMR_TXOK;
6958 if (ahp->ah_txDescInterruptMask)
6959 mask |= AR_IMR_TXDESC;
6960 if (ahp->ah_txErrInterruptMask)
6961 mask |= AR_IMR_TXERR;
6962 if (ahp->ah_txEolInterruptMask)
6963 mask |= AR_IMR_TXEOL;
6965 if (ints & ATH9K_INT_RX) {
6966 mask |= AR_IMR_RXERR;
6967 if (ahp->ah_intrMitigation)
6968 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6970 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6971 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
6972 mask |= AR_IMR_GENTMR;
6975 if (ints & (ATH9K_INT_BMISC)) {
6976 mask |= AR_IMR_BCNMISC;
6977 if (ints & ATH9K_INT_TIM)
6978 mask2 |= AR_IMR_S2_TIM;
6979 if (ints & ATH9K_INT_DTIM)
6980 mask2 |= AR_IMR_S2_DTIM;
6981 if (ints & ATH9K_INT_DTIMSYNC)
6982 mask2 |= AR_IMR_S2_DTIMSYNC;
6983 if (ints & ATH9K_INT_CABEND)
6984 mask2 |= (AR_IMR_S2_CABEND);
6987 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6988 mask |= AR_IMR_BCNMISC;
6989 if (ints & ATH9K_INT_GTT)
6990 mask2 |= AR_IMR_S2_GTT;
6991 if (ints & ATH9K_INT_CST)
6992 mask2 |= AR_IMR_S2_CST;
6995 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
6997 REG_WRITE(ah, AR_IMR, mask);
6998 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7000 AR_IMR_S2_DTIMSYNC |
7004 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7005 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7006 ahp->ah_maskReg = ints;
7008 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
7009 if (ints & ATH9K_INT_TIM_TIMER)
7010 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7012 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7015 if (ints & ATH9K_INT_GLOBAL) {
7016 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7018 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7019 if (!AR_SREV_9100(ah)) {
7020 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7022 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7025 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7026 AR_INTR_SYNC_DEFAULT);
7027 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7028 AR_INTR_SYNC_DEFAULT);
7030 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7031 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7038 ath9k_hw_beaconinit(struct ath_hal *ah,
7039 u32 next_beacon, u32 beacon_period)
7041 struct ath_hal_5416 *ahp = AH5416(ah);
7044 ahp->ah_beaconInterval = beacon_period;
7046 switch (ah->ah_opmode) {
7048 case ATH9K_M_MONITOR:
7049 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7050 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7051 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7052 flags |= AR_TBTT_TIMER_EN;
7055 REG_SET_BIT(ah, AR_TXCFG,
7056 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7057 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7058 TU_TO_USEC(next_beacon +
7059 (ahp->ah_atimWindow ? ahp->
7060 ah_atimWindow : 1)));
7061 flags |= AR_NDP_TIMER_EN;
7062 case ATH9K_M_HOSTAP:
7063 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7064 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7065 TU_TO_USEC(next_beacon -
7067 dma_beacon_response_time));
7068 REG_WRITE(ah, AR_NEXT_SWBA,
7069 TU_TO_USEC(next_beacon -
7071 sw_beacon_response_time));
7073 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7077 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7078 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7079 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7080 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7082 beacon_period &= ~ATH9K_BEACON_ENA;
7083 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7084 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7085 ath9k_hw_reset_tsf(ah);
7088 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7092 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7093 const struct ath9k_beacon_state *bs)
7095 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7096 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7098 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7100 REG_WRITE(ah, AR_BEACON_PERIOD,
7101 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7102 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7103 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7105 REG_RMW_FIELD(ah, AR_RSSI_THR,
7106 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7108 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7110 if (bs->bs_sleepduration > beaconintval)
7111 beaconintval = bs->bs_sleepduration;
7113 dtimperiod = bs->bs_dtimperiod;
7114 if (bs->bs_sleepduration > dtimperiod)
7115 dtimperiod = bs->bs_sleepduration;
7117 if (beaconintval == dtimperiod)
7118 nextTbtt = bs->bs_nextdtim;
7120 nextTbtt = bs->bs_nexttbtt;
7122 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7124 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7126 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7128 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7131 REG_WRITE(ah, AR_NEXT_DTIM,
7132 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7133 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7135 REG_WRITE(ah, AR_SLEEP1,
7136 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7137 | AR_SLEEP1_ASSUME_DTIM);
7139 if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
7140 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7142 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7144 REG_WRITE(ah, AR_SLEEP2,
7145 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7147 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7148 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7150 REG_SET_BIT(ah, AR_TIMER_MODE,
7151 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7156 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7158 if (entry < ah->ah_caps.keycache_size) {
7159 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7160 if (val & AR_KEYTABLE_VALID)
7166 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7170 if (entry >= ah->ah_caps.keycache_size) {
7171 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7172 "%s: entry %u out of range\n", __func__, entry);
7175 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7177 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7178 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7179 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7180 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7181 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7182 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7183 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7184 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7186 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7187 u16 micentry = entry + 64;
7189 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7190 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7191 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7192 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7196 if (ah->ah_curchan == NULL)
7203 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7208 if (entry >= ah->ah_caps.keycache_size) {
7209 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7210 "%s: entry %u out of range\n", __func__, entry);
7215 macHi = (mac[5] << 8) | mac[4];
7216 macLo = (mac[3] << 24) | (mac[2] << 16)
7217 | (mac[1] << 8) | mac[0];
7219 macLo |= (macHi & 1) << 31;
7224 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7225 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7231 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7232 const struct ath9k_keyval *k,
7233 const u8 *mac, int xorKey)
7235 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7236 u32 key0, key1, key2, key3, key4;
7238 u32 xorMask = xorKey ?
7239 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7240 | ATH9K_KEY_XOR) : 0;
7241 struct ath_hal_5416 *ahp = AH5416(ah);
7243 if (entry >= pCap->keycache_size) {
7244 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7245 "%s: entry %u out of range\n", __func__, entry);
7248 switch (k->kv_type) {
7249 case ATH9K_CIPHER_AES_OCB:
7250 keyType = AR_KEYTABLE_TYPE_AES;
7252 case ATH9K_CIPHER_AES_CCM:
7253 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
7254 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7255 "%s: AES-CCM not supported by "
7256 "mac rev 0x%x\n", __func__,
7260 keyType = AR_KEYTABLE_TYPE_CCM;
7262 case ATH9K_CIPHER_TKIP:
7263 keyType = AR_KEYTABLE_TYPE_TKIP;
7264 if (ATH9K_IS_MIC_ENABLED(ah)
7265 && entry + 64 >= pCap->keycache_size) {
7266 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7267 "%s: entry %u inappropriate for TKIP\n",
7272 case ATH9K_CIPHER_WEP:
7273 if (k->kv_len < 40 / NBBY) {
7274 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7275 "%s: WEP key length %u too small\n",
7276 __func__, k->kv_len);
7279 if (k->kv_len <= 40 / NBBY)
7280 keyType = AR_KEYTABLE_TYPE_40;
7281 else if (k->kv_len <= 104 / NBBY)
7282 keyType = AR_KEYTABLE_TYPE_104;
7284 keyType = AR_KEYTABLE_TYPE_128;
7286 case ATH9K_CIPHER_CLR:
7287 keyType = AR_KEYTABLE_TYPE_CLR;
7290 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7291 "%s: cipher %u not supported\n", __func__,
7296 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7297 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7298 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7299 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7300 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7301 if (k->kv_len <= 104 / NBBY)
7304 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7305 u16 micentry = entry + 64;
7307 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7308 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7309 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7310 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7311 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7312 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7313 (void) ath9k_hw_keysetmac(ah, entry, mac);
7315 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7316 u32 mic0, mic1, mic2, mic3, mic4;
7318 mic0 = get_unaligned_le32(k->kv_mic + 0);
7319 mic2 = get_unaligned_le32(k->kv_mic + 4);
7320 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7321 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7322 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7323 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7324 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7325 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7326 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7327 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7328 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7329 AR_KEYTABLE_TYPE_CLR);
7334 mic0 = get_unaligned_le32(k->kv_mic + 0);
7335 mic2 = get_unaligned_le32(k->kv_mic + 4);
7336 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7337 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7338 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7341 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7342 AR_KEYTABLE_TYPE_CLR);
7344 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7345 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7346 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7347 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7349 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7350 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7351 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7352 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7353 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7354 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7356 (void) ath9k_hw_keysetmac(ah, entry, mac);
7359 if (ah->ah_curchan == NULL)
7366 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7368 struct ath_hal_5416 *ahp = AH5416(ah);
7369 u32 txcfg, curLevel, newLevel;
7370 enum ath9k_int omask;
7372 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7375 omask = ath9k_hw_set_interrupts(ah,
7376 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7378 txcfg = REG_READ(ah, AR_TXCFG);
7379 curLevel = MS(txcfg, AR_FTRIG);
7380 newLevel = curLevel;
7381 if (bIncTrigLevel) {
7382 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7384 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7386 if (newLevel != curLevel)
7387 REG_WRITE(ah, AR_TXCFG,
7388 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7390 ath9k_hw_set_interrupts(ah, omask);
7392 ah->ah_txTrigLevel = newLevel;
7394 return newLevel != curLevel;
7397 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7398 const struct ath9k_tx_queue_info *qinfo)
7401 struct ath_hal_5416 *ahp = AH5416(ah);
7402 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7403 struct ath9k_tx_queue_info *qi;
7405 if (q >= pCap->total_queues) {
7406 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7411 qi = &ahp->ah_txq[q];
7412 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7413 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7418 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7420 qi->tqi_ver = qinfo->tqi_ver;
7421 qi->tqi_subtype = qinfo->tqi_subtype;
7422 qi->tqi_qflags = qinfo->tqi_qflags;
7423 qi->tqi_priority = qinfo->tqi_priority;
7424 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7425 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
7427 qi->tqi_aifs = INIT_AIFS;
7428 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7429 cw = min(qinfo->tqi_cwmin, 1024U);
7431 while (qi->tqi_cwmin < cw)
7432 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7434 qi->tqi_cwmin = qinfo->tqi_cwmin;
7435 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7436 cw = min(qinfo->tqi_cwmax, 1024U);
7438 while (qi->tqi_cwmax < cw)
7439 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7441 qi->tqi_cwmax = INIT_CWMAX;
7443 if (qinfo->tqi_shretry != 0)
7444 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
7446 qi->tqi_shretry = INIT_SH_RETRY;
7447 if (qinfo->tqi_lgretry != 0)
7448 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
7450 qi->tqi_lgretry = INIT_LG_RETRY;
7451 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7452 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7453 qi->tqi_burstTime = qinfo->tqi_burstTime;
7454 qi->tqi_readyTime = qinfo->tqi_readyTime;
7456 switch (qinfo->tqi_subtype) {
7457 case ATH9K_WME_UPSD:
7458 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7459 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7467 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7468 struct ath9k_tx_queue_info *qinfo)
7470 struct ath_hal_5416 *ahp = AH5416(ah);
7471 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7472 struct ath9k_tx_queue_info *qi;
7474 if (q >= pCap->total_queues) {
7475 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7480 qi = &ahp->ah_txq[q];
7481 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7482 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7487 qinfo->tqi_qflags = qi->tqi_qflags;
7488 qinfo->tqi_ver = qi->tqi_ver;
7489 qinfo->tqi_subtype = qi->tqi_subtype;
7490 qinfo->tqi_qflags = qi->tqi_qflags;
7491 qinfo->tqi_priority = qi->tqi_priority;
7492 qinfo->tqi_aifs = qi->tqi_aifs;
7493 qinfo->tqi_cwmin = qi->tqi_cwmin;
7494 qinfo->tqi_cwmax = qi->tqi_cwmax;
7495 qinfo->tqi_shretry = qi->tqi_shretry;
7496 qinfo->tqi_lgretry = qi->tqi_lgretry;
7497 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7498 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7499 qinfo->tqi_burstTime = qi->tqi_burstTime;
7500 qinfo->tqi_readyTime = qi->tqi_readyTime;
7506 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7507 const struct ath9k_tx_queue_info *qinfo)
7509 struct ath_hal_5416 *ahp = AH5416(ah);
7510 struct ath9k_tx_queue_info *qi;
7511 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7515 case ATH9K_TX_QUEUE_BEACON:
7516 q = pCap->total_queues - 1;
7518 case ATH9K_TX_QUEUE_CAB:
7519 q = pCap->total_queues - 2;
7521 case ATH9K_TX_QUEUE_PSPOLL:
7524 case ATH9K_TX_QUEUE_UAPSD:
7525 q = pCap->total_queues - 3;
7527 case ATH9K_TX_QUEUE_DATA:
7528 for (q = 0; q < pCap->total_queues; q++)
7529 if (ahp->ah_txq[q].tqi_type ==
7530 ATH9K_TX_QUEUE_INACTIVE)
7532 if (q == pCap->total_queues) {
7533 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7534 "%s: no available tx queue\n", __func__);
7539 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7544 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7546 qi = &ahp->ah_txq[q];
7547 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7548 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7549 "%s: tx queue %u already active\n", __func__, q);
7552 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7553 qi->tqi_type = type;
7554 if (qinfo == NULL) {
7556 TXQ_FLAG_TXOKINT_ENABLE
7557 | TXQ_FLAG_TXERRINT_ENABLE
7558 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7559 qi->tqi_aifs = INIT_AIFS;
7560 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7561 qi->tqi_cwmax = INIT_CWMAX;
7562 qi->tqi_shretry = INIT_SH_RETRY;
7563 qi->tqi_lgretry = INIT_LG_RETRY;
7564 qi->tqi_physCompBuf = 0;
7566 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7567 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
7574 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7575 struct ath9k_tx_queue_info *qi)
7577 struct ath_hal_5416 *ahp = AH5416(ah);
7579 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7580 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7581 __func__, ahp->ah_txOkInterruptMask,
7582 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7583 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7585 REG_WRITE(ah, AR_IMR_S0,
7586 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7587 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7588 REG_WRITE(ah, AR_IMR_S1,
7589 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7590 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7591 REG_RMW_FIELD(ah, AR_IMR_S2,
7592 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7595 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7597 struct ath_hal_5416 *ahp = AH5416(ah);
7598 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7599 struct ath9k_tx_queue_info *qi;
7601 if (q >= pCap->total_queues) {
7602 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7606 qi = &ahp->ah_txq[q];
7607 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7608 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7613 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7616 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7617 ahp->ah_txOkInterruptMask &= ~(1 << q);
7618 ahp->ah_txErrInterruptMask &= ~(1 << q);
7619 ahp->ah_txDescInterruptMask &= ~(1 << q);
7620 ahp->ah_txEolInterruptMask &= ~(1 << q);
7621 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7622 ath9k_hw_set_txq_interrupts(ah, qi);
7627 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7629 struct ath_hal_5416 *ahp = AH5416(ah);
7630 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7631 struct ath9k_channel *chan = ah->ah_curchan;
7632 struct ath9k_tx_queue_info *qi;
7633 u32 cwMin, chanCwMin, value;
7635 if (q >= pCap->total_queues) {
7636 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7640 qi = &ahp->ah_txq[q];
7641 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7642 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7647 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7649 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7650 if (chan && IS_CHAN_B(chan))
7651 chanCwMin = INIT_CWMIN_11B;
7653 chanCwMin = INIT_CWMIN;
7655 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7657 cwMin = qi->tqi_cwmin;
7659 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7660 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7661 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7663 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7664 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7665 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7666 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7669 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7670 REG_WRITE(ah, AR_DMISC(q),
7671 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7673 if (qi->tqi_cbrPeriod) {
7674 REG_WRITE(ah, AR_QCBRCFG(q),
7675 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7676 | SM(qi->tqi_cbrOverflowLimit,
7677 AR_Q_CBRCFG_OVF_THRESH));
7678 REG_WRITE(ah, AR_QMISC(q),
7680 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7681 tqi_cbrOverflowLimit
7683 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7687 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7688 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7689 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7690 AR_Q_RDYTIMECFG_EN);
7693 REG_WRITE(ah, AR_DCHNTIME(q),
7694 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7695 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7697 if (qi->tqi_burstTime
7698 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7699 REG_WRITE(ah, AR_QMISC(q),
7702 AR_Q_MISC_RDYTIME_EXP_POLICY);
7706 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7707 REG_WRITE(ah, AR_DMISC(q),
7708 REG_READ(ah, AR_DMISC(q)) |
7709 AR_D_MISC_POST_FR_BKOFF_DIS);
7711 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7712 REG_WRITE(ah, AR_DMISC(q),
7713 REG_READ(ah, AR_DMISC(q)) |
7714 AR_D_MISC_FRAG_BKOFF_EN);
7716 switch (qi->tqi_type) {
7717 case ATH9K_TX_QUEUE_BEACON:
7718 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7719 | AR_Q_MISC_FSP_DBA_GATED
7720 | AR_Q_MISC_BEACON_USE
7721 | AR_Q_MISC_CBR_INCR_DIS1);
7723 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7724 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7725 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7726 | AR_D_MISC_BEACON_USE
7727 | AR_D_MISC_POST_FR_BKOFF_DIS);
7729 case ATH9K_TX_QUEUE_CAB:
7730 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7731 | AR_Q_MISC_FSP_DBA_GATED
7732 | AR_Q_MISC_CBR_INCR_DIS1
7733 | AR_Q_MISC_CBR_INCR_DIS0);
7734 value = (qi->tqi_readyTime
7735 - (ah->ah_config.sw_beacon_response_time -
7736 ah->ah_config.dma_beacon_response_time)
7738 ah->ah_config.additional_swba_backoff) *
7740 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7741 value | AR_Q_RDYTIMECFG_EN);
7742 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7743 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7744 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7746 case ATH9K_TX_QUEUE_PSPOLL:
7747 REG_WRITE(ah, AR_QMISC(q),
7749 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7751 case ATH9K_TX_QUEUE_UAPSD:
7752 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7753 | AR_D_MISC_POST_FR_BKOFF_DIS);
7759 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7760 REG_WRITE(ah, AR_DMISC(q),
7761 REG_READ(ah, AR_DMISC(q)) |
7762 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7763 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7764 AR_D_MISC_POST_FR_BKOFF_DIS);
7767 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7768 ahp->ah_txOkInterruptMask |= 1 << q;
7770 ahp->ah_txOkInterruptMask &= ~(1 << q);
7771 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7772 ahp->ah_txErrInterruptMask |= 1 << q;
7774 ahp->ah_txErrInterruptMask &= ~(1 << q);
7775 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7776 ahp->ah_txDescInterruptMask |= 1 << q;
7778 ahp->ah_txDescInterruptMask &= ~(1 << q);
7779 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7780 ahp->ah_txEolInterruptMask |= 1 << q;
7782 ahp->ah_txEolInterruptMask &= ~(1 << q);
7783 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7784 ahp->ah_txUrnInterruptMask |= 1 << q;
7786 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7787 ath9k_hw_set_txq_interrupts(ah, qi);
7792 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7794 struct ath_hal_5416 *ahp = AH5416(ah);
7795 *txqs &= ahp->ah_intrTxqs;
7796 ahp->ah_intrTxqs &= ~(*txqs);
7800 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7801 u32 segLen, bool firstSeg,
7802 bool lastSeg, const struct ath_desc *ds0)
7804 struct ar5416_desc *ads = AR5416DESC(ds);
7807 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7808 } else if (lastSeg) {
7810 ads->ds_ctl1 = segLen;
7811 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7812 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7815 ads->ds_ctl1 = segLen | AR_TxMore;
7819 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7820 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7821 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7822 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7823 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7827 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7829 struct ar5416_desc *ads = AR5416DESC(ds);
7831 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7832 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7833 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7834 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7835 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7839 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7841 struct ar5416_desc *ads = AR5416DESC(ds);
7843 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7844 return -EINPROGRESS;
7846 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7847 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7848 ds->ds_txstat.ts_status = 0;
7849 ds->ds_txstat.ts_flags = 0;
7851 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7852 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7853 if (ads->ds_txstatus1 & AR_Filtered)
7854 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7855 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7856 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7857 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7858 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7859 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7860 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7862 if (ads->ds_txstatus1 & AR_DescCfgErr)
7863 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7864 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7865 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7866 ath9k_hw_updatetxtriglevel(ah, true);
7868 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7869 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7870 ath9k_hw_updatetxtriglevel(ah, true);
7872 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7873 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7874 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7875 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7878 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7879 switch (ds->ds_txstat.ts_rateindex) {
7881 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7884 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7887 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7890 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7894 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7895 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7896 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7897 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7898 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7899 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7900 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7901 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7902 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7903 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7904 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7905 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7906 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7907 ds->ds_txstat.ts_antenna = 1;
7913 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7914 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7915 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7917 struct ar5416_desc *ads = AR5416DESC(ds);
7918 struct ath_hal_5416 *ahp = AH5416(ah);
7920 txPower += ahp->ah_txPowerIndexOffset;
7924 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7925 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7926 | SM(txPower, AR_XmitPower)
7927 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7928 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7929 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7930 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7933 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7934 | SM(type, AR_FrameType)
7935 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7936 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7937 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7939 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7941 if (AR_SREV_9285(ah)) {
7951 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7952 struct ath_desc *lastds,
7953 u32 durUpdateEn, u32 rtsctsRate,
7955 struct ath9k_11n_rate_series series[],
7956 u32 nseries, u32 flags)
7958 struct ar5416_desc *ads = AR5416DESC(ds);
7959 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7963 (void) rtsctsDuration;
7965 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7966 ds_ctl0 = ads->ds_ctl0;
7968 if (flags & ATH9K_TXDESC_RTSENA) {
7969 ds_ctl0 &= ~AR_CTSEnable;
7970 ds_ctl0 |= AR_RTSEnable;
7972 ds_ctl0 &= ~AR_RTSEnable;
7973 ds_ctl0 |= AR_CTSEnable;
7976 ads->ds_ctl0 = ds_ctl0;
7979 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7982 ads->ds_ctl2 = set11nTries(series, 0)
7983 | set11nTries(series, 1)
7984 | set11nTries(series, 2)
7985 | set11nTries(series, 3)
7986 | (durUpdateEn ? AR_DurUpdateEna : 0)
7987 | SM(0, AR_BurstDur);
7989 ads->ds_ctl3 = set11nRate(series, 0)
7990 | set11nRate(series, 1)
7991 | set11nRate(series, 2)
7992 | set11nRate(series, 3);
7994 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
7995 | set11nPktDurRTSCTS(series, 1);
7997 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
7998 | set11nPktDurRTSCTS(series, 3);
8000 ads->ds_ctl7 = set11nRateFlags(series, 0)
8001 | set11nRateFlags(series, 1)
8002 | set11nRateFlags(series, 2)
8003 | set11nRateFlags(series, 3)
8004 | SM(rtsctsRate, AR_RTSCTSRate);
8005 last_ads->ds_ctl2 = ads->ds_ctl2;
8006 last_ads->ds_ctl3 = ads->ds_ctl3;
8010 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8013 struct ar5416_desc *ads = AR5416DESC(ds);
8015 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8017 ads->ds_ctl6 &= ~AR_AggrLen;
8018 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8022 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8025 struct ar5416_desc *ads = AR5416DESC(ds);
8028 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8030 ctl6 = ads->ds_ctl6;
8031 ctl6 &= ~AR_PadDelim;
8032 ctl6 |= SM(numDelims, AR_PadDelim);
8033 ads->ds_ctl6 = ctl6;
8036 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8038 struct ar5416_desc *ads = AR5416DESC(ds);
8040 ads->ds_ctl1 |= AR_IsAggr;
8041 ads->ds_ctl1 &= ~AR_MoreAggr;
8042 ads->ds_ctl6 &= ~AR_PadDelim;
8045 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8047 struct ar5416_desc *ads = AR5416DESC(ds);
8049 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8053 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8056 struct ar5416_desc *ads = AR5416DESC(ds);
8058 ads->ds_ctl2 &= ~AR_BurstDur;
8059 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8063 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8066 struct ar5416_desc *ads = AR5416DESC(ds);
8069 ads->ds_ctl0 |= AR_VirtMoreFrag;
8071 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8074 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8076 REG_WRITE(ah, AR_RXDP, rxdp);
8079 void ath9k_hw_rxena(struct ath_hal *ah)
8081 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8084 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8088 REG_SET_BIT(ah, AR_DIAG_SW,
8089 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8092 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8095 REG_CLR_BIT(ah, AR_DIAG_SW,
8099 reg = REG_READ(ah, AR_OBS_BUS_1);
8100 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8101 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8107 REG_CLR_BIT(ah, AR_DIAG_SW,
8108 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8115 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8118 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8119 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8123 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8124 u32 size, u32 flags)
8126 struct ar5416_desc *ads = AR5416DESC(ds);
8127 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
8129 ads->ds_ctl1 = size & AR_BufLen;
8130 if (flags & ATH9K_RXDESC_INTREQ)
8131 ads->ds_ctl1 |= AR_RxIntrReq;
8133 ads->ds_rxstatus8 &= ~AR_RxDone;
8134 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
8135 memset(&(ads->u), 0, sizeof(ads->u));
8140 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8141 u32 pa, struct ath_desc *nds, u64 tsf)
8143 struct ar5416_desc ads;
8144 struct ar5416_desc *adsp = AR5416DESC(ds);
8146 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8147 return -EINPROGRESS;
8149 ads.u.rx = adsp->u.rx;
8151 ds->ds_rxstat.rs_status = 0;
8152 ds->ds_rxstat.rs_flags = 0;
8154 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8155 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8157 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8158 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8159 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8160 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8161 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8162 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8163 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8164 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8165 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8167 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8169 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8170 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8172 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8173 ds->ds_rxstat.rs_moreaggr =
8174 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8175 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8176 ds->ds_rxstat.rs_flags =
8177 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8178 ds->ds_rxstat.rs_flags |=
8179 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8181 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8182 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8183 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8184 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8185 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8186 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8188 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8190 if (ads.ds_rxstatus8 & AR_CRCErr)
8191 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8192 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8195 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8196 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8197 ds->ds_rxstat.rs_phyerr = phyerr;
8198 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8199 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8200 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8201 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8207 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8208 struct ath9k_rate_table *rt)
8212 if (rt->rateCodeToIndex[0] != 0)
8214 for (i = 0; i < 256; i++)
8215 rt->rateCodeToIndex[i] = (u8) -1;
8216 for (i = 0; i < rt->rateCount; i++) {
8217 u8 code = rt->info[i].rateCode;
8218 u8 cix = rt->info[i].controlRate;
8220 rt->rateCodeToIndex[code] = i;
8221 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8223 rt->info[i].lpAckDuration =
8224 ath9k_hw_computetxtime(ah, rt,
8225 WLAN_CTRL_FRAME_SIZE,
8228 rt->info[i].spAckDuration =
8229 ath9k_hw_computetxtime(ah, rt,
8230 WLAN_CTRL_FRAME_SIZE,
8236 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8239 struct ath9k_rate_table *rt;
8241 case ATH9K_MODE_SEL_11A:
8242 rt = &ar5416_11a_table;
8244 case ATH9K_MODE_SEL_11B:
8245 rt = &ar5416_11b_table;
8247 case ATH9K_MODE_SEL_11G:
8248 rt = &ar5416_11g_table;
8250 case ATH9K_MODE_SEL_11NG_HT20:
8251 case ATH9K_MODE_SEL_11NG_HT40PLUS:
8252 case ATH9K_MODE_SEL_11NG_HT40MINUS:
8253 rt = &ar5416_11ng_table;
8255 case ATH9K_MODE_SEL_11NA_HT20:
8256 case ATH9K_MODE_SEL_11NA_HT40PLUS:
8257 case ATH9K_MODE_SEL_11NA_HT40MINUS:
8258 rt = &ar5416_11na_table;
8261 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8265 ath9k_hw_setup_rate_table(ah, rt);
8269 static const char *ath9k_hw_devname(u16 devid)
8272 case AR5416_DEVID_PCI:
8273 case AR5416_DEVID_PCIE:
8274 return "Atheros 5416";
8275 case AR9160_DEVID_PCI:
8276 return "Atheros 9160";
8277 case AR9280_DEVID_PCI:
8278 case AR9280_DEVID_PCIE:
8279 return "Atheros 9280";
8284 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8286 return vendorid == ATHEROS_VENDOR_ID ?
8287 ath9k_hw_devname(devid) : NULL;
8290 struct ath_hal *ath9k_hw_attach(u16 devid,
8291 struct ath_softc *sc,
8295 struct ath_hal *ah = NULL;
8298 case AR5416_DEVID_PCI:
8299 case AR5416_DEVID_PCIE:
8300 case AR9160_DEVID_PCI:
8301 case AR9280_DEVID_PCI:
8302 case AR9280_DEVID_PCIE:
8303 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8306 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8307 "devid=0x%x not supported.\n", devid);
8313 ah->ah_devid = ah->ah_devid;
8314 ah->ah_subvendorid = ah->ah_subvendorid;
8315 ah->ah_macVersion = ah->ah_macVersion;
8316 ah->ah_macRev = ah->ah_macRev;
8317 ah->ah_phyRev = ah->ah_phyRev;
8318 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8319 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8325 ath9k_hw_computetxtime(struct ath_hal *ah,
8326 const struct ath9k_rate_table *rates,
8327 u32 frameLen, u16 rateix,
8330 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8333 kbps = rates->info[rateix].rateKbps;
8337 switch (rates->info[rateix].phy) {
8340 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8341 if (shortPreamble && rates->info[rateix].shortPreamble)
8343 numBits = frameLen << 3;
8344 txTime = CCK_SIFS_TIME + phyTime
8345 + ((numBits * 1000) / kbps);
8348 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8350 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8352 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8353 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8354 txTime = OFDM_SIFS_TIME_QUARTER
8355 + OFDM_PREAMBLE_TIME_QUARTER
8356 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8357 } else if (ah->ah_curchan &&
8358 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8360 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8362 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8363 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8364 txTime = OFDM_SIFS_TIME_HALF +
8365 OFDM_PREAMBLE_TIME_HALF
8366 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8368 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8370 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8371 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8372 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8373 + (numSymbols * OFDM_SYMBOL_TIME);
8378 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8379 "%s: unknown phy %u (rate ix %u)\n", __func__,
8380 rates->info[rateix].phy, rateix);
8387 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8389 if (flags & CHANNEL_2GHZ) {
8393 return (freq - 2407) / 5;
8395 return 15 + ((freq - 2512) / 20);
8396 } else if (flags & CHANNEL_5GHZ) {
8397 if (ath9k_regd_is_public_safety_sku(ah) &&
8398 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8399 return ((freq * 10) +
8400 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8401 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8402 return (freq - 4000) / 5;
8404 return (freq - 5000) / 5;
8410 return (freq - 2407) / 5;
8412 if (ath9k_regd_is_public_safety_sku(ah)
8413 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8414 return ((freq * 10) +
8416 2) ? 5 : 0) - 49400) / 5;
8417 } else if (freq > 4900) {
8418 return (freq - 4000) / 5;
8420 return 15 + ((freq - 2512) / 20);
8423 return (freq - 5000) / 5;
8428 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8430 struct ath9k_channel *ichan;
8432 ichan = ath9k_regd_check_channel(ah, chan);
8433 if (ichan == NULL) {
8434 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8435 "%s: invalid channel %u/0x%x; no mapping\n",
8436 __func__, chan->channel, chan->channelFlags);
8439 if (ichan->rawNoiseFloor == 0) {
8440 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8441 return NOISE_FLOOR[mode];
8443 return ichan->rawNoiseFloor;
8446 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8448 struct ath_hal_5416 *ahp = AH5416(ah);
8451 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8453 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8457 bool ath9k_hw_phycounters(struct ath_hal *ah)
8459 struct ath_hal_5416 *ahp = AH5416(ah);
8461 return ahp->ah_hasHwPhyCounters ? true : false;
8464 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8466 return REG_READ(ah, AR_QTXDP(q));
8469 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8472 REG_WRITE(ah, AR_QTXDP(q), txdp);
8477 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8479 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8481 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8486 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8490 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8493 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8499 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8503 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8505 for (wait = 1000; wait != 0; wait--) {
8506 if (ath9k_hw_numtxpending(ah, q) == 0)
8511 if (ath9k_hw_numtxpending(ah, q)) {
8514 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8515 "%s: Num of pending TX Frames %d on Q %d\n",
8516 __func__, ath9k_hw_numtxpending(ah, q), q);
8518 for (j = 0; j < 2; j++) {
8519 tsfLow = REG_READ(ah, AR_TSF_L32);
8520 REG_WRITE(ah, AR_QUIET2,
8521 SM(10, AR_QUIET2_QUIET_DUR));
8522 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8523 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8524 REG_SET_BIT(ah, AR_TIMER_MODE,
8527 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8531 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8532 "%s: TSF have moved while trying to set "
8533 "quiet time TSF: 0x%08x\n",
8537 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8540 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8544 while (ath9k_hw_numtxpending(ah, q)) {
8545 if ((--wait) == 0) {
8546 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8547 "%s: Failed to stop Tx DMA in 100 "
8548 "msec after killing last frame\n",
8555 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8558 REG_WRITE(ah, AR_Q_TXD, 0);