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 QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler( 560 enum wlan_umac_comp_id id, 561 wlan_objmgr_vdev_peer_free_notify_handler handler) 562 { 563 /* If id is not within valid range, return */ 564 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 565 obj_mgr_err("Component %d is out of range", id); 566 WLAN_OBJMGR_BUG(0); 567 return QDF_STATUS_MAXCOMP_FAIL; 568 } 569 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 570 /* If there is a valid entry, return failure */ 571 if (g_umac_glb_obj->vdev_peer_free_notify_handler[id]) { 572 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 573 obj_mgr_err("Callback for comp %d is already registered", id); 574 return QDF_STATUS_E_FAILURE; 575 } 576 /* Store handler in Global object table */ 577 g_umac_glb_obj->vdev_peer_free_notify_handler[id] = handler; 578 579 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 580 581 return QDF_STATUS_SUCCESS; 582 } 583 584 QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler( 585 enum wlan_umac_comp_id id, 586 wlan_objmgr_vdev_peer_free_notify_handler handler) 587 { 588 /* If id is not within valid range, return */ 589 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 590 obj_mgr_err("Component %d is out of range", id); 591 WLAN_OBJMGR_BUG(0); 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->vdev_peer_free_notify_handler[id] != handler) { 597 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 598 obj_mgr_err("Callback for Component %d is not registered", id); 599 return QDF_STATUS_E_FAILURE; 600 } 601 /* Reset handlers to NULL */ 602 g_umac_glb_obj->vdev_peer_free_notify_handler[id] = NULL; 603 604 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 605 606 return QDF_STATUS_SUCCESS; 607 } 608 609 QDF_STATUS wlan_objmgr_register_peer_create_handler( 610 enum wlan_umac_comp_id id, 611 wlan_objmgr_peer_create_handler handler, 612 void *arg) 613 { 614 /* If id is not within valid range, return */ 615 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 616 obj_mgr_err("Component %d is out of range", id); 617 return QDF_STATUS_MAXCOMP_FAIL; 618 } 619 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 620 /* If there is a valid entry, return failure */ 621 if (g_umac_glb_obj->peer_create_handler[id]) { 622 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 623 obj_mgr_err("Callback for comp %d is already registered", id); 624 QDF_ASSERT(0); 625 return QDF_STATUS_E_FAILURE; 626 } 627 /* Store handler and args in Global object table */ 628 g_umac_glb_obj->peer_create_handler[id] = handler; 629 g_umac_glb_obj->peer_create_handler_arg[id] = arg; 630 631 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 632 return QDF_STATUS_SUCCESS; 633 } 634 635 636 QDF_STATUS wlan_objmgr_unregister_peer_create_handler( 637 enum wlan_umac_comp_id id, 638 wlan_objmgr_peer_create_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_create_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_create_handler[id] = NULL; 656 g_umac_glb_obj->peer_create_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_destroy_handler( 663 enum wlan_umac_comp_id id, 664 wlan_objmgr_peer_destroy_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_destroy_handler[id]) { 675 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 676 obj_mgr_err("Callback for comp %d is already registered", id); 677 QDF_ASSERT(0); 678 return QDF_STATUS_E_FAILURE; 679 } 680 /* Store handler and args in Global object table */ 681 g_umac_glb_obj->peer_destroy_handler[id] = handler; 682 g_umac_glb_obj->peer_destroy_handler_arg[id] = arg; 683 684 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 685 return QDF_STATUS_SUCCESS; 686 } 687 688 QDF_STATUS wlan_objmgr_unregister_peer_destroy_handler( 689 enum wlan_umac_comp_id id, 690 wlan_objmgr_peer_destroy_handler handler, 691 void *arg) 692 { 693 /* If id is not within valid range, return */ 694 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 695 obj_mgr_err("Component %d is out of range", id); 696 return QDF_STATUS_MAXCOMP_FAIL; 697 } 698 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 699 /* If there is an invalid entry, return failure */ 700 if (g_umac_glb_obj->peer_destroy_handler[id] != handler) { 701 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 702 obj_mgr_err("Callback for comp %d is not registered", id); 703 QDF_ASSERT(0); 704 return QDF_STATUS_E_FAILURE; 705 } 706 /* Reset handlers, and args to NULL */ 707 g_umac_glb_obj->peer_destroy_handler[id] = NULL; 708 g_umac_glb_obj->peer_destroy_handler_arg[id] = NULL; 709 710 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 711 return QDF_STATUS_SUCCESS; 712 } 713 714 QDF_STATUS wlan_objmgr_register_peer_status_handler( 715 enum wlan_umac_comp_id id, 716 wlan_objmgr_peer_status_handler handler, 717 void *arg) 718 { 719 /* If id is not within valid range, return */ 720 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 721 obj_mgr_err("Component %d is out of range", id); 722 return QDF_STATUS_MAXCOMP_FAIL; 723 } 724 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 725 /* If there is a valid entry, return failure */ 726 if (g_umac_glb_obj->peer_status_handler[id]) { 727 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 728 obj_mgr_err("Callback for comp %d is already registered", id); 729 return QDF_STATUS_E_FAILURE; 730 } 731 /* Store handler and args in Global object table */ 732 g_umac_glb_obj->peer_status_handler[id] = handler; 733 g_umac_glb_obj->peer_status_handler_arg[id] = arg; 734 735 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 736 return QDF_STATUS_SUCCESS; 737 } 738 739 QDF_STATUS wlan_objmgr_unregister_peer_status_handler( 740 enum wlan_umac_comp_id id, 741 wlan_objmgr_peer_status_handler handler, 742 void *arg) 743 { 744 /* If id is not within valid range, return */ 745 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 746 obj_mgr_err("Component %d is out of range", id); 747 return QDF_STATUS_MAXCOMP_FAIL; 748 } 749 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 750 /* If there is an invalid entry, return failure */ 751 if (g_umac_glb_obj->peer_status_handler[id] != handler) { 752 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 753 obj_mgr_err("Callback for comp %d is not registered", id); 754 return QDF_STATUS_E_FAILURE; 755 } 756 /* Reset handlers, and args to NULL */ 757 g_umac_glb_obj->peer_status_handler[id] = NULL; 758 g_umac_glb_obj->peer_status_handler_arg[id] = NULL; 759 760 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 761 return QDF_STATUS_SUCCESS; 762 } 763 764 QDF_STATUS wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc *psoc) 765 { 766 uint8_t index = 0; 767 QDF_STATUS status = QDF_STATUS_E_FAILURE; 768 769 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 770 /* Find free slot in PSOC table, store the PSOC */ 771 while (index < WLAN_OBJMGR_MAX_DEVICES) { 772 if (!g_umac_glb_obj->psoc[index]) { 773 /* Found free slot, store psoc */ 774 g_umac_glb_obj->psoc[index] = psoc; 775 psoc->soc_objmgr.psoc_id = index; 776 status = QDF_STATUS_SUCCESS; 777 break; 778 } 779 index++; 780 } 781 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 782 return status; 783 } 784 785 QDF_STATUS wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc *psoc) 786 { 787 uint8_t psoc_id; 788 789 psoc_id = psoc->soc_objmgr.psoc_id; 790 QDF_BUG(psoc_id < WLAN_OBJMGR_MAX_DEVICES); 791 if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES) 792 return QDF_STATUS_E_INVAL; 793 794 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 795 g_umac_glb_obj->psoc[psoc_id] = NULL; 796 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 797 798 return QDF_STATUS_SUCCESS; 799 } 800 801 QDF_STATUS wlan_objmgr_global_obj_can_destroyed(void) 802 { 803 uint8_t index = 0; 804 QDF_STATUS status = QDF_STATUS_SUCCESS; 805 806 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 807 /* Check whether all PSOCs are freed */ 808 while (index < WLAN_OBJMGR_MAX_DEVICES) { 809 if (g_umac_glb_obj->psoc[index]) { 810 status = QDF_STATUS_E_FAILURE; 811 break; 812 } 813 index++; 814 } 815 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 816 817 return status; 818 } 819 qdf_export_symbol(wlan_objmgr_global_obj_can_destroyed); 820 821 void wlan_objmgr_print_ref_ids(qdf_atomic_t *id, 822 QDF_TRACE_LEVEL log_level) 823 { 824 uint32_t i; 825 uint32_t pending_ref; 826 827 obj_mgr_log_level(log_level, "Pending references of object"); 828 for (i = 0; i < WLAN_REF_ID_MAX; i++) { 829 pending_ref = qdf_atomic_read(&id[i]); 830 if (pending_ref) 831 obj_mgr_log_level(log_level, "%s -- %d", 832 string_from_dbgid(i), pending_ref); 833 } 834 835 return; 836 } 837 838 QDF_STATUS wlan_objmgr_iterate_psoc_list( 839 wlan_objmgr_psoc_handler handler, 840 void *arg, wlan_objmgr_ref_dbgid dbg_id) 841 { 842 uint8_t index = 0; 843 844 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 845 846 while (index < WLAN_OBJMGR_MAX_DEVICES) { 847 if (g_umac_glb_obj->psoc[index]) { 848 handler((void *)g_umac_glb_obj->psoc[index], 849 arg, index); 850 } 851 index++; 852 } 853 854 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 855 856 return QDF_STATUS_SUCCESS; 857 } 858 859 qdf_export_symbol(wlan_objmgr_iterate_psoc_list); 860 861