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