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