aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c744
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h104
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h313
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c247
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h38
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c382
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c19
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h35
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h88
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c346
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c60
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c17
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h38
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c38
19 files changed, 1801 insertions, 693 deletions
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 090dc6d268a3..cc09595b781a 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -12,5 +12,6 @@ ath5k-y += attach.o
12ath5k-y += base.o 12ath5k-y += base.o
13ath5k-y += led.o 13ath5k-y += led.o
14ath5k-y += rfkill.o 14ath5k-y += rfkill.o
15ath5k-y += ani.o
15ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o 16ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
16obj-$(CONFIG_ATH5K) += ath5k.o 17obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
new file mode 100644
index 000000000000..584a32859bdb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -0,0 +1,744 @@
1/*
2 * Copyright (C) 2010 Bruno Randolf <br1@einfach.org>
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 "ath5k.h"
18#include "base.h"
19#include "reg.h"
20#include "debug.h"
21#include "ani.h"
22
23/**
24 * DOC: Basic ANI Operation
25 *
26 * Adaptive Noise Immunity (ANI) controls five noise immunity parameters
27 * depending on the amount of interference in the environment, increasing
28 * or reducing sensitivity as necessary.
29 *
30 * The parameters are:
31 * - "noise immunity"
32 * - "spur immunity"
33 * - "firstep level"
34 * - "OFDM weak signal detection"
35 * - "CCK weak signal detection"
36 *
37 * Basically we look at the amount of ODFM and CCK timing errors we get and then
38 * raise or lower immunity accordingly by setting one or more of these
39 * parameters.
40 * Newer chipsets have PHY error counters in hardware which will generate a MIB
41 * interrupt when they overflow. Older hardware has too enable PHY error frames
42 * by setting a RX flag and then count every single PHY error. When a specified
43 * threshold of errors has been reached we will raise immunity.
44 * Also we regularly check the amount of errors and lower or raise immunity as
45 * necessary.
46 */
47
48
49/*** ANI parameter control ***/
50
51/**
52 * ath5k_ani_set_noise_immunity_level() - Set noise immunity level
53 *
54 * @level: level between 0 and @ATH5K_ANI_MAX_NOISE_IMM_LVL
55 */
56void
57ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
58{
59 /* TODO:
60 * ANI documents suggest the following five levels to use, but the HAL
61 * and ath9k use only use the last two levels, making this
62 * essentially an on/off option. There *may* be a reason for this (???),
63 * so i stick with the HAL version for now...
64 */
65#if 0
66 const s8 hi[] = { -18, -18, -16, -14, -12 };
67 const s8 lo[] = { -52, -56, -60, -64, -70 };
68 const s8 sz[] = { -34, -41, -48, -55, -62 };
69 const s8 fr[] = { -70, -72, -75, -78, -80 };
70#else
71 const s8 sz[] = { -55, -62 };
72 const s8 lo[] = { -64, -70 };
73 const s8 hi[] = { -14, -12 };
74 const s8 fr[] = { -78, -80 };
75#endif
76 if (level < 0 || level > ARRAY_SIZE(sz)) {
77 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
78 "level out of range %d", level);
79 return;
80 }
81
82 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
83 AR5K_PHY_DESIRED_SIZE_TOT, sz[level]);
84 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE,
85 AR5K_PHY_AGCCOARSE_LO, lo[level]);
86 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE,
87 AR5K_PHY_AGCCOARSE_HI, hi[level]);
88 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
89 AR5K_PHY_SIG_FIRPWR, fr[level]);
90
91 ah->ah_sc->ani_state.noise_imm_level = level;
92 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
93}
94
95
96/**
97 * ath5k_ani_set_spur_immunity_level() - Set spur immunity level
98 *
99 * @level: level between 0 and @max_spur_level (the maximum level is dependent
100 * on the chip revision).
101 */
102void
103ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
104{
105 const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
106
107 if (level < 0 || level > ARRAY_SIZE(val) ||
108 level > ah->ah_sc->ani_state.max_spur_level) {
109 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
110 "level out of range %d", level);
111 return;
112 }
113
114 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
115 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]);
116
117 ah->ah_sc->ani_state.spur_level = level;
118 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
119}
120
121
122/**
123 * ath5k_ani_set_firstep_level() - Set "firstep" level
124 *
125 * @level: level between 0 and @ATH5K_ANI_MAX_FIRSTEP_LVL
126 */
127void
128ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
129{
130 const int val[] = { 0, 4, 8 };
131
132 if (level < 0 || level > ARRAY_SIZE(val)) {
133 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
134 "level out of range %d", level);
135 return;
136 }
137
138 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
139 AR5K_PHY_SIG_FIRSTEP, val[level]);
140
141 ah->ah_sc->ani_state.firstep_level = level;
142 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
143}
144
145
146/**
147 * ath5k_ani_set_ofdm_weak_signal_detection() - Control OFDM weak signal
148 * detection
149 *
150 * @on: turn on or off
151 */
152void
153ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
154{
155 const int m1l[] = { 127, 50 };
156 const int m2l[] = { 127, 40 };
157 const int m1[] = { 127, 0x4d };
158 const int m2[] = { 127, 0x40 };
159 const int m2cnt[] = { 31, 16 };
160 const int m2lcnt[] = { 63, 48 };
161
162 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
163 AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]);
164 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
165 AR5K_PHY_WEAK_OFDM_LOW_THR_M2, m2l[on]);
166 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
167 AR5K_PHY_WEAK_OFDM_HIGH_THR_M1, m1[on]);
168 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
169 AR5K_PHY_WEAK_OFDM_HIGH_THR_M2, m2[on]);
170 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
171 AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT, m2cnt[on]);
172 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
173 AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT, m2lcnt[on]);
174
175 if (on)
176 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
177 AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
178 else
179 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
180 AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
181
182 ah->ah_sc->ani_state.ofdm_weak_sig = on;
183 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
184 on ? "on" : "off");
185}
186
187
188/**
189 * ath5k_ani_set_cck_weak_signal_detection() - control CCK weak signal detection
190 *
191 * @on: turn on or off
192 */
193void
194ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
195{
196 const int val[] = { 8, 6 };
197 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
198 AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
199 ah->ah_sc->ani_state.cck_weak_sig = on;
200 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
201 on ? "on" : "off");
202}
203
204
205/*** ANI algorithm ***/
206
207/**
208 * ath5k_ani_raise_immunity() - Increase noise immunity
209 *
210 * @ofdm_trigger: If this is true we are called because of too many OFDM errors,
211 * the algorithm will tune more parameters then.
212 *
213 * Try to raise noise immunity (=decrease sensitivity) in several steps
214 * depending on the average RSSI of the beacons we received.
215 */
216static void
217ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
218 bool ofdm_trigger)
219{
220 int rssi = ah->ah_beacon_rssi_avg.avg;
221
222 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
223 ofdm_trigger ? "ODFM" : "CCK");
224
225 /* first: raise noise immunity */
226 if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) {
227 ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1);
228 return;
229 }
230
231 /* only OFDM: raise spur immunity level */
232 if (ofdm_trigger &&
233 as->spur_level < ah->ah_sc->ani_state.max_spur_level) {
234 ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
235 return;
236 }
237
238 /* AP mode */
239 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
240 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
241 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
242 return;
243 }
244
245 /* STA and IBSS mode */
246
247 /* TODO: for IBSS mode it would be better to keep a beacon RSSI average
248 * per each neighbour node and use the minimum of these, to make sure we
249 * don't shut out a remote node by raising immunity too high. */
250
251 if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
252 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
253 "beacon RSSI high");
254 /* only OFDM: beacon RSSI is high, we can disable ODFM weak
255 * signal detection */
256 if (ofdm_trigger && as->ofdm_weak_sig == true) {
257 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
258 ath5k_ani_set_spur_immunity_level(ah, 0);
259 return;
260 }
261 /* as a last resort or CCK: raise firstep level */
262 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) {
263 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
264 return;
265 }
266 } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
267 /* beacon RSSI in mid range, we need OFDM weak signal detect,
268 * but can raise firstep level */
269 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
270 "beacon RSSI mid");
271 if (ofdm_trigger && as->ofdm_weak_sig == false)
272 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
273 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
274 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
275 return;
276 } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
277 /* beacon RSSI is low. in B/G mode turn of OFDM weak signal
278 * detect and zero firstep level to maximize CCK sensitivity */
279 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
280 "beacon RSSI low, 2GHz");
281 if (ofdm_trigger && as->ofdm_weak_sig == true)
282 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
283 if (as->firstep_level > 0)
284 ath5k_ani_set_firstep_level(ah, 0);
285 return;
286 }
287
288 /* TODO: why not?:
289 if (as->cck_weak_sig == true) {
290 ath5k_ani_set_cck_weak_signal_detection(ah, false);
291 }
292 */
293}
294
295
296/**
297 * ath5k_ani_lower_immunity() - Decrease noise immunity
298 *
299 * Try to lower noise immunity (=increase sensitivity) in several steps
300 * depending on the average RSSI of the beacons we received.
301 */
302static void
303ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
304{
305 int rssi = ah->ah_beacon_rssi_avg.avg;
306
307 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
308
309 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
310 /* AP mode */
311 if (as->firstep_level > 0) {
312 ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
313 return;
314 }
315 } else {
316 /* STA and IBSS mode (see TODO above) */
317 if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
318 /* beacon signal is high, leave OFDM weak signal
319 * detection off or it may oscillate
320 * TODO: who said it's off??? */
321 } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
322 /* beacon RSSI is mid-range: turn on ODFM weak signal
323 * detection and next, lower firstep level */
324 if (as->ofdm_weak_sig == false) {
325 ath5k_ani_set_ofdm_weak_signal_detection(ah,
326 true);
327 return;
328 }
329 if (as->firstep_level > 0) {
330 ath5k_ani_set_firstep_level(ah,
331 as->firstep_level - 1);
332 return;
333 }
334 } else {
335 /* beacon signal is low: only reduce firstep level */
336 if (as->firstep_level > 0) {
337 ath5k_ani_set_firstep_level(ah,
338 as->firstep_level - 1);
339 return;
340 }
341 }
342 }
343
344 /* all modes */
345 if (as->spur_level > 0) {
346 ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1);
347 return;
348 }
349
350 /* finally, reduce noise immunity */
351 if (as->noise_imm_level > 0) {
352 ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1);
353 return;
354 }
355}
356
357
358/**
359 * ath5k_hw_ani_get_listen_time() - Calculate time spent listening
360 *
361 * Return an approximation of the time spent "listening" in milliseconds (ms)
362 * since the last call of this function by deducting the cycles spent
363 * transmitting and receiving from the total cycle count.
364 * Save profile count values for debugging/statistics and because we might want
365 * to use them later.
366 *
367 * We assume no one else clears these registers!
368 */
369static int
370ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
371{
372 int listen;
373
374 /* freeze */
375 ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
376 /* read */
377 as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
378 as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
379 as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
380 as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
381 /* clear */
382 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
383 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
384 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
385 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
386 /* un-freeze */
387 ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
388
389 /* TODO: where does 44000 come from? (11g clock rate?) */
390 listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
391
392 if (as->pfc_cycles == 0 || listen < 0)
393 return 0;
394 return listen;
395}
396
397
398/**
399 * ath5k_ani_save_and_clear_phy_errors() - Clear and save PHY error counters
400 *
401 * Clear the PHY error counters as soon as possible, since this might be called
402 * from a MIB interrupt and we want to make sure we don't get interrupted again.
403 * Add the count of CCK and OFDM errors to our internal state, so it can be used
404 * by the algorithm later.
405 *
406 * Will be called from interrupt and tasklet context.
407 * Returns 0 if both counters are zero.
408 */
409static int
410ath5k_ani_save_and_clear_phy_errors(struct ath5k_hw *ah,
411 struct ath5k_ani_state *as)
412{
413 unsigned int ofdm_err, cck_err;
414
415 if (!ah->ah_capabilities.cap_has_phyerr_counters)
416 return 0;
417
418 ofdm_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1);
419 cck_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2);
420
421 /* reset counters first, we might be in a hurry (interrupt) */
422 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH,
423 AR5K_PHYERR_CNT1);
424 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH,
425 AR5K_PHYERR_CNT2);
426
427 ofdm_err = ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ofdm_err);
428 cck_err = ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - cck_err);
429
430 /* sometimes both can be zero, especially when there is a superfluous
431 * second interrupt. detect that here and return an error. */
432 if (ofdm_err <= 0 && cck_err <= 0)
433 return 0;
434
435 /* avoid negative values should one of the registers overflow */
436 if (ofdm_err > 0) {
437 as->ofdm_errors += ofdm_err;
438 as->sum_ofdm_errors += ofdm_err;
439 }
440 if (cck_err > 0) {
441 as->cck_errors += cck_err;
442 as->sum_cck_errors += cck_err;
443 }
444 return 1;
445}
446
447
448/**
449 * ath5k_ani_period_restart() - Restart ANI period
450 *
451 * Just reset counters, so they are clear for the next "ani period".
452 */
453static void
454ath5k_ani_period_restart(struct ath5k_hw *ah, struct ath5k_ani_state *as)
455{
456 /* keep last values for debugging */
457 as->last_ofdm_errors = as->ofdm_errors;
458 as->last_cck_errors = as->cck_errors;
459 as->last_listen = as->listen_time;
460
461 as->ofdm_errors = 0;
462 as->cck_errors = 0;
463 as->listen_time = 0;
464}
465
466
467/**
468 * ath5k_ani_calibration() - The main ANI calibration function
469 *
470 * We count OFDM and CCK errors relative to the time where we did not send or
471 * receive ("listen" time) and raise or lower immunity accordingly.
472 * This is called regularly (every second) from the calibration timer, but also
473 * when an error threshold has been reached.
474 *
475 * In order to synchronize access from different contexts, this should be
476 * called only indirectly by scheduling the ANI tasklet!
477 */
478void
479ath5k_ani_calibration(struct ath5k_hw *ah)
480{
481 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
482 int listen, ofdm_high, ofdm_low, cck_high, cck_low;
483
484 if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
485 return;
486
487 /* get listen time since last call and add it to the counter because we
488 * might not have restarted the "ani period" last time */
489 listen = ath5k_hw_ani_get_listen_time(ah, as);
490 as->listen_time += listen;
491
492 ath5k_ani_save_and_clear_phy_errors(ah, as);
493
494 ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000;
495 cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000;
496 ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000;
497 cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000;
498
499 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
500 "listen %d (now %d)", as->listen_time, listen);
501 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
502 "check high ofdm %d/%d cck %d/%d",
503 as->ofdm_errors, ofdm_high, as->cck_errors, cck_high);
504
505 if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) {
506 /* too many PHY errors - we have to raise immunity */
507 bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false;
508 ath5k_ani_raise_immunity(ah, as, ofdm_flag);
509 ath5k_ani_period_restart(ah, as);
510
511 } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) {
512 /* If more than 5 (TODO: why 5?) periods have passed and we got
513 * relatively little errors we can try to lower immunity */
514 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
515 "check low ofdm %d/%d cck %d/%d",
516 as->ofdm_errors, ofdm_low, as->cck_errors, cck_low);
517
518 if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low)
519 ath5k_ani_lower_immunity(ah, as);
520
521 ath5k_ani_period_restart(ah, as);
522 }
523}
524
525
526/*** INTERRUPT HANDLER ***/
527
528/**
529 * ath5k_ani_mib_intr() - Interrupt handler for ANI MIB counters
530 *
531 * Just read & reset the registers quickly, so they don't generate more
532 * interrupts, save the counters and schedule the tasklet to decide whether
533 * to raise immunity or not.
534 *
535 * We just need to handle PHY error counters, ath5k_hw_update_mib_counters()
536 * should take care of all "normal" MIB interrupts.
537 */
538void
539ath5k_ani_mib_intr(struct ath5k_hw *ah)
540{
541 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
542
543 /* nothing to do here if HW does not have PHY error counters - they
544 * can't be the reason for the MIB interrupt then */
545 if (!ah->ah_capabilities.cap_has_phyerr_counters)
546 return;
547
548 /* not in use but clear anyways */
549 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
550 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
551
552 if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
553 return;
554
555 /* if one of the errors triggered, we can get a superfluous second
556 * interrupt, even though we have already reset the register. the
557 * function detects that so we can return early */
558 if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0)
559 return;
560
561 if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH ||
562 as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
563 tasklet_schedule(&ah->ah_sc->ani_tasklet);
564}
565
566
567/**
568 * ath5k_ani_phy_error_report() - Used by older HW to report PHY errors
569 *
570 * This is used by hardware without PHY error counters to report PHY errors
571 * on a frame-by-frame basis, instead of the interrupt.
572 */
573void
574ath5k_ani_phy_error_report(struct ath5k_hw *ah,
575 enum ath5k_phy_error_code phyerr)
576{
577 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
578
579 if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) {
580 as->ofdm_errors++;
581 if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH)
582 tasklet_schedule(&ah->ah_sc->ani_tasklet);
583 } else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) {
584 as->cck_errors++;
585 if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
586 tasklet_schedule(&ah->ah_sc->ani_tasklet);
587 }
588}
589
590
591/*** INIT ***/
592
593/**
594 * ath5k_enable_phy_err_counters() - Enable PHY error counters
595 *
596 * Enable PHY error counters for OFDM and CCK timing errors.
597 */
598static void
599ath5k_enable_phy_err_counters(struct ath5k_hw *ah)
600{
601 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH,
602 AR5K_PHYERR_CNT1);
603 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH,
604 AR5K_PHYERR_CNT2);
605 ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHYERR_CNT1_MASK);
606 ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_CCK, AR5K_PHYERR_CNT2_MASK);
607
608 /* not in use */
609 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
610 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
611}
612
613
614/**
615 * ath5k_disable_phy_err_counters() - Disable PHY error counters
616 *
617 * Disable PHY error counters for OFDM and CCK timing errors.
618 */
619static void
620ath5k_disable_phy_err_counters(struct ath5k_hw *ah)
621{
622 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1);
623 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2);
624 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1_MASK);
625 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2_MASK);
626
627 /* not in use */
628 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
629 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
630}
631
632
633/**
634 * ath5k_ani_init() - Initialize ANI
635 * @mode: Which mode to use (auto, manual high, manual low, off)
636 *
637 * Initialize ANI according to mode.
638 */
639void
640ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
641{
642 /* ANI is only possible on 5212 and newer */
643 if (ah->ah_version < AR5K_AR5212)
644 return;
645
646 /* clear old state information */
647 memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state));
648
649 /* older hardware has more spur levels than newer */
650 if (ah->ah_mac_srev < AR5K_SREV_AR2414)
651 ah->ah_sc->ani_state.max_spur_level = 7;
652 else
653 ah->ah_sc->ani_state.max_spur_level = 2;
654
655 /* initial values for our ani parameters */
656 if (mode == ATH5K_ANI_MODE_OFF) {
657 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n");
658 } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
659 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
660 "ANI manual low -> high sensitivity\n");
661 ath5k_ani_set_noise_immunity_level(ah, 0);
662 ath5k_ani_set_spur_immunity_level(ah, 0);
663 ath5k_ani_set_firstep_level(ah, 0);
664 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
665 ath5k_ani_set_cck_weak_signal_detection(ah, true);
666 } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
667 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
668 "ANI manual high -> low sensitivity\n");
669 ath5k_ani_set_noise_immunity_level(ah,
670 ATH5K_ANI_MAX_NOISE_IMM_LVL);
671 ath5k_ani_set_spur_immunity_level(ah,
672 ah->ah_sc->ani_state.max_spur_level);
673 ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
674 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
675 ath5k_ani_set_cck_weak_signal_detection(ah, false);
676 } else if (mode == ATH5K_ANI_MODE_AUTO) {
677 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI auto\n");
678 ath5k_ani_set_noise_immunity_level(ah, 0);
679 ath5k_ani_set_spur_immunity_level(ah, 0);
680 ath5k_ani_set_firstep_level(ah, 0);
681 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
682 ath5k_ani_set_cck_weak_signal_detection(ah, false);
683 }
684
685 /* newer hardware has PHY error counter registers which we can use to
686 * get OFDM and CCK error counts. older hardware has to set rxfilter and
687 * report every single PHY error by calling ath5k_ani_phy_error_report()
688 */
689 if (mode == ATH5K_ANI_MODE_AUTO) {
690 if (ah->ah_capabilities.cap_has_phyerr_counters)
691 ath5k_enable_phy_err_counters(ah);
692 else
693 ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) |
694 AR5K_RX_FILTER_PHYERR);
695 } else {
696 if (ah->ah_capabilities.cap_has_phyerr_counters)
697 ath5k_disable_phy_err_counters(ah);
698 else
699 ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) &
700 ~AR5K_RX_FILTER_PHYERR);
701 }
702
703 ah->ah_sc->ani_state.ani_mode = mode;
704}
705
706
707/*** DEBUG ***/
708
709#ifdef CONFIG_ATH5K_DEBUG
710
711void
712ath5k_ani_print_counters(struct ath5k_hw *ah)
713{
714 /* clears too */
715 printk(KERN_NOTICE "ACK fail\t%d\n",
716 ath5k_hw_reg_read(ah, AR5K_ACK_FAIL));
717 printk(KERN_NOTICE "RTS fail\t%d\n",
718 ath5k_hw_reg_read(ah, AR5K_RTS_FAIL));
719 printk(KERN_NOTICE "RTS success\t%d\n",
720 ath5k_hw_reg_read(ah, AR5K_RTS_OK));
721 printk(KERN_NOTICE "FCS error\t%d\n",
722 ath5k_hw_reg_read(ah, AR5K_FCS_FAIL));
723
724 /* no clear */
725 printk(KERN_NOTICE "tx\t%d\n",
726 ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX));
727 printk(KERN_NOTICE "rx\t%d\n",
728 ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX));
729 printk(KERN_NOTICE "busy\t%d\n",
730 ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR));
731 printk(KERN_NOTICE "cycles\t%d\n",
732 ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE));
733
734 printk(KERN_NOTICE "AR5K_PHYERR_CNT1\t%d\n",
735 ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1));
736 printk(KERN_NOTICE "AR5K_PHYERR_CNT2\t%d\n",
737 ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2));
738 printk(KERN_NOTICE "AR5K_OFDM_FIL_CNT\t%d\n",
739 ath5k_hw_reg_read(ah, AR5K_OFDM_FIL_CNT));
740 printk(KERN_NOTICE "AR5K_CCK_FIL_CNT\t%d\n",
741 ath5k_hw_reg_read(ah, AR5K_CCK_FIL_CNT));
742}
743
744#endif
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
new file mode 100644
index 000000000000..55cf26d8522c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2010 Bruno Randolf <br1@einfach.org>
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#ifndef ANI_H
17#define ANI_H
18
19/* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */
20#define ATH5K_ANI_LISTEN_PERIOD 100
21#define ATH5K_ANI_OFDM_TRIG_HIGH 500
22#define ATH5K_ANI_OFDM_TRIG_LOW 200
23#define ATH5K_ANI_CCK_TRIG_HIGH 200
24#define ATH5K_ANI_CCK_TRIG_LOW 100
25
26/* average beacon RSSI thresholds */
27#define ATH5K_ANI_RSSI_THR_HIGH 40
28#define ATH5K_ANI_RSSI_THR_LOW 7
29
30/* maximum availabe levels */
31#define ATH5K_ANI_MAX_FIRSTEP_LVL 2
32#define ATH5K_ANI_MAX_NOISE_IMM_LVL 1
33
34
35/**
36 * enum ath5k_ani_mode - mode for ANI / noise sensitivity
37 *
38 * @ATH5K_ANI_MODE_OFF: Turn ANI off. This can be useful to just stop the ANI
39 * algorithm after it has been on auto mode.
40 * ATH5K_ANI_MODE_MANUAL_LOW: Manually set all immunity parameters to low,
41 * maximizing sensitivity. ANI will not run.
42 * ATH5K_ANI_MODE_MANUAL_HIGH: Manually set all immunity parameters to high,
43 * minimizing sensitivity. ANI will not run.
44 * ATH5K_ANI_MODE_AUTO: Automatically control immunity parameters based on the
45 * amount of OFDM and CCK frame errors (default).
46 */
47enum ath5k_ani_mode {
48 ATH5K_ANI_MODE_OFF = 0,
49 ATH5K_ANI_MODE_MANUAL_LOW = 1,
50 ATH5K_ANI_MODE_MANUAL_HIGH = 2,
51 ATH5K_ANI_MODE_AUTO = 3
52};
53
54
55/**
56 * struct ath5k_ani_state - ANI state and associated counters
57 *
58 * @max_spur_level: the maximum spur level is chip dependent
59 */
60struct ath5k_ani_state {
61 enum ath5k_ani_mode ani_mode;
62
63 /* state */
64 int noise_imm_level;
65 int spur_level;
66 int firstep_level;
67 bool ofdm_weak_sig;
68 bool cck_weak_sig;
69
70 int max_spur_level;
71
72 /* used by the algorithm */
73 unsigned int listen_time;
74 unsigned int ofdm_errors;
75 unsigned int cck_errors;
76
77 /* debug/statistics only: numbers from last ANI calibration */
78 unsigned int pfc_tx;
79 unsigned int pfc_rx;
80 unsigned int pfc_busy;
81 unsigned int pfc_cycles;
82 unsigned int last_listen;
83 unsigned int last_ofdm_errors;
84 unsigned int last_cck_errors;
85 unsigned int sum_ofdm_errors;
86 unsigned int sum_cck_errors;
87};
88
89void ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode);
90void ath5k_ani_mib_intr(struct ath5k_hw *ah);
91void ath5k_ani_calibration(struct ath5k_hw *ah);
92void ath5k_ani_phy_error_report(struct ath5k_hw *ah,
93 enum ath5k_phy_error_code phyerr);
94
95/* for manual control */
96void ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level);
97void ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level);
98void ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level);
99void ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on);
100void ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on);
101
102void ath5k_ani_print_counters(struct ath5k_hw *ah);
103
104#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ac67f02e26d8..2785946f659a 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -202,7 +202,8 @@
202#define AR5K_TUNE_MAX_TXPOWER 63 202#define AR5K_TUNE_MAX_TXPOWER 63
203#define AR5K_TUNE_DEFAULT_TXPOWER 25 203#define AR5K_TUNE_DEFAULT_TXPOWER 25
204#define AR5K_TUNE_TPC_TXPOWER false 204#define AR5K_TUNE_TPC_TXPOWER false
205#define AR5K_TUNE_HWTXTRIES 4 205#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */
206#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
206 207
207#define AR5K_INIT_CARR_SENSE_EN 1 208#define AR5K_INIT_CARR_SENSE_EN 1
208 209
@@ -614,28 +615,6 @@ struct ath5k_rx_status {
614#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ 615#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/
615#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ 616#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/
616 617
617#if 0
618/**
619 * struct ath5k_beacon_state - Per-station beacon timer state.
620 * @bs_interval: in TU's, can also include the above flags
621 * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
622 * Point Coordination Function capable AP
623 */
624struct ath5k_beacon_state {
625 u32 bs_next_beacon;
626 u32 bs_next_dtim;
627 u32 bs_interval;
628 u8 bs_dtim_period;
629 u8 bs_cfp_period;
630 u16 bs_cfp_max_duration;
631 u16 bs_cfp_du_remain;
632 u16 bs_tim_offset;
633 u16 bs_sleep_duration;
634 u16 bs_bmiss_threshold;
635 u32 bs_cfp_next;
636};
637#endif
638
639 618
640/* 619/*
641 * TSF to TU conversion: 620 * TSF to TU conversion:
@@ -822,9 +801,9 @@ struct ath5k_athchan_2ghz {
822 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold 801 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
823 * We currently do increments on interrupt by 802 * We currently do increments on interrupt by
824 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 803 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
825 * @AR5K_INT_MIB: Indicates the Management Information Base counters should be 804 * @AR5K_INT_MIB: Indicates the either Management Information Base counters or
826 * checked. We should do this with ath5k_hw_update_mib_counters() but 805 * one of the PHY error counters reached the maximum value and should be
827 * it seems we should also then do some noise immunity work. 806 * read and cleared.
828 * @AR5K_INT_RXPHY: RX PHY Error 807 * @AR5K_INT_RXPHY: RX PHY Error
829 * @AR5K_INT_RXKCM: RX Key cache miss 808 * @AR5K_INT_RXKCM: RX Key cache miss
830 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a 809 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
@@ -912,10 +891,11 @@ enum ath5k_int {
912 AR5K_INT_NOCARD = 0xffffffff 891 AR5K_INT_NOCARD = 0xffffffff
913}; 892};
914 893
915/* Software interrupts used for calibration */ 894/* mask which calibration is active at the moment */
916enum ath5k_software_interrupt { 895enum ath5k_calibration_mask {
917 AR5K_SWI_FULL_CALIBRATION = 0x01, 896 AR5K_CALIBRATION_FULL = 0x01,
918 AR5K_SWI_SHORT_CALIBRATION = 0x02, 897 AR5K_CALIBRATION_SHORT = 0x02,
898 AR5K_CALIBRATION_ANI = 0x04,
919}; 899};
920 900
921/* 901/*
@@ -1004,6 +984,8 @@ struct ath5k_capabilities {
1004 struct { 984 struct {
1005 u8 q_tx_num; 985 u8 q_tx_num;
1006 } cap_queues; 986 } cap_queues;
987
988 bool cap_has_phyerr_counters;
1007}; 989};
1008 990
1009/* size of noise floor history (keep it a power of two) */ 991/* size of noise floor history (keep it a power of two) */
@@ -1014,6 +996,15 @@ struct ath5k_nfcal_hist
1014 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ 996 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
1015}; 997};
1016 998
999/**
1000 * struct avg_val - Helper structure for average calculation
1001 * @avg: contains the actual average value
1002 * @avg_weight: is used internally during calculation to prevent rounding errors
1003 */
1004struct ath5k_avg_val {
1005 int avg;
1006 int avg_weight;
1007};
1017 1008
1018/***************************************\ 1009/***************************************\
1019 HARDWARE ABSTRACTION LAYER STRUCTURE 1010 HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1028,7 +1019,6 @@ struct ath5k_nfcal_hist
1028 1019
1029/* TODO: Clean up and merge with ath5k_softc */ 1020/* TODO: Clean up and merge with ath5k_softc */
1030struct ath5k_hw { 1021struct ath5k_hw {
1031 u32 ah_magic;
1032 struct ath_common common; 1022 struct ath_common common;
1033 1023
1034 struct ath5k_softc *ah_sc; 1024 struct ath5k_softc *ah_sc;
@@ -1036,7 +1026,6 @@ struct ath5k_hw {
1036 1026
1037 enum ath5k_int ah_imr; 1027 enum ath5k_int ah_imr;
1038 1028
1039 enum nl80211_iftype ah_op_mode;
1040 struct ieee80211_channel *ah_current_channel; 1029 struct ieee80211_channel *ah_current_channel;
1041 bool ah_turbo; 1030 bool ah_turbo;
1042 bool ah_calibration; 1031 bool ah_calibration;
@@ -1049,7 +1038,6 @@ struct ath5k_hw {
1049 u32 ah_phy; 1038 u32 ah_phy;
1050 u32 ah_mac_srev; 1039 u32 ah_mac_srev;
1051 u16 ah_mac_version; 1040 u16 ah_mac_version;
1052 u16 ah_mac_revision;
1053 u16 ah_phy_revision; 1041 u16 ah_phy_revision;
1054 u16 ah_radio_5ghz_revision; 1042 u16 ah_radio_5ghz_revision;
1055 u16 ah_radio_2ghz_revision; 1043 u16 ah_radio_2ghz_revision;
@@ -1071,8 +1059,6 @@ struct ath5k_hw {
1071 u8 ah_def_ant; 1059 u8 ah_def_ant;
1072 bool ah_software_retry; 1060 bool ah_software_retry;
1073 1061
1074 int ah_gpio_npins;
1075
1076 struct ath5k_capabilities ah_capabilities; 1062 struct ath5k_capabilities ah_capabilities;
1077 1063
1078 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; 1064 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
@@ -1123,17 +1109,18 @@ struct ath5k_hw {
1123 1109
1124 struct ath5k_nfcal_hist ah_nfcal_hist; 1110 struct ath5k_nfcal_hist ah_nfcal_hist;
1125 1111
1112 /* average beacon RSSI in our BSS (used by ANI) */
1113 struct ath5k_avg_val ah_beacon_rssi_avg;
1114
1126 /* noise floor from last periodic calibration */ 1115 /* noise floor from last periodic calibration */
1127 s32 ah_noise_floor; 1116 s32 ah_noise_floor;
1128 1117
1129 /* Calibration timestamp */ 1118 /* Calibration timestamp */
1130 unsigned long ah_cal_tstamp; 1119 unsigned long ah_cal_next_full;
1131 1120 unsigned long ah_cal_next_ani;
1132 /* Calibration interval (secs) */
1133 u8 ah_cal_intval;
1134 1121
1135 /* Software interrupt mask */ 1122 /* Calibration mask */
1136 u8 ah_swi_mask; 1123 u8 ah_cal_mask;
1137 1124
1138 /* 1125 /*
1139 * Function pointers 1126 * Function pointers
@@ -1141,9 +1128,9 @@ struct ath5k_hw {
1141 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, 1128 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
1142 u32 size, unsigned int flags); 1129 u32 size, unsigned int flags);
1143 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1130 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1144 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, 1131 unsigned int, unsigned int, int, enum ath5k_pkt_type,
1145 unsigned int, unsigned int, unsigned int, unsigned int, 1132 unsigned int, unsigned int, unsigned int, unsigned int,
1146 unsigned int, unsigned int, unsigned int); 1133 unsigned int, unsigned int, unsigned int, unsigned int);
1147 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1134 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1148 unsigned int, unsigned int, unsigned int, unsigned int, 1135 unsigned int, unsigned int, unsigned int, unsigned int,
1149 unsigned int, unsigned int); 1136 unsigned int, unsigned int);
@@ -1158,158 +1145,145 @@ struct ath5k_hw {
1158 */ 1145 */
1159 1146
1160/* Attach/Detach Functions */ 1147/* Attach/Detach Functions */
1161extern int ath5k_hw_attach(struct ath5k_softc *sc); 1148int ath5k_hw_attach(struct ath5k_softc *sc);
1162extern void ath5k_hw_detach(struct ath5k_hw *ah); 1149void ath5k_hw_detach(struct ath5k_hw *ah);
1163 1150
1164/* LED functions */ 1151/* LED functions */
1165extern int ath5k_init_leds(struct ath5k_softc *sc); 1152int ath5k_init_leds(struct ath5k_softc *sc);
1166extern void ath5k_led_enable(struct ath5k_softc *sc); 1153void ath5k_led_enable(struct ath5k_softc *sc);
1167extern void ath5k_led_off(struct ath5k_softc *sc); 1154void ath5k_led_off(struct ath5k_softc *sc);
1168extern void ath5k_unregister_leds(struct ath5k_softc *sc); 1155void ath5k_unregister_leds(struct ath5k_softc *sc);
1169 1156
1170/* Reset Functions */ 1157/* Reset Functions */
1171extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1158int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
1172extern int ath5k_hw_on_hold(struct ath5k_hw *ah); 1159int ath5k_hw_on_hold(struct ath5k_hw *ah);
1173extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); 1160int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1161 struct ieee80211_channel *channel, bool change_channel);
1162int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
1163 bool is_set);
1174/* Power management functions */ 1164/* Power management functions */
1175extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
1176 1165
1177/* DMA Related Functions */ 1166/* DMA Related Functions */
1178extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); 1167void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
1179extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); 1168int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
1180extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); 1169u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
1181extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); 1170void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
1182extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1171int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1183extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1172int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1184extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); 1173u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
1185extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, 1174int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
1186 u32 phys_addr); 1175 u32 phys_addr);
1187extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); 1176int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
1188/* Interrupt handling */ 1177/* Interrupt handling */
1189extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); 1178bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
1190extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); 1179int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
1191extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum 1180enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
1192ath5k_int new_mask); 1181void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
1193extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
1194 1182
1195/* EEPROM access functions */ 1183/* EEPROM access functions */
1196extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1184int ath5k_eeprom_init(struct ath5k_hw *ah);
1197extern void ath5k_eeprom_detach(struct ath5k_hw *ah); 1185void ath5k_eeprom_detach(struct ath5k_hw *ah);
1198extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1186int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1199extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1200 1187
1201/* Protocol Control Unit Functions */ 1188/* Protocol Control Unit Functions */
1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1189extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
1203extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); 1190void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1204/* BSSID Functions */ 1191/* BSSID Functions */
1205extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1192int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1206extern void ath5k_hw_set_associd(struct ath5k_hw *ah); 1193void ath5k_hw_set_associd(struct ath5k_hw *ah);
1207extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1194void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1208/* Receive start/stop functions */ 1195/* Receive start/stop functions */
1209extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1196void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1210extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); 1197void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
1211/* RX Filter functions */ 1198/* RX Filter functions */
1212extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); 1199void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
1213extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1200u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1214extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1201void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1215extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1216extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1217/* Beacon control functions */ 1202/* Beacon control functions */
1218extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); 1203u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
1219extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); 1204void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
1220extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); 1205void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
1221extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); 1206void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1222extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1223#if 0
1224extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
1225extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
1226extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
1227#endif
1228/* ACK bit rate */ 1207/* ACK bit rate */
1229void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); 1208void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
1230/* ACK/CTS Timeouts */
1231extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1232extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1233extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1234extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1235/* Clock rate related functions */ 1209/* Clock rate related functions */
1236unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); 1210unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1237unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); 1211unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1238unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); 1212unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1239/* Key table (WEP) functions */ 1213/* Key table (WEP) functions */
1240extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1214int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1241extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1215int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1242extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); 1216 const struct ieee80211_key_conf *key, const u8 *mac);
1243extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); 1217int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
1244 1218
1245/* Queue Control Unit, DFS Control Unit Functions */ 1219/* Queue Control Unit, DFS Control Unit Functions */
1246extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); 1220int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
1247extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, 1221 struct ath5k_txq_info *queue_info);
1248 const struct ath5k_txq_info *queue_info); 1222int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
1249extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, 1223 const struct ath5k_txq_info *queue_info);
1250 enum ath5k_tx_queue queue_type, 1224int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1251 struct ath5k_txq_info *queue_info); 1225 enum ath5k_tx_queue queue_type,
1252extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); 1226 struct ath5k_txq_info *queue_info);
1253extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1227u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1254extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1228void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1255extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); 1229int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1256extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); 1230int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1257 1231
1258/* Hardware Descriptor Functions */ 1232/* Hardware Descriptor Functions */
1259extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); 1233int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
1260 1234
1261/* GPIO Functions */ 1235/* GPIO Functions */
1262extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1236void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1263extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); 1237int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
1264extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); 1238int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1265extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); 1239u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
1266extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); 1240int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1267extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); 1241void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
1242 u32 interrupt_level);
1268 1243
1269/* rfkill Functions */ 1244/* rfkill Functions */
1270extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); 1245void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
1271extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); 1246void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
1272 1247
1273/* Misc functions */ 1248/* Misc functions */
1274int ath5k_hw_set_capabilities(struct ath5k_hw *ah); 1249int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
1275extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); 1250int ath5k_hw_get_capability(struct ath5k_hw *ah,
1276extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); 1251 enum ath5k_capability_type cap_type, u32 capability,
1277extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); 1252 u32 *result);
1253int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
1254int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1278 1255
1279/* Initial register settings functions */ 1256/* Initial register settings functions */
1280extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1257int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1281 1258
1282/* Initialize RF */ 1259/* Initialize RF */
1283extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, 1260int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
1284 struct ieee80211_channel *channel, 1261 struct ieee80211_channel *channel,
1285 unsigned int mode); 1262 unsigned int mode);
1286extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); 1263int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
1287extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); 1264enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1288extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); 1265int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1289/* PHY/RF channel functions */ 1266/* PHY/RF channel functions */
1290extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1267bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1291extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1268int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1292/* PHY calibration */ 1269/* PHY calibration */
1293void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1270void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1294extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1271int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1295extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1272 struct ieee80211_channel *channel);
1296extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah);
1297extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1298/* Spur mitigation */ 1273/* Spur mitigation */
1299bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1274bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1300 struct ieee80211_channel *channel); 1275 struct ieee80211_channel *channel);
1301void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, 1276void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1302 struct ieee80211_channel *channel); 1277 struct ieee80211_channel *channel);
1303/* Misc PHY functions */ 1278/* Misc PHY functions */
1304extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1279u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1305extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1280int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1306/* Antenna control */ 1281/* Antenna control */
1307extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); 1282void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1308extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
1309extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1310/* TX power setup */ 1283/* TX power setup */
1311extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); 1284int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1312extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1285 u8 ee_mode, u8 txpower);
1286int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1313 1287
1314/* 1288/*
1315 * Functions used internaly 1289 * Functions used internaly
@@ -1335,29 +1309,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1335 iowrite32(val, ah->ah_iobase + reg); 1309 iowrite32(val, ah->ah_iobase + reg);
1336} 1310}
1337 1311
1338#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
1339/*
1340 * Check if a register write has been completed
1341 */
1342static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
1343 u32 val, bool is_set)
1344{
1345 int i;
1346 u32 data;
1347
1348 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
1349 data = ath5k_hw_reg_read(ah, reg);
1350 if (is_set && (data & flag))
1351 break;
1352 else if ((data & flag) == val)
1353 break;
1354 udelay(15);
1355 }
1356
1357 return (i <= 0) ? -EAGAIN : 0;
1358}
1359#endif
1360
1361static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 1312static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1362{ 1313{
1363 u32 retval = 0, bit, i; 1314 u32 retval = 0, bit, i;
@@ -1370,9 +1321,27 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1370 return retval; 1321 return retval;
1371} 1322}
1372 1323
1373static inline int ath5k_pad_size(int hdrlen) 1324#define AVG_SAMPLES 8
1325#define AVG_FACTOR 1000
1326
1327/**
1328 * ath5k_moving_average - Exponentially weighted moving average
1329 * @avg: average structure
1330 * @val: current value
1331 *
1332 * This implementation make use of a struct ath5k_avg_val to prevent rounding
1333 * errors.
1334 */
1335static inline struct ath5k_avg_val
1336ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
1374{ 1337{
1375 return (hdrlen < 24) ? 0 : hdrlen & 3; 1338 struct ath5k_avg_val new;
1339 new.avg_weight = avg.avg_weight ?
1340 (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
1341 (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
1342 (val * (AVG_FACTOR));
1343 new.avg = new.avg_weight / (AVG_FACTOR);
1344 return new;
1376} 1345}
1377 1346
1378#endif 1347#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 42284445b75e..dcf7c30f813f 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -113,7 +113,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
113 /* 113 /*
114 * HW information 114 * HW information
115 */ 115 */
116 ah->ah_op_mode = NL80211_IFTYPE_STATION;
117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; 116 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
118 ah->ah_turbo = false; 117 ah->ah_turbo = false;
119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 118 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
@@ -123,6 +122,9 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
123 ah->ah_cw_min = AR5K_TUNE_CWMIN; 122 ah->ah_cw_min = AR5K_TUNE_CWMIN;
124 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; 123 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
125 ah->ah_software_retry = false; 124 ah->ah_software_retry = false;
125 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
126 ah->ah_noise_floor = -95; /* until first NF calibration is run */
127 sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
126 128
127 /* 129 /*
128 * Find the mac version 130 * Find the mac version
@@ -148,7 +150,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
148 /* Get MAC, PHY and RADIO revisions */ 150 /* Get MAC, PHY and RADIO revisions */
149 ah->ah_mac_srev = srev; 151 ah->ah_mac_srev = srev;
150 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); 152 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
151 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
152 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 153 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
153 0xffffffff; 154 0xffffffff;
154 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, 155 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
@@ -327,7 +328,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
327 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 328 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
328 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); 329 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
329 ath5k_hw_set_associd(ah); 330 ath5k_hw_set_associd(ah);
330 ath5k_hw_set_opmode(ah); 331 ath5k_hw_set_opmode(ah, sc->opmode);
331 332
332 ath5k_hw_rfgain_opt_init(ah); 333 ath5k_hw_rfgain_opt_init(ah);
333 334
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8dce0077b023..c085a06f1e05 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -58,8 +58,8 @@
58#include "base.h" 58#include "base.h"
59#include "reg.h" 59#include "reg.h"
60#include "debug.h" 60#include "debug.h"
61#include "ani.h"
61 62
62static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
63static int modparam_nohwcrypt; 63static int modparam_nohwcrypt;
64module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 64module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
65MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 65MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -198,7 +198,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
198static int ath5k_pci_suspend(struct device *dev); 198static int ath5k_pci_suspend(struct device *dev);
199static int ath5k_pci_resume(struct device *dev); 199static int ath5k_pci_resume(struct device *dev);
200 200
201SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); 201static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
202#define ATH5K_PM_OPS (&ath5k_pm_ops) 202#define ATH5K_PM_OPS (&ath5k_pm_ops)
203#else 203#else
204#define ATH5K_PM_OPS NULL 204#define ATH5K_PM_OPS NULL
@@ -307,7 +307,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
307 struct ath5k_buf *bf); 307 struct ath5k_buf *bf);
308static int ath5k_txbuf_setup(struct ath5k_softc *sc, 308static int ath5k_txbuf_setup(struct ath5k_softc *sc,
309 struct ath5k_buf *bf, 309 struct ath5k_buf *bf,
310 struct ath5k_txq *txq); 310 struct ath5k_txq *txq, int padsize);
311static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 311static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
312 struct ath5k_buf *bf) 312 struct ath5k_buf *bf)
313{ 313{
@@ -364,6 +364,7 @@ static void ath5k_beacon_send(struct ath5k_softc *sc);
364static void ath5k_beacon_config(struct ath5k_softc *sc); 364static void ath5k_beacon_config(struct ath5k_softc *sc);
365static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); 365static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
366static void ath5k_tasklet_beacon(unsigned long data); 366static void ath5k_tasklet_beacon(unsigned long data);
367static void ath5k_tasklet_ani(unsigned long data);
367 368
368static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) 369static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
369{ 370{
@@ -829,6 +830,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
829 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); 830 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
830 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); 831 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
831 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); 832 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
833 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
832 834
833 ret = ath5k_eeprom_read_mac(ah, mac); 835 ret = ath5k_eeprom_read_mac(ah, mac);
834 if (ret) { 836 if (ret) {
@@ -1137,8 +1139,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1137 struct ath5k_hw *ah = sc->ah; 1139 struct ath5k_hw *ah = sc->ah;
1138 u32 rfilt; 1140 u32 rfilt;
1139 1141
1140 ah->ah_op_mode = sc->opmode;
1141
1142 /* configure rx filter */ 1142 /* configure rx filter */
1143 rfilt = sc->filter_flags; 1143 rfilt = sc->filter_flags;
1144 ath5k_hw_set_rx_filter(ah, rfilt); 1144 ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1147,8 +1147,9 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1147 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 1147 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
1148 1148
1149 /* configure operational mode */ 1149 /* configure operational mode */
1150 ath5k_hw_set_opmode(ah); 1150 ath5k_hw_set_opmode(ah, sc->opmode);
1151 1151
1152 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
1152 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 1153 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1153} 1154}
1154 1155
@@ -1271,7 +1272,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1271 1272
1272static int 1273static int
1273ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1274ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1274 struct ath5k_txq *txq) 1275 struct ath5k_txq *txq, int padsize)
1275{ 1276{
1276 struct ath5k_hw *ah = sc->ah; 1277 struct ath5k_hw *ah = sc->ah;
1277 struct ath5k_desc *ds = bf->desc; 1278 struct ath5k_desc *ds = bf->desc;
@@ -1323,7 +1324,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1323 sc->vif, pktlen, info)); 1324 sc->vif, pktlen, info));
1324 } 1325 }
1325 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1326 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1326 ieee80211_get_hdrlen_from_skb(skb), 1327 ieee80211_get_hdrlen_from_skb(skb), padsize,
1327 get_hw_packet_type(skb), 1328 get_hw_packet_type(skb),
1328 (sc->power_level * 2), 1329 (sc->power_level * 2),
1329 hw_rate, 1330 hw_rate,
@@ -1806,6 +1807,86 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1806} 1807}
1807 1808
1808static void 1809static void
1810ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
1811{
1812 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1813 struct ath5k_hw *ah = sc->ah;
1814 struct ath_common *common = ath5k_hw_common(ah);
1815
1816 /* only beacons from our BSSID */
1817 if (!ieee80211_is_beacon(mgmt->frame_control) ||
1818 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
1819 return;
1820
1821 ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
1822 rssi);
1823
1824 /* in IBSS mode we should keep RSSI statistics per neighbour */
1825 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
1826}
1827
1828/*
1829 * Compute padding position. skb must contains an IEEE 802.11 frame
1830 */
1831static int ath5k_common_padpos(struct sk_buff *skb)
1832{
1833 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1834 __le16 frame_control = hdr->frame_control;
1835 int padpos = 24;
1836
1837 if (ieee80211_has_a4(frame_control)) {
1838 padpos += ETH_ALEN;
1839 }
1840 if (ieee80211_is_data_qos(frame_control)) {
1841 padpos += IEEE80211_QOS_CTL_LEN;
1842 }
1843
1844 return padpos;
1845}
1846
1847/*
1848 * This function expects a 802.11 frame and returns the number of
1849 * bytes added, or -1 if we don't have enought header room.
1850 */
1851
1852static int ath5k_add_padding(struct sk_buff *skb)
1853{
1854 int padpos = ath5k_common_padpos(skb);
1855 int padsize = padpos & 3;
1856
1857 if (padsize && skb->len>padpos) {
1858
1859 if (skb_headroom(skb) < padsize)
1860 return -1;
1861
1862 skb_push(skb, padsize);
1863 memmove(skb->data, skb->data+padsize, padpos);
1864 return padsize;
1865 }
1866
1867 return 0;
1868}
1869
1870/*
1871 * This function expects a 802.11 frame and returns the number of
1872 * bytes removed
1873 */
1874
1875static int ath5k_remove_padding(struct sk_buff *skb)
1876{
1877 int padpos = ath5k_common_padpos(skb);
1878 int padsize = padpos & 3;
1879
1880 if (padsize && skb->len>=padpos+padsize) {
1881 memmove(skb->data + padsize, skb->data, padpos);
1882 skb_pull(skb, padsize);
1883 return padsize;
1884 }
1885
1886 return 0;
1887}
1888
1889static void
1809ath5k_tasklet_rx(unsigned long data) 1890ath5k_tasklet_rx(unsigned long data)
1810{ 1891{
1811 struct ieee80211_rx_status *rxs; 1892 struct ieee80211_rx_status *rxs;
@@ -1818,8 +1899,6 @@ ath5k_tasklet_rx(unsigned long data)
1818 struct ath5k_buf *bf; 1899 struct ath5k_buf *bf;
1819 struct ath5k_desc *ds; 1900 struct ath5k_desc *ds;
1820 int ret; 1901 int ret;
1821 int hdrlen;
1822 int padsize;
1823 int rx_flag; 1902 int rx_flag;
1824 1903
1825 spin_lock(&sc->rxbuflock); 1904 spin_lock(&sc->rxbuflock);
@@ -1844,18 +1923,30 @@ ath5k_tasklet_rx(unsigned long data)
1844 break; 1923 break;
1845 else if (unlikely(ret)) { 1924 else if (unlikely(ret)) {
1846 ATH5K_ERR(sc, "error in processing rx descriptor\n"); 1925 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1926 sc->stats.rxerr_proc++;
1847 spin_unlock(&sc->rxbuflock); 1927 spin_unlock(&sc->rxbuflock);
1848 return; 1928 return;
1849 } 1929 }
1850 1930
1931 sc->stats.rx_all_count++;
1932
1851 if (unlikely(rs.rs_more)) { 1933 if (unlikely(rs.rs_more)) {
1852 ATH5K_WARN(sc, "unsupported jumbo\n"); 1934 ATH5K_WARN(sc, "unsupported jumbo\n");
1935 sc->stats.rxerr_jumbo++;
1853 goto next; 1936 goto next;
1854 } 1937 }
1855 1938
1856 if (unlikely(rs.rs_status)) { 1939 if (unlikely(rs.rs_status)) {
1857 if (rs.rs_status & AR5K_RXERR_PHY) 1940 if (rs.rs_status & AR5K_RXERR_CRC)
1941 sc->stats.rxerr_crc++;
1942 if (rs.rs_status & AR5K_RXERR_FIFO)
1943 sc->stats.rxerr_fifo++;
1944 if (rs.rs_status & AR5K_RXERR_PHY) {
1945 sc->stats.rxerr_phy++;
1946 if (rs.rs_phyerr > 0 && rs.rs_phyerr < 32)
1947 sc->stats.rxerr_phy_code[rs.rs_phyerr]++;
1858 goto next; 1948 goto next;
1949 }
1859 if (rs.rs_status & AR5K_RXERR_DECRYPT) { 1950 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1860 /* 1951 /*
1861 * Decrypt error. If the error occurred 1952 * Decrypt error. If the error occurred
@@ -1867,12 +1958,14 @@ ath5k_tasklet_rx(unsigned long data)
1867 * 1958 *
1868 * XXX do key cache faulting 1959 * XXX do key cache faulting
1869 */ 1960 */
1961 sc->stats.rxerr_decrypt++;
1870 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && 1962 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1871 !(rs.rs_status & AR5K_RXERR_CRC)) 1963 !(rs.rs_status & AR5K_RXERR_CRC))
1872 goto accept; 1964 goto accept;
1873 } 1965 }
1874 if (rs.rs_status & AR5K_RXERR_MIC) { 1966 if (rs.rs_status & AR5K_RXERR_MIC) {
1875 rx_flag |= RX_FLAG_MMIC_ERROR; 1967 rx_flag |= RX_FLAG_MMIC_ERROR;
1968 sc->stats.rxerr_mic++;
1876 goto accept; 1969 goto accept;
1877 } 1970 }
1878 1971
@@ -1904,12 +1997,8 @@ accept:
1904 * bytes and we can optimize this a bit. In addition, we must 1997 * bytes and we can optimize this a bit. In addition, we must
1905 * not try to remove padding from short control frames that do 1998 * not try to remove padding from short control frames that do
1906 * not have payload. */ 1999 * not have payload. */
1907 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2000 ath5k_remove_padding(skb);
1908 padsize = ath5k_pad_size(hdrlen); 2001
1909 if (padsize) {
1910 memmove(skb->data + padsize, skb->data, hdrlen);
1911 skb_pull(skb, padsize);
1912 }
1913 rxs = IEEE80211_SKB_RXCB(skb); 2002 rxs = IEEE80211_SKB_RXCB(skb);
1914 2003
1915 /* 2004 /*
@@ -1942,6 +2031,12 @@ accept:
1942 rxs->signal = rxs->noise + rs.rs_rssi; 2031 rxs->signal = rxs->noise + rs.rs_rssi;
1943 2032
1944 rxs->antenna = rs.rs_antenna; 2033 rxs->antenna = rs.rs_antenna;
2034
2035 if (rs.rs_antenna > 0 && rs.rs_antenna < 5)
2036 sc->stats.antenna_rx[rs.rs_antenna]++;
2037 else
2038 sc->stats.antenna_rx[0]++; /* invalid */
2039
1945 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 2040 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1946 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); 2041 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
1947 2042
@@ -1951,6 +2046,8 @@ accept:
1951 2046
1952 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 2047 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
1953 2048
2049 ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi);
2050
1954 /* check beacons in IBSS mode */ 2051 /* check beacons in IBSS mode */
1955 if (sc->opmode == NL80211_IFTYPE_ADHOC) 2052 if (sc->opmode == NL80211_IFTYPE_ADHOC)
1956 ath5k_check_ibss_tsf(sc, skb, rxs); 2053 ath5k_check_ibss_tsf(sc, skb, rxs);
@@ -1996,6 +2093,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1996 break; 2093 break;
1997 } 2094 }
1998 2095
2096 sc->stats.tx_all_count++;
1999 skb = bf->skb; 2097 skb = bf->skb;
2000 info = IEEE80211_SKB_CB(skb); 2098 info = IEEE80211_SKB_CB(skb);
2001 bf->skb = NULL; 2099 bf->skb = NULL;
@@ -2021,14 +2119,31 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2021 info->status.rates[ts.ts_final_idx].count++; 2119 info->status.rates[ts.ts_final_idx].count++;
2022 2120
2023 if (unlikely(ts.ts_status)) { 2121 if (unlikely(ts.ts_status)) {
2024 sc->ll_stats.dot11ACKFailureCount++; 2122 sc->stats.ack_fail++;
2025 if (ts.ts_status & AR5K_TXERR_FILT) 2123 if (ts.ts_status & AR5K_TXERR_FILT) {
2026 info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 2124 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2125 sc->stats.txerr_filt++;
2126 }
2127 if (ts.ts_status & AR5K_TXERR_XRETRY)
2128 sc->stats.txerr_retry++;
2129 if (ts.ts_status & AR5K_TXERR_FIFO)
2130 sc->stats.txerr_fifo++;
2027 } else { 2131 } else {
2028 info->flags |= IEEE80211_TX_STAT_ACK; 2132 info->flags |= IEEE80211_TX_STAT_ACK;
2029 info->status.ack_signal = ts.ts_rssi; 2133 info->status.ack_signal = ts.ts_rssi;
2030 } 2134 }
2031 2135
2136 /*
2137 * Remove MAC header padding before giving the frame
2138 * back to mac80211.
2139 */
2140 ath5k_remove_padding(skb);
2141
2142 if (ts.ts_antenna > 0 && ts.ts_antenna < 5)
2143 sc->stats.antenna_tx[ts.ts_antenna]++;
2144 else
2145 sc->stats.antenna_tx[0]++; /* invalid */
2146
2032 ieee80211_tx_status(sc->hw, skb); 2147 ieee80211_tx_status(sc->hw, skb);
2033 2148
2034 spin_lock(&sc->txbuflock); 2149 spin_lock(&sc->txbuflock);
@@ -2072,6 +2187,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2072 int ret = 0; 2187 int ret = 0;
2073 u8 antenna; 2188 u8 antenna;
2074 u32 flags; 2189 u32 flags;
2190 const int padsize = 0;
2075 2191
2076 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2192 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
2077 PCI_DMA_TODEVICE); 2193 PCI_DMA_TODEVICE);
@@ -2119,7 +2235,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2119 * from tx power (value is in dB units already) */ 2235 * from tx power (value is in dB units already) */
2120 ds->ds_data = bf->skbaddr; 2236 ds->ds_data = bf->skbaddr;
2121 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2237 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2122 ieee80211_get_hdrlen_from_skb(skb), 2238 ieee80211_get_hdrlen_from_skb(skb), padsize,
2123 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2239 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2124 ieee80211_get_tx_rate(sc->hw, info)->hw_value, 2240 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
2125 1, AR5K_TXKEYIX_INVALID, 2241 1, AR5K_TXKEYIX_INVALID,
@@ -2406,9 +2522,6 @@ ath5k_init(struct ath5k_softc *sc)
2406 */ 2522 */
2407 ath5k_stop_locked(sc); 2523 ath5k_stop_locked(sc);
2408 2524
2409 /* Set PHY calibration interval */
2410 ah->ah_cal_intval = ath5k_calinterval;
2411
2412 /* 2525 /*
2413 * The basic interface to setting the hardware in a good 2526 * The basic interface to setting the hardware in a good
2414 * state is ``reset''. On return the hardware is known to 2527 * state is ``reset''. On return the hardware is known to
@@ -2420,7 +2533,8 @@ ath5k_init(struct ath5k_softc *sc)
2420 sc->curband = &sc->sbands[sc->curchan->band]; 2533 sc->curband = &sc->sbands[sc->curchan->band];
2421 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | 2534 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2422 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2535 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2423 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI; 2536 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
2537
2424 ret = ath5k_reset(sc, NULL); 2538 ret = ath5k_reset(sc, NULL);
2425 if (ret) 2539 if (ret)
2426 goto done; 2540 goto done;
@@ -2532,12 +2646,33 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2532 tasklet_kill(&sc->restq); 2646 tasklet_kill(&sc->restq);
2533 tasklet_kill(&sc->calib); 2647 tasklet_kill(&sc->calib);
2534 tasklet_kill(&sc->beacontq); 2648 tasklet_kill(&sc->beacontq);
2649 tasklet_kill(&sc->ani_tasklet);
2535 2650
2536 ath5k_rfkill_hw_stop(sc->ah); 2651 ath5k_rfkill_hw_stop(sc->ah);
2537 2652
2538 return ret; 2653 return ret;
2539} 2654}
2540 2655
2656static void
2657ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2658{
2659 if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) &&
2660 !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) {
2661 /* run ANI only when full calibration is not active */
2662 ah->ah_cal_next_ani = jiffies +
2663 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI);
2664 tasklet_schedule(&ah->ah_sc->ani_tasklet);
2665
2666 } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) {
2667 ah->ah_cal_next_full = jiffies +
2668 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL);
2669 tasklet_schedule(&ah->ah_sc->calib);
2670 }
2671 /* we could use SWI to generate enough interrupts to meet our
2672 * calibration interval requirements, if necessary:
2673 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
2674}
2675
2541static irqreturn_t 2676static irqreturn_t
2542ath5k_intr(int irq, void *dev_id) 2677ath5k_intr(int irq, void *dev_id)
2543{ 2678{
@@ -2586,15 +2721,10 @@ ath5k_intr(int irq, void *dev_id)
2586 if (status & AR5K_INT_BMISS) { 2721 if (status & AR5K_INT_BMISS) {
2587 /* TODO */ 2722 /* TODO */
2588 } 2723 }
2589 if (status & AR5K_INT_SWI) {
2590 tasklet_schedule(&sc->calib);
2591 }
2592 if (status & AR5K_INT_MIB) { 2724 if (status & AR5K_INT_MIB) {
2593 /* 2725 sc->stats.mib_intr++;
2594 * These stats are also used for ANI i think 2726 ath5k_hw_update_mib_counters(ah);
2595 * so how about updating them more often ? 2727 ath5k_ani_mib_intr(ah);
2596 */
2597 ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
2598 } 2728 }
2599 if (status & AR5K_INT_GPIO) 2729 if (status & AR5K_INT_GPIO)
2600 tasklet_schedule(&sc->rf_kill.toggleq); 2730 tasklet_schedule(&sc->rf_kill.toggleq);
@@ -2605,7 +2735,7 @@ ath5k_intr(int irq, void *dev_id)
2605 if (unlikely(!counter)) 2735 if (unlikely(!counter))
2606 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2736 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2607 2737
2608 ath5k_hw_calibration_poll(ah); 2738 ath5k_intr_calibration_poll(ah);
2609 2739
2610 return IRQ_HANDLED; 2740 return IRQ_HANDLED;
2611} 2741}
@@ -2629,8 +2759,7 @@ ath5k_tasklet_calibrate(unsigned long data)
2629 struct ath5k_hw *ah = sc->ah; 2759 struct ath5k_hw *ah = sc->ah;
2630 2760
2631 /* Only full calibration for now */ 2761 /* Only full calibration for now */
2632 if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION) 2762 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
2633 return;
2634 2763
2635 /* Stop queues so that calibration 2764 /* Stop queues so that calibration
2636 * doesn't interfere with tx */ 2765 * doesn't interfere with tx */
@@ -2653,11 +2782,22 @@ ath5k_tasklet_calibrate(unsigned long data)
2653 ieee80211_frequency_to_channel( 2782 ieee80211_frequency_to_channel(
2654 sc->curchan->center_freq)); 2783 sc->curchan->center_freq));
2655 2784
2656 ah->ah_swi_mask = 0;
2657
2658 /* Wake queues */ 2785 /* Wake queues */
2659 ieee80211_wake_queues(sc->hw); 2786 ieee80211_wake_queues(sc->hw);
2660 2787
2788 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
2789}
2790
2791
2792static void
2793ath5k_tasklet_ani(unsigned long data)
2794{
2795 struct ath5k_softc *sc = (void *)data;
2796 struct ath5k_hw *ah = sc->ah;
2797
2798 ah->ah_cal_mask |= AR5K_CALIBRATION_ANI;
2799 ath5k_ani_calibration(ah);
2800 ah->ah_cal_mask &= ~AR5K_CALIBRATION_ANI;
2661} 2801}
2662 2802
2663 2803
@@ -2679,7 +2819,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2679 struct ath5k_softc *sc = hw->priv; 2819 struct ath5k_softc *sc = hw->priv;
2680 struct ath5k_buf *bf; 2820 struct ath5k_buf *bf;
2681 unsigned long flags; 2821 unsigned long flags;
2682 int hdrlen;
2683 int padsize; 2822 int padsize;
2684 2823
2685 ath5k_debug_dump_skb(sc, skb, "TX ", 1); 2824 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
@@ -2691,17 +2830,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2691 * the hardware expects the header padded to 4 byte boundaries 2830 * the hardware expects the header padded to 4 byte boundaries
2692 * if this is not the case we add the padding after the header 2831 * if this is not the case we add the padding after the header
2693 */ 2832 */
2694 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2833 padsize = ath5k_add_padding(skb);
2695 padsize = ath5k_pad_size(hdrlen); 2834 if (padsize < 0) {
2696 if (padsize) { 2835 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
2697 2836 " headroom to pad");
2698 if (skb_headroom(skb) < padsize) { 2837 goto drop_packet;
2699 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2700 " headroom to pad %d\n", hdrlen, padsize);
2701 goto drop_packet;
2702 }
2703 skb_push(skb, padsize);
2704 memmove(skb->data, skb->data+padsize, hdrlen);
2705 } 2838 }
2706 2839
2707 spin_lock_irqsave(&sc->txbuflock, flags); 2840 spin_lock_irqsave(&sc->txbuflock, flags);
@@ -2720,7 +2853,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2720 2853
2721 bf->skb = skb; 2854 bf->skb = skb;
2722 2855
2723 if (ath5k_txbuf_setup(sc, bf, txq)) { 2856 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
2724 bf->skb = NULL; 2857 bf->skb = NULL;
2725 spin_lock_irqsave(&sc->txbuflock, flags); 2858 spin_lock_irqsave(&sc->txbuflock, flags);
2726 list_add_tail(&bf->list, &sc->txbuf); 2859 list_add_tail(&bf->list, &sc->txbuf);
@@ -2767,6 +2900,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2767 goto err; 2900 goto err;
2768 } 2901 }
2769 2902
2903 ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
2904
2770 /* 2905 /*
2771 * Change channels and update the h/w rate map if we're switching; 2906 * Change channels and update the h/w rate map if we're switching;
2772 * e.g. 11a to 11b/g. 2907 * e.g. 11a to 11b/g.
@@ -2835,6 +2970,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2835 goto end; 2970 goto end;
2836 } 2971 }
2837 2972
2973 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
2974
2838 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2975 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2839 ath5k_mode_setup(sc); 2976 ath5k_mode_setup(sc);
2840 2977
@@ -2905,7 +3042,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2905 * then we must allow the user to set how many tx antennas we 3042 * then we must allow the user to set how many tx antennas we
2906 * have available 3043 * have available
2907 */ 3044 */
2908 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 3045 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
2909 3046
2910unlock: 3047unlock:
2911 mutex_unlock(&sc->lock); 3048 mutex_unlock(&sc->lock);
@@ -3123,12 +3260,14 @@ ath5k_get_stats(struct ieee80211_hw *hw,
3123 struct ieee80211_low_level_stats *stats) 3260 struct ieee80211_low_level_stats *stats)
3124{ 3261{
3125 struct ath5k_softc *sc = hw->priv; 3262 struct ath5k_softc *sc = hw->priv;
3126 struct ath5k_hw *ah = sc->ah;
3127 3263
3128 /* Force update */ 3264 /* Force update */
3129 ath5k_hw_update_mib_counters(ah, &sc->ll_stats); 3265 ath5k_hw_update_mib_counters(sc->ah);
3130 3266
3131 memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats)); 3267 stats->dot11ACKFailureCount = sc->stats.ack_fail;
3268 stats->dot11RTSFailureCount = sc->stats.rts_fail;
3269 stats->dot11RTSSuccessCount = sc->stats.rts_ok;
3270 stats->dot11FCSErrorCount = sc->stats.fcs_error;
3132 3271
3133 return 0; 3272 return 0;
3134} 3273}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7e1a88a5abdb..53a5651c57a2 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -50,6 +50,7 @@
50 50
51#include "ath5k.h" 51#include "ath5k.h"
52#include "debug.h" 52#include "debug.h"
53#include "ani.h"
53 54
54#include "../regd.h" 55#include "../regd.h"
55#include "../ath.h" 56#include "../ath.h"
@@ -105,6 +106,37 @@ struct ath5k_rfkill {
105 struct tasklet_struct toggleq; 106 struct tasklet_struct toggleq;
106}; 107};
107 108
109/* statistics */
110struct ath5k_statistics {
111 /* antenna use */
112 unsigned int antenna_rx[5]; /* frames count per antenna RX */
113 unsigned int antenna_tx[5]; /* frames count per antenna TX */
114
115 /* frame errors */
116 unsigned int rx_all_count; /* all RX frames, including errors */
117 unsigned int tx_all_count; /* all TX frames, including errors */
118 unsigned int rxerr_crc;
119 unsigned int rxerr_phy;
120 unsigned int rxerr_phy_code[32];
121 unsigned int rxerr_fifo;
122 unsigned int rxerr_decrypt;
123 unsigned int rxerr_mic;
124 unsigned int rxerr_proc;
125 unsigned int rxerr_jumbo;
126 unsigned int txerr_retry;
127 unsigned int txerr_fifo;
128 unsigned int txerr_filt;
129
130 /* MIB counters */
131 unsigned int ack_fail;
132 unsigned int rts_fail;
133 unsigned int rts_ok;
134 unsigned int fcs_error;
135 unsigned int beacons;
136
137 unsigned int mib_intr;
138};
139
108#if CHAN_DEBUG 140#if CHAN_DEBUG
109#define ATH_CHAN_MAX (26+26+26+200+200) 141#define ATH_CHAN_MAX (26+26+26+200+200)
110#else 142#else
@@ -117,7 +149,6 @@ struct ath5k_softc {
117 struct pci_dev *pdev; /* for dma mapping */ 149 struct pci_dev *pdev; /* for dma mapping */
118 void __iomem *iobase; /* address of the device */ 150 void __iomem *iobase; /* address of the device */
119 struct mutex lock; /* dev-level lock */ 151 struct mutex lock; /* dev-level lock */
120 struct ieee80211_low_level_stats ll_stats;
121 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 152 struct ieee80211_hw *hw; /* IEEE 802.11 common */
122 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 153 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
123 struct ieee80211_channel channels[ATH_CHAN_MAX]; 154 struct ieee80211_channel channels[ATH_CHAN_MAX];
@@ -191,6 +222,11 @@ struct ath5k_softc {
191 int power_level; /* Requested tx power in dbm */ 222 int power_level; /* Requested tx power in dbm */
192 bool assoc; /* associate state */ 223 bool assoc; /* associate state */
193 bool enable_beacon; /* true if beacons are on */ 224 bool enable_beacon; /* true if beacons are on */
225
226 struct ath5k_statistics stats;
227
228 struct ath5k_ani_state ani_state;
229 struct tasklet_struct ani_tasklet; /* ANI calibration */
194}; 230};
195 231
196#define ath5k_hw_hasbssidmask(_ah) \ 232#define ath5k_hw_hasbssidmask(_ah) \
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index 367a6c7d3cc7..74f007126f41 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -102,9 +102,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
102 } 102 }
103 } 103 }
104 104
105 /* GPIO */
106 ah->ah_gpio_npins = AR5K_NUM_GPIO;
107
108 /* Set number of supported TX queues */ 105 /* Set number of supported TX queues */
109 if (ah->ah_version == AR5K_AR5210) 106 if (ah->ah_version == AR5K_AR5210)
110 ah->ah_capabilities.cap_queues.q_tx_num = 107 ah->ah_capabilities.cap_queues.q_tx_num =
@@ -112,6 +109,12 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
112 else 109 else
113 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; 110 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
114 111
112 /* newer hardware has PHY error counters */
113 if (ah->ah_mac_srev >= AR5K_SREV_AR5213A)
114 ah->ah_capabilities.cap_has_phyerr_counters = true;
115 else
116 ah->ah_capabilities.cap_has_phyerr_counters = false;
117
115 return 0; 118 return 0;
116} 119}
117 120
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 747508c15d34..6fb5c5ffa5b1 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -69,6 +69,7 @@ module_param_named(debug, ath5k_debug, uint, 0);
69 69
70#include <linux/seq_file.h> 70#include <linux/seq_file.h>
71#include "reg.h" 71#include "reg.h"
72#include "ani.h"
72 73
73static struct dentry *ath5k_global_debugfs; 74static struct dentry *ath5k_global_debugfs;
74 75
@@ -307,6 +308,7 @@ static const struct {
307 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, 308 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
308 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, 309 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
309 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, 310 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
311 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
310 { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, 312 { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
311}; 313};
312 314
@@ -364,6 +366,369 @@ static const struct file_operations fops_debug = {
364}; 366};
365 367
366 368
369/* debugfs: antenna */
370
371static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
372 size_t count, loff_t *ppos)
373{
374 struct ath5k_softc *sc = file->private_data;
375 char buf[700];
376 unsigned int len = 0;
377 unsigned int i;
378 unsigned int v;
379
380 len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n",
381 sc->ah->ah_ant_mode);
382 len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n",
383 sc->ah->ah_def_ant);
384 len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n",
385 sc->ah->ah_tx_ant);
386
387 len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n");
388 for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
389 len += snprintf(buf+len, sizeof(buf)-len,
390 "[antenna %d]\t%d\t%d\n",
391 i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]);
392 }
393 len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n",
394 sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]);
395
396 v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA);
397 len += snprintf(buf+len, sizeof(buf)-len,
398 "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
399
400 v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1);
401 len += snprintf(buf+len, sizeof(buf)-len,
402 "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
403 (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
404 len += snprintf(buf+len, sizeof(buf)-len,
405 "AR5K_STA_ID1_DESC_ANTENNA\t%d\n",
406 (v & AR5K_STA_ID1_DESC_ANTENNA) != 0);
407 len += snprintf(buf+len, sizeof(buf)-len,
408 "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n",
409 (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0);
410 len += snprintf(buf+len, sizeof(buf)-len,
411 "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
412 (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
413
414 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL);
415 len += snprintf(buf+len, sizeof(buf)-len,
416 "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
417 (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
418
419 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART);
420 len += snprintf(buf+len, sizeof(buf)-len,
421 "AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
422 (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
423
424 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV);
425 len += snprintf(buf+len, sizeof(buf)-len,
426 "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
427 (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
428
429 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
430}
431
432static ssize_t write_file_antenna(struct file *file,
433 const char __user *userbuf,
434 size_t count, loff_t *ppos)
435{
436 struct ath5k_softc *sc = file->private_data;
437 unsigned int i;
438 char buf[20];
439
440 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
441 return -EFAULT;
442
443 if (strncmp(buf, "diversity", 9) == 0) {
444 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
445 printk(KERN_INFO "ath5k debug: enable diversity\n");
446 } else if (strncmp(buf, "fixed-a", 7) == 0) {
447 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
448 printk(KERN_INFO "ath5k debugfs: fixed antenna A\n");
449 } else if (strncmp(buf, "fixed-b", 7) == 0) {
450 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
451 printk(KERN_INFO "ath5k debug: fixed antenna B\n");
452 } else if (strncmp(buf, "clear", 5) == 0) {
453 for (i = 0; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
454 sc->stats.antenna_rx[i] = 0;
455 sc->stats.antenna_tx[i] = 0;
456 }
457 printk(KERN_INFO "ath5k debug: cleared antenna stats\n");
458 }
459 return count;
460}
461
462static const struct file_operations fops_antenna = {
463 .read = read_file_antenna,
464 .write = write_file_antenna,
465 .open = ath5k_debugfs_open,
466 .owner = THIS_MODULE,
467};
468
469
470/* debugfs: frameerrors */
471
472static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
473 size_t count, loff_t *ppos)
474{
475 struct ath5k_softc *sc = file->private_data;
476 struct ath5k_statistics *st = &sc->stats;
477 char buf[700];
478 unsigned int len = 0;
479 int i;
480
481 len += snprintf(buf+len, sizeof(buf)-len,
482 "RX\n---------------------\n");
483 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n",
484 st->rxerr_crc,
485 st->rx_all_count > 0 ?
486 st->rxerr_crc*100/st->rx_all_count : 0);
487 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n",
488 st->rxerr_phy,
489 st->rx_all_count > 0 ?
490 st->rxerr_phy*100/st->rx_all_count : 0);
491 for (i = 0; i < 32; i++) {
492 if (st->rxerr_phy_code[i])
493 len += snprintf(buf+len, sizeof(buf)-len,
494 " phy_err[%d]\t%d\n",
495 i, st->rxerr_phy_code[i]);
496 }
497
498 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
499 st->rxerr_fifo,
500 st->rx_all_count > 0 ?
501 st->rxerr_fifo*100/st->rx_all_count : 0);
502 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n",
503 st->rxerr_decrypt,
504 st->rx_all_count > 0 ?
505 st->rxerr_decrypt*100/st->rx_all_count : 0);
506 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n",
507 st->rxerr_mic,
508 st->rx_all_count > 0 ?
509 st->rxerr_mic*100/st->rx_all_count : 0);
510 len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n",
511 st->rxerr_proc,
512 st->rx_all_count > 0 ?
513 st->rxerr_proc*100/st->rx_all_count : 0);
514 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n",
515 st->rxerr_jumbo,
516 st->rx_all_count > 0 ?
517 st->rxerr_jumbo*100/st->rx_all_count : 0);
518 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
519 st->rx_all_count);
520
521 len += snprintf(buf+len, sizeof(buf)-len,
522 "\nTX\n---------------------\n");
523 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n",
524 st->txerr_retry,
525 st->tx_all_count > 0 ?
526 st->txerr_retry*100/st->tx_all_count : 0);
527 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
528 st->txerr_fifo,
529 st->tx_all_count > 0 ?
530 st->txerr_fifo*100/st->tx_all_count : 0);
531 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n",
532 st->txerr_filt,
533 st->tx_all_count > 0 ?
534 st->txerr_filt*100/st->tx_all_count : 0);
535 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
536 st->tx_all_count);
537
538 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
539}
540
541static ssize_t write_file_frameerrors(struct file *file,
542 const char __user *userbuf,
543 size_t count, loff_t *ppos)
544{
545 struct ath5k_softc *sc = file->private_data;
546 struct ath5k_statistics *st = &sc->stats;
547 char buf[20];
548
549 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
550 return -EFAULT;
551
552 if (strncmp(buf, "clear", 5) == 0) {
553 st->rxerr_crc = 0;
554 st->rxerr_phy = 0;
555 st->rxerr_fifo = 0;
556 st->rxerr_decrypt = 0;
557 st->rxerr_mic = 0;
558 st->rxerr_proc = 0;
559 st->rxerr_jumbo = 0;
560 st->rx_all_count = 0;
561 st->txerr_retry = 0;
562 st->txerr_fifo = 0;
563 st->txerr_filt = 0;
564 st->tx_all_count = 0;
565 printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n");
566 }
567 return count;
568}
569
570static const struct file_operations fops_frameerrors = {
571 .read = read_file_frameerrors,
572 .write = write_file_frameerrors,
573 .open = ath5k_debugfs_open,
574 .owner = THIS_MODULE,
575};
576
577
578/* debugfs: ani */
579
580static ssize_t read_file_ani(struct file *file, char __user *user_buf,
581 size_t count, loff_t *ppos)
582{
583 struct ath5k_softc *sc = file->private_data;
584 struct ath5k_statistics *st = &sc->stats;
585 struct ath5k_ani_state *as = &sc->ani_state;
586
587 char buf[700];
588 unsigned int len = 0;
589
590 len += snprintf(buf+len, sizeof(buf)-len,
591 "HW has PHY error counters:\t%s\n",
592 sc->ah->ah_capabilities.cap_has_phyerr_counters ?
593 "yes" : "no");
594 len += snprintf(buf+len, sizeof(buf)-len,
595 "HW max spur immunity level:\t%d\n",
596 as->max_spur_level);
597 len += snprintf(buf+len, sizeof(buf)-len,
598 "\nANI state\n--------------------------------------------\n");
599 len += snprintf(buf+len, sizeof(buf)-len, "operating mode:\t\t\t");
600 switch (as->ani_mode) {
601 case ATH5K_ANI_MODE_OFF:
602 len += snprintf(buf+len, sizeof(buf)-len, "OFF\n");
603 break;
604 case ATH5K_ANI_MODE_MANUAL_LOW:
605 len += snprintf(buf+len, sizeof(buf)-len,
606 "MANUAL LOW\n");
607 break;
608 case ATH5K_ANI_MODE_MANUAL_HIGH:
609 len += snprintf(buf+len, sizeof(buf)-len,
610 "MANUAL HIGH\n");
611 break;
612 case ATH5K_ANI_MODE_AUTO:
613 len += snprintf(buf+len, sizeof(buf)-len, "AUTO\n");
614 break;
615 default:
616 len += snprintf(buf+len, sizeof(buf)-len,
617 "??? (not good)\n");
618 break;
619 }
620 len += snprintf(buf+len, sizeof(buf)-len,
621 "noise immunity level:\t\t%d\n",
622 as->noise_imm_level);
623 len += snprintf(buf+len, sizeof(buf)-len,
624 "spur immunity level:\t\t%d\n",
625 as->spur_level);
626 len += snprintf(buf+len, sizeof(buf)-len, "firstep level:\t\t\t%d\n",
627 as->firstep_level);
628 len += snprintf(buf+len, sizeof(buf)-len,
629 "OFDM weak signal detection:\t%s\n",
630 as->ofdm_weak_sig ? "on" : "off");
631 len += snprintf(buf+len, sizeof(buf)-len,
632 "CCK weak signal detection:\t%s\n",
633 as->cck_weak_sig ? "on" : "off");
634
635 len += snprintf(buf+len, sizeof(buf)-len,
636 "\nMIB INTERRUPTS:\t\t%u\n",
637 st->mib_intr);
638 len += snprintf(buf+len, sizeof(buf)-len,
639 "beacon RSSI average:\t%d\n",
640 sc->ah->ah_beacon_rssi_avg.avg);
641 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
642 as->pfc_tx,
643 as->pfc_cycles > 0 ?
644 as->pfc_tx*100/as->pfc_cycles : 0);
645 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
646 as->pfc_rx,
647 as->pfc_cycles > 0 ?
648 as->pfc_rx*100/as->pfc_cycles : 0);
649 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
650 as->pfc_busy,
651 as->pfc_cycles > 0 ?
652 as->pfc_busy*100/as->pfc_cycles : 0);
653 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
654 as->pfc_cycles);
655 len += snprintf(buf+len, sizeof(buf)-len,
656 "listen time\t\t%d\tlast: %d\n",
657 as->listen_time, as->last_listen);
658 len += snprintf(buf+len, sizeof(buf)-len,
659 "OFDM errors\t\t%u\tlast: %u\tsum: %u\n",
660 as->ofdm_errors, as->last_ofdm_errors,
661 as->sum_ofdm_errors);
662 len += snprintf(buf+len, sizeof(buf)-len,
663 "CCK errors\t\t%u\tlast: %u\tsum: %u\n",
664 as->cck_errors, as->last_cck_errors,
665 as->sum_cck_errors);
666 len += snprintf(buf+len, sizeof(buf)-len,
667 "AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
668 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1),
669 ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
670 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1)));
671 len += snprintf(buf+len, sizeof(buf)-len,
672 "AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
673 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2),
674 ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
675 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
676
677 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
678}
679
680static ssize_t write_file_ani(struct file *file,
681 const char __user *userbuf,
682 size_t count, loff_t *ppos)
683{
684 struct ath5k_softc *sc = file->private_data;
685 char buf[20];
686
687 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
688 return -EFAULT;
689
690 if (strncmp(buf, "sens-low", 8) == 0) {
691 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_HIGH);
692 } else if (strncmp(buf, "sens-high", 9) == 0) {
693 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_LOW);
694 } else if (strncmp(buf, "ani-off", 7) == 0) {
695 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_OFF);
696 } else if (strncmp(buf, "ani-on", 6) == 0) {
697 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_AUTO);
698 } else if (strncmp(buf, "noise-low", 9) == 0) {
699 ath5k_ani_set_noise_immunity_level(sc->ah, 0);
700 } else if (strncmp(buf, "noise-high", 10) == 0) {
701 ath5k_ani_set_noise_immunity_level(sc->ah,
702 ATH5K_ANI_MAX_NOISE_IMM_LVL);
703 } else if (strncmp(buf, "spur-low", 8) == 0) {
704 ath5k_ani_set_spur_immunity_level(sc->ah, 0);
705 } else if (strncmp(buf, "spur-high", 9) == 0) {
706 ath5k_ani_set_spur_immunity_level(sc->ah,
707 sc->ani_state.max_spur_level);
708 } else if (strncmp(buf, "fir-low", 7) == 0) {
709 ath5k_ani_set_firstep_level(sc->ah, 0);
710 } else if (strncmp(buf, "fir-high", 8) == 0) {
711 ath5k_ani_set_firstep_level(sc->ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
712 } else if (strncmp(buf, "ofdm-off", 8) == 0) {
713 ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, false);
714 } else if (strncmp(buf, "ofdm-on", 7) == 0) {
715 ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, true);
716 } else if (strncmp(buf, "cck-off", 7) == 0) {
717 ath5k_ani_set_cck_weak_signal_detection(sc->ah, false);
718 } else if (strncmp(buf, "cck-on", 6) == 0) {
719 ath5k_ani_set_cck_weak_signal_detection(sc->ah, true);
720 }
721 return count;
722}
723
724static const struct file_operations fops_ani = {
725 .read = read_file_ani,
726 .write = write_file_ani,
727 .open = ath5k_debugfs_open,
728 .owner = THIS_MODULE,
729};
730
731
367/* init */ 732/* init */
368 733
369void 734void
@@ -393,6 +758,20 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
393 758
394 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, 759 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
395 sc->debug.debugfs_phydir, sc, &fops_reset); 760 sc->debug.debugfs_phydir, sc, &fops_reset);
761
762 sc->debug.debugfs_antenna = debugfs_create_file("antenna",
763 S_IWUSR | S_IRUSR,
764 sc->debug.debugfs_phydir, sc, &fops_antenna);
765
766 sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
767 S_IWUSR | S_IRUSR,
768 sc->debug.debugfs_phydir, sc,
769 &fops_frameerrors);
770
771 sc->debug.debugfs_ani = debugfs_create_file("ani",
772 S_IWUSR | S_IRUSR,
773 sc->debug.debugfs_phydir, sc,
774 &fops_ani);
396} 775}
397 776
398void 777void
@@ -408,6 +787,9 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
408 debugfs_remove(sc->debug.debugfs_registers); 787 debugfs_remove(sc->debug.debugfs_registers);
409 debugfs_remove(sc->debug.debugfs_beacon); 788 debugfs_remove(sc->debug.debugfs_beacon);
410 debugfs_remove(sc->debug.debugfs_reset); 789 debugfs_remove(sc->debug.debugfs_reset);
790 debugfs_remove(sc->debug.debugfs_antenna);
791 debugfs_remove(sc->debug.debugfs_frameerrors);
792 debugfs_remove(sc->debug.debugfs_ani);
411 debugfs_remove(sc->debug.debugfs_phydir); 793 debugfs_remove(sc->debug.debugfs_phydir);
412} 794}
413 795
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 66f69f04e55e..ddd5b3a99e8d 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -74,6 +74,9 @@ struct ath5k_dbg_info {
74 struct dentry *debugfs_registers; 74 struct dentry *debugfs_registers;
75 struct dentry *debugfs_beacon; 75 struct dentry *debugfs_beacon;
76 struct dentry *debugfs_reset; 76 struct dentry *debugfs_reset;
77 struct dentry *debugfs_antenna;
78 struct dentry *debugfs_frameerrors;
79 struct dentry *debugfs_ani;
77}; 80};
78 81
79/** 82/**
@@ -113,6 +116,7 @@ enum ath5k_debug_level {
113 ATH5K_DEBUG_DUMP_TX = 0x00000200, 116 ATH5K_DEBUG_DUMP_TX = 0x00000200,
114 ATH5K_DEBUG_DUMPBANDS = 0x00000400, 117 ATH5K_DEBUG_DUMPBANDS = 0x00000400,
115 ATH5K_DEBUG_TRACE = 0x00001000, 118 ATH5K_DEBUG_TRACE = 0x00001000,
119 ATH5K_DEBUG_ANI = 0x00002000,
116 ATH5K_DEBUG_ANY = 0xffffffff 120 ATH5K_DEBUG_ANY = 0xffffffff
117}; 121};
118 122
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index dc30a2b70a6b..7d7b646ab65a 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -35,7 +35,8 @@
35 */ 35 */
36static int 36static int
37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
38 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, 38 unsigned int pkt_len, unsigned int hdr_len, int padsize,
39 enum ath5k_pkt_type type,
39 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, 40 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
40 unsigned int key_index, unsigned int antenna_mode, unsigned int flags, 41 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
41 unsigned int rtscts_rate, unsigned int rtscts_duration) 42 unsigned int rtscts_rate, unsigned int rtscts_duration)
@@ -71,7 +72,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
71 /* Verify and set frame length */ 72 /* Verify and set frame length */
72 73
73 /* remove padding we might have added before */ 74 /* remove padding we might have added before */
74 frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; 75 frame_len = pkt_len - padsize + FCS_LEN;
75 76
76 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) 77 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
77 return -EINVAL; 78 return -EINVAL;
@@ -100,7 +101,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
100 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); 101 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
101 } 102 }
102 103
103 /*Diferences between 5210-5211*/ 104 /*Differences between 5210-5211*/
104 if (ah->ah_version == AR5K_AR5210) { 105 if (ah->ah_version == AR5K_AR5210) {
105 switch (type) { 106 switch (type) {
106 case AR5K_PKT_TYPE_BEACON: 107 case AR5K_PKT_TYPE_BEACON:
@@ -165,6 +166,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
165 */ 166 */
166static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, 167static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
167 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, 168 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
169 int padsize,
168 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, 170 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
169 unsigned int tx_tries0, unsigned int key_index, 171 unsigned int tx_tries0, unsigned int key_index,
170 unsigned int antenna_mode, unsigned int flags, 172 unsigned int antenna_mode, unsigned int flags,
@@ -206,7 +208,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
206 /* Verify and set frame length */ 208 /* Verify and set frame length */
207 209
208 /* remove padding we might have added before */ 210 /* remove padding we might have added before */
209 frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; 211 frame_len = pkt_len - padsize + FCS_LEN;
210 212
211 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 213 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
212 return -EINVAL; 214 return -EINVAL;
@@ -229,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
229 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 231 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
230 tx_ctl->tx_control_1 |= AR5K_REG_SM(type, 232 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
231 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 233 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
232 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, 234 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
233 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); 235 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
234 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 236 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
235 237
@@ -643,6 +645,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
643 rs->rs_status |= AR5K_RXERR_PHY; 645 rs->rs_status |= AR5K_RXERR_PHY;
644 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, 646 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
645 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); 647 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
648 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
646 } 649 }
647 650
648 if (rx_status->rx_status_1 & 651 if (rx_status->rx_status_1 &
@@ -668,12 +671,6 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
668 ah->ah_version != AR5K_AR5212) 671 ah->ah_version != AR5K_AR5212)
669 return -ENOTSUPP; 672 return -ENOTSUPP;
670 673
671 /* XXX: What is this magic value and where is it used ? */
672 if (ah->ah_version == AR5K_AR5212)
673 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
674 else if (ah->ah_version == AR5K_AR5211)
675 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
676
677 if (ah->ah_version == AR5K_AR5212) { 674 if (ah->ah_version == AR5K_AR5212) {
678 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; 675 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
679 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; 676 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index 56158c804e3e..64538fbe4167 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -112,15 +112,32 @@ struct ath5k_hw_rx_error {
112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00
113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8
114 114
115/* PHY Error codes */ 115/**
116#define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 116 * enum ath5k_phy_error_code - PHY Error codes
117#define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 117 */
118#define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 118enum ath5k_phy_error_code {
119#define AR5K_DESC_RX_PHY_ERROR_RATE 0x60 119 AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun */
120#define AR5K_DESC_RX_PHY_ERROR_LENGTH 0x80 120 AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */
121#define AR5K_DESC_RX_PHY_ERROR_64QAM 0xa0 121 AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */
122#define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 122 AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */
123#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 123 AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */
124 AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect */
125 AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */
126 AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */
127 /* these are specific to the 5212 */
128 AR5K_RX_PHY_ERROR_OFDM_TIMING = 17,
129 AR5K_RX_PHY_ERROR_OFDM_SIGNAL_PARITY = 18,
130 AR5K_RX_PHY_ERROR_OFDM_RATE_ILLEGAL = 19,
131 AR5K_RX_PHY_ERROR_OFDM_LENGTH_ILLEGAL = 20,
132 AR5K_RX_PHY_ERROR_OFDM_POWER_DROP = 21,
133 AR5K_RX_PHY_ERROR_OFDM_SERVICE = 22,
134 AR5K_RX_PHY_ERROR_OFDM_RESTART = 23,
135 AR5K_RX_PHY_ERROR_CCK_TIMING = 25,
136 AR5K_RX_PHY_ERROR_CCK_HEADER_CRC = 26,
137 AR5K_RX_PHY_ERROR_CCK_RATE_ILLEGAL = 27,
138 AR5K_RX_PHY_ERROR_CCK_SERVICE = 30,
139 AR5K_RX_PHY_ERROR_CCK_RESTART = 31,
140};
124 141
125/* 142/*
126 * 5210/5211 hardware 2-word TX control descriptor 143 * 5210/5211 hardware 2-word TX control descriptor
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 10b52262b232..a3cbfe4fc389 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -329,7 +329,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
329 ee->ee_x_gain[mode] = (val >> 1) & 0xf; 329 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
330 ee->ee_xpd[mode] = val & 0x1; 330 ee->ee_xpd[mode] = val & 0x1;
331 331
332 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) 332 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
333 mode != AR5K_EEPROM_MODE_11B)
333 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; 334 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
334 335
335 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { 336 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
@@ -339,6 +340,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
339 if (mode == AR5K_EEPROM_MODE_11A) 340 if (mode == AR5K_EEPROM_MODE_11A)
340 ee->ee_xr_power[mode] = val & 0x3f; 341 ee->ee_xr_power[mode] = val & 0x3f;
341 else { 342 else {
343 /* b_DB_11[bg] and b_OB_11[bg] */
342 ee->ee_ob[mode][0] = val & 0x7; 344 ee->ee_ob[mode][0] = val & 0x7;
343 ee->ee_db[mode][0] = (val >> 3) & 0x7; 345 ee->ee_db[mode][0] = (val >> 3) & 0x7;
344 } 346 }
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 473a483bb9c3..c4a6d5f26af4 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -24,9 +24,6 @@
24 * SERDES infos are present */ 24 * SERDES infos are present */
25#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ 25#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
26#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ 26#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
27#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
28#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
29#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
30 27
31#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ 28#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
32 29
@@ -78,9 +75,9 @@
78#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) 75#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
79#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) 76#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
80#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) 77#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
81#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ 78#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz */
82#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ 79#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */
83#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) 80#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */
84#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ 81#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
85#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ 82#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */
86 83
@@ -101,7 +98,7 @@
101 98
102#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) 99#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5)
103#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) 100#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
104#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) 101#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) /* has 32KHz crystal for sleep mode */
105#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) 102#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1)
106 103
107#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) 104#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6)
@@ -114,26 +111,27 @@
114 111
115#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) 112#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8)
116#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) 113#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
117#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) 114#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) /* modes supported by radio 0 (bit 1: G, bit 2: A) */
118#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) 115#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) /* modes supported by radio 1 (bit 1: G, bit 2: A) */
119 116
120#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) 117#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9)
121#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) 118#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) /* disable compression */
122#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) 119#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) /* disable AES */
123#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) 120#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */
124#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) 121#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */
125#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) 122#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */
126#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) 123#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heayy clipping */
127#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) 124#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */
128 125
129#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) 126#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10)
130#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) 127#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x7) /* MIMO chains disabled for TX bitmask */
131#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) 128#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x7) /* MIMO chains disabled for RX bitmask */
132#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) 129#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) /* 5.47-5.7GHz supported */
133#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) 130#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) /* Japan UNII1 band (5.15-5.25GHz) on even channels (5180, 5200, 5220, 5240) supported */
134#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) 131#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) /* Japan UNII2 band (5.25-5.35GHz) supported */
135#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) 132#define AR5K_EEPROM_JAP_MID_EN (((_v) >> 9) & 0x1) /* Japan band from 5.47-5.7GHz supported */
136#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) 133#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 10) & 0x1) /* Japan UNII2 band (5.15-5.25GHz) on odd channels (5170, 5190, 5210, 5230) supported */
134#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 11) & 0x1) /* Japan A mode enabled (using even channels) */
137 135
138/* calibration settings */ 136/* calibration settings */
139#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) 137#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
@@ -389,7 +387,49 @@ struct ath5k_edge_power {
389 bool flag; 387 bool flag;
390}; 388};
391 389
392/* EEPROM calibration data */ 390/**
391 * struct ath5k_eeprom_info - EEPROM calibration data
392 *
393 * @ee_regdomain: ath/regd.c takes care of COUNTRY_ERD and WORLDWIDE_ROAMING
394 * flags
395 * @ee_ant_gain: Antenna gain in 0.5dB steps signed [5211 only?]
396 * @ee_cck_ofdm_gain_delta: difference in gainF to output the same power for
397 * OFDM and CCK packets
398 * @ee_cck_ofdm_power_delta: power difference between OFDM (6Mbps) and CCK
399 * (11Mbps) rate in G mode. 0.1dB steps
400 * @ee_scaled_cck_delta: for Japan Channel 14: 0.1dB resolution
401 *
402 * @ee_i_cal: Initial I coefficient to correct I/Q mismatch in the receive path
403 * @ee_q_cal: Initial Q coefficient to correct I/Q mismatch in the receive path
404 * @ee_fixed_bias: use ee_ob and ee_db settings or use automatic control
405 * @ee_switch_settling: RX/TX Switch settling time
406 * @ee_atn_tx_rx: Difference in attenuation between TX and RX in 1dB steps
407 * @ee_ant_control: Antenna Control Settings
408 * @ee_ob: Bias current for Output stage of PA
409 * B/G mode: Index [0] is used for AR2112/5112, otherwise [1]
410 * A mode: [0] 5.15-5.25 [1] 5.25-5.50 [2] 5.50-5.70 [3] 5.70-5.85 GHz
411 * @ee_db: Bias current for Output stage of PA. see @ee_ob
412 * @ee_tx_end2xlna_enable: Time difference from when BB finishes sending a frame
413 * to when the external LNA is activated
414 * @ee_tx_end2xpa_disable: Time difference from when BB finishes sending a frame
415 * to when the external PA switch is deactivated
416 * @ee_tx_frm2xpa_enable: Time difference from when MAC sends frame to when
417 * external PA switch is activated
418 * @ee_thr_62: Clear Channel Assessment (CCA) sensitivity
419 * (IEEE802.11a section 17.3.10.5 )
420 * @ee_xlna_gain: Total gain of the LNA (information only)
421 * @ee_xpd: Use external (1) or internal power detector
422 * @ee_x_gain: Gain for external power detector output (differences in EEMAP
423 * versions!)
424 * @ee_i_gain: Initial gain value after reset
425 * @ee_margin_tx_rx: Margin in dB when final attenuation stage should be used
426 *
427 * @ee_false_detect: Backoff in Sensitivity (dB) on channels with spur signals
428 * @ee_noise_floor_thr: Noise floor threshold in 1dB steps
429 * @ee_adc_desired_size: Desired amplitude for ADC, used by AGC; in 0.5 dB steps
430 * @ee_pga_desired_size: Desired output of PGA (for BB gain) in 0.5 dB steps
431 * @ee_pd_gain_overlap: PD ADC curves need to overlap in 0.5dB steps (ee_map>=2)
432 */
393struct ath5k_eeprom_info { 433struct ath5k_eeprom_info {
394 434
395 /* Header information */ 435 /* Header information */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index aefe84f9c04b..710870ea179b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -39,16 +39,16 @@
39 * ath5k_hw_set_opmode - Set PCU operating mode 39 * ath5k_hw_set_opmode - Set PCU operating mode
40 * 40 *
41 * @ah: The &struct ath5k_hw 41 * @ah: The &struct ath5k_hw
42 * @op_mode: &enum nl80211_iftype operating mode
42 * 43 *
43 * Initialize PCU for the various operating modes (AP/STA etc) 44 * Initialize PCU for the various operating modes (AP/STA etc)
44 *
45 * NOTE: ah->ah_op_mode must be set before calling this.
46 */ 45 */
47int ath5k_hw_set_opmode(struct ath5k_hw *ah) 46int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
48{ 47{
49 struct ath_common *common = ath5k_hw_common(ah); 48 struct ath_common *common = ath5k_hw_common(ah);
50 u32 pcu_reg, beacon_reg, low_id, high_id; 49 u32 pcu_reg, beacon_reg, low_id, high_id;
51 50
51 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
52 52
53 /* Preserve rest settings */ 53 /* Preserve rest settings */
54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
@@ -61,7 +61,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
61 61
62 ATH5K_TRACE(ah->ah_sc); 62 ATH5K_TRACE(ah->ah_sc);
63 63
64 switch (ah->ah_op_mode) { 64 switch (op_mode) {
65 case NL80211_IFTYPE_ADHOC: 65 case NL80211_IFTYPE_ADHOC:
66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; 66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
67 beacon_reg |= AR5K_BCR_ADHOC; 67 beacon_reg |= AR5K_BCR_ADHOC;
@@ -113,39 +113,26 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
113} 113}
114 114
115/** 115/**
116 * ath5k_hw_update - Update mib counters (mac layer statistics) 116 * ath5k_hw_update - Update MIB counters (mac layer statistics)
117 * 117 *
118 * @ah: The &struct ath5k_hw 118 * @ah: The &struct ath5k_hw
119 * @stats: The &struct ieee80211_low_level_stats we use to track
120 * statistics on the driver
121 * 119 *
122 * Reads MIB counters from PCU and updates sw statistics. Must be 120 * Reads MIB counters from PCU and updates sw statistics. Is called after a
123 * called after a MIB interrupt. 121 * MIB interrupt, because one of these counters might have reached their maximum
122 * and triggered the MIB interrupt, to let us read and clear the counter.
123 *
124 * Is called in interrupt context!
124 */ 125 */
125void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, 126void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
126 struct ieee80211_low_level_stats *stats)
127{ 127{
128 ATH5K_TRACE(ah->ah_sc); 128 struct ath5k_statistics *stats = &ah->ah_sc->stats;
129 129
130 /* Read-And-Clear */ 130 /* Read-And-Clear */
131 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); 131 stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
132 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); 132 stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
133 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); 133 stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
134 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); 134 stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
135 135 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
136 /* XXX: Should we use this to track beacon count ?
137 * -we read it anyway to clear the register */
138 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
139
140 /* Reset profile count registers on 5212*/
141 if (ah->ah_version == AR5K_AR5212) {
142 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
143 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
144 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
145 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
146 }
147
148 /* TODO: Handle ANI stats */
149} 136}
150 137
151/** 138/**
@@ -179,25 +166,12 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
179\******************/ 166\******************/
180 167
181/** 168/**
182 * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
183 *
184 * @ah: The &struct ath5k_hw
185 */
186unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
187{
188 ATH5K_TRACE(ah->ah_sc);
189
190 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
192}
193
194/**
195 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU 169 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
196 * 170 *
197 * @ah: The &struct ath5k_hw 171 * @ah: The &struct ath5k_hw
198 * @timeout: Timeout in usec 172 * @timeout: Timeout in usec
199 */ 173 */
200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 174static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
201{ 175{
202 ATH5K_TRACE(ah->ah_sc); 176 ATH5K_TRACE(ah->ah_sc);
203 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) 177 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
@@ -211,24 +185,12 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
211} 185}
212 186
213/** 187/**
214 * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
215 *
216 * @ah: The &struct ath5k_hw
217 */
218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
219{
220 ATH5K_TRACE(ah->ah_sc);
221 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
223}
224
225/**
226 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU 188 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
227 * 189 *
228 * @ah: The &struct ath5k_hw 190 * @ah: The &struct ath5k_hw
229 * @timeout: Timeout in usec 191 * @timeout: Timeout in usec
230 */ 192 */
231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 193static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
232{ 194{
233 ATH5K_TRACE(ah->ah_sc); 195 ATH5K_TRACE(ah->ah_sc);
234 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) 196 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
@@ -290,7 +252,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
290 * 252 *
291 * @ah: The &struct ath5k_hw 253 * @ah: The &struct ath5k_hw
292 */ 254 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) 255static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
294{ 256{
295 struct ieee80211_channel *channel = ah->ah_current_channel; 257 struct ieee80211_channel *channel = ah->ah_current_channel;
296 258
@@ -308,7 +270,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
308 * 270 *
309 * @ah: The &struct ath5k_hw 271 * @ah: The &struct ath5k_hw
310 */ 272 */
311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) 273static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
312{ 274{
313 struct ieee80211_channel *channel = ah->ah_current_channel; 275 struct ieee80211_channel *channel = ah->ah_current_channel;
314 276
@@ -417,7 +379,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
417 * (ACK etc). 379 * (ACK etc).
418 * 380 *
419 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma 381 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
420 * TODO: Init ANI here
421 */ 382 */
422void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) 383void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
423{ 384{
@@ -451,42 +412,6 @@ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
451 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); 412 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
452} 413}
453 414
454/*
455 * Set multicast filter by index
456 */
457int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
458{
459
460 ATH5K_TRACE(ah->ah_sc);
461 if (index >= 64)
462 return -EINVAL;
463 else if (index >= 32)
464 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
465 (1 << (index - 32)));
466 else
467 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
468
469 return 0;
470}
471
472/*
473 * Clear Multicast filter by index
474 */
475int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
476{
477
478 ATH5K_TRACE(ah->ah_sc);
479 if (index >= 64)
480 return -EINVAL;
481 else if (index >= 32)
482 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
483 (1 << (index - 32)));
484 else
485 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
486
487 return 0;
488}
489
490/** 415/**
491 * ath5k_hw_get_rx_filter - Get current rx filter 416 * ath5k_hw_get_rx_filter - Get current rx filter
492 * 417 *
@@ -572,19 +497,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
572\****************/ 497\****************/
573 498
574/** 499/**
575 * ath5k_hw_get_tsf32 - Get a 32bit TSF
576 *
577 * @ah: The &struct ath5k_hw
578 *
579 * Returns lower 32 bits of current TSF
580 */
581u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
582{
583 ATH5K_TRACE(ah->ah_sc);
584 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
585}
586
587/**
588 * ath5k_hw_get_tsf64 - Get the full 64bit TSF 500 * ath5k_hw_get_tsf64 - Get the full 64bit TSF
589 * 501 *
590 * @ah: The &struct ath5k_hw 502 * @ah: The &struct ath5k_hw
@@ -651,7 +563,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
651 /* 563 /*
652 * Set the additional timers by mode 564 * Set the additional timers by mode
653 */ 565 */
654 switch (ah->ah_op_mode) { 566 switch (ah->ah_sc->opmode) {
655 case NL80211_IFTYPE_MONITOR: 567 case NL80211_IFTYPE_MONITOR:
656 case NL80211_IFTYPE_STATION: 568 case NL80211_IFTYPE_STATION:
657 /* In STA mode timer1 is used as next wakeup 569 /* In STA mode timer1 is used as next wakeup
@@ -688,8 +600,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
688 * Set the beacon register and enable all timers. 600 * Set the beacon register and enable all timers.
689 */ 601 */
690 /* When in AP or Mesh Point mode zero timer0 to start TSF */ 602 /* When in AP or Mesh Point mode zero timer0 to start TSF */
691 if (ah->ah_op_mode == NL80211_IFTYPE_AP || 603 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP ||
692 ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT) 604 ah->ah_sc->opmode == NL80211_IFTYPE_MESH_POINT)
693 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); 605 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
694 606
695 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); 607 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
@@ -722,203 +634,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
722 634
723} 635}
724 636
725#if 0
726/*
727 * Set beacon timers
728 */
729int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
730 const struct ath5k_beacon_state *state)
731{
732 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
733
734 /*
735 * TODO: should be changed through *state
736 * review struct ath5k_beacon_state struct
737 *
738 * XXX: These are used for cfp period bellow, are they
739 * ok ? Is it O.K. for tsf here to be 0 or should we use
740 * get_tsf ?
741 */
742 u32 dtim_count = 0; /* XXX */
743 u32 cfp_count = 0; /* XXX */
744 u32 tsf = 0; /* XXX */
745
746 ATH5K_TRACE(ah->ah_sc);
747 /* Return on an invalid beacon state */
748 if (state->bs_interval < 1)
749 return -EINVAL;
750
751 interval = state->bs_interval;
752 dtim = state->bs_dtim_period;
753
754 /*
755 * PCF support?
756 */
757 if (state->bs_cfp_period > 0) {
758 /*
759 * Enable PCF mode and set the CFP
760 * (Contention Free Period) and timer registers
761 */
762 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
763 state->bs_interval;
764 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
765 state->bs_interval;
766
767 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
768 AR5K_STA_ID1_DEFAULT_ANTENNA |
769 AR5K_STA_ID1_PCF);
770 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
771 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
772 AR5K_CFP_DUR);
773 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
774 next_cfp)) << 3, AR5K_TIMER2);
775 } else {
776 /* Disable PCF mode */
777 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
778 AR5K_STA_ID1_DEFAULT_ANTENNA |
779 AR5K_STA_ID1_PCF);
780 }
781
782 /*
783 * Enable the beacon timer register
784 */
785 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
786
787 /*
788 * Start the beacon timers
789 */
790 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
791 ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
792 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
793 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
794 AR5K_BEACON_PERIOD), AR5K_BEACON);
795
796 /*
797 * Write new beacon miss threshold, if it appears to be valid
798 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
799 * and return if its not in range. We can test this by reading value and
800 * setting value to a largest value and seeing which values register.
801 */
802
803 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
804 state->bs_bmiss_threshold);
805
806 /*
807 * Set sleep control register
808 * XXX: Didn't find this in 5210 code but since this register
809 * exists also in ar5k's 5210 headers i leave it as common code.
810 */
811 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
812 (state->bs_sleep_duration - 3) << 3);
813
814 /*
815 * Set enhanced sleep registers on 5212
816 */
817 if (ah->ah_version == AR5K_AR5212) {
818 if (state->bs_sleep_duration > state->bs_interval &&
819 roundup(state->bs_sleep_duration, interval) ==
820 state->bs_sleep_duration)
821 interval = state->bs_sleep_duration;
822
823 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
824 roundup(state->bs_sleep_duration, dtim) ==
825 state->bs_sleep_duration))
826 dtim = state->bs_sleep_duration;
827
828 if (interval > dtim)
829 return -EINVAL;
830
831 next_beacon = interval == dtim ? state->bs_next_dtim :
832 state->bs_next_beacon;
833
834 ath5k_hw_reg_write(ah,
835 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
836 AR5K_SLEEP0_NEXT_DTIM) |
837 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
838 AR5K_SLEEP0_ENH_SLEEP_EN |
839 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
840
841 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
842 AR5K_SLEEP1_NEXT_TIM) |
843 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
844
845 ath5k_hw_reg_write(ah,
846 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
847 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
848 }
849
850 return 0;
851}
852
853/*
854 * Reset beacon timers
855 */
856void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
857{
858 ATH5K_TRACE(ah->ah_sc);
859 /*
860 * Disable beacon timer
861 */
862 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
863
864 /*
865 * Disable some beacon register values
866 */
867 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
868 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
869 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
870}
871
872/*
873 * Wait for beacon queue to finish
874 */
875int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
876{
877 unsigned int i;
878 int ret;
879
880 ATH5K_TRACE(ah->ah_sc);
881
882 /* 5210 doesn't have QCU*/
883 if (ah->ah_version == AR5K_AR5210) {
884 /*
885 * Wait for beaconn queue to finish by checking
886 * Control Register and Beacon Status Register.
887 */
888 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
889 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
890 ||
891 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
892 break;
893 udelay(10);
894 }
895
896 /* Timeout... */
897 if (i <= 0) {
898 /*
899 * Re-schedule the beacon queue
900 */
901 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
902 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
903 AR5K_BCR);
904
905 return -EIO;
906 }
907 ret = 0;
908 } else {
909 /*5211/5212*/
910 ret = ath5k_hw_register_timeout(ah,
911 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
912 AR5K_QCU_STS_FRMPENDCNT, 0, false);
913
914 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
915 return -EIO;
916 }
917
918 return ret;
919}
920#endif
921
922 637
923/*********************\ 638/*********************\
924* Key table functions * 639* Key table functions *
@@ -971,19 +686,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
971 return 0; 686 return 0;
972} 687}
973 688
974/*
975 * Check if a table entry is valid
976 */
977int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
978{
979 ATH5K_TRACE(ah->ah_sc);
980 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
981
982 /* Check the validation flag at the end of the entry */
983 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
984 AR5K_KEYTABLE_VALID;
985}
986
987static 689static
988int ath5k_keycache_type(const struct ieee80211_key_conf *key) 690int ath5k_keycache_type(const struct ieee80211_key_conf *key)
989{ 691{
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index eff3323efb4b..b6704c93f808 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -20,8 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#define _ATH5K_PHY
24
25#include <linux/delay.h> 23#include <linux/delay.h>
26 24
27#include "ath5k.h" 25#include "ath5k.h"
@@ -1104,28 +1102,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1104 PHY calibration 1102 PHY calibration
1105\*****************/ 1103\*****************/
1106 1104
1107void
1108ath5k_hw_calibration_poll(struct ath5k_hw *ah)
1109{
1110 /* Calibration interval in jiffies */
1111 unsigned long cal_intval;
1112
1113 cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
1114
1115 /* Initialize timestamp if needed */
1116 if (!ah->ah_cal_tstamp)
1117 ah->ah_cal_tstamp = jiffies;
1118
1119 /* For now we always do full calibration
1120 * Mark software interrupt mask and fire software
1121 * interrupt (bit gets auto-cleared) */
1122 if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
1123 ah->ah_cal_tstamp = jiffies;
1124 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
1125 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
1126 }
1127}
1128
1129static int sign_extend(int val, const int nbits) 1105static int sign_extend(int val, const int nbits)
1130{ 1106{
1131 int order = BIT(nbits-1); 1107 int order = BIT(nbits-1);
@@ -1190,7 +1166,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1190 * The median of the values in the history is then loaded into the 1166 * The median of the values in the history is then loaded into the
1191 * hardware for its own use for RSSI and CCA measurements. 1167 * hardware for its own use for RSSI and CCA measurements.
1192 */ 1168 */
1193void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) 1169static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1194{ 1170{
1195 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1171 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1196 u32 val; 1172 u32 val;
@@ -1399,7 +1375,11 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1399 } 1375 }
1400 1376
1401 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; 1377 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1402 q_coffd = q_pwr >> 7; 1378
1379 if (ah->ah_version == AR5K_AR5211)
1380 q_coffd = q_pwr >> 6;
1381 else
1382 q_coffd = q_pwr >> 7;
1403 1383
1404 /* protect against divide by 0 and loss of sign bits */ 1384 /* protect against divide by 0 and loss of sign bits */
1405 if (i_coffd == 0 || q_coffd < 2) 1385 if (i_coffd == 0 || q_coffd < 2)
@@ -1768,7 +1748,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1768* Antenna control * 1748* Antenna control *
1769\*****************/ 1749\*****************/
1770 1750
1771void /*TODO:Boundary check*/ 1751static void /*TODO:Boundary check*/
1772ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) 1752ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1773{ 1753{
1774 ATH5K_TRACE(ah->ah_sc); 1754 ATH5K_TRACE(ah->ah_sc);
@@ -1777,16 +1757,6 @@ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1777 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); 1757 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1778} 1758}
1779 1759
1780unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1781{
1782 ATH5K_TRACE(ah->ah_sc);
1783
1784 if (ah->ah_version != AR5K_AR5210)
1785 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
1786
1787 return false; /*XXX: What do we return for 5210 ?*/
1788}
1789
1790/* 1760/*
1791 * Enable/disable fast rx antenna diversity 1761 * Enable/disable fast rx antenna diversity
1792 */ 1762 */
@@ -1930,6 +1900,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1930 1900
1931 ah->ah_tx_ant = tx_ant; 1901 ah->ah_tx_ant = tx_ant;
1932 ah->ah_ant_mode = ant_mode; 1902 ah->ah_ant_mode = ant_mode;
1903 ah->ah_def_ant = def_ant;
1933 1904
1934 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; 1905 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
1935 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; 1906 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
@@ -2440,19 +2411,6 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2440 pcdac_tmp = pcdac_high_pwr; 2411 pcdac_tmp = pcdac_high_pwr;
2441 2412
2442 edge_flag = 0x40; 2413 edge_flag = 0x40;
2443#if 0
2444 /* If both min and max power limits are in lower
2445 * power curve's range, only use the low power curve.
2446 * TODO: min/max levels are related to target
2447 * power values requested from driver/user
2448 * XXX: Is this really needed ? */
2449 if (min_pwr < table_max[1] &&
2450 max_pwr < table_max[1]) {
2451 edge_flag = 0;
2452 pcdac_tmp = pcdac_low_pwr;
2453 max_pwr_idx = (table_max[1] - table_min[1])/2;
2454 }
2455#endif
2456 } else { 2414 } else {
2457 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ 2415 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
2458 pcdac_high_pwr = ah->ah_txpower.tmpL[0]; 2416 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
@@ -3143,5 +3101,3 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3143 3101
3144 return ath5k_hw_txpower(ah, channel, ee_mode, txpower); 3102 return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
3145} 3103}
3146
3147#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 9122a8556f45..f5831da33f7b 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -517,23 +517,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
517} 517}
518 518
519/* 519/*
520 * Get slot time from DCU
521 */
522unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
523{
524 unsigned int slot_time_clock;
525
526 ATH5K_TRACE(ah->ah_sc);
527
528 if (ah->ah_version == AR5K_AR5210)
529 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
530 else
531 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
532
533 return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
534}
535
536/*
537 * Set slot time on DCU 520 * Set slot time on DCU
538 */ 521 */
539int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 522int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 1464f89b249c..45d62e915e4c 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -212,10 +212,10 @@
212 * MIB control register 212 * MIB control register
213 */ 213 */
214#define AR5K_MIBC 0x0040 /* Register Address */ 214#define AR5K_MIBC 0x0040 /* Register Address */
215#define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */ 215#define AR5K_MIBC_COW 0x00000001 /* Counter Overflow Warning */
216#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ 216#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */
217#define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */ 217#define AR5K_MIBC_CMC 0x00000004 /* Clear MIB Counters */
218#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */ 218#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe, increment all */
219 219
220/* 220/*
221 * Timeout prescale register 221 * Timeout prescale register
@@ -1516,7 +1516,14 @@
1516 AR5K_NAV_5210 : AR5K_NAV_5211) 1516 AR5K_NAV_5210 : AR5K_NAV_5211)
1517 1517
1518/* 1518/*
1519 * RTS success register 1519 * MIB counters:
1520 *
1521 * max value is 0xc000, if this is reached we get a MIB interrupt.
1522 * they can be controlled via AR5K_MIBC and are cleared on read.
1523 */
1524
1525/*
1526 * RTS success (MIB counter)
1520 */ 1527 */
1521#define AR5K_RTS_OK_5210 0x8090 1528#define AR5K_RTS_OK_5210 0x8090
1522#define AR5K_RTS_OK_5211 0x8088 1529#define AR5K_RTS_OK_5211 0x8088
@@ -1524,7 +1531,7 @@
1524 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) 1531 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
1525 1532
1526/* 1533/*
1527 * RTS failure register 1534 * RTS failure (MIB counter)
1528 */ 1535 */
1529#define AR5K_RTS_FAIL_5210 0x8094 1536#define AR5K_RTS_FAIL_5210 0x8094
1530#define AR5K_RTS_FAIL_5211 0x808c 1537#define AR5K_RTS_FAIL_5211 0x808c
@@ -1532,7 +1539,7 @@
1532 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) 1539 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
1533 1540
1534/* 1541/*
1535 * ACK failure register 1542 * ACK failure (MIB counter)
1536 */ 1543 */
1537#define AR5K_ACK_FAIL_5210 0x8098 1544#define AR5K_ACK_FAIL_5210 0x8098
1538#define AR5K_ACK_FAIL_5211 0x8090 1545#define AR5K_ACK_FAIL_5211 0x8090
@@ -1540,7 +1547,7 @@
1540 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) 1547 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
1541 1548
1542/* 1549/*
1543 * FCS failure register 1550 * FCS failure (MIB counter)
1544 */ 1551 */
1545#define AR5K_FCS_FAIL_5210 0x809c 1552#define AR5K_FCS_FAIL_5210 0x809c
1546#define AR5K_FCS_FAIL_5211 0x8094 1553#define AR5K_FCS_FAIL_5211 0x8094
@@ -1667,11 +1674,17 @@
1667 1674
1668/* 1675/*
1669 * Profile count registers 1676 * Profile count registers
1677 *
1678 * These registers can be cleared and freezed with ATH5K_MIBC, but they do not
1679 * generate a MIB interrupt.
1680 * Instead of overflowing, they shift by one bit to the right. All registers
1681 * shift together, i.e. when one reaches the max, all shift at the same time by
1682 * one bit to the right. This way we should always get consistent values.
1670 */ 1683 */
1671#define AR5K_PROFCNT_TX 0x80ec /* Tx count */ 1684#define AR5K_PROFCNT_TX 0x80ec /* Tx count */
1672#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ 1685#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */
1673#define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */ 1686#define AR5K_PROFCNT_RXCLR 0x80f4 /* Busy count */
1674#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ 1687#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle counter */
1675 1688
1676/* 1689/*
1677 * Quiet period control registers 1690 * Quiet period control registers
@@ -1758,7 +1771,7 @@
1758#define AR5K_CCK_FIL_CNT 0x8128 1771#define AR5K_CCK_FIL_CNT 0x8128
1759 1772
1760/* 1773/*
1761 * PHY Error Counters (?) 1774 * PHY Error Counters (same masks as AR5K_PHY_ERR_FIL)
1762 */ 1775 */
1763#define AR5K_PHYERR_CNT1 0x812c 1776#define AR5K_PHYERR_CNT1 0x812c
1764#define AR5K_PHYERR_CNT1_MASK 0x8130 1777#define AR5K_PHYERR_CNT1_MASK 0x8130
@@ -1766,6 +1779,9 @@
1766#define AR5K_PHYERR_CNT2 0x8134 1779#define AR5K_PHYERR_CNT2 0x8134
1767#define AR5K_PHYERR_CNT2_MASK 0x8138 1780#define AR5K_PHYERR_CNT2_MASK 0x8138
1768 1781
1782/* if the PHY Error Counters reach this maximum, we get MIB interrupts */
1783#define ATH5K_PHYERR_CNT_MAX 0x00c00000
1784
1769/* 1785/*
1770 * TSF Threshold register (?) 1786 * TSF Threshold register (?)
1771 */ 1787 */
@@ -1974,7 +1990,7 @@
1974#define AR5K_PHY_SETTLING 0x9844 /* Register Address */ 1990#define AR5K_PHY_SETTLING 0x9844 /* Register Address */
1975#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ 1991#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
1976#define AR5K_PHY_SETTLING_AGC_S 0 1992#define AR5K_PHY_SETTLING_AGC_S 0
1977#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ 1993#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settling time */
1978#define AR5K_PHY_SETTLING_SWITCH_S 7 1994#define AR5K_PHY_SETTLING_SWITCH_S 7
1979 1995
1980/* 1996/*
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index cbf28e379843..44bbbf2a6edd 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -19,8 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#define _ATH5K_RESET
23
24/*****************************\ 22/*****************************\
25 Reset functions and helpers 23 Reset functions and helpers
26\*****************************/ 24\*****************************/
@@ -34,6 +32,27 @@
34#include "base.h" 32#include "base.h"
35#include "debug.h" 33#include "debug.h"
36 34
35/*
36 * Check if a register write has been completed
37 */
38int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
39 bool is_set)
40{
41 int i;
42 u32 data;
43
44 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
45 data = ath5k_hw_reg_read(ah, reg);
46 if (is_set && (data & flag))
47 break;
48 else if ((data & flag) == val)
49 break;
50 udelay(15);
51 }
52
53 return (i <= 0) ? -EAGAIN : 0;
54}
55
37/** 56/**
38 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 57 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
39 * 58 *
@@ -221,8 +240,8 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
221/* 240/*
222 * Sleep control 241 * Sleep control
223 */ 242 */
224int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, 243static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
225 bool set_chip, u16 sleep_duration) 244 bool set_chip, u16 sleep_duration)
226{ 245{
227 unsigned int i; 246 unsigned int i;
228 u32 staid, data; 247 u32 staid, data;
@@ -1017,11 +1036,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1017 if (ret) 1036 if (ret)
1018 return ret; 1037 return ret;
1019 1038
1020 /*
1021 * Initialize operating mode
1022 */
1023 ah->ah_op_mode = op_mode;
1024
1025 /* PHY access enable */ 1039 /* PHY access enable */
1026 if (ah->ah_mac_srev >= AR5K_SREV_AR5211) 1040 if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
1027 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); 1041 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
@@ -1192,7 +1206,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1192 ath5k_hw_set_associd(ah); 1206 ath5k_hw_set_associd(ah);
1193 1207
1194 /* Set PCU config */ 1208 /* Set PCU config */
1195 ath5k_hw_set_opmode(ah); 1209 ath5k_hw_set_opmode(ah, op_mode);
1196 1210
1197 /* Clear any pending interrupts 1211 /* Clear any pending interrupts
1198 * PISR/SISR Not available on 5210 */ 1212 * PISR/SISR Not available on 5210 */
@@ -1378,7 +1392,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1378 * external 32KHz crystal when sleeping if one 1392 * external 32KHz crystal when sleeping if one
1379 * exists */ 1393 * exists */
1380 if (ah->ah_version == AR5K_AR5212 && 1394 if (ah->ah_version == AR5K_AR5212 &&
1381 ah->ah_op_mode != NL80211_IFTYPE_AP) 1395 op_mode != NL80211_IFTYPE_AP)
1382 ath5k_hw_set_sleep_clock(ah, true); 1396 ath5k_hw_set_sleep_clock(ah, true);
1383 1397
1384 /* 1398 /*
@@ -1388,5 +1402,3 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1388 ath5k_hw_reset_tsf(ah); 1402 ath5k_hw_reset_tsf(ah);
1389 return 0; 1403 return 0;
1390} 1404}
1391
1392#undef _ATH5K_RESET