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

📄 ar5312_reset.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 2 页
字号:
			AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,			INIT_IQCAL_LOG_COUNT_MAX);		OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,			AR_PHY_TIMING_CTRL4_DO_IQCAL);		ahp->ah_bIQCalibration = IQ_CAL_RUNNING;	} else		ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;	/* Setup compression registers */	ar5212SetCompRegs(ah);	/* Set 1:1 QCU to DCU mapping for all queues */	for (i = 0; i < AR_NUM_DCU; i++)		OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);	ahp->ah_intrTxqs = 0;	for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)		ar5212ResetTxQueue(ah, i);	/*	 * Setup interrupt handling.  Note that ar5212ResetTxQueue	 * manipulates the secondary IMR's as queues are enabled	 * and disabled.  This is done with RMW ops to insure the	 * settings we make here are preserved.	 */	ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN			| AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN			| AR_IMR_HIUERR			;	if (opmode == HAL_M_HOSTAP)		ahp->ah_maskReg |= AR_IMR_MIB;	OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);	/* Enable bus errors that are OR'd to set the HIUERR bit */	OS_REG_WRITE(ah, AR_IMR_S2,		OS_REG_READ(ah, AR_IMR_S2)		| AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);	if (ar5212GetRfKill(ah))		ar5212EnableRfKill(ah);	if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {		HALDEBUG(ah, "%s: offset calibration failed to complete in 1ms;"			" noisy environment?\n", __func__);	}	/*	 * Set clocks back to 32kHz if they had been using refClk, then	 * use an external 32kHz crystal when sleeping, if one exists.	 */	ar5312SetupClock(ah, opmode);	/*	 * Writing to AR_BEACON will start timers. Hence it should	 * be the last register to be written. Do not reset tsf, do	 * not enable beacons at this point, but preserve other values	 * like beaconInterval.	 */	OS_REG_WRITE(ah, AR_BEACON,		(OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));	/* XXX Setup post reset EAR additions */#ifdef AH_SUPPORT_XR	/* it should be changed to IS_CHAN_XR once the reg domain sets the XR flags on channels */	if (opmode != HAL_M_STA && ahp->ah_xrEnable && !ar5212SetXrMode(ah, opmode,chan)) {		HALDEBUG(ah, "%s: unable to setup XR mode\n", __func__);		FAIL(HAL_EIO);	}#endif /* AH_SUPPORT_XR */	/*  QoS support */	if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||	    (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&	     AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {		OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa);	/* XXX magic */		OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210);	/* XXX magic */	}	/* Turn on NOACK Support for QoS packets */	OS_REG_WRITE(ah, AR_NOACK,		     SM(2, AR_NOACK_2BIT_VALUE) |		     SM(5, AR_NOACK_BIT_OFFSET) |		     SM(0, AR_NOACK_BYTE_OFFSET));	/* Get Antenna Gain reduction */	if (IS_CHAN_5GHZ(chan)) {		twiceAntennaGain = ahp->ah_antennaGainMax[0];	} else {		twiceAntennaGain = ahp->ah_antennaGainMax[1];	}	twiceAntennaReduction =		ath_hal_getantennareduction(ah, chan, twiceAntennaGain);	/* TPC for self-generated frames */	ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK);	if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)		ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;	if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))		ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)			+ ahp->ah_txPowerIndexOffset;	ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS);	if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)		ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;	if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))		ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)			+ ahp->ah_txPowerIndexOffset;	chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP);	if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)		chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;	if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))		chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)			+ ahp->ah_txPowerIndexOffset;	if (ackTpcPow > 63)		ackTpcPow = 63;	if (ctsTpcPow > 63)		ctsTpcPow = 63;	if (chirpTpcPow > 63)		chirpTpcPow = 63;	powerVal = SM(ackTpcPow, AR_TPC_ACK) |		SM(ctsTpcPow, AR_TPC_CTS) |		SM(chirpTpcPow, AR_TPC_CHIRP);	OS_REG_WRITE(ah, AR_TPC, powerVal);	/* Restore user-specified settings */	if (ahp->ah_miscMode != 0)		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);	if (ahp->ah_slottime != (u_int) -1)		ar5212SetSlotTime(ah, ahp->ah_slottime);	if (ahp->ah_acktimeout != (u_int) -1)		ar5212SetAckTimeout(ah, ahp->ah_acktimeout);	if (ahp->ah_ctstimeout != (u_int) -1)		ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);	if (AH_PRIVATE(ah)->ah_diagreg != 0)		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);	AH_PRIVATE(ah)->ah_opmode = opmode;	/* record operating mode */	if (bChannelChange) {		if (!(ichan->channelFlags & CHANNEL_DFS)) 			ichan->privFlags &= ~CHANNEL_INTERFERENCE;		chan->channelFlags = ichan->channelFlags;		chan->privFlags = ichan->privFlags;		chan->maxRegTxPower = ichan->maxRegTxPower;		chan->maxTxPower = ichan->maxTxPower;		chan->minTxPower = ichan->minTxPower;		AH_PRIVATE(ah)->ah_curchan->ah_channel_time=0;		AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar5212GetTsf64(ah);#ifdef AH_SUPPORT_DFS		if (opmode == HAL_M_HOSTAP && (chan->channelFlags & CHANNEL_DFS) &&			(chan->privFlags & CHANNEL_DFS_CLEAR) == 0 )			ar5212TxEnable(ah,AH_FALSE);		else#endif			ar5212TxEnable(ah,AH_TRUE);	}	HALDEBUG(ah, "%s: done\n", __func__);	OS_MARK(ah, AH_MARK_RESET_DONE, 0);	return AH_TRUE;bad:	OS_MARK(ah, AH_MARK_RESET_DONE, ecode);	if (*status)		*status = ecode;	return AH_FALSE;#undef FAIL#undef N}/* * Places the PHY and Radio chips into reset.  A full reset * must be called to leave this state.  The PCI/MAC/PCU are * not placed into reset as we must receive interrupt to * re-enable the hardware. */HAL_BOOLar5312PhyDisable(struct ath_hal *ah){    return ar5312SetResetReg(ah, AR_RC_BB);}/* * Places all of hardware into reset */HAL_BOOLar5312Disable(struct ath_hal *ah){	if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))		return AH_FALSE;	/*	 * Reset the HW - PCI must be reset after the rest of the	 * device has been reset.	 */	return ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB);}/* * Places the hardware into reset and then pulls it out of reset * * TODO: Only write the PLL if we're changing to or from CCK mode *  * WARNING: The order of the PLL and mode registers must be correct. */HAL_BOOLar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan){	struct ath_hal_5212 *ahp = AH5212(ah);  	OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);	/*	 * Reset the HW 	 */	if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB))		return AH_FALSE;	/* Bring out of sleep mode (AGAIN) */	if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))		return AH_FALSE;	/* Clear warm reset register */	if (!ar5312SetResetReg(ah, 0))		return AH_FALSE;	/*	 * Perform warm reset before the mode/PLL/turbo registers	 * are changed in order to deactivate the radio.  Mode changes	 * with an active radio can result in corrupted shifts to the	 * radio device.	 */	/*	 * Set CCK and Turbo modes correctly.	 */	if (chan != AH_NULL) {		/* NB: can be null during attach */		u_int32_t rfMode, phyPLL = 0, curPhyPLL, turbo;		if (IS_5112(ah) || IS_2413(ah)) {			rfMode = AR_PHY_MODE_AR5112;			if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {				phyPLL = AR_PHY_PLL_CTL_44_5112;			} else {				if (IS_CHAN_HALF_RATE(chan)) {					phyPLL = AR_PHY_PLL_CTL_40_5112_HALF;				} else if (IS_CHAN_QUARTER_RATE(chan)) {					phyPLL = AR_PHY_PLL_CTL_40_5112_QUARTER;				} else {					phyPLL = AR_PHY_PLL_CTL_40_5112;				}			}		} else {			rfMode = AR_PHY_MODE_AR5111;			if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {				phyPLL = AR_PHY_PLL_CTL_44;			} else {				if (IS_CHAN_HALF_RATE(chan)) {					phyPLL = AR_PHY_PLL_CTL_40_HALF;				} else if (IS_CHAN_QUARTER_RATE(chan)) {					phyPLL = AR_PHY_PLL_CTL_40_QUARTER;				} else {					phyPLL = AR_PHY_PLL_CTL_40;				}			}		}		if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) || 					   IS_CHAN_G(chan)))			rfMode |= AR_PHY_MODE_DYNAMIC;		else if (IS_CHAN_OFDM(chan))			rfMode |= AR_PHY_MODE_OFDM;		else			rfMode |= AR_PHY_MODE_CCK;		if (IS_CHAN_5GHZ(chan))			rfMode |= AR_PHY_MODE_RF5GHZ;		else			rfMode |= AR_PHY_MODE_RF2GHZ;		turbo = IS_CHAN_TURBO(chan) ?			(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;		curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);#ifdef AH_SUPPORT_XR		if (ahp->ah_xrEnable) {			rfMode |= AR_PHY_MODE_XR;		}#endif		/*		 * PLL, Mode, and Turbo values must be written in the correct		 * order to ensure:		 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC		 *   mode bit is set		 * - Turbo cannot be set at the same time as CCK or DYNAMIC		 */		if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {			OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);			OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);			if (curPhyPLL != phyPLL) {				OS_REG_WRITE(ah,  AR_PHY_PLL_CTL,  phyPLL);				/* Wait for the PLL to settle */				OS_DELAY(PLL_SETTLE_DELAY);			}		} else {			if (curPhyPLL != phyPLL) {				OS_REG_WRITE(ah,  AR_PHY_PLL_CTL,  phyPLL);				/* Wait for the PLL to settle */				OS_DELAY(PLL_SETTLE_DELAY);			}			OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);			OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);		}	}	return AH_TRUE;}/* * Write the given reset bit mask into the reset register */static HAL_BOOLar5312SetResetReg(struct ath_hal *ah, u_int32_t resetMask){	u_int32_t mask = resetMask ? resetMask : ~0;	HAL_BOOL rt;        if ((rt = ar5312MacReset(ah, mask)) == AH_FALSE) {		return rt;	}        if ((resetMask & AR_RC_MAC) == 0) {		if (isBigEndian()) {			/*			 * Set CFG, little-endian for register			 * and descriptor accesses.			 */#ifdef AH_NEED_DESC_SWAP			mask = INIT_CONFIG_STATUS | AR_CFG_SWRD;#else			mask = INIT_CONFIG_STATUS |                                AR_CFG_SWTD | AR_CFG_SWRD;#endif			OS_REG_WRITE(ah, AR_CFG, mask);		} else			OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);	}	return rt;}/* * ar5312MacReset resets (and then un-resets) the specified * wireless components. * Note: The RCMask cannot be zero on entering from ar5312SetResetReg. */HAL_BOOLar5312MacReset(struct ath_hal *ah, unsigned int RCMask){	int wlanNum;	u_int32_t resetBB, resetBits, regMask;	u_int32_t reg;	if (RCMask == 0)		return(AH_FALSE);        if ((wlanNum = GETWMACNUM(ah)) == -1) {                return (AH_FALSE);        }#if (AH_SUPPORT_2316 || AH_SUPPORT_2317)	    if((AH_PRIVATE(ah)->ah_devid ==  AR5212_AR2315_REV6) ||		(AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV7) ||		(AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV1) ||		(AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV2)) {  			switch(wlanNum) {			case 0:				resetBB = AR5315_RC_BB0_CRES | AR5315_RC_WBB0_RES; 				/* Warm and cold reset bits for wbb */				resetBits = AR5315_RC_WMAC0_RES;				break;			case 1:				resetBB = AR5315_RC_BB1_CRES | AR5315_RC_WBB1_RES; 				/* Warm and cold reset bits for wbb */				resetBits = AR5315_RC_WMAC1_RES;				break;			default:				return(AH_FALSE);			}					regMask = ~(resetBB | resetBits);			/* read before */			reg = OS_REG_READ(ah, 							  (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) + AR5315_RESET));			if (RCMask == AR_RC_BB) {				/* Put baseband in reset */				reg |= resetBB;    /* Cold and warm reset the baseband bits */			} else {				/*				 * Reset the MAC and baseband.  This is a bit different than				 * the PCI version, but holding in reset causes problems.				 */				reg &= regMask;				reg |= (resetBits | resetBB) ;			}			OS_REG_WRITE(ah, 						 (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR5315_RESET),						 reg);			/* read after */			OS_REG_READ(ah, 						(AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) +AR5315_RESET));			OS_DELAY(100);			/* Bring MAC and baseband out of reset */			reg &= regMask;			/* read before */			OS_REG_READ(ah, 						(AR5315_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR5315_RESET));			OS_REG_WRITE(ah, 						 (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR5315_RESET),						 reg);			/* read after */			OS_REG_READ(ah,						(AR5315_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR5315_RESET));		}         else #endif		{			switch(wlanNum) {			case 0:				resetBB = AR_RC_BB0_CRES | AR_RC_WBB0_RES; 				/* Warm and cold reset bits for wbb */				resetBits = AR_RC_WMAC0_RES;				break;			case 1:				resetBB = AR_RC_BB1_CRES | AR_RC_WBB1_RES; 				/* Warm and cold reset bits for wbb */				resetBits = AR_RC_WMAC1_RES;				break;			default:				return(AH_FALSE);			}					regMask = ~(resetBB | resetBits);			/* read before */			reg = OS_REG_READ(ah, 							  (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) + AR531X_RESET));			if (RCMask == AR_RC_BB) {				/* Put baseband in reset */				reg |= resetBB;    /* Cold and warm reset the baseband bits */			} else {				/*				 * Reset the MAC and baseband.  This is a bit different than				 * the PCI version, but holding in reset causes problems.				 */				reg &= regMask;				reg |= (resetBits | resetBB) ;			}			OS_REG_WRITE(ah, 						 (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR531X_RESET),						 reg);			/* read after */			OS_REG_READ(ah, 						(AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) +AR531X_RESET));			OS_DELAY(100);			/* Bring MAC and baseband out of reset */			reg &= regMask;			/* read before */			OS_REG_READ(ah, 						(AR_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR531X_RESET));			OS_REG_WRITE(ah, 						 (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR531X_RESET),						 reg);			/* read after */			OS_REG_READ(ah,						(AR_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR531X_RESET));		}	return(AH_TRUE);}#endif /* AH_SUPPORT_AR5312 */

⌨️ 快捷键说明

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