1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * sap_module.c 22 * OVERVIEW: 23 * This software unit holds the implementation of the WLAN SAP modules 24 * functions providing EXTERNAL APIs. It is also where the global SAP module 25 * context gets initialised 26 * DEPENDENCIES: 27 * Are listed for each API below. 28 */ 29 30 /* $Header$ */ 31 32 /*---------------------------------------------------------------------------- 33 * Include Files 34 * -------------------------------------------------------------------------*/ 35 #include "qdf_trace.h" 36 #include "qdf_util.h" 37 #include "qdf_atomic.h" 38 /* Pick up the sme callback registration API */ 39 #include "sme_api.h" 40 41 /* SAP API header file */ 42 43 #include "sap_internal.h" 44 #include "sme_inside.h" 45 #include "cds_ieee80211_common_i.h" 46 #include "cds_regdomain.h" 47 #include "wlan_policy_mgr_api.h" 48 #include <wlan_scan_api.h> 49 #include "wlan_reg_services_api.h" 50 #include <wlan_dfs_utils_api.h> 51 #include <wlan_reg_ucfg_api.h> 52 #include <wlan_cfg80211_crypto.h> 53 #include <wlan_crypto_global_api.h> 54 #include "cfg_ucfg_api.h" 55 #include "wlan_mlme_ucfg_api.h" 56 #include "wlan_mlme_vdev_mgr_interface.h" 57 #include "pld_common.h" 58 #include "wlan_pre_cac_api.h" 59 #include "target_if.h" 60 61 #define SAP_DEBUG 62 static struct sap_context *gp_sap_ctx[SAP_MAX_NUM_SESSION]; 63 static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION]; 64 static qdf_mutex_t sap_context_lock; 65 66 /** 67 * wlansap_global_init() - Initialize SAP globals 68 * 69 * Initializes the SAP global data structures 70 * 71 * Return: QDF_STATUS 72 */ 73 QDF_STATUS wlansap_global_init(void) 74 { 75 uint32_t i; 76 77 if (QDF_IS_STATUS_ERROR(qdf_mutex_create(&sap_context_lock))) { 78 sap_err("failed to init sap_context_lock"); 79 return QDF_STATUS_E_FAULT; 80 } 81 82 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 83 gp_sap_ctx[i] = NULL; 84 qdf_atomic_init(&sap_ctx_ref_count[i]); 85 } 86 87 sap_debug("sap global context initialized"); 88 89 return QDF_STATUS_SUCCESS; 90 } 91 92 /** 93 * wlansap_global_deinit() - De-initialize SAP globals 94 * 95 * De-initializes the SAP global data structures 96 * 97 * Return: QDF_STATUS 98 */ 99 QDF_STATUS wlansap_global_deinit(void) 100 { 101 uint32_t i; 102 103 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 104 if (gp_sap_ctx[i]) { 105 sap_err("we could be leaking context:%d", i); 106 } 107 gp_sap_ctx[i] = NULL; 108 qdf_atomic_init(&sap_ctx_ref_count[i]); 109 } 110 111 if (QDF_IS_STATUS_ERROR(qdf_mutex_destroy(&sap_context_lock))) { 112 sap_err("failed to destroy sap_context_lock"); 113 return QDF_STATUS_E_FAULT; 114 } 115 116 sap_debug("sap global context deinitialized"); 117 118 return QDF_STATUS_SUCCESS; 119 } 120 121 /** 122 * wlansap_save_context() - Save the context in global SAP context 123 * @ctx: SAP context to be stored 124 * 125 * Stores the given SAP context in the global SAP context array 126 * 127 * Return: QDF_STATUS 128 */ 129 static QDF_STATUS wlansap_save_context(struct sap_context *ctx) 130 { 131 uint32_t i; 132 133 qdf_mutex_acquire(&sap_context_lock); 134 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 135 if (!gp_sap_ctx[i]) { 136 gp_sap_ctx[i] = ctx; 137 qdf_atomic_inc(&sap_ctx_ref_count[i]); 138 qdf_mutex_release(&sap_context_lock); 139 sap_debug("sap context saved at index: %d", i); 140 return QDF_STATUS_SUCCESS; 141 } 142 } 143 qdf_mutex_release(&sap_context_lock); 144 145 sap_err("failed to save sap context"); 146 147 return QDF_STATUS_E_FAILURE; 148 } 149 150 /** 151 * wlansap_context_get() - Verify SAP context and increment ref count 152 * @ctx: Context to be checked 153 * 154 * Verifies the SAP context and increments the reference count maintained for 155 * the corresponding SAP context. 156 * 157 * Return: QDF_STATUS 158 */ 159 QDF_STATUS wlansap_context_get(struct sap_context *ctx) 160 { 161 uint32_t i; 162 163 qdf_mutex_acquire(&sap_context_lock); 164 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 165 if (ctx && (gp_sap_ctx[i] == ctx)) { 166 qdf_atomic_inc(&sap_ctx_ref_count[i]); 167 qdf_mutex_release(&sap_context_lock); 168 return QDF_STATUS_SUCCESS; 169 } 170 } 171 qdf_mutex_release(&sap_context_lock); 172 173 sap_debug("sap session is not valid"); 174 return QDF_STATUS_E_FAILURE; 175 } 176 177 /** 178 * wlansap_context_put() - Check the reference count and free SAP context 179 * @ctx: SAP context to be checked and freed 180 * 181 * Checks the reference count and frees the SAP context 182 * 183 * Return: None 184 */ 185 void wlansap_context_put(struct sap_context *ctx) 186 { 187 uint32_t i; 188 189 if (!ctx) 190 return; 191 192 qdf_mutex_acquire(&sap_context_lock); 193 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 194 if (gp_sap_ctx[i] == ctx) { 195 if (qdf_atomic_dec_and_test(&sap_ctx_ref_count[i])) { 196 if (ctx->freq_list) { 197 qdf_mem_free(ctx->freq_list); 198 ctx->freq_list = NULL; 199 ctx->num_of_channel = 0; 200 } 201 qdf_mem_free(ctx); 202 gp_sap_ctx[i] = NULL; 203 sap_debug("sap session freed: %d", i); 204 } 205 qdf_mutex_release(&sap_context_lock); 206 return; 207 } 208 } 209 qdf_mutex_release(&sap_context_lock); 210 } 211 212 struct sap_context *sap_create_ctx(void) 213 { 214 struct sap_context *sap_ctx; 215 QDF_STATUS status; 216 217 sap_ctx = qdf_mem_malloc(sizeof(*sap_ctx)); 218 if (!sap_ctx) 219 return NULL; 220 221 /* Clean up SAP control block, initialize all values */ 222 /* Save the SAP context pointer */ 223 status = wlansap_save_context(sap_ctx); 224 if (QDF_IS_STATUS_ERROR(status)) { 225 sap_err("failed to save SAP context"); 226 qdf_mem_free(sap_ctx); 227 return NULL; 228 } 229 sap_debug("Exit"); 230 231 return sap_ctx; 232 } /* sap_create_ctx */ 233 234 static QDF_STATUS wlansap_owe_init(struct sap_context *sap_ctx) 235 { 236 qdf_list_create(&sap_ctx->owe_pending_assoc_ind_list, 0); 237 238 return QDF_STATUS_SUCCESS; 239 } 240 241 static QDF_STATUS wlansap_ft_init(struct sap_context *sap_ctx) 242 { 243 qdf_list_create(&sap_ctx->ft_pending_assoc_ind_list, 0); 244 qdf_event_create(&sap_ctx->ft_pending_event); 245 246 return QDF_STATUS_SUCCESS; 247 } 248 249 static void wlansap_owe_cleanup(struct sap_context *sap_ctx) 250 { 251 struct mac_context *mac; 252 struct owe_assoc_ind *owe_assoc_ind; 253 struct assoc_ind *assoc_ind = NULL; 254 qdf_list_node_t *node = NULL, *next_node = NULL; 255 QDF_STATUS status; 256 257 if (!sap_ctx) { 258 sap_err("Invalid SAP context"); 259 return; 260 } 261 262 mac = sap_get_mac_context(); 263 if (!mac) { 264 sap_err("Invalid MAC context"); 265 return; 266 } 267 268 if (QDF_STATUS_SUCCESS != 269 qdf_list_peek_front(&sap_ctx->owe_pending_assoc_ind_list, 270 &node)) { 271 sap_debug("Failed to find assoc ind list"); 272 return; 273 } 274 275 while (node) { 276 qdf_list_peek_next(&sap_ctx->owe_pending_assoc_ind_list, 277 node, &next_node); 278 owe_assoc_ind = qdf_container_of(node, struct owe_assoc_ind, 279 node); 280 status = qdf_list_remove_node( 281 &sap_ctx->owe_pending_assoc_ind_list, 282 node); 283 if (status == QDF_STATUS_SUCCESS) { 284 assoc_ind = owe_assoc_ind->assoc_ind; 285 qdf_mem_free(owe_assoc_ind); 286 assoc_ind->owe_ie = NULL; 287 assoc_ind->owe_ie_len = 0; 288 assoc_ind->owe_status = STATUS_UNSPECIFIED_FAILURE; 289 status = sme_update_owe_info(mac, assoc_ind); 290 qdf_mem_free(assoc_ind); 291 } else { 292 sap_err("Failed to remove assoc ind"); 293 } 294 node = next_node; 295 next_node = NULL; 296 } 297 } 298 299 static void wlansap_ft_cleanup(struct sap_context *sap_ctx) 300 { 301 struct mac_context *mac; 302 struct ft_assoc_ind *ft_assoc_ind; 303 struct assoc_ind *assoc_ind = NULL; 304 qdf_list_node_t *node = NULL, *next_node = NULL; 305 QDF_STATUS status; 306 307 if (!sap_ctx) { 308 sap_err("Invalid SAP context"); 309 return; 310 } 311 312 mac = sap_get_mac_context(); 313 if (!mac) { 314 sap_err("Invalid MAC context"); 315 return; 316 } 317 318 if (QDF_STATUS_SUCCESS != 319 qdf_list_peek_front(&sap_ctx->ft_pending_assoc_ind_list, 320 &node)) { 321 sap_debug("Failed to find assoc ind list"); 322 return; 323 } 324 325 while (node) { 326 qdf_list_peek_next(&sap_ctx->ft_pending_assoc_ind_list, 327 node, &next_node); 328 ft_assoc_ind = qdf_container_of(node, struct ft_assoc_ind, 329 node); 330 status = qdf_list_remove_node( 331 &sap_ctx->ft_pending_assoc_ind_list, node); 332 if (status == QDF_STATUS_SUCCESS) { 333 assoc_ind = ft_assoc_ind->assoc_ind; 334 qdf_mem_free(ft_assoc_ind); 335 assoc_ind->ft_ie = NULL; 336 assoc_ind->ft_ie_len = 0; 337 assoc_ind->ft_status = STATUS_UNSPECIFIED_FAILURE; 338 qdf_mem_free(assoc_ind); 339 } else { 340 sap_err("Failed to remove assoc ind"); 341 } 342 node = next_node; 343 next_node = NULL; 344 } 345 } 346 347 static void wlansap_owe_deinit(struct sap_context *sap_ctx) 348 { 349 qdf_list_destroy(&sap_ctx->owe_pending_assoc_ind_list); 350 } 351 352 static void wlansap_ft_deinit(struct sap_context *sap_ctx) 353 { 354 qdf_list_destroy(&sap_ctx->ft_pending_assoc_ind_list); 355 qdf_event_destroy(&sap_ctx->ft_pending_event); 356 } 357 358 QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx, 359 enum QDF_OPMODE mode, 360 uint8_t *addr, uint32_t session_id, bool reinit) 361 { 362 QDF_STATUS status; 363 struct mac_context *mac; 364 365 sap_debug("wlansap_start invoked successfully"); 366 367 if (!sap_ctx) { 368 sap_err("Invalid SAP pointer"); 369 return QDF_STATUS_E_FAULT; 370 } 371 372 sap_ctx->csa_reason = CSA_REASON_UNKNOWN; 373 qdf_mem_copy(sap_ctx->self_mac_addr, addr, QDF_MAC_ADDR_SIZE); 374 375 mac = sap_get_mac_context(); 376 if (!mac) { 377 sap_err("Invalid MAC context"); 378 return QDF_STATUS_E_INVAL; 379 } 380 381 status = sap_set_session_param(MAC_HANDLE(mac), sap_ctx, session_id); 382 if (QDF_STATUS_SUCCESS != status) { 383 sap_err("Calling sap_set_session_param status = %d", status); 384 return QDF_STATUS_E_FAILURE; 385 } 386 /* Register with scan component only during init */ 387 if (!reinit) 388 sap_ctx->req_id = 389 wlan_scan_register_requester(mac->psoc, "SAP", 390 sap_scan_event_callback, sap_ctx); 391 392 if (!reinit) { 393 status = wlansap_owe_init(sap_ctx); 394 if (QDF_STATUS_SUCCESS != status) { 395 sap_err("OWE init failed"); 396 return QDF_STATUS_E_FAILURE; 397 } 398 status = wlansap_ft_init(sap_ctx); 399 if (QDF_STATUS_SUCCESS != status) { 400 sap_err("FT init failed"); 401 return QDF_STATUS_E_FAILURE; 402 } 403 } 404 405 return QDF_STATUS_SUCCESS; 406 } 407 408 QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx) 409 { 410 struct mac_context *mac; 411 412 /* Sanity check - Extract SAP control block */ 413 sap_debug("wlansap_stop invoked successfully "); 414 415 if (!sap_ctx) { 416 sap_err("Invalid SAP pointer"); 417 return QDF_STATUS_E_FAULT; 418 } 419 420 wlansap_ft_cleanup(sap_ctx); 421 wlansap_ft_deinit(sap_ctx); 422 wlansap_owe_cleanup(sap_ctx); 423 wlansap_owe_deinit(sap_ctx); 424 mac = sap_get_mac_context(); 425 if (!mac) { 426 sap_err("Invalid MAC context"); 427 return QDF_STATUS_E_FAULT; 428 } 429 wlan_scan_unregister_requester(mac->psoc, sap_ctx->req_id); 430 431 if (sap_ctx->freq_list) { 432 qdf_mem_free(sap_ctx->freq_list); 433 sap_ctx->freq_list = NULL; 434 sap_ctx->num_of_channel = 0; 435 } 436 437 if (sap_ctx->sessionId != WLAN_UMAC_VDEV_ID_MAX) { 438 /* empty queues/lists/pkts if any */ 439 sap_clear_session_param(MAC_HANDLE(mac), sap_ctx, 440 sap_ctx->sessionId); 441 } 442 443 return QDF_STATUS_SUCCESS; 444 } 445 446 QDF_STATUS sap_destroy_ctx(struct sap_context *sap_ctx) 447 { 448 sap_debug("Enter"); 449 450 if (!sap_ctx) { 451 sap_err("Invalid SAP pointer"); 452 return QDF_STATUS_E_FAULT; 453 } 454 /* Cleanup SAP control block */ 455 /* 456 * wlansap_context_put will release actual sap_ctx memory 457 * allocated during sap_create_ctx 458 */ 459 wlansap_context_put(sap_ctx); 460 461 return QDF_STATUS_SUCCESS; 462 } /* sap_destroy_ctx */ 463 464 bool wlansap_is_channel_in_nol_list(struct sap_context *sap_ctx, 465 qdf_freq_t chan_freq, 466 ePhyChanBondState chanBondState) 467 { 468 if (!sap_ctx) { 469 sap_err("Invalid SAP pointer from pCtx"); 470 return QDF_STATUS_E_FAULT; 471 } 472 473 return sap_dfs_is_channel_in_nol_list(sap_ctx, chan_freq, 474 chanBondState); 475 } 476 477 static QDF_STATUS wlansap_mark_leaking_channel(struct wlan_objmgr_pdev *pdev, 478 uint16_t *leakage_adjusted_lst, 479 uint8_t chan_bw) 480 { 481 482 return utils_dfs_mark_leaking_chan_for_freq(pdev, chan_bw, 1, 483 leakage_adjusted_lst); 484 } 485 486 bool wlansap_is_channel_leaking_in_nol(struct sap_context *sap_ctx, 487 uint16_t chan_freq, 488 uint8_t chan_bw) 489 { 490 struct mac_context *mac_ctx; 491 uint16_t leakage_adjusted_lst[1]; 492 493 leakage_adjusted_lst[0] = chan_freq; 494 mac_ctx = sap_get_mac_context(); 495 if (!mac_ctx) { 496 sap_err("Invalid MAC context"); 497 return QDF_STATUS_E_FAULT; 498 } 499 if (QDF_IS_STATUS_ERROR(wlansap_mark_leaking_channel(mac_ctx->pdev, 500 leakage_adjusted_lst, chan_bw))) 501 return true; 502 503 if (!leakage_adjusted_lst[0]) 504 return true; 505 506 return false; 507 } 508 509 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 510 uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx) 511 { 512 struct mac_context *mac; 513 uint16_t intf_ch_freq; 514 eCsrPhyMode phy_mode; 515 uint8_t vdev_id; 516 517 mac = sap_get_mac_context(); 518 if (!mac) { 519 sap_err("Invalid MAC context"); 520 return 0; 521 } 522 phy_mode = sap_ctx->phyMode; 523 vdev_id = sap_ctx->sessionId; 524 intf_ch_freq = sme_check_concurrent_channel_overlap( 525 MAC_HANDLE(mac), 526 sap_ctx->chan_freq, 527 phy_mode, 528 sap_ctx->cc_switch_mode, 529 vdev_id); 530 return intf_ch_freq; 531 } 532 #endif 533 534 /** 535 * wlansap_set_scan_acs_channel_params() - Config scan and channel parameters. 536 * config: Pointer to the SAP config 537 * psap_ctx: Pointer to the SAP Context. 538 * pusr_context: Parameter that will be passed 539 * back in all the SAP callback events. 540 * 541 * This api function is used to copy Scan and Channel parameters from sap 542 * config to sap context. 543 * 544 * Return: The result code associated with 545 * performing the operation 546 */ 547 static QDF_STATUS 548 wlansap_set_scan_acs_channel_params(struct sap_config *config, 549 struct sap_context *psap_ctx, 550 void *pusr_context) 551 { 552 struct mac_context *mac; 553 QDF_STATUS status = QDF_STATUS_SUCCESS; 554 uint32_t auto_channel_select_weight; 555 556 if (!config) { 557 sap_err("Invalid config passed "); 558 return QDF_STATUS_E_FAULT; 559 } 560 561 if (!psap_ctx) { 562 sap_err("Invalid config passed "); 563 return QDF_STATUS_E_FAULT; 564 } 565 566 mac = sap_get_mac_context(); 567 if (!mac) { 568 sap_err("Invalid MAC context"); 569 return QDF_STATUS_E_INVAL; 570 } 571 572 /* Channel selection is auto or configured */ 573 wlansap_set_acs_ch_freq(psap_ctx, config->chan_freq); 574 psap_ctx->dfs_mode = config->acs_dfs_mode; 575 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 576 psap_ctx->cc_switch_mode = config->cc_switch_mode; 577 #endif 578 status = ucfg_mlme_get_auto_channel_weight( 579 mac->psoc, 580 &auto_channel_select_weight); 581 582 if (!QDF_IS_STATUS_SUCCESS(status)) 583 sap_err("get_auto_channel_weight failed"); 584 585 psap_ctx->auto_channel_select_weight = auto_channel_select_weight; 586 sap_debug("auto_channel_select_weight %d", 587 psap_ctx->auto_channel_select_weight); 588 589 psap_ctx->user_context = pusr_context; 590 psap_ctx->enableOverLapCh = config->enOverLapCh; 591 psap_ctx->acs_cfg = &config->acs_cfg; 592 psap_ctx->ch_width_orig = config->acs_cfg.ch_width; 593 psap_ctx->sec_ch_freq = config->sec_ch_freq; 594 qdf_mem_copy(psap_ctx->self_mac_addr, 595 config->self_macaddr.bytes, QDF_MAC_ADDR_SIZE); 596 597 return status; 598 } 599 600 eCsrPhyMode wlan_sap_get_phymode(struct sap_context *sap_ctx) 601 { 602 if (!sap_ctx) { 603 sap_err("Invalid SAP pointer from ctx"); 604 return 0; 605 } 606 return sap_ctx->phyMode; 607 } 608 609 enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev, 610 struct wlan_objmgr_psoc *psoc, 611 qdf_freq_t con_ch_freq, 612 enum phy_ch_width channel_width) 613 { 614 enum hw_mode_bandwidth sta_ch_width; 615 enum phy_ch_width sta_chan_width = CH_WIDTH_20MHZ; 616 bool scc_sta_present, is_con_chan_dfs = false; 617 bool is_con_sta_indoor = false; 618 uint8_t sta_vdev_id; 619 uint8_t sta_sap_scc_on_dfs_chnl; 620 uint8_t sta_count = 0; 621 bool is_hw_dbs_capable = false; 622 623 if (WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq)) 624 return channel_width; 625 626 if (wlan_reg_is_6ghz_chan_freq(con_ch_freq)) 627 return channel_width; 628 629 /* sta_count is to check if there is STA present on any other 630 * channel freq irrespective of concurrent channel. 631 */ 632 sta_count = policy_mgr_mode_specific_connection_count( 633 psoc, 634 PM_STA_MODE, 635 NULL); 636 scc_sta_present = policy_mgr_is_sta_present_on_freq(psoc, 637 &sta_vdev_id, 638 con_ch_freq, 639 &sta_ch_width); 640 if (scc_sta_present) { 641 sta_chan_width = policy_mgr_get_ch_width(sta_ch_width); 642 sap_debug("sta_chan_width:%d, channel_width:%d", 643 sta_chan_width, channel_width); 644 if (wlan_reg_is_dfs_for_freq(pdev, con_ch_freq) || 645 sta_chan_width == CH_WIDTH_160MHZ) 646 is_con_chan_dfs = true; 647 else if (WLAN_REG_IS_5GHZ_CH_FREQ(con_ch_freq) && 648 wlan_reg_is_freq_indoor(pdev, con_ch_freq)) 649 is_con_sta_indoor = true; 650 } 651 652 policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl); 653 is_hw_dbs_capable = policy_mgr_is_hw_dbs_capable(psoc); 654 sap_debug("sta_sap_scc_on_dfs_chnl:%d, is_hw_dbs_capable:%d, sta_count:%d, scc_sta_present:%d", 655 sta_sap_scc_on_dfs_chnl, 656 is_hw_dbs_capable, sta_count, scc_sta_present); 657 658 if (!is_hw_dbs_capable) 659 goto dfs_master_mode_check; 660 661 /* 662 * In indoor concurrency cases, limit the channel width with the STA 663 * interface bandwidth. Since, only the bonded channels are active 664 * channels. 665 */ 666 if (is_con_sta_indoor) { 667 channel_width = QDF_MIN(sta_chan_width, channel_width); 668 sap_debug("STA + SAP on indoor channels"); 669 return channel_width; 670 } else if (is_con_chan_dfs) { 671 channel_width = QDF_MIN(sta_chan_width, channel_width); 672 sap_debug("STA + SAP on dfs channels"); 673 goto dfs_master_mode_check; 674 } else { 675 /* Handle "DBS + active channel" concurrency/standalone SAP */ 676 sap_debug("STA + SAP/GO or standalone SAP on active channel"); 677 if (scc_sta_present) 678 return QDF_MAX(sta_chan_width, CH_WIDTH_80MHZ); 679 else if (sta_count) 680 return QDF_MIN(channel_width, CH_WIDTH_80MHZ); 681 return channel_width; 682 } 683 684 dfs_master_mode_check: 685 /* Handle "DBS/non-DBS + dfs channels" concurrency */ 686 if (sta_sap_scc_on_dfs_chnl == PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) { 687 if (scc_sta_present) { 688 sap_debug("STA+SAP/GO: limit the SAP channel width"); 689 return QDF_MIN(sta_chan_width, channel_width); 690 } 691 692 sap_debug("Standalone SAP/GO: set BW coming in start req"); 693 return channel_width; 694 } else if (sta_sap_scc_on_dfs_chnl == 695 PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) { 696 if (scc_sta_present) { 697 sap_debug("STA present: Limit the SAP channel width"); 698 channel_width = QDF_MIN(sta_chan_width, channel_width); 699 return channel_width; 700 } 701 /* 702 * sta_sap_scc_on_dfs_chnl = 1, DFS master is disabled. 703 * If STA not present (SAP single), the SAP (160Mhz) is 704 * not allowed on DFS, so limit SAP to 80Mhz. 705 */ 706 sap_debug("Limit Standalone SAP/GO to 80Mhz"); 707 return QDF_MIN(channel_width, CH_WIDTH_80MHZ); 708 } 709 710 /* 711 * sta_sap_scc_on_dfs_chnl = 0, not allow STA+SAP SCC on DFS. 712 * Limit SAP to 80Mhz if STA present. 713 */ 714 if (sta_count) { 715 sap_debug("STA present, Limit SAP/GO to 80Mhz"); 716 return QDF_MIN(channel_width, CH_WIDTH_80MHZ); 717 } 718 719 sap_debug("Single SAP/GO: set BW coming in SAP/GO start req"); 720 return channel_width; 721 722 } 723 724 uint32_t wlan_sap_get_vht_ch_width(struct sap_context *sap_ctx) 725 { 726 if (!sap_ctx) { 727 sap_err("Invalid SAP pointer"); 728 return 0; 729 } 730 731 return sap_ctx->ch_params.ch_width; 732 } 733 734 bool wlan_sap_get_ch_params(struct sap_context *sap_ctx, 735 struct ch_params *ch_params) 736 { 737 if (!sap_ctx) { 738 sap_err("Invalid SAP pointer"); 739 return false; 740 } 741 742 *ch_params = sap_ctx->ch_params; 743 return true; 744 } 745 746 /** 747 * wlan_sap_validate_channel_switch() - validate target channel switch w.r.t 748 * concurreny rules set to avoid channel interference. 749 * @mac_handle: Opaque handle to the global MAC context 750 * @sap_ch_freq: channel to switch 751 * @sap_context: sap session context 752 * 753 * Return: true if there is no channel interference else return false 754 */ 755 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 756 static bool wlan_sap_validate_channel_switch(mac_handle_t mac_handle, 757 uint32_t sap_ch_freq, 758 struct sap_context *sap_context) 759 { 760 return sme_validate_sap_channel_switch( 761 mac_handle, 762 sap_ch_freq, 763 sap_context->phyMode, 764 sap_context->cc_switch_mode, 765 sap_context->sessionId); 766 } 767 #else 768 static bool wlan_sap_validate_channel_switch(mac_handle_t mac_handle, 769 uint32_t sap_ch_freq, 770 struct sap_context *sap_context) 771 { 772 return true; 773 } 774 #endif 775 776 void wlan_sap_set_sap_ctx_acs_cfg(struct sap_context *sap_ctx, 777 struct sap_config *sap_config) 778 { 779 if (!sap_ctx) { 780 sap_err("Invalid SAP pointer"); 781 return; 782 } 783 784 sap_ctx->acs_cfg = &sap_config->acs_cfg; 785 } 786 787 QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, 788 sap_event_cb sap_event_cb, 789 struct sap_config *config, void *user_context) 790 { 791 struct sap_sm_event sap_event; /* State machine event */ 792 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 793 uint32_t auto_channel_select_weight = 794 cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT); 795 int reduced_beacon_interval; 796 struct mac_context *pmac = NULL; 797 int sap_chanswitch_beacon_cnt; 798 bool sap_chanswitch_mode; 799 800 if (!sap_ctx) { 801 sap_info("Invalid SAP context"); 802 return QDF_STATUS_E_FAULT; 803 } 804 805 pmac = sap_get_mac_context(); 806 if (!pmac) { 807 sap_err("Invalid sap MAC context"); 808 qdf_status = QDF_STATUS_E_INVAL; 809 goto fail; 810 } 811 812 sap_ctx->fsm_state = SAP_INIT; 813 sap_debug("sap_fsm: vdev %d: => SAP_INIT", sap_ctx->vdev_id); 814 815 qdf_status = wlan_set_vdev_crypto_prarams_from_ie( 816 sap_ctx->vdev, 817 config->RSNWPAReqIE, 818 config->RSNWPAReqIELength); 819 if (QDF_IS_STATUS_ERROR(qdf_status)) 820 sap_debug("Failed to set crypto params from IE"); 821 822 /* Channel selection is auto or configured */ 823 sap_ctx->chan_freq = config->chan_freq; 824 sap_ctx->dfs_mode = config->acs_dfs_mode; 825 sap_ctx->ch_params = config->ch_params; 826 sap_ctx->ch_width_orig = config->ch_width_orig; 827 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 828 sap_ctx->cc_switch_mode = config->cc_switch_mode; 829 #endif 830 831 qdf_status = ucfg_mlme_get_auto_channel_weight( 832 pmac->psoc, 833 &auto_channel_select_weight); 834 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 835 sap_err("get_auto_channel_weight failed"); 836 837 sap_ctx->auto_channel_select_weight = auto_channel_select_weight; 838 839 sap_ctx->user_context = user_context; 840 sap_ctx->enableOverLapCh = config->enOverLapCh; 841 sap_ctx->acs_cfg = &config->acs_cfg; 842 sap_ctx->sec_ch_freq = config->sec_ch_freq; 843 sap_ctx->dfs_cac_offload = config->dfs_cac_offload; 844 sap_ctx->isCacStartNotified = false; 845 sap_ctx->isCacEndNotified = false; 846 sap_ctx->is_chan_change_inprogress = false; 847 sap_ctx->disabled_mcs13 = false; 848 sap_ctx->phyMode = config->SapHw_mode; 849 sap_ctx->csa_reason = CSA_REASON_UNKNOWN; 850 sap_ctx->require_h2e = config->require_h2e; 851 qdf_mem_copy(sap_ctx->bssid.bytes, config->self_macaddr.bytes, 852 QDF_MAC_ADDR_SIZE); 853 qdf_mem_copy(sap_ctx->self_mac_addr, 854 config->self_macaddr.bytes, QDF_MAC_ADDR_SIZE); 855 /* 856 * Set the DFS Test Mode setting 857 * Set beacon channel count before channel switch 858 */ 859 qdf_status = ucfg_mlme_get_sap_chn_switch_bcn_count( 860 pmac->psoc, 861 &sap_chanswitch_beacon_cnt); 862 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 863 sap_err("ucfg_mlme_get_sap_chn_switch_bcn_count fail, set def"); 864 865 pmac->sap.SapDfsInfo.sap_ch_switch_beacon_cnt = 866 sap_chanswitch_beacon_cnt; 867 pmac->sap.SapDfsInfo.sap_ch_switch_mode = 868 sap_chanswitch_beacon_cnt; 869 870 qdf_status = ucfg_mlme_get_sap_channel_switch_mode( 871 pmac->psoc, 872 &sap_chanswitch_mode); 873 if (QDF_IS_STATUS_ERROR(qdf_status)) 874 sap_err("ucfg_mlme_get_sap_channel_switch_mode, set def"); 875 876 pmac->sap.SapDfsInfo.sap_ch_switch_mode = sap_chanswitch_mode; 877 pmac->sap.sapCtxList[sap_ctx->sessionId].sap_context = sap_ctx; 878 pmac->sap.sapCtxList[sap_ctx->sessionId].sapPersona = 879 config->persona; 880 881 qdf_status = ucfg_mlme_get_sap_reduces_beacon_interval( 882 pmac->psoc, 883 &reduced_beacon_interval); 884 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 885 sap_err("ucfg_mlme_get_sap_reduces_beacon_interval fail"); 886 887 pmac->sap.SapDfsInfo.reduced_beacon_interval = 888 reduced_beacon_interval; 889 sap_debug("SAP: auth ch select weight:%d chswitch bcn cnt:%d chswitch mode:%d reduced bcn intv:%d", 890 sap_ctx->auto_channel_select_weight, 891 sap_chanswitch_beacon_cnt, 892 pmac->sap.SapDfsInfo.sap_ch_switch_mode, 893 pmac->sap.SapDfsInfo.reduced_beacon_interval); 894 895 /* Copy MAC filtering settings to sap context */ 896 sap_ctx->eSapMacAddrAclMode = config->SapMacaddr_acl; 897 qdf_mem_copy(sap_ctx->acceptMacList, config->accept_mac, 898 sizeof(config->accept_mac)); 899 sap_ctx->nAcceptMac = config->num_accept_mac; 900 sap_sort_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac); 901 qdf_mem_copy(sap_ctx->denyMacList, config->deny_mac, 902 sizeof(config->deny_mac)); 903 sap_ctx->nDenyMac = config->num_deny_mac; 904 sap_sort_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac); 905 sap_ctx->beacon_tx_rate = config->beacon_tx_rate; 906 907 /* Fill in the event structure for FSM */ 908 sap_event.event = eSAP_HDD_START_INFRA_BSS; 909 sap_event.params = 0; /* pSapPhysLinkCreate */ 910 911 /* Store the HDD callback in SAP context */ 912 sap_ctx->sap_event_cb = sap_event_cb; 913 914 sap_ctx->sap_bss_cfg.vdev_id = sap_ctx->sessionId; 915 sap_build_start_bss_config(&sap_ctx->sap_bss_cfg, config); 916 /* Handle event */ 917 qdf_status = sap_fsm(sap_ctx, &sap_event); 918 fail: 919 if (QDF_IS_STATUS_ERROR(qdf_status)) 920 qdf_mem_zero(&sap_ctx->sap_bss_cfg, 921 sizeof(sap_ctx->sap_bss_cfg)); 922 return qdf_status; 923 } /* wlansap_start_bss */ 924 925 QDF_STATUS wlansap_set_mac_acl(struct sap_context *sap_ctx, 926 struct sap_config *config) 927 { 928 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 929 930 sap_debug("wlansap_set_mac_acl"); 931 932 if (!sap_ctx) { 933 sap_err("Invalid SAP pointer"); 934 return QDF_STATUS_E_FAULT; 935 } 936 /* Copy MAC filtering settings to sap context */ 937 sap_ctx->eSapMacAddrAclMode = config->SapMacaddr_acl; 938 939 if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) { 940 qdf_mem_copy(sap_ctx->acceptMacList, 941 config->accept_mac, 942 sizeof(config->accept_mac)); 943 sap_ctx->nAcceptMac = config->num_accept_mac; 944 sap_sort_mac_list(sap_ctx->acceptMacList, 945 sap_ctx->nAcceptMac); 946 } else if (eSAP_ACCEPT_UNLESS_DENIED == sap_ctx->eSapMacAddrAclMode) { 947 qdf_mem_copy(sap_ctx->denyMacList, config->deny_mac, 948 sizeof(config->deny_mac)); 949 sap_ctx->nDenyMac = config->num_deny_mac; 950 sap_sort_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac); 951 } 952 953 return qdf_status; 954 } /* wlansap_set_mac_acl */ 955 956 QDF_STATUS wlansap_stop_bss(struct sap_context *sap_ctx) 957 { 958 struct sap_sm_event sap_event; /* State machine event */ 959 QDF_STATUS qdf_status; 960 961 if (!sap_ctx) { 962 sap_err("Invalid SAP pointer"); 963 return QDF_STATUS_E_FAULT; 964 } 965 966 /* Fill in the event structure for FSM */ 967 sap_event.event = eSAP_HDD_STOP_INFRA_BSS; 968 sap_event.params = 0; 969 970 /* Handle event */ 971 qdf_status = sap_fsm(sap_ctx, &sap_event); 972 973 return qdf_status; 974 } 975 976 /* This routine will set the mode of operation for ACL dynamically*/ 977 QDF_STATUS wlansap_set_acl_mode(struct sap_context *sap_ctx, 978 eSapMacAddrACL mode) 979 { 980 if (!sap_ctx) { 981 sap_err("Invalid SAP pointer"); 982 return QDF_STATUS_E_FAULT; 983 } 984 985 sap_ctx->eSapMacAddrAclMode = mode; 986 return QDF_STATUS_SUCCESS; 987 } 988 989 QDF_STATUS wlansap_get_acl_mode(struct sap_context *sap_ctx, 990 eSapMacAddrACL *mode) 991 { 992 if (!sap_ctx) { 993 sap_err("Invalid SAP pointer"); 994 return QDF_STATUS_E_FAULT; 995 } 996 997 *mode = sap_ctx->eSapMacAddrAclMode; 998 return QDF_STATUS_SUCCESS; 999 } 1000 1001 QDF_STATUS wlansap_get_acl_accept_list(struct sap_context *sap_ctx, 1002 struct qdf_mac_addr *pAcceptList, 1003 uint16_t *nAcceptList) 1004 { 1005 if (!sap_ctx) { 1006 sap_err("Invalid SAP pointer"); 1007 return QDF_STATUS_E_FAULT; 1008 } 1009 1010 memcpy(pAcceptList, sap_ctx->acceptMacList, 1011 (sap_ctx->nAcceptMac * QDF_MAC_ADDR_SIZE)); 1012 *nAcceptList = sap_ctx->nAcceptMac; 1013 return QDF_STATUS_SUCCESS; 1014 } 1015 1016 QDF_STATUS wlansap_get_acl_deny_list(struct sap_context *sap_ctx, 1017 struct qdf_mac_addr *pDenyList, 1018 uint16_t *nDenyList) 1019 { 1020 if (!sap_ctx) { 1021 sap_err("Invalid SAP pointer from p_cds_gctx"); 1022 return QDF_STATUS_E_FAULT; 1023 } 1024 1025 memcpy(pDenyList, sap_ctx->denyMacList, 1026 (sap_ctx->nDenyMac * QDF_MAC_ADDR_SIZE)); 1027 *nDenyList = sap_ctx->nDenyMac; 1028 return QDF_STATUS_SUCCESS; 1029 } 1030 1031 QDF_STATUS wlansap_clear_acl(struct sap_context *sap_ctx) 1032 { 1033 uint16_t i; 1034 1035 if (!sap_ctx) { 1036 return QDF_STATUS_E_RESOURCES; 1037 } 1038 1039 for (i = 0; i < sap_ctx->nDenyMac; i++) { 1040 qdf_mem_zero((sap_ctx->denyMacList + i)->bytes, 1041 QDF_MAC_ADDR_SIZE); 1042 } 1043 1044 sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac); 1045 sap_ctx->nDenyMac = 0; 1046 1047 for (i = 0; i < sap_ctx->nAcceptMac; i++) { 1048 qdf_mem_zero((sap_ctx->acceptMacList + i)->bytes, 1049 QDF_MAC_ADDR_SIZE); 1050 } 1051 1052 sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac); 1053 sap_ctx->nAcceptMac = 0; 1054 1055 return QDF_STATUS_SUCCESS; 1056 } 1057 1058 QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, 1059 uint8_t *peer_sta_mac, 1060 eSapACLType list_type, eSapACLCmdType cmd) 1061 { 1062 bool sta_allow_list = false, sta_deny_list = false; 1063 uint16_t staWLIndex, staBLIndex; 1064 1065 if (!sap_ctx) { 1066 sap_err("Invalid SAP Context"); 1067 return QDF_STATUS_E_FAULT; 1068 } 1069 if (qdf_mem_cmp(sap_ctx->bssid.bytes, peer_sta_mac, 1070 QDF_MAC_ADDR_SIZE) == 0) { 1071 sap_err("requested peer mac is "QDF_MAC_ADDR_FMT 1072 "our own SAP BSSID. Do not denylist or allowlist this BSSID", 1073 QDF_MAC_ADDR_REF(peer_sta_mac)); 1074 return QDF_STATUS_E_FAULT; 1075 } 1076 sap_debug("Modify ACL entered\n" "Before modification of ACL\n" 1077 "size of accept and deny lists %d %d", sap_ctx->nAcceptMac, 1078 sap_ctx->nDenyMac); 1079 sap_debug("*** ALLOW LIST ***"); 1080 sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac); 1081 sap_debug("*** DENY LIST ***"); 1082 sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac); 1083 1084 /* the expectation is a mac addr will not be in both the lists 1085 * at the same time. It is the responsibility of userspace to 1086 * ensure this 1087 */ 1088 sta_allow_list = 1089 sap_search_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac, 1090 peer_sta_mac, &staWLIndex); 1091 sta_deny_list = 1092 sap_search_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac, 1093 peer_sta_mac, &staBLIndex); 1094 1095 if (sta_allow_list && sta_deny_list) { 1096 sap_err("Peer mac " QDF_MAC_ADDR_FMT 1097 " found in allow and deny lists." 1098 "Initial lists passed incorrect. Cannot execute this command.", 1099 QDF_MAC_ADDR_REF(peer_sta_mac)); 1100 return QDF_STATUS_E_FAILURE; 1101 1102 } 1103 sap_debug("cmd %d", cmd); 1104 1105 switch (list_type) { 1106 case SAP_ALLOW_LIST: 1107 if (cmd == ADD_STA_TO_ACL || cmd == ADD_STA_TO_ACL_NO_DEAUTH) { 1108 /* error check */ 1109 /* if list is already at max, return failure */ 1110 if (sap_ctx->nAcceptMac == MAX_ACL_MAC_ADDRESS) { 1111 sap_err("Allow list is already maxed out. Cannot accept " 1112 QDF_MAC_ADDR_FMT, 1113 QDF_MAC_ADDR_REF(peer_sta_mac)); 1114 return QDF_STATUS_E_FAILURE; 1115 } 1116 if (sta_allow_list) { 1117 /* 1118 * Do nothing if already present in allow 1119 * list. Just print a warning 1120 */ 1121 sap_warn("MAC address already present in allow list " 1122 QDF_MAC_ADDR_FMT, 1123 QDF_MAC_ADDR_REF(peer_sta_mac)); 1124 return QDF_STATUS_SUCCESS; 1125 } 1126 if (sta_deny_list) { 1127 /* 1128 * remove it from deny list before adding 1129 * to the allow list 1130 */ 1131 sap_warn("STA present in deny list so first remove from it"); 1132 sap_remove_mac_from_acl(sap_ctx->denyMacList, 1133 &sap_ctx->nDenyMac, 1134 staBLIndex); 1135 } 1136 sap_debug("... Now add to the allow list"); 1137 sap_add_mac_to_acl(sap_ctx->acceptMacList, 1138 &sap_ctx->nAcceptMac, 1139 peer_sta_mac); 1140 sap_debug("size of accept and deny lists %d %d", 1141 sap_ctx->nAcceptMac, 1142 sap_ctx->nDenyMac); 1143 } else if (cmd == DELETE_STA_FROM_ACL || 1144 cmd == DELETE_STA_FROM_ACL_NO_DEAUTH) { 1145 if (sta_allow_list) { 1146 1147 struct csr_del_sta_params delStaParams; 1148 1149 sap_info("Delete from allow list"); 1150 sap_remove_mac_from_acl(sap_ctx->acceptMacList, 1151 &sap_ctx->nAcceptMac, 1152 staWLIndex); 1153 /* If a client is deleted from allow list and */ 1154 /* it is connected, send deauth 1155 */ 1156 if (cmd == DELETE_STA_FROM_ACL) { 1157 wlansap_populate_del_sta_params( 1158 peer_sta_mac, 1159 eCsrForcedDeauthSta, 1160 SIR_MAC_MGMT_DEAUTH, 1161 &delStaParams); 1162 wlansap_deauth_sta(sap_ctx, 1163 &delStaParams); 1164 sap_debug("size of accept and deny lists %d %d", 1165 sap_ctx->nAcceptMac, 1166 sap_ctx->nDenyMac); 1167 } 1168 } else { 1169 sap_warn("MAC address to be deleted is not present in the allow list " 1170 QDF_MAC_ADDR_FMT, 1171 QDF_MAC_ADDR_REF(peer_sta_mac)); 1172 return QDF_STATUS_E_FAILURE; 1173 } 1174 } else { 1175 sap_err("Invalid cmd type passed"); 1176 return QDF_STATUS_E_FAILURE; 1177 } 1178 break; 1179 1180 case SAP_DENY_LIST: 1181 1182 if (cmd == ADD_STA_TO_ACL || cmd == ADD_STA_TO_ACL_NO_DEAUTH) { 1183 struct csr_del_sta_params delStaParams; 1184 /* error check */ 1185 /* if list is already at max, return failure */ 1186 if (sap_ctx->nDenyMac == MAX_ACL_MAC_ADDRESS) { 1187 sap_err("Deny list is already maxed out. Cannot accept " 1188 QDF_MAC_ADDR_FMT, 1189 QDF_MAC_ADDR_REF(peer_sta_mac)); 1190 return QDF_STATUS_E_FAILURE; 1191 } 1192 if (sta_deny_list) { 1193 /* 1194 * Do nothing if already present in 1195 * allow list 1196 */ 1197 sap_warn("MAC address already present in deny list " 1198 QDF_MAC_ADDR_FMT, 1199 QDF_MAC_ADDR_REF(peer_sta_mac)); 1200 return QDF_STATUS_SUCCESS; 1201 } 1202 if (sta_allow_list) { 1203 /* 1204 * remove it from allow list before adding to 1205 * the deny list 1206 */ 1207 sap_warn("Present in allow list so first remove from it"); 1208 sap_remove_mac_from_acl(sap_ctx->acceptMacList, 1209 &sap_ctx->nAcceptMac, 1210 staWLIndex); 1211 } 1212 /* If we are adding a client to the deny list; */ 1213 /* if its connected, send deauth 1214 */ 1215 if (cmd == ADD_STA_TO_ACL) { 1216 wlansap_populate_del_sta_params( 1217 peer_sta_mac, 1218 eCsrForcedDeauthSta, 1219 SIR_MAC_MGMT_DEAUTH, 1220 &delStaParams); 1221 wlansap_deauth_sta(sap_ctx, &delStaParams); 1222 } 1223 sap_info("... Now add to deny list"); 1224 sap_add_mac_to_acl(sap_ctx->denyMacList, 1225 &sap_ctx->nDenyMac, peer_sta_mac); 1226 sap_debug("size of accept and deny lists %d %d", 1227 sap_ctx->nAcceptMac, 1228 sap_ctx->nDenyMac); 1229 } else if (cmd == DELETE_STA_FROM_ACL || 1230 cmd == DELETE_STA_FROM_ACL_NO_DEAUTH) { 1231 if (sta_deny_list) { 1232 sap_info("Delete from deny list"); 1233 sap_remove_mac_from_acl(sap_ctx->denyMacList, 1234 &sap_ctx->nDenyMac, 1235 staBLIndex); 1236 sap_debug("no accept and deny mac %d %d", 1237 sap_ctx->nAcceptMac, 1238 sap_ctx->nDenyMac); 1239 } else { 1240 sap_warn("MAC address to be deleted is not present in the deny list " 1241 QDF_MAC_ADDR_FMT, 1242 QDF_MAC_ADDR_REF(peer_sta_mac)); 1243 return QDF_STATUS_E_FAILURE; 1244 } 1245 } else { 1246 sap_err("Invalid cmd type passed"); 1247 return QDF_STATUS_E_FAILURE; 1248 } 1249 break; 1250 1251 default: 1252 { 1253 sap_err("Invalid list type passed %d", list_type); 1254 return QDF_STATUS_E_FAILURE; 1255 } 1256 } 1257 sap_debug("After modification of ACL"); 1258 sap_debug("*** ALLOW LIST ***"); 1259 sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac); 1260 sap_debug("*** DENY LIST ***"); 1261 sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac); 1262 return QDF_STATUS_SUCCESS; 1263 } 1264 1265 QDF_STATUS wlansap_disassoc_sta(struct sap_context *sap_ctx, 1266 struct csr_del_sta_params *params) 1267 { 1268 struct mac_context *mac; 1269 1270 if (!sap_ctx) { 1271 sap_err("Invalid SAP pointer"); 1272 return QDF_STATUS_E_FAULT; 1273 } 1274 1275 mac = sap_get_mac_context(); 1276 if (!mac) { 1277 sap_err("Invalid MAC context"); 1278 return QDF_STATUS_E_FAULT; 1279 } 1280 1281 return sme_roam_disconnect_sta(MAC_HANDLE(mac), sap_ctx->sessionId, 1282 params); 1283 } 1284 1285 QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx, 1286 struct csr_del_sta_params *params) 1287 { 1288 struct mac_context *mac; 1289 1290 if (!sap_ctx) { 1291 sap_err("Invalid SAP pointer"); 1292 return QDF_STATUS_E_FAULT; 1293 } 1294 1295 mac = sap_get_mac_context(); 1296 if (!mac) { 1297 sap_err("Invalid MAC context"); 1298 return QDF_STATUS_E_FAULT; 1299 } 1300 1301 return sme_roam_deauth_sta(MAC_HANDLE(mac), sap_ctx->sessionId, 1302 params); 1303 } 1304 1305 #if defined(WLAN_FEATURE_11BE) 1306 static enum phy_ch_width 1307 wlansap_get_target_eht_phy_ch_width(void) 1308 { 1309 uint32_t max_fw_bw = sme_get_eht_ch_width(); 1310 1311 if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ) 1312 return CH_WIDTH_320MHZ; 1313 else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1314 return CH_WIDTH_160MHZ; 1315 else 1316 return CH_WIDTH_80MHZ; 1317 } 1318 #else /* !WLAN_FEATURE_11BE */ 1319 static enum phy_ch_width 1320 wlansap_get_target_eht_phy_ch_width(void) 1321 { 1322 return CH_WIDTH_20MHZ; 1323 } 1324 #endif /* WLAN_FEATURE_11BE */ 1325 1326 static enum phy_ch_width 1327 wlansap_5g_original_bw_validate( 1328 struct sap_context *sap_context, 1329 uint32_t chan_freq, 1330 enum phy_ch_width ch_width) 1331 { 1332 if (sap_context->csa_reason != CSA_REASON_USER_INITIATED && 1333 WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) && 1334 ch_width >= CH_WIDTH_160MHZ && 1335 sap_context->ch_width_orig < CH_WIDTH_160MHZ) 1336 ch_width = CH_WIDTH_80MHZ; 1337 1338 return ch_width; 1339 } 1340 1341 /** 1342 * wlansap_2g_original_bw_validate() - validate bw for sap on 2.4 GHz 1343 * @sap_context: sap context 1344 * @chan_freq: channel frequency 1345 * @ch_width: band width 1346 * @sec_ch_freq: secondary channel frequency 1347 * 1348 * If initial SAP starts on 2.4 GHz HT40/HT20 mode, driver honors it. 1349 * 1350 * Return: new bandwidth 1351 */ 1352 static enum phy_ch_width 1353 wlansap_2g_original_bw_validate(struct sap_context *sap_context, 1354 uint32_t chan_freq, 1355 enum phy_ch_width ch_width, 1356 qdf_freq_t *sec_ch_freq) 1357 { 1358 if (sap_context->csa_reason == CSA_REASON_UNKNOWN && 1359 WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq) && 1360 sap_context->ch_width_orig == CH_WIDTH_40MHZ) { 1361 ch_width = CH_WIDTH_40MHZ; 1362 if (sap_context->ch_params.sec_ch_offset == LOW_PRIMARY_CH) 1363 *sec_ch_freq = chan_freq + 20; 1364 else if (sap_context->ch_params.sec_ch_offset == 1365 HIGH_PRIMARY_CH) 1366 *sec_ch_freq = chan_freq - 20; 1367 else 1368 *sec_ch_freq = 0; 1369 } 1370 1371 return ch_width; 1372 } 1373 1374 enum phy_ch_width 1375 wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context, 1376 uint32_t chan_freq, 1377 struct ch_params *tgt_ch_params) 1378 { 1379 enum phy_ch_width ch_width, concurrent_bw = 0; 1380 struct mac_context *mac; 1381 struct ch_params ch_params = {0}; 1382 uint32_t channel_bonding_mode = 0; 1383 qdf_freq_t sec_ch_freq = 0; 1384 1385 mac = sap_get_mac_context(); 1386 if (!mac) { 1387 sap_err("Invalid MAC context"); 1388 return CH_WIDTH_20MHZ; 1389 } 1390 1391 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { 1392 /* 1393 * currently OBSS scan is done in hostapd, so to avoid 1394 * SAP coming up in HT40 on channel switch we are 1395 * disabling channel bonding in 2.4Ghz. 1396 */ 1397 ch_width = wlansap_2g_original_bw_validate( 1398 sap_context, chan_freq, CH_WIDTH_20MHZ, 1399 &sec_ch_freq); 1400 } else { 1401 wlan_mlme_get_channel_bonding_5ghz(mac->psoc, 1402 &channel_bonding_mode); 1403 if (policy_mgr_is_vdev_ll_lt_sap(mac->psoc, 1404 sap_context->vdev_id) || 1405 (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) && 1406 !channel_bonding_mode)) 1407 ch_width = CH_WIDTH_20MHZ; 1408 else 1409 ch_width = wlansap_get_max_bw_by_phymode(sap_context); 1410 1411 ch_width = wlansap_5g_original_bw_validate( 1412 sap_context, chan_freq, ch_width); 1413 concurrent_bw = wlan_sap_get_concurrent_bw( 1414 mac->pdev, mac->psoc, chan_freq, 1415 ch_width); 1416 ch_width = QDF_MIN(ch_width, concurrent_bw); 1417 if (tgt_ch_params) 1418 ch_width = QDF_MIN(ch_width, tgt_ch_params->ch_width); 1419 } 1420 ch_params.ch_width = ch_width; 1421 if (sap_phymode_is_eht(sap_context->phyMode)) 1422 wlan_reg_set_create_punc_bitmap(&ch_params, true); 1423 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, chan_freq, 1424 sec_ch_freq, &ch_params, 1425 REG_CURRENT_PWR_MODE); 1426 ch_width = ch_params.ch_width; 1427 if (tgt_ch_params) 1428 *tgt_ch_params = ch_params; 1429 sap_nofl_debug("csa freq %d bw %d (phymode %d con bw %d tgt bw %d orig %d reason %d) channel bonding 5g %d", 1430 chan_freq, ch_width, 1431 sap_context->phyMode, 1432 concurrent_bw, 1433 tgt_ch_params ? tgt_ch_params->ch_width : CH_WIDTH_MAX, 1434 sap_context->ch_width_orig, 1435 sap_context->csa_reason, 1436 channel_bonding_mode); 1437 1438 return ch_width; 1439 } 1440 1441 /** 1442 * sap_start_csa_restart() - send csa start event 1443 * @mac: mac ctx 1444 * @sap_ctx: SAP context 1445 * 1446 * Return: QDF_STATUS 1447 */ 1448 static inline void sap_start_csa_restart(struct mac_context *mac, 1449 struct sap_context *sap_ctx) 1450 { 1451 sme_csa_restart(mac, sap_ctx->sessionId); 1452 } 1453 1454 /** 1455 * sap_get_csa_reason_str() - Get csa reason in string 1456 * @reason: sap reason enum value 1457 * 1458 * Return: string reason 1459 */ 1460 const char *sap_get_csa_reason_str(enum sap_csa_reason_code reason) 1461 { 1462 switch (reason) { 1463 case CSA_REASON_UNKNOWN: 1464 return "UNKNOWN"; 1465 case CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS: 1466 return "STA_CONNECT_DFS_TO_NON_DFS"; 1467 case CSA_REASON_USER_INITIATED: 1468 return "USER_INITIATED"; 1469 case CSA_REASON_PEER_ACTION_FRAME: 1470 return "PEER_ACTION_FRAME"; 1471 case CSA_REASON_PRE_CAC_SUCCESS: 1472 return "PRE_CAC_SUCCESS"; 1473 case CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL: 1474 return "CONCURRENT_STA_CHANGED_CHANNEL"; 1475 case CSA_REASON_UNSAFE_CHANNEL: 1476 return "UNSAFE_CHANNEL"; 1477 case CSA_REASON_LTE_COEX: 1478 return "LTE_COEX"; 1479 case CSA_REASON_CONCURRENT_NAN_EVENT: 1480 return "CONCURRENT_NAN_EVENT"; 1481 case CSA_REASON_BAND_RESTRICTED: 1482 return "BAND_RESTRICTED"; 1483 case CSA_REASON_DCS: 1484 return "DCS"; 1485 case CSA_REASON_CHAN_DISABLED: 1486 return "DISABLED"; 1487 case CSA_REASON_CHAN_PASSIVE: 1488 return "PASSIVE"; 1489 case CSA_REASON_GO_BSS_STARTED: 1490 return "GO_BSS_STARTED"; 1491 case CSA_REASON_SAP_ACS: 1492 return "CSA_REASON_SAP_ACS"; 1493 case CSA_REASON_SAP_FIX_CH_CONC_WITH_GO: 1494 return "SAP_FIX_CH_CONC_WITH_GO"; 1495 default: 1496 return "UNKNOWN"; 1497 } 1498 } 1499 1500 /** 1501 * wlansap_set_chan_params_for_csa() - Update sap channel parameters 1502 * for channel switch 1503 * @mac: mac ctx 1504 * @sap_ctx: sap context 1505 * @target_chan_freq: target channel frequency in MHz 1506 * @target_bw: target bandwidth 1507 * 1508 * Return: QDF_STATUS_SUCCESS for success. 1509 */ 1510 static QDF_STATUS 1511 wlansap_set_chan_params_for_csa(struct mac_context *mac, 1512 struct sap_context *sap_ctx, 1513 uint32_t target_chan_freq, 1514 enum phy_ch_width target_bw) 1515 { 1516 struct ch_params tmp_ch_params = {0}; 1517 1518 tmp_ch_params.ch_width = target_bw; 1519 mac->sap.SapDfsInfo.new_chanWidth = 1520 wlansap_get_csa_chanwidth_from_phymode(sap_ctx, 1521 target_chan_freq, 1522 &tmp_ch_params); 1523 /* 1524 * Copy the requested target channel 1525 * to sap context. 1526 */ 1527 mac->sap.SapDfsInfo.target_chan_freq = target_chan_freq; 1528 mac->sap.SapDfsInfo.new_ch_params.ch_width = 1529 mac->sap.SapDfsInfo.new_chanWidth; 1530 1531 /* By this time, the best bandwidth is calculated for 1532 * the given target channel. Now, if there was a 1533 * request from user to move to a selected bandwidth, 1534 * we can see if it can be honored. 1535 * 1536 * Ex1: BW80 was selected for the target channel and 1537 * user wants BW40, it can be allowed 1538 * Ex2: BW40 was selected for the target channel and 1539 * user wants BW80, it cannot be allowed for the given 1540 * target channel. 1541 * 1542 * So, the MIN of the selected channel bandwidth and 1543 * user input is used for the bandwidth 1544 */ 1545 if (target_bw != CH_WIDTH_MAX) { 1546 sap_nofl_debug("SAP CSA: target bw:%d new width:%d", 1547 target_bw, 1548 mac->sap.SapDfsInfo.new_ch_params.ch_width); 1549 mac->sap.SapDfsInfo.new_ch_params.ch_width = 1550 mac->sap.SapDfsInfo.new_chanWidth = 1551 QDF_MIN(mac->sap.SapDfsInfo.new_ch_params.ch_width, 1552 target_bw); 1553 } 1554 if (sap_phymode_is_eht(sap_ctx->phyMode)) 1555 wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params, true); 1556 wlan_reg_set_channel_params_for_pwrmode( 1557 mac->pdev, target_chan_freq, 0, 1558 &mac->sap.SapDfsInfo.new_ch_params, 1559 REG_CURRENT_PWR_MODE); 1560 1561 return QDF_STATUS_SUCCESS; 1562 } 1563 1564 bool 1565 wlansap_override_csa_strict_for_sap(mac_handle_t mac_handle, 1566 struct sap_context *sap_ctx, 1567 uint32_t target_chan_freq, 1568 bool strict) 1569 { 1570 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 1571 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 1572 uint32_t con_freq; 1573 enum phy_ch_width ch_width; 1574 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 1575 1576 if (!mac_ctx || !sap_ctx->vdev || 1577 wlan_vdev_mlme_get_opmode(sap_ctx->vdev) != QDF_SAP_MODE) 1578 return strict; 1579 1580 if (sap_ctx->csa_reason != CSA_REASON_USER_INITIATED) 1581 return strict; 1582 1583 if (!policy_mgr_is_force_scc(mac_ctx->psoc)) 1584 return strict; 1585 1586 existing_vdev_id = 1587 policy_mgr_fetch_existing_con_info( 1588 mac_ctx->psoc, 1589 sap_ctx->sessionId, 1590 target_chan_freq, 1591 &existing_vdev_mode, 1592 &con_freq, &ch_width); 1593 if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX && 1594 (existing_vdev_mode == PM_STA_MODE || 1595 existing_vdev_mode == PM_P2P_CLIENT_MODE)) 1596 return strict; 1597 1598 return true; 1599 } 1600 1601 QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, 1602 uint32_t target_chan_freq, 1603 enum phy_ch_width target_bw, 1604 bool strict) 1605 { 1606 struct mac_context *mac; 1607 mac_handle_t mac_handle; 1608 bool valid; 1609 QDF_STATUS status, hw_mode_status; 1610 bool sta_sap_scc_on_dfs_chan; 1611 bool is_dfs; 1612 struct ch_params tmp_ch_params = {0}; 1613 enum channel_state state; 1614 1615 if (!sap_ctx) { 1616 sap_err("Invalid SAP pointer"); 1617 1618 return QDF_STATUS_E_FAULT; 1619 } 1620 1621 mac = sap_get_mac_context(); 1622 if (!mac) { 1623 sap_err("Invalid MAC context"); 1624 return QDF_STATUS_E_FAULT; 1625 } 1626 mac_handle = MAC_HANDLE(mac); 1627 1628 if (((sap_ctx->acs_cfg && sap_ctx->acs_cfg->acs_mode) || 1629 policy_mgr_restrict_sap_on_unsafe_chan(mac->psoc) || 1630 sap_ctx->csa_reason != CSA_REASON_USER_INITIATED) && 1631 !policy_mgr_is_sap_freq_allowed(mac->psoc, target_chan_freq)) { 1632 sap_err("%u is unsafe channel freq", target_chan_freq); 1633 return QDF_STATUS_E_FAULT; 1634 } 1635 sap_nofl_debug("SAP CSA: %d BW %d ---> %d BW %d conn on 5GHz:%d, csa_reason:%s(%d) strict %d vdev %d", 1636 sap_ctx->chan_freq, sap_ctx->ch_params.ch_width, 1637 target_chan_freq, target_bw, 1638 policy_mgr_is_any_mode_active_on_band_along_with_session( 1639 mac->psoc, sap_ctx->sessionId, POLICY_MGR_BAND_5), 1640 sap_get_csa_reason_str(sap_ctx->csa_reason), 1641 sap_ctx->csa_reason, strict, sap_ctx->sessionId); 1642 1643 state = wlan_reg_get_channel_state_for_pwrmode(mac->pdev, 1644 target_chan_freq, 1645 REG_CURRENT_PWR_MODE); 1646 if (state == CHANNEL_STATE_DISABLE || state == CHANNEL_STATE_INVALID) { 1647 sap_nofl_debug("invalid target freq %d state %d", 1648 target_chan_freq, state); 1649 return QDF_STATUS_E_INVAL; 1650 } 1651 1652 sta_sap_scc_on_dfs_chan = 1653 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc); 1654 1655 tmp_ch_params.ch_width = target_bw; 1656 wlansap_get_csa_chanwidth_from_phymode(sap_ctx, 1657 target_chan_freq, 1658 &tmp_ch_params); 1659 if (target_bw != CH_WIDTH_MAX) { 1660 tmp_ch_params.ch_width = 1661 QDF_MIN(tmp_ch_params.ch_width, target_bw); 1662 sap_nofl_debug("target ch_width %d to %d ", target_bw, 1663 tmp_ch_params.ch_width); 1664 } 1665 1666 if (sap_phymode_is_eht(sap_ctx->phyMode)) 1667 wlan_reg_set_create_punc_bitmap(&tmp_ch_params, true); 1668 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, target_chan_freq, 0, 1669 &tmp_ch_params, 1670 REG_CURRENT_PWR_MODE); 1671 if (sap_ctx->chan_freq == target_chan_freq && 1672 sap_ctx->ch_params.ch_width == tmp_ch_params.ch_width) { 1673 sap_nofl_debug("target freq and bw %d not changed", 1674 tmp_ch_params.ch_width); 1675 return QDF_STATUS_E_FAULT; 1676 } 1677 is_dfs = wlan_mlme_check_chan_param_has_dfs( 1678 mac->pdev, &tmp_ch_params, 1679 target_chan_freq); 1680 /* 1681 * Now, validate if the passed channel is valid in the 1682 * current regulatory domain. 1683 */ 1684 if (!is_dfs || 1685 (!policy_mgr_is_any_mode_active_on_band_along_with_session( 1686 mac->psoc, sap_ctx->sessionId, 1687 POLICY_MGR_BAND_5) || 1688 sta_sap_scc_on_dfs_chan || 1689 sap_ctx->csa_reason == CSA_REASON_DCS)) { 1690 /* 1691 * validate target channel switch w.r.t various concurrency 1692 * rules set. 1693 */ 1694 if (!strict) { 1695 valid = wlan_sap_validate_channel_switch(mac_handle, 1696 target_chan_freq, 1697 sap_ctx); 1698 if (!valid) { 1699 sap_err("Channel freq switch to %u is not allowed due to concurrent channel interference", 1700 target_chan_freq); 1701 return QDF_STATUS_E_FAULT; 1702 } 1703 } 1704 /* 1705 * Post a CSA IE request to SAP state machine with 1706 * target channel information and also CSA IE required 1707 * flag set in sap_ctx only, if SAP is in SAP_STARTED 1708 * state. 1709 */ 1710 if (sap_ctx->fsm_state == SAP_STARTED) { 1711 status = wlansap_set_chan_params_for_csa( 1712 mac, sap_ctx, target_chan_freq, 1713 target_bw); 1714 if (QDF_IS_STATUS_ERROR(status)) 1715 return status; 1716 1717 hw_mode_status = 1718 policy_mgr_check_and_set_hw_mode_for_channel_switch( 1719 mac->psoc, sap_ctx->sessionId, 1720 target_chan_freq, 1721 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP); 1722 1723 /* 1724 * If hw_mode_status is QDF_STATUS_E_FAILURE, mean HW 1725 * mode change was required but driver failed to set HW 1726 * mode so ignore CSA for the channel. 1727 */ 1728 if (hw_mode_status == QDF_STATUS_E_FAILURE) { 1729 sap_err("HW change required but failed to set hw mode"); 1730 return hw_mode_status; 1731 } 1732 1733 status = policy_mgr_reset_chan_switch_complete_evt( 1734 mac->psoc); 1735 if (QDF_IS_STATUS_ERROR(status)) { 1736 policy_mgr_check_n_start_opportunistic_timer( 1737 mac->psoc); 1738 return status; 1739 } 1740 1741 /* 1742 * Set the CSA IE required flag. 1743 */ 1744 mac->sap.SapDfsInfo.csaIERequired = true; 1745 1746 /* 1747 * Set the radar found status to allow the channel 1748 * change to happen same as in the case of a radar 1749 * detection. Since, this will allow SAP to be in 1750 * correct state and also resume the netif queues 1751 * that were suspended in HDD before the channel 1752 * request was issued. 1753 */ 1754 sap_ctx->sap_radar_found_status = true; 1755 sap_cac_reset_notify(mac_handle); 1756 1757 /* 1758 * If hw_mode_status is QDF_STATUS_SUCCESS mean HW mode 1759 * change was required and was successfully requested so 1760 * the channel switch will continue after HW mode change 1761 * completion. 1762 */ 1763 if (QDF_IS_STATUS_SUCCESS(hw_mode_status)) { 1764 sap_info("Channel change will continue after HW mode change"); 1765 return QDF_STATUS_SUCCESS; 1766 } 1767 /* 1768 * If hw_mode_status is QDF_STATUS_E_NOSUPPORT or 1769 * QDF_STATUS_E_ALREADY (not QDF_STATUS_E_FAILURE and 1770 * not QDF_STATUS_SUCCESS), mean DBS is not supported or 1771 * required HW mode is already set, So contunue with 1772 * CSA from here. 1773 */ 1774 sap_start_csa_restart(mac, sap_ctx); 1775 } else { 1776 sap_err("Failed to request Channel Change, since SAP is not in SAP_STARTED state"); 1777 return QDF_STATUS_E_FAULT; 1778 } 1779 1780 } else { 1781 sap_err("Channel freq = %d is not valid in the current" 1782 "regulatory domain, is_dfs %d", target_chan_freq, 1783 is_dfs); 1784 1785 return QDF_STATUS_E_FAULT; 1786 } 1787 1788 return QDF_STATUS_SUCCESS; 1789 } 1790 1791 QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx, 1792 uint32_t *len, uint8_t *buf) 1793 { 1794 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1795 uint32_t ie_len = 0; 1796 1797 if (!sap_ctx) { 1798 sap_err("Invalid SAP pointer"); 1799 return QDF_STATUS_E_FAULT; 1800 } 1801 1802 if (len) { 1803 ie_len = *len; 1804 *len = sap_ctx->nStaWPARSnReqIeLength; 1805 sap_info("WPAIE len : %x", *len); 1806 if ((buf) && (ie_len >= sap_ctx->nStaWPARSnReqIeLength)) { 1807 qdf_mem_copy(buf, 1808 sap_ctx->pStaWpaRsnReqIE, 1809 sap_ctx->nStaWPARSnReqIeLength); 1810 sap_info("WPAIE: "QDF_MAC_ADDR_FMT, 1811 QDF_MAC_ADDR_REF(buf)); 1812 qdf_status = QDF_STATUS_SUCCESS; 1813 } 1814 } 1815 return qdf_status; 1816 } 1817 1818 QDF_STATUS wlan_sap_update_next_channel(struct sap_context *sap_ctx, 1819 uint8_t channel, 1820 enum phy_ch_width chan_bw) 1821 { 1822 if (!sap_ctx) { 1823 sap_err("Invalid SAP pointer"); 1824 return QDF_STATUS_E_FAULT; 1825 } 1826 1827 sap_ctx->dfs_vendor_channel = channel; 1828 sap_ctx->dfs_vendor_chan_bw = chan_bw; 1829 1830 return QDF_STATUS_SUCCESS; 1831 } 1832 1833 void wlansap_get_sec_channel(uint8_t sec_ch_offset, 1834 uint32_t op_chan_freq, 1835 uint32_t *sec_chan_freq) 1836 { 1837 switch (sec_ch_offset) { 1838 case LOW_PRIMARY_CH: 1839 *sec_chan_freq = op_chan_freq + 20; 1840 break; 1841 case HIGH_PRIMARY_CH: 1842 *sec_chan_freq = op_chan_freq - 20; 1843 break; 1844 default: 1845 *sec_chan_freq = 0; 1846 } 1847 } 1848 1849 #ifdef WLAN_FEATURE_11BE 1850 static void 1851 wlansap_fill_channel_change_puncture(struct channel_change_req *req, 1852 struct ch_params *ch_param) 1853 { 1854 req->target_punc_bitmap = ch_param->reg_punc_bitmap; 1855 } 1856 #else 1857 static inline void 1858 wlansap_fill_channel_change_puncture(struct channel_change_req *req, 1859 struct ch_params *ch_param) 1860 { 1861 } 1862 #endif 1863 1864 /** 1865 * wlansap_fill_channel_change_request() - Fills the channel change request 1866 * @sap_ctx: sap context 1867 * @req: pointer to change channel request 1868 * 1869 * This function fills the channel change request for SAP 1870 * 1871 * Return: None 1872 */ 1873 static void 1874 wlansap_fill_channel_change_request(struct sap_context *sap_ctx, 1875 struct channel_change_req *req) 1876 { 1877 struct mac_context *mac_ctx = sap_get_mac_context(); 1878 struct bss_dot11_config dot11_cfg = {0}; 1879 uint8_t h2e; 1880 1881 dot11_cfg.vdev_id = sap_ctx->sessionId; 1882 dot11_cfg.bss_op_ch_freq = sap_ctx->chan_freq; 1883 dot11_cfg.phy_mode = sap_ctx->phyMode; 1884 dot11_cfg.privacy = sap_ctx->sap_bss_cfg.privacy; 1885 1886 /* Rates configured from start_bss will have 1887 * hostapd rates if hostapd chan rates are enabled 1888 */ 1889 qdf_mem_copy(dot11_cfg.opr_rates.rate, 1890 sap_ctx->sap_bss_cfg.operationalRateSet.rate, 1891 sap_ctx->sap_bss_cfg.operationalRateSet.numRates); 1892 dot11_cfg.opr_rates.numRates = 1893 sap_ctx->sap_bss_cfg.operationalRateSet.numRates; 1894 1895 qdf_mem_copy(dot11_cfg.ext_rates.rate, 1896 sap_ctx->sap_bss_cfg.extendedRateSet.rate, 1897 sap_ctx->sap_bss_cfg.extendedRateSet.numRates); 1898 dot11_cfg.ext_rates.numRates = 1899 sap_ctx->sap_bss_cfg.extendedRateSet.numRates; 1900 sme_get_network_params(mac_ctx, &dot11_cfg); 1901 1902 req->vdev_id = sap_ctx->sessionId; 1903 req->target_chan_freq = sap_ctx->chan_freq; 1904 req->sec_ch_offset = sap_ctx->ch_params.sec_ch_offset; 1905 req->ch_width = sap_ctx->ch_params.ch_width; 1906 req->center_freq_seg0 = sap_ctx->ch_params.center_freq_seg0; 1907 req->center_freq_seg1 = sap_ctx->ch_params.center_freq_seg1; 1908 wlansap_fill_channel_change_puncture(req, &sap_ctx->ch_params); 1909 1910 req->dot11mode = dot11_cfg.dot11_mode; 1911 req->nw_type = dot11_cfg.nw_type; 1912 1913 sap_get_cac_dur_dfs_region(sap_ctx, 1914 &req->cac_duration_ms, 1915 &req->dfs_regdomain, 1916 sap_ctx->chan_freq, 1917 &sap_ctx->ch_params); 1918 mlme_set_cac_required(sap_ctx->vdev, 1919 !!req->cac_duration_ms); 1920 1921 /* Update the rates in sap_bss_cfg for subsequent channel switch */ 1922 if (dot11_cfg.opr_rates.numRates) { 1923 qdf_mem_copy(req->opr_rates.rate, 1924 dot11_cfg.opr_rates.rate, 1925 dot11_cfg.opr_rates.numRates); 1926 qdf_mem_copy(sap_ctx->sap_bss_cfg.operationalRateSet.rate, 1927 dot11_cfg.opr_rates.rate, 1928 dot11_cfg.opr_rates.numRates); 1929 req->opr_rates.numRates = dot11_cfg.opr_rates.numRates; 1930 sap_ctx->sap_bss_cfg.operationalRateSet.numRates = 1931 dot11_cfg.opr_rates.numRates; 1932 } else { 1933 qdf_mem_zero(&sap_ctx->sap_bss_cfg.operationalRateSet, 1934 sizeof(tSirMacRateSet)); 1935 } 1936 1937 if (dot11_cfg.ext_rates.numRates) { 1938 qdf_mem_copy(req->ext_rates.rate, 1939 dot11_cfg.ext_rates.rate, 1940 dot11_cfg.ext_rates.numRates); 1941 qdf_mem_copy(sap_ctx->sap_bss_cfg.extendedRateSet.rate, 1942 dot11_cfg.ext_rates.rate, 1943 dot11_cfg.ext_rates.numRates); 1944 req->ext_rates.numRates = dot11_cfg.ext_rates.numRates; 1945 sap_ctx->sap_bss_cfg.extendedRateSet.numRates = 1946 dot11_cfg.ext_rates.numRates; 1947 } else { 1948 qdf_mem_zero(&sap_ctx->sap_bss_cfg.extendedRateSet, 1949 sizeof(tSirMacRateSet)); 1950 } 1951 1952 if (sap_ctx->require_h2e) { 1953 h2e = WLAN_BASIC_RATE_MASK | 1954 WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E; 1955 if (req->ext_rates.numRates < SIR_MAC_MAX_NUMBER_OF_RATES) { 1956 req->ext_rates.rate[req->ext_rates.numRates] = h2e; 1957 req->ext_rates.numRates++; 1958 sap_debug("H2E bss membership add to ext support rate"); 1959 } else if (req->opr_rates.numRates < 1960 SIR_MAC_MAX_NUMBER_OF_RATES) { 1961 req->opr_rates.rate[req->opr_rates.numRates] = h2e; 1962 req->opr_rates.numRates++; 1963 sap_debug("H2E bss membership add to support rate"); 1964 } else { 1965 sap_err("rates full, can not add H2E bss membership"); 1966 } 1967 } 1968 return; 1969 } 1970 1971 QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx, 1972 uint32_t target_chan_freq) 1973 { 1974 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1975 struct mac_context *mac_ctx; 1976 eCsrPhyMode phy_mode; 1977 struct ch_params *ch_params; 1978 struct channel_change_req *ch_change_req; 1979 1980 if (!target_chan_freq) { 1981 sap_err("channel 0 requested"); 1982 return QDF_STATUS_E_FAULT; 1983 } 1984 1985 if (!sap_ctx) { 1986 sap_err("Invalid SAP pointer"); 1987 return QDF_STATUS_E_FAULT; 1988 } 1989 1990 mac_ctx = sap_get_mac_context(); 1991 if (!mac_ctx) { 1992 sap_err("Invalid MAC context"); 1993 return QDF_STATUS_E_FAULT; 1994 } 1995 1996 phy_mode = sap_ctx->phyMode; 1997 1998 /* Update phy_mode if the target channel is in the other band */ 1999 if (WLAN_REG_IS_5GHZ_CH_FREQ(target_chan_freq) && 2000 ((phy_mode == eCSR_DOT11_MODE_11g) || 2001 (phy_mode == eCSR_DOT11_MODE_11g_ONLY))) 2002 phy_mode = eCSR_DOT11_MODE_11a; 2003 else if (WLAN_REG_IS_24GHZ_CH_FREQ(target_chan_freq) && 2004 (phy_mode == eCSR_DOT11_MODE_11a)) 2005 phy_mode = eCSR_DOT11_MODE_11g; 2006 sap_ctx->phyMode = phy_mode; 2007 2008 if (!sap_ctx->chan_freq) { 2009 sap_err("Invalid channel list"); 2010 return QDF_STATUS_E_FAULT; 2011 } 2012 /* 2013 * We are getting channel bonding mode from sapDfsInfor structure 2014 * because we've implemented channel width fallback mechanism for DFS 2015 * which will result in channel width changing dynamically. 2016 */ 2017 ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params; 2018 if (sap_phymode_is_eht(sap_ctx->phyMode)) 2019 wlan_reg_set_create_punc_bitmap(ch_params, true); 2020 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, target_chan_freq, 2021 0, ch_params, 2022 REG_CURRENT_PWR_MODE); 2023 sap_ctx->ch_params = *ch_params; 2024 sap_ctx->freq_before_ch_switch = sap_ctx->chan_freq; 2025 /* Update the channel as this will be used to 2026 * send event to supplicant 2027 */ 2028 sap_ctx->chan_freq = target_chan_freq; 2029 wlansap_get_sec_channel(ch_params->sec_ch_offset, sap_ctx->chan_freq, 2030 &sap_ctx->sec_ch_freq); 2031 sap_dfs_set_current_channel(sap_ctx); 2032 2033 ch_change_req = qdf_mem_malloc(sizeof(struct channel_change_req)); 2034 if (!ch_change_req) 2035 return QDF_STATUS_E_FAILURE; 2036 2037 wlansap_fill_channel_change_request(sap_ctx, ch_change_req); 2038 2039 status = sme_send_channel_change_req(MAC_HANDLE(mac_ctx), 2040 ch_change_req); 2041 qdf_mem_free(ch_change_req); 2042 sap_debug("chan_freq:%d phy_mode %d width:%d offset:%d seg0:%d seg1:%d", 2043 sap_ctx->chan_freq, phy_mode, ch_params->ch_width, 2044 ch_params->sec_ch_offset, ch_params->center_freq_seg0, 2045 ch_params->center_freq_seg1); 2046 if (policy_mgr_update_indoor_concurrency(mac_ctx->psoc, 2047 wlan_vdev_get_id(sap_ctx->vdev), 2048 sap_ctx->freq_before_ch_switch, 2049 DISCONNECT_WITH_CONCURRENCY)) 2050 wlan_reg_recompute_current_chan_list(mac_ctx->psoc, 2051 mac_ctx->pdev); 2052 2053 return status; 2054 } 2055 2056 QDF_STATUS wlansap_start_beacon_req(struct sap_context *sap_ctx) 2057 { 2058 QDF_STATUS status = QDF_STATUS_SUCCESS; 2059 uint8_t dfs_cac_wait_status; 2060 struct mac_context *mac; 2061 2062 if (!sap_ctx) { 2063 sap_err("Invalid SAP pointer"); 2064 return QDF_STATUS_E_FAULT; 2065 } 2066 2067 mac = sap_get_mac_context(); 2068 if (!mac) { 2069 sap_err("Invalid MAC context"); 2070 return QDF_STATUS_E_FAULT; 2071 } 2072 2073 /* No Radar was found during CAC WAIT, So start Beaconing */ 2074 if (!sap_ctx->sap_radar_found_status) { 2075 /* CAC Wait done without any Radar Detection */ 2076 dfs_cac_wait_status = true; 2077 wlan_pre_cac_complete_set(sap_ctx->vdev, false); 2078 status = sme_roam_start_beacon_req(MAC_HANDLE(mac), 2079 sap_ctx->bssid, 2080 dfs_cac_wait_status); 2081 } 2082 2083 return status; 2084 } 2085 2086 QDF_STATUS wlansap_dfs_send_csa_ie_request(struct sap_context *sap_ctx) 2087 { 2088 struct mac_context *mac; 2089 uint32_t new_cac_ms; 2090 uint32_t dfs_region; 2091 2092 if (!sap_ctx) { 2093 sap_err("Invalid SAP pointer"); 2094 return QDF_STATUS_E_FAULT; 2095 } 2096 2097 mac = sap_get_mac_context(); 2098 if (!mac) { 2099 sap_err("Invalid MAC context"); 2100 return QDF_STATUS_E_FAULT; 2101 } 2102 2103 mac->sap.SapDfsInfo.new_ch_params.ch_width = 2104 mac->sap.SapDfsInfo.new_chanWidth; 2105 if (sap_phymode_is_eht(sap_ctx->phyMode)) 2106 wlan_reg_set_create_punc_bitmap( 2107 &mac->sap.SapDfsInfo.new_ch_params, true); 2108 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, 2109 mac->sap.SapDfsInfo.target_chan_freq, 2110 0, &mac->sap.SapDfsInfo.new_ch_params, 2111 REG_CURRENT_PWR_MODE); 2112 2113 sap_get_cac_dur_dfs_region(sap_ctx, &new_cac_ms, &dfs_region, 2114 mac->sap.SapDfsInfo.target_chan_freq, 2115 &mac->sap.SapDfsInfo.new_ch_params); 2116 mlme_set_cac_required(sap_ctx->vdev, !!new_cac_ms); 2117 sap_debug("chan freq:%d req:%d width:%d off:%d cac %d", 2118 mac->sap.SapDfsInfo.target_chan_freq, 2119 mac->sap.SapDfsInfo.csaIERequired, 2120 mac->sap.SapDfsInfo.new_ch_params.ch_width, 2121 mac->sap.SapDfsInfo.new_ch_params.sec_ch_offset, 2122 new_cac_ms); 2123 2124 return sme_roam_csa_ie_request(MAC_HANDLE(mac), 2125 sap_ctx->bssid, 2126 mac->sap.SapDfsInfo.target_chan_freq, 2127 mac->sap.SapDfsInfo.csaIERequired, 2128 &mac->sap.SapDfsInfo.new_ch_params, 2129 new_cac_ms); 2130 } 2131 2132 QDF_STATUS wlansap_get_dfs_ignore_cac(mac_handle_t mac_handle, 2133 uint8_t *ignore_cac) 2134 { 2135 struct mac_context *mac = NULL; 2136 2137 if (mac_handle) { 2138 mac = MAC_CONTEXT(mac_handle); 2139 } else { 2140 sap_err("Invalid mac_handle pointer"); 2141 return QDF_STATUS_E_FAULT; 2142 } 2143 2144 *ignore_cac = mac->sap.SapDfsInfo.ignore_cac; 2145 return QDF_STATUS_SUCCESS; 2146 } 2147 2148 QDF_STATUS wlansap_set_dfs_ignore_cac(mac_handle_t mac_handle, 2149 uint8_t ignore_cac) 2150 { 2151 struct mac_context *mac = NULL; 2152 2153 if (mac_handle) { 2154 mac = MAC_CONTEXT(mac_handle); 2155 } else { 2156 sap_err("Invalid mac_handle pointer"); 2157 return QDF_STATUS_E_FAULT; 2158 } 2159 2160 mac->sap.SapDfsInfo.ignore_cac = (ignore_cac >= true) ? 2161 true : false; 2162 return QDF_STATUS_SUCCESS; 2163 } 2164 2165 QDF_STATUS wlansap_get_dfs_cac_state(mac_handle_t mac_handle, 2166 struct sap_context *sapcontext, 2167 bool *cac_state) 2168 { 2169 struct mac_context *mac = NULL; 2170 2171 if (mac_handle) { 2172 mac = MAC_CONTEXT(mac_handle); 2173 } else { 2174 sap_err("Invalid mac_handle pointer"); 2175 return QDF_STATUS_E_FAULT; 2176 } 2177 if (!sapcontext) { 2178 sap_err("Invalid sapcontext pointer"); 2179 return QDF_STATUS_E_FAULT; 2180 } 2181 2182 *cac_state = sap_is_dfs_cac_wait_state(sapcontext); 2183 2184 return QDF_STATUS_SUCCESS; 2185 } 2186 2187 bool sap_is_auto_channel_select(struct sap_context *sapcontext) 2188 { 2189 if (!sapcontext) { 2190 sap_err("Invalid SAP pointer"); 2191 return false; 2192 } 2193 return sapcontext->chan_freq == AUTO_CHANNEL_SELECT; 2194 } 2195 2196 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 2197 /** 2198 * wlan_sap_set_channel_avoidance() - sets sap mcc channel avoidance ini param 2199 * @mac_handle: Opaque handle to the global MAC context 2200 * @sap_channel_avoidance: ini parameter value 2201 * 2202 * sets sap mcc channel avoidance ini param, to be called in sap_start 2203 * 2204 * Return: success of failure of operation 2205 */ 2206 QDF_STATUS 2207 wlan_sap_set_channel_avoidance(mac_handle_t mac_handle, 2208 bool sap_channel_avoidance) 2209 { 2210 struct mac_context *mac_ctx = NULL; 2211 2212 if (mac_handle) { 2213 mac_ctx = MAC_CONTEXT(mac_handle); 2214 } else { 2215 sap_err("mac_handle or mac_ctx pointer NULL"); 2216 return QDF_STATUS_E_FAULT; 2217 } 2218 mac_ctx->sap.sap_channel_avoidance = sap_channel_avoidance; 2219 return QDF_STATUS_SUCCESS; 2220 } 2221 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 2222 2223 QDF_STATUS 2224 wlan_sap_set_acs_with_more_param(mac_handle_t mac_handle, 2225 bool acs_with_more_param) 2226 { 2227 struct mac_context *mac_ctx; 2228 2229 if (mac_handle) { 2230 mac_ctx = MAC_CONTEXT(mac_handle); 2231 } else { 2232 sap_err("mac_handle or mac_ctx pointer NULL"); 2233 return QDF_STATUS_E_FAULT; 2234 } 2235 mac_ctx->sap.acs_with_more_param = acs_with_more_param; 2236 return QDF_STATUS_SUCCESS; 2237 } 2238 2239 QDF_STATUS 2240 wlansap_set_dfs_preferred_channel_location(mac_handle_t mac_handle) 2241 { 2242 struct mac_context *mac = NULL; 2243 QDF_STATUS status; 2244 enum dfs_reg dfs_region; 2245 uint8_t dfs_preferred_channels_location = 0; 2246 2247 if (mac_handle) { 2248 mac = MAC_CONTEXT(mac_handle); 2249 } else { 2250 sap_err("Invalid mac_handle pointer"); 2251 return QDF_STATUS_E_FAULT; 2252 } 2253 2254 wlan_reg_get_dfs_region(mac->pdev, &dfs_region); 2255 2256 /* 2257 * The Indoor/Outdoor only random channel selection 2258 * restriction is currently enforeced only for 2259 * JAPAN regulatory domain. 2260 */ 2261 ucfg_mlme_get_pref_chan_location(mac->psoc, 2262 &dfs_preferred_channels_location); 2263 sap_debug("dfs_preferred_channels_location %d dfs region %d", 2264 dfs_preferred_channels_location, dfs_region); 2265 2266 if (dfs_region == DFS_MKK_REGION || 2267 dfs_region == DFS_MKKN_REGION) { 2268 mac->sap.SapDfsInfo.sap_operating_chan_preferred_location = 2269 dfs_preferred_channels_location; 2270 sap_debug("sapdfs:Set Preferred Operating Channel location=%d", 2271 mac->sap.SapDfsInfo. 2272 sap_operating_chan_preferred_location); 2273 2274 status = QDF_STATUS_SUCCESS; 2275 } else { 2276 sap_debug("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location"); 2277 2278 status = QDF_STATUS_E_FAULT; 2279 } 2280 2281 return status; 2282 } 2283 2284 QDF_STATUS wlansap_set_dfs_target_chnl(mac_handle_t mac_handle, 2285 uint32_t target_chan_freq) 2286 { 2287 struct mac_context *mac = NULL; 2288 2289 if (mac_handle) { 2290 mac = MAC_CONTEXT(mac_handle); 2291 } else { 2292 sap_err("Invalid mac_handle pointer"); 2293 return QDF_STATUS_E_FAULT; 2294 } 2295 if (target_chan_freq > 0) { 2296 mac->sap.SapDfsInfo.user_provided_target_chan_freq = 2297 target_chan_freq; 2298 } else { 2299 mac->sap.SapDfsInfo.user_provided_target_chan_freq = 0; 2300 } 2301 2302 return QDF_STATUS_SUCCESS; 2303 } 2304 2305 QDF_STATUS 2306 wlansap_update_sap_config_add_ie(struct sap_config *config, 2307 const uint8_t *pAdditionIEBuffer, 2308 uint16_t additionIELength, 2309 eUpdateIEsType updateType) 2310 { 2311 QDF_STATUS status = QDF_STATUS_SUCCESS; 2312 uint8_t bufferValid = false; 2313 uint16_t bufferLength = 0; 2314 uint8_t *pBuffer = NULL; 2315 2316 if (!config) { 2317 return QDF_STATUS_E_FAULT; 2318 } 2319 2320 if ((pAdditionIEBuffer) && (additionIELength != 0)) { 2321 /* initialize the buffer pointer so that pe can copy */ 2322 if (additionIELength > 0) { 2323 bufferLength = additionIELength; 2324 pBuffer = qdf_mem_malloc(bufferLength); 2325 if (!pBuffer) 2326 return QDF_STATUS_E_NOMEM; 2327 2328 qdf_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength); 2329 bufferValid = true; 2330 sap_debug("update_type: %d", updateType); 2331 qdf_trace_hex_dump(QDF_MODULE_ID_SAP, 2332 QDF_TRACE_LEVEL_DEBUG, pBuffer, bufferLength); 2333 } 2334 } 2335 2336 switch (updateType) { 2337 case eUPDATE_IE_PROBE_BCN: 2338 if (config->pProbeRespBcnIEsBuffer) 2339 qdf_mem_free(config->pProbeRespBcnIEsBuffer); 2340 if (bufferValid) { 2341 config->probeRespBcnIEsLen = bufferLength; 2342 config->pProbeRespBcnIEsBuffer = pBuffer; 2343 } else { 2344 config->probeRespBcnIEsLen = 0; 2345 config->pProbeRespBcnIEsBuffer = NULL; 2346 } 2347 break; 2348 case eUPDATE_IE_PROBE_RESP: 2349 if (config->pProbeRespIEsBuffer) 2350 qdf_mem_free(config->pProbeRespIEsBuffer); 2351 if (bufferValid) { 2352 config->probeRespIEsBufferLen = bufferLength; 2353 config->pProbeRespIEsBuffer = pBuffer; 2354 } else { 2355 config->probeRespIEsBufferLen = 0; 2356 config->pProbeRespIEsBuffer = NULL; 2357 } 2358 break; 2359 case eUPDATE_IE_ASSOC_RESP: 2360 if (config->pAssocRespIEsBuffer) 2361 qdf_mem_free(config->pAssocRespIEsBuffer); 2362 if (bufferValid) { 2363 config->assocRespIEsLen = bufferLength; 2364 config->pAssocRespIEsBuffer = pBuffer; 2365 } else { 2366 config->assocRespIEsLen = 0; 2367 config->pAssocRespIEsBuffer = NULL; 2368 } 2369 break; 2370 default: 2371 sap_debug("No matching buffer type %d", updateType); 2372 if (pBuffer) 2373 qdf_mem_free(pBuffer); 2374 break; 2375 } 2376 2377 return status; 2378 } 2379 2380 QDF_STATUS 2381 wlansap_reset_sap_config_add_ie(struct sap_config *config, 2382 eUpdateIEsType updateType) 2383 { 2384 if (!config) { 2385 sap_err("Invalid Config pointer"); 2386 return QDF_STATUS_E_FAULT; 2387 } 2388 2389 switch (updateType) { 2390 case eUPDATE_IE_ALL: /*only used to reset */ 2391 case eUPDATE_IE_PROBE_RESP: 2392 if (config->pProbeRespIEsBuffer) { 2393 qdf_mem_free(config->pProbeRespIEsBuffer); 2394 config->probeRespIEsBufferLen = 0; 2395 config->pProbeRespIEsBuffer = NULL; 2396 } 2397 if (eUPDATE_IE_ALL != updateType) 2398 break; 2399 fallthrough; 2400 case eUPDATE_IE_ASSOC_RESP: 2401 if (config->pAssocRespIEsBuffer) { 2402 qdf_mem_free(config->pAssocRespIEsBuffer); 2403 config->assocRespIEsLen = 0; 2404 config->pAssocRespIEsBuffer = NULL; 2405 } 2406 if (eUPDATE_IE_ALL != updateType) 2407 break; 2408 fallthrough; 2409 case eUPDATE_IE_PROBE_BCN: 2410 if (config->pProbeRespBcnIEsBuffer) { 2411 qdf_mem_free(config->pProbeRespBcnIEsBuffer); 2412 config->probeRespBcnIEsLen = 0; 2413 config->pProbeRespBcnIEsBuffer = NULL; 2414 } 2415 if (eUPDATE_IE_ALL != updateType) 2416 break; 2417 fallthrough; 2418 default: 2419 if (eUPDATE_IE_ALL != updateType) 2420 sap_err("Invalid buffer type %d", updateType); 2421 break; 2422 } 2423 return QDF_STATUS_SUCCESS; 2424 } 2425 2426 #ifdef WLAN_FEATURE_SON 2427 QDF_STATUS 2428 wlansap_son_update_sap_config_phymode(struct wlan_objmgr_vdev *vdev, 2429 struct sap_config *config, 2430 enum qca_wlan_vendor_phy_mode phy_mode) 2431 { 2432 struct wlan_objmgr_pdev *pdev; 2433 struct wlan_objmgr_psoc *psoc; 2434 struct wlan_channel *des_chan; 2435 2436 if (!vdev || !config) { 2437 sap_err("Invalid input parameters"); 2438 return QDF_STATUS_E_FAULT; 2439 } 2440 2441 pdev = wlan_vdev_get_pdev(vdev); 2442 if (!pdev) { 2443 sap_err("Invalid pdev parameters"); 2444 return QDF_STATUS_E_FAULT; 2445 } 2446 psoc = wlan_pdev_get_psoc(pdev); 2447 if (!psoc) { 2448 sap_err("Invalid psoc parameters"); 2449 return QDF_STATUS_E_FAULT; 2450 } 2451 des_chan = wlan_vdev_mlme_get_des_chan(vdev); 2452 if (!des_chan) { 2453 sap_err("Invalid desired channel"); 2454 return QDF_STATUS_E_FAULT; 2455 } 2456 config->sap_orig_hw_mode = config->SapHw_mode; 2457 config->ch_width_orig = config->ch_params.ch_width; 2458 switch (phy_mode) { 2459 case QCA_WLAN_VENDOR_PHY_MODE_11A: 2460 config->SapHw_mode = eCSR_DOT11_MODE_11a; 2461 config->ch_params.ch_width = CH_WIDTH_20MHZ; 2462 break; 2463 case QCA_WLAN_VENDOR_PHY_MODE_11B: 2464 config->SapHw_mode = eCSR_DOT11_MODE_11b; 2465 config->ch_params.ch_width = CH_WIDTH_20MHZ; 2466 break; 2467 case QCA_WLAN_VENDOR_PHY_MODE_11G: 2468 config->SapHw_mode = eCSR_DOT11_MODE_11g; 2469 config->ch_params.ch_width = CH_WIDTH_20MHZ; 2470 break; 2471 case QCA_WLAN_VENDOR_PHY_MODE_11AGN: 2472 case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20: 2473 case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20: 2474 config->SapHw_mode = eCSR_DOT11_MODE_11n; 2475 config->ch_params.ch_width = CH_WIDTH_20MHZ; 2476 break; 2477 case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS: 2478 case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS: 2479 case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40: 2480 case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS: 2481 case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS: 2482 case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40: 2483 config->SapHw_mode = eCSR_DOT11_MODE_11n; 2484 config->ch_params.ch_width = CH_WIDTH_40MHZ; 2485 break; 2486 case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20: 2487 config->SapHw_mode = eCSR_DOT11_MODE_11ac; 2488 config->ch_params.ch_width = CH_WIDTH_20MHZ; 2489 break; 2490 case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS: 2491 case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS: 2492 case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40: 2493 config->SapHw_mode = eCSR_DOT11_MODE_11ac; 2494 config->ch_params.ch_width = CH_WIDTH_40MHZ; 2495 break; 2496 case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80: 2497 config->SapHw_mode = eCSR_DOT11_MODE_11ac; 2498 config->ch_params.ch_width = CH_WIDTH_80MHZ; 2499 break; 2500 case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160: 2501 config->SapHw_mode = eCSR_DOT11_MODE_11ac; 2502 config->ch_params.ch_width = CH_WIDTH_160MHZ; 2503 break; 2504 case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20: 2505 config->SapHw_mode = eCSR_DOT11_MODE_11ax; 2506 config->ch_params.ch_width = CH_WIDTH_20MHZ; 2507 break; 2508 case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40: 2509 case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS: 2510 case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS: 2511 config->SapHw_mode = eCSR_DOT11_MODE_11ax; 2512 config->ch_params.ch_width = CH_WIDTH_40MHZ; 2513 break; 2514 case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80: 2515 config->SapHw_mode = eCSR_DOT11_MODE_11ax; 2516 config->ch_params.ch_width = CH_WIDTH_80MHZ; 2517 break; 2518 case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160: 2519 config->SapHw_mode = eCSR_DOT11_MODE_11ax; 2520 config->ch_params.ch_width = CH_WIDTH_160MHZ; 2521 break; 2522 case QCA_WLAN_VENDOR_PHY_MODE_AUTO: 2523 config->SapHw_mode = eCSR_DOT11_MODE_AUTO; 2524 break; 2525 default: 2526 sap_err("Invalid phy mode %d to configure", phy_mode); 2527 break; 2528 } 2529 2530 if (sap_phymode_is_eht(config->SapHw_mode)) 2531 wlan_reg_set_create_punc_bitmap(&config->ch_params, true); 2532 if (config->ch_params.ch_width == CH_WIDTH_80P80MHZ && 2533 ucfg_mlme_get_restricted_80p80_bw_supp(psoc)) { 2534 if (!((config->ch_params.center_freq_seg0 == 138 && 2535 config->ch_params.center_freq_seg1 == 155) || 2536 (config->ch_params.center_freq_seg1 == 138 && 2537 config->ch_params.center_freq_seg0 == 155))) { 2538 sap_debug("Falling back to 80 from 80p80 as non supported freq_seq0 %d and freq_seq1 %d", 2539 config->ch_params.mhz_freq_seg0, 2540 config->ch_params.mhz_freq_seg1); 2541 config->ch_params.center_freq_seg1 = 0; 2542 config->ch_params.mhz_freq_seg1 = 0; 2543 config->ch_width_orig = CH_WIDTH_80MHZ; 2544 config->ch_params.ch_width = config->ch_width_orig; 2545 } 2546 } 2547 2548 config->chan_freq = des_chan->ch_freq; 2549 config->sec_ch_freq = 0; 2550 if (WLAN_REG_IS_24GHZ_CH_FREQ(des_chan->ch_freq) && 2551 config->ch_params.ch_width == CH_WIDTH_40MHZ && 2552 des_chan->ch_width == CH_WIDTH_40MHZ) { 2553 if (des_chan->ch_cfreq1 == des_chan->ch_freq + BW_10_MHZ) 2554 config->sec_ch_freq = des_chan->ch_freq + BW_20_MHZ; 2555 if (des_chan->ch_cfreq1 == des_chan->ch_freq - BW_10_MHZ) 2556 config->sec_ch_freq = des_chan->ch_freq - BW_20_MHZ; 2557 } 2558 wlan_reg_set_channel_params_for_pwrmode(pdev, config->chan_freq, 2559 config->sec_ch_freq, 2560 &config->ch_params, 2561 REG_CURRENT_PWR_MODE); 2562 2563 return QDF_STATUS_SUCCESS; 2564 } 2565 #endif 2566 2567 #define ACS_WLAN_20M_CH_INC 20 2568 #define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC 2569 #define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3) 2570 2571 #ifdef CONFIG_BAND_6GHZ 2572 static void wlansap_update_start_range_6ghz( 2573 uint32_t *start_ch_freq, uint32_t *bandStartChannel) 2574 { 2575 *bandStartChannel = MIN_6GHZ_CHANNEL; 2576 *start_ch_freq = (*start_ch_freq - ACS_5G_EXTEND) > 2577 wlan_reg_ch_to_freq(MIN_6GHZ_CHANNEL) ? 2578 (*start_ch_freq - ACS_5G_EXTEND) : 2579 wlan_reg_ch_to_freq(MIN_6GHZ_CHANNEL); 2580 } 2581 2582 static void wlansap_update_end_range_6ghz( 2583 uint32_t *end_ch_freq, uint32_t *bandEndChannel) 2584 { 2585 *bandEndChannel = MAX_6GHZ_CHANNEL; 2586 *end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <= 2587 wlan_reg_ch_to_freq(MAX_6GHZ_CHANNEL) ? 2588 (*end_ch_freq + ACS_5G_EXTEND) : 2589 wlan_reg_ch_to_freq(MAX_6GHZ_CHANNEL); 2590 } 2591 #else 2592 static void wlansap_update_start_range_6ghz( 2593 uint32_t *start_ch_freq, uint32_t *bandStartChannel) 2594 { 2595 } 2596 2597 static void wlansap_update_end_range_6ghz( 2598 uint32_t *end_ch_freq, uint32_t *bandEndChannel) 2599 { 2600 } 2601 #endif 2602 2603 /*========================================================================== 2604 FUNCTION wlansap_extend_to_acs_range 2605 2606 DESCRIPTION Function extends give channel range to consider ACS chan bonding 2607 2608 DEPENDENCIES PARAMETERS 2609 2610 IN /OUT 2611 * start_ch_freq : ACS extend start ch 2612 * end_ch_freq : ACS extended End ch 2613 * bandStartChannel: Band start ch 2614 * bandEndChannel : Band end ch 2615 2616 RETURN VALUE NONE 2617 2618 SIDE EFFECTS 2619 ============================================================================*/ 2620 void wlansap_extend_to_acs_range(mac_handle_t mac_handle, 2621 uint32_t *start_ch_freq, 2622 uint32_t *end_ch_freq, 2623 uint32_t *bandStartChannel, 2624 uint32_t *bandEndChannel) 2625 { 2626 uint32_t tmp_start_ch_freq = 0, tmp_end_ch_freq = 0; 2627 struct mac_context *mac_ctx; 2628 2629 mac_ctx = MAC_CONTEXT(mac_handle); 2630 if (!mac_ctx) { 2631 sap_err("Invalid mac_ctx"); 2632 return; 2633 } 2634 if (*start_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) { 2635 *bandStartChannel = CHAN_ENUM_2412; 2636 tmp_start_ch_freq = *start_ch_freq > 2637 wlan_reg_ch_to_freq(CHAN_ENUM_2432) ? 2638 (*start_ch_freq - ACS_2G_EXTEND) : 2639 wlan_reg_ch_to_freq(CHAN_ENUM_2412); 2640 } else if (*start_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_5885)) { 2641 *bandStartChannel = CHAN_ENUM_5180; 2642 tmp_start_ch_freq = (*start_ch_freq - ACS_5G_EXTEND) > 2643 wlan_reg_ch_to_freq(CHAN_ENUM_5180) ? 2644 (*start_ch_freq - ACS_5G_EXTEND) : 2645 wlan_reg_ch_to_freq(CHAN_ENUM_5180); 2646 } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(*start_ch_freq)) { 2647 tmp_start_ch_freq = *start_ch_freq; 2648 wlansap_update_start_range_6ghz(&tmp_start_ch_freq, 2649 bandStartChannel); 2650 } else { 2651 *bandStartChannel = CHAN_ENUM_2412; 2652 tmp_start_ch_freq = *start_ch_freq > 2653 wlan_reg_ch_to_freq(CHAN_ENUM_2432) ? 2654 (*start_ch_freq - ACS_2G_EXTEND) : 2655 wlan_reg_ch_to_freq(CHAN_ENUM_2412); 2656 sap_err("unexpected start freq %d", 2657 *start_ch_freq); 2658 } 2659 2660 if (*end_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) { 2661 *bandEndChannel = CHAN_ENUM_2484; 2662 tmp_end_ch_freq = (*end_ch_freq + ACS_2G_EXTEND) <= 2663 wlan_reg_ch_to_freq(CHAN_ENUM_2484) ? 2664 (*end_ch_freq + ACS_2G_EXTEND) : 2665 wlan_reg_ch_to_freq(CHAN_ENUM_2484); 2666 } else if (*end_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_5885)) { 2667 *bandEndChannel = CHAN_ENUM_5885; 2668 tmp_end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <= 2669 wlan_reg_ch_to_freq(CHAN_ENUM_5885) ? 2670 (*end_ch_freq + ACS_5G_EXTEND) : 2671 wlan_reg_ch_to_freq(CHAN_ENUM_5885); 2672 } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(*end_ch_freq)) { 2673 tmp_end_ch_freq = *end_ch_freq; 2674 wlansap_update_end_range_6ghz(&tmp_end_ch_freq, 2675 bandEndChannel); 2676 } else { 2677 *bandEndChannel = CHAN_ENUM_5885; 2678 tmp_end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <= 2679 wlan_reg_ch_to_freq(CHAN_ENUM_5885) ? 2680 (*end_ch_freq + ACS_5G_EXTEND) : 2681 wlan_reg_ch_to_freq(CHAN_ENUM_5885); 2682 2683 sap_err("unexpected end freq %d", *end_ch_freq); 2684 } 2685 *start_ch_freq = tmp_start_ch_freq; 2686 *end_ch_freq = tmp_end_ch_freq; 2687 /* Note if the ACS range include only DFS channels, do not cross range 2688 * Active scanning in adjacent non DFS channels results in transmission 2689 * spikes in DFS spectrum channels which is due to emission spill. 2690 * Remove the active channels from extend ACS range for DFS only range 2691 */ 2692 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, *start_ch_freq)) { 2693 while (!wlan_reg_is_dfs_for_freq( 2694 mac_ctx->pdev, 2695 tmp_start_ch_freq) && 2696 tmp_start_ch_freq < *start_ch_freq) 2697 tmp_start_ch_freq += ACS_WLAN_20M_CH_INC; 2698 2699 *start_ch_freq = tmp_start_ch_freq; 2700 } 2701 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, *end_ch_freq)) { 2702 while (!wlan_reg_is_dfs_for_freq( 2703 mac_ctx->pdev, 2704 tmp_end_ch_freq) && 2705 tmp_end_ch_freq > *end_ch_freq) 2706 tmp_end_ch_freq -= ACS_WLAN_20M_CH_INC; 2707 2708 *end_ch_freq = tmp_end_ch_freq; 2709 } 2710 } 2711 2712 QDF_STATUS wlan_sap_set_vendor_acs(struct sap_context *sap_context, 2713 bool is_vendor_acs) 2714 { 2715 if (!sap_context) { 2716 sap_err("Invalid SAP pointer"); 2717 return QDF_STATUS_E_FAULT; 2718 } 2719 sap_context->vendor_acs_dfs_lte_enabled = is_vendor_acs; 2720 2721 return QDF_STATUS_SUCCESS; 2722 } 2723 2724 #ifdef DFS_COMPONENT_ENABLE 2725 QDF_STATUS wlansap_set_dfs_nol(struct sap_context *sap_ctx, 2726 eSapDfsNolType conf) 2727 { 2728 struct mac_context *mac; 2729 2730 if (!sap_ctx) { 2731 sap_err("Invalid SAP pointer"); 2732 return QDF_STATUS_E_FAULT; 2733 } 2734 2735 mac = sap_get_mac_context(); 2736 if (!mac) { 2737 sap_err("Invalid MAC context"); 2738 return QDF_STATUS_E_FAULT; 2739 } 2740 2741 if (conf == eSAP_DFS_NOL_CLEAR) { 2742 struct wlan_objmgr_pdev *pdev; 2743 2744 sap_err("clear the DFS NOL"); 2745 2746 pdev = mac->pdev; 2747 if (!pdev) { 2748 sap_err("null pdev"); 2749 return QDF_STATUS_E_FAULT; 2750 } 2751 utils_dfs_clear_nol_channels(pdev); 2752 } else if (conf == eSAP_DFS_NOL_RANDOMIZE) { 2753 sap_err("Randomize the DFS NOL"); 2754 2755 } else { 2756 sap_err("unsupported type %d", conf); 2757 } 2758 2759 return QDF_STATUS_SUCCESS; 2760 } 2761 #endif 2762 2763 void wlansap_populate_del_sta_params(const uint8_t *mac, 2764 uint16_t reason_code, 2765 uint8_t subtype, 2766 struct csr_del_sta_params *params) 2767 { 2768 if (!mac) 2769 qdf_set_macaddr_broadcast(¶ms->peerMacAddr); 2770 else 2771 qdf_mem_copy(params->peerMacAddr.bytes, mac, 2772 QDF_MAC_ADDR_SIZE); 2773 2774 if (reason_code == 0) 2775 params->reason_code = REASON_DEAUTH_NETWORK_LEAVING; 2776 else 2777 params->reason_code = reason_code; 2778 2779 if (subtype == SIR_MAC_MGMT_DEAUTH || subtype == SIR_MAC_MGMT_DISASSOC) 2780 params->subtype = subtype; 2781 else 2782 params->subtype = SIR_MAC_MGMT_DEAUTH; 2783 2784 sap_debug("Delete STA with RC:%hu subtype:%hhu MAC::" QDF_MAC_ADDR_FMT, 2785 params->reason_code, params->subtype, 2786 QDF_MAC_ADDR_REF(params->peerMacAddr.bytes)); 2787 } 2788 2789 void sap_undo_acs(struct sap_context *sap_ctx, struct sap_config *sap_cfg) 2790 { 2791 struct sap_acs_cfg *acs_cfg; 2792 2793 if (!sap_ctx) 2794 return; 2795 2796 acs_cfg = &sap_cfg->acs_cfg; 2797 if (!acs_cfg) 2798 return; 2799 2800 if (acs_cfg->freq_list) { 2801 sap_debug("Clearing ACS cfg ch freq list"); 2802 qdf_mem_free(acs_cfg->freq_list); 2803 acs_cfg->freq_list = NULL; 2804 } 2805 if (acs_cfg->master_freq_list) { 2806 sap_debug("Clearing master ACS cfg chan freq list"); 2807 qdf_mem_free(acs_cfg->master_freq_list); 2808 acs_cfg->master_freq_list = NULL; 2809 } 2810 if (sap_ctx->freq_list) { 2811 sap_debug("Clearing sap context ch freq list"); 2812 qdf_mem_free(sap_ctx->freq_list); 2813 sap_ctx->freq_list = NULL; 2814 } 2815 acs_cfg->ch_list_count = 0; 2816 acs_cfg->master_ch_list_count = 0; 2817 acs_cfg->acs_mode = false; 2818 acs_cfg->master_ch_list_updated = false; 2819 sap_ctx->num_of_channel = 0; 2820 wlansap_dcs_set_vdev_wlan_interference_mitigation(sap_ctx, false); 2821 } 2822 2823 QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context, 2824 sap_event_cb acs_event_callback, 2825 struct sap_config *config, 2826 void *pusr_context) 2827 { 2828 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2829 struct mac_context *mac; 2830 2831 if (!sap_context) { 2832 sap_err("Invalid SAP pointer"); 2833 2834 return QDF_STATUS_E_FAULT; 2835 } 2836 2837 mac = sap_get_mac_context(); 2838 if (!mac) { 2839 sap_err("Invalid MAC context"); 2840 return QDF_STATUS_E_FAULT; 2841 } 2842 2843 sap_context->acs_cfg = &config->acs_cfg; 2844 sap_context->ch_width_orig = config->acs_cfg.ch_width; 2845 sap_context->phyMode = config->acs_cfg.hw_mode; 2846 2847 /* 2848 * Now, configure the scan and ACS channel params 2849 * to issue a scan request. 2850 */ 2851 wlansap_set_scan_acs_channel_params(config, sap_context, 2852 pusr_context); 2853 2854 /* 2855 * Copy the HDD callback function to report the 2856 * ACS result after scan in SAP context callback function. 2857 */ 2858 sap_context->sap_event_cb = acs_event_callback; 2859 2860 /* 2861 * Issue the scan request. This scan request is 2862 * issued before the start BSS is done so 2863 * 2864 * 1. No need to pass the second parameter 2865 * as the SAP state machine is not started yet 2866 * and there is no need for any event posting. 2867 * 2868 * 2. Set third parameter to TRUE to indicate the 2869 * channel selection function to register a 2870 * different scan callback function to process 2871 * the results pre start BSS. 2872 */ 2873 qdf_status = sap_channel_sel(sap_context); 2874 2875 if (QDF_STATUS_E_ABORTED == qdf_status) { 2876 sap_err("DFS not supported in the current operating mode"); 2877 return QDF_STATUS_E_FAILURE; 2878 } else if (QDF_STATUS_E_CANCELED == qdf_status) { 2879 /* 2880 * ERROR is returned when either the SME scan request 2881 * failed or ACS is overridden due to other constrainst 2882 * So send selected channel to HDD 2883 */ 2884 sap_err("Scan Req Failed/ACS Overridden"); 2885 sap_err("Selected channel frequency = %d", 2886 sap_context->chan_freq); 2887 2888 return sap_signal_hdd_event(sap_context, NULL, 2889 eSAP_ACS_CHANNEL_SELECTED, 2890 (void *) eSAP_STATUS_SUCCESS); 2891 } 2892 2893 return qdf_status; 2894 } 2895 2896 /** 2897 * wlan_sap_enable_phy_error_logs() - Enable DFS phy error logs 2898 * @mac_handle: Opaque handle to the global MAC context 2899 * @enable_log: value to set 2900 * 2901 * Since the frequency of DFS phy error is very high, enabling logs for them 2902 * all the times can cause crash and will also create lot of useless logs 2903 * causing difficulties in debugging other issue. This function will be called 2904 * from iwpriv cmd to enable such logs temporarily. 2905 * 2906 * Return: void 2907 */ 2908 void wlan_sap_enable_phy_error_logs(mac_handle_t mac_handle, 2909 uint32_t enable_log) 2910 { 2911 int error; 2912 2913 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 2914 2915 mac_ctx->sap.enable_dfs_phy_error_logs = !!enable_log; 2916 tgt_dfs_control(mac_ctx->pdev, DFS_SET_DEBUG_LEVEL, &enable_log, 2917 sizeof(uint32_t), NULL, NULL, &error); 2918 } 2919 2920 #ifdef DFS_PRI_MULTIPLIER 2921 void wlan_sap_set_dfs_pri_multiplier(mac_handle_t mac_handle) 2922 { 2923 int error; 2924 2925 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 2926 2927 tgt_dfs_control(mac_ctx->pdev, DFS_SET_PRI_MULTIPILER, 2928 &mac_ctx->mlme_cfg->dfs_cfg.dfs_pri_multiplier, 2929 sizeof(uint32_t), NULL, NULL, &error); 2930 } 2931 #endif 2932 2933 uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx) 2934 { 2935 return wlan_sap_get_vht_ch_width(sap_ctx); 2936 } 2937 2938 enum phy_ch_width 2939 wlansap_get_max_bw_by_phymode(struct sap_context *sap_ctx) 2940 { 2941 uint32_t max_fw_bw; 2942 enum phy_ch_width ch_width; 2943 2944 if (!sap_ctx) { 2945 sap_err("Invalid SAP pointer"); 2946 return CH_WIDTH_20MHZ; 2947 } 2948 2949 if (sap_ctx->phyMode == eCSR_DOT11_MODE_11ac || 2950 sap_ctx->phyMode == eCSR_DOT11_MODE_11ac_ONLY || 2951 sap_ctx->phyMode == eCSR_DOT11_MODE_11ax || 2952 sap_ctx->phyMode == eCSR_DOT11_MODE_11ax_ONLY || 2953 CSR_IS_DOT11_PHY_MODE_11BE(sap_ctx->phyMode) || 2954 CSR_IS_DOT11_PHY_MODE_11BE_ONLY(sap_ctx->phyMode)) { 2955 max_fw_bw = sme_get_vht_ch_width(); 2956 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2957 ch_width = CH_WIDTH_160MHZ; 2958 else 2959 ch_width = CH_WIDTH_80MHZ; 2960 if (CSR_IS_DOT11_PHY_MODE_11BE(sap_ctx->phyMode) || 2961 CSR_IS_DOT11_PHY_MODE_11BE_ONLY(sap_ctx->phyMode)) 2962 ch_width = 2963 QDF_MAX(wlansap_get_target_eht_phy_ch_width(), 2964 ch_width); 2965 } else if (sap_ctx->phyMode == eCSR_DOT11_MODE_11n || 2966 sap_ctx->phyMode == eCSR_DOT11_MODE_11n_ONLY) { 2967 ch_width = CH_WIDTH_40MHZ; 2968 } else { 2969 /* For legacy 11a mode return 20MHz */ 2970 ch_width = CH_WIDTH_20MHZ; 2971 } 2972 2973 return ch_width; 2974 } 2975 2976 QDF_STATUS wlansap_set_invalid_session(struct sap_context *sap_ctx) 2977 { 2978 if (!sap_ctx) { 2979 sap_err("Invalid SAP pointer"); 2980 return QDF_STATUS_E_FAILURE; 2981 } 2982 2983 sap_ctx->sessionId = WLAN_UMAC_VDEV_ID_MAX; 2984 2985 return QDF_STATUS_SUCCESS; 2986 } 2987 2988 QDF_STATUS wlansap_release_vdev_ref(struct sap_context *sap_ctx) 2989 { 2990 if (!sap_ctx) { 2991 sap_err("Invalid SAP pointer"); 2992 return QDF_STATUS_E_FAILURE; 2993 } 2994 2995 sap_release_vdev_ref(sap_ctx); 2996 2997 return QDF_STATUS_SUCCESS; 2998 } 2999 3000 void wlansap_cleanup_cac_timer(struct sap_context *sap_ctx) 3001 { 3002 struct mac_context *mac; 3003 3004 if (!sap_ctx) { 3005 sap_debug("Invalid SAP context"); 3006 return; 3007 } 3008 3009 mac = sap_get_mac_context(); 3010 if (!mac) { 3011 sap_err("Invalid MAC context"); 3012 return; 3013 } 3014 3015 if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) { 3016 sap_err("sapdfs, force cleanup vdev mismatch sap vdev id %d mac_ctx vdev id %d", 3017 sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id); 3018 return; 3019 } 3020 3021 if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) { 3022 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3023 mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 3024 3025 if (!sap_ctx->dfs_cac_offload) { 3026 qdf_mc_timer_stop( 3027 &mac->sap.SapDfsInfo.sap_dfs_cac_timer); 3028 qdf_mc_timer_destroy( 3029 &mac->sap.SapDfsInfo.sap_dfs_cac_timer); 3030 sap_debug("sapdfs, force cleanup running dfs cac timer vdev id %d", 3031 sap_ctx->vdev_id); 3032 } 3033 } 3034 } 3035 3036 #define DH_OUI_TYPE (0x20) 3037 /** 3038 * wlansap_validate_owe_ie() - validate OWE IE 3039 * @ie: IE buffer 3040 * @remaining_ie_len: remaining IE length 3041 * 3042 * Return: validated IE length, negative for failure 3043 */ 3044 static int wlansap_validate_owe_ie(const uint8_t *ie, uint32_t remaining_ie_len) 3045 { 3046 uint8_t ie_id, ie_len, ie_ext_id = 0; 3047 3048 if (remaining_ie_len < 2) { 3049 sap_err("IE too short"); 3050 return -EINVAL; 3051 } 3052 3053 ie_id = ie[0]; 3054 ie_len = ie[1]; 3055 3056 /* IEs that we are expecting in OWE IEs 3057 * - RSN IE 3058 * - DH IE 3059 */ 3060 switch (ie_id) { 3061 case DOT11F_EID_RSN: 3062 if (ie_len < DOT11F_IE_RSN_MIN_LEN || 3063 ie_len > DOT11F_IE_RSN_MAX_LEN) { 3064 sap_err("Invalid RSN IE len %d", ie_len); 3065 return -EINVAL; 3066 } 3067 ie_len += 2; 3068 break; 3069 case DOT11F_EID_DH_PARAMETER_ELEMENT: 3070 ie_ext_id = ie[2]; 3071 if (ie_ext_id != DH_OUI_TYPE) { 3072 sap_err("Invalid DH IE ID %d", ie_ext_id); 3073 return -EINVAL; 3074 } 3075 if (ie_len < DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN || 3076 ie_len > DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN) { 3077 sap_err("Invalid DH IE len %d", ie_len); 3078 return -EINVAL; 3079 } 3080 ie_len += 2; 3081 break; 3082 default: 3083 sap_err("Invalid IE %d", ie_id); 3084 return -EINVAL; 3085 } 3086 3087 if (ie_len > remaining_ie_len) { 3088 sap_err("Invalid IE len"); 3089 return -EINVAL; 3090 } 3091 3092 return ie_len; 3093 } 3094 3095 /** 3096 * wlansap_validate_owe_ies() - validate OWE IEs 3097 * @ie: IE buffer 3098 * @ie_len: IE length 3099 * 3100 * Return: true if validated 3101 */ 3102 static bool wlansap_validate_owe_ies(const uint8_t *ie, uint32_t ie_len) 3103 { 3104 const uint8_t *remaining_ie = ie; 3105 uint32_t remaining_ie_len = ie_len; 3106 int validated_len; 3107 bool validated = true; 3108 3109 while (remaining_ie_len) { 3110 validated_len = wlansap_validate_owe_ie(remaining_ie, 3111 remaining_ie_len); 3112 if (validated_len < 0) { 3113 validated = false; 3114 break; 3115 } 3116 remaining_ie += validated_len; 3117 remaining_ie_len -= validated_len; 3118 } 3119 3120 return validated; 3121 } 3122 3123 QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx, 3124 uint8_t *peer, const uint8_t *ie, 3125 uint32_t ie_len, uint16_t owe_status) 3126 { 3127 struct mac_context *mac; 3128 struct owe_assoc_ind *owe_assoc_ind; 3129 struct assoc_ind *assoc_ind = NULL; 3130 qdf_list_node_t *node = NULL, *next_node = NULL; 3131 QDF_STATUS status = QDF_STATUS_SUCCESS; 3132 3133 if (!wlansap_validate_owe_ies(ie, ie_len)) { 3134 sap_err("Invalid OWE IE"); 3135 return QDF_STATUS_E_FAULT; 3136 } 3137 3138 if (!sap_ctx) { 3139 sap_err("Invalid SAP context"); 3140 return QDF_STATUS_E_FAULT; 3141 } 3142 3143 mac = sap_get_mac_context(); 3144 if (!mac) { 3145 sap_err("Invalid MAC context"); 3146 return QDF_STATUS_E_FAULT; 3147 } 3148 3149 if (QDF_STATUS_SUCCESS != 3150 qdf_list_peek_front(&sap_ctx->owe_pending_assoc_ind_list, 3151 &next_node)) { 3152 sap_err("Failed to find assoc ind list"); 3153 return QDF_STATUS_E_FAILURE; 3154 } 3155 3156 do { 3157 node = next_node; 3158 owe_assoc_ind = qdf_container_of(node, struct owe_assoc_ind, 3159 node); 3160 if (qdf_mem_cmp(peer, 3161 owe_assoc_ind->assoc_ind->peerMacAddr, 3162 QDF_MAC_ADDR_SIZE) == 0) { 3163 status = qdf_list_remove_node( 3164 &sap_ctx->owe_pending_assoc_ind_list, 3165 node); 3166 if (status != QDF_STATUS_SUCCESS) { 3167 sap_err("Failed to remove assoc ind"); 3168 return status; 3169 } 3170 assoc_ind = owe_assoc_ind->assoc_ind; 3171 qdf_mem_free(owe_assoc_ind); 3172 break; 3173 } 3174 } while (QDF_STATUS_SUCCESS == 3175 qdf_list_peek_next(&sap_ctx->owe_pending_assoc_ind_list, 3176 node, &next_node)); 3177 3178 if (assoc_ind) { 3179 assoc_ind->owe_ie = ie; 3180 assoc_ind->owe_ie_len = ie_len; 3181 assoc_ind->owe_status = owe_status; 3182 status = sme_update_owe_info(mac, assoc_ind); 3183 qdf_mem_free(assoc_ind); 3184 } 3185 3186 return status; 3187 } 3188 3189 QDF_STATUS wlansap_update_ft_info(struct sap_context *sap_ctx, 3190 uint8_t *peer, const uint8_t *ie, 3191 uint32_t ie_len, uint16_t ft_status) 3192 { 3193 struct mac_context *mac; 3194 struct ft_assoc_ind *ft_assoc_ind; 3195 struct assoc_ind *assoc_ind = NULL; 3196 qdf_list_node_t *node = NULL, *next_node = NULL; 3197 QDF_STATUS status; 3198 3199 if (!sap_ctx) { 3200 sap_err("Invalid SAP context"); 3201 return QDF_STATUS_E_FAULT; 3202 } 3203 3204 mac = sap_get_mac_context(); 3205 if (!mac) { 3206 sap_err("Invalid MAC context"); 3207 return QDF_STATUS_E_FAULT; 3208 } 3209 status = qdf_wait_single_event(&sap_ctx->ft_pending_event, 3210 500); 3211 if (!QDF_IS_STATUS_SUCCESS(status)) { 3212 sap_err("wait for ft pending event timeout"); 3213 wlansap_ft_cleanup(sap_ctx); 3214 return QDF_STATUS_E_FAULT; 3215 } 3216 3217 if (QDF_STATUS_SUCCESS != 3218 qdf_list_peek_front(&sap_ctx->ft_pending_assoc_ind_list, 3219 &next_node)) { 3220 sap_err("Failed to find ft assoc ind list"); 3221 return QDF_STATUS_E_FAILURE; 3222 } 3223 3224 do { 3225 node = next_node; 3226 ft_assoc_ind = qdf_container_of(node, struct ft_assoc_ind, node); 3227 if (qdf_mem_cmp(peer, 3228 ft_assoc_ind->assoc_ind->peerMacAddr, 3229 QDF_MAC_ADDR_SIZE) == 0) { 3230 status = qdf_list_remove_node(&sap_ctx->ft_pending_assoc_ind_list, 3231 node); 3232 if (status != QDF_STATUS_SUCCESS) { 3233 sap_err("Failed to remove ft assoc ind"); 3234 return status; 3235 } 3236 assoc_ind = ft_assoc_ind->assoc_ind; 3237 qdf_mem_free(ft_assoc_ind); 3238 break; 3239 } 3240 } while (QDF_STATUS_SUCCESS == 3241 qdf_list_peek_next(&sap_ctx->ft_pending_assoc_ind_list, 3242 node, &next_node)); 3243 3244 if (assoc_ind) { 3245 assoc_ind->ft_ie = ie; 3246 assoc_ind->ft_ie_len = ie_len; 3247 assoc_ind->ft_status = ft_status; 3248 status = sme_update_ft_info(mac, assoc_ind); 3249 qdf_mem_free(assoc_ind); 3250 } 3251 return status; 3252 } 3253 3254 bool wlansap_is_channel_present_in_acs_list(uint32_t freq, 3255 uint32_t *ch_freq_list, 3256 uint8_t ch_count) 3257 { 3258 uint8_t i; 3259 3260 for(i = 0; i < ch_count; i++) 3261 if (ch_freq_list[i] == freq) 3262 return true; 3263 3264 return false; 3265 } 3266 3267 QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, 3268 uint32_t *ch_freq_list, 3269 uint32_t *ch_cnt) 3270 { 3271 size_t ch_index; 3272 size_t target_ch_cnt = 0; 3273 3274 if (!sap_ctx || !ch_freq_list || !ch_cnt) { 3275 sap_err("NULL parameters"); 3276 return QDF_STATUS_E_FAULT; 3277 } 3278 3279 if (!sap_ctx->acs_cfg->acs_mode) { 3280 sap_debug("acs not enabled, no filtering required"); 3281 return QDF_STATUS_SUCCESS; 3282 } else if (!sap_ctx->acs_cfg->master_freq_list || 3283 !sap_ctx->acs_cfg->master_ch_list_count) { 3284 sap_err("Empty acs channel list"); 3285 return QDF_STATUS_E_FAULT; 3286 } 3287 3288 for (ch_index = 0; ch_index < *ch_cnt; ch_index++) { 3289 if (wlansap_is_channel_present_in_acs_list( 3290 ch_freq_list[ch_index], 3291 sap_ctx->acs_cfg->master_freq_list, 3292 sap_ctx->acs_cfg->master_ch_list_count)) 3293 ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index]; 3294 } 3295 3296 *ch_cnt = target_ch_cnt; 3297 3298 return QDF_STATUS_SUCCESS; 3299 } 3300 3301 bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx) 3302 { 3303 uint32_t i; 3304 uint32_t *ch_freq_list; 3305 3306 if (!sap_ctx || !sap_ctx->acs_cfg || 3307 !sap_ctx->acs_cfg->master_freq_list || 3308 !sap_ctx->acs_cfg->master_ch_list_count) { 3309 sap_err("NULL parameters"); 3310 return false; 3311 } 3312 ch_freq_list = sap_ctx->acs_cfg->master_freq_list; 3313 for (i = 0; i < sap_ctx->acs_cfg->master_ch_list_count; i++) { 3314 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i])) 3315 return true; 3316 } 3317 return false; 3318 } 3319 3320 #if defined(FEATURE_WLAN_CH_AVOID) 3321 /** 3322 * wlansap_select_chan_with_best_bandwidth() - Select channel with 3323 * max possible band width 3324 * @sap_ctx: sap context 3325 * @ch_freq_list: candidate channel frequency list 3326 * @ch_cnt: count of channel frequency in list 3327 * @selected_freq: selected channel frequency 3328 * @selected_ch_width: selected channel width 3329 * 3330 * Return: QDF_STATUS_SUCCESS if better channel selected 3331 */ 3332 static QDF_STATUS 3333 wlansap_select_chan_with_best_bandwidth(struct sap_context *sap_ctx, 3334 uint32_t *ch_freq_list, 3335 uint32_t ch_cnt, 3336 uint32_t *selected_freq, 3337 enum phy_ch_width *selected_ch_width) 3338 { 3339 struct mac_context *mac; 3340 struct ch_params ch_params = {0}; 3341 enum phy_ch_width ch_width; 3342 uint32_t center_freq, bw_val, bw_start, bw_end; 3343 uint16_t i, j; 3344 uint16_t unsafe_chan[NUM_CHANNELS]; 3345 uint16_t unsafe_chan_cnt = 0; 3346 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 3347 3348 if (!selected_ch_width || !selected_freq) 3349 return QDF_STATUS_E_INVAL; 3350 3351 if (!qdf_ctx) { 3352 sap_err("invalid qdf_ctx"); 3353 return QDF_STATUS_E_INVAL; 3354 } 3355 3356 if (!sap_ctx) { 3357 sap_err("invalid sap_ctx"); 3358 return QDF_STATUS_E_INVAL; 3359 } 3360 3361 mac = sap_get_mac_context(); 3362 if (!mac) { 3363 sap_err("Invalid MAC context"); 3364 return QDF_STATUS_E_INVAL; 3365 } 3366 3367 if (policy_mgr_mode_specific_connection_count(mac->psoc, 3368 PM_STA_MODE, 3369 NULL) || 3370 policy_mgr_mode_specific_connection_count(mac->psoc, 3371 PM_P2P_CLIENT_MODE, 3372 NULL) || 3373 policy_mgr_mode_specific_connection_count(mac->psoc, 3374 PM_P2P_GO_MODE, 3375 NULL)) { 3376 sap_debug("sta/p2p mode active, skip!"); 3377 return QDF_STATUS_E_INVAL; 3378 } 3379 3380 pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, 3381 &unsafe_chan_cnt, 3382 sizeof(uint16_t) * NUM_CHANNELS); 3383 unsafe_chan_cnt = QDF_MIN(unsafe_chan_cnt, NUM_CHANNELS); 3384 if (!unsafe_chan_cnt) 3385 return QDF_STATUS_E_INVAL; 3386 3387 ch_width = sap_ctx->ch_width_orig; 3388 next_lower_bw: 3389 for (i = 0; i < ch_cnt; i++) { 3390 if (!WLAN_REG_IS_SAME_BAND_FREQS(sap_ctx->chan_freq, 3391 ch_freq_list[i])) 3392 continue; 3393 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i]) && 3394 !WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(ch_freq_list[i])) 3395 continue; 3396 qdf_mem_zero(&ch_params, sizeof(ch_params)); 3397 ch_params.ch_width = ch_width; 3398 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, 3399 ch_freq_list[i], 3400 0, &ch_params, 3401 REG_CURRENT_PWR_MODE); 3402 if (!WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i]) && 3403 wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac->pdev, 3404 ch_freq_list[i], 3405 &ch_params, 3406 REG_CURRENT_PWR_MODE) != 3407 CHANNEL_STATE_ENABLE) 3408 continue; 3409 3410 bw_val = wlan_reg_get_bw_value(ch_params.ch_width); 3411 if (!ch_params.mhz_freq_seg0) 3412 continue; 3413 if (bw_val < wlan_reg_get_bw_value(ch_width)) 3414 continue; 3415 if (ch_params.mhz_freq_seg1) 3416 center_freq = ch_params.mhz_freq_seg1; 3417 else 3418 center_freq = ch_params.mhz_freq_seg0; 3419 3420 bw_start = center_freq - bw_val / 2 + 10; 3421 bw_end = center_freq + bw_val / 2 - 10; 3422 for (j = 0; j < unsafe_chan_cnt; j++) 3423 if (unsafe_chan[j] >= bw_start && 3424 unsafe_chan[j] <= bw_end) 3425 break; 3426 3427 if (j < unsafe_chan_cnt) { 3428 sap_debug("ch_freq %d bw %d bw start %d, bw end %d unsafe %d", 3429 ch_freq_list[i], bw_val, bw_start, bw_end, 3430 unsafe_chan[j]); 3431 continue; 3432 } 3433 sap_debug("ch_freq %d bw %d bw start %d, bw end %d", 3434 ch_freq_list[i], bw_val, bw_start, bw_end); 3435 /* found freq/bw pair which is safe for used as sap channel 3436 * avoidance csa target channel/bandwidth. 3437 */ 3438 *selected_freq = ch_freq_list[i]; 3439 *selected_ch_width = ch_params.ch_width; 3440 sap_debug("selected freq %d bw %d", *selected_freq, 3441 *selected_ch_width); 3442 3443 return QDF_STATUS_SUCCESS; 3444 } 3445 3446 ch_width = wlan_reg_get_next_lower_bandwidth(ch_width); 3447 if (!(wlan_reg_get_bw_value(ch_width) < 20 || 3448 ch_width == CH_WIDTH_INVALID)) 3449 goto next_lower_bw; 3450 3451 return QDF_STATUS_E_INVAL; 3452 } 3453 3454 /** 3455 * wlansap_get_safe_channel() - Get safe channel from current regulatory 3456 * @sap_ctx: Pointer to SAP context 3457 * @ch_width: selected channel bandwdith 3458 * @pref_band: Preferred channel band for sap 3459 * 3460 * This function is used to get safe channel from current regulatory valid 3461 * channels to restart SAP if failed to get safe channel from PCL. 3462 * 3463 * Return: Chan freq num to restart SAP in case of success. In case of any 3464 * failure, the channel number returned is zero. 3465 */ 3466 static uint32_t 3467 wlansap_get_safe_channel(struct sap_context *sap_ctx, 3468 enum phy_ch_width *ch_width, 3469 enum reg_wifi_band pref_band) 3470 { 3471 struct mac_context *mac; 3472 uint32_t pcl_freqs[NUM_CHANNELS]; 3473 QDF_STATUS status; 3474 mac_handle_t mac_handle; 3475 uint32_t pcl_len = 0, i; 3476 uint32_t selected_freq; 3477 enum policy_mgr_con_mode mode; 3478 uint32_t first_valid_dfs_5g_freq = 0; 3479 uint32_t first_valid_non_dfs_5g_freq = 0; 3480 uint32_t first_valid_6g_freq = 0; 3481 3482 if (!sap_ctx) { 3483 sap_err("NULL parameter"); 3484 return INVALID_CHANNEL_ID; 3485 } 3486 3487 mac = sap_get_mac_context(); 3488 if (!mac) { 3489 sap_err("Invalid MAC context"); 3490 return INVALID_CHANNEL_ID; 3491 } 3492 mac_handle = MAC_HANDLE(mac); 3493 3494 mode = policy_mgr_qdf_opmode_to_pm_con_mode(mac->psoc, 3495 QDF_SAP_MODE, 3496 sap_ctx->vdev_id); 3497 /* get the channel list for current domain */ 3498 status = policy_mgr_get_valid_chans(mac->psoc, pcl_freqs, &pcl_len); 3499 if (QDF_IS_STATUS_ERROR(status)) { 3500 sap_err("Error in getting valid channels"); 3501 return INVALID_CHANNEL_ID; 3502 } 3503 3504 status = wlansap_filter_ch_based_acs(sap_ctx, pcl_freqs, &pcl_len); 3505 3506 if (QDF_IS_STATUS_ERROR(status)) { 3507 sap_err("failed to filter ch from acs %d", status); 3508 return INVALID_CHANNEL_ID; 3509 } 3510 3511 if (pcl_len) { 3512 status = policy_mgr_get_valid_chans_from_range(mac->psoc, 3513 pcl_freqs, 3514 &pcl_len, 3515 mode); 3516 if (QDF_IS_STATUS_ERROR(status) || !pcl_len) { 3517 sap_err("failed to get valid channel: %d len %d", 3518 status, pcl_len); 3519 return INVALID_CHANNEL_ID; 3520 } 3521 3522 status = 3523 wlansap_select_chan_with_best_bandwidth(sap_ctx, 3524 pcl_freqs, 3525 pcl_len, 3526 &selected_freq, 3527 ch_width); 3528 if (QDF_IS_STATUS_SUCCESS(status)) 3529 return selected_freq; 3530 3531 for (i = 0; i < pcl_len; i++) { 3532 if (!first_valid_non_dfs_5g_freq && 3533 wlan_reg_is_5ghz_ch_freq(pcl_freqs[i])) { 3534 if (!wlan_reg_is_dfs_in_secondary_list_for_freq( 3535 mac->pdev, 3536 pcl_freqs[i])) { 3537 first_valid_non_dfs_5g_freq = pcl_freqs[i]; 3538 if (pref_band == REG_BAND_5G) 3539 break; 3540 } else if (!first_valid_dfs_5g_freq) { 3541 first_valid_dfs_5g_freq = pcl_freqs[i]; 3542 } 3543 } 3544 if (!first_valid_6g_freq && 3545 wlan_reg_is_6ghz_chan_freq(pcl_freqs[i])) { 3546 first_valid_6g_freq = pcl_freqs[i]; 3547 if (pref_band == REG_BAND_6G) 3548 break; 3549 } 3550 } 3551 3552 selected_freq = pcl_freqs[0]; 3553 3554 if (pref_band == REG_BAND_6G) { 3555 if (first_valid_6g_freq) 3556 selected_freq = first_valid_6g_freq; 3557 else if (first_valid_non_dfs_5g_freq) 3558 selected_freq = first_valid_non_dfs_5g_freq; 3559 else if (first_valid_dfs_5g_freq) 3560 selected_freq = first_valid_dfs_5g_freq; 3561 } else if (pref_band == REG_BAND_5G) { 3562 if (first_valid_non_dfs_5g_freq) 3563 selected_freq = first_valid_non_dfs_5g_freq; 3564 else if (first_valid_dfs_5g_freq) 3565 selected_freq = first_valid_dfs_5g_freq; 3566 } 3567 3568 sap_debug("select %d from valid channel list, pref band = %d", 3569 selected_freq, pref_band); 3570 return selected_freq; 3571 } 3572 3573 return INVALID_CHANNEL_ID; 3574 } 3575 #else 3576 /** 3577 * wlansap_select_chan_with_best_bandwidth() - Select channel with 3578 * max possible band width 3579 * @sap_ctx: sap context 3580 * @ch_freq_list: candidate channel frequency list 3581 * @ch_cnt: count of channel frequency in list 3582 * @selected_freq: selected channel frequency 3583 * @selected_ch_width: selected channel width 3584 * 3585 * Return: QDF_STATUS_SUCCESS if better channel selected 3586 */ 3587 static inline QDF_STATUS 3588 wlansap_select_chan_with_best_bandwidth(struct sap_context *sap_ctx, 3589 uint32_t *ch_freq_list, 3590 uint32_t ch_cnt, 3591 uint32_t *selected_freq, 3592 enum phy_ch_width *selected_ch_width) 3593 { 3594 return QDF_STATUS_E_NOSUPPORT; 3595 } 3596 3597 /** 3598 * wlansap_get_safe_channel() - Get safe channel from current regulatory 3599 * @sap_ctx: Pointer to SAP context 3600 * @ch_width: selected channel width 3601 * @pref_band: Preferred channel band for sap 3602 * 3603 * This function is used to get safe channel from current regulatory valid 3604 * channels to restart SAP if failed to get safe channel from PCL. 3605 * 3606 * Return: Channel number to restart SAP in case of success. In case of any 3607 * failure, the channel number returned is zero. 3608 */ 3609 static uint8_t 3610 wlansap_get_safe_channel(struct sap_context *sap_ctx, 3611 enum phy_ch_width *ch_width, 3612 enum reg_wifi_band pref_band) 3613 { 3614 return 0; 3615 } 3616 #endif 3617 3618 uint32_t 3619 wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx, 3620 enum phy_ch_width *ch_width) 3621 { 3622 struct mac_context *mac; 3623 struct sir_pcl_list pcl = {0}; 3624 uint32_t pcl_freqs[NUM_CHANNELS] = {0}; 3625 uint32_t select_freq; 3626 QDF_STATUS status; 3627 mac_handle_t mac_handle; 3628 uint32_t pcl_len = 0; 3629 enum policy_mgr_con_mode mode; 3630 3631 if (!sap_ctx) { 3632 sap_err("NULL parameter"); 3633 return INVALID_CHANNEL_ID; 3634 } 3635 3636 mac = sap_get_mac_context(); 3637 if (!mac) { 3638 sap_err("Invalid MAC context"); 3639 return INVALID_CHANNEL_ID; 3640 } 3641 mac_handle = MAC_HANDLE(mac); 3642 3643 if (policy_mgr_get_connection_count(mac->psoc) == 1) { 3644 sap_debug("only SAP present return best channel from ACS list"); 3645 return wlansap_get_safe_channel(sap_ctx, ch_width, REG_BAND_6G); 3646 } 3647 3648 mode = policy_mgr_qdf_opmode_to_pm_con_mode(mac->psoc, QDF_SAP_MODE, 3649 sap_ctx->vdev_id); 3650 3651 status = 3652 policy_mgr_get_pcl_for_scc_in_same_mode(mac->psoc, mode, 3653 pcl_freqs, &pcl_len, 3654 pcl.weight_list, 3655 QDF_ARRAY_SIZE(pcl.weight_list), 3656 sap_ctx->sessionId); 3657 3658 if (QDF_IS_STATUS_ERROR(status)) { 3659 sap_err("Get PCL failed"); 3660 return INVALID_CHANNEL_ID; 3661 } 3662 3663 if (pcl_len) { 3664 status = wlansap_filter_ch_based_acs(sap_ctx, pcl_freqs, 3665 &pcl_len); 3666 if (QDF_IS_STATUS_ERROR(status)) { 3667 sap_err("failed to filter ch from acs %d", status); 3668 return INVALID_CHANNEL_ID; 3669 } 3670 3671 if (wlansap_select_chan_with_best_bandwidth(sap_ctx, 3672 pcl_freqs, 3673 pcl_len, 3674 &select_freq, 3675 ch_width) == 3676 QDF_STATUS_SUCCESS) 3677 return select_freq; 3678 3679 if (pcl_len) { 3680 sap_debug("select %d from valid ch freq list", 3681 pcl_freqs[0]); 3682 return pcl_freqs[0]; 3683 } 3684 sap_debug("no safe channel from PCL found in ACS range"); 3685 } else { 3686 sap_debug("pcl length is zero!"); 3687 } 3688 3689 /* 3690 * In some scenarios, like hw dbs disabled, sap+sap case, if operating 3691 * channel is unsafe channel, the pcl may be empty, instead of return, 3692 * try to choose a safe channel from acs range. 3693 */ 3694 return wlansap_get_safe_channel(sap_ctx, ch_width, REG_BAND_6G); 3695 } 3696 3697 static uint32_t wlansap_get_2g_first_safe_chan_freq(struct sap_context *sap_ctx) 3698 { 3699 uint32_t i; 3700 uint32_t freq; 3701 enum channel_state state; 3702 struct regulatory_channel *cur_chan_list; 3703 struct wlan_objmgr_pdev *pdev; 3704 struct wlan_objmgr_psoc *psoc; 3705 uint32_t *acs_freq_list; 3706 uint8_t acs_list_count; 3707 3708 pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev; 3709 psoc = pdev->pdev_objmgr.wlan_psoc; 3710 3711 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * 3712 sizeof(struct regulatory_channel)); 3713 if (!cur_chan_list) 3714 return TWOG_CHAN_6_IN_MHZ; 3715 3716 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) != 3717 QDF_STATUS_SUCCESS) { 3718 freq = TWOG_CHAN_6_IN_MHZ; 3719 goto err; 3720 } 3721 3722 acs_freq_list = sap_ctx->acs_cfg->master_freq_list; 3723 acs_list_count = sap_ctx->acs_cfg->master_ch_list_count; 3724 for (i = 0; i < NUM_CHANNELS; i++) { 3725 freq = cur_chan_list[i].center_freq; 3726 state = wlan_reg_get_channel_state_for_pwrmode( 3727 pdev, freq, 3728 REG_CURRENT_PWR_MODE); 3729 if (state != CHANNEL_STATE_DISABLE && 3730 state != CHANNEL_STATE_PASSIVE && 3731 state != CHANNEL_STATE_INVALID && 3732 wlan_reg_is_24ghz_ch_freq(freq) && 3733 policy_mgr_is_safe_channel(psoc, freq) && 3734 wlansap_is_channel_present_in_acs_list(freq, 3735 acs_freq_list, 3736 acs_list_count)) { 3737 sap_debug("found a 2g channel: %d", freq); 3738 goto err; 3739 } 3740 } 3741 3742 freq = TWOG_CHAN_6_IN_MHZ; 3743 err: 3744 qdf_mem_free(cur_chan_list); 3745 return freq; 3746 } 3747 3748 uint32_t wlansap_get_safe_channel_from_pcl_for_sap(struct sap_context *sap_ctx) 3749 { 3750 struct wlan_objmgr_pdev *pdev; 3751 struct mac_context *mac; 3752 struct sir_pcl_list pcl = {0}; 3753 uint32_t pcl_freqs[NUM_CHANNELS] = {0}; 3754 QDF_STATUS status; 3755 uint32_t pcl_len = 0; 3756 enum policy_mgr_con_mode mode; 3757 3758 if (!sap_ctx) { 3759 sap_err("NULL parameter"); 3760 return INVALID_CHANNEL_ID; 3761 } 3762 3763 mac = sap_get_mac_context(); 3764 if (!mac) { 3765 sap_err("Invalid MAC context"); 3766 return INVALID_CHANNEL_ID; 3767 } 3768 3769 pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev; 3770 if (!pdev) { 3771 sap_err("NULL pdev"); 3772 } 3773 3774 mode = policy_mgr_qdf_opmode_to_pm_con_mode(mac->psoc, QDF_SAP_MODE, 3775 sap_ctx->vdev_id); 3776 3777 status = policy_mgr_get_pcl_for_vdev_id(mac->psoc, mode, 3778 pcl_freqs, &pcl_len, 3779 pcl.weight_list, 3780 QDF_ARRAY_SIZE(pcl.weight_list), 3781 sap_ctx->sessionId); 3782 3783 if (QDF_IS_STATUS_ERROR(status)) { 3784 sap_err("Get PCL failed"); 3785 return INVALID_CHANNEL_ID; 3786 } 3787 3788 if (pcl_len) { 3789 status = policy_mgr_filter_passive_ch(pdev, pcl_freqs, 3790 &pcl_len); 3791 if (QDF_IS_STATUS_ERROR(status)) { 3792 sap_err("failed to filter passive channels"); 3793 return INVALID_CHANNEL_ID; 3794 } 3795 3796 if (pcl_len) { 3797 sap_debug("select %d from valid ch freq list", 3798 pcl_freqs[0]); 3799 return pcl_freqs[0]; 3800 } 3801 sap_debug("no active channels found in PCL"); 3802 } else { 3803 sap_debug("pcl length is zero!"); 3804 } 3805 3806 if (mode == PM_LL_LT_SAP_MODE) 3807 return INVALID_CHANNEL_ID; 3808 3809 return wlansap_get_2g_first_safe_chan_freq(sap_ctx); 3810 } 3811 3812 int wlansap_update_sap_chan_list(struct sap_config *sap_config, 3813 qdf_freq_t *freq_list, uint16_t count) 3814 { 3815 uint32_t *acs_cfg_freq_list; 3816 uint32_t *master_freq_list; 3817 uint32_t i; 3818 bool old_acs_2g_only = true, acs_2g_only_new = true; 3819 3820 acs_cfg_freq_list = qdf_mem_malloc(count * sizeof(uint32_t)); 3821 if (!acs_cfg_freq_list) 3822 return -ENOMEM; 3823 if (sap_config->acs_cfg.ch_list_count) { 3824 qdf_mem_free(sap_config->acs_cfg.freq_list); 3825 sap_config->acs_cfg.freq_list = NULL; 3826 sap_config->acs_cfg.ch_list_count = 0; 3827 } 3828 sap_config->acs_cfg.freq_list = acs_cfg_freq_list; 3829 3830 master_freq_list = qdf_mem_malloc(count * sizeof(uint32_t)); 3831 if (!master_freq_list) 3832 return -ENOMEM; 3833 3834 if (sap_config->acs_cfg.master_ch_list_count) { 3835 for (i = 0; i < sap_config->acs_cfg.master_ch_list_count; i++) 3836 if (sap_config->acs_cfg.master_freq_list && 3837 !WLAN_REG_IS_24GHZ_CH_FREQ( 3838 sap_config->acs_cfg.master_freq_list[i])) { 3839 old_acs_2g_only = false; 3840 break; 3841 } 3842 qdf_mem_free(sap_config->acs_cfg.master_freq_list); 3843 sap_config->acs_cfg.master_freq_list = NULL; 3844 sap_config->acs_cfg.master_ch_list_count = 0; 3845 } 3846 sap_config->acs_cfg.master_freq_list = master_freq_list; 3847 3848 qdf_mem_copy(sap_config->acs_cfg.freq_list, freq_list, 3849 sizeof(freq_list[0]) * count); 3850 qdf_mem_copy(sap_config->acs_cfg.master_freq_list, freq_list, 3851 sizeof(freq_list[0]) * count); 3852 sap_config->acs_cfg.master_ch_list_count = count; 3853 sap_config->acs_cfg.ch_list_count = count; 3854 for (i = 0; i < sap_config->acs_cfg.master_ch_list_count; i++) 3855 if (sap_config->acs_cfg.master_freq_list && 3856 !WLAN_REG_IS_24GHZ_CH_FREQ( 3857 sap_config->acs_cfg.master_freq_list[i])) { 3858 acs_2g_only_new = false; 3859 break; 3860 } 3861 /* If SAP initially started on world mode, the SAP ACS master channel 3862 * list will only contain 2.4 GHz channels. When country code changed 3863 * from world mode to non world mode, the master_ch_list will 3864 * be updated by this API from userspace and the list will include 3865 * 2.4 GHz + 5/6 GHz normally. If this transition happens, we set 3866 * master_ch_list_updated flag. And later only if the flag is set, 3867 * wlansap_get_chan_band_restrict will be invoked to select new SAP 3868 * channel frequency based on PCL. 3869 */ 3870 sap_config->acs_cfg.master_ch_list_updated = 3871 old_acs_2g_only && !acs_2g_only_new; 3872 sap_dump_acs_channel(&sap_config->acs_cfg); 3873 3874 return 0; 3875 } 3876 3877 /** 3878 * wlansap_get_valid_freq() - To get valid freq for sap csa 3879 * @psoc: psoc object 3880 * @sap_ctx: sap context 3881 * @freq: pointer to valid freq 3882 * 3883 * If sap master channel list is updated from 2G only to 2G+5G/6G, 3884 * this API will find new SAP channel frequency likely 5G/6G to have 3885 * better performance for SAP. This happens when SAP started in 3886 * world mode, later country code change to non world mode. 3887 * 3888 * Return: None 3889 */ 3890 static 3891 void wlansap_get_valid_freq(struct wlan_objmgr_psoc *psoc, 3892 struct sap_context *sap_ctx, 3893 qdf_freq_t *freq) 3894 { 3895 uint8_t i, j; 3896 struct mac_context *mac; 3897 struct sir_pcl_list pcl = {0}; 3898 uint32_t *pcl_freqs; 3899 QDF_STATUS status; 3900 uint32_t pcl_len = 0; 3901 3902 if (!sap_ctx->acs_cfg || !sap_ctx->acs_cfg->master_ch_list_count) 3903 return; 3904 3905 if (!sap_ctx->acs_cfg->master_ch_list_updated) 3906 return; 3907 3908 sap_ctx->acs_cfg->master_ch_list_updated = false; 3909 3910 pcl_freqs = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t)); 3911 if (!pcl_freqs) 3912 return; 3913 3914 mac = sap_get_mac_context(); 3915 if (!mac) { 3916 sap_err("Invalid MAC context"); 3917 goto done; 3918 } 3919 status = policy_mgr_reset_sap_mandatory_channels(psoc); 3920 if (QDF_IS_STATUS_ERROR(status)) { 3921 sap_err("failed to reset mandatory channels"); 3922 goto done; 3923 } 3924 status = policy_mgr_get_pcl_for_vdev_id(mac->psoc, PM_SAP_MODE, 3925 pcl_freqs, &pcl_len, 3926 pcl.weight_list, 3927 NUM_CHANNELS, 3928 sap_ctx->sessionId); 3929 3930 if (QDF_IS_STATUS_ERROR(status)) { 3931 sap_err("Get PCL failed for session %d", sap_ctx->sessionId); 3932 goto done; 3933 } 3934 for (i = 0; i < pcl_len; i++) { 3935 for (j = 0; j < sap_ctx->acs_cfg->master_ch_list_count; j++) { 3936 /* 3937 * To keep valid freq list order same as pcl weightage 3938 * order pcl list index is compared with all the freq 3939 * provided by set wifi config. 3940 */ 3941 if (sap_ctx->acs_cfg->master_freq_list[j] == 3942 pcl_freqs[i]) { 3943 *freq = pcl_freqs[i]; 3944 goto done; 3945 } 3946 } 3947 } 3948 done: 3949 qdf_mem_free(pcl_freqs); 3950 pcl_freqs = NULL; 3951 } 3952 3953 qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx, 3954 enum sap_csa_reason_code *csa_reason) 3955 { 3956 uint32_t restart_freq; 3957 uint16_t intf_ch_freq; 3958 uint32_t phy_mode; 3959 struct mac_context *mac; 3960 uint8_t cc_mode; 3961 uint8_t vdev_id; 3962 enum reg_wifi_band sap_band; 3963 enum band_info band; 3964 bool sta_sap_scc_on_indoor_channel; 3965 qdf_freq_t freq = 0; 3966 struct ch_params ch_params = {0}; 3967 3968 if (!sap_ctx) { 3969 sap_err("sap_ctx NULL parameter"); 3970 return 0; 3971 } 3972 3973 if (!csa_reason) { 3974 sap_err("csa_reason is NULL"); 3975 return 0; 3976 } 3977 3978 if (cds_is_driver_recovering()) 3979 return 0; 3980 3981 mac = cds_get_context(QDF_MODULE_ID_PE); 3982 if (!mac) 3983 return 0; 3984 3985 if (ucfg_reg_get_band(mac->pdev, &band) != QDF_STATUS_SUCCESS) { 3986 sap_err("Failed to get current band config"); 3987 return 0; 3988 } 3989 sta_sap_scc_on_indoor_channel = 3990 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(mac->psoc); 3991 sap_band = wlan_reg_freq_to_band(sap_ctx->chan_freq); 3992 3993 sap_debug("SAP/Go current band: %d, pdev band capability: %d, cur freq %d (is valid %d), prev freq %d (is valid %d)", 3994 sap_band, band, sap_ctx->chan_freq, 3995 wlan_reg_is_enable_in_secondary_list_for_freq(mac->pdev, 3996 sap_ctx->chan_freq), 3997 sap_ctx->chan_freq_before_switch_band, 3998 wlan_reg_is_enable_in_secondary_list_for_freq(mac->pdev, 3999 sap_ctx->chan_freq_before_switch_band)); 4000 4001 if (sap_band == REG_BAND_5G && band == BIT(REG_BAND_2G)) { 4002 sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq; 4003 sap_ctx->chan_width_before_switch_band = 4004 sap_ctx->ch_params.ch_width; 4005 sap_debug("Save chan info before switch: %d, width: %d", 4006 sap_ctx->chan_freq, sap_ctx->ch_params.ch_width); 4007 restart_freq = wlansap_get_2g_first_safe_chan_freq(sap_ctx); 4008 if (restart_freq == 0) { 4009 sap_debug("use default chan 6"); 4010 restart_freq = TWOG_CHAN_6_IN_MHZ; 4011 } 4012 *csa_reason = CSA_REASON_BAND_RESTRICTED; 4013 } else if (sap_band == REG_BAND_2G && (band & BIT(REG_BAND_5G))) { 4014 if (sap_ctx->chan_freq_before_switch_band) { 4015 if (!wlan_reg_is_disable_in_secondary_list_for_freq( 4016 mac->pdev, 4017 sap_ctx->chan_freq_before_switch_band)) { 4018 restart_freq = 4019 sap_ctx->chan_freq_before_switch_band; 4020 sap_debug("Restore chan freq: %d", 4021 restart_freq); 4022 *csa_reason = CSA_REASON_BAND_RESTRICTED; 4023 } else { 4024 enum reg_wifi_band pref_band; 4025 4026 pref_band = 4027 wlan_reg_freq_to_band( 4028 sap_ctx->chan_freq_before_switch_band); 4029 restart_freq = 4030 policy_mgr_get_alternate_channel_for_sap( 4031 mac->psoc, 4032 sap_ctx->sessionId, 4033 sap_ctx->chan_freq, 4034 pref_band); 4035 if (restart_freq) { 4036 sap_debug("restart SAP on freq %d", 4037 restart_freq); 4038 *csa_reason = 4039 CSA_REASON_BAND_RESTRICTED; 4040 } else { 4041 sap_debug("Did not get valid freq for band %d remain on same channel", 4042 pref_band); 4043 return 0; 4044 } 4045 } 4046 } else { 4047 wlansap_get_valid_freq(mac->psoc, sap_ctx, &freq); 4048 if (!freq) 4049 return 0; 4050 4051 restart_freq = freq; 4052 sap_debug("restart SAP on freq %d", 4053 restart_freq); 4054 *csa_reason = CSA_REASON_BAND_RESTRICTED; 4055 } 4056 } else if (wlan_reg_is_disable_in_secondary_list_for_freq( 4057 mac->pdev, 4058 sap_ctx->chan_freq) && 4059 !utils_dfs_is_freq_in_nol(mac->pdev, sap_ctx->chan_freq)) { 4060 sap_debug("channel is disabled"); 4061 *csa_reason = CSA_REASON_CHAN_DISABLED; 4062 return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx, 4063 NULL); 4064 } else if (wlan_reg_is_passive_for_freq(mac->pdev, 4065 sap_ctx->chan_freq)) { 4066 sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq; 4067 sap_ctx->chan_width_before_switch_band = 4068 sap_ctx->ch_params.ch_width; 4069 sap_debug("Save chan info before switch: %d, width: %d", 4070 sap_ctx->chan_freq, sap_ctx->ch_params.ch_width); 4071 sap_debug("channel is passive"); 4072 *csa_reason = CSA_REASON_CHAN_PASSIVE; 4073 return wlansap_get_safe_channel_from_pcl_for_sap(sap_ctx); 4074 } else if (!policy_mgr_is_sap_freq_allowed(mac->psoc, 4075 sap_ctx->chan_freq)) { 4076 sap_debug("channel is unsafe"); 4077 *csa_reason = CSA_REASON_UNSAFE_CHANNEL; 4078 return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx, 4079 NULL); 4080 } else if (sap_band == REG_BAND_6G && 4081 wlan_reg_get_keep_6ghz_sta_cli_connection(mac->pdev)) { 4082 ch_params.ch_width = sap_ctx->ch_params.ch_width; 4083 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, 4084 sap_ctx->chan_freq, 4085 0, &ch_params, 4086 REG_CURRENT_PWR_MODE); 4087 if (sap_ctx->ch_params.ch_width != ch_params.ch_width) { 4088 sap_debug("Bonded 6GHz channels are disabled"); 4089 *csa_reason = CSA_REASON_BAND_RESTRICTED; 4090 return wlansap_get_safe_channel_from_pcl_and_acs_range( 4091 sap_ctx, NULL); 4092 } else { 4093 sap_debug("No need switch SAP/Go channel"); 4094 return sap_ctx->chan_freq; 4095 } 4096 } else { 4097 sap_debug("No need switch SAP/Go channel"); 4098 return sap_ctx->chan_freq; 4099 } 4100 cc_mode = sap_ctx->cc_switch_mode; 4101 phy_mode = sap_ctx->phyMode; 4102 vdev_id = wlan_vdev_get_id(sap_ctx->vdev); 4103 intf_ch_freq = sme_check_concurrent_channel_overlap( 4104 MAC_HANDLE(mac), 4105 restart_freq, 4106 phy_mode, 4107 cc_mode, vdev_id); 4108 if (intf_ch_freq) 4109 restart_freq = intf_ch_freq; 4110 if (restart_freq == sap_ctx->chan_freq) 4111 restart_freq = 0; 4112 4113 if (restart_freq) 4114 sap_debug("vdev: %d, CSA target freq: %d", vdev_id, 4115 restart_freq); 4116 4117 return restart_freq; 4118 } 4119 4120 static inline bool 4121 wlansap_ch_in_avoid_ranges(uint32_t ch_freq, 4122 struct pld_ch_avoid_ind_type *ch_avoid_ranges) 4123 { 4124 uint32_t i; 4125 4126 for (i = 0; i < ch_avoid_ranges->ch_avoid_range_cnt; i++) { 4127 if (ch_freq >= 4128 ch_avoid_ranges->avoid_freq_range[i].start_freq && 4129 ch_freq <= 4130 ch_avoid_ranges->avoid_freq_range[i].end_freq) 4131 return true; 4132 } 4133 4134 return false; 4135 } 4136 4137 bool wlansap_filter_vendor_unsafe_ch_freq( 4138 struct sap_context *sap_context, struct sap_config *sap_config) 4139 { 4140 struct pld_ch_avoid_ind_type ch_avoid_ranges; 4141 uint32_t i, j; 4142 int ret; 4143 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 4144 struct mac_context *mac; 4145 uint32_t count; 4146 4147 if (!qdf_ctx) 4148 return false; 4149 mac = sap_get_mac_context(); 4150 if (!mac) 4151 return false; 4152 4153 count = policy_mgr_get_sap_mode_count(mac->psoc, NULL); 4154 4155 if (count != policy_mgr_get_connection_count(mac->psoc)) 4156 return false; 4157 4158 ch_avoid_ranges.ch_avoid_range_cnt = 0; 4159 ret = pld_get_wlan_unsafe_channel_sap(qdf_ctx->dev, &ch_avoid_ranges); 4160 if (ret) { 4161 sap_debug("failed to get vendor unsafe ch range, ret %d", ret); 4162 return false; 4163 } 4164 if (!ch_avoid_ranges.ch_avoid_range_cnt) 4165 return false; 4166 for (i = 0; i < ch_avoid_ranges.ch_avoid_range_cnt; i++) { 4167 sap_debug("vendor unsafe range[%d] %d %d", i, 4168 ch_avoid_ranges.avoid_freq_range[i].start_freq, 4169 ch_avoid_ranges.avoid_freq_range[i].end_freq); 4170 } 4171 for (i = 0, j = 0; i < sap_config->acs_cfg.ch_list_count; i++) { 4172 if (!wlansap_ch_in_avoid_ranges( 4173 sap_config->acs_cfg.freq_list[i], 4174 &ch_avoid_ranges)) 4175 sap_config->acs_cfg.freq_list[j++] = 4176 sap_config->acs_cfg.freq_list[i]; 4177 } 4178 sap_config->acs_cfg.ch_list_count = j; 4179 4180 return true; 4181 } 4182 4183 #ifdef DCS_INTERFERENCE_DETECTION 4184 QDF_STATUS wlansap_dcs_set_vdev_wlan_interference_mitigation( 4185 struct sap_context *sap_context, 4186 bool wlan_interference_mitigation_enable) 4187 { 4188 struct mac_context *mac; 4189 4190 if (!sap_context) { 4191 sap_err("Invalid SAP context pointer"); 4192 return QDF_STATUS_E_FAULT; 4193 } 4194 4195 mac = sap_get_mac_context(); 4196 if (!mac) { 4197 sap_err("Invalid MAC context"); 4198 return QDF_STATUS_E_FAULT; 4199 } 4200 4201 mac->sap.dcs_info. 4202 wlan_interference_mitigation_enable[sap_context->sessionId] = 4203 wlan_interference_mitigation_enable; 4204 4205 return QDF_STATUS_SUCCESS; 4206 } 4207 4208 QDF_STATUS wlansap_dcs_set_wlan_interference_mitigation_on_band( 4209 struct sap_context *sap_context, 4210 struct sap_config *sap_cfg) 4211 { 4212 QDF_STATUS status = QDF_STATUS_SUCCESS; 4213 bool wlan_interference_mitigation_enable = false; 4214 4215 if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_cfg->acs_cfg.pri_ch_freq)) 4216 wlan_interference_mitigation_enable = true; 4217 4218 status = wlansap_dcs_set_vdev_wlan_interference_mitigation( 4219 sap_context, 4220 wlan_interference_mitigation_enable); 4221 return status; 4222 } 4223 4224 QDF_STATUS wlansap_dcs_set_vdev_starting(struct sap_context *sap_context, 4225 bool vdev_starting) 4226 { 4227 struct mac_context *mac; 4228 4229 if (!sap_context) { 4230 sap_err("Invalid SAP context pointer"); 4231 return QDF_STATUS_E_FAULT; 4232 } 4233 4234 mac = sap_get_mac_context(); 4235 if (!mac) { 4236 sap_err("Invalid MAC context"); 4237 return QDF_STATUS_E_FAULT; 4238 } 4239 4240 mac->sap.dcs_info.is_vdev_starting[sap_context->sessionId] = 4241 vdev_starting; 4242 4243 return QDF_STATUS_SUCCESS; 4244 } 4245 4246 bool wlansap_dcs_is_wlan_interference_mitigation_enabled( 4247 struct sap_context *sap_context) 4248 { 4249 struct mac_context *mac; 4250 4251 if (!sap_context) { 4252 sap_err("Invalid SAP context pointer"); 4253 return false; 4254 } 4255 4256 mac = sap_get_mac_context(); 4257 if (!mac) { 4258 sap_err("Invalid MAC context"); 4259 return false; 4260 } 4261 4262 return mac->sap.dcs_info. 4263 wlan_interference_mitigation_enable[sap_context->sessionId]; 4264 } 4265 4266 qdf_freq_t wlansap_dcs_get_freq(struct sap_context *sap_context) 4267 { 4268 if (!sap_context) { 4269 sap_err("Invalid SAP context pointer"); 4270 return false; 4271 } 4272 4273 return sap_context->dcs_ch_freq; 4274 } 4275 4276 void wlansap_dump_acs_ch_freq(struct sap_context *sap_context) 4277 { 4278 if (!sap_context) { 4279 sap_err("Invalid sap_debug"); 4280 return; 4281 } 4282 4283 if (sap_context->fsm_state == SAP_STARTED) 4284 sap_info("ACS dump DCS freq=%d", sap_context->dcs_ch_freq); 4285 else 4286 sap_info("ACS dump ch_freq=%d", sap_context->chan_freq); 4287 } 4288 4289 void wlansap_set_acs_ch_freq(struct sap_context *sap_context, 4290 qdf_freq_t ch_freq) 4291 { 4292 if (!sap_context) { 4293 sap_err("Invalid sap_debug"); 4294 return; 4295 } 4296 4297 if (sap_context->fsm_state == SAP_STARTED) { 4298 sap_context->dcs_ch_freq = ch_freq; 4299 sap_debug("ACS configuring dcs_ch_freq=%d", 4300 sap_context->dcs_ch_freq); 4301 } else { 4302 sap_context->chan_freq = ch_freq; 4303 sap_debug("ACS configuring ch_freq=%d", 4304 sap_context->chan_freq); 4305 } 4306 } 4307 #else 4308 void wlansap_dump_acs_ch_freq(struct sap_context *sap_context) 4309 { 4310 if (!sap_context) { 4311 sap_err("Invalid sap_debug"); 4312 return; 4313 } 4314 4315 sap_info("ACS dump ch_freq=%d", sap_context->chan_freq); 4316 } 4317 4318 void wlansap_set_acs_ch_freq(struct sap_context *sap_context, 4319 qdf_freq_t ch_freq) 4320 { 4321 if (!sap_context) { 4322 sap_err("Invalid sap_debug"); 4323 return; 4324 } 4325 4326 sap_context->chan_freq = ch_freq; 4327 sap_debug("ACS configuring ch_freq=%d", sap_context->chan_freq); 4328 } 4329 #endif 4330 4331 #ifdef WLAN_FEATURE_11BE 4332 bool sap_phymode_is_eht(eCsrPhyMode phymode) 4333 { 4334 return CSR_IS_DOT11_PHY_MODE_11BE(phymode) || 4335 CSR_IS_DOT11_PHY_MODE_11BE_ONLY(phymode); 4336 } 4337 4338 bool sap_acs_is_puncture_applicable(struct sap_acs_cfg *acs_cfg) 4339 { 4340 bool is_eht_bw_80 = false; 4341 4342 if (!acs_cfg) { 4343 sap_err("Invalid parameters"); 4344 return is_eht_bw_80; 4345 } 4346 4347 switch (acs_cfg->ch_width) { 4348 case CH_WIDTH_80MHZ: 4349 case CH_WIDTH_80P80MHZ: 4350 case CH_WIDTH_160MHZ: 4351 case CH_WIDTH_320MHZ: 4352 is_eht_bw_80 = acs_cfg->is_eht_enabled; 4353 break; 4354 default: 4355 break; 4356 } 4357 4358 return is_eht_bw_80; 4359 } 4360 4361 void sap_acs_set_puncture_support(struct sap_context *sap_ctx, 4362 struct ch_params *ch_params) 4363 { 4364 if (!sap_ctx || !ch_params) { 4365 sap_err("Invalid parameters"); 4366 return; 4367 } 4368 4369 if (sap_acs_is_puncture_applicable(sap_ctx->acs_cfg)) 4370 ch_params->is_create_punc_bitmap = true; 4371 } 4372 #endif 4373 4374 void wlansap_update_ll_lt_sap_acs_result(struct sap_context *sap_ctx, 4375 qdf_freq_t last_acs_freq) 4376 { 4377 struct mac_context *mac; 4378 4379 mac = sap_get_mac_context(); 4380 if (!mac) { 4381 sap_err("Invalid MAC context"); 4382 return; 4383 } 4384 4385 if (!sap_ctx) { 4386 sap_err("Invalid sap context"); 4387 return; 4388 } 4389 4390 wlansap_set_acs_ch_freq(sap_ctx, last_acs_freq); 4391 sap_ctx->acs_cfg->pri_ch_freq = last_acs_freq; 4392 sap_ctx->acs_cfg->ht_sec_ch_freq = 0; 4393 } 4394 4395 QDF_STATUS wlansap_sort_channel_list(uint8_t vdev_id, qdf_list_t *list, 4396 struct sap_sel_ch_info *ch_info) 4397 { 4398 struct mac_context *mac_ctx; 4399 4400 mac_ctx = sap_get_mac_context(); 4401 if (!mac_ctx) { 4402 sap_err("Invalid MAC context"); 4403 return QDF_STATUS_E_FAILURE; 4404 } 4405 4406 sap_sort_channel_list(mac_ctx, vdev_id, list, 4407 ch_info, NULL, NULL); 4408 4409 return QDF_STATUS_SUCCESS; 4410 } 4411 4412 void wlansap_free_chan_info(struct sap_sel_ch_info *ch_param) 4413 { 4414 sap_chan_sel_exit(ch_param); 4415 } 4416 4417 void wlansap_get_user_config_acs_ch_list(uint8_t vdev_id, 4418 struct scan_filter *filter) 4419 { 4420 struct mac_context *mac_ctx; 4421 struct sap_context *sap_ctx; 4422 uint8_t ch_count = 0; 4423 4424 mac_ctx = sap_get_mac_context(); 4425 if (!mac_ctx) { 4426 sap_err("Invalid MAC context"); 4427 return; 4428 } 4429 4430 if (vdev_id >= WLAN_UMAC_VDEV_ID_MAX) 4431 return; 4432 4433 sap_ctx = mac_ctx->sap.sapCtxList[vdev_id].sap_context; 4434 4435 if (!sap_ctx) { 4436 sap_err("vdev %d sap_ctx is NULL", vdev_id); 4437 return; 4438 } 4439 4440 ch_count = sap_ctx->acs_cfg->master_ch_list_count; 4441 4442 if (!ch_count || ch_count > NUM_CHANNELS) 4443 return; 4444 4445 filter->num_of_channels = ch_count; 4446 qdf_mem_copy(filter->chan_freq_list, sap_ctx->acs_cfg->master_freq_list, 4447 filter->num_of_channels * 4448 sizeof(filter->chan_freq_list[0])); 4449 } 4450