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