From patchwork Tue Dec 17 16:15:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= X-Patchwork-Id: 1211502 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=silabs.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=silabs.onmicrosoft.com header.i=@silabs.onmicrosoft.com header.b="exMRO7/R"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47cjvC3Y8kz9sSV for ; Wed, 18 Dec 2019 03:16:39 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728829AbfLQQQf (ORCPT ); Tue, 17 Dec 2019 11:16:35 -0500 Received: from mail-dm6nam12on2072.outbound.protection.outlook.com ([40.107.243.72]:33729 "EHLO NAM12-DM6-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728466AbfLQQQK (ORCPT ); Tue, 17 Dec 2019 11:16:10 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Cw8moinRmfBl4rIvr5wD/f+wKnvXjMtwzfRXftWaJuQRHBHOK2byJnzeMvv7AXcP+9N76S2tjSnV921k3niFYdJ1w9x+iQNo0HnkgwExZs0H70LFMRcGmxejO/PjpZtCoDZ/iH41olPxHULVQGi3brW5VYoj0pRlgPwhLRwj/sWikRHLcsSwnno2C1RoV2ca8v3/r5nWQDv82uiIgjyA3Ow7ydBPLbFjwws5oYOrawGZPEC0k8TuacJhkAGG5m62dKwbCALKMvYLL3b71zi3+9pjrLtNoIBjc5NgsM0JxgMwluHqljq3AlvugQzEAPiNryQYyLVv0MPkDjTlEunCLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=abwaC/EprcvfAMIMK5YnQofxaQusI+LMGZvh/14CrDk=; b=HUg3/B/Jez9gNW+QWRRWj/XT9/GYLWDv1QolepVr3PvFbx3MzYAs/iJfe0GMATR3IIQdyzAw4Zoh0HPX0O0J0qoX9XGS5Gtx/rpAp4TgX/sWYt0YG6xU5bA1r/RLNM3QaLNYcyXVTt0Ltmp6XhKNA0N9xN+3Bqg5L2hsYnCwvdhAKCXsfY2EBT14TzMrqvMSg35fhjL9S0sxdgoIDi2/KKXUlFww7Shu5lxT+3DjUbm1P0byaHFvqGIlaBgD84Ymc536O/UxK6Ftqm0/LGueMt1rYn6oYPal+OFuym99VfbUoW0mo8whgSVn7FhaIFwMd8CTt+f1RLHql0q+Ocxh0g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=silabs.com; dmarc=pass action=none header.from=silabs.com; dkim=pass header.d=silabs.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=silabs.onmicrosoft.com; s=selector2-silabs-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=abwaC/EprcvfAMIMK5YnQofxaQusI+LMGZvh/14CrDk=; b=exMRO7/R725PSXgikY3Ua/9KMAo78ZiqYomyTM6m219NsrGN5uypbRZXUxsTS5VHGJ3/1rgph2EiktmiY0QGBsbPSWOfnxCItLhiAQDg4czaOYppizF1WlkKmiFqwhnuj0M8RewfR+0sNU9rOwfK1qRK6zT0WiFfVAm+vJvOrMU= Received: from MN2PR11MB4063.namprd11.prod.outlook.com (10.255.180.22) by MN2PR11MB4477.namprd11.prod.outlook.com (52.135.36.93) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2538.17; Tue, 17 Dec 2019 16:16:01 +0000 Received: from MN2PR11MB4063.namprd11.prod.outlook.com ([fe80::f46c:e5b4:2a85:f0bf]) by MN2PR11MB4063.namprd11.prod.outlook.com ([fe80::f46c:e5b4:2a85:f0bf%4]) with mapi id 15.20.2538.019; Tue, 17 Dec 2019 16:16:00 +0000 From: =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= To: "devel@driverdev.osuosl.org" , "linux-wireless@vger.kernel.org" CC: "netdev@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Greg Kroah-Hartman , Kalle Valo , "David S . Miller" , =?utf-8?b?SsOpcsO0bWUgUG91?= =?utf-8?q?iller?= Subject: [PATCH v2 50/55] staging: wfx: rewrite wfx_hw_scan() Thread-Topic: [PATCH v2 50/55] staging: wfx: rewrite wfx_hw_scan() Thread-Index: AQHVtPU2YDzg5LD5lUmnp93AvrDBXg== Date: Tue, 17 Dec 2019 16:15:35 +0000 Message-ID: <20191217161318.31402-51-Jerome.Pouiller@silabs.com> References: <20191217161318.31402-1-Jerome.Pouiller@silabs.com> In-Reply-To: <20191217161318.31402-1-Jerome.Pouiller@silabs.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: PR0P264CA0174.FRAP264.PROD.OUTLOOK.COM (2603:10a6:100:1c::18) To MN2PR11MB4063.namprd11.prod.outlook.com (2603:10b6:208:13f::22) authentication-results: spf=none (sender IP is ) smtp.mailfrom=Jerome.Pouiller@silabs.com; x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.24.0 x-originating-ip: [37.71.187.125] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: c928e248-e79d-41f5-7be7-08d7830c5959 x-ms-traffictypediagnostic: MN2PR11MB4477: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:5236; x-forefront-prvs: 02543CD7CD x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(346002)(396003)(136003)(366004)(39860400002)(199004)(189003)(1076003)(66574012)(186003)(107886003)(8676002)(30864003)(6506007)(86362001)(478600001)(85182001)(5660300002)(81156014)(26005)(4326008)(6486002)(8936002)(316002)(110136005)(54906003)(64756008)(66446008)(66946007)(2616005)(66556008)(66476007)(85202003)(36756003)(6512007)(2906002)(52116002)(6666004)(71200400001)(81166006); DIR:OUT; SFP:1101; SCL:1; SRVR:MN2PR11MB4477; H:MN2PR11MB4063.namprd11.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: silabs.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 0/Uj4GuW5hYQuFyjPq4L3AYJorDKvr1gOZ19LNxjQDMdlfjlUOj+6EuNzkhfhG/YL77KZTqNEVKpQ1C8VTJU4dKpF3/6ZsKYENEHk7eEKTMDZzswIxKhaRDOF+qtQzJiuV0vCkx8DXR1FwrSW0ul2FkYHd8o/ZrDpVcO1VRSJLTkFGGFizAD73oCvtX2R99pFEUOa9ARYJX3DgZlmyOOUWEBB4LnZ1k6ea4qqcPCq+4JSl7Cavqtn6VLiqOXEUKr81qYep21jwupdfNIqlzeZ7ny46ELqVu0lhviUGWAWv8HibISDB/gemeSkAK8MYH77JFsAwP06PpJdFQT1QKP1hRE8ZXgfEDPw7ReZRDOG8huVabI3X8KKDgkL5fX5JVeUiNhCN+PAAiM6kkC2h1ISVR9ddMnJBSYu6ZhxoRK++rSQeojpMVefhG9x2HlT9t/ Content-ID: MIME-Version: 1.0 X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: c928e248-e79d-41f5-7be7-08d7830c5959 X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Dec 2019 16:15:35.9796 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 54dbd822-5231-4b20-944d-6f4abcd541fb X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: UNSC6784cJbDyNIWK8YEfHtkr8ydgB2VXDGG9QCBG64lclOgs2pnZCGqWty5AII2YteYU/qQ6TrAX04Fuahs/g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR11MB4477 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jérôme Pouiller Scan requests from mac80211 must be splitted in a few hardware requests (it is necessary to split channels with active scan and channels with passive scan). Current code schedules a work_struct for each hardware request and one delayed_work to handle scan timeout. It is far simpler to run send all the hardware requests synchronously and replace delayed_work with a simple wait_for_completion_timeout(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 2 +- drivers/staging/wfx/scan.c | 225 ++++++++++------------------------- drivers/staging/wfx/scan.h | 23 +--- drivers/staging/wfx/sta.c | 39 ++---- drivers/staging/wfx/wfx.h | 4 +- 5 files changed, 81 insertions(+), 212 deletions(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 8a3ccdc60b7d..408967a4c457 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -206,7 +206,7 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev, const struct hif_ind_scan_cmpl *body = buf; WARN_ON(!wvif); - wfx_scan_complete_cb(wvif, body); + wfx_scan_complete(wvif, body); return 0; } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index c82c04ff5d06..b73e61e8da46 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -22,33 +22,6 @@ static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw, ieee80211_scan_completed(hw, &info); } -static void wfx_scan_restart_delayed(struct wfx_vif *wvif) -{ - if (wvif->delayed_unjoin) { - wvif->delayed_unjoin = false; - if (!schedule_work(&wvif->unjoin_work)) - wfx_tx_unlock(wvif->wdev); - } else if (wvif->delayed_link_loss) { - wvif->delayed_link_loss = 0; - wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - } -} - -static int wfx_scan_start(struct wfx_vif *wvif, - int chan_start_idx, int chan_num) -{ - int tmo; - - if (wvif->state == WFX_STATE_PRE_STA) - return -EBUSY; - - atomic_set(&wvif->scan.in_progress, 1); - - tmo = hif_scan(wvif, wvif->scan.req, chan_start_idx, chan_num); - schedule_delayed_work(&wvif->scan.timeout, tmo); - return 0; -} - static int update_probe_tmpl(struct wfx_vif *wvif, struct cfg80211_scan_request *req) { @@ -65,153 +38,81 @@ static int update_probe_tmpl(struct wfx_vif *wvif, return 0; } -int wfx_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_scan_request *hw_req) +static int send_scan_req(struct wfx_vif *wvif, + struct cfg80211_scan_request *req, int start_idx) +{ + int i, ret, timeout; + struct ieee80211_channel *ch_start, *ch_cur; + + for (i = start_idx; i < req->n_channels; i++) { + ch_start = req->channels[start_idx]; + ch_cur = req->channels[i]; + WARN(ch_cur->band != NL80211_BAND_2GHZ, "band not supported"); + if (ch_cur->max_power != ch_start->max_power) + break; + if ((ch_cur->flags ^ ch_start->flags) & IEEE80211_CHAN_NO_IR) + break; + } + wfx_tx_lock_flush(wvif->wdev); + reinit_completion(&wvif->scan_complete); + ret = hif_scan(wvif, req, start_idx, i - start_idx); + if (ret < 0) + return ret; + timeout = ret; + ret = wait_for_completion_timeout(&wvif->scan_complete, timeout); + if (req->channels[start_idx]->max_power != wvif->wdev->output_power) + hif_set_output_power(wvif, wvif->wdev->output_power * 10); + wfx_tx_unlock(wvif->wdev); + if (!ret) { + dev_notice(wvif->wdev->dev, "scan timeout\n"); + hif_stop_scan(wvif); + return -ETIMEDOUT; + } + return i - start_idx; +} + +int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) { struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; - struct cfg80211_scan_request *req = &hw_req->req; - int i, ret; + int chan_cur, ret; - if (!wvif) - return -EINVAL; + WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); - if (wvif->state == WFX_STATE_AP) + if (vif->type == NL80211_IFTYPE_AP) return -EOPNOTSUPP; - if (req->n_ssids == 1 && !req->ssids[0].ssid_len) - req->n_ssids = 0; - - if (req->n_ssids > HIF_API_MAX_NB_SSIDS) - return -EINVAL; + if (wvif->state == WFX_STATE_PRE_STA) + return -EBUSY; + mutex_lock(&wvif->scan_lock); mutex_lock(&wdev->conf_mutex); - - ret = update_probe_tmpl(wvif, req); - if (ret) - goto failed; - - ret = wfx_fwd_probe_req(wvif, true); - if (ret) - goto failed; - - wfx_tx_lock_flush(wdev); - - WARN(wvif->scan.req, "unexpected concurrent scan"); - wvif->scan.req = req; - wvif->scan.n_ssids = 0; - wvif->scan.status = 0; - wvif->scan.begin = &req->channels[0]; - wvif->scan.curr = wvif->scan.begin; - wvif->scan.end = &req->channels[req->n_channels]; - wvif->scan.output_power = wdev->output_power; - - for (i = 0; i < req->n_ssids; ++i) { - struct hif_ssid_def *dst = &wvif->scan.ssids[wvif->scan.n_ssids]; - - memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid)); - dst->ssid_length = req->ssids[i].ssid_len; - ++wvif->scan.n_ssids; - } - schedule_work(&wvif->scan.work); - -failed: + update_probe_tmpl(wvif, &hw_req->req); + wfx_fwd_probe_req(wvif, true); + chan_cur = 0; + do { + ret = send_scan_req(wvif, &hw_req->req, chan_cur); + if (ret > 0) + chan_cur += ret; + } while (ret > 0 && chan_cur < hw_req->req.n_channels); + __ieee80211_scan_completed_compat(hw, ret < 0); mutex_unlock(&wdev->conf_mutex); - return ret; -} - -void wfx_scan_work(struct work_struct *work) -{ - struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan.work); - struct ieee80211_channel **it; - struct ieee80211_channel *first; - int i; - - down(&wvif->scan.lock); - mutex_lock(&wvif->wdev->conf_mutex); - - - if (!wvif->scan.req || wvif->scan.curr == wvif->scan.end) { - if (wvif->scan.output_power != wvif->wdev->output_power) - hif_set_output_power(wvif, - wvif->wdev->output_power * 10); - - if (wvif->scan.status < 0) - dev_warn(wvif->wdev->dev, "scan failed\n"); - else if (wvif->scan.req) - dev_dbg(wvif->wdev->dev, "scan completed\n"); - else - dev_dbg(wvif->wdev->dev, "scan canceled\n"); - - wvif->scan.req = NULL; - wfx_scan_restart_delayed(wvif); - wfx_tx_unlock(wvif->wdev); - mutex_unlock(&wvif->wdev->conf_mutex); - __ieee80211_scan_completed_compat(wvif->wdev->hw, - wvif->scan.status ? 1 : 0); - up(&wvif->scan.lock); - return; - } - first = *wvif->scan.curr; - - for (it = wvif->scan.curr + 1, i = 1; - it != wvif->scan.end && i < HIF_API_MAX_NB_CHANNELS; - ++it, ++i) { - if ((*it)->band != first->band) - break; - if (((*it)->flags ^ first->flags) & - IEEE80211_CHAN_NO_IR) - break; - if (!(first->flags & IEEE80211_CHAN_NO_IR) && - (*it)->max_power != first->max_power) - break; - } - if (!(first->flags & IEEE80211_CHAN_NO_IR) && - wvif->scan.output_power != first->max_power) { - wvif->scan.output_power = first->max_power; - hif_set_output_power(wvif, wvif->scan.output_power * 10); - } - wvif->scan.status = wfx_scan_start(wvif, - wvif->scan.curr - wvif->scan.begin, - it - wvif->scan.curr); - if (wvif->scan.status) - goto fail; - wvif->scan.curr = it; - mutex_unlock(&wvif->wdev->conf_mutex); - return; - -fail: - wvif->scan.curr = wvif->scan.end; - mutex_unlock(&wvif->wdev->conf_mutex); - up(&wvif->scan.lock); - schedule_work(&wvif->scan.work); -} - -void wfx_scan_complete_cb(struct wfx_vif *wvif, - const struct hif_ind_scan_cmpl *arg) -{ - if (cancel_delayed_work_sync(&wvif->scan.timeout) > 0) { - wvif->scan.status = 1; - schedule_work(&wvif->scan.timeout.work); + mutex_unlock(&wvif->scan_lock); + if (wvif->delayed_unjoin) { + wvif->delayed_unjoin = false; + wfx_tx_lock(wdev); + if (!schedule_work(&wvif->unjoin_work)) + wfx_tx_unlock(wdev); + } else if (wvif->delayed_link_loss) { + wvif->delayed_link_loss = false; + wfx_cqm_bssloss_sm(wvif, 1, 0, 0); } + return 0; } -void wfx_scan_timeout(struct work_struct *work) +void wfx_scan_complete(struct wfx_vif *wvif, + const struct hif_ind_scan_cmpl *arg) { - struct wfx_vif *wvif = container_of(work, struct wfx_vif, - scan.timeout.work); - - if (atomic_xchg(&wvif->scan.in_progress, 0)) { - if (wvif->scan.status > 0) { - wvif->scan.status = 0; - } else if (!wvif->scan.status) { - dev_warn(wvif->wdev->dev, "timeout waiting for scan complete notification\n"); - wvif->scan.status = -ETIMEDOUT; - wvif->scan.curr = wvif->scan.end; - hif_stop_scan(wvif); - } - up(&wvif->scan.lock); - wfx_scan_work(&wvif->scan.work); - } + complete(&wvif->scan_complete); } diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index e71e5f0f522e..03bc6c7e562d 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -8,8 +8,6 @@ #ifndef WFX_SCAN_H #define WFX_SCAN_H -#include -#include #include #include "hif_api_cmd.h" @@ -17,26 +15,9 @@ struct wfx_dev; struct wfx_vif; -struct wfx_scan { - struct semaphore lock; - struct work_struct work; - struct delayed_work timeout; - struct cfg80211_scan_request *req; - struct ieee80211_channel **begin; - struct ieee80211_channel **curr; - struct ieee80211_channel **end; - struct hif_ssid_def ssids[HIF_API_MAX_NB_SSIDS]; - int output_power; - int n_ssids; - int status; - atomic_t in_progress; -}; - int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req); -void wfx_scan_work(struct work_struct *work); -void wfx_scan_timeout(struct work_struct *work); -void wfx_scan_complete_cb(struct wfx_vif *wvif, - const struct hif_ind_scan_cmpl *arg); +void wfx_scan_complete(struct wfx_vif *wvif, + const struct hif_ind_scan_cmpl *ind); #endif /* WFX_SCAN_H */ diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index ba3e81fd477b..16f5db873275 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -277,13 +277,13 @@ void wfx_configure_filter(struct ieee80211_hw *hw, *total_flags &= FIF_OTHER_BSS | FIF_FCSFAIL | FIF_PROBE_REQ; while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { - down(&wvif->scan.lock); + mutex_lock(&wvif->scan_lock); wvif->filter_bssid = (*total_flags & (FIF_OTHER_BSS | FIF_PROBE_REQ)) ? 0 : 1; wvif->disable_beacon_filter = !(*total_flags & FIF_PROBE_REQ); wfx_fwd_probe_req(wvif, true); wfx_update_filtering(wvif); - up(&wvif->scan.lock); + mutex_unlock(&wvif->scan_lock); } } @@ -433,9 +433,9 @@ static void wfx_event_handler_work(struct work_struct *work) switch (event->evt.event_id) { case HIF_EVENT_IND_BSSLOST: cancel_work_sync(&wvif->unjoin_work); - if (!down_trylock(&wvif->scan.lock)) { + if (mutex_trylock(&wvif->scan_lock)) { wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - up(&wvif->scan.lock); + mutex_unlock(&wvif->scan_lock); } else { /* Scan is in progress. Delay reporting. * Scan complete will trigger bss_loss_work @@ -501,7 +501,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) { mutex_lock(&wvif->wdev->conf_mutex); - if (atomic_read(&wvif->scan.in_progress)) { + if (!mutex_trylock(&wvif->scan_lock)) { if (wvif->delayed_unjoin) dev_dbg(wvif->wdev->dev, "delayed unjoin is already scheduled\n"); @@ -509,6 +509,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) wvif->delayed_unjoin = true; goto done; } + mutex_unlock(&wvif->scan_lock); wvif->delayed_link_loss = false; @@ -613,14 +614,6 @@ static void wfx_do_join(struct wfx_vif *wvif) mutex_lock(&wvif->wdev->conf_mutex); - /* Under the conf lock: check scan status and - * bail out if it is in progress. - */ - if (atomic_read(&wvif->scan.in_progress)) { - wfx_tx_unlock(wvif->wdev); - goto done_put; - } - /* Sanity check basic rates */ if (!join.basic_rate_set) join.basic_rate_set = 7; @@ -684,7 +677,6 @@ static void wfx_do_join(struct wfx_vif *wvif) } wfx_update_filtering(wvif); -done_put: mutex_unlock(&wvif->wdev->conf_mutex); if (bss) cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); @@ -1346,7 +1338,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) return 0; } - down(&wvif->scan.lock); + mutex_lock(&wvif->scan_lock); mutex_lock(&wdev->conf_mutex); if (changed & IEEE80211_CONF_CHANGE_POWER) { wdev->output_power = conf->power_level; @@ -1361,7 +1353,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) } mutex_unlock(&wdev->conf_mutex); - up(&wvif->scan.lock); + mutex_unlock(&wvif->scan_lock); return ret; } @@ -1419,10 +1411,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wvif->wep_default_key_id = -1; INIT_WORK(&wvif->wep_key_work, wfx_wep_key_work); - sema_init(&wvif->scan.lock, 1); - INIT_WORK(&wvif->scan.work, wfx_scan_work); - INIT_DELAYED_WORK(&wvif->scan.timeout, wfx_scan_timeout); - spin_lock_init(&wvif->event_queue_lock); INIT_LIST_HEAD(&wvif->event_queue); INIT_WORK(&wvif->event_handler_work, wfx_event_handler_work); @@ -1435,8 +1423,11 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work); INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work); INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work); - INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); + + mutex_init(&wvif->scan_lock); + init_completion(&wvif->scan_complete); + mutex_unlock(&wdev->conf_mutex); hif_set_macaddr(wvif, vif->addr); @@ -1462,10 +1453,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw, struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; int i; - // If scan is in progress, stop it - while (down_trylock(&wvif->scan.lock)) - schedule(); - up(&wvif->scan.lock); wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300)); mutex_lock(&wdev->conf_mutex); @@ -1505,8 +1492,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw, /* FIXME: In add to reset MAC address, try to reset interface */ hif_set_macaddr(wvif, NULL); - cancel_delayed_work_sync(&wvif->scan.timeout); - wfx_cqm_bssloss_sm(wvif, 0, 0, 0); cancel_work_sync(&wvif->unjoin_work); cancel_delayed_work_sync(&wvif->link_id_gc_work); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 35f5ddc2eeb3..3356d0cbf7af 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -125,7 +125,9 @@ struct wfx_vif { bool delayed_unjoin; struct work_struct unjoin_work; - struct wfx_scan scan; + /* avoid some operations in parallel with scan */ + struct mutex scan_lock; + struct completion scan_complete; struct completion set_pm_mode_complete;