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 any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 /**
18 * DOC: Public APIs to perform operations on Global objects
19 */
20 #include <wlan_objmgr_cmn.h>
21 #include <wlan_objmgr_global_obj.h>
22 #include <wlan_objmgr_psoc_obj.h>
23 #include <wlan_objmgr_pdev_obj.h>
24 #include <wlan_objmgr_vdev_obj.h>
25 #include <wlan_objmgr_peer_obj.h>
26 #include <wlan_objmgr_debug.h>
27 #include <qdf_mem.h>
28 #include <qdf_module.h>
29 #include "wlan_objmgr_global_obj_i.h"
30 #include "wlan_objmgr_psoc_obj_i.h"
31 #include "wlan_objmgr_pdev_obj_i.h"
32 #include "wlan_objmgr_vdev_obj_i.h"
33 #include <wlan_utility.h>
34 #include <wlan_osif_priv.h>
35 #include "cdp_txrx_cmn.h"
36
37 /*
38 * APIs to Create/Delete Global object APIs
39 */
40
wlan_objmgr_vdev_object_status(struct wlan_objmgr_vdev * vdev)41 static QDF_STATUS wlan_objmgr_vdev_object_status(
42 struct wlan_objmgr_vdev *vdev)
43 {
44 uint8_t id;
45 QDF_STATUS status = QDF_STATUS_SUCCESS;
46
47 wlan_vdev_obj_lock(vdev);
48
49 /* Iterate through all components to derive the object status */
50 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
51 /* If component disabled, Ignore */
52 if (vdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
53 continue;
54 /*
55 * If component operates in Async, status is Partially created,
56 * break
57 */
58 } else if (vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
59 if (!vdev->vdev_comp_priv_obj[id]) {
60 status = QDF_STATUS_COMP_ASYNC;
61 break;
62 }
63 /*
64 * If component failed to allocate its object, treat it as
65 * failure, complete object need to be cleaned up
66 */
67 } else if ((vdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
68 (vdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
69 status = QDF_STATUS_E_FAILURE;
70 break;
71 }
72 }
73 wlan_vdev_obj_unlock(vdev);
74
75 return status;
76 }
77
wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev * vdev)78 static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev)
79 {
80 struct wlan_objmgr_pdev *pdev;
81 struct wlan_objmgr_psoc *psoc;
82
83 if (!vdev) {
84 obj_mgr_err("vdev is NULL");
85 return QDF_STATUS_E_FAILURE;
86 }
87 /* if PDEV is NULL, return */
88 pdev = wlan_vdev_get_pdev(vdev);
89 if (!pdev) {
90 obj_mgr_err("pdev is NULL for vdev-id: %d",
91 vdev->vdev_objmgr.vdev_id);
92 return QDF_STATUS_E_FAILURE;
93 }
94 psoc = wlan_pdev_get_psoc(pdev);
95 if (!psoc) {
96 obj_mgr_err("psoc is NULL in pdev");
97 return QDF_STATUS_E_FAILURE;
98 }
99
100 /* Detach VDEV from PDEV VDEV's list */
101 if (wlan_objmgr_pdev_vdev_detach(pdev, vdev) ==
102 QDF_STATUS_E_FAILURE)
103 return QDF_STATUS_E_FAILURE;
104
105 /* Detach VDEV from PSOC VDEV's list */
106 if (wlan_objmgr_psoc_vdev_detach(psoc, vdev) ==
107 QDF_STATUS_E_FAILURE)
108 return QDF_STATUS_E_FAILURE;
109
110 wlan_objmgr_vdev_trace_del_ref_list(vdev);
111 wlan_objmgr_vdev_trace_deinit_lock(vdev);
112 qdf_spinlock_destroy(&vdev->vdev_lock);
113
114 wlan_destroy_vdev_mlo_lock(vdev);
115
116 qdf_mem_free(vdev->vdev_mlme.bss_chan);
117 qdf_mem_free(vdev->vdev_mlme.des_chan);
118 qdf_mem_free(vdev);
119
120 return QDF_STATUS_SUCCESS;
121
122 }
123
wlan_objmgr_vdev_get_osif_priv(struct wlan_objmgr_vdev * vdev)124 static struct vdev_osif_priv *wlan_objmgr_vdev_get_osif_priv(
125 struct wlan_objmgr_vdev *vdev)
126 {
127 struct vdev_osif_priv *osif_priv;
128
129 /* private data area immediately follows the struct wlan_objmgr_vdev */
130 osif_priv = (struct vdev_osif_priv *)(vdev + 1);
131
132 return osif_priv;
133 }
134
wlan_objmgr_vdev_obj_create(struct wlan_objmgr_pdev * pdev,struct wlan_vdev_create_params * params)135 struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
136 struct wlan_objmgr_pdev *pdev,
137 struct wlan_vdev_create_params *params)
138 {
139 struct wlan_objmgr_vdev *vdev;
140 struct wlan_objmgr_psoc *psoc;
141 uint8_t id;
142 wlan_objmgr_vdev_create_handler handler;
143 wlan_objmgr_vdev_status_handler stat_handler;
144 void *arg;
145 QDF_STATUS obj_status;
146
147 if (!pdev) {
148 obj_mgr_err("pdev is NULL");
149 return NULL;
150 }
151 psoc = wlan_pdev_get_psoc(pdev);
152 /* PSOC is NULL */
153 if (!psoc) {
154 obj_mgr_err("psoc is NULL for pdev-id:%d",
155 pdev->pdev_objmgr.wlan_pdev_id);
156 return NULL;
157 }
158 /* Allocate vdev object memory */
159 vdev = qdf_mem_malloc(sizeof(*vdev) + params->size_vdev_priv);
160 if (!vdev)
161 return NULL;
162 vdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
163
164 vdev->vdev_mlme.bss_chan = qdf_mem_malloc(sizeof(struct wlan_channel));
165 if (!vdev->vdev_mlme.bss_chan) {
166 qdf_mem_free(vdev);
167 return NULL;
168 }
169
170 vdev->vdev_mlme.des_chan = qdf_mem_malloc(sizeof(struct wlan_channel));
171 if (!vdev->vdev_mlme.des_chan) {
172 qdf_mem_free(vdev->vdev_mlme.bss_chan);
173 qdf_mem_free(vdev);
174 return NULL;
175 }
176
177 wlan_create_vdev_mlo_lock(vdev);
178
179 wlan_objmgr_vdev_trace_init_lock(vdev);
180 /* Initialize spinlock */
181 qdf_spinlock_create(&vdev->vdev_lock);
182 /* Attach VDEV to PSOC VDEV's list */
183 if (wlan_objmgr_psoc_vdev_attach(psoc, vdev) !=
184 QDF_STATUS_SUCCESS) {
185 obj_mgr_err("psoc vdev attach failed for vdev-id:%d",
186 vdev->vdev_objmgr.vdev_id);
187 qdf_mem_free(vdev->vdev_mlme.bss_chan);
188 qdf_mem_free(vdev->vdev_mlme.des_chan);
189 wlan_destroy_vdev_mlo_lock(vdev);
190 qdf_spinlock_destroy(&vdev->vdev_lock);
191 wlan_objmgr_vdev_trace_deinit_lock(vdev);
192 qdf_mem_free(vdev);
193 return NULL;
194 }
195 /* Store pdev in vdev */
196 wlan_vdev_set_pdev(vdev, pdev);
197 /* Attach vdev to PDEV */
198 if (wlan_objmgr_pdev_vdev_attach(pdev, vdev) !=
199 QDF_STATUS_SUCCESS) {
200 obj_mgr_err("pdev vdev attach failed for vdev-id:%d",
201 vdev->vdev_objmgr.vdev_id);
202 wlan_objmgr_psoc_vdev_detach(psoc, vdev);
203 qdf_mem_free(vdev->vdev_mlme.bss_chan);
204 qdf_mem_free(vdev->vdev_mlme.des_chan);
205 wlan_destroy_vdev_mlo_lock(vdev);
206 qdf_spinlock_destroy(&vdev->vdev_lock);
207 wlan_objmgr_vdev_trace_deinit_lock(vdev);
208 qdf_mem_free(vdev);
209 return NULL;
210 }
211 /* set opmode */
212 wlan_vdev_mlme_set_opmode(vdev, params->opmode);
213 /* set MAC address */
214 wlan_vdev_mlme_set_macaddr(vdev, params->macaddr);
215 /* set MAT address */
216 wlan_vdev_mlme_set_mataddr(vdev, params->mataddr);
217 /* set MLD address */
218 wlan_vdev_mlme_set_mldaddr(vdev, params->mldaddr);
219 /* set link address */
220 wlan_vdev_mlme_set_linkaddr(vdev, params->macaddr);
221 /* Set create flags */
222 vdev->vdev_objmgr.c_flags = params->flags;
223 /* store os-specific pointer */
224 vdev->vdev_nif.osdev = wlan_objmgr_vdev_get_osif_priv(vdev);
225
226 /* peer count to 0 */
227 vdev->vdev_objmgr.wlan_peer_count = 0;
228 wlan_objmgr_vdev_init_ml_peer_count(vdev);
229 qdf_atomic_init(&vdev->vdev_objmgr.ref_cnt);
230 vdev->vdev_objmgr.print_cnt = 0;
231 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
232 /* Initialize max peer count based on opmode type */
233 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
234 vdev->vdev_objmgr.max_peer_count = WLAN_UMAC_MAX_STA_PEERS;
235 else
236 vdev->vdev_objmgr.max_peer_count =
237 wlan_pdev_get_max_peer_count(pdev);
238
239 wlan_vdev_init_skip_pumac_cnt(vdev);
240 if (params->legacy_osif)
241 vdev->vdev_nif.osdev->legacy_osif_priv = params->legacy_osif;
242
243 /* Initialize peer list */
244 qdf_list_create(&vdev->vdev_objmgr.wlan_peer_list,
245 vdev->vdev_objmgr.max_peer_count +
246 WLAN_MAX_PDEV_TEMP_PEERS);
247 /* TODO init other parameters */
248
249 /* Invoke registered create handlers */
250 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
251 handler = g_umac_glb_obj->vdev_create_handler[id];
252 arg = g_umac_glb_obj->vdev_create_handler_arg[id];
253 if (handler)
254 vdev->obj_status[id] = handler(vdev, arg);
255 else
256 vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
257 }
258
259 /* Derive object status */
260 obj_status = wlan_objmgr_vdev_object_status(vdev);
261
262 if (obj_status == QDF_STATUS_SUCCESS) {
263 /* Object status is SUCCESS, Object is created */
264 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
265 /* Invoke component registered status handlers */
266 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
267 stat_handler = g_umac_glb_obj->vdev_status_handler[id];
268 arg = g_umac_glb_obj->vdev_status_handler_arg[id];
269 if (stat_handler) {
270 stat_handler(vdev, arg,
271 QDF_STATUS_SUCCESS);
272 }
273 }
274 /*
275 * Few components operates in Asynchrous communction, Object state
276 * partially created
277 */
278 } else if (obj_status == QDF_STATUS_COMP_ASYNC) {
279 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
280 /* Component object failed to be created, clean up the object */
281 } else if (obj_status == QDF_STATUS_E_FAILURE) {
282 /* Clean up the psoc */
283 obj_mgr_err("VDEV comp objects creation failed for vdev-id:%d",
284 vdev->vdev_objmgr.vdev_id);
285 wlan_objmgr_vdev_obj_delete(vdev);
286 return NULL;
287 }
288
289 wlan_minidump_log(vdev, sizeof(*vdev), psoc,
290 WLAN_MD_OBJMGR_VDEV, "wlan_objmgr_vdev");
291
292 obj_mgr_debug("Created vdev %d", vdev->vdev_objmgr.vdev_id);
293
294 obj_status = wlan_objmgr_vdev_mlo_dev_ctxt_attach(vdev);
295 if (obj_status != QDF_STATUS_SUCCESS)
296 return NULL;
297
298 return vdev;
299 }
300 qdf_export_symbol(wlan_objmgr_vdev_obj_create);
301
wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev * vdev)302 static QDF_STATUS wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev *vdev)
303 {
304 int8_t id;
305 wlan_objmgr_vdev_destroy_handler handler;
306 QDF_STATUS obj_status;
307 void *arg;
308 uint8_t vdev_id;
309 struct wlan_objmgr_psoc *psoc = NULL;
310
311 if (!vdev) {
312 obj_mgr_err("vdev is NULL");
313 return QDF_STATUS_E_FAILURE;
314 }
315
316 psoc = wlan_vdev_get_psoc(vdev);
317 if (!psoc) {
318 obj_mgr_err("Failed to get psoc");
319 return QDF_STATUS_E_FAILURE;
320 }
321
322 wlan_objmgr_notify_destroy(vdev, WLAN_VDEV_OP);
323
324 vdev_id = wlan_vdev_get_id(vdev);
325
326 obj_mgr_debug("Physically deleting vdev %d", vdev_id);
327
328 if (vdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
329 obj_mgr_alert("VDEV object delete is not invoked vdevid:%d objstate:%d",
330 wlan_vdev_get_id(vdev), vdev->obj_state);
331 WLAN_OBJMGR_BUG(0);
332 return QDF_STATUS_E_FAILURE;
333 }
334
335 wlan_minidump_remove(vdev, sizeof(*vdev), wlan_vdev_get_psoc(vdev),
336 WLAN_MD_OBJMGR_VDEV, "wlan_objmgr_vdev");
337
338 /* Detach DP vdev from DP MLO Device Context */
339
340 obj_status = wlan_objmgr_vdev_mlo_dev_ctxt_detach(vdev);
341 if (obj_status != QDF_STATUS_SUCCESS)
342 return obj_status;
343
344 /* Invoke registered destroy handlers in reverse order of creation */
345 for (id = WLAN_UMAC_COMP_ID_MAX - 1; id >= 0; id--) {
346 handler = g_umac_glb_obj->vdev_destroy_handler[id];
347 arg = g_umac_glb_obj->vdev_destroy_handler_arg[id];
348 if (handler &&
349 (vdev->obj_status[id] == QDF_STATUS_SUCCESS ||
350 vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC))
351 vdev->obj_status[id] = handler(vdev, arg);
352 else
353 vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
354 }
355 /* Derive object status */
356 obj_status = wlan_objmgr_vdev_object_status(vdev);
357
358 if (obj_status == QDF_STATUS_E_FAILURE) {
359 obj_mgr_err("VDEV object deletion failed: vdev-id: %d",
360 vdev_id);
361 /* Ideally should not happen */
362 /* This leads to memleak ??? how to handle */
363 QDF_BUG(0);
364 return QDF_STATUS_E_FAILURE;
365 }
366
367 /* Deletion is in progress */
368 if (obj_status == QDF_STATUS_COMP_ASYNC) {
369 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
370 return QDF_STATUS_COMP_ASYNC;
371 }
372
373 /* Free VDEV object */
374 return wlan_objmgr_vdev_obj_free(vdev);
375 }
376
377 QDF_STATUS
wlan_objmgr_vdev_mlo_dev_ctxt_attach(struct wlan_objmgr_vdev * vdev)378 wlan_objmgr_vdev_mlo_dev_ctxt_attach(struct wlan_objmgr_vdev *vdev)
379 {
380 struct wlan_objmgr_psoc *psoc = NULL;
381 QDF_STATUS status = QDF_STATUS_SUCCESS;
382 struct qdf_mac_addr *mld_addr;
383
384 psoc = wlan_vdev_get_psoc(vdev);
385 if (!psoc) {
386 obj_mgr_err("Failed to get psoc");
387 return QDF_STATUS_E_FAILURE;
388 }
389
390 /* Attach DP vdev to DP MLO dev ctx */
391 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
392
393 if (qdf_is_macaddr_zero(mld_addr))
394 return status;
395
396 /* only for MLO vdev's */
397 status = cdp_mlo_dev_ctxt_attach(wlan_psoc_get_dp_handle(psoc),
398 wlan_vdev_get_id(vdev),
399 (uint8_t *)mld_addr);
400 if (status != QDF_STATUS_SUCCESS) {
401 obj_mgr_err("Fail to attach vdev to DP MLO Dev ctxt");
402 wlan_objmgr_vdev_obj_delete(vdev);
403 return status;
404 }
405
406 return status;
407 }
408
409 qdf_export_symbol(wlan_objmgr_vdev_mlo_dev_ctxt_attach);
410
411 #if defined(WLAN_MLO_MULTI_CHIP)
412 QDF_STATUS
wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev * vdev)413 wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev *vdev)
414 {
415 struct qdf_mac_addr *mld_addr;
416 struct wlan_objmgr_psoc *psoc = NULL;
417
418 psoc = wlan_vdev_get_psoc(vdev);
419 if (!psoc) {
420 obj_mgr_err("Failed to get psoc");
421 return QDF_STATUS_E_FAILURE;
422 }
423
424 /* Detach DP vdev from DP MLO Device Context */
425 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
426 if (qdf_is_macaddr_zero(mld_addr))
427 return QDF_STATUS_SUCCESS;
428
429 /* only for MLO vdev's */
430 if (cdp_mlo_dev_ctxt_detach(wlan_psoc_get_dp_handle(psoc),
431 wlan_vdev_get_id(vdev),
432 (uint8_t *)mld_addr)
433 != QDF_STATUS_SUCCESS) {
434 obj_mgr_err("Failed to detach DP vdev from DP MLO Dev ctxt");
435 QDF_BUG(0);
436 return QDF_STATUS_E_FAILURE;
437 }
438 return QDF_STATUS_SUCCESS;
439 }
440
441 qdf_export_symbol(wlan_objmgr_vdev_mlo_dev_ctxt_detach);
442
443 #else
444 QDF_STATUS
wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev * vdev)445 wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev *vdev)
446 {
447 return QDF_STATUS_SUCCESS;
448 }
449
450 qdf_export_symbol(wlan_objmgr_vdev_mlo_dev_ctxt_detach);
451 #endif
452
wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev * vdev)453 QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev)
454 {
455 uint8_t print_idx;
456
457 if (!vdev) {
458 obj_mgr_err("vdev is NULL");
459 return QDF_STATUS_E_FAILURE;
460 }
461
462 obj_mgr_debug("Logically deleting vdev %d", vdev->vdev_objmgr.vdev_id);
463
464 print_idx = qdf_get_pidx();
465 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
466 QDF_TRACE_LEVEL_DEBUG);
467 /*
468 * Update VDEV object state to LOGICALLY DELETED
469 * It prevents further access of this object
470 */
471 wlan_vdev_obj_lock(vdev);
472 vdev->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
473 wlan_vdev_obj_unlock(vdev);
474 wlan_objmgr_notify_log_delete(vdev, WLAN_VDEV_OP);
475 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
476
477 return QDF_STATUS_SUCCESS;
478 }
479 qdf_export_symbol(wlan_objmgr_vdev_obj_delete);
480
481 /*
482 * APIs to attach/detach component objects
483 */
wlan_objmgr_vdev_component_obj_attach(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id,void * comp_priv_obj,QDF_STATUS status)484 QDF_STATUS wlan_objmgr_vdev_component_obj_attach(
485 struct wlan_objmgr_vdev *vdev,
486 enum wlan_umac_comp_id id,
487 void *comp_priv_obj,
488 QDF_STATUS status)
489 {
490 wlan_objmgr_vdev_status_handler stat_handler;
491 void *arg;
492 uint8_t i;
493 QDF_STATUS obj_status;
494
495 /* component id is invalid */
496 if (id >= WLAN_UMAC_MAX_COMPONENTS)
497 return QDF_STATUS_MAXCOMP_FAIL;
498
499 wlan_vdev_obj_lock(vdev);
500 /* If there is a valid entry, return failure */
501 if (vdev->vdev_comp_priv_obj[id]) {
502 wlan_vdev_obj_unlock(vdev);
503 return QDF_STATUS_E_FAILURE;
504 }
505 /* Save component's pointer and status */
506 vdev->vdev_comp_priv_obj[id] = comp_priv_obj;
507 vdev->obj_status[id] = status;
508 wlan_vdev_obj_unlock(vdev);
509 if (vdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
510 return QDF_STATUS_SUCCESS;
511 /*
512 * If VDEV object status is partially created means, this API is
513 * invoked with different context, this block should be executed for
514 * async components only
515 */
516 /* Derive status */
517 obj_status = wlan_objmgr_vdev_object_status(vdev);
518 /* STATUS_SUCCESS means, object is CREATED */
519 if (obj_status == QDF_STATUS_SUCCESS)
520 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
521 /*
522 * update state as CREATION failed, caller has to delete the
523 * VDEV object
524 */
525 else if (obj_status == QDF_STATUS_E_FAILURE)
526 vdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
527 /* Notify components about the CREATION success/failure */
528 if ((obj_status == QDF_STATUS_SUCCESS) ||
529 (obj_status == QDF_STATUS_E_FAILURE)) {
530 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
531 stat_handler = g_umac_glb_obj->vdev_status_handler[i];
532 arg = g_umac_glb_obj->vdev_status_handler_arg[i];
533 if (stat_handler)
534 stat_handler(vdev, arg, obj_status);
535 }
536 }
537 return QDF_STATUS_SUCCESS;
538 }
539 qdf_export_symbol(wlan_objmgr_vdev_component_obj_attach);
540
wlan_objmgr_vdev_component_obj_detach(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id,void * comp_priv_obj)541 QDF_STATUS wlan_objmgr_vdev_component_obj_detach(
542 struct wlan_objmgr_vdev *vdev,
543 enum wlan_umac_comp_id id,
544 void *comp_priv_obj)
545 {
546 QDF_STATUS obj_status;
547
548 /* component id is invalid */
549 if (id >= WLAN_UMAC_MAX_COMPONENTS)
550 return QDF_STATUS_MAXCOMP_FAIL;
551
552 wlan_vdev_obj_lock(vdev);
553 /* If there is a valid entry, return failure */
554 if (vdev->vdev_comp_priv_obj[id] != comp_priv_obj) {
555 vdev->obj_status[id] = QDF_STATUS_E_FAILURE;
556 wlan_vdev_obj_unlock(vdev);
557 return QDF_STATUS_E_FAILURE;
558 }
559 /* Reset pointers to NULL, update the status*/
560 vdev->vdev_comp_priv_obj[id] = NULL;
561 vdev->obj_status[id] = QDF_STATUS_SUCCESS;
562 wlan_vdev_obj_unlock(vdev);
563
564 /*
565 *If VDEV object status is partially destroyed means, this API is
566 * invoked with different context, this block should be executed for
567 * async components only
568 */
569 if ((vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
570 (vdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
571 /* Derive object status */
572 obj_status = wlan_objmgr_vdev_object_status(vdev);
573 if (obj_status == QDF_STATUS_SUCCESS) {
574 /*
575 * Update the status as Deleted, if full object
576 * deletion is in progress
577 */
578 if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
579 vdev->obj_state = WLAN_OBJ_STATE_DELETED;
580 /*
581 * Move to creation state, since this component
582 * deletion alone requested
583 */
584 else if (vdev->obj_state ==
585 WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
586 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
587 /* Object status is failure */
588 } else if (obj_status == QDF_STATUS_E_FAILURE) {
589 /*
590 * Update the status as Deletion failed, if full object
591 * deletion is in progress
592 */
593 if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
594 vdev->obj_state =
595 WLAN_OBJ_STATE_DELETION_FAILED;
596 /* Move to creation state, since this component
597 deletion alone requested (do not block other
598 components) */
599 else if (vdev->obj_state ==
600 WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
601 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
602 }
603 /* Delete vdev object */
604 if ((obj_status == QDF_STATUS_SUCCESS) &&
605 (vdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
606 /* Free VDEV object */
607 return wlan_objmgr_vdev_obj_free(vdev);
608 }
609 }
610 return QDF_STATUS_SUCCESS;
611 }
612 qdf_export_symbol(wlan_objmgr_vdev_component_obj_detach);
613
614 /*
615 * APIs to operations on vdev objects
616 */
wlan_objmgr_iterate_peerobj_list(struct wlan_objmgr_vdev * vdev,wlan_objmgr_vdev_op_handler handler,void * arg,wlan_objmgr_ref_dbgid dbg_id)617 QDF_STATUS wlan_objmgr_iterate_peerobj_list(
618 struct wlan_objmgr_vdev *vdev,
619 wlan_objmgr_vdev_op_handler handler,
620 void *arg, wlan_objmgr_ref_dbgid dbg_id)
621 {
622 qdf_list_t *peer_list = NULL;
623 struct wlan_objmgr_peer *peer = NULL;
624 struct wlan_objmgr_peer *peer_next = NULL;
625 uint8_t vdev_id;
626
627 if (!vdev) {
628 obj_mgr_err("VDEV is NULL");
629 return QDF_STATUS_E_FAILURE;
630 }
631 wlan_vdev_obj_lock(vdev);
632 vdev_id = wlan_vdev_get_id(vdev);
633
634 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
635 wlan_vdev_obj_unlock(vdev);
636 obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d",
637 vdev->obj_state, vdev_id);
638 return QDF_STATUS_E_FAILURE;
639 }
640 wlan_objmgr_vdev_get_ref(vdev, dbg_id);
641 peer_list = &vdev->vdev_objmgr.wlan_peer_list;
642 if (peer_list) {
643 /* Iterate through VDEV's peer list */
644 peer = wlan_vdev_peer_list_peek_head(peer_list);
645 while (peer) {
646 peer_next = wlan_peer_get_next_peer_of_vdev(peer_list,
647 peer);
648 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
649 QDF_STATUS_SUCCESS) {
650 /* Invoke handler for operation */
651 handler(vdev, (void *)peer, arg);
652 wlan_objmgr_peer_release_ref(peer, dbg_id);
653 }
654 peer = peer_next;
655 }
656 }
657 wlan_objmgr_vdev_release_ref(vdev, dbg_id);
658 wlan_vdev_obj_unlock(vdev);
659 return QDF_STATUS_SUCCESS;
660 }
661
662 qdf_export_symbol(wlan_objmgr_iterate_peerobj_list);
663
664 /*
665 * APIs to get a peer with given mac in a vdev
666 */
667 struct wlan_objmgr_peer *
wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac,wlan_objmgr_ref_dbgid dbg_id)668 wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev *vdev,
669 uint8_t *peer_mac,
670 wlan_objmgr_ref_dbgid dbg_id)
671 {
672 qdf_list_t *peer_list;
673 struct wlan_objmgr_peer *peer = NULL;
674 struct wlan_objmgr_peer *peer_next = NULL;
675 uint8_t vdev_id;
676
677 if (!vdev) {
678 obj_mgr_err("VDEV is NULL");
679 return NULL;
680 }
681 wlan_vdev_obj_lock(vdev);
682 vdev_id = wlan_vdev_get_id(vdev);
683
684 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
685 wlan_vdev_obj_unlock(vdev);
686 obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d",
687 vdev->obj_state, vdev_id);
688 return NULL;
689 }
690 wlan_objmgr_vdev_get_ref(vdev, dbg_id);
691 peer_list = &vdev->vdev_objmgr.wlan_peer_list;
692 /* Iterate through VDEV's peer list */
693 peer = wlan_vdev_peer_list_peek_head(peer_list);
694 while (peer) {
695 peer_next = wlan_peer_get_next_peer_of_vdev(peer_list,
696 peer);
697 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
698 QDF_STATUS_SUCCESS) {
699 if (!WLAN_ADDR_EQ(peer_mac,
700 wlan_peer_get_macaddr(peer))) {
701 wlan_objmgr_vdev_release_ref(vdev,
702 dbg_id);
703 wlan_vdev_obj_unlock(vdev);
704 return peer;
705 }
706 wlan_objmgr_peer_release_ref(peer, dbg_id);
707 }
708 peer = peer_next;
709 }
710 wlan_objmgr_vdev_release_ref(vdev, dbg_id);
711 wlan_vdev_obj_unlock(vdev);
712 return NULL;
713 }
714
715 qdf_export_symbol(wlan_objmgr_vdev_find_peer_by_mac);
716
717 /**
718 * wlan_obj_vdev_populate_logically_del_peerlist() - get peer
719 * from vdev peer list
720 * @obj_list: peer object list
721 * @vdev_obj: vdev object mgr substructure
722 * @dbg_id: id of the caller
723 *
724 * API to finds peer object pointer by vdev from peer hash list for a node
725 * which is in logically deleted state
726 *
727 * Caller to free the list allocated in this function
728 *
729 * Return: list of peer pointers
730 * NULL on FAILURE
731 */
wlan_obj_vdev_populate_logically_del_peerlist(qdf_list_t * obj_list,struct wlan_objmgr_vdev_objmgr * vdev_obj,wlan_objmgr_ref_dbgid dbg_id)732 static qdf_list_t *wlan_obj_vdev_populate_logically_del_peerlist(
733 qdf_list_t *obj_list,
734 struct wlan_objmgr_vdev_objmgr *vdev_obj,
735 wlan_objmgr_ref_dbgid dbg_id)
736 {
737 struct wlan_objmgr_peer *peer;
738 struct wlan_objmgr_peer *peer_next;
739 struct wlan_logically_del_peer *peer_list;
740 qdf_list_t *logical_del_peerlist;
741 bool lock_released = false;
742
743 logical_del_peerlist = qdf_mem_malloc(sizeof(*logical_del_peerlist));
744 if (!logical_del_peerlist)
745 return NULL;
746
747 qdf_list_create(logical_del_peerlist, vdev_obj->max_peer_count);
748
749 peer = wlan_vdev_peer_list_peek_head(obj_list);
750 while (peer) {
751 wlan_peer_obj_lock(peer);
752 peer_next = wlan_peer_get_next_peer_of_vdev(obj_list, peer);
753 if (peer->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED &&
754 qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
755 wlan_objmgr_peer_get_ref(peer, dbg_id);
756 wlan_peer_obj_unlock(peer);
757 lock_released = true;
758
759 peer_list = qdf_mem_malloc(sizeof(*peer_list));
760 if (!peer_list) {
761 wlan_objmgr_peer_release_ref(peer, dbg_id);
762 WLAN_OBJMGR_BUG(0);
763 break;
764 }
765
766 peer_list->peer = peer;
767 qdf_list_insert_front(logical_del_peerlist,
768 &peer_list->list);
769 }
770
771 if (!lock_released)
772 wlan_peer_obj_unlock(peer);
773
774 peer = peer_next;
775 lock_released = false;
776 }
777
778 /* Not found, return NULL */
779 if (qdf_list_empty(logical_del_peerlist)) {
780 qdf_mem_free(logical_del_peerlist);
781 return NULL;
782 }
783
784 return logical_del_peerlist;
785 }
786
wlan_objmgr_vdev_get_log_del_peer_list(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)787 qdf_list_t *wlan_objmgr_vdev_get_log_del_peer_list(
788 struct wlan_objmgr_vdev *vdev,
789 wlan_objmgr_ref_dbgid dbg_id)
790 {
791 qdf_list_t *peer_list;
792 qdf_list_t *log_del_peer_list = NULL;
793
794 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
795 obj_mgr_err("Invalid state vdev:%d state:%d",
796 wlan_vdev_get_id(vdev), vdev->obj_state);
797 return NULL;
798 }
799
800 wlan_vdev_obj_lock(vdev);
801 if (vdev->vdev_objmgr.wlan_peer_count == 0) {
802 wlan_vdev_obj_unlock(vdev);
803 return NULL;
804 }
805
806 wlan_objmgr_vdev_get_ref(vdev, dbg_id);
807 peer_list = &vdev->vdev_objmgr.wlan_peer_list;
808 if (peer_list) {
809 log_del_peer_list =
810 wlan_obj_vdev_populate_logically_del_peerlist(
811 peer_list, &vdev->vdev_objmgr,
812 dbg_id);
813 }
814
815 wlan_objmgr_vdev_release_ref(vdev, dbg_id);
816 wlan_vdev_obj_unlock(vdev);
817
818 return log_del_peer_list;
819 }
820
wlan_objmgr_trigger_vdev_comp_priv_object_creation(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)821 QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_creation(
822 struct wlan_objmgr_vdev *vdev,
823 enum wlan_umac_comp_id id)
824 {
825 wlan_objmgr_vdev_create_handler handler;
826 void *arg;
827 QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
828
829 /* Component id is invalid */
830 if (id >= WLAN_UMAC_MAX_COMPONENTS)
831 return QDF_STATUS_MAXCOMP_FAIL;
832
833 wlan_vdev_obj_lock(vdev);
834 /*
835 * If component object is already created, delete old
836 * component object, then invoke creation
837 */
838 if (vdev->vdev_comp_priv_obj[id]) {
839 wlan_vdev_obj_unlock(vdev);
840 return QDF_STATUS_E_FAILURE;
841 }
842 wlan_vdev_obj_unlock(vdev);
843
844 /* Invoke registered create handlers */
845 handler = g_umac_glb_obj->vdev_create_handler[id];
846 arg = g_umac_glb_obj->vdev_create_handler_arg[id];
847 if (handler)
848 vdev->obj_status[id] = handler(vdev, arg);
849 else
850 return QDF_STATUS_E_FAILURE;
851
852 /* If object status is created, then only handle this object status */
853 if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
854 /* Derive object status */
855 obj_status = wlan_objmgr_vdev_object_status(vdev);
856 /* Move PDEV object state to Partially created state */
857 if (obj_status == QDF_STATUS_COMP_ASYNC) {
858 /*TODO atomic */
859 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
860 }
861 }
862 return obj_status;
863 }
864
wlan_objmgr_trigger_vdev_comp_priv_object_deletion(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)865 QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_deletion(
866 struct wlan_objmgr_vdev *vdev,
867 enum wlan_umac_comp_id id)
868 {
869 wlan_objmgr_vdev_destroy_handler handler;
870 void *arg;
871 QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
872
873 /* component id is invalid */
874 if (id >= WLAN_UMAC_MAX_COMPONENTS)
875 return QDF_STATUS_MAXCOMP_FAIL;
876
877 wlan_vdev_obj_lock(vdev);
878 /* Component object was never created, invalid operation */
879 if (!vdev->vdev_comp_priv_obj[id]) {
880 wlan_vdev_obj_unlock(vdev);
881 return QDF_STATUS_E_FAILURE;
882 }
883 wlan_vdev_obj_unlock(vdev);
884
885 /* Invoke registered create handlers */
886 handler = g_umac_glb_obj->vdev_destroy_handler[id];
887 arg = g_umac_glb_obj->vdev_destroy_handler_arg[id];
888 if (handler)
889 vdev->obj_status[id] = handler(vdev, arg);
890 else
891 return QDF_STATUS_E_FAILURE;
892
893 /* If object status is created, then only handle this object status */
894 if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
895 obj_status = wlan_objmgr_vdev_object_status(vdev);
896 /* move object state to DEL progress */
897 if (obj_status == QDF_STATUS_COMP_ASYNC)
898 vdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
899 }
900 return obj_status;
901 }
902
903
904
wlan_obj_vdev_peerlist_add_tail(qdf_list_t * obj_list,struct wlan_objmgr_peer * obj)905 static void wlan_obj_vdev_peerlist_add_tail(qdf_list_t *obj_list,
906 struct wlan_objmgr_peer *obj)
907 {
908 qdf_list_insert_back(obj_list, &obj->vdev_peer);
909 }
910
wlan_obj_vdev_peerlist_remove_peer(qdf_list_t * obj_list,struct wlan_objmgr_peer * peer)911 static QDF_STATUS wlan_obj_vdev_peerlist_remove_peer(qdf_list_t *obj_list,
912 struct wlan_objmgr_peer *peer)
913 {
914 qdf_list_node_t *vdev_node = NULL;
915
916 if (!peer)
917 return QDF_STATUS_E_FAILURE;
918 /* get vdev list node element */
919 vdev_node = &peer->vdev_peer;
920 /* list is empty, return failure */
921 if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
922 return QDF_STATUS_E_FAILURE;
923
924 return QDF_STATUS_SUCCESS;
925 }
926
wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)927 QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
928 struct wlan_objmgr_peer *peer)
929 {
930 struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
931 struct wlan_objmgr_pdev *pdev;
932 enum QDF_OPMODE opmode;
933
934 wlan_vdev_obj_lock(vdev);
935 pdev = wlan_vdev_get_pdev(vdev);
936 /* If Max VDEV peer count exceeds, return failure */
937 if (peer->peer_mlme.peer_type != WLAN_PEER_STA_TEMP &&
938 peer->peer_mlme.peer_type != WLAN_PEER_MLO_TEMP) {
939 if (objmgr->wlan_peer_count >= objmgr->max_peer_count) {
940 wlan_vdev_obj_unlock(vdev);
941 return QDF_STATUS_E_FAILURE;
942 }
943 }
944 wlan_vdev_obj_unlock(vdev);
945
946 /* If Max PDEV peer count exceeds, return failure */
947 wlan_pdev_obj_lock(pdev);
948 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP ||
949 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) {
950 if (wlan_pdev_get_temp_peer_count(pdev) >=
951 WLAN_MAX_PDEV_TEMP_PEERS) {
952 wlan_pdev_obj_unlock(pdev);
953 return QDF_STATUS_E_FAILURE;
954 }
955 } else {
956 if (wlan_pdev_get_peer_count(pdev) >=
957 wlan_pdev_get_max_peer_count(pdev)) {
958 wlan_pdev_obj_unlock(pdev);
959 return QDF_STATUS_E_FAILURE;
960 }
961 }
962
963 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP ||
964 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP)
965 wlan_pdev_incr_temp_peer_count(wlan_vdev_get_pdev(vdev));
966 else
967 wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
968 wlan_pdev_obj_unlock(pdev);
969
970 wlan_vdev_obj_lock(vdev);
971 /* Add peer to vdev's peer list */
972 wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer);
973 objmgr->wlan_peer_count++;
974
975 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
976 wlan_vdev_mlme_get_macaddr(vdev)) ==
977 QDF_STATUS_SUCCESS) {
978 /*
979 * if peer mac address and vdev mac address match, set
980 * this peer as self peer
981 */
982 wlan_vdev_set_selfpeer(vdev, peer);
983 opmode = wlan_vdev_mlme_get_opmode(vdev);
984 /* For AP mode, self peer and BSS peer are same */
985 if ((opmode == QDF_SAP_MODE) ||
986 (opmode == QDF_P2P_GO_MODE) ||
987 (opmode == QDF_NDI_MODE))
988 wlan_vdev_set_bsspeer(vdev, peer);
989 }
990 /* set BSS peer for sta */
991 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
992 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) &&
993 (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP ||
994 wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO))
995 wlan_vdev_set_bsspeer(vdev, peer);
996
997 /* Increment vdev ref count to make sure it won't be destroyed before */
998 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
999 wlan_vdev_obj_unlock(vdev);
1000 return QDF_STATUS_SUCCESS;
1001 }
1002
wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)1003 QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
1004 struct wlan_objmgr_peer *peer)
1005 {
1006 struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
1007 struct wlan_objmgr_pdev *pdev;
1008
1009 wlan_vdev_obj_lock(vdev);
1010 /* if peer count is 0, return failure */
1011 if (objmgr->wlan_peer_count == 0) {
1012 wlan_vdev_obj_unlock(vdev);
1013 return QDF_STATUS_E_FAILURE;
1014 }
1015
1016 if (wlan_vdev_get_selfpeer(vdev) == peer) {
1017 /*
1018 * There might be instances where new node is created
1019 * before deleting existing node, in which case selfpeer
1020 * will be pointing to the new node. So set selfpeer to
1021 * NULL only if vdev->vdev_objmgr.self_peer is pointing
1022 * to the peer processed for deletion
1023 */
1024 wlan_vdev_set_selfpeer(vdev, NULL);
1025 }
1026
1027 if (wlan_vdev_get_bsspeer(vdev) == peer) {
1028 /*
1029 * There might be instances where new node is created
1030 * before deleting existing node, in which case bsspeer
1031 * in vdev will be pointing to the new node. So set
1032 * bsspeer to NULL only if vdev->vdev_objmgr.bss_peer is
1033 * pointing to the peer processed for deletion
1034 */
1035 wlan_vdev_set_bsspeer(vdev, NULL);
1036 }
1037
1038 /* remove peer from vdev's peer list */
1039 if (wlan_obj_vdev_peerlist_remove_peer(&objmgr->wlan_peer_list, peer)
1040 == QDF_STATUS_E_FAILURE) {
1041 wlan_vdev_obj_unlock(vdev);
1042 return QDF_STATUS_E_FAILURE;
1043 }
1044 /* decrement peer count */
1045 objmgr->wlan_peer_count--;
1046 /* decrement pdev peer count */
1047 pdev = wlan_vdev_get_pdev(vdev);
1048 wlan_vdev_obj_unlock(vdev);
1049
1050 wlan_pdev_obj_lock(pdev);
1051 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP ||
1052 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP)
1053 wlan_pdev_decr_temp_peer_count(pdev);
1054 else
1055 wlan_pdev_decr_peer_count(pdev);
1056 wlan_pdev_obj_unlock(pdev);
1057
1058 /* decrement vdev ref count after peer released its reference */
1059 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
1060 return QDF_STATUS_SUCCESS;
1061 }
1062
wlan_objmgr_vdev_try_get_bsspeer(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1063 struct wlan_objmgr_peer *wlan_objmgr_vdev_try_get_bsspeer(
1064 struct wlan_objmgr_vdev *vdev,
1065 wlan_objmgr_ref_dbgid id)
1066 {
1067 struct wlan_objmgr_peer *peer;
1068 QDF_STATUS status = QDF_STATUS_E_EMPTY;
1069
1070 if (!vdev)
1071 return NULL;
1072
1073 wlan_vdev_obj_lock(vdev);
1074 peer = wlan_vdev_get_bsspeer(vdev);
1075 if (peer)
1076 status = wlan_objmgr_peer_try_get_ref(peer, id);
1077 wlan_vdev_obj_unlock(vdev);
1078
1079 if (QDF_IS_STATUS_SUCCESS(status))
1080 return peer;
1081
1082 return NULL;
1083 }
1084
wlan_objmgr_vdev_get_comp_private_obj(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)1085 void *wlan_objmgr_vdev_get_comp_private_obj(
1086 struct wlan_objmgr_vdev *vdev,
1087 enum wlan_umac_comp_id id)
1088 {
1089 void *comp_priv_obj;
1090
1091 /* component id is invalid */
1092 if (id >= WLAN_UMAC_MAX_COMPONENTS) {
1093 QDF_BUG(0);
1094 return NULL;
1095 }
1096
1097 if (!vdev) {
1098 QDF_BUG(0);
1099 return NULL;
1100 }
1101
1102 comp_priv_obj = vdev->vdev_comp_priv_obj[id];
1103
1104 return comp_priv_obj;
1105 }
1106 qdf_export_symbol(wlan_objmgr_vdev_get_comp_private_obj);
1107
1108 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1109 static inline void
wlan_objmgr_vdev_ref_trace(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1110 wlan_objmgr_vdev_ref_trace(struct wlan_objmgr_vdev *vdev,
1111 wlan_objmgr_ref_dbgid id,
1112 const char *func, int line)
1113 {
1114 struct wlan_objmgr_trace *trace;
1115
1116 trace = &vdev->vdev_objmgr.trace;
1117
1118 if (func)
1119 wlan_objmgr_trace_ref(&trace->references[id].head,
1120 trace, func, line);
1121 }
1122
1123 static inline void
wlan_objmgr_vdev_deref_trace(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1124 wlan_objmgr_vdev_deref_trace(struct wlan_objmgr_vdev *vdev,
1125 wlan_objmgr_ref_dbgid id,
1126 const char *func, int line)
1127 {
1128 struct wlan_objmgr_trace *trace;
1129
1130 trace = &vdev->vdev_objmgr.trace;
1131
1132 if (func)
1133 wlan_objmgr_trace_ref(&trace->dereferences[id].head,
1134 trace, func, line);
1135 }
1136 #endif
1137
1138 #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1139 void wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev *vdev,
1140 wlan_objmgr_ref_dbgid id,
1141 const char *func, int line)
1142 {
1143 if (!vdev) {
1144 obj_mgr_err("vdev obj is NULL for id:%d", id);
1145 QDF_ASSERT(0);
1146 return;
1147 }
1148 /* Increment ref count */
1149 qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt);
1150 qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]);
1151
1152 wlan_objmgr_vdev_ref_trace(vdev, id, func, line);
1153 return;
1154 }
1155
1156 qdf_export_symbol(wlan_objmgr_vdev_get_ref_debug);
1157 #else
wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1158 void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev,
1159 wlan_objmgr_ref_dbgid id)
1160 {
1161 if (!vdev) {
1162 obj_mgr_err("vdev obj is NULL for id:%d", id);
1163 QDF_ASSERT(0);
1164 return;
1165 }
1166 /* Increment ref count */
1167 qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt);
1168 qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]);
1169 }
1170
1171 qdf_export_symbol(wlan_objmgr_vdev_get_ref);
1172 #endif
1173
1174 #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1175 QDF_STATUS wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev *vdev,
1176 wlan_objmgr_ref_dbgid id,
1177 const char *func, int line)
1178 {
1179 uint8_t vdev_id;
1180
1181 if (!vdev) {
1182 obj_mgr_err("vdev obj is NULL for id:%d", id);
1183 QDF_ASSERT(0);
1184 return QDF_STATUS_E_FAILURE;
1185 }
1186
1187 wlan_vdev_obj_lock(vdev);
1188 vdev_id = wlan_vdev_get_id(vdev);
1189 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
1190 wlan_vdev_obj_unlock(vdev);
1191 if (vdev->vdev_objmgr.print_cnt++ <=
1192 WLAN_OBJMGR_RATELIMIT_THRESH)
1193 obj_mgr_err(
1194 "[Ref id: %d] vdev(%d) is not in Created state(%d)",
1195 id, vdev_id, vdev->obj_state);
1196
1197 return QDF_STATUS_E_RESOURCES;
1198 }
1199
1200 /* Increment ref count */
1201 wlan_objmgr_vdev_get_ref_debug(vdev, id, func, line);
1202 wlan_vdev_obj_unlock(vdev);
1203
1204 return QDF_STATUS_SUCCESS;
1205 }
1206
1207 qdf_export_symbol(wlan_objmgr_vdev_try_get_ref_debug);
1208 #else
wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1209 QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev,
1210 wlan_objmgr_ref_dbgid id)
1211 {
1212 uint8_t vdev_id;
1213
1214 if (!vdev) {
1215 obj_mgr_err("vdev obj is NULL for id:%d", id);
1216 QDF_ASSERT(0);
1217 return QDF_STATUS_E_FAILURE;
1218 }
1219
1220 wlan_vdev_obj_lock(vdev);
1221 vdev_id = wlan_vdev_get_id(vdev);
1222 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
1223 wlan_vdev_obj_unlock(vdev);
1224 if (vdev->vdev_objmgr.print_cnt++ <=
1225 WLAN_OBJMGR_RATELIMIT_THRESH)
1226 obj_mgr_debug(
1227 "[Ref id: %d] vdev(%d) is not in Created state(%d)",
1228 id, vdev_id, vdev->obj_state);
1229
1230 return QDF_STATUS_E_RESOURCES;
1231 }
1232
1233 /* Increment ref count */
1234 wlan_objmgr_vdev_get_ref(vdev, id);
1235 wlan_vdev_obj_unlock(vdev);
1236
1237 return QDF_STATUS_SUCCESS;
1238 }
1239
1240 qdf_export_symbol(wlan_objmgr_vdev_try_get_ref);
1241 #endif
1242
1243 #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_vdev_get_next_active_vdev_of_pdev_debug(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1244 struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev_debug(
1245 struct wlan_objmgr_pdev *pdev,
1246 qdf_list_t *vdev_list,
1247 struct wlan_objmgr_vdev *vdev,
1248 wlan_objmgr_ref_dbgid dbg_id,
1249 const char *func, int line)
1250 {
1251 struct wlan_objmgr_vdev *vdev_next;
1252 qdf_list_node_t *node = &vdev->vdev_node;
1253 qdf_list_node_t *prev_node = NULL;
1254
1255 if (!node)
1256 return NULL;
1257
1258 wlan_pdev_obj_lock(pdev);
1259 prev_node = node;
1260 while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1261 QDF_STATUS_SUCCESS) {
1262 vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev,
1263 vdev_node);
1264 if (wlan_objmgr_vdev_try_get_ref_debug(vdev_next, dbg_id,
1265 func, line) ==
1266 QDF_STATUS_SUCCESS) {
1267 wlan_pdev_obj_unlock(pdev);
1268 return vdev_next;
1269 }
1270
1271 prev_node = node;
1272 }
1273 wlan_pdev_obj_unlock(pdev);
1274
1275 return NULL;
1276 }
1277 #else
wlan_vdev_get_next_active_vdev_of_pdev(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)1278 struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev(
1279 struct wlan_objmgr_pdev *pdev,
1280 qdf_list_t *vdev_list,
1281 struct wlan_objmgr_vdev *vdev,
1282 wlan_objmgr_ref_dbgid dbg_id)
1283 {
1284 struct wlan_objmgr_vdev *vdev_next;
1285 qdf_list_node_t *node = &vdev->vdev_node;
1286 qdf_list_node_t *prev_node = NULL;
1287
1288 if (!node)
1289 return NULL;
1290
1291 wlan_pdev_obj_lock(pdev);
1292 prev_node = node;
1293 while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1294 QDF_STATUS_SUCCESS) {
1295 vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev,
1296 vdev_node);
1297 if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) ==
1298 QDF_STATUS_SUCCESS) {
1299 wlan_pdev_obj_unlock(pdev);
1300 return vdev_next;
1301 }
1302
1303 prev_node = node;
1304 }
1305 wlan_pdev_obj_unlock(pdev);
1306
1307 return NULL;
1308 }
1309 #endif
1310
1311 #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_pdev_vdev_list_peek_active_head_debug(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1312 struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head_debug(
1313 struct wlan_objmgr_pdev *pdev,
1314 qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id,
1315 const char *func, int line)
1316 {
1317 struct wlan_objmgr_vdev *vdev;
1318 qdf_list_node_t *node = NULL;
1319 qdf_list_node_t *prev_node = NULL;
1320
1321 wlan_pdev_obj_lock(pdev);
1322
1323 if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
1324 wlan_pdev_obj_unlock(pdev);
1325 return NULL;
1326 }
1327
1328 do {
1329 vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1330 vdev_node);
1331 if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id,
1332 func, line) ==
1333 QDF_STATUS_SUCCESS) {
1334 wlan_pdev_obj_unlock(pdev);
1335 return vdev;
1336 }
1337
1338 prev_node = node;
1339 } while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1340 QDF_STATUS_SUCCESS);
1341
1342 wlan_pdev_obj_unlock(pdev);
1343
1344 return NULL;
1345 }
1346 #else
wlan_pdev_vdev_list_peek_active_head(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,wlan_objmgr_ref_dbgid dbg_id)1347 struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head(
1348 struct wlan_objmgr_pdev *pdev,
1349 qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id)
1350 {
1351 struct wlan_objmgr_vdev *vdev;
1352 qdf_list_node_t *node = NULL;
1353 qdf_list_node_t *prev_node = NULL;
1354
1355 wlan_pdev_obj_lock(pdev);
1356
1357 if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
1358 wlan_pdev_obj_unlock(pdev);
1359 return NULL;
1360 }
1361
1362 do {
1363 vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1364 vdev_node);
1365 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
1366 QDF_STATUS_SUCCESS) {
1367 wlan_pdev_obj_unlock(pdev);
1368 return vdev;
1369 }
1370
1371 prev_node = node;
1372 } while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1373 QDF_STATUS_SUCCESS);
1374
1375 wlan_pdev_obj_unlock(pdev);
1376
1377 return NULL;
1378 }
1379 #endif
1380
1381 #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_pdev_peek_active_first_vdev_debug(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1382 struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev_debug(
1383 struct wlan_objmgr_pdev *pdev,
1384 wlan_objmgr_ref_dbgid dbg_id,
1385 const char *func, int line)
1386 {
1387 struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1388 qdf_list_t *vdev_list;
1389
1390 /* VDEV list */
1391 vdev_list = &objmgr->wlan_vdev_list;
1392
1393 return wlan_pdev_vdev_list_peek_active_head_debug(pdev, vdev_list,
1394 dbg_id, func, line);
1395 }
1396 #else
wlan_pdev_peek_active_first_vdev(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id)1397 struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev(
1398 struct wlan_objmgr_pdev *pdev,
1399 wlan_objmgr_ref_dbgid dbg_id)
1400 {
1401 struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1402 qdf_list_t *vdev_list;
1403
1404 /* VDEV list */
1405 vdev_list = &objmgr->wlan_vdev_list;
1406
1407 return wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
1408 dbg_id);
1409 }
1410 #endif
1411
1412 #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1413 void wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev *vdev,
1414 wlan_objmgr_ref_dbgid id,
1415 const char *func, int line)
1416 {
1417 uint8_t vdev_id;
1418
1419 if (!vdev) {
1420 obj_mgr_err("vdev obj is NULL for id:%d", id);
1421 QDF_ASSERT(0);
1422 return;
1423 }
1424
1425 vdev_id = wlan_vdev_get_id(vdev);
1426
1427 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) {
1428 obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d",
1429 vdev_id, id);
1430 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
1431 QDF_TRACE_LEVEL_FATAL);
1432 WLAN_OBJMGR_BUG(0);
1433 return;
1434 }
1435
1436 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) {
1437 obj_mgr_alert("vdev ref cnt is 0");
1438 WLAN_OBJMGR_BUG(0);
1439 return;
1440 }
1441 qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]);
1442 wlan_objmgr_vdev_deref_trace(vdev, id, func, line);
1443
1444 /* Decrement ref count, free vdev, if ref count == 0 */
1445 if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt))
1446 wlan_objmgr_vdev_obj_destroy(vdev);
1447 }
1448
1449 qdf_export_symbol(wlan_objmgr_vdev_release_ref_debug);
1450 #else
wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1451 void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev,
1452 wlan_objmgr_ref_dbgid id)
1453 {
1454 uint8_t vdev_id;
1455
1456 if (!vdev) {
1457 obj_mgr_err("vdev obj is NULL for id:%d", id);
1458 QDF_ASSERT(0);
1459 return;
1460 }
1461
1462 vdev_id = wlan_vdev_get_id(vdev);
1463
1464 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) {
1465 obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d",
1466 vdev_id, id);
1467 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
1468 QDF_TRACE_LEVEL_FATAL);
1469 WLAN_OBJMGR_BUG(0);
1470 return;
1471 }
1472
1473 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) {
1474 obj_mgr_alert("vdev ref cnt is 0");
1475 WLAN_OBJMGR_BUG(0);
1476 return;
1477 }
1478 qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]);
1479
1480 /* Decrement ref count, free vdev, if ref count == 0 */
1481 if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt))
1482 wlan_objmgr_vdev_obj_destroy(vdev);
1483 }
1484
1485 qdf_export_symbol(wlan_objmgr_vdev_release_ref);
1486 #endif
1487
1488 #ifdef WLAN_OBJMGR_DEBUG
wlan_print_vdev_info(struct wlan_objmgr_vdev * vdev)1489 void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev)
1490 {
1491 struct wlan_objmgr_vdev_objmgr *vdev_objmgr;
1492 uint32_t ref_cnt;
1493
1494 vdev_objmgr = &vdev->vdev_objmgr;
1495
1496 ref_cnt = qdf_atomic_read(&vdev_objmgr->ref_cnt);
1497
1498 obj_mgr_debug("vdev: %pK", vdev);
1499 obj_mgr_debug("vdev_id: %d", vdev_objmgr->vdev_id);
1500 obj_mgr_debug("print_cnt: %d", vdev_objmgr->print_cnt);
1501 obj_mgr_debug("wlan_pdev: %pK", vdev_objmgr->wlan_pdev);
1502 obj_mgr_debug("ref_cnt: %d", ref_cnt);
1503 }
1504
1505 qdf_export_symbol(wlan_print_vdev_info);
1506 #endif
1507
wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev * vdev)1508 void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev)
1509 {
1510 wlan_objmgr_vdev_peer_free_notify_handler stat_handler;
1511 uint8_t i;
1512
1513 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
1514 stat_handler = g_umac_glb_obj->vdev_peer_free_notify_handler[i];
1515 if (stat_handler)
1516 stat_handler(vdev);
1517 }
1518 }
1519
1520 QDF_STATUS
wlan_vdev_get_bss_peer_mac_for_pmksa(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bss_peer_mac)1521 wlan_vdev_get_bss_peer_mac_for_pmksa(struct wlan_objmgr_vdev *vdev,
1522 struct qdf_mac_addr *bss_peer_mac)
1523 {
1524 if (wlan_vdev_mlme_is_mlo_vdev(vdev))
1525 return wlan_vdev_get_bss_peer_mld_mac(vdev, bss_peer_mac);
1526
1527 return wlan_vdev_get_bss_peer_mac(vdev, bss_peer_mac);
1528 }
1529
wlan_vdev_get_bss_peer_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bss_peer_mac)1530 QDF_STATUS wlan_vdev_get_bss_peer_mac(struct wlan_objmgr_vdev *vdev,
1531 struct qdf_mac_addr *bss_peer_mac)
1532 {
1533 struct wlan_objmgr_peer *peer;
1534
1535 if (!vdev) {
1536 obj_mgr_err("vdev is null");
1537 return QDF_STATUS_E_INVAL;
1538 }
1539
1540 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_OBJMGR_ID);
1541 if (!peer) {
1542 obj_mgr_debug("not able to find bss peer for vdev %d",
1543 wlan_vdev_get_id(vdev));
1544 return QDF_STATUS_E_INVAL;
1545 }
1546 wlan_peer_obj_lock(peer);
1547 qdf_mem_copy(bss_peer_mac->bytes, wlan_peer_get_macaddr(peer),
1548 QDF_MAC_ADDR_SIZE);
1549 wlan_peer_obj_unlock(peer);
1550
1551 wlan_objmgr_peer_release_ref(peer, WLAN_MLME_OBJMGR_ID);
1552
1553 return QDF_STATUS_SUCCESS;
1554 }
1555
1556 #ifdef WLAN_FEATURE_11BE_MLO
wlan_vdev_get_bss_peer_mld_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * mld_mac)1557 QDF_STATUS wlan_vdev_get_bss_peer_mld_mac(struct wlan_objmgr_vdev *vdev,
1558 struct qdf_mac_addr *mld_mac)
1559 {
1560 struct wlan_objmgr_peer *peer;
1561
1562 if (!vdev) {
1563 obj_mgr_err("vdev is null");
1564 return QDF_STATUS_E_INVAL;
1565 }
1566
1567 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_OBJMGR_ID);
1568 if (!peer) {
1569 obj_mgr_err("not able to find bss peer for vdev %d",
1570 wlan_vdev_get_id(vdev));
1571 return QDF_STATUS_E_INVAL;
1572 }
1573 wlan_peer_obj_lock(peer);
1574 qdf_mem_copy(mld_mac->bytes, wlan_peer_mlme_get_mldaddr(peer),
1575 QDF_MAC_ADDR_SIZE);
1576 wlan_peer_obj_unlock(peer);
1577
1578 wlan_objmgr_peer_release_ref(peer, WLAN_MLME_OBJMGR_ID);
1579
1580 return QDF_STATUS_SUCCESS;
1581 }
1582
wlan_vdev_mlme_is_tdls_vdev(struct wlan_objmgr_vdev * vdev)1583 bool wlan_vdev_mlme_is_tdls_vdev(struct wlan_objmgr_vdev *vdev)
1584 {
1585 bool is_tdls_vdev;
1586
1587 if (!vdev) {
1588 obj_mgr_err("vdev is NULL");
1589 return false;
1590 }
1591
1592 wlan_acquire_vdev_mlo_lock(vdev);
1593
1594 is_tdls_vdev =
1595 wlan_vdev_mlme_feat_ext2_cap_get(vdev,
1596 WLAN_VDEV_FEXT2_MLO_STA_TDLS);
1597
1598 wlan_release_vdev_mlo_lock(vdev);
1599
1600 return is_tdls_vdev;
1601 }
1602
1603 qdf_export_symbol(wlan_vdev_mlme_is_tdls_vdev);
1604
wlan_vdev_mlme_is_mlo_vdev(struct wlan_objmgr_vdev * vdev)1605 bool wlan_vdev_mlme_is_mlo_vdev(struct wlan_objmgr_vdev *vdev)
1606 {
1607 bool is_mlo_vdev;
1608
1609 if (!vdev) {
1610 obj_mgr_err("vdev is NULL");
1611 return false;
1612 }
1613
1614 wlan_acquire_vdev_mlo_lock(vdev);
1615
1616 is_mlo_vdev =
1617 wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO);
1618
1619 wlan_release_vdev_mlo_lock(vdev);
1620
1621 return is_mlo_vdev;
1622 }
1623
1624 qdf_export_symbol(wlan_vdev_mlme_is_mlo_vdev);
1625
1626 #ifdef WLAN_MLO_MULTI_CHIP
wlan_vdev_mlme_is_mlo_bridge_vdev(struct wlan_objmgr_vdev * vdev)1627 bool wlan_vdev_mlme_is_mlo_bridge_vdev(struct wlan_objmgr_vdev *vdev)
1628 {
1629 if (!vdev)
1630 return false;
1631
1632 return vdev->vdev_objmgr.mlo_bridge_vdev;
1633 }
1634 #endif
1635
wlan_vdev_mlme_set_epcs_flag(struct wlan_objmgr_vdev * vdev,bool flag)1636 void wlan_vdev_mlme_set_epcs_flag(struct wlan_objmgr_vdev *vdev, bool flag)
1637 {
1638 if (!vdev) {
1639 obj_mgr_err("vdev is NULL");
1640 return;
1641 }
1642
1643 vdev->vdev_mlme.epcs_enable = flag;
1644 }
1645
wlan_vdev_mlme_get_epcs_flag(struct wlan_objmgr_vdev * vdev)1646 bool wlan_vdev_mlme_get_epcs_flag(struct wlan_objmgr_vdev *vdev)
1647 {
1648 if (!vdev) {
1649 obj_mgr_err("vdev is NULL");
1650 return false;
1651 }
1652
1653 return vdev->vdev_mlme.epcs_enable;
1654 }
1655
wlan_vdev_mlme_set_user_dis_eht_flag(struct wlan_objmgr_vdev * vdev,bool flag)1656 void wlan_vdev_mlme_set_user_dis_eht_flag(struct wlan_objmgr_vdev *vdev,
1657 bool flag)
1658 {
1659 if (!vdev) {
1660 obj_mgr_err("vdev is NULL");
1661 return;
1662 }
1663
1664 vdev->vdev_mlme.user_disable_eht = flag;
1665 }
1666
wlan_vdev_mlme_get_user_dis_eht_flag(struct wlan_objmgr_vdev * vdev)1667 bool wlan_vdev_mlme_get_user_dis_eht_flag(struct wlan_objmgr_vdev *vdev)
1668 {
1669 if (!vdev) {
1670 obj_mgr_err("vdev is NULL");
1671 return false;
1672 }
1673
1674 return vdev->vdev_mlme.user_disable_eht;
1675 }
1676
wlan_vdev_mlme_set_mlo_vdev(struct wlan_objmgr_vdev * vdev)1677 void wlan_vdev_mlme_set_mlo_vdev(struct wlan_objmgr_vdev *vdev)
1678 {
1679 struct wlan_objmgr_pdev *pdev;
1680
1681 if (!vdev) {
1682 obj_mgr_err("vdev is NULL");
1683 return;
1684 }
1685
1686 pdev = wlan_vdev_get_pdev(vdev);
1687 if (!pdev) {
1688 obj_mgr_err("pdev is NULL");
1689 return;
1690 }
1691
1692 wlan_acquire_vdev_mlo_lock(vdev);
1693
1694 if (wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO)) {
1695 wlan_release_vdev_mlo_lock(vdev);
1696 return;
1697 }
1698 wlan_vdev_mlme_feat_ext2_cap_set(vdev, WLAN_VDEV_FEXT2_MLO);
1699
1700 wlan_pdev_inc_mlo_vdev_count(pdev);
1701
1702 wlan_release_vdev_mlo_lock(vdev);
1703 obj_mgr_debug("Set MLO flag: vdev_id: %d", wlan_vdev_get_id(vdev));
1704 }
1705
wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev * vdev)1706 void wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev *vdev)
1707 {
1708 struct wlan_objmgr_pdev *pdev;
1709 uint32_t mlo_vdev_cap;
1710
1711 if (!vdev) {
1712 obj_mgr_err("vdev is NULL");
1713 return;
1714 }
1715
1716 pdev = wlan_vdev_get_pdev(vdev);
1717 if (!pdev) {
1718 obj_mgr_err("pdev is NULL");
1719 return;
1720 }
1721
1722 wlan_acquire_vdev_mlo_lock(vdev);
1723
1724 if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO)) {
1725 wlan_release_vdev_mlo_lock(vdev);
1726 return;
1727 }
1728
1729 mlo_vdev_cap = WLAN_VDEV_FEXT2_MLO | WLAN_VDEV_FEXT2_MLO_STA_LINK;
1730 wlan_vdev_mlme_feat_ext2_cap_clear(vdev, mlo_vdev_cap);
1731
1732 wlan_pdev_dec_mlo_vdev_count(pdev);
1733
1734 wlan_release_vdev_mlo_lock(vdev);
1735 obj_mgr_debug("Clear MLO flag: vdev_id: %d", wlan_vdev_get_id(vdev));
1736 }
1737
wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev * vdev)1738 void wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
1739 {
1740 uint32_t mlo_vdev_cap;
1741 struct wlan_objmgr_pdev *pdev;
1742
1743 if (!vdev) {
1744 obj_mgr_err("vdev is NULL");
1745 return;
1746 }
1747
1748 pdev = wlan_vdev_get_pdev(vdev);
1749 if (!pdev) {
1750 obj_mgr_err("pdev is NULL");
1751 return;
1752 }
1753
1754 wlan_acquire_vdev_mlo_lock(vdev);
1755
1756 if (wlan_vdev_mlme_feat_ext2_cap_get(vdev,
1757 WLAN_VDEV_FEXT2_MLO_STA_LINK)) {
1758 wlan_release_vdev_mlo_lock(vdev);
1759 return;
1760 } else if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO)) {
1761 wlan_pdev_inc_mlo_vdev_count(pdev);
1762 }
1763
1764 mlo_vdev_cap = WLAN_VDEV_FEXT2_MLO | WLAN_VDEV_FEXT2_MLO_STA_LINK;
1765 wlan_vdev_mlme_feat_ext2_cap_set(vdev, mlo_vdev_cap);
1766
1767 wlan_release_vdev_mlo_lock(vdev);
1768 obj_mgr_debug("Set MLO link flag: vdev_id: %d", wlan_vdev_get_id(vdev));
1769 }
1770
wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev * vdev)1771 void wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
1772 {
1773 if (!vdev) {
1774 obj_mgr_err("vdev is NULL");
1775 return;
1776 }
1777
1778 wlan_acquire_vdev_mlo_lock(vdev);
1779
1780 if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev,
1781 WLAN_VDEV_FEXT2_MLO_STA_LINK)) {
1782 wlan_release_vdev_mlo_lock(vdev);
1783 return;
1784 }
1785 wlan_vdev_mlme_feat_ext2_cap_clear(vdev, WLAN_VDEV_FEXT2_MLO_STA_LINK);
1786
1787 wlan_release_vdev_mlo_lock(vdev);
1788 obj_mgr_debug("Clear MLO link flag: vdev_id: %d",
1789 wlan_vdev_get_id(vdev));
1790 }
1791 #endif /* WLAN_FEATURE_11BE_MLO */
1792
wlan_vdev_get_peer_sta_count(struct wlan_objmgr_vdev * vdev)1793 uint8_t wlan_vdev_get_peer_sta_count(struct wlan_objmgr_vdev *vdev)
1794 {
1795 struct wlan_objmgr_peer *peer;
1796 uint8_t peer_count = 0;
1797
1798 wlan_vdev_obj_lock(vdev);
1799 wlan_objmgr_for_each_vdev_peer(vdev, peer) {
1800 wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID);
1801 if (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA)
1802 peer_count++;
1803
1804 wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID);
1805 }
1806 wlan_vdev_obj_unlock(vdev);
1807
1808 return peer_count;
1809 }
1810