Esempio n. 1
0
/*
 * Reads EEPROM header info from device structure and programs
 * all rf registers
 *
 * REQUIRES: Access to the analog rf device
 */
static HAL_BOOL
ar2316SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
	uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define	RF_BANK_SETUP(_priv, _ix, _col) do {				    \
	int i;								    \
	for (i = 0; i < N(ar5212Bank##_ix##_2316); i++)			    \
		(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_2316[i][_col];\
} while (0)
	struct ath_hal_5212 *ahp = AH5212(ah);
	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
	uint16_t ob2GHz = 0, db2GHz = 0;
	struct ar2316State *priv = AR2316(ah);
	int regWrites = 0;

	HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
	    __func__, chan->ic_freq, chan->ic_flags, modesIndex);

	HALASSERT(priv != AH_NULL);

	/* Setup rf parameters */
	if (IEEE80211_IS_CHAN_B(chan)) {
		ob2GHz = ee->ee_obFor24;
		db2GHz = ee->ee_dbFor24;
	} else {
		ob2GHz = ee->ee_obFor24g;
		db2GHz = ee->ee_dbFor24g;
	}

	/* Bank 1 Write */
	RF_BANK_SETUP(priv, 1, 1);

	/* Bank 2 Write */
	RF_BANK_SETUP(priv, 2, modesIndex);

	/* Bank 3 Write */
	RF_BANK_SETUP(priv, 3, modesIndex);

	/* Bank 6 Write */
	RF_BANK_SETUP(priv, 6, modesIndex);

	ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz,   3, 178, 0);
	ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz,   3, 175, 0);

	/* Bank 7 Setup */
	RF_BANK_SETUP(priv, 7, modesIndex);

	/* Write Analog registers */
	HAL_INI_WRITE_BANK(ah, ar5212Bank1_2316, priv->Bank1Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank2_2316, priv->Bank2Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank3_2316, priv->Bank3Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank6_2316, priv->Bank6Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank7_2316, 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
}
Esempio n. 2
0
/*
 * Return a reference to the requested RF Bank.
 */
static uint32_t *
ar2316GetRfBank(struct ath_hal *ah, int bank)
{
	struct ar2316State *priv = AR2316(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;
}
Esempio n. 3
0
/*
 * Uses the data points read from EEPROM to reconstruct the pdadc power table
 * Called by ar2316SetPowerTable()
 */
static int 
ar2316getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
		const RAW_DATA_STRUCT_2316 *pRawDataset,
		uint16_t pdGainOverlap_t2, 
		int16_t  *pMinCalPower, uint16_t pPdGainBoundaries[], 
		uint16_t pPdGainValues[], uint16_t pPDADCValues[]) 
{
	struct ar2316State *priv = AR2316(ah);
#define	VpdTable_L	priv->vpdTable_L
#define	VpdTable_R	priv->vpdTable_R
#define	VpdTable_I	priv->vpdTable_I
	uint32_t ii, jj, kk;
	int32_t ss;/* potentially -ve index for taking care of pdGainOverlap */
	uint32_t idxL, idxR;
	uint32_t numPdGainsUsed = 0;
	/* 
	 * 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 */
	uint16_t numVpd = 0;
	uint16_t Vpd_step;
	int16_t tmpVal ; 
	uint32_t sizeCurrVpdTable, maxIndex, tgtIndex;

	/* 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 < (uint16_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] = (uint16_t)
				((Pmax_t2[ii] + Pmin_t2[ii+1]) / 2 );
		if (pPdGainBoundaries[ii] > 63) {
			HALDEBUG(ah, HAL_DEBUG_ANY,
			    "%s: clamp pPdGainBoundaries[%d] %d\n",
			    __func__, ii, pPdGainBoundaries[ii]);/*XXX*/
			pPdGainBoundaries[ii] = 63;
		}

		/* 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 = (uint16_t)(VpdTable_I[ii][1] - VpdTable_I[ii][0]);
		Vpd_step = (uint16_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++] = (uint16_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 = (uint16_t)(VpdTable_I[ii][sizeCurrVpdTable-1] -
				       VpdTable_I[ii][sizeCurrVpdTable-2]);
		Vpd_step = (uint16_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 = (uint16_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++;
	}

	return numPdGainsUsed;
#undef VpdTable_L
#undef VpdTable_R
#undef VpdTable_I
}
Esempio n. 4
0
/*
 * Reads EEPROM header info from device structure and programs
 * all rf registers
 *
 * REQUIRES: Access to the analog rf device
 */
static HAL_BOOL
ar2316SetRfRegs(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##_2316); i++)			    \
		(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_2316[i][_col];\
} while (0)
	struct ath_hal_5212 *ahp = AH5212(ah);
	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
	uint16_t ob2GHz = 0, db2GHz = 0;
	struct ar2316State *priv = AR2316(ah);
	int regWrites = 0;

	HALDEBUG(ah, HAL_DEBUG_RFPARAM,
	    "%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
	    __func__, chan->channel, chan->channelFlags, modesIndex);

	HALASSERT(priv != AH_NULL);

	/* Setup rf parameters */
	switch (chan->channelFlags & CHANNEL_ALL) {
	case CHANNEL_B:
		ob2GHz = ee->ee_obFor24;
		db2GHz = ee->ee_dbFor24;
		break;
	case CHANNEL_G:
	case CHANNEL_108G:
		ob2GHz = ee->ee_obFor24g;
		db2GHz = ee->ee_dbFor24g;
		break;
	default:
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
		    __func__, chan->channelFlags);
		return AH_FALSE;
	}

	/* Bank 1 Write */
	RF_BANK_SETUP(priv, 1, 1);

	/* Bank 2 Write */
	RF_BANK_SETUP(priv, 2, modesIndex);

	/* Bank 3 Write */
	RF_BANK_SETUP(priv, 3, modesIndex);

	/* Bank 6 Write */
	RF_BANK_SETUP(priv, 6, modesIndex);

	ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz,   3, 178, 0);
	ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz,   3, 175, 0);

	/* Bank 7 Setup */
	RF_BANK_SETUP(priv, 7, modesIndex);

	/* Write Analog registers */
	HAL_INI_WRITE_BANK(ah, ar5212Bank1_2316, priv->Bank1Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank2_2316, priv->Bank2Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank3_2316, priv->Bank3Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank6_2316, priv->Bank6Data, regWrites);
	HAL_INI_WRITE_BANK(ah, ar5212Bank7_2316, 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
}