xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
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 
560 QDF_STATUS wlan_objmgr_register_peer_create_handler(
561 		enum wlan_umac_comp_id id,
562 		wlan_objmgr_peer_create_handler handler,
563 		void *arg)
564 {
565 	/* If id is not within valid range, return */
566 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
567 		obj_mgr_err("Component %d is out of range", id);
568 		return QDF_STATUS_MAXCOMP_FAIL;
569 	}
570 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
571 	/* If there is a valid entry, return failure */
572 	if (g_umac_glb_obj->peer_create_handler[id]) {
573 		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
574 		obj_mgr_err("Callback for comp %d is already registered", id);
575 		QDF_ASSERT(0);
576 		return QDF_STATUS_E_FAILURE;
577 	}
578 	/* Store handler and args in Global object table */
579 	g_umac_glb_obj->peer_create_handler[id] = handler;
580 	g_umac_glb_obj->peer_create_handler_arg[id] = arg;
581 
582 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
583 	return QDF_STATUS_SUCCESS;
584 }
585 
586 
587 QDF_STATUS wlan_objmgr_unregister_peer_create_handler(
588 		enum wlan_umac_comp_id id,
589 		wlan_objmgr_peer_create_handler handler,
590 		void *arg)
591 {
592 	/* If id is not within valid range, return */
593 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
594 		obj_mgr_err("Component %d is out of range", id);
595 		return QDF_STATUS_MAXCOMP_FAIL;
596 	}
597 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
598 	/* If there is an invalid entry, return failure */
599 	if (g_umac_glb_obj->peer_create_handler[id] != handler) {
600 		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
601 		obj_mgr_err("Callback for comp %d is not registered", id);
602 		QDF_ASSERT(0);
603 		return QDF_STATUS_E_FAILURE;
604 	}
605 	/* Reset handlers, and args to NULL */
606 	g_umac_glb_obj->peer_create_handler[id] = NULL;
607 	g_umac_glb_obj->peer_create_handler_arg[id] = NULL;
608 
609 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
610 	return QDF_STATUS_SUCCESS;
611 }
612 
613 QDF_STATUS wlan_objmgr_register_peer_destroy_handler(
614 		enum wlan_umac_comp_id id,
615 		wlan_objmgr_peer_destroy_handler handler,
616 		void *arg)
617 {
618 	/* If id is not within valid range, return */
619 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
620 		obj_mgr_err("Component %d is out of range", id);
621 		return QDF_STATUS_MAXCOMP_FAIL;
622 	}
623 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
624 	/* If there is a valid entry, return failure */
625 	if (g_umac_glb_obj->peer_destroy_handler[id]) {
626 		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
627 		obj_mgr_err("Callback for comp %d is already registered", id);
628 		QDF_ASSERT(0);
629 		return QDF_STATUS_E_FAILURE;
630 	}
631 	/* Store handler and args in Global object table */
632 	g_umac_glb_obj->peer_destroy_handler[id] = handler;
633 	g_umac_glb_obj->peer_destroy_handler_arg[id] = arg;
634 
635 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
636 	return QDF_STATUS_SUCCESS;
637 }
638 
639 QDF_STATUS wlan_objmgr_unregister_peer_destroy_handler(
640 		enum wlan_umac_comp_id id,
641 		wlan_objmgr_peer_destroy_handler handler,
642 		void *arg)
643 {
644 	/* If id is not within valid range, return */
645 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
646 		obj_mgr_err("Component %d is out of range", id);
647 		return QDF_STATUS_MAXCOMP_FAIL;
648 	}
649 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
650 	/* If there is an invalid entry, return failure */
651 	if (g_umac_glb_obj->peer_destroy_handler[id] != handler) {
652 		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
653 		obj_mgr_err("Callback for comp %d is not registered", id);
654 		QDF_ASSERT(0);
655 		return QDF_STATUS_E_FAILURE;
656 	}
657 	/* Reset handlers, and args to NULL */
658 	g_umac_glb_obj->peer_destroy_handler[id] = NULL;
659 	g_umac_glb_obj->peer_destroy_handler_arg[id] = NULL;
660 
661 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
662 	return QDF_STATUS_SUCCESS;
663 }
664 
665 QDF_STATUS wlan_objmgr_register_peer_status_handler(
666 		enum wlan_umac_comp_id id,
667 		wlan_objmgr_peer_status_handler handler,
668 		void *arg)
669 {
670 	/* If id is not within valid range, return */
671 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
672 		obj_mgr_err("Component %d is out of range", id);
673 		return QDF_STATUS_MAXCOMP_FAIL;
674 	}
675 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
676 	/* If there is a valid entry, return failure */
677 	if (g_umac_glb_obj->peer_status_handler[id]) {
678 		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
679 		obj_mgr_err("Callback for comp %d is already registered", id);
680 		return QDF_STATUS_E_FAILURE;
681 	}
682 	/* Store handler and args in Global object table */
683 	g_umac_glb_obj->peer_status_handler[id] = handler;
684 	g_umac_glb_obj->peer_status_handler_arg[id] = arg;
685 
686 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
687 	return QDF_STATUS_SUCCESS;
688 }
689 
690 QDF_STATUS wlan_objmgr_unregister_peer_status_handler(
691 		enum wlan_umac_comp_id id,
692 		wlan_objmgr_peer_status_handler handler,
693 		void *arg)
694 {
695 	/* If id is not within valid range, return */
696 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
697 		obj_mgr_err("Component %d is out of range", id);
698 		return QDF_STATUS_MAXCOMP_FAIL;
699 	}
700 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
701 	/* If there is an invalid entry, return failure */
702 	if (g_umac_glb_obj->peer_status_handler[id] != handler) {
703 		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
704 		obj_mgr_err("Callback for comp %d is not registered", id);
705 		return QDF_STATUS_E_FAILURE;
706 	}
707 	/* Reset handlers, and args to NULL */
708 	g_umac_glb_obj->peer_status_handler[id] = NULL;
709 	g_umac_glb_obj->peer_status_handler_arg[id] = NULL;
710 
711 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
712 	return QDF_STATUS_SUCCESS;
713 }
714 
715 QDF_STATUS wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc *psoc)
716 {
717 	uint8_t index = 0;
718 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
719 
720 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
721 	/* Find free slot in PSOC table, store the PSOC */
722 	while (index < WLAN_OBJMGR_MAX_DEVICES) {
723 		if (!g_umac_glb_obj->psoc[index]) {
724 			/* Found free slot, store psoc */
725 			g_umac_glb_obj->psoc[index] = psoc;
726 			psoc->soc_objmgr.psoc_id = index;
727 			status = QDF_STATUS_SUCCESS;
728 			break;
729 		}
730 		index++;
731 	}
732 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
733 	return status;
734 }
735 
736 QDF_STATUS wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc *psoc)
737 {
738 	uint8_t psoc_id;
739 
740 	psoc_id = psoc->soc_objmgr.psoc_id;
741 	QDF_BUG(psoc_id < WLAN_OBJMGR_MAX_DEVICES);
742 	if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES)
743 		return QDF_STATUS_E_INVAL;
744 
745 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
746 	g_umac_glb_obj->psoc[psoc_id] = NULL;
747 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
748 
749 	return QDF_STATUS_SUCCESS;
750 }
751 
752 QDF_STATUS wlan_objmgr_global_obj_can_destroyed(void)
753 {
754 	uint8_t index = 0;
755 	QDF_STATUS status = QDF_STATUS_SUCCESS;
756 
757 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
758 	/* Check whether all PSOCs are freed */
759 	while (index < WLAN_OBJMGR_MAX_DEVICES) {
760 		if (g_umac_glb_obj->psoc[index]) {
761 			status = QDF_STATUS_E_FAILURE;
762 			break;
763 		}
764 		index++;
765 	}
766 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
767 
768 	return status;
769 }
770 qdf_export_symbol(wlan_objmgr_global_obj_can_destroyed);
771 
772 void wlan_objmgr_print_ref_ids(qdf_atomic_t *id,
773 				QDF_TRACE_LEVEL log_level)
774 {
775 	uint32_t i;
776 	uint32_t pending_ref;
777 
778 	obj_mgr_log_level(log_level, "Pending references of object");
779 	for (i = 0; i < WLAN_REF_ID_MAX; i++) {
780 		pending_ref = qdf_atomic_read(&id[i]);
781 		if (pending_ref)
782 			obj_mgr_log_level(log_level, "%s -- %d",
783 				string_from_dbgid(i), pending_ref);
784 	}
785 
786 	return;
787 }
788 
789 QDF_STATUS wlan_objmgr_iterate_psoc_list(
790 		wlan_objmgr_psoc_handler handler,
791 		void *arg, wlan_objmgr_ref_dbgid dbg_id)
792 {
793 	uint8_t index = 0;
794 
795 	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
796 
797 	while (index < WLAN_OBJMGR_MAX_DEVICES) {
798 		if (g_umac_glb_obj->psoc[index]) {
799 			handler((void *)g_umac_glb_obj->psoc[index],
800 				arg, index);
801 		}
802 		index++;
803 	}
804 
805 	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
806 
807 	return QDF_STATUS_SUCCESS;
808 }
809 
810 qdf_export_symbol(wlan_objmgr_iterate_psoc_list);
811 
812