scan.c revision 90921014608d91a03766d0025fa32662dc7c5062
1/* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2009-2010 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 * 22 */ 23 24#include <linux/ieee80211.h> 25 26#include "wl12xx.h" 27#include "debug.h" 28#include "cmd.h" 29#include "scan.h" 30#include "acx.h" 31#include "ps.h" 32#include "tx.h" 33 34void wl1271_scan_complete_work(struct work_struct *work) 35{ 36 struct delayed_work *dwork; 37 struct wl1271 *wl; 38 struct ieee80211_vif *vif; 39 struct wl12xx_vif *wlvif; 40 int ret; 41 42 dwork = container_of(work, struct delayed_work, work); 43 wl = container_of(dwork, struct wl1271, scan_complete_work); 44 45 wl1271_debug(DEBUG_SCAN, "Scanning complete"); 46 47 mutex_lock(&wl->mutex); 48 49 if (wl->state == WL1271_STATE_OFF) 50 goto out; 51 52 if (wl->scan.state == WL1271_SCAN_STATE_IDLE) 53 goto out; 54 55 vif = wl->scan_vif; 56 wlvif = wl12xx_vif_to_data(vif); 57 58 /* 59 * Rearm the tx watchdog just before idling scan. This 60 * prevents just-finished scans from triggering the watchdog 61 */ 62 wl12xx_rearm_tx_watchdog_locked(wl); 63 64 wl->scan.state = WL1271_SCAN_STATE_IDLE; 65 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 66 wl->scan.req = NULL; 67 wl->scan_vif = NULL; 68 69 ret = wl1271_ps_elp_wakeup(wl); 70 if (ret < 0) 71 goto out; 72 73 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { 74 /* restore hardware connection monitoring template */ 75 wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq); 76 } 77 78 wl1271_ps_elp_sleep(wl); 79 80 if (wl->scan.failed) { 81 wl1271_info("Scan completed due to error."); 82 wl12xx_queue_recovery_work(wl); 83 } 84 85 ieee80211_scan_completed(wl->hw, false); 86 87out: 88 mutex_unlock(&wl->mutex); 89 90} 91 92 93static int wl1271_get_scan_channels(struct wl1271 *wl, 94 struct cfg80211_scan_request *req, 95 struct basic_scan_channel_params *channels, 96 enum ieee80211_band band, bool passive) 97{ 98 struct conf_scan_settings *c = &wl->conf.scan; 99 int i, j; 100 u32 flags; 101 102 for (i = 0, j = 0; 103 i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; 104 i++) { 105 flags = req->channels[i]->flags; 106 107 if (!test_bit(i, wl->scan.scanned_ch) && 108 !(flags & IEEE80211_CHAN_DISABLED) && 109 (req->channels[i]->band == band) && 110 /* 111 * In passive scans, we scan all remaining 112 * channels, even if not marked as such. 113 * In active scans, we only scan channels not 114 * marked as passive. 115 */ 116 (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { 117 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", 118 req->channels[i]->band, 119 req->channels[i]->center_freq); 120 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", 121 req->channels[i]->hw_value, 122 req->channels[i]->flags); 123 wl1271_debug(DEBUG_SCAN, 124 "max_antenna_gain %d, max_power %d", 125 req->channels[i]->max_antenna_gain, 126 req->channels[i]->max_power); 127 wl1271_debug(DEBUG_SCAN, "beacon_found %d", 128 req->channels[i]->beacon_found); 129 130 if (!passive) { 131 channels[j].min_duration = 132 cpu_to_le32(c->min_dwell_time_active); 133 channels[j].max_duration = 134 cpu_to_le32(c->max_dwell_time_active); 135 } else { 136 channels[j].min_duration = 137 cpu_to_le32(c->min_dwell_time_passive); 138 channels[j].max_duration = 139 cpu_to_le32(c->max_dwell_time_passive); 140 } 141 channels[j].early_termination = 0; 142 channels[j].tx_power_att = req->channels[i]->max_power; 143 channels[j].channel = req->channels[i]->hw_value; 144 145 memset(&channels[j].bssid_lsb, 0xff, 4); 146 memset(&channels[j].bssid_msb, 0xff, 2); 147 148 /* Mark the channels we already used */ 149 set_bit(i, wl->scan.scanned_ch); 150 151 j++; 152 } 153 } 154 155 return j; 156} 157 158#define WL1271_NOTHING_TO_SCAN 1 159 160static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif, 161 enum ieee80211_band band, 162 bool passive, u32 basic_rate) 163{ 164 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 165 struct wl1271_cmd_scan *cmd; 166 struct wl1271_cmd_trigger_scan_to *trigger; 167 int ret; 168 u16 scan_options = 0; 169 170 /* skip active scans if we don't have SSIDs */ 171 if (!passive && wl->scan.req->n_ssids == 0) 172 return WL1271_NOTHING_TO_SCAN; 173 174 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 175 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); 176 if (!cmd || !trigger) { 177 ret = -ENOMEM; 178 goto out; 179 } 180 181 if (wl->conf.scan.split_scan_timeout) 182 scan_options |= WL1271_SCAN_OPT_SPLIT_SCAN; 183 184 if (passive) 185 scan_options |= WL1271_SCAN_OPT_PASSIVE; 186 187 if (wlvif->bss_type == BSS_TYPE_AP_BSS || 188 test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 189 cmd->params.role_id = wlvif->role_id; 190 else 191 cmd->params.role_id = wlvif->dev_role_id; 192 193 if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) { 194 ret = -EINVAL; 195 goto out; 196 } 197 198 cmd->params.scan_options = cpu_to_le16(scan_options); 199 200 cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, 201 cmd->channels, 202 band, passive); 203 if (cmd->params.n_ch == 0) { 204 ret = WL1271_NOTHING_TO_SCAN; 205 goto out; 206 } 207 208 cmd->params.tx_rate = cpu_to_le32(basic_rate); 209 cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; 210 cmd->params.tid_trigger = CONF_TX_AC_ANY_TID; 211 cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 212 213 if (band == IEEE80211_BAND_2GHZ) 214 cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ; 215 else 216 cmd->params.band = WL1271_SCAN_BAND_5_GHZ; 217 218 if (wl->scan.ssid_len && wl->scan.ssid) { 219 cmd->params.ssid_len = wl->scan.ssid_len; 220 memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len); 221 } 222 223 memcpy(cmd->addr, vif->addr, ETH_ALEN); 224 225 ret = wl12xx_cmd_build_probe_req(wl, wlvif, 226 cmd->params.role_id, band, 227 wl->scan.ssid, wl->scan.ssid_len, 228 wl->scan.req->ie, 229 wl->scan.req->ie_len); 230 if (ret < 0) { 231 wl1271_error("PROBE request template failed"); 232 goto out; 233 } 234 235 trigger->timeout = cpu_to_le32(wl->conf.scan.split_scan_timeout); 236 ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, 237 sizeof(*trigger), 0); 238 if (ret < 0) { 239 wl1271_error("trigger scan to failed for hw scan"); 240 goto out; 241 } 242 243 wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd)); 244 245 ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0); 246 if (ret < 0) { 247 wl1271_error("SCAN failed"); 248 goto out; 249 } 250 251out: 252 kfree(cmd); 253 kfree(trigger); 254 return ret; 255} 256 257void wl1271_scan_stm(struct wl1271 *wl, struct ieee80211_vif *vif) 258{ 259 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 260 int ret = 0; 261 enum ieee80211_band band; 262 u32 rate, mask; 263 264 switch (wl->scan.state) { 265 case WL1271_SCAN_STATE_IDLE: 266 break; 267 268 case WL1271_SCAN_STATE_2GHZ_ACTIVE: 269 band = IEEE80211_BAND_2GHZ; 270 mask = wlvif->bitrate_masks[band]; 271 if (wl->scan.req->no_cck) { 272 mask &= ~CONF_TX_CCK_RATES; 273 if (!mask) 274 mask = CONF_TX_RATE_MASK_BASIC_P2P; 275 } 276 rate = wl1271_tx_min_rate_get(wl, mask); 277 ret = wl1271_scan_send(wl, vif, band, false, rate); 278 if (ret == WL1271_NOTHING_TO_SCAN) { 279 wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; 280 wl1271_scan_stm(wl, vif); 281 } 282 283 break; 284 285 case WL1271_SCAN_STATE_2GHZ_PASSIVE: 286 band = IEEE80211_BAND_2GHZ; 287 mask = wlvif->bitrate_masks[band]; 288 if (wl->scan.req->no_cck) { 289 mask &= ~CONF_TX_CCK_RATES; 290 if (!mask) 291 mask = CONF_TX_RATE_MASK_BASIC_P2P; 292 } 293 rate = wl1271_tx_min_rate_get(wl, mask); 294 ret = wl1271_scan_send(wl, vif, band, true, rate); 295 if (ret == WL1271_NOTHING_TO_SCAN) { 296 if (wl->enable_11a) 297 wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; 298 else 299 wl->scan.state = WL1271_SCAN_STATE_DONE; 300 wl1271_scan_stm(wl, vif); 301 } 302 303 break; 304 305 case WL1271_SCAN_STATE_5GHZ_ACTIVE: 306 band = IEEE80211_BAND_5GHZ; 307 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); 308 ret = wl1271_scan_send(wl, vif, band, false, rate); 309 if (ret == WL1271_NOTHING_TO_SCAN) { 310 wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; 311 wl1271_scan_stm(wl, vif); 312 } 313 314 break; 315 316 case WL1271_SCAN_STATE_5GHZ_PASSIVE: 317 band = IEEE80211_BAND_5GHZ; 318 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); 319 ret = wl1271_scan_send(wl, vif, band, true, rate); 320 if (ret == WL1271_NOTHING_TO_SCAN) { 321 wl->scan.state = WL1271_SCAN_STATE_DONE; 322 wl1271_scan_stm(wl, vif); 323 } 324 325 break; 326 327 case WL1271_SCAN_STATE_DONE: 328 wl->scan.failed = false; 329 cancel_delayed_work(&wl->scan_complete_work); 330 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, 331 msecs_to_jiffies(0)); 332 break; 333 334 default: 335 wl1271_error("invalid scan state"); 336 break; 337 } 338 339 if (ret < 0) { 340 cancel_delayed_work(&wl->scan_complete_work); 341 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, 342 msecs_to_jiffies(0)); 343 } 344} 345 346int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif, 347 const u8 *ssid, size_t ssid_len, 348 struct cfg80211_scan_request *req) 349{ 350 /* 351 * cfg80211 should guarantee that we don't get more channels 352 * than what we have registered. 353 */ 354 BUG_ON(req->n_channels > WL1271_MAX_CHANNELS); 355 356 if (wl->scan.state != WL1271_SCAN_STATE_IDLE) 357 return -EBUSY; 358 359 wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; 360 361 if (ssid_len && ssid) { 362 wl->scan.ssid_len = ssid_len; 363 memcpy(wl->scan.ssid, ssid, ssid_len); 364 } else { 365 wl->scan.ssid_len = 0; 366 } 367 368 wl->scan_vif = vif; 369 wl->scan.req = req; 370 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 371 372 /* we assume failure so that timeout scenarios are handled correctly */ 373 wl->scan.failed = true; 374 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, 375 msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); 376 377 wl1271_scan_stm(wl, vif); 378 379 return 0; 380} 381 382int wl1271_scan_stop(struct wl1271 *wl) 383{ 384 struct wl1271_cmd_header *cmd = NULL; 385 int ret = 0; 386 387 if (WARN_ON(wl->scan.state == WL1271_SCAN_STATE_IDLE)) 388 return -EINVAL; 389 390 wl1271_debug(DEBUG_CMD, "cmd scan stop"); 391 392 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 393 if (!cmd) { 394 ret = -ENOMEM; 395 goto out; 396 } 397 398 ret = wl1271_cmd_send(wl, CMD_STOP_SCAN, cmd, 399 sizeof(*cmd), 0); 400 if (ret < 0) { 401 wl1271_error("cmd stop_scan failed"); 402 goto out; 403 } 404out: 405 kfree(cmd); 406 return ret; 407} 408 409static int 410wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, 411 struct cfg80211_sched_scan_request *req, 412 struct conn_scan_ch_params *channels, 413 u32 band, bool radar, bool passive, 414 int start, int max_channels) 415{ 416 struct conf_sched_scan_settings *c = &wl->conf.sched_scan; 417 int i, j; 418 u32 flags; 419 bool force_passive = !req->n_ssids; 420 u32 min_dwell_time_active, max_dwell_time_active, delta_per_probe; 421 u32 dwell_time_passive, dwell_time_dfs; 422 423 if (band == IEEE80211_BAND_5GHZ) 424 delta_per_probe = c->dwell_time_delta_per_probe_5; 425 else 426 delta_per_probe = c->dwell_time_delta_per_probe; 427 428 min_dwell_time_active = c->base_dwell_time + 429 req->n_ssids * c->num_probe_reqs * delta_per_probe; 430 431 max_dwell_time_active = min_dwell_time_active + c->max_dwell_time_delta; 432 433 min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000); 434 max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000); 435 dwell_time_passive = DIV_ROUND_UP(c->dwell_time_passive, 1000); 436 dwell_time_dfs = DIV_ROUND_UP(c->dwell_time_dfs, 1000); 437 438 for (i = 0, j = start; 439 i < req->n_channels && j < max_channels; 440 i++) { 441 flags = req->channels[i]->flags; 442 443 if (force_passive) 444 flags |= IEEE80211_CHAN_PASSIVE_SCAN; 445 446 if ((req->channels[i]->band == band) && 447 !(flags & IEEE80211_CHAN_DISABLED) && 448 (!!(flags & IEEE80211_CHAN_RADAR) == radar) && 449 /* if radar is set, we ignore the passive flag */ 450 (radar || 451 !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { 452 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", 453 req->channels[i]->band, 454 req->channels[i]->center_freq); 455 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", 456 req->channels[i]->hw_value, 457 req->channels[i]->flags); 458 wl1271_debug(DEBUG_SCAN, "max_power %d", 459 req->channels[i]->max_power); 460 wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d", 461 min_dwell_time_active, 462 max_dwell_time_active); 463 464 if (flags & IEEE80211_CHAN_RADAR) { 465 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 466 467 channels[j].passive_duration = 468 cpu_to_le16(dwell_time_dfs); 469 } else { 470 channels[j].passive_duration = 471 cpu_to_le16(dwell_time_passive); 472 } 473 474 channels[j].min_duration = 475 cpu_to_le16(min_dwell_time_active); 476 channels[j].max_duration = 477 cpu_to_le16(max_dwell_time_active); 478 479 channels[j].tx_power_att = req->channels[i]->max_power; 480 channels[j].channel = req->channels[i]->hw_value; 481 482 j++; 483 } 484 } 485 486 return j - start; 487} 488 489static bool 490wl1271_scan_sched_scan_channels(struct wl1271 *wl, 491 struct cfg80211_sched_scan_request *req, 492 struct wl1271_cmd_sched_scan_config *cfg) 493{ 494 cfg->passive[0] = 495 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, 496 IEEE80211_BAND_2GHZ, 497 false, true, 0, 498 MAX_CHANNELS_2GHZ); 499 cfg->active[0] = 500 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, 501 IEEE80211_BAND_2GHZ, 502 false, false, 503 cfg->passive[0], 504 MAX_CHANNELS_2GHZ); 505 cfg->passive[1] = 506 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, 507 IEEE80211_BAND_5GHZ, 508 false, true, 0, 509 MAX_CHANNELS_5GHZ); 510 cfg->dfs = 511 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, 512 IEEE80211_BAND_5GHZ, 513 true, true, 514 cfg->passive[1], 515 MAX_CHANNELS_5GHZ); 516 cfg->active[1] = 517 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, 518 IEEE80211_BAND_5GHZ, 519 false, false, 520 cfg->passive[1] + cfg->dfs, 521 MAX_CHANNELS_5GHZ); 522 /* 802.11j channels are not supported yet */ 523 cfg->passive[2] = 0; 524 cfg->active[2] = 0; 525 526 wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", 527 cfg->active[0], cfg->passive[0]); 528 wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", 529 cfg->active[1], cfg->passive[1]); 530 wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs); 531 532 return cfg->passive[0] || cfg->active[0] || 533 cfg->passive[1] || cfg->active[1] || cfg->dfs || 534 cfg->passive[2] || cfg->active[2]; 535} 536 537/* Returns the scan type to be used or a negative value on error */ 538static int 539wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, 540 struct cfg80211_sched_scan_request *req) 541{ 542 struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; 543 struct cfg80211_match_set *sets = req->match_sets; 544 struct cfg80211_ssid *ssids = req->ssids; 545 int ret = 0, type, i, j, n_match_ssids = 0; 546 547 wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list"); 548 549 /* count the match sets that contain SSIDs */ 550 for (i = 0; i < req->n_match_sets; i++) 551 if (sets[i].ssid.ssid_len > 0) 552 n_match_ssids++; 553 554 /* No filter, no ssids or only bcast ssid */ 555 if (!n_match_ssids && 556 (!req->n_ssids || 557 (req->n_ssids == 1 && req->ssids[0].ssid_len == 0))) { 558 type = SCAN_SSID_FILTER_ANY; 559 goto out; 560 } 561 562 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 563 if (!cmd) { 564 ret = -ENOMEM; 565 goto out; 566 } 567 568 if (!n_match_ssids) { 569 /* No filter, with ssids */ 570 type = SCAN_SSID_FILTER_DISABLED; 571 572 for (i = 0; i < req->n_ssids; i++) { 573 cmd->ssids[cmd->n_ssids].type = (ssids[i].ssid_len) ? 574 SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC; 575 cmd->ssids[cmd->n_ssids].len = ssids[i].ssid_len; 576 memcpy(cmd->ssids[cmd->n_ssids].ssid, ssids[i].ssid, 577 ssids[i].ssid_len); 578 cmd->n_ssids++; 579 } 580 } else { 581 type = SCAN_SSID_FILTER_LIST; 582 583 /* Add all SSIDs from the filters */ 584 for (i = 0; i < req->n_match_sets; i++) { 585 /* ignore sets without SSIDs */ 586 if (!sets[i].ssid.ssid_len) 587 continue; 588 589 cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC; 590 cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len; 591 memcpy(cmd->ssids[cmd->n_ssids].ssid, 592 sets[i].ssid.ssid, sets[i].ssid.ssid_len); 593 cmd->n_ssids++; 594 } 595 if ((req->n_ssids > 1) || 596 (req->n_ssids == 1 && req->ssids[0].ssid_len > 0)) { 597 /* 598 * Mark all the SSIDs passed in the SSID list as HIDDEN, 599 * so they're used in probe requests. 600 */ 601 for (i = 0; i < req->n_ssids; i++) { 602 if (!req->ssids[i].ssid_len) 603 continue; 604 605 for (j = 0; j < cmd->n_ssids; j++) 606 if (!memcmp(req->ssids[i].ssid, 607 cmd->ssids[j].ssid, 608 req->ssids[i].ssid_len)) { 609 cmd->ssids[j].type = 610 SCAN_SSID_TYPE_HIDDEN; 611 break; 612 } 613 /* Fail if SSID isn't present in the filters */ 614 if (j == cmd->n_ssids) { 615 ret = -EINVAL; 616 goto out_free; 617 } 618 } 619 } 620 } 621 622 wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd)); 623 624 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd, 625 sizeof(*cmd), 0); 626 if (ret < 0) { 627 wl1271_error("cmd sched scan ssid list failed"); 628 goto out_free; 629 } 630 631out_free: 632 kfree(cmd); 633out: 634 if (ret < 0) 635 return ret; 636 return type; 637} 638 639int wl1271_scan_sched_scan_config(struct wl1271 *wl, 640 struct wl12xx_vif *wlvif, 641 struct cfg80211_sched_scan_request *req, 642 struct ieee80211_sched_scan_ies *ies) 643{ 644 struct wl1271_cmd_sched_scan_config *cfg = NULL; 645 struct conf_sched_scan_settings *c = &wl->conf.sched_scan; 646 int i, ret; 647 bool force_passive = !req->n_ssids; 648 649 wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); 650 651 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 652 if (!cfg) 653 return -ENOMEM; 654 655 cfg->rssi_threshold = c->rssi_threshold; 656 cfg->snr_threshold = c->snr_threshold; 657 cfg->n_probe_reqs = c->num_probe_reqs; 658 /* cycles set to 0 it means infinite (until manually stopped) */ 659 cfg->cycles = 0; 660 /* report APs when at least 1 is found */ 661 cfg->report_after = 1; 662 /* don't stop scanning automatically when something is found */ 663 cfg->terminate = 0; 664 cfg->tag = WL1271_SCAN_DEFAULT_TAG; 665 /* don't filter on BSS type */ 666 cfg->bss_type = SCAN_BSS_TYPE_ANY; 667 /* currently NL80211 supports only a single interval */ 668 for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) 669 cfg->intervals[i] = cpu_to_le32(req->interval); 670 671 cfg->ssid_len = 0; 672 ret = wl12xx_scan_sched_scan_ssid_list(wl, req); 673 if (ret < 0) 674 goto out; 675 676 cfg->filter_type = ret; 677 678 wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type); 679 680 if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { 681 wl1271_error("scan channel list is empty"); 682 ret = -EINVAL; 683 goto out; 684 } 685 686 if (!force_passive && cfg->active[0]) { 687 u8 band = IEEE80211_BAND_2GHZ; 688 ret = wl12xx_cmd_build_probe_req(wl, wlvif, 689 wlvif->dev_role_id, band, 690 req->ssids[0].ssid, 691 req->ssids[0].ssid_len, 692 ies->ie[band], 693 ies->len[band]); 694 if (ret < 0) { 695 wl1271_error("2.4GHz PROBE request template failed"); 696 goto out; 697 } 698 } 699 700 if (!force_passive && cfg->active[1]) { 701 u8 band = IEEE80211_BAND_5GHZ; 702 ret = wl12xx_cmd_build_probe_req(wl, wlvif, 703 wlvif->dev_role_id, band, 704 req->ssids[0].ssid, 705 req->ssids[0].ssid_len, 706 ies->ie[band], 707 ies->len[band]); 708 if (ret < 0) { 709 wl1271_error("5GHz PROBE request template failed"); 710 goto out; 711 } 712 } 713 714 wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg)); 715 716 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg, 717 sizeof(*cfg), 0); 718 if (ret < 0) { 719 wl1271_error("SCAN configuration failed"); 720 goto out; 721 } 722out: 723 kfree(cfg); 724 return ret; 725} 726 727int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) 728{ 729 struct wl1271_cmd_sched_scan_start *start; 730 int ret = 0; 731 732 wl1271_debug(DEBUG_CMD, "cmd periodic scan start"); 733 734 if (wlvif->bss_type != BSS_TYPE_STA_BSS) 735 return -EOPNOTSUPP; 736 737 if (test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) 738 return -EBUSY; 739 740 start = kzalloc(sizeof(*start), GFP_KERNEL); 741 if (!start) 742 return -ENOMEM; 743 744 start->tag = WL1271_SCAN_DEFAULT_TAG; 745 746 ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start, 747 sizeof(*start), 0); 748 if (ret < 0) { 749 wl1271_error("failed to send scan start command"); 750 goto out_free; 751 } 752 753out_free: 754 kfree(start); 755 return ret; 756} 757 758void wl1271_scan_sched_scan_results(struct wl1271 *wl) 759{ 760 wl1271_debug(DEBUG_SCAN, "got periodic scan results"); 761 762 ieee80211_sched_scan_results(wl->hw); 763} 764 765void wl1271_scan_sched_scan_stop(struct wl1271 *wl) 766{ 767 struct wl1271_cmd_sched_scan_stop *stop; 768 int ret = 0; 769 770 wl1271_debug(DEBUG_CMD, "cmd periodic scan stop"); 771 772 /* FIXME: what to do if alloc'ing to stop fails? */ 773 stop = kzalloc(sizeof(*stop), GFP_KERNEL); 774 if (!stop) { 775 wl1271_error("failed to alloc memory to send sched scan stop"); 776 return; 777 } 778 779 stop->tag = WL1271_SCAN_DEFAULT_TAG; 780 781 ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop, 782 sizeof(*stop), 0); 783 if (ret < 0) { 784 wl1271_error("failed to send sched scan stop command"); 785 goto out_free; 786 } 787 788out_free: 789 kfree(stop); 790} 791