⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar5212_ani.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 3 页
字号:
			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 + -