1/****************************************************************************** 2 * 3 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * redistributing this file, you may do so under either license. 5 * 6 * GPL LICENSE SUMMARY 7 * 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 23 * USA 24 * 25 * The full GNU General Public License is included in this distribution 26 * in the file called COPYING. 27 * 28 * Contact Information: 29 * Intel Linux Wireless <ilw@linux.intel.com> 30 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 31 * 32 * BSD LICENSE 33 * 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 42 * * Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * * Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in 46 * the documentation and/or other materials provided with the 47 * distribution. 48 * * Neither the name Intel Corporation nor the names of its 49 * contributors may be used to endorse or promote products derived 50 * from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 53 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 54 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 55 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 56 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 57 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 58 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 62 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63 * 64 *****************************************************************************/ 65 66#include <linux/etherdevice.h> 67#include <net/mac80211.h> 68 69#include "mvm.h" 70#include "iwl-eeprom-parse.h" 71#include "fw-api-scan.h" 72 73#define IWL_PLCP_QUIET_THRESH 1 74#define IWL_ACTIVE_QUIET_TIME 10 75#define IWL_DENSE_EBS_SCAN_RATIO 5 76#define IWL_SPARSE_EBS_SCAN_RATIO 1 77 78struct iwl_mvm_scan_params { 79 u32 max_out_time; 80 u32 suspend_time; 81 bool passive_fragmented; 82 struct _dwell { 83 u16 passive; 84 u16 active; 85 u16 fragmented; 86 } dwell[IEEE80211_NUM_BANDS]; 87}; 88 89enum iwl_umac_scan_uid_type { 90 IWL_UMAC_SCAN_UID_REG_SCAN = BIT(0), 91 IWL_UMAC_SCAN_UID_SCHED_SCAN = BIT(1), 92 IWL_UMAC_SCAN_UID_ALL = IWL_UMAC_SCAN_UID_REG_SCAN | 93 IWL_UMAC_SCAN_UID_SCHED_SCAN, 94}; 95 96static int iwl_umac_scan_stop(struct iwl_mvm *mvm, 97 enum iwl_umac_scan_uid_type type, bool notify); 98 99static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm) 100{ 101 if (mvm->scan_rx_ant != ANT_NONE) 102 return mvm->scan_rx_ant; 103 return iwl_mvm_get_valid_rx_ant(mvm); 104} 105 106static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 107{ 108 u16 rx_chain; 109 u8 rx_ant; 110 111 rx_ant = iwl_mvm_scan_rx_ant(mvm); 112 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; 113 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; 114 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS; 115 rx_chain |= 0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS; 116 return cpu_to_le16(rx_chain); 117} 118 119static __le32 iwl_mvm_scan_rxon_flags(enum ieee80211_band band) 120{ 121 if (band == IEEE80211_BAND_2GHZ) 122 return cpu_to_le32(PHY_BAND_24); 123 else 124 return cpu_to_le32(PHY_BAND_5); 125} 126 127static inline __le32 128iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band, 129 bool no_cck) 130{ 131 u32 tx_ant; 132 133 mvm->scan_last_antenna_idx = 134 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm), 135 mvm->scan_last_antenna_idx); 136 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; 137 138 if (band == IEEE80211_BAND_2GHZ && !no_cck) 139 return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK | 140 tx_ant); 141 else 142 return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant); 143} 144 145/* 146 * We insert the SSIDs in an inverted order, because the FW will 147 * invert it back. The most prioritized SSID, which is first in the 148 * request list, is not copied here, but inserted directly to the probe 149 * request. 150 */ 151static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid, 152 struct cfg80211_ssid *ssids, 153 int n_ssids, int first) 154{ 155 int fw_idx, req_idx; 156 157 for (req_idx = n_ssids - 1, fw_idx = 0; req_idx >= first; 158 req_idx--, fw_idx++) { 159 cmd_ssid[fw_idx].id = WLAN_EID_SSID; 160 cmd_ssid[fw_idx].len = ssids[req_idx].ssid_len; 161 memcpy(cmd_ssid[fw_idx].ssid, 162 ssids[req_idx].ssid, 163 ssids[req_idx].ssid_len); 164 } 165} 166 167/* 168 * If req->n_ssids > 0, it means we should do an active scan. 169 * In case of active scan w/o directed scan, we receive a zero-length SSID 170 * just to notify that this scan is active and not passive. 171 * In order to notify the FW of the number of SSIDs we wish to scan (including 172 * the zero-length one), we need to set the corresponding bits in chan->type, 173 * one for each SSID, and set the active bit (first). If the first SSID is 174 * already included in the probe template, so we need to set only 175 * req->n_ssids - 1 bits in addition to the first bit. 176 */ 177static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm, 178 enum ieee80211_band band, int n_ssids) 179{ 180 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) 181 return 10; 182 if (band == IEEE80211_BAND_2GHZ) 183 return 20 + 3 * (n_ssids + 1); 184 return 10 + 2 * (n_ssids + 1); 185} 186 187static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm, 188 enum ieee80211_band band) 189{ 190 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) 191 return 110; 192 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 193} 194 195static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, 196 struct ieee80211_vif *vif) 197{ 198 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 199 int *global_cnt = data; 200 201 if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt && 202 mvmvif->phy_ctxt->id < MAX_PHYS) 203 *global_cnt += 1; 204} 205 206static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, 207 struct ieee80211_vif *vif, 208 int n_ssids, u32 flags, 209 struct iwl_mvm_scan_params *params) 210{ 211 int global_cnt = 0; 212 enum ieee80211_band band; 213 u8 frag_passive_dwell = 0; 214 215 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 216 IEEE80211_IFACE_ITER_NORMAL, 217 iwl_mvm_scan_condition_iterator, 218 &global_cnt); 219 220 if (!global_cnt) 221 goto not_bound; 222 223 params->suspend_time = 30; 224 params->max_out_time = 120; 225 226 if (iwl_mvm_low_latency(mvm)) { 227 if (mvm->fw->ucode_capa.api[0] & 228 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { 229 params->suspend_time = 105; 230 /* 231 * If there is more than one active interface make 232 * passive scan more fragmented. 233 */ 234 frag_passive_dwell = 40; 235 params->max_out_time = frag_passive_dwell; 236 } else { 237 params->suspend_time = 120; 238 params->max_out_time = 120; 239 } 240 } 241 242 if (frag_passive_dwell && (mvm->fw->ucode_capa.api[0] & 243 IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) { 244 /* 245 * P2P device scan should not be fragmented to avoid negative 246 * impact on P2P device discovery. Configure max_out_time to be 247 * equal to dwell time on passive channel. Take a longest 248 * possible value, one that corresponds to 2GHz band 249 */ 250 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 251 u32 passive_dwell = 252 iwl_mvm_get_passive_dwell(mvm, 253 IEEE80211_BAND_2GHZ); 254 params->max_out_time = passive_dwell; 255 } else { 256 params->passive_fragmented = true; 257 } 258 } 259 260 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY) 261 params->max_out_time = 200; 262 263not_bound: 264 265 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 266 if (params->passive_fragmented) 267 params->dwell[band].fragmented = frag_passive_dwell; 268 269 params->dwell[band].passive = iwl_mvm_get_passive_dwell(mvm, 270 band); 271 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band, 272 n_ssids); 273 } 274} 275 276static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm) 277{ 278 /* require rrm scan whenever the fw supports it */ 279 return mvm->fw->ucode_capa.capa[0] & 280 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT; 281} 282 283static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm, 284 bool is_sched_scan) 285{ 286 int max_probe_len; 287 288 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE; 289 290 /* we create the 802.11 header and SSID element */ 291 max_probe_len -= 24 + 2; 292 293 /* DS parameter set element is added on 2.4GHZ band if required */ 294 if (iwl_mvm_rrm_scan_needed(mvm)) 295 max_probe_len -= 3; 296 297 return max_probe_len; 298} 299 300int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan) 301{ 302 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan); 303 304 /* TODO: [BUG] This function should return the maximum allowed size of 305 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs 306 * in the same command. So the correct implementation of this function 307 * is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan 308 * command has only 512 bytes and it would leave us with about 240 309 * bytes for scan IEs, which is clearly not enough. So meanwhile 310 * we will report an incorrect value. This may result in a failure to 311 * issue a scan in unified_scan_lmac and unified_sched_scan_lmac 312 * functions with -ENOBUFS, if a large enough probe will be provided. 313 */ 314 return max_ie_len; 315} 316 317int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 318 struct iwl_rx_cmd_buffer *rxb, 319 struct iwl_device_cmd *cmd) 320{ 321 struct iwl_rx_packet *pkt = rxb_addr(rxb); 322 struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data; 323 324 IWL_DEBUG_SCAN(mvm, 325 "Scan offload iteration complete: status=0x%x scanned channels=%d\n", 326 notif->status, notif->scanned_channels); 327 return 0; 328} 329 330int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, 331 struct iwl_rx_cmd_buffer *rxb, 332 struct iwl_device_cmd *cmd) 333{ 334 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); 335 ieee80211_sched_scan_results(mvm->hw); 336 337 return 0; 338} 339 340int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 341 struct iwl_rx_cmd_buffer *rxb, 342 struct iwl_device_cmd *cmd) 343{ 344 struct iwl_rx_packet *pkt = rxb_addr(rxb); 345 struct iwl_periodic_scan_complete *scan_notif; 346 347 scan_notif = (void *)pkt->data; 348 349 /* scan status must be locked for proper checking */ 350 lockdep_assert_held(&mvm->mutex); 351 352 IWL_DEBUG_SCAN(mvm, 353 "%s completed, status %s, EBS status %s\n", 354 mvm->scan_status == IWL_MVM_SCAN_SCHED ? 355 "Scheduled scan" : "Scan", 356 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? 357 "completed" : "aborted", 358 scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? 359 "success" : "failed"); 360 361 362 /* only call mac80211 completion if the stop was initiated by FW */ 363 if (mvm->scan_status == IWL_MVM_SCAN_SCHED) { 364 mvm->scan_status = IWL_MVM_SCAN_NONE; 365 ieee80211_sched_scan_stopped(mvm->hw); 366 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) { 367 mvm->scan_status = IWL_MVM_SCAN_NONE; 368 ieee80211_scan_completed(mvm->hw, 369 scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED); 370 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 371 } 372 373 if (scan_notif->ebs_status) 374 mvm->last_ebs_successful = false; 375 376 return 0; 377} 378 379static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) 380{ 381 int i; 382 383 for (i = 0; i < PROBE_OPTION_MAX; i++) { 384 if (!ssid_list[i].len) 385 break; 386 if (ssid_list[i].len == ssid_len && 387 !memcmp(ssid_list->ssid, ssid, ssid_len)) 388 return i; 389 } 390 return -1; 391} 392 393static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req, 394 struct iwl_ssid_ie *direct_scan, 395 u32 *ssid_bitmap, bool basic_ssid) 396{ 397 int i, j; 398 int index; 399 400 /* 401 * copy SSIDs from match list. 402 * iwl_config_sched_scan_profiles() uses the order of these ssids to 403 * config match list. 404 */ 405 for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) { 406 /* skip empty SSID matchsets */ 407 if (!req->match_sets[i].ssid.ssid_len) 408 continue; 409 direct_scan[i].id = WLAN_EID_SSID; 410 direct_scan[i].len = req->match_sets[i].ssid.ssid_len; 411 memcpy(direct_scan[i].ssid, req->match_sets[i].ssid.ssid, 412 direct_scan[i].len); 413 } 414 415 /* add SSIDs from scan SSID list */ 416 *ssid_bitmap = 0; 417 for (j = 0; j < req->n_ssids && i < PROBE_OPTION_MAX; j++) { 418 index = iwl_ssid_exist(req->ssids[j].ssid, 419 req->ssids[j].ssid_len, 420 direct_scan); 421 if (index < 0) { 422 if (!req->ssids[j].ssid_len && basic_ssid) 423 continue; 424 direct_scan[i].id = WLAN_EID_SSID; 425 direct_scan[i].len = req->ssids[j].ssid_len; 426 memcpy(direct_scan[i].ssid, req->ssids[j].ssid, 427 direct_scan[i].len); 428 *ssid_bitmap |= BIT(i + 1); 429 i++; 430 } else { 431 *ssid_bitmap |= BIT(index + 1); 432 } 433 } 434} 435 436int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 437 struct cfg80211_sched_scan_request *req) 438{ 439 struct iwl_scan_offload_profile *profile; 440 struct iwl_scan_offload_profile_cfg *profile_cfg; 441 struct iwl_scan_offload_blacklist *blacklist; 442 struct iwl_host_cmd cmd = { 443 .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD, 444 .len[1] = sizeof(*profile_cfg), 445 .dataflags[0] = IWL_HCMD_DFL_NOCOPY, 446 .dataflags[1] = IWL_HCMD_DFL_NOCOPY, 447 }; 448 int blacklist_len; 449 int i; 450 int ret; 451 452 if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES)) 453 return -EIO; 454 455 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL) 456 blacklist_len = IWL_SCAN_SHORT_BLACKLIST_LEN; 457 else 458 blacklist_len = IWL_SCAN_MAX_BLACKLIST_LEN; 459 460 blacklist = kzalloc(sizeof(*blacklist) * blacklist_len, GFP_KERNEL); 461 if (!blacklist) 462 return -ENOMEM; 463 464 profile_cfg = kzalloc(sizeof(*profile_cfg), GFP_KERNEL); 465 if (!profile_cfg) { 466 ret = -ENOMEM; 467 goto free_blacklist; 468 } 469 470 cmd.data[0] = blacklist; 471 cmd.len[0] = sizeof(*blacklist) * blacklist_len; 472 cmd.data[1] = profile_cfg; 473 474 /* No blacklist configuration */ 475 476 profile_cfg->num_profiles = req->n_match_sets; 477 profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; 478 profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; 479 profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; 480 if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) 481 profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; 482 483 for (i = 0; i < req->n_match_sets; i++) { 484 profile = &profile_cfg->profiles[i]; 485 profile->ssid_index = i; 486 /* Support any cipher and auth algorithm */ 487 profile->unicast_cipher = 0xff; 488 profile->auth_alg = 0xff; 489 profile->network_type = IWL_NETWORK_TYPE_ANY; 490 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY; 491 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN; 492 } 493 494 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n"); 495 496 ret = iwl_mvm_send_cmd(mvm, &cmd); 497 kfree(profile_cfg); 498free_blacklist: 499 kfree(blacklist); 500 501 return ret; 502} 503 504static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm, 505 struct cfg80211_sched_scan_request *req) 506{ 507 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { 508 IWL_DEBUG_SCAN(mvm, 509 "Sending scheduled scan with filtering, n_match_sets %d\n", 510 req->n_match_sets); 511 return false; 512 } 513 514 IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n"); 515 return true; 516} 517 518int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 519 struct ieee80211_vif *vif, 520 struct cfg80211_sched_scan_request *req, 521 struct ieee80211_scan_ies *ies) 522{ 523 int ret; 524 525 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 526 ret = iwl_mvm_config_sched_scan_profiles(mvm, req); 527 if (ret) 528 return ret; 529 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); 530 } else { 531 mvm->scan_status = IWL_MVM_SCAN_SCHED; 532 ret = iwl_mvm_config_sched_scan_profiles(mvm, req); 533 if (ret) 534 return ret; 535 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); 536 } 537 538 return ret; 539} 540 541static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm) 542{ 543 int ret; 544 struct iwl_host_cmd cmd = { 545 .id = SCAN_OFFLOAD_ABORT_CMD, 546 }; 547 u32 status; 548 549 /* Exit instantly with error when device is not ready 550 * to receive scan abort command or it does not perform 551 * scheduled scan currently */ 552 if (mvm->scan_status == IWL_MVM_SCAN_NONE) 553 return -EIO; 554 555 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); 556 if (ret) 557 return ret; 558 559 if (status != CAN_ABORT_STATUS) { 560 /* 561 * The scan abort will return 1 for success or 562 * 2 for "failure". A failure condition can be 563 * due to simply not being in an active scan which 564 * can occur if we send the scan abort before the 565 * microcode has notified us that a scan is completed. 566 */ 567 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status); 568 ret = -ENOENT; 569 } 570 571 return ret; 572} 573 574int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) 575{ 576 int ret; 577 struct iwl_notification_wait wait_scan_done; 578 static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, }; 579 bool sched = mvm->scan_status == IWL_MVM_SCAN_SCHED; 580 581 lockdep_assert_held(&mvm->mutex); 582 583 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) 584 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, 585 notify); 586 587 if (mvm->scan_status == IWL_MVM_SCAN_NONE) 588 return 0; 589 590 if (iwl_mvm_is_radio_killed(mvm)) { 591 ret = 0; 592 goto out; 593 } 594 595 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, 596 scan_done_notif, 597 ARRAY_SIZE(scan_done_notif), 598 NULL, NULL); 599 600 ret = iwl_mvm_send_scan_offload_abort(mvm); 601 if (ret) { 602 IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n", 603 sched ? "offloaded " : "", ret); 604 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); 605 goto out; 606 } 607 608 IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n", 609 sched ? "offloaded " : ""); 610 611 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); 612out: 613 /* 614 * Clear the scan status so the next scan requests will succeed. This 615 * also ensures the Rx handler doesn't do anything, as the scan was 616 * stopped from above. Since the rx handler won't do anything now, 617 * we have to release the scan reference here. 618 */ 619 if (mvm->scan_status == IWL_MVM_SCAN_OS) 620 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 621 622 mvm->scan_status = IWL_MVM_SCAN_NONE; 623 624 if (notify) { 625 if (sched) 626 ieee80211_sched_scan_stopped(mvm->hw); 627 else 628 ieee80211_scan_completed(mvm->hw, true); 629 } 630 631 return ret; 632} 633 634static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm, 635 struct iwl_scan_req_tx_cmd *tx_cmd, 636 bool no_cck) 637{ 638 tx_cmd[0].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | 639 TX_CMD_FLG_BT_DIS); 640 tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, 641 IEEE80211_BAND_2GHZ, 642 no_cck); 643 tx_cmd[0].sta_id = mvm->aux_sta.sta_id; 644 645 tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | 646 TX_CMD_FLG_BT_DIS); 647 tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, 648 IEEE80211_BAND_5GHZ, 649 no_cck); 650 tx_cmd[1].sta_id = mvm->aux_sta.sta_id; 651} 652 653static void 654iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm, 655 struct ieee80211_channel **channels, 656 int n_channels, u32 ssid_bitmap, 657 struct iwl_scan_req_unified_lmac *cmd) 658{ 659 struct iwl_scan_channel_cfg_lmac *channel_cfg = (void *)&cmd->data; 660 int i; 661 662 for (i = 0; i < n_channels; i++) { 663 channel_cfg[i].channel_num = 664 cpu_to_le16(channels[i]->hw_value); 665 channel_cfg[i].iter_count = cpu_to_le16(1); 666 channel_cfg[i].iter_interval = 0; 667 channel_cfg[i].flags = 668 cpu_to_le32(IWL_UNIFIED_SCAN_CHANNEL_PARTIAL | 669 ssid_bitmap); 670 } 671} 672 673static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies, 674 size_t len, u8 *const pos) 675{ 676 static const u8 before_ds_params[] = { 677 WLAN_EID_SSID, 678 WLAN_EID_SUPP_RATES, 679 WLAN_EID_REQUEST, 680 WLAN_EID_EXT_SUPP_RATES, 681 }; 682 size_t offs; 683 u8 *newpos = pos; 684 685 if (!iwl_mvm_rrm_scan_needed(mvm)) { 686 memcpy(newpos, ies, len); 687 return newpos + len; 688 } 689 690 offs = ieee80211_ie_split(ies, len, 691 before_ds_params, 692 ARRAY_SIZE(before_ds_params), 693 0); 694 695 memcpy(newpos, ies, offs); 696 newpos += offs; 697 698 /* Add a placeholder for DS Parameter Set element */ 699 *newpos++ = WLAN_EID_DS_PARAMS; 700 *newpos++ = 1; 701 *newpos++ = 0; 702 703 memcpy(newpos, ies + offs, len - offs); 704 newpos += len - offs; 705 706 return newpos; 707} 708 709static void 710iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 711 struct ieee80211_scan_ies *ies, 712 struct iwl_scan_probe_req *preq, 713 const u8 *mac_addr, const u8 *mac_addr_mask) 714{ 715 struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf; 716 u8 *pos, *newpos; 717 718 /* 719 * Unfortunately, right now the offload scan doesn't support randomising 720 * within the firmware, so until the firmware API is ready we implement 721 * it in the driver. This means that the scan iterations won't really be 722 * random, only when it's restarted, but at least that helps a bit. 723 */ 724 if (mac_addr) 725 get_random_mask_addr(frame->sa, mac_addr, mac_addr_mask); 726 else 727 memcpy(frame->sa, vif->addr, ETH_ALEN); 728 729 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 730 eth_broadcast_addr(frame->da); 731 eth_broadcast_addr(frame->bssid); 732 frame->seq_ctrl = 0; 733 734 pos = frame->u.probe_req.variable; 735 *pos++ = WLAN_EID_SSID; 736 *pos++ = 0; 737 738 preq->mac_header.offset = 0; 739 preq->mac_header.len = cpu_to_le16(24 + 2); 740 741 /* Insert ds parameter set element on 2.4 GHz band */ 742 newpos = iwl_mvm_copy_and_insert_ds_elem(mvm, 743 ies->ies[IEEE80211_BAND_2GHZ], 744 ies->len[IEEE80211_BAND_2GHZ], 745 pos); 746 preq->band_data[0].offset = cpu_to_le16(pos - preq->buf); 747 preq->band_data[0].len = cpu_to_le16(newpos - pos); 748 pos = newpos; 749 750 memcpy(pos, ies->ies[IEEE80211_BAND_5GHZ], 751 ies->len[IEEE80211_BAND_5GHZ]); 752 preq->band_data[1].offset = cpu_to_le16(pos - preq->buf); 753 preq->band_data[1].len = cpu_to_le16(ies->len[IEEE80211_BAND_5GHZ]); 754 pos += ies->len[IEEE80211_BAND_5GHZ]; 755 756 memcpy(pos, ies->common_ies, ies->common_ie_len); 757 preq->common_data.offset = cpu_to_le16(pos - preq->buf); 758 preq->common_data.len = cpu_to_le16(ies->common_ie_len); 759} 760 761static void 762iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, 763 struct iwl_scan_req_unified_lmac *cmd, 764 struct iwl_mvm_scan_params *params) 765{ 766 memset(cmd, 0, ksize(cmd)); 767 cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active; 768 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; 769 if (params->passive_fragmented) 770 cmd->fragmented_dwell = 771 params->dwell[IEEE80211_BAND_2GHZ].fragmented; 772 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); 773 cmd->max_out_time = cpu_to_le32(params->max_out_time); 774 cmd->suspend_time = cpu_to_le32(params->suspend_time); 775 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 776 cmd->iter_num = cpu_to_le32(1); 777 778 if (iwl_mvm_rrm_scan_needed(mvm)) 779 cmd->scan_flags |= 780 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); 781} 782 783int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, 784 struct ieee80211_vif *vif, 785 struct ieee80211_scan_request *req) 786{ 787 struct iwl_host_cmd hcmd = { 788 .id = SCAN_OFFLOAD_REQUEST_CMD, 789 .len = { sizeof(struct iwl_scan_req_unified_lmac) + 790 sizeof(struct iwl_scan_channel_cfg_lmac) * 791 mvm->fw->ucode_capa.n_scan_channels + 792 sizeof(struct iwl_scan_probe_req), }, 793 .data = { mvm->scan_cmd, }, 794 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 795 }; 796 struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd; 797 struct iwl_scan_probe_req *preq; 798 struct iwl_mvm_scan_params params = {}; 799 u32 flags; 800 u32 ssid_bitmap = 0; 801 int ret, i; 802 803 lockdep_assert_held(&mvm->mutex); 804 805 /* we should have failed registration if scan_cmd was NULL */ 806 if (WARN_ON(mvm->scan_cmd == NULL)) 807 return -ENOMEM; 808 809 if (req->req.n_ssids > PROBE_OPTION_MAX || 810 req->ies.common_ie_len + req->ies.len[NL80211_BAND_2GHZ] + 811 req->ies.len[NL80211_BAND_5GHZ] > 812 iwl_mvm_max_scan_ie_fw_cmd_room(mvm, false) || 813 req->req.n_channels > mvm->fw->ucode_capa.n_scan_channels) 814 return -ENOBUFS; 815 816 mvm->scan_status = IWL_MVM_SCAN_OS; 817 818 iwl_mvm_scan_calc_params(mvm, vif, req->req.n_ssids, req->req.flags, 819 ¶ms); 820 821 iwl_mvm_build_generic_unified_scan_cmd(mvm, cmd, ¶ms); 822 823 cmd->n_channels = (u8)req->req.n_channels; 824 825 flags = IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; 826 827 if (req->req.n_ssids == 1 && req->req.ssids[0].ssid_len != 0) 828 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; 829 830 if (params.passive_fragmented) 831 flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED; 832 833 if (req->req.n_ssids == 0) 834 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; 835 836 cmd->scan_flags |= cpu_to_le32(flags); 837 838 cmd->flags = iwl_mvm_scan_rxon_flags(req->req.channels[0]->band); 839 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 840 MAC_FILTER_IN_BEACON); 841 iwl_mvm_unified_scan_fill_tx_cmd(mvm, cmd->tx_cmd, req->req.no_cck); 842 iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->req.ssids, 843 req->req.n_ssids, 0); 844 845 cmd->schedule[0].delay = 0; 846 cmd->schedule[0].iterations = 1; 847 cmd->schedule[0].full_scan_mul = 0; 848 cmd->schedule[1].delay = 0; 849 cmd->schedule[1].iterations = 0; 850 cmd->schedule[1].full_scan_mul = 0; 851 852 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && 853 mvm->last_ebs_successful) { 854 cmd->channel_opt[0].flags = 855 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 856 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 857 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 858 cmd->channel_opt[0].non_ebs_ratio = 859 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); 860 cmd->channel_opt[1].flags = 861 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 862 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 863 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 864 cmd->channel_opt[1].non_ebs_ratio = 865 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); 866 } 867 868 for (i = 1; i <= req->req.n_ssids; i++) 869 ssid_bitmap |= BIT(i); 870 871 iwl_mvm_lmac_scan_cfg_channels(mvm, req->req.channels, 872 req->req.n_channels, ssid_bitmap, 873 cmd); 874 875 preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * 876 mvm->fw->ucode_capa.n_scan_channels); 877 878 iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, preq, 879 req->req.flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? 880 req->req.mac_addr : NULL, 881 req->req.mac_addr_mask); 882 883 ret = iwl_mvm_send_cmd(mvm, &hcmd); 884 if (!ret) { 885 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n"); 886 } else { 887 /* 888 * If the scan failed, it usually means that the FW was unable 889 * to allocate the time events. Warn on it, but maybe we 890 * should try to send the command again with different params. 891 */ 892 IWL_ERR(mvm, "Scan failed! ret %d\n", ret); 893 mvm->scan_status = IWL_MVM_SCAN_NONE; 894 ret = -EIO; 895 } 896 return ret; 897} 898 899int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, 900 struct ieee80211_vif *vif, 901 struct cfg80211_sched_scan_request *req, 902 struct ieee80211_scan_ies *ies) 903{ 904 struct iwl_host_cmd hcmd = { 905 .id = SCAN_OFFLOAD_REQUEST_CMD, 906 .len = { sizeof(struct iwl_scan_req_unified_lmac) + 907 sizeof(struct iwl_scan_channel_cfg_lmac) * 908 mvm->fw->ucode_capa.n_scan_channels + 909 sizeof(struct iwl_scan_probe_req), }, 910 .data = { mvm->scan_cmd, }, 911 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 912 }; 913 struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd; 914 struct iwl_scan_probe_req *preq; 915 struct iwl_mvm_scan_params params = {}; 916 int ret; 917 u32 flags = 0, ssid_bitmap = 0; 918 919 lockdep_assert_held(&mvm->mutex); 920 921 /* we should have failed registration if scan_cmd was NULL */ 922 if (WARN_ON(mvm->scan_cmd == NULL)) 923 return -ENOMEM; 924 925 if (req->n_ssids > PROBE_OPTION_MAX || 926 ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + 927 ies->len[NL80211_BAND_5GHZ] > 928 iwl_mvm_max_scan_ie_fw_cmd_room(mvm, true) || 929 req->n_channels > mvm->fw->ucode_capa.n_scan_channels) 930 return -ENOBUFS; 931 932 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, ¶ms); 933 934 iwl_mvm_build_generic_unified_scan_cmd(mvm, cmd, ¶ms); 935 936 cmd->n_channels = (u8)req->n_channels; 937 938 cmd->delay = cpu_to_le32(req->delay); 939 940 if (iwl_mvm_scan_pass_all(mvm, req)) 941 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; 942 else 943 flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH; 944 945 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) 946 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; 947 948 if (params.passive_fragmented) 949 flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED; 950 951 if (req->n_ssids == 0) 952 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; 953 954#ifdef CONFIG_IWLWIFI_DEBUGFS 955 if (mvm->scan_iter_notif_enabled) 956 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE; 957#endif 958 959 cmd->scan_flags |= cpu_to_le32(flags); 960 961 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); 962 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 963 MAC_FILTER_IN_BEACON); 964 iwl_mvm_unified_scan_fill_tx_cmd(mvm, cmd->tx_cmd, false); 965 iwl_scan_offload_build_ssid(req, cmd->direct_scan, &ssid_bitmap, false); 966 967 cmd->schedule[0].delay = cpu_to_le16(req->interval / MSEC_PER_SEC); 968 cmd->schedule[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS; 969 cmd->schedule[0].full_scan_mul = 1; 970 971 cmd->schedule[1].delay = cpu_to_le16(req->interval / MSEC_PER_SEC); 972 cmd->schedule[1].iterations = 0xff; 973 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; 974 975 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && 976 mvm->last_ebs_successful) { 977 cmd->channel_opt[0].flags = 978 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 979 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 980 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 981 cmd->channel_opt[0].non_ebs_ratio = 982 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); 983 cmd->channel_opt[1].flags = 984 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 985 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 986 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 987 cmd->channel_opt[1].non_ebs_ratio = 988 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); 989 } 990 991 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, 992 ssid_bitmap, cmd); 993 994 preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * 995 mvm->fw->ucode_capa.n_scan_channels); 996 997 iwl_mvm_build_unified_scan_probe(mvm, vif, ies, preq, 998 req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? 999 req->mac_addr : NULL, 1000 req->mac_addr_mask); 1001 1002 ret = iwl_mvm_send_cmd(mvm, &hcmd); 1003 if (!ret) { 1004 IWL_DEBUG_SCAN(mvm, 1005 "Sched scan request was sent successfully\n"); 1006 } else { 1007 /* 1008 * If the scan failed, it usually means that the FW was unable 1009 * to allocate the time events. Warn on it, but maybe we 1010 * should try to send the command again with different params. 1011 */ 1012 IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret); 1013 mvm->scan_status = IWL_MVM_SCAN_NONE; 1014 ret = -EIO; 1015 } 1016 return ret; 1017} 1018 1019 1020int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) 1021{ 1022 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) 1023 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_REG_SCAN, 1024 true); 1025 1026 if (mvm->scan_status == IWL_MVM_SCAN_NONE) 1027 return 0; 1028 1029 if (iwl_mvm_is_radio_killed(mvm)) { 1030 ieee80211_scan_completed(mvm->hw, true); 1031 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1032 mvm->scan_status = IWL_MVM_SCAN_NONE; 1033 return 0; 1034 } 1035 1036 return iwl_mvm_scan_offload_stop(mvm, true); 1037} 1038 1039/* UMAC scan API */ 1040 1041struct iwl_umac_scan_done { 1042 struct iwl_mvm *mvm; 1043 enum iwl_umac_scan_uid_type type; 1044}; 1045 1046static int rate_to_scan_rate_flag(unsigned int rate) 1047{ 1048 static const int rate_to_scan_rate[IWL_RATE_COUNT] = { 1049 [IWL_RATE_1M_INDEX] = SCAN_CONFIG_RATE_1M, 1050 [IWL_RATE_2M_INDEX] = SCAN_CONFIG_RATE_2M, 1051 [IWL_RATE_5M_INDEX] = SCAN_CONFIG_RATE_5M, 1052 [IWL_RATE_11M_INDEX] = SCAN_CONFIG_RATE_11M, 1053 [IWL_RATE_6M_INDEX] = SCAN_CONFIG_RATE_6M, 1054 [IWL_RATE_9M_INDEX] = SCAN_CONFIG_RATE_9M, 1055 [IWL_RATE_12M_INDEX] = SCAN_CONFIG_RATE_12M, 1056 [IWL_RATE_18M_INDEX] = SCAN_CONFIG_RATE_18M, 1057 [IWL_RATE_24M_INDEX] = SCAN_CONFIG_RATE_24M, 1058 [IWL_RATE_36M_INDEX] = SCAN_CONFIG_RATE_36M, 1059 [IWL_RATE_48M_INDEX] = SCAN_CONFIG_RATE_48M, 1060 [IWL_RATE_54M_INDEX] = SCAN_CONFIG_RATE_54M, 1061 }; 1062 1063 return rate_to_scan_rate[rate]; 1064} 1065 1066static __le32 iwl_mvm_scan_config_rates(struct iwl_mvm *mvm) 1067{ 1068 struct ieee80211_supported_band *band; 1069 unsigned int rates = 0; 1070 int i; 1071 1072 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 1073 for (i = 0; i < band->n_bitrates; i++) 1074 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value); 1075 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 1076 for (i = 0; i < band->n_bitrates; i++) 1077 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value); 1078 1079 /* Set both basic rates and supported rates */ 1080 rates |= SCAN_CONFIG_SUPPORTED_RATE(rates); 1081 1082 return cpu_to_le32(rates); 1083} 1084 1085int iwl_mvm_config_scan(struct iwl_mvm *mvm) 1086{ 1087 1088 struct iwl_scan_config *scan_config; 1089 struct ieee80211_supported_band *band; 1090 int num_channels = 1091 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 1092 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 1093 int ret, i, j = 0, cmd_size, data_size; 1094 struct iwl_host_cmd cmd = { 1095 .id = SCAN_CFG_CMD, 1096 }; 1097 1098 if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels)) 1099 return -ENOBUFS; 1100 1101 cmd_size = sizeof(*scan_config) + mvm->fw->ucode_capa.n_scan_channels; 1102 1103 scan_config = kzalloc(cmd_size, GFP_KERNEL); 1104 if (!scan_config) 1105 return -ENOMEM; 1106 1107 data_size = cmd_size - sizeof(struct iwl_mvm_umac_cmd_hdr); 1108 scan_config->hdr.size = cpu_to_le16(data_size); 1109 scan_config->flags = cpu_to_le32(SCAN_CONFIG_FLAG_ACTIVATE | 1110 SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS | 1111 SCAN_CONFIG_FLAG_SET_TX_CHAINS | 1112 SCAN_CONFIG_FLAG_SET_RX_CHAINS | 1113 SCAN_CONFIG_FLAG_SET_ALL_TIMES | 1114 SCAN_CONFIG_FLAG_SET_LEGACY_RATES | 1115 SCAN_CONFIG_FLAG_SET_MAC_ADDR | 1116 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS| 1117 SCAN_CONFIG_N_CHANNELS(num_channels)); 1118 scan_config->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); 1119 scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm)); 1120 scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm); 1121 scan_config->out_of_channel_time = cpu_to_le32(170); 1122 scan_config->suspend_time = cpu_to_le32(30); 1123 scan_config->dwell_active = 20; 1124 scan_config->dwell_passive = 110; 1125 scan_config->dwell_fragmented = 20; 1126 1127 memcpy(&scan_config->mac_addr, &mvm->addresses[0].addr, ETH_ALEN); 1128 1129 scan_config->bcast_sta_id = mvm->aux_sta.sta_id; 1130 scan_config->channel_flags = IWL_CHANNEL_FLAG_EBS | 1131 IWL_CHANNEL_FLAG_ACCURATE_EBS | 1132 IWL_CHANNEL_FLAG_EBS_ADD | 1133 IWL_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE; 1134 1135 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 1136 for (i = 0; i < band->n_channels; i++, j++) 1137 scan_config->channel_array[j] = band->channels[i].hw_value; 1138 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 1139 for (i = 0; i < band->n_channels; i++, j++) 1140 scan_config->channel_array[j] = band->channels[i].hw_value; 1141 1142 cmd.data[0] = scan_config; 1143 cmd.len[0] = cmd_size; 1144 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; 1145 1146 IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n"); 1147 1148 ret = iwl_mvm_send_cmd(mvm, &cmd); 1149 1150 kfree(scan_config); 1151 return ret; 1152} 1153 1154static int iwl_mvm_find_scan_uid(struct iwl_mvm *mvm, u32 uid) 1155{ 1156 int i; 1157 1158 for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) 1159 if (mvm->scan_uid[i] == uid) 1160 return i; 1161 1162 return i; 1163} 1164 1165static int iwl_mvm_find_free_scan_uid(struct iwl_mvm *mvm) 1166{ 1167 return iwl_mvm_find_scan_uid(mvm, 0); 1168} 1169 1170static bool iwl_mvm_find_scan_type(struct iwl_mvm *mvm, 1171 enum iwl_umac_scan_uid_type type) 1172{ 1173 int i; 1174 1175 for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) 1176 if (mvm->scan_uid[i] & type) 1177 return true; 1178 1179 return false; 1180} 1181 1182static int iwl_mvm_find_first_scan(struct iwl_mvm *mvm, 1183 enum iwl_umac_scan_uid_type type) 1184{ 1185 int i; 1186 1187 for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) 1188 if (mvm->scan_uid[i] & type) 1189 return i; 1190 1191 return i; 1192} 1193 1194static u32 iwl_generate_scan_uid(struct iwl_mvm *mvm, 1195 enum iwl_umac_scan_uid_type type) 1196{ 1197 u32 uid; 1198 1199 /* make sure exactly one bit is on in scan type */ 1200 WARN_ON(hweight8(type) != 1); 1201 1202 /* 1203 * Make sure scan uids are unique. If one scan lasts long time while 1204 * others are completing frequently, the seq number will wrap up and 1205 * we may have more than one scan with the same uid. 1206 */ 1207 do { 1208 uid = type | (mvm->scan_seq_num << 1209 IWL_UMAC_SCAN_UID_SEQ_OFFSET); 1210 mvm->scan_seq_num++; 1211 } while (iwl_mvm_find_scan_uid(mvm, uid) < 1212 IWL_MVM_MAX_SIMULTANEOUS_SCANS); 1213 1214 IWL_DEBUG_SCAN(mvm, "Generated scan UID %u\n", uid); 1215 1216 return uid; 1217} 1218 1219static void 1220iwl_mvm_build_generic_umac_scan_cmd(struct iwl_mvm *mvm, 1221 struct iwl_scan_req_umac *cmd, 1222 struct iwl_mvm_scan_params *params) 1223{ 1224 memset(cmd, 0, ksize(cmd)); 1225 cmd->hdr.size = cpu_to_le16(iwl_mvm_scan_size(mvm) - 1226 sizeof(struct iwl_mvm_umac_cmd_hdr)); 1227 cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active; 1228 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; 1229 if (params->passive_fragmented) 1230 cmd->fragmented_dwell = 1231 params->dwell[IEEE80211_BAND_2GHZ].fragmented; 1232 cmd->max_out_time = cpu_to_le32(params->max_out_time); 1233 cmd->suspend_time = cpu_to_le32(params->suspend_time); 1234 cmd->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1235} 1236 1237static void 1238iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm, 1239 struct ieee80211_channel **channels, 1240 int n_channels, u32 ssid_bitmap, 1241 struct iwl_scan_req_umac *cmd) 1242{ 1243 struct iwl_scan_channel_cfg_umac *channel_cfg = (void *)&cmd->data; 1244 int i; 1245 1246 for (i = 0; i < n_channels; i++) { 1247 channel_cfg[i].flags = cpu_to_le32(ssid_bitmap); 1248 channel_cfg[i].channel_num = channels[i]->hw_value; 1249 channel_cfg[i].iter_count = 1; 1250 channel_cfg[i].iter_interval = 0; 1251 } 1252} 1253 1254static u32 iwl_mvm_scan_umac_common_flags(struct iwl_mvm *mvm, int n_ssids, 1255 struct cfg80211_ssid *ssids, 1256 int fragmented) 1257{ 1258 int flags = 0; 1259 1260 if (n_ssids == 0) 1261 flags = IWL_UMAC_SCAN_GEN_FLAGS_PASSIVE; 1262 1263 if (n_ssids == 1 && ssids[0].ssid_len != 0) 1264 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT; 1265 1266 if (fragmented) 1267 flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED; 1268 1269 if (iwl_mvm_rrm_scan_needed(mvm)) 1270 flags |= IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED; 1271 1272 return flags; 1273} 1274 1275int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1276 struct ieee80211_scan_request *req) 1277{ 1278 struct iwl_host_cmd hcmd = { 1279 .id = SCAN_REQ_UMAC, 1280 .len = { iwl_mvm_scan_size(mvm), }, 1281 .data = { mvm->scan_cmd, }, 1282 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 1283 }; 1284 struct iwl_scan_req_umac *cmd = mvm->scan_cmd; 1285 struct iwl_scan_req_umac_tail *sec_part = (void *)&cmd->data + 1286 sizeof(struct iwl_scan_channel_cfg_umac) * 1287 mvm->fw->ucode_capa.n_scan_channels; 1288 struct iwl_mvm_scan_params params = {}; 1289 u32 uid, flags; 1290 u32 ssid_bitmap = 0; 1291 int ret, i, uid_idx; 1292 1293 lockdep_assert_held(&mvm->mutex); 1294 1295 uid_idx = iwl_mvm_find_free_scan_uid(mvm); 1296 if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) 1297 return -EBUSY; 1298 1299 /* we should have failed registration if scan_cmd was NULL */ 1300 if (WARN_ON(mvm->scan_cmd == NULL)) 1301 return -ENOMEM; 1302 1303 if (WARN_ON(req->req.n_ssids > PROBE_OPTION_MAX || 1304 req->ies.common_ie_len + 1305 req->ies.len[NL80211_BAND_2GHZ] + 1306 req->ies.len[NL80211_BAND_5GHZ] + 24 + 2 > 1307 SCAN_OFFLOAD_PROBE_REQ_SIZE || req->req.n_channels > 1308 mvm->fw->ucode_capa.n_scan_channels)) 1309 return -ENOBUFS; 1310 1311 iwl_mvm_scan_calc_params(mvm, vif, req->req.n_ssids, req->req.flags, 1312 ¶ms); 1313 1314 iwl_mvm_build_generic_umac_scan_cmd(mvm, cmd, ¶ms); 1315 1316 uid = iwl_generate_scan_uid(mvm, IWL_UMAC_SCAN_UID_REG_SCAN); 1317 mvm->scan_uid[uid_idx] = uid; 1318 cmd->uid = cpu_to_le32(uid); 1319 1320 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1321 1322 flags = iwl_mvm_scan_umac_common_flags(mvm, req->req.n_ssids, 1323 req->req.ssids, 1324 params.passive_fragmented); 1325 1326 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; 1327 1328 cmd->general_flags = cpu_to_le32(flags); 1329 1330 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && 1331 mvm->last_ebs_successful) 1332 cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS | 1333 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1334 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD; 1335 1336 cmd->n_channels = req->req.n_channels; 1337 1338 for (i = 0; i < req->req.n_ssids; i++) 1339 ssid_bitmap |= BIT(i); 1340 1341 iwl_mvm_umac_scan_cfg_channels(mvm, req->req.channels, 1342 req->req.n_channels, ssid_bitmap, cmd); 1343 1344 sec_part->schedule[0].iter_count = 1; 1345 sec_part->delay = 0; 1346 1347 iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, &sec_part->preq, 1348 req->req.flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? 1349 req->req.mac_addr : NULL, 1350 req->req.mac_addr_mask); 1351 1352 iwl_mvm_scan_fill_ssids(sec_part->direct_scan, req->req.ssids, 1353 req->req.n_ssids, 0); 1354 1355 ret = iwl_mvm_send_cmd(mvm, &hcmd); 1356 if (!ret) { 1357 IWL_DEBUG_SCAN(mvm, 1358 "Scan request was sent successfully\n"); 1359 } else { 1360 /* 1361 * If the scan failed, it usually means that the FW was unable 1362 * to allocate the time events. Warn on it, but maybe we 1363 * should try to send the command again with different params. 1364 */ 1365 IWL_ERR(mvm, "Scan failed! ret %d\n", ret); 1366 } 1367 return ret; 1368} 1369 1370int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1371 struct cfg80211_sched_scan_request *req, 1372 struct ieee80211_scan_ies *ies) 1373{ 1374 1375 struct iwl_host_cmd hcmd = { 1376 .id = SCAN_REQ_UMAC, 1377 .len = { iwl_mvm_scan_size(mvm), }, 1378 .data = { mvm->scan_cmd, }, 1379 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 1380 }; 1381 struct iwl_scan_req_umac *cmd = mvm->scan_cmd; 1382 struct iwl_scan_req_umac_tail *sec_part = (void *)&cmd->data + 1383 sizeof(struct iwl_scan_channel_cfg_umac) * 1384 mvm->fw->ucode_capa.n_scan_channels; 1385 struct iwl_mvm_scan_params params = {}; 1386 u32 uid, flags; 1387 u32 ssid_bitmap = 0; 1388 int ret, uid_idx; 1389 1390 lockdep_assert_held(&mvm->mutex); 1391 1392 uid_idx = iwl_mvm_find_free_scan_uid(mvm); 1393 if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) 1394 return -EBUSY; 1395 1396 /* we should have failed registration if scan_cmd was NULL */ 1397 if (WARN_ON(mvm->scan_cmd == NULL)) 1398 return -ENOMEM; 1399 1400 if (WARN_ON(req->n_ssids > PROBE_OPTION_MAX || 1401 ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + 1402 ies->len[NL80211_BAND_5GHZ] + 24 + 2 > 1403 SCAN_OFFLOAD_PROBE_REQ_SIZE || req->n_channels > 1404 mvm->fw->ucode_capa.n_scan_channels)) 1405 return -ENOBUFS; 1406 1407 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, 1408 ¶ms); 1409 1410 iwl_mvm_build_generic_umac_scan_cmd(mvm, cmd, ¶ms); 1411 1412 cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE); 1413 1414 uid = iwl_generate_scan_uid(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN); 1415 mvm->scan_uid[uid_idx] = uid; 1416 cmd->uid = cpu_to_le32(uid); 1417 1418 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_LOW); 1419 1420 flags = iwl_mvm_scan_umac_common_flags(mvm, req->n_ssids, req->ssids, 1421 params.passive_fragmented); 1422 1423 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PERIODIC; 1424 1425 if (iwl_mvm_scan_pass_all(mvm, req)) 1426 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; 1427 else 1428 flags |= IWL_UMAC_SCAN_GEN_FLAGS_MATCH; 1429 1430 cmd->general_flags = cpu_to_le32(flags); 1431 1432 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && 1433 mvm->last_ebs_successful) 1434 cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS | 1435 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1436 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD; 1437 1438 cmd->n_channels = req->n_channels; 1439 1440 iwl_scan_offload_build_ssid(req, sec_part->direct_scan, &ssid_bitmap, 1441 false); 1442 1443 /* This API uses bits 0-19 instead of 1-20. */ 1444 ssid_bitmap = ssid_bitmap >> 1; 1445 1446 iwl_mvm_umac_scan_cfg_channels(mvm, req->channels, req->n_channels, 1447 ssid_bitmap, cmd); 1448 1449 sec_part->schedule[0].interval = 1450 cpu_to_le16(req->interval / MSEC_PER_SEC); 1451 sec_part->schedule[0].iter_count = 0xff; 1452 1453 if (req->delay > U16_MAX) { 1454 IWL_DEBUG_SCAN(mvm, 1455 "delay value is > 16-bits, set to max possible\n"); 1456 sec_part->delay = cpu_to_le16(U16_MAX); 1457 } else { 1458 sec_part->delay = cpu_to_le16(req->delay); 1459 } 1460 1461 iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq, 1462 req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? 1463 req->mac_addr : NULL, 1464 req->mac_addr_mask); 1465 1466 ret = iwl_mvm_send_cmd(mvm, &hcmd); 1467 if (!ret) { 1468 IWL_DEBUG_SCAN(mvm, 1469 "Sched scan request was sent successfully\n"); 1470 } else { 1471 /* 1472 * If the scan failed, it usually means that the FW was unable 1473 * to allocate the time events. Warn on it, but maybe we 1474 * should try to send the command again with different params. 1475 */ 1476 IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret); 1477 } 1478 return ret; 1479} 1480 1481int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, 1482 struct iwl_rx_cmd_buffer *rxb, 1483 struct iwl_device_cmd *cmd) 1484{ 1485 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1486 struct iwl_umac_scan_complete *notif = (void *)pkt->data; 1487 u32 uid = __le32_to_cpu(notif->uid); 1488 bool sched = !!(uid & IWL_UMAC_SCAN_UID_SCHED_SCAN); 1489 int uid_idx = iwl_mvm_find_scan_uid(mvm, uid); 1490 1491 /* 1492 * Scan uid may be set to zero in case of scan abort request from above. 1493 */ 1494 if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) 1495 return 0; 1496 1497 IWL_DEBUG_SCAN(mvm, 1498 "Scan completed, uid %u type %s, status %s, EBS status %s\n", 1499 uid, sched ? "sched" : "regular", 1500 notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? 1501 "completed" : "aborted", 1502 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? 1503 "success" : "failed"); 1504 1505 if (notif->ebs_status) 1506 mvm->last_ebs_successful = false; 1507 1508 mvm->scan_uid[uid_idx] = 0; 1509 1510 if (!sched) { 1511 ieee80211_scan_completed(mvm->hw, 1512 notif->status == 1513 IWL_SCAN_OFFLOAD_ABORTED); 1514 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1515 } else if (!iwl_mvm_find_scan_type(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN)) { 1516 ieee80211_sched_scan_stopped(mvm->hw); 1517 } else { 1518 IWL_DEBUG_SCAN(mvm, "Another sched scan is running\n"); 1519 } 1520 1521 return 0; 1522} 1523 1524static bool iwl_scan_umac_done_check(struct iwl_notif_wait_data *notif_wait, 1525 struct iwl_rx_packet *pkt, void *data) 1526{ 1527 struct iwl_umac_scan_done *scan_done = data; 1528 struct iwl_umac_scan_complete *notif = (void *)pkt->data; 1529 u32 uid = __le32_to_cpu(notif->uid); 1530 int uid_idx = iwl_mvm_find_scan_uid(scan_done->mvm, uid); 1531 1532 if (WARN_ON(pkt->hdr.cmd != SCAN_COMPLETE_UMAC)) 1533 return false; 1534 1535 if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) 1536 return false; 1537 1538 /* 1539 * Clear scan uid of scans that was aborted from above and completed 1540 * in FW so the RX handler does nothing. Set last_ebs_successful here if 1541 * needed. 1542 */ 1543 scan_done->mvm->scan_uid[uid_idx] = 0; 1544 1545 if (notif->ebs_status) 1546 scan_done->mvm->last_ebs_successful = false; 1547 1548 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type); 1549} 1550 1551static int iwl_umac_scan_abort_one(struct iwl_mvm *mvm, u32 uid) 1552{ 1553 struct iwl_umac_scan_abort cmd = { 1554 .hdr.size = cpu_to_le16(sizeof(struct iwl_umac_scan_abort) - 1555 sizeof(struct iwl_mvm_umac_cmd_hdr)), 1556 .uid = cpu_to_le32(uid), 1557 }; 1558 1559 lockdep_assert_held(&mvm->mutex); 1560 1561 IWL_DEBUG_SCAN(mvm, "Sending scan abort, uid %u\n", uid); 1562 1563 return iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_UMAC, 0, sizeof(cmd), &cmd); 1564} 1565 1566static int iwl_umac_scan_stop(struct iwl_mvm *mvm, 1567 enum iwl_umac_scan_uid_type type, bool notify) 1568{ 1569 struct iwl_notification_wait wait_scan_done; 1570 static const u8 scan_done_notif[] = { SCAN_COMPLETE_UMAC, }; 1571 struct iwl_umac_scan_done scan_done = { 1572 .mvm = mvm, 1573 .type = type, 1574 }; 1575 int i, ret = -EIO; 1576 1577 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, 1578 scan_done_notif, 1579 ARRAY_SIZE(scan_done_notif), 1580 iwl_scan_umac_done_check, &scan_done); 1581 1582 IWL_DEBUG_SCAN(mvm, "Preparing to stop scan, type %x\n", type); 1583 1584 for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { 1585 if (mvm->scan_uid[i] & type) { 1586 int err; 1587 1588 if (iwl_mvm_is_radio_killed(mvm) && 1589 (type & IWL_UMAC_SCAN_UID_REG_SCAN)) { 1590 ieee80211_scan_completed(mvm->hw, true); 1591 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1592 break; 1593 } 1594 1595 err = iwl_umac_scan_abort_one(mvm, mvm->scan_uid[i]); 1596 if (!err) 1597 ret = 0; 1598 } 1599 } 1600 1601 if (ret) { 1602 IWL_DEBUG_SCAN(mvm, "Couldn't stop scan\n"); 1603 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); 1604 return ret; 1605 } 1606 1607 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); 1608 if (ret) 1609 return ret; 1610 1611 if (notify) { 1612 if (type & IWL_UMAC_SCAN_UID_SCHED_SCAN) 1613 ieee80211_sched_scan_stopped(mvm->hw); 1614 if (type & IWL_UMAC_SCAN_UID_REG_SCAN) { 1615 ieee80211_scan_completed(mvm->hw, true); 1616 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1617 } 1618 } 1619 1620 return ret; 1621} 1622 1623int iwl_mvm_scan_size(struct iwl_mvm *mvm) 1624{ 1625 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) 1626 return sizeof(struct iwl_scan_req_umac) + 1627 sizeof(struct iwl_scan_channel_cfg_umac) * 1628 mvm->fw->ucode_capa.n_scan_channels + 1629 sizeof(struct iwl_scan_req_umac_tail); 1630 1631 return sizeof(struct iwl_scan_req_unified_lmac) + 1632 sizeof(struct iwl_scan_channel_cfg_lmac) * 1633 mvm->fw->ucode_capa.n_scan_channels + 1634 sizeof(struct iwl_scan_probe_req); 1635} 1636 1637/* 1638 * This function is used in nic restart flow, to inform mac80211 about scans 1639 * that was aborted by restart flow or by an assert. 1640 */ 1641void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm) 1642{ 1643 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 1644 u32 uid, i; 1645 1646 uid = iwl_mvm_find_first_scan(mvm, IWL_UMAC_SCAN_UID_REG_SCAN); 1647 if (uid < IWL_MVM_MAX_SIMULTANEOUS_SCANS) { 1648 ieee80211_scan_completed(mvm->hw, true); 1649 mvm->scan_uid[uid] = 0; 1650 } 1651 uid = iwl_mvm_find_first_scan(mvm, 1652 IWL_UMAC_SCAN_UID_SCHED_SCAN); 1653 if (uid < IWL_MVM_MAX_SIMULTANEOUS_SCANS && !mvm->restart_fw) { 1654 ieee80211_sched_scan_stopped(mvm->hw); 1655 mvm->scan_uid[uid] = 0; 1656 } 1657 1658 /* We shouldn't have any UIDs still set. Loop over all the 1659 * UIDs to make sure there's nothing left there and warn if 1660 * any is found. 1661 */ 1662 for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { 1663 if (WARN_ONCE(mvm->scan_uid[i], 1664 "UMAC scan UID %d was not cleaned\n", 1665 mvm->scan_uid[i])) 1666 mvm->scan_uid[i] = 0; 1667 } 1668 } else { 1669 switch (mvm->scan_status) { 1670 case IWL_MVM_SCAN_NONE: 1671 break; 1672 case IWL_MVM_SCAN_OS: 1673 ieee80211_scan_completed(mvm->hw, true); 1674 break; 1675 case IWL_MVM_SCAN_SCHED: 1676 /* 1677 * Sched scan will be restarted by mac80211 in 1678 * restart_hw, so do not report if FW is about to be 1679 * restarted. 1680 */ 1681 if (!mvm->restart_fw) 1682 ieee80211_sched_scan_stopped(mvm->hw); 1683 break; 1684 } 1685 } 1686} 1687