From: Julan Hsu <[email protected]>

Use bitrate moving average to smooth out link metric and stablize path
selection.

Signed-off-by: Julan Hsu <[email protected]>
---
 net/mac80211/cfg.c       | 5 +++++
 net/mac80211/mesh_hwmp.c | 9 ++++++---
 net/mac80211/sta_info.h  | 4 ++++
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 818aa0060349..31a47d3a122d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1231,6 +1231,11 @@ static void sta_apply_mesh_params(struct ieee80211_local 
*local,
                        ieee80211_mps_sta_status_update(sta);
                        changed |= ieee80211_mps_set_sta_local_pm(sta,
                                      sdata->u.mesh.mshcfg.power_mode);
+
+                       ewma_mesh_tx_rate_avg_init(&sta->mesh->tx_rate_avg);
+                       /* init at low value */
+                       ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10);
+
                        break;
                case NL80211_PLINK_LISTEN:
                case NL80211_PLINK_BLOCKED:
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 6950cd0bf594..34f11be04e64 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -300,6 +300,7 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
 {
        struct ieee80211_tx_info *txinfo = st->info;
        int failed;
+       struct rate_info rinfo;
 
        failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
 
@@ -310,12 +311,15 @@ void ieee80211s_update_metric(struct ieee80211_local 
*local,
        if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) >
                        LINK_FAIL_THRESH)
                mesh_plink_broken(sta);
+
+       sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
+       ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg,
+                                 cfg80211_calculate_bitrate(&rinfo));
 }
 
 static u32 airtime_link_metric_get(struct ieee80211_local *local,
                                   struct sta_info *sta)
 {
-       struct rate_info rinfo;
        /* This should be adjusted for each device */
        int device_constant = 1 << ARITH_SHIFT;
        int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
@@ -339,8 +343,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local 
*local,
                if (fail_avg > LINK_FAIL_THRESH)
                        return MAX_METRIC;
 
-               sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
-               rate = cfg80211_calculate_bitrate(&rinfo);
+               rate = ewma_mesh_tx_rate_avg_read(&sta->mesh->tx_rate_avg);
                if (WARN_ON(!rate))
                        return MAX_METRIC;
 
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9a04327d71d1..b94aeb680d2d 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -343,6 +343,7 @@ struct ieee80211_fast_rx {
 
 /* we use only values in the range 0-100, so pick a large precision */
 DECLARE_EWMA(mesh_fail_avg, 20, 8)
+DECLARE_EWMA(mesh_tx_rate_avg, 8, 16)
 
 /**
  * struct mesh_sta - mesh STA information
@@ -365,6 +366,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  * @processed_beacon: set to true after peer rates and capabilities are
  *     processed
  * @fail_avg: moving percentage of failed MSDUs
+ * @tx_rate_avg: moving average of tx bitrate
  */
 struct mesh_sta {
        struct timer_list plink_timer;
@@ -392,6 +394,8 @@ struct mesh_sta {
 
        /* moving percentage of failed MSDUs */
        struct ewma_mesh_fail_avg fail_avg;
+       /* moving average of tx bitrate */
+       struct ewma_mesh_tx_rate_avg tx_rate_avg;
 };
 
 DECLARE_EWMA(signal, 10, 8)
-- 
2.20.1.97.g81188d93c3-goog

Reply via email to