diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-05-10 13:40:49 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-16 17:15:09 -0400 |
commit | 2f561feb386d6adefbad63c59a1fcd298ac6a79c (patch) | |
tree | 9f2979c3539314b58f9a417b26347b7b09dd2722 /net | |
parent | 34a961f7db36f10abd6b153411fe8c810f21f6b3 (diff) |
mac80211: Add RTNL version of ieee80211_iterate_active_interfaces
Since commit e38bad4766a110b61fa6038f10be16ced8c6cc38
mac80211: make ieee80211_iterate_active_interfaces not need rtnl
rt2500usb and rt73usb broke down due to attempting register access
in atomic context (which is not possible for USB hardware).
This patch restores ieee80211_iterate_active_interfaces() to use RTNL lock,
and provides the non-RTNL version under a new name:
ieee80211_iterate_active_interfaces_atomic()
So far only rt2x00 uses ieee80211_iterate_active_interfaces(), and those
drivers require the RTNL version of ieee80211_iterate_active_interfaces().
Since they already call that function directly, this patch will automatically
fix the USB rt2x00 drivers.
v2: Rename ieee80211_iterate_active_interfaces_rtnl
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/util.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 24a465c4df09..131e9e6c8a32 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -389,6 +389,41 @@ void ieee80211_iterate_active_interfaces( struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_sub_if_data *sdata; + rtnl_lock(); + + list_for_each_entry(sdata, &local->interfaces, list) { + switch (sdata->vif.type) { + case IEEE80211_IF_TYPE_INVALID: + case IEEE80211_IF_TYPE_MNTR: + case IEEE80211_IF_TYPE_VLAN: + continue; + case IEEE80211_IF_TYPE_AP: + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: + case IEEE80211_IF_TYPE_WDS: + case IEEE80211_IF_TYPE_MESH_POINT: + break; + } + if (sdata->dev == local->mdev) + continue; + if (netif_running(sdata->dev)) + iterator(data, sdata->dev->dev_addr, + &sdata->vif); + } + + rtnl_unlock(); +} +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) +{ + struct ieee80211_local *local = hw_to_local(hw); + struct ieee80211_sub_if_data *sdata; + rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { @@ -413,4 +448,4 @@ void ieee80211_iterate_active_interfaces( rcu_read_unlock(); } -EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); +EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); |