aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8acce724f0dc..ea44a8e941ec 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -15,6 +15,7 @@
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h> 17#include <linux/pm_qos_params.h>
18#include <linux/slab.h>
18#include <net/sch_generic.h> 19#include <net/sch_generic.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <net/mac80211.h> 21#include <net/mac80211.h>
@@ -850,3 +851,101 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
850 } 851 }
851 mutex_unlock(&local->mtx); 852 mutex_unlock(&local->mtx);
852} 853}
854
855int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
856 struct cfg80211_sched_scan_request *req)
857{
858 struct ieee80211_local *local = sdata->local;
859 int ret, i;
860
861 mutex_lock(&sdata->local->mtx);
862
863 if (local->sched_scanning) {
864 ret = -EBUSY;
865 goto out;
866 }
867
868 if (!local->ops->sched_scan_start) {
869 ret = -ENOTSUPP;
870 goto out;
871 }
872
873 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
874 local->sched_scan_ies.ie[i] = kzalloc(2 +
875 IEEE80211_MAX_SSID_LEN +
876 local->scan_ies_len,
877 GFP_KERNEL);
878 if (!local->sched_scan_ies.ie[i]) {
879 ret = -ENOMEM;
880 goto out_free;
881 }
882
883 local->sched_scan_ies.len[i] =
884 ieee80211_build_preq_ies(local,
885 local->sched_scan_ies.ie[i],
886 req->ie, req->ie_len, i,
887 (u32) -1, 0);
888 }
889
890 ret = drv_sched_scan_start(local, sdata, req,
891 &local->sched_scan_ies);
892 if (ret == 0) {
893 local->sched_scanning = true;
894 goto out;
895 }
896
897out_free:
898 while (i > 0)
899 kfree(local->sched_scan_ies.ie[--i]);
900out:
901 mutex_unlock(&sdata->local->mtx);
902 return ret;
903}
904
905int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata,
906 bool driver_initiated)
907{
908 struct ieee80211_local *local = sdata->local;
909 int ret = 0, i;
910
911 mutex_lock(&sdata->local->mtx);
912
913 if (!local->ops->sched_scan_stop) {
914 ret = -ENOTSUPP;
915 goto out;
916 }
917
918 if (local->sched_scanning) {
919 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
920 kfree(local->sched_scan_ies.ie[i]);
921
922 if (!driver_initiated)
923 drv_sched_scan_stop(local, sdata);
924 local->sched_scanning = false;
925 }
926
927out:
928 mutex_unlock(&sdata->local->mtx);
929
930 return ret;
931}
932
933void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
934{
935 struct ieee80211_local *local = hw_to_local(hw);
936
937 trace_api_sched_scan_results(local);
938
939 cfg80211_sched_scan_results(hw->wiphy);
940}
941EXPORT_SYMBOL(ieee80211_sched_scan_results);
942
943void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
944{
945 struct ieee80211_local *local = hw_to_local(hw);
946
947 trace_api_sched_scan_stopped(local);
948
949 cfg80211_sched_scan_stopped(hw->wiphy);
950}
951EXPORT_SYMBOL(ieee80211_sched_scan_stopped);