1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_policy_mgr_action.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 "wlan_objmgr_global_obj.h" 34 #include "qdf_platform.h" 35 #include "wlan_nan_api.h" 36 #include "nan_ucfg_api.h" 37 #include "wlan_mlme_api.h" 38 #include "sap_api.h" 39 #include "wlan_mlme_api.h" 40 #include "wlan_mlme_ucfg_api.h" 41 #include "target_if.h" 42 #include "wlan_cm_api.h" 43 #include "wlan_mlo_link_force.h" 44 #include "wlan_mlo_mgr_sta.h" 45 #include "wlan_mlo_mgr_link_switch.h" 46 #include "wlan_psoc_mlme_api.h" 47 #include "wlan_policy_mgr_ll_sap.h" 48 49 enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) 50 (struct wlan_objmgr_psoc *psoc); 51 52 #define HW_MODE_DUMP_MAX_LEN 100 53 void 54 policy_mgr_dump_freq_range_n_vdev_map(uint32_t num_vdev_mac_entries, 55 struct policy_mgr_vdev_mac_map *vdev_mac_map, 56 uint32_t num_mac_freq, 57 struct policy_mgr_pdev_mac_freq_map *mac_freq_range) 58 { 59 char log_str[HW_MODE_DUMP_MAX_LEN] = {0}; 60 uint32_t str_len = HW_MODE_DUMP_MAX_LEN; 61 uint32_t len = 0; 62 uint32_t i; 63 64 if (mac_freq_range) { 65 for (i = 0, len = 0; i < num_mac_freq; i++) 66 len += qdf_scnprintf(log_str + len, str_len - len, 67 "mac %d: %d => %d ", 68 mac_freq_range[i].mac_id, 69 mac_freq_range[i].start_freq, 70 mac_freq_range[i].end_freq); 71 if (num_mac_freq) 72 policymgr_nofl_debug("Freq range:: %s", log_str); 73 } 74 75 if (!vdev_mac_map || !num_vdev_mac_entries) 76 return; 77 78 for (i = 0, len = 0; i < num_vdev_mac_entries; i++) 79 len += qdf_scnprintf(log_str + len, str_len - len, 80 "vdev %d -> mac %d ", 81 vdev_mac_map[i].vdev_id, 82 vdev_mac_map[i].mac_id); 83 policymgr_nofl_debug("Vdev Map:: %s", log_str); 84 } 85 86 void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, 87 uint32_t new_hw_mode_index, 88 uint32_t num_vdev_mac_entries, 89 struct policy_mgr_vdev_mac_map *vdev_mac_map, 90 uint32_t num_mac_freq, 91 struct policy_mgr_pdev_mac_freq_map *mac_freq_range, 92 struct wlan_objmgr_psoc *context) 93 { 94 QDF_STATUS status; 95 struct policy_mgr_hw_mode_params hw_mode; 96 struct policy_mgr_psoc_priv_obj *pm_ctx; 97 98 pm_ctx = policy_mgr_get_context(context); 99 if (!pm_ctx) { 100 policy_mgr_err("Invalid context"); 101 return; 102 } 103 104 if (!vdev_mac_map) { 105 policy_mgr_err("vdev_mac_map is NULL"); 106 return; 107 } 108 109 status = policy_mgr_get_hw_mode_from_idx(context, new_hw_mode_index, 110 &hw_mode); 111 if (QDF_IS_STATUS_ERROR(status)) { 112 policy_mgr_err("Get HW mode for index %d reason: %d", 113 new_hw_mode_index, status); 114 return; 115 } 116 117 policy_mgr_debug("HW mode: old %d new %d, DBS %d Agile %d SBS %d, MAC0:: SS:Tx %d Rx %d, BW %d band %d, MAC1:: SS:Tx %d Rx %d, BW %d", 118 old_hw_mode_index, new_hw_mode_index, hw_mode.dbs_cap, 119 hw_mode.agile_dfs_cap, hw_mode.sbs_cap, 120 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, 121 hw_mode.mac0_bw, hw_mode.mac0_band_cap, 122 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, 123 hw_mode.mac1_bw); 124 policy_mgr_dump_freq_range_n_vdev_map(num_vdev_mac_entries, 125 vdev_mac_map, num_mac_freq, 126 mac_freq_range); 127 128 /* update pm_conc_connection_list */ 129 policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries, 130 vdev_mac_map, hw_mode, 131 num_mac_freq, mac_freq_range); 132 133 if (pm_ctx->mode_change_cb) 134 pm_ctx->mode_change_cb(); 135 136 return; 137 } 138 139 QDF_STATUS policy_mgr_check_n_start_opportunistic_timer( 140 struct wlan_objmgr_psoc *psoc) 141 { 142 struct policy_mgr_psoc_priv_obj *pm_ctx; 143 QDF_STATUS status = QDF_STATUS_E_FAILURE; 144 enum policy_mgr_conn_update_reason reason = 145 POLICY_MGR_UPDATE_REASON_TIMER_START; 146 147 pm_ctx = policy_mgr_get_context(psoc); 148 if (!pm_ctx) { 149 policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start"); 150 return QDF_STATUS_E_FAILURE; 151 } 152 if (policy_mgr_need_opportunistic_upgrade(psoc, &reason)) { 153 /* let's start the timer */ 154 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); 155 status = qdf_mc_timer_start( 156 &pm_ctx->dbs_opportunistic_timer, 157 DBS_OPPORTUNISTIC_TIME * 1000); 158 if (!QDF_IS_STATUS_SUCCESS(status)) 159 policy_mgr_err("Failed to start dbs opportunistic timer"); 160 } 161 return status; 162 } 163 164 QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, 165 uint32_t session_id, 166 enum hw_mode_ss_config mac0_ss, 167 enum hw_mode_bandwidth mac0_bw, 168 enum hw_mode_ss_config mac1_ss, 169 enum hw_mode_bandwidth mac1_bw, 170 enum hw_mode_mac_band_cap mac0_band_cap, 171 enum hw_mode_dbs_capab dbs, 172 enum hw_mode_agile_dfs_capab dfs, 173 enum hw_mode_sbs_capab sbs, 174 enum policy_mgr_conn_update_reason reason, 175 uint8_t next_action, enum policy_mgr_conc_next_action action, 176 uint32_t request_id) 177 { 178 int8_t hw_mode_index; 179 struct policy_mgr_hw_mode msg; 180 QDF_STATUS status; 181 struct policy_mgr_psoc_priv_obj *pm_ctx; 182 183 pm_ctx = policy_mgr_get_context(psoc); 184 if (!pm_ctx) { 185 policy_mgr_err("Invalid context"); 186 return QDF_STATUS_E_FAILURE; 187 } 188 189 if (!pm_ctx->sme_cbacks.sme_pdev_set_hw_mode) { 190 policy_mgr_debug("NOT supported"); 191 return QDF_STATUS_E_NOSUPPORT; 192 } 193 194 /* 195 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't 196 * allow to request FW for 2x2 197 */ 198 if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) { 199 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0"); 200 mac0_ss = HW_MODE_SS_1x1; 201 } 202 if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) { 203 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1"); 204 mac1_ss = HW_MODE_SS_1x1; 205 } 206 207 hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc, 208 mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap, 209 dbs, dfs, sbs); 210 if (hw_mode_index < 0) { 211 policy_mgr_err("Invalid HW mode index obtained"); 212 return QDF_STATUS_E_FAILURE; 213 } 214 215 /* Don't send WMI_PDEV_SET_HW_MODE_CMDID to FW if existing SAP / GO is 216 * in CAC-in-progress state. Host is blocking this command as FW is 217 * having design limitation and FW don't expect this command when CAC 218 * is in progress state. 219 */ 220 if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && 221 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress() && 222 !policy_mgr_is_hw_dbs_2x2_capable(psoc)) { 223 policy_mgr_err("SAP CAC_IN_PROGRESS state, drop WMI_PDEV_SET_HW_MODE_CMDID"); 224 return QDF_STATUS_E_FAILURE; 225 } 226 227 msg.hw_mode_index = hw_mode_index; 228 msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb; 229 msg.reason = reason; 230 msg.session_id = session_id; 231 msg.next_action = next_action; 232 msg.action = action; 233 msg.context = psoc; 234 msg.request_id = request_id; 235 236 policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d action %d request_id %d", 237 msg.hw_mode_index, msg.session_id, msg.reason, action, 238 msg.request_id); 239 240 status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg); 241 if (status != QDF_STATUS_SUCCESS) { 242 policy_mgr_err("Failed to set hw mode to SME"); 243 return status; 244 } 245 246 return QDF_STATUS_SUCCESS; 247 } 248 249 /** 250 * policy_mgr_get_sap_bw() - get current SAP bandwidth 251 * @psoc: Pointer to psoc 252 * @bw: Buffer to update the bandwidth 253 * 254 * Get the current SAP bandwidth. This API supports only single SAP 255 * concurrencies and doesn't cover multi SAP(e.g. SAP+SAP). 256 * 257 * return : QDF_STATUS 258 */ 259 static QDF_STATUS 260 policy_mgr_get_sap_bw(struct wlan_objmgr_psoc *psoc, enum phy_ch_width *bw) 261 { 262 uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; 263 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; 264 struct wlan_objmgr_vdev *vdev; 265 266 if (policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0], 267 &vdev_id_list[0], 268 PM_SAP_MODE) != 1) 269 return QDF_STATUS_E_NOSUPPORT; 270 271 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[0], 272 WLAN_POLICY_MGR_ID); 273 if (!vdev) { 274 policy_mgr_err("vdev %d is NULL", vdev_id_list[0]); 275 return QDF_STATUS_E_INVAL; 276 } 277 278 *bw = wlan_mlme_get_ap_oper_ch_width(vdev); 279 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 280 281 return QDF_STATUS_SUCCESS; 282 } 283 284 /** 285 * policy_mgr_get_sap_ch_width_update_action() - get SAP ch_width update action 286 * @psoc: Pointer to psoc 287 * @ch_freq: channel frequency of new connection 288 * @next_action: next action to happen in order to update bandwidth 289 * @reason: Bandwidth upgrade/downgrade reason 290 * 291 * Check if current operating SAP needs a downgrade to 160MHz or an upgrade 292 * to 320MHz based on the new connection. 293 * 294 * return : None 295 */ 296 static void 297 policy_mgr_get_sap_ch_width_update_action(struct wlan_objmgr_psoc *psoc, 298 uint32_t ch_freq, 299 enum policy_mgr_conc_next_action *next_action, 300 enum policy_mgr_conn_update_reason *reason) 301 { 302 enum phy_ch_width cur_bw; 303 uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; 304 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; 305 bool eht_capab = false; 306 307 if (QDF_IS_STATUS_ERROR(wlan_psoc_mlme_get_11be_capab(psoc, 308 &eht_capab)) || 309 !eht_capab || 310 QDF_IS_STATUS_ERROR(policy_mgr_get_sap_bw(psoc, &cur_bw)) || 311 cur_bw < CH_WIDTH_160MHZ) 312 return; 313 314 policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0], 315 &vdev_id_list[0], PM_SAP_MODE); 316 if (cur_bw == CH_WIDTH_320MHZ && 317 ch_freq && policy_mgr_is_conn_lead_to_dbs_sbs(psoc, ch_freq)) 318 *next_action = PM_DOWNGRADE_BW; 319 else if (cur_bw == CH_WIDTH_160MHZ && 320 !ch_freq && 321 !policy_mgr_is_conn_lead_to_dbs_sbs(psoc, freq_list[0]) && 322 (reason && 323 (*reason == POLICY_MGR_UPDATE_REASON_TIMER_START || 324 *reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC))) 325 *next_action = PM_UPGRADE_BW; 326 } 327 328 enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( 329 struct wlan_objmgr_psoc *psoc, 330 enum policy_mgr_conn_update_reason *reason) 331 { 332 uint32_t conn_index; 333 enum policy_mgr_conc_next_action upgrade = PM_NOP; 334 enum policy_mgr_conc_next_action preferred_dbs_action; 335 uint8_t mac = 0; 336 struct policy_mgr_hw_mode_params hw_mode; 337 QDF_STATUS status = QDF_STATUS_E_FAILURE; 338 struct policy_mgr_psoc_priv_obj *pm_ctx; 339 340 if (policy_mgr_is_hwmode_offload_enabled(psoc)) { 341 policy_mgr_get_sap_ch_width_update_action(psoc, 0, &upgrade, 342 reason); 343 return upgrade; 344 } 345 346 pm_ctx = policy_mgr_get_context(psoc); 347 if (!pm_ctx) { 348 policy_mgr_err("Invalid Context"); 349 goto exit; 350 } 351 352 if (policy_mgr_is_hw_dbs_capable(psoc) == false) { 353 policy_mgr_rl_debug("driver isn't dbs capable, no further action needed"); 354 goto exit; 355 } 356 357 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); 358 if (!QDF_IS_STATUS_SUCCESS(status)) { 359 policy_mgr_err("policy_mgr_get_current_hw_mode failed"); 360 goto exit; 361 } 362 if (!hw_mode.dbs_cap) { 363 policy_mgr_debug("current HW mode is non-DBS capable"); 364 goto exit; 365 } 366 367 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 368 /* Are both mac's still in use */ 369 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 370 conn_index++) { 371 policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d", 372 conn_index, 373 pm_conc_connection_list[conn_index].mac, 374 pm_conc_connection_list[conn_index].in_use, 375 pm_conc_connection_list[conn_index].freq, 376 pm_conc_connection_list[conn_index].original_nss); 377 if ((pm_conc_connection_list[conn_index].mac == 0) && 378 pm_conc_connection_list[conn_index].in_use) { 379 mac |= POLICY_MGR_MAC0; 380 if (POLICY_MGR_MAC0_AND_MAC1 == mac) { 381 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 382 goto done; 383 } 384 } else if ((pm_conc_connection_list[conn_index].mac == 1) && 385 pm_conc_connection_list[conn_index].in_use) { 386 mac |= POLICY_MGR_MAC1; 387 if (policy_mgr_is_hw_dbs_required_for_band( 388 psoc, HW_MODE_MAC_BAND_2G) && 389 WLAN_REG_IS_24GHZ_CH_FREQ( 390 pm_conc_connection_list[conn_index].freq)) { 391 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 392 policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection"); 393 goto done; 394 } 395 if (POLICY_MGR_MAC0_AND_MAC1 == mac) { 396 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 397 goto done; 398 } 399 } 400 } 401 /* Let's request for single MAC mode */ 402 upgrade = PM_SINGLE_MAC; 403 if (reason) 404 *reason = POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC; 405 /* Is there any connection had an initial connection with 2x2 */ 406 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; 407 conn_index++) { 408 if ((pm_conc_connection_list[conn_index].original_nss == 2) && 409 pm_conc_connection_list[conn_index].in_use) { 410 upgrade = PM_SINGLE_MAC_UPGRADE; 411 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 412 goto done; 413 } 414 } 415 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 416 417 done: 418 if (upgrade == PM_NOP && hw_mode.dbs_cap && 419 policy_mgr_is_2x2_1x1_dbs_capable(psoc)) { 420 preferred_dbs_action = 421 policy_mgr_get_preferred_dbs_action_table( 422 psoc, INVALID_VDEV_ID, 0, 0); 423 if (hw_mode.action_type == PM_DBS1 && 424 preferred_dbs_action == PM_DBS2) { 425 upgrade = PM_DBS2_DOWNGRADE; 426 if (reason) 427 *reason = 428 POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE; 429 } else if (hw_mode.action_type == PM_DBS2 && 430 preferred_dbs_action == PM_DBS1) { 431 upgrade = PM_DBS1_DOWNGRADE; 432 if (reason) 433 *reason = 434 POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE; 435 } 436 } 437 exit: 438 return upgrade; 439 } 440 441 QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, 442 uint32_t vdev_id) 443 { 444 QDF_STATUS status = QDF_STATUS_E_FAILURE; 445 uint32_t conn_index = 0, ch_freq, cur_freq; 446 bool found = false; 447 struct policy_mgr_vdev_entry_info conn_table_entry; 448 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE; 449 uint8_t nss_2g, nss_5g; 450 enum policy_mgr_con_mode mode; 451 uint32_t nss = 0; 452 struct policy_mgr_psoc_priv_obj *pm_ctx; 453 454 pm_ctx = policy_mgr_get_context(psoc); 455 if (!pm_ctx) { 456 policy_mgr_err("Invalid Context"); 457 return status; 458 } 459 460 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 461 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { 462 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { 463 /* debug msg */ 464 found = true; 465 break; 466 } 467 conn_index++; 468 } 469 470 if (!found) { 471 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 472 /* err msg */ 473 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list", 474 vdev_id); 475 return QDF_STATUS_NOT_INITIALIZED; 476 } 477 if (pm_ctx->wma_cbacks.wma_get_connection_info) { 478 status = pm_ctx->wma_cbacks.wma_get_connection_info( 479 vdev_id, &conn_table_entry); 480 if (QDF_STATUS_SUCCESS != status) { 481 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 482 policy_mgr_err("can't find vdev_id %d in connection table", 483 vdev_id); 484 return status; 485 } 486 } else { 487 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 488 policy_mgr_err("wma_get_connection_info is NULL"); 489 return QDF_STATUS_E_FAILURE; 490 } 491 492 cur_freq = pm_conc_connection_list[conn_index].freq; 493 494 mode = policy_mgr_qdf_opmode_to_pm_con_mode( 495 psoc, 496 wlan_get_opmode_from_vdev_id( 497 pm_ctx->pdev, 498 vdev_id), 499 vdev_id); 500 501 ch_freq = conn_table_entry.mhz; 502 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); 503 if (QDF_IS_STATUS_SUCCESS(status)) { 504 if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) || 505 (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1)) 506 chain_mask = POLICY_MGR_TWO_TWO; 507 else 508 chain_mask = POLICY_MGR_ONE_ONE; 509 nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g; 510 } else { 511 policy_mgr_err("Error in getting nss"); 512 } 513 514 policy_mgr_debug("update PM connection table for vdev:%d", vdev_id); 515 516 /* add the entry */ 517 policy_mgr_update_conc_list( 518 psoc, conn_index, mode, ch_freq, 519 policy_mgr_get_bw(conn_table_entry.chan_width), 520 conn_table_entry.mac_id, chain_mask, 521 nss, vdev_id, true, true, conn_table_entry.ch_flagext); 522 policy_mgr_dump_current_concurrency(psoc); 523 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 524 525 /* do we need to change the HW mode */ 526 policy_mgr_check_n_start_opportunistic_timer(psoc); 527 528 if (policy_mgr_is_conc_sap_present_on_sta_freq(psoc, mode, cur_freq) && 529 policy_mgr_update_indoor_concurrency(psoc, vdev_id, 0, 530 SWITCH_WITH_CONCURRENCY)) 531 wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev); 532 else if (policy_mgr_update_indoor_concurrency(psoc, vdev_id, cur_freq, 533 SWITCH_WITHOUT_CONCURRENCY)) 534 wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev); 535 else if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev) && 536 (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)) 537 wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev); 538 539 ml_nlink_conn_change_notify( 540 psoc, vdev_id, ml_nlink_connection_updated_evt, NULL); 541 542 return QDF_STATUS_SUCCESS; 543 } 544 545 QDF_STATUS policy_mgr_update_and_wait_for_connection_update( 546 struct wlan_objmgr_psoc *psoc, 547 uint8_t session_id, 548 uint32_t ch_freq, 549 enum policy_mgr_conn_update_reason reason) 550 { 551 QDF_STATUS status; 552 553 policy_mgr_debug("session:%d ch_freq:%d reason:%d", 554 session_id, ch_freq, reason); 555 556 status = policy_mgr_reset_connection_update(psoc); 557 if (QDF_IS_STATUS_ERROR(status)) 558 policy_mgr_err("clearing event failed"); 559 560 status = policy_mgr_current_connections_update( 561 psoc, session_id, ch_freq, reason, 562 POLICY_MGR_DEF_REQ_ID); 563 if (QDF_STATUS_E_FAILURE == status) { 564 policy_mgr_err("connections update failed"); 565 return QDF_STATUS_E_FAILURE; 566 } 567 568 /* Wait only when status is success */ 569 if (QDF_IS_STATUS_SUCCESS(status)) { 570 status = policy_mgr_wait_for_connection_update(psoc); 571 if (QDF_IS_STATUS_ERROR(status)) { 572 policy_mgr_err("qdf wait for event failed"); 573 return QDF_STATUS_E_FAILURE; 574 } 575 } 576 577 return QDF_STATUS_SUCCESS; 578 } 579 580 bool policy_mgr_is_dbs_allowed_for_concurrency( 581 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode) 582 { 583 struct policy_mgr_psoc_priv_obj *pm_ctx; 584 uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p; 585 bool ret = true; 586 uint32_t ch_sel_plcy; 587 588 pm_ctx = policy_mgr_get_context(psoc); 589 if (!pm_ctx) { 590 policy_mgr_err("Invalid context"); 591 return ret; 592 } 593 594 count = policy_mgr_get_connection_count(psoc); 595 596 if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE) 597 return ret; 598 599 ch_sel_plcy = pm_ctx->cfg.chnl_select_plcy; 600 dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(ch_sel_plcy); 601 dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(ch_sel_plcy); 602 603 switch (pm_conc_connection_list[0].mode) { 604 case PM_STA_MODE: 605 switch (new_conn_mode) { 606 case QDF_STA_MODE: 607 if (!dbs_for_sta_sta) 608 return false; 609 break; 610 case QDF_P2P_DEVICE_MODE: 611 case QDF_P2P_CLIENT_MODE: 612 case QDF_P2P_GO_MODE: 613 if (!dbs_for_sta_p2p) 614 return false; 615 break; 616 default: 617 break; 618 } 619 break; 620 case PM_P2P_CLIENT_MODE: 621 case PM_P2P_GO_MODE: 622 switch (new_conn_mode) { 623 case QDF_STA_MODE: 624 if (!dbs_for_sta_p2p) 625 return false; 626 break; 627 default: 628 break; 629 } 630 break; 631 case PM_NAN_DISC_MODE: 632 switch (new_conn_mode) { 633 case QDF_STA_MODE: 634 case QDF_SAP_MODE: 635 case QDF_NDI_MODE: 636 return true; 637 default: 638 return false; 639 } 640 break; 641 default: 642 break; 643 } 644 645 return ret; 646 } 647 648 bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, 649 uint32_t ch_freq) 650 { 651 uint8_t i; 652 struct policy_mgr_psoc_priv_obj *pm_ctx; 653 654 pm_ctx = policy_mgr_get_context(psoc); 655 if (!pm_ctx) { 656 policy_mgr_err("Invalid Context"); 657 return false; 658 } 659 660 /* 661 * check given channel freq against already existing connections' 662 * channel freqs. if they differ then channels are in different bands 663 */ 664 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 665 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 666 if (pm_conc_connection_list[i].in_use) 667 if (!WLAN_REG_IS_SAME_BAND_FREQS( 668 ch_freq, pm_conc_connection_list[i].freq)) { 669 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 670 policy_mgr_debug("channel is in diff band"); 671 return true; 672 } 673 } 674 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 675 676 return false; 677 } 678 679 bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, 680 uint32_t ch_freq) 681 { 682 enum policy_mgr_band band; 683 bool is_hwmode_dbs, dbs_required_for_2g; 684 685 if (policy_mgr_is_hwmode_offload_enabled(psoc)) 686 return true; 687 688 if (policy_mgr_is_hw_dbs_capable(psoc) == false) 689 return true; 690 691 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) 692 band = POLICY_MGR_BAND_24; 693 else 694 band = POLICY_MGR_BAND_5; 695 696 is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc); 697 dbs_required_for_2g = policy_mgr_is_hw_dbs_required_for_band( 698 psoc, HW_MODE_MAC_BAND_2G); 699 /* 700 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not 701 * yet set then this is the right time to block the connection. 702 */ 703 if (band == POLICY_MGR_BAND_24 && dbs_required_for_2g && 704 !is_hwmode_dbs) { 705 policy_mgr_err("HW mode is not yet in DBS!!!!!"); 706 return false; 707 } 708 709 return true; 710 } 711 712 /** 713 * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to 714 * policy_mgr_con_mode 715 * @pri_id: policy_mgr_pri_id 716 * 717 * The help function converts policy_mgr_pri_id type to policy_mgr_con_mode 718 * type. 719 * 720 * Return: policy_mgr_con_mode type. 721 */ 722 static 723 enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode( 724 enum policy_mgr_pri_id pri_id) 725 { 726 switch (pri_id) { 727 case PM_STA_PRI_ID: 728 return PM_STA_MODE; 729 case PM_SAP_PRI_ID: 730 return PM_SAP_MODE; 731 case PM_P2P_GO_PRI_ID: 732 return PM_P2P_GO_MODE; 733 case PM_P2P_CLI_PRI_ID: 734 return PM_P2P_CLIENT_MODE; 735 default: 736 return PM_MAX_NUM_OF_MODE; 737 } 738 } 739 740 enum policy_mgr_conc_next_action 741 policy_mgr_get_preferred_dbs_action_table( 742 struct wlan_objmgr_psoc *psoc, 743 uint32_t vdev_id, 744 uint32_t ch_freq, 745 enum policy_mgr_conn_update_reason reason) 746 { 747 struct policy_mgr_psoc_priv_obj *pm_ctx; 748 enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE; 749 enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE; 750 enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE; 751 bool band_pref_5g = true; 752 bool vdev_priority_enabled = false; 753 bool dbs_2x2_5g_1x1_2g_supported; 754 bool dbs_2x2_2g_1x1_5g_supported; 755 uint32_t vdev_pri_list, vdev_pri_id; 756 uint32_t ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; 757 uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; 758 uint32_t vdev_count = 0; 759 uint32_t i; 760 bool found; 761 762 pm_ctx = policy_mgr_get_context(psoc); 763 if (!pm_ctx) { 764 policy_mgr_err("Invalid context"); 765 return PM_NOP; 766 } 767 dbs_2x2_5g_1x1_2g_supported = 768 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc); 769 dbs_2x2_2g_1x1_5g_supported = 770 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc); 771 policy_mgr_debug("target support DBS1 %d DBS2 %d", 772 dbs_2x2_5g_1x1_2g_supported, 773 dbs_2x2_2g_1x1_5g_supported); 774 /* 775 * If both DBS1 and DBS2 not supported, this should be Legacy Single 776 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct 777 * action tables. 778 */ 779 if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported) 780 return PM_NOP; 781 if (!dbs_2x2_5g_1x1_2g_supported) { 782 band_pref_5g = false; 783 policy_mgr_debug("target only supports DBS2!"); 784 goto DONE; 785 } 786 if (!dbs_2x2_2g_1x1_5g_supported) { 787 policy_mgr_debug("target only supports DBS1!"); 788 goto DONE; 789 } 790 if (PM_GET_BAND_PREFERRED(pm_ctx->cfg.dbs_selection_plcy) == 1) 791 band_pref_5g = false; 792 793 if (PM_GET_VDEV_PRIORITY_ENABLED( 794 pm_ctx->cfg.dbs_selection_plcy) == 1 && 795 pm_ctx->cfg.vdev_priority_list) 796 vdev_priority_enabled = true; 797 798 if (!vdev_priority_enabled) 799 goto DONE; 800 801 if (vdev_id != INVALID_VDEV_ID && ch_freq) { 802 if (pm_ctx->hdd_cbacks.hdd_get_device_mode) 803 new_conn_op_mode = pm_ctx->hdd_cbacks. 804 hdd_get_device_mode(vdev_id); 805 806 new_conn_mode = 807 policy_mgr_qdf_opmode_to_pm_con_mode(psoc, 808 new_conn_op_mode, 809 vdev_id); 810 if (new_conn_mode == PM_MAX_NUM_OF_MODE) 811 policy_mgr_debug("new vdev %d op_mode %d freq %d reason %d: not prioritized", 812 vdev_id, new_conn_op_mode, 813 ch_freq, reason); 814 else 815 policy_mgr_debug("new vdev %d op_mode %d freq %d : reason %d", 816 vdev_id, new_conn_op_mode, ch_freq, 817 reason); 818 } 819 vdev_pri_list = pm_ctx->cfg.vdev_priority_list; 820 while (vdev_pri_list) { 821 vdev_pri_id = vdev_pri_list & 0xF; 822 pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id); 823 if (pri_conn_mode == PM_MAX_NUM_OF_MODE) { 824 policy_mgr_debug("vdev_pri_id %d prioritization not supported", 825 vdev_pri_id); 826 goto NEXT; 827 } 828 vdev_count = policy_mgr_get_mode_specific_conn_info( 829 psoc, ch_freq_list, vdev_list, pri_conn_mode); 830 /** 831 * Take care of duplication case, the vdev id may 832 * exist in the conn list already with old chan. 833 * Replace with new chan before make decision. 834 */ 835 found = false; 836 for (i = 0; i < vdev_count; i++) { 837 policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d", 838 i, vdev_list[i], ch_freq_list[i], 839 pri_conn_mode); 840 841 if (new_conn_mode == pri_conn_mode && 842 vdev_list[i] == vdev_id) { 843 ch_freq_list[i] = ch_freq; 844 found = true; 845 } 846 } 847 /** 848 * The new coming vdev should be added to the list to 849 * make decision if it is prioritized. 850 */ 851 if (!found && new_conn_mode == pri_conn_mode) { 852 ch_freq_list[vdev_count] = ch_freq; 853 vdev_list[vdev_count++] = vdev_id; 854 } 855 /** 856 * if more than one vdev has same priority, keep "band_pref_5g" 857 * value as default band preference setting. 858 */ 859 if (vdev_count > 1) 860 break; 861 /** 862 * select the only active vdev (or new coming vdev) chan as 863 * preferred band. 864 */ 865 if (vdev_count > 0) { 866 band_pref_5g = 867 WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq_list[0]); 868 break; 869 } 870 NEXT: 871 vdev_pri_list >>= 4; 872 } 873 DONE: 874 policy_mgr_debug("band_pref_5g %d", band_pref_5g); 875 if (band_pref_5g) 876 return PM_DBS1; 877 else 878 return PM_DBS2; 879 } 880 881 /** 882 * policy_mgr_get_second_conn_action_table() - get second conn action table 883 * @psoc: Pointer to psoc 884 * @vdev_id: vdev Id 885 * @ch_freq: channel frequency of vdev. 886 * @reason: reason of request 887 * 888 * Get the action table based on current HW Caps and INI user preference. 889 * This function will be called by policy_mgr_current_connections_update during 890 * DBS action decision. 891 * 892 * return : action table address 893 */ 894 static policy_mgr_next_action_two_connection_table_type * 895 policy_mgr_get_second_conn_action_table( 896 struct wlan_objmgr_psoc *psoc, 897 uint32_t vdev_id, 898 uint32_t ch_freq, 899 enum policy_mgr_conn_update_reason reason) 900 { 901 enum policy_mgr_conc_next_action preferred_action; 902 903 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc)) 904 return next_action_two_connection_table; 905 906 preferred_action = policy_mgr_get_preferred_dbs_action_table( 907 psoc, vdev_id, ch_freq, reason); 908 switch (preferred_action) { 909 case PM_DBS2: 910 return next_action_two_connection_2x2_2g_1x1_5g_table; 911 default: 912 return next_action_two_connection_table; 913 } 914 } 915 916 /** 917 * policy_mgr_get_third_conn_action_table() - get third connection action table 918 * @psoc: Pointer to psoc 919 * @vdev_id: vdev Id 920 * @ch_freq: channel frequency of vdev. 921 * @reason: reason of request 922 * 923 * Get the action table based on current HW Caps and INI user preference. 924 * This function will be called by policy_mgr_current_connections_update during 925 * DBS action decision. 926 * 927 * return : action table address 928 */ 929 static policy_mgr_next_action_three_connection_table_type * 930 policy_mgr_get_third_conn_action_table( 931 struct wlan_objmgr_psoc *psoc, 932 uint32_t vdev_id, 933 uint32_t ch_freq, 934 enum policy_mgr_conn_update_reason reason) 935 { 936 enum policy_mgr_conc_next_action preferred_action; 937 938 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc)) 939 return next_action_three_connection_table; 940 941 preferred_action = policy_mgr_get_preferred_dbs_action_table( 942 psoc, vdev_id, ch_freq, reason); 943 switch (preferred_action) { 944 case PM_DBS2: 945 return next_action_three_connection_2x2_2g_1x1_5g_table; 946 default: 947 return next_action_three_connection_table; 948 } 949 } 950 951 bool 952 policy_mgr_is_conn_lead_to_dbs_sbs(struct wlan_objmgr_psoc *psoc, 953 uint32_t freq) 954 { 955 struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 956 uint32_t connection_count, i; 957 958 connection_count = policy_mgr_get_connection_info(psoc, info); 959 960 for (i = 0; i < connection_count; i++) 961 if (!policy_mgr_2_freq_always_on_same_mac(psoc, freq, 962 info[i].ch_freq)) 963 return true; 964 965 return false; 966 } 967 968 static QDF_STATUS 969 policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, 970 uint32_t session_id, 971 uint32_t ch_freq, 972 enum policy_mgr_conn_update_reason reason, 973 enum policy_mgr_conc_next_action *next_action) 974 { 975 uint32_t num_connections = 0; 976 enum policy_mgr_one_connection_mode second_index = 0; 977 enum policy_mgr_two_connection_mode third_index = 0; 978 policy_mgr_next_action_two_connection_table_type *second_conn_table; 979 policy_mgr_next_action_three_connection_table_type *third_conn_table; 980 enum policy_mgr_band band; 981 struct policy_mgr_psoc_priv_obj *pm_ctx; 982 enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE; 983 984 if (!next_action) { 985 policy_mgr_err("next_action is NULL"); 986 return QDF_STATUS_E_FAILURE; 987 } 988 989 if (policy_mgr_is_hwmode_offload_enabled(psoc)) { 990 *next_action = PM_NOP; 991 policy_mgr_get_sap_ch_width_update_action(psoc, ch_freq, 992 next_action, &reason); 993 return QDF_STATUS_SUCCESS; 994 } 995 996 pm_ctx = policy_mgr_get_context(psoc); 997 if (!pm_ctx) { 998 policy_mgr_err("Invalid context"); 999 return QDF_STATUS_E_FAILURE; 1000 } 1001 1002 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) 1003 band = POLICY_MGR_BAND_24; 1004 else 1005 band = POLICY_MGR_BAND_5; 1006 1007 num_connections = policy_mgr_get_connection_count(psoc); 1008 1009 policy_mgr_debug("num_connections=%d freq=%d", 1010 num_connections, ch_freq); 1011 1012 switch (num_connections) { 1013 case 0: 1014 if (band == POLICY_MGR_BAND_24) 1015 if (policy_mgr_is_hw_dbs_required_for_band( 1016 psoc, HW_MODE_MAC_BAND_2G)) 1017 *next_action = PM_DBS; 1018 else 1019 *next_action = PM_NOP; 1020 else 1021 *next_action = PM_NOP; 1022 break; 1023 case 1: 1024 second_index = 1025 policy_mgr_get_second_connection_pcl_table_index(psoc); 1026 if (PM_MAX_ONE_CONNECTION_MODE == second_index) { 1027 policy_mgr_err( 1028 "couldn't find index for 2nd connection next action table"); 1029 return QDF_STATUS_E_FAILURE; 1030 } 1031 second_conn_table = policy_mgr_get_second_conn_action_table( 1032 psoc, session_id, ch_freq, reason); 1033 *next_action = (*second_conn_table)[second_index][band]; 1034 break; 1035 case 2: 1036 third_index = 1037 policy_mgr_get_third_connection_pcl_table_index(psoc); 1038 if (PM_MAX_TWO_CONNECTION_MODE == third_index) { 1039 policy_mgr_err( 1040 "couldn't find index for 3rd connection next action table"); 1041 return QDF_STATUS_E_FAILURE; 1042 } 1043 third_conn_table = policy_mgr_get_third_conn_action_table( 1044 psoc, session_id, ch_freq, reason); 1045 *next_action = (*third_conn_table)[third_index][band]; 1046 break; 1047 default: 1048 policy_mgr_err("unexpected num_connections value %d", 1049 num_connections); 1050 break; 1051 } 1052 1053 /* 1054 * There is no adapter associated with NAN Discovery, hence skip the 1055 * HDD callback and fill separately. 1056 */ 1057 if (reason == POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY) 1058 new_conn_mode = QDF_NAN_DISC_MODE; 1059 else if (pm_ctx->hdd_cbacks.hdd_get_device_mode) 1060 new_conn_mode = pm_ctx->hdd_cbacks. 1061 hdd_get_device_mode(session_id); 1062 1063 /* 1064 * Based on channel_select_logic_conc ini, hw mode is set 1065 * when second connection is about to come up that results 1066 * in STA+STA and STA+P2P concurrency. 1067 * 1) If MCC is set and if current hw mode is dbs, hw mode 1068 * should be set to single mac for above concurrency. 1069 * 2) If MCC is set and if current hw mode is not dbs, hw 1070 * mode change is not required. 1071 */ 1072 if (policy_mgr_is_current_hwmode_dbs(psoc) && 1073 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode)) 1074 *next_action = PM_SINGLE_MAC; 1075 else if (!policy_mgr_is_current_hwmode_dbs(psoc) && 1076 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode)) 1077 *next_action = PM_NOP; 1078 1079 policy_mgr_debug("idx2=%d idx3=%d next_action=%d, band=%d reason=%d session_id=%d", 1080 second_index, third_index, *next_action, band, 1081 reason, session_id); 1082 1083 return QDF_STATUS_SUCCESS; 1084 } 1085 1086 static bool 1087 policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc *psoc, 1088 uint32_t ch_freq, uint8_t vdev_id) 1089 { 1090 if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) { 1091 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) 1092 return true; 1093 } else { 1094 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && 1095 policy_mgr_is_any_mode_active_on_band_along_with_session 1096 (psoc, vdev_id, POLICY_MGR_BAND_5)) 1097 return true; 1098 1099 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && 1100 policy_mgr_is_any_mode_active_on_band_along_with_session 1101 (psoc, vdev_id, POLICY_MGR_BAND_24)) 1102 return true; 1103 } 1104 1105 return false; 1106 } 1107 1108 static bool 1109 policy_mgr_is_ch_width_downgrade_required(struct wlan_objmgr_psoc *psoc, 1110 struct scan_cache_entry *entry, 1111 qdf_list_t *scan_list) 1112 1113 { 1114 if (policy_mgr_is_conn_lead_to_dbs_sbs(psoc, 1115 entry->channel.chan_freq) || 1116 wlan_cm_bss_mlo_type(psoc, entry, scan_list)) 1117 return true; 1118 1119 return false; 1120 } 1121 1122 static uint32_t 1123 policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc, 1124 qdf_list_t *scan_list, uint8_t vdev_id) 1125 { 1126 1127 struct scan_cache_node *scan_node = NULL; 1128 qdf_list_node_t *cur_node = NULL, *next_node = NULL; 1129 uint32_t ch_freq = 0; 1130 struct scan_cache_entry *entry; 1131 bool eht_capab = false, check_sap_bw_downgrade = false; 1132 enum phy_ch_width cur_bw = CH_WIDTH_INVALID; 1133 1134 if (policy_mgr_is_hwmode_offload_enabled(psoc)) { 1135 wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab); 1136 if (eht_capab && 1137 QDF_IS_STATUS_SUCCESS(policy_mgr_get_sap_bw(psoc, 1138 &cur_bw)) && 1139 cur_bw == CH_WIDTH_320MHZ) 1140 check_sap_bw_downgrade = true; 1141 else 1142 goto end; 1143 } 1144 1145 if (!scan_list || !qdf_list_size(scan_list)) { 1146 policy_mgr_debug("Scan list is NULL or No BSSIDs present"); 1147 goto end; 1148 } 1149 1150 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 1151 policy_mgr_debug("Driver isn't DBS capable"); 1152 goto end; 1153 } 1154 1155 if (check_sap_bw_downgrade) 1156 goto ch_width_update; 1157 1158 if (!policy_mgr_is_dbs_allowed_for_concurrency(psoc, QDF_STA_MODE)) { 1159 policy_mgr_debug("DBS not allowed for concurrency combo"); 1160 goto end; 1161 } 1162 1163 if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) && 1164 !policy_mgr_is_hw_dbs_required_for_band(psoc, 1165 HW_MODE_MAC_BAND_2G) && 1166 !policy_mgr_get_connection_count(psoc)) { 1167 policy_mgr_debug("1x1 DBS with no existing connection, HW mode change not required"); 1168 goto end; 1169 } 1170 1171 ch_width_update: 1172 qdf_list_peek_front(scan_list, &cur_node); 1173 1174 while (cur_node) { 1175 qdf_list_peek_next(scan_list, cur_node, &next_node); 1176 1177 scan_node = qdf_container_of(cur_node, struct scan_cache_node, 1178 node); 1179 entry = scan_node->entry; 1180 ch_freq = entry->channel.chan_freq; 1181 1182 if (policy_mgr_is_hw_mode_change_required(psoc, ch_freq, 1183 vdev_id) || 1184 policy_mgr_is_ch_width_downgrade_required(psoc, entry, 1185 scan_list)) { 1186 policy_mgr_debug("Scan list has BSS of freq %d hw mode/SAP ch_width:%d update required", 1187 ch_freq, cur_bw); 1188 break; 1189 } 1190 1191 ch_freq = 0; 1192 cur_node = next_node; 1193 next_node = NULL; 1194 } 1195 1196 end: 1197 return ch_freq; 1198 } 1199 1200 QDF_STATUS 1201 policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc, 1202 qdf_list_t *scan_list, uint8_t vdev_id, 1203 uint32_t connect_id) 1204 { 1205 QDF_STATUS status; 1206 uint32_t ch_freq; 1207 1208 ch_freq = policy_mgr_check_for_hw_mode_change(psoc, scan_list, vdev_id); 1209 1210 if (!ch_freq) 1211 return QDF_STATUS_E_ALREADY; 1212 1213 status = policy_mgr_current_connections_update(psoc, vdev_id, ch_freq, 1214 POLICY_MGR_UPDATE_REASON_STA_CONNECT, connect_id); 1215 1216 /* 1217 * If status is success then the callback of policy mgr hw mode change 1218 * would be called. 1219 * If status is no support then the DUT is already in required HW mode. 1220 */ 1221 1222 if (status == QDF_STATUS_E_FAILURE) 1223 policy_mgr_err("Hw mode change failed"); 1224 else if (status == QDF_STATUS_E_NOSUPPORT) 1225 status = QDF_STATUS_E_ALREADY; 1226 1227 return status; 1228 } 1229 1230 QDF_STATUS 1231 policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, 1232 uint32_t session_id, uint32_t ch_freq, 1233 enum policy_mgr_conn_update_reason 1234 reason, uint32_t request_id) 1235 { 1236 enum policy_mgr_conc_next_action next_action = PM_NOP; 1237 QDF_STATUS status; 1238 1239 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 1240 policy_mgr_rl_debug("driver isn't dbs capable, no further action needed"); 1241 return QDF_STATUS_E_NOSUPPORT; 1242 } 1243 1244 status = policy_mgr_get_next_action(psoc, session_id, ch_freq, reason, 1245 &next_action); 1246 if (QDF_IS_STATUS_ERROR(status)) 1247 return status; 1248 1249 if (PM_NOP != next_action) 1250 status = policy_mgr_next_actions(psoc, session_id, 1251 next_action, reason, 1252 request_id); 1253 else 1254 status = QDF_STATUS_E_NOSUPPORT; 1255 1256 policy_mgr_debug("next_action %d reason=%d session_id=%d request_id %x", 1257 next_action, reason, session_id, request_id); 1258 1259 return status; 1260 } 1261 1262 /** 1263 * policy_mgr_dbs1_dbs2_need_action() - whether more actions are needed 1264 * in DBS1 and DBS2 hw mode 1265 * @psoc: psoc object 1266 * @action: action type 1267 * @hw_mode: hardware mode 1268 * 1269 * The function checks further action are needed or not for DBS1 and DBS2. 1270 * 1271 * Return: true if more action are needed, otherwise 1272 * return false 1273 */ 1274 static bool 1275 policy_mgr_dbs1_dbs2_need_action(struct wlan_objmgr_psoc *psoc, 1276 enum policy_mgr_conc_next_action action, 1277 struct policy_mgr_hw_mode_params *hw_mode) 1278 { 1279 if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) || 1280 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) { 1281 policy_mgr_debug("curr dbs action %d new action %d", 1282 hw_mode->action_type, action); 1283 if (hw_mode->action_type == PM_DBS1 && 1284 ((action == PM_DBS1 || 1285 action == PM_DBS1_DOWNGRADE))) { 1286 policy_mgr_debug("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed", 1287 hw_mode->action_type, action); 1288 return false; 1289 } else if (hw_mode->action_type == PM_DBS2 && 1290 ((action == PM_DBS2 || 1291 action == PM_DBS2_DOWNGRADE))) { 1292 policy_mgr_debug("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed", 1293 hw_mode->action_type, action); 1294 return false; 1295 } 1296 } 1297 1298 return true; 1299 } 1300 1301 QDF_STATUS 1302 policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc, 1303 enum policy_mgr_conc_next_action action) 1304 { 1305 QDF_STATUS status; 1306 struct policy_mgr_hw_mode_params hw_mode; 1307 1308 /* check for the current HW index to see if really need any action */ 1309 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); 1310 if (!QDF_IS_STATUS_SUCCESS(status)) { 1311 policy_mgr_err("policy_mgr_get_current_hw_mode failed"); 1312 return status; 1313 } 1314 1315 if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) { 1316 if (!policy_mgr_is_hw_sbs_capable(psoc)) { 1317 /* No action */ 1318 policy_mgr_notice("firmware is not sbs capable"); 1319 return QDF_STATUS_E_NOSUPPORT; 1320 } 1321 /* current mode is already SBS nothing to be 1322 * done 1323 */ 1324 if (hw_mode.sbs_cap) { 1325 policy_mgr_notice("current mode is already SBS"); 1326 return QDF_STATUS_E_ALREADY; 1327 } 1328 return QDF_STATUS_SUCCESS; 1329 } 1330 1331 if (!hw_mode.dbs_cap) { 1332 if (action == PM_SINGLE_MAC || 1333 action == PM_SINGLE_MAC_UPGRADE) { 1334 policy_mgr_notice("current mode is already single MAC"); 1335 return QDF_STATUS_E_ALREADY; 1336 } else { 1337 return QDF_STATUS_SUCCESS; 1338 } 1339 } 1340 /** 1341 * If already in DBS, no need to request DBS again (HL, Napier). 1342 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1 1343 * switching, we need to check the current DBS mode is same as 1344 * requested or not. 1345 */ 1346 if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) || 1347 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) { 1348 if (!policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) 1349 return QDF_STATUS_E_ALREADY; 1350 } else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) || 1351 (action == PM_DBS_UPGRADE)) { 1352 policy_mgr_debug("driver is already in %s mode, no further action needed", 1353 (hw_mode.dbs_cap) ? "dbs" : "non dbs"); 1354 return QDF_STATUS_E_ALREADY; 1355 } 1356 return QDF_STATUS_SUCCESS; 1357 } 1358 1359 /** 1360 * policy_mgr_validate_unsupported_action() - unsupported action validation 1361 * @psoc: psoc object 1362 * @action: action type 1363 * 1364 * The help function checks the Action supported by HW or not. 1365 * 1366 * Return: QDF_STATUS_SUCCESS if supported by HW, otherwise 1367 * return QDF_STATUS_E_NOSUPPORT 1368 */ 1369 static QDF_STATUS policy_mgr_validate_unsupported_action 1370 (struct wlan_objmgr_psoc *psoc, 1371 enum policy_mgr_conc_next_action action) 1372 { 1373 if (action == PM_SBS || action == PM_SBS_DOWNGRADE) { 1374 if (!policy_mgr_is_hw_sbs_capable(psoc)) { 1375 /* No action */ 1376 policy_mgr_notice("firmware is not sbs capable"); 1377 return QDF_STATUS_E_NOSUPPORT; 1378 } 1379 } 1380 1381 return QDF_STATUS_SUCCESS; 1382 } 1383 1384 QDF_STATUS policy_mgr_next_actions( 1385 struct wlan_objmgr_psoc *psoc, 1386 uint32_t session_id, 1387 enum policy_mgr_conc_next_action action, 1388 enum policy_mgr_conn_update_reason reason, 1389 uint32_t request_id) 1390 { 1391 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1392 struct dbs_nss nss_dbs = {0}; 1393 struct dbs_bw bw_dbs = {0}; 1394 struct policy_mgr_hw_mode_params hw_mode; 1395 enum policy_mgr_conc_next_action next_action; 1396 bool is_sbs_supported; 1397 enum hw_mode_sbs_capab sbs_capab; 1398 1399 if (policy_mgr_is_hw_dbs_capable(psoc) == false) { 1400 policy_mgr_rl_debug("driver isn't dbs capable, no further action needed"); 1401 return QDF_STATUS_E_NOSUPPORT; 1402 } 1403 status = policy_mgr_validate_unsupported_action(psoc, action); 1404 if (!QDF_IS_STATUS_SUCCESS(status)) 1405 return status; 1406 /* check for the current HW index to see if really need any action */ 1407 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); 1408 if (!QDF_IS_STATUS_SUCCESS(status)) { 1409 policy_mgr_err("policy_mgr_get_current_hw_mode failed"); 1410 return status; 1411 } 1412 1413 switch (action) { 1414 case PM_DBS_DOWNGRADE: 1415 /* 1416 * check if we have a beaconing entity that is using 2x2. If yes, 1417 * update the beacon template & notify FW. Once FW confirms 1418 * beacon updated, send down the HW mode change req 1419 */ 1420 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, 1421 PM_DBS, reason, session_id, request_id); 1422 break; 1423 case PM_DBS: 1424 (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); 1425 policy_mgr_get_hw_dbs_max_bw(psoc, &bw_dbs); 1426 is_sbs_supported = policy_mgr_is_hw_sbs_capable(psoc); 1427 sbs_capab = is_sbs_supported ? HW_MODE_SBS : HW_MODE_SBS_NONE; 1428 status = policy_mgr_pdev_set_hw_mode(psoc, session_id, 1429 nss_dbs.mac0_ss, 1430 bw_dbs.mac0_bw, 1431 nss_dbs.mac1_ss, 1432 bw_dbs.mac1_bw, 1433 HW_MODE_MAC_BAND_NONE, 1434 HW_MODE_DBS, 1435 HW_MODE_AGILE_DFS_NONE, 1436 sbs_capab, 1437 reason, PM_NOP, PM_DBS, 1438 request_id); 1439 break; 1440 case PM_SINGLE_MAC_UPGRADE: 1441 /* 1442 * change the HW mode first before the NSS upgrade 1443 */ 1444 status = policy_mgr_pdev_set_hw_mode(psoc, session_id, 1445 HW_MODE_SS_2x2, 1446 HW_MODE_80_MHZ, 1447 HW_MODE_SS_0x0, HW_MODE_BW_NONE, 1448 HW_MODE_MAC_BAND_NONE, 1449 HW_MODE_DBS_NONE, 1450 HW_MODE_AGILE_DFS_NONE, 1451 HW_MODE_SBS_NONE, 1452 reason, PM_UPGRADE, 1453 PM_SINGLE_MAC_UPGRADE, 1454 request_id); 1455 break; 1456 case PM_SINGLE_MAC: 1457 status = policy_mgr_pdev_set_hw_mode(psoc, session_id, 1458 HW_MODE_SS_2x2, 1459 HW_MODE_80_MHZ, 1460 HW_MODE_SS_0x0, HW_MODE_BW_NONE, 1461 HW_MODE_MAC_BAND_NONE, 1462 HW_MODE_DBS_NONE, 1463 HW_MODE_AGILE_DFS_NONE, 1464 HW_MODE_SBS_NONE, 1465 reason, PM_NOP, PM_SINGLE_MAC, 1466 request_id); 1467 break; 1468 case PM_DBS_UPGRADE: 1469 status = policy_mgr_pdev_set_hw_mode(psoc, session_id, 1470 HW_MODE_SS_2x2, 1471 HW_MODE_80_MHZ, 1472 HW_MODE_SS_2x2, HW_MODE_80_MHZ, 1473 HW_MODE_MAC_BAND_NONE, 1474 HW_MODE_DBS, 1475 HW_MODE_AGILE_DFS_NONE, 1476 HW_MODE_SBS_NONE, 1477 reason, PM_UPGRADE, 1478 PM_DBS_UPGRADE, request_id); 1479 break; 1480 case PM_SBS_DOWNGRADE: 1481 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, 1482 PM_SBS, reason, session_id, request_id); 1483 break; 1484 case PM_SBS: 1485 status = policy_mgr_pdev_set_hw_mode(psoc, session_id, 1486 HW_MODE_SS_1x1, 1487 HW_MODE_80_MHZ, 1488 HW_MODE_SS_1x1, HW_MODE_80_MHZ, 1489 HW_MODE_MAC_BAND_NONE, 1490 HW_MODE_DBS, 1491 HW_MODE_AGILE_DFS_NONE, 1492 HW_MODE_SBS, 1493 reason, PM_NOP, PM_SBS, 1494 request_id); 1495 break; 1496 case PM_DOWNGRADE: 1497 /* 1498 * check if we have a beaconing entity that advertised 2x2 1499 * initially. If yes, update the beacon template & notify FW. 1500 */ 1501 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1, 1502 PM_NOP, POLICY_MGR_ANY, reason, 1503 session_id, request_id); 1504 break; 1505 case PM_UPGRADE: 1506 /* 1507 * check if we have a beaconing entity that advertised 2x2 1508 * initially. If yes, update the beacon template & notify FW. 1509 */ 1510 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2, 1511 PM_NOP, POLICY_MGR_ANY, reason, 1512 session_id, request_id); 1513 break; 1514 case PM_DBS1_DOWNGRADE: 1515 if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) 1516 status = policy_mgr_complete_action(psoc, 1517 POLICY_MGR_RX_NSS_1, 1518 PM_DBS1, reason, 1519 session_id, 1520 request_id); 1521 else 1522 status = QDF_STATUS_E_ALREADY; 1523 break; 1524 case PM_DBS2_DOWNGRADE: 1525 if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) 1526 status = policy_mgr_complete_action(psoc, 1527 POLICY_MGR_RX_NSS_1, 1528 PM_DBS2, reason, 1529 session_id, 1530 request_id); 1531 else 1532 status = QDF_STATUS_E_ALREADY; 1533 break; 1534 case PM_DBS1: 1535 /* 1536 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous 1537 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and 1538 * the 5G band was downgraded to 1x1. So, we need to 1539 * upgrade 5G vdevs after hw mode change. 1540 */ 1541 if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) { 1542 if (hw_mode.dbs_cap) 1543 next_action = PM_UPGRADE_5G; 1544 else 1545 next_action = PM_NOP; 1546 status = policy_mgr_pdev_set_hw_mode( 1547 psoc, session_id, 1548 HW_MODE_SS_2x2, 1549 HW_MODE_80_MHZ, 1550 HW_MODE_SS_1x1, HW_MODE_40_MHZ, 1551 HW_MODE_MAC_BAND_5G, 1552 HW_MODE_DBS, 1553 HW_MODE_AGILE_DFS_NONE, 1554 HW_MODE_SBS_NONE, 1555 reason, next_action, PM_DBS1, 1556 request_id); 1557 } else { 1558 status = QDF_STATUS_E_ALREADY; 1559 } 1560 break; 1561 case PM_DBS2: 1562 /* 1563 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous 1564 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and 1565 * the 2G band was downgraded to 1x1. So, we need to 1566 * upgrade 5G vdevs after hw mode change. 1567 */ 1568 if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) { 1569 if (hw_mode.dbs_cap) 1570 next_action = PM_UPGRADE_2G; 1571 else 1572 next_action = PM_NOP; 1573 status = policy_mgr_pdev_set_hw_mode( 1574 psoc, session_id, 1575 HW_MODE_SS_2x2, 1576 HW_MODE_40_MHZ, 1577 HW_MODE_SS_1x1, HW_MODE_40_MHZ, 1578 HW_MODE_MAC_BAND_2G, 1579 HW_MODE_DBS, 1580 HW_MODE_AGILE_DFS_NONE, 1581 HW_MODE_SBS_NONE, 1582 reason, next_action, PM_DBS2, 1583 request_id); 1584 } else { 1585 status = QDF_STATUS_E_ALREADY; 1586 } 1587 break; 1588 case PM_UPGRADE_5G: 1589 status = policy_mgr_nss_update( 1590 psoc, POLICY_MGR_RX_NSS_2, 1591 PM_NOP, POLICY_MGR_BAND_5, reason, 1592 session_id, request_id); 1593 break; 1594 case PM_UPGRADE_2G: 1595 status = policy_mgr_nss_update( 1596 psoc, POLICY_MGR_RX_NSS_2, 1597 PM_NOP, POLICY_MGR_BAND_24, reason, 1598 session_id, request_id); 1599 break; 1600 case PM_DOWNGRADE_BW: 1601 case PM_UPGRADE_BW: 1602 policy_mgr_sap_ch_width_update(psoc, action, reason, 1603 session_id, request_id); 1604 break; 1605 default: 1606 policy_mgr_err("unexpected action value %d", action); 1607 status = QDF_STATUS_E_FAILURE; 1608 break; 1609 } 1610 1611 return status; 1612 } 1613 1614 QDF_STATUS 1615 policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, 1616 uint8_t vdev_id, uint32_t ch_freq, 1617 enum policy_mgr_conn_update_reason reason, 1618 uint32_t request_id) 1619 { 1620 QDF_STATUS status; 1621 uint8_t num_cxn_del = 0; 1622 struct policy_mgr_conc_connection_info info = {0}; 1623 1624 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, 1625 &info, &num_cxn_del); 1626 1627 if (!policy_mgr_check_for_session_conc(psoc, vdev_id, ch_freq)) { 1628 policy_mgr_err("Conc not allowed for the vdev %d", vdev_id); 1629 return QDF_STATUS_E_FAILURE; 1630 } 1631 1632 status = policy_mgr_reset_connection_update(psoc); 1633 if (!QDF_IS_STATUS_SUCCESS(status)) 1634 policy_mgr_err("clearing event failed"); 1635 1636 status = policy_mgr_current_connections_update(psoc, vdev_id, 1637 ch_freq, reason, 1638 request_id); 1639 if (QDF_STATUS_E_FAILURE == status) 1640 policy_mgr_err("connections update failed"); 1641 1642 if (num_cxn_del > 0) 1643 policy_mgr_restore_deleted_conn_info(psoc, &info, 1644 num_cxn_del); 1645 1646 return status; 1647 } 1648 1649 enum policy_mgr_con_mode 1650 policy_mgr_con_mode_by_vdev_id(struct wlan_objmgr_psoc *psoc, 1651 uint8_t vdev_id) 1652 { 1653 struct policy_mgr_psoc_priv_obj *pm_ctx; 1654 enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE; 1655 enum QDF_OPMODE op_mode; 1656 1657 pm_ctx = policy_mgr_get_context(psoc); 1658 if (!pm_ctx) { 1659 policy_mgr_err("Invalid Context"); 1660 return mode; 1661 } 1662 1663 op_mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 1664 return policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id); 1665 } 1666 1667 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 1668 qdf_freq_t 1669 policy_mgr_get_user_config_sap_freq(struct wlan_objmgr_psoc *psoc, 1670 uint8_t vdev_id) 1671 { 1672 struct wlan_objmgr_vdev *vdev; 1673 qdf_freq_t freq; 1674 1675 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1676 WLAN_POLICY_MGR_ID); 1677 if (!vdev) { 1678 policy_mgr_err("vdev is NULL"); 1679 return 0; 1680 } 1681 freq = wlan_get_sap_user_config_freq(vdev); 1682 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 1683 1684 return freq; 1685 } 1686 1687 /** 1688 * policy_mgr_is_sap_go_existed() - Check if restart SAP/Go exist 1689 * @psoc: PSOC object data 1690 * 1691 * To simplify, if SAP/P2P Go exist, they may need switch channel for 1692 * forcing scc with sta or band capability change. 1693 * Restart: true or false 1694 */ 1695 static bool policy_mgr_is_sap_go_existed(struct wlan_objmgr_psoc *psoc) 1696 { 1697 uint32_t ap_present, go_present; 1698 1699 ap_present = policy_mgr_get_sap_mode_count(psoc, NULL); 1700 if (ap_present) 1701 return true; 1702 1703 go_present = policy_mgr_mode_specific_connection_count( 1704 psoc, PM_P2P_GO_MODE, NULL); 1705 if (go_present) 1706 return true; 1707 1708 return false; 1709 } 1710 1711 #ifdef FEATURE_WLAN_CH_AVOID_EXT 1712 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, 1713 uint32_t ch_freq) 1714 { 1715 struct policy_mgr_psoc_priv_obj *pm_ctx; 1716 bool is_safe = true; 1717 uint8_t j; 1718 unsigned long restriction_mask; 1719 1720 pm_ctx = policy_mgr_get_context(psoc); 1721 if (!pm_ctx) { 1722 policy_mgr_err("Invalid context"); 1723 return is_safe; 1724 } 1725 1726 if (pm_ctx->unsafe_channel_count == 0) 1727 return is_safe; 1728 1729 restriction_mask = 1730 (unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx); 1731 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) { 1732 if ((ch_freq == pm_ctx->unsafe_channel_list[j]) && 1733 (qdf_test_bit(QDF_SAP_MODE, &restriction_mask) || 1734 !wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(psoc))) { 1735 is_safe = false; 1736 policy_mgr_warn("Freq %d is not safe, restriction mask %lu", ch_freq, restriction_mask); 1737 break; 1738 } 1739 } 1740 1741 return is_safe; 1742 } 1743 1744 bool policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc) 1745 { 1746 struct policy_mgr_psoc_priv_obj *pm_ctx; 1747 unsigned long restriction_mask; 1748 1749 pm_ctx = policy_mgr_get_context(psoc); 1750 if (!pm_ctx) { 1751 policy_mgr_err("Invalid context"); 1752 return false; 1753 } 1754 1755 restriction_mask = 1756 (unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx); 1757 return qdf_test_bit(QDF_SAP_MODE, &restriction_mask); 1758 } 1759 #else 1760 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, 1761 uint32_t ch_freq) 1762 { 1763 struct policy_mgr_psoc_priv_obj *pm_ctx; 1764 bool is_safe = true; 1765 uint8_t j; 1766 1767 pm_ctx = policy_mgr_get_context(psoc); 1768 if (!pm_ctx) { 1769 policy_mgr_err("Invalid context"); 1770 return is_safe; 1771 } 1772 1773 if (pm_ctx->unsafe_channel_count == 0) 1774 return is_safe; 1775 1776 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) { 1777 if (ch_freq == pm_ctx->unsafe_channel_list[j]) { 1778 is_safe = false; 1779 policy_mgr_warn("Freq %d is not safe", ch_freq); 1780 break; 1781 } 1782 } 1783 1784 return is_safe; 1785 } 1786 #endif 1787 1788 bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc, 1789 uint32_t sap_freq) 1790 { 1791 uint32_t nan_2g_freq, nan_5g_freq; 1792 1793 if (policy_mgr_is_safe_channel(psoc, sap_freq)) 1794 return true; 1795 1796 /* 1797 * Return true if it's STA+SAP SCC and 1798 * STA+SAP SCC on LTE coex channel is allowed. 1799 */ 1800 if (policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) && 1801 policy_mgr_is_sta_sap_scc(psoc, sap_freq)) { 1802 policy_mgr_debug("unsafe freq %d for sap is allowed", sap_freq); 1803 return true; 1804 } 1805 1806 nan_2g_freq = 1807 policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE); 1808 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc); 1809 1810 if ((WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq) || 1811 WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) && 1812 policy_mgr_is_force_scc(psoc) && 1813 policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc)) { 1814 policy_mgr_debug("NAN+SAP SCC on unsafe freq %d is allowed", 1815 sap_freq); 1816 return true; 1817 } 1818 1819 return false; 1820 } 1821 1822 bool policy_mgr_is_sap_restart_required_after_sta_disconnect( 1823 struct wlan_objmgr_psoc *psoc, 1824 uint32_t sap_vdev_id, uint32_t *intf_ch_freq, 1825 bool is_acs_mode) 1826 { 1827 struct policy_mgr_psoc_priv_obj *pm_ctx; 1828 uint32_t curr_sap_freq = 0, new_sap_freq = 0; 1829 bool sta_sap_scc_on_dfs_chan = 1830 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 1831 bool sta_sap_scc_on_lte_coex_chan = 1832 policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc); 1833 uint8_t sta_sap_scc_on_dfs_chnl_config_value = 0; 1834 uint32_t cc_count, i, go_index_start, pcl_len = 0; 1835 uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS * 2]; 1836 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2]; 1837 enum policy_mgr_con_mode mode; 1838 uint32_t pcl_channels[NUM_CHANNELS + 1]; 1839 uint8_t pcl_weight[NUM_CHANNELS + 1]; 1840 struct policy_mgr_conc_connection_info info = {0}; 1841 uint8_t num_cxn_del = 0; 1842 QDF_STATUS status; 1843 uint32_t sta_gc_present = 0; 1844 bool go_5g_present = 0; 1845 qdf_freq_t user_config_freq = 0; 1846 tQDF_MCC_TO_SCC_SWITCH_MODE cc_mode = 1847 policy_mgr_get_mcc_to_scc_switch_mode(psoc); 1848 1849 if (intf_ch_freq) 1850 *intf_ch_freq = 0; 1851 1852 pm_ctx = policy_mgr_get_context(psoc); 1853 if (!pm_ctx) { 1854 policy_mgr_err("Invalid pm context"); 1855 return false; 1856 } 1857 1858 policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value); 1859 1860 if (!policy_mgr_is_hw_dbs_capable(psoc)) 1861 if (policy_mgr_get_connection_count(psoc) > 1) 1862 return false; 1863 1864 cc_count = policy_mgr_get_mode_specific_conn_info(psoc, 1865 &op_ch_freq_list[0], 1866 &vdev_id[0], 1867 PM_SAP_MODE); 1868 go_index_start = cc_count; 1869 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) 1870 cc_count += policy_mgr_get_mode_specific_conn_info( 1871 psoc, &op_ch_freq_list[cc_count], 1872 &vdev_id[cc_count], PM_P2P_GO_MODE); 1873 1874 for (i = go_index_start ; i < cc_count; i++) { 1875 if (!WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i])) { 1876 go_5g_present = true; 1877 break; 1878 } 1879 } 1880 1881 sta_gc_present = 1882 policy_mgr_mode_specific_connection_count(psoc, 1883 PM_STA_MODE, NULL) + 1884 policy_mgr_mode_specific_connection_count(psoc, 1885 PM_P2P_CLIENT_MODE, 1886 NULL); 1887 1888 for (i = 0 ; i < cc_count; i++) { 1889 if (sap_vdev_id != INVALID_VDEV_ID && 1890 sap_vdev_id != vdev_id[i]) 1891 continue; 1892 1893 sap_vdev_id = vdev_id[i]; 1894 user_config_freq = 1895 policy_mgr_get_user_config_sap_freq(psoc, sap_vdev_id); 1896 1897 if (policy_mgr_is_any_mode_active_on_band_along_with_session( 1898 psoc, vdev_id[i], 1899 WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) ? 1900 POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5)) 1901 continue; 1902 1903 if (sta_sap_scc_on_dfs_chan && 1904 (sta_sap_scc_on_dfs_chnl_config_value != 2) && 1905 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, 1906 op_ch_freq_list[i]) && 1907 pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) { 1908 curr_sap_freq = op_ch_freq_list[i]; 1909 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, dfs sap_ch_freq %u", 1910 sta_sap_scc_on_dfs_chan, 1911 sta_sap_scc_on_dfs_chnl_config_value, 1912 curr_sap_freq); 1913 break; 1914 } 1915 1916 if ((is_acs_mode || 1917 policy_mgr_restrict_sap_on_unsafe_chan(psoc)) && 1918 sta_sap_scc_on_lte_coex_chan && 1919 !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i]) && 1920 pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) { 1921 curr_sap_freq = op_ch_freq_list[i]; 1922 policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_ch_freq %u", 1923 sta_sap_scc_on_lte_coex_chan, 1924 curr_sap_freq); 1925 break; 1926 } 1927 /* When STA+SAP SCC is allowed on indoor channel, 1928 * Restart the SAP when : 1929 * 1. The user configured SAP frequency is not 1930 * the same as current freq. (or) 1931 * 2. The frequency is not allowed in the indoor 1932 * channel. 1933 */ 1934 if (pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i] && 1935 !policy_mgr_is_sap_go_interface_allowed_on_indoor( 1936 pm_ctx->pdev, 1937 sap_vdev_id, 1938 op_ch_freq_list[i])) { 1939 curr_sap_freq = op_ch_freq_list[i]; 1940 policy_mgr_debug("indoor sap_ch_freq %u", 1941 curr_sap_freq); 1942 break; 1943 } 1944 1945 /* 1946 * STA got disconnected & SAP has previously moved to 2.4 GHz 1947 * due to concurrency, then move SAP back to user configured 1948 * frequency. 1949 * if SCC to MCC switch mode is 1950 * QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL, then move SAP to 1951 * user configured frequency whenever standalone SAP is 1952 * currently not on the user configured frequency. 1953 * else move the SAP only when SAP is on 2.4 GHz band and user 1954 * configured frequency is on any other bands. 1955 * And for QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL, if GO 1956 * is on 5/6 GHz, SAP is not allowed to move back to 5/6 GHz. 1957 * If GO is not present on 5/6 GHz, SAP need to moved to 1958 * user configured frequency. 1959 */ 1960 if (!sta_gc_present && user_config_freq && 1961 cc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL && 1962 !wlan_reg_is_same_band_freqs(user_config_freq, 1963 op_ch_freq_list[i])) { 1964 if (go_5g_present && 1965 !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) 1966 continue; 1967 curr_sap_freq = op_ch_freq_list[i]; 1968 policy_mgr_debug("Move sap to user configured freq: %d", 1969 user_config_freq); 1970 break; 1971 } else if (!sta_gc_present && user_config_freq && 1972 WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) && 1973 !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) { 1974 curr_sap_freq = op_ch_freq_list[i]; 1975 policy_mgr_debug("Move sap to user configured freq: %d", 1976 user_config_freq); 1977 break; 1978 } 1979 } 1980 1981 if (!curr_sap_freq) { 1982 policy_mgr_debug("SAP restart is not required"); 1983 return false; 1984 } 1985 1986 mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE; 1987 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1988 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, 1989 &info, &num_cxn_del); 1990 1991 /* Add the user config ch as first condidate */ 1992 pcl_channels[0] = user_config_freq; 1993 pcl_weight[0] = 0; 1994 status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len, 1995 &pcl_weight[1], 1996 QDF_ARRAY_SIZE(pcl_weight) - 1, 1997 sap_vdev_id); 1998 if (status == QDF_STATUS_SUCCESS) 1999 pcl_len++; 2000 else 2001 pcl_len = 1; 2002 2003 2004 for (i = 0; i < pcl_len; i++) { 2005 if (pcl_channels[i] == curr_sap_freq) 2006 continue; 2007 2008 if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) || 2009 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i])) 2010 continue; 2011 2012 /* SAP moved to 2.4 GHz, due to STA on DFS or Indoor where 2013 * concurrency is not allowed, now that there is no 2014 * STA/GC in 5 GHz band, move 2.4 GHz SAP to 5 GHz band if SAP 2015 * was initially started on 5 GHz band. 2016 * Checking again here as pcl_channels[0] could be 2017 * on indoor which is not removed in policy_mgr_get_pcl 2018 */ 2019 if (!sta_gc_present && 2020 !policy_mgr_is_sap_go_interface_allowed_on_indoor( 2021 pm_ctx->pdev, 2022 sap_vdev_id, 2023 pcl_channels[i])) { 2024 policy_mgr_debug("Do not allow SAP on indoor frequency, STA is absent"); 2025 continue; 2026 } 2027 2028 new_sap_freq = pcl_channels[i]; 2029 break; 2030 } 2031 2032 /* Restore the connection entry */ 2033 if (num_cxn_del > 0) 2034 policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); 2035 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2036 2037 if (new_sap_freq == 0 || curr_sap_freq == new_sap_freq) 2038 return false; 2039 if (!intf_ch_freq) 2040 return true; 2041 2042 *intf_ch_freq = new_sap_freq; 2043 policy_mgr_debug("Standalone SAP(vdev_id %d) will be moved to channel %u", 2044 sap_vdev_id, *intf_ch_freq); 2045 2046 return true; 2047 } 2048 2049 /** 2050 * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is 2051 * allowed in LTE COEX unsafe ch 2052 * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context 2053 * @ch_freq: Channel frequency to check 2054 * 2055 * Return: True if allowed else false 2056 */ 2057 static bool 2058 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj 2059 *pm_ctx, uint32_t ch_freq) 2060 { 2061 if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch_freq) || 2062 pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl) 2063 return true; 2064 2065 return false; 2066 } 2067 2068 /** 2069 * policy_mgr_nan_disable_work() - qdf defer function wrapper for NAN disable 2070 * @data: qdf_work data 2071 * 2072 * Return: None 2073 */ 2074 static void policy_mgr_nan_disable_work(void *data) 2075 { 2076 struct wlan_objmgr_psoc *psoc = data; 2077 2078 ucfg_nan_disable_concurrency(psoc); 2079 } 2080 2081 bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, 2082 uint32_t sap_freq) 2083 { 2084 uint32_t nan_2g_freq, nan_5g_freq; 2085 struct policy_mgr_psoc_priv_obj *pm_ctx; 2086 2087 pm_ctx = policy_mgr_get_context(psoc); 2088 if (!pm_ctx) { 2089 policy_mgr_err("Invalid Context"); 2090 return false; 2091 } 2092 2093 nan_2g_freq = policy_mgr_mode_specific_get_channel(psoc, 2094 PM_NAN_DISC_MODE); 2095 if (nan_2g_freq == 0) { 2096 policy_mgr_debug("No NAN+SAP SCC"); 2097 return false; 2098 } 2099 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc); 2100 2101 policy_mgr_debug("Freq SAP: %d NAN: %d %d", sap_freq, 2102 nan_2g_freq, nan_5g_freq); 2103 if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq)) { 2104 if (policy_mgr_is_force_scc(pm_ctx->psoc) && 2105 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, 2106 nan_2g_freq)) 2107 return true; 2108 } else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) { 2109 if (policy_mgr_is_force_scc(pm_ctx->psoc) && 2110 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, 2111 nan_5g_freq)) 2112 return true; 2113 } else { 2114 /* 2115 * NAN + SAP in different bands. Continue to check for 2116 * SAP in unsafe channel 2117 */ 2118 return false; 2119 } 2120 policy_mgr_info("NAN+SAP unsafe ch SCC not allowed. Disabling NAN"); 2121 /* change context to worker since this is executed in sched thread ctx*/ 2122 qdf_create_work(0, &pm_ctx->nan_sap_conc_work, 2123 policy_mgr_nan_disable_work, psoc); 2124 qdf_sched_work(0, &pm_ctx->nan_sap_conc_work); 2125 2126 return false; 2127 } 2128 2129 bool 2130 policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, 2131 enum policy_mgr_con_mode mode, 2132 uint32_t ch_freq) 2133 { 2134 struct policy_mgr_psoc_priv_obj *pm_ctx; 2135 uint32_t sap_freq, nan_2g_freq, nan_5g_freq; 2136 2137 pm_ctx = policy_mgr_get_context(psoc); 2138 if (!pm_ctx) { 2139 policy_mgr_err("Invalid Context"); 2140 return false; 2141 } 2142 2143 if (!policy_mgr_is_sap_mode(mode) || mode == PM_NAN_DISC_MODE) { 2144 policy_mgr_debug("Not NAN or SAP mode"); 2145 return true; 2146 } 2147 2148 if (!ch_freq) { 2149 policy_mgr_err("Invalid channel"); 2150 return false; 2151 } 2152 2153 if (!wlan_nan_get_sap_conc_support(pm_ctx->psoc)) { 2154 policy_mgr_debug("NAN+SAP not supported in fw"); 2155 /* Reject NAN as SAP is of high priority */ 2156 if (mode == PM_NAN_DISC_MODE) 2157 return false; 2158 /* Before SAP start disable NAN */ 2159 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2160 return true; 2161 } 2162 2163 if (mode == PM_NAN_DISC_MODE) { 2164 sap_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc, 2165 PM_SAP_MODE); 2166 policy_mgr_debug("FREQ SAP: %d NAN: %d", sap_freq, ch_freq); 2167 if (!sap_freq) { 2168 sap_freq = policy_mgr_mode_specific_get_channel( 2169 pm_ctx->psoc, 2170 PM_LL_LT_SAP_MODE); 2171 policy_mgr_debug("FREQ LL_LT_SAP: %d NAN: %d", 2172 sap_freq, ch_freq); 2173 } 2174 if (ucfg_is_nan_dbs_supported(pm_ctx->psoc) && 2175 !WLAN_REG_IS_SAME_BAND_FREQS(sap_freq, ch_freq)) 2176 return true; 2177 2178 if (sap_freq == ch_freq) { 2179 policy_mgr_debug("NAN+SAP SCC"); 2180 return true; 2181 } 2182 2183 if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { 2184 policy_mgr_debug("SAP force SCC disabled"); 2185 return false; 2186 } 2187 if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( 2188 pm_ctx, ch_freq)) { 2189 policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); 2190 return false; 2191 } 2192 if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && 2193 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) { 2194 policy_mgr_debug("DFS CAC in progress, reject NAN enable"); 2195 return false; 2196 } 2197 } else if (policy_mgr_is_sap_mode(mode)) { 2198 nan_2g_freq = 2199 policy_mgr_mode_specific_get_channel(pm_ctx->psoc, 2200 PM_NAN_DISC_MODE); 2201 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc); 2202 policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch_freq, 2203 nan_2g_freq, nan_5g_freq); 2204 if (ucfg_is_nan_conc_control_supported(pm_ctx->psoc) && 2205 !ucfg_is_nan_dbs_supported(pm_ctx->psoc) && 2206 !WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq)) { 2207 if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { 2208 policy_mgr_debug("NAN and SAP are in different bands but SAP force SCC disabled"); 2209 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2210 return true; 2211 } 2212 } else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) || 2213 WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)) { 2214 if (ch_freq == nan_2g_freq || ch_freq == nan_5g_freq) { 2215 policy_mgr_debug("NAN+SAP SCC"); 2216 return true; 2217 } 2218 if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { 2219 policy_mgr_debug("SAP force SCC disabled"); 2220 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2221 return true; 2222 } 2223 if ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && 2224 !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( 2225 pm_ctx, nan_5g_freq)) || 2226 (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && 2227 !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( 2228 pm_ctx, nan_2g_freq))) { 2229 policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); 2230 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2231 return true; 2232 } 2233 } 2234 } 2235 return true; 2236 } 2237 2238 QDF_STATUS 2239 policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc) 2240 { 2241 struct policy_mgr_psoc_priv_obj *pm_ctx; 2242 struct policy_mgr_conc_connection_info *sap_info = NULL; 2243 uint8_t i; 2244 qdf_freq_t nan_freq_2g, nan_freq_5g; 2245 QDF_STATUS status = QDF_STATUS_SUCCESS; 2246 2247 pm_ctx = policy_mgr_get_context(psoc); 2248 if (!pm_ctx) { 2249 policy_mgr_err("Invalid pm context"); 2250 return QDF_STATUS_E_INVAL; 2251 } 2252 2253 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 2254 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 2255 if (policy_mgr_is_sap_mode(pm_conc_connection_list[i].mode) && 2256 pm_conc_connection_list[i].in_use) { 2257 sap_info = &pm_conc_connection_list[i]; 2258 break; 2259 } 2260 } 2261 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2262 2263 if (!sap_info) 2264 goto end; 2265 if (sap_info->freq == 0) 2266 goto end; 2267 nan_freq_2g = policy_mgr_mode_specific_get_channel(psoc, 2268 PM_NAN_DISC_MODE); 2269 nan_freq_5g = wlan_nan_get_disc_5g_ch_freq(psoc); 2270 if (sap_info->freq == nan_freq_2g || sap_info->freq == nan_freq_5g) { 2271 policy_mgr_debug("NAN and SAP already in SCC"); 2272 goto end; 2273 } 2274 if (nan_freq_2g == 0) 2275 goto end; 2276 2277 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2278 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2279 policy_mgr_debug("channel switch is already in progress"); 2280 return status; 2281 } 2282 2283 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 2284 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc, 2285 sap_info->vdev_id, 2286 CSA_REASON_CONCURRENT_NAN_EVENT); 2287 2288 /* SAP should be moved to 2g NAN channel on non-DBS platforms */ 2289 if (!ucfg_is_nan_dbs_supported(pm_ctx->psoc) || 2290 WLAN_REG_IS_24GHZ_CH_FREQ(sap_info->freq)) { 2291 policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d", 2292 nan_freq_2g); 2293 status = 2294 policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, 2295 nan_freq_2g, 2296 policy_mgr_get_ch_width( 2297 sap_info->bw), 2298 true); 2299 if (status == QDF_STATUS_SUCCESS) 2300 status = QDF_STATUS_E_PENDING; 2301 } else if (nan_freq_5g && WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq)) { 2302 policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d", 2303 nan_freq_5g); 2304 status = 2305 policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, 2306 nan_freq_5g, 2307 policy_mgr_get_ch_width( 2308 sap_info->bw), 2309 true); 2310 if (status == QDF_STATUS_SUCCESS) 2311 status = QDF_STATUS_E_PENDING; 2312 } 2313 2314 end: 2315 pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = false; 2316 2317 return status; 2318 } 2319 2320 void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc) 2321 { 2322 struct policy_mgr_psoc_priv_obj *pm_ctx; 2323 struct policy_mgr_conc_connection_info *sap_info = NULL; 2324 uint32_t sap_freq = 0, i; 2325 QDF_STATUS status; 2326 uint32_t user_config_freq; 2327 uint8_t band_mask = 0; 2328 uint8_t chn_idx, num_chan; 2329 struct regulatory_channel *channel_list; 2330 2331 pm_ctx = policy_mgr_get_context(psoc); 2332 if (!pm_ctx) { 2333 policy_mgr_err("Invalid pm context"); 2334 return; 2335 } 2336 2337 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 2338 if (pm_conc_connection_list[i].mode == PM_SAP_MODE && 2339 pm_conc_connection_list[i].in_use) { 2340 sap_info = &pm_conc_connection_list[i]; 2341 sap_freq = sap_info->freq; 2342 break; 2343 } 2344 } 2345 if (sap_freq == 0 || policy_mgr_is_safe_channel(psoc, sap_freq)) 2346 return; 2347 2348 user_config_freq = policy_mgr_get_user_config_sap_freq( 2349 psoc, sap_info->vdev_id); 2350 2351 sap_freq = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE, 2352 false, 2353 sap_info->vdev_id); 2354 policy_mgr_debug("User/ACS orig Freq: %d New SAP Freq: %d", 2355 user_config_freq, sap_freq); 2356 2357 if (wlan_reg_is_enable_in_secondary_list_for_freq(pm_ctx->pdev, 2358 user_config_freq) && 2359 policy_mgr_is_safe_channel(psoc, user_config_freq)) { 2360 policy_mgr_debug("Give preference to user config freq"); 2361 sap_freq = user_config_freq; 2362 } else { 2363 channel_list = qdf_mem_malloc( 2364 sizeof(struct regulatory_channel) * 2365 NUM_CHANNELS); 2366 if (!channel_list) 2367 return; 2368 2369 band_mask |= BIT(wlan_reg_freq_to_band(user_config_freq)); 2370 num_chan = wlan_reg_get_band_channel_list_for_pwrmode( 2371 pm_ctx->pdev, 2372 band_mask, 2373 channel_list, 2374 REG_CURRENT_PWR_MODE); 2375 for (chn_idx = 0; chn_idx < num_chan; chn_idx++) { 2376 if (wlan_reg_is_enable_in_secondary_list_for_freq( 2377 pm_ctx->pdev, 2378 channel_list[chn_idx].center_freq) && 2379 policy_mgr_is_safe_channel( 2380 psoc, 2381 channel_list[chn_idx].center_freq)) { 2382 policy_mgr_debug("Prefer user config band freq %d", 2383 channel_list[chn_idx].center_freq); 2384 sap_freq = channel_list[chn_idx].center_freq; 2385 } 2386 } 2387 qdf_mem_free(channel_list); 2388 } 2389 2390 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2391 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2392 policy_mgr_debug("wait as channel switch is already in progress"); 2393 status = qdf_wait_single_event( 2394 &pm_ctx->channel_switch_complete_evt, 2395 CHANNEL_SWITCH_COMPLETE_TIMEOUT); 2396 if (QDF_IS_STATUS_ERROR(status)) 2397 policy_mgr_err("wait for event failed, still continue with channel switch"); 2398 } 2399 2400 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 2401 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( 2402 psoc, sap_info->vdev_id, 2403 CSA_REASON_CONCURRENT_NAN_EVENT); 2404 2405 policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, 2406 sap_freq, 2407 policy_mgr_get_ch_width( 2408 sap_info->bw), true); 2409 } 2410 2411 void policy_mgr_check_sap_restart(struct wlan_objmgr_psoc *psoc, 2412 uint8_t vdev_id) 2413 { 2414 QDF_STATUS status; 2415 uint32_t ch_freq; 2416 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; 2417 2418 if (!psoc) { 2419 policy_mgr_err("Invalid psoc"); 2420 return; 2421 } 2422 pm_ctx = policy_mgr_get_context(psoc); 2423 if (!pm_ctx) { 2424 policy_mgr_err("Invalid context"); 2425 return; 2426 } 2427 2428 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2429 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2430 policy_mgr_debug("channel switch is already in progress"); 2431 return; 2432 } 2433 2434 /* 2435 * Restart should be handled by sap_fsm_validate_and_change_channel(), 2436 * after SAP starts. 2437 */ 2438 if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && 2439 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) { 2440 policy_mgr_debug("DFS CAC in progress, do not restart SAP"); 2441 return; 2442 } 2443 2444 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { 2445 policy_mgr_err("SAP restart get channel callback in NULL"); 2446 goto end; 2447 } 2448 status = 2449 pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart(psoc, 2450 vdev_id, 2451 &ch_freq); 2452 if (status == QDF_STATUS_SUCCESS) 2453 policy_mgr_debug("SAP vdev id %d switch to new ch freq: %d", 2454 vdev_id, ch_freq); 2455 2456 end: 2457 pm_ctx->last_disconn_sta_freq = 0; 2458 } 2459 2460 /** 2461 * policy_mgr_handle_sap_plus_go_force_scc() - Do SAP/GO force SCC 2462 * @psoc: soc object 2463 * 2464 * This function will check SAP/GO channel state and select channel 2465 * to avoid MCC, then do channel change on the second interface. 2466 * 2467 * Return: QDF_STATUS_SUCCESS if successfully handle the SAP/GO 2468 * force SCC. 2469 */ 2470 static QDF_STATUS 2471 policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc *psoc) 2472 { 2473 QDF_STATUS status = QDF_STATUS_E_INVAL; 2474 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 2475 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 2476 enum policy_mgr_con_mode vdev_con_mode; 2477 uint32_t existing_ch_freq, chan_freq, intf_ch_freq; 2478 enum phy_ch_width existing_ch_width; 2479 uint8_t vdev_id; 2480 struct policy_mgr_psoc_priv_obj *pm_ctx; 2481 struct sta_ap_intf_check_work_ctx *work_info; 2482 struct ch_params ch_params = {0}; 2483 enum QDF_OPMODE opmode; 2484 2485 pm_ctx = policy_mgr_get_context(psoc); 2486 if (!pm_ctx) { 2487 policy_mgr_err("Invalid Context"); 2488 return status; 2489 } 2490 2491 work_info = pm_ctx->sta_ap_intf_check_work_info; 2492 if (!work_info) { 2493 policy_mgr_err("invalid work info"); 2494 return status; 2495 } 2496 if (work_info->sap_plus_go_force_scc.reason == CSA_REASON_UNKNOWN) 2497 return status; 2498 2499 vdev_id = work_info->sap_plus_go_force_scc.initiator_vdev_id; 2500 chan_freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id); 2501 opmode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 2502 vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode, 2503 vdev_id); 2504 2505 existing_vdev_id = 2506 policy_mgr_fetch_existing_con_info( 2507 psoc, 2508 vdev_id, 2509 chan_freq, 2510 &existing_vdev_mode, 2511 &existing_ch_freq, &existing_ch_width); 2512 policy_mgr_debug("initiator vdev %d mode %d freq %d, existing vdev %d mode %d freq %d reason %d", 2513 vdev_id, vdev_con_mode, chan_freq, existing_vdev_id, 2514 existing_vdev_mode, existing_ch_freq, 2515 work_info->sap_plus_go_force_scc.reason); 2516 2517 if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX) 2518 goto force_scc_done; 2519 2520 if (!((vdev_con_mode == PM_P2P_GO_MODE && 2521 existing_vdev_mode == PM_SAP_MODE) || 2522 (vdev_con_mode == PM_SAP_MODE && 2523 existing_vdev_mode == PM_P2P_GO_MODE))) 2524 goto force_scc_done; 2525 2526 if (!pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb) 2527 goto force_scc_done; 2528 2529 intf_ch_freq = 0; 2530 status = pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb(psoc, 2531 existing_vdev_id, 2532 &intf_ch_freq); 2533 policy_mgr_debug("vdev %d freq %d intf %d status %d", 2534 existing_vdev_id, existing_ch_freq, 2535 intf_ch_freq, status); 2536 if (QDF_IS_STATUS_ERROR(status)) 2537 goto force_scc_done; 2538 if (!intf_ch_freq || intf_ch_freq == existing_ch_freq) 2539 goto force_scc_done; 2540 2541 ch_params.ch_width = existing_ch_width; 2542 if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) { 2543 status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 2544 psoc, existing_vdev_id, intf_ch_freq, &ch_params); 2545 if (QDF_IS_STATUS_ERROR(status)) 2546 policy_mgr_debug("no candidate valid bw for vdev %d intf %d", 2547 existing_vdev_id, intf_ch_freq); 2548 } 2549 2550 status = policy_mgr_valid_sap_conc_channel_check( 2551 psoc, &intf_ch_freq, existing_ch_freq, existing_vdev_id, 2552 &ch_params); 2553 if (QDF_IS_STATUS_ERROR(status)) { 2554 policy_mgr_err("warning no candidate freq for vdev %d freq %d intf %d", 2555 existing_vdev_id, existing_ch_freq, 2556 intf_ch_freq); 2557 goto force_scc_done; 2558 } 2559 2560 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 2561 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( 2562 psoc, existing_vdev_id, 2563 work_info->sap_plus_go_force_scc.reason); 2564 2565 status = policy_mgr_change_sap_channel_with_csa( 2566 psoc, existing_vdev_id, intf_ch_freq, 2567 ch_params.ch_width, true); 2568 if (QDF_IS_STATUS_ERROR(status)) { 2569 policy_mgr_err("warning sap/go vdev %d freq %d intf %d csa failed", 2570 existing_vdev_id, existing_ch_freq, 2571 intf_ch_freq); 2572 } 2573 2574 force_scc_done: 2575 work_info->sap_plus_go_force_scc.reason = CSA_REASON_UNKNOWN; 2576 work_info->sap_plus_go_force_scc.initiator_vdev_id = 2577 WLAN_UMAC_VDEV_ID_MAX; 2578 work_info->sap_plus_go_force_scc.responder_vdev_id = 2579 WLAN_UMAC_VDEV_ID_MAX; 2580 2581 return status; 2582 } 2583 2584 QDF_STATUS 2585 policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc, 2586 struct wlan_objmgr_vdev *vdev, 2587 enum sap_csa_reason_code reason_code) 2588 { 2589 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 2590 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 2591 enum policy_mgr_con_mode vdev_con_mode; 2592 uint32_t con_freq, chan_freq; 2593 enum phy_ch_width ch_width; 2594 uint8_t vdev_id; 2595 struct policy_mgr_psoc_priv_obj *pm_ctx; 2596 struct sta_ap_intf_check_work_ctx *work_info; 2597 enum QDF_OPMODE opmode; 2598 2599 if (reason_code != CSA_REASON_GO_BSS_STARTED && 2600 reason_code != CSA_REASON_USER_INITIATED) 2601 return QDF_STATUS_SUCCESS; 2602 2603 pm_ctx = policy_mgr_get_context(psoc); 2604 if (!pm_ctx) { 2605 policy_mgr_err("Invalid Context"); 2606 return QDF_STATUS_E_INVAL; 2607 } 2608 if (pm_ctx->cfg.mcc_to_scc_switch == 2609 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) 2610 return QDF_STATUS_SUCCESS; 2611 2612 if (!vdev) { 2613 policy_mgr_err("vdev is null"); 2614 return QDF_STATUS_E_INVAL; 2615 } 2616 vdev_id = wlan_vdev_get_id(vdev); 2617 opmode = wlan_vdev_mlme_get_opmode(vdev); 2618 work_info = pm_ctx->sta_ap_intf_check_work_info; 2619 if (!work_info) { 2620 policy_mgr_err("invalid work info"); 2621 return QDF_STATUS_E_INVAL; 2622 } 2623 2624 chan_freq = wlan_get_operation_chan_freq(vdev); 2625 vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode, 2626 vdev_id); 2627 2628 existing_vdev_id = 2629 policy_mgr_fetch_existing_con_info(psoc, 2630 vdev_id, 2631 chan_freq, 2632 &existing_vdev_mode, 2633 &con_freq, &ch_width); 2634 if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX) 2635 return QDF_STATUS_SUCCESS; 2636 2637 if (!((vdev_con_mode == PM_P2P_GO_MODE && 2638 existing_vdev_mode == PM_SAP_MODE) || 2639 (vdev_con_mode == PM_SAP_MODE && 2640 existing_vdev_mode == PM_P2P_GO_MODE))) 2641 return QDF_STATUS_SUCCESS; 2642 2643 work_info->sap_plus_go_force_scc.reason = reason_code; 2644 work_info->sap_plus_go_force_scc.initiator_vdev_id = vdev_id; 2645 work_info->sap_plus_go_force_scc.responder_vdev_id = existing_vdev_id; 2646 2647 policy_mgr_debug("initiator vdev %d freq %d, existing vdev %d freq %d reason %d", 2648 vdev_id, chan_freq, existing_vdev_id, 2649 con_freq, reason_code); 2650 2651 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2652 WAIT_BEFORE_GO_FORCESCC_RESTART)) 2653 policy_mgr_debug("change interface request already queued"); 2654 2655 return QDF_STATUS_E_PENDING; 2656 } 2657 2658 /** 2659 * policy_mgr_is_any_conn_in_transition() - Check if any STA/CLI 2660 * connection is disconnecting or roaming state 2661 * @psoc: PSOC object information 2662 * 2663 * This function will check connection table and find any STA/CLI 2664 * in transition state such as disconnecting, link switch or roaming. 2665 * 2666 * Return: true if there is one STA/CLI in transition state. 2667 */ 2668 static bool 2669 policy_mgr_is_any_conn_in_transition(struct wlan_objmgr_psoc *psoc) 2670 { 2671 struct policy_mgr_psoc_priv_obj *pm_ctx; 2672 uint32_t i; 2673 struct policy_mgr_conc_connection_info *conn_info; 2674 struct wlan_objmgr_vdev *vdev; 2675 bool non_connected = false; 2676 bool in_link_switch = false; 2677 uint8_t vdev_id; 2678 2679 pm_ctx = policy_mgr_get_context(psoc); 2680 if (!pm_ctx) { 2681 policy_mgr_err("Invalid pm context"); 2682 return false; 2683 } 2684 2685 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 2686 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 2687 conn_info = &pm_conc_connection_list[i]; 2688 if (!(conn_info->in_use && 2689 (conn_info->mode == PM_STA_MODE || 2690 conn_info->mode == PM_P2P_CLIENT_MODE))) 2691 continue; 2692 vdev_id = conn_info->vdev_id; 2693 vdev = wlan_objmgr_get_vdev_by_id_from_pdev( 2694 pm_ctx->pdev, vdev_id, WLAN_POLICY_MGR_ID); 2695 if (!vdev) { 2696 policy_mgr_err("vdev %d: not found", vdev_id); 2697 continue; 2698 } 2699 2700 non_connected = !wlan_cm_is_vdev_connected(vdev); 2701 2702 if (mlo_is_mld_sta(vdev) && 2703 mlo_mgr_is_link_switch_in_progress(vdev)) 2704 in_link_switch = true; 2705 2706 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 2707 if (non_connected) { 2708 policy_mgr_debug("vdev %d: is in transition state", 2709 vdev_id); 2710 break; 2711 } 2712 if (in_link_switch) { 2713 policy_mgr_debug("vdev %d: sta mld is in link switch state", 2714 vdev_id); 2715 break; 2716 } 2717 } 2718 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2719 2720 return non_connected || in_link_switch; 2721 } 2722 2723 static void __policy_mgr_check_sta_ap_concurrent_ch_intf( 2724 struct policy_mgr_psoc_priv_obj *pm_ctx) 2725 { 2726 uint32_t mcc_to_scc_switch, cc_count = 0, i; 2727 QDF_STATUS status; 2728 uint32_t ch_freq; 2729 uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 2730 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; 2731 struct sta_ap_intf_check_work_ctx *work_info; 2732 2733 if (!pm_ctx) { 2734 policy_mgr_err("Invalid context"); 2735 return; 2736 } 2737 work_info = pm_ctx->sta_ap_intf_check_work_info; 2738 2739 if (work_info->nan_force_scc_in_progress) { 2740 policy_mgr_nan_sap_post_enable_conc_check(pm_ctx->psoc); 2741 return; 2742 } 2743 /* 2744 * Check if force scc is required for GO + GO case. vdev id will be 2745 * valid in case of GO+GO force scc only. So, for valid vdev id move 2746 * first GO to newly formed GO channel. 2747 */ 2748 policy_mgr_debug("p2p go vdev id: %d csa reason: %d", 2749 work_info->go_plus_go_force_scc.vdev_id, 2750 work_info->sap_plus_go_force_scc.reason); 2751 if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id < 2752 WLAN_UMAC_VDEV_ID_MAX) { 2753 policy_mgr_do_go_plus_go_force_scc( 2754 pm_ctx->psoc, work_info->go_plus_go_force_scc.vdev_id, 2755 work_info->go_plus_go_force_scc.ch_freq, 2756 work_info->go_plus_go_force_scc.ch_width); 2757 work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX; 2758 goto end; 2759 } 2760 /* 2761 * Check if force scc is required for GO + SAP case. 2762 */ 2763 if (pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason != 2764 CSA_REASON_UNKNOWN) { 2765 status = policy_mgr_handle_sap_plus_go_force_scc(pm_ctx->psoc); 2766 goto end; 2767 } 2768 2769 mcc_to_scc_switch = 2770 policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc); 2771 2772 policy_mgr_debug("Concurrent open sessions running: %d", 2773 policy_mgr_concurrent_open_sessions_running(pm_ctx->psoc)); 2774 2775 if (!policy_mgr_is_sap_go_existed(pm_ctx->psoc)) 2776 goto end; 2777 2778 cc_count = policy_mgr_get_sap_mode_info(pm_ctx->psoc, 2779 &op_ch_freq_list[cc_count], 2780 &vdev_id[cc_count]); 2781 2782 policy_mgr_debug("Number of concurrent SAP: %d", cc_count); 2783 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) 2784 cc_count = cc_count + 2785 policy_mgr_get_mode_specific_conn_info( 2786 pm_ctx->psoc, &op_ch_freq_list[cc_count], 2787 &vdev_id[cc_count], PM_P2P_GO_MODE); 2788 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", 2789 cc_count); 2790 if (!cc_count) { 2791 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid"); 2792 goto end; 2793 } 2794 2795 /* When any STA/CLI is transition state, such as roaming or 2796 * disconnecting, skip force scc for this time. 2797 */ 2798 if (policy_mgr_is_any_conn_in_transition(pm_ctx->psoc)) { 2799 policy_mgr_debug("defer sap conc check to a later time due to another sta/cli dicon/roam pending"); 2800 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2801 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2802 goto end; 2803 } 2804 2805 if (policy_mgr_is_ap_start_in_progress(pm_ctx->psoc)) { 2806 policy_mgr_debug("defer sap conc check to a later time due to another sap/go start pending"); 2807 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2808 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2809 goto end; 2810 } 2811 if (policy_mgr_is_set_link_in_progress(pm_ctx->psoc)) { 2812 policy_mgr_debug("defer sap conc check to a later time due to ml sta set link in progress"); 2813 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2814 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2815 goto end; 2816 } 2817 2818 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2819 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2820 policy_mgr_debug("wait as channel switch is already in progress"); 2821 status = qdf_wait_single_event( 2822 &pm_ctx->channel_switch_complete_evt, 2823 CHANNEL_SWITCH_COMPLETE_TIMEOUT); 2824 if (QDF_IS_STATUS_ERROR(status)) 2825 policy_mgr_err("wait for event failed, still continue with channel switch"); 2826 } 2827 2828 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { 2829 policy_mgr_err("SAP restart get channel callback in NULL"); 2830 goto end; 2831 } 2832 if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) 2833 for (i = 0; i < cc_count; i++) { 2834 status = pm_ctx->hdd_cbacks. 2835 wlan_hdd_get_channel_for_sap_restart 2836 (pm_ctx->psoc, vdev_id[i], &ch_freq); 2837 if (status == QDF_STATUS_SUCCESS) { 2838 policy_mgr_debug("SAP vdev id %d restarts, old ch freq :%d new ch freq: %d", 2839 vdev_id[i], 2840 op_ch_freq_list[i], ch_freq); 2841 break; 2842 } 2843 } 2844 2845 end: 2846 pm_ctx->last_disconn_sta_freq = 0; 2847 } 2848 2849 void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) 2850 { 2851 struct qdf_op_sync *op_sync; 2852 struct policy_mgr_psoc_priv_obj *pm_ctx = data; 2853 int ret; 2854 2855 if (!pm_ctx) { 2856 policy_mgr_err("Invalid context"); 2857 return; 2858 } 2859 2860 ret = qdf_op_protect(&op_sync); 2861 if (ret) { 2862 if (ret == -EAGAIN) { 2863 if (qdf_is_driver_unloading() || 2864 qdf_is_recovering() || 2865 qdf_is_driver_state_module_stop()) { 2866 policy_mgr_debug("driver not ready"); 2867 return; 2868 } 2869 2870 if (!pm_ctx->sta_ap_intf_check_work_info) 2871 return; 2872 2873 pm_ctx->work_fail_count++; 2874 policy_mgr_debug("qdf_op start fail, ret %d, work_fail_count %d", 2875 ret, pm_ctx->work_fail_count); 2876 if (pm_ctx->work_fail_count > 1) { 2877 pm_ctx->work_fail_count = 0; 2878 return; 2879 } 2880 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2881 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2882 } 2883 return; 2884 } 2885 pm_ctx->work_fail_count = 0; 2886 __policy_mgr_check_sta_ap_concurrent_ch_intf(data); 2887 2888 qdf_op_unprotect(op_sync); 2889 } 2890 2891 static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, 2892 uint32_t sta_ch_freq) 2893 { 2894 struct policy_mgr_psoc_priv_obj *pm_ctx; 2895 bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel; 2896 2897 pm_ctx = policy_mgr_get_context(psoc); 2898 if (!pm_ctx) { 2899 policy_mgr_err("Invalid context"); 2900 return false; 2901 } 2902 2903 sta_sap_scc_on_dfs_chan = 2904 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 2905 if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) && 2906 sta_sap_scc_on_dfs_chan) { 2907 policy_mgr_debug("STA, SAP SCC is allowed on DFS chan %u", 2908 sta_ch_freq); 2909 return true; 2910 } 2911 2912 sta_sap_scc_on_indoor_channel = 2913 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 2914 if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) && 2915 sta_sap_scc_on_indoor_channel) { 2916 policy_mgr_debug("STA, SAP SCC is allowed on indoor chan %u", 2917 sta_ch_freq); 2918 return true; 2919 } 2920 2921 if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) && 2922 !sta_sap_scc_on_dfs_chan) || 2923 wlan_reg_is_passive_or_disable_for_pwrmode( 2924 pm_ctx->pdev, sta_ch_freq, REG_CURRENT_PWR_MODE) || 2925 (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) && 2926 !sta_sap_scc_on_indoor_channel) || 2927 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) && 2928 !policy_mgr_is_safe_channel(psoc, sta_ch_freq))) { 2929 if (policy_mgr_is_hw_dbs_capable(psoc)) 2930 return true; 2931 else 2932 return false; 2933 } 2934 else 2935 return true; 2936 } 2937 2938 static bool policy_mgr_get_srd_enable_for_vdev( 2939 struct wlan_objmgr_psoc *psoc, 2940 uint8_t vdev_id) 2941 { 2942 struct wlan_objmgr_vdev *vdev; 2943 enum QDF_OPMODE vdev_opmode; 2944 bool enable_srd_channel = false; 2945 2946 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 2947 WLAN_POLICY_MGR_ID); 2948 if (!vdev) { 2949 policy_mgr_err("vdev is NULL"); 2950 return false; 2951 } 2952 2953 vdev_opmode = wlan_vdev_mlme_get_opmode(vdev); 2954 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 2955 2956 wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode, 2957 &enable_srd_channel); 2958 return enable_srd_channel; 2959 } 2960 2961 QDF_STATUS 2962 policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc, 2963 uint32_t *con_ch_freq, 2964 uint32_t sap_ch_freq, 2965 uint8_t sap_vdev_id, 2966 struct ch_params *ch_params) 2967 { 2968 struct policy_mgr_psoc_priv_obj *pm_ctx; 2969 uint32_t ch_freq = *con_ch_freq; 2970 bool find_alternate = false; 2971 enum phy_ch_width old_ch_width; 2972 bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel; 2973 bool is_dfs; 2974 bool is_6ghz_cap; 2975 bool is_sta_sap_scc; 2976 enum policy_mgr_con_mode con_mode; 2977 uint32_t nan_2g_freq, nan_5g_freq; 2978 2979 pm_ctx = policy_mgr_get_context(psoc); 2980 if (!pm_ctx) { 2981 policy_mgr_err("Invalid context"); 2982 return QDF_STATUS_E_FAILURE; 2983 } 2984 /* 2985 * If force SCC is set, Check if conc channel is DFS 2986 * or passive or part of LTE avoided channel list. 2987 * In that case move SAP to other band if DBS is supported, 2988 * return otherwise 2989 */ 2990 if (!policy_mgr_is_force_scc(psoc)) 2991 return QDF_STATUS_SUCCESS; 2992 2993 /* 2994 * If interference is 0, it could be STA/SAP SCC, 2995 * check further if SAP can start on STA home channel or 2996 * select other band channel if not. 2997 */ 2998 if (!ch_freq) { 2999 if (!policy_mgr_any_other_vdev_on_same_mac_as_freq(psoc, 3000 sap_ch_freq, 3001 sap_vdev_id)) 3002 return QDF_STATUS_SUCCESS; 3003 3004 ch_freq = sap_ch_freq; 3005 } 3006 3007 if (!ch_freq) 3008 return QDF_STATUS_SUCCESS; 3009 3010 con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id); 3011 3012 is_sta_sap_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq); 3013 3014 nan_2g_freq = 3015 policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE); 3016 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc); 3017 3018 sta_sap_scc_on_dfs_chan = 3019 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 3020 3021 sta_sap_scc_on_indoor_channel = 3022 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 3023 old_ch_width = ch_params->ch_width; 3024 if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) 3025 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 3026 psoc, sap_vdev_id, ch_freq, ch_params); 3027 3028 is_dfs = wlan_mlme_check_chan_param_has_dfs( 3029 pm_ctx->pdev, ch_params, ch_freq); 3030 is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL); 3031 3032 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && is_dfs && 3033 !sta_sap_scc_on_dfs_chan && is_sta_sap_scc) { 3034 find_alternate = true; 3035 policymgr_nofl_debug("sap not capable of DFS SCC on con ch_freq %d", 3036 ch_freq); 3037 } else if (wlan_reg_is_disable_for_pwrmode(pm_ctx->pdev, ch_freq, 3038 REG_CURRENT_PWR_MODE)) { 3039 find_alternate = true; 3040 policymgr_nofl_debug("sap not capable on disabled con ch_freq %d", 3041 ch_freq); 3042 } else if (con_mode == PM_P2P_GO_MODE && 3043 wlan_reg_is_passive_or_disable_for_pwrmode( 3044 pm_ctx->pdev, 3045 ch_freq, 3046 REG_CURRENT_PWR_MODE) && 3047 !(policy_mgr_is_go_scc_strict(psoc) && 3048 (!is_sta_sap_scc || sta_sap_scc_on_dfs_chan))) { 3049 find_alternate = true; 3050 policymgr_nofl_debug("Go not capable on dfs/disabled con ch_freq %d", 3051 ch_freq); 3052 } else if (!policy_mgr_is_safe_channel(psoc, ch_freq) && 3053 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) && 3054 is_sta_sap_scc) && 3055 !(policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc) && 3056 (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) || 3057 WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)))) { 3058 find_alternate = true; 3059 policymgr_nofl_debug("sap not capable unsafe con ch_freq %d", 3060 ch_freq); 3061 } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && 3062 !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) && 3063 !is_6ghz_cap) { 3064 policymgr_nofl_debug("sap not capable on 6GHZ con ch_freq %d", 3065 ch_freq); 3066 find_alternate = true; 3067 } else if (wlan_reg_is_etsi_srd_chan_for_freq(pm_ctx->pdev, 3068 ch_freq) && 3069 !policy_mgr_get_srd_enable_for_vdev(psoc, sap_vdev_id)) { 3070 find_alternate = true; 3071 policymgr_nofl_debug("sap not capable on SRD con ch_freq %d", 3072 ch_freq); 3073 } else if (!policy_mgr_is_sap_go_interface_allowed_on_indoor( 3074 pm_ctx->pdev, 3075 sap_vdev_id, ch_freq)) { 3076 policymgr_nofl_debug("sap not capable on indoor con ch_freq %d is_sta_sap_scc:%d", 3077 ch_freq, is_sta_sap_scc); 3078 find_alternate = true; 3079 } 3080 3081 if (find_alternate) { 3082 if (policy_mgr_is_hw_dbs_capable(psoc)) { 3083 ch_freq = policy_mgr_get_alternate_channel_for_sap( 3084 psoc, sap_vdev_id, sap_ch_freq, 3085 REG_BAND_UNKNOWN); 3086 policymgr_nofl_debug("selected alternate ch %d", 3087 ch_freq); 3088 if (!ch_freq) { 3089 policymgr_nofl_debug("Sap can't have concurrency on %d in dbs hw", 3090 *con_ch_freq); 3091 return QDF_STATUS_E_FAILURE; 3092 } 3093 } else { 3094 /* MCC not supported for non-DBS chip*/ 3095 ch_freq = 0; 3096 if (con_mode == PM_SAP_MODE) { 3097 policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d SAP freq %d not supported", 3098 *con_ch_freq, sap_ch_freq); 3099 return QDF_STATUS_E_FAILURE; 3100 } else { 3101 policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d GO freq %d SCC not supported", 3102 *con_ch_freq, sap_ch_freq); 3103 } 3104 } 3105 } 3106 3107 if (ch_freq != sap_ch_freq || old_ch_width != ch_params->ch_width) { 3108 *con_ch_freq = ch_freq; 3109 policymgr_nofl_debug("sap conc result con freq %d bw %d org freq %d bw %d", 3110 ch_freq, ch_params->ch_width, sap_ch_freq, 3111 old_ch_width); 3112 } 3113 3114 if (*con_ch_freq && 3115 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) 3116 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 3117 psoc, sap_vdev_id, ch_freq, ch_params); 3118 3119 return QDF_STATUS_SUCCESS; 3120 } 3121 3122 void policy_mgr_check_concurrent_intf_and_restart_sap( 3123 struct wlan_objmgr_psoc *psoc, bool is_acs_mode) 3124 { 3125 struct policy_mgr_psoc_priv_obj *pm_ctx; 3126 uint32_t mcc_to_scc_switch; 3127 uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3128 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3129 uint32_t cc_count = 0; 3130 uint32_t timeout_ms = 0; 3131 bool restart_sap = false; 3132 uint32_t sap_freq; 3133 /* 3134 * if no sta, sap/p2p go may need switch channel for band 3135 * capability change. 3136 * If sta exist, sap/p2p go may need switch channel to force scc 3137 */ 3138 bool sta_check = false, gc_check = false; 3139 3140 pm_ctx = policy_mgr_get_context(psoc); 3141 if (!pm_ctx) { 3142 policy_mgr_err("Invalid context"); 3143 return; 3144 } 3145 if (!pm_ctx->sta_ap_intf_check_work_info) { 3146 policy_mgr_err("Invalid sta_ap_intf_check_work_info"); 3147 return; 3148 } 3149 if (!policy_mgr_is_sap_go_existed(psoc)) { 3150 policy_mgr_debug( 3151 "No action taken at check_concurrent_intf_and_restart_sap"); 3152 return; 3153 } 3154 3155 if (policy_mgr_is_ll_lt_sap_restart_required(psoc)) { 3156 restart_sap = true; 3157 goto sap_restart; 3158 } 3159 3160 /* 3161 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is 3162 * enabled on DFS channel then move the SAP out of DFS channel 3163 * as soon as STA gets disconnect. 3164 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is 3165 * enabled on unsafe channel then move the SAP to safe channel 3166 * as soon as STA disconnected. 3167 */ 3168 if (policy_mgr_is_sap_restart_required_after_sta_disconnect( 3169 psoc, INVALID_VDEV_ID, &sap_freq, is_acs_mode)) { 3170 policy_mgr_debug("move the SAP to configured channel %u", 3171 sap_freq); 3172 restart_sap = true; 3173 goto sap_restart; 3174 } 3175 3176 /* 3177 * force SCC with STA+STA+SAP will need some additional logic 3178 */ 3179 cc_count = policy_mgr_get_mode_specific_conn_info( 3180 psoc, &op_ch_freq_list[cc_count], 3181 &vdev_id[cc_count], PM_STA_MODE); 3182 if (!cc_count) { 3183 policy_mgr_debug("Could not get STA operating channel&vdevid"); 3184 } 3185 3186 sta_check = !cc_count || 3187 policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]); 3188 3189 cc_count = 0; 3190 cc_count = policy_mgr_get_mode_specific_conn_info( 3191 psoc, &op_ch_freq_list[cc_count], 3192 &vdev_id[cc_count], PM_P2P_CLIENT_MODE); 3193 if (!cc_count) 3194 policy_mgr_debug("Could not get GC operating channel&vdevid"); 3195 3196 gc_check = !!cc_count; 3197 policy_mgr_debug("gc_check: %d", gc_check); 3198 3199 mcc_to_scc_switch = 3200 policy_mgr_get_mcc_to_scc_switch_mode(psoc); 3201 policy_mgr_debug("MCC to SCC switch: %d chan: %d", 3202 mcc_to_scc_switch, op_ch_freq_list[0]); 3203 sap_restart: 3204 /* 3205 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not 3206 * allowed on DFS channel. SAP is allowed on DFS channel only when STA 3207 * is already connected on that channel. 3208 * In following condition restart_sap will be true if 3209 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel. 3210 * This scenario can come if STA+SAP are operating on DFS channel and 3211 * STA gets disconnected. 3212 */ 3213 if (restart_sap || 3214 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && 3215 (sta_check || gc_check))) { 3216 if (!pm_ctx->sta_ap_intf_check_work_info) { 3217 policy_mgr_err("invalid sta_ap_intf_check_work_info"); 3218 return; 3219 } 3220 3221 policy_mgr_debug("Checking for Concurrent Change interference"); 3222 3223 if (policy_mgr_mode_specific_connection_count( 3224 psoc, PM_P2P_GO_MODE, NULL)) 3225 timeout_ms = MAX_NOA_TIME; 3226 3227 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 3228 timeout_ms)) { 3229 policy_mgr_debug("change interface request already queued"); 3230 return; 3231 } 3232 } 3233 } 3234 3235 bool policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc *psoc, 3236 qdf_freq_t center_freq, 3237 enum phy_ch_width ch_width) 3238 { 3239 struct policy_mgr_psoc_priv_obj *pm_ctx; 3240 uint32_t freq_start, freq_end, bw, i, unsafe_chan_freq; 3241 3242 pm_ctx = policy_mgr_get_context(psoc); 3243 if (!pm_ctx) { 3244 policy_mgr_err("Invalid Context"); 3245 return true; 3246 } 3247 3248 if (ch_width <= CH_WIDTH_20MHZ || !center_freq) 3249 return true; 3250 3251 if (!pm_ctx->unsafe_channel_count) 3252 return true; 3253 3254 bw = wlan_reg_get_bw_value(ch_width); 3255 freq_start = center_freq - bw / 2; 3256 freq_end = center_freq + bw / 2; 3257 3258 for (i = 0; i < pm_ctx->unsafe_channel_count; i++) { 3259 unsafe_chan_freq = pm_ctx->unsafe_channel_list[i]; 3260 if (unsafe_chan_freq > freq_start && 3261 unsafe_chan_freq < freq_end) { 3262 policy_mgr_debug("unsafe ch freq %d is in range %d-%d", 3263 unsafe_chan_freq, 3264 freq_start, 3265 freq_end); 3266 return false; 3267 } 3268 } 3269 return true; 3270 } 3271 3272 /** 3273 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA 3274 * @psoc: PSOC object information 3275 * @vdev_id: Vdev id 3276 * @ch_freq: Channel to change 3277 * @ch_width: channel width to change 3278 * @forced: Force to switch channel, ignore SCC/MCC check 3279 * 3280 * Invoke the callback function to change SAP channel using (E)CSA 3281 * 3282 * Return: QDF_STATUS_SUCCESS for success 3283 */ 3284 QDF_STATUS 3285 policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, 3286 uint8_t vdev_id, uint32_t ch_freq, 3287 uint32_t ch_width, bool forced) 3288 { 3289 struct policy_mgr_psoc_priv_obj *pm_ctx; 3290 struct ch_params ch_params = {0}; 3291 qdf_freq_t center_freq; 3292 QDF_STATUS status; 3293 3294 pm_ctx = policy_mgr_get_context(psoc); 3295 if (!pm_ctx) { 3296 policy_mgr_err("Invalid context"); 3297 return QDF_STATUS_E_INVAL; 3298 } 3299 if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) { 3300 ch_params.ch_width = ch_width; 3301 status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 3302 psoc, vdev_id, ch_freq, &ch_params); 3303 if (QDF_IS_STATUS_SUCCESS(status) && 3304 ch_width > ch_params.ch_width) 3305 ch_width = ch_params.ch_width; 3306 } 3307 3308 if (ch_params.mhz_freq_seg1) 3309 center_freq = ch_params.mhz_freq_seg1; 3310 else 3311 center_freq = ch_params.mhz_freq_seg0; 3312 3313 if (!policy_mgr_check_bw_with_unsafe_chan_freq(psoc, 3314 center_freq, 3315 ch_width)) { 3316 policy_mgr_info("SAP bw shrink to 20M for unsafe"); 3317 ch_width = CH_WIDTH_20MHZ; 3318 } 3319 3320 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { 3321 policy_mgr_info("SAP change change without restart"); 3322 status = pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, 3323 vdev_id, 3324 ch_freq, 3325 ch_width, 3326 forced); 3327 } else { 3328 status = QDF_STATUS_E_INVAL; 3329 } 3330 3331 return status; 3332 } 3333 #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ 3334 3335 QDF_STATUS 3336 policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc, 3337 uint8_t vdev_id, 3338 struct csa_offload_params *csa_event) 3339 { 3340 uint8_t concur_vdev_id, i; 3341 bool move_sap_go_first; 3342 enum hw_mode_bandwidth bw; 3343 qdf_freq_t cur_freq, new_freq; 3344 struct wlan_objmgr_vdev *vdev, *conc_vdev; 3345 struct wlan_objmgr_pdev *pdev; 3346 struct policy_mgr_psoc_priv_obj *pm_ctx; 3347 enum policy_mgr_con_mode cur_mode; 3348 enum policy_mgr_con_mode concur_mode = PM_MAX_NUM_OF_MODE; 3349 3350 pm_ctx = policy_mgr_get_context(psoc); 3351 if (!pm_ctx) { 3352 policy_mgr_err("Invalid context"); 3353 return QDF_STATUS_E_INVAL; 3354 } 3355 if (!csa_event) { 3356 policy_mgr_err("CSA IE Received event is NULL"); 3357 return QDF_STATUS_E_INVAL; 3358 } 3359 3360 policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first); 3361 if (!move_sap_go_first) { 3362 policy_mgr_err("g_move_sap_go_1st_on_dfs_sta_csa is disabled"); 3363 return QDF_STATUS_E_NOSUPPORT; 3364 } 3365 3366 cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id); 3367 if (cur_mode != PM_STA_MODE) { 3368 policy_mgr_err("CSA received on non-STA connection"); 3369 return QDF_STATUS_E_INVAL; 3370 } 3371 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3372 WLAN_POLICY_MGR_ID); 3373 if (!vdev) { 3374 policy_mgr_err("vdev is NULL"); 3375 return QDF_STATUS_E_INVAL; 3376 } 3377 pdev = wlan_vdev_get_pdev(vdev); 3378 cur_freq = wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id); 3379 3380 if (!wlan_reg_is_dfs_for_freq(pdev, cur_freq) && 3381 !wlan_reg_is_freq_indoor(pdev, cur_freq)) { 3382 policy_mgr_err("SAP / GO operating channel is non-DFS"); 3383 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3384 return QDF_STATUS_E_INVAL; 3385 } 3386 3387 /* Check if there is any SAP / GO operating on the same channel or not 3388 * If yes, then get the current bandwidth and vdev_id of concurrent SAP 3389 * or GO and trigger channel switch to new channel received in CSA on 3390 * STA interface. If this new channel is DFS then trigger channel 3391 * switch to non-DFS channel. Once STA moves to this new channel and 3392 * when it receives very first beacon, it will then enforce SCC again 3393 */ 3394 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 3395 if (pm_conc_connection_list[i].in_use && 3396 pm_conc_connection_list[i].freq == cur_freq && 3397 pm_conc_connection_list[i].vdev_id != vdev_id && 3398 (pm_conc_connection_list[i].mode == PM_P2P_GO_MODE || 3399 pm_conc_connection_list[i].mode == PM_SAP_MODE)) { 3400 concur_mode = pm_conc_connection_list[i].mode; 3401 bw = pm_conc_connection_list[i].bw; 3402 concur_vdev_id = pm_conc_connection_list[i].vdev_id; 3403 break; 3404 } 3405 } 3406 3407 /* If there is no concurrent SAP / GO, then return */ 3408 if (concur_mode == PM_MAX_NUM_OF_MODE) { 3409 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3410 return QDF_STATUS_E_INVAL; 3411 } 3412 3413 conc_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, concur_vdev_id, 3414 WLAN_POLICY_MGR_ID); 3415 if (!conc_vdev) { 3416 policy_mgr_err("conc_vdev is NULL"); 3417 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3418 return QDF_STATUS_E_INVAL; 3419 } 3420 wlan_vdev_mlme_set_sap_go_move_before_sta(conc_vdev, true); 3421 wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, true); 3422 wlan_objmgr_vdev_release_ref(conc_vdev, WLAN_POLICY_MGR_ID); 3423 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3424 3425 /*Change the CSA count*/ 3426 if (pm_ctx->sme_cbacks.sme_change_sap_csa_count) 3427 /* Total 4 CSA frames are allowed so that GO / SAP 3428 * will move to new channel within 500ms 3429 */ 3430 pm_ctx->sme_cbacks.sme_change_sap_csa_count(4); 3431 new_freq = csa_event->csa_chan_freq; 3432 3433 /* If the new channel is DFS or indoor, then select another channel 3434 * and switch the SAP / GO to avoid CAC. This will resume traffic on 3435 * SAP / GO interface immediately. Once STA moves to this new channel 3436 * and receives the very first beacon, then it will enforece SCC 3437 */ 3438 if (wlan_reg_is_dfs_for_freq(pdev, new_freq) || 3439 wlan_reg_is_freq_indoor(pdev, new_freq)) { 3440 if (wlan_reg_is_24ghz_ch_freq(new_freq)) { 3441 new_freq = wlan_reg_min_24ghz_chan_freq(); 3442 } else if (wlan_reg_is_5ghz_ch_freq(new_freq)) { 3443 new_freq = wlan_reg_min_5ghz_chan_freq(); 3444 /* if none of the 5G channel is non-DFS */ 3445 if (wlan_reg_is_dfs_for_freq(pdev, new_freq) || 3446 wlan_reg_is_freq_indoor(pdev, new_freq)) 3447 new_freq = policy_mgr_get_nondfs_preferred_channel(psoc, 3448 concur_mode, 3449 true, 3450 concur_vdev_id); 3451 } else { 3452 new_freq = wlan_reg_min_6ghz_chan_freq(); 3453 } 3454 } 3455 policy_mgr_debug("Restart vdev: %u on freq: %u", 3456 concur_vdev_id, new_freq); 3457 3458 return policy_mgr_change_sap_channel_with_csa(psoc, concur_vdev_id, 3459 new_freq, bw, true); 3460 } 3461 3462 void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc, 3463 uint8_t vdev_id) 3464 { 3465 bool is_sap_go_moved_before_sta, move_sap_go_first; 3466 struct policy_mgr_psoc_priv_obj *pm_ctx; 3467 struct wlan_objmgr_vdev *vdev; 3468 struct wlan_objmgr_pdev *pdev; 3469 enum policy_mgr_con_mode cur_mode; 3470 3471 pm_ctx = policy_mgr_get_context(psoc); 3472 if (!pm_ctx) { 3473 policy_mgr_err("Invalid context"); 3474 return; 3475 } 3476 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3477 WLAN_POLICY_MGR_ID); 3478 if (!vdev) { 3479 policy_mgr_err("vdev is NULL"); 3480 return; 3481 } 3482 is_sap_go_moved_before_sta = 3483 wlan_vdev_mlme_is_sap_go_move_before_sta(vdev); 3484 pdev = wlan_vdev_get_pdev(vdev); 3485 wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false); 3486 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3487 3488 policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first); 3489 if (!is_sap_go_moved_before_sta || !move_sap_go_first) { 3490 policy_mgr_debug("SAP / GO moved before STA: %u INI g_move_sap_go_1st_on_dfs_sta_csa: %u", 3491 is_sap_go_moved_before_sta, move_sap_go_first); 3492 return; 3493 } 3494 3495 cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id); 3496 if (cur_mode != PM_STA_MODE) { 3497 policy_mgr_err("CSA received on non-STA connection"); 3498 return; 3499 } 3500 3501 policy_mgr_debug("Enforce SCC"); 3502 policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false); 3503 } 3504 3505 #ifdef WLAN_FEATURE_P2P_P2P_STA 3506 void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc, 3507 uint8_t vdev_id, uint32_t ch_freq, 3508 uint32_t ch_width) 3509 { 3510 uint8_t total_connection; 3511 struct policy_mgr_psoc_priv_obj *pm_ctx; 3512 3513 pm_ctx = policy_mgr_get_context(psoc); 3514 if (!pm_ctx) { 3515 policy_mgr_err("Invalid Context"); 3516 return; 3517 } 3518 3519 total_connection = policy_mgr_mode_specific_connection_count( 3520 psoc, PM_P2P_GO_MODE, NULL); 3521 3522 policy_mgr_debug("Total p2p go connection %d", total_connection); 3523 3524 /* If any p2p disconnected, don't do csa */ 3525 if (total_connection > 1) { 3526 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 3527 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( 3528 psoc, vdev_id, 3529 CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL); 3530 3531 policy_mgr_change_sap_channel_with_csa(psoc, vdev_id, 3532 ch_freq, ch_width, true); 3533 } 3534 } 3535 3536 void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc, 3537 uint8_t vdev_id, uint32_t ch_freq, 3538 uint32_t ch_width, 3539 enum policy_mgr_con_mode mode) 3540 { 3541 struct policy_mgr_psoc_priv_obj *pm_ctx; 3542 struct sta_ap_intf_check_work_ctx *work_info; 3543 3544 pm_ctx = policy_mgr_get_context(psoc); 3545 if (!pm_ctx) { 3546 policy_mgr_err("Invalid Context"); 3547 return; 3548 } 3549 if (!pm_ctx->sta_ap_intf_check_work_info) { 3550 policy_mgr_err("invalid work info"); 3551 return; 3552 } 3553 work_info = pm_ctx->sta_ap_intf_check_work_info; 3554 if (mode == PM_P2P_GO_MODE) { 3555 work_info->go_plus_go_force_scc.vdev_id = vdev_id; 3556 work_info->go_plus_go_force_scc.ch_freq = ch_freq; 3557 work_info->go_plus_go_force_scc.ch_width = ch_width; 3558 } 3559 3560 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 3561 WAIT_BEFORE_GO_FORCESCC_RESTART)) 3562 policy_mgr_debug("change interface request already queued"); 3563 } 3564 #endif 3565 3566 bool policy_mgr_is_chan_switch_in_progress(struct wlan_objmgr_psoc *psoc) 3567 { 3568 struct policy_mgr_psoc_priv_obj *pm_ctx; 3569 3570 pm_ctx = policy_mgr_get_context(psoc); 3571 if (!pm_ctx) { 3572 policy_mgr_err("Invalid pm context"); 3573 return false; 3574 } 3575 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 3576 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 3577 policy_mgr_debug("channel switch is in progress"); 3578 return true; 3579 } 3580 3581 return false; 3582 } 3583 3584 QDF_STATUS policy_mgr_wait_chan_switch_complete_evt( 3585 struct wlan_objmgr_psoc *psoc) 3586 { 3587 QDF_STATUS status; 3588 struct policy_mgr_psoc_priv_obj *pm_ctx; 3589 3590 pm_ctx = policy_mgr_get_context(psoc); 3591 3592 if (!pm_ctx) { 3593 policy_mgr_err("Invalid context"); 3594 return QDF_STATUS_E_FAILURE; 3595 } 3596 3597 status = qdf_wait_single_event( 3598 &pm_ctx->channel_switch_complete_evt, 3599 CHANNEL_SWITCH_COMPLETE_TIMEOUT); 3600 if (QDF_IS_STATUS_ERROR(status)) 3601 policy_mgr_err("wait for event failed, still continue with channel switch"); 3602 3603 return status; 3604 } 3605 3606 static void __policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_pdev *pdev, 3607 void *object, void *arg) 3608 { 3609 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 3610 uint32_t *ap_starting_vdev_id = (uint32_t *)arg; 3611 enum wlan_serialization_cmd_type cmd_type; 3612 enum QDF_OPMODE op_mode; 3613 3614 if (!vdev || !ap_starting_vdev_id) 3615 return; 3616 if (*ap_starting_vdev_id != WLAN_INVALID_VDEV_ID) 3617 return; 3618 op_mode = wlan_vdev_mlme_get_opmode(vdev); 3619 if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE && 3620 op_mode != QDF_NDI_MODE) 3621 return; 3622 /* Check AP start is present in active and pending queue or not */ 3623 cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev); 3624 if (cmd_type == WLAN_SER_CMD_VDEV_START_BSS || 3625 wlan_ser_is_non_scan_cmd_type_in_vdev_queue( 3626 vdev, WLAN_SER_CMD_VDEV_START_BSS)) { 3627 *ap_starting_vdev_id = wlan_vdev_get_id(vdev); 3628 policy_mgr_debug("vdev %d op mode %d start bss is pending", 3629 *ap_starting_vdev_id, op_mode); 3630 } 3631 } 3632 3633 bool policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc *psoc) 3634 { 3635 struct policy_mgr_psoc_priv_obj *pm_ctx; 3636 uint32_t ap_starting_vdev_id = WLAN_INVALID_VDEV_ID; 3637 3638 pm_ctx = policy_mgr_get_context(psoc); 3639 if (!pm_ctx) { 3640 policy_mgr_err("Invalid pm context"); 3641 return false; 3642 } 3643 3644 wlan_objmgr_pdev_iterate_obj_list(pm_ctx->pdev, WLAN_VDEV_OP, 3645 __policy_mgr_is_ap_start_in_progress, 3646 &ap_starting_vdev_id, 0, 3647 WLAN_POLICY_MGR_ID); 3648 3649 return ap_starting_vdev_id != WLAN_INVALID_VDEV_ID; 3650 } 3651 3652 void policy_mgr_process_force_scc_for_nan(struct wlan_objmgr_psoc *psoc) 3653 { 3654 struct policy_mgr_psoc_priv_obj *pm_ctx; 3655 3656 pm_ctx = policy_mgr_get_context(psoc); 3657 if (!pm_ctx) { 3658 policy_mgr_err("Invalid Context"); 3659 return; 3660 } 3661 if (!pm_ctx->sta_ap_intf_check_work_info) { 3662 policy_mgr_err("invalid work info"); 3663 return; 3664 } 3665 3666 pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = true; 3667 3668 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 0)) 3669 policy_mgr_debug("change interface request already queued"); 3670 } 3671 3672 QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc) 3673 { 3674 QDF_STATUS status; 3675 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3676 3677 policy_mgr_context = policy_mgr_get_context(psoc); 3678 if (!policy_mgr_context) { 3679 policy_mgr_err("Invalid context"); 3680 return QDF_STATUS_E_FAILURE; 3681 } 3682 3683 status = qdf_wait_single_event( 3684 &policy_mgr_context->connection_update_done_evt, 3685 CONNECTION_UPDATE_TIMEOUT); 3686 3687 if (!QDF_IS_STATUS_SUCCESS(status)) { 3688 policy_mgr_err("wait for event failed"); 3689 return QDF_STATUS_E_FAILURE; 3690 } 3691 3692 return QDF_STATUS_SUCCESS; 3693 } 3694 3695 QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc) 3696 { 3697 QDF_STATUS status; 3698 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3699 3700 policy_mgr_context = policy_mgr_get_context(psoc); 3701 if (!policy_mgr_context) { 3702 policy_mgr_err("Invalid context"); 3703 return QDF_STATUS_E_FAILURE; 3704 } 3705 3706 status = qdf_event_reset( 3707 &policy_mgr_context->connection_update_done_evt); 3708 3709 if (!QDF_IS_STATUS_SUCCESS(status)) { 3710 policy_mgr_err("clear event failed"); 3711 return QDF_STATUS_E_FAILURE; 3712 } 3713 3714 return QDF_STATUS_SUCCESS; 3715 } 3716 3717 void policy_mgr_reset_hw_mode_change(struct wlan_objmgr_psoc *psoc) 3718 { 3719 policy_mgr_err("Clear hw mode change and connection update evt"); 3720 policy_mgr_set_hw_mode_change_in_progress( 3721 psoc, POLICY_MGR_HW_MODE_NOT_IN_PROGRESS); 3722 policy_mgr_reset_connection_update(psoc); 3723 } 3724 3725 QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc) 3726 { 3727 QDF_STATUS status; 3728 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3729 3730 policy_mgr_context = policy_mgr_get_context(psoc); 3731 if (!policy_mgr_context) { 3732 policy_mgr_err("Invalid context"); 3733 return QDF_STATUS_E_FAILURE; 3734 } 3735 3736 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt); 3737 3738 if (!QDF_IS_STATUS_SUCCESS(status)) { 3739 policy_mgr_err("set event failed"); 3740 return QDF_STATUS_E_FAILURE; 3741 } 3742 3743 return QDF_STATUS_SUCCESS; 3744 } 3745 3746 QDF_STATUS policy_mgr_set_chan_switch_complete_evt( 3747 struct wlan_objmgr_psoc *psoc) 3748 { 3749 QDF_STATUS status; 3750 struct policy_mgr_psoc_priv_obj *pm_ctx; 3751 3752 pm_ctx = policy_mgr_get_context(psoc); 3753 3754 if (!pm_ctx) { 3755 policy_mgr_err("Invalid context"); 3756 return QDF_STATUS_E_FAILURE; 3757 } 3758 3759 /* 3760 * Set channel_switch_complete_evt only if no vdev has channel switch 3761 * in progress. 3762 */ 3763 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 3764 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 3765 policy_mgr_info("Not all channel switch completed"); 3766 return QDF_STATUS_SUCCESS; 3767 } 3768 3769 status = qdf_event_set_all(&pm_ctx->channel_switch_complete_evt); 3770 3771 if (!QDF_IS_STATUS_SUCCESS(status)) { 3772 policy_mgr_err("set event failed"); 3773 return QDF_STATUS_E_FAILURE; 3774 } 3775 3776 return QDF_STATUS_SUCCESS; 3777 } 3778 3779 QDF_STATUS policy_mgr_reset_chan_switch_complete_evt( 3780 struct wlan_objmgr_psoc *psoc) 3781 { 3782 QDF_STATUS status; 3783 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3784 3785 policy_mgr_context = policy_mgr_get_context(psoc); 3786 3787 if (!policy_mgr_context) { 3788 policy_mgr_err("Invalid context"); 3789 return QDF_STATUS_E_FAILURE; 3790 } 3791 status = qdf_event_reset( 3792 &policy_mgr_context->channel_switch_complete_evt); 3793 3794 if (!QDF_IS_STATUS_SUCCESS(status)) { 3795 policy_mgr_err("reset event failed"); 3796 return QDF_STATUS_E_FAILURE; 3797 } 3798 3799 return QDF_STATUS_SUCCESS; 3800 } 3801 3802 QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc) 3803 { 3804 QDF_STATUS status; 3805 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3806 3807 policy_mgr_context = policy_mgr_get_context(psoc); 3808 if (!policy_mgr_context) { 3809 policy_mgr_err("Invalid context"); 3810 return QDF_STATUS_E_FAILURE; 3811 } 3812 3813 status = qdf_event_set( 3814 &policy_mgr_context->opportunistic_update_done_evt); 3815 3816 if (!QDF_IS_STATUS_SUCCESS(status)) { 3817 policy_mgr_err("set event failed"); 3818 return QDF_STATUS_E_FAILURE; 3819 } 3820 3821 return QDF_STATUS_SUCCESS; 3822 } 3823 3824 QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc) 3825 { 3826 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 3827 3828 policy_mgr_ctx = policy_mgr_get_context(psoc); 3829 if (!policy_mgr_ctx) { 3830 policy_mgr_err("Invalid context"); 3831 return QDF_STATUS_E_FAILURE; 3832 } 3833 3834 if (policy_mgr_ctx->dbs_opportunistic_timer.state != 3835 QDF_TIMER_STATE_RUNNING) 3836 return QDF_STATUS_SUCCESS; 3837 3838 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer); 3839 return QDF_STATUS_SUCCESS; 3840 } 3841 3842 QDF_STATUS policy_mgr_restart_opportunistic_timer( 3843 struct wlan_objmgr_psoc *psoc, bool check_state) 3844 { 3845 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3846 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 3847 3848 if (policy_mgr_is_hwmode_offload_enabled(psoc)) 3849 return QDF_STATUS_E_NOSUPPORT; 3850 3851 policy_mgr_ctx = policy_mgr_get_context(psoc); 3852 if (!policy_mgr_ctx) { 3853 policy_mgr_err("Invalid context"); 3854 return status; 3855 } 3856 3857 if (check_state && 3858 QDF_TIMER_STATE_RUNNING != 3859 policy_mgr_ctx->dbs_opportunistic_timer.state) 3860 return status; 3861 3862 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer); 3863 3864 status = qdf_mc_timer_start( 3865 &policy_mgr_ctx->dbs_opportunistic_timer, 3866 DBS_OPPORTUNISTIC_TIME * 1000); 3867 3868 if (!QDF_IS_STATUS_SUCCESS(status)) { 3869 policy_mgr_err("failed to start opportunistic timer"); 3870 return status; 3871 } 3872 3873 return status; 3874 } 3875 3876 QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( 3877 struct wlan_objmgr_psoc *psoc, uint8_t session_id) 3878 { 3879 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status; 3880 enum policy_mgr_conc_next_action action; 3881 3882 if (policy_mgr_is_hwmode_offload_enabled(psoc)) 3883 return QDF_STATUS_E_NOSUPPORT; 3884 3885 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 3886 policy_mgr_rl_debug("PM/DBS is disabled"); 3887 return status; 3888 } 3889 3890 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc); 3891 if ((action != PM_DBS_DOWNGRADE) && 3892 (action != PM_SINGLE_MAC_UPGRADE) && 3893 (action != PM_DBS1_DOWNGRADE) && 3894 (action != PM_DBS2_DOWNGRADE)) { 3895 policy_mgr_err("Invalid action: %d", action); 3896 status = QDF_STATUS_SUCCESS; 3897 goto done; 3898 } 3899 3900 policy_mgr_debug("action:%d session id:%d", action, session_id); 3901 3902 /* Opportunistic timer is started, PM will check if MCC upgrade can be 3903 * done on timer expiry. This avoids any possible ping pong effect 3904 * as well. 3905 */ 3906 if (action == PM_SINGLE_MAC_UPGRADE) { 3907 qdf_status = policy_mgr_restart_opportunistic_timer( 3908 psoc, false); 3909 if (QDF_IS_STATUS_SUCCESS(qdf_status)) 3910 policy_mgr_debug("opportunistic timer for MCC upgrade"); 3911 goto done; 3912 } 3913 3914 /* For DBS, we want to move right away to DBS mode */ 3915 status = policy_mgr_next_actions(psoc, session_id, action, 3916 POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH, 3917 POLICY_MGR_DEF_REQ_ID); 3918 if (!QDF_IS_STATUS_SUCCESS(status)) { 3919 policy_mgr_err("no set hw mode command was issued"); 3920 goto done; 3921 } 3922 done: 3923 /* success must be returned only when a set hw mode was done */ 3924 return status; 3925 } 3926 3927 QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( 3928 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3929 uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) 3930 { 3931 QDF_STATUS status; 3932 struct policy_mgr_conc_connection_info info; 3933 uint8_t num_cxn_del = 0; 3934 struct policy_mgr_psoc_priv_obj *pm_ctx; 3935 enum policy_mgr_conc_next_action next_action = PM_NOP; 3936 bool eht_capab = false; 3937 3938 pm_ctx = policy_mgr_get_context(psoc); 3939 if (!pm_ctx) { 3940 policy_mgr_err("Invalid context"); 3941 return QDF_STATUS_E_FAILURE; 3942 } 3943 3944 wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab); 3945 if (eht_capab && 3946 policy_mgr_mode_specific_connection_count(psoc, 3947 PM_SAP_MODE, 3948 NULL) == 1) { 3949 policy_mgr_stop_opportunistic_timer(psoc); 3950 goto ch_width_update; 3951 } 3952 3953 if (!policy_mgr_is_hw_dbs_capable(psoc) || 3954 (!policy_mgr_is_hw_dbs_2x2_capable(psoc) && 3955 !policy_mgr_is_hw_dbs_required_for_band( 3956 psoc, HW_MODE_MAC_BAND_2G))) 3957 return QDF_STATUS_E_NOSUPPORT; 3958 3959 /* 3960 * Stop opportunistic timer as current connection info will change once 3961 * channel is switched and thus if required it will be started once 3962 * channel switch is completed. With new connection info. 3963 */ 3964 policy_mgr_stop_opportunistic_timer(psoc); 3965 3966 if (wlan_reg_freq_to_band(ch_freq) != REG_BAND_2G) 3967 return QDF_STATUS_E_NOSUPPORT; 3968 3969 ch_width_update: 3970 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3971 /* 3972 * Store the connection's parameter and temporarily delete it 3973 * from the concurrency table. This way the allow concurrency 3974 * check can be used as though a new connection is coming up, 3975 * after check, restore the connection to concurrency table. 3976 */ 3977 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, 3978 &info, &num_cxn_del); 3979 3980 status = policy_mgr_get_next_action(psoc, vdev_id, ch_freq, 3981 reason, &next_action); 3982 /* Restore the connection entry */ 3983 if (num_cxn_del) 3984 policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); 3985 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3986 3987 if (QDF_IS_STATUS_ERROR(status)) 3988 goto chk_opportunistic_timer; 3989 3990 if (PM_NOP != next_action) 3991 status = policy_mgr_next_actions(psoc, vdev_id, 3992 next_action, reason, 3993 POLICY_MGR_DEF_REQ_ID); 3994 else 3995 status = QDF_STATUS_E_NOSUPPORT; 3996 3997 chk_opportunistic_timer: 3998 /* 3999 * If hw mode change failed restart the opportunistic timer to 4000 * Switch to single mac if required. 4001 */ 4002 if (status == QDF_STATUS_E_FAILURE) { 4003 policy_mgr_err("Failed to update HW modeStatus %d", status); 4004 policy_mgr_check_n_start_opportunistic_timer(psoc); 4005 } 4006 4007 return status; 4008 } 4009 4010 void policy_mgr_checkn_update_hw_mode_single_mac_mode( 4011 struct wlan_objmgr_psoc *psoc, uint32_t ch_freq) 4012 { 4013 uint8_t i; 4014 struct policy_mgr_psoc_priv_obj *pm_ctx; 4015 bool dbs_required_2g; 4016 pm_ctx = policy_mgr_get_context(psoc); 4017 if (!pm_ctx) { 4018 policy_mgr_err("Invalid Context"); 4019 return; 4020 } 4021 4022 if (!policy_mgr_is_hw_dbs_capable(psoc)) 4023 return; 4024 4025 if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state) 4026 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); 4027 4028 dbs_required_2g = 4029 policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G); 4030 4031 if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { 4032 policy_mgr_debug("DBS required for new connection"); 4033 return; 4034 } 4035 4036 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4037 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 4038 if (pm_conc_connection_list[i].in_use) { 4039 if (!WLAN_REG_IS_SAME_BAND_FREQS( 4040 ch_freq, pm_conc_connection_list[i].freq) && 4041 (WLAN_REG_IS_24GHZ_CH_FREQ( 4042 pm_conc_connection_list[i].freq) || 4043 WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) { 4044 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4045 policy_mgr_debug("DBS required"); 4046 return; 4047 } 4048 if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ( 4049 pm_conc_connection_list[i].freq)) { 4050 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4051 policy_mgr_debug("DBS required"); 4052 return; 4053 } 4054 } 4055 } 4056 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4057 pm_dbs_opportunistic_timer_handler((void *)psoc); 4058 } 4059 4060 void policy_mgr_check_and_stop_opportunistic_timer( 4061 struct wlan_objmgr_psoc *psoc, uint8_t id) 4062 { 4063 struct policy_mgr_psoc_priv_obj *pm_ctx; 4064 enum policy_mgr_conc_next_action action = PM_NOP; 4065 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4066 enum policy_mgr_conn_update_reason reason = 4067 POLICY_MGR_UPDATE_REASON_MAX; 4068 4069 pm_ctx = policy_mgr_get_context(psoc); 4070 if (!pm_ctx) { 4071 policy_mgr_err("Invalid Context"); 4072 return; 4073 } 4074 if (QDF_TIMER_STATE_RUNNING == 4075 pm_ctx->dbs_opportunistic_timer.state) { 4076 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); 4077 action = policy_mgr_need_opportunistic_upgrade(psoc, &reason); 4078 if (action) { 4079 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt); 4080 status = policy_mgr_next_actions(psoc, id, action, 4081 reason, 4082 POLICY_MGR_DEF_REQ_ID); 4083 if (status != QDF_STATUS_SUCCESS) { 4084 policy_mgr_err("Failed in policy_mgr_next_actions"); 4085 return; 4086 } 4087 status = qdf_wait_single_event( 4088 &pm_ctx->opportunistic_update_done_evt, 4089 CONNECTION_UPDATE_TIMEOUT); 4090 4091 if (!QDF_IS_STATUS_SUCCESS(status)) { 4092 policy_mgr_err("wait for event failed"); 4093 return; 4094 } 4095 } 4096 } 4097 } 4098 4099 void policy_mgr_set_hw_mode_change_in_progress( 4100 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value) 4101 { 4102 struct policy_mgr_psoc_priv_obj *pm_ctx; 4103 4104 pm_ctx = policy_mgr_get_context(psoc); 4105 if (!pm_ctx) { 4106 policy_mgr_err("Invalid Context"); 4107 return; 4108 } 4109 4110 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4111 pm_ctx->hw_mode_change_in_progress = value; 4112 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4113 4114 policy_mgr_debug("hw_mode_change_in_progress:%d", value); 4115 } 4116 4117 enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress( 4118 struct wlan_objmgr_psoc *psoc) 4119 { 4120 enum policy_mgr_hw_mode_change value; 4121 struct policy_mgr_psoc_priv_obj *pm_ctx; 4122 4123 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; 4124 4125 pm_ctx = policy_mgr_get_context(psoc); 4126 if (!pm_ctx) { 4127 policy_mgr_err("Invalid Context"); 4128 return value; 4129 } 4130 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4131 value = pm_ctx->hw_mode_change_in_progress; 4132 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4133 4134 return value; 4135 } 4136 4137 enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( 4138 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index) 4139 { 4140 struct policy_mgr_psoc_priv_obj *pm_ctx; 4141 struct policy_mgr_hw_mode_params hw_mode; 4142 enum policy_mgr_hw_mode_change value 4143 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; 4144 QDF_STATUS status; 4145 4146 pm_ctx = policy_mgr_get_context(psoc); 4147 if (!pm_ctx) { 4148 policy_mgr_err("Invalid Context"); 4149 return value; 4150 } 4151 4152 status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode); 4153 if (status != QDF_STATUS_SUCCESS) { 4154 policy_mgr_err("Failed to get HW mode index"); 4155 return value; 4156 } 4157 4158 if (hw_mode.dbs_cap) { 4159 policy_mgr_debug("DBS is requested with HW (%d)", 4160 hw_mode_index); 4161 value = POLICY_MGR_DBS_IN_PROGRESS; 4162 goto ret_value; 4163 } 4164 4165 if (hw_mode.sbs_cap) { 4166 policy_mgr_debug("SBS is requested with HW (%d)", 4167 hw_mode_index); 4168 value = POLICY_MGR_SBS_IN_PROGRESS; 4169 goto ret_value; 4170 } 4171 4172 value = POLICY_MGR_SMM_IN_PROGRESS; 4173 policy_mgr_debug("SMM is requested with HW (%d)", hw_mode_index); 4174 4175 ret_value: 4176 return value; 4177 } 4178 4179 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES 4180 bool 4181 policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc, 4182 struct wlan_objmgr_vdev *vdev, 4183 qdf_freq_t *ch_freq) 4184 { 4185 struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 4186 uint8_t connection_count, i, j, sta_vdev_id; 4187 4188 *ch_freq = 0; 4189 /* 4190 * TDLS off channel is not allowed in any MCC scenario 4191 */ 4192 if (policy_mgr_current_concurrency_is_mcc(psoc)) { 4193 policy_mgr_dump_current_concurrency(psoc); 4194 policy_mgr_debug("TDLS off channel not allowed in MCC"); 4195 return false; 4196 } 4197 4198 /* 4199 * TDLS offchannel is done only when STA is connected on 2G channel and 4200 * the current concurrency is not MCC 4201 */ 4202 if (!policy_mgr_is_sta_connected_2g(psoc)) { 4203 policy_mgr_debug("STA not-connected on 2.4 Ghz"); 4204 return false; 4205 } 4206 4207 /* 4208 * 2 Port DBS scenario - Allow non-STA vdev channel for 4209 * TDLS off-channel operation 4210 * 4211 * 3 Port Scenario - If STA Vdev is on SCC, allow TDLS off-channel on 4212 * the channel of vdev on the other MAC 4213 * If STA vdev is standalone on one mac, and scc on another mac, then 4214 * allow TDLS off channel on other mac scc channel 4215 */ 4216 sta_vdev_id = wlan_vdev_get_id(vdev); 4217 connection_count = policy_mgr_get_connection_info(psoc, info); 4218 switch (connection_count) { 4219 case 1: 4220 return true; 4221 case 2: 4222 /* 4223 * Allow all the 5GHz/6GHz channels when STA is in SCC 4224 */ 4225 if (policy_mgr_current_concurrency_is_scc(psoc)) { 4226 *ch_freq = 0; 4227 return true; 4228 } else if (policy_mgr_is_current_hwmode_dbs(psoc)) { 4229 /* 4230 * In DBS case, allow off-channel operation on the 4231 * other mac 5GHz/6GHz channel where the STA is not 4232 * present 4233 * Don't consider SBS case since STA should be 4234 * connected in 2.4GHz channel for TDLS 4235 * off-channel and MCC on SBS ex. 3 PORT 4236 * 2.4GHz STA + 5GHz Lower MCC + 5GHz Upper will 4237 * not be allowed 4238 */ 4239 if (sta_vdev_id == info[0].vdev_id) 4240 *ch_freq = info[1].ch_freq; 4241 else 4242 *ch_freq = info[0].ch_freq; 4243 4244 return true; 4245 } 4246 4247 break; 4248 case 3: 4249 4250 /* 4251 * 3 Vdev SCC on 2.4GHz band. Allow TDLS off-channel operation 4252 * on all the 5GHz & 6GHz channels 4253 */ 4254 if (info[0].ch_freq == info[1].ch_freq && 4255 info[0].ch_freq == info[2].ch_freq) { 4256 *ch_freq = 0; 4257 return true; 4258 } 4259 4260 /* 4261 * DBS with SCC on one vdev scenario. Allow TDLS off-channel 4262 * on other mac frequency where STA is not present 4263 * SBS case is not considered since STA should be connected 4264 * on 2.4GHz and TDLS off-channel on SBS MCC is not allowed 4265 */ 4266 for (i = 0; i < connection_count; i++) { 4267 for (j = i + 1; j < connection_count; j++) { 4268 /* 4269 * Find 2 vdevs such that STA is one of the vdev 4270 * and STA + other vdev are not on same mac. 4271 * Return the foreign vdev frequency which is 4272 * not on same mac along with STA 4273 */ 4274 if (!policy_mgr_2_freq_always_on_same_mac( 4275 psoc, info[i].ch_freq, 4276 info[j].ch_freq)) { 4277 if (sta_vdev_id == info[i].vdev_id) { 4278 *ch_freq = info[j].ch_freq; 4279 return true; 4280 } else if (sta_vdev_id == 4281 info[j].vdev_id) { 4282 *ch_freq = info[i].ch_freq; 4283 return true; 4284 } 4285 } 4286 } 4287 } 4288 4289 return false; 4290 default: 4291 policy_mgr_debug("TDLS off channel not allowed on > 3 port conc"); 4292 break; 4293 } 4294 4295 return false; 4296 } 4297 #endif 4298