Changes in mac/cfg80211 to notify userspace
of NL80211_CMD_SCHED_SCAN_STOPPED only when the driver
actually reported back that it was stopped. Also
blocks other attempts until we're really done.
This fixes a scenario where stop sched scan
is issued and immediately afterwards a new sched scan
is requested (e.g. with other parameters).
Current state caused a race where the driver started
stopping the sched scan but didn't finish and got
another sched scan request which it couldn't handle.
Eyal Shapira (2):
mac80211: mark stopped sched scan only after driver does
nl80211: report stopped sched scan only after driver does
net/mac80211/scan.c | 9 ++++++---
net/wireless/scan.c | 17 ++++++++---------
2 files changed, 14 insertions(+), 12 deletions(-)
--
1.7.4.1
Change internal state in mac80211 only after the driver
reports that sched scan was actually stopped.
Signed-off-by: Eyal Shapira <[email protected]>
---
net/mac80211/scan.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 2c5041c..33ca4d8 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -885,11 +885,12 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
}
if (local->sched_scanning) {
- for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
kfree(local->sched_scan_ies.ie[i]);
+ local->sched_scan_ies.ie[i] = NULL;
+ }
drv_sched_scan_stop(local, sdata);
- local->sched_scanning = false;
}
out:
mutex_unlock(&sdata->local->mtx);
@@ -921,8 +922,10 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
return;
}
- for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
kfree(local->sched_scan_ies.ie[i]);
+ local->sched_scan_ies.ie[i] = NULL;
+ }
local->sched_scanning = false;
--
1.7.4.1
Report NL80211_CMD_SCHED_SCAN_STOPPED and change internal
states in cfg80211 only after the driver reports that
sched scan was actually stopped.
Signed-off-by: Eyal Shapira <[email protected]>
---
net/wireless/scan.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 31119e3..d6c87d9 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -133,6 +133,7 @@ EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
bool driver_initiated)
{
+ int err = 0;
struct net_device *dev;
lockdep_assert_held(&rdev->sched_scan_mtx);
@@ -143,17 +144,15 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
dev = rdev->sched_scan_req->dev;
if (!driver_initiated) {
- int err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
- if (err)
- return err;
+ err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
+ } else {
+ nl80211_send_sched_scan(rdev, dev,
+ NL80211_CMD_SCHED_SCAN_STOPPED);
+ kfree(rdev->sched_scan_req);
+ rdev->sched_scan_req = NULL;
}
- nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
-
- kfree(rdev->sched_scan_req);
- rdev->sched_scan_req = NULL;
-
- return 0;
+ return err;
}
static void bss_release(struct kref *ref)
--
1.7.4.1