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

📄 ar5212_reset.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Restore previous led state */	OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);	/* Restore soft Led state to GPIO */	OS_REG_WRITE(ah, AR_GPIOCR, softLedCfg);	OS_REG_WRITE(ah, AR_GPIODO, softLedState);	/* Restore previous antenna */	OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);	/* then our BSSID */	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));	/* Restore bmiss rssi & count thresholds */	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);	OS_REG_WRITE(ah, AR_ISR, ~0);		/* cleared on write */	if (!ar5212SetChannel(ah, ichan))		FAIL(HAL_EIO);	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);	ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);	ar5212SetRateDurationTable(ah, chan);	/* Set Tx frame start to tx data start delay */	if (IS_RAD5112_ANY(ah) &&	    (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||	     IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {		txFrm2TxDStart = 			(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?					TX_FRAME_D_START_HALF_RATE:					TX_FRAME_D_START_QUARTER_RATE;		OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL, 			AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);	}	/*	 * Setup fast diversity.	 * Fast diversity can be enabled or disabled via regadd.txt.	 * Default is enabled.	 * For reference,	 *    Disable: reg        val	 *             0x00009860 0x00009d18 (if 11a / 11g, else no change)	 *             0x00009970 0x192bb514	 *             0x0000a208 0xd03e4648	 *	 *    Enable:  0x00009860 0x00009d10 (if 11a / 11g, else no change)	 *             0x00009970 0x192fb514	 *             0x0000a208 0xd03e6788	 */	/* XXX Setup pre PHY ENABLE EAR additions */	/*	 * Wait for the frequency synth to settle (synth goes on	 * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.	 * Value is in 100ns increments.	 */	synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;	if (IS_CHAN_CCK(chan)) {		synthDelay = (4 * synthDelay) / 22;	} else {		synthDelay /= 10;	}	/* Activate the PHY (includes baseband activate and synthesizer on) */	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);	/* 	 * There is an issue if the AP starts the calibration before	 * the base band timeout completes.  This could result in the	 * rx_clear false triggering.  As a workaround we add delay an	 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition	 * does not happen.	 */	if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {		OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);	} else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {		OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);	} else {		OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);	}	/*	 * The udelay method is not reliable with notebooks.	 * Need to check to see if the baseband is ready	 */	testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);	/* Selects the Tx hold */	OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);	i = 0;	while ((i++ < 20) &&	       (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */		OS_DELAY(200);	OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);	/* Calibrate the AGC and start a NF calculation */	OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,		  OS_REG_READ(ah, AR_PHY_AGC_CONTROL)		| AR_PHY_AGC_CONTROL_CAL		| AR_PHY_AGC_CONTROL_NF);	if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {		/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */		OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 			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 (AH_PRIVATE(ah)->ah_rfkillEnabled)		ar5212EnableRfKill(ah);	if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%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.	 */	ar5212SetupClock(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 */	/* 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)) {		ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);	} else {		ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);	}	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_sifstime != (u_int) -1)		ar5212SetSifsTime(ah, ahp->ah_sifstime);	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->privFlags & 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;	}	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);	RESTORE_CCK(ah, ichan, ichan_isBmode);	RESTORE_CCK(ah, chan, isBmode);		OS_MARK(ah, AH_MARK_RESET_DONE, 0);	return AH_TRUE;bad:	if (ichan != AH_NULL)		RESTORE_CCK(ah, ichan, ichan_isBmode);	RESTORE_CCK(ah, chan, isBmode);	OS_MARK(ah, AH_MARK_RESET_DONE, ecode);	if (*status)		*status = ecode;	return AH_FALSE;#undef FAIL#undef N}/* * Call the rf backend to change the channel. */HAL_BOOLar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan){	struct ath_hal_5212 *ahp = AH5212(ah);	/* Change the synth */	if (!ahp->ah_rfHal->setChannel(ah, chan))		return AH_FALSE;	return AH_TRUE;}/* * This channel change evaluates whether the selected hardware can * perform a synthesizer-only channel change (no reset).  If the * TX is not stopped, or the RFBus cannot be granted in the given * time, the function returns false as a reset is necessary */HAL_BOOLar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan){	uint32_t       ulCount;	uint32_t   data, synthDelay, qnum;	uint16_t   rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];	HAL_BOOL    txStopped = AH_TRUE;	HAL_CHANNEL_INTERNAL *ichan;	/*	 * Map public channel to private.	 */	ichan = ath_hal_checkchannel(ah, chan);	/* TX must be stopped or RF Bus grant will not work */	for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) {		if (ar5212NumTxPending(ah, qnum)) {			txStopped = AH_FALSE;			break;		}	}	if (!txStopped)		return AH_FALSE;	/* Kill last Baseband Rx Frame */	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); /* Request analog bus grant */	for (ulCount = 0; ulCount < 100; ulCount++) {		if (OS_REG_READ(ah, AR_PHY_RFBUS_GNT))			break;		OS_DELAY(5);	}	if (ulCount >= 100)		return AH_FALSE;	/* Change the synth */	if (!ar5212SetChannel(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 (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: error init'ing transmit power\n", __func__);		return AH_FALSE;	}	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */	if (IS_CHAN_OFDM(ichan)) {		if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&		    (!IS_CHAN_B(chan)))			ar5212SetSpurMitigation(ah, ichan);		ar5212SetDeltaSlope(ah, chan);	}	/* 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);	if (!(ichan->privFlags & 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;	return AH_TRUE;}voidar5212SetOperatingMode(struct ath_hal *ah, int opmode){	uint32_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;	}}/* * 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)

⌨️ 快捷键说明

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