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