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:
parent
d4ef3ac078
commit
64cd31ce69
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user