mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
mt76: rework tx power handling
There were a number of issues in the existing tx power handling code: 1. The EEPROM target power for chain 0 refers to the actual output power after the channel and bandwidth delta have been added to the initial channel gain. This means the delta values should not be added/subtracted for the rate power calculation 2. When power is reduced significantly, the initial channel gain underflows very quickly, while the per-rate power offsets are high. This miscalculation causes effective tx power to be increased when it should actually be lowered. Fix this by trying to adjust the channel gain to the lowest power from the rate table. In case of under- or overflow, compensate by adding an appropriate delta to the rate power values. This makes power configuration more accurate on a wider range of configurable values Signed-off-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
9f67c277a8
commit
80f28994f7
@ -73,16 +73,6 @@ int mt76x2_phy_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain)
|
||||
return rssi;
|
||||
}
|
||||
|
||||
static u8
|
||||
mt76x2_txpower_check(int value)
|
||||
{
|
||||
if (value < 0)
|
||||
return 0;
|
||||
if (value > 0x2f)
|
||||
return 0x2f;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2_add_rate_power_offset(struct mt76_rate_power *r, int offset)
|
||||
{
|
||||
@ -102,6 +92,26 @@ mt76x2_limit_rate_power(struct mt76_rate_power *r, int limit)
|
||||
r->all[i] = limit;
|
||||
}
|
||||
|
||||
static int
|
||||
mt76x2_get_min_rate_power(struct mt76_rate_power *r)
|
||||
{
|
||||
int i;
|
||||
s8 ret = 0;
|
||||
|
||||
for (i = 0; i < sizeof(r->all); i++) {
|
||||
if (!r->all[i])
|
||||
continue;
|
||||
|
||||
if (ret)
|
||||
ret = min(ret, r->all[i]);
|
||||
else
|
||||
ret = r->all[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
|
||||
{
|
||||
enum nl80211_chan_width width = dev->mt76.chandef.width;
|
||||
@ -109,6 +119,7 @@ void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
|
||||
struct mt76x2_tx_power_info txp;
|
||||
int txp_0, txp_1, delta = 0;
|
||||
struct mt76_rate_power t = {};
|
||||
int base_power, gain;
|
||||
|
||||
mt76x2_get_power_info(dev, &txp, chan);
|
||||
|
||||
@ -117,27 +128,33 @@ void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
|
||||
else if (width == NL80211_CHAN_WIDTH_80)
|
||||
delta = txp.delta_bw80;
|
||||
|
||||
if (txp.target_power > dev->txpower_conf)
|
||||
delta -= txp.target_power - dev->txpower_conf;
|
||||
|
||||
mt76x2_get_rate_power(dev, &t, chan);
|
||||
mt76x2_add_rate_power_offset(&t, txp.chain[0].target_power +
|
||||
txp.chain[0].delta);
|
||||
mt76x2_add_rate_power_offset(&t, txp.chain[0].target_power);
|
||||
mt76x2_limit_rate_power(&t, dev->txpower_conf);
|
||||
dev->txpower_cur = mt76x2_get_max_rate_power(&t);
|
||||
mt76x2_add_rate_power_offset(&t, -(txp.chain[0].target_power +
|
||||
txp.chain[0].delta + delta));
|
||||
|
||||
base_power = mt76x2_get_min_rate_power(&t);
|
||||
delta += base_power - txp.chain[0].target_power;
|
||||
txp_0 = txp.chain[0].target_power + txp.chain[0].delta + delta;
|
||||
txp_1 = txp.chain[1].target_power + txp.chain[1].delta + delta;
|
||||
|
||||
gain = min(txp_0, txp_1);
|
||||
if (gain < 0) {
|
||||
base_power -= gain;
|
||||
txp_0 -= gain;
|
||||
txp_1 -= gain;
|
||||
} else if (gain > 0x2f) {
|
||||
base_power -= gain - 0x2f;
|
||||
txp_0 = 0x2f;
|
||||
txp_1 = 0x2f;
|
||||
}
|
||||
|
||||
mt76x2_add_rate_power_offset(&t, -base_power);
|
||||
dev->target_power = txp.chain[0].target_power;
|
||||
dev->target_power_delta[0] = txp.chain[0].delta + delta;
|
||||
dev->target_power_delta[1] = txp.chain[1].delta + delta;
|
||||
dev->target_power_delta[0] = txp_0 - txp.chain[0].target_power;
|
||||
dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power;
|
||||
dev->rate_power = t;
|
||||
|
||||
txp_0 = mt76x2_txpower_check(txp.chain[0].target_power +
|
||||
txp.chain[0].delta + delta);
|
||||
|
||||
txp_1 = mt76x2_txpower_check(txp.chain[1].target_power +
|
||||
txp.chain[1].delta + delta);
|
||||
|
||||
mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_0, txp_0);
|
||||
mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_1, txp_1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user