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 */
wlan_objmgr_global_obj_init(void)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
wlan_objmgr_global_obj_deinit(void)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 */
wlan_objmgr_register_psoc_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_psoc_create_handler handler,void * arg)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
wlan_objmgr_unregister_psoc_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_psoc_create_handler handler,void * arg)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
wlan_objmgr_register_psoc_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_psoc_destroy_handler handler,void * arg)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
wlan_objmgr_unregister_psoc_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_psoc_destroy_handler handler,void * arg)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
wlan_objmgr_register_psoc_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_psoc_status_handler handler,void * arg)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
wlan_objmgr_unregister_psoc_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_psoc_status_handler handler,void * arg)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
wlan_objmgr_register_pdev_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_pdev_create_handler handler,void * arg)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
wlan_objmgr_unregister_pdev_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_pdev_create_handler handler,void * arg)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
wlan_objmgr_register_pdev_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_pdev_destroy_handler handler,void * arg)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
wlan_objmgr_unregister_pdev_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_pdev_destroy_handler handler,void * arg)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
wlan_objmgr_register_pdev_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_pdev_status_handler handler,void * arg)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
wlan_objmgr_unregister_pdev_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_pdev_status_handler handler,void * arg)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
wlan_objmgr_register_vdev_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_create_handler handler,void * arg)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
wlan_objmgr_unregister_vdev_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_create_handler handler,void * arg)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
wlan_objmgr_register_vdev_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_destroy_handler handler,void * arg)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
wlan_objmgr_unregister_vdev_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_destroy_handler handler,void * arg)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
wlan_objmgr_register_vdev_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_status_handler handler,void * arg)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
wlan_objmgr_unregister_vdev_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_status_handler handler,void * arg)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
wlan_objmgr_register_vdev_peer_free_notify_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_peer_free_notify_handler handler)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
wlan_objmgr_unregister_vdev_peer_free_notify_handler(enum wlan_umac_comp_id id,wlan_objmgr_vdev_peer_free_notify_handler handler)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
wlan_objmgr_register_peer_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_peer_create_handler handler,void * arg)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
wlan_objmgr_unregister_peer_create_handler(enum wlan_umac_comp_id id,wlan_objmgr_peer_create_handler handler,void * arg)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
wlan_objmgr_register_peer_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_peer_destroy_handler handler,void * arg)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
wlan_objmgr_unregister_peer_destroy_handler(enum wlan_umac_comp_id id,wlan_objmgr_peer_destroy_handler handler,void * arg)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
wlan_objmgr_register_peer_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_peer_status_handler handler,void * arg)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
wlan_objmgr_unregister_peer_status_handler(enum wlan_umac_comp_id id,wlan_objmgr_peer_status_handler handler,void * arg)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
wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc * psoc)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
wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc * psoc)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
wlan_objmgr_global_obj_can_destroyed(void)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
wlan_objmgr_print_ref_ids(qdf_atomic_t * id,QDF_TRACE_LEVEL log_level)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
wlan_objmgr_iterate_psoc_list(wlan_objmgr_psoc_handler handler,void * arg,wlan_objmgr_ref_dbgid dbg_id)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
wlan_objmgr_get_psoc_by_id(uint8_t psoc_id,wlan_objmgr_ref_dbgid dbg_id)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_DP_GLOBAL_CTX
wlan_objmgr_get_global_ctx(void)904 struct dp_global_context *wlan_objmgr_get_global_ctx(void)
905 {
906 return g_umac_glb_obj->global_ctx;
907 }
908
909 qdf_export_symbol(wlan_objmgr_get_global_ctx);
910
wlan_objmgr_set_global_ctx(struct dp_global_context * ctx)911 void wlan_objmgr_set_global_ctx(struct dp_global_context *ctx)
912 {
913 g_umac_glb_obj->global_ctx = ctx;
914 }
915
916 qdf_export_symbol(wlan_objmgr_set_global_ctx);
917 #endif
918
919 #ifdef WLAN_FEATURE_11BE_MLO
wlan_objmgr_get_mlo_ctx(void)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
wlan_objmgr_set_mlo_ctx(struct mlo_mgr_context * ctx)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
wlan_objmgr_set_dp_mlo_ctx(void * dp_handle,uint8_t grp_id)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
wlan_objmgr_get_dp_mlo_ctx(uint8_t grp_id)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