From patchwork Sat Feb 6 13:20:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave X-Patchwork-Id: 77509 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o16DKW1v006964 for ; Sat, 6 Feb 2010 13:20:40 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755701Ab0BFNUj (ORCPT ); Sat, 6 Feb 2010 08:20:39 -0500 Received: from mail-ew0-f228.google.com ([209.85.219.228]:53889 "EHLO mail-ew0-f228.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755668Ab0BFNUi (ORCPT ); Sat, 6 Feb 2010 08:20:38 -0500 Received: by ewy28 with SMTP id 28so944897ewy.28 for ; Sat, 06 Feb 2010 05:20:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:received:received:received:from:to:cc:subject :date:message-id:x-mailer:in-reply-to:references; bh=zBRAvIt1FxmWIjBAmbDhR6xNgSdreOqY4b3LA6QIQ04=; b=A/LH3DQGRF/AwcLcB5hlsnWsXfyZE1YH+Zx/0XVJhLg82g1a7vZwEUVZxos4FaBQ72 fhENpCbbumoAG86RotXqlnubJ+t5ZImaCOhy8+t5A0+z8UuxVmxNPpkYXI+M5t/emNiv xbDjDSsumh5zEfje0IlYm2NEnsiIq5l9DLxiM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=CIbJjf8IYbk7zu5sgqQJwftkEm0mnsCfPdmXn94rs7otpcW5w2QbUNYZ6fr3neSHss 3n672nwffvbFB3P26Yj90S5YFQoRuJ/BsTxys0toPv8MVPmKh0gjq6nmDiI948I2QPl4 T29feiN9XDeyLztJL9E5l8WIXfHYHwNqYUybU= Received: by 10.213.100.231 with SMTP id z39mr1841724ebn.32.1265462436876; Sat, 06 Feb 2010 05:20:36 -0800 (PST) Received: from borken (5e040fbf.bb.sky.com [94.4.15.191]) by mx.google.com with ESMTPS id 13sm1690912ewy.1.2010.02.06.05.20.34 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 06 Feb 2010 05:20:36 -0800 (PST) Received: by borken (sSMTP sendmail emulation); Sat, 06 Feb 2010 13:20:34 +0000 From: David Kilroy To: linux-wireless@vger.kernel.org Cc: holgerschurig@gmail.com, sameo@linux.intel.com, dcbw@redhat.com, David Kilroy Subject: [RFC 1/2] cfg80211: generic trigger scan and callback on completion Date: Sat, 6 Feb 2010 13:20:15 +0000 Message-Id: <1265462416-7547-2-git-send-email-kilroyd@googlemail.com> X-Mailer: git-send-email 1.6.4.4 In-Reply-To: <1265462416-7547-1-git-send-email-kilroyd@googlemail.com> References: <1265462416-7547-1-git-send-email-kilroyd@googlemail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sat, 06 Feb 2010 13:20:40 +0000 (UTC) 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; }