aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNaveen Singh <navesing@qca.qualcomm.com>2012-05-16 06:29:00 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2012-05-16 09:25:06 -0400
commitdd45b7598f1c52933f276ba7ce175fa1305b8ba0 (patch)
treedb7aa4349acc89c4fb78115ef44ace79bca7a445 /drivers
parentc422d52d0450988ce9a1ffdddb78807538396749 (diff)
ath6kl: Include match ssid list in scheduled scan
Scheduled scan implementation was only taking probed list into consideration. The matched list was dropped. This would cause FW not to report the AP as the list never had that AP's SSID populated. This was causing long connection time when supplicant would just issue a wild card SSID in probed list. As a part of this implementation, ath6kl driver would create a complete list by taking both probed and matched list and pass it to FW. FW would probe for the SSID that it needs to and would match against the relevant SSIDS that is been configured. kvalo: whitespace changes, less indentation in the for loop, use ++ Signed-off-by: Naveen Singh <navesing@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c98
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h5
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h6
3 files changed, 99 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index e68b1077816a..f3a6cfc0ddc8 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -53,6 +53,11 @@
53 53
54#define DEFAULT_BG_SCAN_PERIOD 60 54#define DEFAULT_BG_SCAN_PERIOD 60
55 55
56struct ath6kl_cfg80211_match_probe_ssid {
57 struct cfg80211_ssid ssid;
58 u8 flag;
59};
60
56static struct ieee80211_rate ath6kl_rates[] = { 61static struct ieee80211_rate ath6kl_rates[] = {
57 RATETAB_ENT(10, 0x1, 0), 62 RATETAB_ENT(10, 0x1, 0),
58 RATETAB_ENT(20, 0x2, 0), 63 RATETAB_ENT(20, 0x2, 0),
@@ -887,23 +892,76 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
887 892
888static int ath6kl_set_probed_ssids(struct ath6kl *ar, 893static int ath6kl_set_probed_ssids(struct ath6kl *ar,
889 struct ath6kl_vif *vif, 894 struct ath6kl_vif *vif,
890 struct cfg80211_ssid *ssids, int n_ssids) 895 struct cfg80211_ssid *ssids, int n_ssids,
896 struct cfg80211_match_set *match_set,
897 int n_match_ssid)
891{ 898{
892 u8 i; 899 u8 i, j, index_to_add, ssid_found = false;
900 struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
901
902 memset(ssid_list, 0, sizeof(ssid_list));
893 903
894 if (n_ssids > MAX_PROBED_SSIDS) 904 if (n_ssids > MAX_PROBED_SSIDS ||
905 n_match_ssid > MAX_PROBED_SSIDS)
895 return -EINVAL; 906 return -EINVAL;
896 907
897 for (i = 0; i < n_ssids; i++) { 908 for (i = 0; i < n_ssids; i++) {
909 memcpy(ssid_list[i].ssid.ssid,
910 ssids[i].ssid,
911 ssids[i].ssid_len);
912 ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
913
914 if (ssids[i].ssid_len)
915 ssid_list[i].flag = SPECIFIC_SSID_FLAG;
916 else
917 ssid_list[i].flag = ANY_SSID_FLAG;
918
919 if (n_match_ssid == 0)
920 ssid_list[i].flag |= MATCH_SSID_FLAG;
921 }
922
923 index_to_add = i;
924
925 for (i = 0; i < n_match_ssid; i++) {
926 ssid_found = false;
927
928 for (j = 0; j < n_ssids; j++) {
929 if ((match_set[i].ssid.ssid_len ==
930 ssid_list[j].ssid.ssid_len) &&
931 (!memcmp(ssid_list[j].ssid.ssid,
932 match_set[i].ssid.ssid,
933 match_set[i].ssid.ssid_len))) {
934 ssid_list[j].flag |= MATCH_SSID_FLAG;
935 ssid_found = true;
936 break;
937 }
938 }
939
940 if (ssid_found)
941 continue;
942
943 if (index_to_add >= MAX_PROBED_SSIDS)
944 continue;
945
946 ssid_list[index_to_add].ssid.ssid_len =
947 match_set[i].ssid.ssid_len;
948 memcpy(ssid_list[index_to_add].ssid.ssid,
949 match_set[i].ssid.ssid,
950 match_set[i].ssid.ssid_len);
951 ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
952 index_to_add++;
953 }
954
955 for (i = 0; i < index_to_add; i++) {
898 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, 956 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
899 ssids[i].ssid_len ? 957 ssid_list[i].flag,
900 SPECIFIC_SSID_FLAG : ANY_SSID_FLAG, 958 ssid_list[i].ssid.ssid_len,
901 ssids[i].ssid_len, 959 ssid_list[i].ssid.ssid);
902 ssids[i].ssid); 960
903 } 961 }
904 962
905 /* Make sure no old entries are left behind */ 963 /* Make sure no old entries are left behind */
906 for (i = n_ssids; i < MAX_PROBED_SSIDS; i++) { 964 for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
907 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, 965 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
908 DISABLE_SSID_FLAG, 0, NULL); 966 DISABLE_SSID_FLAG, 0, NULL);
909 } 967 }
@@ -937,7 +995,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
937 } 995 }
938 996
939 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, 997 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
940 request->n_ssids); 998 request->n_ssids, NULL, 0);
941 if (ret < 0) 999 if (ret < 0)
942 return ret; 1000 return ret;
943 1001
@@ -3194,10 +3252,24 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3194 ath6kl_cfg80211_scan_complete_event(vif, true); 3252 ath6kl_cfg80211_scan_complete_event(vif, true);
3195 3253
3196 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, 3254 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3197 request->n_ssids); 3255 request->n_ssids,
3256 request->match_sets,
3257 request->n_match_sets);
3198 if (ret < 0) 3258 if (ret < 0)
3199 return ret; 3259 return ret;
3200 3260
3261 if (!request->n_match_sets) {
3262 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3263 ALL_BSS_FILTER, 0);
3264 if (ret < 0)
3265 return ret;
3266 } else {
3267 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3268 MATCHED_SSID_FILTER, 0);
3269 if (ret < 0)
3270 return ret;
3271 }
3272
3201 /* fw uses seconds, also make sure that it's >0 */ 3273 /* fw uses seconds, also make sure that it's >0 */
3202 interval = max_t(u16, 1, request->interval / 1000); 3274 interval = max_t(u16, 1, request->interval / 1000);
3203 3275
@@ -3505,6 +3577,12 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3505 3577
3506 /* max num of ssids that can be probed during scanning */ 3578 /* max num of ssids that can be probed during scanning */
3507 wiphy->max_scan_ssids = MAX_PROBED_SSIDS; 3579 wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3580
3581 /* max num of ssids that can be matched after scan */
3582 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3583 ar->fw_capabilities))
3584 wiphy->max_match_sets = MAX_PROBED_SSIDS;
3585
3508 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ 3586 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3509 switch (ar->hw.cap) { 3587 switch (ar->hw.cap) {
3510 case WMI_11AN_CAP: 3588 case WMI_11AN_CAP:
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 99169794ff3a..991bd96f7cf6 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -110,6 +110,11 @@ enum ath6kl_fw_capability {
110 /* Firmware supports enhanced bmiss detection */ 110 /* Firmware supports enhanced bmiss detection */
111 ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, 111 ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
112 112
113 /*
114 * FW supports matching of ssid in schedule scan
115 */
116 ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
117
113 /* this needs to be last */ 118 /* this needs to be last */
114 ATH6KL_FW_CAPABILITY_MAX, 119 ATH6KL_FW_CAPABILITY_MAX,
115}; 120};
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 8c07e3858b11..47756795a26c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -964,6 +964,9 @@ enum wmi_bss_filter {
964 /* beacons matching probed ssid */ 964 /* beacons matching probed ssid */
965 PROBED_SSID_FILTER, 965 PROBED_SSID_FILTER,
966 966
967 /* beacons matching matched ssid */
968 MATCHED_SSID_FILTER,
969
967 /* marker only */ 970 /* marker only */
968 LAST_BSS_FILTER, 971 LAST_BSS_FILTER,
969}; 972};
@@ -993,6 +996,9 @@ enum wmi_ssid_flag {
993 996
994 /* probes for any ssid */ 997 /* probes for any ssid */
995 ANY_SSID_FLAG = 0x02, 998 ANY_SSID_FLAG = 0x02,
999
1000 /* match for ssid */
1001 MATCH_SSID_FLAG = 0x08,
996}; 1002};
997 1003
998struct wmi_probed_ssid_cmd { 1004struct wmi_probed_ssid_cmd {