]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/wireless/core.c
Merge tag 'for-4.12/dm-post-merge-changes' of git://git.kernel.org/pub/scm/linux...
[karo-tx-linux.git] / net / wireless / core.c
index b0d6761f0cdd77ba67bf3caff2df6fcab4733e3c..83ea164f16b3e018546260d8e809ae6b244d85e3 100644 (file)
@@ -305,30 +305,14 @@ static void cfg80211_event_work(struct work_struct *work)
 
 void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
 {
-       struct cfg80211_iface_destroy *item;
+       struct wireless_dev *wdev, *tmp;
 
        ASSERT_RTNL();
 
-       spin_lock_irq(&rdev->destroy_list_lock);
-       while ((item = list_first_entry_or_null(&rdev->destroy_list,
-                                               struct cfg80211_iface_destroy,
-                                               list))) {
-               struct wireless_dev *wdev, *tmp;
-               u32 nlportid = item->nlportid;
-
-               list_del(&item->list);
-               kfree(item);
-               spin_unlock_irq(&rdev->destroy_list_lock);
-
-               list_for_each_entry_safe(wdev, tmp,
-                                        &rdev->wiphy.wdev_list, list) {
-                       if (nlportid == wdev->owner_nlportid)
-                               rdev_del_virtual_intf(rdev, wdev);
-               }
-
-               spin_lock_irq(&rdev->destroy_list_lock);
+       list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
+               if (wdev->nl_owner_dead)
+                       rdev_del_virtual_intf(rdev, wdev);
        }
-       spin_unlock_irq(&rdev->destroy_list_lock);
 }
 
 static void cfg80211_destroy_iface_wk(struct work_struct *work)
@@ -346,14 +330,16 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work)
 static void cfg80211_sched_scan_stop_wk(struct work_struct *work)
 {
        struct cfg80211_registered_device *rdev;
+       struct cfg80211_sched_scan_request *req, *tmp;
 
        rdev = container_of(work, struct cfg80211_registered_device,
                           sched_scan_stop_wk);
 
        rtnl_lock();
-
-       __cfg80211_stop_sched_scan(rdev, false);
-
+       list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
+               if (req->nl_owner_dead)
+                       cfg80211_stop_sched_scan_req(rdev, req, false);
+       }
        rtnl_unlock();
 }
 
@@ -468,8 +454,8 @@ use_default_name:
        spin_lock_init(&rdev->beacon_registrations_lock);
        spin_lock_init(&rdev->bss_lock);
        INIT_LIST_HEAD(&rdev->bss_list);
+       INIT_LIST_HEAD(&rdev->sched_scan_req_list);
        INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
-       INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
        INIT_LIST_HEAD(&rdev->mlme_unreg);
        spin_lock_init(&rdev->mlme_unreg_lock);
        INIT_WORK(&rdev->mlme_unreg_wk, cfg80211_mlme_unreg_wk);
@@ -484,10 +470,9 @@ use_default_name:
        rdev->wiphy.dev.platform_data = rdev;
        device_enable_async_suspend(&rdev->wiphy.dev);
 
-       INIT_LIST_HEAD(&rdev->destroy_list);
-       spin_lock_init(&rdev->destroy_list_lock);
        INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
        INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+       INIT_WORK(&rdev->sched_scan_res_wk, cfg80211_sched_scan_results_wk);
        INIT_WORK(&rdev->propagate_radar_detect_wk,
                  cfg80211_propagate_radar_detect_wk);
        INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
@@ -1046,7 +1031,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
                      struct wireless_dev *wdev)
 {
        struct net_device *dev = wdev->netdev;
-       struct cfg80211_sched_scan_request *sched_scan_req;
+       struct cfg80211_sched_scan_request *pos, *tmp;
 
        ASSERT_RTNL();
        ASSERT_WDEV_LOCK(wdev);
@@ -1057,9 +1042,11 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_STATION:
-               sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
-               if (sched_scan_req && dev == sched_scan_req->dev)
-                       __cfg80211_stop_sched_scan(rdev, false);
+               list_for_each_entry_safe(pos, tmp, &rdev->sched_scan_req_list,
+                                        list) {
+                       if (dev == pos->dev)
+                               cfg80211_stop_sched_scan_req(rdev, pos, false);
+               }
 
 #ifdef CONFIG_CFG80211_WEXT
                kfree(wdev->wext.ie);
@@ -1134,7 +1121,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev;
-       struct cfg80211_sched_scan_request *sched_scan_req;
+       struct cfg80211_sched_scan_request *pos, *tmp;
 
        if (!wdev)
                return NOTIFY_DONE;
@@ -1211,10 +1198,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                        ___cfg80211_scan_done(rdev, false);
                }
 
-               sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
-               if (WARN_ON(sched_scan_req &&
-                           sched_scan_req->dev == wdev->netdev)) {
-                       __cfg80211_stop_sched_scan(rdev, false);
+               list_for_each_entry_safe(pos, tmp,
+                                        &rdev->sched_scan_req_list, list) {
+                       if (WARN_ON(pos && pos->dev == wdev->netdev))
+                               cfg80211_stop_sched_scan_req(rdev, pos, false);
                }
 
                rdev->opencount--;