ath9k_hw: clean up tx power handling
The code for handling various restrictions concerning regulatory limits, antenna gain, etc. is very convoluted and duplicated across various EEPROM parsing implementations, making it hard to review. This patch partially cleans up the mess by unifying regulatory limit handling in one function and simplifying handling of antenna gain. It also removes unused transmit power scaling arrays from the EEPROM code, which belonged to an unimplemented API that isn't supposed to be in the driver anyway. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
72d874c67c
Коммит
ca2c68cc7b
|
@ -71,7 +71,6 @@ struct ath_regulatory {
|
|||
char alpha2[2];
|
||||
u16 country_code;
|
||||
u16 max_power_level;
|
||||
u32 tp_scale;
|
||||
u16 current_rd;
|
||||
u16 current_rd_ext;
|
||||
int16_t power_limit;
|
||||
|
|
|
@ -763,10 +763,8 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
|
|||
static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int i, regWrites = 0;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 modesIndex, freqIndex;
|
||||
|
||||
switch (chan->chanmode) {
|
||||
|
@ -903,14 +901,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
|||
ar5008_hw_set_channel_regs(ah, chan);
|
||||
ar5008_hw_init_chain_masks(ah);
|
||||
ath9k_olc_init(ah);
|
||||
|
||||
/* Set TX power */
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
channel->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
|
||||
/* Write analog registers */
|
||||
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
|
||||
|
|
|
@ -3021,6 +3021,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
|
|||
return (pBase->miscConfiguration >> 0x3) & 0x1;
|
||||
case EEP_ANT_DIV_CTL1:
|
||||
return eep->base_ext1.ant_div_control;
|
||||
case EEP_ANTENNA_GAIN_5G:
|
||||
return eep->modalHeader5G.antennaGain;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
return eep->modalHeader2G.antennaGain;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -4764,20 +4768,14 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
|
|||
static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 *pPwrArray, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] = {
|
||||
0, 3, 6, 9, MAX_RATE_POWER
|
||||
};
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
static const u16 ctlModesFor11a[] = {
|
||||
CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
|
||||
};
|
||||
|
@ -4795,28 +4793,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
|
|||
bool is2ghz = IS_CHAN_2GHZ(chan);
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
/* Compute TxPower reduction due to Antenna Gain */
|
||||
if (is2ghz)
|
||||
twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
|
||||
else
|
||||
twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
|
||||
|
||||
twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
/*
|
||||
* scaledPower is the minimum of the user input power level
|
||||
* and the regulatory allowed power level
|
||||
*/
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
}
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
|
||||
/*
|
||||
* Reduce scaled Power by number of chains active to get
|
||||
|
@ -5003,7 +4980,6 @@ static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
|
|||
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
|
@ -5056,7 +5032,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
|||
ar9003_hw_set_power_per_rate_table(ah, chan,
|
||||
targetPowerValT2, cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
|
||||
|
@ -54,13 +53,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
|||
|
||||
if (val) {
|
||||
ah->paprd_table_write_done = true;
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
chan->chan->max_antenna_gain * 2,
|
||||
chan->chan->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
|
||||
|
|
|
@ -631,9 +631,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
|
|||
static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
unsigned int regWrites = 0, i;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 modesIndex;
|
||||
|
||||
switch (chan->chanmode) {
|
||||
|
@ -693,14 +691,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
|||
ar9003_hw_override_ini(ah);
|
||||
ar9003_hw_set_channel_regs(ah, chan);
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
|
||||
/* Set TX power */
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
channel->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
|
|||
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
|
||||
u16 new_txpow, u16 *txpower)
|
||||
{
|
||||
if (cur_txpow != new_txpow) {
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
|
||||
if (reg->power_limit != new_txpow) {
|
||||
ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
|
||||
/* read back in case value is clamped */
|
||||
*txpower = ath9k_hw_regulatory(ah)->power_limit;
|
||||
*txpower = reg->max_power_level;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_cmn_update_txpow);
|
||||
|
|
|
@ -248,7 +248,9 @@ enum eeprom_param {
|
|||
EEP_PAPRD,
|
||||
EEP_MODAL_VER,
|
||||
EEP_ANT_DIV_CTL1,
|
||||
EEP_CHAIN_MASK_REDUCE
|
||||
EEP_CHAIN_MASK_REDUCE,
|
||||
EEP_ANTENNA_GAIN_2G,
|
||||
EEP_ANTENNA_GAIN_5G
|
||||
};
|
||||
|
||||
enum ar5416_rates {
|
||||
|
@ -652,8 +654,7 @@ struct eeprom_ops {
|
|||
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
|
||||
void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
|
||||
u16 cfgCtl, u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower, u8 powerLimit,
|
||||
bool test);
|
||||
u8 powerLimit, bool test);
|
||||
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
|
||||
};
|
||||
|
||||
|
|
|
@ -350,6 +350,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
|||
return pModal->antdiv_ctl1;
|
||||
case EEP_TXGAIN_TYPE:
|
||||
return pBase->txGainType;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
return pModal->antennaGainCh[0];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -462,8 +464,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
|||
struct ath9k_channel *chan,
|
||||
int16_t *ratesArray,
|
||||
u16 cfgCtl,
|
||||
u16 AntennaReduction,
|
||||
u16 twiceMaxRegulatoryPower,
|
||||
u16 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define CMP_TEST_GRP \
|
||||
|
@ -472,20 +473,16 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
|||
|| (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
|
||||
((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
u16 twiceMinEdgePower;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
u16 numCtlModes;
|
||||
const u16 *pCtlMode;
|
||||
u16 ctlMode, freq;
|
||||
struct chan_centers centers;
|
||||
struct cal_ctl_data_4k *rep;
|
||||
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
|
||||
0, { 0, 0, 0, 0}
|
||||
};
|
||||
|
@ -503,19 +500,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
|||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
|
||||
twiceLargestAntenna = (int16_t)min(AntennaReduction -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
}
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = max((u16)0, scaledPower);
|
||||
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
|
||||
pCtlMode = ctlModesFor11g;
|
||||
|
||||
|
@ -671,7 +656,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
|||
struct ath9k_channel *chan,
|
||||
u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
|
@ -691,7 +675,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
|||
ath9k_hw_set_4k_power_per_rate_table(ah, chan,
|
||||
&ratesArray[0], cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
ath9k_hw_set_4k_power_cal_table(ah, chan);
|
||||
|
|
|
@ -336,6 +336,9 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
|
|||
return pBase->tempSensSlopePalOn;
|
||||
else
|
||||
return 0;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
return max_t(u8, pModal->antennaGainCh[0],
|
||||
pModal->antennaGainCh[1]);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -554,8 +557,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
|||
struct ath9k_channel *chan,
|
||||
int16_t *ratesArray,
|
||||
u16 cfgCtl,
|
||||
u16 AntennaReduction,
|
||||
u16 twiceMaxRegulatoryPower,
|
||||
u16 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define CMP_CTL \
|
||||
|
@ -569,12 +571,8 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
|||
#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
|
||||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
struct cal_ctl_data_ar9287 *rep;
|
||||
struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
|
||||
targetPowerCck = {0, {0, 0, 0, 0} };
|
||||
|
@ -582,7 +580,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
|||
targetPowerCckExt = {0, {0, 0, 0, 0} };
|
||||
struct cal_target_power_ht targetPowerHt20,
|
||||
targetPowerHt40 = {0, {0, 0, 0, 0} };
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
static const u16 ctlModesFor11g[] = {
|
||||
CTL_11B, CTL_11G, CTL_2GHT20,
|
||||
CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
|
||||
|
@ -597,24 +595,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
|||
tx_chainmask = ah->txchainmask;
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
/* Compute TxPower reduction due to Antenna Gain */
|
||||
twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
|
||||
pEepData->modalHeader.antennaGainCh[1]);
|
||||
twiceLargestAntenna = (int16_t)min((AntennaReduction) -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
/*
|
||||
* scaledPower is the minimum of the user input power level
|
||||
* and the regulatory allowed power level.
|
||||
*/
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
|
||||
/*
|
||||
* Reduce scaled Power by number of chains active
|
||||
|
@ -815,7 +796,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
|||
static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
|
@ -834,7 +814,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
|||
ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
|
||||
&ratesArray[0], cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
ath9k_hw_set_ar9287_power_cal_table(ah, chan);
|
||||
|
|
|
@ -400,6 +400,7 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
|||
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
|
||||
struct modal_eep_header *pModal = eep->modalHeader;
|
||||
struct base_eep_header *pBase = &eep->baseEepHeader;
|
||||
int band = 0;
|
||||
|
||||
switch (param) {
|
||||
case EEP_NFTHRESH_5:
|
||||
|
@ -467,6 +468,14 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
|||
return pBase->pwr_table_offset;
|
||||
else
|
||||
return AR5416_PWR_TABLE_OFFSET_DB;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
band = 1;
|
||||
/* fall through */
|
||||
case EEP_ANTENNA_GAIN_5G:
|
||||
return max_t(u8, max_t(u8,
|
||||
pModal[band].antennaGainCh[0],
|
||||
pModal[band].antennaGainCh[1]),
|
||||
pModal[band].antennaGainCh[2]);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -986,21 +995,15 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
|||
struct ath9k_channel *chan,
|
||||
int16_t *ratesArray,
|
||||
u16 cfgCtl,
|
||||
u16 AntennaReduction,
|
||||
u16 twiceMaxRegulatoryPower,
|
||||
u16 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
|
||||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
struct cal_ctl_data *rep;
|
||||
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
|
||||
0, { 0, 0, 0, 0}
|
||||
|
@ -1012,7 +1015,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
|||
struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
|
||||
0, {0, 0, 0, 0}
|
||||
};
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
static const u16 ctlModesFor11a[] = {
|
||||
CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
|
||||
};
|
||||
|
@ -1031,27 +1034,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
|||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
twiceLargestAntenna = max(
|
||||
pEepData->modalHeader
|
||||
[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
|
||||
pEepData->modalHeader
|
||||
[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
|
||||
|
||||
twiceLargestAntenna = max((u8)twiceLargestAntenna,
|
||||
pEepData->modalHeader
|
||||
[IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
|
||||
|
||||
twiceLargestAntenna = (int16_t)min(AntennaReduction -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
}
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
|
||||
switch (ar5416_get_ntxchains(tx_chainmask)) {
|
||||
case 1:
|
||||
|
@ -1256,7 +1239,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
|||
struct ath9k_channel *chan,
|
||||
u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
|
||||
|
@ -1278,7 +1260,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
|||
ath9k_hw_set_def_power_per_rate_table(ah, chan,
|
||||
&ratesArray[0], cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
ath9k_hw_set_def_power_cal_table(ah, chan);
|
||||
|
|
|
@ -433,7 +433,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
|
|||
|
||||
regulatory->country_code = CTRY_DEFAULT;
|
||||
regulatory->power_limit = MAX_RATE_POWER;
|
||||
regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
|
||||
|
||||
ah->hw_version.magic = AR5416_MAGIC;
|
||||
ah->hw_version.subvendorid = 0;
|
||||
|
@ -1389,9 +1388,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
|
|||
static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 qnum;
|
||||
int r;
|
||||
|
||||
|
@ -1416,14 +1413,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
|||
return false;
|
||||
}
|
||||
ath9k_hw_set_clockrate(ah);
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
channel->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_rfbus_done(ah);
|
||||
|
||||
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
|
||||
|
@ -2498,23 +2488,56 @@ bool ath9k_hw_disable(struct ath_hw *ah)
|
|||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_disable);
|
||||
|
||||
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
||||
static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
int reg_pwr = min_t(int, MAX_RATE_POWER, limit);
|
||||
int chan_pwr = channel->max_power * 2;
|
||||
enum eeprom_param gain_param;
|
||||
|
||||
if (test)
|
||||
reg_pwr = chan_pwr = MAX_RATE_POWER;
|
||||
if (IS_CHAN_2GHZ(chan))
|
||||
gain_param = EEP_ANTENNA_GAIN_2G;
|
||||
else
|
||||
gain_param = EEP_ANTENNA_GAIN_5G;
|
||||
|
||||
regulatory->power_limit = reg_pwr;
|
||||
return ah->eep_ops->get_eeprom(ah, gain_param);
|
||||
}
|
||||
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
struct ieee80211_channel *channel;
|
||||
int chan_pwr, new_pwr, max_gain;
|
||||
int ant_gain, ant_reduction = 0;
|
||||
|
||||
if (!chan)
|
||||
return;
|
||||
|
||||
channel = chan->chan;
|
||||
chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
|
||||
new_pwr = min_t(int, chan_pwr, reg->power_limit);
|
||||
max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
|
||||
|
||||
ant_gain = get_antenna_gain(ah, chan);
|
||||
if (ant_gain > max_gain)
|
||||
ant_reduction = ant_gain - max_gain;
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
chan_pwr, reg_pwr, test);
|
||||
ath9k_regd_get_ctl(reg, chan),
|
||||
ant_reduction, new_pwr, false);
|
||||
}
|
||||
|
||||
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
|
||||
reg->power_limit = min_t(int, limit, MAX_RATE_POWER);
|
||||
if (test)
|
||||
channel->max_power = MAX_RATE_POWER / 2;
|
||||
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
|
||||
if (test)
|
||||
channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
|
||||
|
||||
|
|
|
@ -390,14 +390,6 @@ enum ath9k_power_mode {
|
|||
ATH9K_PM_UNDEFINED
|
||||
};
|
||||
|
||||
enum ath9k_tp_scale {
|
||||
ATH9K_TP_SCALE_MAX = 0,
|
||||
ATH9K_TP_SCALE_50,
|
||||
ATH9K_TP_SCALE_25,
|
||||
ATH9K_TP_SCALE_12,
|
||||
ATH9K_TP_SCALE_MIN
|
||||
};
|
||||
|
||||
enum ser_reg_mode {
|
||||
SER_REG_MODE_OFF = 0,
|
||||
SER_REG_MODE_ON = 1,
|
||||
|
@ -968,6 +960,7 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
|
|||
/* PHY */
|
||||
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
|
||||
u32 *coef_mantissa, u32 *coef_exponent);
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
/*
|
||||
* Code Specific to AR5008, AR9001 or AR9002,
|
||||
|
|
|
@ -626,7 +626,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
|
|||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *chan;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
int i;
|
||||
|
||||
sband = &sc->sbands[band];
|
||||
|
@ -635,7 +634,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
|
|||
ah->curchan = &ah->channels[chan->hw_value];
|
||||
ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
|
||||
ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
|
||||
chan->max_power = reg->max_power_level / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче