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

📄 ah_eeprom_v3.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
/* * 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: ah_eeprom_v3.c,v 1.4 2008/11/27 22:39:42 sam Exp $ */#include "opt_ah.h"#include "ah.h"#include "ah_internal.h"#include "ah_eeprom_v3.h"static voidgetPcdacInterceptsFromPcdacMinMax(HAL_EEPROM *ee,	uint16_t pcdacMin, uint16_t pcdacMax, uint16_t *vp){	const static uint16_t intercepts3[] =		{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };	const static uint16_t intercepts3_2[] =		{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };	const uint16_t *ip = ee->ee_version < AR_EEPROM_VER3_2 ?		intercepts3 : intercepts3_2;	int i;	/* loop for the percentages in steps or 5 */	for (i = 0; i < NUM_INTERCEPTS; i++ )		*vp++ = (ip[i] * pcdacMax + (100 - ip[i]) * pcdacMin) / 100;}/* * Get channel value from binary representation held in eeprom */static uint16_tfbin2freq(HAL_EEPROM *ee, uint16_t fbin){	if (fbin == CHANNEL_UNUSED)	/* reserved value, don't convert */		return fbin;	return ee->ee_version <= AR_EEPROM_VER3_2 ?		(fbin > 62 ? 5100 + 10*62 + 5*(fbin-62) : 5100 + 10*fbin) :		4800 + 5*fbin;}static uint16_tfbin2freq_2p4(HAL_EEPROM *ee, uint16_t fbin){	if (fbin == CHANNEL_UNUSED)	/* reserved value, don't convert */		return fbin;	return ee->ee_version <= AR_EEPROM_VER3_2 ?		2400 + fbin :		2300 + fbin;}/* * Now copy EEPROM frequency pier contents into the allocated space */static HAL_BOOLreadEepromFreqPierInfo(struct ath_hal *ah, HAL_EEPROM *ee){#define	EEREAD(_off) do {				\	if (!ath_hal_eepromRead(ah, _off, &eeval))	\		return AH_FALSE;			\} while (0)	uint16_t eeval, off;	int i;	if (ee->ee_version >= AR_EEPROM_VER4_0 &&	    ee->ee_eepMap && !ee->ee_Amode) {		/*		 * V4.0 EEPROMs with map type 1 have frequency pier		 * data only when 11a mode is supported.		 */		return AH_TRUE;	}	if (ee->ee_version >= AR_EEPROM_VER3_3) {		off = GROUPS_OFFSET3_3 + GROUP1_OFFSET;		for (i = 0; i < ee->ee_numChannels11a; i += 2) {			EEREAD(off++);			ee->ee_channels11a[i]   = (eeval >> 8) & FREQ_MASK_3_3;			ee->ee_channels11a[i+1] = eeval & FREQ_MASK_3_3;		} 	} else {		off = GROUPS_OFFSET3_2 + GROUP1_OFFSET;		EEREAD(off++);		ee->ee_channels11a[0] = (eeval >> 9) & FREQ_MASK;		ee->ee_channels11a[1] = (eeval >> 2) & FREQ_MASK;		ee->ee_channels11a[2] = (eeval << 5) & FREQ_MASK;		EEREAD(off++);		ee->ee_channels11a[2] |= (eeval >> 11) & 0x1f;		ee->ee_channels11a[3]  = (eeval >>  4) & FREQ_MASK;		ee->ee_channels11a[4]  = (eeval <<  3) & FREQ_MASK;		EEREAD(off++);		ee->ee_channels11a[4] |= (eeval >> 13) & 0x7;		ee->ee_channels11a[5]  = (eeval >>  6) & FREQ_MASK;		ee->ee_channels11a[6]  = (eeval <<  1) & FREQ_MASK;		EEREAD(off++);		ee->ee_channels11a[6] |= (eeval >> 15) & 0x1;		ee->ee_channels11a[7]  = (eeval >>  8) & FREQ_MASK;		ee->ee_channels11a[8]  = (eeval >>  1) & FREQ_MASK;		ee->ee_channels11a[9]  = (eeval <<  6) & FREQ_MASK;		EEREAD(off++);		ee->ee_channels11a[9] |= (eeval >> 10) & 0x3f;	}	for (i = 0; i < ee->ee_numChannels11a; i++)		ee->ee_channels11a[i] = fbin2freq(ee, ee->ee_channels11a[i]);	return AH_TRUE;#undef EEREAD}/* * Rev 4 Eeprom 5112 Power Extract Functions *//* * Allocate the power information based on the number of channels * recorded by the calibration.  These values are then initialized. */static HAL_BOOLeepromAllocExpnPower5112(struct ath_hal *ah,	const EEPROM_POWER_5112 *pCalDataset,	EEPROM_POWER_EXPN_5112 *pPowerExpn){	uint16_t numChannels = pCalDataset->numChannels;	const uint16_t *pChanList = pCalDataset->pChannels;	void *data;	int i, j;	/* Allocate the channel and Power Data arrays together */	data = ath_hal_malloc(		roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t)) +		sizeof(EXPN_DATA_PER_CHANNEL_5112) * numChannels);	if (data == AH_NULL) {		HALDEBUG(ah, HAL_DEBUG_ANY,		    "%s unable to allocate raw data struct (gen3)\n", __func__);		return AH_FALSE;	}	pPowerExpn->pChannels = data;	pPowerExpn->pDataPerChannel = (void *)(((char *)data) +		roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t)));	pPowerExpn->numChannels = numChannels;	for (i = 0; i < numChannels; i++) {		pPowerExpn->pChannels[i] =			pPowerExpn->pDataPerChannel[i].channelValue =				pChanList[i];		for (j = 0; j < NUM_XPD_PER_CHANNEL; j++) {			pPowerExpn->pDataPerChannel[i].pDataPerXPD[j].xpd_gain = j;			pPowerExpn->pDataPerChannel[i].pDataPerXPD[j].numPcdacs = 0;		}		pPowerExpn->pDataPerChannel[i].pDataPerXPD[0].numPcdacs = 4;		pPowerExpn->pDataPerChannel[i].pDataPerXPD[3].numPcdacs = 3;	}	return AH_TRUE;}/* * Expand the dataSet from the calibration information into the * final power structure for 5112 */static HAL_BOOLeepromExpandPower5112(struct ath_hal *ah,	const EEPROM_POWER_5112 *pCalDataset,	EEPROM_POWER_EXPN_5112 *pPowerExpn){	int ii, jj, kk;	int16_t maxPower_t4;	EXPN_DATA_PER_XPD_5112 *pExpnXPD;	/* ptr to array of info held per channel */	const EEPROM_DATA_PER_CHANNEL_5112 *pCalCh;	uint16_t xgainList[2], xpdMask;	pPowerExpn->xpdMask = pCalDataset->xpdMask;	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,				    "%s: too many xpdGains in dataset: %u\n",				    __func__, kk);				return AH_FALSE;			}			xgainList[kk++] = jj;		}	}	pPowerExpn->numChannels = pCalDataset->numChannels;	if (pPowerExpn->numChannels == 0) {		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no channels\n", __func__);		return AH_FALSE;	}	for (ii = 0; ii < pPowerExpn->numChannels; ii++) {		pCalCh = &pCalDataset->pDataPerChannel[ii];		pPowerExpn->pDataPerChannel[ii].channelValue =			pCalCh->channelValue;		pPowerExpn->pDataPerChannel[ii].maxPower_t4 =			pCalCh->maxPower_t4;		maxPower_t4 = pPowerExpn->pDataPerChannel[ii].maxPower_t4;		for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++)			pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj].numPcdacs = 0;		if (xgainList[1] == 0xDEAD) {			jj = xgainList[0];			pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];			pExpnXPD->numPcdacs = 4;			pExpnXPD->pcdac[0] = pCalCh->pcd1_xg0;			pExpnXPD->pcdac[1] = (uint16_t)				(pExpnXPD->pcdac[0] + pCalCh->pcd2_delta_xg0);			pExpnXPD->pcdac[2] = (uint16_t)				(pExpnXPD->pcdac[1] + pCalCh->pcd3_delta_xg0);			pExpnXPD->pcdac[3] = (uint16_t)				(pExpnXPD->pcdac[2] + pCalCh->pcd4_delta_xg0);			pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg0;			pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg0;			pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg0;			pExpnXPD->pwr_t4[3] = pCalCh->pwr4_xg0;		} else {			pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[0]].pcdac[0] = pCalCh->pcd1_xg0;			pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[0] = 20;			pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[1] = 35;			pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[2] = 63;			jj = xgainList[0];			pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];			pExpnXPD->numPcdacs = 4;			pExpnXPD->pcdac[1] = (uint16_t)				(pExpnXPD->pcdac[0] + pCalCh->pcd2_delta_xg0);			pExpnXPD->pcdac[2] = (uint16_t)				(pExpnXPD->pcdac[1] + pCalCh->pcd3_delta_xg0);			pExpnXPD->pcdac[3] = (uint16_t)				(pExpnXPD->pcdac[2] + pCalCh->pcd4_delta_xg0);			pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg0;			pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg0;			pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg0;			pExpnXPD->pwr_t4[3] = pCalCh->pwr4_xg0;			jj = xgainList[1];			pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];			pExpnXPD->numPcdacs = 3;			pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg3;			pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg3;			pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg3;		}	}	return AH_TRUE;}static HAL_BOOLreadEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee){#define	EEREAD(_off) do {				\	if (!ath_hal_eepromRead(ah, _off, &eeval))	\		return AH_FALSE;			\} while (0)	const uint16_t dbmmask		 = 0xff;	const uint16_t pcdac_delta_mask = 0x1f;	const uint16_t pcdac_mask	 = 0x3f;	const uint16_t freqmask	 = 0xff;	int i, mode, numPiers;	uint32_t off;	uint16_t eeval;	uint16_t freq[NUM_11A_EEPROM_CHANNELS];        EEPROM_POWER_5112 eePower;	HALASSERT(ee->ee_version >= AR_EEPROM_VER4_0);	off = GROUPS_OFFSET3_3;	for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {		numPiers = 0;		switch (mode) {		case headerInfo11A:			if (!ee->ee_Amode)	/* no 11a calibration data */				continue;			while (numPiers < NUM_11A_EEPROM_CHANNELS) {				EEREAD(off++);				if ((eeval & freqmask) == 0)					break;				freq[numPiers++] = fbin2freq(ee,					eeval & freqmask);				if (((eeval >> 8) & freqmask) == 0)					break;				freq[numPiers++] = fbin2freq(ee,					(eeval>>8) & freqmask);			}			break;		case headerInfo11B:			if (!ee->ee_Bmode)	/* no 11b calibration data */				continue;			for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++)				if (ee->ee_calPier11b[i] != CHANNEL_UNUSED)					freq[numPiers++] = ee->ee_calPier11b[i];			break;		case headerInfo11G:			if (!ee->ee_Gmode)	/* no 11g calibration data */				continue;			for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++)				if (ee->ee_calPier11g[i] != CHANNEL_UNUSED)					freq[numPiers++] = ee->ee_calPier11g[i];			break;		default:			HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",			    __func__, mode);			return AH_FALSE;		}		OS_MEMZERO(&eePower, sizeof(eePower));		eePower.numChannels = numPiers;		for (i = 0; i < numPiers; i++) {			eePower.pChannels[i] = freq[i];			eePower.pDataPerChannel[i].channelValue = freq[i];			EEREAD(off++);			eePower.pDataPerChannel[i].pwr1_xg0 = (int16_t)				((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);			eePower.pDataPerChannel[i].pwr2_xg0 = (int16_t)				(((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256);			EEREAD(off++);			eePower.pDataPerChannel[i].pwr3_xg0 = (int16_t)				((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);			eePower.pDataPerChannel[i].pwr4_xg0 = (int16_t)				(((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256);			EEREAD(off++);			eePower.pDataPerChannel[i].pcd2_delta_xg0 = (uint16_t)				(eeval & pcdac_delta_mask);			eePower.pDataPerChannel[i].pcd3_delta_xg0 = (uint16_t)				((eeval >> 5) & pcdac_delta_mask);			eePower.pDataPerChannel[i].pcd4_delta_xg0 = (uint16_t)				((eeval >> 10) & pcdac_delta_mask);			EEREAD(off++);			eePower.pDataPerChannel[i].pwr1_xg3 = (int16_t)				((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);			eePower.pDataPerChannel[i].pwr2_xg3 = (int16_t)				(((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256);			EEREAD(off++);			eePower.pDataPerChannel[i].pwr3_xg3 = (int16_t)				((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);			if (ee->ee_version >= AR_EEPROM_VER4_3) {				eePower.pDataPerChannel[i].maxPower_t4 =					eePower.pDataPerChannel[i].pwr4_xg0;     				eePower.pDataPerChannel[i].pcd1_xg0 = (uint16_t)					((eeval >> 8) & pcdac_mask);			} else {				eePower.pDataPerChannel[i].maxPower_t4 = (int16_t)					(((eeval >> 8) & dbmmask) -					 ((eeval >> 15) & 0x1)*256);				eePower.pDataPerChannel[i].pcd1_xg0 = 1;			}		}		eePower.xpdMask = ee->ee_xgain[mode];		if (!eepromAllocExpnPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) {			HALDEBUG(ah, HAL_DEBUG_ANY,			    "%s: did not allocate power struct\n", __func__);			return AH_FALSE;                }                if (!eepromExpandPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) {			HALDEBUG(ah, HAL_DEBUG_ANY,			    "%s: did not expand power struct\n", __func__);			return AH_FALSE;		}	}	return AH_TRUE;#undef EEREAD}static voidfreeEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee){	int mode;	void *data;	for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {		EEPROM_POWER_EXPN_5112 *pPowerExpn =			&ee->ee_modePowerArray5112[mode];		data = pPowerExpn->pChannels;		if (data != AH_NULL) {			pPowerExpn->pChannels = AH_NULL;			ath_hal_free(data);		}	}}static voidar2413SetupEEPROMDataset(EEPROM_DATA_STRUCT_2413 *pEEPROMDataset2413,	uint16_t myNumRawChannels, uint16_t *pMyRawChanList){	uint16_t i, channelValue;	uint32_t xpd_mask;	uint16_t numPdGainsUsed;	pEEPROMDataset2413->numChannels = myNumRawChannels;	xpd_mask = pEEPROMDataset2413->xpd_mask;	numPdGainsUsed = 0;	if ((xpd_mask >> 0) & 0x1) numPdGainsUsed++;	if ((xpd_mask >> 1) & 0x1) numPdGainsUsed++;	if ((xpd_mask >> 2) & 0x1) numPdGainsUsed++;	if ((xpd_mask >> 3) & 0x1) numPdGainsUsed++;	for (i = 0; i < myNumRawChannels; i++) {		channelValue = pMyRawChanList[i];		pEEPROMDataset2413->pChannels[i] = channelValue;		pEEPROMDataset2413->pDataPerChannel[i].channelValue = channelValue;		pEEPROMDataset2413->pDataPerChannel[i].numPdGains = numPdGainsUsed;	}}static HAL_BOOLar2413ReadCalDataset(struct ath_hal *ah, HAL_EEPROM *ee,	EEPROM_DATA_STRUCT_2413 *pCalDataset,	uint32_t start_offset, uint32_t maxPiers, uint8_t mode){#define	EEREAD(_off) do {				\	if (!ath_hal_eepromRead(ah, _off, &eeval))	\		return AH_FALSE;			\} while (0)	const uint16_t dbm_I_mask = 0x1F;	/* 5-bits. 1dB step. */	const uint16_t dbm_delta_mask = 0xF;	/* 4-bits. 0.5dB step. */	const uint16_t Vpd_I_mask = 0x7F;	/* 7-bits. 0-128 */	const uint16_t Vpd_delta_mask = 0x3F;	/* 6-bits. 0-63 */	const uint16_t freqmask = 0xff;	uint16_t ii, eeval;	uint16_t idx, numPiers;	uint16_t freq[NUM_11A_EEPROM_CHANNELS];	idx = start_offset;    for (numPiers = 0; numPiers < maxPiers;) {        EEREAD(idx++);        if ((eeval & freqmask) == 0)            break;        if (mode == headerInfo11A)            freq[numPiers++] = fbin2freq(ee, (eeval & freqmask));        else            freq[numPiers++] = fbin2freq_2p4(ee, (eeval & freqmask));                                                                                                  if (((eeval >> 8) & freqmask) == 0)            break;

⌨️ 快捷键说明

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