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

📄 ar2316.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* filled out Vpd table for all pdGains (chanL) */	u_int16_t VpdTable_R[MAX_NUM_PDGAINS_PER_CHANNEL][MAX_PWR_RANGE_IN_HALF_DB];	/* filled out Vpd table for all pdGains (chanR) */	u_int16_t VpdTable_I[MAX_NUM_PDGAINS_PER_CHANNEL][MAX_PWR_RANGE_IN_HALF_DB];	/* filled out Vpd table for all pdGains (interpolated) */	/* 	 * If desired to support -ve power levels in future, just	 * change pwr_I_0 to signed 5-bits.	 */	int16_t Pmin_t2[MAX_NUM_PDGAINS_PER_CHANNEL];	/* to accomodate -ve power levels later on. */	int16_t Pmax_t2[MAX_NUM_PDGAINS_PER_CHANNEL];	/* to accomodate -ve power levels later on */	u_int16_t numVpd = 0;	u_int16_t Vpd_step;	int16_t tmpVal ; 	u_int32_t sizeCurrVpdTable, maxIndex, tgtIndex;	HALDEBUG(ah, "==>%s:\n", __func__);    	/* Get upper lower index */	GetLowerUpperIndex(channel, pRawDataset->pChannels,				 pRawDataset->numChannels, &(idxL), &(idxR));	for (ii = 0; ii < MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {		jj = MAX_NUM_PDGAINS_PER_CHANNEL - ii - 1;		/* work backwards 'cause highest pdGain for lowest power */		numVpd = pRawDataset->pDataPerChannel[idxL].pDataPerPDGain[jj].numVpd;		if (numVpd > 0) {			pPdGainValues[numPdGainsUsed] = pRawDataset->pDataPerChannel[idxL].pDataPerPDGain[jj].pd_gain;			Pmin_t2[numPdGainsUsed] = pRawDataset->pDataPerChannel[idxL].pDataPerPDGain[jj].pwr_t4[0];			if (Pmin_t2[numPdGainsUsed] >pRawDataset->pDataPerChannel[idxR].pDataPerPDGain[jj].pwr_t4[0]) {				Pmin_t2[numPdGainsUsed] = pRawDataset->pDataPerChannel[idxR].pDataPerPDGain[jj].pwr_t4[0];			}			Pmin_t2[numPdGainsUsed] = (int16_t)				(Pmin_t2[numPdGainsUsed] / 2);			Pmax_t2[numPdGainsUsed] = pRawDataset->pDataPerChannel[idxL].pDataPerPDGain[jj].pwr_t4[numVpd-1];			if (Pmax_t2[numPdGainsUsed] > pRawDataset->pDataPerChannel[idxR].pDataPerPDGain[jj].pwr_t4[numVpd-1])				Pmax_t2[numPdGainsUsed] = 					pRawDataset->pDataPerChannel[idxR].pDataPerPDGain[jj].pwr_t4[numVpd-1];			Pmax_t2[numPdGainsUsed] = (int16_t)(Pmax_t2[numPdGainsUsed] / 2);			ar2316FillVpdTable(					   numPdGainsUsed, Pmin_t2[numPdGainsUsed], Pmax_t2[numPdGainsUsed], 					   &(pRawDataset->pDataPerChannel[idxL].pDataPerPDGain[jj].pwr_t4[0]), 					   &(pRawDataset->pDataPerChannel[idxL].pDataPerPDGain[jj].Vpd[0]), numVpd, VpdTable_L					   );			ar2316FillVpdTable(					   numPdGainsUsed, Pmin_t2[numPdGainsUsed], Pmax_t2[numPdGainsUsed], 					   &(pRawDataset->pDataPerChannel[idxR].pDataPerPDGain[jj].pwr_t4[0]),					   &(pRawDataset->pDataPerChannel[idxR].pDataPerPDGain[jj].Vpd[0]), numVpd, VpdTable_R					   );			for (kk = 0; kk < (u_int16_t)(Pmax_t2[numPdGainsUsed] - Pmin_t2[numPdGainsUsed]); kk++) {				VpdTable_I[numPdGainsUsed][kk] = 					interpolate_signed(							   channel, pRawDataset->pChannels[idxL], pRawDataset->pChannels[idxR],							   (int16_t)VpdTable_L[numPdGainsUsed][kk], (int16_t)VpdTable_R[numPdGainsUsed][kk]);			}			/* fill VpdTable_I for this pdGain */			numPdGainsUsed++;		}		/* if this pdGain is used */	}	*pMinCalPower = Pmin_t2[0];	kk = 0; /* index for the final table */	for (ii = 0; ii < numPdGainsUsed; ii++) {		if (ii == (numPdGainsUsed - 1))			pPdGainBoundaries[ii] = Pmax_t2[ii] +				PD_GAIN_BOUNDARY_STRETCH_IN_HALF_DB;		else 			pPdGainBoundaries[ii] = (u_int16_t)				((Pmax_t2[ii] + Pmin_t2[ii+1]) / 2 );		/* Find starting index for this pdGain */		if (ii == 0) 			ss = 0; /* for the first pdGain, start from index 0 */		else 			ss = (pPdGainBoundaries[ii-1] - Pmin_t2[ii]) - 				pdGainOverlap_t2;		Vpd_step = (u_int16_t)(VpdTable_I[ii][1] - VpdTable_I[ii][0]);		Vpd_step = (u_int16_t)((Vpd_step < 1) ? 1 : Vpd_step);		/*		 *-ve ss indicates need to extrapolate data below for this pdGain		 */		while (ss < 0) {			tmpVal = (int16_t)(VpdTable_I[ii][0] + ss*Vpd_step);			pPDADCValues[kk++] = (u_int16_t)((tmpVal < 0) ? 0 : tmpVal);			ss++;		}		sizeCurrVpdTable = Pmax_t2[ii] - Pmin_t2[ii];		tgtIndex = pPdGainBoundaries[ii] + pdGainOverlap_t2 - Pmin_t2[ii];		maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;		while (ss < (int16_t)maxIndex)			pPDADCValues[kk++] = VpdTable_I[ii][ss++];		Vpd_step = (u_int16_t)(VpdTable_I[ii][sizeCurrVpdTable-1] -				       VpdTable_I[ii][sizeCurrVpdTable-2]);		Vpd_step = (u_int16_t)((Vpd_step < 1) ? 1 : Vpd_step);           		/*		 * for last gain, pdGainBoundary == Pmax_t2, so will 		 * have to extrapolate		 */		if (tgtIndex > maxIndex) {	/* need to extrapolate above */			while(ss < (int16_t)tgtIndex) {				tmpVal = (u_int16_t)					(VpdTable_I[ii][sizeCurrVpdTable-1] + 					 (ss-maxIndex)*Vpd_step);				pPDADCValues[kk++] = (tmpVal > 127) ? 					127 : tmpVal;				ss++;			}		}				/* extrapolated above */	}					/* for all pdGainUsed */	while (ii < MAX_NUM_PDGAINS_PER_CHANNEL) {		pPdGainBoundaries[ii] = pPdGainBoundaries[ii-1];		ii++;	}	while (kk < 128) {		pPDADCValues[kk] = pPDADCValues[kk-1];		kk++;	}	HALDEBUG(ah, "<==%s\n", __func__);}static HAL_BOOLar2316SetPowerTable(struct ath_hal *ah,	int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan, 	u_int16_t *rfXpdGain){	struct ath_hal_5212 *ahp = AH5212(ah);	RAW_DATA_STRUCT_2316 *pRawDataset = AH_NULL;	u_int16_t pdGainOverlap_t2;	int16_t minCalPower2316_t2;	u_int16_t *pdadcValues = ahp->ah_pcdacTable;	u_int16_t gainBoundaries[4];	u_int32_t i, reg32, regoffset;	HALDEBUG(ah, "%s:chan 0x%x flag 0x%x\n", __func__, chan->channel,chan->channelFlags);	if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))		pRawDataset = &ahp->ah_rawDataset2413[headerInfo11G];	else if (IS_CHAN_B(chan))		pRawDataset = &ahp->ah_rawDataset2413[headerInfo11B];	else {		HALDEBUG(ah, "%s:illegal mode\n", __func__);		return AH_FALSE;	}	pdGainOverlap_t2 = (u_int16_t) SM(OS_REG_READ(ah, AR_PHY_TPCRG5),					  AR_PHY_TPCRG5_PD_GAIN_OVERLAP);    	ar2316getGainBoundariesAndPdadcsForPowers(ah, chan->channel,		pRawDataset, pdGainOverlap_t2,&minCalPower2316_t2,gainBoundaries,		rfXpdGain, pdadcValues);	OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 			 (pRawDataset->pDataPerChannel[0].numPdGains - 1));	/*	 * Note the pdadc table may not start at 0 dBm power, could be	 * negative or greater than 0.  Need to offset the power	 * values by the amount of minPower for griffin	 */	if (minCalPower2316_t2 != 0)		ahp->ah_txPowerIndexOffset = (int16_t)(0 - minCalPower2316_t2);	else		ahp->ah_txPowerIndexOffset = 0;	/* Finally, write the power values into the baseband power table */	regoffset = 0x9800 + (672 <<2); /* beginning of pdadc table in griffin */	for (i = 0; i < 32; i++) {		reg32 = ((pdadcValues[4*i + 0] & 0xFF) << 0)  | 			((pdadcValues[4*i + 1] & 0xFF) << 8)  |			((pdadcValues[4*i + 2] & 0xFF) << 16) |			((pdadcValues[4*i + 3] & 0xFF) << 24) ;        		OS_REG_WRITE(ah, regoffset, reg32);		regoffset += 4;	}	OS_REG_WRITE(ah, AR_PHY_TPCRG5, 		     SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 		     SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |		     SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |		     SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |		     SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));	return AH_TRUE;}/* * Free memory for analog bank scratch buffers */static voidar2316RfDetach(struct ath_hal *ah){	struct ath_hal_5212 *ahp = AH5212(ah);	if (ahp->ah_pcdacTable != AH_NULL) {		ath_hal_free(ahp->ah_pcdacTable);		ahp->ah_pcdacTable = AH_NULL;	}	if (ahp->ah_analogBanks != AH_NULL) {		ath_hal_free(ahp->ah_analogBanks);		ahp->ah_analogBanks = AH_NULL;	}}static int16_tar2316GetMinPower(struct ath_hal *ah, RAW_DATA_PER_CHANNEL_2316 *data){	u_int32_t ii,jj;	u_int16_t Pmin=0,numVpd;	for (ii = 0; ii < MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {		jj = MAX_NUM_PDGAINS_PER_CHANNEL - ii - 1;		/* work backwards 'cause highest pdGain for lowest power */		numVpd = data->pDataPerPDGain[jj].numVpd;		if (numVpd > 0) {			Pmin = data->pDataPerPDGain[jj].pwr_t4[0];			return(Pmin);		}	}	return(Pmin);}static int16_tar2316GetMaxPower(struct ath_hal *ah, RAW_DATA_PER_CHANNEL_2316 *data){	u_int32_t ii;	u_int16_t Pmax=0,numVpd;	u_int16_t vpdmax;		for (ii=0; ii< MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {		/* work forwards cuase lowest pdGain for highest power */		numVpd = data->pDataPerPDGain[ii].numVpd;		if (numVpd > 0) {			Pmax = data->pDataPerPDGain[ii].pwr_t4[numVpd-1];			vpdmax = data->pDataPerPDGain[ii].Vpd[numVpd-1];			return(Pmax);		}	}	return(Pmax);}staticHAL_BOOL ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,				     int16_t *maxPow, int16_t *minPow){	struct ath_hal_5212 *ahp = AH5212(ah);	RAW_DATA_STRUCT_2316 *pRawDataset = AH_NULL;	RAW_DATA_PER_CHANNEL_2316 *data=AH_NULL;	u_int16_t numChannels;	int totalD,totalF, totalMin,last, i;	*maxPow = 0;	if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))		pRawDataset = &ahp->ah_rawDataset2413[headerInfo11G];	else if (IS_CHAN_B(chan))		pRawDataset = &ahp->ah_rawDataset2413[headerInfo11B];	else		return(AH_FALSE);	numChannels = pRawDataset->numChannels;	data = pRawDataset->pDataPerChannel;		/* Make sure the channel is in the range of the TP values 	 *  (freq piers)	 */	if (numChannels < 1)		return(AH_FALSE);	if ((chan->channel < data[0].channelValue) ||	    (chan->channel > data[numChannels-1].channelValue)) {		if (chan->channel < data[0].channelValue) {			*maxPow = ar2316GetMaxPower(ah, &data[0]);			*minPow = ar2316GetMinPower(ah, &data[0]);			return(AH_TRUE);		} else {			*maxPow = ar2316GetMaxPower(ah, &data[numChannels - 1]);			*minPow = ar2316GetMinPower(ah, &data[numChannels - 1]);			return(AH_TRUE);		}	}	/* Linearly interpolate the power value now */	for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);	     last = i++);	totalD = data[i].channelValue - data[last].channelValue;	if (totalD > 0) {		totalF = ar2316GetMaxPower(ah, &data[i]) - ar2316GetMaxPower(ah, &data[last]);		*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + 				     ar2316GetMaxPower(ah, &data[last])*totalD)/totalD);		totalMin = ar2316GetMinPower(ah, &data[i]) - ar2316GetMinPower(ah, &data[last]);		*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +				     ar2316GetMinPower(ah, &data[last])*totalD)/totalD);		return(AH_TRUE);	} else {		if (chan->channel == data[i].channelValue) {			*maxPow = ar2316GetMaxPower(ah, &data[i]);			*minPow = ar2316GetMinPower(ah, &data[i]);			return(AH_TRUE);		} else			return(AH_FALSE);	}}HAL_BOOLar2316GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, u_int32_t nchans){	HAL_BOOL retVal = AH_TRUE;	int i;	int16_t maxPow, minPow;	for (i=0; i<nchans; i++) {		if (ar2316GetChannelMaxMinPower(ah, &chans[i], &maxPow, &minPow)) {			chans[i].maxTxPower = maxPow;			chans[i].minTxPower = minPow;		} else {			HALDEBUG(ah, "Failed setting power table for nchans=%d\n", i);			retVal = AH_FALSE;		}	}#ifdef AH_DEBUG	for (i=0; i<nchans; i++) {		ath_hal_printf(ah,"Chan %d: MaxPow = %d MinPow = %d\n",			 chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);	}#endif	return (retVal);}		/* * Allocate memory for analog bank scratch buffers * Scratch Buffer will be reinitialized every reset so no need to zero now */HAL_BOOLar2316RfAttach(struct ath_hal *ah, HAL_STATUS *status){	struct ath_hal_5212 *ahp = AH5212(ah);	HALASSERT(ahp->ah_analogBanks == AH_NULL);	ahp->ah_analogBanks = ath_hal_malloc(sizeof(AR5212_RF_BANKS_2316));	if (ahp->ah_analogBanks == AH_NULL) {		HALDEBUG(ah, "%s: cannot allocate RF banks\n", __func__);		*status = HAL_ENOMEM;		/* XXX */		return AH_FALSE;	}	HALASSERT(ahp->ah_pcdacTable == AH_NULL);	ahp->ah_pcdacTableSize = PWR_TABLE_SIZE_2316 * sizeof(u_int16_t);	ahp->ah_pcdacTable = ath_hal_malloc(ahp->ah_pcdacTableSize);	if (ahp->ah_pcdacTable == AH_NULL) {		HALDEBUG(ah, "%s: cannot allocate PCDAC table\n", __func__);		*status = HAL_ENOMEM;		/* XXX */		return AH_FALSE;	}	ahp->ah_rfHal.rfDetach		= ar2316RfDetach;	ahp->ah_rfHal.writeRegs		= ar2316WriteRegs;	ahp->ah_rfHal.getRfBank		= ar2316GetRfBank;	ahp->ah_rfHal.setChannel	= ar2316SetChannel;	ahp->ah_rfHal.setRfRegs		= ar2316SetRfRegs;	ahp->ah_rfHal.setPowerTable	= ar2316SetPowerTable;	ahp->ah_rfHal.getChipPowerLim	= ar2316GetChipPowerLimits;	return AH_TRUE;}#endif /* AH_SUPPORT_2316 */

⌨️ 快捷键说明

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