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