📄 ar5212_ani.c
字号:
aniState->ofdmWeakSigDetectOff = !on; } break; } case HAL_ANI_CCK_WEAK_SIGNAL_THR: { const TABLE weakSigThrCck = { 8, 6 }; u_int high = param ? 1 : 0; printk("%s: HAL_ANI_CCK_WEAK_SIGNAL_THR:%s\n", __func__, high ? "high":"low"); 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; } printk("%s: HAL_ANI_FIRSTEP_LEVEL:%d\n", __func__, level); 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; } printk("%s: HAL_ANI_SPUR_IMMUNITY_LEVEL:%d\n", __func__, level); 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}static voidar5212AniRestart(struct ath_hal *ah){ struct ath_hal_5212 *ahp = AH5212(ah); struct ar5212AniState *aniState; aniState = ahp->ah_curani; aniState->listenTime = 0; if (ahp->ah_hasHwPhyCounters) { if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { aniState->ofdmPhyErrBase = 0; HALDEBUG(ah, "OFDM Trigger is too high for hw counters\n"); } else aniState->ofdmPhyErrBase = AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) { aniState->cckPhyErrBase = 0; HALDEBUG(ah, "CCK Trigger is too high for hw counters\n"); } else aniState->cckPhyErrBase = AR_PHY_COUNTMAX - aniState->cckTrigHigh; HALDEBUG(ah, "%s: Writing ofdmbase=%u cckbase=%u\n", __func__, aniState->ofdmPhyErrBase, aniState->cckPhyErrBase); OS_REG_WRITE(ah, AR_PHYCNT1, aniState->ofdmPhyErrBase); OS_REG_WRITE(ah, AR_PHYCNT2, aniState->cckPhyErrBase); OS_REG_WRITE(ah, AR_PHYCNTMASK1, AR_PHY_ERR_OFDM_TIMING); OS_REG_WRITE(ah, AR_PHYCNTMASK2, AR_PHY_ERR_CCK_TIMING); /* Clear the mib counters and save them in the stats */ ar5212UpdateMibCounters(ah, &ahp->ah_mibStats); } aniState->ofdmPhyErrCount = 0; aniState->cckPhyErrCount = 0; aniState->totalSizeDesired = OS_REG_RMR_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_TOT_DES); aniState->coarseHigh = OS_REG_RMR_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_HIGH); aniState->coarseLow = OS_REG_RMR_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_LOW); aniState->firpwr = OS_REG_RMR_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR);}static voidar5212AniOfdmErrTrigger(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, data_rssi; HALASSERT(chan != AH_NULL); if (!DO_ANI(ah)) return; aniState = ahp->ah_curani; /* First, raise noise immunity level, up to max */ rssi = BEACON_RSSI(ahp); data_rssi = DATA_RSSI(ahp); if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (rssi > STRONG_RSSI || data_rssi > STRONG_RSSI) ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1); if (aniState->noiseImmunityLevel == HAL_NOISE_IMMUNE_MAX){ /* Disable DPDT switch */ ar5212AniControl(ah, HAL_ANT_SW_OPT, 0x3); ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); } return; }#if 0 /* then, raise spur immunity level, up to max */ if (aniState->spurImmunityLevel < aniState->maxSpurImmunity) { ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel + 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(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; } }#endif}static voidar5212AniCckErrTrigger(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, data_rssi; HALASSERT(chan != AH_NULL); if (!DO_ANI(ah)) return; /* first, raise noise immunity level, up to max */ aniState = ahp->ah_curani; rssi = BEACON_RSSI(ahp); data_rssi = DATA_RSSI(ahp); if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (rssi > STRONG_RSSI || data_rssi > STRONG_RSSI) ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1); if (aniState->noiseImmunityLevel == HAL_NOISE_IMMUNE_MAX){ /* Disable DPDT switch */ ar5212AniControl(ah, HAL_ANT_SW_OPT, 0x3); ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); } return; }#if 0 /* 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(ahp); 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); } }#endif}/* * 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. */voidar5212AniReset(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; /* 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) { 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);#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 /* NB: enable phy frames so the driver gets stats */ ar5212SetRxFilter(ah, ar5212GetRxFilter(ah) | HAL_RX_FILTER_PHYERR); ar5212AniRestart(ah); return; } ar5212AniControl(ah, HAL_ANT_SW_OPT, 0x0); if (aniState->noiseImmunityLevel != 0) ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -