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