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 #include <linux/pm_runtime.h> 26 27 #include "wlcore.h" 28 #include "debug.h" 29 #include "cmd.h" 30 #include "scan.h" 31 #include "acx.h" 32 #include "tx.h" 33 34 void wl1271_scan_complete_work(struct work_struct *work) 35 { 36 struct delayed_work *dwork; 37 struct wl1271 *wl; 38 struct wl12xx_vif *wlvif; 39 struct cfg80211_scan_info info = { 40 .aborted = false, 41 }; 42 int ret; 43 44 dwork = to_delayed_work(work); 45 wl = container_of(dwork, struct wl1271, scan_complete_work); 46 47 wl1271_debug(DEBUG_SCAN, "Scanning complete"); 48 49 mutex_lock(&wl->mutex); 50 51 if (unlikely(wl->state != WLCORE_STATE_ON)) 52 goto out; 53 54 if (wl->scan.state == WL1271_SCAN_STATE_IDLE) 55 goto out; 56 57 wlvif = wl->scan_wlvif; 58 59 /* 60 * Rearm the tx watchdog just before idling scan. This 61 * prevents just-finished scans from triggering the watchdog 62 */ 63 wl12xx_rearm_tx_watchdog_locked(wl); 64 65 wl->scan.state = WL1271_SCAN_STATE_IDLE; 66 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 67 wl->scan.req = NULL; 68 wl->scan_wlvif = NULL; 69 70 ret = pm_runtime_get_sync(wl->dev); 71 if (ret < 0) { 72 pm_runtime_put_noidle(wl->dev); 73 goto out; 74 } 75 76 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { 77 /* restore hardware connection monitoring template */ 78 wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq); 79 } 80 81 if (wl->scan.failed) { 82 wl1271_info("Scan completed due to error."); 83 wl12xx_queue_recovery_work(wl); 84 } 85 86 wlcore_cmd_regdomain_config_locked(wl); 87 88 pm_runtime_mark_last_busy(wl->dev); 89 pm_runtime_put_autosuspend(wl->dev); 90 91 ieee80211_scan_completed(wl->hw, &info); 92 93 out: 94 mutex_unlock(&wl->mutex); 95 96 } 97 98 static void wlcore_started_vifs_iter(void *data, u8 *mac, 99 struct ieee80211_vif *vif) 100 { 101 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 102 bool active = false; 103 int *count = (int *)data; 104 105 /* 106 * count active interfaces according to interface type. 107 * checking only bss_conf.idle is bad for some cases, e.g. 108 * we don't want to count sta in p2p_find as active interface. 109 */ 110 switch (wlvif->bss_type) { 111 case BSS_TYPE_STA_BSS: 112 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 113 active = true; 114 break; 115 116 case BSS_TYPE_AP_BSS: 117 if (wlvif->wl->active_sta_count > 0) 118 active = true; 119 break; 120 121 default: 122 break; 123 } 124 125 if (active) 126 (*count)++; 127 } 128 129 static int wlcore_count_started_vifs(struct wl1271 *wl) 130 { 131 int count = 0; 132 133 ieee80211_iterate_active_interfaces_atomic(wl->hw, 134 IEEE80211_IFACE_ITER_RESUME_ALL, 135 wlcore_started_vifs_iter, &count); 136 return count; 137 } 138 139 static int 140 wlcore_scan_get_channels(struct wl1271 *wl, 141 struct ieee80211_channel *req_channels[], 142 u32 n_channels, 143 u32 n_ssids, 144 struct conn_scan_ch_params *channels, 145 u32 band, bool radar, bool passive, 146 int start, int max_channels, 147 u8 *n_pactive_ch, 148 int scan_type) 149 { 150 int i, j; 151 u32 flags; 152 bool force_passive = !n_ssids; 153 u32 min_dwell_time_active, max_dwell_time_active; 154 u32 dwell_time_passive, dwell_time_dfs; 155 156 /* configure dwell times according to scan type */ 157 if (scan_type == SCAN_TYPE_SEARCH) { 158 struct conf_scan_settings *c = &wl->conf.scan; 159 bool active_vif_exists = !!wlcore_count_started_vifs(wl); 160 161 min_dwell_time_active = active_vif_exists ? 162 c->min_dwell_time_active : 163 c->min_dwell_time_active_long; 164 max_dwell_time_active = active_vif_exists ? 165 c->max_dwell_time_active : 166 c->max_dwell_time_active_long; 167 dwell_time_passive = c->dwell_time_passive; 168 dwell_time_dfs = c->dwell_time_dfs; 169 } else { 170 struct conf_sched_scan_settings *c = &wl->conf.sched_scan; 171 u32 delta_per_probe; 172 173 if (band == NL80211_BAND_5GHZ) 174 delta_per_probe = c->dwell_time_delta_per_probe_5; 175 else 176 delta_per_probe = c->dwell_time_delta_per_probe; 177 178 min_dwell_time_active = c->base_dwell_time + 179 n_ssids * c->num_probe_reqs * delta_per_probe; 180 181 max_dwell_time_active = min_dwell_time_active + 182 c->max_dwell_time_delta; 183 dwell_time_passive = c->dwell_time_passive; 184 dwell_time_dfs = c->dwell_time_dfs; 185 } 186 min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000); 187 max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000); 188 dwell_time_passive = DIV_ROUND_UP(dwell_time_passive, 1000); 189 dwell_time_dfs = DIV_ROUND_UP(dwell_time_dfs, 1000); 190 191 for (i = 0, j = start; 192 i < n_channels && j < max_channels; 193 i++) { 194 flags = req_channels[i]->flags; 195 196 if (force_passive) 197 flags |= IEEE80211_CHAN_NO_IR; 198 199 if ((req_channels[i]->band == band) && 200 !(flags & IEEE80211_CHAN_DISABLED) && 201 (!!(flags & IEEE80211_CHAN_RADAR) == radar) && 202 /* if radar is set, we ignore the passive flag */ 203 (radar || 204 !!(flags & IEEE80211_CHAN_NO_IR) == passive)) { 205 if (flags & IEEE80211_CHAN_RADAR) { 206 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 207 208 channels[j].passive_duration = 209 cpu_to_le16(dwell_time_dfs); 210 } else { 211 channels[j].passive_duration = 212 cpu_to_le16(dwell_time_passive); 213 } 214 215 channels[j].min_duration = 216 cpu_to_le16(min_dwell_time_active); 217 channels[j].max_duration = 218 cpu_to_le16(max_dwell_time_active); 219 220 channels[j].tx_power_att = req_channels[i]->max_power; 221 channels[j].channel = req_channels[i]->hw_value; 222 223 if (n_pactive_ch && 224 (band == NL80211_BAND_2GHZ) && 225 (channels[j].channel >= 12) && 226 (channels[j].channel <= 14) && 227 (flags & IEEE80211_CHAN_NO_IR) && 228 !force_passive) { 229 /* pactive channels treated as DFS */ 230 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; 231 232 /* 233 * n_pactive_ch is counted down from the end of 234 * the passive channel list 235 */ 236 (*n_pactive_ch)++; 237 wl1271_debug(DEBUG_SCAN, "n_pactive_ch = %d", 238 *n_pactive_ch); 239 } 240 241 wl1271_debug(DEBUG_SCAN, "freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s", 242 req_channels[i]->center_freq, 243 req_channels[i]->hw_value, 244 req_channels[i]->flags, 245 req_channels[i]->max_power, 246 min_dwell_time_active, 247 max_dwell_time_active, 248 flags & IEEE80211_CHAN_RADAR ? 249 ", DFS" : "", 250 flags & IEEE80211_CHAN_NO_IR ? 251 ", NO-IR" : ""); 252 j++; 253 } 254 } 255 256 return j - start; 257 } 258 259 bool 260 wlcore_set_scan_chan_params(struct wl1271 *wl, 261 struct wlcore_scan_channels *cfg, 262 struct ieee80211_channel *channels[], 263 u32 n_channels, 264 u32 n_ssids, 265 int scan_type) 266 { 267 u8 n_pactive_ch = 0; 268 269 cfg->passive[0] = 270 wlcore_scan_get_channels(wl, 271 channels, 272 n_channels, 273 n_ssids, 274 cfg->channels_2, 275 NL80211_BAND_2GHZ, 276 false, true, 0, 277 MAX_CHANNELS_2GHZ, 278 &n_pactive_ch, 279 scan_type); 280 cfg->active[0] = 281 wlcore_scan_get_channels(wl, 282 channels, 283 n_channels, 284 n_ssids, 285 cfg->channels_2, 286 NL80211_BAND_2GHZ, 287 false, false, 288 cfg->passive[0], 289 MAX_CHANNELS_2GHZ, 290 &n_pactive_ch, 291 scan_type); 292 cfg->passive[1] = 293 wlcore_scan_get_channels(wl, 294 channels, 295 n_channels, 296 n_ssids, 297 cfg->channels_5, 298 NL80211_BAND_5GHZ, 299 false, true, 0, 300 wl->max_channels_5, 301 &n_pactive_ch, 302 scan_type); 303 cfg->dfs = 304 wlcore_scan_get_channels(wl, 305 channels, 306 n_channels, 307 n_ssids, 308 cfg->channels_5, 309 NL80211_BAND_5GHZ, 310 true, true, 311 cfg->passive[1], 312 wl->max_channels_5, 313 &n_pactive_ch, 314 scan_type); 315 cfg->active[1] = 316 wlcore_scan_get_channels(wl, 317 channels, 318 n_channels, 319 n_ssids, 320 cfg->channels_5, 321 NL80211_BAND_5GHZ, 322 false, false, 323 cfg->passive[1] + cfg->dfs, 324 wl->max_channels_5, 325 &n_pactive_ch, 326 scan_type); 327 328 /* 802.11j channels are not supported yet */ 329 cfg->passive[2] = 0; 330 cfg->active[2] = 0; 331 332 cfg->passive_active = n_pactive_ch; 333 334 wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", 335 cfg->active[0], cfg->passive[0]); 336 wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", 337 cfg->active[1], cfg->passive[1]); 338 wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs); 339 340 return cfg->passive[0] || cfg->active[0] || 341 cfg->passive[1] || cfg->active[1] || cfg->dfs || 342 cfg->passive[2] || cfg->active[2]; 343 } 344 EXPORT_SYMBOL_GPL(wlcore_set_scan_chan_params); 345 346 int wlcore_scan(struct wl1271 *wl, struct ieee80211_vif *vif, 347 const u8 *ssid, size_t ssid_len, 348 struct cfg80211_scan_request *req) 349 { 350 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 351 352 /* 353 * cfg80211 should guarantee that we don't get more channels 354 * than what we have registered. 355 */ 356 BUG_ON(req->n_channels > WL1271_MAX_CHANNELS); 357 358 if (wl->scan.state != WL1271_SCAN_STATE_IDLE) 359 return -EBUSY; 360 361 wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; 362 363 if (ssid_len && ssid) { 364 wl->scan.ssid_len = ssid_len; 365 memcpy(wl->scan.ssid, ssid, ssid_len); 366 } else { 367 wl->scan.ssid_len = 0; 368 } 369 370 wl->scan_wlvif = wlvif; 371 wl->scan.req = req; 372 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 373 374 /* we assume failure so that timeout scenarios are handled correctly */ 375 wl->scan.failed = true; 376 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, 377 msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); 378 379 wl->ops->scan_start(wl, wlvif, req); 380 381 return 0; 382 } 383 /* Returns the scan type to be used or a negative value on error */ 384 int 385 wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl, 386 struct wl12xx_vif *wlvif, 387 struct cfg80211_sched_scan_request *req) 388 { 389 struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; 390 struct cfg80211_match_set *sets = req->match_sets; 391 struct cfg80211_ssid *ssids = req->ssids; 392 int ret = 0, type, i, j, n_match_ssids = 0; 393 394 wl1271_debug((DEBUG_CMD | DEBUG_SCAN), "cmd sched scan ssid list"); 395 396 /* count the match sets that contain SSIDs */ 397 for (i = 0; i < req->n_match_sets; i++) 398 if (sets[i].ssid.ssid_len > 0) 399 n_match_ssids++; 400 401 /* No filter, no ssids or only bcast ssid */ 402 if (!n_match_ssids && 403 (!req->n_ssids || 404 (req->n_ssids == 1 && req->ssids[0].ssid_len == 0))) { 405 type = SCAN_SSID_FILTER_ANY; 406 goto out; 407 } 408 409 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 410 if (!cmd) { 411 ret = -ENOMEM; 412 goto out; 413 } 414 415 cmd->role_id = wlvif->role_id; 416 if (!n_match_ssids) { 417 /* No filter, with ssids */ 418 type = SCAN_SSID_FILTER_DISABLED; 419 420 for (i = 0; i < req->n_ssids; i++) { 421 cmd->ssids[cmd->n_ssids].type = (ssids[i].ssid_len) ? 422 SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC; 423 cmd->ssids[cmd->n_ssids].len = ssids[i].ssid_len; 424 memcpy(cmd->ssids[cmd->n_ssids].ssid, ssids[i].ssid, 425 ssids[i].ssid_len); 426 cmd->n_ssids++; 427 } 428 } else { 429 type = SCAN_SSID_FILTER_LIST; 430 431 /* Add all SSIDs from the filters */ 432 for (i = 0; i < req->n_match_sets; i++) { 433 /* ignore sets without SSIDs */ 434 if (!sets[i].ssid.ssid_len) 435 continue; 436 437 cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC; 438 cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len; 439 memcpy(cmd->ssids[cmd->n_ssids].ssid, 440 sets[i].ssid.ssid, sets[i].ssid.ssid_len); 441 cmd->n_ssids++; 442 } 443 if ((req->n_ssids > 1) || 444 (req->n_ssids == 1 && req->ssids[0].ssid_len > 0)) { 445 /* 446 * Mark all the SSIDs passed in the SSID list as HIDDEN, 447 * so they're used in probe requests. 448 */ 449 for (i = 0; i < req->n_ssids; i++) { 450 if (!req->ssids[i].ssid_len) 451 continue; 452 453 for (j = 0; j < cmd->n_ssids; j++) 454 if ((req->ssids[i].ssid_len == 455 cmd->ssids[j].len) && 456 !memcmp(req->ssids[i].ssid, 457 cmd->ssids[j].ssid, 458 req->ssids[i].ssid_len)) { 459 cmd->ssids[j].type = 460 SCAN_SSID_TYPE_HIDDEN; 461 break; 462 } 463 /* Fail if SSID isn't present in the filters */ 464 if (j == cmd->n_ssids) { 465 ret = -EINVAL; 466 goto out_free; 467 } 468 } 469 } 470 } 471 472 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd, 473 sizeof(*cmd), 0); 474 if (ret < 0) { 475 wl1271_error("cmd sched scan ssid list failed"); 476 goto out_free; 477 } 478 479 out_free: 480 kfree(cmd); 481 out: 482 if (ret < 0) 483 return ret; 484 return type; 485 } 486 EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_ssid_list); 487 488 void wlcore_scan_sched_scan_results(struct wl1271 *wl) 489 { 490 wl1271_debug(DEBUG_SCAN, "got periodic scan results"); 491 492 ieee80211_sched_scan_results(wl->hw); 493 } 494 EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_results); 495