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 ATH9K_MODE_11A;
230 return ATH9K_MODE_11G;
231 return ATH9K_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 ieee80211_band freq_band)
470 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471 struct modal_eep_header *pModal =
472 &(eep->modalHeader[IEEE80211_BAND_5GHZ == 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 == ATH9K_MODE_11G || mode == ATH9K_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 == ATH9K_MODE_11G || mode == ATH9K_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 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2974 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
2976 if (eeval & AR5416_OPFLAGS_11A) {
2977 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
2978 if (ah->ah_config.ht_enable) {
2979 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
2980 set_bit(ATH9K_MODE_11NA_HT20,
2981 pCap->wireless_modes);
2982 if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
2983 set_bit(ATH9K_MODE_11NA_HT40PLUS,
2984 pCap->wireless_modes);
2985 set_bit(ATH9K_MODE_11NA_HT40MINUS,
2986 pCap->wireless_modes);
2991 if (eeval & AR5416_OPFLAGS_11G) {
2992 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
2993 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
2994 if (ah->ah_config.ht_enable) {
2995 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
2996 set_bit(ATH9K_MODE_11NG_HT20,
2997 pCap->wireless_modes);
2998 if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
2999 set_bit(ATH9K_MODE_11NG_HT40PLUS,
3000 pCap->wireless_modes);
3001 set_bit(ATH9K_MODE_11NG_HT40MINUS,
3002 pCap->wireless_modes);
3007 pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
3008 if ((ah->ah_isPciExpress)
3009 || (eeval & AR5416_OPFLAGS_11A)) {
3010 pCap->rx_chainmask =
3011 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3013 pCap->rx_chainmask =
3014 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3017 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3018 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3020 pCap->low_2ghz_chan = 2312;
3021 pCap->high_2ghz_chan = 2732;
3023 pCap->low_5ghz_chan = 4920;
3024 pCap->high_5ghz_chan = 6100;
3026 pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
3027 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
3028 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
3030 pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
3031 pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
3032 pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
3034 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
3036 if (ah->ah_config.ht_enable)
3037 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3039 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
3041 pCap->hw_caps |= ATH9K_HW_CAP_GTT;
3042 pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
3043 pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
3044 pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
3046 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3047 pCap->total_queues =
3048 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3050 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
3052 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3053 pCap->keycache_size =
3054 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3056 pCap->keycache_size = AR_KEYTABLE_SIZE;
3058 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3059 pCap->num_mr_retries = 4;
3060 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3062 if (AR_SREV_9280_10_OR_LATER(ah))
3063 pCap->num_gpio_pins = AR928X_NUM_GPIO;
3065 pCap->num_gpio_pins = AR_NUM_GPIO;
3067 if (AR_SREV_9280_10_OR_LATER(ah)) {
3068 pCap->hw_caps |= ATH9K_HW_CAP_WOW;
3069 pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3071 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
3072 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3075 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3076 pCap->hw_caps |= ATH9K_HW_CAP_CST;
3077 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
3079 pCap->rts_aggr_limit = (8 * 1024);
3082 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
3084 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3085 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3086 ahp->ah_gpioSelect =
3087 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3089 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3091 ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true,
3093 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3096 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3097 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3098 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3099 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3100 (ah->ah_macVersion == AR_SREV_VERSION_9280))
3101 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3103 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
3105 if (AR_SREV_9280(ah))
3106 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
3108 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
3110 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3112 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3113 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3114 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3115 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3118 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3119 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3122 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3124 pCap->num_antcfg_5ghz =
3125 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_5GHZ);
3126 pCap->num_antcfg_2ghz =
3127 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_2GHZ);
3132 static void ar5416DisablePciePhy(struct ath_hal *ah)
3134 if (!AR_SREV_9100(ah))
3137 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3138 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3139 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3140 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3141 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3142 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3143 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3144 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3145 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3147 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3150 static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3152 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3154 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3155 AR_RTC_FORCE_WAKE_EN);
3156 if (!AR_SREV_9100(ah))
3157 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3159 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3164 static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3166 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3168 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3170 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
3171 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3172 AR_RTC_FORCE_WAKE_ON_INT);
3174 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3175 AR_RTC_FORCE_WAKE_EN);
3180 static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3187 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3188 AR_RTC_STATUS_SHUTDOWN) {
3189 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3194 if (AR_SREV_9100(ah))
3195 REG_SET_BIT(ah, AR_RTC_RESET,
3198 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3199 AR_RTC_FORCE_WAKE_EN);
3202 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3203 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3204 if (val == AR_RTC_STATUS_ON)
3207 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3208 AR_RTC_FORCE_WAKE_EN);
3211 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3212 "%s: Failed to wakeup in %uus\n",
3213 __func__, POWER_UP_TIME / 20);
3218 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3222 bool ath9k_hw_setpower(struct ath_hal *ah,
3223 enum ath9k_power_mode mode)
3225 struct ath_hal_5416 *ahp = AH5416(ah);
3226 static const char *modes[] = {
3232 int status = true, setChip = true;
3234 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3235 modes[ahp->ah_powerMode], modes[mode],
3236 setChip ? "set chip " : "");
3239 case ATH9K_PM_AWAKE:
3240 status = ath9k_hw_set_power_awake(ah, setChip);
3242 case ATH9K_PM_FULL_SLEEP:
3243 ath9k_set_power_sleep(ah, setChip);
3244 ahp->ah_chipFullSleep = true;
3246 case ATH9K_PM_NETWORK_SLEEP:
3247 ath9k_set_power_network_sleep(ah, setChip);
3250 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3251 "%s: unknown power mode %u\n", __func__, mode);
3254 ahp->ah_powerMode = mode;
3258 static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3259 struct ath_softc *sc,
3263 struct ath_hal_5416 *ahp;
3266 #ifndef CONFIG_SLOW_ANT_DIV
3271 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3277 ath9k_hw_set_defaults(ah);
3279 if (ah->ah_config.intr_mitigation != 0)
3280 ahp->ah_intrMitigation = true;
3282 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3283 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3289 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3290 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3296 if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
3297 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3298 ah->ah_config.serialize_regmode =
3301 ah->ah_config.serialize_regmode =
3305 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3306 "%s: serialize_regmode is %d\n",
3307 __func__, ah->ah_config.serialize_regmode);
3309 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3310 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3311 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3312 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3313 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3314 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3315 "this driver\n", __func__,
3316 ah->ah_macVersion, ah->ah_macRev);
3317 ecode = -EOPNOTSUPP;
3321 if (AR_SREV_9100(ah)) {
3322 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3323 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3324 ah->ah_isPciExpress = false;
3326 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3328 if (AR_SREV_9160_10_OR_LATER(ah)) {
3329 if (AR_SREV_9280_10_OR_LATER(ah)) {
3330 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3331 ahp->ah_adcGainCalData.calData =
3332 &adc_gain_cal_single_sample;
3333 ahp->ah_adcDcCalData.calData =
3334 &adc_dc_cal_single_sample;
3335 ahp->ah_adcDcCalInitData.calData =
3338 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3339 ahp->ah_adcGainCalData.calData =
3340 &adc_gain_cal_multi_sample;
3341 ahp->ah_adcDcCalData.calData =
3342 &adc_dc_cal_multi_sample;
3343 ahp->ah_adcDcCalInitData.calData =
3347 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3350 if (AR_SREV_9160(ah)) {
3351 ah->ah_config.enable_ani = 1;
3352 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3353 ATH9K_ANI_FIRSTEP_LEVEL);
3355 ahp->ah_ani_function = ATH9K_ANI_ALL;
3356 if (AR_SREV_9280_10_OR_LATER(ah)) {
3357 ahp->ah_ani_function &=
3358 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3362 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3363 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3364 ah->ah_macVersion, ah->ah_macRev);
3366 if (AR_SREV_9280_20_OR_LATER(ah)) {
3367 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3368 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3369 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3370 ARRAY_SIZE(ar9280Common_9280_2), 2);
3372 if (ah->ah_config.pcie_clock_req) {
3373 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3374 ar9280PciePhy_clkreq_off_L1_9280,
3376 (ar9280PciePhy_clkreq_off_L1_9280),
3379 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3380 ar9280PciePhy_clkreq_always_on_L1_9280,
3382 (ar9280PciePhy_clkreq_always_on_L1_9280),
3385 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3386 ar9280Modes_fast_clock_9280_2,
3387 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3389 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3390 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3391 ARRAY_SIZE(ar9280Modes_9280), 6);
3392 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3393 ARRAY_SIZE(ar9280Common_9280), 2);
3394 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3395 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3396 ARRAY_SIZE(ar5416Modes_9160), 6);
3397 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3398 ARRAY_SIZE(ar5416Common_9160), 2);
3399 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3400 ARRAY_SIZE(ar5416Bank0_9160), 2);
3401 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3402 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3403 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3404 ARRAY_SIZE(ar5416Bank1_9160), 2);
3405 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3406 ARRAY_SIZE(ar5416Bank2_9160), 2);
3407 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3408 ARRAY_SIZE(ar5416Bank3_9160), 3);
3409 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3410 ARRAY_SIZE(ar5416Bank6_9160), 3);
3411 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3412 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3413 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3414 ARRAY_SIZE(ar5416Bank7_9160), 2);
3415 if (AR_SREV_9160_11(ah)) {
3416 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3417 ar5416Addac_91601_1,
3418 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3420 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3421 ARRAY_SIZE(ar5416Addac_9160), 2);
3423 } else if (AR_SREV_9100_OR_LATER(ah)) {
3424 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3425 ARRAY_SIZE(ar5416Modes_9100), 6);
3426 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3427 ARRAY_SIZE(ar5416Common_9100), 2);
3428 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3429 ARRAY_SIZE(ar5416Bank0_9100), 2);
3430 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3431 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3432 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3433 ARRAY_SIZE(ar5416Bank1_9100), 2);
3434 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3435 ARRAY_SIZE(ar5416Bank2_9100), 2);
3436 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3437 ARRAY_SIZE(ar5416Bank3_9100), 3);
3438 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3439 ARRAY_SIZE(ar5416Bank6_9100), 3);
3440 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3441 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3442 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3443 ARRAY_SIZE(ar5416Bank7_9100), 2);
3444 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3445 ARRAY_SIZE(ar5416Addac_9100), 2);
3447 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3448 ARRAY_SIZE(ar5416Modes), 6);
3449 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3450 ARRAY_SIZE(ar5416Common), 2);
3451 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3452 ARRAY_SIZE(ar5416Bank0), 2);
3453 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3454 ARRAY_SIZE(ar5416BB_RfGain), 3);
3455 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3456 ARRAY_SIZE(ar5416Bank1), 2);
3457 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3458 ARRAY_SIZE(ar5416Bank2), 2);
3459 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3460 ARRAY_SIZE(ar5416Bank3), 3);
3461 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3462 ARRAY_SIZE(ar5416Bank6), 3);
3463 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3464 ARRAY_SIZE(ar5416Bank6TPC), 3);
3465 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3466 ARRAY_SIZE(ar5416Bank7), 2);
3467 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3468 ARRAY_SIZE(ar5416Addac), 2);
3471 if (ah->ah_isPciExpress)
3472 ath9k_hw_configpcipowersave(ah, 0);
3474 ar5416DisablePciePhy(ah);
3476 ecode = ath9k_hw_post_attach(ah);
3480 #ifndef CONFIG_SLOW_ANT_DIV
3481 if (ah->ah_devid == AR9280_DEVID_PCI) {
3482 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3483 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3485 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3486 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3488 INI_RA(&ahp->ah_iniModes, i, j) =
3489 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3496 if (!ath9k_hw_fill_cap_info(ah)) {
3497 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3498 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3503 ecode = ath9k_hw_init_macaddr(ah);
3505 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3506 "%s: failed initializing mac address\n",
3511 if (AR_SREV_9285(ah))
3512 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3514 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3516 #ifndef ATH_NF_PER_CHAN
3518 ath9k_init_nfcal_hist_buffer(ah);
3525 ath9k_hw_detach((struct ath_hal *) ahp);
3531 void ath9k_hw_detach(struct ath_hal *ah)
3533 if (!AR_SREV_9100(ah))
3534 ath9k_hw_ani_detach(ah);
3535 ath9k_hw_rfdetach(ah);
3537 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3541 bool ath9k_get_channel_edges(struct ath_hal *ah,
3542 u16 flags, u16 *low,
3545 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3547 if (flags & CHANNEL_5GHZ) {
3548 *low = pCap->low_5ghz_chan;
3549 *high = pCap->high_5ghz_chan;
3552 if ((flags & CHANNEL_2GHZ)) {
3553 *low = pCap->low_2ghz_chan;
3554 *high = pCap->high_2ghz_chan;
3561 static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3570 u8 currPwr = pwrMin;
3571 u16 idxL = 0, idxR = 0;
3573 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3574 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3575 numIntercepts, &(idxL),
3579 if (idxL == numIntercepts - 1)
3580 idxL = (u16) (numIntercepts - 2);
3581 if (pPwrList[idxL] == pPwrList[idxR])
3584 k = (u16) (((currPwr -
3588 currPwr) * pVpdList[idxL]) /
3591 pRetVpdList[i] = (u8) k;
3599 ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3600 struct ath9k_channel *chan,
3601 struct cal_data_per_freq *pRawDataSet,
3605 int16_t *pMinCalPower,
3606 u16 *pPdGainBoundaries,
3612 u16 idxL = 0, idxR = 0, numPiers;
3613 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3614 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3615 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3616 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3617 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3618 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3620 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3621 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3622 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3625 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3627 int16_t minDelta = 0;
3628 struct chan_centers centers;
3630 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3632 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3633 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3637 match = ath9k_hw_get_lower_upper_index((u8)
3642 numPiers, &idxL, &idxR);
3645 for (i = 0; i < numXpdGains; i++) {
3646 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3647 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3648 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3653 AR5416_PD_GAIN_ICEPTS,
3657 for (i = 0; i < numXpdGains; i++) {
3658 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3659 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3660 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3661 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3663 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3666 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3667 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3670 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3672 AR5416_PD_GAIN_ICEPTS,
3674 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3676 AR5416_PD_GAIN_ICEPTS,
3679 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3681 (u8) (ath9k_hw_interpolate
3688 bChans[idxR], vpdTableL[i]
3695 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3698 for (i = 0; i < numXpdGains; i++) {
3699 if (i == (numXpdGains - 1))
3700 pPdGainBoundaries[i] =
3701 (u16) (maxPwrT4[i] / 2);
3703 pPdGainBoundaries[i] =
3704 (u16) ((maxPwrT4[i] +
3705 minPwrT4[i + 1]) / 4);
3707 pPdGainBoundaries[i] =
3708 min((u16) AR5416_MAX_RATE_POWER,
3709 pPdGainBoundaries[i]);
3711 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3712 minDelta = pPdGainBoundaries[0] - 23;
3713 pPdGainBoundaries[0] = 23;
3719 if (AR_SREV_9280_10_OR_LATER(ah))
3720 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3724 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3725 (minPwrT4[i] / 2)) -
3726 tPdGainOverlap + 1 + minDelta);
3728 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3729 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3731 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3732 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3734 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3739 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3740 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3742 maxIndex = (tgtIndex <
3743 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3745 while ((ss < maxIndex)
3746 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3747 pPDADCValues[k++] = vpdTableI[i][ss++];
3750 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3751 vpdTableI[i][sizeCurrVpdTable - 2]);
3752 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3754 if (tgtIndex > maxIndex) {
3755 while ((ss <= tgtIndex)
3756 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3757 tmpVal = (int16_t) ((vpdTableI[i]
3759 1] + (ss - maxIndex +
3761 pPDADCValues[k++] = (u8) ((tmpVal >
3762 255) ? 255 : tmpVal);
3768 while (i < AR5416_PD_GAINS_IN_MASK) {
3769 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3773 while (k < AR5416_NUM_PDADC_VALUES) {
3774 pPDADCValues[k] = pPDADCValues[k - 1];
3781 ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3782 struct ar5416_eeprom *pEepData,
3783 struct ath9k_channel *chan,
3784 int16_t *pTxPowerIndexOffset)
3786 struct cal_data_per_freq *pRawDataset;
3787 u8 *pCalBChans = NULL;
3788 u16 pdGainOverlap_t2;
3789 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3790 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3792 int16_t tMinCalPower;
3793 u16 numXpdGain, xpdMask;
3794 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3795 u32 reg32, regOffset, regChainOffset;
3797 struct ath_hal_5416 *ahp = AH5416(ah);
3799 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3800 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3802 if ((pEepData->baseEepHeader.
3803 version & AR5416_EEP_VER_MINOR_MASK) >=
3804 AR5416_EEP_MINOR_VER_2) {
3806 pEepData->modalHeader[modalIdx].pdGainOverlap;
3810 (REG_READ(ah, AR_PHY_TPCRG5),
3811 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3814 if (IS_CHAN_2GHZ(chan)) {
3815 pCalBChans = pEepData->calFreqPier2G;
3816 numPiers = AR5416_NUM_2G_CAL_PIERS;
3818 pCalBChans = pEepData->calFreqPier5G;
3819 numPiers = AR5416_NUM_5G_CAL_PIERS;
3824 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3825 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3826 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3828 xpdGainValues[numXpdGain] =
3829 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3834 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3835 (numXpdGain - 1) & 0x3);
3836 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3838 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3840 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3843 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3844 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3845 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3847 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3849 regChainOffset = i * 0x1000;
3850 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3851 if (IS_CHAN_2GHZ(chan))
3852 pRawDataset = pEepData->calPierData2G[i];
3854 pRawDataset = pEepData->calPierData5G[i];
3856 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3866 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3869 AR_PHY_TPCRG5 + regChainOffset,
3870 SM(pdGainOverlap_t2,
3871 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3872 | SM(gainBoundaries[0],
3873 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3874 | SM(gainBoundaries[1],
3875 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3876 | SM(gainBoundaries[2],
3877 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3878 | SM(gainBoundaries[3],
3879 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3883 AR_PHY_BASE + (672 << 2) + regChainOffset;
3884 for (j = 0; j < 32; j++) {
3886 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3887 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3888 8) | ((pdadcValues[4 * j + 2] &
3890 ((pdadcValues[4 * j + 3] & 0xFF) <<
3892 REG_WRITE(ah, regOffset, reg32);
3894 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3895 "PDADC (%d,%4x): %4.4x %8.8x\n",
3896 i, regChainOffset, regOffset,
3898 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3899 "PDADC: Chain %d | PDADC %3d Value %3d | "
3900 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3901 "PDADC %3d Value %3d |\n",
3902 i, 4 * j, pdadcValues[4 * j],
3903 4 * j + 1, pdadcValues[4 * j + 1],
3904 4 * j + 2, pdadcValues[4 * j + 2],
3906 pdadcValues[4 * j + 3]);
3912 *pTxPowerIndexOffset = 0;
3917 void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3919 struct ath_hal_5416 *ahp = AH5416(ah);
3922 if (ah->ah_isPciExpress != true)
3925 if (ah->ah_config.pcie_powersave_enable == 2)
3931 if (AR_SREV_9280_20_OR_LATER(ah)) {
3932 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3933 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3934 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3937 } else if (AR_SREV_9280(ah)
3938 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3939 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3940 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3942 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3943 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3944 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3946 if (ah->ah_config.pcie_clock_req)
3947 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3955 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3959 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3960 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3961 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3962 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3963 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3964 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3965 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3966 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3967 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3968 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3971 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3973 if (ah->ah_config.pcie_waen) {
3974 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
3976 if (AR_SREV_9280(ah))
3977 REG_WRITE(ah, AR_WA, 0x0040073f);
3979 REG_WRITE(ah, AR_WA, 0x0000073f);
3984 ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3985 struct ath9k_channel *chan,
3986 struct cal_target_power_leg *powInfo,
3988 struct cal_target_power_leg *pNewPower,
3994 int matchIndex = -1, lowIndex = -1;
3996 struct chan_centers centers;
3998 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3999 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
4001 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
4002 IS_CHAN_2GHZ(chan))) {
4005 for (i = 0; (i < numChannels)
4006 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4008 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4009 IS_CHAN_2GHZ(chan))) {
4013 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4014 IS_CHAN_2GHZ(chan)))
4016 ath9k_hw_fbin2freq(powInfo[i - 1].
4024 if ((matchIndex == -1) && (lowIndex == -1))
4028 if (matchIndex != -1) {
4029 *pNewPower = powInfo[matchIndex];
4031 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4032 IS_CHAN_2GHZ(chan));
4033 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4034 IS_CHAN_2GHZ(chan));
4036 for (i = 0; i < numRates; i++) {
4037 pNewPower->tPow2x[i] =
4038 (u8) ath9k_hw_interpolate(freq, clo, chi,
4050 ath9k_hw_get_target_powers(struct ath_hal *ah,
4051 struct ath9k_channel *chan,
4052 struct cal_target_power_ht *powInfo,
4054 struct cal_target_power_ht *pNewPower,
4060 int matchIndex = -1, lowIndex = -1;
4062 struct chan_centers centers;
4064 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4065 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4068 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4071 for (i = 0; (i < numChannels)
4072 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4074 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4075 IS_CHAN_2GHZ(chan))) {
4080 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4081 IS_CHAN_2GHZ(chan)))
4083 ath9k_hw_fbin2freq(powInfo[i - 1].
4091 if ((matchIndex == -1) && (lowIndex == -1))
4095 if (matchIndex != -1) {
4096 *pNewPower = powInfo[matchIndex];
4098 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4099 IS_CHAN_2GHZ(chan));
4100 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4101 IS_CHAN_2GHZ(chan));
4103 for (i = 0; i < numRates; i++) {
4104 pNewPower->tPow2x[i] =
4105 (u8) ath9k_hw_interpolate(freq, clo, chi,
4117 ath9k_hw_get_max_edge_power(u16 freq,
4118 struct cal_ctl_edges *pRdEdgesPower,
4121 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4124 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4125 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4126 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4128 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4132 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4133 bChannel, is2GHz))) {
4134 if (ath9k_hw_fbin2freq
4135 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4136 && pRdEdgesPower[i - 1].flag) {
4138 pRdEdgesPower[i - 1].tPower;
4143 return twiceMaxEdgePower;
4147 ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4148 struct ar5416_eeprom *pEepData,
4149 struct ath9k_channel *chan,
4150 int16_t *ratesArray,
4152 u8 AntennaReduction,
4153 u8 twiceMaxRegulatoryPower,
4156 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4157 static const u16 tpScaleReductionTable[5] =
4158 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4161 int8_t twiceLargestAntenna;
4162 struct cal_ctl_data *rep;
4163 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4166 struct cal_target_power_leg targetPowerOfdmExt = {
4167 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4170 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4173 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4174 u16 ctlModesFor11a[] =
4175 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4176 u16 ctlModesFor11g[] =
4177 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4180 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4181 struct chan_centers centers;
4183 u8 twiceMinEdgePower;
4184 struct ath_hal_5416 *ahp = AH5416(ah);
4186 tx_chainmask = ahp->ah_txchainmask;
4188 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4190 twiceLargestAntenna = max(
4191 pEepData->modalHeader
4192 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4193 pEepData->modalHeader
4194 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4196 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4197 pEepData->modalHeader
4198 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4200 twiceLargestAntenna =
4201 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4203 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4205 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4206 maxRegAllowedPower -=
4207 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4210 scaledPower = min(powerLimit, maxRegAllowedPower);
4212 switch (ar5416_get_ntxchains(tx_chainmask)) {
4217 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4218 pwrDecreaseFor2Chain;
4222 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4223 pwrDecreaseFor3Chain;
4227 scaledPower = max(0, (int32_t) scaledPower);
4229 if (IS_CHAN_2GHZ(chan)) {
4231 ARRAY_SIZE(ctlModesFor11g) -
4232 SUB_NUM_CTL_MODES_AT_2G_40;
4233 pCtlMode = ctlModesFor11g;
4235 ath9k_hw_get_legacy_target_powers(ah, chan,
4238 AR5416_NUM_2G_CCK_TARGET_POWERS,
4241 ath9k_hw_get_legacy_target_powers(ah, chan,
4244 AR5416_NUM_2G_20_TARGET_POWERS,
4245 &targetPowerOfdm, 4,
4247 ath9k_hw_get_target_powers(ah, chan,
4248 pEepData->calTargetPower2GHT20,
4249 AR5416_NUM_2G_20_TARGET_POWERS,
4250 &targetPowerHt20, 8, false);
4252 if (IS_CHAN_HT40(chan)) {
4253 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4254 ath9k_hw_get_target_powers(ah, chan,
4256 calTargetPower2GHT40,
4257 AR5416_NUM_2G_40_TARGET_POWERS,
4258 &targetPowerHt40, 8,
4260 ath9k_hw_get_legacy_target_powers(ah, chan,
4263 AR5416_NUM_2G_CCK_TARGET_POWERS,
4266 ath9k_hw_get_legacy_target_powers(ah, chan,
4269 AR5416_NUM_2G_20_TARGET_POWERS,
4270 &targetPowerOfdmExt,
4276 ARRAY_SIZE(ctlModesFor11a) -
4277 SUB_NUM_CTL_MODES_AT_5G_40;
4278 pCtlMode = ctlModesFor11a;
4280 ath9k_hw_get_legacy_target_powers(ah, chan,
4283 AR5416_NUM_5G_20_TARGET_POWERS,
4284 &targetPowerOfdm, 4,
4286 ath9k_hw_get_target_powers(ah, chan,
4287 pEepData->calTargetPower5GHT20,
4288 AR5416_NUM_5G_20_TARGET_POWERS,
4289 &targetPowerHt20, 8, false);
4291 if (IS_CHAN_HT40(chan)) {
4292 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4293 ath9k_hw_get_target_powers(ah, chan,
4295 calTargetPower5GHT40,
4296 AR5416_NUM_5G_40_TARGET_POWERS,
4297 &targetPowerHt40, 8,
4299 ath9k_hw_get_legacy_target_powers(ah, chan,
4302 AR5416_NUM_5G_20_TARGET_POWERS,
4303 &targetPowerOfdmExt,
4308 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4309 bool isHt40CtlMode =
4310 (pCtlMode[ctlMode] == CTL_5GHT40)
4311 || (pCtlMode[ctlMode] == CTL_2GHT40);
4313 freq = centers.synth_center;
4314 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4315 freq = centers.ext_center;
4317 freq = centers.ctl_center;
4319 if (ar5416_get_eep_ver(ahp) == 14
4320 && ar5416_get_eep_rev(ahp) <= 2)
4321 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4323 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4324 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4325 "EXT_ADDITIVE %d\n",
4326 ctlMode, numCtlModes, isHt40CtlMode,
4327 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4329 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4331 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4332 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4333 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4335 i, cfgCtl, pCtlMode[ctlMode],
4336 pEepData->ctlIndex[i], chan->channel);
4338 if ((((cfgCtl & ~CTL_MODE_M) |
4339 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4340 pEepData->ctlIndex[i])
4342 (((cfgCtl & ~CTL_MODE_M) |
4343 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4345 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4346 rep = &(pEepData->ctlData[i]);
4349 ath9k_hw_get_max_edge_power(freq,
4352 [ar5416_get_ntxchains
4358 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4359 " MATCH-EE_IDX %d: ch %d is2 %d "
4360 "2xMinEdge %d chainmask %d chains %d\n",
4361 i, freq, IS_CHAN_2GHZ(chan),
4362 twiceMinEdgePower, tx_chainmask,
4363 ar5416_get_ntxchains
4365 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4367 min(twiceMaxEdgePower,
4377 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4379 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4380 " SEL-Min ctlMode %d pCtlMode %d "
4381 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4382 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4383 scaledPower, minCtlPower);
4385 switch (pCtlMode[ctlMode]) {
4387 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4389 targetPowerCck.tPow2x[i] =
4390 min(targetPowerCck.tPow2x[i],
4396 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4398 targetPowerOfdm.tPow2x[i] =
4399 min(targetPowerOfdm.tPow2x[i],
4405 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4407 targetPowerHt20.tPow2x[i] =
4408 min(targetPowerHt20.tPow2x[i],
4413 targetPowerCckExt.tPow2x[0] =
4414 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4418 targetPowerOfdmExt.tPow2x[0] =
4419 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4423 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4425 targetPowerHt40.tPow2x[i] =
4426 min(targetPowerHt40.tPow2x[i],
4435 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4436 ratesArray[rate18mb] = ratesArray[rate24mb] =
4437 targetPowerOfdm.tPow2x[0];
4438 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4439 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4440 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4441 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4443 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4444 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4446 if (IS_CHAN_2GHZ(chan)) {
4447 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4448 ratesArray[rate2s] = ratesArray[rate2l] =
4449 targetPowerCck.tPow2x[1];
4450 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4451 targetPowerCck.tPow2x[2];
4453 ratesArray[rate11s] = ratesArray[rate11l] =
4454 targetPowerCck.tPow2x[3];
4457 if (IS_CHAN_HT40(chan)) {
4458 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4459 ratesArray[rateHt40_0 + i] =
4460 targetPowerHt40.tPow2x[i];
4462 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4463 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4464 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4465 if (IS_CHAN_2GHZ(chan)) {
4466 ratesArray[rateExtCck] =
4467 targetPowerCckExt.tPow2x[0];
4474 ath9k_hw_set_txpower(struct ath_hal *ah,
4475 struct ar5416_eeprom *pEepData,
4476 struct ath9k_channel *chan,
4478 u8 twiceAntennaReduction,
4479 u8 twiceMaxRegulatoryPower,
4482 struct modal_eep_header *pModal =
4483 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4484 int16_t ratesArray[Ar5416RateSize];
4485 int16_t txPowerIndexOffset = 0;
4486 u8 ht40PowerIncForPdadc = 2;
4489 memset(ratesArray, 0, sizeof(ratesArray));
4491 if ((pEepData->baseEepHeader.
4492 version & AR5416_EEP_VER_MINOR_MASK) >=
4493 AR5416_EEP_MINOR_VER_2) {
4494 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4497 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4498 &ratesArray[0], cfgCtl,
4499 twiceAntennaReduction,
4500 twiceMaxRegulatoryPower,
4502 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4503 "ath9k_hw_set_txpower: unable to set "
4504 "tx power per rate table\n");
4508 if (!ath9k_hw_set_power_cal_table
4509 (ah, pEepData, chan, &txPowerIndexOffset)) {
4510 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4511 "ath9k_hw_set_txpower: unable to set power table\n");
4515 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4517 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4518 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4519 ratesArray[i] = AR5416_MAX_RATE_POWER;
4522 if (AR_SREV_9280_10_OR_LATER(ah)) {
4523 for (i = 0; i < Ar5416RateSize; i++)
4524 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4527 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4528 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4529 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4530 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4531 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4533 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4534 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4535 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4536 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4537 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4540 if (IS_CHAN_2GHZ(chan)) {
4541 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4542 ATH9K_POW_SM(ratesArray[rate2s], 24)
4543 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4544 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4545 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4547 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4548 ATH9K_POW_SM(ratesArray[rate11s], 24)
4549 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4550 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4551 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4555 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4556 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4557 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4558 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4559 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4561 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4562 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4563 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4564 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4565 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4568 if (IS_CHAN_HT40(chan)) {
4569 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4570 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4571 ht40PowerIncForPdadc, 24)
4572 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4573 ht40PowerIncForPdadc, 16)
4574 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4575 ht40PowerIncForPdadc, 8)
4576 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4577 ht40PowerIncForPdadc, 0)
4579 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4580 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4581 ht40PowerIncForPdadc, 24)
4582 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4583 ht40PowerIncForPdadc, 16)
4584 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4585 ht40PowerIncForPdadc, 8)
4586 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4587 ht40PowerIncForPdadc, 0)
4590 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4591 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4592 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4593 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4594 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4598 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4599 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4600 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4604 if (IS_CHAN_HT40(chan))
4606 else if (IS_CHAN_HT20(chan))
4609 if (AR_SREV_9280_10_OR_LATER(ah))
4610 ah->ah_maxPowerLevel =
4611 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4613 ah->ah_maxPowerLevel = ratesArray[i];
4618 static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4623 u32 coef_exp, coef_man;
4625 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4626 if ((coef_scaled >> coef_exp) & 0x1)
4629 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4631 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4633 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4634 *coef_exponent = coef_exp - 16;
4638 ath9k_hw_set_delta_slope(struct ath_hal *ah,
4639 struct ath9k_channel *chan)
4641 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4642 u32 clockMhzScaled = 0x64000000;
4643 struct chan_centers centers;
4645 if (IS_CHAN_HALF_RATE(chan))
4646 clockMhzScaled = clockMhzScaled >> 1;
4647 else if (IS_CHAN_QUARTER_RATE(chan))
4648 clockMhzScaled = clockMhzScaled >> 2;
4650 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4651 coef_scaled = clockMhzScaled / centers.synth_center;
4653 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4656 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4657 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4658 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4659 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4661 coef_scaled = (9 * coef_scaled) / 10;
4663 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4666 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4667 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4668 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4669 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4672 static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4673 struct ath9k_channel *chan)
4675 int bb_spur = AR_NO_SPUR;
4678 int bb_spur_off, spur_subchannel_sd;
4680 int spur_delta_phase;
4682 int upper, lower, cur_vit_mask;
4685 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4686 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4688 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4689 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4691 int inc[4] = { 0, 100, 0, 0 };
4692 struct chan_centers centers;
4699 bool is2GHz = IS_CHAN_2GHZ(chan);
4701 memset(&mask_m, 0, sizeof(int8_t) * 123);
4702 memset(&mask_p, 0, sizeof(int8_t) * 123);
4704 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4705 freq = centers.synth_center;
4707 ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
4708 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4709 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4712 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4714 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4716 if (AR_NO_SPUR == cur_bb_spur)
4718 cur_bb_spur = cur_bb_spur - freq;
4720 if (IS_CHAN_HT40(chan)) {
4721 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4722 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4723 bb_spur = cur_bb_spur;
4726 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4727 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4728 bb_spur = cur_bb_spur;
4733 if (AR_NO_SPUR == bb_spur) {
4734 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4735 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4738 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4739 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4742 bin = bb_spur * 320;
4744 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4746 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4747 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4748 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4749 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4750 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4752 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4753 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4754 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4755 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4756 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4757 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4759 if (IS_CHAN_HT40(chan)) {
4761 spur_subchannel_sd = 1;
4762 bb_spur_off = bb_spur + 10;
4764 spur_subchannel_sd = 0;
4765 bb_spur_off = bb_spur - 10;
4768 spur_subchannel_sd = 0;
4769 bb_spur_off = bb_spur;
4772 if (IS_CHAN_HT40(chan))
4774 ((bb_spur * 262144) /
4775 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4778 ((bb_spur * 524288) /
4779 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4781 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4782 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4784 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4785 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4786 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4787 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4789 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4790 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4796 for (i = 0; i < 4; i++) {
4800 for (bp = 0; bp < 30; bp++) {
4801 if ((cur_bin > lower) && (cur_bin < upper)) {
4802 pilot_mask = pilot_mask | 0x1 << bp;
4803 chan_mask = chan_mask | 0x1 << bp;
4808 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4809 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4812 cur_vit_mask = 6100;
4816 for (i = 0; i < 123; i++) {
4817 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
4819 /* workaround for gcc bug #37014 */
4820 volatile int tmp = abs(cur_vit_mask - bin);
4826 if (cur_vit_mask < 0)
4827 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4829 mask_p[cur_vit_mask / 100] = mask_amt;
4831 cur_vit_mask -= 100;
4834 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4835 | (mask_m[48] << 26) | (mask_m[49] << 24)
4836 | (mask_m[50] << 22) | (mask_m[51] << 20)
4837 | (mask_m[52] << 18) | (mask_m[53] << 16)
4838 | (mask_m[54] << 14) | (mask_m[55] << 12)
4839 | (mask_m[56] << 10) | (mask_m[57] << 8)
4840 | (mask_m[58] << 6) | (mask_m[59] << 4)
4841 | (mask_m[60] << 2) | (mask_m[61] << 0);
4842 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4843 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4845 tmp_mask = (mask_m[31] << 28)
4846 | (mask_m[32] << 26) | (mask_m[33] << 24)
4847 | (mask_m[34] << 22) | (mask_m[35] << 20)
4848 | (mask_m[36] << 18) | (mask_m[37] << 16)
4849 | (mask_m[48] << 14) | (mask_m[39] << 12)
4850 | (mask_m[40] << 10) | (mask_m[41] << 8)
4851 | (mask_m[42] << 6) | (mask_m[43] << 4)
4852 | (mask_m[44] << 2) | (mask_m[45] << 0);
4853 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4854 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4856 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4857 | (mask_m[18] << 26) | (mask_m[18] << 24)
4858 | (mask_m[20] << 22) | (mask_m[20] << 20)
4859 | (mask_m[22] << 18) | (mask_m[22] << 16)
4860 | (mask_m[24] << 14) | (mask_m[24] << 12)
4861 | (mask_m[25] << 10) | (mask_m[26] << 8)
4862 | (mask_m[27] << 6) | (mask_m[28] << 4)
4863 | (mask_m[29] << 2) | (mask_m[30] << 0);
4864 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4865 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4867 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4868 | (mask_m[2] << 26) | (mask_m[3] << 24)
4869 | (mask_m[4] << 22) | (mask_m[5] << 20)
4870 | (mask_m[6] << 18) | (mask_m[7] << 16)
4871 | (mask_m[8] << 14) | (mask_m[9] << 12)
4872 | (mask_m[10] << 10) | (mask_m[11] << 8)
4873 | (mask_m[12] << 6) | (mask_m[13] << 4)
4874 | (mask_m[14] << 2) | (mask_m[15] << 0);
4875 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4876 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4878 tmp_mask = (mask_p[15] << 28)
4879 | (mask_p[14] << 26) | (mask_p[13] << 24)
4880 | (mask_p[12] << 22) | (mask_p[11] << 20)
4881 | (mask_p[10] << 18) | (mask_p[9] << 16)
4882 | (mask_p[8] << 14) | (mask_p[7] << 12)
4883 | (mask_p[6] << 10) | (mask_p[5] << 8)
4884 | (mask_p[4] << 6) | (mask_p[3] << 4)
4885 | (mask_p[2] << 2) | (mask_p[1] << 0);
4886 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4887 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4889 tmp_mask = (mask_p[30] << 28)
4890 | (mask_p[29] << 26) | (mask_p[28] << 24)
4891 | (mask_p[27] << 22) | (mask_p[26] << 20)
4892 | (mask_p[25] << 18) | (mask_p[24] << 16)
4893 | (mask_p[23] << 14) | (mask_p[22] << 12)
4894 | (mask_p[21] << 10) | (mask_p[20] << 8)
4895 | (mask_p[19] << 6) | (mask_p[18] << 4)
4896 | (mask_p[17] << 2) | (mask_p[16] << 0);
4897 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4898 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4900 tmp_mask = (mask_p[45] << 28)
4901 | (mask_p[44] << 26) | (mask_p[43] << 24)
4902 | (mask_p[42] << 22) | (mask_p[41] << 20)
4903 | (mask_p[40] << 18) | (mask_p[39] << 16)
4904 | (mask_p[38] << 14) | (mask_p[37] << 12)
4905 | (mask_p[36] << 10) | (mask_p[35] << 8)
4906 | (mask_p[34] << 6) | (mask_p[33] << 4)
4907 | (mask_p[32] << 2) | (mask_p[31] << 0);
4908 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4909 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4911 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4912 | (mask_p[59] << 26) | (mask_p[58] << 24)
4913 | (mask_p[57] << 22) | (mask_p[56] << 20)
4914 | (mask_p[55] << 18) | (mask_p[54] << 16)
4915 | (mask_p[53] << 14) | (mask_p[52] << 12)
4916 | (mask_p[51] << 10) | (mask_p[50] << 8)
4917 | (mask_p[49] << 6) | (mask_p[48] << 4)
4918 | (mask_p[47] << 2) | (mask_p[46] << 0);
4919 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4920 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4923 static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4924 struct ath9k_channel *chan)
4926 int bb_spur = AR_NO_SPUR;
4929 int spur_delta_phase;
4931 int upper, lower, cur_vit_mask;
4934 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4935 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4937 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4938 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4940 int inc[4] = { 0, 100, 0, 0 };
4947 bool is2GHz = IS_CHAN_2GHZ(chan);
4949 memset(&mask_m, 0, sizeof(int8_t) * 123);
4950 memset(&mask_p, 0, sizeof(int8_t) * 123);
4952 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4953 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4954 if (AR_NO_SPUR == cur_bb_spur)
4956 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4957 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4958 bb_spur = cur_bb_spur;
4963 if (AR_NO_SPUR == bb_spur)
4968 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4969 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4970 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4971 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4972 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4974 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4976 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4977 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4978 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4979 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4980 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4981 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4983 spur_delta_phase = ((bb_spur * 524288) / 100) &
4984 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4986 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4987 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4989 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4990 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4991 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4992 REG_WRITE(ah, AR_PHY_TIMING11, new);
4998 for (i = 0; i < 4; i++) {
5002 for (bp = 0; bp < 30; bp++) {
5003 if ((cur_bin > lower) && (cur_bin < upper)) {
5004 pilot_mask = pilot_mask | 0x1 << bp;
5005 chan_mask = chan_mask | 0x1 << bp;
5010 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
5011 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5014 cur_vit_mask = 6100;
5018 for (i = 0; i < 123; i++) {
5019 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5021 /* workaround for gcc bug #37014 */
5022 volatile int tmp = abs(cur_vit_mask - bin);
5028 if (cur_vit_mask < 0)
5029 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5031 mask_p[cur_vit_mask / 100] = mask_amt;
5033 cur_vit_mask -= 100;
5036 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5037 | (mask_m[48] << 26) | (mask_m[49] << 24)
5038 | (mask_m[50] << 22) | (mask_m[51] << 20)
5039 | (mask_m[52] << 18) | (mask_m[53] << 16)
5040 | (mask_m[54] << 14) | (mask_m[55] << 12)
5041 | (mask_m[56] << 10) | (mask_m[57] << 8)
5042 | (mask_m[58] << 6) | (mask_m[59] << 4)
5043 | (mask_m[60] << 2) | (mask_m[61] << 0);
5044 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5045 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5047 tmp_mask = (mask_m[31] << 28)
5048 | (mask_m[32] << 26) | (mask_m[33] << 24)
5049 | (mask_m[34] << 22) | (mask_m[35] << 20)
5050 | (mask_m[36] << 18) | (mask_m[37] << 16)
5051 | (mask_m[48] << 14) | (mask_m[39] << 12)
5052 | (mask_m[40] << 10) | (mask_m[41] << 8)
5053 | (mask_m[42] << 6) | (mask_m[43] << 4)
5054 | (mask_m[44] << 2) | (mask_m[45] << 0);
5055 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5056 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5058 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5059 | (mask_m[18] << 26) | (mask_m[18] << 24)
5060 | (mask_m[20] << 22) | (mask_m[20] << 20)
5061 | (mask_m[22] << 18) | (mask_m[22] << 16)
5062 | (mask_m[24] << 14) | (mask_m[24] << 12)
5063 | (mask_m[25] << 10) | (mask_m[26] << 8)
5064 | (mask_m[27] << 6) | (mask_m[28] << 4)
5065 | (mask_m[29] << 2) | (mask_m[30] << 0);
5066 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5067 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5069 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5070 | (mask_m[2] << 26) | (mask_m[3] << 24)
5071 | (mask_m[4] << 22) | (mask_m[5] << 20)
5072 | (mask_m[6] << 18) | (mask_m[7] << 16)
5073 | (mask_m[8] << 14) | (mask_m[9] << 12)
5074 | (mask_m[10] << 10) | (mask_m[11] << 8)
5075 | (mask_m[12] << 6) | (mask_m[13] << 4)
5076 | (mask_m[14] << 2) | (mask_m[15] << 0);
5077 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5078 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5080 tmp_mask = (mask_p[15] << 28)
5081 | (mask_p[14] << 26) | (mask_p[13] << 24)
5082 | (mask_p[12] << 22) | (mask_p[11] << 20)
5083 | (mask_p[10] << 18) | (mask_p[9] << 16)
5084 | (mask_p[8] << 14) | (mask_p[7] << 12)
5085 | (mask_p[6] << 10) | (mask_p[5] << 8)
5086 | (mask_p[4] << 6) | (mask_p[3] << 4)
5087 | (mask_p[2] << 2) | (mask_p[1] << 0);
5088 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5089 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5091 tmp_mask = (mask_p[30] << 28)
5092 | (mask_p[29] << 26) | (mask_p[28] << 24)
5093 | (mask_p[27] << 22) | (mask_p[26] << 20)
5094 | (mask_p[25] << 18) | (mask_p[24] << 16)
5095 | (mask_p[23] << 14) | (mask_p[22] << 12)
5096 | (mask_p[21] << 10) | (mask_p[20] << 8)
5097 | (mask_p[19] << 6) | (mask_p[18] << 4)
5098 | (mask_p[17] << 2) | (mask_p[16] << 0);
5099 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5100 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5102 tmp_mask = (mask_p[45] << 28)
5103 | (mask_p[44] << 26) | (mask_p[43] << 24)
5104 | (mask_p[42] << 22) | (mask_p[41] << 20)
5105 | (mask_p[40] << 18) | (mask_p[39] << 16)
5106 | (mask_p[38] << 14) | (mask_p[37] << 12)
5107 | (mask_p[36] << 10) | (mask_p[35] << 8)
5108 | (mask_p[34] << 6) | (mask_p[33] << 4)
5109 | (mask_p[32] << 2) | (mask_p[31] << 0);
5110 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5111 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5113 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5114 | (mask_p[59] << 26) | (mask_p[58] << 24)
5115 | (mask_p[57] << 22) | (mask_p[56] << 20)
5116 | (mask_p[55] << 18) | (mask_p[54] << 16)
5117 | (mask_p[53] << 14) | (mask_p[52] << 12)
5118 | (mask_p[51] << 10) | (mask_p[50] << 8)
5119 | (mask_p[49] << 6) | (mask_p[48] << 4)
5120 | (mask_p[47] << 2) | (mask_p[46] << 0);
5121 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5122 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5125 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5127 struct ath_hal_5416 *ahp = AH5416(ah);
5128 int rx_chainmask, tx_chainmask;
5130 rx_chainmask = ahp->ah_rxchainmask;
5131 tx_chainmask = ahp->ah_txchainmask;
5133 switch (rx_chainmask) {
5135 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5136 AR_PHY_SWAP_ALT_CHAIN);
5138 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5139 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5140 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5145 if (!AR_SREV_9280(ah))
5148 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5149 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5155 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5156 if (tx_chainmask == 0x5) {
5157 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5158 AR_PHY_SWAP_ALT_CHAIN);
5160 if (AR_SREV_9100(ah))
5161 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5162 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5165 static void ath9k_hw_set_addac(struct ath_hal *ah,
5166 struct ath9k_channel *chan)
5168 struct modal_eep_header *pModal;
5169 struct ath_hal_5416 *ahp = AH5416(ah);
5170 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5173 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5176 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5179 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5181 if (pModal->xpaBiasLvl != 0xff) {
5182 biaslevel = pModal->xpaBiasLvl;
5185 u16 resetFreqBin, freqBin, freqCount = 0;
5186 struct chan_centers centers;
5188 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5191 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5192 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5193 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5197 while (freqCount < 3) {
5198 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5201 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5202 if (resetFreqBin >= freqBin) {
5205 xpaBiasLvlFreq[freqCount]
5214 if (IS_CHAN_2GHZ(chan)) {
5215 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5216 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5219 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5220 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5225 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5227 if (ah->ah_curchan != NULL)
5229 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5231 return clks / CLOCK_RATE[ATH9K_MODE_11B];
5234 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5236 struct ath9k_channel *chan = ah->ah_curchan;
5238 if (chan && IS_CHAN_HT40(chan))
5239 return ath9k_hw_mac_usec(ah, clks) / 2;
5241 return ath9k_hw_mac_usec(ah, clks);
5244 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5246 if (ah->ah_curchan != NULL)
5247 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5250 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
5253 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5255 struct ath9k_channel *chan = ah->ah_curchan;
5257 if (chan && IS_CHAN_HT40(chan))
5258 return ath9k_hw_mac_clks(ah, usecs) * 2;
5260 return ath9k_hw_mac_clks(ah, usecs);
5263 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5265 struct ath_hal_5416 *ahp = AH5416(ah);
5267 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5268 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5270 ahp->ah_acktimeout = (u32) -1;
5273 REG_RMW_FIELD(ah, AR_TIME_OUT,
5274 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5275 ahp->ah_acktimeout = us;
5280 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5282 struct ath_hal_5416 *ahp = AH5416(ah);
5284 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5285 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5287 ahp->ah_ctstimeout = (u32) -1;
5290 REG_RMW_FIELD(ah, AR_TIME_OUT,
5291 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5292 ahp->ah_ctstimeout = us;
5296 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5299 struct ath_hal_5416 *ahp = AH5416(ah);
5302 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5303 "%s: bad global tx timeout %u\n", __func__, tu);
5304 ahp->ah_globaltxtimeout = (u32) -1;
5307 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5308 ahp->ah_globaltxtimeout = tu;
5313 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5315 struct ath_hal_5416 *ahp = AH5416(ah);
5317 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5318 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5320 ahp->ah_slottime = (u32) -1;
5323 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5324 ahp->ah_slottime = us;
5329 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5331 struct ath_hal_5416 *ahp = AH5416(ah);
5333 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5334 __func__, ahp->ah_miscMode);
5335 if (ahp->ah_miscMode != 0)
5336 REG_WRITE(ah, AR_PCU_MISC,
5337 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5338 if (ahp->ah_slottime != (u32) -1)
5339 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5340 if (ahp->ah_acktimeout != (u32) -1)
5341 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5342 if (ahp->ah_ctstimeout != (u32) -1)
5343 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5344 if (ahp->ah_globaltxtimeout != (u32) -1)
5345 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5349 ath9k_hw_process_ini(struct ath_hal *ah,
5350 struct ath9k_channel *chan,
5351 enum ath9k_ht_macmode macmode)
5353 int i, regWrites = 0;
5354 struct ath_hal_5416 *ahp = AH5416(ah);
5355 u32 modesIndex, freqIndex;
5358 switch (chan->chanmode) {
5360 case CHANNEL_A_HT20:
5364 case CHANNEL_A_HT40PLUS:
5365 case CHANNEL_A_HT40MINUS:
5370 case CHANNEL_G_HT20:
5375 case CHANNEL_G_HT40PLUS:
5376 case CHANNEL_G_HT40MINUS:
5385 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5387 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5389 ath9k_hw_set_addac(ah, chan);
5391 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5392 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5394 struct ar5416IniArray temp;
5396 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5397 ahp->ah_iniAddac.ia_columns;
5399 memcpy(ahp->ah_addac5416_21,
5400 ahp->ah_iniAddac.ia_array, addacSize);
5402 (ahp->ah_addac5416_21)[31 *
5403 ahp->ah_iniAddac.ia_columns + 1] = 0;
5405 temp.ia_array = ahp->ah_addac5416_21;
5406 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5407 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5408 REG_WRITE_ARRAY(&temp, 1, regWrites);
5410 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5412 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5413 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5414 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5416 #ifdef CONFIG_SLOW_ANT_DIV
5417 if (ah->ah_devid == AR9280_DEVID_PCI)
5418 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5422 REG_WRITE(ah, reg, val);
5424 if (reg >= 0x7800 && reg < 0x78a0
5425 && ah->ah_config.analog_shiftreg) {
5429 DO_DELAY(regWrites);
5432 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5433 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5434 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5436 REG_WRITE(ah, reg, val);
5438 if (reg >= 0x7800 && reg < 0x78a0
5439 && ah->ah_config.analog_shiftreg) {
5443 DO_DELAY(regWrites);
5446 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5448 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5449 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5453 ath9k_hw_override_ini(ah, chan);
5454 ath9k_hw_set_regs(ah, chan, macmode);
5455 ath9k_hw_init_chain_masks(ah);
5457 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5458 ath9k_regd_get_ctl(ah, chan),
5459 ath9k_regd_get_antenna_allowed(ah,
5461 chan->maxRegTxPower * 2,
5462 min((u32) MAX_RATE_POWER,
5463 (u32) ah->ah_powerLimit));
5465 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5466 "%s: error init'ing transmit power\n", __func__);
5470 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5471 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5472 "%s: ar5416SetRfRegs failed\n", __func__);
5479 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5480 struct hal_cal_list *currCal)
5482 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5483 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5484 currCal->calData->calCountMax);
5486 switch (currCal->calData->calType) {
5487 case IQ_MISMATCH_CAL:
5488 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5489 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5490 "%s: starting IQ Mismatch Calibration\n",
5494 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5495 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5496 "%s: starting ADC Gain Calibration\n", __func__);
5499 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5500 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5501 "%s: starting ADC DC Calibration\n", __func__);
5503 case ADC_DC_INIT_CAL:
5504 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5505 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5506 "%s: starting Init ADC DC Calibration\n",
5511 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5512 AR_PHY_TIMING_CTRL4_DO_CAL);
5515 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5516 struct hal_cal_list *currCal)
5518 struct ath_hal_5416 *ahp = AH5416(ah);
5521 ath9k_hw_setup_calibration(ah, currCal);
5523 currCal->calState = CAL_RUNNING;
5525 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5526 ahp->ah_Meas0.sign[i] = 0;
5527 ahp->ah_Meas1.sign[i] = 0;
5528 ahp->ah_Meas2.sign[i] = 0;
5529 ahp->ah_Meas3.sign[i] = 0;
5532 ahp->ah_CalSamples = 0;
5536 ath9k_hw_per_calibration(struct ath_hal *ah,
5537 struct ath9k_channel *ichan,
5539 struct hal_cal_list *currCal,
5542 struct ath_hal_5416 *ahp = AH5416(ah);
5546 if (currCal->calState == CAL_RUNNING) {
5548 AR_PHY_TIMING_CTRL4(0)) &
5549 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5551 currCal->calData->calCollect(ah);
5553 ahp->ah_CalSamples++;
5555 if (ahp->ah_CalSamples >=
5556 currCal->calData->calNumSamples) {
5557 int i, numChains = 0;
5558 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5559 if (rxchainmask & (1 << i))
5563 currCal->calData->calPostProc(ah,
5567 currCal->calData->calType;
5568 currCal->calState = CAL_DONE;
5571 ath9k_hw_setup_calibration(ah, currCal);
5574 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5575 ath9k_hw_reset_calibration(ah, currCal);
5579 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5582 struct ath_hal_5416 *ahp = AH5416(ah);
5583 struct ath9k_channel ichan;
5585 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5586 const struct hal_percal_data *calData = currCal->calData;
5589 if (currCal == NULL)
5594 for (i = 0; i < init_cal_count; i++) {
5595 ath9k_hw_reset_calibration(ah, currCal);
5597 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5598 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5599 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5600 "%s: Cal %d failed to complete in 100ms.\n",
5601 __func__, calData->calType);
5603 ahp->ah_cal_list = ahp->ah_cal_list_last =
5604 ahp->ah_cal_list_curr = NULL;
5608 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5609 currCal, &isCalDone);
5611 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5612 "%s: Not able to run Init Cal %d.\n",
5613 __func__, calData->calType);
5615 if (currCal->calNext) {
5616 currCal = currCal->calNext;
5617 calData = currCal->calData;
5621 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5626 ath9k_hw_channel_change(struct ath_hal *ah,
5627 struct ath9k_channel *chan,
5628 enum ath9k_ht_macmode macmode)
5630 u32 synthDelay, qnum;
5631 struct ath_hal_5416 *ahp = AH5416(ah);
5633 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5634 if (ath9k_hw_numtxpending(ah, qnum)) {
5635 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5636 "%s: Transmit frames pending on queue %d\n",
5642 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5643 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5644 AR_PHY_RFBUS_GRANT_EN)) {
5645 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5646 "%s: Could not kill baseband RX\n", __func__);
5650 ath9k_hw_set_regs(ah, chan, macmode);
5652 if (AR_SREV_9280_10_OR_LATER(ah)) {
5653 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5654 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5655 "%s: failed to set channel\n", __func__);
5659 if (!(ath9k_hw_set_channel(ah, chan))) {
5660 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5661 "%s: failed to set channel\n", __func__);
5666 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5667 ath9k_regd_get_ctl(ah, chan),
5668 ath9k_regd_get_antenna_allowed(ah, chan),
5669 chan->maxRegTxPower * 2,
5670 min((u32) MAX_RATE_POWER,
5671 (u32) ah->ah_powerLimit)) != 0) {
5672 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5673 "%s: error init'ing transmit power\n", __func__);
5677 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5678 if (IS_CHAN_CCK(chan))
5679 synthDelay = (4 * synthDelay) / 22;
5683 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5685 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5687 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5688 ath9k_hw_set_delta_slope(ah, chan);
5690 if (AR_SREV_9280_10_OR_LATER(ah))
5691 ath9k_hw_9280_spur_mitigate(ah, chan);
5693 ath9k_hw_spur_mitigate(ah, chan);
5695 if (!chan->oneTimeCalsDone)
5696 chan->oneTimeCalsDone = true;
5701 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5702 struct ath9k_channel *chan)
5704 struct ath_hal_5416 *ahp = AH5416(ah);
5706 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5709 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5712 ahp->ah_chipFullSleep = false;
5714 ath9k_hw_init_pll(ah, chan);
5716 ath9k_hw_set_rfmode(ah, chan);
5721 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5725 regval = REG_READ(ah, AR_AHB_MODE);
5726 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5728 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5729 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5731 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5733 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5734 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5736 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5738 if (AR_SREV_9285(ah)) {
5739 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5740 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5742 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5743 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5747 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5749 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5750 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5751 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5752 "%s: dma failed to stop in 10ms\n"
5753 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5755 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5762 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5764 REG_CLR_BIT(ah, AR_DIAG_SW,
5765 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5767 ath9k_enable_mib_counters(ah);
5769 ath9k_ani_reset(ah);
5772 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5774 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5776 ath9k_hw_disable_mib_counters(ah);
5779 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5780 struct ath9k_channel *chan,
5781 enum hal_cal_types calType)
5783 struct ath_hal_5416 *ahp = AH5416(ah);
5784 bool retval = false;
5786 switch (calType & ahp->ah_suppCals) {
5787 case IQ_MISMATCH_CAL:
5788 if (!IS_CHAN_B(chan))
5793 if (!IS_CHAN_B(chan)
5794 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5802 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5803 struct ath9k_channel *chan)
5805 struct ath_hal_5416 *ahp = AH5416(ah);
5806 struct ath9k_channel *ichan =
5807 ath9k_regd_check_channel(ah, chan);
5809 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5810 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5811 AR_PHY_AGC_CONTROL_CAL);
5814 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5815 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5816 "%s: offset calibration failed to complete in 1ms; "
5817 "noisy environment?\n", __func__);
5821 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5822 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5823 AR_PHY_AGC_CONTROL_NF);
5825 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5828 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5829 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5830 INIT_CAL(&ahp->ah_adcGainCalData);
5831 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5832 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5833 "%s: enabling ADC Gain Calibration.\n",
5836 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5837 INIT_CAL(&ahp->ah_adcDcCalData);
5838 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5839 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5840 "%s: enabling ADC DC Calibration.\n",
5843 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5844 INIT_CAL(&ahp->ah_iqCalData);
5845 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5846 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5847 "%s: enabling IQ Calibration.\n",
5851 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5853 if (ahp->ah_cal_list_curr)
5854 ath9k_hw_reset_calibration(ah,
5855 ahp->ah_cal_list_curr);
5858 ichan->CalValid = 0;
5864 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5865 struct ath9k_channel *chan,
5866 enum ath9k_ht_macmode macmode,
5867 u8 txchainmask, u8 rxchainmask,
5868 enum ath9k_ht_extprotspacing extprotspacing,
5869 bool bChannelChange,
5872 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5874 struct ath_hal_5416 *ahp = AH5416(ah);
5875 struct ath9k_channel *curchan = ah->ah_curchan;
5879 int i, rx_chainmask;
5881 ahp->ah_extprotspacing = extprotspacing;
5882 ahp->ah_txchainmask = txchainmask;
5883 ahp->ah_rxchainmask = rxchainmask;
5885 if (AR_SREV_9280(ah)) {
5886 ahp->ah_txchainmask &= 0x3;
5887 ahp->ah_rxchainmask &= 0x3;
5890 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5891 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5892 "%s: invalid channel %u/0x%x; no mapping\n",
5893 __func__, chan->channel, chan->channelFlags);
5897 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5901 ath9k_hw_getnf(ah, curchan);
5903 if (bChannelChange &&
5904 (ahp->ah_chipFullSleep != true) &&
5905 (ah->ah_curchan != NULL) &&
5906 (chan->channel != ah->ah_curchan->channel) &&
5907 ((chan->channelFlags & CHANNEL_ALL) ==
5908 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5909 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5910 !IS_CHAN_A_5MHZ_SPACED(ah->
5913 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5914 ath9k_hw_loadnf(ah, ah->ah_curchan);
5915 ath9k_hw_start_nfcal(ah);
5920 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5921 if (saveDefAntenna == 0)
5924 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5926 saveLedState = REG_READ(ah, AR_CFG_LED) &
5927 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5928 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5930 ath9k_hw_mark_phy_inactive(ah);
5932 if (!ath9k_hw_chip_reset(ah, chan)) {
5933 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5938 if (AR_SREV_9280(ah)) {
5939 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5940 AR_GPIO_JTAG_DISABLE);
5942 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
5943 if (IS_CHAN_5GHZ(chan))
5944 ath9k_hw_set_gpio(ah, 9, 0);
5946 ath9k_hw_set_gpio(ah, 9, 1);
5948 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5951 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5955 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5956 ath9k_hw_set_delta_slope(ah, chan);
5958 if (AR_SREV_9280_10_OR_LATER(ah))
5959 ath9k_hw_9280_spur_mitigate(ah, chan);
5961 ath9k_hw_spur_mitigate(ah, chan);
5963 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5964 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5965 "%s: error setting board options\n", __func__);
5969 ath9k_hw_decrease_chain_power(ah, chan);
5971 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5972 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5974 | AR_STA_ID1_RTS_USE_DEF
5976 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5977 | ahp->ah_staId1Defaults);
5978 ath9k_hw_set_operating_mode(ah, opmode);
5980 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5981 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5983 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5985 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5986 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5987 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5989 REG_WRITE(ah, AR_ISR, ~0);
5991 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5993 if (AR_SREV_9280_10_OR_LATER(ah)) {
5994 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5997 if (!(ath9k_hw_set_channel(ah, chan)))
6001 for (i = 0; i < AR_NUM_DCU; i++)
6002 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
6004 ahp->ah_intrTxqs = 0;
6005 for (i = 0; i < ah->ah_caps.total_queues; i++)
6006 ath9k_hw_resettxqueue(ah, i);
6008 ath9k_hw_init_interrupt_masks(ah, opmode);
6009 ath9k_hw_init_qos(ah);
6011 ath9k_hw_init_user_settings(ah);
6013 ah->ah_opmode = opmode;
6015 REG_WRITE(ah, AR_STA_ID1,
6016 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6018 ath9k_hw_set_dma(ah);
6020 REG_WRITE(ah, AR_OBS, 8);
6022 if (ahp->ah_intrMitigation) {
6024 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6025 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6028 ath9k_hw_init_bb(ah, chan);
6030 if (!ath9k_hw_init_cal(ah, chan))
6033 rx_chainmask = ahp->ah_rxchainmask;
6034 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6035 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6036 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6039 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6041 if (AR_SREV_9100(ah)) {
6043 mask = REG_READ(ah, AR_CFG);
6044 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6045 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6046 "%s CFG Byte Swap Set 0x%x\n", __func__,
6050 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6051 REG_WRITE(ah, AR_CFG, mask);
6052 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6053 "%s Setting CFG 0x%x\n", __func__,
6054 REG_READ(ah, AR_CFG));
6058 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6070 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6072 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6075 bool ath9k_hw_disable(struct ath_hal *ah)
6077 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6080 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6084 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6085 u8 rxchainmask, bool longcal,
6088 struct ath_hal_5416 *ahp = AH5416(ah);
6089 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6090 struct ath9k_channel *ichan =
6091 ath9k_regd_check_channel(ah, chan);
6095 if (ichan == NULL) {
6096 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6097 "%s: invalid channel %u/0x%x; no mapping\n",
6098 __func__, chan->channel, chan->channelFlags);
6103 (currCal->calState == CAL_RUNNING ||
6104 currCal->calState == CAL_WAITING)) {
6105 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6108 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6110 if (currCal->calState == CAL_WAITING) {
6112 ath9k_hw_reset_calibration(ah, currCal);
6118 ath9k_hw_getnf(ah, ichan);
6119 ath9k_hw_loadnf(ah, ah->ah_curchan);
6120 ath9k_hw_start_nfcal(ah);
6122 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6124 chan->channelFlags |= CHANNEL_CW_INT;
6125 ichan->channelFlags &= ~CHANNEL_CW_INT;
6132 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6134 struct ath_hal_5416 *ahp = AH5416(ah);
6137 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6138 ahp->ah_totalPowerMeasI[i] +=
6139 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6140 ahp->ah_totalPowerMeasQ[i] +=
6141 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6142 ahp->ah_totalIqCorrMeas[i] +=
6143 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6144 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6145 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6146 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6147 ahp->ah_totalPowerMeasQ[i],
6148 ahp->ah_totalIqCorrMeas[i]);
6152 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6154 struct ath_hal_5416 *ahp = AH5416(ah);
6157 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6158 ahp->ah_totalAdcIOddPhase[i] +=
6159 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6160 ahp->ah_totalAdcIEvenPhase[i] +=
6161 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6162 ahp->ah_totalAdcQOddPhase[i] +=
6163 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6164 ahp->ah_totalAdcQEvenPhase[i] +=
6165 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6167 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6168 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6169 "oddq=0x%08x; evenq=0x%08x;\n",
6170 ahp->ah_CalSamples, i,
6171 ahp->ah_totalAdcIOddPhase[i],
6172 ahp->ah_totalAdcIEvenPhase[i],
6173 ahp->ah_totalAdcQOddPhase[i],
6174 ahp->ah_totalAdcQEvenPhase[i]);
6178 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6180 struct ath_hal_5416 *ahp = AH5416(ah);
6183 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6184 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6185 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6186 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6187 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6188 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6189 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6190 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6191 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6193 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6194 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6195 "oddq=0x%08x; evenq=0x%08x;\n",
6196 ahp->ah_CalSamples, i,
6197 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6198 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6199 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6200 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6204 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6206 struct ath_hal_5416 *ahp = AH5416(ah);
6207 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6208 u32 qCoffDenom, iCoffDenom;
6209 int32_t qCoff, iCoff;
6212 for (i = 0; i < numChains; i++) {
6213 powerMeasI = ahp->ah_totalPowerMeasI[i];
6214 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6215 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6217 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218 "Starting IQ Cal and Correction for Chain %d\n",
6221 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6222 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6223 i, ahp->ah_totalIqCorrMeas[i]);
6228 if (iqCorrMeas > 0x80000000) {
6229 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6233 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6234 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6235 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6236 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6237 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6240 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6241 qCoffDenom = powerMeasQ / 64;
6243 if (powerMeasQ != 0) {
6245 iCoff = iqCorrMeas / iCoffDenom;
6246 qCoff = powerMeasI / qCoffDenom - 64;
6247 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6248 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6249 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6250 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6253 iCoff = iCoff & 0x3f;
6254 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6255 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6256 if (iqCorrNeg == 0x0)
6257 iCoff = 0x40 - iCoff;
6261 else if (qCoff <= -16)
6264 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6265 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6268 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6269 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6271 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6272 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6274 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6275 "IQ Cal and Correction done for Chain %d\n",
6280 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6281 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6285 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6287 struct ath_hal_5416 *ahp = AH5416(ah);
6288 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6290 u32 qGainMismatch, iGainMismatch, val, i;
6292 for (i = 0; i < numChains; i++) {
6293 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6294 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6295 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6296 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6298 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6299 "Starting ADC Gain Cal for Chain %d\n", i);
6301 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6302 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6304 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6305 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6307 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6310 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6311 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6314 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6316 ((iEvenMeasOffset * 32) /
6317 iOddMeasOffset) & 0x3f;
6319 ((qOddMeasOffset * 32) /
6320 qEvenMeasOffset) & 0x3f;
6322 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6323 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6325 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6326 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6329 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6331 val |= (qGainMismatch) | (iGainMismatch << 6);
6332 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6334 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6335 "ADC Gain Cal done for Chain %d\n", i);
6339 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6340 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6341 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6345 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6347 struct ath_hal_5416 *ahp = AH5416(ah);
6348 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6349 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6350 const struct hal_percal_data *calData =
6351 ahp->ah_cal_list_curr->calData;
6353 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6355 for (i = 0; i < numChains; i++) {
6356 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6357 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6358 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6359 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6361 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6362 "Starting ADC DC Offset Cal for Chain %d\n", i);
6364 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6365 "Chn %d pwr_meas_odd_i = %d\n", i,
6367 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368 "Chn %d pwr_meas_even_i = %d\n", i,
6370 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6371 "Chn %d pwr_meas_odd_q = %d\n", i,
6373 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6374 "Chn %d pwr_meas_even_q = %d\n", i,
6377 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6378 numSamples) & 0x1ff;
6379 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6380 numSamples) & 0x1ff;
6382 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6383 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6385 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6386 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6389 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6391 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6392 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6394 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6395 "ADC DC Offset Cal done for Chain %d\n", i);
6398 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6399 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6400 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6403 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6405 struct ath_hal_5416 *ahp = AH5416(ah);
6406 struct ath9k_channel *chan = ah->ah_curchan;
6408 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6410 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6411 ath9k_regd_get_ctl(ah, chan),
6412 ath9k_regd_get_antenna_allowed(ah,
6414 chan->maxRegTxPower * 2,
6415 min((u32) MAX_RATE_POWER,
6416 (u32) ah->ah_powerLimit)) != 0)
6423 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6424 struct ath9k_channel *chan,
6425 struct chan_centers *centers)
6428 struct ath_hal_5416 *ahp = AH5416(ah);
6430 if (!IS_CHAN_HT40(chan)) {
6431 centers->ctl_center = centers->ext_center =
6432 centers->synth_center = chan->channel;
6436 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6437 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6438 centers->synth_center =
6439 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6442 centers->synth_center =
6443 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6447 centers->ctl_center = centers->synth_center - (extoff *
6448 HT40_CHANNEL_CENTER_SHIFT);
6449 centers->ext_center = centers->synth_center + (extoff *
6453 ATH9K_HT_EXTPROTSPACING_20)
6455 HT40_CHANNEL_CENTER_SHIFT
6461 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6464 struct ath_hal_5416 *ahp = AH5416(ah);
6465 struct ath9k_channel *ichan =
6466 ath9k_regd_check_channel(ah, chan);
6467 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6471 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6474 if (currCal == NULL)
6477 if (ichan == NULL) {
6478 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6479 "%s: invalid channel %u/0x%x; no mapping\n",
6480 __func__, chan->channel, chan->channelFlags);
6485 if (currCal->calState != CAL_DONE) {
6486 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6487 "%s: Calibration state incorrect, %d\n",
6488 __func__, currCal->calState);
6493 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6496 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6497 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6498 __func__, currCal->calData->calType, chan->channel,
6499 chan->channelFlags);
6501 ichan->CalValid &= ~currCal->calData->calType;
6502 currCal->calState = CAL_WAITING;
6507 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6509 struct ath_hal_5416 *ahp = AH5416(ah);
6511 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6514 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6516 struct ath_hal_5416 *ahp = AH5416(ah);
6518 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6522 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6524 struct ath_hal_5416 *ahp = AH5416(ah);
6526 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6530 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6532 struct ath_hal_5416 *ahp = AH5416(ah);
6534 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6536 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6537 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6542 #ifdef CONFIG_ATH9K_RFKILL
6543 static void ath9k_enable_rfkill(struct ath_hal *ah)
6545 struct ath_hal_5416 *ahp = AH5416(ah);
6547 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6548 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6550 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6551 AR_GPIO_INPUT_MUX2_RFSILENT);
6553 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6554 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6556 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6558 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6561 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6568 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6571 struct ath_hal_5416 *ahp = AH5416(ah);
6573 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6574 ahp->ah_assocId = assocId;
6576 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6577 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6578 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6581 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6585 tsf = REG_READ(ah, AR_TSF_U32);
6586 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6590 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6595 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6598 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6599 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6605 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6608 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6610 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6613 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6615 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6619 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6620 enum ath9k_ant_setting settings,
6621 struct ath9k_channel *chan,
6626 struct ath_hal_5416 *ahp = AH5416(ah);
6627 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6629 if (AR_SREV_9280(ah)) {
6630 if (!tx_chainmask_cfg) {
6632 tx_chainmask_cfg = *tx_chainmask;
6633 rx_chainmask_cfg = *rx_chainmask;
6637 case ATH9K_ANT_FIXED_A:
6638 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6639 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6640 *antenna_cfgd = true;
6642 case ATH9K_ANT_FIXED_B:
6643 if (ah->ah_caps.tx_chainmask >
6644 ATH9K_ANTENNA1_CHAINMASK) {
6645 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6647 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6648 *antenna_cfgd = true;
6650 case ATH9K_ANT_VARIABLE:
6651 *tx_chainmask = tx_chainmask_cfg;
6652 *rx_chainmask = rx_chainmask_cfg;
6653 *antenna_cfgd = true;
6659 ahp->ah_diversityControl = settings;
6665 void ath9k_hw_setopmode(struct ath_hal *ah)
6667 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6671 ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
6672 u32 capability, u32 *result)
6674 struct ath_hal_5416 *ahp = AH5416(ah);
6675 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6678 case ATH9K_CAP_CIPHER:
6679 switch (capability) {
6680 case ATH9K_CIPHER_AES_CCM:
6681 case ATH9K_CIPHER_AES_OCB:
6682 case ATH9K_CIPHER_TKIP:
6683 case ATH9K_CIPHER_WEP:
6684 case ATH9K_CIPHER_MIC:
6685 case ATH9K_CIPHER_CLR:
6690 case ATH9K_CAP_TKIP_MIC:
6691 switch (capability) {
6695 return (ahp->ah_staId1Defaults &
6696 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6699 case ATH9K_CAP_TKIP_SPLIT:
6700 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6702 case ATH9K_CAP_WME_TKIPMIC:
6704 case ATH9K_CAP_PHYCOUNTERS:
6705 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6706 case ATH9K_CAP_DIVERSITY:
6707 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6708 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6710 case ATH9K_CAP_PHYDIAG:
6712 case ATH9K_CAP_MCAST_KEYSRCH:
6713 switch (capability) {
6717 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6720 return (ahp->ah_staId1Defaults &
6721 AR_STA_ID1_MCAST_KSRCH) ? true :
6726 case ATH9K_CAP_TSF_ADJUST:
6727 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6729 case ATH9K_CAP_RFSILENT:
6730 if (capability == 3)
6732 case ATH9K_CAP_ANT_CFG_2GHZ:
6733 *result = pCap->num_antcfg_2ghz;
6735 case ATH9K_CAP_ANT_CFG_5GHZ:
6736 *result = pCap->num_antcfg_5ghz;
6738 case ATH9K_CAP_TXPOW:
6739 switch (capability) {
6743 *result = ah->ah_powerLimit;
6746 *result = ah->ah_maxPowerLevel;
6749 *result = ah->ah_tpScale;
6759 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6761 struct ath_hal_5416 *ahp = AH5416(ah);
6762 struct ath9k_channel *chan = ah->ah_curchan;
6763 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6765 u32 halNumAntConfig;
6768 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6771 if (cfg < halNumAntConfig) {
6772 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6773 cfg, &ant_config)) {
6774 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6782 bool ath9k_hw_intrpend(struct ath_hal *ah)
6786 if (AR_SREV_9100(ah))
6789 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6790 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6793 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6794 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6795 && (host_isr != AR_INTR_SPURIOUS))
6801 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6805 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6807 bool fatal_int = false;
6809 if (!AR_SREV_9100(ah)) {
6810 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6811 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6812 == AR_RTC_STATUS_ON) {
6813 isr = REG_READ(ah, AR_ISR);
6819 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6823 if (!isr && !sync_cause)
6827 isr = REG_READ(ah, AR_ISR);
6831 struct ath_hal_5416 *ahp = AH5416(ah);
6833 if (isr & AR_ISR_BCNMISC) {
6835 isr2 = REG_READ(ah, AR_ISR_S2);
6836 if (isr2 & AR_ISR_S2_TIM)
6837 mask2 |= ATH9K_INT_TIM;
6838 if (isr2 & AR_ISR_S2_DTIM)
6839 mask2 |= ATH9K_INT_DTIM;
6840 if (isr2 & AR_ISR_S2_DTIMSYNC)
6841 mask2 |= ATH9K_INT_DTIMSYNC;
6842 if (isr2 & (AR_ISR_S2_CABEND))
6843 mask2 |= ATH9K_INT_CABEND;
6844 if (isr2 & AR_ISR_S2_GTT)
6845 mask2 |= ATH9K_INT_GTT;
6846 if (isr2 & AR_ISR_S2_CST)
6847 mask2 |= ATH9K_INT_CST;
6850 isr = REG_READ(ah, AR_ISR_RAC);
6851 if (isr == 0xffffffff) {
6856 *masked = isr & ATH9K_INT_COMMON;
6858 if (ahp->ah_intrMitigation) {
6860 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6861 *masked |= ATH9K_INT_RX;
6864 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6865 *masked |= ATH9K_INT_RX;
6867 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6871 *masked |= ATH9K_INT_TX;
6873 s0_s = REG_READ(ah, AR_ISR_S0_S);
6874 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6875 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6877 s1_s = REG_READ(ah, AR_ISR_S1_S);
6878 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6879 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6882 if (isr & AR_ISR_RXORN) {
6883 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6884 "%s: receive FIFO overrun interrupt\n",
6888 if (!AR_SREV_9100(ah)) {
6889 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
6890 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6891 if (isr5 & AR_ISR_S5_TIM_TIMER)
6892 *masked |= ATH9K_INT_TIM_TIMER;
6898 if (AR_SREV_9100(ah))
6903 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6907 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6908 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6909 "%s: received PCI FATAL interrupt\n",
6912 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6913 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6914 "%s: received PCI PERR interrupt\n",
6918 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6919 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6920 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6922 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6923 REG_WRITE(ah, AR_RC, 0);
6924 *masked |= ATH9K_INT_FATAL;
6926 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6927 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6928 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6932 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6933 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6938 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6940 return AH5416(ah)->ah_maskReg;
6943 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6945 struct ath_hal_5416 *ahp = AH5416(ah);
6946 u32 omask = ahp->ah_maskReg;
6948 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6950 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6953 if (omask & ATH9K_INT_GLOBAL) {
6954 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6956 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6957 (void) REG_READ(ah, AR_IER);
6958 if (!AR_SREV_9100(ah)) {
6959 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6960 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6962 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6963 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6967 mask = ints & ATH9K_INT_COMMON;
6970 if (ints & ATH9K_INT_TX) {
6971 if (ahp->ah_txOkInterruptMask)
6972 mask |= AR_IMR_TXOK;
6973 if (ahp->ah_txDescInterruptMask)
6974 mask |= AR_IMR_TXDESC;
6975 if (ahp->ah_txErrInterruptMask)
6976 mask |= AR_IMR_TXERR;
6977 if (ahp->ah_txEolInterruptMask)
6978 mask |= AR_IMR_TXEOL;
6980 if (ints & ATH9K_INT_RX) {
6981 mask |= AR_IMR_RXERR;
6982 if (ahp->ah_intrMitigation)
6983 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6985 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6986 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
6987 mask |= AR_IMR_GENTMR;
6990 if (ints & (ATH9K_INT_BMISC)) {
6991 mask |= AR_IMR_BCNMISC;
6992 if (ints & ATH9K_INT_TIM)
6993 mask2 |= AR_IMR_S2_TIM;
6994 if (ints & ATH9K_INT_DTIM)
6995 mask2 |= AR_IMR_S2_DTIM;
6996 if (ints & ATH9K_INT_DTIMSYNC)
6997 mask2 |= AR_IMR_S2_DTIMSYNC;
6998 if (ints & ATH9K_INT_CABEND)
6999 mask2 |= (AR_IMR_S2_CABEND);
7002 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
7003 mask |= AR_IMR_BCNMISC;
7004 if (ints & ATH9K_INT_GTT)
7005 mask2 |= AR_IMR_S2_GTT;
7006 if (ints & ATH9K_INT_CST)
7007 mask2 |= AR_IMR_S2_CST;
7010 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
7012 REG_WRITE(ah, AR_IMR, mask);
7013 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7015 AR_IMR_S2_DTIMSYNC |
7019 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7020 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7021 ahp->ah_maskReg = ints;
7023 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
7024 if (ints & ATH9K_INT_TIM_TIMER)
7025 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7027 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7030 if (ints & ATH9K_INT_GLOBAL) {
7031 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7033 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7034 if (!AR_SREV_9100(ah)) {
7035 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7037 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7040 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7041 AR_INTR_SYNC_DEFAULT);
7042 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7043 AR_INTR_SYNC_DEFAULT);
7045 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7046 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7053 ath9k_hw_beaconinit(struct ath_hal *ah,
7054 u32 next_beacon, u32 beacon_period)
7056 struct ath_hal_5416 *ahp = AH5416(ah);
7059 ahp->ah_beaconInterval = beacon_period;
7061 switch (ah->ah_opmode) {
7063 case ATH9K_M_MONITOR:
7064 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7065 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7066 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7067 flags |= AR_TBTT_TIMER_EN;
7070 REG_SET_BIT(ah, AR_TXCFG,
7071 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7072 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7073 TU_TO_USEC(next_beacon +
7074 (ahp->ah_atimWindow ? ahp->
7075 ah_atimWindow : 1)));
7076 flags |= AR_NDP_TIMER_EN;
7077 case ATH9K_M_HOSTAP:
7078 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7079 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7080 TU_TO_USEC(next_beacon -
7082 dma_beacon_response_time));
7083 REG_WRITE(ah, AR_NEXT_SWBA,
7084 TU_TO_USEC(next_beacon -
7086 sw_beacon_response_time));
7088 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7092 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7093 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7094 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7095 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7097 beacon_period &= ~ATH9K_BEACON_ENA;
7098 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7099 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7100 ath9k_hw_reset_tsf(ah);
7103 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7107 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7108 const struct ath9k_beacon_state *bs)
7110 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7111 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7113 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7115 REG_WRITE(ah, AR_BEACON_PERIOD,
7116 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7117 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7118 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7120 REG_RMW_FIELD(ah, AR_RSSI_THR,
7121 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7123 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7125 if (bs->bs_sleepduration > beaconintval)
7126 beaconintval = bs->bs_sleepduration;
7128 dtimperiod = bs->bs_dtimperiod;
7129 if (bs->bs_sleepduration > dtimperiod)
7130 dtimperiod = bs->bs_sleepduration;
7132 if (beaconintval == dtimperiod)
7133 nextTbtt = bs->bs_nextdtim;
7135 nextTbtt = bs->bs_nexttbtt;
7137 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7139 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7141 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7143 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7146 REG_WRITE(ah, AR_NEXT_DTIM,
7147 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7148 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7150 REG_WRITE(ah, AR_SLEEP1,
7151 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7152 | AR_SLEEP1_ASSUME_DTIM);
7154 if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
7155 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7157 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7159 REG_WRITE(ah, AR_SLEEP2,
7160 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7162 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7163 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7165 REG_SET_BIT(ah, AR_TIMER_MODE,
7166 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7171 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7173 if (entry < ah->ah_caps.keycache_size) {
7174 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7175 if (val & AR_KEYTABLE_VALID)
7181 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7185 if (entry >= ah->ah_caps.keycache_size) {
7186 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7187 "%s: entry %u out of range\n", __func__, entry);
7190 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7192 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7193 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7194 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7195 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7196 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7197 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7198 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7199 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7201 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7202 u16 micentry = entry + 64;
7204 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7205 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7206 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7207 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7211 if (ah->ah_curchan == NULL)
7218 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7223 if (entry >= ah->ah_caps.keycache_size) {
7224 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7225 "%s: entry %u out of range\n", __func__, entry);
7230 macHi = (mac[5] << 8) | mac[4];
7231 macLo = (mac[3] << 24) | (mac[2] << 16)
7232 | (mac[1] << 8) | mac[0];
7234 macLo |= (macHi & 1) << 31;
7239 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7240 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7246 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7247 const struct ath9k_keyval *k,
7248 const u8 *mac, int xorKey)
7250 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7251 u32 key0, key1, key2, key3, key4;
7253 u32 xorMask = xorKey ?
7254 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7255 | ATH9K_KEY_XOR) : 0;
7256 struct ath_hal_5416 *ahp = AH5416(ah);
7258 if (entry >= pCap->keycache_size) {
7259 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260 "%s: entry %u out of range\n", __func__, entry);
7263 switch (k->kv_type) {
7264 case ATH9K_CIPHER_AES_OCB:
7265 keyType = AR_KEYTABLE_TYPE_AES;
7267 case ATH9K_CIPHER_AES_CCM:
7268 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
7269 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7270 "%s: AES-CCM not supported by "
7271 "mac rev 0x%x\n", __func__,
7275 keyType = AR_KEYTABLE_TYPE_CCM;
7277 case ATH9K_CIPHER_TKIP:
7278 keyType = AR_KEYTABLE_TYPE_TKIP;
7279 if (ATH9K_IS_MIC_ENABLED(ah)
7280 && entry + 64 >= pCap->keycache_size) {
7281 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7282 "%s: entry %u inappropriate for TKIP\n",
7287 case ATH9K_CIPHER_WEP:
7288 if (k->kv_len < LEN_WEP40) {
7289 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7290 "%s: WEP key length %u too small\n",
7291 __func__, k->kv_len);
7294 if (k->kv_len <= LEN_WEP40)
7295 keyType = AR_KEYTABLE_TYPE_40;
7296 else if (k->kv_len <= LEN_WEP104)
7297 keyType = AR_KEYTABLE_TYPE_104;
7299 keyType = AR_KEYTABLE_TYPE_128;
7301 case ATH9K_CIPHER_CLR:
7302 keyType = AR_KEYTABLE_TYPE_CLR;
7305 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7306 "%s: cipher %u not supported\n", __func__,
7311 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7312 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7313 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7314 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7315 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7316 if (k->kv_len <= LEN_WEP104)
7319 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7320 u16 micentry = entry + 64;
7322 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7323 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7324 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7325 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7326 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7327 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7328 (void) ath9k_hw_keysetmac(ah, entry, mac);
7330 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7331 u32 mic0, mic1, mic2, mic3, mic4;
7333 mic0 = get_unaligned_le32(k->kv_mic + 0);
7334 mic2 = get_unaligned_le32(k->kv_mic + 4);
7335 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7336 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7337 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7338 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7341 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7342 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7343 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7344 AR_KEYTABLE_TYPE_CLR);
7349 mic0 = get_unaligned_le32(k->kv_mic + 0);
7350 mic2 = get_unaligned_le32(k->kv_mic + 4);
7351 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7352 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7353 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7354 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7355 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7356 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7357 AR_KEYTABLE_TYPE_CLR);
7359 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7360 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7361 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7362 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7364 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7365 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7366 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7367 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7368 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7369 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7371 (void) ath9k_hw_keysetmac(ah, entry, mac);
7374 if (ah->ah_curchan == NULL)
7381 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7383 struct ath_hal_5416 *ahp = AH5416(ah);
7384 u32 txcfg, curLevel, newLevel;
7385 enum ath9k_int omask;
7387 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7390 omask = ath9k_hw_set_interrupts(ah,
7391 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7393 txcfg = REG_READ(ah, AR_TXCFG);
7394 curLevel = MS(txcfg, AR_FTRIG);
7395 newLevel = curLevel;
7396 if (bIncTrigLevel) {
7397 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7399 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7401 if (newLevel != curLevel)
7402 REG_WRITE(ah, AR_TXCFG,
7403 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7405 ath9k_hw_set_interrupts(ah, omask);
7407 ah->ah_txTrigLevel = newLevel;
7409 return newLevel != curLevel;
7412 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7413 const struct ath9k_tx_queue_info *qinfo)
7416 struct ath_hal_5416 *ahp = AH5416(ah);
7417 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7418 struct ath9k_tx_queue_info *qi;
7420 if (q >= pCap->total_queues) {
7421 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7426 qi = &ahp->ah_txq[q];
7427 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7428 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7433 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7435 qi->tqi_ver = qinfo->tqi_ver;
7436 qi->tqi_subtype = qinfo->tqi_subtype;
7437 qi->tqi_qflags = qinfo->tqi_qflags;
7438 qi->tqi_priority = qinfo->tqi_priority;
7439 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7440 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
7442 qi->tqi_aifs = INIT_AIFS;
7443 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7444 cw = min(qinfo->tqi_cwmin, 1024U);
7446 while (qi->tqi_cwmin < cw)
7447 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7449 qi->tqi_cwmin = qinfo->tqi_cwmin;
7450 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7451 cw = min(qinfo->tqi_cwmax, 1024U);
7453 while (qi->tqi_cwmax < cw)
7454 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7456 qi->tqi_cwmax = INIT_CWMAX;
7458 if (qinfo->tqi_shretry != 0)
7459 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
7461 qi->tqi_shretry = INIT_SH_RETRY;
7462 if (qinfo->tqi_lgretry != 0)
7463 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
7465 qi->tqi_lgretry = INIT_LG_RETRY;
7466 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7467 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7468 qi->tqi_burstTime = qinfo->tqi_burstTime;
7469 qi->tqi_readyTime = qinfo->tqi_readyTime;
7471 switch (qinfo->tqi_subtype) {
7472 case ATH9K_WME_UPSD:
7473 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7474 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7482 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7483 struct ath9k_tx_queue_info *qinfo)
7485 struct ath_hal_5416 *ahp = AH5416(ah);
7486 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7487 struct ath9k_tx_queue_info *qi;
7489 if (q >= pCap->total_queues) {
7490 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7495 qi = &ahp->ah_txq[q];
7496 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7497 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7502 qinfo->tqi_qflags = qi->tqi_qflags;
7503 qinfo->tqi_ver = qi->tqi_ver;
7504 qinfo->tqi_subtype = qi->tqi_subtype;
7505 qinfo->tqi_qflags = qi->tqi_qflags;
7506 qinfo->tqi_priority = qi->tqi_priority;
7507 qinfo->tqi_aifs = qi->tqi_aifs;
7508 qinfo->tqi_cwmin = qi->tqi_cwmin;
7509 qinfo->tqi_cwmax = qi->tqi_cwmax;
7510 qinfo->tqi_shretry = qi->tqi_shretry;
7511 qinfo->tqi_lgretry = qi->tqi_lgretry;
7512 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7513 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7514 qinfo->tqi_burstTime = qi->tqi_burstTime;
7515 qinfo->tqi_readyTime = qi->tqi_readyTime;
7521 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7522 const struct ath9k_tx_queue_info *qinfo)
7524 struct ath_hal_5416 *ahp = AH5416(ah);
7525 struct ath9k_tx_queue_info *qi;
7526 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7530 case ATH9K_TX_QUEUE_BEACON:
7531 q = pCap->total_queues - 1;
7533 case ATH9K_TX_QUEUE_CAB:
7534 q = pCap->total_queues - 2;
7536 case ATH9K_TX_QUEUE_PSPOLL:
7539 case ATH9K_TX_QUEUE_UAPSD:
7540 q = pCap->total_queues - 3;
7542 case ATH9K_TX_QUEUE_DATA:
7543 for (q = 0; q < pCap->total_queues; q++)
7544 if (ahp->ah_txq[q].tqi_type ==
7545 ATH9K_TX_QUEUE_INACTIVE)
7547 if (q == pCap->total_queues) {
7548 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7549 "%s: no available tx queue\n", __func__);
7554 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7559 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7561 qi = &ahp->ah_txq[q];
7562 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7563 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7564 "%s: tx queue %u already active\n", __func__, q);
7567 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7568 qi->tqi_type = type;
7569 if (qinfo == NULL) {
7571 TXQ_FLAG_TXOKINT_ENABLE
7572 | TXQ_FLAG_TXERRINT_ENABLE
7573 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7574 qi->tqi_aifs = INIT_AIFS;
7575 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7576 qi->tqi_cwmax = INIT_CWMAX;
7577 qi->tqi_shretry = INIT_SH_RETRY;
7578 qi->tqi_lgretry = INIT_LG_RETRY;
7579 qi->tqi_physCompBuf = 0;
7581 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7582 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
7589 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7590 struct ath9k_tx_queue_info *qi)
7592 struct ath_hal_5416 *ahp = AH5416(ah);
7594 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7595 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7596 __func__, ahp->ah_txOkInterruptMask,
7597 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7598 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7600 REG_WRITE(ah, AR_IMR_S0,
7601 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7602 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7603 REG_WRITE(ah, AR_IMR_S1,
7604 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7605 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7606 REG_RMW_FIELD(ah, AR_IMR_S2,
7607 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7610 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7612 struct ath_hal_5416 *ahp = AH5416(ah);
7613 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7614 struct ath9k_tx_queue_info *qi;
7616 if (q >= pCap->total_queues) {
7617 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7621 qi = &ahp->ah_txq[q];
7622 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7623 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7628 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7631 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7632 ahp->ah_txOkInterruptMask &= ~(1 << q);
7633 ahp->ah_txErrInterruptMask &= ~(1 << q);
7634 ahp->ah_txDescInterruptMask &= ~(1 << q);
7635 ahp->ah_txEolInterruptMask &= ~(1 << q);
7636 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7637 ath9k_hw_set_txq_interrupts(ah, qi);
7642 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7644 struct ath_hal_5416 *ahp = AH5416(ah);
7645 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7646 struct ath9k_channel *chan = ah->ah_curchan;
7647 struct ath9k_tx_queue_info *qi;
7648 u32 cwMin, chanCwMin, value;
7650 if (q >= pCap->total_queues) {
7651 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7655 qi = &ahp->ah_txq[q];
7656 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7657 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7662 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7664 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7665 if (chan && IS_CHAN_B(chan))
7666 chanCwMin = INIT_CWMIN_11B;
7668 chanCwMin = INIT_CWMIN;
7670 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7672 cwMin = qi->tqi_cwmin;
7674 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7675 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7676 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7678 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7679 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7680 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7681 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7684 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7685 REG_WRITE(ah, AR_DMISC(q),
7686 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7688 if (qi->tqi_cbrPeriod) {
7689 REG_WRITE(ah, AR_QCBRCFG(q),
7690 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7691 | SM(qi->tqi_cbrOverflowLimit,
7692 AR_Q_CBRCFG_OVF_THRESH));
7693 REG_WRITE(ah, AR_QMISC(q),
7695 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7696 tqi_cbrOverflowLimit
7698 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7702 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7703 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7704 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7705 AR_Q_RDYTIMECFG_EN);
7708 REG_WRITE(ah, AR_DCHNTIME(q),
7709 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7710 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7712 if (qi->tqi_burstTime
7713 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7714 REG_WRITE(ah, AR_QMISC(q),
7717 AR_Q_MISC_RDYTIME_EXP_POLICY);
7721 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7722 REG_WRITE(ah, AR_DMISC(q),
7723 REG_READ(ah, AR_DMISC(q)) |
7724 AR_D_MISC_POST_FR_BKOFF_DIS);
7726 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7727 REG_WRITE(ah, AR_DMISC(q),
7728 REG_READ(ah, AR_DMISC(q)) |
7729 AR_D_MISC_FRAG_BKOFF_EN);
7731 switch (qi->tqi_type) {
7732 case ATH9K_TX_QUEUE_BEACON:
7733 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7734 | AR_Q_MISC_FSP_DBA_GATED
7735 | AR_Q_MISC_BEACON_USE
7736 | AR_Q_MISC_CBR_INCR_DIS1);
7738 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7739 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7740 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7741 | AR_D_MISC_BEACON_USE
7742 | AR_D_MISC_POST_FR_BKOFF_DIS);
7744 case ATH9K_TX_QUEUE_CAB:
7745 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7746 | AR_Q_MISC_FSP_DBA_GATED
7747 | AR_Q_MISC_CBR_INCR_DIS1
7748 | AR_Q_MISC_CBR_INCR_DIS0);
7749 value = (qi->tqi_readyTime
7750 - (ah->ah_config.sw_beacon_response_time -
7751 ah->ah_config.dma_beacon_response_time)
7753 ah->ah_config.additional_swba_backoff) *
7755 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7756 value | AR_Q_RDYTIMECFG_EN);
7757 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7758 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7759 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7761 case ATH9K_TX_QUEUE_PSPOLL:
7762 REG_WRITE(ah, AR_QMISC(q),
7764 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7766 case ATH9K_TX_QUEUE_UAPSD:
7767 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7768 | AR_D_MISC_POST_FR_BKOFF_DIS);
7774 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7775 REG_WRITE(ah, AR_DMISC(q),
7776 REG_READ(ah, AR_DMISC(q)) |
7777 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7778 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7779 AR_D_MISC_POST_FR_BKOFF_DIS);
7782 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7783 ahp->ah_txOkInterruptMask |= 1 << q;
7785 ahp->ah_txOkInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7787 ahp->ah_txErrInterruptMask |= 1 << q;
7789 ahp->ah_txErrInterruptMask &= ~(1 << q);
7790 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7791 ahp->ah_txDescInterruptMask |= 1 << q;
7793 ahp->ah_txDescInterruptMask &= ~(1 << q);
7794 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7795 ahp->ah_txEolInterruptMask |= 1 << q;
7797 ahp->ah_txEolInterruptMask &= ~(1 << q);
7798 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7799 ahp->ah_txUrnInterruptMask |= 1 << q;
7801 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7802 ath9k_hw_set_txq_interrupts(ah, qi);
7807 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7809 struct ath_hal_5416 *ahp = AH5416(ah);
7810 *txqs &= ahp->ah_intrTxqs;
7811 ahp->ah_intrTxqs &= ~(*txqs);
7815 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7816 u32 segLen, bool firstSeg,
7817 bool lastSeg, const struct ath_desc *ds0)
7819 struct ar5416_desc *ads = AR5416DESC(ds);
7822 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7823 } else if (lastSeg) {
7825 ads->ds_ctl1 = segLen;
7826 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7827 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7830 ads->ds_ctl1 = segLen | AR_TxMore;
7834 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7835 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7836 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7837 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7838 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7842 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7844 struct ar5416_desc *ads = AR5416DESC(ds);
7846 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7847 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7848 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7849 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7850 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7854 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7856 struct ar5416_desc *ads = AR5416DESC(ds);
7858 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7859 return -EINPROGRESS;
7861 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7862 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7863 ds->ds_txstat.ts_status = 0;
7864 ds->ds_txstat.ts_flags = 0;
7866 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7867 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7868 if (ads->ds_txstatus1 & AR_Filtered)
7869 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7870 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7871 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7872 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7873 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7874 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7875 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7877 if (ads->ds_txstatus1 & AR_DescCfgErr)
7878 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7879 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7880 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7881 ath9k_hw_updatetxtriglevel(ah, true);
7883 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7884 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7885 ath9k_hw_updatetxtriglevel(ah, true);
7887 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7888 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7889 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7890 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7893 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7894 switch (ds->ds_txstat.ts_rateindex) {
7896 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7899 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7902 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7905 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7909 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7910 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7911 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7912 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7913 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7914 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7915 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7916 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7917 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7918 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7919 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7920 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7921 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7922 ds->ds_txstat.ts_antenna = 1;
7928 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7929 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7930 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7932 struct ar5416_desc *ads = AR5416DESC(ds);
7933 struct ath_hal_5416 *ahp = AH5416(ah);
7935 txPower += ahp->ah_txPowerIndexOffset;
7939 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7940 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7941 | SM(txPower, AR_XmitPower)
7942 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7943 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7944 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7945 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7948 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7949 | SM(type, AR_FrameType)
7950 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7951 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7952 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7954 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7956 if (AR_SREV_9285(ah)) {
7966 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7967 struct ath_desc *lastds,
7968 u32 durUpdateEn, u32 rtsctsRate,
7970 struct ath9k_11n_rate_series series[],
7971 u32 nseries, u32 flags)
7973 struct ar5416_desc *ads = AR5416DESC(ds);
7974 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7978 (void) rtsctsDuration;
7980 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7981 ds_ctl0 = ads->ds_ctl0;
7983 if (flags & ATH9K_TXDESC_RTSENA) {
7984 ds_ctl0 &= ~AR_CTSEnable;
7985 ds_ctl0 |= AR_RTSEnable;
7987 ds_ctl0 &= ~AR_RTSEnable;
7988 ds_ctl0 |= AR_CTSEnable;
7991 ads->ds_ctl0 = ds_ctl0;
7994 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7997 ads->ds_ctl2 = set11nTries(series, 0)
7998 | set11nTries(series, 1)
7999 | set11nTries(series, 2)
8000 | set11nTries(series, 3)
8001 | (durUpdateEn ? AR_DurUpdateEna : 0)
8002 | SM(0, AR_BurstDur);
8004 ads->ds_ctl3 = set11nRate(series, 0)
8005 | set11nRate(series, 1)
8006 | set11nRate(series, 2)
8007 | set11nRate(series, 3);
8009 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8010 | set11nPktDurRTSCTS(series, 1);
8012 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8013 | set11nPktDurRTSCTS(series, 3);
8015 ads->ds_ctl7 = set11nRateFlags(series, 0)
8016 | set11nRateFlags(series, 1)
8017 | set11nRateFlags(series, 2)
8018 | set11nRateFlags(series, 3)
8019 | SM(rtsctsRate, AR_RTSCTSRate);
8020 last_ads->ds_ctl2 = ads->ds_ctl2;
8021 last_ads->ds_ctl3 = ads->ds_ctl3;
8025 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8028 struct ar5416_desc *ads = AR5416DESC(ds);
8030 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8032 ads->ds_ctl6 &= ~AR_AggrLen;
8033 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8037 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8040 struct ar5416_desc *ads = AR5416DESC(ds);
8043 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8045 ctl6 = ads->ds_ctl6;
8046 ctl6 &= ~AR_PadDelim;
8047 ctl6 |= SM(numDelims, AR_PadDelim);
8048 ads->ds_ctl6 = ctl6;
8051 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8053 struct ar5416_desc *ads = AR5416DESC(ds);
8055 ads->ds_ctl1 |= AR_IsAggr;
8056 ads->ds_ctl1 &= ~AR_MoreAggr;
8057 ads->ds_ctl6 &= ~AR_PadDelim;
8060 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8062 struct ar5416_desc *ads = AR5416DESC(ds);
8064 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8068 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8071 struct ar5416_desc *ads = AR5416DESC(ds);
8073 ads->ds_ctl2 &= ~AR_BurstDur;
8074 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8078 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8081 struct ar5416_desc *ads = AR5416DESC(ds);
8084 ads->ds_ctl0 |= AR_VirtMoreFrag;
8086 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8089 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8091 REG_WRITE(ah, AR_RXDP, rxdp);
8094 void ath9k_hw_rxena(struct ath_hal *ah)
8096 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8099 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8103 REG_SET_BIT(ah, AR_DIAG_SW,
8104 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8107 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8110 REG_CLR_BIT(ah, AR_DIAG_SW,
8114 reg = REG_READ(ah, AR_OBS_BUS_1);
8115 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8116 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8122 REG_CLR_BIT(ah, AR_DIAG_SW,
8123 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8130 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8133 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8134 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8138 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8139 u32 size, u32 flags)
8141 struct ar5416_desc *ads = AR5416DESC(ds);
8142 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
8144 ads->ds_ctl1 = size & AR_BufLen;
8145 if (flags & ATH9K_RXDESC_INTREQ)
8146 ads->ds_ctl1 |= AR_RxIntrReq;
8148 ads->ds_rxstatus8 &= ~AR_RxDone;
8149 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
8150 memset(&(ads->u), 0, sizeof(ads->u));
8155 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8156 u32 pa, struct ath_desc *nds, u64 tsf)
8158 struct ar5416_desc ads;
8159 struct ar5416_desc *adsp = AR5416DESC(ds);
8161 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8162 return -EINPROGRESS;
8164 ads.u.rx = adsp->u.rx;
8166 ds->ds_rxstat.rs_status = 0;
8167 ds->ds_rxstat.rs_flags = 0;
8169 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8170 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8172 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8173 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8174 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8175 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8176 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8177 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8178 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8179 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8180 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8182 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8184 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8185 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8187 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8188 ds->ds_rxstat.rs_moreaggr =
8189 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8190 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8191 ds->ds_rxstat.rs_flags =
8192 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8193 ds->ds_rxstat.rs_flags |=
8194 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8196 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8197 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8198 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8199 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8200 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8201 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8203 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8205 if (ads.ds_rxstatus8 & AR_CRCErr)
8206 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8207 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8210 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8211 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8212 ds->ds_rxstat.rs_phyerr = phyerr;
8213 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8214 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8215 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8216 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8222 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8223 struct ath9k_rate_table *rt)
8227 if (rt->rateCodeToIndex[0] != 0)
8229 for (i = 0; i < 256; i++)
8230 rt->rateCodeToIndex[i] = (u8) -1;
8231 for (i = 0; i < rt->rateCount; i++) {
8232 u8 code = rt->info[i].rateCode;
8233 u8 cix = rt->info[i].controlRate;
8235 rt->rateCodeToIndex[code] = i;
8236 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8238 rt->info[i].lpAckDuration =
8239 ath9k_hw_computetxtime(ah, rt,
8240 WLAN_CTRL_FRAME_SIZE,
8243 rt->info[i].spAckDuration =
8244 ath9k_hw_computetxtime(ah, rt,
8245 WLAN_CTRL_FRAME_SIZE,
8251 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8254 struct ath9k_rate_table *rt;
8256 case ATH9K_MODE_11A:
8257 rt = &ar5416_11a_table;
8259 case ATH9K_MODE_11B:
8260 rt = &ar5416_11b_table;
8262 case ATH9K_MODE_11G:
8263 rt = &ar5416_11g_table;
8265 case ATH9K_MODE_11NG_HT20:
8266 case ATH9K_MODE_11NG_HT40PLUS:
8267 case ATH9K_MODE_11NG_HT40MINUS:
8268 rt = &ar5416_11ng_table;
8270 case ATH9K_MODE_11NA_HT20:
8271 case ATH9K_MODE_11NA_HT40PLUS:
8272 case ATH9K_MODE_11NA_HT40MINUS:
8273 rt = &ar5416_11na_table;
8276 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8280 ath9k_hw_setup_rate_table(ah, rt);
8284 static const char *ath9k_hw_devname(u16 devid)
8287 case AR5416_DEVID_PCI:
8288 case AR5416_DEVID_PCIE:
8289 return "Atheros 5416";
8290 case AR9160_DEVID_PCI:
8291 return "Atheros 9160";
8292 case AR9280_DEVID_PCI:
8293 case AR9280_DEVID_PCIE:
8294 return "Atheros 9280";
8299 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8301 return vendorid == ATHEROS_VENDOR_ID ?
8302 ath9k_hw_devname(devid) : NULL;
8305 struct ath_hal *ath9k_hw_attach(u16 devid,
8306 struct ath_softc *sc,
8310 struct ath_hal *ah = NULL;
8313 case AR5416_DEVID_PCI:
8314 case AR5416_DEVID_PCIE:
8315 case AR9160_DEVID_PCI:
8316 case AR9280_DEVID_PCI:
8317 case AR9280_DEVID_PCIE:
8318 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8321 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8322 "devid=0x%x not supported.\n", devid);
8328 ah->ah_devid = ah->ah_devid;
8329 ah->ah_subvendorid = ah->ah_subvendorid;
8330 ah->ah_macVersion = ah->ah_macVersion;
8331 ah->ah_macRev = ah->ah_macRev;
8332 ah->ah_phyRev = ah->ah_phyRev;
8333 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8334 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8340 ath9k_hw_computetxtime(struct ath_hal *ah,
8341 const struct ath9k_rate_table *rates,
8342 u32 frameLen, u16 rateix,
8345 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8348 kbps = rates->info[rateix].rateKbps;
8352 switch (rates->info[rateix].phy) {
8355 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8356 if (shortPreamble && rates->info[rateix].shortPreamble)
8358 numBits = frameLen << 3;
8359 txTime = CCK_SIFS_TIME + phyTime
8360 + ((numBits * 1000) / kbps);
8363 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8365 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8367 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8368 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8369 txTime = OFDM_SIFS_TIME_QUARTER
8370 + OFDM_PREAMBLE_TIME_QUARTER
8371 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8372 } else if (ah->ah_curchan &&
8373 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8375 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8377 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8378 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8379 txTime = OFDM_SIFS_TIME_HALF +
8380 OFDM_PREAMBLE_TIME_HALF
8381 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8383 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8385 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8386 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8387 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8388 + (numSymbols * OFDM_SYMBOL_TIME);
8393 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8394 "%s: unknown phy %u (rate ix %u)\n", __func__,
8395 rates->info[rateix].phy, rateix);
8402 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8404 if (flags & CHANNEL_2GHZ) {
8408 return (freq - 2407) / 5;
8410 return 15 + ((freq - 2512) / 20);
8411 } else if (flags & CHANNEL_5GHZ) {
8412 if (ath9k_regd_is_public_safety_sku(ah) &&
8413 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8414 return ((freq * 10) +
8415 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8416 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8417 return (freq - 4000) / 5;
8419 return (freq - 5000) / 5;
8425 return (freq - 2407) / 5;
8427 if (ath9k_regd_is_public_safety_sku(ah)
8428 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8429 return ((freq * 10) +
8431 2) ? 5 : 0) - 49400) / 5;
8432 } else if (freq > 4900) {
8433 return (freq - 4000) / 5;
8435 return 15 + ((freq - 2512) / 20);
8438 return (freq - 5000) / 5;
8443 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8445 struct ath9k_channel *ichan;
8447 ichan = ath9k_regd_check_channel(ah, chan);
8448 if (ichan == NULL) {
8449 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8450 "%s: invalid channel %u/0x%x; no mapping\n",
8451 __func__, chan->channel, chan->channelFlags);
8454 if (ichan->rawNoiseFloor == 0) {
8455 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8456 return NOISE_FLOOR[mode];
8458 return ichan->rawNoiseFloor;
8461 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8463 struct ath_hal_5416 *ahp = AH5416(ah);
8466 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8468 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8472 bool ath9k_hw_phycounters(struct ath_hal *ah)
8474 struct ath_hal_5416 *ahp = AH5416(ah);
8476 return ahp->ah_hasHwPhyCounters ? true : false;
8479 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8481 return REG_READ(ah, AR_QTXDP(q));
8484 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8487 REG_WRITE(ah, AR_QTXDP(q), txdp);
8492 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8494 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8496 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8501 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8505 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8508 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8514 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8518 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8520 for (wait = 1000; wait != 0; wait--) {
8521 if (ath9k_hw_numtxpending(ah, q) == 0)
8526 if (ath9k_hw_numtxpending(ah, q)) {
8529 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8530 "%s: Num of pending TX Frames %d on Q %d\n",
8531 __func__, ath9k_hw_numtxpending(ah, q), q);
8533 for (j = 0; j < 2; j++) {
8534 tsfLow = REG_READ(ah, AR_TSF_L32);
8535 REG_WRITE(ah, AR_QUIET2,
8536 SM(10, AR_QUIET2_QUIET_DUR));
8537 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8538 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8539 REG_SET_BIT(ah, AR_TIMER_MODE,
8542 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8546 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8547 "%s: TSF have moved while trying to set "
8548 "quiet time TSF: 0x%08x\n",
8552 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8555 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8559 while (ath9k_hw_numtxpending(ah, q)) {
8560 if ((--wait) == 0) {
8561 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8562 "%s: Failed to stop Tx DMA in 100 "
8563 "msec after killing last frame\n",
8570 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8573 REG_WRITE(ah, AR_Q_TXD, 0);