/* * 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 ar5416AniReset(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 = 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 && (ichan->privFlags & CHANNEL_ANI_SETUP)) { ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel); ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel); ar5416AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, !aniState->ofdmWeakSigDetectOff); ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, aniState->cckWeakSigThreshold); ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel); } else { ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0); ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0); ar5416AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, AH_TRUE); ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE); ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0); ichan->privFlags |= CHANNEL_ANI_SETUP; } ar5416AniRestart(ah, aniState); /* restore RX filter mask */ ar5212SetRxFilter(ah, rxfilter); }
/* * Control Adaptive Noise Immunity Parameters */ HAL_BOOL ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) { typedef int TABLE[]; struct ath_hal_5212 *ahp = AH5212(ah); struct ar5212AniState *aniState = ahp->ah_curani; const struct ar5212AniParams *params = aniState->params; OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd); switch (cmd) { case HAL_ANI_NOISE_IMMUNITY_LEVEL: { u_int level = param; if (level >= params->maxNoiseImmunityLevel) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: immunity level out of range (%u > %u)\n", __func__, level, params->maxNoiseImmunityLevel); return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_TOT_DES, params->totalSizeDesired[level]); OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_LOW, params->coarseLow[level]); OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_HIGH, params->coarseHigh[level]); OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, params->firpwr[level]); if (level > aniState->noiseImmunityLevel) ahp->ah_stats.ast_ani_niup++; else if (level < aniState->noiseImmunityLevel) ahp->ah_stats.ast_ani_nidown++; aniState->noiseImmunityLevel = level; break; } case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: { static const TABLE m1ThreshLow = { 127, 50 }; static const TABLE m2ThreshLow = { 127, 40 }; static const TABLE m1Thresh = { 127, 0x4d }; static const TABLE m2Thresh = { 127, 0x40 }; static const TABLE m2CountThr = { 31, 16 }; static const TABLE m2CountThrLow = { 63, 48 }; u_int on = param ? 1 : 0; OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1ThreshLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, m2ThreshLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, m2CountThrLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]); if (on) { OS_REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); } else { OS_REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); } if (on) ahp->ah_stats.ast_ani_ofdmon++; else ahp->ah_stats.ast_ani_ofdmoff++; aniState->ofdmWeakSigDetectOff = !on; break; } case HAL_ANI_CCK_WEAK_SIGNAL_THR: { static const TABLE weakSigThrCck = { 8, 6 }; u_int high = param ? 1 : 0; OS_REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, weakSigThrCck[high]); if (high) ahp->ah_stats.ast_ani_cckhigh++; else ahp->ah_stats.ast_ani_ccklow++; aniState->cckWeakSigThreshold = high; break; } case HAL_ANI_FIRSTEP_LEVEL: { u_int level = param; if (level >= params->maxFirstepLevel) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: firstep level out of range (%u > %u)\n", __func__, level, params->maxFirstepLevel); return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, params->firstep[level]); if (level > aniState->firstepLevel) ahp->ah_stats.ast_ani_stepup++; else if (level < aniState->firstepLevel) ahp->ah_stats.ast_ani_stepdown++; aniState->firstepLevel = level; break; } case HAL_ANI_SPUR_IMMUNITY_LEVEL: { u_int level = param; if (level >= params->maxSpurImmunityLevel) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: spur immunity level out of range (%u > %u)\n", __func__, level, params->maxSpurImmunityLevel); return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]); if (level > aniState->spurImmunityLevel) ahp->ah_stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) ahp->ah_stats.ast_ani_spurdown++; aniState->spurImmunityLevel = level; break; } case HAL_ANI_PRESENT: break; case HAL_ANI_MODE: if (param == 0) { ahp->ah_procPhyErr &= ~HAL_ANI_ENA; /* Turn off HW counters if we have them */ ar5416AniDetach(ah); ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); } else { /* normal/auto mode */ /* don't mess with state if already enabled */ if (ahp->ah_procPhyErr & HAL_ANI_ENA) break; ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); /* Enable MIB Counters */ enableAniMIBCounters(ah, ahp->ah_curani != AH_NULL ? ahp->ah_curani->params: &ahp->ah_aniParams24 /*XXX*/); ahp->ah_procPhyErr |= HAL_ANI_ENA; } break; #ifdef AH_PRIVATE_DIAG case HAL_ANI_PHYERR_RESET: ahp->ah_stats.ast_ani_ofdmerrs = 0; ahp->ah_stats.ast_ani_cckerrs = 0; break; #endif /* AH_PRIVATE_DIAG */ default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid cmd %u\n", __func__, cmd); return AH_FALSE; } return AH_TRUE; }
/* * 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); } }
/* * Control Adaptive Noise Immunity Parameters */ HAL_BOOL ar5212AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) { #define N(a) (sizeof(a)/sizeof(a[0])) typedef int TABLE[]; struct ath_hal_5212 *ahp = AH5212(ah); struct ar5212AniState *aniState = ahp->ah_curani; switch (cmd) { case HAL_ANI_NOISE_IMMUNITY_LEVEL: { u_int level = param; if (level >= N(ahp->ah_totalSizeDesired)) { HALDEBUG(ah, "%s: level out of range (%u > %u)\n", __func__, level, N(ahp->ah_totalSizeDesired)); return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_TOT_DES, ahp->ah_totalSizeDesired[level]); OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_LOW, ahp->ah_coarseLow[level]); OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_HIGH, ahp->ah_coarseHigh[level]); OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, ahp->ah_firpwr[level]); if (level > aniState->noiseImmunityLevel) ahp->ah_stats.ast_ani_niup++; else if (level < aniState->noiseImmunityLevel) ahp->ah_stats.ast_ani_nidown++; aniState->noiseImmunityLevel = level; break; } case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: { const TABLE m1ThreshLow = { 127, 50 }; const TABLE m2ThreshLow = { 127, 40 }; const TABLE m1Thresh = { 127, 0x4d }; const TABLE m2Thresh = { 127, 0x40 }; const TABLE m2CountThr = { 31, 16 }; const TABLE m2CountThrLow = { 63, 48 }; u_int on = param ? 1 : 0; OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1ThreshLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, m2ThreshLow[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, m2CountThrLow[on]); if (on) { OS_REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); } else { OS_REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); } if (!on != aniState->ofdmWeakSigDetectOff) { if (on) ahp->ah_stats.ast_ani_ofdmon++; else ahp->ah_stats.ast_ani_ofdmoff++; aniState->ofdmWeakSigDetectOff = !on; } break; } case HAL_ANI_CCK_WEAK_SIGNAL_THR: { const TABLE weakSigThrCck = { 8, 6 }; u_int high = param ? 1 : 0; OS_REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, weakSigThrCck[high]); if (high != aniState->cckWeakSigThreshold) { if (high) ahp->ah_stats.ast_ani_cckhigh++; else ahp->ah_stats.ast_ani_ccklow++; aniState->cckWeakSigThreshold = high; } break; } case HAL_ANI_FIRSTEP_LEVEL: { const TABLE firstep = { 0, 4, 8 }; u_int level = param; if (level >= N(firstep)) { HALDEBUG(ah, "%s: level out of range (%u > %u)\n", __func__, level, N(firstep)); return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, firstep[level]); if (level > aniState->firstepLevel) ahp->ah_stats.ast_ani_stepup++; else if (level < aniState->firstepLevel) ahp->ah_stats.ast_ani_stepdown++; aniState->firstepLevel = level; break; } case HAL_ANI_SPUR_IMMUNITY_LEVEL: { const TABLE cycpwrThr1 = { 2, 4, 6, 8, 10, 12, 14, 16 }; u_int level = param; if (level >= N(cycpwrThr1)) { HALDEBUG(ah, "%s: level out of range (%u > %u)\n", __func__, level, N(cycpwrThr1)); return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, cycpwrThr1[level]); if (level > aniState->spurImmunityLevel) ahp->ah_stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) ahp->ah_stats.ast_ani_spurdown++; aniState->spurImmunityLevel = level; break; } case HAL_ANI_PRESENT: break; #ifdef AH_PRIVATE_DIAG case HAL_ANI_MODE: if (param == 0) { ahp->ah_procPhyErr &= ~HAL_PROCESS_ANI; /* Turn off HW counters if we have them */ ar5212AniDetach(ah); ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); } else { /* normal/auto mode */ ahp->ah_procPhyErr |= HAL_PROCESS_ANI; if (ahp->ah_hasHwPhyCounters) { ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); } else { ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) | HAL_RX_FILTER_PHYERR); } } break; case HAL_ANI_PHYERR_RESET: ahp->ah_stats.ast_ani_ofdmerrs = 0; ahp->ah_stats.ast_ani_cckerrs = 0; break; #endif /* AH_PRIVATE_DIAG */ default: HALDEBUG(ah, "%s: invalid cmd %u\n", __func__, cmd); return AH_FALSE; } return AH_TRUE; #undef N }
/* * 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); }