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 bool go_5g_present = 0; 1843 qdf_freq_t user_config_freq = 0; 1844 tQDF_MCC_TO_SCC_SWITCH_MODE cc_mode = 1845 policy_mgr_get_mcc_to_scc_switch_mode(psoc); 1846 1847 if (intf_ch_freq) 1848 *intf_ch_freq = 0; 1849 1850 pm_ctx = policy_mgr_get_context(psoc); 1851 if (!pm_ctx) { 1852 policy_mgr_err("Invalid pm context"); 1853 return false; 1854 } 1855 1856 policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value); 1857 1858 if (!policy_mgr_is_hw_dbs_capable(psoc)) 1859 if (policy_mgr_get_connection_count(psoc) > 1) 1860 return false; 1861 1862 cc_count = policy_mgr_get_mode_specific_conn_info(psoc, 1863 &op_ch_freq_list[0], 1864 &vdev_id[0], 1865 PM_SAP_MODE); 1866 go_index_start = cc_count; 1867 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) 1868 cc_count += policy_mgr_get_mode_specific_conn_info( 1869 psoc, &op_ch_freq_list[cc_count], 1870 &vdev_id[cc_count], PM_P2P_GO_MODE); 1871 1872 for (i = go_index_start ; i < cc_count; i++) { 1873 if (!WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i])) { 1874 go_5g_present = true; 1875 break; 1876 } 1877 } 1878 1879 sta_gc_present = 1880 policy_mgr_mode_specific_connection_count(psoc, 1881 PM_STA_MODE, NULL) + 1882 policy_mgr_mode_specific_connection_count(psoc, 1883 PM_P2P_CLIENT_MODE, 1884 NULL); 1885 1886 for (i = 0 ; i < cc_count; i++) { 1887 if (sap_vdev_id != INVALID_VDEV_ID && 1888 sap_vdev_id != vdev_id[i]) 1889 continue; 1890 1891 sap_vdev_id = vdev_id[i]; 1892 user_config_freq = 1893 policy_mgr_get_user_config_sap_freq(psoc, sap_vdev_id); 1894 1895 if (policy_mgr_is_any_mode_active_on_band_along_with_session( 1896 psoc, vdev_id[i], 1897 WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) ? 1898 POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5)) 1899 continue; 1900 1901 if (sta_sap_scc_on_dfs_chan && 1902 (sta_sap_scc_on_dfs_chnl_config_value != 2) && 1903 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, 1904 op_ch_freq_list[i]) && 1905 pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) { 1906 curr_sap_freq = op_ch_freq_list[i]; 1907 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, dfs sap_ch_freq %u", 1908 sta_sap_scc_on_dfs_chan, 1909 sta_sap_scc_on_dfs_chnl_config_value, 1910 curr_sap_freq); 1911 break; 1912 } 1913 1914 if ((is_acs_mode || 1915 policy_mgr_restrict_sap_on_unsafe_chan(psoc)) && 1916 sta_sap_scc_on_lte_coex_chan && 1917 !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i]) && 1918 pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) { 1919 curr_sap_freq = op_ch_freq_list[i]; 1920 policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_ch_freq %u", 1921 sta_sap_scc_on_lte_coex_chan, 1922 curr_sap_freq); 1923 break; 1924 } 1925 /* When STA+SAP SCC is allowed on indoor channel, 1926 * Restart the SAP when : 1927 * 1. The user configured SAP frequency is not 1928 * the same as current freq. (or) 1929 * 2. The frequency is not allowed in the indoor 1930 * channel. 1931 */ 1932 if (pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i] && 1933 !policy_mgr_is_sap_go_interface_allowed_on_indoor( 1934 pm_ctx->pdev, 1935 sap_vdev_id, 1936 op_ch_freq_list[i])) { 1937 curr_sap_freq = op_ch_freq_list[i]; 1938 policy_mgr_debug("indoor sap_ch_freq %u", 1939 curr_sap_freq); 1940 break; 1941 } 1942 1943 /* 1944 * STA got disconnected & SAP has previously moved to 2.4 GHz 1945 * due to concurrency, then move SAP back to user configured 1946 * frequency. 1947 * if SCC to MCC switch mode is 1948 * QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL, then move SAP to 1949 * user configured frequency whenever standalone SAP is 1950 * currently not on the user configured frequency. 1951 * else move the SAP only when SAP is on 2.4 GHz band and user 1952 * configured frequency is on any other bands. 1953 * And for QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL, if GO 1954 * is on 5/6 GHz, SAP is not allowed to move back to 5/6 GHz. 1955 * If GO is not present on 5/6 GHz, SAP need to moved to 1956 * user configured frequency. 1957 */ 1958 if (!sta_gc_present && user_config_freq && 1959 cc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL && 1960 !wlan_reg_is_same_band_freqs(user_config_freq, 1961 op_ch_freq_list[i])) { 1962 if (go_5g_present && 1963 !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) 1964 continue; 1965 curr_sap_freq = op_ch_freq_list[i]; 1966 policy_mgr_debug("Move sap to user configured freq: %d", 1967 user_config_freq); 1968 break; 1969 } else if (!sta_gc_present && user_config_freq && 1970 WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) && 1971 !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) { 1972 curr_sap_freq = op_ch_freq_list[i]; 1973 policy_mgr_debug("Move sap to user configured freq: %d", 1974 user_config_freq); 1975 break; 1976 } 1977 } 1978 1979 if (!curr_sap_freq) { 1980 policy_mgr_debug("SAP restart is not required"); 1981 return false; 1982 } 1983 1984 mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE; 1985 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 1986 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, 1987 &info, &num_cxn_del); 1988 1989 /* Add the user config ch as first condidate */ 1990 pcl_channels[0] = user_config_freq; 1991 pcl_weight[0] = 0; 1992 status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len, 1993 &pcl_weight[1], 1994 QDF_ARRAY_SIZE(pcl_weight) - 1, 1995 sap_vdev_id); 1996 if (status == QDF_STATUS_SUCCESS) 1997 pcl_len++; 1998 else 1999 pcl_len = 1; 2000 2001 2002 for (i = 0; i < pcl_len; i++) { 2003 if (pcl_channels[i] == curr_sap_freq) 2004 continue; 2005 2006 if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) || 2007 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i])) 2008 continue; 2009 2010 /* SAP moved to 2.4 GHz, due to STA on DFS or Indoor where 2011 * concurrency is not allowed, now that there is no 2012 * STA/GC in 5 GHz band, move 2.4 GHz SAP to 5 GHz band if SAP 2013 * was initially started on 5 GHz band. 2014 * Checking again here as pcl_channels[0] could be 2015 * on indoor which is not removed in policy_mgr_get_pcl 2016 */ 2017 if (!sta_gc_present && 2018 !policy_mgr_is_sap_go_interface_allowed_on_indoor( 2019 pm_ctx->pdev, 2020 sap_vdev_id, 2021 pcl_channels[i])) { 2022 policy_mgr_debug("Do not allow SAP on indoor frequency, STA is absent"); 2023 continue; 2024 } 2025 2026 new_sap_freq = pcl_channels[i]; 2027 break; 2028 } 2029 2030 /* Restore the connection entry */ 2031 if (num_cxn_del > 0) 2032 policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); 2033 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2034 2035 if (new_sap_freq == 0 || curr_sap_freq == new_sap_freq) 2036 return false; 2037 if (!intf_ch_freq) 2038 return true; 2039 2040 *intf_ch_freq = new_sap_freq; 2041 policy_mgr_debug("Standalone SAP(vdev_id %d) will be moved to channel %u", 2042 sap_vdev_id, *intf_ch_freq); 2043 2044 return true; 2045 } 2046 2047 /** 2048 * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is 2049 * allowed in LTE COEX unsafe ch 2050 * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context 2051 * @ch_freq: Channel frequency to check 2052 * 2053 * Return: True if allowed else false 2054 */ 2055 static bool 2056 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj 2057 *pm_ctx, uint32_t ch_freq) 2058 { 2059 if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch_freq) || 2060 pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl) 2061 return true; 2062 2063 return false; 2064 } 2065 2066 /** 2067 * policy_mgr_nan_disable_work() - qdf defer function wrapper for NAN disable 2068 * @data: qdf_work data 2069 * 2070 * Return: None 2071 */ 2072 static void policy_mgr_nan_disable_work(void *data) 2073 { 2074 struct wlan_objmgr_psoc *psoc = data; 2075 2076 ucfg_nan_disable_concurrency(psoc); 2077 } 2078 2079 bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, 2080 uint32_t sap_freq) 2081 { 2082 uint32_t nan_2g_freq, nan_5g_freq; 2083 struct policy_mgr_psoc_priv_obj *pm_ctx; 2084 2085 pm_ctx = policy_mgr_get_context(psoc); 2086 if (!pm_ctx) { 2087 policy_mgr_err("Invalid Context"); 2088 return false; 2089 } 2090 2091 nan_2g_freq = policy_mgr_mode_specific_get_channel(psoc, 2092 PM_NAN_DISC_MODE); 2093 if (nan_2g_freq == 0) { 2094 policy_mgr_debug("No NAN+SAP SCC"); 2095 return false; 2096 } 2097 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc); 2098 2099 policy_mgr_debug("Freq SAP: %d NAN: %d %d", sap_freq, 2100 nan_2g_freq, nan_5g_freq); 2101 if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq)) { 2102 if (policy_mgr_is_force_scc(pm_ctx->psoc) && 2103 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, 2104 nan_2g_freq)) 2105 return true; 2106 } else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) { 2107 if (policy_mgr_is_force_scc(pm_ctx->psoc) && 2108 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, 2109 nan_5g_freq)) 2110 return true; 2111 } else { 2112 /* 2113 * NAN + SAP in different bands. Continue to check for 2114 * SAP in unsafe channel 2115 */ 2116 return false; 2117 } 2118 policy_mgr_info("NAN+SAP unsafe ch SCC not allowed. Disabling NAN"); 2119 /* change context to worker since this is executed in sched thread ctx*/ 2120 qdf_create_work(0, &pm_ctx->nan_sap_conc_work, 2121 policy_mgr_nan_disable_work, psoc); 2122 qdf_sched_work(0, &pm_ctx->nan_sap_conc_work); 2123 2124 return false; 2125 } 2126 2127 bool 2128 policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, 2129 enum policy_mgr_con_mode mode, 2130 uint32_t ch_freq) 2131 { 2132 struct policy_mgr_psoc_priv_obj *pm_ctx; 2133 uint32_t sap_freq, nan_2g_freq, nan_5g_freq; 2134 2135 pm_ctx = policy_mgr_get_context(psoc); 2136 if (!pm_ctx) { 2137 policy_mgr_err("Invalid Context"); 2138 return false; 2139 } 2140 2141 if (!policy_mgr_is_sap_mode(mode) || mode == PM_NAN_DISC_MODE) { 2142 policy_mgr_debug("Not NAN or SAP mode"); 2143 return true; 2144 } 2145 2146 if (!ch_freq) { 2147 policy_mgr_err("Invalid channel"); 2148 return false; 2149 } 2150 2151 if (!wlan_nan_get_sap_conc_support(pm_ctx->psoc)) { 2152 policy_mgr_debug("NAN+SAP not supported in fw"); 2153 /* Reject NAN as SAP is of high priority */ 2154 if (mode == PM_NAN_DISC_MODE) 2155 return false; 2156 /* Before SAP start disable NAN */ 2157 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2158 return true; 2159 } 2160 2161 if (mode == PM_NAN_DISC_MODE) { 2162 sap_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc, 2163 PM_SAP_MODE); 2164 policy_mgr_debug("FREQ SAP: %d NAN: %d", sap_freq, ch_freq); 2165 if (!sap_freq) { 2166 sap_freq = policy_mgr_mode_specific_get_channel( 2167 pm_ctx->psoc, 2168 PM_LL_LT_SAP_MODE); 2169 policy_mgr_debug("FREQ LL_LT_SAP: %d NAN: %d", 2170 sap_freq, ch_freq); 2171 } 2172 if (ucfg_is_nan_dbs_supported(pm_ctx->psoc) && 2173 !WLAN_REG_IS_SAME_BAND_FREQS(sap_freq, ch_freq)) 2174 return true; 2175 2176 if (sap_freq == ch_freq) { 2177 policy_mgr_debug("NAN+SAP SCC"); 2178 return true; 2179 } 2180 2181 if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { 2182 policy_mgr_debug("SAP force SCC disabled"); 2183 return false; 2184 } 2185 if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( 2186 pm_ctx, ch_freq)) { 2187 policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); 2188 return false; 2189 } 2190 if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && 2191 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) { 2192 policy_mgr_debug("DFS CAC in progress, reject NAN enable"); 2193 return false; 2194 } 2195 } else if (policy_mgr_is_sap_mode(mode)) { 2196 nan_2g_freq = 2197 policy_mgr_mode_specific_get_channel(pm_ctx->psoc, 2198 PM_NAN_DISC_MODE); 2199 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc); 2200 policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch_freq, 2201 nan_2g_freq, nan_5g_freq); 2202 if (ucfg_is_nan_conc_control_supported(pm_ctx->psoc) && 2203 !ucfg_is_nan_dbs_supported(pm_ctx->psoc) && 2204 !WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq)) { 2205 if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { 2206 policy_mgr_debug("NAN and SAP are in different bands but SAP force SCC disabled"); 2207 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2208 return true; 2209 } 2210 } else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) || 2211 WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)) { 2212 if (ch_freq == nan_2g_freq || ch_freq == nan_5g_freq) { 2213 policy_mgr_debug("NAN+SAP SCC"); 2214 return true; 2215 } 2216 if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { 2217 policy_mgr_debug("SAP force SCC disabled"); 2218 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2219 return true; 2220 } 2221 if ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && 2222 !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( 2223 pm_ctx, nan_5g_freq)) || 2224 (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && 2225 !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( 2226 pm_ctx, nan_2g_freq))) { 2227 policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); 2228 ucfg_nan_disable_concurrency(pm_ctx->psoc); 2229 return true; 2230 } 2231 } 2232 } 2233 return true; 2234 } 2235 2236 QDF_STATUS 2237 policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc) 2238 { 2239 struct policy_mgr_psoc_priv_obj *pm_ctx; 2240 struct policy_mgr_conc_connection_info *sap_info = NULL; 2241 uint8_t i; 2242 qdf_freq_t nan_freq_2g, nan_freq_5g; 2243 QDF_STATUS status = QDF_STATUS_SUCCESS; 2244 2245 pm_ctx = policy_mgr_get_context(psoc); 2246 if (!pm_ctx) { 2247 policy_mgr_err("Invalid pm context"); 2248 return QDF_STATUS_E_INVAL; 2249 } 2250 2251 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 2252 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 2253 if (policy_mgr_is_sap_mode(pm_conc_connection_list[i].mode) && 2254 pm_conc_connection_list[i].in_use) { 2255 sap_info = &pm_conc_connection_list[i]; 2256 break; 2257 } 2258 } 2259 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2260 2261 if (!sap_info) 2262 goto end; 2263 if (sap_info->freq == 0) 2264 goto end; 2265 nan_freq_2g = policy_mgr_mode_specific_get_channel(psoc, 2266 PM_NAN_DISC_MODE); 2267 nan_freq_5g = wlan_nan_get_disc_5g_ch_freq(psoc); 2268 if (sap_info->freq == nan_freq_2g || sap_info->freq == nan_freq_5g) { 2269 policy_mgr_debug("NAN and SAP already in SCC"); 2270 goto end; 2271 } 2272 if (nan_freq_2g == 0) 2273 goto end; 2274 2275 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2276 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2277 policy_mgr_debug("channel switch is already in progress"); 2278 return status; 2279 } 2280 2281 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 2282 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc, 2283 sap_info->vdev_id, 2284 CSA_REASON_CONCURRENT_NAN_EVENT); 2285 2286 /* SAP should be moved to 2g NAN channel on non-DBS platforms */ 2287 if (!ucfg_is_nan_dbs_supported(pm_ctx->psoc) || 2288 WLAN_REG_IS_24GHZ_CH_FREQ(sap_info->freq)) { 2289 policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d", 2290 nan_freq_2g); 2291 status = 2292 policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, 2293 nan_freq_2g, 2294 policy_mgr_get_ch_width( 2295 sap_info->bw), 2296 true); 2297 if (status == QDF_STATUS_SUCCESS) 2298 status = QDF_STATUS_E_PENDING; 2299 } else if (nan_freq_5g && WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq)) { 2300 policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d", 2301 nan_freq_5g); 2302 status = 2303 policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, 2304 nan_freq_5g, 2305 policy_mgr_get_ch_width( 2306 sap_info->bw), 2307 true); 2308 if (status == QDF_STATUS_SUCCESS) 2309 status = QDF_STATUS_E_PENDING; 2310 } 2311 2312 end: 2313 pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = false; 2314 2315 return status; 2316 } 2317 2318 void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc) 2319 { 2320 struct policy_mgr_psoc_priv_obj *pm_ctx; 2321 struct policy_mgr_conc_connection_info *sap_info = NULL; 2322 uint32_t sap_freq = 0, i; 2323 QDF_STATUS status; 2324 uint32_t user_config_freq; 2325 uint8_t band_mask = 0; 2326 uint8_t chn_idx, num_chan; 2327 struct regulatory_channel *channel_list; 2328 2329 pm_ctx = policy_mgr_get_context(psoc); 2330 if (!pm_ctx) { 2331 policy_mgr_err("Invalid pm context"); 2332 return; 2333 } 2334 2335 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 2336 if (pm_conc_connection_list[i].mode == PM_SAP_MODE && 2337 pm_conc_connection_list[i].in_use) { 2338 sap_info = &pm_conc_connection_list[i]; 2339 sap_freq = sap_info->freq; 2340 break; 2341 } 2342 } 2343 if (sap_freq == 0 || policy_mgr_is_safe_channel(psoc, sap_freq)) 2344 return; 2345 2346 user_config_freq = policy_mgr_get_user_config_sap_freq( 2347 psoc, sap_info->vdev_id); 2348 2349 sap_freq = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE, 2350 false, 2351 sap_info->vdev_id); 2352 policy_mgr_debug("User/ACS orig Freq: %d New SAP Freq: %d", 2353 user_config_freq, sap_freq); 2354 2355 if (wlan_reg_is_enable_in_secondary_list_for_freq(pm_ctx->pdev, 2356 user_config_freq) && 2357 policy_mgr_is_safe_channel(psoc, user_config_freq)) { 2358 policy_mgr_debug("Give preference to user config freq"); 2359 sap_freq = user_config_freq; 2360 } else { 2361 channel_list = qdf_mem_malloc( 2362 sizeof(struct regulatory_channel) * 2363 NUM_CHANNELS); 2364 if (!channel_list) 2365 return; 2366 2367 band_mask |= BIT(wlan_reg_freq_to_band(user_config_freq)); 2368 num_chan = wlan_reg_get_band_channel_list_for_pwrmode( 2369 pm_ctx->pdev, 2370 band_mask, 2371 channel_list, 2372 REG_CURRENT_PWR_MODE); 2373 for (chn_idx = 0; chn_idx < num_chan; chn_idx++) { 2374 if (wlan_reg_is_enable_in_secondary_list_for_freq( 2375 pm_ctx->pdev, 2376 channel_list[chn_idx].center_freq) && 2377 policy_mgr_is_safe_channel( 2378 psoc, 2379 channel_list[chn_idx].center_freq)) { 2380 policy_mgr_debug("Prefer user config band freq %d", 2381 channel_list[chn_idx].center_freq); 2382 sap_freq = channel_list[chn_idx].center_freq; 2383 } 2384 } 2385 qdf_mem_free(channel_list); 2386 } 2387 2388 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2389 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2390 policy_mgr_debug("wait as channel switch is already in progress"); 2391 status = qdf_wait_single_event( 2392 &pm_ctx->channel_switch_complete_evt, 2393 CHANNEL_SWITCH_COMPLETE_TIMEOUT); 2394 if (QDF_IS_STATUS_ERROR(status)) 2395 policy_mgr_err("wait for event failed, still continue with channel switch"); 2396 } 2397 2398 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 2399 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( 2400 psoc, sap_info->vdev_id, 2401 CSA_REASON_CONCURRENT_NAN_EVENT); 2402 2403 policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, 2404 sap_freq, 2405 policy_mgr_get_ch_width( 2406 sap_info->bw), true); 2407 } 2408 2409 void policy_mgr_check_sap_restart(struct wlan_objmgr_psoc *psoc, 2410 uint8_t vdev_id) 2411 { 2412 QDF_STATUS status; 2413 uint32_t ch_freq; 2414 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; 2415 2416 if (!psoc) { 2417 policy_mgr_err("Invalid psoc"); 2418 return; 2419 } 2420 pm_ctx = policy_mgr_get_context(psoc); 2421 if (!pm_ctx) { 2422 policy_mgr_err("Invalid context"); 2423 return; 2424 } 2425 2426 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2427 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2428 policy_mgr_debug("channel switch is already in progress"); 2429 return; 2430 } 2431 2432 /* 2433 * Restart should be handled by sap_fsm_validate_and_change_channel(), 2434 * after SAP starts. 2435 */ 2436 if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && 2437 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) { 2438 policy_mgr_debug("DFS CAC in progress, do not restart SAP"); 2439 return; 2440 } 2441 2442 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { 2443 policy_mgr_err("SAP restart get channel callback in NULL"); 2444 goto end; 2445 } 2446 status = 2447 pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart(psoc, 2448 vdev_id, 2449 &ch_freq); 2450 if (status == QDF_STATUS_SUCCESS) 2451 policy_mgr_debug("SAP vdev id %d switch to new ch freq: %d", 2452 vdev_id, ch_freq); 2453 2454 end: 2455 pm_ctx->last_disconn_sta_freq = 0; 2456 } 2457 2458 /** 2459 * policy_mgr_handle_sap_plus_go_force_scc() - Do SAP/GO force SCC 2460 * @psoc: soc object 2461 * 2462 * This function will check SAP/GO channel state and select channel 2463 * to avoid MCC, then do channel change on the second interface. 2464 * 2465 * Return: QDF_STATUS_SUCCESS if successfully handle the SAP/GO 2466 * force SCC. 2467 */ 2468 static QDF_STATUS 2469 policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc *psoc) 2470 { 2471 QDF_STATUS status = QDF_STATUS_E_INVAL; 2472 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 2473 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 2474 enum policy_mgr_con_mode vdev_con_mode; 2475 uint32_t existing_ch_freq, chan_freq, intf_ch_freq; 2476 enum phy_ch_width existing_ch_width; 2477 uint8_t vdev_id; 2478 struct policy_mgr_psoc_priv_obj *pm_ctx; 2479 struct sta_ap_intf_check_work_ctx *work_info; 2480 struct ch_params ch_params = {0}; 2481 enum QDF_OPMODE opmode; 2482 2483 pm_ctx = policy_mgr_get_context(psoc); 2484 if (!pm_ctx) { 2485 policy_mgr_err("Invalid Context"); 2486 return status; 2487 } 2488 2489 work_info = pm_ctx->sta_ap_intf_check_work_info; 2490 if (!work_info) { 2491 policy_mgr_err("invalid work info"); 2492 return status; 2493 } 2494 if (work_info->sap_plus_go_force_scc.reason == CSA_REASON_UNKNOWN) 2495 return status; 2496 2497 vdev_id = work_info->sap_plus_go_force_scc.initiator_vdev_id; 2498 chan_freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id); 2499 opmode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id); 2500 vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode, 2501 vdev_id); 2502 2503 existing_vdev_id = 2504 policy_mgr_fetch_existing_con_info( 2505 psoc, 2506 vdev_id, 2507 chan_freq, 2508 &existing_vdev_mode, 2509 &existing_ch_freq, &existing_ch_width); 2510 policy_mgr_debug("initiator vdev %d mode %d freq %d, existing vdev %d mode %d freq %d reason %d", 2511 vdev_id, vdev_con_mode, chan_freq, existing_vdev_id, 2512 existing_vdev_mode, existing_ch_freq, 2513 work_info->sap_plus_go_force_scc.reason); 2514 2515 if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX) 2516 goto force_scc_done; 2517 2518 if (!((vdev_con_mode == PM_P2P_GO_MODE && 2519 existing_vdev_mode == PM_SAP_MODE) || 2520 (vdev_con_mode == PM_SAP_MODE && 2521 existing_vdev_mode == PM_P2P_GO_MODE))) 2522 goto force_scc_done; 2523 2524 if (!pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb) 2525 goto force_scc_done; 2526 2527 intf_ch_freq = 0; 2528 status = pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb(psoc, 2529 existing_vdev_id, 2530 &intf_ch_freq); 2531 policy_mgr_debug("vdev %d freq %d intf %d status %d", 2532 existing_vdev_id, existing_ch_freq, 2533 intf_ch_freq, status); 2534 if (QDF_IS_STATUS_ERROR(status)) 2535 goto force_scc_done; 2536 if (!intf_ch_freq || intf_ch_freq == existing_ch_freq) 2537 goto force_scc_done; 2538 2539 ch_params.ch_width = existing_ch_width; 2540 if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) { 2541 status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 2542 psoc, existing_vdev_id, intf_ch_freq, &ch_params); 2543 if (QDF_IS_STATUS_ERROR(status)) 2544 policy_mgr_debug("no candidate valid bw for vdev %d intf %d", 2545 existing_vdev_id, intf_ch_freq); 2546 } 2547 2548 status = policy_mgr_valid_sap_conc_channel_check( 2549 psoc, &intf_ch_freq, existing_ch_freq, existing_vdev_id, 2550 &ch_params); 2551 if (QDF_IS_STATUS_ERROR(status)) { 2552 policy_mgr_err("warning no candidate freq for vdev %d freq %d intf %d", 2553 existing_vdev_id, existing_ch_freq, 2554 intf_ch_freq); 2555 goto force_scc_done; 2556 } 2557 2558 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 2559 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( 2560 psoc, existing_vdev_id, 2561 work_info->sap_plus_go_force_scc.reason); 2562 2563 status = policy_mgr_change_sap_channel_with_csa( 2564 psoc, existing_vdev_id, intf_ch_freq, 2565 ch_params.ch_width, true); 2566 if (QDF_IS_STATUS_ERROR(status)) { 2567 policy_mgr_err("warning sap/go vdev %d freq %d intf %d csa failed", 2568 existing_vdev_id, existing_ch_freq, 2569 intf_ch_freq); 2570 } 2571 2572 force_scc_done: 2573 work_info->sap_plus_go_force_scc.reason = CSA_REASON_UNKNOWN; 2574 work_info->sap_plus_go_force_scc.initiator_vdev_id = 2575 WLAN_UMAC_VDEV_ID_MAX; 2576 work_info->sap_plus_go_force_scc.responder_vdev_id = 2577 WLAN_UMAC_VDEV_ID_MAX; 2578 2579 return status; 2580 } 2581 2582 QDF_STATUS 2583 policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc, 2584 struct wlan_objmgr_vdev *vdev, 2585 enum sap_csa_reason_code reason_code) 2586 { 2587 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 2588 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 2589 enum policy_mgr_con_mode vdev_con_mode; 2590 uint32_t con_freq, chan_freq; 2591 enum phy_ch_width ch_width; 2592 uint8_t vdev_id; 2593 struct policy_mgr_psoc_priv_obj *pm_ctx; 2594 struct sta_ap_intf_check_work_ctx *work_info; 2595 enum QDF_OPMODE opmode; 2596 2597 if (reason_code != CSA_REASON_GO_BSS_STARTED && 2598 reason_code != CSA_REASON_USER_INITIATED) 2599 return QDF_STATUS_SUCCESS; 2600 2601 pm_ctx = policy_mgr_get_context(psoc); 2602 if (!pm_ctx) { 2603 policy_mgr_err("Invalid Context"); 2604 return QDF_STATUS_E_INVAL; 2605 } 2606 if (pm_ctx->cfg.mcc_to_scc_switch == 2607 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) 2608 return QDF_STATUS_SUCCESS; 2609 2610 if (!vdev) { 2611 policy_mgr_err("vdev is null"); 2612 return QDF_STATUS_E_INVAL; 2613 } 2614 vdev_id = wlan_vdev_get_id(vdev); 2615 opmode = wlan_vdev_mlme_get_opmode(vdev); 2616 work_info = pm_ctx->sta_ap_intf_check_work_info; 2617 if (!work_info) { 2618 policy_mgr_err("invalid work info"); 2619 return QDF_STATUS_E_INVAL; 2620 } 2621 2622 chan_freq = wlan_get_operation_chan_freq(vdev); 2623 vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode, 2624 vdev_id); 2625 2626 existing_vdev_id = 2627 policy_mgr_fetch_existing_con_info(psoc, 2628 vdev_id, 2629 chan_freq, 2630 &existing_vdev_mode, 2631 &con_freq, &ch_width); 2632 if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX) 2633 return QDF_STATUS_SUCCESS; 2634 2635 if (!((vdev_con_mode == PM_P2P_GO_MODE && 2636 existing_vdev_mode == PM_SAP_MODE) || 2637 (vdev_con_mode == PM_SAP_MODE && 2638 existing_vdev_mode == PM_P2P_GO_MODE))) 2639 return QDF_STATUS_SUCCESS; 2640 2641 work_info->sap_plus_go_force_scc.reason = reason_code; 2642 work_info->sap_plus_go_force_scc.initiator_vdev_id = vdev_id; 2643 work_info->sap_plus_go_force_scc.responder_vdev_id = existing_vdev_id; 2644 2645 policy_mgr_debug("initiator vdev %d freq %d, existing vdev %d freq %d reason %d", 2646 vdev_id, chan_freq, existing_vdev_id, 2647 con_freq, reason_code); 2648 2649 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2650 WAIT_BEFORE_GO_FORCESCC_RESTART)) 2651 policy_mgr_debug("change interface request already queued"); 2652 2653 return QDF_STATUS_E_PENDING; 2654 } 2655 2656 /** 2657 * policy_mgr_is_any_conn_in_transition() - Check if any STA/CLI 2658 * connection is disconnecting or roaming state 2659 * @psoc: PSOC object information 2660 * 2661 * This function will check connection table and find any STA/CLI 2662 * in transition state such as disconnecting, link switch or roaming. 2663 * 2664 * Return: true if there is one STA/CLI in transition state. 2665 */ 2666 static bool 2667 policy_mgr_is_any_conn_in_transition(struct wlan_objmgr_psoc *psoc) 2668 { 2669 struct policy_mgr_psoc_priv_obj *pm_ctx; 2670 uint32_t i; 2671 struct policy_mgr_conc_connection_info *conn_info; 2672 struct wlan_objmgr_vdev *vdev; 2673 bool non_connected = false; 2674 bool in_link_switch = false; 2675 uint8_t vdev_id; 2676 2677 pm_ctx = policy_mgr_get_context(psoc); 2678 if (!pm_ctx) { 2679 policy_mgr_err("Invalid pm context"); 2680 return false; 2681 } 2682 2683 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 2684 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 2685 conn_info = &pm_conc_connection_list[i]; 2686 if (!(conn_info->in_use && 2687 (conn_info->mode == PM_STA_MODE || 2688 conn_info->mode == PM_P2P_CLIENT_MODE))) 2689 continue; 2690 vdev_id = conn_info->vdev_id; 2691 vdev = wlan_objmgr_get_vdev_by_id_from_pdev( 2692 pm_ctx->pdev, vdev_id, WLAN_POLICY_MGR_ID); 2693 if (!vdev) { 2694 policy_mgr_err("vdev %d: not found", vdev_id); 2695 continue; 2696 } 2697 2698 non_connected = !wlan_cm_is_vdev_connected(vdev); 2699 2700 if (mlo_is_mld_sta(vdev) && 2701 mlo_mgr_is_link_switch_in_progress(vdev)) 2702 in_link_switch = true; 2703 2704 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 2705 if (non_connected) { 2706 policy_mgr_debug("vdev %d: is in transition state", 2707 vdev_id); 2708 break; 2709 } 2710 if (in_link_switch) { 2711 policy_mgr_debug("vdev %d: sta mld is in link switch state", 2712 vdev_id); 2713 break; 2714 } 2715 } 2716 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 2717 2718 return non_connected || in_link_switch; 2719 } 2720 2721 static void __policy_mgr_check_sta_ap_concurrent_ch_intf( 2722 struct policy_mgr_psoc_priv_obj *pm_ctx) 2723 { 2724 uint32_t mcc_to_scc_switch, cc_count = 0, i; 2725 QDF_STATUS status; 2726 uint32_t ch_freq; 2727 uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 2728 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; 2729 struct sta_ap_intf_check_work_ctx *work_info; 2730 2731 if (!pm_ctx) { 2732 policy_mgr_err("Invalid context"); 2733 return; 2734 } 2735 work_info = pm_ctx->sta_ap_intf_check_work_info; 2736 2737 if (work_info->nan_force_scc_in_progress) { 2738 policy_mgr_nan_sap_post_enable_conc_check(pm_ctx->psoc); 2739 return; 2740 } 2741 /* 2742 * Check if force scc is required for GO + GO case. vdev id will be 2743 * valid in case of GO+GO force scc only. So, for valid vdev id move 2744 * first GO to newly formed GO channel. 2745 */ 2746 policy_mgr_debug("p2p go vdev id: %d csa reason: %d", 2747 work_info->go_plus_go_force_scc.vdev_id, 2748 work_info->sap_plus_go_force_scc.reason); 2749 if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id < 2750 WLAN_UMAC_VDEV_ID_MAX) { 2751 policy_mgr_do_go_plus_go_force_scc( 2752 pm_ctx->psoc, work_info->go_plus_go_force_scc.vdev_id, 2753 work_info->go_plus_go_force_scc.ch_freq, 2754 work_info->go_plus_go_force_scc.ch_width); 2755 work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX; 2756 goto end; 2757 } 2758 /* 2759 * Check if force scc is required for GO + SAP case. 2760 */ 2761 if (pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason != 2762 CSA_REASON_UNKNOWN) { 2763 status = policy_mgr_handle_sap_plus_go_force_scc(pm_ctx->psoc); 2764 goto end; 2765 } 2766 2767 mcc_to_scc_switch = 2768 policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc); 2769 2770 policy_mgr_debug("Concurrent open sessions running: %d", 2771 policy_mgr_concurrent_open_sessions_running(pm_ctx->psoc)); 2772 2773 if (!policy_mgr_is_sap_go_existed(pm_ctx->psoc)) 2774 goto end; 2775 2776 cc_count = policy_mgr_get_sap_mode_info(pm_ctx->psoc, 2777 &op_ch_freq_list[cc_count], 2778 &vdev_id[cc_count]); 2779 2780 policy_mgr_debug("Number of concurrent SAP: %d", cc_count); 2781 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) 2782 cc_count = cc_count + 2783 policy_mgr_get_mode_specific_conn_info( 2784 pm_ctx->psoc, &op_ch_freq_list[cc_count], 2785 &vdev_id[cc_count], PM_P2P_GO_MODE); 2786 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", 2787 cc_count); 2788 if (!cc_count) { 2789 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid"); 2790 goto end; 2791 } 2792 2793 /* When any STA/CLI is transition state, such as roaming or 2794 * disconnecting, skip force scc for this time. 2795 */ 2796 if (policy_mgr_is_any_conn_in_transition(pm_ctx->psoc)) { 2797 policy_mgr_debug("defer sap conc check to a later time due to another sta/cli dicon/roam pending"); 2798 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2799 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2800 goto end; 2801 } 2802 2803 if (policy_mgr_is_ap_start_in_progress(pm_ctx->psoc)) { 2804 policy_mgr_debug("defer sap conc check to a later time due to another sap/go start pending"); 2805 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2806 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2807 goto end; 2808 } 2809 if (policy_mgr_is_set_link_in_progress(pm_ctx->psoc)) { 2810 policy_mgr_debug("defer sap conc check to a later time due to ml sta set link in progress"); 2811 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2812 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2813 goto end; 2814 } 2815 2816 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 2817 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 2818 policy_mgr_debug("wait as channel switch is already in progress"); 2819 status = qdf_wait_single_event( 2820 &pm_ctx->channel_switch_complete_evt, 2821 CHANNEL_SWITCH_COMPLETE_TIMEOUT); 2822 if (QDF_IS_STATUS_ERROR(status)) 2823 policy_mgr_err("wait for event failed, still continue with channel switch"); 2824 } 2825 2826 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { 2827 policy_mgr_err("SAP restart get channel callback in NULL"); 2828 goto end; 2829 } 2830 if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) 2831 for (i = 0; i < cc_count; i++) { 2832 status = pm_ctx->hdd_cbacks. 2833 wlan_hdd_get_channel_for_sap_restart 2834 (pm_ctx->psoc, vdev_id[i], &ch_freq); 2835 if (status == QDF_STATUS_SUCCESS) { 2836 policy_mgr_debug("SAP vdev id %d restarts due to MCC->SCC switch, old ch freq :%d new ch freq: %d", 2837 vdev_id[i], 2838 op_ch_freq_list[i], ch_freq); 2839 break; 2840 } 2841 } 2842 2843 end: 2844 pm_ctx->last_disconn_sta_freq = 0; 2845 } 2846 2847 void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) 2848 { 2849 struct qdf_op_sync *op_sync; 2850 struct policy_mgr_psoc_priv_obj *pm_ctx = data; 2851 int ret; 2852 2853 if (!pm_ctx) { 2854 policy_mgr_err("Invalid context"); 2855 return; 2856 } 2857 2858 ret = qdf_op_protect(&op_sync); 2859 if (ret) { 2860 if (ret == -EAGAIN) { 2861 if (qdf_is_driver_unloading() || 2862 qdf_is_recovering() || 2863 qdf_is_driver_state_module_stop()) { 2864 policy_mgr_debug("driver not ready"); 2865 return; 2866 } 2867 2868 if (!pm_ctx->sta_ap_intf_check_work_info) 2869 return; 2870 2871 pm_ctx->work_fail_count++; 2872 policy_mgr_debug("qdf_op start fail, ret %d, work_fail_count %d", 2873 ret, pm_ctx->work_fail_count); 2874 if (pm_ctx->work_fail_count > 1) { 2875 pm_ctx->work_fail_count = 0; 2876 return; 2877 } 2878 qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 2879 SAP_CONC_CHECK_DEFER_TIMEOUT_MS); 2880 } 2881 return; 2882 } 2883 pm_ctx->work_fail_count = 0; 2884 __policy_mgr_check_sta_ap_concurrent_ch_intf(data); 2885 2886 qdf_op_unprotect(op_sync); 2887 } 2888 2889 static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, 2890 uint32_t sta_ch_freq) 2891 { 2892 struct policy_mgr_psoc_priv_obj *pm_ctx; 2893 bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel; 2894 2895 pm_ctx = policy_mgr_get_context(psoc); 2896 if (!pm_ctx) { 2897 policy_mgr_err("Invalid context"); 2898 return false; 2899 } 2900 2901 sta_sap_scc_on_dfs_chan = 2902 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 2903 if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) && 2904 sta_sap_scc_on_dfs_chan) { 2905 policy_mgr_debug("STA, SAP SCC is allowed on DFS chan %u", 2906 sta_ch_freq); 2907 return true; 2908 } 2909 2910 sta_sap_scc_on_indoor_channel = 2911 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 2912 if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) && 2913 sta_sap_scc_on_indoor_channel) { 2914 policy_mgr_debug("STA, SAP SCC is allowed on indoor chan %u", 2915 sta_ch_freq); 2916 return true; 2917 } 2918 2919 if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) && 2920 !sta_sap_scc_on_dfs_chan) || 2921 wlan_reg_is_passive_or_disable_for_pwrmode( 2922 pm_ctx->pdev, sta_ch_freq, REG_CURRENT_PWR_MODE) || 2923 (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) && 2924 !sta_sap_scc_on_indoor_channel) || 2925 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) && 2926 !policy_mgr_is_safe_channel(psoc, sta_ch_freq))) { 2927 if (policy_mgr_is_hw_dbs_capable(psoc)) 2928 return true; 2929 else 2930 return false; 2931 } 2932 else 2933 return true; 2934 } 2935 2936 static bool policy_mgr_get_srd_enable_for_vdev( 2937 struct wlan_objmgr_psoc *psoc, 2938 uint8_t vdev_id) 2939 { 2940 struct wlan_objmgr_vdev *vdev; 2941 enum QDF_OPMODE vdev_opmode; 2942 bool enable_srd_channel = false; 2943 2944 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 2945 WLAN_POLICY_MGR_ID); 2946 if (!vdev) { 2947 policy_mgr_err("vdev is NULL"); 2948 return false; 2949 } 2950 2951 vdev_opmode = wlan_vdev_mlme_get_opmode(vdev); 2952 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 2953 2954 wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode, 2955 &enable_srd_channel); 2956 return enable_srd_channel; 2957 } 2958 2959 QDF_STATUS 2960 policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc, 2961 uint32_t *con_ch_freq, 2962 uint32_t sap_ch_freq, 2963 uint8_t sap_vdev_id, 2964 struct ch_params *ch_params) 2965 { 2966 struct policy_mgr_psoc_priv_obj *pm_ctx; 2967 uint32_t ch_freq = *con_ch_freq; 2968 bool find_alternate = false; 2969 enum phy_ch_width old_ch_width; 2970 bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel; 2971 bool is_dfs; 2972 bool is_6ghz_cap; 2973 bool is_sta_sap_scc; 2974 enum policy_mgr_con_mode con_mode; 2975 uint32_t nan_2g_freq, nan_5g_freq; 2976 2977 pm_ctx = policy_mgr_get_context(psoc); 2978 if (!pm_ctx) { 2979 policy_mgr_err("Invalid context"); 2980 return QDF_STATUS_E_FAILURE; 2981 } 2982 /* 2983 * If force SCC is set, Check if conc channel is DFS 2984 * or passive or part of LTE avoided channel list. 2985 * In that case move SAP to other band if DBS is supported, 2986 * return otherwise 2987 */ 2988 if (!policy_mgr_is_force_scc(psoc)) 2989 return QDF_STATUS_SUCCESS; 2990 2991 /* 2992 * If interference is 0, it could be STA/SAP SCC, 2993 * check further if SAP can start on STA home channel or 2994 * select other band channel if not. 2995 */ 2996 if (!ch_freq) { 2997 if (!policy_mgr_any_other_vdev_on_same_mac_as_freq(psoc, 2998 sap_ch_freq, 2999 sap_vdev_id)) 3000 return QDF_STATUS_SUCCESS; 3001 3002 ch_freq = sap_ch_freq; 3003 } 3004 3005 if (!ch_freq) 3006 return QDF_STATUS_SUCCESS; 3007 3008 con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id); 3009 3010 is_sta_sap_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq); 3011 3012 nan_2g_freq = 3013 policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE); 3014 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc); 3015 3016 sta_sap_scc_on_dfs_chan = 3017 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); 3018 3019 sta_sap_scc_on_indoor_channel = 3020 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc); 3021 old_ch_width = ch_params->ch_width; 3022 if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) 3023 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 3024 psoc, sap_vdev_id, ch_freq, ch_params); 3025 3026 is_dfs = wlan_mlme_check_chan_param_has_dfs( 3027 pm_ctx->pdev, ch_params, ch_freq); 3028 is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL); 3029 3030 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && is_dfs && 3031 !sta_sap_scc_on_dfs_chan && is_sta_sap_scc) { 3032 find_alternate = true; 3033 policymgr_nofl_debug("sap not capable of DFS SCC on con ch_freq %d", 3034 ch_freq); 3035 } else if (wlan_reg_is_disable_for_pwrmode(pm_ctx->pdev, ch_freq, 3036 REG_CURRENT_PWR_MODE)) { 3037 find_alternate = true; 3038 policymgr_nofl_debug("sap not capable on disabled con ch_freq %d", 3039 ch_freq); 3040 } else if (con_mode == PM_P2P_GO_MODE && 3041 wlan_reg_is_passive_or_disable_for_pwrmode( 3042 pm_ctx->pdev, 3043 ch_freq, 3044 REG_CURRENT_PWR_MODE) && 3045 !(policy_mgr_is_go_scc_strict(psoc) && 3046 (!is_sta_sap_scc || sta_sap_scc_on_dfs_chan))) { 3047 find_alternate = true; 3048 policymgr_nofl_debug("Go not capable on dfs/disabled con ch_freq %d", 3049 ch_freq); 3050 } else if (!policy_mgr_is_safe_channel(psoc, ch_freq) && 3051 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) && 3052 is_sta_sap_scc) && 3053 !(policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc) && 3054 (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) || 3055 WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)))) { 3056 find_alternate = true; 3057 policymgr_nofl_debug("sap not capable unsafe con ch_freq %d", 3058 ch_freq); 3059 } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && 3060 !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) && 3061 !is_6ghz_cap) { 3062 policymgr_nofl_debug("sap not capable on 6GHZ con ch_freq %d", 3063 ch_freq); 3064 find_alternate = true; 3065 } else if (wlan_reg_is_etsi_srd_chan_for_freq(pm_ctx->pdev, 3066 ch_freq) && 3067 !policy_mgr_get_srd_enable_for_vdev(psoc, sap_vdev_id)) { 3068 find_alternate = true; 3069 policymgr_nofl_debug("sap not capable on SRD con ch_freq %d", 3070 ch_freq); 3071 } else if (!policy_mgr_is_sap_go_interface_allowed_on_indoor( 3072 pm_ctx->pdev, 3073 sap_vdev_id, ch_freq)) { 3074 policymgr_nofl_debug("sap not capable on indoor con ch_freq %d is_sta_sap_scc:%d", 3075 ch_freq, is_sta_sap_scc); 3076 find_alternate = true; 3077 } 3078 3079 if (find_alternate) { 3080 if (policy_mgr_is_hw_dbs_capable(psoc)) { 3081 ch_freq = policy_mgr_get_alternate_channel_for_sap( 3082 psoc, sap_vdev_id, sap_ch_freq, 3083 REG_BAND_UNKNOWN); 3084 policymgr_nofl_debug("selected alternate ch %d", 3085 ch_freq); 3086 if (!ch_freq) { 3087 policymgr_nofl_debug("Sap can't have concurrency on %d in dbs hw", 3088 *con_ch_freq); 3089 return QDF_STATUS_E_FAILURE; 3090 } 3091 } else { 3092 /* MCC not supported for non-DBS chip*/ 3093 ch_freq = 0; 3094 if (con_mode == PM_SAP_MODE) { 3095 policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d SAP freq %d not supported", 3096 *con_ch_freq, sap_ch_freq); 3097 return QDF_STATUS_E_FAILURE; 3098 } else { 3099 policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d GO freq %d SCC not supported", 3100 *con_ch_freq, sap_ch_freq); 3101 } 3102 } 3103 } 3104 3105 if (ch_freq != sap_ch_freq || old_ch_width != ch_params->ch_width) { 3106 *con_ch_freq = ch_freq; 3107 policymgr_nofl_debug("sap conc result con freq %d bw %d org freq %d bw %d", 3108 ch_freq, ch_params->ch_width, sap_ch_freq, 3109 old_ch_width); 3110 } 3111 3112 if (*con_ch_freq && 3113 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) 3114 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 3115 psoc, sap_vdev_id, ch_freq, ch_params); 3116 3117 return QDF_STATUS_SUCCESS; 3118 } 3119 3120 void policy_mgr_check_concurrent_intf_and_restart_sap( 3121 struct wlan_objmgr_psoc *psoc, bool is_acs_mode) 3122 { 3123 struct policy_mgr_psoc_priv_obj *pm_ctx; 3124 uint32_t mcc_to_scc_switch; 3125 uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3126 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 3127 uint32_t cc_count = 0; 3128 uint32_t timeout_ms = 0; 3129 bool restart_sap = false; 3130 uint32_t sap_freq; 3131 /* 3132 * if no sta, sap/p2p go may need switch channel for band 3133 * capability change. 3134 * If sta exist, sap/p2p go may need switch channel to force scc 3135 */ 3136 bool sta_check = false, gc_check = false; 3137 3138 pm_ctx = policy_mgr_get_context(psoc); 3139 if (!pm_ctx) { 3140 policy_mgr_err("Invalid context"); 3141 return; 3142 } 3143 if (!pm_ctx->sta_ap_intf_check_work_info) { 3144 policy_mgr_err("Invalid sta_ap_intf_check_work_info"); 3145 return; 3146 } 3147 if (!policy_mgr_is_sap_go_existed(psoc)) { 3148 policy_mgr_debug( 3149 "No action taken at check_concurrent_intf_and_restart_sap"); 3150 return; 3151 } 3152 /* 3153 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is 3154 * enabled on DFS channel then move the SAP out of DFS channel 3155 * as soon as STA gets disconnect. 3156 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is 3157 * enabled on unsafe channel then move the SAP to safe channel 3158 * as soon as STA disconnected. 3159 */ 3160 if (policy_mgr_is_sap_restart_required_after_sta_disconnect( 3161 psoc, INVALID_VDEV_ID, &sap_freq, is_acs_mode)) { 3162 policy_mgr_debug("move the SAP to configured channel %u", 3163 sap_freq); 3164 restart_sap = true; 3165 goto sap_restart; 3166 } 3167 3168 /* 3169 * force SCC with STA+STA+SAP will need some additional logic 3170 */ 3171 cc_count = policy_mgr_get_mode_specific_conn_info( 3172 psoc, &op_ch_freq_list[cc_count], 3173 &vdev_id[cc_count], PM_STA_MODE); 3174 if (!cc_count) { 3175 policy_mgr_debug("Could not get STA operating channel&vdevid"); 3176 } 3177 3178 sta_check = !cc_count || 3179 policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]); 3180 3181 cc_count = 0; 3182 cc_count = policy_mgr_get_mode_specific_conn_info( 3183 psoc, &op_ch_freq_list[cc_count], 3184 &vdev_id[cc_count], PM_P2P_CLIENT_MODE); 3185 if (!cc_count) 3186 policy_mgr_debug("Could not get GC operating channel&vdevid"); 3187 3188 gc_check = !!cc_count; 3189 policy_mgr_debug("gc_check: %d", gc_check); 3190 3191 mcc_to_scc_switch = 3192 policy_mgr_get_mcc_to_scc_switch_mode(psoc); 3193 policy_mgr_debug("MCC to SCC switch: %d chan: %d", 3194 mcc_to_scc_switch, op_ch_freq_list[0]); 3195 sap_restart: 3196 /* 3197 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not 3198 * allowed on DFS channel. SAP is allowed on DFS channel only when STA 3199 * is already connected on that channel. 3200 * In following condition restart_sap will be true if 3201 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel. 3202 * This scenario can come if STA+SAP are operating on DFS channel and 3203 * STA gets disconnected. 3204 */ 3205 if (restart_sap || 3206 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && 3207 (sta_check || gc_check))) { 3208 if (!pm_ctx->sta_ap_intf_check_work_info) { 3209 policy_mgr_err("invalid sta_ap_intf_check_work_info"); 3210 return; 3211 } 3212 3213 policy_mgr_debug("Checking for Concurrent Change interference"); 3214 3215 if (policy_mgr_mode_specific_connection_count( 3216 psoc, PM_P2P_GO_MODE, NULL)) 3217 timeout_ms = MAX_NOA_TIME; 3218 3219 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 3220 timeout_ms)) { 3221 policy_mgr_debug("change interface request already queued"); 3222 return; 3223 } 3224 } 3225 } 3226 3227 bool policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc *psoc, 3228 qdf_freq_t center_freq, 3229 enum phy_ch_width ch_width) 3230 { 3231 struct policy_mgr_psoc_priv_obj *pm_ctx; 3232 uint32_t freq_start, freq_end, bw, i, unsafe_chan_freq; 3233 3234 pm_ctx = policy_mgr_get_context(psoc); 3235 if (!pm_ctx) { 3236 policy_mgr_err("Invalid Context"); 3237 return true; 3238 } 3239 3240 if (ch_width <= CH_WIDTH_20MHZ || !center_freq) 3241 return true; 3242 3243 if (!pm_ctx->unsafe_channel_count) 3244 return true; 3245 3246 bw = wlan_reg_get_bw_value(ch_width); 3247 freq_start = center_freq - bw / 2; 3248 freq_end = center_freq + bw / 2; 3249 3250 for (i = 0; i < pm_ctx->unsafe_channel_count; i++) { 3251 unsafe_chan_freq = pm_ctx->unsafe_channel_list[i]; 3252 if (unsafe_chan_freq > freq_start && 3253 unsafe_chan_freq < freq_end) { 3254 policy_mgr_debug("unsafe ch freq %d is in range %d-%d", 3255 unsafe_chan_freq, 3256 freq_start, 3257 freq_end); 3258 return false; 3259 } 3260 } 3261 return true; 3262 } 3263 3264 /** 3265 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA 3266 * @psoc: PSOC object information 3267 * @vdev_id: Vdev id 3268 * @ch_freq: Channel to change 3269 * @ch_width: channel width to change 3270 * @forced: Force to switch channel, ignore SCC/MCC check 3271 * 3272 * Invoke the callback function to change SAP channel using (E)CSA 3273 * 3274 * Return: QDF_STATUS_SUCCESS for success 3275 */ 3276 QDF_STATUS 3277 policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, 3278 uint8_t vdev_id, uint32_t ch_freq, 3279 uint32_t ch_width, bool forced) 3280 { 3281 struct policy_mgr_psoc_priv_obj *pm_ctx; 3282 struct ch_params ch_params = {0}; 3283 qdf_freq_t center_freq; 3284 QDF_STATUS status; 3285 3286 pm_ctx = policy_mgr_get_context(psoc); 3287 if (!pm_ctx) { 3288 policy_mgr_err("Invalid context"); 3289 return QDF_STATUS_E_INVAL; 3290 } 3291 if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) { 3292 ch_params.ch_width = ch_width; 3293 status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( 3294 psoc, vdev_id, ch_freq, &ch_params); 3295 if (QDF_IS_STATUS_SUCCESS(status) && 3296 ch_width > ch_params.ch_width) 3297 ch_width = ch_params.ch_width; 3298 } 3299 3300 if (ch_params.mhz_freq_seg1) 3301 center_freq = ch_params.mhz_freq_seg1; 3302 else 3303 center_freq = ch_params.mhz_freq_seg0; 3304 3305 if (!policy_mgr_check_bw_with_unsafe_chan_freq(psoc, 3306 center_freq, 3307 ch_width)) { 3308 policy_mgr_info("SAP bw shrink to 20M for unsafe"); 3309 ch_width = CH_WIDTH_20MHZ; 3310 } 3311 3312 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { 3313 policy_mgr_info("SAP change change without restart"); 3314 status = pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, 3315 vdev_id, 3316 ch_freq, 3317 ch_width, 3318 forced); 3319 } else { 3320 status = QDF_STATUS_E_INVAL; 3321 } 3322 3323 return status; 3324 } 3325 #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ 3326 3327 QDF_STATUS 3328 policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc, 3329 uint8_t vdev_id, 3330 struct csa_offload_params *csa_event) 3331 { 3332 uint8_t concur_vdev_id, i; 3333 bool move_sap_go_first; 3334 enum hw_mode_bandwidth bw; 3335 qdf_freq_t cur_freq, new_freq; 3336 struct wlan_objmgr_vdev *vdev, *conc_vdev; 3337 struct wlan_objmgr_pdev *pdev; 3338 struct policy_mgr_psoc_priv_obj *pm_ctx; 3339 enum policy_mgr_con_mode cur_mode; 3340 enum policy_mgr_con_mode concur_mode = PM_MAX_NUM_OF_MODE; 3341 3342 pm_ctx = policy_mgr_get_context(psoc); 3343 if (!pm_ctx) { 3344 policy_mgr_err("Invalid context"); 3345 return QDF_STATUS_E_INVAL; 3346 } 3347 if (!csa_event) { 3348 policy_mgr_err("CSA IE Received event is NULL"); 3349 return QDF_STATUS_E_INVAL; 3350 } 3351 3352 policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first); 3353 if (!move_sap_go_first) { 3354 policy_mgr_err("g_move_sap_go_1st_on_dfs_sta_csa is disabled"); 3355 return QDF_STATUS_E_NOSUPPORT; 3356 } 3357 3358 cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id); 3359 if (cur_mode != PM_STA_MODE) { 3360 policy_mgr_err("CSA received on non-STA connection"); 3361 return QDF_STATUS_E_INVAL; 3362 } 3363 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3364 WLAN_POLICY_MGR_ID); 3365 if (!vdev) { 3366 policy_mgr_err("vdev is NULL"); 3367 return QDF_STATUS_E_INVAL; 3368 } 3369 pdev = wlan_vdev_get_pdev(vdev); 3370 cur_freq = wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id); 3371 3372 if (!wlan_reg_is_dfs_for_freq(pdev, cur_freq) && 3373 !wlan_reg_is_freq_indoor(pdev, cur_freq)) { 3374 policy_mgr_err("SAP / GO operating channel is non-DFS"); 3375 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3376 return QDF_STATUS_E_INVAL; 3377 } 3378 3379 /* Check if there is any SAP / GO operating on the same channel or not 3380 * If yes, then get the current bandwidth and vdev_id of concurrent SAP 3381 * or GO and trigger channel switch to new channel received in CSA on 3382 * STA interface. If this new channel is DFS then trigger channel 3383 * switch to non-DFS channel. Once STA moves to this new channel and 3384 * when it receives very first beacon, it will then enforce SCC again 3385 */ 3386 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 3387 if (pm_conc_connection_list[i].in_use && 3388 pm_conc_connection_list[i].freq == cur_freq && 3389 pm_conc_connection_list[i].vdev_id != vdev_id && 3390 (pm_conc_connection_list[i].mode == PM_P2P_GO_MODE || 3391 pm_conc_connection_list[i].mode == PM_SAP_MODE)) { 3392 concur_mode = pm_conc_connection_list[i].mode; 3393 bw = pm_conc_connection_list[i].bw; 3394 concur_vdev_id = pm_conc_connection_list[i].vdev_id; 3395 break; 3396 } 3397 } 3398 3399 /* If there is no concurrent SAP / GO, then return */ 3400 if (concur_mode == PM_MAX_NUM_OF_MODE) { 3401 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3402 return QDF_STATUS_E_INVAL; 3403 } 3404 3405 conc_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, concur_vdev_id, 3406 WLAN_POLICY_MGR_ID); 3407 if (!conc_vdev) { 3408 policy_mgr_err("conc_vdev is NULL"); 3409 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3410 return QDF_STATUS_E_INVAL; 3411 } 3412 wlan_vdev_mlme_set_sap_go_move_before_sta(conc_vdev, true); 3413 wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, true); 3414 wlan_objmgr_vdev_release_ref(conc_vdev, WLAN_POLICY_MGR_ID); 3415 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3416 3417 /*Change the CSA count*/ 3418 if (pm_ctx->sme_cbacks.sme_change_sap_csa_count) 3419 /* Total 4 CSA frames are allowed so that GO / SAP 3420 * will move to new channel within 500ms 3421 */ 3422 pm_ctx->sme_cbacks.sme_change_sap_csa_count(4); 3423 new_freq = csa_event->csa_chan_freq; 3424 3425 /* If the new channel is DFS or indoor, then select another channel 3426 * and switch the SAP / GO to avoid CAC. This will resume traffic on 3427 * SAP / GO interface immediately. Once STA moves to this new channel 3428 * and receives the very first beacon, then it will enforece SCC 3429 */ 3430 if (wlan_reg_is_dfs_for_freq(pdev, new_freq) || 3431 wlan_reg_is_freq_indoor(pdev, new_freq)) { 3432 if (wlan_reg_is_24ghz_ch_freq(new_freq)) { 3433 new_freq = wlan_reg_min_24ghz_chan_freq(); 3434 } else if (wlan_reg_is_5ghz_ch_freq(new_freq)) { 3435 new_freq = wlan_reg_min_5ghz_chan_freq(); 3436 /* if none of the 5G channel is non-DFS */ 3437 if (wlan_reg_is_dfs_for_freq(pdev, new_freq) || 3438 wlan_reg_is_freq_indoor(pdev, new_freq)) 3439 new_freq = policy_mgr_get_nondfs_preferred_channel(psoc, 3440 concur_mode, 3441 true, 3442 concur_vdev_id); 3443 } else { 3444 new_freq = wlan_reg_min_6ghz_chan_freq(); 3445 } 3446 } 3447 policy_mgr_debug("Restart vdev: %u on freq: %u", 3448 concur_vdev_id, new_freq); 3449 3450 return policy_mgr_change_sap_channel_with_csa(psoc, concur_vdev_id, 3451 new_freq, bw, true); 3452 } 3453 3454 void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc, 3455 uint8_t vdev_id) 3456 { 3457 bool is_sap_go_moved_before_sta, move_sap_go_first; 3458 struct policy_mgr_psoc_priv_obj *pm_ctx; 3459 struct wlan_objmgr_vdev *vdev; 3460 struct wlan_objmgr_pdev *pdev; 3461 enum policy_mgr_con_mode cur_mode; 3462 3463 pm_ctx = policy_mgr_get_context(psoc); 3464 if (!pm_ctx) { 3465 policy_mgr_err("Invalid context"); 3466 return; 3467 } 3468 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3469 WLAN_POLICY_MGR_ID); 3470 if (!vdev) { 3471 policy_mgr_err("vdev is NULL"); 3472 return; 3473 } 3474 is_sap_go_moved_before_sta = 3475 wlan_vdev_mlme_is_sap_go_move_before_sta(vdev); 3476 pdev = wlan_vdev_get_pdev(vdev); 3477 wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false); 3478 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); 3479 3480 policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first); 3481 if (!is_sap_go_moved_before_sta || !move_sap_go_first) { 3482 policy_mgr_debug("SAP / GO moved before STA: %u INI g_move_sap_go_1st_on_dfs_sta_csa: %u", 3483 is_sap_go_moved_before_sta, move_sap_go_first); 3484 return; 3485 } 3486 3487 cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id); 3488 if (cur_mode != PM_STA_MODE) { 3489 policy_mgr_err("CSA received on non-STA connection"); 3490 return; 3491 } 3492 3493 policy_mgr_debug("Enforce SCC"); 3494 policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false); 3495 } 3496 3497 #ifdef WLAN_FEATURE_P2P_P2P_STA 3498 void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc, 3499 uint8_t vdev_id, uint32_t ch_freq, 3500 uint32_t ch_width) 3501 { 3502 uint8_t total_connection; 3503 struct policy_mgr_psoc_priv_obj *pm_ctx; 3504 3505 pm_ctx = policy_mgr_get_context(psoc); 3506 if (!pm_ctx) { 3507 policy_mgr_err("Invalid Context"); 3508 return; 3509 } 3510 3511 total_connection = policy_mgr_mode_specific_connection_count( 3512 psoc, PM_P2P_GO_MODE, NULL); 3513 3514 policy_mgr_debug("Total p2p go connection %d", total_connection); 3515 3516 /* If any p2p disconnected, don't do csa */ 3517 if (total_connection > 1) { 3518 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 3519 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( 3520 psoc, vdev_id, 3521 CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL); 3522 3523 policy_mgr_change_sap_channel_with_csa(psoc, vdev_id, 3524 ch_freq, ch_width, true); 3525 } 3526 } 3527 3528 void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc, 3529 uint8_t vdev_id, uint32_t ch_freq, 3530 uint32_t ch_width, 3531 enum policy_mgr_con_mode mode) 3532 { 3533 struct policy_mgr_psoc_priv_obj *pm_ctx; 3534 struct sta_ap_intf_check_work_ctx *work_info; 3535 3536 pm_ctx = policy_mgr_get_context(psoc); 3537 if (!pm_ctx) { 3538 policy_mgr_err("Invalid Context"); 3539 return; 3540 } 3541 if (!pm_ctx->sta_ap_intf_check_work_info) { 3542 policy_mgr_err("invalid work info"); 3543 return; 3544 } 3545 work_info = pm_ctx->sta_ap_intf_check_work_info; 3546 if (mode == PM_P2P_GO_MODE) { 3547 work_info->go_plus_go_force_scc.vdev_id = vdev_id; 3548 work_info->go_plus_go_force_scc.ch_freq = ch_freq; 3549 work_info->go_plus_go_force_scc.ch_width = ch_width; 3550 } 3551 3552 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 3553 WAIT_BEFORE_GO_FORCESCC_RESTART)) 3554 policy_mgr_debug("change interface request already queued"); 3555 } 3556 #endif 3557 3558 bool policy_mgr_is_chan_switch_in_progress(struct wlan_objmgr_psoc *psoc) 3559 { 3560 struct policy_mgr_psoc_priv_obj *pm_ctx; 3561 3562 pm_ctx = policy_mgr_get_context(psoc); 3563 if (!pm_ctx) { 3564 policy_mgr_err("Invalid pm context"); 3565 return false; 3566 } 3567 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 3568 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 3569 policy_mgr_debug("channel switch is in progress"); 3570 return true; 3571 } 3572 3573 return false; 3574 } 3575 3576 QDF_STATUS policy_mgr_wait_chan_switch_complete_evt( 3577 struct wlan_objmgr_psoc *psoc) 3578 { 3579 QDF_STATUS status; 3580 struct policy_mgr_psoc_priv_obj *pm_ctx; 3581 3582 pm_ctx = policy_mgr_get_context(psoc); 3583 3584 if (!pm_ctx) { 3585 policy_mgr_err("Invalid context"); 3586 return QDF_STATUS_E_FAILURE; 3587 } 3588 3589 status = qdf_wait_single_event( 3590 &pm_ctx->channel_switch_complete_evt, 3591 CHANNEL_SWITCH_COMPLETE_TIMEOUT); 3592 if (QDF_IS_STATUS_ERROR(status)) 3593 policy_mgr_err("wait for event failed, still continue with channel switch"); 3594 3595 return status; 3596 } 3597 3598 static void __policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_pdev *pdev, 3599 void *object, void *arg) 3600 { 3601 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 3602 uint32_t *ap_starting_vdev_id = (uint32_t *)arg; 3603 enum wlan_serialization_cmd_type cmd_type; 3604 enum QDF_OPMODE op_mode; 3605 3606 if (!vdev || !ap_starting_vdev_id) 3607 return; 3608 if (*ap_starting_vdev_id != WLAN_INVALID_VDEV_ID) 3609 return; 3610 op_mode = wlan_vdev_mlme_get_opmode(vdev); 3611 if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE && 3612 op_mode != QDF_NDI_MODE) 3613 return; 3614 /* Check AP start is present in active and pending queue or not */ 3615 cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev); 3616 if (cmd_type == WLAN_SER_CMD_VDEV_START_BSS || 3617 wlan_ser_is_non_scan_cmd_type_in_vdev_queue( 3618 vdev, WLAN_SER_CMD_VDEV_START_BSS)) { 3619 *ap_starting_vdev_id = wlan_vdev_get_id(vdev); 3620 policy_mgr_debug("vdev %d op mode %d start bss is pending", 3621 *ap_starting_vdev_id, op_mode); 3622 } 3623 } 3624 3625 bool policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc *psoc) 3626 { 3627 struct policy_mgr_psoc_priv_obj *pm_ctx; 3628 uint32_t ap_starting_vdev_id = WLAN_INVALID_VDEV_ID; 3629 3630 pm_ctx = policy_mgr_get_context(psoc); 3631 if (!pm_ctx) { 3632 policy_mgr_err("Invalid pm context"); 3633 return false; 3634 } 3635 3636 wlan_objmgr_pdev_iterate_obj_list(pm_ctx->pdev, WLAN_VDEV_OP, 3637 __policy_mgr_is_ap_start_in_progress, 3638 &ap_starting_vdev_id, 0, 3639 WLAN_POLICY_MGR_ID); 3640 3641 return ap_starting_vdev_id != WLAN_INVALID_VDEV_ID; 3642 } 3643 3644 void policy_mgr_process_force_scc_for_nan(struct wlan_objmgr_psoc *psoc) 3645 { 3646 struct policy_mgr_psoc_priv_obj *pm_ctx; 3647 3648 pm_ctx = policy_mgr_get_context(psoc); 3649 if (!pm_ctx) { 3650 policy_mgr_err("Invalid Context"); 3651 return; 3652 } 3653 if (!pm_ctx->sta_ap_intf_check_work_info) { 3654 policy_mgr_err("invalid work info"); 3655 return; 3656 } 3657 3658 pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = true; 3659 3660 if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 0)) 3661 policy_mgr_debug("change interface request already queued"); 3662 } 3663 3664 QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc) 3665 { 3666 QDF_STATUS status; 3667 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3668 3669 policy_mgr_context = policy_mgr_get_context(psoc); 3670 if (!policy_mgr_context) { 3671 policy_mgr_err("Invalid context"); 3672 return QDF_STATUS_E_FAILURE; 3673 } 3674 3675 status = qdf_wait_single_event( 3676 &policy_mgr_context->connection_update_done_evt, 3677 CONNECTION_UPDATE_TIMEOUT); 3678 3679 if (!QDF_IS_STATUS_SUCCESS(status)) { 3680 policy_mgr_err("wait for event failed"); 3681 return QDF_STATUS_E_FAILURE; 3682 } 3683 3684 return QDF_STATUS_SUCCESS; 3685 } 3686 3687 QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc) 3688 { 3689 QDF_STATUS status; 3690 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3691 3692 policy_mgr_context = policy_mgr_get_context(psoc); 3693 if (!policy_mgr_context) { 3694 policy_mgr_err("Invalid context"); 3695 return QDF_STATUS_E_FAILURE; 3696 } 3697 3698 status = qdf_event_reset( 3699 &policy_mgr_context->connection_update_done_evt); 3700 3701 if (!QDF_IS_STATUS_SUCCESS(status)) { 3702 policy_mgr_err("clear event failed"); 3703 return QDF_STATUS_E_FAILURE; 3704 } 3705 3706 return QDF_STATUS_SUCCESS; 3707 } 3708 3709 void policy_mgr_reset_hw_mode_change(struct wlan_objmgr_psoc *psoc) 3710 { 3711 policy_mgr_err("Clear hw mode change and connection update evt"); 3712 policy_mgr_set_hw_mode_change_in_progress( 3713 psoc, POLICY_MGR_HW_MODE_NOT_IN_PROGRESS); 3714 policy_mgr_reset_connection_update(psoc); 3715 } 3716 3717 QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc) 3718 { 3719 QDF_STATUS status; 3720 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3721 3722 policy_mgr_context = policy_mgr_get_context(psoc); 3723 if (!policy_mgr_context) { 3724 policy_mgr_err("Invalid context"); 3725 return QDF_STATUS_E_FAILURE; 3726 } 3727 3728 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt); 3729 3730 if (!QDF_IS_STATUS_SUCCESS(status)) { 3731 policy_mgr_err("set event failed"); 3732 return QDF_STATUS_E_FAILURE; 3733 } 3734 3735 return QDF_STATUS_SUCCESS; 3736 } 3737 3738 QDF_STATUS policy_mgr_set_chan_switch_complete_evt( 3739 struct wlan_objmgr_psoc *psoc) 3740 { 3741 QDF_STATUS status; 3742 struct policy_mgr_psoc_priv_obj *pm_ctx; 3743 3744 pm_ctx = policy_mgr_get_context(psoc); 3745 3746 if (!pm_ctx) { 3747 policy_mgr_err("Invalid context"); 3748 return QDF_STATUS_E_FAILURE; 3749 } 3750 3751 /* 3752 * Set channel_switch_complete_evt only if no vdev has channel switch 3753 * in progress. 3754 */ 3755 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 3756 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 3757 policy_mgr_info("Not all channel switch completed"); 3758 return QDF_STATUS_SUCCESS; 3759 } 3760 3761 status = qdf_event_set_all(&pm_ctx->channel_switch_complete_evt); 3762 3763 if (!QDF_IS_STATUS_SUCCESS(status)) { 3764 policy_mgr_err("set event failed"); 3765 return QDF_STATUS_E_FAILURE; 3766 } 3767 3768 return QDF_STATUS_SUCCESS; 3769 } 3770 3771 QDF_STATUS policy_mgr_reset_chan_switch_complete_evt( 3772 struct wlan_objmgr_psoc *psoc) 3773 { 3774 QDF_STATUS status; 3775 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3776 3777 policy_mgr_context = policy_mgr_get_context(psoc); 3778 3779 if (!policy_mgr_context) { 3780 policy_mgr_err("Invalid context"); 3781 return QDF_STATUS_E_FAILURE; 3782 } 3783 status = qdf_event_reset( 3784 &policy_mgr_context->channel_switch_complete_evt); 3785 3786 if (!QDF_IS_STATUS_SUCCESS(status)) { 3787 policy_mgr_err("reset event failed"); 3788 return QDF_STATUS_E_FAILURE; 3789 } 3790 3791 return QDF_STATUS_SUCCESS; 3792 } 3793 3794 QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc) 3795 { 3796 QDF_STATUS status; 3797 struct policy_mgr_psoc_priv_obj *policy_mgr_context; 3798 3799 policy_mgr_context = policy_mgr_get_context(psoc); 3800 if (!policy_mgr_context) { 3801 policy_mgr_err("Invalid context"); 3802 return QDF_STATUS_E_FAILURE; 3803 } 3804 3805 status = qdf_event_set( 3806 &policy_mgr_context->opportunistic_update_done_evt); 3807 3808 if (!QDF_IS_STATUS_SUCCESS(status)) { 3809 policy_mgr_err("set event failed"); 3810 return QDF_STATUS_E_FAILURE; 3811 } 3812 3813 return QDF_STATUS_SUCCESS; 3814 } 3815 3816 QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc) 3817 { 3818 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 3819 3820 policy_mgr_ctx = policy_mgr_get_context(psoc); 3821 if (!policy_mgr_ctx) { 3822 policy_mgr_err("Invalid context"); 3823 return QDF_STATUS_E_FAILURE; 3824 } 3825 3826 if (policy_mgr_ctx->dbs_opportunistic_timer.state != 3827 QDF_TIMER_STATE_RUNNING) 3828 return QDF_STATUS_SUCCESS; 3829 3830 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer); 3831 return QDF_STATUS_SUCCESS; 3832 } 3833 3834 QDF_STATUS policy_mgr_restart_opportunistic_timer( 3835 struct wlan_objmgr_psoc *psoc, bool check_state) 3836 { 3837 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3838 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 3839 3840 if (policy_mgr_is_hwmode_offload_enabled(psoc)) 3841 return QDF_STATUS_E_NOSUPPORT; 3842 3843 policy_mgr_ctx = policy_mgr_get_context(psoc); 3844 if (!policy_mgr_ctx) { 3845 policy_mgr_err("Invalid context"); 3846 return status; 3847 } 3848 3849 if (check_state && 3850 QDF_TIMER_STATE_RUNNING != 3851 policy_mgr_ctx->dbs_opportunistic_timer.state) 3852 return status; 3853 3854 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer); 3855 3856 status = qdf_mc_timer_start( 3857 &policy_mgr_ctx->dbs_opportunistic_timer, 3858 DBS_OPPORTUNISTIC_TIME * 1000); 3859 3860 if (!QDF_IS_STATUS_SUCCESS(status)) { 3861 policy_mgr_err("failed to start opportunistic timer"); 3862 return status; 3863 } 3864 3865 return status; 3866 } 3867 3868 QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( 3869 struct wlan_objmgr_psoc *psoc, uint8_t session_id) 3870 { 3871 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status; 3872 enum policy_mgr_conc_next_action action; 3873 3874 if (policy_mgr_is_hwmode_offload_enabled(psoc)) 3875 return QDF_STATUS_E_NOSUPPORT; 3876 3877 if (!policy_mgr_is_hw_dbs_capable(psoc)) { 3878 policy_mgr_rl_debug("PM/DBS is disabled"); 3879 return status; 3880 } 3881 3882 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc); 3883 if ((action != PM_DBS_DOWNGRADE) && 3884 (action != PM_SINGLE_MAC_UPGRADE) && 3885 (action != PM_DBS1_DOWNGRADE) && 3886 (action != PM_DBS2_DOWNGRADE)) { 3887 policy_mgr_err("Invalid action: %d", action); 3888 status = QDF_STATUS_SUCCESS; 3889 goto done; 3890 } 3891 3892 policy_mgr_debug("action:%d session id:%d", action, session_id); 3893 3894 /* Opportunistic timer is started, PM will check if MCC upgrade can be 3895 * done on timer expiry. This avoids any possible ping pong effect 3896 * as well. 3897 */ 3898 if (action == PM_SINGLE_MAC_UPGRADE) { 3899 qdf_status = policy_mgr_restart_opportunistic_timer( 3900 psoc, false); 3901 if (QDF_IS_STATUS_SUCCESS(qdf_status)) 3902 policy_mgr_debug("opportunistic timer for MCC upgrade"); 3903 goto done; 3904 } 3905 3906 /* For DBS, we want to move right away to DBS mode */ 3907 status = policy_mgr_next_actions(psoc, session_id, action, 3908 POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH, 3909 POLICY_MGR_DEF_REQ_ID); 3910 if (!QDF_IS_STATUS_SUCCESS(status)) { 3911 policy_mgr_err("no set hw mode command was issued"); 3912 goto done; 3913 } 3914 done: 3915 /* success must be returned only when a set hw mode was done */ 3916 return status; 3917 } 3918 3919 QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( 3920 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3921 uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) 3922 { 3923 QDF_STATUS status; 3924 struct policy_mgr_conc_connection_info info; 3925 uint8_t num_cxn_del = 0; 3926 struct policy_mgr_psoc_priv_obj *pm_ctx; 3927 enum policy_mgr_conc_next_action next_action = PM_NOP; 3928 bool eht_capab = false; 3929 3930 pm_ctx = policy_mgr_get_context(psoc); 3931 if (!pm_ctx) { 3932 policy_mgr_err("Invalid context"); 3933 return QDF_STATUS_E_FAILURE; 3934 } 3935 3936 wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab); 3937 if (eht_capab && 3938 policy_mgr_mode_specific_connection_count(psoc, 3939 PM_SAP_MODE, 3940 NULL) == 1) { 3941 policy_mgr_stop_opportunistic_timer(psoc); 3942 goto ch_width_update; 3943 } 3944 3945 if (!policy_mgr_is_hw_dbs_capable(psoc) || 3946 (!policy_mgr_is_hw_dbs_2x2_capable(psoc) && 3947 !policy_mgr_is_hw_dbs_required_for_band( 3948 psoc, HW_MODE_MAC_BAND_2G))) 3949 return QDF_STATUS_E_NOSUPPORT; 3950 3951 /* 3952 * Stop opportunistic timer as current connection info will change once 3953 * channel is switched and thus if required it will be started once 3954 * channel switch is completed. With new connection info. 3955 */ 3956 policy_mgr_stop_opportunistic_timer(psoc); 3957 3958 if (wlan_reg_freq_to_band(ch_freq) != REG_BAND_2G) 3959 return QDF_STATUS_E_NOSUPPORT; 3960 3961 ch_width_update: 3962 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 3963 /* 3964 * Store the connection's parameter and temporarily delete it 3965 * from the concurrency table. This way the allow concurrency 3966 * check can be used as though a new connection is coming up, 3967 * after check, restore the connection to concurrency table. 3968 */ 3969 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, 3970 &info, &num_cxn_del); 3971 3972 status = policy_mgr_get_next_action(psoc, vdev_id, ch_freq, 3973 reason, &next_action); 3974 /* Restore the connection entry */ 3975 if (num_cxn_del) 3976 policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); 3977 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 3978 3979 if (QDF_IS_STATUS_ERROR(status)) 3980 goto chk_opportunistic_timer; 3981 3982 if (PM_NOP != next_action) 3983 status = policy_mgr_next_actions(psoc, vdev_id, 3984 next_action, reason, 3985 POLICY_MGR_DEF_REQ_ID); 3986 else 3987 status = QDF_STATUS_E_NOSUPPORT; 3988 3989 chk_opportunistic_timer: 3990 /* 3991 * If hw mode change failed restart the opportunistic timer to 3992 * Switch to single mac if required. 3993 */ 3994 if (status == QDF_STATUS_E_FAILURE) { 3995 policy_mgr_err("Failed to update HW modeStatus %d", status); 3996 policy_mgr_check_n_start_opportunistic_timer(psoc); 3997 } 3998 3999 return status; 4000 } 4001 4002 void policy_mgr_checkn_update_hw_mode_single_mac_mode( 4003 struct wlan_objmgr_psoc *psoc, uint32_t ch_freq) 4004 { 4005 uint8_t i; 4006 struct policy_mgr_psoc_priv_obj *pm_ctx; 4007 bool dbs_required_2g; 4008 pm_ctx = policy_mgr_get_context(psoc); 4009 if (!pm_ctx) { 4010 policy_mgr_err("Invalid Context"); 4011 return; 4012 } 4013 4014 if (!policy_mgr_is_hw_dbs_capable(psoc)) 4015 return; 4016 4017 if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state) 4018 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); 4019 4020 dbs_required_2g = 4021 policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G); 4022 4023 if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { 4024 policy_mgr_debug("DBS required for new connection"); 4025 return; 4026 } 4027 4028 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4029 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 4030 if (pm_conc_connection_list[i].in_use) { 4031 if (!WLAN_REG_IS_SAME_BAND_FREQS( 4032 ch_freq, pm_conc_connection_list[i].freq) && 4033 (WLAN_REG_IS_24GHZ_CH_FREQ( 4034 pm_conc_connection_list[i].freq) || 4035 WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) { 4036 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4037 policy_mgr_debug("DBS required"); 4038 return; 4039 } 4040 if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ( 4041 pm_conc_connection_list[i].freq)) { 4042 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4043 policy_mgr_debug("DBS required"); 4044 return; 4045 } 4046 } 4047 } 4048 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4049 pm_dbs_opportunistic_timer_handler((void *)psoc); 4050 } 4051 4052 void policy_mgr_check_and_stop_opportunistic_timer( 4053 struct wlan_objmgr_psoc *psoc, uint8_t id) 4054 { 4055 struct policy_mgr_psoc_priv_obj *pm_ctx; 4056 enum policy_mgr_conc_next_action action = PM_NOP; 4057 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4058 enum policy_mgr_conn_update_reason reason = 4059 POLICY_MGR_UPDATE_REASON_MAX; 4060 4061 pm_ctx = policy_mgr_get_context(psoc); 4062 if (!pm_ctx) { 4063 policy_mgr_err("Invalid Context"); 4064 return; 4065 } 4066 if (QDF_TIMER_STATE_RUNNING == 4067 pm_ctx->dbs_opportunistic_timer.state) { 4068 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); 4069 action = policy_mgr_need_opportunistic_upgrade(psoc, &reason); 4070 if (action) { 4071 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt); 4072 status = policy_mgr_next_actions(psoc, id, action, 4073 reason, 4074 POLICY_MGR_DEF_REQ_ID); 4075 if (status != QDF_STATUS_SUCCESS) { 4076 policy_mgr_err("Failed in policy_mgr_next_actions"); 4077 return; 4078 } 4079 status = qdf_wait_single_event( 4080 &pm_ctx->opportunistic_update_done_evt, 4081 CONNECTION_UPDATE_TIMEOUT); 4082 4083 if (!QDF_IS_STATUS_SUCCESS(status)) { 4084 policy_mgr_err("wait for event failed"); 4085 return; 4086 } 4087 } 4088 } 4089 } 4090 4091 void policy_mgr_set_hw_mode_change_in_progress( 4092 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value) 4093 { 4094 struct policy_mgr_psoc_priv_obj *pm_ctx; 4095 4096 pm_ctx = policy_mgr_get_context(psoc); 4097 if (!pm_ctx) { 4098 policy_mgr_err("Invalid Context"); 4099 return; 4100 } 4101 4102 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4103 pm_ctx->hw_mode_change_in_progress = value; 4104 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4105 4106 policy_mgr_debug("hw_mode_change_in_progress:%d", value); 4107 } 4108 4109 enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress( 4110 struct wlan_objmgr_psoc *psoc) 4111 { 4112 enum policy_mgr_hw_mode_change value; 4113 struct policy_mgr_psoc_priv_obj *pm_ctx; 4114 4115 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; 4116 4117 pm_ctx = policy_mgr_get_context(psoc); 4118 if (!pm_ctx) { 4119 policy_mgr_err("Invalid Context"); 4120 return value; 4121 } 4122 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 4123 value = pm_ctx->hw_mode_change_in_progress; 4124 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 4125 4126 return value; 4127 } 4128 4129 enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( 4130 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index) 4131 { 4132 struct policy_mgr_psoc_priv_obj *pm_ctx; 4133 struct policy_mgr_hw_mode_params hw_mode; 4134 enum policy_mgr_hw_mode_change value 4135 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; 4136 QDF_STATUS status; 4137 4138 pm_ctx = policy_mgr_get_context(psoc); 4139 if (!pm_ctx) { 4140 policy_mgr_err("Invalid Context"); 4141 return value; 4142 } 4143 4144 status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode); 4145 if (status != QDF_STATUS_SUCCESS) { 4146 policy_mgr_err("Failed to get HW mode index"); 4147 return value; 4148 } 4149 4150 if (hw_mode.dbs_cap) { 4151 policy_mgr_debug("DBS is requested with HW (%d)", 4152 hw_mode_index); 4153 value = POLICY_MGR_DBS_IN_PROGRESS; 4154 goto ret_value; 4155 } 4156 4157 if (hw_mode.sbs_cap) { 4158 policy_mgr_debug("SBS is requested with HW (%d)", 4159 hw_mode_index); 4160 value = POLICY_MGR_SBS_IN_PROGRESS; 4161 goto ret_value; 4162 } 4163 4164 value = POLICY_MGR_SMM_IN_PROGRESS; 4165 policy_mgr_debug("SMM is requested with HW (%d)", hw_mode_index); 4166 4167 ret_value: 4168 return value; 4169 } 4170 4171 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES 4172 bool 4173 policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc, 4174 struct wlan_objmgr_vdev *vdev, 4175 qdf_freq_t *ch_freq) 4176 { 4177 struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; 4178 uint8_t connection_count, i, j, sta_vdev_id; 4179 4180 *ch_freq = 0; 4181 /* 4182 * TDLS off channel is not allowed in any MCC scenario 4183 */ 4184 if (policy_mgr_current_concurrency_is_mcc(psoc)) { 4185 policy_mgr_dump_current_concurrency(psoc); 4186 policy_mgr_debug("TDLS off channel not allowed in MCC"); 4187 return false; 4188 } 4189 4190 /* 4191 * TDLS offchannel is done only when STA is connected on 2G channel and 4192 * the current concurrency is not MCC 4193 */ 4194 if (!policy_mgr_is_sta_connected_2g(psoc)) { 4195 policy_mgr_debug("STA not-connected on 2.4 Ghz"); 4196 return false; 4197 } 4198 4199 /* 4200 * 2 Port DBS scenario - Allow non-STA vdev channel for 4201 * TDLS off-channel operation 4202 * 4203 * 3 Port Scenario - If STA Vdev is on SCC, allow TDLS off-channel on 4204 * the channel of vdev on the other MAC 4205 * If STA vdev is standalone on one mac, and scc on another mac, then 4206 * allow TDLS off channel on other mac scc channel 4207 */ 4208 sta_vdev_id = wlan_vdev_get_id(vdev); 4209 connection_count = policy_mgr_get_connection_info(psoc, info); 4210 switch (connection_count) { 4211 case 1: 4212 return true; 4213 case 2: 4214 /* 4215 * Allow all the 5GHz/6GHz channels when STA is in SCC 4216 */ 4217 if (policy_mgr_current_concurrency_is_scc(psoc)) { 4218 *ch_freq = 0; 4219 return true; 4220 } else if (policy_mgr_is_current_hwmode_dbs(psoc)) { 4221 /* 4222 * In DBS case, allow off-channel operation on the 4223 * other mac 5GHz/6GHz channel where the STA is not 4224 * present 4225 * Don't consider SBS case since STA should be 4226 * connected in 2.4GHz channel for TDLS 4227 * off-channel and MCC on SBS ex. 3 PORT 4228 * 2.4GHz STA + 5GHz Lower MCC + 5GHz Upper will 4229 * not be allowed 4230 */ 4231 if (sta_vdev_id == info[0].vdev_id) 4232 *ch_freq = info[1].ch_freq; 4233 else 4234 *ch_freq = info[0].ch_freq; 4235 4236 return true; 4237 } 4238 4239 break; 4240 case 3: 4241 4242 /* 4243 * 3 Vdev SCC on 2.4GHz band. Allow TDLS off-channel operation 4244 * on all the 5GHz & 6GHz channels 4245 */ 4246 if (info[0].ch_freq == info[1].ch_freq && 4247 info[0].ch_freq == info[2].ch_freq) { 4248 *ch_freq = 0; 4249 return true; 4250 } 4251 4252 /* 4253 * DBS with SCC on one vdev scenario. Allow TDLS off-channel 4254 * on other mac frequency where STA is not present 4255 * SBS case is not considered since STA should be connected 4256 * on 2.4GHz and TDLS off-channel on SBS MCC is not allowed 4257 */ 4258 for (i = 0; i < connection_count; i++) { 4259 for (j = i + 1; j < connection_count; j++) { 4260 /* 4261 * Find 2 vdevs such that STA is one of the vdev 4262 * and STA + other vdev are not on same mac. 4263 * Return the foreign vdev frequency which is 4264 * not on same mac along with STA 4265 */ 4266 if (!policy_mgr_2_freq_always_on_same_mac( 4267 psoc, info[i].ch_freq, 4268 info[j].ch_freq)) { 4269 if (sta_vdev_id == info[i].vdev_id) { 4270 *ch_freq = info[j].ch_freq; 4271 return true; 4272 } else if (sta_vdev_id == 4273 info[j].vdev_id) { 4274 *ch_freq = info[i].ch_freq; 4275 return true; 4276 } 4277 } 4278 } 4279 } 4280 4281 return false; 4282 default: 4283 policy_mgr_debug("TDLS off channel not allowed on > 3 port conc"); 4284 break; 4285 } 4286 4287 return false; 4288 } 4289 #endif 4290