From: Felix Fietkau Date: Wed, 24 Jun 2026 10:57:55 +0000 (+0200) Subject: mac80211: notify driver on airtime weight changes X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=92143f94b6b35e5b3602c1f9d2cfb6e2f9a63085;p=thirdparty%2Fopenwrt.git mac80211: notify driver on airtime weight changes Add a new sta_set_airtime_weight driver op so drivers can program the airtime fairness weight into hardware. Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/patches/subsys/390-wifi-mac80211-notify-driver-on-airtime-weight-change.patch b/package/kernel/mac80211/patches/subsys/390-wifi-mac80211-notify-driver-on-airtime-weight-change.patch new file mode 100644 index 00000000000..0de78a4b71e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/390-wifi-mac80211-notify-driver-on-airtime-weight-change.patch @@ -0,0 +1,143 @@ +From: Felix Fietkau +Date: Wed, 10 Jun 2026 11:22:25 +0000 +Subject: [PATCH] wifi: mac80211: notify driver on airtime weight changes + +Add a new sta_set_airtime_weight driver op so drivers can program the +airtime fairness weight into hardware. The op is called when the weight +is updated via sta_apply_parameters, and on station upload if a +non-default weight is already set. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -4484,6 +4484,8 @@ struct ieee80211_prep_tx_info { + * @set_sar_specs: Update the SAR (TX power) settings. + * @sta_set_decap_offload: Called to notify the driver when a station is allowed + * to use rx decapsulation offload ++ * @sta_set_airtime_weight: Called to notify the driver of a change to a ++ * station's airtime fairness weight, so it can be programmed in hardware. + * @add_twt_setup: Update hw with TWT agreement parameters received from the peer. + * This callback allows the hw to check if requested parameters + * are supported and if there is enough room for a new agreement. +@@ -4896,6 +4898,9 @@ struct ieee80211_ops { + void (*sta_set_decap_offload)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool enabled); ++ void (*sta_set_airtime_weight)(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, u16 weight); + void (*add_twt_setup)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct ieee80211_twt_setup *twt); +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2298,8 +2298,12 @@ static int sta_apply_parameters(struct i + if (ieee80211_vif_is_mesh(&sdata->vif)) + sta_apply_mesh_params(local, sta, params); + +- if (params->airtime_weight) ++ if (params->airtime_weight) { + sta->airtime_weight = params->airtime_weight; ++ if (sta->uploaded) ++ drv_sta_set_airtime_weight(local, sdata, &sta->sta, ++ sta->airtime_weight); ++ } + + /* set the STA state after all sta info from usermode has been set */ + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -157,6 +157,10 @@ int drv_sta_state(struct ieee80211_local + sta->uploaded = true; + if (rcu_access_pointer(sta->sta.rates)) + drv_sta_rate_tbl_update(local, sdata, &sta->sta); ++ if (sta->airtime_weight != IEEE80211_DEFAULT_AIRTIME_WEIGHT) ++ drv_sta_set_airtime_weight(local, sdata, ++ &sta->sta, ++ sta->airtime_weight); + } + } else if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) { +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1633,6 +1633,25 @@ static inline void drv_sta_set_decap_off + trace_drv_return_void(local); + } + ++static inline void drv_sta_set_airtime_weight(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_sta *sta, ++ u16 weight) ++{ ++ sdata = get_bss_sdata(sdata); ++ ++ might_sleep(); ++ lockdep_assert_wiphy(local->hw.wiphy); ++ if (!check_sdata_in_driver(sdata)) ++ return; ++ ++ trace_drv_sta_set_airtime_weight(local, sdata, sta, weight); ++ if (local->ops->sta_set_airtime_weight) ++ local->ops->sta_set_airtime_weight(&local->hw, &sdata->vif, sta, ++ weight); ++ trace_drv_return_void(local); ++} ++ + static inline void drv_add_twt_setup(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -832,8 +832,13 @@ static int sta_info_insert_drv_state(str + * Drivers using legacy sta_add/sta_remove callbacks only + * get uploaded set to true after sta_add is called. + */ +- if (!local->ops->sta_add) ++ if (!local->ops->sta_add) { + sta->uploaded = true; ++ if (sta->airtime_weight != IEEE80211_DEFAULT_AIRTIME_WEIGHT) ++ drv_sta_set_airtime_weight(local, sdata, ++ &sta->sta, ++ sta->airtime_weight); ++ } + return 0; + } + +--- a/net/mac80211/trace.h ++++ b/net/mac80211/trace.h +@@ -2481,6 +2481,33 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d + TP_ARGS(local, sdata, sta, enabled) + ); + ++TRACE_EVENT(drv_sta_set_airtime_weight, ++ TP_PROTO(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_sta *sta, u16 weight), ++ ++ TP_ARGS(local, sdata, sta, weight), ++ ++ TP_STRUCT__entry( ++ LOCAL_ENTRY ++ VIF_ENTRY ++ STA_ENTRY ++ __field(u16, weight) ++ ), ++ ++ TP_fast_assign( ++ LOCAL_ASSIGN; ++ VIF_ASSIGN; ++ STA_ASSIGN; ++ __entry->weight = weight; ++ ), ++ ++ TP_printk( ++ LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " weight:%u", ++ LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->weight ++ ) ++); ++ + TRACE_EVENT(drv_add_twt_setup, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sta *sta,