diff options
author | Luciano Coelho <coelho@ti.com> | 2011-05-11 10:09:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-11 15:12:27 -0400 |
commit | 79f460ca49d8d5700756ab7071c951311c7f29cc (patch) | |
tree | b11b62473697c6c1858b83b3abe5181990f85c19 /net/mac80211/scan.c | |
parent | 807f8a8c300435d5483e8d78df9dcdbc27333166 (diff) |
mac80211: add support for HW scheduled scan
Implement support for HW scheduled scan. The mac80211 code doesn't perform
scheduled scans itself, but calls the driver to start and stop scheduled
scans.
This patch also creates a trace event class to be used by drv_hw_scan
and the new drv_sched_scan_start and drv_sched_stop functions, in
order to avoid duplicate code.
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.c | 99 |
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 | |||
855 | int 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 | |||
897 | out_free: | ||
898 | while (i > 0) | ||
899 | kfree(local->sched_scan_ies.ie[--i]); | ||
900 | out: | ||
901 | mutex_unlock(&sdata->local->mtx); | ||
902 | return ret; | ||
903 | } | ||
904 | |||
905 | int 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 | |||
927 | out: | ||
928 | mutex_unlock(&sdata->local->mtx); | ||
929 | |||
930 | return ret; | ||
931 | } | ||
932 | |||
933 | void 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 | } | ||
941 | EXPORT_SYMBOL(ieee80211_sched_scan_results); | ||
942 | |||
943 | void 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 | } | ||
951 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); | ||