1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * DOC: 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 /** 475 * scm_update_passive_dwell_time() - update dwell passive time 476 * @vdev: vdev object 477 * @req: scan request 478 * 479 * Return: None 480 */ 481 static void 482 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 483 struct scan_start_request *req) 484 { 485 struct wlan_objmgr_psoc *psoc; 486 487 psoc = wlan_vdev_get_psoc(vdev); 488 if (!psoc) 489 return; 490 491 if (policy_mgr_is_sta_connected_2g(psoc) && 492 !policy_mgr_is_hw_dbs_capable(psoc) && 493 ucfg_scan_get_bt_activity(psoc)) 494 req->scan_req.dwell_time_passive = 495 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 496 } 497 498 static const struct probe_time_dwell_time 499 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 500 {28, 11}, /* 0 SSID */ 501 {28, 20}, /* 1 SSID */ 502 {28, 20}, /* 2 SSID */ 503 {28, 20}, /* 3 SSID */ 504 {28, 20}, /* 4 SSID */ 505 {28, 20}, /* 5 SSID */ 506 {28, 20}, /* 6 SSID */ 507 {28, 11}, /* 7 SSID */ 508 {28, 11}, /* 8 SSID */ 509 {28, 11}, /* 9 SSID */ 510 {28, 8} /* 10 SSID */ 511 }; 512 513 /** 514 * scm_scan_get_burst_duration() - get burst duration depending on max chan 515 * and miracast. 516 * @max_ch_time: max channel time 517 * @miracast_enabled: if miracast is enabled 518 * 519 * Return: burst_duration 520 */ 521 static inline 522 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) 523 { 524 int burst_duration = 0; 525 526 if (miracast_enabled) { 527 /* 528 * When miracast is running, burst 529 * duration needs to be minimum to avoid 530 * any stutter or glitch in miracast 531 * during station scan 532 */ 533 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 534 burst_duration = max_ch_time; 535 else 536 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 537 } else { 538 /* 539 * If miracast is not running, accommodate max 540 * stations to make the scans faster 541 */ 542 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 543 max_ch_time; 544 545 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 546 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 547 max_ch_time; 548 549 if (channels) 550 burst_duration = channels * max_ch_time; 551 else 552 burst_duration = 553 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 554 } 555 } 556 return burst_duration; 557 } 558 559 #define SCM_ACTIVE_DWELL_TIME_NAN 60 560 #define SCM_ACTIVE_DWELL_TIME_SAP 40 561 562 /** 563 * scm_req_update_concurrency_params() - update scan req params depending on 564 * concurrent mode present. 565 * @vdev: vdev object pointer 566 * @req: scan request 567 * @scan_obj: scan object 568 * 569 * Return: void 570 */ 571 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 572 struct scan_start_request *req, 573 struct wlan_scan_obj *scan_obj) 574 { 575 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 576 struct wlan_objmgr_psoc *psoc; 577 uint16_t sap_peer_count = 0; 578 uint16_t go_peer_count = 0; 579 struct wlan_objmgr_pdev *pdev; 580 581 psoc = wlan_vdev_get_psoc(vdev); 582 pdev = wlan_vdev_get_pdev(vdev); 583 584 if (!psoc || !pdev) 585 return; 586 587 ap_present = policy_mgr_mode_specific_connection_count( 588 psoc, PM_SAP_MODE, NULL); 589 go_present = policy_mgr_mode_specific_connection_count( 590 psoc, PM_P2P_GO_MODE, NULL); 591 p2p_cli_present = policy_mgr_mode_specific_connection_count( 592 psoc, PM_P2P_CLIENT_MODE, NULL); 593 sta_active = policy_mgr_mode_specific_connection_count( 594 psoc, PM_STA_MODE, NULL); 595 ndi_present = policy_mgr_mode_specific_connection_count( 596 psoc, PM_NDI_MODE, NULL); 597 if (ap_present) 598 sap_peer_count = 599 wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); 600 if (go_present) 601 go_peer_count = 602 wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); 603 604 if (!req->scan_req.scan_f_passive) 605 scm_update_passive_dwell_time(vdev, req); 606 607 if (policy_mgr_get_connection_count(psoc)) { 608 if (!req->scan_req.scan_f_passive) 609 req->scan_req.dwell_time_active = 610 scan_obj->scan_def.conc_active_dwell; 611 /* 612 * Irrespective of any concurrency, if a scan request is 613 * triggered to get channel utilization for the current 614 * connected channel, passive scan dwell time should be 615 * MLME_GET_CHAN_STATS_PASSIVE_SCAN_TIME 616 */ 617 if (!req->scan_req.scan_f_pause_home_channel) 618 req->scan_req.dwell_time_passive = 619 scan_obj->scan_def.conc_passive_dwell; 620 req->scan_req.max_rest_time = 621 scan_obj->scan_def.conc_max_rest_time; 622 req->scan_req.min_rest_time = 623 scan_obj->scan_def.conc_min_rest_time; 624 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 625 } 626 627 if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) 628 req->scan_req.adaptive_dwell_time_mode = 629 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 630 /* 631 * If AP/GO is active and has connected clients : 632 * 1.set min rest time same as max rest time, so that 633 * firmware spends more time on home channel which will 634 * increase the probability of sending beacon at TBTT 635 * 2.if DBS is supported and SAP is not on 2g, 636 * do not reset active dwell time for 2g. 637 */ 638 639 /* 640 * For SAP, the dwell time cannot exceed 32 ms as it can't go 641 * offchannel more than 32 ms. For Go, since we 642 * advertise NOA, GO can have regular dwell time which is 40 ms. 643 */ 644 if ((ap_present && sap_peer_count) || 645 (go_present && go_peer_count)) { 646 if ((policy_mgr_is_hw_dbs_capable(psoc) && 647 policy_mgr_is_sap_go_on_2g(psoc)) || 648 !policy_mgr_is_hw_dbs_capable(psoc)) { 649 if (ap_present) 650 req->scan_req.dwell_time_active_2g = 651 QDF_MIN(req->scan_req.dwell_time_active, 652 (SCAN_CTS_DURATION_MS_MAX - 653 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 654 else 655 req->scan_req.dwell_time_active_2g = 0; 656 } 657 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 658 } 659 660 if (policy_mgr_current_concurrency_is_mcc(psoc)) 661 req->scan_req.min_rest_time = 662 scan_obj->scan_def.conc_max_rest_time; 663 664 /* 665 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell 666 * time for 2g channels instead of dwell_time_active_2g 667 */ 668 if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) 669 req->scan_req.dwell_time_active_2g = SCM_ACTIVE_DWELL_TIME_SAP; 670 671 if (req->scan_req.scan_type == SCAN_TYPE_DEFAULT) { 672 /* 673 * Decide burst_duration and dwell_time_active based on 674 * what type of devices are active. 675 */ 676 do { 677 if (ap_present && go_present && sta_active) { 678 if (req->scan_req.dwell_time_active <= 679 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 680 req->scan_req.burst_duration = 681 req->scan_req.dwell_time_active; 682 else 683 req->scan_req.burst_duration = 684 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 685 686 break; 687 } 688 689 if (scan_obj->miracast_enabled && 690 policy_mgr_is_mcc_in_24G(psoc)) 691 req->scan_req.max_rest_time = 692 scan_obj->scan_def.sta_miracast_mcc_rest_time; 693 694 if (go_present) { 695 /* 696 * Background scan while GO is sending beacons. 697 * Every off-channel transition has overhead of 698 * 2 beacon intervals for NOA. Maximize number 699 * of channels in every transition by using 700 * burst scan. 701 */ 702 if (scan_obj->scan_def.go_scan_burst_duration) 703 req->scan_req.burst_duration = 704 scan_obj-> 705 scan_def.go_scan_burst_duration; 706 else 707 req->scan_req.burst_duration = 708 scm_scan_get_burst_duration( 709 req->scan_req. 710 dwell_time_active, 711 scan_obj-> 712 miracast_enabled); 713 break; 714 } 715 if ((sta_active || p2p_cli_present)) { 716 if (scan_obj->scan_def.sta_scan_burst_duration) 717 req->scan_req.burst_duration = 718 scan_obj->scan_def. 719 sta_scan_burst_duration; 720 break; 721 } 722 723 if (go_present && sta_active) { 724 req->scan_req.burst_duration = 725 req->scan_req.dwell_time_active; 726 break; 727 } 728 729 if (ndi_present || (p2p_cli_present && sta_active)) { 730 req->scan_req.burst_duration = 0; 731 break; 732 } 733 } while (0); 734 735 if (ap_present) { 736 uint8_t ssid_num; 737 738 ssid_num = req->scan_req.num_ssids * 739 req->scan_req.num_bssid; 740 req->scan_req.repeat_probe_time = 741 scan_probe_time_dwell_time_map[ 742 QDF_MIN(ssid_num, 743 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 744 - 1)].probe_time; 745 req->scan_req.n_probes = 746 (req->scan_req.repeat_probe_time > 0) ? 747 req->scan_req.dwell_time_active / 748 req->scan_req.repeat_probe_time : 0; 749 } 750 } 751 752 if (ap_present) { 753 uint16_t ap_chan_freq; 754 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 755 756 ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 757 /* 758 * P2P/STA scan while SoftAP is sending beacons. 759 * Max duration of CTS2self is 32 ms, which limits the 760 * dwell time. 761 * If DBS is supported and: 762 * 1.if SAP is on 2G channel then keep passive 763 * dwell time default. 764 * 2.if SAP is on 5G/6G channel then update dwell time active. 765 */ 766 if (sap_peer_count) { 767 if (policy_mgr_is_hw_dbs_capable(psoc) && 768 (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) || 769 WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) { 770 req->scan_req.dwell_time_active = 771 QDF_MIN(req->scan_req.dwell_time_active, 772 (SCAN_CTS_DURATION_MS_MAX - 773 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 774 } 775 if (!policy_mgr_is_hw_dbs_capable(psoc) || 776 (policy_mgr_is_hw_dbs_capable(psoc) && 777 WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) { 778 req->scan_req.dwell_time_passive = 779 req->scan_req.dwell_time_active; 780 } 781 } 782 783 if (scan_obj->scan_def.ap_scan_burst_duration) { 784 req->scan_req.burst_duration = 785 scan_obj->scan_def.ap_scan_burst_duration; 786 } else { 787 req->scan_req.burst_duration = 0; 788 if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq)) 789 req->scan_req.burst_duration = 790 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 791 req->scan_req.dwell_time_active; 792 } 793 } 794 795 if (ndi_present) { 796 req->scan_req.dwell_time_active = 797 SCM_ACTIVE_DWELL_TIME_NAN; 798 req->scan_req.dwell_time_active_2g = 799 QDF_MIN(req->scan_req.dwell_time_active_2g, 800 SCM_ACTIVE_DWELL_TIME_NAN); 801 scm_debug("NDP active modify dwell time 2ghz %d", 802 req->scan_req.dwell_time_active_2g); 803 } 804 805 if (sta_active) { 806 req->scan_req.dwell_time_active_6g = 807 scan_obj->scan_def.active_dwell_time_6g_conc; 808 /* 809 * Irrespective of any concurrency, if a scan request is 810 * triggered to get channel utilization for the current 811 * connected channel, 6g passive scan dwell time should be 812 * MLME_GET_CHAN_STATS_WIDE_BAND_PASSIVE_SCAN_TIME 813 */ 814 if (!req->scan_req.scan_f_pause_home_channel) 815 req->scan_req.dwell_time_passive_6g = 816 scan_obj->scan_def.passive_dwell_time_6g_conc; 817 } 818 } 819 820 static inline void scm_update_5ghz_6ghz_chlist(struct scan_start_request *req, 821 qdf_freq_t intf_freq) 822 { 823 struct wlan_objmgr_psoc *psoc; 824 struct wlan_objmgr_pdev *pdev; 825 uint32_t i; 826 uint32_t num_scan_channels; 827 828 pdev = wlan_vdev_get_pdev(req->vdev); 829 if (!pdev) 830 return; 831 832 psoc = wlan_pdev_get_psoc(pdev); 833 if (!psoc) 834 return; 835 836 num_scan_channels = 0; 837 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 838 if (!WLAN_REG_IS_24GHZ_CH_FREQ( 839 req->scan_req.chan_list.chan[i].freq)) { 840 /* 841 * If no intf_freq, skip all 5 + 6 GHz freq 842 * else, skip only freq on same mac as intf_freq 843 */ 844 if (!intf_freq || 845 policy_mgr_2_freq_always_on_same_mac( 846 psoc, intf_freq, 847 req->scan_req.chan_list.chan[i].freq)) 848 continue; 849 } 850 851 req->scan_req.chan_list.chan[num_scan_channels++] = 852 req->scan_req.chan_list.chan[i]; 853 } 854 if (num_scan_channels < req->scan_req.chan_list.num_chan) 855 scm_debug("5g chan skipped (%d, %d)", 856 req->scan_req.chan_list.num_chan, num_scan_channels); 857 req->scan_req.chan_list.num_chan = num_scan_channels; 858 } 859 860 static inline void scm_update_24g_chlist(struct scan_start_request *req) 861 { 862 uint32_t i; 863 uint32_t num_scan_channels; 864 865 num_scan_channels = 0; 866 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 867 if (WLAN_REG_IS_24GHZ_CH_FREQ( 868 req->scan_req.chan_list.chan[i].freq)) 869 continue; 870 871 req->scan_req.chan_list.chan[num_scan_channels++] = 872 req->scan_req.chan_list.chan[i]; 873 } 874 if (num_scan_channels < req->scan_req.chan_list.num_chan) 875 scm_debug("2g chan skipped (%d, %d)", 876 req->scan_req.chan_list.num_chan, num_scan_channels); 877 req->scan_req.chan_list.num_chan = num_scan_channels; 878 } 879 880 /** 881 * scm_filter_6g_and_indoor_freq() - Modify channel list to skip 6Ghz and 5Ghz 882 * indoor channel if hw mode is non dbs and SAP is present 883 * @pdev: pointer to pdev 884 * @req: scan request 885 * 886 * Return: None 887 */ 888 static void scm_filter_6g_and_indoor_freq(struct wlan_objmgr_pdev *pdev, 889 struct scan_start_request *req) 890 { 891 uint32_t i; 892 uint32_t num_scan_channels; 893 qdf_freq_t freq; 894 895 num_scan_channels = 0; 896 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 897 freq = req->scan_req.chan_list.chan[i].freq; 898 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) 899 continue; 900 901 if (wlan_reg_is_freq_indoor(pdev, freq)) 902 continue; 903 904 req->scan_req.chan_list.chan[num_scan_channels++] = 905 req->scan_req.chan_list.chan[i]; 906 } 907 if (num_scan_channels < req->scan_req.chan_list.num_chan) 908 scm_debug("6g and indoor channel chan skipped (%d, %d)", 909 req->scan_req.chan_list.num_chan, num_scan_channels); 910 req->scan_req.chan_list.num_chan = num_scan_channels; 911 } 912 913 /** 914 * scm_scan_chlist_concurrency_modify() - modify chan list to skip 5G if 915 * required 916 * @vdev: vdev object 917 * @req: scan request 918 * 919 * Check and skip 5G chan list based on DFS AP present and current hw mode. 920 * 921 * Return: void 922 */ 923 static inline void scm_scan_chlist_concurrency_modify( 924 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 925 { 926 struct wlan_objmgr_psoc *psoc; 927 struct wlan_objmgr_pdev *pdev; 928 struct wlan_scan_obj *scan_obj; 929 uint16_t trim; 930 qdf_freq_t dfs_ap_freq; 931 932 pdev = wlan_vdev_get_pdev(vdev); 933 if (!pdev) 934 return; 935 936 psoc = wlan_pdev_get_psoc(pdev); 937 if (!psoc) 938 return; 939 940 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 941 if (!scan_obj) 942 return; 943 944 /* do this only for STA and P2P-CLI mode */ 945 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 946 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 947 return; 948 949 if (policy_mgr_scan_trim_5g_chnls_for_dfs_ap(psoc, &dfs_ap_freq)) 950 scm_update_5ghz_6ghz_chlist(req, dfs_ap_freq); 951 952 if (scan_obj->scan_def.conc_chlist_trim) { 953 trim = policy_mgr_scan_trim_chnls_for_connected_ap(pdev); 954 if (trim & TRIM_CHANNEL_LIST_5G) 955 scm_update_5ghz_6ghz_chlist(req, 0); 956 if (trim & TRIM_CHANNEL_LIST_24G) 957 scm_update_24g_chlist(req); 958 } 959 960 /* 961 * Do not allow STA to scan on 6Ghz or indoor channel for non dbs 962 * hardware if SAP and skip_6g_and_indoor_freq_scan ini are present 963 */ 964 if (scan_obj->scan_def.skip_6g_and_indoor_freq && 965 !policy_mgr_is_hw_dbs_capable(psoc) && 966 (wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 967 policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL)) 968 scm_filter_6g_and_indoor_freq(pdev, req); 969 970 } 971 #else 972 static inline 973 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 974 struct scan_start_request *req, 975 struct wlan_scan_obj *scan_obj) 976 { 977 } 978 979 static inline void 980 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 981 { 982 } 983 984 static inline void scm_scan_chlist_concurrency_modify( 985 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 986 { 987 } 988 #endif 989 990 /** 991 * scm_update_channel_list() - update scan req params depending on dfs inis 992 * and initial scan request. 993 * @req: scan request 994 * @scan_obj: scan object 995 * 996 * Return: void 997 */ 998 static void 999 scm_update_channel_list(struct scan_start_request *req, 1000 struct wlan_scan_obj *scan_obj) 1001 { 1002 uint8_t i; 1003 uint8_t num_scan_channels = 0; 1004 struct scan_vdev_obj *scan_vdev_obj; 1005 struct wlan_objmgr_pdev *pdev; 1006 bool first_scan_done = true; 1007 bool p2p_search = false; 1008 bool skip_dfs_ch = true; 1009 uint32_t first_freq; 1010 1011 pdev = wlan_vdev_get_pdev(req->vdev); 1012 1013 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 1014 if (!scan_vdev_obj) { 1015 scm_err("null scan_vdev_obj"); 1016 return; 1017 } 1018 1019 if (!scan_vdev_obj->first_scan_done) { 1020 first_scan_done = false; 1021 scan_vdev_obj->first_scan_done = true; 1022 } 1023 1024 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH) 1025 p2p_search = true; 1026 /* 1027 * No need to update channels if req is single channel* ie ROC, 1028 * Preauth or a single channel scan etc. 1029 * If the single chan in the scan channel list is an NOL channel,it is 1030 * removed and it would reduce the number of scan channels to 0. 1031 */ 1032 first_freq = req->scan_req.chan_list.chan[0].freq; 1033 if ((req->scan_req.chan_list.num_chan == 1) && 1034 (!utils_dfs_is_freq_in_nol(pdev, first_freq))) 1035 return; 1036 1037 /* do this only for STA and P2P-CLI mode */ 1038 if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 1039 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) && 1040 !p2p_search) 1041 skip_dfs_ch = false; 1042 1043 if ((scan_obj->scan_def.allow_dfs_chan_in_scan && 1044 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 1045 first_scan_done)) && 1046 !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search) && 1047 !scan_obj->miracast_enabled) 1048 skip_dfs_ch = false; 1049 1050 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 1051 uint32_t freq; 1052 1053 freq = req->scan_req.chan_list.chan[i].freq; 1054 if ((wlan_reg_is_6ghz_chan_freq(freq) && 1055 !wlan_reg_is_6ghz_band_set(pdev))) { 1056 scm_nofl_debug("Skip 6 GHz freq = %d", freq); 1057 continue; 1058 } 1059 if (skip_dfs_ch && 1060 wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) { 1061 scm_nofl_debug("Skip DFS freq %d", freq); 1062 continue; 1063 } 1064 if (utils_dfs_is_freq_in_nol(pdev, freq)) { 1065 scm_nofl_debug("Skip NOL freq %d", freq); 1066 continue; 1067 } 1068 1069 req->scan_req.chan_list.chan[num_scan_channels++] = 1070 req->scan_req.chan_list.chan[i]; 1071 } 1072 1073 req->scan_req.chan_list.num_chan = num_scan_channels; 1074 1075 scm_update_6ghz_channel_list(req, scan_obj); 1076 scm_scan_chlist_concurrency_modify(req->vdev, req); 1077 } 1078 1079 /** 1080 * scm_req_update_dwell_time_as_per_scan_mode() - update scan req params 1081 * dwell time as per scan mode. 1082 * @vdev: vdev to update 1083 * @req: scan request 1084 * 1085 * Return: void 1086 */ 1087 static void 1088 scm_req_update_dwell_time_as_per_scan_mode( 1089 struct wlan_objmgr_vdev *vdev, 1090 struct scan_start_request *req) 1091 { 1092 struct wlan_objmgr_psoc *psoc; 1093 1094 psoc = wlan_vdev_get_psoc(vdev); 1095 1096 if (req->scan_req.scan_policy_low_span && 1097 wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 1098 req->scan_req.adaptive_dwell_time_mode = 1099 SCAN_DWELL_MODE_STATIC; 1100 req->scan_req.dwell_time_active = 1101 QDF_MIN(req->scan_req.dwell_time_active, 1102 LOW_SPAN_ACTIVE_DWELL_TIME); 1103 req->scan_req.dwell_time_active_2g = 1104 QDF_MIN(req->scan_req.dwell_time_active_2g, 1105 LOW_SPAN_ACTIVE_DWELL_TIME); 1106 req->scan_req.dwell_time_passive = 1107 QDF_MIN(req->scan_req.dwell_time_passive, 1108 LOW_SPAN_PASSIVE_DWELL_TIME); 1109 } 1110 } 1111 1112 /** 1113 * scm_update_aux_scan_ctrl_ext_flag() - update aux scan policy 1114 * @req: pointer to scan request 1115 * 1116 * Set aux scan bits in scan_ctrl_ext_flag value depending on scan type. 1117 * 1118 * Return: None 1119 */ 1120 1121 static void 1122 scm_update_aux_scan_ctrl_ext_flag(struct scan_start_request *req) 1123 { 1124 if (req->scan_req.scan_policy_low_span) 1125 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_AUX_FAST_SCAN; 1126 else if (req->scan_req.scan_policy_low_power) 1127 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_AUX_FAST_SCAN; 1128 else if (req->scan_req.scan_policy_high_accuracy) 1129 req->scan_req.scan_ctrl_flags_ext |= 1130 SCAN_FLAG_EXT_AUX_RELIABLE_SCAN; 1131 } 1132 1133 /** 1134 * scm_scan_req_update_params() - update scan req params depending on modes 1135 * and scan type. 1136 * @vdev: vdev object pointer 1137 * @req: scan request 1138 * @scan_obj: scan object 1139 * 1140 * Return: void 1141 */ 1142 static void 1143 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 1144 struct scan_start_request *req, 1145 struct wlan_scan_obj *scan_obj) 1146 { 1147 struct chan_list *custom_chan_list; 1148 struct wlan_objmgr_pdev *pdev; 1149 uint8_t pdev_id; 1150 struct wlan_objmgr_psoc *psoc; 1151 1152 /* Ensure correct number of probes are sent on active channel */ 1153 if (!req->scan_req.repeat_probe_time) 1154 req->scan_req.repeat_probe_time = 1155 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 1156 1157 if (req->scan_req.scan_f_passive) 1158 req->scan_req.scan_ctrl_flags_ext |= 1159 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 1160 1161 if (!req->scan_req.n_probes) 1162 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 1163 req->scan_req.dwell_time_active / 1164 req->scan_req.repeat_probe_time : 0; 1165 1166 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH || 1167 req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1168 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 1169 req->scan_req.dwell_time_active_2g = 0; 1170 if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1171 req->scan_req.repeat_probe_time = 0; 1172 } else { 1173 req->scan_req.scan_f_filter_prb_req = true; 1174 if (!req->scan_req.num_ssids) 1175 req->scan_req.scan_f_bcast_probe = true; 1176 1177 req->scan_req.dwell_time_active += 1178 P2P_SEARCH_DWELL_TIME_INC; 1179 /* 1180 * 3 channels with default max dwell time 40 ms. 1181 * Cap limit will be set by 1182 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 1183 * should be such that no channel is scanned less 1184 * than the dwell time in normal scenarios. 1185 */ 1186 if (req->scan_req.chan_list.num_chan == 1187 WLAN_P2P_SOCIAL_CHANNELS && 1188 !scan_obj->miracast_enabled) 1189 req->scan_req.repeat_probe_time = 1190 req->scan_req.dwell_time_active / 5; 1191 else 1192 req->scan_req.repeat_probe_time = 1193 req->scan_req.dwell_time_active / 3; 1194 if (scan_obj->scan_def.p2p_scan_burst_duration) { 1195 req->scan_req.burst_duration = 1196 scan_obj->scan_def. 1197 p2p_scan_burst_duration; 1198 } else { 1199 req->scan_req.burst_duration = 1200 BURST_SCAN_MAX_NUM_OFFCHANNELS * 1201 req->scan_req.dwell_time_active; 1202 if (req->scan_req.burst_duration > 1203 P2P_SCAN_MAX_BURST_DURATION) { 1204 uint8_t channels = 1205 P2P_SCAN_MAX_BURST_DURATION / 1206 req->scan_req.dwell_time_active; 1207 if (channels) 1208 req->scan_req.burst_duration = 1209 channels * 1210 req->scan_req.dwell_time_active; 1211 else 1212 req->scan_req.burst_duration = 1213 P2P_SCAN_MAX_BURST_DURATION; 1214 } 1215 } 1216 req->scan_req.scan_ev_bss_chan = false; 1217 } 1218 } else { 1219 req->scan_req.scan_f_cck_rates = true; 1220 if (!req->scan_req.num_ssids) 1221 req->scan_req.scan_f_bcast_probe = true; 1222 req->scan_req.scan_f_add_ds_ie_in_probe = true; 1223 req->scan_req.scan_f_filter_prb_req = true; 1224 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 1225 } 1226 1227 scm_update_dbs_scan_ctrl_ext_flag(req); 1228 1229 psoc = wlan_vdev_get_psoc(vdev); 1230 if (wlan_scan_get_aux_support(psoc)) 1231 scm_update_aux_scan_ctrl_ext_flag(req); 1232 1233 /* 1234 * No need to update conncurrency parmas if req is passive scan on 1235 * single channel ie ROC, Preauth etc 1236 */ 1237 if (!(req->scan_req.scan_f_passive && 1238 req->scan_req.chan_list.num_chan == 1) && 1239 req->scan_req.scan_type != SCAN_TYPE_RRM) 1240 scm_req_update_concurrency_params(vdev, req, scan_obj); 1241 1242 if (req->scan_req.scan_type == SCAN_TYPE_RRM) 1243 req->scan_req.scan_ctrl_flags_ext |= SCAN_FLAG_EXT_RRM_SCAN_IND; 1244 1245 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_DEVICE_MODE || 1246 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) && 1247 !qdf_is_macaddr_zero(&req->scan_req.bssid_list[0]) && 1248 !qdf_is_macaddr_broadcast(&req->scan_req.bssid_list[0])) 1249 req->scan_req.scan_ctrl_flags_ext |= 1250 SCAN_FLAG_EXT_STOP_IF_BSSID_FOUND; 1251 1252 scm_req_update_dwell_time_as_per_scan_mode(vdev, req); 1253 1254 scm_debug("scan_ctrl_flags_ext %0x", req->scan_req.scan_ctrl_flags_ext); 1255 /* 1256 * Set wide band flag if enabled. This will cause 1257 * phymode TLV being sent to FW. 1258 */ 1259 pdev = wlan_vdev_get_pdev(vdev); 1260 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1261 /* 1262 * Trigger wide band scan also if 1263 * scan_f_report_cca_busy_for_each_20mhz flag is set 1264 */ 1265 if (ucfg_scan_get_wide_band_scan(pdev) || 1266 req->scan_req.scan_f_report_cca_busy_for_each_20mhz) 1267 req->scan_req.scan_f_wide_band = true; 1268 else 1269 req->scan_req.scan_f_wide_band = false; 1270 1271 /* 1272 * Overwrite scan channels with custom scan channel 1273 * list if configured. 1274 */ 1275 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 1276 if (custom_chan_list->num_chan) 1277 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 1278 sizeof(struct chan_list)); 1279 else if (!req->scan_req.chan_list.num_chan) 1280 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 1281 1282 scm_update_channel_list(req, scan_obj); 1283 1284 wlan_scan_update_low_latency_profile_chnlist(vdev, req); 1285 } 1286 1287 static inline void scm_print_scan_req_info(struct scan_req_params *req) 1288 { 1289 uint32_t buff_len; 1290 char *chan_buff; 1291 uint32_t len = 0; 1292 uint8_t buff_size, idx, count = 0; 1293 struct chan_list *chan_lst; 1294 #define MAX_SCAN_FREQ_TO_PRINT 25 1295 1296 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 is_wb: %d pri %d", 1297 req->scan_id, req->vdev_id, req->dwell_time_active, 1298 req->dwell_time_passive, req->dwell_time_active_2g, 1299 req->dwell_time_active_6g, req->dwell_time_passive_6g, 1300 req->repeat_probe_time, req->n_probes, req->scan_flags, 1301 req->scan_ctrl_flags_ext, req->scan_events, 1302 req->scan_policy_type, req->scan_f_wide_band, 1303 req->scan_priority); 1304 scm_nofl_debug("Scan Type %d rest time: min %d max %d probe spacing %d idle %d probe delay %d scan offset %d burst duration %d adaptive dwell mode %d", 1305 req->scan_type, req->min_rest_time, req->max_rest_time, 1306 req->probe_spacing_time, req->idle_time, 1307 req->probe_delay, req->scan_offset_time, 1308 req->burst_duration, req->adaptive_dwell_time_mode); 1309 1310 for (idx = 0; idx < req->num_ssids; idx++) 1311 scm_nofl_debug("SSID[%d]: " QDF_SSID_FMT, idx, 1312 QDF_SSID_REF(req->ssid[idx].length, 1313 req->ssid[idx].ssid)); 1314 1315 chan_lst = &req->chan_list; 1316 1317 if (!chan_lst->num_chan) 1318 return; 1319 1320 /* 1321 * Buffer of (num channel * buff_size) + 1 to consider the 4 char freq, 1322 * 6 char flags and 1 space after it for each channel and 1 to end the 1323 * string with NULL. 1324 * In case of wide band scan extra 4 char for phymode. 1325 */ 1326 if (req->scan_f_wide_band) 1327 buff_size = 15; 1328 else 1329 buff_size = 11; 1330 1331 buff_len = (QDF_MIN(MAX_SCAN_FREQ_TO_PRINT, 1332 chan_lst->num_chan) * buff_size) + 1; 1333 1334 chan_buff = qdf_mem_malloc(buff_len); 1335 if (!chan_buff) 1336 return; 1337 1338 scm_nofl_debug("Total freq %d", chan_lst->num_chan); 1339 for (idx = 0; idx < chan_lst->num_chan; idx++) { 1340 if (req->scan_f_wide_band) 1341 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1342 "%d(0x%02x)[%d] ", 1343 chan_lst->chan[idx].freq, 1344 chan_lst->chan[idx].flags, 1345 chan_lst->chan[idx].phymode); 1346 else 1347 len += qdf_scnprintf(chan_buff + len, buff_len - len, 1348 "%d(0x%02x) ", 1349 chan_lst->chan[idx].freq, 1350 chan_lst->chan[idx].flags); 1351 1352 count++; 1353 if (count >= MAX_SCAN_FREQ_TO_PRINT) { 1354 /* Print the MAX_SCAN_FREQ_TO_PRINT channels */ 1355 scm_nofl_debug("Freq list: %s", chan_buff); 1356 len = 0; 1357 count = 0; 1358 } 1359 } 1360 if (len) 1361 scm_nofl_debug("Freq list: %s", chan_buff); 1362 1363 qdf_mem_free(chan_buff); 1364 } 1365 QDF_STATUS 1366 scm_scan_start_req(struct scheduler_msg *msg) 1367 { 1368 struct wlan_serialization_command cmd = {0, }; 1369 enum wlan_serialization_status ser_cmd_status; 1370 struct scan_start_request *req = NULL; 1371 struct wlan_scan_obj *scan_obj; 1372 QDF_STATUS status = QDF_STATUS_SUCCESS; 1373 1374 1375 if (!msg) { 1376 scm_err("msg received is NULL"); 1377 QDF_ASSERT(0); 1378 return QDF_STATUS_E_NULL_VALUE; 1379 } 1380 if (!msg->bodyptr) { 1381 scm_err("bodyptr is NULL"); 1382 QDF_ASSERT(0); 1383 return QDF_STATUS_E_NULL_VALUE; 1384 } 1385 1386 req = msg->bodyptr; 1387 1388 if (!scm_is_scan_allowed(req->vdev)) { 1389 scm_err("scan disabled, rejecting the scan req"); 1390 status = QDF_STATUS_E_NULL_VALUE; 1391 goto err; 1392 } 1393 1394 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 1395 if (!scan_obj) { 1396 scm_debug("Couldn't find scan object"); 1397 status = QDF_STATUS_E_NULL_VALUE; 1398 goto err; 1399 } 1400 1401 scm_scan_req_update_params(req->vdev, req, scan_obj); 1402 scm_print_scan_req_info(&req->scan_req); 1403 1404 if (!req->scan_req.chan_list.num_chan) { 1405 scm_info("Reject 0 channel Scan"); 1406 status = QDF_STATUS_E_NULL_VALUE; 1407 goto err; 1408 } 1409 1410 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1411 cmd.cmd_id = req->scan_req.scan_id; 1412 cmd.cmd_cb = scm_scan_serialize_callback; 1413 cmd.umac_cmd = req; 1414 cmd.source = WLAN_UMAC_COMP_SCAN; 1415 cmd.is_high_priority = false; 1416 cmd.cmd_timeout_duration = req->scan_req.max_scan_time + 1417 SCAN_TIMEOUT_GRACE_PERIOD; 1418 cmd.vdev = req->vdev; 1419 1420 if (scan_obj->disable_timeout) 1421 cmd.cmd_timeout_duration = 0; 1422 1423 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION, 1424 WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id, 1425 req->scan_req.scan_id); 1426 1427 ser_cmd_status = wlan_serialization_request(&cmd); 1428 switch (ser_cmd_status) { 1429 case WLAN_SER_CMD_PENDING: 1430 /* command moved to pending list.Do nothing */ 1431 break; 1432 case WLAN_SER_CMD_ACTIVE: 1433 /* command moved to active list. Do nothing */ 1434 break; 1435 default: 1436 scm_debug("ser cmd status %d", ser_cmd_status); 1437 goto err; 1438 } 1439 1440 return status; 1441 err: 1442 /* 1443 * notify registered scan event handlers 1444 * about internal error 1445 */ 1446 scm_post_internal_scan_complete_event(req, 1447 SCAN_REASON_INTERNAL_FAILURE); 1448 /* 1449 * cmd can't be serviced. 1450 * release vdev reference and free scan_start_request memory 1451 */ 1452 if (req) { 1453 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1454 scm_scan_free_scan_request_mem(req); 1455 } 1456 1457 return status; 1458 } 1459 1460 static inline enum wlan_serialization_cancel_type 1461 get_serialization_cancel_type(enum scan_cancel_req_type type) 1462 { 1463 enum wlan_serialization_cancel_type serialization_type; 1464 1465 switch (type) { 1466 case WLAN_SCAN_CANCEL_SINGLE: 1467 serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN; 1468 break; 1469 case WLAN_SCAN_CANCEL_VDEV_ALL: 1470 serialization_type = WLAN_SER_CANCEL_VDEV_SCANS; 1471 break; 1472 case WLAN_SCAN_CANCEL_PDEV_ALL: 1473 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1474 break; 1475 case WLAN_SCAN_CANCEL_HOST_VDEV_ALL: 1476 serialization_type = WLAN_SER_CANCEL_VDEV_HOST_SCANS; 1477 break; 1478 default: 1479 QDF_ASSERT(0); 1480 scm_warn("invalid scan_cancel_req_type: %d", type); 1481 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1482 break; 1483 } 1484 1485 return serialization_type; 1486 } 1487 1488 QDF_STATUS 1489 scm_scan_cancel_req(struct scheduler_msg *msg) 1490 { 1491 struct wlan_serialization_queued_cmd_info cmd = {0,}; 1492 struct wlan_serialization_command ser_cmd = {0,}; 1493 enum wlan_serialization_cmd_status ser_cmd_status; 1494 struct scan_cancel_request *req; 1495 QDF_STATUS status = QDF_STATUS_SUCCESS; 1496 1497 if (!msg) { 1498 scm_err("msg received is NULL"); 1499 QDF_ASSERT(0); 1500 return QDF_STATUS_E_NULL_VALUE; 1501 } 1502 if (!msg->bodyptr) { 1503 scm_err("Bodyptr is NULL"); 1504 QDF_ASSERT(0); 1505 return QDF_STATUS_E_NULL_VALUE; 1506 } 1507 1508 req = msg->bodyptr; 1509 /* 1510 * If requester wants to wait for target scan cancel event 1511 * instead of internally generated cancel event, just check 1512 * which queue this scan request belongs to and send scan 1513 * cancel request to FW accordingly. 1514 * Else generate internal scan cancel event and notify 1515 * handlers and free scan request resources. 1516 */ 1517 if (req->wait_tgt_cancel && 1518 (req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) { 1519 ser_cmd.cmd_type = WLAN_SER_CMD_SCAN; 1520 ser_cmd.cmd_id = req->cancel_req.scan_id; 1521 ser_cmd.cmd_cb = NULL; 1522 ser_cmd.umac_cmd = NULL; 1523 ser_cmd.source = WLAN_UMAC_COMP_SCAN; 1524 ser_cmd.is_high_priority = false; 1525 ser_cmd.vdev = req->vdev; 1526 if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd)) 1527 ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST; 1528 else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd)) 1529 ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST; 1530 else 1531 ser_cmd_status = WLAN_SER_CMD_NOT_FOUND; 1532 } else { 1533 cmd.requestor = 0; 1534 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1535 cmd.cmd_id = req->cancel_req.scan_id; 1536 cmd.vdev = req->vdev; 1537 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE | 1538 WLAN_SERIALIZATION_PENDING_QUEUE; 1539 cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type); 1540 1541 ser_cmd_status = wlan_serialization_cancel_request(&cmd); 1542 } 1543 1544 scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d", 1545 ser_cmd_status, req->cancel_req.requester, 1546 req->cancel_req.scan_id, req->cancel_req.vdev_id, 1547 req->cancel_req.req_type); 1548 1549 switch (ser_cmd_status) { 1550 case WLAN_SER_CMD_IN_PENDING_LIST: 1551 /* do nothing */ 1552 break; 1553 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1554 case WLAN_SER_CMDS_IN_ALL_LISTS: 1555 /* send wmi scan cancel to fw */ 1556 status = tgt_scan_cancel(req); 1557 break; 1558 case WLAN_SER_CMD_NOT_FOUND: 1559 /* do nothing */ 1560 break; 1561 default: 1562 QDF_ASSERT(0); 1563 status = QDF_STATUS_E_INVAL; 1564 break; 1565 } 1566 1567 /* Release vdev reference and scan cancel request 1568 * processing is complete 1569 */ 1570 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1571 /* Free cancel request memory */ 1572 qdf_mem_free(req); 1573 1574 return status; 1575 } 1576 1577 #ifdef FEATURE_WLAN_SCAN_PNO 1578 static QDF_STATUS 1579 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1580 struct scan_event *event) 1581 { 1582 struct scan_vdev_obj *scan_vdev_obj; 1583 struct wlan_scan_obj *scan_psoc_obj; 1584 scan_event_handler pno_cb; 1585 void *cb_arg; 1586 1587 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1588 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 1589 if (!scan_vdev_obj || !scan_psoc_obj) { 1590 scm_err("null scan_vdev_obj %pK scan_obj %pK", 1591 scan_vdev_obj, scan_psoc_obj); 1592 return QDF_STATUS_E_INVAL; 1593 } 1594 1595 switch (event->type) { 1596 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1597 if (!scan_vdev_obj->pno_match_evt_received) 1598 return QDF_STATUS_SUCCESS; 1599 qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock, 1600 WIFI_POWER_EVENT_WAKELOCK_PNO); 1601 qdf_wake_lock_timeout_acquire( 1602 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1603 SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT); 1604 qdf_runtime_pm_allow_suspend( 1605 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1606 scan_vdev_obj->pno_match_evt_received = false; 1607 break; 1608 case SCAN_EVENT_TYPE_NLO_MATCH: 1609 scan_vdev_obj->pno_match_evt_received = true; 1610 qdf_wake_lock_timeout_acquire( 1611 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1612 SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT); 1613 qdf_runtime_pm_prevent_suspend( 1614 &scan_psoc_obj->pno_cfg.pno_runtime_pm_lock); 1615 return QDF_STATUS_SUCCESS; 1616 default: 1617 return QDF_STATUS_E_INVAL; 1618 } 1619 qdf_spin_lock_bh(&scan_psoc_obj->lock); 1620 pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func; 1621 cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg; 1622 qdf_spin_unlock_bh(&scan_psoc_obj->lock); 1623 1624 if (pno_cb) 1625 pno_cb(vdev, event, cb_arg); 1626 1627 return QDF_STATUS_SUCCESS; 1628 } 1629 #else 1630 1631 static QDF_STATUS 1632 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1633 struct scan_event *event) 1634 { 1635 return QDF_STATUS_SUCCESS; 1636 } 1637 #endif 1638 1639 /** 1640 * scm_scan_update_scan_event() - update scan event 1641 * @scan: scan object 1642 * @event: scan event 1643 * @scan_start_req: scan_start_req used for triggering scan 1644 * 1645 * update scan params in scan event 1646 * 1647 * Return: QDF_STATUS 1648 */ 1649 static QDF_STATUS 1650 scm_scan_update_scan_event(struct wlan_scan_obj *scan, 1651 struct scan_event *event, 1652 struct scan_start_request *scan_start_req) 1653 { 1654 if (!event) 1655 return QDF_STATUS_E_NULL_VALUE; 1656 1657 if (!scan || !scan_start_req) { 1658 event->scan_start_req = NULL; 1659 return QDF_STATUS_E_NULL_VALUE; 1660 } 1661 /* copy scan start request to pass back buffer */ 1662 qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req, 1663 sizeof(struct scan_start_request)); 1664 /* reset all pointers */ 1665 scan->scan_start_request_buff.scan_req.extraie.ptr = NULL; 1666 scan->scan_start_request_buff.scan_req.extraie.len = 0; 1667 scan->scan_start_request_buff.scan_req.htcap.ptr = NULL; 1668 scan->scan_start_request_buff.scan_req.htcap.len = 0; 1669 scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL; 1670 scan->scan_start_request_buff.scan_req.vhtcap.len = 0; 1671 1672 event->scan_start_req = &scan->scan_start_request_buff; 1673 1674 return QDF_STATUS_SUCCESS; 1675 } 1676 1677 static 1678 void scm_update_last_scan_time_per_channel(struct wlan_objmgr_vdev *vdev, 1679 uint32_t chan_freq, uint32_t time) 1680 { 1681 struct wlan_scan_obj *scan_obj; 1682 struct chan_list_scan_info *chan_info; 1683 bool chan_found = false; 1684 uint8_t pdev_id; 1685 int i; 1686 1687 scan_obj = wlan_vdev_get_scan_obj(vdev); 1688 if (!scan_obj) 1689 return; 1690 1691 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 1692 chan_info = &scan_obj->pdev_info[pdev_id].chan_scan_info; 1693 1694 for (i = 0; i < chan_info->num_chan ; i++) { 1695 if (chan_info->ch_scan_info[i].freq == chan_freq) { 1696 chan_info->ch_scan_info[i].last_scan_time = time; 1697 chan_found = true; 1698 break; 1699 } 1700 } 1701 1702 if (!chan_found) { 1703 chan_info->ch_scan_info[chan_info->num_chan].freq = chan_freq; 1704 chan_info->ch_scan_info[chan_info->num_chan].last_scan_time = 1705 time; 1706 chan_info->num_chan++; 1707 } 1708 } 1709 1710 QDF_STATUS 1711 scm_scan_event_handler(struct scheduler_msg *msg) 1712 { 1713 struct wlan_objmgr_vdev *vdev; 1714 struct scan_event *event; 1715 struct scan_event_info *event_info; 1716 struct wlan_serialization_command cmd = {0,}; 1717 struct wlan_serialization_command *queued_cmd; 1718 struct scan_start_request *scan_start_req; 1719 struct wlan_scan_obj *scan; 1720 1721 if (!msg) { 1722 scm_err("NULL msg received "); 1723 QDF_ASSERT(0); 1724 return QDF_STATUS_E_NULL_VALUE; 1725 } 1726 if (!msg->bodyptr) { 1727 scm_err("NULL scan event received"); 1728 QDF_ASSERT(0); 1729 return QDF_STATUS_E_NULL_VALUE; 1730 } 1731 1732 event_info = msg->bodyptr; 1733 vdev = event_info->vdev; 1734 event = &(event_info->event); 1735 1736 scan = wlan_vdev_get_scan_obj(vdev); 1737 1738 scm_duration_init(scan); 1739 1740 scm_event_duration_start(scan); 1741 1742 scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d," 1743 "scanid:%d (0x%x), timestamp:%u", event->vdev_id, 1744 event->type, event->reason, event->chan_freq, 1745 event->requester, event->scan_id, event->scan_id, 1746 event->timestamp); 1747 1748 if (event->type == SCAN_EVENT_TYPE_FOREIGN_CHANNEL) 1749 scm_update_last_scan_time_per_channel( 1750 vdev, event->chan_freq, qdf_get_time_of_the_day_ms()); 1751 1752 /* 1753 * NLO requests are never queued, so post NLO events 1754 * without checking for their presence in active queue. 1755 */ 1756 switch (event->type) { 1757 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1758 case SCAN_EVENT_TYPE_NLO_MATCH: 1759 scm_pno_event_handler(vdev, event); 1760 goto exit; 1761 default: 1762 break; 1763 } 1764 1765 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1766 cmd.cmd_id = event->scan_id; 1767 cmd.cmd_cb = NULL; 1768 cmd.umac_cmd = NULL; 1769 cmd.source = WLAN_UMAC_COMP_SCAN; 1770 cmd.is_high_priority = false; 1771 cmd.vdev = vdev; 1772 if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { 1773 /* 1774 * We received scan event for an already completed/cancelled 1775 * scan request. Drop this event. 1776 */ 1777 scm_debug("Received scan event while request not in active queue"); 1778 goto exit; 1779 } 1780 1781 /* Fill scan_start_request used to trigger this scan */ 1782 queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id( 1783 wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), 1784 event->scan_id, true); 1785 1786 if (!queued_cmd) { 1787 scm_err("NULL queued_cmd"); 1788 goto exit; 1789 } 1790 if (!queued_cmd->umac_cmd) { 1791 scm_err("NULL umac_cmd"); 1792 goto exit; 1793 } 1794 scan_start_req = queued_cmd->umac_cmd; 1795 1796 if (scan_start_req->scan_req.scan_req_id != event->requester) { 1797 scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d", 1798 scan_start_req->scan_req.scan_req_id, event->requester); 1799 goto exit; 1800 } 1801 1802 if (scan) 1803 scm_scan_update_scan_event(scan, event, scan_start_req); 1804 1805 switch (event->type) { 1806 case SCAN_EVENT_TYPE_COMPLETED: 1807 if (event->reason == SCAN_REASON_COMPLETED) 1808 scm_11d_decide_country_code(vdev); 1809 /* release the command */ 1810 fallthrough; 1811 case SCAN_EVENT_TYPE_START_FAILED: 1812 case SCAN_EVENT_TYPE_DEQUEUED: 1813 scm_release_serialization_command(vdev, event->scan_id); 1814 break; 1815 default: 1816 break; 1817 } 1818 1819 scm_to_post_scan_duration_set(scan); 1820 /* Notify all interested parties */ 1821 scm_scan_post_event(vdev, event); 1822 1823 exit: 1824 /* free event info memory */ 1825 qdf_mem_free(event_info); 1826 1827 scm_event_duration_end(scan); 1828 1829 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1830 1831 return QDF_STATUS_SUCCESS; 1832 } 1833 1834 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg) 1835 { 1836 struct wlan_objmgr_vdev *vdev; 1837 struct scan_event_info *event_info; 1838 struct scan_event *event; 1839 1840 if (!msg || !msg->bodyptr) { 1841 scm_err("msg or msg->bodyptr is NULL"); 1842 return QDF_STATUS_E_NULL_VALUE; 1843 } 1844 1845 event_info = msg->bodyptr; 1846 vdev = event_info->vdev; 1847 event = &event_info->event; 1848 1849 scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d", 1850 event->vdev_id, event->type, event->reason, event->chan_freq, 1851 event->requester, event->scan_id); 1852 1853 /* free event info memory */ 1854 qdf_mem_free(event_info); 1855 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1856 1857 return QDF_STATUS_SUCCESS; 1858 } 1859 1860 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg) 1861 { 1862 struct scan_bcn_probe_event *bcn; 1863 1864 bcn = msg->bodyptr; 1865 1866 if (!bcn) { 1867 scm_err("bcn is NULL"); 1868 return QDF_STATUS_E_NULL_VALUE; 1869 } 1870 if (bcn->psoc) 1871 wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); 1872 if (bcn->rx_data) 1873 qdf_mem_free(bcn->rx_data); 1874 if (bcn->buf) 1875 qdf_nbuf_free(bcn->buf); 1876 qdf_mem_free(bcn); 1877 1878 return QDF_STATUS_SUCCESS; 1879 } 1880 1881 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg) 1882 { 1883 struct scan_start_request *req; 1884 1885 if (!msg || !msg->bodyptr) { 1886 scm_err("msg or msg->bodyptr is NULL"); 1887 return QDF_STATUS_E_NULL_VALUE; 1888 } 1889 1890 req = msg->bodyptr; 1891 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 1892 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1893 scm_scan_free_scan_request_mem(req); 1894 1895 return QDF_STATUS_SUCCESS; 1896 } 1897 1898 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg) 1899 { 1900 struct scan_cancel_request *req; 1901 1902 if (!msg || !msg->bodyptr) { 1903 scm_err("msg or msg->bodyptr is NULL"); 1904 return QDF_STATUS_E_NULL_VALUE; 1905 } 1906 1907 req = msg->bodyptr; 1908 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1909 /* Free cancel request memory */ 1910 qdf_mem_free(req); 1911 1912 return QDF_STATUS_SUCCESS; 1913 } 1914 1915 void scm_disable_obss_pdev_scan(struct wlan_objmgr_psoc *psoc, 1916 struct wlan_objmgr_pdev *pdev) 1917 { 1918 struct wlan_objmgr_vdev *vdev; 1919 struct wlan_scan_obj *scan_obj; 1920 struct scan_vdev_obj *scan_vdev_obj; 1921 QDF_STATUS status; 1922 struct wlan_objmgr_pdev_objmgr *pdev_objmgr; 1923 qdf_list_t *vdev_list; 1924 uint16_t index = 0; 1925 1926 scan_obj = wlan_psoc_get_scan_obj(psoc); 1927 if (!scan_obj) { 1928 scm_err("scan object null"); 1929 return; 1930 } 1931 1932 if (scan_obj->obss_scan_offload) { 1933 pdev_objmgr = &pdev->pdev_objmgr; 1934 1935 wlan_pdev_obj_lock(pdev); 1936 vdev_list = &pdev_objmgr->wlan_vdev_list; 1937 /* Get first vdev */ 1938 vdev = wlan_pdev_vdev_list_peek_head(vdev_list); 1939 1940 while (vdev) { 1941 scm_debug("wlan_vdev_list[%d]: %pK", index, vdev); 1942 1943 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1944 if (!scan_vdev_obj) { 1945 scm_err("null scan_vdev_obj"); 1946 goto next; 1947 } 1948 1949 status = tgt_scan_obss_disable(vdev); 1950 if (QDF_IS_STATUS_ERROR(status)) 1951 scm_err("disable obss scan failed"); 1952 next: 1953 index++; 1954 /* get next vdev */ 1955 vdev = wlan_vdev_get_next_vdev_of_pdev(vdev_list, 1956 vdev); 1957 } 1958 wlan_pdev_obj_unlock(pdev); 1959 } 1960 } 1961