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 * @req: scan request 1042 * 1043 * Return: void 1044 */ 1045 static void 1046 scm_req_update_dwell_time_as_per_scan_mode( 1047 struct wlan_objmgr_vdev *vdev, 1048 struct scan_start_request *req) 1049 { 1050 struct wlan_objmgr_psoc *psoc; 1051 1052 psoc = wlan_vdev_get_psoc(vdev); 1053 1054 if (req->scan_req.scan_policy_low_span && 1055 wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 1056 req->scan_req.adaptive_dwell_time_mode = 1057 SCAN_DWELL_MODE_STATIC; 1058 req->scan_req.dwell_time_active = 1059 QDF_MIN(req->scan_req.dwell_time_active, 1060 LOW_SPAN_ACTIVE_DWELL_TIME); 1061 req->scan_req.dwell_time_active_2g = 1062 QDF_MIN(req->scan_req.dwell_time_active_2g, 1063 LOW_SPAN_ACTIVE_DWELL_TIME); 1064 req->scan_req.dwell_time_passive = 1065 QDF_MIN(req->scan_req.dwell_time_passive, 1066 LOW_SPAN_PASSIVE_DWELL_TIME); 1067 } 1068 } 1069 1070 /** 1071 * scm_scan_req_update_params() - update scan req params depending on modes 1072 * and scan type. 1073 * @vdev: vdev object pointer 1074 * @req: scan request 1075 * @scan_obj: scan object 1076 * 1077 * Return: void 1078 */ 1079 static void 1080 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 1081 struct scan_start_request *req, 1082 struct wlan_scan_obj *scan_obj) 1083 { 1084 struct chan_list *custom_chan_list; 1085 struct wlan_objmgr_pdev *pdev; 1086 uint8_t pdev_id; 1087 1088 /* Ensure correct number of probes are sent on active channel */ 1089 if (!req->scan_req.repeat_probe_time) 1090 req->scan_req.repeat_probe_time = 1091 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 1092 1093 if (req->scan_req.scan_f_passive) 1094 req->scan_req.scan_ctrl_flags_ext |= 1095 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 1096 1097 if (!req->scan_req.n_probes) 1098 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 1099 req->scan_req.dwell_time_active / 1100 req->scan_req.repeat_probe_time : 0; 1101 1102 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH || 1103 req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1104 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 1105 req->scan_req.dwell_time_active_2g = 0; 1106 if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1107 req->scan_req.repeat_probe_time = 0; 1108 } else { 1109 req->scan_req.scan_f_filter_prb_req = true; 1110 if (!req->scan_req.num_ssids) 1111 req->scan_req.scan_f_bcast_probe = true; 1112 1113 req->scan_req.dwell_time_active += 1114 P2P_SEARCH_DWELL_TIME_INC; 1115 /* 1116 * 3 channels with default max dwell time 40 ms. 1117 * Cap limit will be set by 1118 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 1119 * should be such that no channel is scanned less 1120 * than the dwell time in normal scenarios. 1121 */ 1122 if (req->scan_req.chan_list.num_chan == 1123 WLAN_P2P_SOCIAL_CHANNELS && 1124 !scan_obj->miracast_enabled) 1125 req->scan_req.repeat_probe_time = 1126 req->scan_req.dwell_time_active / 5; 1127 else 1128 req->scan_req.repeat_probe_time = 1129 req->scan_req.dwell_time_active / 3; 1130 if (scan_obj->scan_def.p2p_scan_burst_duration) { 1131 req->scan_req.burst_duration = 1132 scan_obj->scan_def. 1133 p2p_scan_burst_duration; 1134 } else { 1135 req->scan_req.burst_duration = 1136 BURST_SCAN_MAX_NUM_OFFCHANNELS * 1137 req->scan_req.dwell_time_active; 1138 if (req->scan_req.burst_duration > 1139 P2P_SCAN_MAX_BURST_DURATION) { 1140 uint8_t channels = 1141 P2P_SCAN_MAX_BURST_DURATION / 1142 req->scan_req.dwell_time_active; 1143 if (channels) 1144 req->scan_req.burst_duration = 1145 channels * 1146 req->scan_req.dwell_time_active; 1147 else 1148 req->scan_req.burst_duration = 1149 P2P_SCAN_MAX_BURST_DURATION; 1150 } 1151 } 1152 req->scan_req.scan_ev_bss_chan = false; 1153 } 1154 } else { 1155 req->scan_req.scan_f_cck_rates = true; 1156 if (!req->scan_req.num_ssids) 1157 req->scan_req.scan_f_bcast_probe = true; 1158 req->scan_req.scan_f_add_ds_ie_in_probe = true; 1159 req->scan_req.scan_f_filter_prb_req = true; 1160 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 1161 } 1162 1163 scm_update_dbs_scan_ctrl_ext_flag(req); 1164 1165 /* 1166 * No need to update conncurrency parmas if req is passive scan on 1167 * single channel ie ROC, Preauth etc 1168 */ 1169 if (!(req->scan_req.scan_f_passive && 1170 req->scan_req.chan_list.num_chan == 1) && 1171 req->scan_req.scan_type != SCAN_TYPE_RRM) 1172 scm_req_update_concurrency_params(vdev, req, scan_obj); 1173 1174 if (req->scan_req.scan_type == SCAN_TYPE_RRM) 1175 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_RRM_SCAN_IND; 1176 1177 scm_req_update_dwell_time_as_per_scan_mode(vdev, req); 1178 1179 scm_debug("scan_ctrl_flags_ext %0x", req->scan_req.scan_ctrl_flags_ext); 1180 /* 1181 * Set wide band flag if enabled. This will cause 1182 * phymode TLV being sent to FW. 1183 */ 1184 pdev = wlan_vdev_get_pdev(vdev); 1185 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1186 if (ucfg_scan_get_wide_band_scan(pdev)) 1187 req->scan_req.scan_f_wide_band = true; 1188 else 1189 req->scan_req.scan_f_wide_band = false; 1190 1191 /* 1192 * Overwrite scan channels with custom scan channel 1193 * list if configured. 1194 */ 1195 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 1196 if (custom_chan_list->num_chan) 1197 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 1198 sizeof(struct chan_list)); 1199 else if (!req->scan_req.chan_list.num_chan) 1200 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 1201 1202 scm_update_channel_list(req, scan_obj); 1203 1204 wlan_scan_update_low_latency_profile_chnlist(vdev, req); 1205 } 1206 1207 static inline void scm_print_scan_req_info(struct scan_req_params *req) 1208 { 1209 uint32_t buff_len; 1210 char *chan_buff; 1211 uint32_t len = 0; 1212 uint8_t idx, count = 0; 1213 struct chan_list *chan_lst; 1214 #define MAX_SCAN_FREQ_TO_PRINT 25 1215 1216 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", 1217 req->scan_id, req->vdev_id, req->dwell_time_active, 1218 req->dwell_time_passive, req->dwell_time_active_2g, 1219 req->dwell_time_active_6g, req->dwell_time_passive_6g, 1220 req->repeat_probe_time, req->n_probes, req->scan_flags, 1221 req->scan_ctrl_flags_ext, req->scan_events, 1222 req->scan_policy_type, req->scan_f_wide_band, 1223 req->scan_priority); 1224 1225 for (idx = 0; idx < req->num_ssids; idx++) 1226 scm_nofl_debug("SSID[%d]: " QDF_SSID_FMT, idx, 1227 QDF_SSID_REF(req->ssid[idx].length, 1228 req->ssid[idx].ssid)); 1229 1230 chan_lst = &req->chan_list; 1231 1232 if (!chan_lst->num_chan) 1233 return; 1234 /* 1235 * Buffer of (num channel * 11) + 1 to consider the 4 char freq, 6 char 1236 * flags and 1 space after it for each channel and 1 to end the string 1237 * with NULL. 1238 */ 1239 buff_len = 1240 (QDF_MIN(MAX_SCAN_FREQ_TO_PRINT, chan_lst->num_chan) * 11) + 1; 1241 chan_buff = qdf_mem_malloc(buff_len); 1242 if (!chan_buff) 1243 return; 1244 scm_nofl_debug("Total freq %d", chan_lst->num_chan); 1245 for (idx = 0; idx < chan_lst->num_chan; idx++) { 1246 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1247 "%d(0x%02x) ", chan_lst->chan[idx].freq, 1248 chan_lst->chan[idx].flags); 1249 count++; 1250 if (count >= MAX_SCAN_FREQ_TO_PRINT) { 1251 /* Print the MAX_SCAN_FREQ_TO_PRINT channels */ 1252 scm_nofl_debug("Freq list: %s", chan_buff); 1253 len = 0; 1254 count = 0; 1255 } 1256 } 1257 if (len) 1258 scm_nofl_debug("Freq list: %s", chan_buff); 1259 1260 qdf_mem_free(chan_buff); 1261 } 1262 QDF_STATUS 1263 scm_scan_start_req(struct scheduler_msg *msg) 1264 { 1265 struct wlan_serialization_command cmd = {0, }; 1266 enum wlan_serialization_status ser_cmd_status; 1267 struct scan_start_request *req = NULL; 1268 struct wlan_scan_obj *scan_obj; 1269 QDF_STATUS status = QDF_STATUS_SUCCESS; 1270 1271 1272 if (!msg) { 1273 scm_err("msg received is NULL"); 1274 QDF_ASSERT(0); 1275 return QDF_STATUS_E_NULL_VALUE; 1276 } 1277 if (!msg->bodyptr) { 1278 scm_err("bodyptr is NULL"); 1279 QDF_ASSERT(0); 1280 return QDF_STATUS_E_NULL_VALUE; 1281 } 1282 1283 req = msg->bodyptr; 1284 1285 if (!scm_is_scan_allowed(req->vdev)) { 1286 scm_err("scan disabled, rejecting the scan req"); 1287 status = QDF_STATUS_E_NULL_VALUE; 1288 goto err; 1289 } 1290 1291 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 1292 if (!scan_obj) { 1293 scm_debug("Couldn't find scan object"); 1294 status = QDF_STATUS_E_NULL_VALUE; 1295 goto err; 1296 } 1297 1298 scm_scan_req_update_params(req->vdev, req, scan_obj); 1299 scm_print_scan_req_info(&req->scan_req); 1300 1301 if (!req->scan_req.chan_list.num_chan) { 1302 scm_info("Reject 0 channel Scan"); 1303 status = QDF_STATUS_E_NULL_VALUE; 1304 goto err; 1305 } 1306 1307 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1308 cmd.cmd_id = req->scan_req.scan_id; 1309 cmd.cmd_cb = scm_scan_serialize_callback; 1310 cmd.umac_cmd = req; 1311 cmd.source = WLAN_UMAC_COMP_SCAN; 1312 cmd.is_high_priority = false; 1313 cmd.cmd_timeout_duration = req->scan_req.max_scan_time + 1314 SCAN_TIMEOUT_GRACE_PERIOD; 1315 cmd.vdev = req->vdev; 1316 1317 if (scan_obj->disable_timeout) 1318 cmd.cmd_timeout_duration = 0; 1319 1320 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION, 1321 WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id, 1322 req->scan_req.scan_id); 1323 1324 ser_cmd_status = wlan_serialization_request(&cmd); 1325 switch (ser_cmd_status) { 1326 case WLAN_SER_CMD_PENDING: 1327 /* command moved to pending list.Do nothing */ 1328 break; 1329 case WLAN_SER_CMD_ACTIVE: 1330 /* command moved to active list. Do nothing */ 1331 break; 1332 default: 1333 scm_debug("ser cmd status %d", ser_cmd_status); 1334 goto err; 1335 } 1336 1337 return status; 1338 err: 1339 /* 1340 * notify registered scan event handlers 1341 * about internal error 1342 */ 1343 scm_post_internal_scan_complete_event(req, 1344 SCAN_REASON_INTERNAL_FAILURE); 1345 /* 1346 * cmd can't be serviced. 1347 * release vdev reference and free scan_start_request memory 1348 */ 1349 if (req) { 1350 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1351 scm_scan_free_scan_request_mem(req); 1352 } 1353 1354 return status; 1355 } 1356 1357 static inline enum wlan_serialization_cancel_type 1358 get_serialization_cancel_type(enum scan_cancel_req_type type) 1359 { 1360 enum wlan_serialization_cancel_type serialization_type; 1361 1362 switch (type) { 1363 case WLAN_SCAN_CANCEL_SINGLE: 1364 serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN; 1365 break; 1366 case WLAN_SCAN_CANCEL_VDEV_ALL: 1367 serialization_type = WLAN_SER_CANCEL_VDEV_SCANS; 1368 break; 1369 case WLAN_SCAN_CANCEL_PDEV_ALL: 1370 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1371 break; 1372 case WLAN_SCAN_CANCEL_HOST_VDEV_ALL: 1373 serialization_type = WLAN_SER_CANCEL_VDEV_HOST_SCANS; 1374 break; 1375 default: 1376 QDF_ASSERT(0); 1377 scm_warn("invalid scan_cancel_req_type: %d", type); 1378 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1379 break; 1380 } 1381 1382 return serialization_type; 1383 } 1384 1385 QDF_STATUS 1386 scm_scan_cancel_req(struct scheduler_msg *msg) 1387 { 1388 struct wlan_serialization_queued_cmd_info cmd = {0,}; 1389 struct wlan_serialization_command ser_cmd = {0,}; 1390 enum wlan_serialization_cmd_status ser_cmd_status; 1391 struct scan_cancel_request *req; 1392 QDF_STATUS status = QDF_STATUS_SUCCESS; 1393 1394 if (!msg) { 1395 scm_err("msg received is NULL"); 1396 QDF_ASSERT(0); 1397 return QDF_STATUS_E_NULL_VALUE; 1398 } 1399 if (!msg->bodyptr) { 1400 scm_err("Bodyptr is NULL"); 1401 QDF_ASSERT(0); 1402 return QDF_STATUS_E_NULL_VALUE; 1403 } 1404 1405 req = msg->bodyptr; 1406 /* 1407 * If requester wants to wait for target scan cancel event 1408 * instead of internally generated cancel event, just check 1409 * which queue this scan request belongs to and send scan 1410 * cancel request to FW accordingly. 1411 * Else generate internal scan cancel event and notify 1412 * handlers and free scan request resources. 1413 */ 1414 if (req->wait_tgt_cancel && 1415 (req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) { 1416 ser_cmd.cmd_type = WLAN_SER_CMD_SCAN; 1417 ser_cmd.cmd_id = req->cancel_req.scan_id; 1418 ser_cmd.cmd_cb = NULL; 1419 ser_cmd.umac_cmd = NULL; 1420 ser_cmd.source = WLAN_UMAC_COMP_SCAN; 1421 ser_cmd.is_high_priority = false; 1422 ser_cmd.vdev = req->vdev; 1423 if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd)) 1424 ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST; 1425 else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd)) 1426 ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST; 1427 else 1428 ser_cmd_status = WLAN_SER_CMD_NOT_FOUND; 1429 } else { 1430 cmd.requestor = 0; 1431 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1432 cmd.cmd_id = req->cancel_req.scan_id; 1433 cmd.vdev = req->vdev; 1434 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE | 1435 WLAN_SERIALIZATION_PENDING_QUEUE; 1436 cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type); 1437 1438 ser_cmd_status = wlan_serialization_cancel_request(&cmd); 1439 } 1440 1441 scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d", 1442 ser_cmd_status, req->cancel_req.requester, 1443 req->cancel_req.scan_id, req->cancel_req.vdev_id, 1444 req->cancel_req.req_type); 1445 1446 switch (ser_cmd_status) { 1447 case WLAN_SER_CMD_IN_PENDING_LIST: 1448 /* do nothing */ 1449 break; 1450 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1451 case WLAN_SER_CMDS_IN_ALL_LISTS: 1452 /* send wmi scan cancel to fw */ 1453 status = tgt_scan_cancel(req); 1454 break; 1455 case WLAN_SER_CMD_NOT_FOUND: 1456 /* do nothing */ 1457 break; 1458 default: 1459 QDF_ASSERT(0); 1460 status = QDF_STATUS_E_INVAL; 1461 break; 1462 } 1463 1464 /* Release vdev reference and scan cancel request 1465 * processing is complete 1466 */ 1467 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1468 /* Free cancel request memory */ 1469 qdf_mem_free(req); 1470 1471 return status; 1472 } 1473 1474 #ifdef FEATURE_WLAN_SCAN_PNO 1475 static QDF_STATUS 1476 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1477 struct scan_event *event) 1478 { 1479 struct scan_vdev_obj *scan_vdev_obj; 1480 struct wlan_scan_obj *scan_psoc_obj; 1481 scan_event_handler pno_cb; 1482 void *cb_arg; 1483 1484 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1485 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 1486 if (!scan_vdev_obj || !scan_psoc_obj) { 1487 scm_err("null scan_vdev_obj %pK scan_obj %pK", 1488 scan_vdev_obj, scan_psoc_obj); 1489 return QDF_STATUS_E_INVAL; 1490 } 1491 1492 switch (event->type) { 1493 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1494 if (!scan_vdev_obj->pno_match_evt_received) 1495 return QDF_STATUS_SUCCESS; 1496 qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock, 1497 WIFI_POWER_EVENT_WAKELOCK_PNO); 1498 qdf_wake_lock_timeout_acquire( 1499 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1500 SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT); 1501 qdf_runtime_pm_allow_suspend( 1502 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1503 scan_vdev_obj->pno_match_evt_received = false; 1504 break; 1505 case SCAN_EVENT_TYPE_NLO_MATCH: 1506 scan_vdev_obj->pno_match_evt_received = true; 1507 qdf_wake_lock_timeout_acquire( 1508 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1509 SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT); 1510 qdf_runtime_pm_prevent_suspend( 1511 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1512 return QDF_STATUS_SUCCESS; 1513 default: 1514 return QDF_STATUS_E_INVAL; 1515 } 1516 qdf_spin_lock_bh(&scan_psoc_obj->lock); 1517 pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func; 1518 cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg; 1519 qdf_spin_unlock_bh(&scan_psoc_obj->lock); 1520 1521 if (pno_cb) 1522 pno_cb(vdev, event, cb_arg); 1523 1524 return QDF_STATUS_SUCCESS; 1525 } 1526 #else 1527 1528 static QDF_STATUS 1529 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1530 struct scan_event *event) 1531 { 1532 return QDF_STATUS_SUCCESS; 1533 } 1534 #endif 1535 1536 /** 1537 * scm_scan_update_scan_event() - update scan event 1538 * @scan: scan object 1539 * @event: scan event 1540 * @scan_start_req: scan_start_req used for triggering scan 1541 * 1542 * update scan params in scan event 1543 * 1544 * Return: QDF_STATUS 1545 */ 1546 static QDF_STATUS 1547 scm_scan_update_scan_event(struct wlan_scan_obj *scan, 1548 struct scan_event *event, 1549 struct scan_start_request *scan_start_req) 1550 { 1551 if (!event) 1552 return QDF_STATUS_E_NULL_VALUE; 1553 1554 if (!scan || !scan_start_req) { 1555 event->scan_start_req = NULL; 1556 return QDF_STATUS_E_NULL_VALUE; 1557 } 1558 /* copy scan start request to pass back buffer */ 1559 qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req, 1560 sizeof(struct scan_start_request)); 1561 /* reset all pointers */ 1562 scan->scan_start_request_buff.scan_req.extraie.ptr = NULL; 1563 scan->scan_start_request_buff.scan_req.extraie.len = 0; 1564 scan->scan_start_request_buff.scan_req.htcap.ptr = NULL; 1565 scan->scan_start_request_buff.scan_req.htcap.len = 0; 1566 scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL; 1567 scan->scan_start_request_buff.scan_req.vhtcap.len = 0; 1568 1569 event->scan_start_req = &scan->scan_start_request_buff; 1570 1571 return QDF_STATUS_SUCCESS; 1572 } 1573 1574 static 1575 void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev, 1576 uint32_t chan_freq, uint32_t time) 1577 { 1578 struct wlan_scan_obj *scan_obj; 1579 struct chan_list_scan_info *chan_info; 1580 bool chan_found = false; 1581 uint8_t pdev_id; 1582 int i; 1583 1584 scan_obj = wlan_vdev_get_scan_obj(vdev); 1585 if (!scan_obj) 1586 return; 1587 1588 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 1589 chan_info = &scan_obj->pdev_info[pdev_id].chan_scan_info; 1590 1591 for (i = 0; i < chan_info->num_chan ; i++) { 1592 if (chan_info->ch_scan_info[i].freq == chan_freq) { 1593 chan_info->ch_scan_info[i].last_scan_time = time; 1594 scm_debug("chan freq %d scan time %u\n", 1595 chan_freq, time); 1596 chan_found = true; 1597 break; 1598 } 1599 } 1600 1601 if (!chan_found) { 1602 chan_info->ch_scan_info[chan_info->num_chan].freq = chan_freq; 1603 chan_info->ch_scan_info[chan_info->num_chan].last_scan_time = 1604 time; 1605 chan_info->num_chan++; 1606 scm_debug("chan freq %d scan time %u\n", chan_freq, time); 1607 } 1608 } 1609 1610 QDF_STATUS 1611 scm_scan_event_handler(struct scheduler_msg *msg) 1612 { 1613 struct wlan_objmgr_vdev *vdev; 1614 struct scan_event *event; 1615 struct scan_event_info *event_info; 1616 struct wlan_serialization_command cmd = {0,}; 1617 struct wlan_serialization_command *queued_cmd; 1618 struct scan_start_request *scan_start_req; 1619 struct wlan_scan_obj *scan; 1620 1621 if (!msg) { 1622 scm_err("NULL msg received "); 1623 QDF_ASSERT(0); 1624 return QDF_STATUS_E_NULL_VALUE; 1625 } 1626 if (!msg->bodyptr) { 1627 scm_err("NULL scan event received"); 1628 QDF_ASSERT(0); 1629 return QDF_STATUS_E_NULL_VALUE; 1630 } 1631 1632 event_info = msg->bodyptr; 1633 vdev = event_info->vdev; 1634 event = &(event_info->event); 1635 1636 scan = wlan_vdev_get_scan_obj(vdev); 1637 1638 scm_duration_init(scan); 1639 1640 scm_event_duration_start(scan); 1641 1642 scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d," 1643 "scanid:%d (0x%x), timestamp:%u", event->vdev_id, 1644 event->type, event->reason, event->chan_freq, 1645 event->requester, event->scan_id, event->scan_id, 1646 event->timestamp); 1647 1648 if (event->type == SCAN_EVENT_TYPE_FOREIGN_CHANNEL) 1649 scm_update_last_scan_time_per_channel( 1650 vdev, event->chan_freq, qdf_get_time_of_the_day_ms()); 1651 1652 /* 1653 * NLO requests are never queued, so post NLO events 1654 * without checking for their presence in active queue. 1655 */ 1656 switch (event->type) { 1657 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1658 case SCAN_EVENT_TYPE_NLO_MATCH: 1659 scm_pno_event_handler(vdev, event); 1660 goto exit; 1661 default: 1662 break; 1663 } 1664 1665 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1666 cmd.cmd_id = event->scan_id; 1667 cmd.cmd_cb = NULL; 1668 cmd.umac_cmd = NULL; 1669 cmd.source = WLAN_UMAC_COMP_SCAN; 1670 cmd.is_high_priority = false; 1671 cmd.vdev = vdev; 1672 if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { 1673 /* 1674 * We received scan event for an already completed/cancelled 1675 * scan request. Drop this event. 1676 */ 1677 scm_debug("Received scan event while request not in active queue"); 1678 goto exit; 1679 } 1680 1681 /* Fill scan_start_request used to trigger this scan */ 1682 queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id( 1683 wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), 1684 event->scan_id, true); 1685 1686 if (!queued_cmd) { 1687 scm_err("NULL queued_cmd"); 1688 goto exit; 1689 } 1690 if (!queued_cmd->umac_cmd) { 1691 scm_err("NULL umac_cmd"); 1692 goto exit; 1693 } 1694 scan_start_req = queued_cmd->umac_cmd; 1695 1696 if (scan_start_req->scan_req.scan_req_id != event->requester) { 1697 scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d", 1698 scan_start_req->scan_req.scan_req_id, event->requester); 1699 goto exit; 1700 } 1701 1702 if (scan) 1703 scm_scan_update_scan_event(scan, event, scan_start_req); 1704 1705 switch (event->type) { 1706 case SCAN_EVENT_TYPE_COMPLETED: 1707 if (event->reason == SCAN_REASON_COMPLETED) 1708 scm_11d_decide_country_code(vdev); 1709 /* release the command */ 1710 fallthrough; 1711 case SCAN_EVENT_TYPE_START_FAILED: 1712 case SCAN_EVENT_TYPE_DEQUEUED: 1713 scm_release_serialization_command(vdev, event->scan_id); 1714 break; 1715 default: 1716 break; 1717 } 1718 1719 scm_to_post_scan_duration_set(scan); 1720 /* Notify all interested parties */ 1721 scm_scan_post_event(vdev, event); 1722 1723 exit: 1724 /* free event info memory */ 1725 qdf_mem_free(event_info); 1726 1727 scm_event_duration_end(scan); 1728 1729 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1730 1731 return QDF_STATUS_SUCCESS; 1732 } 1733 1734 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg) 1735 { 1736 struct wlan_objmgr_vdev *vdev; 1737 struct scan_event_info *event_info; 1738 struct scan_event *event; 1739 1740 if (!msg || !msg->bodyptr) { 1741 scm_err("msg or msg->bodyptr is NULL"); 1742 return QDF_STATUS_E_NULL_VALUE; 1743 } 1744 1745 event_info = msg->bodyptr; 1746 vdev = event_info->vdev; 1747 event = &event_info->event; 1748 1749 scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d", 1750 event->vdev_id, event->type, event->reason, event->chan_freq, 1751 event->requester, event->scan_id); 1752 1753 /* free event info memory */ 1754 qdf_mem_free(event_info); 1755 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1756 1757 return QDF_STATUS_SUCCESS; 1758 } 1759 1760 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg) 1761 { 1762 struct scan_bcn_probe_event *bcn; 1763 1764 bcn = msg->bodyptr; 1765 1766 if (!bcn) { 1767 scm_err("bcn is NULL"); 1768 return QDF_STATUS_E_NULL_VALUE; 1769 } 1770 if (bcn->psoc) 1771 wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); 1772 if (bcn->rx_data) 1773 qdf_mem_free(bcn->rx_data); 1774 if (bcn->buf) 1775 qdf_nbuf_free(bcn->buf); 1776 qdf_mem_free(bcn); 1777 1778 return QDF_STATUS_SUCCESS; 1779 } 1780 1781 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg) 1782 { 1783 struct scan_start_request *req; 1784 1785 if (!msg || !msg->bodyptr) { 1786 scm_err("msg or msg->bodyptr is NULL"); 1787 return QDF_STATUS_E_NULL_VALUE; 1788 } 1789 1790 req = msg->bodyptr; 1791 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 1792 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1793 scm_scan_free_scan_request_mem(req); 1794 1795 return QDF_STATUS_SUCCESS; 1796 } 1797 1798 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg) 1799 { 1800 struct scan_cancel_request *req; 1801 1802 if (!msg || !msg->bodyptr) { 1803 scm_err("msg or msg->bodyptr is NULL"); 1804 return QDF_STATUS_E_NULL_VALUE; 1805 } 1806 1807 req = msg->bodyptr; 1808 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1809 /* Free cancel request memory */ 1810 qdf_mem_free(req); 1811 1812 return QDF_STATUS_SUCCESS; 1813 } 1814 1815 void scm_disable_obss_pdev_scan(struct wlan_objmgr_psoc *psoc, 1816 struct wlan_objmgr_pdev *pdev) 1817 { 1818 struct wlan_objmgr_vdev *vdev; 1819 struct wlan_scan_obj *scan_obj; 1820 struct scan_vdev_obj *scan_vdev_obj; 1821 QDF_STATUS status; 1822 struct wlan_objmgr_pdev_objmgr *pdev_objmgr; 1823 qdf_list_t *vdev_list; 1824 uint16_t index = 0; 1825 1826 scan_obj = wlan_psoc_get_scan_obj(psoc); 1827 if (!scan_obj) { 1828 scm_err("scan object null"); 1829 return; 1830 } 1831 1832 if (scan_obj->obss_scan_offload) { 1833 pdev_objmgr = &pdev->pdev_objmgr; 1834 1835 wlan_pdev_obj_lock(pdev); 1836 vdev_list = &pdev_objmgr->wlan_vdev_list; 1837 /* Get first vdev */ 1838 vdev = wlan_pdev_vdev_list_peek_head(vdev_list); 1839 1840 while (vdev) { 1841 scm_debug("wlan_vdev_list[%d]: %pK", index, vdev); 1842 1843 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1844 if (!scan_vdev_obj) { 1845 scm_err("null scan_vdev_obj"); 1846 goto next; 1847 } 1848 1849 status = tgt_scan_obss_disable(vdev); 1850 if (QDF_IS_STATUS_ERROR(status)) 1851 scm_err("disable obss scan failed"); 1852 next: 1853 index++; 1854 /* get next vdev */ 1855 vdev = wlan_vdev_get_next_vdev_of_pdev(vdev_list, 1856 vdev); 1857 } 1858 wlan_pdev_obj_unlock(pdev); 1859 } 1860 } 1861