1 /* 2 * Copyright (c) 2016-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: Public APIs to perform operations on Global objects 22 */ 23 24 #include "wlan_objmgr_global_obj_i.h" 25 #include <wlan_objmgr_global_obj.h> 26 #include "wlan_objmgr_debug.h" 27 #include "wlan_objmgr_psoc_obj.h" 28 #include "qdf_mem.h" 29 #include <qdf_module.h> 30 31 /* Global object, it is declared globally */ 32 struct wlan_objmgr_global *g_umac_glb_obj; 33 34 qdf_export_symbol(g_umac_glb_obj); 35 36 /* 37 * APIs to Create/Delete Global object APIs 38 */ 39 QDF_STATUS wlan_objmgr_global_obj_init(void) 40 { 41 struct wlan_objmgr_global *umac_global_obj; 42 43 /* If it is already created, ignore */ 44 if (g_umac_glb_obj) { 45 obj_mgr_err("Global object is already created"); 46 return QDF_STATUS_E_FAILURE; 47 } 48 49 /* Allocation of memory for Global object */ 50 umac_global_obj = (struct wlan_objmgr_global *)qdf_mem_malloc( 51 sizeof(*umac_global_obj)); 52 if (!umac_global_obj) 53 return QDF_STATUS_E_NOMEM; 54 55 /* Store Global object pointer in Global variable */ 56 g_umac_glb_obj = umac_global_obj; 57 /* Initialize spinlock */ 58 qdf_spinlock_create(&g_umac_glb_obj->global_lock); 59 wlan_objmgr_debug_info_init(); 60 61 return QDF_STATUS_SUCCESS; 62 } 63 qdf_export_symbol(wlan_objmgr_global_obj_init); 64 65 QDF_STATUS wlan_objmgr_global_obj_deinit(void) 66 { 67 /* If it is already destroyed */ 68 if (!g_umac_glb_obj) { 69 obj_mgr_err("Global object is not allocated"); 70 return QDF_STATUS_E_FAILURE; 71 } 72 73 wlan_objmgr_debug_info_deinit(); 74 75 if (QDF_STATUS_SUCCESS == wlan_objmgr_global_obj_can_destroyed()) { 76 qdf_spinlock_destroy(&g_umac_glb_obj->global_lock); 77 qdf_mem_free(g_umac_glb_obj); 78 g_umac_glb_obj = NULL; 79 } else { 80 obj_mgr_err("PSOCs are leaked can't free global objmgr ctx"); 81 WLAN_OBJMGR_BUG(0); 82 } 83 84 return QDF_STATUS_SUCCESS; 85 } 86 qdf_export_symbol(wlan_objmgr_global_obj_deinit); 87 88 /* 89 * APIs to register/unregister handlers 90 */ 91 QDF_STATUS wlan_objmgr_register_psoc_create_handler( 92 enum wlan_umac_comp_id id, 93 wlan_objmgr_psoc_create_handler handler, 94 void *arg) 95 { 96 /* If id is not within valid range, return */ 97 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 98 obj_mgr_err("Component %d is out of range", id); 99 return QDF_STATUS_MAXCOMP_FAIL; 100 } 101 102 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 103 /* If there is a valid entry, return failure */ 104 if (g_umac_glb_obj->psoc_create_handler[id]) { 105 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 106 obj_mgr_err("Callback for comp %d is already registered", id); 107 QDF_ASSERT(0); 108 return QDF_STATUS_E_FAILURE; 109 } 110 /* Store handler and args in Global object table */ 111 g_umac_glb_obj->psoc_create_handler[id] = handler; 112 g_umac_glb_obj->psoc_create_handler_arg[id] = arg; 113 114 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 115 return QDF_STATUS_SUCCESS; 116 } 117 qdf_export_symbol(wlan_objmgr_register_psoc_create_handler); 118 119 QDF_STATUS wlan_objmgr_unregister_psoc_create_handler( 120 enum wlan_umac_comp_id id, 121 wlan_objmgr_psoc_create_handler handler, 122 void *arg) 123 { 124 /* If id is not within valid range, return */ 125 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 126 obj_mgr_err("Component %d is out of range", id); 127 return QDF_STATUS_MAXCOMP_FAIL; 128 } 129 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 130 /* If there is an invalid entry, return failure */ 131 if (g_umac_glb_obj->psoc_create_handler[id] != handler) { 132 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 133 obj_mgr_err("Callback for comp %d is not registered", id); 134 QDF_ASSERT(0); 135 return QDF_STATUS_E_FAILURE; 136 } 137 /* Reset handlers, and args to NULL */ 138 g_umac_glb_obj->psoc_create_handler[id] = NULL; 139 g_umac_glb_obj->psoc_create_handler_arg[id] = NULL; 140 141 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 142 return QDF_STATUS_SUCCESS; 143 } 144 qdf_export_symbol(wlan_objmgr_unregister_psoc_create_handler); 145 146 QDF_STATUS wlan_objmgr_register_psoc_destroy_handler( 147 enum wlan_umac_comp_id id, 148 wlan_objmgr_psoc_destroy_handler handler, 149 void *arg) 150 { 151 /* If id is not within valid range, return */ 152 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 153 obj_mgr_err("Component %d is out of range", id); 154 return QDF_STATUS_MAXCOMP_FAIL; 155 } 156 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 157 /* If there is a valid entry, return failure */ 158 if (g_umac_glb_obj->psoc_destroy_handler[id]) { 159 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 160 obj_mgr_err("Callback for comp %d is already registered", id); 161 QDF_ASSERT(0); 162 return QDF_STATUS_E_FAILURE; 163 } 164 /* Store handler and args in Global object table */ 165 g_umac_glb_obj->psoc_destroy_handler[id] = handler; 166 g_umac_glb_obj->psoc_destroy_handler_arg[id] = arg; 167 168 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 169 return QDF_STATUS_SUCCESS; 170 } 171 qdf_export_symbol(wlan_objmgr_register_psoc_destroy_handler); 172 173 QDF_STATUS wlan_objmgr_unregister_psoc_destroy_handler( 174 enum wlan_umac_comp_id id, 175 wlan_objmgr_psoc_destroy_handler handler, 176 void *arg) 177 { 178 /* If id is not within valid range, return */ 179 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 180 obj_mgr_err("Component %d is out of range", id); 181 return QDF_STATUS_MAXCOMP_FAIL; 182 } 183 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 184 /* If there is an invalid entry, return failure */ 185 if (g_umac_glb_obj->psoc_destroy_handler[id] != handler) { 186 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 187 obj_mgr_err("Callback for comp %d is not registered", id); 188 QDF_ASSERT(0); 189 return QDF_STATUS_E_FAILURE; 190 } 191 /* Reset handlers, and args to NULL */ 192 g_umac_glb_obj->psoc_destroy_handler[id] = NULL; 193 g_umac_glb_obj->psoc_destroy_handler_arg[id] = NULL; 194 195 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 196 return QDF_STATUS_SUCCESS; 197 } 198 qdf_export_symbol(wlan_objmgr_unregister_psoc_destroy_handler); 199 200 QDF_STATUS wlan_objmgr_register_psoc_status_handler( 201 enum wlan_umac_comp_id id, 202 wlan_objmgr_psoc_status_handler handler, 203 void *arg) 204 { 205 /* If id is not within valid range, return */ 206 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 207 obj_mgr_err("Component %d is out of range", id); 208 return QDF_STATUS_MAXCOMP_FAIL; 209 } 210 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 211 /* If there is a valid entry, return failure */ 212 if (g_umac_glb_obj->psoc_status_handler[id]) { 213 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 214 obj_mgr_err("Callback for comp %d is already registered", id); 215 return QDF_STATUS_E_FAILURE; 216 } 217 /* Store handler and args in Global object table */ 218 g_umac_glb_obj->psoc_status_handler[id] = handler; 219 g_umac_glb_obj->psoc_status_handler_arg[id] = arg; 220 221 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 222 return QDF_STATUS_SUCCESS; 223 } 224 225 QDF_STATUS wlan_objmgr_unregister_psoc_status_handler( 226 enum wlan_umac_comp_id id, 227 wlan_objmgr_psoc_status_handler handler, 228 void *arg) 229 { 230 /* If id is not within valid range, return */ 231 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 232 obj_mgr_err("Component %d is out of range", id); 233 return QDF_STATUS_MAXCOMP_FAIL; 234 } 235 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 236 /* If there is an invalid entry, return failure */ 237 if (g_umac_glb_obj->psoc_status_handler[id] != handler) { 238 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 239 obj_mgr_err("Callback for comp %d is not registered", id); 240 return QDF_STATUS_E_FAILURE; 241 } 242 /* Reset handlers, and args to NULL */ 243 g_umac_glb_obj->psoc_status_handler[id] = NULL; 244 g_umac_glb_obj->psoc_status_handler_arg[id] = NULL; 245 246 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 247 return QDF_STATUS_SUCCESS; 248 } 249 250 251 QDF_STATUS wlan_objmgr_register_pdev_create_handler( 252 enum wlan_umac_comp_id id, 253 wlan_objmgr_pdev_create_handler handler, 254 void *arg) 255 { 256 /* If id is not within valid range, return */ 257 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 258 obj_mgr_err("Component %d is out of range", id); 259 return QDF_STATUS_MAXCOMP_FAIL; 260 } 261 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 262 /* If there is a valid entry, return failure */ 263 if (g_umac_glb_obj->pdev_create_handler[id]) { 264 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 265 obj_mgr_err("Callback for comp %d is already registered", id); 266 QDF_ASSERT(0); 267 return QDF_STATUS_E_FAILURE; 268 } 269 /* Store handler and args in Global object table */ 270 g_umac_glb_obj->pdev_create_handler[id] = handler; 271 g_umac_glb_obj->pdev_create_handler_arg[id] = arg; 272 273 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 274 return QDF_STATUS_SUCCESS; 275 } 276 qdf_export_symbol(wlan_objmgr_register_pdev_create_handler); 277 278 QDF_STATUS wlan_objmgr_unregister_pdev_create_handler( 279 enum wlan_umac_comp_id id, 280 wlan_objmgr_pdev_create_handler handler, 281 void *arg) 282 { 283 /* If id is not within valid range, return */ 284 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 285 obj_mgr_err("Component %d is out of range", id); 286 return QDF_STATUS_MAXCOMP_FAIL; 287 } 288 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 289 /* If there is an invalid entry, return failure */ 290 if (g_umac_glb_obj->pdev_create_handler[id] != handler) { 291 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 292 obj_mgr_err("Callback for comp %d is not registered", id); 293 QDF_ASSERT(0); 294 return QDF_STATUS_E_FAILURE; 295 } 296 /* Reset handlers, and args to NULL */ 297 g_umac_glb_obj->pdev_create_handler[id] = NULL; 298 g_umac_glb_obj->pdev_create_handler_arg[id] = NULL; 299 300 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 301 return QDF_STATUS_SUCCESS; 302 } 303 qdf_export_symbol(wlan_objmgr_unregister_pdev_create_handler); 304 305 QDF_STATUS wlan_objmgr_register_pdev_destroy_handler( 306 enum wlan_umac_comp_id id, 307 wlan_objmgr_pdev_destroy_handler handler, 308 void *arg) 309 { 310 /* If id is not within valid range, return */ 311 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 312 obj_mgr_err("Component %d is out of range", id); 313 return QDF_STATUS_MAXCOMP_FAIL; 314 } 315 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 316 /* If there is a valid entry, return failure */ 317 if (g_umac_glb_obj->pdev_destroy_handler[id]) { 318 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 319 obj_mgr_err("Callback for comp %d is already registered", id); 320 QDF_ASSERT(0); 321 return QDF_STATUS_E_FAILURE; 322 } 323 /* Store handler and args in Global object table */ 324 g_umac_glb_obj->pdev_destroy_handler[id] = handler; 325 g_umac_glb_obj->pdev_destroy_handler_arg[id] = arg; 326 327 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 328 return QDF_STATUS_SUCCESS; 329 } 330 qdf_export_symbol(wlan_objmgr_register_pdev_destroy_handler); 331 332 QDF_STATUS wlan_objmgr_unregister_pdev_destroy_handler( 333 enum wlan_umac_comp_id id, 334 wlan_objmgr_pdev_destroy_handler handler, 335 void *arg) 336 { 337 /* If id is not within valid range, return */ 338 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 339 obj_mgr_err("Component %d is out of range", id); 340 return QDF_STATUS_MAXCOMP_FAIL; 341 } 342 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 343 /* If there is an invalid entry, return failure */ 344 if (g_umac_glb_obj->pdev_destroy_handler[id] != handler) { 345 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 346 obj_mgr_err("Callback for Component %d is not registered", id); 347 QDF_ASSERT(0); 348 return QDF_STATUS_E_FAILURE; 349 } 350 /* Reset handlers, and args to NULL */ 351 g_umac_glb_obj->pdev_destroy_handler[id] = NULL; 352 g_umac_glb_obj->pdev_destroy_handler_arg[id] = NULL; 353 354 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 355 return QDF_STATUS_SUCCESS; 356 } 357 qdf_export_symbol(wlan_objmgr_unregister_pdev_destroy_handler); 358 359 QDF_STATUS wlan_objmgr_register_pdev_status_handler( 360 enum wlan_umac_comp_id id, 361 wlan_objmgr_pdev_status_handler handler, 362 void *arg) 363 { 364 /* If id is not within valid range, return */ 365 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 366 obj_mgr_err("Component %d is out of range", id); 367 return QDF_STATUS_MAXCOMP_FAIL; 368 } 369 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 370 /* If there is a valid entry, return failure */ 371 if (g_umac_glb_obj->pdev_status_handler[id]) { 372 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 373 obj_mgr_err("Callback for comp %d is already registered", id); 374 return QDF_STATUS_E_FAILURE; 375 } 376 /* Store handler and args in Global object table */ 377 g_umac_glb_obj->pdev_status_handler[id] = handler; 378 g_umac_glb_obj->pdev_status_handler_arg[id] = arg; 379 380 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 381 return QDF_STATUS_SUCCESS; 382 } 383 384 QDF_STATUS wlan_objmgr_unregister_pdev_status_handler( 385 enum wlan_umac_comp_id id, 386 wlan_objmgr_pdev_status_handler handler, 387 void *arg) 388 { 389 /* If id is not within valid range, return */ 390 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 391 obj_mgr_err("Component %d is out of range", id); 392 return QDF_STATUS_MAXCOMP_FAIL; 393 } 394 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 395 /* If there is an invalid entry, return failure */ 396 if (g_umac_glb_obj->pdev_status_handler[id] != handler) { 397 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 398 obj_mgr_err("Callback for Component %d is not registered", id); 399 return QDF_STATUS_E_FAILURE; 400 } 401 /* Reset handlers, and args to NULL */ 402 g_umac_glb_obj->pdev_status_handler[id] = NULL; 403 g_umac_glb_obj->pdev_status_handler_arg[id] = NULL; 404 405 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 406 return QDF_STATUS_SUCCESS; 407 } 408 409 410 QDF_STATUS wlan_objmgr_register_vdev_create_handler( 411 enum wlan_umac_comp_id id, 412 wlan_objmgr_vdev_create_handler handler, 413 void *arg) 414 { 415 /* If id is not within valid range, return */ 416 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 417 obj_mgr_err("Component %d is out of range", id); 418 return QDF_STATUS_MAXCOMP_FAIL; 419 } 420 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 421 /* If there is a valid entry, return failure */ 422 if (g_umac_glb_obj->vdev_create_handler[id]) { 423 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 424 obj_mgr_err("Callback for comp %d is already registered", id); 425 QDF_ASSERT(0); 426 return QDF_STATUS_E_FAILURE; 427 } 428 /* Store handler and args in Global object table */ 429 g_umac_glb_obj->vdev_create_handler[id] = handler; 430 g_umac_glb_obj->vdev_create_handler_arg[id] = arg; 431 432 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 433 return QDF_STATUS_SUCCESS; 434 } 435 qdf_export_symbol(wlan_objmgr_register_vdev_create_handler); 436 437 QDF_STATUS wlan_objmgr_unregister_vdev_create_handler( 438 enum wlan_umac_comp_id id, 439 wlan_objmgr_vdev_create_handler handler, 440 void *arg) 441 { 442 /* If id is not within valid range, return */ 443 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 444 obj_mgr_err("Component %d is out of range", id); 445 return QDF_STATUS_MAXCOMP_FAIL; 446 } 447 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 448 /* If there is an invalid entry, return failure */ 449 if (g_umac_glb_obj->vdev_create_handler[id] != handler) { 450 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 451 obj_mgr_err("Callback for comp %d is not registered", id); 452 QDF_ASSERT(0); 453 return QDF_STATUS_E_FAILURE; 454 } 455 /* Reset handlers, and args to NULL */ 456 g_umac_glb_obj->vdev_create_handler[id] = NULL; 457 g_umac_glb_obj->vdev_create_handler_arg[id] = NULL; 458 459 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 460 return QDF_STATUS_SUCCESS; 461 } 462 qdf_export_symbol(wlan_objmgr_unregister_vdev_create_handler); 463 464 QDF_STATUS wlan_objmgr_register_vdev_destroy_handler( 465 enum wlan_umac_comp_id id, 466 wlan_objmgr_vdev_destroy_handler handler, 467 void *arg) 468 { 469 /* If id is not within valid range, return */ 470 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 471 obj_mgr_err("Component %d is out of range", id); 472 return QDF_STATUS_MAXCOMP_FAIL; 473 } 474 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 475 /* If there is a valid entry, return failure */ 476 if (g_umac_glb_obj->vdev_destroy_handler[id]) { 477 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 478 obj_mgr_err("Callback for comp %d is already registered", id); 479 QDF_ASSERT(0); 480 return QDF_STATUS_E_FAILURE; 481 } 482 /* Store handler and args in Global object table */ 483 g_umac_glb_obj->vdev_destroy_handler[id] = handler; 484 g_umac_glb_obj->vdev_destroy_handler_arg[id] = arg; 485 486 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 487 return QDF_STATUS_SUCCESS; 488 } 489 qdf_export_symbol(wlan_objmgr_register_vdev_destroy_handler); 490 491 QDF_STATUS wlan_objmgr_unregister_vdev_destroy_handler( 492 enum wlan_umac_comp_id id, 493 wlan_objmgr_vdev_destroy_handler handler, 494 void *arg) 495 { 496 /* If id is not within valid range, return */ 497 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 498 obj_mgr_err("Component %d is out of range", id); 499 return QDF_STATUS_MAXCOMP_FAIL; 500 } 501 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 502 /* If there is an invalid entry, return failure */ 503 if (g_umac_glb_obj->vdev_destroy_handler[id] != handler) { 504 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 505 obj_mgr_err("Callback for comp %d is not registered", id); 506 QDF_ASSERT(0); 507 return QDF_STATUS_E_FAILURE; 508 } 509 /* Reset handlers, and args to NULL */ 510 g_umac_glb_obj->vdev_destroy_handler[id] = NULL; 511 g_umac_glb_obj->vdev_destroy_handler_arg[id] = NULL; 512 513 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 514 return QDF_STATUS_SUCCESS; 515 } 516 qdf_export_symbol(wlan_objmgr_unregister_vdev_destroy_handler); 517 518 QDF_STATUS wlan_objmgr_register_vdev_status_handler( 519 enum wlan_umac_comp_id id, 520 wlan_objmgr_vdev_status_handler handler, 521 void *arg) 522 { 523 /* If id is not within valid range, return */ 524 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 525 obj_mgr_err("Component %d is out of range", id); 526 return QDF_STATUS_MAXCOMP_FAIL; 527 } 528 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 529 /* If there is a valid entry, return failure */ 530 if (g_umac_glb_obj->vdev_status_handler[id]) { 531 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 532 obj_mgr_err("Callback for comp %d is already registered", id); 533 return QDF_STATUS_E_FAILURE; 534 } 535 /* Store handler and args in Global object table */ 536 g_umac_glb_obj->vdev_status_handler[id] = handler; 537 g_umac_glb_obj->vdev_status_handler_arg[id] = arg; 538 539 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 540 return QDF_STATUS_SUCCESS; 541 } 542 543 QDF_STATUS wlan_objmgr_unregister_vdev_status_handler( 544 enum wlan_umac_comp_id id, 545 wlan_objmgr_vdev_status_handler handler, 546 void *arg) 547 { 548 /* If id is not within valid range, return */ 549 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 550 obj_mgr_err("Component %d is out of range", id); 551 return QDF_STATUS_MAXCOMP_FAIL; 552 } 553 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 554 /* If there is an invalid entry, return failure */ 555 if (g_umac_glb_obj->vdev_status_handler[id] != handler) { 556 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 557 obj_mgr_err("Callback for Component %d is not registered", id); 558 return QDF_STATUS_E_FAILURE; 559 } 560 /* Reset handlers, and args to NULL */ 561 g_umac_glb_obj->vdev_status_handler[id] = NULL; 562 g_umac_glb_obj->vdev_status_handler_arg[id] = NULL; 563 564 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 565 return QDF_STATUS_SUCCESS; 566 } 567 568 QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler( 569 enum wlan_umac_comp_id id, 570 wlan_objmgr_vdev_peer_free_notify_handler handler) 571 { 572 /* If id is not within valid range, return */ 573 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 574 obj_mgr_err("Component %d is out of range", id); 575 WLAN_OBJMGR_BUG(0); 576 return QDF_STATUS_MAXCOMP_FAIL; 577 } 578 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 579 /* If there is a valid entry, return failure */ 580 if (g_umac_glb_obj->vdev_peer_free_notify_handler[id]) { 581 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 582 obj_mgr_err("Callback for comp %d is already registered", id); 583 return QDF_STATUS_E_FAILURE; 584 } 585 /* Store handler in Global object table */ 586 g_umac_glb_obj->vdev_peer_free_notify_handler[id] = handler; 587 588 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 589 590 return QDF_STATUS_SUCCESS; 591 } 592 593 QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler( 594 enum wlan_umac_comp_id id, 595 wlan_objmgr_vdev_peer_free_notify_handler handler) 596 { 597 /* If id is not within valid range, return */ 598 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 599 obj_mgr_err("Component %d is out of range", id); 600 WLAN_OBJMGR_BUG(0); 601 return QDF_STATUS_MAXCOMP_FAIL; 602 } 603 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 604 /* If there is an invalid entry, return failure */ 605 if (g_umac_glb_obj->vdev_peer_free_notify_handler[id] != handler) { 606 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 607 obj_mgr_err("Callback for Component %d is not registered", id); 608 return QDF_STATUS_E_FAILURE; 609 } 610 /* Reset handlers to NULL */ 611 g_umac_glb_obj->vdev_peer_free_notify_handler[id] = NULL; 612 613 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 614 615 return QDF_STATUS_SUCCESS; 616 } 617 618 QDF_STATUS wlan_objmgr_register_peer_create_handler( 619 enum wlan_umac_comp_id id, 620 wlan_objmgr_peer_create_handler handler, 621 void *arg) 622 { 623 /* If id is not within valid range, return */ 624 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 625 obj_mgr_err("Component %d is out of range", id); 626 return QDF_STATUS_MAXCOMP_FAIL; 627 } 628 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 629 /* If there is a valid entry, return failure */ 630 if (g_umac_glb_obj->peer_create_handler[id]) { 631 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 632 obj_mgr_err("Callback for comp %d is already registered", id); 633 QDF_ASSERT(0); 634 return QDF_STATUS_E_FAILURE; 635 } 636 /* Store handler and args in Global object table */ 637 g_umac_glb_obj->peer_create_handler[id] = handler; 638 g_umac_glb_obj->peer_create_handler_arg[id] = arg; 639 640 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 641 return QDF_STATUS_SUCCESS; 642 } 643 644 qdf_export_symbol(wlan_objmgr_register_peer_create_handler); 645 646 QDF_STATUS wlan_objmgr_unregister_peer_create_handler( 647 enum wlan_umac_comp_id id, 648 wlan_objmgr_peer_create_handler handler, 649 void *arg) 650 { 651 /* If id is not within valid range, return */ 652 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 653 obj_mgr_err("Component %d is out of range", id); 654 return QDF_STATUS_MAXCOMP_FAIL; 655 } 656 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 657 /* If there is an invalid entry, return failure */ 658 if (g_umac_glb_obj->peer_create_handler[id] != handler) { 659 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 660 obj_mgr_err("Callback for comp %d is not registered", id); 661 QDF_ASSERT(0); 662 return QDF_STATUS_E_FAILURE; 663 } 664 /* Reset handlers, and args to NULL */ 665 g_umac_glb_obj->peer_create_handler[id] = NULL; 666 g_umac_glb_obj->peer_create_handler_arg[id] = NULL; 667 668 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 669 return QDF_STATUS_SUCCESS; 670 } 671 672 qdf_export_symbol(wlan_objmgr_unregister_peer_create_handler); 673 674 QDF_STATUS wlan_objmgr_register_peer_destroy_handler( 675 enum wlan_umac_comp_id id, 676 wlan_objmgr_peer_destroy_handler handler, 677 void *arg) 678 { 679 /* If id is not within valid range, return */ 680 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 681 obj_mgr_err("Component %d is out of range", id); 682 return QDF_STATUS_MAXCOMP_FAIL; 683 } 684 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 685 /* If there is a valid entry, return failure */ 686 if (g_umac_glb_obj->peer_destroy_handler[id]) { 687 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 688 obj_mgr_err("Callback for comp %d is already registered", id); 689 QDF_ASSERT(0); 690 return QDF_STATUS_E_FAILURE; 691 } 692 /* Store handler and args in Global object table */ 693 g_umac_glb_obj->peer_destroy_handler[id] = handler; 694 g_umac_glb_obj->peer_destroy_handler_arg[id] = arg; 695 696 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 697 return QDF_STATUS_SUCCESS; 698 } 699 700 qdf_export_symbol(wlan_objmgr_register_peer_destroy_handler); 701 702 QDF_STATUS wlan_objmgr_unregister_peer_destroy_handler( 703 enum wlan_umac_comp_id id, 704 wlan_objmgr_peer_destroy_handler handler, 705 void *arg) 706 { 707 /* If id is not within valid range, return */ 708 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 709 obj_mgr_err("Component %d is out of range", id); 710 return QDF_STATUS_MAXCOMP_FAIL; 711 } 712 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 713 /* If there is an invalid entry, return failure */ 714 if (g_umac_glb_obj->peer_destroy_handler[id] != handler) { 715 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 716 obj_mgr_err("Callback for comp %d is not registered", id); 717 QDF_ASSERT(0); 718 return QDF_STATUS_E_FAILURE; 719 } 720 /* Reset handlers, and args to NULL */ 721 g_umac_glb_obj->peer_destroy_handler[id] = NULL; 722 g_umac_glb_obj->peer_destroy_handler_arg[id] = NULL; 723 724 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 725 return QDF_STATUS_SUCCESS; 726 } 727 728 qdf_export_symbol(wlan_objmgr_unregister_peer_destroy_handler); 729 730 QDF_STATUS wlan_objmgr_register_peer_status_handler( 731 enum wlan_umac_comp_id id, 732 wlan_objmgr_peer_status_handler handler, 733 void *arg) 734 { 735 /* If id is not within valid range, return */ 736 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 737 obj_mgr_err("Component %d is out of range", id); 738 return QDF_STATUS_MAXCOMP_FAIL; 739 } 740 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 741 /* If there is a valid entry, return failure */ 742 if (g_umac_glb_obj->peer_status_handler[id]) { 743 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 744 obj_mgr_err("Callback for comp %d is already registered", id); 745 return QDF_STATUS_E_FAILURE; 746 } 747 /* Store handler and args in Global object table */ 748 g_umac_glb_obj->peer_status_handler[id] = handler; 749 g_umac_glb_obj->peer_status_handler_arg[id] = arg; 750 751 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 752 return QDF_STATUS_SUCCESS; 753 } 754 755 QDF_STATUS wlan_objmgr_unregister_peer_status_handler( 756 enum wlan_umac_comp_id id, 757 wlan_objmgr_peer_status_handler handler, 758 void *arg) 759 { 760 /* If id is not within valid range, return */ 761 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 762 obj_mgr_err("Component %d is out of range", id); 763 return QDF_STATUS_MAXCOMP_FAIL; 764 } 765 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 766 /* If there is an invalid entry, return failure */ 767 if (g_umac_glb_obj->peer_status_handler[id] != handler) { 768 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 769 obj_mgr_err("Callback for comp %d is not registered", id); 770 return QDF_STATUS_E_FAILURE; 771 } 772 /* Reset handlers, and args to NULL */ 773 g_umac_glb_obj->peer_status_handler[id] = NULL; 774 g_umac_glb_obj->peer_status_handler_arg[id] = NULL; 775 776 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 777 return QDF_STATUS_SUCCESS; 778 } 779 780 QDF_STATUS wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc *psoc) 781 { 782 uint8_t index = 0; 783 QDF_STATUS status = QDF_STATUS_E_FAILURE; 784 785 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 786 /* Find free slot in PSOC table, store the PSOC */ 787 while (index < WLAN_OBJMGR_MAX_DEVICES) { 788 if (!g_umac_glb_obj->psoc[index]) { 789 /* Found free slot, store psoc */ 790 g_umac_glb_obj->psoc[index] = psoc; 791 psoc->soc_objmgr.psoc_id = index; 792 status = QDF_STATUS_SUCCESS; 793 break; 794 } 795 index++; 796 } 797 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 798 return status; 799 } 800 801 QDF_STATUS wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc *psoc) 802 { 803 uint8_t psoc_id; 804 805 psoc_id = psoc->soc_objmgr.psoc_id; 806 QDF_BUG(psoc_id < WLAN_OBJMGR_MAX_DEVICES); 807 if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES) 808 return QDF_STATUS_E_INVAL; 809 810 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 811 g_umac_glb_obj->psoc[psoc_id] = NULL; 812 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 813 814 return QDF_STATUS_SUCCESS; 815 } 816 817 QDF_STATUS wlan_objmgr_global_obj_can_destroyed(void) 818 { 819 uint8_t index = 0; 820 QDF_STATUS status = QDF_STATUS_SUCCESS; 821 822 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 823 /* Check whether all PSOCs are freed */ 824 while (index < WLAN_OBJMGR_MAX_DEVICES) { 825 if (g_umac_glb_obj->psoc[index]) { 826 status = QDF_STATUS_E_FAILURE; 827 break; 828 } 829 index++; 830 } 831 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 832 833 return status; 834 } 835 qdf_export_symbol(wlan_objmgr_global_obj_can_destroyed); 836 837 void wlan_objmgr_print_ref_ids(qdf_atomic_t *id, 838 QDF_TRACE_LEVEL log_level) 839 { 840 uint32_t i; 841 uint32_t pending_ref; 842 843 obj_mgr_log_level(log_level, "Pending references of object"); 844 for (i = 0; i < WLAN_REF_ID_MAX; i++) { 845 pending_ref = qdf_atomic_read(&id[i]); 846 if (pending_ref) 847 obj_mgr_log_level(log_level, "%s(%d) -- %d", 848 string_from_dbgid(i), i, pending_ref); 849 } 850 851 return; 852 } 853 854 QDF_STATUS wlan_objmgr_iterate_psoc_list( 855 wlan_objmgr_psoc_handler handler, 856 void *arg, wlan_objmgr_ref_dbgid dbg_id) 857 { 858 uint8_t index = 0; 859 860 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 861 862 while (index < WLAN_OBJMGR_MAX_DEVICES) { 863 if (g_umac_glb_obj->psoc[index]) { 864 handler((void *)g_umac_glb_obj->psoc[index], 865 arg, index); 866 } 867 index++; 868 } 869 870 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 871 872 return QDF_STATUS_SUCCESS; 873 } 874 875 qdf_export_symbol(wlan_objmgr_iterate_psoc_list); 876 877 struct wlan_objmgr_psoc 878 *wlan_objmgr_get_psoc_by_id(uint8_t psoc_id, wlan_objmgr_ref_dbgid dbg_id) 879 { 880 struct wlan_objmgr_psoc *psoc; 881 882 if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES) { 883 obj_mgr_err(" PSOC id[%d] is invalid", psoc_id); 884 return NULL; 885 } 886 887 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 888 889 psoc = g_umac_glb_obj->psoc[psoc_id]; 890 if (psoc) { 891 if (QDF_IS_STATUS_ERROR(wlan_objmgr_psoc_try_get_ref(psoc, 892 dbg_id))) 893 psoc = NULL; 894 } 895 896 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 897 898 return psoc; 899 } 900 901 qdf_export_symbol(wlan_objmgr_get_psoc_by_id); 902 903 #ifdef QCA_SUPPORT_DP_GLOBAL_CTX 904 struct dp_global_context *wlan_objmgr_get_global_ctx(void) 905 { 906 return g_umac_glb_obj->global_ctx; 907 } 908 909 qdf_export_symbol(wlan_objmgr_get_global_ctx); 910 911 void wlan_objmgr_set_global_ctx(struct dp_global_context *ctx) 912 { 913 g_umac_glb_obj->global_ctx = ctx; 914 } 915 916 qdf_export_symbol(wlan_objmgr_set_global_ctx); 917 #endif 918 919 #ifdef WLAN_FEATURE_11BE_MLO 920 struct mlo_mgr_context *wlan_objmgr_get_mlo_ctx(void) 921 { 922 return g_umac_glb_obj->mlo_ctx; 923 } 924 925 qdf_export_symbol(wlan_objmgr_get_mlo_ctx); 926 927 void wlan_objmgr_set_mlo_ctx(struct mlo_mgr_context *ctx) 928 { 929 g_umac_glb_obj->mlo_ctx = ctx; 930 } 931 932 #ifdef WLAN_MLO_MULTI_CHIP 933 void wlan_objmgr_set_dp_mlo_ctx(void *dp_handle, uint8_t grp_id) 934 { 935 struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx(); 936 937 if (!mlo_ctx) 938 return; 939 940 if (grp_id >= mlo_ctx->total_grp) 941 return; 942 943 mlo_ctx->setup_info[grp_id].dp_handle = dp_handle; 944 } 945 946 qdf_export_symbol(wlan_objmgr_set_dp_mlo_ctx); 947 948 void *wlan_objmgr_get_dp_mlo_ctx(uint8_t grp_id) 949 { 950 struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx(); 951 952 if (!mlo_ctx) 953 return NULL; 954 955 if (grp_id >= mlo_ctx->total_grp) 956 return NULL; 957 958 return mlo_ctx->setup_info[grp_id].dp_handle; 959 } 960 961 qdf_export_symbol(wlan_objmgr_get_dp_mlo_ctx); 962 #endif /* WLAN_MLO_MULTI_CHIP */ 963 #endif 964