Esempio n. 1
0
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
{
	struct ar5416AniState *aniState;
	struct ath_common *common = ath9k_hw_common(ah);
	u32 ofdmPhyErrRate, cckPhyErrRate;

	if (!DO_ANI(ah))
		return;

	aniState = &ah->curchan->ani;
	if (WARN_ON(!aniState))
		return;

	if (!ath9k_hw_ani_read_counters(ah))
		return;

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

	ath_dbg(common, ATH_DBG_ANI,
		"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);

	if (aniState->listenTime > 5 * ah->aniperiod) {
		if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
		    cckPhyErrRate <= ah->config.cck_trig_low) {
			ath9k_hw_ani_lower_immunity(ah);
			aniState->ofdmsTurn = !aniState->ofdmsTurn;
		}
		ath9k_ani_restart(ah);
	} else if (aniState->listenTime > ah->aniperiod) {
		/* check to see if need to raise immunity */
		if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
		    (cckPhyErrRate <= ah->config.cck_trig_high ||
		     aniState->ofdmsTurn)) {
			ath9k_hw_ani_ofdm_err_trigger(ah);
			ath9k_ani_restart(ah);
			aniState->ofdmsTurn = false;
		} else if (cckPhyErrRate > ah->config.cck_trig_high) {
			ath9k_hw_ani_cck_err_trigger(ah);
			ath9k_ani_restart(ah);
			aniState->ofdmsTurn = true;
		}
	}
}
Esempio n. 2
0
File: ani.c Progetto: 020gzh/linux
static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ar5416AniState *aniState = &ah->ani;
	u32 phyCnt1, phyCnt2;
	int32_t listenTime;

	ath_hw_cycle_counters_update(common);
	listenTime = ath_hw_get_listen_time(common);

	if (listenTime <= 0) {
		ah->stats.ast_ani_lneg_or_lzero++;
		ath9k_ani_restart(ah);
		return false;
	}

	aniState->listenTime += listenTime;

	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);

	ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount;
	aniState->ofdmPhyErrCount = phyCnt1;

	ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount;
	aniState->cckPhyErrCount = phyCnt2;

	return true;
}
Esempio n. 3
0
File: ani.c Progetto: 03199618/linux
void ath9k_hw_ani_init(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ar5416AniState *ani = &ah->ani;

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

	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;

	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;

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

	ath9k_ani_restart(ah);
	ath9k_enable_mib_counters(ah);
}
Esempio n. 4
0
File: ani.c Progetto: 020gzh/linux
/*
 * 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.
 */
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
	struct ar5416AniState *aniState = &ah->ani;
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);
	int ofdm_nil, cck_nil;

	if (!chan)
		return;

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

	ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
			 aniState->ofdmNoiseImmunityLevel);
	cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
			 aniState->cckNoiseImmunityLevel);

	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) {
			ath_dbg(common, ANI,
				"Restore defaults: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
				ah->opmode,
				chan->channel,
				is_scanning,
				aniState->ofdmNoiseImmunityLevel,
				aniState->cckNoiseImmunityLevel);

			ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL;
			cck_nil = ATH9K_ANI_CCK_DEF_LEVEL;
		}
	} else {
		/*
		 * restore historical levels for this channel
		 */
		ath_dbg(common, ANI,
			"Restore history: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
			ah->opmode,
			chan->channel,
			is_scanning,
			aniState->ofdmNoiseImmunityLevel,
			aniState->cckNoiseImmunityLevel);
	}
	ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
	ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);

	ath9k_ani_restart(ah);
}
Esempio n. 5
0
/*
 * Process a MIB interrupt.  We may potentially be invoked because
 * any of the MIB counters overflow/trigger so don't assume we're
 * here because a PHY error counter triggered.
 */
void ath9k_hw_procmibevent(struct ath_hal *ah,
			   const struct ath9k_node_stats *stats)
{
	struct ath_hal_5416 *ahp = AH5416(ah);
	u32 phyCnt1, phyCnt2;

	/* Reset these counters regardless */
	REG_WRITE(ah, AR_FILT_OFDM, 0);
	REG_WRITE(ah, AR_FILT_CCK, 0);
	if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
		REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);

	/* Clear the mib counters and save them in the stats */
	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
	ahp->ah_stats.ast_nodestats = *stats;

	if (!DO_ANI(ah))
		return;

	/* NB: these are not reset-on-read */
	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
	if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
	    ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
		struct ar5416AniState *aniState = ahp->ah_curani;
		u32 ofdmPhyErrCnt, cckPhyErrCnt;

		/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
		ahp->ah_stats.ast_ani_ofdmerrs +=
			ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;

		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
		ahp->ah_stats.ast_ani_cckerrs +=
			cckPhyErrCnt - aniState->cckPhyErrCount;
		aniState->cckPhyErrCount = cckPhyErrCnt;

		/*
		 * NB: figure out which counter triggered.  If both
		 * trigger we'll only deal with one as the processing
		 * clobbers the error counter so the trigger threshold
		 * check will never be true.
		 */
		if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
			ath9k_hw_ani_ofdm_err_trigger(ah);
		if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
			ath9k_hw_ani_cck_err_trigger(ah);
		/* NB: always restart to insure the h/w counters are reset */
		ath9k_ani_restart(ah);
	}
}
Esempio n. 6
0
void ath9k_hw_ani_init(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	int i;

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

	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;

	for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
		struct ath9k_channel *chan = &ah->channels[i];
		struct ar5416AniState *ani = &chan->ani;

		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->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
		ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
		ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
		ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
		ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
	}

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

	if (ah->config.enable_ani)
		ah->proc_phyerr |= HAL_PROCESS_ANI;

	ath9k_ani_restart(ah);
	ath9k_enable_mib_counters(ah);
}
Esempio n. 7
0
/*
 * Process a MIB interrupt.  We may potentially be invoked because
 * any of the MIB counters overflow/trigger so don't assume we're
 * here because a PHY error counter triggered.
 */
void ath9k_hw_proc_mib_event(struct ath_hw *ah)
{
	u32 phyCnt1, phyCnt2;

	/* Reset these counters regardless */
	REG_WRITE(ah, AR_FILT_OFDM, 0);
	REG_WRITE(ah, AR_FILT_CCK, 0);
	if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
		REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);

	/* Clear the mib counters and save them in the stats */
	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

	if (!DO_ANI(ah)) {
		/*
		 * We must always clear the interrupt cause by
		 * resetting the phy error regs.
		 */
		REG_WRITE(ah, AR_PHY_ERR_1, 0);
		REG_WRITE(ah, AR_PHY_ERR_2, 0);
		return;
	}

	/* NB: these are not reset-on-read */
	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
	if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
	    ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {

		if (!use_new_ani(ah))
			ath9k_hw_ani_read_counters(ah);

		/* NB: always restart to insure the h/w counters are reset */
		ath9k_ani_restart(ah);
	}
}
Esempio n. 8
0
void ath9k_hw_proc_mib_event(struct ath_hw *ah)
{
	u32 phyCnt1, phyCnt2;

	/*                                 */
	REG_WRITE(ah, AR_FILT_OFDM, 0);
	REG_WRITE(ah, AR_FILT_CCK, 0);
	if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
		REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);

	/*                                                   */
	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

	if (!DO_ANI(ah)) {
		/*
                                                
                                  
   */
		REG_WRITE(ah, AR_PHY_ERR_1, 0);
		REG_WRITE(ah, AR_PHY_ERR_2, 0);
		return;
	}

	/*                                 */
	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
	if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
	    ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {

		if (!use_new_ani(ah))
			ath9k_hw_ani_read_counters(ah);

		/*                                                         */
		ath9k_ani_restart(ah);
	}
}
Esempio n. 9
0
static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ar5416AniState *aniState = &ah->curchan->ani;
	u32 ofdm_base = 0;
	u32 cck_base = 0;
	u32 ofdmPhyErrCnt, cckPhyErrCnt;
	u32 phyCnt1, phyCnt2;
	int32_t listenTime;

	ath_hw_cycle_counters_update(common);
	listenTime = ath_hw_get_listen_time(common);

	if (listenTime <= 0) {
		ah->stats.ast_ani_lneg_or_lzero++;
		ath9k_ani_restart(ah);
		return false;
	}

	if (!use_new_ani(ah)) {
		ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
		cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
	}

	aniState->listenTime += listenTime;

	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);

	if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
		if (phyCnt1 < ofdm_base) {
			ath_dbg(common, ATH_DBG_ANI,
				"phyCnt1 0x%x, resetting counter value to 0x%x\n",
				phyCnt1, ofdm_base);
			REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
			REG_WRITE(ah, AR_PHY_ERR_MASK_1,
				  AR_PHY_ERR_OFDM_TIMING);
		}
		if (phyCnt2 < cck_base) {
			ath_dbg(common, ATH_DBG_ANI,
				"phyCnt2 0x%x, resetting counter value to 0x%x\n",
				phyCnt2, cck_base);
			REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
			REG_WRITE(ah, AR_PHY_ERR_MASK_2,
				  AR_PHY_ERR_CCK_TIMING);
		}
		return false;
	}

	ofdmPhyErrCnt = phyCnt1 - ofdm_base;
	ah->stats.ast_ani_ofdmerrs +=
		ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
	aniState->ofdmPhyErrCount = ofdmPhyErrCnt;

	cckPhyErrCnt = phyCnt2 - cck_base;
	ah->stats.ast_ani_cckerrs +=
		cckPhyErrCnt - aniState->cckPhyErrCount;
	aniState->cckPhyErrCount = cckPhyErrCnt;
	return true;
}
Esempio n. 10
0
/*
 * 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.
 */
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
	struct ar5416AniState *aniState = &ah->curchan->ani;
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);

	if (!DO_ANI(ah))
		return;

	if (!use_new_ani(ah))
		return ath9k_ani_reset_old(ah, is_scanning);

	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;

	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) {
			ath_dbg(common, ATH_DBG_ANI,
				"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);

			aniState->update_ani = false;
			ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
			ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
		}
	} else {
		/*
		 * restore historical levels for this channel
		 */
		ath_dbg(common, ATH_DBG_ANI,
			"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);

			aniState->update_ani = true;
			ath9k_hw_set_ofdm_nil(ah,
					      aniState->ofdmNoiseImmunityLevel);
			ath9k_hw_set_cck_nil(ah,
					     aniState->cckNoiseImmunityLevel);
	}

	/*
	 * enable phy counters if hw supports or if not, enable phy
	 * interrupts (so we can count each one)
	 */
	ath9k_ani_restart(ah);

	ENABLE_REGWRITE_BUFFER(ah);

	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);
}
Esempio n. 11
0
static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
{
	struct ar5416AniState *aniState;
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);

	if (!DO_ANI(ah))
		return;

	aniState = &ah->curchan->ani;

	if (ah->opmode != NL80211_IFTYPE_STATION
	    && ah->opmode != NL80211_IFTYPE_ADHOC) {
		ath_dbg(common, ATH_DBG_ANI,
			"Reset ANI state opmode %u\n", ah->opmode);
		ah->stats.ast_ani_reset++;

		if (ah->opmode == NL80211_IFTYPE_AP) {
			/*
			 * ath9k_hw_ani_control() will only process items set on
			 * ah->ani_function
			 */
			if (IS_CHAN_2GHZ(chan))
				ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
						    ATH9K_ANI_FIRSTEP_LEVEL);
			else
				ah->ani_function = 0;
		}

		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     !ATH9K_ANI_USE_OFDM_WEAK_SIG);
		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
				     ATH9K_ANI_CCK_WEAK_SIG_THR);

		ath9k_ani_restart(ah);
		return;
	}

	if (aniState->noiseImmunityLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
				     aniState->noiseImmunityLevel);
	if (aniState->spurImmunityLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
				     aniState->spurImmunityLevel);
	if (aniState->ofdmWeakSigDetectOff)
		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     !aniState->ofdmWeakSigDetectOff);
	if (aniState->cckWeakSigThreshold)
		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
				     aniState->cckWeakSigThreshold);
	if (aniState->firstepLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
				     aniState->firstepLevel);

	ath9k_ani_restart(ah);

	ENABLE_REGWRITE_BUFFER(ah);

	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);
}
Esempio n. 12
0
void ath9k_ani_reset(struct ath_hal *ah)
{
	struct ath_hal_5416 *ahp = AH5416(ah);
	struct ar5416AniState *aniState;
	struct ath9k_channel *chan = ah->ah_curchan;
	int index;

	if (!DO_ANI(ah))
		return;

	index = ath9k_hw_get_ani_channel_idx(ah, chan);
	aniState = &ahp->ah_ani[index];
	ahp->ah_curani = aniState;

	if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION
	    && ah->ah_opmode != NL80211_IFTYPE_ADHOC) {
		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
			"Reset ANI state opmode %u\n", ah->ah_opmode);
		ahp->ah_stats.ast_ani_reset++;

		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     !ATH9K_ANI_USE_OFDM_WEAK_SIG);
		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
				     ATH9K_ANI_CCK_WEAK_SIG_THR);

		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
				     ATH9K_RX_FILTER_PHYERR);

		if (ah->ah_opmode == NL80211_IFTYPE_AP) {
			ahp->ah_curani->ofdmTrigHigh =
				ah->ah_config.ofdm_trig_high;
			ahp->ah_curani->ofdmTrigLow =
				ah->ah_config.ofdm_trig_low;
			ahp->ah_curani->cckTrigHigh =
				ah->ah_config.cck_trig_high;
			ahp->ah_curani->cckTrigLow =
				ah->ah_config.cck_trig_low;
		}
		ath9k_ani_restart(ah);
		return;
	}

	if (aniState->noiseImmunityLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
				     aniState->noiseImmunityLevel);
	if (aniState->spurImmunityLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
				     aniState->spurImmunityLevel);
	if (aniState->ofdmWeakSigDetectOff)
		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     !aniState->ofdmWeakSigDetectOff);
	if (aniState->cckWeakSigThreshold)
		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
				     aniState->cckWeakSigThreshold);
	if (aniState->firstepLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
				     aniState->firstepLevel);
	if (ahp->ah_hasHwPhyCounters) {
		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
				     ~ATH9K_RX_FILTER_PHYERR);
		ath9k_ani_restart(ah);
		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);

	} else {
		ath9k_ani_restart(ah);
		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
				     ATH9K_RX_FILTER_PHYERR);
	}
}
Esempio n. 13
0
void ath9k_ani_reset(struct ath_hw *ah)
{
	struct ar5416AniState *aniState;
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);
	int index;

	if (!DO_ANI(ah))
		return;

	index = ath9k_hw_get_ani_channel_idx(ah, chan);
	aniState = &ah->ani[index];
	ah->curani = aniState;

	if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
	    && ah->opmode != NL80211_IFTYPE_ADHOC) {
		ath_print(common, ATH_DBG_ANI,
			  "Reset ANI state opmode %u\n", ah->opmode);
		ah->stats.ast_ani_reset++;

		if (ah->opmode == NL80211_IFTYPE_AP) {
			/*
			 * ath9k_hw_ani_control() will only process items set on
			 * ah->ani_function
			 */
			if (IS_CHAN_2GHZ(chan))
				ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
						    ATH9K_ANI_FIRSTEP_LEVEL);
			else
				ah->ani_function = 0;
		}

		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     !ATH9K_ANI_USE_OFDM_WEAK_SIG);
		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
				     ATH9K_ANI_CCK_WEAK_SIG_THR);

		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
				     ATH9K_RX_FILTER_PHYERR);

		if (ah->opmode == NL80211_IFTYPE_AP) {
			ah->curani->ofdmTrigHigh =
				ah->config.ofdm_trig_high;
			ah->curani->ofdmTrigLow =
				ah->config.ofdm_trig_low;
			ah->curani->cckTrigHigh =
				ah->config.cck_trig_high;
			ah->curani->cckTrigLow =
				ah->config.cck_trig_low;
		}
		ath9k_ani_restart(ah);
		return;
	}

	if (aniState->noiseImmunityLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
				     aniState->noiseImmunityLevel);
	if (aniState->spurImmunityLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
				     aniState->spurImmunityLevel);
	if (aniState->ofdmWeakSigDetectOff)
		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				     !aniState->ofdmWeakSigDetectOff);
	if (aniState->cckWeakSigThreshold)
		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
				     aniState->cckWeakSigThreshold);
	if (aniState->firstepLevel != 0)
		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
				     aniState->firstepLevel);

	ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
			     ~ATH9K_RX_FILTER_PHYERR);
	ath9k_ani_restart(ah);

	ENABLE_REGWRITE_BUFFER(ah);

	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);
	DISABLE_REGWRITE_BUFFER(ah);
}
Esempio n. 14
0
void ath9k_hw_ani_init(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	int i;

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

	if (use_new_ani(ah)) {
		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;

		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
	} else {
		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;

		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
	}

	for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
		struct ath9k_channel *chan = &ah->channels[i];
		struct ar5416AniState *ani = &chan->ani;

		if (use_new_ani(ah)) {
			ani->spurImmunityLevel =
				ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;

			ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;

			if (AR_SREV_9300_20_OR_LATER(ah))
				ani->mrcCCKOff =
					!ATH9K_ANI_ENABLE_MRC_CCK;
			else
				ani->mrcCCKOff = true;

			ani->ofdmsTurn = true;
		} else {
			ani->spurImmunityLevel =
				ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
			ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;

			ani->cckWeakSigThreshold =
				ATH9K_ANI_CCK_WEAK_SIG_THR;
		}

		ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
		ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
		ani->ofdmWeakSigDetectOff =
			!ATH9K_ANI_USE_OFDM_WEAK_SIG;
		ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
		ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
		ani->update_ani = false;
	}

	/*
                                                                        
                                                           
  */
	if (use_new_ani(ah)) {
		ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
		ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
	} else {
		ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
		ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
	}

	if (ah->config.enable_ani)
		ah->proc_phyerr |= HAL_PROCESS_ANI;

	ath9k_ani_restart(ah);
	ath9k_enable_mib_counters(ah);
}
Esempio n. 15
0
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
	struct ar5416AniState *aniState = &ah->curchan->ani;
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);

	if (!DO_ANI(ah))
		return;

	if (!use_new_ani(ah))
		return ath9k_ani_reset_old(ah, is_scanning);

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

	/*                                             */
	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;
	}

	/*                                             */
	ah->ani_function |= ATH9K_ANI_MODE;

	if (is_scanning ||
	    (ah->opmode != NL80211_IFTYPE_STATION &&
	     ah->opmode != NL80211_IFTYPE_ADHOC)) {
		/*
                                                        
                                                           
                                                           
                           
   */
		if (aniState->ofdmNoiseImmunityLevel !=
		    ATH9K_ANI_OFDM_DEF_LEVEL ||
		    aniState->cckNoiseImmunityLevel !=
		    ATH9K_ANI_CCK_DEF_LEVEL) {
			ath_dbg(common, ANI,
				"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);

			aniState->update_ani = false;
			ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
			ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
		}
	} else {
		/*
                                               
   */
		ath_dbg(common, ANI,
			"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);

			aniState->update_ani = true;
			ath9k_hw_set_ofdm_nil(ah,
					      aniState->ofdmNoiseImmunityLevel);
			ath9k_hw_set_cck_nil(ah,
					     aniState->cckNoiseImmunityLevel);
	}

	/*
                                                            
                                         
  */
	ath9k_ani_restart(ah);

	ENABLE_REGWRITE_BUFFER(ah);

	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);
}
Esempio n. 16
0
void ath9k_hw_ani_monitor(struct ath_hal *ah,
			  const struct ath9k_node_stats *stats,
			  struct ath9k_channel *chan)
{
	struct ath_hal_5416 *ahp = AH5416(ah);
	struct ar5416AniState *aniState;
	int32_t listenTime;

	aniState = ahp->ah_curani;
	ahp->ah_stats.ast_nodestats = *stats;

	listenTime = ath9k_hw_ani_get_listen_time(ah);
	if (listenTime < 0) {
		ahp->ah_stats.ast_ani_lneg++;
		ath9k_ani_restart(ah);
		return;
	}

	aniState->listenTime += listenTime;

	if (ahp->ah_hasHwPhyCounters) {
		u32 phyCnt1, phyCnt2;
		u32 ofdmPhyErrCnt, cckPhyErrCnt;

		ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);

		phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
		phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);

		if (phyCnt1 < aniState->ofdmPhyErrBase ||
		    phyCnt2 < aniState->cckPhyErrBase) {
			if (phyCnt1 < aniState->ofdmPhyErrBase) {
				DPRINTF(ah->ah_sc, ATH_DBG_ANI,
					"phyCnt1 0x%x, resetting "
					"counter value to 0x%x\n",
					phyCnt1,
					aniState->ofdmPhyErrBase);
				REG_WRITE(ah, AR_PHY_ERR_1,
					  aniState->ofdmPhyErrBase);
				REG_WRITE(ah, AR_PHY_ERR_MASK_1,
					  AR_PHY_ERR_OFDM_TIMING);
			}
			if (phyCnt2 < aniState->cckPhyErrBase) {
				DPRINTF(ah->ah_sc, ATH_DBG_ANI,
					"phyCnt2 0x%x, resetting "
					"counter value to 0x%x\n",
					phyCnt2,
					aniState->cckPhyErrBase);
				REG_WRITE(ah, AR_PHY_ERR_2,
					  aniState->cckPhyErrBase);
				REG_WRITE(ah, AR_PHY_ERR_MASK_2,
					  AR_PHY_ERR_CCK_TIMING);
			}
			return;
		}

		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
		ahp->ah_stats.ast_ani_ofdmerrs +=
			ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;

		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
		ahp->ah_stats.ast_ani_cckerrs +=
			cckPhyErrCnt - aniState->cckPhyErrCount;
		aniState->cckPhyErrCount = cckPhyErrCnt;
	}

	if (!DO_ANI(ah))
		return;

	if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
		if (aniState->ofdmPhyErrCount <= aniState->listenTime *
		    aniState->ofdmTrigLow / 1000 &&
		    aniState->cckPhyErrCount <= aniState->listenTime *
		    aniState->cckTrigLow / 1000)
			ath9k_hw_ani_lower_immunity(ah);
		ath9k_ani_restart(ah);
	} else if (aniState->listenTime > ahp->ah_aniPeriod) {
		if (aniState->ofdmPhyErrCount > aniState->listenTime *
		    aniState->ofdmTrigHigh / 1000) {
			ath9k_hw_ani_ofdm_err_trigger(ah);
			ath9k_ani_restart(ah);
		} else if (aniState->cckPhyErrCount >
			   aniState->listenTime * aniState->cckTrigHigh /
			   1000) {
			ath9k_hw_ani_cck_err_trigger(ah);
			ath9k_ani_restart(ah);
		}
	}
}
Esempio n. 17
0
File: ani.c Progetto: 03199618/linux
/*
 * 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.
 */
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
	struct ar5416AniState *aniState = &ah->ani;
	struct ath9k_channel *chan = ah->curchan;
	struct ath_common *common = ath9k_hw_common(ah);
	int ofdm_nil, cck_nil;

	if (!ah->curchan)
		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;
	}

	ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
			 aniState->ofdmNoiseImmunityLevel);
	cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
			 aniState->cckNoiseImmunityLevel);

	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) {
			ath_dbg(common, ANI,
				"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);

			ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL;
			cck_nil = ATH9K_ANI_CCK_DEF_LEVEL;
		}
	} else {
		/*
		 * restore historical levels for this channel
		 */
		ath_dbg(common, ANI,
			"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);
	}
	ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
	ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);

	ath9k_ani_restart(ah);
}