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

📄 ar5211_reset.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
		(OS_REG_READ(ah, AR_PHY_BASE + (25 << 2)) & 0xFFF80FFF) |		((ee->ee_thresh62[arrayMode] << 12) & 0x7F000));#define NO_FALSE_DETECT_BACKOFF   2#define CB22_FALSE_DETECT_BACKOFF 6	/*	 * False detect backoff - suspected 32 MHz spur causes	 * false detects in OFDM, causing Tx Hangs.  Decrease	 * weak signal sensitivity for this card.	 */	falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;	if (AH_PRIVATE(ah)->ah_eeversion < AR_EEPROM_VER3_3) {		if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&		    IS_CHAN_OFDM(chan))			falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;	} else {		uint32_t remainder = chan->channel % 32;		if (remainder && (remainder < 10 || remainder > 22))			falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];	}	OS_REG_WRITE(ah, 0x9924,		(OS_REG_READ(ah, 0x9924) & 0xFFFFFF01)		| ((falseDectectBackoff << 1) & 0xF7));	return AH_TRUE;#undef NO_FALSE_DETECT_BACKOFF#undef CB22_FALSE_DETECT_BACKOFF}/* * Set the limit on the overall output power.  Used for dynamic * transmit power control and the like. * * NOTE: The power is passed in is in units of 0.5 dBm. */HAL_BOOLar5211SetTxPowerLimit(struct ath_hal *ah, uint32_t limit){	AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, limit);	return AH_TRUE;}/* * Sets the transmit power in the baseband for the given * operating channel and mode. */HAL_BOOLar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan){	HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;	TRGT_POWER_INFO *pi;	RD_EDGES_POWER *rep;	PCDACS_EEPROM eepromPcdacs;	u_int nchan, cfgCtl;	int i;	/* setup the pcdac struct to point to the correct info, based on mode */	switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {	case CHANNEL_A:		eepromPcdacs.numChannels = ee->ee_numChannels11a;		eepromPcdacs.pChannelList= ee->ee_channels11a;		eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11a;		nchan = ee->ee_numTargetPwr_11a;		pi = ee->ee_trgtPwr_11a;		break;	case CHANNEL_OFDM|CHANNEL_2GHZ:		eepromPcdacs.numChannels = ee->ee_numChannels2_4;		eepromPcdacs.pChannelList= ee->ee_channels11g;		eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11g;		nchan = ee->ee_numTargetPwr_11g;		pi = ee->ee_trgtPwr_11g;		break;	case CHANNEL_CCK|CHANNEL_2GHZ:		eepromPcdacs.numChannels = ee->ee_numChannels2_4;		eepromPcdacs.pChannelList= ee->ee_channels11b;		eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11b;		nchan = ee->ee_numTargetPwr_11b;		pi = ee->ee_trgtPwr_11b;		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",		    __func__, chan->channelFlags);		return AH_FALSE;	}	ar5211SetPowerTable(ah, &eepromPcdacs, chan->channel);	rep = AH_NULL;	/* Match CTL to EEPROM value */	cfgCtl = ath_hal_getctl(ah, chan);	for (i = 0; i < ee->ee_numCtls; i++)		if (ee->ee_ctl[i] != 0 && ee->ee_ctl[i] == cfgCtl) {			rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];			break;		}	ar5211SetRateTable(ah, rep, pi, nchan, chan);	return AH_TRUE;}/* * 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. */voidar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct, uint16_t channel){	static FULL_PCDAC_STRUCT pcdacStruct;	static uint16_t pcdacTable[PWR_TABLE_SIZE];	uint16_t	 i, j;	uint16_t	 *pPcdacValues;	int16_t	  *pScaledUpDbm;	int16_t	  minScaledPwr;	int16_t	  maxScaledPwr;	int16_t	  pwr;	uint16_t	 pcdacMin = 0;	uint16_t	 pcdacMax = 63;	uint16_t	 pcdacTableIndex;	uint16_t	 scaledPcdac;	uint32_t	 addr;	uint32_t	 temp32;	OS_MEMZERO(&pcdacStruct, sizeof(FULL_PCDAC_STRUCT));	OS_MEMZERO(pcdacTable, sizeof(uint16_t) * PWR_TABLE_SIZE);	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] = ar5211GetScaledPower(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++)		pcdacTable[pcdacTableIndex++] = pcdacMin;	i = 0;	while (pwr < pScaledUpDbm[pcdacStruct.numPcdacValues - 1]) {		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)(ar5211GetInterpolatedValue(pwr,				pScaledUpDbm[i], pScaledUpDbm[i+1],				(uint16_t)(pPcdacValues[i] * 2),				(uint16_t)(pPcdacValues[i+1] * 2), 0) + 1);		pcdacTable[pcdacTableIndex] = scaledPcdac / 2;		if (pcdacTable[pcdacTableIndex] > pcdacMax)			pcdacTable[pcdacTableIndex] = pcdacMax;		pcdacTableIndex++;	}	/* Write all the last pcdac entries based off the last valid pcdac */	while (pcdacTableIndex < PWR_TABLE_SIZE) {		pcdacTable[pcdacTableIndex] = pcdacTable[pcdacTableIndex - 1];		pcdacTableIndex++;	}	/* Finally, write the power values into the baseband power table */	addr = AR_PHY_BASE + (608 << 2);	for (i = 0; i < 32; i++) {		temp32 = 0xffff & ((pcdacTable[2 * i + 1] << 8) | 0xff);		temp32 = (temp32 << 16) | (0xffff & ((pcdacTable[2 * i] << 8) | 0xff));		OS_REG_WRITE(ah, addr, temp32);		addr += 4;	}}/* * Set the transmit power in the baseband for the given * operating channel and mode. */voidar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,	TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,	HAL_CHANNEL *chan){	HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;	struct ath_hal_5211 *ahp = AH5211(ah);	static uint16_t ratesArray[NUM_RATES];	static const uint16_t tpcScaleReductionTable[5] =		{ 0, 3, 6, 9, MAX_RATE_POWER };	uint16_t	*pRatesPower;	uint16_t	lowerChannel, lowerIndex=0, lowerPower=0;	uint16_t	upperChannel, upperIndex=0, upperPower=0;	uint16_t	twiceMaxEdgePower=63;	uint16_t	twicePower = 0;	uint16_t	i, numEdges;	uint16_t	tempChannelList[NUM_EDGES]; /* temp array for holding edge channels */	uint16_t	twiceMaxRDPower;	int16_t	 scaledPower = 0;		/* for gcc -O2 */	uint16_t	mask = 0x3f;	HAL_BOOL	  paPreDEnable = 0;	int8_t	  twiceAntennaGain, twiceAntennaReduction = 0;	pRatesPower = ratesArray;	twiceMaxRDPower = chan->maxRegTxPower * 2;	if (IS_CHAN_5GHZ(chan)) {		twiceAntennaGain = ee->ee_antennaGainMax[0];	} else {		twiceAntennaGain = ee->ee_antennaGainMax[1];	}	twiceAntennaReduction = ath_hal_getantennareduction(ah, chan, twiceAntennaGain);	if (pRdEdgesPower) {		/* Get the edge power */		for (i = 0; i < NUM_EDGES; i++) {			if (pRdEdgesPower[i].rdEdge == 0)				break;			tempChannelList[i] = pRdEdgesPower[i].rdEdge;		}		numEdges = i;		ar5211GetLowerUpperValues(chan->channel, tempChannelList,			numEdges, &lowerChannel, &upperChannel);		/* Get the index for this channel */		for (i = 0; i < numEdges; i++)			if (lowerChannel == tempChannelList[i])				break;		HALASSERT(i != numEdges);		if ((lowerChannel == upperChannel &&		     lowerChannel == chan->channel) ||		    pRdEdgesPower[i].flag) {			twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;			HALASSERT(twiceMaxEdgePower > 0);		}	}	/* extrapolate the power values for the test Groups */	for (i = 0; i < numChannels; i++)		tempChannelList[i] = pPowerInfo[i].testChannel;	ar5211GetLowerUpperValues(chan->channel, tempChannelList,		numChannels, &lowerChannel, &upperChannel);	/* get the index for the channel */	for (i = 0; i < numChannels; i++) {		if (lowerChannel == tempChannelList[i])			lowerIndex = i;		if (upperChannel == tempChannelList[i]) {			upperIndex = i;			break;		}	}	for (i = 0; i < NUM_RATES; i++) {		if (IS_CHAN_OFDM(chan)) {			/* power for rates 6,9,12,18,24 is all the same */			if (i < 5) {				lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;				upperPower = pPowerInfo[upperIndex].twicePwr6_24;			} else if (i == 5) {				lowerPower = pPowerInfo[lowerIndex].twicePwr36;				upperPower = pPowerInfo[upperIndex].twicePwr36;			} else if (i == 6) {				lowerPower = pPowerInfo[lowerIndex].twicePwr48;				upperPower = pPowerInfo[upperIndex].twicePwr48;			} else if (i == 7) {				lowerPower = pPowerInfo[lowerIndex].twicePwr54;				upperPower = pPowerInfo[upperIndex].twicePwr54;			}		} else {			switch (i) {			case 0:			case 1:				lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;				upperPower = pPowerInfo[upperIndex].twicePwr6_24;				break;			case 2:			case 3:				lowerPower = pPowerInfo[lowerIndex].twicePwr36;				upperPower = pPowerInfo[upperIndex].twicePwr36;				break;			case 4:			case 5:				lowerPower = pPowerInfo[lowerIndex].twicePwr48;				upperPower = pPowerInfo[upperIndex].twicePwr48;				break;			case 6:			case 7:				lowerPower = pPowerInfo[lowerIndex].twicePwr54;				upperPower = pPowerInfo[upperIndex].twicePwr54;				break;			}		}		twicePower = ar5211GetInterpolatedValue(chan->channel,			lowerChannel, upperChannel, lowerPower, upperPower, 0);		/* Reduce power by band edge restrictions */		twicePower = AH_MIN(twicePower, twiceMaxEdgePower);		/*		 * If turbo is set, reduce power to keep power		 * consumption under 2 Watts.  Note that we always do		 * this unless specially configured.  Then we limit		 * power only for non-AP operation.		 */		if (IS_CHAN_TURBO(chan) &&		    AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1#ifdef AH_ENABLE_AP_SUPPORT		    && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP#endif		) {			twicePower = AH_MIN(twicePower, ee->ee_turbo2WMaxPower5);		}		/* Reduce power by max regulatory domain allowed restrictions */		pRatesPower[i] = AH_MIN(twicePower, twiceMaxRDPower - twiceAntennaReduction);		/* Use 6 Mb power level for transmit power scaling reduction */		/* We don't want to reduce higher rates if its not needed */		if (i == 0) {			scaledPower = pRatesPower[0] -				(tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale] * 2);			if (scaledPower < 1)				scaledPower = 1;		}		pRatesPower[i] = AH_MIN(pRatesPower[i], scaledPower);	}	/* Record txPower at Rate 6 for info gathering */	ahp->ah_tx6PowerInHalfDbm = pRatesPower[0];#ifdef AH_DEBUG	HALDEBUG(ah, HAL_DEBUG_RESET,	    "%s: final output power setting %d MHz:\n",	    __func__, chan->channel);	HALDEBUG(ah, HAL_DEBUG_RESET,	    "6 Mb %d dBm, MaxRD: %d dBm, MaxEdge %d dBm\n",	    scaledPower / 2, twiceMaxRDPower / 2, twiceMaxEdgePower / 2);	HALDEBUG(ah, HAL_DEBUG_RESET, "TPC Scale %d dBm - Ant Red %d dBm\n",	    tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale] * 2,	    twiceAntennaReduction / 2);	if (IS_CHAN_TURBO(chan) &&	    AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1)		HALDEBUG(ah, HAL_DEBUG_RESET, "Max Turbo %d dBm\n",		    ee->ee_turbo2WMaxPower5);	HALDEBUG(ah, HAL_DEBUG_RESET,	    "  %2d | %2d | %2d | %2d | %2d | %2d | %2d | %2d dBm\n",	    pRatesPower[0] / 2, pRatesPower[1] / 2, pRatesPower[2] / 2,	    pRatesPower[3] / 2, pRatesPower[4] / 2, pRatesPower[5] / 2,	    pRatesPower[6] / 2, pRatesPower[7] / 2);#endif /* AH_DEBUG */	/* Write the power table into the hardware */	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,		 ((paPreDEnable & 1)<< 30) | ((pRatesPower[3] & mask) << 24) |		 ((paPreDEnable & 1)<< 22) | ((pRatesPower[2] & mask) << 16) |		 ((paPreDEnable & 1)<< 14) | ((pRatesPower[1] & mask) << 8) |		 ((paPreDEnable & 1)<< 6 ) |  (pRatesPower[0] & mask));	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,		 ((paPreDEnable & 1)<< 30) | ((pRatesPower[7] & mask) << 24) |		 ((paPreDEnable & 1)<< 22) | ((pRatesPower[6] & mask) << 16) |		 ((paPreDEnable & 1)<< 14) | ((pRatesPower[5] & mask) << 8) |		 ((paPreDEnable & 1)<< 6 ) |  (pRatesPower[4] & mask));	/* set max power to the power value at rate 6 */	ar5211SetTxPowerLimit(ah, pRatesPower[0]);	AH_PRIVATE(ah)->ah_maxPowerLevel = pRatesPower[0];}/* * Get or interpolate the pcdac value from the calibrated data */uint16_tar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue, const PCDACS_EEPROM *pSrcStruct)

⌨️ 快捷键说明

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