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