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