1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /** 19 * DOC: Public APIs to perform operations on Global objects 20 */ 21 22 #include "wlan_objmgr_global_obj_i.h" 23 #include <wlan_objmgr_global_obj.h> 24 #include "wlan_objmgr_psoc_obj.h" 25 #include "qdf_mem.h" 26 27 /* Global object, it is declared globally */ 28 struct wlan_objmgr_global *g_umac_glb_obj; 29 30 /* 31 ** APIs to Create/Delete Global object APIs 32 */ 33 QDF_STATUS wlan_objmgr_global_obj_init(void) 34 { 35 struct wlan_objmgr_global *umac_global_obj; 36 37 /* If it is already created, ignore */ 38 if (g_umac_glb_obj != NULL) { 39 obj_mgr_err("Global object is already created"); 40 return QDF_STATUS_E_FAILURE; 41 } 42 43 /* Allocation of memory for Global object */ 44 umac_global_obj = (struct wlan_objmgr_global *)qdf_mem_malloc( 45 sizeof(*umac_global_obj)); 46 if (umac_global_obj == NULL) { 47 obj_mgr_err("Global object alloc failed due to malloc"); 48 return QDF_STATUS_E_NOMEM; 49 } 50 /* Store Global object pointer in Global variable */ 51 g_umac_glb_obj = umac_global_obj; 52 /* Initialize spinlock */ 53 qdf_spinlock_create(&g_umac_glb_obj->global_lock); 54 55 return QDF_STATUS_SUCCESS; 56 } 57 EXPORT_SYMBOL(wlan_objmgr_global_obj_init); 58 59 QDF_STATUS wlan_objmgr_global_obj_deinit(void) 60 { 61 /* If it is already destroyed */ 62 if (g_umac_glb_obj == NULL) { 63 obj_mgr_err("Global object is not allocated"); 64 return QDF_STATUS_E_FAILURE; 65 } 66 67 if (QDF_STATUS_SUCCESS == wlan_objmgr_global_obj_can_destroyed()) { 68 qdf_spinlock_destroy(&g_umac_glb_obj->global_lock); 69 qdf_mem_free(g_umac_glb_obj); 70 g_umac_glb_obj = NULL; 71 } else { 72 obj_mgr_err("PSOCs are leaked can't free global objmgr ctx"); 73 WLAN_OBJMGR_BUG(0); 74 } 75 76 return QDF_STATUS_SUCCESS; 77 } 78 EXPORT_SYMBOL(wlan_objmgr_global_obj_deinit); 79 80 /** 81 ** APIs to register/unregister handlers 82 */ 83 QDF_STATUS wlan_objmgr_register_psoc_create_handler( 84 enum wlan_umac_comp_id id, 85 wlan_objmgr_psoc_create_handler handler, 86 void *arg) 87 { 88 /* If id is not within valid range, return */ 89 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 90 obj_mgr_err("Component %d is out of range", id); 91 return QDF_STATUS_MAXCOMP_FAIL; 92 } 93 94 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 95 /* If there is a valid entry, return failure */ 96 if (g_umac_glb_obj->psoc_create_handler[id] != NULL) { 97 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 98 obj_mgr_err("Callback for comp %d is already registered", id); 99 QDF_ASSERT(0); 100 return QDF_STATUS_E_FAILURE; 101 } 102 /* Store handler and args in Global object table */ 103 g_umac_glb_obj->psoc_create_handler[id] = handler; 104 g_umac_glb_obj->psoc_create_handler_arg[id] = arg; 105 106 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 107 return QDF_STATUS_SUCCESS; 108 } 109 EXPORT_SYMBOL(wlan_objmgr_register_psoc_create_handler); 110 111 QDF_STATUS wlan_objmgr_unregister_psoc_create_handler( 112 enum wlan_umac_comp_id id, 113 wlan_objmgr_psoc_create_handler handler, 114 void *arg) 115 { 116 /* If id is not within valid range, return */ 117 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 118 obj_mgr_err("Component %d is out of range", id); 119 return QDF_STATUS_MAXCOMP_FAIL; 120 } 121 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 122 /* If there is an invalid entry, return failure */ 123 if (g_umac_glb_obj->psoc_create_handler[id] != handler) { 124 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 125 obj_mgr_err("Callback for comp %d is not registered", id); 126 QDF_ASSERT(0); 127 return QDF_STATUS_E_FAILURE; 128 } 129 /* Reset handlers, and args to NULL */ 130 g_umac_glb_obj->psoc_create_handler[id] = NULL; 131 g_umac_glb_obj->psoc_create_handler_arg[id] = NULL; 132 133 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 134 return QDF_STATUS_SUCCESS; 135 } 136 EXPORT_SYMBOL(wlan_objmgr_unregister_psoc_create_handler); 137 138 QDF_STATUS wlan_objmgr_register_psoc_destroy_handler( 139 enum wlan_umac_comp_id id, 140 wlan_objmgr_psoc_destroy_handler handler, 141 void *arg) 142 { 143 /* If id is not within valid range, return */ 144 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 145 obj_mgr_err("Component %d is out of range", id); 146 return QDF_STATUS_MAXCOMP_FAIL; 147 } 148 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 149 /* If there is a valid entry, return failure */ 150 if (g_umac_glb_obj->psoc_destroy_handler[id] != NULL) { 151 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 152 obj_mgr_err("Callback for comp %d is already registered", id); 153 QDF_ASSERT(0); 154 return QDF_STATUS_E_FAILURE; 155 } 156 /* Store handler and args in Global object table */ 157 g_umac_glb_obj->psoc_destroy_handler[id] = handler; 158 g_umac_glb_obj->psoc_destroy_handler_arg[id] = arg; 159 160 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 161 return QDF_STATUS_SUCCESS; 162 } 163 EXPORT_SYMBOL(wlan_objmgr_register_psoc_destroy_handler); 164 165 QDF_STATUS wlan_objmgr_unregister_psoc_destroy_handler( 166 enum wlan_umac_comp_id id, 167 wlan_objmgr_psoc_destroy_handler handler, 168 void *arg) 169 { 170 /* If id is not within valid range, return */ 171 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 172 obj_mgr_err("Component %d is out of range", id); 173 return QDF_STATUS_MAXCOMP_FAIL; 174 } 175 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 176 /* If there is an invalid entry, return failure */ 177 if (g_umac_glb_obj->psoc_destroy_handler[id] != handler) { 178 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 179 obj_mgr_err("Callback for comp %d is not registered", id); 180 QDF_ASSERT(0); 181 return QDF_STATUS_E_FAILURE; 182 } 183 /* Reset handlers, and args to NULL */ 184 g_umac_glb_obj->psoc_destroy_handler[id] = NULL; 185 g_umac_glb_obj->psoc_destroy_handler_arg[id] = NULL; 186 187 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 188 return QDF_STATUS_SUCCESS; 189 } 190 EXPORT_SYMBOL(wlan_objmgr_unregister_psoc_destroy_handler); 191 192 QDF_STATUS wlan_objmgr_register_psoc_status_handler( 193 enum wlan_umac_comp_id id, 194 wlan_objmgr_psoc_status_handler handler, 195 void *arg) 196 { 197 /* If id is not within valid range, return */ 198 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 199 obj_mgr_err("Component %d is out of range", id); 200 return QDF_STATUS_MAXCOMP_FAIL; 201 } 202 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 203 /* If there is a valid entry, return failure */ 204 if (g_umac_glb_obj->psoc_status_handler[id] != NULL) { 205 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 206 obj_mgr_err("Callback for comp %d is already registered", id); 207 return QDF_STATUS_E_FAILURE; 208 } 209 /* Store handler and args in Global object table */ 210 g_umac_glb_obj->psoc_status_handler[id] = handler; 211 g_umac_glb_obj->psoc_status_handler_arg[id] = arg; 212 213 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 214 return QDF_STATUS_SUCCESS; 215 } 216 217 QDF_STATUS wlan_objmgr_unregister_psoc_status_handler( 218 enum wlan_umac_comp_id id, 219 wlan_objmgr_psoc_status_handler handler, 220 void *arg) 221 { 222 /* If id is not within valid range, return */ 223 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 224 obj_mgr_err("Component %d is out of range", id); 225 return QDF_STATUS_MAXCOMP_FAIL; 226 } 227 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 228 /* If there is an invalid entry, return failure */ 229 if (g_umac_glb_obj->psoc_status_handler[id] != handler) { 230 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 231 obj_mgr_err("Callback for comp %d is not registered", id); 232 return QDF_STATUS_E_FAILURE; 233 } 234 /* Reset handlers, and args to NULL */ 235 g_umac_glb_obj->psoc_status_handler[id] = NULL; 236 g_umac_glb_obj->psoc_status_handler_arg[id] = NULL; 237 238 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 239 return QDF_STATUS_SUCCESS; 240 } 241 242 243 QDF_STATUS wlan_objmgr_register_pdev_create_handler( 244 enum wlan_umac_comp_id id, 245 wlan_objmgr_pdev_create_handler handler, 246 void *arg) 247 { 248 /* If id is not within valid range, return */ 249 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 250 obj_mgr_err("Component %d is out of range", id); 251 return QDF_STATUS_MAXCOMP_FAIL; 252 } 253 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 254 /* If there is a valid entry, return failure */ 255 if (g_umac_glb_obj->pdev_create_handler[id] != NULL) { 256 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 257 obj_mgr_err("Callback for comp %d is already registered", id); 258 QDF_ASSERT(0); 259 return QDF_STATUS_E_FAILURE; 260 } 261 /* Store handler and args in Global object table */ 262 g_umac_glb_obj->pdev_create_handler[id] = handler; 263 g_umac_glb_obj->pdev_create_handler_arg[id] = arg; 264 265 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 266 return QDF_STATUS_SUCCESS; 267 } 268 EXPORT_SYMBOL(wlan_objmgr_register_pdev_create_handler); 269 270 QDF_STATUS wlan_objmgr_unregister_pdev_create_handler( 271 enum wlan_umac_comp_id id, 272 wlan_objmgr_pdev_create_handler handler, 273 void *arg) 274 { 275 /* If id is not within valid range, return */ 276 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 277 obj_mgr_err("Component %d is out of range", id); 278 return QDF_STATUS_MAXCOMP_FAIL; 279 } 280 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 281 /* If there is an invalid entry, return failure */ 282 if (g_umac_glb_obj->pdev_create_handler[id] != handler) { 283 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 284 obj_mgr_err("Callback for comp %d is not registered", id); 285 QDF_ASSERT(0); 286 return QDF_STATUS_E_FAILURE; 287 } 288 /* Reset handlers, and args to NULL */ 289 g_umac_glb_obj->pdev_create_handler[id] = NULL; 290 g_umac_glb_obj->pdev_create_handler_arg[id] = NULL; 291 292 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 293 return QDF_STATUS_SUCCESS; 294 } 295 EXPORT_SYMBOL(wlan_objmgr_unregister_pdev_create_handler); 296 297 QDF_STATUS wlan_objmgr_register_pdev_destroy_handler( 298 enum wlan_umac_comp_id id, 299 wlan_objmgr_pdev_destroy_handler handler, 300 void *arg) 301 { 302 /* If id is not within valid range, return */ 303 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 304 obj_mgr_err("Component %d is out of range", id); 305 return QDF_STATUS_MAXCOMP_FAIL; 306 } 307 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 308 /* If there is a valid entry, return failure */ 309 if (g_umac_glb_obj->pdev_destroy_handler[id] != NULL) { 310 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 311 obj_mgr_err("Callback for comp %d is already registered", id); 312 QDF_ASSERT(0); 313 return QDF_STATUS_E_FAILURE; 314 } 315 /* Store handler and args in Global object table */ 316 g_umac_glb_obj->pdev_destroy_handler[id] = handler; 317 g_umac_glb_obj->pdev_destroy_handler_arg[id] = arg; 318 319 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 320 return QDF_STATUS_SUCCESS; 321 } 322 EXPORT_SYMBOL(wlan_objmgr_register_pdev_destroy_handler); 323 324 QDF_STATUS wlan_objmgr_unregister_pdev_destroy_handler( 325 enum wlan_umac_comp_id id, 326 wlan_objmgr_pdev_destroy_handler handler, 327 void *arg) 328 { 329 /* If id is not within valid range, return */ 330 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 331 obj_mgr_err("Component %d is out of range", id); 332 return QDF_STATUS_MAXCOMP_FAIL; 333 } 334 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 335 /* If there is an invalid entry, return failure */ 336 if (g_umac_glb_obj->pdev_destroy_handler[id] != handler) { 337 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 338 obj_mgr_err("Callback for Component %d is not registered", id); 339 QDF_ASSERT(0); 340 return QDF_STATUS_E_FAILURE; 341 } 342 /* Reset handlers, and args to NULL */ 343 g_umac_glb_obj->pdev_destroy_handler[id] = NULL; 344 g_umac_glb_obj->pdev_destroy_handler_arg[id] = NULL; 345 346 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 347 return QDF_STATUS_SUCCESS; 348 } 349 EXPORT_SYMBOL(wlan_objmgr_unregister_pdev_destroy_handler); 350 351 QDF_STATUS wlan_objmgr_register_pdev_status_handler( 352 enum wlan_umac_comp_id id, 353 wlan_objmgr_pdev_status_handler handler, 354 void *arg) 355 { 356 /* If id is not within valid range, return */ 357 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 358 obj_mgr_err("Component %d is out of range", id); 359 return QDF_STATUS_MAXCOMP_FAIL; 360 } 361 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 362 /* If there is a valid entry, return failure */ 363 if (g_umac_glb_obj->pdev_status_handler[id] != NULL) { 364 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 365 obj_mgr_err("Callback for comp %d is already registered", id); 366 return QDF_STATUS_E_FAILURE; 367 } 368 /* Store handler and args in Global object table */ 369 g_umac_glb_obj->pdev_status_handler[id] = handler; 370 g_umac_glb_obj->pdev_status_handler_arg[id] = arg; 371 372 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 373 return QDF_STATUS_SUCCESS; 374 } 375 376 QDF_STATUS wlan_objmgr_unregister_pdev_status_handler( 377 enum wlan_umac_comp_id id, 378 wlan_objmgr_pdev_status_handler handler, 379 void *arg) 380 { 381 /* If id is not within valid range, return */ 382 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 383 obj_mgr_err("Component %d is out of range", id); 384 return QDF_STATUS_MAXCOMP_FAIL; 385 } 386 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 387 /* If there is an invalid entry, return failure */ 388 if (g_umac_glb_obj->pdev_status_handler[id] != handler) { 389 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 390 obj_mgr_err("Callback for Component %d is not registered", id); 391 return QDF_STATUS_E_FAILURE; 392 } 393 /* Reset handlers, and args to NULL */ 394 g_umac_glb_obj->pdev_status_handler[id] = NULL; 395 g_umac_glb_obj->pdev_status_handler_arg[id] = NULL; 396 397 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 398 return QDF_STATUS_SUCCESS; 399 } 400 401 402 QDF_STATUS wlan_objmgr_register_vdev_create_handler( 403 enum wlan_umac_comp_id id, 404 wlan_objmgr_vdev_create_handler handler, 405 void *arg) 406 { 407 /* If id is not within valid range, return */ 408 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 409 obj_mgr_err("Component %d is out of range", id); 410 return QDF_STATUS_MAXCOMP_FAIL; 411 } 412 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 413 /* If there is a valid entry, return failure */ 414 if (g_umac_glb_obj->vdev_create_handler[id] != NULL) { 415 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 416 obj_mgr_err("Callback for comp %d is already registered", id); 417 QDF_ASSERT(0); 418 return QDF_STATUS_E_FAILURE; 419 } 420 /* Store handler and args in Global object table */ 421 g_umac_glb_obj->vdev_create_handler[id] = handler; 422 g_umac_glb_obj->vdev_create_handler_arg[id] = arg; 423 424 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 425 return QDF_STATUS_SUCCESS; 426 } 427 428 QDF_STATUS wlan_objmgr_unregister_vdev_create_handler( 429 enum wlan_umac_comp_id id, 430 wlan_objmgr_vdev_create_handler handler, 431 void *arg) 432 { 433 /* If id is not within valid range, return */ 434 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 435 obj_mgr_err("Component %d is out of range", id); 436 return QDF_STATUS_MAXCOMP_FAIL; 437 } 438 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 439 /* If there is an invalid entry, return failure */ 440 if (g_umac_glb_obj->vdev_create_handler[id] != handler) { 441 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 442 obj_mgr_err("Callback for comp %d is not registered", id); 443 QDF_ASSERT(0); 444 return QDF_STATUS_E_FAILURE; 445 } 446 /* Reset handlers, and args to NULL */ 447 g_umac_glb_obj->vdev_create_handler[id] = NULL; 448 g_umac_glb_obj->vdev_create_handler_arg[id] = NULL; 449 450 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 451 return QDF_STATUS_SUCCESS; 452 } 453 454 QDF_STATUS wlan_objmgr_register_vdev_destroy_handler( 455 enum wlan_umac_comp_id id, 456 wlan_objmgr_vdev_destroy_handler handler, 457 void *arg) 458 { 459 /* If id is not within valid range, return */ 460 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 461 obj_mgr_err("Component %d is out of range", id); 462 return QDF_STATUS_MAXCOMP_FAIL; 463 } 464 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 465 /* If there is a valid entry, return failure */ 466 if (g_umac_glb_obj->vdev_destroy_handler[id] != NULL) { 467 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 468 obj_mgr_err("Callback for comp %d is already registered", id); 469 QDF_ASSERT(0); 470 return QDF_STATUS_E_FAILURE; 471 } 472 /* Store handler and args in Global object table */ 473 g_umac_glb_obj->vdev_destroy_handler[id] = handler; 474 g_umac_glb_obj->vdev_destroy_handler_arg[id] = arg; 475 476 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 477 return QDF_STATUS_SUCCESS; 478 } 479 480 QDF_STATUS wlan_objmgr_unregister_vdev_destroy_handler( 481 enum wlan_umac_comp_id id, 482 wlan_objmgr_vdev_destroy_handler handler, 483 void *arg) 484 { 485 /* If id is not within valid range, return */ 486 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 487 obj_mgr_err("Component %d is out of range", id); 488 return QDF_STATUS_MAXCOMP_FAIL; 489 } 490 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 491 /* If there is an invalid entry, return failure */ 492 if (g_umac_glb_obj->vdev_destroy_handler[id] != handler) { 493 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 494 obj_mgr_err("Callback for comp %d is not registered", id); 495 QDF_ASSERT(0); 496 return QDF_STATUS_E_FAILURE; 497 } 498 /* Reset handlers, and args to NULL */ 499 g_umac_glb_obj->vdev_destroy_handler[id] = NULL; 500 g_umac_glb_obj->vdev_destroy_handler_arg[id] = NULL; 501 502 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 503 return QDF_STATUS_SUCCESS; 504 } 505 506 QDF_STATUS wlan_objmgr_register_vdev_status_handler( 507 enum wlan_umac_comp_id id, 508 wlan_objmgr_vdev_status_handler handler, 509 void *arg) 510 { 511 /* If id is not within valid range, return */ 512 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 513 obj_mgr_err("Component %d is out of range", id); 514 return QDF_STATUS_MAXCOMP_FAIL; 515 } 516 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 517 /* If there is a valid entry, return failure */ 518 if (g_umac_glb_obj->vdev_status_handler[id] != NULL) { 519 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 520 obj_mgr_err("Callback for comp %d is already registered", id); 521 return QDF_STATUS_E_FAILURE; 522 } 523 /* Store handler and args in Global object table */ 524 g_umac_glb_obj->vdev_status_handler[id] = handler; 525 g_umac_glb_obj->vdev_status_handler_arg[id] = arg; 526 527 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 528 return QDF_STATUS_SUCCESS; 529 } 530 531 QDF_STATUS wlan_objmgr_unregister_vdev_status_handler( 532 enum wlan_umac_comp_id id, 533 wlan_objmgr_vdev_status_handler handler, 534 void *arg) 535 { 536 /* If id is not within valid range, return */ 537 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 538 obj_mgr_err("Component %d is out of range", id); 539 return QDF_STATUS_MAXCOMP_FAIL; 540 } 541 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 542 /* If there is an invalid entry, return failure */ 543 if (g_umac_glb_obj->vdev_status_handler[id] != handler) { 544 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 545 obj_mgr_err("Callback for Component %d is not registered", id); 546 return QDF_STATUS_E_FAILURE; 547 } 548 /* Reset handlers, and args to NULL */ 549 g_umac_glb_obj->vdev_status_handler[id] = NULL; 550 g_umac_glb_obj->vdev_status_handler_arg[id] = NULL; 551 552 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 553 return QDF_STATUS_SUCCESS; 554 } 555 556 557 QDF_STATUS wlan_objmgr_register_peer_create_handler( 558 enum wlan_umac_comp_id id, 559 wlan_objmgr_peer_create_handler handler, 560 void *arg) 561 { 562 /* If id is not within valid range, return */ 563 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 564 obj_mgr_err("Component %d is out of range", id); 565 return QDF_STATUS_MAXCOMP_FAIL; 566 } 567 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 568 /* If there is a valid entry, return failure */ 569 if (g_umac_glb_obj->peer_create_handler[id] != NULL) { 570 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 571 obj_mgr_err("Callback for comp %d is already registered", id); 572 QDF_ASSERT(0); 573 return QDF_STATUS_E_FAILURE; 574 } 575 /* Store handler and args in Global object table */ 576 g_umac_glb_obj->peer_create_handler[id] = handler; 577 g_umac_glb_obj->peer_create_handler_arg[id] = arg; 578 579 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 580 return QDF_STATUS_SUCCESS; 581 } 582 583 584 QDF_STATUS wlan_objmgr_unregister_peer_create_handler( 585 enum wlan_umac_comp_id id, 586 wlan_objmgr_peer_create_handler handler, 587 void *arg) 588 { 589 /* If id is not within valid range, return */ 590 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 591 obj_mgr_err("Component %d is out of range", id); 592 return QDF_STATUS_MAXCOMP_FAIL; 593 } 594 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 595 /* If there is an invalid entry, return failure */ 596 if (g_umac_glb_obj->peer_create_handler[id] != handler) { 597 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 598 obj_mgr_err("Callback for comp %d is not registered", id); 599 QDF_ASSERT(0); 600 return QDF_STATUS_E_FAILURE; 601 } 602 /* Reset handlers, and args to NULL */ 603 g_umac_glb_obj->peer_create_handler[id] = NULL; 604 g_umac_glb_obj->peer_create_handler_arg[id] = NULL; 605 606 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 607 return QDF_STATUS_SUCCESS; 608 } 609 610 QDF_STATUS wlan_objmgr_register_peer_destroy_handler( 611 enum wlan_umac_comp_id id, 612 wlan_objmgr_peer_destroy_handler handler, 613 void *arg) 614 { 615 /* If id is not within valid range, return */ 616 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 617 obj_mgr_err("Component %d is out of range", id); 618 return QDF_STATUS_MAXCOMP_FAIL; 619 } 620 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 621 /* If there is a valid entry, return failure */ 622 if (g_umac_glb_obj->peer_destroy_handler[id] != NULL) { 623 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 624 obj_mgr_err("Callback for comp %d is already registered", id); 625 QDF_ASSERT(0); 626 return QDF_STATUS_E_FAILURE; 627 } 628 /* Store handler and args in Global object table */ 629 g_umac_glb_obj->peer_destroy_handler[id] = handler; 630 g_umac_glb_obj->peer_destroy_handler_arg[id] = arg; 631 632 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 633 return QDF_STATUS_SUCCESS; 634 } 635 636 QDF_STATUS wlan_objmgr_unregister_peer_destroy_handler( 637 enum wlan_umac_comp_id id, 638 wlan_objmgr_peer_destroy_handler handler, 639 void *arg) 640 { 641 /* If id is not within valid range, return */ 642 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 643 obj_mgr_err("Component %d is out of range", id); 644 return QDF_STATUS_MAXCOMP_FAIL; 645 } 646 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 647 /* If there is an invalid entry, return failure */ 648 if (g_umac_glb_obj->peer_destroy_handler[id] != handler) { 649 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 650 obj_mgr_err("Callback for comp %d is not registered", id); 651 QDF_ASSERT(0); 652 return QDF_STATUS_E_FAILURE; 653 } 654 /* Reset handlers, and args to NULL */ 655 g_umac_glb_obj->peer_destroy_handler[id] = NULL; 656 g_umac_glb_obj->peer_destroy_handler_arg[id] = NULL; 657 658 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 659 return QDF_STATUS_SUCCESS; 660 } 661 662 QDF_STATUS wlan_objmgr_register_peer_status_handler( 663 enum wlan_umac_comp_id id, 664 wlan_objmgr_peer_status_handler handler, 665 void *arg) 666 { 667 /* If id is not within valid range, return */ 668 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 669 obj_mgr_err("Component %d is out of range", id); 670 return QDF_STATUS_MAXCOMP_FAIL; 671 } 672 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 673 /* If there is a valid entry, return failure */ 674 if (g_umac_glb_obj->peer_status_handler[id] != NULL) { 675 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 676 obj_mgr_err("Callback for comp %d is already registered", id); 677 return QDF_STATUS_E_FAILURE; 678 } 679 /* Store handler and args in Global object table */ 680 g_umac_glb_obj->peer_status_handler[id] = handler; 681 g_umac_glb_obj->peer_status_handler_arg[id] = arg; 682 683 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 684 return QDF_STATUS_SUCCESS; 685 } 686 687 QDF_STATUS wlan_objmgr_unregister_peer_status_handler( 688 enum wlan_umac_comp_id id, 689 wlan_objmgr_peer_status_handler handler, 690 void *arg) 691 { 692 /* If id is not within valid range, return */ 693 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 694 obj_mgr_err("Component %d is out of range", id); 695 return QDF_STATUS_MAXCOMP_FAIL; 696 } 697 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 698 /* If there is an invalid entry, return failure */ 699 if (g_umac_glb_obj->peer_status_handler[id] != handler) { 700 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 701 obj_mgr_err("Callback for comp %d is not registered", id); 702 return QDF_STATUS_E_FAILURE; 703 } 704 /* Reset handlers, and args to NULL */ 705 g_umac_glb_obj->peer_status_handler[id] = NULL; 706 g_umac_glb_obj->peer_status_handler_arg[id] = NULL; 707 708 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 709 return QDF_STATUS_SUCCESS; 710 } 711 712 QDF_STATUS wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc *psoc) 713 { 714 uint8_t index = 0; 715 QDF_STATUS status = QDF_STATUS_E_FAILURE; 716 717 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 718 /* Find free slot in PSOC table, store the PSOC */ 719 while (index < WLAN_OBJMGR_MAX_DEVICES) { 720 if (g_umac_glb_obj->psoc[index] == NULL) { 721 /* Found free slot, store psoc */ 722 g_umac_glb_obj->psoc[index] = psoc; 723 psoc->soc_objmgr.psoc_id = index; 724 status = QDF_STATUS_SUCCESS; 725 break; 726 } 727 index++; 728 } 729 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 730 return status; 731 } 732 733 QDF_STATUS wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc *psoc) 734 { 735 uint8_t psoc_id; 736 737 psoc_id = psoc->soc_objmgr.psoc_id; 738 QDF_BUG(psoc_id < WLAN_OBJMGR_MAX_DEVICES); 739 if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES) 740 return QDF_STATUS_E_INVAL; 741 742 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 743 g_umac_glb_obj->psoc[psoc_id] = NULL; 744 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 745 746 return QDF_STATUS_SUCCESS; 747 } 748 749 QDF_STATUS wlan_objmgr_global_obj_can_destroyed(void) 750 { 751 uint8_t index = 0; 752 QDF_STATUS status = QDF_STATUS_SUCCESS; 753 754 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 755 /* Check whether all PSOCs are freed */ 756 while (index < WLAN_OBJMGR_MAX_DEVICES) { 757 if (g_umac_glb_obj->psoc[index] != NULL) { 758 status = QDF_STATUS_E_FAILURE; 759 break; 760 } 761 index++; 762 } 763 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 764 765 return status; 766 } 767 EXPORT_SYMBOL(wlan_objmgr_global_obj_can_destroyed); 768 769 void wlan_objmgr_print_ref_ids(qdf_atomic_t *id) 770 { 771 uint32_t i; 772 uint32_t pending_ref; 773 774 obj_mgr_info("Pending references of object"); 775 for (i = 0; i < WLAN_REF_ID_MAX; i++) { 776 pending_ref = qdf_atomic_read(&id[i]); 777 if (pending_ref) 778 obj_mgr_info("%s -- %d", 779 string_from_dbgid(i), pending_ref); 780 } 781 782 return; 783 } 784