ath9k: Remove redundant data structure ath9k_txq_info
[deliverable/linux.git] / drivers / net / wireless / ath9k / hw.c
CommitLineData
f078f209
LR
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
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.
7 *
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.
15 */
16
17#include <linux/io.h>
18#include <asm/unaligned.h>
19
20#include "core.h"
21#include "hw.h"
22#include "reg.h"
23#include "phy.h"
24#include "initvals.h"
25
26static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
27static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
28static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
29static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
30 u8 numChains);
31static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
32static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
33 u8 numChains);
34
35static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
36static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
37
38static const struct hal_percal_data iq_cal_multi_sample = {
39 IQ_MISMATCH_CAL,
40 MAX_CAL_SAMPLES,
41 PER_MIN_LOG_COUNT,
42 ath9k_hw_iqcal_collect,
43 ath9k_hw_iqcalibrate
44};
45static const struct hal_percal_data iq_cal_single_sample = {
46 IQ_MISMATCH_CAL,
47 MIN_CAL_SAMPLES,
48 PER_MAX_LOG_COUNT,
49 ath9k_hw_iqcal_collect,
50 ath9k_hw_iqcalibrate
51};
52static const struct hal_percal_data adc_gain_cal_multi_sample = {
53 ADC_GAIN_CAL,
54 MAX_CAL_SAMPLES,
55 PER_MIN_LOG_COUNT,
56 ath9k_hw_adc_gaincal_collect,
57 ath9k_hw_adc_gaincal_calibrate
58};
59static const struct hal_percal_data adc_gain_cal_single_sample = {
60 ADC_GAIN_CAL,
61 MIN_CAL_SAMPLES,
62 PER_MAX_LOG_COUNT,
63 ath9k_hw_adc_gaincal_collect,
64 ath9k_hw_adc_gaincal_calibrate
65};
66static const struct hal_percal_data adc_dc_cal_multi_sample = {
67 ADC_DC_CAL,
68 MAX_CAL_SAMPLES,
69 PER_MIN_LOG_COUNT,
70 ath9k_hw_adc_dccal_collect,
71 ath9k_hw_adc_dccal_calibrate
72};
73static const struct hal_percal_data adc_dc_cal_single_sample = {
74 ADC_DC_CAL,
75 MIN_CAL_SAMPLES,
76 PER_MAX_LOG_COUNT,
77 ath9k_hw_adc_dccal_collect,
78 ath9k_hw_adc_dccal_calibrate
79};
80static const struct hal_percal_data adc_init_dc_cal = {
81 ADC_DC_INIT_CAL,
82 MIN_CAL_SAMPLES,
83 INIT_LOG_COUNT,
84 ath9k_hw_adc_dccal_collect,
85 ath9k_hw_adc_dccal_calibrate
86};
87
88static const struct ath_hal ar5416hal = {
89 AR5416_MAGIC,
90 0,
91 0,
92 NULL,
93 NULL,
94 CTRY_DEFAULT,
95 0,
96 0,
97 0,
98 0,
99 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,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 },
109};
110
111static struct ath9k_rate_table ar5416_11a_table = {
112 8,
113 {0},
114 {
115 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
116 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
117 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
118 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
119 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
120 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
121 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
122 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
123 },
124};
125
126static struct ath9k_rate_table ar5416_11b_table = {
127 4,
128 {0},
129 {
130 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
131 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
132 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
133 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
134 },
135};
136
137static struct ath9k_rate_table ar5416_11g_table = {
138 12,
139 {0},
140 {
141 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
142 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
143 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
144 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
145
146 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
147 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
148 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
149 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
150 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
151 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
152 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
153 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
154 },
155};
156
157static struct ath9k_rate_table ar5416_11ng_table = {
158 28,
159 {0},
160 {
161 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
162 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
163 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
164 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
165
166 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
167 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
168 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
169 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
170 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
171 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
172 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
173 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
174 {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
175 {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
176 {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
177 {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
178 {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
179 {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
180 {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
181 {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
182 {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
183 {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
184 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
185 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
186 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
187 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
188 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
189 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
190 },
191};
192
193static struct ath9k_rate_table ar5416_11na_table = {
194 24,
195 {0},
196 {
197 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
198 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
199 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
200 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
201 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
202 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
203 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
204 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
205 {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
206 {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
207 {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
208 {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
209 {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
210 {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
211 {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
212 {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
213 {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
214 {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
215 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
216 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
217 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
218 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
219 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
220 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
221 },
222};
223
224static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
225 const struct ath9k_channel *chan)
226{
227 if (IS_CHAN_CCK(chan))
228 return WIRELESS_MODE_11b;
229 if (IS_CHAN_G(chan))
230 return WIRELESS_MODE_11g;
231 return WIRELESS_MODE_11a;
232}
233
234static bool ath9k_hw_wait(struct ath_hal *ah,
235 u32 reg,
236 u32 mask,
237 u32 val)
238{
239 int i;
240
241 for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
242 if ((REG_READ(ah, reg) & mask) == val)
243 return true;
244
245 udelay(AH_TIME_QUANTUM);
246 }
247 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
248 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
249 __func__, reg, REG_READ(ah, reg), mask, val);
250 return false;
251}
252
253static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
254 u16 *data)
255{
256 (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
257
258 if (!ath9k_hw_wait(ah,
259 AR_EEPROM_STATUS_DATA,
260 AR_EEPROM_STATUS_DATA_BUSY |
261 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
262 return false;
263 }
264
265 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
266 AR_EEPROM_STATUS_DATA_VAL);
267
268 return true;
269}
270
271static int ath9k_hw_flash_map(struct ath_hal *ah)
272{
273 struct ath_hal_5416 *ahp = AH5416(ah);
274
275 ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
276
277 if (!ahp->ah_cal_mem) {
278 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
279 "%s: cannot remap eeprom region \n", __func__);
280 return -EIO;
281 }
282
283 return 0;
284}
285
286static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
287 u16 *data)
288{
289 struct ath_hal_5416 *ahp = AH5416(ah);
290
291 *data = ioread16(ahp->ah_cal_mem + off);
292 return true;
293}
294
295static void ath9k_hw_read_revisions(struct ath_hal *ah)
296{
297 u32 val;
298
299 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
300
301 if (val == 0xFF) {
302 val = REG_READ(ah, AR_SREV);
303
304 ah->ah_macVersion =
305 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
306
307 ah->ah_macRev = MS(val, AR_SREV_REVISION2);
308 ah->ah_isPciExpress =
309 (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
310
311 } else {
312 if (!AR_SREV_9100(ah))
313 ah->ah_macVersion = MS(val, AR_SREV_VERSION);
314
315 ah->ah_macRev = val & AR_SREV_REVISION;
316
317 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
318 ah->ah_isPciExpress = true;
319 }
320}
321
322u32 ath9k_hw_reverse_bits(u32 val, u32 n)
323{
324 u32 retval;
325 int i;
326
327 for (i = 0, retval = 0; i < n; i++) {
328 retval = (retval << 1) | (val & 1);
329 val >>= 1;
330 }
331 return retval;
332}
333
334static void ath9k_hw_set_defaults(struct ath_hal *ah)
335{
336 int i;
337
60b67f51
S
338 ah->ah_config.dma_beacon_response_time = 2;
339 ah->ah_config.sw_beacon_response_time = 10;
340 ah->ah_config.additional_swba_backoff = 0;
341 ah->ah_config.ack_6mb = 0x0;
342 ah->ah_config.cwm_ignore_extcca = 0;
343 ah->ah_config.pcie_powersave_enable = 0;
344 ah->ah_config.pcie_l1skp_enable = 0;
345 ah->ah_config.pcie_clock_req = 0;
346 ah->ah_config.pcie_power_reset = 0x100;
347 ah->ah_config.pcie_restore = 0;
348 ah->ah_config.pcie_waen = 0;
349 ah->ah_config.analog_shiftreg = 1;
350 ah->ah_config.ht_enable = 1;
351 ah->ah_config.ofdm_trig_low = 200;
352 ah->ah_config.ofdm_trig_high = 500;
353 ah->ah_config.cck_trig_high = 200;
354 ah->ah_config.cck_trig_low = 100;
355 ah->ah_config.enable_ani = 0;
356 ah->ah_config.noise_immunity_level = 4;
357 ah->ah_config.ofdm_weaksignal_det = 1;
358 ah->ah_config.cck_weaksignal_thr = 0;
359 ah->ah_config.spur_immunity_level = 2;
360 ah->ah_config.firstep_level = 0;
361 ah->ah_config.rssi_thr_high = 40;
362 ah->ah_config.rssi_thr_low = 7;
363 ah->ah_config.diversity_control = 0;
364 ah->ah_config.antenna_switch_swap = 0;
f078f209
LR
365
366 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
60b67f51
S
367 ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
368 ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
f078f209
LR
369 }
370
60b67f51 371 ah->ah_config.intr_mitigation = 0;
f078f209
LR
372}
373
374static inline void ath9k_hw_override_ini(struct ath_hal *ah,
375 struct ath9k_channel *chan)
376{
377 if (!AR_SREV_5416_V20_OR_LATER(ah)
378 || AR_SREV_9280_10_OR_LATER(ah))
379 return;
380
381 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
382}
383
384static inline void ath9k_hw_init_bb(struct ath_hal *ah,
385 struct ath9k_channel *chan)
386{
387 u32 synthDelay;
388
389 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
390 if (IS_CHAN_CCK(chan))
391 synthDelay = (4 * synthDelay) / 22;
392 else
393 synthDelay /= 10;
394
395 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
396
397 udelay(synthDelay + BASE_ACTIVATE_DELAY);
398}
399
400static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
401 enum ath9k_opmode opmode)
402{
403 struct ath_hal_5416 *ahp = AH5416(ah);
404
405 ahp->ah_maskReg = AR_IMR_TXERR |
406 AR_IMR_TXURN |
407 AR_IMR_RXERR |
408 AR_IMR_RXORN |
409 AR_IMR_BCNMISC;
410
411 if (ahp->ah_intrMitigation)
412 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
413 else
414 ahp->ah_maskReg |= AR_IMR_RXOK;
415
416 ahp->ah_maskReg |= AR_IMR_TXOK;
417
418 if (opmode == ATH9K_M_HOSTAP)
419 ahp->ah_maskReg |= AR_IMR_MIB;
420
421 REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
422 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
423
424 if (!AR_SREV_9100(ah)) {
425 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
426 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
427 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
428 }
429}
430
431static inline void ath9k_hw_init_qos(struct ath_hal *ah)
432{
433 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
434 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
435
436 REG_WRITE(ah, AR_QOS_NO_ACK,
437 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
438 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
439 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
440
441 REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
442 REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
443 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
444 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
445 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
446}
447
448static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
449 u32 reg,
450 u32 mask,
451 u32 shift,
452 u32 val)
453{
454 u32 regVal;
455
456 regVal = REG_READ(ah, reg) & ~mask;
457 regVal |= (val << shift) & mask;
458
459 REG_WRITE(ah, reg, regVal);
460
60b67f51 461 if (ah->ah_config.analog_shiftreg)
f078f209
LR
462 udelay(100);
463
464 return;
465}
466
467static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
468 enum hal_freq_band freq_band)
469{
470 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471 struct modal_eep_header *pModal =
472 &(eep->modalHeader[HAL_FREQ_BAND_2GHZ == freq_band]);
473 struct base_eep_header *pBase = &eep->baseEepHeader;
474 u8 num_ant_config;
475
476 num_ant_config = 1;
477
478 if (pBase->version >= 0x0E0D)
479 if (pModal->useAnt1)
480 num_ant_config += 1;
481
482 return num_ant_config;
483}
484
485static int
486ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
487 struct ath9k_channel *chan,
488 u8 index,
489 u16 *config)
490{
491 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
492 struct modal_eep_header *pModal =
493 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
494 struct base_eep_header *pBase = &eep->baseEepHeader;
495
496 switch (index) {
497 case 0:
498 *config = pModal->antCtrlCommon & 0xFFFF;
499 return 0;
500 case 1:
501 if (pBase->version >= 0x0E0D) {
502 if (pModal->useAnt1) {
503 *config =
504 ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
505 return 0;
506 }
507 }
508 break;
509 default:
510 break;
511 }
512
513 return -EINVAL;
514}
515
516static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
517 u32 off,
518 u16 *data)
519{
520 if (ath9k_hw_use_flash(ah))
521 return ath9k_hw_flash_read(ah, off, data);
522 else
523 return ath9k_hw_eeprom_read(ah, off, data);
524}
525
526static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
527{
528 struct ath_hal_5416 *ahp = AH5416(ah);
529 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
530 u16 *eep_data;
531 int addr, ar5416_eep_start_loc = 0;
532
533 if (!ath9k_hw_use_flash(ah)) {
534 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
535 "%s: Reading from EEPROM, not flash\n", __func__);
536 ar5416_eep_start_loc = 256;
537 }
538 if (AR_SREV_9100(ah))
539 ar5416_eep_start_loc = 256;
540
541 eep_data = (u16 *) eep;
542 for (addr = 0;
543 addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
544 addr++) {
545 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
546 eep_data)) {
547 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
548 "%s: Unable to read eeprom region \n",
549 __func__);
550 return false;
551 }
552 eep_data++;
553 }
554 return true;
555}
556
557/* XXX: Clean me up, make me more legible */
558static bool
559ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
560 struct ath9k_channel *chan)
561{
562 struct modal_eep_header *pModal;
563 int i, regChainOffset;
564 struct ath_hal_5416 *ahp = AH5416(ah);
565 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
566 u8 txRxAttenLocal;
567 u16 ant_config;
568
569 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
570
571 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
572
573 ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
574 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
575
576 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
577 if (AR_SREV_9280(ah)) {
578 if (i >= 2)
579 break;
580 }
581
582 if (AR_SREV_5416_V20_OR_LATER(ah) &&
583 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
584 && (i != 0))
585 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
586 else
587 regChainOffset = i * 0x1000;
588
589 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
590 pModal->antCtrlChain[i]);
591
592 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
593 (REG_READ(ah,
594 AR_PHY_TIMING_CTRL4(0) +
595 regChainOffset) &
596 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
597 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
598 SM(pModal->iqCalICh[i],
599 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
600 SM(pModal->iqCalQCh[i],
601 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
602
603 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
604 if ((eep->baseEepHeader.version &
605 AR5416_EEP_VER_MINOR_MASK) >=
606 AR5416_EEP_MINOR_VER_3) {
607 txRxAttenLocal = pModal->txRxAttenCh[i];
608 if (AR_SREV_9280_10_OR_LATER(ah)) {
609 REG_RMW_FIELD(ah,
610 AR_PHY_GAIN_2GHZ +
611 regChainOffset,
612 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
613 pModal->
614 bswMargin[i]);
615 REG_RMW_FIELD(ah,
616 AR_PHY_GAIN_2GHZ +
617 regChainOffset,
618 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
619 pModal->
620 bswAtten[i]);
621 REG_RMW_FIELD(ah,
622 AR_PHY_GAIN_2GHZ +
623 regChainOffset,
624 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
625 pModal->
626 xatten2Margin[i]);
627 REG_RMW_FIELD(ah,
628 AR_PHY_GAIN_2GHZ +
629 regChainOffset,
630 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
631 pModal->
632 xatten2Db[i]);
633 } else {
634 REG_WRITE(ah,
635 AR_PHY_GAIN_2GHZ +
636 regChainOffset,
637 (REG_READ(ah,
638 AR_PHY_GAIN_2GHZ +
639 regChainOffset) &
640 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
641 | SM(pModal->
642 bswMargin[i],
643 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
644 REG_WRITE(ah,
645 AR_PHY_GAIN_2GHZ +
646 regChainOffset,
647 (REG_READ(ah,
648 AR_PHY_GAIN_2GHZ +
649 regChainOffset) &
650 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
651 | SM(pModal->bswAtten[i],
652 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
653 }
654 }
655 if (AR_SREV_9280_10_OR_LATER(ah)) {
656 REG_RMW_FIELD(ah,
657 AR_PHY_RXGAIN +
658 regChainOffset,
659 AR9280_PHY_RXGAIN_TXRX_ATTEN,
660 txRxAttenLocal);
661 REG_RMW_FIELD(ah,
662 AR_PHY_RXGAIN +
663 regChainOffset,
664 AR9280_PHY_RXGAIN_TXRX_MARGIN,
665 pModal->rxTxMarginCh[i]);
666 } else {
667 REG_WRITE(ah,
668 AR_PHY_RXGAIN + regChainOffset,
669 (REG_READ(ah,
670 AR_PHY_RXGAIN +
671 regChainOffset) &
672 ~AR_PHY_RXGAIN_TXRX_ATTEN) |
673 SM(txRxAttenLocal,
674 AR_PHY_RXGAIN_TXRX_ATTEN));
675 REG_WRITE(ah,
676 AR_PHY_GAIN_2GHZ +
677 regChainOffset,
678 (REG_READ(ah,
679 AR_PHY_GAIN_2GHZ +
680 regChainOffset) &
681 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
682 SM(pModal->rxTxMarginCh[i],
683 AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
684 }
685 }
686 }
687
688 if (AR_SREV_9280_10_OR_LATER(ah)) {
689 if (IS_CHAN_2GHZ(chan)) {
690 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
691 AR_AN_RF2G1_CH0_OB,
692 AR_AN_RF2G1_CH0_OB_S,
693 pModal->ob);
694 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
695 AR_AN_RF2G1_CH0_DB,
696 AR_AN_RF2G1_CH0_DB_S,
697 pModal->db);
698 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
699 AR_AN_RF2G1_CH1_OB,
700 AR_AN_RF2G1_CH1_OB_S,
701 pModal->ob_ch1);
702 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
703 AR_AN_RF2G1_CH1_DB,
704 AR_AN_RF2G1_CH1_DB_S,
705 pModal->db_ch1);
706 } else {
707 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
708 AR_AN_RF5G1_CH0_OB5,
709 AR_AN_RF5G1_CH0_OB5_S,
710 pModal->ob);
711 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
712 AR_AN_RF5G1_CH0_DB5,
713 AR_AN_RF5G1_CH0_DB5_S,
714 pModal->db);
715 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
716 AR_AN_RF5G1_CH1_OB5,
717 AR_AN_RF5G1_CH1_OB5_S,
718 pModal->ob_ch1);
719 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
720 AR_AN_RF5G1_CH1_DB5,
721 AR_AN_RF5G1_CH1_DB5_S,
722 pModal->db_ch1);
723 }
724 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
725 AR_AN_TOP2_XPABIAS_LVL,
726 AR_AN_TOP2_XPABIAS_LVL_S,
727 pModal->xpaBiasLvl);
728 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
729 AR_AN_TOP2_LOCALBIAS,
730 AR_AN_TOP2_LOCALBIAS_S,
731 pModal->local_bias);
732 DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
733 pModal->force_xpaon);
734 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
735 pModal->force_xpaon);
736 }
737
738 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
739 pModal->switchSettling);
740 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
741 pModal->adcDesiredSize);
742
743 if (!AR_SREV_9280_10_OR_LATER(ah))
744 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
745 AR_PHY_DESIRED_SZ_PGA,
746 pModal->pgaDesiredSize);
747
748 REG_WRITE(ah, AR_PHY_RF_CTL4,
749 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
750 | SM(pModal->txEndToXpaOff,
751 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
752 | SM(pModal->txFrameToXpaOn,
753 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
754 | SM(pModal->txFrameToXpaOn,
755 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
756
757 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
758 pModal->txEndToRxOn);
759 if (AR_SREV_9280_10_OR_LATER(ah)) {
760 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
761 pModal->thresh62);
762 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
763 AR_PHY_EXT_CCA0_THRESH62,
764 pModal->thresh62);
765 } else {
766 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
767 pModal->thresh62);
768 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
769 AR_PHY_EXT_CCA_THRESH62,
770 pModal->thresh62);
771 }
772
773 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
774 AR5416_EEP_MINOR_VER_2) {
775 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
776 AR_PHY_TX_END_DATA_START,
777 pModal->txFrameToDataStart);
778 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
779 pModal->txFrameToPaOn);
780 }
781
782 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
783 AR5416_EEP_MINOR_VER_3) {
784 if (IS_CHAN_HT40(chan))
785 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
786 AR_PHY_SETTLING_SWITCH,
787 pModal->swSettleHt40);
788 }
789
790 return true;
791}
792
793static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
794{
795 u32 sum = 0, el;
796 u16 *eepdata;
797 int i;
798 struct ath_hal_5416 *ahp = AH5416(ah);
799 bool need_swap = false;
800 struct ar5416_eeprom *eep =
801 (struct ar5416_eeprom *) &ahp->ah_eeprom;
802
803 if (!ath9k_hw_use_flash(ah)) {
804 u16 magic, magic2;
805 int addr;
806
807 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
808 &magic)) {
809 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
810 "%s: Reading Magic # failed\n", __func__);
811 return false;
812 }
813 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
814 __func__, magic);
815
816 if (magic != AR5416_EEPROM_MAGIC) {
817 magic2 = swab16(magic);
818
819 if (magic2 == AR5416_EEPROM_MAGIC) {
820 need_swap = true;
821 eepdata = (u16 *) (&ahp->ah_eeprom);
822
823 for (addr = 0;
824 addr <
825 sizeof(struct ar5416_eeprom) /
826 sizeof(u16); addr++) {
827 u16 temp;
828
829 temp = swab16(*eepdata);
830 *eepdata = temp;
831 eepdata++;
832
833 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
834 "0x%04X ", *eepdata);
835 if (((addr + 1) % 6) == 0)
836 DPRINTF(ah->ah_sc,
837 ATH_DBG_EEPROM,
838 "\n");
839 }
840 } else {
841 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
842 "Invalid EEPROM Magic. "
843 "endianness missmatch.\n");
844 return -EINVAL;
845 }
846 }
847 }
848 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
849 need_swap ? "True" : "False");
850
851 if (need_swap)
852 el = swab16(ahp->ah_eeprom.baseEepHeader.length);
853 else
854 el = ahp->ah_eeprom.baseEepHeader.length;
855
856 if (el > sizeof(struct ar5416_eeprom))
857 el = sizeof(struct ar5416_eeprom) / sizeof(u16);
858 else
859 el = el / sizeof(u16);
860
861 eepdata = (u16 *) (&ahp->ah_eeprom);
862
863 for (i = 0; i < el; i++)
864 sum ^= *eepdata++;
865
866 if (need_swap) {
867 u32 integer, j;
868 u16 word;
869
870 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
871 "EEPROM Endianness is not native.. Changing \n");
872
873 word = swab16(eep->baseEepHeader.length);
874 eep->baseEepHeader.length = word;
875
876 word = swab16(eep->baseEepHeader.checksum);
877 eep->baseEepHeader.checksum = word;
878
879 word = swab16(eep->baseEepHeader.version);
880 eep->baseEepHeader.version = word;
881
882 word = swab16(eep->baseEepHeader.regDmn[0]);
883 eep->baseEepHeader.regDmn[0] = word;
884
885 word = swab16(eep->baseEepHeader.regDmn[1]);
886 eep->baseEepHeader.regDmn[1] = word;
887
888 word = swab16(eep->baseEepHeader.rfSilent);
889 eep->baseEepHeader.rfSilent = word;
890
891 word = swab16(eep->baseEepHeader.blueToothOptions);
892 eep->baseEepHeader.blueToothOptions = word;
893
894 word = swab16(eep->baseEepHeader.deviceCap);
895 eep->baseEepHeader.deviceCap = word;
896
897 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
898 struct modal_eep_header *pModal =
899 &eep->modalHeader[j];
900 integer = swab32(pModal->antCtrlCommon);
901 pModal->antCtrlCommon = integer;
902
903 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
904 integer = swab32(pModal->antCtrlChain[i]);
905 pModal->antCtrlChain[i] = integer;
906 }
907
908 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
909 word = swab16(pModal->spurChans[i].spurChan);
910 pModal->spurChans[i].spurChan = word;
911 }
912 }
913 }
914
915 if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
916 ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
917 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
918 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
919 sum, ar5416_get_eep_ver(ahp));
920 return -EINVAL;
921 }
922
923 return 0;
924}
925
926static bool ath9k_hw_chip_test(struct ath_hal *ah)
927{
928 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
929 u32 regHold[2];
930 u32 patternData[4] = { 0x55555555,
931 0xaaaaaaaa,
932 0x66666666,
933 0x99999999 };
934 int i, j;
935
936 for (i = 0; i < 2; i++) {
937 u32 addr = regAddr[i];
938 u32 wrData, rdData;
939
940 regHold[i] = REG_READ(ah, addr);
941 for (j = 0; j < 0x100; j++) {
942 wrData = (j << 16) | j;
943 REG_WRITE(ah, addr, wrData);
944 rdData = REG_READ(ah, addr);
945 if (rdData != wrData) {
946 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
947 "%s: address test failed "
948 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
949 __func__, addr, wrData, rdData);
950 return false;
951 }
952 }
953 for (j = 0; j < 4; j++) {
954 wrData = patternData[j];
955 REG_WRITE(ah, addr, wrData);
956 rdData = REG_READ(ah, addr);
957 if (wrData != rdData) {
958 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
959 "%s: address test failed "
960 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
961 __func__, addr, wrData, rdData);
962 return false;
963 }
964 }
965 REG_WRITE(ah, regAddr[i], regHold[i]);
966 }
967 udelay(100);
968 return true;
969}
970
971u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
972{
973 u32 bits = REG_READ(ah, AR_RX_FILTER);
974 u32 phybits = REG_READ(ah, AR_PHY_ERR);
975
976 if (phybits & AR_PHY_ERR_RADAR)
977 bits |= ATH9K_RX_FILTER_PHYRADAR;
978 if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
979 bits |= ATH9K_RX_FILTER_PHYERR;
980 return bits;
981}
982
983void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
984{
985 u32 phybits;
986
987 REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
988 phybits = 0;
989 if (bits & ATH9K_RX_FILTER_PHYRADAR)
990 phybits |= AR_PHY_ERR_RADAR;
991 if (bits & ATH9K_RX_FILTER_PHYERR)
992 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
993 REG_WRITE(ah, AR_PHY_ERR, phybits);
994
995 if (phybits)
996 REG_WRITE(ah, AR_RXCFG,
997 REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
998 else
999 REG_WRITE(ah, AR_RXCFG,
1000 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
1001}
1002
1003bool ath9k_hw_setcapability(struct ath_hal *ah,
60b67f51 1004 enum ath9k_capability_type type,
f078f209
LR
1005 u32 capability,
1006 u32 setting,
1007 int *status)
1008{
1009 struct ath_hal_5416 *ahp = AH5416(ah);
1010 u32 v;
1011
1012 switch (type) {
60b67f51 1013 case ATH9K_CAP_TKIP_MIC:
f078f209
LR
1014 if (setting)
1015 ahp->ah_staId1Defaults |=
1016 AR_STA_ID1_CRPT_MIC_ENABLE;
1017 else
1018 ahp->ah_staId1Defaults &=
1019 ~AR_STA_ID1_CRPT_MIC_ENABLE;
1020 return true;
60b67f51 1021 case ATH9K_CAP_DIVERSITY:
f078f209
LR
1022 v = REG_READ(ah, AR_PHY_CCK_DETECT);
1023 if (setting)
1024 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1025 else
1026 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1027 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
1028 return true;
60b67f51 1029 case ATH9K_CAP_MCAST_KEYSRCH:
f078f209
LR
1030 if (setting)
1031 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1032 else
1033 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1034 return true;
60b67f51 1035 case ATH9K_CAP_TSF_ADJUST:
f078f209
LR
1036 if (setting)
1037 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
1038 else
1039 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
1040 return true;
1041 default:
1042 return false;
1043 }
1044}
1045
1046void ath9k_hw_dmaRegDump(struct ath_hal *ah)
1047{
1048 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
1049 int qcuOffset = 0, dcuOffset = 0;
1050 u32 *qcuBase = &val[0], *dcuBase = &val[4];
1051 int i;
1052
1053 REG_WRITE(ah, AR_MACMISC,
1054 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1055 (AR_MACMISC_MISC_OBS_BUS_1 <<
1056 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1057
1058 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
1059 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
1060 if (i % 4 == 0)
1061 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1062
1063 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
1064 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
1065 }
1066
1067 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
1068 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1069 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1070
1071 for (i = 0; i < ATH9K_NUM_QUEUES;
1072 i++, qcuOffset += 4, dcuOffset += 5) {
1073 if (i == 8) {
1074 qcuOffset = 0;
1075 qcuBase++;
1076 }
1077
1078 if (i == 6) {
1079 dcuOffset = 0;
1080 dcuBase++;
1081 }
1082
1083 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1084 "%2d %2x %1x %2x %2x\n",
1085 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1086 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
1087 3),
1088 val[2] & (0x7 << (i * 3)) >> (i * 3),
1089 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1090 }
1091
1092 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1093 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1094 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
1095 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
1096 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1097 "qcu_complete state: %2x dcu_complete state: %2x\n",
1098 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
1099 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1100 "dcu_arb state: %2x dcu_fp state: %2x\n",
1101 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
1102 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1103 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
1104 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
1105 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1106 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
1107 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
1108 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1109 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
1110 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
1111
1112 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
1113 REG_READ(ah, AR_OBS_BUS_1));
1114 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1115 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
1116}
1117
1118u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1119 u32 *rxc_pcnt,
1120 u32 *rxf_pcnt,
1121 u32 *txf_pcnt)
1122{
1123 static u32 cycles, rx_clear, rx_frame, tx_frame;
1124 u32 good = 1;
1125
1126 u32 rc = REG_READ(ah, AR_RCCNT);
1127 u32 rf = REG_READ(ah, AR_RFCNT);
1128 u32 tf = REG_READ(ah, AR_TFCNT);
1129 u32 cc = REG_READ(ah, AR_CCCNT);
1130
1131 if (cycles == 0 || cycles > cc) {
1132 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1133 "%s: cycle counter wrap. ExtBusy = 0\n",
1134 __func__);
1135 good = 0;
1136 } else {
1137 u32 cc_d = cc - cycles;
1138 u32 rc_d = rc - rx_clear;
1139 u32 rf_d = rf - rx_frame;
1140 u32 tf_d = tf - tx_frame;
1141
1142 if (cc_d != 0) {
1143 *rxc_pcnt = rc_d * 100 / cc_d;
1144 *rxf_pcnt = rf_d * 100 / cc_d;
1145 *txf_pcnt = tf_d * 100 / cc_d;
1146 } else {
1147 good = 0;
1148 }
1149 }
1150
1151 cycles = cc;
1152 rx_frame = rf;
1153 rx_clear = rc;
1154 tx_frame = tf;
1155
1156 return good;
1157}
1158
1159void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
1160{
1161 u32 macmode;
1162
1163 if (mode == ATH9K_HT_MACMODE_2040 &&
60b67f51 1164 !ah->ah_config.cwm_ignore_extcca)
f078f209
LR
1165 macmode = AR_2040_JOINED_RX_CLEAR;
1166 else
1167 macmode = 0;
1168
1169 REG_WRITE(ah, AR_2040_MODE, macmode);
1170}
1171
1172static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
1173{
1174 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1175}
1176
1177
1178static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1179 struct ath_softc *sc,
1180 void __iomem *mem,
1181 int *status)
1182{
1183 static const u8 defbssidmask[ETH_ALEN] =
1184 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1185 struct ath_hal_5416 *ahp;
1186 struct ath_hal *ah;
1187
1188 ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
1189 if (ahp == NULL) {
1190 DPRINTF(sc, ATH_DBG_FATAL,
1191 "%s: cannot allocate memory for state block\n",
1192 __func__);
1193 *status = -ENOMEM;
1194 return NULL;
1195 }
1196
1197 ah = &ahp->ah;
1198
1199 memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1200
1201 ah->ah_sc = sc;
1202 ah->ah_sh = mem;
1203
1204 ah->ah_devid = devid;
1205 ah->ah_subvendorid = 0;
1206
1207 ah->ah_flags = 0;
1208 if ((devid == AR5416_AR9100_DEVID))
1209 ah->ah_macVersion = AR_SREV_VERSION_9100;
1210 if (!AR_SREV_9100(ah))
1211 ah->ah_flags = AH_USE_EEPROM;
1212
1213 ah->ah_powerLimit = MAX_RATE_POWER;
1214 ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
1215
1216 ahp->ah_atimWindow = 0;
60b67f51 1217 ahp->ah_diversityControl = ah->ah_config.diversity_control;
f078f209 1218 ahp->ah_antennaSwitchSwap =
60b67f51 1219 ah->ah_config.antenna_switch_swap;
f078f209
LR
1220
1221 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
1222 ahp->ah_beaconInterval = 100;
1223 ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
1224 ahp->ah_slottime = (u32) -1;
1225 ahp->ah_acktimeout = (u32) -1;
1226 ahp->ah_ctstimeout = (u32) -1;
1227 ahp->ah_globaltxtimeout = (u32) -1;
1228 memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
1229
1230 ahp->ah_gBeaconRate = 0;
1231
1232 return ahp;
1233}
1234
1235static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
1236{
1237 int status;
1238
1239 if (ath9k_hw_use_flash(ah))
1240 ath9k_hw_flash_map(ah);
1241
1242 if (!ath9k_hw_fill_eeprom(ah))
1243 return -EIO;
1244
1245 status = ath9k_hw_check_eeprom(ah);
1246
1247 return status;
1248}
1249
1250u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1251 enum eeprom_param param)
1252{
1253 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
1254 struct modal_eep_header *pModal = eep->modalHeader;
1255 struct base_eep_header *pBase = &eep->baseEepHeader;
1256
1257 switch (param) {
1258 case EEP_NFTHRESH_5:
1259 return -pModal[0].noiseFloorThreshCh[0];
1260 case EEP_NFTHRESH_2:
1261 return -pModal[1].noiseFloorThreshCh[0];
1262 case AR_EEPROM_MAC(0):
1263 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1264 case AR_EEPROM_MAC(1):
1265 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1266 case AR_EEPROM_MAC(2):
1267 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1268 case EEP_REG_0:
1269 return pBase->regDmn[0];
1270 case EEP_REG_1:
1271 return pBase->regDmn[1];
1272 case EEP_OP_CAP:
1273 return pBase->deviceCap;
1274 case EEP_OP_MODE:
1275 return pBase->opCapFlags;
1276 case EEP_RF_SILENT:
1277 return pBase->rfSilent;
1278 case EEP_OB_5:
1279 return pModal[0].ob;
1280 case EEP_DB_5:
1281 return pModal[0].db;
1282 case EEP_OB_2:
1283 return pModal[1].ob;
1284 case EEP_DB_2:
1285 return pModal[1].db;
1286 case EEP_MINOR_REV:
1287 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
1288 case EEP_TX_MASK:
1289 return pBase->txMask;
1290 case EEP_RX_MASK:
1291 return pBase->rxMask;
1292 default:
1293 return 0;
1294 }
1295}
1296
1297static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1298{
1299 u32 val;
1300 int i;
1301
1302 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
1303 for (i = 0; i < 8; i++)
1304 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
1305 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
1306 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
1307 return ath9k_hw_reverse_bits(val, 8);
1308}
1309
1310static inline int ath9k_hw_init_macaddr(struct ath_hal *ah)
1311{
1312 u32 sum;
1313 int i;
1314 u16 eeval;
1315 struct ath_hal_5416 *ahp = AH5416(ah);
1316 DECLARE_MAC_BUF(mac);
1317
1318 sum = 0;
1319 for (i = 0; i < 3; i++) {
1320 eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
1321 sum += eeval;
1322 ahp->ah_macaddr[2 * i] = eeval >> 8;
1323 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
1324 }
1325 if (sum == 0 || sum == 0xffff * 3) {
1326 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1327 "%s: mac address read failed: %s\n", __func__,
1328 print_mac(mac, ahp->ah_macaddr));
1329 return -EADDRNOTAVAIL;
1330 }
1331
1332 return 0;
1333}
1334
1335static inline int16_t ath9k_hw_interpolate(u16 target,
1336 u16 srcLeft,
1337 u16 srcRight,
1338 int16_t targetLeft,
1339 int16_t targetRight)
1340{
1341 int16_t rv;
1342
1343 if (srcRight == srcLeft) {
1344 rv = targetLeft;
1345 } else {
1346 rv = (int16_t) (((target - srcLeft) * targetRight +
1347 (srcRight - target) * targetLeft) /
1348 (srcRight - srcLeft));
1349 }
1350 return rv;
1351}
1352
1353static inline u16 ath9k_hw_fbin2freq(u8 fbin,
1354 bool is2GHz)
1355{
1356
1357 if (fbin == AR5416_BCHAN_UNUSED)
1358 return fbin;
1359
1360 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1361}
1362
1363static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1364 u16 i,
1365 bool is2GHz)
1366{
1367 struct ath_hal_5416 *ahp = AH5416(ah);
1368 struct ar5416_eeprom *eep =
1369 (struct ar5416_eeprom *) &ahp->ah_eeprom;
1370 u16 spur_val = AR_NO_SPUR;
1371
1372 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1373 "Getting spur idx %d is2Ghz. %d val %x\n",
60b67f51 1374 i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
f078f209 1375
60b67f51 1376 switch (ah->ah_config.spurmode) {
f078f209
LR
1377 case SPUR_DISABLE:
1378 break;
1379 case SPUR_ENABLE_IOCTL:
60b67f51 1380 spur_val = ah->ah_config.spurchans[i][is2GHz];
f078f209
LR
1381 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1382 "Getting spur val from new loc. %d\n", spur_val);
1383 break;
1384 case SPUR_ENABLE_EEPROM:
1385 spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
1386 break;
1387
1388 }
1389 return spur_val;
1390}
1391
1392static inline int ath9k_hw_rfattach(struct ath_hal *ah)
1393{
1394 bool rfStatus = false;
1395 int ecode = 0;
1396
1397 rfStatus = ath9k_hw_init_rf(ah, &ecode);
1398 if (!rfStatus) {
1399 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1400 "%s: RF setup failed, status %u\n", __func__,
1401 ecode);
1402 return ecode;
1403 }
1404
1405 return 0;
1406}
1407
1408static int ath9k_hw_rf_claim(struct ath_hal *ah)
1409{
1410 u32 val;
1411
1412 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1413
1414 val = ath9k_hw_get_radiorev(ah);
1415 switch (val & AR_RADIO_SREV_MAJOR) {
1416 case 0:
1417 val = AR_RAD5133_SREV_MAJOR;
1418 break;
1419 case AR_RAD5133_SREV_MAJOR:
1420 case AR_RAD5122_SREV_MAJOR:
1421 case AR_RAD2133_SREV_MAJOR:
1422 case AR_RAD2122_SREV_MAJOR:
1423 break;
1424 default:
1425 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1426 "%s: 5G Radio Chip Rev 0x%02X is not "
1427 "supported by this driver\n",
1428 __func__, ah->ah_analog5GhzRev);
1429 return -EOPNOTSUPP;
1430 }
1431
1432 ah->ah_analog5GhzRev = val;
1433
1434 return 0;
1435}
1436
1437static inline void ath9k_hw_init_pll(struct ath_hal *ah,
1438 struct ath9k_channel *chan)
1439{
1440 u32 pll;
1441
1442 if (AR_SREV_9100(ah)) {
1443 if (chan && IS_CHAN_5GHZ(chan))
1444 pll = 0x1450;
1445 else
1446 pll = 0x1458;
1447 } else {
1448 if (AR_SREV_9280_10_OR_LATER(ah)) {
1449 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1450
1451 if (chan && IS_CHAN_HALF_RATE(chan))
1452 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1453 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1454 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1455
1456 if (chan && IS_CHAN_5GHZ(chan)) {
1457 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1458
1459
1460 if (AR_SREV_9280_20(ah)) {
1461 if (((chan->channel % 20) == 0)
1462 || ((chan->channel % 10) == 0))
1463 pll = 0x2850;
1464 else
1465 pll = 0x142c;
1466 }
1467 } else {
1468 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1469 }
1470
1471 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1472
1473 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1474
1475 if (chan && IS_CHAN_HALF_RATE(chan))
1476 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1477 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1478 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1479
1480 if (chan && IS_CHAN_5GHZ(chan))
1481 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1482 else
1483 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1484 } else {
1485 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1486
1487 if (chan && IS_CHAN_HALF_RATE(chan))
1488 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1489 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1490 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1491
1492 if (chan && IS_CHAN_5GHZ(chan))
1493 pll |= SM(0xa, AR_RTC_PLL_DIV);
1494 else
1495 pll |= SM(0xb, AR_RTC_PLL_DIV);
1496 }
1497 }
1498 REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
1499
1500 udelay(RTC_PLL_SETTLE_DELAY);
1501
1502 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1503}
1504
1505static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1506 enum ath9k_ht_macmode macmode)
1507{
1508 u32 phymode;
1509 struct ath_hal_5416 *ahp = AH5416(ah);
1510
1511 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1512 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
1513
1514 if (IS_CHAN_HT40(chan)) {
1515 phymode |= AR_PHY_FC_DYN2040_EN;
1516
1517 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1518 (chan->chanmode == CHANNEL_G_HT40PLUS))
1519 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1520
1521 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1522 phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1523 }
1524 REG_WRITE(ah, AR_PHY_TURBO, phymode);
1525
1526 ath9k_hw_set11nmac2040(ah, macmode);
1527
1528 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1529 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1530}
1531
1532static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1533{
1534 u32 val;
1535
1536 val = REG_READ(ah, AR_STA_ID1);
1537 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1538 switch (opmode) {
1539 case ATH9K_M_HOSTAP:
1540 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
1541 | AR_STA_ID1_KSRCH_MODE);
1542 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1543 break;
1544 case ATH9K_M_IBSS:
1545 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1546 | AR_STA_ID1_KSRCH_MODE);
1547 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1548 break;
1549 case ATH9K_M_STA:
1550 case ATH9K_M_MONITOR:
1551 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1552 break;
1553 }
1554}
1555
1556static inline void
1557ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1558{
1559 u32 rfMode = 0;
1560
1561 if (chan == NULL)
1562 return;
1563
1564 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1565 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1566
1567 if (!AR_SREV_9280_10_OR_LATER(ah))
1568 rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
1569 AR_PHY_MODE_RF2GHZ;
1570
1571 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1572 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1573
1574 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1575}
1576
1577static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1578{
1579 u32 rst_flags;
1580 u32 tmpReg;
1581
1582 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1583 AR_RTC_FORCE_WAKE_ON_INT);
1584
1585 if (AR_SREV_9100(ah)) {
1586 rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1587 AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1588 } else {
1589 tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1590 if (tmpReg &
1591 (AR_INTR_SYNC_LOCAL_TIMEOUT |
1592 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1593 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1594 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
1595 } else {
1596 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1597 }
1598
1599 rst_flags = AR_RTC_RC_MAC_WARM;
1600 if (type == ATH9K_RESET_COLD)
1601 rst_flags |= AR_RTC_RC_MAC_COLD;
1602 }
1603
1604 REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
1605 udelay(50);
1606
1607 REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
1608 if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
1609 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1610 "%s: RTC stuck in MAC reset\n",
1611 __func__);
1612 return false;
1613 }
1614
1615 if (!AR_SREV_9100(ah))
1616 REG_WRITE(ah, AR_RC, 0);
1617
1618 ath9k_hw_init_pll(ah, NULL);
1619
1620 if (AR_SREV_9100(ah))
1621 udelay(50);
1622
1623 return true;
1624}
1625
1626static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1627{
1628 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1629 AR_RTC_FORCE_WAKE_ON_INT);
1630
1631 REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
1632 REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
1633
1634 if (!ath9k_hw_wait(ah,
1635 AR_RTC_STATUS,
1636 AR_RTC_STATUS_M,
1637 AR_RTC_STATUS_ON)) {
1638 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
1639 __func__);
1640 return false;
1641 }
1642
1643 ath9k_hw_read_revisions(ah);
1644
1645 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1646}
1647
1648static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1649 u32 type)
1650{
1651 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1652 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1653
1654 switch (type) {
1655 case ATH9K_RESET_POWER_ON:
1656 return ath9k_hw_set_reset_power_on(ah);
1657 break;
1658 case ATH9K_RESET_WARM:
1659 case ATH9K_RESET_COLD:
1660 return ath9k_hw_set_reset(ah, type);
1661 break;
1662 default:
1663 return false;
1664 }
1665}
1666
1667static inline
1668struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1669 struct ath9k_channel *chan)
1670{
1671 if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
1672 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1673 "%s: invalid channel %u/0x%x; not marked as "
1674 "2GHz or 5GHz\n", __func__, chan->channel,
1675 chan->channelFlags);
1676 return NULL;
1677 }
1678
1679 if (!IS_CHAN_OFDM(chan) &&
1680 !IS_CHAN_CCK(chan) &&
1681 !IS_CHAN_HT20(chan) &&
1682 !IS_CHAN_HT40(chan)) {
1683 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1684 "%s: invalid channel %u/0x%x; not marked as "
1685 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1686 __func__, chan->channel, chan->channelFlags);
1687 return NULL;
1688 }
1689
1690 return ath9k_regd_check_channel(ah, chan);
1691}
1692
1693static inline bool
1694ath9k_hw_get_lower_upper_index(u8 target,
1695 u8 *pList,
1696 u16 listSize,
1697 u16 *indexL,
1698 u16 *indexR)
1699{
1700 u16 i;
1701
1702 if (target <= pList[0]) {
1703 *indexL = *indexR = 0;
1704 return true;
1705 }
1706 if (target >= pList[listSize - 1]) {
1707 *indexL = *indexR = (u16) (listSize - 1);
1708 return true;
1709 }
1710
1711 for (i = 0; i < listSize - 1; i++) {
1712 if (pList[i] == target) {
1713 *indexL = *indexR = i;
1714 return true;
1715 }
1716 if (target < pList[i + 1]) {
1717 *indexL = i;
1718 *indexR = (u16) (i + 1);
1719 return false;
1720 }
1721 }
1722 return false;
1723}
1724
1725static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
1726{
1727 int16_t nfval;
1728 int16_t sort[ATH9K_NF_CAL_HIST_MAX];
1729 int i, j;
1730
1731 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
1732 sort[i] = nfCalBuffer[i];
1733
1734 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
1735 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
1736 if (sort[j] > sort[j - 1]) {
1737 nfval = sort[j];
1738 sort[j] = sort[j - 1];
1739 sort[j - 1] = nfval;
1740 }
1741 }
1742 }
1743 nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
1744
1745 return nfval;
1746}
1747
1748static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
1749 int16_t *nfarray)
1750{
1751 int i;
1752
1753 for (i = 0; i < NUM_NF_READINGS; i++) {
1754 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
1755
1756 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
1757 h[i].currIndex = 0;
1758
1759 if (h[i].invalidNFcount > 0) {
1760 if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
1761 || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
1762 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
1763 } else {
1764 h[i].invalidNFcount--;
1765 h[i].privNF = nfarray[i];
1766 }
1767 } else {
1768 h[i].privNF =
1769 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
1770 }
1771 }
1772 return;
1773}
1774
1775static void ar5416GetNoiseFloor(struct ath_hal *ah,
1776 int16_t nfarray[NUM_NF_READINGS])
1777{
1778 int16_t nf;
1779
1780 if (AR_SREV_9280_10_OR_LATER(ah))
1781 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
1782 else
1783 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1784
1785 if (nf & 0x100)
1786 nf = 0 - ((nf ^ 0x1ff) + 1);
1787 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1788 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1789 nfarray[0] = nf;
1790
1791 if (AR_SREV_9280_10_OR_LATER(ah))
1792 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1793 AR9280_PHY_CH1_MINCCA_PWR);
1794 else
1795 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1796 AR_PHY_CH1_MINCCA_PWR);
1797
1798 if (nf & 0x100)
1799 nf = 0 - ((nf ^ 0x1ff) + 1);
1800 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1801 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1802 nfarray[1] = nf;
1803
1804 if (!AR_SREV_9280(ah)) {
1805 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
1806 AR_PHY_CH2_MINCCA_PWR);
1807 if (nf & 0x100)
1808 nf = 0 - ((nf ^ 0x1ff) + 1);
1809 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1810 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1811 nfarray[2] = nf;
1812 }
1813
1814 if (AR_SREV_9280_10_OR_LATER(ah))
1815 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1816 AR9280_PHY_EXT_MINCCA_PWR);
1817 else
1818 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1819 AR_PHY_EXT_MINCCA_PWR);
1820
1821 if (nf & 0x100)
1822 nf = 0 - ((nf ^ 0x1ff) + 1);
1823 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1824 "NF calibrated [ext] [chain 0] is %d\n", nf);
1825 nfarray[3] = nf;
1826
1827 if (AR_SREV_9280_10_OR_LATER(ah))
1828 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1829 AR9280_PHY_CH1_EXT_MINCCA_PWR);
1830 else
1831 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1832 AR_PHY_CH1_EXT_MINCCA_PWR);
1833
1834 if (nf & 0x100)
1835 nf = 0 - ((nf ^ 0x1ff) + 1);
1836 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1837 "NF calibrated [ext] [chain 1] is %d\n", nf);
1838 nfarray[4] = nf;
1839
1840 if (!AR_SREV_9280(ah)) {
1841 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
1842 AR_PHY_CH2_EXT_MINCCA_PWR);
1843 if (nf & 0x100)
1844 nf = 0 - ((nf ^ 0x1ff) + 1);
1845 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1846 "NF calibrated [ext] [chain 2] is %d\n", nf);
1847 nfarray[5] = nf;
1848 }
1849}
1850
1851static bool
1852getNoiseFloorThresh(struct ath_hal *ah,
1853 const struct ath9k_channel *chan,
1854 int16_t *nft)
1855{
1856 struct ath_hal_5416 *ahp = AH5416(ah);
1857
1858 switch (chan->chanmode) {
1859 case CHANNEL_A:
1860 case CHANNEL_A_HT20:
1861 case CHANNEL_A_HT40PLUS:
1862 case CHANNEL_A_HT40MINUS:
1863 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
1864 break;
1865 case CHANNEL_B:
1866 case CHANNEL_G:
1867 case CHANNEL_G_HT20:
1868 case CHANNEL_G_HT40PLUS:
1869 case CHANNEL_G_HT40MINUS:
1870 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
1871 break;
1872 default:
1873 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1874 "%s: invalid channel flags 0x%x\n", __func__,
1875 chan->channelFlags);
1876 return false;
1877 }
1878 return true;
1879}
1880
1881static void ath9k_hw_start_nfcal(struct ath_hal *ah)
1882{
1883 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1884 AR_PHY_AGC_CONTROL_ENABLE_NF);
1885 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1886 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1887 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1888}
1889
1890static void
1891ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
1892{
1893 struct ath9k_nfcal_hist *h;
1894 int i, j;
1895 int32_t val;
1896 const u32 ar5416_cca_regs[6] = {
1897 AR_PHY_CCA,
1898 AR_PHY_CH1_CCA,
1899 AR_PHY_CH2_CCA,
1900 AR_PHY_EXT_CCA,
1901 AR_PHY_CH1_EXT_CCA,
1902 AR_PHY_CH2_EXT_CCA
1903 };
1904 u8 chainmask;
1905
1906 if (AR_SREV_9280(ah))
1907 chainmask = 0x1B;
1908 else
1909 chainmask = 0x3F;
1910
1911#ifdef ATH_NF_PER_CHAN
1912 h = chan->nfCalHist;
1913#else
1914 h = ah->nfCalHist;
1915#endif
1916
1917 for (i = 0; i < NUM_NF_READINGS; i++) {
1918 if (chainmask & (1 << i)) {
1919 val = REG_READ(ah, ar5416_cca_regs[i]);
1920 val &= 0xFFFFFE00;
1921 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1922 REG_WRITE(ah, ar5416_cca_regs[i], val);
1923 }
1924 }
1925
1926 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1927 AR_PHY_AGC_CONTROL_ENABLE_NF);
1928 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1929 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1930 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1931
1932 for (j = 0; j < 1000; j++) {
1933 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1934 AR_PHY_AGC_CONTROL_NF) == 0)
1935 break;
1936 udelay(10);
1937 }
1938
1939 for (i = 0; i < NUM_NF_READINGS; i++) {
1940 if (chainmask & (1 << i)) {
1941 val = REG_READ(ah, ar5416_cca_regs[i]);
1942 val &= 0xFFFFFE00;
1943 val |= (((u32) (-50) << 1) & 0x1ff);
1944 REG_WRITE(ah, ar5416_cca_regs[i], val);
1945 }
1946 }
1947}
1948
1949static int16_t ath9k_hw_getnf(struct ath_hal *ah,
1950 struct ath9k_channel *chan)
1951{
1952 int16_t nf, nfThresh;
1953 int16_t nfarray[NUM_NF_READINGS] = { 0 };
1954 struct ath9k_nfcal_hist *h;
1955 u8 chainmask;
1956
1957 if (AR_SREV_9280(ah))
1958 chainmask = 0x1B;
1959 else
1960 chainmask = 0x3F;
1961
1962 chan->channelFlags &= (~CHANNEL_CW_INT);
1963 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1964 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1965 "%s: NF did not complete in calibration window\n",
1966 __func__);
1967 nf = 0;
1968 chan->rawNoiseFloor = nf;
1969 return chan->rawNoiseFloor;
1970 } else {
1971 ar5416GetNoiseFloor(ah, nfarray);
1972 nf = nfarray[0];
1973 if (getNoiseFloorThresh(ah, chan, &nfThresh)
1974 && nf > nfThresh) {
1975 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1976 "%s: noise floor failed detected; "
1977 "detected %d, threshold %d\n", __func__,
1978 nf, nfThresh);
1979 chan->channelFlags |= CHANNEL_CW_INT;
1980 }
1981 }
1982
1983#ifdef ATH_NF_PER_CHAN
1984 h = chan->nfCalHist;
1985#else
1986 h = ah->nfCalHist;
1987#endif
1988
1989 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
1990 chan->rawNoiseFloor = h[0].privNF;
1991
1992 return chan->rawNoiseFloor;
1993}
1994
1995static void ath9k_hw_update_mibstats(struct ath_hal *ah,
1996 struct ath9k_mib_stats *stats)
1997{
1998 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
1999 stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
2000 stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
2001 stats->rts_good += REG_READ(ah, AR_RTS_OK);
2002 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
2003}
2004
2005static void ath9k_enable_mib_counters(struct ath_hal *ah)
2006{
2007 struct ath_hal_5416 *ahp = AH5416(ah);
2008
2009 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
2010
2011 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2012
2013 REG_WRITE(ah, AR_FILT_OFDM, 0);
2014 REG_WRITE(ah, AR_FILT_CCK, 0);
2015 REG_WRITE(ah, AR_MIBC,
2016 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
2017 & 0x0f);
2018 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2019 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2020}
2021
2022static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
2023{
2024 struct ath_hal_5416 *ahp = AH5416(ah);
2025
2026 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
2027
2028 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
2029
2030 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2031
2032 REG_WRITE(ah, AR_FILT_OFDM, 0);
2033 REG_WRITE(ah, AR_FILT_CCK, 0);
2034}
2035
2036static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
2037 struct ath9k_channel *chan)
2038{
2039 struct ath_hal_5416 *ahp = AH5416(ah);
2040 int i;
2041
2042 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2043 if (ahp->ah_ani[i].c.channel == chan->channel)
2044 return i;
2045 if (ahp->ah_ani[i].c.channel == 0) {
2046 ahp->ah_ani[i].c.channel = chan->channel;
2047 ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
2048 return i;
2049 }
2050 }
2051
2052 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2053 "No more channel states left. Using channel 0\n");
2054 return 0;
2055}
2056
2057static void ath9k_hw_ani_attach(struct ath_hal *ah)
2058{
2059 struct ath_hal_5416 *ahp = AH5416(ah);
2060 int i;
2061
2062 ahp->ah_hasHwPhyCounters = 1;
2063
2064 memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
2065 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2066 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
2067 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
2068 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
2069 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
2070 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
2071 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
2072 ahp->ah_ani[i].ofdmWeakSigDetectOff =
2073 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
2074 ahp->ah_ani[i].cckWeakSigThreshold =
2075 ATH9K_ANI_CCK_WEAK_SIG_THR;
2076 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
2077 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
2078 if (ahp->ah_hasHwPhyCounters) {
2079 ahp->ah_ani[i].ofdmPhyErrBase =
2080 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
2081 ahp->ah_ani[i].cckPhyErrBase =
2082 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
2083 }
2084 }
2085 if (ahp->ah_hasHwPhyCounters) {
2086 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2087 "Setting OfdmErrBase = 0x%08x\n",
2088 ahp->ah_ani[0].ofdmPhyErrBase);
2089 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
2090 ahp->ah_ani[0].cckPhyErrBase);
2091
2092 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
2093 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
2094 ath9k_enable_mib_counters(ah);
2095 }
2096 ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
60b67f51 2097 if (ah->ah_config.enable_ani)
f078f209
LR
2098 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2099}
2100
2101static inline void ath9k_hw_ani_setup(struct ath_hal *ah)
2102{
2103 struct ath_hal_5416 *ahp = AH5416(ah);
2104 int i;
2105
2106 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
2107 const int coarseHigh[] = { -14, -14, -14, -14, -12 };
2108 const int coarseLow[] = { -64, -64, -64, -64, -70 };
2109 const int firpwr[] = { -78, -78, -78, -78, -80 };
2110
2111 for (i = 0; i < 5; i++) {
2112 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
2113 ahp->ah_coarseHigh[i] = coarseHigh[i];
2114 ahp->ah_coarseLow[i] = coarseLow[i];
2115 ahp->ah_firpwr[i] = firpwr[i];
2116 }
2117}
2118
2119static void ath9k_hw_ani_detach(struct ath_hal *ah)
2120{
2121 struct ath_hal_5416 *ahp = AH5416(ah);
2122
2123 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
2124 if (ahp->ah_hasHwPhyCounters) {
2125 ath9k_hw_disable_mib_counters(ah);
2126 REG_WRITE(ah, AR_PHY_ERR_1, 0);
2127 REG_WRITE(ah, AR_PHY_ERR_2, 0);
2128 }
2129}
2130
2131
2132static bool ath9k_hw_ani_control(struct ath_hal *ah,
2133 enum ath9k_ani_cmd cmd, int param)
2134{
2135 struct ath_hal_5416 *ahp = AH5416(ah);
2136 struct ar5416AniState *aniState = ahp->ah_curani;
2137
2138 switch (cmd & ahp->ah_ani_function) {
2139 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
2140 u32 level = param;
2141
2142 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
2143 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2144 "%s: level out of range (%u > %u)\n",
2145 __func__, level,
2146 (unsigned) ARRAY_SIZE(ahp->
2147 ah_totalSizeDesired));
2148 return false;
2149 }
2150
2151 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2152 AR_PHY_DESIRED_SZ_TOT_DES,
2153 ahp->ah_totalSizeDesired[level]);
2154 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2155 AR_PHY_AGC_CTL1_COARSE_LOW,
2156 ahp->ah_coarseLow[level]);
2157 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2158 AR_PHY_AGC_CTL1_COARSE_HIGH,
2159 ahp->ah_coarseHigh[level]);
2160 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2161 AR_PHY_FIND_SIG_FIRPWR,
2162 ahp->ah_firpwr[level]);
2163
2164 if (level > aniState->noiseImmunityLevel)
2165 ahp->ah_stats.ast_ani_niup++;
2166 else if (level < aniState->noiseImmunityLevel)
2167 ahp->ah_stats.ast_ani_nidown++;
2168 aniState->noiseImmunityLevel = level;
2169 break;
2170 }
2171 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
2172 const int m1ThreshLow[] = { 127, 50 };
2173 const int m2ThreshLow[] = { 127, 40 };
2174 const int m1Thresh[] = { 127, 0x4d };
2175 const int m2Thresh[] = { 127, 0x40 };
2176 const int m2CountThr[] = { 31, 16 };
2177 const int m2CountThrLow[] = { 63, 48 };
2178 u32 on = param ? 1 : 0;
2179
2180 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2181 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
2182 m1ThreshLow[on]);
2183 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2184 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
2185 m2ThreshLow[on]);
2186 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2187 AR_PHY_SFCORR_M1_THRESH,
2188 m1Thresh[on]);
2189 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2190 AR_PHY_SFCORR_M2_THRESH,
2191 m2Thresh[on]);
2192 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2193 AR_PHY_SFCORR_M2COUNT_THR,
2194 m2CountThr[on]);
2195 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2196 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
2197 m2CountThrLow[on]);
2198
2199 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2200 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
2201 m1ThreshLow[on]);
2202 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2203 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
2204 m2ThreshLow[on]);
2205 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2206 AR_PHY_SFCORR_EXT_M1_THRESH,
2207 m1Thresh[on]);
2208 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2209 AR_PHY_SFCORR_EXT_M2_THRESH,
2210 m2Thresh[on]);
2211
2212 if (on)
2213 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
2214 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2215 else
2216 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
2217 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2218
2219 if (!on != aniState->ofdmWeakSigDetectOff) {
2220 if (on)
2221 ahp->ah_stats.ast_ani_ofdmon++;
2222 else
2223 ahp->ah_stats.ast_ani_ofdmoff++;
2224 aniState->ofdmWeakSigDetectOff = !on;
2225 }
2226 break;
2227 }
2228 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
2229 const int weakSigThrCck[] = { 8, 6 };
2230 u32 high = param ? 1 : 0;
2231
2232 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
2233 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
2234 weakSigThrCck[high]);
2235 if (high != aniState->cckWeakSigThreshold) {
2236 if (high)
2237 ahp->ah_stats.ast_ani_cckhigh++;
2238 else
2239 ahp->ah_stats.ast_ani_ccklow++;
2240 aniState->cckWeakSigThreshold = high;
2241 }
2242 break;
2243 }
2244 case ATH9K_ANI_FIRSTEP_LEVEL:{
2245 const int firstep[] = { 0, 4, 8 };
2246 u32 level = param;
2247
2248 if (level >= ARRAY_SIZE(firstep)) {
2249 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2250 "%s: level out of range (%u > %u)\n",
2251 __func__, level,
2252 (unsigned) ARRAY_SIZE(firstep));
2253 return false;
2254 }
2255 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2256 AR_PHY_FIND_SIG_FIRSTEP,
2257 firstep[level]);
2258 if (level > aniState->firstepLevel)
2259 ahp->ah_stats.ast_ani_stepup++;
2260 else if (level < aniState->firstepLevel)
2261 ahp->ah_stats.ast_ani_stepdown++;
2262 aniState->firstepLevel = level;
2263 break;
2264 }
2265 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
2266 const int cycpwrThr1[] =
2267 { 2, 4, 6, 8, 10, 12, 14, 16 };
2268 u32 level = param;
2269
2270 if (level >= ARRAY_SIZE(cycpwrThr1)) {
2271 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2272 "%s: level out of range (%u > %u)\n",
2273 __func__, level,
2274 (unsigned)
2275 ARRAY_SIZE(cycpwrThr1));
2276 return false;
2277 }
2278 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
2279 AR_PHY_TIMING5_CYCPWR_THR1,
2280 cycpwrThr1[level]);
2281 if (level > aniState->spurImmunityLevel)
2282 ahp->ah_stats.ast_ani_spurup++;
2283 else if (level < aniState->spurImmunityLevel)
2284 ahp->ah_stats.ast_ani_spurdown++;
2285 aniState->spurImmunityLevel = level;
2286 break;
2287 }
2288 case ATH9K_ANI_PRESENT:
2289 break;
2290 default:
2291 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2292 "%s: invalid cmd %u\n", __func__, cmd);
2293 return false;
2294 }
2295
2296 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
2297 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2298 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2299 "ofdmWeakSigDetectOff=%d\n",
2300 aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
2301 !aniState->ofdmWeakSigDetectOff);
2302 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2303 "cckWeakSigThreshold=%d, "
2304 "firstepLevel=%d, listenTime=%d\n",
2305 aniState->cckWeakSigThreshold, aniState->firstepLevel,
2306 aniState->listenTime);
2307 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2308 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2309 aniState->cycleCount, aniState->ofdmPhyErrCount,
2310 aniState->cckPhyErrCount);
2311 return true;
2312}
2313
2314static void ath9k_ani_restart(struct ath_hal *ah)
2315{
2316 struct ath_hal_5416 *ahp = AH5416(ah);
2317 struct ar5416AniState *aniState;
2318
2319 if (!DO_ANI(ah))
2320 return;
2321
2322 aniState = ahp->ah_curani;
2323
2324 aniState->listenTime = 0;
2325 if (ahp->ah_hasHwPhyCounters) {
2326 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
2327 aniState->ofdmPhyErrBase = 0;
2328 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2329 "OFDM Trigger is too high for hw counters\n");
2330 } else {
2331 aniState->ofdmPhyErrBase =
2332 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
2333 }
2334 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
2335 aniState->cckPhyErrBase = 0;
2336 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2337 "CCK Trigger is too high for hw counters\n");
2338 } else {
2339 aniState->cckPhyErrBase =
2340 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
2341 }
2342 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2343 "%s: Writing ofdmbase=%u cckbase=%u\n",
2344 __func__, aniState->ofdmPhyErrBase,
2345 aniState->cckPhyErrBase);
2346 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
2347 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
2348 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2349 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2350
2351 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2352 }
2353 aniState->ofdmPhyErrCount = 0;
2354 aniState->cckPhyErrCount = 0;
2355}
2356
2357static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2358{
2359 struct ath_hal_5416 *ahp = AH5416(ah);
2360 struct ath9k_channel *chan = ah->ah_curchan;
2361 struct ar5416AniState *aniState;
2362 enum wireless_mode mode;
2363 int32_t rssi;
2364
2365 if (!DO_ANI(ah))
2366 return;
2367
2368 aniState = ahp->ah_curani;
2369
2370 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2371 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2372 aniState->noiseImmunityLevel + 1)) {
2373 return;
2374 }
2375 }
2376
2377 if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
2378 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2379 aniState->spurImmunityLevel + 1)) {
2380 return;
2381 }
2382 }
2383
2384 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2385 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2386 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2387 aniState->firstepLevel + 1);
2388 }
2389 return;
2390 }
2391 rssi = BEACON_RSSI(ahp);
2392 if (rssi > aniState->rssiThrHigh) {
2393 if (!aniState->ofdmWeakSigDetectOff) {
2394 if (ath9k_hw_ani_control(ah,
2395 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2396 false)) {
2397 ath9k_hw_ani_control(ah,
2398 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2399 0);
2400 return;
2401 }
2402 }
2403 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2404 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2405 aniState->firstepLevel + 1);
2406 return;
2407 }
2408 } else if (rssi > aniState->rssiThrLow) {
2409 if (aniState->ofdmWeakSigDetectOff)
2410 ath9k_hw_ani_control(ah,
2411 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2412 true);
2413 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2414 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2415 aniState->firstepLevel + 1);
2416 return;
2417 } else {
2418 mode = ath9k_hw_chan2wmode(ah, chan);
2419 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2420 if (!aniState->ofdmWeakSigDetectOff)
2421 ath9k_hw_ani_control(ah,
2422 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2423 false);
2424 if (aniState->firstepLevel > 0)
2425 ath9k_hw_ani_control(ah,
2426 ATH9K_ANI_FIRSTEP_LEVEL,
2427 0);
2428 return;
2429 }
2430 }
2431}
2432
2433static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2434{
2435 struct ath_hal_5416 *ahp = AH5416(ah);
2436 struct ath9k_channel *chan = ah->ah_curchan;
2437 struct ar5416AniState *aniState;
2438 enum wireless_mode mode;
2439 int32_t rssi;
2440
2441 if (!DO_ANI(ah))
2442 return;
2443
2444 aniState = ahp->ah_curani;
2445 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2446 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2447 aniState->noiseImmunityLevel + 1)) {
2448 return;
2449 }
2450 }
2451 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2452 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2453 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2454 aniState->firstepLevel + 1);
2455 }
2456 return;
2457 }
2458 rssi = BEACON_RSSI(ahp);
2459 if (rssi > aniState->rssiThrLow) {
2460 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2461 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2462 aniState->firstepLevel + 1);
2463 } else {
2464 mode = ath9k_hw_chan2wmode(ah, chan);
2465 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2466 if (aniState->firstepLevel > 0)
2467 ath9k_hw_ani_control(ah,
2468 ATH9K_ANI_FIRSTEP_LEVEL,
2469 0);
2470 }
2471 }
2472}
2473
2474static void ath9k_ani_reset(struct ath_hal *ah)
2475{
2476 struct ath_hal_5416 *ahp = AH5416(ah);
2477 struct ar5416AniState *aniState;
2478 struct ath9k_channel *chan = ah->ah_curchan;
2479 int index;
2480
2481 if (!DO_ANI(ah))
2482 return;
2483
2484 index = ath9k_hw_get_ani_channel_idx(ah, chan);
2485 aniState = &ahp->ah_ani[index];
2486 ahp->ah_curani = aniState;
2487
2488 if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
2489 && ah->ah_opmode != ATH9K_M_IBSS) {
2490 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2491 "%s: Reset ANI state opmode %u\n", __func__,
2492 ah->ah_opmode);
2493 ahp->ah_stats.ast_ani_reset++;
2494 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
2495 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
2496 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
2497 ath9k_hw_ani_control(ah,
2498 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2499 !ATH9K_ANI_USE_OFDM_WEAK_SIG);
2500 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2501 ATH9K_ANI_CCK_WEAK_SIG_THR);
2502 ath9k_hw_setrxfilter(ah,
2503 ath9k_hw_getrxfilter(ah) |
2504 ATH9K_RX_FILTER_PHYERR);
2505 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2506 ahp->ah_curani->ofdmTrigHigh =
60b67f51 2507 ah->ah_config.ofdm_trig_high;
f078f209 2508 ahp->ah_curani->ofdmTrigLow =
60b67f51 2509 ah->ah_config.ofdm_trig_low;
f078f209 2510 ahp->ah_curani->cckTrigHigh =
60b67f51 2511 ah->ah_config.cck_trig_high;
f078f209 2512 ahp->ah_curani->cckTrigLow =
60b67f51 2513 ah->ah_config.cck_trig_low;
f078f209
LR
2514 }
2515 ath9k_ani_restart(ah);
2516 return;
2517 }
2518
2519 if (aniState->noiseImmunityLevel != 0)
2520 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2521 aniState->noiseImmunityLevel);
2522 if (aniState->spurImmunityLevel != 0)
2523 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2524 aniState->spurImmunityLevel);
2525 if (aniState->ofdmWeakSigDetectOff)
2526 ath9k_hw_ani_control(ah,
2527 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2528 !aniState->ofdmWeakSigDetectOff);
2529 if (aniState->cckWeakSigThreshold)
2530 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2531 aniState->cckWeakSigThreshold);
2532 if (aniState->firstepLevel != 0)
2533 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2534 aniState->firstepLevel);
2535 if (ahp->ah_hasHwPhyCounters) {
2536 ath9k_hw_setrxfilter(ah,
2537 ath9k_hw_getrxfilter(ah) &
2538 ~ATH9K_RX_FILTER_PHYERR);
2539 ath9k_ani_restart(ah);
2540 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2541 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2542
2543 } else {
2544 ath9k_ani_restart(ah);
2545 ath9k_hw_setrxfilter(ah,
2546 ath9k_hw_getrxfilter(ah) |
2547 ATH9K_RX_FILTER_PHYERR);
2548 }
2549}
2550
2551void ath9k_hw_procmibevent(struct ath_hal *ah,
2552 const struct ath9k_node_stats *stats)
2553{
2554 struct ath_hal_5416 *ahp = AH5416(ah);
2555 u32 phyCnt1, phyCnt2;
2556
2557 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
2558
2559 REG_WRITE(ah, AR_FILT_OFDM, 0);
2560 REG_WRITE(ah, AR_FILT_CCK, 0);
2561 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
2562 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
2563
2564 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2565 ahp->ah_stats.ast_nodestats = *stats;
2566
2567 if (!DO_ANI(ah))
2568 return;
2569
2570 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2571 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2572 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
2573 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
2574 struct ar5416AniState *aniState = ahp->ah_curani;
2575 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2576
2577 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2578 ahp->ah_stats.ast_ani_ofdmerrs +=
2579 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2580 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2581
2582 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2583 ahp->ah_stats.ast_ani_cckerrs +=
2584 cckPhyErrCnt - aniState->cckPhyErrCount;
2585 aniState->cckPhyErrCount = cckPhyErrCnt;
2586
2587 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
2588 ath9k_hw_ani_ofdm_err_trigger(ah);
2589 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
2590 ath9k_hw_ani_cck_err_trigger(ah);
2591
2592 ath9k_ani_restart(ah);
2593 }
2594}
2595
2596static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
2597{
2598 struct ath_hal_5416 *ahp = AH5416(ah);
2599 struct ar5416AniState *aniState;
2600 int32_t rssi;
2601
2602 aniState = ahp->ah_curani;
2603
2604 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2605 if (aniState->firstepLevel > 0) {
2606 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2607 aniState->firstepLevel - 1)) {
2608 return;
2609 }
2610 }
2611 } else {
2612 rssi = BEACON_RSSI(ahp);
2613 if (rssi > aniState->rssiThrHigh) {
2614 /* XXX: Handle me */
2615 } else if (rssi > aniState->rssiThrLow) {
2616 if (aniState->ofdmWeakSigDetectOff) {
2617 if (ath9k_hw_ani_control(ah,
2618 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2619 true) ==
2620 true) {
2621 return;
2622 }
2623 }
2624 if (aniState->firstepLevel > 0) {
2625 if (ath9k_hw_ani_control
2626 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2627 aniState->firstepLevel - 1) ==
2628 true) {
2629 return;
2630 }
2631 }
2632 } else {
2633 if (aniState->firstepLevel > 0) {
2634 if (ath9k_hw_ani_control
2635 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2636 aniState->firstepLevel - 1) ==
2637 true) {
2638 return;
2639 }
2640 }
2641 }
2642 }
2643
2644 if (aniState->spurImmunityLevel > 0) {
2645 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2646 aniState->spurImmunityLevel - 1)) {
2647 return;
2648 }
2649 }
2650
2651 if (aniState->noiseImmunityLevel > 0) {
2652 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2653 aniState->noiseImmunityLevel - 1);
2654 return;
2655 }
2656}
2657
2658static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
2659{
2660 struct ath_hal_5416 *ahp = AH5416(ah);
2661 struct ar5416AniState *aniState;
2662 u32 txFrameCount, rxFrameCount, cycleCount;
2663 int32_t listenTime;
2664
2665 txFrameCount = REG_READ(ah, AR_TFCNT);
2666 rxFrameCount = REG_READ(ah, AR_RFCNT);
2667 cycleCount = REG_READ(ah, AR_CCCNT);
2668
2669 aniState = ahp->ah_curani;
2670 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
2671
2672 listenTime = 0;
2673 ahp->ah_stats.ast_ani_lzero++;
2674 } else {
2675 int32_t ccdelta = cycleCount - aniState->cycleCount;
2676 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
2677 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
2678 listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
2679 }
2680 aniState->cycleCount = cycleCount;
2681 aniState->txFrameCount = txFrameCount;
2682 aniState->rxFrameCount = rxFrameCount;
2683
2684 return listenTime;
2685}
2686
2687void ath9k_hw_ani_monitor(struct ath_hal *ah,
2688 const struct ath9k_node_stats *stats,
2689 struct ath9k_channel *chan)
2690{
2691 struct ath_hal_5416 *ahp = AH5416(ah);
2692 struct ar5416AniState *aniState;
2693 int32_t listenTime;
2694
2695 aniState = ahp->ah_curani;
2696 ahp->ah_stats.ast_nodestats = *stats;
2697
2698 listenTime = ath9k_hw_ani_get_listen_time(ah);
2699 if (listenTime < 0) {
2700 ahp->ah_stats.ast_ani_lneg++;
2701 ath9k_ani_restart(ah);
2702 return;
2703 }
2704
2705 aniState->listenTime += listenTime;
2706
2707 if (ahp->ah_hasHwPhyCounters) {
2708 u32 phyCnt1, phyCnt2;
2709 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2710
2711 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2712
2713 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2714 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2715
2716 if (phyCnt1 < aniState->ofdmPhyErrBase ||
2717 phyCnt2 < aniState->cckPhyErrBase) {
2718 if (phyCnt1 < aniState->ofdmPhyErrBase) {
2719 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2720 "%s: phyCnt1 0x%x, resetting "
2721 "counter value to 0x%x\n",
2722 __func__, phyCnt1,
2723 aniState->ofdmPhyErrBase);
2724 REG_WRITE(ah, AR_PHY_ERR_1,
2725 aniState->ofdmPhyErrBase);
2726 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
2727 AR_PHY_ERR_OFDM_TIMING);
2728 }
2729 if (phyCnt2 < aniState->cckPhyErrBase) {
2730 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2731 "%s: phyCnt2 0x%x, resetting "
2732 "counter value to 0x%x\n",
2733 __func__, phyCnt2,
2734 aniState->cckPhyErrBase);
2735 REG_WRITE(ah, AR_PHY_ERR_2,
2736 aniState->cckPhyErrBase);
2737 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
2738 AR_PHY_ERR_CCK_TIMING);
2739 }
2740 return;
2741 }
2742
2743 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2744 ahp->ah_stats.ast_ani_ofdmerrs +=
2745 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2746 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2747
2748 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2749 ahp->ah_stats.ast_ani_cckerrs +=
2750 cckPhyErrCnt - aniState->cckPhyErrCount;
2751 aniState->cckPhyErrCount = cckPhyErrCnt;
2752 }
2753
2754 if (!DO_ANI(ah))
2755 return;
2756
2757 if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
2758 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
2759 aniState->ofdmTrigLow / 1000 &&
2760 aniState->cckPhyErrCount <= aniState->listenTime *
2761 aniState->cckTrigLow / 1000)
2762 ath9k_hw_ani_lower_immunity(ah);
2763 ath9k_ani_restart(ah);
2764 } else if (aniState->listenTime > ahp->ah_aniPeriod) {
2765 if (aniState->ofdmPhyErrCount > aniState->listenTime *
2766 aniState->ofdmTrigHigh / 1000) {
2767 ath9k_hw_ani_ofdm_err_trigger(ah);
2768 ath9k_ani_restart(ah);
2769 } else if (aniState->cckPhyErrCount >
2770 aniState->listenTime * aniState->cckTrigHigh /
2771 1000) {
2772 ath9k_hw_ani_cck_err_trigger(ah);
2773 ath9k_ani_restart(ah);
2774 }
2775 }
2776}
2777
2778#ifndef ATH_NF_PER_CHAN
2779static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
2780{
2781 int i, j;
2782
2783 for (i = 0; i < NUM_NF_READINGS; i++) {
2784 ah->nfCalHist[i].currIndex = 0;
2785 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
2786 ah->nfCalHist[i].invalidNFcount =
2787 AR_PHY_CCA_FILTERWINDOW_LENGTH;
2788 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
2789 ah->nfCalHist[i].nfCalBuffer[j] =
2790 AR_PHY_CCA_MAX_GOOD_VALUE;
2791 }
2792 }
2793 return;
2794}
2795#endif
2796
2797static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2798 u32 gpio, u32 type)
2799{
2800 int addr;
2801 u32 gpio_shift, tmp;
2802
2803 if (gpio > 11)
2804 addr = AR_GPIO_OUTPUT_MUX3;
2805 else if (gpio > 5)
2806 addr = AR_GPIO_OUTPUT_MUX2;
2807 else
2808 addr = AR_GPIO_OUTPUT_MUX1;
2809
2810 gpio_shift = (gpio % 6) * 5;
2811
2812 if (AR_SREV_9280_20_OR_LATER(ah)
2813 || (addr != AR_GPIO_OUTPUT_MUX1)) {
2814 REG_RMW(ah, addr, (type << gpio_shift),
2815 (0x1f << gpio_shift));
2816 } else {
2817 tmp = REG_READ(ah, addr);
2818 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
2819 tmp &= ~(0x1f << gpio_shift);
2820 tmp |= (type << gpio_shift);
2821 REG_WRITE(ah, addr, tmp);
2822 }
2823}
2824
2825static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2826 enum ath9k_gpio_output_mux_type
2827 halSignalType)
2828{
2829 u32 ah_signal_type;
2830 u32 gpio_shift;
2831
2832 static u32 MuxSignalConversionTable[] = {
2833
2834 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2835
2836 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2837
2838 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2839
2840 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2841
2842 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2843 };
2844
2845 if ((halSignalType >= 0)
2846 && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2847 ah_signal_type = MuxSignalConversionTable[halSignalType];
2848 else
2849 return false;
2850
2851 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2852
2853 gpio_shift = 2 * gpio;
2854
2855 REG_RMW(ah,
2856 AR_GPIO_OE_OUT,
2857 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2858 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2859
2860 return true;
2861}
2862
2863static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio,
2864 u32 val)
2865{
2866 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2867 AR_GPIO_BIT(gpio));
2868 return true;
2869}
2870
2871static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2872{
60b67f51 2873 if (gpio >= ah->ah_caps.num_gpio_pins)
f078f209
LR
2874 return 0xffffffff;
2875
2876 if (AR_SREV_9280_10_OR_LATER(ah)) {
2877 return (MS
2878 (REG_READ(ah, AR_GPIO_IN_OUT),
2879 AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
2880 } else {
2881 return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
2882 AR_GPIO_BIT(gpio)) != 0;
2883 }
2884}
2885
2886static inline int ath9k_hw_post_attach(struct ath_hal *ah)
2887{
2888 int ecode;
2889
2890 if (!ath9k_hw_chip_test(ah)) {
2891 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2892 "%s: hardware self-test failed\n", __func__);
2893 return -ENODEV;
2894 }
2895
2896 ecode = ath9k_hw_rf_claim(ah);
2897 if (ecode != 0)
2898 return ecode;
2899
2900 ecode = ath9k_hw_eeprom_attach(ah);
2901 if (ecode != 0)
2902 return ecode;
2903 ecode = ath9k_hw_rfattach(ah);
2904 if (ecode != 0)
2905 return ecode;
2906
2907 if (!AR_SREV_9100(ah)) {
2908 ath9k_hw_ani_setup(ah);
2909 ath9k_hw_ani_attach(ah);
2910 }
2911 return 0;
2912}
2913
2914static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
2915 struct ar5416_eeprom *pEepData,
2916 u32 reg, u32 value)
2917{
2918 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
2919
2920 switch (ah->ah_devid) {
2921 case AR9280_DEVID_PCI:
2922 if (reg == 0x7894) {
2923 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2924 "ini VAL: %x EEPROM: %x\n", value,
2925 (pBase->version & 0xff));
2926
2927 if ((pBase->version & 0xff) > 0x0a) {
2928 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2929 "PWDCLKIND: %d\n",
2930 pBase->pwdclkind);
2931 value &= ~AR_AN_TOP2_PWDCLKIND;
2932 value |= AR_AN_TOP2_PWDCLKIND & (pBase->
2933 pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
2934 } else {
2935 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2936 "PWDCLKIND Earlier Rev\n");
2937 }
2938
2939 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2940 "final ini VAL: %x\n", value);
2941 }
2942 break;
2943 }
2944 return value;
2945}
2946
2947static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2948{
2949 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 2950 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
2951 u16 capField = 0, eeval;
2952
2953 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
2954
2955 ah->ah_currentRD = eeval;
2956
2957 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
2958 ah->ah_currentRDExt = eeval;
2959
2960 capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
2961
2962 if (ah->ah_opmode != ATH9K_M_HOSTAP &&
2963 ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2964 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
2965 ah->ah_currentRD += 5;
2966 else if (ah->ah_currentRD == 0x41)
2967 ah->ah_currentRD = 0x43;
2968 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
2969 "%s: regdomain mapped to 0x%x\n", __func__,
2970 ah->ah_currentRD);
2971 }
2972
60b67f51 2973 pCap->wireless_modes = 0;
f078f209
LR
2974 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2975
2976 if (eeval & AR5416_OPFLAGS_11A) {
60b67f51
S
2977 pCap->wireless_modes |= ATH9K_MODE_SEL_11A |
2978 ((!ah->ah_config.ht_enable
f078f209
LR
2979 || (eeval & AR5416_OPFLAGS_N_5G_HT20)) ? 0
2980 : (ATH9K_MODE_SEL_11NA_HT20 |
2981 ((eeval & AR5416_OPFLAGS_N_5G_HT40) ? 0
2982 : (ATH9K_MODE_SEL_11NA_HT40PLUS |
2983 ATH9K_MODE_SEL_11NA_HT40MINUS))));
2984 }
2985 if (eeval & AR5416_OPFLAGS_11G) {
60b67f51 2986 pCap->wireless_modes |=
f078f209 2987 ATH9K_MODE_SEL_11B | ATH9K_MODE_SEL_11G |
60b67f51 2988 ((!ah->ah_config.ht_enable
f078f209
LR
2989 || (eeval & AR5416_OPFLAGS_N_2G_HT20)) ? 0
2990 : (ATH9K_MODE_SEL_11NG_HT20 |
2991 ((eeval & AR5416_OPFLAGS_N_2G_HT40) ? 0
2992 : (ATH9K_MODE_SEL_11NG_HT40PLUS |
2993 ATH9K_MODE_SEL_11NG_HT40MINUS))));
2994
2995 }
60b67f51 2996 pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
f078f209
LR
2997 if ((ah->ah_isPciExpress)
2998 || (eeval & AR5416_OPFLAGS_11A)) {
60b67f51 2999 pCap->rx_chainmask =
f078f209
LR
3000 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3001 } else {
60b67f51 3002 pCap->rx_chainmask =
f078f209
LR
3003 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3004 }
3005
3006 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3007 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3008
60b67f51
S
3009 pCap->low_2ghz_chan = 2312;
3010 pCap->high_2ghz_chan = 2732;
f078f209 3011
60b67f51
S
3012 pCap->low_5ghz_chan = 4920;
3013 pCap->high_5ghz_chan = 6100;
f078f209 3014
60b67f51
S
3015 pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
3016 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
3017 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
f078f209 3018
60b67f51
S
3019 pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
3020 pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
3021 pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
f078f209 3022
60b67f51 3023 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
f078f209 3024
60b67f51
S
3025 if (ah->ah_config.ht_enable)
3026 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3027 else
3028 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
3029
3030 pCap->hw_caps |= ATH9K_HW_CAP_GTT;
3031 pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
3032 pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
3033 pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
f078f209
LR
3034
3035 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
60b67f51 3036 pCap->total_queues =
f078f209
LR
3037 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3038 else
60b67f51 3039 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
f078f209
LR
3040
3041 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
60b67f51 3042 pCap->keycache_size =
f078f209
LR
3043 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3044 else
60b67f51 3045 pCap->keycache_size = AR_KEYTABLE_SIZE;
f078f209 3046
60b67f51
S
3047 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3048 pCap->num_mr_retries = 4;
3049 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
f078f209
LR
3050
3051 if (AR_SREV_9280_10_OR_LATER(ah))
60b67f51 3052 pCap->num_gpio_pins = AR928X_NUM_GPIO;
f078f209 3053 else
60b67f51 3054 pCap->num_gpio_pins = AR_NUM_GPIO;
f078f209
LR
3055
3056 if (AR_SREV_9280_10_OR_LATER(ah)) {
60b67f51
S
3057 pCap->hw_caps |= ATH9K_HW_CAP_WOW;
3058 pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
f078f209 3059 } else {
60b67f51
S
3060 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
3061 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
f078f209
LR
3062 }
3063
3064 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
60b67f51
S
3065 pCap->hw_caps |= ATH9K_HW_CAP_CST;
3066 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
f078f209 3067 } else {
60b67f51 3068 pCap->rts_aggr_limit = (8 * 1024);
f078f209
LR
3069 }
3070
60b67f51 3071 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
f078f209
LR
3072
3073 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3074 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3075 ahp->ah_gpioSelect =
3076 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3077 ahp->ah_polarity =
3078 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3079
60b67f51 3080 ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true,
f078f209 3081 NULL);
60b67f51 3082 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
f078f209
LR
3083 }
3084
3085 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3086 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3087 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3088 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3089 (ah->ah_macVersion == AR_SREV_VERSION_9280))
60b67f51 3090 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
f078f209 3091 else
60b67f51 3092 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
f078f209
LR
3093
3094 if (AR_SREV_9280(ah))
60b67f51 3095 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
f078f209 3096 else
60b67f51 3097 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
f078f209
LR
3098
3099 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
60b67f51 3100 pCap->reg_cap =
f078f209
LR
3101 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3102 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3103 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3104 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3105 } else {
60b67f51 3106 pCap->reg_cap =
f078f209
LR
3107 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3108 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3109 }
3110
60b67f51 3111 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
f078f209 3112
60b67f51 3113 pCap->num_antcfg_5ghz =
f078f209 3114 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_5GHZ);
60b67f51 3115 pCap->num_antcfg_2ghz =
f078f209
LR
3116 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_2GHZ);
3117
3118 return true;
3119}
3120
3121static void ar5416DisablePciePhy(struct ath_hal *ah)
3122{
3123 if (!AR_SREV_9100(ah))
3124 return;
3125
3126 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3127 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3128 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3129 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3130 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3131 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3132 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3133 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3134 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3135
3136 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3137}
3138
3139static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3140{
3141 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3142 if (setChip) {
3143 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3144 AR_RTC_FORCE_WAKE_EN);
3145 if (!AR_SREV_9100(ah))
3146 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3147
3148 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3149 AR_RTC_RESET_EN);
3150 }
3151}
3152
3153static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3154{
3155 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3156 if (setChip) {
60b67f51 3157 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209 3158
60b67f51 3159 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
f078f209
LR
3160 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3161 AR_RTC_FORCE_WAKE_ON_INT);
3162 } else {
3163 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3164 AR_RTC_FORCE_WAKE_EN);
3165 }
3166 }
3167}
3168
3169static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3170 int setChip)
3171{
3172 u32 val;
3173 int i;
3174
3175 if (setChip) {
3176 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3177 AR_RTC_STATUS_SHUTDOWN) {
3178 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3179 != true) {
3180 return false;
3181 }
3182 }
3183 if (AR_SREV_9100(ah))
3184 REG_SET_BIT(ah, AR_RTC_RESET,
3185 AR_RTC_RESET_EN);
3186
3187 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3188 AR_RTC_FORCE_WAKE_EN);
3189 udelay(50);
3190
3191 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3192 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3193 if (val == AR_RTC_STATUS_ON)
3194 break;
3195 udelay(50);
3196 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3197 AR_RTC_FORCE_WAKE_EN);
3198 }
3199 if (i == 0) {
3200 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3201 "%s: Failed to wakeup in %uus\n",
3202 __func__, POWER_UP_TIME / 20);
3203 return false;
3204 }
3205 }
3206
3207 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3208 return true;
3209}
3210
3211bool ath9k_hw_setpower(struct ath_hal *ah,
3212 enum ath9k_power_mode mode)
3213{
3214 struct ath_hal_5416 *ahp = AH5416(ah);
3215 static const char *modes[] = {
3216 "AWAKE",
3217 "FULL-SLEEP",
3218 "NETWORK SLEEP",
3219 "UNDEFINED"
3220 };
3221 int status = true, setChip = true;
3222
3223 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3224 modes[ahp->ah_powerMode], modes[mode],
3225 setChip ? "set chip " : "");
3226
3227 switch (mode) {
3228 case ATH9K_PM_AWAKE:
3229 status = ath9k_hw_set_power_awake(ah, setChip);
3230 break;
3231 case ATH9K_PM_FULL_SLEEP:
3232 ath9k_set_power_sleep(ah, setChip);
3233 ahp->ah_chipFullSleep = true;
3234 break;
3235 case ATH9K_PM_NETWORK_SLEEP:
3236 ath9k_set_power_network_sleep(ah, setChip);
3237 break;
3238 default:
3239 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3240 "%s: unknown power mode %u\n", __func__, mode);
3241 return false;
3242 }
3243 ahp->ah_powerMode = mode;
3244 return status;
3245}
3246
3247static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3248 struct ath_softc *sc,
3249 void __iomem *mem,
3250 int *status)
3251{
3252 struct ath_hal_5416 *ahp;
3253 struct ath_hal *ah;
3254 int ecode;
3255#ifndef CONFIG_SLOW_ANT_DIV
3256 u32 i;
3257 u32 j;
3258#endif
3259
3260 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3261 if (ahp == NULL)
3262 return NULL;
3263
3264 ah = &ahp->ah;
3265
3266 ath9k_hw_set_defaults(ah);
3267
60b67f51 3268 if (ah->ah_config.intr_mitigation != 0)
f078f209
LR
3269 ahp->ah_intrMitigation = true;
3270
3271 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3272 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3273 __func__);
3274 ecode = -EIO;
3275 goto bad;
3276 }
3277
3278 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3279 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3280 __func__);
3281 ecode = -EIO;
3282 goto bad;
3283 }
3284
60b67f51 3285 if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
f078f209 3286 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
60b67f51 3287 ah->ah_config.serialize_regmode =
f078f209
LR
3288 SER_REG_MODE_ON;
3289 } else {
60b67f51 3290 ah->ah_config.serialize_regmode =
f078f209
LR
3291 SER_REG_MODE_OFF;
3292 }
3293 }
3294 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
60b67f51
S
3295 "%s: serialize_regmode is %d\n",
3296 __func__, ah->ah_config.serialize_regmode);
f078f209
LR
3297
3298 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3299 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3300 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3301 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3302 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3303 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3304 "this driver\n", __func__,
3305 ah->ah_macVersion, ah->ah_macRev);
3306 ecode = -EOPNOTSUPP;
3307 goto bad;
3308 }
3309
3310 if (AR_SREV_9100(ah)) {
3311 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3312 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3313 ah->ah_isPciExpress = false;
3314 }
3315 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3316
3317 if (AR_SREV_9160_10_OR_LATER(ah)) {
3318 if (AR_SREV_9280_10_OR_LATER(ah)) {
3319 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3320 ahp->ah_adcGainCalData.calData =
3321 &adc_gain_cal_single_sample;
3322 ahp->ah_adcDcCalData.calData =
3323 &adc_dc_cal_single_sample;
3324 ahp->ah_adcDcCalInitData.calData =
3325 &adc_init_dc_cal;
3326 } else {
3327 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3328 ahp->ah_adcGainCalData.calData =
3329 &adc_gain_cal_multi_sample;
3330 ahp->ah_adcDcCalData.calData =
3331 &adc_dc_cal_multi_sample;
3332 ahp->ah_adcDcCalInitData.calData =
3333 &adc_init_dc_cal;
3334 }
3335 ahp->ah_suppCals =
3336 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3337 }
3338
3339 if (AR_SREV_9160(ah)) {
60b67f51 3340 ah->ah_config.enable_ani = 1;
f078f209
LR
3341 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3342 ATH9K_ANI_FIRSTEP_LEVEL);
3343 } else {
3344 ahp->ah_ani_function = ATH9K_ANI_ALL;
3345 if (AR_SREV_9280_10_OR_LATER(ah)) {
3346 ahp->ah_ani_function &=
3347 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3348 }
3349 }
3350
3351 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3352 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3353 ah->ah_macVersion, ah->ah_macRev);
3354
3355 if (AR_SREV_9280_20_OR_LATER(ah)) {
3356 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3357 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3358 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3359 ARRAY_SIZE(ar9280Common_9280_2), 2);
3360
60b67f51 3361 if (ah->ah_config.pcie_clock_req) {
f078f209
LR
3362 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3363 ar9280PciePhy_clkreq_off_L1_9280,
3364 ARRAY_SIZE
3365 (ar9280PciePhy_clkreq_off_L1_9280),
3366 2);
3367 } else {
3368 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3369 ar9280PciePhy_clkreq_always_on_L1_9280,
3370 ARRAY_SIZE
3371 (ar9280PciePhy_clkreq_always_on_L1_9280),
3372 2);
3373 }
3374 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3375 ar9280Modes_fast_clock_9280_2,
3376 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3377 3);
3378 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3379 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3380 ARRAY_SIZE(ar9280Modes_9280), 6);
3381 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3382 ARRAY_SIZE(ar9280Common_9280), 2);
3383 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3384 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3385 ARRAY_SIZE(ar5416Modes_9160), 6);
3386 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3387 ARRAY_SIZE(ar5416Common_9160), 2);
3388 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3389 ARRAY_SIZE(ar5416Bank0_9160), 2);
3390 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3391 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3392 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3393 ARRAY_SIZE(ar5416Bank1_9160), 2);
3394 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3395 ARRAY_SIZE(ar5416Bank2_9160), 2);
3396 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3397 ARRAY_SIZE(ar5416Bank3_9160), 3);
3398 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3399 ARRAY_SIZE(ar5416Bank6_9160), 3);
3400 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3401 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3402 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3403 ARRAY_SIZE(ar5416Bank7_9160), 2);
3404 if (AR_SREV_9160_11(ah)) {
3405 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3406 ar5416Addac_91601_1,
3407 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3408 } else {
3409 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3410 ARRAY_SIZE(ar5416Addac_9160), 2);
3411 }
3412 } else if (AR_SREV_9100_OR_LATER(ah)) {
3413 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3414 ARRAY_SIZE(ar5416Modes_9100), 6);
3415 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3416 ARRAY_SIZE(ar5416Common_9100), 2);
3417 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3418 ARRAY_SIZE(ar5416Bank0_9100), 2);
3419 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3420 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3421 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3422 ARRAY_SIZE(ar5416Bank1_9100), 2);
3423 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3424 ARRAY_SIZE(ar5416Bank2_9100), 2);
3425 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3426 ARRAY_SIZE(ar5416Bank3_9100), 3);
3427 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3428 ARRAY_SIZE(ar5416Bank6_9100), 3);
3429 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3430 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3431 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3432 ARRAY_SIZE(ar5416Bank7_9100), 2);
3433 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3434 ARRAY_SIZE(ar5416Addac_9100), 2);
3435 } else {
3436 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3437 ARRAY_SIZE(ar5416Modes), 6);
3438 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3439 ARRAY_SIZE(ar5416Common), 2);
3440 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3441 ARRAY_SIZE(ar5416Bank0), 2);
3442 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3443 ARRAY_SIZE(ar5416BB_RfGain), 3);
3444 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3445 ARRAY_SIZE(ar5416Bank1), 2);
3446 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3447 ARRAY_SIZE(ar5416Bank2), 2);
3448 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3449 ARRAY_SIZE(ar5416Bank3), 3);
3450 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3451 ARRAY_SIZE(ar5416Bank6), 3);
3452 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3453 ARRAY_SIZE(ar5416Bank6TPC), 3);
3454 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3455 ARRAY_SIZE(ar5416Bank7), 2);
3456 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3457 ARRAY_SIZE(ar5416Addac), 2);
3458 }
3459
3460 if (ah->ah_isPciExpress)
3461 ath9k_hw_configpcipowersave(ah, 0);
3462 else
3463 ar5416DisablePciePhy(ah);
3464
3465 ecode = ath9k_hw_post_attach(ah);
3466 if (ecode != 0)
3467 goto bad;
3468
3469#ifndef CONFIG_SLOW_ANT_DIV
3470 if (ah->ah_devid == AR9280_DEVID_PCI) {
3471 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3472 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3473
3474 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3475 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3476
3477 INI_RA(&ahp->ah_iniModes, i, j) =
3478 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3479 reg, val);
3480 }
3481 }
3482 }
3483#endif
3484
3485 if (!ath9k_hw_fill_cap_info(ah)) {
3486 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3487 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3488 ecode = -EINVAL;
3489 goto bad;
3490 }
3491
3492 ecode = ath9k_hw_init_macaddr(ah);
3493 if (ecode != 0) {
3494 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3495 "%s: failed initializing mac address\n",
3496 __func__);
3497 goto bad;
3498 }
3499
3500 if (AR_SREV_9285(ah))
3501 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3502 else
3503 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3504
3505#ifndef ATH_NF_PER_CHAN
3506
3507 ath9k_init_nfcal_hist_buffer(ah);
3508#endif
3509
3510 return ah;
3511
3512bad:
3513 if (ahp)
3514 ath9k_hw_detach((struct ath_hal *) ahp);
3515 if (status)
3516 *status = ecode;
3517 return NULL;
3518}
3519
3520void ath9k_hw_detach(struct ath_hal *ah)
3521{
3522 if (!AR_SREV_9100(ah))
3523 ath9k_hw_ani_detach(ah);
3524 ath9k_hw_rfdetach(ah);
3525
3526 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3527 kfree(ah);
3528}
3529
3530bool ath9k_get_channel_edges(struct ath_hal *ah,
3531 u16 flags, u16 *low,
3532 u16 *high)
3533{
60b67f51 3534 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
3535
3536 if (flags & CHANNEL_5GHZ) {
60b67f51
S
3537 *low = pCap->low_5ghz_chan;
3538 *high = pCap->high_5ghz_chan;
f078f209
LR
3539 return true;
3540 }
3541 if ((flags & CHANNEL_2GHZ)) {
60b67f51
S
3542 *low = pCap->low_2ghz_chan;
3543 *high = pCap->high_2ghz_chan;
f078f209
LR
3544
3545 return true;
3546 }
3547 return false;
3548}
3549
3550static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3551 u8 pwrMax,
3552 u8 *pPwrList,
3553 u8 *pVpdList,
3554 u16
3555 numIntercepts,
3556 u8 *pRetVpdList)
3557{
3558 u16 i, k;
3559 u8 currPwr = pwrMin;
3560 u16 idxL = 0, idxR = 0;
3561
3562 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3563 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3564 numIntercepts, &(idxL),
3565 &(idxR));
3566 if (idxR < 1)
3567 idxR = 1;
3568 if (idxL == numIntercepts - 1)
3569 idxL = (u16) (numIntercepts - 2);
3570 if (pPwrList[idxL] == pPwrList[idxR])
3571 k = pVpdList[idxL];
3572 else
3573 k = (u16) (((currPwr -
3574 pPwrList[idxL]) *
3575 pVpdList[idxR] +
3576 (pPwrList[idxR] -
3577 currPwr) * pVpdList[idxL]) /
3578 (pPwrList[idxR] -
3579 pPwrList[idxL]));
3580 pRetVpdList[i] = (u8) k;
3581 currPwr += 2;
3582 }
3583
3584 return true;
3585}
3586
3587static inline void
3588ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3589 struct ath9k_channel *chan,
3590 struct cal_data_per_freq *pRawDataSet,
3591 u8 *bChans,
3592 u16 availPiers,
3593 u16 tPdGainOverlap,
3594 int16_t *pMinCalPower,
3595 u16 *pPdGainBoundaries,
3596 u8 *pPDADCValues,
3597 u16 numXpdGains)
3598{
3599 int i, j, k;
3600 int16_t ss;
3601 u16 idxL = 0, idxR = 0, numPiers;
3602 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3603 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3604 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3605 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3606 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3607 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3608
3609 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3610 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3611 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3612 int16_t vpdStep;
3613 int16_t tmpVal;
3614 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3615 bool match;
3616 int16_t minDelta = 0;
3617 struct chan_centers centers;
3618
3619 ath9k_hw_get_channel_centers(ah, chan, &centers);
3620
3621 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3622 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3623 break;
3624 }
3625
3626 match = ath9k_hw_get_lower_upper_index((u8)
3627 FREQ2FBIN(centers.
3628 synth_center,
3629 IS_CHAN_2GHZ
3630 (chan)), bChans,
3631 numPiers, &idxL, &idxR);
3632
3633 if (match) {
3634 for (i = 0; i < numXpdGains; i++) {
3635 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3636 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3637 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3638 pRawDataSet[idxL].
3639 pwrPdg[i],
3640 pRawDataSet[idxL].
3641 vpdPdg[i],
3642 AR5416_PD_GAIN_ICEPTS,
3643 vpdTableI[i]);
3644 }
3645 } else {
3646 for (i = 0; i < numXpdGains; i++) {
3647 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3648 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3649 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3650 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3651
3652 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3653
3654 maxPwrT4[i] =
3655 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3656 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3657
3658
3659 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3660 pPwrL, pVpdL,
3661 AR5416_PD_GAIN_ICEPTS,
3662 vpdTableL[i]);
3663 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3664 pPwrR, pVpdR,
3665 AR5416_PD_GAIN_ICEPTS,
3666 vpdTableR[i]);
3667
3668 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3669 vpdTableI[i][j] =
3670 (u8) (ath9k_hw_interpolate
3671 ((u16)
3672 FREQ2FBIN(centers.
3673 synth_center,
3674 IS_CHAN_2GHZ
3675 (chan)),
3676 bChans[idxL],
3677 bChans[idxR], vpdTableL[i]
3678 [j], vpdTableR[i]
3679 [j]));
3680 }
3681 }
3682 }
3683
3684 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3685
3686 k = 0;
3687 for (i = 0; i < numXpdGains; i++) {
3688 if (i == (numXpdGains - 1))
3689 pPdGainBoundaries[i] =
3690 (u16) (maxPwrT4[i] / 2);
3691 else
3692 pPdGainBoundaries[i] =
3693 (u16) ((maxPwrT4[i] +
3694 minPwrT4[i + 1]) / 4);
3695
3696 pPdGainBoundaries[i] =
3697 min((u16) AR5416_MAX_RATE_POWER,
3698 pPdGainBoundaries[i]);
3699
3700 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3701 minDelta = pPdGainBoundaries[0] - 23;
3702 pPdGainBoundaries[0] = 23;
3703 } else {
3704 minDelta = 0;
3705 }
3706
3707 if (i == 0) {
3708 if (AR_SREV_9280_10_OR_LATER(ah))
3709 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3710 else
3711 ss = 0;
3712 } else {
3713 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3714 (minPwrT4[i] / 2)) -
3715 tPdGainOverlap + 1 + minDelta);
3716 }
3717 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3718 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3719
3720 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3721 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3722 pPDADCValues[k++] =
3723 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3724 ss++;
3725 }
3726
3727 sizeCurrVpdTable =
3728 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3729 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3730 (minPwrT4[i] / 2));
3731 maxIndex = (tgtIndex <
3732 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3733
3734 while ((ss < maxIndex)
3735 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3736 pPDADCValues[k++] = vpdTableI[i][ss++];
3737 }
3738
3739 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3740 vpdTableI[i][sizeCurrVpdTable - 2]);
3741 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3742
3743 if (tgtIndex > maxIndex) {
3744 while ((ss <= tgtIndex)
3745 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3746 tmpVal = (int16_t) ((vpdTableI[i]
3747 [sizeCurrVpdTable -
3748 1] + (ss - maxIndex +
3749 1) * vpdStep));
3750 pPDADCValues[k++] = (u8) ((tmpVal >
3751 255) ? 255 : tmpVal);
3752 ss++;
3753 }
3754 }
3755 }
3756
3757 while (i < AR5416_PD_GAINS_IN_MASK) {
3758 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3759 i++;
3760 }
3761
3762 while (k < AR5416_NUM_PDADC_VALUES) {
3763 pPDADCValues[k] = pPDADCValues[k - 1];
3764 k++;
3765 }
3766 return;
3767}
3768
3769static inline bool
3770ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3771 struct ar5416_eeprom *pEepData,
3772 struct ath9k_channel *chan,
3773 int16_t *pTxPowerIndexOffset)
3774{
3775 struct cal_data_per_freq *pRawDataset;
3776 u8 *pCalBChans = NULL;
3777 u16 pdGainOverlap_t2;
3778 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3779 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3780 u16 numPiers, i, j;
3781 int16_t tMinCalPower;
3782 u16 numXpdGain, xpdMask;
3783 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3784 u32 reg32, regOffset, regChainOffset;
3785 int16_t modalIdx;
3786 struct ath_hal_5416 *ahp = AH5416(ah);
3787
3788 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3789 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3790
3791 if ((pEepData->baseEepHeader.
3792 version & AR5416_EEP_VER_MINOR_MASK) >=
3793 AR5416_EEP_MINOR_VER_2) {
3794 pdGainOverlap_t2 =
3795 pEepData->modalHeader[modalIdx].pdGainOverlap;
3796 } else {
3797 pdGainOverlap_t2 =
3798 (u16) (MS
3799 (REG_READ(ah, AR_PHY_TPCRG5),
3800 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3801 }
3802
3803 if (IS_CHAN_2GHZ(chan)) {
3804 pCalBChans = pEepData->calFreqPier2G;
3805 numPiers = AR5416_NUM_2G_CAL_PIERS;
3806 } else {
3807 pCalBChans = pEepData->calFreqPier5G;
3808 numPiers = AR5416_NUM_5G_CAL_PIERS;
3809 }
3810
3811 numXpdGain = 0;
3812
3813 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3814 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3815 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3816 break;
3817 xpdGainValues[numXpdGain] =
3818 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3819 numXpdGain++;
3820 }
3821 }
3822
3823 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3824 (numXpdGain - 1) & 0x3);
3825 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3826 xpdGainValues[0]);
3827 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3828 xpdGainValues[1]);
3829 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3830 xpdGainValues[2]);
3831
3832 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3833 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3834 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3835 && (i != 0)) {
3836 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3837 } else
3838 regChainOffset = i * 0x1000;
3839 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3840 if (IS_CHAN_2GHZ(chan))
3841 pRawDataset = pEepData->calPierData2G[i];
3842 else
3843 pRawDataset = pEepData->calPierData5G[i];
3844
3845 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3846 pRawDataset,
3847 pCalBChans,
3848 numPiers,
3849 pdGainOverlap_t2,
3850 &tMinCalPower,
3851 gainBoundaries,
3852 pdadcValues,
3853 numXpdGain);
3854
3855 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3856
3857 REG_WRITE(ah,
3858 AR_PHY_TPCRG5 + regChainOffset,
3859 SM(pdGainOverlap_t2,
3860 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3861 | SM(gainBoundaries[0],
3862 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3863 | SM(gainBoundaries[1],
3864 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3865 | SM(gainBoundaries[2],
3866 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3867 | SM(gainBoundaries[3],
3868 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3869 }
3870
3871 regOffset =
3872 AR_PHY_BASE + (672 << 2) + regChainOffset;
3873 for (j = 0; j < 32; j++) {
3874 reg32 =
3875 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3876 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3877 8) | ((pdadcValues[4 * j + 2] &
3878 0xFF) << 16) |
3879 ((pdadcValues[4 * j + 3] & 0xFF) <<
3880 24);
3881 REG_WRITE(ah, regOffset, reg32);
3882
3883 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3884 "PDADC (%d,%4x): %4.4x %8.8x\n",
3885 i, regChainOffset, regOffset,
3886 reg32);
3887 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3888 "PDADC: Chain %d | PDADC %3d Value %3d | "
3889 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3890 "PDADC %3d Value %3d |\n",
3891 i, 4 * j, pdadcValues[4 * j],
3892 4 * j + 1, pdadcValues[4 * j + 1],
3893 4 * j + 2, pdadcValues[4 * j + 2],
3894 4 * j + 3,
3895 pdadcValues[4 * j + 3]);
3896
3897 regOffset += 4;
3898 }
3899 }
3900 }
3901 *pTxPowerIndexOffset = 0;
3902
3903 return true;
3904}
3905
3906void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3907{
3908 struct ath_hal_5416 *ahp = AH5416(ah);
3909 u8 i;
3910
3911 if (ah->ah_isPciExpress != true)
3912 return;
3913
60b67f51 3914 if (ah->ah_config.pcie_powersave_enable == 2)
f078f209
LR
3915 return;
3916
3917 if (restore)
3918 return;
3919
3920 if (AR_SREV_9280_20_OR_LATER(ah)) {
3921 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3922 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3923 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3924 }
3925 udelay(1000);
3926 } else if (AR_SREV_9280(ah)
3927 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3928 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3929 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3930
3931 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3932 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3933 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3934
60b67f51 3935 if (ah->ah_config.pcie_clock_req)
f078f209
LR
3936 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3937 else
3938 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3939
3940 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3941 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3942 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3943
3944 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3945
3946 udelay(1000);
3947 } else {
3948 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3950 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3954 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3955 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3956 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3957 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3958 }
3959
3960 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3961
60b67f51
S
3962 if (ah->ah_config.pcie_waen) {
3963 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
f078f209
LR
3964 } else {
3965 if (AR_SREV_9280(ah))
3966 REG_WRITE(ah, AR_WA, 0x0040073f);
3967 else
3968 REG_WRITE(ah, AR_WA, 0x0000073f);
3969 }
3970}
3971
3972static inline void
3973ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3974 struct ath9k_channel *chan,
3975 struct cal_target_power_leg *powInfo,
3976 u16 numChannels,
3977 struct cal_target_power_leg *pNewPower,
3978 u16 numRates,
3979 bool isExtTarget)
3980{
3981 u16 clo, chi;
3982 int i;
3983 int matchIndex = -1, lowIndex = -1;
3984 u16 freq;
3985 struct chan_centers centers;
3986
3987 ath9k_hw_get_channel_centers(ah, chan, &centers);
3988 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
3989
3990 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
3991 IS_CHAN_2GHZ(chan))) {
3992 matchIndex = 0;
3993 } else {
3994 for (i = 0; (i < numChannels)
3995 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
3996 if (freq ==
3997 ath9k_hw_fbin2freq(powInfo[i].bChannel,
3998 IS_CHAN_2GHZ(chan))) {
3999 matchIndex = i;
4000 break;
4001 } else if ((freq <
4002 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4003 IS_CHAN_2GHZ(chan)))
4004 && (freq >
4005 ath9k_hw_fbin2freq(powInfo[i - 1].
4006 bChannel,
4007 IS_CHAN_2GHZ
4008 (chan)))) {
4009 lowIndex = i - 1;
4010 break;
4011 }
4012 }
4013 if ((matchIndex == -1) && (lowIndex == -1))
4014 matchIndex = i - 1;
4015 }
4016
4017 if (matchIndex != -1) {
4018 *pNewPower = powInfo[matchIndex];
4019 } else {
4020 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4021 IS_CHAN_2GHZ(chan));
4022 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4023 IS_CHAN_2GHZ(chan));
4024
4025 for (i = 0; i < numRates; i++) {
4026 pNewPower->tPow2x[i] =
4027 (u8) ath9k_hw_interpolate(freq, clo, chi,
4028 powInfo
4029 [lowIndex].
4030 tPow2x[i],
4031 powInfo
4032 [lowIndex +
4033 1].tPow2x[i]);
4034 }
4035 }
4036}
4037
4038static inline void
4039ath9k_hw_get_target_powers(struct ath_hal *ah,
4040 struct ath9k_channel *chan,
4041 struct cal_target_power_ht *powInfo,
4042 u16 numChannels,
4043 struct cal_target_power_ht *pNewPower,
4044 u16 numRates,
4045 bool isHt40Target)
4046{
4047 u16 clo, chi;
4048 int i;
4049 int matchIndex = -1, lowIndex = -1;
4050 u16 freq;
4051 struct chan_centers centers;
4052
4053 ath9k_hw_get_channel_centers(ah, chan, &centers);
4054 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4055
4056 if (freq <=
4057 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4058 matchIndex = 0;
4059 } else {
4060 for (i = 0; (i < numChannels)
4061 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4062 if (freq ==
4063 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4064 IS_CHAN_2GHZ(chan))) {
4065 matchIndex = i;
4066 break;
4067 } else
4068 if ((freq <
4069 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4070 IS_CHAN_2GHZ(chan)))
4071 && (freq >
4072 ath9k_hw_fbin2freq(powInfo[i - 1].
4073 bChannel,
4074 IS_CHAN_2GHZ
4075 (chan)))) {
4076 lowIndex = i - 1;
4077 break;
4078 }
4079 }
4080 if ((matchIndex == -1) && (lowIndex == -1))
4081 matchIndex = i - 1;
4082 }
4083
4084 if (matchIndex != -1) {
4085 *pNewPower = powInfo[matchIndex];
4086 } else {
4087 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4088 IS_CHAN_2GHZ(chan));
4089 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4090 IS_CHAN_2GHZ(chan));
4091
4092 for (i = 0; i < numRates; i++) {
4093 pNewPower->tPow2x[i] =
4094 (u8) ath9k_hw_interpolate(freq, clo, chi,
4095 powInfo
4096 [lowIndex].
4097 tPow2x[i],
4098 powInfo
4099 [lowIndex +
4100 1].tPow2x[i]);
4101 }
4102 }
4103}
4104
4105static inline u16
4106ath9k_hw_get_max_edge_power(u16 freq,
4107 struct cal_ctl_edges *pRdEdgesPower,
4108 bool is2GHz)
4109{
4110 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4111 int i;
4112
4113 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4114 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4115 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4116 is2GHz)) {
4117 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4118 break;
4119 } else if ((i > 0)
4120 && (freq <
4121 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4122 bChannel, is2GHz))) {
4123 if (ath9k_hw_fbin2freq
4124 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4125 && pRdEdgesPower[i - 1].flag) {
4126 twiceMaxEdgePower =
4127 pRdEdgesPower[i - 1].tPower;
4128 }
4129 break;
4130 }
4131 }
4132 return twiceMaxEdgePower;
4133}
4134
4135static inline bool
4136ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4137 struct ar5416_eeprom *pEepData,
4138 struct ath9k_channel *chan,
4139 int16_t *ratesArray,
4140 u16 cfgCtl,
4141 u8 AntennaReduction,
4142 u8 twiceMaxRegulatoryPower,
4143 u8 powerLimit)
4144{
4145 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4146 static const u16 tpScaleReductionTable[5] =
4147 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4148
4149 int i;
4150 int8_t twiceLargestAntenna;
4151 struct cal_ctl_data *rep;
4152 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4153 0, { 0, 0, 0, 0}
4154 };
4155 struct cal_target_power_leg targetPowerOfdmExt = {
4156 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4157 0, { 0, 0, 0, 0 }
4158 };
4159 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4160 0, {0, 0, 0, 0}
4161 };
4162 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4163 u16 ctlModesFor11a[] =
4164 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4165 u16 ctlModesFor11g[] =
4166 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4167 CTL_2GHT40
4168 };
4169 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4170 struct chan_centers centers;
4171 int tx_chainmask;
4172 u8 twiceMinEdgePower;
4173 struct ath_hal_5416 *ahp = AH5416(ah);
4174
4175 tx_chainmask = ahp->ah_txchainmask;
4176
4177 ath9k_hw_get_channel_centers(ah, chan, &centers);
4178
4179 twiceLargestAntenna = max(
4180 pEepData->modalHeader
4181 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4182 pEepData->modalHeader
4183 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4184
4185 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4186 pEepData->modalHeader
4187 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4188
4189 twiceLargestAntenna =
4190 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4191
4192 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4193
4194 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4195 maxRegAllowedPower -=
4196 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4197 }
4198
4199 scaledPower = min(powerLimit, maxRegAllowedPower);
4200
4201 switch (ar5416_get_ntxchains(tx_chainmask)) {
4202 case 1:
4203 break;
4204 case 2:
4205 scaledPower -=
4206 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4207 pwrDecreaseFor2Chain;
4208 break;
4209 case 3:
4210 scaledPower -=
4211 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4212 pwrDecreaseFor3Chain;
4213 break;
4214 }
4215
4216 scaledPower = max(0, (int32_t) scaledPower);
4217
4218 if (IS_CHAN_2GHZ(chan)) {
4219 numCtlModes =
4220 ARRAY_SIZE(ctlModesFor11g) -
4221 SUB_NUM_CTL_MODES_AT_2G_40;
4222 pCtlMode = ctlModesFor11g;
4223
4224 ath9k_hw_get_legacy_target_powers(ah, chan,
4225 pEepData->
4226 calTargetPowerCck,
4227 AR5416_NUM_2G_CCK_TARGET_POWERS,
4228 &targetPowerCck, 4,
4229 false);
4230 ath9k_hw_get_legacy_target_powers(ah, chan,
4231 pEepData->
4232 calTargetPower2G,
4233 AR5416_NUM_2G_20_TARGET_POWERS,
4234 &targetPowerOfdm, 4,
4235 false);
4236 ath9k_hw_get_target_powers(ah, chan,
4237 pEepData->calTargetPower2GHT20,
4238 AR5416_NUM_2G_20_TARGET_POWERS,
4239 &targetPowerHt20, 8, false);
4240
4241 if (IS_CHAN_HT40(chan)) {
4242 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4243 ath9k_hw_get_target_powers(ah, chan,
4244 pEepData->
4245 calTargetPower2GHT40,
4246 AR5416_NUM_2G_40_TARGET_POWERS,
4247 &targetPowerHt40, 8,
4248 true);
4249 ath9k_hw_get_legacy_target_powers(ah, chan,
4250 pEepData->
4251 calTargetPowerCck,
4252 AR5416_NUM_2G_CCK_TARGET_POWERS,
4253 &targetPowerCckExt,
4254 4, true);
4255 ath9k_hw_get_legacy_target_powers(ah, chan,
4256 pEepData->
4257 calTargetPower2G,
4258 AR5416_NUM_2G_20_TARGET_POWERS,
4259 &targetPowerOfdmExt,
4260 4, true);
4261 }
4262 } else {
4263
4264 numCtlModes =
4265 ARRAY_SIZE(ctlModesFor11a) -
4266 SUB_NUM_CTL_MODES_AT_5G_40;
4267 pCtlMode = ctlModesFor11a;
4268
4269 ath9k_hw_get_legacy_target_powers(ah, chan,
4270 pEepData->
4271 calTargetPower5G,
4272 AR5416_NUM_5G_20_TARGET_POWERS,
4273 &targetPowerOfdm, 4,
4274 false);
4275 ath9k_hw_get_target_powers(ah, chan,
4276 pEepData->calTargetPower5GHT20,
4277 AR5416_NUM_5G_20_TARGET_POWERS,
4278 &targetPowerHt20, 8, false);
4279
4280 if (IS_CHAN_HT40(chan)) {
4281 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4282 ath9k_hw_get_target_powers(ah, chan,
4283 pEepData->
4284 calTargetPower5GHT40,
4285 AR5416_NUM_5G_40_TARGET_POWERS,
4286 &targetPowerHt40, 8,
4287 true);
4288 ath9k_hw_get_legacy_target_powers(ah, chan,
4289 pEepData->
4290 calTargetPower5G,
4291 AR5416_NUM_5G_20_TARGET_POWERS,
4292 &targetPowerOfdmExt,
4293 4, true);
4294 }
4295 }
4296
4297 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4298 bool isHt40CtlMode =
4299 (pCtlMode[ctlMode] == CTL_5GHT40)
4300 || (pCtlMode[ctlMode] == CTL_2GHT40);
4301 if (isHt40CtlMode)
4302 freq = centers.synth_center;
4303 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4304 freq = centers.ext_center;
4305 else
4306 freq = centers.ctl_center;
4307
4308 if (ar5416_get_eep_ver(ahp) == 14
4309 && ar5416_get_eep_rev(ahp) <= 2)
4310 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4311
4312 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4313 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4314 "EXT_ADDITIVE %d\n",
4315 ctlMode, numCtlModes, isHt40CtlMode,
4316 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4317
4318 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4319 i++) {
4320 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4321 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4322 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4323 "chan %d\n",
4324 i, cfgCtl, pCtlMode[ctlMode],
4325 pEepData->ctlIndex[i], chan->channel);
4326
4327 if ((((cfgCtl & ~CTL_MODE_M) |
4328 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4329 pEepData->ctlIndex[i])
4330 ||
4331 (((cfgCtl & ~CTL_MODE_M) |
4332 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4333 ((pEepData->
4334 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4335 rep = &(pEepData->ctlData[i]);
4336
4337 twiceMinEdgePower =
4338 ath9k_hw_get_max_edge_power(freq,
4339 rep->
4340 ctlEdges
4341 [ar5416_get_ntxchains
4342 (tx_chainmask)
4343 - 1],
4344 IS_CHAN_2GHZ
4345 (chan));
4346
4347 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4348 " MATCH-EE_IDX %d: ch %d is2 %d "
4349 "2xMinEdge %d chainmask %d chains %d\n",
4350 i, freq, IS_CHAN_2GHZ(chan),
4351 twiceMinEdgePower, tx_chainmask,
4352 ar5416_get_ntxchains
4353 (tx_chainmask));
4354 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4355 twiceMaxEdgePower =
4356 min(twiceMaxEdgePower,
4357 twiceMinEdgePower);
4358 } else {
4359 twiceMaxEdgePower =
4360 twiceMinEdgePower;
4361 break;
4362 }
4363 }
4364 }
4365
4366 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4367
4368 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4369 " SEL-Min ctlMode %d pCtlMode %d "
4370 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4371 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4372 scaledPower, minCtlPower);
4373
4374 switch (pCtlMode[ctlMode]) {
4375 case CTL_11B:
4376 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4377 i++) {
4378 targetPowerCck.tPow2x[i] =
4379 min(targetPowerCck.tPow2x[i],
4380 minCtlPower);
4381 }
4382 break;
4383 case CTL_11A:
4384 case CTL_11G:
4385 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4386 i++) {
4387 targetPowerOfdm.tPow2x[i] =
4388 min(targetPowerOfdm.tPow2x[i],
4389 minCtlPower);
4390 }
4391 break;
4392 case CTL_5GHT20:
4393 case CTL_2GHT20:
4394 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4395 i++) {
4396 targetPowerHt20.tPow2x[i] =
4397 min(targetPowerHt20.tPow2x[i],
4398 minCtlPower);
4399 }
4400 break;
4401 case CTL_11B_EXT:
4402 targetPowerCckExt.tPow2x[0] =
4403 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4404 break;
4405 case CTL_11A_EXT:
4406 case CTL_11G_EXT:
4407 targetPowerOfdmExt.tPow2x[0] =
4408 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4409 break;
4410 case CTL_5GHT40:
4411 case CTL_2GHT40:
4412 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4413 i++) {
4414 targetPowerHt40.tPow2x[i] =
4415 min(targetPowerHt40.tPow2x[i],
4416 minCtlPower);
4417 }
4418 break;
4419 default:
4420 break;
4421 }
4422 }
4423
4424 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4425 ratesArray[rate18mb] = ratesArray[rate24mb] =
4426 targetPowerOfdm.tPow2x[0];
4427 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4428 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4429 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4430 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4431
4432 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4433 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4434
4435 if (IS_CHAN_2GHZ(chan)) {
4436 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4437 ratesArray[rate2s] = ratesArray[rate2l] =
4438 targetPowerCck.tPow2x[1];
4439 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4440 targetPowerCck.tPow2x[2];
4441 ;
4442 ratesArray[rate11s] = ratesArray[rate11l] =
4443 targetPowerCck.tPow2x[3];
4444 ;
4445 }
4446 if (IS_CHAN_HT40(chan)) {
4447 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4448 ratesArray[rateHt40_0 + i] =
4449 targetPowerHt40.tPow2x[i];
4450 }
4451 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4452 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4453 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4454 if (IS_CHAN_2GHZ(chan)) {
4455 ratesArray[rateExtCck] =
4456 targetPowerCckExt.tPow2x[0];
4457 }
4458 }
4459 return true;
4460}
4461
4462static int
4463ath9k_hw_set_txpower(struct ath_hal *ah,
4464 struct ar5416_eeprom *pEepData,
4465 struct ath9k_channel *chan,
4466 u16 cfgCtl,
4467 u8 twiceAntennaReduction,
4468 u8 twiceMaxRegulatoryPower,
4469 u8 powerLimit)
4470{
4471 struct modal_eep_header *pModal =
4472 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4473 int16_t ratesArray[Ar5416RateSize];
4474 int16_t txPowerIndexOffset = 0;
4475 u8 ht40PowerIncForPdadc = 2;
4476 int i;
4477
4478 memset(ratesArray, 0, sizeof(ratesArray));
4479
4480 if ((pEepData->baseEepHeader.
4481 version & AR5416_EEP_VER_MINOR_MASK) >=
4482 AR5416_EEP_MINOR_VER_2) {
4483 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4484 }
4485
4486 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4487 &ratesArray[0], cfgCtl,
4488 twiceAntennaReduction,
4489 twiceMaxRegulatoryPower,
4490 powerLimit)) {
4491 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4492 "ath9k_hw_set_txpower: unable to set "
4493 "tx power per rate table\n");
4494 return -EIO;
4495 }
4496
4497 if (!ath9k_hw_set_power_cal_table
4498 (ah, pEepData, chan, &txPowerIndexOffset)) {
4499 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4500 "ath9k_hw_set_txpower: unable to set power table\n");
4501 return -EIO;
4502 }
4503
4504 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4505 ratesArray[i] =
4506 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4507 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4508 ratesArray[i] = AR5416_MAX_RATE_POWER;
4509 }
4510
4511 if (AR_SREV_9280_10_OR_LATER(ah)) {
4512 for (i = 0; i < Ar5416RateSize; i++)
4513 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4514 }
4515
4516 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4517 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4518 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4519 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4520 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4521 );
4522 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4523 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4524 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4525 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4526 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4527 );
4528
4529 if (IS_CHAN_2GHZ(chan)) {
4530 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4531 ATH9K_POW_SM(ratesArray[rate2s], 24)
4532 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4533 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4534 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4535 );
4536 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4537 ATH9K_POW_SM(ratesArray[rate11s], 24)
4538 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4539 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4540 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4541 );
4542 }
4543
4544 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4545 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4546 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4547 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4548 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4549 );
4550 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4551 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4552 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4553 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4554 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4555 );
4556
4557 if (IS_CHAN_HT40(chan)) {
4558 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4559 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4560 ht40PowerIncForPdadc, 24)
4561 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4562 ht40PowerIncForPdadc, 16)
4563 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4564 ht40PowerIncForPdadc, 8)
4565 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4566 ht40PowerIncForPdadc, 0)
4567 );
4568 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4569 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4570 ht40PowerIncForPdadc, 24)
4571 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4572 ht40PowerIncForPdadc, 16)
4573 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4574 ht40PowerIncForPdadc, 8)
4575 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4576 ht40PowerIncForPdadc, 0)
4577 );
4578
4579 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4580 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4581 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4582 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4583 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4584 );
4585 }
4586
4587 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4588 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4589 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4590 );
4591
4592 i = rate6mb;
4593 if (IS_CHAN_HT40(chan))
4594 i = rateHt40_0;
4595 else if (IS_CHAN_HT20(chan))
4596 i = rateHt20_0;
4597
4598 if (AR_SREV_9280_10_OR_LATER(ah))
4599 ah->ah_maxPowerLevel =
4600 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4601 else
4602 ah->ah_maxPowerLevel = ratesArray[i];
4603
4604 return 0;
4605}
4606
4607static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4608 u32 coef_scaled,
4609 u32 *coef_mantissa,
4610 u32 *coef_exponent)
4611{
4612 u32 coef_exp, coef_man;
4613
4614 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4615 if ((coef_scaled >> coef_exp) & 0x1)
4616 break;
4617
4618 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4619
4620 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4621
4622 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4623 *coef_exponent = coef_exp - 16;
4624}
4625
4626static void
4627ath9k_hw_set_delta_slope(struct ath_hal *ah,
4628 struct ath9k_channel *chan)
4629{
4630 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4631 u32 clockMhzScaled = 0x64000000;
4632 struct chan_centers centers;
4633
4634 if (IS_CHAN_HALF_RATE(chan))
4635 clockMhzScaled = clockMhzScaled >> 1;
4636 else if (IS_CHAN_QUARTER_RATE(chan))
4637 clockMhzScaled = clockMhzScaled >> 2;
4638
4639 ath9k_hw_get_channel_centers(ah, chan, &centers);
4640 coef_scaled = clockMhzScaled / centers.synth_center;
4641
4642 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4643 &ds_coef_exp);
4644
4645 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4646 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4647 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4648 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4649
4650 coef_scaled = (9 * coef_scaled) / 10;
4651
4652 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4653 &ds_coef_exp);
4654
4655 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4656 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4657 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4658 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4659}
4660
4661static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4662 struct ath9k_channel *chan)
4663{
4664 int bb_spur = AR_NO_SPUR;
4665 int freq;
4666 int bin, cur_bin;
4667 int bb_spur_off, spur_subchannel_sd;
4668 int spur_freq_sd;
4669 int spur_delta_phase;
4670 int denominator;
4671 int upper, lower, cur_vit_mask;
4672 int tmp, newVal;
4673 int i;
4674 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4675 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4676 };
4677 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4678 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4679 };
4680 int inc[4] = { 0, 100, 0, 0 };
4681 struct chan_centers centers;
4682
4683 int8_t mask_m[123];
4684 int8_t mask_p[123];
4685 int8_t mask_amt;
4686 int tmp_mask;
4687 int cur_bb_spur;
4688 bool is2GHz = IS_CHAN_2GHZ(chan);
4689
4690 memset(&mask_m, 0, sizeof(int8_t) * 123);
4691 memset(&mask_p, 0, sizeof(int8_t) * 123);
4692
4693 ath9k_hw_get_channel_centers(ah, chan, &centers);
4694 freq = centers.synth_center;
4695
60b67f51 4696 ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
f078f209
LR
4697 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4698 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4699
4700 if (is2GHz)
4701 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4702 else
4703 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4704
4705 if (AR_NO_SPUR == cur_bb_spur)
4706 break;
4707 cur_bb_spur = cur_bb_spur - freq;
4708
4709 if (IS_CHAN_HT40(chan)) {
4710 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4711 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4712 bb_spur = cur_bb_spur;
4713 break;
4714 }
4715 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4716 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4717 bb_spur = cur_bb_spur;
4718 break;
4719 }
4720 }
4721
4722 if (AR_NO_SPUR == bb_spur) {
4723 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4724 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4725 return;
4726 } else {
4727 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4728 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4729 }
4730
4731 bin = bb_spur * 320;
4732
4733 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4734
4735 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4736 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4737 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4738 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4739 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4740
4741 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4742 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4743 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4744 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4745 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4746 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4747
4748 if (IS_CHAN_HT40(chan)) {
4749 if (bb_spur < 0) {
4750 spur_subchannel_sd = 1;
4751 bb_spur_off = bb_spur + 10;
4752 } else {
4753 spur_subchannel_sd = 0;
4754 bb_spur_off = bb_spur - 10;
4755 }
4756 } else {
4757 spur_subchannel_sd = 0;
4758 bb_spur_off = bb_spur;
4759 }
4760
4761 if (IS_CHAN_HT40(chan))
4762 spur_delta_phase =
4763 ((bb_spur * 262144) /
4764 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4765 else
4766 spur_delta_phase =
4767 ((bb_spur * 524288) /
4768 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4769
4770 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4771 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4772
4773 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4774 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4775 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4776 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4777
4778 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4779 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4780
4781 cur_bin = -6000;
4782 upper = bin + 100;
4783 lower = bin - 100;
4784
4785 for (i = 0; i < 4; i++) {
4786 int pilot_mask = 0;
4787 int chan_mask = 0;
4788 int bp = 0;
4789 for (bp = 0; bp < 30; bp++) {
4790 if ((cur_bin > lower) && (cur_bin < upper)) {
4791 pilot_mask = pilot_mask | 0x1 << bp;
4792 chan_mask = chan_mask | 0x1 << bp;
4793 }
4794 cur_bin += 100;
4795 }
4796 cur_bin += inc[i];
4797 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4798 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4799 }
4800
4801 cur_vit_mask = 6100;
4802 upper = bin + 120;
4803 lower = bin - 120;
4804
4805 for (i = 0; i < 123; i++) {
4806 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
b08cbcd4
AB
4807
4808 /* workaround for gcc bug #37014 */
4809 volatile int tmp = abs(cur_vit_mask - bin);
4810
4811 if (tmp < 75)
f078f209
LR
4812 mask_amt = 1;
4813 else
4814 mask_amt = 0;
4815 if (cur_vit_mask < 0)
4816 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4817 else
4818 mask_p[cur_vit_mask / 100] = mask_amt;
4819 }
4820 cur_vit_mask -= 100;
4821 }
4822
4823 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4824 | (mask_m[48] << 26) | (mask_m[49] << 24)
4825 | (mask_m[50] << 22) | (mask_m[51] << 20)
4826 | (mask_m[52] << 18) | (mask_m[53] << 16)
4827 | (mask_m[54] << 14) | (mask_m[55] << 12)
4828 | (mask_m[56] << 10) | (mask_m[57] << 8)
4829 | (mask_m[58] << 6) | (mask_m[59] << 4)
4830 | (mask_m[60] << 2) | (mask_m[61] << 0);
4831 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4832 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4833
4834 tmp_mask = (mask_m[31] << 28)
4835 | (mask_m[32] << 26) | (mask_m[33] << 24)
4836 | (mask_m[34] << 22) | (mask_m[35] << 20)
4837 | (mask_m[36] << 18) | (mask_m[37] << 16)
4838 | (mask_m[48] << 14) | (mask_m[39] << 12)
4839 | (mask_m[40] << 10) | (mask_m[41] << 8)
4840 | (mask_m[42] << 6) | (mask_m[43] << 4)
4841 | (mask_m[44] << 2) | (mask_m[45] << 0);
4842 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4843 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4844
4845 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4846 | (mask_m[18] << 26) | (mask_m[18] << 24)
4847 | (mask_m[20] << 22) | (mask_m[20] << 20)
4848 | (mask_m[22] << 18) | (mask_m[22] << 16)
4849 | (mask_m[24] << 14) | (mask_m[24] << 12)
4850 | (mask_m[25] << 10) | (mask_m[26] << 8)
4851 | (mask_m[27] << 6) | (mask_m[28] << 4)
4852 | (mask_m[29] << 2) | (mask_m[30] << 0);
4853 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4854 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4855
4856 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4857 | (mask_m[2] << 26) | (mask_m[3] << 24)
4858 | (mask_m[4] << 22) | (mask_m[5] << 20)
4859 | (mask_m[6] << 18) | (mask_m[7] << 16)
4860 | (mask_m[8] << 14) | (mask_m[9] << 12)
4861 | (mask_m[10] << 10) | (mask_m[11] << 8)
4862 | (mask_m[12] << 6) | (mask_m[13] << 4)
4863 | (mask_m[14] << 2) | (mask_m[15] << 0);
4864 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4865 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4866
4867 tmp_mask = (mask_p[15] << 28)
4868 | (mask_p[14] << 26) | (mask_p[13] << 24)
4869 | (mask_p[12] << 22) | (mask_p[11] << 20)
4870 | (mask_p[10] << 18) | (mask_p[9] << 16)
4871 | (mask_p[8] << 14) | (mask_p[7] << 12)
4872 | (mask_p[6] << 10) | (mask_p[5] << 8)
4873 | (mask_p[4] << 6) | (mask_p[3] << 4)
4874 | (mask_p[2] << 2) | (mask_p[1] << 0);
4875 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4876 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4877
4878 tmp_mask = (mask_p[30] << 28)
4879 | (mask_p[29] << 26) | (mask_p[28] << 24)
4880 | (mask_p[27] << 22) | (mask_p[26] << 20)
4881 | (mask_p[25] << 18) | (mask_p[24] << 16)
4882 | (mask_p[23] << 14) | (mask_p[22] << 12)
4883 | (mask_p[21] << 10) | (mask_p[20] << 8)
4884 | (mask_p[19] << 6) | (mask_p[18] << 4)
4885 | (mask_p[17] << 2) | (mask_p[16] << 0);
4886 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4887 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4888
4889 tmp_mask = (mask_p[45] << 28)
4890 | (mask_p[44] << 26) | (mask_p[43] << 24)
4891 | (mask_p[42] << 22) | (mask_p[41] << 20)
4892 | (mask_p[40] << 18) | (mask_p[39] << 16)
4893 | (mask_p[38] << 14) | (mask_p[37] << 12)
4894 | (mask_p[36] << 10) | (mask_p[35] << 8)
4895 | (mask_p[34] << 6) | (mask_p[33] << 4)
4896 | (mask_p[32] << 2) | (mask_p[31] << 0);
4897 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4898 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4899
4900 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4901 | (mask_p[59] << 26) | (mask_p[58] << 24)
4902 | (mask_p[57] << 22) | (mask_p[56] << 20)
4903 | (mask_p[55] << 18) | (mask_p[54] << 16)
4904 | (mask_p[53] << 14) | (mask_p[52] << 12)
4905 | (mask_p[51] << 10) | (mask_p[50] << 8)
4906 | (mask_p[49] << 6) | (mask_p[48] << 4)
4907 | (mask_p[47] << 2) | (mask_p[46] << 0);
4908 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4909 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4910}
4911
4912static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4913 struct ath9k_channel *chan)
4914{
4915 int bb_spur = AR_NO_SPUR;
4916 int bin, cur_bin;
4917 int spur_freq_sd;
4918 int spur_delta_phase;
4919 int denominator;
4920 int upper, lower, cur_vit_mask;
4921 int tmp, new;
4922 int i;
4923 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4924 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4925 };
4926 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4927 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4928 };
4929 int inc[4] = { 0, 100, 0, 0 };
4930
4931 int8_t mask_m[123];
4932 int8_t mask_p[123];
4933 int8_t mask_amt;
4934 int tmp_mask;
4935 int cur_bb_spur;
4936 bool is2GHz = IS_CHAN_2GHZ(chan);
4937
4938 memset(&mask_m, 0, sizeof(int8_t) * 123);
4939 memset(&mask_p, 0, sizeof(int8_t) * 123);
4940
4941 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4942 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4943 if (AR_NO_SPUR == cur_bb_spur)
4944 break;
4945 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4946 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4947 bb_spur = cur_bb_spur;
4948 break;
4949 }
4950 }
4951
4952 if (AR_NO_SPUR == bb_spur)
4953 return;
4954
4955 bin = bb_spur * 32;
4956
4957 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4958 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4959 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4960 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4961 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4962
4963 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4964
4965 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4966 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4967 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4968 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4969 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4970 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4971
4972 spur_delta_phase = ((bb_spur * 524288) / 100) &
4973 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4974
4975 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4976 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4977
4978 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4979 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4980 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4981 REG_WRITE(ah, AR_PHY_TIMING11, new);
4982
4983 cur_bin = -6000;
4984 upper = bin + 100;
4985 lower = bin - 100;
4986
4987 for (i = 0; i < 4; i++) {
4988 int pilot_mask = 0;
4989 int chan_mask = 0;
4990 int bp = 0;
4991 for (bp = 0; bp < 30; bp++) {
4992 if ((cur_bin > lower) && (cur_bin < upper)) {
4993 pilot_mask = pilot_mask | 0x1 << bp;
4994 chan_mask = chan_mask | 0x1 << bp;
4995 }
4996 cur_bin += 100;
4997 }
4998 cur_bin += inc[i];
4999 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
5000 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5001 }
5002
5003 cur_vit_mask = 6100;
5004 upper = bin + 120;
5005 lower = bin - 120;
5006
5007 for (i = 0; i < 123; i++) {
5008 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5009 if ((abs(cur_vit_mask - bin)) < 75)
5010 mask_amt = 1;
5011 else
5012 mask_amt = 0;
5013 if (cur_vit_mask < 0)
5014 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5015 else
5016 mask_p[cur_vit_mask / 100] = mask_amt;
5017 }
5018 cur_vit_mask -= 100;
5019 }
5020
5021 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5022 | (mask_m[48] << 26) | (mask_m[49] << 24)
5023 | (mask_m[50] << 22) | (mask_m[51] << 20)
5024 | (mask_m[52] << 18) | (mask_m[53] << 16)
5025 | (mask_m[54] << 14) | (mask_m[55] << 12)
5026 | (mask_m[56] << 10) | (mask_m[57] << 8)
5027 | (mask_m[58] << 6) | (mask_m[59] << 4)
5028 | (mask_m[60] << 2) | (mask_m[61] << 0);
5029 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5030 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5031
5032 tmp_mask = (mask_m[31] << 28)
5033 | (mask_m[32] << 26) | (mask_m[33] << 24)
5034 | (mask_m[34] << 22) | (mask_m[35] << 20)
5035 | (mask_m[36] << 18) | (mask_m[37] << 16)
5036 | (mask_m[48] << 14) | (mask_m[39] << 12)
5037 | (mask_m[40] << 10) | (mask_m[41] << 8)
5038 | (mask_m[42] << 6) | (mask_m[43] << 4)
5039 | (mask_m[44] << 2) | (mask_m[45] << 0);
5040 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5041 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5042
5043 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5044 | (mask_m[18] << 26) | (mask_m[18] << 24)
5045 | (mask_m[20] << 22) | (mask_m[20] << 20)
5046 | (mask_m[22] << 18) | (mask_m[22] << 16)
5047 | (mask_m[24] << 14) | (mask_m[24] << 12)
5048 | (mask_m[25] << 10) | (mask_m[26] << 8)
5049 | (mask_m[27] << 6) | (mask_m[28] << 4)
5050 | (mask_m[29] << 2) | (mask_m[30] << 0);
5051 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5052 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5053
5054 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5055 | (mask_m[2] << 26) | (mask_m[3] << 24)
5056 | (mask_m[4] << 22) | (mask_m[5] << 20)
5057 | (mask_m[6] << 18) | (mask_m[7] << 16)
5058 | (mask_m[8] << 14) | (mask_m[9] << 12)
5059 | (mask_m[10] << 10) | (mask_m[11] << 8)
5060 | (mask_m[12] << 6) | (mask_m[13] << 4)
5061 | (mask_m[14] << 2) | (mask_m[15] << 0);
5062 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5063 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5064
5065 tmp_mask = (mask_p[15] << 28)
5066 | (mask_p[14] << 26) | (mask_p[13] << 24)
5067 | (mask_p[12] << 22) | (mask_p[11] << 20)
5068 | (mask_p[10] << 18) | (mask_p[9] << 16)
5069 | (mask_p[8] << 14) | (mask_p[7] << 12)
5070 | (mask_p[6] << 10) | (mask_p[5] << 8)
5071 | (mask_p[4] << 6) | (mask_p[3] << 4)
5072 | (mask_p[2] << 2) | (mask_p[1] << 0);
5073 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5074 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5075
5076 tmp_mask = (mask_p[30] << 28)
5077 | (mask_p[29] << 26) | (mask_p[28] << 24)
5078 | (mask_p[27] << 22) | (mask_p[26] << 20)
5079 | (mask_p[25] << 18) | (mask_p[24] << 16)
5080 | (mask_p[23] << 14) | (mask_p[22] << 12)
5081 | (mask_p[21] << 10) | (mask_p[20] << 8)
5082 | (mask_p[19] << 6) | (mask_p[18] << 4)
5083 | (mask_p[17] << 2) | (mask_p[16] << 0);
5084 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5085 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5086
5087 tmp_mask = (mask_p[45] << 28)
5088 | (mask_p[44] << 26) | (mask_p[43] << 24)
5089 | (mask_p[42] << 22) | (mask_p[41] << 20)
5090 | (mask_p[40] << 18) | (mask_p[39] << 16)
5091 | (mask_p[38] << 14) | (mask_p[37] << 12)
5092 | (mask_p[36] << 10) | (mask_p[35] << 8)
5093 | (mask_p[34] << 6) | (mask_p[33] << 4)
5094 | (mask_p[32] << 2) | (mask_p[31] << 0);
5095 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5096 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5097
5098 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5099 | (mask_p[59] << 26) | (mask_p[58] << 24)
5100 | (mask_p[57] << 22) | (mask_p[56] << 20)
5101 | (mask_p[55] << 18) | (mask_p[54] << 16)
5102 | (mask_p[53] << 14) | (mask_p[52] << 12)
5103 | (mask_p[51] << 10) | (mask_p[50] << 8)
5104 | (mask_p[49] << 6) | (mask_p[48] << 4)
5105 | (mask_p[47] << 2) | (mask_p[46] << 0);
5106 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5107 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5108}
5109
5110static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5111{
5112 struct ath_hal_5416 *ahp = AH5416(ah);
5113 int rx_chainmask, tx_chainmask;
5114
5115 rx_chainmask = ahp->ah_rxchainmask;
5116 tx_chainmask = ahp->ah_txchainmask;
5117
5118 switch (rx_chainmask) {
5119 case 0x5:
5120 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5121 AR_PHY_SWAP_ALT_CHAIN);
5122 case 0x3:
5123 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5124 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5125 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5126 break;
5127 }
5128 case 0x1:
5129 case 0x2:
5130 if (!AR_SREV_9280(ah))
5131 break;
5132 case 0x7:
5133 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5134 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5135 break;
5136 default:
5137 break;
5138 }
5139
5140 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5141 if (tx_chainmask == 0x5) {
5142 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5143 AR_PHY_SWAP_ALT_CHAIN);
5144 }
5145 if (AR_SREV_9100(ah))
5146 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5147 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5148}
5149
5150static void ath9k_hw_set_addac(struct ath_hal *ah,
5151 struct ath9k_channel *chan)
5152{
5153 struct modal_eep_header *pModal;
5154 struct ath_hal_5416 *ahp = AH5416(ah);
5155 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5156 u8 biaslevel;
5157
5158 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5159 return;
5160
5161 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5162 return;
5163
5164 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5165
5166 if (pModal->xpaBiasLvl != 0xff) {
5167 biaslevel = pModal->xpaBiasLvl;
5168 } else {
5169
5170 u16 resetFreqBin, freqBin, freqCount = 0;
5171 struct chan_centers centers;
5172
5173 ath9k_hw_get_channel_centers(ah, chan, &centers);
5174
5175 resetFreqBin =
5176 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5177 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5178 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5179
5180 freqCount++;
5181
5182 while (freqCount < 3) {
5183 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5184 break;
5185
5186 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5187 if (resetFreqBin >= freqBin) {
5188 biaslevel =
5189 (u8) (pModal->
5190 xpaBiasLvlFreq[freqCount]
5191 >> 14);
5192 } else {
5193 break;
5194 }
5195 freqCount++;
5196 }
5197 }
5198
5199 if (IS_CHAN_2GHZ(chan)) {
5200 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5201 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5202 << 3;
5203 } else {
5204 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5205 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5206 << 6;
5207 }
5208}
5209
5210static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5211{
5212 if (ah->ah_curchan != NULL)
5213 return clks /
5214 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5215 else
5216 return clks / CLOCK_RATE[WIRELESS_MODE_11b];
5217}
5218
5219static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5220{
5221 struct ath9k_channel *chan = ah->ah_curchan;
5222
5223 if (chan && IS_CHAN_HT40(chan))
5224 return ath9k_hw_mac_usec(ah, clks) / 2;
5225 else
5226 return ath9k_hw_mac_usec(ah, clks);
5227}
5228
5229static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5230{
5231 if (ah->ah_curchan != NULL)
5232 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5233 ah->ah_curchan)];
5234 else
5235 return usecs * CLOCK_RATE[WIRELESS_MODE_11b];
5236}
5237
5238static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5239{
5240 struct ath9k_channel *chan = ah->ah_curchan;
5241
5242 if (chan && IS_CHAN_HT40(chan))
5243 return ath9k_hw_mac_clks(ah, usecs) * 2;
5244 else
5245 return ath9k_hw_mac_clks(ah, usecs);
5246}
5247
5248static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5249{
5250 struct ath_hal_5416 *ahp = AH5416(ah);
5251
5252 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5253 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5254 __func__, us);
5255 ahp->ah_acktimeout = (u32) -1;
5256 return false;
5257 } else {
5258 REG_RMW_FIELD(ah, AR_TIME_OUT,
5259 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5260 ahp->ah_acktimeout = us;
5261 return true;
5262 }
5263}
5264
5265static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5266{
5267 struct ath_hal_5416 *ahp = AH5416(ah);
5268
5269 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5270 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5271 __func__, us);
5272 ahp->ah_ctstimeout = (u32) -1;
5273 return false;
5274 } else {
5275 REG_RMW_FIELD(ah, AR_TIME_OUT,
5276 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5277 ahp->ah_ctstimeout = us;
5278 return true;
5279 }
5280}
5281static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5282 u32 tu)
5283{
5284 struct ath_hal_5416 *ahp = AH5416(ah);
5285
5286 if (tu > 0xFFFF) {
5287 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5288 "%s: bad global tx timeout %u\n", __func__, tu);
5289 ahp->ah_globaltxtimeout = (u32) -1;
5290 return false;
5291 } else {
5292 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5293 ahp->ah_globaltxtimeout = tu;
5294 return true;
5295 }
5296}
5297
5298bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5299{
5300 struct ath_hal_5416 *ahp = AH5416(ah);
5301
5302 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5303 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5304 __func__, us);
5305 ahp->ah_slottime = (u32) -1;
5306 return false;
5307 } else {
5308 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5309 ahp->ah_slottime = us;
5310 return true;
5311 }
5312}
5313
5314static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5315{
5316 struct ath_hal_5416 *ahp = AH5416(ah);
5317
5318 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5319 __func__, ahp->ah_miscMode);
5320 if (ahp->ah_miscMode != 0)
5321 REG_WRITE(ah, AR_PCU_MISC,
5322 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5323 if (ahp->ah_slottime != (u32) -1)
5324 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5325 if (ahp->ah_acktimeout != (u32) -1)
5326 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5327 if (ahp->ah_ctstimeout != (u32) -1)
5328 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5329 if (ahp->ah_globaltxtimeout != (u32) -1)
5330 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5331}
5332
5333static inline int
5334ath9k_hw_process_ini(struct ath_hal *ah,
5335 struct ath9k_channel *chan,
5336 enum ath9k_ht_macmode macmode)
5337{
5338 int i, regWrites = 0;
5339 struct ath_hal_5416 *ahp = AH5416(ah);
5340 u32 modesIndex, freqIndex;
5341 int status;
5342
5343 switch (chan->chanmode) {
5344 case CHANNEL_A:
5345 case CHANNEL_A_HT20:
5346 modesIndex = 1;
5347 freqIndex = 1;
5348 break;
5349 case CHANNEL_A_HT40PLUS:
5350 case CHANNEL_A_HT40MINUS:
5351 modesIndex = 2;
5352 freqIndex = 1;
5353 break;
5354 case CHANNEL_G:
5355 case CHANNEL_G_HT20:
5356 case CHANNEL_B:
5357 modesIndex = 4;
5358 freqIndex = 2;
5359 break;
5360 case CHANNEL_G_HT40PLUS:
5361 case CHANNEL_G_HT40MINUS:
5362 modesIndex = 3;
5363 freqIndex = 2;
5364 break;
5365
5366 default:
5367 return -EINVAL;
5368 }
5369
5370 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5371
5372 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5373
5374 ath9k_hw_set_addac(ah, chan);
5375
5376 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5377 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5378 } else {
5379 struct ar5416IniArray temp;
5380 u32 addacSize =
5381 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5382 ahp->ah_iniAddac.ia_columns;
5383
5384 memcpy(ahp->ah_addac5416_21,
5385 ahp->ah_iniAddac.ia_array, addacSize);
5386
5387 (ahp->ah_addac5416_21)[31 *
5388 ahp->ah_iniAddac.ia_columns + 1] = 0;
5389
5390 temp.ia_array = ahp->ah_addac5416_21;
5391 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5392 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5393 REG_WRITE_ARRAY(&temp, 1, regWrites);
5394 }
5395 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5396
5397 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5398 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5399 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5400
5401#ifdef CONFIG_SLOW_ANT_DIV
5402 if (ah->ah_devid == AR9280_DEVID_PCI)
5403 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5404 val);
5405#endif
5406
5407 REG_WRITE(ah, reg, val);
5408
5409 if (reg >= 0x7800 && reg < 0x78a0
60b67f51 5410 && ah->ah_config.analog_shiftreg) {
f078f209
LR
5411 udelay(100);
5412 }
5413
5414 DO_DELAY(regWrites);
5415 }
5416
5417 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5418 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5419 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5420
5421 REG_WRITE(ah, reg, val);
5422
5423 if (reg >= 0x7800 && reg < 0x78a0
60b67f51 5424 && ah->ah_config.analog_shiftreg) {
f078f209
LR
5425 udelay(100);
5426 }
5427
5428 DO_DELAY(regWrites);
5429 }
5430
5431 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5432
5433 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5434 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5435 regWrites);
5436 }
5437
5438 ath9k_hw_override_ini(ah, chan);
5439 ath9k_hw_set_regs(ah, chan, macmode);
5440 ath9k_hw_init_chain_masks(ah);
5441
5442 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5443 ath9k_regd_get_ctl(ah, chan),
5444 ath9k_regd_get_antenna_allowed(ah,
5445 chan),
5446 chan->maxRegTxPower * 2,
5447 min((u32) MAX_RATE_POWER,
5448 (u32) ah->ah_powerLimit));
5449 if (status != 0) {
5450 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5451 "%s: error init'ing transmit power\n", __func__);
5452 return -EIO;
5453 }
5454
5455 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5456 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5457 "%s: ar5416SetRfRegs failed\n", __func__);
5458 return -EIO;
5459 }
5460
5461 return 0;
5462}
5463
5464static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5465 struct hal_cal_list *currCal)
5466{
5467 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5468 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5469 currCal->calData->calCountMax);
5470
5471 switch (currCal->calData->calType) {
5472 case IQ_MISMATCH_CAL:
5473 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5474 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5475 "%s: starting IQ Mismatch Calibration\n",
5476 __func__);
5477 break;
5478 case ADC_GAIN_CAL:
5479 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5480 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5481 "%s: starting ADC Gain Calibration\n", __func__);
5482 break;
5483 case ADC_DC_CAL:
5484 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5485 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5486 "%s: starting ADC DC Calibration\n", __func__);
5487 break;
5488 case ADC_DC_INIT_CAL:
5489 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5490 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5491 "%s: starting Init ADC DC Calibration\n",
5492 __func__);
5493 break;
5494 }
5495
5496 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5497 AR_PHY_TIMING_CTRL4_DO_CAL);
5498}
5499
5500static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5501 struct hal_cal_list *currCal)
5502{
5503 struct ath_hal_5416 *ahp = AH5416(ah);
5504 int i;
5505
5506 ath9k_hw_setup_calibration(ah, currCal);
5507
5508 currCal->calState = CAL_RUNNING;
5509
5510 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5511 ahp->ah_Meas0.sign[i] = 0;
5512 ahp->ah_Meas1.sign[i] = 0;
5513 ahp->ah_Meas2.sign[i] = 0;
5514 ahp->ah_Meas3.sign[i] = 0;
5515 }
5516
5517 ahp->ah_CalSamples = 0;
5518}
5519
5520static inline void
5521ath9k_hw_per_calibration(struct ath_hal *ah,
5522 struct ath9k_channel *ichan,
5523 u8 rxchainmask,
5524 struct hal_cal_list *currCal,
5525 bool *isCalDone)
5526{
5527 struct ath_hal_5416 *ahp = AH5416(ah);
5528
5529 *isCalDone = false;
5530
5531 if (currCal->calState == CAL_RUNNING) {
5532 if (!(REG_READ(ah,
5533 AR_PHY_TIMING_CTRL4(0)) &
5534 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5535
5536 currCal->calData->calCollect(ah);
5537
5538 ahp->ah_CalSamples++;
5539
5540 if (ahp->ah_CalSamples >=
5541 currCal->calData->calNumSamples) {
5542 int i, numChains = 0;
5543 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5544 if (rxchainmask & (1 << i))
5545 numChains++;
5546 }
5547
5548 currCal->calData->calPostProc(ah,
5549 numChains);
5550
5551 ichan->CalValid |=
5552 currCal->calData->calType;
5553 currCal->calState = CAL_DONE;
5554 *isCalDone = true;
5555 } else {
5556 ath9k_hw_setup_calibration(ah, currCal);
5557 }
5558 }
5559 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5560 ath9k_hw_reset_calibration(ah, currCal);
5561 }
5562}
5563
5564static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5565 int init_cal_count)
5566{
5567 struct ath_hal_5416 *ahp = AH5416(ah);
5568 struct ath9k_channel ichan;
5569 bool isCalDone;
5570 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5571 const struct hal_percal_data *calData = currCal->calData;
5572 int i;
5573
5574 if (currCal == NULL)
5575 return false;
5576
5577 ichan.CalValid = 0;
5578
5579 for (i = 0; i < init_cal_count; i++) {
5580 ath9k_hw_reset_calibration(ah, currCal);
5581
5582 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5583 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5584 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5585 "%s: Cal %d failed to complete in 100ms.\n",
5586 __func__, calData->calType);
5587
5588 ahp->ah_cal_list = ahp->ah_cal_list_last =
5589 ahp->ah_cal_list_curr = NULL;
5590 return false;
5591 }
5592
5593 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5594 currCal, &isCalDone);
5595 if (!isCalDone) {
5596 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5597 "%s: Not able to run Init Cal %d.\n",
5598 __func__, calData->calType);
5599 }
5600 if (currCal->calNext) {
5601 currCal = currCal->calNext;
5602 calData = currCal->calData;
5603 }
5604 }
5605
5606 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5607 return true;
5608}
5609
5610static inline bool
5611ath9k_hw_channel_change(struct ath_hal *ah,
5612 struct ath9k_channel *chan,
5613 enum ath9k_ht_macmode macmode)
5614{
5615 u32 synthDelay, qnum;
5616 struct ath_hal_5416 *ahp = AH5416(ah);
5617
5618 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5619 if (ath9k_hw_numtxpending(ah, qnum)) {
5620 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5621 "%s: Transmit frames pending on queue %d\n",
5622 __func__, qnum);
5623 return false;
5624 }
5625 }
5626
5627 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5628 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5629 AR_PHY_RFBUS_GRANT_EN)) {
5630 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5631 "%s: Could not kill baseband RX\n", __func__);
5632 return false;
5633 }
5634
5635 ath9k_hw_set_regs(ah, chan, macmode);
5636
5637 if (AR_SREV_9280_10_OR_LATER(ah)) {
5638 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5639 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5640 "%s: failed to set channel\n", __func__);
5641 return false;
5642 }
5643 } else {
5644 if (!(ath9k_hw_set_channel(ah, chan))) {
5645 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5646 "%s: failed to set channel\n", __func__);
5647 return false;
5648 }
5649 }
5650
5651 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5652 ath9k_regd_get_ctl(ah, chan),
5653 ath9k_regd_get_antenna_allowed(ah, chan),
5654 chan->maxRegTxPower * 2,
5655 min((u32) MAX_RATE_POWER,
5656 (u32) ah->ah_powerLimit)) != 0) {
5657 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5658 "%s: error init'ing transmit power\n", __func__);
5659 return false;
5660 }
5661
5662 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5663 if (IS_CHAN_CCK(chan))
5664 synthDelay = (4 * synthDelay) / 22;
5665 else
5666 synthDelay /= 10;
5667
5668 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5669
5670 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5671
5672 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5673 ath9k_hw_set_delta_slope(ah, chan);
5674
5675 if (AR_SREV_9280_10_OR_LATER(ah))
5676 ath9k_hw_9280_spur_mitigate(ah, chan);
5677 else
5678 ath9k_hw_spur_mitigate(ah, chan);
5679
5680 if (!chan->oneTimeCalsDone)
5681 chan->oneTimeCalsDone = true;
5682
5683 return true;
5684}
5685
5686static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5687 struct ath9k_channel *chan)
5688{
5689 struct ath_hal_5416 *ahp = AH5416(ah);
5690
5691 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5692 return false;
5693
5694 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5695 return false;
5696
5697 ahp->ah_chipFullSleep = false;
5698
5699 ath9k_hw_init_pll(ah, chan);
5700
5701 ath9k_hw_set_rfmode(ah, chan);
5702
5703 return true;
5704}
5705
5706static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5707{
5708 u32 regval;
5709
5710 regval = REG_READ(ah, AR_AHB_MODE);
5711 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5712
5713 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5714 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5715
5716 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5717
5718 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5719 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5720
5721 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5722
5723 if (AR_SREV_9285(ah)) {
5724 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5725 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5726 } else {
5727 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5728 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5729 }
5730}
5731
5732bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5733{
5734 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5735 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5736 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5737 "%s: dma failed to stop in 10ms\n"
5738 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5739 __func__,
5740 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5741 return false;
5742 } else {
5743 return true;
5744 }
5745}
5746
5747void ath9k_hw_startpcureceive(struct ath_hal *ah)
5748{
5749 REG_CLR_BIT(ah, AR_DIAG_SW,
5750 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5751
5752 ath9k_enable_mib_counters(ah);
5753
5754 ath9k_ani_reset(ah);
5755}
5756
5757void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5758{
5759 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5760
5761 ath9k_hw_disable_mib_counters(ah);
5762}
5763
5764static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5765 struct ath9k_channel *chan,
5766 enum hal_cal_types calType)
5767{
5768 struct ath_hal_5416 *ahp = AH5416(ah);
5769 bool retval = false;
5770
5771 switch (calType & ahp->ah_suppCals) {
5772 case IQ_MISMATCH_CAL:
5773 if (!IS_CHAN_B(chan))
5774 retval = true;
5775 break;
5776 case ADC_GAIN_CAL:
5777 case ADC_DC_CAL:
5778 if (!IS_CHAN_B(chan)
5779 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5780 retval = true;
5781 break;
5782 }
5783
5784 return retval;
5785}
5786
5787static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5788 struct ath9k_channel *chan)
5789{
5790 struct ath_hal_5416 *ahp = AH5416(ah);
5791 struct ath9k_channel *ichan =
5792 ath9k_regd_check_channel(ah, chan);
5793
5794 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5795 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5796 AR_PHY_AGC_CONTROL_CAL);
5797
5798 if (!ath9k_hw_wait
5799 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5800 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5801 "%s: offset calibration failed to complete in 1ms; "
5802 "noisy environment?\n", __func__);
5803 return false;
5804 }
5805
5806 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5807 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5808 AR_PHY_AGC_CONTROL_NF);
5809
5810 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5811 NULL;
5812
5813 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5814 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5815 INIT_CAL(&ahp->ah_adcGainCalData);
5816 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5817 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5818 "%s: enabling ADC Gain Calibration.\n",
5819 __func__);
5820 }
5821 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5822 INIT_CAL(&ahp->ah_adcDcCalData);
5823 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5824 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5825 "%s: enabling ADC DC Calibration.\n",
5826 __func__);
5827 }
5828 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5829 INIT_CAL(&ahp->ah_iqCalData);
5830 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5831 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5832 "%s: enabling IQ Calibration.\n",
5833 __func__);
5834 }
5835
5836 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5837
5838 if (ahp->ah_cal_list_curr)
5839 ath9k_hw_reset_calibration(ah,
5840 ahp->ah_cal_list_curr);
5841 }
5842
5843 ichan->CalValid = 0;
5844
5845 return true;
5846}
5847
5848
5849bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5850 struct ath9k_channel *chan,
5851 enum ath9k_ht_macmode macmode,
5852 u8 txchainmask, u8 rxchainmask,
5853 enum ath9k_ht_extprotspacing extprotspacing,
5854 bool bChannelChange,
5855 int *status)
5856{
5857#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5858 u32 saveLedState;
5859 struct ath_hal_5416 *ahp = AH5416(ah);
5860 struct ath9k_channel *curchan = ah->ah_curchan;
5861 u32 saveDefAntenna;
5862 u32 macStaId1;
5863 int ecode;
5864 int i, rx_chainmask;
5865
5866 ahp->ah_extprotspacing = extprotspacing;
5867 ahp->ah_txchainmask = txchainmask;
5868 ahp->ah_rxchainmask = rxchainmask;
5869
5870 if (AR_SREV_9280(ah)) {
5871 ahp->ah_txchainmask &= 0x3;
5872 ahp->ah_rxchainmask &= 0x3;
5873 }
5874
5875 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5876 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5877 "%s: invalid channel %u/0x%x; no mapping\n",
5878 __func__, chan->channel, chan->channelFlags);
5879 FAIL(-EINVAL);
5880 }
5881
5882 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5883 return false;
5884
5885 if (curchan)
5886 ath9k_hw_getnf(ah, curchan);
5887
5888 if (bChannelChange &&
5889 (ahp->ah_chipFullSleep != true) &&
5890 (ah->ah_curchan != NULL) &&
5891 (chan->channel != ah->ah_curchan->channel) &&
5892 ((chan->channelFlags & CHANNEL_ALL) ==
5893 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5894 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5895 !IS_CHAN_A_5MHZ_SPACED(ah->
5896 ah_curchan)))) {
5897
5898 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5899 ath9k_hw_loadnf(ah, ah->ah_curchan);
5900 ath9k_hw_start_nfcal(ah);
5901 return true;
5902 }
5903 }
5904
5905 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5906 if (saveDefAntenna == 0)
5907 saveDefAntenna = 1;
5908
5909 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5910
5911 saveLedState = REG_READ(ah, AR_CFG_LED) &
5912 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5913 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5914
5915 ath9k_hw_mark_phy_inactive(ah);
5916
5917 if (!ath9k_hw_chip_reset(ah, chan)) {
5918 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5919 __func__);
5920 FAIL(-EIO);
5921 }
5922
5923 if (AR_SREV_9280(ah)) {
5924 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5925 AR_GPIO_JTAG_DISABLE);
5926
60b67f51 5927 if (ah->ah_caps.wireless_modes & ATH9K_MODE_SEL_11A) {
f078f209
LR
5928 if (IS_CHAN_5GHZ(chan))
5929 ath9k_hw_set_gpio(ah, 9, 0);
5930 else
5931 ath9k_hw_set_gpio(ah, 9, 1);
5932 }
5933 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5934 }
5935
5936 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5937 if (ecode != 0)
5938 goto bad;
5939
5940 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5941 ath9k_hw_set_delta_slope(ah, chan);
5942
5943 if (AR_SREV_9280_10_OR_LATER(ah))
5944 ath9k_hw_9280_spur_mitigate(ah, chan);
5945 else
5946 ath9k_hw_spur_mitigate(ah, chan);
5947
5948 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5949 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5950 "%s: error setting board options\n", __func__);
5951 FAIL(-EIO);
5952 }
5953
5954 ath9k_hw_decrease_chain_power(ah, chan);
5955
5956 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5957 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5958 | macStaId1
5959 | AR_STA_ID1_RTS_USE_DEF
5960 | (ah->ah_config.
60b67f51 5961 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
f078f209
LR
5962 | ahp->ah_staId1Defaults);
5963 ath9k_hw_set_operating_mode(ah, opmode);
5964
5965 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5966 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5967
5968 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5969
5970 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5971 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5972 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5973
5974 REG_WRITE(ah, AR_ISR, ~0);
5975
5976 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5977
5978 if (AR_SREV_9280_10_OR_LATER(ah)) {
5979 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5980 FAIL(-EIO);
5981 } else {
5982 if (!(ath9k_hw_set_channel(ah, chan)))
5983 FAIL(-EIO);
5984 }
5985
5986 for (i = 0; i < AR_NUM_DCU; i++)
5987 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5988
5989 ahp->ah_intrTxqs = 0;
60b67f51 5990 for (i = 0; i < ah->ah_caps.total_queues; i++)
f078f209
LR
5991 ath9k_hw_resettxqueue(ah, i);
5992
5993 ath9k_hw_init_interrupt_masks(ah, opmode);
5994 ath9k_hw_init_qos(ah);
5995
5996 ath9k_hw_init_user_settings(ah);
5997
5998 ah->ah_opmode = opmode;
5999
6000 REG_WRITE(ah, AR_STA_ID1,
6001 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6002
6003 ath9k_hw_set_dma(ah);
6004
6005 REG_WRITE(ah, AR_OBS, 8);
6006
6007 if (ahp->ah_intrMitigation) {
6008
6009 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6010 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6011 }
6012
6013 ath9k_hw_init_bb(ah, chan);
6014
6015 if (!ath9k_hw_init_cal(ah, chan))
6016 FAIL(-ENODEV);
6017
6018 rx_chainmask = ahp->ah_rxchainmask;
6019 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6020 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6021 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6022 }
6023
6024 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6025
6026 if (AR_SREV_9100(ah)) {
6027 u32 mask;
6028 mask = REG_READ(ah, AR_CFG);
6029 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6030 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6031 "%s CFG Byte Swap Set 0x%x\n", __func__,
6032 mask);
6033 } else {
6034 mask =
6035 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6036 REG_WRITE(ah, AR_CFG, mask);
6037 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6038 "%s Setting CFG 0x%x\n", __func__,
6039 REG_READ(ah, AR_CFG));
6040 }
6041 } else {
6042#ifdef __BIG_ENDIAN
6043 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6044#endif
6045 }
6046
6047 return true;
6048bad:
6049 if (status)
6050 *status = ecode;
6051 return false;
6052#undef FAIL
6053}
6054
6055bool ath9k_hw_phy_disable(struct ath_hal *ah)
6056{
6057 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6058}
6059
6060bool ath9k_hw_disable(struct ath_hal *ah)
6061{
6062 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6063 return false;
6064
6065 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6066}
6067
6068bool
6069ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6070 u8 rxchainmask, bool longcal,
6071 bool *isCalDone)
6072{
6073 struct ath_hal_5416 *ahp = AH5416(ah);
6074 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6075 struct ath9k_channel *ichan =
6076 ath9k_regd_check_channel(ah, chan);
6077
6078 *isCalDone = true;
6079
6080 if (ichan == NULL) {
6081 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6082 "%s: invalid channel %u/0x%x; no mapping\n",
6083 __func__, chan->channel, chan->channelFlags);
6084 return false;
6085 }
6086
6087 if (currCal &&
6088 (currCal->calState == CAL_RUNNING ||
6089 currCal->calState == CAL_WAITING)) {
6090 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6091 isCalDone);
6092 if (*isCalDone) {
6093 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6094
6095 if (currCal->calState == CAL_WAITING) {
6096 *isCalDone = false;
6097 ath9k_hw_reset_calibration(ah, currCal);
6098 }
6099 }
6100 }
6101
6102 if (longcal) {
6103 ath9k_hw_getnf(ah, ichan);
6104 ath9k_hw_loadnf(ah, ah->ah_curchan);
6105 ath9k_hw_start_nfcal(ah);
6106
6107 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6108
6109 chan->channelFlags |= CHANNEL_CW_INT;
6110 ichan->channelFlags &= ~CHANNEL_CW_INT;
6111 }
6112 }
6113
6114 return true;
6115}
6116
6117static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6118{
6119 struct ath_hal_5416 *ahp = AH5416(ah);
6120 int i;
6121
6122 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6123 ahp->ah_totalPowerMeasI[i] +=
6124 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6125 ahp->ah_totalPowerMeasQ[i] +=
6126 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6127 ahp->ah_totalIqCorrMeas[i] +=
6128 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6129 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6130 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6131 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6132 ahp->ah_totalPowerMeasQ[i],
6133 ahp->ah_totalIqCorrMeas[i]);
6134 }
6135}
6136
6137static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6138{
6139 struct ath_hal_5416 *ahp = AH5416(ah);
6140 int i;
6141
6142 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6143 ahp->ah_totalAdcIOddPhase[i] +=
6144 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6145 ahp->ah_totalAdcIEvenPhase[i] +=
6146 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6147 ahp->ah_totalAdcQOddPhase[i] +=
6148 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6149 ahp->ah_totalAdcQEvenPhase[i] +=
6150 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6151
6152 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6153 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6154 "oddq=0x%08x; evenq=0x%08x;\n",
6155 ahp->ah_CalSamples, i,
6156 ahp->ah_totalAdcIOddPhase[i],
6157 ahp->ah_totalAdcIEvenPhase[i],
6158 ahp->ah_totalAdcQOddPhase[i],
6159 ahp->ah_totalAdcQEvenPhase[i]);
6160 }
6161}
6162
6163static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6164{
6165 struct ath_hal_5416 *ahp = AH5416(ah);
6166 int i;
6167
6168 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6169 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6170 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6171 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6172 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6173 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6174 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6175 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6176 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6177
6178 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6179 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6180 "oddq=0x%08x; evenq=0x%08x;\n",
6181 ahp->ah_CalSamples, i,
6182 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6183 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6184 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6185 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6186 }
6187}
6188
6189static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6190{
6191 struct ath_hal_5416 *ahp = AH5416(ah);
6192 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6193 u32 qCoffDenom, iCoffDenom;
6194 int32_t qCoff, iCoff;
6195 int iqCorrNeg, i;
6196
6197 for (i = 0; i < numChains; i++) {
6198 powerMeasI = ahp->ah_totalPowerMeasI[i];
6199 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6200 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6201
6202 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6203 "Starting IQ Cal and Correction for Chain %d\n",
6204 i);
6205
6206 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6207 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6208 i, ahp->ah_totalIqCorrMeas[i]);
6209
6210 iqCorrNeg = 0;
6211
6212
6213 if (iqCorrMeas > 0x80000000) {
6214 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6215 iqCorrNeg = 1;
6216 }
6217
6218 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6219 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6220 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6221 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6222 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6223 iqCorrNeg);
6224
6225 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6226 qCoffDenom = powerMeasQ / 64;
6227
6228 if (powerMeasQ != 0) {
6229
6230 iCoff = iqCorrMeas / iCoffDenom;
6231 qCoff = powerMeasI / qCoffDenom - 64;
6232 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6233 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6234 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6235 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6236
6237
6238 iCoff = iCoff & 0x3f;
6239 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6240 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6241 if (iqCorrNeg == 0x0)
6242 iCoff = 0x40 - iCoff;
6243
6244 if (qCoff > 15)
6245 qCoff = 15;
6246 else if (qCoff <= -16)
6247 qCoff = 16;
6248
6249 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6250 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6251 i, iCoff, qCoff);
6252
6253 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6254 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6255 iCoff);
6256 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6257 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6258 qCoff);
6259 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6260 "IQ Cal and Correction done for Chain %d\n",
6261 i);
6262 }
6263 }
6264
6265 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6266 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6267}
6268
6269static void
6270ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6271{
6272 struct ath_hal_5416 *ahp = AH5416(ah);
6273 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6274 qEvenMeasOffset;
6275 u32 qGainMismatch, iGainMismatch, val, i;
6276
6277 for (i = 0; i < numChains; i++) {
6278 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6279 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6280 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6281 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6282
6283 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6284 "Starting ADC Gain Cal for Chain %d\n", i);
6285
6286 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6287 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6288 iOddMeasOffset);
6289 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6290 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6291 iEvenMeasOffset);
6292 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6293 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6294 qOddMeasOffset);
6295 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6296 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6297 qEvenMeasOffset);
6298
6299 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6300 iGainMismatch =
6301 ((iEvenMeasOffset * 32) /
6302 iOddMeasOffset) & 0x3f;
6303 qGainMismatch =
6304 ((qOddMeasOffset * 32) /
6305 qEvenMeasOffset) & 0x3f;
6306
6307 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6309 iGainMismatch);
6310 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6311 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6312 qGainMismatch);
6313
6314 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6315 val &= 0xfffff000;
6316 val |= (qGainMismatch) | (iGainMismatch << 6);
6317 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6318
6319 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6320 "ADC Gain Cal done for Chain %d\n", i);
6321 }
6322 }
6323
6324 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6325 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6326 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6327}
6328
6329static void
6330ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6331{
6332 struct ath_hal_5416 *ahp = AH5416(ah);
6333 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6334 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6335 const struct hal_percal_data *calData =
6336 ahp->ah_cal_list_curr->calData;
6337 u32 numSamples =
6338 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6339
6340 for (i = 0; i < numChains; i++) {
6341 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6342 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6343 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6344 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6345
6346 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6347 "Starting ADC DC Offset Cal for Chain %d\n", i);
6348
6349 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6350 "Chn %d pwr_meas_odd_i = %d\n", i,
6351 iOddMeasOffset);
6352 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6353 "Chn %d pwr_meas_even_i = %d\n", i,
6354 iEvenMeasOffset);
6355 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6356 "Chn %d pwr_meas_odd_q = %d\n", i,
6357 qOddMeasOffset);
6358 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6359 "Chn %d pwr_meas_even_q = %d\n", i,
6360 qEvenMeasOffset);
6361
6362 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6363 numSamples) & 0x1ff;
6364 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6365 numSamples) & 0x1ff;
6366
6367 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6369 iDcMismatch);
6370 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6371 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6372 qDcMismatch);
6373
6374 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6375 val &= 0xc0000fff;
6376 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6377 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6378
6379 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6380 "ADC DC Offset Cal done for Chain %d\n", i);
6381 }
6382
6383 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6384 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6385 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6386}
6387
6388bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6389{
6390 struct ath_hal_5416 *ahp = AH5416(ah);
6391 struct ath9k_channel *chan = ah->ah_curchan;
6392
6393 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6394
6395 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6396 ath9k_regd_get_ctl(ah, chan),
6397 ath9k_regd_get_antenna_allowed(ah,
6398 chan),
6399 chan->maxRegTxPower * 2,
6400 min((u32) MAX_RATE_POWER,
6401 (u32) ah->ah_powerLimit)) != 0)
6402 return false;
6403
6404 return true;
6405}
6406
6407void
6408ath9k_hw_get_channel_centers(struct ath_hal *ah,
6409 struct ath9k_channel *chan,
6410 struct chan_centers *centers)
6411{
6412 int8_t extoff;
6413 struct ath_hal_5416 *ahp = AH5416(ah);
6414
6415 if (!IS_CHAN_HT40(chan)) {
6416 centers->ctl_center = centers->ext_center =
6417 centers->synth_center = chan->channel;
6418 return;
6419 }
6420
6421 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6422 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6423 centers->synth_center =
6424 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6425 extoff = 1;
6426 } else {
6427 centers->synth_center =
6428 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6429 extoff = -1;
6430 }
6431
6432 centers->ctl_center = centers->synth_center - (extoff *
6433 HT40_CHANNEL_CENTER_SHIFT);
6434 centers->ext_center = centers->synth_center + (extoff *
6435 ((ahp->
6436 ah_extprotspacing
6437 ==
6438 ATH9K_HT_EXTPROTSPACING_20)
6439 ?
6440 HT40_CHANNEL_CENTER_SHIFT
6441 : 15));
6442
6443}
6444
6445void
6446ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6447 bool *isCalDone)
6448{
6449 struct ath_hal_5416 *ahp = AH5416(ah);
6450 struct ath9k_channel *ichan =
6451 ath9k_regd_check_channel(ah, chan);
6452 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6453
6454 *isCalDone = true;
6455
6456 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6457 return;
6458
6459 if (currCal == NULL)
6460 return;
6461
6462 if (ichan == NULL) {
6463 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6464 "%s: invalid channel %u/0x%x; no mapping\n",
6465 __func__, chan->channel, chan->channelFlags);
6466 return;
6467 }
6468
6469
6470 if (currCal->calState != CAL_DONE) {
6471 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6472 "%s: Calibration state incorrect, %d\n",
6473 __func__, currCal->calState);
6474 return;
6475 }
6476
6477
6478 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6479 return;
6480
6481 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6482 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6483 __func__, currCal->calData->calType, chan->channel,
6484 chan->channelFlags);
6485
6486 ichan->CalValid &= ~currCal->calData->calType;
6487 currCal->calState = CAL_WAITING;
6488
6489 *isCalDone = false;
6490}
6491
6492void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6493{
6494 struct ath_hal_5416 *ahp = AH5416(ah);
6495
6496 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6497}
6498
6499bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6500{
6501 struct ath_hal_5416 *ahp = AH5416(ah);
6502
6503 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6504 return true;
6505}
6506
6507void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6508{
6509 struct ath_hal_5416 *ahp = AH5416(ah);
6510
6511 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6512}
6513
6514bool
6515ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6516{
6517 struct ath_hal_5416 *ahp = AH5416(ah);
6518
6519 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6520
6521 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6522 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6523
6524 return true;
6525}
6526
6527#ifdef CONFIG_ATH9K_RFKILL
6528static void ath9k_enable_rfkill(struct ath_hal *ah)
6529{
6530 struct ath_hal_5416 *ahp = AH5416(ah);
6531
6532 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6533 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6534
6535 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6536 AR_GPIO_INPUT_MUX2_RFSILENT);
6537
6538 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6539 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6540
6541 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6542
6543 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6544 !ahp->ah_gpioBit);
6545 } else {
6546 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6547 ahp->ah_gpioBit);
6548 }
6549}
6550#endif
6551
6552void
6553ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6554 u16 assocId)
6555{
6556 struct ath_hal_5416 *ahp = AH5416(ah);
6557
6558 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6559 ahp->ah_assocId = assocId;
6560
6561 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6562 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6563 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6564}
6565
6566u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6567{
6568 u64 tsf;
6569
6570 tsf = REG_READ(ah, AR_TSF_U32);
6571 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6572 return tsf;
6573}
6574
6575void ath9k_hw_reset_tsf(struct ath_hal *ah)
6576{
6577 int count;
6578
6579 count = 0;
6580 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6581 count++;
6582 if (count > 10) {
6583 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6584 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6585 __func__);
6586 break;
6587 }
6588 udelay(10);
6589 }
6590 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6591}
6592
6593u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6594{
6595 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6596}
6597
6598void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6599{
6600 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6601}
6602
6603bool
6604ath9k_hw_setantennaswitch(struct ath_hal *ah,
6605 enum ath9k_ant_setting settings,
6606 struct ath9k_channel *chan,
6607 u8 *tx_chainmask,
6608 u8 *rx_chainmask,
6609 u8 *antenna_cfgd)
6610{
6611 struct ath_hal_5416 *ahp = AH5416(ah);
6612 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6613
6614 if (AR_SREV_9280(ah)) {
6615 if (!tx_chainmask_cfg) {
6616
6617 tx_chainmask_cfg = *tx_chainmask;
6618 rx_chainmask_cfg = *rx_chainmask;
6619 }
6620
6621 switch (settings) {
6622 case ATH9K_ANT_FIXED_A:
6623 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6624 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6625 *antenna_cfgd = true;
6626 break;
6627 case ATH9K_ANT_FIXED_B:
60b67f51 6628 if (ah->ah_caps.tx_chainmask >
f078f209
LR
6629 ATH9K_ANTENNA1_CHAINMASK) {
6630 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6631 }
6632 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6633 *antenna_cfgd = true;
6634 break;
6635 case ATH9K_ANT_VARIABLE:
6636 *tx_chainmask = tx_chainmask_cfg;
6637 *rx_chainmask = rx_chainmask_cfg;
6638 *antenna_cfgd = true;
6639 break;
6640 default:
6641 break;
6642 }
6643 } else {
6644 ahp->ah_diversityControl = settings;
6645 }
6646
6647 return true;
6648}
6649
6650void ath9k_hw_setopmode(struct ath_hal *ah)
6651{
6652 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6653}
6654
6655bool
60b67f51 6656ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
f078f209
LR
6657 u32 capability, u32 *result)
6658{
6659 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 6660 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6661
6662 switch (type) {
60b67f51 6663 case ATH9K_CAP_CIPHER:
f078f209
LR
6664 switch (capability) {
6665 case ATH9K_CIPHER_AES_CCM:
6666 case ATH9K_CIPHER_AES_OCB:
6667 case ATH9K_CIPHER_TKIP:
6668 case ATH9K_CIPHER_WEP:
6669 case ATH9K_CIPHER_MIC:
6670 case ATH9K_CIPHER_CLR:
6671 return true;
6672 default:
6673 return false;
6674 }
60b67f51 6675 case ATH9K_CAP_TKIP_MIC:
f078f209
LR
6676 switch (capability) {
6677 case 0:
6678 return true;
6679 case 1:
6680 return (ahp->ah_staId1Defaults &
6681 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6682 false;
6683 }
60b67f51 6684 case ATH9K_CAP_TKIP_SPLIT:
f078f209
LR
6685 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6686 false : true;
60b67f51 6687 case ATH9K_CAP_WME_TKIPMIC:
f078f209 6688 return 0;
60b67f51 6689 case ATH9K_CAP_PHYCOUNTERS:
f078f209 6690 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
60b67f51 6691 case ATH9K_CAP_DIVERSITY:
f078f209
LR
6692 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6693 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6694 true : false;
60b67f51 6695 case ATH9K_CAP_PHYDIAG:
f078f209 6696 return true;
60b67f51 6697 case ATH9K_CAP_MCAST_KEYSRCH:
f078f209
LR
6698 switch (capability) {
6699 case 0:
6700 return true;
6701 case 1:
6702 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6703 return false;
6704 } else {
6705 return (ahp->ah_staId1Defaults &
6706 AR_STA_ID1_MCAST_KSRCH) ? true :
6707 false;
6708 }
6709 }
6710 return false;
60b67f51 6711 case ATH9K_CAP_TSF_ADJUST:
f078f209
LR
6712 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6713 true : false;
60b67f51 6714 case ATH9K_CAP_RFSILENT:
f078f209
LR
6715 if (capability == 3)
6716 return false;
60b67f51
S
6717 case ATH9K_CAP_ANT_CFG_2GHZ:
6718 *result = pCap->num_antcfg_2ghz;
f078f209 6719 return true;
60b67f51
S
6720 case ATH9K_CAP_ANT_CFG_5GHZ:
6721 *result = pCap->num_antcfg_5ghz;
f078f209 6722 return true;
60b67f51 6723 case ATH9K_CAP_TXPOW:
f078f209
LR
6724 switch (capability) {
6725 case 0:
6726 return 0;
6727 case 1:
6728 *result = ah->ah_powerLimit;
6729 return 0;
6730 case 2:
6731 *result = ah->ah_maxPowerLevel;
6732 return 0;
6733 case 3:
6734 *result = ah->ah_tpScale;
6735 return 0;
6736 }
6737 return false;
6738 default:
6739 return false;
6740 }
6741}
6742
6743int
6744ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6745{
6746 struct ath_hal_5416 *ahp = AH5416(ah);
6747 struct ath9k_channel *chan = ah->ah_curchan;
60b67f51 6748 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6749 u16 ant_config;
6750 u32 halNumAntConfig;
6751
6752 halNumAntConfig =
60b67f51
S
6753 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6754 num_antcfg_5ghz;
f078f209
LR
6755
6756 if (cfg < halNumAntConfig) {
6757 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6758 cfg, &ant_config)) {
6759 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6760 return 0;
6761 }
6762 }
6763
6764 return -EINVAL;
6765}
6766
6767bool ath9k_hw_intrpend(struct ath_hal *ah)
6768{
6769 u32 host_isr;
6770
6771 if (AR_SREV_9100(ah))
6772 return true;
6773
6774 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6775 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6776 return true;
6777
6778 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6779 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6780 && (host_isr != AR_INTR_SPURIOUS))
6781 return true;
6782
6783 return false;
6784}
6785
6786bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6787{
6788 u32 isr = 0;
6789 u32 mask2 = 0;
60b67f51 6790 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6791 u32 sync_cause = 0;
6792 bool fatal_int = false;
6793
6794 if (!AR_SREV_9100(ah)) {
6795 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6796 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6797 == AR_RTC_STATUS_ON) {
6798 isr = REG_READ(ah, AR_ISR);
6799 }
6800 }
6801
6802 sync_cause =
6803 REG_READ(ah,
6804 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6805
6806 *masked = 0;
6807
6808 if (!isr && !sync_cause)
6809 return false;
6810 } else {
6811 *masked = 0;
6812 isr = REG_READ(ah, AR_ISR);
6813 }
6814
6815 if (isr) {
6816 struct ath_hal_5416 *ahp = AH5416(ah);
6817
6818 if (isr & AR_ISR_BCNMISC) {
6819 u32 isr2;
6820 isr2 = REG_READ(ah, AR_ISR_S2);
6821 if (isr2 & AR_ISR_S2_TIM)
6822 mask2 |= ATH9K_INT_TIM;
6823 if (isr2 & AR_ISR_S2_DTIM)
6824 mask2 |= ATH9K_INT_DTIM;
6825 if (isr2 & AR_ISR_S2_DTIMSYNC)
6826 mask2 |= ATH9K_INT_DTIMSYNC;
6827 if (isr2 & (AR_ISR_S2_CABEND))
6828 mask2 |= ATH9K_INT_CABEND;
6829 if (isr2 & AR_ISR_S2_GTT)
6830 mask2 |= ATH9K_INT_GTT;
6831 if (isr2 & AR_ISR_S2_CST)
6832 mask2 |= ATH9K_INT_CST;
6833 }
6834
6835 isr = REG_READ(ah, AR_ISR_RAC);
6836 if (isr == 0xffffffff) {
6837 *masked = 0;
6838 return false;
6839 }
6840
6841 *masked = isr & ATH9K_INT_COMMON;
6842
6843 if (ahp->ah_intrMitigation) {
6844
6845 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6846 *masked |= ATH9K_INT_RX;
6847 }
6848
6849 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6850 *masked |= ATH9K_INT_RX;
6851 if (isr &
6852 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6853 AR_ISR_TXEOL)) {
6854 u32 s0_s, s1_s;
6855
6856 *masked |= ATH9K_INT_TX;
6857
6858 s0_s = REG_READ(ah, AR_ISR_S0_S);
6859 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6860 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6861
6862 s1_s = REG_READ(ah, AR_ISR_S1_S);
6863 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6864 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6865 }
6866
6867 if (isr & AR_ISR_RXORN) {
6868 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6869 "%s: receive FIFO overrun interrupt\n",
6870 __func__);
6871 }
6872
6873 if (!AR_SREV_9100(ah)) {
60b67f51 6874 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
f078f209
LR
6875 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6876 if (isr5 & AR_ISR_S5_TIM_TIMER)
6877 *masked |= ATH9K_INT_TIM_TIMER;
6878 }
6879 }
6880
6881 *masked |= mask2;
6882 }
6883 if (AR_SREV_9100(ah))
6884 return true;
6885 if (sync_cause) {
6886 fatal_int =
6887 (sync_cause &
6888 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6889 ? true : false;
6890
6891 if (fatal_int) {
6892 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6893 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6894 "%s: received PCI FATAL interrupt\n",
6895 __func__);
6896 }
6897 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6898 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6899 "%s: received PCI PERR interrupt\n",
6900 __func__);
6901 }
6902 }
6903 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6904 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6905 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6906 __func__);
6907 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6908 REG_WRITE(ah, AR_RC, 0);
6909 *masked |= ATH9K_INT_FATAL;
6910 }
6911 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6912 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6913 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6914 __func__);
6915 }
6916
6917 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6918 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6919 }
6920 return true;
6921}
6922
6923enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6924{
6925 return AH5416(ah)->ah_maskReg;
6926}
6927
6928enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6929{
6930 struct ath_hal_5416 *ahp = AH5416(ah);
6931 u32 omask = ahp->ah_maskReg;
6932 u32 mask, mask2;
60b67f51 6933 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6934
6935 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6936 omask, ints);
6937
6938 if (omask & ATH9K_INT_GLOBAL) {
6939 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6940 __func__);
6941 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6942 (void) REG_READ(ah, AR_IER);
6943 if (!AR_SREV_9100(ah)) {
6944 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6945 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6946
6947 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6948 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6949 }
6950 }
6951
6952 mask = ints & ATH9K_INT_COMMON;
6953 mask2 = 0;
6954
6955 if (ints & ATH9K_INT_TX) {
6956 if (ahp->ah_txOkInterruptMask)
6957 mask |= AR_IMR_TXOK;
6958 if (ahp->ah_txDescInterruptMask)
6959 mask |= AR_IMR_TXDESC;
6960 if (ahp->ah_txErrInterruptMask)
6961 mask |= AR_IMR_TXERR;
6962 if (ahp->ah_txEolInterruptMask)
6963 mask |= AR_IMR_TXEOL;
6964 }
6965 if (ints & ATH9K_INT_RX) {
6966 mask |= AR_IMR_RXERR;
6967 if (ahp->ah_intrMitigation)
6968 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6969 else
6970 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
60b67f51 6971 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
f078f209
LR
6972 mask |= AR_IMR_GENTMR;
6973 }
6974
6975 if (ints & (ATH9K_INT_BMISC)) {
6976 mask |= AR_IMR_BCNMISC;
6977 if (ints & ATH9K_INT_TIM)
6978 mask2 |= AR_IMR_S2_TIM;
6979 if (ints & ATH9K_INT_DTIM)
6980 mask2 |= AR_IMR_S2_DTIM;
6981 if (ints & ATH9K_INT_DTIMSYNC)
6982 mask2 |= AR_IMR_S2_DTIMSYNC;
6983 if (ints & ATH9K_INT_CABEND)
6984 mask2 |= (AR_IMR_S2_CABEND);
6985 }
6986
6987 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6988 mask |= AR_IMR_BCNMISC;
6989 if (ints & ATH9K_INT_GTT)
6990 mask2 |= AR_IMR_S2_GTT;
6991 if (ints & ATH9K_INT_CST)
6992 mask2 |= AR_IMR_S2_CST;
6993 }
6994
6995 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
6996 mask);
6997 REG_WRITE(ah, AR_IMR, mask);
6998 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
6999 AR_IMR_S2_DTIM |
7000 AR_IMR_S2_DTIMSYNC |
7001 AR_IMR_S2_CABEND |
7002 AR_IMR_S2_CABTO |
7003 AR_IMR_S2_TSFOOR |
7004 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7005 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7006 ahp->ah_maskReg = ints;
7007
60b67f51 7008 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
f078f209
LR
7009 if (ints & ATH9K_INT_TIM_TIMER)
7010 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7011 else
7012 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7013 }
7014
7015 if (ints & ATH9K_INT_GLOBAL) {
7016 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7017 __func__);
7018 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7019 if (!AR_SREV_9100(ah)) {
7020 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7021 AR_INTR_MAC_IRQ);
7022 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7023
7024
7025 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7026 AR_INTR_SYNC_DEFAULT);
7027 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7028 AR_INTR_SYNC_DEFAULT);
7029 }
7030 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7031 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7032 }
7033
7034 return omask;
7035}
7036
7037void
7038ath9k_hw_beaconinit(struct ath_hal *ah,
7039 u32 next_beacon, u32 beacon_period)
7040{
7041 struct ath_hal_5416 *ahp = AH5416(ah);
7042 int flags = 0;
7043
7044 ahp->ah_beaconInterval = beacon_period;
7045
7046 switch (ah->ah_opmode) {
7047 case ATH9K_M_STA:
7048 case ATH9K_M_MONITOR:
7049 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7050 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7051 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7052 flags |= AR_TBTT_TIMER_EN;
7053 break;
7054 case ATH9K_M_IBSS:
7055 REG_SET_BIT(ah, AR_TXCFG,
7056 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7057 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7058 TU_TO_USEC(next_beacon +
7059 (ahp->ah_atimWindow ? ahp->
7060 ah_atimWindow : 1)));
7061 flags |= AR_NDP_TIMER_EN;
7062 case ATH9K_M_HOSTAP:
7063 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7064 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7065 TU_TO_USEC(next_beacon -
7066 ah->ah_config.
60b67f51 7067 dma_beacon_response_time));
f078f209
LR
7068 REG_WRITE(ah, AR_NEXT_SWBA,
7069 TU_TO_USEC(next_beacon -
7070 ah->ah_config.
60b67f51 7071 sw_beacon_response_time));
f078f209
LR
7072 flags |=
7073 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7074 break;
7075 }
7076
7077 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7078 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7079 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7080 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7081
7082 beacon_period &= ~ATH9K_BEACON_ENA;
7083 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7084 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7085 ath9k_hw_reset_tsf(ah);
7086 }
7087
7088 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7089}
7090
7091void
7092ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7093 const struct ath9k_beacon_state *bs)
7094{
7095 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
60b67f51 7096 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7097
7098 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7099
7100 REG_WRITE(ah, AR_BEACON_PERIOD,
7101 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7102 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7103 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7104
7105 REG_RMW_FIELD(ah, AR_RSSI_THR,
7106 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7107
7108 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7109
7110 if (bs->bs_sleepduration > beaconintval)
7111 beaconintval = bs->bs_sleepduration;
7112
7113 dtimperiod = bs->bs_dtimperiod;
7114 if (bs->bs_sleepduration > dtimperiod)
7115 dtimperiod = bs->bs_sleepduration;
7116
7117 if (beaconintval == dtimperiod)
7118 nextTbtt = bs->bs_nextdtim;
7119 else
7120 nextTbtt = bs->bs_nexttbtt;
7121
7122 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7123 bs->bs_nextdtim);
7124 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7125 nextTbtt);
7126 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7127 beaconintval);
7128 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7129 dtimperiod);
7130
7131 REG_WRITE(ah, AR_NEXT_DTIM,
7132 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7133 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7134
7135 REG_WRITE(ah, AR_SLEEP1,
7136 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7137 | AR_SLEEP1_ASSUME_DTIM);
7138
60b67f51 7139 if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
f078f209
LR
7140 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7141 else
7142 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7143
7144 REG_WRITE(ah, AR_SLEEP2,
7145 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7146
7147 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7148 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7149
7150 REG_SET_BIT(ah, AR_TIMER_MODE,
7151 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7152 AR_DTIM_TIMER_EN);
7153
7154}
7155
7156bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7157{
60b67f51 7158 if (entry < ah->ah_caps.keycache_size) {
f078f209
LR
7159 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7160 if (val & AR_KEYTABLE_VALID)
7161 return true;
7162 }
7163 return false;
7164}
7165
7166bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7167{
7168 u32 keyType;
7169
60b67f51 7170 if (entry >= ah->ah_caps.keycache_size) {
f078f209
LR
7171 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7172 "%s: entry %u out of range\n", __func__, entry);
7173 return false;
7174 }
7175 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7176
7177 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7178 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7179 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7180 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7181 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7182 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7183 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7184 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7185
7186 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7187 u16 micentry = entry + 64;
7188
7189 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7190 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7191 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7192 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7193
7194 }
7195
7196 if (ah->ah_curchan == NULL)
7197 return true;
7198
7199 return true;
7200}
7201
7202bool
7203ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7204 const u8 *mac)
7205{
7206 u32 macHi, macLo;
7207
60b67f51 7208 if (entry >= ah->ah_caps.keycache_size) {
f078f209
LR
7209 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7210 "%s: entry %u out of range\n", __func__, entry);
7211 return false;
7212 }
7213
7214 if (mac != NULL) {
7215 macHi = (mac[5] << 8) | mac[4];
7216 macLo = (mac[3] << 24) | (mac[2] << 16)
7217 | (mac[1] << 8) | mac[0];
7218 macLo >>= 1;
7219 macLo |= (macHi & 1) << 31;
7220 macHi >>= 1;
7221 } else {
7222 macLo = macHi = 0;
7223 }
7224 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7225 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7226
7227 return true;
7228}
7229
7230bool
7231ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7232 const struct ath9k_keyval *k,
7233 const u8 *mac, int xorKey)
7234{
60b67f51 7235 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7236 u32 key0, key1, key2, key3, key4;
7237 u32 keyType;
7238 u32 xorMask = xorKey ?
7239 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7240 | ATH9K_KEY_XOR) : 0;
7241 struct ath_hal_5416 *ahp = AH5416(ah);
7242
60b67f51 7243 if (entry >= pCap->keycache_size) {
f078f209
LR
7244 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7245 "%s: entry %u out of range\n", __func__, entry);
7246 return false;
7247 }
7248 switch (k->kv_type) {
7249 case ATH9K_CIPHER_AES_OCB:
7250 keyType = AR_KEYTABLE_TYPE_AES;
7251 break;
7252 case ATH9K_CIPHER_AES_CCM:
60b67f51 7253 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
f078f209
LR
7254 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7255 "%s: AES-CCM not supported by "
7256 "mac rev 0x%x\n", __func__,
7257 ah->ah_macRev);
7258 return false;
7259 }
7260 keyType = AR_KEYTABLE_TYPE_CCM;
7261 break;
7262 case ATH9K_CIPHER_TKIP:
7263 keyType = AR_KEYTABLE_TYPE_TKIP;
7264 if (ATH9K_IS_MIC_ENABLED(ah)
60b67f51 7265 && entry + 64 >= pCap->keycache_size) {
f078f209
LR
7266 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7267 "%s: entry %u inappropriate for TKIP\n",
7268 __func__, entry);
7269 return false;
7270 }
7271 break;
7272 case ATH9K_CIPHER_WEP:
7273 if (k->kv_len < 40 / NBBY) {
7274 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7275 "%s: WEP key length %u too small\n",
7276 __func__, k->kv_len);
7277 return false;
7278 }
7279 if (k->kv_len <= 40 / NBBY)
7280 keyType = AR_KEYTABLE_TYPE_40;
7281 else if (k->kv_len <= 104 / NBBY)
7282 keyType = AR_KEYTABLE_TYPE_104;
7283 else
7284 keyType = AR_KEYTABLE_TYPE_128;
7285 break;
7286 case ATH9K_CIPHER_CLR:
7287 keyType = AR_KEYTABLE_TYPE_CLR;
7288 break;
7289 default:
7290 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7291 "%s: cipher %u not supported\n", __func__,
7292 k->kv_type);
7293 return false;
7294 }
7295
7296 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7297 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7298 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7299 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7300 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7301 if (k->kv_len <= 104 / NBBY)
7302 key4 &= 0xff;
7303
7304 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7305 u16 micentry = entry + 64;
7306
7307 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7308 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7309 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7310 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7311 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7312 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7313 (void) ath9k_hw_keysetmac(ah, entry, mac);
7314
7315 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7316 u32 mic0, mic1, mic2, mic3, mic4;
7317
7318 mic0 = get_unaligned_le32(k->kv_mic + 0);
7319 mic2 = get_unaligned_le32(k->kv_mic + 4);
7320 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7321 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7322 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7323 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7324 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7325 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7326 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7327 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7328 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7329 AR_KEYTABLE_TYPE_CLR);
7330
7331 } else {
7332 u32 mic0, mic2;
7333
7334 mic0 = get_unaligned_le32(k->kv_mic + 0);
7335 mic2 = get_unaligned_le32(k->kv_mic + 4);
7336 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7337 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7338 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7341 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7342 AR_KEYTABLE_TYPE_CLR);
7343 }
7344 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7345 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7346 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7347 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7348 } else {
7349 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7350 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7351 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7352 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7353 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7354 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7355
7356 (void) ath9k_hw_keysetmac(ah, entry, mac);
7357 }
7358
7359 if (ah->ah_curchan == NULL)
7360 return true;
7361
7362 return true;
7363}
7364
7365bool
7366ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7367{
7368 struct ath_hal_5416 *ahp = AH5416(ah);
7369 u32 txcfg, curLevel, newLevel;
7370 enum ath9k_int omask;
7371
7372 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7373 return false;
7374
7375 omask = ath9k_hw_set_interrupts(ah,
7376 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7377
7378 txcfg = REG_READ(ah, AR_TXCFG);
7379 curLevel = MS(txcfg, AR_FTRIG);
7380 newLevel = curLevel;
7381 if (bIncTrigLevel) {
7382 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7383 newLevel++;
7384 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7385 newLevel--;
7386 if (newLevel != curLevel)
7387 REG_WRITE(ah, AR_TXCFG,
7388 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7389
7390 ath9k_hw_set_interrupts(ah, omask);
7391
7392 ah->ah_txTrigLevel = newLevel;
7393
7394 return newLevel != curLevel;
7395}
7396
ea9880fb
S
7397bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7398 const struct ath9k_tx_queue_info *qinfo)
f078f209
LR
7399{
7400 u32 cw;
ea9880fb
S
7401 struct ath_hal_5416 *ahp = AH5416(ah);
7402 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7403 struct ath9k_tx_queue_info *qi;
f078f209 7404
ea9880fb
S
7405 if (q >= pCap->total_queues) {
7406 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7407 __func__, q);
7408 return false;
7409 }
7410
7411 qi = &ahp->ah_txq[q];
f078f209
LR
7412 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7413 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7414 __func__);
7415 return false;
7416 }
7417
7418 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7419
ea9880fb
S
7420 qi->tqi_ver = qinfo->tqi_ver;
7421 qi->tqi_subtype = qinfo->tqi_subtype;
7422 qi->tqi_qflags = qinfo->tqi_qflags;
7423 qi->tqi_priority = qinfo->tqi_priority;
7424 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7425 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
f078f209
LR
7426 else
7427 qi->tqi_aifs = INIT_AIFS;
ea9880fb
S
7428 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7429 cw = min(qinfo->tqi_cwmin, 1024U);
f078f209
LR
7430 qi->tqi_cwmin = 1;
7431 while (qi->tqi_cwmin < cw)
7432 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7433 } else
ea9880fb
S
7434 qi->tqi_cwmin = qinfo->tqi_cwmin;
7435 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7436 cw = min(qinfo->tqi_cwmax, 1024U);
f078f209
LR
7437 qi->tqi_cwmax = 1;
7438 while (qi->tqi_cwmax < cw)
7439 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7440 } else
7441 qi->tqi_cwmax = INIT_CWMAX;
7442
ea9880fb
S
7443 if (qinfo->tqi_shretry != 0)
7444 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
f078f209
LR
7445 else
7446 qi->tqi_shretry = INIT_SH_RETRY;
ea9880fb
S
7447 if (qinfo->tqi_lgretry != 0)
7448 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
f078f209
LR
7449 else
7450 qi->tqi_lgretry = INIT_LG_RETRY;
ea9880fb
S
7451 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7452 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7453 qi->tqi_burstTime = qinfo->tqi_burstTime;
7454 qi->tqi_readyTime = qinfo->tqi_readyTime;
f078f209 7455
ea9880fb 7456 switch (qinfo->tqi_subtype) {
f078f209
LR
7457 case ATH9K_WME_UPSD:
7458 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7459 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7460 break;
7461 default:
7462 break;
7463 }
7464 return true;
7465}
7466
ea9880fb
S
7467bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7468 struct ath9k_tx_queue_info *qinfo)
f078f209
LR
7469{
7470 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 7471 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
ea9880fb 7472 struct ath9k_tx_queue_info *qi;
f078f209 7473
60b67f51 7474 if (q >= pCap->total_queues) {
f078f209
LR
7475 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7476 __func__, q);
7477 return false;
7478 }
f078f209 7479
ea9880fb 7480 qi = &ahp->ah_txq[q];
f078f209
LR
7481 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7482 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7483 __func__);
7484 return false;
7485 }
7486
ea9880fb
S
7487 qinfo->tqi_qflags = qi->tqi_qflags;
7488 qinfo->tqi_ver = qi->tqi_ver;
7489 qinfo->tqi_subtype = qi->tqi_subtype;
7490 qinfo->tqi_qflags = qi->tqi_qflags;
7491 qinfo->tqi_priority = qi->tqi_priority;
7492 qinfo->tqi_aifs = qi->tqi_aifs;
7493 qinfo->tqi_cwmin = qi->tqi_cwmin;
7494 qinfo->tqi_cwmax = qi->tqi_cwmax;
7495 qinfo->tqi_shretry = qi->tqi_shretry;
7496 qinfo->tqi_lgretry = qi->tqi_lgretry;
7497 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7498 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7499 qinfo->tqi_burstTime = qi->tqi_burstTime;
7500 qinfo->tqi_readyTime = qi->tqi_readyTime;
f078f209
LR
7501
7502 return true;
7503}
7504
f078f209
LR
7505int
7506ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
ea9880fb 7507 const struct ath9k_tx_queue_info *qinfo)
f078f209
LR
7508{
7509 struct ath_hal_5416 *ahp = AH5416(ah);
7510 struct ath9k_tx_queue_info *qi;
60b67f51 7511 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7512 int q;
7513
7514 switch (type) {
7515 case ATH9K_TX_QUEUE_BEACON:
60b67f51 7516 q = pCap->total_queues - 1;
f078f209
LR
7517 break;
7518 case ATH9K_TX_QUEUE_CAB:
60b67f51 7519 q = pCap->total_queues - 2;
f078f209
LR
7520 break;
7521 case ATH9K_TX_QUEUE_PSPOLL:
7522 q = 1;
7523 break;
7524 case ATH9K_TX_QUEUE_UAPSD:
60b67f51 7525 q = pCap->total_queues - 3;
f078f209
LR
7526 break;
7527 case ATH9K_TX_QUEUE_DATA:
60b67f51 7528 for (q = 0; q < pCap->total_queues; q++)
f078f209
LR
7529 if (ahp->ah_txq[q].tqi_type ==
7530 ATH9K_TX_QUEUE_INACTIVE)
7531 break;
60b67f51 7532 if (q == pCap->total_queues) {
f078f209
LR
7533 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7534 "%s: no available tx queue\n", __func__);
7535 return -1;
7536 }
7537 break;
7538 default:
7539 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7540 __func__, type);
7541 return -1;
7542 }
7543
7544 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7545
7546 qi = &ahp->ah_txq[q];
7547 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7548 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7549 "%s: tx queue %u already active\n", __func__, q);
7550 return -1;
7551 }
7552 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7553 qi->tqi_type = type;
ea9880fb 7554 if (qinfo == NULL) {
f078f209
LR
7555 qi->tqi_qflags =
7556 TXQ_FLAG_TXOKINT_ENABLE
7557 | TXQ_FLAG_TXERRINT_ENABLE
7558 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7559 qi->tqi_aifs = INIT_AIFS;
7560 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7561 qi->tqi_cwmax = INIT_CWMAX;
7562 qi->tqi_shretry = INIT_SH_RETRY;
7563 qi->tqi_lgretry = INIT_LG_RETRY;
7564 qi->tqi_physCompBuf = 0;
7565 } else {
ea9880fb
S
7566 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7567 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
f078f209
LR
7568 }
7569
7570 return q;
7571}
7572
7573static void
7574ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7575 struct ath9k_tx_queue_info *qi)
7576{
7577 struct ath_hal_5416 *ahp = AH5416(ah);
7578
7579 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7580 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7581 __func__, ahp->ah_txOkInterruptMask,
7582 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7583 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7584
7585 REG_WRITE(ah, AR_IMR_S0,
7586 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7587 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7588 REG_WRITE(ah, AR_IMR_S1,
7589 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7590 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7591 REG_RMW_FIELD(ah, AR_IMR_S2,
7592 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7593}
7594
7595bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7596{
7597 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 7598 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7599 struct ath9k_tx_queue_info *qi;
7600
60b67f51 7601 if (q >= pCap->total_queues) {
f078f209
LR
7602 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7603 __func__, q);
7604 return false;
7605 }
7606 qi = &ahp->ah_txq[q];
7607 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7608 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7609 __func__, q);
7610 return false;
7611 }
7612
7613 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7614 __func__, q);
7615
7616 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7617 ahp->ah_txOkInterruptMask &= ~(1 << q);
7618 ahp->ah_txErrInterruptMask &= ~(1 << q);
7619 ahp->ah_txDescInterruptMask &= ~(1 << q);
7620 ahp->ah_txEolInterruptMask &= ~(1 << q);
7621 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7622 ath9k_hw_set_txq_interrupts(ah, qi);
7623
7624 return true;
7625}
7626
7627bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7628{
7629 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 7630 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7631 struct ath9k_channel *chan = ah->ah_curchan;
7632 struct ath9k_tx_queue_info *qi;
7633 u32 cwMin, chanCwMin, value;
7634
60b67f51 7635 if (q >= pCap->total_queues) {
f078f209
LR
7636 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7637 __func__, q);
7638 return false;
7639 }
7640 qi = &ahp->ah_txq[q];
7641 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7642 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7643 __func__, q);
7644 return true;
7645 }
7646
7647 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7648
7649 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7650 if (chan && IS_CHAN_B(chan))
7651 chanCwMin = INIT_CWMIN_11B;
7652 else
7653 chanCwMin = INIT_CWMIN;
7654
7655 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7656 } else
7657 cwMin = qi->tqi_cwmin;
7658
7659 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7660 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7661 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7662
7663 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7664 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7665 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7666 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7667 );
7668
7669 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7670 REG_WRITE(ah, AR_DMISC(q),
7671 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7672
7673 if (qi->tqi_cbrPeriod) {
7674 REG_WRITE(ah, AR_QCBRCFG(q),
7675 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7676 | SM(qi->tqi_cbrOverflowLimit,
7677 AR_Q_CBRCFG_OVF_THRESH));
7678 REG_WRITE(ah, AR_QMISC(q),
7679 REG_READ(ah,
7680 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7681 tqi_cbrOverflowLimit
7682 ?
7683 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7684 :
7685 0));
7686 }
7687 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7688 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7689 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7690 AR_Q_RDYTIMECFG_EN);
7691 }
7692
7693 REG_WRITE(ah, AR_DCHNTIME(q),
7694 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7695 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7696
7697 if (qi->tqi_burstTime
7698 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7699 REG_WRITE(ah, AR_QMISC(q),
7700 REG_READ(ah,
7701 AR_QMISC(q)) |
7702 AR_Q_MISC_RDYTIME_EXP_POLICY);
7703
7704 }
7705
7706 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7707 REG_WRITE(ah, AR_DMISC(q),
7708 REG_READ(ah, AR_DMISC(q)) |
7709 AR_D_MISC_POST_FR_BKOFF_DIS);
7710 }
7711 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7712 REG_WRITE(ah, AR_DMISC(q),
7713 REG_READ(ah, AR_DMISC(q)) |
7714 AR_D_MISC_FRAG_BKOFF_EN);
7715 }
7716 switch (qi->tqi_type) {
7717 case ATH9K_TX_QUEUE_BEACON:
7718 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7719 | AR_Q_MISC_FSP_DBA_GATED
7720 | AR_Q_MISC_BEACON_USE
7721 | AR_Q_MISC_CBR_INCR_DIS1);
7722
7723 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7724 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7725 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7726 | AR_D_MISC_BEACON_USE
7727 | AR_D_MISC_POST_FR_BKOFF_DIS);
7728 break;
7729 case ATH9K_TX_QUEUE_CAB:
7730 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7731 | AR_Q_MISC_FSP_DBA_GATED
7732 | AR_Q_MISC_CBR_INCR_DIS1
7733 | AR_Q_MISC_CBR_INCR_DIS0);
7734 value = (qi->tqi_readyTime
60b67f51
S
7735 - (ah->ah_config.sw_beacon_response_time -
7736 ah->ah_config.dma_beacon_response_time)
f078f209 7737 -
60b67f51 7738 ah->ah_config.additional_swba_backoff) *
f078f209
LR
7739 1024;
7740 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7741 value | AR_Q_RDYTIMECFG_EN);
7742 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7743 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7744 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7745 break;
7746 case ATH9K_TX_QUEUE_PSPOLL:
7747 REG_WRITE(ah, AR_QMISC(q),
7748 REG_READ(ah,
7749 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7750 break;
7751 case ATH9K_TX_QUEUE_UAPSD:
7752 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7753 | AR_D_MISC_POST_FR_BKOFF_DIS);
7754 break;
7755 default:
7756 break;
7757 }
7758
7759 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7760 REG_WRITE(ah, AR_DMISC(q),
7761 REG_READ(ah, AR_DMISC(q)) |
7762 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7763 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7764 AR_D_MISC_POST_FR_BKOFF_DIS);
7765 }
7766
7767 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7768 ahp->ah_txOkInterruptMask |= 1 << q;
7769 else
7770 ahp->ah_txOkInterruptMask &= ~(1 << q);
7771 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7772 ahp->ah_txErrInterruptMask |= 1 << q;
7773 else
7774 ahp->ah_txErrInterruptMask &= ~(1 << q);
7775 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7776 ahp->ah_txDescInterruptMask |= 1 << q;
7777 else
7778 ahp->ah_txDescInterruptMask &= ~(1 << q);
7779 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7780 ahp->ah_txEolInterruptMask |= 1 << q;
7781 else
7782 ahp->ah_txEolInterruptMask &= ~(1 << q);
7783 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7784 ahp->ah_txUrnInterruptMask |= 1 << q;
7785 else
7786 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7787 ath9k_hw_set_txq_interrupts(ah, qi);
7788
7789 return true;
7790}
7791
7792void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7793{
7794 struct ath_hal_5416 *ahp = AH5416(ah);
7795 *txqs &= ahp->ah_intrTxqs;
7796 ahp->ah_intrTxqs &= ~(*txqs);
7797}
7798
7799bool
7800ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7801 u32 segLen, bool firstSeg,
7802 bool lastSeg, const struct ath_desc *ds0)
7803{
7804 struct ar5416_desc *ads = AR5416DESC(ds);
7805
7806 if (firstSeg) {
7807 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7808 } else if (lastSeg) {
7809 ads->ds_ctl0 = 0;
7810 ads->ds_ctl1 = segLen;
7811 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7812 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7813 } else {
7814 ads->ds_ctl0 = 0;
7815 ads->ds_ctl1 = segLen | AR_TxMore;
7816 ads->ds_ctl2 = 0;
7817 ads->ds_ctl3 = 0;
7818 }
7819 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7820 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7821 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7822 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7823 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7824 return true;
7825}
7826
7827void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7828{
7829 struct ar5416_desc *ads = AR5416DESC(ds);
7830
7831 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7832 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7833 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7834 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7835 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7836}
7837
7838int
7839ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7840{
7841 struct ar5416_desc *ads = AR5416DESC(ds);
7842
7843 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7844 return -EINPROGRESS;
7845
7846 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7847 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7848 ds->ds_txstat.ts_status = 0;
7849 ds->ds_txstat.ts_flags = 0;
7850
7851 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7852 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7853 if (ads->ds_txstatus1 & AR_Filtered)
7854 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7855 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7856 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7857 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7858 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7859 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7860 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7861
7862 if (ads->ds_txstatus1 & AR_DescCfgErr)
7863 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7864 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7865 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7866 ath9k_hw_updatetxtriglevel(ah, true);
7867 }
7868 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7869 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7870 ath9k_hw_updatetxtriglevel(ah, true);
7871 }
7872 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7873 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7874 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7875 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7876 }
7877
7878 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7879 switch (ds->ds_txstat.ts_rateindex) {
7880 case 0:
7881 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7882 break;
7883 case 1:
7884 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7885 break;
7886 case 2:
7887 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7888 break;
7889 case 3:
7890 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7891 break;
7892 }
7893
7894 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7895 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7896 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7897 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7898 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7899 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7900 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7901 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7902 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7903 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7904 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7905 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7906 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7907 ds->ds_txstat.ts_antenna = 1;
7908
7909 return 0;
7910}
7911
7912void
7913ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7914 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7915 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7916{
7917 struct ar5416_desc *ads = AR5416DESC(ds);
7918 struct ath_hal_5416 *ahp = AH5416(ah);
7919
7920 txPower += ahp->ah_txPowerIndexOffset;
7921 if (txPower > 63)
7922 txPower = 63;
7923
7924 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7925 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7926 | SM(txPower, AR_XmitPower)
7927 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7928 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7929 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7930 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7931
7932 ads->ds_ctl1 =
7933 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7934 | SM(type, AR_FrameType)
7935 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7936 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7937 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7938
7939 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7940
7941 if (AR_SREV_9285(ah)) {
7942
7943 ads->ds_ctl8 = 0;
7944 ads->ds_ctl9 = 0;
7945 ads->ds_ctl10 = 0;
7946 ads->ds_ctl11 = 0;
7947 }
7948}
7949
7950void
7951ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7952 struct ath_desc *lastds,
7953 u32 durUpdateEn, u32 rtsctsRate,
7954 u32 rtsctsDuration,
7955 struct ath9k_11n_rate_series series[],
7956 u32 nseries, u32 flags)
7957{
7958 struct ar5416_desc *ads = AR5416DESC(ds);
7959 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7960 u32 ds_ctl0;
7961
7962 (void) nseries;
7963 (void) rtsctsDuration;
7964
7965 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7966 ds_ctl0 = ads->ds_ctl0;
7967
7968 if (flags & ATH9K_TXDESC_RTSENA) {
7969 ds_ctl0 &= ~AR_CTSEnable;
7970 ds_ctl0 |= AR_RTSEnable;
7971 } else {
7972 ds_ctl0 &= ~AR_RTSEnable;
7973 ds_ctl0 |= AR_CTSEnable;
7974 }
7975
7976 ads->ds_ctl0 = ds_ctl0;
7977 } else {
7978 ads->ds_ctl0 =
7979 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7980 }
7981
7982 ads->ds_ctl2 = set11nTries(series, 0)
7983 | set11nTries(series, 1)
7984 | set11nTries(series, 2)
7985 | set11nTries(series, 3)
7986 | (durUpdateEn ? AR_DurUpdateEna : 0)
7987 | SM(0, AR_BurstDur);
7988
7989 ads->ds_ctl3 = set11nRate(series, 0)
7990 | set11nRate(series, 1)
7991 | set11nRate(series, 2)
7992 | set11nRate(series, 3);
7993
7994 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
7995 | set11nPktDurRTSCTS(series, 1);
7996
7997 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
7998 | set11nPktDurRTSCTS(series, 3);
7999
8000 ads->ds_ctl7 = set11nRateFlags(series, 0)
8001 | set11nRateFlags(series, 1)
8002 | set11nRateFlags(series, 2)
8003 | set11nRateFlags(series, 3)
8004 | SM(rtsctsRate, AR_RTSCTSRate);
8005 last_ads->ds_ctl2 = ads->ds_ctl2;
8006 last_ads->ds_ctl3 = ads->ds_ctl3;
8007}
8008
8009void
8010ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8011 u32 aggrLen)
8012{
8013 struct ar5416_desc *ads = AR5416DESC(ds);
8014
8015 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8016
8017 ads->ds_ctl6 &= ~AR_AggrLen;
8018 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8019}
8020
8021void
8022ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8023 u32 numDelims)
8024{
8025 struct ar5416_desc *ads = AR5416DESC(ds);
8026 unsigned int ctl6;
8027
8028 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8029
8030 ctl6 = ads->ds_ctl6;
8031 ctl6 &= ~AR_PadDelim;
8032 ctl6 |= SM(numDelims, AR_PadDelim);
8033 ads->ds_ctl6 = ctl6;
8034}
8035
8036void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8037{
8038 struct ar5416_desc *ads = AR5416DESC(ds);
8039
8040 ads->ds_ctl1 |= AR_IsAggr;
8041 ads->ds_ctl1 &= ~AR_MoreAggr;
8042 ads->ds_ctl6 &= ~AR_PadDelim;
8043}
8044
8045void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8046{
8047 struct ar5416_desc *ads = AR5416DESC(ds);
8048
8049 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8050}
8051
8052void
8053ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8054 u32 burstDuration)
8055{
8056 struct ar5416_desc *ads = AR5416DESC(ds);
8057
8058 ads->ds_ctl2 &= ~AR_BurstDur;
8059 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8060}
8061
8062void
8063ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8064 u32 vmf)
8065{
8066 struct ar5416_desc *ads = AR5416DESC(ds);
8067
8068 if (vmf)
8069 ads->ds_ctl0 |= AR_VirtMoreFrag;
8070 else
8071 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8072}
8073
8074void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8075{
8076 REG_WRITE(ah, AR_RXDP, rxdp);
8077}
8078
8079void ath9k_hw_rxena(struct ath_hal *ah)
8080{
8081 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8082}
8083
8084bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8085{
8086 if (set) {
8087
8088 REG_SET_BIT(ah, AR_DIAG_SW,
8089 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8090
8091 if (!ath9k_hw_wait
8092 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8093 u32 reg;
8094
8095 REG_CLR_BIT(ah, AR_DIAG_SW,
8096 (AR_DIAG_RX_DIS |
8097 AR_DIAG_RX_ABORT));
8098
8099 reg = REG_READ(ah, AR_OBS_BUS_1);
8100 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8101 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8102 __func__, reg);
8103
8104 return false;
8105 }
8106 } else {
8107 REG_CLR_BIT(ah, AR_DIAG_SW,
8108 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8109 }
8110
8111 return true;
8112}
8113
8114void
8115ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8116 u32 filter1)
8117{
8118 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8119 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8120}
8121
8122bool
8123ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8124 u32 size, u32 flags)
8125{
8126 struct ar5416_desc *ads = AR5416DESC(ds);
60b67f51 8127 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
8128
8129 ads->ds_ctl1 = size & AR_BufLen;
8130 if (flags & ATH9K_RXDESC_INTREQ)
8131 ads->ds_ctl1 |= AR_RxIntrReq;
8132
8133 ads->ds_rxstatus8 &= ~AR_RxDone;
60b67f51 8134 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
f078f209
LR
8135 memset(&(ads->u), 0, sizeof(ads->u));
8136 return true;
8137}
8138
8139int
8140ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8141 u32 pa, struct ath_desc *nds, u64 tsf)
8142{
8143 struct ar5416_desc ads;
8144 struct ar5416_desc *adsp = AR5416DESC(ds);
8145
8146 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8147 return -EINPROGRESS;
8148
8149 ads.u.rx = adsp->u.rx;
8150
8151 ds->ds_rxstat.rs_status = 0;
8152 ds->ds_rxstat.rs_flags = 0;
8153
8154 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8155 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8156
8157 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8158 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8159 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8160 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8161 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8162 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8163 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8164 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8165 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8166 else
8167 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8168
8169 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8170 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8171
8172 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8173 ds->ds_rxstat.rs_moreaggr =
8174 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8175 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8176 ds->ds_rxstat.rs_flags =
8177 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8178 ds->ds_rxstat.rs_flags |=
8179 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8180
8181 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8182 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8183 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8184 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8185 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8186 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8187
8188 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8189
8190 if (ads.ds_rxstatus8 & AR_CRCErr)
8191 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8192 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8193 u32 phyerr;
8194
8195 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8196 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8197 ds->ds_rxstat.rs_phyerr = phyerr;
8198 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8199 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8200 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8201 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8202 }
8203
8204 return 0;
8205}
8206
8207static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8208 struct ath9k_rate_table *rt)
8209{
8210 int i;
8211
8212 if (rt->rateCodeToIndex[0] != 0)
8213 return;
8214 for (i = 0; i < 256; i++)
8215 rt->rateCodeToIndex[i] = (u8) -1;
8216 for (i = 0; i < rt->rateCount; i++) {
8217 u8 code = rt->info[i].rateCode;
8218 u8 cix = rt->info[i].controlRate;
8219
8220 rt->rateCodeToIndex[code] = i;
8221 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8222
8223 rt->info[i].lpAckDuration =
8224 ath9k_hw_computetxtime(ah, rt,
8225 WLAN_CTRL_FRAME_SIZE,
8226 cix,
8227 false);
8228 rt->info[i].spAckDuration =
8229 ath9k_hw_computetxtime(ah, rt,
8230 WLAN_CTRL_FRAME_SIZE,
8231 cix,
8232 true);
8233 }
8234}
8235
8236const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8237 u32 mode)
8238{
8239 struct ath9k_rate_table *rt;
8240 switch (mode) {
8241 case ATH9K_MODE_SEL_11A:
8242 rt = &ar5416_11a_table;
8243 break;
8244 case ATH9K_MODE_SEL_11B:
8245 rt = &ar5416_11b_table;
8246 break;
8247 case ATH9K_MODE_SEL_11G:
8248 rt = &ar5416_11g_table;
8249 break;
8250 case ATH9K_MODE_SEL_11NG_HT20:
8251 case ATH9K_MODE_SEL_11NG_HT40PLUS:
8252 case ATH9K_MODE_SEL_11NG_HT40MINUS:
8253 rt = &ar5416_11ng_table;
8254 break;
8255 case ATH9K_MODE_SEL_11NA_HT20:
8256 case ATH9K_MODE_SEL_11NA_HT40PLUS:
8257 case ATH9K_MODE_SEL_11NA_HT40MINUS:
8258 rt = &ar5416_11na_table;
8259 break;
8260 default:
8261 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8262 __func__, mode);
8263 return NULL;
8264 }
8265 ath9k_hw_setup_rate_table(ah, rt);
8266 return rt;
8267}
8268
8269static const char *ath9k_hw_devname(u16 devid)
8270{
8271 switch (devid) {
8272 case AR5416_DEVID_PCI:
8273 case AR5416_DEVID_PCIE:
8274 return "Atheros 5416";
8275 case AR9160_DEVID_PCI:
8276 return "Atheros 9160";
8277 case AR9280_DEVID_PCI:
8278 case AR9280_DEVID_PCIE:
8279 return "Atheros 9280";
8280 }
8281 return NULL;
8282}
8283
8284const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8285{
8286 return vendorid == ATHEROS_VENDOR_ID ?
8287 ath9k_hw_devname(devid) : NULL;
8288}
8289
8290struct ath_hal *ath9k_hw_attach(u16 devid,
8291 struct ath_softc *sc,
8292 void __iomem *mem,
8293 int *error)
8294{
8295 struct ath_hal *ah = NULL;
8296
8297 switch (devid) {
8298 case AR5416_DEVID_PCI:
8299 case AR5416_DEVID_PCIE:
8300 case AR9160_DEVID_PCI:
8301 case AR9280_DEVID_PCI:
8302 case AR9280_DEVID_PCIE:
8303 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8304 break;
8305 default:
8306 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8307 "devid=0x%x not supported.\n", devid);
8308 ah = NULL;
8309 *error = -ENXIO;
8310 break;
8311 }
8312 if (ah != NULL) {
8313 ah->ah_devid = ah->ah_devid;
8314 ah->ah_subvendorid = ah->ah_subvendorid;
8315 ah->ah_macVersion = ah->ah_macVersion;
8316 ah->ah_macRev = ah->ah_macRev;
8317 ah->ah_phyRev = ah->ah_phyRev;
8318 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8319 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8320 }
8321 return ah;
8322}
8323
8324u16
8325ath9k_hw_computetxtime(struct ath_hal *ah,
8326 const struct ath9k_rate_table *rates,
8327 u32 frameLen, u16 rateix,
8328 bool shortPreamble)
8329{
8330 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8331 u32 kbps;
8332
8333 kbps = rates->info[rateix].rateKbps;
8334
8335 if (kbps == 0)
8336 return 0;
8337 switch (rates->info[rateix].phy) {
8338
8339 case PHY_CCK:
8340 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8341 if (shortPreamble && rates->info[rateix].shortPreamble)
8342 phyTime >>= 1;
8343 numBits = frameLen << 3;
8344 txTime = CCK_SIFS_TIME + phyTime
8345 + ((numBits * 1000) / kbps);
8346 break;
8347 case PHY_OFDM:
8348 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8349 bitsPerSymbol =
8350 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8351
8352 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8353 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8354 txTime = OFDM_SIFS_TIME_QUARTER
8355 + OFDM_PREAMBLE_TIME_QUARTER
8356 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8357 } else if (ah->ah_curchan &&
8358 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8359 bitsPerSymbol =
8360 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8361
8362 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8363 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8364 txTime = OFDM_SIFS_TIME_HALF +
8365 OFDM_PREAMBLE_TIME_HALF
8366 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8367 } else {
8368 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8369
8370 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8371 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8372 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8373 + (numSymbols * OFDM_SYMBOL_TIME);
8374 }
8375 break;
8376
8377 default:
8378 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8379 "%s: unknown phy %u (rate ix %u)\n", __func__,
8380 rates->info[rateix].phy, rateix);
8381 txTime = 0;
8382 break;
8383 }
8384 return txTime;
8385}
8386
8387u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8388{
8389 if (flags & CHANNEL_2GHZ) {
8390 if (freq == 2484)
8391 return 14;
8392 if (freq < 2484)
8393 return (freq - 2407) / 5;
8394 else
8395 return 15 + ((freq - 2512) / 20);
8396 } else if (flags & CHANNEL_5GHZ) {
8397 if (ath9k_regd_is_public_safety_sku(ah) &&
8398 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8399 return ((freq * 10) +
8400 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8401 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8402 return (freq - 4000) / 5;
8403 } else {
8404 return (freq - 5000) / 5;
8405 }
8406 } else {
8407 if (freq == 2484)
8408 return 14;
8409 if (freq < 2484)
8410 return (freq - 2407) / 5;
8411 if (freq < 5000) {
8412 if (ath9k_regd_is_public_safety_sku(ah)
8413 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8414 return ((freq * 10) +
8415 (((freq % 5) ==
8416 2) ? 5 : 0) - 49400) / 5;
8417 } else if (freq > 4900) {
8418 return (freq - 4000) / 5;
8419 } else {
8420 return 15 + ((freq - 2512) / 20);
8421 }
8422 }
8423 return (freq - 5000) / 5;
8424 }
8425}
8426
8427int16_t
8428ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8429{
8430 struct ath9k_channel *ichan;
8431
8432 ichan = ath9k_regd_check_channel(ah, chan);
8433 if (ichan == NULL) {
8434 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8435 "%s: invalid channel %u/0x%x; no mapping\n",
8436 __func__, chan->channel, chan->channelFlags);
8437 return 0;
8438 }
8439 if (ichan->rawNoiseFloor == 0) {
8440 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8441 return NOISE_FLOOR[mode];
8442 } else
8443 return ichan->rawNoiseFloor;
8444}
8445
8446bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8447{
8448 struct ath_hal_5416 *ahp = AH5416(ah);
8449
8450 if (setting)
8451 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8452 else
8453 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8454 return true;
8455}
8456
8457bool ath9k_hw_phycounters(struct ath_hal *ah)
8458{
8459 struct ath_hal_5416 *ahp = AH5416(ah);
8460
8461 return ahp->ah_hasHwPhyCounters ? true : false;
8462}
8463
8464u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8465{
8466 return REG_READ(ah, AR_QTXDP(q));
8467}
8468
8469bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8470 u32 txdp)
8471{
8472 REG_WRITE(ah, AR_QTXDP(q), txdp);
8473
8474 return true;
8475}
8476
8477bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8478{
8479 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8480
8481 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8482
8483 return true;
8484}
8485
8486u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8487{
8488 u32 npend;
8489
8490 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8491 if (npend == 0) {
8492
8493 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8494 npend = 1;
8495 }
8496 return npend;
8497}
8498
8499bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8500{
8501 u32 wait;
8502
8503 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8504
8505 for (wait = 1000; wait != 0; wait--) {
8506 if (ath9k_hw_numtxpending(ah, q) == 0)
8507 break;
8508 udelay(100);
8509 }
8510
8511 if (ath9k_hw_numtxpending(ah, q)) {
8512 u32 tsfLow, j;
8513
8514 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8515 "%s: Num of pending TX Frames %d on Q %d\n",
8516 __func__, ath9k_hw_numtxpending(ah, q), q);
8517
8518 for (j = 0; j < 2; j++) {
8519 tsfLow = REG_READ(ah, AR_TSF_L32);
8520 REG_WRITE(ah, AR_QUIET2,
8521 SM(10, AR_QUIET2_QUIET_DUR));
8522 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8523 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8524 REG_SET_BIT(ah, AR_TIMER_MODE,
8525 AR_QUIET_TIMER_EN);
8526
8527 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8528 (tsfLow >> 10)) {
8529 break;
8530 }
8531 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8532 "%s: TSF have moved while trying to set "
8533 "quiet time TSF: 0x%08x\n",
8534 __func__, tsfLow);
8535 }
8536
8537 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8538
8539 udelay(200);
8540 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8541
8542 wait = 1000;
8543
8544 while (ath9k_hw_numtxpending(ah, q)) {
8545 if ((--wait) == 0) {
8546 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8547 "%s: Failed to stop Tx DMA in 100 "
8548 "msec after killing last frame\n",
8549 __func__);
8550 break;
8551 }
8552 udelay(100);
8553 }
8554
8555 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8556 }
8557
8558 REG_WRITE(ah, AR_Q_TXD, 0);
8559 return wait != 0;
8560}
This page took 0.348349 seconds and 5 git commands to generate.