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