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

📄 ar5212_reset.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 5 页
字号:
HAL_BOOLar5212SetTxPowerLimit(struct ath_hal *ah, u_int32_t limit){	u_int16_t dummyXpdGains[2];	AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);	return AH_PRIVATE(ah)->ah_setTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan,			dummyXpdGains);}static const GAIN_OPTIMIZATION_LADDER gainLadder = {	9,					/* numStepsInLadder */	4,					/* defaultStepNum */	{ { {4, 1, 1, 1},  6, "FG8"},	  { {4, 0, 1, 1},  4, "FG7"},	  { {3, 1, 1, 1},  3, "FG6"},	  { {4, 0, 0, 1},  1, "FG5"},	  { {4, 1, 1, 0},  0, "FG4"},	/* noJack */	  { {4, 0, 1, 0}, -2, "FG3"},	/* halfJack */	  { {3, 1, 1, 0}, -3, "FG2"},	/* clip3 */	  { {4, 0, 0, 0}, -4, "FG1"},	/* noJack */	  { {2, 1, 1, 0}, -6, "FG0"} 	/* clip2 */	}};const static GAIN_OPTIMIZATION_LADDER gainLadder5112 = {	8,					/* numStepsInLadder */	1,					/* defaultStepNum */	{ { {3, 0,0,0, 0,0,0},   6, "FG7"},	/* most fixed gain */	  { {2, 0,0,0, 0,0,0},   0, "FG6"},	  { {1, 0,0,0, 0,0,0},  -3, "FG5"},	  { {0, 0,0,0, 0,0,0},  -6, "FG4"},	  { {0, 1,1,0, 0,0,0},  -8, "FG3"},	  { {0, 1,1,0, 1,1,0}, -10, "FG2"},	  { {0, 1,0,1, 1,1,0}, -13, "FG1"},	  { {0, 1,0,1, 1,0,1}, -16, "FG0"},	/* least fixed gain */	}};/* * Initialize the gain structure to good values */voidar5212InitializeGainValues(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	GAIN_VALUES *gv = &ahp->ah_gainValues;	/* initialize gain optimization values */	if (IS_5112(ah)) {		gv->currStepNum = gainLadder5112.defaultStepNum;		gv->currStep =			&gainLadder5112.optStep[gainLadder5112.defaultStepNum];		gv->active = AH_TRUE;		gv->loTrig = 20;		gv->hiTrig = 85;	} else {		gv->currStepNum = gainLadder.defaultStepNum;		gv->currStep = &gainLadder.optStep[gainLadder.defaultStepNum];		gv->active = AH_TRUE;		gv->loTrig = 20;		gv->hiTrig = 35;	}}static HAL_BOOLar5212InvalidGainReadback(struct ath_hal *ah, GAIN_VALUES *gv){	u_int32_t gStep, g, mixOvr;	u_int32_t L1, L2, L3, L4;	if (IS_5112(ah)) {		mixOvr = ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0);		L1 = 0;		L2 = 107;		L3 = 0;		L4 = 107;		if (mixOvr == 1) {			L2 = 83;			L4 = 83;			gv->hiTrig = 55;		}	} else {		gStep = ar5212GetRfField(ar5212GetRfBank(ah, 7), 6, 37, 0);		L1 = 0;		L2 = (gStep == 0x3f) ? 50 : gStep + 4;		L3 = (gStep != 0x3f) ? 0x40 : L1;		L4 = L3 + 50;		gv->loTrig = L1 + (gStep == 0x3f ? DYN_ADJ_LO_MARGIN : 0);		/* never adjust if != 0x3f */		gv->hiTrig = L4 - (gStep == 0x3f ? DYN_ADJ_UP_MARGIN : -5);	}	g = gv->currGain;	return !((g >= L1 && g<= L2) || (g >= L3 && g <= L4));}/* * Enable the probe gain check on the next packet */static voidar5212RequestRfgain(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	u_int32_t probePowerIndex;	/* Enable the gain readback probe */	probePowerIndex = ahp->ah_ofdmTxPower + ahp->ah_txPowerIndexOffset;	OS_REG_WRITE(ah, AR_PHY_PAPD_PROBE,		  SM(probePowerIndex, AR_PHY_PAPD_PROBE_POWERTX)		| AR_PHY_PAPD_PROBE_NEXT_TX);	ahp->ah_rfgainState = HAL_RFGAIN_READ_REQUESTED;}/* * Exported call to check for a recent gain reading and return * the current state of the thermal calibration gain engine. */HAL_RFGAINar5212GetRfgain(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	GAIN_VALUES *gv = &ahp->ah_gainValues;	u_int32_t rddata, probeType;		if (IS_5416(ah))		return HAL_RFGAIN_INACTIVE;	if (!gv->active)		return HAL_RFGAIN_INACTIVE;	if (ahp->ah_rfgainState == HAL_RFGAIN_READ_REQUESTED) {		/* Caller had asked to setup a new reading. Check it. */		rddata = OS_REG_READ(ah, AR_PHY_PAPD_PROBE);		if ((rddata & AR_PHY_PAPD_PROBE_NEXT_TX) == 0) {			/* bit got cleared, we have a new reading. */			gv->currGain = rddata >> AR_PHY_PAPD_PROBE_GAINF_S;			probeType = MS(rddata, AR_PHY_PAPD_PROBE_TYPE);			if (probeType == AR_PHY_PAPD_PROBE_TYPE_CCK) {				HALASSERT(IS_5112(ah));				if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2)					gv->currGain += ahp->ah_cckOfdmGainDelta;				else					gv->currGain += PHY_PROBE_CCK_CORRECTION;			}			if (IS_5112(ah)) {				ar5212GetGainFCorrection(ah);				if (gv->currGain >= gv->gainFCorrection)					gv->currGain -= gv->gainFCorrection;				else					gv->currGain = 0;			}			/* inactive by default */			ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;			if (!ar5212InvalidGainReadback(ah, gv) &&			    ar5212IsGainAdjustNeeded(ah, gv) &&			    ar5212AdjustGain(ah, gv) > 0) {				/*				 * Change needed. Copy ladder info				 * into eeprom info.				 */				ahp->ah_rfgainState = HAL_RFGAIN_NEED_CHANGE;                               /* WAR 18034 */                                 AH_PRIVATE(ah)->ah_cwCalRequire = AH_TRUE;				/* Request IQ recalibration for temperature chang */				ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;			}		}	}	return ahp->ah_rfgainState;}/* * Check to see if our readback gain level sits within the linear * region of our current variable attenuation window */static HAL_BOOLar5212IsGainAdjustNeeded(struct ath_hal *ah, const GAIN_VALUES *gv){	return (gv->currGain <= gv->loTrig || gv->currGain >= gv->hiTrig);}/* * Move the rabbit ears in the correct direction. */static int32_t ar5212AdjustGain(struct ath_hal *ah, GAIN_VALUES *gv){	const GAIN_OPTIMIZATION_LADDER *gl;	if (IS_5112(ah))		gl = &gainLadder5112;	else		gl = &gainLadder;	gv->currStep = &gl->optStep[gv->currStepNum];	if (gv->currGain >= gv->hiTrig) {		if (gv->currStepNum == 0) {			HALDEBUG(ah, "%s: Max gain limit.\n", __func__);			return -1;		}		HALDEBUG(ah, "%s: Adding gain: currG=%d [%s] --> ",			__func__, gv->currGain, gv->currStep->stepName);		gv->targetGain = gv->currGain;		while (gv->targetGain >= gv->hiTrig && gv->currStepNum > 0) {			gv->targetGain -= 2 * (gl->optStep[--(gv->currStepNum)].stepGain -				gv->currStep->stepGain);			gv->currStep = &gl->optStep[gv->currStepNum];		}		HALDEBUG(ah, "targG=%d [%s]\n",			gv->targetGain, gv->currStep->stepName);		return 1;	}	if (gv->currGain <= gv->loTrig) {		if (gv->currStepNum == gl->numStepsInLadder-1) {			HALDEBUG(ah, "%s: Min gain limit.\n", __func__);			return -2;		}		HALDEBUG(ah, "%s: Deducting gain: currG=%d [%s] --> ",			__func__, gv->currGain, gv->currStep->stepName);		gv->targetGain = gv->currGain;		while (gv->targetGain <= gv->loTrig &&		      gv->currStepNum < (gl->numStepsInLadder - 1)) {			gv->targetGain -= 2 *				(gl->optStep[++(gv->currStepNum)].stepGain - gv->currStep->stepGain);			gv->currStep = &gl->optStep[gv->currStepNum];		}		HALDEBUG(ah, "targG=%d [%s]\n",			gv->targetGain, gv->currStep->stepName);		return 2;	}	return 0;		/* caller didn't call needAdjGain first */}/* * Read rf register to determine if gainF needs correction */static voidar5212GetGainFCorrection(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	GAIN_VALUES *gv = &ahp->ah_gainValues;	HALASSERT(IS_RADX112_REV2(ah));	gv->gainFCorrection = 0;	if (ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0) == 1) {		u_int32_t mixGain = gv->currStep->paramVal[0];		u_int32_t gainStep =			ar5212GetRfField(ar5212GetRfBank(ah, 7), 4, 32, 0);		switch (mixGain) {		case 0 :			gv->gainFCorrection = 0;			break;		case 1 :			gv->gainFCorrection = gainStep;			break;		case 2 :			gv->gainFCorrection = 2 * gainStep - 5;			break;		case 3 :			gv->gainFCorrection = 2 * gainStep;			break;		}	}}/* * Perform analog "swizzling" of parameters into their location */voidar5212ModifyRfBuffer(u_int32_t *rfBuf, u_int32_t reg32, u_int32_t numBits,                     u_int32_t firstBit, u_int32_t column){	u_int32_t tmp32, mask, arrayEntry, lastBit;	int32_t bitPosition, bitsLeft;	HALASSERT(column <= 3);	HALASSERT(numBits <= 32);	HALASSERT(firstBit + numBits <= MAX_ANALOG_START);	tmp32 = ath_hal_reverseBits(reg32, numBits);	arrayEntry = (firstBit - 1) / 8;	bitPosition = (firstBit - 1) % 8;	bitsLeft = numBits;	while (bitsLeft > 0) {		lastBit = (bitPosition + bitsLeft > 8) ?			8 : bitPosition + bitsLeft;		mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<			(column * 8);		rfBuf[arrayEntry] &= ~mask;		rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<			(column * 8)) & mask;		bitsLeft -= 8 - bitPosition;		tmp32 = tmp32 >> (8 - bitPosition);		bitPosition = 0;		arrayEntry++;	}}/* * Sets the rate to duration values in MAC - used for multi- * rate retry. * The rate duration table needs to cover all valid rate codes; * the XR table covers all ofdm and xr rates, while the 11b table * covers all cck rates => all valid rates get covered between * these two mode's ratetables! * But if we're turbo, the ofdm phy is replaced by the turbo phy * and xr or cck is not valid with turbo => all rates get covered * by the turbo ratetable only */voidar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan){#define	WLAN_CTRL_FRAME_SIZE	(2+2+6+4)	/* ACK+FCS */	const HAL_RATE_TABLE *rt;	int i;	if (IS_5416(ah))			return;				if (IS_CHAN_HALF_RATE(chan)) {		rt = ah->ah_getRateTable(ah, HAL_MODE_11A_HALF_RATE);	} else if (IS_CHAN_QUARTER_RATE(chan)) {		rt = ah->ah_getRateTable(ah, HAL_MODE_11A_QUARTER_RATE);	} else {		rt = ah->ah_getRateTable(ah,			IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_XR);	}	for (i = 0; i < rt->rateCount; ++i)		OS_REG_WRITE(ah,			AR_RATE_DURATION(rt->info[i].rateCode),			ath_hal_computetxtime(ah, rt,				WLAN_CTRL_FRAME_SIZE,				rt->info[i].controlRate, AH_FALSE));	if (!IS_CHAN_TURBO(chan)) {		/* 11g Table is used to cover the CCK rates. */		rt = ah->ah_getRateTable(ah, HAL_MODE_11G);		for (i = 0; i < rt->rateCount; ++i) {			u_int32_t reg = AR_RATE_DURATION(rt->info[i].rateCode);			if (rt->info[i].phy != IEEE80211_T_CCK)				continue;			OS_REG_WRITE(ah, reg,				ath_hal_computetxtime(ah, rt,					WLAN_CTRL_FRAME_SIZE,					rt->info[i].controlRate, AH_FALSE));			/* cck rates have short preamble option also */			if (rt->info[i].shortPreamble) {				reg += rt->info[i].shortPreamble << 2;				OS_REG_WRITE(ah, reg,					ath_hal_computetxtime(ah, rt,						WLAN_CTRL_FRAME_SIZE,						rt->info[i].controlRate,						AH_TRUE));			}		}	}#undef WLAN_CTRL_FRAME_SIZE}/* Adjust various register settings based on half/quarter rate clock setting. * This includes: +USEC, TX/RX latency,  *                + IFS params: slot, eifs, misc etc. */void ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan){	u_int32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec;	refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32;	if (IS_CHAN_HALF_RATE(chan)) {		slot = IFS_SLOT_HALF_RATE;		rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;		txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S;		usec = HALF_RATE_USEC;		eifs = IFS_EIFS_HALF_RATE;		init_usec = INIT_USEC >> 1;	} else { /* quarter rate */		slot = IFS_SLOT_QUARTER_RATE;		rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;		txLat = TX_QUARTER_RATE_LATENCY << AR5212_USEC_TX_LAT_S;		usec = QUARTER_RATE_USEC;		eifs = IFS_EIFS_QUARTER_RATE;		init_usec = INIT_USEC >> 2;	}	OS_REG_WRITE(ah, AR_USEC, (usec | refClock | txLat | rxLat));	OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);	OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);	OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC,				AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec);	return;}#endif /* AH_SUPPORT_AR5212 */

⌨️ 快捷键说明

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