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

📄 ar5111.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
	if (srcRight != srcLeft) {		/*		 * Note the ratio always need to be scaled,		 * since it will be a fraction.		 */		lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft);		if (lRatio < 0) {		    /* Return as Left target if value would be negative */		    rv = targetLeft;		} else if (lRatio > EEP_SCALE) {		    /* Return as Right target if Ratio is greater than 100% (SCALE) */		    rv = targetRight;		} else {			rv = (lRatio * targetRight + (EEP_SCALE - lRatio) *					targetLeft) / EEP_SCALE;		}	} else {		rv = targetLeft;	}	return rv;}/* * Read the transmit power levels from the structures taken from EEPROM * Interpolate read transmit power values for this channel * Organize the transmit power values into a table for writing into the hardware */static HAL_BOOLar5111SetPowerTable(struct ath_hal *ah,	int16_t *pMinPower, int16_t *pMaxPower, HAL_CHANNEL_INTERNAL *chan,	uint16_t *rfXpdGain){	struct ath_hal_5212 *ahp = AH5212(ah);	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;	FULL_PCDAC_STRUCT pcdacStruct;	int i, j;	uint16_t     *pPcdacValues;	int16_t      *pScaledUpDbm;	int16_t      minScaledPwr;	int16_t      maxScaledPwr;	int16_t      pwr;	uint16_t     pcdacMin = 0;	uint16_t     pcdacMax = PCDAC_STOP;	uint16_t     pcdacTableIndex;	uint16_t     scaledPcdac;	PCDACS_EEPROM *pSrcStruct;	PCDACS_EEPROM eepromPcdacs;	/* setup the pcdac struct to point to the correct info, based on mode */	switch (chan->channelFlags & CHANNEL_ALL) {	case CHANNEL_A:	case CHANNEL_T:		eepromPcdacs.numChannels     = ee->ee_numChannels11a;		eepromPcdacs.pChannelList    = ee->ee_channels11a;		eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11a;		break;	case CHANNEL_B:		eepromPcdacs.numChannels     = ee->ee_numChannels2_4;		eepromPcdacs.pChannelList    = ee->ee_channels11b;		eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11b;		break;	case CHANNEL_G:	case CHANNEL_108G:		eepromPcdacs.numChannels     = ee->ee_numChannels2_4;		eepromPcdacs.pChannelList    = ee->ee_channels11g;		eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11g;		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",		    __func__, chan->channelFlags);		return AH_FALSE;	}	pSrcStruct = &eepromPcdacs;	OS_MEMZERO(&pcdacStruct, sizeof(pcdacStruct));	pPcdacValues = pcdacStruct.PcdacValues;	pScaledUpDbm = pcdacStruct.PwrValues;	/* Initialize the pcdacs to dBM structs pcdacs to be 1 to 63 */	for (i = PCDAC_START, j = 0; i <= PCDAC_STOP; i+= PCDAC_STEP, j++)		pPcdacValues[j] = i;	pcdacStruct.numPcdacValues = j;	pcdacStruct.pcdacMin = PCDAC_START;	pcdacStruct.pcdacMax = PCDAC_STOP;	/* Fill out the power values for this channel */	for (j = 0; j < pcdacStruct.numPcdacValues; j++ )		pScaledUpDbm[j] = ar5212GetScaledPower(chan->channel,			pPcdacValues[j], pSrcStruct);	/* Now scale the pcdac values to fit in the 64 entry power table */	minScaledPwr = pScaledUpDbm[0];	maxScaledPwr = pScaledUpDbm[pcdacStruct.numPcdacValues - 1];	/* find minimum and make monotonic */	for (j = 0; j < pcdacStruct.numPcdacValues; j++) {		if (minScaledPwr >= pScaledUpDbm[j]) {			minScaledPwr = pScaledUpDbm[j];			pcdacMin = j;		}		/*		 * Make the full_hsh monotonically increasing otherwise		 * interpolation algorithm will get fooled gotta start		 * working from the top, hence i = 63 - j.		 */		i = (uint16_t)(pcdacStruct.numPcdacValues - 1 - j);		if (i == 0)			break;		if (pScaledUpDbm[i-1] > pScaledUpDbm[i]) {			/*			 * It could be a glitch, so make the power for			 * this pcdac the same as the power from the			 * next highest pcdac.			 */			pScaledUpDbm[i - 1] = pScaledUpDbm[i];		}	}	for (j = 0; j < pcdacStruct.numPcdacValues; j++)		if (maxScaledPwr < pScaledUpDbm[j]) {			maxScaledPwr = pScaledUpDbm[j];			pcdacMax = j;		}	/* Find the first power level with a pcdac */	pwr = (uint16_t)(PWR_STEP *		((minScaledPwr - PWR_MIN + PWR_STEP / 2) / PWR_STEP) + PWR_MIN);	/* Write all the first pcdac entries based off the pcdacMin */	pcdacTableIndex = 0;	for (i = 0; i < (2 * (pwr - PWR_MIN) / EEP_SCALE + 1); i++) {		HALASSERT(pcdacTableIndex < PWR_TABLE_SIZE);		ahp->ah_pcdacTable[pcdacTableIndex++] = pcdacMin;	}	i = 0;	while (pwr < pScaledUpDbm[pcdacStruct.numPcdacValues - 1] &&	    pcdacTableIndex < PWR_TABLE_SIZE) {		pwr += PWR_STEP;		/* stop if dbM > max_power_possible */		while (pwr < pScaledUpDbm[pcdacStruct.numPcdacValues - 1] &&		       (pwr - pScaledUpDbm[i])*(pwr - pScaledUpDbm[i+1]) > 0)			i++;		/* scale by 2 and add 1 to enable round up or down as needed */		scaledPcdac = (uint16_t)(interpolate(pwr,			pScaledUpDbm[i], pScaledUpDbm[i + 1],			(uint16_t)(pPcdacValues[i] * 2),			(uint16_t)(pPcdacValues[i + 1] * 2)) + 1);		HALASSERT(pcdacTableIndex < PWR_TABLE_SIZE);		ahp->ah_pcdacTable[pcdacTableIndex] = scaledPcdac / 2;		if (ahp->ah_pcdacTable[pcdacTableIndex] > pcdacMax)			ahp->ah_pcdacTable[pcdacTableIndex] = pcdacMax;		pcdacTableIndex++;	}	/* Write all the last pcdac entries based off the last valid pcdac */	while (pcdacTableIndex < PWR_TABLE_SIZE) {		ahp->ah_pcdacTable[pcdacTableIndex] =			ahp->ah_pcdacTable[pcdacTableIndex - 1];		pcdacTableIndex++;	}	/* No power table adjustment for 5111 */	ahp->ah_txPowerIndexOffset = 0;	return AH_TRUE;}/* * Get or interpolate the pcdac value from the calibrated data. */static uint16_tar5212GetScaledPower(uint16_t channel, uint16_t pcdacValue,	const PCDACS_EEPROM *pSrcStruct){	uint16_t powerValue;	uint16_t lFreq, rFreq;		/* left and right frequency values */	uint16_t llPcdac, ulPcdac;	/* lower and upper left pcdac values */	uint16_t lrPcdac, urPcdac;	/* lower and upper right pcdac values */	uint16_t lPwr, uPwr;		/* lower and upper temp pwr values */	uint16_t lScaledPwr, rScaledPwr; /* left and right scaled power */	if (ar5212FindValueInList(channel, pcdacValue, pSrcStruct, &powerValue)) {		/* value was copied from srcStruct */		return powerValue;	}	ar5212GetLowerUpperValues(channel,		pSrcStruct->pChannelList, pSrcStruct->numChannels,		&lFreq, &rFreq);	ar5212GetLowerUpperPcdacs(pcdacValue,		lFreq, pSrcStruct, &llPcdac, &ulPcdac);	ar5212GetLowerUpperPcdacs(pcdacValue,		rFreq, pSrcStruct, &lrPcdac, &urPcdac);	/* get the power index for the pcdac value */	ar5212FindValueInList(lFreq, llPcdac, pSrcStruct, &lPwr);	ar5212FindValueInList(lFreq, ulPcdac, pSrcStruct, &uPwr);	lScaledPwr = interpolate(pcdacValue, llPcdac, ulPcdac, lPwr, uPwr);	ar5212FindValueInList(rFreq, lrPcdac, pSrcStruct, &lPwr);	ar5212FindValueInList(rFreq, urPcdac, pSrcStruct, &uPwr);	rScaledPwr = interpolate(pcdacValue, lrPcdac, urPcdac, lPwr, uPwr);	return interpolate(channel, lFreq, rFreq, lScaledPwr, rScaledPwr);}/* * Find the value from the calibrated source data struct */static HAL_BOOLar5212FindValueInList(uint16_t channel, uint16_t pcdacValue,	const PCDACS_EEPROM *pSrcStruct, uint16_t *powerValue){	const DATA_PER_CHANNEL *pChannelData = pSrcStruct->pDataPerChannel;	int i;	for (i = 0; i < pSrcStruct->numChannels; i++ ) {		if (pChannelData->channelValue == channel) {			const uint16_t* pPcdac = pChannelData->PcdacValues;			int j;			for (j = 0; j < pChannelData->numPcdacValues; j++ ) {				if (*pPcdac == pcdacValue) {					*powerValue = pChannelData->PwrValues[j];					return AH_TRUE;				}				pPcdac++;			}		}		pChannelData++;	}	return AH_FALSE;}/* * Get the upper and lower pcdac given the channel and the pcdac * used in the search */static voidar5212GetLowerUpperPcdacs(uint16_t pcdac, uint16_t channel,	const PCDACS_EEPROM *pSrcStruct,	uint16_t *pLowerPcdac, uint16_t *pUpperPcdac){	const DATA_PER_CHANNEL *pChannelData = pSrcStruct->pDataPerChannel;	int i;	/* Find the channel information */	for (i = 0; i < pSrcStruct->numChannels; i++) {		if (pChannelData->channelValue == channel)			break;		pChannelData++;	}	ar5212GetLowerUpperValues(pcdac, pChannelData->PcdacValues,		      pChannelData->numPcdacValues,		      pLowerPcdac, pUpperPcdac);}static HAL_BOOLar5111GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,	int16_t *maxPow, int16_t *minPow){	/* XXX - Get 5111 power limits! */	/* NB: caller will cope */	return AH_FALSE;}/* * Adjust NF based on statistical values for 5GHz frequencies. */static int16_tar5111GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c){	static const struct {		uint16_t freqLow;		int16_t	  adjust;	} adjust5111[] = {		{ 5790,	6 },	/* NB: ordered high -> low */		{ 5730, 4 },		{ 5690, 3 },		{ 5660, 2 },		{ 5610, 1 },		{ 5530, 0 },		{ 5450, 0 },		{ 5379, 1 },		{ 5209, 3 },		{ 3000, 5 },		{    0, 0 },	};	int i;	for (i = 0; c->channel <= adjust5111[i].freqLow; i++)		;	return adjust5111[i].adjust;}/* * Free memory for analog bank scratch buffers */static voidar5111RfDetach(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	HALASSERT(ahp->ah_rfHal != AH_NULL);	ath_hal_free(ahp->ah_rfHal);	ahp->ah_rfHal = AH_NULL;}/* * Allocate memory for analog bank scratch buffers * Scratch Buffer will be reinitialized every reset so no need to zero now */static HAL_BOOLar5111RfAttach(struct ath_hal *ah, HAL_STATUS *status){	struct ath_hal_5212 *ahp = AH5212(ah);	struct ar5111State *priv;	HALASSERT(ah->ah_magic == AR5212_MAGIC);	HALASSERT(ahp->ah_rfHal == AH_NULL);	priv = ath_hal_malloc(sizeof(struct ar5111State));	if (priv == AH_NULL) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: cannot allocate private state\n", __func__);		*status = HAL_ENOMEM;		/* XXX */		return AH_FALSE;	}	priv->base.rfDetach		= ar5111RfDetach;	priv->base.writeRegs		= ar5111WriteRegs;	priv->base.getRfBank		= ar5111GetRfBank;	priv->base.setChannel		= ar5111SetChannel;	priv->base.setRfRegs		= ar5111SetRfRegs;	priv->base.setPowerTable	= ar5111SetPowerTable;	priv->base.getChannelMaxMinPower = ar5111GetChannelMaxMinPower;	priv->base.getNfAdjust		= ar5111GetNfAdjust;	ahp->ah_pcdacTable = priv->pcdacTable;	ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable);	ahp->ah_rfHal = &priv->base;	return AH_TRUE;}static HAL_BOOLar5111Probe(struct ath_hal *ah){	return IS_RAD5111(ah);}AH_RF(RF5111, ar5111Probe, ar5111RfAttach);

⌨️ 快捷键说明

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