From: Felix Fietkau Date: Tue, 27 Jan 2026 09:51:28 +0000 (+0000) Subject: mac80211: backport upstream patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4229e76f30e15b2c550fcbf1372ad0175c98b94;p=thirdparty%2Fopenwrt.git mac80211: backport upstream patches Will be used by an upcoming mt76 update Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-improve-interface-iteration-ergonomics.patch b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-improve-interface-iteration-ergonomics.patch new file mode 100644 index 00000000000..e7c582f8c6a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-improve-interface-iteration-ergonomics.patch @@ -0,0 +1,148 @@ +From: Johannes Berg +Date: Thu, 8 Jan 2026 14:34:31 +0100 +Subject: [PATCH] wifi: mac80211: improve interface iteration ergonomics + +Right now, the only way to iterate interfaces is to declare an +iterator function, possibly data structure to use, and pass all +that to the iteration helper function. This is annoying, and +there's really no inherent need for it, except it was easier to +implement with the iflist mutex, but that's not used much now. + +Add a new for_each_interface() macro that does the iteration in +a more ergonomic way. To avoid even more exported functions, do +the old ieee80211_iterate_active_interfaces_mtx() as an inline +using the new way, which may also let the compiler optimise it +a bit more, e.g. via inlining the iterator function. + +Also provide for_each_active_interface() for the common case of +just iterating active interfaces. + +Link: https://patch.msgid.link/20260108143431.f2581e0c381a.Ie387227504c975c109c125b3c57f0bb3fdab2835@changeid +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6270,6 +6270,30 @@ void ieee80211_iterate_active_interfaces + struct ieee80211_vif *vif), + void *data); + ++struct ieee80211_vif * ++__ieee80211_iterate_interfaces(struct ieee80211_hw *hw, ++ struct ieee80211_vif *prev, ++ u32 iter_flags); ++ ++/** ++ * for_each_interface - iterate interfaces under wiphy mutex ++ * @vif: the iterator variable ++ * @hw: the HW to iterate for ++ * @flags: the iteration flags, see &enum ieee80211_interface_iteration_flags ++ */ ++#define for_each_interface(vif, hw, flags) \ ++ for (vif = __ieee80211_iterate_interfaces(hw, NULL, flags); \ ++ vif; \ ++ vif = __ieee80211_iterate_interfaces(hw, vif, flags)) ++ ++/** ++ * for_each_active_interface - iterate active interfaces under wiphy mutex ++ * @vif: the iterator variable ++ * @hw: the HW to iterate for ++ */ ++#define for_each_active_interface(vif, hw) \ ++ for_each_interface(vif, hw, IEEE80211_IFACE_ITER_ACTIVE) ++ + /** + * ieee80211_iterate_active_interfaces_mtx - iterate active interfaces + * +@@ -6282,12 +6306,18 @@ void ieee80211_iterate_active_interfaces + * @iterator: the iterator function to call, cannot sleep + * @data: first argument of the iterator function + */ +-void ieee80211_iterate_active_interfaces_mtx(struct ieee80211_hw *hw, +- u32 iter_flags, +- void (*iterator)(void *data, +- u8 *mac, +- struct ieee80211_vif *vif), +- void *data); ++static inline void ++ieee80211_iterate_active_interfaces_mtx(struct ieee80211_hw *hw, ++ u32 iter_flags, ++ void (*iterator)(void *data, u8 *mac, ++ struct ieee80211_vif *vif), ++ void *data) ++{ ++ struct ieee80211_vif *vif; ++ ++ for_each_interface(vif, hw, iter_flags | IEEE80211_IFACE_ITER_ACTIVE) ++ iterator(data, vif->addr, vif); ++} + + /** + * ieee80211_iterate_stations_atomic - iterate stations +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -800,20 +800,56 @@ void ieee80211_iterate_active_interfaces + } + EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); + +-void ieee80211_iterate_active_interfaces_mtx( +- struct ieee80211_hw *hw, u32 iter_flags, +- void (*iterator)(void *data, u8 *mac, +- struct ieee80211_vif *vif), +- void *data) ++struct ieee80211_vif * ++__ieee80211_iterate_interfaces(struct ieee80211_hw *hw, ++ struct ieee80211_vif *prev, ++ u32 iter_flags) + { ++ bool active_only = iter_flags & IEEE80211_IFACE_ITER_ACTIVE; ++ struct ieee80211_sub_if_data *sdata = NULL, *monitor; + struct ieee80211_local *local = hw_to_local(hw); + + lockdep_assert_wiphy(hw->wiphy); + +- __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, +- iterator, data); ++ if (prev) ++ sdata = vif_to_sdata(prev); ++ ++ monitor = rcu_dereference_check(local->monitor_sdata, ++ lockdep_is_held(&hw->wiphy->mtx)); ++ if (monitor && monitor == sdata) ++ return NULL; ++ ++ sdata = list_prepare_entry(sdata, &local->interfaces, list); ++ list_for_each_entry_continue(sdata, &local->interfaces, list) { ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_MONITOR: ++ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) && ++ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) ++ continue; ++ break; ++ case NL80211_IFTYPE_AP_VLAN: ++ continue; ++ default: ++ break; ++ } ++ if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && ++ active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) ++ continue; ++ if ((iter_flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) && ++ !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) ++ continue; ++ if (ieee80211_sdata_running(sdata) || !active_only) ++ return &sdata->vif; ++ } ++ ++ if (monitor && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && ++ (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only || ++ monitor->flags & IEEE80211_SDATA_IN_DRIVER)) ++ return &monitor->vif; ++ ++ return NULL; + } +-EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_mtx); ++EXPORT_SYMBOL_GPL(__ieee80211_iterate_interfaces); + + static void __iterate_stations(struct ieee80211_local *local, + void (*iterator)(void *data, diff --git a/package/kernel/mac80211/patches/subsys/363-wifi-mac80211-improve-station-iteration-ergonomics.patch b/package/kernel/mac80211/patches/subsys/363-wifi-mac80211-improve-station-iteration-ergonomics.patch new file mode 100644 index 00000000000..c85008c3c1c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/363-wifi-mac80211-improve-station-iteration-ergonomics.patch @@ -0,0 +1,102 @@ +From: Johannes Berg +Date: Thu, 8 Jan 2026 14:34:32 +0100 +Subject: [PATCH] wifi: mac80211: improve station iteration ergonomics + +Right now, the only way to iterate stations is to declare an +iterator function, possibly data structure to use, and pass all +that to the iteration helper function. This is annoying, and +there's really no inherent need for it. + +Add a new for_each_station() macro that does the iteration in +a more ergonomic way. To avoid even more exported functions, do +the old ieee80211_iterate_stations_mtx() as an inline using the +new way, which may also let the compiler optimise it a bit more, +e.g. via inlining the iterator function. + +Link: https://patch.msgid.link/20260108143431.d2b641f6f6af.I4470024f7404446052564b15bcf8b3f1ada33655@changeid +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6336,6 +6336,20 @@ void ieee80211_iterate_stations_atomic(s + struct ieee80211_sta *sta), + void *data); + ++struct ieee80211_sta * ++__ieee80211_iterate_stations(struct ieee80211_hw *hw, ++ struct ieee80211_sta *prev); ++ ++/** ++ * for_each_station - iterate stations under wiphy mutex ++ * @sta: the iterator variable ++ * @hw: the HW to iterate for ++ */ ++#define for_each_station(sta, hw) \ ++ for (sta = __ieee80211_iterate_stations(hw, NULL); \ ++ sta; \ ++ sta = __ieee80211_iterate_stations(hw, sta)) ++ + /** + * ieee80211_iterate_stations_mtx - iterate stations + * +@@ -6348,10 +6362,17 @@ void ieee80211_iterate_stations_atomic(s + * @iterator: the iterator function to call + * @data: first argument of the iterator function + */ +-void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, +- void (*iterator)(void *data, +- struct ieee80211_sta *sta), +- void *data); ++static inline void ++ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data) ++{ ++ struct ieee80211_sta *sta; ++ ++ for_each_station(sta, hw) ++ iterator(data, sta); ++} + + /** + * ieee80211_queue_work - add work onto the mac80211 workqueue +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -880,18 +880,29 @@ void ieee80211_iterate_stations_atomic(s + } + EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic); + +-void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, +- void (*iterator)(void *data, +- struct ieee80211_sta *sta), +- void *data) ++struct ieee80211_sta * ++__ieee80211_iterate_stations(struct ieee80211_hw *hw, ++ struct ieee80211_sta *prev) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct sta_info *sta = NULL; + + lockdep_assert_wiphy(local->hw.wiphy); + +- __iterate_stations(local, iterator, data); ++ if (prev) ++ sta = container_of(prev, struct sta_info, sta); ++ ++ sta = list_prepare_entry(sta, &local->sta_list, list); ++ list_for_each_entry_continue(sta, &local->sta_list, list) { ++ if (!sta->uploaded) ++ continue; ++ ++ return &sta->sta; ++ } ++ ++ return NULL; + } +-EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_mtx); ++EXPORT_SYMBOL_GPL(__ieee80211_iterate_stations); + + struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) + {