aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/ani.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ani.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c760
1 files changed, 176 insertions, 584 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index a3d95cca8f0c..bfb6481f01f9 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-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 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
@@ -14,6 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/kernel.h>
17#include "hw.h" 18#include "hw.h"
18#include "hw-ops.h" 19#include "hw-ops.h"
19 20
@@ -48,7 +49,7 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = {
48 { 7, 8, 0 } /* lvl 9 */ 49 { 7, 8, 0 } /* lvl 9 */
49}; 50};
50#define ATH9K_ANI_OFDM_NUM_LEVEL \ 51#define ATH9K_ANI_OFDM_NUM_LEVEL \
51 (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0])) 52 ARRAY_SIZE(ofdm_level_table)
52#define ATH9K_ANI_OFDM_MAX_LEVEL \ 53#define ATH9K_ANI_OFDM_MAX_LEVEL \
53 (ATH9K_ANI_OFDM_NUM_LEVEL-1) 54 (ATH9K_ANI_OFDM_NUM_LEVEL-1)
54#define ATH9K_ANI_OFDM_DEF_LEVEL \ 55#define ATH9K_ANI_OFDM_DEF_LEVEL \
@@ -94,7 +95,7 @@ static const struct ani_cck_level_entry cck_level_table[] = {
94}; 95};
95 96
96#define ATH9K_ANI_CCK_NUM_LEVEL \ 97#define ATH9K_ANI_CCK_NUM_LEVEL \
97 (sizeof(cck_level_table)/sizeof(cck_level_table[0])) 98 ARRAY_SIZE(cck_level_table)
98#define ATH9K_ANI_CCK_MAX_LEVEL \ 99#define ATH9K_ANI_CCK_MAX_LEVEL \
99 (ATH9K_ANI_CCK_NUM_LEVEL-1) 100 (ATH9K_ANI_CCK_NUM_LEVEL-1)
100#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \ 101#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
@@ -102,31 +103,9 @@ static const struct ani_cck_level_entry cck_level_table[] = {
102#define ATH9K_ANI_CCK_DEF_LEVEL \ 103#define ATH9K_ANI_CCK_DEF_LEVEL \
103 2 /* default level - matches the INI settings */ 104 2 /* default level - matches the INI settings */
104 105
105/* Private to ani.c */ 106static bool use_new_ani(struct ath_hw *ah)
106static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
107{ 107{
108 ath9k_hw_private_ops(ah)->ani_lower_immunity(ah); 108 return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
109}
110
111int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
112 struct ath9k_channel *chan)
113{
114 int i;
115
116 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
117 if (ah->ani[i].c &&
118 ah->ani[i].c->channel == chan->channel)
119 return i;
120 if (ah->ani[i].c == NULL) {
121 ah->ani[i].c = chan;
122 return i;
123 }
124 }
125
126 ath_print(ath9k_hw_common(ah), ATH_DBG_ANI,
127 "No more channel states left. Using channel 0\n");
128
129 return 0;
130} 109}
131 110
132static void ath9k_hw_update_mibstats(struct ath_hw *ah, 111static void ath9k_hw_update_mibstats(struct ath_hw *ah,
@@ -139,82 +118,34 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
139 stats->beacons += REG_READ(ah, AR_BEACON_CNT); 118 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
140} 119}
141 120
142static void ath9k_ani_restart_old(struct ath_hw *ah) 121static void ath9k_ani_restart(struct ath_hw *ah)
143{ 122{
144 struct ar5416AniState *aniState; 123 struct ar5416AniState *aniState;
145 struct ath_common *common = ath9k_hw_common(ah); 124 struct ath_common *common = ath9k_hw_common(ah);
125 u32 ofdm_base = 0, cck_base = 0;
146 126
147 if (!DO_ANI(ah)) 127 if (!DO_ANI(ah))
148 return; 128 return;
149 129
150 aniState = ah->curani; 130 aniState = &ah->curchan->ani;
151 aniState->listenTime = 0; 131 aniState->listenTime = 0;
152 132
153 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { 133 if (!use_new_ani(ah)) {
154 aniState->ofdmPhyErrBase = 0; 134 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
155 ath_print(common, ATH_DBG_ANI, 135 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
156 "OFDM Trigger is too high for hw counters\n");
157 } else {
158 aniState->ofdmPhyErrBase =
159 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
160 }
161 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
162 aniState->cckPhyErrBase = 0;
163 ath_print(common, ATH_DBG_ANI,
164 "CCK Trigger is too high for hw counters\n");
165 } else {
166 aniState->cckPhyErrBase =
167 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
168 } 136 }
169 ath_print(common, ATH_DBG_ANI,
170 "Writing ofdmbase=%u cckbase=%u\n",
171 aniState->ofdmPhyErrBase,
172 aniState->cckPhyErrBase);
173
174 ENABLE_REGWRITE_BUFFER(ah);
175
176 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
177 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
178 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
179 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
180
181 REGWRITE_BUFFER_FLUSH(ah);
182 DISABLE_REGWRITE_BUFFER(ah);
183
184 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
185
186 aniState->ofdmPhyErrCount = 0;
187 aniState->cckPhyErrCount = 0;
188}
189 137
190static void ath9k_ani_restart_new(struct ath_hw *ah) 138 ath_dbg(common, ATH_DBG_ANI,
191{ 139 "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
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 140
209 ENABLE_REGWRITE_BUFFER(ah); 141 ENABLE_REGWRITE_BUFFER(ah);
210 142
211 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); 143 REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
212 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); 144 REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
213 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 145 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); 146 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
215 147
216 REGWRITE_BUFFER_FLUSH(ah); 148 REGWRITE_BUFFER_FLUSH(ah);
217 DISABLE_REGWRITE_BUFFER(ah);
218 149
219 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 150 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
220 151
@@ -228,10 +159,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
228 struct ar5416AniState *aniState; 159 struct ar5416AniState *aniState;
229 int32_t rssi; 160 int32_t rssi;
230 161
231 if (!DO_ANI(ah)) 162 aniState = &ah->curchan->ani;
232 return;
233
234 aniState = ah->curani;
235 163
236 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 164 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
237 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 165 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -300,10 +228,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
300 struct ar5416AniState *aniState; 228 struct ar5416AniState *aniState;
301 int32_t rssi; 229 int32_t rssi;
302 230
303 if (!DO_ANI(ah)) 231 aniState = &ah->curchan->ani;
304 return;
305
306 aniState = ah->curani;
307 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 232 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
308 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 233 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
309 aniState->noiseImmunityLevel + 1)) { 234 aniState->noiseImmunityLevel + 1)) {
@@ -335,18 +260,18 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
335/* Adjust the OFDM Noise Immunity Level */ 260/* Adjust the OFDM Noise Immunity Level */
336static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) 261static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
337{ 262{
338 struct ar5416AniState *aniState = ah->curani; 263 struct ar5416AniState *aniState = &ah->curchan->ani;
339 struct ath_common *common = ath9k_hw_common(ah); 264 struct ath_common *common = ath9k_hw_common(ah);
340 const struct ani_ofdm_level_entry *entry_ofdm; 265 const struct ani_ofdm_level_entry *entry_ofdm;
341 const struct ani_cck_level_entry *entry_cck; 266 const struct ani_cck_level_entry *entry_cck;
342 267
343 aniState->noiseFloor = BEACON_RSSI(ah); 268 aniState->noiseFloor = BEACON_RSSI(ah);
344 269
345 ath_print(common, ATH_DBG_ANI, 270 ath_dbg(common, ATH_DBG_ANI,
346 "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", 271 "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
347 aniState->ofdmNoiseImmunityLevel, 272 aniState->ofdmNoiseImmunityLevel,
348 immunityLevel, aniState->noiseFloor, 273 immunityLevel, aniState->noiseFloor,
349 aniState->rssiThrLow, aniState->rssiThrHigh); 274 aniState->rssiThrLow, aniState->rssiThrHigh);
350 275
351 aniState->ofdmNoiseImmunityLevel = immunityLevel; 276 aniState->ofdmNoiseImmunityLevel = immunityLevel;
352 277
@@ -380,14 +305,19 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
380 } 305 }
381} 306}
382 307
383static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) 308static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
384{ 309{
385 struct ar5416AniState *aniState; 310 struct ar5416AniState *aniState;
386 311
387 if (!DO_ANI(ah)) 312 if (!DO_ANI(ah))
388 return; 313 return;
389 314
390 aniState = ah->curani; 315 if (!use_new_ani(ah)) {
316 ath9k_hw_ani_ofdm_err_trigger_old(ah);
317 return;
318 }
319
320 aniState = &ah->curchan->ani;
391 321
392 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) 322 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
393 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); 323 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
@@ -398,17 +328,17 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
398 */ 328 */
399static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) 329static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
400{ 330{
401 struct ar5416AniState *aniState = ah->curani; 331 struct ar5416AniState *aniState = &ah->curchan->ani;
402 struct ath_common *common = ath9k_hw_common(ah); 332 struct ath_common *common = ath9k_hw_common(ah);
403 const struct ani_ofdm_level_entry *entry_ofdm; 333 const struct ani_ofdm_level_entry *entry_ofdm;
404 const struct ani_cck_level_entry *entry_cck; 334 const struct ani_cck_level_entry *entry_cck;
405 335
406 aniState->noiseFloor = BEACON_RSSI(ah); 336 aniState->noiseFloor = BEACON_RSSI(ah);
407 ath_print(common, ATH_DBG_ANI, 337 ath_dbg(common, ATH_DBG_ANI,
408 "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", 338 "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
409 aniState->cckNoiseImmunityLevel, immunityLevel, 339 aniState->cckNoiseImmunityLevel, immunityLevel,
410 aniState->noiseFloor, aniState->rssiThrLow, 340 aniState->noiseFloor, aniState->rssiThrLow,
411 aniState->rssiThrHigh); 341 aniState->rssiThrHigh);
412 342
413 if ((ah->opmode == NL80211_IFTYPE_STATION || 343 if ((ah->opmode == NL80211_IFTYPE_STATION ||
414 ah->opmode == NL80211_IFTYPE_ADHOC) && 344 ah->opmode == NL80211_IFTYPE_ADHOC) &&
@@ -428,7 +358,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
428 entry_cck->fir_step_level); 358 entry_cck->fir_step_level);
429 359
430 /* Skip MRC CCK for pre AR9003 families */ 360 /* Skip MRC CCK for pre AR9003 families */
431 if (!AR_SREV_9300_20_OR_LATER(ah)) 361 if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
432 return; 362 return;
433 363
434 if (aniState->mrcCCKOff == entry_cck->mrc_cck_on) 364 if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
@@ -437,14 +367,19 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
437 entry_cck->mrc_cck_on); 367 entry_cck->mrc_cck_on);
438} 368}
439 369
440static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah) 370static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
441{ 371{
442 struct ar5416AniState *aniState; 372 struct ar5416AniState *aniState;
443 373
444 if (!DO_ANI(ah)) 374 if (!DO_ANI(ah))
445 return; 375 return;
446 376
447 aniState = ah->curani; 377 if (!use_new_ani(ah)) {
378 ath9k_hw_ani_cck_err_trigger_old(ah);
379 return;
380 }
381
382 aniState = &ah->curchan->ani;
448 383
449 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) 384 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
450 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); 385 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
@@ -455,7 +390,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
455 struct ar5416AniState *aniState; 390 struct ar5416AniState *aniState;
456 int32_t rssi; 391 int32_t rssi;
457 392
458 aniState = ah->curani; 393 aniState = &ah->curchan->ani;
459 394
460 if (ah->opmode == NL80211_IFTYPE_AP) { 395 if (ah->opmode == NL80211_IFTYPE_AP) {
461 if (aniState->firstepLevel > 0) { 396 if (aniState->firstepLevel > 0) {
@@ -507,11 +442,16 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
507 * only lower either OFDM or CCK errors per turn 442 * only lower either OFDM or CCK errors per turn
508 * we lower the other one next time 443 * we lower the other one next time
509 */ 444 */
510static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) 445static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
511{ 446{
512 struct ar5416AniState *aniState; 447 struct ar5416AniState *aniState;
513 448
514 aniState = ah->curani; 449 aniState = &ah->curchan->ani;
450
451 if (!use_new_ani(ah)) {
452 ath9k_hw_ani_lower_immunity_old(ah);
453 return;
454 }
515 455
516 /* lower OFDM noise immunity */ 456 /* lower OFDM noise immunity */
517 if (aniState->ofdmNoiseImmunityLevel > 0 && 457 if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -525,90 +465,21 @@ static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
525 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); 465 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
526} 466}
527 467
528static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
529{
530 struct ath9k_channel *chan = ah->curchan;
531 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
532 u8 clockrate; /* in MHz */
533
534 if (!ah->curchan) /* should really check for CCK instead */
535 clockrate = ATH9K_CLOCK_RATE_CCK;
536 else if (conf->channel->band == IEEE80211_BAND_2GHZ)
537 clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
538 else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
539 clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
540 else
541 clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
542
543 if (conf_is_ht40(conf))
544 return clockrate * 2;
545
546 return clockrate;
547}
548
549static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
550{
551 struct ar5416AniState *aniState;
552 struct ath_common *common = ath9k_hw_common(ah);
553 u32 txFrameCount, rxFrameCount, cycleCount;
554 int32_t listenTime;
555
556 txFrameCount = REG_READ(ah, AR_TFCNT);
557 rxFrameCount = REG_READ(ah, AR_RFCNT);
558 cycleCount = REG_READ(ah, AR_CCCNT);
559
560 aniState = ah->curani;
561 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
562 listenTime = 0;
563 ah->stats.ast_ani_lzero++;
564 ath_print(common, ATH_DBG_ANI,
565 "1st call: aniState->cycleCount=%d\n",
566 aniState->cycleCount);
567 } else {
568 int32_t ccdelta = cycleCount - aniState->cycleCount;
569 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
570 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
571 int32_t clock_rate;
572
573 /*
574 * convert HW counter values to ms using mode
575 * specifix clock rate
576 */
577 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
578
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);
585 }
586
587 aniState->cycleCount = cycleCount;
588 aniState->txFrameCount = txFrameCount;
589 aniState->rxFrameCount = rxFrameCount;
590
591 return listenTime;
592}
593
594static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) 468static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
595{ 469{
596 struct ar5416AniState *aniState; 470 struct ar5416AniState *aniState;
597 struct ath9k_channel *chan = ah->curchan; 471 struct ath9k_channel *chan = ah->curchan;
598 struct ath_common *common = ath9k_hw_common(ah); 472 struct ath_common *common = ath9k_hw_common(ah);
599 int index;
600 473
601 if (!DO_ANI(ah)) 474 if (!DO_ANI(ah))
602 return; 475 return;
603 476
604 index = ath9k_hw_get_ani_channel_idx(ah, chan); 477 aniState = &ah->curchan->ani;
605 aniState = &ah->ani[index];
606 ah->curani = aniState;
607 478
608 if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION 479 if (ah->opmode != NL80211_IFTYPE_STATION
609 && ah->opmode != NL80211_IFTYPE_ADHOC) { 480 && ah->opmode != NL80211_IFTYPE_ADHOC) {
610 ath_print(common, ATH_DBG_ANI, 481 ath_dbg(common, ATH_DBG_ANI,
611 "Reset ANI state opmode %u\n", ah->opmode); 482 "Reset ANI state opmode %u\n", ah->opmode);
612 ah->stats.ast_ani_reset++; 483 ah->stats.ast_ani_reset++;
613 484
614 if (ah->opmode == NL80211_IFTYPE_AP) { 485 if (ah->opmode == NL80211_IFTYPE_AP) {
@@ -634,17 +505,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
634 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | 505 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
635 ATH9K_RX_FILTER_PHYERR); 506 ATH9K_RX_FILTER_PHYERR);
636 507
637 if (ah->opmode == NL80211_IFTYPE_AP) { 508 ath9k_ani_restart(ah);
638 ah->curani->ofdmTrigHigh =
639 ah->config.ofdm_trig_high;
640 ah->curani->ofdmTrigLow =
641 ah->config.ofdm_trig_low;
642 ah->curani->cckTrigHigh =
643 ah->config.cck_trig_high;
644 ah->curani->cckTrigLow =
645 ah->config.cck_trig_low;
646 }
647 ath9k_ani_restart_old(ah);
648 return; 509 return;
649 } 510 }
650 511
@@ -666,7 +527,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
666 527
667 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 528 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
668 ~ATH9K_RX_FILTER_PHYERR); 529 ~ATH9K_RX_FILTER_PHYERR);
669 ath9k_ani_restart_old(ah); 530 ath9k_ani_restart(ah);
670 531
671 ENABLE_REGWRITE_BUFFER(ah); 532 ENABLE_REGWRITE_BUFFER(ah);
672 533
@@ -674,7 +535,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
674 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 535 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
675 536
676 REGWRITE_BUFFER_FLUSH(ah); 537 REGWRITE_BUFFER_FLUSH(ah);
677 DISABLE_REGWRITE_BUFFER(ah);
678} 538}
679 539
680/* 540/*
@@ -682,15 +542,18 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
682 * This routine should be called for every hardware reset and for 542 * This routine should be called for every hardware reset and for
683 * every channel change. 543 * every channel change.
684 */ 544 */
685static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) 545void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
686{ 546{
687 struct ar5416AniState *aniState = ah->curani; 547 struct ar5416AniState *aniState = &ah->curchan->ani;
688 struct ath9k_channel *chan = ah->curchan; 548 struct ath9k_channel *chan = ah->curchan;
689 struct ath_common *common = ath9k_hw_common(ah); 549 struct ath_common *common = ath9k_hw_common(ah);
690 550
691 if (!DO_ANI(ah)) 551 if (!DO_ANI(ah))
692 return; 552 return;
693 553
554 if (!use_new_ani(ah))
555 return ath9k_ani_reset_old(ah, is_scanning);
556
694 BUG_ON(aniState == NULL); 557 BUG_ON(aniState == NULL);
695 ah->stats.ast_ani_reset++; 558 ah->stats.ast_ani_reset++;
696 559
@@ -721,16 +584,14 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
721 ATH9K_ANI_OFDM_DEF_LEVEL || 584 ATH9K_ANI_OFDM_DEF_LEVEL ||
722 aniState->cckNoiseImmunityLevel != 585 aniState->cckNoiseImmunityLevel !=
723 ATH9K_ANI_CCK_DEF_LEVEL) { 586 ATH9K_ANI_CCK_DEF_LEVEL) {
724 ath_print(common, ATH_DBG_ANI, 587 ath_dbg(common, ATH_DBG_ANI,
725 "Restore defaults: opmode %u " 588 "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
726 "chan %d Mhz/0x%x is_scanning=%d " 589 ah->opmode,
727 "ofdm:%d cck:%d\n", 590 chan->channel,
728 ah->opmode, 591 chan->channelFlags,
729 chan->channel, 592 is_scanning,
730 chan->channelFlags, 593 aniState->ofdmNoiseImmunityLevel,
731 is_scanning, 594 aniState->cckNoiseImmunityLevel);
732 aniState->ofdmNoiseImmunityLevel,
733 aniState->cckNoiseImmunityLevel);
734 595
735 ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL); 596 ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
736 ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL); 597 ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
@@ -739,16 +600,14 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
739 /* 600 /*
740 * restore historical levels for this channel 601 * restore historical levels for this channel
741 */ 602 */
742 ath_print(common, ATH_DBG_ANI, 603 ath_dbg(common, ATH_DBG_ANI,
743 "Restore history: opmode %u " 604 "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
744 "chan %d Mhz/0x%x is_scanning=%d " 605 ah->opmode,
745 "ofdm:%d cck:%d\n", 606 chan->channel,
746 ah->opmode, 607 chan->channelFlags,
747 chan->channel, 608 is_scanning,
748 chan->channelFlags, 609 aniState->ofdmNoiseImmunityLevel,
749 is_scanning, 610 aniState->cckNoiseImmunityLevel);
750 aniState->ofdmNoiseImmunityLevel,
751 aniState->cckNoiseImmunityLevel);
752 611
753 ath9k_hw_set_ofdm_nil(ah, 612 ath9k_hw_set_ofdm_nil(ah,
754 aniState->ofdmNoiseImmunityLevel); 613 aniState->ofdmNoiseImmunityLevel);
@@ -760,7 +619,7 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
760 * enable phy counters if hw supports or if not, enable phy 619 * enable phy counters if hw supports or if not, enable phy
761 * interrupts (so we can count each one) 620 * interrupts (so we can count each one)
762 */ 621 */
763 ath9k_ani_restart_new(ah); 622 ath9k_ani_restart(ah);
764 623
765 ENABLE_REGWRITE_BUFFER(ah); 624 ENABLE_REGWRITE_BUFFER(ah);
766 625
@@ -768,28 +627,30 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
768 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 627 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
769 628
770 REGWRITE_BUFFER_FLUSH(ah); 629 REGWRITE_BUFFER_FLUSH(ah);
771 DISABLE_REGWRITE_BUFFER(ah);
772} 630}
773 631
774static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, 632static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
775 struct ath9k_channel *chan)
776{ 633{
777 struct ar5416AniState *aniState;
778 struct ath_common *common = ath9k_hw_common(ah); 634 struct ath_common *common = ath9k_hw_common(ah);
779 int32_t listenTime; 635 struct ar5416AniState *aniState = &ah->curchan->ani;
780 u32 phyCnt1, phyCnt2; 636 u32 ofdm_base = 0;
637 u32 cck_base = 0;
781 u32 ofdmPhyErrCnt, cckPhyErrCnt; 638 u32 ofdmPhyErrCnt, cckPhyErrCnt;
639 u32 phyCnt1, phyCnt2;
640 int32_t listenTime;
782 641
783 if (!DO_ANI(ah)) 642 ath_hw_cycle_counters_update(common);
784 return; 643 listenTime = ath_hw_get_listen_time(common);
785
786 aniState = ah->curani;
787 644
788 listenTime = ath9k_hw_ani_get_listen_time(ah); 645 if (listenTime <= 0) {
789 if (listenTime < 0) {
790 ah->stats.ast_ani_lneg++; 646 ah->stats.ast_ani_lneg++;
791 ath9k_ani_restart_old(ah); 647 ath9k_ani_restart(ah);
792 return; 648 return false;
649 }
650
651 if (!use_new_ani(ah)) {
652 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
653 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
793 } 654 }
794 655
795 aniState->listenTime += listenTime; 656 aniState->listenTime += listenTime;
@@ -799,215 +660,95 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
799 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 660 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
800 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 661 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
801 662
802 if (phyCnt1 < aniState->ofdmPhyErrBase || 663 if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
803 phyCnt2 < aniState->cckPhyErrBase) { 664 if (phyCnt1 < ofdm_base) {
804 if (phyCnt1 < aniState->ofdmPhyErrBase) { 665 ath_dbg(common, ATH_DBG_ANI,
805 ath_print(common, ATH_DBG_ANI, 666 "phyCnt1 0x%x, resetting counter value to 0x%x\n",
806 "phyCnt1 0x%x, resetting " 667 phyCnt1, ofdm_base);
807 "counter value to 0x%x\n", 668 REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
808 phyCnt1,
809 aniState->ofdmPhyErrBase);
810 REG_WRITE(ah, AR_PHY_ERR_1,
811 aniState->ofdmPhyErrBase);
812 REG_WRITE(ah, AR_PHY_ERR_MASK_1, 669 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
813 AR_PHY_ERR_OFDM_TIMING); 670 AR_PHY_ERR_OFDM_TIMING);
814 } 671 }
815 if (phyCnt2 < aniState->cckPhyErrBase) { 672 if (phyCnt2 < cck_base) {
816 ath_print(common, ATH_DBG_ANI, 673 ath_dbg(common, ATH_DBG_ANI,
817 "phyCnt2 0x%x, resetting " 674 "phyCnt2 0x%x, resetting counter value to 0x%x\n",
818 "counter value to 0x%x\n", 675 phyCnt2, cck_base);
819 phyCnt2, 676 REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
820 aniState->cckPhyErrBase);
821 REG_WRITE(ah, AR_PHY_ERR_2,
822 aniState->cckPhyErrBase);
823 REG_WRITE(ah, AR_PHY_ERR_MASK_2, 677 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
824 AR_PHY_ERR_CCK_TIMING); 678 AR_PHY_ERR_CCK_TIMING);
825 } 679 }
826 return; 680 return false;
827 } 681 }
828 682
829 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 683 ofdmPhyErrCnt = phyCnt1 - ofdm_base;
830 ah->stats.ast_ani_ofdmerrs += 684 ah->stats.ast_ani_ofdmerrs +=
831 ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 685 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
832 aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 686 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
833 687
834 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 688 cckPhyErrCnt = phyCnt2 - cck_base;
835 ah->stats.ast_ani_cckerrs += 689 ah->stats.ast_ani_cckerrs +=
836 cckPhyErrCnt - aniState->cckPhyErrCount; 690 cckPhyErrCnt - aniState->cckPhyErrCount;
837 aniState->cckPhyErrCount = cckPhyErrCnt; 691 aniState->cckPhyErrCount = cckPhyErrCnt;
838 692 return true;
839 if (aniState->listenTime > 5 * ah->aniperiod) {
840 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
841 aniState->ofdmTrigLow / 1000 &&
842 aniState->cckPhyErrCount <= aniState->listenTime *
843 aniState->cckTrigLow / 1000)
844 ath9k_hw_ani_lower_immunity(ah);
845 ath9k_ani_restart_old(ah);
846 } else if (aniState->listenTime > ah->aniperiod) {
847 if (aniState->ofdmPhyErrCount > aniState->listenTime *
848 aniState->ofdmTrigHigh / 1000) {
849 ath9k_hw_ani_ofdm_err_trigger_old(ah);
850 ath9k_ani_restart_old(ah);
851 } else if (aniState->cckPhyErrCount >
852 aniState->listenTime * aniState->cckTrigHigh /
853 1000) {
854 ath9k_hw_ani_cck_err_trigger_old(ah);
855 ath9k_ani_restart_old(ah);
856 }
857 }
858} 693}
859 694
860static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, 695void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
861 struct ath9k_channel *chan)
862{ 696{
863 struct ar5416AniState *aniState; 697 struct ar5416AniState *aniState;
864 struct ath_common *common = ath9k_hw_common(ah); 698 struct ath_common *common = ath9k_hw_common(ah);
865 int32_t listenTime;
866 u32 phyCnt1, phyCnt2;
867 u32 ofdmPhyErrCnt, cckPhyErrCnt;
868 u32 ofdmPhyErrRate, cckPhyErrRate; 699 u32 ofdmPhyErrRate, cckPhyErrRate;
869 700
870 if (!DO_ANI(ah)) 701 if (!DO_ANI(ah))
871 return; 702 return;
872 703
873 aniState = ah->curani; 704 aniState = &ah->curchan->ani;
874 if (WARN_ON(!aniState)) 705 if (WARN_ON(!aniState))
875 return; 706 return;
876 707
877 listenTime = ath9k_hw_ani_get_listen_time(ah); 708 if (!ath9k_hw_ani_read_counters(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; 709 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 710
942 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / 711 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
943 aniState->listenTime; 712 aniState->listenTime;
944 cckPhyErrRate = aniState->cckPhyErrCount * 1000 / 713 cckPhyErrRate = aniState->cckPhyErrCount * 1000 /
945 aniState->listenTime; 714 aniState->listenTime;
946 715
947 ath_print(common, ATH_DBG_ANI, 716 ath_dbg(common, ATH_DBG_ANI,
948 "listenTime=%d OFDM:%d errs=%d/s CCK:%d " 717 "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
949 "errs=%d/s ofdm_turn=%d\n", 718 aniState->listenTime,
950 listenTime, aniState->ofdmNoiseImmunityLevel, 719 aniState->ofdmNoiseImmunityLevel,
951 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, 720 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
952 cckPhyErrRate, aniState->ofdmsTurn); 721 cckPhyErrRate, aniState->ofdmsTurn);
953 722
954 if (aniState->listenTime > 5 * ah->aniperiod) { 723 if (aniState->listenTime > 5 * ah->aniperiod) {
955 if (ofdmPhyErrRate <= aniState->ofdmTrigLow && 724 if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
956 cckPhyErrRate <= aniState->cckTrigLow) { 725 cckPhyErrRate <= ah->config.cck_trig_low) {
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); 726 ath9k_hw_ani_lower_immunity(ah);
969 aniState->ofdmsTurn = !aniState->ofdmsTurn; 727 aniState->ofdmsTurn = !aniState->ofdmsTurn;
970 } 728 }
971 ath_print(common, ATH_DBG_ANI, 729 ath9k_ani_restart(ah);
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) { 730 } else if (aniState->listenTime > ah->aniperiod) {
977 /* check to see if need to raise immunity */ 731 /* check to see if need to raise immunity */
978 if (ofdmPhyErrRate > aniState->ofdmTrigHigh && 732 if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
979 (cckPhyErrRate <= aniState->cckTrigHigh || 733 (cckPhyErrRate <= ah->config.cck_trig_high ||
980 aniState->ofdmsTurn)) { 734 aniState->ofdmsTurn)) {
981 ath_print(common, ATH_DBG_ANI, 735 ath9k_hw_ani_ofdm_err_trigger(ah);
982 "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " 736 ath9k_ani_restart(ah);
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; 737 aniState->ofdmsTurn = false;
991 } else if (cckPhyErrRate > aniState->cckTrigHigh) { 738 } else if (cckPhyErrRate > ah->config.cck_trig_high) {
992 ath_print(common, ATH_DBG_ANI, 739 ath9k_hw_ani_cck_err_trigger(ah);
993 "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " 740 ath9k_ani_restart(ah);
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; 741 aniState->ofdmsTurn = true;
1002 } 742 }
1003 } 743 }
1004} 744}
745EXPORT_SYMBOL(ath9k_hw_ani_monitor);
1005 746
1006void ath9k_enable_mib_counters(struct ath_hw *ah) 747void ath9k_enable_mib_counters(struct ath_hw *ah)
1007{ 748{
1008 struct ath_common *common = ath9k_hw_common(ah); 749 struct ath_common *common = ath9k_hw_common(ah);
1009 750
1010 ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n"); 751 ath_dbg(common, ATH_DBG_ANI, "Enable MIB counters\n");
1011 752
1012 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 753 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
1013 754
@@ -1022,7 +763,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
1022 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 763 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
1023 764
1024 REGWRITE_BUFFER_FLUSH(ah); 765 REGWRITE_BUFFER_FLUSH(ah);
1025 DISABLE_REGWRITE_BUFFER(ah);
1026} 766}
1027 767
1028/* Freeze the MIB counters, get the stats and then clear them */ 768/* Freeze the MIB counters, get the stats and then clear them */
@@ -1030,7 +770,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
1030{ 770{
1031 struct ath_common *common = ath9k_hw_common(ah); 771 struct ath_common *common = ath9k_hw_common(ah);
1032 772
1033 ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n"); 773 ath_dbg(common, ATH_DBG_ANI, "Disable MIB counters\n");
1034 774
1035 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); 775 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
1036 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 776 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -1040,53 +780,12 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
1040} 780}
1041EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); 781EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
1042 782
1043u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
1044 u32 *rxc_pcnt,
1045 u32 *rxf_pcnt,
1046 u32 *txf_pcnt)
1047{
1048 struct ath_common *common = ath9k_hw_common(ah);
1049 static u32 cycles, rx_clear, rx_frame, tx_frame;
1050 u32 good = 1;
1051
1052 u32 rc = REG_READ(ah, AR_RCCNT);
1053 u32 rf = REG_READ(ah, AR_RFCNT);
1054 u32 tf = REG_READ(ah, AR_TFCNT);
1055 u32 cc = REG_READ(ah, AR_CCCNT);
1056
1057 if (cycles == 0 || cycles > cc) {
1058 ath_print(common, ATH_DBG_ANI,
1059 "cycle counter wrap. ExtBusy = 0\n");
1060 good = 0;
1061 } else {
1062 u32 cc_d = cc - cycles;
1063 u32 rc_d = rc - rx_clear;
1064 u32 rf_d = rf - rx_frame;
1065 u32 tf_d = tf - tx_frame;
1066
1067 if (cc_d != 0) {
1068 *rxc_pcnt = rc_d * 100 / cc_d;
1069 *rxf_pcnt = rf_d * 100 / cc_d;
1070 *txf_pcnt = tf_d * 100 / cc_d;
1071 } else {
1072 good = 0;
1073 }
1074 }
1075
1076 cycles = cc;
1077 rx_frame = rf;
1078 rx_clear = rc;
1079 tx_frame = tf;
1080
1081 return good;
1082}
1083
1084/* 783/*
1085 * Process a MIB interrupt. We may potentially be invoked because 784 * Process a MIB interrupt. We may potentially be invoked because
1086 * any of the MIB counters overflow/trigger so don't assume we're 785 * any of the MIB counters overflow/trigger so don't assume we're
1087 * here because a PHY error counter triggered. 786 * here because a PHY error counter triggered.
1088 */ 787 */
1089static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) 788void ath9k_hw_proc_mib_event(struct ath_hw *ah)
1090{ 789{
1091 u32 phyCnt1, phyCnt2; 790 u32 phyCnt1, phyCnt2;
1092 791
@@ -1114,81 +813,24 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
1114 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 813 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
1115 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || 814 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
1116 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { 815 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
1117 struct ar5416AniState *aniState = ah->curani;
1118 u32 ofdmPhyErrCnt, cckPhyErrCnt;
1119 816
1120 /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ 817 if (!use_new_ani(ah))
1121 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 818 ath9k_hw_ani_read_counters(ah);
1122 ah->stats.ast_ani_ofdmerrs +=
1123 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
1124 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
1125 819
1126 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
1127 ah->stats.ast_ani_cckerrs +=
1128 cckPhyErrCnt - aniState->cckPhyErrCount;
1129 aniState->cckPhyErrCount = cckPhyErrCnt;
1130
1131 /*
1132 * NB: figure out which counter triggered. If both
1133 * trigger we'll only deal with one as the processing
1134 * clobbers the error counter so the trigger threshold
1135 * check will never be true.
1136 */
1137 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
1138 ath9k_hw_ani_ofdm_err_trigger_new(ah);
1139 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
1140 ath9k_hw_ani_cck_err_trigger_old(ah);
1141 /* NB: always restart to insure the h/w counters are reset */ 820 /* NB: always restart to insure the h/w counters are reset */
1142 ath9k_ani_restart_old(ah); 821 ath9k_ani_restart(ah);
1143 }
1144}
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 } 822 }
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} 823}
824EXPORT_SYMBOL(ath9k_hw_proc_mib_event);
1183 825
1184void ath9k_hw_ani_setup(struct ath_hw *ah) 826void ath9k_hw_ani_setup(struct ath_hw *ah)
1185{ 827{
1186 int i; 828 int i;
1187 829
1188 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; 830 static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
1189 const int coarseHigh[] = { -14, -14, -14, -14, -12 }; 831 static const int coarseHigh[] = { -14, -14, -14, -14, -12 };
1190 const int coarseLow[] = { -64, -64, -64, -64, -70 }; 832 static const int coarseLow[] = { -64, -64, -64, -64, -70 };
1191 const int firpwr[] = { -78, -78, -78, -78, -80 }; 833 static const int firpwr[] = { -78, -78, -78, -78, -80 };
1192 834
1193 for (i = 0; i < 5; i++) { 835 for (i = 0; i < 5; i++) {
1194 ah->totalSizeDesired[i] = totalSizeDesired[i]; 836 ah->totalSizeDesired[i] = totalSizeDesired[i];
@@ -1203,69 +845,60 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
1203 struct ath_common *common = ath9k_hw_common(ah); 845 struct ath_common *common = ath9k_hw_common(ah);
1204 int i; 846 int i;
1205 847
1206 ath_print(common, ATH_DBG_ANI, "Initialize ANI\n"); 848 ath_dbg(common, ATH_DBG_ANI, "Initialize ANI\n");
1207 849
1208 memset(ah->ani, 0, sizeof(ah->ani)); 850 if (use_new_ani(ah)) {
1209 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { 851 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
1210 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { 852 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
1211 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
1212 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
1213 853
1214 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW; 854 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
1215 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW; 855 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
856 } else {
857 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
858 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
1216 859
1217 ah->ani[i].spurImmunityLevel = 860 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1218 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; 861 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
862 }
1219 863
1220 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; 864 for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
865 struct ath9k_channel *chan = &ah->channels[i];
866 struct ar5416AniState *ani = &chan->ani;
1221 867
1222 ah->ani[i].ofdmPhyErrBase = 0; 868 if (use_new_ani(ah)) {
1223 ah->ani[i].cckPhyErrBase = 0; 869 ani->spurImmunityLevel =
870 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
871
872 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1224 873
1225 if (AR_SREV_9300_20_OR_LATER(ah)) 874 if (AR_SREV_9300_20_OR_LATER(ah))
1226 ah->ani[i].mrcCCKOff = 875 ani->mrcCCKOff =
1227 !ATH9K_ANI_ENABLE_MRC_CCK; 876 !ATH9K_ANI_ENABLE_MRC_CCK;
1228 else 877 else
1229 ah->ani[i].mrcCCKOff = true; 878 ani->mrcCCKOff = true;
1230 879
1231 ah->ani[i].ofdmsTurn = true; 880 ani->ofdmsTurn = true;
1232 } else { 881 } else {
1233 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; 882 ani->spurImmunityLevel =
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; 883 ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
1241 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; 884 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
1242 885
1243 ah->ani[i].ofdmPhyErrBase = 886 ani->cckWeakSigThreshold =
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; 887 ATH9K_ANI_CCK_WEAK_SIG_THR;
1249 } 888 }
1250 889
1251 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; 890 ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
1252 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; 891 ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
1253 ah->ani[i].ofdmWeakSigDetectOff = 892 ani->ofdmWeakSigDetectOff =
1254 !ATH9K_ANI_USE_OFDM_WEAK_SIG; 893 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1255 ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; 894 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
1256 } 895 }
1257 896
1258 /* 897 /*
1259 * since we expect some ongoing maintenance on the tables, let's sanity 898 * since we expect some ongoing maintenance on the tables, let's sanity
1260 * check here default level should not modify INI setting. 899 * check here default level should not modify INI setting.
1261 */ 900 */
1262 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { 901 if (use_new_ani(ah)) {
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; 902 ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
1270 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; 903 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
1271 } else { 904 } else {
@@ -1273,50 +906,9 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
1273 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; 906 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
1274 } 907 }
1275 908
1276 ath_print(common, ATH_DBG_ANI,
1277 "Setting OfdmErrBase = 0x%08x\n",
1278 ah->ani[0].ofdmPhyErrBase);
1279 ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
1280 ah->ani[0].cckPhyErrBase);
1281
1282 ENABLE_REGWRITE_BUFFER(ah);
1283
1284 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
1285 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
1286
1287 REGWRITE_BUFFER_FLUSH(ah);
1288 DISABLE_REGWRITE_BUFFER(ah);
1289
1290 ath9k_enable_mib_counters(ah);
1291
1292 if (ah->config.enable_ani) 909 if (ah->config.enable_ani)
1293 ah->proc_phyerr |= HAL_PROCESS_ANI; 910 ah->proc_phyerr |= HAL_PROCESS_ANI;
1294}
1295
1296void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah)
1297{
1298 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1299 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1300
1301 priv_ops->ani_reset = ath9k_ani_reset_old;
1302 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old;
1303
1304 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_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 911
1315 priv_ops->ani_reset = ath9k_ani_reset_new; 912 ath9k_ani_restart(ah);
1316 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new; 913 ath9k_enable_mib_counters(ah);
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");
1322} 914}