Date: Thu, 26 May 2011 15:01:38 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r222310 - head/sys/dev/ath/ath_hal/ar9002 Message-ID: <201105261501.p4QF1cla069356@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Thu May 26 15:01:37 2011 New Revision: 222310 URL: http://svn.freebsd.org/changeset/base/222310 Log: Flesh out ar9287SetTransmitPower() based on the AR9285 routine. Hard-code the per-rate TX power at 5dBm for now so testing can be done. This passes initial TX testing in 11g mode (but, obviously, at 5dBm.) Modified: head/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c Modified: head/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c ============================================================================== --- head/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c Thu May 26 14:34:22 2011 (r222309) +++ head/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c Thu May 26 15:01:37 2011 (r222310) @@ -111,26 +111,136 @@ ar9287SetPowerCalTable(struct ath_hal *a *pTxPowerIndexOffset = 0; } +/* + * Fetch the maximum TX power per rate. + * + * For now, this is hard-coded at 5dBm until this code has been ported + * from Atheros/ath9k and tested. + */ +static HAL_BOOL +ar9285SetPowerPerRateTable(struct ath_hal *ah, + struct ar9287_eeprom *pEepData, + const struct ieee80211_channel *chan, + int16_t *ratesArray, uint16_t cfgCtl, + uint16_t AntennaReduction, + uint16_t twiceMaxRegulatoryPower, + uint16_t powerLimit) +{ + int i; + + /* For now, set all tx power rates to 5 dBm */ + for (i = 0; i < Ar5416RateSize; i++) + ratesArray[i] = 10; + + return AH_TRUE; +} + +/* + * This is based off of the AR5416/AR9285 code and likely could + * be unified in the future. + */ HAL_BOOL ar9287SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan, uint16_t *rfXpdGain) { - int16_t txPowerIndexOffset = 0; +#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) +#define N(a) (sizeof (a) / sizeof (a[0])) + + const struct modal_eep_ar9287_header *pModal; + struct ath_hal_5212 *ahp = AH5212(ah); + int16_t ratesArray[Ar5416RateSize]; + int16_t txPowerIndexOffset = 0; + uint8_t ht40PowerIncForPdadc = 2; + int i; + + uint16_t cfgCtl; + uint16_t powerLimit; + uint16_t twiceAntennaReduction; + uint16_t twiceMaxRegulatoryPower; + int16_t maxPower; + HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom; + struct ar9287_eeprom *pEepData = &ee->ee_base; + + /* Setup info for the actual eeprom */ + OS_MEMZERO(ratesArray, sizeof(ratesArray)); + cfgCtl = ath_hal_getctl(ah, chan); + powerLimit = chan->ic_maxregpower * 2; + twiceAntennaReduction = chan->ic_maxantgain; + twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); + pModal = &pEepData->modalHeader; + HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", + __func__,chan->ic_freq, cfgCtl ); - /* XXX TODO */ + /* XXX Assume Minor is v2 or later */ + ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; /* Fetch per-rate power table for the given channel */ + if (!ar9285SetPowerPerRateTable(ah, pEepData, chan, + &ratesArray[0],cfgCtl, + twiceAntennaReduction, + twiceMaxRegulatoryPower, powerLimit)) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "%s: unable to set tx power per rate table\n", __func__); + return AH_FALSE; + } - /* Set open-loop TX power control calibration */ + /* Set TX power control calibration curves for each TX chain */ ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset); - /* Calculate regulatory maximum power level */ + /* Calculate maximum power level */ + maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); + maxPower = AH_MAX(maxPower, ratesArray[rate1l]); + + if (IEEE80211_IS_CHAN_HT40(chan)) + maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); + + ahp->ah_tx6PowerInHalfDbm = maxPower; + AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; + ahp->ah_txPowerIndexOffset = txPowerIndexOffset; + + /* + * txPowerIndexOffset is set by the SetPowerTable() call - + * adjust the rate table (0 offset if rates EEPROM not loaded) + */ + /* XXX what about the pwrTableOffset? */ + for (i = 0; i < N(ratesArray); i++) { + ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); + /* -5 dBm offset for Merlin and later; this includes Kiwi */ + ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; + if (ratesArray[i] > AR5416_MAX_RATE_POWER) + ratesArray[i] = AR5416_MAX_RATE_POWER; + if (ratesArray[i] < 0) + ratesArray[i] = 0; + } - /* Kiwi TX power starts at -5 dBm */ +#ifdef AH_EEPROM_DUMP + ar5416PrintPowerPerRate(ah, ratesArray); +#endif + + /* + * Adjust the HT40 power to meet the correct target TX power + * for 40MHz mode, based on TX power curves that are established + * for 20MHz mode. + * + * XXX handle overflow/too high power level? + */ + if (IEEE80211_IS_CHAN_HT40(chan)) { + ratesArray[rateHt40_0] += ht40PowerIncForPdadc; + ratesArray[rateHt40_1] += ht40PowerIncForPdadc; + ratesArray[rateHt40_2] += ht40PowerIncForPdadc; + ratesArray[rateHt40_3] += ht40PowerIncForPdadc; + ratesArray[rateHt40_4] += ht40PowerIncForPdadc; + ratesArray[rateHt40_5] += ht40PowerIncForPdadc; + ratesArray[rateHt40_6] += ht40PowerIncForPdadc; + ratesArray[rateHt40_7] += ht40PowerIncForPdadc; + } - /* Write TX power registers */ + /* Write the TX power rate registers */ + ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray); return AH_TRUE; +#undef POW_SM +#undef N } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105261501.p4QF1cla069356>