]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: add link_sta_statistics ops to fill link station statistics
authorSarika Sharma <quic_sarishar@quicinc.com>
Wed, 28 May 2025 05:44:20 +0000 (11:14 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 24 Jun 2025 13:19:27 +0000 (15:19 +0200)
Currently, link station statistics for MLO are filled by mac80211.
But there are some statistics that kept by mac80211 might not be
accurate, so let the driver pre-fill the link statistics. The driver
can fill the values (indicating which field is filled, by setting the
filled bitmapin in link_station structure).
Statistics that driver don't fill are filled by mac80211.

Hence, add link_sta_statistics callback to fill link station statistics
for MLO in sta_set_link_sinfo() by drivers.

Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com>
Link: https://patch.msgid.link/20250528054420.3050133-11-quic_sarishar@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/driver-ops.h
net/mac80211/sta_info.c
net/mac80211/trace.h

index a305e7f9c6b2038b2af99a3c3fd33d489a992fd0..fa2325692abf94ffe312acaf431c99d4c793cac3 100644 (file)
@@ -4133,6 +4133,15 @@ struct ieee80211_prep_tx_info {
  *     Statistics that the driver doesn't fill will be filled by mac80211.
  *     The callback can sleep.
  *
+ * @link_sta_statistics: Get link statistics for this station. For example with
+ *     beacon filtering, the statistics kept by mac80211 might not be
+ *     accurate, so let the driver pre-fill the statistics. The driver can
+ *     fill most of the values (indicating which by setting the filled
+ *     bitmap), but not all of them make sense - see the source for which
+ *     ones are possible.
+ *     Statistics that the driver doesn't fill will be filled by mac80211.
+ *     The callback can sleep.
+ *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
  *     bursting) for a hardware TX queue.
  *     Returns a negative error code on failure.
@@ -4627,6 +4636,10 @@ struct ieee80211_ops {
                           s64 offset);
        void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
        int (*tx_last_beacon)(struct ieee80211_hw *hw);
+       void (*link_sta_statistics)(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_link_sta *link_sta,
+                                   struct link_station_info *link_sinfo);
 
        /**
         * @ampdu_action:
index 307587c8a0037b8c02591ba8f3f0c48e2b26f18f..ba017bf3fd15b8e70e779c37367a8376cf41d691 100644 (file)
@@ -631,6 +631,25 @@ static inline void drv_sta_statistics(struct ieee80211_local *local,
        trace_drv_return_void(local);
 }
 
+static inline void drv_link_sta_statistics(struct ieee80211_local *local,
+                                          struct ieee80211_sub_if_data *sdata,
+                                          struct ieee80211_link_sta *link_sta,
+                                          struct link_station_info *link_sinfo)
+{
+       might_sleep();
+       lockdep_assert_wiphy(local->hw.wiphy);
+
+       sdata = get_bss_sdata(sdata);
+       if (!check_sdata_in_driver(sdata))
+               return;
+
+       trace_drv_link_sta_statistics(local, sdata, link_sta);
+       if (local->ops->link_sta_statistics)
+               local->ops->link_sta_statistics(&local->hw, &sdata->vif,
+                                               link_sta, link_sinfo);
+       trace_drv_return_void(local);
+}
+
 int drv_conf_tx(struct ieee80211_local *local,
                struct ieee80211_link_data *link, u16 ac,
                const struct ieee80211_tx_queue_params *params);
index 67af43d2e09bb9bea8c0f8bac01c23953408f4e4..89cf365b07e69a06ebee51de9f0fd7c7c9e36b98 100644 (file)
@@ -2744,9 +2744,9 @@ static void sta_set_link_sinfo(struct sta_info *sta,
 
        ether_addr_copy(link_sinfo->addr, link_sta_info->addr);
 
-       /* TODO: add drv_link_sta_statistics() ops to fill link_station
-        * statistics of station.
-        */
+       drv_link_sta_statistics(sta->local, sdata,
+                               link_sta_info->pub,
+                               link_sinfo);
 
        link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) |
                         BIT_ULL(NL80211_STA_INFO_BSS_PARAM) |
index 72fad8ea8bb9aee2c44802f5918f853e745326f9..8215ca58ce5e31acc98de21f312e825a09324128 100644 (file)
@@ -1002,6 +1002,33 @@ DEFINE_EVENT(sta_event, drv_sta_statistics,
        TP_ARGS(local, sdata, sta)
 );
 
+TRACE_EVENT(drv_link_sta_statistics,
+       TP_PROTO(struct ieee80211_local *local,
+                struct ieee80211_sub_if_data *sdata,
+                struct ieee80211_link_sta *link_sta),
+
+       TP_ARGS(local, sdata, link_sta),
+
+       TP_STRUCT__entry(
+               LOCAL_ENTRY
+               VIF_ENTRY
+               STA_ENTRY
+               __field(u32, link_id)
+       ),
+
+       TP_fast_assign(
+               LOCAL_ASSIGN;
+               VIF_ASSIGN;
+               STA_NAMED_ASSIGN(link_sta->sta);
+               __entry->link_id = link_sta->link_id;
+       ),
+
+       TP_printk(
+               LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " (link %d)",
+               LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id
+       )
+);
+
 DEFINE_EVENT(sta_event, drv_sta_add,
        TP_PROTO(struct ieee80211_local *local,
                 struct ieee80211_sub_if_data *sdata,