Commit c3ae2103 authored by Felix Fietkau's avatar Felix Fietkau Committed by Kalle Valo

mt76: improve gain adjustment in noisy environments

When switching between low gain (high RSSI) and high gain settings, it
can take a few seconds to adjust to the current environment.
This can lead to short periods of time with extreme packet loss.

When switching from low_gain=1 to low_gain=2, start with the same gain
adjustment value instead of the lowest to avoid spikes of huge numbers
of false CCA events

Also avoid resetting adjustment values on switching between low_gain
values 0 and 1, since it affects only the upper limit of vga adjustment
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 32e49efe
...@@ -491,7 +491,8 @@ mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev) ...@@ -491,7 +491,8 @@ mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
dev->cal.false_cca = false_cca; dev->cal.false_cca = false_cca;
if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
dev->cal.agc_gain_adjust += 2; dev->cal.agc_gain_adjust += 2;
else if (false_cca < 10 && dev->cal.agc_gain_adjust > 0) else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) ||
(dev->cal.agc_gain_adjust >= limit && false_cca < 500))
dev->cal.agc_gain_adjust -= 2; dev->cal.agc_gain_adjust -= 2;
else else
return; return;
...@@ -550,7 +551,8 @@ static void ...@@ -550,7 +551,8 @@ static void
mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev) mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
{ {
u8 *gain = dev->cal.agc_gain_init; u8 *gain = dev->cal.agc_gain_init;
u8 gain_delta; u8 low_gain_delta, gain_delta;
bool gain_change;
int low_gain; int low_gain;
u32 val; u32 val;
...@@ -559,13 +561,14 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev) ...@@ -559,13 +561,14 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) + low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
(dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev)); (dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev));
if (dev->cal.low_gain == low_gain) { gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
dev->cal.low_gain = low_gain;
if (!gain_change) {
mt76x2_phy_adjust_vga_gain(dev); mt76x2_phy_adjust_vga_gain(dev);
return; return;
} }
dev->cal.low_gain = low_gain;
if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) { if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) {
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211); mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211);
val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf; val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf;
...@@ -578,14 +581,17 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev) ...@@ -578,14 +581,17 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423); mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
} }
if (mt76x2_has_ext_lna(dev))
low_gain_delta = 10;
else
low_gain_delta = 14;
if (low_gain == 2) { if (low_gain == 2) {
mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990); mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808); mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808);
mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808); mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808);
if (mt76x2_has_ext_lna(dev)) gain_delta = low_gain_delta;
gain_delta = 10; dev->cal.agc_gain_adjust = 0;
else
gain_delta = 14;
} else { } else {
mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991); mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80)
...@@ -594,11 +600,11 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev) ...@@ -594,11 +600,11 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116); mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116);
mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C); mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C);
gain_delta = 0; gain_delta = 0;
dev->cal.agc_gain_adjust = low_gain_delta;
} }
dev->cal.agc_gain_cur[0] = gain[0] - gain_delta; dev->cal.agc_gain_cur[0] = gain[0] - gain_delta;
dev->cal.agc_gain_cur[1] = gain[1] - gain_delta; dev->cal.agc_gain_cur[1] = gain[1] - gain_delta;
dev->cal.agc_gain_adjust = 0;
mt76x2_phy_set_gain_val(dev); mt76x2_phy_set_gain_val(dev);
/* clear false CCA counters */ /* clear false CCA counters */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment