xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
1 /*
2  * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18  /**
19   * DOC: Public APIs to perform operations on Global objects
20   */
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 <qdf_mem.h>
29 #include <qdf_types.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_objmgr_vdev_obj_i.h"
35 
36 /**
37  ** APIs to Create/Delete Global object APIs
38  */
39 static QDF_STATUS wlan_objmgr_psoc_object_status(
40 			struct wlan_objmgr_psoc *psoc)
41 {
42 	uint8_t id;
43 	QDF_STATUS status = QDF_STATUS_SUCCESS;
44 
45 	wlan_psoc_obj_lock(psoc);
46 	/* Iterate through all components to derive the object status */
47 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
48 		/* If component disabled, Ignore */
49 		if (psoc->obj_status[id] == QDF_STATUS_COMP_DISABLED)
50 			continue;
51 		/* If component operates in Async, status is Partially created,
52 		 * break
53 		 */
54 		else if (psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
55 			if (!psoc->soc_comp_priv_obj[id]) {
56 				status = QDF_STATUS_COMP_ASYNC;
57 				break;
58 			}
59 		/*
60 		 * If component failed to allocate its object, treat it as
61 		 * failure, complete object need to be cleaned up
62 		 */
63 		} else if ((psoc->obj_status[id] == QDF_STATUS_E_NOMEM) ||
64 			(psoc->obj_status[id] == QDF_STATUS_E_FAILURE)) {
65 			status = QDF_STATUS_E_FAILURE;
66 			break;
67 		}
68 	}
69 	wlan_psoc_obj_unlock(psoc);
70 
71 	return status;
72 }
73 
74 static void wlan_objmgr_psoc_peer_list_init(struct wlan_peer_list *peer_list)
75 {
76 	uint8_t i;
77 
78 	qdf_spinlock_create(&peer_list->peer_list_lock);
79 	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
80 		qdf_list_create(&peer_list->peer_hash[i],
81 			WLAN_UMAC_PSOC_MAX_PEERS +
82 			WLAN_MAX_PSOC_TEMP_PEERS);
83 }
84 
85 static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list)
86 {
87 	uint8_t i;
88 
89 	/* deinit the lock */
90 	qdf_spinlock_destroy(&peer_list->peer_list_lock);
91 	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
92 		qdf_list_destroy(&peer_list->peer_hash[i]);
93 }
94 
95 static QDF_STATUS wlan_objmgr_psoc_obj_free(struct wlan_objmgr_psoc *psoc)
96 {
97 	/* Detach PSOC from global object's psoc list  */
98 	if (wlan_objmgr_psoc_object_detach(psoc) == QDF_STATUS_E_FAILURE) {
99 		obj_mgr_err("PSOC object detach failed");
100 		return QDF_STATUS_E_FAILURE;
101 	}
102 	wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list);
103 
104 	qdf_spinlock_destroy(&psoc->psoc_lock);
105 	qdf_mem_free(psoc);
106 
107 	return QDF_STATUS_SUCCESS;
108 }
109 
110 struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version,
111 						WLAN_DEV_TYPE dev_type)
112 {
113 	uint8_t id;
114 	struct wlan_objmgr_psoc *psoc = NULL;
115 	wlan_objmgr_psoc_create_handler handler;
116 	wlan_objmgr_psoc_status_handler stat_handler;
117 	struct wlan_objmgr_psoc_objmgr *objmgr;
118 	QDF_STATUS obj_status;
119 	void *arg;
120 
121 	psoc = qdf_mem_malloc(sizeof(*psoc));
122 	if (!psoc)
123 		return NULL;
124 
125 	psoc->obj_state = WLAN_OBJ_STATE_ALLOCATED;
126 	qdf_spinlock_create(&psoc->psoc_lock);
127 	/* Initialize with default values */
128 	objmgr = &psoc->soc_objmgr;
129 	objmgr->wlan_pdev_count = 0;
130 	objmgr->wlan_vdev_count = 0;
131 	objmgr->max_vdev_count = WLAN_UMAC_PSOC_MAX_VDEVS;
132 	objmgr->wlan_peer_count = 0;
133 	objmgr->temp_peer_count = 0;
134 	objmgr->max_peer_count = WLAN_UMAC_PSOC_MAX_PEERS;
135 	qdf_atomic_init(&objmgr->ref_cnt);
136 	objmgr->print_cnt = 0;
137 	/* set phy version, dev_type in psoc */
138 	wlan_psoc_set_nif_phy_version(psoc, phy_version);
139 	wlan_psoc_set_dev_type(psoc, dev_type);
140 	/* Initialize peer list */
141 	wlan_objmgr_psoc_peer_list_init(&objmgr->peer_list);
142 	wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID);
143 	/* Invoke registered create handlers */
144 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
145 		handler = g_umac_glb_obj->psoc_create_handler[id];
146 		arg = g_umac_glb_obj->psoc_create_handler_arg[id];
147 		if (handler)
148 			psoc->obj_status[id] = handler(psoc, arg);
149 		else
150 			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
151 	}
152 	/* Derive object status */
153 	obj_status = wlan_objmgr_psoc_object_status(psoc);
154 
155 	if (obj_status == QDF_STATUS_SUCCESS) {
156 		/* Object status is SUCCESS, Object is created */
157 		psoc->obj_state = WLAN_OBJ_STATE_CREATED;
158 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
159 			stat_handler = g_umac_glb_obj->psoc_status_handler[id];
160 			arg = g_umac_glb_obj->psoc_status_handler_arg[id];
161 			if (stat_handler)
162 				stat_handler(psoc, arg,
163 					     QDF_STATUS_SUCCESS);
164 		}
165 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
166 		/*
167 		 * Few components operates in Asynchrous communction
168 		 * Object state partially created
169 		 */
170 		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
171 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
172 		/* Component object failed to be created, clean up the object */
173 		obj_mgr_err("PSOC component objects allocation failed");
174 		/* Clean up the psoc */
175 		wlan_objmgr_psoc_obj_delete(psoc);
176 		return NULL;
177 	}
178 
179 	if (wlan_objmgr_psoc_object_attach(psoc) !=
180 				QDF_STATUS_SUCCESS) {
181 		obj_mgr_err("PSOC object attach failed");
182 		wlan_objmgr_psoc_obj_delete(psoc);
183 		return NULL;
184 	}
185 
186 	obj_mgr_info("Created psoc %d", psoc->soc_objmgr.psoc_id);
187 
188 	return psoc;
189 }
190 qdf_export_symbol(wlan_objmgr_psoc_obj_create);
191 
192 static QDF_STATUS wlan_objmgr_psoc_obj_destroy(struct wlan_objmgr_psoc *psoc)
193 {
194 	uint8_t id;
195 	wlan_objmgr_psoc_destroy_handler handler;
196 	QDF_STATUS obj_status;
197 	void *arg;
198 
199 	if (!psoc) {
200 		obj_mgr_err("psoc is NULL");
201 		return QDF_STATUS_E_FAILURE;
202 	}
203 	wlan_objmgr_notify_destroy(psoc, WLAN_PSOC_OP);
204 
205 	wlan_print_psoc_info(psoc);
206 	obj_mgr_info("Physically deleting psoc %d", psoc->soc_objmgr.psoc_id);
207 
208 	if (psoc->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
209 		obj_mgr_err("PSOC object delete is not invoked obj_state:%d",
210 			    psoc->obj_state);
211 		WLAN_OBJMGR_BUG(0);
212 	}
213 
214 	/* Invoke registered create handlers */
215 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
216 		handler = g_umac_glb_obj->psoc_destroy_handler[id];
217 		arg = g_umac_glb_obj->psoc_destroy_handler_arg[id];
218 		if (handler &&
219 		    (psoc->obj_status[id] == QDF_STATUS_SUCCESS ||
220 		     psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC))
221 			psoc->obj_status[id] = handler(psoc, arg);
222 		else
223 			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
224 	}
225 	/* Derive object status */
226 	obj_status = wlan_objmgr_psoc_object_status(psoc);
227 
228 	if (obj_status == QDF_STATUS_E_FAILURE) {
229 		obj_mgr_err("PSOC component object free failed");
230 		/* Ideally should not happen
231 		 * This leads to memleak, BUG_ON to find which component
232 		 * delete notification failed and fix it.
233 		 */
234 		QDF_BUG(0);
235 		return QDF_STATUS_E_FAILURE;
236 	}
237 	/* Deletion is in progress */
238 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
239 		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
240 		return QDF_STATUS_COMP_ASYNC;
241 	}
242 
243 	/* Free psoc object */
244 	return wlan_objmgr_psoc_obj_free(psoc);
245 }
246 
247 
248 QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc)
249 {
250 	uint8_t print_idx;
251 
252 	if (!psoc) {
253 		obj_mgr_err("psoc is NULL");
254 		return QDF_STATUS_E_FAILURE;
255 	}
256 
257 	obj_mgr_info("Logically deleting psoc %d", psoc->soc_objmgr.psoc_id);
258 
259 	print_idx = qdf_get_pidx();
260 	wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg,
261 				  QDF_TRACE_LEVEL_DEBUG);
262 	/*
263 	 * Update PSOC object state to LOGICALLY DELETED
264 	 * It prevents further access of this object
265 	 */
266 	wlan_psoc_obj_lock(psoc);
267 	psoc->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
268 	wlan_psoc_obj_unlock(psoc);
269 	wlan_objmgr_notify_log_delete(psoc, WLAN_PSOC_OP);
270 	wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID);
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 qdf_export_symbol(wlan_objmgr_psoc_obj_delete);
275 
276 QDF_STATUS wlan_objmgr_psoc_component_obj_attach(
277 		struct wlan_objmgr_psoc *psoc,
278 		enum wlan_umac_comp_id id,
279 		void *comp_priv_obj,
280 		QDF_STATUS status)
281 {
282 	wlan_objmgr_psoc_status_handler stat_handler;
283 	void *arg = NULL;
284 	QDF_STATUS obj_status;
285 	uint8_t i;
286 
287 	/* component id is invalid */
288 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
289 		return QDF_STATUS_MAXCOMP_FAIL;
290 
291 	wlan_psoc_obj_lock(psoc);
292 	/* If there is a valid entry, return failure */
293 	if (psoc->soc_comp_priv_obj[id]) {
294 		wlan_psoc_obj_unlock(psoc);
295 		return QDF_STATUS_E_FAILURE;
296 	}
297 	/* Save component's pointer and status */
298 	psoc->soc_comp_priv_obj[id] = comp_priv_obj;
299 	psoc->obj_status[id] = status;
300 
301 	wlan_psoc_obj_unlock(psoc);
302 
303 	if (psoc->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
304 		return QDF_STATUS_SUCCESS;
305 	/* If PSOC object status is partially created means, this API is
306 	 * invoked with differnt context, this block should be executed for
307 	 * async components only
308 	 */
309 	/* Derive status */
310 	obj_status = wlan_objmgr_psoc_object_status(psoc);
311 	/* STATUS_SUCCESS means, object is CREATED */
312 	if (obj_status == QDF_STATUS_SUCCESS)
313 		psoc->obj_state = WLAN_OBJ_STATE_CREATED;
314 	/* update state as CREATION failed, caller has to delete the
315 	 * PSOC object
316 	 */
317 	else if (obj_status == QDF_STATUS_E_FAILURE)
318 		psoc->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
319 
320 	/* Notify components about the CREATION success/failure */
321 	if ((obj_status == QDF_STATUS_SUCCESS) ||
322 	    (obj_status == QDF_STATUS_E_FAILURE)) {
323 		/* nofity object status */
324 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
325 			stat_handler = g_umac_glb_obj->psoc_status_handler[i];
326 			arg = g_umac_glb_obj->psoc_status_handler_arg[i];
327 			if (stat_handler)
328 				stat_handler(psoc, arg, obj_status);
329 		}
330 	}
331 
332 	return QDF_STATUS_SUCCESS;
333 }
334 qdf_export_symbol(wlan_objmgr_psoc_component_obj_attach);
335 
336 QDF_STATUS wlan_objmgr_psoc_component_obj_detach(
337 		struct wlan_objmgr_psoc *psoc,
338 		enum wlan_umac_comp_id id,
339 		void *comp_priv_obj)
340 {
341 	QDF_STATUS obj_status;
342 
343 	/* component id is invalid */
344 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
345 		return QDF_STATUS_MAXCOMP_FAIL;
346 
347 	wlan_psoc_obj_lock(psoc);
348 	/* If there is a valid entry, return failure */
349 	if (psoc->soc_comp_priv_obj[id] != comp_priv_obj) {
350 		psoc->obj_status[id] = QDF_STATUS_E_FAILURE;
351 		wlan_psoc_obj_unlock(psoc);
352 		return QDF_STATUS_E_FAILURE;
353 	}
354 	/* Reset pointers to NULL, update the status*/
355 	psoc->soc_comp_priv_obj[id] = NULL;
356 	psoc->obj_status[id] = QDF_STATUS_SUCCESS;
357 	wlan_psoc_obj_unlock(psoc);
358 
359 	/* If PSOC object status is partially created means, this API is
360 	 * invoked with differnt context, this block should be executed for
361 	 * async components only
362 	 */
363 	if ((psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
364 	    (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
365 		/* Derive object status */
366 		obj_status = wlan_objmgr_psoc_object_status(psoc);
367 		if (obj_status == QDF_STATUS_SUCCESS) {
368 			/* Update the status as Deleted, if full object
369 			 * deletion is in progress
370 			 */
371 			if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
372 				psoc->obj_state = WLAN_OBJ_STATE_DELETED;
373 
374 			/* Move to creation state, since this component
375 			 * deletion alone requested
376 			 */
377 			if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
378 				psoc->obj_state = WLAN_OBJ_STATE_CREATED;
379 		/* Object status is failure */
380 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
381 			/* Update the status as Deletion failed, if full object
382 			 * deletion is in progress
383 			 */
384 			if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
385 				psoc->obj_state =
386 					WLAN_OBJ_STATE_DELETION_FAILED;
387 
388 			/* Move to creation state, since this component
389 			 * deletion alone requested (do not block other
390 			 * components)
391 			 */
392 			if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
393 				psoc->obj_state = WLAN_OBJ_STATE_CREATED;
394 		}
395 
396 		/* Delete psoc object */
397 		if ((obj_status == QDF_STATUS_SUCCESS)  &&
398 		    (psoc->obj_state == WLAN_OBJ_STATE_DELETED)) {
399 			/* Free psoc object */
400 			return wlan_objmgr_psoc_obj_free(psoc);
401 		}
402 	}
403 
404 	return QDF_STATUS_SUCCESS;
405 }
406 qdf_export_symbol(wlan_objmgr_psoc_component_obj_detach);
407 
408 QDF_STATUS wlan_objmgr_iterate_obj_list(
409 		struct wlan_objmgr_psoc *psoc,
410 		enum wlan_objmgr_obj_type obj_type,
411 		wlan_objmgr_op_handler handler,
412 		void *arg, uint8_t lock_free_op,
413 		wlan_objmgr_ref_dbgid dbg_id)
414 {
415 	uint16_t obj_id;
416 	uint8_t i;
417 	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
418 	struct wlan_peer_list *peer_list;
419 	struct wlan_objmgr_pdev *pdev;
420 	struct wlan_objmgr_vdev *vdev;
421 	struct wlan_objmgr_peer *peer;
422 	struct wlan_objmgr_peer *peer_next;
423 	uint16_t max_vdev_cnt;
424 
425 	switch (obj_type) {
426 	case WLAN_PDEV_OP:
427 		/* Iterate through PDEV list, invoke handler for each pdev */
428 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
429 			pdev = wlan_objmgr_get_pdev_by_id(psoc, obj_id, dbg_id);
430 			if (pdev) {
431 				handler(psoc, (void *)pdev, arg);
432 				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
433 			}
434 		}
435 		break;
436 	case WLAN_VDEV_OP:
437 		/* Iterate through VDEV list, invoke handler for each vdev */
438 		max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
439 		for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) {
440 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
441 						obj_id, dbg_id);
442 			if (vdev) {
443 				handler(psoc, vdev, arg);
444 				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
445 			}
446 		}
447 		break;
448 	case WLAN_PEER_OP:
449 		/* Iterate through PEER list, invoke handler for each peer */
450 		peer_list = &objmgr->peer_list;
451 		/* Since peer list has sublist, iterate through sublists */
452 		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
453 			peer = wlan_psoc_peer_list_peek_active_head(peer_list,
454 					i, dbg_id);
455 			while (peer) {
456 				handler(psoc, (void *)peer, arg);
457 				/* Get next peer */
458 				peer_next =
459 					wlan_peer_get_next_active_peer_of_psoc(
460 						peer_list, i, peer, dbg_id);
461 				wlan_objmgr_peer_release_ref(peer,  dbg_id);
462 				peer = peer_next;
463 			}
464 		}
465 		break;
466 	default:
467 		break;
468 	}
469 
470 	return QDF_STATUS_SUCCESS;
471 }
472 qdf_export_symbol(wlan_objmgr_iterate_obj_list);
473 
474 QDF_STATUS wlan_objmgr_iterate_obj_list_all(
475 		struct wlan_objmgr_psoc *psoc,
476 		enum wlan_objmgr_obj_type obj_type,
477 		wlan_objmgr_op_handler handler,
478 		void *arg, uint8_t lock_free_op,
479 		wlan_objmgr_ref_dbgid dbg_id)
480 {
481 	uint16_t obj_id;
482 	uint8_t i;
483 	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
484 	struct wlan_peer_list *peer_list;
485 	struct wlan_objmgr_pdev *pdev;
486 	struct wlan_objmgr_vdev *vdev;
487 	struct wlan_objmgr_peer *peer;
488 	struct wlan_objmgr_peer *peer_next;
489 	uint16_t max_vdev_cnt;
490 
491 	/* If caller requests for lock free opeation, do not acquire,
492 	 * handler will handle the synchronization
493 	 */
494 
495 	switch (obj_type) {
496 	case WLAN_PDEV_OP:
497 		/* Iterate through PDEV list, invoke handler for each pdev */
498 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
499 			pdev = wlan_objmgr_get_pdev_by_id_no_state(psoc,
500 							obj_id, dbg_id);
501 			if (pdev) {
502 				handler(psoc, (void *)pdev, arg);
503 				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
504 			}
505 		}
506 		break;
507 	case WLAN_VDEV_OP:
508 		/* Iterate through VDEV list, invoke handler for each vdev */
509 		max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
510 		for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) {
511 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc_no_state(
512 					psoc, obj_id, dbg_id);
513 			if (vdev) {
514 				handler(psoc, vdev, arg);
515 				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
516 			}
517 		}
518 		break;
519 	case WLAN_PEER_OP:
520 		/* Iterate through PEER list, invoke handler for each peer */
521 		peer_list = &objmgr->peer_list;
522 		/* Since peer list has sublist, iterate through sublists */
523 		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
524 			peer = wlan_psoc_peer_list_peek_head_ref(peer_list, i,
525 									dbg_id);
526 
527 			while (peer) {
528 				handler(psoc, (void *)peer, arg);
529 				/* Get next peer */
530 				peer_next = wlan_peer_get_next_peer_of_psoc_ref(
531 								peer_list, i,
532 								peer, dbg_id);
533 				wlan_objmgr_peer_release_ref(peer, dbg_id);
534 				peer = peer_next;
535 			}
536 		}
537 		break;
538 	default:
539 		break;
540 	}
541 
542 	return QDF_STATUS_SUCCESS;
543 }
544 qdf_export_symbol(wlan_objmgr_iterate_obj_list_all);
545 
546 /**
547  * wlan_objmgr_iterate_obj_list_all_noref() - iterate through all psoc objects
548  *                                            without taking ref
549  * @psoc: PSOC object
550  * @obj_type: PDEV_OP/VDEV_OP/PEER_OP
551  * @handler: the handler will be called for each object of requested type
552  *            the handler should be implemented to perform required operation
553  * @arg:     agruments passed by caller
554  *
555  * API to be used for performing the operations on all PDEV/VDEV/PEER objects
556  * of psoc with lock protected
557  *
558  * Return: SUCCESS/FAILURE
559  */
560 static QDF_STATUS wlan_objmgr_iterate_obj_list_all_noref(
561 		struct wlan_objmgr_psoc *psoc,
562 		enum wlan_objmgr_obj_type obj_type,
563 		wlan_objmgr_op_handler handler,
564 		void *arg)
565 {
566 	uint16_t obj_id;
567 	uint8_t i;
568 	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
569 	struct wlan_peer_list *peer_list;
570 	qdf_list_t *obj_list;
571 	struct wlan_objmgr_pdev *pdev;
572 	struct wlan_objmgr_vdev *vdev;
573 	struct wlan_objmgr_peer *peer;
574 	struct wlan_objmgr_peer *peer_next;
575 	uint16_t max_vdev_cnt;
576 
577 	/* If caller requests for lock free opeation, do not acquire,
578 	 * handler will handle the synchronization
579 	 */
580 	wlan_psoc_obj_lock(psoc);
581 
582 	switch (obj_type) {
583 	case WLAN_PDEV_OP:
584 		/* Iterate through PDEV list, invoke handler for each pdev */
585 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
586 			pdev = objmgr->wlan_pdev_list[obj_id];
587 			if (pdev)
588 				handler(psoc, (void *)pdev, arg);
589 		}
590 		break;
591 	case WLAN_VDEV_OP:
592 		/* Iterate through VDEV list, invoke handler for each vdev */
593 		max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
594 		for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) {
595 			vdev = objmgr->wlan_vdev_list[obj_id];
596 			if (vdev)
597 				handler(psoc, vdev, arg);
598 		}
599 		break;
600 	case WLAN_PEER_OP:
601 		/* Iterate through PEER list, invoke handler for each peer */
602 		peer_list = &objmgr->peer_list;
603 		/* psoc lock should be taken before list lock */
604 		qdf_spin_lock_bh(&peer_list->peer_list_lock);
605 		/* Since peer list has sublist, iterate through sublists */
606 		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
607 			obj_list = &peer_list->peer_hash[i];
608 			peer = wlan_psoc_peer_list_peek_head(obj_list);
609 			while (peer) {
610 				/* Get next peer */
611 				peer_next = wlan_peer_get_next_peer_of_psoc(
612 								obj_list, peer);
613 				handler(psoc, (void *)peer, arg);
614 				peer = peer_next;
615 			}
616 		}
617 		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
618 		break;
619 	default:
620 		break;
621 	}
622 	wlan_psoc_obj_unlock(psoc);
623 
624 	return QDF_STATUS_SUCCESS;
625 }
626 
627 static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc,
628 					 void *obj, void *args)
629 {
630 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
631 
632 	wlan_objmgr_peer_obj_delete(peer);
633 }
634 
635 static void wlan_objmgr_psoc_vdev_delete(struct wlan_objmgr_psoc *psoc,
636 					 void *obj, void *args)
637 {
638 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
639 
640 	wlan_objmgr_vdev_obj_delete(vdev);
641 }
642 
643 static void wlan_objmgr_psoc_pdev_delete(struct wlan_objmgr_psoc *psoc,
644 					 void *obj, void *args)
645 {
646 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
647 
648 	wlan_objmgr_pdev_obj_delete(pdev);
649 }
650 
651 QDF_STATUS wlan_objmgr_free_all_objects_per_psoc(
652 		struct wlan_objmgr_psoc *psoc)
653 {
654 	/* Free all peers */
655 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
656 				     wlan_objmgr_psoc_peer_delete, NULL, 1,
657 				     WLAN_OBJMGR_ID);
658 	/* Free all vdevs */
659 	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
660 				     wlan_objmgr_psoc_vdev_delete, NULL, 1,
661 				     WLAN_OBJMGR_ID);
662 	/* Free all PDEVs */
663 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
664 				     wlan_objmgr_psoc_pdev_delete, NULL, 1,
665 				     WLAN_OBJMGR_ID);
666 
667 	return QDF_STATUS_SUCCESS;
668 }
669 
670 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_creation(
671 		struct wlan_objmgr_psoc *psoc,
672 		enum wlan_umac_comp_id id)
673 {
674 	wlan_objmgr_psoc_create_handler handler;
675 	void *arg;
676 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
677 
678 	/* Component id is invalid */
679 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
680 		return QDF_STATUS_MAXCOMP_FAIL;
681 
682 	wlan_psoc_obj_lock(psoc);
683 	/* If component object is already created, delete old
684 	 * component object, then invoke creation
685 	 */
686 	if (psoc->soc_comp_priv_obj[id]) {
687 		wlan_psoc_obj_unlock(psoc);
688 		return QDF_STATUS_E_FAILURE;
689 	}
690 	wlan_psoc_obj_unlock(psoc);
691 	/* Invoke registered create handlers */
692 	handler = g_umac_glb_obj->psoc_create_handler[id];
693 	arg = g_umac_glb_obj->psoc_create_handler_arg[id];
694 	if (handler)
695 		psoc->obj_status[id] = handler(psoc, arg);
696 	else
697 		return QDF_STATUS_E_FAILURE;
698 
699 	/* If object status is created, then only handle this object status */
700 	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
701 		/* Derive object status */
702 		obj_status = wlan_objmgr_psoc_object_status(psoc);
703 		/* Move PSOC object state to Partially created state */
704 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
705 			/*TODO atomic */
706 			psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
707 		}
708 	}
709 
710 	return obj_status;
711 }
712 
713 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_deletion(
714 		struct wlan_objmgr_psoc *psoc,
715 		enum wlan_umac_comp_id id)
716 {
717 	wlan_objmgr_psoc_destroy_handler handler;
718 	void *arg;
719 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
720 
721 	/* component id is invalid */
722 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
723 		return QDF_STATUS_MAXCOMP_FAIL;
724 
725 	wlan_psoc_obj_lock(psoc);
726 	/* Component object was never created, invalid operation */
727 	if (!psoc->soc_comp_priv_obj[id]) {
728 		wlan_psoc_obj_unlock(psoc);
729 		return QDF_STATUS_E_FAILURE;
730 	}
731 	wlan_psoc_obj_unlock(psoc);
732 	/* Invoke registered create handlers */
733 	handler = g_umac_glb_obj->psoc_destroy_handler[id];
734 	arg = g_umac_glb_obj->psoc_destroy_handler_arg[id];
735 	if (handler)
736 		psoc->obj_status[id] = handler(psoc, arg);
737 	else
738 		return QDF_STATUS_E_FAILURE;
739 
740 	/* If object status is created, then only handle this object status */
741 	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
742 		obj_status = wlan_objmgr_psoc_object_status(psoc);
743 			/* move object state to DEL progress */
744 		if (obj_status == QDF_STATUS_COMP_ASYNC)
745 			psoc->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
746 	}
747 
748 	return obj_status;
749 }
750 
751 /* Util APIs */
752 
753 QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc,
754 					struct wlan_objmgr_pdev *pdev)
755 {
756 	struct wlan_objmgr_psoc_objmgr *objmgr;
757 	uint8_t id = 0;
758 	QDF_STATUS status;
759 
760 	wlan_psoc_obj_lock(psoc);
761 	objmgr = &psoc->soc_objmgr;
762 	/*
763 	 * Derive pdev id from pdev map
764 	 * First free pdev id is assigned
765 	 */
766 	while ((id < WLAN_UMAC_MAX_PDEVS) &&
767 			(objmgr->wlan_pdev_id_map & (1<<id)))
768 		id++;
769 
770 	if (id == WLAN_UMAC_MAX_PDEVS) {
771 		status = QDF_STATUS_E_FAILURE;
772 	} else {
773 		/* Update the map for reserving the id */
774 		objmgr->wlan_pdev_id_map |= (1<<id);
775 		/* store pdev in pdev list */
776 		objmgr->wlan_pdev_list[id] = pdev;
777 		/* Increment pdev count */
778 		objmgr->wlan_pdev_count++;
779 		/* save pdev id */
780 		pdev->pdev_objmgr.wlan_pdev_id = id;
781 		status = QDF_STATUS_SUCCESS;
782 		/* Inrement psoc ref count to block its free before pdev */
783 		wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID);
784 	}
785 	wlan_psoc_obj_unlock(psoc);
786 
787 	return status;
788 }
789 
790 QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc,
791 						struct wlan_objmgr_pdev *pdev)
792 {
793 	struct wlan_objmgr_psoc_objmgr *objmgr;
794 	uint8_t id;
795 
796 	id = pdev->pdev_objmgr.wlan_pdev_id;
797 	/* If id is invalid, return */
798 	if (id >= WLAN_UMAC_MAX_PDEVS)
799 		return QDF_STATUS_E_FAILURE;
800 
801 	wlan_psoc_obj_lock(psoc);
802 	objmgr = &psoc->soc_objmgr;
803 	/* Free pdev id slot */
804 	objmgr->wlan_pdev_id_map &= ~(1<<id);
805 	objmgr->wlan_pdev_list[id] = NULL;
806 	objmgr->wlan_pdev_count--;
807 	pdev->pdev_objmgr.wlan_pdev_id = 0xff;
808 	wlan_psoc_obj_unlock(psoc);
809 	/* Release ref count of psoc */
810 	wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID);
811 
812 	return QDF_STATUS_SUCCESS;
813 }
814 
815 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id(
816 		struct wlan_objmgr_psoc *psoc, uint8_t id,
817 		wlan_objmgr_ref_dbgid dbg_id)
818 {
819 	struct wlan_objmgr_psoc_objmgr *objmgr;
820 	struct wlan_objmgr_pdev *pdev = NULL;
821 
822 	/* If id is invalid, return */
823 	if (id >= WLAN_UMAC_MAX_PDEVS)
824 		return NULL;
825 
826 	wlan_psoc_obj_lock(psoc);
827 	objmgr = &psoc->soc_objmgr;
828 	/* get pdev from pdev list */
829 	pdev = objmgr->wlan_pdev_list[id];
830 	/* Do not return object, if it is not CREATED state */
831 	if (pdev) {
832 		if (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) !=
833 							QDF_STATUS_SUCCESS)
834 			pdev = NULL;
835 	}
836 
837 	wlan_psoc_obj_unlock(psoc);
838 
839 	return pdev;
840 }
841 qdf_export_symbol(wlan_objmgr_get_pdev_by_id);
842 
843 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id_no_state(
844 		struct wlan_objmgr_psoc *psoc, uint8_t id,
845 		wlan_objmgr_ref_dbgid dbg_id)
846 {
847 	struct wlan_objmgr_psoc_objmgr *objmgr;
848 	struct wlan_objmgr_pdev *pdev = NULL;
849 
850 	/* If id is invalid, return */
851 	if (id >= WLAN_UMAC_MAX_PDEVS)
852 		return NULL;
853 
854 	wlan_psoc_obj_lock(psoc);
855 	objmgr = &psoc->soc_objmgr;
856 	/* get pdev from pdev list */
857 	pdev = objmgr->wlan_pdev_list[id];
858 	/* Do not return object, if it is not CREATED state */
859 	if (pdev)
860 		wlan_objmgr_pdev_get_ref(pdev, dbg_id);
861 
862 	wlan_psoc_obj_unlock(psoc);
863 
864 	return pdev;
865 }
866 QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc,
867 					struct wlan_objmgr_vdev *vdev)
868 {
869 	struct wlan_objmgr_psoc_objmgr *objmgr;
870 	uint8_t id = 0;
871 	uint8_t map_index = 0;
872 	uint8_t map_entry_size = 32;
873 	uint8_t adjust_ix = 0;
874 	QDF_STATUS status;
875 
876 	wlan_psoc_obj_lock(psoc);
877 	objmgr = &psoc->soc_objmgr;
878 	/* Find first free vdev id */
879 	while ((id < objmgr->max_vdev_count) &&
880 		(objmgr->wlan_vdev_id_map[map_index] & (1<<(id - adjust_ix)))) {
881 		id++;
882 		/*
883 		 * The map is two DWORDS(32 bits), so, map_index
884 		 * adjust_ix derived based on the id value
885 		 */
886 		if (id == ((map_index + 1) * map_entry_size)) {
887 			map_index++;
888 			adjust_ix = map_index * map_entry_size;
889 		}
890 	}
891 	/* If no free slot, return failure */
892 	if (id == objmgr->max_vdev_count) {
893 		status = QDF_STATUS_E_FAILURE;
894 	} else {
895 		/* set free vdev id index */
896 		objmgr->wlan_vdev_id_map[map_index] |= (1<<(id-adjust_ix));
897 		/* store vdev pointer in vdev list */
898 		objmgr->wlan_vdev_list[id] = vdev;
899 		/* increment vdev counter */
900 		objmgr->wlan_vdev_count++;
901 		/* save vdev id */
902 		vdev->vdev_objmgr.vdev_id = id;
903 		status = QDF_STATUS_SUCCESS;
904 	}
905 	wlan_psoc_obj_unlock(psoc);
906 
907 	return status;
908 }
909 
910 QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc,
911 					struct wlan_objmgr_vdev *vdev)
912 {
913 	struct wlan_objmgr_psoc_objmgr *objmgr;
914 	uint8_t id = 0;
915 	uint8_t map_index = 0;
916 	uint8_t map_entry_size = 32;
917 	uint8_t adjust_ix = 0;
918 
919 	id = vdev->vdev_objmgr.vdev_id;
920 	/* Invalid vdev id */
921 	if (id >= wlan_psoc_get_max_vdev_count(psoc))
922 		return QDF_STATUS_E_FAILURE;
923 	/*
924 	 * Derive map_index and adjust_ix to find actual DWORD
925 	 * the id map is present
926 	 */
927 	while ((id - adjust_ix) >= map_entry_size) {
928 		map_index++;
929 		adjust_ix = map_index * map_entry_size;
930 	}
931 	wlan_psoc_obj_lock(psoc);
932 	objmgr = &psoc->soc_objmgr;
933 	/* unset bit, to free the slot */
934 	objmgr->wlan_vdev_id_map[map_index] &= ~(1<<(id-adjust_ix));
935 	/* reset VDEV pointer to NULL in VDEV list array */
936 	objmgr->wlan_vdev_list[id] = NULL;
937 	/* decrement vdev count */
938 	objmgr->wlan_vdev_count--;
939 	vdev->vdev_objmgr.vdev_id = 0xff;
940 	wlan_psoc_obj_unlock(psoc);
941 
942 	return QDF_STATUS_SUCCESS;
943 }
944 
945 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc(
946 			struct wlan_objmgr_psoc *psoc,
947 			enum QDF_OPMODE opmode,
948 			wlan_objmgr_ref_dbgid dbg_id)
949 {
950 	struct wlan_objmgr_vdev *vdev = NULL;
951 	int vdev_cnt = 0;
952 	uint16_t max_vdev_cnt;
953 
954 	/* if PSOC is NULL, return */
955 	if (!psoc)
956 		return NULL;
957 
958 	wlan_psoc_obj_lock(psoc);
959 
960 	max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
961 	/* retrieve vdev pointer from vdev list */
962 	while (vdev_cnt < max_vdev_cnt) {
963 		vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt];
964 		vdev_cnt++;
965 		if (!vdev)
966 			continue;
967 		wlan_vdev_obj_lock(vdev);
968 		if (vdev->vdev_mlme.vdev_opmode == opmode) {
969 			wlan_vdev_obj_unlock(vdev);
970 			if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
971 							QDF_STATUS_SUCCESS) {
972 				vdev = NULL;
973 				continue;
974 			}
975 			break;
976 		}
977 		wlan_vdev_obj_unlock(vdev);
978 	}
979 	wlan_psoc_obj_unlock(psoc);
980 
981 	return vdev;
982 }
983 
984 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc(
985 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
986 			wlan_objmgr_ref_dbgid dbg_id)
987 {
988 	struct wlan_objmgr_vdev *vdev;
989 
990 	/* if PSOC is NULL, return */
991 	if (!psoc)
992 		return NULL;
993 	/* vdev id is invalid */
994 	if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc))
995 		return NULL;
996 
997 	wlan_psoc_obj_lock(psoc);
998 	/* retrieve vdev pointer from vdev list */
999 	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
1000 	if (vdev) {
1001 		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
1002 							QDF_STATUS_SUCCESS)
1003 			vdev = NULL;
1004 	}
1005 	wlan_psoc_obj_unlock(psoc);
1006 
1007 	return vdev;
1008 }
1009 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc);
1010 
1011 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state(
1012 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
1013 			wlan_objmgr_ref_dbgid dbg_id)
1014 {
1015 	struct wlan_objmgr_vdev *vdev;
1016 
1017 	/* if PSOC is NULL, return */
1018 	if (!psoc)
1019 		return NULL;
1020 	/* vdev id is invalid */
1021 	if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc))
1022 		return NULL;
1023 
1024 	wlan_psoc_obj_lock(psoc);
1025 	/* retrieve vdev pointer from vdev list */
1026 	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
1027 	if (vdev)
1028 		wlan_objmgr_vdev_get_ref(vdev, dbg_id);
1029 
1030 	wlan_psoc_obj_unlock(psoc);
1031 
1032 	return vdev;
1033 }
1034 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state);
1035 
1036 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc(
1037 		struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1038 		uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1039 {
1040 	struct wlan_objmgr_vdev *vdev;
1041 	struct wlan_objmgr_pdev *pdev;
1042 
1043 	/* if PSOC is NULL, return */
1044 	if (!psoc)
1045 		return NULL;
1046 
1047 	if (!macaddr)
1048 		return NULL;
1049 
1050 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
1051 	if (!pdev) {
1052 		obj_mgr_err("pdev is null");
1053 		return NULL;
1054 	}
1055 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, macaddr, dbg_id);
1056 	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
1057 
1058 	return vdev;
1059 }
1060 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc);
1061 
1062 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state(
1063 		struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1064 		uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1065 {
1066 	struct wlan_objmgr_vdev *vdev;
1067 	struct wlan_objmgr_pdev *pdev;
1068 
1069 	/* if PSOC is NULL, return */
1070 	if (!psoc)
1071 		return NULL;
1072 
1073 	if (!macaddr)
1074 		return NULL;
1075 
1076 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
1077 	if (!pdev) {
1078 		obj_mgr_err("pdev is null");
1079 		return NULL;
1080 	}
1081 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(pdev, macaddr, dbg_id);
1082 	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
1083 
1084 	return vdev;
1085 }
1086 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state);
1087 
1088 static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list,
1089 				struct wlan_objmgr_peer *obj)
1090 {
1091 	qdf_list_insert_back(obj_list, &obj->psoc_peer);
1092 }
1093 
1094 static QDF_STATUS wlan_obj_psoc_peerlist_remove_peer(
1095 				qdf_list_t *obj_list,
1096 				struct wlan_objmgr_peer *peer)
1097 {
1098 	qdf_list_node_t *psoc_node = NULL;
1099 
1100 	if (!peer)
1101 		return QDF_STATUS_E_FAILURE;
1102 	/* get vdev list node element */
1103 	psoc_node = &peer->psoc_peer;
1104 	/* list is empty, return failure */
1105 	if (qdf_list_remove_node(obj_list, psoc_node) != QDF_STATUS_SUCCESS)
1106 		return QDF_STATUS_E_FAILURE;
1107 
1108 	return QDF_STATUS_SUCCESS;
1109 }
1110 
1111 static QDF_STATUS wlan_peer_bssid_match(struct wlan_objmgr_peer *peer,
1112 				     uint8_t *bssid)
1113 {
1114 	struct wlan_objmgr_vdev *vdev = wlan_peer_get_vdev(peer);
1115 	uint8_t *peer_bssid = wlan_vdev_mlme_get_macaddr(vdev);
1116 
1117 	if (WLAN_ADDR_EQ(peer_bssid, bssid) == QDF_STATUS_SUCCESS)
1118 		return QDF_STATUS_SUCCESS;
1119 	else
1120 		return QDF_STATUS_E_FAILURE;
1121 }
1122 
1123 /**
1124  * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer
1125  * from psoc peer list
1126  * @psoc: PSOC object
1127  * @macaddr: MAC address
1128  *
1129  * API to finds peer object pointer of logically deleted peer
1130  *
1131  * Return: peer pointer
1132  *         NULL on FAILURE
1133  */
1134 static struct wlan_objmgr_peer *
1135 			wlan_obj_psoc_peerlist_get_peer_logically_deleted(
1136 				qdf_list_t *obj_list, uint8_t *macaddr,
1137 				wlan_objmgr_ref_dbgid dbg_id)
1138 {
1139 	struct wlan_objmgr_peer *peer;
1140 	struct wlan_objmgr_peer *peer_temp;
1141 
1142 	/* Iterate through hash list to get the peer */
1143 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1144 	while (peer) {
1145 		/* For peer, macaddr is key */
1146 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1147 			== QDF_STATUS_SUCCESS) {
1148 			/* Return peer in logically deleted state */
1149 			if (peer->obj_state ==
1150 					WLAN_OBJ_STATE_LOGICALLY_DELETED) {
1151 				wlan_objmgr_peer_get_ref(peer, dbg_id);
1152 
1153 				return peer;
1154 			}
1155 
1156 		}
1157 		/* Move to next peer */
1158 		peer_temp = peer;
1159 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1160 	}
1161 
1162 	/* Not found, return NULL */
1163 	return NULL;
1164 }
1165 
1166 /**
1167  * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list
1168  * @psoc: PSOC object
1169  * @macaddr: MAC address
1170  *
1171  * API to finds peer object pointer by MAC addr from hash list
1172  *
1173  * Return: peer pointer
1174  *         NULL on FAILURE
1175  */
1176 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer(
1177 		qdf_list_t *obj_list, uint8_t *macaddr,
1178 		wlan_objmgr_ref_dbgid dbg_id)
1179 {
1180 	struct wlan_objmgr_peer *peer;
1181 	struct wlan_objmgr_peer *peer_temp;
1182 
1183 	/* Iterate through hash list to get the peer */
1184 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1185 	while (peer) {
1186 		/* For peer, macaddr is key */
1187 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1188 				== QDF_STATUS_SUCCESS) {
1189 			if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
1190 					QDF_STATUS_SUCCESS) {
1191 				return peer;
1192 			}
1193 		}
1194 		/* Move to next peer */
1195 		peer_temp = peer;
1196 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1197 	}
1198 
1199 	/* Not found, return NULL */
1200 	return NULL;
1201 }
1202 
1203 /**
1204  * wlan_obj_psoc_peerlist_get_peer_by_pdev_id() - get peer from psoc peer list
1205  * @psoc: PSOC object
1206  * @macaddr: MAC address
1207  * #pdev_id: Pdev id
1208  *
1209  * API to finds peer object pointer by MAC addr and pdev id from hash list
1210  *
1211  * Return: peer pointer
1212  *         NULL on FAILURE
1213  */
1214 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id(
1215 				qdf_list_t *obj_list, uint8_t *macaddr,
1216 				uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id)
1217 {
1218 	struct wlan_objmgr_peer *peer;
1219 	struct wlan_objmgr_peer *peer_temp;
1220 
1221 	/* Iterate through hash list to get the peer */
1222 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1223 	while (peer) {
1224 		/* For peer, macaddr is key */
1225 		if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1226 			== QDF_STATUS_SUCCESS) &&
1227 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1228 			if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
1229 							QDF_STATUS_SUCCESS) {
1230 				return peer;
1231 			}
1232 		}
1233 		/* Move to next peer */
1234 		peer_temp = peer;
1235 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1236 	}
1237 
1238 	/* Not found, return NULL */
1239 	return NULL;
1240 }
1241 
1242 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state(
1243 				qdf_list_t *obj_list, uint8_t *macaddr,
1244 				uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id)
1245 {
1246 	struct wlan_objmgr_peer *peer;
1247 	struct wlan_objmgr_peer *peer_temp;
1248 
1249 	/* Iterate through hash list to get the peer */
1250 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1251 	while (peer) {
1252 		/* For peer, macaddr and pdev_id is key */
1253 		if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1254 			== QDF_STATUS_SUCCESS) &&
1255 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1256 			wlan_objmgr_peer_get_ref(peer, dbg_id);
1257 
1258 			return peer;
1259 		}
1260 		/* Move to next peer */
1261 		peer_temp = peer;
1262 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1263 	}
1264 
1265 	/* Not found, return NULL */
1266 	return NULL;
1267 }
1268 
1269 /**
1270  * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - get peer
1271  *                                           from psoc peer list using
1272  *                                           mac and vdev self mac
1273  * @obj_list: peer object list
1274  * @macaddr: MAC address
1275  * @bssid: BSSID address
1276  * @dbg_id: id of the caller
1277  *
1278  * API to finds peer object pointer by MAC addr and BSSID from
1279  * peer hash list for a node which is in logically deleted state,
1280  * bssid check is done on matching peer
1281  *
1282  * Caller to free the list allocated in this function
1283  *
1284  * Return: list of peer pointers
1285  *         NULL on FAILURE
1286  */
1287 static qdf_list_t
1288 	*wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid(
1289 				qdf_list_t *obj_list, uint8_t *macaddr,
1290 				uint8_t *bssid, uint8_t pdev_id,
1291 				wlan_objmgr_ref_dbgid dbg_id)
1292 {
1293 	struct wlan_objmgr_peer *peer;
1294 	struct wlan_objmgr_peer *peer_temp;
1295 	struct wlan_logically_del_peer *peer_list = NULL;
1296 	qdf_list_t *logical_del_peer_list = NULL;
1297 	bool lock_released = false;
1298 
1299 	logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list));
1300 	if (!logical_del_peer_list)
1301 		return NULL;
1302 
1303 	qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS);
1304 
1305 	/* Iterate through hash list to get the peer */
1306 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1307 	while (peer) {
1308 		wlan_peer_obj_lock(peer);
1309 		/* For peer, macaddr and pdev id are keys */
1310 		if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1311 			== QDF_STATUS_SUCCESS) &&
1312 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1313 			/*
1314 			 *  if BSSID not NULL,
1315 			 *  then match is requested by caller, check BSSID
1316 			 *  (vdev mac == bssid) --  return peer
1317 			 *  (vdev mac != bssid) --  perform next iteration
1318 			 */
1319 			if ((!bssid) ||
1320 				(wlan_peer_bssid_match(peer, bssid) ==
1321 				 QDF_STATUS_SUCCESS)) {
1322 				/* Return peer in logically deleted state */
1323 				if ((peer->obj_state ==
1324 					WLAN_OBJ_STATE_LOGICALLY_DELETED) &&
1325 				     qdf_atomic_read(
1326 						&peer->peer_objmgr.ref_cnt)) {
1327 
1328 					wlan_objmgr_peer_get_ref(peer, dbg_id);
1329 					wlan_peer_obj_unlock(peer);
1330 					lock_released = true;
1331 
1332 					peer_list =
1333 					qdf_mem_malloc(
1334 					sizeof(struct wlan_logically_del_peer));
1335 					if (!peer_list) {
1336 						wlan_objmgr_peer_release_ref(peer, dbg_id);
1337 						/* Lock is already released */
1338 						WLAN_OBJMGR_BUG(0);
1339 						break;
1340 					}
1341 
1342 					peer_list->peer = peer;
1343 
1344 					qdf_list_insert_front(
1345 						logical_del_peer_list,
1346 							&peer_list->list);
1347 				}
1348 			}
1349 		}
1350 
1351 		if (!lock_released)
1352 			wlan_peer_obj_unlock(peer);
1353 
1354 		/* Move to next peer */
1355 		peer_temp = peer;
1356 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1357 		lock_released = false;
1358 	}
1359 
1360 	/* Not found, return NULL */
1361 	if (qdf_list_empty(logical_del_peer_list)) {
1362 		qdf_mem_free(logical_del_peer_list);
1363 		return NULL;
1364 	} else {
1365 		return logical_del_peer_list;
1366 	}
1367 
1368 }
1369 
1370 /**
1371  * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer from psoc peer
1372  *                                                    list using mac and vdev
1373  *                                                    self mac
1374  * @psoc: PSOC object
1375  * @macaddr: MAC address
1376  * @bssid: BSSID address
1377  *
1378  * API to finds peer object pointer by MAC addr and BSSID from
1379  * peer hash list, bssid check is done on matching peer
1380  *
1381  * Return: peer pointer
1382  *         NULL on FAILURE
1383  */
1384 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid(
1385 					qdf_list_t *obj_list, uint8_t *macaddr,
1386 					uint8_t *bssid, uint8_t pdev_id,
1387 					wlan_objmgr_ref_dbgid dbg_id)
1388 {
1389 	struct wlan_objmgr_peer *peer;
1390 	struct wlan_objmgr_peer *peer_temp;
1391 
1392 	/* Iterate through hash list to get the peer */
1393 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1394 	while (peer) {
1395 		/* For peer, macaddr is key */
1396 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1397 			== QDF_STATUS_SUCCESS) {
1398 			/*
1399 			 *  BSSID match is requested by caller, check BSSID
1400 			 *  (vdev mac == bssid) --  return peer
1401 			 *  (vdev mac != bssid) --  perform next iteration
1402 			 */
1403 			if ((wlan_peer_bssid_match(peer, bssid) ==
1404 				QDF_STATUS_SUCCESS) &&
1405 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1406 				if (wlan_objmgr_peer_try_get_ref(peer, dbg_id)
1407 					== QDF_STATUS_SUCCESS) {
1408 					return peer;
1409 				}
1410 			}
1411 		}
1412 		/* Move to next peer */
1413 		peer_temp = peer;
1414 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1415 	}
1416 	/* Not found, return NULL */
1417 	return NULL;
1418 }
1419 
1420 static struct wlan_objmgr_peer
1421 		*wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state(
1422 					qdf_list_t *obj_list, uint8_t *macaddr,
1423 					uint8_t *bssid,
1424 					uint8_t pdev_id,
1425 					wlan_objmgr_ref_dbgid dbg_id)
1426 {
1427 	struct wlan_objmgr_peer *peer;
1428 	struct wlan_objmgr_peer *peer_temp;
1429 
1430 	/* Iterate through hash list to get the peer */
1431 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1432 	while (peer) {
1433 		/* For peer, macaddr is key */
1434 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1435 			== QDF_STATUS_SUCCESS) {
1436 			/*
1437 			 *  BSSID match is requested by caller, check BSSID
1438 			 *  (vdev mac == bssid) --  return peer
1439 			 *  (vdev mac != bssid) --  perform next iteration
1440 			 */
1441 			if ((wlan_peer_bssid_match(peer, bssid) ==
1442 				QDF_STATUS_SUCCESS) &&
1443 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1444 				wlan_objmgr_peer_get_ref(peer, dbg_id);
1445 
1446 				return peer;
1447 			}
1448 		}
1449 		/* Move to next peer */
1450 		peer_temp = peer;
1451 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1452 	}
1453 
1454 	/* Not found, return NULL */
1455 	return NULL;
1456 }
1457 
1458 QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc,
1459 					 struct wlan_objmgr_peer *peer)
1460 {
1461 	struct wlan_objmgr_psoc_objmgr *objmgr;
1462 	uint8_t hash_index;
1463 	struct wlan_peer_list *peer_list;
1464 
1465 	wlan_psoc_obj_lock(psoc);
1466 	objmgr = &psoc->soc_objmgr;
1467 	/* Max temporary peer limit is reached, return failure */
1468 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) {
1469 		if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) {
1470 			wlan_psoc_obj_unlock(psoc);
1471 			return QDF_STATUS_E_FAILURE;
1472 		}
1473 	} else {
1474 		/* Max peer limit is reached, return failure */
1475 		if (objmgr->wlan_peer_count
1476 			>= wlan_psoc_get_max_peer_count(psoc)) {
1477 			wlan_psoc_obj_unlock(psoc);
1478 			return QDF_STATUS_E_FAILURE;
1479 		}
1480 	}
1481 
1482 	/* Derive hash index from mac address */
1483 	hash_index = WLAN_PEER_HASH(peer->macaddr);
1484 	peer_list = &objmgr->peer_list;
1485 	/* psoc lock should be taken before list lock */
1486 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1487 	/* add peer to hash peer list */
1488 	wlan_obj_psoc_peerlist_add_tail(
1489 			&peer_list->peer_hash[hash_index],
1490 							peer);
1491 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1492 	/* Increment peer count */
1493 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
1494 		objmgr->temp_peer_count++;
1495 	else
1496 		objmgr->wlan_peer_count++;
1497 
1498 	wlan_psoc_obj_unlock(psoc);
1499 
1500 	return QDF_STATUS_SUCCESS;
1501 }
1502 
1503 QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc,
1504 						struct wlan_objmgr_peer *peer)
1505 {
1506 	struct wlan_objmgr_psoc_objmgr *objmgr;
1507 	uint8_t hash_index;
1508 	struct wlan_peer_list *peer_list;
1509 
1510 	wlan_psoc_obj_lock(psoc);
1511 	objmgr = &psoc->soc_objmgr;
1512 	/* if list is empty, return */
1513 	if (objmgr->wlan_peer_count == 0) {
1514 		wlan_psoc_obj_unlock(psoc);
1515 		return QDF_STATUS_E_FAILURE;
1516 	}
1517 	/* Get hash index, to locate the actual peer list */
1518 	hash_index = WLAN_PEER_HASH(peer->macaddr);
1519 	peer_list = &objmgr->peer_list;
1520 	/* psoc lock should be taken before list lock */
1521 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1522 	/* removes the peer from peer_list */
1523 	if (wlan_obj_psoc_peerlist_remove_peer(
1524 				&peer_list->peer_hash[hash_index],
1525 						peer) ==
1526 				QDF_STATUS_E_FAILURE) {
1527 		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1528 		wlan_psoc_obj_unlock(psoc);
1529 		obj_mgr_err("Failed to detach peer");
1530 		return QDF_STATUS_E_FAILURE;
1531 	}
1532 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1533 	/* Decrement peer count */
1534 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
1535 		objmgr->temp_peer_count--;
1536 	else
1537 		objmgr->wlan_peer_count--;
1538 	wlan_psoc_obj_unlock(psoc);
1539 
1540 	return QDF_STATUS_SUCCESS;
1541 }
1542 
1543 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted(
1544 			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
1545 			wlan_objmgr_ref_dbgid dbg_id)
1546 {
1547 	struct wlan_objmgr_psoc_objmgr *objmgr;
1548 	uint8_t hash_index;
1549 	struct wlan_objmgr_peer *peer = NULL;
1550 	struct wlan_peer_list *peer_list;
1551 
1552 	/* psoc lock should be taken before peer list lock */
1553 	wlan_psoc_obj_lock(psoc);
1554 	objmgr = &psoc->soc_objmgr;
1555 	/* List is empty, return NULL */
1556 	if (objmgr->wlan_peer_count == 0) {
1557 		wlan_psoc_obj_unlock(psoc);
1558 		return NULL;
1559 	}
1560 	/* reduce the search window, with hash key */
1561 	hash_index = WLAN_PEER_HASH(macaddr);
1562 	peer_list = &objmgr->peer_list;
1563 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1564 	/* Iterate through peer list, get peer */
1565 	peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted(
1566 		&peer_list->peer_hash[hash_index], macaddr, dbg_id);
1567 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1568 	wlan_psoc_obj_unlock(psoc);
1569 
1570 	return peer;
1571 }
1572 
1573 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac(
1574 		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
1575 		wlan_objmgr_ref_dbgid dbg_id)
1576 {
1577 	struct wlan_objmgr_psoc_objmgr *objmgr;
1578 	uint8_t hash_index;
1579 	struct wlan_objmgr_peer *peer = NULL;
1580 	struct wlan_peer_list *peer_list;
1581 
1582 	if (!macaddr)
1583 		return NULL;
1584 
1585 	/* psoc lock should be taken before peer list lock */
1586 	wlan_psoc_obj_lock(psoc);
1587 	objmgr = &psoc->soc_objmgr;
1588 	/* List is empty, return NULL */
1589 	if (objmgr->wlan_peer_count == 0) {
1590 		wlan_psoc_obj_unlock(psoc);
1591 		return NULL;
1592 	}
1593 	/* reduce the search window, with hash key */
1594 	hash_index = WLAN_PEER_HASH(macaddr);
1595 	peer_list = &objmgr->peer_list;
1596 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1597 	/* Iterate through peer list, get peer */
1598 	peer = wlan_obj_psoc_peerlist_get_peer(
1599 			&peer_list->peer_hash[hash_index], macaddr, dbg_id);
1600 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1601 	wlan_psoc_obj_unlock(psoc);
1602 
1603 	return peer;
1604 }
1605 qdf_export_symbol(wlan_objmgr_get_peer_by_mac);
1606 
1607 struct wlan_objmgr_peer *wlan_objmgr_get_peer(
1608 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1609 			uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1610 {
1611 	struct wlan_objmgr_psoc_objmgr *objmgr;
1612 	uint8_t hash_index;
1613 	struct wlan_objmgr_peer *peer = NULL;
1614 	struct wlan_peer_list *peer_list;
1615 
1616 	if (pdev_id >= WLAN_UMAC_MAX_PDEVS)
1617 		QDF_ASSERT(0);
1618 
1619 	if (!macaddr)
1620 		return NULL;
1621 
1622 	/* psoc lock should be taken before peer list lock */
1623 	wlan_psoc_obj_lock(psoc);
1624 	objmgr = &psoc->soc_objmgr;
1625 	/* List is empty, return NULL */
1626 	if (objmgr->wlan_peer_count == 0) {
1627 		wlan_psoc_obj_unlock(psoc);
1628 		return NULL;
1629 	}
1630 	/* reduce the search window, with hash key */
1631 	hash_index = WLAN_PEER_HASH(macaddr);
1632 	peer_list = &objmgr->peer_list;
1633 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1634 	/* Iterate through peer list, get peer */
1635 	peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id(
1636 		&peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id);
1637 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1638 	wlan_psoc_obj_unlock(psoc);
1639 
1640 	return peer;
1641 }
1642 qdf_export_symbol(wlan_objmgr_get_peer);
1643 
1644 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock(
1645 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1646 			uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1647 {
1648 	struct wlan_objmgr_psoc_objmgr *objmgr;
1649 	uint8_t hash_index;
1650 	struct wlan_objmgr_peer *peer = NULL;
1651 	struct wlan_peer_list *peer_list;
1652 
1653 	/* psoc lock should be taken before peer list lock */
1654 	objmgr = &psoc->soc_objmgr;
1655 	/* List is empty, return NULL */
1656 	if (objmgr->wlan_peer_count == 0)
1657 		return NULL;
1658 
1659 	/* reduce the search window, with hash key */
1660 	hash_index = WLAN_PEER_HASH(macaddr);
1661 	peer_list = &objmgr->peer_list;
1662 	/* Iterate through peer list, get peer */
1663 	peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id(
1664 		&peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id);
1665 
1666 	return peer;
1667 }
1668 qdf_export_symbol(wlan_objmgr_get_peer_nolock);
1669 
1670 
1671 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state(
1672 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1673 			uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1674 {
1675 	struct wlan_objmgr_psoc_objmgr *objmgr;
1676 	uint8_t hash_index;
1677 	struct wlan_objmgr_peer *peer = NULL;
1678 	struct wlan_peer_list *peer_list;
1679 
1680 	/* psoc lock should be taken before peer list lock */
1681 	wlan_psoc_obj_lock(psoc);
1682 	objmgr = &psoc->soc_objmgr;
1683 	/* List is empty, return NULL */
1684 	if (objmgr->wlan_peer_count == 0) {
1685 		wlan_psoc_obj_unlock(psoc);
1686 		return NULL;
1687 	}
1688 	/* reduce the search window, with hash key */
1689 	hash_index = WLAN_PEER_HASH(macaddr);
1690 	peer_list = &objmgr->peer_list;
1691 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1692 	/* Iterate through peer list, get peer */
1693 	peer = wlan_obj_psoc_peerlist_get_peer_no_state(
1694 		&peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id);
1695 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1696 	wlan_psoc_obj_unlock(psoc);
1697 
1698 	return peer;
1699 }
1700 qdf_export_symbol(wlan_objmgr_get_peer_no_state);
1701 
1702 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev(
1703 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1704 			uint8_t *bssid, uint8_t *macaddr,
1705 			wlan_objmgr_ref_dbgid dbg_id)
1706 {
1707 	struct wlan_objmgr_psoc_objmgr *objmgr;
1708 	uint8_t hash_index;
1709 	struct wlan_objmgr_peer *peer = NULL;
1710 	struct wlan_peer_list *peer_list;
1711 
1712 	/* psoc lock should be taken before peer list lock */
1713 	wlan_psoc_obj_lock(psoc);
1714 	objmgr = &psoc->soc_objmgr;
1715 	/* List is empty, return NULL */
1716 	if (objmgr->wlan_peer_count == 0) {
1717 		wlan_psoc_obj_unlock(psoc);
1718 		return NULL;
1719 	}
1720 	/* reduce the search window, with hash key */
1721 	hash_index = WLAN_PEER_HASH(macaddr);
1722 	peer_list = &objmgr->peer_list;
1723 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1724 	/* Iterate through peer list, get peer */
1725 	peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid(
1726 		&peer_list->peer_hash[hash_index], macaddr, bssid,
1727 		pdev_id, dbg_id);
1728 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1729 	wlan_psoc_obj_unlock(psoc);
1730 
1731 	return peer;
1732 }
1733 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev);
1734 
1735 
1736 /**
1737  * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - get peer from psoc
1738  *                                                           peer list using
1739  *                                                           mac and vdev
1740  *                                                           self mac
1741  * @psoc: PSOC object
1742  * @pdev_id: Pdev id
1743  * @macaddr: MAC address
1744  * @bssid: BSSID address. NULL mac means search all.
1745  * @dbg_id: id of the caller
1746  *
1747  * API to finds peer object pointer by MAC addr and BSSID from
1748  * peer hash list, bssid check is done on matching peer
1749  *
1750  * Return: list of peer pointer pointers
1751  *         NULL on FAILURE
1752  */
1753 
1754 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev(
1755 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1756 			uint8_t *bssid, uint8_t *macaddr,
1757 			wlan_objmgr_ref_dbgid dbg_id)
1758 {
1759 	struct wlan_objmgr_psoc_objmgr *objmgr;
1760 	uint8_t hash_index;
1761 	struct wlan_peer_list *peer_list = NULL;
1762 	qdf_list_t *logical_del_peer_list = NULL;
1763 
1764 	/* psoc lock should be taken before peer list lock */
1765 	wlan_psoc_obj_lock(psoc);
1766 	objmgr = &psoc->soc_objmgr;
1767 	/* List is empty, return NULL */
1768 	if (objmgr->wlan_peer_count == 0) {
1769 		wlan_psoc_obj_unlock(psoc);
1770 		return NULL;
1771 	}
1772 	/* reduce the search window, with hash key */
1773 	hash_index = WLAN_PEER_HASH(macaddr);
1774 	peer_list = &objmgr->peer_list;
1775 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1776 
1777 	/* Iterate through peer list, get peer */
1778 	logical_del_peer_list =
1779 		wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid(
1780 			&peer_list->peer_hash[hash_index], macaddr,
1781 			bssid, pdev_id, dbg_id);
1782 
1783 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1784 	wlan_psoc_obj_unlock(psoc);
1785 
1786 	return logical_del_peer_list;
1787 }
1788 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev);
1789 
1790 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state(
1791 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1792 			uint8_t *bssid, uint8_t *macaddr,
1793 			wlan_objmgr_ref_dbgid dbg_id)
1794 {
1795 	struct wlan_objmgr_psoc_objmgr *objmgr;
1796 	uint8_t hash_index;
1797 	struct wlan_objmgr_peer *peer = NULL;
1798 	struct wlan_peer_list *peer_list;
1799 
1800 	/* psoc lock should be taken before peer list lock */
1801 	wlan_psoc_obj_lock(psoc);
1802 	objmgr = &psoc->soc_objmgr;
1803 	/* List is empty, return NULL */
1804 	if (objmgr->wlan_peer_count == 0) {
1805 		wlan_psoc_obj_unlock(psoc);
1806 		return NULL;
1807 	}
1808 	/* reduce the search window, with hash key */
1809 	hash_index = WLAN_PEER_HASH(macaddr);
1810 	peer_list = &objmgr->peer_list;
1811 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1812 	/* Iterate through peer list, get peer */
1813 	peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state(
1814 		&peer_list->peer_hash[hash_index], macaddr, bssid,
1815 		pdev_id, dbg_id);
1816 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1817 	wlan_psoc_obj_unlock(psoc);
1818 
1819 	return peer;
1820 }
1821 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state);
1822 
1823 void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc,
1824 					enum wlan_umac_comp_id id)
1825 {
1826 	void *comp_private_obj;
1827 
1828 	/* component id is invalid */
1829 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
1830 		QDF_BUG(0);
1831 		return NULL;
1832 	}
1833 
1834 	if (!psoc) {
1835 		QDF_BUG(0);
1836 		return NULL;
1837 	}
1838 
1839 	comp_private_obj = psoc->soc_comp_priv_obj[id];
1840 
1841 	return comp_private_obj;
1842 }
1843 qdf_export_symbol(wlan_objmgr_psoc_get_comp_private_obj);
1844 
1845 void wlan_objmgr_psoc_get_ref(struct wlan_objmgr_psoc *psoc,
1846 						wlan_objmgr_ref_dbgid id)
1847 {
1848 	if (!psoc) {
1849 		obj_mgr_err("psoc obj is NULL for id:%d", id);
1850 		QDF_ASSERT(0);
1851 		return;
1852 	}
1853 	/* Increment ref count */
1854 	qdf_atomic_inc(&psoc->soc_objmgr.ref_cnt);
1855 	qdf_atomic_inc(&psoc->soc_objmgr.ref_id_dbg[id]);
1856 	return;
1857 }
1858 qdf_export_symbol(wlan_objmgr_psoc_get_ref);
1859 
1860 QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc,
1861 						wlan_objmgr_ref_dbgid id)
1862 {
1863 	if (!psoc) {
1864 		obj_mgr_err("psoc obj is NULL for id:%d", id);
1865 		QDF_ASSERT(0);
1866 		return QDF_STATUS_E_FAILURE;
1867 	}
1868 
1869 	wlan_psoc_obj_lock(psoc);
1870 	if (psoc->obj_state != WLAN_OBJ_STATE_CREATED) {
1871 		wlan_psoc_obj_unlock(psoc);
1872 		if (psoc->soc_objmgr.print_cnt++ <=
1873 				WLAN_OBJMGR_RATELIMIT_THRESH)
1874 			obj_mgr_err(
1875 			"[Ref id: %d] psoc is not in Created state(%d)",
1876 					id, psoc->obj_state);
1877 
1878 		return QDF_STATUS_E_RESOURCES;
1879 	}
1880 
1881 	/* Increment ref count */
1882 	wlan_objmgr_psoc_get_ref(psoc, id);
1883 	wlan_psoc_obj_unlock(psoc);
1884 
1885 	return QDF_STATUS_SUCCESS;
1886 }
1887 qdf_export_symbol(wlan_objmgr_psoc_try_get_ref);
1888 
1889 void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc,
1890 						wlan_objmgr_ref_dbgid id)
1891 {
1892 	if (!psoc) {
1893 		obj_mgr_err("psoc obj is NULL for id:%d", id);
1894 		QDF_ASSERT(0);
1895 		return;
1896 	}
1897 
1898 	if (!qdf_atomic_read(&psoc->soc_objmgr.ref_id_dbg[id])) {
1899 		obj_mgr_err("psoc ref cnt was not taken by %d", id);
1900 		wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg,
1901 					  QDF_TRACE_LEVEL_FATAL);
1902 		WLAN_OBJMGR_BUG(0);
1903 	}
1904 
1905 	if (!qdf_atomic_read(&psoc->soc_objmgr.ref_cnt)) {
1906 		obj_mgr_err("psoc ref cnt is 0");
1907 		WLAN_OBJMGR_BUG(0);
1908 		return;
1909 	}
1910 
1911 	qdf_atomic_dec(&psoc->soc_objmgr.ref_id_dbg[id]);
1912 	/* Decrement ref count, free psoc, if ref count == 0 */
1913 	if (qdf_atomic_dec_and_test(&psoc->soc_objmgr.ref_cnt))
1914 		wlan_objmgr_psoc_obj_destroy(psoc);
1915 
1916 	return;
1917 }
1918 qdf_export_symbol(wlan_objmgr_psoc_release_ref);
1919 
1920 static void wlan_objmgr_psoc_peer_ref_print(struct wlan_objmgr_psoc *psoc,
1921 					 void *obj, void *args)
1922 {
1923 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
1924 	WLAN_OBJ_STATE obj_state;
1925 	uint8_t vdev_id;
1926 	uint8_t *macaddr;
1927 
1928 	wlan_peer_obj_lock(peer);
1929 	macaddr = wlan_peer_get_macaddr(peer);
1930 	obj_state = peer->obj_state;
1931 	vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
1932 	wlan_peer_obj_unlock(peer);
1933 
1934 	obj_mgr_alert("Peer MAC:%02x:%02x:%02x:%02x:%02x:%02x state:%d vdev_id:%d",
1935 		  macaddr[0], macaddr[1], macaddr[2], macaddr[3],
1936 		  macaddr[4], macaddr[5], obj_state, vdev_id);
1937 	wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_FATAL);
1938 }
1939 
1940 static void wlan_objmgr_psoc_vdev_ref_print(struct wlan_objmgr_psoc *psoc,
1941 					 void *obj, void *args)
1942 {
1943 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
1944 	WLAN_OBJ_STATE obj_state;
1945 	uint8_t id;
1946 
1947 	wlan_vdev_obj_lock(vdev);
1948 	id = wlan_vdev_get_id(vdev);
1949 	obj_state =  vdev->obj_state;
1950 	wlan_vdev_obj_unlock(vdev);
1951 	obj_mgr_alert("Vdev ID is %d, state %d", id, obj_state);
1952 
1953 	wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
1954 				  QDF_TRACE_LEVEL_FATAL);
1955 }
1956 
1957 static void wlan_objmgr_psoc_pdev_ref_print(struct wlan_objmgr_psoc *psoc,
1958 					 void *obj, void *args)
1959 {
1960 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
1961 	uint8_t id;
1962 
1963 	wlan_pdev_obj_lock(pdev);
1964 	id = wlan_objmgr_pdev_get_pdev_id(pdev);
1965 	wlan_pdev_obj_unlock(pdev);
1966 	obj_mgr_alert("pdev ID is %d", id);
1967 
1968 	wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg,
1969 				  QDF_TRACE_LEVEL_FATAL);
1970 }
1971 
1972 QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc(
1973 		struct wlan_objmgr_psoc *psoc)
1974 {
1975 	obj_mgr_alert("Ref counts of PEER");
1976 	wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PEER_OP,
1977 				wlan_objmgr_psoc_peer_ref_print, NULL);
1978 	obj_mgr_alert("Ref counts of VDEV");
1979 	wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_VDEV_OP,
1980 				wlan_objmgr_psoc_vdev_ref_print, NULL);
1981 	obj_mgr_alert("Ref counts of PDEV");
1982 	wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PDEV_OP,
1983 				wlan_objmgr_psoc_pdev_ref_print, NULL);
1984 
1985 	obj_mgr_alert(" Ref counts of PSOC");
1986 	wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg,
1987 				  QDF_TRACE_LEVEL_FATAL);
1988 
1989 	return QDF_STATUS_SUCCESS;
1990 }
1991 qdf_export_symbol(wlan_objmgr_print_ref_all_objects_per_psoc);
1992 
1993 QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc,
1994 		struct wlan_objmgr_psoc_user_config *user_config_data)
1995 {
1996 	if (!user_config_data) {
1997 		obj_mgr_err("user_config_data is NULL");
1998 		QDF_BUG(0);
1999 		return QDF_STATUS_E_FAILURE;
2000 	}
2001 	wlan_psoc_obj_lock(psoc);
2002 	qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data,
2003 		     sizeof(psoc->soc_nif.user_config));
2004 	wlan_psoc_obj_unlock(psoc);
2005 
2006 	return QDF_STATUS_SUCCESS;
2007 }
2008 
2009 void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc)
2010 {
2011 	struct wlan_objmgr_psoc_objmgr *_psoc;
2012 	struct wlan_objmgr_pdev *pdev;
2013 	int pdev_id;
2014 	uint32_t leaks = 0;
2015 
2016 	QDF_BUG(psoc);
2017 	if (!psoc)
2018 		return;
2019 
2020 	wlan_psoc_obj_lock(psoc);
2021 	_psoc = &psoc->soc_objmgr;
2022 	if (!_psoc->wlan_pdev_count) {
2023 		wlan_psoc_obj_unlock(psoc);
2024 		return;
2025 	}
2026 
2027 	obj_mgr_alert("objmgr pdev leaks detected for psoc %u!",
2028 		      _psoc->psoc_id);
2029 	obj_mgr_alert("----------------------------------------------------");
2030 	obj_mgr_alert("Pdev Id   Refs   Module");
2031 	obj_mgr_alert("----------------------------------------------------");
2032 
2033 	wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) {
2034 		qdf_atomic_t *ref_id_dbg;
2035 		int ref_id;
2036 		int32_t refs;
2037 
2038 		wlan_pdev_obj_lock(pdev);
2039 		ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg;
2040 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) {
2041 			leaks++;
2042 			obj_mgr_alert("%7u   %4u   %s",
2043 				      pdev_id, refs,
2044 				      string_from_dbgid(ref_id));
2045 		}
2046 		wlan_pdev_obj_unlock(pdev);
2047 	}
2048 
2049 	QDF_DEBUG_PANIC("%u objmgr pdev leaks detected for psoc %u!",
2050 			leaks, _psoc->psoc_id);
2051 
2052 	wlan_psoc_obj_unlock(psoc);
2053 }
2054 qdf_export_symbol(wlan_objmgr_psoc_check_for_pdev_leaks);
2055 
2056 void wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc)
2057 {
2058 	struct wlan_objmgr_psoc_objmgr *_psoc;
2059 	struct wlan_objmgr_vdev *vdev;
2060 	int vdev_id;
2061 	uint32_t leaks = 0;
2062 
2063 	QDF_BUG(psoc);
2064 	if (!psoc)
2065 		return;
2066 
2067 	wlan_psoc_obj_lock(psoc);
2068 	_psoc = &psoc->soc_objmgr;
2069 	if (!_psoc->wlan_vdev_count) {
2070 		wlan_psoc_obj_unlock(psoc);
2071 		return;
2072 	}
2073 
2074 	obj_mgr_alert("objmgr vdev leaks detected for psoc %u!",
2075 		      _psoc->psoc_id);
2076 	obj_mgr_alert("----------------------------------------------------");
2077 	obj_mgr_alert("Vdev Id   Refs   Module");
2078 	obj_mgr_alert("----------------------------------------------------");
2079 
2080 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
2081 		qdf_atomic_t *ref_id_dbg;
2082 		int ref_id;
2083 		int32_t refs;
2084 
2085 		wlan_vdev_obj_lock(vdev);
2086 		ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
2087 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) {
2088 			leaks++;
2089 			obj_mgr_alert("%7u   %4u   %s",
2090 				      vdev_id, refs, string_from_dbgid(ref_id));
2091 		}
2092 		wlan_vdev_obj_unlock(vdev);
2093 	}
2094 
2095 	QDF_DEBUG_PANIC("%u objmgr vdev leaks detected for psoc %u!",
2096 			leaks, _psoc->psoc_id);
2097 
2098 	wlan_psoc_obj_unlock(psoc);
2099 }
2100 qdf_export_symbol(wlan_objmgr_psoc_check_for_vdev_leaks);
2101 
2102 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
2103 static void
2104 wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id)
2105 {
2106 	qdf_atomic_t *ref_id_dbg;
2107 	int32_t refs;
2108 	int ref_id;
2109 
2110 	ref_id_dbg = peer->peer_objmgr.ref_id_dbg;
2111 	wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) {
2112 		obj_mgr_alert(QDF_MAC_ADDR_STR " %7u   %4u   %s",
2113 			      QDF_MAC_ADDR_ARRAY(peer->macaddr),
2114 			      vdev_id,
2115 			      refs,
2116 			      string_from_dbgid(ref_id));
2117 	}
2118 }
2119 #else
2120 static inline void
2121 wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id)
2122 {
2123 	obj_mgr_alert(QDF_MAC_ADDR_STR " %7u   %4u   %s",
2124 		      QDF_MAC_ADDR_ARRAY(peer->macaddr),
2125 		      vdev_id,
2126 		      qdf_atomic_read(&peer->peer_objmgr.ref_cnt),
2127 		      "TOTAL_REF_COUNT");
2128 }
2129 #endif
2130 
2131 void wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc)
2132 {
2133 	struct wlan_objmgr_psoc_objmgr *_psoc;
2134 	struct wlan_objmgr_vdev *vdev;
2135 	int vdev_id;
2136 	uint32_t leaks = 0;
2137 
2138 	QDF_BUG(psoc);
2139 	if (!psoc)
2140 		return;
2141 
2142 	wlan_psoc_obj_lock(psoc);
2143 	_psoc = &psoc->soc_objmgr;
2144 	if (!_psoc->temp_peer_count && !_psoc->wlan_peer_count) {
2145 		wlan_psoc_obj_unlock(psoc);
2146 		return;
2147 	}
2148 
2149 	obj_mgr_alert("objmgr peer leaks detected for psoc %u!",
2150 		      _psoc->psoc_id);
2151 	obj_mgr_alert("----------------------------------------------------");
2152 	obj_mgr_alert("Peer MAC          Vdev Id   Refs   Module");
2153 	obj_mgr_alert("----------------------------------------------------");
2154 
2155 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
2156 		struct wlan_objmgr_peer *peer;
2157 
2158 		wlan_vdev_obj_lock(vdev);
2159 		wlan_objmgr_for_each_vdev_peer(vdev, peer) {
2160 			wlan_peer_obj_lock(peer);
2161 			leaks += qdf_atomic_read(&peer->peer_objmgr.ref_cnt);
2162 			wlan_objmgr_print_peer_ref_leaks(peer, vdev_id);
2163 			wlan_peer_obj_unlock(peer);
2164 		}
2165 		wlan_vdev_obj_unlock(vdev);
2166 	}
2167 
2168 	QDF_DEBUG_PANIC("%u objmgr peer leaks detected for psoc %u!",
2169 			leaks, _psoc->psoc_id);
2170 
2171 	wlan_psoc_obj_unlock(psoc);
2172 }
2173 qdf_export_symbol(wlan_objmgr_psoc_check_for_peer_leaks);
2174 
2175 #ifdef WLAN_OBJMGR_DEBUG
2176 void wlan_print_psoc_info(struct wlan_objmgr_psoc *psoc)
2177 {
2178 	struct wlan_objmgr_psoc_objmgr *psoc_objmgr;
2179 	struct wlan_objmgr_pdev *pdev;
2180 	struct wlan_objmgr_vdev *vdev;
2181 	uint16_t index = 0;
2182 
2183 	psoc_objmgr = &psoc->soc_objmgr;
2184 
2185 	obj_mgr_debug("psoc: %pK", psoc);
2186 	obj_mgr_debug("psoc_id: %d", psoc_objmgr->psoc_id);
2187 	obj_mgr_debug("wlan_pdev_count: %d", psoc_objmgr->wlan_pdev_count);
2188 	obj_mgr_debug("wlan_pdev_id_map: 0x%x", psoc_objmgr->wlan_pdev_id_map);
2189 	obj_mgr_debug("wlan_vdev_count: %d", psoc_objmgr->wlan_vdev_count);
2190 	obj_mgr_debug("max_vdev_count: %d", psoc_objmgr->max_vdev_count);
2191 	obj_mgr_debug("wlan_peer_count: %d", psoc_objmgr->wlan_peer_count);
2192 	obj_mgr_debug("max_peer_count: %d", psoc_objmgr->max_peer_count);
2193 	obj_mgr_debug("temp_peer_count: %d", psoc_objmgr->temp_peer_count);
2194 	obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&psoc_objmgr->ref_cnt));
2195 	obj_mgr_debug("qdf_dev: %pK", psoc_objmgr->qdf_dev);
2196 
2197 	obj_mgr_debug("wlan_vdev_id_map[%d]: 0x%x",
2198 		      index, psoc_objmgr->wlan_vdev_id_map[index]);
2199 	index++;
2200 	obj_mgr_debug("wlan_vdev_id_map[%d]: 0x%x",
2201 		      index, psoc_objmgr->wlan_vdev_id_map[index]);
2202 
2203 	wlan_objmgr_for_each_psoc_pdev(psoc, index, pdev) {
2204 		obj_mgr_debug("wlan_pdev_list[%d]: %pK", index, pdev);
2205 		wlan_print_pdev_info(pdev);
2206 	}
2207 
2208 	wlan_objmgr_for_each_psoc_vdev(psoc, index, vdev) {
2209 		obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev);
2210 		wlan_print_vdev_info(vdev);
2211 	}
2212 }
2213 
2214 qdf_export_symbol(wlan_print_psoc_info);
2215 #endif
2216