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

📄 ar5212_attach.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * Copyright (c) 2002-2005 Atheros Communications, Inc. * All rights reserved. * * $Id: ar5212_attach.c,v 1.3 2006/10/13 07:10:49 steven Exp $ */#include "opt_ah.h"#ifdef AH_SUPPORT_AR5212#if !defined(AH_SUPPORT_5112) && !defined(AH_SUPPORT_5111) && !defined(AH_SUPPORT_2413) && !defined (AH_SUPPORT_5413)#error "No 5212 RF support defined"#endif#include "ah.h"#include "ah_internal.h"#include "ah_devid.h"#include "ar5212/ar5212.h"#include "ar5212/ar5212reg.h"#include "ar5212/ar5212phy.h"#ifdef AH_SUPPORT_AR5311#include "ar5212/ar5311reg.h"#endifstatic HAL_BOOL	ar5212GetChipPowerLimits(struct ath_hal *ah,		HAL_CHANNEL *chans, u_int32_t nchans);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_setPCUConfig		= ar5212SetPCUConfig,	.ah_perCalibration		= ar5212PerCalibration,	.ah_setTxPowerLimit		= ar5212SetTxPowerLimit,	/* AR/Radar Functions */	.ah_checkDfs			= ar5212CheckDfs,	.ah_dfsFound			= ar5212DfsFound,	.ah_enableDfs			= ar5212EnableDfs,	.ah_getDfsThresh		= ar5212GetDfsThresh,	.ah_radarWait                   = ar5212RadarWait,		/* Xr Functions */	.ah_xrEnable			= ar5212XrEnable,	.ah_xrDisable			= ar5212XrDisable,	/* 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_updateCTSForBursting	= ar5212UpdateCTSForBursting,		.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			= ar5212AniArPoll,	.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_setSlotTime			= ar5212SetSlotTime,	.ah_getSlotTime			= ar5212GetSlotTime,	.ah_setAckTimeout		= ar5212SetAckTimeout,	.ah_getAckTimeout		= ar5212GetAckTimeout,	.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_beaconInit			= ar5212BeaconInit,	.ah_setStationBeaconTimers	= ar5212SetStaBeaconTimers,	.ah_resetStationBeaconTimers	= ar5212ResetStaBeaconTimers,	.ah_waitForBeaconDone		= ar5212WaitForBeaconDone,	/* Interrupt Functions */	.ah_isInterruptPending		= ar5212IsInterruptPending,	.ah_getPendingInterrupts	= ar5212GetPendingInterrupts,	.ah_getInterrupts		= ar5212GetInterrupts,	.ah_setInterrupts		= ar5212SetInterrupts },	.ah_getChannelEdges		= ar5212GetChannelEdges,	.ah_getWirelessModes		= ar5212GetWirelessModes,	.ah_eepromAttach		= ar5212EepromAttach,#if 0	.ah_eepromRead			= ar5212EepromRead,	.ah_eepromAttach		= ar5212EepromAttach,#ifdef AH_SUPPORT_WRITE_EEPROM	.ah_eepromWrite			= ar5212EepromWrite,#endif	.ah_eepromSetBoardValues	= ar5212SetBoardValues,#endif	.ah_gpioCfgOutput		= ar5212GpioCfgOutput,	.ah_gpioCfgInput		= ar5212GpioCfgInput,	.ah_gpioGet			= ar5212GpioGet,	.ah_gpioSet			= ar5212GpioSet,	.ah_gpioSetIntr			= ar5212GpioSetIntr,//	.ah_getChipPowerLimits		= ar5212GetChipPowerLimits,};#if 0/* * TODO: Need to talk to Praveen about this, these are * not valid 2.4 channels, either we change these * or I need to change the beanie coding to accept these */static const u_int16_t channels11b[] = { 2412, 2447, 2484 };static const u_int16_t channels11g[] = { 2312, 2412, 2484 };#endif/* * 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. */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);}u_int32_tar5212GetRadioRev(struct ath_hal *ah){	u_int32_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){	struct ath_hal_5212 *ahp = AH5212(ah);	int i;#if 0	const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };	const int coarseHigh[]       = { -14, -14, -14, -14, -12 };	const int coarseLow[]        = { -64, -64, -64, -64, -70 };	const int firpwr[]           = { -78, -78, -78, -78, -80 };#endif	const int totalSizeDesired[] = { -55, -55, -55, -55, -68 };	const int coarseHigh[]       = { -14, -14, -14, -14, -14 };	const int coarseLow[]        = { -64, -64, -64, -64, -64 };	const int firpwr[]           = { -78, -78, -78, -78, -78 };	for (i = 0; i < 5; i++) {		ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];		ahp->ah_coarseHigh[i] = coarseHigh[i];		ahp->ah_coarseLow[i] = coarseLow[i];		ahp->ah_firpwr[i] = firpwr[i];	}}/* * Attach for an AR5212 part. */struct ath_hal_5212 *ar5212NewState(u_int16_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 u_int8_t defbssidmask[IEEE80211_ADDR_LEN] =		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };	struct ath_hal_5212 *ahp;	struct ath_hal *ah;	*status = 0;	/* NB: memory is returned zero'd */	ahp = ath_hal_malloc(sizeof (struct ath_hal_5212));	if (ahp == AH_NULL) {		HALDEBUG(AH_NULL, "%s: cannot allocate memory for "			"state block\n", __func__);		*status = HAL_ENOMEM;		return AH_NULL;	}	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_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_atimWindow = 0;			/* [0..1000] */	ahp->ah_diversityControl = HAL_ANT_VARIABLE;	ahp->ah_bIQCalibration = AH_FALSE;	/*	 * Enable MIC handling.	 */	ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;	ahp->ah_tpcEnabled = AH_FALSE;		/* disabled by default */	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;	OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);	/*	 * 11g-specific stuff	 */	ahp->ah_gBeaconRate = 0;		/* adhoc beacon fixed rate */	return ahp;#undef N}       /* * Attach for an AR5212 part. */struct ath_hal *ar5212Attach(u_int16_t devid, HAL_SOFTC sc,	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status){	struct ath_hal_5212 *ahp=AH_NULL;	struct ath_hal *ah=AH_NULL;	//u_int i;	//u_int32_t sum;	u_int32_t val=0;	//u_int32_t eepMax;	//u_int16_t eeval;	HAL_STATUS ecode=0;	HAL_BOOL rfStatus=0;	HALDEBUG(AH_NULL, "%s: sc %p st %u sh %p\n",		__func__, sc, st, (void*) sh);	/* NB: memory is returned zero'd */	ahp = ar5212NewState(devid, sc, st, sh, status);	if (ahp == AH_NULL) 		return AH_NULL;	ah = &ahp->ah_priv.h;	if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {		HALDEBUG(ah, "%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;		/* copy mac version and revision to public structure */	AH_PRIVATE(ah)->h.ah_macVersion = AH_PRIVATE(ah)->ah_macVersion;	AH_PRIVATE(ah)->h.ah_macRev = AH_PRIVATE(ah)->ah_macRev;	HALDEBUG(ah, "%s: Mac Chip Rev 0x%02x.%03x  \n" , __func__,			AH_PRIVATE(ah)->ah_macVersion,			AH_PRIVATE(ah)->ah_macRev);	        if ((AH_PRIVATE(ah)->ah_macVersion != AR_SREV_VERSION_VENICE &&	     AH_PRIVATE(ah)->ah_macVersion != AR_SREV_VERSION_GRIFFIN &&	     AH_PRIVATE(ah)->ah_macVersion != AR_SREV_5413 &&	     AH_PRIVATE(ah)->ah_macVersion != AR_SREV_5424) ||	    AH_PRIVATE(ah)->ah_macRev < AR_SREV_D2PLUS) {		HALDEBUG(ah, "%s: Mac Chip Rev 0x%02x.%x is not supported by "			"this driver\n", __func__,			AH_PRIVATE(ah)->ah_macVersion,			AH_PRIVATE(ah)->ah_macRev);		ecode = HAL_ENOTSUPP;		goto bad;	}	if (!ar5212ChipReset(ah, AH_NULL)) {	/* reset chip */		HALDEBUG(ah, "%s: chip reset failed\n", __func__);		ecode = HAL_EIO;		goto bad;	}	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);	AH_PRIVATE(ah)->h.ah_phyRev = AH_PRIVATE(ah)->ah_phyRev;	if (IS_5424(ah)) {		/* XXX: build flag to disable this? */		configurePciePowerSave(ah);	}	if (!ar5212ChipTest(ah)) {		HALDEBUG(ah, "%s: hardware self-test failed\n", __func__);		ecode = HAL_ESELFTEST;		goto bad;	}	/*	 * 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);	AH_PRIVATE(ah)->h.ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev;	/* 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_RAD2111_SREV_MAJOR:	case AR_SREV_2413:	case AR_SREV_5413:	case AR_RAD2413_SREV_MAJOR:	case AR_RAD5413_SREV_MAJOR:	case AR_RAD5424_SREV_MAJOR:		break;	default:		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {			/*			 * WAR for bug 10062.  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;

⌨️ 快捷键说明

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