if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
                if (WARN_ON(!rdev->scan_req->notified))
                        rdev->scan_req->aborted = true;
-               ___cfg80211_scan_done(rdev);
+               ___cfg80211_scan_done(rdev, false);
        }
 }
 
                if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
                        if (WARN_ON(!rdev->scan_req->notified))
                                rdev->scan_req->aborted = true;
-                       ___cfg80211_scan_done(rdev);
+                       ___cfg80211_scan_done(rdev, false);
                }
 
                if (WARN_ON(rdev->sched_scan_req &&
 
        struct rb_root bss_tree;
        u32 bss_generation;
        struct cfg80211_scan_request *scan_req; /* protected by RTNL */
+       struct sk_buff *scan_msg;
        struct cfg80211_sched_scan_request *sched_scan_req;
        unsigned long suspend_at;
        struct work_struct scan_done_wk;
                                   struct key_params *params, int key_idx,
                                   bool pairwise, const u8 *mac_addr);
 void __cfg80211_scan_done(struct work_struct *wk);
-void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
+                          bool send_message);
 void __cfg80211_sched_scan_results(struct work_struct *wk);
 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
                               bool driver_initiated);
 
        if (!rdev->ops->scan)
                return -EOPNOTSUPP;
 
-       if (rdev->scan_req) {
+       if (rdev->scan_req || rdev->scan_msg) {
                err = -EBUSY;
                goto unlock;
        }
                                NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
-void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
-                           struct wireless_dev *wdev)
+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
+                                      struct wireless_dev *wdev, bool aborted)
 {
        struct sk_buff *msg;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
-               return;
+               return NULL;
 
        if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
-                                 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
+                                 aborted ? NL80211_CMD_SCAN_ABORTED :
+                                           NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
                nlmsg_free(msg);
-               return;
+               return NULL;
        }
 
-       genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
-                               NL80211_MCGRP_SCAN, GFP_KERNEL);
+       return msg;
 }
 
-void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
-                              struct wireless_dev *wdev)
+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
+                             struct sk_buff *msg)
 {
-       struct sk_buff *msg;
-
-       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
 
-       if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
-                                 NL80211_CMD_SCAN_ABORTED) < 0) {
-               nlmsg_free(msg);
-               return;
-       }
-
        genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
                                NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
 void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
                             struct wireless_dev *wdev);
-void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
-                           struct wireless_dev *wdev);
-void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
-                              struct wireless_dev *wdev);
+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
+                                      struct wireless_dev *wdev, bool aborted);
+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
+                             struct sk_buff *msg);
 void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
                             struct net_device *netdev, u32 cmd);
 void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 
                dev->bss_generation++;
 }
 
-void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
+                          bool send_message)
 {
        struct cfg80211_scan_request *request;
        struct wireless_dev *wdev;
+       struct sk_buff *msg;
 #ifdef CONFIG_CFG80211_WEXT
        union iwreq_data wrqu;
 #endif
 
        ASSERT_RTNL();
 
-       request = rdev->scan_req;
+       if (rdev->scan_msg) {
+               nl80211_send_scan_result(rdev, rdev->scan_msg);
+               rdev->scan_msg = NULL;
+               return;
+       }
 
+       request = rdev->scan_req;
        if (!request)
                return;
 
        if (wdev->netdev)
                cfg80211_sme_scan_done(wdev->netdev);
 
-       if (request->aborted) {
-               nl80211_send_scan_aborted(rdev, wdev);
-       } else {
-               if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
-                       /* flush entries from previous scans */
-                       spin_lock_bh(&rdev->bss_lock);
-                       __cfg80211_bss_expire(rdev, request->scan_start);
-                       spin_unlock_bh(&rdev->bss_lock);
-               }
-               nl80211_send_scan_done(rdev, wdev);
+       if (!request->aborted &&
+           request->flags & NL80211_SCAN_FLAG_FLUSH) {
+               /* flush entries from previous scans */
+               spin_lock_bh(&rdev->bss_lock);
+               __cfg80211_bss_expire(rdev, request->scan_start);
+               spin_unlock_bh(&rdev->bss_lock);
        }
 
+       msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
+
 #ifdef CONFIG_CFG80211_WEXT
        if (wdev->netdev && !request->aborted) {
                memset(&wrqu, 0, sizeof(wrqu));
 
        rdev->scan_req = NULL;
        kfree(request);
+
+       if (!send_message)
+               rdev->scan_msg = msg;
+       else
+               nl80211_send_scan_result(rdev, msg);
 }
 
 void __cfg80211_scan_done(struct work_struct *wk)
                            scan_done_wk);
 
        rtnl_lock();
-       ___cfg80211_scan_done(rdev);
+       ___cfg80211_scan_done(rdev, true);
        rtnl_unlock();
 }
 
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
-       if (rdev->scan_req) {
+       if (rdev->scan_req || rdev->scan_msg) {
                err = -EBUSY;
                goto out;
        }
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
-       if (rdev->scan_req)
+       if (rdev->scan_req || rdev->scan_msg)
                return -EAGAIN;
 
        res = ieee80211_scan_results(rdev, info, extra, data->length);
 
        ASSERT_RDEV_LOCK(rdev);
        ASSERT_WDEV_LOCK(wdev);
 
-       if (rdev->scan_req)
+       if (rdev->scan_req || rdev->scan_msg)
                return -EBUSY;
 
        if (wdev->conn->params.channel)