1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_policy_mgr_get_set_utils.c 22 * 23 * WLAN Concurrenct Connection Management APIs 24 * 25 */ 26 27 /* Include files */ 28 #include "target_if.h" 29 #include "wlan_policy_mgr_api.h" 30 #include "wlan_policy_mgr_i.h" 31 #include "qdf_types.h" 32 #include "qdf_trace.h" 33 #include "wlan_objmgr_global_obj.h" 34 #include "wlan_objmgr_pdev_obj.h" 35 #include "wlan_objmgr_vdev_obj.h" 36 #include "wlan_nan_api.h" 37 #include "nan_public_structs.h" 38 #include "wlan_reg_services_api.h" 39 #include "wlan_cm_roam_public_struct.h" 40 #include "wlan_mlme_api.h" 41 #include "wlan_mlme_main.h" 42 #include "wlan_mlme_vdev_mgr_interface.h" 43 #include "wlan_mlo_mgr_sta.h" 44 #include "wlan_cm_ucfg_api.h" 45 #include "wlan_cm_roam_api.h" 46 #include "wlan_mlme_ucfg_api.h" 47 #include "wlan_p2p_ucfg_api.h" 48 #include "wlan_mlo_link_force.h" 49 50 /* invalid channel id. */ 51 #define INVALID_CHANNEL_ID 0 52 53 #define IS_FREQ_ON_MAC_ID(freq_range, freq, mac_id) \ 54 ((freq >= freq_range[mac_id].low_2ghz_freq && \ 55 freq <= freq_range[mac_id].high_2ghz_freq) || \ 56 (freq >= freq_range[mac_id].low_5ghz_freq && \ 57 freq <= freq_range[mac_id].high_5ghz_freq)) 58 59 /** 60 * policy_mgr_debug_alert() - fatal error alert 61 * 62 * This function will flush host drv log and 63 * disable all level logs. 64 * It can be called in fatal error detected in policy 65 * manager. 66 * This is to avoid host log overwritten in stress 67 * test to help issue debug. 68 * 69 * Return: none 70 */ 71 static void 72 policy_mgr_debug_alert(void) 73 { 74 int module_id; 75 int qdf_print_idx; 76 77 policy_mgr_err("fatal error detected to flush and pause host log"); 78 qdf_logging_flush_logs(); 79 qdf_print_idx = qdf_get_pidx(); 80 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++) 81 qdf_print_set_category_verbose( 82 qdf_print_idx, 83 module_id, QDF_TRACE_LEVEL_NONE, 84 0); 85 } 86 87 QDF_STATUS 88 policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc, 89 uint8_t *allow_mcc_go_diff_bi) 90 { 91 struct policy_mgr_psoc_priv_obj *pm_ctx; 92 93 pm_ctx = policy_mgr_get_context(psoc); 94 if (!pm_ctx) { 95 policy_mgr_err("pm_ctx is NULL"); 96 return QDF_STATUS_E_FAILURE; 97 } 98 *allow_mcc_go_diff_bi = pm_ctx->cfg.allow_mcc_go_diff_bi; 99 100 return QDF_STATUS_SUCCESS; 101 } 102 103 QDF_STATUS policy_mgr_set_dual_mac_feature(struct wlan_objmgr_psoc *psoc, 104 uint8_t dual_mac_feature) 105 { 106 struct policy_mgr_psoc_priv_obj *pm_ctx; 107 108 pm_ctx = policy_mgr_get_context(psoc); 109 if (!pm_ctx) { 110 policy_mgr_err("pm_ctx is NULL"); 111 return QDF_STATUS_E_FAILURE; 112 } 113 114 pm_ctx->cfg.dual_mac_feature = dual_mac_feature; 115 116 return QDF_STATUS_SUCCESS; 117 } 118 119 QDF_STATUS policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc *psoc, 120 uint8_t *dual_mac_feature) 121 { 122 struct policy_mgr_psoc_priv_obj *pm_ctx; 123 124 pm_ctx = policy_mgr_get_context(psoc); 125 if (!pm_ctx) { 126 policy_mgr_err("pm_ctx is NULL"); 127 return QDF_STATUS_E_FAILURE; 128 } 129 *dual_mac_feature = pm_ctx->cfg.dual_mac_feature; 130 131 return QDF_STATUS_SUCCESS; 132 } 133 134 QDF_STATUS policy_mgr_get_force_1x1(struct wlan_objmgr_psoc *psoc, 135 uint8_t *force_1x1) 136 { 137 struct policy_mgr_psoc_priv_obj *pm_ctx; 138 139 pm_ctx = policy_mgr_get_context(psoc); 140 if (!pm_ctx) { 141 policy_mgr_err("pm_ctx is NULL"); 142 return QDF_STATUS_E_FAILURE; 143 } 144 *force_1x1 = pm_ctx->cfg.is_force_1x1_enable; 145 146 return QDF_STATUS_SUCCESS; 147 } 148 149 uint32_t policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc) 150 { 151 struct policy_mgr_psoc_priv_obj *pm_ctx; 152 153 pm_ctx = policy_mgr_get_context(psoc); 154 if (!pm_ctx) { 155 policy_mgr_err("pm_ctx is NULL"); 156 return 0; 157 } 158 159 return pm_ctx->cfg.max_conc_cxns; 160 } 161 162 QDF_STATUS policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc *psoc, 163 uint32_t max_conc_cxns) 164 { 165 struct policy_mgr_psoc_priv_obj *pm_ctx; 166 167 pm_ctx = policy_mgr_get_context(psoc); 168 if (!pm_ctx) { 169 policy_mgr_err("pm_ctx is NULL"); 170 return QDF_STATUS_E_FAILURE; 171 } 172 173 policy_mgr_debug("set max_conc_cxns %d old %d", max_conc_cxns, 174 pm_ctx->cfg.max_conc_cxns); 175 pm_ctx->cfg.max_conc_cxns = max_conc_cxns; 176 177 return QDF_STATUS_SUCCESS; 178 } 179 180 QDF_STATUS 181 policy_mgr_set_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc, 182 uint8_t sta_sap_scc_on_dfs_chnl) 183 { 184 struct policy_mgr_psoc_priv_obj *pm_ctx; 185 186 pm_ctx = policy_mgr_get_context(psoc); 187 if (!pm_ctx) { 188 policy_mgr_err("pm_ctx is NULL"); 189 return QDF_STATUS_E_FAILURE; 190 } 191 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl = sta_sap_scc_on_dfs_chnl; 192 193 return QDF_STATUS_SUCCESS; 194 } 195 196 QDF_STATUS 197 policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc, 198 uint8_t *sta_sap_scc_on_dfs_chnl) 199 { 200 struct policy_mgr_psoc_priv_obj *pm_ctx; 201 202 pm_ctx = policy_mgr_get_context(psoc); 203 if (!pm_ctx) { 204 policy_mgr_err("pm_ctx is NULL"); 205 return QDF_STATUS_E_FAILURE; 206 } 207 *sta_sap_scc_on_dfs_chnl = pm_ctx->cfg.sta_sap_scc_on_dfs_chnl; 208 209 return QDF_STATUS_SUCCESS; 210 } 211 212 bool 213 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(struct wlan_objmgr_psoc *psoc) 214 { 215 struct policy_mgr_psoc_priv_obj *pm_ctx; 216 217 pm_ctx = policy_mgr_get_context(psoc); 218 if (!pm_ctx) { 219 policy_mgr_err("pm_ctx is NULL"); 220 return false; 221 } 222 223 return pm_ctx->cfg.sta_sap_scc_on_indoor_channel; 224 } 225 226 QDF_STATUS 227 policy_mgr_set_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc, 228 bool multi_sap_allowed_on_same_band) 229 { 230 struct policy_mgr_psoc_priv_obj *pm_ctx; 231 232 pm_ctx = policy_mgr_get_context(psoc); 233 if (!pm_ctx) { 234 policy_mgr_err("pm_ctx is NULL"); 235 return QDF_STATUS_E_FAILURE; 236 } 237 pm_ctx->cfg.multi_sap_allowed_on_same_band = 238 multi_sap_allowed_on_same_band; 239 240 return QDF_STATUS_SUCCESS; 241 } 242 243 QDF_STATUS 244 policy_mgr_get_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc, 245 bool *multi_sap_allowed_on_same_band) 246 { 247 struct policy_mgr_psoc_priv_obj *pm_ctx; 248 249 pm_ctx = policy_mgr_get_context(psoc); 250 if (!pm_ctx) { 251 policy_mgr_err("pm_ctx is NULL"); 252 return QDF_STATUS_E_FAILURE; 253 } 254 *multi_sap_allowed_on_same_band = 255 pm_ctx->cfg.multi_sap_allowed_on_same_band; 256 257 return QDF_STATUS_SUCCESS; 258 } 259 260 QDF_STATUS 261 policy_mgr_set_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc, 262 bool use_sap_original_bw) 263 { 264 struct policy_mgr_psoc_priv_obj *pm_ctx; 265 266 pm_ctx = policy_mgr_get_context(psoc); 267 if (!pm_ctx) { 268 policy_mgr_err("pm_ctx is NULL"); 269 return QDF_STATUS_E_FAILURE; 270 } 271 pm_ctx->cfg.use_sap_original_bw = use_sap_original_bw; 272 273 return QDF_STATUS_SUCCESS; 274 } 275 276 QDF_STATUS 277 policy_mgr_get_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc, 278 bool *use_sap_original_bw) 279 { 280 struct policy_mgr_psoc_priv_obj *pm_ctx; 281 282 pm_ctx = policy_mgr_get_context(psoc); 283 if (!pm_ctx) { 284 policy_mgr_err("pm_ctx is NULL"); 285 return QDF_STATUS_E_FAILURE; 286 } 287 *use_sap_original_bw = pm_ctx->cfg.use_sap_original_bw; 288 289 return QDF_STATUS_SUCCESS; 290 } 291 292 QDF_STATUS 293 policy_mgr_get_dfs_sta_sap_go_scc_movement(struct wlan_objmgr_psoc *psoc, 294 bool *move_sap_go_first) 295 { 296 struct policy_mgr_psoc_priv_obj *pm_ctx; 297 298 pm_ctx = policy_mgr_get_context(psoc); 299 if (!pm_ctx) { 300 policy_mgr_err("pm_ctx is NULL"); 301 return QDF_STATUS_E_FAILURE; 302 } 303 *move_sap_go_first = pm_ctx->cfg.move_sap_go_1st_on_dfs_sta_csa; 304 305 return QDF_STATUS_SUCCESS; 306 } 307 308 static bool 309 policy_mgr_update_dfs_master_dynamic_enabled( 310 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 311 { 312 struct policy_mgr_psoc_priv_obj *pm_ctx; 313 bool sta_on_5g = false; 314 bool sta_on_2g = false; 315 uint32_t i; 316 bool enable = true; 317 318 pm_ctx = policy_mgr_get_context(psoc); 319 if (!pm_ctx) { 320 policy_mgr_err("pm_ctx is NULL"); 321 return true; 322 } 323 324 if (!pm_ctx->cfg.sta_sap_scc_on_dfs_chnl) { 325 enable = true; 326 goto end; 327 } 328 if (pm_ctx->cfg.sta_sap_scc_on_dfs_chnl == 329 PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) { 330 enable = false; 331 goto end; 332 } 333 if (pm_ctx->cfg.sta_sap_scc_on_dfs_chnl != 334 PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) { 335 policy_mgr_debug("sta_sap_scc_on_dfs_chnl %d unknown", 336 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl); 337 enable = true; 338 goto end; 339 } 340 341 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 342 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 343 if (!((pm_conc_connection_list[i].vdev_id != vdev_id) && 344 pm_conc_connection_list[i].in_use && 345 (pm_conc_connection_list[i].mode == PM_STA_MODE || 346 pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE))) 347 continue; 348 if (WLAN_REG_IS_5GHZ_CH_FREQ(pm_conc_connection_list[i].freq)) 349 sta_on_5g = true; 350 else 351 sta_on_2g = true; 352 } 353 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 354 355 if (policy_mgr_is_hw_dbs_capable(psoc) && !sta_on_5g) 356 enable = true; 357 else if (!sta_on_5g && !sta_on_2g) 358 enable = true; 359 else 360 enable = false; 361 end: 362 pm_ctx->dynamic_dfs_master_disabled = !enable; 363 if (!enable) 364 policy_mgr_debug("sta_sap_scc_on_dfs_chnl %d sta_on_2g %d sta_on_5g %d enable %d", 365 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl, sta_on_2g, 366 sta_on_5g, enable); 367 368 return enable; 369 } 370 371 bool 372 policy_mgr_get_dfs_master_dynamic_enabled( 373 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 374 { 375 struct policy_mgr_psoc_priv_obj *pm_ctx; 376 377 pm_ctx = policy_mgr_get_context(psoc); 378 if (!pm_ctx) { 379 policy_mgr_err("pm_ctx is NULL"); 380 return true; 381 } 382 383 return policy_mgr_update_dfs_master_dynamic_enabled(psoc, vdev_id); 384 } 385 386 bool 387 policy_mgr_get_can_skip_radar_event(struct wlan_objmgr_psoc *psoc, 388 uint8_t vdev_id) 389 { 390 struct policy_mgr_psoc_priv_obj *pm_ctx; 391 392 pm_ctx = policy_mgr_get_context(psoc); 393 if (!pm_ctx) { 394 policy_mgr_err("pm_ctx is NULL"); 395 return false; 396 } 397 398 return pm_ctx->dynamic_dfs_master_disabled; 399 } 400 401 QDF_STATUS 402 policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc, 403 uint8_t *sta_sap_scc_lte_coex) 404 { 405 struct policy_mgr_psoc_priv_obj *pm_ctx; 406 407 pm_ctx = policy_mgr_get_context(psoc); 408 if (!pm_ctx) { 409 policy_mgr_err("pm_ctx is NULL"); 410 return QDF_STATUS_E_FAILURE; 411 } 412 *sta_sap_scc_lte_coex = pm_ctx->cfg.sta_sap_scc_on_lte_coex_chnl; 413 414 return QDF_STATUS_SUCCESS; 415 } 416 417 QDF_STATUS policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc, 418 uint8_t *sap_mandt_chnl) 419 { 420 struct policy_mgr_psoc_priv_obj *pm_ctx; 421 422 pm_ctx = policy_mgr_get_context(psoc); 423 if (!pm_ctx) { 424 policy_mgr_err("pm_ctx is NULL"); 425 return QDF_STATUS_E_FAILURE; 426 } 427 *sap_mandt_chnl = pm_ctx->cfg.sap_mandatory_chnl_enable; 428 429 return QDF_STATUS_SUCCESS; 430 } 431 432 QDF_STATUS 433 policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc, 434 uint8_t *indoor_chnl_marking) 435 { 436 struct policy_mgr_psoc_priv_obj *pm_ctx; 437 438 pm_ctx = policy_mgr_get_context(psoc); 439 if (!pm_ctx) { 440 policy_mgr_err("pm_ctx is NULL"); 441 return QDF_STATUS_E_FAILURE; 442 } 443 *indoor_chnl_marking = pm_ctx->cfg.mark_indoor_chnl_disable; 444 445 return QDF_STATUS_SUCCESS; 446 } 447 448 QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, 449 uint8_t *mcc_scc_switch) 450 { 451 struct policy_mgr_psoc_priv_obj *pm_ctx; 452 453 pm_ctx = policy_mgr_get_context(psoc); 454 if (!pm_ctx) { 455 policy_mgr_err("pm_ctx is NULL"); 456 return QDF_STATUS_E_FAILURE; 457 } 458 *mcc_scc_switch = pm_ctx->cfg.mcc_to_scc_switch; 459 460 return QDF_STATUS_SUCCESS; 461 } 462 463 QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, 464 uint8_t *sys_pref) 465 { 466 struct policy_mgr_psoc_priv_obj *pm_ctx; 467 468 pm_ctx = policy_mgr_get_context(psoc); 469 if (!pm_ctx) { 470 policy_mgr_err("pm_ctx is NULL"); 471 return QDF_STATUS_E_FAILURE; 472 } 473 *sys_pref = pm_ctx->cfg.sys_pref; 474 475 return QDF_STATUS_SUCCESS; 476 } 477 478 QDF_STATUS policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc, 479 uint8_t sys_pref) 480 { 481 struct policy_mgr_psoc_priv_obj *pm_ctx; 482 483 pm_ctx = policy_mgr_get_context(psoc); 484 if (!pm_ctx) { 485 policy_mgr_err("pm_ctx is NULL"); 486 return QDF_STATUS_E_FAILURE; 487 } 488 pm_ctx->cfg.sys_pref = sys_pref; 489 490 return QDF_STATUS_SUCCESS; 491 } 492 493 QDF_STATUS policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc, 494 uint8_t *conc_rule1) 495 { 496 struct policy_mgr_psoc_priv_obj *pm_ctx; 497 498 pm_ctx = policy_mgr_get_context(psoc); 499 if (!pm_ctx) { 500 policy_mgr_err("pm_ctx is NULL"); 501 return QDF_STATUS_E_FAILURE; 502 } 503 *conc_rule1 = pm_ctx->cfg.conc_rule1; 504 505 return QDF_STATUS_SUCCESS; 506 } 507 508 QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, 509 uint8_t *conc_rule2) 510 { 511 struct policy_mgr_psoc_priv_obj *pm_ctx; 512 513 pm_ctx = policy_mgr_get_context(psoc); 514 if (!pm_ctx) { 515 policy_mgr_err("pm_ctx is NULL"); 516 return QDF_STATUS_E_FAILURE; 517 } 518 *conc_rule2 = pm_ctx->cfg.conc_rule2; 519 520 return QDF_STATUS_SUCCESS; 521 } 522 523 QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, 524 uint32_t *chnl_select_plcy) 525 { 526 struct policy_mgr_psoc_priv_obj *pm_ctx; 527 528 pm_ctx = policy_mgr_get_context(psoc); 529 if (!pm_ctx) { 530 policy_mgr_err("pm_ctx is NULL"); 531 return QDF_STATUS_E_FAILURE; 532 } 533 *chnl_select_plcy = pm_ctx->cfg.chnl_select_plcy; 534 535 return QDF_STATUS_SUCCESS; 536 } 537 538 QDF_STATUS policy_mgr_set_ch_select_plcy(struct wlan_objmgr_psoc *psoc, 539 uint32_t ch_select_policy) 540 { 541 struct policy_mgr_psoc_priv_obj *pm_ctx; 542 543 pm_ctx = policy_mgr_get_context(psoc); 544 if (!pm_ctx) { 545 policy_mgr_err("pm_ctx is NULL"); 546 return QDF_STATUS_E_FAILURE; 547 } 548 pm_ctx->cfg.chnl_select_plcy = ch_select_policy; 549 550 return QDF_STATUS_SUCCESS; 551 } 552 553 QDF_STATUS policy_mgr_set_dynamic_mcc_adaptive_sch( 554 struct wlan_objmgr_psoc *psoc, 555 bool dynamic_mcc_adaptive_sched) 556 { 557 struct policy_mgr_psoc_priv_obj *pm_ctx; 558 559 pm_ctx = policy_mgr_get_context(psoc); 560 if (!pm_ctx) { 561 policy_mgr_err("pm_ctx is NULL"); 562 return QDF_STATUS_E_FAILURE; 563 } 564 pm_ctx->dynamic_mcc_adaptive_sched = dynamic_mcc_adaptive_sched; 565 566 return QDF_STATUS_SUCCESS; 567 } 568 569 QDF_STATUS policy_mgr_get_dynamic_mcc_adaptive_sch( 570 struct wlan_objmgr_psoc *psoc, 571 bool *dynamic_mcc_adaptive_sched) 572 { 573 struct policy_mgr_psoc_priv_obj *pm_ctx; 574 575 pm_ctx = policy_mgr_get_context(psoc); 576 if (!pm_ctx) { 577 policy_mgr_err("pm_ctx is NULL"); 578 return QDF_STATUS_E_FAILURE; 579 } 580 *dynamic_mcc_adaptive_sched = pm_ctx->dynamic_mcc_adaptive_sched; 581 582 return QDF_STATUS_SUCCESS; 583 } 584 585 QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, 586 bool *enable_mcc_adaptive_sch) 587 { 588 struct policy_mgr_psoc_priv_obj *pm_ctx; 589 590 pm_ctx = policy_mgr_get_context(psoc); 591 if (!pm_ctx) { 592 policy_mgr_err("pm_ctx is NULL"); 593 return QDF_STATUS_E_FAILURE; 594 } 595 *enable_mcc_adaptive_sch = pm_ctx->cfg.enable_mcc_adaptive_sch; 596 597 return QDF_STATUS_SUCCESS; 598 } 599 600 QDF_STATUS policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc, 601 uint8_t *enable_sta_cxn_5g_band) 602 { 603 struct policy_mgr_psoc_priv_obj *pm_ctx; 604 605 pm_ctx = policy_mgr_get_context(psoc); 606 if (!pm_ctx) { 607 policy_mgr_err("pm_ctx is NULL"); 608 return QDF_STATUS_E_FAILURE; 609 } 610 *enable_sta_cxn_5g_band = pm_ctx->cfg.enable_sta_cxn_5g_band; 611 612 return QDF_STATUS_SUCCESS; 613 } 614 615 void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, 616 uint32_t new_hw_mode_index) 617 { 618 struct policy_mgr_psoc_priv_obj *pm_ctx; 619 620 pm_ctx = policy_mgr_get_context(psoc); 621 if (!pm_ctx) { 622 policy_mgr_err("Invalid Context"); 623 return; 624 } 625 pm_ctx->new_hw_mode_index = new_hw_mode_index; 626 } 627 628 void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc, 629 uint32_t old_hw_mode_index) 630 { 631 struct policy_mgr_psoc_priv_obj *pm_ctx; 632 633 pm_ctx = policy_mgr_get_context(psoc); 634 if (!pm_ctx) { 635 policy_mgr_err("Invalid Context"); 636 return; 637 } 638 pm_ctx->old_hw_mode_index = old_hw_mode_index; 639 } 640 641 void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc, 642 uint32_t new_hw_mode_index) 643 { 644 struct policy_mgr_psoc_priv_obj *pm_ctx; 645 646 pm_ctx = policy_mgr_get_context(psoc); 647 if (!pm_ctx) { 648 policy_mgr_err("Invalid Context"); 649 return; 650 } 651 if (POLICY_MGR_DEFAULT_HW_MODE_INDEX == pm_ctx->new_hw_mode_index) { 652 pm_ctx->new_hw_mode_index = new_hw_mode_index; 653 } else { 654 pm_ctx->old_hw_mode_index = pm_ctx->new_hw_mode_index; 655 pm_ctx->new_hw_mode_index = new_hw_mode_index; 656 } 657 policy_mgr_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d", 658 pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index); 659 } 660 661 /** 662 * policy_mgr_get_num_of_setbits_from_bitmask() - to get num of 663 * setbits from bitmask 664 * @mask: given bitmask 665 * 666 * This helper function should return number of setbits from bitmask 667 * 668 * Return: number of setbits from bitmask 669 */ 670 static uint32_t policy_mgr_get_num_of_setbits_from_bitmask(uint32_t mask) 671 { 672 uint32_t num_of_setbits = 0; 673 674 while (mask) { 675 mask &= (mask - 1); 676 num_of_setbits++; 677 } 678 return num_of_setbits; 679 } 680 681 /** 682 * policy_mgr_map_wmi_channel_width_to_hw_mode_bw() - returns 683 * bandwidth in terms of hw_mode_bandwidth 684 * @width: bandwidth in terms of wmi_channel_width 685 * 686 * This function returns the bandwidth in terms of hw_mode_bandwidth. 687 * 688 * Return: BW in terms of hw_mode_bandwidth. 689 */ 690 static enum hw_mode_bandwidth policy_mgr_map_wmi_channel_width_to_hw_mode_bw( 691 wmi_channel_width width) 692 { 693 switch (width) { 694 case WMI_CHAN_WIDTH_20: 695 return HW_MODE_20_MHZ; 696 case WMI_CHAN_WIDTH_40: 697 return HW_MODE_40_MHZ; 698 case WMI_CHAN_WIDTH_80: 699 return HW_MODE_80_MHZ; 700 case WMI_CHAN_WIDTH_160: 701 return HW_MODE_160_MHZ; 702 case WMI_CHAN_WIDTH_80P80: 703 return HW_MODE_80_PLUS_80_MHZ; 704 case WMI_CHAN_WIDTH_5: 705 return HW_MODE_5_MHZ; 706 case WMI_CHAN_WIDTH_10: 707 return HW_MODE_10_MHZ; 708 #ifdef WLAN_FEATURE_11BE 709 case WMI_CHAN_WIDTH_320: 710 return HW_MODE_320_MHZ; 711 #endif 712 default: 713 return HW_MODE_BW_NONE; 714 } 715 716 return HW_MODE_BW_NONE; 717 } 718 719 static void policy_mgr_get_hw_mode_params( 720 struct wlan_psoc_host_mac_phy_caps *caps, 721 struct policy_mgr_mac_ss_bw_info *info) 722 { 723 qdf_freq_t max_5g_freq; 724 725 if (!caps) { 726 policy_mgr_err("Invalid capabilities"); 727 return; 728 } 729 730 info->mac_tx_stream = policy_mgr_get_num_of_setbits_from_bitmask( 731 QDF_MAX(caps->tx_chain_mask_2G, 732 caps->tx_chain_mask_5G)); 733 info->mac_rx_stream = policy_mgr_get_num_of_setbits_from_bitmask( 734 QDF_MAX(caps->rx_chain_mask_2G, 735 caps->rx_chain_mask_5G)); 736 info->mac_bw = policy_mgr_map_wmi_channel_width_to_hw_mode_bw( 737 QDF_MAX(caps->max_bw_supported_2G, 738 caps->max_bw_supported_5G)); 739 info->mac_band_cap = caps->supported_bands; 740 741 if (caps->supported_bands & WMI_HOST_WLAN_5G_CAPABILITY) { 742 max_5g_freq = wlan_reg_max_6ghz_chan_freq() ? 743 wlan_reg_max_6ghz_chan_freq() : 744 wlan_reg_max_5ghz_chan_freq(); 745 max_5g_freq = caps->reg_cap_ext.high_5ghz_chan ? 746 QDF_MIN(caps->reg_cap_ext.high_5ghz_chan, 747 max_5g_freq) : max_5g_freq; 748 info->support_6ghz_band = 749 max_5g_freq > wlan_reg_min_6ghz_chan_freq(); 750 } 751 } 752 753 /** 754 * policy_mgr_set_hw_mode_params() - sets TX-RX stream, 755 * bandwidth and DBS in hw_mode_list 756 * @psoc: PSOC object information 757 * @mac0_ss_bw_info: TX-RX streams, BW for MAC0 758 * @mac1_ss_bw_info: TX-RX streams, BW for MAC1 759 * @pos: refers to hw_mode_list array index 760 * @hw_mode_id: hw mode id value used by firmware 761 * @dbs_mode: dbs_mode for the dbs_hw_mode 762 * @sbs_mode: sbs_mode for the sbs_hw_mode 763 * @emlsr_mode: emlsr_mode for the emlsr_hw_mode 764 * 765 * This function sets TX-RX stream, bandwidth and DBS mode in 766 * hw_mode_list. 767 * 768 * Return: none 769 */ 770 static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc, 771 struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info, 772 struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info, 773 uint32_t pos, uint32_t hw_mode_id, uint32_t dbs_mode, 774 uint32_t sbs_mode, uint64_t emlsr_mode) 775 { 776 struct policy_mgr_psoc_priv_obj *pm_ctx; 777 uint64_t legacy_hwmode_lst; 778 779 pm_ctx = policy_mgr_get_context(psoc); 780 if (!pm_ctx) { 781 policy_mgr_err("Invalid Context"); 782 return; 783 } 784 785 POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET( 786 pm_ctx->hw_mode.hw_mode_list[pos], 787 mac0_ss_bw_info.mac_tx_stream); 788 POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET( 789 pm_ctx->hw_mode.hw_mode_list[pos], 790 mac0_ss_bw_info.mac_rx_stream); 791 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET( 792 pm_ctx->hw_mode.hw_mode_list[pos], 793 mac0_ss_bw_info.mac_bw); 794 POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET( 795 pm_ctx->hw_mode.hw_mode_list[pos], 796 mac1_ss_bw_info.mac_tx_stream); 797 POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET( 798 pm_ctx->hw_mode.hw_mode_list[pos], 799 mac1_ss_bw_info.mac_rx_stream); 800 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET( 801 pm_ctx->hw_mode.hw_mode_list[pos], 802 mac1_ss_bw_info.mac_bw); 803 POLICY_MGR_HW_MODE_DBS_MODE_SET( 804 pm_ctx->hw_mode.hw_mode_list[pos], 805 dbs_mode); 806 POLICY_MGR_HW_MODE_AGILE_DFS_SET( 807 pm_ctx->hw_mode.hw_mode_list[pos], 808 HW_MODE_AGILE_DFS_NONE); 809 POLICY_MGR_HW_MODE_SBS_MODE_SET( 810 pm_ctx->hw_mode.hw_mode_list[pos], 811 sbs_mode); 812 POLICY_MGR_HW_MODE_MAC0_BAND_SET( 813 pm_ctx->hw_mode.hw_mode_list[pos], 814 mac0_ss_bw_info.mac_band_cap); 815 POLICY_MGR_HW_MODE_ID_SET( 816 pm_ctx->hw_mode.hw_mode_list[pos], 817 hw_mode_id); 818 819 legacy_hwmode_lst = pm_ctx->hw_mode.hw_mode_list[pos]; 820 POLICY_MGR_HW_MODE_EMLSR_MODE_SET( 821 pm_ctx->hw_mode.hw_mode_list[pos], 822 legacy_hwmode_lst, emlsr_mode); 823 } 824 825 QDF_STATUS policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc *psoc, 826 struct radio_combination *comb, 827 uint32_t comb_max, 828 uint32_t *comb_num) 829 { 830 struct policy_mgr_psoc_priv_obj *pm_ctx; 831 struct radio_combination *radio_comb; 832 uint32_t i; 833 bool dbs_or_sbs_enabled = false; 834 835 pm_ctx = policy_mgr_get_context(psoc); 836 if (!pm_ctx) { 837 policy_mgr_err("Invalid Context"); 838 return QDF_STATUS_E_FAILURE; 839 } 840 841 *comb_num = 0; 842 if (policy_mgr_is_hw_dbs_capable(psoc) || 843 policy_mgr_is_hw_sbs_capable(psoc)) 844 dbs_or_sbs_enabled = true; 845 846 for (i = 0; i < pm_ctx->radio_comb_num; i++) { 847 radio_comb = &pm_ctx->radio_combinations[i]; 848 if (!dbs_or_sbs_enabled && radio_comb->hw_mode != MODE_SMM) 849 continue; 850 if (*comb_num >= comb_max) { 851 policy_mgr_err("out of buffer %d max %d", 852 pm_ctx->radio_comb_num, 853 comb_max); 854 return QDF_STATUS_E_FAILURE; 855 } 856 policy_mgr_debug("radio %d: mode %d mac0 (0x%x, 0x%x), mac1 (0x%x 0x%x)", 857 *comb_num, 858 radio_comb->hw_mode, 859 radio_comb->band_mask[0], 860 radio_comb->antenna[0], 861 radio_comb->band_mask[1], 862 radio_comb->antenna[1]); 863 qdf_mem_copy(&comb[*comb_num], radio_comb, 864 sizeof(*radio_comb)); 865 (*comb_num)++; 866 } 867 868 return QDF_STATUS_SUCCESS; 869 } 870 871 /** 872 * policy_mgr_add_radio_comb() - Add radio combination 873 * @pm_ctx: bandwidth in terms of wmi_channel_width 874 * @radio: radio combination 875 * 876 * This function adds one radio combination to list 877 * 878 * Return: void 879 */ 880 static void policy_mgr_add_radio_comb(struct policy_mgr_psoc_priv_obj *pm_ctx, 881 struct radio_combination *radio) 882 { 883 uint32_t i; 884 struct radio_combination *comb; 885 886 /* don't add duplicated item */ 887 for (i = 0; i < pm_ctx->radio_comb_num; i++) { 888 comb = &pm_ctx->radio_combinations[i]; 889 if (radio->hw_mode == comb->hw_mode && 890 radio->band_mask[0] == comb->band_mask[0] && 891 radio->band_mask[1] == comb->band_mask[1] && 892 radio->antenna[0] == comb->antenna[0] && 893 radio->antenna[1] == comb->antenna[1]) 894 return; 895 } 896 if (pm_ctx->radio_comb_num == MAX_RADIO_COMBINATION) { 897 policy_mgr_err("radio combination overflow %d", 898 pm_ctx->radio_comb_num); 899 return; 900 } 901 policy_mgr_debug("radio %d: mode %d mac0 (0x%x, 0x%x), mac1 (0x%x 0x%x)", 902 pm_ctx->radio_comb_num, 903 radio->hw_mode, 904 radio->band_mask[0], 905 radio->antenna[0], 906 radio->band_mask[1], 907 radio->antenna[1]); 908 909 qdf_mem_copy(&pm_ctx->radio_combinations[pm_ctx->radio_comb_num], 910 radio, sizeof(*radio)); 911 pm_ctx->radio_comb_num++; 912 } 913 914 #define SET_RADIO(_radio, _mode, _mac0_band, _mac1_band,\ 915 _mac0_antenna, _mac1_antenna) \ 916 do { \ 917 (_radio)->hw_mode = _mode; \ 918 (_radio)->band_mask[0] = _mac0_band; \ 919 (_radio)->band_mask[1] = _mac1_band; \ 920 (_radio)->antenna[0] = _mac0_antenna; \ 921 (_radio)->antenna[1] = _mac1_antenna; \ 922 } while (0) 923 924 /** 925 * policy_mgr_update_radio_combination_matrix() - Update radio combination 926 * list 927 * @psoc: psoc object 928 * @mac0_ss_bw_info: mac 0 band/bw info 929 * @mac1_ss_bw_info: mac 1 band/bw info 930 * @dbs_mode: dbs mode 931 * @sbs_mode: sbs mode 932 * 933 * This function updates radio combination list based on hw mode information. 934 * 935 * Return: void 936 */ 937 static void 938 policy_mgr_update_radio_combination_matrix( 939 struct wlan_objmgr_psoc *psoc, 940 struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info, 941 struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info, 942 uint32_t dbs_mode, uint32_t sbs_mode) 943 { 944 struct policy_mgr_psoc_priv_obj *pm_ctx; 945 struct radio_combination radio; 946 947 pm_ctx = policy_mgr_get_context(psoc); 948 if (!pm_ctx) { 949 policy_mgr_err("Invalid Context"); 950 return; 951 } 952 953 if (!dbs_mode && !sbs_mode) { 954 if (mac0_ss_bw_info.mac_band_cap & 955 WMI_HOST_WLAN_2G_CAPABILITY) { 956 SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_2G), 0, 957 mac0_ss_bw_info.mac_tx_stream, 0); 958 policy_mgr_add_radio_comb(pm_ctx, &radio); 959 } 960 if (mac0_ss_bw_info.mac_band_cap & 961 WMI_HOST_WLAN_5G_CAPABILITY) { 962 SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_5G), 0, 963 mac0_ss_bw_info.mac_tx_stream, 0); 964 policy_mgr_add_radio_comb(pm_ctx, &radio); 965 if (mac0_ss_bw_info.support_6ghz_band) { 966 SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_6G), 967 0, mac0_ss_bw_info.mac_tx_stream, 0); 968 policy_mgr_add_radio_comb(pm_ctx, &radio); 969 } 970 } 971 return; 972 } 973 if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_2G_CAPABILITY) && 974 (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY)) { 975 SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), BIT(REG_BAND_5G), 976 mac0_ss_bw_info.mac_tx_stream, 977 mac1_ss_bw_info.mac_tx_stream); 978 policy_mgr_add_radio_comb(pm_ctx, &radio); 979 if (mac1_ss_bw_info.support_6ghz_band) { 980 SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), 981 BIT(REG_BAND_6G), 982 mac0_ss_bw_info.mac_tx_stream, 983 mac1_ss_bw_info.mac_tx_stream); 984 policy_mgr_add_radio_comb(pm_ctx, &radio); 985 } 986 } 987 if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY) && 988 (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_2G_CAPABILITY)) { 989 SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), BIT(REG_BAND_5G), 990 mac1_ss_bw_info.mac_tx_stream, 991 mac0_ss_bw_info.mac_tx_stream); 992 policy_mgr_add_radio_comb(pm_ctx, &radio); 993 if (mac0_ss_bw_info.support_6ghz_band) { 994 SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), 995 BIT(REG_BAND_6G), 996 mac1_ss_bw_info.mac_tx_stream, 997 mac0_ss_bw_info.mac_tx_stream); 998 policy_mgr_add_radio_comb(pm_ctx, &radio); 999 } 1000 } 1001 if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY) && 1002 (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY)) { 1003 if (mac0_ss_bw_info.support_6ghz_band) { 1004 SET_RADIO(&radio, MODE_SBS, BIT(REG_BAND_5G), 1005 BIT(REG_BAND_6G), 1006 mac1_ss_bw_info.mac_tx_stream, 1007 mac0_ss_bw_info.mac_tx_stream); 1008 policy_mgr_add_radio_comb(pm_ctx, &radio); 1009 } else if (mac1_ss_bw_info.support_6ghz_band) { 1010 SET_RADIO(&radio, MODE_SBS, BIT(REG_BAND_5G), 1011 BIT(REG_BAND_6G), 1012 mac0_ss_bw_info.mac_tx_stream, 1013 mac1_ss_bw_info.mac_tx_stream); 1014 policy_mgr_add_radio_comb(pm_ctx, &radio); 1015 } 1016 } 1017 } 1018 1019 static void 1020 policy_mgr_update_24Ghz_freq_info(struct policy_mgr_freq_range *mac_range, 1021 struct wlan_psoc_host_mac_phy_caps *mac_cap) 1022 { 1023 mac_range->low_2ghz_freq = QDF_MAX(mac_cap->reg_cap_ext.low_2ghz_chan, 1024 wlan_reg_min_24ghz_chan_freq()); 1025 mac_range->high_2ghz_freq = mac_cap->reg_cap_ext.high_2ghz_chan ? 1026 QDF_MIN(mac_cap->reg_cap_ext.high_2ghz_chan, 1027 wlan_reg_max_24ghz_chan_freq()) : 1028 wlan_reg_max_24ghz_chan_freq(); 1029 } 1030 1031 static void 1032 policy_mgr_update_5Ghz_freq_info(struct policy_mgr_freq_range *mac_range, 1033 struct wlan_psoc_host_mac_phy_caps *mac_cap) 1034 { 1035 qdf_freq_t max_5g_freq; 1036 1037 max_5g_freq = wlan_reg_max_6ghz_chan_freq() ? 1038 wlan_reg_max_6ghz_chan_freq() : 1039 wlan_reg_max_5ghz_chan_freq(); 1040 1041 mac_range->low_5ghz_freq = QDF_MAX(mac_cap->reg_cap_ext.low_5ghz_chan, 1042 wlan_reg_min_5ghz_chan_freq()); 1043 mac_range->high_5ghz_freq = mac_cap->reg_cap_ext.high_5ghz_chan ? 1044 QDF_MIN(mac_cap->reg_cap_ext.high_5ghz_chan, 1045 max_5g_freq) : 1046 max_5g_freq; 1047 1048 } 1049 1050 static void 1051 policy_mgr_update_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx, 1052 struct wlan_psoc_host_mac_phy_caps *mac_cap, 1053 enum policy_mgr_mode mode, 1054 uint32_t phy_id) 1055 { 1056 struct policy_mgr_freq_range *mac_range; 1057 1058 mac_range = &pm_ctx->hw_mode.freq_range_caps[mode][phy_id]; 1059 if (mac_cap->supported_bands & WMI_HOST_WLAN_2G_CAPABILITY) 1060 policy_mgr_update_24Ghz_freq_info(mac_range, mac_cap); 1061 1062 if (mac_cap->supported_bands & WMI_HOST_WLAN_5G_CAPABILITY) 1063 policy_mgr_update_5Ghz_freq_info(mac_range, mac_cap); 1064 } 1065 1066 static QDF_STATUS 1067 policy_mgr_modify_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx, 1068 uint8_t phy_id) 1069 { 1070 uint8_t shared_phy_id; 1071 struct policy_mgr_freq_range *sbs_mac_range, *shared_mac_range; 1072 struct policy_mgr_freq_range *non_shared_range; 1073 1074 sbs_mac_range = &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][phy_id]; 1075 1076 /* 1077 * if SBS mac range has both 2.4 and 5 Ghz range, i e shared phy_id 1078 * keep the range as it is in SBS 1079 */ 1080 if (sbs_mac_range->low_2ghz_freq && sbs_mac_range->low_5ghz_freq) 1081 return QDF_STATUS_SUCCESS; 1082 if (sbs_mac_range->low_2ghz_freq && !sbs_mac_range->low_5ghz_freq) { 1083 policy_mgr_err("Invalid DBS/SBS mode with only 2.4Ghz"); 1084 policy_mgr_dump_freq_range_per_mac(sbs_mac_range, MODE_SBS); 1085 return QDF_STATUS_E_INVAL; 1086 } 1087 1088 non_shared_range = sbs_mac_range; 1089 /* 1090 * if SBS mac range has only 5Ghz then its the non shared phy, so 1091 * modify the range as per the shared mac. 1092 */ 1093 shared_phy_id = phy_id ? 0 : 1; 1094 shared_mac_range = 1095 &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][shared_phy_id]; 1096 1097 if (shared_mac_range->low_5ghz_freq > non_shared_range->low_5ghz_freq) { 1098 policy_mgr_debug("High 5Ghz shared"); 1099 /* 1100 * If the shared mac lower 5Ghz frequency is greater than 1101 * non-shared mac lower 5Ghz frequency then the shared mac has 1102 * HIGH 5Ghz shared with 2.4Ghz. So non-shared mac's 5Ghz high 1103 * freq should be less than the shared mac's low 5Ghz freq. 1104 */ 1105 if (non_shared_range->high_5ghz_freq >= 1106 shared_mac_range->low_5ghz_freq) 1107 non_shared_range->high_5ghz_freq = 1108 QDF_MAX(shared_mac_range->low_5ghz_freq - 10, 1109 non_shared_range->low_5ghz_freq); 1110 } else if (shared_mac_range->high_5ghz_freq < 1111 non_shared_range->high_5ghz_freq) { 1112 policy_mgr_debug("LOW 5Ghz shared"); 1113 /* 1114 * If the shared mac high 5Ghz frequency is less than 1115 * non-shared mac high 5Ghz frequency then the shared mac has 1116 * LOW 5Ghz shared with 2.4Ghz So non-shared mac's 5Ghz low 1117 * freq should be greater than the shared mac's high 5Ghz freq. 1118 */ 1119 if (shared_mac_range->high_5ghz_freq >= 1120 non_shared_range->low_5ghz_freq) 1121 non_shared_range->low_5ghz_freq = 1122 QDF_MIN(shared_mac_range->high_5ghz_freq + 10, 1123 non_shared_range->high_5ghz_freq); 1124 } else { 1125 policy_mgr_info("Invalid SBS range with all 5Ghz shared"); 1126 return QDF_STATUS_E_INVAL; 1127 } 1128 1129 return QDF_STATUS_SUCCESS; 1130 } 1131 1132 static qdf_freq_t 1133 policy_mgr_get_highest_5ghz_freq_frm_range(struct policy_mgr_freq_range *range) 1134 { 1135 uint8_t phy_id; 1136 qdf_freq_t highest_freq = 0; 1137 qdf_freq_t max_5g_freq = wlan_reg_max_6ghz_chan_freq() ? 1138 wlan_reg_max_6ghz_chan_freq() : 1139 wlan_reg_max_5ghz_chan_freq(); 1140 1141 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1142 if (range[phy_id].high_5ghz_freq > highest_freq) 1143 highest_freq = range[phy_id].high_5ghz_freq; 1144 } 1145 1146 return highest_freq ? highest_freq : max_5g_freq; 1147 } 1148 1149 static qdf_freq_t 1150 policy_mgr_get_lowest_5ghz_freq_frm_range(struct policy_mgr_freq_range *range) 1151 { 1152 uint8_t phy_id; 1153 qdf_freq_t lowest_freq = 0; 1154 1155 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1156 if ((!lowest_freq && range[phy_id].low_5ghz_freq) || 1157 (range[phy_id].low_5ghz_freq < lowest_freq)) 1158 lowest_freq = range[phy_id].low_5ghz_freq; 1159 } 1160 1161 return lowest_freq ? lowest_freq : wlan_reg_min_5ghz_chan_freq(); 1162 } 1163 1164 static void 1165 policy_mgr_fill_lower_share_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx, 1166 uint16_t sbs_range_sep, 1167 struct policy_mgr_freq_range *ref_freq) 1168 { 1169 struct policy_mgr_freq_range *lower_sbs_freq_range; 1170 uint8_t phy_id; 1171 1172 lower_sbs_freq_range = 1173 pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE]; 1174 1175 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1176 lower_sbs_freq_range[phy_id].low_2ghz_freq = 1177 ref_freq[phy_id].low_2ghz_freq; 1178 lower_sbs_freq_range[phy_id].high_2ghz_freq = 1179 ref_freq[phy_id].high_2ghz_freq; 1180 1181 /* update for shared mac */ 1182 if (lower_sbs_freq_range[phy_id].low_2ghz_freq) { 1183 lower_sbs_freq_range[phy_id].low_5ghz_freq = 1184 policy_mgr_get_lowest_5ghz_freq_frm_range(ref_freq); 1185 lower_sbs_freq_range[phy_id].high_5ghz_freq = 1186 sbs_range_sep; 1187 } else { 1188 lower_sbs_freq_range[phy_id].low_5ghz_freq = 1189 sbs_range_sep + 10; 1190 lower_sbs_freq_range[phy_id].high_5ghz_freq = 1191 policy_mgr_get_highest_5ghz_freq_frm_range(ref_freq); 1192 } 1193 } 1194 } 1195 1196 static void 1197 policy_mgr_fill_upper_share_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx, 1198 uint16_t sbs_range_sep, 1199 struct policy_mgr_freq_range *ref_freq) 1200 { 1201 struct policy_mgr_freq_range *upper_sbs_freq_range; 1202 uint8_t phy_id; 1203 1204 upper_sbs_freq_range = 1205 pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE]; 1206 1207 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1208 upper_sbs_freq_range[phy_id].low_2ghz_freq = 1209 ref_freq[phy_id].low_2ghz_freq; 1210 upper_sbs_freq_range[phy_id].high_2ghz_freq = 1211 ref_freq[phy_id].high_2ghz_freq; 1212 1213 /* update for shared mac */ 1214 if (upper_sbs_freq_range[phy_id].low_2ghz_freq) { 1215 upper_sbs_freq_range[phy_id].low_5ghz_freq = 1216 sbs_range_sep + 10; 1217 upper_sbs_freq_range[phy_id].high_5ghz_freq = 1218 policy_mgr_get_highest_5ghz_freq_frm_range(ref_freq); 1219 } else { 1220 upper_sbs_freq_range[phy_id].low_5ghz_freq = 1221 policy_mgr_get_lowest_5ghz_freq_frm_range(ref_freq); 1222 upper_sbs_freq_range[phy_id].high_5ghz_freq = 1223 sbs_range_sep; 1224 } 1225 } 1226 } 1227 1228 static bool 1229 policy_mgr_both_phy_range_updated(struct policy_mgr_psoc_priv_obj *pm_ctx, 1230 enum policy_mgr_mode hwmode) 1231 { 1232 struct policy_mgr_freq_range *mac_range; 1233 uint8_t phy_id; 1234 1235 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1236 mac_range = 1237 &pm_ctx->hw_mode.freq_range_caps[hwmode][phy_id]; 1238 /* modify SBS/DBS range only when both phy for DBS are filled */ 1239 if (!mac_range->low_2ghz_freq && !mac_range->low_5ghz_freq) 1240 return false; 1241 } 1242 1243 return true; 1244 } 1245 1246 static void 1247 policy_mgr_update_sbs_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx) 1248 { 1249 uint16_t sbs_range_sep; 1250 struct policy_mgr_freq_range *mac_range; 1251 uint8_t phy_id; 1252 QDF_STATUS status; 1253 1254 mac_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS]; 1255 1256 /* 1257 * If sbs_lower_band_end_freq has a value Z, then the frequency range 1258 * will be split using that value. 1259 */ 1260 sbs_range_sep = pm_ctx->hw_mode.sbs_lower_band_end_freq; 1261 if (sbs_range_sep) { 1262 policy_mgr_fill_upper_share_sbs_freq(pm_ctx, sbs_range_sep, 1263 mac_range); 1264 policy_mgr_fill_lower_share_sbs_freq(pm_ctx, sbs_range_sep, 1265 mac_range); 1266 /* Reset the SBS range */ 1267 qdf_mem_zero(mac_range, sizeof(*mac_range) * MAX_MAC); 1268 return; 1269 } 1270 1271 /* 1272 * If sbs_lower_band_end_freq is not set that means FW will send one 1273 * shared mac range and one non-shared mac range. so update that freq. 1274 */ 1275 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1276 status = policy_mgr_modify_sbs_freq(pm_ctx, phy_id); 1277 if (QDF_IS_STATUS_ERROR(status)) { 1278 /* Reset the SBS range */ 1279 qdf_mem_zero(mac_range, sizeof(*mac_range) * MAX_MAC); 1280 break; 1281 } 1282 } 1283 } 1284 1285 static void 1286 policy_mgr_update_dbs_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx) 1287 { 1288 struct policy_mgr_freq_range *mac_range; 1289 uint8_t phy_id; 1290 1291 mac_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; 1292 /* Reset 5Ghz range for shared mac for DBS */ 1293 for (phy_id = 0; phy_id < MAX_MAC; phy_id++) { 1294 if (mac_range[phy_id].low_2ghz_freq && 1295 mac_range[phy_id].low_5ghz_freq) { 1296 mac_range[phy_id].low_5ghz_freq = 0; 1297 mac_range[phy_id].high_5ghz_freq = 0; 1298 } 1299 } 1300 } 1301 1302 static void 1303 policy_mgr_update_mac_freq_info(struct wlan_objmgr_psoc *psoc, 1304 struct policy_mgr_psoc_priv_obj *pm_ctx, 1305 enum wmi_hw_mode_config_type hw_config_type, 1306 uint32_t phy_id, 1307 struct wlan_psoc_host_mac_phy_caps *mac_cap) 1308 { 1309 if (phy_id >= MAX_MAC) { 1310 policy_mgr_err("mac more than two not supported: %d", 1311 phy_id); 1312 return; 1313 } 1314 1315 policy_mgr_debug("hw_mode_cfg: %d mac: %d band: 0x%x, SBS cutoff freq %d, 2Ghz: %d -> %d 5Ghz: %d -> %d", 1316 hw_config_type, phy_id, mac_cap->supported_bands, 1317 pm_ctx->hw_mode.sbs_lower_band_end_freq, 1318 mac_cap->reg_cap_ext.low_2ghz_chan, 1319 mac_cap->reg_cap_ext.high_2ghz_chan, 1320 mac_cap->reg_cap_ext.low_5ghz_chan, 1321 mac_cap->reg_cap_ext.high_5ghz_chan); 1322 1323 switch (hw_config_type) { 1324 case WMI_HW_MODE_SINGLE: 1325 if (phy_id) { 1326 policy_mgr_debug("MAC Phy 1 is not supported"); 1327 break; 1328 } 1329 policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SMM, phy_id); 1330 break; 1331 1332 case WMI_HW_MODE_DBS: 1333 case WMI_HW_MODE_DBS_2G_5G: 1334 if (!policy_mgr_both_phy_range_updated(pm_ctx, MODE_DBS)) 1335 policy_mgr_update_freq_info(pm_ctx, mac_cap, 1336 MODE_DBS, phy_id); 1337 break; 1338 case WMI_HW_MODE_DBS_SBS: 1339 case WMI_HW_MODE_DBS_OR_SBS: 1340 policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_DBS, phy_id); 1341 /* 1342 * fill SBS only if freq is provided by FW or 1343 * pm_ctx->hw_mode.sbs_lower_band_end_freq is set 1344 */ 1345 if (pm_ctx->hw_mode.sbs_lower_band_end_freq || 1346 mac_cap->reg_cap_ext.low_5ghz_chan || 1347 mac_cap->reg_cap_ext.low_2ghz_chan) 1348 policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SBS, 1349 phy_id); 1350 1351 /* Modify the DBS list once both phy info are filled */ 1352 if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_DBS)) 1353 policy_mgr_update_dbs_freq_info(pm_ctx); 1354 /* Modify the SBS list once both phy info are filled */ 1355 if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS)) 1356 policy_mgr_update_sbs_freq_info(pm_ctx); 1357 break; 1358 case WMI_HW_MODE_2G_PHYB: 1359 if (phy_id) 1360 policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SMM, 1361 phy_id); 1362 break; 1363 case WMI_HW_MODE_SBS: 1364 case WMI_HW_MODE_SBS_PASSIVE: 1365 policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SBS, phy_id); 1366 /* Modify the SBS Upper Lower list once both phy are filled */ 1367 if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS)) 1368 policy_mgr_update_sbs_freq_info(pm_ctx); 1369 1370 break; 1371 case WMI_HW_MODE_EMLSR: 1372 case WMI_HW_MODE_AUX_EMLSR_SINGLE: 1373 case WMI_HW_MODE_AUX_EMLSR_SPLIT: 1374 policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR, 1375 phy_id); 1376 break; 1377 default: 1378 policy_mgr_err("HW mode not defined %d", 1379 hw_config_type); 1380 break; 1381 } 1382 } 1383 1384 void 1385 policy_mgr_dump_curr_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx) 1386 { 1387 uint32_t i; 1388 struct policy_mgr_freq_range *freq_range; 1389 1390 freq_range = pm_ctx->hw_mode.cur_mac_freq_range; 1391 for (i = 0; i < MAX_MAC; i++) 1392 if (freq_range[i].low_2ghz_freq || freq_range[i].low_5ghz_freq) 1393 policymgr_nofl_debug("PLCY_MGR_FREQ_RANGE_CUR: mac %d: 2Ghz: %d -> %d, 5Ghz: %d -> %d", 1394 i, freq_range[i].low_2ghz_freq, 1395 freq_range[i].high_2ghz_freq, 1396 freq_range[i].low_5ghz_freq, 1397 freq_range[i].high_5ghz_freq); 1398 } 1399 1400 static const char *policy_mgr_hw_mode_to_str(enum policy_mgr_mode hw_mode) 1401 { 1402 if (hw_mode >= MODE_HW_MAX) 1403 return "Unknown"; 1404 1405 switch (hw_mode) { 1406 CASE_RETURN_STRING(MODE_SMM); 1407 CASE_RETURN_STRING(MODE_DBS); 1408 CASE_RETURN_STRING(MODE_SBS); 1409 CASE_RETURN_STRING(MODE_SBS_UPPER_SHARE); 1410 CASE_RETURN_STRING(MODE_SBS_LOWER_SHARE); 1411 CASE_RETURN_STRING(MODE_EMLSR); 1412 default: 1413 return "Unknown"; 1414 } 1415 } 1416 1417 void 1418 policy_mgr_dump_freq_range_per_mac(struct policy_mgr_freq_range *freq_range, 1419 enum policy_mgr_mode hw_mode) 1420 { 1421 uint32_t i; 1422 1423 for (i = 0; i < MAX_MAC; i++) 1424 if (freq_range[i].low_2ghz_freq || freq_range[i].low_5ghz_freq) 1425 policymgr_nofl_debug("PLCY_MGR_FREQ_RANGE: %s(%d): mac %d: 2Ghz: %d -> %d, 5Ghz: %d -> %d", 1426 policy_mgr_hw_mode_to_str(hw_mode), 1427 hw_mode, i, 1428 freq_range[i].low_2ghz_freq, 1429 freq_range[i].high_2ghz_freq, 1430 freq_range[i].low_5ghz_freq, 1431 freq_range[i].high_5ghz_freq); 1432 } 1433 1434 static void 1435 policy_mgr_dump_hw_modes_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx) 1436 { 1437 uint32_t i; 1438 struct policy_mgr_freq_range *freq_range; 1439 1440 for (i = MODE_SMM; i < MODE_HW_MAX; i++) { 1441 freq_range = pm_ctx->hw_mode.freq_range_caps[i]; 1442 policy_mgr_dump_freq_range_per_mac(freq_range, i); 1443 } 1444 } 1445 1446 void policy_mgr_dump_sbs_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx) 1447 { 1448 uint32_t i; 1449 struct policy_mgr_freq_range *freq_range; 1450 1451 for (i = MODE_SMM; i < MODE_HW_MAX; i++) { 1452 if ((i == MODE_SBS) || 1453 (pm_ctx->hw_mode.sbs_lower_band_end_freq && 1454 (i == MODE_SBS_LOWER_SHARE || i == MODE_SBS_UPPER_SHARE))) { 1455 freq_range = pm_ctx->hw_mode.freq_range_caps[i]; 1456 policy_mgr_dump_freq_range_per_mac(freq_range, i); 1457 } 1458 } 1459 } 1460 1461 static bool 1462 policy_mgr_sbs_range_present(struct policy_mgr_psoc_priv_obj *pm_ctx) 1463 { 1464 if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS) || 1465 (pm_ctx->hw_mode.sbs_lower_band_end_freq && 1466 policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS_LOWER_SHARE) && 1467 policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS_UPPER_SHARE))) 1468 return true; 1469 1470 return false; 1471 } 1472 1473 void 1474 policy_mgr_dump_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx) 1475 { 1476 policy_mgr_dump_hw_modes_freq_range(pm_ctx); 1477 policy_mgr_dump_curr_freq_range(pm_ctx); 1478 } 1479 1480 static void 1481 policy_mgr_update_sbs_lowr_band_end_frq(struct policy_mgr_psoc_priv_obj *pm_ctx, 1482 struct tgt_info *info) 1483 { 1484 if (wlan_reg_is_5ghz_ch_freq(info->sbs_lower_band_end_freq) || 1485 wlan_reg_is_6ghz_chan_freq(info->sbs_lower_band_end_freq)) 1486 pm_ctx->hw_mode.sbs_lower_band_end_freq = 1487 info->sbs_lower_band_end_freq; 1488 } 1489 1490 QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, 1491 struct target_psoc_info *tgt_hdl) 1492 { 1493 struct wlan_psoc_host_mac_phy_caps *tmp; 1494 struct wlan_psoc_host_mac_phy_caps_ext2 *cap; 1495 uint32_t i, j = 0; 1496 enum wmi_hw_mode_config_type hw_config_type; 1497 uint32_t dbs_mode, sbs_mode; 1498 uint64_t emlsr_mode; 1499 struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info = {0}; 1500 struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info = {0}; 1501 struct policy_mgr_psoc_priv_obj *pm_ctx; 1502 struct tgt_info *info; 1503 1504 pm_ctx = policy_mgr_get_context(psoc); 1505 if (!pm_ctx) { 1506 policy_mgr_err("Invalid Context"); 1507 return QDF_STATUS_E_FAILURE; 1508 } 1509 1510 info = &tgt_hdl->info; 1511 if (!info->service_ext_param.num_hw_modes) { 1512 policy_mgr_err("Number of HW modes: %d", 1513 info->service_ext_param.num_hw_modes); 1514 return QDF_STATUS_E_FAILURE; 1515 } 1516 1517 /* 1518 * This list was updated as part of service ready event. Re-populate 1519 * HW mode list from the device capabilities. 1520 */ 1521 if (pm_ctx->hw_mode.hw_mode_list) { 1522 qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); 1523 pm_ctx->hw_mode.hw_mode_list = NULL; 1524 policy_mgr_debug("DBS list is freed"); 1525 } 1526 1527 /* Reset old freq ranges */ 1528 qdf_mem_zero(pm_ctx->hw_mode.freq_range_caps, 1529 sizeof(pm_ctx->hw_mode.freq_range_caps)); 1530 qdf_mem_zero(pm_ctx->hw_mode.cur_mac_freq_range, 1531 sizeof(pm_ctx->hw_mode.cur_mac_freq_range)); 1532 pm_ctx->num_dbs_hw_modes = info->service_ext_param.num_hw_modes; 1533 pm_ctx->hw_mode.hw_mode_list = 1534 qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) * 1535 pm_ctx->num_dbs_hw_modes); 1536 if (!pm_ctx->hw_mode.hw_mode_list) { 1537 pm_ctx->num_dbs_hw_modes = 0; 1538 return QDF_STATUS_E_NOMEM; 1539 } 1540 pm_ctx->radio_comb_num = 0; 1541 qdf_mem_zero(pm_ctx->radio_combinations, 1542 sizeof(pm_ctx->radio_combinations)); 1543 1544 policy_mgr_debug("Updated HW mode list: Num modes:%d", 1545 pm_ctx->num_dbs_hw_modes); 1546 1547 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 1548 /* Update for MAC0 */ 1549 tmp = &info->mac_phy_cap[j++]; 1550 policy_mgr_get_hw_mode_params(tmp, &mac0_ss_bw_info); 1551 dbs_mode = HW_MODE_DBS_NONE; 1552 sbs_mode = HW_MODE_SBS_NONE; 1553 emlsr_mode = HW_MODE_EMLSR_NONE; 1554 mac1_ss_bw_info.mac_tx_stream = 0; 1555 mac1_ss_bw_info.mac_rx_stream = 0; 1556 mac1_ss_bw_info.mac_bw = 0; 1557 1558 hw_config_type = tmp->hw_mode_config_type; 1559 if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) == 1560 WMI_HW_MODE_EMLSR) 1561 hw_config_type = WMI_HW_MODE_EMLSR; 1562 1563 policy_mgr_update_mac_freq_info(psoc, pm_ctx, 1564 hw_config_type, 1565 tmp->phy_id, tmp); 1566 1567 /* SBS and DBS have dual MAC. Upto 2 MACs are considered. */ 1568 if ((hw_config_type == WMI_HW_MODE_DBS) || 1569 (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) || 1570 (hw_config_type == WMI_HW_MODE_SBS) || 1571 (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)) { 1572 /* Update for MAC1 */ 1573 tmp = &info->mac_phy_cap[j++]; 1574 policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info); 1575 policy_mgr_update_mac_freq_info(psoc, pm_ctx, 1576 hw_config_type, 1577 tmp->phy_id, tmp); 1578 if (hw_config_type == WMI_HW_MODE_DBS || 1579 hw_config_type == WMI_HW_MODE_DBS_OR_SBS) 1580 dbs_mode = HW_MODE_DBS; 1581 if (policy_mgr_sbs_range_present(pm_ctx) && 1582 ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) || 1583 (hw_config_type == WMI_HW_MODE_SBS) || 1584 (hw_config_type == WMI_HW_MODE_DBS_OR_SBS))) 1585 sbs_mode = HW_MODE_SBS; 1586 } else if (hw_config_type == WMI_HW_MODE_EMLSR) { 1587 /* eMLSR mode */ 1588 tmp = &info->mac_phy_cap[j++]; 1589 cap = &info->mac_phy_caps_ext2[i]; 1590 wlan_mlme_set_eml_params(psoc, cap); 1591 policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info); 1592 policy_mgr_update_mac_freq_info(psoc, pm_ctx, 1593 hw_config_type, 1594 tmp->phy_id, tmp); 1595 emlsr_mode = HW_MODE_EMLSR; 1596 } 1597 1598 /* Updating HW mode list */ 1599 policy_mgr_set_hw_mode_params(psoc, mac0_ss_bw_info, 1600 mac1_ss_bw_info, i, tmp->hw_mode_id, dbs_mode, 1601 sbs_mode, emlsr_mode); 1602 /* Update radio combination info */ 1603 policy_mgr_update_radio_combination_matrix( 1604 psoc, mac0_ss_bw_info, mac1_ss_bw_info, 1605 dbs_mode, sbs_mode); 1606 } 1607 1608 /* 1609 * Initializing Current frequency with SMM frequency. 1610 */ 1611 policy_mgr_fill_curr_mac_freq_by_hwmode(pm_ctx, MODE_SMM); 1612 policy_mgr_dump_freq_range(pm_ctx); 1613 1614 return QDF_STATUS_SUCCESS; 1615 } 1616 1617 QDF_STATUS policy_mgr_update_sbs_freq(struct wlan_objmgr_psoc *psoc, 1618 struct target_psoc_info *tgt_hdl) 1619 { 1620 struct policy_mgr_psoc_priv_obj *pm_ctx; 1621 struct tgt_info *info; 1622 1623 pm_ctx = policy_mgr_get_context(psoc); 1624 if (!pm_ctx) { 1625 policy_mgr_err("Invalid Context"); 1626 return QDF_STATUS_E_FAILURE; 1627 } 1628 1629 info = &tgt_hdl->info; 1630 policy_mgr_debug("sbs_lower_band_end_freq %d", 1631 info->sbs_lower_band_end_freq); 1632 policy_mgr_update_sbs_lowr_band_end_frq(pm_ctx, info); 1633 1634 policy_mgr_update_hw_mode_list(psoc, tgt_hdl); 1635 1636 return QDF_STATUS_SUCCESS; 1637 } 1638 1639 qdf_freq_t policy_mgr_get_sbs_cut_off_freq(struct wlan_objmgr_psoc *psoc) 1640 { 1641 struct policy_mgr_psoc_priv_obj *pm_ctx; 1642 struct policy_mgr_freq_range *first_mac_range, *second_mac_range; 1643 qdf_freq_t sbs_cut_off_freq = 0; 1644 1645 pm_ctx = policy_mgr_get_context(psoc); 1646 if (!pm_ctx) { 1647 policy_mgr_err("Invalid Context"); 1648 return 0; 1649 } 1650 1651 if (pm_ctx->hw_mode.sbs_lower_band_end_freq) 1652 return pm_ctx->hw_mode.sbs_lower_band_end_freq; 1653 /* 1654 * if cutoff freq is not available from FW (i.e SBS is not dynamic) 1655 * get it from SBS freq range 1656 */ 1657 first_mac_range = &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][0]; 1658 1659 second_mac_range = 1660 &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][1]; 1661 1662 /* 1663 * SBS range is low 5Ghz shared with 2.4Ghz: The low_5Ghz of shared 1664 * mac will be starting of 5Ghz and low_5Ghz of non-shared mac will be 1665 * the cutoff freq 1666 * 1667 * SBS range is high 5Ghz shared with 2.4Ghz: The low_5Ghz of shared 1668 * mac will be cutoff freq and low_5Ghz of non-shared mac will be 1669 * the starting of 5Ghz 1670 * 1671 * so, maximum of low_5Ghz will be cutoff freq 1672 */ 1673 sbs_cut_off_freq = QDF_MAX(second_mac_range->low_5ghz_freq, 1674 first_mac_range->low_5ghz_freq) - 1; 1675 policy_mgr_debug("sbs cutoff freq %d", sbs_cut_off_freq); 1676 1677 return sbs_cut_off_freq; 1678 } 1679 1680 static bool 1681 policy_mgr_2_freq_same_mac_in_freq_range( 1682 struct policy_mgr_psoc_priv_obj *pm_ctx, 1683 struct policy_mgr_freq_range *freq_range, 1684 qdf_freq_t freq_1, qdf_freq_t freq_2) 1685 { 1686 uint8_t i; 1687 1688 for (i = 0; i < MAX_MAC; i++) { 1689 if (IS_FREQ_ON_MAC_ID(freq_range, freq_1, i) && 1690 IS_FREQ_ON_MAC_ID(freq_range, freq_2, i)) 1691 return true; 1692 } 1693 1694 return false; 1695 } 1696 1697 bool policy_mgr_can_2ghz_share_low_high_5ghz_sbs( 1698 struct policy_mgr_psoc_priv_obj *pm_ctx) 1699 { 1700 if (pm_ctx->hw_mode.sbs_lower_band_end_freq) 1701 return true; 1702 1703 return false; 1704 } 1705 1706 bool 1707 policy_mgr_sbs_24_shared_with_high_5(struct policy_mgr_psoc_priv_obj *pm_ctx) 1708 { 1709 qdf_freq_t sbs_cut_off_freq; 1710 struct policy_mgr_freq_range freq_range; 1711 uint8_t i = 0; 1712 1713 if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx)) 1714 return true; 1715 1716 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc); 1717 if (!sbs_cut_off_freq) { 1718 policy_mgr_err("Invalid cut off freq"); 1719 return false; 1720 } 1721 1722 for (i = 0; i < MAX_MAC; i++) { 1723 freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS][i]; 1724 /* 1725 * if 5 GHZ start freq of this mac is greater than cutoff 1726 * return true 1727 */ 1728 if (freq_range.low_2ghz_freq && freq_range.low_5ghz_freq) { 1729 if (sbs_cut_off_freq < freq_range.low_5ghz_freq) 1730 return true; 1731 } 1732 } 1733 1734 return false; 1735 } 1736 1737 bool 1738 policy_mgr_sbs_24_shared_with_low_5(struct policy_mgr_psoc_priv_obj *pm_ctx) 1739 { 1740 qdf_freq_t sbs_cut_off_freq; 1741 struct policy_mgr_freq_range freq_range; 1742 uint8_t i = 0; 1743 1744 if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx)) 1745 return true; 1746 1747 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc); 1748 if (!sbs_cut_off_freq) { 1749 policy_mgr_err("Invalid cut off freq"); 1750 return false; 1751 } 1752 1753 for (i = 0; i < MAX_MAC; i++) { 1754 freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS][i]; 1755 if (freq_range.low_2ghz_freq && freq_range.high_5ghz_freq) { 1756 /* 1757 * if 5 GHZ end freq of this mac is less than cutoff 1758 * return true 1759 */ 1760 if (sbs_cut_off_freq > freq_range.high_5ghz_freq) 1761 return true; 1762 } 1763 } 1764 1765 return false; 1766 } 1767 1768 bool 1769 policy_mgr_2_freq_same_mac_in_dbs(struct policy_mgr_psoc_priv_obj *pm_ctx, 1770 qdf_freq_t freq_1, qdf_freq_t freq_2) 1771 { 1772 struct policy_mgr_freq_range *freq_range; 1773 1774 /* Return true if non DBS capable HW */ 1775 if (!policy_mgr_is_hw_dbs_capable(pm_ctx->psoc)) 1776 return true; 1777 1778 freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; 1779 return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, freq_range, 1780 freq_1, freq_2); 1781 } 1782 1783 bool 1784 policy_mgr_2_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx, 1785 qdf_freq_t freq_1, qdf_freq_t freq_2) 1786 { 1787 struct policy_mgr_freq_range *sbs_low_share; 1788 struct policy_mgr_freq_range *sbs_uppr_share; 1789 struct policy_mgr_freq_range *sbs_range; 1790 1791 /* Return true if non SBS capable HW */ 1792 if (!policy_mgr_is_hw_sbs_capable(pm_ctx->psoc)) 1793 return true; 1794 1795 if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx)) { 1796 sbs_uppr_share = 1797 pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE]; 1798 sbs_low_share = 1799 pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE]; 1800 if (policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, 1801 sbs_low_share, 1802 freq_1, freq_2) || 1803 policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, 1804 sbs_uppr_share, 1805 freq_1, freq_2)) 1806 return true; 1807 1808 return false; 1809 } 1810 1811 sbs_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS]; 1812 1813 return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, sbs_range, 1814 freq_1, freq_2); 1815 } 1816 1817 static bool 1818 policy_mgr_is_cur_freq_range_sbs(struct wlan_objmgr_psoc *psoc) 1819 { 1820 struct policy_mgr_psoc_priv_obj *pm_ctx; 1821 struct policy_mgr_freq_range *freq_range; 1822 uint8_t i; 1823 1824 pm_ctx = policy_mgr_get_context(psoc); 1825 if (!pm_ctx) 1826 return false; 1827 1828 /* Check if any of the mac is shared */ 1829 for (i = 0 ; i < MAX_MAC; i++) { 1830 freq_range = &pm_ctx->hw_mode.cur_mac_freq_range[i]; 1831 if (freq_range->low_2ghz_freq && freq_range->low_5ghz_freq) 1832 return true; 1833 } 1834 1835 return false; 1836 } 1837 1838 bool policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc, 1839 qdf_freq_t freq_1, qdf_freq_t freq_2) 1840 { 1841 struct policy_mgr_psoc_priv_obj *pm_ctx; 1842 bool is_dbs_mode_same_mac = true; 1843 bool is_sbs_mode_same_mac = true; 1844 1845 pm_ctx = policy_mgr_get_context(psoc); 1846 if (!pm_ctx) 1847 return false; 1848 1849 is_dbs_mode_same_mac = 1850 policy_mgr_2_freq_same_mac_in_dbs(pm_ctx, freq_1, freq_2); 1851 1852 /* if DBS mode leading to same mac, check for SBS mode */ 1853 if (is_dbs_mode_same_mac) 1854 is_sbs_mode_same_mac = 1855 policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq_1, 1856 freq_2); 1857 1858 policy_mgr_rl_debug("freq1 %d freq2 %d: Same mac:: DBS:%d SBS:%d", 1859 freq_1, freq_2, is_dbs_mode_same_mac, 1860 is_sbs_mode_same_mac); 1861 /* 1862 * if in SBS and DBS mode, both is leading to freqs on same mac, 1863 * return true else return false. 1864 */ 1865 if (is_dbs_mode_same_mac && is_sbs_mode_same_mac) 1866 return true; 1867 1868 return false; 1869 } 1870 1871 bool policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, 1872 qdf_freq_t freq_1, 1873 qdf_freq_t freq_2) 1874 { 1875 struct policy_mgr_psoc_priv_obj *pm_ctx; 1876 struct policy_mgr_freq_range *freq_range; 1877 struct policy_mgr_hw_mode_params hw_mode; 1878 QDF_STATUS status; 1879 bool cur_range_sbs = false; 1880 1881 pm_ctx = policy_mgr_get_context(psoc); 1882 if (!pm_ctx) 1883 return false; 1884 1885 /* if HW is not DBS return true*/ 1886 if (!policy_mgr_is_hw_dbs_capable(psoc)) 1887 return true; 1888 1889 policy_mgr_rl_debug("freq_1 %d freq_2 %d old_hw_mode_index=%d, new_hw_mode_index=%d", 1890 freq_1, freq_2, pm_ctx->old_hw_mode_index, 1891 pm_ctx->new_hw_mode_index); 1892 1893 /* HW is DBS/SBS capable */ 1894 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); 1895 if (!QDF_IS_STATUS_SUCCESS(status)) { 1896 policy_mgr_err("policy_mgr_get_current_hw_mode failed"); 1897 return false; 1898 } 1899 1900 if (hw_mode.dbs_cap || hw_mode.sbs_cap) 1901 cur_range_sbs = policy_mgr_is_cur_freq_range_sbs(psoc); 1902 1903 policy_mgr_rl_debug("dbs_cap %d sbs_cap %d, cur range is sbs %d", 1904 hw_mode.dbs_cap, hw_mode.sbs_cap, cur_range_sbs); 1905 freq_range = pm_ctx->hw_mode.cur_mac_freq_range; 1906 /* current HW is DBS OR SBS check current DBS/SBS freq range */ 1907 if (hw_mode.dbs_cap || hw_mode.sbs_cap) 1908 return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, 1909 freq_range, 1910 freq_1, freq_2); 1911 1912 /* 1913 * If current HW mode is not DBS/SBS, check if in all supported mode 1914 * it they will be on same mac 1915 */ 1916 return policy_mgr_2_freq_always_on_same_mac(psoc, freq_1, freq_2); 1917 } 1918 1919 static bool 1920 policy_mgr_3_freq_same_mac_in_freq_range( 1921 struct policy_mgr_psoc_priv_obj *pm_ctx, 1922 struct policy_mgr_freq_range *freq_range, 1923 qdf_freq_t freq_1, qdf_freq_t freq_2, 1924 qdf_freq_t freq_3) 1925 { 1926 uint8_t i; 1927 1928 for (i = 0 ; i < MAX_MAC; i++) { 1929 if (IS_FREQ_ON_MAC_ID(freq_range, freq_1, i) && 1930 IS_FREQ_ON_MAC_ID(freq_range, freq_2, i) && 1931 IS_FREQ_ON_MAC_ID(freq_range, freq_3, i)) 1932 return true; 1933 } 1934 1935 return false; 1936 } 1937 1938 static bool 1939 policy_mgr_3_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx, 1940 qdf_freq_t freq_1, qdf_freq_t freq_2, 1941 qdf_freq_t freq_3) 1942 { 1943 struct policy_mgr_freq_range *sbs_low_share; 1944 struct policy_mgr_freq_range *sbs_uppr_share; 1945 struct policy_mgr_freq_range *sbs_range; 1946 1947 /* Return true if non SBS capable HW */ 1948 if (!policy_mgr_is_hw_sbs_capable(pm_ctx->psoc)) 1949 return true; 1950 1951 if (pm_ctx->hw_mode.sbs_lower_band_end_freq) { 1952 sbs_uppr_share = 1953 pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE]; 1954 sbs_low_share = 1955 pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE]; 1956 if (policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, 1957 sbs_low_share, 1958 freq_1, freq_2, 1959 freq_3) || 1960 policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, 1961 sbs_uppr_share, 1962 freq_1, freq_2, 1963 freq_3)) 1964 return true; 1965 1966 return false; 1967 } 1968 1969 sbs_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS]; 1970 return policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, sbs_range, 1971 freq_1, freq_2, freq_3); 1972 } 1973 1974 bool 1975 policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc, 1976 qdf_freq_t freq_1, qdf_freq_t freq_2, 1977 qdf_freq_t freq_3) 1978 { 1979 struct policy_mgr_psoc_priv_obj *pm_ctx; 1980 struct policy_mgr_freq_range *freq_range; 1981 bool is_dbs_mode_same_mac = true; 1982 bool is_sbs_mode_same_mac = true; 1983 1984 pm_ctx = policy_mgr_get_context(psoc); 1985 if (!pm_ctx) 1986 return false; 1987 1988 /* if HW is not DBS return true*/ 1989 if (!policy_mgr_is_hw_dbs_capable(psoc)) 1990 return true; 1991 1992 /* Check for DBS mode first */ 1993 freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS]; 1994 is_dbs_mode_same_mac = 1995 policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, freq_range, 1996 freq_1, freq_2, 1997 freq_3); 1998 1999 /* if DBS mode leading to same mac, check for SBS mode */ 2000 if (is_dbs_mode_same_mac) 2001 is_sbs_mode_same_mac = 2002 policy_mgr_3_freq_same_mac_in_sbs(pm_ctx, freq_1, 2003 freq_2, freq_3); 2004 2005 policy_mgr_rl_debug("freq1 %d freq2 %d freq3 %d: Same mac:: DBS:%d SBS:%d", 2006 freq_1, freq_2, freq_3, is_dbs_mode_same_mac, 2007 is_sbs_mode_same_mac); 2008 /* 2009 * if in SBS and DBS mode, both is leading to freqs on same mac, 2010 * return true else return false. 2011 */ 2012 if (is_dbs_mode_same_mac && is_sbs_mode_same_mac) 2013 return true; 2014 2015 return false; 2016 } 2017 2018 bool 2019 policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc, 2020 qdf_freq_t freq_1, qdf_freq_t freq_2, 2021 qdf_freq_t freq_3) 2022 { 2023 struct policy_mgr_psoc_priv_obj *pm_ctx; 2024 struct policy_mgr_freq_range *freq_range; 2025 QDF_STATUS status; 2026 struct policy_mgr_hw_mode_params hw_mode; 2027 bool cur_range_sbs = false; 2028 2029 pm_ctx = policy_mgr_get_context(psoc); 2030 if (!pm_ctx) 2031 return false; 2032 2033 /* if HW is not DBS return true*/ 2034 if (!policy_mgr_is_hw_dbs_capable(psoc)) 2035 return true; 2036 2037 policy_mgr_rl_debug("freq_1 %d freq_2 %d freq_3 %d", freq_1, freq_2, 2038 freq_3); 2039 2040 /* HW is DBS/SBS capable, get current HW mode */ 2041 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); 2042 if (!QDF_IS_STATUS_SUCCESS(status)) { 2043 policy_mgr_err("policy_mgr_get_current_hw_mode failed"); 2044 return false; 2045 } 2046 if (hw_mode.dbs_cap || hw_mode.sbs_cap) 2047 cur_range_sbs = policy_mgr_is_cur_freq_range_sbs(psoc); 2048 2049 policy_mgr_rl_debug("dbs_cap %d sbs_cap %d, cur range is sbs %d", 2050 hw_mode.dbs_cap, hw_mode.sbs_cap, cur_range_sbs); 2051 freq_range = pm_ctx->hw_mode.cur_mac_freq_range; 2052 2053 /* current HW is DBS OR SBS check current DBS/SBS freq range */ 2054 if (hw_mode.dbs_cap || hw_mode.sbs_cap) 2055 return policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, 2056 freq_range, 2057 freq_1, freq_2, freq_3); 2058 /* 2059 * If current HW mode is not DBS/SBS, check if in all supported mode 2060 * it they will be on same mac 2061 */ 2062 return policy_mgr_3_freq_always_on_same_mac(psoc, freq_1, freq_2, 2063 freq_3); 2064 } 2065 2066 #ifdef FEATURE_FOURTH_CONNECTION 2067 static void 2068 policy_mgr_get_mac_freq_list(struct policy_mgr_freq_range *freq_range, 2069 uint8_t mac_id, 2070 uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS], 2071 uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS], 2072 uint8_t *mac_freq_num, 2073 qdf_freq_t freq_1, enum policy_mgr_con_mode mode_1, 2074 qdf_freq_t freq_2, enum policy_mgr_con_mode mode_2, 2075 qdf_freq_t freq_3, enum policy_mgr_con_mode mode_3, 2076 qdf_freq_t freq_4, enum policy_mgr_con_mode mode_4) 2077 { 2078 uint8_t j = 0; 2079 2080 if (freq_1 && IS_FREQ_ON_MAC_ID(freq_range, freq_1, mac_id)) { 2081 mac_freq_list[j] = freq_1; 2082 mac_mode_list[j++] = mode_1; 2083 } 2084 if (freq_2 && IS_FREQ_ON_MAC_ID(freq_range, freq_2, mac_id)) { 2085 mac_freq_list[j] = freq_2; 2086 mac_mode_list[j++] = mode_2; 2087 } 2088 if (freq_3 && IS_FREQ_ON_MAC_ID(freq_range, freq_3, mac_id)) { 2089 mac_freq_list[j] = freq_3; 2090 mac_mode_list[j++] = mode_3; 2091 } 2092 if (freq_4 && IS_FREQ_ON_MAC_ID(freq_range, freq_4, mac_id)) { 2093 mac_freq_list[j] = freq_4; 2094 mac_mode_list[j++] = mode_4; 2095 } 2096 2097 *mac_freq_num = j; 2098 } 2099 2100 static bool 2101 policy_mgr_is_supported_hw_mode(struct wlan_objmgr_psoc *psoc, 2102 struct policy_mgr_psoc_priv_obj *pm_ctx, 2103 enum policy_mgr_mode hw_mode) 2104 { 2105 if (hw_mode == MODE_SMM) 2106 return true; 2107 2108 if (hw_mode == MODE_DBS) 2109 return policy_mgr_is_hw_dbs_capable(psoc); 2110 2111 if (hw_mode == MODE_SBS_UPPER_SHARE || 2112 hw_mode == MODE_SBS_LOWER_SHARE) 2113 return policy_mgr_is_hw_sbs_capable(psoc) && 2114 pm_ctx->hw_mode.sbs_lower_band_end_freq; 2115 2116 if (hw_mode == MODE_SBS) 2117 return policy_mgr_is_hw_sbs_capable(psoc); 2118 2119 return false; 2120 } 2121 2122 static bool 2123 policy_mgr_mac_freq_list_allow(uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS], 2124 uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS], 2125 uint8_t mac_freq_num) 2126 { 2127 uint8_t sta = 0, ap = 0, i; 2128 2129 switch (mac_freq_num) { 2130 case 1: 2131 case 2: 2132 return true; 2133 case 3: 2134 /* If 3 vifs are active in same mac, target only support: 2135 * 3 vifs are in SCC and 3 vifs are : 2136 * 1 STA + 2 APs, or 3 APs 2137 */ 2138 if (mac_freq_list[0] != mac_freq_list[1] || 2139 mac_freq_list[0] != mac_freq_list[2]) 2140 return false; 2141 for (i = 0; i < mac_freq_num; i++) { 2142 if (mac_mode_list[i] == PM_STA_MODE || 2143 mac_mode_list[i] == PM_P2P_CLIENT_MODE) 2144 sta++; 2145 else 2146 ap++; 2147 } 2148 2149 if (sta == 1 && ap == 2) 2150 return true; 2151 if (ap == 3) 2152 return true; 2153 return false; 2154 default: 2155 return false; 2156 } 2157 } 2158 2159 #ifdef WLAN_FEATURE_11BE_MLO 2160 static void 2161 policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc, 2162 qdf_freq_t ch_freq, 2163 enum policy_mgr_con_mode mode, 2164 uint32_t ext_flags, 2165 qdf_freq_t *ml_sta_link0_freq, 2166 qdf_freq_t *ml_sta_link1_freq) 2167 { 2168 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0; 2169 uint8_t num_active_ml_sta; 2170 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 2171 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 2172 union conc_ext_flag conc_ext_flags; 2173 2174 conc_ext_flags.value = ext_flags; 2175 /* find the two active ml sta home channels */ 2176 policy_mgr_get_ml_sta_info_psoc(psoc, &num_ml_sta, 2177 &num_disabled_ml_sta, 2178 ml_sta_vdev_lst, ml_freq_lst, 2179 NULL, NULL, NULL); 2180 if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 2181 num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 2182 num_ml_sta <= num_disabled_ml_sta) { 2183 if (num_ml_sta || num_disabled_ml_sta) 2184 policy_mgr_rl_debug("unexpected ml sta num %d %d", 2185 num_ml_sta, num_disabled_ml_sta); 2186 return; 2187 } 2188 num_active_ml_sta = num_ml_sta; 2189 if (num_ml_sta >= num_disabled_ml_sta) 2190 num_active_ml_sta = num_ml_sta - num_disabled_ml_sta; 2191 if (num_active_ml_sta > 1) { 2192 *ml_sta_link0_freq = ml_freq_lst[0]; 2193 *ml_sta_link1_freq = ml_freq_lst[1]; 2194 } else if (num_active_ml_sta > 0 && conc_ext_flags.mlo && 2195 mode == PM_STA_MODE) { 2196 *ml_sta_link0_freq = ml_freq_lst[0]; 2197 *ml_sta_link1_freq = ch_freq; 2198 } 2199 } 2200 #else 2201 static void 2202 policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc, 2203 qdf_freq_t ch_freq, 2204 enum policy_mgr_con_mode mode, 2205 uint32_t ext_flags, 2206 qdf_freq_t *ml_sta_link0_freq, 2207 qdf_freq_t *ml_sta_link1_freq) 2208 { 2209 } 2210 #endif 2211 2212 bool 2213 policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc, 2214 qdf_freq_t ch_freq, 2215 enum policy_mgr_con_mode mode, 2216 uint32_t ext_flags) 2217 { 2218 struct policy_mgr_conc_connection_info *conn = pm_conc_connection_list; 2219 uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 2220 uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 2221 uint8_t mac_freq_num; 2222 struct policy_mgr_psoc_priv_obj *pm_ctx; 2223 qdf_freq_t ml_sta_link0_freq = 0; 2224 qdf_freq_t ml_sta_link1_freq = 0; 2225 uint8_t i, j; 2226 struct policy_mgr_freq_range *freq_range; 2227 2228 pm_ctx = policy_mgr_get_context(psoc); 2229 if (!pm_ctx) { 2230 policy_mgr_err("Invalid Context"); 2231 return false; 2232 } 2233 2234 /* if HW is not DBS return false */ 2235 if (!policy_mgr_is_hw_dbs_capable(psoc)) 2236 return false; 2237 2238 /* Find the two active ml sta home channels */ 2239 policy_mgr_ml_sta_active_freq(psoc, ch_freq, mode, ext_flags, 2240 &ml_sta_link0_freq, 2241 &ml_sta_link1_freq); 2242 2243 /* Check if any hw mode can support the 4th channel frequency 2244 * and device mode. 2245 */ 2246 for (j = 0; j < MODE_HW_MAX; j++) { 2247 if (!policy_mgr_is_supported_hw_mode(psoc, pm_ctx, j)) 2248 continue; 2249 freq_range = pm_ctx->hw_mode.freq_range_caps[j]; 2250 2251 /* If ml sta present, the two links should be in 2252 * different mac always. Skip the hw mode which 2253 * causes they in same mac. 2254 */ 2255 if (ml_sta_link0_freq && ml_sta_link1_freq && 2256 policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, 2257 freq_range, 2258 ml_sta_link0_freq, 2259 ml_sta_link1_freq)) 2260 continue; 2261 for (i = 0; i < MAX_MAC; i++) { 2262 /* Get the freq list which are in the MAC 2263 * supported freq range. 2264 */ 2265 policy_mgr_get_mac_freq_list( 2266 freq_range, 2267 i, 2268 mac_freq_list, mac_mode_list, &mac_freq_num, 2269 conn[0].freq, conn[0].mode, 2270 conn[1].freq, conn[1].mode, 2271 conn[2].freq, conn[2].mode, 2272 ch_freq, mode); 2273 2274 /* Check the freq & mode list support or not in the 2275 * MAC. 2276 */ 2277 if (!policy_mgr_mac_freq_list_allow( 2278 mac_freq_list, mac_mode_list, mac_freq_num)) 2279 break; 2280 } 2281 2282 /* If the frequency/mode combination meet requirement in the 2283 * hw mode, then the 4th new ch_freq/mode are allowed to start 2284 * in this hw mode. 2285 */ 2286 if (i == MAX_MAC) { 2287 policy_mgr_rl_debug("new freq %d mode %s is allowed in hw mode %s", 2288 ch_freq, 2289 device_mode_to_string(mode), 2290 policy_mgr_hw_mode_to_str(j)); 2291 return true; 2292 } 2293 } 2294 policy_mgr_debug("the 4th new freq %d mode %s is not allowed in any hw mode", 2295 ch_freq, device_mode_to_string(mode)); 2296 2297 return false; 2298 } 2299 #endif 2300 2301 bool policy_mgr_are_sbs_chan(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1, 2302 qdf_freq_t freq_2) 2303 { 2304 struct policy_mgr_psoc_priv_obj *pm_ctx; 2305 2306 pm_ctx = policy_mgr_get_context(psoc); 2307 if (!pm_ctx) 2308 return false; 2309 2310 if (!policy_mgr_is_hw_sbs_capable(psoc)) 2311 return false; 2312 2313 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq_1) || 2314 WLAN_REG_IS_24GHZ_CH_FREQ(freq_2)) 2315 return false; 2316 2317 return !policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq_1, freq_2); 2318 } 2319 2320 bool policy_mgr_is_current_hwmode_sbs(struct wlan_objmgr_psoc *psoc) 2321 { 2322 struct policy_mgr_hw_mode_params hw_mode; 2323 2324 if (!policy_mgr_is_hw_sbs_capable(psoc)) 2325 return false; 2326 2327 if (QDF_STATUS_SUCCESS != 2328 policy_mgr_get_current_hw_mode(psoc, &hw_mode)) 2329 return false; 2330 2331 if (hw_mode.sbs_cap && policy_mgr_is_cur_freq_range_sbs(psoc)) 2332 return true; 2333 2334 return false; 2335 } 2336 2337 void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc, 2338 uint32_t num_dbs_hw_modes, 2339 uint32_t *ev_wlan_dbs_hw_mode_list) 2340 { 2341 struct policy_mgr_psoc_priv_obj *pm_ctx; 2342 2343 pm_ctx = policy_mgr_get_context(psoc); 2344 if (!pm_ctx) { 2345 policy_mgr_err("Invalid Context"); 2346 return; 2347 } 2348 2349 pm_ctx->num_dbs_hw_modes = num_dbs_hw_modes; 2350 pm_ctx->hw_mode.hw_mode_list = 2351 qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) * 2352 pm_ctx->num_dbs_hw_modes); 2353 if (!pm_ctx->hw_mode.hw_mode_list) { 2354 pm_ctx->num_dbs_hw_modes = 0; 2355 return; 2356 } 2357 2358 qdf_mem_copy(pm_ctx->hw_mode.hw_mode_list, 2359 ev_wlan_dbs_hw_mode_list, 2360 (sizeof(*pm_ctx->hw_mode.hw_mode_list) * 2361 pm_ctx->num_dbs_hw_modes)); 2362 2363 policy_mgr_dump_dbs_hw_mode(psoc); 2364 } 2365 2366 void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc) 2367 { 2368 uint32_t i; 2369 uint32_t param; 2370 uint32_t param1; 2371 2372 struct policy_mgr_psoc_priv_obj *pm_ctx; 2373 2374 pm_ctx = policy_mgr_get_context(psoc); 2375 if (!pm_ctx) { 2376 policy_mgr_err("Invalid Context"); 2377 return; 2378 } 2379 policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d", 2380 pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index); 2381 2382 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 2383 param = pm_ctx->hw_mode.hw_mode_list[i]; 2384 param1 = pm_ctx->hw_mode.hw_mode_list[i] >> 32; 2385 policy_mgr_debug("[%d] 0x%x 0x%x", i, param, param1); 2386 policy_mgr_debug("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d band_cap:%d", 2387 i, 2388 POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param), 2389 POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param), 2390 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param), 2391 POLICY_MGR_HW_MODE_MAC0_BAND_GET(param)); 2392 policy_mgr_debug("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d", 2393 i, 2394 POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param), 2395 POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param), 2396 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param)); 2397 policy_mgr_debug("[%d] DBS:%d SBS:%d hw_mode_id:%d", i, 2398 POLICY_MGR_HW_MODE_DBS_MODE_GET(param), 2399 POLICY_MGR_HW_MODE_SBS_MODE_GET(param), 2400 POLICY_MGR_HW_MODE_ID_GET(param)); 2401 } 2402 } 2403 2404 void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc, 2405 uint32_t scan_config, uint32_t fw_config) 2406 { 2407 struct policy_mgr_psoc_priv_obj *pm_ctx; 2408 uint8_t dual_mac_feature; 2409 2410 pm_ctx = policy_mgr_get_context(psoc); 2411 if (!pm_ctx) { 2412 policy_mgr_err("Invalid Context"); 2413 return; 2414 } 2415 pm_ctx->dual_mac_cfg.cur_scan_config = 0; 2416 pm_ctx->dual_mac_cfg.cur_fw_mode_config = 0; 2417 2418 dual_mac_feature = pm_ctx->cfg.dual_mac_feature; 2419 /* If dual mac features are disabled in the INI, we 2420 * need not proceed further 2421 */ 2422 if (dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) { 2423 policy_mgr_err("Disabling dual mac capabilities"); 2424 /* All capabilities are initialized to 0. We can return */ 2425 goto done; 2426 } 2427 2428 /* Initialize concurrent_scan_config_bits with default FW value */ 2429 WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET( 2430 pm_ctx->dual_mac_cfg.cur_scan_config, 2431 WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_GET(scan_config)); 2432 WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_SET( 2433 pm_ctx->dual_mac_cfg.cur_scan_config, 2434 WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_GET(scan_config)); 2435 WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET( 2436 pm_ctx->dual_mac_cfg.cur_scan_config, 2437 WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config)); 2438 WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET( 2439 pm_ctx->dual_mac_cfg.cur_scan_config, 2440 WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config)); 2441 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET( 2442 pm_ctx->dual_mac_cfg.cur_scan_config, 2443 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config)); 2444 2445 /* Initialize fw_mode_config_bits with default FW value */ 2446 WMI_DBS_FW_MODE_CFG_DBS_SET( 2447 pm_ctx->dual_mac_cfg.cur_fw_mode_config, 2448 WMI_DBS_FW_MODE_CFG_DBS_GET(fw_config)); 2449 WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET( 2450 pm_ctx->dual_mac_cfg.cur_fw_mode_config, 2451 WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_config)); 2452 WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET( 2453 pm_ctx->dual_mac_cfg.cur_fw_mode_config, 2454 WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_GET(fw_config)); 2455 done: 2456 /* Initialize the previous scan/fw mode config */ 2457 pm_ctx->dual_mac_cfg.prev_scan_config = 2458 pm_ctx->dual_mac_cfg.cur_scan_config; 2459 pm_ctx->dual_mac_cfg.prev_fw_mode_config = 2460 pm_ctx->dual_mac_cfg.cur_fw_mode_config; 2461 2462 policy_mgr_debug("cur_scan_config:%x cur_fw_mode_config:%x", 2463 pm_ctx->dual_mac_cfg.cur_scan_config, 2464 pm_ctx->dual_mac_cfg.cur_fw_mode_config); 2465 } 2466 2467 void policy_mgr_init_sbs_fw_config(struct wlan_objmgr_psoc *psoc, 2468 uint32_t fw_config) 2469 { 2470 struct policy_mgr_psoc_priv_obj *pm_ctx; 2471 bool sbs_enabled; 2472 2473 pm_ctx = policy_mgr_get_context(psoc); 2474 if (!pm_ctx) { 2475 policy_mgr_err("Invalid Context"); 2476 return; 2477 } 2478 2479 /* 2480 * If SBS is not enabled from ini, no need to set SBS bits in fw config 2481 */ 2482 sbs_enabled = pm_ctx->cfg.sbs_enable; 2483 if (!sbs_enabled) { 2484 policy_mgr_debug("SBS not enabled from ini"); 2485 return; 2486 } 2487 2488 /* Initialize fw_mode_config_bits with default FW value */ 2489 WMI_DBS_FW_MODE_CFG_ASYNC_SBS_SET( 2490 pm_ctx->dual_mac_cfg.cur_fw_mode_config, 2491 WMI_DBS_FW_MODE_CFG_ASYNC_SBS_GET(fw_config)); 2492 2493 policy_mgr_debug("fw_mode config updated from %x to %x", 2494 pm_ctx->dual_mac_cfg.prev_fw_mode_config, 2495 pm_ctx->dual_mac_cfg.cur_fw_mode_config); 2496 /* Initialize the previous scan/fw mode config */ 2497 pm_ctx->dual_mac_cfg.prev_fw_mode_config = 2498 pm_ctx->dual_mac_cfg.cur_fw_mode_config; 2499 } 2500 2501 void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc) 2502 { 2503 struct policy_mgr_psoc_priv_obj *pm_ctx; 2504 2505 pm_ctx = policy_mgr_get_context(psoc); 2506 if (!pm_ctx) { 2507 policy_mgr_err("Invalid Context"); 2508 return; 2509 } 2510 2511 pm_ctx->dual_mac_cfg.prev_scan_config = 2512 pm_ctx->dual_mac_cfg.cur_scan_config; 2513 pm_ctx->dual_mac_cfg.cur_scan_config = 2514 pm_ctx->dual_mac_cfg.req_scan_config; 2515 } 2516 2517 void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc) 2518 { 2519 struct policy_mgr_psoc_priv_obj *pm_ctx; 2520 2521 pm_ctx = policy_mgr_get_context(psoc); 2522 if (!pm_ctx) { 2523 policy_mgr_err("Invalid Context"); 2524 return; 2525 } 2526 2527 pm_ctx->dual_mac_cfg.prev_fw_mode_config = 2528 pm_ctx->dual_mac_cfg.cur_fw_mode_config; 2529 pm_ctx->dual_mac_cfg.cur_fw_mode_config = 2530 pm_ctx->dual_mac_cfg.req_fw_mode_config; 2531 } 2532 2533 void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc, 2534 uint32_t scan_config, uint32_t fw_mode_config) 2535 { 2536 struct policy_mgr_psoc_priv_obj *pm_ctx; 2537 2538 pm_ctx = policy_mgr_get_context(psoc); 2539 if (!pm_ctx) { 2540 policy_mgr_err("Invalid Context"); 2541 return; 2542 } 2543 pm_ctx->dual_mac_cfg.req_scan_config = scan_config; 2544 pm_ctx->dual_mac_cfg.req_fw_mode_config = fw_mode_config; 2545 } 2546 2547 bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc) 2548 { 2549 uint32_t scan_config; 2550 struct policy_mgr_psoc_priv_obj *pm_ctx; 2551 2552 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) 2553 return false; 2554 2555 2556 pm_ctx = policy_mgr_get_context(psoc); 2557 if (!pm_ctx) { 2558 policy_mgr_err("Invalid Context"); 2559 /* We take that it is disabled and proceed */ 2560 return false; 2561 } 2562 scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; 2563 2564 return WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config); 2565 } 2566 2567 bool policy_mgr_get_single_mac_scan_with_dfs_config( 2568 struct wlan_objmgr_psoc *psoc) 2569 { 2570 uint32_t scan_config; 2571 struct policy_mgr_psoc_priv_obj *pm_ctx; 2572 2573 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) 2574 return false; 2575 2576 2577 pm_ctx = policy_mgr_get_context(psoc); 2578 if (!pm_ctx) { 2579 policy_mgr_err("Invalid Context"); 2580 /* We take that it is disabled and proceed */ 2581 return false; 2582 } 2583 scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; 2584 2585 return WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config); 2586 } 2587 2588 int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc) 2589 { 2590 struct policy_mgr_psoc_priv_obj *pm_ctx; 2591 2592 pm_ctx = policy_mgr_get_context(psoc); 2593 if (!pm_ctx) { 2594 policy_mgr_err("Invalid Context"); 2595 return -EINVAL; 2596 } 2597 return pm_ctx->num_dbs_hw_modes; 2598 } 2599 2600 bool policy_mgr_find_if_fw_supports_dbs(struct wlan_objmgr_psoc *psoc) 2601 { 2602 struct policy_mgr_psoc_priv_obj *pm_ctx; 2603 struct wmi_unified *wmi_handle; 2604 bool dbs_support; 2605 2606 pm_ctx = policy_mgr_get_context(psoc); 2607 2608 if (!pm_ctx) { 2609 policy_mgr_err("Invalid Context"); 2610 return false; 2611 } 2612 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 2613 if (!wmi_handle) { 2614 policy_mgr_debug("Invalid WMI handle"); 2615 return false; 2616 } 2617 dbs_support = 2618 wmi_service_enabled(wmi_handle, 2619 wmi_service_dual_band_simultaneous_support); 2620 2621 /* The agreement with FW is that: To know if the target is DBS 2622 * capable, DBS needs to be supported both in the HW mode list 2623 * and in the service ready event 2624 */ 2625 if (!dbs_support) 2626 return false; 2627 2628 return true; 2629 } 2630 2631 bool policy_mgr_find_if_hwlist_has_dbs(struct wlan_objmgr_psoc *psoc) 2632 { 2633 struct policy_mgr_psoc_priv_obj *pm_ctx; 2634 uint32_t param, i, found = 0; 2635 2636 pm_ctx = policy_mgr_get_context(psoc); 2637 2638 if (!pm_ctx) { 2639 policy_mgr_err("Invalid Context"); 2640 return false; 2641 } 2642 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 2643 param = pm_ctx->hw_mode.hw_mode_list[i]; 2644 if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) { 2645 found = 1; 2646 break; 2647 } 2648 } 2649 if (found) 2650 return true; 2651 2652 return false; 2653 } 2654 2655 static bool policy_mgr_find_if_hwlist_has_sbs(struct wlan_objmgr_psoc *psoc) 2656 { 2657 struct policy_mgr_psoc_priv_obj *pm_ctx; 2658 uint32_t param, i; 2659 2660 pm_ctx = policy_mgr_get_context(psoc); 2661 2662 if (!pm_ctx) { 2663 policy_mgr_err("Invalid Context"); 2664 return false; 2665 } 2666 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 2667 param = pm_ctx->hw_mode.hw_mode_list[i]; 2668 if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) { 2669 return true; 2670 } 2671 } 2672 2673 return false; 2674 } 2675 2676 bool policy_mgr_is_dbs_scan_allowed(struct wlan_objmgr_psoc *psoc) 2677 { 2678 uint8_t dbs_type = DISABLE_DBS_CXN_AND_SCAN; 2679 struct policy_mgr_psoc_priv_obj *pm_ctx; 2680 2681 pm_ctx = policy_mgr_get_context(psoc); 2682 if (!pm_ctx) { 2683 policy_mgr_err("Invalid Context"); 2684 return false; 2685 } 2686 2687 if (!policy_mgr_find_if_fw_supports_dbs(psoc) || 2688 !policy_mgr_find_if_hwlist_has_dbs(psoc)) 2689 return false; 2690 2691 policy_mgr_get_dual_mac_feature(psoc, &dbs_type); 2692 /* 2693 * If DBS support for scan is disabled through INI then DBS is not 2694 * supported for scan. 2695 * 2696 * For DBS scan check the INI value explicitly 2697 */ 2698 switch (dbs_type) { 2699 case DISABLE_DBS_CXN_AND_SCAN: 2700 case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN: 2701 return false; 2702 default: 2703 return true; 2704 } 2705 } 2706 2707 bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) 2708 { 2709 if (!policy_mgr_is_dbs_enable(psoc)) 2710 return false; 2711 2712 if (!policy_mgr_find_if_fw_supports_dbs(psoc)) 2713 return false; 2714 2715 if (!policy_mgr_find_if_hwlist_has_dbs(psoc)) { 2716 policymgr_nofl_debug("HW mode list has no DBS"); 2717 return false; 2718 } 2719 2720 return true; 2721 } 2722 2723 bool policy_mgr_is_hw_emlsr_capable(struct wlan_objmgr_psoc *psoc) 2724 { 2725 struct policy_mgr_psoc_priv_obj *pm_ctx; 2726 uint64_t param, i; 2727 2728 pm_ctx = policy_mgr_get_context(psoc); 2729 2730 if (!pm_ctx) { 2731 policy_mgr_err("Invalid Context"); 2732 return false; 2733 } 2734 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 2735 param = pm_ctx->hw_mode.hw_mode_list[i]; 2736 if (POLICY_MGR_HW_MODE_EMLSR_MODE_GET(param)) 2737 return true; 2738 } 2739 2740 return false; 2741 } 2742 2743 bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc) 2744 { 2745 struct policy_mgr_hw_mode_params hw_mode; 2746 2747 if (!policy_mgr_is_hw_dbs_capable(psoc)) 2748 return false; 2749 2750 if (QDF_STATUS_SUCCESS != policy_mgr_get_current_hw_mode(psoc, 2751 &hw_mode)) 2752 return false; 2753 2754 if (!hw_mode.dbs_cap) 2755 return false; 2756 2757 /* sbs is not enabled and dbs_cap is set return true */ 2758 if (!policy_mgr_is_hw_sbs_capable(psoc)) 2759 return true; 2760 2761 /* sbs is enabled and dbs_cap is set then check the freq range */ 2762 if (!policy_mgr_is_cur_freq_range_sbs(psoc)) 2763 return true; 2764 2765 return false; 2766 } 2767 2768 bool policy_mgr_is_pcl_weightage_required(struct wlan_objmgr_psoc *psoc) 2769 { 2770 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2771 struct dual_sta_policy *dual_sta_policy; 2772 2773 mlme_obj = mlme_get_psoc_ext_obj(psoc); 2774 if (!mlme_obj) 2775 return true; 2776 2777 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 2778 2779 if (dual_sta_policy->concurrent_sta_policy == 2780 QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && 2781 dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 2782 policy_mgr_debug("dual_sta_policy : %d, primary_vdev_id:%d", 2783 dual_sta_policy->concurrent_sta_policy, 2784 dual_sta_policy->primary_vdev_id); 2785 return false; 2786 } 2787 2788 return true; 2789 } 2790 2791 bool policy_mgr_is_interband_mcc_supported(struct wlan_objmgr_psoc *psoc) 2792 { 2793 struct policy_mgr_psoc_priv_obj *pm_ctx; 2794 struct wmi_unified *wmi_handle; 2795 2796 pm_ctx = policy_mgr_get_context(psoc); 2797 2798 if (!pm_ctx) { 2799 policy_mgr_err("Invalid Context"); 2800 return false; 2801 } 2802 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 2803 if (!wmi_handle) { 2804 policy_mgr_debug("Invalid WMI handle"); 2805 return false; 2806 } 2807 2808 return !wmi_service_enabled(wmi_handle, 2809 wmi_service_no_interband_mcc_support); 2810 } 2811 2812 static bool policy_mgr_is_sbs_enable(struct wlan_objmgr_psoc *psoc) 2813 { 2814 struct policy_mgr_psoc_priv_obj *pm_ctx; 2815 2816 pm_ctx = policy_mgr_get_context(psoc); 2817 if (!pm_ctx) { 2818 policy_mgr_err("Invalid Context"); 2819 return false; 2820 } 2821 2822 /* 2823 * if gEnableSBS is not set then policy_mgr_init_sbs_fw_config won't 2824 * enable Async SBS fw config bit 2825 */ 2826 if (WMI_DBS_FW_MODE_CFG_ASYNC_SBS_GET( 2827 pm_ctx->dual_mac_cfg.cur_fw_mode_config)) 2828 return true; 2829 2830 return false; 2831 } 2832 2833 bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) 2834 { 2835 if (!policy_mgr_is_sbs_enable(psoc)) { 2836 policy_mgr_rl_debug("SBS INI is disabled"); 2837 return false; 2838 } 2839 2840 if (!policy_mgr_find_if_fw_supports_dbs(psoc)) { 2841 policy_mgr_rl_debug("fw doesn't support dual band"); 2842 return false; 2843 } 2844 2845 if (!policy_mgr_find_if_hwlist_has_sbs(psoc)) { 2846 policy_mgr_rl_debug("HW mode list has no SBS"); 2847 return false; 2848 } 2849 2850 return true; 2851 } 2852 2853 QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, 2854 bool *one_by_one_dbs, bool *two_by_two_dbs) 2855 { 2856 struct policy_mgr_psoc_priv_obj *pm_ctx; 2857 uint32_t i; 2858 int8_t found_one_by_one = -EINVAL, found_two_by_two = -EINVAL; 2859 uint32_t conf1_tx_ss, conf1_rx_ss; 2860 uint32_t conf2_tx_ss, conf2_rx_ss; 2861 2862 *one_by_one_dbs = false; 2863 *two_by_two_dbs = false; 2864 2865 if (policy_mgr_is_hw_dbs_capable(psoc) == false) { 2866 policy_mgr_rl_debug("HW is not DBS capable"); 2867 /* Caller will understand that DBS is disabled */ 2868 return QDF_STATUS_SUCCESS; 2869 2870 } 2871 2872 pm_ctx = policy_mgr_get_context(psoc); 2873 if (!pm_ctx) { 2874 policy_mgr_err("Invalid Context"); 2875 return QDF_STATUS_E_FAILURE; 2876 } 2877 2878 /* To check 1x1 capability */ 2879 policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_1x1, 2880 &conf1_tx_ss, &conf1_rx_ss); 2881 /* To check 2x2 capability */ 2882 policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_2x2, 2883 &conf2_tx_ss, &conf2_rx_ss); 2884 2885 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 2886 uint32_t t_conf0_tx_ss, t_conf0_rx_ss; 2887 uint32_t t_conf1_tx_ss, t_conf1_rx_ss; 2888 uint32_t dbs_mode; 2889 2890 t_conf0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET( 2891 pm_ctx->hw_mode.hw_mode_list[i]); 2892 t_conf0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET( 2893 pm_ctx->hw_mode.hw_mode_list[i]); 2894 t_conf1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET( 2895 pm_ctx->hw_mode.hw_mode_list[i]); 2896 t_conf1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET( 2897 pm_ctx->hw_mode.hw_mode_list[i]); 2898 dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET( 2899 pm_ctx->hw_mode.hw_mode_list[i]); 2900 2901 if (((((t_conf0_tx_ss == conf1_tx_ss) && 2902 (t_conf0_rx_ss == conf1_rx_ss)) || 2903 ((t_conf1_tx_ss == conf1_tx_ss) && 2904 (t_conf1_rx_ss == conf1_rx_ss))) && 2905 (dbs_mode == HW_MODE_DBS)) && 2906 (found_one_by_one < 0)) { 2907 found_one_by_one = i; 2908 policy_mgr_debug("1x1 hw_mode index %d found", i); 2909 /* Once an entry is found, need not check for 1x1 2910 * again 2911 */ 2912 continue; 2913 } 2914 2915 if (((((t_conf0_tx_ss == conf2_tx_ss) && 2916 (t_conf0_rx_ss == conf2_rx_ss)) || 2917 ((t_conf1_tx_ss == conf2_tx_ss) && 2918 (t_conf1_rx_ss == conf2_rx_ss))) && 2919 (dbs_mode == HW_MODE_DBS)) && 2920 (found_two_by_two < 0)) { 2921 found_two_by_two = i; 2922 policy_mgr_debug("2x2 hw_mode index %d found", i); 2923 /* Once an entry is found, need not check for 2x2 2924 * again 2925 */ 2926 continue; 2927 } 2928 } 2929 2930 if (found_one_by_one >= 0) 2931 *one_by_one_dbs = true; 2932 if (found_two_by_two >= 0) 2933 *two_by_two_dbs = true; 2934 2935 return QDF_STATUS_SUCCESS; 2936 } 2937 2938 QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc, 2939 struct policy_mgr_hw_mode_params *hw_mode) 2940 { 2941 QDF_STATUS status; 2942 uint32_t old_hw_index = 0, new_hw_index = 0; 2943 2944 status = policy_mgr_get_old_and_new_hw_index(psoc, &old_hw_index, 2945 &new_hw_index); 2946 if (QDF_STATUS_SUCCESS != status) { 2947 policy_mgr_err("Failed to get HW mode index"); 2948 return QDF_STATUS_E_FAILURE; 2949 } 2950 2951 if (new_hw_index == POLICY_MGR_DEFAULT_HW_MODE_INDEX) { 2952 policy_mgr_err("HW mode is not yet initialized"); 2953 return QDF_STATUS_E_FAILURE; 2954 } 2955 2956 status = policy_mgr_get_hw_mode_from_idx(psoc, new_hw_index, hw_mode); 2957 if (QDF_STATUS_SUCCESS != status) { 2958 policy_mgr_err("Failed to get HW mode index"); 2959 return QDF_STATUS_E_FAILURE; 2960 } 2961 return QDF_STATUS_SUCCESS; 2962 } 2963 2964 bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) 2965 { 2966 struct policy_mgr_psoc_priv_obj *pm_ctx; 2967 2968 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) { 2969 policy_mgr_rl_debug("DBS is disabled from ini"); 2970 return false; 2971 } 2972 2973 pm_ctx = policy_mgr_get_context(psoc); 2974 if (!pm_ctx) { 2975 policy_mgr_err("Invalid Context"); 2976 return false; 2977 } 2978 2979 if (WMI_DBS_FW_MODE_CFG_DBS_GET( 2980 pm_ctx->dual_mac_cfg.cur_fw_mode_config)) 2981 return true; 2982 2983 return false; 2984 } 2985 2986 bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc) 2987 { 2988 struct dbs_nss nss_dbs = {0}; 2989 uint32_t nss; 2990 2991 nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); 2992 if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss == nss_dbs.mac1_ss)) 2993 return true; 2994 else 2995 return false; 2996 } 2997 2998 bool policy_mgr_is_hw_dbs_required_for_band(struct wlan_objmgr_psoc *psoc, 2999 enum hw_mode_mac_band_cap band) 3000 { 3001 struct dbs_nss nss_dbs = {0}; 3002 uint32_t nss; 3003 3004 nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); 3005 if (nss >= HW_MODE_SS_1x1 && nss_dbs.mac0_ss >= nss_dbs.mac1_ss && 3006 !(nss_dbs.single_mac0_band_cap & band)) 3007 return true; 3008 else 3009 return false; 3010 } 3011 3012 bool policy_mgr_is_dp_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) 3013 { 3014 return policy_mgr_find_if_hwlist_has_dbs(psoc); 3015 } 3016 3017 /* 3018 * policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not 3019 * @psoc: PSOC object data 3020 * 3021 * This routine is called to check 2x2 5G + 1x1 2G (DBS1) or 3022 * 2x2 2G + 1x1 5G (DBS2) support or not. 3023 * Either DBS1 or DBS2 supported 3024 * 3025 * Return: true/false 3026 */ 3027 bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc) 3028 { 3029 struct dbs_nss nss_dbs; 3030 uint32_t nss; 3031 3032 nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); 3033 if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss > nss_dbs.mac1_ss)) 3034 return true; 3035 else 3036 return false; 3037 } 3038 3039 /* 3040 * policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not 3041 * @psoc: PSOC object data 3042 * 3043 * This routine is called to check support DBS1 or not. 3044 * Notes: DBS1: 2x2 5G + 1x1 2G. 3045 * This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match 3046 * the HW mode from hw mode list. The parameters will also be matched to 3047 * 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone 3048 * with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with 3049 * policy_mgr_get_hw_mode_idx_from_dbs_hw_list. 3050 * 3051 * Return: true/false 3052 */ 3053 bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc) 3054 { 3055 return policy_mgr_is_2x2_1x1_dbs_capable(psoc) && 3056 (policy_mgr_get_hw_mode_idx_from_dbs_hw_list( 3057 psoc, 3058 HW_MODE_SS_2x2, 3059 HW_MODE_80_MHZ, 3060 HW_MODE_SS_1x1, HW_MODE_40_MHZ, 3061 HW_MODE_MAC_BAND_5G, 3062 HW_MODE_DBS, 3063 HW_MODE_AGILE_DFS_NONE, 3064 HW_MODE_SBS_NONE) >= 0); 3065 } 3066 3067 /* 3068 * policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not 3069 * @psoc: PSOC object data 3070 * 3071 * This routine is called to check support DBS2 or not. 3072 * Notes: DBS2: 2x2 2G + 1x1 5G 3073 * 3074 * Return: true/false 3075 */ 3076 bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc) 3077 { 3078 return policy_mgr_is_2x2_1x1_dbs_capable(psoc) && 3079 (policy_mgr_get_hw_mode_idx_from_dbs_hw_list( 3080 psoc, 3081 HW_MODE_SS_2x2, 3082 HW_MODE_40_MHZ, 3083 HW_MODE_SS_1x1, HW_MODE_40_MHZ, 3084 HW_MODE_MAC_BAND_2G, 3085 HW_MODE_DBS, 3086 HW_MODE_AGILE_DFS_NONE, 3087 HW_MODE_SBS_NONE) >= 0); 3088 } 3089 3090 uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) 3091 { 3092 uint32_t conn_index, count = 0; 3093 struct policy_mgr_psoc_priv_obj *pm_ctx; 3094 3095 pm_ctx = policy_mgr_get_context(psoc); 3096 if (!pm_ctx) { 3097 policy_mgr_err("Invalid Context"); 3098 return count; 3099 } 3100 3101 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3102 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 3103 conn_index++) { 3104 if (pm_conc_connection_list[conn_index].in_use) 3105 count++; 3106 } 3107 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3108 3109 return count; 3110 } 3111 3112 uint32_t 3113 policy_mgr_get_connection_count_with_mlo(struct wlan_objmgr_psoc *psoc) 3114 { 3115 uint32_t conn_index, count = 0; 3116 struct policy_mgr_psoc_priv_obj *pm_ctx; 3117 enum policy_mgr_con_mode mode; 3118 bool is_mlo = false, count_mlo = false; 3119 3120 pm_ctx = policy_mgr_get_context(psoc); 3121 if (!pm_ctx) { 3122 policy_mgr_err("Invalid Context"); 3123 return count; 3124 } 3125 3126 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3127 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 3128 conn_index++) { 3129 if (pm_conc_connection_list[conn_index].in_use) { 3130 is_mlo = policy_mgr_is_ml_vdev_id(psoc, 3131 pm_conc_connection_list[conn_index].vdev_id); 3132 mode = pm_conc_connection_list[conn_index].mode; 3133 if (is_mlo && (mode == PM_STA_MODE)) { 3134 if (!count_mlo) { 3135 count_mlo = true; 3136 count++; 3137 } 3138 } else { 3139 count++; 3140 } 3141 } 3142 } 3143 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3144 3145 return count; 3146 } 3147 3148 uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc, 3149 enum policy_mgr_con_mode mode) 3150 { 3151 uint32_t conn_index = 0; 3152 uint32_t vdev_id = WLAN_INVALID_VDEV_ID; 3153 struct policy_mgr_psoc_priv_obj *pm_ctx; 3154 3155 pm_ctx = policy_mgr_get_context(psoc); 3156 if (!pm_ctx) { 3157 policy_mgr_err("Invalid Context"); 3158 return vdev_id; 3159 } 3160 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3161 /* 3162 * Note: This gives you the first vdev id of the mode type in a 3163 * sta+sta or sap+sap or p2p + p2p case 3164 */ 3165 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 3166 conn_index++) { 3167 if ((pm_conc_connection_list[conn_index].mode == mode) && 3168 pm_conc_connection_list[conn_index].in_use) { 3169 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 3170 break; 3171 } 3172 } 3173 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3174 3175 return vdev_id; 3176 } 3177 3178 uint32_t policy_mgr_mode_get_macid_by_vdev_id(struct wlan_objmgr_psoc *psoc, 3179 uint32_t vdev_id) 3180 { 3181 uint32_t conn_index = 0; 3182 uint32_t mac_id = 0xFF; 3183 enum policy_mgr_con_mode mode; 3184 struct policy_mgr_psoc_priv_obj *pm_ctx; 3185 3186 pm_ctx = policy_mgr_get_context(psoc); 3187 if (!pm_ctx) { 3188 policy_mgr_err("Invalid Context"); 3189 return vdev_id; 3190 } 3191 mode = policy_mgr_con_mode_by_vdev_id(psoc, vdev_id); 3192 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3193 3194 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 3195 conn_index++) { 3196 if ((pm_conc_connection_list[conn_index].mode == mode) && 3197 pm_conc_connection_list[conn_index].in_use && 3198 vdev_id == pm_conc_connection_list[conn_index].vdev_id) { 3199 mac_id = pm_conc_connection_list[conn_index].mac; 3200 break; 3201 } 3202 } 3203 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3204 3205 return mac_id; 3206 } 3207 3208 uint32_t policy_mgr_mode_specific_connection_count( 3209 struct wlan_objmgr_psoc *psoc, 3210 enum policy_mgr_con_mode mode, 3211 uint32_t *list) 3212 { 3213 uint32_t conn_index = 0, count = 0; 3214 struct policy_mgr_psoc_priv_obj *pm_ctx; 3215 3216 pm_ctx = policy_mgr_get_context(psoc); 3217 if (!pm_ctx) { 3218 policy_mgr_err("Invalid Context"); 3219 return count; 3220 } 3221 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3222 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 3223 conn_index++) { 3224 if ((pm_conc_connection_list[conn_index].mode == mode) && 3225 pm_conc_connection_list[conn_index].in_use) { 3226 if (list) 3227 list[count] = conn_index; 3228 count++; 3229 } 3230 } 3231 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3232 3233 return count; 3234 } 3235 3236 uint32_t policy_mgr_get_sap_mode_count(struct wlan_objmgr_psoc *psoc, 3237 uint32_t *list) 3238 { 3239 uint32_t count; 3240 3241 count = policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, 3242 list); 3243 3244 count += policy_mgr_mode_specific_connection_count( 3245 psoc, 3246 PM_LL_LT_SAP_MODE, 3247 list ? &list[count] : NULL); 3248 return count; 3249 } 3250 3251 uint32_t policy_mgr_get_beaconing_mode_count(struct wlan_objmgr_psoc *psoc, 3252 uint32_t *list) 3253 { 3254 uint32_t count; 3255 3256 count = policy_mgr_get_sap_mode_count(psoc, list); 3257 3258 count += policy_mgr_mode_specific_connection_count( 3259 psoc, 3260 PM_P2P_GO_MODE, 3261 list ? &list[count] : NULL); 3262 return count; 3263 } 3264 3265 QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id( 3266 struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, 3267 uint32_t vdev_id) 3268 { 3269 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3270 uint32_t conn_index = 0; 3271 struct policy_mgr_psoc_priv_obj *pm_ctx; 3272 3273 pm_ctx = policy_mgr_get_context(psoc); 3274 if (!pm_ctx) { 3275 policy_mgr_err("Invalid Context"); 3276 return qdf_status; 3277 } 3278 3279 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3280 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 3281 if ((pm_conc_connection_list[conn_index].mode == mode) && 3282 (pm_conc_connection_list[conn_index].vdev_id == vdev_id)) { 3283 qdf_status = QDF_STATUS_SUCCESS; 3284 break; 3285 } 3286 conn_index++; 3287 } 3288 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3289 return qdf_status; 3290 } 3291 3292 void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, 3293 uint32_t scan_config, 3294 uint32_t fw_mode_config) 3295 { 3296 policy_mgr_debug("Status:%d for scan_config:%x fw_mode_config:%x", 3297 status, scan_config, fw_mode_config); 3298 } 3299 3300 void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, 3301 uint8_t dbs_val, 3302 uint8_t dbs_plus_agile_scan_val, 3303 uint8_t single_mac_scan_with_dbs_val) 3304 { 3305 struct policy_mgr_dual_mac_config cfg; 3306 QDF_STATUS status; 3307 struct policy_mgr_psoc_priv_obj *pm_ctx; 3308 3309 pm_ctx = policy_mgr_get_context(psoc); 3310 if (!pm_ctx) { 3311 policy_mgr_err("Invalid Context"); 3312 return; 3313 } 3314 3315 /* Any non-zero positive value is treated as 1 */ 3316 if (dbs_val != 0) 3317 dbs_val = 1; 3318 if (dbs_plus_agile_scan_val != 0) 3319 dbs_plus_agile_scan_val = 1; 3320 if (single_mac_scan_with_dbs_val != 0) 3321 single_mac_scan_with_dbs_val = 1; 3322 3323 status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config, 3324 dbs_val, 3325 dbs_plus_agile_scan_val, 3326 single_mac_scan_with_dbs_val); 3327 if (status != QDF_STATUS_SUCCESS) { 3328 policy_mgr_err("policy_mgr_get_updated_scan_config failed %d", 3329 status); 3330 return; 3331 } 3332 3333 status = policy_mgr_get_updated_fw_mode_config(psoc, 3334 &cfg.fw_mode_config, 3335 policy_mgr_get_dbs_config(psoc), 3336 policy_mgr_get_agile_dfs_config(psoc)); 3337 if (status != QDF_STATUS_SUCCESS) { 3338 policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d", 3339 status); 3340 return; 3341 } 3342 3343 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; 3344 3345 policy_mgr_debug("scan_config:%x fw_mode_config:%x", 3346 cfg.scan_config, cfg.fw_mode_config); 3347 3348 status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg); 3349 if (status != QDF_STATUS_SUCCESS) 3350 policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status); 3351 } 3352 3353 void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, 3354 uint8_t dbs, uint8_t dfs) 3355 { 3356 struct policy_mgr_dual_mac_config cfg; 3357 QDF_STATUS status; 3358 struct policy_mgr_psoc_priv_obj *pm_ctx; 3359 3360 pm_ctx = policy_mgr_get_context(psoc); 3361 if (!pm_ctx) { 3362 policy_mgr_err("Invalid Context"); 3363 return; 3364 } 3365 3366 /* Any non-zero positive value is treated as 1 */ 3367 if (dbs != 0) 3368 dbs = 1; 3369 if (dfs != 0) 3370 dfs = 1; 3371 3372 status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config, 3373 policy_mgr_get_dbs_scan_config(psoc), 3374 policy_mgr_get_dbs_plus_agile_scan_config(psoc), 3375 policy_mgr_get_single_mac_scan_with_dfs_config(psoc)); 3376 if (status != QDF_STATUS_SUCCESS) { 3377 policy_mgr_err("policy_mgr_get_updated_scan_config failed %d", 3378 status); 3379 return; 3380 } 3381 3382 status = policy_mgr_get_updated_fw_mode_config(psoc, 3383 &cfg.fw_mode_config, dbs, dfs); 3384 if (status != QDF_STATUS_SUCCESS) { 3385 policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d", 3386 status); 3387 return; 3388 } 3389 3390 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; 3391 3392 policy_mgr_debug("scan_config:%x fw_mode_config:%x", 3393 cfg.scan_config, cfg.fw_mode_config); 3394 3395 status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg); 3396 if (status != QDF_STATUS_SUCCESS) 3397 policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status); 3398 } 3399 3400 bool policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, 3401 uint8_t vdev_id) 3402 { 3403 struct policy_mgr_psoc_priv_obj *pm_ctx; 3404 uint32_t i, ch_freq; 3405 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3406 3407 pm_ctx = policy_mgr_get_context(psoc); 3408 if (!pm_ctx) { 3409 policy_mgr_err("Invalid Context"); 3410 return false; 3411 } 3412 3413 /* Get the channel freq for a given vdev_id */ 3414 status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, 3415 &ch_freq); 3416 if (QDF_IS_STATUS_ERROR(status)) { 3417 policy_mgr_err("Failed to get channel for vdev:%d", vdev_id); 3418 return false; 3419 } 3420 3421 /* Compare given vdev_id freq against other vdev_id's */ 3422 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3423 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 3424 if ((pm_conc_connection_list[i].vdev_id != vdev_id) && 3425 (pm_conc_connection_list[i].in_use) && 3426 (pm_conc_connection_list[i].freq == ch_freq)) { 3427 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3428 return true; 3429 } 3430 } 3431 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3432 3433 return false; 3434 } 3435 3436 bool policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, 3437 uint8_t vdev_id, uint8_t *mcc_vdev_id) 3438 { 3439 struct policy_mgr_psoc_priv_obj *pm_ctx; 3440 uint32_t i, ch_freq; 3441 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3442 3443 if (mcc_vdev_id) 3444 *mcc_vdev_id = WLAN_INVALID_VDEV_ID; 3445 3446 pm_ctx = policy_mgr_get_context(psoc); 3447 if (!pm_ctx) { 3448 policy_mgr_err("Invalid Context"); 3449 return false; 3450 } 3451 3452 /* Get the channel freq for a given vdev_id */ 3453 status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq); 3454 if (QDF_IS_STATUS_ERROR(status)) { 3455 policy_mgr_err("Failed to get channel for vdev:%d", vdev_id); 3456 return false; 3457 } 3458 3459 /* Compare given vdev_id freq against other vdev_id's */ 3460 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3461 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 3462 if (pm_conc_connection_list[i].vdev_id == vdev_id) 3463 continue; 3464 3465 if (!pm_conc_connection_list[i].in_use) 3466 continue; 3467 3468 if (pm_conc_connection_list[i].freq != ch_freq && 3469 policy_mgr_are_2_freq_on_same_mac(psoc, 3470 pm_conc_connection_list[i].freq, 3471 ch_freq)) { 3472 if (mcc_vdev_id) 3473 *mcc_vdev_id = pm_conc_connection_list[i].vdev_id; 3474 3475 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3476 return true; 3477 } 3478 } 3479 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3480 3481 return false; 3482 } 3483 3484 bool policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc *psoc) 3485 { 3486 uint8_t connection_count, i; 3487 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3488 3489 connection_count = 3490 policy_mgr_get_mode_specific_conn_info(psoc, NULL, vdev_id_list, 3491 PM_STA_MODE); 3492 if (!connection_count) 3493 return false; 3494 3495 for (i = 0; i < connection_count; i++) 3496 if (policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id_list[i], 3497 NULL)) 3498 return true; 3499 3500 return false; 3501 } 3502 3503 bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc) 3504 { 3505 uint32_t num_connections = 0; 3506 bool is_scc = false; 3507 struct policy_mgr_psoc_priv_obj *pm_ctx; 3508 3509 pm_ctx = policy_mgr_get_context(psoc); 3510 if (!pm_ctx) { 3511 policy_mgr_err("Invalid Context"); 3512 return is_scc; 3513 } 3514 3515 num_connections = policy_mgr_get_connection_count(psoc); 3516 3517 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3518 switch (num_connections) { 3519 case 1: 3520 break; 3521 case 2: 3522 if (pm_conc_connection_list[0].freq == 3523 pm_conc_connection_list[1].freq && 3524 policy_mgr_are_2_freq_on_same_mac(psoc, 3525 pm_conc_connection_list[0].freq, 3526 pm_conc_connection_list[1].freq)) 3527 is_scc = true; 3528 break; 3529 case 3: 3530 /* 3531 * In DBS/SBS mode 2 freq are different and on different mac. 3532 * Thus if any of 2 freq are same that mean one of the MAC is 3533 * in SCC. 3534 * For non DBS/SBS, if all 3 freq are same then its SCC 3535 */ 3536 if ((policy_mgr_is_current_hwmode_dbs(psoc) || 3537 policy_mgr_is_current_hwmode_sbs(psoc)) && 3538 (pm_conc_connection_list[0].freq == 3539 pm_conc_connection_list[1].freq || 3540 pm_conc_connection_list[0].freq == 3541 pm_conc_connection_list[2].freq || 3542 pm_conc_connection_list[1].freq == 3543 pm_conc_connection_list[2].freq)) 3544 is_scc = true; 3545 else if ((pm_conc_connection_list[0].freq == 3546 pm_conc_connection_list[1].freq) && 3547 (pm_conc_connection_list[0].freq == 3548 pm_conc_connection_list[2].freq)) 3549 is_scc = true; 3550 3551 break; 3552 default: 3553 policy_mgr_debug("unexpected num_connections value %d", 3554 num_connections); 3555 break; 3556 } 3557 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3558 3559 return is_scc; 3560 } 3561 3562 bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) 3563 { 3564 uint32_t num_connections = 0; 3565 bool is_mcc = false; 3566 struct policy_mgr_psoc_priv_obj *pm_ctx; 3567 3568 pm_ctx = policy_mgr_get_context(psoc); 3569 if (!pm_ctx) { 3570 policy_mgr_err("Invalid Context"); 3571 return is_mcc; 3572 } 3573 3574 num_connections = policy_mgr_get_connection_count(psoc); 3575 3576 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3577 switch (num_connections) { 3578 case 1: 3579 break; 3580 case 2: 3581 if (pm_conc_connection_list[0].freq != 3582 pm_conc_connection_list[1].freq && 3583 policy_mgr_are_2_freq_on_same_mac(psoc, 3584 pm_conc_connection_list[0].freq, 3585 pm_conc_connection_list[1].freq)) 3586 is_mcc = true; 3587 break; 3588 case 3: 3589 /* 3590 * Check if any 2 different freq is on same MAC. 3591 * Return true if any of the different freq is on same MAC. 3592 */ 3593 if ((pm_conc_connection_list[0].freq != 3594 pm_conc_connection_list[1].freq && 3595 policy_mgr_are_2_freq_on_same_mac(psoc, 3596 pm_conc_connection_list[0].freq, 3597 pm_conc_connection_list[1].freq)) || 3598 (pm_conc_connection_list[0].freq != 3599 pm_conc_connection_list[2].freq && 3600 policy_mgr_are_2_freq_on_same_mac(psoc, 3601 pm_conc_connection_list[0].freq, 3602 pm_conc_connection_list[2].freq)) || 3603 (pm_conc_connection_list[1].freq != 3604 pm_conc_connection_list[2].freq && 3605 policy_mgr_are_2_freq_on_same_mac(psoc, 3606 pm_conc_connection_list[1].freq, 3607 pm_conc_connection_list[2].freq))) 3608 is_mcc = true; 3609 break; 3610 default: 3611 policy_mgr_debug("unexpected num_connections value %d", 3612 num_connections); 3613 break; 3614 } 3615 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3616 3617 return is_mcc; 3618 } 3619 3620 bool policy_mgr_is_sap_p2pgo_on_dfs(struct wlan_objmgr_psoc *psoc) 3621 { 3622 int index, count; 3623 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3624 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; 3625 3626 if (psoc) 3627 pm_ctx = policy_mgr_get_context(psoc); 3628 3629 if (!pm_ctx) { 3630 policy_mgr_err("Invalid Context"); 3631 return false; 3632 } 3633 3634 index = 0; 3635 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3636 count = policy_mgr_mode_specific_connection_count(psoc, 3637 PM_SAP_MODE, 3638 list); 3639 while (index < count) { 3640 if (pm_conc_connection_list[list[index]].ch_flagext & 3641 (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) { 3642 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3643 return true; 3644 } 3645 index++; 3646 } 3647 count = policy_mgr_mode_specific_connection_count(psoc, 3648 PM_P2P_GO_MODE, 3649 list); 3650 index = 0; 3651 while (index < count) { 3652 if (pm_conc_connection_list[list[index]].ch_flagext & 3653 (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) { 3654 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3655 return true; 3656 } 3657 index++; 3658 } 3659 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3660 return false; 3661 } 3662 3663 /** 3664 * policy_mgr_set_concurrency_mode() - To set concurrency mode 3665 * @psoc: PSOC object data 3666 * @mode: device mode 3667 * 3668 * This routine is called to set the concurrency mode 3669 * 3670 * Return: NONE 3671 */ 3672 void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, 3673 enum QDF_OPMODE mode) 3674 { 3675 struct policy_mgr_psoc_priv_obj *pm_ctx; 3676 3677 pm_ctx = policy_mgr_get_context(psoc); 3678 if (!pm_ctx) { 3679 policy_mgr_err("Invalid context"); 3680 return; 3681 } 3682 3683 switch (mode) { 3684 case QDF_STA_MODE: 3685 case QDF_P2P_CLIENT_MODE: 3686 case QDF_P2P_GO_MODE: 3687 case QDF_SAP_MODE: 3688 case QDF_MONITOR_MODE: 3689 pm_ctx->concurrency_mode |= (1 << mode); 3690 pm_ctx->no_of_open_sessions[mode]++; 3691 break; 3692 default: 3693 break; 3694 } 3695 3696 policy_mgr_debug("concurrency_mode = 0x%x Number of open sessions for mode %d = %d", 3697 pm_ctx->concurrency_mode, mode, 3698 pm_ctx->no_of_open_sessions[mode]); 3699 } 3700 3701 /** 3702 * policy_mgr_clear_concurrency_mode() - To clear concurrency mode 3703 * @psoc: PSOC object data 3704 * @mode: device mode 3705 * 3706 * This routine is called to clear the concurrency mode 3707 * 3708 * Return: NONE 3709 */ 3710 void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, 3711 enum QDF_OPMODE mode) 3712 { 3713 struct policy_mgr_psoc_priv_obj *pm_ctx; 3714 3715 pm_ctx = policy_mgr_get_context(psoc); 3716 if (!pm_ctx) { 3717 policy_mgr_err("Invalid context"); 3718 return; 3719 } 3720 3721 switch (mode) { 3722 case QDF_STA_MODE: 3723 case QDF_P2P_CLIENT_MODE: 3724 case QDF_P2P_GO_MODE: 3725 case QDF_SAP_MODE: 3726 case QDF_MONITOR_MODE: 3727 pm_ctx->no_of_open_sessions[mode]--; 3728 if (!(pm_ctx->no_of_open_sessions[mode])) 3729 pm_ctx->concurrency_mode &= (~(1 << mode)); 3730 break; 3731 default: 3732 break; 3733 } 3734 3735 policy_mgr_debug("concurrency_mode = 0x%x Number of open sessions for mode %d = %d", 3736 pm_ctx->concurrency_mode, mode, 3737 pm_ctx->no_of_open_sessions[mode]); 3738 } 3739 3740 /** 3741 * policy_mgr_validate_conn_info() - validate conn info list 3742 * @psoc: PSOC object data 3743 * 3744 * This function will check connection list to see duplicated 3745 * vdev entry existing or not. 3746 * 3747 * Return: true if conn list is in abnormal state. 3748 */ 3749 static bool 3750 policy_mgr_validate_conn_info(struct wlan_objmgr_psoc *psoc) 3751 { 3752 uint32_t i, j, conn_num = 0; 3753 bool panic = false; 3754 struct policy_mgr_psoc_priv_obj *pm_ctx; 3755 3756 pm_ctx = policy_mgr_get_context(psoc); 3757 if (!pm_ctx) { 3758 policy_mgr_err("Invalid Context"); 3759 return true; 3760 } 3761 3762 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3763 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 3764 if (pm_conc_connection_list[i].in_use) { 3765 for (j = i + 1; j < MAX_NUMBER_OF_CONC_CONNECTIONS; 3766 j++) { 3767 if (pm_conc_connection_list[j].in_use && 3768 pm_conc_connection_list[i].vdev_id == 3769 pm_conc_connection_list[j].vdev_id) { 3770 policy_mgr_debug( 3771 "dup entry %d", 3772 pm_conc_connection_list[i].vdev_id); 3773 panic = true; 3774 } 3775 } 3776 conn_num++; 3777 } 3778 } 3779 if (panic) 3780 policy_mgr_err("dup entry"); 3781 3782 for (i = 0, j = 0; i < QDF_MAX_NO_OF_MODE; i++) 3783 j += pm_ctx->no_of_active_sessions[i]; 3784 3785 if (j != conn_num) { 3786 policy_mgr_err("active session/conn count mismatch %d %d", 3787 j, conn_num); 3788 panic = true; 3789 } 3790 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3791 3792 if (panic) 3793 policy_mgr_debug_alert(); 3794 3795 return panic; 3796 } 3797 3798 #ifdef WLAN_FEATURE_11BE_MLO 3799 bool policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3800 { 3801 struct wlan_objmgr_vdev *vdev; 3802 bool is_mlo = false; 3803 3804 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3805 WLAN_POLICY_MGR_ID); 3806 if (!vdev) 3807 return is_mlo; 3808 3809 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) 3810 is_mlo = true; 3811 3812 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3813 3814 return is_mlo; 3815 } 3816 3817 /* 3818 * policy_mgr_get_ml_sta_info() - Get number of ML STA vdev ids and freq list 3819 * @pm_ctx: pm_ctx ctx 3820 * @num_ml_sta: Return number of ML STA present 3821 * @num_disabled_ml_sta: Return number of disabled ML STA links 3822 * @ml_vdev_lst: Return ML STA vdev id list 3823 * @ml_freq_lst: Return ML STA freq list 3824 * @num_non_ml: Return number of non-ML STA present 3825 * @non_ml_vdev_lst: Return non-ML STA vdev id list 3826 * @non_ml_freq_lst: Return non-ML STA freq list 3827 * 3828 * Return: void 3829 */ 3830 static void 3831 policy_mgr_get_ml_sta_info(struct policy_mgr_psoc_priv_obj *pm_ctx, 3832 uint8_t *num_ml_sta, 3833 uint8_t *num_disabled_ml_sta, 3834 uint8_t *ml_vdev_lst, 3835 qdf_freq_t *ml_freq_lst, 3836 uint8_t *num_non_ml, 3837 uint8_t *non_ml_vdev_lst, 3838 qdf_freq_t *non_ml_freq_lst) 3839 { 3840 struct wlan_objmgr_vdev *vdev; 3841 uint8_t vdev_id, conn_index; 3842 qdf_freq_t freq; 3843 3844 *num_ml_sta = 0; 3845 *num_disabled_ml_sta = 0; 3846 if (num_non_ml) 3847 *num_non_ml = 0; 3848 3849 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3850 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 3851 conn_index++) { 3852 if (!pm_conc_connection_list[conn_index].in_use) 3853 continue; 3854 if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE) 3855 continue; 3856 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 3857 freq = pm_conc_connection_list[conn_index].freq; 3858 3859 /* add ml sta vdev and freq list */ 3860 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc, 3861 vdev_id, 3862 WLAN_POLICY_MGR_ID); 3863 if (!vdev) { 3864 policy_mgr_err("invalid vdev for id %d", vdev_id); 3865 continue; 3866 } 3867 3868 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) { 3869 ml_vdev_lst[*num_ml_sta] = vdev_id; 3870 ml_freq_lst[(*num_ml_sta)++] = freq; 3871 } else if (num_non_ml) { 3872 if (non_ml_vdev_lst) 3873 non_ml_vdev_lst[*num_non_ml] = vdev_id; 3874 if (non_ml_freq_lst) 3875 non_ml_freq_lst[*num_non_ml] = freq; 3876 (*num_non_ml)++; 3877 } 3878 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3879 } 3880 /* Get disabled link info as well and keep it at last */ 3881 for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK; 3882 conn_index++) { 3883 if (!pm_disabled_ml_links[conn_index].in_use) 3884 continue; 3885 if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE) 3886 continue; 3887 ml_vdev_lst[*num_ml_sta] = 3888 pm_disabled_ml_links[conn_index].vdev_id; 3889 ml_freq_lst[(*num_ml_sta)++] = 3890 pm_disabled_ml_links[conn_index].freq; 3891 (*num_disabled_ml_sta)++; 3892 } 3893 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3894 } 3895 3896 void 3897 policy_mgr_get_ml_sta_info_psoc(struct wlan_objmgr_psoc *psoc, 3898 uint8_t *num_ml_sta, 3899 uint8_t *num_disabled_ml_sta, 3900 uint8_t *ml_vdev_lst, 3901 qdf_freq_t *ml_freq_lst, 3902 uint8_t *num_non_ml, 3903 uint8_t *non_ml_vdev_lst, 3904 qdf_freq_t *non_ml_freq_lst) 3905 { 3906 struct policy_mgr_psoc_priv_obj *pm_ctx; 3907 3908 pm_ctx = policy_mgr_get_context(psoc); 3909 if (!pm_ctx) { 3910 policy_mgr_err("Invalid pm_ctx"); 3911 return; 3912 } 3913 3914 return policy_mgr_get_ml_sta_info(pm_ctx, 3915 num_ml_sta, 3916 num_disabled_ml_sta, 3917 ml_vdev_lst, 3918 ml_freq_lst, 3919 num_non_ml, 3920 non_ml_vdev_lst, 3921 non_ml_freq_lst); 3922 } 3923 3924 uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc) 3925 { 3926 uint32_t i, count = 0; 3927 struct policy_mgr_psoc_priv_obj *pm_ctx; 3928 3929 pm_ctx = policy_mgr_get_context(psoc); 3930 if (!pm_ctx) { 3931 policy_mgr_err("Invalid pm_ctx"); 3932 return count; 3933 } 3934 3935 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3936 for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) { 3937 if (pm_disabled_ml_links[i].in_use) 3938 count++; 3939 } 3940 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3941 3942 return count; 3943 } 3944 3945 static QDF_STATUS 3946 policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx, 3947 uint8_t vdev_id) 3948 { 3949 int i; 3950 3951 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3952 for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) { 3953 if (pm_disabled_ml_links[i].in_use && 3954 pm_disabled_ml_links[i].vdev_id == vdev_id) { 3955 pm_disabled_ml_links[i].in_use = false; 3956 policy_mgr_debug("Disabled link removed for vdev %d", 3957 vdev_id); 3958 break; 3959 } 3960 } 3961 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3962 /* Return failure if not found */ 3963 if (i >= MAX_NUMBER_OF_DISABLE_LINK) 3964 return QDF_STATUS_E_EXISTS; 3965 3966 return QDF_STATUS_SUCCESS; 3967 } 3968 3969 void policy_mgr_move_vdev_from_disabled_to_connection_tbl( 3970 struct wlan_objmgr_psoc *psoc, 3971 uint8_t vdev_id) 3972 { 3973 struct policy_mgr_psoc_priv_obj *pm_ctx; 3974 QDF_STATUS status; 3975 enum QDF_OPMODE mode; 3976 3977 pm_ctx = policy_mgr_get_context(psoc); 3978 if (!pm_ctx) { 3979 policy_mgr_err("Invalid pm_ctx"); 3980 return; 3981 } 3982 mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 3983 if (mode != QDF_STA_MODE) { 3984 policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode); 3985 return; 3986 } 3987 3988 if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) { 3989 policy_mgr_err("vdev %d is not ML", vdev_id); 3990 return; 3991 } 3992 3993 status = policy_mgr_delete_from_disabled_links(pm_ctx, vdev_id); 3994 if (QDF_IS_STATUS_ERROR(status)) { 3995 policy_mgr_debug("Disabled link not found for vdev %d", 3996 vdev_id); 3997 return; 3998 } 3999 4000 /* 4001 * Add entry to pm_conc_connection_list if remove from disabled links 4002 * was success 4003 */ 4004 policy_mgr_incr_active_session(psoc, mode, vdev_id); 4005 } 4006 4007 static QDF_STATUS 4008 policy_mgr_add_to_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx, 4009 qdf_freq_t freq, enum QDF_OPMODE mode, 4010 uint8_t vdev_id) 4011 { 4012 int i; 4013 enum policy_mgr_con_mode pm_mode; 4014 4015 pm_mode = policy_mgr_qdf_opmode_to_pm_con_mode(pm_ctx->psoc, mode, 4016 vdev_id); 4017 4018 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4019 for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) { 4020 if (pm_disabled_ml_links[i].in_use && 4021 pm_disabled_ml_links[i].vdev_id == vdev_id) 4022 break; 4023 } 4024 4025 if (i < MAX_NUMBER_OF_DISABLE_LINK) { 4026 pm_disabled_ml_links[i].freq = freq; 4027 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4028 policy_mgr_debug("Disabled link already present vdev %d, pm_mode %d, update freq %d", 4029 vdev_id, pm_mode, freq); 4030 4031 return QDF_STATUS_E_EXISTS; 4032 } 4033 4034 for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) { 4035 if (!pm_disabled_ml_links[i].in_use) { 4036 /* add in empty place */ 4037 pm_disabled_ml_links[i].vdev_id = vdev_id; 4038 pm_disabled_ml_links[i].mode = pm_mode; 4039 pm_disabled_ml_links[i].in_use = true; 4040 pm_disabled_ml_links[i].freq = freq; 4041 policy_mgr_debug("Disabled link added vdev id: %d freq: %d pm_mode %d", 4042 vdev_id, freq, pm_mode); 4043 break; 4044 } 4045 } 4046 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4047 if (i >= MAX_NUMBER_OF_DISABLE_LINK) { 4048 policy_mgr_err("No empty entry found to disable link for vdev %d", 4049 vdev_id); 4050 return QDF_STATUS_E_RESOURCES; 4051 } 4052 4053 return QDF_STATUS_SUCCESS; 4054 } 4055 4056 void policy_mgr_move_vdev_from_connection_to_disabled_tbl( 4057 struct wlan_objmgr_psoc *psoc, 4058 uint8_t vdev_id) 4059 { 4060 struct policy_mgr_psoc_priv_obj *pm_ctx; 4061 qdf_freq_t freq; 4062 enum QDF_OPMODE mode; 4063 QDF_STATUS status; 4064 4065 pm_ctx = policy_mgr_get_context(psoc); 4066 if (!pm_ctx) { 4067 policy_mgr_err("Invalid pm_ctx"); 4068 return; 4069 } 4070 4071 mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 4072 if (mode != QDF_STA_MODE) { 4073 policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode); 4074 return; 4075 } 4076 4077 if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) { 4078 policy_mgr_err("vdev %d is not ML", vdev_id); 4079 return; 4080 } 4081 freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id); 4082 status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc, PM_STA_MODE, 4083 vdev_id); 4084 /* 4085 * Remove entry if present in pm_conc_connection_list, if not just add 4086 * it in disabled table. 4087 */ 4088 if (QDF_IS_STATUS_SUCCESS(status)) 4089 policy_mgr_decr_session_set_pcl(psoc, mode, vdev_id); 4090 else 4091 policy_mgr_debug("Connection tbl dont have vdev %d in STA mode, Add it in disabled tbl", 4092 vdev_id); 4093 4094 policy_mgr_add_to_disabled_links(pm_ctx, freq, mode, vdev_id); 4095 policy_mgr_dump_current_concurrency(psoc); 4096 } 4097 4098 static bool 4099 policy_mgr_vdev_disabled_by_link_force(struct wlan_objmgr_psoc *psoc, 4100 struct wlan_objmgr_vdev *vdev, 4101 bool peer_assoc) 4102 { 4103 uint16_t dynamic_inactive = 0, forced_inactive = 0; 4104 uint16_t link_id; 4105 4106 if (ml_is_nlink_service_supported(psoc) && 4107 !peer_assoc) { 4108 ml_nlink_get_dynamic_inactive_links(psoc, vdev, 4109 &dynamic_inactive, 4110 &forced_inactive); 4111 link_id = wlan_vdev_get_link_id(vdev); 4112 if ((forced_inactive | dynamic_inactive) & 4113 (1 << link_id)) { 4114 policy_mgr_debug("vdev %d linkid %d is forced inactived 0x%0x dyn 0x%x", 4115 wlan_vdev_get_id(vdev), 4116 link_id, forced_inactive, 4117 dynamic_inactive); 4118 return true; 4119 } 4120 } 4121 4122 return false; 4123 } 4124 4125 bool 4126 policy_mgr_ml_link_vdev_need_to_be_disabled(struct wlan_objmgr_psoc *psoc, 4127 struct wlan_objmgr_vdev *vdev, 4128 bool peer_assoc) 4129 { 4130 union conc_ext_flag conc_ext_flags; 4131 4132 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 4133 return false; 4134 4135 /* Check only for link vdev */ 4136 if (!wlan_vdev_mlme_is_mlo_vdev(vdev) || 4137 !wlan_vdev_mlme_is_mlo_link_vdev(vdev)) 4138 return false; 4139 4140 /* Check vdev is disabled by link force command */ 4141 if (policy_mgr_vdev_disabled_by_link_force(psoc, vdev, 4142 peer_assoc)) 4143 return true; 4144 4145 conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false); 4146 /* 4147 * For non-assoc link vdev set link as disabled if concurrency is 4148 * not allowed 4149 */ 4150 return !policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE, 4151 wlan_get_operation_chan_freq(vdev), 4152 HW_MODE_20_MHZ, 4153 conc_ext_flags.value, NULL); 4154 } 4155 4156 static void 4157 policy_mgr_enable_disable_link_from_vdev_bitmask(struct wlan_objmgr_psoc *psoc, 4158 unsigned long enable_vdev_mask, 4159 unsigned long disable_vdev_mask, 4160 uint8_t start_vdev_id) 4161 { 4162 uint8_t i; 4163 4164 /* Enable required link if enable_vdev_mask preset */ 4165 for (i = 0; enable_vdev_mask && i < WLAN_MAX_VDEVS; i++) { 4166 if (qdf_test_and_clear_bit(i, &enable_vdev_mask)) 4167 policy_mgr_move_vdev_from_disabled_to_connection_tbl( 4168 psoc, 4169 i + start_vdev_id); 4170 } 4171 4172 /* Disable required link if disable_mask preset */ 4173 for (i = 0; disable_vdev_mask && i < WLAN_MAX_VDEVS; i++) { 4174 if (qdf_test_and_clear_bit(i, &disable_vdev_mask)) 4175 policy_mgr_move_vdev_from_connection_to_disabled_tbl( 4176 psoc, 4177 i + start_vdev_id); 4178 } 4179 } 4180 4181 static void 4182 policy_mgr_set_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx, 4183 bool value) 4184 { 4185 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4186 pm_ctx->set_link_in_progress = value; 4187 /* if set link has started reset the event, else complete the event */ 4188 if (pm_ctx->set_link_in_progress) 4189 qdf_event_reset(&pm_ctx->set_link_update_done_evt); 4190 else 4191 qdf_event_set(&pm_ctx->set_link_update_done_evt); 4192 policy_mgr_debug("set_link_in_progress %d", 4193 pm_ctx->set_link_in_progress); 4194 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4195 } 4196 4197 static bool 4198 policy_mgr_get_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx) 4199 { 4200 bool value; 4201 4202 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4203 value = pm_ctx->set_link_in_progress; 4204 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4205 if (value) 4206 policy_mgr_debug("set_link_in_progress %d", value); 4207 4208 return value; 4209 } 4210 4211 bool policy_mgr_is_set_link_in_progress(struct wlan_objmgr_psoc *psoc) 4212 { 4213 struct policy_mgr_psoc_priv_obj *pm_ctx; 4214 4215 pm_ctx = policy_mgr_get_context(psoc); 4216 if (!pm_ctx) { 4217 policy_mgr_err("Invalid Context"); 4218 return false; 4219 } 4220 4221 return policy_mgr_get_link_in_progress(pm_ctx); 4222 } 4223 4224 /* 4225 * policy_mgr_trigger_roam_on_link_removal() - Trigger roam on link removal 4226 * @vdev: vdev object 4227 * 4228 * In multilink ML STA, if one link is removed by AP, and no other active 4229 * link, trigger roam by roaming invoke command. 4230 * 4231 * Return: void 4232 */ 4233 static void 4234 policy_mgr_trigger_roam_on_link_removal(struct wlan_objmgr_vdev *vdev) 4235 { 4236 struct wlan_objmgr_psoc *psoc; 4237 struct wlan_objmgr_pdev *pdev; 4238 struct wlan_objmgr_vdev *ml_vdev; 4239 struct policy_mgr_psoc_priv_obj *pm_ctx; 4240 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0; 4241 uint8_t num_active_ml_sta; 4242 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 4243 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 4244 uint8_t vdev_id = wlan_vdev_get_id(vdev); 4245 uint8_t assoc_vdev_id = WLAN_INVALID_VDEV_ID; 4246 uint8_t removed_vdev_id = WLAN_INVALID_VDEV_ID; 4247 struct qdf_mac_addr bssid; 4248 QDF_STATUS status; 4249 bool ml_sta_is_not_connected = false; 4250 uint32_t i; 4251 4252 psoc = wlan_vdev_get_psoc(vdev); 4253 if (!psoc) { 4254 policy_mgr_err("Failed to get psoc"); 4255 return; 4256 } 4257 pdev = wlan_vdev_get_pdev(vdev); 4258 if (!pdev) { 4259 policy_mgr_err("Failed to get pdev"); 4260 return; 4261 } 4262 pm_ctx = policy_mgr_get_context(psoc); 4263 if (!pm_ctx) { 4264 policy_mgr_err("Invalid Context"); 4265 return; 4266 } 4267 4268 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 4269 ml_sta_vdev_lst, ml_freq_lst, 4270 NULL, NULL, NULL); 4271 if (!num_ml_sta) { 4272 policy_mgr_debug("unexpected event, no ml sta"); 4273 return; 4274 } 4275 if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 4276 num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 4277 num_ml_sta <= num_disabled_ml_sta) { 4278 policy_mgr_debug("unexpected ml sta num %d %d", 4279 num_ml_sta, num_disabled_ml_sta); 4280 return; 4281 } 4282 num_active_ml_sta = num_ml_sta; 4283 if (num_ml_sta >= num_disabled_ml_sta) 4284 num_active_ml_sta = num_ml_sta - num_disabled_ml_sta; 4285 4286 for (i = 0; i < num_active_ml_sta; i++) { 4287 if (!wlan_get_vdev_link_removed_flag_by_vdev_id( 4288 psoc, ml_sta_vdev_lst[i])) 4289 break; 4290 } 4291 4292 /* After link removal, one link is still active, no need invoke 4293 * roaming. 4294 * For Single link MLO, FW will do roaming automatically. 4295 */ 4296 if (i < num_active_ml_sta || num_ml_sta < 2) 4297 return; 4298 4299 /* For multi-link MLO STA, if one link is removed and no other active 4300 * link, then trigger roaming. the other link may have concurrency 4301 * limitation and can't be active. 4302 */ 4303 for (i = 0; i < num_ml_sta; i++) { 4304 if (removed_vdev_id == WLAN_INVALID_VDEV_ID && 4305 wlan_get_vdev_link_removed_flag_by_vdev_id( 4306 psoc, ml_sta_vdev_lst[i])) { 4307 policy_mgr_debug("removal link vdev %d is removed ", 4308 vdev_id); 4309 removed_vdev_id = ml_sta_vdev_lst[i]; 4310 } 4311 ml_vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 4312 pm_ctx->psoc, 4313 ml_sta_vdev_lst[i], 4314 WLAN_POLICY_MGR_ID); 4315 if (!ml_vdev) { 4316 policy_mgr_err("invalid vdev for id %d", 4317 ml_sta_vdev_lst[i]); 4318 continue; 4319 } 4320 if (!wlan_cm_is_vdev_connected(ml_vdev)) { 4321 policy_mgr_debug("ml sta vdev %d is not connected state", 4322 ml_sta_vdev_lst[i]); 4323 ml_sta_is_not_connected = true; 4324 } 4325 4326 wlan_objmgr_vdev_release_ref(ml_vdev, WLAN_POLICY_MGR_ID); 4327 4328 if (assoc_vdev_id == WLAN_INVALID_VDEV_ID && 4329 !wlan_vdev_mlme_get_is_mlo_link(psoc, 4330 ml_sta_vdev_lst[i])) 4331 assoc_vdev_id = ml_sta_vdev_lst[i]; 4332 } 4333 if (removed_vdev_id == WLAN_INVALID_VDEV_ID) { 4334 policy_mgr_debug("no link removed, unexpected"); 4335 return; 4336 } 4337 if (assoc_vdev_id == WLAN_INVALID_VDEV_ID) { 4338 policy_mgr_debug("no find assoc vdev, unexpected"); 4339 return; 4340 } 4341 if (ml_sta_is_not_connected) { 4342 policy_mgr_debug("ml sta is non-connected state, don't trigger roam"); 4343 return; 4344 } 4345 /* trigger roaming */ 4346 policy_mgr_debug("link removal detected, try roaming on vdev id: %d", 4347 assoc_vdev_id); 4348 qdf_zero_macaddr(&bssid); 4349 status = wlan_cm_roam_invoke(pdev, assoc_vdev_id, &bssid, 0, 4350 CM_ROAMING_LINK_REMOVAL); 4351 if (QDF_IS_STATUS_ERROR(status)) 4352 policy_mgr_err("roam invoke failed"); 4353 } 4354 4355 static void 4356 policy_mgr_update_dynamic_inactive_bitmap( 4357 struct wlan_objmgr_psoc *psoc, 4358 struct wlan_objmgr_vdev *vdev, 4359 struct mlo_link_set_active_req *req, 4360 struct mlo_link_set_active_resp *resp) 4361 { 4362 uint32_t candidate_inactive_links; 4363 uint32_t dyn_inactive_links = 0; 4364 uint8_t dyn_num = 0, num = 0, i; 4365 uint8_t link_ids[MAX_MLO_LINK_ID * 2]; 4366 4367 if (req->param.force_mode != MLO_LINK_FORCE_MODE_INACTIVE_NUM || 4368 !req->param.control_flags.dynamic_force_link_num) 4369 return; 4370 4371 /* force inactive num "clear" case, return 0 - no 4372 * dynamic inactive links. 4373 */ 4374 if (!req->param.force_cmd.link_num) { 4375 dyn_inactive_links = 0; 4376 dyn_num = 0; 4377 goto update; 4378 } 4379 /* 1. If force inactive overlap with force num bitmap, 4380 * select the inactive link from overlapped links firstly. 4381 * 2. If selected inactive link num < 4382 * req->param.force_cmd.link_num, then select the inactive 4383 * links from current inactive links reported from FW. 4384 */ 4385 candidate_inactive_links = 4386 req->param.force_cmd.ieee_link_id_bitmap & 4387 resp->inactive_linkid_bitmap; 4388 4389 num = ml_nlink_convert_link_bitmap_to_ids(candidate_inactive_links, 4390 QDF_ARRAY_SIZE(link_ids), 4391 link_ids); 4392 if (num < req->param.force_cmd.link_num && 4393 num < QDF_ARRAY_SIZE(link_ids)) { 4394 candidate_inactive_links = 4395 req->param.force_cmd.ieee_link_id_bitmap & 4396 resp->curr_inactive_linkid_bitmap & 4397 ~candidate_inactive_links; 4398 num += ml_nlink_convert_link_bitmap_to_ids( 4399 candidate_inactive_links, 4400 QDF_ARRAY_SIZE(link_ids) - num, 4401 &link_ids[num]); 4402 } 4403 for (i = 0; i < num; i++) { 4404 if (dyn_num >= req->param.force_cmd.link_num) 4405 break; 4406 dyn_inactive_links |= 1 << link_ids[i]; 4407 dyn_num++; 4408 } 4409 4410 update: 4411 policy_mgr_debug("inactive link num %d bitmap 0x%x force inactive 0x%x dyn links 0x%x num %d", 4412 req->param.force_cmd.link_num, 4413 req->param.force_cmd.ieee_link_id_bitmap, 4414 resp->inactive_linkid_bitmap, 4415 dyn_inactive_links, dyn_num); 4416 if (dyn_num < req->param.force_cmd.link_num) 4417 policy_mgr_debug("unexpected selected dynamic inactive link num %d", 4418 dyn_num); 4419 ml_nlink_set_dynamic_inactive_links(psoc, vdev, dyn_inactive_links); 4420 } 4421 4422 static void 4423 policy_mgr_handle_vdev_active_inactive_resp( 4424 struct wlan_objmgr_psoc *psoc, 4425 struct wlan_objmgr_vdev *vdev, 4426 struct mlo_link_set_active_req *req, 4427 struct mlo_link_set_active_resp *resp) 4428 { 4429 uint8_t i; 4430 uint8_t vdev_id_num = 0; 4431 uint8_t vdev_ids[WLAN_MLO_MAX_VDEVS] = {0}; 4432 uint32_t assoc_bitmap = 0; 4433 uint16_t dynamic_inactive_bitmap = 0; 4434 uint16_t forced_inactive_bitmap = 0; 4435 4436 /* convert link id to vdev id and update vdev status based 4437 * on both inactive and active bitmap. 4438 * In link bitmap based WMI event (use_ieee_link_id = true), 4439 * target will always indicate current force inactive and 4440 * active bitmaps to host. For links in inactive_linkid_bitmap, 4441 * they will be moved to policy mgr disable connection table. 4442 * for other links, they will be in active tables. 4443 */ 4444 ml_nlink_get_dynamic_inactive_links(psoc, vdev, 4445 &dynamic_inactive_bitmap, 4446 &forced_inactive_bitmap); 4447 resp->inactive_linkid_bitmap |= dynamic_inactive_bitmap; 4448 ml_nlink_convert_linkid_bitmap_to_vdev_bitmap( 4449 psoc, vdev, resp->inactive_linkid_bitmap, 4450 &assoc_bitmap, 4451 &resp->inactive_sz, resp->inactive, 4452 &vdev_id_num, vdev_ids); 4453 4454 ml_nlink_convert_linkid_bitmap_to_vdev_bitmap( 4455 psoc, vdev, 4456 (~resp->inactive_linkid_bitmap) & assoc_bitmap, 4457 NULL, 4458 &resp->active_sz, resp->active, 4459 &vdev_id_num, vdev_ids); 4460 for (i = 0; i < resp->inactive_sz; i++) 4461 policy_mgr_enable_disable_link_from_vdev_bitmask( 4462 psoc, 0, resp->inactive[i], i * 32); 4463 for (i = 0; i < resp->active_sz; i++) 4464 policy_mgr_enable_disable_link_from_vdev_bitmask( 4465 psoc, resp->active[i], 0, i * 32); 4466 } 4467 4468 static void 4469 policy_mgr_handle_force_active_resp(struct wlan_objmgr_psoc *psoc, 4470 struct wlan_objmgr_vdev *vdev, 4471 struct mlo_link_set_active_req *req, 4472 struct mlo_link_set_active_resp *resp) 4473 { 4474 uint8_t i; 4475 uint32_t assoc_bitmap = 0; 4476 4477 if (resp->use_ieee_link_id) { 4478 /* save link force active bitmap */ 4479 ml_nlink_set_curr_force_active_state( 4480 psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap, 4481 req->param.control_flags.overwrite_force_active_bitmap ? 4482 LINK_OVERWRITE : LINK_ADD); 4483 4484 /* update vdev active inactive status */ 4485 policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req, 4486 resp); 4487 return; 4488 } 4489 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4490 psoc, vdev, req->param.num_vdev_bitmap, 4491 req->param.vdev_bitmap, &resp->active_linkid_bitmap, 4492 &assoc_bitmap); 4493 ml_nlink_set_curr_force_active_state( 4494 psoc, vdev, resp->active_linkid_bitmap, LINK_ADD); 4495 4496 for (i = 0; i < resp->active_sz; i++) 4497 policy_mgr_enable_disable_link_from_vdev_bitmask( 4498 psoc, resp->active[i], 0, i * 32); 4499 } 4500 4501 static void 4502 policy_mgr_handle_force_inactive_resp(struct wlan_objmgr_psoc *psoc, 4503 struct wlan_objmgr_vdev *vdev, 4504 struct mlo_link_set_active_req *req, 4505 struct mlo_link_set_active_resp *resp) 4506 { 4507 uint8_t i; 4508 uint32_t assoc_bitmap = 0; 4509 4510 if (resp->use_ieee_link_id) { 4511 /* save link force inactive bitmap */ 4512 ml_nlink_set_curr_force_inactive_state( 4513 psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap, 4514 req->param.control_flags.overwrite_force_inactive_bitmap ? 4515 LINK_OVERWRITE : LINK_ADD); 4516 4517 /* update vdev active inactive status */ 4518 policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req, 4519 resp); 4520 return; 4521 } 4522 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4523 psoc, vdev, req->param.num_vdev_bitmap, 4524 req->param.vdev_bitmap, &resp->inactive_linkid_bitmap, 4525 &assoc_bitmap); 4526 ml_nlink_set_curr_force_inactive_state( 4527 psoc, vdev, resp->inactive_linkid_bitmap, LINK_ADD); 4528 4529 for (i = 0; i < resp->inactive_sz; i++) 4530 policy_mgr_enable_disable_link_from_vdev_bitmask( 4531 psoc, 0, resp->inactive[i], i * 32); 4532 } 4533 4534 static void 4535 policy_mgr_handle_force_active_num_resp(struct wlan_objmgr_psoc *psoc, 4536 struct wlan_objmgr_vdev *vdev, 4537 struct mlo_link_set_active_req *req, 4538 struct mlo_link_set_active_resp *resp) 4539 { 4540 uint8_t i; 4541 uint32_t assoc_bitmap = 0; 4542 uint32_t link_bitmap = 0; 4543 4544 if (resp->use_ieee_link_id) { 4545 /* save force num and force num bitmap */ 4546 ml_nlink_set_curr_force_active_num_state( 4547 psoc, vdev, req->param.force_cmd.link_num, 4548 req->param.force_cmd.ieee_link_id_bitmap); 4549 4550 /* update vdev active inactive status */ 4551 policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req, 4552 resp); 4553 return; 4554 } 4555 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4556 psoc, vdev, req->param.num_vdev_bitmap, 4557 req->param.vdev_bitmap, 4558 &link_bitmap, 4559 &assoc_bitmap); 4560 ml_nlink_set_curr_force_active_num_state( 4561 psoc, vdev, req->param.link_num[0].num_of_link, 4562 link_bitmap); 4563 /* 4564 * When the host sends a set link command with force link num 4565 * and dynamic flag set, FW may not process it immediately. 4566 * In this case FW buffer the request and sends a response as 4567 * success to the host with VDEV bitmap as zero. 4568 * FW ensures that the number of active links will be equal to 4569 * the link num sent via WMI_MLO_LINK_SET_ACTIVE_CMDID command. 4570 * So the host should also fill the mlo policy_mgr table as per 4571 * request. 4572 */ 4573 if (req->param.control_flags.dynamic_force_link_num) { 4574 policy_mgr_debug("Enable ML vdev(s) as sent in req"); 4575 for (i = 0; i < req->param.num_vdev_bitmap; i++) 4576 policy_mgr_enable_disable_link_from_vdev_bitmask( 4577 psoc, 4578 req->param.vdev_bitmap[i], 0, i * 32); 4579 return; 4580 } 4581 4582 /* 4583 * MLO_LINK_FORCE_MODE_ACTIVE_NUM return which vdev is active 4584 * So XOR of the requested ML vdev and active vdev bit will give 4585 * the vdev bits to disable 4586 */ 4587 for (i = 0; i < resp->active_sz; i++) 4588 policy_mgr_enable_disable_link_from_vdev_bitmask( 4589 psoc, resp->active[i], 4590 resp->active[i] ^ req->param.vdev_bitmap[i], 4591 i * 32); 4592 } 4593 4594 static void 4595 policy_mgr_handle_force_inactive_num_resp( 4596 struct wlan_objmgr_psoc *psoc, 4597 struct wlan_objmgr_vdev *vdev, 4598 struct mlo_link_set_active_req *req, 4599 struct mlo_link_set_active_resp *resp) 4600 { 4601 uint8_t i; 4602 uint32_t assoc_bitmap = 0; 4603 uint32_t link_bitmap = 0; 4604 4605 if (resp->use_ieee_link_id) { 4606 /* save force num and force num bitmap */ 4607 ml_nlink_set_curr_force_inactive_num_state( 4608 psoc, vdev, req->param.force_cmd.link_num, 4609 req->param.force_cmd.ieee_link_id_bitmap); 4610 policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req, 4611 resp); 4612 4613 /* update vdev active inactive status */ 4614 policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req, 4615 resp); 4616 return; 4617 } 4618 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4619 psoc, vdev, req->param.num_vdev_bitmap, 4620 req->param.vdev_bitmap, 4621 &link_bitmap, 4622 &assoc_bitmap); 4623 ml_nlink_set_curr_force_inactive_num_state( 4624 psoc, vdev, req->param.link_num[0].num_of_link, 4625 link_bitmap); 4626 4627 /* 4628 * MLO_LINK_FORCE_MODE_INACTIVE_NUM return which vdev is 4629 * inactive So XOR of the requested ML vdev and inactive vdev 4630 * bit will give the vdev bits to be enable. 4631 */ 4632 for (i = 0; i < resp->inactive_sz; i++) 4633 policy_mgr_enable_disable_link_from_vdev_bitmask( 4634 psoc, 4635 resp->inactive[i] ^ req->param.vdev_bitmap[i], 4636 resp->inactive[i], i * 32); 4637 } 4638 4639 static void 4640 policy_mgr_handle_force_active_inactive_resp( 4641 struct wlan_objmgr_psoc *psoc, 4642 struct wlan_objmgr_vdev *vdev, 4643 struct mlo_link_set_active_req *req, 4644 struct mlo_link_set_active_resp *resp) 4645 { 4646 uint8_t i; 4647 uint32_t assoc_bitmap = 0; 4648 4649 if (resp->use_ieee_link_id) { 4650 /* save link active/inactive bitmap */ 4651 ml_nlink_set_curr_force_active_state( 4652 psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap, 4653 req->param.control_flags.overwrite_force_active_bitmap ? 4654 LINK_OVERWRITE : LINK_ADD); 4655 ml_nlink_set_curr_force_inactive_state( 4656 psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap2, 4657 req->param.control_flags.overwrite_force_inactive_bitmap ? 4658 LINK_OVERWRITE : LINK_ADD); 4659 4660 /* update vdev active inactive status */ 4661 policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req, 4662 resp); 4663 return; 4664 } 4665 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4666 psoc, vdev, req->param.num_inactive_vdev_bitmap, 4667 req->param.inactive_vdev_bitmap, 4668 &resp->inactive_linkid_bitmap, 4669 &assoc_bitmap); 4670 ml_nlink_set_curr_force_inactive_state( 4671 psoc, vdev, resp->inactive_linkid_bitmap, LINK_ADD); 4672 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4673 psoc, vdev, req->param.num_vdev_bitmap, 4674 req->param.vdev_bitmap, 4675 &resp->active_linkid_bitmap, 4676 &assoc_bitmap); 4677 ml_nlink_set_curr_force_active_state( 4678 psoc, vdev, resp->active_linkid_bitmap, LINK_ADD); 4679 4680 for (i = 0; i < resp->inactive_sz; i++) 4681 policy_mgr_enable_disable_link_from_vdev_bitmask( 4682 psoc, 0, resp->inactive[i], i * 32); 4683 for (i = 0; i < resp->active_sz; i++) 4684 policy_mgr_enable_disable_link_from_vdev_bitmask( 4685 psoc, resp->active[i], 0, i * 32); 4686 } 4687 4688 static void 4689 policy_mgr_handle_no_force_resp(struct wlan_objmgr_psoc *psoc, 4690 struct wlan_objmgr_vdev *vdev, 4691 struct mlo_link_set_active_req *req, 4692 struct mlo_link_set_active_resp *resp) 4693 { 4694 uint8_t i; 4695 uint32_t assoc_bitmap = 0; 4696 uint32_t link_bitmap = 0; 4697 4698 if (resp->use_ieee_link_id) { 4699 /* update link inactive/active bitmap */ 4700 if (req->param.force_cmd.ieee_link_id_bitmap) { 4701 ml_nlink_set_curr_force_inactive_state( 4702 psoc, vdev, 4703 req->param.force_cmd.ieee_link_id_bitmap, 4704 LINK_CLR); 4705 ml_nlink_set_curr_force_active_state( 4706 psoc, vdev, 4707 req->param.force_cmd.ieee_link_id_bitmap, 4708 LINK_CLR); 4709 } else { 4710 /* special handling for no force to clear all */ 4711 ml_nlink_clr_force_state(psoc, vdev); 4712 } 4713 4714 /* update vdev active inactive status */ 4715 policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req, 4716 resp); 4717 return; 4718 } 4719 4720 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 4721 psoc, vdev, req->param.num_vdev_bitmap, 4722 req->param.vdev_bitmap, 4723 &link_bitmap, &assoc_bitmap); 4724 4725 ml_nlink_set_curr_force_inactive_state( 4726 psoc, vdev, link_bitmap, LINK_CLR); 4727 ml_nlink_set_curr_force_active_state( 4728 psoc, vdev, link_bitmap, LINK_CLR); 4729 ml_nlink_set_curr_force_active_num_state( 4730 psoc, vdev, 0, 0); 4731 ml_nlink_set_curr_force_inactive_num_state( 4732 psoc, vdev, 0, 0); 4733 4734 /* Enable all the ML vdev id sent in request */ 4735 for (i = 0; i < req->param.num_vdev_bitmap; i++) 4736 policy_mgr_enable_disable_link_from_vdev_bitmask( 4737 psoc, req->param.vdev_bitmap[i], 0, i * 32); 4738 } 4739 4740 static void 4741 policy_mgr_handle_link_enable_disable_resp(struct wlan_objmgr_vdev *vdev, 4742 void *arg, 4743 struct mlo_link_set_active_resp *resp) 4744 { 4745 struct mlo_link_set_active_req *req = arg; 4746 struct wlan_objmgr_psoc *psoc; 4747 struct policy_mgr_psoc_priv_obj *pm_ctx; 4748 QDF_STATUS status = QDF_STATUS_SUCCESS; 4749 4750 psoc = wlan_vdev_get_psoc(vdev); 4751 if (!psoc) { 4752 policy_mgr_err("Psoc is Null"); 4753 return; 4754 } 4755 pm_ctx = policy_mgr_get_context(psoc); 4756 if (!pm_ctx) { 4757 policy_mgr_err("Invalid Context"); 4758 return; 4759 } 4760 4761 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4762 if (!req || !resp) { 4763 policy_mgr_err("arguments or event empty for vdev %d", 4764 wlan_vdev_get_id(vdev)); 4765 goto complete_evnt; 4766 } 4767 4768 if (resp->status) { 4769 policy_mgr_err("Set link status %d, for mode %d reason %d vdev bitmask 0x%x", 4770 resp->status, req->param.force_mode, 4771 req->param.reason, req->param.vdev_bitmap[0]); 4772 goto complete_evnt; 4773 } 4774 4775 policy_mgr_debug("Req mode %d reason %d, bitmask[0] = 0x%x, resp: active %d inactive %d, active[0] 0x%x inactive[0] 0x%x", 4776 req->param.force_mode, req->param.reason, 4777 req->param.vdev_bitmap[0], 4778 resp->active_sz, resp->inactive_sz, 4779 resp->active[0], resp->inactive[0]); 4780 switch (req->param.force_mode) { 4781 case MLO_LINK_FORCE_MODE_ACTIVE: 4782 policy_mgr_handle_force_active_resp(psoc, vdev, req, resp); 4783 break; 4784 case MLO_LINK_FORCE_MODE_INACTIVE: 4785 policy_mgr_handle_force_inactive_resp(psoc, vdev, req, resp); 4786 break; 4787 case MLO_LINK_FORCE_MODE_ACTIVE_NUM: 4788 policy_mgr_handle_force_active_num_resp(psoc, vdev, req, resp); 4789 break; 4790 case MLO_LINK_FORCE_MODE_INACTIVE_NUM: 4791 policy_mgr_handle_force_inactive_num_resp(psoc, vdev, req, 4792 resp); 4793 break; 4794 case MLO_LINK_FORCE_MODE_NO_FORCE: 4795 policy_mgr_handle_no_force_resp(psoc, vdev, req, resp); 4796 break; 4797 case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE: 4798 policy_mgr_handle_force_active_inactive_resp(psoc, vdev, req, 4799 resp); 4800 break; 4801 default: 4802 policy_mgr_err("Invalid request req mode %d", 4803 req->param.force_mode); 4804 break; 4805 } 4806 if (req->param.reason == MLO_LINK_FORCE_REASON_LINK_REMOVAL) 4807 policy_mgr_trigger_roam_on_link_removal(vdev); 4808 4809 complete_evnt: 4810 policy_mgr_set_link_in_progress(pm_ctx, false); 4811 if (ml_is_nlink_service_supported(psoc) && 4812 req && resp && !resp->status && 4813 req->param.control_flags.post_re_evaluate) 4814 status = ml_nlink_conn_change_notify( 4815 psoc, wlan_vdev_get_id(vdev), 4816 ml_nlink_connection_updated_evt, NULL); 4817 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4818 4819 /* reschedule force scc workqueue after link state changes */ 4820 if (req && resp && !resp->status && 4821 status == QDF_STATUS_SUCCESS) 4822 policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false); 4823 } 4824 #else 4825 static inline QDF_STATUS 4826 policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx, 4827 uint8_t vdev_id) 4828 { 4829 return QDF_STATUS_SUCCESS; 4830 } 4831 #endif 4832 4833 bool policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc *psoc, 4834 uint8_t vdev_id) 4835 { 4836 struct wlan_objmgr_vdev *vdev; 4837 bool disconnected; 4838 4839 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 4840 WLAN_POLICY_MGR_ID); 4841 if (!vdev) 4842 return true; 4843 /* mlo mgr has no corresponding protocol api used in non-osif/hdd 4844 * component. Todo: clean up to use internal API 4845 */ 4846 disconnected = ucfg_mlo_is_mld_disconnected(vdev); 4847 4848 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 4849 4850 return disconnected; 4851 } 4852 4853 void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, 4854 enum QDF_OPMODE mode, 4855 uint8_t session_id) 4856 { 4857 struct policy_mgr_psoc_priv_obj *pm_ctx; 4858 uint32_t conn_6ghz_flag = 0; 4859 4860 pm_ctx = policy_mgr_get_context(psoc); 4861 if (!pm_ctx) { 4862 policy_mgr_err("Invalid Context"); 4863 return; 4864 } 4865 4866 /* 4867 * Need to acquire mutex as entire functionality in this function 4868 * is in critical section 4869 */ 4870 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4871 switch (mode) { 4872 case QDF_STA_MODE: 4873 case QDF_P2P_CLIENT_MODE: 4874 case QDF_P2P_GO_MODE: 4875 case QDF_SAP_MODE: 4876 case QDF_NAN_DISC_MODE: 4877 case QDF_NDI_MODE: 4878 pm_ctx->no_of_active_sessions[mode]++; 4879 break; 4880 default: 4881 break; 4882 } 4883 4884 if (mode == QDF_NDI_MODE && 4885 pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt) 4886 pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt( 4887 psoc, session_id, 4888 pm_ctx->no_of_active_sessions[mode]); 4889 4890 if (mode != QDF_NAN_DISC_MODE && pm_ctx->dp_cbacks.hdd_v2_flow_pool_map) 4891 pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id); 4892 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) 4893 policy_mgr_get_ap_6ghz_capable(psoc, session_id, 4894 &conn_6ghz_flag); 4895 4896 policy_mgr_debug("No.# of active sessions for mode %d = %d", 4897 mode, pm_ctx->no_of_active_sessions[mode]); 4898 policy_mgr_incr_connection_count(psoc, session_id, mode); 4899 4900 if ((policy_mgr_mode_specific_connection_count( 4901 psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) { 4902 /* Send set pcl for all the connected STA vdev */ 4903 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4904 polic_mgr_send_pcl_to_fw(psoc, mode); 4905 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4906 } 4907 4908 /* Notify tdls */ 4909 if (pm_ctx->tdls_cbacks.tdls_notify_increment_session) 4910 pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc); 4911 4912 /* 4913 * Disable LRO/GRO if P2P or SAP connection has come up or 4914 * there are more than one STA connections 4915 */ 4916 if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) > 1) || 4917 (policy_mgr_get_beaconing_mode_count(psoc, NULL) > 0) || 4918 (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) > 4919 0) || 4920 (policy_mgr_mode_specific_connection_count(psoc, 4921 PM_NDI_MODE, 4922 NULL) > 0)) { 4923 if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency) 4924 pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(true); 4925 }; 4926 4927 /* Enable RPS if SAP interface has come up */ 4928 if (policy_mgr_get_sap_mode_count(psoc, NULL) == 1) { 4929 if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb) 4930 pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true); 4931 } 4932 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) 4933 policy_mgr_init_ap_6ghz_capable(psoc, session_id, 4934 conn_6ghz_flag); 4935 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE || 4936 mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) 4937 policy_mgr_update_dfs_master_dynamic_enabled(psoc, session_id); 4938 4939 policy_mgr_dump_current_concurrency(psoc); 4940 4941 if (policy_mgr_update_indoor_concurrency(psoc, session_id, 0, CONNECT)) 4942 wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev); 4943 4944 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4945 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) 4946 ml_nlink_conn_change_notify( 4947 psoc, session_id, ml_nlink_ap_started_evt, NULL); 4948 } 4949 4950 /** 4951 * policy_mgr_update_sta_scc_info_for_later_check() - function to update sta/sap 4952 * scc channel frequency and later check flag. 4953 * @pm_ctx: policy manager context pointer 4954 * @mode: operation mode 4955 * @vdev_id: vdev id 4956 * 4957 * Return: None 4958 */ 4959 static void policy_mgr_update_sta_scc_info_for_later_check( 4960 struct policy_mgr_psoc_priv_obj *pm_ctx, 4961 enum QDF_OPMODE mode, 4962 uint8_t vdev_id) 4963 { 4964 uint32_t conn_index = 0; 4965 qdf_freq_t sta_freq = 0; 4966 4967 if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE) 4968 return; 4969 4970 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4971 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 4972 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { 4973 sta_freq = pm_conc_connection_list[conn_index].freq; 4974 break; 4975 } 4976 conn_index++; 4977 } 4978 4979 if (!sta_freq) 4980 goto release_mutex; 4981 4982 /* 4983 * When STA disconnected, we need to move DFS SAP 4984 * to Non-DFS if g_sta_sap_scc_on_dfs_chan enabled. 4985 * The same if g_sta_sap_scc_on_lte_coex_chan enabled, 4986 * need to move SAP on unsafe channel to safe channel. 4987 * The flag will be checked by 4988 * policy_mgr_is_sap_restart_required_after_sta_disconnect. 4989 */ 4990 conn_index = 0; 4991 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 4992 if (pm_conc_connection_list[conn_index].freq == sta_freq && 4993 (pm_conc_connection_list[conn_index].mode == PM_SAP_MODE || 4994 pm_conc_connection_list[conn_index].mode == 4995 PM_P2P_GO_MODE)) { 4996 pm_ctx->last_disconn_sta_freq = sta_freq; 4997 break; 4998 } 4999 conn_index++; 5000 } 5001 5002 release_mutex: 5003 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5004 } 5005 5006 QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, 5007 enum QDF_OPMODE mode, 5008 uint8_t session_id) 5009 { 5010 struct policy_mgr_psoc_priv_obj *pm_ctx; 5011 QDF_STATUS qdf_status; 5012 bool mcc_mode; 5013 uint32_t session_count, cur_freq; 5014 5015 pm_ctx = policy_mgr_get_context(psoc); 5016 if (!pm_ctx) { 5017 policy_mgr_err("context is NULL"); 5018 return QDF_STATUS_E_EMPTY; 5019 } 5020 5021 qdf_status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc, 5022 policy_mgr_qdf_opmode_to_pm_con_mode(psoc, mode, 5023 session_id), 5024 session_id); 5025 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5026 policy_mgr_debug("No connection with mode:%d vdev_id:%d", 5027 policy_mgr_qdf_opmode_to_pm_con_mode(psoc, mode, 5028 session_id), 5029 session_id); 5030 /* 5031 * In case of disconnect try delete the link from disabled link 5032 * as well, if its not present in pm_conc_connection_list, 5033 * it can be present in pm_disabled_ml_links. 5034 */ 5035 policy_mgr_delete_from_disabled_links(pm_ctx, session_id); 5036 policy_mgr_dump_current_concurrency(psoc); 5037 return qdf_status; 5038 } 5039 policy_mgr_update_sta_scc_info_for_later_check(pm_ctx, 5040 mode, 5041 session_id); 5042 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5043 switch (mode) { 5044 case QDF_STA_MODE: 5045 case QDF_P2P_CLIENT_MODE: 5046 case QDF_P2P_GO_MODE: 5047 case QDF_SAP_MODE: 5048 case QDF_NAN_DISC_MODE: 5049 case QDF_NDI_MODE: 5050 if (pm_ctx->no_of_active_sessions[mode]) 5051 pm_ctx->no_of_active_sessions[mode]--; 5052 break; 5053 default: 5054 break; 5055 } 5056 5057 policy_mgr_get_chan_by_session_id(psoc, session_id, &cur_freq); 5058 5059 policy_mgr_decr_connection_count(psoc, session_id); 5060 session_count = pm_ctx->no_of_active_sessions[mode]; 5061 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5062 5063 if (mode != QDF_NAN_DISC_MODE && 5064 pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap) 5065 pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id); 5066 5067 if (mode == QDF_NDI_MODE && 5068 pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt) 5069 pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt( 5070 psoc, session_id, session_count); 5071 5072 policy_mgr_debug("No.# of active sessions for mode %d = %d", 5073 mode, session_count); 5074 5075 /* Notify tdls */ 5076 if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session) 5077 pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc); 5078 /* Enable LRO/GRO if there no concurrency */ 5079 if ((policy_mgr_get_connection_count(psoc) == 0) || 5080 ((policy_mgr_mode_specific_connection_count(psoc, 5081 PM_STA_MODE, 5082 NULL) == 1) && 5083 (policy_mgr_get_beaconing_mode_count(psoc, NULL) == 0) && 5084 (policy_mgr_mode_specific_connection_count(psoc, 5085 PM_P2P_CLIENT_MODE, 5086 NULL) == 0) && 5087 (policy_mgr_mode_specific_connection_count(psoc, 5088 PM_NDI_MODE, 5089 NULL) == 0))) { 5090 if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency) 5091 pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(false); 5092 }; 5093 5094 /* Disable RPS if SAP interface has come up */ 5095 if (policy_mgr_get_sap_mode_count(psoc, NULL) == 0) { 5096 if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb) 5097 pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(false); 5098 } 5099 5100 policy_mgr_dump_current_concurrency(psoc); 5101 5102 /* 5103 * Check mode of entry being removed. Update mcc_mode only when STA 5104 * or SAP since IPA only cares about these two 5105 */ 5106 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) { 5107 mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc); 5108 5109 if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb) 5110 pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode); 5111 } 5112 5113 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE || 5114 mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) 5115 policy_mgr_update_dfs_master_dynamic_enabled(psoc, session_id); 5116 5117 if (!pm_ctx->last_disconn_sta_freq) { 5118 if (policy_mgr_update_indoor_concurrency(psoc, session_id, 5119 cur_freq, DISCONNECT_WITHOUT_CONCURRENCY)) 5120 wlan_reg_recompute_current_chan_list(psoc, 5121 pm_ctx->pdev); 5122 } 5123 5124 if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev) && 5125 (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE)) 5126 wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev); 5127 5128 return qdf_status; 5129 } 5130 5131 QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc, 5132 uint32_t vdev_id, 5133 enum QDF_OPMODE op_mode) 5134 { 5135 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5136 uint32_t conn_index; 5137 struct policy_mgr_vdev_entry_info conn_table_entry = {0}; 5138 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE; 5139 uint8_t nss_2g = 0, nss_5g = 0; 5140 enum policy_mgr_con_mode mode; 5141 uint32_t ch_freq; 5142 uint32_t nss = 0; 5143 struct policy_mgr_psoc_priv_obj *pm_ctx; 5144 bool update_conn = true; 5145 5146 pm_ctx = policy_mgr_get_context(psoc); 5147 if (!pm_ctx) { 5148 policy_mgr_err("context is NULL"); 5149 return status; 5150 } 5151 5152 conn_index = policy_mgr_get_connection_count(psoc); 5153 if (pm_ctx->cfg.max_conc_cxns < conn_index) { 5154 policy_mgr_err("exceeded max connection limit %d", 5155 pm_ctx->cfg.max_conc_cxns); 5156 return status; 5157 } 5158 5159 if (op_mode == QDF_NAN_DISC_MODE) { 5160 status = wlan_nan_get_connection_info(psoc, &conn_table_entry); 5161 if (QDF_IS_STATUS_ERROR(status)) { 5162 policy_mgr_err("Can't get NAN Connection info"); 5163 return status; 5164 } 5165 } else if (pm_ctx->wma_cbacks.wma_get_connection_info) { 5166 status = pm_ctx->wma_cbacks.wma_get_connection_info( 5167 vdev_id, &conn_table_entry); 5168 if (QDF_STATUS_SUCCESS != status) { 5169 policy_mgr_err("can't find vdev_id %d in connection table", 5170 vdev_id); 5171 return status; 5172 } 5173 } else { 5174 policy_mgr_err("wma_get_connection_info is NULL"); 5175 return QDF_STATUS_E_FAILURE; 5176 } 5177 5178 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id); 5179 5180 ch_freq = conn_table_entry.mhz; 5181 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); 5182 if (QDF_IS_STATUS_SUCCESS(status)) { 5183 if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) || 5184 (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1)) 5185 chain_mask = POLICY_MGR_TWO_TWO; 5186 else 5187 chain_mask = POLICY_MGR_ONE_ONE; 5188 nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g; 5189 } else { 5190 policy_mgr_err("Error in getting nss"); 5191 } 5192 5193 if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE) 5194 update_conn = false; 5195 5196 /* add the entry */ 5197 policy_mgr_update_conc_list(psoc, conn_index, 5198 mode, 5199 ch_freq, 5200 policy_mgr_get_bw(conn_table_entry.chan_width), 5201 conn_table_entry.mac_id, 5202 chain_mask, 5203 nss, vdev_id, true, update_conn, 5204 conn_table_entry.ch_flagext); 5205 policy_mgr_debug("Add at idx:%d vdev %d mac=%d", 5206 conn_index, vdev_id, 5207 conn_table_entry.mac_id); 5208 5209 return QDF_STATUS_SUCCESS; 5210 } 5211 5212 QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, 5213 uint32_t vdev_id) 5214 { 5215 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5216 uint32_t conn_index = 0, next_conn_index = 0; 5217 bool found = false; 5218 struct policy_mgr_psoc_priv_obj *pm_ctx; 5219 bool panic = false; 5220 5221 pm_ctx = policy_mgr_get_context(psoc); 5222 if (!pm_ctx) { 5223 policy_mgr_err("Invalid Context"); 5224 return status; 5225 } 5226 5227 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5228 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 5229 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { 5230 /* debug msg */ 5231 found = true; 5232 break; 5233 } 5234 conn_index++; 5235 } 5236 if (!found) { 5237 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list", 5238 vdev_id); 5239 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5240 return status; 5241 } 5242 next_conn_index = conn_index + 1; 5243 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(next_conn_index)) { 5244 pm_conc_connection_list[conn_index].vdev_id = 5245 pm_conc_connection_list[next_conn_index].vdev_id; 5246 pm_conc_connection_list[conn_index].mode = 5247 pm_conc_connection_list[next_conn_index].mode; 5248 pm_conc_connection_list[conn_index].mac = 5249 pm_conc_connection_list[next_conn_index].mac; 5250 pm_conc_connection_list[conn_index].freq = 5251 pm_conc_connection_list[next_conn_index].freq; 5252 pm_conc_connection_list[conn_index].bw = 5253 pm_conc_connection_list[next_conn_index].bw; 5254 pm_conc_connection_list[conn_index].chain_mask = 5255 pm_conc_connection_list[next_conn_index].chain_mask; 5256 pm_conc_connection_list[conn_index].original_nss = 5257 pm_conc_connection_list[next_conn_index].original_nss; 5258 pm_conc_connection_list[conn_index].in_use = 5259 pm_conc_connection_list[next_conn_index].in_use; 5260 pm_conc_connection_list[conn_index].ch_flagext = 5261 pm_conc_connection_list[next_conn_index].ch_flagext; 5262 conn_index++; 5263 next_conn_index++; 5264 } 5265 5266 /* clean up the entry */ 5267 qdf_mem_zero(&pm_conc_connection_list[next_conn_index - 1], 5268 sizeof(*pm_conc_connection_list)); 5269 5270 conn_index = 0; 5271 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 5272 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { 5273 panic = true; 5274 break; 5275 } 5276 conn_index++; 5277 } 5278 5279 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5280 if (panic) { 5281 policy_mgr_err("dup entry occur"); 5282 policy_mgr_debug_alert(); 5283 } 5284 if (pm_ctx->conc_cbacks.connection_info_update) 5285 pm_ctx->conc_cbacks.connection_info_update(); 5286 5287 return QDF_STATUS_SUCCESS; 5288 } 5289 5290 uint32_t policy_mgr_get_mode_specific_conn_info( 5291 struct wlan_objmgr_psoc *psoc, 5292 uint32_t *ch_freq_list, uint8_t *vdev_id, 5293 enum policy_mgr_con_mode mode) 5294 { 5295 5296 uint32_t count = 0, index = 0; 5297 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 5298 struct policy_mgr_psoc_priv_obj *pm_ctx; 5299 5300 pm_ctx = policy_mgr_get_context(psoc); 5301 if (!pm_ctx) { 5302 policy_mgr_err("Invalid Context"); 5303 return count; 5304 } 5305 if (!vdev_id) { 5306 policy_mgr_err("Null pointer error"); 5307 return count; 5308 } 5309 5310 count = policy_mgr_mode_specific_connection_count( 5311 psoc, mode, list); 5312 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5313 if (count == 1) { 5314 if (ch_freq_list) 5315 *ch_freq_list = 5316 pm_conc_connection_list[list[index]].freq; 5317 *vdev_id = 5318 pm_conc_connection_list[list[index]].vdev_id; 5319 } else { 5320 for (index = 0; index < count; index++) { 5321 if (ch_freq_list) 5322 ch_freq_list[index] = 5323 pm_conc_connection_list[list[index]].freq; 5324 5325 vdev_id[index] = 5326 pm_conc_connection_list[list[index]].vdev_id; 5327 } 5328 } 5329 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5330 5331 return count; 5332 } 5333 5334 uint32_t policy_mgr_get_sap_mode_info(struct wlan_objmgr_psoc *psoc, 5335 uint32_t *ch_freq_list, uint8_t *vdev_id) 5336 { 5337 uint32_t count; 5338 5339 count = policy_mgr_get_mode_specific_conn_info(psoc, ch_freq_list, 5340 vdev_id, PM_SAP_MODE); 5341 5342 count += policy_mgr_get_mode_specific_conn_info( 5343 psoc, 5344 ch_freq_list ? &ch_freq_list[count] : NULL, 5345 vdev_id ? &vdev_id[count] : NULL, 5346 PM_LL_LT_SAP_MODE); 5347 return count; 5348 } 5349 5350 uint32_t policy_mgr_get_beaconing_mode_info(struct wlan_objmgr_psoc *psoc, 5351 uint32_t *ch_freq_list, 5352 uint8_t *vdev_id) 5353 { 5354 uint32_t count; 5355 5356 count = policy_mgr_get_sap_mode_info(psoc, ch_freq_list, vdev_id); 5357 5358 count += policy_mgr_get_mode_specific_conn_info( 5359 psoc, 5360 ch_freq_list ? &ch_freq_list[count] : NULL, 5361 vdev_id ? &vdev_id[count] : NULL, 5362 PM_P2P_GO_MODE); 5363 return count; 5364 } 5365 5366 void policy_mgr_get_ml_and_non_ml_sta_count(struct wlan_objmgr_psoc *psoc, 5367 uint8_t *num_ml, uint8_t *ml_idx, 5368 uint8_t *num_non_ml, 5369 uint8_t *non_ml_idx, 5370 qdf_freq_t *freq_list, 5371 uint8_t *vdev_id_list) 5372 { 5373 uint32_t sta_num = 0; 5374 uint8_t i; 5375 struct wlan_objmgr_vdev *temp_vdev; 5376 5377 *num_ml = 0; 5378 *num_non_ml = 0; 5379 5380 sta_num = policy_mgr_get_mode_specific_conn_info(psoc, freq_list, 5381 vdev_id_list, 5382 PM_STA_MODE); 5383 if (!sta_num) 5384 return; 5385 5386 for (i = 0; i < sta_num; i++) { 5387 temp_vdev = 5388 wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 5389 vdev_id_list[i], 5390 WLAN_POLICY_MGR_ID); 5391 if (!temp_vdev) { 5392 policy_mgr_err("invalid vdev for id %d", 5393 vdev_id_list[i]); 5394 *num_ml = 0; 5395 *num_non_ml = 0; 5396 return; 5397 } 5398 5399 if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) { 5400 if (ml_idx) 5401 ml_idx[*num_ml] = i; 5402 (*num_ml)++; 5403 } else { 5404 if (non_ml_idx) 5405 non_ml_idx[*num_non_ml] = i; 5406 (*num_non_ml)++; 5407 } 5408 5409 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID); 5410 } 5411 } 5412 5413 bool policy_mgr_concurrent_sta_on_different_mac(struct wlan_objmgr_psoc *psoc) 5414 { 5415 uint8_t num_ml = 0, num_non_ml = 0; 5416 uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 5417 uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 5418 qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 5419 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 5420 struct policy_mgr_psoc_priv_obj *pm_ctx; 5421 bool is_different_mac = false; 5422 int i; 5423 5424 if (!policy_mgr_is_hw_dbs_capable(psoc)) 5425 return false; 5426 5427 pm_ctx = policy_mgr_get_context(psoc); 5428 if (!pm_ctx) { 5429 policy_mgr_err("Invalid Context"); 5430 return false; 5431 } 5432 5433 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5434 policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx, 5435 &num_non_ml, non_ml_idx, 5436 freq_list, vdev_id_list); 5437 if (num_ml + num_non_ml < 2 || !num_non_ml) 5438 goto out; 5439 5440 /* 5441 * If more than 1 Non-ML STA is present, check whether they are 5442 * within the same band. 5443 */ 5444 for (i = 1; i < num_non_ml; i++) { 5445 if (!policy_mgr_2_freq_always_on_same_mac(psoc, 5446 freq_list[non_ml_idx[i]], 5447 freq_list[non_ml_idx[0]])) { 5448 is_different_mac = true; 5449 goto out; 5450 } 5451 } 5452 5453 if (num_non_ml >= 2) 5454 goto out; 5455 5456 /* ML STA + Non-ML STA */ 5457 for (i = 0; i < num_ml; i++) { 5458 if (!policy_mgr_2_freq_always_on_same_mac(psoc, 5459 freq_list[ml_idx[i]], 5460 freq_list[non_ml_idx[0]])) { 5461 is_different_mac = true; 5462 goto out; 5463 } 5464 } 5465 5466 out: 5467 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5468 policy_mgr_debug("Non-ML STA count %d, ML STA count %d, sta concurrency on different mac %d", 5469 num_non_ml, num_ml, is_different_mac); 5470 5471 return is_different_mac; 5472 } 5473 5474 bool policy_mgr_max_concurrent_connections_reached( 5475 struct wlan_objmgr_psoc *psoc) 5476 { 5477 uint8_t i = 0, j = 0; 5478 struct policy_mgr_psoc_priv_obj *pm_ctx; 5479 5480 pm_ctx = policy_mgr_get_context(psoc); 5481 if (pm_ctx) { 5482 for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) 5483 j += pm_ctx->no_of_active_sessions[i]; 5484 return j > 5485 (pm_ctx->cfg.max_conc_cxns - 1); 5486 } 5487 5488 return false; 5489 } 5490 5491 static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc) 5492 { 5493 struct policy_mgr_psoc_priv_obj *pm_ctx; 5494 5495 pm_ctx = policy_mgr_get_context(psoc); 5496 if (!pm_ctx) { 5497 policy_mgr_err("Invalid Context"); 5498 return false; 5499 } 5500 5501 return pm_ctx->user_cfg.sub_20_mhz_enabled; 5502 } 5503 5504 /** 5505 * policy_mgr_allow_wapi_concurrency() - Check if WAPI concurrency is allowed 5506 * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context 5507 * 5508 * This routine is called to check vdev security mode allowed in concurrency. 5509 * At present, WAPI security mode is not allowed to run concurrency with any 5510 * other vdev if the hardware doesn't support WAPI concurrency. 5511 * 5512 * Return: true - allow 5513 */ 5514 static bool 5515 policy_mgr_allow_wapi_concurrency(struct policy_mgr_psoc_priv_obj *pm_ctx) 5516 { 5517 struct wlan_objmgr_pdev *pdev = pm_ctx->pdev; 5518 struct wmi_unified *wmi_handle; 5519 struct wlan_objmgr_psoc *psoc; 5520 5521 if (!pdev) { 5522 policy_mgr_debug("pdev is Null"); 5523 return false; 5524 } 5525 5526 psoc = wlan_pdev_get_psoc(pdev); 5527 if (!psoc) 5528 return false; 5529 5530 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 5531 if (!wmi_handle) { 5532 policy_mgr_debug("Invalid WMI handle"); 5533 return false; 5534 } 5535 5536 if (!wmi_service_enabled(wmi_handle, 5537 wmi_service_wapi_concurrency_supported) && 5538 mlme_is_wapi_sta_active(pdev) && 5539 policy_mgr_get_connection_count(pm_ctx->psoc) > 0) 5540 return false; 5541 5542 return true; 5543 } 5544 5545 #ifdef FEATURE_FOURTH_CONNECTION 5546 static bool policy_mgr_is_concurrency_allowed_4_port( 5547 struct wlan_objmgr_psoc *psoc, 5548 enum policy_mgr_con_mode mode, 5549 uint32_t ch_freq, 5550 struct policy_mgr_pcl_list pcl) 5551 { 5552 uint32_t i; 5553 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; 5554 uint8_t sap_cnt, go_cnt; 5555 5556 /* new STA may just have ssid, no channel until bssid assigned */ 5557 if (ch_freq == 0 && mode == PM_STA_MODE) 5558 return true; 5559 5560 sap_cnt = policy_mgr_mode_specific_connection_count(psoc, 5561 PM_SAP_MODE, NULL); 5562 5563 go_cnt = policy_mgr_mode_specific_connection_count(psoc, 5564 PM_P2P_GO_MODE, NULL); 5565 if (sap_cnt || go_cnt) { 5566 pm_ctx = policy_mgr_get_context(psoc); 5567 if (!pm_ctx) { 5568 policy_mgr_err("context is NULL"); 5569 return false; 5570 } 5571 5572 if (!policy_mgr_is_force_scc(psoc)) { 5573 policy_mgr_err("couldn't start 4th port for bad force scc cfg"); 5574 return false; 5575 } 5576 5577 if (!policy_mgr_is_dbs_enable(psoc) || 5578 !pm_ctx->cfg.sta_sap_scc_on_dfs_chnl || 5579 !pm_ctx->cfg.sta_sap_scc_on_lte_coex_chnl) { 5580 policy_mgr_err( 5581 "Couldn't start 4th port for bad cfg of dual mac, dfs scc, lte coex scc"); 5582 return false; 5583 } 5584 for (i = 0; i < pcl.pcl_len; i++) 5585 if (ch_freq == pcl.pcl_list[i]) 5586 return true; 5587 5588 policy_mgr_err("4th port failed on ch freq %d with mode %d", 5589 ch_freq, mode); 5590 5591 return false; 5592 } 5593 5594 return true; 5595 } 5596 #else 5597 static inline bool policy_mgr_is_concurrency_allowed_4_port( 5598 struct wlan_objmgr_psoc *psoc, 5599 enum policy_mgr_con_mode mode, 5600 uint32_t ch_freq, 5601 struct policy_mgr_pcl_list pcl) 5602 {return false; } 5603 #endif 5604 5605 bool 5606 policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc) 5607 { 5608 struct wmi_unified *wmi_handle; 5609 5610 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 5611 if (!wmi_handle) { 5612 policy_mgr_debug("Invalid WMI handle"); 5613 return false; 5614 } 5615 if (!wmi_service_enabled(wmi_handle, 5616 wmi_service_sta_plus_sta_support)) { 5617 policy_mgr_rl_debug("STA+STA is not supported"); 5618 return false; 5619 } 5620 5621 return true; 5622 } 5623 5624 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) 5625 bool policy_mgr_is_6ghz_conc_mode_supported( 5626 struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) 5627 { 5628 if (mode == PM_STA_MODE || mode == PM_SAP_MODE || 5629 mode == PM_P2P_CLIENT_MODE || mode == PM_P2P_GO_MODE) 5630 return true; 5631 else 5632 return false; 5633 } 5634 #endif 5635 5636 /** 5637 * policy_mgr_is_6g_channel_allowed() - Check new 6Ghz connection 5638 * allowed or not 5639 * @psoc: Pointer to soc 5640 * @mode: new connection mode 5641 * @ch_freq: channel freq 5642 * 5643 * 1. Only STA/SAP are allowed on 6Ghz. 5644 * 2. If there is DFS beacon entity existing on 5G band, 5G+6G MCC is not 5645 * allowed. 5646 * 5647 * Return: true if supports else false. 5648 */ 5649 static bool policy_mgr_is_6g_channel_allowed( 5650 struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, 5651 uint32_t ch_freq) 5652 { 5653 uint32_t conn_index = 0; 5654 struct policy_mgr_psoc_priv_obj *pm_ctx; 5655 struct policy_mgr_conc_connection_info *conn; 5656 bool is_dfs; 5657 5658 pm_ctx = policy_mgr_get_context(psoc); 5659 if (!pm_ctx) { 5660 policy_mgr_err("Invalid Context"); 5661 return false; 5662 } 5663 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) { 5664 policy_mgr_rl_debug("Not a 6Ghz channel Freq"); 5665 return true; 5666 } 5667 /* Only STA/SAP is supported on 6Ghz currently */ 5668 if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) { 5669 policy_mgr_rl_debug("mode %d for 6ghz not supported", mode); 5670 return false; 5671 } 5672 5673 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5674 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 5675 conn_index++) { 5676 conn = &pm_conc_connection_list[conn_index]; 5677 if (!conn->in_use) 5678 continue; 5679 is_dfs = (conn->ch_flagext & 5680 (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) && 5681 WLAN_REG_IS_5GHZ_CH_FREQ(conn->freq); 5682 if (policy_mgr_is_beaconing_mode(conn->mode) && 5683 is_dfs && (ch_freq != conn->freq && 5684 !policy_mgr_are_sbs_chan(psoc, ch_freq, 5685 conn->freq))) { 5686 policy_mgr_rl_debug("don't allow MCC if SAP/GO on DFS channel"); 5687 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5688 return false; 5689 } 5690 } 5691 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5692 5693 return true; 5694 } 5695 5696 #ifdef WLAN_FEATURE_11BE_MLO 5697 static bool policy_mgr_is_acs_2ghz_only_sap(struct wlan_objmgr_psoc *psoc, 5698 uint8_t sap_vdev_id) 5699 { 5700 struct policy_mgr_psoc_priv_obj *pm_ctx; 5701 uint32_t acs_band = QCA_ACS_MODE_IEEE80211ANY; 5702 5703 pm_ctx = policy_mgr_get_context(psoc); 5704 if (!pm_ctx) { 5705 policy_mgr_err("Invalid Context"); 5706 return false; 5707 } 5708 5709 if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band) 5710 pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc, 5711 sap_vdev_id, 5712 &acs_band); 5713 5714 if (acs_band == QCA_ACS_MODE_IEEE80211B || 5715 acs_band == QCA_ACS_MODE_IEEE80211G) 5716 return true; 5717 5718 return false; 5719 } 5720 5721 bool policy_mgr_vdev_is_force_inactive(struct wlan_objmgr_psoc *psoc, 5722 uint8_t vdev_id) 5723 { 5724 bool force_inactive = false; 5725 uint8_t conn_index; 5726 struct policy_mgr_psoc_priv_obj *pm_ctx; 5727 5728 pm_ctx = policy_mgr_get_context(psoc); 5729 if (!pm_ctx) { 5730 policy_mgr_err("Invalid Context"); 5731 return false; 5732 } 5733 5734 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5735 /* Get disabled link info as well and keep it at last */ 5736 for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK; 5737 conn_index++) { 5738 if (pm_disabled_ml_links[conn_index].in_use && 5739 pm_disabled_ml_links[conn_index].mode == PM_STA_MODE && 5740 pm_disabled_ml_links[conn_index].vdev_id == vdev_id) { 5741 force_inactive = true; 5742 break; 5743 } 5744 } 5745 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5746 5747 return force_inactive; 5748 } 5749 5750 /* MCC avoidance priority value for different legacy connection type. 5751 * Internal macro, not expected used other code. 5752 * Bigger value have higher priority. 5753 */ 5754 #define PRIORITY_STA 3 5755 #define PRIORITY_SAP 2 5756 #define PRIORITY_P2P 1 5757 #define PRIORITY_OTHER 0 5758 5759 uint8_t 5760 policy_mgr_get_legacy_conn_info(struct wlan_objmgr_psoc *psoc, 5761 uint8_t *vdev_lst, 5762 qdf_freq_t *freq_lst, 5763 enum policy_mgr_con_mode *mode_lst, 5764 uint8_t lst_sz) 5765 { 5766 struct policy_mgr_psoc_priv_obj *pm_ctx; 5767 uint8_t conn_index, j = 0, i, k, n; 5768 struct wlan_objmgr_vdev *vdev; 5769 uint8_t vdev_id; 5770 uint8_t has_priority[MAX_NUMBER_OF_CONC_CONNECTIONS]; 5771 5772 pm_ctx = policy_mgr_get_context(psoc); 5773 if (!pm_ctx) { 5774 policy_mgr_err("Invalid Context"); 5775 return 0; 5776 } 5777 5778 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5779 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 5780 conn_index++) { 5781 if (j >= lst_sz) 5782 break; 5783 if (!pm_conc_connection_list[conn_index].in_use) 5784 continue; 5785 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 5786 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 5787 pm_ctx->psoc, vdev_id, WLAN_POLICY_MGR_ID); 5788 if (!vdev) { 5789 policy_mgr_err("invalid vdev for id %d", vdev_id); 5790 continue; 5791 } 5792 5793 if (wlan_vdev_mlme_is_mlo_vdev(vdev) && 5794 pm_conc_connection_list[conn_index].mode == 5795 PM_STA_MODE) { 5796 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 5797 continue; 5798 } 5799 if (pm_conc_connection_list[conn_index].mode != 5800 PM_STA_MODE && 5801 pm_conc_connection_list[conn_index].mode != 5802 PM_SAP_MODE && 5803 pm_conc_connection_list[conn_index].mode != 5804 PM_P2P_CLIENT_MODE && 5805 pm_conc_connection_list[conn_index].mode != 5806 PM_P2P_GO_MODE) { 5807 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 5808 continue; 5809 } 5810 5811 /* Set mcc avoidance priority value. The bigger value 5812 * have higher priority to avoid MCC. In 3 Port concurrency 5813 * case, usually we can only meet the higher priority intf's 5814 * MCC avoidance by force inactive link. 5815 */ 5816 if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE) 5817 has_priority[j] = PRIORITY_STA; 5818 else if (pm_conc_connection_list[conn_index].mode == 5819 PM_SAP_MODE && 5820 policy_mgr_is_acs_2ghz_only_sap(psoc, vdev_id)) 5821 has_priority[j] = PRIORITY_SAP; 5822 else if ((pm_conc_connection_list[conn_index].mode == 5823 PM_P2P_CLIENT_MODE || 5824 pm_conc_connection_list[conn_index].mode == 5825 PM_P2P_GO_MODE) && 5826 policy_mgr_is_vdev_high_tput_or_low_latency( 5827 psoc, vdev_id)) 5828 has_priority[j] = PRIORITY_P2P; 5829 else 5830 has_priority[j] = PRIORITY_OTHER; 5831 5832 vdev_lst[j] = vdev_id; 5833 freq_lst[j] = pm_conc_connection_list[conn_index].freq; 5834 mode_lst[j] = pm_conc_connection_list[conn_index].mode; 5835 policy_mgr_debug("vdev %d freq %d mode %s pri %d", 5836 vdev_id, freq_lst[j], 5837 device_mode_to_string(mode_lst[j]), 5838 has_priority[j]); 5839 j++; 5840 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 5841 } 5842 /* sort the list based on priority */ 5843 for (i = 0; i < j; i++) { 5844 uint8_t tmp_vdev_lst; 5845 qdf_freq_t tmp_freq_lst; 5846 enum policy_mgr_con_mode tmp_mode_lst; 5847 5848 n = i; 5849 for (k = i + 1; k < j; k++) { 5850 if (has_priority[n] < has_priority[k]) 5851 n = k; 5852 else if ((has_priority[n] == has_priority[k]) && 5853 (vdev_lst[n] > vdev_lst[k])) 5854 n = k; 5855 } 5856 if (n == i) 5857 continue; 5858 tmp_vdev_lst = vdev_lst[i]; 5859 tmp_freq_lst = freq_lst[i]; 5860 tmp_mode_lst = mode_lst[i]; 5861 5862 vdev_lst[i] = vdev_lst[n]; 5863 freq_lst[i] = freq_lst[n]; 5864 mode_lst[i] = mode_lst[n]; 5865 5866 vdev_lst[n] = tmp_vdev_lst; 5867 freq_lst[n] = tmp_freq_lst; 5868 mode_lst[n] = tmp_mode_lst; 5869 } 5870 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5871 5872 return j; 5873 } 5874 5875 static void 5876 policy_mgr_fill_ml_active_link_vdev_bitmap(struct mlo_link_set_active_req *req, 5877 uint8_t *mlo_vdev_lst, 5878 uint32_t num_mlo_vdev) 5879 { 5880 uint32_t entry_idx, entry_offset, vdev_idx; 5881 uint8_t vdev_id; 5882 5883 for (vdev_idx = 0; vdev_idx < num_mlo_vdev; vdev_idx++) { 5884 vdev_id = mlo_vdev_lst[vdev_idx]; 5885 entry_idx = vdev_id / 32; 5886 entry_offset = vdev_id % 32; 5887 if (entry_idx >= MLO_LINK_NUM_SZ) { 5888 policy_mgr_err("Invalid entry_idx %d num_mlo_vdev %d vdev %d", 5889 entry_idx, num_mlo_vdev, vdev_id); 5890 continue; 5891 } 5892 req->param.vdev_bitmap[entry_idx] |= (1 << entry_offset); 5893 /* update entry number if entry index changed */ 5894 if (req->param.num_vdev_bitmap < entry_idx + 1) 5895 req->param.num_vdev_bitmap = entry_idx + 1; 5896 } 5897 5898 policy_mgr_debug("num_vdev_bitmap %d vdev_bitmap[0] = 0x%x, vdev_bitmap[1] = 0x%x", 5899 req->param.num_vdev_bitmap, req->param.vdev_bitmap[0], 5900 req->param.vdev_bitmap[1]); 5901 } 5902 5903 static void 5904 policy_mgr_fill_ml_inactive_link_vdev_bitmap( 5905 struct mlo_link_set_active_req *req, 5906 uint8_t *mlo_inactive_vdev_lst, 5907 uint32_t num_mlo_inactive_vdev) 5908 { 5909 uint32_t entry_idx, entry_offset, vdev_idx; 5910 uint8_t vdev_id; 5911 5912 for (vdev_idx = 0; vdev_idx < num_mlo_inactive_vdev; vdev_idx++) { 5913 vdev_id = mlo_inactive_vdev_lst[vdev_idx]; 5914 entry_idx = vdev_id / 32; 5915 entry_offset = vdev_id % 32; 5916 if (entry_idx >= MLO_LINK_NUM_SZ) { 5917 policy_mgr_err("Invalid entry_idx %d num_mlo_vdev %d vdev %d", 5918 entry_idx, num_mlo_inactive_vdev, 5919 vdev_id); 5920 continue; 5921 } 5922 req->param.inactive_vdev_bitmap[entry_idx] |= 5923 (1 << entry_offset); 5924 /* update entry number if entry index changed */ 5925 if (req->param.num_inactive_vdev_bitmap < entry_idx + 1) 5926 req->param.num_inactive_vdev_bitmap = entry_idx + 1; 5927 } 5928 5929 policy_mgr_debug("num_vdev_bitmap %d inactive_vdev_bitmap[0] = 0x%x, inactive_vdev_bitmap[1] = 0x%x", 5930 req->param.num_inactive_vdev_bitmap, 5931 req->param.inactive_vdev_bitmap[0], 5932 req->param.inactive_vdev_bitmap[1]); 5933 } 5934 5935 /* 5936 * policy_mgr_handle_ml_sta_link_state_allowed() - Check ml sta connection to 5937 * allow link state change. 5938 * @psoc: psoc object 5939 * @reason: set link state reason 5940 * 5941 * If ml sta is not "connected" state, no need to do link state handling. 5942 * After disconnected, target will clear the force active/inactive state 5943 * and host will remove the connection entry finally. 5944 * After roaming done, active/inactive will be re-calculated. 5945 * 5946 * Return: QDF_STATUS_SUCCESS if link state is allowed to change 5947 */ 5948 static QDF_STATUS 5949 policy_mgr_handle_ml_sta_link_state_allowed(struct wlan_objmgr_psoc *psoc, 5950 enum mlo_link_force_reason reason) 5951 { 5952 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0; 5953 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 5954 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 5955 struct policy_mgr_psoc_priv_obj *pm_ctx; 5956 struct wlan_objmgr_vdev *vdev; 5957 bool ml_sta_is_not_connected = false; 5958 bool ml_sta_is_link_removal = false; 5959 uint8_t i; 5960 QDF_STATUS status = QDF_STATUS_SUCCESS; 5961 5962 pm_ctx = policy_mgr_get_context(psoc); 5963 if (!pm_ctx) { 5964 policy_mgr_err("Invalid Context"); 5965 return QDF_STATUS_E_INVAL; 5966 } 5967 5968 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 5969 ml_sta_vdev_lst, ml_freq_lst, &num_non_ml, 5970 NULL, NULL); 5971 if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) { 5972 policy_mgr_debug("ml sta num is %d", num_ml_sta); 5973 return QDF_STATUS_E_INVAL; 5974 } 5975 5976 for (i = 0; i < num_ml_sta; i++) { 5977 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc, 5978 ml_sta_vdev_lst[i], 5979 WLAN_POLICY_MGR_ID); 5980 if (!vdev) { 5981 policy_mgr_err("invalid vdev for id %d", 5982 ml_sta_vdev_lst[i]); 5983 continue; 5984 } 5985 if (!wlan_cm_is_vdev_connected(vdev)) { 5986 policy_mgr_debug("ml sta vdev %d is not connected state", 5987 ml_sta_vdev_lst[i]); 5988 ml_sta_is_not_connected = true; 5989 } 5990 if (wlan_get_vdev_link_removed_flag_by_vdev_id( 5991 psoc, ml_sta_vdev_lst[i])) { 5992 policy_mgr_debug("ml sta vdev %d link removed", 5993 ml_sta_vdev_lst[i]); 5994 ml_sta_is_link_removal = true; 5995 } 5996 5997 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 5998 } 5999 6000 if (ml_sta_is_not_connected) 6001 status = QDF_STATUS_E_FAILURE; 6002 else if (reason == MLO_LINK_FORCE_REASON_LINK_REMOVAL) { 6003 if (!ml_sta_is_link_removal) 6004 status = QDF_STATUS_E_FAILURE; 6005 } else { 6006 if (ml_sta_is_link_removal) 6007 status = QDF_STATUS_E_FAILURE; 6008 } 6009 policy_mgr_debug("set link reason %d status %d", reason, status); 6010 6011 return status; 6012 } 6013 6014 /* 6015 * policy_mgr_validate_set_mlo_link_cb() - Callback to check whether 6016 * it is allowed to set mlo sta link state. 6017 * @psoc: psoc object 6018 * @param: set mlo link parameter 6019 * 6020 * This api will be used as callback to be called by mlo_link_set_active 6021 * in serialization context. 6022 * 6023 * Return: QDF_STATUS_SUCCESS if set mlo link is allowed 6024 */ 6025 static QDF_STATUS 6026 policy_mgr_validate_set_mlo_link_cb(struct wlan_objmgr_psoc *psoc, 6027 struct mlo_link_set_active_param *param) 6028 { 6029 return policy_mgr_handle_ml_sta_link_state_allowed(psoc, 6030 param->reason); 6031 } 6032 6033 uint32_t 6034 policy_mgr_get_active_vdev_bitmap(struct wlan_objmgr_psoc *psoc) 6035 { 6036 struct policy_mgr_psoc_priv_obj *pm_ctx; 6037 6038 pm_ctx = policy_mgr_get_context(psoc); 6039 if (!pm_ctx) { 6040 policy_mgr_err("Invalid Context"); 6041 return QDF_STATUS_E_INVAL; 6042 } 6043 6044 policy_mgr_debug("active link bitmap value: %d", 6045 pm_ctx->active_vdev_bitmap); 6046 6047 return pm_ctx->active_vdev_bitmap; 6048 } 6049 6050 /** 6051 * policy_mgr_mlo_sta_set_link_by_linkid() - wrapper API to call set link 6052 * by link id bitmap API 6053 * @psoc: psoc object 6054 * @vdev: vdev object 6055 * @reason: Reason for which link is forced 6056 * @mode: Force reason 6057 * @link_num: valid for MLO_LINK_FORCE_MODE_ACTIVE_NUM and 6058 * MLO_LINK_FORCE_MODE_INACTIVE_NUM. 6059 * @num_mlo_vdev: number of mlo vdev in array mlo_vdev_lst 6060 * @mlo_vdev_lst: MLO STA vdev list 6061 * @num_mlo_inactive_vdev: number of mlo vdev in array mlo_inactive_vdev_lst 6062 * @mlo_inactive_vdev_lst: MLO STA vdev list 6063 * 6064 * This is internal wrapper of policy_mgr_mlo_sta_set_nlink to convert 6065 * vdev based set link to link id based API for being compatible with old code. 6066 * New code to use policy_mgr_mlo_sta_set_nlink directly as much as possible. 6067 * 6068 * Return: QDF_STATUS 6069 */ 6070 static QDF_STATUS 6071 policy_mgr_mlo_sta_set_link_by_linkid(struct wlan_objmgr_psoc *psoc, 6072 struct wlan_objmgr_vdev *vdev, 6073 enum mlo_link_force_reason reason, 6074 enum mlo_link_force_mode mode, 6075 uint8_t link_num, 6076 uint8_t num_mlo_vdev, 6077 uint8_t *mlo_vdev_lst, 6078 uint8_t num_mlo_inactive_vdev, 6079 uint8_t *mlo_inactive_vdev_lst) 6080 { 6081 uint32_t link_bitmap = 0; 6082 uint32_t link_bitmap2 = 0; 6083 uint32_t assoc_bitmap = 0; 6084 uint32_t vdev_bitmap[MLO_VDEV_BITMAP_SZ]; 6085 uint32_t vdev_bitmap2[MLO_VDEV_BITMAP_SZ]; 6086 uint8_t i, idx; 6087 uint32_t link_control_flags = 0; 6088 6089 qdf_mem_zero(vdev_bitmap, sizeof(vdev_bitmap)); 6090 qdf_mem_zero(vdev_bitmap2, sizeof(vdev_bitmap2)); 6091 6092 for (i = 0; i < num_mlo_vdev; i++) { 6093 idx = mlo_vdev_lst[i] / 32; 6094 if (idx >= MLO_VDEV_BITMAP_SZ) 6095 return QDF_STATUS_E_INVAL; 6096 vdev_bitmap[idx] |= 1 << (mlo_vdev_lst[i] % 32); 6097 } 6098 6099 for (i = 0; i < num_mlo_inactive_vdev; i++) { 6100 idx = mlo_inactive_vdev_lst[i] / 32; 6101 if (idx >= MLO_VDEV_BITMAP_SZ) 6102 return QDF_STATUS_E_INVAL; 6103 vdev_bitmap2[idx] |= 1 << (mlo_inactive_vdev_lst[i] % 32); 6104 } 6105 6106 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 6107 psoc, vdev, MLO_VDEV_BITMAP_SZ, vdev_bitmap, 6108 &link_bitmap, &assoc_bitmap); 6109 6110 ml_nlink_convert_vdev_bitmap_to_linkid_bitmap( 6111 psoc, vdev, MLO_VDEV_BITMAP_SZ, vdev_bitmap2, 6112 &link_bitmap2, &assoc_bitmap); 6113 6114 switch (mode) { 6115 case MLO_LINK_FORCE_MODE_ACTIVE: 6116 link_control_flags = link_ctrl_f_overwrite_active_bitmap; 6117 break; 6118 case MLO_LINK_FORCE_MODE_INACTIVE: 6119 if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL) 6120 link_control_flags = 6121 link_ctrl_f_overwrite_inactive_bitmap; 6122 break; 6123 case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE: 6124 if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL) 6125 link_control_flags = 6126 link_ctrl_f_overwrite_active_bitmap | 6127 link_ctrl_f_overwrite_inactive_bitmap; 6128 break; 6129 case MLO_LINK_FORCE_MODE_ACTIVE_NUM: 6130 link_control_flags = link_ctrl_f_dynamic_force_link_num; 6131 break; 6132 case MLO_LINK_FORCE_MODE_INACTIVE_NUM: 6133 link_control_flags = link_ctrl_f_dynamic_force_link_num; 6134 break; 6135 case MLO_LINK_FORCE_MODE_NO_FORCE: 6136 link_control_flags = 0; 6137 break; 6138 default: 6139 policy_mgr_err("Invalid force mode: %d", mode); 6140 return QDF_STATUS_E_INVAL; 6141 } 6142 6143 return policy_mgr_mlo_sta_set_nlink(psoc, vdev, reason, mode, 6144 link_num, link_bitmap, 6145 link_bitmap2, link_control_flags); 6146 } 6147 6148 /** 6149 * policy_mgr_mlo_sta_set_link_ext() - Set links for MLO STA 6150 * @psoc: psoc object 6151 * @reason: Reason for which link is forced 6152 * @mode: Force reason 6153 * @num_mlo_vdev: number of mlo vdev 6154 * @mlo_vdev_lst: MLO STA vdev list 6155 * @num_mlo_inactive_vdev: number of mlo vdev 6156 * @mlo_inactive_vdev_lst: MLO STA vdev list 6157 * 6158 * Interface manager Set links for MLO STA. And it supports to 6159 * add inactive vdev list. 6160 * 6161 * Return: QDF_STATUS 6162 */ 6163 static QDF_STATUS 6164 policy_mgr_mlo_sta_set_link_ext(struct wlan_objmgr_psoc *psoc, 6165 enum mlo_link_force_reason reason, 6166 enum mlo_link_force_mode mode, 6167 uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst, 6168 uint8_t num_mlo_inactive_vdev, 6169 uint8_t *mlo_inactive_vdev_lst) 6170 { 6171 struct mlo_link_set_active_req *req; 6172 QDF_STATUS status; 6173 struct policy_mgr_psoc_priv_obj *pm_ctx; 6174 struct wlan_objmgr_vdev *vdev; 6175 6176 if (!num_mlo_vdev) { 6177 policy_mgr_err("invalid 0 num_mlo_vdev"); 6178 return QDF_STATUS_E_INVAL; 6179 } 6180 6181 pm_ctx = policy_mgr_get_context(psoc); 6182 if (!pm_ctx) { 6183 policy_mgr_err("Invalid Context"); 6184 return QDF_STATUS_E_INVAL; 6185 } 6186 6187 req = qdf_mem_malloc(sizeof(*req)); 6188 if (!req) 6189 return QDF_STATUS_E_NOMEM; 6190 6191 /* 6192 * Use one of the ML vdev as, if called from disconnect the caller vdev 6193 * may get deleted, and thus flush serialization command. 6194 */ 6195 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, mlo_vdev_lst[0], 6196 WLAN_POLICY_MGR_ID); 6197 if (!vdev) { 6198 policy_mgr_err("vdev %d: invalid vdev", mlo_vdev_lst[0]); 6199 qdf_mem_free(req); 6200 return QDF_STATUS_E_FAILURE; 6201 } 6202 6203 policy_mgr_debug("vdev %d: mode %d num_mlo_vdev %d reason %d", 6204 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, reason); 6205 6206 req->ctx.vdev = vdev; 6207 req->param.reason = reason; 6208 req->param.force_mode = mode; 6209 req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp; 6210 req->ctx.validate_set_mlo_link_cb = 6211 policy_mgr_validate_set_mlo_link_cb; 6212 req->ctx.cb_arg = req; 6213 6214 /* set MLO vdev bit mask for all case */ 6215 policy_mgr_fill_ml_active_link_vdev_bitmap(req, mlo_vdev_lst, 6216 num_mlo_vdev); 6217 6218 pm_ctx->active_vdev_bitmap = req->param.vdev_bitmap[0]; 6219 pm_ctx->inactive_vdev_bitmap = req->param.vdev_bitmap[1]; 6220 6221 if (mode == MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE) 6222 policy_mgr_fill_ml_inactive_link_vdev_bitmap( 6223 req, mlo_inactive_vdev_lst, num_mlo_inactive_vdev); 6224 6225 /* 6226 * Fill number of links for MLO_LINK_FORCE_MODE_ACTIVE_NUM or 6227 * MLO_LINK_FORCE_MODE_INACTIVE_NUM mode. 6228 */ 6229 if (mode == MLO_LINK_FORCE_MODE_ACTIVE_NUM || 6230 mode == MLO_LINK_FORCE_MODE_INACTIVE_NUM) { 6231 req->param.num_link_entry = 1; 6232 req->param.link_num[0].num_of_link = num_mlo_vdev - 1; 6233 } 6234 6235 if (ml_is_nlink_service_supported(psoc) && 6236 reason != MLO_LINK_FORCE_REASON_TDLS) { 6237 status = 6238 policy_mgr_mlo_sta_set_link_by_linkid(psoc, vdev, reason, 6239 mode, 6240 req->param.link_num[0]. 6241 num_of_link, 6242 num_mlo_vdev, 6243 mlo_vdev_lst, 6244 num_mlo_inactive_vdev, 6245 mlo_inactive_vdev_lst); 6246 qdf_mem_free(req); 6247 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6248 6249 if (status != QDF_STATUS_E_PENDING) { 6250 policy_mgr_err("set_link_by_linkid status %d", status); 6251 return status; 6252 } 6253 return QDF_STATUS_SUCCESS; 6254 } 6255 6256 policy_mgr_set_link_in_progress(pm_ctx, true); 6257 6258 status = mlo_ser_set_link_req(req); 6259 if (QDF_IS_STATUS_ERROR(status)) { 6260 policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d reason %d", 6261 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, 6262 reason); 6263 qdf_mem_free(req); 6264 policy_mgr_set_link_in_progress(pm_ctx, false); 6265 } 6266 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6267 return status; 6268 } 6269 6270 QDF_STATUS 6271 policy_mgr_mlo_sta_set_link(struct wlan_objmgr_psoc *psoc, 6272 enum mlo_link_force_reason reason, 6273 enum mlo_link_force_mode mode, 6274 uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst) 6275 { 6276 return policy_mgr_mlo_sta_set_link_ext(psoc, reason, mode, num_mlo_vdev, 6277 mlo_vdev_lst, 0, NULL); 6278 } 6279 6280 QDF_STATUS 6281 policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc, 6282 struct wlan_objmgr_vdev *vdev, 6283 enum mlo_link_force_reason reason, 6284 enum mlo_link_force_mode mode, 6285 uint8_t link_num, 6286 uint16_t link_bitmap, 6287 uint16_t link_bitmap2, 6288 uint32_t link_control_flags) 6289 { 6290 struct mlo_link_set_active_req *req; 6291 QDF_STATUS status = QDF_STATUS_E_FAILURE; 6292 struct policy_mgr_psoc_priv_obj *pm_ctx; 6293 6294 pm_ctx = policy_mgr_get_context(psoc); 6295 if (!pm_ctx) { 6296 policy_mgr_err("Invalid Context"); 6297 return QDF_STATUS_E_INVAL; 6298 } 6299 6300 req = qdf_mem_malloc(sizeof(*req)); 6301 if (!req) 6302 return QDF_STATUS_E_NOMEM; 6303 6304 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_POLICY_MGR_ID); 6305 if (QDF_IS_STATUS_ERROR(status)) { 6306 qdf_mem_free(req); 6307 return QDF_STATUS_E_FAILURE; 6308 } 6309 6310 policy_mgr_set_link_in_progress(pm_ctx, true); 6311 6312 policy_mgr_debug("vdev %d: mode %d %s reason %d bitmap 0x%x 0x%x ctrl 0x%x", 6313 wlan_vdev_get_id(vdev), mode, 6314 force_mode_to_string(mode), reason, 6315 link_bitmap, link_bitmap2, 6316 link_control_flags); 6317 6318 req->ctx.vdev = vdev; 6319 req->param.reason = reason; 6320 req->param.force_mode = mode; 6321 req->param.use_ieee_link_id = true; 6322 req->param.force_cmd.ieee_link_id_bitmap = link_bitmap; 6323 req->param.force_cmd.ieee_link_id_bitmap2 = link_bitmap2; 6324 req->param.force_cmd.link_num = link_num; 6325 if (link_control_flags & link_ctrl_f_overwrite_active_bitmap) 6326 req->param.control_flags.overwrite_force_active_bitmap = true; 6327 if (link_control_flags & link_ctrl_f_overwrite_inactive_bitmap) 6328 req->param.control_flags.overwrite_force_inactive_bitmap = 6329 true; 6330 if (link_control_flags & link_ctrl_f_dynamic_force_link_num) 6331 req->param.control_flags.dynamic_force_link_num = true; 6332 if (link_control_flags & link_ctrl_f_post_re_evaluate) 6333 req->param.control_flags.post_re_evaluate = true; 6334 6335 status = 6336 wlan_vdev_get_bss_peer_mld_mac(vdev, 6337 &req->param.force_cmd.ap_mld_mac_addr); 6338 if (QDF_IS_STATUS_ERROR(status)) { 6339 policy_mgr_err("fail to get ap mld addr for vdev %d", 6340 wlan_vdev_get_id(vdev)); 6341 goto end; 6342 } 6343 if (qdf_is_macaddr_zero(&req->param.force_cmd.ap_mld_mac_addr)) { 6344 policy_mgr_err("get ap zero mld addr for vdev %d", 6345 wlan_vdev_get_id(vdev)); 6346 goto end; 6347 } 6348 6349 req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp; 6350 req->ctx.validate_set_mlo_link_cb = 6351 policy_mgr_validate_set_mlo_link_cb; 6352 req->ctx.cb_arg = req; 6353 status = mlo_ser_set_link_req(req); 6354 end: 6355 if (QDF_IS_STATUS_ERROR(status)) { 6356 policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d reason %d", 6357 wlan_vdev_get_id(vdev), mode, link_num, 6358 reason); 6359 qdf_mem_free(req); 6360 policy_mgr_set_link_in_progress(pm_ctx, false); 6361 } else { 6362 status = QDF_STATUS_E_PENDING; 6363 } 6364 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6365 6366 return status; 6367 } 6368 6369 uint32_t 6370 policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo) 6371 { 6372 struct wlan_objmgr_vdev *assoc_vdev; 6373 union conc_ext_flag conc_ext_flags; 6374 6375 conc_ext_flags.value = 0; 6376 if (!vdev || wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 6377 return conc_ext_flags.value; 6378 6379 if (!force_mlo && !wlan_vdev_mlme_is_mlo_vdev(vdev)) 6380 return conc_ext_flags.value; 6381 6382 conc_ext_flags.mlo = 1; 6383 if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) { 6384 assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev); 6385 if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev)) 6386 conc_ext_flags.mlo_link_assoc_connected = 1; 6387 } 6388 6389 return conc_ext_flags.value; 6390 } 6391 6392 /** 6393 * policy_mgr_allow_sta_concurrency() - check whether STA concurrency is allowed 6394 * @psoc: Pointer to soc 6395 * @freq: frequency to be checked 6396 * @ext_flags: extended flags for concurrency check 6397 * 6398 * Return: true if supports else false. 6399 */ 6400 static bool 6401 policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc, 6402 qdf_freq_t freq, 6403 uint32_t ext_flags) 6404 { 6405 uint32_t conn_index = 0; 6406 struct policy_mgr_psoc_priv_obj *pm_ctx; 6407 struct wlan_objmgr_vdev *vdev; 6408 bool is_mlo, mlo_sta_present = false; 6409 uint8_t vdev_id, sta_cnt = 0; 6410 enum policy_mgr_con_mode mode; 6411 union conc_ext_flag conc_ext_flags; 6412 6413 pm_ctx = policy_mgr_get_context(psoc); 6414 if (!pm_ctx) { 6415 policy_mgr_err("Invalid Context"); 6416 return false; 6417 } 6418 6419 conc_ext_flags.value = ext_flags; 6420 6421 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 6422 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 6423 conn_index++) { 6424 mode = pm_conc_connection_list[conn_index].mode; 6425 if (mode != PM_STA_MODE || 6426 !pm_conc_connection_list[conn_index].in_use) 6427 continue; 6428 6429 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 6430 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 6431 WLAN_POLICY_MGR_ID); 6432 if (!vdev) 6433 continue; 6434 6435 is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev); 6436 6437 /* Skip the link vdev for MLO STA */ 6438 if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) 6439 goto next; 6440 6441 sta_cnt++; 6442 if (!is_mlo) 6443 goto next; 6444 6445 mlo_sta_present = true; 6446 next: 6447 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6448 } 6449 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 6450 6451 /* Reject if multiple STA connections are not allowed */ 6452 if (sta_cnt && 6453 !policy_mgr_allow_multiple_sta_connections(psoc)) { 6454 policy_mgr_rl_debug("Disallow Multiple STA connections"); 6455 return false; 6456 } 6457 6458 if (mlo_sta_present && conc_ext_flags.mlo_link_assoc_connected) { 6459 policy_mgr_rl_debug("Allow secondary MLO link"); 6460 return true; 6461 } 6462 6463 if (conc_ext_flags.mlo && mlo_sta_present) { 6464 policy_mgr_rl_debug("Disallow ML STA when ML STA is present"); 6465 return false; 6466 } 6467 6468 /* 6469 * Reject a 3rd STA. 6470 * Treat a MLO STA(including the primary and secondary link vdevs) 6471 * as 1 STA here. 6472 */ 6473 if (sta_cnt >= 2) { 6474 policy_mgr_rl_debug("Disallow 3rd STA"); 6475 return false; 6476 } 6477 6478 return true; 6479 } 6480 6481 bool 6482 policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc, 6483 bool is_new_vdev_mlo, 6484 uint8_t new_vdev_id) 6485 { 6486 struct policy_mgr_psoc_priv_obj *pm_ctx; 6487 uint32_t conn_index; 6488 bool ret = false, mlo_sap_present = false; 6489 struct wlan_objmgr_vdev *vdev; 6490 uint32_t vdev_id; 6491 6492 pm_ctx = policy_mgr_get_context(psoc); 6493 if (!pm_ctx) { 6494 policy_mgr_err("Invalid Context"); 6495 return ret; 6496 } 6497 6498 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 6499 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 6500 conn_index++) { 6501 if (!pm_conc_connection_list[conn_index].in_use || 6502 (pm_conc_connection_list[conn_index].mode != PM_SAP_MODE)) 6503 continue; 6504 6505 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 6506 if (vdev_id == new_vdev_id) 6507 continue; 6508 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 6509 WLAN_POLICY_MGR_ID); 6510 if (!vdev) { 6511 policy_mgr_err("vdev for vdev_id:%d is NULL", vdev_id); 6512 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 6513 return ret; 6514 } 6515 6516 /* As only one ML SAP is allowed, break after one ML SAP 6517 * instance found in the policy manager list. 6518 */ 6519 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) { 6520 mlo_sap_present = true; 6521 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6522 break; 6523 } 6524 6525 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6526 } 6527 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 6528 6529 if (is_new_vdev_mlo && mlo_sap_present) 6530 ret = false; 6531 else 6532 ret = true; 6533 6534 return ret; 6535 } 6536 6537 QDF_STATUS 6538 policy_mgr_link_switch_notifier_cb(struct wlan_objmgr_vdev *vdev, 6539 struct wlan_mlo_link_switch_req *req) 6540 { 6541 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 6542 struct policy_mgr_psoc_priv_obj *pm_ctx; 6543 uint8_t vdev_id = req->vdev_id; 6544 uint8_t curr_ieee_link_id = req->curr_ieee_link_id; 6545 uint8_t new_ieee_link_id = req->new_ieee_link_id; 6546 uint32_t new_primary_freq = req->new_primary_freq; 6547 QDF_STATUS status; 6548 union conc_ext_flag conc_ext_flags; 6549 struct policy_mgr_conc_connection_info 6550 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; 6551 uint8_t num_del = 0; 6552 struct ml_nlink_change_event data; 6553 6554 pm_ctx = policy_mgr_get_context(psoc); 6555 if (!pm_ctx) { 6556 policy_mgr_err("Invalid Context"); 6557 return QDF_STATUS_E_INVAL; 6558 } 6559 6560 policy_mgr_debug("target link %d freq %d curr link %d vdev %d", 6561 new_ieee_link_id, new_primary_freq, 6562 curr_ieee_link_id, vdev_id); 6563 qdf_mem_zero(&data, sizeof(data)); 6564 data.evt.link_switch.curr_ieee_link_id = curr_ieee_link_id; 6565 data.evt.link_switch.new_ieee_link_id = new_ieee_link_id; 6566 data.evt.link_switch.new_primary_freq = new_primary_freq; 6567 status = ml_nlink_conn_change_notify(psoc, vdev_id, 6568 ml_nlink_link_switch_start_evt, 6569 &data); 6570 if (QDF_IS_STATUS_ERROR(status)) 6571 return status; 6572 6573 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 6574 6575 policy_mgr_store_and_del_conn_info_by_vdev_id( 6576 psoc, vdev_id, info, &num_del); 6577 conc_ext_flags.value = 6578 policy_mgr_get_conc_ext_flags(vdev, true); 6579 if (!policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE, 6580 new_primary_freq, 6581 HW_MODE_20_MHZ, 6582 conc_ext_flags.value, 6583 NULL)) { 6584 status = QDF_STATUS_E_INVAL; 6585 policy_mgr_debug("target link %d freq %d not allowed by conc rule", 6586 new_ieee_link_id, new_primary_freq); 6587 } 6588 6589 if (num_del > 0) 6590 policy_mgr_restore_deleted_conn_info(psoc, info, num_del); 6591 6592 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 6593 6594 return status; 6595 } 6596 6597 bool policy_mgr_is_non_ml_sta_present(struct wlan_objmgr_psoc *psoc) 6598 { 6599 uint32_t conn_index = 0; 6600 struct policy_mgr_psoc_priv_obj *pm_ctx; 6601 struct wlan_objmgr_vdev *vdev; 6602 bool non_ml_sta_present = false; 6603 uint8_t vdev_id; 6604 6605 pm_ctx = policy_mgr_get_context(psoc); 6606 if (!pm_ctx) { 6607 policy_mgr_err("Invalid Context"); 6608 return false; 6609 } 6610 6611 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 6612 for (conn_index = 0; 6613 conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 6614 conn_index++) { 6615 if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE || 6616 !pm_conc_connection_list[conn_index].in_use) 6617 continue; 6618 6619 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 6620 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 6621 WLAN_POLICY_MGR_ID); 6622 if (!vdev) 6623 continue; 6624 6625 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) { 6626 non_ml_sta_present = true; 6627 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6628 break; 6629 } 6630 6631 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6632 } 6633 6634 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 6635 return non_ml_sta_present; 6636 } 6637 6638 bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc) 6639 { 6640 uint32_t conn_index = 0; 6641 struct policy_mgr_psoc_priv_obj *pm_ctx; 6642 struct wlan_objmgr_vdev *vdev; 6643 bool mlo_sta_present = false; 6644 uint8_t vdev_id; 6645 6646 pm_ctx = policy_mgr_get_context(psoc); 6647 if (!pm_ctx) { 6648 policy_mgr_err("Invalid Context"); 6649 return false; 6650 } 6651 6652 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 6653 for (conn_index = 0; 6654 conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS && !mlo_sta_present; 6655 conn_index++) { 6656 if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE || 6657 !pm_conc_connection_list[conn_index].in_use) 6658 continue; 6659 6660 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 6661 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 6662 WLAN_POLICY_MGR_ID); 6663 if (!vdev) 6664 continue; 6665 6666 mlo_sta_present = wlan_vdev_mlme_is_mlo_vdev(vdev); 6667 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 6668 } 6669 6670 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 6671 return mlo_sta_present; 6672 } 6673 6674 bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc, 6675 enum policy_mgr_con_mode mode, 6676 uint8_t *mlo_vdev_lst, uint8_t *num_mlo) 6677 { 6678 uint32_t mode_num = 0; 6679 uint8_t i, mlo_idx = 0; 6680 struct wlan_objmgr_vdev *temp_vdev; 6681 qdf_freq_t mlo_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 6682 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 6683 bool is_sbs_link = true; 6684 6685 mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL, 6686 vdev_id_list, mode); 6687 if (!mode_num || mode_num < 2) 6688 return false; 6689 6690 for (i = 0; i < mode_num; i++) { 6691 temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 6692 vdev_id_list[i], 6693 WLAN_POLICY_MGR_ID); 6694 if (!temp_vdev) { 6695 policy_mgr_err("invalid vdev for id %d", 6696 vdev_id_list[i]); 6697 return false; 6698 } 6699 6700 if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) { 6701 if (mlo_vdev_lst) 6702 mlo_vdev_lst[mlo_idx] = vdev_id_list[i]; 6703 mlo_freq_list[mlo_idx] = 6704 wlan_get_operation_chan_freq(temp_vdev); 6705 if (wlan_reg_is_24ghz_ch_freq(mlo_freq_list[mlo_idx])) 6706 is_sbs_link = false; 6707 mlo_idx++; 6708 } 6709 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID); 6710 } 6711 6712 if (num_mlo) 6713 *num_mlo = mlo_idx; 6714 if (mlo_idx < 2) 6715 is_sbs_link = false; 6716 if (is_sbs_link && 6717 !policy_mgr_are_sbs_chan(psoc, mlo_freq_list[0], 6718 mlo_freq_list[1])) { 6719 policy_mgr_debug("Freq %d and %d are not SBS, set SBS false", 6720 mlo_freq_list[0], 6721 mlo_freq_list[1]); 6722 is_sbs_link = false; 6723 } 6724 6725 return is_sbs_link; 6726 } 6727 6728 bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc, 6729 enum policy_mgr_con_mode mode, 6730 uint8_t *mlo_vdev_lst, uint8_t *num_mlo) 6731 { 6732 uint32_t mode_num = 0; 6733 uint8_t i, mlo_idx = 0; 6734 struct wlan_objmgr_vdev *temp_vdev; 6735 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 6736 bool has_2g_link = false; 6737 bool has_5g_link = false; 6738 qdf_freq_t mlo_freq; 6739 6740 mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL, 6741 vdev_id_list, mode); 6742 if (!mode_num || mode_num < 2) 6743 return false; 6744 6745 for (i = 0; i < mode_num; i++) { 6746 temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 6747 psoc, 6748 vdev_id_list[i], 6749 WLAN_POLICY_MGR_ID); 6750 if (!temp_vdev) { 6751 policy_mgr_err("invalid vdev for id %d", 6752 vdev_id_list[i]); 6753 return false; 6754 } 6755 6756 if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) { 6757 if (mlo_vdev_lst) 6758 mlo_vdev_lst[mlo_idx] = vdev_id_list[i]; 6759 mlo_freq = 6760 wlan_get_operation_chan_freq(temp_vdev); 6761 if (wlan_reg_is_24ghz_ch_freq(mlo_freq)) 6762 has_2g_link = true; 6763 else 6764 has_5g_link = true; 6765 mlo_idx++; 6766 } 6767 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID); 6768 } 6769 6770 if (num_mlo) 6771 *num_mlo = mlo_idx; 6772 6773 return has_2g_link && has_5g_link; 6774 } 6775 6776 bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc) 6777 { 6778 struct policy_mgr_hw_mode_params hw_mode; 6779 6780 if (!policy_mgr_is_hw_emlsr_capable(psoc)) 6781 return false; 6782 6783 if (QDF_STATUS_SUCCESS != policy_mgr_get_current_hw_mode(psoc, 6784 &hw_mode)) 6785 return false; 6786 6787 if (!hw_mode.emlsr_cap) 6788 return false; 6789 6790 return true; 6791 } 6792 6793 bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc, 6794 uint8_t *mlo_vdev_lst, uint8_t *num_mlo) 6795 { 6796 bool emlsr_connection = false; 6797 uint32_t mode_num = 0; 6798 uint8_t i, mlo_idx = 0; 6799 struct wlan_objmgr_vdev *temp_vdev; 6800 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 6801 6802 mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL, 6803 vdev_id_list, 6804 PM_STA_MODE); 6805 6806 for (i = 0; i < mode_num; i++) { 6807 temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 6808 psoc, vdev_id_list[i], 6809 WLAN_POLICY_MGR_ID); 6810 if (!temp_vdev) { 6811 policy_mgr_err("invalid vdev for id %d", 6812 vdev_id_list[i]); 6813 goto end; 6814 } 6815 6816 if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) { 6817 if (mlo_vdev_lst) 6818 mlo_vdev_lst[mlo_idx] = vdev_id_list[i]; 6819 mlo_idx++; 6820 } 6821 /* Check if existing vdev is eMLSR STA */ 6822 if (wlan_vdev_mlme_cap_get(temp_vdev, WLAN_VDEV_C_EMLSR_CAP)) 6823 emlsr_connection = true; 6824 6825 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID); 6826 } 6827 end: 6828 if (num_mlo) 6829 *num_mlo = mlo_idx; 6830 6831 return emlsr_connection; 6832 } 6833 6834 void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc, 6835 bool conc_con_coming_up, 6836 bool emlsr_sta_coming_up) 6837 { 6838 uint8_t num_mlo = 0; 6839 uint8_t mlo_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 6840 bool is_mlo_emlsr = false; 6841 uint8_t num_disabled_ml_sta = 0; 6842 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 6843 struct policy_mgr_psoc_priv_obj *pm_ctx; 6844 6845 pm_ctx = policy_mgr_get_context(psoc); 6846 if (!pm_ctx) { 6847 policy_mgr_err("Invalid Context"); 6848 return; 6849 } 6850 6851 is_mlo_emlsr = policy_mgr_is_mlo_in_mode_emlsr(psoc, mlo_vdev_lst, 6852 &num_mlo); 6853 policy_mgr_debug("num_mlo %d is_mlo_emlsr %d conc_con_coming_up: %d", 6854 num_mlo, is_mlo_emlsr, conc_con_coming_up); 6855 6856 if (!is_mlo_emlsr) 6857 return; 6858 6859 if (num_mlo < 2) { 6860 policy_mgr_debug("conc_con_coming_up %d num mlo sta links %d", 6861 conc_con_coming_up, num_mlo); 6862 policy_mgr_get_ml_sta_info(pm_ctx, &num_mlo, 6863 &num_disabled_ml_sta, 6864 mlo_vdev_lst, ml_freq_lst, 6865 NULL, NULL, NULL); 6866 if (policy_mgr_get_connection_count(psoc) != 1 || 6867 !num_disabled_ml_sta) 6868 return; 6869 } 6870 6871 if (conc_con_coming_up || 6872 (emlsr_sta_coming_up && 6873 policy_mgr_get_connection_count(psoc) > 2)) { 6874 /* 6875 * Force disable one of the links (FW will decide which link) if 6876 * 1) EMLSR STA is present and SAP/STA/NAN connection comes up. 6877 * 2) There is a legacy connection (SAP/P2P/NAN) and a STA comes 6878 * up in EMLSR mode. 6879 */ 6880 policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT, 6881 MLO_LINK_FORCE_MODE_INACTIVE_NUM, 6882 num_mlo, mlo_vdev_lst); 6883 return; 6884 } 6885 6886 if (!conc_con_coming_up && emlsr_sta_coming_up) 6887 /* 6888 * No force i.e. Re-enable the disabled link if- 6889 * 1) EMLSR STA is present and new SAP/STA/NAN connection goes 6890 * down. One of the links was disabled while a new connection 6891 * came up. 6892 * 2) Legacy connection (SAP/P2P/NAN) goes down and if STA is 6893 * EMLSR capable. One of the links was disabled after EMLSR 6894 * association. 6895 */ 6896 policy_mgr_mlo_sta_set_link(psoc, 6897 MLO_LINK_FORCE_REASON_DISCONNECT, 6898 MLO_LINK_FORCE_MODE_NO_FORCE, 6899 num_mlo, mlo_vdev_lst); 6900 } 6901 6902 bool 6903 policy_mgr_is_emlsr_sta_concurrency_present(struct wlan_objmgr_psoc *psoc) 6904 { 6905 uint8_t num_mlo = 0; 6906 6907 if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, &num_mlo) && 6908 num_mlo < policy_mgr_get_connection_count(psoc)) 6909 return true; 6910 6911 return false; 6912 } 6913 6914 static uint8_t 6915 policy_mgr_get_affected_links_for_sta_sta(struct wlan_objmgr_psoc *psoc, 6916 uint8_t num_ml, qdf_freq_t *freq_list, 6917 uint8_t *vdev_id_list, 6918 uint8_t *ml_vdev_lst, 6919 uint8_t *ml_idx, qdf_freq_t freq) 6920 { 6921 uint8_t i = 0; 6922 bool same_band_sta_allowed; 6923 6924 /* 6925 * STA freq: ML STA combo: SBS Action 6926 * --------------------------------------------------- 6927 * 2Ghz 2Ghz+5/6Ghz Disable 2Ghz(Same MAC) 6928 * 5Ghz 2Ghz+5/6Ghz Disable 2.4Ghz if 5Ghz lead to SBS 6929 * (SBS, same MAC) and same band STA 6930 * allowed, else disable 5/6Ghz 6931 * (NON SBS, same MAC) 6932 * 5Ghz(lower) 5Ghz+6Ghz Disable 5Ghz (NON SBS, same MAC) 6933 * 5Ghz(higher) 5Ghz+6Ghz Disable 6Ghz (NON SBS, Same MAC) 6934 * 2Ghz 5Ghz+6Ghz Disable Any 6935 */ 6936 6937 /* If non-ML STA is 2.4Ghz disable 2.4Ghz if present OR disable any */ 6938 if (wlan_reg_is_24ghz_ch_freq(freq)) { 6939 while (i < num_ml) { 6940 if (wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) { 6941 /* Affected ML STA link on 2.4Ghz */ 6942 ml_vdev_lst[0] = vdev_id_list[ml_idx[i]]; 6943 return 1; 6944 } 6945 /* Fill non effected vdev in list */ 6946 ml_vdev_lst[i] = vdev_id_list[ml_idx[i]]; 6947 i++; 6948 } 6949 /* No link affected return num_ml to disable any */ 6950 return i; 6951 } 6952 6953 /* This mean non-ML STA is 5Ghz */ 6954 6955 /* check if ML STA is DBS */ 6956 i = 0; 6957 while (i < num_ml && 6958 !wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) 6959 i++; 6960 6961 same_band_sta_allowed = wlan_cm_same_band_sta_allowed(psoc); 6962 6963 /* 6964 * if ML STA is DBS ie 2.4Ghz link present and if same_band_sta_allowed 6965 * is false, disable 5/6Ghz link to make sure we dont have all link 6966 * on 5Ghz 6967 */ 6968 if (i < num_ml && !same_band_sta_allowed) 6969 goto check_dbs_ml; 6970 6971 /* check if any link lead to SBS, so that we can disable the other*/ 6972 i = 0; 6973 while (i < num_ml && 6974 !policy_mgr_are_sbs_chan(psoc, freq, freq_list[ml_idx[i]])) 6975 i++; 6976 6977 /* 6978 * if i < num_ml then i is the SBS link, in this case disable the other 6979 * non SBS link, this mean ML STA is 5+6 or 2+5/6. 6980 */ 6981 if (i < num_ml) { 6982 i = 0; 6983 while (i < num_ml) { 6984 if (!policy_mgr_are_sbs_chan(psoc, freq, 6985 freq_list[ml_idx[i]])) { 6986 /* Affected non SBS ML STA link */ 6987 ml_vdev_lst[0] = vdev_id_list[ml_idx[i]]; 6988 return 1; 6989 } 6990 /* Fill non effected vdev in list */ 6991 ml_vdev_lst[i] = vdev_id_list[ml_idx[i]]; 6992 i++; 6993 } 6994 /* All link lead to SBS, disable any, This should not happen */ 6995 return i; 6996 } 6997 6998 check_dbs_ml: 6999 /* 7000 * None of the link can lead to SBS, i.e. its 2+ 5/6 ML STA in this case 7001 * disable 5Ghz link. 7002 */ 7003 i = 0; 7004 while (i < num_ml) { 7005 if (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) { 7006 /* Affected 5/6Ghz ML STA link */ 7007 ml_vdev_lst[0] = vdev_id_list[ml_idx[i]]; 7008 return 1; 7009 } 7010 /* Fill non effected vdev in list */ 7011 ml_vdev_lst[i] = vdev_id_list[ml_idx[i]]; 7012 i++; 7013 } 7014 7015 /* No link affected, This should not happen */ 7016 return i; 7017 } 7018 7019 /* 7020 * policy_mgr_get_concurrent_num_links() - get links which are affected 7021 * if no affected then return num ml. Also fills the ml_vdev_lst to send. 7022 * @num_ml: number of ML vdev 7023 * @freq_list: freq list of all vdev 7024 * @vdev_id_list: vdev id list 7025 * @ml_vdev_lst: ML vdev list 7026 * @ml_idx: ML index 7027 * @freq: non ML STA freq 7028 * 7029 * Return: number of the affected links, else total link and ml_vdev_lst list. 7030 */ 7031 static uint8_t 7032 policy_mgr_get_concurrent_num_links(struct wlan_objmgr_vdev *vdev, 7033 uint8_t num_ml, qdf_freq_t *freq_list, 7034 uint8_t *vdev_id_list, 7035 uint8_t *ml_vdev_lst, 7036 uint8_t *ml_idx, qdf_freq_t freq) 7037 { 7038 uint8_t i = 0; 7039 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 7040 7041 if (!psoc) 7042 return 0; 7043 7044 while (i < num_ml && (freq_list[ml_idx[i]] != freq)) 7045 i++; 7046 7047 if (i < num_ml) { 7048 /* if one link is SCC then no need to disable any link */ 7049 policy_mgr_debug("vdev %d: ML vdev %d lead to SCC, STA freq %d ML freq %d, no need to disable link", 7050 wlan_vdev_get_id(vdev), 7051 vdev_id_list[ml_idx[i]], 7052 freq, freq_list[ml_idx[i]]); 7053 return 0; 7054 } 7055 7056 7057 return policy_mgr_get_affected_links_for_sta_sta(psoc, num_ml, 7058 freq_list, 7059 vdev_id_list, 7060 ml_vdev_lst, 7061 ml_idx, freq); 7062 } 7063 7064 static void 7065 policy_mgr_ml_sta_concurrency_on_connect(struct wlan_objmgr_psoc *psoc, 7066 struct wlan_objmgr_vdev *vdev, 7067 uint8_t num_ml, uint8_t *ml_idx, 7068 uint8_t num_non_ml, uint8_t *non_ml_idx, 7069 qdf_freq_t *freq_list, 7070 uint8_t *vdev_id_list) 7071 { 7072 qdf_freq_t freq = 0; 7073 struct wlan_channel *bss_chan; 7074 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7075 uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7076 uint8_t affected_links = 0; 7077 enum mlo_link_force_mode mode = MLO_LINK_FORCE_MODE_ACTIVE_NUM; 7078 7079 /* non ML STA doesn't exist, no need to change to link.*/ 7080 if (!num_non_ml) 7081 return; 7082 7083 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) { 7084 freq = freq_list[non_ml_idx[0]]; 7085 } else { 7086 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 7087 if (bss_chan) 7088 freq = bss_chan->ch_freq; 7089 } 7090 policy_mgr_debug("vdev %d: Freq %d (non ML vdev id %d), is ML STA %d", 7091 vdev_id, freq, vdev_id_list[non_ml_idx[0]], 7092 wlan_vdev_mlme_is_mlo_vdev(vdev)); 7093 if (!freq) 7094 return; 7095 7096 affected_links = 7097 policy_mgr_get_concurrent_num_links(vdev, num_ml, freq_list, 7098 vdev_id_list, ml_vdev_lst, 7099 ml_idx, freq); 7100 7101 if (!affected_links) { 7102 policy_mgr_debug("vdev %d: no affected link found", vdev_id); 7103 return; 7104 } 7105 policy_mgr_debug("affected link found: %u vdev_id: %u", 7106 affected_links, ml_vdev_lst[0]); 7107 7108 /* 7109 * If affected link is less than num_ml, ie not all link are affected, 7110 * send MLO_LINK_FORCE_MODE_INACTIVE. 7111 */ 7112 if (affected_links < num_ml && 7113 affected_links <= MAX_NUMBER_OF_CONC_CONNECTIONS) { 7114 if (mlo_is_sta_inactivity_allowed_with_quiet(psoc, vdev_id_list, 7115 num_ml, ml_idx, 7116 affected_links, 7117 ml_vdev_lst)) { 7118 mode = MLO_LINK_FORCE_MODE_INACTIVE; 7119 } else { 7120 policy_mgr_debug("vdev %d: force inactivity is not allowed", 7121 ml_vdev_lst[0]); 7122 return; 7123 } 7124 } 7125 7126 policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT, 7127 mode, affected_links, ml_vdev_lst); 7128 } 7129 7130 static void 7131 policy_mgr_get_disabled_ml_sta_idx(struct wlan_objmgr_psoc *psoc, 7132 uint8_t *ml_sta, 7133 uint8_t *ml_idx, 7134 qdf_freq_t *freq_list, 7135 uint8_t *vdev_id_list, uint8_t next_idx) 7136 { 7137 uint8_t conn_index, fill_index = next_idx; 7138 struct policy_mgr_psoc_priv_obj *pm_ctx; 7139 7140 pm_ctx = policy_mgr_get_context(psoc); 7141 if (!pm_ctx) { 7142 policy_mgr_err("Invalid Context"); 7143 return; 7144 } 7145 7146 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 7147 /* Get disabled link info as well and keep it at last */ 7148 for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK; 7149 conn_index++) { 7150 if (!pm_disabled_ml_links[conn_index].in_use) 7151 continue; 7152 if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE) 7153 continue; 7154 if ((fill_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) || 7155 (*ml_sta >= MAX_NUMBER_OF_CONC_CONNECTIONS)) { 7156 policy_mgr_err("Invalid fill_index: %d or ml_sta: %d", 7157 fill_index, *ml_sta); 7158 break; 7159 } 7160 vdev_id_list[fill_index] = 7161 pm_disabled_ml_links[conn_index].vdev_id; 7162 freq_list[fill_index] = pm_disabled_ml_links[conn_index].freq; 7163 ml_idx[(*ml_sta)++] = fill_index++; 7164 } 7165 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 7166 } 7167 7168 /** 7169 * policy_mgr_handle_ml_sta_link_concurrency() - Handle STA+ML_STA concurrency 7170 * @psoc: PSOC object information 7171 * @vdev: vdev of the changed interface caller 7172 * 7173 * Return: void 7174 */ 7175 static QDF_STATUS 7176 policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc, 7177 struct wlan_objmgr_vdev *vdev) 7178 { 7179 uint8_t num_ml = 0, num_non_ml = 0, next_idx, disabled_links; 7180 uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7181 uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7182 qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7183 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7184 struct policy_mgr_psoc_priv_obj *pm_ctx; 7185 7186 pm_ctx = policy_mgr_get_context(psoc); 7187 if (!pm_ctx) { 7188 policy_mgr_err("Invalid Context"); 7189 return QDF_STATUS_E_INVAL; 7190 } 7191 7192 /* Skip non STA connection handling */ 7193 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 7194 return QDF_STATUS_E_INVAL; 7195 7196 /* 7197 * Skip this in case of SAP/P2P Concurrencies, to avoid renable of 7198 * the link, disabled by SAP/P2P logic, as this API only consider 7199 * STA specific counts and ignore other counts. 7200 */ 7201 if (policy_mgr_get_beaconing_mode_count(psoc, NULL) || 7202 policy_mgr_mode_specific_connection_count(psoc, 7203 PM_P2P_CLIENT_MODE, 7204 NULL)) { 7205 policy_mgr_debug("SAP/GO/CLI exist ignore this check"); 7206 return QDF_STATUS_E_INVAL; 7207 } 7208 7209 policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx, 7210 &num_non_ml, non_ml_idx, 7211 freq_list, vdev_id_list); 7212 /* Skip non STA+STA cases */ 7213 if (!num_ml || !num_non_ml) 7214 return QDF_STATUS_E_INVAL; 7215 7216 next_idx = num_ml + num_non_ml; 7217 policy_mgr_get_disabled_ml_sta_idx(psoc, &num_ml, ml_idx, 7218 freq_list, vdev_id_list, next_idx); 7219 7220 disabled_links = num_ml - (next_idx - num_non_ml); 7221 policy_mgr_debug("vdev %d: num_ml %d num_non_ml %d disabled_links: %d", 7222 wlan_vdev_get_id(vdev), num_ml, num_non_ml, 7223 disabled_links); 7224 7225 /* ML STA is not up or not sufficient links to disable */ 7226 if (num_ml < 2 || num_ml > MAX_NUMBER_OF_CONC_CONNECTIONS || 7227 num_ml - disabled_links < 2) { 7228 policy_mgr_debug("ML STA is not up or not sufficient links to disable"); 7229 return QDF_STATUS_E_INVAL; 7230 } 7231 /* 7232 * TODO: Check if both link enable/ link switch is possible when 7233 * secondary STA switch happens to a new channel due to CSA 7234 */ 7235 7236 policy_mgr_ml_sta_concurrency_on_connect(psoc, vdev, num_ml, 7237 ml_idx, num_non_ml, 7238 non_ml_idx, freq_list, 7239 vdev_id_list); 7240 return QDF_STATUS_SUCCESS; 7241 } 7242 7243 static bool 7244 policy_mgr_is_mode_p2p_sap(enum policy_mgr_con_mode mode) 7245 { 7246 return (policy_mgr_is_beaconing_mode(mode) || 7247 (mode == PM_P2P_CLIENT_MODE)); 7248 } 7249 7250 bool 7251 policy_mgr_is_vdev_high_tput_or_low_latency(struct wlan_objmgr_psoc *psoc, 7252 uint8_t vdev_id) 7253 { 7254 struct wlan_objmgr_vdev *vdev; 7255 bool is_vdev_ll_ht; 7256 7257 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 7258 WLAN_POLICY_MGR_ID); 7259 if (!vdev) { 7260 policy_mgr_err("invalid vdev for id %d", vdev_id); 7261 return false; 7262 } 7263 is_vdev_ll_ht = wlan_is_vdev_traffic_ll_ht(vdev); 7264 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 7265 7266 return is_vdev_ll_ht; 7267 } 7268 7269 bool 7270 policy_mgr_check_2ghz_only_sap_affected_link( 7271 struct wlan_objmgr_psoc *psoc, 7272 uint8_t sap_vdev_id, 7273 qdf_freq_t sap_ch_freq, 7274 uint8_t ml_ch_freq_num, 7275 qdf_freq_t *ml_freq_lst) 7276 { 7277 uint8_t i; 7278 struct policy_mgr_psoc_priv_obj *pm_ctx; 7279 struct wlan_objmgr_vdev *vdev; 7280 enum QDF_OPMODE op_mode; 7281 7282 pm_ctx = policy_mgr_get_context(psoc); 7283 if (!pm_ctx) { 7284 policy_mgr_err("Invalid Context"); 7285 return false; 7286 } 7287 7288 if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq)) 7289 return false; 7290 7291 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 7292 psoc, sap_vdev_id, 7293 WLAN_POLICY_MGR_ID); 7294 if (!vdev) { 7295 policy_mgr_debug("vdev is null %d", sap_vdev_id); 7296 return false; 7297 } 7298 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7299 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 7300 if (op_mode != QDF_SAP_MODE) 7301 return false; 7302 7303 if (!policy_mgr_is_acs_2ghz_only_sap(psoc, sap_vdev_id)) 7304 return false; 7305 7306 /* If 2G ml STA exist, force scc will happen, no link 7307 * to get affected. 7308 */ 7309 for (i = 0; i < ml_ch_freq_num; i++) 7310 if (WLAN_REG_IS_24GHZ_CH_FREQ(ml_freq_lst[i])) 7311 return false; 7312 7313 /* If All ml STA are 5/6 band, force SCC will not happen 7314 * for 2G only SAP, so return true to indicate one 7315 * link get affected. 7316 */ 7317 return true; 7318 } 7319 7320 /* 7321 * policy_mgr_get_affected_links_for_go_sap_cli() - Check if any of the P2P OR 7322 * SAP is causing MCC with a ML link and also is configured high tput or low 7323 * latency 7324 * @psoc: psoc ctx 7325 * @num_ml_sta: Number of ML STA present 7326 * @ml_vdev_lst: ML STA vdev id list 7327 * @ml_freq_lst: ML STA freq list 7328 * @num_p2p_sap: Number of P2P and SAP present 7329 * @p2p_sap_vdev_lst: P2P and SAP vdev id list 7330 * @p2p_sap_freq_lst: P2P and SAP freq list 7331 * 7332 * Return: Number of links causing MCC with any of the P2P or SAP which is 7333 * configured high tput or low latency 7334 */ 7335 static uint8_t 7336 policy_mgr_get_affected_links_for_go_sap_cli(struct wlan_objmgr_psoc *psoc, 7337 uint8_t num_ml_sta, 7338 uint8_t *ml_vdev_lst, 7339 qdf_freq_t *ml_freq_lst, 7340 uint8_t num_p2p_sap, 7341 uint8_t *p2p_sap_vdev_lst, 7342 qdf_freq_t *p2p_sap_freq_lst) 7343 { 7344 uint8_t i = 0, k = 0, num_affected_links = 0; 7345 7346 if (!num_p2p_sap || num_ml_sta < 2) 7347 return num_affected_links; 7348 7349 while (i < num_ml_sta) { 7350 /* if any link is causing MCC with GO/GC/AP, set mcc as true.*/ 7351 for (k = 0; k < num_p2p_sap; k++) { 7352 /* Continue if SCC */ 7353 if (ml_freq_lst[i] == p2p_sap_freq_lst[k]) 7354 continue; 7355 7356 /* SAP MCC with MLO STA link is not preferred. 7357 * If SAP is 2Ghz only by ACS and two ML link are 7358 * 5/6 band, then force SCC may not happen. In such 7359 * case inactive one link. 7360 */ 7361 if (policy_mgr_check_2ghz_only_sap_affected_link( 7362 psoc, p2p_sap_vdev_lst[k], 7363 p2p_sap_freq_lst[k], 7364 num_ml_sta, ml_freq_lst)) { 7365 policy_mgr_debug("2G only SAP vdev %d ch freq %d is not SCC with any MLO STA link", 7366 p2p_sap_vdev_lst[k], 7367 p2p_sap_freq_lst[k]); 7368 num_affected_links++; 7369 continue; 7370 } 7371 7372 /* Continue if high tput or low latency is not set */ 7373 if (!policy_mgr_is_vdev_high_tput_or_low_latency( 7374 psoc, p2p_sap_vdev_lst[k])) 7375 continue; 7376 7377 /* If both freq are on same mac then its MCC */ 7378 if (policy_mgr_are_2_freq_on_same_mac(psoc, 7379 ml_freq_lst[i], 7380 p2p_sap_freq_lst[k])) { 7381 policy_mgr_debug("ml sta vdev %d (freq %d) and p2p/sap vdev %d (freq %d) are MCC", 7382 ml_vdev_lst[i], ml_freq_lst[i], 7383 p2p_sap_vdev_lst[k], 7384 p2p_sap_freq_lst[k]); 7385 num_affected_links++; 7386 } 7387 } 7388 i++; 7389 } 7390 7391 return num_affected_links; 7392 } 7393 7394 /* 7395 * policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info() - Get number of ML STA, 7396 * P2P and SAP interfaces and their vdev ids and freq list 7397 * @pm_ctx: pm_ctx ctx 7398 * @num_ml_sta: Return number of ML STA present 7399 * @num_disabled_ml_sta: Return number of disabled ML STA links 7400 * @ml_vdev_lst: Return ML STA vdev id list 7401 * @ml_freq_lst: Return ML STA freq list 7402 * @num_p2p_sap: Return number of P2P and SAP present 7403 * @p2p_sap_vdev_lst: Return P2P and SAP vdev id list 7404 * @p2p_sap_freq_lst: Return P2P and SAP freq list 7405 * 7406 * Return: void 7407 */ 7408 static void 7409 policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info( 7410 struct policy_mgr_psoc_priv_obj *pm_ctx, 7411 uint8_t *num_ml_sta, 7412 uint8_t *num_disabled_ml_sta, 7413 uint8_t *ml_vdev_lst, 7414 qdf_freq_t *ml_freq_lst, 7415 uint8_t *num_p2p_sap, 7416 uint8_t *p2p_sap_vdev_lst, 7417 qdf_freq_t *p2p_sap_freq_lst) 7418 { 7419 enum policy_mgr_con_mode mode; 7420 uint8_t vdev_id, conn_index; 7421 qdf_freq_t freq; 7422 7423 *num_p2p_sap = 0; 7424 7425 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 7426 policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, num_disabled_ml_sta, 7427 ml_vdev_lst, ml_freq_lst, NULL, NULL, NULL); 7428 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 7429 conn_index++) { 7430 if (!pm_conc_connection_list[conn_index].in_use) 7431 continue; 7432 mode = pm_conc_connection_list[conn_index].mode; 7433 if (!policy_mgr_is_mode_p2p_sap(mode)) 7434 continue; 7435 vdev_id = pm_conc_connection_list[conn_index].vdev_id; 7436 freq = pm_conc_connection_list[conn_index].freq; 7437 7438 /* add p2p and sap vdev and freq list */ 7439 p2p_sap_vdev_lst[*num_p2p_sap] = vdev_id; 7440 p2p_sap_freq_lst[(*num_p2p_sap)++] = freq; 7441 } 7442 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 7443 } 7444 7445 /* 7446 * policy_mgr_is_ml_sta_links_in_mcc() - Check ML links are in MCC or not 7447 * @psoc: psoc ctx 7448 * @ml_freq_lst: ML STA freq list 7449 * @ml_vdev_lst: ML STA vdev id list 7450 * @ml_linkid_lst: ML STA link id list 7451 * @num_ml_sta: Number of total ML STA links 7452 * @affected_linkid_bitmap: link id bitmap which home channels are in MCC 7453 * with each other 7454 * 7455 * Return: true if ML link in MCC else false 7456 */ 7457 bool 7458 policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc, 7459 qdf_freq_t *ml_freq_lst, 7460 uint8_t *ml_vdev_lst, 7461 uint8_t *ml_linkid_lst, 7462 uint8_t num_ml_sta, 7463 uint32_t *affected_linkid_bitmap) 7464 { 7465 uint8_t i, j; 7466 uint32_t link_id_bitmap; 7467 7468 for (i = 0; i < num_ml_sta; i++) { 7469 link_id_bitmap = 0; 7470 if (ml_linkid_lst) 7471 link_id_bitmap = 1 << ml_linkid_lst[i]; 7472 for (j = i + 1; j < num_ml_sta; j++) { 7473 if (ml_freq_lst[i] != ml_freq_lst[j] && 7474 policy_mgr_2_freq_always_on_same_mac( 7475 psoc, ml_freq_lst[i], ml_freq_lst[j])) { 7476 if (ml_vdev_lst) 7477 policy_mgr_debug("vdev %d and %d are in MCC with freq %d and freq %d", 7478 ml_vdev_lst[i], 7479 ml_vdev_lst[j], 7480 ml_freq_lst[i], 7481 ml_freq_lst[j]); 7482 if (ml_linkid_lst) { 7483 link_id_bitmap |= 1 << ml_linkid_lst[j]; 7484 policy_mgr_debug("link %d and %d are in MCC with freq %d and freq %d", 7485 ml_linkid_lst[i], 7486 ml_linkid_lst[j], 7487 ml_freq_lst[i], 7488 ml_freq_lst[j]); 7489 if (affected_linkid_bitmap) 7490 *affected_linkid_bitmap = 7491 link_id_bitmap; 7492 } 7493 return true; 7494 } 7495 } 7496 } 7497 7498 return false; 7499 } 7500 7501 /* 7502 * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC 7503 * DBS - if ML STA links on 5 GHz + 6 GHz 7504 * SBS - if both ML STA links on 5 GHz high/5 GHz low 7505 * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz) 7506 * @psoc: psoc ctx 7507 * 7508 * Return: Success if MCC link is disabled else failure 7509 */ 7510 static QDF_STATUS 7511 policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc, 7512 struct wlan_objmgr_vdev *vdev) 7513 { 7514 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0; 7515 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7516 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7517 struct policy_mgr_psoc_priv_obj *pm_ctx; 7518 7519 if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)) 7520 return QDF_STATUS_E_FAILURE; 7521 7522 pm_ctx = policy_mgr_get_context(psoc); 7523 if (!pm_ctx) { 7524 policy_mgr_err("Invalid Context"); 7525 return QDF_STATUS_E_FAILURE; 7526 } 7527 7528 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 7529 ml_sta_vdev_lst, ml_freq_lst, 7530 NULL, NULL, NULL); 7531 if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 7532 num_disabled_ml_sta) { 7533 policy_mgr_debug("num_ml_sta invalid %d or link already disabled%d", 7534 num_ml_sta, num_disabled_ml_sta); 7535 return QDF_STATUS_E_FAILURE; 7536 } 7537 7538 if (!policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst, 7539 ml_sta_vdev_lst, NULL, 7540 num_ml_sta, 7541 NULL)) 7542 return QDF_STATUS_E_FAILURE; 7543 7544 /* 7545 * eMLSR is allowed in MCC mode also. So, don't disable any links 7546 * if current connection happens in eMLSR mode. 7547 */ 7548 if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) { 7549 policy_mgr_debug("Don't disable eMLSR links"); 7550 return QDF_STATUS_E_FAILURE; 7551 } 7552 7553 policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT, 7554 MLO_LINK_FORCE_MODE_ACTIVE_NUM, 7555 num_ml_sta, ml_sta_vdev_lst); 7556 return QDF_STATUS_SUCCESS; 7557 } 7558 7559 /* 7560 * policy_mgr_sta_ml_link_enable_allowed() - Check with given ML links and 7561 * existing concurrencies, a disabled ml link can be enabled back. 7562 * @psoc: psoc ctx 7563 * @num_disabled_ml_sta: Number of existing disabled links 7564 * @num_ml_sta: Number of total ML STA links 7565 * @ml_freq_lst: ML STA freq list 7566 * @ml_vdev_lst: ML STA vdev id list 7567 * 7568 * Return: if link can be enabled or not 7569 */ 7570 static bool 7571 policy_mgr_sta_ml_link_enable_allowed(struct wlan_objmgr_psoc *psoc, 7572 uint8_t num_disabled_ml_sta, 7573 uint8_t num_ml_sta, 7574 qdf_freq_t *ml_freq_lst, 7575 uint8_t *ml_vdev_lst) 7576 { 7577 union conc_ext_flag conc_ext_flags; 7578 uint8_t disabled_link_vdev_id; 7579 qdf_freq_t disabled_link_freq; 7580 struct wlan_objmgr_vdev *vdev; 7581 7582 /* If no link is disabled nothing to do */ 7583 if (!num_disabled_ml_sta || num_ml_sta < 2) 7584 return false; 7585 if (policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst, ml_vdev_lst, 7586 NULL, num_ml_sta, 7587 NULL)) 7588 return false; 7589 /* Disabled link is at the last index */ 7590 disabled_link_vdev_id = ml_vdev_lst[num_ml_sta - 1]; 7591 disabled_link_freq = ml_freq_lst[num_ml_sta - 1]; 7592 policy_mgr_debug("disabled_link_vdev_id %d disabled_link_freq %d", 7593 disabled_link_vdev_id, disabled_link_freq); 7594 if (!disabled_link_freq) 7595 return false; 7596 7597 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, disabled_link_vdev_id, 7598 WLAN_POLICY_MGR_ID); 7599 if (!vdev) { 7600 policy_mgr_err("invalid vdev for id %d", disabled_link_vdev_id); 7601 return false; 7602 } 7603 conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false); 7604 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 7605 7606 return policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE, 7607 disabled_link_freq, HW_MODE_20_MHZ, 7608 conc_ext_flags.value, NULL); 7609 } 7610 7611 /* 7612 * policy_mgr_re_enable_ml_sta_on_p2p_sap_down() - Handle enable 7613 * link on P2P/SAP/ML_STA vdev UP or channel change 7614 * @psoc: objmgr psoc 7615 * @vdev: vdev which went UP or changed chan 7616 * 7617 * Return: void 7618 */ 7619 static void 7620 policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc *psoc, 7621 struct wlan_objmgr_vdev *vdev) 7622 { 7623 uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0; 7624 uint8_t num_affected_link; 7625 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7626 uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7627 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7628 qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7629 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7630 struct policy_mgr_psoc_priv_obj *pm_ctx; 7631 QDF_STATUS status; 7632 7633 pm_ctx = policy_mgr_get_context(psoc); 7634 if (!pm_ctx) { 7635 policy_mgr_err("Invalid Context"); 7636 return; 7637 } 7638 7639 status = policy_mgr_handle_ml_sta_link_state_allowed( 7640 psoc, MLO_LINK_FORCE_REASON_CONNECT); 7641 if (QDF_IS_STATUS_ERROR(status)) 7642 return; 7643 7644 /* 7645 * eMLSR API policy_mgr_handle_emlsr_sta_concurrency() takes care of 7646 * eMLSR concurrencies. Currently, eMLSR STA can't operate with any 7647 * cocurrent mode, i.e. one link gets force-disabled when a new 7648 * concurrecy is coming up. 7649 */ 7650 if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) { 7651 policy_mgr_debug("STA connected in eMLSR mode, don't enable/disable links"); 7652 return; 7653 } 7654 7655 if (QDF_IS_STATUS_SUCCESS(policy_mgr_handle_mcc_ml_sta(psoc, vdev))) 7656 return; 7657 7658 status = policy_mgr_handle_ml_sta_link_concurrency(psoc, vdev); 7659 if (QDF_IS_STATUS_SUCCESS(status)) 7660 return; 7661 7662 policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta, 7663 &num_disabled_ml_sta, 7664 ml_sta_vdev_lst, 7665 ml_freq_lst, &num_p2p_sap, 7666 p2p_sap_vdev_lst, 7667 p2p_sap_freq_lst); 7668 7669 policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d", 7670 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap); 7671 if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 7672 num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS) 7673 return; 7674 7675 num_affected_link = policy_mgr_get_affected_links_for_go_sap_cli(psoc, 7676 num_ml_sta, ml_sta_vdev_lst, 7677 ml_freq_lst, num_p2p_sap, 7678 p2p_sap_vdev_lst, 7679 p2p_sap_freq_lst); 7680 7681 if (!num_affected_link) { 7682 policy_mgr_debug("vdev %d: no affected link found", vdev_id); 7683 goto enable_link; 7684 } 7685 7686 if (num_disabled_ml_sta) { 7687 policy_mgr_debug("As a link is already disabled and affected link present (%d), No action required", 7688 num_affected_link); 7689 return; 7690 } 7691 7692 policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT, 7693 MLO_LINK_FORCE_MODE_ACTIVE_NUM, 7694 num_ml_sta, ml_sta_vdev_lst); 7695 7696 return; 7697 enable_link: 7698 7699 /* 7700 * if no affected link and link can be allowed to enable then renable 7701 * the disabled link. 7702 */ 7703 if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta, 7704 num_ml_sta, ml_freq_lst, 7705 ml_sta_vdev_lst)) 7706 policy_mgr_mlo_sta_set_link(psoc, 7707 MLO_LINK_FORCE_REASON_DISCONNECT, 7708 MLO_LINK_FORCE_MODE_NO_FORCE, 7709 num_ml_sta, ml_sta_vdev_lst); 7710 } 7711 7712 void 7713 policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc *psoc, 7714 enum QDF_OPMODE mode, 7715 uint8_t vdev_id) 7716 { 7717 struct wlan_objmgr_vdev *vdev; 7718 7719 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 7720 WLAN_POLICY_MGR_ID); 7721 if (!vdev) { 7722 policy_mgr_err("vdev %d: invalid vdev", vdev_id); 7723 return; 7724 } 7725 7726 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE || 7727 mode == QDF_P2P_CLIENT_MODE || mode == QDF_P2P_GO_MODE) 7728 policy_mgr_handle_sap_cli_go_ml_sta_up_csa(psoc, vdev); 7729 7730 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 7731 } 7732 7733 #define SET_LINK_TIMEOUT 6000 7734 QDF_STATUS policy_mgr_wait_for_set_link_update(struct wlan_objmgr_psoc *psoc) 7735 { 7736 struct policy_mgr_psoc_priv_obj *pm_ctx; 7737 QDF_STATUS status; 7738 7739 pm_ctx = policy_mgr_get_context(psoc); 7740 if (!pm_ctx) { 7741 policy_mgr_err("Invalid Context"); 7742 return QDF_STATUS_E_INVAL; 7743 } 7744 7745 if (!policy_mgr_get_link_in_progress(pm_ctx)) { 7746 policy_mgr_err("link is not in progress"); 7747 return QDF_STATUS_E_FAILURE; 7748 } 7749 7750 status = 7751 qdf_wait_for_event_completion(&pm_ctx->set_link_update_done_evt, 7752 SET_LINK_TIMEOUT); 7753 7754 if (QDF_IS_STATUS_ERROR(status)) { 7755 policy_mgr_set_link_in_progress(pm_ctx, false); 7756 policy_mgr_err("wait for set_link_in_progress failed"); 7757 } 7758 7759 return status; 7760 } 7761 7762 void policy_mgr_handle_ml_sta_link_on_traffic_type_change( 7763 struct wlan_objmgr_psoc *psoc, 7764 struct wlan_objmgr_vdev *vdev) 7765 { 7766 /* Check if any set link is already progress and thus wait */ 7767 policy_mgr_wait_for_set_link_update(psoc); 7768 7769 ml_nlink_conn_change_notify( 7770 psoc, wlan_vdev_get_id(vdev), 7771 ml_nlink_connection_updated_evt, NULL); 7772 7773 /* 7774 * Check if traffic type change lead to set link is progress and 7775 * thus wait for it to complete. 7776 */ 7777 policy_mgr_wait_for_set_link_update(psoc); 7778 } 7779 7780 static QDF_STATUS 7781 policy_mgr_handle_ml_sta_link_enable_on_sta_down(struct wlan_objmgr_psoc *psoc, 7782 struct wlan_objmgr_vdev *vdev) 7783 { 7784 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0; 7785 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7786 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7787 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7788 struct policy_mgr_psoc_priv_obj *pm_ctx; 7789 7790 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 7791 return QDF_STATUS_E_INVAL; 7792 7793 pm_ctx = policy_mgr_get_context(psoc); 7794 if (!pm_ctx) { 7795 policy_mgr_err("Invalid Context"); 7796 return QDF_STATUS_E_INVAL; 7797 } 7798 7799 /* Handle only when non-ML STA is going down and ML STA is active */ 7800 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 7801 ml_sta_vdev_lst, ml_freq_lst, &num_non_ml, 7802 NULL, NULL); 7803 policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d", 7804 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml); 7805 7806 /* 7807 * No ML STA is present or sinle link ML is present or 7808 * more no.of links are active than supported concurrent connections 7809 */ 7810 if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) 7811 return QDF_STATUS_E_INVAL; 7812 7813 /* STA+STA cases */ 7814 7815 /* One ML/non-ML STA is going down and another non ML STA is present */ 7816 if (num_non_ml) { 7817 policy_mgr_debug("non-ML STA is present"); 7818 return QDF_STATUS_SUCCESS; 7819 } 7820 7821 /* 7822 * If no links are disabled or 7823 * link can not be allowed to enable then skip checking further. 7824 */ 7825 if (!num_disabled_ml_sta || 7826 !policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta, 7827 num_ml_sta, ml_freq_lst, 7828 ml_sta_vdev_lst)) { 7829 if (num_disabled_ml_sta) 7830 policy_mgr_debug("Not re-enabled due to disallowed concurrency"); 7831 goto done; 7832 } 7833 7834 policy_mgr_mlo_sta_set_link(psoc, 7835 MLO_LINK_FORCE_REASON_DISCONNECT, 7836 MLO_LINK_FORCE_MODE_NO_FORCE, 7837 num_ml_sta, ml_sta_vdev_lst); 7838 7839 done: 7840 return QDF_STATUS_SUCCESS; 7841 } 7842 7843 /* 7844 * policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down() - Handle enable 7845 * link on P2P/SAP/ML_STA vdev down 7846 * @psoc: objmgr psoc 7847 * @vdev: vdev which went down 7848 * 7849 * Return: void 7850 */ 7851 static void 7852 policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(struct wlan_objmgr_psoc *psoc, 7853 struct wlan_objmgr_vdev *vdev) 7854 { 7855 uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0; 7856 uint8_t num_affected_link = 0; 7857 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7858 uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7859 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7860 qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 7861 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7862 struct policy_mgr_psoc_priv_obj *pm_ctx; 7863 QDF_STATUS status; 7864 7865 status = policy_mgr_handle_ml_sta_link_state_allowed( 7866 psoc, MLO_LINK_FORCE_REASON_DISCONNECT); 7867 if (QDF_IS_STATUS_ERROR(status)) 7868 return; 7869 7870 status = policy_mgr_handle_ml_sta_link_enable_on_sta_down(psoc, vdev); 7871 if (QDF_IS_STATUS_SUCCESS(status)) 7872 return; 7873 7874 pm_ctx = policy_mgr_get_context(psoc); 7875 if (!pm_ctx) { 7876 policy_mgr_err("Invalid Context"); 7877 return; 7878 } 7879 7880 policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta, 7881 &num_disabled_ml_sta, 7882 ml_sta_vdev_lst, 7883 ml_freq_lst, &num_p2p_sap, 7884 p2p_sap_vdev_lst, 7885 p2p_sap_freq_lst); 7886 7887 policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d", 7888 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap); 7889 7890 if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 7891 num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS) 7892 return; 7893 7894 /* If link can not be allowed to enable then skip checking further. */ 7895 if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta, 7896 num_ml_sta, ml_freq_lst, 7897 ml_sta_vdev_lst)) 7898 return; 7899 7900 /* 7901 * If num_p2p_sap is non zero, ie p2p or sap still present check if 7902 * disable link is still required, if not enable the link. 7903 * 7904 * If num_p2p_sap is 0, ie only ml sta is present, enable the link. 7905 */ 7906 if (num_p2p_sap) 7907 num_affected_link = 7908 policy_mgr_get_affected_links_for_go_sap_cli(psoc, 7909 num_ml_sta, ml_sta_vdev_lst, 7910 ml_freq_lst, num_p2p_sap, 7911 p2p_sap_vdev_lst, 7912 p2p_sap_freq_lst); 7913 7914 if (num_affected_link) 7915 policy_mgr_debug("vdev %d: Affected link present, dont reanabe ML link", 7916 vdev_id); 7917 else 7918 policy_mgr_mlo_sta_set_link(psoc, 7919 MLO_LINK_FORCE_REASON_DISCONNECT, 7920 MLO_LINK_FORCE_MODE_NO_FORCE, 7921 num_ml_sta, ml_sta_vdev_lst); 7922 } 7923 7924 void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc, 7925 enum QDF_OPMODE mode, 7926 uint8_t vdev_id) 7927 { 7928 struct wlan_objmgr_vdev *vdev; 7929 7930 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 7931 WLAN_POLICY_MGR_ID); 7932 if (!vdev) { 7933 policy_mgr_err("vdev %d: invalid vdev", vdev_id); 7934 return; 7935 } 7936 7937 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE || 7938 mode == QDF_P2P_CLIENT_MODE || mode == QDF_P2P_GO_MODE) 7939 policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(psoc, vdev); 7940 7941 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 7942 } 7943 7944 /** 7945 * policy_mgr_pick_link_vdev_from_inactive_list() - Get inactive vdev 7946 * which can be activated 7947 * @psoc: PSOC object information 7948 * @vdev: vdev object 7949 * @inactive_vdev_num: inactive vdev num in list 7950 * @inactive_vdev_lst: inactive vdev list 7951 * @inactive_freq_lst: inactive vdev frequency list 7952 * @picked_vdev_id: Picked vdev id 7953 * @non_removed_vdev_id: not removed inactive vdev id 7954 * 7955 * If one link is removed and inactivated, pick one of existing inactive 7956 * vdev which can be activated by checking concurrency API. 7957 * 7958 * Return: void 7959 */ 7960 static void 7961 policy_mgr_pick_link_vdev_from_inactive_list( 7962 struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, 7963 uint8_t inactive_vdev_num, uint8_t *inactive_vdev_lst, 7964 qdf_freq_t *inactive_freq_lst, uint8_t *picked_vdev_id, 7965 uint8_t *non_removed_vdev_id) 7966 { 7967 struct policy_mgr_psoc_priv_obj *pm_ctx; 7968 struct policy_mgr_conc_connection_info 7969 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; 7970 uint8_t num_del = 0; 7971 union conc_ext_flag conc_ext_flags = {0}; 7972 uint8_t i; 7973 7974 pm_ctx = policy_mgr_get_context(psoc); 7975 if (!pm_ctx) { 7976 policy_mgr_err("Invalid Context"); 7977 return; 7978 } 7979 7980 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 7981 policy_mgr_store_and_del_conn_info_by_vdev_id( 7982 psoc, wlan_vdev_get_id(vdev), 7983 info, &num_del); 7984 /* pick one inactive parnter link and make it active */ 7985 for (i = 0; i < inactive_vdev_num; i++) { 7986 struct wlan_objmgr_vdev *partner_vdev; 7987 7988 if (wlan_get_vdev_link_removed_flag_by_vdev_id( 7989 psoc, inactive_vdev_lst[i])) { 7990 policy_mgr_debug("skip removed link vdev %d", 7991 inactive_vdev_lst[i]); 7992 continue; 7993 } 7994 7995 partner_vdev = 7996 wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 7997 inactive_vdev_lst[i], 7998 WLAN_POLICY_MGR_ID); 7999 if (!partner_vdev) { 8000 policy_mgr_err("invalid partner_vdev %d ", 8001 inactive_vdev_lst[i]); 8002 continue; 8003 } 8004 *non_removed_vdev_id = inactive_vdev_lst[i]; 8005 8006 conc_ext_flags.value = 8007 policy_mgr_get_conc_ext_flags(partner_vdev, false); 8008 8009 if (policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE, 8010 inactive_freq_lst[i], 8011 HW_MODE_20_MHZ, 8012 conc_ext_flags.value, 8013 NULL)) { 8014 *picked_vdev_id = inactive_vdev_lst[i]; 8015 wlan_objmgr_vdev_release_ref(partner_vdev, 8016 WLAN_POLICY_MGR_ID); 8017 break; 8018 } 8019 wlan_objmgr_vdev_release_ref(partner_vdev, WLAN_POLICY_MGR_ID); 8020 } 8021 /* Restore the connection info */ 8022 policy_mgr_restore_deleted_conn_info(psoc, info, num_del); 8023 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 8024 } 8025 8026 void policy_mgr_handle_link_removal_on_vdev(struct wlan_objmgr_vdev *vdev) 8027 { 8028 struct wlan_objmgr_psoc *psoc; 8029 struct policy_mgr_psoc_priv_obj *pm_ctx; 8030 uint32_t i; 8031 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0; 8032 uint8_t num_active_ml_sta; 8033 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8034 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8035 uint8_t vdev_id = wlan_vdev_get_id(vdev); 8036 uint8_t non_removal_link_vdev_id = WLAN_INVALID_VDEV_ID; 8037 uint8_t picked_vdev_id = WLAN_INVALID_VDEV_ID; 8038 QDF_STATUS status; 8039 8040 psoc = wlan_vdev_get_psoc(vdev); 8041 if (!psoc) { 8042 policy_mgr_err("Failed to get psoc"); 8043 return; 8044 } 8045 pm_ctx = policy_mgr_get_context(psoc); 8046 if (!pm_ctx) { 8047 policy_mgr_err("Invalid Context"); 8048 return; 8049 } 8050 if (wlan_get_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id)) { 8051 policy_mgr_debug("removal link vdev %d is removed already", 8052 vdev_id); 8053 return; 8054 } 8055 /* mark link removed for vdev */ 8056 wlan_set_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id, 8057 true); 8058 status = policy_mgr_handle_ml_sta_link_state_allowed( 8059 psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL); 8060 if (QDF_IS_STATUS_ERROR(status)) { 8061 wlan_set_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id, 8062 false); 8063 return; 8064 } 8065 8066 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 8067 ml_sta_vdev_lst, ml_freq_lst, 8068 NULL, NULL, NULL); 8069 if (!num_ml_sta) { 8070 policy_mgr_debug("unexpected event, no ml sta"); 8071 return; 8072 } 8073 if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 8074 num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 8075 num_ml_sta <= num_disabled_ml_sta) { 8076 policy_mgr_debug("unexpected ml sta num %d %d", 8077 num_ml_sta, num_disabled_ml_sta); 8078 return; 8079 } 8080 /* Single link FW should handle BTM/disassoc and do roaming. 8081 * Host will not send inactive command to FW. 8082 */ 8083 if (num_ml_sta < 2) { 8084 policy_mgr_debug("no op for single link mlo, num_ml_sta %d", 8085 num_ml_sta); 8086 return; 8087 } 8088 8089 policy_mgr_debug("removal link vdev %d num_ml_sta %d num_disabled_ml_sta %d", 8090 vdev_id, num_ml_sta, num_disabled_ml_sta); 8091 8092 num_active_ml_sta = num_ml_sta; 8093 if (num_ml_sta >= num_disabled_ml_sta) 8094 num_active_ml_sta = num_ml_sta - num_disabled_ml_sta; 8095 8096 for (i = 0; i < num_active_ml_sta; i++) 8097 if (ml_sta_vdev_lst[i] == vdev_id) 8098 break; 8099 8100 if (i == num_active_ml_sta) { 8101 /* no found in active ml list, it must be in inactive list */ 8102 policy_mgr_debug("removal link vdev %d is inactive already", 8103 vdev_id); 8104 8105 /* send inactive command to fw again with "link removal 8106 * reason" 8107 */ 8108 policy_mgr_mlo_sta_set_link( 8109 psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL, 8110 MLO_LINK_FORCE_MODE_INACTIVE, 8111 1, &vdev_id); 8112 return; 8113 } 8114 8115 /* pick one inactive parnter link and make it active */ 8116 if (num_active_ml_sta < num_ml_sta) 8117 policy_mgr_pick_link_vdev_from_inactive_list( 8118 psoc, vdev, num_disabled_ml_sta, 8119 &ml_sta_vdev_lst[num_active_ml_sta], 8120 &ml_freq_lst[num_active_ml_sta], 8121 &picked_vdev_id, 8122 &non_removal_link_vdev_id); 8123 if (picked_vdev_id != WLAN_INVALID_VDEV_ID) { 8124 /* find one inactive link can be active, send it to fw with 8125 * the removed link together. 8126 */ 8127 policy_mgr_debug("active parnter vdev %d, inactive removal vdev %d", 8128 picked_vdev_id, vdev_id); 8129 policy_mgr_mlo_sta_set_link_ext( 8130 psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL, 8131 MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, 8132 1, &picked_vdev_id, 8133 1, &vdev_id); 8134 return; 8135 } 8136 if (num_active_ml_sta < 2) { 8137 /* For multi-link MLO, one link is removed and 8138 * no find one inactive link can be active: 8139 * 1. If at least one left link is not link removed state, 8140 * host will trigger roaming. 8141 * 2. If all left links are link removed state, 8142 * FW will trigger roaming based on BTM or disassoc frame 8143 */ 8144 if (non_removal_link_vdev_id != WLAN_INVALID_VDEV_ID) { 8145 policy_mgr_debug("trigger roaming, non_removal_link_vdev_id %d", 8146 non_removal_link_vdev_id); 8147 policy_mgr_trigger_roam_on_link_removal(vdev); 8148 } 8149 return; 8150 } 8151 /* If active link number >= 2 and one link is removed, then at least 8152 * one link is still active, just send inactived command to fw. 8153 */ 8154 policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL, 8155 MLO_LINK_FORCE_MODE_INACTIVE, 8156 1, &vdev_id); 8157 } 8158 8159 /** 8160 * policy_mgr_is_restart_sap_required_with_mlo_sta() - Check SAP required to 8161 * restart for force SCC with MLO STA 8162 * @psoc: PSOC object information 8163 * @sap_vdev_id: sap vdev id 8164 * @sap_ch_freq: sap channel frequency 8165 * 8166 * For MLO STA+SAP case, mlo link maybe in inactive state after connected 8167 * and the hw mode maybe not updated, check MCC/SCC by 8168 * policy_mgr_are_2_freq_on_same_mac may not match MCC/SCC state 8169 * after the link is activated by target later. So to check frequency match 8170 * or not to decide SAP do force SCC or not if MLO STA 2 links are present. 8171 * 8172 * Return: true if SAP is required to force SCC with MLO STA 8173 */ 8174 static bool 8175 policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc *psoc, 8176 uint8_t sap_vdev_id, 8177 qdf_freq_t sap_ch_freq) 8178 { 8179 struct policy_mgr_psoc_priv_obj *pm_ctx; 8180 uint32_t i; 8181 bool same_freq_with_mlo_sta = false; 8182 bool restart_required = false; 8183 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_ml_active_sta = 0; 8184 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8185 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8186 8187 pm_ctx = policy_mgr_get_context(psoc); 8188 if (!pm_ctx) { 8189 policy_mgr_err("Invalid Context"); 8190 return false; 8191 } 8192 8193 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 8194 ml_sta_vdev_lst, ml_freq_lst, 8195 NULL, NULL, NULL); 8196 if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) { 8197 policy_mgr_debug("unexpected num_ml_sta %d ", num_ml_sta); 8198 return false; 8199 } 8200 8201 num_ml_active_sta = num_ml_sta; 8202 if (num_ml_sta >= num_disabled_ml_sta) 8203 num_ml_active_sta = num_ml_sta - num_disabled_ml_sta; 8204 for (i = 0; i < num_ml_active_sta; i++) { 8205 if (ml_freq_lst[i] == sap_ch_freq) { 8206 same_freq_with_mlo_sta = true; 8207 break; 8208 } 8209 } 8210 8211 if (num_ml_active_sta >= 2 && !same_freq_with_mlo_sta) { 8212 policy_mgr_debug("SAP is not SCC with any of active MLO STA link, restart SAP"); 8213 restart_required = true; 8214 } 8215 8216 return restart_required; 8217 } 8218 8219 void policy_mgr_activate_mlo_links(struct wlan_objmgr_psoc *psoc, 8220 uint8_t session_id, uint8_t num_links, 8221 struct qdf_mac_addr active_link_addr[2]) 8222 { 8223 uint8_t idx, link, active_vdev_cnt = 0, inactive_vdev_cnt = 0; 8224 uint16_t ml_vdev_cnt = 0; 8225 struct wlan_objmgr_vdev *tmp_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; 8226 uint8_t active_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; 8227 uint8_t inactive_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; 8228 struct wlan_objmgr_vdev *vdev; 8229 uint8_t *link_mac_addr; 8230 bool active_vdev_present = false; 8231 8232 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, 8233 WLAN_POLICY_MGR_ID); 8234 if (!vdev) { 8235 policy_mgr_err("vdev_id: %d vdev not found", session_id); 8236 return; 8237 } 8238 8239 if (!wlan_cm_is_vdev_connected(vdev)) { 8240 policy_mgr_err("vdev is not in connected state"); 8241 goto done; 8242 } 8243 8244 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) { 8245 policy_mgr_err("vdev is not mlo vdev"); 8246 goto done; 8247 } 8248 8249 mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, tmp_vdev_lst); 8250 policy_mgr_debug("Num active links: %d, ML vdev cnt: %d", num_links, 8251 ml_vdev_cnt); 8252 for (idx = 0; idx < ml_vdev_cnt; idx++) { 8253 link_mac_addr = wlan_vdev_mlme_get_macaddr(tmp_vdev_lst[idx]); 8254 policy_mgr_debug("link addr: " QDF_MAC_ADDR_FMT, 8255 QDF_MAC_ADDR_REF(link_mac_addr)); 8256 for (link = 0; link < num_links; link++) { 8257 policy_mgr_debug("active addr: " QDF_MAC_ADDR_FMT, 8258 QDF_MAC_ADDR_REF(&active_link_addr[link].bytes[0])); 8259 if (!qdf_mem_cmp(link_mac_addr, 8260 &active_link_addr[link].bytes[0], 8261 QDF_MAC_ADDR_SIZE)) { 8262 active_vdev_lst[active_vdev_cnt] = 8263 wlan_vdev_get_id(tmp_vdev_lst[idx]); 8264 active_vdev_cnt++; 8265 active_vdev_present = true; 8266 policy_mgr_debug("Link address match"); 8267 } 8268 } 8269 if (!active_vdev_present) { 8270 inactive_vdev_lst[inactive_vdev_cnt] = 8271 wlan_vdev_get_id(tmp_vdev_lst[idx]); 8272 inactive_vdev_cnt++; 8273 policy_mgr_err("No link address match"); 8274 } 8275 active_vdev_present = false; 8276 } 8277 8278 policy_mgr_debug("active vdev cnt: %d, inactive vdev cnt: %d", 8279 active_vdev_cnt, inactive_vdev_cnt); 8280 8281 if (active_vdev_cnt && 8282 policy_mgr_is_emlsr_sta_concurrency_present(psoc)) { 8283 policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode"); 8284 goto ref_release; 8285 } 8286 8287 /* 8288 * If there are both active and inactive vdev count, then issue a 8289 * single WMI with force mode MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, 8290 * else if there is only active vdev count, send single WMI for 8291 * all active vdevs with force mode MLO_LINK_FORCE_MODE_ACTIVE. 8292 */ 8293 if (active_vdev_cnt && inactive_vdev_cnt) 8294 policy_mgr_mlo_sta_set_link_ext( 8295 psoc, MLO_LINK_FORCE_REASON_CONNECT, 8296 MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, 8297 active_vdev_cnt, active_vdev_lst, 8298 inactive_vdev_cnt, inactive_vdev_lst); 8299 else if (active_vdev_cnt && !inactive_vdev_cnt) 8300 policy_mgr_mlo_sta_set_link(psoc, 8301 MLO_LINK_FORCE_REASON_DISCONNECT, 8302 MLO_LINK_FORCE_MODE_ACTIVE, 8303 active_vdev_cnt, active_vdev_lst); 8304 ref_release: 8305 for (idx = 0; idx < ml_vdev_cnt; idx++) 8306 mlo_release_vdev_ref(tmp_vdev_lst[idx]); 8307 done: 8308 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 8309 } 8310 8311 QDF_STATUS 8312 policy_mgr_update_mlo_links_based_on_linkid(struct wlan_objmgr_psoc *psoc, 8313 uint8_t vdev_id, 8314 uint8_t num_links, 8315 uint8_t *link_id_list, 8316 uint32_t *config_state_list) 8317 { 8318 uint8_t idx, link, active_vdev_cnt = 0, inactive_vdev_cnt = 0; 8319 uint16_t ml_vdev_cnt = 0; 8320 struct wlan_objmgr_vdev *vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; 8321 uint8_t active_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; 8322 uint8_t inactive_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; 8323 struct wlan_objmgr_vdev *vdev; 8324 uint8_t link_id, num_links_to_disable = 0, num_matched_linkid = 0; 8325 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8326 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0; 8327 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8328 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8329 struct policy_mgr_psoc_priv_obj *pm_ctx; 8330 8331 for (idx = 0; idx < num_links; idx++) { 8332 if (config_state_list[idx] == 0) 8333 num_links_to_disable++; 8334 } 8335 8336 if (num_links_to_disable == num_links) { 8337 policy_mgr_debug("vdev: %d num_links_to_disable: %d", vdev_id, 8338 num_links_to_disable); 8339 return QDF_STATUS_E_FAILURE; 8340 } 8341 8342 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 8343 WLAN_POLICY_MGR_ID); 8344 if (!vdev) { 8345 policy_mgr_err("vdev: %d vdev not found", vdev_id); 8346 return QDF_STATUS_E_FAILURE; 8347 } 8348 8349 if (!wlan_cm_is_vdev_connected(vdev)) { 8350 policy_mgr_err("vdev: %d is not in connected state", vdev_id); 8351 goto release_vdev_ref; 8352 } 8353 8354 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) { 8355 policy_mgr_err("vdev:%d is not mlo vdev", vdev_id); 8356 goto release_vdev_ref; 8357 } 8358 8359 pm_ctx = policy_mgr_get_context(psoc); 8360 if (!pm_ctx) { 8361 policy_mgr_err("Invalid pm context"); 8362 goto release_vdev_ref; 8363 } 8364 8365 mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, vdev_lst); 8366 for (idx = 0; idx < ml_vdev_cnt; idx++) { 8367 link_id = wlan_vdev_get_link_id(vdev_lst[idx]); 8368 for (link = 0; link < num_links; link++) { 8369 if (link_id_list[link] == link_id) { 8370 num_matched_linkid++; 8371 policy_mgr_debug("link id:%d match", link_id); 8372 if (config_state_list[link]) { 8373 active_vdev_lst[active_vdev_cnt] = 8374 wlan_vdev_get_id(vdev_lst[idx]); 8375 active_vdev_cnt++; 8376 } else { 8377 inactive_vdev_lst[inactive_vdev_cnt] = 8378 wlan_vdev_get_id(vdev_lst[idx]); 8379 inactive_vdev_cnt++; 8380 } 8381 } 8382 } 8383 } 8384 8385 policy_mgr_debug("vdev: %d, active links: %d, ml count: %d, active count: %d, inactive count: %d", 8386 vdev_id, num_links, ml_vdev_cnt, active_vdev_cnt, 8387 inactive_vdev_cnt); 8388 8389 if (num_links != num_matched_linkid) { 8390 policy_mgr_debug("invalid link id(s), num_matched_linkid: %d", 8391 num_matched_linkid); 8392 goto release_ml_vdev_ref; 8393 } 8394 8395 if (active_vdev_cnt && 8396 policy_mgr_is_emlsr_sta_concurrency_present(psoc)) { 8397 policy_mgr_debug("vdev: %d emlsr sta conn present", vdev_id); 8398 if (active_vdev_cnt == 1) 8399 status = QDF_STATUS_SUCCESS; 8400 goto release_ml_vdev_ref; 8401 } 8402 8403 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 8404 ml_sta_vdev_lst, ml_freq_lst, &num_non_ml, 8405 NULL, NULL); 8406 policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d", 8407 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml); 8408 8409 /* 8410 * No ML STA is present or sinle link ML is present or 8411 * more no.of links are active than supported concurrent connections 8412 */ 8413 if (!num_ml_sta || num_ml_sta < 2 || 8414 num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) 8415 goto release_ml_vdev_ref; 8416 8417 if (!num_disabled_ml_sta) { 8418 /* 8419 * both link are already enabled and received set link req to 8420 * enable both again 8421 */ 8422 if (active_vdev_cnt && !inactive_vdev_cnt) { 8423 status = QDF_STATUS_SUCCESS; 8424 goto release_ml_vdev_ref; 8425 } 8426 8427 /* 8428 * both link are already enabled and received set link req 8429 * disable one link, disable any 8430 */ 8431 if (active_vdev_cnt && inactive_vdev_cnt) { 8432 status = policy_mgr_mlo_sta_set_link_ext(psoc, 8433 MLO_LINK_FORCE_REASON_CONNECT, 8434 MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, 8435 active_vdev_cnt, active_vdev_lst, 8436 inactive_vdev_cnt, inactive_vdev_lst); 8437 goto release_ml_vdev_ref; 8438 } 8439 } else { 8440 /* 8441 * one link is enable and one link is disabled, If disabled 8442 * link can not be allowed to enable then send status failure 8443 * to upper layer. 8444 */ 8445 if (active_vdev_cnt && 8446 !policy_mgr_sta_ml_link_enable_allowed(psoc, 8447 num_disabled_ml_sta, 8448 num_ml_sta, 8449 ml_freq_lst, 8450 ml_sta_vdev_lst)) { 8451 policy_mgr_debug("vdev %d: link enable not allowed", 8452 vdev_id); 8453 goto release_ml_vdev_ref; 8454 } 8455 8456 /* 8457 * If there are both active and inactive vdev count, then 8458 * issue a single WMI with force mode 8459 * MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, else if there is only 8460 * active vdev count, send single WMI for all active vdevs 8461 * with force mode MLO_LINK_FORCE_MODE_ACTIVE. 8462 */ 8463 if (active_vdev_cnt && inactive_vdev_cnt) 8464 status = policy_mgr_mlo_sta_set_link_ext(psoc, 8465 MLO_LINK_FORCE_REASON_CONNECT, 8466 MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, 8467 active_vdev_cnt, active_vdev_lst, 8468 inactive_vdev_cnt, inactive_vdev_lst); 8469 else if (active_vdev_cnt && !inactive_vdev_cnt) 8470 status = policy_mgr_mlo_sta_set_link(psoc, 8471 MLO_LINK_FORCE_REASON_DISCONNECT, 8472 MLO_LINK_FORCE_MODE_ACTIVE, 8473 active_vdev_cnt, active_vdev_lst); 8474 } 8475 8476 release_ml_vdev_ref: 8477 for (idx = 0; idx < ml_vdev_cnt; idx++) 8478 mlo_release_vdev_ref(vdev_lst[idx]); 8479 release_vdev_ref: 8480 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 8481 8482 return status; 8483 } 8484 8485 /** 8486 * policy_mgr_process_mlo_sta_dynamic_force_num_link() - Set links for MLO STA 8487 * @psoc: psoc object 8488 * @reason: Reason for which link is forced 8489 * @mode: Force reason 8490 * @num_mlo_vdev: number of mlo vdev 8491 * @mlo_vdev_lst: MLO STA vdev list 8492 * @force_active_cnt: number of MLO links to operate in active state as per 8493 * user req 8494 * 8495 * User space provides the desired number of MLO links to operate in active 8496 * state at any given time. Host validate request as per current concurrency 8497 * and send SET LINK requests to FW. FW will choose which MLO links should 8498 * operate in the active state. 8499 * 8500 * Return: QDF_STATUS 8501 */ 8502 static QDF_STATUS 8503 policy_mgr_process_mlo_sta_dynamic_force_num_link(struct wlan_objmgr_psoc *psoc, 8504 enum mlo_link_force_reason reason, 8505 enum mlo_link_force_mode mode, 8506 uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst, 8507 uint8_t force_active_cnt) 8508 { 8509 struct mlo_link_set_active_req *req; 8510 QDF_STATUS status; 8511 struct policy_mgr_psoc_priv_obj *pm_ctx; 8512 struct wlan_objmgr_vdev *vdev; 8513 8514 if (!num_mlo_vdev) { 8515 policy_mgr_err("invalid 0 num_mlo_vdev"); 8516 return QDF_STATUS_E_INVAL; 8517 } 8518 8519 pm_ctx = policy_mgr_get_context(psoc); 8520 if (!pm_ctx) { 8521 policy_mgr_err("Invalid Context"); 8522 return QDF_STATUS_E_INVAL; 8523 } 8524 8525 req = qdf_mem_malloc(sizeof(*req)); 8526 if (!req) 8527 return QDF_STATUS_E_NOMEM; 8528 8529 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, mlo_vdev_lst[0], 8530 WLAN_POLICY_MGR_ID); 8531 if (!vdev) { 8532 policy_mgr_err("vdev %d: invalid vdev", mlo_vdev_lst[0]); 8533 qdf_mem_free(req); 8534 return QDF_STATUS_E_FAILURE; 8535 } 8536 8537 policy_mgr_debug("vdev %d: mode %d num_mlo_vdev %d reason %d", 8538 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, reason); 8539 8540 /* 8541 * TODO: this API has to be merged with policy_mgr_mlo_sta_set_link_ext 8542 * as part of 3 link FR change as in caller only we have to decide how 8543 * many links to disable/enable for MLO_LINK_FORCE_MODE_ACTIVE_NUM or 8544 * MLO_LINK_FORCE_MODE_INACTIVE_NUM scenario 8545 */ 8546 req->ctx.vdev = vdev; 8547 req->param.reason = reason; 8548 req->param.force_mode = mode; 8549 req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp; 8550 req->ctx.validate_set_mlo_link_cb = 8551 policy_mgr_validate_set_mlo_link_cb; 8552 req->ctx.cb_arg = req; 8553 8554 /* set MLO vdev bit mask */ 8555 policy_mgr_fill_ml_active_link_vdev_bitmap(req, mlo_vdev_lst, 8556 num_mlo_vdev); 8557 8558 pm_ctx->active_vdev_bitmap = req->param.vdev_bitmap[0]; 8559 pm_ctx->inactive_vdev_bitmap = req->param.vdev_bitmap[1]; 8560 8561 req->param.num_link_entry = 1; 8562 req->param.link_num[0].num_of_link = force_active_cnt; 8563 req->param.control_flags.dynamic_force_link_num = 1; 8564 8565 if (ml_is_nlink_service_supported(psoc)) { 8566 status = 8567 policy_mgr_mlo_sta_set_link_by_linkid(psoc, vdev, reason, 8568 mode, 8569 req->param.link_num[0]. 8570 num_of_link, 8571 num_mlo_vdev, 8572 mlo_vdev_lst, 8573 0, 8574 NULL); 8575 qdf_mem_free(req); 8576 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 8577 8578 if (status != QDF_STATUS_E_PENDING) { 8579 policy_mgr_err("set_link_by_linkid status %d", status); 8580 return status; 8581 } 8582 return QDF_STATUS_SUCCESS; 8583 } 8584 8585 policy_mgr_set_link_in_progress(pm_ctx, true); 8586 8587 status = mlo_ser_set_link_req(req); 8588 if (QDF_IS_STATUS_ERROR(status)) { 8589 policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d force_active_cnt: %d, reason %d", 8590 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, 8591 force_active_cnt, 8592 reason); 8593 qdf_mem_free(req); 8594 policy_mgr_set_link_in_progress(pm_ctx, false); 8595 } 8596 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 8597 return status; 8598 } 8599 8600 QDF_STATUS policy_mgr_update_active_mlo_num_links(struct wlan_objmgr_psoc *psoc, 8601 uint8_t vdev_id, 8602 uint8_t force_active_cnt) 8603 { 8604 struct wlan_objmgr_vdev *vdev; 8605 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0; 8606 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8607 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8608 struct policy_mgr_psoc_priv_obj *pm_ctx; 8609 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8610 8611 if (policy_mgr_is_emlsr_sta_concurrency_present(psoc)) { 8612 policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode"); 8613 return QDF_STATUS_E_FAILURE; 8614 } 8615 8616 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 8617 WLAN_POLICY_MGR_ID); 8618 if (!vdev) { 8619 policy_mgr_err("vdev_id: %d vdev not found", vdev_id); 8620 return QDF_STATUS_E_FAILURE; 8621 } 8622 8623 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 8624 goto release_vdev_ref; 8625 8626 if (!wlan_cm_is_vdev_connected(vdev)) { 8627 policy_mgr_err("vdev is not in connected state"); 8628 goto release_vdev_ref; 8629 } 8630 8631 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) { 8632 policy_mgr_err("vdev is not mlo vdev"); 8633 goto release_vdev_ref; 8634 } 8635 8636 pm_ctx = policy_mgr_get_context(psoc); 8637 if (!pm_ctx) { 8638 policy_mgr_err("Invalid Context"); 8639 goto release_vdev_ref; 8640 } 8641 8642 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 8643 ml_sta_vdev_lst, ml_freq_lst, &num_non_ml, 8644 NULL, NULL); 8645 policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d", 8646 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml); 8647 8648 /* 8649 * No ML STA is present or more no.of links are active than supported 8650 * concurrent connections 8651 */ 8652 if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) 8653 goto release_vdev_ref; 8654 8655 /* 8656 * DUT connected with MLO AP, one link is always active, So if 8657 * request comes to make one link is active, host sends set link command 8658 * with mode MLO_LINK_FORCE_MODE_ACTIVE_NUM, so that FW should restrict 8659 * to only one link and avoid switch from MLSR to MLMR. 8660 */ 8661 if (force_active_cnt == 1) 8662 goto set_link; 8663 8664 /* 8665 * num_disabled_ml_sta == 0, means 2 link is already active, 8666 * In this case send set link command with num link 2 and mode 8667 * MLO_LINK_FORCE_MODE_ACTIVE_NUM, so that FW should restrict to only 8668 * in MLMR mode (2 link should be active). 8669 */ 8670 if (force_active_cnt == 2 && num_disabled_ml_sta == 0) 8671 goto set_link; 8672 8673 /* Link can not be allowed to enable then skip checking further */ 8674 if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta, 8675 num_ml_sta, ml_freq_lst, 8676 ml_sta_vdev_lst)) { 8677 policy_mgr_debug("vdev %d: link enable not allowed", vdev_id); 8678 goto release_vdev_ref; 8679 } 8680 8681 set_link: 8682 status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc, 8683 MLO_LINK_FORCE_REASON_CONNECT, 8684 MLO_LINK_FORCE_MODE_ACTIVE_NUM, 8685 num_ml_sta, ml_sta_vdev_lst, 8686 force_active_cnt); 8687 if (QDF_IS_STATUS_SUCCESS(status)) 8688 policy_mgr_debug("vdev %d: link enable allowed", vdev_id); 8689 8690 release_vdev_ref: 8691 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 8692 return status; 8693 } 8694 8695 QDF_STATUS 8696 policy_mgr_clear_ml_links_settings_in_fw(struct wlan_objmgr_psoc *psoc, 8697 uint8_t vdev_id) 8698 { 8699 struct wlan_objmgr_vdev *vdev; 8700 uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0; 8701 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8702 qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 8703 struct policy_mgr_psoc_priv_obj *pm_ctx; 8704 uint8_t num_link_to_no_force = 0, num_active_ml_sta = 0; 8705 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8706 8707 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 8708 WLAN_POLICY_MGR_ID); 8709 if (!vdev) { 8710 policy_mgr_err("vdev: %d vdev not found", vdev_id); 8711 return QDF_STATUS_E_FAILURE; 8712 } 8713 8714 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 8715 goto release_vdev_ref; 8716 8717 if (!wlan_cm_is_vdev_connected(vdev)) { 8718 policy_mgr_err("vdev: %d is not in connected state", vdev_id); 8719 goto release_vdev_ref; 8720 } 8721 8722 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) { 8723 policy_mgr_err("vdev: %d is not mlo vdev", vdev_id); 8724 goto release_vdev_ref; 8725 } 8726 8727 pm_ctx = policy_mgr_get_context(psoc); 8728 if (!pm_ctx) { 8729 policy_mgr_err("vdev: %d Invalid Context", vdev_id); 8730 goto release_vdev_ref; 8731 } 8732 8733 policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta, 8734 ml_sta_vdev_lst, ml_freq_lst, &num_non_ml, 8735 NULL, NULL); 8736 policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d", 8737 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml); 8738 8739 if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS || 8740 num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) 8741 goto release_vdev_ref; 8742 8743 num_active_ml_sta = num_ml_sta; 8744 if (num_ml_sta >= num_disabled_ml_sta) 8745 num_active_ml_sta = num_ml_sta - num_disabled_ml_sta; 8746 8747 num_link_to_no_force += num_active_ml_sta; 8748 8749 /* Link can not be allowed to enable then skip checking further */ 8750 if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta, 8751 num_ml_sta, ml_freq_lst, 8752 ml_sta_vdev_lst)) { 8753 num_link_to_no_force += num_disabled_ml_sta; 8754 policy_mgr_debug("Link enable allowed, total num_links: %d", 8755 num_link_to_no_force); 8756 } 8757 8758 if (num_link_to_no_force < 1 || 8759 num_link_to_no_force > MAX_NUMBER_OF_CONC_CONNECTIONS) { 8760 policy_mgr_debug("vdev %d: invalid num_link_to_no_force: %d", 8761 vdev_id, num_link_to_no_force); 8762 goto release_vdev_ref; 8763 } 8764 8765 /* 8766 * send WMI_MLO_LINK_SET_ACTIVE_CMDID to clear user mode setting 8767 * configured via QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in FW 8768 */ 8769 status = policy_mgr_mlo_sta_set_link(psoc, 8770 MLO_LINK_FORCE_REASON_CONNECT, 8771 MLO_LINK_FORCE_MODE_NO_FORCE, 8772 num_link_to_no_force, 8773 ml_sta_vdev_lst); 8774 if (QDF_IS_STATUS_ERROR(status)) 8775 goto release_vdev_ref; 8776 else 8777 policy_mgr_debug("clear user mode setting for num_links:%d", 8778 num_link_to_no_force); 8779 8780 /* 8781 * send WMI_MLO_LINK_SET_ACTIVE_CMDID with value of 8782 * num_link as 0 to clear dynamic mode setting configured 8783 * via vendor attr LINK_STATE_MIXED_MODE_ACTIVE_NUM_LINKS in FW 8784 */ 8785 status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc, 8786 MLO_LINK_FORCE_REASON_CONNECT, 8787 MLO_LINK_FORCE_MODE_ACTIVE_NUM, 8788 num_link_to_no_force, ml_sta_vdev_lst, 0); 8789 if (QDF_IS_STATUS_SUCCESS(status)) 8790 policy_mgr_debug("clear mixed mode setting for num_links:%d", 8791 num_link_to_no_force); 8792 release_vdev_ref: 8793 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 8794 return status; 8795 } 8796 8797 #else 8798 static bool 8799 policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc, 8800 qdf_freq_t freq, 8801 uint32_t ext_flags) 8802 { 8803 uint32_t count; 8804 8805 count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 8806 NULL); 8807 if (!count) 8808 return true; 8809 8810 if (count >= 2) { 8811 policy_mgr_rl_debug("Disallow 3rd STA"); 8812 return false; 8813 } 8814 8815 if (!policy_mgr_allow_multiple_sta_connections(psoc)) { 8816 policy_mgr_rl_debug("Multiple STA connections is not allowed"); 8817 return false; 8818 } 8819 8820 return true; 8821 } 8822 8823 static bool 8824 policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc *psoc, 8825 uint8_t sap_vdev_id, 8826 qdf_freq_t sap_ch_freq) 8827 { 8828 return false; 8829 } 8830 #endif 8831 8832 #ifdef WLAN_FEATURE_P2P_P2P_STA 8833 bool policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc) 8834 { 8835 return wlan_mlme_get_p2p_p2p_conc_support(psoc); 8836 } 8837 #endif 8838 8839 /** 8840 * policy_mgr_is_third_conn_sta_p2p_p2p_valid: This API checks the firmware 8841 * capability and allows STA + P2P + P2P combination. It can be in SCC/MCC/DBS 8842 * @psoc: psoc pointer 8843 * @new_conn_mode: third connection mode 8844 * 8845 * Return: true if support else false 8846 */ 8847 static bool policy_mgr_is_third_conn_sta_p2p_p2p_valid( 8848 struct wlan_objmgr_psoc *psoc, 8849 enum policy_mgr_con_mode new_conn_mode) 8850 { 8851 int num_sta, num_go, num_cli; 8852 8853 num_sta = policy_mgr_mode_specific_connection_count(psoc, 8854 PM_STA_MODE, 8855 NULL); 8856 8857 num_go = policy_mgr_mode_specific_connection_count(psoc, 8858 PM_P2P_GO_MODE, 8859 NULL); 8860 8861 num_cli = policy_mgr_mode_specific_connection_count(psoc, 8862 PM_P2P_CLIENT_MODE, 8863 NULL); 8864 8865 if (num_sta + num_go + num_cli != 2) 8866 return true; 8867 8868 /* If STA + P2P + another STA comes up then return true 8869 * as this API is only for two port P2P + single STA combo 8870 * checks 8871 */ 8872 if (num_sta == 1 && new_conn_mode == PM_STA_MODE) 8873 return true; 8874 8875 if ((((PM_STA_MODE == pm_conc_connection_list[0].mode && 8876 PM_P2P_GO_MODE == pm_conc_connection_list[1].mode) || 8877 (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode && 8878 PM_STA_MODE == pm_conc_connection_list[1].mode)) 8879 || 8880 (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode && 8881 PM_P2P_GO_MODE == pm_conc_connection_list[1].mode) 8882 || 8883 ((PM_STA_MODE == pm_conc_connection_list[0].mode && 8884 PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode) || 8885 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode && 8886 PM_STA_MODE == pm_conc_connection_list[1].mode)) 8887 || 8888 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode && 8889 PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode) 8890 || 8891 ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode && 8892 PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode) || 8893 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode && 8894 PM_P2P_GO_MODE == pm_conc_connection_list[1].mode))) && 8895 num_sta <= 1) { 8896 if ((new_conn_mode == PM_STA_MODE || 8897 new_conn_mode == PM_P2P_CLIENT_MODE || 8898 new_conn_mode == PM_P2P_GO_MODE) && 8899 !policy_mgr_is_p2p_p2p_conc_supported(psoc)) 8900 return false; 8901 } 8902 8903 return true; 8904 } 8905 8906 static bool policy_mgr_is_sap_go_allowed_with_ll_sap( 8907 struct wlan_objmgr_psoc *psoc, 8908 qdf_freq_t freq, 8909 enum policy_mgr_con_mode mode) 8910 { 8911 /** 8912 * Scenario: When ll SAP(whose profile is set as gaming or 8913 * lossless audio) is present on 5GHz channel and SAP/GO 8914 * is trying to come up. 8915 * Validate the ch_freq of SAP/GO for both DBS and SBS case 8916 */ 8917 if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && 8918 !policy_mgr_is_ll_sap_concurrency_valid(psoc, freq, mode)) 8919 return false; 8920 8921 return true; 8922 } 8923 8924 bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, 8925 enum policy_mgr_con_mode mode, 8926 uint32_t ch_freq, 8927 enum hw_mode_bandwidth bw, 8928 uint32_t ext_flags, 8929 struct policy_mgr_pcl_list *pcl) 8930 { 8931 uint32_t num_connections = 0, count = 0, index = 0, i; 8932 bool status = false, match = false; 8933 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 8934 struct policy_mgr_psoc_priv_obj *pm_ctx; 8935 bool sta_sap_scc_on_dfs_chan; 8936 bool go_force_scc; 8937 enum channel_state chan_state; 8938 bool is_dfs_ch = false; 8939 struct ch_params ch_params; 8940 8941 pm_ctx = policy_mgr_get_context(psoc); 8942 if (!pm_ctx) { 8943 policy_mgr_err("Invalid Context"); 8944 return status; 8945 } 8946 /* find the current connection state from pm_conc_connection_list*/ 8947 num_connections = policy_mgr_get_connection_count(psoc); 8948 8949 if (num_connections && policy_mgr_is_sub_20_mhz_enabled(psoc)) { 8950 policy_mgr_rl_debug("dont allow concurrency if Sub 20 MHz is enabled"); 8951 return status; 8952 } 8953 8954 if (policy_mgr_max_concurrent_connections_reached(psoc)) { 8955 policy_mgr_rl_debug("Reached max concurrent connections: %d", 8956 pm_ctx->cfg.max_conc_cxns); 8957 policy_mgr_validate_conn_info(psoc); 8958 return status; 8959 } 8960 8961 if (ch_freq) { 8962 if (wlan_reg_is_5ghz_ch_freq(ch_freq)) { 8963 qdf_mem_zero(&ch_params, sizeof(ch_params)); 8964 ch_params.ch_width = policy_mgr_get_ch_width(bw); 8965 chan_state = 8966 wlan_reg_get_5g_bonded_channel_state_for_pwrmode( 8967 pm_ctx->pdev, ch_freq, 8968 &ch_params, REG_CURRENT_PWR_MODE); 8969 if (chan_state == CHANNEL_STATE_DFS) 8970 is_dfs_ch = true; 8971 } 8972 /* don't allow 3rd home channel on same MAC 8973 * also check for single mac target which doesn't 8974 * support interbad MCC as well 8975 */ 8976 if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq, 8977 num_connections, 8978 is_dfs_ch, 8979 ext_flags)) 8980 return status; 8981 8982 /* 8983 * 1) DFS MCC is not yet supported 8984 * 2) If you already have STA connection on 5G channel then 8985 * don't allow any other persona to make connection on DFS 8986 * channel because STA 5G + DFS MCC is not allowed. 8987 * 3) If STA is on 2G channel and SAP is coming up on 8988 * DFS channel then allow concurrency but make sure it is 8989 * going to DBS and send PCL to firmware indicating that 8990 * don't allow STA to roam to 5G channels. 8991 * 4) On a single MAC device, if a SAP/P2PGO is already on a DFS 8992 * channel, don't allow a 2 channel as it will result 8993 * in MCC which is not allowed. 8994 */ 8995 if (!policy_mgr_is_5g_channel_allowed(psoc, 8996 ch_freq, list, PM_P2P_GO_MODE)) 8997 return status; 8998 if (!policy_mgr_is_5g_channel_allowed(psoc, 8999 ch_freq, list, PM_SAP_MODE)) 9000 return status; 9001 if (!policy_mgr_is_6g_channel_allowed(psoc, mode, 9002 ch_freq)) 9003 return status; 9004 9005 sta_sap_scc_on_dfs_chan = 9006 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 9007 go_force_scc = policy_mgr_go_scc_enforced(psoc); 9008 if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && 9009 (!sta_sap_scc_on_dfs_chan || 9010 !policy_mgr_is_sta_sap_scc(psoc, ch_freq) || 9011 (!go_force_scc && mode == PM_P2P_GO_MODE))) { 9012 if (is_dfs_ch) 9013 match = policy_mgr_disallow_mcc(psoc, 9014 ch_freq); 9015 } 9016 if (true == match) { 9017 policy_mgr_rl_debug("No MCC, SAP/GO about to come up on DFS channel"); 9018 return status; 9019 } 9020 if ((policy_mgr_is_hw_dbs_capable(psoc) != true) && 9021 num_connections) { 9022 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { 9023 if (policy_mgr_is_sap_p2pgo_on_dfs(psoc)) { 9024 policy_mgr_rl_debug("MCC not allowed: SAP/P2PGO on DFS"); 9025 return status; 9026 } 9027 } 9028 } 9029 } 9030 9031 if (mode == PM_STA_MODE && 9032 !policy_mgr_allow_sta_concurrency(psoc, ch_freq, ext_flags)) 9033 return status; 9034 9035 if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq, 9036 WLAN_INVALID_VDEV_ID)) { 9037 policy_mgr_rl_debug("This concurrency combination is not allowed"); 9038 return status; 9039 } 9040 9041 /* 9042 * don't allow two P2P GO on same band, if fw doesn't 9043 * support p2p +p2p concurrency 9044 */ 9045 if (ch_freq && mode == PM_P2P_GO_MODE && num_connections && 9046 !policy_mgr_is_p2p_p2p_conc_supported(psoc)) { 9047 index = 0; 9048 count = policy_mgr_mode_specific_connection_count( 9049 psoc, PM_P2P_GO_MODE, list); 9050 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9051 while (index < count) { 9052 if (WLAN_REG_IS_SAME_BAND_FREQS( 9053 ch_freq, 9054 pm_conc_connection_list[list[index]].freq)) { 9055 policy_mgr_rl_debug("Don't allow P2P GO on same band"); 9056 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9057 return status; 9058 } 9059 index++; 9060 } 9061 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9062 } 9063 9064 if (!policy_mgr_allow_wapi_concurrency(pm_ctx)) { 9065 policy_mgr_rl_debug("Don't allow new conn when wapi security conn existing"); 9066 return status; 9067 } 9068 9069 /* Allow sta+p2p+p2p only if firmware supports the capability */ 9070 if (!policy_mgr_is_third_conn_sta_p2p_p2p_valid(psoc, mode)) { 9071 policy_mgr_err("Don't allow third connection as GO or GC or STA with old fw"); 9072 return status; 9073 } 9074 9075 /* Validate ll sap + sap/go concurrency */ 9076 if (!policy_mgr_is_sap_go_allowed_with_ll_sap(psoc, ch_freq, mode)) { 9077 policy_mgr_err("LL SAP concurrency is not valid"); 9078 return status; 9079 } 9080 9081 /* 9082 * Don't allow DFS SAP on non-SCC channels if an ML-STA is already 9083 * present. PCL list returns the SCC channels and all channels from 9084 * other MAC in case of non-ML/single link STA. 9085 */ 9086 if (mode == PM_SAP_MODE && pcl && 9087 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq)) { 9088 for (i = 0; i < pcl->pcl_len; i++) 9089 if (pcl->pcl_list[i] == ch_freq) { 9090 status = true; 9091 break; 9092 } 9093 if (!status) { 9094 policy_mgr_err("SAP channel %d Not present in PCL", 9095 ch_freq); 9096 return status; 9097 } 9098 } 9099 status = true; 9100 9101 return status; 9102 } 9103 9104 bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, 9105 enum policy_mgr_con_mode mode, 9106 uint32_t ch_freq, 9107 enum hw_mode_bandwidth bw, 9108 uint32_t ext_flags, uint8_t vdev_id) 9109 { 9110 QDF_STATUS status; 9111 struct policy_mgr_pcl_list pcl; 9112 bool allowed; 9113 9114 qdf_mem_zero(&pcl, sizeof(pcl)); 9115 status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len, 9116 pcl.weight_list, 9117 QDF_ARRAY_SIZE(pcl.weight_list), vdev_id); 9118 if (QDF_IS_STATUS_ERROR(status)) { 9119 policy_mgr_err("disallow connection:%d", status); 9120 return false; 9121 } 9122 9123 allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq, 9124 bw, ext_flags, &pcl); 9125 9126 /* Fourth connection concurrency check */ 9127 if (allowed && policy_mgr_get_connection_count(psoc) == 3) 9128 allowed = policy_mgr_is_concurrency_allowed_4_port( 9129 psoc, 9130 mode, 9131 ch_freq, 9132 pcl); 9133 return allowed; 9134 } 9135 9136 bool 9137 policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, 9138 enum policy_mgr_con_mode mode, 9139 uint32_t ch_freq, enum hw_mode_bandwidth bw, 9140 uint32_t vdev_id, bool forced, 9141 enum sap_csa_reason_code reason) 9142 { 9143 bool allow = false; 9144 struct policy_mgr_conc_connection_info 9145 info[MAX_NUMBER_OF_CONC_CONNECTIONS]; 9146 uint8_t num_cxn_del = 0; 9147 struct policy_mgr_psoc_priv_obj *pm_ctx; 9148 uint32_t old_ch_freq, conc_ext_flags; 9149 QDF_STATUS status; 9150 struct wlan_objmgr_vdev *vdev; 9151 9152 pm_ctx = policy_mgr_get_context(psoc); 9153 if (!pm_ctx) { 9154 policy_mgr_err("Invalid Context"); 9155 return allow; 9156 } 9157 policy_mgr_debug("check concurrency_csa vdev:%d ch %d bw %d, forced %d, reason %d", 9158 vdev_id, ch_freq, bw, forced, reason); 9159 9160 status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, 9161 &old_ch_freq); 9162 if (QDF_IS_STATUS_ERROR(status)) { 9163 policy_mgr_err("Failed to get channel for vdev:%d", 9164 vdev_id); 9165 return allow; 9166 } 9167 qdf_mem_zero(info, sizeof(info)); 9168 9169 /* 9170 * Store the connection's parameter and temporarily delete it 9171 * from the concurrency table. This way the allow concurrency 9172 * check can be used as though a new connection is coming up, 9173 * after check, restore the connection to concurrency table. 9174 * 9175 * In SAP+SAP SCC case, when LTE unsafe event processing, 9176 * we should remove the all SAP conn entry on the same ch before 9177 * do the concurrency check. Otherwise the left SAP on old channel 9178 * will cause the concurrency check failure because of dual beacon 9179 * MCC not supported. for the CSA request reason code, 9180 * PM_CSA_REASON_UNSAFE_CHANNEL, we remove all the SAP 9181 * entry on old channel before do concurrency check. 9182 * 9183 * The assumption is both SAP should move to the new channel later for 9184 * the reason code. 9185 */ 9186 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9187 9188 if (forced && (reason == CSA_REASON_UNSAFE_CHANNEL || 9189 reason == CSA_REASON_DCS)) 9190 policy_mgr_store_and_del_conn_info_by_chan_and_mode( 9191 psoc, old_ch_freq, mode, info, &num_cxn_del); 9192 else 9193 policy_mgr_store_and_del_conn_info_by_vdev_id( 9194 psoc, vdev_id, info, &num_cxn_del); 9195 9196 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 9197 WLAN_POLICY_MGR_ID); 9198 conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false); 9199 allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq, 9200 bw, conc_ext_flags, vdev_id); 9201 if (vdev) 9202 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 9203 9204 /* Restore the connection entry */ 9205 if (num_cxn_del > 0) 9206 policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); 9207 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9208 9209 if (!allow) 9210 policy_mgr_err("CSA concurrency check failed"); 9211 9212 return allow; 9213 } 9214 9215 /** 9216 * policy_mgr_get_concurrency_mode() - return concurrency mode 9217 * @psoc: PSOC object information 9218 * 9219 * This routine is used to retrieve concurrency mode 9220 * 9221 * Return: uint32_t value of concurrency mask 9222 */ 9223 uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc) 9224 { 9225 struct policy_mgr_psoc_priv_obj *pm_ctx; 9226 9227 pm_ctx = policy_mgr_get_context(psoc); 9228 if (!pm_ctx) { 9229 policy_mgr_err("Invalid context"); 9230 return QDF_STA_MASK; 9231 } 9232 9233 policy_mgr_debug("concurrency_mode: 0x%x", 9234 pm_ctx->concurrency_mode); 9235 9236 return pm_ctx->concurrency_mode; 9237 } 9238 9239 QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, 9240 struct policy_mgr_user_cfg *user_cfg) 9241 { 9242 9243 struct policy_mgr_psoc_priv_obj *pm_ctx; 9244 9245 pm_ctx = policy_mgr_get_context(psoc); 9246 if (!pm_ctx) { 9247 policy_mgr_err("Invalid context"); 9248 return QDF_STATUS_E_FAILURE; 9249 } 9250 if (!user_cfg) { 9251 policy_mgr_err("Invalid User Config"); 9252 return QDF_STATUS_E_FAILURE; 9253 } 9254 9255 pm_ctx->user_cfg = *user_cfg; 9256 policy_mgr_debug("dbs_selection_plcy 0x%x", 9257 pm_ctx->cfg.dbs_selection_plcy); 9258 policy_mgr_debug("vdev_priority_list 0x%x", 9259 pm_ctx->cfg.vdev_priority_list); 9260 pm_ctx->cur_conc_system_pref = pm_ctx->cfg.sys_pref; 9261 9262 return QDF_STATUS_SUCCESS; 9263 } 9264 9265 bool policy_mgr_will_freq_lead_to_mcc(struct wlan_objmgr_psoc *psoc, 9266 qdf_freq_t freq) 9267 { 9268 bool is_mcc = false; 9269 uint32_t conn_index; 9270 struct policy_mgr_psoc_priv_obj *pm_ctx; 9271 9272 pm_ctx = policy_mgr_get_context(psoc); 9273 if (!pm_ctx) { 9274 policy_mgr_err("Invalid Context"); 9275 return is_mcc; 9276 } 9277 9278 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9279 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9280 conn_index++) { 9281 if (pm_conc_connection_list[conn_index].in_use && 9282 policy_mgr_2_freq_always_on_same_mac(psoc, freq, 9283 pm_conc_connection_list[conn_index].freq)) { 9284 is_mcc = true; 9285 break; 9286 } 9287 } 9288 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9289 9290 return is_mcc; 9291 } 9292 9293 /** 9294 * policy_mgr_is_two_connection_mcc() - Check if MCC scenario 9295 * when there are two connections 9296 * @psoc: PSOC object information 9297 * 9298 * If if MCC scenario when there are two connections 9299 * 9300 * Return: true or false 9301 */ 9302 static bool policy_mgr_is_two_connection_mcc(struct wlan_objmgr_psoc *psoc) 9303 { 9304 return ((pm_conc_connection_list[0].freq != 9305 pm_conc_connection_list[1].freq) && 9306 (policy_mgr_are_2_freq_on_same_mac(psoc, 9307 pm_conc_connection_list[0].freq, 9308 pm_conc_connection_list[1].freq)) && 9309 (pm_conc_connection_list[0].freq <= 9310 WLAN_REG_MAX_24GHZ_CHAN_FREQ) && 9311 (pm_conc_connection_list[1].freq <= 9312 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false; 9313 } 9314 9315 /** 9316 * policy_mgr_is_three_connection_mcc() - Check if MCC scenario 9317 * when there are three connections 9318 * 9319 * If if MCC scenario when there are three connections 9320 * 9321 * Return: true or false 9322 */ 9323 static bool policy_mgr_is_three_connection_mcc(void) 9324 { 9325 return (((pm_conc_connection_list[0].freq != 9326 pm_conc_connection_list[1].freq) || 9327 (pm_conc_connection_list[0].freq != 9328 pm_conc_connection_list[2].freq) || 9329 (pm_conc_connection_list[1].freq != 9330 pm_conc_connection_list[2].freq)) && 9331 (pm_conc_connection_list[0].freq <= 9332 WLAN_REG_MAX_24GHZ_CHAN_FREQ) && 9333 (pm_conc_connection_list[1].freq <= 9334 WLAN_REG_MAX_24GHZ_CHAN_FREQ) && 9335 (pm_conc_connection_list[2].freq <= 9336 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false; 9337 } 9338 9339 uint32_t policy_mgr_get_conc_vdev_on_same_mac(struct wlan_objmgr_psoc *psoc, 9340 uint32_t vdev_id, uint8_t mac_id) 9341 { 9342 uint32_t id = WLAN_INVALID_VDEV_ID; 9343 uint32_t conn_index; 9344 struct policy_mgr_psoc_priv_obj *pm_ctx; 9345 9346 pm_ctx = policy_mgr_get_context(psoc); 9347 if (!pm_ctx) { 9348 policy_mgr_err("Invalid Context"); 9349 return id; 9350 } 9351 9352 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9353 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9354 conn_index++) { 9355 if ((pm_conc_connection_list[conn_index].in_use) && 9356 (pm_conc_connection_list[conn_index].vdev_id != vdev_id) && 9357 (pm_conc_connection_list[conn_index].mac == mac_id)) { 9358 id = pm_conc_connection_list[conn_index].vdev_id; 9359 break; 9360 } 9361 } 9362 9363 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9364 9365 return id; 9366 } 9367 9368 bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) 9369 { 9370 uint32_t num_connections = 0; 9371 bool is_24G_mcc = false; 9372 9373 num_connections = policy_mgr_get_connection_count(psoc); 9374 9375 switch (num_connections) { 9376 case 1: 9377 break; 9378 case 2: 9379 if (policy_mgr_is_two_connection_mcc(psoc)) 9380 is_24G_mcc = true; 9381 break; 9382 case 3: 9383 if (policy_mgr_is_three_connection_mcc()) 9384 is_24G_mcc = true; 9385 break; 9386 default: 9387 policy_mgr_err("unexpected num_connections value %d", 9388 num_connections); 9389 break; 9390 } 9391 9392 return is_24G_mcc; 9393 } 9394 9395 bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, 9396 uint8_t vdev_id, uint32_t ch_freq) 9397 { 9398 enum policy_mgr_con_mode mode; 9399 bool ret; 9400 struct policy_mgr_psoc_priv_obj *pm_ctx; 9401 struct wlan_objmgr_vdev *vdev; 9402 uint32_t conc_ext_flags; 9403 9404 pm_ctx = policy_mgr_get_context(psoc); 9405 if (!pm_ctx) { 9406 policy_mgr_err("Invalid Context"); 9407 return false; 9408 } 9409 9410 if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) { 9411 mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev( 9412 psoc, vdev_id); 9413 if (PM_MAX_NUM_OF_MODE == mode) { 9414 policy_mgr_err("Invalid mode"); 9415 return false; 9416 } 9417 } else 9418 return false; 9419 9420 if (ch_freq == 0) { 9421 policy_mgr_err("Invalid channel number 0"); 9422 return false; 9423 } 9424 9425 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 9426 WLAN_POLICY_MGR_ID); 9427 9428 /* Take care of 160MHz and 80+80Mhz later */ 9429 conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false); 9430 ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ, 9431 conc_ext_flags, vdev_id); 9432 if (vdev) 9433 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 9434 9435 if (false == ret) { 9436 policy_mgr_err("Connection failed due to conc check fail"); 9437 return 0; 9438 } 9439 9440 return true; 9441 } 9442 9443 /** 9444 * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval 9445 * @psoc: PSOC object information 9446 * @vdev_id: vdev id 9447 * @dev_mode: device mode 9448 * 9449 * Updates the beacon parameters of the GO in MCC scenario 9450 * 9451 * Return: Success or Failure depending on the overall function behavior 9452 */ 9453 QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( 9454 struct wlan_objmgr_psoc *psoc, 9455 uint8_t vdev_id, enum QDF_OPMODE dev_mode) 9456 { 9457 QDF_STATUS status; 9458 struct policy_mgr_psoc_priv_obj *pm_ctx; 9459 9460 pm_ctx = policy_mgr_get_context(psoc); 9461 if (!pm_ctx) { 9462 policy_mgr_err("Invalid context"); 9463 return QDF_STATUS_E_FAILURE; 9464 } 9465 9466 policy_mgr_debug("UPDATE Beacon Params"); 9467 9468 if (QDF_SAP_MODE == dev_mode) { 9469 if (pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval 9470 ) { 9471 status = pm_ctx->sme_cbacks. 9472 sme_change_mcc_beacon_interval(vdev_id); 9473 if (status == QDF_STATUS_E_FAILURE) { 9474 policy_mgr_err("Failed to update Beacon Params"); 9475 return QDF_STATUS_E_FAILURE; 9476 } 9477 } else { 9478 policy_mgr_err("sme_change_mcc_beacon_interval callback is NULL"); 9479 return QDF_STATUS_E_FAILURE; 9480 } 9481 } 9482 9483 return QDF_STATUS_SUCCESS; 9484 } 9485 9486 struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len) 9487 { 9488 struct policy_mgr_conc_connection_info *conn_ptr = 9489 &pm_conc_connection_list[0]; 9490 *len = MAX_NUMBER_OF_CONC_CONNECTIONS; 9491 9492 return conn_ptr; 9493 } 9494 9495 enum policy_mgr_con_mode 9496 policy_mgr_qdf_opmode_to_pm_con_mode(struct wlan_objmgr_psoc *psoc, 9497 enum QDF_OPMODE device_mode, 9498 uint8_t vdev_id) 9499 { 9500 enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE; 9501 9502 switch (device_mode) { 9503 case QDF_STA_MODE: 9504 mode = PM_STA_MODE; 9505 break; 9506 case QDF_P2P_CLIENT_MODE: 9507 mode = PM_P2P_CLIENT_MODE; 9508 break; 9509 case QDF_P2P_GO_MODE: 9510 mode = PM_P2P_GO_MODE; 9511 break; 9512 case QDF_SAP_MODE: 9513 #ifdef WLAN_FEATURE_LL_LT_SAP 9514 if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) 9515 mode = PM_LL_LT_SAP_MODE; 9516 else 9517 #endif 9518 mode = PM_SAP_MODE; 9519 break; 9520 case QDF_NAN_DISC_MODE: 9521 mode = PM_NAN_DISC_MODE; 9522 break; 9523 case QDF_NDI_MODE: 9524 mode = PM_NDI_MODE; 9525 break; 9526 default: 9527 policy_mgr_debug("Unsupported mode (%d)", 9528 device_mode); 9529 } 9530 9531 return mode; 9532 } 9533 9534 enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( 9535 enum policy_mgr_con_mode device_mode) 9536 { 9537 enum QDF_OPMODE mode = QDF_MAX_NO_OF_MODE; 9538 9539 switch (device_mode) { 9540 case PM_STA_MODE: 9541 mode = QDF_STA_MODE; 9542 break; 9543 case PM_SAP_MODE: 9544 case PM_LL_LT_SAP_MODE: 9545 mode = QDF_SAP_MODE; 9546 break; 9547 case PM_P2P_CLIENT_MODE: 9548 mode = QDF_P2P_CLIENT_MODE; 9549 break; 9550 case PM_P2P_GO_MODE: 9551 mode = QDF_P2P_GO_MODE; 9552 break; 9553 case PM_NAN_DISC_MODE: 9554 mode = QDF_NAN_DISC_MODE; 9555 break; 9556 case PM_NDI_MODE: 9557 mode = QDF_NDI_MODE; 9558 break; 9559 default: 9560 policy_mgr_debug("Unsupported policy mgr mode (%d)", 9561 device_mode); 9562 } 9563 return mode; 9564 } 9565 9566 QDF_STATUS policy_mgr_mode_specific_num_open_sessions( 9567 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, 9568 uint8_t *num_sessions) 9569 { 9570 struct policy_mgr_psoc_priv_obj *pm_ctx; 9571 9572 pm_ctx = policy_mgr_get_context(psoc); 9573 if (!pm_ctx) { 9574 policy_mgr_err("Invalid context"); 9575 return QDF_STATUS_E_FAILURE; 9576 } 9577 9578 *num_sessions = pm_ctx->no_of_open_sessions[mode]; 9579 return QDF_STATUS_SUCCESS; 9580 } 9581 9582 QDF_STATUS policy_mgr_mode_specific_num_active_sessions( 9583 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, 9584 uint8_t *num_sessions) 9585 { 9586 struct policy_mgr_psoc_priv_obj *pm_ctx; 9587 9588 pm_ctx = policy_mgr_get_context(psoc); 9589 if (!pm_ctx) { 9590 policy_mgr_err("Invalid context"); 9591 return QDF_STATUS_E_FAILURE; 9592 } 9593 9594 *num_sessions = pm_ctx->no_of_active_sessions[mode]; 9595 return QDF_STATUS_SUCCESS; 9596 } 9597 9598 /** 9599 * policy_mgr_concurrent_open_sessions_running() - Checks for 9600 * concurrent open session 9601 * @psoc: PSOC object information 9602 * 9603 * Checks if more than one open session is running for all the allowed modes 9604 * in the driver 9605 * 9606 * Return: True if more than one open session exists, False otherwise 9607 */ 9608 bool policy_mgr_concurrent_open_sessions_running( 9609 struct wlan_objmgr_psoc *psoc) 9610 { 9611 uint8_t i = 0; 9612 uint8_t j = 0; 9613 struct policy_mgr_psoc_priv_obj *pm_ctx; 9614 9615 pm_ctx = policy_mgr_get_context(psoc); 9616 if (!pm_ctx) { 9617 policy_mgr_err("Invalid context"); 9618 return false; 9619 } 9620 9621 for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) 9622 j += pm_ctx->no_of_open_sessions[i]; 9623 9624 return j > 1; 9625 } 9626 9627 /** 9628 * policy_mgr_concurrent_beaconing_sessions_running() - Checks 9629 * for concurrent beaconing entities 9630 * @psoc: PSOC object information 9631 * 9632 * Checks if multiple beaconing sessions are running i.e., if SAP or GO 9633 * are beaconing together 9634 * 9635 * Return: True if multiple entities are beaconing together, False otherwise 9636 */ 9637 bool policy_mgr_concurrent_beaconing_sessions_running( 9638 struct wlan_objmgr_psoc *psoc) 9639 { 9640 struct policy_mgr_psoc_priv_obj *pm_ctx; 9641 9642 pm_ctx = policy_mgr_get_context(psoc); 9643 if (!pm_ctx) { 9644 policy_mgr_err("Invalid context"); 9645 return false; 9646 } 9647 9648 return (pm_ctx->no_of_open_sessions[QDF_SAP_MODE] + 9649 pm_ctx->no_of_open_sessions[QDF_P2P_GO_MODE] 9650 > 1) ? true : false; 9651 } 9652 9653 9654 void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc) 9655 { 9656 uint8_t i = 0; 9657 struct policy_mgr_psoc_priv_obj *pm_ctx; 9658 9659 pm_ctx = policy_mgr_get_context(psoc); 9660 if (pm_ctx) { 9661 for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) 9662 pm_ctx->no_of_active_sessions[i] = 0; 9663 } 9664 } 9665 9666 bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc) 9667 { 9668 return policy_mgr_mode_specific_connection_count( 9669 psoc, PM_STA_MODE, NULL) > 1; 9670 } 9671 9672 bool policy_mgr_is_sta_present_on_dfs_channel(struct wlan_objmgr_psoc *psoc, 9673 uint8_t *vdev_id, 9674 qdf_freq_t *ch_freq, 9675 enum hw_mode_bandwidth *ch_width) 9676 { 9677 struct policy_mgr_conc_connection_info *conn_info; 9678 bool status = false; 9679 uint32_t conn_index = 0; 9680 struct policy_mgr_psoc_priv_obj *pm_ctx; 9681 9682 pm_ctx = policy_mgr_get_context(psoc); 9683 if (!pm_ctx) { 9684 policy_mgr_err("Invalid Context"); 9685 return false; 9686 } 9687 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9688 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9689 conn_index++) { 9690 conn_info = &pm_conc_connection_list[conn_index]; 9691 if (conn_info->in_use && 9692 (conn_info->mode == PM_STA_MODE || 9693 conn_info->mode == PM_P2P_CLIENT_MODE) && 9694 (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) || 9695 (wlan_reg_is_5ghz_ch_freq(conn_info->freq) && 9696 conn_info->bw == HW_MODE_160_MHZ))) { 9697 *vdev_id = conn_info->vdev_id; 9698 *ch_freq = pm_conc_connection_list[conn_index].freq; 9699 *ch_width = conn_info->bw; 9700 status = true; 9701 break; 9702 } 9703 } 9704 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9705 9706 return status; 9707 } 9708 9709 bool policy_mgr_is_sta_present_on_freq(struct wlan_objmgr_psoc *psoc, 9710 uint8_t *vdev_id, 9711 qdf_freq_t ch_freq, 9712 enum hw_mode_bandwidth *ch_width) 9713 { 9714 struct policy_mgr_conc_connection_info *conn_info; 9715 bool status = false; 9716 uint32_t conn_index = 0; 9717 struct policy_mgr_psoc_priv_obj *pm_ctx; 9718 9719 pm_ctx = policy_mgr_get_context(psoc); 9720 if (!pm_ctx) { 9721 policy_mgr_err("Invalid Context"); 9722 return false; 9723 } 9724 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9725 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9726 conn_index++) { 9727 conn_info = &pm_conc_connection_list[conn_index]; 9728 if (conn_info->in_use && 9729 (conn_info->mode == PM_STA_MODE || 9730 conn_info->mode == PM_P2P_CLIENT_MODE) && 9731 ch_freq == conn_info->freq) { 9732 *vdev_id = conn_info->vdev_id; 9733 *ch_width = conn_info->bw; 9734 status = true; 9735 break; 9736 } 9737 } 9738 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9739 9740 return status; 9741 } 9742 9743 bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc, 9744 uint8_t mac_id) 9745 { 9746 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 9747 uint32_t index, count; 9748 struct policy_mgr_psoc_priv_obj *pm_ctx; 9749 9750 pm_ctx = policy_mgr_get_context(psoc); 9751 if (!pm_ctx) { 9752 policy_mgr_err("Invalid Context"); 9753 return false; 9754 } 9755 9756 count = policy_mgr_mode_specific_connection_count( 9757 psoc, PM_STA_MODE, list); 9758 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9759 for (index = 0; index < count; index++) { 9760 if (mac_id == pm_conc_connection_list[list[index]].mac) { 9761 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9762 return true; 9763 } 9764 } 9765 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9766 9767 count = policy_mgr_mode_specific_connection_count( 9768 psoc, PM_P2P_CLIENT_MODE, list); 9769 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9770 for (index = 0; index < count; index++) { 9771 if (mac_id == pm_conc_connection_list[list[index]].mac) { 9772 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9773 return true; 9774 } 9775 } 9776 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9777 9778 return false; 9779 } 9780 9781 /** 9782 * policy_mgr_is_sta_active_connection_exists() - Check if a STA 9783 * connection is active 9784 * @psoc: PSOC object information 9785 * 9786 * Checks if there is atleast one active STA connection in the driver 9787 * 9788 * Return: True if an active STA session is present, False otherwise 9789 */ 9790 bool policy_mgr_is_sta_active_connection_exists( 9791 struct wlan_objmgr_psoc *psoc) 9792 { 9793 return (!policy_mgr_mode_specific_connection_count( 9794 psoc, PM_STA_MODE, NULL)) ? false : true; 9795 } 9796 9797 bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, 9798 uint32_t *ch_freq) 9799 { 9800 bool status = false; 9801 uint32_t conn_index = 0; 9802 struct policy_mgr_psoc_priv_obj *pm_ctx; 9803 9804 pm_ctx = policy_mgr_get_context(psoc); 9805 if (!pm_ctx) { 9806 policy_mgr_err("Invalid Context"); 9807 return false; 9808 } 9809 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9810 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9811 conn_index++) { 9812 if (pm_conc_connection_list[conn_index].in_use && 9813 !wlan_reg_is_dfs_for_freq(pm_ctx->pdev, 9814 pm_conc_connection_list[conn_index].freq)) { 9815 *ch_freq = pm_conc_connection_list[conn_index].freq; 9816 status = true; 9817 } 9818 } 9819 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9820 9821 return status; 9822 } 9823 9824 uint32_t policy_mgr_get_dfs_beaconing_session_id( 9825 struct wlan_objmgr_psoc *psoc) 9826 { 9827 uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; 9828 struct policy_mgr_conc_connection_info *conn_info; 9829 uint32_t conn_index = 0; 9830 struct policy_mgr_psoc_priv_obj *pm_ctx; 9831 9832 pm_ctx = policy_mgr_get_context(psoc); 9833 if (!pm_ctx) { 9834 policy_mgr_err("Invalid Context"); 9835 return session_id; 9836 } 9837 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9838 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9839 conn_index++) { 9840 conn_info = &pm_conc_connection_list[conn_index]; 9841 if (conn_info->in_use && 9842 WLAN_REG_IS_5GHZ_CH_FREQ(conn_info->freq) && 9843 (conn_info->ch_flagext & (IEEE80211_CHAN_DFS | 9844 IEEE80211_CHAN_DFS_CFREQ2)) && 9845 (conn_info->mode == PM_SAP_MODE || 9846 conn_info->mode == PM_P2P_GO_MODE)) { 9847 session_id = 9848 pm_conc_connection_list[conn_index].vdev_id; 9849 break; 9850 } 9851 } 9852 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9853 9854 return session_id; 9855 } 9856 9857 bool policy_mgr_is_any_dfs_beaconing_session_present( 9858 struct wlan_objmgr_psoc *psoc, qdf_freq_t *ch_freq, 9859 enum hw_mode_bandwidth *ch_width) 9860 { 9861 struct policy_mgr_conc_connection_info *conn_info; 9862 bool status = false; 9863 uint32_t conn_index = 0; 9864 struct policy_mgr_psoc_priv_obj *pm_ctx; 9865 9866 pm_ctx = policy_mgr_get_context(psoc); 9867 if (!pm_ctx) { 9868 policy_mgr_err("Invalid Context"); 9869 return false; 9870 } 9871 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 9872 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 9873 conn_index++) { 9874 conn_info = &pm_conc_connection_list[conn_index]; 9875 if (conn_info->in_use && 9876 (conn_info->mode == PM_SAP_MODE || 9877 conn_info->mode == PM_P2P_GO_MODE) && 9878 (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) || 9879 (wlan_reg_is_5ghz_ch_freq(conn_info->freq) && 9880 conn_info->bw == HW_MODE_160_MHZ))) { 9881 *ch_freq = pm_conc_connection_list[conn_index].freq; 9882 *ch_width = conn_info->bw; 9883 status = true; 9884 } 9885 } 9886 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 9887 9888 return status; 9889 } 9890 9891 bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc, 9892 qdf_freq_t *freq) 9893 { 9894 qdf_freq_t dfs_ch_frq = 0; 9895 qdf_freq_t dfs_sta_frq = 0; 9896 uint8_t vdev_id; 9897 enum hw_mode_bandwidth ch_width; 9898 enum hw_mode_bandwidth ch_sta_width; 9899 QDF_STATUS status; 9900 uint8_t sta_sap_scc_on_dfs_chnl; 9901 9902 policy_mgr_is_any_dfs_beaconing_session_present(psoc, &dfs_ch_frq, 9903 &ch_width); 9904 if (!dfs_ch_frq) 9905 return false; 9906 9907 *freq = dfs_ch_frq; 9908 9909 status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, 9910 &sta_sap_scc_on_dfs_chnl); 9911 if (QDF_IS_STATUS_ERROR(status)) 9912 return false; 9913 9914 if (policy_mgr_is_sta_present_on_dfs_channel(psoc, &vdev_id, 9915 &dfs_sta_frq, 9916 &ch_sta_width) && 9917 !policy_mgr_is_hw_dbs_capable(psoc) && 9918 sta_sap_scc_on_dfs_chnl != PM_STA_SAP_ON_DFS_DEFAULT) { 9919 policymgr_nofl_err("DFS STA present vdev_id %d ch_feq %d ch_width %d", 9920 vdev_id, dfs_sta_frq, ch_sta_width); 9921 return false; 9922 } 9923 9924 /* 9925 * 1) if agile & DFS scans are supported 9926 * 2) if hardware is DBS capable 9927 * 3) if current hw mode is non-dbs 9928 * if all above 3 conditions are true then don't skip any 9929 * channel from scan list 9930 */ 9931 if (policy_mgr_is_hw_dbs_capable(psoc) && 9932 !policy_mgr_is_current_hwmode_dbs(psoc) && 9933 policy_mgr_get_dbs_plus_agile_scan_config(psoc) && 9934 policy_mgr_get_single_mac_scan_with_dfs_config(psoc)) 9935 return false; 9936 9937 policy_mgr_debug("scan skip 5g chan due to dfs ap(ch %d / ch_width %d) present", 9938 dfs_ch_frq, ch_width); 9939 9940 return true; 9941 } 9942 9943 static void 9944 policy_mgr_fill_trim_chan(struct wlan_objmgr_pdev *pdev, 9945 void *object, void *arg) 9946 { 9947 struct wlan_objmgr_vdev *vdev = object; 9948 struct trim_chan_info *trim_info = arg; 9949 uint16_t sap_peer_count = 0; 9950 qdf_freq_t chan_freq; 9951 9952 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE) 9953 return; 9954 9955 if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) 9956 return; 9957 9958 sap_peer_count = wlan_vdev_get_peer_count(vdev); 9959 policy_mgr_debug("vdev %d - peer count %d", 9960 wlan_vdev_get_id(vdev), sap_peer_count); 9961 if (sap_peer_count <= 1) 9962 return; 9963 9964 chan_freq = wlan_get_operation_chan_freq(vdev); 9965 if (!chan_freq) 9966 return; 9967 9968 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) { 9969 trim_info->trim |= TRIM_CHANNEL_LIST_5G; 9970 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { 9971 if (trim_info->sap_count != 1) 9972 return; 9973 9974 if ((trim_info->band_capability & BIT(REG_BAND_5G)) == 9975 BIT(REG_BAND_5G)) 9976 return; 9977 9978 trim_info->trim |= TRIM_CHANNEL_LIST_24G; 9979 } 9980 } 9981 9982 uint16_t 9983 policy_mgr_scan_trim_chnls_for_connected_ap(struct wlan_objmgr_pdev *pdev) 9984 { 9985 struct trim_chan_info trim_info; 9986 struct wlan_objmgr_psoc *psoc; 9987 QDF_STATUS status; 9988 9989 psoc = wlan_pdev_get_psoc(pdev); 9990 if (!psoc) 9991 return TRIM_CHANNEL_LIST_NONE; 9992 9993 status = wlan_mlme_get_band_capability(psoc, 9994 &trim_info.band_capability); 9995 if (QDF_IS_STATUS_ERROR(status)) { 9996 policy_mgr_err("Could not get band capability"); 9997 return TRIM_CHANNEL_LIST_NONE; 9998 } 9999 10000 trim_info.sap_count = policy_mgr_mode_specific_connection_count(psoc, 10001 PM_SAP_MODE, NULL); 10002 if (!trim_info.sap_count) 10003 return TRIM_CHANNEL_LIST_NONE; 10004 10005 trim_info.trim = TRIM_CHANNEL_LIST_NONE; 10006 10007 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 10008 policy_mgr_fill_trim_chan, &trim_info, 10009 0, WLAN_POLICY_MGR_ID); 10010 policy_mgr_debug("band_capability %d, sap_count %d, trim %d", 10011 trim_info.band_capability, trim_info.sap_count, 10012 trim_info.trim); 10013 10014 return trim_info.trim; 10015 } 10016 10017 QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, 10018 enum policy_mgr_con_mode mode, 10019 uint8_t *nss_2g, uint8_t *nss_5g) 10020 { 10021 enum QDF_OPMODE dev_mode; 10022 struct policy_mgr_psoc_priv_obj *pm_ctx; 10023 10024 dev_mode = policy_mgr_get_qdf_mode_from_pm(mode); 10025 if (dev_mode == QDF_MAX_NO_OF_MODE) 10026 return QDF_STATUS_E_FAILURE; 10027 pm_ctx = policy_mgr_get_context(psoc); 10028 if (!pm_ctx) { 10029 policy_mgr_err("Invalid Context"); 10030 return QDF_STATUS_E_FAILURE; 10031 } 10032 10033 if (pm_ctx->sme_cbacks.sme_get_nss_for_vdev) { 10034 pm_ctx->sme_cbacks.sme_get_nss_for_vdev( 10035 dev_mode, nss_2g, nss_5g); 10036 10037 } else { 10038 policy_mgr_err("sme_get_nss_for_vdev callback is NULL"); 10039 return QDF_STATUS_E_FAILURE; 10040 } 10041 10042 return QDF_STATUS_SUCCESS; 10043 } 10044 10045 void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc) 10046 { 10047 uint32_t i; 10048 struct policy_mgr_psoc_priv_obj *pm_ctx; 10049 10050 pm_ctx = policy_mgr_get_context(psoc); 10051 if (!pm_ctx) { 10052 policy_mgr_err("Invalid Context"); 10053 return; 10054 } 10055 10056 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10057 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 10058 if (!pm_conc_connection_list[i].in_use) 10059 continue; 10060 policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d freq:%d orig chainmask:%d orig nss:%d bw:%d, ch_flags %0X", 10061 i, pm_conc_connection_list[i].in_use, 10062 pm_conc_connection_list[i].vdev_id, 10063 pm_conc_connection_list[i].mode, 10064 pm_conc_connection_list[i].mac, 10065 pm_conc_connection_list[i].freq, 10066 pm_conc_connection_list[i].chain_mask, 10067 pm_conc_connection_list[i].original_nss, 10068 pm_conc_connection_list[i].bw, 10069 pm_conc_connection_list[i].ch_flagext); 10070 } 10071 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10072 10073 policy_mgr_dump_freq_range(pm_ctx); 10074 policy_mgr_validate_conn_info(psoc); 10075 } 10076 10077 bool policy_mgr_is_any_mode_active_on_band_along_with_session( 10078 struct wlan_objmgr_psoc *psoc, 10079 uint8_t session_id, 10080 enum policy_mgr_band band) 10081 { 10082 uint32_t i; 10083 bool status = false; 10084 struct policy_mgr_psoc_priv_obj *pm_ctx; 10085 10086 pm_ctx = policy_mgr_get_context(psoc); 10087 if (!pm_ctx) { 10088 policy_mgr_err("Invalid Context"); 10089 status = false; 10090 goto send_status; 10091 } 10092 10093 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10094 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 10095 switch (band) { 10096 case POLICY_MGR_BAND_24: 10097 if ((pm_conc_connection_list[i].vdev_id != session_id) 10098 && (pm_conc_connection_list[i].in_use) && 10099 (WLAN_REG_IS_24GHZ_CH_FREQ( 10100 pm_conc_connection_list[i].freq))) { 10101 status = true; 10102 goto release_mutex_and_send_status; 10103 } 10104 break; 10105 case POLICY_MGR_BAND_5: 10106 if ((pm_conc_connection_list[i].vdev_id != session_id) 10107 && (pm_conc_connection_list[i].in_use) && 10108 (WLAN_REG_IS_5GHZ_CH_FREQ( 10109 pm_conc_connection_list[i].freq))) { 10110 status = true; 10111 goto release_mutex_and_send_status; 10112 } 10113 break; 10114 default: 10115 policy_mgr_err("Invalidband option:%d", band); 10116 status = false; 10117 goto release_mutex_and_send_status; 10118 } 10119 } 10120 release_mutex_and_send_status: 10121 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10122 send_status: 10123 return status; 10124 } 10125 10126 enum phy_ch_width 10127 policy_mgr_get_bw_by_session_id(struct wlan_objmgr_psoc *psoc, 10128 uint8_t session_id) 10129 { 10130 uint32_t i; 10131 struct policy_mgr_psoc_priv_obj *pm_ctx; 10132 enum hw_mode_bandwidth bw = HW_MODE_BW_NONE; 10133 10134 pm_ctx = policy_mgr_get_context(psoc); 10135 if (!pm_ctx) { 10136 policy_mgr_err("Invalid Context"); 10137 return CH_WIDTH_INVALID; 10138 } 10139 10140 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10141 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 10142 if (pm_conc_connection_list[i].vdev_id == session_id && 10143 pm_conc_connection_list[i].in_use) { 10144 bw = pm_conc_connection_list[i].bw; 10145 break; 10146 } 10147 } 10148 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10149 return policy_mgr_get_ch_width(bw); 10150 } 10151 10152 QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, 10153 uint8_t session_id, 10154 uint32_t *ch_freq) 10155 { 10156 uint32_t i; 10157 struct policy_mgr_psoc_priv_obj *pm_ctx; 10158 10159 pm_ctx = policy_mgr_get_context(psoc); 10160 if (!pm_ctx) { 10161 policy_mgr_err("Invalid Context"); 10162 return QDF_STATUS_E_FAILURE; 10163 } 10164 10165 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10166 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 10167 if ((pm_conc_connection_list[i].vdev_id == session_id) && 10168 (pm_conc_connection_list[i].in_use)) { 10169 *ch_freq = pm_conc_connection_list[i].freq; 10170 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10171 return QDF_STATUS_SUCCESS; 10172 } 10173 } 10174 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10175 10176 return QDF_STATUS_E_FAILURE; 10177 } 10178 10179 QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, 10180 uint8_t session_id, 10181 uint8_t *mac_id) 10182 { 10183 uint32_t i; 10184 struct policy_mgr_psoc_priv_obj *pm_ctx; 10185 10186 pm_ctx = policy_mgr_get_context(psoc); 10187 if (!pm_ctx) { 10188 policy_mgr_err("Invalid Context"); 10189 return QDF_STATUS_E_FAILURE; 10190 } 10191 10192 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10193 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 10194 if ((pm_conc_connection_list[i].vdev_id == session_id) && 10195 (pm_conc_connection_list[i].in_use)) { 10196 *mac_id = pm_conc_connection_list[i].mac; 10197 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10198 return QDF_STATUS_SUCCESS; 10199 } 10200 } 10201 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10202 10203 return QDF_STATUS_E_FAILURE; 10204 } 10205 10206 uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc, 10207 uint32_t *list, uint8_t mac_id) 10208 { 10209 uint32_t conn_index; 10210 uint32_t count = 0; 10211 struct policy_mgr_psoc_priv_obj *pm_ctx; 10212 10213 pm_ctx = policy_mgr_get_context(psoc); 10214 if (!pm_ctx) { 10215 policy_mgr_err("Invalid Context"); 10216 return count; 10217 } 10218 10219 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10220 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 10221 conn_index++) { 10222 if (pm_conc_connection_list[conn_index].mac == mac_id && 10223 pm_conc_connection_list[conn_index].in_use && 10224 policy_mgr_is_beaconing_mode( 10225 pm_conc_connection_list[conn_index].mode)) { 10226 if (list) 10227 list[count] = 10228 pm_conc_connection_list[conn_index].vdev_id; 10229 count++; 10230 } 10231 } 10232 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10233 10234 return count; 10235 } 10236 10237 uint32_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, 10238 uint8_t vdev_id) 10239 { 10240 uint8_t mcc_vdev_id; 10241 QDF_STATUS status; 10242 uint32_t ch_freq; 10243 10244 if (!policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id, &mcc_vdev_id)) { 10245 policy_mgr_debug("No concurrent MCC vdev for id:%d", vdev_id); 10246 return INVALID_CHANNEL_ID; 10247 } 10248 10249 status = policy_mgr_get_chan_by_session_id(psoc, mcc_vdev_id, &ch_freq); 10250 if (QDF_IS_STATUS_ERROR(status)) { 10251 policy_mgr_err("Failed to get channel for MCC vdev:%d", 10252 mcc_vdev_id); 10253 return INVALID_CHANNEL_ID; 10254 } 10255 10256 return ch_freq; 10257 } 10258 10259 bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) 10260 { 10261 bool roffchan; 10262 10263 if (!vdev) { 10264 policy_mgr_err("Invalid parameter"); 10265 return false; 10266 } 10267 10268 roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); 10269 10270 if (roffchan) 10271 policy_mgr_debug("Restrict offchannel is set"); 10272 10273 return roffchan; 10274 } 10275 10276 QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, 10277 uint32_t ch_freq, bool *ok) 10278 { 10279 uint32_t cc_count = 0, i; 10280 uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 10281 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; 10282 struct wlan_objmgr_vdev *vdev; 10283 10284 if (!ok) { 10285 policy_mgr_err("Invalid parameter"); 10286 return QDF_STATUS_E_INVAL; 10287 } 10288 10289 cc_count = policy_mgr_get_sap_mode_info(psoc, 10290 &op_ch_freq_list[cc_count], 10291 &vdev_id[cc_count]); 10292 10293 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) 10294 cc_count = cc_count + 10295 policy_mgr_get_mode_specific_conn_info( 10296 psoc, &op_ch_freq_list[cc_count], 10297 &vdev_id[cc_count], PM_P2P_GO_MODE); 10298 10299 if (!cc_count) { 10300 *ok = true; 10301 return QDF_STATUS_SUCCESS; 10302 } 10303 10304 if (!ch_freq) { 10305 policy_mgr_err("channel is 0, cc count %d", cc_count); 10306 return QDF_STATUS_E_INVAL; 10307 } 10308 10309 if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) { 10310 for (i = 0; i < cc_count; i++) { 10311 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 10312 psoc, vdev_id[i], WLAN_POLICY_MGR_ID); 10313 if (!vdev) { 10314 policy_mgr_err("vdev for vdev_id:%d is NULL", 10315 vdev_id[i]); 10316 return QDF_STATUS_E_INVAL; 10317 } 10318 10319 /** 10320 * If channel passed is same as AP/GO operating 10321 * channel, return true. 10322 * 10323 * If channel is different from operating channel but 10324 * in same band, return false. 10325 * 10326 * If operating channel in different band 10327 * (DBS capable), return true. 10328 * 10329 * If operating channel in different band 10330 * (not DBS capable), return false. 10331 */ 10332 /* TODO: To be enhanced for SBS */ 10333 if (policy_mgr_is_dnsc_set(vdev)) { 10334 if (op_ch_freq_list[i] == ch_freq) { 10335 *ok = true; 10336 wlan_objmgr_vdev_release_ref( 10337 vdev, 10338 WLAN_POLICY_MGR_ID); 10339 break; 10340 } else if (WLAN_REG_IS_SAME_BAND_FREQS( 10341 op_ch_freq_list[i], ch_freq)) { 10342 *ok = false; 10343 wlan_objmgr_vdev_release_ref( 10344 vdev, 10345 WLAN_POLICY_MGR_ID); 10346 break; 10347 } else if (policy_mgr_is_hw_dbs_capable(psoc)) { 10348 *ok = true; 10349 wlan_objmgr_vdev_release_ref( 10350 vdev, 10351 WLAN_POLICY_MGR_ID); 10352 break; 10353 } else { 10354 *ok = false; 10355 wlan_objmgr_vdev_release_ref( 10356 vdev, 10357 WLAN_POLICY_MGR_ID); 10358 break; 10359 } 10360 } else { 10361 *ok = true; 10362 } 10363 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 10364 } 10365 } 10366 10367 return QDF_STATUS_SUCCESS; 10368 } 10369 10370 void policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc *psoc, 10371 struct dbs_bw *bw_dbs) 10372 { 10373 uint32_t dbs, sbs, i, param; 10374 struct policy_mgr_psoc_priv_obj *pm_ctx; 10375 10376 pm_ctx = policy_mgr_get_context(psoc); 10377 if (!pm_ctx) { 10378 policy_mgr_err("Invalid Context"); 10379 return; 10380 } 10381 10382 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 10383 param = pm_ctx->hw_mode.hw_mode_list[i]; 10384 dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); 10385 sbs = POLICY_MGR_HW_MODE_SBS_MODE_GET(param); 10386 10387 if (!dbs && !sbs) 10388 bw_dbs->mac0_bw = 10389 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param); 10390 10391 if (dbs) { 10392 bw_dbs->mac0_bw = 10393 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param); 10394 bw_dbs->mac1_bw = 10395 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param); 10396 } else { 10397 continue; 10398 } 10399 } 10400 } 10401 10402 uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, 10403 struct dbs_nss *nss_dbs) 10404 { 10405 int i, param; 10406 uint32_t dbs, sbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1; 10407 uint32_t min_mac0_rf_chains, min_mac1_rf_chains; 10408 uint32_t max_rf_chains, final_max_rf_chains = HW_MODE_SS_0x0; 10409 struct policy_mgr_psoc_priv_obj *pm_ctx; 10410 10411 pm_ctx = policy_mgr_get_context(psoc); 10412 if (!pm_ctx) { 10413 policy_mgr_err("Invalid Context"); 10414 return final_max_rf_chains; 10415 } 10416 10417 nss_dbs->single_mac0_band_cap = 0; 10418 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { 10419 param = pm_ctx->hw_mode.hw_mode_list[i]; 10420 dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); 10421 sbs = POLICY_MGR_HW_MODE_SBS_MODE_GET(param); 10422 10423 if (!dbs && !sbs && !nss_dbs->single_mac0_band_cap) 10424 nss_dbs->single_mac0_band_cap = 10425 POLICY_MGR_HW_MODE_MAC0_BAND_GET(param); 10426 10427 if (dbs) { 10428 tx_chain0 10429 = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param); 10430 rx_chain0 10431 = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param); 10432 10433 tx_chain1 10434 = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param); 10435 rx_chain1 10436 = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param); 10437 10438 min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0); 10439 min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1); 10440 10441 max_rf_chains 10442 = QDF_MAX(min_mac0_rf_chains, min_mac1_rf_chains); 10443 10444 if (final_max_rf_chains < max_rf_chains) { 10445 final_max_rf_chains 10446 = (max_rf_chains == 2) 10447 ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; 10448 10449 nss_dbs->mac0_ss 10450 = (min_mac0_rf_chains == 2) 10451 ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; 10452 10453 nss_dbs->mac1_ss 10454 = (min_mac1_rf_chains == 2) 10455 ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; 10456 } 10457 } else { 10458 continue; 10459 } 10460 } 10461 10462 return final_max_rf_chains; 10463 } 10464 10465 bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc) 10466 { 10467 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN; 10468 10469 policy_mgr_get_dual_mac_feature(psoc, &dual_mac_feature); 10470 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) || 10471 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN) || 10472 (dual_mac_feature == 10473 ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN) || 10474 !policy_mgr_is_hw_dbs_capable(psoc)) 10475 return false; 10476 10477 return true; 10478 } 10479 10480 void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc, 10481 uint8_t conc_system_pref) 10482 { 10483 struct policy_mgr_psoc_priv_obj *pm_ctx; 10484 10485 pm_ctx = policy_mgr_get_context(psoc); 10486 10487 if (!pm_ctx) { 10488 policy_mgr_err("Invalid Context"); 10489 return; 10490 } 10491 10492 policy_mgr_debug("conc_system_pref %hu", conc_system_pref); 10493 pm_ctx->cur_conc_system_pref = conc_system_pref; 10494 } 10495 10496 uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc) 10497 { 10498 struct policy_mgr_psoc_priv_obj *pm_ctx; 10499 10500 pm_ctx = policy_mgr_get_context(psoc); 10501 if (!pm_ctx) { 10502 policy_mgr_err("Invalid Context"); 10503 return PM_THROUGHPUT; 10504 } 10505 10506 policy_mgr_debug("conc_system_pref %hu", pm_ctx->cur_conc_system_pref); 10507 return pm_ctx->cur_conc_system_pref; 10508 } 10509 10510 QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( 10511 struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, 10512 uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini, 10513 uint32_t channel_select_logic_conc) 10514 { 10515 struct policy_mgr_psoc_priv_obj *pm_ctx; 10516 10517 pm_ctx = policy_mgr_get_context(psoc); 10518 if (!pm_ctx) { 10519 policy_mgr_err("Invalid Context"); 10520 return QDF_STATUS_E_FAILURE; 10521 } 10522 10523 *scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; 10524 *fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config; 10525 switch (dual_mac_disable_ini) { 10526 case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF: 10527 policy_mgr_debug("dual_mac_disable_ini:%d async/dbs off", 10528 dual_mac_disable_ini); 10529 WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0); 10530 WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0); 10531 break; 10532 case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN: 10533 policy_mgr_debug("dual_mac_disable_ini:%d dbs_cxn off", 10534 dual_mac_disable_ini); 10535 WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0); 10536 break; 10537 case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF: 10538 policy_mgr_debug("dual_mac_disable_ini:%d async off", 10539 dual_mac_disable_ini); 10540 WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0); 10541 break; 10542 case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN: 10543 policy_mgr_debug("dual_mac_disable_ini:%d ", 10544 dual_mac_disable_ini); 10545 WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, 0); 10546 break; 10547 default: 10548 break; 10549 } 10550 10551 WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_STA_SET(*fw_mode_config, 10552 PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(channel_select_logic_conc)); 10553 WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_P2P_SET(*fw_mode_config, 10554 PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(channel_select_logic_conc)); 10555 10556 policy_mgr_debug("*scan_config:%x ", *scan_config); 10557 policy_mgr_debug("*fw_mode_config:%x ", *fw_mode_config); 10558 10559 return QDF_STATUS_SUCCESS; 10560 } 10561 10562 bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) 10563 { 10564 struct policy_mgr_psoc_priv_obj *pm_ctx; 10565 10566 pm_ctx = policy_mgr_get_context(psoc); 10567 if (!pm_ctx) { 10568 policy_mgr_err("Invalid Context"); 10569 return 0; 10570 } 10571 10572 return ((pm_ctx->cfg.mcc_to_scc_switch == 10573 QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) || 10574 (pm_ctx->cfg.mcc_to_scc_switch == 10575 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) || 10576 (pm_ctx->cfg.mcc_to_scc_switch == 10577 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) || 10578 (pm_ctx->cfg.mcc_to_scc_switch == 10579 QDF_MCC_TO_SCC_WITH_PREFERRED_BAND)); 10580 } 10581 10582 bool policy_mgr_is_sap_allowed_on_dfs_freq(struct wlan_objmgr_pdev *pdev, 10583 uint8_t vdev_id, qdf_freq_t ch_freq) 10584 { 10585 struct wlan_objmgr_psoc *psoc; 10586 uint32_t sta_sap_scc_on_dfs_chan; 10587 uint32_t sta_cnt, gc_cnt; 10588 10589 psoc = wlan_pdev_get_psoc(pdev); 10590 if (!psoc) 10591 return false; 10592 10593 sta_sap_scc_on_dfs_chan = 10594 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 10595 sta_cnt = policy_mgr_mode_specific_connection_count(psoc, 10596 PM_STA_MODE, NULL); 10597 gc_cnt = policy_mgr_mode_specific_connection_count(psoc, 10598 PM_P2P_CLIENT_MODE, NULL); 10599 10600 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u, gc_cnt %u", 10601 sta_sap_scc_on_dfs_chan, sta_cnt, gc_cnt); 10602 10603 /* if sta_sap_scc_on_dfs_chan ini is set, DFS master capability is 10604 * assumed disabled in the driver. 10605 */ 10606 if ((wlan_reg_get_channel_state_for_pwrmode( 10607 pdev, ch_freq, REG_CURRENT_PWR_MODE) == CHANNEL_STATE_DFS) && 10608 !sta_cnt && !gc_cnt && sta_sap_scc_on_dfs_chan && 10609 !policy_mgr_get_dfs_master_dynamic_enabled(psoc, vdev_id)) { 10610 policy_mgr_err("SAP not allowed on DFS channel if no dfs master capability!!"); 10611 return false; 10612 } 10613 10614 return true; 10615 } 10616 10617 bool 10618 policy_mgr_is_sap_go_interface_allowed_on_indoor(struct wlan_objmgr_pdev *pdev, 10619 uint8_t vdev_id, 10620 qdf_freq_t ch_freq) 10621 { 10622 struct wlan_objmgr_psoc *psoc; 10623 bool is_scc = false, indoor_support = false; 10624 enum QDF_OPMODE mode; 10625 10626 psoc = wlan_pdev_get_psoc(pdev); 10627 if (!psoc) 10628 return true; 10629 10630 if (!wlan_reg_is_freq_indoor(pdev, ch_freq)) 10631 return true; 10632 10633 is_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq); 10634 mode = wlan_get_opmode_from_vdev_id(pdev, vdev_id); 10635 ucfg_mlme_get_indoor_channel_support(psoc, &indoor_support); 10636 10637 /* 10638 * Rules for indoor operation: 10639 * If gindoor_channel_support is enabled - Allow SAP/GO 10640 * If gindoor_channel_support is disabled 10641 * a) Restrict 6 GHz SAP 10642 * b) Restrict standalone 5 GHz SAP 10643 * 10644 * If p2p_go_on_5ghz_indoor_chan is enabled - Allow GO 10645 * with or without concurrency 10646 * 10647 * If sta_sap_scc_on_indoor_chan is enabled - Allow 10648 * SAP/GO with concurrent STA in indoor SCC 10649 * 10650 * Restrict all other operations on indoor 10651 */ 10652 10653 if (indoor_support) 10654 return true; 10655 10656 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) { 10657 policy_mgr_rl_debug("SAP operation is not allowed on 6 GHz indoor channel"); 10658 return false; 10659 } 10660 10661 if (mode == QDF_SAP_MODE) { 10662 if (is_scc && 10663 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc)) 10664 return true; 10665 policy_mgr_rl_debug("SAP operation is not allowed on indoor channel"); 10666 return false; 10667 } 10668 10669 if (mode == QDF_P2P_GO_MODE) { 10670 if (ucfg_p2p_get_indoor_ch_support(psoc) || 10671 (is_scc && 10672 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc))) 10673 return true; 10674 policy_mgr_rl_debug("GO operation is not allowed on indoor channel"); 10675 return false; 10676 } 10677 10678 policy_mgr_rl_debug("SAP operation is not allowed on indoor channel"); 10679 return false; 10680 } 10681 10682 bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( 10683 struct wlan_objmgr_psoc *psoc) 10684 { 10685 struct policy_mgr_psoc_priv_obj *pm_ctx; 10686 uint8_t sta_sap_scc_on_dfs_chnl = 0; 10687 bool status = false; 10688 10689 pm_ctx = policy_mgr_get_context(psoc); 10690 if (!pm_ctx) { 10691 policy_mgr_err("Invalid Context"); 10692 return status; 10693 } 10694 10695 policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, 10696 &sta_sap_scc_on_dfs_chnl); 10697 if (policy_mgr_is_force_scc(psoc) && sta_sap_scc_on_dfs_chnl) 10698 status = true; 10699 10700 return status; 10701 } 10702 10703 bool policy_mgr_is_multi_sap_allowed_on_same_band( 10704 struct wlan_objmgr_pdev *pdev, 10705 enum policy_mgr_con_mode mode, 10706 qdf_freq_t ch_freq) 10707 { 10708 struct wlan_objmgr_psoc *psoc; 10709 struct policy_mgr_psoc_priv_obj *pm_ctx; 10710 bool multi_sap_allowed_on_same_band; 10711 QDF_STATUS status; 10712 10713 psoc = wlan_pdev_get_psoc(pdev); 10714 if (!psoc) 10715 return false; 10716 10717 pm_ctx = policy_mgr_get_context(psoc); 10718 if (!pm_ctx) { 10719 policy_mgr_err("Invalid Context"); 10720 return false; 10721 } 10722 10723 if (!ch_freq || !policy_mgr_is_sap_mode(mode)) 10724 return true; 10725 10726 status = policy_mgr_get_multi_sap_allowed_on_same_band(psoc, 10727 &multi_sap_allowed_on_same_band); 10728 if (!QDF_IS_STATUS_SUCCESS(status)) { 10729 policy_mgr_err("Failed to get multi_sap_allowed_on_same_band"); 10730 /* Allow multi SAPs started on same band by default. */ 10731 multi_sap_allowed_on_same_band = true; 10732 } 10733 if (!multi_sap_allowed_on_same_band) { 10734 uint32_t ap_cnt, index = 0; 10735 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 10736 struct policy_mgr_conc_connection_info *ap_info; 10737 10738 ap_cnt = policy_mgr_get_sap_mode_count(psoc, list); 10739 if (!ap_cnt) 10740 return true; 10741 10742 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10743 while (index < ap_cnt) { 10744 ap_info = &pm_conc_connection_list[list[index]]; 10745 if (WLAN_REG_IS_SAME_BAND_FREQS(ch_freq, 10746 ap_info->freq)) { 10747 policy_mgr_rl_debug("Don't allow SAP on same band"); 10748 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10749 return false; 10750 } 10751 index++; 10752 } 10753 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10754 } 10755 10756 return true; 10757 } 10758 10759 bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc, 10760 enum policy_mgr_con_mode mode) 10761 { 10762 struct policy_mgr_psoc_priv_obj *pm_ctx; 10763 uint32_t conn_index; 10764 bool ret = false; 10765 10766 pm_ctx = policy_mgr_get_context(psoc); 10767 if (!pm_ctx) { 10768 policy_mgr_err("Invalid Context"); 10769 return ret; 10770 } 10771 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10772 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 10773 conn_index++) { 10774 if (pm_conc_connection_list[conn_index].mode == mode && 10775 pm_conc_connection_list[conn_index].freq >= 10776 WLAN_REG_MIN_5GHZ_CHAN_FREQ && 10777 pm_conc_connection_list[conn_index].in_use) 10778 ret = true; 10779 } 10780 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10781 10782 return ret; 10783 } 10784 10785 bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc) 10786 { 10787 struct policy_mgr_psoc_priv_obj *pm_ctx; 10788 uint32_t conn_index; 10789 bool ret = false; 10790 10791 pm_ctx = policy_mgr_get_context(psoc); 10792 if (!pm_ctx) { 10793 policy_mgr_err("Invalid Context"); 10794 return ret; 10795 } 10796 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10797 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 10798 conn_index++) { 10799 if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE && 10800 pm_conc_connection_list[conn_index].freq <= 10801 WLAN_REG_MAX_24GHZ_CHAN_FREQ && 10802 pm_conc_connection_list[conn_index].in_use) 10803 ret = true; 10804 } 10805 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10806 10807 return ret; 10808 } 10809 10810 bool 10811 policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc *psoc, qdf_freq_t *freq) 10812 { 10813 struct policy_mgr_psoc_priv_obj *pm_ctx; 10814 uint32_t conn_index; 10815 bool ret = false; 10816 10817 pm_ctx = policy_mgr_get_context(psoc); 10818 if (!pm_ctx) { 10819 policy_mgr_err("Invalid Context"); 10820 return ret; 10821 } 10822 10823 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10824 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 10825 conn_index++) { 10826 *freq = pm_conc_connection_list[conn_index].freq; 10827 if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE && 10828 WLAN_REG_IS_5GHZ_CH_FREQ(*freq) && 10829 pm_conc_connection_list[conn_index].in_use) { 10830 ret = true; 10831 break; 10832 } 10833 } 10834 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10835 10836 return ret; 10837 } 10838 10839 uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, 10840 struct connection_info *info) 10841 { 10842 struct policy_mgr_psoc_priv_obj *pm_ctx; 10843 uint32_t conn_index, count = 0; 10844 10845 pm_ctx = policy_mgr_get_context(psoc); 10846 if (!pm_ctx) { 10847 policy_mgr_err("Invalid Context"); 10848 return count; 10849 } 10850 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 10851 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 10852 conn_index++) { 10853 if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 10854 info[count].vdev_id = 10855 pm_conc_connection_list[conn_index].vdev_id; 10856 info[count].mac_id = 10857 pm_conc_connection_list[conn_index].mac; 10858 info[count].channel = wlan_reg_freq_to_chan( 10859 pm_ctx->pdev, 10860 pm_conc_connection_list[conn_index].freq); 10861 info[count].ch_freq = 10862 pm_conc_connection_list[conn_index].freq; 10863 count++; 10864 } 10865 } 10866 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 10867 10868 return count; 10869 } 10870 10871 bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, 10872 enum policy_mgr_con_mode mode, 10873 uint32_t ch_freq, 10874 uint32_t vdev_id) 10875 { 10876 enum policy_mgr_con_mode con_mode; 10877 int id; 10878 uint32_t vdev, con_freq; 10879 bool dbs; 10880 10881 if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE) 10882 return true; 10883 dbs = policy_mgr_is_hw_dbs_capable(psoc); 10884 for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) { 10885 if (!pm_conc_connection_list[id].in_use) 10886 continue; 10887 vdev = pm_conc_connection_list[id].vdev_id; 10888 if (vdev_id == vdev) 10889 continue; 10890 con_mode = pm_conc_connection_list[id].mode; 10891 if (con_mode != PM_SAP_MODE && con_mode != PM_P2P_GO_MODE) 10892 continue; 10893 con_freq = pm_conc_connection_list[id].freq; 10894 10895 if (policy_mgr_is_p2p_p2p_conc_supported(psoc) && 10896 (mode == PM_P2P_GO_MODE) && (con_mode == PM_P2P_GO_MODE)) { 10897 policy_mgr_debug("GO+GO scc is allowed freq = %d ", 10898 ch_freq); 10899 return true; 10900 } 10901 10902 if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc) && 10903 (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && 10904 (con_mode == PM_SAP_MODE || con_mode == PM_P2P_GO_MODE)) 10905 return true; 10906 10907 if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) && 10908 (ch_freq == con_freq)) { 10909 policy_mgr_debug("SCC enabled, 2 AP on same channel, allow 2nd AP"); 10910 return true; 10911 } 10912 if (!dbs) { 10913 policy_mgr_debug("DBS unsupported, mcc and scc unsupported too, don't allow 2nd AP"); 10914 return false; 10915 } 10916 10917 if (policy_mgr_are_2_freq_on_same_mac(psoc, ch_freq, 10918 con_freq)) { 10919 policy_mgr_debug("DBS supported, 2 SAP on same band, reject 2nd AP"); 10920 return false; 10921 } 10922 } 10923 10924 /* Don't block the second interface */ 10925 return true; 10926 } 10927 10928 bool policy_mgr_dual_beacon_on_single_mac_scc_capable( 10929 struct wlan_objmgr_psoc *psoc) 10930 { 10931 struct wmi_unified *wmi_handle; 10932 10933 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 10934 if (!wmi_handle) { 10935 policy_mgr_debug("Invalid WMI handle"); 10936 return false; 10937 } 10938 10939 if (wmi_service_enabled( 10940 wmi_handle, 10941 wmi_service_dual_beacon_on_single_mac_scc_support)) { 10942 policy_mgr_debug("Dual beaconing on same channel on single MAC supported"); 10943 return true; 10944 } 10945 policy_mgr_debug("Dual beaconing on same channel on single MAC is not supported"); 10946 return false; 10947 } 10948 10949 bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( 10950 struct wlan_objmgr_psoc *psoc) 10951 { 10952 struct wmi_unified *wmi_handle; 10953 10954 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 10955 if (!wmi_handle) { 10956 policy_mgr_debug("Invalid WMI handle"); 10957 return false; 10958 } 10959 10960 if (wmi_service_enabled( 10961 wmi_handle, 10962 wmi_service_dual_beacon_on_single_mac_mcc_support)) { 10963 policy_mgr_debug("Dual beaconing on different channel on single MAC supported"); 10964 return true; 10965 } 10966 policy_mgr_debug("Dual beaconing on different channel on single MAC is not supported"); 10967 return false; 10968 } 10969 10970 bool policy_mgr_sta_sap_scc_on_lte_coex_chan( 10971 struct wlan_objmgr_psoc *psoc) 10972 { 10973 struct policy_mgr_psoc_priv_obj *pm_ctx; 10974 uint8_t scc_lte_coex = 0; 10975 10976 pm_ctx = policy_mgr_get_context(psoc); 10977 if (!pm_ctx) { 10978 policy_mgr_err("Invalid Context"); 10979 return false; 10980 } 10981 policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_lte_coex); 10982 10983 return scc_lte_coex; 10984 } 10985 10986 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) 10987 void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, 10988 uint8_t vdev_id, 10989 enum conn_6ghz_flag ap_6ghz_capable) 10990 { 10991 struct policy_mgr_conc_connection_info *conn_info; 10992 uint32_t conn_index; 10993 struct policy_mgr_psoc_priv_obj *pm_ctx; 10994 enum conn_6ghz_flag conn_6ghz_flag = 0; 10995 10996 pm_ctx = policy_mgr_get_context(psoc); 10997 if (!pm_ctx) { 10998 policy_mgr_err("Invalid Context"); 10999 return; 11000 } 11001 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11002 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11003 conn_index++) { 11004 conn_info = &pm_conc_connection_list[conn_index]; 11005 if (conn_info->in_use && 11006 policy_mgr_is_sap_mode(conn_info->mode) && 11007 vdev_id == conn_info->vdev_id) { 11008 conn_info->conn_6ghz_flag = ap_6ghz_capable; 11009 conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID; 11010 conn_6ghz_flag = conn_info->conn_6ghz_flag; 11011 break; 11012 } 11013 } 11014 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11015 policy_mgr_debug("vdev %d init conn_6ghz_flag %x new %x", 11016 vdev_id, ap_6ghz_capable, conn_6ghz_flag); 11017 } 11018 11019 void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, 11020 uint8_t vdev_id, 11021 bool set, 11022 enum conn_6ghz_flag ap_6ghz_capable) 11023 { 11024 struct policy_mgr_conc_connection_info *conn_info; 11025 uint32_t conn_index; 11026 struct policy_mgr_psoc_priv_obj *pm_ctx; 11027 enum conn_6ghz_flag conn_6ghz_flag = 0; 11028 11029 pm_ctx = policy_mgr_get_context(psoc); 11030 if (!pm_ctx) { 11031 policy_mgr_err("Invalid Context"); 11032 return; 11033 } 11034 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11035 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11036 conn_index++) { 11037 conn_info = &pm_conc_connection_list[conn_index]; 11038 if (conn_info->in_use && 11039 policy_mgr_is_beaconing_mode(conn_info->mode) && 11040 policy_mgr_is_6ghz_conc_mode_supported( 11041 psoc, conn_info->mode) && 11042 vdev_id == conn_info->vdev_id) { 11043 if (set) 11044 conn_info->conn_6ghz_flag |= ap_6ghz_capable; 11045 else 11046 conn_info->conn_6ghz_flag &= ~ap_6ghz_capable; 11047 conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID; 11048 conn_6ghz_flag = conn_info->conn_6ghz_flag; 11049 break; 11050 } 11051 } 11052 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11053 policy_mgr_debug("vdev %d %s conn_6ghz_flag %x new %x", 11054 vdev_id, set ? "set" : "clr", 11055 ap_6ghz_capable, conn_6ghz_flag); 11056 } 11057 11058 bool policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, 11059 uint8_t vdev_id, 11060 uint32_t *conn_flag) 11061 { 11062 struct policy_mgr_conc_connection_info *conn_info; 11063 uint32_t conn_index; 11064 struct policy_mgr_psoc_priv_obj *pm_ctx; 11065 enum conn_6ghz_flag conn_6ghz_flag = 0; 11066 bool is_6g_allowed = false; 11067 11068 if (conn_flag) 11069 *conn_flag = 0; 11070 pm_ctx = policy_mgr_get_context(psoc); 11071 if (!pm_ctx) { 11072 policy_mgr_err("Invalid Context"); 11073 return false; 11074 } 11075 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11076 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11077 conn_index++) { 11078 conn_info = &pm_conc_connection_list[conn_index]; 11079 if (conn_info->in_use && 11080 policy_mgr_is_beaconing_mode(conn_info->mode) && 11081 policy_mgr_is_6ghz_conc_mode_supported( 11082 psoc, conn_info->mode) && 11083 vdev_id == conn_info->vdev_id) { 11084 conn_6ghz_flag = conn_info->conn_6ghz_flag; 11085 break; 11086 } 11087 } 11088 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11089 11090 /* If the vdev connection is not active, policy mgr will query legacy 11091 * hdd to get sap acs and security information. 11092 * The assumption is no legacy client connected for non active 11093 * connection. 11094 */ 11095 if (!(conn_6ghz_flag & CONN_6GHZ_FLAG_VALID) && 11096 pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable) 11097 conn_6ghz_flag = pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable( 11098 psoc, vdev_id) | 11099 CONN_6GHZ_FLAG_NO_LEGACY_CLIENT; 11100 11101 if ((conn_6ghz_flag & CONN_6GHZ_CAPABLE) == CONN_6GHZ_CAPABLE) 11102 is_6g_allowed = true; 11103 policy_mgr_debug("vdev %d conn_6ghz_flag %x 6ghz %s", vdev_id, 11104 conn_6ghz_flag, is_6g_allowed ? "allowed" : "deny"); 11105 if (conn_flag) 11106 *conn_flag = conn_6ghz_flag; 11107 11108 return is_6g_allowed; 11109 } 11110 #endif 11111 11112 bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, 11113 uint32_t ch_freq) 11114 { 11115 uint32_t sta_sap_scc_on_dfs_chan, sta_sap_scc_allowed_on_indoor_chan; 11116 uint32_t sap_count; 11117 enum channel_state state; 11118 struct policy_mgr_psoc_priv_obj *pm_ctx; 11119 11120 pm_ctx = policy_mgr_get_context(psoc); 11121 if (!pm_ctx) { 11122 policy_mgr_err("Invalid Context"); 11123 return false; 11124 } 11125 11126 sta_sap_scc_on_dfs_chan = 11127 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 11128 sta_sap_scc_allowed_on_indoor_chan = 11129 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 11130 11131 sap_count = policy_mgr_mode_specific_connection_count(psoc, 11132 PM_SAP_MODE, 11133 NULL); 11134 state = wlan_reg_get_channel_state_for_pwrmode(pm_ctx->pdev, ch_freq, 11135 REG_CURRENT_PWR_MODE); 11136 11137 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u, ch freq %u, state %u", 11138 sta_sap_scc_on_dfs_chan, sap_count, ch_freq, state); 11139 11140 if ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) || 11141 (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq) && 11142 sta_sap_scc_on_dfs_chan) || 11143 (sta_sap_scc_allowed_on_indoor_chan && 11144 wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))) { 11145 policy_mgr_debug("Valid channel for channel switch"); 11146 return true; 11147 } 11148 11149 policy_mgr_debug("Invalid channel for channel switch"); 11150 return false; 11151 } 11152 11153 bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, 11154 uint32_t sap_freq) 11155 { 11156 uint32_t conn_index; 11157 bool is_scc = false; 11158 struct policy_mgr_psoc_priv_obj *pm_ctx; 11159 11160 pm_ctx = policy_mgr_get_context(psoc); 11161 if (!pm_ctx) { 11162 policy_mgr_err("Invalid Context"); 11163 return is_scc; 11164 } 11165 11166 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11167 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11168 conn_index++) { 11169 if (pm_conc_connection_list[conn_index].in_use && 11170 (pm_conc_connection_list[conn_index].mode == 11171 PM_STA_MODE || 11172 pm_conc_connection_list[conn_index].mode == 11173 PM_P2P_CLIENT_MODE) && (sap_freq == 11174 pm_conc_connection_list[conn_index].freq)) { 11175 is_scc = true; 11176 break; 11177 } 11178 } 11179 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11180 11181 return is_scc; 11182 } 11183 11184 bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc) 11185 { 11186 uint32_t mcc_to_scc_switch; 11187 struct policy_mgr_psoc_priv_obj *pm_ctx; 11188 11189 pm_ctx = policy_mgr_get_context(psoc); 11190 if (!pm_ctx) { 11191 policy_mgr_err("Invalid Context"); 11192 return false; 11193 } 11194 mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc); 11195 if (mcc_to_scc_switch == 11196 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) 11197 return true; 11198 11199 if (pm_ctx->cfg.go_force_scc && policy_mgr_is_force_scc(psoc)) 11200 return true; 11201 11202 return false; 11203 } 11204 11205 uint8_t 11206 policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc, 11207 uint8_t vdev_id, uint32_t freq, 11208 enum policy_mgr_con_mode *mode, 11209 uint32_t *existing_con_freq, 11210 enum phy_ch_width *existing_ch_width) 11211 { 11212 struct policy_mgr_psoc_priv_obj *pm_ctx; 11213 uint32_t conn_index; 11214 11215 pm_ctx = policy_mgr_get_context(psoc); 11216 if (!pm_ctx) { 11217 policy_mgr_err("Invalid Context"); 11218 return WLAN_UMAC_VDEV_ID_MAX; 11219 } 11220 11221 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11222 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11223 conn_index++) { 11224 if ((policy_mgr_is_beaconing_mode( 11225 pm_conc_connection_list[conn_index].mode) || 11226 pm_conc_connection_list[conn_index].mode == 11227 PM_P2P_CLIENT_MODE || 11228 pm_conc_connection_list[conn_index].mode == 11229 PM_STA_MODE) && 11230 pm_conc_connection_list[conn_index].in_use && 11231 policy_mgr_are_2_freq_on_same_mac( 11232 psoc, freq, pm_conc_connection_list[conn_index].freq) && 11233 freq != pm_conc_connection_list[conn_index].freq && 11234 vdev_id != pm_conc_connection_list[conn_index].vdev_id) { 11235 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11236 policy_mgr_debug( 11237 "Existing vdev_id for mode %d is %d", 11238 pm_conc_connection_list[conn_index].mode, 11239 pm_conc_connection_list[conn_index].vdev_id); 11240 *mode = pm_conc_connection_list[conn_index].mode; 11241 *existing_con_freq = 11242 pm_conc_connection_list[conn_index].freq; 11243 *existing_ch_width = policy_mgr_get_ch_width( 11244 pm_conc_connection_list[conn_index].bw); 11245 return pm_conc_connection_list[conn_index].vdev_id; 11246 } 11247 } 11248 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11249 11250 return WLAN_UMAC_VDEV_ID_MAX; 11251 } 11252 11253 #ifdef WLAN_FEATURE_P2P_P2P_STA 11254 bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc) 11255 { 11256 struct policy_mgr_psoc_priv_obj *pm_ctx; 11257 bool ret = false; 11258 11259 pm_ctx = policy_mgr_get_context(psoc); 11260 if (!pm_ctx) { 11261 ret = false; 11262 goto return_val; 11263 } 11264 if (pm_ctx->cfg.go_force_scc & GO_FORCE_SCC_STRICT) { 11265 ret = true; 11266 goto return_val; 11267 } 11268 ret = false; 11269 return_val: 11270 policy_mgr_debug("ret val is %d", ret); 11271 return ret; 11272 } 11273 #endif 11274 11275 QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc, 11276 uint8_t nan_vdev_id, 11277 uint8_t mac_id) 11278 { 11279 struct policy_mgr_hw_mode_params hw_mode = {0}; 11280 struct policy_mgr_vdev_mac_map vdev_mac_map = {0}; 11281 QDF_STATUS status; 11282 11283 vdev_mac_map.vdev_id = nan_vdev_id; 11284 vdev_mac_map.mac_id = mac_id; 11285 11286 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); 11287 11288 if (QDF_IS_STATUS_SUCCESS(status)) 11289 policy_mgr_update_hw_mode_conn_info(psoc, 1, &vdev_mac_map, 11290 hw_mode, 0, NULL); 11291 11292 return status; 11293 } 11294 11295 bool policy_mgr_is_sap_go_on_2g(struct wlan_objmgr_psoc *psoc) 11296 { 11297 struct policy_mgr_psoc_priv_obj *pm_ctx; 11298 uint32_t conn_index; 11299 bool ret = false; 11300 11301 pm_ctx = policy_mgr_get_context(psoc); 11302 if (!pm_ctx) { 11303 policy_mgr_err("Invalid Context"); 11304 return ret; 11305 } 11306 11307 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11308 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11309 conn_index++) { 11310 if ((pm_conc_connection_list[conn_index].mode == PM_SAP_MODE || 11311 pm_conc_connection_list[conn_index].mode == PM_P2P_GO_MODE) && 11312 pm_conc_connection_list[conn_index].freq <= 11313 WLAN_REG_MAX_24GHZ_CHAN_FREQ && 11314 pm_conc_connection_list[conn_index].in_use) 11315 ret = true; 11316 } 11317 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11318 11319 return ret; 11320 } 11321 11322 bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc, 11323 uint8_t vdev_id, 11324 qdf_freq_t freq, 11325 tQDF_MCC_TO_SCC_SWITCH_MODE scc_mode) 11326 { 11327 uint8_t i; 11328 bool restart_required = false; 11329 bool is_sta_p2p_cli; 11330 bool sap_on_dfs = false; 11331 struct policy_mgr_psoc_priv_obj *pm_ctx; 11332 struct policy_mgr_conc_connection_info *connection; 11333 bool sta_sap_scc_on_dfs_chan, sta_sap_scc_allowed_on_indoor_ch; 11334 qdf_freq_t user_config_freq; 11335 bool sap_found = false; 11336 uint8_t num_mcc_conn = 0; 11337 uint8_t num_scc_conn = 0; 11338 11339 pm_ctx = policy_mgr_get_context(psoc); 11340 if (!pm_ctx) { 11341 policy_mgr_err("Invalid psoc"); 11342 return false; 11343 } 11344 if (scc_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) { 11345 policy_mgr_debug("No scc required"); 11346 return false; 11347 } 11348 11349 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11350 connection = pm_conc_connection_list; 11351 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 11352 if (!connection[i].in_use) 11353 continue; 11354 if (connection[i].vdev_id == vdev_id) { 11355 if (WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) && 11356 (connection[i].ch_flagext & (IEEE80211_CHAN_DFS | 11357 IEEE80211_CHAN_DFS_CFREQ2))) 11358 sap_on_dfs = true; 11359 sap_found = true; 11360 } else if (connection[i].freq == freq) { 11361 num_scc_conn++; 11362 } else { 11363 num_mcc_conn++; 11364 } 11365 } 11366 if (!sap_found) { 11367 policy_mgr_err("Invalid vdev id: %d", vdev_id); 11368 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11369 return false; 11370 } 11371 /* Current hw mode is SBS low share. STA 5180, SAP 1 2412, 11372 * SAP 2 5745, but SAP 1 is 2G only, can't move to STA 5180, 11373 * SAP 2 is SBS with STA, policy_mgr_are_2_freq_on_same_mac 11374 * return false for 5745 and 5180 and finally this function 11375 * return false, no force SCC on SAP2. 11376 * Add mcc conntion count check for SAP2, if SAP 2 channel 11377 * is different from all of exsting 2 or more connections, then 11378 * try to force SCC on SAP 2. 11379 */ 11380 if (num_mcc_conn > 1 && !num_scc_conn) { 11381 policy_mgr_debug("sap vdev %d has chan %d diff with %d exsting conn", 11382 vdev_id, freq, num_mcc_conn); 11383 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11384 return true; 11385 } 11386 sta_sap_scc_on_dfs_chan = 11387 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 11388 11389 sta_sap_scc_allowed_on_indoor_ch = 11390 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 11391 11392 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 11393 is_sta_p2p_cli = 11394 connection[i].in_use && 11395 (connection[i].mode == PM_STA_MODE || 11396 connection[i].mode == PM_P2P_CLIENT_MODE); 11397 if (!is_sta_p2p_cli) 11398 continue; 11399 11400 if (connection[i].freq != freq && 11401 policy_mgr_are_2_freq_on_same_mac(psoc, freq, 11402 connection[i].freq)) { 11403 policy_mgr_debug("SAP:%d and STA:%d on same mac. Restart SAP ", 11404 freq, connection[i].freq); 11405 restart_required = true; 11406 break; 11407 } 11408 if (connection[i].freq == freq && 11409 !sta_sap_scc_on_dfs_chan && sap_on_dfs) { 11410 policy_mgr_debug("Move SAP out of DFS ch:%d", freq); 11411 restart_required = true; 11412 break; 11413 } 11414 11415 if (connection[i].freq == freq && 11416 !sta_sap_scc_allowed_on_indoor_ch && 11417 wlan_reg_is_freq_indoor(pm_ctx->pdev, connection[i].freq)) { 11418 policy_mgr_debug("Move SAP out of indoor ch:%d", freq); 11419 restart_required = true; 11420 break; 11421 } 11422 11423 /* 11424 * Existing connection: 11425 * 1. "STA in DFS ch and SoftAP in 2.4 GHz channel, and then 11426 * STA moves to 5 GHz non-DFS channel 11427 * 11428 * 2. "STA in indoor channel and sta_sap_scc_on_indoor_ch 11429 * ini is false & SAP has moved to 2.4 GHz channel" 11430 * STA moves back to 5 GHZ non indoor/non DFS channel 11431 * 11432 * Now SAP has to move to STA 5 GHz channel if SAP 11433 * was started on 5 GHz channel initially. 11434 */ 11435 user_config_freq = 11436 policy_mgr_get_user_config_sap_freq(psoc, vdev_id); 11437 11438 if (connection[i].freq != freq && 11439 WLAN_REG_IS_24GHZ_CH_FREQ(freq) && 11440 WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) && 11441 !wlan_reg_is_dfs_for_freq(pm_ctx->pdev, 11442 connection[i].freq) && 11443 WLAN_REG_IS_5GHZ_CH_FREQ(user_config_freq)) { 11444 policy_mgr_debug("Move SAP from:%d to STA ch:%d (sap start freq:%d)", 11445 freq, connection[i].freq, 11446 user_config_freq); 11447 restart_required = true; 11448 11449 if (wlan_reg_is_freq_indoor(pm_ctx->pdev, 11450 connection[i].freq) && 11451 !sta_sap_scc_allowed_on_indoor_ch) 11452 restart_required = false; 11453 break; 11454 } 11455 11456 /* 11457 * SAP has to move away from indoor only channel 11458 * when STA moves out of indoor only channel and 11459 * SAP standalone support on indoor only 11460 * channel ini is disabled 11461 **/ 11462 if (connection[i].freq != freq && 11463 WLAN_REG_IS_24GHZ_CH_FREQ(connection[i].freq) && 11464 WLAN_REG_IS_5GHZ_CH_FREQ(freq) && 11465 !policy_mgr_is_sap_go_interface_allowed_on_indoor( 11466 pm_ctx->pdev, 11467 vdev_id, freq)) { 11468 policy_mgr_debug("SAP in indoor freq: sta:%d sap:%d", 11469 connection[i].freq, freq); 11470 restart_required = true; 11471 } 11472 } 11473 11474 if (!restart_required && 11475 policy_mgr_is_restart_sap_required_with_mlo_sta( 11476 psoc, vdev_id, freq)) 11477 restart_required = true; 11478 11479 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11480 11481 return restart_required; 11482 } 11483 11484 uint8_t policy_mgr_get_roam_enabled_sta_session_id( 11485 struct wlan_objmgr_psoc *psoc, 11486 uint8_t vdev_id) 11487 { 11488 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 11489 uint32_t index, count; 11490 struct policy_mgr_psoc_priv_obj *pm_ctx; 11491 struct wlan_objmgr_vdev *vdev, *assoc_vdev; 11492 11493 pm_ctx = policy_mgr_get_context(psoc); 11494 if (!pm_ctx) { 11495 policy_mgr_err("Invalid Context"); 11496 return WLAN_UMAC_VDEV_ID_MAX; 11497 } 11498 11499 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 11500 WLAN_POLICY_MGR_ID); 11501 if (!vdev) { 11502 policy_mgr_err("Invalid vdev"); 11503 return WLAN_UMAC_VDEV_ID_MAX; 11504 } 11505 11506 if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) { 11507 assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev); 11508 if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev)) { 11509 policy_mgr_debug("replace link vdev %d with assoc vdev %d", 11510 vdev_id, wlan_vdev_get_id(assoc_vdev)); 11511 vdev_id = wlan_vdev_get_id(assoc_vdev); 11512 } 11513 } 11514 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 11515 11516 count = policy_mgr_mode_specific_connection_count( 11517 psoc, PM_STA_MODE, list); 11518 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11519 11520 for (index = 0; index < count; index++) { 11521 if (vdev_id == pm_conc_connection_list[list[index]].vdev_id) 11522 continue; 11523 if (MLME_IS_ROAM_INITIALIZED( 11524 psoc, pm_conc_connection_list[list[index]].vdev_id)) { 11525 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11526 return pm_conc_connection_list[list[index]].vdev_id; 11527 } 11528 } 11529 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11530 11531 return WLAN_UMAC_VDEV_ID_MAX; 11532 } 11533 11534 bool policy_mgr_is_sta_mon_concurrency(struct wlan_objmgr_psoc *psoc) 11535 { 11536 uint32_t conc_mode; 11537 11538 if (wlan_mlme_is_sta_mon_conc_supported(psoc)) { 11539 conc_mode = policy_mgr_get_concurrency_mode(psoc); 11540 if (conc_mode & QDF_STA_MASK && 11541 conc_mode & QDF_MONITOR_MASK) { 11542 policy_mgr_err("STA + MON mode is UP"); 11543 return true; 11544 } 11545 } 11546 return false; 11547 } 11548 11549 QDF_STATUS policy_mgr_check_mon_concurrency(struct wlan_objmgr_psoc *psoc) 11550 { 11551 uint8_t num_open_session = 0; 11552 11553 if (policy_mgr_mode_specific_num_open_sessions( 11554 psoc, 11555 QDF_MONITOR_MODE, 11556 &num_open_session) != QDF_STATUS_SUCCESS) 11557 return QDF_STATUS_E_INVAL; 11558 11559 if (num_open_session) { 11560 policy_mgr_err("monitor mode already exists, only one is possible"); 11561 return QDF_STATUS_E_BUSY; 11562 } 11563 11564 num_open_session = policy_mgr_get_sap_mode_count(psoc, NULL); 11565 11566 if (num_open_session) { 11567 policy_mgr_err("cannot add monitor mode, due to SAP concurrency"); 11568 return QDF_STATUS_E_INVAL; 11569 } 11570 11571 num_open_session = policy_mgr_mode_specific_connection_count( 11572 psoc, 11573 PM_P2P_CLIENT_MODE, 11574 NULL); 11575 11576 if (num_open_session) { 11577 policy_mgr_err("cannot add monitor mode, due to P2P CLIENT concurrency"); 11578 return QDF_STATUS_E_INVAL; 11579 } 11580 11581 num_open_session = policy_mgr_mode_specific_connection_count( 11582 psoc, 11583 PM_P2P_GO_MODE, 11584 NULL); 11585 11586 if (num_open_session) { 11587 policy_mgr_err("cannot add monitor mode, due to P2P GO concurrency"); 11588 return QDF_STATUS_E_INVAL; 11589 } 11590 11591 num_open_session = policy_mgr_mode_specific_connection_count( 11592 psoc, 11593 PM_NAN_DISC_MODE, 11594 NULL); 11595 11596 if (num_open_session) { 11597 policy_mgr_err("cannot add monitor mode, due to NAN concurrency"); 11598 return QDF_STATUS_E_INVAL; 11599 } 11600 11601 return QDF_STATUS_SUCCESS; 11602 } 11603 11604 bool policy_mgr_is_hwmode_offload_enabled(struct wlan_objmgr_psoc *psoc) 11605 { 11606 struct wmi_unified *wmi_handle; 11607 11608 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 11609 if (!wmi_handle) { 11610 policy_mgr_err("Invalid WMI handle"); 11611 return false; 11612 } 11613 11614 return wmi_service_enabled(wmi_handle, 11615 wmi_service_hw_mode_policy_offload_support); 11616 } 11617 11618 bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc, 11619 struct wlan_objmgr_pdev *pdev, 11620 struct wlan_objmgr_vdev *vdev, 11621 uint32_t ch_freq, 11622 enum phy_ch_width ch_width, 11623 uint8_t *con_vdev_id, 11624 uint32_t *con_freq) 11625 { 11626 enum QDF_OPMODE mode; 11627 enum policy_mgr_con_mode con_mode; 11628 union conc_ext_flag conc_ext_flags; 11629 uint32_t cc_count, i, j, ap_index; 11630 uint32_t op_freq[MAX_NUMBER_OF_CONC_CONNECTIONS * 2]; 11631 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2]; 11632 QDF_STATUS status; 11633 struct policy_mgr_pcl_list pcl; 11634 11635 if (!psoc || !vdev || !pdev) { 11636 policy_mgr_debug("psoc or vdev or pdev is NULL"); 11637 return false; 11638 } 11639 11640 cc_count = policy_mgr_get_mode_specific_conn_info(psoc, 11641 &op_freq[0], 11642 &vdev_id[0], 11643 PM_SAP_MODE); 11644 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) 11645 cc_count = cc_count + 11646 policy_mgr_get_mode_specific_conn_info( 11647 psoc, 11648 &op_freq[cc_count], 11649 &vdev_id[cc_count], 11650 PM_P2P_GO_MODE); 11651 if (!cc_count) 11652 return true; 11653 11654 mode = wlan_vdev_mlme_get_opmode(vdev); 11655 con_mode = policy_mgr_qdf_opmode_to_pm_con_mode( 11656 psoc, mode, wlan_vdev_get_id(vdev)); 11657 qdf_mem_zero(&pcl, sizeof(pcl)); 11658 status = policy_mgr_get_pcl(psoc, con_mode, pcl.pcl_list, &pcl.pcl_len, 11659 pcl.weight_list, 11660 QDF_ARRAY_SIZE(pcl.weight_list), 11661 wlan_vdev_get_id(vdev)); 11662 if (!pcl.pcl_len) 11663 return true; 11664 ap_index = cc_count; 11665 for (i = 0 ; i < pcl.pcl_len; i++) { 11666 for (j = 0; j < cc_count; j++) { 11667 if (op_freq[j] == pcl.pcl_list[i]) 11668 break; 11669 } 11670 if (j >= cc_count) 11671 continue; 11672 if (ch_freq == op_freq[j]) { 11673 ap_index = j; 11674 break; 11675 } 11676 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 11677 ap_index = j; 11678 break; 11679 } 11680 if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[j]) && 11681 !policy_mgr_are_sbs_chan(psoc, ch_freq, op_freq[j])) { 11682 ap_index = j; 11683 break; 11684 } 11685 if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[j]) && 11686 policy_mgr_get_connection_count(psoc) > 2) { 11687 ap_index = j; 11688 break; 11689 } 11690 } 11691 /* If same band MCC SAP/GO not present, return true, 11692 * no AP to AP channel override 11693 */ 11694 if (ap_index >= cc_count) 11695 return true; 11696 11697 *con_freq = op_freq[ap_index]; 11698 *con_vdev_id = vdev_id[ap_index]; 11699 /* 11700 * For 3Vif concurrency we only support SCC in same MAC 11701 * in below combination: 11702 * 2 beaconing entities with STA in SCC. 11703 * 3 beaconing entities in SCC. 11704 */ 11705 conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false); 11706 if (!policy_mgr_allow_concurrency( 11707 psoc, con_mode, ch_freq, 11708 policy_mgr_get_bw(ch_width), 11709 conc_ext_flags.value, 11710 wlan_vdev_get_id(vdev))) { 11711 policy_mgr_debug("AP AP mcc not allowed, try to override 2nd SAP/GO chan"); 11712 return false; 11713 } 11714 /* For SCC case & bandwdith > 20, the center frequency have to be 11715 * same to avoid target MCC on different center frequency even though 11716 * primary channel are same. 11717 */ 11718 if (*con_freq == ch_freq && wlan_reg_get_bw_value(ch_width) > 20) 11719 return false; 11720 11721 return true; 11722 } 11723 11724 bool policy_mgr_any_other_vdev_on_same_mac_as_freq( 11725 struct wlan_objmgr_psoc *psoc, 11726 uint32_t freq, uint8_t vdev_id) 11727 { 11728 struct policy_mgr_psoc_priv_obj *pm_ctx; 11729 uint32_t conn_index = 0; 11730 bool same_mac = false; 11731 11732 pm_ctx = policy_mgr_get_context(psoc); 11733 if (!pm_ctx) { 11734 policy_mgr_err("Invalid Context"); 11735 return false; 11736 } 11737 11738 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11739 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 11740 conn_index++) { 11741 if (!pm_conc_connection_list[conn_index].in_use) 11742 continue; 11743 11744 if (pm_conc_connection_list[conn_index].vdev_id == vdev_id) 11745 continue; 11746 11747 if (policy_mgr_are_2_freq_on_same_mac( 11748 psoc, 11749 pm_conc_connection_list[conn_index].freq, 11750 freq)) { 11751 same_mac = true; 11752 break; 11753 } 11754 } 11755 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11756 11757 return same_mac; 11758 } 11759 11760 QDF_STATUS policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc *psoc, bool *sbs) 11761 { 11762 struct policy_mgr_psoc_priv_obj *pm_ctx; 11763 11764 pm_ctx = policy_mgr_get_context(psoc); 11765 if (!pm_ctx) { 11766 policy_mgr_err("pm_ctx is NULL"); 11767 return QDF_STATUS_E_FAILURE; 11768 } 11769 *sbs = pm_ctx->cfg.sbs_enable; 11770 11771 return QDF_STATUS_SUCCESS; 11772 } 11773 11774 #ifdef WLAN_FEATURE_SR 11775 bool policy_mgr_sr_same_mac_conc_enabled(struct wlan_objmgr_psoc *psoc) 11776 { 11777 struct wmi_unified *wmi_handle; 11778 bool sr_conc_enabled; 11779 11780 if (!psoc) { 11781 mlme_err("PSOC is NULL"); 11782 return false; 11783 } 11784 11785 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 11786 if (!wmi_handle) { 11787 mlme_err("wmi_handle is null"); 11788 return false; 11789 } 11790 11791 sr_conc_enabled = policy_mgr_get_same_mac_conc_sr_status(psoc); 11792 11793 return (sr_conc_enabled && 11794 wmi_service_enabled(wmi_handle, 11795 wmi_service_obss_per_packet_sr_support)); 11796 } 11797 #endif 11798 11799 /** 11800 * _policy_mgr_get_ll_sap_freq()- Function to get LL sap freq if it's present 11801 * for provided type 11802 * @psoc: PSOC object 11803 * @ap_type: low latency ap type 11804 * 11805 * Return: freq if LL SAP otherwise return 0 11806 * 11807 */ 11808 static qdf_freq_t _policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc, 11809 enum ll_ap_type ap_type) 11810 { 11811 struct wlan_objmgr_vdev *sap_vdev; 11812 struct policy_mgr_psoc_priv_obj *pm_ctx; 11813 uint32_t conn_idx = 0, vdev_id; 11814 bool is_ll_sap_present = false; 11815 qdf_freq_t freq = 0; 11816 enum host_concurrent_ap_policy profile = 11817 HOST_CONCURRENT_AP_POLICY_UNSPECIFIED; 11818 11819 pm_ctx = policy_mgr_get_context(psoc); 11820 if (!pm_ctx) { 11821 policy_mgr_err("pm_ctx is NULL"); 11822 return 0; 11823 } 11824 11825 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 11826 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; 11827 conn_idx++) { 11828 if (!(policy_mgr_is_sap_mode( 11829 pm_conc_connection_list[conn_idx].mode) && 11830 pm_conc_connection_list[conn_idx].in_use)) 11831 continue; 11832 11833 vdev_id = pm_conc_connection_list[conn_idx].vdev_id; 11834 freq = pm_conc_connection_list[conn_idx].freq; 11835 11836 sap_vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 11837 psoc, 11838 vdev_id, 11839 WLAN_POLICY_MGR_ID); 11840 11841 if (!sap_vdev) { 11842 policy_mgr_err("vdev %d: not a sap vdev", vdev_id); 11843 continue; 11844 } 11845 11846 profile = wlan_mlme_get_ap_policy(sap_vdev); 11847 wlan_objmgr_vdev_release_ref(sap_vdev, 11848 WLAN_POLICY_MGR_ID); 11849 switch (ap_type) { 11850 case LL_AP_TYPE_HT: 11851 if (profile == HOST_CONCURRENT_AP_POLICY_XR) 11852 is_ll_sap_present = true; 11853 break; 11854 case LL_AP_TYPE_LT: 11855 if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO || 11856 profile == 11857 HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING) 11858 is_ll_sap_present = true; 11859 break; 11860 case LL_AP_TYPE_ANY: 11861 if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO || 11862 profile == HOST_CONCURRENT_AP_POLICY_XR || 11863 profile == 11864 HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING) 11865 is_ll_sap_present = true; 11866 break; 11867 default: 11868 break; 11869 } 11870 if (!is_ll_sap_present) 11871 continue; 11872 11873 policy_mgr_debug("LL SAP %d present with vdev_id %d and freq %d", 11874 ap_type, vdev_id, freq); 11875 11876 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11877 return freq; 11878 } 11879 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 11880 return 0; 11881 } 11882 11883 qdf_freq_t policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc) 11884 { 11885 return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_ANY); 11886 } 11887 11888 qdf_freq_t policy_mgr_get_ht_ll_sap_freq(struct wlan_objmgr_psoc *psoc) 11889 { 11890 return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_HT); 11891 } 11892 11893 qdf_freq_t policy_mgr_get_lt_ll_sap_freq(struct wlan_objmgr_psoc *psoc) 11894 { 11895 return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_LT); 11896 } 11897 11898 bool policy_mgr_is_ll_sap_concurrency_valid(struct wlan_objmgr_psoc *psoc, 11899 qdf_freq_t freq, 11900 enum policy_mgr_con_mode mode) 11901 { 11902 qdf_freq_t ll_sap_freq; 11903 11904 ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc); 11905 if (!ll_sap_freq) 11906 return true; 11907 11908 /* 11909 * Scenario: When low latency SAP with 5GHz channel(whose 11910 * profile is set as gaming or lossless audio or XR) is present 11911 * on SBS/DBS hardware and the other interface like 11912 * STA/SAP/GC/GO trying to form connection. 11913 * Allow connection on those freq which are mutually exclusive 11914 * to LL SAP mac 11915 */ 11916 11917 if (policy_mgr_2_freq_always_on_same_mac(psoc, ll_sap_freq, 11918 freq)) { 11919 policy_mgr_debug("Invalid LL-SAP concurrency for SBS/DBS hw, ll-sap freq %d, conc_freq %d, conc_mode %d", 11920 ll_sap_freq, freq, mode); 11921 return false; 11922 } 11923 11924 return true; 11925 } 11926 11927 bool 11928 policy_mgr_update_indoor_concurrency(struct wlan_objmgr_psoc *psoc, 11929 uint8_t vdev_id, 11930 uint32_t discon_freq, 11931 enum indoor_conc_update_type type) 11932 { 11933 uint32_t ch_freq; 11934 enum QDF_OPMODE mode; 11935 struct policy_mgr_psoc_priv_obj *pm_ctx; 11936 enum phy_ch_width ch_width = CH_WIDTH_INVALID; 11937 bool indoor_support = false; 11938 11939 pm_ctx = policy_mgr_get_context(psoc); 11940 if (!pm_ctx) { 11941 policy_mgr_err("Invalid pm context"); 11942 return false; 11943 } 11944 11945 ucfg_mlme_get_indoor_channel_support(psoc, &indoor_support); 11946 if (indoor_support || 11947 !policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc)) 11948 return false; 11949 11950 mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 11951 11952 /** 11953 * DISCONNECT_WITH_CONCURRENCY update comes after SAP/GO CSA. 11954 * Whereas, all other updates come from STA/GC operation. 11955 */ 11956 if (type != DISCONNECT_WITH_CONCURRENCY && 11957 (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)) { 11958 return false; 11959 } else if (type == DISCONNECT_WITH_CONCURRENCY && 11960 (mode != QDF_SAP_MODE && mode != QDF_P2P_GO_MODE)) { 11961 return false; 11962 } 11963 11964 switch (type) { 11965 case CONNECT: 11966 case SWITCH_WITHOUT_CONCURRENCY: 11967 case SWITCH_WITH_CONCURRENCY: 11968 policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq); 11969 ch_width = policy_mgr_get_bw_by_session_id(psoc, vdev_id); 11970 break; 11971 case DISCONNECT_WITHOUT_CONCURRENCY: 11972 case DISCONNECT_WITH_CONCURRENCY: 11973 ch_freq = discon_freq; 11974 break; 11975 default: 11976 return false; 11977 } 11978 11979 if (type != SWITCH_WITHOUT_CONCURRENCY && 11980 !(WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && 11981 wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))) { 11982 return false; 11983 } else if (type == SWITCH_WITHOUT_CONCURRENCY) { 11984 /* Either the previous frequency or the current 11985 * frequency can be indoor. Or both can be indoor. 11986 * Therefore, atleast one of the frequency must be 11987 * indoor in order to proceed for the update. 11988 */ 11989 if (!((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && 11990 wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq)) || 11991 (WLAN_REG_IS_5GHZ_CH_FREQ(discon_freq) && 11992 wlan_reg_is_freq_indoor(pm_ctx->pdev, discon_freq)))) 11993 return false; 11994 } 11995 11996 switch (type) { 11997 case CONNECT: 11998 wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id, 11999 ch_freq, ch_width, true); 12000 break; 12001 case DISCONNECT_WITHOUT_CONCURRENCY: 12002 wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id, 12003 0, CH_WIDTH_INVALID, false); 12004 break; 12005 case SWITCH_WITHOUT_CONCURRENCY: 12006 wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id, 0, 12007 CH_WIDTH_INVALID, false); 12008 if (wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq)) 12009 wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, 12010 vdev_id, ch_freq, 12011 ch_width, true); 12012 break; 12013 case DISCONNECT_WITH_CONCURRENCY: 12014 /*If there are other sessions, do not change current chan list*/ 12015 if (policy_mgr_get_connection_count_with_ch_freq(ch_freq) > 1) 12016 return false; 12017 wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, 12018 INVALID_VDEV_ID, ch_freq, 12019 CH_WIDTH_INVALID, false); 12020 break; 12021 case SWITCH_WITH_CONCURRENCY: 12022 wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id, 12023 ch_freq, ch_width, true); 12024 /* 12025 * The previous frequency removal and current channel list 12026 * recomputation will happen after SAP CSA 12027 */ 12028 return false; 12029 } 12030 return true; 12031 } 12032 12033 bool policy_mgr_is_conc_sap_present_on_sta_freq(struct wlan_objmgr_psoc *psoc, 12034 enum policy_mgr_con_mode mode, 12035 uint32_t ch_freq) 12036 { 12037 struct policy_mgr_psoc_priv_obj *pm_ctx; 12038 uint8_t i; 12039 bool sap_go_exists = false; 12040 enum policy_mgr_con_mode cmode; 12041 12042 pm_ctx = policy_mgr_get_context(psoc); 12043 if (!pm_ctx) { 12044 policy_mgr_err("Invalid pm context"); 12045 return false; 12046 } 12047 12048 if (mode != PM_STA_MODE && mode != PM_P2P_CLIENT_MODE) 12049 return false; 12050 12051 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 12052 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 12053 cmode = pm_conc_connection_list[i].mode; 12054 if (pm_conc_connection_list[i].in_use && 12055 ch_freq == pm_conc_connection_list[i].freq && 12056 (cmode == PM_SAP_MODE || cmode == PM_P2P_GO_MODE)) { 12057 sap_go_exists = true; 12058 break; 12059 } 12060 } 12061 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 12062 12063 return sap_go_exists; 12064 } 12065 12066 bool policy_mgr_is_sap_mode(enum policy_mgr_con_mode mode) 12067 { 12068 if (mode == PM_SAP_MODE || mode == PM_LL_LT_SAP_MODE) 12069 return true; 12070 12071 return false; 12072 } 12073 12074 bool policy_mgr_is_beaconing_mode(enum policy_mgr_con_mode mode) 12075 { 12076 if (mode == PM_SAP_MODE || mode == PM_LL_LT_SAP_MODE || 12077 mode == PM_P2P_GO_MODE) 12078 return true; 12079 12080 return false; 12081 } 12082 12083 bool policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(struct wlan_objmgr_psoc *psoc) 12084 { 12085 struct policy_mgr_psoc_priv_obj *pm_ctx; 12086 12087 pm_ctx = policy_mgr_get_context(psoc); 12088 if (!pm_ctx) { 12089 policy_mgr_err("pm_ctx is NULL"); 12090 return 0; 12091 } 12092 return pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl; 12093 } 12094 12095 QDF_STATUS 12096 policy_mgr_reset_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc) 12097 { 12098 struct policy_mgr_psoc_priv_obj *pm_ctx; 12099 12100 pm_ctx = policy_mgr_get_context(psoc); 12101 if (!pm_ctx) { 12102 policy_mgr_err("Invalid Context"); 12103 return QDF_STATUS_E_FAILURE; 12104 } 12105 12106 pm_ctx->sap_mandatory_channels_len = 0; 12107 qdf_mem_zero(pm_ctx->sap_mandatory_channels, 12108 QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels) * 12109 sizeof(*pm_ctx->sap_mandatory_channels)); 12110 12111 return QDF_STATUS_SUCCESS; 12112 } 12113 12114 bool policy_mgr_is_freq_on_mac_id(struct policy_mgr_freq_range *freq_range, 12115 qdf_freq_t freq, uint8_t mac_id) 12116 { 12117 return IS_FREQ_ON_MAC_ID(freq_range, freq, mac_id); 12118 } 12119