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