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

📄 ar5416_reset.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ar5416_reset.c,v 1.27 2008/11/27 22:30:08 sam Exp $ */#include "opt_ah.h"#include "ah.h"#include "ah_internal.h"#include "ah_devid.h"#include "ah_eeprom_v14.h"#include "ar5416/ar5416.h"#include "ar5416/ar5416reg.h"#include "ar5416/ar5416phy.h"#ifdef AH_SUPPORT_AR9280#include "ar5416/ar9280.h"#endif/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ #define	EEP_MINOR(_ah) \	(AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)#define IS_EEP_MINOR_V2(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2)#define IS_EEP_MINOR_V3(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3)/* Additional Time delay to wait after activiting the Base band */#define BASE_ACTIVATE_DELAY	100	/* 100 usec */#define PLL_SETTLE_DELAY	300	/* 300 usec */#define RTC_PLL_SETTLE_DELAY    1000    /* 1 ms     */static void ar5416InitDMA(struct ath_hal *ah);static void ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan);static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode);static void ar5416InitQoS(struct ath_hal *ah);static void ar5416InitUserSettings(struct ath_hal *ah);static HAL_BOOL ar5416SetTransmitPower(struct ath_hal *ah, 	HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);#if 0static HAL_BOOL	ar5416ChannelChange(struct ath_hal *, HAL_CHANNEL *);#endifstatic void ar5416SetDeltaSlope(struct ath_hal *, HAL_CHANNEL_INTERNAL *);static void ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan);#ifdef AH_SUPPORT_AR9280static void ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan);#endifstatic HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah);static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type);static void ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan);static HAL_BOOL ar5416SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah,	struct ar5416eeprom *pEepData, 	HAL_CHANNEL_INTERNAL *chan, int16_t *ratesArray,	uint16_t cfgCtl, uint16_t AntennaReduction,	uint16_t twiceMaxRegulatoryPower, 	uint16_t powerLimit);static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah,	struct ar5416eeprom *pEepData,	HAL_CHANNEL_INTERNAL *chan,	int16_t *pTxPowerIndexOffset);static uint16_t ar5416GetMaxEdgePower(uint16_t freq,	CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz);static void ar5416GetTargetPowers(struct ath_hal *ah, 	HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_HT *powInfo,	uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower,	uint16_t numRates, HAL_BOOL isHt40Target);static void ar5416GetTargetPowersLeg(struct ath_hal *ah, 	HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_LEG *powInfo,	uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower,	uint16_t numRates, HAL_BOOL isExtTarget);static int16_t interpolate(uint16_t target, uint16_t srcLeft,	uint16_t srcRight, int16_t targetLeft, int16_t targetRight);static void ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan);static void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 	HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet,	uint8_t * bChans, uint16_t availPiers,	uint16_t tPdGainOverlap, int16_t *pMinCalPower,	uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,	uint16_t numXpdGains);static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList,	uint16_t listSize,  uint16_t *indexL, uint16_t *indexR);static HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,	uint8_t *pPwrList, uint8_t *pVpdList,	uint16_t numIntercepts, uint8_t *pRetVpdList);/* * Places the device in and out of reset and then places sane * values in the registers based on EEPROM config, initialization * vectors (as determined by the mode), and station configuration * * bChannelChange is used to preserve DMA/PCU registers across * a HW Reset during channel change. */HAL_BOOLar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,	HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status){#define	N(a)	(sizeof (a) / sizeof (a[0]))#define	FAIL(_code)	do { ecode = _code; goto bad; } while (0)	struct ath_hal_5212 *ahp = AH5212(ah);	HAL_CHANNEL_INTERNAL *ichan;	uint32_t softLedCfg;	uint32_t saveDefAntenna, saveLedState;	uint32_t macStaId1;	uint16_t rfXpdGain[2];	u_int modesIndex, freqIndex;	HAL_STATUS ecode;	int i, regWrites = 0;	uint32_t powerVal, rssiThrReg;	uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;	OS_MARK(ah, AH_MARK_RESET, bChannelChange);#define	IS(_c,_f)	(((_c)->channelFlags & _f) || 0)	if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",		    __func__, chan->channel, chan->channelFlags);		FAIL(HAL_EINVAL);	}	if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",		    __func__, chan->channel, chan->channelFlags);		FAIL(HAL_EINVAL);	}#undef IS	/* Bring out of sleep mode */	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n",		    __func__);		FAIL(HAL_EIO);	}	/*	 * Map public channel to private.	 */	ichan = ath_hal_checkchannel(ah, chan);	if (ichan == AH_NULL) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: invalid channel %u/0x%x; no mapping\n",		    __func__, chan->channel, chan->channelFlags);		FAIL(HAL_EINVAL);	} else {		HALDEBUG(ah, HAL_DEBUG_RESET,		    "%s: Ch=%u Max=%d Min=%d\n",__func__,		    ichan->channel, ichan->maxTxPower, ichan->minTxPower);	}	switch (opmode) {	case HAL_M_STA:	case HAL_M_IBSS:	case HAL_M_HOSTAP:	case HAL_M_MONITOR:		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",		    __func__, opmode);		FAIL(HAL_EINVAL);		break;	}	HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);	/* XXX Turn on fast channel change for 5416 */	/*	 * Preserve the bmiss rssi threshold and count threshold	 * across resets	 */	rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR);	/* If reg is zero, first time thru set to default val */	if (rssiThrReg == 0)		rssiThrReg = INIT_RSSI_THR;	/*	 * Preserve the antenna on a channel change	 */	saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);	if (saveDefAntenna == 0)		/* XXX magic constants */		saveDefAntenna = 1;	/* Save hardware flag before chip reset clears the register */	macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 		(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);	/* Save led state from pci config register */	saveLedState = OS_REG_READ(ah, AR_MAC_LED) &		(AR_MAC_LED_ASSOC | AR_MAC_LED_MODE |		 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW);	softLedCfg = OS_REG_READ(ah, AR_GPIO_INTR_OUT);		/*	 * Adjust gain parameters before reset if	 * there's an outstanding gain updated.	 */	(void) ar5416GetRfgain(ah);	if (!ar5416ChipReset(ah, chan)) {		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);		FAIL(HAL_EIO);	}	/* Restore bmiss rssi & count thresholds */	OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg);	/* Setup the indices for the next set of register array writes */	/* XXX Ignore 11n dynamic mode on the AR5416 for the moment */	switch (chan->channelFlags & CHANNEL_ALL) {	case CHANNEL_A:    	case CHANNEL_A_HT20:                modesIndex = 1;                freqIndex  = 1;		break;    	case CHANNEL_T:    	case CHANNEL_A_HT40PLUS:    	case CHANNEL_A_HT40MINUS:                modesIndex = 2;                freqIndex  = 1;	    	break;	case CHANNEL_PUREG:	case CHANNEL_G_HT20:	case CHANNEL_B:	/* treat as channel G , no  B mode suport in owl */		modesIndex = 4;		freqIndex  = 2;		break;    	case CHANNEL_G_HT40PLUS:    	case CHANNEL_G_HT40MINUS:		modesIndex = 3;		freqIndex  = 2;		break;	case CHANNEL_108G:		modesIndex = 5;		freqIndex  = 2;		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",		    __func__, chan->channelFlags);		FAIL(HAL_EINVAL);	}	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);	/* Set correct Baseband to analog shift setting to access analog chips. */	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);	 /*	 * Write addac shifts	 */	OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);#if 0	/* NB: only required for Sowl */	ar5416EepromSetAddac(ah, ichan);#endif	regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1,	    regWrites);	OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);	/* XXX Merlin ini fixups */	/* XXX Merlin 100us delay for shift registers */	regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex,	    regWrites);#ifdef AH_SUPPORT_AR9280	if (AR_SREV_MERLIN_20_OR_LATER(ah)) {		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain,		    modesIndex, regWrites);		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain,		    modesIndex, regWrites);	}#endif	/* XXX Merlin 100us delay for shift registers */	regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_common, 1, regWrites);	/* Setup 11n MAC/Phy mode registers */	ar5416Set11nRegs(ah,chan);		/* XXX updated regWrites? */	ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);#ifdef AH_SUPPORT_AR9280	if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {		/* 5GHz channels w/ Fast Clock use different modal values */		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes,		    modesIndex, regWrites);	}#endif	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);	HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n",		__func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK));	HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n",		__func__, OS_REG_READ(ah,AR_PHY_ADC_CTL));		/* Set the mute mask to the correct default */	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2)		OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {		/* Clear reg to alllow RX_CLEAR line debug */		OS_REG_WRITE(ah, AR_PHY_BLUETOOTH,  0);	}	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {#ifdef notyet		/* Enable burst prefetch for the data queues */		OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );		/* Enable double-buffering */		OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);#endif	}	/* Set ADC/DAC select values */	OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);	if (AH5416(ah)->ah_rx_chainmask == 0x5 ||	    AH5416(ah)->ah_tx_chainmask == 0x5)		OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);	/* Setup Chain Masks */	OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask);	OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask);	OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask);	/* Setup the transmit power values. */	if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: error init'ing transmit power\n", __func__);		FAIL(HAL_EIO);	}	/* Write the analog registers */	if (!ahp->ah_rfHal->setRfRegs(ah, ichan, freqIndex, rfXpdGain)) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: ar5212SetRfRegs failed\n", __func__);		FAIL(HAL_EIO);	}	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */	if (IS_CHAN_OFDM(chan)|| IS_CHAN_HT(chan))		ar5416SetDeltaSlope(ah, ichan);#ifdef AH_SUPPORT_AR9280	if (AR_SREV_MERLIN_10_OR_LATER(ah))		ar9280SpurMitigate(ah, ichan);	else#endif		ar5416SpurMitigate(ah, ichan);	/* Setup board specific options for EEPROM version 3 */	if (!ar5416SetBoardValues(ah, ichan)) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: error setting board options\n", __func__);		FAIL(HAL_EIO);	}	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);	OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));	OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)		| macStaId1		| AR_STA_ID1_RTS_USE_DEF		| ahp->ah_staId1Defaults	);	ar5212SetOperatingMode(ah, opmode);	/* Set Venice BSSID mask according to current state */	OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));	OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));	/* Restore previous led state */	OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState);	/* Restore soft Led state to GPIO */	OS_REG_WRITE(ah, AR_GPIO_INTR_OUT, softLedCfg);	/* 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))

⌨️ 快捷键说明

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