diff options
author | Luciano Coelho <coelho@ti.com> | 2011-08-23 11:34:44 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-08-25 03:24:29 -0400 |
commit | f952079a19c69843f4da2f7e0da008192421c6ce (patch) | |
tree | 06cbe22ff43bae74bc8bb2426df1387bb1384ce5 /drivers/net/wireless/wl12xx/scan.c | |
parent | 05dba3550603b9dc8609b5ea7c3ffba4e3bb97f2 (diff) |
wl12xx: add support for multiple SSIDs in sched_scan
The wl12xx firmwares support multiple SSIDs in a single sched_scan
run. This patch implements support for it.
We use three different types os sched_scan: FILTER_ANY (ie. not
filtering, only wildcard SSID in the probe_reqs); FILTER_LIST (ie. send out
probe_reqs with the specified SSIDs and only report if they are
found); and FILTER_DISABLED (ie. send out probe_reqs with the
specified SSIDs, but report anything found).
Since we still don't have proper filter support in nl80211/cfg80211
yet, we cannot use filters when the wildcard SSID is used. Thus, we
will not filter anything if the wildcard SSID is specified.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/scan.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 7229eaa89018..af9d53c8e19c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -473,6 +473,48 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, | |||
473 | cfg->passive[2] || cfg->active[2]; | 473 | cfg->passive[2] || cfg->active[2]; |
474 | } | 474 | } |
475 | 475 | ||
476 | /* Returns 0 if no wildcard is used, 1 if wildcard is used or a | ||
477 | * negative value on error */ | ||
478 | static int | ||
479 | wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, | ||
480 | struct cfg80211_sched_scan_request *req) | ||
481 | { | ||
482 | struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; | ||
483 | struct cfg80211_ssid *ssid = req->ssids; | ||
484 | int ret, wildcard = 0; | ||
485 | |||
486 | wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list"); | ||
487 | |||
488 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
489 | if (!cmd) | ||
490 | return -ENOMEM; | ||
491 | |||
492 | while ((cmd->n_ssids < req->n_ssids) && ssid) { | ||
493 | if (ssid->ssid_len == 0) | ||
494 | wildcard = 1; | ||
495 | cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN; | ||
496 | cmd->ssids[cmd->n_ssids].len = ssid->ssid_len; | ||
497 | memcpy(cmd->ssids[cmd->n_ssids].ssid, ssid->ssid, | ||
498 | ssid->ssid_len); | ||
499 | ssid++; | ||
500 | cmd->n_ssids++; | ||
501 | } | ||
502 | |||
503 | wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd)); | ||
504 | |||
505 | ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd, | ||
506 | sizeof(*cmd), 0); | ||
507 | if (ret < 0) { | ||
508 | wl1271_error("cmd sched scan ssid list failed"); | ||
509 | goto out; | ||
510 | } | ||
511 | |||
512 | ret = wildcard; | ||
513 | out: | ||
514 | kfree(cmd); | ||
515 | return ret; | ||
516 | } | ||
517 | |||
476 | int wl1271_scan_sched_scan_config(struct wl1271 *wl, | 518 | int wl1271_scan_sched_scan_config(struct wl1271 *wl, |
477 | struct cfg80211_sched_scan_request *req, | 519 | struct cfg80211_sched_scan_request *req, |
478 | struct ieee80211_sched_scan_ies *ies) | 520 | struct ieee80211_sched_scan_ies *ies) |
@@ -504,14 +546,21 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
504 | for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) | 546 | for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) |
505 | cfg->intervals[i] = cpu_to_le32(req->interval); | 547 | cfg->intervals[i] = cpu_to_le32(req->interval); |
506 | 548 | ||
507 | if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { | 549 | cfg->ssid_len = 0; |
508 | cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; | 550 | if (req->n_ssids == 0) { |
509 | cfg->ssid_len = req->ssids[0].ssid_len; | 551 | wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_ANY"); |
510 | memcpy(cfg->ssid, req->ssids[0].ssid, | ||
511 | req->ssids[0].ssid_len); | ||
512 | } else { | ||
513 | cfg->filter_type = SCAN_SSID_FILTER_ANY; | 552 | cfg->filter_type = SCAN_SSID_FILTER_ANY; |
514 | cfg->ssid_len = 0; | 553 | } else { |
554 | ret = wl12xx_scan_sched_scan_ssid_list(wl, req); | ||
555 | if (ret < 0) | ||
556 | goto out; | ||
557 | if (ret) { | ||
558 | wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_DISABLED"); | ||
559 | cfg->filter_type = SCAN_SSID_FILTER_DISABLED; | ||
560 | } else { | ||
561 | wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_LIST"); | ||
562 | cfg->filter_type = SCAN_SSID_FILTER_LIST; | ||
563 | } | ||
515 | } | 564 | } |
516 | 565 | ||
517 | if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { | 566 | if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { |