diff options
author | adrian <adrian@FreeBSD.org> | 2013-04-17 07:31:53 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2013-04-17 07:31:53 +0000 |
commit | 94252a362d14192a49dd969d5bc0622be1c9a92f (patch) | |
tree | 6f0015ff31c1c24d83b04021ae4346e5cc4517ca /sys/dev/ath/ath_hal | |
parent | 004d764babe413d9d2d36057285b0eecea7b038d (diff) | |
download | FreeBSD-src-94252a362d14192a49dd969d5bc0622be1c9a92f.zip FreeBSD-src-94252a362d14192a49dd969d5bc0622be1c9a92f.tar.gz |
Setup needed tables for TPC on AR5416->AR9287 chips.
* Add ah_ratesArray[] to the ar5416 HAL state - this stores the maximum
values permissable per rate.
* Since different chip EEPROM formats store this value in a different place,
store the HT40 power detector increment value in the ar5416 HAL state.
* Modify the target power setup code to store the maximum values in the
ar5416 HAL state rather than using a local variable.
* Add ar5416RateToRateTable() - to convert a hardware rate code to the
ratesArray enum / index.
* Add ar5416GetTxRatePower() - which goes through the gymnastics required
to correctly calculate the target TX power:
+ Add the power detector increment for ht40;
+ Take the power offset into account for AR9280 and later;
+ Offset the TX power correctly when doing open-loop TX power control;
+ Enforce the per-rate maximum value allowable.
Note - setting a TPC value of 0x0 in the TX descriptor on (at least)
the AR9160 resulted in the TX power being very high indeed. This didn't
happen on the AR9220. I'm guessing it's a chip bug that was fixed at
some point. So for now, just assume the AR5416/AR5418 and AR9130 are
also suspect and clamp the minimum value here at 1.
Tested:
* AR5416, AR9160, AR9220 hostap, verified using (2GHz) spectrum analyser
* Looked at target TX power in TX descriptor (using athalq) as well as TX
power on the spectrum analyser.
TODO:
* The TX descriptor code sets the target TX power to 0 for AR9285 chips.
I'm not yet sure why. Disable this for TPC and ensure that the TPC
TX power is set.
* AR9280, AR9285, AR9227, AR9287 testing!
* 5GHz testing!
Quirks:
* The per-packet TPC code is only exercised when the tpc sysctl is set
to 1. (dev.ath.X.tpc=1.) This needs to be done before you bring the
interface up.
* When TPC is enabled, setting the TX power doesn't end up with a call
through to the HAL to update the maximum TX power. So ensure that
you set the TPC sysctl before you bring the interface up and configure
a lower TX power or the hardware will be clamped by the lower TX
power (at least until the next channel change.)
Thanks to Qualcomm Atheros for all the hardware, and Sam Leffler for use
of his spectrum analyser to verify the TX channel power.
Diffstat (limited to 'sys/dev/ath/ath_hal')
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416.h | 5 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416_reset.c | 79 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c | 217 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar9002/ar9285_reset.c | 59 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar9002/ar9287_reset.c | 65 |
5 files changed, 344 insertions, 81 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h index c5ff6ae..a631aad 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h @@ -132,7 +132,12 @@ struct ath_hal_5416 { struct ar5416NfLimits nf_2g; struct ar5416NfLimits nf_5g; + /* + * TX power configuration related structures + */ int initPDADC; + int ah_ht40PowerIncForPdadc; + int16_t ah_ratesArray[Ar5416RateSize]; int ah_need_an_top2_fixup; /* merlin or later chips that may need this workaround */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index 5f8f2ad..41d63e2 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -1005,6 +1005,14 @@ ar5416WriteTxPowerRateRegisters(struct ath_hal *ah, | POW_SM(ratesArray[rateDupCck], 0) ); } + + /* + * Set max power to 30 dBm and, optionally, + * enable TPC in tx descriptors. + */ + OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER | + (AH5212(ah)->ah_tpcEnabled ? AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE : 0)); +#undef POW_SM } @@ -1019,12 +1027,11 @@ ar5416SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan, uint16_t *rfXpdGain) { #define N(a) (sizeof (a) / sizeof (a[0])) +#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) MODAL_EEP_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; @@ -1037,8 +1044,13 @@ ar5416SetTransmitPower(struct ath_hal *ah, HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); + /* + * Default to 2, is overridden based on the EEPROM version / value. + */ + AH5416(ah)->ah_ht40PowerIncForPdadc = 2; + /* Setup info for the actual eeprom */ - OS_MEMZERO(ratesArray, sizeof(ratesArray)); + OS_MEMZERO(AH5416(ah)->ah_ratesArray, sizeof(AH5416(ah)->ah_ratesArray)); cfgCtl = ath_hal_getctl(ah, chan); powerLimit = chan->ic_maxregpower * 2; twiceAntennaReduction = chan->ic_maxantgain; @@ -1048,11 +1060,12 @@ ar5416SetTransmitPower(struct ath_hal *ah, __func__,chan->ic_freq, cfgCtl ); if (IS_EEP_MINOR_V2(ah)) { - ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; + AH5416(ah)->ah_ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; } if (!ar5416SetPowerPerRateTable(ah, pEepData, chan, - &ratesArray[0],cfgCtl, + &AH5416(ah)->ah_ratesArray[0], + cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit)) { HALDEBUG(ah, HAL_DEBUG_ANY, @@ -1066,14 +1079,15 @@ ar5416SetTransmitPower(struct ath_hal *ah, return AH_FALSE; } - maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); + maxPower = AH_MAX(AH5416(ah)->ah_ratesArray[rate6mb], + AH5416(ah)->ah_ratesArray[rateHt20_0]); if (IEEE80211_IS_CHAN_2GHZ(chan)) { - maxPower = AH_MAX(maxPower, ratesArray[rate1l]); + maxPower = AH_MAX(maxPower, AH5416(ah)->ah_ratesArray[rate1l]); } if (IEEE80211_IS_CHAN_HT40(chan)) { - maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); + maxPower = AH_MAX(maxPower, AH5416(ah)->ah_ratesArray[rateHt40_0]); } ahp->ah_tx6PowerInHalfDbm = maxPower; @@ -1084,10 +1098,11 @@ ar5416SetTransmitPower(struct ath_hal *ah, * txPowerIndexOffset is set by the SetPowerTable() call - * adjust the rate table (0 offset if rates EEPROM not loaded) */ - for (i = 0; i < N(ratesArray); i++) { - ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); - if (ratesArray[i] > AR5416_MAX_RATE_POWER) - ratesArray[i] = AR5416_MAX_RATE_POWER; + for (i = 0; i < N(AH5416(ah)->ah_ratesArray); i++) { + AH5416(ah)->ah_ratesArray[i] = + (int16_t)(txPowerIndexOffset + AH5416(ah)->ah_ratesArray[i]); + if (AH5416(ah)->ah_ratesArray[i] > AR5416_MAX_RATE_POWER) + AH5416(ah)->ah_ratesArray[i] = AR5416_MAX_RATE_POWER; } #ifdef AH_EEPROM_DUMP @@ -1098,7 +1113,7 @@ ar5416SetTransmitPower(struct ath_hal *ah, * this debugging; the values won't necessarily be what's being * programmed into the hardware. */ - ar5416PrintPowerPerRate(ah, ratesArray); + ar5416PrintPowerPerRate(ah, AH5416(ah)->ah_ratesArray); #endif /* @@ -1114,16 +1129,16 @@ ar5416SetTransmitPower(struct ath_hal *ah, &pwr_table_offset); /* Underflow power gets clamped at raw value 0 */ /* Overflow power gets camped at AR5416_MAX_RATE_POWER */ - for (i = 0; i < N(ratesArray); i++) { + for (i = 0; i < N(AH5416(ah)->ah_ratesArray); i++) { /* * + pwr_table_offset is in dBm * + ratesArray is in 1/2 dBm */ - ratesArray[i] -= (pwr_table_offset * 2); - if (ratesArray[i] < 0) - ratesArray[i] = 0; - else if (ratesArray[i] > AR5416_MAX_RATE_POWER) - ratesArray[i] = AR5416_MAX_RATE_POWER; + AH5416(ah)->ah_ratesArray[i] -= (pwr_table_offset * 2); + if (AH5416(ah)->ah_ratesArray[i] < 0) + AH5416(ah)->ah_ratesArray[i] = 0; + else if (AH5416(ah)->ah_ratesArray[i] > AR5416_MAX_RATE_POWER) + AH5416(ah)->ah_ratesArray[i] = AR5416_MAX_RATE_POWER; } } @@ -1150,9 +1165,9 @@ ar5416SetTransmitPower(struct ath_hal *ah, int cck_ofdm_delta = 2; int i; for (i = 0; i < N(adj); i++) { - ratesArray[adj[i]] -= cck_ofdm_delta; - if (ratesArray[adj[i]] < 0) - ratesArray[adj[i]] = 0; + AH5416(ah)->ah_ratesArray[adj[i]] -= cck_ofdm_delta; + if (AH5416(ah)->ah_ratesArray[adj[i]] < 0) + AH5416(ah)->ah_ratesArray[adj[i]] = 0; } } @@ -1164,18 +1179,20 @@ ar5416SetTransmitPower(struct ath_hal *ah, * 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; + AH5416(ah)->ah_ratesArray[rateHt40_0] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_1] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_2] += AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_3] += AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_4] += AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_5] += AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_6] += AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_7] += AH5416(ah)->ah_ht40PowerIncForPdadc; } /* Write the TX power rate registers */ - ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray); + ar5416WriteTxPowerRateRegisters(ah, chan, AH5416(ah)->ah_ratesArray); /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c index f17cc8a..47e8c35 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c @@ -155,6 +155,169 @@ ar5416StopTxDma(struct ath_hal *ah, u_int q) /* NB: accept HT rates */ #define isValidTxRate(_r) ((1<<((_r) & 0x7f)) & VALID_TX_RATES) +static inline int +ar5416RateToRateTable(struct ath_hal *ah, uint8_t rate, HAL_BOOL is_ht40) +{ + + /* + * Handle the non-MCS rates + */ + switch (rate) { + case /* 1 Mb */ 0x1b: + case /* 1 MbS*/ 0x1b | 0x4: + return (AH5416(ah)->ah_ratesArray[rate1l]); + case /* 2 Mb */ 0x1a: + return (AH5416(ah)->ah_ratesArray[rate2l]); + case /* 2 MbS*/ 0x1a | 0x4: + return (AH5416(ah)->ah_ratesArray[rate2s]); + case /* 5.5 Mb */ 0x19: + return (AH5416(ah)->ah_ratesArray[rate5_5l]); + case /* 5.5 MbS*/ 0x19 | 0x4: + return (AH5416(ah)->ah_ratesArray[rate5_5s]); + case /* 11 Mb */ 0x18: + return (AH5416(ah)->ah_ratesArray[rate11l]); + case /* 11 MbS*/ 0x18 | 0x4: + return (AH5416(ah)->ah_ratesArray[rate11s]); + } + + /* OFDM rates */ + switch (rate) { + case /* 6 Mb */ 0x0b: + return (AH5416(ah)->ah_ratesArray[rate6mb]); + case /* 9 Mb */ 0x0f: + return (AH5416(ah)->ah_ratesArray[rate9mb]); + case /* 12 Mb */ 0x0a: + return (AH5416(ah)->ah_ratesArray[rate12mb]); + case /* 18 Mb */ 0x0e: + return (AH5416(ah)->ah_ratesArray[rate18mb]); + case /* 24 Mb */ 0x09: + return (AH5416(ah)->ah_ratesArray[rate24mb]); + case /* 36 Mb */ 0x0d: + return (AH5416(ah)->ah_ratesArray[rate36mb]); + case /* 48 Mb */ 0x08: + return (AH5416(ah)->ah_ratesArray[rate48mb]); + case /* 54 Mb */ 0x0c: + return (AH5416(ah)->ah_ratesArray[rate54mb]); + } + + /* + * Handle HT20/HT40 - we only have to do MCS0-7; + * there's no stream differences. + */ + if ((rate & 0x80) && is_ht40) { + return (AH5416(ah)->ah_ratesArray[rateHt40_0 + (rate & 0x7)]); + } else if (rate & 0x80) { + return (AH5416(ah)->ah_ratesArray[rateHt20_0 + (rate & 0x7)]); + } + + /* XXX default (eg XR, bad bad person!) */ + return (AH5416(ah)->ah_ratesArray[rate6mb]); +} + +/* + * Return the TX power to be used for the given rate/chains/TX power. + * + * There are a bunch of tweaks to make to a given TX power based on + * the current configuration, so... + */ +static uint16_t +ar5416GetTxRatePower(struct ath_hal *ah, uint8_t rate, uint8_t tx_chainmask, + uint16_t txPower, HAL_BOOL is_ht40) +{ + int n_txpower, max_txpower; + const int cck_ofdm_delta = 2; +#define EEP_MINOR(_ah) \ + (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) +#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) + + /* Take a copy ; we may underflow and thus need to clamp things */ + n_txpower = txPower; + + /* HT40? Need to adjust the TX power by this */ + if (is_ht40) + n_txpower += AH5416(ah)->ah_ht40PowerIncForPdadc; + + /* + * Merlin? Offset the target TX power offset - it defaults to + * starting at -5.0dBm, but that can change! + * + * Kiwi/Kite? Always -5.0dBm offset. + */ + if (AR_SREV_KIWI_10_OR_LATER(ah)) { + n_txpower -= (AR5416_PWR_TABLE_OFFSET_DB * 2); + } else if (AR_SREV_MERLIN_20_OR_LATER(ah)) { + int8_t pwr_table_offset = 0; + /* This is in dBm, convert to 1/2 dBm */ + (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, + &pwr_table_offset); + n_txpower -= (pwr_table_offset * 2); + } + + /* + * If Open-loop TX power control is used, the CCK rates need + * to be offset by that. + * + * Rates: 2S, 2L, 1S, 1L, 5.5S, 5.5L + * + * XXX Odd, we don't have a PHY table entry for long preamble + * 1mbit CCK? + */ + if (AR_SREV_MERLIN_20_OR_LATER(ah) && + ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { + + if (rate == 0x19 || rate == 0x1a || rate == 0x1b || + rate == (0x19 | 0x04) || rate == (0x1a | 0x04) || + rate == (0x1b | 0x04)) { + n_txpower -= cck_ofdm_delta; + } + } + + /* + * We're now offset by the same amount that the static maximum + * PHY power tables are. So, clamp the value based on that rate. + */ + max_txpower = ar5416RateToRateTable(ah, rate, is_ht40); +#if 0 + ath_hal_printf(ah, "%s: n_txpower = %d, max_txpower = %d, " + "rate = 0x%x , is_ht40 = %d\n", + __func__, + n_txpower, + max_txpower, + rate, + is_ht40); +#endif + n_txpower = MIN(max_txpower, n_txpower); + + /* + * We don't have to offset the TX power for two or three + * chain operation here - it's done by the AR_PHY_POWER_TX_SUB + * register setting via the EEPROM. + * + * So for vendors that programmed the maximum target power assuming + * that 2/3 chains are always on, things will just plain work. + * (They won't reach that target power if only one chain is on, but + * that's a different problem.) + */ + + /* Over/underflow? Adjust */ + if (n_txpower < 0) + n_txpower = 0; + else if (n_txpower > 63) + n_txpower = 63; + + /* + * For some odd reason the AR9160 with txpower=0 results in a + * much higher (max?) TX power. So, if it's a chipset before + * AR9220/AR9280, just clamp the minimum value at 1. + */ + if ((! AR_SREV_MERLIN_10_OR_LATER(ah)) && (n_txpower == 0)) + n_txpower = 1; + + return (n_txpower); +#undef EEP_MINOR +#undef IS_EEP_MINOR_V2 +} + HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, @@ -187,6 +350,16 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, if (txPower > 63) txPower = 63; + /* + * XXX For now, just assume that this isn't a HT40 frame. + */ + if (AH5212(ah)->ah_tpcEnabled) { + txPower = ar5416GetTxRatePower(ah, txRate0, + ahp->ah_tx_chainmask, + txPower, + AH_FALSE); + } + ads->ds_ctl0 = (pktLen & AR_FrameLen) | (txPower << AR_XmitPower_S) | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0) @@ -238,6 +411,8 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, * Set the TX antenna to 0 for Kite * To preserve existing behaviour, also set the TPC bits to 0; * when TPC is enabled these should be filled in appropriately. + * + * XXX TODO: when doing TPC, set the TX power up appropriately? */ if (AR_SREV_KITE(ah)) { ads->ds_ctl8 = SM(0, AR_AntCtl0); @@ -744,6 +919,48 @@ ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds, | set11nRateFlags(series, 2) | set11nRateFlags(series, 3) | SM(rtsctsRate, AR_RTSCTSRate); + + /* + * Doing per-packet TPC - update the TX power for the first + * field; program in the other series. + */ + if (AH5212(ah)->ah_tpcEnabled) { + uint32_t ds_ctl0; + uint16_t txPower; + + /* Modify the tx power field for rate 0 */ + txPower = ar5416GetTxRatePower(ah, series[0].Rate, + series[0].ChSel, + series[0].tx_power_cap, + !! (series[0].RateFlags & HAL_RATESERIES_2040)); + ds_ctl0 = ads->ds_ctl0 & ~AR_XmitPower; + ds_ctl0 |= (txPower << AR_XmitPower_S); + ads->ds_ctl0 = ds_ctl0; + + /* + * Override the whole descriptor field for each TX power. + * + * This will need changing if we ever support antenna control + * programming. + */ + txPower = ar5416GetTxRatePower(ah, series[1].Rate, + series[1].ChSel, + series[1].tx_power_cap, + !! (series[1].RateFlags & HAL_RATESERIES_2040)); + ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1); + + txPower = ar5416GetTxRatePower(ah, series[2].Rate, + series[2].ChSel, + series[2].tx_power_cap, + !! (series[2].RateFlags & HAL_RATESERIES_2040)); + ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2); + + txPower = ar5416GetTxRatePower(ah, series[3].Rate, + series[3].ChSel, + series[3].tx_power_cap, + !! (series[3].RateFlags & HAL_RATESERIES_2040)); + ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3); + } } /* diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c index 1a0c77b..7a781bb 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c @@ -76,9 +76,7 @@ ar9285SetTransmitPower(struct ath_hal *ah, MODAL_EEP4K_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; @@ -91,8 +89,10 @@ ar9285SetTransmitPower(struct ath_hal *ah, HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); + AH5416(ah)->ah_ht40PowerIncForPdadc = 2; + /* Setup info for the actual eeprom */ - OS_MEMZERO(ratesArray, sizeof(ratesArray)); + OS_MEMZERO(AH5416(ah)->ah_ratesArray, sizeof(AH5416(ah)->ah_ratesArray)); cfgCtl = ath_hal_getctl(ah, chan); powerLimit = chan->ic_maxregpower * 2; twiceAntennaReduction = chan->ic_maxantgain; @@ -102,11 +102,11 @@ ar9285SetTransmitPower(struct ath_hal *ah, __func__,chan->ic_freq, cfgCtl ); if (IS_EEP_MINOR_V2(ah)) { - ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; + AH5416(ah)->ah_ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; } if (!ar9285SetPowerPerRateTable(ah, pEepData, chan, - &ratesArray[0],cfgCtl, + &AH5416(ah)->ah_ratesArray[0],cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit)) { HALDEBUG(ah, HAL_DEBUG_ANY, @@ -120,11 +120,12 @@ ar9285SetTransmitPower(struct ath_hal *ah, return AH_FALSE; } - maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); - maxPower = AH_MAX(maxPower, ratesArray[rate1l]); + maxPower = AH_MAX(AH5416(ah)->ah_ratesArray[rate6mb], + AH5416(ah)->ah_ratesArray[rateHt20_0]); + maxPower = AH_MAX(maxPower, AH5416(ah)->ah_ratesArray[rate1l]); if (IEEE80211_IS_CHAN_HT40(chan)) { - maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); + maxPower = AH_MAX(maxPower, AH5416(ah)->ah_ratesArray[rateHt40_0]); } ahp->ah_tx6PowerInHalfDbm = maxPower; @@ -135,18 +136,18 @@ ar9285SetTransmitPower(struct ath_hal *ah, * txPowerIndexOffset is set by the SetPowerTable() call - * adjust the rate table (0 offset if rates EEPROM not loaded) */ - for (i = 0; i < N(ratesArray); i++) { - ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); + for (i = 0; i < N(AH5416(ah)->ah_ratesArray); i++) { + AH5416(ah)->ah_ratesArray[i] = (int16_t)(txPowerIndexOffset + AH5416(ah)->ah_ratesArray[i]); /* -5 dBm offset for Merlin and later; this includes Kite */ - 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; + AH5416(ah)->ah_ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; + if (AH5416(ah)->ah_ratesArray[i] > AR5416_MAX_RATE_POWER) + AH5416(ah)->ah_ratesArray[i] = AR5416_MAX_RATE_POWER; + if (AH5416(ah)->ah_ratesArray[i] < 0) + AH5416(ah)->ah_ratesArray[i] = 0; } #ifdef AH_EEPROM_DUMP - ar5416PrintPowerPerRate(ah, ratesArray); + ar5416PrintPowerPerRate(ah, AH5416(ah)->ah_ratesArray); #endif /* @@ -157,18 +158,26 @@ ar9285SetTransmitPower(struct ath_hal *ah, * 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; + AH5416(ah)->ah_ratesArray[rateHt40_0] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_1] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_2] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_3] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_4] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_5] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_6] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_7] += + AH5416(ah)->ah_ht40PowerIncForPdadc; } /* Write the TX power rate registers */ - ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray); + ar5416WriteTxPowerRateRegisters(ah, chan, AH5416(ah)->ah_ratesArray); return AH_TRUE; #undef POW_SM diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c index 8b7cecc..5ed4af2 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c @@ -333,9 +333,7 @@ ar9287SetTransmitPower(struct ath_hal *ah, 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; @@ -346,8 +344,11 @@ ar9287SetTransmitPower(struct ath_hal *ah, HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom; struct ar9287_eeprom *pEepData = &ee->ee_base; + AH5416(ah)->ah_ht40PowerIncForPdadc = 2; + /* Setup info for the actual eeprom */ - OS_MEMZERO(ratesArray, sizeof(ratesArray)); + OS_MEMZERO(AH5416(ah)->ah_ratesArray, + sizeof(AH5416(ah)->ah_ratesArray)); cfgCtl = ath_hal_getctl(ah, chan); powerLimit = chan->ic_maxregpower * 2; twiceAntennaReduction = chan->ic_maxantgain; @@ -358,11 +359,12 @@ ar9287SetTransmitPower(struct ath_hal *ah, __func__,chan->ic_freq, cfgCtl ); /* XXX Assume Minor is v2 or later */ - ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; + AH5416(ah)->ah_ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; /* Fetch per-rate power table for the given channel */ if (! ar9287SetPowerPerRateTable(ah, pEepData, chan, - &ratesArray[0],cfgCtl, + &AH5416(ah)->ah_ratesArray[0], + cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit)) { HALDEBUG(ah, HAL_DEBUG_ANY, @@ -374,11 +376,14 @@ ar9287SetTransmitPower(struct ath_hal *ah, ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset); /* Calculate maximum power level */ - maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); - maxPower = AH_MAX(maxPower, ratesArray[rate1l]); + maxPower = AH_MAX(AH5416(ah)->ah_ratesArray[rate6mb], + AH5416(ah)->ah_ratesArray[rateHt20_0]); + maxPower = AH_MAX(maxPower, + AH5416(ah)->ah_ratesArray[rate1l]); if (IEEE80211_IS_CHAN_HT40(chan)) - maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); + maxPower = AH_MAX(maxPower, + AH5416(ah)->ah_ratesArray[rateHt40_0]); ahp->ah_tx6PowerInHalfDbm = maxPower; AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; @@ -389,18 +394,20 @@ ar9287SetTransmitPower(struct ath_hal *ah, * 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]); + for (i = 0; i < N(AH5416(ah)->ah_ratesArray); i++) { + AH5416(ah)->ah_ratesArray[i] = + (int16_t)(txPowerIndexOffset + + AH5416(ah)->ah_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; + AH5416(ah)->ah_ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; + if (AH5416(ah)->ah_ratesArray[i] > AR5416_MAX_RATE_POWER) + AH5416(ah)->ah_ratesArray[i] = AR5416_MAX_RATE_POWER; + if (AH5416(ah)->ah_ratesArray[i] < 0) + AH5416(ah)->ah_ratesArray[i] = 0; } #ifdef AH_EEPROM_DUMP - ar5416PrintPowerPerRate(ah, ratesArray); + ar5416PrintPowerPerRate(ah, AH5416(ah)->ah_ratesArray); #endif /* @@ -411,18 +418,26 @@ ar9287SetTransmitPower(struct ath_hal *ah, * 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; + AH5416(ah)->ah_ratesArray[rateHt40_0] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_1] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_2] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_3] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_4] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_5] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_6] += + AH5416(ah)->ah_ht40PowerIncForPdadc; + AH5416(ah)->ah_ratesArray[rateHt40_7] += + AH5416(ah)->ah_ht40PowerIncForPdadc; } /* Write the TX power rate registers */ - ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray); + ar5416WriteTxPowerRateRegisters(ah, chan, AH5416(ah)->ah_ratesArray); return AH_TRUE; #undef POW_SM |