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 438 psoc = wlan_vdev_get_psoc(req->vdev); 439 440 if (!policy_mgr_is_dbs_scan_allowed(psoc)) { 441 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 442 goto end; 443 } 444 445 if (!wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 446 scm_debug_rl("nl scan policy flags not honoured, goto end"); 447 goto end; 448 } 449 450 if (req->scan_req.scan_policy_high_accuracy) { 451 scm_debug("high accuracy scan received, going for non-dbs scan"); 452 scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; 453 goto end; 454 } 455 if ((req->scan_req.scan_policy_low_power) || 456 (req->scan_req.scan_policy_low_span)) { 457 scm_debug("low power/span scan received, going for dbs scan"); 458 scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; 459 goto end; 460 } 461 462 end: 463 req->scan_req.scan_ctrl_flags_ext |= 464 ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) 465 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); 466 } 467 468 /** 469 * scm_update_passive_dwell_time() - update dwell passive time 470 * @vdev: vdev object 471 * @req: scan request 472 * 473 * Return: None 474 */ 475 static void 476 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, 477 struct scan_start_request *req) 478 { 479 struct wlan_objmgr_psoc *psoc; 480 481 psoc = wlan_vdev_get_psoc(vdev); 482 if (!psoc) 483 return; 484 485 if (policy_mgr_is_sta_connected_2g(psoc) && 486 !policy_mgr_is_hw_dbs_capable(psoc) && 487 ucfg_scan_get_bt_activity(psoc)) 488 req->scan_req.dwell_time_passive = 489 PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; 490 } 491 492 static const struct probe_time_dwell_time 493 scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { 494 {28, 11}, /* 0 SSID */ 495 {28, 20}, /* 1 SSID */ 496 {28, 20}, /* 2 SSID */ 497 {28, 20}, /* 3 SSID */ 498 {28, 20}, /* 4 SSID */ 499 {28, 20}, /* 5 SSID */ 500 {28, 20}, /* 6 SSID */ 501 {28, 11}, /* 7 SSID */ 502 {28, 11}, /* 8 SSID */ 503 {28, 11}, /* 9 SSID */ 504 {28, 8} /* 10 SSID */ 505 }; 506 507 /** 508 * scm_scan_get_burst_duration() - get burst duration depending on max chan 509 * and miracast. 510 * @max_ch_time: max channel time 511 * @miracast_enabled: if miracast is enabled 512 * 513 * Return: burst_duration 514 */ 515 static inline 516 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) 517 { 518 int burst_duration = 0; 519 520 if (miracast_enabled) { 521 /* 522 * When miracast is running, burst 523 * duration needs to be minimum to avoid 524 * any stutter or glitch in miracast 525 * during station scan 526 */ 527 if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) 528 burst_duration = max_ch_time; 529 else 530 burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; 531 } else { 532 /* 533 * If miracast is not running, accommodate max 534 * stations to make the scans faster 535 */ 536 burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * 537 max_ch_time; 538 539 if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { 540 uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / 541 max_ch_time; 542 543 if (channels) 544 burst_duration = channels * max_ch_time; 545 else 546 burst_duration = 547 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; 548 } 549 } 550 return burst_duration; 551 } 552 553 /** 554 * scm_req_update_concurrency_params() - update scan req params depending on 555 * concurrent mode present. 556 * @vdev: vdev object pointer 557 * @req: scan request 558 * @scan_obj: scan object 559 * 560 * Return: void 561 */ 562 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 563 struct scan_start_request *req, 564 struct wlan_scan_obj *scan_obj) 565 { 566 bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; 567 struct wlan_objmgr_psoc *psoc; 568 uint16_t sap_peer_count = 0; 569 uint16_t go_peer_count = 0; 570 struct wlan_objmgr_pdev *pdev; 571 572 psoc = wlan_vdev_get_psoc(vdev); 573 pdev = wlan_vdev_get_pdev(vdev); 574 575 if (!psoc || !pdev) 576 return; 577 578 ap_present = policy_mgr_mode_specific_connection_count( 579 psoc, PM_SAP_MODE, NULL); 580 go_present = policy_mgr_mode_specific_connection_count( 581 psoc, PM_P2P_GO_MODE, NULL); 582 p2p_cli_present = policy_mgr_mode_specific_connection_count( 583 psoc, PM_P2P_CLIENT_MODE, NULL); 584 sta_active = policy_mgr_mode_specific_connection_count( 585 psoc, PM_STA_MODE, NULL); 586 ndi_present = policy_mgr_mode_specific_connection_count( 587 psoc, PM_NDI_MODE, NULL); 588 if (ap_present) 589 sap_peer_count = 590 wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); 591 if (go_present) 592 go_peer_count = 593 wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); 594 595 if (!req->scan_req.scan_f_passive) 596 scm_update_passive_dwell_time(vdev, req); 597 598 if (policy_mgr_get_connection_count(psoc)) { 599 if (req->scan_req.scan_f_passive) 600 req->scan_req.dwell_time_passive = 601 scan_obj->scan_def.conc_passive_dwell; 602 else 603 req->scan_req.dwell_time_active = 604 scan_obj->scan_def.conc_active_dwell; 605 req->scan_req.max_rest_time = 606 scan_obj->scan_def.conc_max_rest_time; 607 req->scan_req.min_rest_time = 608 scan_obj->scan_def.conc_min_rest_time; 609 req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; 610 } 611 612 if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) 613 req->scan_req.adaptive_dwell_time_mode = 614 scan_obj->scan_def.adaptive_dwell_time_mode_nc; 615 /* 616 * If AP/GO is active and has connected clients : 617 * 1.set min rest time same as max rest time, so that 618 * firmware spends more time on home channel which will 619 * increase the probability of sending beacon at TBTT 620 * 2.if DBS is supported and SAP is not on 2g, 621 * do not reset active dwell time for 2g. 622 */ 623 if ((ap_present && sap_peer_count) || 624 (go_present && go_peer_count)) { 625 if (policy_mgr_is_hw_dbs_capable(psoc) && 626 policy_mgr_is_sap_go_on_2g(psoc)) { 627 req->scan_req.dwell_time_active_2g = 628 QDF_MIN(req->scan_req.dwell_time_active, 629 (SCAN_CTS_DURATION_MS_MAX - 630 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 631 } 632 req->scan_req.min_rest_time = req->scan_req.max_rest_time; 633 } 634 635 /* 636 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell 637 * time for 2g channels instead of dwell_time_active_2g 638 */ 639 if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) 640 req->scan_req.dwell_time_active_2g = 0; 641 642 if (req->scan_req.scan_type == SCAN_TYPE_DEFAULT) { 643 /* 644 * Decide burst_duration and dwell_time_active based on 645 * what type of devices are active. 646 */ 647 do { 648 if (ap_present && go_present && sta_active) { 649 if (req->scan_req.dwell_time_active <= 650 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) 651 req->scan_req.burst_duration = 652 req->scan_req.dwell_time_active; 653 else 654 req->scan_req.burst_duration = 655 SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; 656 657 break; 658 } 659 660 if (scan_obj->miracast_enabled && 661 policy_mgr_is_mcc_in_24G(psoc)) 662 req->scan_req.max_rest_time = 663 scan_obj->scan_def.sta_miracast_mcc_rest_time; 664 665 if (go_present) { 666 /* 667 * Background scan while GO is sending beacons. 668 * Every off-channel transition has overhead of 669 * 2 beacon intervals for NOA. Maximize number 670 * of channels in every transition by using 671 * burst scan. 672 */ 673 if (scan_obj->scan_def.go_scan_burst_duration) 674 req->scan_req.burst_duration = 675 scan_obj-> 676 scan_def.go_scan_burst_duration; 677 else 678 req->scan_req.burst_duration = 679 scm_scan_get_burst_duration( 680 req->scan_req. 681 dwell_time_active, 682 scan_obj-> 683 miracast_enabled); 684 break; 685 } 686 if ((sta_active || p2p_cli_present)) { 687 if (scan_obj->scan_def.sta_scan_burst_duration) 688 req->scan_req.burst_duration = 689 scan_obj->scan_def. 690 sta_scan_burst_duration; 691 break; 692 } 693 694 if (ndi_present) { 695 req->scan_req.burst_duration = 696 scm_scan_get_burst_duration( 697 req->scan_req.dwell_time_active, 698 scan_obj->miracast_enabled); 699 break; 700 } 701 } while (0); 702 703 if (ap_present) { 704 uint8_t ssid_num; 705 706 ssid_num = req->scan_req.num_ssids * 707 req->scan_req.num_bssid; 708 req->scan_req.repeat_probe_time = 709 scan_probe_time_dwell_time_map[ 710 QDF_MIN(ssid_num, 711 SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE 712 - 1)].probe_time; 713 req->scan_req.n_probes = 714 (req->scan_req.repeat_probe_time > 0) ? 715 req->scan_req.dwell_time_active / 716 req->scan_req.repeat_probe_time : 0; 717 } 718 } 719 720 if (ap_present) { 721 uint16_t ap_chan_freq; 722 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 723 724 ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); 725 /* 726 * P2P/STA scan while SoftAP is sending beacons. 727 * Max duration of CTS2self is 32 ms, which limits the 728 * dwell time. 729 * If DBS is supported and: 730 * 1.if SAP is on 2G channel then keep passive 731 * dwell time default. 732 * 2.if SAP is on 5G/6G channel then update dwell time active. 733 */ 734 if (sap_peer_count) { 735 if (policy_mgr_is_hw_dbs_capable(psoc) && 736 (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) || 737 WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) { 738 req->scan_req.dwell_time_active = 739 QDF_MIN(req->scan_req.dwell_time_active, 740 (SCAN_CTS_DURATION_MS_MAX - 741 SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); 742 } 743 if (!policy_mgr_is_hw_dbs_capable(psoc) || 744 (policy_mgr_is_hw_dbs_capable(psoc) && 745 WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) { 746 req->scan_req.dwell_time_passive = 747 req->scan_req.dwell_time_active; 748 } 749 } 750 751 if (scan_obj->scan_def.ap_scan_burst_duration) { 752 req->scan_req.burst_duration = 753 scan_obj->scan_def.ap_scan_burst_duration; 754 } else { 755 req->scan_req.burst_duration = 0; 756 if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq)) 757 req->scan_req.burst_duration = 758 SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * 759 req->scan_req.dwell_time_active; 760 } 761 } 762 } 763 764 /** 765 * scm_scan_chlist_concurrency_modify() - modify chan list to skip 5G if 766 * required 767 * @vdev: vdev object 768 * @req: scan request 769 * 770 * Check and skip 5G chan list based on DFS AP present and current hw mode. 771 * 772 * Return: void 773 */ 774 static inline void scm_scan_chlist_concurrency_modify( 775 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 776 { 777 struct wlan_objmgr_psoc *psoc; 778 uint32_t i; 779 uint32_t num_scan_channels; 780 781 psoc = wlan_vdev_get_psoc(vdev); 782 if (!psoc) 783 return; 784 /* do this only for STA and P2P-CLI mode */ 785 if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 786 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) 787 return; 788 if (!policy_mgr_scan_trim_5g_chnls_for_dfs_ap(psoc)) 789 return; 790 num_scan_channels = 0; 791 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 792 if (WLAN_REG_IS_5GHZ_CH_FREQ( 793 req->scan_req.chan_list.chan[i].freq)) { 794 continue; 795 } 796 req->scan_req.chan_list.chan[num_scan_channels++] = 797 req->scan_req.chan_list.chan[i]; 798 } 799 if (num_scan_channels < req->scan_req.chan_list.num_chan) 800 scm_debug("5g chan skipped (%d, %d)", 801 req->scan_req.chan_list.num_chan, num_scan_channels); 802 req->scan_req.chan_list.num_chan = num_scan_channels; 803 } 804 #else 805 static inline 806 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, 807 struct scan_start_request *req, 808 struct wlan_scan_obj *scan_obj) 809 { 810 } 811 812 static inline void 813 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) 814 { 815 } 816 817 static inline void scm_scan_chlist_concurrency_modify( 818 struct wlan_objmgr_vdev *vdev, struct scan_start_request *req) 819 { 820 } 821 #endif 822 823 #ifdef CONFIG_BAND_6GHZ 824 static void 825 scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, 826 struct chan_list *chan_list, 827 struct wlan_scan_obj *scan_obj) 828 { 829 uint8_t i; 830 struct regulatory_channel *chan_list_6g; 831 bool psc_channel_found = false; 832 bool channel_6g_found = false; 833 uint8_t num_scan_channels = 0, channel_count; 834 struct wlan_objmgr_pdev *pdev; 835 uint32_t freq; 836 837 pdev = wlan_vdev_get_pdev(vdev); 838 if (!pdev) 839 return; 840 841 scm_debug("6g scan mode %d", scan_obj->scan_def.scan_mode_6g); 842 for (i = 0; i < chan_list->num_chan; i++) { 843 freq = chan_list->chan[i].freq; 844 if ((scan_obj->scan_def.scan_mode_6g == 845 SCAN_MODE_6G_NO_CHANNEL) && 846 (wlan_reg_is_6ghz_chan_freq(freq))) { 847 /* Drop the 6Ghz channels */ 848 continue; 849 } else if ((scan_obj->scan_def.scan_mode_6g == 850 SCAN_MODE_6G_PSC_CHANNEL) && 851 (wlan_reg_is_6ghz_chan_freq(freq))) { 852 /* Allow only PSC channels */ 853 if (wlan_reg_is_6ghz_psc_chan_freq(freq)) 854 psc_channel_found = true; 855 else 856 continue; 857 } else if ((scan_obj->scan_def.scan_mode_6g == 858 SCAN_MODE_6G_ALL_CHANNEL) && 859 (wlan_reg_is_6ghz_chan_freq(freq))) { 860 /* Allow any 6ghz channel */ 861 channel_6g_found = true; 862 } 863 chan_list->chan[num_scan_channels++] = 864 chan_list->chan[i]; 865 } 866 867 scm_debug("psc_channel_found %d channel_6g_found%d", 868 psc_channel_found, channel_6g_found); 869 if ((scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_PSC_CHANNEL && 870 !psc_channel_found) || 871 (scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_ALL_CHANNEL && 872 !channel_6g_found)) { 873 chan_list_6g = qdf_mem_malloc(NUM_6GHZ_CHANNELS * 874 sizeof(struct regulatory_channel)); 875 if (!chan_list_6g) 876 goto end; 877 878 /* Add the 6Ghz channels based on config*/ 879 channel_count = wlan_reg_get_band_channel_list(pdev, 880 BIT(REG_BAND_6G), 881 chan_list_6g); 882 scm_debug("Number of 6G channels %d", channel_count); 883 for (i = 0; i < channel_count; i++) { 884 if ((scan_obj->scan_def.scan_mode_6g == 885 SCAN_MODE_6G_PSC_CHANNEL) && 886 (!psc_channel_found) && 887 wlan_reg_is_6ghz_psc_chan_freq(chan_list_6g[i]. 888 center_freq)) { 889 chan_list->chan[num_scan_channels++].freq = 890 chan_list_6g[i].center_freq; 891 } else if ((scan_obj->scan_def.scan_mode_6g == 892 SCAN_MODE_6G_ALL_CHANNEL) && 893 (!channel_6g_found)) { 894 chan_list->chan[num_scan_channels++].freq = 895 chan_list_6g[i].center_freq; 896 } 897 } 898 qdf_mem_free(chan_list_6g); 899 } 900 end: 901 chan_list->num_chan = num_scan_channels; 902 } 903 #else 904 static void 905 scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, 906 struct chan_list *chan_list, 907 struct wlan_scan_obj *scan_obj) 908 { 909 } 910 #endif 911 912 #ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO 913 static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, 914 struct chan_list *chan_list) 915 { 916 uint8_t i, j = 0, min, tmp_list_count; 917 struct meta_rnr_channel *channel; 918 struct chan_info temp_list[MAX_6GHZ_CHANNEL]; 919 struct rnr_chan_weight *rnr_chan_info, *temp; 920 uint32_t weight; 921 922 rnr_chan_info = qdf_mem_malloc(sizeof(rnr_chan_info) * MAX_6GHZ_CHANNEL); 923 if (!rnr_chan_info) 924 return; 925 926 for (i = 0; i < chan_list->num_chan; i++) { 927 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_list->chan[i].freq)) 928 temp_list[j++].freq = chan_list->chan[i].freq; 929 } 930 tmp_list_count = j; 931 scm_debug("Total 6ghz channels %d", tmp_list_count); 932 933 /* No Need to sort if the 6ghz channels are less than one */ 934 if (tmp_list_count < 1) { 935 qdf_mem_free(rnr_chan_info); 936 return; 937 } 938 939 /* compute the weightage */ 940 for (i = 0; i < tmp_list_count; i++) { 941 channel = scm_get_chan_meta(temp_list[i].freq); 942 weight = channel->bss_beacon_probe_count * BCN_PROBE_WEIGHTAGE + 943 channel->saved_profile_count * SAVED_PROFILE_WEIGHTAGE; 944 rnr_chan_info[i].weight = weight; 945 rnr_chan_info[i].chan_freq = temp_list[i].freq; 946 } 947 948 /* Sort the channel using selection sort */ 949 for (i = 0; i < tmp_list_count - 1; i++) { 950 min = i; 951 for (j = i + 1; j < tmp_list_count; j++) { 952 if (rnr_chan_info[j].weight < 953 rnr_chan_info[min].weight) { 954 min = j; 955 } 956 } 957 if (min != i) { 958 qdf_mem_copy(&temp, &rnr_chan_info[min], 959 sizeof(*rnr_chan_info)); 960 qdf_mem_copy(&rnr_chan_info[min], &rnr_chan_info[i], 961 sizeof(*rnr_chan_info)); 962 qdf_mem_copy(&rnr_chan_info[i], &temp, 963 sizeof(*rnr_chan_info)); 964 } 965 } 966 967 /* update the 6g list based on the weightage */ 968 for (i = 0, j = 0; 969 (i < NUM_CHANNELS && j < NUM_6GHZ_CHANNELS); i++) { 970 if (wlan_reg_is_6ghz_chan_freq(chan_list->chan[i].freq)) 971 chan_list->chan[i].freq = rnr_chan_info[j++].chan_freq; 972 } 973 qdf_mem_free(rnr_chan_info); 974 } 975 976 static void scm_update_rnr_info(struct scan_start_request *req) 977 { 978 uint8_t i, num_bssid = 0, num_ssid = 0; 979 uint8_t total_count = MAX_HINTS_PER_SCAN_REQ; 980 uint32_t freq; 981 struct meta_rnr_channel *chan; 982 qdf_list_node_t *cur_node, *next_node = NULL; 983 struct scan_rnr_node *rnr_node; 984 struct chan_list *chan_list; 985 QDF_STATUS status; 986 987 if (!req) 988 return; 989 990 chan_list = &req->scan_req.chan_list; 991 for (i = 0; i < chan_list->num_chan; i++) { 992 freq = chan_list->chan[i].freq; 993 if (!wlan_reg_is_6ghz_chan_freq(freq)) 994 continue; 995 996 chan = scm_get_chan_meta(freq); 997 if (!chan) { 998 scm_debug("Failed to get meta, freq %d", freq); 999 continue; 1000 } 1001 if (qdf_list_empty(&chan->rnr_list)) 1002 continue; 1003 1004 qdf_list_peek_front(&chan->rnr_list, &cur_node); 1005 while (cur_node && total_count) { 1006 rnr_node = qdf_container_of(cur_node, 1007 struct scan_rnr_node, 1008 node); 1009 if (!qdf_is_macaddr_zero(&rnr_node->entry.bssid)) { 1010 qdf_mem_copy(&req->scan_req.hint_bssid[num_bssid++].bssid, 1011 &rnr_node->entry.bssid, 1012 QDF_MAC_ADDR_SIZE); 1013 req->scan_req.num_hint_bssid++; 1014 total_count--; 1015 } else if (rnr_node->entry.short_ssid) { 1016 req->scan_req.hint_s_ssid[num_ssid++].short_ssid = 1017 rnr_node->entry.short_ssid; 1018 req->scan_req.num_hint_s_ssid++; 1019 total_count--; 1020 } 1021 status = qdf_list_peek_next(&chan->rnr_list, cur_node, 1022 &next_node); 1023 if (QDF_IS_STATUS_ERROR(status)) 1024 break; 1025 cur_node = next_node; 1026 next_node = NULL; 1027 } 1028 } 1029 } 1030 #else 1031 static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, 1032 struct chan_list *chan_list) 1033 { 1034 } 1035 1036 static void scm_update_rnr_info(struct scan_start_request *req) 1037 { 1038 } 1039 #endif 1040 1041 /** 1042 * scm_update_channel_list() - update scan req params depending on dfs inis 1043 * and initial scan request. 1044 * @req: scan request 1045 * @scan_obj: scan object 1046 * 1047 * Return: void 1048 */ 1049 static void 1050 scm_update_channel_list(struct scan_start_request *req, 1051 struct wlan_scan_obj *scan_obj) 1052 { 1053 uint8_t i; 1054 uint8_t num_scan_channels = 0; 1055 struct scan_vdev_obj *scan_vdev_obj; 1056 struct wlan_objmgr_pdev *pdev; 1057 bool first_scan_done = true; 1058 bool p2p_search = false; 1059 bool skip_dfs_ch = true; 1060 uint32_t first_freq; 1061 1062 pdev = wlan_vdev_get_pdev(req->vdev); 1063 1064 scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); 1065 if (!scan_vdev_obj) { 1066 scm_err("null scan_vdev_obj"); 1067 return; 1068 } 1069 1070 if (!scan_vdev_obj->first_scan_done) { 1071 first_scan_done = false; 1072 scan_vdev_obj->first_scan_done = true; 1073 } 1074 1075 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH) 1076 p2p_search = true; 1077 /* 1078 * No need to update channels if req is single channel* ie ROC, 1079 * Preauth or a single channel scan etc. 1080 * If the single chan in the scan channel list is an NOL channel,it is 1081 * removed and it would reduce the number of scan channels to 0. 1082 */ 1083 first_freq = req->scan_req.chan_list.chan[0].freq; 1084 if ((req->scan_req.chan_list.num_chan == 1) && 1085 (!utils_dfs_is_freq_in_nol(pdev, first_freq))) 1086 return; 1087 1088 /* do this only for STA and P2P-CLI mode */ 1089 if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && 1090 !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) && 1091 !p2p_search) 1092 skip_dfs_ch = false; 1093 1094 if ((scan_obj->scan_def.allow_dfs_chan_in_scan && 1095 (scan_obj->scan_def.allow_dfs_chan_in_first_scan || 1096 first_scan_done)) && 1097 !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search) && 1098 !scan_obj->miracast_enabled) 1099 skip_dfs_ch = false; 1100 1101 for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { 1102 uint32_t freq; 1103 1104 freq = req->scan_req.chan_list.chan[i].freq; 1105 if (skip_dfs_ch && 1106 wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) { 1107 scm_nofl_debug("Skip DFS freq %d", freq); 1108 continue; 1109 } 1110 if (utils_dfs_is_freq_in_nol(pdev, freq)) { 1111 scm_nofl_debug("Skip NOL freq %d", freq); 1112 continue; 1113 } 1114 1115 req->scan_req.chan_list.chan[num_scan_channels++] = 1116 req->scan_req.chan_list.chan[i]; 1117 } 1118 1119 req->scan_req.chan_list.num_chan = num_scan_channels; 1120 /* Dont upadte the channel list for SAP mode */ 1121 if (wlan_vdev_mlme_get_opmode(req->vdev) != QDF_SAP_MODE) { 1122 scm_update_6ghz_channel_list(req->vdev, 1123 &req->scan_req.chan_list, 1124 scan_obj); 1125 scm_sort_6ghz_channel_list(req->vdev, &req->scan_req.chan_list); 1126 } 1127 scm_scan_chlist_concurrency_modify(req->vdev, req); 1128 } 1129 1130 /** 1131 * scm_scan_req_update_params() - update scan req params depending on modes 1132 * and scan type. 1133 * @vdev: vdev object pointer 1134 * @req: scan request 1135 * @scan_obj: scan object 1136 * 1137 * Return: void 1138 */ 1139 static void 1140 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, 1141 struct scan_start_request *req, 1142 struct wlan_scan_obj *scan_obj) 1143 { 1144 struct chan_list *custom_chan_list; 1145 struct wlan_objmgr_pdev *pdev; 1146 uint8_t pdev_id; 1147 1148 /* Ensure correct number of probes are sent on active channel */ 1149 if (!req->scan_req.repeat_probe_time) 1150 req->scan_req.repeat_probe_time = 1151 req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; 1152 1153 if (req->scan_req.scan_f_passive) 1154 req->scan_req.scan_ctrl_flags_ext |= 1155 SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; 1156 1157 if (!req->scan_req.n_probes) 1158 req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? 1159 req->scan_req.dwell_time_active / 1160 req->scan_req.repeat_probe_time : 0; 1161 1162 if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH || 1163 req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1164 req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; 1165 req->scan_req.dwell_time_active_2g = 0; 1166 if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) { 1167 req->scan_req.repeat_probe_time = 0; 1168 } else { 1169 req->scan_req.scan_f_filter_prb_req = true; 1170 if (!req->scan_req.num_ssids) 1171 req->scan_req.scan_f_bcast_probe = true; 1172 1173 req->scan_req.dwell_time_active += 1174 P2P_SEARCH_DWELL_TIME_INC; 1175 /* 1176 * 3 channels with default max dwell time 40 ms. 1177 * Cap limit will be set by 1178 * P2P_SCAN_MAX_BURST_DURATION. Burst duration 1179 * should be such that no channel is scanned less 1180 * than the dwell time in normal scenarios. 1181 */ 1182 if (req->scan_req.chan_list.num_chan == 1183 WLAN_P2P_SOCIAL_CHANNELS && 1184 !scan_obj->miracast_enabled) 1185 req->scan_req.repeat_probe_time = 1186 req->scan_req.dwell_time_active / 5; 1187 else 1188 req->scan_req.repeat_probe_time = 1189 req->scan_req.dwell_time_active / 3; 1190 if (scan_obj->scan_def.p2p_scan_burst_duration) { 1191 req->scan_req.burst_duration = 1192 scan_obj->scan_def. 1193 p2p_scan_burst_duration; 1194 } else { 1195 req->scan_req.burst_duration = 1196 BURST_SCAN_MAX_NUM_OFFCHANNELS * 1197 req->scan_req.dwell_time_active; 1198 if (req->scan_req.burst_duration > 1199 P2P_SCAN_MAX_BURST_DURATION) { 1200 uint8_t channels = 1201 P2P_SCAN_MAX_BURST_DURATION / 1202 req->scan_req.dwell_time_active; 1203 if (channels) 1204 req->scan_req.burst_duration = 1205 channels * 1206 req->scan_req.dwell_time_active; 1207 else 1208 req->scan_req.burst_duration = 1209 P2P_SCAN_MAX_BURST_DURATION; 1210 } 1211 } 1212 req->scan_req.scan_ev_bss_chan = false; 1213 } 1214 } else { 1215 req->scan_req.scan_f_cck_rates = true; 1216 if (!req->scan_req.num_ssids) 1217 req->scan_req.scan_f_bcast_probe = true; 1218 req->scan_req.scan_f_add_ds_ie_in_probe = true; 1219 req->scan_req.scan_f_filter_prb_req = true; 1220 req->scan_req.scan_f_add_tpc_ie_in_probe = true; 1221 } 1222 1223 scm_update_dbs_scan_ctrl_ext_flag(req); 1224 1225 /* 1226 * No need to update conncurrency parmas if req is passive scan on 1227 * single channel ie ROC, Preauth etc 1228 */ 1229 if (!(req->scan_req.scan_f_passive && 1230 req->scan_req.chan_list.num_chan == 1) && 1231 req->scan_req.scan_type != SCAN_TYPE_RRM) 1232 scm_req_update_concurrency_params(vdev, req, scan_obj); 1233 1234 /* 1235 * Set wide band flag if enabled. This will cause 1236 * phymode TLV being sent to FW. 1237 */ 1238 pdev = wlan_vdev_get_pdev(vdev); 1239 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1240 if (ucfg_scan_get_wide_band_scan(pdev)) 1241 req->scan_req.scan_f_wide_band = true; 1242 else 1243 req->scan_req.scan_f_wide_band = false; 1244 1245 /* 1246 * Overwrite scan channles with custom scan channel 1247 * list if configured. 1248 */ 1249 custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; 1250 if (custom_chan_list->num_chan) 1251 qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, 1252 sizeof(struct chan_list)); 1253 else if (!req->scan_req.chan_list.num_chan) 1254 ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); 1255 1256 scm_update_channel_list(req, scan_obj); 1257 scm_update_rnr_info(req); 1258 } 1259 1260 static inline void scm_print_scan_req_info(struct scan_req_params *req) 1261 { 1262 uint32_t buff_len; 1263 char *chan_buff; 1264 uint32_t len = 0; 1265 uint8_t idx; 1266 struct chan_list *chan_lst; 1267 1268 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", 1269 req->scan_id, req->vdev_id, req->dwell_time_active, 1270 req->dwell_time_passive, req->dwell_time_active_2g, 1271 req->dwell_time_active_6g, req->dwell_time_passive_6g, 1272 req->repeat_probe_time, req->n_probes, req->scan_flags, 1273 req->scan_ctrl_flags_ext, req->scan_events, 1274 req->scan_policy_type, req->scan_f_wide_band, 1275 req->scan_priority); 1276 1277 for (idx = 0; idx < req->num_ssids; idx++) 1278 scm_nofl_debug("SSID[%d]: %.*s", idx, req->ssid[idx].length, 1279 req->ssid[idx].ssid); 1280 1281 chan_lst = &req->chan_list; 1282 1283 if (!chan_lst->num_chan) 1284 return; 1285 /* 1286 * Buffer of (num channl * 5) + 1 to consider the 4 char freq and 1287 * 1 space after it for each channel and 1 to end the string with NULL. 1288 */ 1289 buff_len = (chan_lst->num_chan * 5) + 1; 1290 chan_buff = qdf_mem_malloc(buff_len); 1291 if (!chan_buff) 1292 return; 1293 1294 for (idx = 0; idx < chan_lst->num_chan; idx++) 1295 len += qdf_scnprintf(chan_buff + len, buff_len - len, "%d ", 1296 chan_lst->chan[idx].freq); 1297 1298 scm_nofl_debug("Freq list[%d]: %s", chan_lst->num_chan, chan_buff); 1299 1300 qdf_mem_free(chan_buff); 1301 } 1302 QDF_STATUS 1303 scm_scan_start_req(struct scheduler_msg *msg) 1304 { 1305 struct wlan_serialization_command cmd = {0, }; 1306 enum wlan_serialization_status ser_cmd_status; 1307 struct scan_start_request *req = NULL; 1308 struct wlan_scan_obj *scan_obj; 1309 QDF_STATUS status = QDF_STATUS_SUCCESS; 1310 1311 1312 if (!msg) { 1313 scm_err("msg received is NULL"); 1314 QDF_ASSERT(0); 1315 return QDF_STATUS_E_NULL_VALUE; 1316 } 1317 if (!msg->bodyptr) { 1318 scm_err("bodyptr is NULL"); 1319 QDF_ASSERT(0); 1320 return QDF_STATUS_E_NULL_VALUE; 1321 } 1322 1323 req = msg->bodyptr; 1324 1325 if (!scm_is_scan_allowed(req->vdev)) { 1326 scm_err("scan disabled, rejecting the scan req"); 1327 status = QDF_STATUS_E_NULL_VALUE; 1328 goto err; 1329 } 1330 1331 scan_obj = wlan_vdev_get_scan_obj(req->vdev); 1332 if (!scan_obj) { 1333 scm_debug("Couldn't find scan object"); 1334 status = QDF_STATUS_E_NULL_VALUE; 1335 goto err; 1336 } 1337 1338 scm_scan_req_update_params(req->vdev, req, scan_obj); 1339 scm_print_scan_req_info(&req->scan_req); 1340 1341 if (!req->scan_req.chan_list.num_chan) { 1342 scm_info("Reject 0 channel Scan"); 1343 status = QDF_STATUS_E_NULL_VALUE; 1344 goto err; 1345 } 1346 1347 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1348 cmd.cmd_id = req->scan_req.scan_id; 1349 cmd.cmd_cb = scm_scan_serialize_callback; 1350 cmd.umac_cmd = req; 1351 cmd.source = WLAN_UMAC_COMP_SCAN; 1352 cmd.is_high_priority = false; 1353 cmd.cmd_timeout_duration = req->scan_req.max_scan_time + 1354 SCAN_TIMEOUT_GRACE_PERIOD; 1355 cmd.vdev = req->vdev; 1356 1357 if (scan_obj->disable_timeout) 1358 cmd.cmd_timeout_duration = 0; 1359 1360 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION, 1361 WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id, 1362 req->scan_req.scan_id); 1363 1364 ser_cmd_status = wlan_serialization_request(&cmd); 1365 switch (ser_cmd_status) { 1366 case WLAN_SER_CMD_PENDING: 1367 /* command moved to pending list.Do nothing */ 1368 break; 1369 case WLAN_SER_CMD_ACTIVE: 1370 /* command moved to active list. Do nothing */ 1371 break; 1372 default: 1373 scm_debug("ser cmd status %d", ser_cmd_status); 1374 goto err; 1375 } 1376 1377 return status; 1378 err: 1379 /* 1380 * notify registered scan event handlers 1381 * about internal error 1382 */ 1383 scm_post_internal_scan_complete_event(req, 1384 SCAN_REASON_INTERNAL_FAILURE); 1385 /* 1386 * cmd can't be serviced. 1387 * release vdev reference and free scan_start_request memory 1388 */ 1389 if (req) { 1390 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1391 scm_scan_free_scan_request_mem(req); 1392 } 1393 1394 return status; 1395 } 1396 1397 static inline enum wlan_serialization_cancel_type 1398 get_serialization_cancel_type(enum scan_cancel_req_type type) 1399 { 1400 enum wlan_serialization_cancel_type serialization_type; 1401 1402 switch (type) { 1403 case WLAN_SCAN_CANCEL_SINGLE: 1404 serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN; 1405 break; 1406 case WLAN_SCAN_CANCEL_VDEV_ALL: 1407 serialization_type = WLAN_SER_CANCEL_VDEV_SCANS; 1408 break; 1409 case WLAN_SCAN_CANCEL_PDEV_ALL: 1410 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1411 break; 1412 default: 1413 QDF_ASSERT(0); 1414 scm_warn("invalid scan_cancel_req_type: %d", type); 1415 serialization_type = WLAN_SER_CANCEL_PDEV_SCANS; 1416 break; 1417 } 1418 1419 return serialization_type; 1420 } 1421 1422 QDF_STATUS 1423 scm_scan_cancel_req(struct scheduler_msg *msg) 1424 { 1425 struct wlan_serialization_queued_cmd_info cmd = {0,}; 1426 struct wlan_serialization_command ser_cmd = {0,}; 1427 enum wlan_serialization_cmd_status ser_cmd_status; 1428 struct scan_cancel_request *req; 1429 QDF_STATUS status = QDF_STATUS_SUCCESS; 1430 1431 if (!msg) { 1432 scm_err("msg received is NULL"); 1433 QDF_ASSERT(0); 1434 return QDF_STATUS_E_NULL_VALUE; 1435 } 1436 if (!msg->bodyptr) { 1437 scm_err("Bodyptr is NULL"); 1438 QDF_ASSERT(0); 1439 return QDF_STATUS_E_NULL_VALUE; 1440 } 1441 1442 req = msg->bodyptr; 1443 /* 1444 * If requester wants to wait for target scan cancel event 1445 * instead of internally generated cancel event, just check 1446 * which queue this scan request belongs to and send scan 1447 * cancel request to FW accordingly. 1448 * Else generate internal scan cancel event and notify 1449 * handlers and free scan request resources. 1450 */ 1451 if (req->wait_tgt_cancel && 1452 (req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) { 1453 ser_cmd.cmd_type = WLAN_SER_CMD_SCAN; 1454 ser_cmd.cmd_id = req->cancel_req.scan_id; 1455 ser_cmd.cmd_cb = NULL; 1456 ser_cmd.umac_cmd = NULL; 1457 ser_cmd.source = WLAN_UMAC_COMP_SCAN; 1458 ser_cmd.is_high_priority = false; 1459 ser_cmd.vdev = req->vdev; 1460 if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd)) 1461 ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST; 1462 else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd)) 1463 ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST; 1464 else 1465 ser_cmd_status = WLAN_SER_CMD_NOT_FOUND; 1466 } else { 1467 cmd.requestor = 0; 1468 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1469 cmd.cmd_id = req->cancel_req.scan_id; 1470 cmd.vdev = req->vdev; 1471 cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE | 1472 WLAN_SERIALIZATION_PENDING_QUEUE; 1473 cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type); 1474 1475 ser_cmd_status = wlan_serialization_cancel_request(&cmd); 1476 } 1477 1478 scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d", 1479 ser_cmd_status, req->cancel_req.requester, 1480 req->cancel_req.scan_id, req->cancel_req.vdev_id, 1481 req->cancel_req.req_type); 1482 1483 switch (ser_cmd_status) { 1484 case WLAN_SER_CMD_IN_PENDING_LIST: 1485 /* do nothing */ 1486 break; 1487 case WLAN_SER_CMD_IN_ACTIVE_LIST: 1488 case WLAN_SER_CMDS_IN_ALL_LISTS: 1489 /* send wmi scan cancel to fw */ 1490 status = tgt_scan_cancel(req); 1491 break; 1492 case WLAN_SER_CMD_NOT_FOUND: 1493 /* do nothing */ 1494 break; 1495 default: 1496 QDF_ASSERT(0); 1497 status = QDF_STATUS_E_INVAL; 1498 break; 1499 } 1500 1501 /* Release vdev reference and scan cancel request 1502 * processing is complete 1503 */ 1504 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1505 /* Free cancel request memory */ 1506 qdf_mem_free(req); 1507 1508 return status; 1509 } 1510 1511 #ifdef FEATURE_WLAN_SCAN_PNO 1512 static QDF_STATUS 1513 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1514 struct scan_event *event) 1515 { 1516 struct scan_vdev_obj *scan_vdev_obj; 1517 struct wlan_scan_obj *scan_psoc_obj; 1518 scan_event_handler pno_cb; 1519 void *cb_arg; 1520 1521 scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); 1522 scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); 1523 if (!scan_vdev_obj || !scan_psoc_obj) { 1524 scm_err("null scan_vdev_obj %pK scan_obj %pK", 1525 scan_vdev_obj, scan_psoc_obj); 1526 return QDF_STATUS_E_INVAL; 1527 } 1528 1529 switch (event->type) { 1530 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1531 if (!scan_vdev_obj->pno_match_evt_received) 1532 return QDF_STATUS_SUCCESS; 1533 qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock, 1534 WIFI_POWER_EVENT_WAKELOCK_PNO); 1535 qdf_wake_lock_timeout_acquire( 1536 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1537 SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT); 1538 scan_vdev_obj->pno_match_evt_received = false; 1539 break; 1540 case SCAN_EVENT_TYPE_NLO_MATCH: 1541 scan_vdev_obj->pno_match_evt_received = true; 1542 qdf_wake_lock_timeout_acquire( 1543 &scan_psoc_obj->pno_cfg.pno_wake_lock, 1544 SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT); 1545 return QDF_STATUS_SUCCESS; 1546 default: 1547 return QDF_STATUS_E_INVAL; 1548 } 1549 qdf_spin_lock_bh(&scan_psoc_obj->lock); 1550 pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func; 1551 cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg; 1552 qdf_spin_unlock_bh(&scan_psoc_obj->lock); 1553 1554 if (pno_cb) 1555 pno_cb(vdev, event, cb_arg); 1556 1557 return QDF_STATUS_SUCCESS; 1558 } 1559 #else 1560 1561 static QDF_STATUS 1562 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev, 1563 struct scan_event *event) 1564 { 1565 return QDF_STATUS_SUCCESS; 1566 } 1567 #endif 1568 1569 /** 1570 * scm_scan_update_scan_event() - update scan event 1571 * @scan: scan object 1572 * @event: scan event 1573 * @scan_start_req: scan_start_req used for triggering scan 1574 * 1575 * update scan params in scan event 1576 * 1577 * Return: QDF_STATUS 1578 */ 1579 static QDF_STATUS 1580 scm_scan_update_scan_event(struct wlan_scan_obj *scan, 1581 struct scan_event *event, 1582 struct scan_start_request *scan_start_req) 1583 { 1584 if (!event) 1585 return QDF_STATUS_E_NULL_VALUE; 1586 1587 if (!scan || !scan_start_req) { 1588 event->scan_start_req = NULL; 1589 return QDF_STATUS_E_NULL_VALUE; 1590 } 1591 /* copy scan start request to pass back buffer */ 1592 qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req, 1593 sizeof(struct scan_start_request)); 1594 /* reset all pointers */ 1595 scan->scan_start_request_buff.scan_req.extraie.ptr = NULL; 1596 scan->scan_start_request_buff.scan_req.extraie.len = 0; 1597 scan->scan_start_request_buff.scan_req.htcap.ptr = NULL; 1598 scan->scan_start_request_buff.scan_req.htcap.len = 0; 1599 scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL; 1600 scan->scan_start_request_buff.scan_req.vhtcap.len = 0; 1601 1602 event->scan_start_req = &scan->scan_start_request_buff; 1603 1604 return QDF_STATUS_SUCCESS; 1605 } 1606 1607 QDF_STATUS 1608 scm_scan_event_handler(struct scheduler_msg *msg) 1609 { 1610 struct wlan_objmgr_vdev *vdev; 1611 struct scan_event *event; 1612 struct scan_event_info *event_info; 1613 struct wlan_serialization_command cmd = {0,}; 1614 struct wlan_serialization_command *queued_cmd; 1615 struct scan_start_request *scan_start_req; 1616 struct wlan_scan_obj *scan; 1617 1618 if (!msg) { 1619 scm_err("NULL msg received "); 1620 QDF_ASSERT(0); 1621 return QDF_STATUS_E_NULL_VALUE; 1622 } 1623 if (!msg->bodyptr) { 1624 scm_err("NULL scan event received"); 1625 QDF_ASSERT(0); 1626 return QDF_STATUS_E_NULL_VALUE; 1627 } 1628 1629 event_info = msg->bodyptr; 1630 vdev = event_info->vdev; 1631 event = &(event_info->event); 1632 1633 scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d, scanid:%d", 1634 event->vdev_id, event->type, event->reason, event->chan_freq, 1635 event->requester, event->scan_id); 1636 /* 1637 * NLO requests are never queued, so post NLO events 1638 * without checking for their presence in active queue. 1639 */ 1640 switch (event->type) { 1641 case SCAN_EVENT_TYPE_NLO_COMPLETE: 1642 case SCAN_EVENT_TYPE_NLO_MATCH: 1643 scm_pno_event_handler(vdev, event); 1644 goto exit; 1645 default: 1646 break; 1647 } 1648 1649 cmd.cmd_type = WLAN_SER_CMD_SCAN; 1650 cmd.cmd_id = event->scan_id; 1651 cmd.cmd_cb = NULL; 1652 cmd.umac_cmd = NULL; 1653 cmd.source = WLAN_UMAC_COMP_SCAN; 1654 cmd.is_high_priority = false; 1655 cmd.vdev = vdev; 1656 if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { 1657 /* 1658 * We received scan event for an already completed/cancelled 1659 * scan request. Drop this event. 1660 */ 1661 scm_debug("Received scan event while request not in active queue"); 1662 goto exit; 1663 } 1664 1665 /* Fill scan_start_request used to trigger this scan */ 1666 queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id( 1667 wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), 1668 event->scan_id, true); 1669 1670 if (!queued_cmd) { 1671 scm_err("NULL queued_cmd"); 1672 goto exit; 1673 } 1674 if (!queued_cmd->umac_cmd) { 1675 scm_err("NULL umac_cmd"); 1676 goto exit; 1677 } 1678 scan_start_req = queued_cmd->umac_cmd; 1679 1680 if (scan_start_req->scan_req.scan_req_id != event->requester) { 1681 scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d", 1682 scan_start_req->scan_req.scan_req_id, event->requester); 1683 goto exit; 1684 } 1685 1686 scan = wlan_vdev_get_scan_obj(vdev); 1687 if (scan) 1688 scm_scan_update_scan_event(scan, event, scan_start_req); 1689 1690 switch (event->type) { 1691 case SCAN_EVENT_TYPE_COMPLETED: 1692 if (event->reason == SCAN_REASON_COMPLETED) 1693 scm_11d_decide_country_code(vdev); 1694 /* fall through to release the command */ 1695 case SCAN_EVENT_TYPE_START_FAILED: 1696 case SCAN_EVENT_TYPE_DEQUEUED: 1697 scm_release_serialization_command(vdev, event->scan_id); 1698 break; 1699 default: 1700 break; 1701 } 1702 1703 /* Notify all interested parties */ 1704 scm_scan_post_event(vdev, event); 1705 1706 exit: 1707 /* free event info memory */ 1708 qdf_mem_free(event_info); 1709 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1710 1711 return QDF_STATUS_SUCCESS; 1712 } 1713 1714 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg) 1715 { 1716 struct wlan_objmgr_vdev *vdev; 1717 struct scan_event_info *event_info; 1718 struct scan_event *event; 1719 1720 if (!msg || !msg->bodyptr) { 1721 scm_err("msg or msg->bodyptr is NULL"); 1722 return QDF_STATUS_E_NULL_VALUE; 1723 } 1724 1725 event_info = msg->bodyptr; 1726 vdev = event_info->vdev; 1727 event = &event_info->event; 1728 1729 scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d", 1730 event->vdev_id, event->type, event->reason, event->chan_freq, 1731 event->requester, event->scan_id); 1732 1733 /* free event info memory */ 1734 qdf_mem_free(event_info); 1735 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 1736 1737 return QDF_STATUS_SUCCESS; 1738 } 1739 1740 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg) 1741 { 1742 struct scan_bcn_probe_event *bcn; 1743 1744 bcn = msg->bodyptr; 1745 1746 if (!bcn) { 1747 scm_err("bcn is NULL"); 1748 return QDF_STATUS_E_NULL_VALUE; 1749 } 1750 if (bcn->psoc) 1751 wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); 1752 if (bcn->rx_data) 1753 qdf_mem_free(bcn->rx_data); 1754 if (bcn->buf) 1755 qdf_nbuf_free(bcn->buf); 1756 qdf_mem_free(bcn); 1757 1758 return QDF_STATUS_SUCCESS; 1759 } 1760 1761 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg) 1762 { 1763 struct scan_start_request *req; 1764 1765 if (!msg || !msg->bodyptr) { 1766 scm_err("msg or msg->bodyptr is NULL"); 1767 return QDF_STATUS_E_NULL_VALUE; 1768 } 1769 1770 req = msg->bodyptr; 1771 scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED); 1772 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1773 scm_scan_free_scan_request_mem(req); 1774 1775 return QDF_STATUS_SUCCESS; 1776 } 1777 1778 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg) 1779 { 1780 struct scan_cancel_request *req; 1781 1782 if (!msg || !msg->bodyptr) { 1783 scm_err("msg or msg->bodyptr is NULL"); 1784 return QDF_STATUS_E_NULL_VALUE; 1785 } 1786 1787 req = msg->bodyptr; 1788 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); 1789 /* Free cancel request memory */ 1790 qdf_mem_free(req); 1791 1792 return QDF_STATUS_SUCCESS; 1793 } 1794