1 /* 2 * Copyright (c) 2016-2020 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_debug.h" 25 #include "wlan_objmgr_psoc_obj.h" 26 #include "qdf_mem.h" 27 #include <qdf_module.h> 28 29 /* Global object, it is declared globally */ 30 struct wlan_objmgr_global *g_umac_glb_obj; 31 32 /* 33 ** APIs to Create/Delete Global object APIs 34 */ 35 QDF_STATUS wlan_objmgr_global_obj_init(void) 36 { 37 struct wlan_objmgr_global *umac_global_obj; 38 39 /* If it is already created, ignore */ 40 if (g_umac_glb_obj) { 41 obj_mgr_err("Global object is already created"); 42 return QDF_STATUS_E_FAILURE; 43 } 44 45 /* Allocation of memory for Global object */ 46 umac_global_obj = (struct wlan_objmgr_global *)qdf_mem_malloc( 47 sizeof(*umac_global_obj)); 48 if (!umac_global_obj) 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) { 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]) { 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]) { 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]) { 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]) { 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]) { 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]) { 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]) { 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 qdf_export_symbol(wlan_objmgr_register_vdev_create_handler); 432 433 QDF_STATUS wlan_objmgr_unregister_vdev_create_handler( 434 enum wlan_umac_comp_id id, 435 wlan_objmgr_vdev_create_handler handler, 436 void *arg) 437 { 438 /* If id is not within valid range, return */ 439 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 440 obj_mgr_err("Component %d is out of range", id); 441 return QDF_STATUS_MAXCOMP_FAIL; 442 } 443 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 444 /* If there is an invalid entry, return failure */ 445 if (g_umac_glb_obj->vdev_create_handler[id] != handler) { 446 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 447 obj_mgr_err("Callback for comp %d is not registered", id); 448 QDF_ASSERT(0); 449 return QDF_STATUS_E_FAILURE; 450 } 451 /* Reset handlers, and args to NULL */ 452 g_umac_glb_obj->vdev_create_handler[id] = NULL; 453 g_umac_glb_obj->vdev_create_handler_arg[id] = NULL; 454 455 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 456 return QDF_STATUS_SUCCESS; 457 } 458 qdf_export_symbol(wlan_objmgr_unregister_vdev_create_handler); 459 460 QDF_STATUS wlan_objmgr_register_vdev_destroy_handler( 461 enum wlan_umac_comp_id id, 462 wlan_objmgr_vdev_destroy_handler handler, 463 void *arg) 464 { 465 /* If id is not within valid range, return */ 466 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 467 obj_mgr_err("Component %d is out of range", id); 468 return QDF_STATUS_MAXCOMP_FAIL; 469 } 470 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 471 /* If there is a valid entry, return failure */ 472 if (g_umac_glb_obj->vdev_destroy_handler[id]) { 473 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 474 obj_mgr_err("Callback for comp %d is already registered", id); 475 QDF_ASSERT(0); 476 return QDF_STATUS_E_FAILURE; 477 } 478 /* Store handler and args in Global object table */ 479 g_umac_glb_obj->vdev_destroy_handler[id] = handler; 480 g_umac_glb_obj->vdev_destroy_handler_arg[id] = arg; 481 482 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 483 return QDF_STATUS_SUCCESS; 484 } 485 qdf_export_symbol(wlan_objmgr_register_vdev_destroy_handler); 486 487 QDF_STATUS wlan_objmgr_unregister_vdev_destroy_handler( 488 enum wlan_umac_comp_id id, 489 wlan_objmgr_vdev_destroy_handler handler, 490 void *arg) 491 { 492 /* If id is not within valid range, return */ 493 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 494 obj_mgr_err("Component %d is out of range", id); 495 return QDF_STATUS_MAXCOMP_FAIL; 496 } 497 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 498 /* If there is an invalid entry, return failure */ 499 if (g_umac_glb_obj->vdev_destroy_handler[id] != handler) { 500 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 501 obj_mgr_err("Callback for comp %d is not registered", id); 502 QDF_ASSERT(0); 503 return QDF_STATUS_E_FAILURE; 504 } 505 /* Reset handlers, and args to NULL */ 506 g_umac_glb_obj->vdev_destroy_handler[id] = NULL; 507 g_umac_glb_obj->vdev_destroy_handler_arg[id] = NULL; 508 509 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 510 return QDF_STATUS_SUCCESS; 511 } 512 qdf_export_symbol(wlan_objmgr_unregister_vdev_destroy_handler); 513 514 QDF_STATUS wlan_objmgr_register_vdev_status_handler( 515 enum wlan_umac_comp_id id, 516 wlan_objmgr_vdev_status_handler handler, 517 void *arg) 518 { 519 /* If id is not within valid range, return */ 520 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 521 obj_mgr_err("Component %d is out of range", id); 522 return QDF_STATUS_MAXCOMP_FAIL; 523 } 524 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 525 /* If there is a valid entry, return failure */ 526 if (g_umac_glb_obj->vdev_status_handler[id]) { 527 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 528 obj_mgr_err("Callback for comp %d is already registered", id); 529 return QDF_STATUS_E_FAILURE; 530 } 531 /* Store handler and args in Global object table */ 532 g_umac_glb_obj->vdev_status_handler[id] = handler; 533 g_umac_glb_obj->vdev_status_handler_arg[id] = arg; 534 535 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 536 return QDF_STATUS_SUCCESS; 537 } 538 539 QDF_STATUS wlan_objmgr_unregister_vdev_status_handler( 540 enum wlan_umac_comp_id id, 541 wlan_objmgr_vdev_status_handler handler, 542 void *arg) 543 { 544 /* If id is not within valid range, return */ 545 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 546 obj_mgr_err("Component %d is out of range", id); 547 return QDF_STATUS_MAXCOMP_FAIL; 548 } 549 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 550 /* If there is an invalid entry, return failure */ 551 if (g_umac_glb_obj->vdev_status_handler[id] != handler) { 552 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 553 obj_mgr_err("Callback for Component %d is not registered", id); 554 return QDF_STATUS_E_FAILURE; 555 } 556 /* Reset handlers, and args to NULL */ 557 g_umac_glb_obj->vdev_status_handler[id] = NULL; 558 g_umac_glb_obj->vdev_status_handler_arg[id] = NULL; 559 560 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 561 return QDF_STATUS_SUCCESS; 562 } 563 564 QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler( 565 enum wlan_umac_comp_id id, 566 wlan_objmgr_vdev_peer_free_notify_handler handler) 567 { 568 /* If id is not within valid range, return */ 569 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 570 obj_mgr_err("Component %d is out of range", id); 571 WLAN_OBJMGR_BUG(0); 572 return QDF_STATUS_MAXCOMP_FAIL; 573 } 574 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 575 /* If there is a valid entry, return failure */ 576 if (g_umac_glb_obj->vdev_peer_free_notify_handler[id]) { 577 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 578 obj_mgr_err("Callback for comp %d is already registered", id); 579 return QDF_STATUS_E_FAILURE; 580 } 581 /* Store handler in Global object table */ 582 g_umac_glb_obj->vdev_peer_free_notify_handler[id] = handler; 583 584 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 585 586 return QDF_STATUS_SUCCESS; 587 } 588 589 QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler( 590 enum wlan_umac_comp_id id, 591 wlan_objmgr_vdev_peer_free_notify_handler handler) 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 WLAN_OBJMGR_BUG(0); 597 return QDF_STATUS_MAXCOMP_FAIL; 598 } 599 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 600 /* If there is an invalid entry, return failure */ 601 if (g_umac_glb_obj->vdev_peer_free_notify_handler[id] != handler) { 602 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 603 obj_mgr_err("Callback for Component %d is not registered", id); 604 return QDF_STATUS_E_FAILURE; 605 } 606 /* Reset handlers to NULL */ 607 g_umac_glb_obj->vdev_peer_free_notify_handler[id] = NULL; 608 609 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 610 611 return QDF_STATUS_SUCCESS; 612 } 613 614 QDF_STATUS wlan_objmgr_register_peer_create_handler( 615 enum wlan_umac_comp_id id, 616 wlan_objmgr_peer_create_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_create_handler[id]) { 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_create_handler[id] = handler; 634 g_umac_glb_obj->peer_create_handler_arg[id] = arg; 635 636 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 637 return QDF_STATUS_SUCCESS; 638 } 639 640 641 QDF_STATUS wlan_objmgr_unregister_peer_create_handler( 642 enum wlan_umac_comp_id id, 643 wlan_objmgr_peer_create_handler handler, 644 void *arg) 645 { 646 /* If id is not within valid range, return */ 647 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 648 obj_mgr_err("Component %d is out of range", id); 649 return QDF_STATUS_MAXCOMP_FAIL; 650 } 651 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 652 /* If there is an invalid entry, return failure */ 653 if (g_umac_glb_obj->peer_create_handler[id] != handler) { 654 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 655 obj_mgr_err("Callback for comp %d is not registered", id); 656 QDF_ASSERT(0); 657 return QDF_STATUS_E_FAILURE; 658 } 659 /* Reset handlers, and args to NULL */ 660 g_umac_glb_obj->peer_create_handler[id] = NULL; 661 g_umac_glb_obj->peer_create_handler_arg[id] = NULL; 662 663 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 664 return QDF_STATUS_SUCCESS; 665 } 666 667 QDF_STATUS wlan_objmgr_register_peer_destroy_handler( 668 enum wlan_umac_comp_id id, 669 wlan_objmgr_peer_destroy_handler handler, 670 void *arg) 671 { 672 /* If id is not within valid range, return */ 673 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 674 obj_mgr_err("Component %d is out of range", id); 675 return QDF_STATUS_MAXCOMP_FAIL; 676 } 677 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 678 /* If there is a valid entry, return failure */ 679 if (g_umac_glb_obj->peer_destroy_handler[id]) { 680 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 681 obj_mgr_err("Callback for comp %d is already registered", id); 682 QDF_ASSERT(0); 683 return QDF_STATUS_E_FAILURE; 684 } 685 /* Store handler and args in Global object table */ 686 g_umac_glb_obj->peer_destroy_handler[id] = handler; 687 g_umac_glb_obj->peer_destroy_handler_arg[id] = arg; 688 689 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 690 return QDF_STATUS_SUCCESS; 691 } 692 693 QDF_STATUS wlan_objmgr_unregister_peer_destroy_handler( 694 enum wlan_umac_comp_id id, 695 wlan_objmgr_peer_destroy_handler handler, 696 void *arg) 697 { 698 /* If id is not within valid range, return */ 699 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 700 obj_mgr_err("Component %d is out of range", id); 701 return QDF_STATUS_MAXCOMP_FAIL; 702 } 703 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 704 /* If there is an invalid entry, return failure */ 705 if (g_umac_glb_obj->peer_destroy_handler[id] != handler) { 706 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 707 obj_mgr_err("Callback for comp %d is not registered", id); 708 QDF_ASSERT(0); 709 return QDF_STATUS_E_FAILURE; 710 } 711 /* Reset handlers, and args to NULL */ 712 g_umac_glb_obj->peer_destroy_handler[id] = NULL; 713 g_umac_glb_obj->peer_destroy_handler_arg[id] = NULL; 714 715 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 716 return QDF_STATUS_SUCCESS; 717 } 718 719 QDF_STATUS wlan_objmgr_register_peer_status_handler( 720 enum wlan_umac_comp_id id, 721 wlan_objmgr_peer_status_handler handler, 722 void *arg) 723 { 724 /* If id is not within valid range, return */ 725 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 726 obj_mgr_err("Component %d is out of range", id); 727 return QDF_STATUS_MAXCOMP_FAIL; 728 } 729 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 730 /* If there is a valid entry, return failure */ 731 if (g_umac_glb_obj->peer_status_handler[id]) { 732 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 733 obj_mgr_err("Callback for comp %d is already registered", id); 734 return QDF_STATUS_E_FAILURE; 735 } 736 /* Store handler and args in Global object table */ 737 g_umac_glb_obj->peer_status_handler[id] = handler; 738 g_umac_glb_obj->peer_status_handler_arg[id] = arg; 739 740 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 741 return QDF_STATUS_SUCCESS; 742 } 743 744 QDF_STATUS wlan_objmgr_unregister_peer_status_handler( 745 enum wlan_umac_comp_id id, 746 wlan_objmgr_peer_status_handler handler, 747 void *arg) 748 { 749 /* If id is not within valid range, return */ 750 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 751 obj_mgr_err("Component %d is out of range", id); 752 return QDF_STATUS_MAXCOMP_FAIL; 753 } 754 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 755 /* If there is an invalid entry, return failure */ 756 if (g_umac_glb_obj->peer_status_handler[id] != handler) { 757 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 758 obj_mgr_err("Callback for comp %d is not registered", id); 759 return QDF_STATUS_E_FAILURE; 760 } 761 /* Reset handlers, and args to NULL */ 762 g_umac_glb_obj->peer_status_handler[id] = NULL; 763 g_umac_glb_obj->peer_status_handler_arg[id] = NULL; 764 765 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 766 return QDF_STATUS_SUCCESS; 767 } 768 769 QDF_STATUS wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc *psoc) 770 { 771 uint8_t index = 0; 772 QDF_STATUS status = QDF_STATUS_E_FAILURE; 773 774 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 775 /* Find free slot in PSOC table, store the PSOC */ 776 while (index < WLAN_OBJMGR_MAX_DEVICES) { 777 if (!g_umac_glb_obj->psoc[index]) { 778 /* Found free slot, store psoc */ 779 g_umac_glb_obj->psoc[index] = psoc; 780 psoc->soc_objmgr.psoc_id = index; 781 status = QDF_STATUS_SUCCESS; 782 break; 783 } 784 index++; 785 } 786 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 787 return status; 788 } 789 790 QDF_STATUS wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc *psoc) 791 { 792 uint8_t psoc_id; 793 794 psoc_id = psoc->soc_objmgr.psoc_id; 795 QDF_BUG(psoc_id < WLAN_OBJMGR_MAX_DEVICES); 796 if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES) 797 return QDF_STATUS_E_INVAL; 798 799 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 800 g_umac_glb_obj->psoc[psoc_id] = NULL; 801 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 802 803 return QDF_STATUS_SUCCESS; 804 } 805 806 QDF_STATUS wlan_objmgr_global_obj_can_destroyed(void) 807 { 808 uint8_t index = 0; 809 QDF_STATUS status = QDF_STATUS_SUCCESS; 810 811 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 812 /* Check whether all PSOCs are freed */ 813 while (index < WLAN_OBJMGR_MAX_DEVICES) { 814 if (g_umac_glb_obj->psoc[index]) { 815 status = QDF_STATUS_E_FAILURE; 816 break; 817 } 818 index++; 819 } 820 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 821 822 return status; 823 } 824 qdf_export_symbol(wlan_objmgr_global_obj_can_destroyed); 825 826 void wlan_objmgr_print_ref_ids(qdf_atomic_t *id, 827 QDF_TRACE_LEVEL log_level) 828 { 829 uint32_t i; 830 uint32_t pending_ref; 831 832 obj_mgr_log_level(log_level, "Pending references of object"); 833 for (i = 0; i < WLAN_REF_ID_MAX; i++) { 834 pending_ref = qdf_atomic_read(&id[i]); 835 if (pending_ref) 836 obj_mgr_log_level(log_level, "%s -- %d", 837 string_from_dbgid(i), pending_ref); 838 } 839 840 return; 841 } 842 843 QDF_STATUS wlan_objmgr_iterate_psoc_list( 844 wlan_objmgr_psoc_handler handler, 845 void *arg, wlan_objmgr_ref_dbgid dbg_id) 846 { 847 uint8_t index = 0; 848 849 qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); 850 851 while (index < WLAN_OBJMGR_MAX_DEVICES) { 852 if (g_umac_glb_obj->psoc[index]) { 853 handler((void *)g_umac_glb_obj->psoc[index], 854 arg, index); 855 } 856 index++; 857 } 858 859 qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); 860 861 return QDF_STATUS_SUCCESS; 862 } 863 864 qdf_export_symbol(wlan_objmgr_iterate_psoc_list); 865 866