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