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

📄 ar5112.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 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: ar5112.c,v 1.7 2008/11/10 04:08:03 sam Exp $ */#include "opt_ah.h"#include "ah.h"#include "ah_internal.h"#include "ah_eeprom_v3.h"#include "ar5212/ar5212.h"#include "ar5212/ar5212reg.h"#include "ar5212/ar5212phy.h"#define AH_5212_5112#include "ar5212/ar5212.ini"#define	N(a)	(sizeof(a)/sizeof(a[0]))struct ar5112State {	RF_HAL_FUNCS	base;		/* public state, must be first */	uint16_t	pcdacTable[PWR_TABLE_SIZE];	uint32_t	Bank1Data[N(ar5212Bank1_5112)];	uint32_t	Bank2Data[N(ar5212Bank2_5112)];	uint32_t	Bank3Data[N(ar5212Bank3_5112)];	uint32_t	Bank6Data[N(ar5212Bank6_5112)];	uint32_t	Bank7Data[N(ar5212Bank7_5112)];};#define	AR5112(ah)	((struct ar5112State *) AH5212(ah)->ah_rfHal)static	void ar5212GetLowerUpperIndex(uint16_t v,		uint16_t *lp, uint16_t listSize,		uint32_t *vlo, uint32_t *vhi);static HAL_BOOL getFullPwrTable(uint16_t numPcdacs, uint16_t *pcdacs,		int16_t *power, int16_t maxPower, int16_t *retVals);static int16_t getPminAndPcdacTableFromPowerTable(int16_t *pwrTableT4,		uint16_t retVals[]);static int16_t getPminAndPcdacTableFromTwoPowerTables(int16_t *pwrTableLXpdT4,		int16_t *pwrTableHXpdT4, uint16_t retVals[], int16_t *pMid);static int16_t interpolate_signed(uint16_t target,		uint16_t srcLeft, uint16_t srcRight,		int16_t targetLeft, int16_t targetRight);extern	void ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,		uint32_t numBits, uint32_t firstBit, uint32_t column);static voidar5112WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,	int writes){	HAL_INI_WRITE_ARRAY(ah, ar5212Modes_5112, modesIndex, writes);	HAL_INI_WRITE_ARRAY(ah, ar5212Common_5112, 1, writes);	HAL_INI_WRITE_ARRAY(ah, ar5212BB_RfGain_5112, freqIndex, writes);}/* * Take the MHz channel value and set the Channel value * * ASSUMES: Writes enabled to analog bus */static HAL_BOOLar5112SetChannel(struct ath_hal *ah,  HAL_CHANNEL_INTERNAL *chan){	uint32_t channelSel  = 0;	uint32_t bModeSynth  = 0;	uint32_t aModeRefSel = 0;	uint32_t reg32       = 0;	uint16_t freq;	OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);	if (chan->channel < 4800) {		uint32_t txctl;		if (((chan->channel - 2192) % 5) == 0) {			channelSel = ((chan->channel - 672) * 2 - 3040)/10;			bModeSynth = 0;		} else if (((chan->channel - 2224) % 5) == 0) {			channelSel = ((chan->channel - 704) * 2 - 3040) / 10;			bModeSynth = 1;		} else {			HALDEBUG(ah, HAL_DEBUG_ANY,			    "%s: invalid channel %u MHz\n",			    __func__, chan->channel);			return AH_FALSE;		}		channelSel = (channelSel << 2) & 0xff;		channelSel = ath_hal_reverseBits(channelSel, 8);		txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);		if (chan->channel == 2484) {			/* Enable channel spreading for channel 14 */			OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,				txctl | AR_PHY_CCK_TX_CTRL_JAPAN);		} else {			OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,				txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);		}	} else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {		freq = chan->channel - 2; /* Align to even 5MHz raster */		channelSel = ath_hal_reverseBits(			(uint32_t)(((freq - 4800)*10)/25 + 1), 8);            	aModeRefSel = ath_hal_reverseBits(0, 2);	} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {		channelSel = ath_hal_reverseBits(			((chan->channel - 4800) / 20 << 2), 8);		aModeRefSel = ath_hal_reverseBits(3, 2);	} else if ((chan->channel % 10) == 0) {		channelSel = ath_hal_reverseBits(			((chan->channel - 4800) / 10 << 1), 8);		aModeRefSel = ath_hal_reverseBits(2, 2);	} else if ((chan->channel % 5) == 0) {		channelSel = ath_hal_reverseBits(			(chan->channel - 4800) / 5, 8);		aModeRefSel = ath_hal_reverseBits(1, 2);	} else {		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",		    __func__, chan->channel);		return AH_FALSE;	}	reg32 = (channelSel << 4) | (aModeRefSel << 2) | (bModeSynth << 1) |			(1 << 12) | 0x1;	OS_REG_WRITE(ah, AR_PHY(0x27), reg32 & 0xff);	reg32 >>= 8;	OS_REG_WRITE(ah, AR_PHY(0x36), reg32 & 0x7f);	AH_PRIVATE(ah)->ah_curchan = chan;	return AH_TRUE;}/* * Return a reference to the requested RF Bank. */static uint32_t *ar5112GetRfBank(struct ath_hal *ah, int bank){	struct ar5112State *priv = AR5112(ah);	HALASSERT(priv != AH_NULL);	switch (bank) {	case 1: return priv->Bank1Data;	case 2: return priv->Bank2Data;	case 3: return priv->Bank3Data;	case 6: return priv->Bank6Data;	case 7: return priv->Bank7Data;	}	HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n",	    __func__, bank);	return AH_NULL;}/* * Reads EEPROM header info from device structure and programs * all rf registers * * REQUIRES: Access to the analog rf device */static HAL_BOOLar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,	uint16_t modesIndex, uint16_t *rfXpdGain){#define	RF_BANK_SETUP(_priv, _ix, _col) do {				    \	int i;								    \	for (i = 0; i < N(ar5212Bank##_ix##_5112); i++)			    \		(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_5112[i][_col];\} while (0)	struct ath_hal_5212 *ahp = AH5212(ah);	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;	uint16_t rfXpdSel, gainI;	uint16_t ob5GHz = 0, db5GHz = 0;	uint16_t ob2GHz = 0, db2GHz = 0;	struct ar5112State *priv = AR5112(ah);	GAIN_VALUES *gv = &ahp->ah_gainValues;	int regWrites = 0;	HALASSERT(priv);	/* Setup rf parameters */	switch (chan->channelFlags & CHANNEL_ALL) {	case CHANNEL_A:	case CHANNEL_T:		if (chan->channel > 4000 && chan->channel < 5260) {			ob5GHz = ee->ee_ob1;			db5GHz = ee->ee_db1;		} else if (chan->channel >= 5260 && chan->channel < 5500) {			ob5GHz = ee->ee_ob2;			db5GHz = ee->ee_db2;		} else if (chan->channel >= 5500 && chan->channel < 5725) {			ob5GHz = ee->ee_ob3;			db5GHz = ee->ee_db3;		} else if (chan->channel >= 5725) {			ob5GHz = ee->ee_ob4;			db5GHz = ee->ee_db4;		} else {			/* XXX else */		}		rfXpdSel = ee->ee_xpd[headerInfo11A];		gainI = ee->ee_gainI[headerInfo11A];		break;	case CHANNEL_B:		ob2GHz = ee->ee_ob2GHz[0];		db2GHz = ee->ee_db2GHz[0];		rfXpdSel = ee->ee_xpd[headerInfo11B];		gainI = ee->ee_gainI[headerInfo11B];		break;	case CHANNEL_G:	case CHANNEL_108G:		ob2GHz = ee->ee_ob2GHz[1];		db2GHz = ee->ee_ob2GHz[1];		rfXpdSel = ee->ee_xpd[headerInfo11G];		gainI = ee->ee_gainI[headerInfo11G];		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",		    __func__, chan->channelFlags);		return AH_FALSE;	}	/* Setup Bank 1 Write */	RF_BANK_SETUP(priv, 1, 1);	/* Setup Bank 2 Write */	RF_BANK_SETUP(priv, 2, modesIndex);	/* Setup Bank 3 Write */	RF_BANK_SETUP(priv, 3, modesIndex);	/* Setup Bank 6 Write */	RF_BANK_SETUP(priv, 6, modesIndex);	ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdSel,     1, 302, 0);	ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdGain[0], 2, 270, 0);	ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdGain[1], 2, 257, 0);	if (IS_CHAN_OFDM(chan)) {		ar5212ModifyRfBuffer(priv->Bank6Data,			gv->currStep->paramVal[GP_PWD_138], 1, 168, 3);		ar5212ModifyRfBuffer(priv->Bank6Data,			gv->currStep->paramVal[GP_PWD_137], 1, 169, 3);		ar5212ModifyRfBuffer(priv->Bank6Data,			gv->currStep->paramVal[GP_PWD_136], 1, 170, 3);		ar5212ModifyRfBuffer(priv->Bank6Data,			gv->currStep->paramVal[GP_PWD_132], 1, 174, 3);		ar5212ModifyRfBuffer(priv->Bank6Data,			gv->currStep->paramVal[GP_PWD_131], 1, 175, 3);		ar5212ModifyRfBuffer(priv->Bank6Data,			gv->currStep->paramVal[GP_PWD_130], 1, 176, 3);	}	/* Only the 5 or 2 GHz OB/DB need to be set for a mode */	if (IS_CHAN_2GHZ(chan)) {		ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz, 3, 287, 0);		ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz, 3, 290, 0);	} else {		ar5212ModifyRfBuffer(priv->Bank6Data, ob5GHz, 3, 279, 0);		ar5212ModifyRfBuffer(priv->Bank6Data, db5GHz, 3, 282, 0);	}		/* Lower synth voltage for X112 Rev 2.0 only */	if (IS_RADX112_REV2(ah)) {		/* Non-Reversed analyg registers - so values are pre-reversed */		ar5212ModifyRfBuffer(priv->Bank6Data, 2, 2, 90, 2);		ar5212ModifyRfBuffer(priv->Bank6Data, 2, 2, 92, 2);		ar5212ModifyRfBuffer(priv->Bank6Data, 2, 2, 94, 2);		ar5212ModifyRfBuffer(priv->Bank6Data, 2, 1, 254, 2);	}    /* Decrease Power Consumption for 5312/5213 and up */    if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {        ar5212ModifyRfBuffer(priv->Bank6Data, 1, 1, 281, 1);        ar5212ModifyRfBuffer(priv->Bank6Data, 1, 2, 1, 3);        ar5212ModifyRfBuffer(priv->Bank6Data, 1, 2, 3, 3);        ar5212ModifyRfBuffer(priv->Bank6Data, 1, 1, 139, 3);        ar5212ModifyRfBuffer(priv->Bank6Data, 1, 1, 140, 3);    }	/* Setup Bank 7 Setup */	RF_BANK_SETUP(priv, 7, modesIndex);	if (IS_CHAN_OFDM(chan))		ar5212ModifyRfBuffer(priv->Bank7Data,			gv->currStep->paramVal[GP_MIXGAIN_OVR], 2, 37, 0);	ar5212ModifyRfBuffer(priv->Bank7Data, gainI, 6, 14, 0);	/* Adjust params for Derby TX power control */	if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {        	uint32_t	rfDelay, rfPeriod;        	rfDelay = 0xf;        	rfPeriod = (IS_CHAN_HALF_RATE(chan)) ?  0x8 : 0xf;        	ar5212ModifyRfBuffer(priv->Bank7Data, rfDelay, 4, 58, 0);        	ar5212ModifyRfBuffer(priv->Bank7Data, rfPeriod, 4, 70, 0);	}#ifdef notyet	/* Analog registers are setup - EAR can modify */	if (ar5212IsEarEngaged(pDev, chan))		uint32_t modifier;		ar5212EarModify(pDev, EAR_LC_RF_WRITE, chan, &modifier);#endif	/* Write Analog registers */	HAL_INI_WRITE_BANK(ah, ar5212Bank1_5112, priv->Bank1Data, regWrites);	HAL_INI_WRITE_BANK(ah, ar5212Bank2_5112, priv->Bank2Data, regWrites);	HAL_INI_WRITE_BANK(ah, ar5212Bank3_5112, priv->Bank3Data, regWrites);	HAL_INI_WRITE_BANK(ah, ar5212Bank6_5112, priv->Bank6Data, regWrites);	HAL_INI_WRITE_BANK(ah, ar5212Bank7_5112, priv->Bank7Data, regWrites);	/* Now that we have reprogrammed rfgain value, clear the flag. */	ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;	return AH_TRUE;#undef	RF_BANK_SETUP}/* * Read the transmit power levels from the structures taken from EEPROM * Interpolate read transmit power values for this channel * Organize the transmit power values into a table for writing into the hardware */static HAL_BOOLar5112SetPowerTable(struct ath_hal *ah,	int16_t *pPowerMin, int16_t *pPowerMax, HAL_CHANNEL_INTERNAL *chan,	uint16_t *rfXpdGain){	struct ath_hal_5212 *ahp = AH5212(ah);	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;	uint32_t numXpdGain = IS_RADX112_REV2(ah) ? 2 : 1;	uint32_t    xpdGainMask = 0;	int16_t     powerMid, *pPowerMid = &powerMid;	const EXPN_DATA_PER_CHANNEL_5112 *pRawCh;	const EEPROM_POWER_EXPN_5112     *pPowerExpn = AH_NULL;	uint32_t    ii, jj, kk;	int16_t     minPwr_t4, maxPwr_t4, Pmin, Pmid;	uint32_t    chan_idx_L = 0, chan_idx_R = 0;	uint16_t    chan_L, chan_R;	int16_t     pwr_table0[64];	int16_t     pwr_table1[64];	uint16_t    pcdacs[10];	int16_t     powers[10];	uint16_t    numPcd;	int16_t     powTableLXPD[2][64];	int16_t     powTableHXPD[2][64];	int16_t     tmpPowerTable[64];	uint16_t    xgainList[2];	uint16_t    xpdMask;	switch (chan->channelFlags & CHANNEL_ALL) {	case CHANNEL_A:	case CHANNEL_T:		pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11A];		xpdGainMask = ee->ee_xgain[headerInfo11A];		break;	case CHANNEL_B:		pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11B];		xpdGainMask = ee->ee_xgain[headerInfo11B];		break;	case CHANNEL_G:	case CHANNEL_108G:		pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11G];		xpdGainMask = ee->ee_xgain[headerInfo11G];		break;	default:		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown channel flags 0x%x\n",		    __func__, chan->channelFlags & CHANNEL_ALL);		return AH_FALSE;	}	if ((xpdGainMask & pPowerExpn->xpdMask) < 1) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s: desired xpdGainMask 0x%x not supported by "		    "calibrated xpdMask 0x%x\n", __func__,		    xpdGainMask, pPowerExpn->xpdMask);		return AH_FALSE;	}	maxPwr_t4 = (int16_t)(2*(*pPowerMax));	/* pwr_t2 -> pwr_t4 */	minPwr_t4 = (int16_t)(2*(*pPowerMin));	/* pwr_t2 -> pwr_t4 */	xgainList[0] = 0xDEAD;	xgainList[1] = 0xDEAD;	kk = 0;	xpdMask = pPowerExpn->xpdMask;	for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++) {		if (((xpdMask >> jj) & 1) > 0) {			if (kk > 1) {				HALDEBUG(ah, HAL_DEBUG_ANY,				    "A maximum of 2 xpdGains supported"				    "in pExpnPower data\n");				return AH_FALSE;			}			xgainList[kk++] = (uint16_t)jj;		}	}	ar5212GetLowerUpperIndex(chan->channel, &pPowerExpn->pChannels[0],		pPowerExpn->numChannels, &chan_idx_L, &chan_idx_R);	kk = 0;	for (ii = chan_idx_L; ii <= chan_idx_R; ii++) {		pRawCh = &(pPowerExpn->pDataPerChannel[ii]);		if (xgainList[1] == 0xDEAD) {			jj = xgainList[0];			numPcd = pRawCh->pDataPerXPD[jj].numPcdacs;			OS_MEMCPY(&pcdacs[0], &pRawCh->pDataPerXPD[jj].pcdac[0],				numPcd * sizeof(uint16_t));			OS_MEMCPY(&powers[0], &pRawCh->pDataPerXPD[jj].pwr_t4[0],				numPcd * sizeof(int16_t));			if (!getFullPwrTable(numPcd, &pcdacs[0], &powers[0],				pRawCh->maxPower_t4, &tmpPowerTable[0])) {				return AH_FALSE;			}			OS_MEMCPY(&powTableLXPD[kk][0], &tmpPowerTable[0],				64*sizeof(int16_t));		} else {			jj = xgainList[0];			numPcd = pRawCh->pDataPerXPD[jj].numPcdacs;			OS_MEMCPY(&pcdacs[0], &pRawCh->pDataPerXPD[jj].pcdac[0],

⌨️ 快捷键说明

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