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

📄 ar5212_eeprom.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 3 页
字号:
 *     [8..14] --> cck 1L, 2L, 2S, .. 11L, 11S *     [15]    --> XR (all rates get the same power) *   2. powv[ii]  is the pcdac corresponding to ii/2 dBm. */static voidar5212CorrectGainDelta(struct ath_hal *ah, int twiceOfdmCckDelta){#define	N(_a)	(sizeof(_a) / sizeof(_a[0]))	struct ath_hal_5212 *ahp = AH5212(ah);	int16_t ratesIndex[N(ahp->ah_ratesArray)];	u_int16_t ii, jj, iter;	int32_t cckIndex;	int16_t gainDeltaAdjust = ahp->ah_cckOfdmGainDelta;	/* make a local copy of desired powers as initial indices */	OS_MEMCPY(ratesIndex, ahp->ah_ratesArray, sizeof(ratesIndex));	/* fix only the CCK indices */	for (ii = 8; ii < 15; ii++) {		/* apply a gain_delta correction of -15 for CCK */		ratesIndex[ii] -= gainDeltaAdjust;		/* Now check for contention with all ofdm target powers */		jj = 0;		iter = 0;		/* indicates not all ofdm rates checked forcontention yet */		while (jj < 16) {			if (ratesIndex[ii] < 0)				ratesIndex[ii] = 0;			if (jj == 8) {		/* skip CCK rates */				jj = 15;				continue;			}			if (ratesIndex[ii] == ahp->ah_ratesArray[jj]) {				if (ahp->ah_ratesArray[jj] == 0)					ratesIndex[ii]++;				else if (iter > 50) {					/*					 * To avoid pathological case of of					 * dm target powers 0 and 0.5dBm					 */					ratesIndex[ii]++;				} else					ratesIndex[ii]--;				/* check with all rates again */				jj = 0;				iter++;			} else				jj++;		}		if (ratesIndex[ii] >= PWR_TABLE_SIZE)			ratesIndex[ii] = PWR_TABLE_SIZE -1;		cckIndex = ahp->ah_ratesArray[ii] - twiceOfdmCckDelta;		if (cckIndex < 0)			cckIndex = 0;		/* 		 * Validate that the indexes for the powv are not		 * out of bounds. BUG 6694		 */		HALASSERT(cckIndex < PWR_TABLE_SIZE);		HALASSERT(ratesIndex[ii] < PWR_TABLE_SIZE);		ahp->ah_pcdacTable[ratesIndex[ii]] =			ahp->ah_pcdacTable[cckIndex];	}	/* Override rate per power table with new values */	for (ii = 8; ii < 15; ii++)		ahp->ah_ratesArray[ii] = ratesIndex[ii];}#undef N/* * Find the maximum conformance test limit for the given channel and CTL info */static u_int16_tar5212GetMaxEdgePower(u_int16_t channel, RD_EDGES_POWER *pRdEdgesPower){	/* temp array for holding edge channels */	u_int16_t tempChannelList[NUM_EDGES];	u_int16_t clo, chi, twiceMaxEdgePower;	int i, numEdges;	/* Get the edge power */	for (i = 0; i < NUM_EDGES; i++) {		if (pRdEdgesPower[i].rdEdge == 0)			break;		tempChannelList[i] = pRdEdgesPower[i].rdEdge;	}	numEdges = i;	ar5212GetLowerUpperValues(channel, tempChannelList,		numEdges, &clo, &chi);	/* Get the index for the lower channel */	for (i = 0; i < numEdges && clo != tempChannelList[i]; i++)		;	/* Is lower channel ever outside the rdEdge? */	HALASSERT(i != numEdges);	if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) {		/* 		 * If there's an exact channel match or an inband flag set		 * on the lower channel use the given rdEdgePower 		 */		twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;		HALASSERT(twiceMaxEdgePower > 0);	} else		twiceMaxEdgePower = MAX_RATE_POWER;	return twiceMaxEdgePower;}/* * 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;}/* * Return the four rates of target power for the given target power table  * channel, and number of channels */static voidar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,	TRGT_POWER_INFO *powInfo,	u_int16_t numChannels, TRGT_POWER_INFO *pNewPower){	/* temp array for holding target power channels */	u_int16_t tempChannelList[NUM_TEST_FREQUENCIES];	u_int16_t clo, chi, ixlo, ixhi;	int i;	/* Copy the target powers into the temp channel list */	for (i = 0; i < numChannels; i++)		tempChannelList[i] = powInfo[i].testChannel;	ar5212GetLowerUpperValues(chan->channel, tempChannelList,		numChannels, &clo, &chi);	/* Get the indices for the channel */	ixlo = ixhi = 0;	for (i = 0; i < numChannels; i++) {		if (clo == tempChannelList[i]) {			ixlo = i;		}		if (chi == tempChannelList[i]) {			ixhi = i;			break;		}	}	/*	 * Get the lower and upper channels, target powers,	 * and interpolate between them.	 */	pNewPower->twicePwr6_24 = interpolate(chan->channel, clo, chi,		powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);	pNewPower->twicePwr36 = interpolate(chan->channel, clo, chi,		powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);	pNewPower->twicePwr48 = interpolate(chan->channel, clo, chi,		powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);	pNewPower->twicePwr54 = interpolate(chan->channel, clo, chi,		powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);}/* * Search a list for a specified value v that is within * EEP_DELTA of the search values.  Return the closest * values in the list above and below the desired value. * EEP_DELTA is a factional value; everything is scaled * so only integer arithmetic is used. * * NB: the input list is assumed to be sorted in ascending order */voidar5212GetLowerUpperValues(u_int16_t v, u_int16_t *lp, u_int16_t listSize,                          u_int16_t *vlo, u_int16_t *vhi){	u_int32_t target = v * EEP_SCALE;	u_int16_t *ep = lp+listSize;	/*	 * Check first and last elements for out-of-bounds conditions.	 */	if (target < (u_int32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) {		*vlo = *vhi = lp[0];		return;	}	if (target > (u_int32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) {		*vlo = *vhi = ep[-1];		return;	}	/* look for value being near or between 2 values in list */	for (; lp < ep; lp++) {		/*		 * If value is close to the current value of the list		 * then target is not between values, it is one of the values		 */		if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {			*vlo = *vhi = lp[0];			return;		}		/*		 * Look for value being between current value and next value		 * if so return these 2 values		 */		if (target < (u_int32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) {			*vlo = lp[0];			*vhi = lp[1];			return;		}	}}static HAL_BOOLar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, u_int32_t nchans){	struct ath_hal_5212 *ahp = AH5212(ah);	static const u_int16_t tpcScaleReductionTable[5] =		{ 0, 3, 6, 9, MAX_RATE_POWER };	int16_t minPower, maxPower, tpcInDb, powerLimit;	HAL_CHANNEL *chan=AH_NULL;	u_int32_t i;	/* Get Pier table max and min powers */	if (!(*ahp->ah_rfHal.getChipPowerLim)(ah, chans, nchans))		return AH_FALSE;	powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);	if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)		tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];	else		tpcInDb = 0;	for (i=0; i<nchans; i++) {		chan = &chans[i];		if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,					AH_FALSE, &minPower, &maxPower)) {			HALDEBUG(ah,"%s: unable to find max/min power\n",__func__);			return AH_FALSE;		}		if (maxPower < chan->maxTxPower)			chan->maxTxPower= maxPower;		if (minPower < chan->minTxPower)			chan->minTxPower = minPower;	}#ifdef AH_DEBUG	for (i=0; i<nchans; i++) {		ath_hal_printf(ah,"Chan %d: MaxPow = %d MinPow = %d\n",			 chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);	}#endif	return AH_TRUE;}static HAL_BOOLar5212GetEepromCapabilityInfo(struct ath_hal *ah, u_int16_t *capField) {	struct ath_hal_5212 *ahp = AH5212(ah);    	struct ath_hal_private *ahpriv = AH_PRIVATE(ah);    	HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;	u_int16_t	eeval;	u_int32_t	sum,i;		/* Get Reg domain */        if (!ath_hal_eepromRead(ah, AR_EEPROM_REG_DOMAIN, &eeval)) {		HALDEBUG(ah, "%s: cannot read regulator domain from EEPROM\n",			__func__);		return AH_FALSE;        }	ahp->ah_regdomain = eeval;		/* Get RF Silent */	if (!ath_hal_eepromRead(ah, AR_EEPROM_RFSILENT, &ahpriv->ah_rfsilent)) {		HALDEBUG(ah, "%s: unable to read rf_silent from eeprom\n", __func__);		return AH_FALSE;	}		if (ahp->ah_rfKill) {	    		/* NB: enabled by default */		ahpriv->ah_rfkillEnabled = AH_TRUE;		pCap->halRfSilentSupport = AH_TRUE;	}	/* Read the capability EEPROM location */	*capField = 0;	if (ahp->ah_eeversion >= AR_EEPROM_VER5_1 &&	    !ath_hal_eepromRead(ah, AR_EEPROM_CAPABILITIES_OFFSET, capField)) {		HALDEBUG(ah, "%s: unable to read caps from eeprom\n", __func__);		return AH_FALSE;	}	/* Construct wireless mode from EEPROM */	pCap->halWirelessModes = 0;	if (ahp->ah_Amode) {		pCap->halWirelessModes |= HAL_MODE_11A;		if (!ahp->ah_turbo5Disable)			pCap->halWirelessModes |= HAL_MODE_TURBO;	}	if (ahp->ah_Bmode)		pCap->halWirelessModes |= HAL_MODE_11B;	if (ahp->ah_Gmode &&	    ahpriv->ah_subvendorid != AR_SUBVENDOR_ID_NOG) {		pCap->halWirelessModes |= HAL_MODE_11G;		if (!ahp->ah_turbo2Disable)			pCap->halWirelessModes |= HAL_MODE_108G;	}		/* Get MAC Address */	sum = 0;	for (i = 0; i < 3; i++) {		if (!ath_hal_eepromRead(ah, AR_EEPROM_MAC(2-i), &eeval)) {			HALDEBUG(ah, "%s: cannot read EEPROM "				"location %u\n", __func__, i);			return AH_FALSE;		}		sum += eeval;		ahp->ah_macaddr[2*i] = eeval >> 8;		ahp->ah_macaddr[2*i + 1] = eeval & 0xff;	}		if (sum == 0 || sum == 0xffff*3) {		HALDEBUG(ah, "%s: mac address read failed: %s\n",		    __func__, ath_hal_ether_sprintf(ahp->ah_macaddr));		return AH_FALSE;	}	return AH_TRUE;}static HAL_BOOLar5212GetEepromNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,	int16_t *nft){	struct ath_hal_5212 *ahp = AH5212(ah);	switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {	case CHANNEL_A:		*nft = ahp->ah_noiseFloorThresh[headerInfo11A];		break;	case CHANNEL_B:		*nft = ahp->ah_noiseFloorThresh[headerInfo11B];		break;	case CHANNEL_PUREG:		*nft = ahp->ah_noiseFloorThresh[headerInfo11G];		break;	default:		HALDEBUG(ah, "%s: invalid channel flags 0x%x\n",			__func__, chan->channelFlags);		return AH_FALSE;	}	return AH_TRUE;}			  #endif /* AH_SUPPORT_AR5212 */

⌨️ 快捷键说明

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