diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h index c5ff6ae7a5e..a631aadda70 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 5f8f2ad5b65..41d63e25587 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 f17cc8a52bd..47e8c356235 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 1a0c77be26d..7a781bb6d73 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 8b7cecc3fbb..5ed4af2330f 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