Search Linux Wireless

[virtual-sta 1/3] mac80211: Add more general interface iterator.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ben Greear <greearb@xxxxxxxxxxxxxxx>

This allows callers to specify whether they want all
or just active interfaces, and whether their iterator
is atomic or not.  A count for the number of interfaces
is returned to remove need for similar logic in the
drivers.

Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx>
---
:100644 100644 f91fc33... 53e5d5b... M	include/net/mac80211.h
:100644 100644 bd40b11... ad96d5f... M	net/mac80211/util.c
 include/net/mac80211.h |   24 +++++++++++
 net/mac80211/util.c    |  102 +++++++++++++++++++++++++++---------------------
 2 files changed, 82 insertions(+), 44 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f91fc33..53e5d5b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2320,6 +2320,30 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
 						    u8 *mac,
 						    struct ieee80211_vif *vif),
 						void *data);
+/**
+ * ieee80211_iterate_interfaces_helper - iterate interfaces
+ *
+ * This function iterates over the interfaces associated with a given
+ * hardware and calls the callback for them.  If do_atomic is true,
+ * this function requires the iterator callback function to be atomic,
+ * if that is not desired, set do_atomic to false.
+ * If you want only active interfaces, set active_only to true.
+ * See also: @ieee80211_iterate_active_interfaces
+ *           @ieee80211_iterate_active_interfaces_atomic
+ *
+ * Returns number of interfaces to be filtered.
+ * @hw: the hardware struct of which the interfaces should be iterated over
+ * @do_atomic:  Should iterator be treated as atomic or not.
+ * @active_only:  Should we only iterate over active interfaces.
+ * @iterator: the iterator function to call, cannot sleep
+ * @data: first argument of the iterator function
+ */
+int ieee80211_iterate_interfaces_helper(struct ieee80211_hw *hw,
+					bool do_atomic,
+					bool active_only,
+					void (*iterator)(void *data, u8 *mac,
+						struct ieee80211_vif *vif),
+					void *data);
 
 /**
  * ieee80211_queue_work - add work onto the mac80211 workqueue
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index bd40b11..ad96d5f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -461,71 +461,85 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
 }
 EXPORT_SYMBOL(ieee80211_wake_queues);
 
-void ieee80211_iterate_active_interfaces(
-	struct ieee80211_hw *hw,
+static int _iter_loop_helper(
+	struct ieee80211_sub_if_data *sdata,
+	bool active_only,
 	void (*iterator)(void *data, u8 *mac,
 			 struct ieee80211_vif *vif),
 	void *data)
 {
-	struct ieee80211_local *local = hw_to_local(hw);
-	struct ieee80211_sub_if_data *sdata;
-
-	mutex_lock(&local->iflist_mtx);
-
-	list_for_each_entry(sdata, &local->interfaces, list) {
-		switch (sdata->vif.type) {
-		case NUM_NL80211_IFTYPES:
-		case NL80211_IFTYPE_UNSPECIFIED:
-		case NL80211_IFTYPE_MONITOR:
-		case NL80211_IFTYPE_AP_VLAN:
-			continue;
-		case NL80211_IFTYPE_AP:
-		case NL80211_IFTYPE_STATION:
-		case NL80211_IFTYPE_ADHOC:
-		case NL80211_IFTYPE_WDS:
-		case NL80211_IFTYPE_MESH_POINT:
-			break;
-		}
-		if (ieee80211_sdata_running(sdata))
+	switch (sdata->vif.type) {
+	case NUM_NL80211_IFTYPES:
+	case NL80211_IFTYPE_UNSPECIFIED:
+	case NL80211_IFTYPE_MONITOR:
+	case NL80211_IFTYPE_AP_VLAN:
+		return 0;
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_WDS:
+	case NL80211_IFTYPE_MESH_POINT:
+		break;
+	}
+	if (ieee80211_sdata_running(sdata) || !active_only) {
+		if (iterator)
 			iterator(data, sdata->vif.addr,
 				 &sdata->vif);
+		return 1;
 	}
-
-	mutex_unlock(&local->iflist_mtx);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
 
-void ieee80211_iterate_active_interfaces_atomic(
+int ieee80211_iterate_interfaces_helper(
 	struct ieee80211_hw *hw,
+	bool do_atomic,
+	bool active_only,
 	void (*iterator)(void *data, u8 *mac,
 			 struct ieee80211_vif *vif),
 	void *data)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_sub_if_data *sdata;
+	int cnt = 0;
 
-	rcu_read_lock();
+	if (do_atomic) {
+		rcu_read_lock();
 
-	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-		switch (sdata->vif.type) {
-		case NUM_NL80211_IFTYPES:
-		case NL80211_IFTYPE_UNSPECIFIED:
-		case NL80211_IFTYPE_MONITOR:
-		case NL80211_IFTYPE_AP_VLAN:
-			continue;
-		case NL80211_IFTYPE_AP:
-		case NL80211_IFTYPE_STATION:
-		case NL80211_IFTYPE_ADHOC:
-		case NL80211_IFTYPE_WDS:
-		case NL80211_IFTYPE_MESH_POINT:
-			break;
+		list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+			cnt += _iter_loop_helper(sdata, active_only,
+						 iterator, data);
 		}
-		if (ieee80211_sdata_running(sdata))
-			iterator(data, sdata->vif.addr,
-				 &sdata->vif);
+		rcu_read_unlock();
+	} else {
+		mutex_lock(&local->iflist_mtx);
+		list_for_each_entry(sdata, &local->interfaces, list) {
+			cnt += _iter_loop_helper(sdata, active_only,
+						 iterator, data);
+		}
+		mutex_unlock(&local->iflist_mtx);
 	}
+	return cnt;
+}
+EXPORT_SYMBOL_GPL(ieee80211_iterate_interfaces_helper);
 
-	rcu_read_unlock();
+
+void ieee80211_iterate_active_interfaces(
+	struct ieee80211_hw *hw,
+	void (*iterator)(void *data, u8 *mac,
+			 struct ieee80211_vif *vif),
+	void *data)
+{
+	ieee80211_iterate_interfaces_helper(hw, false, false, iterator, data);
+}
+EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
+
+void ieee80211_iterate_active_interfaces_atomic(
+	struct ieee80211_hw *hw,
+	void (*iterator)(void *data, u8 *mac,
+			 struct ieee80211_vif *vif),
+	void *data)
+{
+	ieee80211_iterate_interfaces_helper(hw, true, false, iterator, data);
 }
 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
 
-- 
1.7.2.2

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux