Пример #1
0
static void
ar5212AniCckErrTrigger(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
	struct ar5212AniState *aniState;
	const struct ar5212AniParams *params;

	HALASSERT(chan != AH_NULL);

	if (!ANI_ENA(ah))
		return;

	/* first, raise noise immunity level, up to max */
	aniState = ahp->ah_curani;
	params = aniState->params;
	if (aniState->noiseImmunityLevel+1 <= params->maxNoiseImmunityLevel) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "%s: raise NI to %u\n", __func__,
		    aniState->noiseImmunityLevel + 1);
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel + 1);
		return;
	}

	if (ANI_ENA_RSSI(ah)) {
		int32_t rssi = BEACON_RSSI(ahp);
		if (rssi >  params->rssiThrLow) {
			/*
			 * Beacon signal in mid and high range,
			 * raise firstep level.
			 */
			if (aniState->firstepLevel+1 <= params->maxFirstepLevel) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d raise ST %u\n", __func__, rssi,
				    aniState->firstepLevel+1);
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
						 aniState->firstepLevel + 1);
			}
		} else {
			/*
			 * Beacon rssi is low, zero firstep level to maximize
			 * CCK sensitivity in 11b/g mode.
			 */
			/* XXX can optimize */
			if (IEEE80211_IS_CHAN_B(chan) ||
			    IEEE80211_IS_CHAN_G(chan)) {
				if (aniState->firstepLevel > 0) {
					HALDEBUG(ah, HAL_DEBUG_ANI,
					    "%s: rssi %d zero ST (was %u)\n",
					    __func__, rssi,
					    aniState->firstepLevel);
					ar5212AniControl(ah,
					    HAL_ANI_FIRSTEP_LEVEL, 0);
				}
			}
		}
	}
}
Пример #2
0
static void
ar5212AniLowerImmunity(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	struct ar5212AniState *aniState;
	int32_t rssi;
	
	aniState = ahp->ah_curani;
	
	rssi = BEACON_RSSI(ahp);
	if (rssi > aniState->rssiThrHigh) {
		/* 
		 * Beacon signal is high, leave ofdm weak signal detection off
		 * or it may oscillate. Let it fall through.
		 */
	} else if (rssi > aniState->rssiThrLow) {
		/*
		 * Beacon rssi in mid range, turn on ofdm weak signal
		 * detection or lower first step level.
		 */
		if (aniState->ofdmWeakSigDetectOff) {
			ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
					 AH_TRUE);
			return;
		}
		if (aniState->firstepLevel > 0) {
			ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
					 aniState->firstepLevel - 1);
			return;
		}
	} else {
		/*
		 * Beacon rssi is low, reduce first step level.
		 */
		if (aniState->firstepLevel > 0) {
			ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
					 aniState->firstepLevel - 1);
			return;
		}
	}
	/* then lower spur immunity level, down to zero */
	if (aniState->spurImmunityLevel > 0) {
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel - 1);
		return;
	}
	/* 
	 * if all else fails, lower noise immunity level down to a min value
	 * zero for now
	 */
	if (aniState->noiseImmunityLevel > 0) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel - 1);
		return;
	}
}
Пример #3
0
static void
ar5212AniCckErrTrigger(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
	struct ar5212AniState *aniState;
	WIRELESS_MODE mode;
	int32_t rssi;

	HALASSERT(chan != AH_NULL);

	if (!DO_ANI(ah))
		return;

	/* first, raise noise immunity level, up to max */
	aniState = ahp->ah_curani;
	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel + 1);
		return;
	}
	/* Do not play with OFDM and CCK weak detection in AP mode */
        if( AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
		return;
	}
	rssi = BEACON_RSSI(aniState);
	if (rssi >  aniState->rssiThrLow) {
		/*
		 * Beacon signal in mid and high range, raise firsteplevel.
		 */
		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
			ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
					 aniState->firstepLevel + 1);
	} else {
		/*
		 * Beacon rssi is low, zero firstepLevel to maximize
		 * CCK sensitivity.
		 */
		mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) chan);
		if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
			if (aniState->firstepLevel > 0)
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
		}
	}
}
Пример #4
0
HAL_BOOL
ar5212AniSetParams(struct ath_hal *ah, const struct ar5212AniParams *params24,
	const struct ar5212AniParams *params5)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	HAL_BOOL ena = (ahp->ah_procPhyErr & HAL_ANI_ENA) != 0;

	ar5212AniControl(ah, HAL_ANI_MODE, AH_FALSE);

	OS_MEMCPY(&ahp->ah_aniParams24, params24, sizeof(*params24));
	setPhyErrBase(ah, &ahp->ah_aniParams24);
	OS_MEMCPY(&ahp->ah_aniParams5, params5, sizeof(*params5));
	setPhyErrBase(ah, &ahp->ah_aniParams5);

	OS_MEMZERO(ahp->ah_ani, sizeof(ahp->ah_ani));
	ar5212AniReset(ah, AH_PRIVATE(ah)->ah_curchan,
	    AH_PRIVATE(ah)->ah_opmode, AH_FALSE);

	ar5212AniControl(ah, HAL_ANI_MODE, ena);

	return AH_TRUE;
}
Пример #5
0
static void
ar5212AniLowerImmunity(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	struct ar5212AniState *aniState;
	const struct ar5212AniParams *params;
	
	HALASSERT(ANI_ENA(ah));

	aniState = ahp->ah_curani;
	params = aniState->params;
	if (ANI_ENA_RSSI(ah)) {
		int32_t rssi = BEACON_RSSI(ahp);
		if (rssi > params->rssiThrHigh) {
			/* 
			 * Beacon signal is high, leave ofdm weak signal
			 * detection off or it may oscillate.  Let it fall
			 * through.
			 */
		} else if (rssi > params->rssiThrLow) {
			/*
			 * Beacon rssi in mid range, turn on ofdm weak signal
			 * detection or lower firstep level.
			 */
			if (aniState->ofdmWeakSigDetectOff) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d OWSD on\n", __func__, rssi);
				ar5212AniControl(ah,
				    HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				    AH_TRUE);
				return;
			}
			if (aniState->firstepLevel > 0) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d lower ST %u\n", __func__, rssi,
				    aniState->firstepLevel-1);
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
						 aniState->firstepLevel - 1);
				return;
			}
		} else {
			/*
			 * Beacon rssi is low, reduce firstep level.
			 */
			if (aniState->firstepLevel > 0) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d lower ST %u\n", __func__, rssi,
				    aniState->firstepLevel-1);
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
						 aniState->firstepLevel - 1);
				return;
			}
		}
	}
	/* then lower spur immunity level, down to zero */
	if (aniState->spurImmunityLevel > 0) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "%s: lower SI %u\n",
		    __func__, aniState->spurImmunityLevel-1);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel - 1);
		return;
	}
	/* 
	 * if all else fails, lower noise immunity level down to a min value
	 * zero for now
	 */
	if (aniState->noiseImmunityLevel > 0) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "%s: lower NI %u\n",
		    __func__, aniState->noiseImmunityLevel-1);
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel - 1);
		return;
	}
}
Пример #6
0
/*
 * Restore/reset the ANI parameters and reset the statistics.
 * This routine must be called for every channel change.
 */
void
ar5212AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
	HAL_OPMODE opmode, int restore)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
	/* XXX bounds check ic_devdata */
	struct ar5212AniState *aniState = &ahp->ah_ani[chan->ic_devdata];
	uint32_t rxfilter;

	if ((ichan->privFlags & CHANNEL_ANI_INIT) == 0) {
		OS_MEMZERO(aniState, sizeof(*aniState));
		if (IEEE80211_IS_CHAN_2GHZ(chan))
			aniState->params = &ahp->ah_aniParams24;
		else
			aniState->params = &ahp->ah_aniParams5;
		ichan->privFlags |= CHANNEL_ANI_INIT;
		HALASSERT((ichan->privFlags & CHANNEL_ANI_SETUP) == 0);
	}
	ahp->ah_curani = aniState;
#if 0
	ath_hal_printf(ah,"%s: chan %u/0x%x restore %d opmode %u%s\n",
	    __func__, chan->ic_freq, chan->ic_flags, restore, opmode,
	    ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#else
	HALDEBUG(ah, HAL_DEBUG_ANI, "%s: chan %u/0x%x restore %d opmode %u%s\n",
	    __func__, chan->ic_freq, chan->ic_flags, restore, opmode,
	    ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#endif
	OS_MARK(ah, AH_MARK_ANI_RESET, opmode);

	/*
	 * Turn off PHY error frame delivery while we futz with settings.
	 */
	rxfilter = ah->ah_getRxFilter(ah);
	ah->ah_setRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR);

	/*
	 * If ANI is disabled at this point, don't set the default
	 * ANI parameter settings - leave the HAL settings there.
	 * This is (currently) needed for reliable radar detection.
	 */
	if (! ANI_ENA(ah)) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "%s: ANI disabled\n",
		    __func__);
		goto finish;
	}

	/*
	 * Automatic processing is done only in station mode right now.
	 */
	if (opmode == HAL_M_STA)
		ahp->ah_procPhyErr |= HAL_RSSI_ANI_ENA;
	else
		ahp->ah_procPhyErr &= ~HAL_RSSI_ANI_ENA;
	/*
	 * Set all ani parameters.  We either set them to initial
	 * values or restore the previous ones for the channel.
	 * XXX if ANI follows hardware, we don't care what mode we're
	 * XXX in, we should keep the ani parameters
	 */
	if (restore && (ichan->privFlags & CHANNEL_ANI_SETUP)) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				 !aniState->ofdmWeakSigDetectOff);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
				 aniState->cckWeakSigThreshold);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
				 aniState->firstepLevel);
	} else {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
			AH_TRUE);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
		ichan->privFlags |= CHANNEL_ANI_SETUP;
	}
	/*
	 * In case the counters haven't yet been setup; set them up.
	 */
	enableAniMIBCounters(ah, ahp->ah_curani->params);
	ar5212AniRestart(ah, aniState);

finish:
	/* restore RX filter mask */
	ah->ah_setRxFilter(ah, rxfilter);
}
Пример #7
0
static void
ar5212AniOfdmErrTrigger(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
	struct ar5212AniState *aniState;
	const struct ar5212AniParams *params;

	HALASSERT(chan != AH_NULL);

	if (!ANI_ENA(ah))
		return;

	aniState = ahp->ah_curani;
	params = aniState->params;
	/* First, raise noise immunity level, up to max */
	if (aniState->noiseImmunityLevel+1 <= params->maxNoiseImmunityLevel) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "%s: raise NI to %u\n", __func__,
		    aniState->noiseImmunityLevel + 1);
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 
				 aniState->noiseImmunityLevel + 1);
		return;
	}
	/* then, raise spur immunity level, up to max */
	if (aniState->spurImmunityLevel+1 <= params->maxSpurImmunityLevel) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "%s: raise SI to %u\n", __func__,
		    aniState->spurImmunityLevel + 1);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel + 1);
		return;
	}

	if (ANI_ENA_RSSI(ah)) {
		int32_t rssi = BEACON_RSSI(ahp);
		if (rssi > params->rssiThrHigh) {
			/*
			 * Beacon rssi is high, can turn off ofdm
			 * weak sig detect.
			 */
			if (!aniState->ofdmWeakSigDetectOff) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d OWSD off\n", __func__, rssi);
				ar5212AniControl(ah,
				    HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				    AH_FALSE);
				ar5212AniControl(ah,
				    HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
				return;
			}
			/* 
			 * If weak sig detect is already off, as last resort,
			 * raise firstep level 
			 */
			if (aniState->firstepLevel+1 <= params->maxFirstepLevel) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d raise ST %u\n", __func__, rssi,
				    aniState->firstepLevel+1);
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
						 aniState->firstepLevel + 1);
				return;
			}
		} else if (rssi > params->rssiThrLow) {
			/* 
			 * Beacon rssi in mid range, need ofdm weak signal
			 * detect, but we can raise firststepLevel.
			 */
			if (aniState->ofdmWeakSigDetectOff) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d OWSD on\n", __func__, rssi);
				ar5212AniControl(ah,
				    HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				    AH_TRUE);
			}
			if (aniState->firstepLevel+1 <= params->maxFirstepLevel) {
				HALDEBUG(ah, HAL_DEBUG_ANI,
				    "%s: rssi %d raise ST %u\n", __func__, rssi,
				    aniState->firstepLevel+1);
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
				     aniState->firstepLevel + 1);
			}
			return;
		} else {
			/* 
			 * Beacon rssi is low, if in 11b/g mode, turn off ofdm
			 * weak signal detection and zero firstepLevel to
			 * maximize CCK sensitivity 
			 */
			if (IEEE80211_IS_CHAN_CCK(chan)) {
				if (!aniState->ofdmWeakSigDetectOff) {
					HALDEBUG(ah, HAL_DEBUG_ANI,
					    "%s: rssi %d OWSD off\n",
					    __func__, rssi);
					ar5212AniControl(ah,
					    HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
					    AH_FALSE);
				}
				if (aniState->firstepLevel > 0) {
					HALDEBUG(ah, HAL_DEBUG_ANI,
					    "%s: rssi %d zero ST (was %u)\n",
					    __func__, rssi,
					    aniState->firstepLevel);
					ar5212AniControl(ah,
					     HAL_ANI_FIRSTEP_LEVEL, 0);
				}
				return;
			}
		}
	}
}
Пример #8
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.  NOTE: This must be called for every channel
 * change for ah_curani to be set correctly.
 */
void
ar5212AniReset(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	struct ar5212AniState *aniState;
	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
	int index;

	HALASSERT(chan != AH_NULL);

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

	/*
	 * ANI is enabled but we're not operating in station
	 * mode.  Reset all parameters.  This can happen, for
	 * example, when starting up AP operation.
	 */
	if (DO_ANI(ah) && AH_PRIVATE(ah)->ah_opmode != HAL_M_STA) {
		HALDEBUG(ah,"%s: Reset ANI state opmode %u\n",
			__func__, AH_PRIVATE(ah)->ah_opmode);
		ahp->ah_stats.ast_ani_reset++;
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
			!HAL_ANI_USE_OFDM_WEAK_SIG);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
			HAL_ANI_CCK_WEAK_SIG_THR);
		/* NB: enable phy frames so the driver gets stats */
		ar5212SetRxFilter(ah,
			ar5212GetRxFilter(ah) | HAL_RX_FILTER_PHYERR);
		ar5212AniRestart(ah);
		return;
	}

	if (aniState->noiseImmunityLevel != 0)
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel);
	if (aniState->spurImmunityLevel != 0)
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel);
	if (aniState->ofdmWeakSigDetectOff)
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				 !aniState->ofdmWeakSigDetectOff);
	if (aniState->cckWeakSigThreshold)
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
				 aniState->cckWeakSigThreshold);
	if (aniState->firstepLevel != 0)
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel);
	if (ahp->ah_hasHwPhyCounters) {
		ar5212SetRxFilter(ah,
			  ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR);
		ar5212AniRestart(ah);
		OS_REG_WRITE(ah, AR_PHYCNTMASK1, AR_PHY_ERR_OFDM_TIMING);
		OS_REG_WRITE(ah, AR_PHYCNTMASK2, AR_PHY_ERR_CCK_TIMING);

	} else {
		ar5212AniRestart(ah);
		ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) | HAL_RX_FILTER_PHYERR);
	}
}
Пример #9
0
static void
ar5212AniOfdmErrTrigger(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
	struct ar5212AniState *aniState;
	WIRELESS_MODE mode;
	int32_t rssi;

	HALASSERT(chan != AH_NULL);

	if (!DO_ANI(ah) || AH_PRIVATE(ah)->ah_opmode != HAL_M_STA)
		return;

	aniState = ahp->ah_curani;
	/* First, raise noise immunity level, up to max */
	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 
				 aniState->noiseImmunityLevel + 1);
		return;
	}
	/* then, raise spur immunity level, up to max */
	if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel + 1);
		return;
	}
	rssi = BEACON_RSSI(ahp);
	if (rssi > aniState->rssiThrHigh) {
		/*
		 * Beacon rssi is high, can turn off ofdm weak sig detect.
		 */
		if (!aniState->ofdmWeakSigDetectOff) {
			ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
					 AH_FALSE);
			ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
			return;
		}
		/* 
		 * If weak sig detect is already off, as last resort, raise
		 * first step level 
		 */
		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
			ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
					 aniState->firstepLevel + 1);
			return;
		}
	} else if (rssi > aniState->rssiThrLow) {
		/* 
		 * Beacon rssi in mid range, need ofdm weak signal detect,
		 * but we can raise firststepLevel 
		 */
		if (aniState->ofdmWeakSigDetectOff)
			ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
					 AH_TRUE);
		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
			ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
					 aniState->firstepLevel + 1);
		return;
	} else {
		/* 
		 * Beacon rssi is low, if in 11b/g mode, turn off ofdm
		 * weak sign detction and zero firstepLevel to maximize
		 * CCK sensitivity 
		 */
		mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) chan);
		if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
			if (!aniState->ofdmWeakSigDetectOff)
				ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
						 AH_FALSE);
			if (aniState->firstepLevel > 0)
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
			return;
		}
	}
}
Пример #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.  NOTE: This must be called for every channel
 * change for ah_curani to be set correctly.
 */
void
ar5212AniReset(struct ath_hal *ah, int isRestore)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	struct ar5212AniState *aniState;
	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
	int index;

	HALASSERT(chan != AH_NULL);

	if (!(DO_ANI(ah))) {
		return;
	}

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

	/* If ANI follows hardware, we don't care what mode we're
	   in, we should keep the ani parameters */
	/*
	 * ANI is enabled but we're not operating in station
	 * mode.  Reset all parameters.  This can happen, for
	 * example, when starting up AP operation.
	 */
	if (AH_PRIVATE(ah)->ah_opmode != HAL_M_STA &&
	    AH_PRIVATE(ah)->ah_opmode != HAL_M_IBSS) {
		HDPRINTF(ah, HAL_DBG_ANI, "%s: Reset ANI state opmode %u\n",
			     __func__, AH_PRIVATE(ah)->ah_opmode);
		ahp->ah_stats.ast_ani_reset++;
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
#ifdef notyet
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
			!HAL_ANI_USE_OFDM_WEAK_SIG);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
			HAL_ANI_CCK_WEAK_SIG_THR);
#endif
		ar5212AniRestart(ah);
		return;
	}

	if (isRestore) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				 !aniState->ofdmWeakSigDetectOff);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
				 aniState->cckWeakSigThreshold);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel);
	}
	else {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 4);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 7);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,1);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,1);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 2);
	}

	if (ahp->ah_hasHwPhyCounters) {
		ar5212SetRxFilter(ah,
			  ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR);
		ar5212AniRestart(ah);
		OS_REG_WRITE(ah, AR_PHYCNTMASK1, AR_PHY_ERR_OFDM_TIMING);
		OS_REG_WRITE(ah, AR_PHYCNTMASK2, AR_PHY_ERR_CCK_TIMING);

	} else {
		ar5212AniRestart(ah);
		ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) | HAL_RX_FILTER_PHYERR);
	}
}
/*
 * Restore/reset the ANI parameters and reset the statistics.
 * This routine must be called for every channel change.
 *
 * NOTE: This is where ah_curani is set; other ani code assumes
 *       it is setup to reflect the current channel.
 */
void
ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
	HAL_OPMODE opmode, int restore)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	struct ar5212AniState *aniState;
	uint32_t rxfilter;
	int index;

	index = ar5212GetAniChannelIndex(ah, chan);
	aniState = &ahp->ah_ani[index];
	ahp->ah_curani = aniState;
#if 0
	ath_hal_printf(ah,"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
	    __func__, chan->channel, chan->channelFlags, restore,
	    aniState->isSetup, opmode);
#else
	HALDEBUG(ah, HAL_DEBUG_ANI,
	    "%s: chan %u/0x%x restore %d setup %d opmode %u\n",
	    __func__, chan->channel, chan->channelFlags, restore,
	    aniState->isSetup, opmode);
#endif
	OS_MARK(ah, AH_MARK_ANI_RESET, opmode);

	/*
	 * Turn off PHY error frame delivery while we futz with settings.
	 */
	rxfilter = ar5212GetRxFilter(ah);
	ar5212SetRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR);
	/*
	 * Automatic processing is done only in station mode right now.
	 */
	if (opmode == HAL_M_STA)
		ahp->ah_procPhyErr |= HAL_RSSI_ANI_ENA;
	else
		ahp->ah_procPhyErr &= ~HAL_RSSI_ANI_ENA;
	/*
	 * Set all ani parameters.  We either set them to initial
	 * values or restore the previous ones for the channel.
	 * XXX if ANI follows hardware, we don't care what mode we're
	 * XXX in, we should keep the ani parameters
	 */
	if (restore && aniState->isSetup) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
				 aniState->spurImmunityLevel);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
				 !aniState->ofdmWeakSigDetectOff);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
				 aniState->cckWeakSigThreshold);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
				 aniState->firstepLevel);
	} else {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
			AH_TRUE);
		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
		aniState->isSetup = AH_TRUE;
	}
	ar5212AniRestart(ah, aniState);

	/* restore RX filter mask */
	ar5212SetRxFilter(ah, rxfilter);
}