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