1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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: contains scan manager functionality 22 */ 23 24 #include <wlan_serialization_api.h> 25 #include <wlan_scan_ucfg_api.h> 26 #include <wlan_scan_tgt_api.h> 27 #include "wlan_scan_main.h" 28 #include "wlan_scan_manager.h" 29 #include "wlan_utility.h" 30 #include <wlan_reg_services_api.h> 31 #ifdef FEATURE_WLAN_SCAN_PNO 32 #include <host_diag_core_event.h> 33 #endif 34 #ifdef WLAN_POLICY_MGR_ENABLE 35 #include <wlan_policy_mgr_api.h> 36 #endif 37 #include <wlan_dfs_utils_api.h> 38 #include <cfg_scan.h> 39 40 QDF_STATUS 41 scm_scan_free_scan_request_mem(struct scan_start_request *req) 42 { 43 void *ie; 44 45 if (!req) { 46 scm_err("null request"); 47 QDF_ASSERT(0); 48 return QDF_STATUS_E_FAILURE; 49 } 50 /* Free vendor(extra) ie */ 51 ie = req->scan_req.extraie.ptr; 52 if (ie) { 53 req->scan_req.extraie.ptr = NULL; 54 req->scan_req.extraie.len = 0; 55 qdf_mem_free(ie); 56 } 57 58 /* Free htcap ie */ 59 ie = req->scan_req.htcap.ptr; 60 if (ie) { 61 req->scan_req.htcap.len = 0; 62 req->scan_req.htcap.ptr = NULL; 63 qdf_mem_free(ie); 64 } 65 66 /* Free vhtcap ie */ 67 ie = req->scan_req.vhtcap.ptr; 68 if (ie) { 69 req->scan_req.vhtcap.len = 0; 70 req->scan_req.vhtcap.ptr = NULL; 71 qdf_mem_free(ie); 72 } 73 /* free scan_start_request memory */ 74 qdf_mem_free(req); 75 76 return QDF_STATUS_SUCCESS; 77 } 78 79 static QDF_STATUS 80 scm_scan_get_pdev_global_event_handlers(struct scan_event_listeners *listeners, 81 struct pdev_scan_ev_handler *pdev_ev_handler) 82 { 83 uint32_t i; 84 struct cb_handler *cb_handlers = &(pdev_ev_handler->cb_handlers[0]); 85 86 for (i = 0; i < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; i++, cb_handlers++) { 87 if ((cb_handlers->func) && 88 (listeners->count < MAX_SCAN_EVENT_LISTENERS)) { 89 listeners->cb[listeners->count].func = 90 cb_handlers->func; 91 listeners->cb[listeners->count].arg = 92 cb_handlers->arg; 93 listeners->count++; 94 } 95 } 96 97 return QDF_STATUS_SUCCESS; 98 } 99 100 static QDF_STATUS 101 scm_scan_get_requester_event_handler(struct scan_event_listeners *listeners, 102 struct scan_requester_info *requesters, 103 wlan_scan_requester requester_id) 104 { 105 uint32_t idx; 106 struct cb_handler *ev_handler; 107 108 idx = requester_id & WLAN_SCAN_REQUESTER_ID_PREFIX; 109 if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX) 110 return QDF_STATUS_SUCCESS; 111 112 idx = requester_id & WLAN_SCAN_REQUESTER_ID_MASK; 113 if (idx < WLAN_MAX_REQUESTORS) { 114 ev_handler = &(requesters[idx].ev_handler); 115 if (ev_handler->func) { 116 if (listeners->count < MAX_SCAN_EVENT_LISTENERS) { 117 listeners->cb[listeners->count].func = 118 ev_handler->func; 119 listeners->cb[listeners->count].arg = 120 ev_handler->arg; 121 listeners->count++; 122 } 123 } 124 return QDF_STATUS_SUCCESS; 125 } else { 126 scm_err("invalid requester id"); 127 return QDF_STATUS_E_INVAL; 128 } 129 130 } 131 132 static void scm_scan_post_event(struct wlan_objmgr_vdev *vdev, 133 struct scan_event *event) 134 { 135 uint32_t i = 0; 136 struct wlan_scan_obj *scan; 137 struct pdev_scan_ev_handler *pdev_ev_handler; 138 struct cb_handler *cb_handlers; 139 struct scan_requester_info *requesters; 140 struct scan_event_listeners *listeners; 141 142 if (!vdev || !event) { 143 scm_err("vdev: 0x%pK, event: 0x%pK", vdev, event); 144 return; 145 } 146 if (!event->requester) { 147 scm_err("invalid requester id"); 148 QDF_ASSERT(0); 149 } 150 scan = wlan_vdev_get_scan_obj(vdev); 151 pdev_ev_handler = wlan_vdev_get_pdev_scan_ev_handlers(vdev); 152 if (!pdev_ev_handler) 153 return; 154 cb_handlers = &(pdev_ev_handler->cb_handlers[0]); 155 requesters = scan->requesters; 156 157 listeners = qdf_mem_malloc_atomic(sizeof(*listeners)); 158 if (!listeners) { 159 scm_warn("couldn't allocate listeners list"); 160 return; 161 } 162 163 /* initialize number of listeners */ 164 listeners->count = 0; 165 166 /* 167 * Initiator of scan request decides which all scan events 168 * he is interested in and FW will send only those scan events 169 * to host driver. 170 * All the events received by scan module will be notified 171 * to all registered handlers. 172 */ 173 174 qdf_spin_lock_bh(&scan->lock); 175 /* find all global scan event handlers on this pdev */ 176 scm_scan_get_pdev_global_event_handlers(listeners, pdev_ev_handler); 177 /* find owner who triggered this scan request */ 178 scm_scan_get_requester_event_handler(listeners, requesters, 179 event->requester); 180 qdf_spin_unlock_bh(&scan->lock); 181 182 scm_listener_duration_init(scan); 183 184 /* notify all interested handlers */ 185 for (i = 0; i < listeners->count; i++) { 186 scm_listener_cb_exe_dur_start(scan, i); 187 listeners->cb[i].func(vdev, event, listeners->cb[i].arg); 188 scm_listener_cb_exe_dur_end(scan, i); 189 } 190 qdf_mem_free(listeners); 191 } 192 193 static QDF_STATUS 194 scm_release_serialization_command(struct wlan_objmgr_vdev *vdev, 195 uint32_t scan_id) 196 { 197 struct wlan_serialization_queued_cmd_info cmd = {0}; 198 199 cmd.requestor = WLAN_UMAC_COMP_SCAN; 200 cmd.cmd_type = WLAN_SER_CMD_SCAN; 201 cmd.cmd_id = scan_id; 202 cmd.req_type = WLAN_SER_CANCEL_SINGLE_SCAN; 203 cmd.vdev = vdev; 204 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE; 205 206 /* Inform serialization for command completion */ 207 wlan_serialization_remove_cmd(&cmd); 208 209 return QDF_STATUS_SUCCESS; 210 } 211 212 static QDF_STATUS 213 scm_post_internal_scan_complete_event(struct scan_start_request *req, 214 enum scan_completion_reason reason) 215 { 216 struct scan_event event = {0, }; 217 218 /* prepare internal scan complete event */ 219 event.type = SCAN_EVENT_TYPE_COMPLETED; 220 event.reason = reason; 221 event.chan_freq = 0; /* Invalid frequency */ 222 event.vdev_id = req->scan_req.vdev_id; 223 event.requester = req->scan_req.scan_req_id; 224 event.scan_id = req->scan_req.scan_id; 225 /* Fill scan_start_request used to trigger this scan */ 226 event.scan_start_req = req; 227 /* post scan event to registered handlers */ 228 scm_scan_post_event(req->vdev, &event); 229 230 return QDF_STATUS_SUCCESS; 231 } 232 233 static inline struct pdev_scan_info * 234 scm_scan_get_pdev_priv_info(uint8_t pdev_id, struct wlan_scan_obj *scan_obj) 235 { 236 return &scan_obj->pdev_info[pdev_id]; 237 } 238 239 static QDF_STATUS 240 scm_update_last_scan_time(struct scan_start_request *req) 241 { 242 uint8_t pdev_id; 243 struct wlan_scan_obj *scan_obj; 244 struct pdev_scan_info *pdev_scan_info; 245 246 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 247 pdev_id = wlan_scan_vdev_get_pdev_id(req->vdev); 248 pdev_scan_info = scm_scan_get_pdev_priv_info(pdev_id, scan_obj); 249 /* update last scan start time */ 250 pdev_scan_info->last_scan_time = qdf_system_ticks(); 251 252 return QDF_STATUS_SUCCESS; 253 } 254 255 static QDF_STATUS 256 scm_activate_scan_request(struct scan_start_request *req) 257 { 258 QDF_STATUS status; 259 260 status = tgt_scan_start(req); 261 if (status != QDF_STATUS_SUCCESS) { 262 scm_err("tgt_scan_start failed, status: %d", status); 263 /* scan could not be started and hence 264 * we will not receive any completions. 265 * post scan cancelled 266 */ 267 scm_post_internal_scan_complete_event(req, 268 SCAN_REASON_CANCELLED); 269 return status; 270 } 271 /* save last scan start time */ 272 status = scm_update_last_scan_time(req); 273 274 return status; 275 } 276 277 static QDF_STATUS 278 scm_cancel_scan_request(struct scan_start_request *req) 279 { 280 struct scan_cancel_request cancel_req = {0, }; 281 QDF_STATUS status; 282 283 cancel_req.vdev = req->vdev; 284 cancel_req.cancel_req.scan_id = req->scan_req.scan_id; 285 cancel_req.cancel_req.requester = req->scan_req.scan_req_id; 286 cancel_req.cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE; 287 cancel_req.cancel_req.vdev_id = req->scan_req.vdev_id; 288 /* send scan cancel to fw */ 289 status = tgt_scan_cancel(&cancel_req); 290 if (status != QDF_STATUS_SUCCESS) 291 scm_err("tgt_scan_cancel failed: status: %d, scanid: %d", 292 status, req->scan_req.scan_id); 293 /* notify event handler about scan cancellation */ 294 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 295 296 return status; 297 } 298 299 static QDF_STATUS 300 scm_scan_serialize_callback(struct wlan_serialization_command *cmd, 301 enum wlan_serialization_cb_reason reason) 302 { 303 struct scan_start_request *req; 304 QDF_STATUS status; 305 306 if (!cmd) { 307 scm_err("cmd is NULL, reason: %d", reason); 308 QDF_ASSERT(0); 309 return QDF_STATUS_E_NULL_VALUE; 310 } 311 312 if (!cmd->umac_cmd) { 313 scm_err("cmd->umac_cmd is NULL , reason: %d", reason); 314 QDF_ASSERT(0); 315 return QDF_STATUS_E_NULL_VALUE; 316 } 317 318 req = cmd->umac_cmd; 319 if (!req->vdev) { 320 scm_err("NULL vdev. req:0x%pK, reason:%d\n", req, reason); 321 QDF_ASSERT(0); 322 return QDF_STATUS_E_NULL_VALUE; 323 } 324 325 qdf_mtrace(QDF_MODULE_ID_SERIALIZATION, QDF_MODULE_ID_SCAN, reason, 326 req->scan_req.vdev_id, req->scan_req.scan_id); 327 328 switch (reason) { 329 case WLAN_SER_CB_ACTIVATE_CMD: 330 /* command moved to active list 331 * modify the params if required for concurrency case. 332 */ 333 status = scm_activate_scan_request(req); 334 break; 335 336 case WLAN_SER_CB_CANCEL_CMD: 337 /* command removed from pending list. 338 * notify registered scan event handlers with 339 * status completed and reason cancelled. 340 */ 341 status = scm_post_internal_scan_complete_event(req, 342 SCAN_REASON_CANCELLED); 343 break; 344 345 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 346 /* active command timed out. 347 * prepare internal scan cancel request 348 */ 349 status = scm_cancel_scan_request(req); 350 break; 351 352 case WLAN_SER_CB_RELEASE_MEM_CMD: 353 /* command successfully completed. 354 * Release vdev reference and free scan_start_request memory 355 */ 356 cmd->umac_cmd = NULL; 357 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 358 status = scm_scan_free_scan_request_mem(req); 359 break; 360 361 default: 362 /* Do nothing but logging */ 363 QDF_ASSERT(0); 364 status = QDF_STATUS_E_INVAL; 365 break; 366 } 367 368 return status; 369 } 370 371 bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev) 372 { 373 struct wlan_scan_obj *scan_psoc_obj; 374 struct scan_vdev_obj *scan_vdev_obj; 375 376 if (!vdev) { 377 scm_err("vdev is NULL"); 378 return false; 379 } 380 381 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 382 if (!scan_psoc_obj) { 383 scm_err("Couldn't find scan psoc object"); 384 return false; 385 } 386 387 if (scan_psoc_obj->scan_disabled) { 388 scm_err_rl("scan disabled %x, for psoc", 389 scan_psoc_obj->scan_disabled); 390 return false; 391 } 392 393 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 394 if (!scan_vdev_obj) { 395 scm_err("Couldn't find scan vdev object"); 396 return false; 397 } 398 399 if (scan_vdev_obj->scan_disabled) { 400 scm_err_rl("scan disabled %x on vdev_id:%d", 401 scan_vdev_obj->scan_disabled, 402 wlan_vdev_get_id(vdev)); 403 return false; 404 } 405 406 return true; 407 } 408 409 #ifdef WLAN_POLICY_MGR_ENABLE 410 /** 411 * scm_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags 412 * @req: pointer to scan request 413 * 414 * This function sets scan_ctrl_flags_ext value depending on the type of 415 * scan and the channel lists. 416 * 417 * Non-DBS scan is requested if any of the below case is met: 418 * 1. HW is DBS incapable 419 * 2. A high accuracy scan request is sent by kernel. 420 * 421 * DBS scan is enabled for these conditions: 422 * 1. A low power or low span scan request is sent by kernel. 423 * For remaining cases DBS is enabled by default. 424 * Return: void 425 */ 426 static void 427 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 428 { 429 struct wlan_objmgr_psoc *psoc; 430 uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; 431 bool ndi_present; 432 433 psoc = wlan_vdev_get_psoc(req->vdev); 434 435 if (!policy_mgr_is_dbs_scan_allowed(psoc)) { 436 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 437 goto end; 438 } 439 440 if (!wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 441 scm_debug_rl("nl scan policy flags not honoured, goto end"); 442 goto end; 443 } 444 445 ndi_present = policy_mgr_mode_specific_connection_count(psoc, 446 PM_NDI_MODE, 447 NULL); 448 449 if (ndi_present || policy_mgr_is_hw_dbs_2x2_capable(psoc)) { 450 scm_debug("NDP present or HW 2x2 capable, go for DBS scan"); 451 goto end; 452 } 453 454 if (req->scan_req.scan_policy_high_accuracy) { 455 scm_debug("high accuracy scan received, going for non-dbs scan"); 456 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 457 goto end; 458 } 459 460 if ((req->scan_req.scan_policy_low_power) || 461 (req->scan_req.scan_policy_low_span)) { 462 scm_debug("low power/span scan received, going for dbs scan"); 463 scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; 464 goto end; 465 } 466 467 end: 468 req->scan_req.scan_ctrl_flags_ext |= 469 ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) 470 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); 471 } 472 473 /** 474 * scm_update_passive_dwell_time() - update dwell passive time 475 * @vdev: vdev object 476 * @req: scan request 477 * 478 * Return: None 479 */ 480 static void 481 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 482 struct scan_start_request *req) 483 { 484 struct wlan_objmgr_psoc *psoc; 485 486 psoc = wlan_vdev_get_psoc(vdev); 487 if (!psoc) 488 return; 489 490 if (policy_mgr_is_sta_connected_2g(psoc) && 491 !policy_mgr_is_hw_dbs_capable(psoc) && 492 ucfg_scan_get_bt_activity(psoc)) 493 req->scan_req.dwell_time_passive = 494 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 495 } 496 497 static const struct probe_time_dwell_time 498 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 499 {28, 11}, /* 0 SSID */ 500 {28, 20}, /* 1 SSID */ 501 {28, 20}, /* 2 SSID */ 502 {28, 20}, /* 3 SSID */ 503 {28, 20}, /* 4 SSID */ 504 {28, 20}, /* 5 SSID */ 505 {28, 20}, /* 6 SSID */ 506 {28, 11}, /* 7 SSID */ 507 {28, 11}, /* 8 SSID */ 508 {28, 11}, /* 9 SSID */ 509 {28, 8} /* 10 SSID */ 510 }; 511 512 /** 513 * scm_scan_get_burst_duration() - get burst duration depending on max chan 514 * and miracast. 515 * @max_ch_time: max channel time 516 * @miracast_enabled: if miracast is enabled 517 * 518 * Return: burst_duration 519 */ 520 static inline 521 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) 522 { 523 int burst_duration = 0; 524 525 if (miracast_enabled) { 526 /* 527 * When miracast is running, burst 528 * duration needs to be minimum to avoid 529 * any stutter or glitch in miracast 530 * during station scan 531 */ 532 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 533 burst_duration = max_ch_time; 534 else 535 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 536 } else { 537 /* 538 * If miracast is not running, accommodate max 539 * stations to make the scans faster 540 */ 541 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 542 max_ch_time; 543 544 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 545 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 546 max_ch_time; 547 548 if (channels) 549 burst_duration = channels * max_ch_time; 550 else 551 burst_duration = 552 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 553 } 554 } 555 return burst_duration; 556 } 557 558 #define SCM_ACTIVE_DWELL_TIME_NAN 60 559 #define SCM_ACTIVE_DWELL_TIME_SAP 40 560 561 /** 562 * scm_req_update_concurrency_params() - update scan req params depending on 563 * concurrent mode present. 564 * @vdev: vdev object pointer 565 * @req: scan request 566 * @scan_obj: scan object 567 * 568 * Return: void 569 */ 570 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 571 struct scan_start_request *req, 572 struct wlan_scan_obj *scan_obj) 573 { 574 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 575 struct wlan_objmgr_psoc *psoc; 576 uint16_t sap_peer_count = 0; 577 uint16_t go_peer_count = 0; 578 struct wlan_objmgr_pdev *pdev; 579 580 psoc = wlan_vdev_get_psoc(vdev); 581 pdev = wlan_vdev_get_pdev(vdev); 582 583 if (!psoc || !pdev) 584 return; 585 586 ap_present = policy_mgr_mode_specific_connection_count( 587 psoc, PM_SAP_MODE, NULL); 588 go_present = policy_mgr_mode_specific_connection_count( 589 psoc, PM_P2P_GO_MODE, NULL); 590 p2p_cli_present = policy_mgr_mode_specific_connection_count( 591 psoc, PM_P2P_CLIENT_MODE, NULL); 592 sta_active = policy_mgr_mode_specific_connection_count( 593 psoc, PM_STA_MODE, NULL); 594 ndi_present = policy_mgr_mode_specific_connection_count( 595 psoc, PM_NDI_MODE, NULL); 596 if (ap_present) 597 sap_peer_count = 598 wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); 599 if (go_present) 600 go_peer_count = 601 wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); 602 603 if (!req->scan_req.scan_f_passive) 604 scm_update_passive_dwell_time(vdev, req); 605 606 if (policy_mgr_get_connection_count(psoc)) { 607 if (!req->scan_req.scan_f_passive) 608 req->scan_req.dwell_time_active = 609 scan_obj->scan_def.conc_active_dwell; 610 req->scan_req.dwell_time_passive = 611 scan_obj->scan_def.conc_passive_dwell; 612 req->scan_req.max_rest_time = 613 scan_obj->scan_def.conc_max_rest_time; 614 req->scan_req.min_rest_time = 615 scan_obj->scan_def.conc_min_rest_time; 616 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 617 } 618 619 if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) 620 req->scan_req.adaptive_dwell_time_mode = 621 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 622 /* 623 * If AP/GO is active and has connected clients : 624 * 1.set min rest time same as max rest time, so that 625 * firmware spends more time on home channel which will 626 * increase the probability of sending beacon at TBTT 627 * 2.if DBS is supported and SAP is not on 2g, 628 * do not reset active dwell time for 2g. 629 */ 630 631 /* 632 * For SAP, the dwell time cannot exceed 32 ms as it can't go 633 * offchannel more than 32 ms. For Go, since we 634 * advertise NOA, GO can have regular dwell time which is 40 ms. 635 */ 636 if ((ap_present && sap_peer_count) || 637 (go_present && go_peer_count)) { 638 if ((policy_mgr_is_hw_dbs_capable(psoc) && 639 policy_mgr_is_sap_go_on_2g(psoc)) || 640 !policy_mgr_is_hw_dbs_capable(psoc)) { 641 if (ap_present) 642 req->scan_req.dwell_time_active_2g = 643 QDF_MIN(req->scan_req.dwell_time_active, 644 (SCAN_CTS_DURATION_MS_MAX - 645 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 646 else 647 req->scan_req.dwell_time_active_2g = 0; 648 } 649 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 650 } 651 652 if (policy_mgr_current_concurrency_is_mcc(psoc)) 653 req->scan_req.min_rest_time = 654 scan_obj->scan_def.conc_max_rest_time; 655 656 /* 657 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell 658 * time for 2g channels instead of dwell_time_active_2g 659 */ 660 if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) 661 req->scan_req.dwell_time_active_2g = SCM_ACTIVE_DWELL_TIME_SAP; 662 663 if (req->scan_req.scan_type == SCAN_TYPE_DEFAULT) { 664 /* 665 * Decide burst_duration and dwell_time_active based on 666 * what type of devices are active. 667 */ 668 do { 669 if (ap_present && go_present && sta_active) { 670 if (req->scan_req.dwell_time_active <= 671 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 672 req->scan_req.burst_duration = 673 req->scan_req.dwell_time_active; 674 else 675 req->scan_req.burst_duration = 676 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 677 678 break; 679 } 680 681 if (scan_obj->miracast_enabled && 682 policy_mgr_is_mcc_in_24G(psoc)) 683 req->scan_req.max_rest_time = 684 scan_obj->scan_def.sta_miracast_mcc_rest_time; 685 686 if (go_present) { 687 /* 688 * Background scan while GO is sending beacons. 689 * Every off-channel transition has overhead of 690 * 2 beacon intervals for NOA. Maximize number 691 * of channels in every transition by using 692 * burst scan. 693 */ 694 if (scan_obj->scan_def.go_scan_burst_duration) 695 req->scan_req.burst_duration = 696 scan_obj-> 697 scan_def.go_scan_burst_duration; 698 else 699 req->scan_req.burst_duration = 700 scm_scan_get_burst_duration( 701 req->scan_req. 702 dwell_time_active, 703 scan_obj-> 704 miracast_enabled); 705 break; 706 } 707 if ((sta_active || p2p_cli_present)) { 708 if (scan_obj->scan_def.sta_scan_burst_duration) 709 req->scan_req.burst_duration = 710 scan_obj->scan_def. 711 sta_scan_burst_duration; 712 break; 713 } 714 715 if (go_present && sta_active) { 716 req->scan_req.burst_duration = 717 req->scan_req.dwell_time_active; 718 break; 719 } 720 721 if (ndi_present || (p2p_cli_present && sta_active)) { 722 req->scan_req.burst_duration = 0; 723 break; 724 } 725 } while (0); 726 727 if (ap_present) { 728 uint8_t ssid_num; 729 730 ssid_num = req->scan_req.num_ssids * 731 req->scan_req.num_bssid; 732 req->scan_req.repeat_probe_time = 733 scan_probe_time_dwell_time_map[ 734 QDF_MIN(ssid_num, 735 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 736 - 1)].probe_time; 737 req->scan_req.n_probes = 738 (req->scan_req.repeat_probe_time > 0) ? 739 req->scan_req.dwell_time_active / 740 req->scan_req.repeat_probe_time : 0; 741 } 742 } 743 744 if (ap_present) { 745 uint16_t ap_chan_freq; 746 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 747 748 ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 749 /* 750 * P2P/STA scan while SoftAP is sending beacons. 751 * Max duration of CTS2self is 32 ms, which limits the 752 * dwell time. 753 * If DBS is supported and: 754 * 1.if SAP is on 2G channel then keep passive 755 * dwell time default. 756 * 2.if SAP is on 5G/6G channel then update dwell time active. 757 */ 758 if (sap_peer_count) { 759 if (policy_mgr_is_hw_dbs_capable(psoc) && 760 (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) || 761 WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) { 762 req->scan_req.dwell_time_active = 763 QDF_MIN(req->scan_req.dwell_time_active, 764 (SCAN_CTS_DURATION_MS_MAX - 765 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 766 } 767 if (!policy_mgr_is_hw_dbs_capable(psoc) || 768 (policy_mgr_is_hw_dbs_capable(psoc) && 769 WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) { 770 req->scan_req.dwell_time_passive = 771 req->scan_req.dwell_time_active; 772 } 773 } 774 775 if (scan_obj->scan_def.ap_scan_burst_duration) { 776 req->scan_req.burst_duration = 777 scan_obj->scan_def.ap_scan_burst_duration; 778 } else { 779 req->scan_req.burst_duration = 0; 780 if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq)) 781 req->scan_req.burst_duration = 782 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 783 req->scan_req.dwell_time_active; 784 } 785 } 786 787 if (ndi_present) { 788 req->scan_req.dwell_time_active = 789 SCM_ACTIVE_DWELL_TIME_NAN; 790 req->scan_req.dwell_time_active_2g = 791 QDF_MIN(req->scan_req.dwell_time_active_2g, 792 SCM_ACTIVE_DWELL_TIME_NAN); 793 scm_debug("NDP active modify dwell time 2ghz %d", 794 req->scan_req.dwell_time_active_2g); 795 } 796 797 if (sta_active) { 798 req->scan_req.dwell_time_active_6g = 799 scan_obj->scan_def.active_dwell_time_6g_conc; 800 req->scan_req.dwell_time_passive_6g = 801 scan_obj->scan_def.passive_dwell_time_6g_conc; 802 } 803 } 804 805 static inline void scm_update_5g_chlist(struct scan_start_request *req) 806 { 807 uint32_t i; 808 uint32_t num_scan_channels; 809 810 num_scan_channels = 0; 811 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 812 if (WLAN_REG_IS_5GHZ_CH_FREQ( 813 req->scan_req.chan_list.chan[i].freq)) 814 continue; 815 816 req->scan_req.chan_list.chan[num_scan_channels++] = 817 req->scan_req.chan_list.chan[i]; 818 } 819 if (num_scan_channels < req->scan_req.chan_list.num_chan) 820 scm_debug("5g chan skipped (%d, %d)", 821 req->scan_req.chan_list.num_chan, num_scan_channels); 822 req->scan_req.chan_list.num_chan = num_scan_channels; 823 } 824 825 static inline void scm_update_24g_chlist(struct scan_start_request *req) 826 { 827 uint32_t i; 828 uint32_t num_scan_channels; 829 830 num_scan_channels = 0; 831 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 832 if (WLAN_REG_IS_24GHZ_CH_FREQ( 833 req->scan_req.chan_list.chan[i].freq)) 834 continue; 835 836 req->scan_req.chan_list.chan[num_scan_channels++] = 837 req->scan_req.chan_list.chan[i]; 838 } 839 if (num_scan_channels < req->scan_req.chan_list.num_chan) 840 scm_debug("2g chan skipped (%d, %d)", 841 req->scan_req.chan_list.num_chan, num_scan_channels); 842 req->scan_req.chan_list.num_chan = num_scan_channels; 843 } 844 845 /** 846 * scm_filter_6g_and_indoor_freq() - Modify channel list to skip 6Ghz and 5Ghz 847 * indoor channel if hw mode is non dbs and SAP is present 848 * @pdev: pointer to pdev 849 * @req: scan request 850 * 851 * Return: None 852 */ 853 static void scm_filter_6g_and_indoor_freq(struct wlan_objmgr_pdev *pdev, 854 struct scan_start_request *req) 855 { 856 uint32_t i; 857 uint32_t num_scan_channels; 858 qdf_freq_t freq; 859 860 num_scan_channels = 0; 861 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 862 freq = req->scan_req.chan_list.chan[i].freq; 863 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) 864 continue; 865 866 if (wlan_reg_is_freq_indoor(pdev, freq)) 867 continue; 868 869 req->scan_req.chan_list.chan[num_scan_channels++] = 870 req->scan_req.chan_list.chan[i]; 871 } 872 if (num_scan_channels < req->scan_req.chan_list.num_chan) 873 scm_debug("6g and indoor channel chan skipped (%d, %d)", 874 req->scan_req.chan_list.num_chan, num_scan_channels); 875 req->scan_req.chan_list.num_chan = num_scan_channels; 876 } 877 878 /** 879 * scm_scan_chlist_concurrency_modify() - modify chan list to skip 5G if 880 * required 881 * @vdev: vdev object 882 * @req: scan request 883 * 884 * Check and skip 5G chan list based on DFS AP present and current hw mode. 885 * 886 * Return: void 887 */ 888 static inline void scm_scan_chlist_concurrency_modify( 889 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 890 { 891 struct wlan_objmgr_psoc *psoc; 892 struct wlan_objmgr_pdev *pdev; 893 struct wlan_scan_obj *scan_obj; 894 uint16_t trim; 895 896 pdev = wlan_vdev_get_pdev(vdev); 897 if (!pdev) 898 return; 899 900 psoc = wlan_pdev_get_psoc(pdev); 901 if (!psoc) 902 return; 903 904 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 905 if (!scan_obj) 906 return; 907 908 /* do this only for STA and P2P-CLI mode */ 909 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 910 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 911 return; 912 913 if (policy_mgr_scan_trim_5g_chnls_for_dfs_ap(psoc)) 914 scm_update_5g_chlist(req); 915 916 if (scan_obj->scan_def.conc_chlist_trim) { 917 trim = policy_mgr_scan_trim_chnls_for_connected_ap(pdev); 918 if (trim & TRIM_CHANNEL_LIST_5G) 919 scm_update_5g_chlist(req); 920 if (trim & TRIM_CHANNEL_LIST_24G) 921 scm_update_24g_chlist(req); 922 } 923 924 /* 925 * Do not allow STA to scan on 6Ghz or indoor channel for non dbs 926 * hardware if SAP and skip_6g_and_indoor_freq_scan ini are present 927 */ 928 if (scan_obj->scan_def.skip_6g_and_indoor_freq && 929 !policy_mgr_is_hw_dbs_capable(psoc) && 930 (wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 931 policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL)) 932 scm_filter_6g_and_indoor_freq(pdev, req); 933 934 } 935 #else 936 static inline 937 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 938 struct scan_start_request *req, 939 struct wlan_scan_obj *scan_obj) 940 { 941 } 942 943 static inline void 944 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 945 { 946 } 947 948 static inline void scm_scan_chlist_concurrency_modify( 949 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 950 { 951 } 952 #endif 953 954 /** 955 * scm_update_channel_list() - update scan req params depending on dfs inis 956 * and initial scan request. 957 * @req: scan request 958 * @scan_obj: scan object 959 * 960 * Return: void 961 */ 962 static void 963 scm_update_channel_list(struct scan_start_request *req, 964 struct wlan_scan_obj *scan_obj) 965 { 966 uint8_t i; 967 uint8_t num_scan_channels = 0; 968 struct scan_vdev_obj *scan_vdev_obj; 969 struct wlan_objmgr_pdev *pdev; 970 bool first_scan_done = true; 971 bool p2p_search = false; 972 bool skip_dfs_ch = true; 973 uint32_t first_freq; 974 975 pdev = wlan_vdev_get_pdev(req->vdev); 976 977 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 978 if (!scan_vdev_obj) { 979 scm_err("null scan_vdev_obj"); 980 return; 981 } 982 983 if (!scan_vdev_obj->first_scan_done) { 984 first_scan_done = false; 985 scan_vdev_obj->first_scan_done = true; 986 } 987 988 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH) 989 p2p_search = true; 990 /* 991 * No need to update channels if req is single channel* ie ROC, 992 * Preauth or a single channel scan etc. 993 * If the single chan in the scan channel list is an NOL channel,it is 994 * removed and it would reduce the number of scan channels to 0. 995 */ 996 first_freq = req->scan_req.chan_list.chan[0].freq; 997 if ((req->scan_req.chan_list.num_chan == 1) && 998 (!utils_dfs_is_freq_in_nol(pdev, first_freq))) 999 return; 1000 1001 /* do this only for STA and P2P-CLI mode */ 1002 if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 1003 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) && 1004 !p2p_search) 1005 skip_dfs_ch = false; 1006 1007 if ((scan_obj->scan_def.allow_dfs_chan_in_scan && 1008 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 1009 first_scan_done)) && 1010 !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search) && 1011 !scan_obj->miracast_enabled) 1012 skip_dfs_ch = false; 1013 1014 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 1015 uint32_t freq; 1016 1017 freq = req->scan_req.chan_list.chan[i].freq; 1018 if (skip_dfs_ch && 1019 wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) { 1020 scm_nofl_debug("Skip DFS freq %d", freq); 1021 continue; 1022 } 1023 if (utils_dfs_is_freq_in_nol(pdev, freq)) { 1024 scm_nofl_debug("Skip NOL freq %d", freq); 1025 continue; 1026 } 1027 1028 req->scan_req.chan_list.chan[num_scan_channels++] = 1029 req->scan_req.chan_list.chan[i]; 1030 } 1031 1032 req->scan_req.chan_list.num_chan = num_scan_channels; 1033 1034 scm_update_6ghz_channel_list(req, scan_obj); 1035 scm_scan_chlist_concurrency_modify(req->vdev, req); 1036 } 1037 1038 /** 1039 * scm_req_update_dwell_time_as_per_scan_mode() - update scan req params 1040 * dwell time as per scan mode. 1041 * @vdev: vdev to update 1042 * @req: scan request 1043 * 1044 * Return: void 1045 */ 1046 static void 1047 scm_req_update_dwell_time_as_per_scan_mode( 1048 struct wlan_objmgr_vdev *vdev, 1049 struct scan_start_request *req) 1050 { 1051 struct wlan_objmgr_psoc *psoc; 1052 1053 psoc = wlan_vdev_get_psoc(vdev); 1054 1055 if (req->scan_req.scan_policy_low_span && 1056 wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 1057 req->scan_req.adaptive_dwell_time_mode = 1058 SCAN_DWELL_MODE_STATIC; 1059 req->scan_req.dwell_time_active = 1060 QDF_MIN(req->scan_req.dwell_time_active, 1061 LOW_SPAN_ACTIVE_DWELL_TIME); 1062 req->scan_req.dwell_time_active_2g = 1063 QDF_MIN(req->scan_req.dwell_time_active_2g, 1064 LOW_SPAN_ACTIVE_DWELL_TIME); 1065 req->scan_req.dwell_time_passive = 1066 QDF_MIN(req->scan_req.dwell_time_passive, 1067 LOW_SPAN_PASSIVE_DWELL_TIME); 1068 } 1069 } 1070 1071 /** 1072 * scm_scan_req_update_params() - update scan req params depending on modes 1073 * and scan type. 1074 * @vdev: vdev object pointer 1075 * @req: scan request 1076 * @scan_obj: scan object 1077 * 1078 * Return: void 1079 */ 1080 static void 1081 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 1082 struct scan_start_request *req, 1083 struct wlan_scan_obj *scan_obj) 1084 { 1085 struct chan_list *custom_chan_list; 1086 struct wlan_objmgr_pdev *pdev; 1087 uint8_t pdev_id; 1088 1089 /* Ensure correct number of probes are sent on active channel */ 1090 if (!req->scan_req.repeat_probe_time) 1091 req->scan_req.repeat_probe_time = 1092 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 1093 1094 if (req->scan_req.scan_f_passive) 1095 req->scan_req.scan_ctrl_flags_ext |= 1096 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 1097 1098 if (!req->scan_req.n_probes) 1099 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 1100 req->scan_req.dwell_time_active / 1101 req->scan_req.repeat_probe_time : 0; 1102 1103 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH || 1104 req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1105 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 1106 req->scan_req.dwell_time_active_2g = 0; 1107 if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1108 req->scan_req.repeat_probe_time = 0; 1109 } else { 1110 req->scan_req.scan_f_filter_prb_req = true; 1111 if (!req->scan_req.num_ssids) 1112 req->scan_req.scan_f_bcast_probe = true; 1113 1114 req->scan_req.dwell_time_active += 1115 P2P_SEARCH_DWELL_TIME_INC; 1116 /* 1117 * 3 channels with default max dwell time 40 ms. 1118 * Cap limit will be set by 1119 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 1120 * should be such that no channel is scanned less 1121 * than the dwell time in normal scenarios. 1122 */ 1123 if (req->scan_req.chan_list.num_chan == 1124 WLAN_P2P_SOCIAL_CHANNELS && 1125 !scan_obj->miracast_enabled) 1126 req->scan_req.repeat_probe_time = 1127 req->scan_req.dwell_time_active / 5; 1128 else 1129 req->scan_req.repeat_probe_time = 1130 req->scan_req.dwell_time_active / 3; 1131 if (scan_obj->scan_def.p2p_scan_burst_duration) { 1132 req->scan_req.burst_duration = 1133 scan_obj->scan_def. 1134 p2p_scan_burst_duration; 1135 } else { 1136 req->scan_req.burst_duration = 1137 BURST_SCAN_MAX_NUM_OFFCHANNELS * 1138 req->scan_req.dwell_time_active; 1139 if (req->scan_req.burst_duration > 1140 P2P_SCAN_MAX_BURST_DURATION) { 1141 uint8_t channels = 1142 P2P_SCAN_MAX_BURST_DURATION / 1143 req->scan_req.dwell_time_active; 1144 if (channels) 1145 req->scan_req.burst_duration = 1146 channels * 1147 req->scan_req.dwell_time_active; 1148 else 1149 req->scan_req.burst_duration = 1150 P2P_SCAN_MAX_BURST_DURATION; 1151 } 1152 } 1153 req->scan_req.scan_ev_bss_chan = false; 1154 } 1155 } else { 1156 req->scan_req.scan_f_cck_rates = true; 1157 if (!req->scan_req.num_ssids) 1158 req->scan_req.scan_f_bcast_probe = true; 1159 req->scan_req.scan_f_add_ds_ie_in_probe = true; 1160 req->scan_req.scan_f_filter_prb_req = true; 1161 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 1162 } 1163 1164 scm_update_dbs_scan_ctrl_ext_flag(req); 1165 1166 /* 1167 * No need to update conncurrency parmas if req is passive scan on 1168 * single channel ie ROC, Preauth etc 1169 */ 1170 if (!(req->scan_req.scan_f_passive && 1171 req->scan_req.chan_list.num_chan == 1) && 1172 req->scan_req.scan_type != SCAN_TYPE_RRM) 1173 scm_req_update_concurrency_params(vdev, req, scan_obj); 1174 1175 if (req->scan_req.scan_type == SCAN_TYPE_RRM) 1176 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_RRM_SCAN_IND; 1177 1178 scm_req_update_dwell_time_as_per_scan_mode(vdev, req); 1179 1180 scm_debug("scan_ctrl_flags_ext %0x", req->scan_req.scan_ctrl_flags_ext); 1181 /* 1182 * Set wide band flag if enabled. This will cause 1183 * phymode TLV being sent to FW. 1184 */ 1185 pdev = wlan_vdev_get_pdev(vdev); 1186 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1187 if (ucfg_scan_get_wide_band_scan(pdev)) 1188 req->scan_req.scan_f_wide_band = true; 1189 else 1190 req->scan_req.scan_f_wide_band = false; 1191 1192 /* 1193 * Overwrite scan channels with custom scan channel 1194 * list if configured. 1195 */ 1196 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 1197 if (custom_chan_list->num_chan) 1198 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 1199 sizeof(struct chan_list)); 1200 else if (!req->scan_req.chan_list.num_chan) 1201 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 1202 1203 scm_update_channel_list(req, scan_obj); 1204 1205 wlan_scan_update_low_latency_profile_chnlist(vdev, req); 1206 } 1207 1208 static inline void scm_print_scan_req_info(struct scan_req_params *req) 1209 { 1210 uint32_t buff_len; 1211 char *chan_buff; 1212 uint32_t len = 0; 1213 uint8_t idx, count = 0; 1214 struct chan_list *chan_lst; 1215 #define MAX_SCAN_FREQ_TO_PRINT 25 1216 1217 scm_nofl_debug("Scan start: scan id %d vdev %d Dwell time: act %d pass %d act_2G %d act_6G %d pass_6G %d, probe time %d n_probes %d flags %x ext_flag %x events %x policy %d wide_bw %d pri %d", 1218 req->scan_id, req->vdev_id, req->dwell_time_active, 1219 req->dwell_time_passive, req->dwell_time_active_2g, 1220 req->dwell_time_active_6g, req->dwell_time_passive_6g, 1221 req->repeat_probe_time, req->n_probes, req->scan_flags, 1222 req->scan_ctrl_flags_ext, req->scan_events, 1223 req->scan_policy_type, req->scan_f_wide_band, 1224 req->scan_priority); 1225 1226 for (idx = 0; idx < req->num_ssids; idx++) 1227 scm_nofl_debug("SSID[%d]: " QDF_SSID_FMT, idx, 1228 QDF_SSID_REF(req->ssid[idx].length, 1229 req->ssid[idx].ssid)); 1230 1231 chan_lst = &req->chan_list; 1232 1233 if (!chan_lst->num_chan) 1234 return; 1235 /* 1236 * Buffer of (num channel * 11) + 1 to consider the 4 char freq, 6 char 1237 * flags and 1 space after it for each channel and 1 to end the string 1238 * with NULL. 1239 */ 1240 buff_len = 1241 (QDF_MIN(MAX_SCAN_FREQ_TO_PRINT, chan_lst->num_chan) * 11) + 1; 1242 chan_buff = qdf_mem_malloc(buff_len); 1243 if (!chan_buff) 1244 return; 1245 scm_nofl_debug("Total freq %d", chan_lst->num_chan); 1246 for (idx = 0; idx < chan_lst->num_chan; idx++) { 1247 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1248 "%d(0x%02x) ", chan_lst->chan[idx].freq, 1249 chan_lst->chan[idx].flags); 1250 count++; 1251 if (count >= MAX_SCAN_FREQ_TO_PRINT) { 1252 /* Print the MAX_SCAN_FREQ_TO_PRINT channels */ 1253 scm_nofl_debug("Freq list: %s", chan_buff); 1254 len = 0; 1255 count = 0; 1256 } 1257 } 1258 if (len) 1259 scm_nofl_debug("Freq list: %s", chan_buff); 1260 1261 qdf_mem_free(chan_buff); 1262 } 1263 QDF_STATUS 1264 scm_scan_start_req(struct scheduler_msg *msg) 1265 { 1266 struct wlan_serialization_command cmd = {0, }; 1267 enum wlan_serialization_status ser_cmd_status; 1268 struct scan_start_request *req = NULL; 1269 struct wlan_scan_obj *scan_obj; 1270 QDF_STATUS status = QDF_STATUS_SUCCESS; 1271 1272 1273 if (!msg) { 1274 scm_err("msg received is NULL"); 1275 QDF_ASSERT(0); 1276 return QDF_STATUS_E_NULL_VALUE; 1277 } 1278 if (!msg->bodyptr) { 1279 scm_err("bodyptr is NULL"); 1280 QDF_ASSERT(0); 1281 return QDF_STATUS_E_NULL_VALUE; 1282 } 1283 1284 req = msg->bodyptr; 1285 1286 if (!scm_is_scan_allowed(req->vdev)) { 1287 scm_err("scan disabled, rejecting the scan req"); 1288 status = QDF_STATUS_E_NULL_VALUE; 1289 goto err; 1290 } 1291 1292 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 1293 if (!scan_obj) { 1294 scm_debug("Couldn't find scan object"); 1295 status = QDF_STATUS_E_NULL_VALUE; 1296 goto err; 1297 } 1298 1299 scm_scan_req_update_params(req->vdev, req, scan_obj); 1300 scm_print_scan_req_info(&req->scan_req); 1301 1302 if (!req->scan_req.chan_list.num_chan) { 1303 scm_info("Reject 0 channel Scan"); 1304 status = QDF_STATUS_E_NULL_VALUE; 1305 goto err; 1306 } 1307 1308 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1309 cmd.cmd_id = req->scan_req.scan_id; 1310 cmd.cmd_cb = scm_scan_serialize_callback; 1311 cmd.umac_cmd = req; 1312 cmd.source = WLAN_UMAC_COMP_SCAN; 1313 cmd.is_high_priority = false; 1314 cmd.cmd_timeout_duration = req->scan_req.max_scan_time + 1315 SCAN_TIMEOUT_GRACE_PERIOD; 1316 cmd.vdev = req->vdev; 1317 1318 if (scan_obj->disable_timeout) 1319 cmd.cmd_timeout_duration = 0; 1320 1321 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION, 1322 WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id, 1323 req->scan_req.scan_id); 1324 1325 ser_cmd_status = wlan_serialization_request(&cmd); 1326 switch (ser_cmd_status) { 1327 case WLAN_SER_CMD_PENDING: 1328 /* command moved to pending list.Do nothing */ 1329 break; 1330 case WLAN_SER_CMD_ACTIVE: 1331 /* command moved to active list. Do nothing */ 1332 break; 1333 default: 1334 scm_debug("ser cmd status %d", ser_cmd_status); 1335 goto err; 1336 } 1337 1338 return status; 1339 err: 1340 /* 1341 * notify registered scan event handlers 1342 * about internal error 1343 */ 1344 scm_post_internal_scan_complete_event(req, 1345 SCAN_REASON_INTERNAL_FAILURE); 1346 /* 1347 * cmd can't be serviced. 1348 * release vdev reference and free scan_start_request memory 1349 */ 1350 if (req) { 1351 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1352 scm_scan_free_scan_request_mem(req); 1353 } 1354 1355 return status; 1356 } 1357 1358 static inline enum wlan_serialization_cancel_type 1359 get_serialization_cancel_type(enum scan_cancel_req_type type) 1360 { 1361 enum wlan_serialization_cancel_type serialization_type; 1362 1363 switch (type) { 1364 case WLAN_SCAN_CANCEL_SINGLE: 1365 serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN; 1366 break; 1367 case WLAN_SCAN_CANCEL_VDEV_ALL: 1368 serialization_type = WLAN_SER_CANCEL_VDEV_SCANS; 1369 break; 1370 case WLAN_SCAN_CANCEL_PDEV_ALL: 1371 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1372 break; 1373 case WLAN_SCAN_CANCEL_HOST_VDEV_ALL: 1374 serialization_type = WLAN_SER_CANCEL_VDEV_HOST_SCANS; 1375 break; 1376 default: 1377 QDF_ASSERT(0); 1378 scm_warn("invalid scan_cancel_req_type: %d", type); 1379 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1380 break; 1381 } 1382 1383 return serialization_type; 1384 } 1385 1386 QDF_STATUS 1387 scm_scan_cancel_req(struct scheduler_msg *msg) 1388 { 1389 struct wlan_serialization_queued_cmd_info cmd = {0,}; 1390 struct wlan_serialization_command ser_cmd = {0,}; 1391 enum wlan_serialization_cmd_status ser_cmd_status; 1392 struct scan_cancel_request *req; 1393 QDF_STATUS status = QDF_STATUS_SUCCESS; 1394 1395 if (!msg) { 1396 scm_err("msg received is NULL"); 1397 QDF_ASSERT(0); 1398 return QDF_STATUS_E_NULL_VALUE; 1399 } 1400 if (!msg->bodyptr) { 1401 scm_err("Bodyptr is NULL"); 1402 QDF_ASSERT(0); 1403 return QDF_STATUS_E_NULL_VALUE; 1404 } 1405 1406 req = msg->bodyptr; 1407 /* 1408 * If requester wants to wait for target scan cancel event 1409 * instead of internally generated cancel event, just check 1410 * which queue this scan request belongs to and send scan 1411 * cancel request to FW accordingly. 1412 * Else generate internal scan cancel event and notify 1413 * handlers and free scan request resources. 1414 */ 1415 if (req->wait_tgt_cancel && 1416 (req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) { 1417 ser_cmd.cmd_type = WLAN_SER_CMD_SCAN; 1418 ser_cmd.cmd_id = req->cancel_req.scan_id; 1419 ser_cmd.cmd_cb = NULL; 1420 ser_cmd.umac_cmd = NULL; 1421 ser_cmd.source = WLAN_UMAC_COMP_SCAN; 1422 ser_cmd.is_high_priority = false; 1423 ser_cmd.vdev = req->vdev; 1424 if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd)) 1425 ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST; 1426 else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd)) 1427 ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST; 1428 else 1429 ser_cmd_status = WLAN_SER_CMD_NOT_FOUND; 1430 } else { 1431 cmd.requestor = 0; 1432 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1433 cmd.cmd_id = req->cancel_req.scan_id; 1434 cmd.vdev = req->vdev; 1435 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE | 1436 WLAN_SERIALIZATION_PENDING_QUEUE; 1437 cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type); 1438 1439 ser_cmd_status = wlan_serialization_cancel_request(&cmd); 1440 } 1441 1442 scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d", 1443 ser_cmd_status, req->cancel_req.requester, 1444 req->cancel_req.scan_id, req->cancel_req.vdev_id, 1445 req->cancel_req.req_type); 1446 1447 switch (ser_cmd_status) { 1448 case WLAN_SER_CMD_IN_PENDING_LIST: 1449 /* do nothing */ 1450 break; 1451 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1452 case WLAN_SER_CMDS_IN_ALL_LISTS: 1453 /* send wmi scan cancel to fw */ 1454 status = tgt_scan_cancel(req); 1455 break; 1456 case WLAN_SER_CMD_NOT_FOUND: 1457 /* do nothing */ 1458 break; 1459 default: 1460 QDF_ASSERT(0); 1461 status = QDF_STATUS_E_INVAL; 1462 break; 1463 } 1464 1465 /* Release vdev reference and scan cancel request 1466 * processing is complete 1467 */ 1468 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1469 /* Free cancel request memory */ 1470 qdf_mem_free(req); 1471 1472 return status; 1473 } 1474 1475 #ifdef FEATURE_WLAN_SCAN_PNO 1476 static QDF_STATUS 1477 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1478 struct scan_event *event) 1479 { 1480 struct scan_vdev_obj *scan_vdev_obj; 1481 struct wlan_scan_obj *scan_psoc_obj; 1482 scan_event_handler pno_cb; 1483 void *cb_arg; 1484 1485 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1486 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 1487 if (!scan_vdev_obj || !scan_psoc_obj) { 1488 scm_err("null scan_vdev_obj %pK scan_obj %pK", 1489 scan_vdev_obj, scan_psoc_obj); 1490 return QDF_STATUS_E_INVAL; 1491 } 1492 1493 switch (event->type) { 1494 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1495 if (!scan_vdev_obj->pno_match_evt_received) 1496 return QDF_STATUS_SUCCESS; 1497 qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock, 1498 WIFI_POWER_EVENT_WAKELOCK_PNO); 1499 qdf_wake_lock_timeout_acquire( 1500 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1501 SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT); 1502 qdf_runtime_pm_allow_suspend( 1503 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1504 scan_vdev_obj->pno_match_evt_received = false; 1505 break; 1506 case SCAN_EVENT_TYPE_NLO_MATCH: 1507 scan_vdev_obj->pno_match_evt_received = true; 1508 qdf_wake_lock_timeout_acquire( 1509 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1510 SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT); 1511 qdf_runtime_pm_prevent_suspend( 1512 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1513 return QDF_STATUS_SUCCESS; 1514 default: 1515 return QDF_STATUS_E_INVAL; 1516 } 1517 qdf_spin_lock_bh(&scan_psoc_obj->lock); 1518 pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func; 1519 cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg; 1520 qdf_spin_unlock_bh(&scan_psoc_obj->lock); 1521 1522 if (pno_cb) 1523 pno_cb(vdev, event, cb_arg); 1524 1525 return QDF_STATUS_SUCCESS; 1526 } 1527 #else 1528 1529 static QDF_STATUS 1530 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1531 struct scan_event *event) 1532 { 1533 return QDF_STATUS_SUCCESS; 1534 } 1535 #endif 1536 1537 /** 1538 * scm_scan_update_scan_event() - update scan event 1539 * @scan: scan object 1540 * @event: scan event 1541 * @scan_start_req: scan_start_req used for triggering scan 1542 * 1543 * update scan params in scan event 1544 * 1545 * Return: QDF_STATUS 1546 */ 1547 static QDF_STATUS 1548 scm_scan_update_scan_event(struct wlan_scan_obj *scan, 1549 struct scan_event *event, 1550 struct scan_start_request *scan_start_req) 1551 { 1552 if (!event) 1553 return QDF_STATUS_E_NULL_VALUE; 1554 1555 if (!scan || !scan_start_req) { 1556 event->scan_start_req = NULL; 1557 return QDF_STATUS_E_NULL_VALUE; 1558 } 1559 /* copy scan start request to pass back buffer */ 1560 qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req, 1561 sizeof(struct scan_start_request)); 1562 /* reset all pointers */ 1563 scan->scan_start_request_buff.scan_req.extraie.ptr = NULL; 1564 scan->scan_start_request_buff.scan_req.extraie.len = 0; 1565 scan->scan_start_request_buff.scan_req.htcap.ptr = NULL; 1566 scan->scan_start_request_buff.scan_req.htcap.len = 0; 1567 scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL; 1568 scan->scan_start_request_buff.scan_req.vhtcap.len = 0; 1569 1570 event->scan_start_req = &scan->scan_start_request_buff; 1571 1572 return QDF_STATUS_SUCCESS; 1573 } 1574 1575 static 1576 void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev, 1577 uint32_t chan_freq, uint32_t time) 1578 { 1579 struct wlan_scan_obj *scan_obj; 1580 struct chan_list_scan_info *chan_info; 1581 bool chan_found = false; 1582 uint8_t pdev_id; 1583 int i; 1584 1585 scan_obj = wlan_vdev_get_scan_obj(vdev); 1586 if (!scan_obj) 1587 return; 1588 1589 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 1590 chan_info = &scan_obj->pdev_info[pdev_id].chan_scan_info; 1591 1592 for (i = 0; i < chan_info->num_chan ; i++) { 1593 if (chan_info->ch_scan_info[i].freq == chan_freq) { 1594 chan_info->ch_scan_info[i].last_scan_time = time; 1595 scm_debug("chan freq %d scan time %u\n", 1596 chan_freq, time); 1597 chan_found = true; 1598 break; 1599 } 1600 } 1601 1602 if (!chan_found) { 1603 chan_info->ch_scan_info[chan_info->num_chan].freq = chan_freq; 1604 chan_info->ch_scan_info[chan_info->num_chan].last_scan_time = 1605 time; 1606 chan_info->num_chan++; 1607 scm_debug("chan freq %d scan time %u\n", chan_freq, time); 1608 } 1609 } 1610 1611 QDF_STATUS 1612 scm_scan_event_handler(struct scheduler_msg *msg) 1613 { 1614 struct wlan_objmgr_vdev *vdev; 1615 struct scan_event *event; 1616 struct scan_event_info *event_info; 1617 struct wlan_serialization_command cmd = {0,}; 1618 struct wlan_serialization_command *queued_cmd; 1619 struct scan_start_request *scan_start_req; 1620 struct wlan_scan_obj *scan; 1621 1622 if (!msg) { 1623 scm_err("NULL msg received "); 1624 QDF_ASSERT(0); 1625 return QDF_STATUS_E_NULL_VALUE; 1626 } 1627 if (!msg->bodyptr) { 1628 scm_err("NULL scan event received"); 1629 QDF_ASSERT(0); 1630 return QDF_STATUS_E_NULL_VALUE; 1631 } 1632 1633 event_info = msg->bodyptr; 1634 vdev = event_info->vdev; 1635 event = &(event_info->event); 1636 1637 scan = wlan_vdev_get_scan_obj(vdev); 1638 1639 scm_duration_init(scan); 1640 1641 scm_event_duration_start(scan); 1642 1643 scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d," 1644 "scanid:%d (0x%x), timestamp:%u", event->vdev_id, 1645 event->type, event->reason, event->chan_freq, 1646 event->requester, event->scan_id, event->scan_id, 1647 event->timestamp); 1648 1649 if (event->type == SCAN_EVENT_TYPE_FOREIGN_CHANNEL) 1650 scm_update_last_scan_time_per_channel( 1651 vdev, event->chan_freq, qdf_get_time_of_the_day_ms()); 1652 1653 /* 1654 * NLO requests are never queued, so post NLO events 1655 * without checking for their presence in active queue. 1656 */ 1657 switch (event->type) { 1658 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1659 case SCAN_EVENT_TYPE_NLO_MATCH: 1660 scm_pno_event_handler(vdev, event); 1661 goto exit; 1662 default: 1663 break; 1664 } 1665 1666 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1667 cmd.cmd_id = event->scan_id; 1668 cmd.cmd_cb = NULL; 1669 cmd.umac_cmd = NULL; 1670 cmd.source = WLAN_UMAC_COMP_SCAN; 1671 cmd.is_high_priority = false; 1672 cmd.vdev = vdev; 1673 if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { 1674 /* 1675 * We received scan event for an already completed/cancelled 1676 * scan request. Drop this event. 1677 */ 1678 scm_debug("Received scan event while request not in active queue"); 1679 goto exit; 1680 } 1681 1682 /* Fill scan_start_request used to trigger this scan */ 1683 queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id( 1684 wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), 1685 event->scan_id, true); 1686 1687 if (!queued_cmd) { 1688 scm_err("NULL queued_cmd"); 1689 goto exit; 1690 } 1691 if (!queued_cmd->umac_cmd) { 1692 scm_err("NULL umac_cmd"); 1693 goto exit; 1694 } 1695 scan_start_req = queued_cmd->umac_cmd; 1696 1697 if (scan_start_req->scan_req.scan_req_id != event->requester) { 1698 scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d", 1699 scan_start_req->scan_req.scan_req_id, event->requester); 1700 goto exit; 1701 } 1702 1703 if (scan) 1704 scm_scan_update_scan_event(scan, event, scan_start_req); 1705 1706 switch (event->type) { 1707 case SCAN_EVENT_TYPE_COMPLETED: 1708 if (event->reason == SCAN_REASON_COMPLETED) 1709 scm_11d_decide_country_code(vdev); 1710 /* release the command */ 1711 fallthrough; 1712 case SCAN_EVENT_TYPE_START_FAILED: 1713 case SCAN_EVENT_TYPE_DEQUEUED: 1714 scm_release_serialization_command(vdev, event->scan_id); 1715 break; 1716 default: 1717 break; 1718 } 1719 1720 scm_to_post_scan_duration_set(scan); 1721 /* Notify all interested parties */ 1722 scm_scan_post_event(vdev, event); 1723 1724 exit: 1725 /* free event info memory */ 1726 qdf_mem_free(event_info); 1727 1728 scm_event_duration_end(scan); 1729 1730 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1731 1732 return QDF_STATUS_SUCCESS; 1733 } 1734 1735 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg) 1736 { 1737 struct wlan_objmgr_vdev *vdev; 1738 struct scan_event_info *event_info; 1739 struct scan_event *event; 1740 1741 if (!msg || !msg->bodyptr) { 1742 scm_err("msg or msg->bodyptr is NULL"); 1743 return QDF_STATUS_E_NULL_VALUE; 1744 } 1745 1746 event_info = msg->bodyptr; 1747 vdev = event_info->vdev; 1748 event = &event_info->event; 1749 1750 scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d", 1751 event->vdev_id, event->type, event->reason, event->chan_freq, 1752 event->requester, event->scan_id); 1753 1754 /* free event info memory */ 1755 qdf_mem_free(event_info); 1756 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1757 1758 return QDF_STATUS_SUCCESS; 1759 } 1760 1761 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg) 1762 { 1763 struct scan_bcn_probe_event *bcn; 1764 1765 bcn = msg->bodyptr; 1766 1767 if (!bcn) { 1768 scm_err("bcn is NULL"); 1769 return QDF_STATUS_E_NULL_VALUE; 1770 } 1771 if (bcn->psoc) 1772 wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); 1773 if (bcn->rx_data) 1774 qdf_mem_free(bcn->rx_data); 1775 if (bcn->buf) 1776 qdf_nbuf_free(bcn->buf); 1777 qdf_mem_free(bcn); 1778 1779 return QDF_STATUS_SUCCESS; 1780 } 1781 1782 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg) 1783 { 1784 struct scan_start_request *req; 1785 1786 if (!msg || !msg->bodyptr) { 1787 scm_err("msg or msg->bodyptr is NULL"); 1788 return QDF_STATUS_E_NULL_VALUE; 1789 } 1790 1791 req = msg->bodyptr; 1792 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 1793 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1794 scm_scan_free_scan_request_mem(req); 1795 1796 return QDF_STATUS_SUCCESS; 1797 } 1798 1799 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg) 1800 { 1801 struct scan_cancel_request *req; 1802 1803 if (!msg || !msg->bodyptr) { 1804 scm_err("msg or msg->bodyptr is NULL"); 1805 return QDF_STATUS_E_NULL_VALUE; 1806 } 1807 1808 req = msg->bodyptr; 1809 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1810 /* Free cancel request memory */ 1811 qdf_mem_free(req); 1812 1813 return QDF_STATUS_SUCCESS; 1814 } 1815 1816 void scm_disable_obss_pdev_scan(struct wlan_objmgr_psoc *psoc, 1817 struct wlan_objmgr_pdev *pdev) 1818 { 1819 struct wlan_objmgr_vdev *vdev; 1820 struct wlan_scan_obj *scan_obj; 1821 struct scan_vdev_obj *scan_vdev_obj; 1822 QDF_STATUS status; 1823 struct wlan_objmgr_pdev_objmgr *pdev_objmgr; 1824 qdf_list_t *vdev_list; 1825 uint16_t index = 0; 1826 1827 scan_obj = wlan_psoc_get_scan_obj(psoc); 1828 if (!scan_obj) { 1829 scm_err("scan object null"); 1830 return; 1831 } 1832 1833 if (scan_obj->obss_scan_offload) { 1834 pdev_objmgr = &pdev->pdev_objmgr; 1835 1836 wlan_pdev_obj_lock(pdev); 1837 vdev_list = &pdev_objmgr->wlan_vdev_list; 1838 /* Get first vdev */ 1839 vdev = wlan_pdev_vdev_list_peek_head(vdev_list); 1840 1841 while (vdev) { 1842 scm_debug("wlan_vdev_list[%d]: %pK", index, vdev); 1843 1844 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1845 if (!scan_vdev_obj) { 1846 scm_err("null scan_vdev_obj"); 1847 goto next; 1848 } 1849 1850 status = tgt_scan_obss_disable(vdev); 1851 if (QDF_IS_STATUS_ERROR(status)) 1852 scm_err("disable obss scan failed"); 1853 next: 1854 index++; 1855 /* get next vdev */ 1856 vdev = wlan_vdev_get_next_vdev_of_pdev(vdev_list, 1857 vdev); 1858 } 1859 wlan_pdev_obj_unlock(pdev); 1860 } 1861 } 1862