Просмотр исходного кода

mac80211: backport upstream patches

Will be used by an upcoming mt76 update

Signed-off-by: Felix Fietkau <[email protected]>
Felix Fietkau 2 недель назад
Родитель
Сommit
c4229e76f3

+ 148 - 0
package/kernel/mac80211/patches/subsys/362-wifi-mac80211-improve-interface-iteration-ergonomics.patch

@@ -0,0 +1,148 @@
+From: Johannes Berg <[email protected]>
+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 <[email protected]>
+---
+
+--- 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,

+ 102 - 0
package/kernel/mac80211/patches/subsys/363-wifi-mac80211-improve-station-iteration-ergonomics.patch

@@ -0,0 +1,102 @@
+From: Johannes Berg <[email protected]>
+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 <[email protected]>
+---
+
+--- 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)
+ {