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

📄 ar5212_reset.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Change the synth */	if (!ahp->ah_rfHal.setChannel(ah, ichan))		return AH_FALSE;	/*	 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).	 * Read the phy active delay register. Value is in 100ns increments.	 */	data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;	if (IS_CHAN_CCK(ichan))		synthDelay = (4 * data) / 22;	else		synthDelay = data / 10;	OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);		/* Setup the transmit power values. */	if (!AH_PRIVATE(ah)->ah_setTransmitPower(ah, ichan, rfXpdGain)) {		HALDEBUG(ah, "%s: error init'ing transmit power\n", __func__);		return AH_FALSE;	}	/* Release the RFBus Grant */		OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);		/* Start Noise Floor Cal */		OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);	/* Copy over internal channel flags to public hal channel */	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 ((AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) && (chan->channelFlags & CHANNEL_DFS)) {			OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,					 AR_PHY_DESIRED_SZ_TOT_DES, -34);			OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,					 AR_PHY_AGC_CTL1_COARSE_LOW, -52);			OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,					 AR_PHY_AGC_CTL1_COARSE_HIGH, -18);			OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,					 AR_PHY_FIND_SIG_FIRPWR, -70);		/* Reset all ANI parameters now to a good value */#if 0		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);#endif		ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);		ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);		ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,				 HAL_ANI_USE_OFDM_WEAK_SIG);		ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,				 !HAL_ANI_CCK_WEAK_SIG_THR);		if ((chan->privFlags & CHANNEL_DFS_CLEAR) == 0)			ar5212TxEnable(ah,AH_FALSE);	} else#endif		ar5212TxEnable(ah,AH_TRUE);	return AH_TRUE;}voidar5212SetOperatingMode(struct ath_hal *ah, int opmode){	u_int32_t val;	val = OS_REG_READ(ah, AR_STA_ID1);	val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);	switch (opmode) {	case HAL_M_HOSTAP:		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP					| AR_STA_ID1_KSRCH_MODE);		OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);		break;	case HAL_M_IBSS:		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC					| AR_STA_ID1_KSRCH_MODE);		OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);		break;	case HAL_M_STA:	case HAL_M_MONITOR:		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);		break;	}}#ifdef AH_SUPPORT_XR/* * Configure XR mode support. */HAL_BOOLar5212SetXrMode(struct ath_hal *ah, HAL_OPMODE opmode,HAL_CHANNEL *chan){#define MAC_CLKS(_usec) (IS_CHAN_5GHZ(chan) ? (_usec) * 40  :  (_usec) * 44)	OS_REG_WRITE(ah, AR_XRMODE,		  (OS_REG_READ(ah, AR_XRMODE) &~ (AR_XRMODE_XR_POLL_TYPE|AR_XRMODE_XR_POLL_SUBTYPE))		| SM(FRAME_DATA, AR_XRMODE_XR_POLL_TYPE)		| SM(SUBT_NODATA_CFPOLL, AR_XRMODE_XR_POLL_SUBTYPE)	);	/*	 * Acks to XR frames require longer timeouts - we end	 * up increasing timeout corresponding to all types of	 * frames on the AP; the sta will anyway do XR frames	 * only; given by HW guys to be 100usec	 */	OS_REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, MAC_CLKS(100));	if (opmode == HAL_M_HOSTAP) {		/*		 * timeout values on the AP side corresponding to		 * ctsChirp->xrData and grpPoll->rtsChirp; the former is		 * from the detection of the rtsChirp to the detection		 * of XR data - so a rtsChirp slot, a ctsChirp slot,		 * the XR data detection time and a fudge; the latter		 * i.e. the group poll timeout value depends on the		 * XR mode aifs and cwMin/Max in slot time units plus		 * time for a chirp and some fudge; the AP also needs		 * the slot delay to figure out the timing between		 * rtsChirp->ctsChirp		 */		OS_REG_WRITE(ah, AR_XRTO,			  (OS_REG_READ(ah, AR_XRTO) &~				(AR_XRTO_CHIRP_TO|AR_XRTO_POLL_TO))			| SM(MAC_CLKS(2 * XR_SLOT_DELAY +				XR_DATA_DETECT_DELAY + 80),				AR_XRTO_CHIRP_TO)			| SM(MAC_CLKS((INIT_AIFS_XR + INIT_CWMAX_XR) *				XR_SLOT_DELAY + XR_CHIRP_DUR + 16),				 AR_XRTO_POLL_TO)		);		OS_REG_WRITE(ah, AR_XRDEL,			  (OS_REG_READ(ah, AR_XRDEL) &~ (AR_XRDEL_SLOT_DELAY))					 | SM(MAC_CLKS(XR_SLOT_DELAY), AR_XRDEL_SLOT_DELAY));	} else {		/*		 * used by the station to figure out timing between		 * end of rtsChirp->xrData; there is one ctsChirp		 * slot to be left in between - so two slots minus		 * the chirp duration and a fudge		 */		OS_REG_RMW_FIELD(ah, AR_XRDEL, AR_XRDEL_CHIRP_DATA_DELAY,		    MAC_CLKS(2 * XR_SLOT_DELAY - (XR_CHIRP_DUR + 1)));		OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, MAC_CLKS(XR_SLOT_DELAY));		OS_REG_WRITE(ah, AR_XRMODE,			OS_REG_READ(ah, AR_XRMODE) | AR_XRMODE_XR_WAIT_FOR_POLL);	}	return AH_TRUE;#undef MAC_CLKS}#endif /* AH_SUPPORT_XR *//* * 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_BOOLar5212PhyDisable(struct ath_hal *ah){	return ar5212SetResetReg(ah, AR_RC_BB);}/* * Places all of hardware into reset */HAL_BOOLar5212Disable(struct ath_hal *ah){	if (!ar5212SetPowerMode(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 ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI);}/* * 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_BOOLar5212ChipReset(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 - PCI must be reset after the rest of the	 	* device has been reset	 	*/		if (!ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI))			return AH_FALSE;		/* Bring out of sleep mode (AGAIN) */		if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))			return AH_FALSE;		/* Clear warm reset register */		if (!ar5212SetResetReg(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_5413(ah)) {			rfMode = AR_PHY_MODE_AR5112;						if (IS_CHAN_HALF_RATE(chan))				rfMode |= AR_PHY_MODE_HALF;			else if (IS_CHAN_QUARTER_RATE(chan))				rfMode |= AR_PHY_MODE_QUARTER;			if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))				phyPLL = AR_PHY_PLL_CTL_44_5112;			else				phyPLL = AR_PHY_PLL_CTL_40_5413;		} else 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;}/* * Recalibrate the lower PHY chips to account for temperature/environment * changes. */HAL_BOOLar5212PerCalibration(struct ath_hal *ah,  HAL_CHANNEL *chan, HAL_BOOL *isIQdone){#define IQ_CAL_TRIES    10	struct ath_hal_5212 *ahp = AH5212(ah);	HAL_CHANNEL_INTERNAL *ichan;	int32_t qCoff, qCoffDenom;	int32_t iqCorrMeas, iCoff, iCoffDenom;	u_int32_t powerMeasQ, powerMeasI;	OS_MARK(ah, AH_MARK_PERCAL, chan->channel);	*isIQdone = AH_FALSE;	ichan = ath_hal_checkchannel(ah, chan);	if (ichan == AH_NULL) {		HALDEBUG(ah, "%s: invalid channel %u/0x%x; no mapping\n",			__func__, chan->channel, chan->channelFlags);		return AH_FALSE;	}#ifdef AH_SUPPORT_DFS	if (((ichan->channelFlags & CHANNEL_DFS) != 0) &&	    ((ichan->privFlags & CHANNEL_INTERFERENCE) != 0)) {		HALDEBUG(ah, "%s: invalid channel %u/0x%x; Radar detected on channel\n",			__func__, chan->channel, chan->channelFlags);		return AH_FALSE;	}#endif	/* XXX EAR */	if ((ahp->ah_bIQCalibration == IQ_CAL_DONE) ||	    (ahp->ah_bIQCalibration == IQ_CAL_INACTIVE))		*isIQdone = AH_TRUE;	/* IQ calibration in progress. Check to see if it has finished. */	if (ahp->ah_bIQCalibration == IQ_CAL_RUNNING &&	    !(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_IQCAL)) {		int i;		/* IQ Calibration has finished. */		ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;		*isIQdone = AH_TRUE;		/* workaround for misgated IQ Cal results */		for (i = 0; i < IQ_CAL_TRIES; i++) {			/* Read calibration results. */			powerMeasI = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_I);			powerMeasQ = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_Q);			iqCorrMeas = OS_REG_READ(ah, AR_PHY_IQCAL_RES_IQ_CORR_MEAS);			if (powerMeasI && powerMeasQ)				break;			/* Do we really need this??? */			OS_REG_WRITE (ah,  AR_PHY_TIMING_CTRL4,				      OS_REG_READ(ah,  AR_PHY_TIMING_CTRL4) |				      AR_PHY_TIMING_CTRL4_DO_IQCAL);		}		/*		 * Prescale these values to remove 64-bit operation		 * requirement at the loss of a little precision.		 */		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;		qCoffDenom = powerMeasQ / 128;		/* Protect against divide-by-0 and loss of sign bits. */		if (iCoffDenom != 0 && qCoffDenom >= 2) {			iCoff = (int8_t)(-iqCorrMeas) / iCoffDenom;			/* IQCORR_Q_I_COFF is a signed 6 bit number */			if (iCoff < -32) {				iCoff = -32;			} else if (iCoff > 31) {				iCoff = 31;			}			/* IQCORR_Q_Q_COFF is a signed 5 bit number */			qCoff = (powerMeasI / qCoffDenom) - 128;			if (qCoff < -16) {				qCoff = -16;			} else if (qCoff > 15) {				qCoff = 15;			}#ifdef CALIBRATION_DEBUG			HALDEBUG(ah, "****************** MISGATED IQ CAL! *******************\n");			HALDEBUG(ah, "time       = %d, i = %d, \n",				OS_GETUPTIME(ah), i);			HALDEBUG(ah, "powerMeasI = 0x%08x\n", powerMeasI);			HALDEBUG(ah, "powerMeasQ = 0x%08x\n", powerMeasQ);

⌨️ 快捷键说明

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