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