aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c676
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h74
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c361
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c385
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c10
10 files changed, 1390 insertions, 151 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index f5b971973d31..cc648b6ae31c 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -17,14 +17,99 @@
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h" 18#include "hw-ops.h"
19 19
20struct ani_ofdm_level_entry {
21 int spur_immunity_level;
22 int fir_step_level;
23 int ofdm_weak_signal_on;
24};
25
26/* values here are relative to the INI */
27
28/*
29 * Legend:
30 *
31 * SI: Spur immunity
32 * FS: FIR Step
33 * WS: OFDM / CCK Weak Signal detection
34 * MRC-CCK: Maximal Ratio Combining for CCK
35 */
36
37static const struct ani_ofdm_level_entry ofdm_level_table[] = {
38 /* SI FS WS */
39 { 0, 0, 1 }, /* lvl 0 */
40 { 1, 1, 1 }, /* lvl 1 */
41 { 2, 2, 1 }, /* lvl 2 */
42 { 3, 2, 1 }, /* lvl 3 (default) */
43 { 4, 3, 1 }, /* lvl 4 */
44 { 5, 4, 1 }, /* lvl 5 */
45 { 6, 5, 1 }, /* lvl 6 */
46 { 7, 6, 1 }, /* lvl 7 */
47 { 7, 7, 1 }, /* lvl 8 */
48 { 7, 8, 0 } /* lvl 9 */
49};
50#define ATH9K_ANI_OFDM_NUM_LEVEL \
51 (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0]))
52#define ATH9K_ANI_OFDM_MAX_LEVEL \
53 (ATH9K_ANI_OFDM_NUM_LEVEL-1)
54#define ATH9K_ANI_OFDM_DEF_LEVEL \
55 3 /* default level - matches the INI settings */
56
57/*
58 * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
59 * With OFDM for single stream you just add up all antenna inputs, you're
60 * only interested in what you get after FFT. Signal aligment is also not
61 * required for OFDM because any phase difference adds up in the frequency
62 * domain.
63 *
64 * MRC requires extra work for use with CCK. You need to align the antenna
65 * signals from the different antenna before you can add the signals together.
66 * You need aligment of signals as CCK is in time domain, so addition can cancel
67 * your signal completely if phase is 180 degrees (think of adding sine waves).
68 * You also need to remove noise before the addition and this is where ANI
69 * MRC CCK comes into play. One of the antenna inputs may be stronger but
70 * lower SNR, so just adding after alignment can be dangerous.
71 *
72 * Regardless of alignment in time, the antenna signals add constructively after
73 * FFT and improve your reception. For more information:
74 *
75 * http://en.wikipedia.org/wiki/Maximal-ratio_combining
76 */
77
78struct ani_cck_level_entry {
79 int fir_step_level;
80 int mrc_cck_on;
81};
82
83static const struct ani_cck_level_entry cck_level_table[] = {
84 /* FS MRC-CCK */
85 { 0, 1 }, /* lvl 0 */
86 { 1, 1 }, /* lvl 1 */
87 { 2, 1 }, /* lvl 2 (default) */
88 { 3, 1 }, /* lvl 3 */
89 { 4, 0 }, /* lvl 4 */
90 { 5, 0 }, /* lvl 5 */
91 { 6, 0 }, /* lvl 6 */
92 { 7, 0 }, /* lvl 7 (only for high rssi) */
93 { 8, 0 } /* lvl 8 (only for high rssi) */
94};
95
96#define ATH9K_ANI_CCK_NUM_LEVEL \
97 (sizeof(cck_level_table)/sizeof(cck_level_table[0]))
98#define ATH9K_ANI_CCK_MAX_LEVEL \
99 (ATH9K_ANI_CCK_NUM_LEVEL-1)
100#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
101 (ATH9K_ANI_CCK_NUM_LEVEL-3)
102#define ATH9K_ANI_CCK_DEF_LEVEL \
103 2 /* default level - matches the INI settings */
104
20/* Private to ani.c */ 105/* Private to ani.c */
21static inline void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) 106static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
22{ 107{
23 ath9k_hw_private_ops(ah)->ani_lower_immunity(ah); 108 ath9k_hw_private_ops(ah)->ani_lower_immunity(ah);
24} 109}
25 110
26static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 111int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
27 struct ath9k_channel *chan) 112 struct ath9k_channel *chan)
28{ 113{
29 int i; 114 int i;
30 115
@@ -54,7 +139,7 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
54 stats->beacons += REG_READ(ah, AR_BEACON_CNT); 139 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
55} 140}
56 141
57static void ath9k_ani_restart(struct ath_hw *ah) 142static void ath9k_ani_restart_old(struct ath_hw *ah)
58{ 143{
59 struct ar5416AniState *aniState; 144 struct ar5416AniState *aniState;
60 struct ath_common *common = ath9k_hw_common(ah); 145 struct ath_common *common = ath9k_hw_common(ah);
@@ -102,7 +187,42 @@ static void ath9k_ani_restart(struct ath_hw *ah)
102 aniState->cckPhyErrCount = 0; 187 aniState->cckPhyErrCount = 0;
103} 188}
104 189
105static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) 190static void ath9k_ani_restart_new(struct ath_hw *ah)
191{
192 struct ar5416AniState *aniState;
193 struct ath_common *common = ath9k_hw_common(ah);
194
195 if (!DO_ANI(ah))
196 return;
197
198 aniState = ah->curani;
199 aniState->listenTime = 0;
200
201 aniState->ofdmPhyErrBase = 0;
202 aniState->cckPhyErrBase = 0;
203
204 ath_print(common, ATH_DBG_ANI,
205 "Writing ofdmbase=%08x cckbase=%08x\n",
206 aniState->ofdmPhyErrBase,
207 aniState->cckPhyErrBase);
208
209 ENABLE_REGWRITE_BUFFER(ah);
210
211 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
212 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
213 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
214 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
215
216 REGWRITE_BUFFER_FLUSH(ah);
217 DISABLE_REGWRITE_BUFFER(ah);
218
219 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
220
221 aniState->ofdmPhyErrCount = 0;
222 aniState->cckPhyErrCount = 0;
223}
224
225static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
106{ 226{
107 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 227 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
108 struct ar5416AniState *aniState; 228 struct ar5416AniState *aniState;
@@ -174,7 +294,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
174 } 294 }
175} 295}
176 296
177static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) 297static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
178{ 298{
179 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 299 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
180 struct ar5416AniState *aniState; 300 struct ar5416AniState *aniState;
@@ -212,6 +332,124 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
212 } 332 }
213} 333}
214 334
335/* Adjust the OFDM Noise Immunity Level */
336static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
337{
338 struct ar5416AniState *aniState = ah->curani;
339 struct ath_common *common = ath9k_hw_common(ah);
340 const struct ani_ofdm_level_entry *entry_ofdm;
341 const struct ani_cck_level_entry *entry_cck;
342
343 aniState->noiseFloor = BEACON_RSSI(ah);
344
345 ath_print(common, ATH_DBG_ANI,
346 "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
347 aniState->ofdmNoiseImmunityLevel,
348 immunityLevel, aniState->noiseFloor,
349 aniState->rssiThrLow, aniState->rssiThrHigh);
350
351 aniState->ofdmNoiseImmunityLevel = immunityLevel;
352
353 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
354 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
355
356 if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
357 ath9k_hw_ani_control(ah,
358 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
359 entry_ofdm->spur_immunity_level);
360
361 if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
362 entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
363 ath9k_hw_ani_control(ah,
364 ATH9K_ANI_FIRSTEP_LEVEL,
365 entry_ofdm->fir_step_level);
366
367 if ((ah->opmode != NL80211_IFTYPE_STATION &&
368 ah->opmode != NL80211_IFTYPE_ADHOC) ||
369 aniState->noiseFloor <= aniState->rssiThrHigh) {
370 if (aniState->ofdmWeakSigDetectOff)
371 /* force on ofdm weak sig detect */
372 ath9k_hw_ani_control(ah,
373 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
374 true);
375 else if (aniState->ofdmWeakSigDetectOff ==
376 entry_ofdm->ofdm_weak_signal_on)
377 ath9k_hw_ani_control(ah,
378 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
379 entry_ofdm->ofdm_weak_signal_on);
380 }
381}
382
383static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
384{
385 struct ar5416AniState *aniState;
386
387 if (!DO_ANI(ah))
388 return;
389
390 aniState = ah->curani;
391
392 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
393 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
394}
395
396/*
397 * Set the ANI settings to match an CCK level.
398 */
399static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
400{
401 struct ar5416AniState *aniState = ah->curani;
402 struct ath_common *common = ath9k_hw_common(ah);
403 const struct ani_ofdm_level_entry *entry_ofdm;
404 const struct ani_cck_level_entry *entry_cck;
405
406 aniState->noiseFloor = BEACON_RSSI(ah);
407 ath_print(common, ATH_DBG_ANI,
408 "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
409 aniState->cckNoiseImmunityLevel, immunityLevel,
410 aniState->noiseFloor, aniState->rssiThrLow,
411 aniState->rssiThrHigh);
412
413 if ((ah->opmode == NL80211_IFTYPE_STATION ||
414 ah->opmode == NL80211_IFTYPE_ADHOC) &&
415 aniState->noiseFloor <= aniState->rssiThrLow &&
416 immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
417 immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
418
419 aniState->cckNoiseImmunityLevel = immunityLevel;
420
421 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
422 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
423
424 if (aniState->firstepLevel != entry_cck->fir_step_level &&
425 entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
426 ath9k_hw_ani_control(ah,
427 ATH9K_ANI_FIRSTEP_LEVEL,
428 entry_cck->fir_step_level);
429
430 /* Skip MRC CCK for pre AR9003 families */
431 if (!AR_SREV_9300_20_OR_LATER(ah))
432 return;
433
434 if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
435 ath9k_hw_ani_control(ah,
436 ATH9K_ANI_MRC_CCK,
437 entry_cck->mrc_cck_on);
438}
439
440static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah)
441{
442 struct ar5416AniState *aniState;
443
444 if (!DO_ANI(ah))
445 return;
446
447 aniState = ah->curani;
448
449 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
450 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
451}
452
215static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) 453static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
216{ 454{
217 struct ar5416AniState *aniState; 455 struct ar5416AniState *aniState;
@@ -265,6 +503,28 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
265 } 503 }
266} 504}
267 505
506/*
507 * only lower either OFDM or CCK errors per turn
508 * we lower the other one next time
509 */
510static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
511{
512 struct ar5416AniState *aniState;
513
514 aniState = ah->curani;
515
516 /* lower OFDM noise immunity */
517 if (aniState->ofdmNoiseImmunityLevel > 0 &&
518 (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
519 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1);
520 return;
521 }
522
523 /* lower CCK noise immunity */
524 if (aniState->cckNoiseImmunityLevel > 0)
525 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
526}
527
268static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) 528static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
269{ 529{
270 struct ath9k_channel *chan = ah->curchan; 530 struct ath9k_channel *chan = ah->curchan;
@@ -289,6 +549,7 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
289static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) 549static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
290{ 550{
291 struct ar5416AniState *aniState; 551 struct ar5416AniState *aniState;
552 struct ath_common *common = ath9k_hw_common(ah);
292 u32 txFrameCount, rxFrameCount, cycleCount; 553 u32 txFrameCount, rxFrameCount, cycleCount;
293 int32_t listenTime; 554 int32_t listenTime;
294 555
@@ -298,14 +559,16 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
298 559
299 aniState = ah->curani; 560 aniState = ah->curani;
300 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { 561 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
301
302 listenTime = 0; 562 listenTime = 0;
303 ah->stats.ast_ani_lzero++; 563 ah->stats.ast_ani_lzero++;
564 ath_print(common, ATH_DBG_ANI,
565 "1st call: aniState->cycleCount=%d\n",
566 aniState->cycleCount);
304 } else { 567 } else {
305 int32_t ccdelta = cycleCount - aniState->cycleCount; 568 int32_t ccdelta = cycleCount - aniState->cycleCount;
306 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; 569 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
307 int32_t tfdelta = txFrameCount - aniState->txFrameCount; 570 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
308 int32_t clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;; 571 int32_t clock_rate;
309 572
310 /* 573 /*
311 * convert HW counter values to ms using mode 574 * convert HW counter values to ms using mode
@@ -314,7 +577,13 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
314 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;; 577 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
315 578
316 listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate; 579 listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate;
580
581 ath_print(common, ATH_DBG_ANI,
582 "cyclecount=%d, rfcount=%d, "
583 "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
584 ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
317 } 585 }
586
318 aniState->cycleCount = cycleCount; 587 aniState->cycleCount = cycleCount;
319 aniState->txFrameCount = txFrameCount; 588 aniState->txFrameCount = txFrameCount;
320 aniState->rxFrameCount = rxFrameCount; 589 aniState->rxFrameCount = rxFrameCount;
@@ -375,7 +644,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
375 ah->curani->cckTrigLow = 644 ah->curani->cckTrigLow =
376 ah->config.cck_trig_low; 645 ah->config.cck_trig_low;
377 } 646 }
378 ath9k_ani_restart(ah); 647 ath9k_ani_restart_old(ah);
379 return; 648 return;
380 } 649 }
381 650
@@ -397,7 +666,101 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
397 666
398 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 667 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
399 ~ATH9K_RX_FILTER_PHYERR); 668 ~ATH9K_RX_FILTER_PHYERR);
400 ath9k_ani_restart(ah); 669 ath9k_ani_restart_old(ah);
670
671 ENABLE_REGWRITE_BUFFER(ah);
672
673 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
674 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
675
676 REGWRITE_BUFFER_FLUSH(ah);
677 DISABLE_REGWRITE_BUFFER(ah);
678}
679
680/*
681 * Restore the ANI parameters in the HAL and reset the statistics.
682 * This routine should be called for every hardware reset and for
683 * every channel change.
684 */
685static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
686{
687 struct ar5416AniState *aniState = ah->curani;
688 struct ath9k_channel *chan = ah->curchan;
689 struct ath_common *common = ath9k_hw_common(ah);
690
691 if (!DO_ANI(ah))
692 return;
693
694 BUG_ON(aniState == NULL);
695 ah->stats.ast_ani_reset++;
696
697 /* only allow a subset of functions in AP mode */
698 if (ah->opmode == NL80211_IFTYPE_AP) {
699 if (IS_CHAN_2GHZ(chan)) {
700 ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
701 ATH9K_ANI_FIRSTEP_LEVEL);
702 if (AR_SREV_9300_20_OR_LATER(ah))
703 ah->ani_function |= ATH9K_ANI_MRC_CCK;
704 } else
705 ah->ani_function = 0;
706 }
707
708 /* always allow mode (on/off) to be controlled */
709 ah->ani_function |= ATH9K_ANI_MODE;
710
711 if (is_scanning ||
712 (ah->opmode != NL80211_IFTYPE_STATION &&
713 ah->opmode != NL80211_IFTYPE_ADHOC)) {
714 /*
715 * If we're scanning or in AP mode, the defaults (ini)
716 * should be in place. For an AP we assume the historical
717 * levels for this channel are probably outdated so start
718 * from defaults instead.
719 */
720 if (aniState->ofdmNoiseImmunityLevel !=
721 ATH9K_ANI_OFDM_DEF_LEVEL ||
722 aniState->cckNoiseImmunityLevel !=
723 ATH9K_ANI_CCK_DEF_LEVEL) {
724 ath_print(common, ATH_DBG_ANI,
725 "Restore defaults: opmode %u "
726 "chan %d Mhz/0x%x is_scanning=%d "
727 "ofdm:%d cck:%d\n",
728 ah->opmode,
729 chan->channel,
730 chan->channelFlags,
731 is_scanning,
732 aniState->ofdmNoiseImmunityLevel,
733 aniState->cckNoiseImmunityLevel);
734
735 ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
736 ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
737 }
738 } else {
739 /*
740 * restore historical levels for this channel
741 */
742 ath_print(common, ATH_DBG_ANI,
743 "Restore history: opmode %u "
744 "chan %d Mhz/0x%x is_scanning=%d "
745 "ofdm:%d cck:%d\n",
746 ah->opmode,
747 chan->channel,
748 chan->channelFlags,
749 is_scanning,
750 aniState->ofdmNoiseImmunityLevel,
751 aniState->cckNoiseImmunityLevel);
752
753 ath9k_hw_set_ofdm_nil(ah,
754 aniState->ofdmNoiseImmunityLevel);
755 ath9k_hw_set_cck_nil(ah,
756 aniState->cckNoiseImmunityLevel);
757 }
758
759 /*
760 * enable phy counters if hw supports or if not, enable phy
761 * interrupts (so we can count each one)
762 */
763 ath9k_ani_restart_new(ah);
401 764
402 ENABLE_REGWRITE_BUFFER(ah); 765 ENABLE_REGWRITE_BUFFER(ah);
403 766
@@ -425,7 +788,7 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
425 listenTime = ath9k_hw_ani_get_listen_time(ah); 788 listenTime = ath9k_hw_ani_get_listen_time(ah);
426 if (listenTime < 0) { 789 if (listenTime < 0) {
427 ah->stats.ast_ani_lneg++; 790 ah->stats.ast_ani_lneg++;
428 ath9k_ani_restart(ah); 791 ath9k_ani_restart_old(ah);
429 return; 792 return;
430 } 793 }
431 794
@@ -479,17 +842,163 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
479 aniState->cckPhyErrCount <= aniState->listenTime * 842 aniState->cckPhyErrCount <= aniState->listenTime *
480 aniState->cckTrigLow / 1000) 843 aniState->cckTrigLow / 1000)
481 ath9k_hw_ani_lower_immunity(ah); 844 ath9k_hw_ani_lower_immunity(ah);
482 ath9k_ani_restart(ah); 845 ath9k_ani_restart_old(ah);
483 } else if (aniState->listenTime > ah->aniperiod) { 846 } else if (aniState->listenTime > ah->aniperiod) {
484 if (aniState->ofdmPhyErrCount > aniState->listenTime * 847 if (aniState->ofdmPhyErrCount > aniState->listenTime *
485 aniState->ofdmTrigHigh / 1000) { 848 aniState->ofdmTrigHigh / 1000) {
486 ath9k_hw_ani_ofdm_err_trigger(ah); 849 ath9k_hw_ani_ofdm_err_trigger_old(ah);
487 ath9k_ani_restart(ah); 850 ath9k_ani_restart_old(ah);
488 } else if (aniState->cckPhyErrCount > 851 } else if (aniState->cckPhyErrCount >
489 aniState->listenTime * aniState->cckTrigHigh / 852 aniState->listenTime * aniState->cckTrigHigh /
490 1000) { 853 1000) {
491 ath9k_hw_ani_cck_err_trigger(ah); 854 ath9k_hw_ani_cck_err_trigger_old(ah);
492 ath9k_ani_restart(ah); 855 ath9k_ani_restart_old(ah);
856 }
857 }
858}
859
860static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
861 struct ath9k_channel *chan)
862{
863 struct ar5416AniState *aniState;
864 struct ath_common *common = ath9k_hw_common(ah);
865 int32_t listenTime;
866 u32 phyCnt1, phyCnt2;
867 u32 ofdmPhyErrCnt, cckPhyErrCnt;
868 u32 ofdmPhyErrRate, cckPhyErrRate;
869
870 if (!DO_ANI(ah))
871 return;
872
873 aniState = ah->curani;
874 if (WARN_ON(!aniState))
875 return;
876
877 listenTime = ath9k_hw_ani_get_listen_time(ah);
878 if (listenTime <= 0) {
879 ah->stats.ast_ani_lneg++;
880 /* restart ANI period if listenTime is invalid */
881 ath_print(common, ATH_DBG_ANI,
882 "listenTime=%d - on new ani monitor\n",
883 listenTime);
884 ath9k_ani_restart_new(ah);
885 return;
886 }
887
888 aniState->listenTime += listenTime;
889
890 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
891
892 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
893 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
894
895 if (phyCnt1 < aniState->ofdmPhyErrBase ||
896 phyCnt2 < aniState->cckPhyErrBase) {
897 if (phyCnt1 < aniState->ofdmPhyErrBase) {
898 ath_print(common, ATH_DBG_ANI,
899 "phyCnt1 0x%x, resetting "
900 "counter value to 0x%x\n",
901 phyCnt1,
902 aniState->ofdmPhyErrBase);
903 REG_WRITE(ah, AR_PHY_ERR_1,
904 aniState->ofdmPhyErrBase);
905 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
906 AR_PHY_ERR_OFDM_TIMING);
907 }
908 if (phyCnt2 < aniState->cckPhyErrBase) {
909 ath_print(common, ATH_DBG_ANI,
910 "phyCnt2 0x%x, resetting "
911 "counter value to 0x%x\n",
912 phyCnt2,
913 aniState->cckPhyErrBase);
914 REG_WRITE(ah, AR_PHY_ERR_2,
915 aniState->cckPhyErrBase);
916 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
917 AR_PHY_ERR_CCK_TIMING);
918 }
919 return;
920 }
921
922 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
923 ah->stats.ast_ani_ofdmerrs +=
924 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
925 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
926
927 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
928 ah->stats.ast_ani_cckerrs +=
929 cckPhyErrCnt - aniState->cckPhyErrCount;
930 aniState->cckPhyErrCount = cckPhyErrCnt;
931
932 ath_print(common, ATH_DBG_ANI,
933 "Errors: OFDM=0x%08x-0x%08x=%d "
934 "CCK=0x%08x-0x%08x=%d\n",
935 phyCnt1,
936 aniState->ofdmPhyErrBase,
937 ofdmPhyErrCnt,
938 phyCnt2,
939 aniState->cckPhyErrBase,
940 cckPhyErrCnt);
941
942 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
943 aniState->listenTime;
944 cckPhyErrRate = aniState->cckPhyErrCount * 1000 /
945 aniState->listenTime;
946
947 ath_print(common, ATH_DBG_ANI,
948 "listenTime=%d OFDM:%d errs=%d/s CCK:%d "
949 "errs=%d/s ofdm_turn=%d\n",
950 listenTime, aniState->ofdmNoiseImmunityLevel,
951 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
952 cckPhyErrRate, aniState->ofdmsTurn);
953
954 if (aniState->listenTime > 5 * ah->aniperiod) {
955 if (ofdmPhyErrRate <= aniState->ofdmTrigLow &&
956 cckPhyErrRate <= aniState->cckTrigLow) {
957 ath_print(common, ATH_DBG_ANI,
958 "1. listenTime=%d OFDM:%d errs=%d/s(<%d) "
959 "CCK:%d errs=%d/s(<%d) -> "
960 "ath9k_hw_ani_lower_immunity()\n",
961 aniState->listenTime,
962 aniState->ofdmNoiseImmunityLevel,
963 ofdmPhyErrRate,
964 aniState->ofdmTrigLow,
965 aniState->cckNoiseImmunityLevel,
966 cckPhyErrRate,
967 aniState->cckTrigLow);
968 ath9k_hw_ani_lower_immunity(ah);
969 aniState->ofdmsTurn = !aniState->ofdmsTurn;
970 }
971 ath_print(common, ATH_DBG_ANI,
972 "1 listenTime=%d ofdm=%d/s cck=%d/s - "
973 "calling ath9k_ani_restart_new()\n",
974 aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate);
975 ath9k_ani_restart_new(ah);
976 } else if (aniState->listenTime > ah->aniperiod) {
977 /* check to see if need to raise immunity */
978 if (ofdmPhyErrRate > aniState->ofdmTrigHigh &&
979 (cckPhyErrRate <= aniState->cckTrigHigh ||
980 aniState->ofdmsTurn)) {
981 ath_print(common, ATH_DBG_ANI,
982 "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> "
983 "ath9k_hw_ani_ofdm_err_trigger_new()\n",
984 aniState->listenTime,
985 aniState->ofdmNoiseImmunityLevel,
986 ofdmPhyErrRate,
987 aniState->ofdmTrigHigh);
988 ath9k_hw_ani_ofdm_err_trigger_new(ah);
989 ath9k_ani_restart_new(ah);
990 aniState->ofdmsTurn = false;
991 } else if (cckPhyErrRate > aniState->cckTrigHigh) {
992 ath_print(common, ATH_DBG_ANI,
993 "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> "
994 "ath9k_hw_ani_cck_err_trigger_new()\n",
995 aniState->listenTime,
996 aniState->cckNoiseImmunityLevel,
997 cckPhyErrRate,
998 aniState->cckTrigHigh);
999 ath9k_hw_ani_cck_err_trigger_new(ah);
1000 ath9k_ani_restart_new(ah);
1001 aniState->ofdmsTurn = true;
493 } 1002 }
494 } 1003 }
495} 1004}
@@ -626,14 +1135,52 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
626 * check will never be true. 1135 * check will never be true.
627 */ 1136 */
628 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) 1137 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
629 ath9k_hw_ani_ofdm_err_trigger(ah); 1138 ath9k_hw_ani_ofdm_err_trigger_new(ah);
630 if (aniState->cckPhyErrCount > aniState->cckTrigHigh) 1139 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
631 ath9k_hw_ani_cck_err_trigger(ah); 1140 ath9k_hw_ani_cck_err_trigger_old(ah);
632 /* NB: always restart to insure the h/w counters are reset */ 1141 /* NB: always restart to insure the h/w counters are reset */
633 ath9k_ani_restart(ah); 1142 ath9k_ani_restart_old(ah);
634 } 1143 }
635} 1144}
636 1145
1146/*
1147 * Process a MIB interrupt. We may potentially be invoked because
1148 * any of the MIB counters overflow/trigger so don't assume we're
1149 * here because a PHY error counter triggered.
1150 */
1151static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah)
1152{
1153 u32 phyCnt1, phyCnt2;
1154
1155 /* Reset these counters regardless */
1156 REG_WRITE(ah, AR_FILT_OFDM, 0);
1157 REG_WRITE(ah, AR_FILT_CCK, 0);
1158 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
1159 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
1160
1161 /* Clear the mib counters and save them in the stats */
1162 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
1163
1164 if (!DO_ANI(ah)) {
1165 /*
1166 * We must always clear the interrupt cause by
1167 * resetting the phy error regs.
1168 */
1169 REG_WRITE(ah, AR_PHY_ERR_1, 0);
1170 REG_WRITE(ah, AR_PHY_ERR_2, 0);
1171 return;
1172 }
1173
1174 /* NB: these are not reset-on-read */
1175 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
1176 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
1177
1178 /* NB: always restart to insure the h/w counters are reset */
1179 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
1180 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK))
1181 ath9k_ani_restart_new(ah);
1182}
1183
637void ath9k_hw_ani_setup(struct ath_hw *ah) 1184void ath9k_hw_ani_setup(struct ath_hw *ah)
638{ 1185{
639 int i; 1186 int i;
@@ -660,22 +1207,70 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
660 1207
661 memset(ah->ani, 0, sizeof(ah->ani)); 1208 memset(ah->ani, 0, sizeof(ah->ani));
662 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { 1209 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
663 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; 1210 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
664 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; 1211 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
665 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; 1212 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
666 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; 1213
1214 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
1215 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW;
1216
1217 ah->ani[i].spurImmunityLevel =
1218 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1219
1220 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1221
1222 ah->ani[i].ofdmPhyErrBase = 0;
1223 ah->ani[i].cckPhyErrBase = 0;
1224
1225 if (AR_SREV_9300_20_OR_LATER(ah))
1226 ah->ani[i].mrcCCKOff =
1227 !ATH9K_ANI_ENABLE_MRC_CCK;
1228 else
1229 ah->ani[i].mrcCCKOff = true;
1230
1231 ah->ani[i].ofdmsTurn = true;
1232 } else {
1233 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
1234 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
1235
1236 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1237 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD;
1238
1239 ah->ani[i].spurImmunityLevel =
1240 ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
1241 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
1242
1243 ah->ani[i].ofdmPhyErrBase =
1244 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
1245 ah->ani[i].cckPhyErrBase =
1246 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1247 ah->ani[i].cckWeakSigThreshold =
1248 ATH9K_ANI_CCK_WEAK_SIG_THR;
1249 }
1250
667 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; 1251 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
668 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; 1252 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
669 ah->ani[i].ofdmWeakSigDetectOff = 1253 ah->ani[i].ofdmWeakSigDetectOff =
670 !ATH9K_ANI_USE_OFDM_WEAK_SIG; 1254 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
671 ah->ani[i].cckWeakSigThreshold = 1255 ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
672 ATH9K_ANI_CCK_WEAK_SIG_THR; 1256 }
673 ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 1257
674 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 1258 /*
675 ah->ani[i].ofdmPhyErrBase = 1259 * since we expect some ongoing maintenance on the tables, let's sanity
676 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; 1260 * check here default level should not modify INI setting.
677 ah->ani[i].cckPhyErrBase = 1261 */
678 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; 1262 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
1263 const struct ani_ofdm_level_entry *entry_ofdm;
1264 const struct ani_cck_level_entry *entry_cck;
1265
1266 entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
1267 entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
1268
1269 ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
1270 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
1271 } else {
1272 ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
1273 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
679 } 1274 }
680 1275
681 ath_print(common, ATH_DBG_ANI, 1276 ath_print(common, ATH_DBG_ANI,
@@ -694,7 +1289,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
694 1289
695 ath9k_enable_mib_counters(ah); 1290 ath9k_enable_mib_counters(ah);
696 1291
697 ah->aniperiod = ATH9K_ANI_PERIOD;
698 if (ah->config.enable_ani) 1292 if (ah->config.enable_ani)
699 ah->proc_phyerr |= HAL_PROCESS_ANI; 1293 ah->proc_phyerr |= HAL_PROCESS_ANI;
700} 1294}
@@ -709,4 +1303,20 @@ void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah)
709 1303
710 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old; 1304 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old;
711 ops->ani_monitor = ath9k_hw_ani_monitor_old; 1305 ops->ani_monitor = ath9k_hw_ani_monitor_old;
1306
1307 ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n");
1308}
1309
1310void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah)
1311{
1312 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1313 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1314
1315 priv_ops->ani_reset = ath9k_ani_reset_new;
1316 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new;
1317
1318 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new;
1319 ops->ani_monitor = ath9k_hw_ani_monitor_new;
1320
1321 ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n");
712} 1322}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 4631ab269697..f4d0a4d48b37 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -23,23 +23,55 @@
23 23
24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) 24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
25 25
26#define ATH9K_ANI_OFDM_TRIG_HIGH 500 26/* units are errors per second */
27#define ATH9K_ANI_OFDM_TRIG_LOW 200 27#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
28#define ATH9K_ANI_CCK_TRIG_HIGH 200 28#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 1000
29#define ATH9K_ANI_CCK_TRIG_LOW 100 29
30/* units are errors per second */
31#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
32#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400
33
34/* units are errors per second */
35#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
36#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600
37
38/* units are errors per second */
39#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
40#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300
41
30#define ATH9K_ANI_NOISE_IMMUNE_LVL 4 42#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
31#define ATH9K_ANI_USE_OFDM_WEAK_SIG true 43#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
32#define ATH9K_ANI_CCK_WEAK_SIG_THR false 44#define ATH9K_ANI_CCK_WEAK_SIG_THR false
33#define ATH9K_ANI_SPUR_IMMUNE_LVL 7 45
34#define ATH9K_ANI_FIRSTEP_LVL 0 46#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD 7
47#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3
48
49#define ATH9K_ANI_FIRSTEP_LVL_OLD 0
50#define ATH9K_ANI_FIRSTEP_LVL_NEW 2
51
35#define ATH9K_ANI_RSSI_THR_HIGH 40 52#define ATH9K_ANI_RSSI_THR_HIGH 40
36#define ATH9K_ANI_RSSI_THR_LOW 7 53#define ATH9K_ANI_RSSI_THR_LOW 7
37#define ATH9K_ANI_PERIOD 100 54
55#define ATH9K_ANI_PERIOD_OLD 100
56#define ATH9K_ANI_PERIOD_NEW 1000
57
58/* in ms */
59#define ATH9K_ANI_POLLINTERVAL_OLD 100
60#define ATH9K_ANI_POLLINTERVAL_NEW 1000
38 61
39#define HAL_NOISE_IMMUNE_MAX 4 62#define HAL_NOISE_IMMUNE_MAX 4
40#define HAL_SPUR_IMMUNE_MAX 7 63#define HAL_SPUR_IMMUNE_MAX 7
41#define HAL_FIRST_STEP_MAX 2 64#define HAL_FIRST_STEP_MAX 2
42 65
66#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
67#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20
68#define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0
69#define ATH9K_SIG_SPUR_IMM_SETTING_MAX 22
70
71#define ATH9K_ANI_ENABLE_MRC_CCK true
72
73/* values here are relative to the INI */
74
43enum ath9k_ani_cmd { 75enum ath9k_ani_cmd {
44 ATH9K_ANI_PRESENT = 0x1, 76 ATH9K_ANI_PRESENT = 0x1,
45 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2, 77 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
@@ -49,7 +81,8 @@ enum ath9k_ani_cmd {
49 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20, 81 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
50 ATH9K_ANI_MODE = 0x40, 82 ATH9K_ANI_MODE = 0x40,
51 ATH9K_ANI_PHYERR_RESET = 0x80, 83 ATH9K_ANI_PHYERR_RESET = 0x80,
52 ATH9K_ANI_ALL = 0xff 84 ATH9K_ANI_MRC_CCK = 0x100,
85 ATH9K_ANI_ALL = 0xfff
53}; 86};
54 87
55struct ath9k_mib_stats { 88struct ath9k_mib_stats {
@@ -60,9 +93,31 @@ struct ath9k_mib_stats {
60 u32 beacons; 93 u32 beacons;
61}; 94};
62 95
96/* INI default values for ANI registers */
97struct ath9k_ani_default {
98 u16 m1ThreshLow;
99 u16 m2ThreshLow;
100 u16 m1Thresh;
101 u16 m2Thresh;
102 u16 m2CountThr;
103 u16 m2CountThrLow;
104 u16 m1ThreshLowExt;
105 u16 m2ThreshLowExt;
106 u16 m1ThreshExt;
107 u16 m2ThreshExt;
108 u16 firstep;
109 u16 firstepLow;
110 u16 cycpwrThr1;
111 u16 cycpwrThr1Ext;
112};
113
63struct ar5416AniState { 114struct ar5416AniState {
64 struct ath9k_channel *c; 115 struct ath9k_channel *c;
65 u8 noiseImmunityLevel; 116 u8 noiseImmunityLevel;
117 u8 ofdmNoiseImmunityLevel;
118 u8 cckNoiseImmunityLevel;
119 bool ofdmsTurn;
120 u8 mrcCCKOff;
66 u8 spurImmunityLevel; 121 u8 spurImmunityLevel;
67 u8 firstepLevel; 122 u8 firstepLevel;
68 u8 ofdmWeakSigDetectOff; 123 u8 ofdmWeakSigDetectOff;
@@ -85,6 +140,7 @@ struct ar5416AniState {
85 int16_t pktRssi[2]; 140 int16_t pktRssi[2];
86 int16_t ofdmErrRssi[2]; 141 int16_t ofdmErrRssi[2];
87 int16_t cckErrRssi[2]; 142 int16_t cckErrRssi[2];
143 struct ath9k_ani_default iniDef;
88}; 144};
89 145
90struct ar5416Stats { 146struct ar5416Stats {
@@ -114,5 +170,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
114 u32 *rxf_pcnt, u32 *txf_pcnt); 170 u32 *rxf_pcnt, u32 *txf_pcnt);
115void ath9k_hw_ani_setup(struct ath_hw *ah); 171void ath9k_hw_ani_setup(struct ath_hw *ah);
116void ath9k_hw_ani_init(struct ath_hw *ah); 172void ath9k_hw_ani_init(struct ath_hw *ah);
173int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
174 struct ath9k_channel *chan);
117 175
118#endif /* ANI_H */ 176#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 96018d53f48e..ee34a495b0be 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -19,7 +19,30 @@
19#include "../regd.h" 19#include "../regd.h"
20#include "ar9002_phy.h" 20#include "ar9002_phy.h"
21 21
22/* All code below is for non single-chip solutions */ 22/* All code below is for AR5008, AR9001, AR9002 */
23
24static const int firstep_table[] =
25/* level: 0 1 2 3 4 5 6 7 8 */
26 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
27
28static const int cycpwrThr1_table[] =
29/* level: 0 1 2 3 4 5 6 7 8 */
30 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
31
32/*
33 * register values to turn OFDM weak signal detection OFF
34 */
35static const int m1ThreshLow_off = 127;
36static const int m2ThreshLow_off = 127;
37static const int m1Thresh_off = 127;
38static const int m2Thresh_off = 127;
39static const int m2CountThr_off = 31;
40static const int m2CountThrLow_off = 63;
41static const int m1ThreshLowExt_off = 127;
42static const int m2ThreshLowExt_off = 127;
43static const int m1ThreshExt_off = 127;
44static const int m2ThreshExt_off = 127;
45
23 46
24/** 47/**
25 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters 48 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
@@ -1026,8 +1049,9 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
1026 return pll; 1049 return pll;
1027} 1050}
1028 1051
1029static bool ar5008_hw_ani_control(struct ath_hw *ah, 1052static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
1030 enum ath9k_ani_cmd cmd, int param) 1053 enum ath9k_ani_cmd cmd,
1054 int param)
1031{ 1055{
1032 struct ar5416AniState *aniState = ah->curani; 1056 struct ar5416AniState *aniState = ah->curani;
1033 struct ath_common *common = ath9k_hw_common(ah); 1057 struct ath_common *common = ath9k_hw_common(ah);
@@ -1209,6 +1233,265 @@ static bool ar5008_hw_ani_control(struct ath_hw *ah,
1209 return true; 1233 return true;
1210} 1234}
1211 1235
1236static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
1237 enum ath9k_ani_cmd cmd,
1238 int param)
1239{
1240 struct ar5416AniState *aniState = ah->curani;
1241 struct ath_common *common = ath9k_hw_common(ah);
1242 struct ath9k_channel *chan = ah->curchan;
1243 s32 value, value2;
1244
1245 switch (cmd & ah->ani_function) {
1246 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
1247 /*
1248 * on == 1 means ofdm weak signal detection is ON
1249 * on == 1 is the default, for less noise immunity
1250 *
1251 * on == 0 means ofdm weak signal detection is OFF
1252 * on == 0 means more noise imm
1253 */
1254 u32 on = param ? 1 : 0;
1255 /*
1256 * make register setting for default
1257 * (weak sig detect ON) come from INI file
1258 */
1259 int m1ThreshLow = on ?
1260 aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
1261 int m2ThreshLow = on ?
1262 aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
1263 int m1Thresh = on ?
1264 aniState->iniDef.m1Thresh : m1Thresh_off;
1265 int m2Thresh = on ?
1266 aniState->iniDef.m2Thresh : m2Thresh_off;
1267 int m2CountThr = on ?
1268 aniState->iniDef.m2CountThr : m2CountThr_off;
1269 int m2CountThrLow = on ?
1270 aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
1271 int m1ThreshLowExt = on ?
1272 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
1273 int m2ThreshLowExt = on ?
1274 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
1275 int m1ThreshExt = on ?
1276 aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
1277 int m2ThreshExt = on ?
1278 aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
1279
1280 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1281 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
1282 m1ThreshLow);
1283 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1284 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
1285 m2ThreshLow);
1286 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1287 AR_PHY_SFCORR_M1_THRESH, m1Thresh);
1288 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1289 AR_PHY_SFCORR_M2_THRESH, m2Thresh);
1290 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1291 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
1292 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1293 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
1294 m2CountThrLow);
1295
1296 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1297 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
1298 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1299 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
1300 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1301 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
1302 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1303 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
1304
1305 if (on)
1306 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
1307 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1308 else
1309 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
1310 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1311
1312 if (!on != aniState->ofdmWeakSigDetectOff) {
1313 ath_print(common, ATH_DBG_ANI,
1314 "** ch %d: ofdm weak signal: %s=>%s\n",
1315 chan->channel,
1316 !aniState->ofdmWeakSigDetectOff ?
1317 "on" : "off",
1318 on ? "on" : "off");
1319 if (on)
1320 ah->stats.ast_ani_ofdmon++;
1321 else
1322 ah->stats.ast_ani_ofdmoff++;
1323 aniState->ofdmWeakSigDetectOff = !on;
1324 }
1325 break;
1326 }
1327 case ATH9K_ANI_FIRSTEP_LEVEL:{
1328 u32 level = param;
1329
1330 if (level >= ARRAY_SIZE(firstep_table)) {
1331 ath_print(common, ATH_DBG_ANI,
1332 "ATH9K_ANI_FIRSTEP_LEVEL: level "
1333 "out of range (%u > %u)\n",
1334 level,
1335 (unsigned) ARRAY_SIZE(firstep_table));
1336 return false;
1337 }
1338
1339 /*
1340 * make register setting relative to default
1341 * from INI file & cap value
1342 */
1343 value = firstep_table[level] -
1344 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
1345 aniState->iniDef.firstep;
1346 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
1347 value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
1348 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
1349 value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
1350 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
1351 AR_PHY_FIND_SIG_FIRSTEP,
1352 value);
1353 /*
1354 * we need to set first step low register too
1355 * make register setting relative to default
1356 * from INI file & cap value
1357 */
1358 value2 = firstep_table[level] -
1359 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
1360 aniState->iniDef.firstepLow;
1361 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
1362 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
1363 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
1364 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
1365
1366 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
1367 AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
1368
1369 if (level != aniState->firstepLevel) {
1370 ath_print(common, ATH_DBG_ANI,
1371 "** ch %d: level %d=>%d[def:%d] "
1372 "firstep[level]=%d ini=%d\n",
1373 chan->channel,
1374 aniState->firstepLevel,
1375 level,
1376 ATH9K_ANI_FIRSTEP_LVL_NEW,
1377 value,
1378 aniState->iniDef.firstep);
1379 ath_print(common, ATH_DBG_ANI,
1380 "** ch %d: level %d=>%d[def:%d] "
1381 "firstep_low[level]=%d ini=%d\n",
1382 chan->channel,
1383 aniState->firstepLevel,
1384 level,
1385 ATH9K_ANI_FIRSTEP_LVL_NEW,
1386 value2,
1387 aniState->iniDef.firstepLow);
1388 if (level > aniState->firstepLevel)
1389 ah->stats.ast_ani_stepup++;
1390 else if (level < aniState->firstepLevel)
1391 ah->stats.ast_ani_stepdown++;
1392 aniState->firstepLevel = level;
1393 }
1394 break;
1395 }
1396 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
1397 u32 level = param;
1398
1399 if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
1400 ath_print(common, ATH_DBG_ANI,
1401 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
1402 "out of range (%u > %u)\n",
1403 level,
1404 (unsigned) ARRAY_SIZE(cycpwrThr1_table));
1405 return false;
1406 }
1407 /*
1408 * make register setting relative to default
1409 * from INI file & cap value
1410 */
1411 value = cycpwrThr1_table[level] -
1412 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
1413 aniState->iniDef.cycpwrThr1;
1414 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
1415 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
1416 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
1417 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
1418 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
1419 AR_PHY_TIMING5_CYCPWR_THR1,
1420 value);
1421
1422 /*
1423 * set AR_PHY_EXT_CCA for extension channel
1424 * make register setting relative to default
1425 * from INI file & cap value
1426 */
1427 value2 = cycpwrThr1_table[level] -
1428 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
1429 aniState->iniDef.cycpwrThr1Ext;
1430 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
1431 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
1432 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
1433 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
1434 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
1435 AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
1436
1437 if (level != aniState->spurImmunityLevel) {
1438 ath_print(common, ATH_DBG_ANI,
1439 "** ch %d: level %d=>%d[def:%d] "
1440 "cycpwrThr1[level]=%d ini=%d\n",
1441 chan->channel,
1442 aniState->spurImmunityLevel,
1443 level,
1444 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
1445 value,
1446 aniState->iniDef.cycpwrThr1);
1447 ath_print(common, ATH_DBG_ANI,
1448 "** ch %d: level %d=>%d[def:%d] "
1449 "cycpwrThr1Ext[level]=%d ini=%d\n",
1450 chan->channel,
1451 aniState->spurImmunityLevel,
1452 level,
1453 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
1454 value2,
1455 aniState->iniDef.cycpwrThr1Ext);
1456 if (level > aniState->spurImmunityLevel)
1457 ah->stats.ast_ani_spurup++;
1458 else if (level < aniState->spurImmunityLevel)
1459 ah->stats.ast_ani_spurdown++;
1460 aniState->spurImmunityLevel = level;
1461 }
1462 break;
1463 }
1464 case ATH9K_ANI_MRC_CCK:
1465 /*
1466 * You should not see this as AR5008, AR9001, AR9002
1467 * does not have hardware support for MRC CCK.
1468 */
1469 WARN_ON(1);
1470 break;
1471 case ATH9K_ANI_PRESENT:
1472 break;
1473 default:
1474 ath_print(common, ATH_DBG_ANI,
1475 "invalid cmd %u\n", cmd);
1476 return false;
1477 }
1478
1479 ath_print(common, ATH_DBG_ANI,
1480 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
1481 "MRCcck=%s listenTime=%d CC=%d listen=%d "
1482 "ofdmErrs=%d cckErrs=%d\n",
1483 aniState->spurImmunityLevel,
1484 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
1485 aniState->firstepLevel,
1486 !aniState->mrcCCKOff ? "on" : "off",
1487 aniState->listenTime,
1488 aniState->cycleCount,
1489 aniState->listenTime,
1490 aniState->ofdmPhyErrCount,
1491 aniState->cckPhyErrCount);
1492 return true;
1493}
1494
1212static void ar5008_hw_do_getnf(struct ath_hw *ah, 1495static void ar5008_hw_do_getnf(struct ath_hw *ah,
1213 int16_t nfarray[NUM_NF_READINGS]) 1496 int16_t nfarray[NUM_NF_READINGS])
1214{ 1497{
@@ -1329,6 +1612,71 @@ static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1329 DISABLE_REGWRITE_BUFFER(ah); 1612 DISABLE_REGWRITE_BUFFER(ah);
1330} 1613}
1331 1614
1615/*
1616 * Initialize the ANI register values with default (ini) values.
1617 * This routine is called during a (full) hardware reset after
1618 * all the registers are initialised from the INI.
1619 */
1620static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1621{
1622 struct ar5416AniState *aniState;
1623 struct ath_common *common = ath9k_hw_common(ah);
1624 struct ath9k_channel *chan = ah->curchan;
1625 struct ath9k_ani_default *iniDef;
1626 int index;
1627 u32 val;
1628
1629 index = ath9k_hw_get_ani_channel_idx(ah, chan);
1630 aniState = &ah->ani[index];
1631 ah->curani = aniState;
1632 iniDef = &aniState->iniDef;
1633
1634 ath_print(common, ATH_DBG_ANI,
1635 "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
1636 ah->hw_version.macVersion,
1637 ah->hw_version.macRev,
1638 ah->opmode,
1639 chan->channel,
1640 chan->channelFlags);
1641
1642 val = REG_READ(ah, AR_PHY_SFCORR);
1643 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
1644 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
1645 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
1646
1647 val = REG_READ(ah, AR_PHY_SFCORR_LOW);
1648 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
1649 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
1650 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
1651
1652 val = REG_READ(ah, AR_PHY_SFCORR_EXT);
1653 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
1654 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
1655 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
1656 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
1657 iniDef->firstep = REG_READ_FIELD(ah,
1658 AR_PHY_FIND_SIG,
1659 AR_PHY_FIND_SIG_FIRSTEP);
1660 iniDef->firstepLow = REG_READ_FIELD(ah,
1661 AR_PHY_FIND_SIG_LOW,
1662 AR_PHY_FIND_SIG_FIRSTEP_LOW);
1663 iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
1664 AR_PHY_TIMING5,
1665 AR_PHY_TIMING5_CYCPWR_THR1);
1666 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
1667 AR_PHY_EXT_CCA,
1668 AR_PHY_EXT_TIMING5_CYCPWR_THR1);
1669
1670 /* these levels just got reset to defaults by the INI */
1671 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1672 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1673 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1674 aniState->mrcCCKOff = true; /* not available on pre AR9003 */
1675
1676 aniState->cycleCount = 0;
1677}
1678
1679
1332void ar5008_hw_attach_phy_ops(struct ath_hw *ah) 1680void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1333{ 1681{
1334 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1682 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1350,10 +1698,15 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1350 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; 1698 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
1351 priv_ops->restore_chainmask = ar5008_restore_chainmask; 1699 priv_ops->restore_chainmask = ar5008_restore_chainmask;
1352 priv_ops->set_diversity = ar5008_set_diversity; 1700 priv_ops->set_diversity = ar5008_set_diversity;
1353 priv_ops->ani_control = ar5008_hw_ani_control;
1354 priv_ops->do_getnf = ar5008_hw_do_getnf; 1701 priv_ops->do_getnf = ar5008_hw_do_getnf;
1355 priv_ops->loadnf = ar5008_hw_loadnf; 1702 priv_ops->loadnf = ar5008_hw_loadnf;
1356 1703
1704 if (modparam_force_new_ani) {
1705 priv_ops->ani_control = ar5008_hw_ani_control_new;
1706 priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
1707 } else
1708 priv_ops->ani_control = ar5008_hw_ani_control_old;
1709
1357 if (AR_SREV_9100(ah)) 1710 if (AR_SREV_9100(ah))
1358 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; 1711 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
1359 else if (AR_SREV_9160_10_OR_LATER(ah)) 1712 else if (AR_SREV_9160_10_OR_LATER(ah))
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 917eae02acda..0317ac9fc1b7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -20,6 +20,10 @@
20#include "ar9002_initvals.h" 20#include "ar9002_initvals.h"
21#include "ar9002_phy.h" 21#include "ar9002_phy.h"
22 22
23int modparam_force_new_ani;
24module_param_named(force_new_ani, modparam_force_new_ani, int, 0444);
25MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002");
26
23/* General hardware code for the A5008/AR9001/AR9002 hadware families */ 27/* General hardware code for the A5008/AR9001/AR9002 hadware families */
24 28
25static bool ar9002_hw_macversion_supported(u32 macversion) 29static bool ar9002_hw_macversion_supported(u32 macversion)
@@ -637,5 +641,8 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
637 ar9002_hw_attach_calib_ops(ah); 641 ar9002_hw_attach_calib_ops(ah);
638 ar9002_hw_attach_mac_ops(ah); 642 ar9002_hw_attach_mac_ops(ah);
639 643
640 ath9k_hw_attach_ani_ops_old(ah); 644 if (modparam_force_new_ani)
645 ath9k_hw_attach_ani_ops_new(ah);
646 else
647 ath9k_hw_attach_ani_ops_old(ah);
641} 648}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index b7574704f677..82c3ab756cd0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -314,5 +314,5 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
314 ar9003_hw_attach_calib_ops(ah); 314 ar9003_hw_attach_calib_ops(ah);
315 ar9003_hw_attach_mac_ops(ah); 315 ar9003_hw_attach_mac_ops(ah);
316 316
317 ath9k_hw_attach_ani_ops_old(ah); 317 ath9k_hw_attach_ani_ops_new(ah);
318} 318}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index c714579b5483..bababbe1edea 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -17,6 +17,28 @@
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_phy.h" 18#include "ar9003_phy.h"
19 19
20static const int firstep_table[] =
21/* level: 0 1 2 3 4 5 6 7 8 */
22 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
23
24static const int cycpwrThr1_table[] =
25/* level: 0 1 2 3 4 5 6 7 8 */
26 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
27
28/*
29 * register values to turn OFDM weak signal detection OFF
30 */
31static const int m1ThreshLow_off = 127;
32static const int m2ThreshLow_off = 127;
33static const int m1Thresh_off = 127;
34static const int m2Thresh_off = 127;
35static const int m2CountThr_off = 31;
36static const int m2CountThrLow_off = 63;
37static const int m1ThreshLowExt_off = 127;
38static const int m2ThreshLowExt_off = 127;
39static const int m1ThreshExt_off = 127;
40static const int m2ThreshExt_off = 127;
41
20/** 42/**
21 * ar9003_hw_set_channel - set channel on single-chip device 43 * ar9003_hw_set_channel - set channel on single-chip device
22 * @ah: atheros hardware structure 44 * @ah: atheros hardware structure
@@ -94,7 +116,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
94} 116}
95 117
96/** 118/**
97 * ar9003_hw_spur_mitigate - convert baseband spur frequency 119 * ar9003_hw_spur_mitigate_mrc_cck - convert baseband spur frequency
98 * @ah: atheros hardware structure 120 * @ah: atheros hardware structure
99 * @chan: 121 * @chan:
100 * 122 *
@@ -732,71 +754,68 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
732{ 754{
733 struct ar5416AniState *aniState = ah->curani; 755 struct ar5416AniState *aniState = ah->curani;
734 struct ath_common *common = ath9k_hw_common(ah); 756 struct ath_common *common = ath9k_hw_common(ah);
757 struct ath9k_channel *chan = ah->curchan;
758 s32 value, value2;
735 759
736 switch (cmd & ah->ani_function) { 760 switch (cmd & ah->ani_function) {
737 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
738 u32 level = param;
739
740 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
741 ath_print(common, ATH_DBG_ANI,
742 "level out of range (%u > %u)\n",
743 level,
744 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
745 return false;
746 }
747
748 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
749 AR_PHY_DESIRED_SZ_TOT_DES,
750 ah->totalSizeDesired[level]);
751 REG_RMW_FIELD(ah, AR_PHY_AGC,
752 AR_PHY_AGC_COARSE_LOW,
753 ah->coarse_low[level]);
754 REG_RMW_FIELD(ah, AR_PHY_AGC,
755 AR_PHY_AGC_COARSE_HIGH,
756 ah->coarse_high[level]);
757 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
758 AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
759
760 if (level > aniState->noiseImmunityLevel)
761 ah->stats.ast_ani_niup++;
762 else if (level < aniState->noiseImmunityLevel)
763 ah->stats.ast_ani_nidown++;
764 aniState->noiseImmunityLevel = level;
765 break;
766 }
767 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 761 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
768 const int m1ThreshLow[] = { 127, 50 }; 762 /*
769 const int m2ThreshLow[] = { 127, 40 }; 763 * on == 1 means ofdm weak signal detection is ON
770 const int m1Thresh[] = { 127, 0x4d }; 764 * on == 1 is the default, for less noise immunity
771 const int m2Thresh[] = { 127, 0x40 }; 765 *
772 const int m2CountThr[] = { 31, 16 }; 766 * on == 0 means ofdm weak signal detection is OFF
773 const int m2CountThrLow[] = { 63, 48 }; 767 * on == 0 means more noise imm
768 */
774 u32 on = param ? 1 : 0; 769 u32 on = param ? 1 : 0;
770 /*
771 * make register setting for default
772 * (weak sig detect ON) come from INI file
773 */
774 int m1ThreshLow = on ?
775 aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
776 int m2ThreshLow = on ?
777 aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
778 int m1Thresh = on ?
779 aniState->iniDef.m1Thresh : m1Thresh_off;
780 int m2Thresh = on ?
781 aniState->iniDef.m2Thresh : m2Thresh_off;
782 int m2CountThr = on ?
783 aniState->iniDef.m2CountThr : m2CountThr_off;
784 int m2CountThrLow = on ?
785 aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
786 int m1ThreshLowExt = on ?
787 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
788 int m2ThreshLowExt = on ?
789 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
790 int m1ThreshExt = on ?
791 aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
792 int m2ThreshExt = on ?
793 aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
775 794
776 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 795 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
777 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 796 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
778 m1ThreshLow[on]); 797 m1ThreshLow);
779 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
780 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 799 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
781 m2ThreshLow[on]); 800 m2ThreshLow);
782 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 801 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
783 AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); 802 AR_PHY_SFCORR_M1_THRESH, m1Thresh);
784 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 803 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
785 AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); 804 AR_PHY_SFCORR_M2_THRESH, m2Thresh);
786 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 805 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
787 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); 806 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
788 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 807 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
789 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 808 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
790 m2CountThrLow[on]); 809 m2CountThrLow);
791 810
792 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 811 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
793 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); 812 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
794 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 813 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
795 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]); 814 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
796 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 815 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
797 AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]); 816 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 817 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
799 AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]); 818 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
800 819
801 if (on) 820 if (on)
802 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 821 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
@@ -806,6 +825,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
806 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 825 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
807 826
808 if (!on != aniState->ofdmWeakSigDetectOff) { 827 if (!on != aniState->ofdmWeakSigDetectOff) {
828 ath_print(common, ATH_DBG_ANI,
829 "** ch %d: ofdm weak signal: %s=>%s\n",
830 chan->channel,
831 !aniState->ofdmWeakSigDetectOff ?
832 "on" : "off",
833 on ? "on" : "off");
809 if (on) 834 if (on)
810 ah->stats.ast_ani_ofdmon++; 835 ah->stats.ast_ani_ofdmon++;
811 else 836 else
@@ -814,64 +839,167 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
814 } 839 }
815 break; 840 break;
816 } 841 }
817 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
818 const int weakSigThrCck[] = { 8, 6 };
819 u32 high = param ? 1 : 0;
820
821 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
822 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
823 weakSigThrCck[high]);
824 if (high != aniState->cckWeakSigThreshold) {
825 if (high)
826 ah->stats.ast_ani_cckhigh++;
827 else
828 ah->stats.ast_ani_ccklow++;
829 aniState->cckWeakSigThreshold = high;
830 }
831 break;
832 }
833 case ATH9K_ANI_FIRSTEP_LEVEL:{ 842 case ATH9K_ANI_FIRSTEP_LEVEL:{
834 const int firstep[] = { 0, 4, 8 };
835 u32 level = param; 843 u32 level = param;
836 844
837 if (level >= ARRAY_SIZE(firstep)) { 845 if (level >= ARRAY_SIZE(firstep_table)) {
838 ath_print(common, ATH_DBG_ANI, 846 ath_print(common, ATH_DBG_ANI,
839 "level out of range (%u > %u)\n", 847 "ATH9K_ANI_FIRSTEP_LEVEL: level "
848 "out of range (%u > %u)\n",
840 level, 849 level,
841 (unsigned) ARRAY_SIZE(firstep)); 850 (unsigned) ARRAY_SIZE(firstep_table));
842 return false; 851 return false;
843 } 852 }
853
854 /*
855 * make register setting relative to default
856 * from INI file & cap value
857 */
858 value = firstep_table[level] -
859 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
860 aniState->iniDef.firstep;
861 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
862 value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
863 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
864 value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
844 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 865 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
845 AR_PHY_FIND_SIG_FIRSTEP, 866 AR_PHY_FIND_SIG_FIRSTEP,
846 firstep[level]); 867 value);
847 if (level > aniState->firstepLevel) 868 /*
848 ah->stats.ast_ani_stepup++; 869 * we need to set first step low register too
849 else if (level < aniState->firstepLevel) 870 * make register setting relative to default
850 ah->stats.ast_ani_stepdown++; 871 * from INI file & cap value
851 aniState->firstepLevel = level; 872 */
873 value2 = firstep_table[level] -
874 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
875 aniState->iniDef.firstepLow;
876 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
877 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
878 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
879 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
880
881 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
882 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
883
884 if (level != aniState->firstepLevel) {
885 ath_print(common, ATH_DBG_ANI,
886 "** ch %d: level %d=>%d[def:%d] "
887 "firstep[level]=%d ini=%d\n",
888 chan->channel,
889 aniState->firstepLevel,
890 level,
891 ATH9K_ANI_FIRSTEP_LVL_NEW,
892 value,
893 aniState->iniDef.firstep);
894 ath_print(common, ATH_DBG_ANI,
895 "** ch %d: level %d=>%d[def:%d] "
896 "firstep_low[level]=%d ini=%d\n",
897 chan->channel,
898 aniState->firstepLevel,
899 level,
900 ATH9K_ANI_FIRSTEP_LVL_NEW,
901 value2,
902 aniState->iniDef.firstepLow);
903 if (level > aniState->firstepLevel)
904 ah->stats.ast_ani_stepup++;
905 else if (level < aniState->firstepLevel)
906 ah->stats.ast_ani_stepdown++;
907 aniState->firstepLevel = level;
908 }
852 break; 909 break;
853 } 910 }
854 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ 911 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
855 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
856 u32 level = param; 912 u32 level = param;
857 913
858 if (level >= ARRAY_SIZE(cycpwrThr1)) { 914 if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
859 ath_print(common, ATH_DBG_ANI, 915 ath_print(common, ATH_DBG_ANI,
860 "level out of range (%u > %u)\n", 916 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
917 "out of range (%u > %u)\n",
861 level, 918 level,
862 (unsigned) ARRAY_SIZE(cycpwrThr1)); 919 (unsigned) ARRAY_SIZE(cycpwrThr1_table));
863 return false; 920 return false;
864 } 921 }
922 /*
923 * make register setting relative to default
924 * from INI file & cap value
925 */
926 value = cycpwrThr1_table[level] -
927 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
928 aniState->iniDef.cycpwrThr1;
929 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
930 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
931 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
932 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
865 REG_RMW_FIELD(ah, AR_PHY_TIMING5, 933 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
866 AR_PHY_TIMING5_CYCPWR_THR1, 934 AR_PHY_TIMING5_CYCPWR_THR1,
867 cycpwrThr1[level]); 935 value);
868 if (level > aniState->spurImmunityLevel) 936
869 ah->stats.ast_ani_spurup++; 937 /*
870 else if (level < aniState->spurImmunityLevel) 938 * set AR_PHY_EXT_CCA for extension channel
871 ah->stats.ast_ani_spurdown++; 939 * make register setting relative to default
872 aniState->spurImmunityLevel = level; 940 * from INI file & cap value
941 */
942 value2 = cycpwrThr1_table[level] -
943 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
944 aniState->iniDef.cycpwrThr1Ext;
945 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
946 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
947 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
948 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
949 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
950 AR_PHY_EXT_CYCPWR_THR1, value2);
951
952 if (level != aniState->spurImmunityLevel) {
953 ath_print(common, ATH_DBG_ANI,
954 "** ch %d: level %d=>%d[def:%d] "
955 "cycpwrThr1[level]=%d ini=%d\n",
956 chan->channel,
957 aniState->spurImmunityLevel,
958 level,
959 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
960 value,
961 aniState->iniDef.cycpwrThr1);
962 ath_print(common, ATH_DBG_ANI,
963 "** ch %d: level %d=>%d[def:%d] "
964 "cycpwrThr1Ext[level]=%d ini=%d\n",
965 chan->channel,
966 aniState->spurImmunityLevel,
967 level,
968 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
969 value2,
970 aniState->iniDef.cycpwrThr1Ext);
971 if (level > aniState->spurImmunityLevel)
972 ah->stats.ast_ani_spurup++;
973 else if (level < aniState->spurImmunityLevel)
974 ah->stats.ast_ani_spurdown++;
975 aniState->spurImmunityLevel = level;
976 }
873 break; 977 break;
874 } 978 }
979 case ATH9K_ANI_MRC_CCK:{
980 /*
981 * is_on == 1 means MRC CCK ON (default, less noise imm)
982 * is_on == 0 means MRC CCK is OFF (more noise imm)
983 */
984 bool is_on = param ? 1 : 0;
985 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
986 AR_PHY_MRC_CCK_ENABLE, is_on);
987 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
988 AR_PHY_MRC_CCK_MUX_REG, is_on);
989 if (!is_on != aniState->mrcCCKOff) {
990 ath_print(common, ATH_DBG_ANI,
991 "** ch %d: MRC CCK: %s=>%s\n",
992 chan->channel,
993 !aniState->mrcCCKOff ? "on" : "off",
994 is_on ? "on" : "off");
995 if (is_on)
996 ah->stats.ast_ani_ccklow++;
997 else
998 ah->stats.ast_ani_cckhigh++;
999 aniState->mrcCCKOff = !is_on;
1000 }
1001 break;
1002 }
875 case ATH9K_ANI_PRESENT: 1003 case ATH9K_ANI_PRESENT:
876 break; 1004 break;
877 default: 1005 default:
@@ -880,25 +1008,19 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
880 return false; 1008 return false;
881 } 1009 }
882 1010
883 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
884 ath_print(common, ATH_DBG_ANI, 1011 ath_print(common, ATH_DBG_ANI,
885 "noiseImmunityLevel=%d, spurImmunityLevel=%d, " 1012 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
886 "ofdmWeakSigDetectOff=%d\n", 1013 "MRCcck=%s listenTime=%d CC=%d listen=%d "
887 aniState->noiseImmunityLevel, 1014 "ofdmErrs=%d cckErrs=%d\n",
888 aniState->spurImmunityLevel, 1015 aniState->spurImmunityLevel,
889 !aniState->ofdmWeakSigDetectOff); 1016 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
890 ath_print(common, ATH_DBG_ANI,
891 "cckWeakSigThreshold=%d, "
892 "firstepLevel=%d, listenTime=%d\n",
893 aniState->cckWeakSigThreshold,
894 aniState->firstepLevel, 1017 aniState->firstepLevel,
895 aniState->listenTime); 1018 !aniState->mrcCCKOff ? "on" : "off",
896 ath_print(common, ATH_DBG_ANI, 1019 aniState->listenTime,
897 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", 1020 aniState->cycleCount,
898 aniState->cycleCount, 1021 aniState->listenTime,
899 aniState->ofdmPhyErrCount, 1022 aniState->ofdmPhyErrCount,
900 aniState->cckPhyErrCount); 1023 aniState->cckPhyErrCount);
901
902 return true; 1024 return true;
903} 1025}
904 1026
@@ -1111,6 +1233,70 @@ static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1111 } 1233 }
1112} 1234}
1113 1235
1236/*
1237 * Initialize the ANI register values with default (ini) values.
1238 * This routine is called during a (full) hardware reset after
1239 * all the registers are initialised from the INI.
1240 */
1241static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1242{
1243 struct ar5416AniState *aniState;
1244 struct ath_common *common = ath9k_hw_common(ah);
1245 struct ath9k_channel *chan = ah->curchan;
1246 struct ath9k_ani_default *iniDef;
1247 int index;
1248 u32 val;
1249
1250 index = ath9k_hw_get_ani_channel_idx(ah, chan);
1251 aniState = &ah->ani[index];
1252 ah->curani = aniState;
1253 iniDef = &aniState->iniDef;
1254
1255 ath_print(common, ATH_DBG_ANI,
1256 "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
1257 ah->hw_version.macVersion,
1258 ah->hw_version.macRev,
1259 ah->opmode,
1260 chan->channel,
1261 chan->channelFlags);
1262
1263 val = REG_READ(ah, AR_PHY_SFCORR);
1264 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
1265 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
1266 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
1267
1268 val = REG_READ(ah, AR_PHY_SFCORR_LOW);
1269 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
1270 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
1271 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
1272
1273 val = REG_READ(ah, AR_PHY_SFCORR_EXT);
1274 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
1275 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
1276 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
1277 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
1278 iniDef->firstep = REG_READ_FIELD(ah,
1279 AR_PHY_FIND_SIG,
1280 AR_PHY_FIND_SIG_FIRSTEP);
1281 iniDef->firstepLow = REG_READ_FIELD(ah,
1282 AR_PHY_FIND_SIG_LOW,
1283 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW);
1284 iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
1285 AR_PHY_TIMING5,
1286 AR_PHY_TIMING5_CYCPWR_THR1);
1287 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
1288 AR_PHY_EXT_CCA,
1289 AR_PHY_EXT_CYCPWR_THR1);
1290
1291 /* these levels just got reset to defaults by the INI */
1292 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1293 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1294 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1295 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
1296
1297 aniState->cycleCount = 0;
1298}
1299
1114void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1300void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1115{ 1301{
1116 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1302 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1131,6 +1317,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1131 priv_ops->ani_control = ar9003_hw_ani_control; 1317 priv_ops->ani_control = ar9003_hw_ani_control;
1132 priv_ops->do_getnf = ar9003_hw_do_getnf; 1318 priv_ops->do_getnf = ar9003_hw_do_getnf;
1133 priv_ops->loadnf = ar9003_hw_loadnf; 1319 priv_ops->loadnf = ar9003_hw_loadnf;
1320 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1134} 1321}
1135 1322
1136void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) 1323void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 82aca4b6154c..c00946ddd97e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -417,7 +417,8 @@ int ath_beaconq_config(struct ath_softc *sc);
417 417
418#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ 418#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
419#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ 419#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
420#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ 420#define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */
421#define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */
421#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 422#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
422#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 423#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
423 424
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5f46861fd100..739be8f6e6af 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -75,6 +75,15 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
75 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); 75 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
76} 76}
77 77
78static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
79{
80 /* You will not have this callback if using the old ANI */
81 if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
82 return;
83
84 ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
85}
86
78/********************/ 87/********************/
79/* Helper Functions */ 88/* Helper Functions */
80/********************/ 89/********************/
@@ -560,6 +569,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
560 ah->ani_function = ATH9K_ANI_ALL; 569 ah->ani_function = ATH9K_ANI_ALL;
561 if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 570 if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
562 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; 571 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
572 if (!AR_SREV_9300_20_OR_LATER(ah))
573 ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
563 574
564 ath9k_hw_init_mode_regs(ah); 575 ath9k_hw_init_mode_regs(ah);
565 576
@@ -1360,6 +1371,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1360 ath9k_hw_resettxqueue(ah, i); 1371 ath9k_hw_resettxqueue(ah, i);
1361 1372
1362 ath9k_hw_init_interrupt_masks(ah, ah->opmode); 1373 ath9k_hw_init_interrupt_masks(ah, ah->opmode);
1374 ath9k_hw_ani_cache_ini_regs(ah);
1363 ath9k_hw_init_qos(ah); 1375 ath9k_hw_init_qos(ah);
1364 1376
1365 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 1377 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 790a4572270f..009f0fafee5d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -266,6 +266,7 @@ struct ath9k_ops_config {
266 int spurmode; 266 int spurmode;
267 u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; 267 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
268 u8 max_txtrig_level; 268 u8 max_txtrig_level;
269 u16 ani_poll_interval; /* ANI poll interval in ms */
269}; 270};
270 271
271enum ath9k_int { 272enum ath9k_int {
@@ -520,6 +521,8 @@ struct ath_gen_timer_table {
520 * few dB more of noise immunity. If you have a strong time-varying 521 * few dB more of noise immunity. If you have a strong time-varying
521 * interference that is causing false detections (OFDM timing errors or 522 * interference that is causing false detections (OFDM timing errors or
522 * CCK timing errors) the level can be increased. 523 * CCK timing errors) the level can be increased.
524 * @ani_cache_ini_regs: cache the values for ANI from the initial
525 * register settings through the register initialization.
523 */ 526 */
524struct ath_hw_private_ops { 527struct ath_hw_private_ops {
525 /* Calibration ops */ 528 /* Calibration ops */
@@ -567,6 +570,7 @@ struct ath_hw_private_ops {
567 /* ANI */ 570 /* ANI */
568 void (*ani_reset)(struct ath_hw *ah, bool is_scanning); 571 void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
569 void (*ani_lower_immunity)(struct ath_hw *ah); 572 void (*ani_lower_immunity)(struct ath_hw *ah);
573 void (*ani_cache_ini_regs)(struct ath_hw *ah);
570}; 574};
571 575
572/** 576/**
@@ -959,9 +963,12 @@ void ar9003_hw_attach_ops(struct ath_hw *ah);
959 * ANI work can be shared between all families but a next 963 * ANI work can be shared between all families but a next
960 * generation implementation of ANI will be used only for AR9003 only 964 * generation implementation of ANI will be used only for AR9003 only
961 * for now as the other families still need to be tested with the same 965 * for now as the other families still need to be tested with the same
962 * next generation ANI. 966 * next generation ANI. Feel free to start testing it though for the
967 * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
963 */ 968 */
969extern int modparam_force_new_ani;
964void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); 970void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah);
971void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah);
965 972
966#define ATH_PCIE_CAP_LINK_CTRL 0x70 973#define ATH_PCIE_CAP_LINK_CTRL 0x70
967#define ATH_PCIE_CAP_LINK_L0S 1 974#define ATH_PCIE_CAP_LINK_L0S 1
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e1b8456f3d2c..9959e89d5496 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -285,7 +285,8 @@ void ath_ani_calibrate(unsigned long data)
285 } 285 }
286 286
287 /* Verify whether we must check ANI */ 287 /* Verify whether we must check ANI */
288 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { 288 if ((timestamp - common->ani.checkani_timer) >=
289 ah->config.ani_poll_interval) {
289 aniflag = true; 290 aniflag = true;
290 common->ani.checkani_timer = timestamp; 291 common->ani.checkani_timer = timestamp;
291 } 292 }
@@ -326,7 +327,8 @@ set_timer:
326 */ 327 */
327 cal_interval = ATH_LONG_CALINTERVAL; 328 cal_interval = ATH_LONG_CALINTERVAL;
328 if (sc->sc_ah->config.enable_ani) 329 if (sc->sc_ah->config.enable_ani)
329 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); 330 cal_interval = min(cal_interval,
331 (u32)ah->config.ani_poll_interval);
330 if (!common->ani.caldone) 332 if (!common->ani.caldone)
331 cal_interval = min(cal_interval, (u32)short_cal_interval); 333 cal_interval = min(cal_interval, (u32)short_cal_interval);
332 334
@@ -335,6 +337,7 @@ set_timer:
335 337
336static void ath_start_ani(struct ath_common *common) 338static void ath_start_ani(struct ath_common *common)
337{ 339{
340 struct ath_hw *ah = common->ah;
338 unsigned long timestamp = jiffies_to_msecs(jiffies); 341 unsigned long timestamp = jiffies_to_msecs(jiffies);
339 342
340 common->ani.longcal_timer = timestamp; 343 common->ani.longcal_timer = timestamp;
@@ -342,7 +345,8 @@ static void ath_start_ani(struct ath_common *common)
342 common->ani.checkani_timer = timestamp; 345 common->ani.checkani_timer = timestamp;
343 346
344 mod_timer(&common->ani.timer, 347 mod_timer(&common->ani.timer,
345 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 348 jiffies +
349 msecs_to_jiffies((u32)ah->config.ani_poll_interval));
346} 350}
347 351
348/* 352/*