Bring over an XPA (external power amplifer) bias fix for the AR9160.

This fix modifies the const addac initval array, rather than modifying
a local copy. It means that running >1 AR9160 on a board may prove to
be unpredictable.

The AR5416 init path also does something similar, so supporting
>1 AR5416 of different revisions could cause problems.

The later fix will be to create a private copy of the Addac data
for the AR5416, AR9160 (and AR9100 when it's merged in) and then
modify that as needed.

Obtained From:	Linux ath9k
This commit is contained in:
Adrian Chadd 2011-03-22 10:29:36 +00:00
parent 507de8028f
commit f6f59583bf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=219863
3 changed files with 79 additions and 3 deletions

View File

@ -235,6 +235,8 @@ extern void ar5416GetTargetPowersLeg(struct ath_hal *ah,
uint16_t numRates, HAL_BOOL isExtTarget);
extern void ar5416InitChainMasks(struct ath_hal *ah);
extern void ar5416RestoreChainMask(struct ath_hal *ah);
extern void ar5416EepromSetAddac(struct ath_hal *ah,
const struct ieee80211_channel *chan);
/* TX power setup related routines in ar5416_reset.c */
extern void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,

View File

@ -474,10 +474,11 @@ ar5416WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
* Write addac shifts
*/
OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
#if 0
/* NB: only required for Sowl */
ar5416EepromSetAddac(ah, chan);
#endif
if (AR_SREV_SOWL(ah))
ar5416EepromSetAddac(ah, chan);
regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1,
regWrites);
OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);

View File

@ -2425,3 +2425,76 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
}
}
struct ini {
uint32_t *data; /* NB: !const */
int rows, cols;
};
/*
* Override XPA bias level based on operating frequency.
* This is a v14 EEPROM specific thing for the AR9160.
*/
void
ar5416EepromSetAddac(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
MODAL_EEP_HEADER *pModal;
HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ar5416eeprom *eep = &ee->ee_base;
uint8_t biaslevel;
if (! AR_SREV_SOWL(ah))
return;
if (EEP_MINOR(ah) < AR5416_EEP_MINOR_VER_7)
return;
pModal = &(eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]);
if (pModal->xpaBiasLvl != 0xff)
biaslevel = pModal->xpaBiasLvl;
else {
uint16_t resetFreqBin, freqBin, freqCount = 0;
CHAN_CENTERS centers;
ar5416GetChannelCenters(ah, chan, &centers);
resetFreqBin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan));
freqBin = XPA_LVL_FREQ(0) & 0xff;
biaslevel = (uint8_t) (XPA_LVL_FREQ(0) >> 14);
freqCount++;
while (freqCount < 3) {
if (XPA_LVL_FREQ(freqCount) == 0x0)
break;
freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
if (resetFreqBin >= freqBin)
biaslevel = (uint8_t)(XPA_LVL_FREQ(freqCount) >> 14);
else
break;
freqCount++;
}
}
HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: overriding XPA bias level = %d\n",
__func__, biaslevel);
/*
* This is a dirty workaround for the const initval data,
* which will upset multiple AR9160's on the same board.
*
* The HAL should likely just have a private copy of the addac
* data per instance.
*/
if (IEEE80211_IS_CHAN_2GHZ(chan))
HAL_INI_VAL((struct ini *) &AH5416(ah)->ah_ini_addac, 7, 1) =
(HAL_INI_VAL(&AH5416(ah)->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3;
else
HAL_INI_VAL((struct ini *) &AH5416(ah)->ah_ini_addac, 6, 1) =
(HAL_INI_VAL(&AH5416(ah)->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6;
#undef XPA_LVL_FREQ
}