The 10.4 firmware adds extended peer information to the
firmware's statistics payload. This additional info is
stored as a separate data field. During review of
"ath10k: add accounting for the extended peer statistics" [0]

Mohammed Shafi Shajakhan commented that the extended peer statistics
lists are of little use:"... there is not much use in appending
the extended peer stats (which gets periodically updated) to the
linked list '&ar->debug.fw_stats.peers_extd)' and should we get
rid of the below (and the required cleanup as well)

list_splice_tail_init(&stats.peers_extd,
                &ar->debug.fw_stats.peers_extd);

since rx_duration is getting updated periodically to the per sta
information."

This patch replaces the extended peers list with a lookup and
puts the retrieved data (rx_duration) into the existing
ath10k_fw_stats_peer entry that was created earlier.

[0] 
<https://lkml.kernel.org/r/992a4e2676037a06f482cdbe2d3d39e287530be5.1480974623.git.chunk...@googlemail.com>
Cc: Mohammed Shafi Shajakhan <moham...@codeaurora.org>
Signed-off-by: Christian Lamparter <chunk...@googlemail.com>
---
 drivers/net/wireless/ath/ath10k/core.h        |  2 --
 drivers/net/wireless/ath/ath10k/debug.c       | 17 --------------
 drivers/net/wireless/ath/ath10k/debugfs_sta.c | 32 ++-----------------------
 drivers/net/wireless/ath/ath10k/wmi.c         | 34 ++++++++++++++++++++-------
 4 files changed, 28 insertions(+), 57 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 09ff8b8a6441..3fffbbb18c25 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -268,11 +268,9 @@ struct ath10k_fw_stats_pdev {
 };
 
 struct ath10k_fw_stats {
-       bool extended;
        struct list_head pdevs;
        struct list_head vdevs;
        struct list_head peers;
-       struct list_head peers_extd;
 };
 
 #define ATH10K_TPC_TABLE_TYPE_FLAG     1
diff --git a/drivers/net/wireless/ath/ath10k/debug.c 
b/drivers/net/wireless/ath/ath10k/debug.c
index 82a4c67f3672..89f7fde77cdf 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -315,25 +315,13 @@ static void ath10k_fw_stats_peers_free(struct list_head 
*head)
        }
 }
 
-static void ath10k_fw_extd_stats_peers_free(struct list_head *head)
-{
-       struct ath10k_fw_extd_stats_peer *i, *tmp;
-
-       list_for_each_entry_safe(i, tmp, head, list) {
-               list_del(&i->list);
-               kfree(i);
-       }
-}
-
 static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
 {
        spin_lock_bh(&ar->data_lock);
        ar->debug.fw_stats_done = false;
-       ar->debug.fw_stats.extended = false;
        ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
        ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
        ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
-       ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
        spin_unlock_bh(&ar->data_lock);
 }
 
@@ -348,7 +336,6 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, 
struct sk_buff *skb)
        INIT_LIST_HEAD(&stats.pdevs);
        INIT_LIST_HEAD(&stats.vdevs);
        INIT_LIST_HEAD(&stats.peers);
-       INIT_LIST_HEAD(&stats.peers_extd);
 
        spin_lock_bh(&ar->data_lock);
        ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats);
@@ -411,8 +398,6 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, 
struct sk_buff *skb)
 
                list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
                list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
-               list_splice_tail_init(&stats.peers_extd,
-                                     &ar->debug.fw_stats.peers_extd);
        }
 
        complete(&ar->debug.fw_stats_complete);
@@ -424,7 +409,6 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, 
struct sk_buff *skb)
        ath10k_fw_stats_pdevs_free(&stats.pdevs);
        ath10k_fw_stats_vdevs_free(&stats.vdevs);
        ath10k_fw_stats_peers_free(&stats.peers);
-       ath10k_fw_extd_stats_peers_free(&stats.peers_extd);
 
        spin_unlock_bh(&ar->data_lock);
 }
@@ -2347,7 +2331,6 @@ int ath10k_debug_create(struct ath10k *ar)
        INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
        INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
        INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
-       INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd);
 
        return 0;
 }
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c 
b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index fce6f8137d33..bf2d49cbb3bb 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -18,27 +18,8 @@
 #include "wmi-ops.h"
 #include "debug.h"
 
-static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
-                                                    struct ath10k_fw_stats 
*stats)
-{
-       struct ath10k_fw_extd_stats_peer *peer;
-       struct ieee80211_sta *sta;
-       struct ath10k_sta *arsta;
-
-       rcu_read_lock();
-       list_for_each_entry(peer, &stats->peers_extd, list) {
-               sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
-                                                  NULL);
-               if (!sta)
-                       continue;
-               arsta = (struct ath10k_sta *)sta->drv_priv;
-               arsta->rx_duration += (u64)peer->rx_duration;
-       }
-       rcu_read_unlock();
-}
-
-static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar,
-                                               struct ath10k_fw_stats *stats)
+void ath10k_sta_update_rx_duration(struct ath10k *ar,
+                                  struct ath10k_fw_stats *stats)
 {
        struct ath10k_fw_stats_peer *peer;
        struct ieee80211_sta *sta;
@@ -56,15 +37,6 @@ static void ath10k_sta_update_stats_rx_duration(struct 
ath10k *ar,
        rcu_read_unlock();
 }
 
-void ath10k_sta_update_rx_duration(struct ath10k *ar,
-                                  struct ath10k_fw_stats *stats)
-{
-       if (stats->extended)
-               ath10k_sta_update_extd_stats_rx_duration(ar, stats);
-       else
-               ath10k_sta_update_stats_rx_duration(ar, stats);
-}
-
 void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                           struct ieee80211_sta *sta,
                           struct station_info *sinfo)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index c893314a191f..c7ec7b9e9b55 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -3044,23 +3044,41 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct 
ath10k *ar,
        if ((stats_id & WMI_10_4_STAT_PEER_EXTD) == 0)
                return 0;
 
-       stats->extended = true;
-
        for (i = 0; i < num_peer_stats; i++) {
                const struct wmi_10_4_peer_extd_stats *src;
-               struct ath10k_fw_extd_stats_peer *dst;
+               struct ath10k_fw_stats_peer *dst;
 
                src = (void *)skb->data;
                if (!skb_pull(skb, sizeof(*src)))
                        return -EPROTO;
 
-               dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
-               if (!dst)
-                       continue;
+               /* Because the stat data may exceed htc-wmi buffer
+                * limit the firmware might split the stats data
+                * and delivers it in multiple update events.
+                * if we can't find the entry in the current event
+                * payload, we have to look in main list as well.
+                */
+               list_for_each_entry(dst, &stats->peers, list) {
+                       if (ether_addr_equal(dst->peer_macaddr,
+                                            src->peer_macaddr.addr))
+                               goto found;
+               }
+
+#ifdef CONFIG_ATH10K_DEBUGFS
+               list_for_each_entry(dst, &ar->debug.fw_stats.peers, list) {
+                       if (ether_addr_equal(dst->peer_macaddr,
+                                            src->peer_macaddr.addr))
+                               goto found;
+               }
+#endif
+
+               ath10k_dbg(ar, ATH10K_DBG_WMI,
+                          "Orphaned extended stats entry for station %pM.\n",
+                          src->peer_macaddr.addr);
+               continue;
 
-               ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
+found:
                dst->rx_duration = __le32_to_cpu(src->rx_duration);
-               list_add_tail(&dst->list, &stats->peers_extd);
        }
 
        return 0;
-- 
2.11.0


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

Reply via email to