avr_rssi is not calculated correctly as we do not divide result
by 256 (mt76 sum avg_rssi1 and avg_rssi2 and divide by 512).
However dividing by 256 will make avg_rssi almost the same as
last rssi value - not really an average. So use EWMA to calculate
avg_rssi. I've chosen weight_rcp=4 to convergence quicker on signal
strength changes.
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Jakub Kicinski <[email protected]>
---
drivers/net/wireless/mediatek/mt7601u/mac.c | 4 ++--
drivers/net/wireless/mediatek/mt7601u/mt7601u.h | 5 ++++-
drivers/net/wireless/mediatek/mt7601u/phy.c | 10 +++++++---
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt7601u/mac.c b/drivers/net/wireless/mediatek/mt7601u/mac.c
index d6dc59bb00df..8ec18d69f564 100644
--- a/drivers/net/wireless/mediatek/mt7601u/mac.c
+++ b/drivers/net/wireless/mediatek/mt7601u/mac.c
@@ -437,7 +437,7 @@ void mt7601u_mac_set_ampdu_factor(struct mt7601u_dev *dev)
{
dev->bcn_freq_off = rxwi->freq_off;
dev->bcn_phy_mode = FIELD_GET(MT_RXWI_RATE_PHY, rate);
- dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8);
+ ewma_rssi_add(&dev->avg_rssi, -rssi);
}
static int
@@ -479,7 +479,7 @@ u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb,
if (mt7601u_rx_is_our_beacon(dev, data))
mt7601u_rx_monitor_beacon(dev, rxwi, rate, rssi);
else if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_U2M))
- dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8);
+ ewma_rssi_add(&dev->avg_rssi, -rssi);
spin_unlock_bh(&dev->con_mon_lock);
return len;
diff --git a/drivers/net/wireless/mediatek/mt7601u/mt7601u.h b/drivers/net/wireless/mediatek/mt7601u/mt7601u.h
index c7ec40475a5f..9058b0af7bec 100644
--- a/drivers/net/wireless/mediatek/mt7601u/mt7601u.h
+++ b/drivers/net/wireless/mediatek/mt7601u/mt7601u.h
@@ -23,6 +23,7 @@
#include <linux/completion.h>
#include <net/mac80211.h>
#include <linux/debugfs.h>
+#include <linux/average.h>
#include "regs.h"
@@ -138,6 +139,8 @@ enum {
MT7601U_STATE_MORE_STATS,
};
+DECLARE_EWMA(rssi, 10, 4);
+
/**
* struct mt7601u_dev - adapter structure
* @lock: protects @wcid->tx_rate.
@@ -219,7 +222,7 @@ struct mt7601u_dev {
s8 bcn_freq_off;
u8 bcn_phy_mode;
- int avg_rssi; /* starts at 0 and converges */
+ struct ewma_rssi avg_rssi;
u8 agc_save;
diff --git a/drivers/net/wireless/mediatek/mt7601u/phy.c b/drivers/net/wireless/mediatek/mt7601u/phy.c
index ca09a5d4305e..d440c550bdb1 100644
--- a/drivers/net/wireless/mediatek/mt7601u/phy.c
+++ b/drivers/net/wireless/mediatek/mt7601u/phy.c
@@ -974,6 +974,7 @@ void mt7601u_agc_restore(struct mt7601u_dev *dev)
static void mt7601u_agc_tune(struct mt7601u_dev *dev)
{
u8 val = mt7601u_agc_default(dev);
+ long avg_rssi;
if (test_bit(MT7601U_STATE_SCANNING, &dev->state))
return;
@@ -983,9 +984,12 @@ static void mt7601u_agc_tune(struct mt7601u_dev *dev)
* Rssi updates are only on beacons and U2M so should work...
*/
spin_lock_bh(&dev->con_mon_lock);
- if (dev->avg_rssi <= -70)
+ avg_rssi = ewma_rssi_read(&dev->avg_rssi);
+ WARN_ON_ONCE(avg_rssi == 0);
+ avg_rssi = -avg_rssi;
+ if (avg_rssi <= -70)
val -= 0x20;
- else if (dev->avg_rssi <= -60)
+ else if (avg_rssi <= -60)
val -= 0x10;
spin_unlock_bh(&dev->con_mon_lock);
@@ -1101,7 +1105,7 @@ void mt7601u_phy_con_cal_onoff(struct mt7601u_dev *dev,
/* Start/stop collecting beacon data */
spin_lock_bh(&dev->con_mon_lock);
ether_addr_copy(dev->ap_bssid, info->bssid);
- dev->avg_rssi = 0;
+ ewma_rssi_init(&dev->avg_rssi);
dev->bcn_freq_off = MT_FREQ_OFFSET_INVALID;
spin_unlock_bh(&dev->con_mon_lock);
--
1.9.3
When finishing scanning we switch to operational channel sill with
SCANNING flag. This mean that we never perform calibration works after
scanning. To fix the problem queue calibration works on
.sw_scan_complete() routine.
Signed-off-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/mediatek/mt7601u/main.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt7601u/main.c b/drivers/net/wireless/mediatek/mt7601u/main.c
index 43ebd460ba86..f2ddefaa29f7 100644
--- a/drivers/net/wireless/mediatek/mt7601u/main.c
+++ b/drivers/net/wireless/mediatek/mt7601u/main.c
@@ -285,6 +285,12 @@ static int mt7601u_config(struct ieee80211_hw *hw, u32 changed)
mt7601u_agc_restore(dev);
clear_bit(MT7601U_STATE_SCANNING, &dev->state);
+
+ ieee80211_queue_delayed_work(dev->hw, &dev->cal_work,
+ MT_CALIBRATE_INTERVAL);
+ if (dev->freq_cal.enabled)
+ ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work,
+ MT_FREQ_CAL_INIT_DELAY);
}
static int
--
1.9.3
On Mon, 16 Apr 2018 13:56:18 +0200, Stanislaw Gruszka wrote:
> When finishing scanning we switch to operational channel sill with
> SCANNING flag. This mean that we never perform calibration works after
> scanning. To fix the problem queue calibration works on
> .sw_scan_complete() routine.
>
> Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Jakub Kicinski <[email protected]>
Thank you!!
Stanislaw Gruszka <[email protected]> wrote:
> avr_rssi is not calculated correctly as we do not divide result
> by 256 (mt76 sum avg_rssi1 and avg_rssi2 and divide by 512).
> However dividing by 256 will make avg_rssi almost the same as
> last rssi value - not really an average. So use EWMA to calculate
> avg_rssi. I've chosen weight_rcp=4 to convergence quicker on signal
> strength changes.
>
> Signed-off-by: Stanislaw Gruszka <[email protected]>
> Acked-by: Jakub Kicinski <[email protected]>
2 patches applied to wireless-drivers-next.git, thanks.
b305a6ab0247 mt7601u: use EWMA to calculate avg_rssi
2019c39a2d60 mt7601u: run calibration works after finishing scanning
--
https://patchwork.kernel.org/patch/10342803/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches