Move out some of the shared eeprom board value calculation routines into ah.c

rather than duplicating them for the v14 (ar5416+) and v4k (ar9285) codebases.

Further chipsets (eg the AR9287) have yet another EEPROM format which will use
these routines to calculate things.
This commit is contained in:
adrian 2011-03-13 05:54:05 +00:00
parent d4ef3ac078
commit 64cd31ce69
6 changed files with 139 additions and 147 deletions

View File

@ -986,3 +986,115 @@ ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
}
return regWr;
}
/*
* These are EEPROM board related routines which should likely live in
* a helper library of some sort.
*/
/**************************************************************
* ath_ee_getLowerUppderIndex
*
* Return indices surrounding the value in sorted integer lists.
* Requirement: the input list must be monotonically increasing
* and populated up to the list size
* Returns: match is set if an index in the array matches exactly
* or a the target is before or after the range of the array.
*/
HAL_BOOL
ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
uint16_t *indexL, uint16_t *indexR)
{
uint16_t i;
/*
* Check first and last elements for beyond ordered array cases.
*/
if (target <= pList[0]) {
*indexL = *indexR = 0;
return AH_TRUE;
}
if (target >= pList[listSize-1]) {
*indexL = *indexR = (uint16_t)(listSize - 1);
return AH_TRUE;
}
/* look for value being near or between 2 values in list */
for (i = 0; i < listSize - 1; i++) {
/*
* If value is close to the current value of the list
* then target is not between values, it is one of the values
*/
if (pList[i] == target) {
*indexL = *indexR = i;
return AH_TRUE;
}
/*
* Look for value being between current value and next value
* if so return these 2 values
*/
if (target < pList[i + 1]) {
*indexL = i;
*indexR = (uint16_t)(i + 1);
return AH_FALSE;
}
}
HALASSERT(0);
*indexL = *indexR = 0;
return AH_FALSE;
}
/**************************************************************
* ath_ee_FillVpdTable
*
* Fill the Vpdlist for indices Pmax-Pmin
* Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
*/
HAL_BOOL
ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
{
uint16_t i, k;
uint8_t currPwr = pwrMin;
uint16_t idxL, idxR;
HALASSERT(pwrMax > pwrMin);
for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
&(idxL), &(idxR));
if (idxR < 1)
idxR = 1; /* extrapolate below */
if (idxL == numIntercepts - 1)
idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */
if (pPwrList[idxL] == pPwrList[idxR])
k = pVpdList[idxL];
else
k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
(pPwrList[idxR] - pPwrList[idxL]) );
HALASSERT(k < 256);
pRetVpdList[i] = (uint8_t)k;
currPwr += 2; /* half dB steps */
}
return AH_TRUE;
}
/**************************************************************************
* ath_ee_interpolate
*
* Returns signed interpolated or the scaled up interpolated value
*/
int16_t
ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
int16_t targetLeft, int16_t targetRight)
{
int16_t rv;
if (srcRight == srcLeft) {
rv = targetLeft;
} else {
rv = (int16_t)( ((target - srcLeft) * targetRight +
(srcRight - target) * targetLeft) / (srcRight - srcLeft) );
}
return rv;
}

View File

@ -784,4 +784,14 @@ extern int ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
#define TURBO_SYMBOL_TIME 4
#define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* ACK+FCS */
/* Generic EEPROM board value functions */
extern HAL_BOOL ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList,
uint16_t listSize, uint16_t *indexL, uint16_t *indexR);
extern HAL_BOOL ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,
uint8_t *pPwrList, uint8_t *pVpdList, uint16_t numIntercepts,
uint8_t *pRetVpdList);
extern int16_t ath_ee_interpolate(uint16_t target, uint16_t srcLeft,
uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
#endif /* _ATH_AH_INTERAL_H_ */

View File

@ -237,11 +237,6 @@ extern void ar5416InitChainMasks(struct ath_hal *ah);
extern void ar5416RestoreChainMask(struct ath_hal *ah);
/* TX power setup related routines in ar5416_reset.c */
extern HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList,
uint16_t listSize, uint16_t *indexL, uint16_t *indexR);
extern HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,
uint8_t *pPwrList, uint8_t *pVpdList, uint16_t numIntercepts,
uint8_t *pRetVpdList);
extern void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet,
uint8_t * bChans, uint16_t availPiers,

View File

@ -63,9 +63,6 @@ static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah,
uint16_t powerLimit);
static uint16_t ar5416GetMaxEdgePower(uint16_t freq,
CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz);
static int16_t interpolate(uint16_t target, uint16_t srcLeft,
uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
static void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan);
/*
@ -1864,7 +1861,7 @@ ar5416GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan,
chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
for (i = 0; i < numRates; i++) {
pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi,
pNewPower->tPow2x[i] = (uint8_t)ath_ee_interpolate(freq, clo, chi,
powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]);
}
}
@ -1924,7 +1921,7 @@ ar5416GetTargetPowersLeg(struct ath_hal *ah,
chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
for (i = 0; i < numRates; i++) {
pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi,
pNewPower->tPow2x[i] = (uint8_t)ath_ee_interpolate(freq, clo, chi,
powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]);
}
}
@ -2179,15 +2176,15 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
}
/* Find pier indexes around the current channel */
match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
bChans, numPiers, &idxL, &idxR);
match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center,
IEEE80211_IS_CHAN_2GHZ(chan)), bChans, numPiers, &idxL, &idxR);
if (match) {
/* Directly fill both vpd tables from the matching index */
for (i = 0; i < numXpdGains; i++) {
minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i],
ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i],
pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);
}
} else {
@ -2205,12 +2202,13 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
HALASSERT(maxPwrT4[i] > minPwrT4[i]);
/* Fill pier Vpds */
ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);
ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);
ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);
ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);
/* Interpolate the final vpd */
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
vpdTableI[i][j] = (uint8_t)(ath_ee_interpolate((uint16_t)FREQ2FBIN(centers.synth_center,
IEEE80211_IS_CHAN_2GHZ(chan)),
bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));
}
}
@ -2299,113 +2297,6 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
return;
}
/**************************************************************
* getLowerUppderIndex
*
* Return indices surrounding the value in sorted integer lists.
* Requirement: the input list must be monotonically increasing
* and populated up to the list size
* Returns: match is set if an index in the array matches exactly
* or a the target is before or after the range of the array.
*/
HAL_BOOL
getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
uint16_t *indexL, uint16_t *indexR)
{
uint16_t i;
/*
* Check first and last elements for beyond ordered array cases.
*/
if (target <= pList[0]) {
*indexL = *indexR = 0;
return AH_TRUE;
}
if (target >= pList[listSize-1]) {
*indexL = *indexR = (uint16_t)(listSize - 1);
return AH_TRUE;
}
/* look for value being near or between 2 values in list */
for (i = 0; i < listSize - 1; i++) {
/*
* If value is close to the current value of the list
* then target is not between values, it is one of the values
*/
if (pList[i] == target) {
*indexL = *indexR = i;
return AH_TRUE;
}
/*
* Look for value being between current value and next value
* if so return these 2 values
*/
if (target < pList[i + 1]) {
*indexL = i;
*indexR = (uint16_t)(i + 1);
return AH_FALSE;
}
}
HALASSERT(0);
*indexL = *indexR = 0;
return AH_FALSE;
}
/**************************************************************
* ar5416FillVpdTable
*
* Fill the Vpdlist for indices Pmax-Pmin
* Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
*/
HAL_BOOL
ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
{
uint16_t i, k;
uint8_t currPwr = pwrMin;
uint16_t idxL, idxR;
HALASSERT(pwrMax > pwrMin);
for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
&(idxL), &(idxR));
if (idxR < 1)
idxR = 1; /* extrapolate below */
if (idxL == numIntercepts - 1)
idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */
if (pPwrList[idxL] == pPwrList[idxR])
k = pVpdList[idxL];
else
k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
(pPwrList[idxR] - pPwrList[idxL]) );
HALASSERT(k < 256);
pRetVpdList[i] = (uint8_t)k;
currPwr += 2; /* half dB steps */
}
return AH_TRUE;
}
/**************************************************************************
* interpolate
*
* Returns signed interpolated or the scaled up interpolated value
*/
static int16_t
interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
int16_t targetLeft, int16_t targetRight)
{
int16_t rv;
if (srcRight == srcLeft) {
rv = targetLeft;
} else {
rv = (int16_t)( ((target - srcLeft) * targetRight +
(srcRight - target) * targetLeft) / (srcRight - srcLeft) );
}
return rv;
}
/*
* The linux ath9k driver and (from what I've been told) the reference
* Atheros driver enables the 11n PHY by default whether or not it's

View File

@ -67,7 +67,7 @@ ar9280olcGetTxGainIndex(struct ath_hal *ah,
if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
break;
match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center,
match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center,
IEEE80211_IS_CHAN_2GHZ(chan)), calChans, numPiers,
&idxL, &idxR);
if (match) {

View File

@ -57,8 +57,6 @@ static HAL_BOOL ar9285SetPowerCalTable(struct ath_hal *ah,
struct ar5416eeprom_4k *pEepData,
const struct ieee80211_channel *chan,
int16_t *pTxPowerIndexOffset);
static int16_t interpolate(uint16_t target, uint16_t srcLeft,
uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
static void ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah,
const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ_4K *pRawDataSet,
uint8_t * bChans, uint16_t availPiers,
@ -657,15 +655,15 @@ ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah,
}
/* Find pier indexes around the current channel */
match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
bChans, numPiers, &idxL, &idxR);
match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center,
IEEE80211_IS_CHAN_2GHZ(chan)), bChans, numPiers, &idxL, &idxR);
if (match) {
/* Directly fill both vpd tables from the matching index */
for (i = 0; i < numXpdGains; i++) {
minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i],
ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i],
pRawDataSet[idxL].pwrPdg[i],
pRawDataSet[idxL].vpdPdg[i],
AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);
@ -685,14 +683,15 @@ ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah,
HALASSERT(maxPwrT4[i] > minPwrT4[i]);
/* Fill pier Vpds */
ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL,
ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL,
AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);
ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR,
ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR,
AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);
/* Interpolate the final vpd */
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
vpdTableI[i][j] = (uint8_t)(ath_ee_interpolate((uint16_t)FREQ2FBIN(centers.synth_center,
IEEE80211_IS_CHAN_2GHZ(chan)),
bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));
}
}
@ -780,18 +779,3 @@ ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah,
}
return;
}
static int16_t
interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
int16_t targetLeft, int16_t targetRight)
{
int16_t rv;
if (srcRight == srcLeft) {
rv = targetLeft;
} else {
rv = (int16_t)( ((target - srcLeft) * targetRight +
(srcRight - target) * targetLeft) / (srcRight - srcLeft) );
}
return rv;
}