diff mbox

[RFC,1/2] cfg80211: generic trigger scan and callback on completion

Message ID 1265462416-7547-2-git-send-email-kilroyd@googlemail.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Dave Feb. 6, 2010, 1:20 p.m. UTC
None
diff mbox

Patch

diff --git a/net/wireless/core.h b/net/wireless/core.h
index c326a66..7e0112f 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -63,6 +63,8 @@  struct cfg80211_registered_device {
 	unsigned long suspend_at;
 	struct work_struct scan_done_wk;
 
+	void (*async_scan_cb)(struct net_device *);
+
 #ifdef CONFIG_NL80211_TESTMODE
 	struct genl_info *testmode_info;
 #endif
@@ -372,6 +374,10 @@  int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev, enum nl80211_iftype ntype,
 			  u32 *flags, struct vif_params *params);
 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
+int cfg80211_async_scan(struct wireless_dev *wdev,
+			struct cfg80211_scan_request *request,
+			bool set_cb_on_busy,
+			void (*cb)(struct net_device *));
 
 struct ieee80211_channel *
 rdev_fixed_channel(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 978cac3..e3d0957 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -40,7 +40,10 @@  void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
 	 * Otherwise, wpa_supplicant gets completely confused with
 	 * wext events.
 	 */
-	cfg80211_sme_scan_done(dev);
+	if (rdev->async_scan_cb) {
+		rdev->async_scan_cb(dev);
+		rdev->async_scan_cb = NULL;
+	}
 
 	if (request->aborted)
 		nl80211_send_scan_aborted(rdev, dev);
@@ -655,6 +658,37 @@  void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 }
 EXPORT_SYMBOL(cfg80211_unlink_bss);
 
+/* Do a scan, and schedule a callback to be run on completion. */
+int cfg80211_async_scan(struct wireless_dev *wdev,
+			struct cfg80211_scan_request *request,
+			bool set_cb_on_busy,
+			void (*cb)(struct net_device *))
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	int err;
+
+	ASSERT_RDEV_LOCK(rdev);
+
+	if (rdev->scan_req) {
+		if (set_cb_on_busy)
+			rdev->async_scan_cb = cb;
+		return -EBUSY;
+	}
+
+	rdev->scan_req = request;
+	rdev->async_scan_cb = cb;
+
+	err = rdev->ops->scan(wdev->wiphy, wdev->netdev, request);
+	if (!err) {
+		nl80211_send_scan_start(rdev, wdev->netdev);
+		dev_hold(wdev->netdev);
+	} else {
+		rdev->scan_req = NULL;
+	}
+
+	return err;
+}
+
 #ifdef CONFIG_CFG80211_WEXT
 int cfg80211_wext_siwscan(struct net_device *dev,
 			  struct iw_request_info *info,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 17fde0d..2ef83b7 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -75,17 +75,12 @@  static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
 
 static int cfg80211_conn_scan(struct wireless_dev *wdev)
 {
-	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 	struct cfg80211_scan_request *request;
 	int n_channels, err;
 
 	ASSERT_RTNL();
-	ASSERT_RDEV_LOCK(rdev);
 	ASSERT_WDEV_LOCK(wdev);
 
-	if (rdev->scan_req)
-		return -EBUSY;
-
 	if (wdev->conn->params.channel) {
 		n_channels = 1;
 	} else {
@@ -128,19 +123,14 @@  static int cfg80211_conn_scan(struct wireless_dev *wdev)
 	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
 
 	request->dev = wdev->netdev;
-	request->wiphy = &rdev->wiphy;
-
-	rdev->scan_req = request;
+	request->wiphy = wdev->wiphy;
 
-	err = rdev->ops->scan(wdev->wiphy, wdev->netdev, request);
-	if (!err) {
+	err = cfg80211_async_scan(wdev, request, true, cfg80211_sme_scan_done);
+	if (!err)
 		wdev->conn->state = CFG80211_CONN_SCANNING;
-		nl80211_send_scan_start(rdev, wdev->netdev);
-		dev_hold(wdev->netdev);
-	} else {
-		rdev->scan_req = NULL;
+	else
 		kfree(request);
-	}
+
 	return err;
 }