1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_scan.c 22 * 23 * WLAN Host Device Driver scan implementation 24 */ 25 26 #include <linux/wireless.h> 27 #include <net/cfg80211.h> 28 29 #include "wlan_hdd_includes.h" 30 #include "cds_api.h" 31 #include "cds_api.h" 32 #include "ani_global.h" 33 #include "dot11f.h" 34 #include "cds_sched.h" 35 #include "osif_sync.h" 36 #include "wlan_hdd_p2p.h" 37 #include "wlan_hdd_trace.h" 38 #include "wlan_hdd_scan.h" 39 #include "wlan_policy_mgr_api.h" 40 #include "wlan_hdd_power.h" 41 #include "wma_api.h" 42 #include "cds_utils.h" 43 #include "wlan_p2p_ucfg_api.h" 44 #include "cfg_ucfg_api.h" 45 46 #include <qca_vendor.h> 47 #include <wlan_cfg80211_scan.h> 48 #include "wlan_utility.h" 49 #include "wlan_hdd_object_manager.h" 50 #include "nan_ucfg_api.h" 51 52 #define SCAN_DONE_EVENT_BUF_SIZE 4096 53 #define RATE_MASK 0x7f 54 55 /** 56 * hdd_vendor_scan_callback() - Scan completed callback event 57 * @adapter: HDD adapter 58 * @req: Scan request 59 * @aborted: true scan aborted false scan success 60 * 61 * This function sends scan completed callback event to NL. 62 * 63 * Return: none 64 */ 65 static void hdd_vendor_scan_callback(struct hdd_adapter *adapter, 66 struct cfg80211_scan_request *req, 67 bool aborted) 68 { 69 struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter); 70 struct sk_buff *skb; 71 struct nlattr *attr; 72 int i; 73 uint8_t scan_status; 74 uint64_t cookie; 75 enum qca_nl80211_vendor_subcmds_index index = 76 QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX; 77 78 hdd_enter(); 79 80 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 81 hdd_err("Invalid adapter magic"); 82 qdf_mem_free(req); 83 return; 84 } 85 skb = wlan_cfg80211_vendor_event_alloc(hddctx->wiphy, &adapter->wdev, 86 SCAN_DONE_EVENT_BUF_SIZE + 87 4 + NLMSG_HDRLEN, 88 index, GFP_KERNEL); 89 if (!skb) { 90 hdd_err("skb alloc failed"); 91 qdf_mem_free(req); 92 return; 93 } 94 95 cookie = (uintptr_t)req; 96 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS); 97 if (!attr) 98 goto nla_put_failure; 99 for (i = 0; i < req->n_ssids; i++) { 100 if (nla_put(skb, i, req->ssids[i].ssid_len, 101 req->ssids[i].ssid)) { 102 hdd_err("Failed to add ssid"); 103 goto nla_put_failure; 104 } 105 } 106 nla_nest_end(skb, attr); 107 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES); 108 if (!attr) 109 goto nla_put_failure; 110 for (i = 0; i < req->n_channels; i++) { 111 if (nla_put_u32(skb, i, req->channels[i]->center_freq)) { 112 hdd_err("Failed to add channel"); 113 goto nla_put_failure; 114 } 115 } 116 nla_nest_end(skb, attr); 117 118 if (req->ie && 119 nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len, 120 req->ie)) { 121 hdd_err("Failed to add scan ie"); 122 goto nla_put_failure; 123 } 124 if (req->flags && 125 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags)) { 126 hdd_err("Failed to add scan flags"); 127 goto nla_put_failure; 128 } 129 if (hdd_wlan_nla_put_u64(skb, 130 QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, 131 cookie)) { 132 hdd_err("Failed to add scan cookie"); 133 goto nla_put_failure; 134 } 135 scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED : 136 VENDOR_SCAN_STATUS_NEW_RESULTS; 137 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) { 138 hdd_err("Failed to add scan status"); 139 goto nla_put_failure; 140 } 141 wlan_cfg80211_vendor_event(skb, GFP_KERNEL); 142 hdd_info("scan complete event sent to NL"); 143 qdf_mem_free(req); 144 return; 145 146 nla_put_failure: 147 wlan_cfg80211_vendor_free_skb(skb); 148 qdf_mem_free(req); 149 } 150 151 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) 152 /** 153 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211 154 * @adapter: Pointer to the adapter 155 * @req : Scan request 156 * @aborted : true scan aborted false scan success 157 * 158 * This function notifies scan done to cfg80211 159 * 160 * Return: none 161 */ 162 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter, 163 struct cfg80211_scan_request *req, 164 bool aborted) 165 { 166 struct cfg80211_scan_info info = { 167 .aborted = aborted 168 }; 169 170 if (adapter->dev->flags & IFF_UP) 171 cfg80211_scan_done(req, &info); 172 } 173 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) 174 /** 175 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211 176 * @adapter: Pointer to the adapter 177 * @req : Scan request 178 * @aborted : true scan aborted false scan success 179 * 180 * This function notifies scan done to cfg80211 181 * 182 * Return: none 183 */ 184 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter, 185 struct cfg80211_scan_request *req, 186 bool aborted) 187 { 188 if (adapter->dev->flags & IFF_UP) 189 cfg80211_scan_done(req, aborted); 190 } 191 #else 192 /** 193 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211 194 * @adapter: Pointer to the adapter 195 * @req : Scan request 196 * @aborted : true scan aborted false scan success 197 * 198 * This function notifies scan done to cfg80211 199 * 200 * Return: none 201 */ 202 static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter, 203 struct cfg80211_scan_request *req, 204 bool aborted) 205 { 206 cfg80211_scan_done(req, aborted); 207 } 208 #endif 209 210 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 211 /** 212 * wlan_hdd_sap_skip_scan_check() - The function will check OBSS 213 * scan skip or not for SAP. 214 * @hdd_ctx: pointer to hdd context. 215 * @request: pointer to scan request. 216 * 217 * This function will check the scan request's chan list against the 218 * previous ACS scan chan list. If all the chan are covered by 219 * previous ACS scan, we can skip the scan and return scan complete 220 * to save the SAP starting time. 221 * 222 * Return: true to skip the scan, 223 * false to continue the scan 224 */ 225 static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx, 226 struct cfg80211_scan_request *request) 227 { 228 int i, j; 229 bool skip; 230 231 hdd_debug("HDD_ACS_SKIP_STATUS = %d", 232 hdd_ctx->skip_acs_scan_status); 233 if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN) 234 return false; 235 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 236 if (!hdd_ctx->last_acs_freq_list || 237 hdd_ctx->num_of_channels == 0 || 238 request->n_channels == 0) { 239 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 240 return false; 241 } 242 skip = true; 243 for (i = 0; i < request->n_channels ; i++) { 244 bool find = false; 245 246 for (j = 0; j < hdd_ctx->num_of_channels; j++) { 247 if (hdd_ctx->last_acs_freq_list[j] == 248 request->channels[i]->center_freq) { 249 find = true; 250 break; 251 } 252 } 253 if (!find) { 254 skip = false; 255 hdd_debug("Freq %d isn't in ACS freq list", 256 request->channels[i]->center_freq); 257 break; 258 } 259 } 260 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 261 return skip; 262 } 263 #else 264 static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx, 265 struct cfg80211_scan_request *request) 266 { 267 return false; 268 } 269 #endif 270 271 void wlan_hdd_cfg80211_scan_block(struct hdd_adapter *adapter) 272 { 273 struct cfg80211_scan_request *request; 274 struct scan_req *blocked_scan_req; 275 qdf_list_node_t *node; 276 277 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 278 hdd_err("HDD adapter context is invalid"); 279 return; 280 } 281 282 qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock); 283 284 while (!qdf_list_empty(&adapter->blocked_scan_request_q)) { 285 qdf_list_remove_front(&adapter->blocked_scan_request_q, 286 &node); 287 blocked_scan_req = qdf_container_of(node, struct scan_req, 288 node); 289 request = blocked_scan_req->scan_request; 290 request->n_ssids = 0; 291 request->n_channels = 0; 292 if (blocked_scan_req->source == NL_SCAN) { 293 hdd_err("Scan aborted. Null result sent"); 294 hdd_cfg80211_scan_done(adapter, request, true); 295 } else { 296 hdd_err("Vendor scan aborted. Null result sent"); 297 hdd_vendor_scan_callback(adapter, request, true); 298 } 299 qdf_mem_free(blocked_scan_req); 300 } 301 302 qdf_mutex_release(&adapter->blocked_scan_request_q_lock); 303 } 304 305 void hdd_init_scan_reject_params(struct hdd_context *hdd_ctx) 306 { 307 if (hdd_ctx) { 308 hdd_ctx->last_scan_reject_timestamp = 0; 309 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 310 hdd_ctx->last_scan_reject_reason = 0; 311 hdd_ctx->scan_reject_cnt = 0; 312 } 313 } 314 315 /* 316 * wlan_hdd_update_scan_ies() - API to update the scan IEs of scan request 317 * with already stored default scan IEs 318 * 319 * @adapter: Pointer to HDD adapter 320 * @scan_info: Pointer to scan info in HDD adapter 321 * @scan_ie: Pointer to scan IE in scan request 322 * @scan_ie_len: Pointer to scan IE length in scan request 323 * 324 * Return: 0 on success; error number otherwise 325 */ 326 static int wlan_hdd_update_scan_ies(struct hdd_adapter *adapter, 327 struct hdd_scan_info *scan_info, uint8_t *scan_ie, 328 uint16_t *scan_ie_len) 329 { 330 uint16_t rem_len = scan_info->default_scan_ies_len; 331 uint8_t *temp_ie = scan_info->default_scan_ies; 332 uint8_t *current_ie; 333 const uint8_t *mbo_ie; 334 uint8_t elem_id; 335 uint16_t elem_len; 336 bool add_ie = false; 337 338 if (!scan_info->default_scan_ies_len || !scan_info->default_scan_ies) 339 return 0; 340 341 mbo_ie = wlan_get_vendor_ie_ptr_from_oui(MBO_OUI_TYPE, 342 MBO_OUI_TYPE_SIZE, scan_ie, 343 *scan_ie_len); 344 while (rem_len >= 2) { 345 current_ie = temp_ie; 346 elem_id = *temp_ie++; 347 elem_len = *temp_ie++; 348 rem_len -= 2; 349 350 if (elem_len > rem_len) { 351 hdd_err("Invalid element len %d for elem %d", elem_len, 352 elem_id); 353 return 0; 354 } 355 356 switch (elem_id) { 357 case DOT11F_EID_EXTCAP: 358 if (!wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP, 359 scan_ie, *scan_ie_len)) 360 add_ie = true; 361 break; 362 case WLAN_ELEMID_VENDOR: 363 /* Donot add MBO IE if its already present */ 364 if ((!mbo_ie && 365 0 == qdf_mem_cmp(&temp_ie[0], MBO_OUI_TYPE, 366 MBO_OUI_TYPE_SIZE)) || 367 (0 == qdf_mem_cmp(&temp_ie[0], QCN_OUI_TYPE, 368 QCN_OUI_TYPE_SIZE))) 369 add_ie = true; 370 break; 371 } 372 373 if (add_ie && (((*scan_ie_len) + elem_len) > 374 SIR_MAC_MAX_ADD_IE_LENGTH)){ 375 hdd_err("Not enough buffer to save default scan IE's"); 376 return 0; 377 } 378 379 if (add_ie) { 380 qdf_mem_copy(scan_ie + (*scan_ie_len), 381 current_ie, elem_len + 2); 382 (*scan_ie_len) += (elem_len + 2); 383 add_ie = false; 384 } 385 386 temp_ie += elem_len; 387 rem_len -= elem_len; 388 } 389 return 0; 390 } 391 392 static int 393 wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev, 394 struct cfg80211_scan_request *request, 395 uint8_t source) 396 { 397 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 398 struct scan_req *blocked_scan_req = 399 qdf_mem_malloc(sizeof(*blocked_scan_req)); 400 int ret = 0; 401 402 if (!blocked_scan_req) 403 return -EINVAL; 404 405 blocked_scan_req->dev = dev; 406 blocked_scan_req->scan_request = request; 407 blocked_scan_req->source = source; 408 blocked_scan_req->scan_id = 0; 409 410 qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock); 411 if (qdf_list_size(&adapter->blocked_scan_request_q) < 412 WLAN_MAX_SCAN_COUNT) 413 qdf_list_insert_back(&adapter->blocked_scan_request_q, 414 &blocked_scan_req->node); 415 else 416 ret = -EINVAL; 417 qdf_mutex_release(&adapter->blocked_scan_request_q_lock); 418 419 if (ret) { 420 hdd_err("Maximum number of block scan request reached!"); 421 qdf_mem_free(blocked_scan_req); 422 } 423 424 return ret; 425 } 426 427 /* Define short name to use in cds_trigger_recovery */ 428 #define SCAN_FAILURE QDF_SCAN_ATTEMPT_FAILURES 429 430 /** 431 * __wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request 432 * @wiphy: Pointer to wiphy 433 * @request: Pointer to scan request 434 * @source: scan request source(NL/Vendor scan) 435 * 436 * This API responds to scan trigger and update cfg80211 scan database 437 * later, scan dump command can be used to receive scan results 438 * 439 * Return: 0 for success, non zero for failure 440 */ 441 static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, 442 struct cfg80211_scan_request *request, 443 uint8_t source) 444 { 445 struct net_device *dev = request->wdev->netdev; 446 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 447 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 448 int status; 449 struct hdd_scan_info *scan_info = NULL; 450 struct hdd_adapter *con_sap_adapter; 451 struct hdd_ap_ctx *ap_ctx; 452 qdf_freq_t con_dfs_ch_freq; 453 uint8_t curr_vdev_id; 454 enum scan_reject_states curr_reason; 455 static uint32_t scan_ebusy_cnt; 456 struct scan_params params = {0}; 457 bool self_recovery; 458 struct wlan_objmgr_vdev *vdev; 459 QDF_STATUS qdf_status; 460 bool enable_connected_scan; 461 enum phy_ch_width con_dfs_ch_width; 462 463 if (cds_is_fw_down()) { 464 hdd_err("firmware is down, scan cmd cannot be processed"); 465 return -EINVAL; 466 } 467 468 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 469 hdd_err("Command not allowed in FTM mode"); 470 return -EINVAL; 471 } 472 473 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 474 return -EINVAL; 475 476 status = wlan_hdd_validate_context(hdd_ctx); 477 if (0 != status) 478 return status; 479 480 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 481 TRACE_CODE_HDD_CFG80211_SCAN, 482 adapter->deflink->vdev_id, request->n_channels); 483 484 if (!sme_is_session_id_valid(hdd_ctx->mac_handle, 485 adapter->deflink->vdev_id)) 486 return -EINVAL; 487 488 qdf_status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 489 if (QDF_IS_STATUS_ERROR(qdf_status)) { 490 hdd_err("Failed to get self recovery ini config"); 491 return -EIO; 492 } 493 494 enable_connected_scan = ucfg_scan_is_connected_scan_enabled( 495 hdd_ctx->psoc); 496 if (!enable_connected_scan && 497 hdd_cm_is_vdev_associated(adapter->deflink)) { 498 hdd_info("enable_connected_scan is false, Aborting scan"); 499 if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source)) 500 return -EAGAIN; 501 schedule_work(&adapter->scan_block_work); 502 return 0; 503 } 504 505 /* 506 * NDI and monitor mode don't need scan from userspace to establish 507 * connection and it does not support scan request either. 508 */ 509 if (QDF_NDI_MODE == adapter->device_mode || 510 QDF_MONITOR_MODE == adapter->device_mode) { 511 hdd_err("Scan not supported for %s", 512 qdf_opmode_str(adapter->device_mode)); 513 return -EINVAL; 514 } 515 516 scan_info = &adapter->scan_info; 517 518 /* Block All Scan during DFS operation and send null scan result */ 519 520 con_sap_adapter = hdd_get_con_sap_adapter(adapter, true); 521 if (con_sap_adapter) { 522 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(con_sap_adapter->deflink); 523 con_dfs_ch_freq = ap_ctx->sap_config.chan_freq; 524 con_dfs_ch_width = ap_ctx->sap_config.ch_params.ch_width; 525 if (con_dfs_ch_freq == AUTO_CHANNEL_SELECT) 526 con_dfs_ch_freq = ap_ctx->operating_chan_freq; 527 528 if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) && 529 !policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( 530 hdd_ctx->psoc) && 531 (wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, con_dfs_ch_freq) || 532 (wlan_reg_is_5ghz_ch_freq(con_dfs_ch_freq) && 533 con_dfs_ch_width == CH_WIDTH_160MHZ))) { 534 /* Provide empty scan result during DFS operation since 535 * scanning not supported during DFS. Reason is 536 * following case: 537 * DFS is supported only in SCC for MBSSID Mode. 538 * We shall not return EBUSY or ENOTSUPP as when Primary 539 * AP is operating in DFS channel and secondary AP is 540 * started. Though we force SCC in driver, the hostapd 541 * issues obss scan before starting secAP. This results 542 * in MCC in DFS mode. Thus we return null scan result. 543 * If we return scan failure hostapd fails secondary AP 544 * startup. 545 */ 546 hdd_err("##In DFS Master mode. Scan aborted"); 547 if (wlan_hdd_enqueue_blocked_scan_request(dev, request, 548 source)) 549 return -EAGAIN; 550 schedule_work(&adapter->scan_block_work); 551 return 0; 552 } 553 } 554 555 /* Check if scan is allowed at this point of time */ 556 if (hdd_is_connection_in_progress(&curr_vdev_id, &curr_reason)) { 557 scan_ebusy_cnt++; 558 hdd_err_rl("Scan not allowed. scan_ebusy_cnt: %d Session %d Reason %d", 559 scan_ebusy_cnt, curr_vdev_id, curr_reason); 560 if (hdd_ctx->last_scan_reject_vdev_id != curr_vdev_id || 561 hdd_ctx->last_scan_reject_reason != curr_reason || 562 !hdd_ctx->last_scan_reject_timestamp) { 563 hdd_ctx->last_scan_reject_vdev_id = curr_vdev_id; 564 hdd_ctx->last_scan_reject_reason = curr_reason; 565 hdd_ctx->last_scan_reject_timestamp = jiffies + 566 msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME); 567 hdd_ctx->scan_reject_cnt = 0; 568 } else { 569 hdd_ctx->scan_reject_cnt++; 570 if ((hdd_ctx->scan_reject_cnt >= 571 SCAN_REJECT_THRESHOLD) && 572 qdf_system_time_after(jiffies, 573 hdd_ctx->last_scan_reject_timestamp)) { 574 hdd_err("scan reject threshold reached Session %d Reason %d count %d reject timestamp %lu jiffies %lu", 575 curr_vdev_id, curr_reason, 576 hdd_ctx->scan_reject_cnt, 577 hdd_ctx->last_scan_reject_timestamp, 578 jiffies); 579 hdd_ctx->last_scan_reject_timestamp = 0; 580 hdd_ctx->scan_reject_cnt = 0; 581 if (cds_is_fatal_event_enabled()) { 582 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 583 WLAN_LOG_INDICATOR_HOST_DRIVER, 584 WLAN_LOG_REASON_SCAN_NOT_ALLOWED, 585 false, 586 self_recovery); 587 } else { 588 hdd_err("Triggering SSR due to scan stuck"); 589 cds_trigger_recovery(SCAN_FAILURE); 590 } 591 } 592 } 593 return -EBUSY; 594 } 595 596 hdd_init_scan_reject_params(hdd_ctx); 597 598 /* Check whether SAP scan can be skipped or not */ 599 if (adapter->device_mode == QDF_SAP_MODE && 600 wlan_hdd_sap_skip_scan_check(hdd_ctx, request)) { 601 hdd_debug("sap scan skipped"); 602 if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source)) 603 return -EAGAIN; 604 schedule_work(&adapter->scan_block_work); 605 return 0; 606 } 607 608 params.source = source; 609 params.default_ie.len = 0; 610 /* Store the Scan IE's in Adapter*/ 611 if (request->ie_len) { 612 if (request->ie_len > SIR_MAC_MAX_ADD_IE_LENGTH) { 613 hdd_debug("Invalid ie_len: %zu", request->ie_len); 614 return -EINVAL; 615 } 616 617 /* save this for future association (join requires this) */ 618 memset(&scan_info->scan_add_ie, 0, sizeof(scan_info->scan_add_ie)); 619 memcpy(scan_info->scan_add_ie.addIEdata, request->ie, 620 request->ie_len); 621 scan_info->scan_add_ie.length = request->ie_len; 622 623 wlan_hdd_update_scan_ies(adapter, scan_info, 624 scan_info->scan_add_ie.addIEdata, 625 &scan_info->scan_add_ie.length); 626 } else { 627 if (scan_info->default_scan_ies && 628 scan_info->default_scan_ies_len) { 629 qdf_mem_copy(scan_info->scan_add_ie.addIEdata, 630 scan_info->default_scan_ies, 631 scan_info->default_scan_ies_len); 632 scan_info->scan_add_ie.length = 633 scan_info->default_scan_ies_len; 634 params.default_ie.ptr = 635 qdf_mem_malloc(scan_info->default_scan_ies_len); 636 if (params.default_ie.ptr) { 637 qdf_mem_copy(params.default_ie.ptr, 638 scan_info->default_scan_ies, 639 scan_info->default_scan_ies_len); 640 params.default_ie.len = 641 scan_info->default_scan_ies_len; 642 } 643 } 644 } 645 646 if (QDF_P2P_CLIENT_MODE == adapter->device_mode || 647 QDF_P2P_DEVICE_MODE == adapter->device_mode) { 648 /* Disable NAN Discovery if enabled */ 649 ucfg_nan_disable_concurrency(hdd_ctx->psoc); 650 } 651 652 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID); 653 if (!vdev) { 654 status = -EINVAL; 655 goto error; 656 } 657 658 if ((request->n_ssids == 1) && (request->ssids) && 659 (request->ssids[0].ssid_len > 7) && 660 !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7)) 661 ucfg_p2p_status_scan(vdev); 662 663 /* If this a scan on SAP adapter, use scan priority high */ 664 if (adapter->device_mode == QDF_SAP_MODE) 665 params.priority = SCAN_PRIORITY_HIGH; 666 else 667 /* Use default scan priority */ 668 params.priority = SCAN_PRIORITY_COUNT; 669 670 status = ucfg_mlme_get_scan_probe_unicast_ra( 671 hdd_ctx->psoc, 672 ¶ms.scan_probe_unicast_ra); 673 if (QDF_IS_STATUS_ERROR(status)) 674 hdd_err("Failed to get unicast probe req ra cfg"); 675 676 params.mld_id = ucfg_mlme_get_eht_mld_id(hdd_ctx->psoc); 677 hdd_debug("MLD ID: %d", params.mld_id); 678 679 status = wlan_cfg80211_scan(vdev, request, ¶ms); 680 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 681 error: 682 if (params.default_ie.ptr) 683 qdf_mem_free(params.default_ie.ptr); 684 685 return status; 686 } 687 688 #undef SCAN_FAILURE 689 690 /** 691 * wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request 692 * @wiphy: Pointer to wiphy 693 * @request: Pointer to scan request 694 * 695 * This API responds to scan trigger and update cfg80211 scan database 696 * later, scan dump command can be used to receive scan results 697 * 698 * Return: 0 for success, non zero for failure 699 */ 700 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy, 701 struct cfg80211_scan_request *request) 702 { 703 int errno; 704 struct osif_vdev_sync *vdev_sync; 705 706 errno = osif_vdev_sync_op_start(request->wdev->netdev, &vdev_sync); 707 if (errno) 708 return errno; 709 710 errno = __wlan_hdd_cfg80211_scan(wiphy, request, NL_SCAN); 711 712 osif_vdev_sync_op_stop(vdev_sync); 713 714 return errno; 715 } 716 717 /** 718 * wlan_hdd_get_rates() -API to get the rates from scan request 719 * @wiphy: Pointer to wiphy 720 * @band: Band 721 * @rates: array of rates 722 * @rate_count: number of rates 723 * 724 * Return: o for failure, rate bitmap for success 725 */ 726 static uint32_t wlan_hdd_get_rates(struct wiphy *wiphy, 727 enum nl80211_band band, 728 const u8 *rates, unsigned int rate_count) 729 { 730 uint32_t j, count, rate_bitmap = 0; 731 uint32_t rate; 732 bool found; 733 734 for (count = 0; count < rate_count; count++) { 735 rate = ((rates[count]) & RATE_MASK) * 5; 736 found = false; 737 for (j = 0; j < wiphy->bands[band]->n_bitrates; j++) { 738 if (wiphy->bands[band]->bitrates[j].bitrate == rate) { 739 found = true; 740 rate_bitmap |= (1 << j); 741 break; 742 } 743 } 744 if (!found) 745 return 0; 746 } 747 return rate_bitmap; 748 } 749 750 /** 751 * wlan_hdd_send_scan_start_event() -API to send the scan start event 752 * @wiphy: Pointer to wiphy 753 * @wdev: Pointer to net device 754 * @cookie: scan identifier 755 * 756 * Return: return 0 on success and negative error code on failure 757 */ 758 static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy, 759 struct wireless_dev *wdev, uint64_t cookie) 760 { 761 struct sk_buff *skb; 762 int ret; 763 enum qca_nl80211_vendor_subcmds_index index = 764 QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX; 765 766 skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) + 767 NLA_HDRLEN + NLMSG_HDRLEN); 768 if (!skb) { 769 hdd_err(" reply skb alloc failed"); 770 return -ENOMEM; 771 } 772 773 if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, 774 cookie)) { 775 hdd_err("nla put fail"); 776 wlan_cfg80211_vendor_free_skb(skb); 777 return -EINVAL; 778 } 779 780 ret = wlan_cfg80211_vendor_cmd_reply(skb); 781 782 /* Send a scan started event to supplicant */ 783 skb = wlan_cfg80211_vendor_event_alloc(wiphy, wdev, 784 sizeof(u64) + 4 + NLMSG_HDRLEN, 785 index, GFP_KERNEL); 786 if (!skb) { 787 hdd_err("skb alloc failed"); 788 return -ENOMEM; 789 } 790 791 if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, 792 cookie)) { 793 wlan_cfg80211_vendor_free_skb(skb); 794 return -EINVAL; 795 } 796 797 wlan_cfg80211_vendor_event(skb, GFP_KERNEL); 798 return ret; 799 } 800 801 /** 802 * wlan_hdd_copy_bssid() - API to copy the bssid to vendor Scan request 803 * @request: Pointer to vendor scan request 804 * @bssid: Pointer to BSSID 805 * 806 * This API copies the specific BSSID received from Supplicant and copies it to 807 * the vendor Scan request 808 * 809 * Return: None 810 */ 811 #if defined(CFG80211_SCAN_BSSID) || \ 812 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) 813 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request, 814 uint8_t *bssid) 815 { 816 qdf_mem_copy(request->bssid, bssid, QDF_MAC_ADDR_SIZE); 817 } 818 #else 819 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request, 820 uint8_t *bssid) 821 { 822 } 823 #endif 824 825 static void hdd_process_vendor_acs_response(struct hdd_adapter *adapter) 826 { 827 qdf_mc_timer_t *vendor_acs_timer; 828 829 if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, 830 &adapter->deflink->link_flags)) { 831 return; 832 } 833 834 vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer; 835 if (QDF_TIMER_STATE_RUNNING == 836 qdf_mc_timer_get_current_state(vendor_acs_timer)) { 837 qdf_mc_timer_stop(vendor_acs_timer); 838 } 839 } 840 841 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ 842 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 843 /** 844 * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs 845 * @wiphy: Pointer to wiphy 846 * @request: Pointer to scan request 847 * @adapter: Pointer to hdd adapter 848 * @tb: Pointer to nl attributes 849 * 850 * This function is invoked to check whether vendor scan needs 851 * probe req source addr, if so populates mac_addr and mac_addr_mask 852 * in scan request with nl attrs. 853 * 854 * Return: 0 - on success, negative value on failure 855 */ 856 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, 857 struct cfg80211_scan_request *request, 858 struct hdd_adapter *adapter, 859 struct nlattr **tb) 860 { 861 uint32_t i; 862 int32_t len = QDF_MAC_ADDR_SIZE; 863 864 if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) 865 return 0; 866 867 if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) || 868 (hdd_cm_is_vdev_connected(adapter->deflink))) { 869 hdd_err("SCAN RANDOMIZATION not supported"); 870 return -EOPNOTSUPP; 871 } 872 873 if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] && 874 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) { 875 qdf_mem_zero(request->mac_addr, len); 876 qdf_mem_zero(request->mac_addr_mask, len); 877 request->mac_addr[0] = 0x2; 878 request->mac_addr_mask[0] = 0x3; 879 880 return 0; 881 } 882 883 if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] || 884 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) 885 return -EINVAL; 886 887 if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) || 888 (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len)) 889 return -EINVAL; 890 891 qdf_mem_copy(request->mac_addr, 892 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len); 893 894 qdf_mem_copy(request->mac_addr_mask, 895 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len); 896 897 /* avoid configure on multicast address */ 898 if (!cds_is_group_addr(request->mac_addr_mask) || 899 cds_is_group_addr(request->mac_addr)) 900 return -EINVAL; 901 902 for (i = 0; i < ETH_ALEN; i++) 903 request->mac_addr[i] &= request->mac_addr_mask[i]; 904 905 return 0; 906 } 907 #else 908 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, 909 struct cfg80211_scan_request *request, 910 struct hdd_adapter *adapter, 911 struct nlattr **tb) 912 { 913 return 0; 914 } 915 #endif 916 917 const 918 struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = { 919 [QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32}, 920 [QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG}, 921 [QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64}, 922 [QCA_WLAN_VENDOR_ATTR_SCAN_IE] = {.type = NLA_BINARY, 923 .len = MAX_DEFAULT_SCAN_IE_LEN}, 924 [QCA_WLAN_VENDOR_ATTR_SCAN_MAC] = VENDOR_NLA_POLICY_MAC_ADDR, 925 [QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK] = VENDOR_NLA_POLICY_MAC_ADDR, 926 [QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES] = {.type = NLA_NESTED}, 927 [QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS] = {.type = NLA_NESTED}, 928 [QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES] = {.type = NLA_NESTED}, 929 [QCA_WLAN_VENDOR_ATTR_SCAN_BSSID] = {.type = NLA_BINARY}, 930 }; 931 932 /** 933 * __wlan_hdd_cfg80211_vendor_scan() - API to process venor scan request 934 * @wiphy: Pointer to wiphy 935 * @wdev: Pointer to net device 936 * @data : Pointer to the data 937 * @data_len : length of the data 938 * 939 * API to process venor scan request. 940 * 941 * Return: return 0 on success and negative error code on failure 942 */ 943 static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, 944 struct wireless_dev *wdev, const void *data, 945 int data_len) 946 { 947 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1]; 948 struct cfg80211_scan_request *request = NULL; 949 struct nlattr *attr; 950 enum nl80211_band band; 951 uint32_t n_channels = 0, n_ssid = 0; 952 uint32_t count, j; 953 int tmp; 954 size_t len, ie_len = 0; 955 struct ieee80211_channel *chan; 956 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 957 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev); 958 int ret; 959 960 hdd_enter_dev(wdev->netdev); 961 962 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 963 hdd_err("Command not allowed in FTM mode"); 964 return -EPERM; 965 } 966 967 ret = wlan_hdd_validate_context(hdd_ctx); 968 if (ret) { 969 /* 970 * During SSR, if -EBUSY is returned then OBSS vendor scan is 971 * not issued immediately. 972 */ 973 if (ret == -EAGAIN) 974 return -EBUSY; 975 976 return ret; 977 } 978 979 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, 980 data, data_len, scan_policy)) { 981 hdd_err("Invalid ATTR"); 982 return -EINVAL; 983 } 984 985 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) { 986 nla_for_each_nested(attr, 987 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], tmp) 988 n_channels++; 989 } else { 990 for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) 991 if (wiphy->bands[band]) 992 n_channels += wiphy->bands[band]->n_channels; 993 } 994 995 if (n_channels > NUM_CHANNELS) { 996 hdd_err("Exceed max number of channels: %d", n_channels); 997 return -EINVAL; 998 } 999 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) 1000 nla_for_each_nested(attr, 1001 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], tmp) 1002 n_ssid++; 1003 1004 if (MAX_SCAN_SSID < n_ssid) { 1005 hdd_err("Exceed max number of SSID: %d", n_ssid); 1006 return -EINVAL; 1007 } 1008 1009 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]) 1010 ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]); 1011 1012 len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) + 1013 (sizeof(*request->channels) * n_channels) + ie_len; 1014 1015 request = qdf_mem_malloc(len); 1016 if (!request) 1017 goto error; 1018 if (n_ssid) 1019 request->ssids = (void *)&request->channels[n_channels]; 1020 request->n_ssids = n_ssid; 1021 if (ie_len) { 1022 if (request->ssids) 1023 request->ie = (void *)(request->ssids + n_ssid); 1024 else 1025 request->ie = (void *)(request->channels + n_channels); 1026 } 1027 1028 request->ie_len = ie_len; 1029 count = 0; 1030 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) { 1031 nla_for_each_nested(attr, 1032 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], 1033 tmp) { 1034 if (nla_len(attr) != sizeof(uint32_t)) { 1035 hdd_err("len is not correct for frequency %d", 1036 count); 1037 goto error; 1038 } 1039 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); 1040 if (!chan) 1041 goto error; 1042 if (chan->flags & IEEE80211_CHAN_DISABLED) 1043 continue; 1044 request->channels[count] = chan; 1045 count++; 1046 } 1047 } else { 1048 for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) { 1049 if (!wiphy->bands[band]) 1050 continue; 1051 for (j = 0; j < wiphy->bands[band]->n_channels; 1052 j++) { 1053 chan = &wiphy->bands[band]->channels[j]; 1054 if (chan->flags & IEEE80211_CHAN_DISABLED) 1055 continue; 1056 request->channels[count] = chan; 1057 count++; 1058 } 1059 } 1060 } 1061 1062 if (!count) 1063 goto error; 1064 1065 request->n_channels = count; 1066 count = 0; 1067 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) { 1068 int ssid_length; 1069 1070 nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], 1071 tmp) { 1072 ssid_length = nla_len(attr); 1073 if ((ssid_length > WLAN_SSID_MAX_LEN) || 1074 (ssid_length < 0)) { 1075 hdd_err("SSID Len %d is not correct for network %d", 1076 ssid_length, count); 1077 goto error; 1078 } 1079 1080 request->ssids[count].ssid_len = ssid_length; 1081 memcpy(request->ssids[count].ssid, nla_data(attr), 1082 ssid_length); 1083 count++; 1084 } 1085 } 1086 1087 if (ie_len) 1088 nla_memcpy((void *)request->ie, 1089 tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE], ie_len); 1090 1091 for (count = 0; count < HDD_NUM_NL80211_BANDS; count++) 1092 if (wiphy->bands[count]) 1093 request->rates[count] = 1094 (1 << wiphy->bands[count]->n_bitrates) - 1; 1095 1096 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES]) { 1097 nla_for_each_nested(attr, 1098 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES], 1099 tmp) { 1100 band = nla_type(attr); 1101 if (band >= HDD_NUM_NL80211_BANDS) 1102 continue; 1103 if (!wiphy->bands[band]) 1104 continue; 1105 request->rates[band] = 1106 wlan_hdd_get_rates(wiphy, 1107 band, nla_data(attr), 1108 nla_len(attr)); 1109 } 1110 } 1111 1112 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]) { 1113 request->flags = 1114 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]); 1115 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 1116 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { 1117 hdd_err("LOW PRIORITY SCAN not supported"); 1118 goto error; 1119 } 1120 1121 if (wlan_hdd_vendor_scan_random_attr(wiphy, request, 1122 adapter, tb)) 1123 goto error; 1124 } 1125 1126 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) { 1127 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) < 1128 QDF_MAC_ADDR_SIZE) { 1129 hdd_err("invalid bssid length"); 1130 goto error; 1131 } 1132 wlan_hdd_copy_bssid(request, 1133 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID])); 1134 } 1135 1136 /* Check if external acs was requested on this adapter */ 1137 hdd_process_vendor_acs_response(adapter); 1138 1139 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]) 1140 request->no_cck = 1141 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]); 1142 request->wdev = wdev; 1143 request->wiphy = wiphy; 1144 request->scan_start = jiffies; 1145 1146 ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN); 1147 if (0 != ret) { 1148 hdd_err("Scan Failed. Ret = %d", ret); 1149 qdf_mem_free(request); 1150 return ret; 1151 } 1152 ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request); 1153 1154 return ret; 1155 error: 1156 hdd_err("Scan Request Failed"); 1157 qdf_mem_free(request); 1158 return -EINVAL; 1159 } 1160 1161 /** 1162 * wlan_hdd_cfg80211_vendor_scan() -API to process venor scan request 1163 * @wiphy: Pointer to wiphy 1164 * @wdev: Pointer to wireless device 1165 * @data: Pointer to the data 1166 * @data_len: length of the data 1167 * 1168 * This is called from userspace to request scan. 1169 * 1170 * Return: Return the Success or Failure code. 1171 */ 1172 int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, 1173 struct wireless_dev *wdev, const void *data, 1174 int data_len) 1175 { 1176 int errno; 1177 struct osif_vdev_sync *vdev_sync; 1178 1179 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); 1180 if (errno) 1181 return errno; 1182 1183 errno = __wlan_hdd_cfg80211_vendor_scan(wiphy, wdev, data, data_len); 1184 1185 osif_vdev_sync_op_stop(vdev_sync); 1186 1187 return errno; 1188 } 1189 1190 /** 1191 * __wlan_hdd_vendor_abort_scan() - API to process vendor command for 1192 * abort scan 1193 * @wiphy: Pointer to wiphy 1194 * @data: Pointer to the data 1195 * @data_len: length of the data 1196 * 1197 * API to process vendor abort scan 1198 * 1199 * Return: zero for success and non zero for failure 1200 */ 1201 static int __wlan_hdd_vendor_abort_scan( 1202 struct wiphy *wiphy, const void *data, 1203 int data_len) 1204 { 1205 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 1206 int ret; 1207 1208 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 1209 hdd_err("Command not allowed in FTM mode"); 1210 return -EINVAL; 1211 } 1212 1213 ret = wlan_hdd_validate_context(hdd_ctx); 1214 if (0 != ret) 1215 return ret; 1216 1217 wlan_vendor_abort_scan(hdd_ctx->pdev, data, data_len); 1218 1219 return ret; 1220 } 1221 1222 /** 1223 * wlan_hdd_vendor_abort_scan() - API to process vendor command for 1224 * abort scan 1225 * @wiphy: Pointer to wiphy 1226 * @wdev: Pointer to net device 1227 * @data : Pointer to the data 1228 * @data_len : length of the data 1229 * 1230 * This is called from supplicant to abort scan 1231 * 1232 * Return: zero for success and non zero for failure 1233 */ 1234 int wlan_hdd_vendor_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev, 1235 const void *data, int data_len) 1236 { 1237 struct osif_vdev_sync *vdev_sync; 1238 int errno; 1239 1240 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); 1241 if (errno) 1242 return errno; 1243 1244 errno = __wlan_hdd_vendor_abort_scan(wiphy, data, data_len); 1245 1246 osif_vdev_sync_op_stop(vdev_sync); 1247 1248 return errno; 1249 } 1250 1251 int wlan_hdd_scan_abort(struct wlan_hdd_link_info *link_info) 1252 { 1253 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 1254 1255 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 1256 link_info->vdev_id, INVALID_SCAN_ID, true); 1257 1258 return 0; 1259 } 1260 1261 #ifdef FEATURE_WLAN_SCAN_PNO 1262 /** 1263 * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start 1264 * @wiphy: Pointer to wiphy 1265 * @dev: Pointer network device 1266 * @request: Pointer to cfg80211 scheduled scan start request 1267 * 1268 * Return: 0 for success, non zero for failure 1269 */ 1270 static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, 1271 struct net_device *dev, 1272 struct 1273 cfg80211_sched_scan_request 1274 *request) 1275 { 1276 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1277 struct hdd_context *hdd_ctx; 1278 struct wlan_objmgr_vdev *vdev; 1279 int ret; 1280 bool pno_offload_enabled; 1281 uint8_t scan_backoff_multiplier; 1282 bool enable_connected_scan; 1283 enum QDF_GLOBAL_MODE curr_mode; 1284 1285 curr_mode = hdd_get_conparam(); 1286 1287 if (QDF_GLOBAL_FTM_MODE == curr_mode || 1288 QDF_GLOBAL_MONITOR_MODE == curr_mode) { 1289 hdd_err_rl("Command not allowed in FTM/Monitor mode"); 1290 return -EINVAL; 1291 } 1292 1293 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1294 return -EINVAL; 1295 1296 if (adapter->device_mode != QDF_STA_MODE) { 1297 hdd_info("Sched scans only supported on STA ifaces"); 1298 return -EINVAL; 1299 } 1300 1301 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1302 ret = wlan_hdd_validate_context(hdd_ctx); 1303 if (ret) 1304 return ret; 1305 1306 pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc); 1307 if (!pno_offload_enabled) { 1308 hdd_debug("Pno Offload is not enabled"); 1309 return -EINVAL; 1310 } 1311 1312 enable_connected_scan = ucfg_scan_is_connected_scan_enabled( 1313 hdd_ctx->psoc); 1314 if (!enable_connected_scan && 1315 hdd_cm_is_vdev_associated(adapter->deflink)) { 1316 hdd_info("enable_connected_scan is false, Aborting scan"); 1317 return -EBUSY; 1318 } 1319 1320 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID); 1321 if (!vdev) 1322 return -EINVAL; 1323 1324 scan_backoff_multiplier = 1325 ucfg_get_scan_backoff_multiplier(hdd_ctx->psoc); 1326 ret = wlan_cfg80211_sched_scan_start(vdev, request, 1327 scan_backoff_multiplier); 1328 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 1329 1330 return ret; 1331 } 1332 1333 /** 1334 * wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start 1335 * @wiphy: Pointer to wiphy 1336 * @dev: Pointer network device 1337 * @request: Pointer to cfg80211 scheduled scan start request 1338 * 1339 * Return: 0 for success, non zero for failure 1340 */ 1341 int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, 1342 struct net_device *dev, 1343 struct cfg80211_sched_scan_request 1344 *request) 1345 { 1346 int errno; 1347 struct osif_vdev_sync *vdev_sync; 1348 1349 errno = osif_vdev_sync_op_start(dev, &vdev_sync); 1350 if (errno) 1351 return errno; 1352 1353 errno = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request); 1354 1355 osif_vdev_sync_op_stop(vdev_sync); 1356 1357 return errno; 1358 } 1359 1360 int wlan_hdd_sched_scan_stop(struct net_device *dev) 1361 { 1362 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1363 struct hdd_context *hdd_ctx; 1364 struct wlan_objmgr_vdev *vdev; 1365 int ret; 1366 bool pno_offload_enabled; 1367 1368 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 1369 hdd_err("Command not allowed in FTM mode"); 1370 return -EINVAL; 1371 } 1372 1373 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1374 return -EINVAL; 1375 1376 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1377 if (!hdd_ctx) { 1378 hdd_err("HDD context is Null"); 1379 return -EINVAL; 1380 } 1381 1382 pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc); 1383 if (!pno_offload_enabled) { 1384 hdd_debug("PnoOffload is not enabled!!!"); 1385 return -EINVAL; 1386 } 1387 1388 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID); 1389 if (!vdev) 1390 return -EINVAL; 1391 ret = wlan_cfg80211_sched_scan_stop(vdev); 1392 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 1393 1394 return ret; 1395 } 1396 1397 /** 1398 * __wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled scan(pno) 1399 * @dev: Pointer network device 1400 * 1401 * This is a wrapper around wlan_hdd_sched_scan_stop() that returns success 1402 * in the event that the driver is currently recovering or unloading. This 1403 * prevents a race condition where we get a scan stop from kernel during 1404 * a driver unload from PLD. 1405 * 1406 * Return: 0 for success, non zero for failure 1407 */ 1408 static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev) 1409 { 1410 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1411 int errno; 1412 enum QDF_GLOBAL_MODE curr_mode; 1413 1414 curr_mode = hdd_get_conparam(); 1415 1416 if (QDF_GLOBAL_FTM_MODE == curr_mode || 1417 QDF_GLOBAL_MONITOR_MODE == curr_mode) { 1418 hdd_err_rl("Command not allowed in FTM/Monitor mode"); 1419 return -EINVAL; 1420 } 1421 1422 /* The return 0 is intentional when Recovery and Load/Unload in 1423 * progress. We did observe a crash due to a return of 1424 * failure in sched_scan_stop , especially for a case where the unload 1425 * of the happens at the same time. The function 1426 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only 1427 * when the sched_scan_stop returns success. If it returns a failure , 1428 * then its next invocation due to the clean up of the second interface 1429 * will have the dev pointer corresponding to the first one leading to 1430 * a crash. 1431 */ 1432 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { 1433 hdd_info("Recovery in Progress. State: 0x%x Ignore!!!", 1434 cds_get_driver_state()); 1435 return 0; 1436 } 1437 1438 if (cds_is_load_or_unload_in_progress()) { 1439 hdd_info("Unload/Load in Progress, state: 0x%x. Ignore!!!", 1440 cds_get_driver_state()); 1441 return 0; 1442 } 1443 1444 errno = hdd_validate_adapter(adapter); 1445 if (errno) 1446 return errno; 1447 1448 if (adapter->device_mode != QDF_STA_MODE) { 1449 hdd_info("Sched scans only supported on STA ifaces"); 1450 return -EINVAL; 1451 } 1452 1453 errno = wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter)); 1454 if (errno) 1455 return errno; 1456 1457 errno = wlan_hdd_sched_scan_stop(dev); 1458 1459 return errno; 1460 } 1461 1462 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) 1463 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, 1464 struct net_device *dev) 1465 { 1466 int errno; 1467 struct osif_vdev_sync *vdev_sync; 1468 1469 errno = osif_vdev_sync_op_start(dev, &vdev_sync); 1470 if (errno) 1471 return errno; 1472 1473 errno = __wlan_hdd_cfg80211_sched_scan_stop(dev); 1474 1475 osif_vdev_sync_op_stop(vdev_sync); 1476 1477 /* The return 0 is intentional. We observed a crash due to a return of 1478 * failure in sched_scan_stop , especially for a case where the unload 1479 * of the happens at the same time. The function 1480 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only 1481 * when the sched_scan_stop returns success. If it returns a failure , 1482 * then its next invocation due to the clean up of the second interface 1483 * will have the dev pointer corresponding to the first one leading to 1484 * a crash. 1485 */ 1486 return 0; 1487 } 1488 #else 1489 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, 1490 struct net_device *dev, 1491 uint64_t reqid) 1492 { 1493 int errno; 1494 struct osif_vdev_sync *vdev_sync; 1495 1496 errno = osif_vdev_sync_op_start(dev, &vdev_sync); 1497 if (errno) 1498 return errno; 1499 1500 errno = __wlan_hdd_cfg80211_sched_scan_stop(dev); 1501 1502 osif_vdev_sync_op_stop(vdev_sync); 1503 1504 /* The return 0 is intentional. We observed a crash due to a return of 1505 * failure in sched_scan_stop , especially for a case where the unload 1506 * of the happens at the same time. The function 1507 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only 1508 * when the sched_scan_stop returns success. If it returns a failure , 1509 * then its next invocation due to the clean up of the second interface 1510 * will have the dev pointer corresponding to the first one leading to 1511 * a crash. 1512 */ 1513 return 0; 1514 } 1515 #endif /* KERNEL_VERSION(4, 12, 0) */ 1516 #endif /*FEATURE_WLAN_SCAN_PNO */ 1517 1518 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \ 1519 defined(CFG80211_ABORT_SCAN) 1520 /** 1521 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api 1522 * @wiphy: Pointer to wiphy 1523 * @wdev: Pointer to wireless device structure 1524 * 1525 * This function is used to abort an ongoing scan 1526 * 1527 * Return: None 1528 */ 1529 static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, 1530 struct wireless_dev *wdev) 1531 { 1532 struct net_device *dev = wdev->netdev; 1533 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1534 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 1535 int ret; 1536 1537 hdd_enter_dev(dev); 1538 1539 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 1540 hdd_err("Command not allowed in FTM mode"); 1541 return; 1542 } 1543 1544 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1545 return; 1546 1547 ret = wlan_hdd_validate_context(hdd_ctx); 1548 if (ret) 1549 return; 1550 1551 wlan_cfg80211_abort_scan(hdd_ctx->pdev); 1552 1553 hdd_exit(); 1554 } 1555 1556 /** 1557 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api 1558 * @wiphy: Pointer to wiphy 1559 * @wdev: Pointer to wireless device structure 1560 * 1561 * Wrapper to __wlan_hdd_cfg80211_abort_scan() - 1562 * function is used to abort an ongoing scan 1563 * 1564 * Return: None 1565 */ 1566 void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, 1567 struct wireless_dev *wdev) 1568 { 1569 struct osif_psoc_sync *psoc_sync; 1570 int errno; 1571 1572 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); 1573 if (errno) 1574 return; 1575 1576 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev); 1577 1578 osif_psoc_sync_op_stop(psoc_sync); 1579 } 1580 #endif 1581 1582 /** 1583 * hdd_scan_context_destroy() - Destroy scan context 1584 * @hdd_ctx: HDD context. 1585 * 1586 * Destroy scan context. 1587 * 1588 * Return: None. 1589 */ 1590 void hdd_scan_context_destroy(struct hdd_context *hdd_ctx) 1591 { 1592 } 1593 1594 /** 1595 * hdd_scan_context_init() - Initialize scan context 1596 * @hdd_ctx: HDD context. 1597 * 1598 * Initialize scan related resources like spin lock and lists. 1599 * 1600 * Return: 0 on success and errno on failure. 1601 */ 1602 int hdd_scan_context_init(struct hdd_context *hdd_ctx) 1603 { 1604 return 0; 1605 } 1606