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

📄 ar5212_attach.c

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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: ar5212_attach.c,v 1.18 2008/11/19 22:10:42 sam Exp $ */#include "opt_ah.h"#include "ah.h"#include "ah_internal.h"#include "ah_devid.h"#include "ar5212/ar5212.h"#include "ar5212/ar5212reg.h"#include "ar5212/ar5212phy.h"#define AH_5212_COMMON#include "ar5212/ar5212.ini"static const struct ath_hal_private ar5212hal = {{	.ah_magic			= AR5212_MAGIC,	.ah_abi				= HAL_ABI_VERSION,	.ah_countryCode			= CTRY_DEFAULT,	.ah_getRateTable		= ar5212GetRateTable,	.ah_detach			= ar5212Detach,	/* Reset Functions */	.ah_reset			= ar5212Reset,	.ah_phyDisable			= ar5212PhyDisable,	.ah_disable			= ar5212Disable,	.ah_setPCUConfig		= ar5212SetPCUConfig,	.ah_perCalibration		= ar5212PerCalibration,	.ah_perCalibrationN		= ar5212PerCalibrationN,	.ah_resetCalValid		= ar5212ResetCalValid,	.ah_setTxPowerLimit		= ar5212SetTxPowerLimit,	.ah_getChanNoise		= ath_hal_getChanNoise,	/* Transmit functions */	.ah_updateTxTrigLevel		= ar5212UpdateTxTrigLevel,	.ah_setupTxQueue		= ar5212SetupTxQueue,	.ah_setTxQueueProps             = ar5212SetTxQueueProps,	.ah_getTxQueueProps             = ar5212GetTxQueueProps,	.ah_releaseTxQueue		= ar5212ReleaseTxQueue,	.ah_resetTxQueue		= ar5212ResetTxQueue,	.ah_getTxDP			= ar5212GetTxDP,	.ah_setTxDP			= ar5212SetTxDP,	.ah_numTxPending		= ar5212NumTxPending,	.ah_startTxDma			= ar5212StartTxDma,	.ah_stopTxDma			= ar5212StopTxDma,	.ah_setupTxDesc			= ar5212SetupTxDesc,	.ah_setupXTxDesc		= ar5212SetupXTxDesc,	.ah_fillTxDesc			= ar5212FillTxDesc,	.ah_procTxDesc			= ar5212ProcTxDesc,	.ah_getTxIntrQueue		= ar5212GetTxIntrQueue,	.ah_reqTxIntrDesc 		= ar5212IntrReqTxDesc,	/* RX Functions */	.ah_getRxDP			= ar5212GetRxDP,	.ah_setRxDP			= ar5212SetRxDP,	.ah_enableReceive		= ar5212EnableReceive,	.ah_stopDmaReceive		= ar5212StopDmaReceive,	.ah_startPcuReceive		= ar5212StartPcuReceive,	.ah_stopPcuReceive		= ar5212StopPcuReceive,	.ah_setMulticastFilter		= ar5212SetMulticastFilter,	.ah_setMulticastFilterIndex	= ar5212SetMulticastFilterIndex,	.ah_clrMulticastFilterIndex	= ar5212ClrMulticastFilterIndex,	.ah_getRxFilter			= ar5212GetRxFilter,	.ah_setRxFilter			= ar5212SetRxFilter,	.ah_setupRxDesc			= ar5212SetupRxDesc,	.ah_procRxDesc			= ar5212ProcRxDesc,	.ah_rxMonitor			= ar5212AniPoll,	.ah_procMibEvent		= ar5212ProcessMibIntr,	/* Misc Functions */	.ah_getCapability		= ar5212GetCapability,	.ah_setCapability		= ar5212SetCapability,	.ah_getDiagState		= ar5212GetDiagState,	.ah_getMacAddress		= ar5212GetMacAddress,	.ah_setMacAddress		= ar5212SetMacAddress,	.ah_getBssIdMask		= ar5212GetBssIdMask,	.ah_setBssIdMask		= ar5212SetBssIdMask,	.ah_setRegulatoryDomain		= ar5212SetRegulatoryDomain,	.ah_setLedState			= ar5212SetLedState,	.ah_writeAssocid		= ar5212WriteAssocid,	.ah_gpioCfgInput		= ar5212GpioCfgInput,	.ah_gpioCfgOutput		= ar5212GpioCfgOutput,	.ah_gpioGet			= ar5212GpioGet,	.ah_gpioSet			= ar5212GpioSet,	.ah_gpioSetIntr			= ar5212GpioSetIntr,	.ah_getTsf32			= ar5212GetTsf32,	.ah_getTsf64			= ar5212GetTsf64,	.ah_resetTsf			= ar5212ResetTsf,	.ah_detectCardPresent		= ar5212DetectCardPresent,	.ah_updateMibCounters		= ar5212UpdateMibCounters,	.ah_getRfGain			= ar5212GetRfgain,	.ah_getDefAntenna		= ar5212GetDefAntenna,	.ah_setDefAntenna		= ar5212SetDefAntenna,	.ah_getAntennaSwitch		= ar5212GetAntennaSwitch,	.ah_setAntennaSwitch		= ar5212SetAntennaSwitch,	.ah_setSifsTime			= ar5212SetSifsTime,	.ah_getSifsTime			= ar5212GetSifsTime,	.ah_setSlotTime			= ar5212SetSlotTime,	.ah_getSlotTime			= ar5212GetSlotTime,	.ah_setAckTimeout		= ar5212SetAckTimeout,	.ah_getAckTimeout		= ar5212GetAckTimeout,	.ah_setAckCTSRate		= ar5212SetAckCTSRate,	.ah_getAckCTSRate		= ar5212GetAckCTSRate,	.ah_setCTSTimeout		= ar5212SetCTSTimeout,	.ah_getCTSTimeout		= ar5212GetCTSTimeout,	.ah_setDecompMask               = ar5212SetDecompMask,	.ah_setCoverageClass            = ar5212SetCoverageClass,	/* Key Cache Functions */	.ah_getKeyCacheSize		= ar5212GetKeyCacheSize,	.ah_resetKeyCacheEntry		= ar5212ResetKeyCacheEntry,	.ah_isKeyCacheEntryValid	= ar5212IsKeyCacheEntryValid,	.ah_setKeyCacheEntry		= ar5212SetKeyCacheEntry,	.ah_setKeyCacheEntryMac		= ar5212SetKeyCacheEntryMac,	/* Power Management Functions */	.ah_setPowerMode		= ar5212SetPowerMode,	.ah_getPowerMode		= ar5212GetPowerMode,	/* Beacon Functions */	.ah_setBeaconTimers		= ar5212SetBeaconTimers,	.ah_beaconInit			= ar5212BeaconInit,	.ah_setStationBeaconTimers	= ar5212SetStaBeaconTimers,	.ah_resetStationBeaconTimers	= ar5212ResetStaBeaconTimers,	/* Interrupt Functions */	.ah_isInterruptPending		= ar5212IsInterruptPending,	.ah_getPendingInterrupts	= ar5212GetPendingInterrupts,	.ah_getInterrupts		= ar5212GetInterrupts,	.ah_setInterrupts		= ar5212SetInterrupts },	.ah_getChannelEdges		= ar5212GetChannelEdges,	.ah_getWirelessModes		= ar5212GetWirelessModes,	.ah_eepromRead			= ar5212EepromRead,#ifdef AH_SUPPORT_WRITE_EEPROM	.ah_eepromWrite			= ar5212EepromWrite,#endif	.ah_gpioCfgOutput		= ar5212GpioCfgOutput,	.ah_gpioCfgInput		= ar5212GpioCfgInput,	.ah_gpioGet			= ar5212GpioGet,	.ah_gpioSet			= ar5212GpioSet,	.ah_gpioSetIntr			= ar5212GpioSetIntr,	.ah_getChipPowerLimits		= ar5212GetChipPowerLimits,};/* * Disable PLL when in L0s as well as receiver clock when in L1. * This power saving option must be enabled through the Serdes. * * Programming the Serdes must go through the same 288 bit serial shift * register as the other analog registers.  Hence the 9 writes. * * XXX Clean up the magic numbers. */static voidconfigurePciePowerSave(struct ath_hal *ah){	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);	/* RX shut off when elecidle is asserted */	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);                                                                                           	/* Shut off PLL and CLKREQ active in L1 */	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);                                                                                           	/* Load the new settings */	OS_REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);}uint32_tar5212GetRadioRev(struct ath_hal *ah){	uint32_t val;	int i;	/* Read Radio Chip Rev Extract */	OS_REG_WRITE(ah, AR_PHY(0x34), 0x00001c16);	for (i = 0; i < 8; i++)		OS_REG_WRITE(ah, AR_PHY(0x20), 0x00010000);	val = (OS_REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;	val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);	return ath_hal_reverseBits(val, 8);}static voidar5212AniSetup(struct ath_hal *ah){	static const struct ar5212AniParams aniparams = {		.maxNoiseImmunityLevel	= 4,	/* levels 0..4 */		.totalSizeDesired	= { -55, -55, -55, -55, -62 },		.coarseHigh		= { -14, -14, -14, -14, -12 },		.coarseLow		= { -64, -64, -64, -64, -70 },		.firpwr			= { -78, -78, -78, -78, -80 },		.maxSpurImmunityLevel	= 2,	/* NB: depends on chip rev */		.cycPwrThr1		= { 2, 4, 6, 8, 10, 12, 14, 16 },		.maxFirstepLevel	= 2,	/* levels 0..2 */		.firstep		= { 0, 4, 8 },		.ofdmTrigHigh		= 500,		.ofdmTrigLow		= 200,		.cckTrigHigh		= 200,		.cckTrigLow		= 100,		.rssiThrHigh		= 40,		.rssiThrLow		= 7,		.period			= 100,	};	if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_GRIFFIN) {		struct ar5212AniParams tmp;		OS_MEMCPY(&tmp, &aniparams, sizeof(struct ar5212AniParams));		tmp.maxSpurImmunityLevel = 7;	/* Venice and earlier */		ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE);	} else		ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE);}/* * Attach for an AR5212 part. */voidar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status){#define	N(a)	(sizeof(a)/sizeof(a[0]))	static const uint8_t defbssidmask[IEEE80211_ADDR_LEN] =		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };	struct ath_hal *ah;	ah = &ahp->ah_priv.h;	/* set initial values */	OS_MEMCPY(&ahp->ah_priv, &ar5212hal, sizeof(struct ath_hal_private));	ah->ah_sc = sc;	ah->ah_st = st;	ah->ah_sh = sh;	ah->ah_devid = devid;			/* NB: for alq */	AH_PRIVATE(ah)->ah_devid = devid;	AH_PRIVATE(ah)->ah_subvendorid = 0;	/* XXX */	AH_PRIVATE(ah)->ah_powerLimit = MAX_RATE_POWER;	AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX;	/* no scaling */	ahp->ah_antControl = HAL_ANT_VARIABLE;	ahp->ah_diversity = AH_TRUE;	ahp->ah_bIQCalibration = AH_FALSE;	/*	 * Enable MIC handling.	 */	ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;	ahp->ah_rssiThr = INIT_RSSI_THR;	ahp->ah_tpcEnabled = AH_FALSE;		/* disabled by default */	ahp->ah_phyPowerOn = AH_FALSE;	ahp->ah_macTPC = SM(MAX_RATE_POWER, AR_TPC_ACK)		       | SM(MAX_RATE_POWER, AR_TPC_CTS)		       | SM(MAX_RATE_POWER, AR_TPC_CHIRP);	ahp->ah_beaconInterval = 100;		/* XXX [20..1000] */	ahp->ah_enable32kHzClock = DONT_USE_32KHZ;/* XXX */	ahp->ah_slottime = (u_int) -1;	ahp->ah_acktimeout = (u_int) -1;	ahp->ah_ctstimeout = (u_int) -1;	ahp->ah_sifstime = (u_int) -1;	OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);#undef N}/* * Validate MAC version and revision.  */static HAL_BOOLar5212IsMacSupported(uint8_t macVersion, uint8_t macRev){#define	N(a)	(sizeof(a)/sizeof(a[0]))	static const struct {		uint8_t	version;		uint8_t	revMin, revMax;	} macs[] = {	    { AR_SREV_VERSION_VENICE,	      AR_SREV_D2PLUS,		AR_SREV_REVISION_MAX },	    { AR_SREV_VERSION_GRIFFIN,	      AR_SREV_D2PLUS,		AR_SREV_REVISION_MAX },	    { AR_SREV_5413,	      AR_SREV_REVISION_MIN,	AR_SREV_REVISION_MAX },	    { AR_SREV_5424,	      AR_SREV_REVISION_MIN,	AR_SREV_REVISION_MAX },	    { AR_SREV_2425,	      AR_SREV_REVISION_MIN,	AR_SREV_REVISION_MAX },	    { AR_SREV_2417,	      AR_SREV_REVISION_MIN,	AR_SREV_REVISION_MAX },	};	int i;	for (i = 0; i < N(macs); i++)		if (macs[i].version == macVersion &&		    macs[i].revMin <= macRev && macRev <= macs[i].revMax)			return AH_TRUE;	return AH_FALSE;#undef N}       /* * Attach for an AR5212 part. */static struct ath_hal *ar5212Attach(uint16_t devid, HAL_SOFTC sc,	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status){#define	AH_EEPROM_PROTECT(ah) \	(IS_PCIE(ah) ? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT)	struct ath_hal_5212 *ahp;	struct ath_hal *ah;	struct ath_hal_rf *rf;	uint32_t val;	uint16_t eeval;	HAL_STATUS ecode;	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",	    __func__, sc, (void*) st, (void*) sh);	/* NB: memory is returned zero'd */	ahp = ath_hal_malloc(sizeof (struct ath_hal_5212));	if (ahp == AH_NULL) {		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,		    "%s: cannot allocate memory for state block\n", __func__);		*status = HAL_ENOMEM;		return AH_NULL;	}	ar5212InitState(ahp, devid, sc, st, sh, status);	ah = &ahp->ah_priv.h;	if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",		    __func__);		ecode = HAL_EIO;		goto bad;	}	/* Read Revisions from Chips before taking out of reset */	val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID;	AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S;	AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION;	if (!ar5212IsMacSupported(AH_PRIVATE(ah)->ah_macVersion, AH_PRIVATE(ah)->ah_macRev)) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: Mac Chip Rev 0x%02x.%x not supported\n" ,		    __func__, AH_PRIVATE(ah)->ah_macVersion,		    AH_PRIVATE(ah)->ah_macRev);		ecode = HAL_ENOTSUPP;		goto bad;	}	/* setup common ini data; rf backends handle remainder */	HAL_INI_INIT(&ahp->ah_ini_modes, ar5212Modes, 6);	HAL_INI_INIT(&ahp->ah_ini_common, ar5212Common, 2);	if (!ar5212ChipReset(ah, AH_NULL)) {	/* reset chip */		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);		ecode = HAL_EIO;		goto bad;	}	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);	if (IS_PCIE(ah)) {		/* XXX: build flag to disable this? */		configurePciePowerSave(ah);	}	if (!ar5212ChipTest(ah)) {		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",		    __func__);		ecode = HAL_ESELFTEST;		goto bad;	}	/* Enable PCI core retry fix in software for Hainan and up */	if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_VENICE)		OS_REG_SET_BIT(ah, AR_PCICFG, AR_PCICFG_RETRYFIXEN);	/*	 * Set correct Baseband to analog shift	 * setting to access analog chips.	 */	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);	/* Read Radio Chip Rev Extract */	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah);	rf = ath_hal_rfprobe(ah, &ecode);	if (rf == AH_NULL)		goto bad;	/* NB: silently accept anything in release code per Atheros */	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {	case AR_RAD5111_SREV_MAJOR:	case AR_RAD5112_SREV_MAJOR:	case AR_RAD2112_SREV_MAJOR:	case AR_RAD2111_SREV_MAJOR:	case AR_RAD2413_SREV_MAJOR:	case AR_RAD5413_SREV_MAJOR:	case AR_RAD5424_SREV_MAJOR:		break;	default:		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {			/*			 * When RF_Silent is used, the			 * analog chip is reset.  So when the system boots			 * up with the radio switch off we cannot determine			 * the RF chip rev.  To workaround this check the			 * mac+phy revs and if Hainan, set the radio rev			 * to Derby.			 */			if (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&			    AH_PRIVATE(ah)->ah_macRev == AR_SREV_HAINAN &&			    AH_PRIVATE(ah)->ah_phyRev == AR_PHYREV_HAINAN) {				AH_PRIVATE(ah)->ah_analog5GhzRev = AR_ANALOG5REV_HAINAN;				break;

⌨️ 快捷键说明

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