ani.c 15.0 KB
Newer Older
S
Sujith 已提交
1
/*
2
 * Copyright (c) 2008-2011 Atheros Communications Inc.
S
Sujith 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

17
#include <linux/kernel.h>
18
#include <linux/export.h>
19
#include "hw.h"
20
#include "hw-ops.h"
S
Sujith 已提交
21

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
struct ani_ofdm_level_entry {
	int spur_immunity_level;
	int fir_step_level;
	int ofdm_weak_signal_on;
};

/* values here are relative to the INI */

/*
 * Legend:
 *
 * SI: Spur immunity
 * FS: FIR Step
 * WS: OFDM / CCK Weak Signal detection
 * MRC-CCK: Maximal Ratio Combining for CCK
 */

static const struct ani_ofdm_level_entry ofdm_level_table[] = {
	/* SI  FS  WS */
	{  0,  0,  1  }, /* lvl 0 */
	{  1,  1,  1  }, /* lvl 1 */
	{  2,  2,  1  }, /* lvl 2 */
	{  3,  2,  1  }, /* lvl 3  (default) */
	{  4,  3,  1  }, /* lvl 4 */
	{  5,  4,  1  }, /* lvl 5 */
	{  6,  5,  1  }, /* lvl 6 */
	{  7,  6,  1  }, /* lvl 7 */
S
Sujith Manoharan 已提交
49 50
	{  7,  7,  1  }, /* lvl 8 */
	{  7,  8,  0  }  /* lvl 9 */
51 52
};
#define ATH9K_ANI_OFDM_NUM_LEVEL \
53
	ARRAY_SIZE(ofdm_level_table)
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
#define ATH9K_ANI_OFDM_MAX_LEVEL \
	(ATH9K_ANI_OFDM_NUM_LEVEL-1)
#define ATH9K_ANI_OFDM_DEF_LEVEL \
	3 /* default level - matches the INI settings */

/*
 * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
 * With OFDM for single stream you just add up all antenna inputs, you're
 * only interested in what you get after FFT. Signal aligment is also not
 * required for OFDM because any phase difference adds up in the frequency
 * domain.
 *
 * MRC requires extra work for use with CCK. You need to align the antenna
 * signals from the different antenna before you can add the signals together.
 * You need aligment of signals as CCK is in time domain, so addition can cancel
 * your signal completely if phase is 180 degrees (think of adding sine waves).
 * You also need to remove noise before the addition and this is where ANI
 * MRC CCK comes into play. One of the antenna inputs may be stronger but
 * lower SNR, so just adding after alignment can be dangerous.
 *
 * Regardless of alignment in time, the antenna signals add constructively after
 * FFT and improve your reception. For more information:
 *
 * http://en.wikipedia.org/wiki/Maximal-ratio_combining
 */

struct ani_cck_level_entry {
	int fir_step_level;
	int mrc_cck_on;
};

static const struct ani_cck_level_entry cck_level_table[] = {
	/* FS  MRC-CCK  */
	{  0,  1  }, /* lvl 0 */
	{  1,  1  }, /* lvl 1 */
	{  2,  1  }, /* lvl 2  (default) */
	{  3,  1  }, /* lvl 3 */
	{  4,  0  }, /* lvl 4 */
	{  5,  0  }, /* lvl 5 */
	{  6,  0  }, /* lvl 6 */
S
Sujith Manoharan 已提交
94 95
	{  7,  0  }, /* lvl 7 (only for high rssi) */
	{  8,  0  }  /* lvl 8 (only for high rssi) */
96 97 98
};

#define ATH9K_ANI_CCK_NUM_LEVEL \
99
	ARRAY_SIZE(cck_level_table)
100 101 102 103 104 105 106
#define ATH9K_ANI_CCK_MAX_LEVEL \
	(ATH9K_ANI_CCK_NUM_LEVEL-1)
#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
	(ATH9K_ANI_CCK_NUM_LEVEL-3)
#define ATH9K_ANI_CCK_DEF_LEVEL \
	2 /* default level - matches the INI settings */

107
static void ath9k_hw_update_mibstats(struct ath_hw *ah,
S
Sujith 已提交
108 109 110 111 112 113 114 115 116
				     struct ath9k_mib_stats *stats)
{
	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
	stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
	stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
	stats->rts_good += REG_READ(ah, AR_RTS_OK);
	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
}

117
static void ath9k_ani_restart(struct ath_hw *ah)
S
Sujith 已提交
118 119 120
{
	struct ar5416AniState *aniState;

121
	if (!ah->curchan)
S
Sujith 已提交
122 123
		return;

124
	aniState = &ah->ani;
S
Sujith 已提交
125
	aniState->listenTime = 0;
S
Sujith 已提交
126

127 128
	ENABLE_REGWRITE_BUFFER(ah);

129 130
	REG_WRITE(ah, AR_PHY_ERR_1, 0);
	REG_WRITE(ah, AR_PHY_ERR_2, 0);
131 132 133 134 135 136 137 138 139 140 141 142
	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

	REGWRITE_BUFFER_FLUSH(ah);

	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

	aniState->ofdmPhyErrCount = 0;
	aniState->cckPhyErrCount = 0;
}

/* Adjust the OFDM Noise Immunity Level */
143 144
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
				  bool scan)
145
{
146
	struct ar5416AniState *aniState = &ah->ani;
147 148 149
	struct ath_common *common = ath9k_hw_common(ah);
	const struct ani_ofdm_level_entry *entry_ofdm;
	const struct ani_cck_level_entry *entry_cck;
150
	bool weak_sig;
151

152
	ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
J
Joe Perches 已提交
153
		aniState->ofdmNoiseImmunityLevel,
154
		immunityLevel, BEACON_RSSI(ah),
155 156
		ATH9K_ANI_RSSI_THR_LOW,
		ATH9K_ANI_RSSI_THR_HIGH);
157

158
	if (!scan)
159
		aniState->ofdmNoiseImmunityLevel = immunityLevel;
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

	entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
	entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];

	if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
		ath9k_hw_ani_control(ah,
				     ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
				     entry_ofdm->spur_immunity_level);

	if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
	    entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
		ath9k_hw_ani_control(ah,
				     ATH9K_ANI_FIRSTEP_LEVEL,
				     entry_ofdm->fir_step_level);

175 176
	weak_sig = entry_ofdm->ofdm_weak_signal_on;
	if (ah->opmode == NL80211_IFTYPE_STATION &&
177
	    BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
178 179
		weak_sig = true;

180 181 182 183 184 185 186 187 188
	/*
	 * OFDM Weak signal detection is always enabled for AP mode.
	 */
	if (ah->opmode != NL80211_IFTYPE_AP &&
	    aniState->ofdmWeakSigDetect != weak_sig) {
		ath9k_hw_ani_control(ah,
				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     entry_ofdm->ofdm_weak_signal_on);
	}
S
Sujith Manoharan 已提交
189 190 191 192 193 194 195 196

	if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
	} else {
		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
	}
197 198
}

199
static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
200 201 202
{
	struct ar5416AniState *aniState;

203
	if (!ah->curchan)
204 205
		return;

206
	aniState = &ah->ani;
207 208

	if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
209
		ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
210 211 212 213 214
}

/*
 * Set the ANI settings to match an CCK level.
 */
215 216
static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
				 bool scan)
217
{
218
	struct ar5416AniState *aniState = &ah->ani;
219 220 221 222
	struct ath_common *common = ath9k_hw_common(ah);
	const struct ani_ofdm_level_entry *entry_ofdm;
	const struct ani_cck_level_entry *entry_cck;

223
	ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
J
Joe Perches 已提交
224
		aniState->cckNoiseImmunityLevel, immunityLevel,
225 226
		BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
		ATH9K_ANI_RSSI_THR_HIGH);
227

228
	if (ah->opmode == NL80211_IFTYPE_STATION &&
229
	    BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
230 231 232
	    immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
		immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;

233
	if (!scan)
234
		aniState->cckNoiseImmunityLevel = immunityLevel;
235 236 237 238 239 240 241 242 243 244 245

	entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
	entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];

	if (aniState->firstepLevel != entry_cck->fir_step_level &&
	    entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
		ath9k_hw_ani_control(ah,
				     ATH9K_ANI_FIRSTEP_LEVEL,
				     entry_cck->fir_step_level);

	/* Skip MRC CCK for pre AR9003 families */
246
	if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
247 248
		return;

249
	if (aniState->mrcCCK != entry_cck->mrc_cck_on)
250 251 252 253 254
		ath9k_hw_ani_control(ah,
				     ATH9K_ANI_MRC_CCK,
				     entry_cck->mrc_cck_on);
}

255
static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
256 257 258
{
	struct ar5416AniState *aniState;

259
	if (!ah->curchan)
260 261
		return;

262
	aniState = &ah->ani;
263 264

	if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
265 266
		ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
				     false);
267 268 269 270 271 272
}

/*
 * only lower either OFDM or CCK errors per turn
 * we lower the other one next time
 */
273
static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
274 275 276
{
	struct ar5416AniState *aniState;

277
	aniState = &ah->ani;
278 279 280 281

	/* lower OFDM noise immunity */
	if (aniState->ofdmNoiseImmunityLevel > 0 &&
	    (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
282 283
		ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1,
				      false);
284 285 286 287 288
		return;
	}

	/* lower CCK noise immunity */
	if (aniState->cckNoiseImmunityLevel > 0)
289 290
		ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1,
				     false);
291 292 293 294 295 296 297
}

/*
 * Restore the ANI parameters in the HAL and reset the statistics.
 * This routine should be called for every hardware reset and for
 * every channel change.
 */
298
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
299
{
300
	struct ar5416AniState *aniState = &ah->ani;
301 302
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);
303
	int ofdm_nil, cck_nil;
304

305
	if (!ah->curchan)
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
		return;

	BUG_ON(aniState == NULL);
	ah->stats.ast_ani_reset++;

	/* only allow a subset of functions in AP mode */
	if (ah->opmode == NL80211_IFTYPE_AP) {
		if (IS_CHAN_2GHZ(chan)) {
			ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
					    ATH9K_ANI_FIRSTEP_LEVEL);
			if (AR_SREV_9300_20_OR_LATER(ah))
				ah->ani_function |= ATH9K_ANI_MRC_CCK;
		} else
			ah->ani_function = 0;
	}

	/* always allow mode (on/off) to be controlled */
	ah->ani_function |= ATH9K_ANI_MODE;

325 326 327 328 329
	ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
			 aniState->ofdmNoiseImmunityLevel);
	cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
			 aniState->cckNoiseImmunityLevel);

330 331 332 333 334 335 336 337 338 339 340 341 342
	if (is_scanning ||
	    (ah->opmode != NL80211_IFTYPE_STATION &&
	     ah->opmode != NL80211_IFTYPE_ADHOC)) {
		/*
		 * If we're scanning or in AP mode, the defaults (ini)
		 * should be in place. For an AP we assume the historical
		 * levels for this channel are probably outdated so start
		 * from defaults instead.
		 */
		if (aniState->ofdmNoiseImmunityLevel !=
		    ATH9K_ANI_OFDM_DEF_LEVEL ||
		    aniState->cckNoiseImmunityLevel !=
		    ATH9K_ANI_CCK_DEF_LEVEL) {
343
			ath_dbg(common, ANI,
J
Joe Perches 已提交
344 345 346 347 348 349 350
				"Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
				ah->opmode,
				chan->channel,
				chan->channelFlags,
				is_scanning,
				aniState->ofdmNoiseImmunityLevel,
				aniState->cckNoiseImmunityLevel);
351

352 353
			ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL;
			cck_nil = ATH9K_ANI_CCK_DEF_LEVEL;
354 355 356 357 358
		}
	} else {
		/*
		 * restore historical levels for this channel
		 */
359
		ath_dbg(common, ANI,
J
Joe Perches 已提交
360 361 362 363 364 365 366
			"Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
			ah->opmode,
			chan->channel,
			chan->channelFlags,
			is_scanning,
			aniState->ofdmNoiseImmunityLevel,
			aniState->cckNoiseImmunityLevel);
367
	}
368 369
	ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
	ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);
370

371
	ath9k_ani_restart(ah);
S
Sujith 已提交
372 373
}

374
static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
S
Sujith 已提交
375
{
376
	struct ath_common *common = ath9k_hw_common(ah);
377
	struct ar5416AniState *aniState = &ah->ani;
378 379
	u32 phyCnt1, phyCnt2;
	int32_t listenTime;
S
Sujith 已提交
380

381 382 383
	ath_hw_cycle_counters_update(common);
	listenTime = ath_hw_get_listen_time(common);

384
	if (listenTime <= 0) {
385
		ah->stats.ast_ani_lneg_or_lzero++;
386
		ath9k_ani_restart(ah);
387
		return false;
S
Sujith 已提交
388 389 390 391
	}

	aniState->listenTime += listenTime;

S
Sujith 已提交
392
	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
S
Sujith 已提交
393

S
Sujith 已提交
394 395 396
	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);

397 398 399 400 401
	ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount;
	aniState->ofdmPhyErrCount = phyCnt1;

	ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount;
	aniState->cckPhyErrCount = phyCnt2;
S
Sujith 已提交
402

403
	return true;
404 405
}

406
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
407 408 409 410 411
{
	struct ar5416AniState *aniState;
	struct ath_common *common = ath9k_hw_common(ah);
	u32 ofdmPhyErrRate, cckPhyErrRate;

412
	if (!ah->curchan)
413 414
		return;

415
	aniState = &ah->ani;
416 417
	if (!ath9k_hw_ani_read_counters(ah))
		return;
418 419 420 421 422 423

	ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
			 aniState->listenTime;
	cckPhyErrRate =  aniState->cckPhyErrCount * 1000 /
			 aniState->listenTime;

424
	ath_dbg(common, ANI,
J
Joe Perches 已提交
425 426 427 428 429
		"listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
		aniState->listenTime,
		aniState->ofdmNoiseImmunityLevel,
		ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
		cckPhyErrRate, aniState->ofdmsTurn);
430

S
Sujith Manoharan 已提交
431 432 433
	if (aniState->listenTime > ah->aniperiod) {
		if (cckPhyErrRate < ah->config.cck_trig_low &&
		    ofdmPhyErrRate < ah->config.ofdm_trig_low) {
434 435
			ath9k_hw_ani_lower_immunity(ah);
			aniState->ofdmsTurn = !aniState->ofdmsTurn;
S
Sujith Manoharan 已提交
436
		} else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
437
			ath9k_hw_ani_ofdm_err_trigger(ah);
438
			aniState->ofdmsTurn = false;
439
		} else if (cckPhyErrRate > ah->config.cck_trig_high) {
440
			ath9k_hw_ani_cck_err_trigger(ah);
441
			aniState->ofdmsTurn = true;
S
Sujith 已提交
442
		}
443
		ath9k_ani_restart(ah);
S
Sujith 已提交
444 445
	}
}
446
EXPORT_SYMBOL(ath9k_hw_ani_monitor);
S
Sujith 已提交
447

448
void ath9k_enable_mib_counters(struct ath_hw *ah)
S
Sujith 已提交
449
{
450 451
	struct ath_common *common = ath9k_hw_common(ah);

452
	ath_dbg(common, ANI, "Enable MIB counters\n");
S
Sujith 已提交
453

454
	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
S
Sujith 已提交
455

S
Sujith 已提交
456 457
	ENABLE_REGWRITE_BUFFER(ah);

S
Sujith 已提交
458 459 460 461 462 463 464
	REG_WRITE(ah, AR_FILT_OFDM, 0);
	REG_WRITE(ah, AR_FILT_CCK, 0);
	REG_WRITE(ah, AR_MIBC,
		  ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
		  & 0x0f);
	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
S
Sujith 已提交
465 466

	REGWRITE_BUFFER_FLUSH(ah);
S
Sujith 已提交
467 468
}

469
/* Freeze the MIB counters, get the stats and then clear them */
470
void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
S
Sujith 已提交
471
{
472 473
	struct ath_common *common = ath9k_hw_common(ah);

474
	ath_dbg(common, ANI, "Disable MIB counters\n");
475

476
	REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
477
	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
478
	REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
S
Sujith 已提交
479 480 481
	REG_WRITE(ah, AR_FILT_OFDM, 0);
	REG_WRITE(ah, AR_FILT_CCK, 0);
}
S
Sujith 已提交
482
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
S
Sujith 已提交
483

484
void ath9k_hw_ani_init(struct ath_hw *ah)
S
Sujith 已提交
485
{
486
	struct ath_common *common = ath9k_hw_common(ah);
487
	struct ar5416AniState *ani = &ah->ani;
S
Sujith 已提交
488

489
	ath_dbg(common, ANI, "Initialize ANI\n");
490

491 492 493 494
	ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
	ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
	ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
	ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
495

496 497 498 499 500 501 502
	ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
	ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
	ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
	ani->ofdmsTurn = true;
	ani->ofdmWeakSigDetect = true;
	ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
	ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
503 504 505 506 507

	/*
	 * since we expect some ongoing maintenance on the tables, let's sanity
	 * check here default level should not modify INI setting.
	 */
508 509
	ah->aniperiod = ATH9K_ANI_PERIOD;
	ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
S
Sujith 已提交
510

511 512
	ath9k_ani_restart(ah);
	ath9k_enable_mib_counters(ah);
S
Sujith 已提交
513
}