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

📄 ar5211_reset.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 4 页
字号:
	freqIndex = (chan->channelFlags & CHANNEL_2GHZ) ? 2 : 1;	/*	 * TODO: This array mode correspondes with the index used	 *	 during the read.	 * For readability, this should be changed to an enum or #define	 */	switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {	case CHANNEL_A:		if (chan->channel > 4000 && chan->channel < 5260) {			tempOB = ahp->ah_ob1;			tempDB = ahp->ah_db1;		} else if (chan->channel >= 5260 && chan->channel < 5500) {			tempOB = ahp->ah_ob2;			tempDB = ahp->ah_db2;		} else if (chan->channel >= 5500 && chan->channel < 5725) {			tempOB = ahp->ah_ob3;			tempDB = ahp->ah_db3;		} else if (chan->channel >= 5725) {			tempOB = ahp->ah_ob4;			tempDB = ahp->ah_db4;		} else {			/* XXX panic?? */			tempOB = tempDB = 0;		}		rfXpdGain = ahp->ah_xgain[0];		rfPloSel  = ahp->ah_xpd[0];		rfPwdXpd  = !ahp->ah_xpd[0];		ar5211Rf6n7[5][freqIndex]  =			(ar5211Rf6n7[5][freqIndex] & ~0x10000000) |				(ahp->ah_cornerCal.pd84<< 28);		ar5211Rf6n7[6][freqIndex]  =			(ar5211Rf6n7[6][freqIndex] & ~0x04000000) |				(ahp->ah_cornerCal.pd90 << 26);		ar5211Rf6n7[21][freqIndex] =			(ar5211Rf6n7[21][freqIndex] & ~0x08) |				(ahp->ah_cornerCal.gSel << 3);		break;	case CHANNEL_CCK|CHANNEL_2GHZ:		tempOB = ahp->ah_obFor24;		tempDB = ahp->ah_dbFor24;		rfXpdGain = ahp->ah_xgain[1];		rfPloSel  = ahp->ah_xpd[1];		rfPwdXpd  = !ahp->ah_xpd[1];		break;	case CHANNEL_OFDM|CHANNEL_2GHZ:		tempOB = ahp->ah_obFor24g;		tempDB = ahp->ah_dbFor24g;		rfXpdGain = ahp->ah_xgain[2];		rfPloSel  = ahp->ah_xpd[2];		rfPwdXpd  = !ahp->ah_xpd[2];		break;	default:		HALDEBUG(ah, "%s: invalid channel flags 0x%x\n",			__func__, chan->channelFlags);		return AH_FALSE;	}	HALASSERT(1 <= tempOB && tempOB <= 5);	HALASSERT(1 <= tempDB && tempDB <= 5);	/* Set rfXpdGain and rfPwdXpd */	ar5211Rf6n7[11][freqIndex] =  (ar5211Rf6n7[11][freqIndex] & ~0xC0) |		(((ath_hal_reverseBits(rfXpdGain, 4) << 7) | (rfPwdXpd << 6)) & 0xC0);	ar5211Rf6n7[12][freqIndex] =  (ar5211Rf6n7[12][freqIndex] & ~0x07) |		((ath_hal_reverseBits(rfXpdGain, 4) >> 1) & 0x07);	/* Set OB */	ar5211Rf6n7[12][freqIndex] =  (ar5211Rf6n7[12][freqIndex] & ~0x80) |		((ath_hal_reverseBits(tempOB, 3) << 7) & 0x80);	ar5211Rf6n7[13][freqIndex] =  (ar5211Rf6n7[13][freqIndex] & ~0x03) |		((ath_hal_reverseBits(tempOB, 3) >> 1) & 0x03);	/* Set DB */	ar5211Rf6n7[13][freqIndex] =  (ar5211Rf6n7[13][freqIndex] & ~0x1C) |		((ath_hal_reverseBits(tempDB, 3) << 2) & 0x1C);	/* Set rfPloSel */	ar5211Rf6n7[17][freqIndex] =  (ar5211Rf6n7[17][freqIndex] & ~0x08) |		((rfPloSel << 3) & 0x08);	/* Write the Rf registers 6 & 7 */	for (i = 0; i < N(ar5211Rf6n7); i++)		OS_REG_WRITE(ah, ar5211Rf6n7[i][0], ar5211Rf6n7[i][freqIndex]);	/* Now that we have reprogrammed rfgain value, clear the flag. */	ahp->ah_rfgainState = RFGAIN_INACTIVE;	return AH_TRUE;#undef N}/* * Reads EEPROM header info and programs the device for correct operation * given the channel value */static HAL_BOOLar5211SetBoardValues(struct ath_hal *ah, HAL_CHANNEL *chan){	struct ath_hal_5211 *ahp = AH5211(ah);	int arrayMode, falseDectectBackoff;	switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {	case CHANNEL_A:		arrayMode = 0;		OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,			AR_PHY_FRAME_CTL_TX_CLIP, ahp->ah_cornerCal.clip);		break;	case CHANNEL_CCK|CHANNEL_2GHZ:		arrayMode = 1;		break;	case CHANNEL_OFDM|CHANNEL_2GHZ:		arrayMode = 2;		break;	default:		HALDEBUG(ah, "%s: invalid channel flags 0x%x\n",			__func__, chan->channelFlags);		return AH_FALSE;	}	/* Set the antenna register(s) correctly for the chip revision */	if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_OAHU) {		OS_REG_WRITE(ah, AR_PHY(68),			(OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) | 0x3);	} else {		OS_REG_WRITE(ah, AR_PHY(68),			(OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFC06) |			(ahp->ah_antennaControl[0][arrayMode] << 4) | 0x1);		ar5211SetAntennaSwitch(ah, ahp->ah_diversityControl, chan);		/* Set the Noise Floor Thresh on ar5211 devices */		OS_REG_WRITE(ah, AR_PHY_BASE + (90 << 2),			(ahp->ah_noiseFloorThresh[arrayMode] & 0x1FF) | (1<<9));	}	OS_REG_WRITE(ah, AR_PHY_BASE + (17 << 2),		(OS_REG_READ(ah, AR_PHY_BASE + (17 << 2)) & 0xFFFFC07F) |		((ahp->ah_switchSettling[arrayMode] << 7) & 0x3F80));	OS_REG_WRITE(ah, AR_PHY_BASE + (18 << 2),		(OS_REG_READ(ah, AR_PHY_BASE + (18 << 2)) & 0xFFFC0FFF) |		((ahp->ah_txrxAtten[arrayMode] << 12) & 0x3F000));	OS_REG_WRITE(ah, AR_PHY_BASE + (20 << 2),		(OS_REG_READ(ah, AR_PHY_BASE + (20 << 2)) & 0xFFFF0000) |		((ahp->ah_pgaDesiredSize[arrayMode] << 8) & 0xFF00) |		(ahp->ah_adcDesiredSize[arrayMode] & 0x00FF));	OS_REG_WRITE(ah, AR_PHY_BASE + (13 << 2),		(ahp->ah_txEndToXPAOff[arrayMode] << 24) |		(ahp->ah_txEndToXPAOff[arrayMode] << 16) |		(ahp->ah_txFrameToXPAOn[arrayMode] << 8) |		ahp->ah_txFrameToXPAOn[arrayMode]);	OS_REG_WRITE(ah, AR_PHY_BASE + (10 << 2),		(OS_REG_READ(ah, AR_PHY_BASE + (10 << 2)) & 0xFFFF00FF) |		(ahp->ah_txEndToXLNAOn[arrayMode] << 8));	OS_REG_WRITE(ah, AR_PHY_BASE + (25 << 2),		(OS_REG_READ(ah, AR_PHY_BASE + (25 << 2)) & 0xFFF80FFF) |		((ahp->ah_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 (ahp->ah_eeversion < AR_EEPROM_VER3_3) {		if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&		    IS_CHAN_OFDM(chan))			falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;	} else {		u_int32_t remainder = chan->channel % 32;		if (remainder && (remainder < 10 || remainder > 22))			falseDectectBackoff += ahp->ah_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, u_int32_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){	struct ath_hal_5211 *ahp = AH5211(ah);	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 = ahp->ah_numChannels11a;		eepromPcdacs.pChannelList= ahp->ah_channels11a;		eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11a;		nchan = ahp->ah_numTargetPwr_11a;		pi = ahp->ah_trgtPwr_11a;		break;	case CHANNEL_OFDM|CHANNEL_2GHZ:		eepromPcdacs.numChannels = ahp->ah_numChannels2_4;		eepromPcdacs.pChannelList= ahp->ah_channels11g;		eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11g;		nchan = ahp->ah_numTargetPwr_11g;		pi = ahp->ah_trgtPwr_11g;		break;	case CHANNEL_CCK|CHANNEL_2GHZ:		eepromPcdacs.numChannels = ahp->ah_numChannels2_4;		eepromPcdacs.pChannelList= ahp->ah_channels11b;		eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11b;		nchan = ahp->ah_numTargetPwr_11b;		pi = ahp->ah_trgtPwr_11b;		break;	default:		HALDEBUG(ah, "%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 < ahp->ah_numCtls; i++)		if (ahp->ah_ctl[i] != 0 && ahp->ah_ctl[i] == cfgCtl) {			rep = &ahp->ah_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, u_int16_t channel){	static FULL_PCDAC_STRUCT pcdacStruct;	static u_int16_t pcdacTable[PWR_TABLE_SIZE];	u_int16_t	 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 = 63;	u_int16_t	 pcdacTableIndex;	u_int16_t	 scaledPcdac;	u_int32_t	 addr;	u_int32_t	 temp32;	OS_MEMZERO(&pcdacStruct, sizeof(FULL_PCDAC_STRUCT));	OS_MEMZERO(pcdacTable, sizeof(u_int16_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 = (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++)		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 = (u_int16_t)(ar5211GetInterpolatedValue(pwr,				pScaledUpDbm[i], pScaledUpDbm[i+1],				(u_int16_t)(pPcdacValues[i] * 2),				(u_int16_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, u_int16_t numChannels,	HAL_CHANNEL *chan){	struct ath_hal_5211 *ahp = AH5211(ah);	static u_int16_t ratesArray[NUM_RATES];	static const u_int16_t tpcScaleReductionTable[5] =		{ 0, 3, 6, 9, MAX_RATE_POWER };	u_int16_t	*pRatesPower;	u_int16_t	lowerChannel, lowerIndex=0, lowerPower=0;	u_int16_t	upperChannel, upperIndex=0, upperPower=0;	u_int16_t	twiceMaxEdgePower=63;	u_int16_t	twicePower = 0;	u_int16_t	i, numEdges;	u_int16_t	tempChannelList[NUM_EDGES]; /* temp array for holding edge channels */	u_int16_t	twiceMaxRDPower;	int16_t	 scaledPower = 0;		/* for gcc -O2 */	u_int16_t	mask = 0x3f;	HAL_BOOL	  paPreDEnable = 0;	int8_t	  twiceAntennaGain, twiceAntennaReduction = 0;	pRatesPower = ratesArray;	twiceMaxRDPower = chan->maxRegTxPower * 2;	if (IS_CHAN_5GHZ(chan)) {		twiceAntennaGain = ahp->ah_antennaGainMax[0];	} else {		twiceAntennaGain = ahp->ah_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;

⌨️ 快捷键说明

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