linux/drivers/net/wireless/ath/ath9k/ani.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008-2011 Atheros Communications Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/export.h>
  19#include "hw.h"
  20#include "hw-ops.h"
  21
  22struct ani_ofdm_level_entry {
  23        int spur_immunity_level;
  24        int fir_step_level;
  25        int ofdm_weak_signal_on;
  26};
  27
  28/* values here are relative to the INI */
  29
  30/*
  31 * Legend:
  32 *
  33 * SI: Spur immunity
  34 * FS: FIR Step
  35 * WS: OFDM / CCK Weak Signal detection
  36 * MRC-CCK: Maximal Ratio Combining for CCK
  37 */
  38
  39static const struct ani_ofdm_level_entry ofdm_level_table[] = {
  40        /* SI  FS  WS */
  41        {  0,  0,  1  }, /* lvl 0 */
  42        {  1,  1,  1  }, /* lvl 1 */
  43        {  2,  2,  1  }, /* lvl 2 */
  44        {  3,  2,  1  }, /* lvl 3  (default) */
  45        {  4,  3,  1  }, /* lvl 4 */
  46        {  5,  4,  1  }, /* lvl 5 */
  47        {  6,  5,  1  }, /* lvl 6 */
  48        {  7,  6,  1  }, /* lvl 7 */
  49        {  7,  7,  1  }, /* lvl 8 */
  50        {  7,  8,  0  }  /* lvl 9 */
  51};
  52#define ATH9K_ANI_OFDM_NUM_LEVEL \
  53        ARRAY_SIZE(ofdm_level_table)
  54#define ATH9K_ANI_OFDM_MAX_LEVEL \
  55        (ATH9K_ANI_OFDM_NUM_LEVEL-1)
  56#define ATH9K_ANI_OFDM_DEF_LEVEL \
  57        3 /* default level - matches the INI settings */
  58
  59/*
  60 * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
  61 * With OFDM for single stream you just add up all antenna inputs, you're
  62 * only interested in what you get after FFT. Signal alignment is also not
  63 * required for OFDM because any phase difference adds up in the frequency
  64 * domain.
  65 *
  66 * MRC requires extra work for use with CCK. You need to align the antenna
  67 * signals from the different antenna before you can add the signals together.
  68 * You need alignment of signals as CCK is in time domain, so addition can cancel
  69 * your signal completely if phase is 180 degrees (think of adding sine waves).
  70 * You also need to remove noise before the addition and this is where ANI
  71 * MRC CCK comes into play. One of the antenna inputs may be stronger but
  72 * lower SNR, so just adding after alignment can be dangerous.
  73 *
  74 * Regardless of alignment in time, the antenna signals add constructively after
  75 * FFT and improve your reception. For more information:
  76 *
  77 * http://en.wikipedia.org/wiki/Maximal-ratio_combining
  78 */
  79
  80struct ani_cck_level_entry {
  81        int fir_step_level;
  82        int mrc_cck_on;
  83};
  84
  85static const struct ani_cck_level_entry cck_level_table[] = {
  86        /* FS  MRC-CCK  */
  87        {  0,  1  }, /* lvl 0 */
  88        {  1,  1  }, /* lvl 1 */
  89        {  2,  1  }, /* lvl 2  (default) */
  90        {  3,  1  }, /* lvl 3 */
  91        {  4,  0  }, /* lvl 4 */
  92        {  5,  0  }, /* lvl 5 */
  93        {  6,  0  }, /* lvl 6 */
  94        {  7,  0  }, /* lvl 7 (only for high rssi) */
  95        {  8,  0  }  /* lvl 8 (only for high rssi) */
  96};
  97
  98#define ATH9K_ANI_CCK_NUM_LEVEL \
  99        ARRAY_SIZE(cck_level_table)
 100#define ATH9K_ANI_CCK_MAX_LEVEL \
 101        (ATH9K_ANI_CCK_NUM_LEVEL-1)
 102#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
 103        (ATH9K_ANI_CCK_NUM_LEVEL-3)
 104#define ATH9K_ANI_CCK_DEF_LEVEL \
 105        2 /* default level - matches the INI settings */
 106
 107static void ath9k_hw_update_mibstats(struct ath_hw *ah,
 108                                     struct ath9k_mib_stats *stats)
 109{
 110        u32 addr[5] = {AR_RTS_OK, AR_RTS_FAIL, AR_ACK_FAIL,
 111                       AR_FCS_FAIL, AR_BEACON_CNT};
 112        u32 data[5];
 113
 114        REG_READ_MULTI(ah, &addr[0], &data[0], 5);
 115        /* AR_RTS_OK */
 116        stats->rts_good += data[0];
 117        /* AR_RTS_FAIL */
 118        stats->rts_bad += data[1];
 119        /* AR_ACK_FAIL */
 120        stats->ackrcv_bad += data[2];
 121        /* AR_FCS_FAIL */
 122        stats->fcs_bad += data[3];
 123        /* AR_BEACON_CNT */
 124        stats->beacons += data[4];
 125}
 126
 127static void ath9k_ani_restart(struct ath_hw *ah)
 128{
 129        struct ar5416AniState *aniState = &ah->ani;
 130
 131        aniState->listenTime = 0;
 132
 133        ENABLE_REGWRITE_BUFFER(ah);
 134
 135        REG_WRITE(ah, AR_PHY_ERR_1, 0);
 136        REG_WRITE(ah, AR_PHY_ERR_2, 0);
 137        REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
 138        REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 139
 140        REGWRITE_BUFFER_FLUSH(ah);
 141
 142        ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 143
 144        aniState->ofdmPhyErrCount = 0;
 145        aniState->cckPhyErrCount = 0;
 146}
 147
 148/* Adjust the OFDM Noise Immunity Level */
 149static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
 150                                  bool scan)
 151{
 152        struct ar5416AniState *aniState = &ah->ani;
 153        struct ath_common *common = ath9k_hw_common(ah);
 154        const struct ani_ofdm_level_entry *entry_ofdm;
 155        const struct ani_cck_level_entry *entry_cck;
 156        bool weak_sig;
 157
 158        ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
 159                aniState->ofdmNoiseImmunityLevel,
 160                immunityLevel, BEACON_RSSI(ah),
 161                ATH9K_ANI_RSSI_THR_LOW,
 162                ATH9K_ANI_RSSI_THR_HIGH);
 163
 164        if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL)
 165                immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
 166
 167        if (!scan)
 168                aniState->ofdmNoiseImmunityLevel = immunityLevel;
 169
 170        entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
 171        entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
 172
 173        if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
 174                ath9k_hw_ani_control(ah,
 175                                     ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
 176                                     entry_ofdm->spur_immunity_level);
 177
 178        if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
 179            entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
 180                ath9k_hw_ani_control(ah,
 181                                     ATH9K_ANI_FIRSTEP_LEVEL,
 182                                     entry_ofdm->fir_step_level);
 183
 184        weak_sig = entry_ofdm->ofdm_weak_signal_on;
 185        if (ah->opmode == NL80211_IFTYPE_STATION &&
 186            BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
 187                weak_sig = true;
 188        /*
 189         * Newer chipsets are better at dealing with high PHY error counts -
 190         * keep weak signal detection enabled when no RSSI threshold is
 191         * available to determine if it is needed (mode != STA)
 192         */
 193        else if (AR_SREV_9300_20_OR_LATER(ah) &&
 194                 ah->opmode != NL80211_IFTYPE_STATION)
 195                weak_sig = true;
 196
 197        /* Older chipsets are more sensitive to high PHY error counts */
 198        else if (!AR_SREV_9300_20_OR_LATER(ah) &&
 199                 aniState->ofdmNoiseImmunityLevel >= 8)
 200                weak_sig = false;
 201
 202        if (aniState->ofdmWeakSigDetect != weak_sig)
 203                ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
 204                                     weak_sig);
 205
 206        if (!AR_SREV_9300_20_OR_LATER(ah))
 207                return;
 208
 209        if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
 210                ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
 211                ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
 212        } else {
 213                ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
 214                ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
 215        }
 216}
 217
 218static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
 219{
 220        struct ar5416AniState *aniState = &ah->ani;
 221
 222        if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
 223                ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
 224}
 225
 226/*
 227 * Set the ANI settings to match an CCK level.
 228 */
 229static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
 230                                 bool scan)
 231{
 232        struct ar5416AniState *aniState = &ah->ani;
 233        struct ath_common *common = ath9k_hw_common(ah);
 234        const struct ani_ofdm_level_entry *entry_ofdm;
 235        const struct ani_cck_level_entry *entry_cck;
 236
 237        ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
 238                aniState->cckNoiseImmunityLevel, immunityLevel,
 239                BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
 240                ATH9K_ANI_RSSI_THR_HIGH);
 241
 242        if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL)
 243                immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
 244
 245        if (ah->opmode == NL80211_IFTYPE_STATION &&
 246            BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
 247            immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
 248                immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
 249
 250        if (!scan)
 251                aniState->cckNoiseImmunityLevel = immunityLevel;
 252
 253        entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
 254        entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
 255
 256        if (aniState->firstepLevel != entry_cck->fir_step_level &&
 257            entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
 258                ath9k_hw_ani_control(ah,
 259                                     ATH9K_ANI_FIRSTEP_LEVEL,
 260                                     entry_cck->fir_step_level);
 261
 262        /* Skip MRC CCK for pre AR9003 families */
 263        if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah) ||
 264            AR_SREV_9565(ah) || AR_SREV_9561(ah))
 265                return;
 266
 267        if (aniState->mrcCCK != entry_cck->mrc_cck_on)
 268                ath9k_hw_ani_control(ah,
 269                                     ATH9K_ANI_MRC_CCK,
 270                                     entry_cck->mrc_cck_on);
 271}
 272
 273static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
 274{
 275        struct ar5416AniState *aniState = &ah->ani;
 276
 277        if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
 278                ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
 279                                     false);
 280}
 281
 282/*
 283 * only lower either OFDM or CCK errors per turn
 284 * we lower the other one next time
 285 */
 286static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
 287{
 288        struct ar5416AniState *aniState = &ah->ani;
 289
 290        /* lower OFDM noise immunity */
 291        if (aniState->ofdmNoiseImmunityLevel > 0 &&
 292            (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
 293                ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1,
 294                                      false);
 295                return;
 296        }
 297
 298        /* lower CCK noise immunity */
 299        if (aniState->cckNoiseImmunityLevel > 0)
 300                ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1,
 301                                     false);
 302}
 303
 304/*
 305 * Restore the ANI parameters in the HAL and reset the statistics.
 306 * This routine should be called for every hardware reset and for
 307 * every channel change.
 308 */
 309void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 310{
 311        struct ar5416AniState *aniState = &ah->ani;
 312        struct ath9k_channel *chan = ah->curchan;
 313        struct ath_common *common = ath9k_hw_common(ah);
 314        int ofdm_nil, cck_nil;
 315
 316        if (!chan)
 317                return;
 318
 319        BUG_ON(aniState == NULL);
 320        ah->stats.ast_ani_reset++;
 321
 322        ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
 323                         aniState->ofdmNoiseImmunityLevel);
 324        cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
 325                         aniState->cckNoiseImmunityLevel);
 326
 327        if (is_scanning ||
 328            (ah->opmode != NL80211_IFTYPE_STATION &&
 329             ah->opmode != NL80211_IFTYPE_ADHOC)) {
 330                /*
 331                 * If we're scanning or in AP mode, the defaults (ini)
 332                 * should be in place. For an AP we assume the historical
 333                 * levels for this channel are probably outdated so start
 334                 * from defaults instead.
 335                 */
 336                if (aniState->ofdmNoiseImmunityLevel !=
 337                    ATH9K_ANI_OFDM_DEF_LEVEL ||
 338                    aniState->cckNoiseImmunityLevel !=
 339                    ATH9K_ANI_CCK_DEF_LEVEL) {
 340                        ath_dbg(common, ANI,
 341                                "Restore defaults: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
 342                                ah->opmode,
 343                                chan->channel,
 344                                is_scanning,
 345                                aniState->ofdmNoiseImmunityLevel,
 346                                aniState->cckNoiseImmunityLevel);
 347
 348                        ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL;
 349                        cck_nil = ATH9K_ANI_CCK_DEF_LEVEL;
 350                }
 351        } else {
 352                /*
 353                 * restore historical levels for this channel
 354                 */
 355                ath_dbg(common, ANI,
 356                        "Restore history: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
 357                        ah->opmode,
 358                        chan->channel,
 359                        is_scanning,
 360                        aniState->ofdmNoiseImmunityLevel,
 361                        aniState->cckNoiseImmunityLevel);
 362        }
 363        ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
 364        ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);
 365
 366        ath9k_ani_restart(ah);
 367}
 368
 369static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
 370{
 371        struct ath_common *common = ath9k_hw_common(ah);
 372        struct ar5416AniState *aniState = &ah->ani;
 373        u32 phyCnt1, phyCnt2;
 374        int32_t listenTime;
 375
 376        ath_hw_cycle_counters_update(common);
 377        listenTime = ath_hw_get_listen_time(common);
 378
 379        if (listenTime <= 0) {
 380                ah->stats.ast_ani_lneg_or_lzero++;
 381                ath9k_ani_restart(ah);
 382                return false;
 383        }
 384
 385        aniState->listenTime += listenTime;
 386
 387        ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 388
 389        phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
 390        phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
 391
 392        ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount;
 393        aniState->ofdmPhyErrCount = phyCnt1;
 394
 395        ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount;
 396        aniState->cckPhyErrCount = phyCnt2;
 397
 398        return true;
 399}
 400
 401void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
 402{
 403        struct ar5416AniState *aniState = &ah->ani;
 404        struct ath_common *common = ath9k_hw_common(ah);
 405        u32 ofdmPhyErrRate, cckPhyErrRate;
 406
 407        if (!ath9k_hw_ani_read_counters(ah))
 408                return;
 409
 410        ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
 411                         aniState->listenTime;
 412        cckPhyErrRate =  aniState->cckPhyErrCount * 1000 /
 413                         aniState->listenTime;
 414
 415        ath_dbg(common, ANI,
 416                "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
 417                aniState->listenTime,
 418                aniState->ofdmNoiseImmunityLevel,
 419                ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
 420                cckPhyErrRate, aniState->ofdmsTurn);
 421
 422        if (aniState->listenTime > ah->aniperiod) {
 423                if (cckPhyErrRate < ah->config.cck_trig_low &&
 424                    ofdmPhyErrRate < ah->config.ofdm_trig_low) {
 425                        ath9k_hw_ani_lower_immunity(ah);
 426                        aniState->ofdmsTurn = !aniState->ofdmsTurn;
 427                } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
 428                        ath9k_hw_ani_ofdm_err_trigger(ah);
 429                        aniState->ofdmsTurn = false;
 430                } else if (cckPhyErrRate > ah->config.cck_trig_high) {
 431                        ath9k_hw_ani_cck_err_trigger(ah);
 432                        aniState->ofdmsTurn = true;
 433                } else
 434                        return;
 435                        
 436                ath9k_ani_restart(ah);
 437        }
 438}
 439EXPORT_SYMBOL(ath9k_hw_ani_monitor);
 440
 441void ath9k_enable_mib_counters(struct ath_hw *ah)
 442{
 443        struct ath_common *common = ath9k_hw_common(ah);
 444
 445        ath_dbg(common, ANI, "Enable MIB counters\n");
 446
 447        ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 448
 449        ENABLE_REGWRITE_BUFFER(ah);
 450
 451        REG_WRITE(ah, AR_FILT_OFDM, 0);
 452        REG_WRITE(ah, AR_FILT_CCK, 0);
 453        REG_WRITE(ah, AR_MIBC,
 454                  ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
 455                  & 0x0f);
 456        REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
 457        REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 458
 459        REGWRITE_BUFFER_FLUSH(ah);
 460}
 461
 462/* Freeze the MIB counters, get the stats and then clear them */
 463void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
 464{
 465        struct ath_common *common = ath9k_hw_common(ah);
 466
 467        ath_dbg(common, ANI, "Disable MIB counters\n");
 468
 469        REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
 470        ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 471        REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
 472        REG_WRITE(ah, AR_FILT_OFDM, 0);
 473        REG_WRITE(ah, AR_FILT_CCK, 0);
 474}
 475EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
 476
 477void ath9k_hw_ani_init(struct ath_hw *ah)
 478{
 479        struct ath_common *common = ath9k_hw_common(ah);
 480        struct ar5416AniState *ani = &ah->ani;
 481
 482        ath_dbg(common, ANI, "Initialize ANI\n");
 483
 484        if (AR_SREV_9300_20_OR_LATER(ah)) {
 485                ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
 486                ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
 487                ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
 488                ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
 489        } else {
 490                ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
 491                ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
 492                ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
 493                ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
 494        }
 495
 496        ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
 497        ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
 498        ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
 499        ani->ofdmsTurn = true;
 500        ani->ofdmWeakSigDetect = true;
 501        ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
 502        ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
 503
 504        /*
 505         * since we expect some ongoing maintenance on the tables, let's sanity
 506         * check here default level should not modify INI setting.
 507         */
 508        ah->aniperiod = ATH9K_ANI_PERIOD;
 509        ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
 510
 511        ath9k_ani_restart(ah);
 512        ath9k_enable_mib_counters(ah);
 513}
 514