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