All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi
@ 2018-04-13 14:44 Stanislaw Gruszka
  2018-04-13 14:44 ` [PATCH 2/2] mt7601u: run calibration works after finishing scanning Stanislaw Gruszka
  2018-04-13 18:06 ` [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi Jakub Kicinski
  0 siblings, 2 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2018-04-13 14:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: Jakub Kicinski, Stanislaw Gruszka

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 <sgruszka@redhat.com>
---
 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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] mt7601u: run calibration works after finishing scanning
  2018-04-13 14:44 [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi Stanislaw Gruszka
@ 2018-04-13 14:44 ` Stanislaw Gruszka
  2018-04-13 18:06   ` Jakub Kicinski
  2018-04-13 18:06 ` [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi Jakub Kicinski
  1 sibling, 1 reply; 6+ messages in thread
From: Stanislaw Gruszka @ 2018-04-13 14:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: Jakub Kicinski, Stanislaw Gruszka

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 cancel and queue calibration works on
.sw_scan_start() and .sw_scan_complete() routines.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt7601u/main.c |  9 +++++++++
 drivers/net/wireless/mediatek/mt7601u/phy.c  | 15 +--------------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt7601u/main.c b/drivers/net/wireless/mediatek/mt7601u/main.c
index 43ebd460ba86..a09b92a9137d 100644
--- a/drivers/net/wireless/mediatek/mt7601u/main.c
+++ b/drivers/net/wireless/mediatek/mt7601u/main.c
@@ -273,6 +273,9 @@ static int mt7601u_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct mt7601u_dev *dev = hw->priv;
 
+	cancel_delayed_work_sync(&dev->cal_work);
+	cancel_delayed_work_sync(&dev->freq_cal.work);
+
 	mt7601u_agc_save(dev);
 	set_bit(MT7601U_STATE_SCANNING, &dev->state);
 }
@@ -285,6 +288,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
diff --git a/drivers/net/wireless/mediatek/mt7601u/phy.c b/drivers/net/wireless/mediatek/mt7601u/phy.c
index d440c550bdb1..e5fe3bef596e 100644
--- a/drivers/net/wireless/mediatek/mt7601u/phy.c
+++ b/drivers/net/wireless/mediatek/mt7601u/phy.c
@@ -452,24 +452,11 @@ int mt7601u_phy_set_channel(struct mt7601u_dev *dev,
 {
 	int ret;
 
-	cancel_delayed_work_sync(&dev->cal_work);
-	cancel_delayed_work_sync(&dev->freq_cal.work);
-
 	mutex_lock(&dev->hw_atomic_mutex);
 	ret = __mt7601u_phy_set_channel(dev, chandef);
 	mutex_unlock(&dev->hw_atomic_mutex);
-	if (ret)
-		return ret;
-
-	if (test_bit(MT7601U_STATE_SCANNING, &dev->state))
-		return 0;
 
-	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);
-	return 0;
+	return ret;
 }
 
 #define BBP_R47_FLAG		GENMASK(2, 0)
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] mt7601u: run calibration works after finishing scanning
  2018-04-13 14:44 ` [PATCH 2/2] mt7601u: run calibration works after finishing scanning Stanislaw Gruszka
@ 2018-04-13 18:06   ` Jakub Kicinski
  2018-04-14 10:56     ` Stanislaw Gruszka
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Kicinski @ 2018-04-13 18:06 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless

On Fri, 13 Apr 2018 16:44:38 +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 cancel and queue calibration works on
> .sw_scan_start() and .sw_scan_complete() routines.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>

IOW the stack will potentially ask us to return to the original channel
before calling .sw_scan_complete()?  Hm.  That's unpleasant.

I'm not entirely on board with the patch.  Now normal channel setting
will happen while calibration is running.  Is that necessary?  Would it
not be sufficient to make sure work is scheduled
from .sw_scan_complete()?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi
  2018-04-13 14:44 [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi Stanislaw Gruszka
  2018-04-13 14:44 ` [PATCH 2/2] mt7601u: run calibration works after finishing scanning Stanislaw Gruszka
@ 2018-04-13 18:06 ` Jakub Kicinski
  1 sibling, 0 replies; 6+ messages in thread
From: Jakub Kicinski @ 2018-04-13 18:06 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless

On Fri, 13 Apr 2018 16:44:37 +0200, Stanislaw Gruszka 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 <sgruszka@redhat.com>

Acked-by: Jakub Kicinski <kubakici@wp.pl>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] mt7601u: run calibration works after finishing scanning
  2018-04-13 18:06   ` Jakub Kicinski
@ 2018-04-14 10:56     ` Stanislaw Gruszka
  2018-04-16 18:45       ` Arend van Spriel
  0 siblings, 1 reply; 6+ messages in thread
From: Stanislaw Gruszka @ 2018-04-14 10:56 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: linux-wireless

On Fri, Apr 13, 2018 at 11:06:13AM -0700, Jakub Kicinski wrote:
> On Fri, 13 Apr 2018 16:44:38 +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 cancel and queue calibration works on
> > .sw_scan_start() and .sw_scan_complete() routines.
> > 
> > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> 
> IOW the stack will potentially ask us to return to the original channel
> before calling .sw_scan_complete()?  Hm.  That's unpleasant.

I think the stack need to assure we start and end scanning on
operational channel, otherwise we would have possibility to be on
undefined channel during normal work.

> I'm not entirely on board with the patch.  Now normal channel setting
> will happen while calibration is running.  Is that necessary? 
> Would it not be sufficient to make sure work is scheduled
> from .sw_scan_complete()?

Yes, that would be sufficient, I'll post v2.

Thanks
Stanislaw

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] mt7601u: run calibration works after finishing scanning
  2018-04-14 10:56     ` Stanislaw Gruszka
@ 2018-04-16 18:45       ` Arend van Spriel
  0 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2018-04-16 18:45 UTC (permalink / raw)
  To: Stanislaw Gruszka, Jakub Kicinski; +Cc: linux-wireless

On 4/14/2018 12:56 PM, Stanislaw Gruszka wrote:
> On Fri, Apr 13, 2018 at 11:06:13AM -0700, Jakub Kicinski wrote:
>> >On Fri, 13 Apr 2018 16:44:38 +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 cancel and queue calibration works on
>>> > >.sw_scan_start() and .sw_scan_complete() routines.
>>> > >
>>> > >Signed-off-by: Stanislaw Gruszka<sgruszka@redhat.com>
>> >
>> >IOW the stack will potentially ask us to return to the original channel
>> >before calling .sw_scan_complete()?  Hm.  That's unpleasant.
> I think the stack need to assure we start and end scanning on
> operational channel, otherwise we would have possibility to be on
> undefined channel during normal work.

Returning to the operating channels during scanning is mostly important 
when connected so you can receive the beacon of your AP and mc/bc 
traffic and also to handle regular unicast traffic so you are not 
screwing up your TCP window too much for instance.

Regards,
Arend

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-04-16 18:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-13 14:44 [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi Stanislaw Gruszka
2018-04-13 14:44 ` [PATCH 2/2] mt7601u: run calibration works after finishing scanning Stanislaw Gruszka
2018-04-13 18:06   ` Jakub Kicinski
2018-04-14 10:56     ` Stanislaw Gruszka
2018-04-16 18:45       ` Arend van Spriel
2018-04-13 18:06 ` [PATCH 1/2] mt7601u: use EWMA to calculate avg_rssi Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.