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