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