aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
authorLuciano Coelho <coelho@ti.com>2011-05-11 10:09:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-11 15:12:27 -0400
commit79f460ca49d8d5700756ab7071c951311c7f29cc (patch)
treeb11b62473697c6c1858b83b3abe5181990f85c19 /net/mac80211/scan.c
parent807f8a8c300435d5483e8d78df9dcdbc27333166 (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.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);