/* * 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 ar5416AniReset(struct ath_hal *ah) { struct ath_hal_5416 *ahp = AH5416(ah); struct ar5416AniState *aniState; HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; HAL_CHANNEL_INTERNAL *ichan = AH_PRIVATE(ah)->ah_curchan; struct ath_hal_private *ap = AH_PRIVATE(ah); int index; HALASSERT(chan != AH_NULL); if (!DO_ANI(ah)) { return; } index = ar5416GetAniChannelIndex(ah, chan); aniState = &ahp->ah_ani[index]; ahp->ah_curani = aniState; aniState->phyNoiseSpur = 0; /* 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 (DO_ANI(ah) && 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++; if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) { if (IS_CHAN_2GHZ(ichan)) ahp->ah_ani_function = (HAL_ANI_SPUR_IMMUNITY_LEVEL | HAL_ANI_FIRSTEP_LEVEL); else ahp->ah_ani_function = 0; } ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0, AH_FALSE); ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0, AH_FALSE); ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0, AH_FALSE); ar5416AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, !HAL_ANI_USE_OFDM_WEAK_SIG, AH_FALSE); ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, HAL_ANI_CCK_WEAK_SIG_THR, AH_FALSE); if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) { ahp->ah_curani->ofdmTrigHigh = ap->ah_config.ath_hal_ofdmTrigHigh; ahp->ah_curani->ofdmTrigLow = ap->ah_config.ath_hal_ofdmTrigLow; ahp->ah_curani->cckTrigHigh = ap->ah_config.ath_hal_cckTrigHigh; ahp->ah_curani->cckTrigLow = ap->ah_config.ath_hal_cckTrigLow; } ar5416AniRestart(ah); } else { if (aniState->noiseImmunityLevel != 0) ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel, AH_FALSE); if (aniState->spurImmunityLevel != 0) ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel,AH_FALSE); if (aniState->ofdmWeakSigDetectOff) ar5416AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, !aniState->ofdmWeakSigDetectOff, AH_FALSE); if (aniState->cckWeakSigThreshold) ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, aniState->cckWeakSigThreshold, AH_FALSE); if (aniState->firstepLevel != 0) ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel, AH_FALSE); } /* * enable phy counters if hw supports or if not, enable phy interrupts * (so we can count each one) */ if (ahp->ah_hasHwPhyCounters) { ar5416SetRxFilter(ah, ar5416GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); ar5416AniRestart(ah); ENABLE_REG_WRITE_BUFFER OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); OS_REG_WRITE_FLUSH(ah); DISABLE_REG_WRITE_BUFFER } else {
/* * 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, 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 = ar5416GetAniChannelIndex(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) { 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); aniState->isSetup = AH_TRUE; } ar5416AniRestart(ah, aniState); /* restore RX filter mask */ ar5212SetRxFilter(ah, rxfilter); }