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

📄 ar5413.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * Copyright (c) 2004 Atheros Communications, Inc. * All rights reserved. * * $Id: ar5413.c,v 1.1.1.1 2006/09/12 03:45:28 steven Exp $ * $File: //depot/sw/releases/linuxsrc/src/802_11/madwifi/hal/main/ar5212/ar5413.c $ * $Author: steven $ * $DateTime: 2006/05/25 22:01:10 $ * $Change: 171292 $ * */#include "opt_ah.h"#ifdef AH_SUPPORT_5413#include "ah.h"#include "ah_internal.h"#include "ar5212/ar5212.h"#include "ar5212/ar5212reg.h"#include "ar5212/ar5212phy.h"/* Add static register initialization vectors */#define AH_5212_5413#include "ar5212/ar5212.ini"#define	N(a)	(sizeof(a)/sizeof(a[0]))typedef struct {	u_int32_t Bank1Data[N(ar5212Bank1_5413)];	u_int32_t Bank2Data[N(ar5212Bank2_5413)];	u_int32_t Bank3Data[N(ar5212Bank3_5413)];	u_int32_t Bank6Data[N(ar5212Bank6_5413)];	u_int32_t Bank7Data[N(ar5212Bank7_5413)];} AR5212_RF_BANKS_5413;/* * WAR for bug 6773.  OS_DELAY() does a PIO READ on the PCI bus which allows * other cards' DMA reads to complete in the middle of our reset. */#define WAR_6773(x) do {		\	if ((++(x) % 64) == 0)		\		OS_DELAY(1);		\} while (0)#define REG_WRITE_ARRAY(regArray, column, regWr) do {			\	int r;								\	for (r = 0; r < N(regArray); r++) {				\		OS_REG_WRITE(ah, (regArray)[r][0], (regArray)[r][(column)]);\		WAR_6773(regWr);					\	}								\} while (0)#define REG_WRITE_RF_ARRAY(regArray, regData, regWr) do {               \	int r;								\	for (r = 0; r < N(regArray); r++) {				\		OS_REG_WRITE(ah, (regArray)[r][0], (regData)[r]);	\		WAR_6773(regWr);					\	}								\} while (0)extern	void ar5212ModifyRfBuffer(u_int32_t *rfBuf, u_int32_t reg32,		u_int32_t numBits, u_int32_t firstBit, u_int32_t column);static voidar5413WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, int regWrites){	REG_WRITE_ARRAY(ar5212Modes_5413, modesIndex, regWrites);	REG_WRITE_ARRAY(ar5212Common_5413, 1, regWrites);	REG_WRITE_ARRAY(ar5212BB_RfGain_5413, freqIndex, regWrites);}/* * Take the MHz channel value and set the Channel value * * ASSUMES: Writes enabled to analog bus */static HAL_BOOLar5413SetChannel(struct ath_hal *ah,  HAL_CHANNEL_INTERNAL *chan){	u_int32_t channelSel  = 0;	u_int32_t bModeSynth  = 0;	u_int32_t aModeRefSel = 0;	u_int32_t reg32       = 0;	u_int16_t freq;	OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);	if (chan->channel < 4800) {		u_int32_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, "%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(			(u_int32_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(1, 2);	} else if ((chan->channel % 10) == 0) {		channelSel = ath_hal_reverseBits(			((chan->channel - 4800) / 10 << 1), 8);		aModeRefSel = ath_hal_reverseBits(1, 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, "%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;}/* * Reads EEPROM header info from device structure and programs * all rf registers * * REQUIRES: Access to the analog rf device */static HAL_BOOLar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, u_int16_t modesIndex, u_int16_t *rfXpdGain){#define	RF_BANK_SETUP(_pb, _ix, _col) do {				    \	int i;								    \	for (i = 0; i < N(ar5212Bank##_ix##_5413); i++)			    \		(_pb)->Bank##_ix##Data[i] = ar5212Bank##_ix##_5413[i][_col];\} while (0)	struct ath_hal_5212 *ahp = AH5212(ah);	u_int16_t ob5GHz = 0, db5GHz = 0;		u_int16_t ob2GHz = 0, db2GHz = 0;	AR5212_RF_BANKS_5413 *pRfBanks;	int regWrites = 0;	HALDEBUG(ah, "==>%s:chan 0x%x flag 0x%x modesIndex 0x%x\n", 		 __func__, chan->channel, chan->channelFlags, modesIndex);	pRfBanks = ahp->ah_analogBanks;	HALASSERT(pRfBanks);	/* Setup rf parameters */	switch (chan->channelFlags & CHANNEL_ALL) {	case CHANNEL_A:	case CHANNEL_T:		if (chan->channel > 4000 && chan->channel < 5260) {			ob5GHz = ahp->ah_ob1;			db5GHz = ahp->ah_db1;		} else if (chan->channel >= 5260 && chan->channel < 5500) {			ob5GHz = ahp->ah_ob2;			db5GHz = ahp->ah_db2;		} else if (chan->channel >= 5500 && chan->channel < 5725) {			ob5GHz = ahp->ah_ob3;			db5GHz = ahp->ah_db3;		} else if (chan->channel >= 5725) {			ob5GHz = ahp->ah_ob4;			db5GHz = ahp->ah_db4;		} else {			/* XXX else */		}		break;	case CHANNEL_B:		ob2GHz = ahp->ah_obFor24;		db2GHz = ahp->ah_dbFor24;		break;	case CHANNEL_G:	case CHANNEL_108G:		ob2GHz = ahp->ah_obFor24g;		db2GHz = ahp->ah_dbFor24g;		break;	default:		HALDEBUG(ah, "%s: invalid channel flags 0x%x\n",			 __func__, chan->channelFlags);		return AH_FALSE;	}	/* Bank 1 Write */	RF_BANK_SETUP(pRfBanks, 1, 1);	/* Bank 2 Write */	RF_BANK_SETUP(pRfBanks, 2, modesIndex);	/* Bank 3 Write */	RF_BANK_SETUP(pRfBanks, 3, modesIndex);	/* Bank 6 Write */	RF_BANK_SETUP(pRfBanks, 6, modesIndex);    	/* Only the 5 or 2 GHz OB/DB need to be set for a mode */	if (IS_CHAN_2GHZ(chan)) {        	ar5212ModifyRfBuffer(pRfBanks->Bank6Data, ob2GHz, 3, 241, 0);        	ar5212ModifyRfBuffer(pRfBanks->Bank6Data, db2GHz, 3, 238, 0);			/* TODO - only for Eagle 1.0 2GHz - remove for production */			/* XXX: but without this bit G doesn't work. */			ar5212ModifyRfBuffer(pRfBanks->Bank6Data, 1 , 1, 291, 2);			/* Optimum value for rf_pwd_iclobuf2G for PCIe chips only */			if (IS_PCIE(ah)) {				ar5212ModifyRfBuffer(pRfBanks->Bank6Data, ath_hal_reverseBits(6, 3),						 3, 131, 3);			}	} else {        	ar5212ModifyRfBuffer(pRfBanks->Bank6Data, ob5GHz, 3, 247, 0);        	ar5212ModifyRfBuffer(pRfBanks->Bank6Data, db5GHz, 3, 244, 0);	}	/* Bank 7 Setup */	RF_BANK_SETUP(pRfBanks, 7, modesIndex);	/* Write Analog registers */	REG_WRITE_RF_ARRAY(ar5212Bank1_5413, pRfBanks->Bank1Data, regWrites);	REG_WRITE_RF_ARRAY(ar5212Bank2_5413, pRfBanks->Bank2Data, regWrites);	REG_WRITE_RF_ARRAY(ar5212Bank3_5413, pRfBanks->Bank3Data, regWrites);	REG_WRITE_RF_ARRAY(ar5212Bank6_5413, pRfBanks->Bank6Data, regWrites);	REG_WRITE_RF_ARRAY(ar5212Bank7_5413, pRfBanks->Bank7Data, regWrites);	/* Now that we have reprogrammed rfgain value, clear the flag. */	ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;	HALDEBUG(ah, "<==%s\n", __func__);	return AH_TRUE;#undef	RF_BANK_SETUP}/* * Return a reference to the requested RF Bank. */static u_int32_t *ar5413GetRfBank(struct ath_hal *ah, int bank){	struct ath_hal_5212 *ahp = AH5212(ah);	AR5212_RF_BANKS_5413 *pRfBank5413 = ahp->ah_analogBanks;	HALASSERT(ahp->ah_analogBanks != AH_NULL);	switch (bank) {	case 1: return pRfBank5413->Bank1Data;	case 2: return pRfBank5413->Bank2Data;	case 3: return pRfBank5413->Bank3Data;	case 6: return pRfBank5413->Bank6Data;	case 7: return pRfBank5413->Bank7Data;	}	HALDEBUG(ah, "%s: unknown RF Bank %d requested\n", __func__, bank);	return AH_NULL;}/* * Return indices surrounding the value in sorted integer lists. * * NB: the input list is assumed to be sorted in ascending order */static voidGetLowerUpperIndex(int16_t v, u_int16_t *lp, u_int16_t listSize,                          u_int32_t *vlo, u_int32_t *vhi){	int16_t target = v;	u_int16_t *ep = lp+listSize;	u_int16_t *tp;	/*	 * Check first and last elements for out-of-bounds conditions.	 */	if (target < lp[0]) {		*vlo = *vhi = 0;		return;	}	if (target >= ep[-1]) {		*vlo = *vhi = listSize - 1;		return;	}	/* look for value being near or between 2 values in list */	for (tp = lp; tp < ep; tp++) {		/*		 * If value is close to the current value of the list		 * then target is not between values, it is one of the values		 */		if (*tp == target) {			*vlo = *vhi = tp - (u_int16_t *) lp;			return;		}		/*		 * Look for value being between current value and next value		 * if so return these 2 values		 */		if (target < tp[1]) {			*vlo = tp - (u_int16_t *) lp;			*vhi = *vlo + 1;			return;		}	}}/* * Fill the Vpdlist for indices Pmax-Pmin */static HAL_BOOLar5413FillVpdTable(u_int32_t pdGainIdx, int16_t Pmin, int16_t  Pmax,		   int16_t *pwrList, u_int16_t *VpdList, u_int16_t numIntercepts,		   u_int16_t retVpdList[][64]){	u_int16_t ii, jj, kk;	int16_t currPwr = (int16_t)(2*Pmin);	/* since Pmin is pwr*2 and pwrList is 4*pwr */	u_int32_t  idxL, idxR;	ii = 0;	jj = 0;	if (numIntercepts < 2)		return AH_FALSE;	while (ii <= (u_int16_t)(Pmax - Pmin)) {		GetLowerUpperIndex(currPwr, (u_int16_t *) pwrList,				   numIntercepts, &(idxL), &(idxR));		if (idxR < 1)			idxR = 1;			/* extrapolate below */		if (idxL == (u_int32_t)(numIntercepts - 1))			idxL = numIntercepts - 2;	/* extrapolate above */		if (pwrList[idxL] == pwrList[idxR])			kk = VpdList[idxL];		else			kk = (u_int16_t)				(((currPwr - pwrList[idxL])*VpdList[idxR]+ 				  (pwrList[idxR] - currPwr)*VpdList[idxL])/				 (pwrList[idxR] - pwrList[idxL]));		retVpdList[pdGainIdx][ii] = kk;		ii++;		currPwr += 2;				/* half dB steps */	}	return AH_TRUE;}/* * Returns interpolated or the scaled up interpolated value */static int16_tinterpolate_signed(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight,	int16_t targetLeft, int16_t targetRight){	int16_t rv;	if (srcRight != srcLeft) {		rv = ((target - srcLeft)*targetRight +		      (srcRight - target)*targetLeft) / (srcRight - srcLeft);	} else {		rv = targetLeft;	}	return rv;}

⌨️ 快捷键说明

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