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

📄 ar5416_cal.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;	/* Cal is assumed not done until explicitly set below */	*isCalDone = AH_FALSE;	HALDEBUG(ah, HAL_DEBUG_PERCAL,	    "%s: %s Calibration, state %d, calValid 0x%x\n",	    __func__, currCal->calData->calName, currCal->calState,	    ichan->calValid);	/* Calibration in progress. */	if (currCal->calState == CAL_RUNNING) {		/* Check to see if it has finished. */		if (!(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_CAL)) {			HALDEBUG(ah, HAL_DEBUG_PERCAL,			    "%s: sample %d of %d finished\n",			    __func__, cal->calSamples,			    currCal->calData->calNumSamples);			/* 			 * Collect measurements for active chains.			 */			currCal->calData->calCollect(ah);			if (++cal->calSamples >= currCal->calData->calNumSamples) {				int i, numChains = 0;				for (i = 0; i < AR5416_MAX_CHAINS; i++) {					if (rxchainmask & (1 << i))						numChains++;				}				/* 				 * Process accumulated data				 */				currCal->calData->calPostProc(ah, numChains);				/* Calibration has finished. */				ichan->calValid |= currCal->calData->calType;				currCal->calState = CAL_DONE;				*isCalDone = AH_TRUE;			} else {				/*				 * Set-up to collect of another sub-sample.				 */				ar5416SetupMeasurement(ah, currCal);			}		}	} else if (!(ichan->calValid & currCal->calData->calType)) {		/* If current cal is marked invalid in channel, kick it off */		ar5416ResetMeasurement(ah, currCal);	}}/* * Internal interface to schedule periodic calibration work. */HAL_BOOLar5416PerCalibrationN(struct ath_hal *ah,  HAL_CHANNEL *chan,	u_int rxchainmask, HAL_BOOL longcal, HAL_BOOL *isCalDone){	struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;	HAL_CAL_LIST *currCal = cal->cal_curr;	HAL_CHANNEL_INTERNAL *ichan;	OS_MARK(ah, AH_MARK_PERCAL, chan->channel);	*isCalDone = AH_TRUE;	/* Invalid channel check */	ichan = ath_hal_checkchannel(ah, chan);	if (ichan == AH_NULL) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: invalid channel %u/0x%x; no mapping\n",		    __func__, chan->channel, chan->channelFlags);		return AH_FALSE;	}	/*	 * For given calibration:	 * 1. Call generic cal routine	 * 2. When this cal is done (isCalDone) if we have more cals waiting	 *    (eg after reset), mask this to upper layers by not propagating	 *    isCalDone if it is set to TRUE.	 *    Instead, change isCalDone to FALSE and setup the waiting cal(s)	 *    to be run.	 */	if (currCal != AH_NULL &&	    (currCal->calState == CAL_RUNNING ||	     currCal->calState == CAL_WAITING)) {		ar5416DoCalibration(ah, ichan, rxchainmask, currCal, isCalDone);		if (*isCalDone == AH_TRUE) {			cal->cal_curr = currCal = currCal->calNext;			if (currCal->calState == CAL_WAITING) {				*isCalDone = AH_FALSE;				ar5416ResetMeasurement(ah, currCal);			}		}	}	/* Do NF cal only at longer intervals */	if (longcal) {		/*		 * Get the value from the previous NF cal		 * and update the history buffer.		 */		ar5416GetNf(ah, ichan);		/* 		 * Load the NF from history buffer of the current channel.		 * NF is slow time-variant, so it is OK to use a		 * historical value.		 */		ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan);		/* start NF calibration, without updating BB NF register*/		ar5416StartNFCal(ah);		if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {			/* report up and clear internal state */			chan->channelFlags |= CHANNEL_CW_INT;			ichan->channelFlags &= ~CHANNEL_CW_INT;		}	}	return AH_TRUE;}/* * Recalibrate the lower PHY chips to account for temperature/environment * changes. */HAL_BOOLar5416PerCalibration(struct ath_hal *ah,  HAL_CHANNEL *chan, HAL_BOOL *isIQdone){	struct ath_hal_5416 *ahp = AH5416(ah);	struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;	HAL_CAL_LIST *curCal = cal->cal_curr;	if (curCal != AH_NULL && curCal->calData->calType == IQ_MISMATCH_CAL) {		return ar5416PerCalibrationN(ah, chan, ahp->ah_rx_chainmask,		    AH_TRUE, isIQdone);	} else {		HAL_BOOL isCalDone;		*isIQdone = AH_FALSE;		return ar5416PerCalibrationN(ah, chan, ahp->ah_rx_chainmask,		    AH_TRUE, &isCalDone);	}}static HAL_BOOLar5416GetEepromNoiseFloorThresh(struct ath_hal *ah,	const HAL_CHANNEL_INTERNAL *chan, int16_t *nft){	switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {	case CHANNEL_A:	case CHANNEL_A_HT20:	case CHANNEL_A_HT40PLUS:	case CHANNEL_A_HT40MINUS:		ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_5, nft);		break;	case CHANNEL_B:	case CHANNEL_G:	case CHANNEL_G_HT20:	case CHANNEL_G_HT40PLUS:	case CHANNEL_G_HT40MINUS:		ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_2, nft);		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: invalid channel flags 0x%x\n",		    __func__, chan->channelFlags);		return AH_FALSE;	}	return AH_TRUE;}static voidar5416StartNFCal(struct ath_hal *ah){	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);}static voidar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan){	static const uint32_t ar5416_cca_regs[] = {		AR_PHY_CCA,		AR_PHY_CH1_CCA,		AR_PHY_CH2_CCA,		AR_PHY_EXT_CCA,		AR_PHY_CH1_EXT_CCA,		AR_PHY_CH2_EXT_CCA	};	struct ar5212NfCalHist *h;	int i, j;	int32_t val;	uint8_t chainmask;	/*	 * Force NF calibration for all chains.	 */	if (AR_SREV_KITE(ah)) {		/* Kite has only one chain */		chainmask = 0x9;	} else if (AR_SREV_MERLIN(ah)) {		/* Merlin has only two chains */		chainmask = 0x1B;	} else {		chainmask = 0x3F;	}	/*	 * Write filtered NF values into maxCCApwr register parameter	 * so we can load below.	 */	h = AH5416(ah)->ah_cal.nfCalHist;	for (i = 0; i < AR5416_NUM_NF_READINGS; i ++)		if (chainmask & (1 << i)) { 			val = OS_REG_READ(ah, ar5416_cca_regs[i]);			val &= 0xFFFFFE00;			val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff);			OS_REG_WRITE(ah, ar5416_cca_regs[i], val);		}	/* Load software filtered NF value into baseband internal minCCApwr variable. */	OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);	OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);	/* Wait for load to complete, should be fast, a few 10s of us. */	for (j = 0; j < 1000; j++) {		if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0)			break;		OS_DELAY(10);	}	/*	 * Restore maxCCAPower register parameter again so that we're not capped	 * by the median we just loaded.  This will be initial (and max) value	 * of next noise floor calibration the baseband does.  	 */	for (i = 0; i < AR5416_NUM_NF_READINGS; i ++)		if (chainmask & (1 << i)) {				val = OS_REG_READ(ah, ar5416_cca_regs[i]);			val &= 0xFFFFFE00;			val |= (((uint32_t)(-50) << 1) & 0x1ff);			OS_REG_WRITE(ah, ar5416_cca_regs[i], val);		}}voidar5416InitNfHistBuff(struct ar5212NfCalHist *h){	int i, j;	for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {		h[i].currIndex = 0;		h[i].privNF = AR5416_CCA_MAX_GOOD_VALUE;		h[i].invalidNFcount = AR512_NF_CAL_HIST_MAX;		for (j = 0; j < AR512_NF_CAL_HIST_MAX; j ++)			h[i].nfCalBuffer[j] = AR5416_CCA_MAX_GOOD_VALUE;	}}/* * Update the noise floor buffer as a ring buffer */static voidar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray){	int i;	for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {		h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];		if (++h[i].currIndex >= AR512_NF_CAL_HIST_MAX)			h[i].currIndex = 0;		if (h[i].invalidNFcount > 0) {			if (nfarray[i] < AR5416_CCA_MIN_BAD_VALUE ||			    nfarray[i] > AR5416_CCA_MAX_HIGH_VALUE) {				h[i].invalidNFcount = AR512_NF_CAL_HIST_MAX;			} else {				h[i].invalidNFcount--;				h[i].privNF = nfarray[i];			}		} else {			h[i].privNF = ar5212GetNfHistMid(h[i].nfCalBuffer);		}	}}   /* * Read the NF and check it against the noise floor threshhold */static int16_tar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan){	int16_t nf, nfThresh;	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: NF didn't complete in calibration window\n", __func__);		nf = 0;	} else {		/* Finished NF cal, check against threshold */		int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 };					/* TODO - enhance for multiple chains and ext ch */		ath_hal_getNoiseFloor(ah, nfarray);		nf = nfarray[0];		if (ar5416GetEepromNoiseFloorThresh(ah, chan, &nfThresh)) {			if (nf > nfThresh) {				HALDEBUG(ah, HAL_DEBUG_ANY,				    "%s: noise floor failed detected; "				    "detected %d, threshold %d\n", __func__,				    nf, nfThresh);				/*				 * NB: Don't discriminate 2.4 vs 5Ghz, if this				 *     happens it indicates a problem regardless				 *     of the band.				 */				chan->channelFlags |= CHANNEL_CW_INT;				nf = 0;			}		} else {			nf = 0;		}		ar5416UpdateNFHistBuff(AH5416(ah)->ah_cal.nfCalHist, nfarray);		chan->rawNoiseFloor = nf;	}	return nf;}

⌨️ 快捷键说明

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