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)) {
5020 if ((abs(cur_vit_mask - bin)) < 75)
5024 if (cur_vit_mask < 0)
5025 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5027 mask_p[cur_vit_mask / 100] = mask_amt;
5029 cur_vit_mask -= 100;
5032 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5033 | (mask_m[48] << 26) | (mask_m[49] << 24)
5034 | (mask_m[50] << 22) | (mask_m[51] << 20)
5035 | (mask_m[52] << 18) | (mask_m[53] << 16)
5036 | (mask_m[54] << 14) | (mask_m[55] << 12)
5037 | (mask_m[56] << 10) | (mask_m[57] << 8)
5038 | (mask_m[58] << 6) | (mask_m[59] << 4)
5039 | (mask_m[60] << 2) | (mask_m[61] << 0);
5040 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5041 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5043 tmp_mask = (mask_m[31] << 28)
5044 | (mask_m[32] << 26) | (mask_m[33] << 24)
5045 | (mask_m[34] << 22) | (mask_m[35] << 20)
5046 | (mask_m[36] << 18) | (mask_m[37] << 16)
5047 | (mask_m[48] << 14) | (mask_m[39] << 12)
5048 | (mask_m[40] << 10) | (mask_m[41] << 8)
5049 | (mask_m[42] << 6) | (mask_m[43] << 4)
5050 | (mask_m[44] << 2) | (mask_m[45] << 0);
5051 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5052 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5054 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5055 | (mask_m[18] << 26) | (mask_m[18] << 24)
5056 | (mask_m[20] << 22) | (mask_m[20] << 20)
5057 | (mask_m[22] << 18) | (mask_m[22] << 16)
5058 | (mask_m[24] << 14) | (mask_m[24] << 12)
5059 | (mask_m[25] << 10) | (mask_m[26] << 8)
5060 | (mask_m[27] << 6) | (mask_m[28] << 4)
5061 | (mask_m[29] << 2) | (mask_m[30] << 0);
5062 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5063 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5065 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5066 | (mask_m[2] << 26) | (mask_m[3] << 24)
5067 | (mask_m[4] << 22) | (mask_m[5] << 20)
5068 | (mask_m[6] << 18) | (mask_m[7] << 16)
5069 | (mask_m[8] << 14) | (mask_m[9] << 12)
5070 | (mask_m[10] << 10) | (mask_m[11] << 8)
5071 | (mask_m[12] << 6) | (mask_m[13] << 4)
5072 | (mask_m[14] << 2) | (mask_m[15] << 0);
5073 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5074 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5076 tmp_mask = (mask_p[15] << 28)
5077 | (mask_p[14] << 26) | (mask_p[13] << 24)
5078 | (mask_p[12] << 22) | (mask_p[11] << 20)
5079 | (mask_p[10] << 18) | (mask_p[9] << 16)
5080 | (mask_p[8] << 14) | (mask_p[7] << 12)
5081 | (mask_p[6] << 10) | (mask_p[5] << 8)
5082 | (mask_p[4] << 6) | (mask_p[3] << 4)
5083 | (mask_p[2] << 2) | (mask_p[1] << 0);
5084 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5085 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5087 tmp_mask = (mask_p[30] << 28)
5088 | (mask_p[29] << 26) | (mask_p[28] << 24)
5089 | (mask_p[27] << 22) | (mask_p[26] << 20)
5090 | (mask_p[25] << 18) | (mask_p[24] << 16)
5091 | (mask_p[23] << 14) | (mask_p[22] << 12)
5092 | (mask_p[21] << 10) | (mask_p[20] << 8)
5093 | (mask_p[19] << 6) | (mask_p[18] << 4)
5094 | (mask_p[17] << 2) | (mask_p[16] << 0);
5095 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5096 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5098 tmp_mask = (mask_p[45] << 28)
5099 | (mask_p[44] << 26) | (mask_p[43] << 24)
5100 | (mask_p[42] << 22) | (mask_p[41] << 20)
5101 | (mask_p[40] << 18) | (mask_p[39] << 16)
5102 | (mask_p[38] << 14) | (mask_p[37] << 12)
5103 | (mask_p[36] << 10) | (mask_p[35] << 8)
5104 | (mask_p[34] << 6) | (mask_p[33] << 4)
5105 | (mask_p[32] << 2) | (mask_p[31] << 0);
5106 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5107 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5109 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5110 | (mask_p[59] << 26) | (mask_p[58] << 24)
5111 | (mask_p[57] << 22) | (mask_p[56] << 20)
5112 | (mask_p[55] << 18) | (mask_p[54] << 16)
5113 | (mask_p[53] << 14) | (mask_p[52] << 12)
5114 | (mask_p[51] << 10) | (mask_p[50] << 8)
5115 | (mask_p[49] << 6) | (mask_p[48] << 4)
5116 | (mask_p[47] << 2) | (mask_p[46] << 0);
5117 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5118 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5121 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5123 struct ath_hal_5416 *ahp = AH5416(ah);
5124 int rx_chainmask, tx_chainmask;
5126 rx_chainmask = ahp->ah_rxchainmask;
5127 tx_chainmask = ahp->ah_txchainmask;
5129 switch (rx_chainmask) {
5131 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5132 AR_PHY_SWAP_ALT_CHAIN);
5134 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5135 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5136 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5141 if (!AR_SREV_9280(ah))
5144 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5145 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5151 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5152 if (tx_chainmask == 0x5) {
5153 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5154 AR_PHY_SWAP_ALT_CHAIN);
5156 if (AR_SREV_9100(ah))
5157 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5158 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5161 static void ath9k_hw_set_addac(struct ath_hal *ah,
5162 struct ath9k_channel *chan)
5164 struct modal_eep_header *pModal;
5165 struct ath_hal_5416 *ahp = AH5416(ah);
5166 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5169 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5172 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5175 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5177 if (pModal->xpaBiasLvl != 0xff) {
5178 biaslevel = pModal->xpaBiasLvl;
5181 u16 resetFreqBin, freqBin, freqCount = 0;
5182 struct chan_centers centers;
5184 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5187 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5188 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5189 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5193 while (freqCount < 3) {
5194 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5197 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5198 if (resetFreqBin >= freqBin) {
5201 xpaBiasLvlFreq[freqCount]
5210 if (IS_CHAN_2GHZ(chan)) {
5211 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5212 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5215 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5216 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5221 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5223 if (ah->ah_curchan != NULL)
5225 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5227 return clks / CLOCK_RATE[ATH9K_MODE_11B];
5230 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5232 struct ath9k_channel *chan = ah->ah_curchan;
5234 if (chan && IS_CHAN_HT40(chan))
5235 return ath9k_hw_mac_usec(ah, clks) / 2;
5237 return ath9k_hw_mac_usec(ah, clks);
5240 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5242 if (ah->ah_curchan != NULL)
5243 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5246 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
5249 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5251 struct ath9k_channel *chan = ah->ah_curchan;
5253 if (chan && IS_CHAN_HT40(chan))
5254 return ath9k_hw_mac_clks(ah, usecs) * 2;
5256 return ath9k_hw_mac_clks(ah, usecs);
5259 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5261 struct ath_hal_5416 *ahp = AH5416(ah);
5263 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5264 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5266 ahp->ah_acktimeout = (u32) -1;
5269 REG_RMW_FIELD(ah, AR_TIME_OUT,
5270 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5271 ahp->ah_acktimeout = us;
5276 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5278 struct ath_hal_5416 *ahp = AH5416(ah);
5280 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5281 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5283 ahp->ah_ctstimeout = (u32) -1;
5286 REG_RMW_FIELD(ah, AR_TIME_OUT,
5287 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5288 ahp->ah_ctstimeout = us;
5292 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5295 struct ath_hal_5416 *ahp = AH5416(ah);
5298 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5299 "%s: bad global tx timeout %u\n", __func__, tu);
5300 ahp->ah_globaltxtimeout = (u32) -1;
5303 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5304 ahp->ah_globaltxtimeout = tu;
5309 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5311 struct ath_hal_5416 *ahp = AH5416(ah);
5313 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5314 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5316 ahp->ah_slottime = (u32) -1;
5319 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5320 ahp->ah_slottime = us;
5325 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5327 struct ath_hal_5416 *ahp = AH5416(ah);
5329 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5330 __func__, ahp->ah_miscMode);
5331 if (ahp->ah_miscMode != 0)
5332 REG_WRITE(ah, AR_PCU_MISC,
5333 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5334 if (ahp->ah_slottime != (u32) -1)
5335 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5336 if (ahp->ah_acktimeout != (u32) -1)
5337 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5338 if (ahp->ah_ctstimeout != (u32) -1)
5339 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5340 if (ahp->ah_globaltxtimeout != (u32) -1)
5341 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5345 ath9k_hw_process_ini(struct ath_hal *ah,
5346 struct ath9k_channel *chan,
5347 enum ath9k_ht_macmode macmode)
5349 int i, regWrites = 0;
5350 struct ath_hal_5416 *ahp = AH5416(ah);
5351 u32 modesIndex, freqIndex;
5354 switch (chan->chanmode) {
5356 case CHANNEL_A_HT20:
5360 case CHANNEL_A_HT40PLUS:
5361 case CHANNEL_A_HT40MINUS:
5366 case CHANNEL_G_HT20:
5371 case CHANNEL_G_HT40PLUS:
5372 case CHANNEL_G_HT40MINUS:
5381 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5383 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5385 ath9k_hw_set_addac(ah, chan);
5387 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5388 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5390 struct ar5416IniArray temp;
5392 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5393 ahp->ah_iniAddac.ia_columns;
5395 memcpy(ahp->ah_addac5416_21,
5396 ahp->ah_iniAddac.ia_array, addacSize);
5398 (ahp->ah_addac5416_21)[31 *
5399 ahp->ah_iniAddac.ia_columns + 1] = 0;
5401 temp.ia_array = ahp->ah_addac5416_21;
5402 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5403 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5404 REG_WRITE_ARRAY(&temp, 1, regWrites);
5406 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5408 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5409 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5410 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5412 #ifdef CONFIG_SLOW_ANT_DIV
5413 if (ah->ah_devid == AR9280_DEVID_PCI)
5414 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5418 REG_WRITE(ah, reg, val);
5420 if (reg >= 0x7800 && reg < 0x78a0
5421 && ah->ah_config.analog_shiftreg) {
5425 DO_DELAY(regWrites);
5428 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5429 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5430 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5432 REG_WRITE(ah, reg, val);
5434 if (reg >= 0x7800 && reg < 0x78a0
5435 && ah->ah_config.analog_shiftreg) {
5439 DO_DELAY(regWrites);
5442 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5444 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5445 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5449 ath9k_hw_override_ini(ah, chan);
5450 ath9k_hw_set_regs(ah, chan, macmode);
5451 ath9k_hw_init_chain_masks(ah);
5453 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5454 ath9k_regd_get_ctl(ah, chan),
5455 ath9k_regd_get_antenna_allowed(ah,
5457 chan->maxRegTxPower * 2,
5458 min((u32) MAX_RATE_POWER,
5459 (u32) ah->ah_powerLimit));
5461 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5462 "%s: error init'ing transmit power\n", __func__);
5466 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5467 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5468 "%s: ar5416SetRfRegs failed\n", __func__);
5475 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5476 struct hal_cal_list *currCal)
5478 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5479 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5480 currCal->calData->calCountMax);
5482 switch (currCal->calData->calType) {
5483 case IQ_MISMATCH_CAL:
5484 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5485 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5486 "%s: starting IQ Mismatch Calibration\n",
5490 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5491 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5492 "%s: starting ADC Gain Calibration\n", __func__);
5495 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5496 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5497 "%s: starting ADC DC Calibration\n", __func__);
5499 case ADC_DC_INIT_CAL:
5500 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5501 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5502 "%s: starting Init ADC DC Calibration\n",
5507 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5508 AR_PHY_TIMING_CTRL4_DO_CAL);
5511 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5512 struct hal_cal_list *currCal)
5514 struct ath_hal_5416 *ahp = AH5416(ah);
5517 ath9k_hw_setup_calibration(ah, currCal);
5519 currCal->calState = CAL_RUNNING;
5521 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5522 ahp->ah_Meas0.sign[i] = 0;
5523 ahp->ah_Meas1.sign[i] = 0;
5524 ahp->ah_Meas2.sign[i] = 0;
5525 ahp->ah_Meas3.sign[i] = 0;
5528 ahp->ah_CalSamples = 0;
5532 ath9k_hw_per_calibration(struct ath_hal *ah,
5533 struct ath9k_channel *ichan,
5535 struct hal_cal_list *currCal,
5538 struct ath_hal_5416 *ahp = AH5416(ah);
5542 if (currCal->calState == CAL_RUNNING) {
5544 AR_PHY_TIMING_CTRL4(0)) &
5545 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5547 currCal->calData->calCollect(ah);
5549 ahp->ah_CalSamples++;
5551 if (ahp->ah_CalSamples >=
5552 currCal->calData->calNumSamples) {
5553 int i, numChains = 0;
5554 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5555 if (rxchainmask & (1 << i))
5559 currCal->calData->calPostProc(ah,
5563 currCal->calData->calType;
5564 currCal->calState = CAL_DONE;
5567 ath9k_hw_setup_calibration(ah, currCal);
5570 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5571 ath9k_hw_reset_calibration(ah, currCal);
5575 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5578 struct ath_hal_5416 *ahp = AH5416(ah);
5579 struct ath9k_channel ichan;
5581 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5582 const struct hal_percal_data *calData = currCal->calData;
5585 if (currCal == NULL)
5590 for (i = 0; i < init_cal_count; i++) {
5591 ath9k_hw_reset_calibration(ah, currCal);
5593 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5594 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5595 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5596 "%s: Cal %d failed to complete in 100ms.\n",
5597 __func__, calData->calType);
5599 ahp->ah_cal_list = ahp->ah_cal_list_last =
5600 ahp->ah_cal_list_curr = NULL;
5604 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5605 currCal, &isCalDone);
5607 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5608 "%s: Not able to run Init Cal %d.\n",
5609 __func__, calData->calType);
5611 if (currCal->calNext) {
5612 currCal = currCal->calNext;
5613 calData = currCal->calData;
5617 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5622 ath9k_hw_channel_change(struct ath_hal *ah,
5623 struct ath9k_channel *chan,
5624 enum ath9k_ht_macmode macmode)
5626 u32 synthDelay, qnum;
5627 struct ath_hal_5416 *ahp = AH5416(ah);
5629 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5630 if (ath9k_hw_numtxpending(ah, qnum)) {
5631 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5632 "%s: Transmit frames pending on queue %d\n",
5638 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5639 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5640 AR_PHY_RFBUS_GRANT_EN)) {
5641 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5642 "%s: Could not kill baseband RX\n", __func__);
5646 ath9k_hw_set_regs(ah, chan, macmode);
5648 if (AR_SREV_9280_10_OR_LATER(ah)) {
5649 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5650 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5651 "%s: failed to set channel\n", __func__);
5655 if (!(ath9k_hw_set_channel(ah, chan))) {
5656 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5657 "%s: failed to set channel\n", __func__);
5662 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5663 ath9k_regd_get_ctl(ah, chan),
5664 ath9k_regd_get_antenna_allowed(ah, chan),
5665 chan->maxRegTxPower * 2,
5666 min((u32) MAX_RATE_POWER,
5667 (u32) ah->ah_powerLimit)) != 0) {
5668 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5669 "%s: error init'ing transmit power\n", __func__);
5673 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5674 if (IS_CHAN_CCK(chan))
5675 synthDelay = (4 * synthDelay) / 22;
5679 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5681 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5683 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5684 ath9k_hw_set_delta_slope(ah, chan);
5686 if (AR_SREV_9280_10_OR_LATER(ah))
5687 ath9k_hw_9280_spur_mitigate(ah, chan);
5689 ath9k_hw_spur_mitigate(ah, chan);
5691 if (!chan->oneTimeCalsDone)
5692 chan->oneTimeCalsDone = true;
5697 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5698 struct ath9k_channel *chan)
5700 struct ath_hal_5416 *ahp = AH5416(ah);
5702 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5705 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5708 ahp->ah_chipFullSleep = false;
5710 ath9k_hw_init_pll(ah, chan);
5712 ath9k_hw_set_rfmode(ah, chan);
5717 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5721 regval = REG_READ(ah, AR_AHB_MODE);
5722 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5724 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5725 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5727 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5729 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5730 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5732 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5734 if (AR_SREV_9285(ah)) {
5735 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5736 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5738 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5739 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5743 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5745 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5746 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5747 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5748 "%s: dma failed to stop in 10ms\n"
5749 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5751 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5758 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5760 REG_CLR_BIT(ah, AR_DIAG_SW,
5761 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5763 ath9k_enable_mib_counters(ah);
5765 ath9k_ani_reset(ah);
5768 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5770 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5772 ath9k_hw_disable_mib_counters(ah);
5775 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5776 struct ath9k_channel *chan,
5777 enum hal_cal_types calType)
5779 struct ath_hal_5416 *ahp = AH5416(ah);
5780 bool retval = false;
5782 switch (calType & ahp->ah_suppCals) {
5783 case IQ_MISMATCH_CAL:
5784 if (!IS_CHAN_B(chan))
5789 if (!IS_CHAN_B(chan)
5790 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5798 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5799 struct ath9k_channel *chan)
5801 struct ath_hal_5416 *ahp = AH5416(ah);
5802 struct ath9k_channel *ichan =
5803 ath9k_regd_check_channel(ah, chan);
5805 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5806 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5807 AR_PHY_AGC_CONTROL_CAL);
5810 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5811 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5812 "%s: offset calibration failed to complete in 1ms; "
5813 "noisy environment?\n", __func__);
5817 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5818 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5819 AR_PHY_AGC_CONTROL_NF);
5821 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5824 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5825 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5826 INIT_CAL(&ahp->ah_adcGainCalData);
5827 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5828 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5829 "%s: enabling ADC Gain Calibration.\n",
5832 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5833 INIT_CAL(&ahp->ah_adcDcCalData);
5834 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5835 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5836 "%s: enabling ADC DC Calibration.\n",
5839 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5840 INIT_CAL(&ahp->ah_iqCalData);
5841 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5842 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5843 "%s: enabling IQ Calibration.\n",
5847 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5849 if (ahp->ah_cal_list_curr)
5850 ath9k_hw_reset_calibration(ah,
5851 ahp->ah_cal_list_curr);
5854 ichan->CalValid = 0;
5860 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5861 struct ath9k_channel *chan,
5862 enum ath9k_ht_macmode macmode,
5863 u8 txchainmask, u8 rxchainmask,
5864 enum ath9k_ht_extprotspacing extprotspacing,
5865 bool bChannelChange,
5868 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5870 struct ath_hal_5416 *ahp = AH5416(ah);
5871 struct ath9k_channel *curchan = ah->ah_curchan;
5875 int i, rx_chainmask;
5877 ahp->ah_extprotspacing = extprotspacing;
5878 ahp->ah_txchainmask = txchainmask;
5879 ahp->ah_rxchainmask = rxchainmask;
5881 if (AR_SREV_9280(ah)) {
5882 ahp->ah_txchainmask &= 0x3;
5883 ahp->ah_rxchainmask &= 0x3;
5886 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5887 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5888 "%s: invalid channel %u/0x%x; no mapping\n",
5889 __func__, chan->channel, chan->channelFlags);
5893 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5897 ath9k_hw_getnf(ah, curchan);
5899 if (bChannelChange &&
5900 (ahp->ah_chipFullSleep != true) &&
5901 (ah->ah_curchan != NULL) &&
5902 (chan->channel != ah->ah_curchan->channel) &&
5903 ((chan->channelFlags & CHANNEL_ALL) ==
5904 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5905 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5906 !IS_CHAN_A_5MHZ_SPACED(ah->
5909 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5910 ath9k_hw_loadnf(ah, ah->ah_curchan);
5911 ath9k_hw_start_nfcal(ah);
5916 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5917 if (saveDefAntenna == 0)
5920 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5922 saveLedState = REG_READ(ah, AR_CFG_LED) &
5923 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5924 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5926 ath9k_hw_mark_phy_inactive(ah);
5928 if (!ath9k_hw_chip_reset(ah, chan)) {
5929 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5934 if (AR_SREV_9280(ah)) {
5935 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5936 AR_GPIO_JTAG_DISABLE);
5938 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
5939 if (IS_CHAN_5GHZ(chan))
5940 ath9k_hw_set_gpio(ah, 9, 0);
5942 ath9k_hw_set_gpio(ah, 9, 1);
5944 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5947 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5951 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5952 ath9k_hw_set_delta_slope(ah, chan);
5954 if (AR_SREV_9280_10_OR_LATER(ah))
5955 ath9k_hw_9280_spur_mitigate(ah, chan);
5957 ath9k_hw_spur_mitigate(ah, chan);
5959 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5960 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5961 "%s: error setting board options\n", __func__);
5965 ath9k_hw_decrease_chain_power(ah, chan);
5967 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5968 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5970 | AR_STA_ID1_RTS_USE_DEF
5972 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5973 | ahp->ah_staId1Defaults);
5974 ath9k_hw_set_operating_mode(ah, opmode);
5976 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5977 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5979 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5981 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5982 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5983 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5985 REG_WRITE(ah, AR_ISR, ~0);
5987 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5989 if (AR_SREV_9280_10_OR_LATER(ah)) {
5990 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5993 if (!(ath9k_hw_set_channel(ah, chan)))
5997 for (i = 0; i < AR_NUM_DCU; i++)
5998 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
6000 ahp->ah_intrTxqs = 0;
6001 for (i = 0; i < ah->ah_caps.total_queues; i++)
6002 ath9k_hw_resettxqueue(ah, i);
6004 ath9k_hw_init_interrupt_masks(ah, opmode);
6005 ath9k_hw_init_qos(ah);
6007 ath9k_hw_init_user_settings(ah);
6009 ah->ah_opmode = opmode;
6011 REG_WRITE(ah, AR_STA_ID1,
6012 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6014 ath9k_hw_set_dma(ah);
6016 REG_WRITE(ah, AR_OBS, 8);
6018 if (ahp->ah_intrMitigation) {
6020 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6021 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6024 ath9k_hw_init_bb(ah, chan);
6026 if (!ath9k_hw_init_cal(ah, chan))
6029 rx_chainmask = ahp->ah_rxchainmask;
6030 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6031 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6032 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6035 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6037 if (AR_SREV_9100(ah)) {
6039 mask = REG_READ(ah, AR_CFG);
6040 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6041 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6042 "%s CFG Byte Swap Set 0x%x\n", __func__,
6046 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6047 REG_WRITE(ah, AR_CFG, mask);
6048 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6049 "%s Setting CFG 0x%x\n", __func__,
6050 REG_READ(ah, AR_CFG));
6054 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6066 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6068 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6071 bool ath9k_hw_disable(struct ath_hal *ah)
6073 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6076 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6080 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6081 u8 rxchainmask, bool longcal,
6084 struct ath_hal_5416 *ahp = AH5416(ah);
6085 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6086 struct ath9k_channel *ichan =
6087 ath9k_regd_check_channel(ah, chan);
6091 if (ichan == NULL) {
6092 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6093 "%s: invalid channel %u/0x%x; no mapping\n",
6094 __func__, chan->channel, chan->channelFlags);
6099 (currCal->calState == CAL_RUNNING ||
6100 currCal->calState == CAL_WAITING)) {
6101 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6104 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6106 if (currCal->calState == CAL_WAITING) {
6108 ath9k_hw_reset_calibration(ah, currCal);
6114 ath9k_hw_getnf(ah, ichan);
6115 ath9k_hw_loadnf(ah, ah->ah_curchan);
6116 ath9k_hw_start_nfcal(ah);
6118 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6120 chan->channelFlags |= CHANNEL_CW_INT;
6121 ichan->channelFlags &= ~CHANNEL_CW_INT;
6128 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6130 struct ath_hal_5416 *ahp = AH5416(ah);
6133 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6134 ahp->ah_totalPowerMeasI[i] +=
6135 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6136 ahp->ah_totalPowerMeasQ[i] +=
6137 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6138 ahp->ah_totalIqCorrMeas[i] +=
6139 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6140 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6141 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6142 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6143 ahp->ah_totalPowerMeasQ[i],
6144 ahp->ah_totalIqCorrMeas[i]);
6148 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6150 struct ath_hal_5416 *ahp = AH5416(ah);
6153 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6154 ahp->ah_totalAdcIOddPhase[i] +=
6155 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6156 ahp->ah_totalAdcIEvenPhase[i] +=
6157 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6158 ahp->ah_totalAdcQOddPhase[i] +=
6159 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6160 ahp->ah_totalAdcQEvenPhase[i] +=
6161 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6163 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6164 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6165 "oddq=0x%08x; evenq=0x%08x;\n",
6166 ahp->ah_CalSamples, i,
6167 ahp->ah_totalAdcIOddPhase[i],
6168 ahp->ah_totalAdcIEvenPhase[i],
6169 ahp->ah_totalAdcQOddPhase[i],
6170 ahp->ah_totalAdcQEvenPhase[i]);
6174 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6176 struct ath_hal_5416 *ahp = AH5416(ah);
6179 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6180 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6181 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6182 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6183 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6184 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6185 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6186 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6187 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6189 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6190 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6191 "oddq=0x%08x; evenq=0x%08x;\n",
6192 ahp->ah_CalSamples, i,
6193 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6194 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6195 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6196 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6200 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6202 struct ath_hal_5416 *ahp = AH5416(ah);
6203 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6204 u32 qCoffDenom, iCoffDenom;
6205 int32_t qCoff, iCoff;
6208 for (i = 0; i < numChains; i++) {
6209 powerMeasI = ahp->ah_totalPowerMeasI[i];
6210 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6211 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6213 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6214 "Starting IQ Cal and Correction for Chain %d\n",
6217 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6219 i, ahp->ah_totalIqCorrMeas[i]);
6224 if (iqCorrMeas > 0x80000000) {
6225 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6229 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6230 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6231 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6232 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6233 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6236 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6237 qCoffDenom = powerMeasQ / 64;
6239 if (powerMeasQ != 0) {
6241 iCoff = iqCorrMeas / iCoffDenom;
6242 qCoff = powerMeasI / qCoffDenom - 64;
6243 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6244 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6245 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6246 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6249 iCoff = iCoff & 0x3f;
6250 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6251 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6252 if (iqCorrNeg == 0x0)
6253 iCoff = 0x40 - iCoff;
6257 else if (qCoff <= -16)
6260 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6261 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6264 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6265 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6267 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6268 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6270 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6271 "IQ Cal and Correction done for Chain %d\n",
6276 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6277 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6281 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6283 struct ath_hal_5416 *ahp = AH5416(ah);
6284 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6286 u32 qGainMismatch, iGainMismatch, val, i;
6288 for (i = 0; i < numChains; i++) {
6289 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6290 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6291 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6292 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6294 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6295 "Starting ADC Gain Cal for Chain %d\n", i);
6297 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6298 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6300 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6301 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6303 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6304 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6306 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6307 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6310 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6312 ((iEvenMeasOffset * 32) /
6313 iOddMeasOffset) & 0x3f;
6315 ((qOddMeasOffset * 32) /
6316 qEvenMeasOffset) & 0x3f;
6318 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6319 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6321 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6322 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6325 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6327 val |= (qGainMismatch) | (iGainMismatch << 6);
6328 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6330 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6331 "ADC Gain Cal done for Chain %d\n", i);
6335 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6336 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6337 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6341 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6343 struct ath_hal_5416 *ahp = AH5416(ah);
6344 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6345 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6346 const struct hal_percal_data *calData =
6347 ahp->ah_cal_list_curr->calData;
6349 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6351 for (i = 0; i < numChains; i++) {
6352 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6353 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6354 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6355 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6357 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6358 "Starting ADC DC Offset Cal for Chain %d\n", i);
6360 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6361 "Chn %d pwr_meas_odd_i = %d\n", i,
6363 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6364 "Chn %d pwr_meas_even_i = %d\n", i,
6366 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6367 "Chn %d pwr_meas_odd_q = %d\n", i,
6369 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6370 "Chn %d pwr_meas_even_q = %d\n", i,
6373 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6374 numSamples) & 0x1ff;
6375 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6376 numSamples) & 0x1ff;
6378 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6379 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6381 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6382 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6385 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6387 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6388 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6390 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6391 "ADC DC Offset Cal done for Chain %d\n", i);
6394 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6395 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6396 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6399 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6401 struct ath_hal_5416 *ahp = AH5416(ah);
6402 struct ath9k_channel *chan = ah->ah_curchan;
6404 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6406 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6407 ath9k_regd_get_ctl(ah, chan),
6408 ath9k_regd_get_antenna_allowed(ah,
6410 chan->maxRegTxPower * 2,
6411 min((u32) MAX_RATE_POWER,
6412 (u32) ah->ah_powerLimit)) != 0)
6419 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6420 struct ath9k_channel *chan,
6421 struct chan_centers *centers)
6424 struct ath_hal_5416 *ahp = AH5416(ah);
6426 if (!IS_CHAN_HT40(chan)) {
6427 centers->ctl_center = centers->ext_center =
6428 centers->synth_center = chan->channel;
6432 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6433 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6434 centers->synth_center =
6435 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6438 centers->synth_center =
6439 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6443 centers->ctl_center = centers->synth_center - (extoff *
6444 HT40_CHANNEL_CENTER_SHIFT);
6445 centers->ext_center = centers->synth_center + (extoff *
6449 ATH9K_HT_EXTPROTSPACING_20)
6451 HT40_CHANNEL_CENTER_SHIFT
6457 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6460 struct ath_hal_5416 *ahp = AH5416(ah);
6461 struct ath9k_channel *ichan =
6462 ath9k_regd_check_channel(ah, chan);
6463 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6467 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6470 if (currCal == NULL)
6473 if (ichan == NULL) {
6474 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6475 "%s: invalid channel %u/0x%x; no mapping\n",
6476 __func__, chan->channel, chan->channelFlags);
6481 if (currCal->calState != CAL_DONE) {
6482 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6483 "%s: Calibration state incorrect, %d\n",
6484 __func__, currCal->calState);
6489 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6492 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6493 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6494 __func__, currCal->calData->calType, chan->channel,
6495 chan->channelFlags);
6497 ichan->CalValid &= ~currCal->calData->calType;
6498 currCal->calState = CAL_WAITING;
6503 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6505 struct ath_hal_5416 *ahp = AH5416(ah);
6507 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6510 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6512 struct ath_hal_5416 *ahp = AH5416(ah);
6514 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6518 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6520 struct ath_hal_5416 *ahp = AH5416(ah);
6522 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6526 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6528 struct ath_hal_5416 *ahp = AH5416(ah);
6530 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6532 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6533 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6538 #ifdef CONFIG_ATH9K_RFKILL
6539 static void ath9k_enable_rfkill(struct ath_hal *ah)
6541 struct ath_hal_5416 *ahp = AH5416(ah);
6543 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6544 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6546 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6547 AR_GPIO_INPUT_MUX2_RFSILENT);
6549 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6550 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6552 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6554 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6557 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6564 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6567 struct ath_hal_5416 *ahp = AH5416(ah);
6569 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6570 ahp->ah_assocId = assocId;
6572 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6573 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6574 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6577 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6581 tsf = REG_READ(ah, AR_TSF_U32);
6582 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6586 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6591 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6594 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6595 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6601 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6604 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6606 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6609 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6611 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6615 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6616 enum ath9k_ant_setting settings,
6617 struct ath9k_channel *chan,
6622 struct ath_hal_5416 *ahp = AH5416(ah);
6623 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6625 if (AR_SREV_9280(ah)) {
6626 if (!tx_chainmask_cfg) {
6628 tx_chainmask_cfg = *tx_chainmask;
6629 rx_chainmask_cfg = *rx_chainmask;
6633 case ATH9K_ANT_FIXED_A:
6634 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6635 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6636 *antenna_cfgd = true;
6638 case ATH9K_ANT_FIXED_B:
6639 if (ah->ah_caps.tx_chainmask >
6640 ATH9K_ANTENNA1_CHAINMASK) {
6641 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6643 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6644 *antenna_cfgd = true;
6646 case ATH9K_ANT_VARIABLE:
6647 *tx_chainmask = tx_chainmask_cfg;
6648 *rx_chainmask = rx_chainmask_cfg;
6649 *antenna_cfgd = true;
6655 ahp->ah_diversityControl = settings;
6661 void ath9k_hw_setopmode(struct ath_hal *ah)
6663 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6667 ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
6668 u32 capability, u32 *result)
6670 struct ath_hal_5416 *ahp = AH5416(ah);
6671 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6674 case ATH9K_CAP_CIPHER:
6675 switch (capability) {
6676 case ATH9K_CIPHER_AES_CCM:
6677 case ATH9K_CIPHER_AES_OCB:
6678 case ATH9K_CIPHER_TKIP:
6679 case ATH9K_CIPHER_WEP:
6680 case ATH9K_CIPHER_MIC:
6681 case ATH9K_CIPHER_CLR:
6686 case ATH9K_CAP_TKIP_MIC:
6687 switch (capability) {
6691 return (ahp->ah_staId1Defaults &
6692 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6695 case ATH9K_CAP_TKIP_SPLIT:
6696 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6698 case ATH9K_CAP_WME_TKIPMIC:
6700 case ATH9K_CAP_PHYCOUNTERS:
6701 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6702 case ATH9K_CAP_DIVERSITY:
6703 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6704 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6706 case ATH9K_CAP_PHYDIAG:
6708 case ATH9K_CAP_MCAST_KEYSRCH:
6709 switch (capability) {
6713 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6716 return (ahp->ah_staId1Defaults &
6717 AR_STA_ID1_MCAST_KSRCH) ? true :
6722 case ATH9K_CAP_TSF_ADJUST:
6723 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6725 case ATH9K_CAP_RFSILENT:
6726 if (capability == 3)
6728 case ATH9K_CAP_ANT_CFG_2GHZ:
6729 *result = pCap->num_antcfg_2ghz;
6731 case ATH9K_CAP_ANT_CFG_5GHZ:
6732 *result = pCap->num_antcfg_5ghz;
6734 case ATH9K_CAP_TXPOW:
6735 switch (capability) {
6739 *result = ah->ah_powerLimit;
6742 *result = ah->ah_maxPowerLevel;
6745 *result = ah->ah_tpScale;
6755 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6757 struct ath_hal_5416 *ahp = AH5416(ah);
6758 struct ath9k_channel *chan = ah->ah_curchan;
6759 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6761 u32 halNumAntConfig;
6764 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6767 if (cfg < halNumAntConfig) {
6768 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6769 cfg, &ant_config)) {
6770 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6778 bool ath9k_hw_intrpend(struct ath_hal *ah)
6782 if (AR_SREV_9100(ah))
6785 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6786 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6789 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6790 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6791 && (host_isr != AR_INTR_SPURIOUS))
6797 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6801 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6803 bool fatal_int = false;
6805 if (!AR_SREV_9100(ah)) {
6806 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6807 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6808 == AR_RTC_STATUS_ON) {
6809 isr = REG_READ(ah, AR_ISR);
6815 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6819 if (!isr && !sync_cause)
6823 isr = REG_READ(ah, AR_ISR);
6827 struct ath_hal_5416 *ahp = AH5416(ah);
6829 if (isr & AR_ISR_BCNMISC) {
6831 isr2 = REG_READ(ah, AR_ISR_S2);
6832 if (isr2 & AR_ISR_S2_TIM)
6833 mask2 |= ATH9K_INT_TIM;
6834 if (isr2 & AR_ISR_S2_DTIM)
6835 mask2 |= ATH9K_INT_DTIM;
6836 if (isr2 & AR_ISR_S2_DTIMSYNC)
6837 mask2 |= ATH9K_INT_DTIMSYNC;
6838 if (isr2 & (AR_ISR_S2_CABEND))
6839 mask2 |= ATH9K_INT_CABEND;
6840 if (isr2 & AR_ISR_S2_GTT)
6841 mask2 |= ATH9K_INT_GTT;
6842 if (isr2 & AR_ISR_S2_CST)
6843 mask2 |= ATH9K_INT_CST;
6846 isr = REG_READ(ah, AR_ISR_RAC);
6847 if (isr == 0xffffffff) {
6852 *masked = isr & ATH9K_INT_COMMON;
6854 if (ahp->ah_intrMitigation) {
6856 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6857 *masked |= ATH9K_INT_RX;
6860 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6861 *masked |= ATH9K_INT_RX;
6863 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6867 *masked |= ATH9K_INT_TX;
6869 s0_s = REG_READ(ah, AR_ISR_S0_S);
6870 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6871 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6873 s1_s = REG_READ(ah, AR_ISR_S1_S);
6874 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6875 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6878 if (isr & AR_ISR_RXORN) {
6879 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6880 "%s: receive FIFO overrun interrupt\n",
6884 if (!AR_SREV_9100(ah)) {
6885 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
6886 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6887 if (isr5 & AR_ISR_S5_TIM_TIMER)
6888 *masked |= ATH9K_INT_TIM_TIMER;
6894 if (AR_SREV_9100(ah))
6899 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6903 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6904 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6905 "%s: received PCI FATAL interrupt\n",
6908 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6909 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6910 "%s: received PCI PERR interrupt\n",
6914 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6915 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6916 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6918 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6919 REG_WRITE(ah, AR_RC, 0);
6920 *masked |= ATH9K_INT_FATAL;
6922 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6923 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6924 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6928 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6929 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6934 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6936 return AH5416(ah)->ah_maskReg;
6939 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6941 struct ath_hal_5416 *ahp = AH5416(ah);
6942 u32 omask = ahp->ah_maskReg;
6944 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6946 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6949 if (omask & ATH9K_INT_GLOBAL) {
6950 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6952 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6953 (void) REG_READ(ah, AR_IER);
6954 if (!AR_SREV_9100(ah)) {
6955 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6956 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6958 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6959 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6963 mask = ints & ATH9K_INT_COMMON;
6966 if (ints & ATH9K_INT_TX) {
6967 if (ahp->ah_txOkInterruptMask)
6968 mask |= AR_IMR_TXOK;
6969 if (ahp->ah_txDescInterruptMask)
6970 mask |= AR_IMR_TXDESC;
6971 if (ahp->ah_txErrInterruptMask)
6972 mask |= AR_IMR_TXERR;
6973 if (ahp->ah_txEolInterruptMask)
6974 mask |= AR_IMR_TXEOL;
6976 if (ints & ATH9K_INT_RX) {
6977 mask |= AR_IMR_RXERR;
6978 if (ahp->ah_intrMitigation)
6979 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6981 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6982 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
6983 mask |= AR_IMR_GENTMR;
6986 if (ints & (ATH9K_INT_BMISC)) {
6987 mask |= AR_IMR_BCNMISC;
6988 if (ints & ATH9K_INT_TIM)
6989 mask2 |= AR_IMR_S2_TIM;
6990 if (ints & ATH9K_INT_DTIM)
6991 mask2 |= AR_IMR_S2_DTIM;
6992 if (ints & ATH9K_INT_DTIMSYNC)
6993 mask2 |= AR_IMR_S2_DTIMSYNC;
6994 if (ints & ATH9K_INT_CABEND)
6995 mask2 |= (AR_IMR_S2_CABEND);
6998 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6999 mask |= AR_IMR_BCNMISC;
7000 if (ints & ATH9K_INT_GTT)
7001 mask2 |= AR_IMR_S2_GTT;
7002 if (ints & ATH9K_INT_CST)
7003 mask2 |= AR_IMR_S2_CST;
7006 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
7008 REG_WRITE(ah, AR_IMR, mask);
7009 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7011 AR_IMR_S2_DTIMSYNC |
7015 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7016 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7017 ahp->ah_maskReg = ints;
7019 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
7020 if (ints & ATH9K_INT_TIM_TIMER)
7021 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7023 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7026 if (ints & ATH9K_INT_GLOBAL) {
7027 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7029 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7030 if (!AR_SREV_9100(ah)) {
7031 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7033 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7036 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7037 AR_INTR_SYNC_DEFAULT);
7038 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7039 AR_INTR_SYNC_DEFAULT);
7041 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7042 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7049 ath9k_hw_beaconinit(struct ath_hal *ah,
7050 u32 next_beacon, u32 beacon_period)
7052 struct ath_hal_5416 *ahp = AH5416(ah);
7055 ahp->ah_beaconInterval = beacon_period;
7057 switch (ah->ah_opmode) {
7059 case ATH9K_M_MONITOR:
7060 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7061 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7062 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7063 flags |= AR_TBTT_TIMER_EN;
7066 REG_SET_BIT(ah, AR_TXCFG,
7067 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7068 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7069 TU_TO_USEC(next_beacon +
7070 (ahp->ah_atimWindow ? ahp->
7071 ah_atimWindow : 1)));
7072 flags |= AR_NDP_TIMER_EN;
7073 case ATH9K_M_HOSTAP:
7074 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7075 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7076 TU_TO_USEC(next_beacon -
7078 dma_beacon_response_time));
7079 REG_WRITE(ah, AR_NEXT_SWBA,
7080 TU_TO_USEC(next_beacon -
7082 sw_beacon_response_time));
7084 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7088 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7089 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7090 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7091 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7093 beacon_period &= ~ATH9K_BEACON_ENA;
7094 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7095 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7096 ath9k_hw_reset_tsf(ah);
7099 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7103 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7104 const struct ath9k_beacon_state *bs)
7106 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7107 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7109 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7111 REG_WRITE(ah, AR_BEACON_PERIOD,
7112 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7113 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7114 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7116 REG_RMW_FIELD(ah, AR_RSSI_THR,
7117 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7119 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7121 if (bs->bs_sleepduration > beaconintval)
7122 beaconintval = bs->bs_sleepduration;
7124 dtimperiod = bs->bs_dtimperiod;
7125 if (bs->bs_sleepduration > dtimperiod)
7126 dtimperiod = bs->bs_sleepduration;
7128 if (beaconintval == dtimperiod)
7129 nextTbtt = bs->bs_nextdtim;
7131 nextTbtt = bs->bs_nexttbtt;
7133 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7135 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7137 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7139 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7142 REG_WRITE(ah, AR_NEXT_DTIM,
7143 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7144 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7146 REG_WRITE(ah, AR_SLEEP1,
7147 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7148 | AR_SLEEP1_ASSUME_DTIM);
7150 if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
7151 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7153 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7155 REG_WRITE(ah, AR_SLEEP2,
7156 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7158 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7159 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7161 REG_SET_BIT(ah, AR_TIMER_MODE,
7162 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7167 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7169 if (entry < ah->ah_caps.keycache_size) {
7170 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7171 if (val & AR_KEYTABLE_VALID)
7177 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7181 if (entry >= ah->ah_caps.keycache_size) {
7182 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7183 "%s: entry %u out of range\n", __func__, entry);
7186 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7188 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7189 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7190 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7191 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7192 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7193 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7194 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7195 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7197 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7198 u16 micentry = entry + 64;
7200 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7201 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7202 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7203 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7207 if (ah->ah_curchan == NULL)
7214 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7219 if (entry >= ah->ah_caps.keycache_size) {
7220 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7221 "%s: entry %u out of range\n", __func__, entry);
7226 macHi = (mac[5] << 8) | mac[4];
7227 macLo = (mac[3] << 24) | (mac[2] << 16)
7228 | (mac[1] << 8) | mac[0];
7230 macLo |= (macHi & 1) << 31;
7235 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7236 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7242 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7243 const struct ath9k_keyval *k,
7244 const u8 *mac, int xorKey)
7246 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7247 u32 key0, key1, key2, key3, key4;
7249 u32 xorMask = xorKey ?
7250 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7251 | ATH9K_KEY_XOR) : 0;
7252 struct ath_hal_5416 *ahp = AH5416(ah);
7254 if (entry >= pCap->keycache_size) {
7255 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7256 "%s: entry %u out of range\n", __func__, entry);
7259 switch (k->kv_type) {
7260 case ATH9K_CIPHER_AES_OCB:
7261 keyType = AR_KEYTABLE_TYPE_AES;
7263 case ATH9K_CIPHER_AES_CCM:
7264 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
7265 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7266 "%s: AES-CCM not supported by "
7267 "mac rev 0x%x\n", __func__,
7271 keyType = AR_KEYTABLE_TYPE_CCM;
7273 case ATH9K_CIPHER_TKIP:
7274 keyType = AR_KEYTABLE_TYPE_TKIP;
7275 if (ATH9K_IS_MIC_ENABLED(ah)
7276 && entry + 64 >= pCap->keycache_size) {
7277 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7278 "%s: entry %u inappropriate for TKIP\n",
7283 case ATH9K_CIPHER_WEP:
7284 if (k->kv_len < 40 / NBBY) {
7285 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7286 "%s: WEP key length %u too small\n",
7287 __func__, k->kv_len);
7290 if (k->kv_len <= 40 / NBBY)
7291 keyType = AR_KEYTABLE_TYPE_40;
7292 else if (k->kv_len <= 104 / NBBY)
7293 keyType = AR_KEYTABLE_TYPE_104;
7295 keyType = AR_KEYTABLE_TYPE_128;
7297 case ATH9K_CIPHER_CLR:
7298 keyType = AR_KEYTABLE_TYPE_CLR;
7301 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7302 "%s: cipher %u not supported\n", __func__,
7307 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7308 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7309 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7310 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7311 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7312 if (k->kv_len <= 104 / NBBY)
7315 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7316 u16 micentry = entry + 64;
7318 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7319 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7320 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7321 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7322 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7323 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7324 (void) ath9k_hw_keysetmac(ah, entry, mac);
7326 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7327 u32 mic0, mic1, mic2, mic3, mic4;
7329 mic0 = get_unaligned_le32(k->kv_mic + 0);
7330 mic2 = get_unaligned_le32(k->kv_mic + 4);
7331 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7332 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7333 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7334 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7335 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7336 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7337 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7338 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7339 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7340 AR_KEYTABLE_TYPE_CLR);
7345 mic0 = get_unaligned_le32(k->kv_mic + 0);
7346 mic2 = get_unaligned_le32(k->kv_mic + 4);
7347 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7348 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7349 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7350 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7351 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7352 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7353 AR_KEYTABLE_TYPE_CLR);
7355 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7356 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7357 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7358 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7360 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7361 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7362 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7363 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7364 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7365 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7367 (void) ath9k_hw_keysetmac(ah, entry, mac);
7370 if (ah->ah_curchan == NULL)
7377 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7379 struct ath_hal_5416 *ahp = AH5416(ah);
7380 u32 txcfg, curLevel, newLevel;
7381 enum ath9k_int omask;
7383 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7386 omask = ath9k_hw_set_interrupts(ah,
7387 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7389 txcfg = REG_READ(ah, AR_TXCFG);
7390 curLevel = MS(txcfg, AR_FTRIG);
7391 newLevel = curLevel;
7392 if (bIncTrigLevel) {
7393 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7395 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7397 if (newLevel != curLevel)
7398 REG_WRITE(ah, AR_TXCFG,
7399 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7401 ath9k_hw_set_interrupts(ah, omask);
7403 ah->ah_txTrigLevel = newLevel;
7405 return newLevel != curLevel;
7408 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7409 const struct ath9k_tx_queue_info *qinfo)
7412 struct ath_hal_5416 *ahp = AH5416(ah);
7413 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7414 struct ath9k_tx_queue_info *qi;
7416 if (q >= pCap->total_queues) {
7417 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7422 qi = &ahp->ah_txq[q];
7423 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7424 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7429 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7431 qi->tqi_ver = qinfo->tqi_ver;
7432 qi->tqi_subtype = qinfo->tqi_subtype;
7433 qi->tqi_qflags = qinfo->tqi_qflags;
7434 qi->tqi_priority = qinfo->tqi_priority;
7435 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7436 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
7438 qi->tqi_aifs = INIT_AIFS;
7439 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7440 cw = min(qinfo->tqi_cwmin, 1024U);
7442 while (qi->tqi_cwmin < cw)
7443 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7445 qi->tqi_cwmin = qinfo->tqi_cwmin;
7446 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7447 cw = min(qinfo->tqi_cwmax, 1024U);
7449 while (qi->tqi_cwmax < cw)
7450 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7452 qi->tqi_cwmax = INIT_CWMAX;
7454 if (qinfo->tqi_shretry != 0)
7455 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
7457 qi->tqi_shretry = INIT_SH_RETRY;
7458 if (qinfo->tqi_lgretry != 0)
7459 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
7461 qi->tqi_lgretry = INIT_LG_RETRY;
7462 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7463 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7464 qi->tqi_burstTime = qinfo->tqi_burstTime;
7465 qi->tqi_readyTime = qinfo->tqi_readyTime;
7467 switch (qinfo->tqi_subtype) {
7468 case ATH9K_WME_UPSD:
7469 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7470 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7478 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7479 struct ath9k_tx_queue_info *qinfo)
7481 struct ath_hal_5416 *ahp = AH5416(ah);
7482 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7483 struct ath9k_tx_queue_info *qi;
7485 if (q >= pCap->total_queues) {
7486 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7491 qi = &ahp->ah_txq[q];
7492 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7493 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7498 qinfo->tqi_qflags = qi->tqi_qflags;
7499 qinfo->tqi_ver = qi->tqi_ver;
7500 qinfo->tqi_subtype = qi->tqi_subtype;
7501 qinfo->tqi_qflags = qi->tqi_qflags;
7502 qinfo->tqi_priority = qi->tqi_priority;
7503 qinfo->tqi_aifs = qi->tqi_aifs;
7504 qinfo->tqi_cwmin = qi->tqi_cwmin;
7505 qinfo->tqi_cwmax = qi->tqi_cwmax;
7506 qinfo->tqi_shretry = qi->tqi_shretry;
7507 qinfo->tqi_lgretry = qi->tqi_lgretry;
7508 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7509 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7510 qinfo->tqi_burstTime = qi->tqi_burstTime;
7511 qinfo->tqi_readyTime = qi->tqi_readyTime;
7517 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7518 const struct ath9k_tx_queue_info *qinfo)
7520 struct ath_hal_5416 *ahp = AH5416(ah);
7521 struct ath9k_tx_queue_info *qi;
7522 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7526 case ATH9K_TX_QUEUE_BEACON:
7527 q = pCap->total_queues - 1;
7529 case ATH9K_TX_QUEUE_CAB:
7530 q = pCap->total_queues - 2;
7532 case ATH9K_TX_QUEUE_PSPOLL:
7535 case ATH9K_TX_QUEUE_UAPSD:
7536 q = pCap->total_queues - 3;
7538 case ATH9K_TX_QUEUE_DATA:
7539 for (q = 0; q < pCap->total_queues; q++)
7540 if (ahp->ah_txq[q].tqi_type ==
7541 ATH9K_TX_QUEUE_INACTIVE)
7543 if (q == pCap->total_queues) {
7544 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7545 "%s: no available tx queue\n", __func__);
7550 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7555 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7557 qi = &ahp->ah_txq[q];
7558 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7559 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7560 "%s: tx queue %u already active\n", __func__, q);
7563 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7564 qi->tqi_type = type;
7565 if (qinfo == NULL) {
7567 TXQ_FLAG_TXOKINT_ENABLE
7568 | TXQ_FLAG_TXERRINT_ENABLE
7569 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7570 qi->tqi_aifs = INIT_AIFS;
7571 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7572 qi->tqi_cwmax = INIT_CWMAX;
7573 qi->tqi_shretry = INIT_SH_RETRY;
7574 qi->tqi_lgretry = INIT_LG_RETRY;
7575 qi->tqi_physCompBuf = 0;
7577 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7578 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
7585 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7586 struct ath9k_tx_queue_info *qi)
7588 struct ath_hal_5416 *ahp = AH5416(ah);
7590 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7591 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7592 __func__, ahp->ah_txOkInterruptMask,
7593 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7594 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7596 REG_WRITE(ah, AR_IMR_S0,
7597 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7598 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7599 REG_WRITE(ah, AR_IMR_S1,
7600 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7601 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7602 REG_RMW_FIELD(ah, AR_IMR_S2,
7603 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7606 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7608 struct ath_hal_5416 *ahp = AH5416(ah);
7609 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7610 struct ath9k_tx_queue_info *qi;
7612 if (q >= pCap->total_queues) {
7613 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7617 qi = &ahp->ah_txq[q];
7618 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7619 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7624 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7627 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7628 ahp->ah_txOkInterruptMask &= ~(1 << q);
7629 ahp->ah_txErrInterruptMask &= ~(1 << q);
7630 ahp->ah_txDescInterruptMask &= ~(1 << q);
7631 ahp->ah_txEolInterruptMask &= ~(1 << q);
7632 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7633 ath9k_hw_set_txq_interrupts(ah, qi);
7638 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7640 struct ath_hal_5416 *ahp = AH5416(ah);
7641 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7642 struct ath9k_channel *chan = ah->ah_curchan;
7643 struct ath9k_tx_queue_info *qi;
7644 u32 cwMin, chanCwMin, value;
7646 if (q >= pCap->total_queues) {
7647 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7651 qi = &ahp->ah_txq[q];
7652 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7653 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7658 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7660 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7661 if (chan && IS_CHAN_B(chan))
7662 chanCwMin = INIT_CWMIN_11B;
7664 chanCwMin = INIT_CWMIN;
7666 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7668 cwMin = qi->tqi_cwmin;
7670 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7671 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7672 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7674 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7675 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7676 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7677 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7680 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7681 REG_WRITE(ah, AR_DMISC(q),
7682 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7684 if (qi->tqi_cbrPeriod) {
7685 REG_WRITE(ah, AR_QCBRCFG(q),
7686 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7687 | SM(qi->tqi_cbrOverflowLimit,
7688 AR_Q_CBRCFG_OVF_THRESH));
7689 REG_WRITE(ah, AR_QMISC(q),
7691 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7692 tqi_cbrOverflowLimit
7694 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7698 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7699 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7700 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7701 AR_Q_RDYTIMECFG_EN);
7704 REG_WRITE(ah, AR_DCHNTIME(q),
7705 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7706 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7708 if (qi->tqi_burstTime
7709 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7710 REG_WRITE(ah, AR_QMISC(q),
7713 AR_Q_MISC_RDYTIME_EXP_POLICY);
7717 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7718 REG_WRITE(ah, AR_DMISC(q),
7719 REG_READ(ah, AR_DMISC(q)) |
7720 AR_D_MISC_POST_FR_BKOFF_DIS);
7722 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7723 REG_WRITE(ah, AR_DMISC(q),
7724 REG_READ(ah, AR_DMISC(q)) |
7725 AR_D_MISC_FRAG_BKOFF_EN);
7727 switch (qi->tqi_type) {
7728 case ATH9K_TX_QUEUE_BEACON:
7729 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7730 | AR_Q_MISC_FSP_DBA_GATED
7731 | AR_Q_MISC_BEACON_USE
7732 | AR_Q_MISC_CBR_INCR_DIS1);
7734 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7735 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7736 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7737 | AR_D_MISC_BEACON_USE
7738 | AR_D_MISC_POST_FR_BKOFF_DIS);
7740 case ATH9K_TX_QUEUE_CAB:
7741 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7742 | AR_Q_MISC_FSP_DBA_GATED
7743 | AR_Q_MISC_CBR_INCR_DIS1
7744 | AR_Q_MISC_CBR_INCR_DIS0);
7745 value = (qi->tqi_readyTime
7746 - (ah->ah_config.sw_beacon_response_time -
7747 ah->ah_config.dma_beacon_response_time)
7749 ah->ah_config.additional_swba_backoff) *
7751 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7752 value | AR_Q_RDYTIMECFG_EN);
7753 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7754 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7755 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7757 case ATH9K_TX_QUEUE_PSPOLL:
7758 REG_WRITE(ah, AR_QMISC(q),
7760 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7762 case ATH9K_TX_QUEUE_UAPSD:
7763 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7764 | AR_D_MISC_POST_FR_BKOFF_DIS);
7770 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7771 REG_WRITE(ah, AR_DMISC(q),
7772 REG_READ(ah, AR_DMISC(q)) |
7773 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7774 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7775 AR_D_MISC_POST_FR_BKOFF_DIS);
7778 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7779 ahp->ah_txOkInterruptMask |= 1 << q;
7781 ahp->ah_txOkInterruptMask &= ~(1 << q);
7782 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7783 ahp->ah_txErrInterruptMask |= 1 << q;
7785 ahp->ah_txErrInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7787 ahp->ah_txDescInterruptMask |= 1 << q;
7789 ahp->ah_txDescInterruptMask &= ~(1 << q);
7790 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7791 ahp->ah_txEolInterruptMask |= 1 << q;
7793 ahp->ah_txEolInterruptMask &= ~(1 << q);
7794 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7795 ahp->ah_txUrnInterruptMask |= 1 << q;
7797 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7798 ath9k_hw_set_txq_interrupts(ah, qi);
7803 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7805 struct ath_hal_5416 *ahp = AH5416(ah);
7806 *txqs &= ahp->ah_intrTxqs;
7807 ahp->ah_intrTxqs &= ~(*txqs);
7811 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7812 u32 segLen, bool firstSeg,
7813 bool lastSeg, const struct ath_desc *ds0)
7815 struct ar5416_desc *ads = AR5416DESC(ds);
7818 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7819 } else if (lastSeg) {
7821 ads->ds_ctl1 = segLen;
7822 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7823 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7826 ads->ds_ctl1 = segLen | AR_TxMore;
7830 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7831 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7832 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7833 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7834 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7838 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7840 struct ar5416_desc *ads = AR5416DESC(ds);
7842 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7843 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7844 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7845 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7846 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7850 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7852 struct ar5416_desc *ads = AR5416DESC(ds);
7854 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7855 return -EINPROGRESS;
7857 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7858 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7859 ds->ds_txstat.ts_status = 0;
7860 ds->ds_txstat.ts_flags = 0;
7862 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7863 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7864 if (ads->ds_txstatus1 & AR_Filtered)
7865 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7866 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7867 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7868 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7869 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7870 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7871 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7873 if (ads->ds_txstatus1 & AR_DescCfgErr)
7874 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7875 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7876 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7877 ath9k_hw_updatetxtriglevel(ah, true);
7879 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7880 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7881 ath9k_hw_updatetxtriglevel(ah, true);
7883 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7884 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7885 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7886 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7889 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7890 switch (ds->ds_txstat.ts_rateindex) {
7892 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7895 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7898 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7901 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7905 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7906 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7907 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7908 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7909 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7910 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7911 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7912 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7913 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7914 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7915 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7916 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7917 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7918 ds->ds_txstat.ts_antenna = 1;
7924 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7925 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7926 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7928 struct ar5416_desc *ads = AR5416DESC(ds);
7929 struct ath_hal_5416 *ahp = AH5416(ah);
7931 txPower += ahp->ah_txPowerIndexOffset;
7935 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7936 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7937 | SM(txPower, AR_XmitPower)
7938 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7939 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7940 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7941 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7944 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7945 | SM(type, AR_FrameType)
7946 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7947 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7948 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7950 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7952 if (AR_SREV_9285(ah)) {
7962 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7963 struct ath_desc *lastds,
7964 u32 durUpdateEn, u32 rtsctsRate,
7966 struct ath9k_11n_rate_series series[],
7967 u32 nseries, u32 flags)
7969 struct ar5416_desc *ads = AR5416DESC(ds);
7970 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7974 (void) rtsctsDuration;
7976 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7977 ds_ctl0 = ads->ds_ctl0;
7979 if (flags & ATH9K_TXDESC_RTSENA) {
7980 ds_ctl0 &= ~AR_CTSEnable;
7981 ds_ctl0 |= AR_RTSEnable;
7983 ds_ctl0 &= ~AR_RTSEnable;
7984 ds_ctl0 |= AR_CTSEnable;
7987 ads->ds_ctl0 = ds_ctl0;
7990 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7993 ads->ds_ctl2 = set11nTries(series, 0)
7994 | set11nTries(series, 1)
7995 | set11nTries(series, 2)
7996 | set11nTries(series, 3)
7997 | (durUpdateEn ? AR_DurUpdateEna : 0)
7998 | SM(0, AR_BurstDur);
8000 ads->ds_ctl3 = set11nRate(series, 0)
8001 | set11nRate(series, 1)
8002 | set11nRate(series, 2)
8003 | set11nRate(series, 3);
8005 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8006 | set11nPktDurRTSCTS(series, 1);
8008 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8009 | set11nPktDurRTSCTS(series, 3);
8011 ads->ds_ctl7 = set11nRateFlags(series, 0)
8012 | set11nRateFlags(series, 1)
8013 | set11nRateFlags(series, 2)
8014 | set11nRateFlags(series, 3)
8015 | SM(rtsctsRate, AR_RTSCTSRate);
8016 last_ads->ds_ctl2 = ads->ds_ctl2;
8017 last_ads->ds_ctl3 = ads->ds_ctl3;
8021 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8024 struct ar5416_desc *ads = AR5416DESC(ds);
8026 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8028 ads->ds_ctl6 &= ~AR_AggrLen;
8029 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8033 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8036 struct ar5416_desc *ads = AR5416DESC(ds);
8039 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8041 ctl6 = ads->ds_ctl6;
8042 ctl6 &= ~AR_PadDelim;
8043 ctl6 |= SM(numDelims, AR_PadDelim);
8044 ads->ds_ctl6 = ctl6;
8047 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8049 struct ar5416_desc *ads = AR5416DESC(ds);
8051 ads->ds_ctl1 |= AR_IsAggr;
8052 ads->ds_ctl1 &= ~AR_MoreAggr;
8053 ads->ds_ctl6 &= ~AR_PadDelim;
8056 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8058 struct ar5416_desc *ads = AR5416DESC(ds);
8060 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8064 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8067 struct ar5416_desc *ads = AR5416DESC(ds);
8069 ads->ds_ctl2 &= ~AR_BurstDur;
8070 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8074 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8077 struct ar5416_desc *ads = AR5416DESC(ds);
8080 ads->ds_ctl0 |= AR_VirtMoreFrag;
8082 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8085 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8087 REG_WRITE(ah, AR_RXDP, rxdp);
8090 void ath9k_hw_rxena(struct ath_hal *ah)
8092 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8095 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8099 REG_SET_BIT(ah, AR_DIAG_SW,
8100 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8103 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8106 REG_CLR_BIT(ah, AR_DIAG_SW,
8110 reg = REG_READ(ah, AR_OBS_BUS_1);
8111 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8112 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8118 REG_CLR_BIT(ah, AR_DIAG_SW,
8119 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8126 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8129 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8130 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8134 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8135 u32 size, u32 flags)
8137 struct ar5416_desc *ads = AR5416DESC(ds);
8138 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
8140 ads->ds_ctl1 = size & AR_BufLen;
8141 if (flags & ATH9K_RXDESC_INTREQ)
8142 ads->ds_ctl1 |= AR_RxIntrReq;
8144 ads->ds_rxstatus8 &= ~AR_RxDone;
8145 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
8146 memset(&(ads->u), 0, sizeof(ads->u));
8151 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8152 u32 pa, struct ath_desc *nds, u64 tsf)
8154 struct ar5416_desc ads;
8155 struct ar5416_desc *adsp = AR5416DESC(ds);
8157 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8158 return -EINPROGRESS;
8160 ads.u.rx = adsp->u.rx;
8162 ds->ds_rxstat.rs_status = 0;
8163 ds->ds_rxstat.rs_flags = 0;
8165 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8166 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8168 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8169 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8170 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8171 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8172 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8173 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8174 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8175 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8176 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8178 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8180 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8181 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8183 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8184 ds->ds_rxstat.rs_moreaggr =
8185 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8186 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8187 ds->ds_rxstat.rs_flags =
8188 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8189 ds->ds_rxstat.rs_flags |=
8190 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8192 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8193 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8194 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8195 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8196 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8197 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8199 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8201 if (ads.ds_rxstatus8 & AR_CRCErr)
8202 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8203 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8206 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8207 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8208 ds->ds_rxstat.rs_phyerr = phyerr;
8209 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8210 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8211 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8212 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8218 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8219 struct ath9k_rate_table *rt)
8223 if (rt->rateCodeToIndex[0] != 0)
8225 for (i = 0; i < 256; i++)
8226 rt->rateCodeToIndex[i] = (u8) -1;
8227 for (i = 0; i < rt->rateCount; i++) {
8228 u8 code = rt->info[i].rateCode;
8229 u8 cix = rt->info[i].controlRate;
8231 rt->rateCodeToIndex[code] = i;
8232 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8234 rt->info[i].lpAckDuration =
8235 ath9k_hw_computetxtime(ah, rt,
8236 WLAN_CTRL_FRAME_SIZE,
8239 rt->info[i].spAckDuration =
8240 ath9k_hw_computetxtime(ah, rt,
8241 WLAN_CTRL_FRAME_SIZE,
8247 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8250 struct ath9k_rate_table *rt;
8252 case ATH9K_MODE_11A:
8253 rt = &ar5416_11a_table;
8255 case ATH9K_MODE_11B:
8256 rt = &ar5416_11b_table;
8258 case ATH9K_MODE_11G:
8259 rt = &ar5416_11g_table;
8261 case ATH9K_MODE_11NG_HT20:
8262 case ATH9K_MODE_11NG_HT40PLUS:
8263 case ATH9K_MODE_11NG_HT40MINUS:
8264 rt = &ar5416_11ng_table;
8266 case ATH9K_MODE_11NA_HT20:
8267 case ATH9K_MODE_11NA_HT40PLUS:
8268 case ATH9K_MODE_11NA_HT40MINUS:
8269 rt = &ar5416_11na_table;
8272 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8276 ath9k_hw_setup_rate_table(ah, rt);
8280 static const char *ath9k_hw_devname(u16 devid)
8283 case AR5416_DEVID_PCI:
8284 case AR5416_DEVID_PCIE:
8285 return "Atheros 5416";
8286 case AR9160_DEVID_PCI:
8287 return "Atheros 9160";
8288 case AR9280_DEVID_PCI:
8289 case AR9280_DEVID_PCIE:
8290 return "Atheros 9280";
8295 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8297 return vendorid == ATHEROS_VENDOR_ID ?
8298 ath9k_hw_devname(devid) : NULL;
8301 struct ath_hal *ath9k_hw_attach(u16 devid,
8302 struct ath_softc *sc,
8306 struct ath_hal *ah = NULL;
8309 case AR5416_DEVID_PCI:
8310 case AR5416_DEVID_PCIE:
8311 case AR9160_DEVID_PCI:
8312 case AR9280_DEVID_PCI:
8313 case AR9280_DEVID_PCIE:
8314 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8317 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8318 "devid=0x%x not supported.\n", devid);
8324 ah->ah_devid = ah->ah_devid;
8325 ah->ah_subvendorid = ah->ah_subvendorid;
8326 ah->ah_macVersion = ah->ah_macVersion;
8327 ah->ah_macRev = ah->ah_macRev;
8328 ah->ah_phyRev = ah->ah_phyRev;
8329 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8330 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8336 ath9k_hw_computetxtime(struct ath_hal *ah,
8337 const struct ath9k_rate_table *rates,
8338 u32 frameLen, u16 rateix,
8341 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8344 kbps = rates->info[rateix].rateKbps;
8348 switch (rates->info[rateix].phy) {
8351 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8352 if (shortPreamble && rates->info[rateix].shortPreamble)
8354 numBits = frameLen << 3;
8355 txTime = CCK_SIFS_TIME + phyTime
8356 + ((numBits * 1000) / kbps);
8359 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8361 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8363 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8364 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8365 txTime = OFDM_SIFS_TIME_QUARTER
8366 + OFDM_PREAMBLE_TIME_QUARTER
8367 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8368 } else if (ah->ah_curchan &&
8369 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8371 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8373 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8374 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8375 txTime = OFDM_SIFS_TIME_HALF +
8376 OFDM_PREAMBLE_TIME_HALF
8377 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8379 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8381 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8382 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8383 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8384 + (numSymbols * OFDM_SYMBOL_TIME);
8389 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8390 "%s: unknown phy %u (rate ix %u)\n", __func__,
8391 rates->info[rateix].phy, rateix);
8398 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8400 if (flags & CHANNEL_2GHZ) {
8404 return (freq - 2407) / 5;
8406 return 15 + ((freq - 2512) / 20);
8407 } else if (flags & CHANNEL_5GHZ) {
8408 if (ath9k_regd_is_public_safety_sku(ah) &&
8409 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8410 return ((freq * 10) +
8411 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8412 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8413 return (freq - 4000) / 5;
8415 return (freq - 5000) / 5;
8421 return (freq - 2407) / 5;
8423 if (ath9k_regd_is_public_safety_sku(ah)
8424 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8425 return ((freq * 10) +
8427 2) ? 5 : 0) - 49400) / 5;
8428 } else if (freq > 4900) {
8429 return (freq - 4000) / 5;
8431 return 15 + ((freq - 2512) / 20);
8434 return (freq - 5000) / 5;
8439 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8441 struct ath9k_channel *ichan;
8443 ichan = ath9k_regd_check_channel(ah, chan);
8444 if (ichan == NULL) {
8445 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8446 "%s: invalid channel %u/0x%x; no mapping\n",
8447 __func__, chan->channel, chan->channelFlags);
8450 if (ichan->rawNoiseFloor == 0) {
8451 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8452 return NOISE_FLOOR[mode];
8454 return ichan->rawNoiseFloor;
8457 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8459 struct ath_hal_5416 *ahp = AH5416(ah);
8462 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8464 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8468 bool ath9k_hw_phycounters(struct ath_hal *ah)
8470 struct ath_hal_5416 *ahp = AH5416(ah);
8472 return ahp->ah_hasHwPhyCounters ? true : false;
8475 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8477 return REG_READ(ah, AR_QTXDP(q));
8480 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8483 REG_WRITE(ah, AR_QTXDP(q), txdp);
8488 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8490 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8492 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8497 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8501 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8504 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8510 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8514 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8516 for (wait = 1000; wait != 0; wait--) {
8517 if (ath9k_hw_numtxpending(ah, q) == 0)
8522 if (ath9k_hw_numtxpending(ah, q)) {
8525 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8526 "%s: Num of pending TX Frames %d on Q %d\n",
8527 __func__, ath9k_hw_numtxpending(ah, q), q);
8529 for (j = 0; j < 2; j++) {
8530 tsfLow = REG_READ(ah, AR_TSF_L32);
8531 REG_WRITE(ah, AR_QUIET2,
8532 SM(10, AR_QUIET2_QUIET_DUR));
8533 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8534 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8535 REG_SET_BIT(ah, AR_TIMER_MODE,
8538 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8542 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8543 "%s: TSF have moved while trying to set "
8544 "quiet time TSF: 0x%08x\n",
8548 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8551 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8555 while (ath9k_hw_numtxpending(ah, q)) {
8556 if ((--wait) == 0) {
8557 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8558 "%s: Failed to stop Tx DMA in 100 "
8559 "msec after killing last frame\n",
8566 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8569 REG_WRITE(ah, AR_Q_TXD, 0);