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

📄 ar5212_eeprom.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * Copyright (c) 2002-2005 Atheros Communications, Inc. * All rights reserved. * * $Id: ar5212_eeprom.c,v 1.2 2006/10/13 07:10:49 steven Exp $ */#include "opt_ah.h"#ifdef AH_SUPPORT_AR5212#include "ah.h"#include "ah_internal.h"#include "ah_devid.h"#ifdef AH_DEBUG#include "ah_desc.h"			/* NB: for HAL_PHYERR* */#endif#include "ah_eeprom.h"#include "ar5212/ar5212.h"#include "ar5212/ar5212reg.h"#include "ar5212/ar5212phy.h"#ifdef AH_SUPPORT_AR5311#include "ar5212/ar5311reg.h"#endifstatic HAL_BOOL ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan);static HAL_BOOL	ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);#ifdef AH_SUPPORT_WRITE_EEPROMstatic HAL_BOOL	ar5212EepromWrite(struct ath_hal *ah, u_int off, u_int16_t data);#endif static HAL_BOOL	ar5212EepromRead(struct ath_hal *ah, u_int off, u_int16_t *data);static u_int16_t ar5212EepromGetSpurChan(struct ath_hal *ah, u_int16_t spurChan,HAL_BOOL is2GHz);HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, u_int16_t *rfXpdGain);static HAL_BOOL ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,		   int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit,                   int16_t *pMinPower, int16_t *pMaxPower);static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta);static u_int16_t ar5212GetMaxEdgePower(u_int16_t channel, RD_EDGES_POWER *pRdEdgesPower);static u_int16_t interpolate(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight,	u_int16_t targetLeft, u_int16_t targetRight);static void ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,	TRGT_POWER_INFO *powInfo, u_int16_t numChannels, TRGT_POWER_INFO *pNewPower);void ar5212GetLowerUpperValues(u_int16_t v, u_int16_t *lp, u_int16_t listSize,                          u_int16_t *vlo, u_int16_t *vhi);static HAL_BOOL ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, u_int32_t nchans);static HAL_BOOL ar5212GetEepromCapabilityInfo(struct ath_hal *ah, u_int16_t *capField);static HAL_STATUS ar5212EepromDetach(struct ath_hal *ah);static HAL_BOOL ar5212GetEepromNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,	int16_t *nft);			  /* * Read 16 bits of data from offset into *data */HAL_BOOLar5212EepromRead(struct ath_hal *ah, u_int off, u_int16_t *data){	OS_REG_WRITE(ah, AR_EEPROM_ADDR, off);	OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_READ);	if (!ath_hal_wait(ah, AR_EEPROM_STS,   		AR_EEPROM_STS_READ_COMPLETE | AR_EEPROM_STS_READ_ERROR,   		AR_EEPROM_STS_READ_COMPLETE)) {			HALDEBUG(ah, "%s: read failed for entry 0x%x\n", __func__, off);		return AH_FALSE;		}	*data = OS_REG_READ(ah, AR_EEPROM_DATA) & 0xffff;	return AH_TRUE;}#ifdef AH_SUPPORT_WRITE_EEPROM/* * Write 16 bits of data from data to the specified EEPROM offset. */HAL_BOOLar5212EepromWrite(struct ath_hal *ah, u_int off, u_int16_t data){	OS_REG_WRITE(ah, AR_EEPROM_ADDR, off);	OS_REG_WRITE(ah, AR_EEPROM_DATA, data);	OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_WRITE);	if (!ath_hal_wait(ah, AR_EEPROM_STS,	    AR_EEPROM_STS_WRITE_COMPLETE | AR_EEPROM_STS_WRITE_ERROR,	    AR_EEPROM_STS_WRITE_COMPLETE)) {		HALDEBUG(ah, "%s: write failed for entry 0x%x, data 0x%x\n",			__func__, off, data);		return AH_FALSE;	}	return AH_TRUE;}#endif /* AH_SUPPORT_WRITE_EEPROM */HAL_STATUSar5212EepromAttach(struct ath_hal *ah) {	struct ath_hal_5212 *ahp = AH5212(ah);	u_int32_t	i, eepMax, sum, val;	u_int16_t	eeval;	/*	 * 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 };	if (AH_PRIVATE(ah)->ah_eepromRead == AH_NULL)		AH_PRIVATE(ah)->ah_eepromRead = ar5212EepromRead;	//ahp->ah_eepromAttach = ar5212EepromAttach;	ath_hal_printf(ah, "Setting ah_eepromDetach\n");	AH_PRIVATE(ah)->ah_eepromDetach = ar5212EepromDetach;	AH_PRIVATE(ah)->ah_eepromSetBoardValues = ar5212SetBoardValues;	AH_PRIVATE(ah)->ah_eepromGetSpurChan = ar5212EepromGetSpurChan;	AH_PRIVATE(ah)->ah_setTransmitPower = ar5212SetTransmitPower;	AH_PRIVATE(ah)->ah_getChipPowerLimits = ar5212GetChipPowerLimits;	AH_PRIVATE(ah)->ah_getEepromCapabilityInfo = ar5212GetEepromCapabilityInfo;	AH_PRIVATE(ah)->ah_getEepromNoiseFloorThresh = ar5212GetEepromNoiseFloorThresh;		if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_VERSION, &eeval)) {			HALDEBUG(ah, "%s: unable to read EEPROM version\n", __func__);			return HAL_EEREAD;	}	if (eeval < AR_EEPROM_VER3_2) {			HALDEBUG(ah, "%s: unsupported EEPROM version %u (0x%x)\n",				__func__, eeval, eeval);			return HAL_EEVERSION;	}	ahp->ah_eeversion = eeval;	switch (AH_PRIVATE(ah)->ah_devid) {#ifdef AH_SUPPORT_AR5312		u_int16_t data16;		u_int32_t eepEndLoc;	case AR5212_AR5312_REV2:	case AR5212_AR5312_REV7:	case AR5212_AR2313_REV8:	case AR5212_AR2315_REV6:	case AR5212_AR2315_REV7:	case AR5212_AR2317_REV1:		/* Read sizing information */		if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_SIZE_UPPER, &data16)) {			HALDEBUG(ah, "%s: cannot read eeprom upper size\n", __func__);			return HAL_EEREAD;		}                if (data16 == 0) {			eepEndLoc = AR_EEPROM_ATHEROS_MAX_LOC;		} else {			eepEndLoc = (data16 & AR_EEPROM_SIZE_UPPER_MASK) << AR_EEPROM_SIZE_UPPER_SHIFT;			if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_SIZE_LOWER, &data16)) {				HALDEBUG(ah, "%s: cannot read eeprom lower size\n", __func__);				return HAL_EEREAD;			}                }                eepEndLoc |= data16;		if (eepEndLoc < AR_EEPROM_ATHEROS_BASE)			return HAL_EESIZE;		break;#endif	default:		val = OS_REG_READ(ah, AR_PCICFG);		val = MS(val, AR_PCICFG_EEPROM_SIZE);		if (val != AR_PCICFG_EEPROM_SIZE_16K) {			if (AR_PCICFG_EEPROM_SIZE_FAILED == val) {				HALDEBUG(ah, "%s: unsupported EEPROM size "					 "%u (0x%x) found\n", __func__, val, val);				return HAL_EESIZE;			}			if (!IS_5424(ah)) {				HALDEBUG(ah, "%s: EEPROM size = %d. Must be %d (16k).\n", __func__,					 val, AR_PCICFG_EEPROM_SIZE_16K);				return HAL_EESIZE;			}		}	}	if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_PROTECT, &eeval)) {			HALDEBUG(ah, "%s: cannot read EEPROM protection "				"bits; read locked?\n", __func__);			return HAL_EEREAD;	}	HALDEBUG(ah, "EEPROM protect 0x%x\n", eeval);	ahp->ah_eeprotect = eeval;	/* XXX check proper access before continuing */	/*	 * Read the Atheros EEPROM entries and calculate the checksum.	 */	if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_SIZE_UPPER, &eeval)) {			HALDEBUG(ah, "%s: cannot read EEPROM upper size\n" , __func__);			return HAL_EEREAD;		}	if (eeval != 0)	{		eepMax = (eeval & AR_EEPROM_SIZE_UPPER_MASK) <<				AR_EEPROM_SIZE_ENDLOC_SHIFT;		if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_SIZE_LOWER, &eeval)) {				HALDEBUG(ah, "%s: cannot read EEPROM lower size\n" ,					__func__);				return HAL_EEREAD;		}		eepMax = (eepMax | eeval) - AR_EEPROM_ATHEROS_BASE;	} else		eepMax = AR_EEPROM_ATHEROS_MAX;		sum = 0;	for (i = 0; i < eepMax; i++) {		if (!AH_PRIVATE(ah)->ah_eepromRead(ah, AR_EEPROM_ATHEROS(i), &eeval)) {				return HAL_EEREAD;		}		sum ^= eeval;	}	if (sum != 0xffff) {		HALDEBUG(ah, "%s: bad EEPROM checksum 0x%x\n", __func__, sum);		return HAL_EEBADSUM;	}	ahp->ah_numChannels11a = NUM_11A_EEPROM_CHANNELS;	ahp->ah_numChannels2_4 = NUM_2_4_EEPROM_CHANNELS;	for (i = 0; i < NUM_11A_EEPROM_CHANNELS; i ++)		ahp->ah_dataPerChannel11a[i].numPcdacValues = NUM_PCDAC_VALUES;	/* the channel list for 2.4 is fixed, fill this in here */	for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++) {		ahp->ah_channels11b[i] = channels11b[i];		ahp->ah_channels11g[i] = channels11g[i];		ahp->ah_dataPerChannel11b[i].numPcdacValues = NUM_PCDAC_VALUES;		ahp->ah_dataPerChannel11g[i].numPcdacValues = NUM_PCDAC_VALUES;	}	ath_hal_printf(ah,"**** Going to ath_hal_readEepromIntoDataset\n");	if (!ath_hal_readEepromIntoDataset(ah, &ahp->ah_eeprom)) {		return HAL_EEREAD;		/* XXX */	}	if ((ahp->ah_eeversion < AR_EEPROM_VER5_3) && (IS_5413(ah))) {		ahp->ah_eeprom.ee_spurChans[0][1] = AR_SPUR_5413_1;		ahp->ah_eeprom.ee_spurChans[1][1] = AR_SPUR_5413_2;		ahp->ah_eeprom.ee_spurChans[2][1] = AR_NO_SPUR;		ahp->ah_eeprom.ee_spurChans[0][0] = AR_NO_SPUR;	}	return HAL_OK;}//static HAL_STATUSHAL_STATUSar5212EepromDetach(struct ath_hal *ah) {	ath_hal_printf(ah, "In %s\n", __func__);	ath_hal_eepromDetach(ah, &AH5212(ah)->ah_eeprom);	return HAL_OK;}/* * Read EEPROM header info and program the device for correct operation * given the channel value. */HAL_BOOLstatic ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan){#define NO_FALSE_DETECT_BACKOFF   2#define CB22_FALSE_DETECT_BACKOFF 6#define	AR_PHY_BIS(_ah, _reg, _mask, _val) \	OS_REG_WRITE(_ah, AR_PHY(_reg), \		(OS_REG_READ(_ah, AR_PHY(_reg)) & _mask) | (_val));	struct ath_hal_5212 *ahp = AH5212(ah);	int arrayMode, falseDectectBackoff;	int is2GHz = IS_CHAN_2GHZ(chan);	int8_t adcDesiredSize, pgaDesiredSize;	u_int16_t switchSettling, txrxAtten, rxtxMargin;	int iCoff, qCoff;			switch (chan->channelFlags & CHANNEL_ALL) {	case CHANNEL_A:	case CHANNEL_T:	case CHANNEL_XR_A:	case CHANNEL_XR_T:		arrayMode = headerInfo11A;		if (!IS_5112(ah) && !IS_2413(ah) && !IS_5413(ah))			OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,				AR_PHY_FRAME_CTL_TX_CLIP,				ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]);		break;	case CHANNEL_B:		arrayMode = headerInfo11B;		break;	case CHANNEL_G:	case CHANNEL_108G:	case CHANNEL_XR_G:		arrayMode = headerInfo11G;		break;	default:		HALDEBUG(ah, "%s: invalid channel flags 0x%x\n",			__func__, chan->channelFlags);		return AH_FALSE;	}	/* Set the antenna register(s) correctly for the chip revision */	AR_PHY_BIS(ah, 68, 0xFFFFFC06,		(ahp->ah_antennaControl[0][arrayMode] << 4) | 0x1);	ahp->ah_diversityControl &= ~HAL_ANT_OPT_MASK;		ar5212SetAntennaSwitch(ah, ahp->ah_diversityControl,			(HAL_CHANNEL *) chan);	/* Set the Noise Floor Thresh on ar5211 devices */	OS_REG_WRITE(ah, AR_PHY(90),		(ahp->ah_noiseFloorThresh[arrayMode] & 0x1FF)		| (1 << 9));	if (ahp->ah_eeversion >= AR_EEPROM_VER5_0 && IS_CHAN_TURBO(chan)) {		switchSettling = ahp->ah_switchSettlingTurbo[is2GHz];		adcDesiredSize = ahp->ah_adcDesiredSizeTurbo[is2GHz];		pgaDesiredSize = ahp->ah_pgaDesiredSizeTurbo[is2GHz];		txrxAtten = ahp->ah_txrxAttenTurbo[is2GHz];		rxtxMargin = ahp->ah_rxtxMarginTurbo[is2GHz];	} else {		switchSettling = ahp->ah_switchSettling[arrayMode];		adcDesiredSize = ahp->ah_adcDesiredSize[arrayMode];		pgaDesiredSize = ahp->ah_pgaDesiredSize[is2GHz];		txrxAtten = ahp->ah_txrxAtten[is2GHz];		rxtxMargin = ahp->ah_rxtxMargin[is2GHz];	}	OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, 			 AR_PHY_SETTLING_SWITCH, switchSettling);	OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,			 AR_PHY_DESIRED_SZ_ADC, adcDesiredSize);	OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,			 AR_PHY_DESIRED_SZ_PGA, pgaDesiredSize);	OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN,			 AR_PHY_RXGAIN_TXRX_ATTEN, txrxAtten);	OS_REG_WRITE(ah, AR_PHY(13),		(ahp->ah_txEndToXPAOff[arrayMode] << 24)		| (ahp->ah_txEndToXPAOff[arrayMode] << 16)		| (ahp->ah_txFrameToXPAOn[arrayMode] << 8)		| ahp->ah_txFrameToXPAOn[arrayMode]);	AR_PHY_BIS(ah, 10, 0xFFFF00FF,		ahp->ah_txEndToXLNAOn[arrayMode] << 8);	AR_PHY_BIS(ah, 25, 0xFFF80FFF,		(ahp->ah_thresh62[arrayMode] << 12) & 0x7F000);	/*	 * False detect backoff - suspected 32 MHz spur causes false	 * detects in OFDM, causing Tx Hangs.  Decrease weak signal	 * sensitivity for this card.	 */	falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;	if (ahp->ah_eeversion < AR_EEPROM_VER3_3) {		/* XXX magic number */		if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&		    IS_CHAN_OFDM(chan))			falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;	} else {		if (ar5212IsSpurChannel(ah, (HAL_CHANNEL *)chan)) {			falseDectectBackoff += ahp->ah_falseDetectBackoff[arrayMode];		}	}	AR_PHY_BIS(ah, 73, 0xFFFFFF01, (falseDectectBackoff << 1) & 0xF7);	if (chan->iqCalValid) {		iCoff = chan->iCoff;		qCoff = chan->qCoff;	} else {		iCoff = ahp->ah_iqCalI[is2GHz];		qCoff = ahp->ah_iqCalQ[is2GHz];	}	/* write previous IQ results */	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,		AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,		AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);	OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,		AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);	if (ahp->ah_eeversion >= AR_EEPROM_VER4_1) {		if (!IS_CHAN_108G(chan) ||		    ahp->ah_eeversion >= AR_EEPROM_VER5_0)			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,				AR_PHY_GAIN_2GHZ_RXTX_MARGIN, rxtxMargin);	}

⌨️ 快捷键说明

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