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

📄 ar5212_ani.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);		aniState->isSetup = AH_TRUE;	}	ar5212AniRestart(ah, aniState);	/* restore RX filter mask */	ar5212SetRxFilter(ah, rxfilter);}/* * Process a MIB interrupt.  We may potentially be invoked because * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */voidar5212ProcessMibIntr(struct ath_hal *ah, const HAL_NODE_STATS *stats){	struct ath_hal_5212 *ahp = AH5212(ah);	uint32_t phyCnt1, phyCnt2;	HALDEBUG(ah, HAL_DEBUG_ANI, "%s: mibc 0x%x phyCnt1 0x%x phyCnt2 0x%x "	    "filtofdm 0x%x filtcck 0x%x\n",	    __func__, OS_REG_READ(ah, AR_MIBC),	    OS_REG_READ(ah, AR_PHYCNT1), OS_REG_READ(ah, AR_PHYCNT2),	    OS_REG_READ(ah, AR_FILTOFDM), OS_REG_READ(ah, AR_FILTCCK));	/*	 * First order of business is to clear whatever caused	 * the interrupt so we don't keep getting interrupted.	 * We have the usual mib counters that are reset-on-read	 * and the additional counters that appeared starting in	 * Hainan.  We collect the mib counters and explicitly	 * zero additional counters we are not using.  Anything	 * else is reset only if it caused the interrupt.	 */	/* NB: these are not reset-on-read */	phyCnt1 = OS_REG_READ(ah, AR_PHYCNT1);	phyCnt2 = OS_REG_READ(ah, AR_PHYCNT2);	/* not used, always reset them in case they are the cause */	OS_REG_WRITE(ah, AR_FILTOFDM, 0);	OS_REG_WRITE(ah, AR_FILTCCK, 0);	/* Clear the mib counters and save them in the stats */	ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);	ahp->ah_stats.ast_nodestats = *stats;	/*	 * Check for an ani stat hitting the trigger threshold.	 * When this happens we get a MIB interrupt and the top	 * 2 bits of the counter register will be 0b11, hence	 * the mask check of phyCnt?.	 */	if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || 	    ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {		struct ar5212AniState *aniState = ahp->ah_curani;		const struct ar5212AniParams *params = aniState->params;		uint32_t ofdmPhyErrCnt, cckPhyErrCnt;		ofdmPhyErrCnt = phyCnt1 - params->ofdmPhyErrBase;		ahp->ah_stats.ast_ani_ofdmerrs +=			ofdmPhyErrCnt - aniState->ofdmPhyErrCount;		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;		cckPhyErrCnt = phyCnt2 - params->cckPhyErrBase;		ahp->ah_stats.ast_ani_cckerrs +=			cckPhyErrCnt - aniState->cckPhyErrCount;		aniState->cckPhyErrCount = cckPhyErrCnt;		/*		 * NB: figure out which counter triggered.  If both		 * trigger we'll only deal with one as the processing		 * clobbers the error counter so the trigger threshold		 * check will never be true.		 */		if (aniState->ofdmPhyErrCount > params->ofdmTrigHigh)			ar5212AniOfdmErrTrigger(ah);		if (aniState->cckPhyErrCount > params->cckTrigHigh)			ar5212AniCckErrTrigger(ah);		/* NB: always restart to insure the h/w counters are reset */		ar5212AniRestart(ah, aniState);	}}void ar5212AniPhyErrReport(struct ath_hal *ah, const struct ath_rx_status *rs){	struct ath_hal_5212 *ahp = AH5212(ah);	struct ar5212AniState *aniState;	const struct ar5212AniParams *params;	HALASSERT(!ahp->ah_hasHwPhyCounters && rs != AH_NULL);	aniState = ahp->ah_curani;	params = aniState->params;	if (rs->rs_phyerr == HAL_PHYERR_OFDM_TIMING) {		aniState->ofdmPhyErrCount++;		ahp->ah_stats.ast_ani_ofdmerrs++;		if (aniState->ofdmPhyErrCount > params->ofdmTrigHigh) {			ar5212AniOfdmErrTrigger(ah);			ar5212AniRestart(ah, aniState);		}	} else if (rs->rs_phyerr == HAL_PHYERR_CCK_TIMING) {		aniState->cckPhyErrCount++;		ahp->ah_stats.ast_ani_cckerrs++;		if (aniState->cckPhyErrCount > params->cckTrigHigh) {			ar5212AniCckErrTrigger(ah);			ar5212AniRestart(ah, aniState);		}	}}static voidar5212AniLowerImmunity(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;	}}#define CLOCK_RATE 44000	/* XXX use mac_usec or similar *//* convert HW counter values to ms using 11g clock rate, goo9d enough   for 11a and Turbo *//*  * Return an approximation of the time spent ``listening'' by * deducting the cycles spent tx'ing and rx'ing from the total * cycle count since our last call.  A return value <0 indicates * an invalid/inconsistent time. */static int32_tar5212AniGetListenTime(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	struct ar5212AniState *aniState;	uint32_t txFrameCount, rxFrameCount, cycleCount;	int32_t listenTime;	txFrameCount = OS_REG_READ(ah, AR_TFCNT);	rxFrameCount = OS_REG_READ(ah, AR_RFCNT);	cycleCount = OS_REG_READ(ah, AR_CCCNT);	aniState = ahp->ah_curani;	if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {		/*		 * Cycle counter wrap (or initial call); it's not possible		 * to accurately calculate a value because the registers		 * right shift rather than wrap--so punt and return 0.		 */		listenTime = 0;		ahp->ah_stats.ast_ani_lzero++;	} else {		int32_t ccdelta = cycleCount - aniState->cycleCount;		int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;		int32_t tfdelta = txFrameCount - aniState->txFrameCount;		listenTime = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE;	}	aniState->cycleCount = cycleCount;	aniState->txFrameCount = txFrameCount;	aniState->rxFrameCount = rxFrameCount;	return listenTime;}/* * Update ani stats in preparation for listen time processing. */static voidupdateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState){	struct ath_hal_5212 *ahp = AH5212(ah);	const struct ar5212AniParams *params = aniState->params;	uint32_t phyCnt1, phyCnt2;	int32_t ofdmPhyErrCnt, cckPhyErrCnt;	HALASSERT(ahp->ah_hasHwPhyCounters);	/* Clear the mib counters and save them in the stats */	ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);	/* NB: these are not reset-on-read */	phyCnt1 = OS_REG_READ(ah, AR_PHYCNT1);	phyCnt2 = OS_REG_READ(ah, AR_PHYCNT2);	/* NB: these are spec'd to never roll-over */	ofdmPhyErrCnt = phyCnt1 - params->ofdmPhyErrBase;	if (ofdmPhyErrCnt < 0) {		HALDEBUG(ah, HAL_DEBUG_ANI, "OFDM phyErrCnt %d phyCnt1 0x%x\n",		    ofdmPhyErrCnt, phyCnt1);		ofdmPhyErrCnt = AR_PHY_COUNTMAX;	}	ahp->ah_stats.ast_ani_ofdmerrs +=	     ofdmPhyErrCnt - aniState->ofdmPhyErrCount;	aniState->ofdmPhyErrCount = ofdmPhyErrCnt;	cckPhyErrCnt = phyCnt2 - params->cckPhyErrBase;	if (cckPhyErrCnt < 0) {		HALDEBUG(ah, HAL_DEBUG_ANI, "CCK phyErrCnt %d phyCnt2 0x%x\n",		    cckPhyErrCnt, phyCnt2);		cckPhyErrCnt = AR_PHY_COUNTMAX;	}	ahp->ah_stats.ast_ani_cckerrs +=		cckPhyErrCnt - aniState->cckPhyErrCount;	aniState->cckPhyErrCount = cckPhyErrCnt;}/* * Do periodic processing.  This routine is called from the * driver's rx interrupt handler after processing frames. */voidar5212AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,		HAL_CHANNEL *chan){	struct ath_hal_5212 *ahp = AH5212(ah);	struct ar5212AniState *aniState = ahp->ah_curani;	const struct ar5212AniParams *params;	int32_t listenTime;	ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;	/* XXX can aniState be null? */	if (aniState == AH_NULL)		return;	if (!ANI_ENA(ah))		return;	listenTime = ar5212AniGetListenTime(ah);	if (listenTime < 0) {		ahp->ah_stats.ast_ani_lneg++;		/* restart ANI period if listenTime is invalid */		ar5212AniRestart(ah, aniState);	}	/* XXX beware of overflow? */	aniState->listenTime += listenTime;	OS_MARK(ah, AH_MARK_ANI_POLL, aniState->listenTime);	params = aniState->params;	if (aniState->listenTime > 5*params->period) {		/* 		 * Check to see if need to lower immunity if		 * 5 aniPeriods have passed		 */		if (ahp->ah_hasHwPhyCounters)			updateMIBStats(ah, aniState);		if (aniState->ofdmPhyErrCount <= aniState->listenTime *		    params->ofdmTrigLow/1000 &&		    aniState->cckPhyErrCount <= aniState->listenTime *		    params->cckTrigLow/1000)			ar5212AniLowerImmunity(ah);		ar5212AniRestart(ah, aniState);	} else if (aniState->listenTime > params->period) {		if (ahp->ah_hasHwPhyCounters)			updateMIBStats(ah, aniState);		/* check to see if need to raise immunity */		if (aniState->ofdmPhyErrCount > aniState->listenTime *		    params->ofdmTrigHigh / 1000) {			HALDEBUG(ah, HAL_DEBUG_ANI,			    "%s: OFDM err %u listenTime %u\n", __func__,			    aniState->ofdmPhyErrCount, aniState->listenTime);			ar5212AniOfdmErrTrigger(ah);			ar5212AniRestart(ah, aniState);		} else if (aniState->cckPhyErrCount > aniState->listenTime *			   params->cckTrigHigh / 1000) {			HALDEBUG(ah, HAL_DEBUG_ANI,			    "%s: CCK err %u listenTime %u\n", __func__,			    aniState->cckPhyErrCount, aniState->listenTime);			ar5212AniCckErrTrigger(ah);			ar5212AniRestart(ah, aniState);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -