xref: /wlan-driver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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