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.
25 static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
26 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
27 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
28 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
30 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
31 static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
34 static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
35 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
37 static const struct hal_percal_data iq_cal_multi_sample = {
41 ath9k_hw_iqcal_collect,
44 static const struct hal_percal_data iq_cal_single_sample = {
48 ath9k_hw_iqcal_collect,
51 static const struct hal_percal_data adc_gain_cal_multi_sample = {
55 ath9k_hw_adc_gaincal_collect,
56 ath9k_hw_adc_gaincal_calibrate
58 static const struct hal_percal_data adc_gain_cal_single_sample = {
62 ath9k_hw_adc_gaincal_collect,
63 ath9k_hw_adc_gaincal_calibrate
65 static const struct hal_percal_data adc_dc_cal_multi_sample = {
69 ath9k_hw_adc_dccal_collect,
70 ath9k_hw_adc_dccal_calibrate
72 static const struct hal_percal_data adc_dc_cal_single_sample = {
76 ath9k_hw_adc_dccal_collect,
77 ath9k_hw_adc_dccal_calibrate
79 static const struct hal_percal_data adc_init_dc_cal = {
83 ath9k_hw_adc_dccal_collect,
84 ath9k_hw_adc_dccal_calibrate
87 static const struct ath_hal ar5416hal = {
99 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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,
110 static struct ath9k_rate_table ar5416_11a_table = {
114 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
115 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
116 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
117 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
118 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
119 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
120 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
121 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
125 static struct ath9k_rate_table ar5416_11b_table = {
129 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
130 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
131 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
132 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
136 static struct ath9k_rate_table ar5416_11g_table = {
140 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
141 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
142 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
143 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
145 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
146 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
147 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
148 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
149 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
150 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
151 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
152 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
156 static struct ath9k_rate_table ar5416_11ng_table = {
160 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
161 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
162 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
163 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
165 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
166 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
167 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
168 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
169 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
170 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
171 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
172 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
173 {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
174 {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
175 {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
176 {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
177 {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
178 {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
179 {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
180 {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
181 {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
182 {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
183 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
184 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
185 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
186 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
187 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
188 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
192 static struct ath9k_rate_table ar5416_11na_table = {
196 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
197 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
198 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
199 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
200 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
201 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
202 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
203 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
204 {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
205 {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
206 {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
207 {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
208 {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
209 {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
210 {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
211 {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
212 {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
213 {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
214 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
215 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
216 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
217 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
218 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
219 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
223 static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
224 const struct ath9k_channel *chan)
226 if (IS_CHAN_CCK(chan))
227 return WIRELESS_MODE_11b;
229 return WIRELESS_MODE_11g;
230 return WIRELESS_MODE_11a;
233 static bool ath9k_hw_wait(struct ath_hal *ah,
240 for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
241 if ((REG_READ(ah, reg) & mask) == val)
244 udelay(AH_TIME_QUANTUM);
246 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
247 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
248 __func__, reg, REG_READ(ah, reg), mask, val);
252 static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
255 (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
257 if (!ath9k_hw_wait(ah,
258 AR_EEPROM_STATUS_DATA,
259 AR_EEPROM_STATUS_DATA_BUSY |
260 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
264 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
265 AR_EEPROM_STATUS_DATA_VAL);
270 static int ath9k_hw_flash_map(struct ath_hal *ah)
272 struct ath_hal_5416 *ahp = AH5416(ah);
274 ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
276 if (!ahp->ah_cal_mem) {
277 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
278 "%s: cannot remap eeprom region \n", __func__);
285 static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
288 struct ath_hal_5416 *ahp = AH5416(ah);
290 *data = ioread16(ahp->ah_cal_mem + off);
294 static void ath9k_hw_read_revisions(struct ath_hal *ah)
298 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
301 val = REG_READ(ah, AR_SREV);
304 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
306 ah->ah_macRev = MS(val, AR_SREV_REVISION2);
307 ah->ah_isPciExpress =
308 (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
311 if (!AR_SREV_9100(ah))
312 ah->ah_macVersion = MS(val, AR_SREV_VERSION);
314 ah->ah_macRev = val & AR_SREV_REVISION;
316 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
317 ah->ah_isPciExpress = true;
321 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
326 for (i = 0, retval = 0; i < n; i++) {
327 retval = (retval << 1) | (val & 1);
333 static void ath9k_hw_set_defaults(struct ath_hal *ah)
337 ah->ah_config.ath_hal_dma_beacon_response_time = 2;
338 ah->ah_config.ath_hal_sw_beacon_response_time = 10;
339 ah->ah_config.ath_hal_additional_swba_backoff = 0;
340 ah->ah_config.ath_hal_6mb_ack = 0x0;
341 ah->ah_config.ath_hal_cwmIgnoreExtCCA = 0;
342 ah->ah_config.ath_hal_pciePowerSaveEnable = 0;
343 ah->ah_config.ath_hal_pcieL1SKPEnable = 0;
344 ah->ah_config.ath_hal_pcieClockReq = 0;
345 ah->ah_config.ath_hal_pciePowerReset = 0x100;
346 ah->ah_config.ath_hal_pcieRestore = 0;
347 ah->ah_config.ath_hal_pcieWaen = 0;
348 ah->ah_config.ath_hal_analogShiftReg = 1;
349 ah->ah_config.ath_hal_htEnable = 1;
350 ah->ah_config.ath_hal_ofdmTrigLow = 200;
351 ah->ah_config.ath_hal_ofdmTrigHigh = 500;
352 ah->ah_config.ath_hal_cckTrigHigh = 200;
353 ah->ah_config.ath_hal_cckTrigLow = 100;
354 ah->ah_config.ath_hal_enableANI = 0;
355 ah->ah_config.ath_hal_noiseImmunityLvl = 4;
356 ah->ah_config.ath_hal_ofdmWeakSigDet = 1;
357 ah->ah_config.ath_hal_cckWeakSigThr = 0;
358 ah->ah_config.ath_hal_spurImmunityLvl = 2;
359 ah->ah_config.ath_hal_firStepLvl = 0;
360 ah->ah_config.ath_hal_rssiThrHigh = 40;
361 ah->ah_config.ath_hal_rssiThrLow = 7;
362 ah->ah_config.ath_hal_diversityControl = 0;
363 ah->ah_config.ath_hal_antennaSwitchSwap = 0;
365 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
366 ah->ah_config.ath_hal_spurChans[i][0] = AR_NO_SPUR;
367 ah->ah_config.ath_hal_spurChans[i][1] = AR_NO_SPUR;
370 ah->ah_config.ath_hal_intrMitigation = 0;
373 static inline void ath9k_hw_override_ini(struct ath_hal *ah,
374 struct ath9k_channel *chan)
376 if (!AR_SREV_5416_V20_OR_LATER(ah)
377 || AR_SREV_9280_10_OR_LATER(ah))
380 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
383 static inline void ath9k_hw_init_bb(struct ath_hal *ah,
384 struct ath9k_channel *chan)
388 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
389 if (IS_CHAN_CCK(chan))
390 synthDelay = (4 * synthDelay) / 22;
394 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
396 udelay(synthDelay + BASE_ACTIVATE_DELAY);
399 static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
400 enum ath9k_opmode opmode)
402 struct ath_hal_5416 *ahp = AH5416(ah);
404 ahp->ah_maskReg = AR_IMR_TXERR |
410 if (ahp->ah_intrMitigation)
411 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
413 ahp->ah_maskReg |= AR_IMR_RXOK;
415 ahp->ah_maskReg |= AR_IMR_TXOK;
417 if (opmode == ATH9K_M_HOSTAP)
418 ahp->ah_maskReg |= AR_IMR_MIB;
420 REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
421 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
423 if (!AR_SREV_9100(ah)) {
424 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
425 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
426 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
430 static inline void ath9k_hw_init_qos(struct ath_hal *ah)
432 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
433 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
435 REG_WRITE(ah, AR_QOS_NO_ACK,
436 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
437 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
438 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
440 REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
441 REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
442 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
443 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
444 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
447 static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
455 regVal = REG_READ(ah, reg) & ~mask;
456 regVal |= (val << shift) & mask;
458 REG_WRITE(ah, reg, regVal);
460 if (ah->ah_config.ath_hal_analogShiftReg)
466 static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
467 enum hal_freq_band freq_band)
469 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
470 struct modal_eep_header *pModal =
471 &(eep->modalHeader[HAL_FREQ_BAND_2GHZ == freq_band]);
472 struct base_eep_header *pBase = &eep->baseEepHeader;
477 if (pBase->version >= 0x0E0D)
481 return num_ant_config;
485 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
486 struct ath9k_channel *chan,
490 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
491 struct modal_eep_header *pModal =
492 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
493 struct base_eep_header *pBase = &eep->baseEepHeader;
497 *config = pModal->antCtrlCommon & 0xFFFF;
500 if (pBase->version >= 0x0E0D) {
501 if (pModal->useAnt1) {
503 ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
515 static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
519 if (ath9k_hw_use_flash(ah))
520 return ath9k_hw_flash_read(ah, off, data);
522 return ath9k_hw_eeprom_read(ah, off, data);
525 static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
527 struct ath_hal_5416 *ahp = AH5416(ah);
528 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
530 int addr, ar5416_eep_start_loc = 0;
532 if (!ath9k_hw_use_flash(ah)) {
533 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
534 "%s: Reading from EEPROM, not flash\n", __func__);
535 ar5416_eep_start_loc = 256;
537 if (AR_SREV_9100(ah))
538 ar5416_eep_start_loc = 256;
540 eep_data = (u16 *) eep;
542 addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
544 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
546 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
547 "%s: Unable to read eeprom region \n",
556 /* XXX: Clean me up, make me more legible */
558 ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
559 struct ath9k_channel *chan)
561 struct modal_eep_header *pModal;
562 int i, regChainOffset;
563 struct ath_hal_5416 *ahp = AH5416(ah);
564 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
568 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
570 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
572 ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
573 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
575 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
576 if (AR_SREV_9280(ah)) {
581 if (AR_SREV_5416_V20_OR_LATER(ah) &&
582 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
584 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
586 regChainOffset = i * 0x1000;
588 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
589 pModal->antCtrlChain[i]);
591 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
593 AR_PHY_TIMING_CTRL4(0) +
595 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
596 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
597 SM(pModal->iqCalICh[i],
598 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
599 SM(pModal->iqCalQCh[i],
600 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
602 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
603 if ((eep->baseEepHeader.version &
604 AR5416_EEP_VER_MINOR_MASK) >=
605 AR5416_EEP_MINOR_VER_3) {
606 txRxAttenLocal = pModal->txRxAttenCh[i];
607 if (AR_SREV_9280_10_OR_LATER(ah)) {
611 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
617 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
623 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
629 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
639 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
642 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
649 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
650 | SM(pModal->bswAtten[i],
651 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
654 if (AR_SREV_9280_10_OR_LATER(ah)) {
658 AR9280_PHY_RXGAIN_TXRX_ATTEN,
663 AR9280_PHY_RXGAIN_TXRX_MARGIN,
664 pModal->rxTxMarginCh[i]);
667 AR_PHY_RXGAIN + regChainOffset,
671 ~AR_PHY_RXGAIN_TXRX_ATTEN) |
673 AR_PHY_RXGAIN_TXRX_ATTEN));
680 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
681 SM(pModal->rxTxMarginCh[i],
682 AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
687 if (AR_SREV_9280_10_OR_LATER(ah)) {
688 if (IS_CHAN_2GHZ(chan)) {
689 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
691 AR_AN_RF2G1_CH0_OB_S,
693 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
695 AR_AN_RF2G1_CH0_DB_S,
697 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
699 AR_AN_RF2G1_CH1_OB_S,
701 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
703 AR_AN_RF2G1_CH1_DB_S,
706 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
708 AR_AN_RF5G1_CH0_OB5_S,
710 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
712 AR_AN_RF5G1_CH0_DB5_S,
714 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
716 AR_AN_RF5G1_CH1_OB5_S,
718 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
720 AR_AN_RF5G1_CH1_DB5_S,
723 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
724 AR_AN_TOP2_XPABIAS_LVL,
725 AR_AN_TOP2_XPABIAS_LVL_S,
727 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
728 AR_AN_TOP2_LOCALBIAS,
729 AR_AN_TOP2_LOCALBIAS_S,
731 DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
732 pModal->force_xpaon);
733 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
734 pModal->force_xpaon);
737 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
738 pModal->switchSettling);
739 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
740 pModal->adcDesiredSize);
742 if (!AR_SREV_9280_10_OR_LATER(ah))
743 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
744 AR_PHY_DESIRED_SZ_PGA,
745 pModal->pgaDesiredSize);
747 REG_WRITE(ah, AR_PHY_RF_CTL4,
748 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
749 | SM(pModal->txEndToXpaOff,
750 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
751 | SM(pModal->txFrameToXpaOn,
752 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
753 | SM(pModal->txFrameToXpaOn,
754 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
756 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
757 pModal->txEndToRxOn);
758 if (AR_SREV_9280_10_OR_LATER(ah)) {
759 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
761 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
762 AR_PHY_EXT_CCA0_THRESH62,
765 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
767 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
768 AR_PHY_EXT_CCA_THRESH62,
772 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
773 AR5416_EEP_MINOR_VER_2) {
774 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
775 AR_PHY_TX_END_DATA_START,
776 pModal->txFrameToDataStart);
777 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
778 pModal->txFrameToPaOn);
781 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
782 AR5416_EEP_MINOR_VER_3) {
783 if (IS_CHAN_HT40(chan))
784 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
785 AR_PHY_SETTLING_SWITCH,
786 pModal->swSettleHt40);
792 static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
797 struct ath_hal_5416 *ahp = AH5416(ah);
798 bool need_swap = false;
799 struct ar5416_eeprom *eep =
800 (struct ar5416_eeprom *) &ahp->ah_eeprom;
802 if (!ath9k_hw_use_flash(ah)) {
806 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
808 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
809 "%s: Reading Magic # failed\n", __func__);
812 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
815 if (magic != AR5416_EEPROM_MAGIC) {
816 magic2 = swab16(magic);
818 if (magic2 == AR5416_EEPROM_MAGIC) {
820 eepdata = (u16 *) (&ahp->ah_eeprom);
824 sizeof(struct ar5416_eeprom) /
825 sizeof(u16); addr++) {
828 temp = swab16(*eepdata);
832 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
833 "0x%04X ", *eepdata);
834 if (((addr + 1) % 6) == 0)
840 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
841 "Invalid EEPROM Magic. "
842 "endianness missmatch.\n");
847 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
848 need_swap ? "True" : "False");
851 el = swab16(ahp->ah_eeprom.baseEepHeader.length);
853 el = ahp->ah_eeprom.baseEepHeader.length;
855 if (el > sizeof(struct ar5416_eeprom))
856 el = sizeof(struct ar5416_eeprom) / sizeof(u16);
858 el = el / sizeof(u16);
860 eepdata = (u16 *) (&ahp->ah_eeprom);
862 for (i = 0; i < el; i++)
869 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
870 "EEPROM Endianness is not native.. Changing \n");
872 word = swab16(eep->baseEepHeader.length);
873 eep->baseEepHeader.length = word;
875 word = swab16(eep->baseEepHeader.checksum);
876 eep->baseEepHeader.checksum = word;
878 word = swab16(eep->baseEepHeader.version);
879 eep->baseEepHeader.version = word;
881 word = swab16(eep->baseEepHeader.regDmn[0]);
882 eep->baseEepHeader.regDmn[0] = word;
884 word = swab16(eep->baseEepHeader.regDmn[1]);
885 eep->baseEepHeader.regDmn[1] = word;
887 word = swab16(eep->baseEepHeader.rfSilent);
888 eep->baseEepHeader.rfSilent = word;
890 word = swab16(eep->baseEepHeader.blueToothOptions);
891 eep->baseEepHeader.blueToothOptions = word;
893 word = swab16(eep->baseEepHeader.deviceCap);
894 eep->baseEepHeader.deviceCap = word;
896 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
897 struct modal_eep_header *pModal =
898 &eep->modalHeader[j];
899 integer = swab32(pModal->antCtrlCommon);
900 pModal->antCtrlCommon = integer;
902 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
903 integer = swab32(pModal->antCtrlChain[i]);
904 pModal->antCtrlChain[i] = integer;
907 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
908 word = swab16(pModal->spurChans[i].spurChan);
909 pModal->spurChans[i].spurChan = word;
914 if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
915 ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
916 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
917 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
918 sum, ar5416_get_eep_ver(ahp));
925 static bool ath9k_hw_chip_test(struct ath_hal *ah)
927 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
929 u32 patternData[4] = { 0x55555555,
935 for (i = 0; i < 2; i++) {
936 u32 addr = regAddr[i];
939 regHold[i] = REG_READ(ah, addr);
940 for (j = 0; j < 0x100; j++) {
941 wrData = (j << 16) | j;
942 REG_WRITE(ah, addr, wrData);
943 rdData = REG_READ(ah, addr);
944 if (rdData != wrData) {
945 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
946 "%s: address test failed "
947 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
948 __func__, addr, wrData, rdData);
952 for (j = 0; j < 4; j++) {
953 wrData = patternData[j];
954 REG_WRITE(ah, addr, wrData);
955 rdData = REG_READ(ah, addr);
956 if (wrData != rdData) {
957 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
958 "%s: address test failed "
959 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
960 __func__, addr, wrData, rdData);
964 REG_WRITE(ah, regAddr[i], regHold[i]);
970 u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
972 u32 bits = REG_READ(ah, AR_RX_FILTER);
973 u32 phybits = REG_READ(ah, AR_PHY_ERR);
975 if (phybits & AR_PHY_ERR_RADAR)
976 bits |= ATH9K_RX_FILTER_PHYRADAR;
977 if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
978 bits |= ATH9K_RX_FILTER_PHYERR;
982 void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
986 REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
988 if (bits & ATH9K_RX_FILTER_PHYRADAR)
989 phybits |= AR_PHY_ERR_RADAR;
990 if (bits & ATH9K_RX_FILTER_PHYERR)
991 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
992 REG_WRITE(ah, AR_PHY_ERR, phybits);
995 REG_WRITE(ah, AR_RXCFG,
996 REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
998 REG_WRITE(ah, AR_RXCFG,
999 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
1002 bool ath9k_hw_setcapability(struct ath_hal *ah,
1003 enum hal_capability_type type,
1008 struct ath_hal_5416 *ahp = AH5416(ah);
1012 case HAL_CAP_TKIP_MIC:
1014 ahp->ah_staId1Defaults |=
1015 AR_STA_ID1_CRPT_MIC_ENABLE;
1017 ahp->ah_staId1Defaults &=
1018 ~AR_STA_ID1_CRPT_MIC_ENABLE;
1020 case HAL_CAP_DIVERSITY:
1021 v = REG_READ(ah, AR_PHY_CCK_DETECT);
1023 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1025 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1026 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
1028 case HAL_CAP_MCAST_KEYSRCH:
1030 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1032 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1034 case HAL_CAP_TSF_ADJUST:
1036 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
1038 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
1045 void ath9k_hw_dmaRegDump(struct ath_hal *ah)
1047 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
1048 int qcuOffset = 0, dcuOffset = 0;
1049 u32 *qcuBase = &val[0], *dcuBase = &val[4];
1052 REG_WRITE(ah, AR_MACMISC,
1053 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1054 (AR_MACMISC_MISC_OBS_BUS_1 <<
1055 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1057 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
1058 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
1060 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1062 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
1063 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
1066 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
1067 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1068 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1070 for (i = 0; i < ATH9K_NUM_QUEUES;
1071 i++, qcuOffset += 4, dcuOffset += 5) {
1082 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1083 "%2d %2x %1x %2x %2x\n",
1084 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1085 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
1087 val[2] & (0x7 << (i * 3)) >> (i * 3),
1088 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1091 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1092 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1093 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
1094 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
1095 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1096 "qcu_complete state: %2x dcu_complete state: %2x\n",
1097 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
1098 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1099 "dcu_arb state: %2x dcu_fp state: %2x\n",
1100 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
1101 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1102 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
1103 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
1104 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1105 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
1106 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
1107 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1108 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
1109 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
1111 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
1112 REG_READ(ah, AR_OBS_BUS_1));
1113 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1114 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
1117 u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1122 static u32 cycles, rx_clear, rx_frame, tx_frame;
1125 u32 rc = REG_READ(ah, AR_RCCNT);
1126 u32 rf = REG_READ(ah, AR_RFCNT);
1127 u32 tf = REG_READ(ah, AR_TFCNT);
1128 u32 cc = REG_READ(ah, AR_CCCNT);
1130 if (cycles == 0 || cycles > cc) {
1131 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1132 "%s: cycle counter wrap. ExtBusy = 0\n",
1136 u32 cc_d = cc - cycles;
1137 u32 rc_d = rc - rx_clear;
1138 u32 rf_d = rf - rx_frame;
1139 u32 tf_d = tf - tx_frame;
1142 *rxc_pcnt = rc_d * 100 / cc_d;
1143 *rxf_pcnt = rf_d * 100 / cc_d;
1144 *txf_pcnt = tf_d * 100 / cc_d;
1158 void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
1162 if (mode == ATH9K_HT_MACMODE_2040 &&
1163 !ah->ah_config.ath_hal_cwmIgnoreExtCCA)
1164 macmode = AR_2040_JOINED_RX_CLEAR;
1168 REG_WRITE(ah, AR_2040_MODE, macmode);
1171 static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
1173 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1177 static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1178 struct ath_softc *sc,
1182 static const u8 defbssidmask[ETH_ALEN] =
1183 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1184 struct ath_hal_5416 *ahp;
1187 ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
1189 DPRINTF(sc, ATH_DBG_FATAL,
1190 "%s: cannot allocate memory for state block\n",
1198 memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1203 ah->ah_devid = devid;
1204 ah->ah_subvendorid = 0;
1207 if ((devid == AR5416_AR9100_DEVID))
1208 ah->ah_macVersion = AR_SREV_VERSION_9100;
1209 if (!AR_SREV_9100(ah))
1210 ah->ah_flags = AH_USE_EEPROM;
1212 ah->ah_powerLimit = MAX_RATE_POWER;
1213 ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
1215 ahp->ah_atimWindow = 0;
1216 ahp->ah_diversityControl = ah->ah_config.ath_hal_diversityControl;
1217 ahp->ah_antennaSwitchSwap =
1218 ah->ah_config.ath_hal_antennaSwitchSwap;
1220 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
1221 ahp->ah_beaconInterval = 100;
1222 ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
1223 ahp->ah_slottime = (u32) -1;
1224 ahp->ah_acktimeout = (u32) -1;
1225 ahp->ah_ctstimeout = (u32) -1;
1226 ahp->ah_globaltxtimeout = (u32) -1;
1227 memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
1229 ahp->ah_gBeaconRate = 0;
1234 static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
1238 if (ath9k_hw_use_flash(ah))
1239 ath9k_hw_flash_map(ah);
1241 if (!ath9k_hw_fill_eeprom(ah))
1244 status = ath9k_hw_check_eeprom(ah);
1249 u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1250 enum eeprom_param param)
1252 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
1253 struct modal_eep_header *pModal = eep->modalHeader;
1254 struct base_eep_header *pBase = &eep->baseEepHeader;
1257 case EEP_NFTHRESH_5:
1258 return -pModal[0].noiseFloorThreshCh[0];
1259 case EEP_NFTHRESH_2:
1260 return -pModal[1].noiseFloorThreshCh[0];
1261 case AR_EEPROM_MAC(0):
1262 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1263 case AR_EEPROM_MAC(1):
1264 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1265 case AR_EEPROM_MAC(2):
1266 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1268 return pBase->regDmn[0];
1270 return pBase->regDmn[1];
1272 return pBase->deviceCap;
1274 return pBase->opCapFlags;
1276 return pBase->rfSilent;
1278 return pModal[0].ob;
1280 return pModal[0].db;
1282 return pModal[1].ob;
1284 return pModal[1].db;
1286 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
1288 return pBase->txMask;
1290 return pBase->rxMask;
1296 static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1301 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
1302 for (i = 0; i < 8; i++)
1303 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
1304 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
1305 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
1306 return ath9k_hw_reverse_bits(val, 8);
1309 static inline int ath9k_hw_init_macaddr(struct ath_hal *ah)
1314 struct ath_hal_5416 *ahp = AH5416(ah);
1315 DECLARE_MAC_BUF(mac);
1318 for (i = 0; i < 3; i++) {
1319 eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
1321 ahp->ah_macaddr[2 * i] = eeval >> 8;
1322 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
1324 if (sum == 0 || sum == 0xffff * 3) {
1325 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1326 "%s: mac address read failed: %s\n", __func__,
1327 print_mac(mac, ahp->ah_macaddr));
1328 return -EADDRNOTAVAIL;
1334 static inline int16_t ath9k_hw_interpolate(u16 target,
1338 int16_t targetRight)
1342 if (srcRight == srcLeft) {
1345 rv = (int16_t) (((target - srcLeft) * targetRight +
1346 (srcRight - target) * targetLeft) /
1347 (srcRight - srcLeft));
1352 static inline u16 ath9k_hw_fbin2freq(u8 fbin,
1356 if (fbin == AR5416_BCHAN_UNUSED)
1359 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1362 static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1366 struct ath_hal_5416 *ahp = AH5416(ah);
1367 struct ar5416_eeprom *eep =
1368 (struct ar5416_eeprom *) &ahp->ah_eeprom;
1369 u16 spur_val = AR_NO_SPUR;
1371 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1372 "Getting spur idx %d is2Ghz. %d val %x\n",
1373 i, is2GHz, ah->ah_config.ath_hal_spurChans[i][is2GHz]);
1375 switch (ah->ah_config.ath_hal_spurMode) {
1378 case SPUR_ENABLE_IOCTL:
1379 spur_val = ah->ah_config.ath_hal_spurChans[i][is2GHz];
1380 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1381 "Getting spur val from new loc. %d\n", spur_val);
1383 case SPUR_ENABLE_EEPROM:
1384 spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
1391 static inline int ath9k_hw_rfattach(struct ath_hal *ah)
1393 bool rfStatus = false;
1396 rfStatus = ath9k_hw_init_rf(ah, &ecode);
1398 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1399 "%s: RF setup failed, status %u\n", __func__,
1407 static int ath9k_hw_rf_claim(struct ath_hal *ah)
1411 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1413 val = ath9k_hw_get_radiorev(ah);
1414 switch (val & AR_RADIO_SREV_MAJOR) {
1416 val = AR_RAD5133_SREV_MAJOR;
1418 case AR_RAD5133_SREV_MAJOR:
1419 case AR_RAD5122_SREV_MAJOR:
1420 case AR_RAD2133_SREV_MAJOR:
1421 case AR_RAD2122_SREV_MAJOR:
1424 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1425 "%s: 5G Radio Chip Rev 0x%02X is not "
1426 "supported by this driver\n",
1427 __func__, ah->ah_analog5GhzRev);
1431 ah->ah_analog5GhzRev = val;
1436 static inline void ath9k_hw_init_pll(struct ath_hal *ah,
1437 struct ath9k_channel *chan)
1441 if (AR_SREV_9100(ah)) {
1442 if (chan && IS_CHAN_5GHZ(chan))
1447 if (AR_SREV_9280_10_OR_LATER(ah)) {
1448 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1450 if (chan && IS_CHAN_HALF_RATE(chan))
1451 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1452 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1453 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1455 if (chan && IS_CHAN_5GHZ(chan)) {
1456 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1459 if (AR_SREV_9280_20(ah)) {
1460 if (((chan->channel % 20) == 0)
1461 || ((chan->channel % 10) == 0))
1467 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1470 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1472 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1474 if (chan && IS_CHAN_HALF_RATE(chan))
1475 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1476 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1477 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1479 if (chan && IS_CHAN_5GHZ(chan))
1480 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1482 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1484 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1486 if (chan && IS_CHAN_HALF_RATE(chan))
1487 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1488 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1489 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1491 if (chan && IS_CHAN_5GHZ(chan))
1492 pll |= SM(0xa, AR_RTC_PLL_DIV);
1494 pll |= SM(0xb, AR_RTC_PLL_DIV);
1497 REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
1499 udelay(RTC_PLL_SETTLE_DELAY);
1501 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1504 static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1505 enum ath9k_ht_macmode macmode)
1508 struct ath_hal_5416 *ahp = AH5416(ah);
1510 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1511 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
1513 if (IS_CHAN_HT40(chan)) {
1514 phymode |= AR_PHY_FC_DYN2040_EN;
1516 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1517 (chan->chanmode == CHANNEL_G_HT40PLUS))
1518 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1520 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1521 phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1523 REG_WRITE(ah, AR_PHY_TURBO, phymode);
1525 ath9k_hw_set11nmac2040(ah, macmode);
1527 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1528 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1531 static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1535 val = REG_READ(ah, AR_STA_ID1);
1536 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1538 case ATH9K_M_HOSTAP:
1539 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
1540 | AR_STA_ID1_KSRCH_MODE);
1541 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1544 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1545 | AR_STA_ID1_KSRCH_MODE);
1546 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1549 case ATH9K_M_MONITOR:
1550 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1556 ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1563 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1564 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1566 if (!AR_SREV_9280_10_OR_LATER(ah))
1567 rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
1570 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1571 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1573 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1576 static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1581 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1582 AR_RTC_FORCE_WAKE_ON_INT);
1584 if (AR_SREV_9100(ah)) {
1585 rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1586 AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1588 tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1590 (AR_INTR_SYNC_LOCAL_TIMEOUT |
1591 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1592 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1593 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
1595 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1598 rst_flags = AR_RTC_RC_MAC_WARM;
1599 if (type == ATH9K_RESET_COLD)
1600 rst_flags |= AR_RTC_RC_MAC_COLD;
1603 REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
1606 REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
1607 if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
1608 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1609 "%s: RTC stuck in MAC reset\n",
1614 if (!AR_SREV_9100(ah))
1615 REG_WRITE(ah, AR_RC, 0);
1617 ath9k_hw_init_pll(ah, NULL);
1619 if (AR_SREV_9100(ah))
1625 static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1627 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1628 AR_RTC_FORCE_WAKE_ON_INT);
1630 REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
1631 REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
1633 if (!ath9k_hw_wait(ah,
1636 AR_RTC_STATUS_ON)) {
1637 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
1642 ath9k_hw_read_revisions(ah);
1644 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1647 static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1650 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1651 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1654 case ATH9K_RESET_POWER_ON:
1655 return ath9k_hw_set_reset_power_on(ah);
1657 case ATH9K_RESET_WARM:
1658 case ATH9K_RESET_COLD:
1659 return ath9k_hw_set_reset(ah, type);
1667 struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1668 struct ath9k_channel *chan)
1670 if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
1671 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1672 "%s: invalid channel %u/0x%x; not marked as "
1673 "2GHz or 5GHz\n", __func__, chan->channel,
1674 chan->channelFlags);
1678 if (!IS_CHAN_OFDM(chan) &&
1679 !IS_CHAN_CCK(chan) &&
1680 !IS_CHAN_HT20(chan) &&
1681 !IS_CHAN_HT40(chan)) {
1682 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1683 "%s: invalid channel %u/0x%x; not marked as "
1684 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1685 __func__, chan->channel, chan->channelFlags);
1689 return ath9k_regd_check_channel(ah, chan);
1693 ath9k_hw_get_lower_upper_index(u8 target,
1701 if (target <= pList[0]) {
1702 *indexL = *indexR = 0;
1705 if (target >= pList[listSize - 1]) {
1706 *indexL = *indexR = (u16) (listSize - 1);
1710 for (i = 0; i < listSize - 1; i++) {
1711 if (pList[i] == target) {
1712 *indexL = *indexR = i;
1715 if (target < pList[i + 1]) {
1717 *indexR = (u16) (i + 1);
1724 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
1727 int16_t sort[ATH9K_NF_CAL_HIST_MAX];
1730 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
1731 sort[i] = nfCalBuffer[i];
1733 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
1734 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
1735 if (sort[j] > sort[j - 1]) {
1737 sort[j] = sort[j - 1];
1738 sort[j - 1] = nfval;
1742 nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
1747 static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
1752 for (i = 0; i < NUM_NF_READINGS; i++) {
1753 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
1755 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
1758 if (h[i].invalidNFcount > 0) {
1759 if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
1760 || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
1761 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
1763 h[i].invalidNFcount--;
1764 h[i].privNF = nfarray[i];
1768 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
1774 static void ar5416GetNoiseFloor(struct ath_hal *ah,
1775 int16_t nfarray[NUM_NF_READINGS])
1779 if (AR_SREV_9280_10_OR_LATER(ah))
1780 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
1782 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1785 nf = 0 - ((nf ^ 0x1ff) + 1);
1786 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1787 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1790 if (AR_SREV_9280_10_OR_LATER(ah))
1791 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1792 AR9280_PHY_CH1_MINCCA_PWR);
1794 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1795 AR_PHY_CH1_MINCCA_PWR);
1798 nf = 0 - ((nf ^ 0x1ff) + 1);
1799 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1800 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1803 if (!AR_SREV_9280(ah)) {
1804 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
1805 AR_PHY_CH2_MINCCA_PWR);
1807 nf = 0 - ((nf ^ 0x1ff) + 1);
1808 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1809 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1813 if (AR_SREV_9280_10_OR_LATER(ah))
1814 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1815 AR9280_PHY_EXT_MINCCA_PWR);
1817 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1818 AR_PHY_EXT_MINCCA_PWR);
1821 nf = 0 - ((nf ^ 0x1ff) + 1);
1822 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1823 "NF calibrated [ext] [chain 0] is %d\n", nf);
1826 if (AR_SREV_9280_10_OR_LATER(ah))
1827 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1828 AR9280_PHY_CH1_EXT_MINCCA_PWR);
1830 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1831 AR_PHY_CH1_EXT_MINCCA_PWR);
1834 nf = 0 - ((nf ^ 0x1ff) + 1);
1835 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1836 "NF calibrated [ext] [chain 1] is %d\n", nf);
1839 if (!AR_SREV_9280(ah)) {
1840 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
1841 AR_PHY_CH2_EXT_MINCCA_PWR);
1843 nf = 0 - ((nf ^ 0x1ff) + 1);
1844 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1845 "NF calibrated [ext] [chain 2] is %d\n", nf);
1851 getNoiseFloorThresh(struct ath_hal *ah,
1852 const struct ath9k_channel *chan,
1855 struct ath_hal_5416 *ahp = AH5416(ah);
1857 switch (chan->chanmode) {
1859 case CHANNEL_A_HT20:
1860 case CHANNEL_A_HT40PLUS:
1861 case CHANNEL_A_HT40MINUS:
1862 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
1866 case CHANNEL_G_HT20:
1867 case CHANNEL_G_HT40PLUS:
1868 case CHANNEL_G_HT40MINUS:
1869 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
1872 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1873 "%s: invalid channel flags 0x%x\n", __func__,
1874 chan->channelFlags);
1880 static void ath9k_hw_start_nfcal(struct ath_hal *ah)
1882 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1883 AR_PHY_AGC_CONTROL_ENABLE_NF);
1884 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1885 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1886 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1890 ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
1892 struct ath9k_nfcal_hist *h;
1895 const u32 ar5416_cca_regs[6] = {
1905 if (AR_SREV_9280(ah))
1910 #ifdef ATH_NF_PER_CHAN
1911 h = chan->nfCalHist;
1916 for (i = 0; i < NUM_NF_READINGS; i++) {
1917 if (chainmask & (1 << i)) {
1918 val = REG_READ(ah, ar5416_cca_regs[i]);
1920 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1921 REG_WRITE(ah, ar5416_cca_regs[i], val);
1925 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1926 AR_PHY_AGC_CONTROL_ENABLE_NF);
1927 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1928 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1929 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1931 for (j = 0; j < 1000; j++) {
1932 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1933 AR_PHY_AGC_CONTROL_NF) == 0)
1938 for (i = 0; i < NUM_NF_READINGS; i++) {
1939 if (chainmask & (1 << i)) {
1940 val = REG_READ(ah, ar5416_cca_regs[i]);
1942 val |= (((u32) (-50) << 1) & 0x1ff);
1943 REG_WRITE(ah, ar5416_cca_regs[i], val);
1948 static int16_t ath9k_hw_getnf(struct ath_hal *ah,
1949 struct ath9k_channel *chan)
1951 int16_t nf, nfThresh;
1952 int16_t nfarray[NUM_NF_READINGS] = { 0 };
1953 struct ath9k_nfcal_hist *h;
1956 if (AR_SREV_9280(ah))
1961 chan->channelFlags &= (~CHANNEL_CW_INT);
1962 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1963 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1964 "%s: NF did not complete in calibration window\n",
1967 chan->rawNoiseFloor = nf;
1968 return chan->rawNoiseFloor;
1970 ar5416GetNoiseFloor(ah, nfarray);
1972 if (getNoiseFloorThresh(ah, chan, &nfThresh)
1974 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1975 "%s: noise floor failed detected; "
1976 "detected %d, threshold %d\n", __func__,
1978 chan->channelFlags |= CHANNEL_CW_INT;
1982 #ifdef ATH_NF_PER_CHAN
1983 h = chan->nfCalHist;
1988 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
1989 chan->rawNoiseFloor = h[0].privNF;
1991 return chan->rawNoiseFloor;
1994 static void ath9k_hw_update_mibstats(struct ath_hal *ah,
1995 struct ath9k_mib_stats *stats)
1997 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
1998 stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
1999 stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
2000 stats->rts_good += REG_READ(ah, AR_RTS_OK);
2001 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
2004 static void ath9k_enable_mib_counters(struct ath_hal *ah)
2006 struct ath_hal_5416 *ahp = AH5416(ah);
2008 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
2010 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2012 REG_WRITE(ah, AR_FILT_OFDM, 0);
2013 REG_WRITE(ah, AR_FILT_CCK, 0);
2014 REG_WRITE(ah, AR_MIBC,
2015 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
2017 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2018 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2021 static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
2023 struct ath_hal_5416 *ahp = AH5416(ah);
2025 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
2027 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
2029 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2031 REG_WRITE(ah, AR_FILT_OFDM, 0);
2032 REG_WRITE(ah, AR_FILT_CCK, 0);
2035 static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
2036 struct ath9k_channel *chan)
2038 struct ath_hal_5416 *ahp = AH5416(ah);
2041 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2042 if (ahp->ah_ani[i].c.channel == chan->channel)
2044 if (ahp->ah_ani[i].c.channel == 0) {
2045 ahp->ah_ani[i].c.channel = chan->channel;
2046 ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
2051 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2052 "No more channel states left. Using channel 0\n");
2056 static void ath9k_hw_ani_attach(struct ath_hal *ah)
2058 struct ath_hal_5416 *ahp = AH5416(ah);
2061 ahp->ah_hasHwPhyCounters = 1;
2063 memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
2064 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2065 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
2066 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
2067 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
2068 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
2069 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
2070 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
2071 ahp->ah_ani[i].ofdmWeakSigDetectOff =
2072 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
2073 ahp->ah_ani[i].cckWeakSigThreshold =
2074 ATH9K_ANI_CCK_WEAK_SIG_THR;
2075 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
2076 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
2077 if (ahp->ah_hasHwPhyCounters) {
2078 ahp->ah_ani[i].ofdmPhyErrBase =
2079 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
2080 ahp->ah_ani[i].cckPhyErrBase =
2081 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
2084 if (ahp->ah_hasHwPhyCounters) {
2085 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2086 "Setting OfdmErrBase = 0x%08x\n",
2087 ahp->ah_ani[0].ofdmPhyErrBase);
2088 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
2089 ahp->ah_ani[0].cckPhyErrBase);
2091 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
2092 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
2093 ath9k_enable_mib_counters(ah);
2095 ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
2096 if (ah->ah_config.ath_hal_enableANI)
2097 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2100 static inline void ath9k_hw_ani_setup(struct ath_hal *ah)
2102 struct ath_hal_5416 *ahp = AH5416(ah);
2105 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
2106 const int coarseHigh[] = { -14, -14, -14, -14, -12 };
2107 const int coarseLow[] = { -64, -64, -64, -64, -70 };
2108 const int firpwr[] = { -78, -78, -78, -78, -80 };
2110 for (i = 0; i < 5; i++) {
2111 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
2112 ahp->ah_coarseHigh[i] = coarseHigh[i];
2113 ahp->ah_coarseLow[i] = coarseLow[i];
2114 ahp->ah_firpwr[i] = firpwr[i];
2118 static void ath9k_hw_ani_detach(struct ath_hal *ah)
2120 struct ath_hal_5416 *ahp = AH5416(ah);
2122 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
2123 if (ahp->ah_hasHwPhyCounters) {
2124 ath9k_hw_disable_mib_counters(ah);
2125 REG_WRITE(ah, AR_PHY_ERR_1, 0);
2126 REG_WRITE(ah, AR_PHY_ERR_2, 0);
2131 static bool ath9k_hw_ani_control(struct ath_hal *ah,
2132 enum ath9k_ani_cmd cmd, int param)
2134 struct ath_hal_5416 *ahp = AH5416(ah);
2135 struct ar5416AniState *aniState = ahp->ah_curani;
2137 switch (cmd & ahp->ah_ani_function) {
2138 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
2141 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
2142 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2143 "%s: level out of range (%u > %u)\n",
2145 (unsigned) ARRAY_SIZE(ahp->
2146 ah_totalSizeDesired));
2150 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2151 AR_PHY_DESIRED_SZ_TOT_DES,
2152 ahp->ah_totalSizeDesired[level]);
2153 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2154 AR_PHY_AGC_CTL1_COARSE_LOW,
2155 ahp->ah_coarseLow[level]);
2156 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2157 AR_PHY_AGC_CTL1_COARSE_HIGH,
2158 ahp->ah_coarseHigh[level]);
2159 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2160 AR_PHY_FIND_SIG_FIRPWR,
2161 ahp->ah_firpwr[level]);
2163 if (level > aniState->noiseImmunityLevel)
2164 ahp->ah_stats.ast_ani_niup++;
2165 else if (level < aniState->noiseImmunityLevel)
2166 ahp->ah_stats.ast_ani_nidown++;
2167 aniState->noiseImmunityLevel = level;
2170 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
2171 const int m1ThreshLow[] = { 127, 50 };
2172 const int m2ThreshLow[] = { 127, 40 };
2173 const int m1Thresh[] = { 127, 0x4d };
2174 const int m2Thresh[] = { 127, 0x40 };
2175 const int m2CountThr[] = { 31, 16 };
2176 const int m2CountThrLow[] = { 63, 48 };
2177 u32 on = param ? 1 : 0;
2179 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2180 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
2182 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2183 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
2185 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2186 AR_PHY_SFCORR_M1_THRESH,
2188 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2189 AR_PHY_SFCORR_M2_THRESH,
2191 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2192 AR_PHY_SFCORR_M2COUNT_THR,
2194 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2195 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
2198 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2199 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
2201 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2202 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
2204 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2205 AR_PHY_SFCORR_EXT_M1_THRESH,
2207 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2208 AR_PHY_SFCORR_EXT_M2_THRESH,
2212 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
2213 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2215 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
2216 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2218 if (!on != aniState->ofdmWeakSigDetectOff) {
2220 ahp->ah_stats.ast_ani_ofdmon++;
2222 ahp->ah_stats.ast_ani_ofdmoff++;
2223 aniState->ofdmWeakSigDetectOff = !on;
2227 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
2228 const int weakSigThrCck[] = { 8, 6 };
2229 u32 high = param ? 1 : 0;
2231 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
2232 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
2233 weakSigThrCck[high]);
2234 if (high != aniState->cckWeakSigThreshold) {
2236 ahp->ah_stats.ast_ani_cckhigh++;
2238 ahp->ah_stats.ast_ani_ccklow++;
2239 aniState->cckWeakSigThreshold = high;
2243 case ATH9K_ANI_FIRSTEP_LEVEL:{
2244 const int firstep[] = { 0, 4, 8 };
2247 if (level >= ARRAY_SIZE(firstep)) {
2248 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2249 "%s: level out of range (%u > %u)\n",
2251 (unsigned) ARRAY_SIZE(firstep));
2254 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2255 AR_PHY_FIND_SIG_FIRSTEP,
2257 if (level > aniState->firstepLevel)
2258 ahp->ah_stats.ast_ani_stepup++;
2259 else if (level < aniState->firstepLevel)
2260 ahp->ah_stats.ast_ani_stepdown++;
2261 aniState->firstepLevel = level;
2264 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
2265 const int cycpwrThr1[] =
2266 { 2, 4, 6, 8, 10, 12, 14, 16 };
2269 if (level >= ARRAY_SIZE(cycpwrThr1)) {
2270 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2271 "%s: level out of range (%u > %u)\n",
2274 ARRAY_SIZE(cycpwrThr1));
2277 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
2278 AR_PHY_TIMING5_CYCPWR_THR1,
2280 if (level > aniState->spurImmunityLevel)
2281 ahp->ah_stats.ast_ani_spurup++;
2282 else if (level < aniState->spurImmunityLevel)
2283 ahp->ah_stats.ast_ani_spurdown++;
2284 aniState->spurImmunityLevel = level;
2287 case ATH9K_ANI_PRESENT:
2290 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2291 "%s: invalid cmd %u\n", __func__, cmd);
2295 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
2296 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2297 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2298 "ofdmWeakSigDetectOff=%d\n",
2299 aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
2300 !aniState->ofdmWeakSigDetectOff);
2301 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2302 "cckWeakSigThreshold=%d, "
2303 "firstepLevel=%d, listenTime=%d\n",
2304 aniState->cckWeakSigThreshold, aniState->firstepLevel,
2305 aniState->listenTime);
2306 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2307 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2308 aniState->cycleCount, aniState->ofdmPhyErrCount,
2309 aniState->cckPhyErrCount);
2313 static void ath9k_ani_restart(struct ath_hal *ah)
2315 struct ath_hal_5416 *ahp = AH5416(ah);
2316 struct ar5416AniState *aniState;
2321 aniState = ahp->ah_curani;
2323 aniState->listenTime = 0;
2324 if (ahp->ah_hasHwPhyCounters) {
2325 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
2326 aniState->ofdmPhyErrBase = 0;
2327 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2328 "OFDM Trigger is too high for hw counters\n");
2330 aniState->ofdmPhyErrBase =
2331 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
2333 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
2334 aniState->cckPhyErrBase = 0;
2335 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2336 "CCK Trigger is too high for hw counters\n");
2338 aniState->cckPhyErrBase =
2339 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
2341 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2342 "%s: Writing ofdmbase=%u cckbase=%u\n",
2343 __func__, aniState->ofdmPhyErrBase,
2344 aniState->cckPhyErrBase);
2345 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
2346 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
2347 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2348 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2350 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2352 aniState->ofdmPhyErrCount = 0;
2353 aniState->cckPhyErrCount = 0;
2356 static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2358 struct ath_hal_5416 *ahp = AH5416(ah);
2359 struct ath9k_channel *chan = ah->ah_curchan;
2360 struct ar5416AniState *aniState;
2361 enum wireless_mode mode;
2367 aniState = ahp->ah_curani;
2369 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2370 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2371 aniState->noiseImmunityLevel + 1)) {
2376 if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
2377 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2378 aniState->spurImmunityLevel + 1)) {
2383 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2384 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2385 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2386 aniState->firstepLevel + 1);
2390 rssi = BEACON_RSSI(ahp);
2391 if (rssi > aniState->rssiThrHigh) {
2392 if (!aniState->ofdmWeakSigDetectOff) {
2393 if (ath9k_hw_ani_control(ah,
2394 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2396 ath9k_hw_ani_control(ah,
2397 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2402 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2403 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2404 aniState->firstepLevel + 1);
2407 } else if (rssi > aniState->rssiThrLow) {
2408 if (aniState->ofdmWeakSigDetectOff)
2409 ath9k_hw_ani_control(ah,
2410 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2412 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2413 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2414 aniState->firstepLevel + 1);
2417 mode = ath9k_hw_chan2wmode(ah, chan);
2418 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2419 if (!aniState->ofdmWeakSigDetectOff)
2420 ath9k_hw_ani_control(ah,
2421 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2423 if (aniState->firstepLevel > 0)
2424 ath9k_hw_ani_control(ah,
2425 ATH9K_ANI_FIRSTEP_LEVEL,
2432 static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2434 struct ath_hal_5416 *ahp = AH5416(ah);
2435 struct ath9k_channel *chan = ah->ah_curchan;
2436 struct ar5416AniState *aniState;
2437 enum wireless_mode mode;
2443 aniState = ahp->ah_curani;
2444 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2445 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2446 aniState->noiseImmunityLevel + 1)) {
2450 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2451 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2452 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2453 aniState->firstepLevel + 1);
2457 rssi = BEACON_RSSI(ahp);
2458 if (rssi > aniState->rssiThrLow) {
2459 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2460 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2461 aniState->firstepLevel + 1);
2463 mode = ath9k_hw_chan2wmode(ah, chan);
2464 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2465 if (aniState->firstepLevel > 0)
2466 ath9k_hw_ani_control(ah,
2467 ATH9K_ANI_FIRSTEP_LEVEL,
2473 static void ath9k_ani_reset(struct ath_hal *ah)
2475 struct ath_hal_5416 *ahp = AH5416(ah);
2476 struct ar5416AniState *aniState;
2477 struct ath9k_channel *chan = ah->ah_curchan;
2483 index = ath9k_hw_get_ani_channel_idx(ah, chan);
2484 aniState = &ahp->ah_ani[index];
2485 ahp->ah_curani = aniState;
2487 if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
2488 && ah->ah_opmode != ATH9K_M_IBSS) {
2489 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2490 "%s: Reset ANI state opmode %u\n", __func__,
2492 ahp->ah_stats.ast_ani_reset++;
2493 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
2494 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
2495 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
2496 ath9k_hw_ani_control(ah,
2497 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2498 !ATH9K_ANI_USE_OFDM_WEAK_SIG);
2499 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2500 ATH9K_ANI_CCK_WEAK_SIG_THR);
2501 ath9k_hw_setrxfilter(ah,
2502 ath9k_hw_getrxfilter(ah) |
2503 ATH9K_RX_FILTER_PHYERR);
2504 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2505 ahp->ah_curani->ofdmTrigHigh =
2506 ah->ah_config.ath_hal_ofdmTrigHigh;
2507 ahp->ah_curani->ofdmTrigLow =
2508 ah->ah_config.ath_hal_ofdmTrigLow;
2509 ahp->ah_curani->cckTrigHigh =
2510 ah->ah_config.ath_hal_cckTrigHigh;
2511 ahp->ah_curani->cckTrigLow =
2512 ah->ah_config.ath_hal_cckTrigLow;
2514 ath9k_ani_restart(ah);
2518 if (aniState->noiseImmunityLevel != 0)
2519 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2520 aniState->noiseImmunityLevel);
2521 if (aniState->spurImmunityLevel != 0)
2522 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2523 aniState->spurImmunityLevel);
2524 if (aniState->ofdmWeakSigDetectOff)
2525 ath9k_hw_ani_control(ah,
2526 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2527 !aniState->ofdmWeakSigDetectOff);
2528 if (aniState->cckWeakSigThreshold)
2529 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2530 aniState->cckWeakSigThreshold);
2531 if (aniState->firstepLevel != 0)
2532 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2533 aniState->firstepLevel);
2534 if (ahp->ah_hasHwPhyCounters) {
2535 ath9k_hw_setrxfilter(ah,
2536 ath9k_hw_getrxfilter(ah) &
2537 ~ATH9K_RX_FILTER_PHYERR);
2538 ath9k_ani_restart(ah);
2539 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2540 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2543 ath9k_ani_restart(ah);
2544 ath9k_hw_setrxfilter(ah,
2545 ath9k_hw_getrxfilter(ah) |
2546 ATH9K_RX_FILTER_PHYERR);
2550 void ath9k_hw_procmibevent(struct ath_hal *ah,
2551 const struct ath9k_node_stats *stats)
2553 struct ath_hal_5416 *ahp = AH5416(ah);
2554 u32 phyCnt1, phyCnt2;
2556 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
2558 REG_WRITE(ah, AR_FILT_OFDM, 0);
2559 REG_WRITE(ah, AR_FILT_CCK, 0);
2560 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
2561 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
2563 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2564 ahp->ah_stats.ast_nodestats = *stats;
2569 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2570 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2571 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
2572 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
2573 struct ar5416AniState *aniState = ahp->ah_curani;
2574 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2576 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2577 ahp->ah_stats.ast_ani_ofdmerrs +=
2578 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2579 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2581 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2582 ahp->ah_stats.ast_ani_cckerrs +=
2583 cckPhyErrCnt - aniState->cckPhyErrCount;
2584 aniState->cckPhyErrCount = cckPhyErrCnt;
2586 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
2587 ath9k_hw_ani_ofdm_err_trigger(ah);
2588 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
2589 ath9k_hw_ani_cck_err_trigger(ah);
2591 ath9k_ani_restart(ah);
2595 static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
2597 struct ath_hal_5416 *ahp = AH5416(ah);
2598 struct ar5416AniState *aniState;
2601 aniState = ahp->ah_curani;
2603 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2604 if (aniState->firstepLevel > 0) {
2605 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2606 aniState->firstepLevel - 1)) {
2611 rssi = BEACON_RSSI(ahp);
2612 if (rssi > aniState->rssiThrHigh) {
2614 } else if (rssi > aniState->rssiThrLow) {
2615 if (aniState->ofdmWeakSigDetectOff) {
2616 if (ath9k_hw_ani_control(ah,
2617 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2623 if (aniState->firstepLevel > 0) {
2624 if (ath9k_hw_ani_control
2625 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2626 aniState->firstepLevel - 1) ==
2632 if (aniState->firstepLevel > 0) {
2633 if (ath9k_hw_ani_control
2634 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2635 aniState->firstepLevel - 1) ==
2643 if (aniState->spurImmunityLevel > 0) {
2644 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2645 aniState->spurImmunityLevel - 1)) {
2650 if (aniState->noiseImmunityLevel > 0) {
2651 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2652 aniState->noiseImmunityLevel - 1);
2657 static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
2659 struct ath_hal_5416 *ahp = AH5416(ah);
2660 struct ar5416AniState *aniState;
2661 u32 txFrameCount, rxFrameCount, cycleCount;
2664 txFrameCount = REG_READ(ah, AR_TFCNT);
2665 rxFrameCount = REG_READ(ah, AR_RFCNT);
2666 cycleCount = REG_READ(ah, AR_CCCNT);
2668 aniState = ahp->ah_curani;
2669 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
2672 ahp->ah_stats.ast_ani_lzero++;
2674 int32_t ccdelta = cycleCount - aniState->cycleCount;
2675 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
2676 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
2677 listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
2679 aniState->cycleCount = cycleCount;
2680 aniState->txFrameCount = txFrameCount;
2681 aniState->rxFrameCount = rxFrameCount;
2686 void ath9k_hw_ani_monitor(struct ath_hal *ah,
2687 const struct ath9k_node_stats *stats,
2688 struct ath9k_channel *chan)
2690 struct ath_hal_5416 *ahp = AH5416(ah);
2691 struct ar5416AniState *aniState;
2694 aniState = ahp->ah_curani;
2695 ahp->ah_stats.ast_nodestats = *stats;
2697 listenTime = ath9k_hw_ani_get_listen_time(ah);
2698 if (listenTime < 0) {
2699 ahp->ah_stats.ast_ani_lneg++;
2700 ath9k_ani_restart(ah);
2704 aniState->listenTime += listenTime;
2706 if (ahp->ah_hasHwPhyCounters) {
2707 u32 phyCnt1, phyCnt2;
2708 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2710 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2712 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2713 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2715 if (phyCnt1 < aniState->ofdmPhyErrBase ||
2716 phyCnt2 < aniState->cckPhyErrBase) {
2717 if (phyCnt1 < aniState->ofdmPhyErrBase) {
2718 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2719 "%s: phyCnt1 0x%x, resetting "
2720 "counter value to 0x%x\n",
2722 aniState->ofdmPhyErrBase);
2723 REG_WRITE(ah, AR_PHY_ERR_1,
2724 aniState->ofdmPhyErrBase);
2725 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
2726 AR_PHY_ERR_OFDM_TIMING);
2728 if (phyCnt2 < aniState->cckPhyErrBase) {
2729 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2730 "%s: phyCnt2 0x%x, resetting "
2731 "counter value to 0x%x\n",
2733 aniState->cckPhyErrBase);
2734 REG_WRITE(ah, AR_PHY_ERR_2,
2735 aniState->cckPhyErrBase);
2736 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
2737 AR_PHY_ERR_CCK_TIMING);
2742 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2743 ahp->ah_stats.ast_ani_ofdmerrs +=
2744 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2745 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2747 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2748 ahp->ah_stats.ast_ani_cckerrs +=
2749 cckPhyErrCnt - aniState->cckPhyErrCount;
2750 aniState->cckPhyErrCount = cckPhyErrCnt;
2756 if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
2757 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
2758 aniState->ofdmTrigLow / 1000 &&
2759 aniState->cckPhyErrCount <= aniState->listenTime *
2760 aniState->cckTrigLow / 1000)
2761 ath9k_hw_ani_lower_immunity(ah);
2762 ath9k_ani_restart(ah);
2763 } else if (aniState->listenTime > ahp->ah_aniPeriod) {
2764 if (aniState->ofdmPhyErrCount > aniState->listenTime *
2765 aniState->ofdmTrigHigh / 1000) {
2766 ath9k_hw_ani_ofdm_err_trigger(ah);
2767 ath9k_ani_restart(ah);
2768 } else if (aniState->cckPhyErrCount >
2769 aniState->listenTime * aniState->cckTrigHigh /
2771 ath9k_hw_ani_cck_err_trigger(ah);
2772 ath9k_ani_restart(ah);
2777 #ifndef ATH_NF_PER_CHAN
2778 static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
2782 for (i = 0; i < NUM_NF_READINGS; i++) {
2783 ah->nfCalHist[i].currIndex = 0;
2784 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
2785 ah->nfCalHist[i].invalidNFcount =
2786 AR_PHY_CCA_FILTERWINDOW_LENGTH;
2787 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
2788 ah->nfCalHist[i].nfCalBuffer[j] =
2789 AR_PHY_CCA_MAX_GOOD_VALUE;
2796 static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2800 u32 gpio_shift, tmp;
2803 addr = AR_GPIO_OUTPUT_MUX3;
2805 addr = AR_GPIO_OUTPUT_MUX2;
2807 addr = AR_GPIO_OUTPUT_MUX1;
2809 gpio_shift = (gpio % 6) * 5;
2811 if (AR_SREV_9280_20_OR_LATER(ah)
2812 || (addr != AR_GPIO_OUTPUT_MUX1)) {
2813 REG_RMW(ah, addr, (type << gpio_shift),
2814 (0x1f << gpio_shift));
2816 tmp = REG_READ(ah, addr);
2817 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
2818 tmp &= ~(0x1f << gpio_shift);
2819 tmp |= (type << gpio_shift);
2820 REG_WRITE(ah, addr, tmp);
2824 static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2825 enum ath9k_gpio_output_mux_type
2831 static u32 MuxSignalConversionTable[] = {
2833 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2835 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2837 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2839 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2841 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2844 if ((halSignalType >= 0)
2845 && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2846 ah_signal_type = MuxSignalConversionTable[halSignalType];
2850 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2852 gpio_shift = 2 * gpio;
2856 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2857 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2862 static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio,
2865 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2870 static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2872 if (gpio >= ah->ah_caps.halNumGpioPins)
2875 if (AR_SREV_9280_10_OR_LATER(ah)) {
2877 (REG_READ(ah, AR_GPIO_IN_OUT),
2878 AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
2880 return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
2881 AR_GPIO_BIT(gpio)) != 0;
2885 static inline int ath9k_hw_post_attach(struct ath_hal *ah)
2889 if (!ath9k_hw_chip_test(ah)) {
2890 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2891 "%s: hardware self-test failed\n", __func__);
2895 ecode = ath9k_hw_rf_claim(ah);
2899 ecode = ath9k_hw_eeprom_attach(ah);
2902 ecode = ath9k_hw_rfattach(ah);
2906 if (!AR_SREV_9100(ah)) {
2907 ath9k_hw_ani_setup(ah);
2908 ath9k_hw_ani_attach(ah);
2913 static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
2914 struct ar5416_eeprom *pEepData,
2917 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
2919 switch (ah->ah_devid) {
2920 case AR9280_DEVID_PCI:
2921 if (reg == 0x7894) {
2922 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2923 "ini VAL: %x EEPROM: %x\n", value,
2924 (pBase->version & 0xff));
2926 if ((pBase->version & 0xff) > 0x0a) {
2927 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2930 value &= ~AR_AN_TOP2_PWDCLKIND;
2931 value |= AR_AN_TOP2_PWDCLKIND & (pBase->
2932 pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
2934 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2935 "PWDCLKIND Earlier Rev\n");
2938 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2939 "final ini VAL: %x\n", value);
2946 static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2948 struct ath_hal_5416 *ahp = AH5416(ah);
2949 struct hal_capabilities *pCap = &ah->ah_caps;
2950 u16 capField = 0, eeval;
2952 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
2954 ah->ah_currentRD = eeval;
2956 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
2957 ah->ah_currentRDExt = eeval;
2959 capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
2961 if (ah->ah_opmode != ATH9K_M_HOSTAP &&
2962 ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2963 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
2964 ah->ah_currentRD += 5;
2965 else if (ah->ah_currentRD == 0x41)
2966 ah->ah_currentRD = 0x43;
2967 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
2968 "%s: regdomain mapped to 0x%x\n", __func__,
2972 pCap->halWirelessModes = 0;
2973 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2975 if (eeval & AR5416_OPFLAGS_11A) {
2976 pCap->halWirelessModes |= ATH9K_MODE_SEL_11A |
2977 ((!ah->ah_config.ath_hal_htEnable
2978 || (eeval & AR5416_OPFLAGS_N_5G_HT20)) ? 0
2979 : (ATH9K_MODE_SEL_11NA_HT20 |
2980 ((eeval & AR5416_OPFLAGS_N_5G_HT40) ? 0
2981 : (ATH9K_MODE_SEL_11NA_HT40PLUS |
2982 ATH9K_MODE_SEL_11NA_HT40MINUS))));
2984 if (eeval & AR5416_OPFLAGS_11G) {
2985 pCap->halWirelessModes |=
2986 ATH9K_MODE_SEL_11B | ATH9K_MODE_SEL_11G |
2987 ((!ah->ah_config.ath_hal_htEnable
2988 || (eeval & AR5416_OPFLAGS_N_2G_HT20)) ? 0
2989 : (ATH9K_MODE_SEL_11NG_HT20 |
2990 ((eeval & AR5416_OPFLAGS_N_2G_HT40) ? 0
2991 : (ATH9K_MODE_SEL_11NG_HT40PLUS |
2992 ATH9K_MODE_SEL_11NG_HT40MINUS))));
2995 pCap->halTxChainMask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
2996 if ((ah->ah_isPciExpress)
2997 || (eeval & AR5416_OPFLAGS_11A)) {
2998 pCap->halRxChainMask =
2999 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3001 pCap->halRxChainMask =
3002 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3005 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3006 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3008 pCap->halLow2GhzChan = 2312;
3009 pCap->halHigh2GhzChan = 2732;
3011 pCap->halLow5GhzChan = 4920;
3012 pCap->halHigh5GhzChan = 6100;
3014 pCap->halCipherCkipSupport = false;
3015 pCap->halCipherTkipSupport = true;
3016 pCap->halCipherAesCcmSupport = true;
3018 pCap->halMicCkipSupport = false;
3019 pCap->halMicTkipSupport = true;
3020 pCap->halMicAesCcmSupport = true;
3022 pCap->halChanSpreadSupport = true;
3024 pCap->halHTSupport =
3025 ah->ah_config.ath_hal_htEnable ? true : false;
3026 pCap->halGTTSupport = true;
3027 pCap->halVEOLSupport = true;
3028 pCap->halBssIdMaskSupport = true;
3029 pCap->halMcastKeySrchSupport = false;
3031 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3032 pCap->halTotalQueues =
3033 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3035 pCap->halTotalQueues = ATH9K_NUM_TX_QUEUES;
3037 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3038 pCap->halKeyCacheSize =
3039 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3041 pCap->halKeyCacheSize = AR_KEYTABLE_SIZE;
3043 pCap->halFastCCSupport = true;
3044 pCap->halNumMRRetries = 4;
3045 pCap->halTxTrigLevelMax = MAX_TX_FIFO_THRESHOLD;
3047 if (AR_SREV_9280_10_OR_LATER(ah))
3048 pCap->halNumGpioPins = AR928X_NUM_GPIO;
3050 pCap->halNumGpioPins = AR_NUM_GPIO;
3052 if (AR_SREV_9280_10_OR_LATER(ah)) {
3053 pCap->halWowSupport = true;
3054 pCap->halWowMatchPatternExact = true;
3056 pCap->halWowSupport = false;
3057 pCap->halWowMatchPatternExact = false;
3060 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3061 pCap->halCSTSupport = true;
3062 pCap->halRtsAggrLimit = ATH_AMPDU_LIMIT_MAX;
3064 pCap->halRtsAggrLimit = (8 * 1024);
3067 pCap->halEnhancedPmSupport = true;
3069 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3070 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3071 ahp->ah_gpioSelect =
3072 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3074 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3076 ath9k_hw_setcapability(ah, HAL_CAP_RFSILENT, 1, true,
3078 pCap->halRfSilentSupport = true;
3081 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3082 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3083 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3084 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3085 (ah->ah_macVersion == AR_SREV_VERSION_9280))
3086 pCap->halAutoSleepSupport = false;
3088 pCap->halAutoSleepSupport = true;
3090 if (AR_SREV_9280(ah))
3091 pCap->hal4kbSplitTransSupport = false;
3093 pCap->hal4kbSplitTransSupport = true;
3095 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3097 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3098 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3099 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3100 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3103 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3104 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3107 pCap->halRegCap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3109 pCap->halNumAntCfg5GHz =
3110 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_5GHZ);
3111 pCap->halNumAntCfg2GHz =
3112 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_2GHZ);
3117 static void ar5416DisablePciePhy(struct ath_hal *ah)
3119 if (!AR_SREV_9100(ah))
3122 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3123 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3124 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3125 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3126 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3127 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3128 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3129 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3130 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3132 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3135 static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3137 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3139 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3140 AR_RTC_FORCE_WAKE_EN);
3141 if (!AR_SREV_9100(ah))
3142 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3144 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3149 static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3151 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3153 struct hal_capabilities *pCap = &ah->ah_caps;
3155 if (!pCap->halAutoSleepSupport) {
3156 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3157 AR_RTC_FORCE_WAKE_ON_INT);
3159 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3160 AR_RTC_FORCE_WAKE_EN);
3165 static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3172 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3173 AR_RTC_STATUS_SHUTDOWN) {
3174 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3179 if (AR_SREV_9100(ah))
3180 REG_SET_BIT(ah, AR_RTC_RESET,
3183 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3184 AR_RTC_FORCE_WAKE_EN);
3187 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3188 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3189 if (val == AR_RTC_STATUS_ON)
3192 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3193 AR_RTC_FORCE_WAKE_EN);
3196 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3197 "%s: Failed to wakeup in %uus\n",
3198 __func__, POWER_UP_TIME / 20);
3203 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3207 bool ath9k_hw_setpower(struct ath_hal *ah,
3208 enum ath9k_power_mode mode)
3210 struct ath_hal_5416 *ahp = AH5416(ah);
3211 static const char *modes[] = {
3217 int status = true, setChip = true;
3219 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3220 modes[ahp->ah_powerMode], modes[mode],
3221 setChip ? "set chip " : "");
3224 case ATH9K_PM_AWAKE:
3225 status = ath9k_hw_set_power_awake(ah, setChip);
3227 case ATH9K_PM_FULL_SLEEP:
3228 ath9k_set_power_sleep(ah, setChip);
3229 ahp->ah_chipFullSleep = true;
3231 case ATH9K_PM_NETWORK_SLEEP:
3232 ath9k_set_power_network_sleep(ah, setChip);
3235 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3236 "%s: unknown power mode %u\n", __func__, mode);
3239 ahp->ah_powerMode = mode;
3243 static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3244 struct ath_softc *sc,
3248 struct ath_hal_5416 *ahp;
3251 #ifndef CONFIG_SLOW_ANT_DIV
3256 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3262 ath9k_hw_set_defaults(ah);
3264 if (ah->ah_config.ath_hal_intrMitigation != 0)
3265 ahp->ah_intrMitigation = true;
3267 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3268 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3274 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3275 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3281 if (ah->ah_config.ath_hal_serializeRegMode == SER_REG_MODE_AUTO) {
3282 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3283 ah->ah_config.ath_hal_serializeRegMode =
3286 ah->ah_config.ath_hal_serializeRegMode =
3290 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3291 "%s: ath_hal_serializeRegMode is %d\n",
3292 __func__, ah->ah_config.ath_hal_serializeRegMode);
3294 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3295 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3296 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3297 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3298 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3299 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3300 "this driver\n", __func__,
3301 ah->ah_macVersion, ah->ah_macRev);
3302 ecode = -EOPNOTSUPP;
3306 if (AR_SREV_9100(ah)) {
3307 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3308 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3309 ah->ah_isPciExpress = false;
3311 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3313 if (AR_SREV_9160_10_OR_LATER(ah)) {
3314 if (AR_SREV_9280_10_OR_LATER(ah)) {
3315 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3316 ahp->ah_adcGainCalData.calData =
3317 &adc_gain_cal_single_sample;
3318 ahp->ah_adcDcCalData.calData =
3319 &adc_dc_cal_single_sample;
3320 ahp->ah_adcDcCalInitData.calData =
3323 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3324 ahp->ah_adcGainCalData.calData =
3325 &adc_gain_cal_multi_sample;
3326 ahp->ah_adcDcCalData.calData =
3327 &adc_dc_cal_multi_sample;
3328 ahp->ah_adcDcCalInitData.calData =
3332 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3335 if (AR_SREV_9160(ah)) {
3336 ah->ah_config.ath_hal_enableANI = 1;
3337 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3338 ATH9K_ANI_FIRSTEP_LEVEL);
3340 ahp->ah_ani_function = ATH9K_ANI_ALL;
3341 if (AR_SREV_9280_10_OR_LATER(ah)) {
3342 ahp->ah_ani_function &=
3343 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3347 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3348 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3349 ah->ah_macVersion, ah->ah_macRev);
3351 if (AR_SREV_9280_20_OR_LATER(ah)) {
3352 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3353 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3354 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3355 ARRAY_SIZE(ar9280Common_9280_2), 2);
3357 if (ah->ah_config.ath_hal_pcieClockReq) {
3358 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3359 ar9280PciePhy_clkreq_off_L1_9280,
3361 (ar9280PciePhy_clkreq_off_L1_9280),
3364 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3365 ar9280PciePhy_clkreq_always_on_L1_9280,
3367 (ar9280PciePhy_clkreq_always_on_L1_9280),
3370 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3371 ar9280Modes_fast_clock_9280_2,
3372 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3374 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3375 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3376 ARRAY_SIZE(ar9280Modes_9280), 6);
3377 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3378 ARRAY_SIZE(ar9280Common_9280), 2);
3379 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3380 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3381 ARRAY_SIZE(ar5416Modes_9160), 6);
3382 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3383 ARRAY_SIZE(ar5416Common_9160), 2);
3384 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3385 ARRAY_SIZE(ar5416Bank0_9160), 2);
3386 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3387 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3388 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3389 ARRAY_SIZE(ar5416Bank1_9160), 2);
3390 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3391 ARRAY_SIZE(ar5416Bank2_9160), 2);
3392 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3393 ARRAY_SIZE(ar5416Bank3_9160), 3);
3394 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3395 ARRAY_SIZE(ar5416Bank6_9160), 3);
3396 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3397 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3398 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3399 ARRAY_SIZE(ar5416Bank7_9160), 2);
3400 if (AR_SREV_9160_11(ah)) {
3401 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3402 ar5416Addac_91601_1,
3403 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3405 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3406 ARRAY_SIZE(ar5416Addac_9160), 2);
3408 } else if (AR_SREV_9100_OR_LATER(ah)) {
3409 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3410 ARRAY_SIZE(ar5416Modes_9100), 6);
3411 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3412 ARRAY_SIZE(ar5416Common_9100), 2);
3413 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3414 ARRAY_SIZE(ar5416Bank0_9100), 2);
3415 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3416 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3417 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3418 ARRAY_SIZE(ar5416Bank1_9100), 2);
3419 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3420 ARRAY_SIZE(ar5416Bank2_9100), 2);
3421 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3422 ARRAY_SIZE(ar5416Bank3_9100), 3);
3423 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3424 ARRAY_SIZE(ar5416Bank6_9100), 3);
3425 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3426 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3427 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3428 ARRAY_SIZE(ar5416Bank7_9100), 2);
3429 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3430 ARRAY_SIZE(ar5416Addac_9100), 2);
3432 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3433 ARRAY_SIZE(ar5416Modes), 6);
3434 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3435 ARRAY_SIZE(ar5416Common), 2);
3436 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3437 ARRAY_SIZE(ar5416Bank0), 2);
3438 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3439 ARRAY_SIZE(ar5416BB_RfGain), 3);
3440 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3441 ARRAY_SIZE(ar5416Bank1), 2);
3442 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3443 ARRAY_SIZE(ar5416Bank2), 2);
3444 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3445 ARRAY_SIZE(ar5416Bank3), 3);
3446 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3447 ARRAY_SIZE(ar5416Bank6), 3);
3448 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3449 ARRAY_SIZE(ar5416Bank6TPC), 3);
3450 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3451 ARRAY_SIZE(ar5416Bank7), 2);
3452 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3453 ARRAY_SIZE(ar5416Addac), 2);
3456 if (ah->ah_isPciExpress)
3457 ath9k_hw_configpcipowersave(ah, 0);
3459 ar5416DisablePciePhy(ah);
3461 ecode = ath9k_hw_post_attach(ah);
3465 #ifndef CONFIG_SLOW_ANT_DIV
3466 if (ah->ah_devid == AR9280_DEVID_PCI) {
3467 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3468 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3470 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3471 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3473 INI_RA(&ahp->ah_iniModes, i, j) =
3474 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3481 if (!ath9k_hw_fill_cap_info(ah)) {
3482 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3483 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3488 ecode = ath9k_hw_init_macaddr(ah);
3490 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3491 "%s: failed initializing mac address\n",
3496 if (AR_SREV_9285(ah))
3497 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3499 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3501 #ifndef ATH_NF_PER_CHAN
3503 ath9k_init_nfcal_hist_buffer(ah);
3510 ath9k_hw_detach((struct ath_hal *) ahp);
3516 void ath9k_hw_detach(struct ath_hal *ah)
3518 if (!AR_SREV_9100(ah))
3519 ath9k_hw_ani_detach(ah);
3520 ath9k_hw_rfdetach(ah);
3522 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3526 bool ath9k_get_channel_edges(struct ath_hal *ah,
3527 u16 flags, u16 *low,
3530 struct hal_capabilities *pCap = &ah->ah_caps;
3532 if (flags & CHANNEL_5GHZ) {
3533 *low = pCap->halLow5GhzChan;
3534 *high = pCap->halHigh5GhzChan;
3537 if ((flags & CHANNEL_2GHZ)) {
3538 *low = pCap->halLow2GhzChan;
3539 *high = pCap->halHigh2GhzChan;
3546 static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3555 u8 currPwr = pwrMin;
3556 u16 idxL = 0, idxR = 0;
3558 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3559 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3560 numIntercepts, &(idxL),
3564 if (idxL == numIntercepts - 1)
3565 idxL = (u16) (numIntercepts - 2);
3566 if (pPwrList[idxL] == pPwrList[idxR])
3569 k = (u16) (((currPwr -
3573 currPwr) * pVpdList[idxL]) /
3576 pRetVpdList[i] = (u8) k;
3584 ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3585 struct ath9k_channel *chan,
3586 struct cal_data_per_freq *pRawDataSet,
3590 int16_t *pMinCalPower,
3591 u16 *pPdGainBoundaries,
3597 u16 idxL = 0, idxR = 0, numPiers;
3598 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3599 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3600 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3601 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3602 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3603 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3605 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3606 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3607 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3610 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3612 int16_t minDelta = 0;
3613 struct chan_centers centers;
3615 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3617 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3618 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3622 match = ath9k_hw_get_lower_upper_index((u8)
3627 numPiers, &idxL, &idxR);
3630 for (i = 0; i < numXpdGains; i++) {
3631 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3632 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3633 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3638 AR5416_PD_GAIN_ICEPTS,
3642 for (i = 0; i < numXpdGains; i++) {
3643 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3644 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3645 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3646 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3648 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3651 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3652 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3655 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3657 AR5416_PD_GAIN_ICEPTS,
3659 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3661 AR5416_PD_GAIN_ICEPTS,
3664 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3666 (u8) (ath9k_hw_interpolate
3673 bChans[idxR], vpdTableL[i]
3680 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3683 for (i = 0; i < numXpdGains; i++) {
3684 if (i == (numXpdGains - 1))
3685 pPdGainBoundaries[i] =
3686 (u16) (maxPwrT4[i] / 2);
3688 pPdGainBoundaries[i] =
3689 (u16) ((maxPwrT4[i] +
3690 minPwrT4[i + 1]) / 4);
3692 pPdGainBoundaries[i] =
3693 min((u16) AR5416_MAX_RATE_POWER,
3694 pPdGainBoundaries[i]);
3696 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3697 minDelta = pPdGainBoundaries[0] - 23;
3698 pPdGainBoundaries[0] = 23;
3704 if (AR_SREV_9280_10_OR_LATER(ah))
3705 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3709 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3710 (minPwrT4[i] / 2)) -
3711 tPdGainOverlap + 1 + minDelta);
3713 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3714 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3716 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3717 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3719 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3724 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3725 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3727 maxIndex = (tgtIndex <
3728 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3730 while ((ss < maxIndex)
3731 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3732 pPDADCValues[k++] = vpdTableI[i][ss++];
3735 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3736 vpdTableI[i][sizeCurrVpdTable - 2]);
3737 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3739 if (tgtIndex > maxIndex) {
3740 while ((ss <= tgtIndex)
3741 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3742 tmpVal = (int16_t) ((vpdTableI[i]
3744 1] + (ss - maxIndex +
3746 pPDADCValues[k++] = (u8) ((tmpVal >
3747 255) ? 255 : tmpVal);
3753 while (i < AR5416_PD_GAINS_IN_MASK) {
3754 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3758 while (k < AR5416_NUM_PDADC_VALUES) {
3759 pPDADCValues[k] = pPDADCValues[k - 1];
3766 ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3767 struct ar5416_eeprom *pEepData,
3768 struct ath9k_channel *chan,
3769 int16_t *pTxPowerIndexOffset)
3771 struct cal_data_per_freq *pRawDataset;
3772 u8 *pCalBChans = NULL;
3773 u16 pdGainOverlap_t2;
3774 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3775 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3777 int16_t tMinCalPower;
3778 u16 numXpdGain, xpdMask;
3779 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3780 u32 reg32, regOffset, regChainOffset;
3782 struct ath_hal_5416 *ahp = AH5416(ah);
3784 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3785 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3787 if ((pEepData->baseEepHeader.
3788 version & AR5416_EEP_VER_MINOR_MASK) >=
3789 AR5416_EEP_MINOR_VER_2) {
3791 pEepData->modalHeader[modalIdx].pdGainOverlap;
3795 (REG_READ(ah, AR_PHY_TPCRG5),
3796 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3799 if (IS_CHAN_2GHZ(chan)) {
3800 pCalBChans = pEepData->calFreqPier2G;
3801 numPiers = AR5416_NUM_2G_CAL_PIERS;
3803 pCalBChans = pEepData->calFreqPier5G;
3804 numPiers = AR5416_NUM_5G_CAL_PIERS;
3809 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3810 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3811 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3813 xpdGainValues[numXpdGain] =
3814 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3819 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3820 (numXpdGain - 1) & 0x3);
3821 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3823 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3825 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3828 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3829 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3830 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3832 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3834 regChainOffset = i * 0x1000;
3835 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3836 if (IS_CHAN_2GHZ(chan))
3837 pRawDataset = pEepData->calPierData2G[i];
3839 pRawDataset = pEepData->calPierData5G[i];
3841 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3851 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3854 AR_PHY_TPCRG5 + regChainOffset,
3855 SM(pdGainOverlap_t2,
3856 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3857 | SM(gainBoundaries[0],
3858 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3859 | SM(gainBoundaries[1],
3860 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3861 | SM(gainBoundaries[2],
3862 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3863 | SM(gainBoundaries[3],
3864 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3868 AR_PHY_BASE + (672 << 2) + regChainOffset;
3869 for (j = 0; j < 32; j++) {
3871 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3872 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3873 8) | ((pdadcValues[4 * j + 2] &
3875 ((pdadcValues[4 * j + 3] & 0xFF) <<
3877 REG_WRITE(ah, regOffset, reg32);
3879 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3880 "PDADC (%d,%4x): %4.4x %8.8x\n",
3881 i, regChainOffset, regOffset,
3883 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3884 "PDADC: Chain %d | PDADC %3d Value %3d | "
3885 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3886 "PDADC %3d Value %3d |\n",
3887 i, 4 * j, pdadcValues[4 * j],
3888 4 * j + 1, pdadcValues[4 * j + 1],
3889 4 * j + 2, pdadcValues[4 * j + 2],
3891 pdadcValues[4 * j + 3]);
3897 *pTxPowerIndexOffset = 0;
3902 void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3904 struct ath_hal_5416 *ahp = AH5416(ah);
3907 if (ah->ah_isPciExpress != true)
3910 if (ah->ah_config.ath_hal_pciePowerSaveEnable == 2)
3916 if (AR_SREV_9280_20_OR_LATER(ah)) {
3917 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3918 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3919 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3922 } else if (AR_SREV_9280(ah)
3923 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3924 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3925 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3927 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3928 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3929 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3931 if (ah->ah_config.ath_hal_pcieClockReq)
3932 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3934 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3936 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3937 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3938 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3940 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3944 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3945 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3946 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3947 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3948 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3950 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3953 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3956 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3958 if (ah->ah_config.ath_hal_pcieWaen) {
3959 REG_WRITE(ah, AR_WA, ah->ah_config.ath_hal_pcieWaen);
3961 if (AR_SREV_9280(ah))
3962 REG_WRITE(ah, AR_WA, 0x0040073f);
3964 REG_WRITE(ah, AR_WA, 0x0000073f);
3969 ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3970 struct ath9k_channel *chan,
3971 struct cal_target_power_leg *powInfo,
3973 struct cal_target_power_leg *pNewPower,
3979 int matchIndex = -1, lowIndex = -1;
3981 struct chan_centers centers;
3983 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
3984 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
3986 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
3987 IS_CHAN_2GHZ(chan))) {
3990 for (i = 0; (i < numChannels)
3991 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
3993 ath9k_hw_fbin2freq(powInfo[i].bChannel,
3994 IS_CHAN_2GHZ(chan))) {
3998 ath9k_hw_fbin2freq(powInfo[i].bChannel,
3999 IS_CHAN_2GHZ(chan)))
4001 ath9k_hw_fbin2freq(powInfo[i - 1].
4009 if ((matchIndex == -1) && (lowIndex == -1))
4013 if (matchIndex != -1) {
4014 *pNewPower = powInfo[matchIndex];
4016 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4017 IS_CHAN_2GHZ(chan));
4018 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4019 IS_CHAN_2GHZ(chan));
4021 for (i = 0; i < numRates; i++) {
4022 pNewPower->tPow2x[i] =
4023 (u8) ath9k_hw_interpolate(freq, clo, chi,
4035 ath9k_hw_get_target_powers(struct ath_hal *ah,
4036 struct ath9k_channel *chan,
4037 struct cal_target_power_ht *powInfo,
4039 struct cal_target_power_ht *pNewPower,
4045 int matchIndex = -1, lowIndex = -1;
4047 struct chan_centers centers;
4049 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4050 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4053 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4056 for (i = 0; (i < numChannels)
4057 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4059 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4060 IS_CHAN_2GHZ(chan))) {
4065 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4066 IS_CHAN_2GHZ(chan)))
4068 ath9k_hw_fbin2freq(powInfo[i - 1].
4076 if ((matchIndex == -1) && (lowIndex == -1))
4080 if (matchIndex != -1) {
4081 *pNewPower = powInfo[matchIndex];
4083 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4084 IS_CHAN_2GHZ(chan));
4085 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4086 IS_CHAN_2GHZ(chan));
4088 for (i = 0; i < numRates; i++) {
4089 pNewPower->tPow2x[i] =
4090 (u8) ath9k_hw_interpolate(freq, clo, chi,
4102 ath9k_hw_get_max_edge_power(u16 freq,
4103 struct cal_ctl_edges *pRdEdgesPower,
4106 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4109 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4110 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4111 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4113 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4117 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4118 bChannel, is2GHz))) {
4119 if (ath9k_hw_fbin2freq
4120 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4121 && pRdEdgesPower[i - 1].flag) {
4123 pRdEdgesPower[i - 1].tPower;
4128 return twiceMaxEdgePower;
4132 ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4133 struct ar5416_eeprom *pEepData,
4134 struct ath9k_channel *chan,
4135 int16_t *ratesArray,
4137 u8 AntennaReduction,
4138 u8 twiceMaxRegulatoryPower,
4141 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4142 static const u16 tpScaleReductionTable[5] =
4143 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4146 int8_t twiceLargestAntenna;
4147 struct cal_ctl_data *rep;
4148 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4151 struct cal_target_power_leg targetPowerOfdmExt = {
4152 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4155 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4158 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4159 u16 ctlModesFor11a[] =
4160 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4161 u16 ctlModesFor11g[] =
4162 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4165 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4166 struct chan_centers centers;
4168 u8 twiceMinEdgePower;
4169 struct ath_hal_5416 *ahp = AH5416(ah);
4171 tx_chainmask = ahp->ah_txchainmask;
4173 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4175 twiceLargestAntenna = max(
4176 pEepData->modalHeader
4177 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4178 pEepData->modalHeader
4179 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4181 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4182 pEepData->modalHeader
4183 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4185 twiceLargestAntenna =
4186 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4188 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4190 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4191 maxRegAllowedPower -=
4192 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4195 scaledPower = min(powerLimit, maxRegAllowedPower);
4197 switch (ar5416_get_ntxchains(tx_chainmask)) {
4202 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4203 pwrDecreaseFor2Chain;
4207 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4208 pwrDecreaseFor3Chain;
4212 scaledPower = max(0, (int32_t) scaledPower);
4214 if (IS_CHAN_2GHZ(chan)) {
4216 ARRAY_SIZE(ctlModesFor11g) -
4217 SUB_NUM_CTL_MODES_AT_2G_40;
4218 pCtlMode = ctlModesFor11g;
4220 ath9k_hw_get_legacy_target_powers(ah, chan,
4223 AR5416_NUM_2G_CCK_TARGET_POWERS,
4226 ath9k_hw_get_legacy_target_powers(ah, chan,
4229 AR5416_NUM_2G_20_TARGET_POWERS,
4230 &targetPowerOfdm, 4,
4232 ath9k_hw_get_target_powers(ah, chan,
4233 pEepData->calTargetPower2GHT20,
4234 AR5416_NUM_2G_20_TARGET_POWERS,
4235 &targetPowerHt20, 8, false);
4237 if (IS_CHAN_HT40(chan)) {
4238 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4239 ath9k_hw_get_target_powers(ah, chan,
4241 calTargetPower2GHT40,
4242 AR5416_NUM_2G_40_TARGET_POWERS,
4243 &targetPowerHt40, 8,
4245 ath9k_hw_get_legacy_target_powers(ah, chan,
4248 AR5416_NUM_2G_CCK_TARGET_POWERS,
4251 ath9k_hw_get_legacy_target_powers(ah, chan,
4254 AR5416_NUM_2G_20_TARGET_POWERS,
4255 &targetPowerOfdmExt,
4261 ARRAY_SIZE(ctlModesFor11a) -
4262 SUB_NUM_CTL_MODES_AT_5G_40;
4263 pCtlMode = ctlModesFor11a;
4265 ath9k_hw_get_legacy_target_powers(ah, chan,
4268 AR5416_NUM_5G_20_TARGET_POWERS,
4269 &targetPowerOfdm, 4,
4271 ath9k_hw_get_target_powers(ah, chan,
4272 pEepData->calTargetPower5GHT20,
4273 AR5416_NUM_5G_20_TARGET_POWERS,
4274 &targetPowerHt20, 8, false);
4276 if (IS_CHAN_HT40(chan)) {
4277 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4278 ath9k_hw_get_target_powers(ah, chan,
4280 calTargetPower5GHT40,
4281 AR5416_NUM_5G_40_TARGET_POWERS,
4282 &targetPowerHt40, 8,
4284 ath9k_hw_get_legacy_target_powers(ah, chan,
4287 AR5416_NUM_5G_20_TARGET_POWERS,
4288 &targetPowerOfdmExt,
4293 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4294 bool isHt40CtlMode =
4295 (pCtlMode[ctlMode] == CTL_5GHT40)
4296 || (pCtlMode[ctlMode] == CTL_2GHT40);
4298 freq = centers.synth_center;
4299 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4300 freq = centers.ext_center;
4302 freq = centers.ctl_center;
4304 if (ar5416_get_eep_ver(ahp) == 14
4305 && ar5416_get_eep_rev(ahp) <= 2)
4306 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4308 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4309 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4310 "EXT_ADDITIVE %d\n",
4311 ctlMode, numCtlModes, isHt40CtlMode,
4312 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4314 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4316 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4317 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4318 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4320 i, cfgCtl, pCtlMode[ctlMode],
4321 pEepData->ctlIndex[i], chan->channel);
4323 if ((((cfgCtl & ~CTL_MODE_M) |
4324 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4325 pEepData->ctlIndex[i])
4327 (((cfgCtl & ~CTL_MODE_M) |
4328 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4330 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4331 rep = &(pEepData->ctlData[i]);
4334 ath9k_hw_get_max_edge_power(freq,
4337 [ar5416_get_ntxchains
4343 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4344 " MATCH-EE_IDX %d: ch %d is2 %d "
4345 "2xMinEdge %d chainmask %d chains %d\n",
4346 i, freq, IS_CHAN_2GHZ(chan),
4347 twiceMinEdgePower, tx_chainmask,
4348 ar5416_get_ntxchains
4350 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4352 min(twiceMaxEdgePower,
4362 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4364 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4365 " SEL-Min ctlMode %d pCtlMode %d "
4366 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4367 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4368 scaledPower, minCtlPower);
4370 switch (pCtlMode[ctlMode]) {
4372 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4374 targetPowerCck.tPow2x[i] =
4375 min(targetPowerCck.tPow2x[i],
4381 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4383 targetPowerOfdm.tPow2x[i] =
4384 min(targetPowerOfdm.tPow2x[i],
4390 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4392 targetPowerHt20.tPow2x[i] =
4393 min(targetPowerHt20.tPow2x[i],
4398 targetPowerCckExt.tPow2x[0] =
4399 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4403 targetPowerOfdmExt.tPow2x[0] =
4404 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4408 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4410 targetPowerHt40.tPow2x[i] =
4411 min(targetPowerHt40.tPow2x[i],
4420 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4421 ratesArray[rate18mb] = ratesArray[rate24mb] =
4422 targetPowerOfdm.tPow2x[0];
4423 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4424 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4425 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4426 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4428 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4429 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4431 if (IS_CHAN_2GHZ(chan)) {
4432 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4433 ratesArray[rate2s] = ratesArray[rate2l] =
4434 targetPowerCck.tPow2x[1];
4435 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4436 targetPowerCck.tPow2x[2];
4438 ratesArray[rate11s] = ratesArray[rate11l] =
4439 targetPowerCck.tPow2x[3];
4442 if (IS_CHAN_HT40(chan)) {
4443 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4444 ratesArray[rateHt40_0 + i] =
4445 targetPowerHt40.tPow2x[i];
4447 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4448 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4449 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4450 if (IS_CHAN_2GHZ(chan)) {
4451 ratesArray[rateExtCck] =
4452 targetPowerCckExt.tPow2x[0];
4459 ath9k_hw_set_txpower(struct ath_hal *ah,
4460 struct ar5416_eeprom *pEepData,
4461 struct ath9k_channel *chan,
4463 u8 twiceAntennaReduction,
4464 u8 twiceMaxRegulatoryPower,
4467 struct modal_eep_header *pModal =
4468 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4469 int16_t ratesArray[Ar5416RateSize];
4470 int16_t txPowerIndexOffset = 0;
4471 u8 ht40PowerIncForPdadc = 2;
4474 memset(ratesArray, 0, sizeof(ratesArray));
4476 if ((pEepData->baseEepHeader.
4477 version & AR5416_EEP_VER_MINOR_MASK) >=
4478 AR5416_EEP_MINOR_VER_2) {
4479 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4482 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4483 &ratesArray[0], cfgCtl,
4484 twiceAntennaReduction,
4485 twiceMaxRegulatoryPower,
4487 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4488 "ath9k_hw_set_txpower: unable to set "
4489 "tx power per rate table\n");
4493 if (!ath9k_hw_set_power_cal_table
4494 (ah, pEepData, chan, &txPowerIndexOffset)) {
4495 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4496 "ath9k_hw_set_txpower: unable to set power table\n");
4500 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4502 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4503 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4504 ratesArray[i] = AR5416_MAX_RATE_POWER;
4507 if (AR_SREV_9280_10_OR_LATER(ah)) {
4508 for (i = 0; i < Ar5416RateSize; i++)
4509 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4512 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4513 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4514 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4515 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4516 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4518 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4519 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4520 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4521 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4522 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4525 if (IS_CHAN_2GHZ(chan)) {
4526 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4527 ATH9K_POW_SM(ratesArray[rate2s], 24)
4528 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4529 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4530 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4532 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4533 ATH9K_POW_SM(ratesArray[rate11s], 24)
4534 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4535 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4536 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4540 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4541 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4542 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4543 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4544 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4546 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4547 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4548 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4549 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4550 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4553 if (IS_CHAN_HT40(chan)) {
4554 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4555 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4556 ht40PowerIncForPdadc, 24)
4557 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4558 ht40PowerIncForPdadc, 16)
4559 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4560 ht40PowerIncForPdadc, 8)
4561 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4562 ht40PowerIncForPdadc, 0)
4564 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4565 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4566 ht40PowerIncForPdadc, 24)
4567 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4568 ht40PowerIncForPdadc, 16)
4569 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4570 ht40PowerIncForPdadc, 8)
4571 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4572 ht40PowerIncForPdadc, 0)
4575 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4576 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4577 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4578 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4579 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4583 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4584 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4585 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4589 if (IS_CHAN_HT40(chan))
4591 else if (IS_CHAN_HT20(chan))
4594 if (AR_SREV_9280_10_OR_LATER(ah))
4595 ah->ah_maxPowerLevel =
4596 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4598 ah->ah_maxPowerLevel = ratesArray[i];
4603 static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4608 u32 coef_exp, coef_man;
4610 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4611 if ((coef_scaled >> coef_exp) & 0x1)
4614 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4616 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4618 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4619 *coef_exponent = coef_exp - 16;
4623 ath9k_hw_set_delta_slope(struct ath_hal *ah,
4624 struct ath9k_channel *chan)
4626 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4627 u32 clockMhzScaled = 0x64000000;
4628 struct chan_centers centers;
4630 if (IS_CHAN_HALF_RATE(chan))
4631 clockMhzScaled = clockMhzScaled >> 1;
4632 else if (IS_CHAN_QUARTER_RATE(chan))
4633 clockMhzScaled = clockMhzScaled >> 2;
4635 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4636 coef_scaled = clockMhzScaled / centers.synth_center;
4638 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4641 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4642 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4643 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4644 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4646 coef_scaled = (9 * coef_scaled) / 10;
4648 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4651 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4652 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4653 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4654 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4657 static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4658 struct ath9k_channel *chan)
4660 int bb_spur = AR_NO_SPUR;
4663 int bb_spur_off, spur_subchannel_sd;
4665 int spur_delta_phase;
4667 int upper, lower, cur_vit_mask;
4670 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4671 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4673 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4674 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4676 int inc[4] = { 0, 100, 0, 0 };
4677 struct chan_centers centers;
4684 bool is2GHz = IS_CHAN_2GHZ(chan);
4686 memset(&mask_m, 0, sizeof(int8_t) * 123);
4687 memset(&mask_p, 0, sizeof(int8_t) * 123);
4689 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4690 freq = centers.synth_center;
4692 ah->ah_config.ath_hal_spurMode = SPUR_ENABLE_EEPROM;
4693 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4694 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4697 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4699 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4701 if (AR_NO_SPUR == cur_bb_spur)
4703 cur_bb_spur = cur_bb_spur - freq;
4705 if (IS_CHAN_HT40(chan)) {
4706 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4707 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4708 bb_spur = cur_bb_spur;
4711 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4712 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4713 bb_spur = cur_bb_spur;
4718 if (AR_NO_SPUR == bb_spur) {
4719 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4720 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4723 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4724 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4727 bin = bb_spur * 320;
4729 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4731 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4732 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4733 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4734 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4735 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4737 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4738 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4739 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4740 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4741 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4742 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4744 if (IS_CHAN_HT40(chan)) {
4746 spur_subchannel_sd = 1;
4747 bb_spur_off = bb_spur + 10;
4749 spur_subchannel_sd = 0;
4750 bb_spur_off = bb_spur - 10;
4753 spur_subchannel_sd = 0;
4754 bb_spur_off = bb_spur;
4757 if (IS_CHAN_HT40(chan))
4759 ((bb_spur * 262144) /
4760 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4763 ((bb_spur * 524288) /
4764 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4766 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4767 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4769 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4770 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4771 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4772 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4774 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4775 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4781 for (i = 0; i < 4; i++) {
4785 for (bp = 0; bp < 30; bp++) {
4786 if ((cur_bin > lower) && (cur_bin < upper)) {
4787 pilot_mask = pilot_mask | 0x1 << bp;
4788 chan_mask = chan_mask | 0x1 << bp;
4793 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4794 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4797 cur_vit_mask = 6100;
4801 for (i = 0; i < 123; i++) {
4802 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
4803 if ((abs(cur_vit_mask - bin)) < 75)
4807 if (cur_vit_mask < 0)
4808 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4810 mask_p[cur_vit_mask / 100] = mask_amt;
4812 cur_vit_mask -= 100;
4815 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4816 | (mask_m[48] << 26) | (mask_m[49] << 24)
4817 | (mask_m[50] << 22) | (mask_m[51] << 20)
4818 | (mask_m[52] << 18) | (mask_m[53] << 16)
4819 | (mask_m[54] << 14) | (mask_m[55] << 12)
4820 | (mask_m[56] << 10) | (mask_m[57] << 8)
4821 | (mask_m[58] << 6) | (mask_m[59] << 4)
4822 | (mask_m[60] << 2) | (mask_m[61] << 0);
4823 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4824 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4826 tmp_mask = (mask_m[31] << 28)
4827 | (mask_m[32] << 26) | (mask_m[33] << 24)
4828 | (mask_m[34] << 22) | (mask_m[35] << 20)
4829 | (mask_m[36] << 18) | (mask_m[37] << 16)
4830 | (mask_m[48] << 14) | (mask_m[39] << 12)
4831 | (mask_m[40] << 10) | (mask_m[41] << 8)
4832 | (mask_m[42] << 6) | (mask_m[43] << 4)
4833 | (mask_m[44] << 2) | (mask_m[45] << 0);
4834 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4835 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4837 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4838 | (mask_m[18] << 26) | (mask_m[18] << 24)
4839 | (mask_m[20] << 22) | (mask_m[20] << 20)
4840 | (mask_m[22] << 18) | (mask_m[22] << 16)
4841 | (mask_m[24] << 14) | (mask_m[24] << 12)
4842 | (mask_m[25] << 10) | (mask_m[26] << 8)
4843 | (mask_m[27] << 6) | (mask_m[28] << 4)
4844 | (mask_m[29] << 2) | (mask_m[30] << 0);
4845 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4846 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4848 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4849 | (mask_m[2] << 26) | (mask_m[3] << 24)
4850 | (mask_m[4] << 22) | (mask_m[5] << 20)
4851 | (mask_m[6] << 18) | (mask_m[7] << 16)
4852 | (mask_m[8] << 14) | (mask_m[9] << 12)
4853 | (mask_m[10] << 10) | (mask_m[11] << 8)
4854 | (mask_m[12] << 6) | (mask_m[13] << 4)
4855 | (mask_m[14] << 2) | (mask_m[15] << 0);
4856 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4857 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4859 tmp_mask = (mask_p[15] << 28)
4860 | (mask_p[14] << 26) | (mask_p[13] << 24)
4861 | (mask_p[12] << 22) | (mask_p[11] << 20)
4862 | (mask_p[10] << 18) | (mask_p[9] << 16)
4863 | (mask_p[8] << 14) | (mask_p[7] << 12)
4864 | (mask_p[6] << 10) | (mask_p[5] << 8)
4865 | (mask_p[4] << 6) | (mask_p[3] << 4)
4866 | (mask_p[2] << 2) | (mask_p[1] << 0);
4867 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4868 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4870 tmp_mask = (mask_p[30] << 28)
4871 | (mask_p[29] << 26) | (mask_p[28] << 24)
4872 | (mask_p[27] << 22) | (mask_p[26] << 20)
4873 | (mask_p[25] << 18) | (mask_p[24] << 16)
4874 | (mask_p[23] << 14) | (mask_p[22] << 12)
4875 | (mask_p[21] << 10) | (mask_p[20] << 8)
4876 | (mask_p[19] << 6) | (mask_p[18] << 4)
4877 | (mask_p[17] << 2) | (mask_p[16] << 0);
4878 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4879 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4881 tmp_mask = (mask_p[45] << 28)
4882 | (mask_p[44] << 26) | (mask_p[43] << 24)
4883 | (mask_p[42] << 22) | (mask_p[41] << 20)
4884 | (mask_p[40] << 18) | (mask_p[39] << 16)
4885 | (mask_p[38] << 14) | (mask_p[37] << 12)
4886 | (mask_p[36] << 10) | (mask_p[35] << 8)
4887 | (mask_p[34] << 6) | (mask_p[33] << 4)
4888 | (mask_p[32] << 2) | (mask_p[31] << 0);
4889 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4890 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4892 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4893 | (mask_p[59] << 26) | (mask_p[58] << 24)
4894 | (mask_p[57] << 22) | (mask_p[56] << 20)
4895 | (mask_p[55] << 18) | (mask_p[54] << 16)
4896 | (mask_p[53] << 14) | (mask_p[52] << 12)
4897 | (mask_p[51] << 10) | (mask_p[50] << 8)
4898 | (mask_p[49] << 6) | (mask_p[48] << 4)
4899 | (mask_p[47] << 2) | (mask_p[46] << 0);
4900 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4901 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4904 static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4905 struct ath9k_channel *chan)
4907 int bb_spur = AR_NO_SPUR;
4910 int spur_delta_phase;
4912 int upper, lower, cur_vit_mask;
4915 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4916 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4918 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4919 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4921 int inc[4] = { 0, 100, 0, 0 };
4928 bool is2GHz = IS_CHAN_2GHZ(chan);
4930 memset(&mask_m, 0, sizeof(int8_t) * 123);
4931 memset(&mask_p, 0, sizeof(int8_t) * 123);
4933 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4934 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4935 if (AR_NO_SPUR == cur_bb_spur)
4937 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4938 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4939 bb_spur = cur_bb_spur;
4944 if (AR_NO_SPUR == bb_spur)
4949 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4950 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4951 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4952 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4953 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4955 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4957 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4958 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4959 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4960 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4961 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4962 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4964 spur_delta_phase = ((bb_spur * 524288) / 100) &
4965 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4967 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4968 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4970 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4971 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4972 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4973 REG_WRITE(ah, AR_PHY_TIMING11, new);
4979 for (i = 0; i < 4; i++) {
4983 for (bp = 0; bp < 30; bp++) {
4984 if ((cur_bin > lower) && (cur_bin < upper)) {
4985 pilot_mask = pilot_mask | 0x1 << bp;
4986 chan_mask = chan_mask | 0x1 << bp;
4991 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4992 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4995 cur_vit_mask = 6100;
4999 for (i = 0; i < 123; i++) {
5000 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5001 if ((abs(cur_vit_mask - bin)) < 75)
5005 if (cur_vit_mask < 0)
5006 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5008 mask_p[cur_vit_mask / 100] = mask_amt;
5010 cur_vit_mask -= 100;
5013 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5014 | (mask_m[48] << 26) | (mask_m[49] << 24)
5015 | (mask_m[50] << 22) | (mask_m[51] << 20)
5016 | (mask_m[52] << 18) | (mask_m[53] << 16)
5017 | (mask_m[54] << 14) | (mask_m[55] << 12)
5018 | (mask_m[56] << 10) | (mask_m[57] << 8)
5019 | (mask_m[58] << 6) | (mask_m[59] << 4)
5020 | (mask_m[60] << 2) | (mask_m[61] << 0);
5021 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5022 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5024 tmp_mask = (mask_m[31] << 28)
5025 | (mask_m[32] << 26) | (mask_m[33] << 24)
5026 | (mask_m[34] << 22) | (mask_m[35] << 20)
5027 | (mask_m[36] << 18) | (mask_m[37] << 16)
5028 | (mask_m[48] << 14) | (mask_m[39] << 12)
5029 | (mask_m[40] << 10) | (mask_m[41] << 8)
5030 | (mask_m[42] << 6) | (mask_m[43] << 4)
5031 | (mask_m[44] << 2) | (mask_m[45] << 0);
5032 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5033 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5035 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5036 | (mask_m[18] << 26) | (mask_m[18] << 24)
5037 | (mask_m[20] << 22) | (mask_m[20] << 20)
5038 | (mask_m[22] << 18) | (mask_m[22] << 16)
5039 | (mask_m[24] << 14) | (mask_m[24] << 12)
5040 | (mask_m[25] << 10) | (mask_m[26] << 8)
5041 | (mask_m[27] << 6) | (mask_m[28] << 4)
5042 | (mask_m[29] << 2) | (mask_m[30] << 0);
5043 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5044 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5046 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5047 | (mask_m[2] << 26) | (mask_m[3] << 24)
5048 | (mask_m[4] << 22) | (mask_m[5] << 20)
5049 | (mask_m[6] << 18) | (mask_m[7] << 16)
5050 | (mask_m[8] << 14) | (mask_m[9] << 12)
5051 | (mask_m[10] << 10) | (mask_m[11] << 8)
5052 | (mask_m[12] << 6) | (mask_m[13] << 4)
5053 | (mask_m[14] << 2) | (mask_m[15] << 0);
5054 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5055 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5057 tmp_mask = (mask_p[15] << 28)
5058 | (mask_p[14] << 26) | (mask_p[13] << 24)
5059 | (mask_p[12] << 22) | (mask_p[11] << 20)
5060 | (mask_p[10] << 18) | (mask_p[9] << 16)
5061 | (mask_p[8] << 14) | (mask_p[7] << 12)
5062 | (mask_p[6] << 10) | (mask_p[5] << 8)
5063 | (mask_p[4] << 6) | (mask_p[3] << 4)
5064 | (mask_p[2] << 2) | (mask_p[1] << 0);
5065 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5066 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5068 tmp_mask = (mask_p[30] << 28)
5069 | (mask_p[29] << 26) | (mask_p[28] << 24)
5070 | (mask_p[27] << 22) | (mask_p[26] << 20)
5071 | (mask_p[25] << 18) | (mask_p[24] << 16)
5072 | (mask_p[23] << 14) | (mask_p[22] << 12)
5073 | (mask_p[21] << 10) | (mask_p[20] << 8)
5074 | (mask_p[19] << 6) | (mask_p[18] << 4)
5075 | (mask_p[17] << 2) | (mask_p[16] << 0);
5076 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5077 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5079 tmp_mask = (mask_p[45] << 28)
5080 | (mask_p[44] << 26) | (mask_p[43] << 24)
5081 | (mask_p[42] << 22) | (mask_p[41] << 20)
5082 | (mask_p[40] << 18) | (mask_p[39] << 16)
5083 | (mask_p[38] << 14) | (mask_p[37] << 12)
5084 | (mask_p[36] << 10) | (mask_p[35] << 8)
5085 | (mask_p[34] << 6) | (mask_p[33] << 4)
5086 | (mask_p[32] << 2) | (mask_p[31] << 0);
5087 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5088 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5090 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5091 | (mask_p[59] << 26) | (mask_p[58] << 24)
5092 | (mask_p[57] << 22) | (mask_p[56] << 20)
5093 | (mask_p[55] << 18) | (mask_p[54] << 16)
5094 | (mask_p[53] << 14) | (mask_p[52] << 12)
5095 | (mask_p[51] << 10) | (mask_p[50] << 8)
5096 | (mask_p[49] << 6) | (mask_p[48] << 4)
5097 | (mask_p[47] << 2) | (mask_p[46] << 0);
5098 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5099 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5102 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5104 struct ath_hal_5416 *ahp = AH5416(ah);
5105 int rx_chainmask, tx_chainmask;
5107 rx_chainmask = ahp->ah_rxchainmask;
5108 tx_chainmask = ahp->ah_txchainmask;
5110 switch (rx_chainmask) {
5112 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5113 AR_PHY_SWAP_ALT_CHAIN);
5115 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5116 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5117 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5122 if (!AR_SREV_9280(ah))
5125 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5126 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5132 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5133 if (tx_chainmask == 0x5) {
5134 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5135 AR_PHY_SWAP_ALT_CHAIN);
5137 if (AR_SREV_9100(ah))
5138 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5139 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5142 static void ath9k_hw_set_addac(struct ath_hal *ah,
5143 struct ath9k_channel *chan)
5145 struct modal_eep_header *pModal;
5146 struct ath_hal_5416 *ahp = AH5416(ah);
5147 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5150 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5153 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5156 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5158 if (pModal->xpaBiasLvl != 0xff) {
5159 biaslevel = pModal->xpaBiasLvl;
5162 u16 resetFreqBin, freqBin, freqCount = 0;
5163 struct chan_centers centers;
5165 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5168 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5169 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5170 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5174 while (freqCount < 3) {
5175 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5178 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5179 if (resetFreqBin >= freqBin) {
5182 xpaBiasLvlFreq[freqCount]
5191 if (IS_CHAN_2GHZ(chan)) {
5192 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5193 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5196 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5197 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5202 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5204 if (ah->ah_curchan != NULL)
5206 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5208 return clks / CLOCK_RATE[WIRELESS_MODE_11b];
5211 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5213 struct ath9k_channel *chan = ah->ah_curchan;
5215 if (chan && IS_CHAN_HT40(chan))
5216 return ath9k_hw_mac_usec(ah, clks) / 2;
5218 return ath9k_hw_mac_usec(ah, clks);
5221 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5223 if (ah->ah_curchan != NULL)
5224 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5227 return usecs * CLOCK_RATE[WIRELESS_MODE_11b];
5230 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5232 struct ath9k_channel *chan = ah->ah_curchan;
5234 if (chan && IS_CHAN_HT40(chan))
5235 return ath9k_hw_mac_clks(ah, usecs) * 2;
5237 return ath9k_hw_mac_clks(ah, usecs);
5240 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5242 struct ath_hal_5416 *ahp = AH5416(ah);
5244 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5245 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5247 ahp->ah_acktimeout = (u32) -1;
5250 REG_RMW_FIELD(ah, AR_TIME_OUT,
5251 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5252 ahp->ah_acktimeout = us;
5257 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5259 struct ath_hal_5416 *ahp = AH5416(ah);
5261 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5262 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5264 ahp->ah_ctstimeout = (u32) -1;
5267 REG_RMW_FIELD(ah, AR_TIME_OUT,
5268 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5269 ahp->ah_ctstimeout = us;
5273 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5276 struct ath_hal_5416 *ahp = AH5416(ah);
5279 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5280 "%s: bad global tx timeout %u\n", __func__, tu);
5281 ahp->ah_globaltxtimeout = (u32) -1;
5284 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5285 ahp->ah_globaltxtimeout = tu;
5290 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5292 struct ath_hal_5416 *ahp = AH5416(ah);
5294 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5295 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5297 ahp->ah_slottime = (u32) -1;
5300 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5301 ahp->ah_slottime = us;
5306 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5308 struct ath_hal_5416 *ahp = AH5416(ah);
5310 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5311 __func__, ahp->ah_miscMode);
5312 if (ahp->ah_miscMode != 0)
5313 REG_WRITE(ah, AR_PCU_MISC,
5314 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5315 if (ahp->ah_slottime != (u32) -1)
5316 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5317 if (ahp->ah_acktimeout != (u32) -1)
5318 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5319 if (ahp->ah_ctstimeout != (u32) -1)
5320 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5321 if (ahp->ah_globaltxtimeout != (u32) -1)
5322 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5326 ath9k_hw_process_ini(struct ath_hal *ah,
5327 struct ath9k_channel *chan,
5328 enum ath9k_ht_macmode macmode)
5330 int i, regWrites = 0;
5331 struct ath_hal_5416 *ahp = AH5416(ah);
5332 u32 modesIndex, freqIndex;
5335 switch (chan->chanmode) {
5337 case CHANNEL_A_HT20:
5341 case CHANNEL_A_HT40PLUS:
5342 case CHANNEL_A_HT40MINUS:
5347 case CHANNEL_G_HT20:
5352 case CHANNEL_G_HT40PLUS:
5353 case CHANNEL_G_HT40MINUS:
5362 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5364 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5366 ath9k_hw_set_addac(ah, chan);
5368 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5369 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5371 struct ar5416IniArray temp;
5373 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5374 ahp->ah_iniAddac.ia_columns;
5376 memcpy(ahp->ah_addac5416_21,
5377 ahp->ah_iniAddac.ia_array, addacSize);
5379 (ahp->ah_addac5416_21)[31 *
5380 ahp->ah_iniAddac.ia_columns + 1] = 0;
5382 temp.ia_array = ahp->ah_addac5416_21;
5383 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5384 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5385 REG_WRITE_ARRAY(&temp, 1, regWrites);
5387 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5389 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5390 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5391 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5393 #ifdef CONFIG_SLOW_ANT_DIV
5394 if (ah->ah_devid == AR9280_DEVID_PCI)
5395 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5399 REG_WRITE(ah, reg, val);
5401 if (reg >= 0x7800 && reg < 0x78a0
5402 && ah->ah_config.ath_hal_analogShiftReg) {
5406 DO_DELAY(regWrites);
5409 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5410 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5411 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5413 REG_WRITE(ah, reg, val);
5415 if (reg >= 0x7800 && reg < 0x78a0
5416 && ah->ah_config.ath_hal_analogShiftReg) {
5420 DO_DELAY(regWrites);
5423 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5425 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5426 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5430 ath9k_hw_override_ini(ah, chan);
5431 ath9k_hw_set_regs(ah, chan, macmode);
5432 ath9k_hw_init_chain_masks(ah);
5434 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5435 ath9k_regd_get_ctl(ah, chan),
5436 ath9k_regd_get_antenna_allowed(ah,
5438 chan->maxRegTxPower * 2,
5439 min((u32) MAX_RATE_POWER,
5440 (u32) ah->ah_powerLimit));
5442 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5443 "%s: error init'ing transmit power\n", __func__);
5447 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5448 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5449 "%s: ar5416SetRfRegs failed\n", __func__);
5456 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5457 struct hal_cal_list *currCal)
5459 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5460 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5461 currCal->calData->calCountMax);
5463 switch (currCal->calData->calType) {
5464 case IQ_MISMATCH_CAL:
5465 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5466 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5467 "%s: starting IQ Mismatch Calibration\n",
5471 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5472 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5473 "%s: starting ADC Gain Calibration\n", __func__);
5476 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5477 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5478 "%s: starting ADC DC Calibration\n", __func__);
5480 case ADC_DC_INIT_CAL:
5481 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5482 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5483 "%s: starting Init ADC DC Calibration\n",
5488 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5489 AR_PHY_TIMING_CTRL4_DO_CAL);
5492 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5493 struct hal_cal_list *currCal)
5495 struct ath_hal_5416 *ahp = AH5416(ah);
5498 ath9k_hw_setup_calibration(ah, currCal);
5500 currCal->calState = CAL_RUNNING;
5502 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5503 ahp->ah_Meas0.sign[i] = 0;
5504 ahp->ah_Meas1.sign[i] = 0;
5505 ahp->ah_Meas2.sign[i] = 0;
5506 ahp->ah_Meas3.sign[i] = 0;
5509 ahp->ah_CalSamples = 0;
5513 ath9k_hw_per_calibration(struct ath_hal *ah,
5514 struct ath9k_channel *ichan,
5516 struct hal_cal_list *currCal,
5519 struct ath_hal_5416 *ahp = AH5416(ah);
5523 if (currCal->calState == CAL_RUNNING) {
5525 AR_PHY_TIMING_CTRL4(0)) &
5526 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5528 currCal->calData->calCollect(ah);
5530 ahp->ah_CalSamples++;
5532 if (ahp->ah_CalSamples >=
5533 currCal->calData->calNumSamples) {
5534 int i, numChains = 0;
5535 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5536 if (rxchainmask & (1 << i))
5540 currCal->calData->calPostProc(ah,
5544 currCal->calData->calType;
5545 currCal->calState = CAL_DONE;
5548 ath9k_hw_setup_calibration(ah, currCal);
5551 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5552 ath9k_hw_reset_calibration(ah, currCal);
5556 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5559 struct ath_hal_5416 *ahp = AH5416(ah);
5560 struct ath9k_channel ichan;
5562 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5563 const struct hal_percal_data *calData = currCal->calData;
5566 if (currCal == NULL)
5571 for (i = 0; i < init_cal_count; i++) {
5572 ath9k_hw_reset_calibration(ah, currCal);
5574 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5575 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5576 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5577 "%s: Cal %d failed to complete in 100ms.\n",
5578 __func__, calData->calType);
5580 ahp->ah_cal_list = ahp->ah_cal_list_last =
5581 ahp->ah_cal_list_curr = NULL;
5585 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5586 currCal, &isCalDone);
5588 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5589 "%s: Not able to run Init Cal %d.\n",
5590 __func__, calData->calType);
5592 if (currCal->calNext) {
5593 currCal = currCal->calNext;
5594 calData = currCal->calData;
5598 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5603 ath9k_hw_channel_change(struct ath_hal *ah,
5604 struct ath9k_channel *chan,
5605 enum ath9k_ht_macmode macmode)
5607 u32 synthDelay, qnum;
5608 struct ath_hal_5416 *ahp = AH5416(ah);
5610 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5611 if (ath9k_hw_numtxpending(ah, qnum)) {
5612 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5613 "%s: Transmit frames pending on queue %d\n",
5619 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5620 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5621 AR_PHY_RFBUS_GRANT_EN)) {
5622 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5623 "%s: Could not kill baseband RX\n", __func__);
5627 ath9k_hw_set_regs(ah, chan, macmode);
5629 if (AR_SREV_9280_10_OR_LATER(ah)) {
5630 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5631 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5632 "%s: failed to set channel\n", __func__);
5636 if (!(ath9k_hw_set_channel(ah, chan))) {
5637 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5638 "%s: failed to set channel\n", __func__);
5643 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5644 ath9k_regd_get_ctl(ah, chan),
5645 ath9k_regd_get_antenna_allowed(ah, chan),
5646 chan->maxRegTxPower * 2,
5647 min((u32) MAX_RATE_POWER,
5648 (u32) ah->ah_powerLimit)) != 0) {
5649 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5650 "%s: error init'ing transmit power\n", __func__);
5654 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5655 if (IS_CHAN_CCK(chan))
5656 synthDelay = (4 * synthDelay) / 22;
5660 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5662 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5664 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5665 ath9k_hw_set_delta_slope(ah, chan);
5667 if (AR_SREV_9280_10_OR_LATER(ah))
5668 ath9k_hw_9280_spur_mitigate(ah, chan);
5670 ath9k_hw_spur_mitigate(ah, chan);
5672 if (!chan->oneTimeCalsDone)
5673 chan->oneTimeCalsDone = true;
5678 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5679 struct ath9k_channel *chan)
5681 struct ath_hal_5416 *ahp = AH5416(ah);
5683 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5686 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5689 ahp->ah_chipFullSleep = false;
5691 ath9k_hw_init_pll(ah, chan);
5693 ath9k_hw_set_rfmode(ah, chan);
5698 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5702 regval = REG_READ(ah, AR_AHB_MODE);
5703 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5705 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5706 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5708 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5710 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5711 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5713 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5715 if (AR_SREV_9285(ah)) {
5716 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5717 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5719 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5720 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5724 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5726 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5727 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5728 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5729 "%s: dma failed to stop in 10ms\n"
5730 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5732 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5739 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5741 REG_CLR_BIT(ah, AR_DIAG_SW,
5742 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5744 ath9k_enable_mib_counters(ah);
5746 ath9k_ani_reset(ah);
5749 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5751 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5753 ath9k_hw_disable_mib_counters(ah);
5756 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5757 struct ath9k_channel *chan,
5758 enum hal_cal_types calType)
5760 struct ath_hal_5416 *ahp = AH5416(ah);
5761 bool retval = false;
5763 switch (calType & ahp->ah_suppCals) {
5764 case IQ_MISMATCH_CAL:
5765 if (!IS_CHAN_B(chan))
5770 if (!IS_CHAN_B(chan)
5771 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5779 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5780 struct ath9k_channel *chan)
5782 struct ath_hal_5416 *ahp = AH5416(ah);
5783 struct ath9k_channel *ichan =
5784 ath9k_regd_check_channel(ah, chan);
5786 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5787 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5788 AR_PHY_AGC_CONTROL_CAL);
5791 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5792 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5793 "%s: offset calibration failed to complete in 1ms; "
5794 "noisy environment?\n", __func__);
5798 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5799 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5800 AR_PHY_AGC_CONTROL_NF);
5802 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5805 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5806 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5807 INIT_CAL(&ahp->ah_adcGainCalData);
5808 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5809 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5810 "%s: enabling ADC Gain Calibration.\n",
5813 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5814 INIT_CAL(&ahp->ah_adcDcCalData);
5815 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5816 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5817 "%s: enabling ADC DC Calibration.\n",
5820 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5821 INIT_CAL(&ahp->ah_iqCalData);
5822 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5823 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5824 "%s: enabling IQ Calibration.\n",
5828 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5830 if (ahp->ah_cal_list_curr)
5831 ath9k_hw_reset_calibration(ah,
5832 ahp->ah_cal_list_curr);
5835 ichan->CalValid = 0;
5841 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5842 struct ath9k_channel *chan,
5843 enum ath9k_ht_macmode macmode,
5844 u8 txchainmask, u8 rxchainmask,
5845 enum ath9k_ht_extprotspacing extprotspacing,
5846 bool bChannelChange,
5849 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5851 struct ath_hal_5416 *ahp = AH5416(ah);
5852 struct ath9k_channel *curchan = ah->ah_curchan;
5856 int i, rx_chainmask;
5858 ahp->ah_extprotspacing = extprotspacing;
5859 ahp->ah_txchainmask = txchainmask;
5860 ahp->ah_rxchainmask = rxchainmask;
5862 if (AR_SREV_9280(ah)) {
5863 ahp->ah_txchainmask &= 0x3;
5864 ahp->ah_rxchainmask &= 0x3;
5867 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5868 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5869 "%s: invalid channel %u/0x%x; no mapping\n",
5870 __func__, chan->channel, chan->channelFlags);
5874 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5878 ath9k_hw_getnf(ah, curchan);
5880 if (bChannelChange &&
5881 (ahp->ah_chipFullSleep != true) &&
5882 (ah->ah_curchan != NULL) &&
5883 (chan->channel != ah->ah_curchan->channel) &&
5884 ((chan->channelFlags & CHANNEL_ALL) ==
5885 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5886 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5887 !IS_CHAN_A_5MHZ_SPACED(ah->
5890 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5891 ath9k_hw_loadnf(ah, ah->ah_curchan);
5892 ath9k_hw_start_nfcal(ah);
5897 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5898 if (saveDefAntenna == 0)
5901 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5903 saveLedState = REG_READ(ah, AR_CFG_LED) &
5904 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5905 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5907 ath9k_hw_mark_phy_inactive(ah);
5909 if (!ath9k_hw_chip_reset(ah, chan)) {
5910 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5915 if (AR_SREV_9280(ah)) {
5916 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5917 AR_GPIO_JTAG_DISABLE);
5919 if (ah->ah_caps.halWirelessModes & ATH9K_MODE_SEL_11A) {
5920 if (IS_CHAN_5GHZ(chan))
5921 ath9k_hw_set_gpio(ah, 9, 0);
5923 ath9k_hw_set_gpio(ah, 9, 1);
5925 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5928 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5932 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5933 ath9k_hw_set_delta_slope(ah, chan);
5935 if (AR_SREV_9280_10_OR_LATER(ah))
5936 ath9k_hw_9280_spur_mitigate(ah, chan);
5938 ath9k_hw_spur_mitigate(ah, chan);
5940 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5941 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5942 "%s: error setting board options\n", __func__);
5946 ath9k_hw_decrease_chain_power(ah, chan);
5948 REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
5949 REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
5951 | AR_STA_ID1_RTS_USE_DEF
5953 ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
5954 | ahp->ah_staId1Defaults);
5955 ath9k_hw_set_operating_mode(ah, opmode);
5957 REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
5958 REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
5960 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5962 REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
5963 REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4) |
5964 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5966 REG_WRITE(ah, AR_ISR, ~0);
5968 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5970 if (AR_SREV_9280_10_OR_LATER(ah)) {
5971 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5974 if (!(ath9k_hw_set_channel(ah, chan)))
5978 for (i = 0; i < AR_NUM_DCU; i++)
5979 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5981 ahp->ah_intrTxqs = 0;
5982 for (i = 0; i < ah->ah_caps.halTotalQueues; i++)
5983 ath9k_hw_resettxqueue(ah, i);
5985 ath9k_hw_init_interrupt_masks(ah, opmode);
5986 ath9k_hw_init_qos(ah);
5988 ath9k_hw_init_user_settings(ah);
5990 ah->ah_opmode = opmode;
5992 REG_WRITE(ah, AR_STA_ID1,
5993 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
5995 ath9k_hw_set_dma(ah);
5997 REG_WRITE(ah, AR_OBS, 8);
5999 if (ahp->ah_intrMitigation) {
6001 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6002 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6005 ath9k_hw_init_bb(ah, chan);
6007 if (!ath9k_hw_init_cal(ah, chan))
6010 rx_chainmask = ahp->ah_rxchainmask;
6011 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6012 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6013 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6016 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6018 if (AR_SREV_9100(ah)) {
6020 mask = REG_READ(ah, AR_CFG);
6021 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6022 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6023 "%s CFG Byte Swap Set 0x%x\n", __func__,
6027 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6028 REG_WRITE(ah, AR_CFG, mask);
6029 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6030 "%s Setting CFG 0x%x\n", __func__,
6031 REG_READ(ah, AR_CFG));
6035 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6047 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6049 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6052 bool ath9k_hw_disable(struct ath_hal *ah)
6054 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6057 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6061 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6062 u8 rxchainmask, bool longcal,
6065 struct ath_hal_5416 *ahp = AH5416(ah);
6066 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6067 struct ath9k_channel *ichan =
6068 ath9k_regd_check_channel(ah, chan);
6072 if (ichan == NULL) {
6073 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6074 "%s: invalid channel %u/0x%x; no mapping\n",
6075 __func__, chan->channel, chan->channelFlags);
6080 (currCal->calState == CAL_RUNNING ||
6081 currCal->calState == CAL_WAITING)) {
6082 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6085 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6087 if (currCal->calState == CAL_WAITING) {
6089 ath9k_hw_reset_calibration(ah, currCal);
6095 ath9k_hw_getnf(ah, ichan);
6096 ath9k_hw_loadnf(ah, ah->ah_curchan);
6097 ath9k_hw_start_nfcal(ah);
6099 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6101 chan->channelFlags |= CHANNEL_CW_INT;
6102 ichan->channelFlags &= ~CHANNEL_CW_INT;
6109 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6111 struct ath_hal_5416 *ahp = AH5416(ah);
6114 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6115 ahp->ah_totalPowerMeasI[i] +=
6116 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6117 ahp->ah_totalPowerMeasQ[i] +=
6118 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6119 ahp->ah_totalIqCorrMeas[i] +=
6120 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6121 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6122 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6123 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6124 ahp->ah_totalPowerMeasQ[i],
6125 ahp->ah_totalIqCorrMeas[i]);
6129 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6131 struct ath_hal_5416 *ahp = AH5416(ah);
6134 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6135 ahp->ah_totalAdcIOddPhase[i] +=
6136 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6137 ahp->ah_totalAdcIEvenPhase[i] +=
6138 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6139 ahp->ah_totalAdcQOddPhase[i] +=
6140 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6141 ahp->ah_totalAdcQEvenPhase[i] +=
6142 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6144 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6145 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6146 "oddq=0x%08x; evenq=0x%08x;\n",
6147 ahp->ah_CalSamples, i,
6148 ahp->ah_totalAdcIOddPhase[i],
6149 ahp->ah_totalAdcIEvenPhase[i],
6150 ahp->ah_totalAdcQOddPhase[i],
6151 ahp->ah_totalAdcQEvenPhase[i]);
6155 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6157 struct ath_hal_5416 *ahp = AH5416(ah);
6160 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6161 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6162 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6163 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6164 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6165 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6166 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6167 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6168 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6170 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6171 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6172 "oddq=0x%08x; evenq=0x%08x;\n",
6173 ahp->ah_CalSamples, i,
6174 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6175 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6176 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6177 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6181 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6183 struct ath_hal_5416 *ahp = AH5416(ah);
6184 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6185 u32 qCoffDenom, iCoffDenom;
6186 int32_t qCoff, iCoff;
6189 for (i = 0; i < numChains; i++) {
6190 powerMeasI = ahp->ah_totalPowerMeasI[i];
6191 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6192 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6194 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6195 "Starting IQ Cal and Correction for Chain %d\n",
6198 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6199 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6200 i, ahp->ah_totalIqCorrMeas[i]);
6205 if (iqCorrMeas > 0x80000000) {
6206 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6210 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6211 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6212 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6213 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6214 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6217 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6218 qCoffDenom = powerMeasQ / 64;
6220 if (powerMeasQ != 0) {
6222 iCoff = iqCorrMeas / iCoffDenom;
6223 qCoff = powerMeasI / qCoffDenom - 64;
6224 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6225 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6226 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6227 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6230 iCoff = iCoff & 0x3f;
6231 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6232 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6233 if (iqCorrNeg == 0x0)
6234 iCoff = 0x40 - iCoff;
6238 else if (qCoff <= -16)
6241 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6242 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6245 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6246 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6248 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6249 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6251 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6252 "IQ Cal and Correction done for Chain %d\n",
6257 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6258 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6262 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6264 struct ath_hal_5416 *ahp = AH5416(ah);
6265 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6267 u32 qGainMismatch, iGainMismatch, val, i;
6269 for (i = 0; i < numChains; i++) {
6270 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6271 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6272 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6273 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6275 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6276 "Starting ADC Gain Cal for Chain %d\n", i);
6278 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6279 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6281 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6282 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6284 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6285 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6287 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6288 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6291 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6293 ((iEvenMeasOffset * 32) /
6294 iOddMeasOffset) & 0x3f;
6296 ((qOddMeasOffset * 32) /
6297 qEvenMeasOffset) & 0x3f;
6299 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6300 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6302 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6303 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6306 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6308 val |= (qGainMismatch) | (iGainMismatch << 6);
6309 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6311 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6312 "ADC Gain Cal done for Chain %d\n", i);
6316 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6317 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6318 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6322 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6324 struct ath_hal_5416 *ahp = AH5416(ah);
6325 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6326 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6327 const struct hal_percal_data *calData =
6328 ahp->ah_cal_list_curr->calData;
6330 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6332 for (i = 0; i < numChains; i++) {
6333 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6334 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6335 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6336 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6338 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6339 "Starting ADC DC Offset Cal for Chain %d\n", i);
6341 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6342 "Chn %d pwr_meas_odd_i = %d\n", i,
6344 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6345 "Chn %d pwr_meas_even_i = %d\n", i,
6347 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6348 "Chn %d pwr_meas_odd_q = %d\n", i,
6350 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6351 "Chn %d pwr_meas_even_q = %d\n", i,
6354 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6355 numSamples) & 0x1ff;
6356 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6357 numSamples) & 0x1ff;
6359 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6360 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6362 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6363 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6366 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6368 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6369 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6371 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6372 "ADC DC Offset Cal done for Chain %d\n", i);
6375 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6376 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6377 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6380 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6382 struct ath_hal_5416 *ahp = AH5416(ah);
6383 struct ath9k_channel *chan = ah->ah_curchan;
6385 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6387 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6388 ath9k_regd_get_ctl(ah, chan),
6389 ath9k_regd_get_antenna_allowed(ah,
6391 chan->maxRegTxPower * 2,
6392 min((u32) MAX_RATE_POWER,
6393 (u32) ah->ah_powerLimit)) != 0)
6400 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6401 struct ath9k_channel *chan,
6402 struct chan_centers *centers)
6405 struct ath_hal_5416 *ahp = AH5416(ah);
6407 if (!IS_CHAN_HT40(chan)) {
6408 centers->ctl_center = centers->ext_center =
6409 centers->synth_center = chan->channel;
6413 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6414 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6415 centers->synth_center =
6416 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6419 centers->synth_center =
6420 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6424 centers->ctl_center = centers->synth_center - (extoff *
6425 HT40_CHANNEL_CENTER_SHIFT);
6426 centers->ext_center = centers->synth_center + (extoff *
6430 ATH9K_HT_EXTPROTSPACING_20)
6432 HT40_CHANNEL_CENTER_SHIFT
6438 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6441 struct ath_hal_5416 *ahp = AH5416(ah);
6442 struct ath9k_channel *ichan =
6443 ath9k_regd_check_channel(ah, chan);
6444 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6448 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6451 if (currCal == NULL)
6454 if (ichan == NULL) {
6455 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6456 "%s: invalid channel %u/0x%x; no mapping\n",
6457 __func__, chan->channel, chan->channelFlags);
6462 if (currCal->calState != CAL_DONE) {
6463 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6464 "%s: Calibration state incorrect, %d\n",
6465 __func__, currCal->calState);
6470 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType)) {
6474 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6475 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6476 __func__, currCal->calData->calType, chan->channel,
6477 chan->channelFlags);
6479 ichan->CalValid &= ~currCal->calData->calType;
6480 currCal->calState = CAL_WAITING;
6485 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6487 struct ath_hal_5416 *ahp = AH5416(ah);
6489 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6492 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6494 struct ath_hal_5416 *ahp = AH5416(ah);
6496 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6500 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6502 struct ath_hal_5416 *ahp = AH5416(ah);
6504 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6508 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6510 struct ath_hal_5416 *ahp = AH5416(ah);
6512 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6514 REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
6515 REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
6520 #ifdef CONFIG_ATH9K_RFKILL
6521 static void ath9k_enable_rfkill(struct ath_hal *ah)
6523 struct ath_hal_5416 *ahp = AH5416(ah);
6525 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6526 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6528 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6529 AR_GPIO_INPUT_MUX2_RFSILENT);
6531 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6532 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6534 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6536 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6539 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6546 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6549 struct ath_hal_5416 *ahp = AH5416(ah);
6551 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6552 ahp->ah_assocId = assocId;
6554 REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
6555 REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4) |
6556 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6559 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6563 tsf = REG_READ(ah, AR_TSF_U32);
6564 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6568 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6573 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6576 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6577 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6583 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6586 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6588 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6591 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6593 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6597 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6598 enum ath9k_ant_setting settings,
6599 struct ath9k_channel *chan,
6604 struct ath_hal_5416 *ahp = AH5416(ah);
6605 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6607 if (AR_SREV_9280(ah)) {
6608 if (!tx_chainmask_cfg) {
6610 tx_chainmask_cfg = *tx_chainmask;
6611 rx_chainmask_cfg = *rx_chainmask;
6615 case ATH9K_ANT_FIXED_A:
6616 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6617 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6618 *antenna_cfgd = true;
6620 case ATH9K_ANT_FIXED_B:
6621 if (ah->ah_caps.halTxChainMask >
6622 ATH9K_ANTENNA1_CHAINMASK) {
6623 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6625 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6626 *antenna_cfgd = true;
6628 case ATH9K_ANT_VARIABLE:
6629 *tx_chainmask = tx_chainmask_cfg;
6630 *rx_chainmask = rx_chainmask_cfg;
6631 *antenna_cfgd = true;
6637 ahp->ah_diversityControl = settings;
6643 void ath9k_hw_setopmode(struct ath_hal *ah)
6645 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6649 ath9k_hw_getcapability(struct ath_hal *ah, enum hal_capability_type type,
6650 u32 capability, u32 *result)
6652 struct ath_hal_5416 *ahp = AH5416(ah);
6653 const struct hal_capabilities *pCap = &ah->ah_caps;
6656 case HAL_CAP_CIPHER:
6657 switch (capability) {
6658 case ATH9K_CIPHER_AES_CCM:
6659 case ATH9K_CIPHER_AES_OCB:
6660 case ATH9K_CIPHER_TKIP:
6661 case ATH9K_CIPHER_WEP:
6662 case ATH9K_CIPHER_MIC:
6663 case ATH9K_CIPHER_CLR:
6668 case HAL_CAP_TKIP_MIC:
6669 switch (capability) {
6673 return (ahp->ah_staId1Defaults &
6674 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6677 case HAL_CAP_TKIP_SPLIT:
6678 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6680 case HAL_CAP_WME_TKIPMIC:
6682 case HAL_CAP_PHYCOUNTERS:
6683 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6684 case HAL_CAP_DIVERSITY:
6685 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6686 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6688 case HAL_CAP_PHYDIAG:
6690 case HAL_CAP_MCAST_KEYSRCH:
6691 switch (capability) {
6695 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6698 return (ahp->ah_staId1Defaults &
6699 AR_STA_ID1_MCAST_KSRCH) ? true :
6704 case HAL_CAP_TSF_ADJUST:
6705 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6707 case HAL_CAP_RFSILENT:
6708 if (capability == 3)
6710 case HAL_CAP_ANT_CFG_2GHZ:
6711 *result = pCap->halNumAntCfg2GHz;
6713 case HAL_CAP_ANT_CFG_5GHZ:
6714 *result = pCap->halNumAntCfg5GHz;
6717 switch (capability) {
6721 *result = ah->ah_powerLimit;
6724 *result = ah->ah_maxPowerLevel;
6727 *result = ah->ah_tpScale;
6737 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6739 struct ath_hal_5416 *ahp = AH5416(ah);
6740 struct ath9k_channel *chan = ah->ah_curchan;
6741 const struct hal_capabilities *pCap = &ah->ah_caps;
6743 u32 halNumAntConfig;
6746 IS_CHAN_2GHZ(chan) ? pCap->halNumAntCfg2GHz : pCap->
6749 if (cfg < halNumAntConfig) {
6750 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6751 cfg, &ant_config)) {
6752 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6760 bool ath9k_hw_intrpend(struct ath_hal *ah)
6764 if (AR_SREV_9100(ah))
6767 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6768 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6771 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6772 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6773 && (host_isr != AR_INTR_SPURIOUS))
6779 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6783 struct hal_capabilities *pCap = &ah->ah_caps;
6785 bool fatal_int = false;
6787 if (!AR_SREV_9100(ah)) {
6788 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6789 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6790 == AR_RTC_STATUS_ON) {
6791 isr = REG_READ(ah, AR_ISR);
6797 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6801 if (!isr && !sync_cause)
6805 isr = REG_READ(ah, AR_ISR);
6809 struct ath_hal_5416 *ahp = AH5416(ah);
6811 if (isr & AR_ISR_BCNMISC) {
6813 isr2 = REG_READ(ah, AR_ISR_S2);
6814 if (isr2 & AR_ISR_S2_TIM)
6815 mask2 |= ATH9K_INT_TIM;
6816 if (isr2 & AR_ISR_S2_DTIM)
6817 mask2 |= ATH9K_INT_DTIM;
6818 if (isr2 & AR_ISR_S2_DTIMSYNC)
6819 mask2 |= ATH9K_INT_DTIMSYNC;
6820 if (isr2 & (AR_ISR_S2_CABEND))
6821 mask2 |= ATH9K_INT_CABEND;
6822 if (isr2 & AR_ISR_S2_GTT)
6823 mask2 |= ATH9K_INT_GTT;
6824 if (isr2 & AR_ISR_S2_CST)
6825 mask2 |= ATH9K_INT_CST;
6828 isr = REG_READ(ah, AR_ISR_RAC);
6829 if (isr == 0xffffffff) {
6834 *masked = isr & ATH9K_INT_COMMON;
6836 if (ahp->ah_intrMitigation) {
6838 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6839 *masked |= ATH9K_INT_RX;
6842 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6843 *masked |= ATH9K_INT_RX;
6845 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6849 *masked |= ATH9K_INT_TX;
6851 s0_s = REG_READ(ah, AR_ISR_S0_S);
6852 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6853 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6855 s1_s = REG_READ(ah, AR_ISR_S1_S);
6856 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6857 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6860 if (isr & AR_ISR_RXORN) {
6861 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6862 "%s: receive FIFO overrun interrupt\n",
6866 if (!AR_SREV_9100(ah)) {
6867 if (!pCap->halAutoSleepSupport) {
6868 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6869 if (isr5 & AR_ISR_S5_TIM_TIMER)
6870 *masked |= ATH9K_INT_TIM_TIMER;
6876 if (AR_SREV_9100(ah))
6881 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6885 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6886 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6887 "%s: received PCI FATAL interrupt\n",
6890 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6891 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6892 "%s: received PCI PERR interrupt\n",
6896 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6897 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6898 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6900 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6901 REG_WRITE(ah, AR_RC, 0);
6902 *masked |= ATH9K_INT_FATAL;
6904 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6905 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6906 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6910 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6911 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6916 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6918 return AH5416(ah)->ah_maskReg;
6921 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6923 struct ath_hal_5416 *ahp = AH5416(ah);
6924 u32 omask = ahp->ah_maskReg;
6926 struct hal_capabilities *pCap = &ah->ah_caps;
6928 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6931 if (omask & ATH9K_INT_GLOBAL) {
6932 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6934 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6935 (void) REG_READ(ah, AR_IER);
6936 if (!AR_SREV_9100(ah)) {
6937 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6938 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6940 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6941 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6945 mask = ints & ATH9K_INT_COMMON;
6948 if (ints & ATH9K_INT_TX) {
6949 if (ahp->ah_txOkInterruptMask)
6950 mask |= AR_IMR_TXOK;
6951 if (ahp->ah_txDescInterruptMask)
6952 mask |= AR_IMR_TXDESC;
6953 if (ahp->ah_txErrInterruptMask)
6954 mask |= AR_IMR_TXERR;
6955 if (ahp->ah_txEolInterruptMask)
6956 mask |= AR_IMR_TXEOL;
6958 if (ints & ATH9K_INT_RX) {
6959 mask |= AR_IMR_RXERR;
6960 if (ahp->ah_intrMitigation)
6961 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6963 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6964 if (!pCap->halAutoSleepSupport)
6965 mask |= AR_IMR_GENTMR;
6968 if (ints & (ATH9K_INT_BMISC)) {
6969 mask |= AR_IMR_BCNMISC;
6970 if (ints & ATH9K_INT_TIM)
6971 mask2 |= AR_IMR_S2_TIM;
6972 if (ints & ATH9K_INT_DTIM)
6973 mask2 |= AR_IMR_S2_DTIM;
6974 if (ints & ATH9K_INT_DTIMSYNC)
6975 mask2 |= AR_IMR_S2_DTIMSYNC;
6976 if (ints & ATH9K_INT_CABEND)
6977 mask2 |= (AR_IMR_S2_CABEND);
6980 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6981 mask |= AR_IMR_BCNMISC;
6982 if (ints & ATH9K_INT_GTT)
6983 mask2 |= AR_IMR_S2_GTT;
6984 if (ints & ATH9K_INT_CST)
6985 mask2 |= AR_IMR_S2_CST;
6988 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
6990 REG_WRITE(ah, AR_IMR, mask);
6991 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
6993 AR_IMR_S2_DTIMSYNC |
6997 AR_IMR_S2_GTT | AR_IMR_S2_CST);
6998 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
6999 ahp->ah_maskReg = ints;
7001 if (!pCap->halAutoSleepSupport) {
7002 if (ints & ATH9K_INT_TIM_TIMER)
7003 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7005 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7008 if (ints & ATH9K_INT_GLOBAL) {
7009 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7011 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7012 if (!AR_SREV_9100(ah)) {
7013 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7015 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7018 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7019 AR_INTR_SYNC_DEFAULT);
7020 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7021 AR_INTR_SYNC_DEFAULT);
7023 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7024 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7031 ath9k_hw_beaconinit(struct ath_hal *ah,
7032 u32 next_beacon, u32 beacon_period)
7034 struct ath_hal_5416 *ahp = AH5416(ah);
7037 ahp->ah_beaconInterval = beacon_period;
7039 switch (ah->ah_opmode) {
7041 case ATH9K_M_MONITOR:
7042 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7043 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7044 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7045 flags |= AR_TBTT_TIMER_EN;
7048 REG_SET_BIT(ah, AR_TXCFG,
7049 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7050 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7051 TU_TO_USEC(next_beacon +
7052 (ahp->ah_atimWindow ? ahp->
7053 ah_atimWindow : 1)));
7054 flags |= AR_NDP_TIMER_EN;
7055 case ATH9K_M_HOSTAP:
7056 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7057 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7058 TU_TO_USEC(next_beacon -
7060 ath_hal_dma_beacon_response_time));
7061 REG_WRITE(ah, AR_NEXT_SWBA,
7062 TU_TO_USEC(next_beacon -
7064 ath_hal_sw_beacon_response_time));
7066 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7070 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7071 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7072 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7073 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7075 beacon_period &= ~ATH9K_BEACON_ENA;
7076 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7077 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7078 ath9k_hw_reset_tsf(ah);
7081 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7085 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7086 const struct ath9k_beacon_state *bs)
7088 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7089 struct hal_capabilities *pCap = &ah->ah_caps;
7091 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7093 REG_WRITE(ah, AR_BEACON_PERIOD,
7094 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7095 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7096 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7098 REG_RMW_FIELD(ah, AR_RSSI_THR,
7099 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7101 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7103 if (bs->bs_sleepduration > beaconintval)
7104 beaconintval = bs->bs_sleepduration;
7106 dtimperiod = bs->bs_dtimperiod;
7107 if (bs->bs_sleepduration > dtimperiod)
7108 dtimperiod = bs->bs_sleepduration;
7110 if (beaconintval == dtimperiod)
7111 nextTbtt = bs->bs_nextdtim;
7113 nextTbtt = bs->bs_nexttbtt;
7115 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7117 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7119 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7121 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7124 REG_WRITE(ah, AR_NEXT_DTIM,
7125 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7126 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7128 REG_WRITE(ah, AR_SLEEP1,
7129 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7130 | AR_SLEEP1_ASSUME_DTIM);
7132 if (pCap->halAutoSleepSupport)
7133 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7135 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7137 REG_WRITE(ah, AR_SLEEP2,
7138 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7140 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7141 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7143 REG_SET_BIT(ah, AR_TIMER_MODE,
7144 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7149 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7151 if (entry < ah->ah_caps.halKeyCacheSize) {
7152 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7153 if (val & AR_KEYTABLE_VALID)
7159 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7163 if (entry >= ah->ah_caps.halKeyCacheSize) {
7164 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7165 "%s: entry %u out of range\n", __func__, entry);
7168 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7170 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7171 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7172 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7173 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7174 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7175 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7176 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7177 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7179 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7180 u16 micentry = entry + 64;
7182 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7183 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7184 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7185 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7189 if (ah->ah_curchan == NULL)
7196 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7201 if (entry >= ah->ah_caps.halKeyCacheSize) {
7202 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7203 "%s: entry %u out of range\n", __func__, entry);
7208 macHi = (mac[5] << 8) | mac[4];
7209 macLo = (mac[3] << 24) | (mac[2] << 16)
7210 | (mac[1] << 8) | mac[0];
7212 macLo |= (macHi & 1) << 31;
7217 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7218 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7224 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7225 const struct ath9k_keyval *k,
7226 const u8 *mac, int xorKey)
7228 const struct hal_capabilities *pCap = &ah->ah_caps;
7229 u32 key0, key1, key2, key3, key4;
7231 u32 xorMask = xorKey ?
7232 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7233 | ATH9K_KEY_XOR) : 0;
7234 struct ath_hal_5416 *ahp = AH5416(ah);
7236 if (entry >= pCap->halKeyCacheSize) {
7237 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7238 "%s: entry %u out of range\n", __func__, entry);
7241 switch (k->kv_type) {
7242 case ATH9K_CIPHER_AES_OCB:
7243 keyType = AR_KEYTABLE_TYPE_AES;
7245 case ATH9K_CIPHER_AES_CCM:
7246 if (!pCap->halCipherAesCcmSupport) {
7247 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7248 "%s: AES-CCM not supported by "
7249 "mac rev 0x%x\n", __func__,
7253 keyType = AR_KEYTABLE_TYPE_CCM;
7255 case ATH9K_CIPHER_TKIP:
7256 keyType = AR_KEYTABLE_TYPE_TKIP;
7257 if (ATH9K_IS_MIC_ENABLED(ah)
7258 && entry + 64 >= pCap->halKeyCacheSize) {
7259 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260 "%s: entry %u inappropriate for TKIP\n",
7265 case ATH9K_CIPHER_WEP:
7266 if (k->kv_len < 40 / NBBY) {
7267 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7268 "%s: WEP key length %u too small\n",
7269 __func__, k->kv_len);
7272 if (k->kv_len <= 40 / NBBY)
7273 keyType = AR_KEYTABLE_TYPE_40;
7274 else if (k->kv_len <= 104 / NBBY)
7275 keyType = AR_KEYTABLE_TYPE_104;
7277 keyType = AR_KEYTABLE_TYPE_128;
7279 case ATH9K_CIPHER_CLR:
7280 keyType = AR_KEYTABLE_TYPE_CLR;
7283 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7284 "%s: cipher %u not supported\n", __func__,
7289 key0 = LE_READ_4(k->kv_val + 0) ^ xorMask;
7290 key1 = (LE_READ_2(k->kv_val + 4) ^ xorMask) & 0xffff;
7291 key2 = LE_READ_4(k->kv_val + 6) ^ xorMask;
7292 key3 = (LE_READ_2(k->kv_val + 10) ^ xorMask) & 0xffff;
7293 key4 = LE_READ_4(k->kv_val + 12) ^ xorMask;
7294 if (k->kv_len <= 104 / NBBY)
7297 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7298 u16 micentry = entry + 64;
7300 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7301 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7302 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7303 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7304 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7305 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7306 (void) ath9k_hw_keysetmac(ah, entry, mac);
7308 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7309 u32 mic0, mic1, mic2, mic3, mic4;
7311 mic0 = LE_READ_4(k->kv_mic + 0);
7312 mic2 = LE_READ_4(k->kv_mic + 4);
7313 mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff;
7314 mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff;
7315 mic4 = LE_READ_4(k->kv_txmic + 4);
7316 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7317 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7318 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7319 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7320 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7321 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7322 AR_KEYTABLE_TYPE_CLR);
7327 mic0 = LE_READ_4(k->kv_mic + 0);
7328 mic2 = LE_READ_4(k->kv_mic + 4);
7329 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7330 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7331 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7332 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7333 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7334 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7335 AR_KEYTABLE_TYPE_CLR);
7337 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7338 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7342 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7343 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7344 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7345 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7346 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7347 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7349 (void) ath9k_hw_keysetmac(ah, entry, mac);
7352 if (ah->ah_curchan == NULL)
7359 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7361 struct ath_hal_5416 *ahp = AH5416(ah);
7362 u32 txcfg, curLevel, newLevel;
7363 enum ath9k_int omask;
7365 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7368 omask = ath9k_hw_set_interrupts(ah,
7369 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7371 txcfg = REG_READ(ah, AR_TXCFG);
7372 curLevel = MS(txcfg, AR_FTRIG);
7373 newLevel = curLevel;
7374 if (bIncTrigLevel) {
7375 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7377 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7379 if (newLevel != curLevel)
7380 REG_WRITE(ah, AR_TXCFG,
7381 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7383 ath9k_hw_set_interrupts(ah, omask);
7385 ah->ah_txTrigLevel = newLevel;
7387 return newLevel != curLevel;
7390 static bool ath9k_hw_set_txq_props(struct ath_hal *ah,
7391 struct ath9k_tx_queue_info *qi,
7392 const struct ath9k_txq_info *qInfo)
7396 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7397 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7402 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7404 qi->tqi_ver = qInfo->tqi_ver;
7405 qi->tqi_subtype = qInfo->tqi_subtype;
7406 qi->tqi_qflags = qInfo->tqi_qflags;
7407 qi->tqi_priority = qInfo->tqi_priority;
7408 if (qInfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7409 qi->tqi_aifs = min(qInfo->tqi_aifs, 255U);
7411 qi->tqi_aifs = INIT_AIFS;
7412 if (qInfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7413 cw = min(qInfo->tqi_cwmin, 1024U);
7415 while (qi->tqi_cwmin < cw)
7416 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7418 qi->tqi_cwmin = qInfo->tqi_cwmin;
7419 if (qInfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7420 cw = min(qInfo->tqi_cwmax, 1024U);
7422 while (qi->tqi_cwmax < cw)
7423 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7425 qi->tqi_cwmax = INIT_CWMAX;
7427 if (qInfo->tqi_shretry != 0)
7428 qi->tqi_shretry = min((u32) qInfo->tqi_shretry, 15U);
7430 qi->tqi_shretry = INIT_SH_RETRY;
7431 if (qInfo->tqi_lgretry != 0)
7432 qi->tqi_lgretry = min((u32) qInfo->tqi_lgretry, 15U);
7434 qi->tqi_lgretry = INIT_LG_RETRY;
7435 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
7436 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
7437 qi->tqi_burstTime = qInfo->tqi_burstTime;
7438 qi->tqi_readyTime = qInfo->tqi_readyTime;
7440 switch (qInfo->tqi_subtype) {
7441 case ATH9K_WME_UPSD:
7442 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7443 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7451 bool ath9k_hw_settxqueueprops(struct ath_hal *ah, int q,
7452 const struct ath9k_txq_info *qInfo)
7454 struct ath_hal_5416 *ahp = AH5416(ah);
7455 struct hal_capabilities *pCap = &ah->ah_caps;
7457 if (q >= pCap->halTotalQueues) {
7458 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7462 return ath9k_hw_set_txq_props(ah, &ahp->ah_txq[q], qInfo);
7465 static bool ath9k_hw_get_txq_props(struct ath_hal *ah,
7466 struct ath9k_txq_info *qInfo,
7467 const struct ath9k_tx_queue_info *qi)
7469 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7470 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7475 qInfo->tqi_qflags = qi->tqi_qflags;
7476 qInfo->tqi_ver = qi->tqi_ver;
7477 qInfo->tqi_subtype = qi->tqi_subtype;
7478 qInfo->tqi_qflags = qi->tqi_qflags;
7479 qInfo->tqi_priority = qi->tqi_priority;
7480 qInfo->tqi_aifs = qi->tqi_aifs;
7481 qInfo->tqi_cwmin = qi->tqi_cwmin;
7482 qInfo->tqi_cwmax = qi->tqi_cwmax;
7483 qInfo->tqi_shretry = qi->tqi_shretry;
7484 qInfo->tqi_lgretry = qi->tqi_lgretry;
7485 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7486 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7487 qInfo->tqi_burstTime = qi->tqi_burstTime;
7488 qInfo->tqi_readyTime = qi->tqi_readyTime;
7494 ath9k_hw_gettxqueueprops(struct ath_hal *ah, int q,
7495 struct ath9k_txq_info *qInfo)
7497 struct ath_hal_5416 *ahp = AH5416(ah);
7498 struct hal_capabilities *pCap = &ah->ah_caps;
7500 if (q >= pCap->halTotalQueues) {
7501 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7505 return ath9k_hw_get_txq_props(ah, qInfo, &ahp->ah_txq[q]);
7509 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7510 const struct ath9k_txq_info *qInfo)
7512 struct ath_hal_5416 *ahp = AH5416(ah);
7513 struct ath9k_tx_queue_info *qi;
7514 struct hal_capabilities *pCap = &ah->ah_caps;
7518 case ATH9K_TX_QUEUE_BEACON:
7519 q = pCap->halTotalQueues - 1;
7521 case ATH9K_TX_QUEUE_CAB:
7522 q = pCap->halTotalQueues - 2;
7524 case ATH9K_TX_QUEUE_PSPOLL:
7527 case ATH9K_TX_QUEUE_UAPSD:
7528 q = pCap->halTotalQueues - 3;
7530 case ATH9K_TX_QUEUE_DATA:
7531 for (q = 0; q < pCap->halTotalQueues; q++)
7532 if (ahp->ah_txq[q].tqi_type ==
7533 ATH9K_TX_QUEUE_INACTIVE)
7535 if (q == pCap->halTotalQueues) {
7536 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7537 "%s: no available tx queue\n", __func__);
7542 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7547 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7549 qi = &ahp->ah_txq[q];
7550 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7551 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7552 "%s: tx queue %u already active\n", __func__, q);
7555 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7556 qi->tqi_type = type;
7557 if (qInfo == NULL) {
7559 TXQ_FLAG_TXOKINT_ENABLE
7560 | TXQ_FLAG_TXERRINT_ENABLE
7561 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7562 qi->tqi_aifs = INIT_AIFS;
7563 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7564 qi->tqi_cwmax = INIT_CWMAX;
7565 qi->tqi_shretry = INIT_SH_RETRY;
7566 qi->tqi_lgretry = INIT_LG_RETRY;
7567 qi->tqi_physCompBuf = 0;
7569 qi->tqi_physCompBuf = qInfo->tqi_compBuf;
7570 (void) ath9k_hw_settxqueueprops(ah, q, qInfo);
7577 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7578 struct ath9k_tx_queue_info *qi)
7580 struct ath_hal_5416 *ahp = AH5416(ah);
7582 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7583 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7584 __func__, ahp->ah_txOkInterruptMask,
7585 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7586 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7588 REG_WRITE(ah, AR_IMR_S0,
7589 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7590 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7591 REG_WRITE(ah, AR_IMR_S1,
7592 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7593 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7594 REG_RMW_FIELD(ah, AR_IMR_S2,
7595 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7598 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7600 struct ath_hal_5416 *ahp = AH5416(ah);
7601 struct hal_capabilities *pCap = &ah->ah_caps;
7602 struct ath9k_tx_queue_info *qi;
7604 if (q >= pCap->halTotalQueues) {
7605 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7609 qi = &ahp->ah_txq[q];
7610 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7611 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7616 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7619 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7620 ahp->ah_txOkInterruptMask &= ~(1 << q);
7621 ahp->ah_txErrInterruptMask &= ~(1 << q);
7622 ahp->ah_txDescInterruptMask &= ~(1 << q);
7623 ahp->ah_txEolInterruptMask &= ~(1 << q);
7624 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7625 ath9k_hw_set_txq_interrupts(ah, qi);
7630 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7632 struct ath_hal_5416 *ahp = AH5416(ah);
7633 struct hal_capabilities *pCap = &ah->ah_caps;
7634 struct ath9k_channel *chan = ah->ah_curchan;
7635 struct ath9k_tx_queue_info *qi;
7636 u32 cwMin, chanCwMin, value;
7638 if (q >= pCap->halTotalQueues) {
7639 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7643 qi = &ahp->ah_txq[q];
7644 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7645 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7650 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7652 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7653 if (chan && IS_CHAN_B(chan))
7654 chanCwMin = INIT_CWMIN_11B;
7656 chanCwMin = INIT_CWMIN;
7658 for (cwMin = 1; cwMin < chanCwMin;
7659 cwMin = (cwMin << 1) | 1);
7661 cwMin = qi->tqi_cwmin;
7663 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7664 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7665 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7667 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7668 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7669 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7670 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7673 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7674 REG_WRITE(ah, AR_DMISC(q),
7675 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7677 if (qi->tqi_cbrPeriod) {
7678 REG_WRITE(ah, AR_QCBRCFG(q),
7679 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7680 | SM(qi->tqi_cbrOverflowLimit,
7681 AR_Q_CBRCFG_OVF_THRESH));
7682 REG_WRITE(ah, AR_QMISC(q),
7684 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7685 tqi_cbrOverflowLimit
7687 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7691 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7692 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7693 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7694 AR_Q_RDYTIMECFG_EN);
7697 REG_WRITE(ah, AR_DCHNTIME(q),
7698 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7699 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7701 if (qi->tqi_burstTime
7702 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7703 REG_WRITE(ah, AR_QMISC(q),
7706 AR_Q_MISC_RDYTIME_EXP_POLICY);
7710 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7711 REG_WRITE(ah, AR_DMISC(q),
7712 REG_READ(ah, AR_DMISC(q)) |
7713 AR_D_MISC_POST_FR_BKOFF_DIS);
7715 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7716 REG_WRITE(ah, AR_DMISC(q),
7717 REG_READ(ah, AR_DMISC(q)) |
7718 AR_D_MISC_FRAG_BKOFF_EN);
7720 switch (qi->tqi_type) {
7721 case ATH9K_TX_QUEUE_BEACON:
7722 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7723 | AR_Q_MISC_FSP_DBA_GATED
7724 | AR_Q_MISC_BEACON_USE
7725 | AR_Q_MISC_CBR_INCR_DIS1);
7727 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7728 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7729 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7730 | AR_D_MISC_BEACON_USE
7731 | AR_D_MISC_POST_FR_BKOFF_DIS);
7733 case ATH9K_TX_QUEUE_CAB:
7734 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7735 | AR_Q_MISC_FSP_DBA_GATED
7736 | AR_Q_MISC_CBR_INCR_DIS1
7737 | AR_Q_MISC_CBR_INCR_DIS0);
7738 value = (qi->tqi_readyTime
7739 - (ah->ah_config.ath_hal_sw_beacon_response_time -
7740 ah->ah_config.ath_hal_dma_beacon_response_time)
7742 ah->ah_config.ath_hal_additional_swba_backoff) *
7744 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7745 value | AR_Q_RDYTIMECFG_EN);
7746 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7747 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7748 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7750 case ATH9K_TX_QUEUE_PSPOLL:
7751 REG_WRITE(ah, AR_QMISC(q),
7753 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7755 case ATH9K_TX_QUEUE_UAPSD:
7756 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7757 | AR_D_MISC_POST_FR_BKOFF_DIS);
7763 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7764 REG_WRITE(ah, AR_DMISC(q),
7765 REG_READ(ah, AR_DMISC(q)) |
7766 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7767 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7768 AR_D_MISC_POST_FR_BKOFF_DIS);
7771 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7772 ahp->ah_txOkInterruptMask |= 1 << q;
7774 ahp->ah_txOkInterruptMask &= ~(1 << q);
7775 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7776 ahp->ah_txErrInterruptMask |= 1 << q;
7778 ahp->ah_txErrInterruptMask &= ~(1 << q);
7779 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7780 ahp->ah_txDescInterruptMask |= 1 << q;
7782 ahp->ah_txDescInterruptMask &= ~(1 << q);
7783 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7784 ahp->ah_txEolInterruptMask |= 1 << q;
7786 ahp->ah_txEolInterruptMask &= ~(1 << q);
7787 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7788 ahp->ah_txUrnInterruptMask |= 1 << q;
7790 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7791 ath9k_hw_set_txq_interrupts(ah, qi);
7796 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7798 struct ath_hal_5416 *ahp = AH5416(ah);
7799 *txqs &= ahp->ah_intrTxqs;
7800 ahp->ah_intrTxqs &= ~(*txqs);
7804 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7805 u32 segLen, bool firstSeg,
7806 bool lastSeg, const struct ath_desc *ds0)
7808 struct ar5416_desc *ads = AR5416DESC(ds);
7811 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7812 } else if (lastSeg) {
7814 ads->ds_ctl1 = segLen;
7815 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7816 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7819 ads->ds_ctl1 = segLen | AR_TxMore;
7823 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7824 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7825 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7826 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7827 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7831 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7833 struct ar5416_desc *ads = AR5416DESC(ds);
7835 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7836 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7837 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7838 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7839 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7843 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7845 struct ar5416_desc *ads = AR5416DESC(ds);
7847 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7848 return -EINPROGRESS;
7850 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7851 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7852 ds->ds_txstat.ts_status = 0;
7853 ds->ds_txstat.ts_flags = 0;
7855 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7856 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7857 if (ads->ds_txstatus1 & AR_Filtered)
7858 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7859 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7860 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7861 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7862 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7863 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7864 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7866 if (ads->ds_txstatus1 & AR_DescCfgErr)
7867 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7868 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7869 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7870 ath9k_hw_updatetxtriglevel(ah, true);
7872 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7873 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7874 ath9k_hw_updatetxtriglevel(ah, true);
7876 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7877 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7878 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7879 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7882 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7883 switch (ds->ds_txstat.ts_rateindex) {
7885 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7888 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7891 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7894 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7898 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7899 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7900 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7901 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7902 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7903 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7904 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7905 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7906 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7907 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7908 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7909 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7910 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7911 ds->ds_txstat.ts_antenna = 1;
7917 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7918 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7919 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7921 struct ar5416_desc *ads = AR5416DESC(ds);
7922 struct ath_hal_5416 *ahp = AH5416(ah);
7924 txPower += ahp->ah_txPowerIndexOffset;
7928 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7929 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7930 | SM(txPower, AR_XmitPower)
7931 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7932 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7933 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7934 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7937 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7938 | SM(type, AR_FrameType)
7939 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7940 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7941 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7943 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7945 if (AR_SREV_9285(ah)) {
7955 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7956 struct ath_desc *lastds,
7957 u32 durUpdateEn, u32 rtsctsRate,
7959 struct ath9k_11n_rate_series series[],
7960 u32 nseries, u32 flags)
7962 struct ar5416_desc *ads = AR5416DESC(ds);
7963 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7967 (void) rtsctsDuration;
7969 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7970 ds_ctl0 = ads->ds_ctl0;
7972 if (flags & ATH9K_TXDESC_RTSENA) {
7973 ds_ctl0 &= ~AR_CTSEnable;
7974 ds_ctl0 |= AR_RTSEnable;
7976 ds_ctl0 &= ~AR_RTSEnable;
7977 ds_ctl0 |= AR_CTSEnable;
7980 ads->ds_ctl0 = ds_ctl0;
7983 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7986 ads->ds_ctl2 = set11nTries(series, 0)
7987 | set11nTries(series, 1)
7988 | set11nTries(series, 2)
7989 | set11nTries(series, 3)
7990 | (durUpdateEn ? AR_DurUpdateEna : 0)
7991 | SM(0, AR_BurstDur);
7993 ads->ds_ctl3 = set11nRate(series, 0)
7994 | set11nRate(series, 1)
7995 | set11nRate(series, 2)
7996 | set11nRate(series, 3);
7998 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
7999 | set11nPktDurRTSCTS(series, 1);
8001 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8002 | set11nPktDurRTSCTS(series, 3);
8004 ads->ds_ctl7 = set11nRateFlags(series, 0)
8005 | set11nRateFlags(series, 1)
8006 | set11nRateFlags(series, 2)
8007 | set11nRateFlags(series, 3)
8008 | SM(rtsctsRate, AR_RTSCTSRate);
8009 last_ads->ds_ctl2 = ads->ds_ctl2;
8010 last_ads->ds_ctl3 = ads->ds_ctl3;
8014 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8017 struct ar5416_desc *ads = AR5416DESC(ds);
8019 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8021 ads->ds_ctl6 &= ~AR_AggrLen;
8022 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8026 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8029 struct ar5416_desc *ads = AR5416DESC(ds);
8032 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8034 ctl6 = ads->ds_ctl6;
8035 ctl6 &= ~AR_PadDelim;
8036 ctl6 |= SM(numDelims, AR_PadDelim);
8037 ads->ds_ctl6 = ctl6;
8040 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8042 struct ar5416_desc *ads = AR5416DESC(ds);
8044 ads->ds_ctl1 |= AR_IsAggr;
8045 ads->ds_ctl1 &= ~AR_MoreAggr;
8046 ads->ds_ctl6 &= ~AR_PadDelim;
8049 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8051 struct ar5416_desc *ads = AR5416DESC(ds);
8053 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8057 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8060 struct ar5416_desc *ads = AR5416DESC(ds);
8062 ads->ds_ctl2 &= ~AR_BurstDur;
8063 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8067 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8070 struct ar5416_desc *ads = AR5416DESC(ds);
8073 ads->ds_ctl0 |= AR_VirtMoreFrag;
8075 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8078 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8080 REG_WRITE(ah, AR_RXDP, rxdp);
8083 void ath9k_hw_rxena(struct ath_hal *ah)
8085 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8088 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8092 REG_SET_BIT(ah, AR_DIAG_SW,
8093 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8096 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8099 REG_CLR_BIT(ah, AR_DIAG_SW,
8103 reg = REG_READ(ah, AR_OBS_BUS_1);
8104 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8105 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8111 REG_CLR_BIT(ah, AR_DIAG_SW,
8112 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8119 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8122 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8123 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8127 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8128 u32 size, u32 flags)
8130 struct ar5416_desc *ads = AR5416DESC(ds);
8131 struct hal_capabilities *pCap = &ah->ah_caps;
8133 ads->ds_ctl1 = size & AR_BufLen;
8134 if (flags & ATH9K_RXDESC_INTREQ)
8135 ads->ds_ctl1 |= AR_RxIntrReq;
8137 ads->ds_rxstatus8 &= ~AR_RxDone;
8138 if (!pCap->halAutoSleepSupport)
8139 memset(&(ads->u), 0, sizeof(ads->u));
8144 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8145 u32 pa, struct ath_desc *nds, u64 tsf)
8147 struct ar5416_desc ads;
8148 struct ar5416_desc *adsp = AR5416DESC(ds);
8150 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8151 return -EINPROGRESS;
8153 ads.u.rx = adsp->u.rx;
8155 ds->ds_rxstat.rs_status = 0;
8156 ds->ds_rxstat.rs_flags = 0;
8158 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8159 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8161 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8162 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8163 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8164 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8165 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8166 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8167 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8168 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8169 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8171 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8173 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8174 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8176 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8177 ds->ds_rxstat.rs_moreaggr =
8178 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8179 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8180 ds->ds_rxstat.rs_flags =
8181 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8182 ds->ds_rxstat.rs_flags |=
8183 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8185 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8186 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8187 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8188 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8189 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8190 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8192 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8194 if (ads.ds_rxstatus8 & AR_CRCErr)
8195 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8196 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8199 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8200 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8201 ds->ds_rxstat.rs_phyerr = phyerr;
8202 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8203 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8204 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8205 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8211 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8212 struct ath9k_rate_table *rt)
8216 if (rt->rateCodeToIndex[0] != 0)
8218 for (i = 0; i < 256; i++)
8219 rt->rateCodeToIndex[i] = (u8) -1;
8220 for (i = 0; i < rt->rateCount; i++) {
8221 u8 code = rt->info[i].rateCode;
8222 u8 cix = rt->info[i].controlRate;
8224 rt->rateCodeToIndex[code] = i;
8225 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8227 rt->info[i].lpAckDuration =
8228 ath9k_hw_computetxtime(ah, rt,
8229 WLAN_CTRL_FRAME_SIZE,
8232 rt->info[i].spAckDuration =
8233 ath9k_hw_computetxtime(ah, rt,
8234 WLAN_CTRL_FRAME_SIZE,
8240 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8243 struct ath9k_rate_table *rt;
8245 case ATH9K_MODE_SEL_11A:
8246 rt = &ar5416_11a_table;
8248 case ATH9K_MODE_SEL_11B:
8249 rt = &ar5416_11b_table;
8251 case ATH9K_MODE_SEL_11G:
8252 rt = &ar5416_11g_table;
8254 case ATH9K_MODE_SEL_11NG_HT20:
8255 case ATH9K_MODE_SEL_11NG_HT40PLUS:
8256 case ATH9K_MODE_SEL_11NG_HT40MINUS:
8257 rt = &ar5416_11ng_table;
8259 case ATH9K_MODE_SEL_11NA_HT20:
8260 case ATH9K_MODE_SEL_11NA_HT40PLUS:
8261 case ATH9K_MODE_SEL_11NA_HT40MINUS:
8262 rt = &ar5416_11na_table;
8265 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8269 ath9k_hw_setup_rate_table(ah, rt);
8273 static const char *ath9k_hw_devname(u16 devid)
8276 case AR5416_DEVID_PCI:
8277 case AR5416_DEVID_PCIE:
8278 return "Atheros 5416";
8279 case AR9160_DEVID_PCI:
8280 return "Atheros 9160";
8281 case AR9280_DEVID_PCI:
8282 case AR9280_DEVID_PCIE:
8283 return "Atheros 9280";
8288 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8290 return vendorid == ATHEROS_VENDOR_ID ?
8291 ath9k_hw_devname(devid) : NULL;
8294 struct ath_hal *ath9k_hw_attach(u16 devid,
8295 struct ath_softc *sc,
8299 struct ath_hal *ah = NULL;
8302 case AR5416_DEVID_PCI:
8303 case AR5416_DEVID_PCIE:
8304 case AR9160_DEVID_PCI:
8305 case AR9280_DEVID_PCI:
8306 case AR9280_DEVID_PCIE:
8307 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8310 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8311 "devid=0x%x not supported.\n", devid);
8317 ah->ah_devid = ah->ah_devid;
8318 ah->ah_subvendorid = ah->ah_subvendorid;
8319 ah->ah_macVersion = ah->ah_macVersion;
8320 ah->ah_macRev = ah->ah_macRev;
8321 ah->ah_phyRev = ah->ah_phyRev;
8322 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8323 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8329 ath9k_hw_computetxtime(struct ath_hal *ah,
8330 const struct ath9k_rate_table *rates,
8331 u32 frameLen, u16 rateix,
8334 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8337 kbps = rates->info[rateix].rateKbps;
8341 switch (rates->info[rateix].phy) {
8344 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8345 if (shortPreamble && rates->info[rateix].shortPreamble)
8347 numBits = frameLen << 3;
8348 txTime = CCK_SIFS_TIME + phyTime
8349 + ((numBits * 1000) / kbps);
8352 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8354 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8356 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8357 numSymbols = howmany(numBits, bitsPerSymbol);
8358 txTime = OFDM_SIFS_TIME_QUARTER
8359 + OFDM_PREAMBLE_TIME_QUARTER
8360 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8361 } else if (ah->ah_curchan &&
8362 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8364 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8366 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8367 numSymbols = howmany(numBits, bitsPerSymbol);
8368 txTime = OFDM_SIFS_TIME_HALF +
8369 OFDM_PREAMBLE_TIME_HALF
8370 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8372 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8374 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8375 numSymbols = howmany(numBits, bitsPerSymbol);
8376 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8377 + (numSymbols * OFDM_SYMBOL_TIME);
8382 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8383 "%s: unknown phy %u (rate ix %u)\n", __func__,
8384 rates->info[rateix].phy, rateix);
8391 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8393 if (flags & CHANNEL_2GHZ) {
8397 return (freq - 2407) / 5;
8399 return 15 + ((freq - 2512) / 20);
8400 } else if (flags & CHANNEL_5GHZ) {
8401 if (ath9k_regd_is_public_safety_sku(ah) &&
8402 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8403 return ((freq * 10) +
8404 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8405 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8406 return (freq - 4000) / 5;
8408 return (freq - 5000) / 5;
8414 return (freq - 2407) / 5;
8416 if (ath9k_regd_is_public_safety_sku(ah)
8417 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8418 return ((freq * 10) +
8420 2) ? 5 : 0) - 49400) / 5;
8421 } else if (freq > 4900) {
8422 return (freq - 4000) / 5;
8424 return 15 + ((freq - 2512) / 20);
8427 return (freq - 5000) / 5;
8432 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8434 struct ath9k_channel *ichan;
8436 ichan = ath9k_regd_check_channel(ah, chan);
8437 if (ichan == NULL) {
8438 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8439 "%s: invalid channel %u/0x%x; no mapping\n",
8440 __func__, chan->channel, chan->channelFlags);
8443 if (ichan->rawNoiseFloor == 0) {
8444 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8445 return NOISE_FLOOR[mode];
8447 return ichan->rawNoiseFloor;
8450 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8452 struct ath_hal_5416 *ahp = AH5416(ah);
8455 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8457 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8461 bool ath9k_hw_phycounters(struct ath_hal *ah)
8463 struct ath_hal_5416 *ahp = AH5416(ah);
8465 return ahp->ah_hasHwPhyCounters ? true : false;
8468 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8470 return REG_READ(ah, AR_QTXDP(q));
8473 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8476 REG_WRITE(ah, AR_QTXDP(q), txdp);
8481 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8483 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8485 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8490 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8494 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8497 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8503 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8507 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8509 for (wait = 1000; wait != 0; wait--) {
8510 if (ath9k_hw_numtxpending(ah, q) == 0)
8515 if (ath9k_hw_numtxpending(ah, q)) {
8518 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8519 "%s: Num of pending TX Frames %d on Q %d\n",
8520 __func__, ath9k_hw_numtxpending(ah, q), q);
8522 for (j = 0; j < 2; j++) {
8523 tsfLow = REG_READ(ah, AR_TSF_L32);
8524 REG_WRITE(ah, AR_QUIET2,
8525 SM(10, AR_QUIET2_QUIET_DUR));
8526 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8527 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8528 REG_SET_BIT(ah, AR_TIMER_MODE,
8531 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8535 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8536 "%s: TSF have moved while trying to set "
8537 "quiet time TSF: 0x%08x\n",
8541 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8544 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8548 while (ath9k_hw_numtxpending(ah, q)) {
8549 if ((--wait) == 0) {
8550 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8551 "%s: Failed to stop Tx DMA in 100 "
8552 "msec after killing last frame\n",
8559 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8562 REG_WRITE(ah, AR_Q_TXD, 0);