struct ieee80211_vif *vif),
                                                void *data);
 
+/**
+ * ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces
+ *
+ * This function iterates over the interfaces associated with a given
+ * hardware that are currently active and calls the callback for them.
+ * This version can only be used while holding the RTNL.
+ *
+ * @hw: the hardware struct of which the interfaces should be iterated over
+ * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
+ * @iterator: the iterator function to call, cannot sleep
+ * @data: first argument of the iterator function
+ */
+void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw,
+                                             u32 iter_flags,
+                                             void (*iterator)(void *data,
+                                               u8 *mac,
+                                               struct ieee80211_vif *vif),
+                                             void *data);
+
 /**
  * ieee80211_queue_work - add work onto the mac80211 workqueue
  *
 
                                        IEEE80211_QUEUE_STOP_REASON_FLUSH);
 }
 
-void ieee80211_iterate_active_interfaces(
-       struct ieee80211_hw *hw, u32 iter_flags,
-       void (*iterator)(void *data, u8 *mac,
-                        struct ieee80211_vif *vif),
-       void *data)
+static void __iterate_active_interfaces(struct ieee80211_local *local,
+                                       u32 iter_flags,
+                                       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) {
+       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                switch (sdata->vif.type) {
                case NL80211_IFTYPE_MONITOR:
                        if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
                                 &sdata->vif);
        }
 
-       sdata = rcu_dereference_protected(local->monitor_sdata,
-                                         lockdep_is_held(&local->iflist_mtx));
+       sdata = rcu_dereference_check(local->monitor_sdata,
+                                     lockdep_is_held(&local->iflist_mtx) ||
+                                     lockdep_rtnl_is_held());
        if (sdata &&
            (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
             sdata->flags & IEEE80211_SDATA_IN_DRIVER))
                iterator(data, sdata->vif.addr, &sdata->vif);
+}
 
+void ieee80211_iterate_active_interfaces(
+       struct ieee80211_hw *hw, u32 iter_flags,
+       void (*iterator)(void *data, u8 *mac,
+                        struct ieee80211_vif *vif),
+       void *data)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+
+       mutex_lock(&local->iflist_mtx);
+       __iterate_active_interfaces(local, iter_flags, iterator, data);
        mutex_unlock(&local->iflist_mtx);
 }
 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
        void *data)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_sub_if_data *sdata;
 
        rcu_read_lock();
+       __iterate_active_interfaces(local, iter_flags, iterator, data);
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
 
-       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-               switch (sdata->vif.type) {
-               case NL80211_IFTYPE_MONITOR:
-                       if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
-                               continue;
-                       break;
-               case NL80211_IFTYPE_AP_VLAN:
-                       continue;
-               default:
-                       break;
-               }
-               if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
-                   !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
-                       continue;
-               if (ieee80211_sdata_running(sdata))
-                       iterator(data, sdata->vif.addr,
-                                &sdata->vif);
-       }
+void ieee80211_iterate_active_interfaces_rtnl(
+       struct ieee80211_hw *hw, u32 iter_flags,
+       void (*iterator)(void *data, u8 *mac,
+                        struct ieee80211_vif *vif),
+       void *data)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
 
-       sdata = rcu_dereference(local->monitor_sdata);
-       if (sdata &&
-           (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
-            sdata->flags & IEEE80211_SDATA_IN_DRIVER))
-               iterator(data, sdata->vif.addr, &sdata->vif);
+       ASSERT_RTNL();
 
-       rcu_read_unlock();
+       __iterate_active_interfaces(local, iter_flags, iterator, data);
 }
-EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
+EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl);
 
 /*
  * Nothing should have been stuffed into the workqueue during