]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
mac80211: backport upstream patches
authorFelix Fietkau <nbd@nbd.name>
Tue, 27 Jan 2026 09:51:28 +0000 (09:51 +0000)
committerFelix Fietkau <nbd@nbd.name>
Wed, 28 Jan 2026 11:37:29 +0000 (12:37 +0100)
Will be used by an upcoming mt76 update

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/subsys/362-wifi-mac80211-improve-interface-iteration-ergonomics.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/363-wifi-mac80211-improve-station-iteration-ergonomics.patch [new file with mode: 0644]

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 (file)
index 0000000..e7c582f
--- /dev/null
@@ -0,0 +1,148 @@
+From: Johannes Berg <johannes.berg@intel.com>
+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 <johannes.berg@intel.com>
+---
+
+--- 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 (file)
index 0000000..c85008c
--- /dev/null
@@ -0,0 +1,102 @@
+From: Johannes Berg <johannes.berg@intel.com>
+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 <johannes.berg@intel.com>
+---
+
+--- 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)
+ {