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