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_pcl.c 22 * 23 * WLAN Concurrenct Connection Management APIs 24 * 25 */ 26 27 /* Include files */ 28 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 "qdf_str.h" 34 #include "wlan_objmgr_global_obj.h" 35 #include "wlan_utility.h" 36 #include "wlan_mlme_ucfg_api.h" 37 #ifdef WLAN_FEATURE_11BE_MLO 38 #include "wlan_mlo_mgr_cmn.h" 39 #endif 40 #include "wlan_policy_mgr_ll_sap.h" 41 #include "wlan_cm_ucfg_api.h" 42 #include "wlan_cm_roam_api.h" 43 #include "wlan_scan_api.h" 44 #include "wlan_nan_api.h" 45 #include "wlan_mlo_link_force.h" 46 47 /* 48 * first_connection_pcl_table - table which provides PCL for the 49 * very first connection in the system 50 */ 51 const enum policy_mgr_pcl_type 52 first_connection_pcl_table[PM_MAX_NUM_OF_MODE] 53 [PM_MAX_CONC_PRIORITY_MODE] = { 54 [PM_STA_MODE] = {PM_NONE, PM_NONE, PM_NONE}, 55 [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G }, 56 [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G }, 57 [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G }, 58 [PM_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G}, 59 [PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, 60 }; 61 62 pm_dbs_pcl_second_connection_table_type 63 *second_connection_pcl_dbs_table; 64 65 enum policy_mgr_pcl_type const 66 (*second_connection_pcl_non_dbs_table)[PM_MAX_ONE_CONNECTION_MODE] 67 [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE]; 68 pm_dbs_pcl_third_connection_table_type 69 *third_connection_pcl_dbs_table; 70 enum policy_mgr_pcl_type const 71 (*third_connection_pcl_non_dbs_table)[PM_MAX_TWO_CONNECTION_MODE] 72 [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE]; 73 policy_mgr_next_action_two_connection_table_type 74 *next_action_two_connection_table; 75 policy_mgr_next_action_three_connection_table_type 76 *next_action_three_connection_table; 77 policy_mgr_next_action_two_connection_table_type 78 *next_action_two_connection_2x2_2g_1x1_5g_table; 79 policy_mgr_next_action_three_connection_table_type 80 *next_action_three_connection_2x2_2g_1x1_5g_table; 81 82 QDF_STATUS policy_mgr_get_pcl_for_existing_conn( 83 struct wlan_objmgr_psoc *psoc, 84 enum policy_mgr_con_mode mode, 85 uint32_t *pcl_ch, uint32_t *len, 86 uint8_t *pcl_weight, uint32_t weight_len, 87 bool all_matching_cxn_to_del, 88 uint8_t vdev_id) 89 { 90 struct policy_mgr_conc_connection_info 91 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; 92 uint8_t num_cxn_del = 0; 93 94 QDF_STATUS status = QDF_STATUS_SUCCESS; 95 struct policy_mgr_psoc_priv_obj *pm_ctx; 96 97 policy_mgr_debug("get pcl for existing conn:%d", mode); 98 pm_ctx = policy_mgr_get_context(psoc); 99 if (!pm_ctx) { 100 policy_mgr_err("Invalid Context"); 101 return QDF_STATUS_E_FAILURE; 102 } 103 104 *len = 0; 105 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 106 if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { 107 /* Check, store and temp delete the mode's parameter */ 108 policy_mgr_store_and_del_conn_info(psoc, mode, 109 all_matching_cxn_to_del, info, &num_cxn_del); 110 /* Get the PCL */ 111 status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, 112 pcl_weight, weight_len, vdev_id); 113 policy_mgr_debug("Get PCL to FW for mode:%d", mode); 114 /* Restore the connection info */ 115 policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); 116 } 117 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 118 119 return status; 120 } 121 122 #ifdef WLAN_FEATURE_11BE_MLO 123 /** 124 * policy_mgr_get_pcl_concurrent_connetions() - Get concurrent connections 125 * those will affect PCL fetching for the given vdev id 126 * @psoc: PSOC object information 127 * @mode: Connection Mode 128 * @vdev_id: vdev id 129 * @vdev_ids: vdev id list of the concurrent connections 130 * @vdev_ids_size: size of the vdev id list 131 * 132 * Return: number of the concurrent connections 133 */ 134 static uint32_t 135 policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc *psoc, 136 enum policy_mgr_con_mode mode, 137 uint8_t vdev_id, uint8_t *vdev_ids, 138 uint32_t vdev_ids_size) 139 { 140 struct wlan_objmgr_vdev *vdev; 141 struct policy_mgr_psoc_priv_obj *pm_ctx; 142 uint32_t num_related = 0; 143 bool is_ml_sta, has_same_band = false; 144 uint8_t vdev_id_with_diff_band = WLAN_INVALID_VDEV_ID; 145 uint8_t num_ml = 0, num_non_ml = 0, ml_vdev_id; 146 uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 147 uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 148 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 149 qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 150 qdf_freq_t freq = 0, ml_freq; 151 int i; 152 153 if (!vdev_ids || !vdev_ids_size) { 154 policy_mgr_err("Invalid parameters"); 155 return num_related; 156 } 157 158 if (mode != PM_STA_MODE) { 159 vdev_ids[0] = vdev_id; 160 return 1; 161 } 162 163 pm_ctx = policy_mgr_get_context(psoc); 164 if (!pm_ctx) { 165 policy_mgr_err("Invalid Context"); 166 return 0; 167 } 168 169 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 170 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 171 WLAN_POLICY_MGR_ID); 172 if (!vdev) { 173 policy_mgr_err("vdev %d is not present", vdev_id); 174 goto out; 175 } 176 177 if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) { 178 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 179 policy_mgr_debug("ignore ML STA link vdev %d", vdev_id); 180 goto out; 181 } 182 183 is_ml_sta = wlan_vdev_mlme_is_mlo_vdev(vdev); 184 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 185 186 policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx, 187 &num_non_ml, non_ml_idx, 188 freq_list, vdev_id_list); 189 for (i = 0; 190 i < num_non_ml + num_ml && num_related < vdev_ids_size; i++) { 191 if (vdev_id_list[i] == vdev_id) { 192 vdev_ids[num_related++] = vdev_id; 193 freq = freq_list[i]; 194 break; 195 } 196 } 197 198 /* No existing connection for the vdev id */ 199 if (!freq) 200 goto out; 201 202 for (i = 0; i < num_ml && num_related < vdev_ids_size; i++) { 203 ml_vdev_id = vdev_id_list[ml_idx[i]]; 204 if (ml_vdev_id == vdev_id) 205 continue; 206 207 /* If it's ML STA, return vdev ids for all links */ 208 if (is_ml_sta) { 209 policy_mgr_debug("vdev_ids[%d]: %d", 210 num_related, ml_vdev_id); 211 vdev_ids[num_related++] = ml_vdev_id; 212 continue; 213 } 214 215 ml_freq = freq_list[ml_idx[i]]; 216 if (wlan_reg_is_24ghz_ch_freq(ml_freq) == 217 wlan_reg_is_24ghz_ch_freq(freq)) { 218 if (policy_mgr_are_sbs_chan(psoc, freq, ml_freq) && 219 wlan_cm_same_band_sta_allowed(psoc)) 220 continue; 221 222 /* 223 * If it's Non-ML STA, and its freq is within the same 224 * band with one of the existing ML link, but can NOT 225 * lead to SBS, return the original vdev id and vdev id 226 * of the ML link within same band. 227 */ 228 policy_mgr_debug("vdev_ids[%d]: %d", 229 num_related, ml_vdev_id); 230 vdev_ids[num_related++] = ml_vdev_id; 231 has_same_band = true; 232 break; 233 } 234 235 vdev_id_with_diff_band = ml_vdev_id; 236 } 237 238 /* 239 * If it's Non-ML STA, and ML STA is present but the links are 240 * within different band or (within same band but can lead to SBS and 241 * same band STA is allowed), return original vdev id and vdev id of 242 * any ML link within different band. 243 */ 244 if (!has_same_band && vdev_id_with_diff_band != WLAN_INVALID_VDEV_ID) { 245 policy_mgr_debug("vdev_ids[%d]: %d", 246 num_related, vdev_id_with_diff_band); 247 248 if (num_related < vdev_ids_size) 249 vdev_ids[num_related++] = vdev_id_with_diff_band; 250 } 251 252 out: 253 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 254 return num_related; 255 } 256 #else 257 static inline uint32_t 258 policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc *psoc, 259 enum policy_mgr_con_mode mode, 260 uint8_t vdev_id, uint8_t *vdev_ids, 261 uint32_t vdev_ids_size) 262 { 263 if (!vdev_ids || !vdev_ids_size) { 264 policy_mgr_err("Invalid parameters"); 265 return 0; 266 } 267 268 vdev_ids[0] = vdev_id; 269 return 1; 270 } 271 #endif 272 273 QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc, 274 enum policy_mgr_con_mode mode, 275 uint32_t *pcl_ch, uint32_t *len, 276 uint8_t *pcl_weight, 277 uint32_t weight_len, 278 uint8_t vdev_id) 279 { 280 struct policy_mgr_conc_connection_info 281 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; 282 QDF_STATUS status = QDF_STATUS_SUCCESS; 283 struct policy_mgr_psoc_priv_obj *pm_ctx; 284 uint8_t ids[MAX_NUMBER_OF_CONC_CONNECTIONS]; 285 uint8_t num_del = 0, total_del = 0, id_num = 0; 286 int i; 287 288 policy_mgr_debug("get pcl for existing conn:%d vdev id %d", 289 mode, vdev_id); 290 pm_ctx = policy_mgr_get_context(psoc); 291 if (!pm_ctx) { 292 policy_mgr_err("Invalid Context"); 293 return QDF_STATUS_E_FAILURE; 294 } 295 296 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 297 id_num = policy_mgr_get_pcl_concurrent_connetions(psoc, mode, 298 vdev_id, ids, 299 QDF_ARRAY_SIZE(ids)); 300 if (!id_num || id_num > MAX_NUMBER_OF_CONC_CONNECTIONS) { 301 status = QDF_STATUS_E_FAILURE; 302 goto out; 303 } 304 305 *len = 0; 306 307 /* Check, store and temp delete the mode's parameter */ 308 for (i = 0; i < id_num; i++) { 309 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, 310 ids[i], 311 &info[i], 312 &num_del); 313 total_del += num_del; 314 } 315 316 /* Get the PCL */ 317 status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, 318 pcl_weight, weight_len, vdev_id); 319 policy_mgr_debug("Get PCL to FW for mode:%d", mode); 320 /* Restore the connection info */ 321 policy_mgr_restore_deleted_conn_info(psoc, info, total_del); 322 323 out: 324 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 325 326 return status; 327 } 328 329 QDF_STATUS 330 policy_mgr_get_pcl_for_scc_in_same_mode(struct wlan_objmgr_psoc *psoc, 331 enum policy_mgr_con_mode mode, 332 uint32_t *pcl_ch, uint32_t *len, 333 uint8_t *pcl_weight, 334 uint32_t weight_len, 335 uint8_t vdev_id) 336 { 337 struct policy_mgr_psoc_priv_obj *pm_ctx; 338 struct policy_mgr_conc_connection_info 339 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; 340 qdf_freq_t vdev_freq; 341 QDF_STATUS status; 342 uint8_t num_del = 0; 343 344 pm_ctx = policy_mgr_get_context(psoc); 345 if (!pm_ctx) { 346 policy_mgr_err("Invalid Context"); 347 return QDF_STATUS_E_FAILURE; 348 } 349 350 status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &vdev_freq); 351 if (QDF_IS_STATUS_ERROR(status)) { 352 policy_mgr_err("Fail to get channel by vdev id %d", vdev_id); 353 return status; 354 } 355 356 policy_mgr_debug("get pcl for existing conn:%d vdev id %d", 357 mode, vdev_id); 358 359 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 360 policy_mgr_store_and_del_conn_info_by_chan_and_mode(psoc, 361 vdev_freq, 362 mode, 363 info, 364 &num_del); 365 status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, 366 pcl_weight, weight_len, vdev_id); 367 if (num_del > 0) 368 policy_mgr_restore_deleted_conn_info(psoc, info, num_del); 369 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 370 371 return status; 372 } 373 374 void 375 polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc *psoc, 376 enum QDF_OPMODE mode) 377 { 378 uint32_t conn_idx = 0; 379 mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME); 380 uint8_t vdev_id = WLAN_INVALID_VDEV_ID; 381 struct policy_mgr_psoc_priv_obj *pm_ctx; 382 383 pm_ctx = policy_mgr_get_context(psoc); 384 if (!pm_ctx) { 385 policy_mgr_err("Invalid Context"); 386 return; 387 } 388 389 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; 390 conn_idx++) { 391 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 392 if (!(pm_conc_connection_list[conn_idx].mode == 393 PM_STA_MODE && 394 pm_conc_connection_list[conn_idx].in_use)) { 395 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 396 continue; 397 } 398 399 vdev_id = pm_conc_connection_list[conn_idx].vdev_id; 400 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 401 402 /* 403 * Avoid sending PCL when roaming is in progress. PCL 404 * gets updated to firmware once roaming is done 405 */ 406 if (mode == QDF_SAP_MODE && 407 wlan_cm_roaming_in_progress(pm_ctx->pdev, 408 vdev_id)) { 409 policy_mgr_debug("Roaming is in progress, don't stop RSO for vdev_id: %d", 410 vdev_id); 411 continue; 412 } 413 414 pm_ctx->sme_cbacks.sme_rso_stop_cb( 415 mac_handle, vdev_id, 416 REASON_DRIVER_DISABLED, 417 RSO_SET_PCL); 418 419 policy_mgr_set_pcl_for_existing_combo(pm_ctx->psoc, PM_STA_MODE, 420 vdev_id); 421 pm_ctx->sme_cbacks.sme_rso_start_cb( 422 mac_handle, vdev_id, 423 REASON_DRIVER_ENABLED, 424 RSO_SET_PCL); 425 } 426 } 427 428 void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, 429 enum QDF_OPMODE mode, 430 uint8_t session_id) 431 { 432 QDF_STATUS qdf_status; 433 struct policy_mgr_psoc_priv_obj *pm_ctx; 434 435 pm_ctx = policy_mgr_get_context(psoc); 436 if (!pm_ctx) { 437 policy_mgr_err("Invalid Context"); 438 return; 439 } 440 441 qdf_status = policy_mgr_decr_active_session(psoc, mode, session_id); 442 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 443 policy_mgr_debug("Invalid active session"); 444 return; 445 } 446 447 /* 448 * After the removal of this connection, we need to check if 449 * a STA connection still exists. The reason for this is that 450 * if one or more STA exists, we need to provide the updated 451 * PCL to the FW for cases like LFR. 452 * 453 * Since policy_mgr_get_pcl provides PCL list based on the new 454 * connection that is going to come up, we will find the 455 * existing STA entry, save it and delete it temporarily. 456 * After this we will get PCL as though as new STA connection 457 * is coming up. This will give the exact PCL that needs to be 458 * given to the FW. After setting the PCL, we need to restore 459 * the entry that we have saved before. 460 */ 461 462 if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 463 NULL) > 0) && 464 mode != QDF_STA_MODE) 465 polic_mgr_send_pcl_to_fw(psoc, mode); 466 467 /* do we need to change the HW mode */ 468 if (!policy_mgr_is_hw_dbs_capable(psoc)) 469 return; 470 471 policy_mgr_check_n_start_opportunistic_timer(psoc); 472 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) 473 ml_nlink_conn_change_notify( 474 psoc, session_id, ml_nlink_ap_stopped_evt, NULL); 475 } 476 477 /** 478 * policy_mgr_update_valid_ch_freq_list() - Update policy manager valid ch list 479 * @pm_ctx: policy manager context data 480 * @reg_ch_list: Regulatory channel list 481 * @is_client: true if caller is a client, false if it is a beaconing entity 482 * 483 * When regulatory component channel list is updated this internal function is 484 * called to update policy manager copy of valid channel list. 485 * 486 * Return: QDF_STATUS_SUCCESS on success other qdf error status code 487 */ 488 static void 489 policy_mgr_update_valid_ch_freq_list(struct policy_mgr_psoc_priv_obj *pm_ctx, 490 struct regulatory_channel *reg_ch_list, 491 bool is_client) 492 { 493 uint32_t i, j = 0, ch_freq; 494 enum channel_state state; 495 496 for (i = 0; i < NUM_CHANNELS; i++) { 497 ch_freq = reg_ch_list[i].center_freq; 498 if (is_client) 499 state = wlan_reg_get_channel_state_for_pwrmode( 500 pm_ctx->pdev, ch_freq, 501 REG_CURRENT_PWR_MODE); 502 else 503 state = 504 wlan_reg_get_channel_state_from_secondary_list_for_freq( 505 pm_ctx->pdev, ch_freq); 506 507 if (state != CHANNEL_STATE_DISABLE && 508 state != CHANNEL_STATE_INVALID) { 509 pm_ctx->valid_ch_freq_list[j] = 510 reg_ch_list[i].center_freq; 511 j++; 512 } 513 } 514 pm_ctx->valid_ch_freq_list_count = j; 515 } 516 517 #ifdef FEATURE_WLAN_CH_AVOID_EXT 518 void 519 policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx, 520 struct ch_avoid_ind_type *freq_list) 521 { 522 pm_ctx->restriction_mask = freq_list->restriction_mask; 523 } 524 525 uint32_t 526 policy_mgr_get_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx) 527 { 528 return pm_ctx->restriction_mask; 529 } 530 #endif 531 532 void 533 policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, 534 struct wlan_objmgr_pdev *pdev, 535 struct regulatory_channel *chan_list, 536 struct avoid_freq_ind_data *avoid_freq_ind, 537 void *arg) 538 { 539 struct policy_mgr_psoc_priv_obj *pm_ctx; 540 uint32_t i; 541 struct ch_avoid_ind_type *freq_list; 542 543 pm_ctx = policy_mgr_get_context(psoc); 544 if (!pm_ctx) { 545 policy_mgr_err("Invalid Context"); 546 return; 547 } 548 549 policy_mgr_update_valid_ch_freq_list(pm_ctx, chan_list, false); 550 551 if (!avoid_freq_ind) { 552 policy_mgr_debug("avoid_freq_ind NULL"); 553 return; 554 } 555 556 /* 557 * The ch_list buffer can accommodate a maximum of 558 * NUM_CHANNELS and hence the ch_cnt should also not 559 * exceed NUM_CHANNELS. 560 */ 561 pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.chan_cnt >= 562 NUM_CHANNELS ? 563 NUM_CHANNELS : avoid_freq_ind->chan_list.chan_cnt; 564 565 freq_list = &avoid_freq_ind->freq_list; 566 policy_mgr_set_freq_restriction_mask(pm_ctx, freq_list); 567 568 for (i = 0; i < pm_ctx->unsafe_channel_count; i++) 569 pm_ctx->unsafe_channel_list[i] = 570 avoid_freq_ind->chan_list.chan_freq_list[i]; 571 572 policy_mgr_debug("Channel list update, received %d avoided channels", 573 pm_ctx->unsafe_channel_count); 574 } 575 576 QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, 577 qdf_freq_t *chan_freq_list, 578 uint16_t chan_cnt) 579 { 580 struct policy_mgr_psoc_priv_obj *pm_ctx; 581 uint32_t i; 582 583 pm_ctx = policy_mgr_get_context(psoc); 584 if (!pm_ctx) { 585 policy_mgr_err("Invalid Context"); 586 return QDF_STATUS_E_FAILURE; 587 } 588 589 pm_ctx->unsafe_channel_count = chan_cnt >= NUM_CHANNELS ? 590 NUM_CHANNELS : chan_cnt; 591 592 for (i = 0; i < pm_ctx->unsafe_channel_count; i++) 593 pm_ctx->unsafe_channel_list[i] = chan_freq_list[i]; 594 595 policy_mgr_debug("Channel list init, received %d avoided channels", 596 pm_ctx->unsafe_channel_count); 597 598 return QDF_STATUS_SUCCESS; 599 } 600 601 void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, 602 uint32_t *pcl_channels, 603 uint32_t *len, 604 uint8_t *weight_list, 605 uint32_t weight_len) 606 { 607 uint32_t current_channel_list[NUM_CHANNELS]; 608 uint8_t org_weight_list[NUM_CHANNELS]; 609 uint8_t is_unsafe = 1; 610 uint8_t i, j; 611 uint32_t safe_channel_count = 0, current_channel_count = 0; 612 struct policy_mgr_psoc_priv_obj *pm_ctx; 613 uint8_t scc_on_lte_coex = 0; 614 uint32_t nan_2g_freq, nan_5g_freq; 615 616 pm_ctx = policy_mgr_get_context(psoc); 617 if (!pm_ctx) { 618 policy_mgr_err("Invalid Context"); 619 return; 620 } 621 622 if (len) { 623 current_channel_count = QDF_MIN(*len, NUM_CHANNELS); 624 } else { 625 policy_mgr_err("invalid number of channel length"); 626 return; 627 } 628 629 if (!pm_ctx->unsafe_channel_count) 630 return; 631 632 qdf_mem_copy(current_channel_list, pcl_channels, 633 current_channel_count * sizeof(*current_channel_list)); 634 qdf_mem_zero(pcl_channels, 635 current_channel_count * sizeof(*pcl_channels)); 636 637 qdf_mem_copy(org_weight_list, weight_list, NUM_CHANNELS); 638 qdf_mem_zero(weight_list, weight_len); 639 640 policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_on_lte_coex); 641 nan_2g_freq = 642 policy_mgr_mode_specific_get_channel(pm_ctx->psoc, 643 PM_NAN_DISC_MODE); 644 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc); 645 646 for (i = 0; i < current_channel_count; i++) { 647 is_unsafe = 0; 648 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) { 649 if (current_channel_list[i] == 650 pm_ctx->unsafe_channel_list[j]) { 651 /* Found unsafe channel, update it */ 652 is_unsafe = 1; 653 policy_mgr_debug("CH %d is not safe", 654 current_channel_list[i]); 655 break; 656 } 657 } 658 if (is_unsafe && scc_on_lte_coex && 659 policy_mgr_is_sta_sap_scc(psoc, current_channel_list[i])) { 660 policy_mgr_debug("CH %d unsafe ignored when STA present on it", 661 current_channel_list[i]); 662 is_unsafe = 0; 663 } else if (is_unsafe && 664 (nan_2g_freq == current_channel_list[i] || 665 nan_5g_freq == current_channel_list[i]) && 666 policy_mgr_is_force_scc(pm_ctx->psoc) && 667 policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(pm_ctx->psoc)) { 668 is_unsafe = 0; 669 } 670 671 if (!is_unsafe) { 672 pcl_channels[safe_channel_count] = 673 current_channel_list[i]; 674 if (safe_channel_count < weight_len) 675 weight_list[safe_channel_count] = 676 org_weight_list[i]; 677 safe_channel_count++; 678 } 679 } 680 *len = safe_channel_count; 681 682 return; 683 } 684 685 static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( 686 struct wlan_objmgr_psoc *psoc, 687 uint32_t *pcl_list_org, 688 uint8_t *weight_list_org, 689 uint32_t *pcl_len_org) 690 { 691 uint32_t i, pcl_len = 0; 692 bool allow_go_scc_on_dfs_chn = false; 693 bool dfs_master_capable = false; 694 uint8_t sta_sap_scc_on_dfs_chnl = 0; 695 QDF_STATUS status = QDF_STATUS_E_FAILURE; 696 struct policy_mgr_psoc_priv_obj *pm_ctx; 697 698 pm_ctx = policy_mgr_get_context(psoc); 699 if (!pm_ctx) { 700 policy_mgr_err("context is NULL"); 701 return status; 702 } 703 704 status = ucfg_mlme_get_dfs_master_capability(psoc, &dfs_master_capable); 705 if (QDF_IS_STATUS_ERROR(status)) { 706 policy_mgr_err("failed to get dfs master capable"); 707 return status; 708 } 709 710 status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, 711 &sta_sap_scc_on_dfs_chnl); 712 if (QDF_IS_STATUS_ERROR(status)) { 713 policy_mgr_err("failed to get sta_sap_scc_on_dfs_chnl"); 714 return status; 715 } 716 717 if (dfs_master_capable && sta_sap_scc_on_dfs_chnl && 718 pm_ctx->cfg.go_force_scc == GO_FORCE_SCC_STRICT) { 719 allow_go_scc_on_dfs_chn = true; 720 } 721 722 for (i = 0; i < *pcl_len_org; i++) { 723 if ((!wlan_reg_is_passive_or_disable_for_pwrmode( 724 pm_ctx->pdev, pcl_list_org[i], 725 REG_CURRENT_PWR_MODE)) || 726 (allow_go_scc_on_dfs_chn && 727 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_list_org[i]))) { 728 pcl_list_org[pcl_len] = pcl_list_org[i]; 729 weight_list_org[pcl_len++] = weight_list_org[i]; 730 } 731 } 732 *pcl_len_org = pcl_len; 733 734 return QDF_STATUS_SUCCESS; 735 } 736 737 static QDF_STATUS policy_mgr_modify_pcl_based_on_dnbs( 738 struct wlan_objmgr_psoc *psoc, 739 uint32_t *pcl_list_org, 740 uint8_t *weight_list_org, 741 uint32_t *pcl_len_org) 742 { 743 uint32_t i, pcl_len = 0; 744 uint32_t pcl_list[NUM_CHANNELS]; 745 uint8_t weight_list[NUM_CHANNELS]; 746 bool ok; 747 QDF_STATUS status = QDF_STATUS_E_FAILURE; 748 749 if (*pcl_len_org > NUM_CHANNELS) { 750 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 751 return status; 752 } 753 for (i = 0; i < *pcl_len_org; i++) { 754 status = policy_mgr_is_chan_ok_for_dnbs(psoc, pcl_list_org[i], 755 &ok); 756 757 if (QDF_IS_STATUS_ERROR(status)) { 758 policy_mgr_err("Not able to check DNBS eligibility"); 759 return status; 760 } 761 if (ok) { 762 pcl_list[pcl_len] = pcl_list_org[i]; 763 weight_list[pcl_len++] = weight_list_org[i]; 764 } 765 } 766 767 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); 768 qdf_mem_zero(weight_list_org, *pcl_len_org); 769 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); 770 qdf_mem_copy(weight_list_org, weight_list, pcl_len); 771 *pcl_len_org = pcl_len; 772 773 return QDF_STATUS_SUCCESS; 774 } 775 776 uint32_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, 777 enum policy_mgr_con_mode mode, 778 uint32_t *vdev_id) 779 { 780 uint32_t idx = 0; 781 struct policy_mgr_psoc_priv_obj *pm_ctx; 782 783 pm_ctx = policy_mgr_get_context(psoc); 784 if (!pm_ctx) { 785 policy_mgr_err("Invalid Context"); 786 return 0; 787 } 788 789 if (mode >= PM_MAX_NUM_OF_MODE) { 790 policy_mgr_err("incorrect mode"); 791 return 0; 792 } 793 794 for (idx = 0; idx < MAX_NUMBER_OF_CONC_CONNECTIONS; idx++) { 795 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 796 if ((pm_conc_connection_list[idx].mode == mode) && 797 (!vdev_id || (*vdev_id == 798 pm_conc_connection_list[idx].vdev_id)) 799 && pm_conc_connection_list[idx].in_use) { 800 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 801 return pm_conc_connection_list[idx].freq; 802 } 803 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 804 } 805 806 return 0; 807 } 808 809 QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc, 810 bool *skip_dfs_channel) 811 { 812 bool sta_sap_scc_on_dfs_chan; 813 bool dfs_master_capable; 814 QDF_STATUS status; 815 816 status = ucfg_mlme_get_dfs_master_capability(psoc, 817 &dfs_master_capable); 818 if (QDF_IS_STATUS_ERROR(status)) { 819 policy_mgr_err("failed to get dfs master capable"); 820 return status; 821 } 822 823 *skip_dfs_channel = false; 824 if (!dfs_master_capable) { 825 policy_mgr_debug("skip DFS ch for SAP/Go dfs master cap %d", 826 dfs_master_capable); 827 *skip_dfs_channel = true; 828 return QDF_STATUS_SUCCESS; 829 } 830 831 sta_sap_scc_on_dfs_chan = 832 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 833 834 if (policy_mgr_is_hw_dbs_capable(psoc)) { 835 if ((policy_mgr_is_special_mode_active_5g(psoc, 836 PM_P2P_CLIENT_MODE) || 837 policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)) && 838 !sta_sap_scc_on_dfs_chan) { 839 policy_mgr_debug("skip DFS ch from pcl for DBS SAP/Go"); 840 *skip_dfs_channel = true; 841 } 842 } else { 843 if ((policy_mgr_mode_specific_connection_count(psoc, 844 PM_STA_MODE, 845 NULL) > 0) && 846 !sta_sap_scc_on_dfs_chan) { 847 policy_mgr_debug("skip DFS ch from pcl for non-DBS SAP/Go"); 848 *skip_dfs_channel = true; 849 } 850 } 851 852 return QDF_STATUS_SUCCESS; 853 } 854 855 /** 856 * policy_mgr_modify_sap_pcl_based_on_dfs() - filter out DFS channel if needed 857 * @psoc: pointer to soc 858 * @pcl_list_org: channel list to filter out 859 * @weight_list_org: weight of channel list 860 * @pcl_len_org: length of channel list 861 * 862 * Return: QDF_STATUS 863 */ 864 static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs( 865 struct wlan_objmgr_psoc *psoc, 866 uint32_t *pcl_list_org, 867 uint8_t *weight_list_org, 868 uint32_t *pcl_len_org) 869 { 870 size_t i, pcl_len = 0; 871 struct policy_mgr_psoc_priv_obj *pm_ctx; 872 bool skip_dfs_channel = false; 873 QDF_STATUS status; 874 875 pm_ctx = policy_mgr_get_context(psoc); 876 if (!pm_ctx) { 877 policy_mgr_err("Invalid Context"); 878 return QDF_STATUS_E_FAILURE; 879 } 880 if (*pcl_len_org > NUM_CHANNELS) { 881 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 882 return QDF_STATUS_E_FAILURE; 883 } 884 885 status = policy_mgr_skip_dfs_ch(psoc, &skip_dfs_channel); 886 if (QDF_IS_STATUS_ERROR(status)) { 887 policy_mgr_err("failed to get dfs channel skip info"); 888 return status; 889 } 890 891 if (!skip_dfs_channel) 892 return QDF_STATUS_SUCCESS; 893 894 for (i = 0; i < *pcl_len_org; i++) { 895 if (!wlan_reg_is_dfs_in_secondary_list_for_freq( 896 pm_ctx->pdev, 897 pcl_list_org[i])) { 898 pcl_list_org[pcl_len] = pcl_list_org[i]; 899 weight_list_org[pcl_len++] = weight_list_org[i]; 900 } 901 } 902 903 *pcl_len_org = pcl_len; 904 905 return QDF_STATUS_SUCCESS; 906 } 907 908 static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol( 909 struct wlan_objmgr_psoc *psoc, 910 uint32_t *pcl_list_org, 911 uint8_t *weight_list_org, 912 uint32_t *pcl_len_org) 913 { 914 uint32_t i, pcl_len = 0; 915 uint32_t pcl_list[NUM_CHANNELS]; 916 uint8_t weight_list[NUM_CHANNELS]; 917 struct policy_mgr_psoc_priv_obj *pm_ctx; 918 919 pm_ctx = policy_mgr_get_context(psoc); 920 if (!pm_ctx) { 921 policy_mgr_err("Invalid Context"); 922 return QDF_STATUS_E_FAILURE; 923 } 924 if (*pcl_len_org > NUM_CHANNELS) { 925 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 926 return QDF_STATUS_E_FAILURE; 927 } 928 929 for (i = 0; i < *pcl_len_org; i++) { 930 if (!wlan_reg_is_disable_in_secondary_list_for_freq( 931 pm_ctx->pdev, pcl_list_org[i])) { 932 pcl_list[pcl_len] = pcl_list_org[i]; 933 weight_list[pcl_len++] = weight_list_org[i]; 934 } 935 } 936 937 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); 938 qdf_mem_zero(weight_list_org, *pcl_len_org); 939 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); 940 qdf_mem_copy(weight_list_org, weight_list, pcl_len); 941 *pcl_len_org = pcl_len; 942 943 return QDF_STATUS_SUCCESS; 944 } 945 946 static QDF_STATUS 947 policy_mgr_modify_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc, 948 uint32_t *pcl_list_org, 949 uint8_t *weight_list_org, 950 uint32_t *pcl_len_org) 951 { 952 uint32_t i, pcl_len = 0; 953 uint32_t pcl_list[NUM_CHANNELS]; 954 uint8_t weight_list[NUM_CHANNELS]; 955 struct policy_mgr_psoc_priv_obj *pm_ctx; 956 957 pm_ctx = policy_mgr_get_context(psoc); 958 if (!pm_ctx) { 959 policy_mgr_err("Invalid Context"); 960 return QDF_STATUS_E_FAILURE; 961 } 962 963 if (*pcl_len_org > NUM_CHANNELS) { 964 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 965 return QDF_STATUS_E_FAILURE; 966 } 967 for (i = 0; i < *pcl_len_org; i++) { 968 if (wlan_reg_is_etsi_srd_chan_for_freq( 969 pm_ctx->pdev, pcl_list_org[i])) 970 continue; 971 pcl_list[pcl_len] = pcl_list_org[i]; 972 weight_list[pcl_len++] = weight_list_org[i]; 973 } 974 975 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); 976 qdf_mem_zero(weight_list_org, *pcl_len_org); 977 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); 978 qdf_mem_copy(weight_list_org, weight_list, pcl_len); 979 *pcl_len_org = pcl_len; 980 981 return QDF_STATUS_SUCCESS; 982 } 983 984 /** 985 * policy_mgr_modify_pcl_based_on_indoor() - filter out indoor channel if needed 986 * @psoc: pointer to soc 987 * @pcl_list_org: channel list to filter out 988 * @weight_list_org: weight of channel list 989 * @pcl_len_org: length of channel list 990 * 991 * Return: QDF_STATUS 992 */ 993 static QDF_STATUS 994 policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc, 995 uint32_t *pcl_list_org, 996 uint8_t *weight_list_org, 997 uint32_t *pcl_len_org) 998 { 999 uint32_t i, pcl_len = 0; 1000 uint32_t pcl_list[NUM_CHANNELS]; 1001 uint8_t weight_list[NUM_CHANNELS]; 1002 struct policy_mgr_psoc_priv_obj *pm_ctx; 1003 bool include_indoor_channel, sta_sap_scc_on_indoor_channel_allowed; 1004 QDF_STATUS status; 1005 1006 pm_ctx = policy_mgr_get_context(psoc); 1007 if (!pm_ctx) { 1008 policy_mgr_err("Invalid Context"); 1009 return QDF_STATUS_E_FAILURE; 1010 } 1011 1012 if (*pcl_len_org > NUM_CHANNELS) { 1013 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 1014 return QDF_STATUS_E_FAILURE; 1015 } 1016 1017 status = ucfg_mlme_get_indoor_channel_support(psoc, 1018 &include_indoor_channel); 1019 if (QDF_IS_STATUS_ERROR(status)) { 1020 policy_mgr_err("failed to get indoor channel skip info"); 1021 return status; 1022 } 1023 1024 /* 1025 * If STA SAP scc is allowed on indoor channels, and if STA/P2P 1026 * client is present on 5 GHz channel, include indoor channels 1027 */ 1028 sta_sap_scc_on_indoor_channel_allowed = 1029 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 1030 if (!include_indoor_channel && sta_sap_scc_on_indoor_channel_allowed && 1031 (policy_mgr_is_special_mode_active_5g(psoc, PM_P2P_CLIENT_MODE) || 1032 policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE))) 1033 include_indoor_channel = true; 1034 1035 if (include_indoor_channel) { 1036 policy_mgr_debug("Indoor channels allowed. PCL not modified for indoor channels"); 1037 return QDF_STATUS_SUCCESS; 1038 } 1039 1040 for (i = 0; i < *pcl_len_org; i++) { 1041 if (wlan_reg_is_freq_indoor_in_secondary_list(pm_ctx->pdev, 1042 pcl_list_org[i])) { 1043 policy_mgr_debug("Remove freq: %d from PCL as it's indoor", 1044 pcl_list_org[i]); 1045 continue; 1046 } 1047 pcl_list[pcl_len] = pcl_list_org[i]; 1048 weight_list[pcl_len++] = weight_list_org[i]; 1049 } 1050 1051 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); 1052 qdf_mem_zero(weight_list_org, *pcl_len_org); 1053 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); 1054 qdf_mem_copy(weight_list_org, weight_list, pcl_len); 1055 *pcl_len_org = pcl_len; 1056 1057 return QDF_STATUS_SUCCESS; 1058 } 1059 1060 /** 1061 * policy_mgr_modify_sap_pcl_for_6G_channels() - filter out the 1062 * 6GHz channels where SCC is not supported. 1063 * @psoc: pointer to soc 1064 * @pcl_list_org: channel list to filter out 1065 * @weight_list_org: weight of channel list 1066 * @pcl_len_org: length of channel list 1067 * 1068 * Return: QDF_STATUS 1069 */ 1070 static QDF_STATUS 1071 policy_mgr_modify_sap_pcl_for_6G_channels(struct wlan_objmgr_psoc *psoc, 1072 uint32_t *pcl_list_org, 1073 uint8_t *weight_list_org, 1074 uint32_t *pcl_len_org) 1075 { 1076 struct policy_mgr_psoc_priv_obj *pm_ctx; 1077 uint32_t pcl_list[NUM_CHANNELS]; 1078 uint8_t weight_list[NUM_CHANNELS]; 1079 uint32_t vdev_id = 0, pcl_len = 0, i; 1080 struct wlan_objmgr_vdev *vdev; 1081 qdf_freq_t sta_gc_6ghz_freq = 0; 1082 uint32_t ap_pwr_type_6g = 0; 1083 bool indoor_ch_support = false; 1084 bool keep_6ghz_sta_cli_conn; 1085 1086 pm_ctx = policy_mgr_get_context(psoc); 1087 if (!pm_ctx) { 1088 policy_mgr_err("Invalid Context"); 1089 return QDF_STATUS_E_FAILURE; 1090 } 1091 1092 if (*pcl_len_org > NUM_CHANNELS) { 1093 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 1094 return QDF_STATUS_E_FAILURE; 1095 } 1096 1097 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1098 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 1099 if ((pm_conc_connection_list[i].mode == PM_STA_MODE || 1100 pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE) && 1101 pm_conc_connection_list[i].in_use) { 1102 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(pm_conc_connection_list[i].freq)) 1103 continue; 1104 sta_gc_6ghz_freq = pm_conc_connection_list[i].freq; 1105 vdev_id = pm_conc_connection_list[i].vdev_id; 1106 break; 1107 } 1108 } 1109 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 1110 1111 if (!sta_gc_6ghz_freq) 1112 return QDF_STATUS_SUCCESS; 1113 1114 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1115 WLAN_POLICY_MGR_ID); 1116 if (!vdev) { 1117 policy_mgr_err("vdev %d is not present", vdev_id); 1118 return QDF_STATUS_E_FAILURE; 1119 } 1120 1121 /* If STA is present in 6GHz PSC, STA+SAP SCC is allowed 1122 * only for the following combinations: 1123 * 1124 * VLP STA + SAP - Allowed with VLP Power 1125 * LPI STA + SAP - Allowed with VLP power if channel supports VLP. 1126 * LPI STA + SAP - Allowed with LPI power if gindoor_channel_support=1 1127 */ 1128 ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev); 1129 policy_mgr_debug("STA power type : %d", ap_pwr_type_6g); 1130 1131 ucfg_mlme_get_indoor_channel_support(psoc, &indoor_ch_support); 1132 keep_6ghz_sta_cli_conn = wlan_reg_get_keep_6ghz_sta_cli_connection( 1133 pm_ctx->pdev); 1134 for (i = 0; i < *pcl_len_org; i++) { 1135 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_list_org[i])) { 1136 if (!WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(pcl_list_org[i]) || 1137 keep_6ghz_sta_cli_conn) 1138 continue; 1139 if (ap_pwr_type_6g == REG_VERY_LOW_POWER_AP) 1140 goto add_freq; 1141 else if (ap_pwr_type_6g == REG_INDOOR_AP && 1142 (!wlan_reg_is_freq_indoor(pm_ctx->pdev, 1143 pcl_list_org[i]) || 1144 indoor_ch_support)) 1145 goto add_freq; 1146 else 1147 continue; 1148 } 1149 add_freq: 1150 pcl_list[pcl_len] = pcl_list_org[i]; 1151 weight_list[pcl_len++] = weight_list_org[i]; 1152 } 1153 1154 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); 1155 qdf_mem_zero(weight_list_org, *pcl_len_org * sizeof(*weight_list_org)); 1156 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); 1157 qdf_mem_copy(weight_list_org, weight_list, pcl_len); 1158 *pcl_len_org = pcl_len; 1159 1160 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 1161 return QDF_STATUS_SUCCESS; 1162 } 1163 1164 /** 1165 * policy_mgr_channel_mcc_with_non_sap() - Helper function to check if channel 1166 * is MCC with exist non-movable connections. 1167 * @psoc: pointer to SOC 1168 * @chan_freq: channel frequency to check 1169 * 1170 * Return: true if is MCC with exist non-movable connections, otherwise false. 1171 */ 1172 static bool policy_mgr_channel_mcc_with_non_sap(struct wlan_objmgr_psoc *psoc, 1173 qdf_freq_t chan_freq) 1174 { 1175 uint32_t i, connection_of_2ghz = 0; 1176 qdf_freq_t conc_freq; 1177 bool is_mcc = false, check_only_dbs = false; 1178 struct policy_mgr_psoc_priv_obj *pm_ctx; 1179 1180 pm_ctx = policy_mgr_get_context(psoc); 1181 if (!pm_ctx) { 1182 policy_mgr_err("Invalid Context"); 1183 return false; 1184 } 1185 1186 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1187 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 1188 if (pm_conc_connection_list[i].in_use && 1189 WLAN_REG_IS_24GHZ_CH_FREQ(pm_conc_connection_list[i].freq)) 1190 connection_of_2ghz++; 1191 } 1192 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 1193 1194 if (connection_of_2ghz >= 2) 1195 check_only_dbs = true; 1196 1197 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1198 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 1199 if (pm_conc_connection_list[i].in_use && 1200 (pm_conc_connection_list[i].mode == PM_STA_MODE || 1201 pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE || 1202 pm_conc_connection_list[i].mode == PM_P2P_GO_MODE)) { 1203 conc_freq = pm_conc_connection_list[i].freq; 1204 if (conc_freq != chan_freq && 1205 ((check_only_dbs && 1206 policy_mgr_2_freq_same_mac_in_dbs(pm_ctx, 1207 chan_freq, 1208 conc_freq)) || 1209 policy_mgr_2_freq_always_on_same_mac(psoc, 1210 chan_freq, 1211 conc_freq))) { 1212 is_mcc = true; 1213 break; 1214 } 1215 } 1216 } 1217 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 1218 1219 return is_mcc; 1220 } 1221 1222 /** 1223 * policy_mgr_modify_sap_pcl_filter_mcc() - API to filter out MCC channel with 1224 * existing non-SAP connection frequency from SAP PCL list. 1225 * @psoc: pointer to SOC 1226 * @pcl_list_org: channel list to filter out 1227 * @weight_list_org: weight of channel list 1228 * @pcl_len_org: length of channel list 1229 * @mode: Policy manager connection mode 1230 * 1231 * Return: QDF_STATUS 1232 */ 1233 static QDF_STATUS 1234 policy_mgr_modify_sap_pcl_filter_mcc(struct wlan_objmgr_psoc *psoc, 1235 uint32_t *pcl_list_org, 1236 uint8_t *weight_list_org, 1237 uint32_t *pcl_len_org, 1238 enum policy_mgr_con_mode mode) 1239 { 1240 uint32_t i, pcl_len = 0; 1241 struct policy_mgr_psoc_priv_obj *pm_ctx; 1242 1243 if (mode == PM_LL_LT_SAP_MODE) 1244 return QDF_STATUS_SUCCESS; 1245 1246 pm_ctx = policy_mgr_get_context(psoc); 1247 if (!pm_ctx) { 1248 policy_mgr_err("Invalid Context"); 1249 return QDF_STATUS_E_FAILURE; 1250 } 1251 1252 if (*pcl_len_org > NUM_CHANNELS) { 1253 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 1254 return QDF_STATUS_E_FAILURE; 1255 } 1256 1257 if (!policy_mgr_is_force_scc(psoc)) { 1258 policy_mgr_debug("force SCC is not prefer, skip!"); 1259 return QDF_STATUS_SUCCESS; 1260 } 1261 1262 for (i = 0; i < *pcl_len_org; i++) { 1263 if (policy_mgr_channel_mcc_with_non_sap(psoc, pcl_list_org[i])) 1264 continue; 1265 1266 pcl_list_org[pcl_len] = pcl_list_org[i]; 1267 weight_list_org[pcl_len++] = weight_list_org[i]; 1268 } 1269 1270 *pcl_len_org = pcl_len; 1271 1272 return QDF_STATUS_SUCCESS; 1273 } 1274 1275 /** 1276 * policy_mgr_modify_sap_go_4th_conc_disallow() - filter out channel that 1277 * is not allowed for 4th sap/go connection 1278 * @psoc: pointer to soc 1279 * @mode: interface mode 1280 * @pcl_list_org: channel list to filter out 1281 * @weight_list_org: weight of channel list 1282 * @pcl_len_org: length of channel list 1283 * 1284 * Return: QDF_STATUS 1285 */ 1286 static QDF_STATUS policy_mgr_modify_sap_go_4th_conc_disallow( 1287 struct wlan_objmgr_psoc *psoc, 1288 enum policy_mgr_con_mode mode, 1289 uint32_t *pcl_list_org, 1290 uint8_t *weight_list_org, 1291 uint32_t *pcl_len_org) 1292 { 1293 size_t i, pcl_len = 0; 1294 struct policy_mgr_psoc_priv_obj *pm_ctx; 1295 uint32_t num_connections; 1296 1297 pm_ctx = policy_mgr_get_context(psoc); 1298 if (!pm_ctx) { 1299 policy_mgr_err("Invalid Context"); 1300 return QDF_STATUS_E_FAILURE; 1301 } 1302 if (*pcl_len_org > NUM_CHANNELS) { 1303 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); 1304 return QDF_STATUS_E_FAILURE; 1305 } 1306 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1307 num_connections = policy_mgr_get_connection_count(psoc); 1308 if (num_connections < 3) 1309 goto end; 1310 1311 for (i = 0; i < *pcl_len_org; i++) { 1312 if (policy_mgr_allow_4th_new_freq(psoc, pcl_list_org[i], 1313 mode, 0)) { 1314 pcl_list_org[pcl_len] = pcl_list_org[i]; 1315 weight_list_org[pcl_len++] = weight_list_org[i]; 1316 } 1317 } 1318 1319 *pcl_len_org = pcl_len; 1320 end: 1321 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 1322 1323 return QDF_STATUS_SUCCESS; 1324 } 1325 1326 static QDF_STATUS policy_mgr_pcl_modification_for_sap( 1327 struct wlan_objmgr_psoc *psoc, 1328 uint32_t *pcl_channels, uint8_t *pcl_weight, 1329 uint32_t *len, uint32_t weight_len, 1330 enum policy_mgr_con_mode mode) 1331 { 1332 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1333 struct policy_mgr_psoc_priv_obj *pm_ctx; 1334 bool mandatory_modified_pcl = false; 1335 bool nol_modified_pcl = false; 1336 bool dfs_modified_pcl = false; 1337 bool indoor_modified_pcl = false; 1338 bool passive_modified_pcl = false; 1339 bool band_6ghz_modified_pcl = false; 1340 bool fourth_conc_modified_pcl = false; 1341 bool modified_final_pcl = false; 1342 bool srd_chan_enabled; 1343 1344 pm_ctx = policy_mgr_get_context(psoc); 1345 if (!pm_ctx) { 1346 policy_mgr_err("Invalid context"); 1347 return QDF_STATUS_E_FAILURE; 1348 } 1349 1350 /* check the channel avoidance list for beaconing entities */ 1351 policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, 1352 len, pcl_weight, weight_len); 1353 1354 if (policy_mgr_is_sap_mandatory_channel_set(psoc)) { 1355 status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( 1356 psoc, pcl_channels, pcl_weight, len); 1357 if (QDF_IS_STATUS_ERROR(status)) { 1358 policy_mgr_err( 1359 "failed to get mandatory modified pcl for SAP"); 1360 return status; 1361 } 1362 mandatory_modified_pcl = true; 1363 } 1364 1365 status = policy_mgr_modify_sap_pcl_based_on_nol( 1366 psoc, pcl_channels, pcl_weight, len); 1367 if (QDF_IS_STATUS_ERROR(status)) { 1368 policy_mgr_err("failed to get nol modified pcl for SAP"); 1369 return status; 1370 } 1371 nol_modified_pcl = true; 1372 1373 status = policy_mgr_modify_sap_pcl_based_on_dfs( 1374 psoc, pcl_channels, pcl_weight, len); 1375 if (QDF_IS_STATUS_ERROR(status)) { 1376 policy_mgr_err("failed to get dfs modified pcl for SAP"); 1377 return status; 1378 } 1379 dfs_modified_pcl = true; 1380 1381 wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_SAP_MODE, 1382 &srd_chan_enabled); 1383 1384 if (!srd_chan_enabled) { 1385 status = policy_mgr_modify_pcl_based_on_srd 1386 (psoc, pcl_channels, pcl_weight, len); 1387 if (QDF_IS_STATUS_ERROR(status)) { 1388 policy_mgr_err("Failed to modify SRD in pcl for SAP"); 1389 return status; 1390 } 1391 } 1392 1393 status = policy_mgr_modify_pcl_based_on_indoor(psoc, pcl_channels, 1394 pcl_weight, len); 1395 if (QDF_IS_STATUS_ERROR(status)) { 1396 policy_mgr_err("failed to get indoor modified pcl for SAP"); 1397 return status; 1398 } 1399 indoor_modified_pcl = true; 1400 1401 status = policy_mgr_filter_passive_ch(pm_ctx->pdev, 1402 pcl_channels, len); 1403 1404 if (QDF_IS_STATUS_ERROR(status)) { 1405 policy_mgr_err("failed to filter passive channels"); 1406 return INVALID_CHANNEL_ID; 1407 } 1408 passive_modified_pcl = true; 1409 1410 status = policy_mgr_modify_sap_pcl_for_6G_channels(psoc, 1411 pcl_channels, 1412 pcl_weight, len); 1413 if (QDF_IS_STATUS_ERROR(status)) { 1414 policy_mgr_err("failed to modify pcl for 6G channels"); 1415 return status; 1416 } 1417 band_6ghz_modified_pcl = true; 1418 1419 status = policy_mgr_modify_sap_go_4th_conc_disallow(psoc, 1420 PM_SAP_MODE, 1421 pcl_channels, 1422 pcl_weight, len); 1423 if (QDF_IS_STATUS_ERROR(status)) { 1424 policy_mgr_err("failed to modify pcl for 4th sap channels"); 1425 return status; 1426 } 1427 fourth_conc_modified_pcl = true; 1428 1429 status = policy_mgr_modify_sap_pcl_filter_mcc(psoc, 1430 pcl_channels, 1431 pcl_weight, len, 1432 mode); 1433 if (QDF_IS_STATUS_ERROR(status)) { 1434 policy_mgr_err("failed to modify pcl for filter mcc"); 1435 return status; 1436 } 1437 1438 modified_final_pcl = true; 1439 policy_mgr_debug("%d %d %d %d %d %d %d %d", 1440 mandatory_modified_pcl, 1441 nol_modified_pcl, 1442 dfs_modified_pcl, 1443 indoor_modified_pcl, 1444 passive_modified_pcl, 1445 band_6ghz_modified_pcl, 1446 fourth_conc_modified_pcl, 1447 modified_final_pcl); 1448 1449 return QDF_STATUS_SUCCESS; 1450 } 1451 1452 static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go( 1453 struct wlan_objmgr_psoc *psoc, 1454 uint32_t *pcl_channels, uint8_t *pcl_weight, 1455 uint32_t *len, uint32_t weight_len) 1456 { 1457 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1458 bool srd_chan_enabled; 1459 1460 /* check the channel avoidance list for beaconing entities */ 1461 policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, 1462 len, pcl_weight, weight_len); 1463 1464 status = policy_mgr_modify_pcl_based_on_enabled_channels( 1465 psoc, pcl_channels, pcl_weight, len); 1466 if (QDF_IS_STATUS_ERROR(status)) { 1467 policy_mgr_err("failed to get modified pcl for GO"); 1468 return status; 1469 } 1470 1471 status = policy_mgr_modify_sap_pcl_based_on_dfs( 1472 psoc, pcl_channels, pcl_weight, len); 1473 if (QDF_IS_STATUS_ERROR(status)) { 1474 policy_mgr_err("failed to get dfs modified pcl for GO"); 1475 return status; 1476 } 1477 1478 wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_P2P_GO_MODE, 1479 &srd_chan_enabled); 1480 1481 if (!srd_chan_enabled) { 1482 status = policy_mgr_modify_pcl_based_on_srd 1483 (psoc, pcl_channels, pcl_weight, len); 1484 if (QDF_IS_STATUS_ERROR(status)) { 1485 policy_mgr_err("Failed to modify SRD in pcl for GO"); 1486 return status; 1487 } 1488 } 1489 status = policy_mgr_modify_sap_go_4th_conc_disallow(psoc, 1490 PM_P2P_GO_MODE, 1491 pcl_channels, 1492 pcl_weight, len); 1493 if (QDF_IS_STATUS_ERROR(status)) { 1494 policy_mgr_err("failed to modify pcl for 4th go channels"); 1495 return status; 1496 } 1497 1498 return QDF_STATUS_SUCCESS; 1499 } 1500 1501 #ifdef WLAN_FEATURE_LL_LT_SAP 1502 #ifdef WLAN_FEATURE_LL_LT_SAP_6G_SUPPORT 1503 static bool policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq) 1504 { 1505 if (!wlan_reg_is_6ghz_chan_freq(freq)) 1506 return true; 1507 1508 if (wlan_reg_is_6ghz_psc_chan_freq(freq) && 1509 wlan_reg_is_6ghz_unii5_chan_freq(freq)) 1510 return true; 1511 1512 return false; 1513 } 1514 #else 1515 static inline bool policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq) 1516 { 1517 if (!wlan_reg_is_6ghz_chan_freq(freq)) 1518 return true; 1519 1520 return false; 1521 } 1522 #endif 1523 1524 static bool policy_mgr_is_dynamic_sbs_enabled(struct wlan_objmgr_psoc *psoc) 1525 { 1526 struct policy_mgr_psoc_priv_obj *pm_ctx; 1527 1528 pm_ctx = policy_mgr_get_context(psoc); 1529 if (!pm_ctx) 1530 return false; 1531 1532 return (policy_mgr_is_hw_sbs_capable(psoc) && 1533 policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx)); 1534 } 1535 1536 /** 1537 * policy_mgr_is_sbs_mac0_freq() - Check if the given frequency is 1538 * sbs frequency on mac0 for static sbs case. 1539 * @psoc: psoc pointer 1540 * @freq: Frequency which needs to be checked. 1541 * 1542 * Return: true/false. 1543 */ 1544 static bool policy_mgr_is_sbs_mac0_freq(struct wlan_objmgr_psoc *psoc, 1545 qdf_freq_t freq) 1546 { 1547 struct policy_mgr_psoc_priv_obj *pm_ctx; 1548 struct policy_mgr_freq_range *freq_range; 1549 1550 if (policy_mgr_is_dynamic_sbs_enabled(psoc)) 1551 return false; 1552 1553 pm_ctx = policy_mgr_get_context(psoc); 1554 if (!pm_ctx) 1555 return false; 1556 1557 freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS]; 1558 1559 if (policy_mgr_is_freq_on_mac_id(freq_range, freq, 0)) 1560 return true; 1561 1562 return false; 1563 } 1564 1565 static QDF_STATUS policy_mgr_pcl_modification_for_ll_lt_sap( 1566 struct wlan_objmgr_psoc *psoc, 1567 uint32_t *pcl_channels, uint8_t *pcl_weight, 1568 uint32_t *len, uint32_t weight_len) 1569 { 1570 struct policy_mgr_psoc_priv_obj *pm_ctx; 1571 uint32_t pcl_list[NUM_CHANNELS], orig_len = *len; 1572 uint8_t weight_list[NUM_CHANNELS]; 1573 uint32_t i, pcl_len = 0; 1574 bool sbs_mac0_modified_pcl = false; 1575 1576 pm_ctx = policy_mgr_get_context(psoc); 1577 if (!pm_ctx) { 1578 policy_mgr_err("pm_ctx is NULL"); 1579 return QDF_STATUS_E_FAILURE; 1580 } 1581 1582 policy_mgr_pcl_modification_for_sap( 1583 psoc, pcl_channels, pcl_weight, len, weight_len, 1584 PM_LL_LT_SAP_MODE); 1585 1586 for (i = 0; i < *len; i++) { 1587 /* Remove passive/dfs/6G invalid channel for LL_LT_SAP */ 1588 if (wlan_reg_is_24ghz_ch_freq(pcl_channels[i]) || 1589 wlan_reg_is_passive_for_freq( 1590 pm_ctx->pdev, 1591 pcl_channels[i]) || 1592 wlan_reg_is_dfs_for_freq( 1593 pm_ctx->pdev, 1594 pcl_channels[i]) || 1595 !policy_mgr_is_6G_chan_valid_for_ll_sap(pcl_channels[i])) 1596 continue; 1597 1598 /* Remove mac0 frequencies for static SBS case */ 1599 if (policy_mgr_is_sbs_mac0_freq(psoc, pcl_channels[i])) { 1600 sbs_mac0_modified_pcl = true; 1601 continue; 1602 } 1603 1604 pcl_list[pcl_len] = pcl_channels[i]; 1605 weight_list[pcl_len++] = pcl_weight[i]; 1606 } 1607 1608 if (orig_len == pcl_len) 1609 return QDF_STATUS_SUCCESS; 1610 1611 qdf_mem_zero(pcl_channels, *len * sizeof(*pcl_channels)); 1612 qdf_mem_zero(pcl_weight, *len); 1613 qdf_mem_copy(pcl_channels, pcl_list, pcl_len * sizeof(*pcl_channels)); 1614 qdf_mem_copy(pcl_weight, weight_list, pcl_len); 1615 *len = pcl_len; 1616 1617 policy_mgr_debug("sbs_mac0_modified_pcl %d, PCL after ll sap modification", 1618 sbs_mac0_modified_pcl); 1619 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); 1620 1621 return QDF_STATUS_SUCCESS; 1622 } 1623 #else 1624 static inline QDF_STATUS 1625 policy_mgr_pcl_modification_for_ll_lt_sap(struct wlan_objmgr_psoc *psoc, 1626 uint32_t *pcl_channels, 1627 uint8_t *pcl_weight, 1628 uint32_t *len, uint32_t weight_len) 1629 { 1630 return QDF_STATUS_SUCCESS; 1631 } 1632 #endif 1633 1634 static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl( 1635 struct wlan_objmgr_psoc *psoc, 1636 uint32_t *pcl_channels, uint8_t *pcl_weight, 1637 uint32_t *len, uint32_t weight_len, 1638 enum policy_mgr_con_mode mode) 1639 { 1640 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1641 1642 switch (mode) { 1643 case PM_SAP_MODE: 1644 status = policy_mgr_pcl_modification_for_sap( 1645 psoc, pcl_channels, pcl_weight, len, weight_len, mode); 1646 break; 1647 case PM_P2P_GO_MODE: 1648 status = policy_mgr_pcl_modification_for_p2p_go( 1649 psoc, pcl_channels, pcl_weight, len, weight_len); 1650 break; 1651 case PM_STA_MODE: 1652 case PM_P2P_CLIENT_MODE: 1653 case PM_NAN_DISC_MODE: 1654 status = QDF_STATUS_SUCCESS; 1655 break; 1656 case PM_LL_LT_SAP_MODE: 1657 status = policy_mgr_pcl_modification_for_ll_lt_sap( 1658 psoc, pcl_channels, pcl_weight, len, weight_len); 1659 break; 1660 default: 1661 policy_mgr_err("unexpected mode %d", mode); 1662 break; 1663 } 1664 1665 return status; 1666 } 1667 1668 #ifdef FEATURE_FOURTH_CONNECTION 1669 static enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port( 1670 struct wlan_objmgr_psoc *psoc, 1671 enum policy_mgr_con_mode mode, 1672 enum policy_mgr_conc_priority_mode pref) 1673 { 1674 enum policy_mgr_three_connection_mode fourth_index = 0; 1675 enum policy_mgr_pcl_type pcl; 1676 1677 /* Will be enhanced for other types of 4 port conc (NaN etc.) 1678 * in future. 1679 */ 1680 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 1681 policy_mgr_err("Can't find index for 4th port pcl table for non dbs capable"); 1682 return PM_MAX_PCL_TYPE; 1683 } 1684 1685 /* SAP and P2P Go have same result in 4th port pcl table */ 1686 if (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) 1687 mode = PM_SAP_MODE; 1688 else if (mode == PM_P2P_CLIENT_MODE) 1689 mode = PM_STA_MODE; 1690 1691 if (mode != PM_STA_MODE && mode != PM_SAP_MODE && 1692 mode != PM_NDI_MODE) { 1693 policy_mgr_err("Can't start 4th port if not STA, SAP, NDI"); 1694 return PM_MAX_PCL_TYPE; 1695 } 1696 1697 fourth_index = 1698 policy_mgr_get_fourth_connection_pcl_table_index(psoc); 1699 if (PM_MAX_THREE_CONNECTION_MODE == fourth_index) { 1700 policy_mgr_err("Can't find index for 4th port pcl table"); 1701 return PM_MAX_PCL_TYPE; 1702 } 1703 policy_mgr_debug("Index for 4th port pcl table: %d", fourth_index); 1704 1705 pcl = fourth_connection_pcl_dbs_sbs_table[fourth_index][mode][pref]; 1706 1707 return pcl; 1708 } 1709 #else 1710 static inline enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port( 1711 struct wlan_objmgr_psoc *psoc, 1712 enum policy_mgr_con_mode mode, 1713 enum policy_mgr_conc_priority_mode pref) 1714 {return PM_MAX_PCL_TYPE; } 1715 #endif 1716 1717 QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, 1718 enum policy_mgr_con_mode mode, 1719 uint32_t *pcl_channels, uint32_t *len, 1720 uint8_t *pcl_weight, uint32_t weight_len, 1721 uint8_t vdev_id) 1722 { 1723 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1724 uint32_t num_connections = 0; 1725 enum policy_mgr_conc_priority_mode first_index = 0; 1726 enum policy_mgr_one_connection_mode second_index = 0; 1727 enum policy_mgr_two_connection_mode third_index = 0; 1728 enum policy_mgr_pcl_type pcl = PM_NONE; 1729 enum policy_mgr_conc_priority_mode conc_system_pref = 0; 1730 struct policy_mgr_psoc_priv_obj *pm_ctx; 1731 enum QDF_OPMODE qdf_mode; 1732 uint32_t orig_pcl_len; 1733 1734 pm_ctx = policy_mgr_get_context(psoc); 1735 if (!pm_ctx) { 1736 policy_mgr_err("context is NULL"); 1737 return status; 1738 } 1739 1740 if ((mode < 0) || (mode >= PM_MAX_NUM_OF_MODE)) { 1741 policy_mgr_err("Invalid connection mode %d received", mode); 1742 return status; 1743 } 1744 1745 /* find the current connection state from pm_conc_connection_list*/ 1746 num_connections = policy_mgr_get_connection_count(psoc); 1747 policy_mgr_debug("connections:%d pref:%d requested mode:%d vdev_id:%d", 1748 num_connections, pm_ctx->cur_conc_system_pref, mode, 1749 vdev_id); 1750 1751 switch (pm_ctx->cur_conc_system_pref) { 1752 case 0: 1753 conc_system_pref = PM_THROUGHPUT; 1754 break; 1755 case 1: 1756 conc_system_pref = PM_POWERSAVE; 1757 break; 1758 case 2: 1759 conc_system_pref = PM_LATENCY; 1760 break; 1761 default: 1762 policy_mgr_err("unknown cur_conc_system_pref value %d", 1763 pm_ctx->cur_conc_system_pref); 1764 break; 1765 } 1766 1767 switch (num_connections) { 1768 case 0: 1769 first_index = 1770 policy_mgr_get_first_connection_pcl_table_index(psoc); 1771 pcl = first_connection_pcl_table[mode][first_index]; 1772 break; 1773 case 1: 1774 second_index = 1775 policy_mgr_get_second_connection_pcl_table_index(psoc); 1776 if (PM_MAX_ONE_CONNECTION_MODE == second_index) { 1777 policy_mgr_err("couldn't find index for 2nd connection pcl table"); 1778 return status; 1779 } 1780 qdf_mode = policy_mgr_get_qdf_mode_from_pm(mode); 1781 if (qdf_mode == QDF_MAX_NO_OF_MODE) 1782 return status; 1783 1784 if (policy_mgr_is_hw_dbs_capable(psoc) == true && 1785 policy_mgr_is_dbs_allowed_for_concurrency( 1786 psoc, qdf_mode)) { 1787 pcl = (*second_connection_pcl_dbs_table) 1788 [second_index][mode][conc_system_pref]; 1789 } else { 1790 pcl = (*second_connection_pcl_non_dbs_table) 1791 [second_index][mode][conc_system_pref]; 1792 } 1793 1794 break; 1795 case 2: 1796 third_index = 1797 policy_mgr_get_third_connection_pcl_table_index(psoc); 1798 if (PM_MAX_TWO_CONNECTION_MODE == third_index) { 1799 policy_mgr_err( 1800 "couldn't find index for 3rd connection pcl table"); 1801 return status; 1802 } 1803 if (policy_mgr_is_hw_dbs_capable(psoc) == true) { 1804 pcl = (*third_connection_pcl_dbs_table) 1805 [third_index][mode][conc_system_pref]; 1806 } else { 1807 pcl = (*third_connection_pcl_non_dbs_table) 1808 [third_index][mode][conc_system_pref]; 1809 } 1810 break; 1811 case 3: 1812 pcl = policy_mgr_get_pcl_4_port(psoc, mode, conc_system_pref); 1813 break; 1814 default: 1815 policy_mgr_err("unexpected num_connections value %d", 1816 num_connections); 1817 break; 1818 } 1819 1820 /* once the PCL enum is obtained find out the exact channel list with 1821 * help from sme_get_cfg_valid_channels 1822 */ 1823 status = policy_mgr_get_channel_list(psoc, pcl, mode, pcl_channels, 1824 pcl_weight, weight_len, len); 1825 if (QDF_IS_STATUS_ERROR(status)) { 1826 policy_mgr_err("failed to get channel list:%d", status); 1827 return status; 1828 } 1829 1830 if (!*len) { 1831 policymgr_nofl_debug("Total PCL Chan %d", *len); 1832 return QDF_STATUS_SUCCESS; 1833 } 1834 orig_pcl_len = *len; 1835 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); 1836 policy_mgr_mode_specific_modification_on_pcl( 1837 psoc, pcl_channels, pcl_weight, len, weight_len, mode); 1838 1839 status = policy_mgr_modify_pcl_based_on_dnbs(psoc, pcl_channels, 1840 pcl_weight, len); 1841 1842 if (QDF_IS_STATUS_ERROR(status)) { 1843 policy_mgr_err("failed to get modified pcl based on DNBS"); 1844 return status; 1845 } 1846 1847 if (orig_pcl_len != *len) { 1848 policy_mgr_debug("PCL after modification"); 1849 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); 1850 } 1851 1852 return QDF_STATUS_SUCCESS; 1853 } 1854 1855 enum policy_mgr_conc_priority_mode 1856 policy_mgr_get_first_connection_pcl_table_index( 1857 struct wlan_objmgr_psoc *psoc) 1858 { 1859 struct policy_mgr_psoc_priv_obj *pm_ctx; 1860 1861 pm_ctx = policy_mgr_get_context(psoc); 1862 if (!pm_ctx) { 1863 policy_mgr_err("context is NULL"); 1864 return PM_THROUGHPUT; 1865 } 1866 1867 if (pm_ctx->cur_conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE) 1868 return PM_THROUGHPUT; 1869 1870 return pm_ctx->cur_conc_system_pref; 1871 } 1872 1873 enum policy_mgr_one_connection_mode 1874 policy_mgr_get_second_connection_pcl_table_index( 1875 struct wlan_objmgr_psoc *psoc) 1876 { 1877 enum policy_mgr_one_connection_mode index = PM_MAX_ONE_CONNECTION_MODE; 1878 struct policy_mgr_psoc_priv_obj *pm_ctx; 1879 1880 pm_ctx = policy_mgr_get_context(psoc); 1881 if (!pm_ctx) { 1882 policy_mgr_err("Invalid Context"); 1883 return index; 1884 } 1885 1886 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1887 if (PM_STA_MODE == pm_conc_connection_list[0].mode) { 1888 if (WLAN_REG_IS_24GHZ_CH_FREQ( 1889 pm_conc_connection_list[0].freq)) { 1890 if (POLICY_MGR_ONE_ONE == 1891 pm_conc_connection_list[0].chain_mask) 1892 index = PM_STA_24_1x1; 1893 else 1894 index = PM_STA_24_2x2; 1895 } else { 1896 if (POLICY_MGR_ONE_ONE == 1897 pm_conc_connection_list[0].chain_mask) 1898 index = PM_STA_5_1x1; 1899 else 1900 index = PM_STA_5_2x2; 1901 } 1902 } else if (PM_SAP_MODE == pm_conc_connection_list[0].mode) { 1903 if (WLAN_REG_IS_24GHZ_CH_FREQ( 1904 pm_conc_connection_list[0].freq)) { 1905 if (POLICY_MGR_ONE_ONE == 1906 pm_conc_connection_list[0].chain_mask) 1907 index = PM_SAP_24_1x1; 1908 else 1909 index = PM_SAP_24_2x2; 1910 } else { 1911 if (POLICY_MGR_ONE_ONE == 1912 pm_conc_connection_list[0].chain_mask) 1913 index = PM_SAP_5_1x1; 1914 else 1915 index = PM_SAP_5_2x2; 1916 } 1917 } else if (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) { 1918 if (WLAN_REG_IS_24GHZ_CH_FREQ( 1919 pm_conc_connection_list[0].freq)) { 1920 if (POLICY_MGR_ONE_ONE == 1921 pm_conc_connection_list[0].chain_mask) 1922 index = PM_P2P_CLI_24_1x1; 1923 else 1924 index = PM_P2P_CLI_24_2x2; 1925 } else { 1926 if (POLICY_MGR_ONE_ONE == 1927 pm_conc_connection_list[0].chain_mask) 1928 index = PM_P2P_CLI_5_1x1; 1929 else 1930 index = PM_P2P_CLI_5_2x2; 1931 } 1932 } else if (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) { 1933 if (WLAN_REG_IS_24GHZ_CH_FREQ( 1934 pm_conc_connection_list[0].freq)) { 1935 if (POLICY_MGR_ONE_ONE == 1936 pm_conc_connection_list[0].chain_mask) 1937 index = PM_P2P_GO_24_1x1; 1938 else 1939 index = PM_P2P_GO_24_2x2; 1940 } else { 1941 if (POLICY_MGR_ONE_ONE == 1942 pm_conc_connection_list[0].chain_mask) 1943 index = PM_P2P_GO_5_1x1; 1944 else 1945 index = PM_P2P_GO_5_2x2; 1946 } 1947 } else if (PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) { 1948 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 1949 index = PM_NAN_DISC_24_1x1; 1950 else 1951 index = PM_NAN_DISC_24_2x2; 1952 } else if (PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) { 1953 index = PM_LL_LT_SAP_5_2x2; 1954 } 1955 1956 policy_mgr_debug("mode:%d freq:%d chain:%d index:%d", 1957 pm_conc_connection_list[0].mode, 1958 pm_conc_connection_list[0].freq, 1959 pm_conc_connection_list[0].chain_mask, index); 1960 1961 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 1962 1963 return index; 1964 } 1965 1966 /* 1967 * policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc() - 1968 * This function checks connection mode is in scc or not and returns 1969 * index value based on mode and prvided index inputs. 1970 * 1971 * @scc_2g_1x1: index of scc_2g_1x1 for provided concurrency 1972 * @scc_2g_2x2: index of scc_2g_2x2 for provided concurrency 1973 * @scc_5g_1x1: index of scc_5g_1x1 for provided concurrency 1974 * @scc_5g_2x2: index of scc_5g_2x2 for provided concurrency 1975 * 1976 * Return: policy_mgr_two_connection_mode index 1977 */ 1978 static enum policy_mgr_two_connection_mode 1979 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 1980 enum policy_mgr_two_connection_mode scc_2g_1x1, 1981 enum policy_mgr_two_connection_mode scc_2g_2x2, 1982 enum policy_mgr_two_connection_mode scc_5g_1x1, 1983 enum policy_mgr_two_connection_mode scc_5g_2x2) 1984 { 1985 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 1986 1987 if (pm_conc_connection_list[0].freq == 1988 pm_conc_connection_list[1].freq) { 1989 if (WLAN_REG_IS_24GHZ_CH_FREQ( 1990 pm_conc_connection_list[0].freq)) { 1991 if (POLICY_MGR_ONE_ONE == 1992 pm_conc_connection_list[0].chain_mask) 1993 index = scc_2g_1x1; 1994 else 1995 index = scc_2g_2x2; 1996 } else { 1997 if (POLICY_MGR_ONE_ONE == 1998 pm_conc_connection_list[0].chain_mask) 1999 index = scc_5g_1x1; 2000 else 2001 index = scc_5g_2x2; 2002 } 2003 } 2004 return index; 2005 } 2006 2007 /* 2008 * policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc() - 2009 * This function checks connection mode is in mcc or not and returns 2010 * index value based on mode and prvided index inputs. 2011 * 2012 * @mcc_2g_1x1: index of mcc_2g_1x1 for provided concurrency 2013 * @mcc_2g_2x2: index of mcc_2g_2x2 for provided concurrency 2014 * @mcc_5g_1x1: index of mcc_5g_1x1 for provided concurrency 2015 * @mcc_5g_2x2: index of mcc_5g_2x2 for provided concurrency 2016 * @mcc_24_5_1x1: index of mcc_24_5_1x1 for provided concurrency 2017 * @mcc_24_5_2x2: index of mcc_24_5_2x2 for provided concurrency 2018 * 2019 * Return: policy_mgr_two_connection_mode index 2020 */ 2021 static enum policy_mgr_two_connection_mode 2022 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc( 2023 struct wlan_objmgr_psoc *psoc, 2024 enum policy_mgr_two_connection_mode mcc_2g_1x1, 2025 enum policy_mgr_two_connection_mode mcc_2g_2x2, 2026 enum policy_mgr_two_connection_mode mcc_5g_1x1, 2027 enum policy_mgr_two_connection_mode mcc_5g_2x2, 2028 enum policy_mgr_two_connection_mode mcc_24_5_1x1, 2029 enum policy_mgr_two_connection_mode mcc_24_5_2x2) 2030 { 2031 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2032 2033 if (policy_mgr_are_2_freq_on_same_mac(psoc, 2034 pm_conc_connection_list[0].freq, 2035 pm_conc_connection_list[1].freq) 2036 ) { 2037 if ((WLAN_REG_IS_24GHZ_CH_FREQ( 2038 pm_conc_connection_list[0].freq)) && 2039 (WLAN_REG_IS_24GHZ_CH_FREQ( 2040 pm_conc_connection_list[1].freq))) { 2041 if (POLICY_MGR_ONE_ONE == 2042 pm_conc_connection_list[0].chain_mask) 2043 index = mcc_2g_1x1; 2044 else 2045 index = mcc_2g_2x2; 2046 } else if (!(WLAN_REG_IS_24GHZ_CH_FREQ( 2047 pm_conc_connection_list[0].freq)) && 2048 !(WLAN_REG_IS_24GHZ_CH_FREQ( 2049 pm_conc_connection_list[1].freq))) { 2050 if (POLICY_MGR_ONE_ONE == 2051 pm_conc_connection_list[0].chain_mask) 2052 index = mcc_5g_1x1; 2053 else 2054 index = mcc_5g_2x2; 2055 } else { 2056 if (POLICY_MGR_ONE_ONE == 2057 pm_conc_connection_list[0].chain_mask) 2058 index = mcc_24_5_1x1; 2059 else 2060 index = mcc_24_5_2x2; 2061 } 2062 } 2063 return index; 2064 } 2065 2066 /* 2067 * policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs() - 2068 * This function checks connection mode is in dbs or sbs and returns index 2069 * value based on mode and prvided index inputs. 2070 * 2071 * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency 2072 * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency 2073 * @dbs_1x1: index of dbs_1x1 for provided concurrency 2074 * @dbs_2x2: index of dbs_2x2 for provided concurrency 2075 * 2076 * Return: policy_mgr_two_connection_mode index 2077 */ 2078 static enum policy_mgr_two_connection_mode 2079 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( 2080 struct wlan_objmgr_psoc *psoc, 2081 enum policy_mgr_two_connection_mode sbs_5g_1x1, 2082 enum policy_mgr_two_connection_mode sbs_5g_2x2, 2083 enum policy_mgr_two_connection_mode dbs_1x1, 2084 enum policy_mgr_two_connection_mode dbs_2x2) 2085 { 2086 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2087 2088 if (!policy_mgr_are_2_freq_on_same_mac(psoc, 2089 pm_conc_connection_list[0].freq, 2090 pm_conc_connection_list[1].freq) 2091 ) { 2092 /* SBS */ 2093 if (!(WLAN_REG_IS_24GHZ_CH_FREQ( 2094 pm_conc_connection_list[0].freq)) && 2095 !(WLAN_REG_IS_24GHZ_CH_FREQ( 2096 pm_conc_connection_list[1].freq))) { 2097 if (POLICY_MGR_ONE_ONE == 2098 pm_conc_connection_list[0].chain_mask) 2099 index = sbs_5g_1x1; 2100 else 2101 index = sbs_5g_2x2; 2102 } else { 2103 /* DBS */ 2104 if (POLICY_MGR_ONE_ONE == 2105 pm_conc_connection_list[0].chain_mask) 2106 index = dbs_1x1; 2107 else 2108 index = dbs_2x2; 2109 } 2110 } 2111 2112 return index; 2113 } 2114 2115 /* 2116 * policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta() - 2117 * Get third connection pcl table index when ML STA is present 2118 * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency 2119 * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency 2120 * @dbs_1x1: index of dbs_1x1 for provided concurrency 2121 * @dbs_2x2: index of dbs_2x2 for provided concurrency 2122 * 2123 * This function checks connection mode is in dbs or sbs when two ML STA links 2124 * are active and returns index value based on mode and provided index inputs. 2125 * 2126 * Return: policy_mgr_two_connection_mode index 2127 */ 2128 static enum policy_mgr_two_connection_mode 2129 policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta( 2130 struct wlan_objmgr_psoc *psoc, 2131 enum policy_mgr_two_connection_mode sbs_5g_1x1, 2132 enum policy_mgr_two_connection_mode sbs_5g_2x2, 2133 enum policy_mgr_two_connection_mode dbs_1x1, 2134 enum policy_mgr_two_connection_mode dbs_2x2) 2135 { 2136 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2137 2138 if (!policy_mgr_2_freq_always_on_same_mac( 2139 psoc, 2140 pm_conc_connection_list[0].freq, 2141 pm_conc_connection_list[1].freq)) { 2142 /* SBS */ 2143 if (!(WLAN_REG_IS_24GHZ_CH_FREQ( 2144 pm_conc_connection_list[0].freq)) && 2145 !(WLAN_REG_IS_24GHZ_CH_FREQ( 2146 pm_conc_connection_list[1].freq))) { 2147 if (POLICY_MGR_ONE_ONE == 2148 pm_conc_connection_list[0].chain_mask) 2149 index = sbs_5g_1x1; 2150 else 2151 index = sbs_5g_2x2; 2152 } else { 2153 /* DBS */ 2154 if (POLICY_MGR_ONE_ONE == 2155 pm_conc_connection_list[0].chain_mask) 2156 index = dbs_1x1; 2157 else 2158 index = dbs_2x2; 2159 } 2160 } 2161 2162 return index; 2163 } 2164 2165 static enum policy_mgr_two_connection_mode 2166 policy_mgr_get_third_connection_pcl_table_index_cli_sap( 2167 struct wlan_objmgr_psoc *psoc) 2168 { 2169 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2170 2171 index = 2172 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2173 PM_P2P_CLI_SAP_SCC_24_1x1, 2174 PM_P2P_CLI_SAP_SCC_24_2x2, 2175 PM_P2P_CLI_SAP_SCC_5_1x1, 2176 PM_P2P_CLI_SAP_SCC_5_2x2); 2177 if (index != PM_MAX_TWO_CONNECTION_MODE) 2178 return index; 2179 2180 index = 2181 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2182 PM_P2P_CLI_SAP_MCC_24_1x1, 2183 PM_P2P_CLI_SAP_MCC_24_2x2, 2184 PM_P2P_CLI_SAP_MCC_5_1x1, 2185 PM_P2P_CLI_SAP_MCC_5_2x2, 2186 PM_P2P_CLI_SAP_MCC_24_5_1x1, 2187 PM_P2P_CLI_SAP_MCC_24_5_2x2); 2188 2189 if (index != PM_MAX_TWO_CONNECTION_MODE) 2190 return index; 2191 2192 index = 2193 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2194 PM_P2P_CLI_SAP_SBS_5_1x1, 2195 PM_P2P_CLI_SAP_SBS_5_2x2, 2196 PM_P2P_CLI_SAP_DBS_1x1, 2197 PM_P2P_CLI_SAP_DBS_2x2); 2198 2199 return index; 2200 } 2201 2202 static enum policy_mgr_two_connection_mode 2203 policy_mgr_get_third_connection_pcl_table_index_sta_sap( 2204 struct wlan_objmgr_psoc *psoc) 2205 { 2206 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2207 2208 index = 2209 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2210 PM_STA_SAP_SCC_24_1x1, 2211 PM_STA_SAP_SCC_24_2x2, 2212 PM_STA_SAP_SCC_5_1x1, 2213 PM_STA_SAP_SCC_5_2x2); 2214 if (index != PM_MAX_TWO_CONNECTION_MODE) 2215 return index; 2216 2217 index = 2218 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2219 PM_STA_SAP_MCC_24_1x1, 2220 PM_STA_SAP_MCC_24_2x2, 2221 PM_STA_SAP_MCC_5_1x1, 2222 PM_STA_SAP_MCC_5_2x2, 2223 PM_STA_SAP_MCC_24_5_1x1, 2224 PM_STA_SAP_MCC_24_5_2x2); 2225 2226 if (index != PM_MAX_TWO_CONNECTION_MODE) 2227 return index; 2228 2229 index = 2230 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2231 PM_STA_SAP_SBS_5_1x1, 2232 PM_STA_SAP_SBS_5_2x2, 2233 PM_STA_SAP_DBS_1x1, 2234 PM_STA_SAP_DBS_2x2); 2235 2236 return index; 2237 } 2238 2239 static enum policy_mgr_two_connection_mode 2240 policy_mgr_get_third_connection_pcl_table_index_sap_sap( 2241 struct wlan_objmgr_psoc *psoc) 2242 { 2243 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2244 2245 index = 2246 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2247 PM_SAP_SAP_SCC_24_1x1, 2248 PM_SAP_SAP_SCC_24_2x2, 2249 PM_SAP_SAP_SCC_5_1x1, 2250 PM_SAP_SAP_SCC_5_2x2); 2251 if (index != PM_MAX_TWO_CONNECTION_MODE) 2252 return index; 2253 2254 index = 2255 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2256 PM_SAP_SAP_MCC_24_1x1, 2257 PM_SAP_SAP_MCC_24_2x2, 2258 PM_SAP_SAP_MCC_5_1x1, 2259 PM_SAP_SAP_MCC_5_2x2, 2260 PM_SAP_SAP_MCC_24_5_1x1, 2261 PM_SAP_SAP_MCC_24_5_2x2); 2262 2263 if (index != PM_MAX_TWO_CONNECTION_MODE) 2264 return index; 2265 2266 index = 2267 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2268 PM_SAP_SAP_SBS_5_1x1, 2269 PM_SAP_SAP_SBS_5_2x2, 2270 PM_SAP_SAP_DBS_1x1, 2271 PM_SAP_SAP_DBS_2x2); 2272 2273 return index; 2274 } 2275 2276 static enum policy_mgr_two_connection_mode 2277 policy_mgr_get_third_connection_pcl_table_index_sta_go( 2278 struct wlan_objmgr_psoc *psoc) 2279 { 2280 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2281 2282 index = 2283 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2284 PM_STA_P2P_GO_SCC_24_1x1, 2285 PM_STA_P2P_GO_SCC_24_2x2, 2286 PM_STA_P2P_GO_SCC_5_1x1, 2287 PM_STA_P2P_GO_SCC_5_2x2); 2288 if (index != PM_MAX_TWO_CONNECTION_MODE) 2289 return index; 2290 2291 index = 2292 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2293 PM_STA_P2P_GO_MCC_24_1x1, 2294 PM_STA_P2P_GO_MCC_24_2x2, 2295 PM_STA_P2P_GO_MCC_5_1x1, 2296 PM_STA_P2P_GO_MCC_5_2x2, 2297 PM_STA_P2P_GO_MCC_24_5_1x1, 2298 PM_STA_P2P_GO_MCC_24_5_2x2); 2299 2300 if (index != PM_MAX_TWO_CONNECTION_MODE) 2301 return index; 2302 2303 index = 2304 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2305 PM_STA_P2P_GO_SBS_5_1x1, 2306 PM_STA_P2P_GO_SBS_5_2x2, 2307 PM_STA_P2P_GO_DBS_1x1, 2308 PM_STA_P2P_GO_DBS_2x2); 2309 2310 return index; 2311 } 2312 2313 static enum policy_mgr_two_connection_mode 2314 policy_mgr_get_third_connection_pcl_table_index_sta_cli( 2315 struct wlan_objmgr_psoc *psoc) 2316 { 2317 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2318 2319 index = 2320 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2321 PM_STA_P2P_CLI_SCC_24_1x1, 2322 PM_STA_P2P_CLI_SCC_24_2x2, 2323 PM_STA_P2P_CLI_SCC_5_1x1, 2324 PM_STA_P2P_CLI_SCC_5_2x2); 2325 if (index != PM_MAX_TWO_CONNECTION_MODE) 2326 return index; 2327 2328 index = 2329 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2330 PM_STA_P2P_CLI_MCC_24_1x1, 2331 PM_STA_P2P_CLI_MCC_24_2x2, 2332 PM_STA_P2P_CLI_MCC_5_1x1, 2333 PM_STA_P2P_CLI_MCC_5_2x2, 2334 PM_STA_P2P_CLI_MCC_24_5_1x1, 2335 PM_STA_P2P_CLI_MCC_24_5_2x2); 2336 2337 if (index != PM_MAX_TWO_CONNECTION_MODE) 2338 return index; 2339 2340 index = 2341 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2342 PM_STA_P2P_CLI_SBS_5_1x1, 2343 PM_STA_P2P_CLI_SBS_5_2x2, 2344 PM_STA_P2P_CLI_DBS_1x1, 2345 PM_STA_P2P_CLI_DBS_2x2); 2346 2347 return index; 2348 } 2349 2350 static enum policy_mgr_two_connection_mode 2351 policy_mgr_get_third_connection_pcl_table_index_go_cli( 2352 struct wlan_objmgr_psoc *psoc) 2353 { 2354 enum policy_mgr_two_connection_mode index; 2355 2356 index = 2357 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2358 PM_P2P_GO_P2P_CLI_SCC_24_1x1, 2359 PM_P2P_GO_P2P_CLI_SCC_24_2x2, 2360 PM_P2P_GO_P2P_CLI_SCC_5_1x1, 2361 PM_P2P_GO_P2P_CLI_SCC_5_2x2); 2362 if (index != PM_MAX_TWO_CONNECTION_MODE) 2363 return index; 2364 2365 index = 2366 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2367 PM_P2P_GO_P2P_CLI_MCC_24_1x1, 2368 PM_P2P_GO_P2P_CLI_MCC_24_2x2, 2369 PM_P2P_GO_P2P_CLI_MCC_5_1x1, 2370 PM_P2P_GO_P2P_CLI_MCC_5_2x2, 2371 PM_P2P_GO_P2P_CLI_MCC_24_5_1x1, 2372 PM_P2P_GO_P2P_CLI_MCC_24_5_2x2); 2373 2374 if (index != PM_MAX_TWO_CONNECTION_MODE) 2375 return index; 2376 2377 index = 2378 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2379 PM_P2P_GO_P2P_CLI_SBS_5_1x1, 2380 PM_P2P_GO_P2P_CLI_SBS_5_2x2, 2381 PM_P2P_GO_P2P_CLI_DBS_1x1, 2382 PM_P2P_GO_P2P_CLI_DBS_2x2); 2383 2384 return index; 2385 } 2386 2387 static enum policy_mgr_two_connection_mode 2388 policy_mgr_get_third_connection_pcl_table_index_go_sap( 2389 struct wlan_objmgr_psoc *psoc) 2390 { 2391 enum policy_mgr_two_connection_mode index; 2392 2393 index = 2394 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2395 PM_P2P_GO_SAP_SCC_24_1x1, 2396 PM_P2P_GO_SAP_SCC_24_2x2, 2397 PM_P2P_GO_SAP_SCC_5_1x1, 2398 PM_P2P_GO_SAP_SCC_5_2x2); 2399 if (index != PM_MAX_TWO_CONNECTION_MODE) 2400 return index; 2401 2402 index = 2403 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2404 PM_P2P_GO_SAP_MCC_24_1x1, 2405 PM_P2P_GO_SAP_MCC_24_2x2, 2406 PM_P2P_GO_SAP_MCC_5_1x1, 2407 PM_P2P_GO_SAP_MCC_5_2x2, 2408 PM_P2P_GO_SAP_MCC_24_5_1x1, 2409 PM_P2P_GO_SAP_MCC_24_5_2x2); 2410 2411 if (index != PM_MAX_TWO_CONNECTION_MODE) 2412 return index; 2413 2414 index = 2415 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2416 PM_P2P_GO_SAP_SBS_5_1x1, 2417 PM_P2P_GO_SAP_SBS_5_2x2, 2418 PM_P2P_GO_SAP_DBS_1x1, 2419 PM_P2P_GO_SAP_DBS_2x2); 2420 2421 return index; 2422 } 2423 2424 static enum policy_mgr_two_connection_mode 2425 policy_mgr_get_third_connection_pcl_table_index_sta_sta( 2426 struct wlan_objmgr_psoc *psoc) 2427 { 2428 enum policy_mgr_two_connection_mode index; 2429 2430 if (policy_mgr_is_ml_vdev_id(psoc, 2431 pm_conc_connection_list[0].vdev_id) && 2432 policy_mgr_is_ml_vdev_id(psoc, 2433 pm_conc_connection_list[1].vdev_id)) { 2434 index = 2435 policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta( 2436 psoc, 2437 PM_STA_STA_SBS_5_1x1, 2438 PM_STA_STA_SBS_5_2x2, 2439 PM_STA_STA_DBS_1x1, 2440 PM_STA_STA_DBS_2x2); 2441 if (index != PM_MAX_TWO_CONNECTION_MODE) 2442 return index; 2443 } 2444 index = 2445 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2446 PM_STA_STA_SCC_24_1x1, 2447 PM_STA_STA_SCC_24_2x2, 2448 PM_STA_STA_SCC_5_1x1, 2449 PM_STA_STA_SCC_5_2x2); 2450 if (index != PM_MAX_TWO_CONNECTION_MODE) 2451 return index; 2452 2453 index = 2454 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2455 PM_STA_STA_MCC_24_1x1, 2456 PM_STA_STA_MCC_24_2x2, 2457 PM_STA_STA_MCC_5_1x1, 2458 PM_STA_STA_MCC_5_2x2, 2459 PM_STA_STA_MCC_24_5_1x1, 2460 PM_STA_STA_MCC_24_5_2x2); 2461 2462 if (index != PM_MAX_TWO_CONNECTION_MODE) 2463 return index; 2464 2465 index = 2466 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2467 PM_STA_STA_SBS_5_1x1, 2468 PM_STA_STA_SBS_5_2x2, 2469 PM_STA_STA_DBS_1x1, 2470 PM_STA_STA_DBS_2x2); 2471 2472 return index; 2473 } 2474 2475 static enum policy_mgr_two_connection_mode 2476 policy_mgr_get_third_connection_pcl_table_index_cli_cli( 2477 struct wlan_objmgr_psoc *psoc) 2478 { 2479 enum policy_mgr_two_connection_mode index; 2480 2481 index = 2482 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2483 PM_P2P_CLI_P2P_CLI_SCC_24_1x1, 2484 PM_P2P_CLI_P2P_CLI_SCC_24_2x2, 2485 PM_P2P_CLI_P2P_CLI_SCC_5_1x1, 2486 PM_P2P_CLI_P2P_CLI_SCC_5_2x2); 2487 if (index != PM_MAX_TWO_CONNECTION_MODE) 2488 return index; 2489 2490 index = 2491 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2492 PM_P2P_CLI_P2P_CLI_MCC_24_1x1, 2493 PM_P2P_CLI_P2P_CLI_MCC_24_2x2, 2494 PM_P2P_CLI_P2P_CLI_MCC_5_1x1, 2495 PM_P2P_CLI_P2P_CLI_MCC_5_2x2, 2496 PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1, 2497 PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2); 2498 2499 if (index != PM_MAX_TWO_CONNECTION_MODE) 2500 return index; 2501 2502 index = 2503 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2504 PM_P2P_CLI_P2P_CLI_SBS_5_1x1, 2505 PM_P2P_CLI_P2P_CLI_SBS_5_2x2, 2506 PM_P2P_CLI_P2P_CLI_DBS_1x1, 2507 PM_P2P_CLI_P2P_CLI_DBS_2x2); 2508 2509 return index; 2510 } 2511 2512 static enum policy_mgr_two_connection_mode 2513 policy_mgr_get_third_connection_pcl_table_index_go_go( 2514 struct wlan_objmgr_psoc *psoc) 2515 { 2516 enum policy_mgr_two_connection_mode index; 2517 2518 index = 2519 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc( 2520 PM_P2P_GO_P2P_GO_SCC_24_1x1, 2521 PM_P2P_GO_P2P_GO_SCC_24_2x2, 2522 PM_P2P_GO_P2P_GO_SCC_5_1x1, 2523 PM_P2P_GO_P2P_GO_SCC_5_2x2); 2524 if (index != PM_MAX_TWO_CONNECTION_MODE) 2525 return index; 2526 2527 index = 2528 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc, 2529 PM_P2P_GO_P2P_GO_MCC_24_1x1, 2530 PM_P2P_GO_P2P_GO_MCC_24_2x2, 2531 PM_P2P_GO_P2P_GO_MCC_5_1x1, 2532 PM_P2P_GO_P2P_GO_MCC_5_2x2, 2533 PM_P2P_GO_P2P_GO_MCC_24_5_1x1, 2534 PM_P2P_GO_P2P_GO_MCC_24_5_2x2); 2535 if (index != PM_MAX_TWO_CONNECTION_MODE) 2536 return index; 2537 2538 index = 2539 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc, 2540 PM_P2P_GO_P2P_GO_SBS_5_1x1, 2541 PM_P2P_GO_P2P_GO_SBS_5_2x2, 2542 PM_P2P_GO_P2P_GO_DBS_1x1, 2543 PM_P2P_GO_P2P_GO_DBS_2x2); 2544 return index; 2545 } 2546 2547 static enum policy_mgr_two_connection_mode 2548 policy_mgr_get_third_connection_pcl_table_index_nan_ndi( 2549 struct wlan_objmgr_psoc *psoc) 2550 { 2551 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2552 /* SCC */ 2553 if (pm_conc_connection_list[0].freq == 2554 pm_conc_connection_list[1].freq) { 2555 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 2556 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2557 index = PM_NAN_DISC_NDI_SCC_24_1x1; 2558 else 2559 index = PM_NAN_DISC_NDI_SCC_24_2x2; 2560 /* MCC */ 2561 } else if (policy_mgr_are_2_freq_on_same_mac(psoc, 2562 pm_conc_connection_list[0].freq, 2563 pm_conc_connection_list[1].freq)) { 2564 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 2565 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2566 index = PM_NAN_DISC_NDI_MCC_24_1x1; 2567 else 2568 index = PM_NAN_DISC_NDI_MCC_24_2x2; 2569 /* DBS */ 2570 } else { 2571 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2572 index = PM_NAN_DISC_NDI_DBS_1x1; 2573 else 2574 index = PM_NAN_DISC_NDI_DBS_2x2; 2575 } 2576 return index; 2577 } 2578 2579 static enum policy_mgr_two_connection_mode 2580 policy_mgr_get_third_connection_pcl_table_index_sta_nan( 2581 struct wlan_objmgr_psoc *psoc) 2582 { 2583 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2584 /* SCC */ 2585 if (pm_conc_connection_list[0].freq == 2586 pm_conc_connection_list[1].freq) { 2587 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 2588 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2589 index = PM_STA_NAN_DISC_SCC_24_1x1; 2590 else 2591 index = PM_STA_NAN_DISC_SCC_24_2x2; 2592 /* MCC */ 2593 } else if (policy_mgr_are_2_freq_on_same_mac(psoc, 2594 pm_conc_connection_list[0].freq, 2595 pm_conc_connection_list[1].freq)) { 2596 /* Policy mgr only considers NAN Disc ch in 2.4 GHz */ 2597 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2598 index = PM_STA_NAN_DISC_MCC_24_1x1; 2599 else 2600 index = PM_STA_NAN_DISC_MCC_24_2x2; 2601 /* DBS */ 2602 } else { 2603 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2604 index = PM_STA_NAN_DISC_DBS_1x1; 2605 else 2606 index = PM_STA_NAN_DISC_DBS_2x2; 2607 } 2608 return index; 2609 } 2610 2611 static enum policy_mgr_two_connection_mode 2612 policy_mgr_get_third_connection_pcl_table_index_sap_nan( 2613 struct wlan_objmgr_psoc *psoc) 2614 { 2615 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2616 /* SCC */ 2617 if (pm_conc_connection_list[0].freq == 2618 pm_conc_connection_list[1].freq) { 2619 /* Policy mgr only considers NAN Disc ch in 2.4 GHz */ 2620 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2621 index = PM_SAP_NAN_DISC_SCC_24_1x1; 2622 else 2623 index = PM_SAP_NAN_DISC_SCC_24_2x2; 2624 /* MCC */ 2625 } else if (policy_mgr_are_2_freq_on_same_mac(psoc, 2626 pm_conc_connection_list[0].freq, 2627 pm_conc_connection_list[1].freq)) { 2628 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 2629 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2630 index = PM_SAP_NAN_DISC_MCC_24_1x1; 2631 else 2632 index = PM_SAP_NAN_DISC_MCC_24_2x2; 2633 /* DBS */ 2634 } else { 2635 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) 2636 index = PM_SAP_NAN_DISC_DBS_1x1; 2637 else 2638 index = PM_SAP_NAN_DISC_DBS_2x2; 2639 } 2640 return index; 2641 } 2642 2643 static enum policy_mgr_two_connection_mode 2644 policy_mgr_get_third_connection_pcl_table_index_sta_ll_lt_sap( 2645 struct wlan_objmgr_psoc *psoc) 2646 { 2647 enum policy_mgr_two_connection_mode index; 2648 enum policy_mgr_two_connection_mode sbs_5g_1x1; 2649 enum policy_mgr_two_connection_mode sbs_5g_2x2; 2650 qdf_freq_t sta_freq, sbs_cut_off_freq; 2651 2652 /* 2653 * LL_LT_SAP can not be in SCC so there will not be any scc index. 2654 * With LL_LT_SAP, MCC is possible only on 5 GHz 2655 */ 2656 if (policy_mgr_are_2_freq_on_same_mac( 2657 psoc, 2658 pm_conc_connection_list[0].freq, 2659 pm_conc_connection_list[1].freq)) { 2660 if (!(WLAN_REG_IS_24GHZ_CH_FREQ( 2661 pm_conc_connection_list[0].freq)) && 2662 !(WLAN_REG_IS_24GHZ_CH_FREQ( 2663 pm_conc_connection_list[1].freq))) { 2664 if (POLICY_MGR_ONE_ONE == 2665 pm_conc_connection_list[0].chain_mask) 2666 index = PM_STA_5_LL_LT_SAP_MCC_1x1; 2667 else 2668 index = PM_STA_5_LL_LT_SAP_MCC_2x2; 2669 2670 return index; 2671 } 2672 } 2673 2674 if (pm_conc_connection_list[0].mode == PM_STA_MODE) 2675 sta_freq = pm_conc_connection_list[0].freq; 2676 else 2677 sta_freq = pm_conc_connection_list[1].freq; 2678 2679 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc); 2680 2681 if (sta_freq < sbs_cut_off_freq) { 2682 sbs_5g_1x1 = PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1; 2683 sbs_5g_2x2 = PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2; 2684 } else { 2685 sbs_5g_1x1 = PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1; 2686 sbs_5g_2x2 = PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2; 2687 } 2688 2689 index = 2690 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( 2691 psoc, sbs_5g_1x1, sbs_5g_2x2, 2692 PM_STA_24_LL_LT_SAP_DBS_1x1, 2693 PM_STA_24_LL_LT_SAP_DBS_2x2); 2694 return index; 2695 } 2696 2697 static enum policy_mgr_two_connection_mode 2698 policy_mgr_get_third_connection_pcl_table_index_sap_ll_lt_sap( 2699 struct wlan_objmgr_psoc *psoc) 2700 { 2701 enum policy_mgr_two_connection_mode index; 2702 enum policy_mgr_two_connection_mode sbs_5g_1x1; 2703 enum policy_mgr_two_connection_mode sbs_5g_2x2; 2704 qdf_freq_t sap_freq, sbs_cut_off_freq; 2705 2706 if (pm_conc_connection_list[0].mode == PM_SAP_MODE) 2707 sap_freq = pm_conc_connection_list[0].freq; 2708 else 2709 sap_freq = pm_conc_connection_list[1].freq; 2710 2711 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc); 2712 2713 if (sap_freq < sbs_cut_off_freq) { 2714 sbs_5g_1x1 = PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1; 2715 sbs_5g_2x2 = PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2; 2716 } else { 2717 sbs_5g_1x1 = PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1; 2718 sbs_5g_2x2 = PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2; 2719 } 2720 2721 /* 2722 * LL_LT_SAP can not be in SCC so there will not be any scc index. 2723 * For LL_LT_SAP + SAP, MCC is not possible, so there will be only 2724 * sbs or dbs index 2725 */ 2726 2727 index = 2728 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( 2729 psoc, sbs_5g_1x1, sbs_5g_2x2, 2730 PM_SAP_24_LL_LT_SAP_DBS_1x1, 2731 PM_SAP_24_LL_LT_SAP_DBS_2x2); 2732 return index; 2733 } 2734 2735 static enum policy_mgr_two_connection_mode 2736 policy_mgr_get_third_connection_pcl_table_index_go_ll_lt_sap( 2737 struct wlan_objmgr_psoc *psoc) 2738 { 2739 enum policy_mgr_two_connection_mode index; 2740 enum policy_mgr_two_connection_mode sbs_5g_1x1; 2741 enum policy_mgr_two_connection_mode sbs_5g_2x2; 2742 qdf_freq_t go_freq, sbs_cut_off_freq; 2743 2744 /* 2745 * LL_LT_SAP can not be in SCC so there will not be any scc index. 2746 * With LL_LT_SAP, MCC is possible only on 5 GHz 2747 */ 2748 if (policy_mgr_are_2_freq_on_same_mac( 2749 psoc, 2750 pm_conc_connection_list[0].freq, 2751 pm_conc_connection_list[1].freq)) { 2752 if (!(WLAN_REG_IS_24GHZ_CH_FREQ( 2753 pm_conc_connection_list[0].freq)) && 2754 !(WLAN_REG_IS_24GHZ_CH_FREQ( 2755 pm_conc_connection_list[1].freq))) { 2756 if (POLICY_MGR_ONE_ONE == 2757 pm_conc_connection_list[0].chain_mask) 2758 index = PM_P2P_GO_5_LL_LT_SAP_MCC_1x1; 2759 else 2760 index = PM_P2P_GO_5_LL_LT_SAP_MCC_2x2; 2761 2762 return index; 2763 } 2764 } 2765 2766 if (pm_conc_connection_list[0].mode == PM_P2P_GO_MODE) 2767 go_freq = pm_conc_connection_list[0].freq; 2768 else 2769 go_freq = pm_conc_connection_list[1].freq; 2770 2771 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc); 2772 2773 if (go_freq < sbs_cut_off_freq) { 2774 sbs_5g_1x1 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1; 2775 sbs_5g_2x2 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2; 2776 } else { 2777 sbs_5g_1x1 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1; 2778 sbs_5g_2x2 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2; 2779 } 2780 2781 index = 2782 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( 2783 psoc, sbs_5g_1x1, sbs_5g_2x2, 2784 PM_P2P_GO_24_LL_LT_SAP_DBS_1x1, 2785 PM_P2P_GO_24_LL_LT_SAP_DBS_2x2); 2786 return index; 2787 } 2788 2789 static enum policy_mgr_two_connection_mode 2790 policy_mgr_get_third_connection_pcl_table_index_cli_ll_lt_sap( 2791 struct wlan_objmgr_psoc *psoc) 2792 { 2793 enum policy_mgr_two_connection_mode index; 2794 enum policy_mgr_two_connection_mode sbs_5g_1x1; 2795 enum policy_mgr_two_connection_mode sbs_5g_2x2; 2796 qdf_freq_t cli_freq, sbs_cut_off_freq; 2797 2798 /* 2799 * LL_LT_SAP can not be in SCC so there will not be any scc index. 2800 * With LL_LT_SAP, MCC is possible only on 5 GHz 2801 */ 2802 if (policy_mgr_are_2_freq_on_same_mac( 2803 psoc, 2804 pm_conc_connection_list[0].freq, 2805 pm_conc_connection_list[1].freq)) { 2806 if (!(WLAN_REG_IS_24GHZ_CH_FREQ( 2807 pm_conc_connection_list[0].freq)) && 2808 !(WLAN_REG_IS_24GHZ_CH_FREQ( 2809 pm_conc_connection_list[1].freq))) { 2810 if (POLICY_MGR_ONE_ONE == 2811 pm_conc_connection_list[0].chain_mask) 2812 index = PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1; 2813 else 2814 index = PM_P2P_CLI_5_LL_LT_SAP_MCC_2x2; 2815 2816 return index; 2817 } 2818 } 2819 2820 if (pm_conc_connection_list[0].mode == PM_P2P_GO_MODE) 2821 cli_freq = pm_conc_connection_list[0].freq; 2822 else 2823 cli_freq = pm_conc_connection_list[1].freq; 2824 2825 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc); 2826 2827 if (cli_freq < sbs_cut_off_freq) { 2828 sbs_5g_1x1 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1; 2829 sbs_5g_2x2 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2; 2830 } else { 2831 sbs_5g_1x1 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1; 2832 sbs_5g_2x2 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2; 2833 } 2834 2835 index = 2836 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs( 2837 psoc, sbs_5g_1x1, sbs_5g_2x2, 2838 PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1, 2839 PM_P2P_CLI_24_LL_LT_SAP_DBS_2x2); 2840 return index; 2841 } 2842 2843 enum policy_mgr_two_connection_mode 2844 policy_mgr_get_third_connection_pcl_table_index( 2845 struct wlan_objmgr_psoc *psoc) 2846 { 2847 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; 2848 struct policy_mgr_psoc_priv_obj *pm_ctx; 2849 2850 pm_ctx = policy_mgr_get_context(psoc); 2851 if (!pm_ctx) { 2852 policy_mgr_err("Invalid Context"); 2853 return index; 2854 } 2855 2856 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 2857 if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && 2858 (PM_SAP_MODE == pm_conc_connection_list[1].mode)) || 2859 ((PM_SAP_MODE == pm_conc_connection_list[0].mode) && 2860 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode))) 2861 index = 2862 policy_mgr_get_third_connection_pcl_table_index_cli_sap(psoc); 2863 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2864 (PM_SAP_MODE == pm_conc_connection_list[1].mode)) || 2865 ((PM_SAP_MODE == pm_conc_connection_list[0].mode) && 2866 (PM_STA_MODE == pm_conc_connection_list[1].mode))) 2867 index = 2868 policy_mgr_get_third_connection_pcl_table_index_sta_sap(psoc); 2869 else if ((PM_SAP_MODE == pm_conc_connection_list[0].mode) && 2870 (PM_SAP_MODE == pm_conc_connection_list[1].mode)) 2871 index = 2872 policy_mgr_get_third_connection_pcl_table_index_sap_sap(psoc); 2873 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2874 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) || 2875 ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && 2876 (PM_STA_MODE == pm_conc_connection_list[1].mode))) 2877 index = 2878 policy_mgr_get_third_connection_pcl_table_index_sta_go(psoc); 2879 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2880 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) || 2881 ((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && 2882 (PM_STA_MODE == pm_conc_connection_list[1].mode))) 2883 index = 2884 policy_mgr_get_third_connection_pcl_table_index_sta_cli(psoc); 2885 else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && 2886 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) || 2887 ((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && 2888 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode))) 2889 index = 2890 policy_mgr_get_third_connection_pcl_table_index_go_cli(psoc); 2891 else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) && 2892 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) || 2893 ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && 2894 (PM_SAP_MODE == pm_conc_connection_list[1].mode))) 2895 index = 2896 policy_mgr_get_third_connection_pcl_table_index_go_sap(psoc); 2897 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2898 (PM_STA_MODE == pm_conc_connection_list[1].mode)) || 2899 ((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2900 (PM_STA_MODE == pm_conc_connection_list[1].mode))) 2901 index = 2902 policy_mgr_get_third_connection_pcl_table_index_sta_sta(psoc); 2903 else if (((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) && 2904 (PM_STA_MODE == pm_conc_connection_list[1].mode)) || 2905 ((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2906 (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode))) 2907 index = 2908 policy_mgr_get_third_connection_pcl_table_index_sta_nan(psoc); 2909 else if (((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) && 2910 (PM_NDI_MODE == pm_conc_connection_list[1].mode)) || 2911 ((PM_NDI_MODE == pm_conc_connection_list[0].mode) && 2912 (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode))) 2913 index = 2914 policy_mgr_get_third_connection_pcl_table_index_nan_ndi(psoc); 2915 else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) && 2916 (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)) || 2917 ((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) && 2918 (PM_SAP_MODE == pm_conc_connection_list[1].mode))) 2919 index = 2920 policy_mgr_get_third_connection_pcl_table_index_sap_nan(psoc); 2921 else if ((pm_conc_connection_list[0].mode == PM_P2P_GO_MODE) && 2922 (pm_conc_connection_list[1].mode == PM_P2P_GO_MODE)) 2923 index = 2924 policy_mgr_get_third_connection_pcl_table_index_go_go(psoc); 2925 2926 else if ((pm_conc_connection_list[0].mode == PM_P2P_CLIENT_MODE) && 2927 (pm_conc_connection_list[1].mode == PM_P2P_CLIENT_MODE)) 2928 index = 2929 policy_mgr_get_third_connection_pcl_table_index_cli_cli(psoc); 2930 2931 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && 2932 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) || 2933 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) && 2934 (PM_STA_MODE == pm_conc_connection_list[1].mode))) 2935 index = policy_mgr_get_third_connection_pcl_table_index_sta_ll_lt_sap(psoc); 2936 2937 else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) && 2938 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) || 2939 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) && 2940 (PM_SAP_MODE == pm_conc_connection_list[1].mode))) 2941 index = policy_mgr_get_third_connection_pcl_table_index_sap_ll_lt_sap(psoc); 2942 2943 else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && 2944 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) || 2945 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) && 2946 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode))) 2947 index = policy_mgr_get_third_connection_pcl_table_index_go_ll_lt_sap(psoc); 2948 2949 else if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && 2950 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) || 2951 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) && 2952 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode))) 2953 index = policy_mgr_get_third_connection_pcl_table_index_cli_ll_lt_sap(psoc); 2954 2955 policy_mgr_debug("mode0:%d mode1:%d freq0:%d freq1:%d chain:%d index:%d", 2956 pm_conc_connection_list[0].mode, 2957 pm_conc_connection_list[1].mode, 2958 pm_conc_connection_list[0].freq, 2959 pm_conc_connection_list[1].freq, 2960 pm_conc_connection_list[0].chain_mask, index); 2961 2962 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2963 2964 return index; 2965 } 2966 2967 #ifdef FEATURE_FOURTH_CONNECTION 2968 /** 2969 * policy_mgr_get_index_for_3_given_freq_dbs() - Find the index for next 2970 * connection for given 3 freq in DBS mode 2971 * @pm_ctx: policy manager context 2972 * @index: Index to return for next connection 2973 * @freq1: freq of interface 1 2974 * @freq2: freq of interface 2 2975 * @freq3: freq of interface 3 2976 * 2977 * This function finds the index for next connection for 3 freq in DBS mode. 2978 * 2979 * Return: none 2980 */ 2981 static void 2982 policy_mgr_get_index_for_3_given_freq_dbs( 2983 struct policy_mgr_psoc_priv_obj *pm_ctx, 2984 enum policy_mgr_three_connection_mode *index, 2985 qdf_freq_t freq1, qdf_freq_t freq2, qdf_freq_t freq3) 2986 { 2987 /* If all freq are on same band */ 2988 if ((WLAN_REG_IS_24GHZ_CH_FREQ(freq1) == 2989 WLAN_REG_IS_24GHZ_CH_FREQ(freq2) && 2990 (WLAN_REG_IS_24GHZ_CH_FREQ(freq2) == 2991 WLAN_REG_IS_24GHZ_CH_FREQ(freq3)))) { 2992 policy_mgr_err("Invalid mode for all freq %d, %d and %d on same band", 2993 freq1, freq2, freq3); 2994 return; 2995 } 2996 2997 /* 2998 * If freq1 and freq2 are on same band and freq3 is on differet band and 2999 * is not sharing mac with any SAP. STA on same band is handled above, 3000 * so both SAP on same band mean STA cannot be on same band. This can 3001 * happen if SBS is not enabled. 3002 */ 3003 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1) == 3004 WLAN_REG_IS_24GHZ_CH_FREQ(freq2)) { 3005 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq3)) 3006 /* 3007 * As all 3 cannot be on same band, so if freq3 is 3008 * 2.4 GHZ mean both freq1 and freq2 are on 5 / 6 GHZ 3009 */ 3010 *index = PM_5_SCC_MCC_PLUS_24_DBS; 3011 else 3012 /* 3013 * As all 3 cannot be on same band, so if freq3 is 3014 * 5 / 6 GHZ, mean both freq1 and freq2 are on 2.4 GHZ. 3015 */ 3016 *index = PM_24_SCC_MCC_PLUS_5_DBS; 3017 return; 3018 } 3019 3020 /* 3021 * if freq1 and freq 2 are on different band (2 GHZ + 5 GHZ/6 GHZ DBS), 3022 * check with which freq the freq3 will share mac, and return index as 3023 * per it. 3024 */ 3025 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq3)) 3026 *index = PM_24_SCC_MCC_PLUS_5_DBS; 3027 else 3028 *index = PM_5_SCC_MCC_PLUS_24_DBS; 3029 } 3030 3031 /** 3032 * policy_mgr_get_index_for_3_given_freq_sbs() - Find the index for next 3033 * connection for 3 given freq, in case current HW mode is SBS 3034 * @pm_ctx: policy manager context 3035 * @index: Index to return for next connection 3036 * @freq1: freq of interface 1 3037 * @freq2: freq of interface 2 3038 * @freq3: freq of interface 3 3039 * 3040 * This function finds the index for next 3041 * connection for 3 given freq, in case current HW mode is SBS 3042 * 3043 * Return: none 3044 */ 3045 static void policy_mgr_get_index_for_3_given_freq_sbs( 3046 struct policy_mgr_psoc_priv_obj *pm_ctx, 3047 enum policy_mgr_three_connection_mode *index, 3048 qdf_freq_t freq1, qdf_freq_t freq2, qdf_freq_t freq3) 3049 { 3050 qdf_freq_t sbs_cut_off_freq; 3051 qdf_freq_t shared_5_ghz_freq = 0; 3052 3053 /* 3054 * Sanity check: At least 2 of the given freq needs to be creating SBS 3055 * separation for HW mode to be in SBS, if not it shouldn't have 3056 * entered this API. 3057 */ 3058 if (!policy_mgr_are_sbs_chan(pm_ctx->psoc, freq1, freq2) && 3059 !policy_mgr_are_sbs_chan(pm_ctx->psoc, freq2, freq3) && 3060 !policy_mgr_are_sbs_chan(pm_ctx->psoc, freq3, freq1)) { 3061 policy_mgr_err("freq1 %d, freq2 %d and freq3 %d, none of the 2 connections/3 vdevs are leading to SBS", 3062 freq1, freq2, freq3); 3063 return; 3064 } 3065 3066 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc); 3067 if (!sbs_cut_off_freq) { 3068 policy_mgr_err("Invalid cutoff freq"); 3069 return; 3070 } 3071 3072 /* 3073 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH 3074 * 5GHZ as well as LOW 5 GHZ, but one at a time) and one of the 3075 * freq is 2.4 GHZ, this mean that the new interface can come up on 3076 * 5 GHZ LOW or HIGH and HW mode will move the 2.4 GHZ link to 3077 * the other mac dynamically. 3078 */ 3079 if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx) && 3080 (WLAN_REG_IS_24GHZ_CH_FREQ(freq1) || 3081 WLAN_REG_IS_24GHZ_CH_FREQ(freq2) || 3082 WLAN_REG_IS_24GHZ_CH_FREQ(freq3))) { 3083 *index = PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS; 3084 return; 3085 } 3086 /* 3087 * if freq1 on freq2 same mac, get the 5 / 6 GHZ freq from it check 3088 * and determine shared mac. 3089 */ 3090 if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq1, freq2)) { 3091 /* 3092 * If freq1 is 2.4 GHZ that mean freq2 is 5 / 6 GHZ. 3093 * so take decision using freq2. 3094 */ 3095 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1)) 3096 shared_5_ghz_freq = freq2; 3097 else 3098 /* freq1 5 / 6 GHZ, use freq1 */ 3099 shared_5_ghz_freq = freq1; 3100 } else if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq2, freq3)) { 3101 /* 3102 * If freq2 is 2.4 GHZ that mean freq3 is 5 / 6 GHZ. 3103 * so take decision using freq3. 3104 */ 3105 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq2)) 3106 shared_5_ghz_freq = freq3; 3107 else 3108 /* freq2 5 / 6 GHZ, use freq1 */ 3109 shared_5_ghz_freq = freq2; 3110 } else if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq3, freq1)) { 3111 /* 3112 * If freq1 is 2.4 GHZ that mean freq3 is 5 / 6 GHZ. 3113 * so take decision using freq3. 3114 */ 3115 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1)) 3116 shared_5_ghz_freq = freq3; 3117 else 3118 /* freq1 5 / 6 GHZ, use freq1 */ 3119 shared_5_ghz_freq = freq1; 3120 } 3121 3122 if (!shared_5_ghz_freq || 3123 WLAN_REG_IS_24GHZ_CH_FREQ(shared_5_ghz_freq)) { 3124 policy_mgr_err("shared_5_ghz_freq %d is not 5 / 6 GHZ", 3125 shared_5_ghz_freq); 3126 return; 3127 } 3128 3129 /* If shared 5 / 6 GHZ freq is low 5 GHZ, then return high 5 GHZ freq */ 3130 if (shared_5_ghz_freq < sbs_cut_off_freq) 3131 *index = PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS; 3132 else 3133 *index = PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS; 3134 } 3135 3136 #ifdef WLAN_FEATURE_11BE_MLO 3137 /** 3138 * policy_mgr_get_index_for_ml_sta_sap_dbs() - Find the index for next 3139 * connection for ML STA + SAP, in case current HW mode is DBS and ML STA is 3140 * 2.4 GHZ + 5 GHZ/6 GHZ OR if SBS is not supported. 3141 * @pm_ctx: policy manager context 3142 * @index: Index to return for next connection 3143 * @sap_freq: SAP freq 3144 * @sta_freq_list: STA freq list 3145 * @ml_sta_idx: ML STA index in freq_list 3146 * 3147 * This function finds the index for next 3148 * connection for ML STA + SAP, in case current HW mode is DBS and ML STA is 3149 * 2.4 GHZ + 5 GHZ/6 GHZ OR if SBS is not supported. 3150 * 3151 * Return: none 3152 */ 3153 static void 3154 policy_mgr_get_index_for_ml_sta_sap_dbs( 3155 struct policy_mgr_psoc_priv_obj *pm_ctx, 3156 enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq, 3157 qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx) 3158 { 3159 /* If ML STA and SAP all are on same band */ 3160 if ((WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) == 3161 WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) && 3162 (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) == 3163 WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))) { 3164 policy_mgr_err("Invalid mode for ML STA %d and %d are on same band as SAP %d", 3165 sta_freq_list[ml_sta_idx[0]], 3166 sta_freq_list[ml_sta_idx[1]], sap_freq); 3167 return; 3168 } 3169 3170 /* 3171 * If ML STA is MCC and SAP is on differet band and is not sharing mac 3172 * with any link. SAP on same band is handled above, so ML STA on same 3173 * band mean SAP cannot be on same band. This can happen if SBS is not 3174 * enabled. 3175 */ 3176 if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) == 3177 WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) { 3178 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) 3179 /* 3180 * As all 3 cannot be on same band, so if SAP is 2.4 GHZ 3181 * mean both ML STA are on 5 / 6 GHZ 3182 */ 3183 *index = PM_STA_STA_5_SAP_24_DBS; 3184 else 3185 /* 3186 * As all 3 cannot be on same band, so if SAP is 3187 * 5 / 6 GHZ, mean both ML STA are on 2.4 GHZ. 3188 */ 3189 policy_mgr_err("Invalid mode for ML STA %d and %d are on 2.4 GHZ, sap freq %d", 3190 sta_freq_list[ml_sta_idx[0]], 3191 sta_freq_list[ml_sta_idx[1]], sap_freq); 3192 3193 return; 3194 } 3195 3196 /* 3197 * if ML STA is 2 GHZ + 5 GHZ/6 GHZ DBS, check with which freq the SAP 3198 * will share mac, and return index as per it. 3199 */ 3200 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) 3201 *index = PM_STA_SAP_24_STA_5_DBS; 3202 else 3203 *index = PM_STA_SAP_5_STA_24_DBS; 3204 } 3205 3206 /** 3207 * policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs() - Find the index for next 3208 * connection for ML STA + SAP, in case current HW mode is SBS but ML STA is 3209 * with 2 GHz + 5/6 GHz. 3210 * @pm_ctx: policy manager context 3211 * @index: Index to return for next connection 3212 * @sap_freq: SAP freq 3213 * @sta_freq_list: STA freq list 3214 * @ml_sta_idx: ML STA index in freq_list 3215 * 3216 * This function finds the index for next connection for ML STA + SAP, 3217 * in case current HW mode is SBS but ML STA is with 2 GHz + 5/6 GHz. 3218 * 3219 * Return: none 3220 */ 3221 static void policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs( 3222 struct policy_mgr_psoc_priv_obj *pm_ctx, 3223 enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq, 3224 qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx) 3225 { 3226 bool sbs_24_shared_high_support = 3227 policy_mgr_sbs_24_shared_with_high_5(pm_ctx); 3228 bool sbs_24_shared_low_support = 3229 policy_mgr_sbs_24_shared_with_low_5(pm_ctx); 3230 qdf_freq_t sbs_cut_off_freq, ml_sta_5g_freq; 3231 bool ml_sta_5g_low; 3232 3233 /* HW supports sbs but ml sta 2 home channels are not in sbs frequency 3234 * separation by check policy_mgr_are_sbs_chan. 3235 * It means one ml sta is 2.4 GHz, the other is 5/6 GHz. 3236 * The combinations handled by this API: 3237 * 2.4 GHz band | 5 GHz low band | 5/6 GHz high band | PCL list 3238 * ---------------------------------------------------------------------- 3239 * ML STA | ML STA+SAP | | 5 GHz High + 2.4 GHz 3240 * ML STA | ML STA+SAP | | 2.4 GHz(nhss) 3241 * ML STA | ML STA | SAP | 5 GHz Low + 2.4 GHz 3242 * ML STA | ML STA | SAP | 2.4 GHz (nhss) 3243 * ML STA | SAP | ML STA | 5 GHz High+ 2.4 GHz 3244 * ML STA | SAP | ML STA | 2.4 GHz (nlss) 3245 * ML STA | | ML STA+SAP | 5 GHz Low + 2.4 GHz 3246 * ML STA | | ML STA+SAP | 2.4 GHz (nlss) 3247 * ML STA+SAP | ML STA | | 5 GHz Low+5 GHz High 3248 * ML STA+SAP | | ML STA | 5 GHz Low+5 GHz High 3249 * 3250 * nhss: no high share supported 3251 * nlss: no low share supported 3252 */ 3253 3254 if (!WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) && 3255 !WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) { 3256 policy_mgr_err("unexpected ml sta home freq to handle (%d %d)", 3257 sta_freq_list[ml_sta_idx[0]], 3258 sta_freq_list[ml_sta_idx[1]]); 3259 return; 3260 } 3261 if (!sbs_24_shared_low_support && !sbs_24_shared_high_support) { 3262 policy_mgr_err("unexpected sbs mode: low share %d high share %d", 3263 sbs_24_shared_low_support, 3264 sbs_24_shared_high_support); 3265 return; 3266 } 3267 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc); 3268 if (!sbs_cut_off_freq) { 3269 policy_mgr_err("Invalid cutoff freq"); 3270 return; 3271 } 3272 3273 if (!WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]])) 3274 ml_sta_5g_freq = sta_freq_list[ml_sta_idx[0]]; 3275 else 3276 ml_sta_5g_freq = sta_freq_list[ml_sta_idx[1]]; 3277 if (ml_sta_5g_freq < sbs_cut_off_freq) 3278 ml_sta_5g_low = true; 3279 else 3280 ml_sta_5g_low = false; 3281 3282 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) { 3283 /* pcl 5 GHz Low+5 GHz High - PM_SCC_ON_5_CH_5G */ 3284 *index = PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS; 3285 } else if (sap_freq < sbs_cut_off_freq) { 3286 if ((ml_sta_5g_low && sbs_24_shared_high_support) || 3287 (!ml_sta_5g_low && sbs_24_shared_low_support)) 3288 /* pcl 5 GHz High + 2.4 GHz - 3289 * PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G 3290 */ 3291 *index = PM_STA_24_STA_5_MCC_SAP_5_LOW_SBS; 3292 else 3293 *index = PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS; 3294 } else { 3295 if ((ml_sta_5g_low && sbs_24_shared_high_support) || 3296 (!ml_sta_5g_low && sbs_24_shared_low_support)) 3297 /* pcl 5 GHz Low + 2.4 GHz - 3298 * PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G 3299 */ 3300 *index = PM_STA_24_STA_5_MCC_SAP_5_HIGH_SBS; 3301 else 3302 *index = PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS; 3303 } 3304 policy_mgr_debug("4th index %d sap freq %d ml sta 5g %d sbs_cut_off_freq %d support high share %d low share %d", 3305 *index, sap_freq, ml_sta_5g_freq, sbs_cut_off_freq, 3306 sbs_24_shared_high_support, 3307 sbs_24_shared_low_support); 3308 } 3309 3310 /** 3311 * policy_mgr_get_index_for_ml_sta_sap_sbs() - Find the index for next 3312 * connection for ML STA + SAP, in case current HW mode is SBS or ML STA is 3313 * with 5 GHZ + 5 GHZ/6 GHZ SBS separation. 3314 * @pm_ctx: policy manager context 3315 * @index: Index to return for next connection 3316 * @sap_freq: SAP freq 3317 * @sta_freq_list: STA freq list 3318 * @ml_sta_idx: ML STA index in freq_list 3319 * 3320 * This function finds the index for next 3321 * connection for ML STA + SAP, in case current HW mode is SBS or ML STA is 3322 * with 5 GHZ + 5 GHZ/6 GHZ SBS separation. 3323 * 3324 * Return: none 3325 */ 3326 static void policy_mgr_get_index_for_ml_sta_sap_sbs( 3327 struct policy_mgr_psoc_priv_obj *pm_ctx, 3328 enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq, 3329 qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx) 3330 { 3331 qdf_freq_t sbs_cut_off_freq; 3332 bool can_2ghz_share_low_high_5ghz = 3333 policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx); 3334 3335 /* 3336 * Sanity check: At least one of the 3 combo (ML STA OR SAP + one of 3337 * ML STA link) needs to be creating SBS separation for 3338 * HW mode to be in SBS, if not it shouldn't have entered this API. 3339 */ 3340 if (!policy_mgr_are_sbs_chan(pm_ctx->psoc, sta_freq_list[ml_sta_idx[0]], 3341 sta_freq_list[ml_sta_idx[1]]) && 3342 !policy_mgr_are_sbs_chan(pm_ctx->psoc, sap_freq, 3343 sta_freq_list[ml_sta_idx[0]]) && 3344 !policy_mgr_are_sbs_chan(pm_ctx->psoc, sap_freq, 3345 sta_freq_list[ml_sta_idx[1]])) { 3346 if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc)) { 3347 policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs( 3348 pm_ctx, index, sap_freq, sta_freq_list, 3349 ml_sta_idx); 3350 return; 3351 } 3352 policy_mgr_err("SAP freq (%d) and ML STA freq %d and %d, none of the 2 connections/3 vdevs are leading to SBS", 3353 sap_freq, 3354 sta_freq_list[ml_sta_idx[0]], 3355 sta_freq_list[ml_sta_idx[1]]); 3356 return; 3357 } 3358 3359 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc); 3360 if (!sbs_cut_off_freq) { 3361 policy_mgr_err("Invalid cutoff freq"); 3362 return; 3363 } 3364 3365 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) { 3366 /* 3367 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH 3368 * 5GHZ as well as LOW 5 GHZ, but one at a time) and SAP is 3369 * 2.4 GHZ, this mean that the new SAP can come up on 5 GHZ LOW 3370 * or HIGH and HW mode will move the 2.4 GHZ SAP to the other 3371 * mac dynamically. 3372 */ 3373 if (can_2ghz_share_low_high_5ghz) { 3374 *index = PM_SAP_24_STA_5_STA_5_LOW_N_HIGH_SHARE_SBS; 3375 return; 3376 } 3377 /* 3378 * if SAP is 2.4 GHZ that means both ML STA needs to 3379 * be with 5 GHZ + 5 GHZ/6 GHZ SBS separation. If not, it would 3380 * have failed the sanity check. So Get STA link with 3381 * which SAP freq is sharing mac and select index accordingly 3382 */ 3383 if (policy_mgr_2_freq_same_mac_in_sbs( 3384 pm_ctx, sap_freq, 3385 sta_freq_list[ml_sta_idx[0]])) { 3386 /* 3387 * SAP is sharig mac with link ml_sta_idx[0], so check 3388 * if ml_sta_idx[0] is lower 5 GHZ or high 5 GHZ and 3389 * select index 3390 */ 3391 if (sta_freq_list[ml_sta_idx[0]] < sbs_cut_off_freq) 3392 *index = PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS; 3393 else 3394 *index = PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS; 3395 } else { 3396 /* 3397 * SAP is sharig mac with link ml_sta_idx[1], so check 3398 * if ml_sta_idx[1] is lower 5 GHZ or high 5 GHZ and 3399 * select index 3400 */ 3401 if (sta_freq_list[ml_sta_idx[1]] < sbs_cut_off_freq) 3402 *index = PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS; 3403 else 3404 *index = PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS; 3405 } 3406 3407 return; 3408 } 3409 3410 /* SAP freq is 5 GHZ or 6 GHZ and one ML sta is on 2.4 GHZ */ 3411 if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) || 3412 WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) { 3413 /* 3414 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH 3415 * 5GHZ as well as LOW 5 GHZ, but one at a time) and one STA 3416 * link is 2.4 GHZ, this mean that the new SAP can come up on 3417 * 5 GHZ LOW or HIGH and HW mode will move the 2.4 GHZ link to 3418 * the other mac dynamically. 3419 */ 3420 if (can_2ghz_share_low_high_5ghz) { 3421 *index = PM_STA_24_SAP_5_STA_5_LOW_N_HIGH_SHARE_SBS; 3422 return; 3423 } 3424 /* 3425 * If (2 GHZ + 5 GHZ/6 GHZ) ML is MCC i.e Both sta links are on 3426 * same mac and SAP is on separate mac. This can happen if SBS 3427 * is not dynamic and is low 5 GHZ shared, with ML STA on 5 GHZ 3428 * low along with SAP 5Ghz high and vice versa. As both links 3429 * of ML STA and sap are on different mac, so set index based 3430 * on sap frequency whether it is in 5 GHZ low band or 5 GHZ 3431 * high Band. 3432 */ 3433 if (policy_mgr_2_freq_same_mac_in_sbs( 3434 pm_ctx, sta_freq_list[ml_sta_idx[0]], 3435 sta_freq_list[ml_sta_idx[1]])) { 3436 if (sap_freq < sbs_cut_off_freq) 3437 *index = PM_STA_24_STA_5_HIGH_MCC_SAP_5_LOW_SBS; 3438 else 3439 *index = PM_STA_24_STA_5_LOW_MCC_SAP_5_HIGH_SBS; 3440 } else { 3441 /* 3442 * STA ML is (2 GHZ + 5 GHZ/6 GHZ) select as per the SAP 3443 * freq, as for current mode to be in SBS, SAP will 3444 * share mac with STA 2.4 GHZ Link or will not share 3445 * mac at all (2 GHZ + 5 GHZ/6 GHZ MCC). Other case i.e 3446 * 2 links on 5 GHZ and one STA link on 2 GHZ is DBS and 3447 * sanity check already taken care this at start of the 3448 * func. 3449 */ 3450 if (sap_freq < sbs_cut_off_freq) 3451 *index = PM_STA_24_SAP_5_LOW_MCC_STA_5_HIGH_SBS; 3452 else 3453 *index = PM_STA_24_SAP_5_HIGH_MCC_STA_5_LOW_SBS; 3454 } 3455 return; 3456 } 3457 /* 3458 * If (5 GHZ + 5 GHZ/6 GHZ) ML is MCC i.e SAP is not sharing mac 3459 * with any link. This can happen if SBS is not dynamic and is 3460 * low 5 GHZ shared, with ML STA on 5 GHZ low along with SAP 5 GHZ 3461 * high and vice versa. As both ML sta link are on same mac and 3462 * sap is on different mac, so decide whether ML links are sharing 3463 * low 5 GHZ frequency or high 5 GHZ frequency based on sap frequency 3464 */ 3465 if (policy_mgr_2_freq_same_mac_in_sbs( 3466 pm_ctx, sta_freq_list[ml_sta_idx[0]], 3467 sta_freq_list[ml_sta_idx[1]])) { 3468 if (sap_freq < sbs_cut_off_freq) 3469 *index = PM_STA_STA_5_HIGH_MCC_SAP_5_LOW_SBS; 3470 else 3471 *index = PM_STA_STA_5_LOW_MCC_SAP_5_HIGH_SBS; 3472 } else { 3473 /* 3474 * STA ML is (5 GHZ + 5 GHZ/6 GHZ SBS/MCC), select as per the 3475 * SAP freq, as for current mode to be in SBS, SAP will share 3476 * mac with the corresponding low/high 5 GHZ 3477 * (5 GHZ + 5 GHZ/6 GHZ SBS) or will not share mac at all 3478 * (5 GHZ +5 GHZ/6 GHZ MCC). Other case sanity already 3479 * taken care at start of the func. 3480 */ 3481 if (sap_freq < sbs_cut_off_freq) 3482 *index = PM_STA_SAP_5_LOW_STA_5_HIGH_SBS; 3483 else 3484 *index = PM_STA_SAP_5_HIGH_STA_5_LOW_SBS; 3485 } 3486 } 3487 3488 static void 3489 policy_mgr_get_index_for_ml_sta_sap( 3490 struct policy_mgr_psoc_priv_obj *pm_ctx, 3491 enum policy_mgr_three_connection_mode *index, 3492 qdf_freq_t sap_freq, qdf_freq_t *sta_freq_list, 3493 uint8_t *ml_sta_idx) 3494 { 3495 /* 3496 * P2P GO/P2P CLI are treated as SAP to optimize as pcl 3497 * table is same for all three. 3498 */ 3499 policy_mgr_debug("channel: sap0: %d, ML STA link0: %d, ML STA link1: %d", 3500 sap_freq, sta_freq_list[ml_sta_idx[0]], 3501 sta_freq_list[ml_sta_idx[1]]); 3502 if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc) || 3503 policy_mgr_are_sbs_chan(pm_ctx->psoc, sta_freq_list[ml_sta_idx[0]], 3504 sta_freq_list[ml_sta_idx[1]])) { 3505 /* if current mode is SBS or the ML STA is 5+5/6Ghz SBS */ 3506 policy_mgr_get_index_for_ml_sta_sap_sbs(pm_ctx, index, 3507 sap_freq, 3508 sta_freq_list, 3509 ml_sta_idx); 3510 return; 3511 } 3512 /* 3513 * current HW mode is DBS and ML STA is 2.4 GHZ + 5 GHZ or SBS 3514 * is not enabled 3515 */ 3516 policy_mgr_get_index_for_ml_sta_sap_dbs(pm_ctx, index, sap_freq, 3517 sta_freq_list, ml_sta_idx); 3518 } 3519 3520 static void 3521 policy_mgr_get_index_for_ml_sta_sap_sap( 3522 struct policy_mgr_psoc_priv_obj *pm_ctx, 3523 enum policy_mgr_three_connection_mode *index, 3524 qdf_freq_t ml_sta_freq, qdf_freq_t sap_freq_1, 3525 qdf_freq_t sap_freq_2) 3526 { 3527 /* 3528 * P2P GO/P2P CLI are treated as SAP to optimize as pcl 3529 * table is same for all three. 3530 */ 3531 policy_mgr_debug("channel: ML sta0: %d, SAP0: %d, SAP1: %d", 3532 ml_sta_freq, sap_freq_1, sap_freq_2); 3533 if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc)) 3534 /* if current mode is SBS */ 3535 return policy_mgr_get_index_for_3_given_freq_sbs(pm_ctx, index, 3536 ml_sta_freq, sap_freq_1, 3537 sap_freq_2); 3538 3539 /* current HW mode is DBS */ 3540 policy_mgr_get_index_for_3_given_freq_dbs(pm_ctx, index, ml_sta_freq, 3541 sap_freq_1, sap_freq_2); 3542 } 3543 3544 #else /* WLAN_FEATURE_11BE_MLO */ 3545 3546 static inline void 3547 policy_mgr_get_index_for_ml_sta_sap( 3548 struct policy_mgr_psoc_priv_obj *pm_ctx, 3549 enum policy_mgr_three_connection_mode *index, 3550 qdf_freq_t sap_freq, qdf_freq_t *sta_freq_list, 3551 uint8_t *ml_sta_idx) {} 3552 3553 static inline void 3554 policy_mgr_get_index_for_ml_sta_sap_sap( 3555 struct policy_mgr_psoc_priv_obj *pm_ctx, 3556 enum policy_mgr_three_connection_mode *index, 3557 qdf_freq_t ml_sta_freq, qdf_freq_t sap_freq_1, 3558 qdf_freq_t sap_freq_2) {} 3559 #endif /* WLAN_FEATURE_11BE_MLO */ 3560 3561 enum policy_mgr_three_connection_mode 3562 policy_mgr_get_fourth_connection_pcl_table_index( 3563 struct wlan_objmgr_psoc *psoc) 3564 { 3565 enum policy_mgr_three_connection_mode index = 3566 PM_MAX_THREE_CONNECTION_MODE; 3567 struct policy_mgr_psoc_priv_obj *pm_ctx; 3568 uint32_t count_sap = 0; 3569 uint32_t count_sta = 0; 3570 uint32_t count_ndi = 0; 3571 uint32_t count_nan_disc = 0; 3572 uint8_t num_ml_sta = 0, num_non_ml_sta = 0; 3573 uint32_t list_sap[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3574 uint32_t list_sta[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3575 uint32_t list_ndi[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3576 uint32_t list_nan_disc[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3577 uint8_t ml_sta_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3578 uint8_t non_ml_sta_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3579 qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3580 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3581 qdf_freq_t sap_freq = 0; 3582 3583 pm_ctx = policy_mgr_get_context(psoc); 3584 if (!pm_ctx) { 3585 policy_mgr_err("Invalid Context"); 3586 return index; 3587 } 3588 3589 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3590 3591 /* For 4 port concurrency case, 3592 * 1st step: (SAP+STA)(2.4G MAC SCC) + (SAP+STA)(5G MAC SCC) 3593 * 2nd step: (AGO+STA)(2.4G MAC SCC) + (AGO+STA)(5G MAC SCC) 3594 */ 3595 count_sap += policy_mgr_mode_specific_connection_count( 3596 psoc, PM_SAP_MODE, &list_sap[count_sap]); 3597 count_sap += policy_mgr_mode_specific_connection_count( 3598 psoc, PM_P2P_GO_MODE, &list_sap[count_sap]); 3599 count_sap += policy_mgr_mode_specific_connection_count( 3600 psoc, PM_P2P_CLIENT_MODE, &list_sap[count_sap]); 3601 count_sta = policy_mgr_mode_specific_connection_count( 3602 psoc, PM_STA_MODE, list_sta); 3603 policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml_sta, ml_sta_idx, 3604 &num_non_ml_sta, non_ml_sta_idx, 3605 freq_list, vdev_id_list); 3606 3607 count_ndi = policy_mgr_mode_specific_connection_count( 3608 psoc, PM_NDI_MODE, list_ndi); 3609 count_nan_disc = policy_mgr_mode_specific_connection_count( 3610 psoc, PM_NAN_DISC_MODE, list_nan_disc); 3611 policy_mgr_debug("sap/go/cli:%d sta:%d ndi:%d nan disc:%d ml_sta:%d", 3612 count_sap, count_sta, count_ndi, count_nan_disc, 3613 num_ml_sta); 3614 3615 if (count_sap == 2 && num_ml_sta == 1) { 3616 policy_mgr_get_index_for_ml_sta_sap_sap( 3617 pm_ctx, &index, 3618 freq_list[ml_sta_idx[0]], 3619 pm_conc_connection_list[list_sap[0]].freq, 3620 pm_conc_connection_list[list_sap[1]].freq); 3621 } else if (count_sap == 2 && count_sta == 1 && !num_ml_sta) { 3622 policy_mgr_debug( 3623 "channel: sap0: %d, sap1: %d, sta0: %d", 3624 pm_conc_connection_list[list_sap[0]].freq, 3625 pm_conc_connection_list[list_sap[1]].freq, 3626 pm_conc_connection_list[list_sta[0]].freq); 3627 if (WLAN_REG_IS_24GHZ_CH_FREQ( 3628 pm_conc_connection_list[list_sap[0]].freq) && 3629 WLAN_REG_IS_24GHZ_CH_FREQ( 3630 pm_conc_connection_list[list_sta[0]].freq) && 3631 WLAN_REG_IS_5GHZ_CH_FREQ( 3632 pm_conc_connection_list[list_sap[1]].freq)) { 3633 index = PM_STA_SAP_SCC_24_SAP_5_DBS; 3634 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3635 pm_conc_connection_list[list_sap[1]].freq) && 3636 WLAN_REG_IS_24GHZ_CH_FREQ( 3637 pm_conc_connection_list[list_sta[0]].freq) && 3638 WLAN_REG_IS_5GHZ_CH_FREQ( 3639 pm_conc_connection_list[list_sap[0]].freq)) { 3640 index = PM_STA_SAP_SCC_24_SAP_5_DBS; 3641 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3642 pm_conc_connection_list[list_sap[0]].freq) && 3643 WLAN_REG_IS_5GHZ_CH_FREQ( 3644 pm_conc_connection_list[list_sta[0]].freq) && 3645 WLAN_REG_IS_5GHZ_CH_FREQ( 3646 pm_conc_connection_list[list_sap[1]].freq)) { 3647 index = PM_STA_SAP_SCC_5_SAP_24_DBS; 3648 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3649 pm_conc_connection_list[list_sap[1]].freq) && 3650 WLAN_REG_IS_5GHZ_CH_FREQ( 3651 pm_conc_connection_list[list_sta[0]].freq) && 3652 WLAN_REG_IS_5GHZ_CH_FREQ( 3653 pm_conc_connection_list[list_sap[0]].freq)) { 3654 index = PM_STA_SAP_SCC_5_SAP_24_DBS; 3655 } else { 3656 index = PM_MAX_THREE_CONNECTION_MODE; 3657 } 3658 } else if (num_ml_sta == 2 && count_sap == 1) { 3659 sap_freq = pm_conc_connection_list[list_sap[0]].freq; 3660 policy_mgr_get_index_for_ml_sta_sap(pm_ctx, &index, sap_freq, 3661 freq_list, ml_sta_idx); 3662 } else if (count_sap == 1 && count_sta == 2 && !num_ml_sta) { 3663 policy_mgr_debug( 3664 "channel: sap0: %d, sta0: %d, sta1: %d", 3665 pm_conc_connection_list[list_sap[0]].freq, 3666 pm_conc_connection_list[list_sta[0]].freq, 3667 pm_conc_connection_list[list_sta[1]].freq); 3668 if (WLAN_REG_IS_24GHZ_CH_FREQ( 3669 pm_conc_connection_list[list_sta[0]].freq) && 3670 WLAN_REG_IS_24GHZ_CH_FREQ( 3671 pm_conc_connection_list[list_sap[0]].freq) && 3672 WLAN_REG_IS_5GHZ_CH_FREQ( 3673 pm_conc_connection_list[list_sta[1]].freq)) { 3674 index = PM_STA_SAP_24_STA_5_DBS; 3675 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3676 pm_conc_connection_list[list_sta[1]].freq) && 3677 WLAN_REG_IS_24GHZ_CH_FREQ( 3678 pm_conc_connection_list[list_sap[0]].freq) && 3679 WLAN_REG_IS_5GHZ_CH_FREQ( 3680 pm_conc_connection_list[list_sta[0]].freq)) { 3681 index = PM_STA_SAP_24_STA_5_DBS; 3682 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3683 pm_conc_connection_list[list_sta[0]].freq) && 3684 WLAN_REG_IS_5GHZ_CH_FREQ( 3685 pm_conc_connection_list[list_sap[0]].freq) && 3686 WLAN_REG_IS_5GHZ_CH_FREQ( 3687 pm_conc_connection_list[list_sta[1]].freq)) { 3688 index = PM_STA_SAP_5_STA_24_DBS; 3689 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3690 pm_conc_connection_list[list_sta[1]].freq) && 3691 WLAN_REG_IS_5GHZ_CH_FREQ( 3692 pm_conc_connection_list[list_sap[0]].freq) && 3693 WLAN_REG_IS_5GHZ_CH_FREQ( 3694 pm_conc_connection_list[list_sta[0]].freq)) { 3695 index = PM_STA_SAP_5_STA_24_DBS; 3696 } else { 3697 index = PM_MAX_THREE_CONNECTION_MODE; 3698 } 3699 } else if (count_nan_disc == 1 && count_ndi == 1 && count_sap == 1) { 3700 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 3701 if (WLAN_REG_IS_24GHZ_CH_FREQ( 3702 pm_conc_connection_list[list_sap[0]].freq) && 3703 WLAN_REG_IS_5GHZ_CH_FREQ( 3704 pm_conc_connection_list[list_ndi[0]].freq)) { 3705 index = PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS; 3706 } else if (WLAN_REG_IS_5GHZ_CH_FREQ( 3707 pm_conc_connection_list[list_sap[0]].freq) && 3708 WLAN_REG_IS_24GHZ_CH_FREQ( 3709 pm_conc_connection_list[list_ndi[0]].freq)) { 3710 index = PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS; 3711 } else if (WLAN_REG_IS_5GHZ_CH_FREQ( 3712 pm_conc_connection_list[list_sap[0]].freq) && 3713 WLAN_REG_IS_5GHZ_CH_FREQ( 3714 pm_conc_connection_list[list_ndi[0]].freq)) { 3715 index = PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS; 3716 } else { 3717 index = PM_MAX_THREE_CONNECTION_MODE; 3718 } 3719 } else if (count_nan_disc == 1 && count_ndi == 1 && count_sta == 1) { 3720 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 3721 if (WLAN_REG_IS_24GHZ_CH_FREQ( 3722 pm_conc_connection_list[list_sta[0]].freq) && 3723 WLAN_REG_IS_5GHZ_CH_FREQ( 3724 pm_conc_connection_list[list_ndi[0]].freq)) { 3725 index = PM_NAN_DISC_STA_24_NDI_5_DBS; 3726 } else if (WLAN_REG_IS_5GHZ_CH_FREQ( 3727 pm_conc_connection_list[list_sta[0]].freq) && 3728 WLAN_REG_IS_24GHZ_CH_FREQ( 3729 pm_conc_connection_list[list_ndi[0]].freq)) { 3730 index = PM_NAN_DISC_NDI_24_STA_5_DBS; 3731 } else if (WLAN_REG_IS_5GHZ_CH_FREQ( 3732 pm_conc_connection_list[list_sta[0]].freq) && 3733 WLAN_REG_IS_5GHZ_CH_FREQ( 3734 pm_conc_connection_list[list_ndi[0]].freq)) { 3735 index = PM_STA_NDI_5_NAN_DISC_24_DBS; 3736 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3737 pm_conc_connection_list[list_sta[0]].freq) && 3738 WLAN_REG_IS_24GHZ_CH_FREQ( 3739 pm_conc_connection_list[list_ndi[0]].freq)) { 3740 index = PM_STA_NDI_NAN_DISC_24_SMM; 3741 } 3742 } else if (count_nan_disc == 1 && count_ndi == 2) { 3743 /* Policy mgr only considers NAN Disc ch in 2.4GHz */ 3744 if (WLAN_REG_IS_24GHZ_CH_FREQ( 3745 pm_conc_connection_list[list_ndi[0]].freq) && 3746 WLAN_REG_IS_5GHZ_CH_FREQ( 3747 pm_conc_connection_list[list_ndi[1]].freq)) { 3748 index = PM_NAN_DISC_NDI_24_NDI_5_DBS; 3749 } else if (WLAN_REG_IS_5GHZ_CH_FREQ( 3750 pm_conc_connection_list[list_ndi[0]].freq) && 3751 WLAN_REG_IS_24GHZ_CH_FREQ( 3752 pm_conc_connection_list[list_ndi[0]].freq)) { 3753 index = PM_NAN_DISC_NDI_24_NDI_5_DBS; 3754 } else if (WLAN_REG_IS_5GHZ_CH_FREQ( 3755 pm_conc_connection_list[list_ndi[0]].freq) && 3756 WLAN_REG_IS_5GHZ_CH_FREQ( 3757 pm_conc_connection_list[list_ndi[0]].freq)) { 3758 index = PM_NDI_NDI_5_NAN_DISC_24_DBS; 3759 } else if (WLAN_REG_IS_24GHZ_CH_FREQ( 3760 pm_conc_connection_list[list_ndi[0]].freq) && 3761 WLAN_REG_IS_24GHZ_CH_FREQ( 3762 pm_conc_connection_list[list_ndi[0]].freq)) { 3763 index = PM_NDI_NDI_NAN_DISC_24_SMM; 3764 } 3765 } else if (count_sap == 3) { 3766 if (policy_mgr_is_current_hwmode_sbs(psoc)) 3767 policy_mgr_get_index_for_3_given_freq_sbs(pm_ctx, 3768 &index, 3769 pm_conc_connection_list[list_sap[0]].freq, 3770 pm_conc_connection_list[list_sap[1]].freq, 3771 pm_conc_connection_list[list_sap[2]].freq); 3772 else if (policy_mgr_is_current_hwmode_dbs(psoc)) 3773 policy_mgr_get_index_for_3_given_freq_dbs(pm_ctx, 3774 &index, 3775 pm_conc_connection_list[list_sap[0]].freq, 3776 pm_conc_connection_list[list_sap[1]].freq, 3777 pm_conc_connection_list[list_sap[2]].freq); 3778 } 3779 3780 policy_mgr_debug( 3781 "mode0:%d mode1:%d mode2:%d chan0:%d chan1:%d chan2:%d chain:%d index:%d", 3782 pm_conc_connection_list[0].mode, 3783 pm_conc_connection_list[1].mode, 3784 pm_conc_connection_list[2].mode, 3785 pm_conc_connection_list[0].freq, 3786 pm_conc_connection_list[1].freq, 3787 pm_conc_connection_list[2].freq, 3788 pm_conc_connection_list[0].chain_mask, index); 3789 3790 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3791 3792 return index; 3793 } 3794 #endif 3795 3796 uint32_t 3797 policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, 3798 enum policy_mgr_con_mode mode, 3799 bool for_existing_conn, 3800 uint8_t vdev_id) 3801 { 3802 uint32_t pcl_channels[NUM_CHANNELS]; 3803 uint8_t pcl_weight[NUM_CHANNELS]; 3804 struct policy_mgr_psoc_priv_obj *pm_ctx; 3805 3806 /* 3807 * in worst case if we can't find any channel at all 3808 * then return 2.4G channel, so atleast we won't fall 3809 * under 5G MCC scenario 3810 */ 3811 uint32_t i, pcl_len = 0, non_dfs_freq, freq; 3812 3813 pm_ctx = policy_mgr_get_context(psoc); 3814 if (!pm_ctx) { 3815 policy_mgr_err("Invalid Context"); 3816 return PM_24_GHZ_CH_FREQ_6; 3817 } 3818 3819 freq = PM_24_GHZ_CH_FREQ_6; 3820 if (true == for_existing_conn) { 3821 /* 3822 * First try to see if there is any non-dfs channel already 3823 * present in current connection table. If yes then return 3824 * that channel 3825 */ 3826 if (true == policy_mgr_is_any_nondfs_chnl_present( 3827 psoc, &non_dfs_freq)) 3828 return non_dfs_freq; 3829 3830 if (QDF_STATUS_SUCCESS != 3831 policy_mgr_get_pcl_for_existing_conn( 3832 psoc, mode, 3833 pcl_channels, &pcl_len, 3834 pcl_weight, QDF_ARRAY_SIZE(pcl_weight), 3835 false, vdev_id)) 3836 return freq; 3837 } else { 3838 if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl( 3839 psoc, mode, pcl_channels, &pcl_len, pcl_weight, 3840 QDF_ARRAY_SIZE(pcl_weight), vdev_id)) 3841 return freq; 3842 } 3843 3844 for (i = 0; i < pcl_len; i++) { 3845 if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]) || 3846 !policy_mgr_is_safe_channel(psoc, pcl_channels[i])) { 3847 continue; 3848 } else { 3849 freq = pcl_channels[i]; 3850 break; 3851 } 3852 } 3853 3854 return freq; 3855 } 3856 3857 static void policy_mgr_remove_dsrc_channels(uint32_t *ch_freq_list, 3858 uint32_t *num_channels, 3859 struct wlan_objmgr_pdev *pdev) 3860 { 3861 uint32_t num_chan_temp = 0; 3862 int i; 3863 3864 for (i = 0; i < *num_channels; i++) { 3865 if (!wlan_reg_is_dsrc_freq(ch_freq_list[i])) { 3866 ch_freq_list[num_chan_temp] = ch_freq_list[i]; 3867 num_chan_temp++; 3868 } 3869 } 3870 3871 *num_channels = num_chan_temp; 3872 } 3873 3874 QDF_STATUS policy_mgr_get_valid_chans_from_range( 3875 struct wlan_objmgr_psoc *psoc, uint32_t *ch_freq_list, 3876 uint32_t *ch_cnt, enum policy_mgr_con_mode mode) 3877 { 3878 uint8_t ch_weight_list[NUM_CHANNELS] = {0}; 3879 uint32_t ch_weight_len; 3880 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3881 size_t chan_index = 0; 3882 3883 if (!ch_freq_list || !ch_cnt) { 3884 policy_mgr_err("NULL parameters"); 3885 return QDF_STATUS_E_FAILURE; 3886 } 3887 3888 for (chan_index = 0; chan_index < *ch_cnt; chan_index++) 3889 ch_weight_list[chan_index] = WEIGHT_OF_GROUP1_PCL_CHANNELS; 3890 3891 ch_weight_len = *ch_cnt; 3892 3893 /* check the channel avoidance list for beaconing entities */ 3894 if (policy_mgr_is_beaconing_mode(mode)) 3895 policy_mgr_update_with_safe_channel_list( 3896 psoc, ch_freq_list, ch_cnt, ch_weight_list, 3897 ch_weight_len); 3898 3899 status = policy_mgr_mode_specific_modification_on_pcl( 3900 psoc, ch_freq_list, ch_weight_list, ch_cnt, 3901 ch_weight_len, mode); 3902 3903 if (QDF_IS_STATUS_ERROR(status)) { 3904 policy_mgr_err("failed to get modified pcl for mode %d", mode); 3905 return status; 3906 } 3907 3908 status = policy_mgr_modify_pcl_based_on_dnbs(psoc, ch_freq_list, 3909 ch_weight_list, ch_cnt); 3910 3911 if (QDF_IS_STATUS_ERROR(status)) { 3912 policy_mgr_err("failed to get modified pcl based on DNBS"); 3913 return status; 3914 } 3915 policy_mgr_dump_channel_list(*ch_cnt, ch_freq_list, ch_weight_list); 3916 3917 return status; 3918 } 3919 3920 QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, 3921 uint32_t *ch_freq_list, 3922 uint32_t *list_len) 3923 { 3924 struct policy_mgr_psoc_priv_obj *pm_ctx; 3925 3926 *list_len = 0; 3927 3928 pm_ctx = policy_mgr_get_context(psoc); 3929 if (!pm_ctx) { 3930 policy_mgr_err("Invalid Context"); 3931 return QDF_STATUS_E_FAILURE; 3932 } 3933 if (!pm_ctx->valid_ch_freq_list_count) { 3934 policy_mgr_err("Invalid PM valid channel list"); 3935 return QDF_STATUS_E_INVAL; 3936 } 3937 3938 *list_len = pm_ctx->valid_ch_freq_list_count; 3939 qdf_mem_copy(ch_freq_list, pm_ctx->valid_ch_freq_list, 3940 pm_ctx->valid_ch_freq_list_count * 3941 sizeof(pm_ctx->valid_ch_freq_list[0])); 3942 3943 policy_mgr_remove_dsrc_channels(ch_freq_list, list_len, pm_ctx->pdev); 3944 3945 return QDF_STATUS_SUCCESS; 3946 } 3947 3948 bool policy_mgr_list_has_24GHz_channel(uint32_t *ch_freq_list, 3949 uint32_t list_len) 3950 { 3951 uint32_t i; 3952 3953 for (i = 0; i < list_len; i++) { 3954 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i])) 3955 return true; 3956 } 3957 3958 return false; 3959 } 3960 3961 QDF_STATUS 3962 policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, 3963 uint32_t *ch_freq_list, uint32_t len) 3964 { 3965 uint32_t i; 3966 struct policy_mgr_psoc_priv_obj *pm_ctx; 3967 3968 pm_ctx = policy_mgr_get_context(psoc); 3969 if (!pm_ctx) { 3970 policy_mgr_err("Invalid Context"); 3971 return QDF_STATUS_E_FAILURE; 3972 } 3973 3974 if (!len) { 3975 policy_mgr_err("No mandatory freq/chan configured"); 3976 return QDF_STATUS_E_FAILURE; 3977 } 3978 3979 if (!policy_mgr_list_has_24GHz_channel(ch_freq_list, len)) { 3980 policy_mgr_err("2.4GHz channels missing, this is not expected"); 3981 return QDF_STATUS_E_FAILURE; 3982 } 3983 3984 policy_mgr_debug("mandatory chan length:%d", 3985 pm_ctx->sap_mandatory_channels_len); 3986 3987 for (i = 0; i < len; i++) { 3988 pm_ctx->sap_mandatory_channels[i] = ch_freq_list[i]; 3989 policy_mgr_debug("chan:%d", pm_ctx->sap_mandatory_channels[i]); 3990 } 3991 3992 pm_ctx->sap_mandatory_channels_len = len; 3993 3994 return QDF_STATUS_SUCCESS; 3995 } 3996 3997 bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc) 3998 { 3999 struct policy_mgr_psoc_priv_obj *pm_ctx; 4000 4001 pm_ctx = policy_mgr_get_context(psoc); 4002 if (!pm_ctx) { 4003 policy_mgr_err("Invalid Context"); 4004 return false; 4005 } 4006 4007 if (pm_ctx->sap_mandatory_channels_len) 4008 return true; 4009 else 4010 return false; 4011 } 4012 4013 static inline 4014 uint32_t policy_mgr_is_sta_on_indoor_channel(struct wlan_objmgr_psoc *psoc) 4015 { 4016 struct policy_mgr_psoc_priv_obj *pm_ctx; 4017 uint32_t conn_index; 4018 uint32_t freq = INVALID_CHANNEL_ID; 4019 4020 pm_ctx = policy_mgr_get_context(psoc); 4021 if (!pm_ctx) { 4022 policy_mgr_err("Invalid Context"); 4023 return freq; 4024 } 4025 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4026 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 4027 conn_index++) { 4028 if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE && 4029 wlan_reg_is_freq_indoor(pm_ctx->pdev, 4030 pm_conc_connection_list[conn_index].freq) && 4031 pm_conc_connection_list[conn_index].in_use) { 4032 freq = pm_conc_connection_list[conn_index].freq; 4033 break; 4034 } 4035 } 4036 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4037 4038 return freq; 4039 } 4040 4041 QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( 4042 struct wlan_objmgr_psoc *psoc, uint32_t *pcl_list_org, 4043 uint8_t *weight_list_org, uint32_t *pcl_len_org) 4044 { 4045 uint32_t i, j, pcl_len = 0; 4046 bool found; 4047 struct policy_mgr_psoc_priv_obj *pm_ctx; 4048 qdf_freq_t dfs_sta_freq = INVALID_CHANNEL_ID; 4049 qdf_freq_t indoor_sta_freq = INVALID_CHANNEL_ID; 4050 qdf_freq_t sta_5GHz_freq = INVALID_CHANNEL_ID; 4051 enum hw_mode_bandwidth sta_ch_width; 4052 uint8_t sta_vdev_id = 0, scc_on_dfs_channel = 0; 4053 bool sta_sap_scc_on_5ghz_channel; 4054 bool scc_on_indoor = 4055 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 4056 uint8_t go_count; 4057 uint32_t go_op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 4058 uint8_t go_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 4059 uint32_t go_op_ch_freq_5g = 0; 4060 4061 pm_ctx = policy_mgr_get_context(psoc); 4062 if (!pm_ctx) { 4063 policy_mgr_err("Invalid Context"); 4064 return QDF_STATUS_E_FAILURE; 4065 } 4066 4067 if (!pm_ctx->sap_mandatory_channels_len) 4068 return QDF_STATUS_SUCCESS; 4069 4070 if (!policy_mgr_list_has_24GHz_channel(pm_ctx->sap_mandatory_channels, 4071 pm_ctx->sap_mandatory_channels_len)) { 4072 policy_mgr_err("fav channel list is missing 2.4GHz channels"); 4073 return QDF_STATUS_E_FAILURE; 4074 } 4075 4076 4077 for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) 4078 policy_mgr_debug("fav chan:%d", 4079 pm_ctx->sap_mandatory_channels[i]); 4080 4081 if (scc_on_indoor) 4082 indoor_sta_freq = policy_mgr_is_sta_on_indoor_channel(psoc); 4083 4084 policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &scc_on_dfs_channel); 4085 if (scc_on_dfs_channel) 4086 policy_mgr_is_sta_present_on_dfs_channel(psoc, 4087 &sta_vdev_id, 4088 &dfs_sta_freq, 4089 &sta_ch_width); 4090 sta_sap_scc_on_5ghz_channel = 4091 policy_mgr_is_connected_sta_5g(psoc, &sta_5GHz_freq); 4092 4093 go_count = policy_mgr_get_mode_specific_conn_info( 4094 psoc, go_op_ch_freq_list, 4095 go_vdev_id_list, PM_P2P_GO_MODE); 4096 if (go_count && !WLAN_REG_IS_24GHZ_CH_FREQ(go_op_ch_freq_list[0])) { 4097 go_op_ch_freq_5g = go_op_ch_freq_list[0]; 4098 policy_mgr_debug("go 5/6G present, SAP exclude 5/6G channels"); 4099 } 4100 4101 for (i = 0; i < *pcl_len_org; i++) { 4102 found = false; 4103 if (i >= NUM_CHANNELS) { 4104 policy_mgr_debug("index is exceeding NUM_CHANNELS"); 4105 break; 4106 } 4107 4108 if (go_op_ch_freq_5g && 4109 !WLAN_REG_IS_24GHZ_CH_FREQ(pcl_list_org[i])) 4110 continue; 4111 4112 if (scc_on_indoor && policy_mgr_is_force_scc(psoc) && 4113 pcl_list_org[i] == indoor_sta_freq) { 4114 policy_mgr_debug("indoor chan:%d", pcl_list_org[i]); 4115 found = true; 4116 goto update_pcl; 4117 } 4118 4119 if (scc_on_dfs_channel && policy_mgr_is_force_scc(psoc) && 4120 pcl_list_org[i] == dfs_sta_freq) { 4121 policy_mgr_debug("dfs chan:%d", pcl_list_org[i]); 4122 found = true; 4123 goto update_pcl; 4124 } 4125 4126 if (sta_sap_scc_on_5ghz_channel && 4127 policy_mgr_is_force_scc(psoc) && 4128 pcl_list_org[i] == sta_5GHz_freq) { 4129 policy_mgr_debug("scc chan:%d", pcl_list_org[i]); 4130 found = true; 4131 goto update_pcl; 4132 } 4133 4134 for (j = 0; j < pm_ctx->sap_mandatory_channels_len; j++) { 4135 if (pcl_list_org[i] == 4136 pm_ctx->sap_mandatory_channels[j]) { 4137 found = true; 4138 break; 4139 } 4140 } 4141 4142 update_pcl: 4143 if (found && (pcl_len < NUM_CHANNELS)) { 4144 pcl_list_org[pcl_len] = pcl_list_org[i]; 4145 weight_list_org[pcl_len++] = weight_list_org[i]; 4146 } 4147 } 4148 *pcl_len_org = pcl_len; 4149 4150 return QDF_STATUS_SUCCESS; 4151 } 4152 4153 void 4154 policy_mgr_sap_on_non_psc_channel(struct wlan_objmgr_psoc *psoc, 4155 qdf_freq_t *intf_ch_freq, uint8_t vdev_id) 4156 { 4157 struct policy_mgr_pcl_list pcl; 4158 struct wlan_objmgr_vdev *vdev; 4159 QDF_STATUS status; 4160 uint32_t i; 4161 uint32_t ap_pwr_type_6g = 0; 4162 4163 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(*intf_ch_freq)) 4164 return; 4165 4166 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 4167 WLAN_POLICY_MGR_ID); 4168 4169 if (!vdev) { 4170 policy_mgr_err("vdev %d is not present", vdev_id); 4171 return; 4172 } 4173 4174 ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev); 4175 qdf_mem_zero(&pcl, sizeof(pcl)); 4176 4177 /* PCL list is filtered with Non-PSC channels during 4178 * policy_mgr_pcl_modification_for_sap, Reuse same list to check 4179 * if STA is in PSC channel for STA + SAP concurrency during SAP restart 4180 */ 4181 status = policy_mgr_get_pcl_for_existing_conn( 4182 psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, 4183 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list), 4184 false, vdev_id); 4185 4186 if (QDF_IS_STATUS_ERROR(status)) { 4187 policy_mgr_err("Unable to get PCL for SAP"); 4188 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 4189 return; 4190 } 4191 4192 for (i = 0; i < pcl.pcl_len; i++) { 4193 if ((WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl.pcl_list[i])) && 4194 pcl.pcl_list[i] == *intf_ch_freq && 4195 ap_pwr_type_6g == REG_VERY_LOW_POWER_AP) { 4196 policy_mgr_debug("STA is in PSC channel %d in VLP mode, Hence SAP + STA allowed in PSC", 4197 *intf_ch_freq); 4198 *intf_ch_freq = 0; 4199 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 4200 return; 4201 } 4202 } 4203 4204 /* if STA is in Non-PSC Channel + VLP or in non-VLP mode then move 4205 * SAP to 2 GHz from PCL list channels 4206 */ 4207 *intf_ch_freq = pcl.pcl_list[0]; 4208 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 4209 } 4210 4211 QDF_STATUS 4212 policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, 4213 uint32_t sap_ch_freq, 4214 uint32_t *intf_ch_freq, 4215 uint8_t vdev_id) 4216 { 4217 struct policy_mgr_psoc_priv_obj *pm_ctx; 4218 QDF_STATUS status; 4219 struct policy_mgr_pcl_list pcl; 4220 uint32_t i; 4221 uint32_t sap_new_freq; 4222 uint8_t mcc_to_scc_switch; 4223 uint8_t sta_count; 4224 qdf_freq_t user_config_freq = 0; 4225 bool sta_sap_scc_on_indoor_channel = 4226 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 4227 4228 mcc_to_scc_switch = 4229 policy_mgr_get_mcc_to_scc_switch_mode(psoc); 4230 4231 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 4232 NULL); 4233 4234 if (!sta_count || mcc_to_scc_switch != 4235 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) 4236 return QDF_STATUS_E_FAILURE; 4237 4238 pm_ctx = policy_mgr_get_context(psoc); 4239 if (!pm_ctx) { 4240 policy_mgr_err("Invalid Context"); 4241 return QDF_STATUS_E_FAILURE; 4242 } 4243 4244 qdf_mem_zero(&pcl, sizeof(pcl)); 4245 4246 status = policy_mgr_get_pcl_for_existing_conn( 4247 psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, 4248 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list), 4249 false, vdev_id); 4250 if (QDF_IS_STATUS_ERROR(status)) { 4251 policy_mgr_err("Unable to get PCL for SAP"); 4252 return status; 4253 } 4254 4255 /* 4256 * Get inside below loop if no existing SAP connection and hence a new 4257 * SAP connection might be coming up. pcl.pcl_len can be 0 if no common 4258 * channel between PCL & mandatory channel list as well 4259 */ 4260 if (!pcl.pcl_len && !policy_mgr_mode_specific_connection_count(psoc, 4261 PM_SAP_MODE, NULL)) { 4262 policy_mgr_debug("policy_mgr_get_pcl_for_existing_conn returned no pcl"); 4263 status = policy_mgr_get_pcl( 4264 psoc, PM_SAP_MODE, 4265 pcl.pcl_list, &pcl.pcl_len, 4266 pcl.weight_list, 4267 QDF_ARRAY_SIZE(pcl.weight_list), vdev_id); 4268 if (QDF_IS_STATUS_ERROR(status)) { 4269 policy_mgr_err("Unable to get PCL for SAP: policy_mgr_get_pcl"); 4270 return status; 4271 } 4272 } 4273 4274 status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( 4275 psoc, pcl.pcl_list, 4276 pcl.weight_list, 4277 &pcl.pcl_len); 4278 if (QDF_IS_STATUS_ERROR(status)) { 4279 policy_mgr_err("Unable to modify SAP PCL"); 4280 return status; 4281 } 4282 4283 if (!pcl.pcl_len) { 4284 policy_mgr_err("No common channel between mandatory list & PCL"); 4285 return QDF_STATUS_E_FAILURE; 4286 } 4287 4288 /* 4289 * If both freq leads to SBS, and sap_ch_freq is a mandatory freq, 4290 * allow it as they are not interfering. 4291 */ 4292 if (policy_mgr_are_sbs_chan(psoc, sap_ch_freq, *intf_ch_freq)) { 4293 for (i = 0; i < pcl.pcl_len; i++) { 4294 if (pcl.pcl_list[i] == sap_ch_freq) { 4295 policy_mgr_debug("As both freq, %d and %d are SBS, allow sap on mandatory freq %d", 4296 sap_ch_freq, *intf_ch_freq, 4297 sap_ch_freq); 4298 *intf_ch_freq = 0; 4299 return QDF_STATUS_SUCCESS; 4300 } 4301 } 4302 } 4303 4304 /* 4305 * If intf_ch_freq is non-2.4Ghz, First try to get a mandatory freq 4306 * which can cause SBS with intf_ch_freq. i.e if STA is in lower 5Ghz, 4307 * allow higher 5Ghz mandatory freq. 4308 */ 4309 if (!WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) { 4310 for (i = 0; i < pcl.pcl_len; i++) { 4311 if (policy_mgr_are_sbs_chan(psoc, pcl.pcl_list[i], 4312 *intf_ch_freq)) { 4313 sap_new_freq = pcl.pcl_list[i]; 4314 goto update_freq; 4315 } 4316 } 4317 } 4318 4319 sap_new_freq = pcl.pcl_list[0]; 4320 /* 4321 * pcl_list carries multiple channel in ML-STA case depending on 4322 * the no.of links connected. Check if intf_ch_freq is carrying 4323 * any frequency from the list and pick it. If intf_ch_freq is not 4324 * present in the list, the frequency present at pcl_list[0] can 4325 * be picked as caller doesn't have any preferred/chosen channel 4326 * as such. 4327 */ 4328 for (i = 0; i < pcl.pcl_len; i++) { 4329 if (pcl.pcl_list[i] == *intf_ch_freq) { 4330 sap_new_freq = pcl.pcl_list[i]; 4331 break; 4332 } 4333 } 4334 4335 user_config_freq = policy_mgr_get_user_config_sap_freq(psoc, vdev_id); 4336 4337 for (i = 0; i < pcl.pcl_len; i++) { 4338 /* When sta_sap_scc_on_indoor_channel is enabled, 4339 * and if pcl contains SCC channel, then STA must 4340 * exist on the concurrent session. Therefore, choose 4341 * Indoor channel to restart SAP in SCC. 4342 */ 4343 if (wlan_reg_is_freq_indoor(pm_ctx->pdev, pcl.pcl_list[i]) && 4344 !WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl.pcl_list[i]) && 4345 sta_sap_scc_on_indoor_channel) { 4346 sap_new_freq = pcl.pcl_list[i]; 4347 policy_mgr_debug("Choose Indoor channel from PCL list %d sap_new_freq %d", 4348 *intf_ch_freq, sap_new_freq); 4349 goto update_freq; 4350 } 4351 4352 if (user_config_freq && (pcl.pcl_list[i] == user_config_freq)) { 4353 sap_new_freq = pcl.pcl_list[i]; 4354 policy_mgr_debug("Prefer starting SAP on user configured channel:%d", 4355 sap_new_freq); 4356 goto update_freq; 4357 } 4358 } 4359 4360 /* If no SBS Try get SCC freq */ 4361 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) || 4362 (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ch_freq) && 4363 WLAN_REG_IS_5GHZ_CH_FREQ(*intf_ch_freq))) { 4364 for (i = 0; i < pcl.pcl_len; i++) { 4365 if (pcl.pcl_list[i] == *intf_ch_freq) { 4366 sap_new_freq = pcl.pcl_list[i]; 4367 break; 4368 } 4369 } 4370 } 4371 4372 update_freq: 4373 *intf_ch_freq = sap_new_freq; 4374 policy_mgr_debug("Mandatory channel:%d org sap ch %d", *intf_ch_freq, 4375 sap_ch_freq); 4376 4377 return QDF_STATUS_SUCCESS; 4378 } 4379 4380 QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, 4381 struct policy_mgr_pcl_chan_weights *weight, 4382 enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev) 4383 { 4384 uint32_t i, j; 4385 struct policy_mgr_conc_connection_info 4386 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; 4387 uint8_t num_del = 0; 4388 struct policy_mgr_psoc_priv_obj *pm_ctx; 4389 bool strict_follow_pcl = false; 4390 4391 pm_ctx = policy_mgr_get_context(psoc); 4392 if (!pm_ctx) { 4393 policy_mgr_err("Invalid Context"); 4394 return QDF_STATUS_E_FAILURE; 4395 } 4396 4397 qdf_mem_set(weight->weighed_valid_list, NUM_CHANNELS, 4398 WEIGHT_OF_DISALLOWED_CHANNELS); 4399 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4400 if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) || 4401 (mode == PM_STA_MODE && 4402 policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 4403 NULL))) { 4404 /* 4405 * Store the STA mode's parameter and temporarily delete it 4406 * from the concurrency table. This way the allow concurrency 4407 * check can be used as though a new connection is coming up, 4408 * allowing to detect the disallowed channels. 4409 */ 4410 if (mode == PM_STA_MODE) { 4411 if (policy_mgr_concurrent_sta_on_different_mac(psoc) && 4412 !wlan_cm_same_band_sta_allowed(psoc) && 4413 weight->pcl_len) { 4414 policy_mgr_debug("sta follow pcl strictly"); 4415 strict_follow_pcl = true; 4416 } 4417 if (vdev) 4418 policy_mgr_store_and_del_conn_info_by_vdev_id( 4419 psoc, wlan_vdev_get_id(vdev), 4420 info, &num_del); 4421 else 4422 policy_mgr_store_and_del_conn_info(psoc, 4423 mode, true, 4424 info, 4425 &num_del); 4426 } 4427 /* 4428 * For two port/three port connection strictly follow 4429 * PCL weight if coming intf is p2p GO/GC and existing 4430 * vdev is SAP/P2PGO/P2PGC. 4431 */ 4432 if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) && 4433 ((policy_mgr_get_beaconing_mode_count(psoc, NULL)) || 4434 policy_mgr_mode_specific_connection_count( 4435 psoc, PM_P2P_CLIENT_MODE, NULL))) 4436 strict_follow_pcl = true; 4437 4438 /* 4439 * This is a temporary check and will be removed once ll_lt_sap 4440 * CSA support is added. 4441 */ 4442 if (wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc) != 4443 WLAN_INVALID_VDEV_ID) { 4444 policy_mgr_debug("LL_LT_SAP present, strict follow PCL"); 4445 strict_follow_pcl = true; 4446 } 4447 4448 /* 4449 * There is a small window between releasing the above lock 4450 * and acquiring the same in policy_mgr_allow_concurrency, 4451 * below! 4452 */ 4453 4454 for (i = 0; i < weight->saved_num_chan; i++) { 4455 /* 4456 * If channel is not allowed for concurrency, keep pcl 4457 * weight as 0 (WEIGHT_OF_DISALLOWED_CHANNELS) 4458 */ 4459 if (!policy_mgr_is_concurrency_allowed 4460 (psoc, mode, weight->saved_chan_list[i], 4461 HW_MODE_20_MHZ, 4462 policy_mgr_get_conc_ext_flags(vdev, false), NULL)) 4463 continue; 4464 /* 4465 * Keep weight 0 (WEIGHT_OF_DISALLOWED_CHANNELS) not 4466 * changed for scenarios which require to follow PCL. 4467 */ 4468 if (strict_follow_pcl) 4469 continue; 4470 weight->weighed_valid_list[i] = 4471 WEIGHT_OF_NON_PCL_CHANNELS; 4472 } 4473 /* Restore the connection info */ 4474 if (mode == PM_STA_MODE) 4475 policy_mgr_restore_deleted_conn_info(psoc, info, 4476 num_del); 4477 } 4478 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4479 4480 for (i = 0; i < weight->saved_num_chan; i++) { 4481 for (j = 0; j < weight->pcl_len; j++) { 4482 if (weight->saved_chan_list[i] == weight->pcl_list[j]) { 4483 weight->weighed_valid_list[i] = 4484 weight->weight_list[j]; 4485 break; 4486 } 4487 } 4488 } 4489 4490 return QDF_STATUS_SUCCESS; 4491 } 4492 4493 uint32_t policy_mgr_mode_specific_get_channel( 4494 struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) 4495 { 4496 uint32_t conn_index; 4497 struct policy_mgr_psoc_priv_obj *pm_ctx; 4498 uint32_t freq = 0; 4499 4500 pm_ctx = policy_mgr_get_context(psoc); 4501 if (!pm_ctx) { 4502 policy_mgr_err("Invalid Context"); 4503 return 0; 4504 } 4505 /* provides the channel for the first matching mode type */ 4506 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4507 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 4508 conn_index++) { 4509 if ((pm_conc_connection_list[conn_index].mode == mode) && 4510 pm_conc_connection_list[conn_index].in_use) { 4511 freq = pm_conc_connection_list[conn_index].freq; 4512 break; 4513 } 4514 } 4515 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4516 4517 return freq; 4518 } 4519 4520 uint32_t policy_mgr_get_connection_count_with_ch_freq(uint32_t ch_freq) 4521 { 4522 uint32_t i; 4523 uint32_t count = 0; 4524 4525 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 4526 if (pm_conc_connection_list[i].in_use && 4527 ch_freq == pm_conc_connection_list[i].freq) 4528 count++; 4529 } 4530 4531 return count; 4532 } 4533 4534 uint32_t policy_mgr_get_alternate_channel_for_sap( 4535 struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id, 4536 uint32_t sap_ch_freq, 4537 enum reg_wifi_band pref_band) 4538 { 4539 uint32_t pcl_channels[NUM_CHANNELS]; 4540 uint8_t pcl_weight[NUM_CHANNELS]; 4541 uint32_t ch_freq = 0; 4542 uint32_t pcl_len = 0; 4543 uint32_t first_valid_dfs_5g_freq = 0; 4544 uint32_t first_valid_non_dfs_5g_freq = 0; 4545 uint32_t first_valid_6g_freq = 0; 4546 struct policy_mgr_conc_connection_info info; 4547 uint8_t num_cxn_del = 0; 4548 struct policy_mgr_psoc_priv_obj *pm_ctx; 4549 uint8_t i; 4550 enum policy_mgr_con_mode con_mode; 4551 bool is_6ghz_cap; 4552 4553 pm_ctx = policy_mgr_get_context(psoc); 4554 if (!pm_ctx) { 4555 policy_mgr_err("Invalid Context"); 4556 return 0; 4557 } 4558 con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id); 4559 is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL); 4560 /* 4561 * Store the connection's parameter and temporarily delete it 4562 * from the concurrency table. This way the get pcl can be used as a 4563 * new connection is coming up, after check, restore the connection to 4564 * concurrency table. 4565 */ 4566 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4567 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, 4568 &info, &num_cxn_del); 4569 if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl( 4570 psoc, con_mode, pcl_channels, &pcl_len, 4571 pcl_weight, QDF_ARRAY_SIZE(pcl_weight), sap_vdev_id)) { 4572 for (i = 0; i < pcl_len; i++) { 4573 /* 4574 * The API is expected to select the channel on the 4575 * other band which is not same as sap's home and 4576 * concurrent interference channel (if present), 4577 * so skip the sap home channel in PCL. 4578 */ 4579 if (pcl_channels[i] == sap_ch_freq) 4580 continue; 4581 if (!is_6ghz_cap && 4582 WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_channels[i])) 4583 continue; 4584 if (policy_mgr_get_connection_count(psoc) && 4585 policy_mgr_are_2_freq_on_same_mac(psoc, 4586 sap_ch_freq, 4587 pcl_channels[i])) 4588 continue; 4589 if (policy_mgr_get_connection_count_with_ch_freq( 4590 pcl_channels[i])) { 4591 ch_freq = pcl_channels[i]; 4592 break; 4593 } else if (!ch_freq) { 4594 ch_freq = pcl_channels[i]; 4595 } 4596 if (!first_valid_non_dfs_5g_freq && 4597 wlan_reg_is_5ghz_ch_freq(pcl_channels[i])) { 4598 if (!wlan_reg_is_dfs_in_secondary_list_for_freq( 4599 pm_ctx->pdev, 4600 pcl_channels[i])) { 4601 first_valid_non_dfs_5g_freq = pcl_channels[i]; 4602 if (pref_band == REG_BAND_5G) 4603 break; 4604 } else if (!first_valid_dfs_5g_freq) { 4605 first_valid_dfs_5g_freq = pcl_channels[i]; 4606 } 4607 } 4608 if (!first_valid_6g_freq && 4609 wlan_reg_is_6ghz_chan_freq(pcl_channels[i])) { 4610 first_valid_6g_freq = pcl_channels[i]; 4611 if (pref_band == REG_BAND_6G) 4612 break; 4613 } 4614 } 4615 } 4616 4617 /* Restore the connection entry */ 4618 if (num_cxn_del > 0) 4619 policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); 4620 4621 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4622 if (pref_band == REG_BAND_6G) { 4623 if (first_valid_6g_freq) 4624 ch_freq = first_valid_6g_freq; 4625 else if (first_valid_non_dfs_5g_freq) 4626 ch_freq = first_valid_non_dfs_5g_freq; 4627 else if (first_valid_dfs_5g_freq) 4628 ch_freq = first_valid_dfs_5g_freq; 4629 } else if (pref_band == REG_BAND_5G) { 4630 if (first_valid_non_dfs_5g_freq) 4631 ch_freq = first_valid_non_dfs_5g_freq; 4632 else if (first_valid_dfs_5g_freq) 4633 ch_freq = first_valid_dfs_5g_freq; 4634 } 4635 4636 return ch_freq; 4637 } 4638 4639 /* 4640 * Buffer len size to consider the 4 char freq, 3 char weight, 2 char 4641 * for open close brackets and space and a space, Total 10 4642 */ 4643 #define CHAN_WEIGHT_CHAR_LEN 10 4644 #define MAX_CHAN_TO_PRINT 39 4645 4646 bool policy_mgr_dump_channel_list(uint32_t len, uint32_t *pcl_channels, 4647 uint8_t *pcl_weight) 4648 { 4649 uint32_t idx, buff_len, num = 0, count = 0; 4650 char *chan_buff = NULL; 4651 4652 buff_len = (QDF_MIN(len, MAX_CHAN_TO_PRINT) * CHAN_WEIGHT_CHAR_LEN) + 1; 4653 chan_buff = qdf_mem_malloc(buff_len); 4654 if (!chan_buff) 4655 return false; 4656 4657 policymgr_nofl_debug("Total PCL Chan Freq %d", len); 4658 for (idx = 0; (idx < len) && (idx < NUM_CHANNELS); idx++) { 4659 num += qdf_scnprintf(chan_buff + num, buff_len - num, 4660 " %d[%d]", pcl_channels[idx], 4661 pcl_weight[idx]); 4662 count++; 4663 if (count >= MAX_CHAN_TO_PRINT) { 4664 /* Print the MAX_CHAN_TO_PRINT channels */ 4665 policymgr_nofl_debug("Freq[weight]:%s", 4666 chan_buff); 4667 count = 0; 4668 num = 0; 4669 } 4670 } 4671 /* Print any pending channels */ 4672 if (num) 4673 policymgr_nofl_debug("Freq[weight]:%s", chan_buff); 4674 4675 qdf_mem_free(chan_buff); 4676 4677 return true; 4678 } 4679 4680 QDF_STATUS policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev *pdev, 4681 uint32_t *ch_freq_list, 4682 uint32_t *ch_cnt) 4683 { 4684 size_t ch_index; 4685 size_t target_ch_cnt = 0; 4686 4687 if (!pdev || !ch_freq_list || !ch_cnt) { 4688 policy_mgr_err("NULL parameters"); 4689 return QDF_STATUS_E_FAULT; 4690 } 4691 4692 for (ch_index = 0; ch_index < *ch_cnt; ch_index++) { 4693 if (wlan_reg_is_passive_for_freq(pdev, 4694 ch_freq_list[ch_index])) { 4695 policy_mgr_debug("Remove freq: %d from list as it's passive", 4696 ch_freq_list[ch_index]); 4697 continue; 4698 } 4699 ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index]; 4700 } 4701 4702 *ch_cnt = target_ch_cnt; 4703 4704 return QDF_STATUS_SUCCESS; 4705 } 4706 4707 bool policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc *psoc, 4708 enum policy_mgr_con_mode mode, 4709 qdf_freq_t ch_freq) 4710 { 4711 enum policy_mgr_pcl_type pcl = PM_NONE; 4712 enum policy_mgr_conc_priority_mode conc_system_pref = 0; 4713 enum policy_mgr_two_connection_mode third_index = 0; 4714 struct policy_mgr_psoc_priv_obj *pm_ctx; 4715 bool ret = false; 4716 4717 pm_ctx = policy_mgr_get_context(psoc); 4718 if (!pm_ctx) { 4719 policy_mgr_err("context is NULL"); 4720 return false; 4721 } 4722 4723 if (pm_conc_connection_list[0].freq != ch_freq || 4724 pm_conc_connection_list[0].freq != 4725 pm_conc_connection_list[1].freq) { 4726 policy_mgr_debug("No MCC support in 3vif in same mac: %d %d %d", 4727 pm_conc_connection_list[0].freq, 4728 pm_conc_connection_list[1].freq, 4729 ch_freq); 4730 return false; 4731 } 4732 4733 policy_mgr_debug("pref:%d requested mode:%d", 4734 pm_ctx->cur_conc_system_pref, mode); 4735 4736 switch (pm_ctx->cur_conc_system_pref) { 4737 case 0: 4738 conc_system_pref = PM_THROUGHPUT; 4739 break; 4740 case 1: 4741 conc_system_pref = PM_POWERSAVE; 4742 break; 4743 case 2: 4744 conc_system_pref = PM_LATENCY; 4745 break; 4746 default: 4747 policy_mgr_err("unknown cur_conc_system_pref value %d", 4748 pm_ctx->cur_conc_system_pref); 4749 break; 4750 } 4751 4752 third_index = policy_mgr_get_third_connection_pcl_table_index(psoc); 4753 if (PM_MAX_TWO_CONNECTION_MODE == third_index) { 4754 policy_mgr_err( 4755 "couldn't find index for 3rd connection pcl table"); 4756 return false; 4757 } 4758 if (policy_mgr_is_hw_dbs_capable(psoc) == true) { 4759 pcl = (*third_connection_pcl_dbs_table) 4760 [third_index][mode][conc_system_pref]; 4761 } else { 4762 pcl = (*third_connection_pcl_non_dbs_table) 4763 [third_index][mode][conc_system_pref]; 4764 } 4765 4766 policy_mgr_debug("pcl for third connection mode %s is %d %s", 4767 device_mode_to_string(mode), pcl, 4768 pcl_type_to_string(pcl)); 4769 switch (pcl) { 4770 case PM_SCC_CH: 4771 case PM_SCC_CH_24G: 4772 case PM_SCC_CH_5G: 4773 case PM_24G_SCC_CH: 4774 case PM_5G_SCC_CH: 4775 case PM_SCC_ON_5_CH_5G: 4776 case PM_SCC_ON_5_SCC_ON_24_24G: 4777 case PM_SCC_ON_5_SCC_ON_24_5G: 4778 case PM_SCC_ON_5_5G_24G: 4779 case PM_SCC_ON_5_5G_SCC_ON_24G: 4780 case PM_SCC_ON_24_SCC_ON_5_24G: 4781 case PM_SCC_ON_24_SCC_ON_5_5G: 4782 case PM_SCC_ON_24_CH_24G: 4783 case PM_SCC_ON_5_SCC_ON_24: 4784 case PM_SCC_ON_24_SCC_ON_5: 4785 case PM_24G_SCC_CH_SBS_CH: 4786 case PM_24G_SCC_CH_SBS_CH_5G: 4787 case PM_SBS_CH_24G_SCC_CH: 4788 case PM_SBS_CH_SCC_CH_24G: 4789 case PM_SCC_CH_SBS_CH_24G: 4790 case PM_SBS_CH_SCC_CH_5G_24G: 4791 case PM_SCC_CH_MCC_CH_SBS_CH_24G: 4792 case PM_MCC_CH: 4793 case PM_MCC_CH_24G: 4794 case PM_MCC_CH_5G: 4795 case PM_24G_MCC_CH: 4796 case PM_5G_MCC_CH: 4797 case PM_24G_SBS_CH_MCC_CH: 4798 ret = true; 4799 break; 4800 default: 4801 policy_mgr_debug("Not in SCC case"); 4802 ret = false; 4803 break; 4804 } 4805 return ret; 4806 } 4807 4808 bool policy_mgr_is_sta_chan_valid_for_connect_and_roam( 4809 struct wlan_objmgr_pdev *pdev, 4810 qdf_freq_t freq) 4811 { 4812 struct wlan_objmgr_psoc *psoc; 4813 uint32_t sap_count; 4814 bool skip_6g_and_indoor_freq; 4815 4816 psoc = wlan_pdev_get_psoc(pdev); 4817 if (!psoc) 4818 return true; 4819 4820 skip_6g_and_indoor_freq = 4821 wlan_scan_cfg_skip_6g_and_indoor_freq(psoc); 4822 sap_count = 4823 policy_mgr_get_sap_mode_count(psoc, NULL); 4824 /* 4825 * Do not allow STA to connect/roam on 6Ghz or indoor channel for 4826 * non-dbs hardware if SAP is present and skip_6g_and_indoor_freq_scan 4827 * ini is enabled 4828 */ 4829 if (skip_6g_and_indoor_freq && sap_count && 4830 !policy_mgr_is_hw_dbs_capable(psoc) && 4831 (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq) || 4832 wlan_reg_is_freq_indoor(pdev, freq))) 4833 return false; 4834 4835 return true; 4836 } 4837 4838 /** 4839 * _policy_mgr_is_vdev_ll_sap() - Check whether any LL SAP is present or not 4840 * for provided ap policy 4841 * @psoc: psoc object 4842 * @vdev_id: vdev id 4843 * @ap_type: LL SAP type 4844 * 4845 * Return: true if it's present otherwise false 4846 */ 4847 static bool 4848 _policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc, 4849 uint32_t vdev_id, enum ll_ap_type ap_type) 4850 { 4851 struct wlan_objmgr_vdev *vdev; 4852 bool is_ll_sap = false; 4853 enum QDF_OPMODE mode; 4854 struct policy_mgr_psoc_priv_obj *pm_ctx; 4855 enum host_concurrent_ap_policy profile = 4856 HOST_CONCURRENT_AP_POLICY_UNSPECIFIED; 4857 4858 pm_ctx = policy_mgr_get_context(psoc); 4859 if (!pm_ctx) { 4860 policy_mgr_err("Invalid pm_ctx"); 4861 return is_ll_sap; 4862 } 4863 4864 mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 4865 4866 if (mode != QDF_SAP_MODE) 4867 return is_ll_sap; 4868 4869 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 4870 WLAN_POLICY_MGR_ID); 4871 if (!vdev) { 4872 policy_mgr_err("vdev %d: invalid vdev", vdev_id); 4873 return is_ll_sap; 4874 } 4875 4876 profile = wlan_mlme_get_ap_policy(vdev); 4877 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 4878 switch (ap_type) { 4879 case LL_AP_TYPE_HT: 4880 if (profile == HOST_CONCURRENT_AP_POLICY_XR) 4881 is_ll_sap = true; 4882 break; 4883 case LL_AP_TYPE_LT: 4884 if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO || 4885 profile == 4886 HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING) 4887 is_ll_sap = true; 4888 break; 4889 case LL_AP_TYPE_ANY: 4890 if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO || 4891 profile == 4892 HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING || 4893 profile == HOST_CONCURRENT_AP_POLICY_XR) 4894 is_ll_sap = true; 4895 break; 4896 default: 4897 policy_mgr_err("invalid ap type %d", ap_type); 4898 } 4899 return is_ll_sap; 4900 } 4901 4902 bool 4903 policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc, 4904 uint32_t vdev_id) 4905 { 4906 return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_ANY); 4907 } 4908 4909 bool 4910 policy_mgr_is_vdev_ll_ht_sap(struct wlan_objmgr_psoc *psoc, 4911 uint32_t vdev_id) 4912 { 4913 return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_HT); 4914 } 4915 4916 bool 4917 policy_mgr_is_vdev_ll_lt_sap(struct wlan_objmgr_psoc *psoc, 4918 uint32_t vdev_id) 4919 { 4920 return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_LT); 4921 } 4922 4923 #ifndef WLAN_FEATURE_LL_LT_SAP 4924 QDF_STATUS 4925 policy_mgr_get_pcl_chlist_for_ll_sap(struct wlan_objmgr_psoc *psoc, 4926 uint32_t *len, uint32_t *pcl_channels, 4927 uint8_t *pcl_weight) 4928 { 4929 struct policy_mgr_psoc_priv_obj *pm_ctx; 4930 uint32_t pcl_len = 0, i, conn_idx = 0; 4931 uint32_t pcl_list[NUM_CHANNELS], total_connection = 0; 4932 uint8_t weight_list[NUM_CHANNELS]; 4933 qdf_freq_t freq; 4934 4935 pm_ctx = policy_mgr_get_context(psoc); 4936 if (!pm_ctx) { 4937 policy_mgr_err("pm_ctx is null"); 4938 return QDF_STATUS_E_FAILURE; 4939 } 4940 4941 total_connection = policy_mgr_get_connection_count(psoc); 4942 if (!total_connection) { 4943 for (i = 0; i < *len; i++) { 4944 if (WLAN_REG_IS_24GHZ_CH_FREQ(pcl_channels[i])) 4945 continue; 4946 4947 pcl_list[pcl_len] = pcl_channels[i]; 4948 weight_list[pcl_len++] = pcl_weight[i]; 4949 } 4950 qdf_mem_zero(pcl_channels, *len * sizeof(*pcl_channels)); 4951 qdf_mem_copy(pcl_channels, pcl_list, 4952 pcl_len * sizeof(*pcl_channels)); 4953 } else { 4954 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4955 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; 4956 conn_idx++) { 4957 if (!pm_conc_connection_list[conn_idx].in_use) 4958 continue; 4959 4960 freq = pm_conc_connection_list[conn_idx].freq; 4961 4962 for (i = 0; i < *len; i++) { 4963 if (policy_mgr_2_freq_always_on_same_mac( 4964 psoc, 4965 pcl_channels[i], 4966 freq) || 4967 WLAN_REG_IS_24GHZ_CH_FREQ(pcl_channels[i])) 4968 continue; 4969 pcl_list[pcl_len] = pcl_channels[i]; 4970 weight_list[pcl_len++] = pcl_weight[i]; 4971 } 4972 *len = pcl_len; 4973 qdf_mem_zero(pcl_channels, 4974 *len * sizeof(*pcl_channels)); 4975 qdf_mem_copy(pcl_channels, pcl_list, 4976 pcl_len * sizeof(*pcl_channels)); 4977 } 4978 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4979 } 4980 4981 qdf_mem_zero(pcl_weight, *len * sizeof(*pcl_weight)); 4982 qdf_mem_copy(pcl_weight, weight_list, pcl_len); 4983 *len = pcl_len; 4984 4985 return QDF_STATUS_SUCCESS; 4986 } 4987 4988 QDF_STATUS 4989 policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present( 4990 struct wlan_objmgr_psoc *psoc, 4991 uint32_t *len, uint32_t *pcl_channels, 4992 uint8_t *pcl_weight) 4993 { 4994 struct policy_mgr_psoc_priv_obj *pm_ctx; 4995 uint32_t pcl_len = 0, i, conn_idx = 0; 4996 uint32_t pcl_list[NUM_CHANNELS]; 4997 uint8_t weight_list[NUM_CHANNELS]; 4998 qdf_freq_t freq; 4999 uint32_t vdev_id; 5000 bool is_ll_sap = 0; 5001 5002 pm_ctx = policy_mgr_get_context(psoc); 5003 if (!pm_ctx) { 5004 policy_mgr_err("pm_ctx is null"); 5005 return QDF_STATUS_E_FAILURE; 5006 } 5007 5008 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5009 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; 5010 conn_idx++) { 5011 if (!pm_conc_connection_list[conn_idx].in_use) 5012 continue; 5013 5014 freq = pm_conc_connection_list[conn_idx].freq; 5015 vdev_id = pm_conc_connection_list[conn_idx].vdev_id; 5016 if (!policy_mgr_is_vdev_ll_sap(psoc, vdev_id)) 5017 continue; 5018 5019 is_ll_sap = 1; 5020 for (i = 0; i < *len; i++) { 5021 if (policy_mgr_2_freq_always_on_same_mac( 5022 psoc, 5023 pcl_channels[i], 5024 freq)) 5025 continue; 5026 pcl_list[pcl_len] = pcl_channels[i]; 5027 weight_list[pcl_len++] = pcl_weight[i]; 5028 } 5029 *len = pcl_len; 5030 qdf_mem_zero(pcl_channels, 5031 *len * sizeof(*pcl_channels)); 5032 qdf_mem_copy(pcl_channels, pcl_list, 5033 pcl_len * sizeof(*pcl_channels)); 5034 } 5035 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5036 5037 if (!is_ll_sap) 5038 return QDF_STATUS_SUCCESS; 5039 5040 qdf_mem_zero(pcl_weight, *len * sizeof(*pcl_weight)); 5041 qdf_mem_copy(pcl_weight, weight_list, pcl_len); 5042 *len = pcl_len; 5043 5044 return QDF_STATUS_SUCCESS; 5045 } 5046 5047 QDF_STATUS 5048 policy_mgr_get_pcl_channel_for_ll_sap_concurrency( 5049 struct wlan_objmgr_psoc *psoc, 5050 uint32_t vdev_id, 5051 uint32_t *pcl_channels, 5052 uint8_t *pcl_weight, uint32_t *len) 5053 { 5054 uint32_t orig_len = *len; 5055 5056 if (policy_mgr_is_vdev_ll_sap(psoc, vdev_id)) { 5057 /* Scenario: If there is some existing interface present and 5058 * LL SAP is coming up. 5059 * Filter pcl channel for LL SAP 5060 */ 5061 policy_mgr_get_pcl_chlist_for_ll_sap(psoc, len, pcl_channels, 5062 pcl_weight); 5063 } else { 5064 /* Scenario: If there is LL SAP and GO/SAP is coming up. 5065 * Filter pcl channel for GO/SAP 5066 */ 5067 policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present( 5068 psoc, 5069 len, 5070 pcl_channels, 5071 pcl_weight); 5072 } 5073 5074 if (orig_len != *len) { 5075 policy_mgr_debug("PCL after ll sap modification"); 5076 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); 5077 } 5078 5079 return QDF_STATUS_SUCCESS; 5080 } 5081 #endif 5082 5083 #ifdef WLAN_FEATURE_LL_LT_SAP 5084 QDF_STATUS policy_mgr_get_pcl_ch_list_for_ll_sap( 5085 struct wlan_objmgr_psoc *psoc, 5086 struct policy_mgr_pcl_list *pcl, 5087 uint8_t vdev_id, 5088 struct connection_info *info, 5089 uint8_t *connection_count) 5090 { 5091 struct policy_mgr_psoc_priv_obj *pm_ctx; 5092 uint8_t num_cxn_del = 0; 5093 struct policy_mgr_conc_connection_info pm_info = {0}; 5094 QDF_STATUS status; 5095 5096 pm_ctx = policy_mgr_get_context(psoc); 5097 if (!pm_ctx) 5098 return QDF_STATUS_E_FAILURE; 5099 5100 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 5101 5102 /* 5103 * Scenario: Standalone XPAN is present and CSA happens on 5104 * LL_LT_SAP interface. 5105 * During CSA, it will check the PCL list to get the new freq. 5106 * Since there is already LL_LT_SAP interface entry in PCL index. 5107 * It will lead to LL_LT_SAP + LL_LT_SAP concurrencies. To avoid 5108 * that, delete the existing connection entry from PCL index, 5109 * get the PCL list and restore it back. 5110 */ 5111 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, 5112 &pm_info, &num_cxn_del); 5113 5114 status = policy_mgr_get_pcl(psoc, PM_LL_LT_SAP_MODE, pcl->pcl_list, 5115 &pcl->pcl_len, pcl->weight_list, 5116 QDF_ARRAY_SIZE(pcl->weight_list), 5117 vdev_id); 5118 5119 /* 5120 * Get existing connection info before updating LL_LT_SAP freq list 5121 * This will help to avoid updation of SCC channel in LL_LT_SAP 5122 * freq list. 5123 */ 5124 *connection_count = policy_mgr_get_connection_info(psoc, info); 5125 5126 /* Restore the connection entry */ 5127 if (num_cxn_del > 0) 5128 policy_mgr_restore_deleted_conn_info(psoc, &pm_info, 5129 num_cxn_del); 5130 5131 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 5132 5133 return status; 5134 } 5135 #endif 5136