1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_policy_mgr_init_deinit.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_tables_no_dbs_i.h" 31 #include "wlan_policy_mgr_tables_1x1_dbs_i.h" 32 #include "wlan_policy_mgr_tables_2x2_dbs_i.h" 33 #include "wlan_policy_mgr_tables_2x2_5g_1x1_2g.h" 34 #include "wlan_policy_mgr_tables_2x2_2g_1x1_5g.h" 35 #include "wlan_policy_mgr_tables_2x2_dbs_sbs_i.h" 36 #include "wlan_policy_mgr_i.h" 37 #include "qdf_types.h" 38 #include "qdf_trace.h" 39 #include "wlan_objmgr_global_obj.h" 40 #include "target_if.h" 41 42 static QDF_STATUS policy_mgr_psoc_obj_create_cb(struct wlan_objmgr_psoc *psoc, 43 void *data) 44 { 45 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 46 47 policy_mgr_ctx = qdf_mem_malloc( 48 sizeof(struct policy_mgr_psoc_priv_obj)); 49 if (!policy_mgr_ctx) 50 return QDF_STATUS_E_FAILURE; 51 52 policy_mgr_ctx->psoc = psoc; 53 policy_mgr_ctx->old_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX; 54 policy_mgr_ctx->new_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX; 55 56 wlan_objmgr_psoc_component_obj_attach(psoc, 57 WLAN_UMAC_COMP_POLICY_MGR, 58 policy_mgr_ctx, 59 QDF_STATUS_SUCCESS); 60 61 return QDF_STATUS_SUCCESS; 62 } 63 64 static QDF_STATUS policy_mgr_psoc_obj_destroy_cb(struct wlan_objmgr_psoc *psoc, 65 void *data) 66 { 67 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 68 69 policy_mgr_ctx = policy_mgr_get_context(psoc); 70 wlan_objmgr_psoc_component_obj_detach(psoc, 71 WLAN_UMAC_COMP_POLICY_MGR, 72 policy_mgr_ctx); 73 qdf_mem_free(policy_mgr_ctx); 74 75 return QDF_STATUS_SUCCESS; 76 } 77 78 static void policy_mgr_psoc_obj_status_cb(struct wlan_objmgr_psoc *psoc, 79 void *data, QDF_STATUS status) 80 { 81 return; 82 } 83 84 static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev, 85 void *data) 86 { 87 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 88 struct wlan_objmgr_psoc *psoc; 89 90 psoc = wlan_pdev_get_psoc(pdev); 91 policy_mgr_ctx = policy_mgr_get_context(psoc); 92 if (!policy_mgr_ctx) { 93 policy_mgr_err("invalid context"); 94 return QDF_STATUS_E_FAILURE; 95 } 96 97 policy_mgr_ctx->pdev = pdev; 98 99 wlan_reg_register_chan_change_callback(psoc, 100 policy_mgr_reg_chan_change_callback, NULL); 101 102 return QDF_STATUS_SUCCESS; 103 } 104 105 static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev, 106 void *data) 107 { 108 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; 109 struct wlan_objmgr_psoc *psoc; 110 111 psoc = wlan_pdev_get_psoc(pdev); 112 policy_mgr_ctx = policy_mgr_get_context(psoc); 113 if (!policy_mgr_ctx) { 114 policy_mgr_err("invalid context"); 115 return QDF_STATUS_E_FAILURE; 116 } 117 118 policy_mgr_ctx->pdev = NULL; 119 wlan_reg_unregister_chan_change_callback(psoc, 120 policy_mgr_reg_chan_change_callback); 121 122 return QDF_STATUS_SUCCESS; 123 } 124 125 static QDF_STATUS policy_mgr_vdev_obj_create_cb(struct wlan_objmgr_vdev *vdev, 126 void *data) 127 { 128 return QDF_STATUS_SUCCESS; 129 } 130 131 static QDF_STATUS policy_mgr_vdev_obj_destroy_cb(struct wlan_objmgr_vdev *vdev, 132 void *data) 133 { 134 return QDF_STATUS_SUCCESS; 135 } 136 137 static void policy_mgr_vdev_obj_status_cb(struct wlan_objmgr_vdev *vdev, 138 void *data, QDF_STATUS status) 139 { 140 return; 141 } 142 143 #ifdef WLAN_FEATURE_11BE_MLO 144 static QDF_STATUS policy_mgr_register_link_switch_notifier(void) 145 { 146 QDF_STATUS status; 147 148 status = mlo_mgr_register_link_switch_notifier( 149 WLAN_UMAC_COMP_POLICY_MGR, 150 policy_mgr_link_switch_notifier_cb); 151 if (status == QDF_STATUS_E_NOSUPPORT) { 152 status = QDF_STATUS_SUCCESS; 153 policy_mgr_debug("Link switch not supported"); 154 } else if (status != QDF_STATUS_SUCCESS) { 155 policy_mgr_err("Failed to register link switch notifier for policy mgr!"); 156 } 157 158 return status; 159 } 160 161 static QDF_STATUS policy_mgr_unregister_link_switch_notifier(void) 162 { 163 QDF_STATUS status; 164 165 status = mlo_mgr_unregister_link_switch_notifier( 166 WLAN_UMAC_COMP_POLICY_MGR); 167 if (status == QDF_STATUS_E_NOSUPPORT) 168 status = QDF_STATUS_SUCCESS; 169 else if (status != QDF_STATUS_SUCCESS) 170 policy_mgr_err("Failed to unregister link switch notifier for policy mgr!"); 171 172 return status; 173 } 174 #else 175 static QDF_STATUS policy_mgr_register_link_switch_notifier(void) 176 { 177 return QDF_STATUS_SUCCESS; 178 } 179 180 static QDF_STATUS policy_mgr_unregister_link_switch_notifier(void) 181 { 182 return QDF_STATUS_SUCCESS; 183 } 184 #endif 185 186 QDF_STATUS policy_mgr_init(void) 187 { 188 QDF_STATUS status = QDF_STATUS_SUCCESS; 189 status = wlan_objmgr_register_psoc_create_handler( 190 WLAN_UMAC_COMP_POLICY_MGR, 191 policy_mgr_psoc_obj_create_cb, 192 NULL); 193 if (status != QDF_STATUS_SUCCESS) { 194 policy_mgr_err("Failed to register psoc obj create cback"); 195 goto err_psoc_create; 196 } 197 198 status = wlan_objmgr_register_psoc_destroy_handler( 199 WLAN_UMAC_COMP_POLICY_MGR, 200 policy_mgr_psoc_obj_destroy_cb, 201 NULL); 202 if (status != QDF_STATUS_SUCCESS) { 203 policy_mgr_err("Failed to register psoc obj delete cback"); 204 goto err_psoc_delete; 205 } 206 207 status = wlan_objmgr_register_psoc_status_handler( 208 WLAN_UMAC_COMP_POLICY_MGR, 209 policy_mgr_psoc_obj_status_cb, 210 NULL); 211 if (status != QDF_STATUS_SUCCESS) { 212 policy_mgr_err("Failed to register psoc obj status cback"); 213 goto err_psoc_status; 214 } 215 216 status = wlan_objmgr_register_pdev_create_handler( 217 WLAN_UMAC_COMP_POLICY_MGR, 218 policy_mgr_pdev_obj_create_cb, 219 NULL); 220 if (status != QDF_STATUS_SUCCESS) { 221 policy_mgr_err("Failed to register pdev obj create cback"); 222 goto err_pdev_create; 223 } 224 225 status = wlan_objmgr_register_pdev_destroy_handler( 226 WLAN_UMAC_COMP_POLICY_MGR, 227 policy_mgr_pdev_obj_destroy_cb, 228 NULL); 229 if (status != QDF_STATUS_SUCCESS) { 230 policy_mgr_err("Failed to register pdev obj delete cback"); 231 goto err_pdev_delete; 232 } 233 234 status = wlan_objmgr_register_vdev_create_handler( 235 WLAN_UMAC_COMP_POLICY_MGR, 236 policy_mgr_vdev_obj_create_cb, 237 NULL); 238 if (status != QDF_STATUS_SUCCESS) { 239 policy_mgr_err("Failed to register vdev obj create cback"); 240 goto err_vdev_create; 241 } 242 243 status = wlan_objmgr_register_vdev_destroy_handler( 244 WLAN_UMAC_COMP_POLICY_MGR, 245 policy_mgr_vdev_obj_destroy_cb, 246 NULL); 247 if (status != QDF_STATUS_SUCCESS) { 248 policy_mgr_err("Failed to register vdev obj delete cback"); 249 goto err_vdev_delete; 250 } 251 252 status = wlan_objmgr_register_vdev_status_handler( 253 WLAN_UMAC_COMP_POLICY_MGR, 254 policy_mgr_vdev_obj_status_cb, 255 NULL); 256 if (status != QDF_STATUS_SUCCESS) { 257 policy_mgr_err("Failed to register vdev obj status cback"); 258 goto err_vdev_status; 259 } 260 261 status = policy_mgr_register_link_switch_notifier(); 262 if (status != QDF_STATUS_SUCCESS) { 263 policy_mgr_err("Failed to register link switch cback"); 264 goto err_link_switch; 265 } 266 267 policy_mgr_notice("Callbacks registered with obj mgr"); 268 269 return QDF_STATUS_SUCCESS; 270 err_link_switch: 271 wlan_objmgr_unregister_vdev_status_handler( 272 WLAN_UMAC_COMP_POLICY_MGR, 273 policy_mgr_vdev_obj_status_cb, 274 NULL); 275 err_vdev_status: 276 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, 277 policy_mgr_vdev_obj_destroy_cb, 278 NULL); 279 err_vdev_delete: 280 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR, 281 policy_mgr_vdev_obj_create_cb, 282 NULL); 283 err_vdev_create: 284 wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, 285 policy_mgr_pdev_obj_destroy_cb, 286 NULL); 287 err_pdev_delete: 288 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR, 289 policy_mgr_pdev_obj_create_cb, 290 NULL); 291 err_pdev_create: 292 wlan_objmgr_unregister_psoc_status_handler(WLAN_UMAC_COMP_POLICY_MGR, 293 policy_mgr_psoc_obj_status_cb, 294 NULL); 295 err_psoc_status: 296 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, 297 policy_mgr_psoc_obj_destroy_cb, 298 NULL); 299 err_psoc_delete: 300 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_POLICY_MGR, 301 policy_mgr_psoc_obj_create_cb, 302 NULL); 303 err_psoc_create: 304 return status; 305 } 306 307 QDF_STATUS policy_mgr_deinit(void) 308 { 309 QDF_STATUS status; 310 311 status = policy_mgr_unregister_link_switch_notifier(); 312 if (status != QDF_STATUS_SUCCESS) 313 policy_mgr_err("Failed to deregister link switch cback"); 314 315 status = wlan_objmgr_unregister_psoc_status_handler( 316 WLAN_UMAC_COMP_POLICY_MGR, 317 policy_mgr_psoc_obj_status_cb, 318 NULL); 319 if (status != QDF_STATUS_SUCCESS) 320 policy_mgr_err("Failed to deregister psoc obj status cback"); 321 322 status = wlan_objmgr_unregister_psoc_destroy_handler( 323 WLAN_UMAC_COMP_POLICY_MGR, 324 policy_mgr_psoc_obj_destroy_cb, 325 NULL); 326 if (status != QDF_STATUS_SUCCESS) 327 policy_mgr_err("Failed to deregister psoc obj delete cback"); 328 329 status = wlan_objmgr_unregister_psoc_create_handler( 330 WLAN_UMAC_COMP_POLICY_MGR, 331 policy_mgr_psoc_obj_create_cb, 332 NULL); 333 if (status != QDF_STATUS_SUCCESS) 334 policy_mgr_err("Failed to deregister psoc obj create cback"); 335 336 status = wlan_objmgr_unregister_pdev_destroy_handler( 337 WLAN_UMAC_COMP_POLICY_MGR, 338 policy_mgr_pdev_obj_destroy_cb, 339 NULL); 340 if (status != QDF_STATUS_SUCCESS) 341 policy_mgr_err("Failed to deregister pdev obj delete cback"); 342 343 status = wlan_objmgr_unregister_pdev_create_handler( 344 WLAN_UMAC_COMP_POLICY_MGR, 345 policy_mgr_pdev_obj_create_cb, 346 NULL); 347 if (status != QDF_STATUS_SUCCESS) 348 policy_mgr_err("Failed to deregister pdev obj create cback"); 349 350 status = wlan_objmgr_unregister_vdev_status_handler( 351 WLAN_UMAC_COMP_POLICY_MGR, 352 policy_mgr_vdev_obj_status_cb, 353 NULL); 354 if (status != QDF_STATUS_SUCCESS) 355 policy_mgr_err("Failed to deregister vdev obj status cback"); 356 357 status = wlan_objmgr_unregister_vdev_destroy_handler( 358 WLAN_UMAC_COMP_POLICY_MGR, 359 policy_mgr_vdev_obj_destroy_cb, 360 NULL); 361 if (status != QDF_STATUS_SUCCESS) 362 policy_mgr_err("Failed to deregister vdev obj delete cback"); 363 364 status = wlan_objmgr_unregister_vdev_create_handler( 365 WLAN_UMAC_COMP_POLICY_MGR, 366 policy_mgr_vdev_obj_create_cb, 367 NULL); 368 if (status != QDF_STATUS_SUCCESS) 369 policy_mgr_err("Failed to deregister vdev obj create cback"); 370 371 policy_mgr_info("deregistered callbacks with obj mgr successfully"); 372 373 return status; 374 } 375 376 QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc) 377 { 378 struct policy_mgr_psoc_priv_obj *pm_ctx; 379 380 pm_ctx = policy_mgr_get_context(psoc); 381 if (!pm_ctx) { 382 policy_mgr_err("Invalid Context"); 383 return QDF_STATUS_E_FAILURE; 384 } 385 386 if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( 387 &pm_ctx->qdf_conc_list_lock))) { 388 policy_mgr_err("Failed to init qdf_conc_list_lock"); 389 QDF_ASSERT(0); 390 return QDF_STATUS_E_FAILURE; 391 } 392 393 pm_ctx->sta_ap_intf_check_work_info = qdf_mem_malloc( 394 sizeof(struct sta_ap_intf_check_work_ctx)); 395 if (!pm_ctx->sta_ap_intf_check_work_info) { 396 qdf_mutex_destroy(&pm_ctx->qdf_conc_list_lock); 397 return QDF_STATUS_E_FAILURE; 398 } 399 pm_ctx->sta_ap_intf_check_work_info->psoc = psoc; 400 pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id = 401 WLAN_UMAC_VDEV_ID_MAX; 402 pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason = 403 CSA_REASON_UNKNOWN; 404 if (QDF_IS_STATUS_ERROR(qdf_delayed_work_create( 405 &pm_ctx->sta_ap_intf_check_work, 406 policy_mgr_check_sta_ap_concurrent_ch_intf, 407 pm_ctx))) { 408 policy_mgr_err("Failed to create dealyed work queue"); 409 qdf_mutex_destroy(&pm_ctx->qdf_conc_list_lock); 410 qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info); 411 return QDF_STATUS_E_FAILURE; 412 } 413 414 return QDF_STATUS_SUCCESS; 415 } 416 417 QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) 418 { 419 struct policy_mgr_psoc_priv_obj *pm_ctx; 420 421 pm_ctx = policy_mgr_get_context(psoc); 422 if (!pm_ctx) { 423 policy_mgr_err("Invalid Context"); 424 return QDF_STATUS_E_FAILURE; 425 } 426 427 if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( 428 &pm_ctx->qdf_conc_list_lock))) { 429 policy_mgr_err("Failed to destroy qdf_conc_list_lock"); 430 QDF_ASSERT(0); 431 return QDF_STATUS_E_FAILURE; 432 } 433 434 if (pm_ctx->hw_mode.hw_mode_list) { 435 qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); 436 pm_ctx->hw_mode.hw_mode_list = NULL; 437 policy_mgr_debug("HW list is freed"); 438 } 439 440 if (pm_ctx->sta_ap_intf_check_work_info) { 441 qdf_delayed_work_destroy(&pm_ctx->sta_ap_intf_check_work); 442 qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info); 443 pm_ctx->sta_ap_intf_check_work_info = NULL; 444 } 445 446 return QDF_STATUS_SUCCESS; 447 } 448 449 #ifdef FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT 450 static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc) 451 { 452 struct wmi_unified *wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 453 454 if (!wmi_handle) { 455 policy_mgr_debug("Invalid WMI handle"); 456 return; 457 } 458 459 if (wmi_service_enabled(wmi_handle, 460 wmi_service_no_interband_mcc_support) && 461 !wmi_service_enabled(wmi_handle, 462 wmi_service_dual_band_simultaneous_support)) { 463 second_connection_pcl_non_dbs_table = 464 &second_connection_pcl_nodbs_no_interband_mcc_table; 465 third_connection_pcl_non_dbs_table = 466 &third_connection_pcl_nodbs_no_interband_mcc_table; 467 } else { 468 second_connection_pcl_non_dbs_table = 469 &second_connection_pcl_nodbs_table; 470 third_connection_pcl_non_dbs_table = 471 &third_connection_pcl_nodbs_table; 472 } 473 } 474 #else 475 static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc) 476 { 477 second_connection_pcl_non_dbs_table = 478 &second_connection_pcl_nodbs_table; 479 third_connection_pcl_non_dbs_table = 480 &third_connection_pcl_nodbs_table; 481 } 482 #endif 483 484 #ifdef WLAN_FEATURE_11BE_MLO 485 static inline void policy_mgr_memzero_disabled_ml_list(void) 486 { 487 qdf_mem_zero(pm_disabled_ml_links, sizeof(pm_disabled_ml_links)); 488 } 489 490 static QDF_STATUS 491 policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx) 492 { 493 QDF_STATUS qdf_status; 494 495 qdf_atomic_init(&pm_ctx->link_in_progress); 496 qdf_status = qdf_event_create(&pm_ctx->set_link_update_done_evt); 497 if (QDF_IS_STATUS_ERROR(qdf_status)) { 498 policy_mgr_err("init event failed for for set_link_update_done_evt"); 499 return QDF_STATUS_E_FAILURE; 500 } 501 502 return QDF_STATUS_SUCCESS; 503 } 504 505 static QDF_STATUS 506 policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx) 507 { 508 QDF_STATUS qdf_status; 509 510 qdf_atomic_set(&pm_ctx->link_in_progress, 0); 511 qdf_status = qdf_event_destroy(&pm_ctx->set_link_update_done_evt); 512 if (QDF_IS_STATUS_ERROR(qdf_status)) { 513 policy_mgr_err("deinit event failed for set_link_update_done_evt"); 514 return QDF_STATUS_E_FAILURE; 515 } 516 517 return QDF_STATUS_SUCCESS; 518 } 519 520 #else 521 static inline void policy_mgr_memzero_disabled_ml_list(void) {} 522 523 static inline QDF_STATUS 524 policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx) 525 { 526 return QDF_STATUS_SUCCESS; 527 } 528 529 static inline QDF_STATUS 530 policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx) 531 { 532 return QDF_STATUS_SUCCESS; 533 } 534 #endif 535 536 QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) 537 { 538 QDF_STATUS status; 539 struct policy_mgr_psoc_priv_obj *pm_ctx; 540 bool enable_mcc_adaptive_sch = false; 541 542 pm_ctx = policy_mgr_get_context(psoc); 543 if (!pm_ctx) { 544 policy_mgr_err("Invalid Context"); 545 return QDF_STATUS_E_FAILURE; 546 } 547 548 policy_mgr_debug("Initializing the policy manager"); 549 550 /* init pm_conc_connection_list */ 551 qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list)); 552 policy_mgr_memzero_disabled_ml_list(); 553 policy_mgr_clear_concurrent_session_count(psoc); 554 /* init dbs_opportunistic_timer */ 555 status = qdf_mc_timer_init(&pm_ctx->dbs_opportunistic_timer, 556 QDF_TIMER_TYPE_SW, 557 pm_dbs_opportunistic_timer_handler, 558 (void *)psoc); 559 if (!QDF_IS_STATUS_SUCCESS(status)) { 560 policy_mgr_err("Failed to init DBS opportunistic timer"); 561 return status; 562 } 563 564 status = policy_mgr_init_ml_link_update(pm_ctx); 565 if (QDF_IS_STATUS_ERROR(status)) 566 return status; 567 568 /* init connection_update_done_evt */ 569 status = policy_mgr_init_connection_update(pm_ctx); 570 if (!QDF_IS_STATUS_SUCCESS(status)) { 571 policy_mgr_err("connection_update_done_evt init failed"); 572 return status; 573 } 574 575 status = qdf_event_create(&pm_ctx->opportunistic_update_done_evt); 576 if (!QDF_IS_STATUS_SUCCESS(status)) { 577 policy_mgr_err("opportunistic_update_done_evt init failed"); 578 return status; 579 } 580 581 status = qdf_event_create(&pm_ctx->channel_switch_complete_evt); 582 if (!QDF_IS_STATUS_SUCCESS(status)) { 583 policy_mgr_err("channel_switch_complete_evt init failed"); 584 return status; 585 } 586 policy_mgr_get_mcc_adaptive_sch(psoc, &enable_mcc_adaptive_sch); 587 policy_mgr_set_dynamic_mcc_adaptive_sch(psoc, enable_mcc_adaptive_sch); 588 pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; 589 /* reset sap mandatory channels */ 590 status = policy_mgr_reset_sap_mandatory_channels(psoc); 591 if (QDF_IS_STATUS_ERROR(status)) { 592 policy_mgr_err("failed to reset mandatory channels"); 593 return status; 594 } 595 596 /* init PCL table & function pointers based on HW capability */ 597 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) || 598 policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) 599 policy_mgr_get_current_pref_hw_mode_ptr = 600 policy_mgr_get_current_pref_hw_mode_dbs_2x2; 601 else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) 602 policy_mgr_get_current_pref_hw_mode_ptr = 603 policy_mgr_get_current_pref_hw_mode_dual_dbs; 604 else 605 policy_mgr_get_current_pref_hw_mode_ptr = 606 policy_mgr_get_current_pref_hw_mode_dbs_1x1; 607 608 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) && 609 policy_mgr_is_hw_sbs_capable(psoc)) 610 second_connection_pcl_dbs_table = 611 &pm_second_connection_pcl_dbs_sbs_2x2_table; 612 else if (policy_mgr_is_hw_dbs_2x2_capable(psoc) || 613 policy_mgr_is_hw_dbs_required_for_band(psoc, 614 HW_MODE_MAC_BAND_2G) || 615 policy_mgr_is_2x2_1x1_dbs_capable(psoc)) 616 second_connection_pcl_dbs_table = 617 &pm_second_connection_pcl_dbs_2x2_table; 618 else 619 second_connection_pcl_dbs_table = 620 &pm_second_connection_pcl_dbs_1x1_table; 621 622 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) && 623 policy_mgr_is_hw_sbs_capable(psoc)) 624 third_connection_pcl_dbs_table = 625 &pm_third_connection_pcl_dbs_sbs_2x2_table; 626 else if (policy_mgr_is_hw_dbs_2x2_capable(psoc) || 627 policy_mgr_is_hw_dbs_required_for_band(psoc, 628 HW_MODE_MAC_BAND_2G) || 629 policy_mgr_is_2x2_1x1_dbs_capable(psoc)) 630 third_connection_pcl_dbs_table = 631 &pm_third_connection_pcl_dbs_2x2_table; 632 else 633 third_connection_pcl_dbs_table = 634 &pm_third_connection_pcl_dbs_1x1_table; 635 636 /* Initialize non-DBS pcl table pointer to particular table*/ 637 policy_mgr_init_non_dbs_pcl(psoc); 638 639 if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) { 640 if (policy_mgr_is_hw_dbs_required_for_band(psoc, 641 HW_MODE_MAC_BAND_2G)) { 642 next_action_two_connection_table = 643 &pm_next_action_two_connection_dbs_2x2_table; 644 policy_mgr_debug("using hst/hsp policy manager table"); 645 } else { 646 next_action_two_connection_table = 647 &pm_next_action_two_connection_dbs_2x2_table_v2; 648 policy_mgr_debug("using hmt policy manager table"); 649 } 650 } else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) { 651 next_action_two_connection_table = 652 &pm_next_action_two_connection_dbs_2x2_5g_1x1_2g_table; 653 next_action_two_connection_2x2_2g_1x1_5g_table = 654 &pm_next_action_two_connection_dbs_2x2_2g_1x1_5g_table; 655 } else { 656 next_action_two_connection_table = 657 &pm_next_action_two_connection_dbs_1x1_table; 658 } 659 660 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) || 661 policy_mgr_is_hw_dbs_required_for_band(psoc, 662 HW_MODE_MAC_BAND_2G)) { 663 next_action_three_connection_table = 664 &pm_next_action_three_connection_dbs_2x2_table; 665 } else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) { 666 next_action_three_connection_table = 667 &pm_next_action_three_connection_dbs_2x2_5g_1x1_2g_table; 668 next_action_three_connection_2x2_2g_1x1_5g_table = 669 &pm_next_action_three_connection_dbs_2x2_2g_1x1_5g_table; 670 } else { 671 next_action_three_connection_table = 672 &pm_next_action_three_connection_dbs_1x1_table; 673 } 674 policy_mgr_debug("is DBS Capable %d, is SBS Capable %d", 675 policy_mgr_is_hw_dbs_capable(psoc), 676 policy_mgr_is_hw_sbs_capable(psoc)); 677 policy_mgr_debug("is2x2 %d, 2g-on-dbs %d is2x2+1x1 %d, is2x2_5g+1x1_2g %d, is2x2_2g+1x1_5g %d", 678 policy_mgr_is_hw_dbs_2x2_capable(psoc), 679 policy_mgr_is_hw_dbs_required_for_band( 680 psoc, HW_MODE_MAC_BAND_2G), 681 policy_mgr_is_2x2_1x1_dbs_capable(psoc), 682 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc), 683 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)); 684 685 return QDF_STATUS_SUCCESS; 686 } 687 688 QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) 689 { 690 QDF_STATUS status = QDF_STATUS_SUCCESS; 691 struct policy_mgr_psoc_priv_obj *pm_ctx; 692 693 pm_ctx = policy_mgr_get_context(psoc); 694 if (!pm_ctx) { 695 policy_mgr_err("Invalid Context"); 696 return QDF_STATUS_E_FAILURE; 697 } 698 699 /* destroy connection_update_done_evt */ 700 if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy 701 (&pm_ctx->connection_update_done_evt))) { 702 policy_mgr_err("Failed to destroy connection_update_done_evt"); 703 status = QDF_STATUS_E_FAILURE; 704 QDF_ASSERT(0); 705 } 706 707 /* destroy opportunistic_update_done_evt */ 708 if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy 709 (&pm_ctx->opportunistic_update_done_evt))) { 710 policy_mgr_err("Failed to destroy opportunistic_update_done_evt"); 711 status = QDF_STATUS_E_FAILURE; 712 QDF_ASSERT(0); 713 } 714 /* destroy channel_switch_complete_evt */ 715 if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy 716 (&pm_ctx->channel_switch_complete_evt))) { 717 policy_mgr_err("Failed to destroy channel_switch_complete evt"); 718 status = QDF_STATUS_E_FAILURE; 719 QDF_ASSERT(0); 720 } 721 722 if (QDF_IS_STATUS_ERROR(policy_mgr_deinit_ml_link_update(pm_ctx))) { 723 status = QDF_STATUS_E_FAILURE; 724 QDF_ASSERT(0); 725 } 726 727 /* deallocate dbs_opportunistic_timer */ 728 if (QDF_TIMER_STATE_RUNNING == 729 qdf_mc_timer_get_current_state( 730 &pm_ctx->dbs_opportunistic_timer)) { 731 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); 732 } 733 734 if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_destroy( 735 &pm_ctx->dbs_opportunistic_timer))) { 736 policy_mgr_err("Cannot deallocate dbs opportunistic timer"); 737 status = QDF_STATUS_E_FAILURE; 738 QDF_ASSERT(0); 739 } 740 741 /* reset sap mandatory channels */ 742 if (QDF_IS_STATUS_ERROR( 743 policy_mgr_reset_sap_mandatory_channels(psoc))) { 744 policy_mgr_err("failed to reset sap mandatory channels"); 745 status = QDF_STATUS_E_FAILURE; 746 QDF_ASSERT(0); 747 } 748 749 /* deinit pm_conc_connection_list */ 750 qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list)); 751 policy_mgr_clear_concurrent_session_count(psoc); 752 753 return status; 754 } 755 756 QDF_STATUS policy_mgr_register_conc_cb(struct wlan_objmgr_psoc *psoc, 757 struct policy_mgr_conc_cbacks *conc_cbacks) 758 { 759 struct policy_mgr_psoc_priv_obj *pm_ctx; 760 761 pm_ctx = policy_mgr_get_context(psoc); 762 if (!pm_ctx) { 763 policy_mgr_err("Invalid Context"); 764 return QDF_STATUS_E_FAILURE; 765 } 766 767 pm_ctx->conc_cbacks.connection_info_update = 768 conc_cbacks->connection_info_update; 769 return QDF_STATUS_SUCCESS; 770 } 771 772 QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, 773 struct policy_mgr_sme_cbacks *sme_cbacks) 774 { 775 struct policy_mgr_psoc_priv_obj *pm_ctx; 776 777 pm_ctx = policy_mgr_get_context(psoc); 778 if (!pm_ctx) { 779 policy_mgr_err("Invalid Context"); 780 return QDF_STATUS_E_FAILURE; 781 } 782 783 pm_ctx->sme_cbacks.sme_get_nss_for_vdev = 784 sme_cbacks->sme_get_nss_for_vdev; 785 pm_ctx->sme_cbacks.sme_nss_update_request = 786 sme_cbacks->sme_nss_update_request; 787 if (!policy_mgr_is_hwmode_offload_enabled(psoc)) 788 pm_ctx->sme_cbacks.sme_pdev_set_hw_mode = 789 sme_cbacks->sme_pdev_set_hw_mode; 790 pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config = 791 sme_cbacks->sme_soc_set_dual_mac_config; 792 pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval = 793 sme_cbacks->sme_change_mcc_beacon_interval; 794 pm_ctx->sme_cbacks.sme_rso_start_cb = 795 sme_cbacks->sme_rso_start_cb; 796 pm_ctx->sme_cbacks.sme_rso_stop_cb = 797 sme_cbacks->sme_rso_stop_cb; 798 pm_ctx->sme_cbacks.sme_change_sap_csa_count = 799 sme_cbacks->sme_change_sap_csa_count; 800 pm_ctx->sme_cbacks.sme_sap_update_ch_width = 801 sme_cbacks->sme_sap_update_ch_width; 802 803 return QDF_STATUS_SUCCESS; 804 } 805 806 /** 807 * policy_mgr_register_hdd_cb() - register HDD callbacks 808 * @psoc: PSOC object information 809 * @hdd_cbacks: function pointers from HDD 810 * 811 * API, allows HDD to register callbacks to be invoked by policy 812 * mgr 813 * 814 * Return: SUCCESS, 815 * Failure (if registration fails) 816 */ 817 QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, 818 struct policy_mgr_hdd_cbacks *hdd_cbacks) 819 { 820 struct policy_mgr_psoc_priv_obj *pm_ctx; 821 822 pm_ctx = policy_mgr_get_context(psoc); 823 if (!pm_ctx) { 824 policy_mgr_err("Invalid Context"); 825 return QDF_STATUS_E_FAILURE; 826 } 827 828 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = 829 hdd_cbacks->sap_restart_chan_switch_cb; 830 pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = 831 hdd_cbacks->wlan_hdd_get_channel_for_sap_restart; 832 pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = 833 hdd_cbacks->get_mode_for_non_connected_vdev; 834 pm_ctx->hdd_cbacks.hdd_get_device_mode = 835 hdd_cbacks->hdd_get_device_mode; 836 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = 837 hdd_cbacks->hdd_is_chan_switch_in_progress; 838 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = 839 hdd_cbacks->hdd_is_cac_in_progress; 840 pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = 841 hdd_cbacks->hdd_get_ap_6ghz_capable; 842 pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = 843 hdd_cbacks->wlan_hdd_indicate_active_ndp_cnt; 844 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = 845 hdd_cbacks->wlan_get_ap_prefer_conc_ch_params; 846 pm_ctx->hdd_cbacks.wlan_get_sap_acs_band = 847 hdd_cbacks->wlan_get_sap_acs_band; 848 pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb = 849 hdd_cbacks->wlan_check_cc_intf_cb; 850 pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb = 851 hdd_cbacks->wlan_set_tx_rx_nss_cb; 852 853 return QDF_STATUS_SUCCESS; 854 } 855 856 QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc) 857 { 858 struct policy_mgr_psoc_priv_obj *pm_ctx; 859 860 pm_ctx = policy_mgr_get_context(psoc); 861 if (!pm_ctx) { 862 policy_mgr_err("Invalid Context"); 863 return QDF_STATUS_E_FAILURE; 864 } 865 866 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL; 867 pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL; 868 pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = NULL; 869 pm_ctx->hdd_cbacks.hdd_get_device_mode = NULL; 870 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = NULL; 871 pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = NULL; 872 pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = NULL; 873 pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = NULL; 874 pm_ctx->hdd_cbacks.wlan_get_sap_acs_band = NULL; 875 pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb = NULL; 876 877 return QDF_STATUS_SUCCESS; 878 } 879 880 QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc, 881 struct policy_mgr_wma_cbacks *wma_cbacks) 882 { 883 struct policy_mgr_psoc_priv_obj *pm_ctx; 884 885 pm_ctx = policy_mgr_get_context(psoc); 886 if (!pm_ctx) { 887 policy_mgr_err("Invalid Context"); 888 return QDF_STATUS_E_FAILURE; 889 } 890 891 pm_ctx->wma_cbacks.wma_get_connection_info = 892 wma_cbacks->wma_get_connection_info; 893 894 return QDF_STATUS_SUCCESS; 895 } 896 897 QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc, 898 struct policy_mgr_cdp_cbacks *cdp_cbacks) 899 { 900 struct policy_mgr_psoc_priv_obj *pm_ctx; 901 902 pm_ctx = policy_mgr_get_context(psoc); 903 if (!pm_ctx) { 904 policy_mgr_err("Invalid Context"); 905 return QDF_STATUS_E_FAILURE; 906 } 907 908 pm_ctx->cdp_cbacks.cdp_update_mac_id = 909 cdp_cbacks->cdp_update_mac_id; 910 911 return QDF_STATUS_SUCCESS; 912 } 913 914 QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, 915 struct policy_mgr_dp_cbacks *dp_cbacks) 916 { 917 struct policy_mgr_psoc_priv_obj *pm_ctx; 918 919 pm_ctx = policy_mgr_get_context(psoc); 920 if (!pm_ctx) { 921 policy_mgr_err("Invalid Context"); 922 return QDF_STATUS_E_FAILURE; 923 } 924 925 pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency = 926 dp_cbacks->hdd_disable_rx_ol_in_concurrency; 927 pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb = 928 dp_cbacks->hdd_set_rx_mode_rps_cb; 929 pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb = 930 dp_cbacks->hdd_ipa_set_mcc_mode_cb; 931 pm_ctx->dp_cbacks.hdd_v2_flow_pool_map = 932 dp_cbacks->hdd_v2_flow_pool_map; 933 pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap = 934 dp_cbacks->hdd_v2_flow_pool_unmap; 935 pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw = 936 dp_cbacks->hdd_ipa_set_perf_level_bw; 937 938 return QDF_STATUS_SUCCESS; 939 } 940 941 QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, 942 struct policy_mgr_tdls_cbacks *tdls_cbacks) 943 { 944 struct policy_mgr_psoc_priv_obj *pm_ctx; 945 946 pm_ctx = policy_mgr_get_context(psoc); 947 if (!pm_ctx) { 948 policy_mgr_err("Invalid Context"); 949 return QDF_STATUS_E_FAILURE; 950 } 951 952 pm_ctx->tdls_cbacks.tdls_notify_increment_session = 953 tdls_cbacks->tdls_notify_increment_session; 954 pm_ctx->tdls_cbacks.tdls_notify_decrement_session = 955 tdls_cbacks->tdls_notify_decrement_session; 956 957 return QDF_STATUS_SUCCESS; 958 } 959 960 QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc, 961 send_mode_change_event_cb mode_change_cb) 962 { 963 struct policy_mgr_psoc_priv_obj *pm_ctx; 964 965 pm_ctx = policy_mgr_get_context(psoc); 966 if (!pm_ctx) { 967 policy_mgr_err("Invalid Context"); 968 return QDF_STATUS_E_FAILURE; 969 } 970 971 pm_ctx->mode_change_cb = mode_change_cb; 972 973 return QDF_STATUS_SUCCESS; 974 } 975 976 QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc) 977 { 978 struct policy_mgr_psoc_priv_obj *pm_ctx; 979 980 pm_ctx = policy_mgr_get_context(psoc); 981 if (!pm_ctx) { 982 policy_mgr_err("Invalid Context"); 983 return QDF_STATUS_E_FAILURE; 984 } 985 986 pm_ctx->mode_change_cb = NULL; 987 988 return QDF_STATUS_SUCCESS; 989 } 990