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 status = wlan_cfg80211_scan(vdev, request, ¶ms); 677 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 678 error: 679 if (params.default_ie.ptr) 680 qdf_mem_free(params.default_ie.ptr); 681 682 return status; 683 } 684 685 #undef SCAN_FAILURE 686 687 /** 688 * wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request 689 * @wiphy: Pointer to wiphy 690 * @request: Pointer to scan request 691 * 692 * This API responds to scan trigger and update cfg80211 scan database 693 * later, scan dump command can be used to receive scan results 694 * 695 * Return: 0 for success, non zero for failure 696 */ 697 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy, 698 struct cfg80211_scan_request *request) 699 { 700 int errno; 701 struct osif_vdev_sync *vdev_sync; 702 703 errno = osif_vdev_sync_op_start(request->wdev->netdev, &vdev_sync); 704 if (errno) 705 return errno; 706 707 errno = __wlan_hdd_cfg80211_scan(wiphy, request, NL_SCAN); 708 709 osif_vdev_sync_op_stop(vdev_sync); 710 711 return errno; 712 } 713 714 /** 715 * wlan_hdd_get_rates() -API to get the rates from scan request 716 * @wiphy: Pointer to wiphy 717 * @band: Band 718 * @rates: array of rates 719 * @rate_count: number of rates 720 * 721 * Return: o for failure, rate bitmap for success 722 */ 723 static uint32_t wlan_hdd_get_rates(struct wiphy *wiphy, 724 enum nl80211_band band, 725 const u8 *rates, unsigned int rate_count) 726 { 727 uint32_t j, count, rate_bitmap = 0; 728 uint32_t rate; 729 bool found; 730 731 for (count = 0; count < rate_count; count++) { 732 rate = ((rates[count]) & RATE_MASK) * 5; 733 found = false; 734 for (j = 0; j < wiphy->bands[band]->n_bitrates; j++) { 735 if (wiphy->bands[band]->bitrates[j].bitrate == rate) { 736 found = true; 737 rate_bitmap |= (1 << j); 738 break; 739 } 740 } 741 if (!found) 742 return 0; 743 } 744 return rate_bitmap; 745 } 746 747 /** 748 * wlan_hdd_send_scan_start_event() -API to send the scan start event 749 * @wiphy: Pointer to wiphy 750 * @wdev: Pointer to net device 751 * @cookie: scan identifier 752 * 753 * Return: return 0 on success and negative error code on failure 754 */ 755 static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy, 756 struct wireless_dev *wdev, uint64_t cookie) 757 { 758 struct sk_buff *skb; 759 int ret; 760 enum qca_nl80211_vendor_subcmds_index index = 761 QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX; 762 763 skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) + 764 NLA_HDRLEN + NLMSG_HDRLEN); 765 if (!skb) { 766 hdd_err(" reply skb alloc failed"); 767 return -ENOMEM; 768 } 769 770 if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, 771 cookie)) { 772 hdd_err("nla put fail"); 773 wlan_cfg80211_vendor_free_skb(skb); 774 return -EINVAL; 775 } 776 777 ret = wlan_cfg80211_vendor_cmd_reply(skb); 778 779 /* Send a scan started event to supplicant */ 780 skb = wlan_cfg80211_vendor_event_alloc(wiphy, wdev, 781 sizeof(u64) + 4 + NLMSG_HDRLEN, 782 index, GFP_KERNEL); 783 if (!skb) { 784 hdd_err("skb alloc failed"); 785 return -ENOMEM; 786 } 787 788 if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, 789 cookie)) { 790 wlan_cfg80211_vendor_free_skb(skb); 791 return -EINVAL; 792 } 793 794 wlan_cfg80211_vendor_event(skb, GFP_KERNEL); 795 return ret; 796 } 797 798 /** 799 * wlan_hdd_copy_bssid() - API to copy the bssid to vendor Scan request 800 * @request: Pointer to vendor scan request 801 * @bssid: Pointer to BSSID 802 * 803 * This API copies the specific BSSID received from Supplicant and copies it to 804 * the vendor Scan request 805 * 806 * Return: None 807 */ 808 #if defined(CFG80211_SCAN_BSSID) || \ 809 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) 810 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request, 811 uint8_t *bssid) 812 { 813 qdf_mem_copy(request->bssid, bssid, QDF_MAC_ADDR_SIZE); 814 } 815 #else 816 static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request, 817 uint8_t *bssid) 818 { 819 } 820 #endif 821 822 static void hdd_process_vendor_acs_response(struct hdd_adapter *adapter) 823 { 824 qdf_mc_timer_t *vendor_acs_timer; 825 826 if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, 827 &adapter->deflink->link_flags)) { 828 return; 829 } 830 831 vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer; 832 if (QDF_TIMER_STATE_RUNNING == 833 qdf_mc_timer_get_current_state(vendor_acs_timer)) { 834 qdf_mc_timer_stop(vendor_acs_timer); 835 } 836 } 837 838 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ 839 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 840 /** 841 * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs 842 * @wiphy: Pointer to wiphy 843 * @request: Pointer to scan request 844 * @adapter: Pointer to hdd adapter 845 * @tb: Pointer to nl attributes 846 * 847 * This function is invoked to check whether vendor scan needs 848 * probe req source addr, if so populates mac_addr and mac_addr_mask 849 * in scan request with nl attrs. 850 * 851 * Return: 0 - on success, negative value on failure 852 */ 853 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, 854 struct cfg80211_scan_request *request, 855 struct hdd_adapter *adapter, 856 struct nlattr **tb) 857 { 858 uint32_t i; 859 int32_t len = QDF_MAC_ADDR_SIZE; 860 861 if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) 862 return 0; 863 864 if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) || 865 (hdd_cm_is_vdev_connected(adapter->deflink))) { 866 hdd_err("SCAN RANDOMIZATION not supported"); 867 return -EOPNOTSUPP; 868 } 869 870 if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] && 871 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) { 872 qdf_mem_zero(request->mac_addr, len); 873 qdf_mem_zero(request->mac_addr_mask, len); 874 request->mac_addr[0] = 0x2; 875 request->mac_addr_mask[0] = 0x3; 876 877 return 0; 878 } 879 880 if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] || 881 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) 882 return -EINVAL; 883 884 if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) || 885 (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len)) 886 return -EINVAL; 887 888 qdf_mem_copy(request->mac_addr, 889 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len); 890 891 qdf_mem_copy(request->mac_addr_mask, 892 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len); 893 894 /* avoid configure on multicast address */ 895 if (!cds_is_group_addr(request->mac_addr_mask) || 896 cds_is_group_addr(request->mac_addr)) 897 return -EINVAL; 898 899 for (i = 0; i < ETH_ALEN; i++) 900 request->mac_addr[i] &= request->mac_addr_mask[i]; 901 902 return 0; 903 } 904 #else 905 static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, 906 struct cfg80211_scan_request *request, 907 struct hdd_adapter *adapter, 908 struct nlattr **tb) 909 { 910 return 0; 911 } 912 #endif 913 914 const 915 struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = { 916 [QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32}, 917 [QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG}, 918 [QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64}, 919 [QCA_WLAN_VENDOR_ATTR_SCAN_IE] = {.type = NLA_BINARY, 920 .len = MAX_DEFAULT_SCAN_IE_LEN}, 921 [QCA_WLAN_VENDOR_ATTR_SCAN_MAC] = VENDOR_NLA_POLICY_MAC_ADDR, 922 [QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK] = VENDOR_NLA_POLICY_MAC_ADDR, 923 [QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES] = {.type = NLA_NESTED}, 924 [QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS] = {.type = NLA_NESTED}, 925 [QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES] = {.type = NLA_NESTED}, 926 [QCA_WLAN_VENDOR_ATTR_SCAN_BSSID] = {.type = NLA_BINARY}, 927 }; 928 929 /** 930 * __wlan_hdd_cfg80211_vendor_scan() - API to process venor scan request 931 * @wiphy: Pointer to wiphy 932 * @wdev: Pointer to net device 933 * @data : Pointer to the data 934 * @data_len : length of the data 935 * 936 * API to process venor scan request. 937 * 938 * Return: return 0 on success and negative error code on failure 939 */ 940 static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, 941 struct wireless_dev *wdev, const void *data, 942 int data_len) 943 { 944 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1]; 945 struct cfg80211_scan_request *request = NULL; 946 struct nlattr *attr; 947 enum nl80211_band band; 948 uint32_t n_channels = 0, n_ssid = 0; 949 uint32_t count, j; 950 int tmp; 951 size_t len, ie_len = 0; 952 struct ieee80211_channel *chan; 953 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 954 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev); 955 int ret; 956 957 hdd_enter_dev(wdev->netdev); 958 959 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 960 hdd_err("Command not allowed in FTM mode"); 961 return -EPERM; 962 } 963 964 ret = wlan_hdd_validate_context(hdd_ctx); 965 if (ret) { 966 /* 967 * During SSR, if -EBUSY is returned then OBSS vendor scan is 968 * not issued immediately. 969 */ 970 if (ret == -EAGAIN) 971 return -EBUSY; 972 973 return ret; 974 } 975 976 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, 977 data, data_len, scan_policy)) { 978 hdd_err("Invalid ATTR"); 979 return -EINVAL; 980 } 981 982 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) { 983 nla_for_each_nested(attr, 984 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], tmp) 985 n_channels++; 986 } else { 987 for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) 988 if (wiphy->bands[band]) 989 n_channels += wiphy->bands[band]->n_channels; 990 } 991 992 if (n_channels > NUM_CHANNELS) { 993 hdd_err("Exceed max number of channels: %d", n_channels); 994 return -EINVAL; 995 } 996 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) 997 nla_for_each_nested(attr, 998 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], tmp) 999 n_ssid++; 1000 1001 if (MAX_SCAN_SSID < n_ssid) { 1002 hdd_err("Exceed max number of SSID: %d", n_ssid); 1003 return -EINVAL; 1004 } 1005 1006 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]) 1007 ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]); 1008 1009 len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) + 1010 (sizeof(*request->channels) * n_channels) + ie_len; 1011 1012 request = qdf_mem_malloc(len); 1013 if (!request) 1014 goto error; 1015 if (n_ssid) 1016 request->ssids = (void *)&request->channels[n_channels]; 1017 request->n_ssids = n_ssid; 1018 if (ie_len) { 1019 if (request->ssids) 1020 request->ie = (void *)(request->ssids + n_ssid); 1021 else 1022 request->ie = (void *)(request->channels + n_channels); 1023 } 1024 1025 request->ie_len = ie_len; 1026 count = 0; 1027 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) { 1028 nla_for_each_nested(attr, 1029 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], 1030 tmp) { 1031 if (nla_len(attr) != sizeof(uint32_t)) { 1032 hdd_err("len is not correct for frequency %d", 1033 count); 1034 goto error; 1035 } 1036 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); 1037 if (!chan) 1038 goto error; 1039 if (chan->flags & IEEE80211_CHAN_DISABLED) 1040 continue; 1041 request->channels[count] = chan; 1042 count++; 1043 } 1044 } else { 1045 for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) { 1046 if (!wiphy->bands[band]) 1047 continue; 1048 for (j = 0; j < wiphy->bands[band]->n_channels; 1049 j++) { 1050 chan = &wiphy->bands[band]->channels[j]; 1051 if (chan->flags & IEEE80211_CHAN_DISABLED) 1052 continue; 1053 request->channels[count] = chan; 1054 count++; 1055 } 1056 } 1057 } 1058 1059 if (!count) 1060 goto error; 1061 1062 request->n_channels = count; 1063 count = 0; 1064 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) { 1065 int ssid_length; 1066 1067 nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], 1068 tmp) { 1069 ssid_length = nla_len(attr); 1070 if ((ssid_length > WLAN_SSID_MAX_LEN) || 1071 (ssid_length < 0)) { 1072 hdd_err("SSID Len %d is not correct for network %d", 1073 ssid_length, count); 1074 goto error; 1075 } 1076 1077 request->ssids[count].ssid_len = ssid_length; 1078 memcpy(request->ssids[count].ssid, nla_data(attr), 1079 ssid_length); 1080 count++; 1081 } 1082 } 1083 1084 if (ie_len) 1085 nla_memcpy((void *)request->ie, 1086 tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE], ie_len); 1087 1088 for (count = 0; count < HDD_NUM_NL80211_BANDS; count++) 1089 if (wiphy->bands[count]) 1090 request->rates[count] = 1091 (1 << wiphy->bands[count]->n_bitrates) - 1; 1092 1093 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES]) { 1094 nla_for_each_nested(attr, 1095 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES], 1096 tmp) { 1097 band = nla_type(attr); 1098 if (band >= HDD_NUM_NL80211_BANDS) 1099 continue; 1100 if (!wiphy->bands[band]) 1101 continue; 1102 request->rates[band] = 1103 wlan_hdd_get_rates(wiphy, 1104 band, nla_data(attr), 1105 nla_len(attr)); 1106 } 1107 } 1108 1109 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]) { 1110 request->flags = 1111 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]); 1112 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 1113 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { 1114 hdd_err("LOW PRIORITY SCAN not supported"); 1115 goto error; 1116 } 1117 1118 if (wlan_hdd_vendor_scan_random_attr(wiphy, request, 1119 adapter, tb)) 1120 goto error; 1121 } 1122 1123 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) { 1124 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) < 1125 QDF_MAC_ADDR_SIZE) { 1126 hdd_err("invalid bssid length"); 1127 goto error; 1128 } 1129 wlan_hdd_copy_bssid(request, 1130 nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID])); 1131 } 1132 1133 /* Check if external acs was requested on this adapter */ 1134 hdd_process_vendor_acs_response(adapter); 1135 1136 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]) 1137 request->no_cck = 1138 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]); 1139 request->wdev = wdev; 1140 request->wiphy = wiphy; 1141 request->scan_start = jiffies; 1142 1143 ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN); 1144 if (0 != ret) { 1145 hdd_err("Scan Failed. Ret = %d", ret); 1146 qdf_mem_free(request); 1147 return ret; 1148 } 1149 ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request); 1150 1151 return ret; 1152 error: 1153 hdd_err("Scan Request Failed"); 1154 qdf_mem_free(request); 1155 return -EINVAL; 1156 } 1157 1158 /** 1159 * wlan_hdd_cfg80211_vendor_scan() -API to process venor scan request 1160 * @wiphy: Pointer to wiphy 1161 * @wdev: Pointer to wireless device 1162 * @data: Pointer to the data 1163 * @data_len: length of the data 1164 * 1165 * This is called from userspace to request scan. 1166 * 1167 * Return: Return the Success or Failure code. 1168 */ 1169 int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, 1170 struct wireless_dev *wdev, const void *data, 1171 int data_len) 1172 { 1173 int errno; 1174 struct osif_vdev_sync *vdev_sync; 1175 1176 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); 1177 if (errno) 1178 return errno; 1179 1180 errno = __wlan_hdd_cfg80211_vendor_scan(wiphy, wdev, data, data_len); 1181 1182 osif_vdev_sync_op_stop(vdev_sync); 1183 1184 return errno; 1185 } 1186 1187 /** 1188 * __wlan_hdd_vendor_abort_scan() - API to process vendor command for 1189 * abort scan 1190 * @wiphy: Pointer to wiphy 1191 * @data: Pointer to the data 1192 * @data_len: length of the data 1193 * 1194 * API to process vendor abort scan 1195 * 1196 * Return: zero for success and non zero for failure 1197 */ 1198 static int __wlan_hdd_vendor_abort_scan( 1199 struct wiphy *wiphy, const void *data, 1200 int data_len) 1201 { 1202 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 1203 int ret; 1204 1205 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 1206 hdd_err("Command not allowed in FTM mode"); 1207 return -EINVAL; 1208 } 1209 1210 ret = wlan_hdd_validate_context(hdd_ctx); 1211 if (0 != ret) 1212 return ret; 1213 1214 wlan_vendor_abort_scan(hdd_ctx->pdev, data, data_len); 1215 1216 return ret; 1217 } 1218 1219 /** 1220 * wlan_hdd_vendor_abort_scan() - API to process vendor command for 1221 * abort scan 1222 * @wiphy: Pointer to wiphy 1223 * @wdev: Pointer to net device 1224 * @data : Pointer to the data 1225 * @data_len : length of the data 1226 * 1227 * This is called from supplicant to abort scan 1228 * 1229 * Return: zero for success and non zero for failure 1230 */ 1231 int wlan_hdd_vendor_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev, 1232 const void *data, int data_len) 1233 { 1234 struct osif_vdev_sync *vdev_sync; 1235 int errno; 1236 1237 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); 1238 if (errno) 1239 return errno; 1240 1241 errno = __wlan_hdd_vendor_abort_scan(wiphy, data, data_len); 1242 1243 osif_vdev_sync_op_stop(vdev_sync); 1244 1245 return errno; 1246 } 1247 1248 int wlan_hdd_scan_abort(struct wlan_hdd_link_info *link_info) 1249 { 1250 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 1251 1252 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 1253 link_info->vdev_id, INVALID_SCAN_ID, true); 1254 1255 return 0; 1256 } 1257 1258 #ifdef FEATURE_WLAN_SCAN_PNO 1259 /** 1260 * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start 1261 * @wiphy: Pointer to wiphy 1262 * @dev: Pointer network device 1263 * @request: Pointer to cfg80211 scheduled scan start request 1264 * 1265 * Return: 0 for success, non zero for failure 1266 */ 1267 static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, 1268 struct net_device *dev, 1269 struct 1270 cfg80211_sched_scan_request 1271 *request) 1272 { 1273 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1274 struct hdd_context *hdd_ctx; 1275 struct wlan_objmgr_vdev *vdev; 1276 int ret; 1277 bool pno_offload_enabled; 1278 uint8_t scan_backoff_multiplier; 1279 bool enable_connected_scan; 1280 enum QDF_GLOBAL_MODE curr_mode; 1281 1282 curr_mode = hdd_get_conparam(); 1283 1284 if (QDF_GLOBAL_FTM_MODE == curr_mode || 1285 QDF_GLOBAL_MONITOR_MODE == curr_mode) { 1286 hdd_err_rl("Command not allowed in FTM/Monitor mode"); 1287 return -EINVAL; 1288 } 1289 1290 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1291 return -EINVAL; 1292 1293 if (adapter->device_mode != QDF_STA_MODE) { 1294 hdd_info("Sched scans only supported on STA ifaces"); 1295 return -EINVAL; 1296 } 1297 1298 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1299 ret = wlan_hdd_validate_context(hdd_ctx); 1300 if (ret) 1301 return ret; 1302 1303 pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc); 1304 if (!pno_offload_enabled) { 1305 hdd_debug("Pno Offload is not enabled"); 1306 return -EINVAL; 1307 } 1308 1309 enable_connected_scan = ucfg_scan_is_connected_scan_enabled( 1310 hdd_ctx->psoc); 1311 if (!enable_connected_scan && 1312 hdd_cm_is_vdev_associated(adapter->deflink)) { 1313 hdd_info("enable_connected_scan is false, Aborting scan"); 1314 return -EBUSY; 1315 } 1316 1317 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID); 1318 if (!vdev) 1319 return -EINVAL; 1320 1321 scan_backoff_multiplier = 1322 ucfg_get_scan_backoff_multiplier(hdd_ctx->psoc); 1323 ret = wlan_cfg80211_sched_scan_start(vdev, request, 1324 scan_backoff_multiplier); 1325 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 1326 1327 return ret; 1328 } 1329 1330 /** 1331 * wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start 1332 * @wiphy: Pointer to wiphy 1333 * @dev: Pointer network device 1334 * @request: Pointer to cfg80211 scheduled scan start request 1335 * 1336 * Return: 0 for success, non zero for failure 1337 */ 1338 int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, 1339 struct net_device *dev, 1340 struct cfg80211_sched_scan_request 1341 *request) 1342 { 1343 int errno; 1344 struct osif_vdev_sync *vdev_sync; 1345 1346 errno = osif_vdev_sync_op_start(dev, &vdev_sync); 1347 if (errno) 1348 return errno; 1349 1350 errno = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request); 1351 1352 osif_vdev_sync_op_stop(vdev_sync); 1353 1354 return errno; 1355 } 1356 1357 int wlan_hdd_sched_scan_stop(struct net_device *dev) 1358 { 1359 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1360 struct hdd_context *hdd_ctx; 1361 struct wlan_objmgr_vdev *vdev; 1362 int ret; 1363 bool pno_offload_enabled; 1364 1365 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 1366 hdd_err("Command not allowed in FTM mode"); 1367 return -EINVAL; 1368 } 1369 1370 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1371 return -EINVAL; 1372 1373 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1374 if (!hdd_ctx) { 1375 hdd_err("HDD context is Null"); 1376 return -EINVAL; 1377 } 1378 1379 pno_offload_enabled = ucfg_scan_is_pno_offload_enabled(hdd_ctx->psoc); 1380 if (!pno_offload_enabled) { 1381 hdd_debug("PnoOffload is not enabled!!!"); 1382 return -EINVAL; 1383 } 1384 1385 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_SCAN_ID); 1386 if (!vdev) 1387 return -EINVAL; 1388 ret = wlan_cfg80211_sched_scan_stop(vdev); 1389 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 1390 1391 return ret; 1392 } 1393 1394 /** 1395 * __wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled scan(pno) 1396 * @dev: Pointer network device 1397 * 1398 * This is a wrapper around wlan_hdd_sched_scan_stop() that returns success 1399 * in the event that the driver is currently recovering or unloading. This 1400 * prevents a race condition where we get a scan stop from kernel during 1401 * a driver unload from PLD. 1402 * 1403 * Return: 0 for success, non zero for failure 1404 */ 1405 static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev) 1406 { 1407 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1408 int errno; 1409 enum QDF_GLOBAL_MODE curr_mode; 1410 1411 curr_mode = hdd_get_conparam(); 1412 1413 if (QDF_GLOBAL_FTM_MODE == curr_mode || 1414 QDF_GLOBAL_MONITOR_MODE == curr_mode) { 1415 hdd_err_rl("Command not allowed in FTM/Monitor mode"); 1416 return -EINVAL; 1417 } 1418 1419 /* The return 0 is intentional when Recovery and Load/Unload in 1420 * progress. We did observe a crash due to a return of 1421 * failure in sched_scan_stop , especially for a case where the unload 1422 * of the happens at the same time. The function 1423 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only 1424 * when the sched_scan_stop returns success. If it returns a failure , 1425 * then its next invocation due to the clean up of the second interface 1426 * will have the dev pointer corresponding to the first one leading to 1427 * a crash. 1428 */ 1429 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { 1430 hdd_info("Recovery in Progress. State: 0x%x Ignore!!!", 1431 cds_get_driver_state()); 1432 return 0; 1433 } 1434 1435 if (cds_is_load_or_unload_in_progress()) { 1436 hdd_info("Unload/Load in Progress, state: 0x%x. Ignore!!!", 1437 cds_get_driver_state()); 1438 return 0; 1439 } 1440 1441 errno = hdd_validate_adapter(adapter); 1442 if (errno) 1443 return errno; 1444 1445 if (adapter->device_mode != QDF_STA_MODE) { 1446 hdd_info("Sched scans only supported on STA ifaces"); 1447 return -EINVAL; 1448 } 1449 1450 errno = wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter)); 1451 if (errno) 1452 return errno; 1453 1454 errno = wlan_hdd_sched_scan_stop(dev); 1455 1456 return errno; 1457 } 1458 1459 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) 1460 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, 1461 struct net_device *dev) 1462 { 1463 int errno; 1464 struct osif_vdev_sync *vdev_sync; 1465 1466 errno = osif_vdev_sync_op_start(dev, &vdev_sync); 1467 if (errno) 1468 return errno; 1469 1470 errno = __wlan_hdd_cfg80211_sched_scan_stop(dev); 1471 1472 osif_vdev_sync_op_stop(vdev_sync); 1473 1474 /* The return 0 is intentional. We observed a crash due to a return of 1475 * failure in sched_scan_stop , especially for a case where the unload 1476 * of the happens at the same time. The function 1477 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only 1478 * when the sched_scan_stop returns success. If it returns a failure , 1479 * then its next invocation due to the clean up of the second interface 1480 * will have the dev pointer corresponding to the first one leading to 1481 * a crash. 1482 */ 1483 return 0; 1484 } 1485 #else 1486 int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, 1487 struct net_device *dev, 1488 uint64_t reqid) 1489 { 1490 int errno; 1491 struct osif_vdev_sync *vdev_sync; 1492 1493 errno = osif_vdev_sync_op_start(dev, &vdev_sync); 1494 if (errno) 1495 return errno; 1496 1497 errno = __wlan_hdd_cfg80211_sched_scan_stop(dev); 1498 1499 osif_vdev_sync_op_stop(vdev_sync); 1500 1501 /* The return 0 is intentional. We observed a crash due to a return of 1502 * failure in sched_scan_stop , especially for a case where the unload 1503 * of the happens at the same time. The function 1504 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only 1505 * when the sched_scan_stop returns success. If it returns a failure , 1506 * then its next invocation due to the clean up of the second interface 1507 * will have the dev pointer corresponding to the first one leading to 1508 * a crash. 1509 */ 1510 return 0; 1511 } 1512 #endif /* KERNEL_VERSION(4, 12, 0) */ 1513 #endif /*FEATURE_WLAN_SCAN_PNO */ 1514 1515 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \ 1516 defined(CFG80211_ABORT_SCAN) 1517 /** 1518 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api 1519 * @wiphy: Pointer to wiphy 1520 * @wdev: Pointer to wireless device structure 1521 * 1522 * This function is used to abort an ongoing scan 1523 * 1524 * Return: None 1525 */ 1526 static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, 1527 struct wireless_dev *wdev) 1528 { 1529 struct net_device *dev = wdev->netdev; 1530 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 1531 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 1532 int ret; 1533 1534 hdd_enter_dev(dev); 1535 1536 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 1537 hdd_err("Command not allowed in FTM mode"); 1538 return; 1539 } 1540 1541 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1542 return; 1543 1544 ret = wlan_hdd_validate_context(hdd_ctx); 1545 if (ret) 1546 return; 1547 1548 wlan_cfg80211_abort_scan(hdd_ctx->pdev); 1549 1550 hdd_exit(); 1551 } 1552 1553 /** 1554 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api 1555 * @wiphy: Pointer to wiphy 1556 * @wdev: Pointer to wireless device structure 1557 * 1558 * Wrapper to __wlan_hdd_cfg80211_abort_scan() - 1559 * function is used to abort an ongoing scan 1560 * 1561 * Return: None 1562 */ 1563 void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, 1564 struct wireless_dev *wdev) 1565 { 1566 struct osif_psoc_sync *psoc_sync; 1567 int errno; 1568 1569 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); 1570 if (errno) 1571 return; 1572 1573 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev); 1574 1575 osif_psoc_sync_op_stop(psoc_sync); 1576 } 1577 #endif 1578 1579 /** 1580 * hdd_scan_context_destroy() - Destroy scan context 1581 * @hdd_ctx: HDD context. 1582 * 1583 * Destroy scan context. 1584 * 1585 * Return: None. 1586 */ 1587 void hdd_scan_context_destroy(struct hdd_context *hdd_ctx) 1588 { 1589 } 1590 1591 /** 1592 * hdd_scan_context_init() - Initialize scan context 1593 * @hdd_ctx: HDD context. 1594 * 1595 * Initialize scan related resources like spin lock and lists. 1596 * 1597 * Return: 0 on success and errno on failure. 1598 */ 1599 int hdd_scan_context_init(struct hdd_context *hdd_ctx) 1600 { 1601 return 0; 1602 } 1603