ath9k: Remove a few unnecessary macros
[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))
86b89eed 228 return ATH9K_MODE_11A;
f078f209 229 if (IS_CHAN_G(chan))
86b89eed
S
230 return ATH9K_MODE_11G;
231 return ATH9K_MODE_11A;
f078f209
LR
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,
06df8bea 468 enum ieee80211_band freq_band)
f078f209
LR
469{
470 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471 struct modal_eep_header *pModal =
06df8bea 472 &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]);
f078f209
LR
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);
86b89eed 2419 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
f078f209
LR
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);
86b89eed 2465 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
f078f209
LR
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
f078f209 2973 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
86b89eed 2974 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
f078f209
LR
2975
2976 if (eeval & AR5416_OPFLAGS_11A) {
86b89eed
S
2977 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
2978 if (ah->ah_config.ht_enable) {
2979 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
2980 set_bit(ATH9K_MODE_11NA_HT20,
2981 pCap->wireless_modes);
2982 if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
2983 set_bit(ATH9K_MODE_11NA_HT40PLUS,
2984 pCap->wireless_modes);
2985 set_bit(ATH9K_MODE_11NA_HT40MINUS,
2986 pCap->wireless_modes);
2987 }
2988 }
f078f209 2989 }
f078f209 2990
86b89eed
S
2991 if (eeval & AR5416_OPFLAGS_11G) {
2992 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
2993 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
2994 if (ah->ah_config.ht_enable) {
2995 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
2996 set_bit(ATH9K_MODE_11NG_HT20,
2997 pCap->wireless_modes);
2998 if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
2999 set_bit(ATH9K_MODE_11NG_HT40PLUS,
3000 pCap->wireless_modes);
3001 set_bit(ATH9K_MODE_11NG_HT40MINUS,
3002 pCap->wireless_modes);
3003 }
3004 }
f078f209 3005 }
86b89eed 3006
60b67f51 3007 pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
f078f209
LR
3008 if ((ah->ah_isPciExpress)
3009 || (eeval & AR5416_OPFLAGS_11A)) {
60b67f51 3010 pCap->rx_chainmask =
f078f209
LR
3011 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3012 } else {
60b67f51 3013 pCap->rx_chainmask =
f078f209
LR
3014 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3015 }
3016
3017 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3018 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3019
60b67f51
S
3020 pCap->low_2ghz_chan = 2312;
3021 pCap->high_2ghz_chan = 2732;
f078f209 3022
60b67f51
S
3023 pCap->low_5ghz_chan = 4920;
3024 pCap->high_5ghz_chan = 6100;
f078f209 3025
60b67f51
S
3026 pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
3027 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
3028 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
f078f209 3029
60b67f51
S
3030 pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
3031 pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
3032 pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
f078f209 3033
60b67f51 3034 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
f078f209 3035
60b67f51
S
3036 if (ah->ah_config.ht_enable)
3037 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3038 else
3039 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
3040
3041 pCap->hw_caps |= ATH9K_HW_CAP_GTT;
3042 pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
3043 pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
3044 pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
f078f209
LR
3045
3046 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
60b67f51 3047 pCap->total_queues =
f078f209
LR
3048 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3049 else
60b67f51 3050 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
f078f209
LR
3051
3052 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
60b67f51 3053 pCap->keycache_size =
f078f209
LR
3054 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3055 else
60b67f51 3056 pCap->keycache_size = AR_KEYTABLE_SIZE;
f078f209 3057
60b67f51
S
3058 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3059 pCap->num_mr_retries = 4;
3060 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
f078f209
LR
3061
3062 if (AR_SREV_9280_10_OR_LATER(ah))
60b67f51 3063 pCap->num_gpio_pins = AR928X_NUM_GPIO;
f078f209 3064 else
60b67f51 3065 pCap->num_gpio_pins = AR_NUM_GPIO;
f078f209
LR
3066
3067 if (AR_SREV_9280_10_OR_LATER(ah)) {
60b67f51
S
3068 pCap->hw_caps |= ATH9K_HW_CAP_WOW;
3069 pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
f078f209 3070 } else {
60b67f51
S
3071 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
3072 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
f078f209
LR
3073 }
3074
3075 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
60b67f51
S
3076 pCap->hw_caps |= ATH9K_HW_CAP_CST;
3077 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
f078f209 3078 } else {
60b67f51 3079 pCap->rts_aggr_limit = (8 * 1024);
f078f209
LR
3080 }
3081
60b67f51 3082 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
f078f209
LR
3083
3084 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3085 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3086 ahp->ah_gpioSelect =
3087 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3088 ahp->ah_polarity =
3089 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3090
60b67f51 3091 ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true,
f078f209 3092 NULL);
60b67f51 3093 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
f078f209
LR
3094 }
3095
3096 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3097 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3098 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3099 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3100 (ah->ah_macVersion == AR_SREV_VERSION_9280))
60b67f51 3101 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
f078f209 3102 else
60b67f51 3103 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
f078f209
LR
3104
3105 if (AR_SREV_9280(ah))
60b67f51 3106 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
f078f209 3107 else
60b67f51 3108 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
f078f209
LR
3109
3110 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
60b67f51 3111 pCap->reg_cap =
f078f209
LR
3112 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3113 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3114 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3115 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3116 } else {
60b67f51 3117 pCap->reg_cap =
f078f209
LR
3118 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3119 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3120 }
3121
60b67f51 3122 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
f078f209 3123
60b67f51 3124 pCap->num_antcfg_5ghz =
06df8bea 3125 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_5GHZ);
60b67f51 3126 pCap->num_antcfg_2ghz =
06df8bea 3127 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_2GHZ);
f078f209
LR
3128
3129 return true;
3130}
3131
3132static void ar5416DisablePciePhy(struct ath_hal *ah)
3133{
3134 if (!AR_SREV_9100(ah))
3135 return;
3136
3137 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3138 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3139 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3140 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3141 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3142 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3143 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3144 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3145 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3146
3147 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3148}
3149
3150static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3151{
3152 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3153 if (setChip) {
3154 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3155 AR_RTC_FORCE_WAKE_EN);
3156 if (!AR_SREV_9100(ah))
3157 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3158
3159 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3160 AR_RTC_RESET_EN);
3161 }
3162}
3163
3164static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3165{
3166 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3167 if (setChip) {
60b67f51 3168 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209 3169
60b67f51 3170 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
f078f209
LR
3171 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3172 AR_RTC_FORCE_WAKE_ON_INT);
3173 } else {
3174 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3175 AR_RTC_FORCE_WAKE_EN);
3176 }
3177 }
3178}
3179
3180static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3181 int setChip)
3182{
3183 u32 val;
3184 int i;
3185
3186 if (setChip) {
3187 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3188 AR_RTC_STATUS_SHUTDOWN) {
3189 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3190 != true) {
3191 return false;
3192 }
3193 }
3194 if (AR_SREV_9100(ah))
3195 REG_SET_BIT(ah, AR_RTC_RESET,
3196 AR_RTC_RESET_EN);
3197
3198 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3199 AR_RTC_FORCE_WAKE_EN);
3200 udelay(50);
3201
3202 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3203 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3204 if (val == AR_RTC_STATUS_ON)
3205 break;
3206 udelay(50);
3207 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3208 AR_RTC_FORCE_WAKE_EN);
3209 }
3210 if (i == 0) {
3211 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3212 "%s: Failed to wakeup in %uus\n",
3213 __func__, POWER_UP_TIME / 20);
3214 return false;
3215 }
3216 }
3217
3218 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3219 return true;
3220}
3221
3222bool ath9k_hw_setpower(struct ath_hal *ah,
3223 enum ath9k_power_mode mode)
3224{
3225 struct ath_hal_5416 *ahp = AH5416(ah);
3226 static const char *modes[] = {
3227 "AWAKE",
3228 "FULL-SLEEP",
3229 "NETWORK SLEEP",
3230 "UNDEFINED"
3231 };
3232 int status = true, setChip = true;
3233
3234 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3235 modes[ahp->ah_powerMode], modes[mode],
3236 setChip ? "set chip " : "");
3237
3238 switch (mode) {
3239 case ATH9K_PM_AWAKE:
3240 status = ath9k_hw_set_power_awake(ah, setChip);
3241 break;
3242 case ATH9K_PM_FULL_SLEEP:
3243 ath9k_set_power_sleep(ah, setChip);
3244 ahp->ah_chipFullSleep = true;
3245 break;
3246 case ATH9K_PM_NETWORK_SLEEP:
3247 ath9k_set_power_network_sleep(ah, setChip);
3248 break;
3249 default:
3250 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3251 "%s: unknown power mode %u\n", __func__, mode);
3252 return false;
3253 }
3254 ahp->ah_powerMode = mode;
3255 return status;
3256}
3257
3258static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3259 struct ath_softc *sc,
3260 void __iomem *mem,
3261 int *status)
3262{
3263 struct ath_hal_5416 *ahp;
3264 struct ath_hal *ah;
3265 int ecode;
3266#ifndef CONFIG_SLOW_ANT_DIV
3267 u32 i;
3268 u32 j;
3269#endif
3270
3271 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3272 if (ahp == NULL)
3273 return NULL;
3274
3275 ah = &ahp->ah;
3276
3277 ath9k_hw_set_defaults(ah);
3278
60b67f51 3279 if (ah->ah_config.intr_mitigation != 0)
f078f209
LR
3280 ahp->ah_intrMitigation = true;
3281
3282 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3283 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3284 __func__);
3285 ecode = -EIO;
3286 goto bad;
3287 }
3288
3289 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3290 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3291 __func__);
3292 ecode = -EIO;
3293 goto bad;
3294 }
3295
60b67f51 3296 if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
f078f209 3297 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
60b67f51 3298 ah->ah_config.serialize_regmode =
f078f209
LR
3299 SER_REG_MODE_ON;
3300 } else {
60b67f51 3301 ah->ah_config.serialize_regmode =
f078f209
LR
3302 SER_REG_MODE_OFF;
3303 }
3304 }
3305 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
60b67f51
S
3306 "%s: serialize_regmode is %d\n",
3307 __func__, ah->ah_config.serialize_regmode);
f078f209
LR
3308
3309 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3310 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3311 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3312 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3313 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3314 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3315 "this driver\n", __func__,
3316 ah->ah_macVersion, ah->ah_macRev);
3317 ecode = -EOPNOTSUPP;
3318 goto bad;
3319 }
3320
3321 if (AR_SREV_9100(ah)) {
3322 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3323 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3324 ah->ah_isPciExpress = false;
3325 }
3326 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3327
3328 if (AR_SREV_9160_10_OR_LATER(ah)) {
3329 if (AR_SREV_9280_10_OR_LATER(ah)) {
3330 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3331 ahp->ah_adcGainCalData.calData =
3332 &adc_gain_cal_single_sample;
3333 ahp->ah_adcDcCalData.calData =
3334 &adc_dc_cal_single_sample;
3335 ahp->ah_adcDcCalInitData.calData =
3336 &adc_init_dc_cal;
3337 } else {
3338 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3339 ahp->ah_adcGainCalData.calData =
3340 &adc_gain_cal_multi_sample;
3341 ahp->ah_adcDcCalData.calData =
3342 &adc_dc_cal_multi_sample;
3343 ahp->ah_adcDcCalInitData.calData =
3344 &adc_init_dc_cal;
3345 }
3346 ahp->ah_suppCals =
3347 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3348 }
3349
3350 if (AR_SREV_9160(ah)) {
60b67f51 3351 ah->ah_config.enable_ani = 1;
f078f209
LR
3352 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3353 ATH9K_ANI_FIRSTEP_LEVEL);
3354 } else {
3355 ahp->ah_ani_function = ATH9K_ANI_ALL;
3356 if (AR_SREV_9280_10_OR_LATER(ah)) {
3357 ahp->ah_ani_function &=
3358 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3359 }
3360 }
3361
3362 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3363 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3364 ah->ah_macVersion, ah->ah_macRev);
3365
3366 if (AR_SREV_9280_20_OR_LATER(ah)) {
3367 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3368 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3369 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3370 ARRAY_SIZE(ar9280Common_9280_2), 2);
3371
60b67f51 3372 if (ah->ah_config.pcie_clock_req) {
f078f209
LR
3373 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3374 ar9280PciePhy_clkreq_off_L1_9280,
3375 ARRAY_SIZE
3376 (ar9280PciePhy_clkreq_off_L1_9280),
3377 2);
3378 } else {
3379 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3380 ar9280PciePhy_clkreq_always_on_L1_9280,
3381 ARRAY_SIZE
3382 (ar9280PciePhy_clkreq_always_on_L1_9280),
3383 2);
3384 }
3385 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3386 ar9280Modes_fast_clock_9280_2,
3387 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3388 3);
3389 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3390 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3391 ARRAY_SIZE(ar9280Modes_9280), 6);
3392 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3393 ARRAY_SIZE(ar9280Common_9280), 2);
3394 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3395 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3396 ARRAY_SIZE(ar5416Modes_9160), 6);
3397 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3398 ARRAY_SIZE(ar5416Common_9160), 2);
3399 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3400 ARRAY_SIZE(ar5416Bank0_9160), 2);
3401 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3402 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3403 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3404 ARRAY_SIZE(ar5416Bank1_9160), 2);
3405 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3406 ARRAY_SIZE(ar5416Bank2_9160), 2);
3407 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3408 ARRAY_SIZE(ar5416Bank3_9160), 3);
3409 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3410 ARRAY_SIZE(ar5416Bank6_9160), 3);
3411 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3412 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3413 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3414 ARRAY_SIZE(ar5416Bank7_9160), 2);
3415 if (AR_SREV_9160_11(ah)) {
3416 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3417 ar5416Addac_91601_1,
3418 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3419 } else {
3420 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3421 ARRAY_SIZE(ar5416Addac_9160), 2);
3422 }
3423 } else if (AR_SREV_9100_OR_LATER(ah)) {
3424 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3425 ARRAY_SIZE(ar5416Modes_9100), 6);
3426 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3427 ARRAY_SIZE(ar5416Common_9100), 2);
3428 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3429 ARRAY_SIZE(ar5416Bank0_9100), 2);
3430 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3431 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3432 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3433 ARRAY_SIZE(ar5416Bank1_9100), 2);
3434 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3435 ARRAY_SIZE(ar5416Bank2_9100), 2);
3436 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3437 ARRAY_SIZE(ar5416Bank3_9100), 3);
3438 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3439 ARRAY_SIZE(ar5416Bank6_9100), 3);
3440 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3441 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3442 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3443 ARRAY_SIZE(ar5416Bank7_9100), 2);
3444 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3445 ARRAY_SIZE(ar5416Addac_9100), 2);
3446 } else {
3447 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3448 ARRAY_SIZE(ar5416Modes), 6);
3449 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3450 ARRAY_SIZE(ar5416Common), 2);
3451 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3452 ARRAY_SIZE(ar5416Bank0), 2);
3453 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3454 ARRAY_SIZE(ar5416BB_RfGain), 3);
3455 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3456 ARRAY_SIZE(ar5416Bank1), 2);
3457 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3458 ARRAY_SIZE(ar5416Bank2), 2);
3459 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3460 ARRAY_SIZE(ar5416Bank3), 3);
3461 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3462 ARRAY_SIZE(ar5416Bank6), 3);
3463 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3464 ARRAY_SIZE(ar5416Bank6TPC), 3);
3465 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3466 ARRAY_SIZE(ar5416Bank7), 2);
3467 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3468 ARRAY_SIZE(ar5416Addac), 2);
3469 }
3470
3471 if (ah->ah_isPciExpress)
3472 ath9k_hw_configpcipowersave(ah, 0);
3473 else
3474 ar5416DisablePciePhy(ah);
3475
3476 ecode = ath9k_hw_post_attach(ah);
3477 if (ecode != 0)
3478 goto bad;
3479
3480#ifndef CONFIG_SLOW_ANT_DIV
3481 if (ah->ah_devid == AR9280_DEVID_PCI) {
3482 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3483 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3484
3485 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3486 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3487
3488 INI_RA(&ahp->ah_iniModes, i, j) =
3489 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3490 reg, val);
3491 }
3492 }
3493 }
3494#endif
3495
3496 if (!ath9k_hw_fill_cap_info(ah)) {
3497 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3498 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3499 ecode = -EINVAL;
3500 goto bad;
3501 }
3502
3503 ecode = ath9k_hw_init_macaddr(ah);
3504 if (ecode != 0) {
3505 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3506 "%s: failed initializing mac address\n",
3507 __func__);
3508 goto bad;
3509 }
3510
3511 if (AR_SREV_9285(ah))
3512 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3513 else
3514 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3515
3516#ifndef ATH_NF_PER_CHAN
3517
3518 ath9k_init_nfcal_hist_buffer(ah);
3519#endif
3520
3521 return ah;
3522
3523bad:
3524 if (ahp)
3525 ath9k_hw_detach((struct ath_hal *) ahp);
3526 if (status)
3527 *status = ecode;
3528 return NULL;
3529}
3530
3531void ath9k_hw_detach(struct ath_hal *ah)
3532{
3533 if (!AR_SREV_9100(ah))
3534 ath9k_hw_ani_detach(ah);
3535 ath9k_hw_rfdetach(ah);
3536
3537 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3538 kfree(ah);
3539}
3540
3541bool ath9k_get_channel_edges(struct ath_hal *ah,
3542 u16 flags, u16 *low,
3543 u16 *high)
3544{
60b67f51 3545 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
3546
3547 if (flags & CHANNEL_5GHZ) {
60b67f51
S
3548 *low = pCap->low_5ghz_chan;
3549 *high = pCap->high_5ghz_chan;
f078f209
LR
3550 return true;
3551 }
3552 if ((flags & CHANNEL_2GHZ)) {
60b67f51
S
3553 *low = pCap->low_2ghz_chan;
3554 *high = pCap->high_2ghz_chan;
f078f209
LR
3555
3556 return true;
3557 }
3558 return false;
3559}
3560
3561static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3562 u8 pwrMax,
3563 u8 *pPwrList,
3564 u8 *pVpdList,
3565 u16
3566 numIntercepts,
3567 u8 *pRetVpdList)
3568{
3569 u16 i, k;
3570 u8 currPwr = pwrMin;
3571 u16 idxL = 0, idxR = 0;
3572
3573 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3574 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3575 numIntercepts, &(idxL),
3576 &(idxR));
3577 if (idxR < 1)
3578 idxR = 1;
3579 if (idxL == numIntercepts - 1)
3580 idxL = (u16) (numIntercepts - 2);
3581 if (pPwrList[idxL] == pPwrList[idxR])
3582 k = pVpdList[idxL];
3583 else
3584 k = (u16) (((currPwr -
3585 pPwrList[idxL]) *
3586 pVpdList[idxR] +
3587 (pPwrList[idxR] -
3588 currPwr) * pVpdList[idxL]) /
3589 (pPwrList[idxR] -
3590 pPwrList[idxL]));
3591 pRetVpdList[i] = (u8) k;
3592 currPwr += 2;
3593 }
3594
3595 return true;
3596}
3597
3598static inline void
3599ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3600 struct ath9k_channel *chan,
3601 struct cal_data_per_freq *pRawDataSet,
3602 u8 *bChans,
3603 u16 availPiers,
3604 u16 tPdGainOverlap,
3605 int16_t *pMinCalPower,
3606 u16 *pPdGainBoundaries,
3607 u8 *pPDADCValues,
3608 u16 numXpdGains)
3609{
3610 int i, j, k;
3611 int16_t ss;
3612 u16 idxL = 0, idxR = 0, numPiers;
3613 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3614 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3615 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3616 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3617 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3618 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3619
3620 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3621 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3622 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3623 int16_t vpdStep;
3624 int16_t tmpVal;
3625 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3626 bool match;
3627 int16_t minDelta = 0;
3628 struct chan_centers centers;
3629
3630 ath9k_hw_get_channel_centers(ah, chan, &centers);
3631
3632 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3633 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3634 break;
3635 }
3636
3637 match = ath9k_hw_get_lower_upper_index((u8)
3638 FREQ2FBIN(centers.
3639 synth_center,
3640 IS_CHAN_2GHZ
3641 (chan)), bChans,
3642 numPiers, &idxL, &idxR);
3643
3644 if (match) {
3645 for (i = 0; i < numXpdGains; i++) {
3646 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3647 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3648 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3649 pRawDataSet[idxL].
3650 pwrPdg[i],
3651 pRawDataSet[idxL].
3652 vpdPdg[i],
3653 AR5416_PD_GAIN_ICEPTS,
3654 vpdTableI[i]);
3655 }
3656 } else {
3657 for (i = 0; i < numXpdGains; i++) {
3658 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3659 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3660 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3661 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3662
3663 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3664
3665 maxPwrT4[i] =
3666 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3667 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3668
3669
3670 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3671 pPwrL, pVpdL,
3672 AR5416_PD_GAIN_ICEPTS,
3673 vpdTableL[i]);
3674 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3675 pPwrR, pVpdR,
3676 AR5416_PD_GAIN_ICEPTS,
3677 vpdTableR[i]);
3678
3679 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3680 vpdTableI[i][j] =
3681 (u8) (ath9k_hw_interpolate
3682 ((u16)
3683 FREQ2FBIN(centers.
3684 synth_center,
3685 IS_CHAN_2GHZ
3686 (chan)),
3687 bChans[idxL],
3688 bChans[idxR], vpdTableL[i]
3689 [j], vpdTableR[i]
3690 [j]));
3691 }
3692 }
3693 }
3694
3695 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3696
3697 k = 0;
3698 for (i = 0; i < numXpdGains; i++) {
3699 if (i == (numXpdGains - 1))
3700 pPdGainBoundaries[i] =
3701 (u16) (maxPwrT4[i] / 2);
3702 else
3703 pPdGainBoundaries[i] =
3704 (u16) ((maxPwrT4[i] +
3705 minPwrT4[i + 1]) / 4);
3706
3707 pPdGainBoundaries[i] =
3708 min((u16) AR5416_MAX_RATE_POWER,
3709 pPdGainBoundaries[i]);
3710
3711 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3712 minDelta = pPdGainBoundaries[0] - 23;
3713 pPdGainBoundaries[0] = 23;
3714 } else {
3715 minDelta = 0;
3716 }
3717
3718 if (i == 0) {
3719 if (AR_SREV_9280_10_OR_LATER(ah))
3720 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3721 else
3722 ss = 0;
3723 } else {
3724 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3725 (minPwrT4[i] / 2)) -
3726 tPdGainOverlap + 1 + minDelta);
3727 }
3728 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3729 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3730
3731 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3732 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3733 pPDADCValues[k++] =
3734 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3735 ss++;
3736 }
3737
3738 sizeCurrVpdTable =
3739 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3740 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3741 (minPwrT4[i] / 2));
3742 maxIndex = (tgtIndex <
3743 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3744
3745 while ((ss < maxIndex)
3746 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3747 pPDADCValues[k++] = vpdTableI[i][ss++];
3748 }
3749
3750 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3751 vpdTableI[i][sizeCurrVpdTable - 2]);
3752 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3753
3754 if (tgtIndex > maxIndex) {
3755 while ((ss <= tgtIndex)
3756 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3757 tmpVal = (int16_t) ((vpdTableI[i]
3758 [sizeCurrVpdTable -
3759 1] + (ss - maxIndex +
3760 1) * vpdStep));
3761 pPDADCValues[k++] = (u8) ((tmpVal >
3762 255) ? 255 : tmpVal);
3763 ss++;
3764 }
3765 }
3766 }
3767
3768 while (i < AR5416_PD_GAINS_IN_MASK) {
3769 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3770 i++;
3771 }
3772
3773 while (k < AR5416_NUM_PDADC_VALUES) {
3774 pPDADCValues[k] = pPDADCValues[k - 1];
3775 k++;
3776 }
3777 return;
3778}
3779
3780static inline bool
3781ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3782 struct ar5416_eeprom *pEepData,
3783 struct ath9k_channel *chan,
3784 int16_t *pTxPowerIndexOffset)
3785{
3786 struct cal_data_per_freq *pRawDataset;
3787 u8 *pCalBChans = NULL;
3788 u16 pdGainOverlap_t2;
3789 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3790 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3791 u16 numPiers, i, j;
3792 int16_t tMinCalPower;
3793 u16 numXpdGain, xpdMask;
3794 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3795 u32 reg32, regOffset, regChainOffset;
3796 int16_t modalIdx;
3797 struct ath_hal_5416 *ahp = AH5416(ah);
3798
3799 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3800 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3801
3802 if ((pEepData->baseEepHeader.
3803 version & AR5416_EEP_VER_MINOR_MASK) >=
3804 AR5416_EEP_MINOR_VER_2) {
3805 pdGainOverlap_t2 =
3806 pEepData->modalHeader[modalIdx].pdGainOverlap;
3807 } else {
3808 pdGainOverlap_t2 =
3809 (u16) (MS
3810 (REG_READ(ah, AR_PHY_TPCRG5),
3811 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3812 }
3813
3814 if (IS_CHAN_2GHZ(chan)) {
3815 pCalBChans = pEepData->calFreqPier2G;
3816 numPiers = AR5416_NUM_2G_CAL_PIERS;
3817 } else {
3818 pCalBChans = pEepData->calFreqPier5G;
3819 numPiers = AR5416_NUM_5G_CAL_PIERS;
3820 }
3821
3822 numXpdGain = 0;
3823
3824 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3825 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3826 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3827 break;
3828 xpdGainValues[numXpdGain] =
3829 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3830 numXpdGain++;
3831 }
3832 }
3833
3834 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3835 (numXpdGain - 1) & 0x3);
3836 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3837 xpdGainValues[0]);
3838 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3839 xpdGainValues[1]);
3840 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3841 xpdGainValues[2]);
3842
3843 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3844 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3845 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3846 && (i != 0)) {
3847 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3848 } else
3849 regChainOffset = i * 0x1000;
3850 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3851 if (IS_CHAN_2GHZ(chan))
3852 pRawDataset = pEepData->calPierData2G[i];
3853 else
3854 pRawDataset = pEepData->calPierData5G[i];
3855
3856 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3857 pRawDataset,
3858 pCalBChans,
3859 numPiers,
3860 pdGainOverlap_t2,
3861 &tMinCalPower,
3862 gainBoundaries,
3863 pdadcValues,
3864 numXpdGain);
3865
3866 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3867
3868 REG_WRITE(ah,
3869 AR_PHY_TPCRG5 + regChainOffset,
3870 SM(pdGainOverlap_t2,
3871 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3872 | SM(gainBoundaries[0],
3873 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3874 | SM(gainBoundaries[1],
3875 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3876 | SM(gainBoundaries[2],
3877 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3878 | SM(gainBoundaries[3],
3879 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3880 }
3881
3882 regOffset =
3883 AR_PHY_BASE + (672 << 2) + regChainOffset;
3884 for (j = 0; j < 32; j++) {
3885 reg32 =
3886 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3887 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3888 8) | ((pdadcValues[4 * j + 2] &
3889 0xFF) << 16) |
3890 ((pdadcValues[4 * j + 3] & 0xFF) <<
3891 24);
3892 REG_WRITE(ah, regOffset, reg32);
3893
3894 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3895 "PDADC (%d,%4x): %4.4x %8.8x\n",
3896 i, regChainOffset, regOffset,
3897 reg32);
3898 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3899 "PDADC: Chain %d | PDADC %3d Value %3d | "
3900 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3901 "PDADC %3d Value %3d |\n",
3902 i, 4 * j, pdadcValues[4 * j],
3903 4 * j + 1, pdadcValues[4 * j + 1],
3904 4 * j + 2, pdadcValues[4 * j + 2],
3905 4 * j + 3,
3906 pdadcValues[4 * j + 3]);
3907
3908 regOffset += 4;
3909 }
3910 }
3911 }
3912 *pTxPowerIndexOffset = 0;
3913
3914 return true;
3915}
3916
3917void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3918{
3919 struct ath_hal_5416 *ahp = AH5416(ah);
3920 u8 i;
3921
3922 if (ah->ah_isPciExpress != true)
3923 return;
3924
60b67f51 3925 if (ah->ah_config.pcie_powersave_enable == 2)
f078f209
LR
3926 return;
3927
3928 if (restore)
3929 return;
3930
3931 if (AR_SREV_9280_20_OR_LATER(ah)) {
3932 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3933 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3934 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3935 }
3936 udelay(1000);
3937 } else if (AR_SREV_9280(ah)
3938 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3939 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3940 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3941
3942 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3943 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3944 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3945
60b67f51 3946 if (ah->ah_config.pcie_clock_req)
f078f209
LR
3947 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3948 else
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3950
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3954
3955 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3956
3957 udelay(1000);
3958 } else {
3959 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3960 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3961 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3962 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3963 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3964 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3965 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3966 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3967 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3968 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3969 }
3970
3971 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3972
60b67f51
S
3973 if (ah->ah_config.pcie_waen) {
3974 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
f078f209
LR
3975 } else {
3976 if (AR_SREV_9280(ah))
3977 REG_WRITE(ah, AR_WA, 0x0040073f);
3978 else
3979 REG_WRITE(ah, AR_WA, 0x0000073f);
3980 }
3981}
3982
3983static inline void
3984ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3985 struct ath9k_channel *chan,
3986 struct cal_target_power_leg *powInfo,
3987 u16 numChannels,
3988 struct cal_target_power_leg *pNewPower,
3989 u16 numRates,
3990 bool isExtTarget)
3991{
3992 u16 clo, chi;
3993 int i;
3994 int matchIndex = -1, lowIndex = -1;
3995 u16 freq;
3996 struct chan_centers centers;
3997
3998 ath9k_hw_get_channel_centers(ah, chan, &centers);
3999 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
4000
4001 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
4002 IS_CHAN_2GHZ(chan))) {
4003 matchIndex = 0;
4004 } else {
4005 for (i = 0; (i < numChannels)
4006 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4007 if (freq ==
4008 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4009 IS_CHAN_2GHZ(chan))) {
4010 matchIndex = i;
4011 break;
4012 } else if ((freq <
4013 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4014 IS_CHAN_2GHZ(chan)))
4015 && (freq >
4016 ath9k_hw_fbin2freq(powInfo[i - 1].
4017 bChannel,
4018 IS_CHAN_2GHZ
4019 (chan)))) {
4020 lowIndex = i - 1;
4021 break;
4022 }
4023 }
4024 if ((matchIndex == -1) && (lowIndex == -1))
4025 matchIndex = i - 1;
4026 }
4027
4028 if (matchIndex != -1) {
4029 *pNewPower = powInfo[matchIndex];
4030 } else {
4031 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4032 IS_CHAN_2GHZ(chan));
4033 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4034 IS_CHAN_2GHZ(chan));
4035
4036 for (i = 0; i < numRates; i++) {
4037 pNewPower->tPow2x[i] =
4038 (u8) ath9k_hw_interpolate(freq, clo, chi,
4039 powInfo
4040 [lowIndex].
4041 tPow2x[i],
4042 powInfo
4043 [lowIndex +
4044 1].tPow2x[i]);
4045 }
4046 }
4047}
4048
4049static inline void
4050ath9k_hw_get_target_powers(struct ath_hal *ah,
4051 struct ath9k_channel *chan,
4052 struct cal_target_power_ht *powInfo,
4053 u16 numChannels,
4054 struct cal_target_power_ht *pNewPower,
4055 u16 numRates,
4056 bool isHt40Target)
4057{
4058 u16 clo, chi;
4059 int i;
4060 int matchIndex = -1, lowIndex = -1;
4061 u16 freq;
4062 struct chan_centers centers;
4063
4064 ath9k_hw_get_channel_centers(ah, chan, &centers);
4065 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4066
4067 if (freq <=
4068 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4069 matchIndex = 0;
4070 } else {
4071 for (i = 0; (i < numChannels)
4072 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4073 if (freq ==
4074 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4075 IS_CHAN_2GHZ(chan))) {
4076 matchIndex = i;
4077 break;
4078 } else
4079 if ((freq <
4080 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4081 IS_CHAN_2GHZ(chan)))
4082 && (freq >
4083 ath9k_hw_fbin2freq(powInfo[i - 1].
4084 bChannel,
4085 IS_CHAN_2GHZ
4086 (chan)))) {
4087 lowIndex = i - 1;
4088 break;
4089 }
4090 }
4091 if ((matchIndex == -1) && (lowIndex == -1))
4092 matchIndex = i - 1;
4093 }
4094
4095 if (matchIndex != -1) {
4096 *pNewPower = powInfo[matchIndex];
4097 } else {
4098 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4099 IS_CHAN_2GHZ(chan));
4100 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4101 IS_CHAN_2GHZ(chan));
4102
4103 for (i = 0; i < numRates; i++) {
4104 pNewPower->tPow2x[i] =
4105 (u8) ath9k_hw_interpolate(freq, clo, chi,
4106 powInfo
4107 [lowIndex].
4108 tPow2x[i],
4109 powInfo
4110 [lowIndex +
4111 1].tPow2x[i]);
4112 }
4113 }
4114}
4115
4116static inline u16
4117ath9k_hw_get_max_edge_power(u16 freq,
4118 struct cal_ctl_edges *pRdEdgesPower,
4119 bool is2GHz)
4120{
4121 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4122 int i;
4123
4124 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4125 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4126 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4127 is2GHz)) {
4128 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4129 break;
4130 } else if ((i > 0)
4131 && (freq <
4132 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4133 bChannel, is2GHz))) {
4134 if (ath9k_hw_fbin2freq
4135 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4136 && pRdEdgesPower[i - 1].flag) {
4137 twiceMaxEdgePower =
4138 pRdEdgesPower[i - 1].tPower;
4139 }
4140 break;
4141 }
4142 }
4143 return twiceMaxEdgePower;
4144}
4145
4146static inline bool
4147ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4148 struct ar5416_eeprom *pEepData,
4149 struct ath9k_channel *chan,
4150 int16_t *ratesArray,
4151 u16 cfgCtl,
4152 u8 AntennaReduction,
4153 u8 twiceMaxRegulatoryPower,
4154 u8 powerLimit)
4155{
4156 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4157 static const u16 tpScaleReductionTable[5] =
4158 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4159
4160 int i;
4161 int8_t twiceLargestAntenna;
4162 struct cal_ctl_data *rep;
4163 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4164 0, { 0, 0, 0, 0}
4165 };
4166 struct cal_target_power_leg targetPowerOfdmExt = {
4167 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4168 0, { 0, 0, 0, 0 }
4169 };
4170 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4171 0, {0, 0, 0, 0}
4172 };
4173 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4174 u16 ctlModesFor11a[] =
4175 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4176 u16 ctlModesFor11g[] =
4177 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4178 CTL_2GHT40
4179 };
4180 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4181 struct chan_centers centers;
4182 int tx_chainmask;
4183 u8 twiceMinEdgePower;
4184 struct ath_hal_5416 *ahp = AH5416(ah);
4185
4186 tx_chainmask = ahp->ah_txchainmask;
4187
4188 ath9k_hw_get_channel_centers(ah, chan, &centers);
4189
4190 twiceLargestAntenna = max(
4191 pEepData->modalHeader
4192 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4193 pEepData->modalHeader
4194 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4195
4196 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4197 pEepData->modalHeader
4198 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4199
4200 twiceLargestAntenna =
4201 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4202
4203 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4204
4205 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4206 maxRegAllowedPower -=
4207 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4208 }
4209
4210 scaledPower = min(powerLimit, maxRegAllowedPower);
4211
4212 switch (ar5416_get_ntxchains(tx_chainmask)) {
4213 case 1:
4214 break;
4215 case 2:
4216 scaledPower -=
4217 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4218 pwrDecreaseFor2Chain;
4219 break;
4220 case 3:
4221 scaledPower -=
4222 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4223 pwrDecreaseFor3Chain;
4224 break;
4225 }
4226
4227 scaledPower = max(0, (int32_t) scaledPower);
4228
4229 if (IS_CHAN_2GHZ(chan)) {
4230 numCtlModes =
4231 ARRAY_SIZE(ctlModesFor11g) -
4232 SUB_NUM_CTL_MODES_AT_2G_40;
4233 pCtlMode = ctlModesFor11g;
4234
4235 ath9k_hw_get_legacy_target_powers(ah, chan,
4236 pEepData->
4237 calTargetPowerCck,
4238 AR5416_NUM_2G_CCK_TARGET_POWERS,
4239 &targetPowerCck, 4,
4240 false);
4241 ath9k_hw_get_legacy_target_powers(ah, chan,
4242 pEepData->
4243 calTargetPower2G,
4244 AR5416_NUM_2G_20_TARGET_POWERS,
4245 &targetPowerOfdm, 4,
4246 false);
4247 ath9k_hw_get_target_powers(ah, chan,
4248 pEepData->calTargetPower2GHT20,
4249 AR5416_NUM_2G_20_TARGET_POWERS,
4250 &targetPowerHt20, 8, false);
4251
4252 if (IS_CHAN_HT40(chan)) {
4253 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4254 ath9k_hw_get_target_powers(ah, chan,
4255 pEepData->
4256 calTargetPower2GHT40,
4257 AR5416_NUM_2G_40_TARGET_POWERS,
4258 &targetPowerHt40, 8,
4259 true);
4260 ath9k_hw_get_legacy_target_powers(ah, chan,
4261 pEepData->
4262 calTargetPowerCck,
4263 AR5416_NUM_2G_CCK_TARGET_POWERS,
4264 &targetPowerCckExt,
4265 4, true);
4266 ath9k_hw_get_legacy_target_powers(ah, chan,
4267 pEepData->
4268 calTargetPower2G,
4269 AR5416_NUM_2G_20_TARGET_POWERS,
4270 &targetPowerOfdmExt,
4271 4, true);
4272 }
4273 } else {
4274
4275 numCtlModes =
4276 ARRAY_SIZE(ctlModesFor11a) -
4277 SUB_NUM_CTL_MODES_AT_5G_40;
4278 pCtlMode = ctlModesFor11a;
4279
4280 ath9k_hw_get_legacy_target_powers(ah, chan,
4281 pEepData->
4282 calTargetPower5G,
4283 AR5416_NUM_5G_20_TARGET_POWERS,
4284 &targetPowerOfdm, 4,
4285 false);
4286 ath9k_hw_get_target_powers(ah, chan,
4287 pEepData->calTargetPower5GHT20,
4288 AR5416_NUM_5G_20_TARGET_POWERS,
4289 &targetPowerHt20, 8, false);
4290
4291 if (IS_CHAN_HT40(chan)) {
4292 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4293 ath9k_hw_get_target_powers(ah, chan,
4294 pEepData->
4295 calTargetPower5GHT40,
4296 AR5416_NUM_5G_40_TARGET_POWERS,
4297 &targetPowerHt40, 8,
4298 true);
4299 ath9k_hw_get_legacy_target_powers(ah, chan,
4300 pEepData->
4301 calTargetPower5G,
4302 AR5416_NUM_5G_20_TARGET_POWERS,
4303 &targetPowerOfdmExt,
4304 4, true);
4305 }
4306 }
4307
4308 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4309 bool isHt40CtlMode =
4310 (pCtlMode[ctlMode] == CTL_5GHT40)
4311 || (pCtlMode[ctlMode] == CTL_2GHT40);
4312 if (isHt40CtlMode)
4313 freq = centers.synth_center;
4314 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4315 freq = centers.ext_center;
4316 else
4317 freq = centers.ctl_center;
4318
4319 if (ar5416_get_eep_ver(ahp) == 14
4320 && ar5416_get_eep_rev(ahp) <= 2)
4321 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4322
4323 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4324 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4325 "EXT_ADDITIVE %d\n",
4326 ctlMode, numCtlModes, isHt40CtlMode,
4327 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4328
4329 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4330 i++) {
4331 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4332 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4333 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4334 "chan %d\n",
4335 i, cfgCtl, pCtlMode[ctlMode],
4336 pEepData->ctlIndex[i], chan->channel);
4337
4338 if ((((cfgCtl & ~CTL_MODE_M) |
4339 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4340 pEepData->ctlIndex[i])
4341 ||
4342 (((cfgCtl & ~CTL_MODE_M) |
4343 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4344 ((pEepData->
4345 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4346 rep = &(pEepData->ctlData[i]);
4347
4348 twiceMinEdgePower =
4349 ath9k_hw_get_max_edge_power(freq,
4350 rep->
4351 ctlEdges
4352 [ar5416_get_ntxchains
4353 (tx_chainmask)
4354 - 1],
4355 IS_CHAN_2GHZ
4356 (chan));
4357
4358 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4359 " MATCH-EE_IDX %d: ch %d is2 %d "
4360 "2xMinEdge %d chainmask %d chains %d\n",
4361 i, freq, IS_CHAN_2GHZ(chan),
4362 twiceMinEdgePower, tx_chainmask,
4363 ar5416_get_ntxchains
4364 (tx_chainmask));
4365 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4366 twiceMaxEdgePower =
4367 min(twiceMaxEdgePower,
4368 twiceMinEdgePower);
4369 } else {
4370 twiceMaxEdgePower =
4371 twiceMinEdgePower;
4372 break;
4373 }
4374 }
4375 }
4376
4377 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4378
4379 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4380 " SEL-Min ctlMode %d pCtlMode %d "
4381 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4382 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4383 scaledPower, minCtlPower);
4384
4385 switch (pCtlMode[ctlMode]) {
4386 case CTL_11B:
4387 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4388 i++) {
4389 targetPowerCck.tPow2x[i] =
4390 min(targetPowerCck.tPow2x[i],
4391 minCtlPower);
4392 }
4393 break;
4394 case CTL_11A:
4395 case CTL_11G:
4396 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4397 i++) {
4398 targetPowerOfdm.tPow2x[i] =
4399 min(targetPowerOfdm.tPow2x[i],
4400 minCtlPower);
4401 }
4402 break;
4403 case CTL_5GHT20:
4404 case CTL_2GHT20:
4405 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4406 i++) {
4407 targetPowerHt20.tPow2x[i] =
4408 min(targetPowerHt20.tPow2x[i],
4409 minCtlPower);
4410 }
4411 break;
4412 case CTL_11B_EXT:
4413 targetPowerCckExt.tPow2x[0] =
4414 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4415 break;
4416 case CTL_11A_EXT:
4417 case CTL_11G_EXT:
4418 targetPowerOfdmExt.tPow2x[0] =
4419 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4420 break;
4421 case CTL_5GHT40:
4422 case CTL_2GHT40:
4423 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4424 i++) {
4425 targetPowerHt40.tPow2x[i] =
4426 min(targetPowerHt40.tPow2x[i],
4427 minCtlPower);
4428 }
4429 break;
4430 default:
4431 break;
4432 }
4433 }
4434
4435 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4436 ratesArray[rate18mb] = ratesArray[rate24mb] =
4437 targetPowerOfdm.tPow2x[0];
4438 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4439 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4440 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4441 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4442
4443 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4444 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4445
4446 if (IS_CHAN_2GHZ(chan)) {
4447 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4448 ratesArray[rate2s] = ratesArray[rate2l] =
4449 targetPowerCck.tPow2x[1];
4450 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4451 targetPowerCck.tPow2x[2];
4452 ;
4453 ratesArray[rate11s] = ratesArray[rate11l] =
4454 targetPowerCck.tPow2x[3];
4455 ;
4456 }
4457 if (IS_CHAN_HT40(chan)) {
4458 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4459 ratesArray[rateHt40_0 + i] =
4460 targetPowerHt40.tPow2x[i];
4461 }
4462 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4463 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4464 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4465 if (IS_CHAN_2GHZ(chan)) {
4466 ratesArray[rateExtCck] =
4467 targetPowerCckExt.tPow2x[0];
4468 }
4469 }
4470 return true;
4471}
4472
4473static int
4474ath9k_hw_set_txpower(struct ath_hal *ah,
4475 struct ar5416_eeprom *pEepData,
4476 struct ath9k_channel *chan,
4477 u16 cfgCtl,
4478 u8 twiceAntennaReduction,
4479 u8 twiceMaxRegulatoryPower,
4480 u8 powerLimit)
4481{
4482 struct modal_eep_header *pModal =
4483 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4484 int16_t ratesArray[Ar5416RateSize];
4485 int16_t txPowerIndexOffset = 0;
4486 u8 ht40PowerIncForPdadc = 2;
4487 int i;
4488
4489 memset(ratesArray, 0, sizeof(ratesArray));
4490
4491 if ((pEepData->baseEepHeader.
4492 version & AR5416_EEP_VER_MINOR_MASK) >=
4493 AR5416_EEP_MINOR_VER_2) {
4494 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4495 }
4496
4497 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4498 &ratesArray[0], cfgCtl,
4499 twiceAntennaReduction,
4500 twiceMaxRegulatoryPower,
4501 powerLimit)) {
4502 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4503 "ath9k_hw_set_txpower: unable to set "
4504 "tx power per rate table\n");
4505 return -EIO;
4506 }
4507
4508 if (!ath9k_hw_set_power_cal_table
4509 (ah, pEepData, chan, &txPowerIndexOffset)) {
4510 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4511 "ath9k_hw_set_txpower: unable to set power table\n");
4512 return -EIO;
4513 }
4514
4515 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4516 ratesArray[i] =
4517 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4518 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4519 ratesArray[i] = AR5416_MAX_RATE_POWER;
4520 }
4521
4522 if (AR_SREV_9280_10_OR_LATER(ah)) {
4523 for (i = 0; i < Ar5416RateSize; i++)
4524 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4525 }
4526
4527 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4528 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4529 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4530 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4531 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4532 );
4533 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4534 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4535 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4536 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4537 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4538 );
4539
4540 if (IS_CHAN_2GHZ(chan)) {
4541 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4542 ATH9K_POW_SM(ratesArray[rate2s], 24)
4543 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4544 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4545 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4546 );
4547 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4548 ATH9K_POW_SM(ratesArray[rate11s], 24)
4549 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4550 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4551 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4552 );
4553 }
4554
4555 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4556 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4557 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4558 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4559 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4560 );
4561 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4562 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4563 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4564 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4565 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4566 );
4567
4568 if (IS_CHAN_HT40(chan)) {
4569 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4570 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4571 ht40PowerIncForPdadc, 24)
4572 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4573 ht40PowerIncForPdadc, 16)
4574 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4575 ht40PowerIncForPdadc, 8)
4576 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4577 ht40PowerIncForPdadc, 0)
4578 );
4579 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4580 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4581 ht40PowerIncForPdadc, 24)
4582 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4583 ht40PowerIncForPdadc, 16)
4584 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4585 ht40PowerIncForPdadc, 8)
4586 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4587 ht40PowerIncForPdadc, 0)
4588 );
4589
4590 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4591 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4592 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4593 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4594 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4595 );
4596 }
4597
4598 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4599 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4600 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4601 );
4602
4603 i = rate6mb;
4604 if (IS_CHAN_HT40(chan))
4605 i = rateHt40_0;
4606 else if (IS_CHAN_HT20(chan))
4607 i = rateHt20_0;
4608
4609 if (AR_SREV_9280_10_OR_LATER(ah))
4610 ah->ah_maxPowerLevel =
4611 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4612 else
4613 ah->ah_maxPowerLevel = ratesArray[i];
4614
4615 return 0;
4616}
4617
4618static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4619 u32 coef_scaled,
4620 u32 *coef_mantissa,
4621 u32 *coef_exponent)
4622{
4623 u32 coef_exp, coef_man;
4624
4625 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4626 if ((coef_scaled >> coef_exp) & 0x1)
4627 break;
4628
4629 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4630
4631 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4632
4633 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4634 *coef_exponent = coef_exp - 16;
4635}
4636
4637static void
4638ath9k_hw_set_delta_slope(struct ath_hal *ah,
4639 struct ath9k_channel *chan)
4640{
4641 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4642 u32 clockMhzScaled = 0x64000000;
4643 struct chan_centers centers;
4644
4645 if (IS_CHAN_HALF_RATE(chan))
4646 clockMhzScaled = clockMhzScaled >> 1;
4647 else if (IS_CHAN_QUARTER_RATE(chan))
4648 clockMhzScaled = clockMhzScaled >> 2;
4649
4650 ath9k_hw_get_channel_centers(ah, chan, &centers);
4651 coef_scaled = clockMhzScaled / centers.synth_center;
4652
4653 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4654 &ds_coef_exp);
4655
4656 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4657 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4658 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4659 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4660
4661 coef_scaled = (9 * coef_scaled) / 10;
4662
4663 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4664 &ds_coef_exp);
4665
4666 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4667 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4668 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4669 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4670}
4671
4672static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4673 struct ath9k_channel *chan)
4674{
4675 int bb_spur = AR_NO_SPUR;
4676 int freq;
4677 int bin, cur_bin;
4678 int bb_spur_off, spur_subchannel_sd;
4679 int spur_freq_sd;
4680 int spur_delta_phase;
4681 int denominator;
4682 int upper, lower, cur_vit_mask;
4683 int tmp, newVal;
4684 int i;
4685 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4686 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4687 };
4688 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4689 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4690 };
4691 int inc[4] = { 0, 100, 0, 0 };
4692 struct chan_centers centers;
4693
4694 int8_t mask_m[123];
4695 int8_t mask_p[123];
4696 int8_t mask_amt;
4697 int tmp_mask;
4698 int cur_bb_spur;
4699 bool is2GHz = IS_CHAN_2GHZ(chan);
4700
4701 memset(&mask_m, 0, sizeof(int8_t) * 123);
4702 memset(&mask_p, 0, sizeof(int8_t) * 123);
4703
4704 ath9k_hw_get_channel_centers(ah, chan, &centers);
4705 freq = centers.synth_center;
4706
60b67f51 4707 ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
f078f209
LR
4708 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4709 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4710
4711 if (is2GHz)
4712 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4713 else
4714 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4715
4716 if (AR_NO_SPUR == cur_bb_spur)
4717 break;
4718 cur_bb_spur = cur_bb_spur - freq;
4719
4720 if (IS_CHAN_HT40(chan)) {
4721 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4722 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4723 bb_spur = cur_bb_spur;
4724 break;
4725 }
4726 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4727 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4728 bb_spur = cur_bb_spur;
4729 break;
4730 }
4731 }
4732
4733 if (AR_NO_SPUR == bb_spur) {
4734 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4735 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4736 return;
4737 } else {
4738 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4739 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4740 }
4741
4742 bin = bb_spur * 320;
4743
4744 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4745
4746 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4747 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4748 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4749 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4750 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4751
4752 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4753 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4754 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4755 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4756 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4757 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4758
4759 if (IS_CHAN_HT40(chan)) {
4760 if (bb_spur < 0) {
4761 spur_subchannel_sd = 1;
4762 bb_spur_off = bb_spur + 10;
4763 } else {
4764 spur_subchannel_sd = 0;
4765 bb_spur_off = bb_spur - 10;
4766 }
4767 } else {
4768 spur_subchannel_sd = 0;
4769 bb_spur_off = bb_spur;
4770 }
4771
4772 if (IS_CHAN_HT40(chan))
4773 spur_delta_phase =
4774 ((bb_spur * 262144) /
4775 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4776 else
4777 spur_delta_phase =
4778 ((bb_spur * 524288) /
4779 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4780
4781 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4782 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4783
4784 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4785 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4786 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4787 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4788
4789 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4790 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4791
4792 cur_bin = -6000;
4793 upper = bin + 100;
4794 lower = bin - 100;
4795
4796 for (i = 0; i < 4; i++) {
4797 int pilot_mask = 0;
4798 int chan_mask = 0;
4799 int bp = 0;
4800 for (bp = 0; bp < 30; bp++) {
4801 if ((cur_bin > lower) && (cur_bin < upper)) {
4802 pilot_mask = pilot_mask | 0x1 << bp;
4803 chan_mask = chan_mask | 0x1 << bp;
4804 }
4805 cur_bin += 100;
4806 }
4807 cur_bin += inc[i];
4808 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4809 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4810 }
4811
4812 cur_vit_mask = 6100;
4813 upper = bin + 120;
4814 lower = bin - 120;
4815
4816 for (i = 0; i < 123; i++) {
4817 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
b08cbcd4
AB
4818
4819 /* workaround for gcc bug #37014 */
4820 volatile int tmp = abs(cur_vit_mask - bin);
4821
4822 if (tmp < 75)
f078f209
LR
4823 mask_amt = 1;
4824 else
4825 mask_amt = 0;
4826 if (cur_vit_mask < 0)
4827 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4828 else
4829 mask_p[cur_vit_mask / 100] = mask_amt;
4830 }
4831 cur_vit_mask -= 100;
4832 }
4833
4834 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4835 | (mask_m[48] << 26) | (mask_m[49] << 24)
4836 | (mask_m[50] << 22) | (mask_m[51] << 20)
4837 | (mask_m[52] << 18) | (mask_m[53] << 16)
4838 | (mask_m[54] << 14) | (mask_m[55] << 12)
4839 | (mask_m[56] << 10) | (mask_m[57] << 8)
4840 | (mask_m[58] << 6) | (mask_m[59] << 4)
4841 | (mask_m[60] << 2) | (mask_m[61] << 0);
4842 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4843 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4844
4845 tmp_mask = (mask_m[31] << 28)
4846 | (mask_m[32] << 26) | (mask_m[33] << 24)
4847 | (mask_m[34] << 22) | (mask_m[35] << 20)
4848 | (mask_m[36] << 18) | (mask_m[37] << 16)
4849 | (mask_m[48] << 14) | (mask_m[39] << 12)
4850 | (mask_m[40] << 10) | (mask_m[41] << 8)
4851 | (mask_m[42] << 6) | (mask_m[43] << 4)
4852 | (mask_m[44] << 2) | (mask_m[45] << 0);
4853 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4854 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4855
4856 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4857 | (mask_m[18] << 26) | (mask_m[18] << 24)
4858 | (mask_m[20] << 22) | (mask_m[20] << 20)
4859 | (mask_m[22] << 18) | (mask_m[22] << 16)
4860 | (mask_m[24] << 14) | (mask_m[24] << 12)
4861 | (mask_m[25] << 10) | (mask_m[26] << 8)
4862 | (mask_m[27] << 6) | (mask_m[28] << 4)
4863 | (mask_m[29] << 2) | (mask_m[30] << 0);
4864 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4865 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4866
4867 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4868 | (mask_m[2] << 26) | (mask_m[3] << 24)
4869 | (mask_m[4] << 22) | (mask_m[5] << 20)
4870 | (mask_m[6] << 18) | (mask_m[7] << 16)
4871 | (mask_m[8] << 14) | (mask_m[9] << 12)
4872 | (mask_m[10] << 10) | (mask_m[11] << 8)
4873 | (mask_m[12] << 6) | (mask_m[13] << 4)
4874 | (mask_m[14] << 2) | (mask_m[15] << 0);
4875 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4876 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4877
4878 tmp_mask = (mask_p[15] << 28)
4879 | (mask_p[14] << 26) | (mask_p[13] << 24)
4880 | (mask_p[12] << 22) | (mask_p[11] << 20)
4881 | (mask_p[10] << 18) | (mask_p[9] << 16)
4882 | (mask_p[8] << 14) | (mask_p[7] << 12)
4883 | (mask_p[6] << 10) | (mask_p[5] << 8)
4884 | (mask_p[4] << 6) | (mask_p[3] << 4)
4885 | (mask_p[2] << 2) | (mask_p[1] << 0);
4886 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4887 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4888
4889 tmp_mask = (mask_p[30] << 28)
4890 | (mask_p[29] << 26) | (mask_p[28] << 24)
4891 | (mask_p[27] << 22) | (mask_p[26] << 20)
4892 | (mask_p[25] << 18) | (mask_p[24] << 16)
4893 | (mask_p[23] << 14) | (mask_p[22] << 12)
4894 | (mask_p[21] << 10) | (mask_p[20] << 8)
4895 | (mask_p[19] << 6) | (mask_p[18] << 4)
4896 | (mask_p[17] << 2) | (mask_p[16] << 0);
4897 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4898 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4899
4900 tmp_mask = (mask_p[45] << 28)
4901 | (mask_p[44] << 26) | (mask_p[43] << 24)
4902 | (mask_p[42] << 22) | (mask_p[41] << 20)
4903 | (mask_p[40] << 18) | (mask_p[39] << 16)
4904 | (mask_p[38] << 14) | (mask_p[37] << 12)
4905 | (mask_p[36] << 10) | (mask_p[35] << 8)
4906 | (mask_p[34] << 6) | (mask_p[33] << 4)
4907 | (mask_p[32] << 2) | (mask_p[31] << 0);
4908 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4909 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4910
4911 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4912 | (mask_p[59] << 26) | (mask_p[58] << 24)
4913 | (mask_p[57] << 22) | (mask_p[56] << 20)
4914 | (mask_p[55] << 18) | (mask_p[54] << 16)
4915 | (mask_p[53] << 14) | (mask_p[52] << 12)
4916 | (mask_p[51] << 10) | (mask_p[50] << 8)
4917 | (mask_p[49] << 6) | (mask_p[48] << 4)
4918 | (mask_p[47] << 2) | (mask_p[46] << 0);
4919 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4920 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4921}
4922
4923static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4924 struct ath9k_channel *chan)
4925{
4926 int bb_spur = AR_NO_SPUR;
4927 int bin, cur_bin;
4928 int spur_freq_sd;
4929 int spur_delta_phase;
4930 int denominator;
4931 int upper, lower, cur_vit_mask;
4932 int tmp, new;
4933 int i;
4934 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4935 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4936 };
4937 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4938 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4939 };
4940 int inc[4] = { 0, 100, 0, 0 };
4941
4942 int8_t mask_m[123];
4943 int8_t mask_p[123];
4944 int8_t mask_amt;
4945 int tmp_mask;
4946 int cur_bb_spur;
4947 bool is2GHz = IS_CHAN_2GHZ(chan);
4948
4949 memset(&mask_m, 0, sizeof(int8_t) * 123);
4950 memset(&mask_p, 0, sizeof(int8_t) * 123);
4951
4952 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4953 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4954 if (AR_NO_SPUR == cur_bb_spur)
4955 break;
4956 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4957 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4958 bb_spur = cur_bb_spur;
4959 break;
4960 }
4961 }
4962
4963 if (AR_NO_SPUR == bb_spur)
4964 return;
4965
4966 bin = bb_spur * 32;
4967
4968 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4969 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4970 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4971 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4972 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4973
4974 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4975
4976 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4977 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4978 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4979 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4980 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4981 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4982
4983 spur_delta_phase = ((bb_spur * 524288) / 100) &
4984 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4985
4986 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4987 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4988
4989 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4990 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4991 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4992 REG_WRITE(ah, AR_PHY_TIMING11, new);
4993
4994 cur_bin = -6000;
4995 upper = bin + 100;
4996 lower = bin - 100;
4997
4998 for (i = 0; i < 4; i++) {
4999 int pilot_mask = 0;
5000 int chan_mask = 0;
5001 int bp = 0;
5002 for (bp = 0; bp < 30; bp++) {
5003 if ((cur_bin > lower) && (cur_bin < upper)) {
5004 pilot_mask = pilot_mask | 0x1 << bp;
5005 chan_mask = chan_mask | 0x1 << bp;
5006 }
5007 cur_bin += 100;
5008 }
5009 cur_bin += inc[i];
5010 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
5011 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5012 }
5013
5014 cur_vit_mask = 6100;
5015 upper = bin + 120;
5016 lower = bin - 120;
5017
5018 for (i = 0; i < 123; i++) {
5019 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
88b9e2be
AB
5020
5021 /* workaround for gcc bug #37014 */
5022 volatile int tmp = abs(cur_vit_mask - bin);
5023
5024 if (tmp < 75)
f078f209
LR
5025 mask_amt = 1;
5026 else
5027 mask_amt = 0;
5028 if (cur_vit_mask < 0)
5029 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5030 else
5031 mask_p[cur_vit_mask / 100] = mask_amt;
5032 }
5033 cur_vit_mask -= 100;
5034 }
5035
5036 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5037 | (mask_m[48] << 26) | (mask_m[49] << 24)
5038 | (mask_m[50] << 22) | (mask_m[51] << 20)
5039 | (mask_m[52] << 18) | (mask_m[53] << 16)
5040 | (mask_m[54] << 14) | (mask_m[55] << 12)
5041 | (mask_m[56] << 10) | (mask_m[57] << 8)
5042 | (mask_m[58] << 6) | (mask_m[59] << 4)
5043 | (mask_m[60] << 2) | (mask_m[61] << 0);
5044 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5045 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5046
5047 tmp_mask = (mask_m[31] << 28)
5048 | (mask_m[32] << 26) | (mask_m[33] << 24)
5049 | (mask_m[34] << 22) | (mask_m[35] << 20)
5050 | (mask_m[36] << 18) | (mask_m[37] << 16)
5051 | (mask_m[48] << 14) | (mask_m[39] << 12)
5052 | (mask_m[40] << 10) | (mask_m[41] << 8)
5053 | (mask_m[42] << 6) | (mask_m[43] << 4)
5054 | (mask_m[44] << 2) | (mask_m[45] << 0);
5055 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5056 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5057
5058 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5059 | (mask_m[18] << 26) | (mask_m[18] << 24)
5060 | (mask_m[20] << 22) | (mask_m[20] << 20)
5061 | (mask_m[22] << 18) | (mask_m[22] << 16)
5062 | (mask_m[24] << 14) | (mask_m[24] << 12)
5063 | (mask_m[25] << 10) | (mask_m[26] << 8)
5064 | (mask_m[27] << 6) | (mask_m[28] << 4)
5065 | (mask_m[29] << 2) | (mask_m[30] << 0);
5066 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5067 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5068
5069 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5070 | (mask_m[2] << 26) | (mask_m[3] << 24)
5071 | (mask_m[4] << 22) | (mask_m[5] << 20)
5072 | (mask_m[6] << 18) | (mask_m[7] << 16)
5073 | (mask_m[8] << 14) | (mask_m[9] << 12)
5074 | (mask_m[10] << 10) | (mask_m[11] << 8)
5075 | (mask_m[12] << 6) | (mask_m[13] << 4)
5076 | (mask_m[14] << 2) | (mask_m[15] << 0);
5077 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5078 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5079
5080 tmp_mask = (mask_p[15] << 28)
5081 | (mask_p[14] << 26) | (mask_p[13] << 24)
5082 | (mask_p[12] << 22) | (mask_p[11] << 20)
5083 | (mask_p[10] << 18) | (mask_p[9] << 16)
5084 | (mask_p[8] << 14) | (mask_p[7] << 12)
5085 | (mask_p[6] << 10) | (mask_p[5] << 8)
5086 | (mask_p[4] << 6) | (mask_p[3] << 4)
5087 | (mask_p[2] << 2) | (mask_p[1] << 0);
5088 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5089 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5090
5091 tmp_mask = (mask_p[30] << 28)
5092 | (mask_p[29] << 26) | (mask_p[28] << 24)
5093 | (mask_p[27] << 22) | (mask_p[26] << 20)
5094 | (mask_p[25] << 18) | (mask_p[24] << 16)
5095 | (mask_p[23] << 14) | (mask_p[22] << 12)
5096 | (mask_p[21] << 10) | (mask_p[20] << 8)
5097 | (mask_p[19] << 6) | (mask_p[18] << 4)
5098 | (mask_p[17] << 2) | (mask_p[16] << 0);
5099 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5100 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5101
5102 tmp_mask = (mask_p[45] << 28)
5103 | (mask_p[44] << 26) | (mask_p[43] << 24)
5104 | (mask_p[42] << 22) | (mask_p[41] << 20)
5105 | (mask_p[40] << 18) | (mask_p[39] << 16)
5106 | (mask_p[38] << 14) | (mask_p[37] << 12)
5107 | (mask_p[36] << 10) | (mask_p[35] << 8)
5108 | (mask_p[34] << 6) | (mask_p[33] << 4)
5109 | (mask_p[32] << 2) | (mask_p[31] << 0);
5110 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5111 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5112
5113 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5114 | (mask_p[59] << 26) | (mask_p[58] << 24)
5115 | (mask_p[57] << 22) | (mask_p[56] << 20)
5116 | (mask_p[55] << 18) | (mask_p[54] << 16)
5117 | (mask_p[53] << 14) | (mask_p[52] << 12)
5118 | (mask_p[51] << 10) | (mask_p[50] << 8)
5119 | (mask_p[49] << 6) | (mask_p[48] << 4)
5120 | (mask_p[47] << 2) | (mask_p[46] << 0);
5121 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5122 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5123}
5124
5125static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5126{
5127 struct ath_hal_5416 *ahp = AH5416(ah);
5128 int rx_chainmask, tx_chainmask;
5129
5130 rx_chainmask = ahp->ah_rxchainmask;
5131 tx_chainmask = ahp->ah_txchainmask;
5132
5133 switch (rx_chainmask) {
5134 case 0x5:
5135 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5136 AR_PHY_SWAP_ALT_CHAIN);
5137 case 0x3:
5138 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5139 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5140 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5141 break;
5142 }
5143 case 0x1:
5144 case 0x2:
5145 if (!AR_SREV_9280(ah))
5146 break;
5147 case 0x7:
5148 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5149 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5150 break;
5151 default:
5152 break;
5153 }
5154
5155 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5156 if (tx_chainmask == 0x5) {
5157 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5158 AR_PHY_SWAP_ALT_CHAIN);
5159 }
5160 if (AR_SREV_9100(ah))
5161 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5162 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5163}
5164
5165static void ath9k_hw_set_addac(struct ath_hal *ah,
5166 struct ath9k_channel *chan)
5167{
5168 struct modal_eep_header *pModal;
5169 struct ath_hal_5416 *ahp = AH5416(ah);
5170 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5171 u8 biaslevel;
5172
5173 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5174 return;
5175
5176 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5177 return;
5178
5179 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5180
5181 if (pModal->xpaBiasLvl != 0xff) {
5182 biaslevel = pModal->xpaBiasLvl;
5183 } else {
5184
5185 u16 resetFreqBin, freqBin, freqCount = 0;
5186 struct chan_centers centers;
5187
5188 ath9k_hw_get_channel_centers(ah, chan, &centers);
5189
5190 resetFreqBin =
5191 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5192 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5193 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5194
5195 freqCount++;
5196
5197 while (freqCount < 3) {
5198 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5199 break;
5200
5201 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5202 if (resetFreqBin >= freqBin) {
5203 biaslevel =
5204 (u8) (pModal->
5205 xpaBiasLvlFreq[freqCount]
5206 >> 14);
5207 } else {
5208 break;
5209 }
5210 freqCount++;
5211 }
5212 }
5213
5214 if (IS_CHAN_2GHZ(chan)) {
5215 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5216 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5217 << 3;
5218 } else {
5219 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5220 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5221 << 6;
5222 }
5223}
5224
5225static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5226{
5227 if (ah->ah_curchan != NULL)
5228 return clks /
5229 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5230 else
86b89eed 5231 return clks / CLOCK_RATE[ATH9K_MODE_11B];
f078f209
LR
5232}
5233
5234static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5235{
5236 struct ath9k_channel *chan = ah->ah_curchan;
5237
5238 if (chan && IS_CHAN_HT40(chan))
5239 return ath9k_hw_mac_usec(ah, clks) / 2;
5240 else
5241 return ath9k_hw_mac_usec(ah, clks);
5242}
5243
5244static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5245{
5246 if (ah->ah_curchan != NULL)
5247 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5248 ah->ah_curchan)];
5249 else
86b89eed 5250 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
f078f209
LR
5251}
5252
5253static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5254{
5255 struct ath9k_channel *chan = ah->ah_curchan;
5256
5257 if (chan && IS_CHAN_HT40(chan))
5258 return ath9k_hw_mac_clks(ah, usecs) * 2;
5259 else
5260 return ath9k_hw_mac_clks(ah, usecs);
5261}
5262
5263static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5264{
5265 struct ath_hal_5416 *ahp = AH5416(ah);
5266
5267 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5268 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5269 __func__, us);
5270 ahp->ah_acktimeout = (u32) -1;
5271 return false;
5272 } else {
5273 REG_RMW_FIELD(ah, AR_TIME_OUT,
5274 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5275 ahp->ah_acktimeout = us;
5276 return true;
5277 }
5278}
5279
5280static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5281{
5282 struct ath_hal_5416 *ahp = AH5416(ah);
5283
5284 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5285 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5286 __func__, us);
5287 ahp->ah_ctstimeout = (u32) -1;
5288 return false;
5289 } else {
5290 REG_RMW_FIELD(ah, AR_TIME_OUT,
5291 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5292 ahp->ah_ctstimeout = us;
5293 return true;
5294 }
5295}
5296static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5297 u32 tu)
5298{
5299 struct ath_hal_5416 *ahp = AH5416(ah);
5300
5301 if (tu > 0xFFFF) {
5302 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5303 "%s: bad global tx timeout %u\n", __func__, tu);
5304 ahp->ah_globaltxtimeout = (u32) -1;
5305 return false;
5306 } else {
5307 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5308 ahp->ah_globaltxtimeout = tu;
5309 return true;
5310 }
5311}
5312
5313bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5314{
5315 struct ath_hal_5416 *ahp = AH5416(ah);
5316
5317 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5318 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5319 __func__, us);
5320 ahp->ah_slottime = (u32) -1;
5321 return false;
5322 } else {
5323 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5324 ahp->ah_slottime = us;
5325 return true;
5326 }
5327}
5328
5329static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5330{
5331 struct ath_hal_5416 *ahp = AH5416(ah);
5332
5333 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5334 __func__, ahp->ah_miscMode);
5335 if (ahp->ah_miscMode != 0)
5336 REG_WRITE(ah, AR_PCU_MISC,
5337 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5338 if (ahp->ah_slottime != (u32) -1)
5339 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5340 if (ahp->ah_acktimeout != (u32) -1)
5341 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5342 if (ahp->ah_ctstimeout != (u32) -1)
5343 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5344 if (ahp->ah_globaltxtimeout != (u32) -1)
5345 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5346}
5347
5348static inline int
5349ath9k_hw_process_ini(struct ath_hal *ah,
5350 struct ath9k_channel *chan,
5351 enum ath9k_ht_macmode macmode)
5352{
5353 int i, regWrites = 0;
5354 struct ath_hal_5416 *ahp = AH5416(ah);
5355 u32 modesIndex, freqIndex;
5356 int status;
5357
5358 switch (chan->chanmode) {
5359 case CHANNEL_A:
5360 case CHANNEL_A_HT20:
5361 modesIndex = 1;
5362 freqIndex = 1;
5363 break;
5364 case CHANNEL_A_HT40PLUS:
5365 case CHANNEL_A_HT40MINUS:
5366 modesIndex = 2;
5367 freqIndex = 1;
5368 break;
5369 case CHANNEL_G:
5370 case CHANNEL_G_HT20:
5371 case CHANNEL_B:
5372 modesIndex = 4;
5373 freqIndex = 2;
5374 break;
5375 case CHANNEL_G_HT40PLUS:
5376 case CHANNEL_G_HT40MINUS:
5377 modesIndex = 3;
5378 freqIndex = 2;
5379 break;
5380
5381 default:
5382 return -EINVAL;
5383 }
5384
5385 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5386
5387 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5388
5389 ath9k_hw_set_addac(ah, chan);
5390
5391 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5392 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5393 } else {
5394 struct ar5416IniArray temp;
5395 u32 addacSize =
5396 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5397 ahp->ah_iniAddac.ia_columns;
5398
5399 memcpy(ahp->ah_addac5416_21,
5400 ahp->ah_iniAddac.ia_array, addacSize);
5401
5402 (ahp->ah_addac5416_21)[31 *
5403 ahp->ah_iniAddac.ia_columns + 1] = 0;
5404
5405 temp.ia_array = ahp->ah_addac5416_21;
5406 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5407 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5408 REG_WRITE_ARRAY(&temp, 1, regWrites);
5409 }
5410 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5411
5412 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5413 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5414 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5415
5416#ifdef CONFIG_SLOW_ANT_DIV
5417 if (ah->ah_devid == AR9280_DEVID_PCI)
5418 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5419 val);
5420#endif
5421
5422 REG_WRITE(ah, reg, val);
5423
5424 if (reg >= 0x7800 && reg < 0x78a0
60b67f51 5425 && ah->ah_config.analog_shiftreg) {
f078f209
LR
5426 udelay(100);
5427 }
5428
5429 DO_DELAY(regWrites);
5430 }
5431
5432 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5433 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5434 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5435
5436 REG_WRITE(ah, reg, val);
5437
5438 if (reg >= 0x7800 && reg < 0x78a0
60b67f51 5439 && ah->ah_config.analog_shiftreg) {
f078f209
LR
5440 udelay(100);
5441 }
5442
5443 DO_DELAY(regWrites);
5444 }
5445
5446 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5447
5448 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5449 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5450 regWrites);
5451 }
5452
5453 ath9k_hw_override_ini(ah, chan);
5454 ath9k_hw_set_regs(ah, chan, macmode);
5455 ath9k_hw_init_chain_masks(ah);
5456
5457 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5458 ath9k_regd_get_ctl(ah, chan),
5459 ath9k_regd_get_antenna_allowed(ah,
5460 chan),
5461 chan->maxRegTxPower * 2,
5462 min((u32) MAX_RATE_POWER,
5463 (u32) ah->ah_powerLimit));
5464 if (status != 0) {
5465 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5466 "%s: error init'ing transmit power\n", __func__);
5467 return -EIO;
5468 }
5469
5470 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5471 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5472 "%s: ar5416SetRfRegs failed\n", __func__);
5473 return -EIO;
5474 }
5475
5476 return 0;
5477}
5478
5479static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5480 struct hal_cal_list *currCal)
5481{
5482 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5483 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5484 currCal->calData->calCountMax);
5485
5486 switch (currCal->calData->calType) {
5487 case IQ_MISMATCH_CAL:
5488 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5489 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5490 "%s: starting IQ Mismatch Calibration\n",
5491 __func__);
5492 break;
5493 case ADC_GAIN_CAL:
5494 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5495 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5496 "%s: starting ADC Gain Calibration\n", __func__);
5497 break;
5498 case ADC_DC_CAL:
5499 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5500 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5501 "%s: starting ADC DC Calibration\n", __func__);
5502 break;
5503 case ADC_DC_INIT_CAL:
5504 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5505 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5506 "%s: starting Init ADC DC Calibration\n",
5507 __func__);
5508 break;
5509 }
5510
5511 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5512 AR_PHY_TIMING_CTRL4_DO_CAL);
5513}
5514
5515static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5516 struct hal_cal_list *currCal)
5517{
5518 struct ath_hal_5416 *ahp = AH5416(ah);
5519 int i;
5520
5521 ath9k_hw_setup_calibration(ah, currCal);
5522
5523 currCal->calState = CAL_RUNNING;
5524
5525 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5526 ahp->ah_Meas0.sign[i] = 0;
5527 ahp->ah_Meas1.sign[i] = 0;
5528 ahp->ah_Meas2.sign[i] = 0;
5529 ahp->ah_Meas3.sign[i] = 0;
5530 }
5531
5532 ahp->ah_CalSamples = 0;
5533}
5534
5535static inline void
5536ath9k_hw_per_calibration(struct ath_hal *ah,
5537 struct ath9k_channel *ichan,
5538 u8 rxchainmask,
5539 struct hal_cal_list *currCal,
5540 bool *isCalDone)
5541{
5542 struct ath_hal_5416 *ahp = AH5416(ah);
5543
5544 *isCalDone = false;
5545
5546 if (currCal->calState == CAL_RUNNING) {
5547 if (!(REG_READ(ah,
5548 AR_PHY_TIMING_CTRL4(0)) &
5549 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5550
5551 currCal->calData->calCollect(ah);
5552
5553 ahp->ah_CalSamples++;
5554
5555 if (ahp->ah_CalSamples >=
5556 currCal->calData->calNumSamples) {
5557 int i, numChains = 0;
5558 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5559 if (rxchainmask & (1 << i))
5560 numChains++;
5561 }
5562
5563 currCal->calData->calPostProc(ah,
5564 numChains);
5565
5566 ichan->CalValid |=
5567 currCal->calData->calType;
5568 currCal->calState = CAL_DONE;
5569 *isCalDone = true;
5570 } else {
5571 ath9k_hw_setup_calibration(ah, currCal);
5572 }
5573 }
5574 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5575 ath9k_hw_reset_calibration(ah, currCal);
5576 }
5577}
5578
5579static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5580 int init_cal_count)
5581{
5582 struct ath_hal_5416 *ahp = AH5416(ah);
5583 struct ath9k_channel ichan;
5584 bool isCalDone;
5585 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5586 const struct hal_percal_data *calData = currCal->calData;
5587 int i;
5588
5589 if (currCal == NULL)
5590 return false;
5591
5592 ichan.CalValid = 0;
5593
5594 for (i = 0; i < init_cal_count; i++) {
5595 ath9k_hw_reset_calibration(ah, currCal);
5596
5597 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5598 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5599 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5600 "%s: Cal %d failed to complete in 100ms.\n",
5601 __func__, calData->calType);
5602
5603 ahp->ah_cal_list = ahp->ah_cal_list_last =
5604 ahp->ah_cal_list_curr = NULL;
5605 return false;
5606 }
5607
5608 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5609 currCal, &isCalDone);
5610 if (!isCalDone) {
5611 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5612 "%s: Not able to run Init Cal %d.\n",
5613 __func__, calData->calType);
5614 }
5615 if (currCal->calNext) {
5616 currCal = currCal->calNext;
5617 calData = currCal->calData;
5618 }
5619 }
5620
5621 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5622 return true;
5623}
5624
5625static inline bool
5626ath9k_hw_channel_change(struct ath_hal *ah,
5627 struct ath9k_channel *chan,
5628 enum ath9k_ht_macmode macmode)
5629{
5630 u32 synthDelay, qnum;
5631 struct ath_hal_5416 *ahp = AH5416(ah);
5632
5633 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5634 if (ath9k_hw_numtxpending(ah, qnum)) {
5635 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5636 "%s: Transmit frames pending on queue %d\n",
5637 __func__, qnum);
5638 return false;
5639 }
5640 }
5641
5642 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5643 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5644 AR_PHY_RFBUS_GRANT_EN)) {
5645 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5646 "%s: Could not kill baseband RX\n", __func__);
5647 return false;
5648 }
5649
5650 ath9k_hw_set_regs(ah, chan, macmode);
5651
5652 if (AR_SREV_9280_10_OR_LATER(ah)) {
5653 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5654 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5655 "%s: failed to set channel\n", __func__);
5656 return false;
5657 }
5658 } else {
5659 if (!(ath9k_hw_set_channel(ah, chan))) {
5660 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5661 "%s: failed to set channel\n", __func__);
5662 return false;
5663 }
5664 }
5665
5666 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5667 ath9k_regd_get_ctl(ah, chan),
5668 ath9k_regd_get_antenna_allowed(ah, chan),
5669 chan->maxRegTxPower * 2,
5670 min((u32) MAX_RATE_POWER,
5671 (u32) ah->ah_powerLimit)) != 0) {
5672 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5673 "%s: error init'ing transmit power\n", __func__);
5674 return false;
5675 }
5676
5677 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5678 if (IS_CHAN_CCK(chan))
5679 synthDelay = (4 * synthDelay) / 22;
5680 else
5681 synthDelay /= 10;
5682
5683 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5684
5685 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5686
5687 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5688 ath9k_hw_set_delta_slope(ah, chan);
5689
5690 if (AR_SREV_9280_10_OR_LATER(ah))
5691 ath9k_hw_9280_spur_mitigate(ah, chan);
5692 else
5693 ath9k_hw_spur_mitigate(ah, chan);
5694
5695 if (!chan->oneTimeCalsDone)
5696 chan->oneTimeCalsDone = true;
5697
5698 return true;
5699}
5700
5701static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5702 struct ath9k_channel *chan)
5703{
5704 struct ath_hal_5416 *ahp = AH5416(ah);
5705
5706 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5707 return false;
5708
5709 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5710 return false;
5711
5712 ahp->ah_chipFullSleep = false;
5713
5714 ath9k_hw_init_pll(ah, chan);
5715
5716 ath9k_hw_set_rfmode(ah, chan);
5717
5718 return true;
5719}
5720
5721static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5722{
5723 u32 regval;
5724
5725 regval = REG_READ(ah, AR_AHB_MODE);
5726 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5727
5728 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5729 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5730
5731 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5732
5733 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5734 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5735
5736 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5737
5738 if (AR_SREV_9285(ah)) {
5739 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5740 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5741 } else {
5742 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5743 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5744 }
5745}
5746
5747bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5748{
5749 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5750 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5751 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5752 "%s: dma failed to stop in 10ms\n"
5753 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5754 __func__,
5755 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5756 return false;
5757 } else {
5758 return true;
5759 }
5760}
5761
5762void ath9k_hw_startpcureceive(struct ath_hal *ah)
5763{
5764 REG_CLR_BIT(ah, AR_DIAG_SW,
5765 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5766
5767 ath9k_enable_mib_counters(ah);
5768
5769 ath9k_ani_reset(ah);
5770}
5771
5772void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5773{
5774 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5775
5776 ath9k_hw_disable_mib_counters(ah);
5777}
5778
5779static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5780 struct ath9k_channel *chan,
5781 enum hal_cal_types calType)
5782{
5783 struct ath_hal_5416 *ahp = AH5416(ah);
5784 bool retval = false;
5785
5786 switch (calType & ahp->ah_suppCals) {
5787 case IQ_MISMATCH_CAL:
5788 if (!IS_CHAN_B(chan))
5789 retval = true;
5790 break;
5791 case ADC_GAIN_CAL:
5792 case ADC_DC_CAL:
5793 if (!IS_CHAN_B(chan)
5794 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5795 retval = true;
5796 break;
5797 }
5798
5799 return retval;
5800}
5801
5802static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5803 struct ath9k_channel *chan)
5804{
5805 struct ath_hal_5416 *ahp = AH5416(ah);
5806 struct ath9k_channel *ichan =
5807 ath9k_regd_check_channel(ah, chan);
5808
5809 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5810 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5811 AR_PHY_AGC_CONTROL_CAL);
5812
5813 if (!ath9k_hw_wait
5814 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5815 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5816 "%s: offset calibration failed to complete in 1ms; "
5817 "noisy environment?\n", __func__);
5818 return false;
5819 }
5820
5821 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5822 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5823 AR_PHY_AGC_CONTROL_NF);
5824
5825 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5826 NULL;
5827
5828 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5829 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5830 INIT_CAL(&ahp->ah_adcGainCalData);
5831 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5832 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5833 "%s: enabling ADC Gain Calibration.\n",
5834 __func__);
5835 }
5836 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5837 INIT_CAL(&ahp->ah_adcDcCalData);
5838 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5839 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5840 "%s: enabling ADC DC Calibration.\n",
5841 __func__);
5842 }
5843 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5844 INIT_CAL(&ahp->ah_iqCalData);
5845 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5846 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5847 "%s: enabling IQ Calibration.\n",
5848 __func__);
5849 }
5850
5851 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5852
5853 if (ahp->ah_cal_list_curr)
5854 ath9k_hw_reset_calibration(ah,
5855 ahp->ah_cal_list_curr);
5856 }
5857
5858 ichan->CalValid = 0;
5859
5860 return true;
5861}
5862
5863
5864bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5865 struct ath9k_channel *chan,
5866 enum ath9k_ht_macmode macmode,
5867 u8 txchainmask, u8 rxchainmask,
5868 enum ath9k_ht_extprotspacing extprotspacing,
5869 bool bChannelChange,
5870 int *status)
5871{
5872#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5873 u32 saveLedState;
5874 struct ath_hal_5416 *ahp = AH5416(ah);
5875 struct ath9k_channel *curchan = ah->ah_curchan;
5876 u32 saveDefAntenna;
5877 u32 macStaId1;
5878 int ecode;
5879 int i, rx_chainmask;
5880
5881 ahp->ah_extprotspacing = extprotspacing;
5882 ahp->ah_txchainmask = txchainmask;
5883 ahp->ah_rxchainmask = rxchainmask;
5884
5885 if (AR_SREV_9280(ah)) {
5886 ahp->ah_txchainmask &= 0x3;
5887 ahp->ah_rxchainmask &= 0x3;
5888 }
5889
5890 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5891 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5892 "%s: invalid channel %u/0x%x; no mapping\n",
5893 __func__, chan->channel, chan->channelFlags);
5894 FAIL(-EINVAL);
5895 }
5896
5897 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5898 return false;
5899
5900 if (curchan)
5901 ath9k_hw_getnf(ah, curchan);
5902
5903 if (bChannelChange &&
5904 (ahp->ah_chipFullSleep != true) &&
5905 (ah->ah_curchan != NULL) &&
5906 (chan->channel != ah->ah_curchan->channel) &&
5907 ((chan->channelFlags & CHANNEL_ALL) ==
5908 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5909 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5910 !IS_CHAN_A_5MHZ_SPACED(ah->
5911 ah_curchan)))) {
5912
5913 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5914 ath9k_hw_loadnf(ah, ah->ah_curchan);
5915 ath9k_hw_start_nfcal(ah);
5916 return true;
5917 }
5918 }
5919
5920 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5921 if (saveDefAntenna == 0)
5922 saveDefAntenna = 1;
5923
5924 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5925
5926 saveLedState = REG_READ(ah, AR_CFG_LED) &
5927 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5928 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5929
5930 ath9k_hw_mark_phy_inactive(ah);
5931
5932 if (!ath9k_hw_chip_reset(ah, chan)) {
5933 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5934 __func__);
5935 FAIL(-EIO);
5936 }
5937
5938 if (AR_SREV_9280(ah)) {
5939 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5940 AR_GPIO_JTAG_DISABLE);
5941
86b89eed 5942 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
f078f209
LR
5943 if (IS_CHAN_5GHZ(chan))
5944 ath9k_hw_set_gpio(ah, 9, 0);
5945 else
5946 ath9k_hw_set_gpio(ah, 9, 1);
5947 }
5948 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5949 }
5950
5951 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5952 if (ecode != 0)
5953 goto bad;
5954
5955 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5956 ath9k_hw_set_delta_slope(ah, chan);
5957
5958 if (AR_SREV_9280_10_OR_LATER(ah))
5959 ath9k_hw_9280_spur_mitigate(ah, chan);
5960 else
5961 ath9k_hw_spur_mitigate(ah, chan);
5962
5963 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5964 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5965 "%s: error setting board options\n", __func__);
5966 FAIL(-EIO);
5967 }
5968
5969 ath9k_hw_decrease_chain_power(ah, chan);
5970
5971 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5972 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5973 | macStaId1
5974 | AR_STA_ID1_RTS_USE_DEF
5975 | (ah->ah_config.
60b67f51 5976 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
f078f209
LR
5977 | ahp->ah_staId1Defaults);
5978 ath9k_hw_set_operating_mode(ah, opmode);
5979
5980 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5981 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5982
5983 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5984
5985 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5986 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5987 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5988
5989 REG_WRITE(ah, AR_ISR, ~0);
5990
5991 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5992
5993 if (AR_SREV_9280_10_OR_LATER(ah)) {
5994 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5995 FAIL(-EIO);
5996 } else {
5997 if (!(ath9k_hw_set_channel(ah, chan)))
5998 FAIL(-EIO);
5999 }
6000
6001 for (i = 0; i < AR_NUM_DCU; i++)
6002 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
6003
6004 ahp->ah_intrTxqs = 0;
60b67f51 6005 for (i = 0; i < ah->ah_caps.total_queues; i++)
f078f209
LR
6006 ath9k_hw_resettxqueue(ah, i);
6007
6008 ath9k_hw_init_interrupt_masks(ah, opmode);
6009 ath9k_hw_init_qos(ah);
6010
6011 ath9k_hw_init_user_settings(ah);
6012
6013 ah->ah_opmode = opmode;
6014
6015 REG_WRITE(ah, AR_STA_ID1,
6016 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6017
6018 ath9k_hw_set_dma(ah);
6019
6020 REG_WRITE(ah, AR_OBS, 8);
6021
6022 if (ahp->ah_intrMitigation) {
6023
6024 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6025 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6026 }
6027
6028 ath9k_hw_init_bb(ah, chan);
6029
6030 if (!ath9k_hw_init_cal(ah, chan))
6031 FAIL(-ENODEV);
6032
6033 rx_chainmask = ahp->ah_rxchainmask;
6034 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6035 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6036 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6037 }
6038
6039 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6040
6041 if (AR_SREV_9100(ah)) {
6042 u32 mask;
6043 mask = REG_READ(ah, AR_CFG);
6044 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6045 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6046 "%s CFG Byte Swap Set 0x%x\n", __func__,
6047 mask);
6048 } else {
6049 mask =
6050 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6051 REG_WRITE(ah, AR_CFG, mask);
6052 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6053 "%s Setting CFG 0x%x\n", __func__,
6054 REG_READ(ah, AR_CFG));
6055 }
6056 } else {
6057#ifdef __BIG_ENDIAN
6058 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6059#endif
6060 }
6061
6062 return true;
6063bad:
6064 if (status)
6065 *status = ecode;
6066 return false;
6067#undef FAIL
6068}
6069
6070bool ath9k_hw_phy_disable(struct ath_hal *ah)
6071{
6072 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6073}
6074
6075bool ath9k_hw_disable(struct ath_hal *ah)
6076{
6077 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6078 return false;
6079
6080 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6081}
6082
6083bool
6084ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6085 u8 rxchainmask, bool longcal,
6086 bool *isCalDone)
6087{
6088 struct ath_hal_5416 *ahp = AH5416(ah);
6089 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6090 struct ath9k_channel *ichan =
6091 ath9k_regd_check_channel(ah, chan);
6092
6093 *isCalDone = true;
6094
6095 if (ichan == NULL) {
6096 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6097 "%s: invalid channel %u/0x%x; no mapping\n",
6098 __func__, chan->channel, chan->channelFlags);
6099 return false;
6100 }
6101
6102 if (currCal &&
6103 (currCal->calState == CAL_RUNNING ||
6104 currCal->calState == CAL_WAITING)) {
6105 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6106 isCalDone);
6107 if (*isCalDone) {
6108 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6109
6110 if (currCal->calState == CAL_WAITING) {
6111 *isCalDone = false;
6112 ath9k_hw_reset_calibration(ah, currCal);
6113 }
6114 }
6115 }
6116
6117 if (longcal) {
6118 ath9k_hw_getnf(ah, ichan);
6119 ath9k_hw_loadnf(ah, ah->ah_curchan);
6120 ath9k_hw_start_nfcal(ah);
6121
6122 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6123
6124 chan->channelFlags |= CHANNEL_CW_INT;
6125 ichan->channelFlags &= ~CHANNEL_CW_INT;
6126 }
6127 }
6128
6129 return true;
6130}
6131
6132static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6133{
6134 struct ath_hal_5416 *ahp = AH5416(ah);
6135 int i;
6136
6137 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6138 ahp->ah_totalPowerMeasI[i] +=
6139 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6140 ahp->ah_totalPowerMeasQ[i] +=
6141 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6142 ahp->ah_totalIqCorrMeas[i] +=
6143 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6144 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6145 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6146 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6147 ahp->ah_totalPowerMeasQ[i],
6148 ahp->ah_totalIqCorrMeas[i]);
6149 }
6150}
6151
6152static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6153{
6154 struct ath_hal_5416 *ahp = AH5416(ah);
6155 int i;
6156
6157 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6158 ahp->ah_totalAdcIOddPhase[i] +=
6159 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6160 ahp->ah_totalAdcIEvenPhase[i] +=
6161 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6162 ahp->ah_totalAdcQOddPhase[i] +=
6163 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6164 ahp->ah_totalAdcQEvenPhase[i] +=
6165 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6166
6167 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6168 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6169 "oddq=0x%08x; evenq=0x%08x;\n",
6170 ahp->ah_CalSamples, i,
6171 ahp->ah_totalAdcIOddPhase[i],
6172 ahp->ah_totalAdcIEvenPhase[i],
6173 ahp->ah_totalAdcQOddPhase[i],
6174 ahp->ah_totalAdcQEvenPhase[i]);
6175 }
6176}
6177
6178static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6179{
6180 struct ath_hal_5416 *ahp = AH5416(ah);
6181 int i;
6182
6183 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6184 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6185 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6186 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6187 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6188 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6189 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6190 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6191 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6192
6193 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6194 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6195 "oddq=0x%08x; evenq=0x%08x;\n",
6196 ahp->ah_CalSamples, i,
6197 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6198 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6199 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6200 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6201 }
6202}
6203
6204static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6205{
6206 struct ath_hal_5416 *ahp = AH5416(ah);
6207 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6208 u32 qCoffDenom, iCoffDenom;
6209 int32_t qCoff, iCoff;
6210 int iqCorrNeg, i;
6211
6212 for (i = 0; i < numChains; i++) {
6213 powerMeasI = ahp->ah_totalPowerMeasI[i];
6214 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6215 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6216
6217 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218 "Starting IQ Cal and Correction for Chain %d\n",
6219 i);
6220
6221 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6222 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6223 i, ahp->ah_totalIqCorrMeas[i]);
6224
6225 iqCorrNeg = 0;
6226
6227
6228 if (iqCorrMeas > 0x80000000) {
6229 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6230 iqCorrNeg = 1;
6231 }
6232
6233 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6234 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6235 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6236 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6237 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6238 iqCorrNeg);
6239
6240 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6241 qCoffDenom = powerMeasQ / 64;
6242
6243 if (powerMeasQ != 0) {
6244
6245 iCoff = iqCorrMeas / iCoffDenom;
6246 qCoff = powerMeasI / qCoffDenom - 64;
6247 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6248 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6249 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6250 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6251
6252
6253 iCoff = iCoff & 0x3f;
6254 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6255 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6256 if (iqCorrNeg == 0x0)
6257 iCoff = 0x40 - iCoff;
6258
6259 if (qCoff > 15)
6260 qCoff = 15;
6261 else if (qCoff <= -16)
6262 qCoff = 16;
6263
6264 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6265 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6266 i, iCoff, qCoff);
6267
6268 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6269 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6270 iCoff);
6271 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6272 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6273 qCoff);
6274 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6275 "IQ Cal and Correction done for Chain %d\n",
6276 i);
6277 }
6278 }
6279
6280 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6281 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6282}
6283
6284static void
6285ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6286{
6287 struct ath_hal_5416 *ahp = AH5416(ah);
6288 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6289 qEvenMeasOffset;
6290 u32 qGainMismatch, iGainMismatch, val, i;
6291
6292 for (i = 0; i < numChains; i++) {
6293 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6294 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6295 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6296 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6297
6298 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6299 "Starting ADC Gain Cal for Chain %d\n", i);
6300
6301 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6302 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6303 iOddMeasOffset);
6304 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6305 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6306 iEvenMeasOffset);
6307 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6309 qOddMeasOffset);
6310 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6311 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6312 qEvenMeasOffset);
6313
6314 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6315 iGainMismatch =
6316 ((iEvenMeasOffset * 32) /
6317 iOddMeasOffset) & 0x3f;
6318 qGainMismatch =
6319 ((qOddMeasOffset * 32) /
6320 qEvenMeasOffset) & 0x3f;
6321
6322 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6323 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6324 iGainMismatch);
6325 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6326 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6327 qGainMismatch);
6328
6329 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6330 val &= 0xfffff000;
6331 val |= (qGainMismatch) | (iGainMismatch << 6);
6332 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6333
6334 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6335 "ADC Gain Cal done for Chain %d\n", i);
6336 }
6337 }
6338
6339 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6340 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6341 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6342}
6343
6344static void
6345ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6346{
6347 struct ath_hal_5416 *ahp = AH5416(ah);
6348 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6349 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6350 const struct hal_percal_data *calData =
6351 ahp->ah_cal_list_curr->calData;
6352 u32 numSamples =
6353 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6354
6355 for (i = 0; i < numChains; i++) {
6356 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6357 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6358 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6359 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6360
6361 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6362 "Starting ADC DC Offset Cal for Chain %d\n", i);
6363
6364 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6365 "Chn %d pwr_meas_odd_i = %d\n", i,
6366 iOddMeasOffset);
6367 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368 "Chn %d pwr_meas_even_i = %d\n", i,
6369 iEvenMeasOffset);
6370 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6371 "Chn %d pwr_meas_odd_q = %d\n", i,
6372 qOddMeasOffset);
6373 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6374 "Chn %d pwr_meas_even_q = %d\n", i,
6375 qEvenMeasOffset);
6376
6377 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6378 numSamples) & 0x1ff;
6379 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6380 numSamples) & 0x1ff;
6381
6382 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6383 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6384 iDcMismatch);
6385 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6386 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6387 qDcMismatch);
6388
6389 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6390 val &= 0xc0000fff;
6391 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6392 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6393
6394 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6395 "ADC DC Offset Cal done for Chain %d\n", i);
6396 }
6397
6398 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6399 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6400 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6401}
6402
6403bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6404{
6405 struct ath_hal_5416 *ahp = AH5416(ah);
6406 struct ath9k_channel *chan = ah->ah_curchan;
6407
6408 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6409
6410 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6411 ath9k_regd_get_ctl(ah, chan),
6412 ath9k_regd_get_antenna_allowed(ah,
6413 chan),
6414 chan->maxRegTxPower * 2,
6415 min((u32) MAX_RATE_POWER,
6416 (u32) ah->ah_powerLimit)) != 0)
6417 return false;
6418
6419 return true;
6420}
6421
6422void
6423ath9k_hw_get_channel_centers(struct ath_hal *ah,
6424 struct ath9k_channel *chan,
6425 struct chan_centers *centers)
6426{
6427 int8_t extoff;
6428 struct ath_hal_5416 *ahp = AH5416(ah);
6429
6430 if (!IS_CHAN_HT40(chan)) {
6431 centers->ctl_center = centers->ext_center =
6432 centers->synth_center = chan->channel;
6433 return;
6434 }
6435
6436 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6437 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6438 centers->synth_center =
6439 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6440 extoff = 1;
6441 } else {
6442 centers->synth_center =
6443 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6444 extoff = -1;
6445 }
6446
6447 centers->ctl_center = centers->synth_center - (extoff *
6448 HT40_CHANNEL_CENTER_SHIFT);
6449 centers->ext_center = centers->synth_center + (extoff *
6450 ((ahp->
6451 ah_extprotspacing
6452 ==
6453 ATH9K_HT_EXTPROTSPACING_20)
6454 ?
6455 HT40_CHANNEL_CENTER_SHIFT
6456 : 15));
6457
6458}
6459
6460void
6461ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6462 bool *isCalDone)
6463{
6464 struct ath_hal_5416 *ahp = AH5416(ah);
6465 struct ath9k_channel *ichan =
6466 ath9k_regd_check_channel(ah, chan);
6467 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6468
6469 *isCalDone = true;
6470
6471 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6472 return;
6473
6474 if (currCal == NULL)
6475 return;
6476
6477 if (ichan == NULL) {
6478 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6479 "%s: invalid channel %u/0x%x; no mapping\n",
6480 __func__, chan->channel, chan->channelFlags);
6481 return;
6482 }
6483
6484
6485 if (currCal->calState != CAL_DONE) {
6486 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6487 "%s: Calibration state incorrect, %d\n",
6488 __func__, currCal->calState);
6489 return;
6490 }
6491
6492
6493 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6494 return;
6495
6496 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6497 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6498 __func__, currCal->calData->calType, chan->channel,
6499 chan->channelFlags);
6500
6501 ichan->CalValid &= ~currCal->calData->calType;
6502 currCal->calState = CAL_WAITING;
6503
6504 *isCalDone = false;
6505}
6506
6507void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6508{
6509 struct ath_hal_5416 *ahp = AH5416(ah);
6510
6511 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6512}
6513
6514bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6515{
6516 struct ath_hal_5416 *ahp = AH5416(ah);
6517
6518 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6519 return true;
6520}
6521
6522void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6523{
6524 struct ath_hal_5416 *ahp = AH5416(ah);
6525
6526 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6527}
6528
6529bool
6530ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6531{
6532 struct ath_hal_5416 *ahp = AH5416(ah);
6533
6534 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6535
6536 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6537 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6538
6539 return true;
6540}
6541
6542#ifdef CONFIG_ATH9K_RFKILL
6543static void ath9k_enable_rfkill(struct ath_hal *ah)
6544{
6545 struct ath_hal_5416 *ahp = AH5416(ah);
6546
6547 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6548 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6549
6550 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6551 AR_GPIO_INPUT_MUX2_RFSILENT);
6552
6553 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6554 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6555
6556 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6557
6558 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6559 !ahp->ah_gpioBit);
6560 } else {
6561 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6562 ahp->ah_gpioBit);
6563 }
6564}
6565#endif
6566
6567void
6568ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6569 u16 assocId)
6570{
6571 struct ath_hal_5416 *ahp = AH5416(ah);
6572
6573 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6574 ahp->ah_assocId = assocId;
6575
6576 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6577 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6578 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6579}
6580
6581u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6582{
6583 u64 tsf;
6584
6585 tsf = REG_READ(ah, AR_TSF_U32);
6586 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6587 return tsf;
6588}
6589
6590void ath9k_hw_reset_tsf(struct ath_hal *ah)
6591{
6592 int count;
6593
6594 count = 0;
6595 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6596 count++;
6597 if (count > 10) {
6598 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6599 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6600 __func__);
6601 break;
6602 }
6603 udelay(10);
6604 }
6605 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6606}
6607
6608u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6609{
6610 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6611}
6612
6613void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6614{
6615 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6616}
6617
6618bool
6619ath9k_hw_setantennaswitch(struct ath_hal *ah,
6620 enum ath9k_ant_setting settings,
6621 struct ath9k_channel *chan,
6622 u8 *tx_chainmask,
6623 u8 *rx_chainmask,
6624 u8 *antenna_cfgd)
6625{
6626 struct ath_hal_5416 *ahp = AH5416(ah);
6627 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6628
6629 if (AR_SREV_9280(ah)) {
6630 if (!tx_chainmask_cfg) {
6631
6632 tx_chainmask_cfg = *tx_chainmask;
6633 rx_chainmask_cfg = *rx_chainmask;
6634 }
6635
6636 switch (settings) {
6637 case ATH9K_ANT_FIXED_A:
6638 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6639 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6640 *antenna_cfgd = true;
6641 break;
6642 case ATH9K_ANT_FIXED_B:
60b67f51 6643 if (ah->ah_caps.tx_chainmask >
f078f209
LR
6644 ATH9K_ANTENNA1_CHAINMASK) {
6645 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6646 }
6647 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6648 *antenna_cfgd = true;
6649 break;
6650 case ATH9K_ANT_VARIABLE:
6651 *tx_chainmask = tx_chainmask_cfg;
6652 *rx_chainmask = rx_chainmask_cfg;
6653 *antenna_cfgd = true;
6654 break;
6655 default:
6656 break;
6657 }
6658 } else {
6659 ahp->ah_diversityControl = settings;
6660 }
6661
6662 return true;
6663}
6664
6665void ath9k_hw_setopmode(struct ath_hal *ah)
6666{
6667 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6668}
6669
6670bool
60b67f51 6671ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
f078f209
LR
6672 u32 capability, u32 *result)
6673{
6674 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 6675 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6676
6677 switch (type) {
60b67f51 6678 case ATH9K_CAP_CIPHER:
f078f209
LR
6679 switch (capability) {
6680 case ATH9K_CIPHER_AES_CCM:
6681 case ATH9K_CIPHER_AES_OCB:
6682 case ATH9K_CIPHER_TKIP:
6683 case ATH9K_CIPHER_WEP:
6684 case ATH9K_CIPHER_MIC:
6685 case ATH9K_CIPHER_CLR:
6686 return true;
6687 default:
6688 return false;
6689 }
60b67f51 6690 case ATH9K_CAP_TKIP_MIC:
f078f209
LR
6691 switch (capability) {
6692 case 0:
6693 return true;
6694 case 1:
6695 return (ahp->ah_staId1Defaults &
6696 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6697 false;
6698 }
60b67f51 6699 case ATH9K_CAP_TKIP_SPLIT:
f078f209
LR
6700 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6701 false : true;
60b67f51 6702 case ATH9K_CAP_WME_TKIPMIC:
f078f209 6703 return 0;
60b67f51 6704 case ATH9K_CAP_PHYCOUNTERS:
f078f209 6705 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
60b67f51 6706 case ATH9K_CAP_DIVERSITY:
f078f209
LR
6707 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6708 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6709 true : false;
60b67f51 6710 case ATH9K_CAP_PHYDIAG:
f078f209 6711 return true;
60b67f51 6712 case ATH9K_CAP_MCAST_KEYSRCH:
f078f209
LR
6713 switch (capability) {
6714 case 0:
6715 return true;
6716 case 1:
6717 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6718 return false;
6719 } else {
6720 return (ahp->ah_staId1Defaults &
6721 AR_STA_ID1_MCAST_KSRCH) ? true :
6722 false;
6723 }
6724 }
6725 return false;
60b67f51 6726 case ATH9K_CAP_TSF_ADJUST:
f078f209
LR
6727 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6728 true : false;
60b67f51 6729 case ATH9K_CAP_RFSILENT:
f078f209
LR
6730 if (capability == 3)
6731 return false;
60b67f51
S
6732 case ATH9K_CAP_ANT_CFG_2GHZ:
6733 *result = pCap->num_antcfg_2ghz;
f078f209 6734 return true;
60b67f51
S
6735 case ATH9K_CAP_ANT_CFG_5GHZ:
6736 *result = pCap->num_antcfg_5ghz;
f078f209 6737 return true;
60b67f51 6738 case ATH9K_CAP_TXPOW:
f078f209
LR
6739 switch (capability) {
6740 case 0:
6741 return 0;
6742 case 1:
6743 *result = ah->ah_powerLimit;
6744 return 0;
6745 case 2:
6746 *result = ah->ah_maxPowerLevel;
6747 return 0;
6748 case 3:
6749 *result = ah->ah_tpScale;
6750 return 0;
6751 }
6752 return false;
6753 default:
6754 return false;
6755 }
6756}
6757
6758int
6759ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6760{
6761 struct ath_hal_5416 *ahp = AH5416(ah);
6762 struct ath9k_channel *chan = ah->ah_curchan;
60b67f51 6763 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6764 u16 ant_config;
6765 u32 halNumAntConfig;
6766
6767 halNumAntConfig =
60b67f51
S
6768 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6769 num_antcfg_5ghz;
f078f209
LR
6770
6771 if (cfg < halNumAntConfig) {
6772 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6773 cfg, &ant_config)) {
6774 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6775 return 0;
6776 }
6777 }
6778
6779 return -EINVAL;
6780}
6781
6782bool ath9k_hw_intrpend(struct ath_hal *ah)
6783{
6784 u32 host_isr;
6785
6786 if (AR_SREV_9100(ah))
6787 return true;
6788
6789 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6790 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6791 return true;
6792
6793 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6794 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6795 && (host_isr != AR_INTR_SPURIOUS))
6796 return true;
6797
6798 return false;
6799}
6800
6801bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6802{
6803 u32 isr = 0;
6804 u32 mask2 = 0;
60b67f51 6805 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6806 u32 sync_cause = 0;
6807 bool fatal_int = false;
6808
6809 if (!AR_SREV_9100(ah)) {
6810 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6811 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6812 == AR_RTC_STATUS_ON) {
6813 isr = REG_READ(ah, AR_ISR);
6814 }
6815 }
6816
6817 sync_cause =
6818 REG_READ(ah,
6819 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6820
6821 *masked = 0;
6822
6823 if (!isr && !sync_cause)
6824 return false;
6825 } else {
6826 *masked = 0;
6827 isr = REG_READ(ah, AR_ISR);
6828 }
6829
6830 if (isr) {
6831 struct ath_hal_5416 *ahp = AH5416(ah);
6832
6833 if (isr & AR_ISR_BCNMISC) {
6834 u32 isr2;
6835 isr2 = REG_READ(ah, AR_ISR_S2);
6836 if (isr2 & AR_ISR_S2_TIM)
6837 mask2 |= ATH9K_INT_TIM;
6838 if (isr2 & AR_ISR_S2_DTIM)
6839 mask2 |= ATH9K_INT_DTIM;
6840 if (isr2 & AR_ISR_S2_DTIMSYNC)
6841 mask2 |= ATH9K_INT_DTIMSYNC;
6842 if (isr2 & (AR_ISR_S2_CABEND))
6843 mask2 |= ATH9K_INT_CABEND;
6844 if (isr2 & AR_ISR_S2_GTT)
6845 mask2 |= ATH9K_INT_GTT;
6846 if (isr2 & AR_ISR_S2_CST)
6847 mask2 |= ATH9K_INT_CST;
6848 }
6849
6850 isr = REG_READ(ah, AR_ISR_RAC);
6851 if (isr == 0xffffffff) {
6852 *masked = 0;
6853 return false;
6854 }
6855
6856 *masked = isr & ATH9K_INT_COMMON;
6857
6858 if (ahp->ah_intrMitigation) {
6859
6860 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6861 *masked |= ATH9K_INT_RX;
6862 }
6863
6864 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6865 *masked |= ATH9K_INT_RX;
6866 if (isr &
6867 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6868 AR_ISR_TXEOL)) {
6869 u32 s0_s, s1_s;
6870
6871 *masked |= ATH9K_INT_TX;
6872
6873 s0_s = REG_READ(ah, AR_ISR_S0_S);
6874 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6875 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6876
6877 s1_s = REG_READ(ah, AR_ISR_S1_S);
6878 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6879 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6880 }
6881
6882 if (isr & AR_ISR_RXORN) {
6883 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6884 "%s: receive FIFO overrun interrupt\n",
6885 __func__);
6886 }
6887
6888 if (!AR_SREV_9100(ah)) {
60b67f51 6889 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
f078f209
LR
6890 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6891 if (isr5 & AR_ISR_S5_TIM_TIMER)
6892 *masked |= ATH9K_INT_TIM_TIMER;
6893 }
6894 }
6895
6896 *masked |= mask2;
6897 }
6898 if (AR_SREV_9100(ah))
6899 return true;
6900 if (sync_cause) {
6901 fatal_int =
6902 (sync_cause &
6903 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6904 ? true : false;
6905
6906 if (fatal_int) {
6907 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6908 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6909 "%s: received PCI FATAL interrupt\n",
6910 __func__);
6911 }
6912 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6913 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6914 "%s: received PCI PERR interrupt\n",
6915 __func__);
6916 }
6917 }
6918 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6919 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6920 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6921 __func__);
6922 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6923 REG_WRITE(ah, AR_RC, 0);
6924 *masked |= ATH9K_INT_FATAL;
6925 }
6926 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6927 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6928 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6929 __func__);
6930 }
6931
6932 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6933 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6934 }
6935 return true;
6936}
6937
6938enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6939{
6940 return AH5416(ah)->ah_maskReg;
6941}
6942
6943enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6944{
6945 struct ath_hal_5416 *ahp = AH5416(ah);
6946 u32 omask = ahp->ah_maskReg;
6947 u32 mask, mask2;
60b67f51 6948 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
6949
6950 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6951 omask, ints);
6952
6953 if (omask & ATH9K_INT_GLOBAL) {
6954 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6955 __func__);
6956 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6957 (void) REG_READ(ah, AR_IER);
6958 if (!AR_SREV_9100(ah)) {
6959 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6960 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6961
6962 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6963 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6964 }
6965 }
6966
6967 mask = ints & ATH9K_INT_COMMON;
6968 mask2 = 0;
6969
6970 if (ints & ATH9K_INT_TX) {
6971 if (ahp->ah_txOkInterruptMask)
6972 mask |= AR_IMR_TXOK;
6973 if (ahp->ah_txDescInterruptMask)
6974 mask |= AR_IMR_TXDESC;
6975 if (ahp->ah_txErrInterruptMask)
6976 mask |= AR_IMR_TXERR;
6977 if (ahp->ah_txEolInterruptMask)
6978 mask |= AR_IMR_TXEOL;
6979 }
6980 if (ints & ATH9K_INT_RX) {
6981 mask |= AR_IMR_RXERR;
6982 if (ahp->ah_intrMitigation)
6983 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6984 else
6985 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
60b67f51 6986 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
f078f209
LR
6987 mask |= AR_IMR_GENTMR;
6988 }
6989
6990 if (ints & (ATH9K_INT_BMISC)) {
6991 mask |= AR_IMR_BCNMISC;
6992 if (ints & ATH9K_INT_TIM)
6993 mask2 |= AR_IMR_S2_TIM;
6994 if (ints & ATH9K_INT_DTIM)
6995 mask2 |= AR_IMR_S2_DTIM;
6996 if (ints & ATH9K_INT_DTIMSYNC)
6997 mask2 |= AR_IMR_S2_DTIMSYNC;
6998 if (ints & ATH9K_INT_CABEND)
6999 mask2 |= (AR_IMR_S2_CABEND);
7000 }
7001
7002 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
7003 mask |= AR_IMR_BCNMISC;
7004 if (ints & ATH9K_INT_GTT)
7005 mask2 |= AR_IMR_S2_GTT;
7006 if (ints & ATH9K_INT_CST)
7007 mask2 |= AR_IMR_S2_CST;
7008 }
7009
7010 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
7011 mask);
7012 REG_WRITE(ah, AR_IMR, mask);
7013 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7014 AR_IMR_S2_DTIM |
7015 AR_IMR_S2_DTIMSYNC |
7016 AR_IMR_S2_CABEND |
7017 AR_IMR_S2_CABTO |
7018 AR_IMR_S2_TSFOOR |
7019 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7020 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7021 ahp->ah_maskReg = ints;
7022
60b67f51 7023 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
f078f209
LR
7024 if (ints & ATH9K_INT_TIM_TIMER)
7025 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7026 else
7027 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7028 }
7029
7030 if (ints & ATH9K_INT_GLOBAL) {
7031 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7032 __func__);
7033 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7034 if (!AR_SREV_9100(ah)) {
7035 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7036 AR_INTR_MAC_IRQ);
7037 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7038
7039
7040 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7041 AR_INTR_SYNC_DEFAULT);
7042 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7043 AR_INTR_SYNC_DEFAULT);
7044 }
7045 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7046 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7047 }
7048
7049 return omask;
7050}
7051
7052void
7053ath9k_hw_beaconinit(struct ath_hal *ah,
7054 u32 next_beacon, u32 beacon_period)
7055{
7056 struct ath_hal_5416 *ahp = AH5416(ah);
7057 int flags = 0;
7058
7059 ahp->ah_beaconInterval = beacon_period;
7060
7061 switch (ah->ah_opmode) {
7062 case ATH9K_M_STA:
7063 case ATH9K_M_MONITOR:
7064 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7065 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7066 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7067 flags |= AR_TBTT_TIMER_EN;
7068 break;
7069 case ATH9K_M_IBSS:
7070 REG_SET_BIT(ah, AR_TXCFG,
7071 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7072 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7073 TU_TO_USEC(next_beacon +
7074 (ahp->ah_atimWindow ? ahp->
7075 ah_atimWindow : 1)));
7076 flags |= AR_NDP_TIMER_EN;
7077 case ATH9K_M_HOSTAP:
7078 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7079 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7080 TU_TO_USEC(next_beacon -
7081 ah->ah_config.
60b67f51 7082 dma_beacon_response_time));
f078f209
LR
7083 REG_WRITE(ah, AR_NEXT_SWBA,
7084 TU_TO_USEC(next_beacon -
7085 ah->ah_config.
60b67f51 7086 sw_beacon_response_time));
f078f209
LR
7087 flags |=
7088 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7089 break;
7090 }
7091
7092 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7093 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7094 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7095 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7096
7097 beacon_period &= ~ATH9K_BEACON_ENA;
7098 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7099 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7100 ath9k_hw_reset_tsf(ah);
7101 }
7102
7103 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7104}
7105
7106void
7107ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7108 const struct ath9k_beacon_state *bs)
7109{
7110 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
60b67f51 7111 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7112
7113 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7114
7115 REG_WRITE(ah, AR_BEACON_PERIOD,
7116 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7117 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7118 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7119
7120 REG_RMW_FIELD(ah, AR_RSSI_THR,
7121 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7122
7123 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7124
7125 if (bs->bs_sleepduration > beaconintval)
7126 beaconintval = bs->bs_sleepduration;
7127
7128 dtimperiod = bs->bs_dtimperiod;
7129 if (bs->bs_sleepduration > dtimperiod)
7130 dtimperiod = bs->bs_sleepduration;
7131
7132 if (beaconintval == dtimperiod)
7133 nextTbtt = bs->bs_nextdtim;
7134 else
7135 nextTbtt = bs->bs_nexttbtt;
7136
7137 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7138 bs->bs_nextdtim);
7139 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7140 nextTbtt);
7141 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7142 beaconintval);
7143 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7144 dtimperiod);
7145
7146 REG_WRITE(ah, AR_NEXT_DTIM,
7147 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7148 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7149
7150 REG_WRITE(ah, AR_SLEEP1,
7151 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7152 | AR_SLEEP1_ASSUME_DTIM);
7153
60b67f51 7154 if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
f078f209
LR
7155 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7156 else
7157 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7158
7159 REG_WRITE(ah, AR_SLEEP2,
7160 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7161
7162 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7163 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7164
7165 REG_SET_BIT(ah, AR_TIMER_MODE,
7166 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7167 AR_DTIM_TIMER_EN);
7168
7169}
7170
7171bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7172{
60b67f51 7173 if (entry < ah->ah_caps.keycache_size) {
f078f209
LR
7174 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7175 if (val & AR_KEYTABLE_VALID)
7176 return true;
7177 }
7178 return false;
7179}
7180
7181bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7182{
7183 u32 keyType;
7184
60b67f51 7185 if (entry >= ah->ah_caps.keycache_size) {
f078f209
LR
7186 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7187 "%s: entry %u out of range\n", __func__, entry);
7188 return false;
7189 }
7190 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7191
7192 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7193 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7194 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7195 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7196 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7197 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7198 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7199 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7200
7201 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7202 u16 micentry = entry + 64;
7203
7204 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7205 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7206 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7207 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7208
7209 }
7210
7211 if (ah->ah_curchan == NULL)
7212 return true;
7213
7214 return true;
7215}
7216
7217bool
7218ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7219 const u8 *mac)
7220{
7221 u32 macHi, macLo;
7222
60b67f51 7223 if (entry >= ah->ah_caps.keycache_size) {
f078f209
LR
7224 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7225 "%s: entry %u out of range\n", __func__, entry);
7226 return false;
7227 }
7228
7229 if (mac != NULL) {
7230 macHi = (mac[5] << 8) | mac[4];
7231 macLo = (mac[3] << 24) | (mac[2] << 16)
7232 | (mac[1] << 8) | mac[0];
7233 macLo >>= 1;
7234 macLo |= (macHi & 1) << 31;
7235 macHi >>= 1;
7236 } else {
7237 macLo = macHi = 0;
7238 }
7239 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7240 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7241
7242 return true;
7243}
7244
7245bool
7246ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7247 const struct ath9k_keyval *k,
7248 const u8 *mac, int xorKey)
7249{
60b67f51 7250 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7251 u32 key0, key1, key2, key3, key4;
7252 u32 keyType;
7253 u32 xorMask = xorKey ?
7254 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7255 | ATH9K_KEY_XOR) : 0;
7256 struct ath_hal_5416 *ahp = AH5416(ah);
7257
60b67f51 7258 if (entry >= pCap->keycache_size) {
f078f209
LR
7259 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260 "%s: entry %u out of range\n", __func__, entry);
7261 return false;
7262 }
7263 switch (k->kv_type) {
7264 case ATH9K_CIPHER_AES_OCB:
7265 keyType = AR_KEYTABLE_TYPE_AES;
7266 break;
7267 case ATH9K_CIPHER_AES_CCM:
60b67f51 7268 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
f078f209
LR
7269 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7270 "%s: AES-CCM not supported by "
7271 "mac rev 0x%x\n", __func__,
7272 ah->ah_macRev);
7273 return false;
7274 }
7275 keyType = AR_KEYTABLE_TYPE_CCM;
7276 break;
7277 case ATH9K_CIPHER_TKIP:
7278 keyType = AR_KEYTABLE_TYPE_TKIP;
7279 if (ATH9K_IS_MIC_ENABLED(ah)
60b67f51 7280 && entry + 64 >= pCap->keycache_size) {
f078f209
LR
7281 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7282 "%s: entry %u inappropriate for TKIP\n",
7283 __func__, entry);
7284 return false;
7285 }
7286 break;
7287 case ATH9K_CIPHER_WEP:
7288 if (k->kv_len < 40 / NBBY) {
7289 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7290 "%s: WEP key length %u too small\n",
7291 __func__, k->kv_len);
7292 return false;
7293 }
7294 if (k->kv_len <= 40 / NBBY)
7295 keyType = AR_KEYTABLE_TYPE_40;
7296 else if (k->kv_len <= 104 / NBBY)
7297 keyType = AR_KEYTABLE_TYPE_104;
7298 else
7299 keyType = AR_KEYTABLE_TYPE_128;
7300 break;
7301 case ATH9K_CIPHER_CLR:
7302 keyType = AR_KEYTABLE_TYPE_CLR;
7303 break;
7304 default:
7305 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7306 "%s: cipher %u not supported\n", __func__,
7307 k->kv_type);
7308 return false;
7309 }
7310
7311 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7312 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7313 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7314 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7315 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7316 if (k->kv_len <= 104 / NBBY)
7317 key4 &= 0xff;
7318
7319 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7320 u16 micentry = entry + 64;
7321
7322 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7323 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7324 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7325 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7326 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7327 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7328 (void) ath9k_hw_keysetmac(ah, entry, mac);
7329
7330 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7331 u32 mic0, mic1, mic2, mic3, mic4;
7332
7333 mic0 = get_unaligned_le32(k->kv_mic + 0);
7334 mic2 = get_unaligned_le32(k->kv_mic + 4);
7335 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7336 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7337 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7338 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7341 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7342 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7343 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7344 AR_KEYTABLE_TYPE_CLR);
7345
7346 } else {
7347 u32 mic0, mic2;
7348
7349 mic0 = get_unaligned_le32(k->kv_mic + 0);
7350 mic2 = get_unaligned_le32(k->kv_mic + 4);
7351 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7352 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7353 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7354 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7355 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7356 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7357 AR_KEYTABLE_TYPE_CLR);
7358 }
7359 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7360 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7361 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7362 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7363 } else {
7364 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7365 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7366 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7367 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7368 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7369 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7370
7371 (void) ath9k_hw_keysetmac(ah, entry, mac);
7372 }
7373
7374 if (ah->ah_curchan == NULL)
7375 return true;
7376
7377 return true;
7378}
7379
7380bool
7381ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7382{
7383 struct ath_hal_5416 *ahp = AH5416(ah);
7384 u32 txcfg, curLevel, newLevel;
7385 enum ath9k_int omask;
7386
7387 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7388 return false;
7389
7390 omask = ath9k_hw_set_interrupts(ah,
7391 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7392
7393 txcfg = REG_READ(ah, AR_TXCFG);
7394 curLevel = MS(txcfg, AR_FTRIG);
7395 newLevel = curLevel;
7396 if (bIncTrigLevel) {
7397 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7398 newLevel++;
7399 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7400 newLevel--;
7401 if (newLevel != curLevel)
7402 REG_WRITE(ah, AR_TXCFG,
7403 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7404
7405 ath9k_hw_set_interrupts(ah, omask);
7406
7407 ah->ah_txTrigLevel = newLevel;
7408
7409 return newLevel != curLevel;
7410}
7411
ea9880fb
S
7412bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7413 const struct ath9k_tx_queue_info *qinfo)
f078f209
LR
7414{
7415 u32 cw;
ea9880fb
S
7416 struct ath_hal_5416 *ahp = AH5416(ah);
7417 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7418 struct ath9k_tx_queue_info *qi;
f078f209 7419
ea9880fb
S
7420 if (q >= pCap->total_queues) {
7421 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7422 __func__, q);
7423 return false;
7424 }
7425
7426 qi = &ahp->ah_txq[q];
f078f209
LR
7427 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7428 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7429 __func__);
7430 return false;
7431 }
7432
7433 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7434
ea9880fb
S
7435 qi->tqi_ver = qinfo->tqi_ver;
7436 qi->tqi_subtype = qinfo->tqi_subtype;
7437 qi->tqi_qflags = qinfo->tqi_qflags;
7438 qi->tqi_priority = qinfo->tqi_priority;
7439 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7440 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
f078f209
LR
7441 else
7442 qi->tqi_aifs = INIT_AIFS;
ea9880fb
S
7443 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7444 cw = min(qinfo->tqi_cwmin, 1024U);
f078f209
LR
7445 qi->tqi_cwmin = 1;
7446 while (qi->tqi_cwmin < cw)
7447 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7448 } else
ea9880fb
S
7449 qi->tqi_cwmin = qinfo->tqi_cwmin;
7450 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7451 cw = min(qinfo->tqi_cwmax, 1024U);
f078f209
LR
7452 qi->tqi_cwmax = 1;
7453 while (qi->tqi_cwmax < cw)
7454 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7455 } else
7456 qi->tqi_cwmax = INIT_CWMAX;
7457
ea9880fb
S
7458 if (qinfo->tqi_shretry != 0)
7459 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
f078f209
LR
7460 else
7461 qi->tqi_shretry = INIT_SH_RETRY;
ea9880fb
S
7462 if (qinfo->tqi_lgretry != 0)
7463 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
f078f209
LR
7464 else
7465 qi->tqi_lgretry = INIT_LG_RETRY;
ea9880fb
S
7466 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7467 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7468 qi->tqi_burstTime = qinfo->tqi_burstTime;
7469 qi->tqi_readyTime = qinfo->tqi_readyTime;
f078f209 7470
ea9880fb 7471 switch (qinfo->tqi_subtype) {
f078f209
LR
7472 case ATH9K_WME_UPSD:
7473 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7474 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7475 break;
7476 default:
7477 break;
7478 }
7479 return true;
7480}
7481
ea9880fb
S
7482bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7483 struct ath9k_tx_queue_info *qinfo)
f078f209
LR
7484{
7485 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 7486 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
ea9880fb 7487 struct ath9k_tx_queue_info *qi;
f078f209 7488
60b67f51 7489 if (q >= pCap->total_queues) {
f078f209
LR
7490 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7491 __func__, q);
7492 return false;
7493 }
f078f209 7494
ea9880fb 7495 qi = &ahp->ah_txq[q];
f078f209
LR
7496 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7497 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7498 __func__);
7499 return false;
7500 }
7501
ea9880fb
S
7502 qinfo->tqi_qflags = qi->tqi_qflags;
7503 qinfo->tqi_ver = qi->tqi_ver;
7504 qinfo->tqi_subtype = qi->tqi_subtype;
7505 qinfo->tqi_qflags = qi->tqi_qflags;
7506 qinfo->tqi_priority = qi->tqi_priority;
7507 qinfo->tqi_aifs = qi->tqi_aifs;
7508 qinfo->tqi_cwmin = qi->tqi_cwmin;
7509 qinfo->tqi_cwmax = qi->tqi_cwmax;
7510 qinfo->tqi_shretry = qi->tqi_shretry;
7511 qinfo->tqi_lgretry = qi->tqi_lgretry;
7512 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7513 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7514 qinfo->tqi_burstTime = qi->tqi_burstTime;
7515 qinfo->tqi_readyTime = qi->tqi_readyTime;
f078f209
LR
7516
7517 return true;
7518}
7519
f078f209
LR
7520int
7521ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
ea9880fb 7522 const struct ath9k_tx_queue_info *qinfo)
f078f209
LR
7523{
7524 struct ath_hal_5416 *ahp = AH5416(ah);
7525 struct ath9k_tx_queue_info *qi;
60b67f51 7526 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7527 int q;
7528
7529 switch (type) {
7530 case ATH9K_TX_QUEUE_BEACON:
60b67f51 7531 q = pCap->total_queues - 1;
f078f209
LR
7532 break;
7533 case ATH9K_TX_QUEUE_CAB:
60b67f51 7534 q = pCap->total_queues - 2;
f078f209
LR
7535 break;
7536 case ATH9K_TX_QUEUE_PSPOLL:
7537 q = 1;
7538 break;
7539 case ATH9K_TX_QUEUE_UAPSD:
60b67f51 7540 q = pCap->total_queues - 3;
f078f209
LR
7541 break;
7542 case ATH9K_TX_QUEUE_DATA:
60b67f51 7543 for (q = 0; q < pCap->total_queues; q++)
f078f209
LR
7544 if (ahp->ah_txq[q].tqi_type ==
7545 ATH9K_TX_QUEUE_INACTIVE)
7546 break;
60b67f51 7547 if (q == pCap->total_queues) {
f078f209
LR
7548 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7549 "%s: no available tx queue\n", __func__);
7550 return -1;
7551 }
7552 break;
7553 default:
7554 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7555 __func__, type);
7556 return -1;
7557 }
7558
7559 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7560
7561 qi = &ahp->ah_txq[q];
7562 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7563 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7564 "%s: tx queue %u already active\n", __func__, q);
7565 return -1;
7566 }
7567 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7568 qi->tqi_type = type;
ea9880fb 7569 if (qinfo == NULL) {
f078f209
LR
7570 qi->tqi_qflags =
7571 TXQ_FLAG_TXOKINT_ENABLE
7572 | TXQ_FLAG_TXERRINT_ENABLE
7573 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7574 qi->tqi_aifs = INIT_AIFS;
7575 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7576 qi->tqi_cwmax = INIT_CWMAX;
7577 qi->tqi_shretry = INIT_SH_RETRY;
7578 qi->tqi_lgretry = INIT_LG_RETRY;
7579 qi->tqi_physCompBuf = 0;
7580 } else {
ea9880fb
S
7581 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7582 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
f078f209
LR
7583 }
7584
7585 return q;
7586}
7587
7588static void
7589ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7590 struct ath9k_tx_queue_info *qi)
7591{
7592 struct ath_hal_5416 *ahp = AH5416(ah);
7593
7594 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7595 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7596 __func__, ahp->ah_txOkInterruptMask,
7597 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7598 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7599
7600 REG_WRITE(ah, AR_IMR_S0,
7601 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7602 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7603 REG_WRITE(ah, AR_IMR_S1,
7604 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7605 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7606 REG_RMW_FIELD(ah, AR_IMR_S2,
7607 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7608}
7609
7610bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7611{
7612 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 7613 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7614 struct ath9k_tx_queue_info *qi;
7615
60b67f51 7616 if (q >= pCap->total_queues) {
f078f209
LR
7617 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7618 __func__, q);
7619 return false;
7620 }
7621 qi = &ahp->ah_txq[q];
7622 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7623 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7624 __func__, q);
7625 return false;
7626 }
7627
7628 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7629 __func__, q);
7630
7631 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7632 ahp->ah_txOkInterruptMask &= ~(1 << q);
7633 ahp->ah_txErrInterruptMask &= ~(1 << q);
7634 ahp->ah_txDescInterruptMask &= ~(1 << q);
7635 ahp->ah_txEolInterruptMask &= ~(1 << q);
7636 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7637 ath9k_hw_set_txq_interrupts(ah, qi);
7638
7639 return true;
7640}
7641
7642bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7643{
7644 struct ath_hal_5416 *ahp = AH5416(ah);
60b67f51 7645 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
7646 struct ath9k_channel *chan = ah->ah_curchan;
7647 struct ath9k_tx_queue_info *qi;
7648 u32 cwMin, chanCwMin, value;
7649
60b67f51 7650 if (q >= pCap->total_queues) {
f078f209
LR
7651 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7652 __func__, q);
7653 return false;
7654 }
7655 qi = &ahp->ah_txq[q];
7656 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7657 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7658 __func__, q);
7659 return true;
7660 }
7661
7662 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7663
7664 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7665 if (chan && IS_CHAN_B(chan))
7666 chanCwMin = INIT_CWMIN_11B;
7667 else
7668 chanCwMin = INIT_CWMIN;
7669
7670 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7671 } else
7672 cwMin = qi->tqi_cwmin;
7673
7674 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7675 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7676 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7677
7678 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7679 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7680 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7681 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7682 );
7683
7684 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7685 REG_WRITE(ah, AR_DMISC(q),
7686 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7687
7688 if (qi->tqi_cbrPeriod) {
7689 REG_WRITE(ah, AR_QCBRCFG(q),
7690 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7691 | SM(qi->tqi_cbrOverflowLimit,
7692 AR_Q_CBRCFG_OVF_THRESH));
7693 REG_WRITE(ah, AR_QMISC(q),
7694 REG_READ(ah,
7695 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7696 tqi_cbrOverflowLimit
7697 ?
7698 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7699 :
7700 0));
7701 }
7702 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7703 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7704 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7705 AR_Q_RDYTIMECFG_EN);
7706 }
7707
7708 REG_WRITE(ah, AR_DCHNTIME(q),
7709 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7710 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7711
7712 if (qi->tqi_burstTime
7713 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7714 REG_WRITE(ah, AR_QMISC(q),
7715 REG_READ(ah,
7716 AR_QMISC(q)) |
7717 AR_Q_MISC_RDYTIME_EXP_POLICY);
7718
7719 }
7720
7721 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7722 REG_WRITE(ah, AR_DMISC(q),
7723 REG_READ(ah, AR_DMISC(q)) |
7724 AR_D_MISC_POST_FR_BKOFF_DIS);
7725 }
7726 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7727 REG_WRITE(ah, AR_DMISC(q),
7728 REG_READ(ah, AR_DMISC(q)) |
7729 AR_D_MISC_FRAG_BKOFF_EN);
7730 }
7731 switch (qi->tqi_type) {
7732 case ATH9K_TX_QUEUE_BEACON:
7733 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7734 | AR_Q_MISC_FSP_DBA_GATED
7735 | AR_Q_MISC_BEACON_USE
7736 | AR_Q_MISC_CBR_INCR_DIS1);
7737
7738 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7739 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7740 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7741 | AR_D_MISC_BEACON_USE
7742 | AR_D_MISC_POST_FR_BKOFF_DIS);
7743 break;
7744 case ATH9K_TX_QUEUE_CAB:
7745 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7746 | AR_Q_MISC_FSP_DBA_GATED
7747 | AR_Q_MISC_CBR_INCR_DIS1
7748 | AR_Q_MISC_CBR_INCR_DIS0);
7749 value = (qi->tqi_readyTime
60b67f51
S
7750 - (ah->ah_config.sw_beacon_response_time -
7751 ah->ah_config.dma_beacon_response_time)
f078f209 7752 -
60b67f51 7753 ah->ah_config.additional_swba_backoff) *
f078f209
LR
7754 1024;
7755 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7756 value | AR_Q_RDYTIMECFG_EN);
7757 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7758 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7759 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7760 break;
7761 case ATH9K_TX_QUEUE_PSPOLL:
7762 REG_WRITE(ah, AR_QMISC(q),
7763 REG_READ(ah,
7764 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7765 break;
7766 case ATH9K_TX_QUEUE_UAPSD:
7767 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7768 | AR_D_MISC_POST_FR_BKOFF_DIS);
7769 break;
7770 default:
7771 break;
7772 }
7773
7774 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7775 REG_WRITE(ah, AR_DMISC(q),
7776 REG_READ(ah, AR_DMISC(q)) |
7777 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7778 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7779 AR_D_MISC_POST_FR_BKOFF_DIS);
7780 }
7781
7782 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7783 ahp->ah_txOkInterruptMask |= 1 << q;
7784 else
7785 ahp->ah_txOkInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7787 ahp->ah_txErrInterruptMask |= 1 << q;
7788 else
7789 ahp->ah_txErrInterruptMask &= ~(1 << q);
7790 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7791 ahp->ah_txDescInterruptMask |= 1 << q;
7792 else
7793 ahp->ah_txDescInterruptMask &= ~(1 << q);
7794 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7795 ahp->ah_txEolInterruptMask |= 1 << q;
7796 else
7797 ahp->ah_txEolInterruptMask &= ~(1 << q);
7798 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7799 ahp->ah_txUrnInterruptMask |= 1 << q;
7800 else
7801 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7802 ath9k_hw_set_txq_interrupts(ah, qi);
7803
7804 return true;
7805}
7806
7807void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7808{
7809 struct ath_hal_5416 *ahp = AH5416(ah);
7810 *txqs &= ahp->ah_intrTxqs;
7811 ahp->ah_intrTxqs &= ~(*txqs);
7812}
7813
7814bool
7815ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7816 u32 segLen, bool firstSeg,
7817 bool lastSeg, const struct ath_desc *ds0)
7818{
7819 struct ar5416_desc *ads = AR5416DESC(ds);
7820
7821 if (firstSeg) {
7822 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7823 } else if (lastSeg) {
7824 ads->ds_ctl0 = 0;
7825 ads->ds_ctl1 = segLen;
7826 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7827 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7828 } else {
7829 ads->ds_ctl0 = 0;
7830 ads->ds_ctl1 = segLen | AR_TxMore;
7831 ads->ds_ctl2 = 0;
7832 ads->ds_ctl3 = 0;
7833 }
7834 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7835 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7836 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7837 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7838 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7839 return true;
7840}
7841
7842void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7843{
7844 struct ar5416_desc *ads = AR5416DESC(ds);
7845
7846 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7847 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7848 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7849 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7850 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7851}
7852
7853int
7854ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7855{
7856 struct ar5416_desc *ads = AR5416DESC(ds);
7857
7858 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7859 return -EINPROGRESS;
7860
7861 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7862 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7863 ds->ds_txstat.ts_status = 0;
7864 ds->ds_txstat.ts_flags = 0;
7865
7866 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7867 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7868 if (ads->ds_txstatus1 & AR_Filtered)
7869 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7870 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7871 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7872 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7873 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7874 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7875 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7876
7877 if (ads->ds_txstatus1 & AR_DescCfgErr)
7878 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7879 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7880 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7881 ath9k_hw_updatetxtriglevel(ah, true);
7882 }
7883 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7884 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7885 ath9k_hw_updatetxtriglevel(ah, true);
7886 }
7887 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7888 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7889 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7890 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7891 }
7892
7893 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7894 switch (ds->ds_txstat.ts_rateindex) {
7895 case 0:
7896 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7897 break;
7898 case 1:
7899 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7900 break;
7901 case 2:
7902 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7903 break;
7904 case 3:
7905 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7906 break;
7907 }
7908
7909 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7910 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7911 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7912 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7913 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7914 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7915 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7916 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7917 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7918 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7919 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7920 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7921 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7922 ds->ds_txstat.ts_antenna = 1;
7923
7924 return 0;
7925}
7926
7927void
7928ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7929 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7930 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7931{
7932 struct ar5416_desc *ads = AR5416DESC(ds);
7933 struct ath_hal_5416 *ahp = AH5416(ah);
7934
7935 txPower += ahp->ah_txPowerIndexOffset;
7936 if (txPower > 63)
7937 txPower = 63;
7938
7939 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7940 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7941 | SM(txPower, AR_XmitPower)
7942 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7943 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7944 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7945 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7946
7947 ads->ds_ctl1 =
7948 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7949 | SM(type, AR_FrameType)
7950 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7951 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7952 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7953
7954 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7955
7956 if (AR_SREV_9285(ah)) {
7957
7958 ads->ds_ctl8 = 0;
7959 ads->ds_ctl9 = 0;
7960 ads->ds_ctl10 = 0;
7961 ads->ds_ctl11 = 0;
7962 }
7963}
7964
7965void
7966ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7967 struct ath_desc *lastds,
7968 u32 durUpdateEn, u32 rtsctsRate,
7969 u32 rtsctsDuration,
7970 struct ath9k_11n_rate_series series[],
7971 u32 nseries, u32 flags)
7972{
7973 struct ar5416_desc *ads = AR5416DESC(ds);
7974 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7975 u32 ds_ctl0;
7976
7977 (void) nseries;
7978 (void) rtsctsDuration;
7979
7980 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7981 ds_ctl0 = ads->ds_ctl0;
7982
7983 if (flags & ATH9K_TXDESC_RTSENA) {
7984 ds_ctl0 &= ~AR_CTSEnable;
7985 ds_ctl0 |= AR_RTSEnable;
7986 } else {
7987 ds_ctl0 &= ~AR_RTSEnable;
7988 ds_ctl0 |= AR_CTSEnable;
7989 }
7990
7991 ads->ds_ctl0 = ds_ctl0;
7992 } else {
7993 ads->ds_ctl0 =
7994 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7995 }
7996
7997 ads->ds_ctl2 = set11nTries(series, 0)
7998 | set11nTries(series, 1)
7999 | set11nTries(series, 2)
8000 | set11nTries(series, 3)
8001 | (durUpdateEn ? AR_DurUpdateEna : 0)
8002 | SM(0, AR_BurstDur);
8003
8004 ads->ds_ctl3 = set11nRate(series, 0)
8005 | set11nRate(series, 1)
8006 | set11nRate(series, 2)
8007 | set11nRate(series, 3);
8008
8009 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8010 | set11nPktDurRTSCTS(series, 1);
8011
8012 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8013 | set11nPktDurRTSCTS(series, 3);
8014
8015 ads->ds_ctl7 = set11nRateFlags(series, 0)
8016 | set11nRateFlags(series, 1)
8017 | set11nRateFlags(series, 2)
8018 | set11nRateFlags(series, 3)
8019 | SM(rtsctsRate, AR_RTSCTSRate);
8020 last_ads->ds_ctl2 = ads->ds_ctl2;
8021 last_ads->ds_ctl3 = ads->ds_ctl3;
8022}
8023
8024void
8025ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8026 u32 aggrLen)
8027{
8028 struct ar5416_desc *ads = AR5416DESC(ds);
8029
8030 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8031
8032 ads->ds_ctl6 &= ~AR_AggrLen;
8033 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8034}
8035
8036void
8037ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8038 u32 numDelims)
8039{
8040 struct ar5416_desc *ads = AR5416DESC(ds);
8041 unsigned int ctl6;
8042
8043 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8044
8045 ctl6 = ads->ds_ctl6;
8046 ctl6 &= ~AR_PadDelim;
8047 ctl6 |= SM(numDelims, AR_PadDelim);
8048 ads->ds_ctl6 = ctl6;
8049}
8050
8051void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8052{
8053 struct ar5416_desc *ads = AR5416DESC(ds);
8054
8055 ads->ds_ctl1 |= AR_IsAggr;
8056 ads->ds_ctl1 &= ~AR_MoreAggr;
8057 ads->ds_ctl6 &= ~AR_PadDelim;
8058}
8059
8060void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8061{
8062 struct ar5416_desc *ads = AR5416DESC(ds);
8063
8064 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8065}
8066
8067void
8068ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8069 u32 burstDuration)
8070{
8071 struct ar5416_desc *ads = AR5416DESC(ds);
8072
8073 ads->ds_ctl2 &= ~AR_BurstDur;
8074 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8075}
8076
8077void
8078ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8079 u32 vmf)
8080{
8081 struct ar5416_desc *ads = AR5416DESC(ds);
8082
8083 if (vmf)
8084 ads->ds_ctl0 |= AR_VirtMoreFrag;
8085 else
8086 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8087}
8088
8089void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8090{
8091 REG_WRITE(ah, AR_RXDP, rxdp);
8092}
8093
8094void ath9k_hw_rxena(struct ath_hal *ah)
8095{
8096 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8097}
8098
8099bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8100{
8101 if (set) {
8102
8103 REG_SET_BIT(ah, AR_DIAG_SW,
8104 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8105
8106 if (!ath9k_hw_wait
8107 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8108 u32 reg;
8109
8110 REG_CLR_BIT(ah, AR_DIAG_SW,
8111 (AR_DIAG_RX_DIS |
8112 AR_DIAG_RX_ABORT));
8113
8114 reg = REG_READ(ah, AR_OBS_BUS_1);
8115 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8116 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8117 __func__, reg);
8118
8119 return false;
8120 }
8121 } else {
8122 REG_CLR_BIT(ah, AR_DIAG_SW,
8123 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8124 }
8125
8126 return true;
8127}
8128
8129void
8130ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8131 u32 filter1)
8132{
8133 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8134 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8135}
8136
8137bool
8138ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8139 u32 size, u32 flags)
8140{
8141 struct ar5416_desc *ads = AR5416DESC(ds);
60b67f51 8142 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
f078f209
LR
8143
8144 ads->ds_ctl1 = size & AR_BufLen;
8145 if (flags & ATH9K_RXDESC_INTREQ)
8146 ads->ds_ctl1 |= AR_RxIntrReq;
8147
8148 ads->ds_rxstatus8 &= ~AR_RxDone;
60b67f51 8149 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
f078f209
LR
8150 memset(&(ads->u), 0, sizeof(ads->u));
8151 return true;
8152}
8153
8154int
8155ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8156 u32 pa, struct ath_desc *nds, u64 tsf)
8157{
8158 struct ar5416_desc ads;
8159 struct ar5416_desc *adsp = AR5416DESC(ds);
8160
8161 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8162 return -EINPROGRESS;
8163
8164 ads.u.rx = adsp->u.rx;
8165
8166 ds->ds_rxstat.rs_status = 0;
8167 ds->ds_rxstat.rs_flags = 0;
8168
8169 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8170 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8171
8172 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8173 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8174 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8175 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8176 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8177 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8178 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8179 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8180 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8181 else
8182 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8183
8184 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8185 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8186
8187 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8188 ds->ds_rxstat.rs_moreaggr =
8189 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8190 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8191 ds->ds_rxstat.rs_flags =
8192 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8193 ds->ds_rxstat.rs_flags |=
8194 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8195
8196 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8197 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8198 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8199 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8200 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8201 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8202
8203 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8204
8205 if (ads.ds_rxstatus8 & AR_CRCErr)
8206 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8207 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8208 u32 phyerr;
8209
8210 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8211 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8212 ds->ds_rxstat.rs_phyerr = phyerr;
8213 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8214 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8215 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8216 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8217 }
8218
8219 return 0;
8220}
8221
8222static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8223 struct ath9k_rate_table *rt)
8224{
8225 int i;
8226
8227 if (rt->rateCodeToIndex[0] != 0)
8228 return;
8229 for (i = 0; i < 256; i++)
8230 rt->rateCodeToIndex[i] = (u8) -1;
8231 for (i = 0; i < rt->rateCount; i++) {
8232 u8 code = rt->info[i].rateCode;
8233 u8 cix = rt->info[i].controlRate;
8234
8235 rt->rateCodeToIndex[code] = i;
8236 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8237
8238 rt->info[i].lpAckDuration =
8239 ath9k_hw_computetxtime(ah, rt,
8240 WLAN_CTRL_FRAME_SIZE,
8241 cix,
8242 false);
8243 rt->info[i].spAckDuration =
8244 ath9k_hw_computetxtime(ah, rt,
8245 WLAN_CTRL_FRAME_SIZE,
8246 cix,
8247 true);
8248 }
8249}
8250
8251const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8252 u32 mode)
8253{
8254 struct ath9k_rate_table *rt;
8255 switch (mode) {
86b89eed 8256 case ATH9K_MODE_11A:
f078f209
LR
8257 rt = &ar5416_11a_table;
8258 break;
86b89eed 8259 case ATH9K_MODE_11B:
f078f209
LR
8260 rt = &ar5416_11b_table;
8261 break;
86b89eed 8262 case ATH9K_MODE_11G:
f078f209
LR
8263 rt = &ar5416_11g_table;
8264 break;
86b89eed
S
8265 case ATH9K_MODE_11NG_HT20:
8266 case ATH9K_MODE_11NG_HT40PLUS:
8267 case ATH9K_MODE_11NG_HT40MINUS:
f078f209
LR
8268 rt = &ar5416_11ng_table;
8269 break;
86b89eed
S
8270 case ATH9K_MODE_11NA_HT20:
8271 case ATH9K_MODE_11NA_HT40PLUS:
8272 case ATH9K_MODE_11NA_HT40MINUS:
f078f209
LR
8273 rt = &ar5416_11na_table;
8274 break;
8275 default:
8276 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8277 __func__, mode);
8278 return NULL;
8279 }
8280 ath9k_hw_setup_rate_table(ah, rt);
8281 return rt;
8282}
8283
8284static const char *ath9k_hw_devname(u16 devid)
8285{
8286 switch (devid) {
8287 case AR5416_DEVID_PCI:
8288 case AR5416_DEVID_PCIE:
8289 return "Atheros 5416";
8290 case AR9160_DEVID_PCI:
8291 return "Atheros 9160";
8292 case AR9280_DEVID_PCI:
8293 case AR9280_DEVID_PCIE:
8294 return "Atheros 9280";
8295 }
8296 return NULL;
8297}
8298
8299const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8300{
8301 return vendorid == ATHEROS_VENDOR_ID ?
8302 ath9k_hw_devname(devid) : NULL;
8303}
8304
8305struct ath_hal *ath9k_hw_attach(u16 devid,
8306 struct ath_softc *sc,
8307 void __iomem *mem,
8308 int *error)
8309{
8310 struct ath_hal *ah = NULL;
8311
8312 switch (devid) {
8313 case AR5416_DEVID_PCI:
8314 case AR5416_DEVID_PCIE:
8315 case AR9160_DEVID_PCI:
8316 case AR9280_DEVID_PCI:
8317 case AR9280_DEVID_PCIE:
8318 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8319 break;
8320 default:
8321 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8322 "devid=0x%x not supported.\n", devid);
8323 ah = NULL;
8324 *error = -ENXIO;
8325 break;
8326 }
8327 if (ah != NULL) {
8328 ah->ah_devid = ah->ah_devid;
8329 ah->ah_subvendorid = ah->ah_subvendorid;
8330 ah->ah_macVersion = ah->ah_macVersion;
8331 ah->ah_macRev = ah->ah_macRev;
8332 ah->ah_phyRev = ah->ah_phyRev;
8333 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8334 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8335 }
8336 return ah;
8337}
8338
8339u16
8340ath9k_hw_computetxtime(struct ath_hal *ah,
8341 const struct ath9k_rate_table *rates,
8342 u32 frameLen, u16 rateix,
8343 bool shortPreamble)
8344{
8345 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8346 u32 kbps;
8347
8348 kbps = rates->info[rateix].rateKbps;
8349
8350 if (kbps == 0)
8351 return 0;
8352 switch (rates->info[rateix].phy) {
8353
8354 case PHY_CCK:
8355 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8356 if (shortPreamble && rates->info[rateix].shortPreamble)
8357 phyTime >>= 1;
8358 numBits = frameLen << 3;
8359 txTime = CCK_SIFS_TIME + phyTime
8360 + ((numBits * 1000) / kbps);
8361 break;
8362 case PHY_OFDM:
8363 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8364 bitsPerSymbol =
8365 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8366
8367 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8368 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8369 txTime = OFDM_SIFS_TIME_QUARTER
8370 + OFDM_PREAMBLE_TIME_QUARTER
8371 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8372 } else if (ah->ah_curchan &&
8373 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8374 bitsPerSymbol =
8375 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8376
8377 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8378 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8379 txTime = OFDM_SIFS_TIME_HALF +
8380 OFDM_PREAMBLE_TIME_HALF
8381 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8382 } else {
8383 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8384
8385 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8386 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8387 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8388 + (numSymbols * OFDM_SYMBOL_TIME);
8389 }
8390 break;
8391
8392 default:
8393 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8394 "%s: unknown phy %u (rate ix %u)\n", __func__,
8395 rates->info[rateix].phy, rateix);
8396 txTime = 0;
8397 break;
8398 }
8399 return txTime;
8400}
8401
8402u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8403{
8404 if (flags & CHANNEL_2GHZ) {
8405 if (freq == 2484)
8406 return 14;
8407 if (freq < 2484)
8408 return (freq - 2407) / 5;
8409 else
8410 return 15 + ((freq - 2512) / 20);
8411 } else if (flags & CHANNEL_5GHZ) {
8412 if (ath9k_regd_is_public_safety_sku(ah) &&
8413 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8414 return ((freq * 10) +
8415 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8416 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8417 return (freq - 4000) / 5;
8418 } else {
8419 return (freq - 5000) / 5;
8420 }
8421 } else {
8422 if (freq == 2484)
8423 return 14;
8424 if (freq < 2484)
8425 return (freq - 2407) / 5;
8426 if (freq < 5000) {
8427 if (ath9k_regd_is_public_safety_sku(ah)
8428 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8429 return ((freq * 10) +
8430 (((freq % 5) ==
8431 2) ? 5 : 0) - 49400) / 5;
8432 } else if (freq > 4900) {
8433 return (freq - 4000) / 5;
8434 } else {
8435 return 15 + ((freq - 2512) / 20);
8436 }
8437 }
8438 return (freq - 5000) / 5;
8439 }
8440}
8441
8442int16_t
8443ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8444{
8445 struct ath9k_channel *ichan;
8446
8447 ichan = ath9k_regd_check_channel(ah, chan);
8448 if (ichan == NULL) {
8449 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8450 "%s: invalid channel %u/0x%x; no mapping\n",
8451 __func__, chan->channel, chan->channelFlags);
8452 return 0;
8453 }
8454 if (ichan->rawNoiseFloor == 0) {
8455 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8456 return NOISE_FLOOR[mode];
8457 } else
8458 return ichan->rawNoiseFloor;
8459}
8460
8461bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8462{
8463 struct ath_hal_5416 *ahp = AH5416(ah);
8464
8465 if (setting)
8466 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8467 else
8468 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8469 return true;
8470}
8471
8472bool ath9k_hw_phycounters(struct ath_hal *ah)
8473{
8474 struct ath_hal_5416 *ahp = AH5416(ah);
8475
8476 return ahp->ah_hasHwPhyCounters ? true : false;
8477}
8478
8479u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8480{
8481 return REG_READ(ah, AR_QTXDP(q));
8482}
8483
8484bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8485 u32 txdp)
8486{
8487 REG_WRITE(ah, AR_QTXDP(q), txdp);
8488
8489 return true;
8490}
8491
8492bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8493{
8494 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8495
8496 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8497
8498 return true;
8499}
8500
8501u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8502{
8503 u32 npend;
8504
8505 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8506 if (npend == 0) {
8507
8508 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8509 npend = 1;
8510 }
8511 return npend;
8512}
8513
8514bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8515{
8516 u32 wait;
8517
8518 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8519
8520 for (wait = 1000; wait != 0; wait--) {
8521 if (ath9k_hw_numtxpending(ah, q) == 0)
8522 break;
8523 udelay(100);
8524 }
8525
8526 if (ath9k_hw_numtxpending(ah, q)) {
8527 u32 tsfLow, j;
8528
8529 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8530 "%s: Num of pending TX Frames %d on Q %d\n",
8531 __func__, ath9k_hw_numtxpending(ah, q), q);
8532
8533 for (j = 0; j < 2; j++) {
8534 tsfLow = REG_READ(ah, AR_TSF_L32);
8535 REG_WRITE(ah, AR_QUIET2,
8536 SM(10, AR_QUIET2_QUIET_DUR));
8537 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8538 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8539 REG_SET_BIT(ah, AR_TIMER_MODE,
8540 AR_QUIET_TIMER_EN);
8541
8542 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8543 (tsfLow >> 10)) {
8544 break;
8545 }
8546 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8547 "%s: TSF have moved while trying to set "
8548 "quiet time TSF: 0x%08x\n",
8549 __func__, tsfLow);
8550 }
8551
8552 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8553
8554 udelay(200);
8555 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8556
8557 wait = 1000;
8558
8559 while (ath9k_hw_numtxpending(ah, q)) {
8560 if ((--wait) == 0) {
8561 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8562 "%s: Failed to stop Tx DMA in 100 "
8563 "msec after killing last frame\n",
8564 __func__);
8565 break;
8566 }
8567 udelay(100);
8568 }
8569
8570 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8571 }
8572
8573 REG_WRITE(ah, AR_Q_TXD, 0);
8574 return wait != 0;
8575}
This page took 0.36294 seconds and 5 git commands to generate.