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