1  /*
2   * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   * Permission to use, copy, modify, and/or distribute this software for
6   * any purpose with or without fee is hereby granted, provided that the
7   * above copyright notice and this permission notice appear in all
8   * copies.
9   *
10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17   * PERFORMANCE OF THIS SOFTWARE.
18   */
19   /**
20    * DOC: Public APIs to perform operations on Global objects
21    */
22  #include <wlan_objmgr_cmn.h>
23  #include <wlan_objmgr_global_obj.h>
24  #include <wlan_objmgr_psoc_obj.h>
25  #include <wlan_objmgr_pdev_obj.h>
26  #include <wlan_objmgr_vdev_obj.h>
27  #include <wlan_objmgr_peer_obj.h>
28  #include <wlan_objmgr_debug.h>
29  #include <qdf_mem.h>
30  #include <qdf_module.h>
31  #include "wlan_objmgr_global_obj_i.h"
32  #include "wlan_objmgr_psoc_obj_i.h"
33  #include "wlan_objmgr_pdev_obj_i.h"
34  #include <wlan_utility.h>
35  #include <wlan_cm_api.h>
36  
37  /*
38   * APIs to Create/Delete Global object APIs
39   */
wlan_objmgr_pdev_object_status(struct wlan_objmgr_pdev * pdev)40  static QDF_STATUS wlan_objmgr_pdev_object_status(
41  		struct wlan_objmgr_pdev *pdev)
42  {
43  	uint8_t id;
44  	QDF_STATUS status = QDF_STATUS_SUCCESS;
45  
46  	wlan_pdev_obj_lock(pdev);
47  	/* Iterate through all components to derive the object status */
48  	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
49  		/* If component disabled, Ignore */
50  		if (pdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
51  			continue;
52  		/* If component operates in Async, status is Partially created,
53  			break */
54  		} else if (pdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
55  			if (!pdev->pdev_comp_priv_obj[id]) {
56  				status = QDF_STATUS_COMP_ASYNC;
57  				break;
58  			}
59  		/* If component failed to allocate its object, treat it as
60  			failure, complete object need to be cleaned up */
61  		} else if ((pdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
62  			(pdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
63  			status = QDF_STATUS_E_FAILURE;
64  			break;
65  		}
66  	}
67  	wlan_pdev_obj_unlock(pdev);
68  	return status;
69  }
70  
wlan_objmgr_pdev_obj_free(struct wlan_objmgr_pdev * pdev)71  static QDF_STATUS wlan_objmgr_pdev_obj_free(struct wlan_objmgr_pdev *pdev)
72  {
73  
74  	uint8_t pdev_id;
75  
76  	if (!pdev) {
77  		obj_mgr_err("pdev obj is NULL");
78  		QDF_ASSERT(0);
79  		return QDF_STATUS_E_FAILURE;
80  	}
81  
82  	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
83  
84  	/* Detach PDEV from PSOC PDEV's list */
85  	if (wlan_objmgr_psoc_pdev_detach(pdev->pdev_objmgr.wlan_psoc, pdev) ==
86  						QDF_STATUS_E_FAILURE) {
87  		obj_mgr_err("PSOC PDEV detach failed: pdev-id: %d", pdev_id);
88  		return QDF_STATUS_E_FAILURE;
89  	}
90  	qdf_spinlock_destroy(&pdev->pdev_lock);
91  	wlan_delayed_peer_obj_free_deinit(pdev);
92  	qdf_mem_free(pdev);
93  
94  	return QDF_STATUS_SUCCESS;
95  }
96  
wlan_objmgr_pdev_obj_create(struct wlan_objmgr_psoc * psoc,struct pdev_osif_priv * osdev_priv)97  struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create(
98  			struct wlan_objmgr_psoc *psoc,
99  			struct pdev_osif_priv *osdev_priv)
100  {
101  	struct wlan_objmgr_pdev *pdev;
102  	uint8_t id;
103  	wlan_objmgr_pdev_create_handler handler;
104  	wlan_objmgr_pdev_status_handler s_handler;
105  	void *arg;
106  	QDF_STATUS obj_status;
107  
108  	if (!psoc) {
109  		obj_mgr_err("psoc is NULL");
110  		return NULL;
111  	}
112  	/* Allocate PDEV object's memory */
113  	pdev = qdf_mem_malloc(sizeof(*pdev));
114  	if (!pdev)
115  		return NULL;
116  
117  	pdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
118  	/* Initialize PDEV spinlock */
119  	qdf_spinlock_create(&pdev->pdev_lock);
120  	wlan_delayed_peer_obj_free_init(pdev);
121  
122  	/* Attach PDEV with PSOC */
123  	if (wlan_objmgr_psoc_pdev_attach(psoc, pdev)
124  				!= QDF_STATUS_SUCCESS) {
125  		obj_mgr_err("pdev psoc attach failed");
126  		qdf_spinlock_destroy(&pdev->pdev_lock);
127  		qdf_mem_free(pdev);
128  		return NULL;
129  	}
130  	wlan_minidump_log(pdev, sizeof(*pdev), psoc,
131  			  WLAN_MD_OBJMGR_PDEV, "wlan_objmgr_pdev");
132  	/* Save PSOC object pointer in PDEV */
133  	wlan_pdev_set_psoc(pdev, psoc);
134  	/* Initialize PDEV's VDEV list, assign default values */
135  	qdf_list_create(&pdev->pdev_objmgr.wlan_vdev_list,
136  			WLAN_UMAC_PDEV_MAX_VDEVS);
137  	pdev->pdev_objmgr.wlan_vdev_count = 0;
138  	pdev->pdev_objmgr.max_vdev_count = WLAN_UMAC_PDEV_MAX_VDEVS;
139  	pdev->pdev_objmgr.wlan_peer_count = 0;
140  	pdev->pdev_objmgr.temp_peer_count = 0;
141  	pdev->pdev_objmgr.max_peer_count = wlan_psoc_get_max_peer_count(psoc);
142  	wlan_pdev_init_mlo_vdev_count(pdev);
143  	wlan_pdev_init_mlo_bridge_vdev_count(pdev);
144  	/* Save HDD/OSIF pointer */
145  	pdev->pdev_nif.pdev_ospriv = osdev_priv;
146  	qdf_atomic_init(&pdev->pdev_objmgr.ref_cnt);
147  	pdev->pdev_objmgr.print_cnt = 0;
148  	wlan_objmgr_pdev_get_ref(pdev, WLAN_OBJMGR_ID);
149  	/* Invoke registered create handlers */
150  	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
151  		handler = g_umac_glb_obj->pdev_create_handler[id];
152  		arg = g_umac_glb_obj->pdev_create_handler_arg[id];
153  		if (handler)
154  			pdev->obj_status[id] = handler(pdev, arg);
155  		else
156  			pdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
157  	}
158  	/* Derive object status */
159  	obj_status = wlan_objmgr_pdev_object_status(pdev);
160  
161  	if (obj_status == QDF_STATUS_SUCCESS) {
162  		/* Object status is SUCCESS, Object is created */
163  		pdev->obj_state = WLAN_OBJ_STATE_CREATED;
164  		/* Invoke component registered status handlers */
165  		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
166  			s_handler = g_umac_glb_obj->pdev_status_handler[id];
167  			arg = g_umac_glb_obj->pdev_status_handler_arg[id];
168  			if (s_handler) {
169  				s_handler(pdev, arg,
170  					  QDF_STATUS_SUCCESS);
171  			}
172  		}
173  	/* Few components operates in Asynchrous communction, Object state
174  	partially created */
175  	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
176  		pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
177  	/* Component object failed to be created, clean up the object */
178  	} else if (obj_status == QDF_STATUS_E_FAILURE) {
179  		/* Clean up the psoc */
180  		obj_mgr_err("PDEV component objects allocation failed");
181  		wlan_objmgr_pdev_obj_delete(pdev);
182  		return NULL;
183  	}
184  
185  	obj_mgr_debug("Created pdev %d", pdev->pdev_objmgr.wlan_pdev_id);
186  
187  	return pdev;
188  }
189  qdf_export_symbol(wlan_objmgr_pdev_obj_create);
190  
wlan_objmgr_pdev_obj_destroy(struct wlan_objmgr_pdev * pdev)191  static QDF_STATUS wlan_objmgr_pdev_obj_destroy(struct wlan_objmgr_pdev *pdev)
192  {
193  	uint8_t id;
194  	wlan_objmgr_pdev_destroy_handler handler;
195  	QDF_STATUS obj_status;
196  	void *arg;
197  	uint8_t pdev_id;
198  
199  	if (!pdev) {
200  		obj_mgr_err("pdev is NULL");
201  		return QDF_STATUS_E_FAILURE;
202  	}
203  	wlan_objmgr_notify_destroy(pdev, WLAN_PDEV_OP);
204  
205  	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
206  
207  	wlan_print_pdev_info(pdev);
208  	obj_mgr_debug("Physically deleting pdev %d", pdev_id);
209  
210  	if (pdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
211  		obj_mgr_err("PDEV object delete is not invoked pdevid:%d objstate:%d",
212  			    pdev_id, pdev->obj_state);
213  		WLAN_OBJMGR_BUG(0);
214  	}
215  
216  	wlan_minidump_remove(pdev, sizeof(*pdev), wlan_pdev_get_psoc(pdev),
217  			     WLAN_MD_OBJMGR_PDEV, "wlan_objmgr_pdev");
218  
219  	/* Invoke registered destroy handlers */
220  	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
221  		handler = g_umac_glb_obj->pdev_destroy_handler[id];
222  		arg = g_umac_glb_obj->pdev_destroy_handler_arg[id];
223  		if (handler &&
224  		    (pdev->obj_status[id] == QDF_STATUS_SUCCESS ||
225  		     pdev->obj_status[id] == QDF_STATUS_COMP_ASYNC))
226  			pdev->obj_status[id] = handler(pdev, arg);
227  		else
228  			pdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
229  	}
230  	/* Derive object status */
231  	obj_status = wlan_objmgr_pdev_object_status(pdev);
232  
233  	if (obj_status == QDF_STATUS_E_FAILURE) {
234  		obj_mgr_err("PDEV component objects destroy failed: pdev-id:%d",
235  				pdev_id);
236  		/* Ideally should not happen */
237  		/* This leads to memleak ??? how to handle */
238  		QDF_BUG(0);
239  		return QDF_STATUS_E_FAILURE;
240  	}
241  	/* Deletion is in progress */
242  	if (obj_status == QDF_STATUS_COMP_ASYNC) {
243  		pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
244  		return QDF_STATUS_COMP_ASYNC;
245  	}
246  	/* Free PDEV object */
247  	return wlan_objmgr_pdev_obj_free(pdev);
248  }
249  
wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev * pdev)250  QDF_STATUS wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev *pdev)
251  {
252  	uint8_t print_idx;
253  
254  	if (!pdev) {
255  		obj_mgr_err("pdev is NULL");
256  		return QDF_STATUS_E_FAILURE;
257  	}
258  
259  	obj_mgr_debug("Logically deleting pdev %d",
260  		      pdev->pdev_objmgr.wlan_pdev_id);
261  
262  	print_idx = qdf_get_pidx();
263  	wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg,
264  				  QDF_TRACE_LEVEL_DEBUG);
265  	/*
266  	 * Update PDEV object state to LOGICALLY DELETED
267  	 * It prevents further access of this object
268  	 */
269  	wlan_pdev_obj_lock(pdev);
270  	pdev->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
271  	wlan_pdev_obj_unlock(pdev);
272  	wlan_objmgr_notify_log_delete(pdev, WLAN_PDEV_OP);
273  	wlan_objmgr_pdev_release_ref(pdev, WLAN_OBJMGR_ID);
274  
275  	return QDF_STATUS_SUCCESS;
276  }
277  qdf_export_symbol(wlan_objmgr_pdev_obj_delete);
278  
279  /*
280   * APIs to attach/detach component objects
281   */
wlan_objmgr_pdev_component_obj_attach(struct wlan_objmgr_pdev * pdev,enum wlan_umac_comp_id id,void * comp_priv_obj,QDF_STATUS status)282  QDF_STATUS wlan_objmgr_pdev_component_obj_attach(
283  		struct wlan_objmgr_pdev *pdev,
284  		enum wlan_umac_comp_id id,
285  		void *comp_priv_obj,
286  		QDF_STATUS status)
287  {
288  	uint8_t i;
289  	wlan_objmgr_pdev_status_handler s_hlr;
290  	void *a;
291  	QDF_STATUS obj_status;
292  
293  	/* component id is invalid */
294  	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
295  		obj_mgr_err("component-id %d is not supported", id);
296  		return QDF_STATUS_MAXCOMP_FAIL;
297  	}
298  	wlan_pdev_obj_lock(pdev);
299  	/* If there is a valid entry, return failure */
300  	if (pdev->pdev_comp_priv_obj[id]) {
301  		obj_mgr_err("component-%d already have valid pointer", id);
302  		wlan_pdev_obj_unlock(pdev);
303  		return QDF_STATUS_E_FAILURE;
304  	}
305  	/* Save component's pointer and status */
306  	pdev->pdev_comp_priv_obj[id] = comp_priv_obj;
307  	pdev->obj_status[id] = status;
308  
309  	wlan_pdev_obj_unlock(pdev);
310  
311  	if (pdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
312  		return QDF_STATUS_SUCCESS;
313  	/*
314  	 * If PDEV object status is partially created means, this API is
315  	 * invoked with different context, this block should be executed for
316  	 * async components only
317  	 */
318  	/* Derive status */
319  	obj_status = wlan_objmgr_pdev_object_status(pdev);
320  	/* STATUS_SUCCESS means, object is CREATED */
321  	if (obj_status == QDF_STATUS_SUCCESS)
322  		pdev->obj_state = WLAN_OBJ_STATE_CREATED;
323  	/* update state as CREATION failed, caller has to delete the
324  	PDEV object */
325  	else if (obj_status == QDF_STATUS_E_FAILURE)
326  		pdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
327  	/* Notify components about the CREATION success/failure */
328  	if ((obj_status == QDF_STATUS_SUCCESS) ||
329  	    (obj_status == QDF_STATUS_E_FAILURE)) {
330  		/* notify object status */
331  		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
332  			s_hlr = g_umac_glb_obj->pdev_status_handler[i];
333  			a = g_umac_glb_obj->pdev_status_handler_arg[i];
334  			if (s_hlr)
335  				s_hlr(pdev, a, obj_status);
336  		}
337  	}
338  	return QDF_STATUS_SUCCESS;
339  }
340  qdf_export_symbol(wlan_objmgr_pdev_component_obj_attach);
341  
wlan_objmgr_pdev_component_obj_detach(struct wlan_objmgr_pdev * pdev,enum wlan_umac_comp_id id,void * comp_priv_obj)342  QDF_STATUS wlan_objmgr_pdev_component_obj_detach(
343  		struct wlan_objmgr_pdev *pdev,
344  		enum wlan_umac_comp_id id,
345  		void *comp_priv_obj)
346  {
347  	QDF_STATUS obj_status;
348  
349  	/* component id is invalid */
350  	if (id >= WLAN_UMAC_MAX_COMPONENTS)
351  		return QDF_STATUS_MAXCOMP_FAIL;
352  
353  	wlan_pdev_obj_lock(pdev);
354  	/* If there is a invalid entry, return failure */
355  	if (pdev->pdev_comp_priv_obj[id] != comp_priv_obj) {
356  		pdev->obj_status[id] = QDF_STATUS_E_FAILURE;
357  		wlan_pdev_obj_unlock(pdev);
358  		return QDF_STATUS_E_FAILURE;
359  	}
360  	/* Reset pointers to NULL, update the status*/
361  	pdev->pdev_comp_priv_obj[id] = NULL;
362  	pdev->obj_status[id] = QDF_STATUS_SUCCESS;
363  	wlan_pdev_obj_unlock(pdev);
364  
365  	/* If PDEV object status is partially destroyed means, this API is
366  	invoked with different context, this block should be executed for async
367  	components only */
368  	if ((pdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
369  	    (pdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
370  		/* Derive object status */
371  		obj_status = wlan_objmgr_pdev_object_status(pdev);
372  		if (obj_status == QDF_STATUS_SUCCESS) {
373  			/*Update the status as Deleted, if full object
374  				deletion is in progress */
375  			if (pdev->obj_state ==
376  				WLAN_OBJ_STATE_PARTIALLY_DELETED)
377  				pdev->obj_state = WLAN_OBJ_STATE_DELETED;
378  			/* Move to creation state, since this component
379  			deletion alone requested */
380  			if (pdev->obj_state ==
381  				WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
382  				pdev->obj_state = WLAN_OBJ_STATE_CREATED;
383  		/* Object status is failure */
384  		} else if (obj_status == QDF_STATUS_E_FAILURE) {
385  			/*Update the status as Deletion failed, if full object
386  				deletion is in progress */
387  			if (pdev->obj_state ==
388  					WLAN_OBJ_STATE_PARTIALLY_DELETED)
389  				pdev->obj_state =
390  					WLAN_OBJ_STATE_DELETION_FAILED;
391  			/* Move to creation state, since this component
392  			deletion alone requested (do not block other
393  			components)*/
394  			if (pdev->obj_state ==
395  					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
396  				pdev->obj_state = WLAN_OBJ_STATE_CREATED;
397  		}
398  
399  		/* Delete pdev object */
400  		if ((obj_status == QDF_STATUS_SUCCESS) &&
401  		    (pdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
402  			/* Free PDEV object */
403  			return wlan_objmgr_pdev_obj_free(pdev);
404  		}
405  	}
406  	return QDF_STATUS_SUCCESS;
407  }
408  qdf_export_symbol(wlan_objmgr_pdev_component_obj_detach);
409  
410  /*
411   * APIs to operations on pdev objects
412   */
wlan_objmgr_pdev_vdev_iterate_peers(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,wlan_objmgr_pdev_op_handler handler,void * arg,uint8_t lock_free_op,wlan_objmgr_ref_dbgid dbg_id)413  static void wlan_objmgr_pdev_vdev_iterate_peers(struct wlan_objmgr_pdev *pdev,
414  				struct wlan_objmgr_vdev *vdev,
415  				wlan_objmgr_pdev_op_handler handler,
416  				void *arg, uint8_t lock_free_op,
417  				wlan_objmgr_ref_dbgid dbg_id)
418  {
419  	qdf_list_t *peer_list = NULL;
420  	struct wlan_objmgr_peer *peer = NULL;
421  	struct wlan_objmgr_peer *peer_next = NULL;
422  
423  	/* Iterating through vdev's peer list, so lock is
424  		needed */
425  	/* Get peer list of the vdev */
426  	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
427  	if (peer_list) {
428  		peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
429  								dbg_id);
430  		while (peer) {
431  			/* Invoke the handler */
432  			handler(pdev, (void *)peer, arg);
433  			/* Get next peer pointer, increments the ref count */
434  			peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev,
435  						peer_list, peer, dbg_id);
436  			wlan_objmgr_peer_release_ref(peer, dbg_id);
437  			peer = peer_next;
438  		}
439  	}
440  }
441  
wlan_objmgr_pdev_iterate_obj_list(struct wlan_objmgr_pdev * pdev,enum wlan_objmgr_obj_type obj_type,wlan_objmgr_pdev_op_handler handler,void * arg,uint8_t lock_free_op,wlan_objmgr_ref_dbgid dbg_id)442  QDF_STATUS wlan_objmgr_pdev_iterate_obj_list(
443  		struct wlan_objmgr_pdev *pdev,
444  		enum wlan_objmgr_obj_type obj_type,
445  		wlan_objmgr_pdev_op_handler handler,
446  		void *arg, uint8_t lock_free_op,
447  		wlan_objmgr_ref_dbgid dbg_id)
448  {
449  	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
450  	qdf_list_t *vdev_list = NULL;
451  	struct wlan_objmgr_vdev *vdev = NULL;
452  	struct wlan_objmgr_vdev *vdev_next = NULL;
453  
454  	/* VDEV list */
455  	vdev_list = &objmgr->wlan_vdev_list;
456  
457  	switch (obj_type) {
458  	case WLAN_VDEV_OP:
459  		/* Iterate through all VDEV object, and invoke handler for each
460  			VDEV object */
461  		vdev = wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
462  								dbg_id);
463  		while (vdev) {
464  			handler(pdev, (void *)vdev, arg);
465  			 /* Get next vdev, it increments ref of next vdev */
466  			vdev_next = wlan_vdev_get_next_active_vdev_of_pdev(
467  					pdev, vdev_list, vdev, dbg_id);
468  			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
469  			vdev = vdev_next;
470  		}
471  		break;
472  	case WLAN_PEER_OP:
473  		vdev = wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
474  								dbg_id);
475  		while (vdev) {
476  			wlan_objmgr_pdev_vdev_iterate_peers(pdev, vdev,	handler,
477  						arg, lock_free_op, dbg_id);
478  			 /* Get next vdev, it increments ref of next vdev */
479  			vdev_next = wlan_vdev_get_next_active_vdev_of_pdev(
480  					pdev, vdev_list, vdev, dbg_id);
481  			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
482  			vdev = vdev_next;
483  		}
484  		break;
485  	default:
486  		break;
487  	}
488  
489  	return QDF_STATUS_SUCCESS;
490  }
491  qdf_export_symbol(wlan_objmgr_pdev_iterate_obj_list);
492  
wlan_objmgr_trigger_pdev_comp_priv_object_creation(struct wlan_objmgr_pdev * pdev,enum wlan_umac_comp_id id)493  QDF_STATUS wlan_objmgr_trigger_pdev_comp_priv_object_creation(
494  		struct wlan_objmgr_pdev *pdev,
495  		enum wlan_umac_comp_id id)
496  {
497  	wlan_objmgr_pdev_create_handler handler;
498  	void *arg;
499  	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
500  
501  	/* Component id is invalid */
502  	if (id >= WLAN_UMAC_MAX_COMPONENTS)
503  		return QDF_STATUS_MAXCOMP_FAIL;
504  
505  	wlan_pdev_obj_lock(pdev);
506  	/* If component object is already created, delete old
507  		component object, then invoke creation */
508  	if (pdev->pdev_comp_priv_obj[id]) {
509  		wlan_pdev_obj_unlock(pdev);
510  		return QDF_STATUS_E_FAILURE;
511  	}
512  	wlan_pdev_obj_unlock(pdev);
513  
514  	/* Invoke registered create handlers */
515  	handler = g_umac_glb_obj->pdev_create_handler[id];
516  	arg = g_umac_glb_obj->pdev_create_handler_arg[id];
517  	if (handler)
518  		pdev->obj_status[id] = handler(pdev, arg);
519  	else
520  		return QDF_STATUS_E_FAILURE;
521  	/* If object status is created, then only handle this object status */
522  	if (pdev->obj_state == WLAN_OBJ_STATE_CREATED) {
523  		/* Derive object status */
524  		obj_status = wlan_objmgr_pdev_object_status(pdev);
525  		/* Move PDEV object state to Partially created state */
526  		if (obj_status == QDF_STATUS_COMP_ASYNC) {
527  			/*TODO atomic */
528  			pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
529  		}
530  	}
531  	return obj_status;
532  }
533  
wlan_objmgr_trigger_pdev_comp_priv_object_deletion(struct wlan_objmgr_pdev * pdev,enum wlan_umac_comp_id id)534  QDF_STATUS wlan_objmgr_trigger_pdev_comp_priv_object_deletion(
535  		struct wlan_objmgr_pdev *pdev,
536  		enum wlan_umac_comp_id id)
537  {
538  	wlan_objmgr_pdev_destroy_handler handler;
539  	void *arg;
540  	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
541  
542  	/* component id is invalid */
543  	if (id >= WLAN_UMAC_MAX_COMPONENTS)
544  		return QDF_STATUS_MAXCOMP_FAIL;
545  
546  	wlan_pdev_obj_lock(pdev);
547  	/* Component object was never created, invalid operation */
548  	if (!pdev->pdev_comp_priv_obj[id]) {
549  		wlan_pdev_obj_unlock(pdev);
550  		return QDF_STATUS_E_FAILURE;
551  	}
552  	wlan_pdev_obj_unlock(pdev);
553  
554  	/* Invoke registered create handlers */
555  	handler = g_umac_glb_obj->pdev_destroy_handler[id];
556  	arg = g_umac_glb_obj->pdev_destroy_handler_arg[id];
557  	if (handler)
558  		pdev->obj_status[id] = handler(pdev, arg);
559  	else
560  		return QDF_STATUS_E_FAILURE;
561  
562  	/* If object status is created, then only handle this object status */
563  	if (pdev->obj_state == WLAN_OBJ_STATE_CREATED) {
564  		obj_status = wlan_objmgr_pdev_object_status(pdev);
565  		/* move object state to DEL progress */
566  		if (obj_status == QDF_STATUS_COMP_ASYNC)
567  			pdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
568  	}
569  	return obj_status;
570  }
571  
wlan_obj_pdev_vdevlist_add_tail(qdf_list_t * obj_list,struct wlan_objmgr_vdev * obj)572  static void wlan_obj_pdev_vdevlist_add_tail(qdf_list_t *obj_list,
573  				struct wlan_objmgr_vdev *obj)
574  {
575  	qdf_list_insert_back(obj_list, &obj->vdev_node);
576  }
577  
wlan_obj_pdev_vdevlist_remove_vdev(qdf_list_t * obj_list,struct wlan_objmgr_vdev * vdev)578  static QDF_STATUS wlan_obj_pdev_vdevlist_remove_vdev(
579  				qdf_list_t *obj_list,
580  				struct wlan_objmgr_vdev *vdev)
581  {
582  	qdf_list_node_t *vdev_node = NULL;
583  
584  	if (!vdev)
585  		return QDF_STATUS_E_FAILURE;
586  	/* get vdev list node element */
587  	vdev_node = &vdev->vdev_node;
588  	/* list is empty, return failure */
589  	if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
590  		return QDF_STATUS_E_FAILURE;
591  
592  	return QDF_STATUS_SUCCESS;
593  }
594  
wlan_objmgr_pdev_vdev_attach(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev)595  QDF_STATUS wlan_objmgr_pdev_vdev_attach(struct wlan_objmgr_pdev *pdev,
596  					struct wlan_objmgr_vdev *vdev)
597  {
598  	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
599  
600  	wlan_pdev_obj_lock(pdev);
601  	/* If Max vdev count exceeds, return failure */
602  	if (objmgr->wlan_vdev_count >= objmgr->max_vdev_count) {
603  		wlan_pdev_obj_unlock(pdev);
604  		return QDF_STATUS_E_FAILURE;
605  	}
606  	/* Add vdev to pdev's vdev list */
607  	wlan_obj_pdev_vdevlist_add_tail(&objmgr->wlan_vdev_list, vdev);
608  	/* Increment pdev ref count to make sure it won't be destroyed before */
609  	wlan_objmgr_pdev_get_ref(pdev, WLAN_OBJMGR_ID);
610  	/* Increment vdev count of pdev */
611  	objmgr->wlan_vdev_count++;
612  	wlan_pdev_obj_unlock(pdev);
613  
614  	return QDF_STATUS_SUCCESS;
615  }
616  
wlan_objmgr_pdev_vdev_detach(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev)617  QDF_STATUS wlan_objmgr_pdev_vdev_detach(struct wlan_objmgr_pdev *pdev,
618  				struct wlan_objmgr_vdev *vdev)
619  {
620  	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
621  
622  	wlan_pdev_obj_lock(pdev);
623  	/* if vdev count is 0, return failure */
624  	if (objmgr->wlan_vdev_count == 0) {
625  		wlan_pdev_obj_unlock(pdev);
626  		return QDF_STATUS_E_FAILURE;
627  	}
628  	/* remove vdev from pdev's vdev list */
629  	wlan_obj_pdev_vdevlist_remove_vdev(&objmgr->wlan_vdev_list, vdev);
630  	/* decrement vdev count */
631  	objmgr->wlan_vdev_count--;
632  	wlan_pdev_obj_unlock(pdev);
633  	/* Decrement pdev ref count since vdev is releasing reference */
634  	wlan_objmgr_pdev_release_ref(pdev, WLAN_OBJMGR_ID);
635  	return QDF_STATUS_SUCCESS;
636  }
637  
wlan_objmgr_pdev_get_comp_private_obj(struct wlan_objmgr_pdev * pdev,enum wlan_umac_comp_id id)638  void *wlan_objmgr_pdev_get_comp_private_obj(
639  		struct wlan_objmgr_pdev *pdev,
640  		enum wlan_umac_comp_id id)
641  {
642  	void *comp_priv_obj;
643  
644  	/* component id is invalid */
645  	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
646  		QDF_BUG(0);
647  		return NULL;
648  	}
649  
650  	if (!pdev) {
651  		QDF_BUG(0);
652  		return NULL;
653  	}
654  
655  	comp_priv_obj = pdev->pdev_comp_priv_obj[id];
656  
657  	return comp_priv_obj;
658  }
659  
660  qdf_export_symbol(wlan_objmgr_pdev_get_comp_private_obj);
661  
wlan_objmgr_pdev_get_ref(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid id)662  void wlan_objmgr_pdev_get_ref(struct wlan_objmgr_pdev *pdev,
663  			      wlan_objmgr_ref_dbgid id)
664  {
665  	if (!pdev) {
666  		obj_mgr_err("pdev obj is NULL");
667  		QDF_ASSERT(0);
668  		return;
669  	}
670  	qdf_atomic_inc(&pdev->pdev_objmgr.ref_cnt);
671  	qdf_atomic_inc(&pdev->pdev_objmgr.ref_id_dbg[id]);
672  }
673  
674  qdf_export_symbol(wlan_objmgr_pdev_get_ref);
675  
wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid id)676  QDF_STATUS wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev *pdev,
677  					wlan_objmgr_ref_dbgid id)
678  {
679  	uint8_t pdev_id;
680  
681  	if (!pdev) {
682  		obj_mgr_err("pdev obj is NULL");
683  		QDF_ASSERT(0);
684  		return QDF_STATUS_E_FAILURE;
685  	}
686  
687  	wlan_pdev_obj_lock(pdev);
688  	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
689  	if (pdev->obj_state != WLAN_OBJ_STATE_CREATED) {
690  		wlan_pdev_obj_unlock(pdev);
691  		if (pdev->pdev_objmgr.print_cnt++ <=
692  				WLAN_OBJMGR_RATELIMIT_THRESH)
693  			obj_mgr_err(
694  			"[Ref id: %d] pdev [%d] is not in Created(st:%d)",
695  					id, pdev_id, pdev->obj_state);
696  		return QDF_STATUS_E_RESOURCES;
697  	}
698  
699  	wlan_objmgr_pdev_get_ref(pdev, id);
700  	wlan_pdev_obj_unlock(pdev);
701  
702  	return QDF_STATUS_SUCCESS;
703  }
704  
705  qdf_export_symbol(wlan_objmgr_pdev_try_get_ref);
706  
wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid id)707  void wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev *pdev,
708  				  wlan_objmgr_ref_dbgid id)
709  {
710  	uint8_t pdev_id;
711  
712  	if (!pdev) {
713  		obj_mgr_err("pdev obj is NULL");
714  		QDF_ASSERT(0);
715  		return;
716  	}
717  
718  	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
719  
720  	if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_id_dbg[id])) {
721  		obj_mgr_err("pdev (id:%d)ref cnt was not taken by %d",
722  			    pdev_id, id);
723  		wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg,
724  					  QDF_TRACE_LEVEL_FATAL);
725  		WLAN_OBJMGR_BUG(0);
726  		return;
727  	}
728  
729  	if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_cnt)) {
730  		obj_mgr_err("pdev ref cnt is 0: pdev-id:%d", pdev_id);
731  		WLAN_OBJMGR_BUG(0);
732  		return;
733  	}
734  
735  	qdf_atomic_dec(&pdev->pdev_objmgr.ref_id_dbg[id]);
736  	/* Decrement ref count, free pdev, if ref count == 0 */
737  	if (qdf_atomic_dec_and_test(&pdev->pdev_objmgr.ref_cnt))
738  		wlan_objmgr_pdev_obj_destroy(pdev);
739  }
740  
741  qdf_export_symbol(wlan_objmgr_pdev_release_ref);
742  
743  #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_pdev_get_first_vdev_debug(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)744  struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev_debug(
745  		struct wlan_objmgr_pdev *pdev,
746  		wlan_objmgr_ref_dbgid dbg_id,
747  		const char *func, int line)
748  {
749  	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
750  	qdf_list_t *vdev_list = NULL;
751  	struct wlan_objmgr_vdev *vdev;
752  	qdf_list_node_t *node = NULL;
753  	qdf_list_node_t *prev_node = NULL;
754  
755  	wlan_pdev_obj_lock(pdev);
756  
757  	/* VDEV list */
758  	vdev_list = &objmgr->wlan_vdev_list;
759  	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
760  		wlan_pdev_obj_unlock(pdev);
761  		return NULL;
762  	}
763  
764  	do {
765  		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
766  					vdev_node);
767  		if (wlan_objmgr_vdev_try_get_ref_debug(vdev,
768  						       dbg_id, func, line) ==
769  						QDF_STATUS_SUCCESS) {
770  			wlan_pdev_obj_unlock(pdev);
771  			return vdev;
772  		}
773  
774  		prev_node = node;
775  	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
776  						QDF_STATUS_SUCCESS);
777  
778  	wlan_pdev_obj_unlock(pdev);
779  
780  	return NULL;
781  }
782  
783  qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev_debug);
784  #else
wlan_objmgr_pdev_get_first_vdev(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id)785  struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev(
786  		struct wlan_objmgr_pdev *pdev,
787  		wlan_objmgr_ref_dbgid dbg_id)
788  {
789  	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
790  	qdf_list_t *vdev_list = NULL;
791  	struct wlan_objmgr_vdev *vdev;
792  	qdf_list_node_t *node = NULL;
793  	qdf_list_node_t *prev_node = NULL;
794  
795  	wlan_pdev_obj_lock(pdev);
796  
797  	/* VDEV list */
798  	vdev_list = &objmgr->wlan_vdev_list;
799  	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
800  		wlan_pdev_obj_unlock(pdev);
801  		return NULL;
802  	}
803  
804  	do {
805  		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
806  					vdev_node);
807  		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
808  						QDF_STATUS_SUCCESS) {
809  			wlan_pdev_obj_unlock(pdev);
810  			return vdev;
811  		}
812  
813  		prev_node = node;
814  	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
815  						QDF_STATUS_SUCCESS);
816  
817  	wlan_pdev_obj_unlock(pdev);
818  
819  	return NULL;
820  }
821  
822  qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev);
823  #endif
824  
wlan_objmgr_pdev_get_roam_vdev(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id)825  struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_roam_vdev(
826  		struct wlan_objmgr_pdev *pdev,
827  		wlan_objmgr_ref_dbgid dbg_id)
828  {
829  	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
830  	qdf_list_t *vdev_list = NULL;
831  	struct wlan_objmgr_vdev *vdev;
832  	qdf_list_node_t *node = NULL;
833  	qdf_list_node_t *prev_node = NULL;
834  
835  	wlan_pdev_obj_lock(pdev);
836  
837  	/* VDEV list */
838  	vdev_list = &objmgr->wlan_vdev_list;
839  	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
840  		wlan_pdev_obj_unlock(pdev);
841  		return NULL;
842  	}
843  
844  	do {
845  		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
846  					vdev_node);
847  		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
848  						QDF_STATUS_SUCCESS) {
849  			if (wlan_cm_is_vdev_roaming(vdev)) {
850  				wlan_pdev_obj_unlock(pdev);
851  				return vdev;
852  			}
853  
854  			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
855  		}
856  
857  		prev_node = node;
858  	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
859  						QDF_STATUS_SUCCESS);
860  
861  	wlan_pdev_obj_unlock(pdev);
862  
863  	return NULL;
864  }
865  
866  #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_get_vdev_by_id_from_pdev_debug(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)867  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_debug(
868  			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
869  			wlan_objmgr_ref_dbgid dbg_id,
870  			const char *func, int line)
871  {
872  	struct wlan_objmgr_vdev *vdev;
873  	struct wlan_objmgr_vdev *vdev_next;
874  	struct wlan_objmgr_pdev_objmgr *objmgr;
875  	qdf_list_t *vdev_list;
876  
877  	wlan_pdev_obj_lock(pdev);
878  
879  	objmgr = &pdev->pdev_objmgr;
880  	vdev_list = &objmgr->wlan_vdev_list;
881  	/* Get first vdev */
882  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
883  	/*
884  	 * Iterate through pdev's vdev list, till vdev id matches with
885  	 * entry of vdev list
886  	 */
887  	while (vdev) {
888  		if (wlan_vdev_get_id(vdev) == vdev_id) {
889  			if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id,
890  							       func, line) !=
891  				QDF_STATUS_SUCCESS)
892  				vdev = NULL;
893  
894  			wlan_pdev_obj_unlock(pdev);
895  			return vdev;
896  		}
897  		/* get next vdev */
898  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
899  		vdev = vdev_next;
900  	}
901  	wlan_pdev_obj_unlock(pdev);
902  	return NULL;
903  }
904  
905  qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_debug);
906  #else
wlan_objmgr_get_vdev_by_id_from_pdev(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,wlan_objmgr_ref_dbgid dbg_id)907  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev(
908  			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
909  			wlan_objmgr_ref_dbgid dbg_id)
910  {
911  	struct wlan_objmgr_vdev *vdev;
912  	struct wlan_objmgr_vdev *vdev_next;
913  	struct wlan_objmgr_pdev_objmgr *objmgr;
914  	qdf_list_t *vdev_list;
915  
916  	wlan_pdev_obj_lock(pdev);
917  
918  	objmgr = &pdev->pdev_objmgr;
919  	vdev_list = &objmgr->wlan_vdev_list;
920  	/* Get first vdev */
921  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
922  	/*
923  	 * Iterate through pdev's vdev list, till vdev id matches with
924  	 * entry of vdev list
925  	 */
926  	while (vdev) {
927  		if (wlan_vdev_get_id(vdev) == vdev_id) {
928  			if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
929  							QDF_STATUS_SUCCESS)
930  				vdev = NULL;
931  
932  			wlan_pdev_obj_unlock(pdev);
933  			return vdev;
934  		}
935  		/* get next vdev */
936  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
937  		vdev = vdev_next;
938  	}
939  	wlan_pdev_obj_unlock(pdev);
940  	return NULL;
941  }
942  
943  qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev);
944  #endif
945  
946  #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)947  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug(
948  			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
949  			wlan_objmgr_ref_dbgid dbg_id,
950  			const char *func, int line)
951  {
952  	struct wlan_objmgr_vdev *vdev;
953  	struct wlan_objmgr_vdev *vdev_next;
954  	struct wlan_objmgr_pdev_objmgr *objmgr;
955  	qdf_list_t *vdev_list;
956  
957  	wlan_pdev_obj_lock(pdev);
958  
959  	objmgr = &pdev->pdev_objmgr;
960  	vdev_list = &objmgr->wlan_vdev_list;
961  	/* Get first vdev */
962  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
963  	/*
964  	 * Iterate through pdev's vdev list, till vdev id matches with
965  	 * entry of vdev list
966  	 */
967  	while (vdev) {
968  		if (wlan_vdev_get_id(vdev) == vdev_id) {
969  			wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id,
970  						       func, line);
971  			wlan_pdev_obj_unlock(pdev);
972  
973  			return vdev;
974  		}
975  		/* get next vdev */
976  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
977  		vdev = vdev_next;
978  	}
979  	wlan_pdev_obj_unlock(pdev);
980  
981  	return NULL;
982  }
983  
984  qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug);
985  #else
wlan_objmgr_get_vdev_by_id_from_pdev_no_state(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,wlan_objmgr_ref_dbgid dbg_id)986  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state(
987  			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
988  			wlan_objmgr_ref_dbgid dbg_id)
989  {
990  	struct wlan_objmgr_vdev *vdev;
991  	struct wlan_objmgr_vdev *vdev_next;
992  	struct wlan_objmgr_pdev_objmgr *objmgr;
993  	qdf_list_t *vdev_list;
994  
995  	wlan_pdev_obj_lock(pdev);
996  
997  	objmgr = &pdev->pdev_objmgr;
998  	vdev_list = &objmgr->wlan_vdev_list;
999  	/* Get first vdev */
1000  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1001  	/*
1002  	 * Iterate through pdev's vdev list, till vdev id matches with
1003  	 * entry of vdev list
1004  	 */
1005  	while (vdev) {
1006  		if (wlan_vdev_get_id(vdev) == vdev_id) {
1007  			wlan_objmgr_vdev_get_ref(vdev, dbg_id);
1008  			wlan_pdev_obj_unlock(pdev);
1009  
1010  			return vdev;
1011  		}
1012  		/* get next vdev */
1013  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1014  		vdev = vdev_next;
1015  	}
1016  	wlan_pdev_obj_unlock(pdev);
1017  
1018  	return NULL;
1019  }
1020  
1021  qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state);
1022  #endif
1023  
1024  #ifdef WLAN_OBJMGR_REF_ID_TRACE
wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug(struct wlan_objmgr_pdev * pdev,const uint8_t * macaddr,wlan_objmgr_ref_dbgid dbg_id,const char * fnc,int ln)1025  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug(
1026  		struct wlan_objmgr_pdev *pdev, const uint8_t *macaddr,
1027  		wlan_objmgr_ref_dbgid dbg_id,
1028  		const char *fnc, int ln)
1029  {
1030  	struct wlan_objmgr_vdev *vdev;
1031  	struct wlan_objmgr_vdev *vdev_next;
1032  	struct wlan_objmgr_pdev_objmgr *objmgr;
1033  	qdf_list_t *vdev_list;
1034  
1035  	wlan_pdev_obj_lock(pdev);
1036  	objmgr = &pdev->pdev_objmgr;
1037  	vdev_list = &objmgr->wlan_vdev_list;
1038  	/* Get first vdev */
1039  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1040  	/*
1041  	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1042  	 * entry of vdev list
1043  	 */
1044  	while (vdev) {
1045  		if (QDF_IS_STATUS_SUCCESS(
1046  		    WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr))) {
1047  			if (QDF_IS_STATUS_SUCCESS(
1048  				wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id,
1049  								   fnc, ln))) {
1050  				wlan_pdev_obj_unlock(pdev);
1051  				return vdev;
1052  			}
1053  		}
1054  		/* get next vdev */
1055  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1056  		vdev = vdev_next;
1057  	}
1058  	wlan_pdev_obj_unlock(pdev);
1059  
1060  	return NULL;
1061  }
1062  #else
wlan_objmgr_get_vdev_by_macaddr_from_pdev(struct wlan_objmgr_pdev * pdev,const uint8_t * macaddr,wlan_objmgr_ref_dbgid dbg_id)1063  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev(
1064  		struct wlan_objmgr_pdev *pdev, const uint8_t *macaddr,
1065  		wlan_objmgr_ref_dbgid dbg_id)
1066  {
1067  	struct wlan_objmgr_vdev *vdev;
1068  	struct wlan_objmgr_vdev *vdev_next;
1069  	struct wlan_objmgr_pdev_objmgr *objmgr;
1070  	qdf_list_t *vdev_list;
1071  
1072  	wlan_pdev_obj_lock(pdev);
1073  	objmgr = &pdev->pdev_objmgr;
1074  	vdev_list = &objmgr->wlan_vdev_list;
1075  	/* Get first vdev */
1076  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1077  	/*
1078  	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1079  	 * entry of vdev list
1080  	 */
1081  	while (vdev) {
1082  		if (QDF_IS_STATUS_SUCCESS(
1083  		    WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr))) {
1084  			if (QDF_IS_STATUS_SUCCESS(
1085  				wlan_objmgr_vdev_try_get_ref(vdev, dbg_id))) {
1086  				wlan_pdev_obj_unlock(pdev);
1087  				return vdev;
1088  			}
1089  		}
1090  		/* get next vdev */
1091  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1092  		vdev = vdev_next;
1093  	}
1094  	wlan_pdev_obj_unlock(pdev);
1095  
1096  	return NULL;
1097  }
1098  #endif
1099  
1100  #ifdef WLAN_OBJMGR_REF_ID_TRACE
1101  struct wlan_objmgr_vdev
wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug(struct wlan_objmgr_pdev * pdev,const uint8_t * macaddr,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1102  	*wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug(
1103  		struct wlan_objmgr_pdev *pdev, const uint8_t *macaddr,
1104  		wlan_objmgr_ref_dbgid dbg_id,
1105  		const char *func, int line)
1106  {
1107  	struct wlan_objmgr_vdev *vdev;
1108  	struct wlan_objmgr_vdev *vdev_next;
1109  	struct wlan_objmgr_pdev_objmgr *objmgr;
1110  	qdf_list_t *vdev_list;
1111  
1112  	wlan_pdev_obj_lock(pdev);
1113  	objmgr = &pdev->pdev_objmgr;
1114  	vdev_list = &objmgr->wlan_vdev_list;
1115  	/* Get first vdev */
1116  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1117  	/*
1118  	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1119  	 * entry of vdev list
1120  	 */
1121  	while (vdev) {
1122  		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
1123  					== QDF_STATUS_SUCCESS) {
1124  			wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id,
1125  						       func, line);
1126  			wlan_pdev_obj_unlock(pdev);
1127  
1128  			return vdev;
1129  		}
1130  		/* get next vdev */
1131  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1132  		vdev = vdev_next;
1133  	}
1134  	wlan_pdev_obj_unlock(pdev);
1135  
1136  	return NULL;
1137  }
1138  #else
wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(struct wlan_objmgr_pdev * pdev,const uint8_t * macaddr,wlan_objmgr_ref_dbgid dbg_id)1139  struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(
1140  		struct wlan_objmgr_pdev *pdev, const uint8_t *macaddr,
1141  		wlan_objmgr_ref_dbgid dbg_id)
1142  {
1143  	struct wlan_objmgr_vdev *vdev;
1144  	struct wlan_objmgr_vdev *vdev_next;
1145  	struct wlan_objmgr_pdev_objmgr *objmgr;
1146  	qdf_list_t *vdev_list;
1147  
1148  	wlan_pdev_obj_lock(pdev);
1149  	objmgr = &pdev->pdev_objmgr;
1150  	vdev_list = &objmgr->wlan_vdev_list;
1151  	/* Get first vdev */
1152  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1153  	/*
1154  	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1155  	 * entry of vdev list
1156  	 */
1157  	while (vdev) {
1158  		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
1159  					== QDF_STATUS_SUCCESS) {
1160  			wlan_objmgr_vdev_get_ref(vdev, dbg_id);
1161  			wlan_pdev_obj_unlock(pdev);
1162  
1163  			return vdev;
1164  		}
1165  		/* get next vdev */
1166  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1167  		vdev = vdev_next;
1168  	}
1169  	wlan_pdev_obj_unlock(pdev);
1170  
1171  	return NULL;
1172  }
1173  #endif
1174  
1175  #ifdef WLAN_OBJMGR_DEBUG
wlan_print_pdev_info(struct wlan_objmgr_pdev * pdev)1176  void wlan_print_pdev_info(struct wlan_objmgr_pdev *pdev)
1177  {
1178  	struct wlan_objmgr_pdev_objmgr *pdev_objmgr;
1179  	struct wlan_objmgr_vdev *vdev;
1180  	struct wlan_objmgr_vdev *vdev_next;
1181  	qdf_list_t *vdev_list;
1182  	uint16_t index = 0;
1183  
1184  	pdev_objmgr = &pdev->pdev_objmgr;
1185  
1186  	obj_mgr_debug("pdev: %pK", pdev);
1187  	obj_mgr_debug("wlan_pdev_id: %d", pdev_objmgr->wlan_pdev_id);
1188  	obj_mgr_debug("wlan_vdev_count: %d", pdev_objmgr->wlan_vdev_count);
1189  	obj_mgr_debug("max_vdev_count: %d", pdev_objmgr->max_vdev_count);
1190  	obj_mgr_debug("wlan_peer_count: %d", pdev_objmgr->wlan_peer_count);
1191  	obj_mgr_debug("max_peer_count: %d", pdev_objmgr->max_peer_count);
1192  	obj_mgr_debug("temp_peer_count: %d", pdev_objmgr->temp_peer_count);
1193  	obj_mgr_debug("wlan_psoc: %pK", pdev_objmgr->wlan_psoc);
1194  	obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&pdev_objmgr->ref_cnt));
1195  
1196  	wlan_pdev_obj_lock(pdev);
1197  	vdev_list = &pdev_objmgr->wlan_vdev_list;
1198  	/* Get first vdev */
1199  	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1200  
1201  	while (vdev) {
1202  		obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev);
1203  		wlan_print_vdev_info(vdev);
1204  		index++;
1205  		/* get next vdev */
1206  		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1207  		vdev = vdev_next;
1208  	}
1209  	wlan_pdev_obj_unlock(pdev);
1210  }
1211  
1212  qdf_export_symbol(wlan_print_pdev_info);
1213  #endif
1214