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

📄 ar5111.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/* Now that we have reprogrammed rfgain value, clear the flag. */	ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;	return AH_TRUE;}/* * Returns interpolated or the scaled up interpolated value */static u_int16_tinterpolate(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight,	u_int16_t targetLeft, u_int16_t targetRight){	u_int16_t rv;	int16_t lRatio;	/* to get an accurate ratio, always scale, if want to scale, then don't scale back down */	if ((targetLeft * targetRight) == 0)		return 0;	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,	u_int16_t *rfXpdGain){	struct ath_hal_5212 *ahp = AH5212(ah);	FULL_PCDAC_STRUCT pcdacStruct;	int i, j;	u_int16_t     *pPcdacValues;	int16_t      *pScaledUpDbm;	int16_t      minScaledPwr;	int16_t      maxScaledPwr;	int16_t      pwr;	u_int16_t     pcdacMin = 0;	u_int16_t     pcdacMax = PCDAC_STOP;	u_int16_t     pcdacTableIndex;	u_int16_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:	case CHANNEL_X:		eepromPcdacs.numChannels     = ahp->ah_numChannels11a;		eepromPcdacs.pChannelList    = ahp->ah_channels11a;		eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11a;		break;	case CHANNEL_B:		eepromPcdacs.numChannels     = ahp->ah_numChannels2_4;		eepromPcdacs.pChannelList    = ahp->ah_channels11b;		eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11b;		break;	case CHANNEL_G:	case CHANNEL_108G:		eepromPcdacs.numChannels     = ahp->ah_numChannels2_4;		eepromPcdacs.pChannelList    = ahp->ah_channels11g;		eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11g;		break;	default:		HALDEBUG(ah, "%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 = (u_int16_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 = (u_int16_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 = (u_int16_t)(interpolate(pwr,			pScaledUpDbm[i], pScaledUpDbm[i + 1],			(u_int16_t)(pPcdacValues[i] * 2),			(u_int16_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 u_int16_tar5212GetScaledPower(u_int16_t channel, u_int16_t pcdacValue, PCDACS_EEPROM *pSrcStruct){	u_int16_t powerValue;	u_int16_t lFreq, rFreq;		/* left and right frequency values */	u_int16_t llPcdac, ulPcdac;	/* lower and upper left pcdac values */	u_int16_t lrPcdac, urPcdac;	/* lower and upper right pcdac values */	u_int16_t lPwr, uPwr;		/* lower and upper temp pwr values */	u_int16_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(u_int16_t channel, u_int16_t pcdacValue,	PCDACS_EEPROM *pSrcStruct, u_int16_t *powerValue){	DATA_PER_CHANNEL *pChannelData = pSrcStruct->pDataPerChannel;	int i;	for (i = 0; i < pSrcStruct->numChannels; i++ ) {		if (pChannelData->channelValue == channel) {			u_int16_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(u_int16_t pcdac, u_int16_t channel,	PCDACS_EEPROM *pSrcStruct,	u_int16_t *pLowerPcdac, u_int16_t *pUpperPcdac){	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);}/* * Free memory for analog bank scratch buffers */static voidar5111Detach(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	if (ahp->ah_pcdacTable != AH_NULL) {		ath_hal_free(ahp->ah_pcdacTable);		ahp->ah_pcdacTable = AH_NULL;	}	if (ahp->ah_analogBanks != AH_NULL) {		ath_hal_free(ahp->ah_analogBanks);		ahp->ah_analogBanks = AH_NULL;	}}static HAL_BOOLar5111GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, u_int32_t nchans){	/* XXX - Get 5111 power limits! */	return AH_TRUE;}/* * Allocate memory for analog bank scratch buffers * Scratch Buffer will be reinitialized every reset so no need to zero now */HAL_BOOLar5111RfAttach(struct ath_hal *ah, HAL_STATUS *status){	struct ath_hal_5212 *ahp = AH5212(ah);	HALASSERT(ahp->ah_analogBanks == AH_NULL);	ahp->ah_analogBanks = ath_hal_malloc(sizeof(AR5212_RF_BANKS_5111));	if (ahp->ah_analogBanks == AH_NULL) {		HALDEBUG(ah, "%s: cannot allocate RF banks\n", __func__);		*status = HAL_ENOMEM;		/* XXX */		return AH_FALSE;	}	HALASSERT(ahp->ah_pcdacTable == AH_NULL);	ahp->ah_pcdacTableSize = PWR_TABLE_SIZE * sizeof(u_int16_t);	ahp->ah_pcdacTable = ath_hal_malloc(ahp->ah_pcdacTableSize);	if (ahp->ah_pcdacTable == AH_NULL) {		HALDEBUG(ah, "%s: cannot allocate PCDAC table\n", __func__);		*status = HAL_ENOMEM;		/* XXX */		return AH_FALSE;	}	ahp->ah_rfHal.rfDetach		= ar5111Detach;	ahp->ah_rfHal.writeRegs		= ar5111WriteRegs;	ahp->ah_rfHal.getRfBank		= ar5111GetRfBank;	ahp->ah_rfHal.setChannel	= ar5111SetChannel;	ahp->ah_rfHal.setRfRegs		= ar5111SetRfRegs;	ahp->ah_rfHal.setPowerTable	= ar5111SetPowerTable;	ahp->ah_rfHal.getChipPowerLim	= ar5111GetChipPowerLimits;	return AH_TRUE;}#endif /* AH_SUPPORT_5111 */

⌨️ 快捷键说明

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