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 34void 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 87out: 88 mutex_unlock(&wl->mutex); 89 90} 91 92static 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 123static 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 133static int 134wlcore_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_NO_IR; 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_NO_IR) == passive)) { 199 if (flags & IEEE80211_CHAN_RADAR) { 200 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 201 202 channels[j].passive_duration = 203 cpu_to_le16(dwell_time_dfs); 204 } else { 205 channels[j].passive_duration = 206 cpu_to_le16(dwell_time_passive); 207 } 208 209 channels[j].min_duration = 210 cpu_to_le16(min_dwell_time_active); 211 channels[j].max_duration = 212 cpu_to_le16(max_dwell_time_active); 213 214 channels[j].tx_power_att = req_channels[i]->max_power; 215 channels[j].channel = req_channels[i]->hw_value; 216 217 if (n_pactive_ch && 218 (band == IEEE80211_BAND_2GHZ) && 219 (channels[j].channel >= 12) && 220 (channels[j].channel <= 14) && 221 (flags & IEEE80211_CHAN_NO_IR) && 222 !force_passive) { 223 /* pactive channels treated as DFS */ 224 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; 225 226 /* 227 * n_pactive_ch is counted down from the end of 228 * the passive channel list 229 */ 230 (*n_pactive_ch)++; 231 wl1271_debug(DEBUG_SCAN, "n_pactive_ch = %d", 232 *n_pactive_ch); 233 } 234 235 wl1271_debug(DEBUG_SCAN, "freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s", 236 req_channels[i]->center_freq, 237 req_channels[i]->hw_value, 238 req_channels[i]->flags, 239 req_channels[i]->max_power, 240 min_dwell_time_active, 241 max_dwell_time_active, 242 flags & IEEE80211_CHAN_RADAR ? 243 ", DFS" : "", 244 flags & IEEE80211_CHAN_NO_IR ? 245 ", NO-IR" : ""); 246 j++; 247 } 248 } 249 250 return j - start; 251} 252 253bool 254wlcore_set_scan_chan_params(struct wl1271 *wl, 255 struct wlcore_scan_channels *cfg, 256 struct ieee80211_channel *channels[], 257 u32 n_channels, 258 u32 n_ssids, 259 int scan_type) 260{ 261 u8 n_pactive_ch = 0; 262 263 cfg->passive[0] = 264 wlcore_scan_get_channels(wl, 265 channels, 266 n_channels, 267 n_ssids, 268 cfg->channels_2, 269 IEEE80211_BAND_2GHZ, 270 false, true, 0, 271 MAX_CHANNELS_2GHZ, 272 &n_pactive_ch, 273 scan_type); 274 cfg->active[0] = 275 wlcore_scan_get_channels(wl, 276 channels, 277 n_channels, 278 n_ssids, 279 cfg->channels_2, 280 IEEE80211_BAND_2GHZ, 281 false, false, 282 cfg->passive[0], 283 MAX_CHANNELS_2GHZ, 284 &n_pactive_ch, 285 scan_type); 286 cfg->passive[1] = 287 wlcore_scan_get_channels(wl, 288 channels, 289 n_channels, 290 n_ssids, 291 cfg->channels_5, 292 IEEE80211_BAND_5GHZ, 293 false, true, 0, 294 wl->max_channels_5, 295 &n_pactive_ch, 296 scan_type); 297 cfg->dfs = 298 wlcore_scan_get_channels(wl, 299 channels, 300 n_channels, 301 n_ssids, 302 cfg->channels_5, 303 IEEE80211_BAND_5GHZ, 304 true, true, 305 cfg->passive[1], 306 wl->max_channels_5, 307 &n_pactive_ch, 308 scan_type); 309 cfg->active[1] = 310 wlcore_scan_get_channels(wl, 311 channels, 312 n_channels, 313 n_ssids, 314 cfg->channels_5, 315 IEEE80211_BAND_5GHZ, 316 false, false, 317 cfg->passive[1] + cfg->dfs, 318 wl->max_channels_5, 319 &n_pactive_ch, 320 scan_type); 321 322 /* 802.11j channels are not supported yet */ 323 cfg->passive[2] = 0; 324 cfg->active[2] = 0; 325 326 cfg->passive_active = n_pactive_ch; 327 328 wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", 329 cfg->active[0], cfg->passive[0]); 330 wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", 331 cfg->active[1], cfg->passive[1]); 332 wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs); 333 334 return cfg->passive[0] || cfg->active[0] || 335 cfg->passive[1] || cfg->active[1] || cfg->dfs || 336 cfg->passive[2] || cfg->active[2]; 337} 338EXPORT_SYMBOL_GPL(wlcore_set_scan_chan_params); 339 340int wlcore_scan(struct wl1271 *wl, struct ieee80211_vif *vif, 341 const u8 *ssid, size_t ssid_len, 342 struct cfg80211_scan_request *req) 343{ 344 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 345 346 /* 347 * cfg80211 should guarantee that we don't get more channels 348 * than what we have registered. 349 */ 350 BUG_ON(req->n_channels > WL1271_MAX_CHANNELS); 351 352 if (wl->scan.state != WL1271_SCAN_STATE_IDLE) 353 return -EBUSY; 354 355 wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; 356 357 if (ssid_len && ssid) { 358 wl->scan.ssid_len = ssid_len; 359 memcpy(wl->scan.ssid, ssid, ssid_len); 360 } else { 361 wl->scan.ssid_len = 0; 362 } 363 364 wl->scan_wlvif = wlvif; 365 wl->scan.req = req; 366 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 367 368 /* we assume failure so that timeout scenarios are handled correctly */ 369 wl->scan.failed = true; 370 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, 371 msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); 372 373 wl->ops->scan_start(wl, wlvif, req); 374 375 return 0; 376} 377/* Returns the scan type to be used or a negative value on error */ 378int 379wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl, 380 struct wl12xx_vif *wlvif, 381 struct cfg80211_sched_scan_request *req) 382{ 383 struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; 384 struct cfg80211_match_set *sets = req->match_sets; 385 struct cfg80211_ssid *ssids = req->ssids; 386 int ret = 0, type, i, j, n_match_ssids = 0; 387 388 wl1271_debug((DEBUG_CMD | DEBUG_SCAN), "cmd sched scan ssid list"); 389 390 /* count the match sets that contain SSIDs */ 391 for (i = 0; i < req->n_match_sets; i++) 392 if (sets[i].ssid.ssid_len > 0) 393 n_match_ssids++; 394 395 /* No filter, no ssids or only bcast ssid */ 396 if (!n_match_ssids && 397 (!req->n_ssids || 398 (req->n_ssids == 1 && req->ssids[0].ssid_len == 0))) { 399 type = SCAN_SSID_FILTER_ANY; 400 goto out; 401 } 402 403 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 404 if (!cmd) { 405 ret = -ENOMEM; 406 goto out; 407 } 408 409 cmd->role_id = wlvif->role_id; 410 if (!n_match_ssids) { 411 /* No filter, with ssids */ 412 type = SCAN_SSID_FILTER_DISABLED; 413 414 for (i = 0; i < req->n_ssids; i++) { 415 cmd->ssids[cmd->n_ssids].type = (ssids[i].ssid_len) ? 416 SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC; 417 cmd->ssids[cmd->n_ssids].len = ssids[i].ssid_len; 418 memcpy(cmd->ssids[cmd->n_ssids].ssid, ssids[i].ssid, 419 ssids[i].ssid_len); 420 cmd->n_ssids++; 421 } 422 } else { 423 type = SCAN_SSID_FILTER_LIST; 424 425 /* Add all SSIDs from the filters */ 426 for (i = 0; i < req->n_match_sets; i++) { 427 /* ignore sets without SSIDs */ 428 if (!sets[i].ssid.ssid_len) 429 continue; 430 431 cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC; 432 cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len; 433 memcpy(cmd->ssids[cmd->n_ssids].ssid, 434 sets[i].ssid.ssid, sets[i].ssid.ssid_len); 435 cmd->n_ssids++; 436 } 437 if ((req->n_ssids > 1) || 438 (req->n_ssids == 1 && req->ssids[0].ssid_len > 0)) { 439 /* 440 * Mark all the SSIDs passed in the SSID list as HIDDEN, 441 * so they're used in probe requests. 442 */ 443 for (i = 0; i < req->n_ssids; i++) { 444 if (!req->ssids[i].ssid_len) 445 continue; 446 447 for (j = 0; j < cmd->n_ssids; j++) 448 if ((req->ssids[i].ssid_len == 449 cmd->ssids[j].len) && 450 !memcmp(req->ssids[i].ssid, 451 cmd->ssids[j].ssid, 452 req->ssids[i].ssid_len)) { 453 cmd->ssids[j].type = 454 SCAN_SSID_TYPE_HIDDEN; 455 break; 456 } 457 /* Fail if SSID isn't present in the filters */ 458 if (j == cmd->n_ssids) { 459 ret = -EINVAL; 460 goto out_free; 461 } 462 } 463 } 464 } 465 466 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd, 467 sizeof(*cmd), 0); 468 if (ret < 0) { 469 wl1271_error("cmd sched scan ssid list failed"); 470 goto out_free; 471 } 472 473out_free: 474 kfree(cmd); 475out: 476 if (ret < 0) 477 return ret; 478 return type; 479} 480EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_ssid_list); 481 482void wlcore_scan_sched_scan_results(struct wl1271 *wl) 483{ 484 wl1271_debug(DEBUG_SCAN, "got periodic scan results"); 485 486 ieee80211_sched_scan_results(wl->hw); 487} 488EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_results); 489