xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
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