Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: mac80211: add link_sta_statistics ops to fill link station statistics

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>

authored by

Sarika Sharma and committed by
Johannes Berg
4cb1ce7e 5e9129f5

+62 -3
+13
include/net/mac80211.h
··· 4133 4133 * Statistics that the driver doesn't fill will be filled by mac80211. 4134 4134 * The callback can sleep. 4135 4135 * 4136 + * @link_sta_statistics: Get link statistics for this station. For example with 4137 + * beacon filtering, the statistics kept by mac80211 might not be 4138 + * accurate, so let the driver pre-fill the statistics. The driver can 4139 + * fill most of the values (indicating which by setting the filled 4140 + * bitmap), but not all of them make sense - see the source for which 4141 + * ones are possible. 4142 + * Statistics that the driver doesn't fill will be filled by mac80211. 4143 + * The callback can sleep. 4144 + * 4136 4145 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), 4137 4146 * bursting) for a hardware TX queue. 4138 4147 * Returns a negative error code on failure. ··· 4636 4627 s64 offset); 4637 4628 void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 4638 4629 int (*tx_last_beacon)(struct ieee80211_hw *hw); 4630 + void (*link_sta_statistics)(struct ieee80211_hw *hw, 4631 + struct ieee80211_vif *vif, 4632 + struct ieee80211_link_sta *link_sta, 4633 + struct link_station_info *link_sinfo); 4639 4634 4640 4635 /** 4641 4636 * @ampdu_action:
+19
net/mac80211/driver-ops.h
··· 631 631 trace_drv_return_void(local); 632 632 } 633 633 634 + static inline void drv_link_sta_statistics(struct ieee80211_local *local, 635 + struct ieee80211_sub_if_data *sdata, 636 + struct ieee80211_link_sta *link_sta, 637 + struct link_station_info *link_sinfo) 638 + { 639 + might_sleep(); 640 + lockdep_assert_wiphy(local->hw.wiphy); 641 + 642 + sdata = get_bss_sdata(sdata); 643 + if (!check_sdata_in_driver(sdata)) 644 + return; 645 + 646 + trace_drv_link_sta_statistics(local, sdata, link_sta); 647 + if (local->ops->link_sta_statistics) 648 + local->ops->link_sta_statistics(&local->hw, &sdata->vif, 649 + link_sta, link_sinfo); 650 + trace_drv_return_void(local); 651 + } 652 + 634 653 int drv_conf_tx(struct ieee80211_local *local, 635 654 struct ieee80211_link_data *link, u16 ac, 636 655 const struct ieee80211_tx_queue_params *params);
+3 -3
net/mac80211/sta_info.c
··· 2744 2744 2745 2745 ether_addr_copy(link_sinfo->addr, link_sta_info->addr); 2746 2746 2747 - /* TODO: add drv_link_sta_statistics() ops to fill link_station 2748 - * statistics of station. 2749 - */ 2747 + drv_link_sta_statistics(sta->local, sdata, 2748 + link_sta_info->pub, 2749 + link_sinfo); 2750 2750 2751 2751 link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | 2752 2752 BIT_ULL(NL80211_STA_INFO_BSS_PARAM) |
+27
net/mac80211/trace.h
··· 1002 1002 TP_ARGS(local, sdata, sta) 1003 1003 ); 1004 1004 1005 + TRACE_EVENT(drv_link_sta_statistics, 1006 + TP_PROTO(struct ieee80211_local *local, 1007 + struct ieee80211_sub_if_data *sdata, 1008 + struct ieee80211_link_sta *link_sta), 1009 + 1010 + TP_ARGS(local, sdata, link_sta), 1011 + 1012 + TP_STRUCT__entry( 1013 + LOCAL_ENTRY 1014 + VIF_ENTRY 1015 + STA_ENTRY 1016 + __field(u32, link_id) 1017 + ), 1018 + 1019 + TP_fast_assign( 1020 + LOCAL_ASSIGN; 1021 + VIF_ASSIGN; 1022 + STA_NAMED_ASSIGN(link_sta->sta); 1023 + __entry->link_id = link_sta->link_id; 1024 + ), 1025 + 1026 + TP_printk( 1027 + LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " (link %d)", 1028 + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id 1029 + ) 1030 + ); 1031 + 1005 1032 DEFINE_EVENT(sta_event, drv_sta_add, 1006 1033 TP_PROTO(struct ieee80211_local *local, 1007 1034 struct ieee80211_sub_if_data *sdata,