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