aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h3
-rw-r--r--net/mac80211/cfg.c5
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/scan.c33
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/scan.c21
8 files changed, 43 insertions, 30 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a46adb7a91b7..e1f1b41f7b13 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1515,8 +1515,7 @@ struct cfg80211_ops {
1515 int (*sched_scan_start)(struct wiphy *wiphy, 1515 int (*sched_scan_start)(struct wiphy *wiphy,
1516 struct net_device *dev, 1516 struct net_device *dev,
1517 struct cfg80211_sched_scan_request *request); 1517 struct cfg80211_sched_scan_request *request);
1518 int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev, 1518 int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev);
1519 bool driver_initiated);
1520}; 1519};
1521 1520
1522/* 1521/*
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 303f33fcb844..2d1c1a5f3c51 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1372,15 +1372,14 @@ ieee80211_sched_scan_start(struct wiphy *wiphy,
1372} 1372}
1373 1373
1374static int 1374static int
1375ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, 1375ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
1376 bool driver_initiated)
1377{ 1376{
1378 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1377 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1379 1378
1380 if (!sdata->local->ops->sched_scan_stop) 1379 if (!sdata->local->ops->sched_scan_stop)
1381 return -EOPNOTSUPP; 1380 return -EOPNOTSUPP;
1382 1381
1383 return ieee80211_request_sched_scan_stop(sdata, driver_initiated); 1382 return ieee80211_request_sched_scan_stop(sdata);
1384} 1383}
1385 1384
1386static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, 1385static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6f55a789c099..82f90ff8bb18 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -849,6 +849,7 @@ struct ieee80211_local {
849 849
850 bool sched_scanning; 850 bool sched_scanning;
851 struct ieee80211_sched_scan_ies sched_scan_ies; 851 struct ieee80211_sched_scan_ies sched_scan_ies;
852 struct work_struct sched_scan_stopped_work;
852 853
853 unsigned long leave_oper_channel_time; 854 unsigned long leave_oper_channel_time;
854 enum mac80211_scan_state next_scan_state; 855 enum mac80211_scan_state next_scan_state;
@@ -1160,8 +1161,8 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
1160/* scheduled scan handling */ 1161/* scheduled scan handling */
1161int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, 1162int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
1162 struct cfg80211_sched_scan_request *req); 1163 struct cfg80211_sched_scan_request *req);
1163int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata, 1164int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
1164 bool driver_initiated); 1165void ieee80211_sched_scan_stopped_work(struct work_struct *work);
1165 1166
1166/* off-channel helpers */ 1167/* off-channel helpers */
1167bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local); 1168bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 30e6a682a047..7f89011fa22d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -652,6 +652,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
652 setup_timer(&local->dynamic_ps_timer, 652 setup_timer(&local->dynamic_ps_timer,
653 ieee80211_dynamic_ps_timer, (unsigned long) local); 653 ieee80211_dynamic_ps_timer, (unsigned long) local);
654 654
655 INIT_WORK(&local->sched_scan_stopped_work,
656 ieee80211_sched_scan_stopped_work);
657
655 sta_info_init(local); 658 sta_info_init(local);
656 659
657 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 660 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ea44a8e941ec..d20046b5d8f4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -902,8 +902,7 @@ out:
902 return ret; 902 return ret;
903} 903}
904 904
905int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata, 905int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
906 bool driver_initiated)
907{ 906{
908 struct ieee80211_local *local = sdata->local; 907 struct ieee80211_local *local = sdata->local;
909 int ret = 0, i; 908 int ret = 0, i;
@@ -919,11 +918,9 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata,
919 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 918 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
920 kfree(local->sched_scan_ies.ie[i]); 919 kfree(local->sched_scan_ies.ie[i]);
921 920
922 if (!driver_initiated) 921 drv_sched_scan_stop(local, sdata);
923 drv_sched_scan_stop(local, sdata);
924 local->sched_scanning = false; 922 local->sched_scanning = false;
925 } 923 }
926
927out: 924out:
928 mutex_unlock(&sdata->local->mtx); 925 mutex_unlock(&sdata->local->mtx);
929 926
@@ -940,12 +937,36 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
940} 937}
941EXPORT_SYMBOL(ieee80211_sched_scan_results); 938EXPORT_SYMBOL(ieee80211_sched_scan_results);
942 939
940void ieee80211_sched_scan_stopped_work(struct work_struct *work)
941{
942 struct ieee80211_local *local =
943 container_of(work, struct ieee80211_local,
944 sched_scan_stopped_work);
945 int i;
946
947 mutex_lock(&local->mtx);
948
949 if (!local->sched_scanning) {
950 mutex_unlock(&local->mtx);
951 return;
952 }
953
954 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
955 kfree(local->sched_scan_ies.ie[i]);
956
957 local->sched_scanning = false;
958
959 mutex_unlock(&local->mtx);
960
961 cfg80211_sched_scan_stopped(local->hw.wiphy);
962}
963
943void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) 964void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
944{ 965{
945 struct ieee80211_local *local = hw_to_local(hw); 966 struct ieee80211_local *local = hw_to_local(hw);
946 967
947 trace_api_sched_scan_stopped(local); 968 trace_api_sched_scan_stopped(local);
948 969
949 cfg80211_sched_scan_stopped(hw->wiphy); 970 ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
950} 971}
951EXPORT_SYMBOL(ieee80211_sched_scan_stopped); 972EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index e2ab65d7c86d..18b002f16860 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -371,7 +371,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
371 INIT_LIST_HEAD(&rdev->bss_list); 371 INIT_LIST_HEAD(&rdev->bss_list);
372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
373 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results); 373 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
374 INIT_WORK(&rdev->sched_scan_stopped_wk, __cfg80211_sched_scan_stopped);
375#ifdef CONFIG_CFG80211_WEXT 374#ifdef CONFIG_CFG80211_WEXT
376 rdev->wiphy.wext = &cfg80211_wext_handler; 375 rdev->wiphy.wext = &cfg80211_wext_handler;
377#endif 376#endif
diff --git a/net/wireless/core.h b/net/wireless/core.h
index fd9135f9b5be..d4b8f4c0bbbb 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -64,7 +64,6 @@ struct cfg80211_registered_device {
64 unsigned long suspend_at; 64 unsigned long suspend_at;
65 struct work_struct scan_done_wk; 65 struct work_struct scan_done_wk;
66 struct work_struct sched_scan_results_wk; 66 struct work_struct sched_scan_results_wk;
67 struct work_struct sched_scan_stopped_wk;
68 67
69#ifdef CONFIG_NL80211_TESTMODE 68#ifdef CONFIG_NL80211_TESTMODE
70 struct genl_info *testmode_info; 69 struct genl_info *testmode_info;
@@ -417,7 +416,6 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
417void __cfg80211_sched_scan_results(struct work_struct *wk); 416void __cfg80211_sched_scan_results(struct work_struct *wk);
418int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 417int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
419 bool driver_initiated); 418 bool driver_initiated);
420void __cfg80211_sched_scan_stopped(struct work_struct *wk);
421void cfg80211_upload_connect_keys(struct wireless_dev *wdev); 419void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
422int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 420int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
423 struct net_device *dev, enum nl80211_iftype ntype, 421 struct net_device *dev, enum nl80211_iftype ntype,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 65dfae3b9d41..73a441d237b5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -119,22 +119,14 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy)
119} 119}
120EXPORT_SYMBOL(cfg80211_sched_scan_results); 120EXPORT_SYMBOL(cfg80211_sched_scan_results);
121 121
122void __cfg80211_sched_scan_stopped(struct work_struct *wk) 122void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
123{ 123{
124 struct cfg80211_registered_device *rdev; 124 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
125
126 rdev = container_of(wk, struct cfg80211_registered_device,
127 sched_scan_stopped_wk);
128 125
129 cfg80211_lock_rdev(rdev); 126 cfg80211_lock_rdev(rdev);
130 __cfg80211_stop_sched_scan(rdev, true); 127 __cfg80211_stop_sched_scan(rdev, true);
131 cfg80211_unlock_rdev(rdev); 128 cfg80211_unlock_rdev(rdev);
132} 129}
133
134void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
135{
136 queue_work(cfg80211_wq, &wiphy_to_dev(wiphy)->sched_scan_stopped_wk);
137}
138EXPORT_SYMBOL(cfg80211_sched_scan_stopped); 130EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
139 131
140int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 132int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
@@ -150,10 +142,11 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
150 142
151 dev = rdev->sched_scan_req->dev; 143 dev = rdev->sched_scan_req->dev;
152 144
153 err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev, 145 if (!driver_initiated) {
154 driver_initiated); 146 err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
155 if (err) 147 if (err)
156 return err; 148 return err;
149 }
157 150
158 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); 151 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
159 152