aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
authorLuciano Coelho <coelho@ti.com>2011-05-12 09:28:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-12 14:10:55 -0400
commit85a9994a0a6cba1a6cc6af4bd3ebd85f778be0fe (patch)
treee9dd8fff75d9c0ee2f5aec129bb6132499c72461 /net/mac80211/scan.c
parenta3836e02ba4c50db958d32d710b226f2408623dc (diff)
cfg80211/mac80211: avoid bounce back mac->cfg->mac on sched_scan_stopped
When sched_scan_stopped was called by the driver, mac80211 calls cfg80211, which in turn was calling mac80211 back with a flag "driver_initiated". This flag was used so that mac80211 would do the necessary cleanup but would not call the driver. This was enough to prevent the bounce back between the driver and mac80211, but not between mac80211 and cfg80211. To fix this, we now do the cleanup in mac80211 before calling cfg80211. To help with locking issues, the workqueue was moved from cfg80211 to mac80211. Reported-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Luciano Coelho <coelho@ti.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ea44a8e941e..d20046b5d8f 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);