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