xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c (revision 4865edfd190c086bbe2c69aae12a8226f877b91e)
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 <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 
35 /**
36  ** APIs to Create/Delete Global object APIs
37  */
38 static QDF_STATUS wlan_objmgr_psoc_object_status(
39 			struct wlan_objmgr_psoc *psoc)
40 {
41 	uint8_t id;
42 	QDF_STATUS status = QDF_STATUS_SUCCESS;
43 
44 	wlan_psoc_obj_lock(psoc);
45 	/* Iterate through all components to derive the object status */
46 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
47 		/* If component disabled, Ignore */
48 		if (psoc->obj_status[id] == QDF_STATUS_COMP_DISABLED)
49 			continue;
50 		/* If component operates in Async, status is Partially created,
51 		 * break
52 		 */
53 		else if (psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
54 			if (psoc->soc_comp_priv_obj[id] == NULL) {
55 				status = QDF_STATUS_COMP_ASYNC;
56 				break;
57 			}
58 		/*
59 		 * If component failed to allocate its object, treat it as
60 		 * failure, complete object need to be cleaned up
61 		 */
62 		} else if ((psoc->obj_status[id] == QDF_STATUS_E_NOMEM) ||
63 			(psoc->obj_status[id] == QDF_STATUS_E_FAILURE)) {
64 			status = QDF_STATUS_E_FAILURE;
65 			break;
66 		}
67 	}
68 	wlan_psoc_obj_unlock(psoc);
69 
70 	return status;
71 }
72 
73 static void wlan_objmgr_psoc_peer_list_init(struct wlan_peer_list *peer_list)
74 {
75 	uint8_t i;
76 
77 	qdf_spinlock_create(&peer_list->peer_list_lock);
78 	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
79 		qdf_list_create(&peer_list->peer_hash[i],
80 			WLAN_UMAC_PSOC_MAX_PEERS +
81 			WLAN_MAX_PSOC_TEMP_PEERS);
82 }
83 
84 static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list)
85 {
86 	uint8_t i;
87 
88 	/* deinit the lock */
89 	qdf_spinlock_destroy(&peer_list->peer_list_lock);
90 	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
91 		qdf_list_destroy(&peer_list->peer_hash[i]);
92 }
93 
94 static QDF_STATUS wlan_objmgr_psoc_obj_free(struct wlan_objmgr_psoc *psoc)
95 {
96 	/* Detach PSOC from global object's psoc list  */
97 	if (wlan_objmgr_psoc_object_detach(psoc) == QDF_STATUS_E_FAILURE) {
98 		obj_mgr_err("PSOC object detach failed");
99 		return QDF_STATUS_E_FAILURE;
100 	}
101 	wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list);
102 
103 	qdf_spinlock_destroy(&psoc->psoc_lock);
104 	qdf_mem_free(psoc);
105 
106 	return QDF_STATUS_SUCCESS;
107 }
108 
109 struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version,
110 						WLAN_DEV_TYPE dev_type)
111 {
112 	uint8_t id;
113 	struct wlan_objmgr_psoc *psoc = NULL;
114 	wlan_objmgr_psoc_create_handler handler;
115 	wlan_objmgr_psoc_status_handler stat_handler;
116 	struct wlan_objmgr_psoc_objmgr *objmgr;
117 	QDF_STATUS obj_status;
118 	void *arg;
119 
120 	psoc = qdf_mem_malloc(sizeof(*psoc));
121 	if (psoc == NULL) {
122 		obj_mgr_err("PSOC allocation failed");
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 != NULL)
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 != NULL)
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 == NULL) {
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 	obj_mgr_info("Physically deleting psoc %d", psoc->soc_objmgr.psoc_id);
206 
207 	if (psoc->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
208 		obj_mgr_err("PSOC object delete is not invoked obj_state:%d",
209 			    psoc->obj_state);
210 		WLAN_OBJMGR_BUG(0);
211 	}
212 
213 	/* Invoke registered create handlers */
214 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
215 		handler = g_umac_glb_obj->psoc_destroy_handler[id];
216 		arg = g_umac_glb_obj->psoc_destroy_handler_arg[id];
217 		if (handler != NULL)
218 			psoc->obj_status[id] = handler(psoc, arg);
219 		else
220 			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
221 	}
222 	/* Derive object status */
223 	obj_status = wlan_objmgr_psoc_object_status(psoc);
224 
225 	if (obj_status == QDF_STATUS_E_FAILURE) {
226 		obj_mgr_err("PSOC component object free failed");
227 		/* Ideally should not happen
228 		 * This leads to memleak, BUG_ON to find which component
229 		 * delete notification failed and fix it.
230 		 */
231 		QDF_BUG(0);
232 		return QDF_STATUS_E_FAILURE;
233 	}
234 	/* Deletion is in progress */
235 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
236 		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
237 		return QDF_STATUS_COMP_ASYNC;
238 	}
239 
240 	/* Free psoc object */
241 	return wlan_objmgr_psoc_obj_free(psoc);
242 }
243 
244 
245 QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc)
246 {
247 	uint8_t print_idx;
248 
249 	if (psoc == NULL) {
250 		obj_mgr_err("psoc is NULL");
251 		return QDF_STATUS_E_FAILURE;
252 	}
253 
254 	obj_mgr_info("Logically deleting psoc %d", psoc->soc_objmgr.psoc_id);
255 
256 	print_idx = qdf_get_pidx();
257 	if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR,
258 		QDF_TRACE_LEVEL_DEBUG)) {
259 		wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg);
260 	}
261 
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] != NULL) {
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 != NULL)
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 	qdf_list_t *obj_list;
420 	struct wlan_objmgr_pdev *pdev;
421 	struct wlan_objmgr_vdev *vdev;
422 	struct wlan_objmgr_peer *peer;
423 	struct wlan_objmgr_peer *peer_next;
424 	uint16_t max_vdev_cnt;
425 
426 	/* If caller requests for lock free opeation, do not acquire,
427 	 * handler will handle the synchronization
428 	 */
429 	if (!lock_free_op)
430 		wlan_psoc_obj_lock(psoc);
431 
432 	switch (obj_type) {
433 	case WLAN_PDEV_OP:
434 		/* Iterate through PDEV list, invoke handler for each pdev */
435 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
436 			pdev = objmgr->wlan_pdev_list[obj_id];
437 			if ((pdev != NULL) &&
438 			    (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) ==
439 				QDF_STATUS_SUCCESS)) {
440 				handler(psoc, (void *)pdev, arg);
441 				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
442 			}
443 		}
444 		break;
445 	case WLAN_VDEV_OP:
446 		/* Iterate through VDEV list, invoke handler for each vdev */
447 		max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
448 		for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) {
449 			vdev = objmgr->wlan_vdev_list[obj_id];
450 			if ((vdev != NULL) &&
451 			    (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
452 				QDF_STATUS_SUCCESS)) {
453 				handler(psoc, vdev, arg);
454 				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
455 			}
456 		}
457 		break;
458 	case WLAN_PEER_OP:
459 		/* Iterate through PEER list, invoke handler for each peer */
460 		peer_list = &objmgr->peer_list;
461 		/* psoc lock should be taken before list lock */
462 		if (!lock_free_op)
463 			qdf_spin_lock_bh(&peer_list->peer_list_lock);
464 		/* Since peer list has sublist, iterate through sublists */
465 		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
466 			obj_list = &peer_list->peer_hash[i];
467 			peer = wlan_psoc_peer_list_peek_head(obj_list);
468 			while (peer) {
469 				/* Get next peer */
470 				peer_next = wlan_peer_get_next_peer_of_psoc(
471 								obj_list, peer);
472 				if (wlan_objmgr_peer_try_get_ref(peer, dbg_id)
473 						== QDF_STATUS_SUCCESS) {
474 					handler(psoc, (void *)peer, arg);
475 					wlan_objmgr_peer_release_ref(peer,
476 								     dbg_id);
477 				}
478 				peer = peer_next;
479 			}
480 		}
481 		if (!lock_free_op)
482 			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
483 		break;
484 	default:
485 		break;
486 	}
487 	if (!lock_free_op)
488 		wlan_psoc_obj_unlock(psoc);
489 
490 	return QDF_STATUS_SUCCESS;
491 }
492 qdf_export_symbol(wlan_objmgr_iterate_obj_list);
493 
494 QDF_STATUS wlan_objmgr_iterate_obj_list_all(
495 		struct wlan_objmgr_psoc *psoc,
496 		enum wlan_objmgr_obj_type obj_type,
497 		wlan_objmgr_op_handler handler,
498 		void *arg, uint8_t lock_free_op,
499 		wlan_objmgr_ref_dbgid dbg_id)
500 {
501 	uint16_t obj_id;
502 	uint8_t i;
503 	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
504 	struct wlan_peer_list *peer_list;
505 	qdf_list_t *obj_list;
506 	struct wlan_objmgr_pdev *pdev;
507 	struct wlan_objmgr_vdev *vdev;
508 	struct wlan_objmgr_peer *peer;
509 	struct wlan_objmgr_peer *peer_next;
510 	uint16_t max_vdev_cnt;
511 
512 	/* If caller requests for lock free opeation, do not acquire,
513 	 * handler will handle the synchronization
514 	 */
515 	if (!lock_free_op)
516 		wlan_psoc_obj_lock(psoc);
517 
518 	switch (obj_type) {
519 	case WLAN_PDEV_OP:
520 		/* Iterate through PDEV list, invoke handler for each pdev */
521 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
522 			pdev = objmgr->wlan_pdev_list[obj_id];
523 			if (pdev != NULL) {
524 				wlan_objmgr_pdev_get_ref(pdev, dbg_id);
525 				handler(psoc, (void *)pdev, arg);
526 				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
527 			}
528 		}
529 		break;
530 	case WLAN_VDEV_OP:
531 		/* Iterate through VDEV list, invoke handler for each vdev */
532 		max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
533 		for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) {
534 			vdev = objmgr->wlan_vdev_list[obj_id];
535 			if (vdev != NULL) {
536 				wlan_objmgr_vdev_get_ref(vdev, dbg_id);
537 				handler(psoc, vdev, arg);
538 				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
539 			}
540 		}
541 		break;
542 	case WLAN_PEER_OP:
543 		/* Iterate through PEER list, invoke handler for each peer */
544 		peer_list = &objmgr->peer_list;
545 		/* psoc lock should be taken before list lock */
546 		if (!lock_free_op)
547 			qdf_spin_lock_bh(&peer_list->peer_list_lock);
548 		/* Since peer list has sublist, iterate through sublists */
549 		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
550 			obj_list = &peer_list->peer_hash[i];
551 			peer = wlan_psoc_peer_list_peek_head(obj_list);
552 			while (peer) {
553 				/* Get next peer */
554 				peer_next = wlan_peer_get_next_peer_of_psoc(
555 								obj_list, peer);
556 				wlan_objmgr_peer_get_ref(peer, dbg_id);
557 				handler(psoc, (void *)peer, arg);
558 				wlan_objmgr_peer_release_ref(peer, dbg_id);
559 				peer = peer_next;
560 			}
561 		}
562 		if (!lock_free_op)
563 			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
564 		break;
565 	default:
566 		break;
567 	}
568 	if (!lock_free_op)
569 		wlan_psoc_obj_unlock(psoc);
570 
571 	return QDF_STATUS_SUCCESS;
572 }
573 qdf_export_symbol(wlan_objmgr_iterate_obj_list_all);
574 
575 /**
576  * wlan_objmgr_iterate_obj_list_all_noref() - iterate through all psoc objects
577  *                                            without taking ref
578  * @psoc: PSOC object
579  * @obj_type: PDEV_OP/VDEV_OP/PEER_OP
580  * @handler: the handler will be called for each object of requested type
581  *            the handler should be implemented to perform required operation
582  * @arg:     agruments passed by caller
583  *
584  * API to be used for performing the operations on all PDEV/VDEV/PEER objects
585  * of psoc with lock protected
586  *
587  * Return: SUCCESS/FAILURE
588  */
589 static QDF_STATUS wlan_objmgr_iterate_obj_list_all_noref(
590 		struct wlan_objmgr_psoc *psoc,
591 		enum wlan_objmgr_obj_type obj_type,
592 		wlan_objmgr_op_handler handler,
593 		void *arg)
594 {
595 	uint16_t obj_id;
596 	uint8_t i;
597 	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
598 	struct wlan_peer_list *peer_list;
599 	qdf_list_t *obj_list;
600 	struct wlan_objmgr_pdev *pdev;
601 	struct wlan_objmgr_vdev *vdev;
602 	struct wlan_objmgr_peer *peer;
603 	struct wlan_objmgr_peer *peer_next;
604 	uint16_t max_vdev_cnt;
605 
606 	/* If caller requests for lock free opeation, do not acquire,
607 	 * handler will handle the synchronization
608 	 */
609 	wlan_psoc_obj_lock(psoc);
610 
611 	switch (obj_type) {
612 	case WLAN_PDEV_OP:
613 		/* Iterate through PDEV list, invoke handler for each pdev */
614 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
615 			pdev = objmgr->wlan_pdev_list[obj_id];
616 			if (pdev != NULL)
617 				handler(psoc, (void *)pdev, arg);
618 		}
619 		break;
620 	case WLAN_VDEV_OP:
621 		/* Iterate through VDEV list, invoke handler for each vdev */
622 		max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
623 		for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) {
624 			vdev = objmgr->wlan_vdev_list[obj_id];
625 			if (vdev != NULL)
626 				handler(psoc, vdev, arg);
627 		}
628 		break;
629 	case WLAN_PEER_OP:
630 		/* Iterate through PEER list, invoke handler for each peer */
631 		peer_list = &objmgr->peer_list;
632 		/* psoc lock should be taken before list lock */
633 		qdf_spin_lock_bh(&peer_list->peer_list_lock);
634 		/* Since peer list has sublist, iterate through sublists */
635 		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
636 			obj_list = &peer_list->peer_hash[i];
637 			peer = wlan_psoc_peer_list_peek_head(obj_list);
638 			while (peer) {
639 				/* Get next peer */
640 				peer_next = wlan_peer_get_next_peer_of_psoc(
641 								obj_list, peer);
642 				handler(psoc, (void *)peer, arg);
643 				peer = peer_next;
644 			}
645 		}
646 		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
647 		break;
648 	default:
649 		break;
650 	}
651 	wlan_psoc_obj_unlock(psoc);
652 
653 	return QDF_STATUS_SUCCESS;
654 }
655 
656 static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc,
657 					 void *obj, void *args)
658 {
659 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
660 
661 	wlan_objmgr_peer_obj_delete(peer);
662 }
663 
664 static void wlan_objmgr_psoc_vdev_delete(struct wlan_objmgr_psoc *psoc,
665 					 void *obj, void *args)
666 {
667 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
668 
669 	wlan_objmgr_vdev_obj_delete(vdev);
670 }
671 
672 static void wlan_objmgr_psoc_pdev_delete(struct wlan_objmgr_psoc *psoc,
673 					 void *obj, void *args)
674 {
675 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
676 
677 	wlan_objmgr_pdev_obj_delete(pdev);
678 }
679 
680 QDF_STATUS wlan_objmgr_free_all_objects_per_psoc(
681 		struct wlan_objmgr_psoc *psoc)
682 {
683 	/* Free all peers */
684 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
685 				     wlan_objmgr_psoc_peer_delete, NULL, 1,
686 				     WLAN_OBJMGR_ID);
687 	/* Free all vdevs */
688 	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
689 				     wlan_objmgr_psoc_vdev_delete, NULL, 1,
690 				     WLAN_OBJMGR_ID);
691 	/* Free all PDEVs */
692 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
693 				     wlan_objmgr_psoc_pdev_delete, NULL, 1,
694 				     WLAN_OBJMGR_ID);
695 
696 	return QDF_STATUS_SUCCESS;
697 }
698 
699 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_creation(
700 		struct wlan_objmgr_psoc *psoc,
701 		enum wlan_umac_comp_id id)
702 {
703 	wlan_objmgr_psoc_create_handler handler;
704 	void *arg;
705 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
706 
707 	/* Component id is invalid */
708 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
709 		return QDF_STATUS_MAXCOMP_FAIL;
710 
711 	wlan_psoc_obj_lock(psoc);
712 	/* If component object is already created, delete old
713 	 * component object, then invoke creation
714 	 */
715 	if (psoc->soc_comp_priv_obj[id] != NULL) {
716 		wlan_psoc_obj_unlock(psoc);
717 		return QDF_STATUS_E_FAILURE;
718 	}
719 	wlan_psoc_obj_unlock(psoc);
720 	/* Invoke registered create handlers */
721 	handler = g_umac_glb_obj->psoc_create_handler[id];
722 	arg = g_umac_glb_obj->psoc_create_handler_arg[id];
723 	if (handler != NULL)
724 		psoc->obj_status[id] = handler(psoc, arg);
725 	else
726 		return QDF_STATUS_E_FAILURE;
727 
728 	/* If object status is created, then only handle this object status */
729 	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
730 		/* Derive object status */
731 		obj_status = wlan_objmgr_psoc_object_status(psoc);
732 		/* Move PSOC object state to Partially created state */
733 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
734 			/*TODO atomic */
735 			psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
736 		}
737 	}
738 
739 	return obj_status;
740 }
741 
742 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_deletion(
743 		struct wlan_objmgr_psoc *psoc,
744 		enum wlan_umac_comp_id id)
745 {
746 	wlan_objmgr_psoc_destroy_handler handler;
747 	void *arg;
748 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
749 
750 	/* component id is invalid */
751 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
752 		return QDF_STATUS_MAXCOMP_FAIL;
753 
754 	wlan_psoc_obj_lock(psoc);
755 	/* Component object was never created, invalid operation */
756 	if (psoc->soc_comp_priv_obj[id] == NULL) {
757 		wlan_psoc_obj_unlock(psoc);
758 		return QDF_STATUS_E_FAILURE;
759 	}
760 	wlan_psoc_obj_unlock(psoc);
761 	/* Invoke registered create handlers */
762 	handler = g_umac_glb_obj->psoc_destroy_handler[id];
763 	arg = g_umac_glb_obj->psoc_destroy_handler_arg[id];
764 	if (handler != NULL)
765 		psoc->obj_status[id] = handler(psoc, arg);
766 	else
767 		return QDF_STATUS_E_FAILURE;
768 
769 	/* If object status is created, then only handle this object status */
770 	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
771 		obj_status = wlan_objmgr_psoc_object_status(psoc);
772 			/* move object state to DEL progress */
773 		if (obj_status == QDF_STATUS_COMP_ASYNC)
774 			psoc->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
775 	}
776 
777 	return obj_status;
778 }
779 
780 /* Util APIs */
781 
782 QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc,
783 					struct wlan_objmgr_pdev *pdev)
784 {
785 	struct wlan_objmgr_psoc_objmgr *objmgr;
786 	uint8_t id = 0;
787 	QDF_STATUS status;
788 
789 	wlan_psoc_obj_lock(psoc);
790 	objmgr = &psoc->soc_objmgr;
791 	/*
792 	 * Derive pdev id from pdev map
793 	 * First free pdev id is assigned
794 	 */
795 	while ((id < WLAN_UMAC_MAX_PDEVS) &&
796 			(objmgr->wlan_pdev_id_map & (1<<id)))
797 		id++;
798 
799 	if (id == WLAN_UMAC_MAX_PDEVS) {
800 		status = QDF_STATUS_E_FAILURE;
801 	} else {
802 		/* Update the map for reserving the id */
803 		objmgr->wlan_pdev_id_map |= (1<<id);
804 		/* store pdev in pdev list */
805 		objmgr->wlan_pdev_list[id] = pdev;
806 		/* Increment pdev count */
807 		objmgr->wlan_pdev_count++;
808 		/* save pdev id */
809 		pdev->pdev_objmgr.wlan_pdev_id = id;
810 		status = QDF_STATUS_SUCCESS;
811 		/* Inrement psoc ref count to block its free before pdev */
812 		wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID);
813 	}
814 	wlan_psoc_obj_unlock(psoc);
815 
816 	return status;
817 }
818 
819 QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc,
820 						struct wlan_objmgr_pdev *pdev)
821 {
822 	struct wlan_objmgr_psoc_objmgr *objmgr;
823 	uint8_t id;
824 
825 	id = pdev->pdev_objmgr.wlan_pdev_id;
826 	/* If id is invalid, return */
827 	if (id >= WLAN_UMAC_MAX_PDEVS)
828 		return QDF_STATUS_E_FAILURE;
829 
830 	wlan_psoc_obj_lock(psoc);
831 	objmgr = &psoc->soc_objmgr;
832 	/* Free pdev id slot */
833 	objmgr->wlan_pdev_id_map &= ~(1<<id);
834 	objmgr->wlan_pdev_list[id] = NULL;
835 	objmgr->wlan_pdev_count--;
836 	pdev->pdev_objmgr.wlan_pdev_id = 0xff;
837 	wlan_psoc_obj_unlock(psoc);
838 	/* Release ref count of psoc */
839 	wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID);
840 
841 	return QDF_STATUS_SUCCESS;
842 }
843 
844 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id(
845 		struct wlan_objmgr_psoc *psoc, uint8_t id,
846 		wlan_objmgr_ref_dbgid dbg_id)
847 {
848 	struct wlan_objmgr_psoc_objmgr *objmgr;
849 	struct wlan_objmgr_pdev *pdev = NULL;
850 
851 	/* If id is invalid, return */
852 	if (id >= WLAN_UMAC_MAX_PDEVS)
853 		return NULL;
854 
855 	wlan_psoc_obj_lock(psoc);
856 	objmgr = &psoc->soc_objmgr;
857 	/* get pdev from pdev list */
858 	pdev = objmgr->wlan_pdev_list[id];
859 	/* Do not return object, if it is not CREATED state */
860 	if (pdev != NULL) {
861 		if (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) !=
862 							QDF_STATUS_SUCCESS)
863 			pdev = NULL;
864 	}
865 
866 	wlan_psoc_obj_unlock(psoc);
867 
868 	return pdev;
869 }
870 qdf_export_symbol(wlan_objmgr_get_pdev_by_id);
871 
872 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id_no_state(
873 		struct wlan_objmgr_psoc *psoc, uint8_t id,
874 		wlan_objmgr_ref_dbgid dbg_id)
875 {
876 	struct wlan_objmgr_psoc_objmgr *objmgr;
877 	struct wlan_objmgr_pdev *pdev = NULL;
878 
879 	/* If id is invalid, return */
880 	if (id >= WLAN_UMAC_MAX_PDEVS)
881 		return NULL;
882 
883 	wlan_psoc_obj_lock(psoc);
884 	objmgr = &psoc->soc_objmgr;
885 	/* get pdev from pdev list */
886 	pdev = objmgr->wlan_pdev_list[id];
887 	/* Do not return object, if it is not CREATED state */
888 	if (pdev != NULL)
889 		wlan_objmgr_pdev_get_ref(pdev, dbg_id);
890 
891 	wlan_psoc_obj_unlock(psoc);
892 
893 	return pdev;
894 }
895 QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc,
896 					struct wlan_objmgr_vdev *vdev)
897 {
898 	struct wlan_objmgr_psoc_objmgr *objmgr;
899 	uint8_t id = 0;
900 	uint8_t map_index = 0;
901 	uint8_t map_entry_size = 32;
902 	uint8_t adjust_ix = 0;
903 	QDF_STATUS status;
904 
905 	wlan_psoc_obj_lock(psoc);
906 	objmgr = &psoc->soc_objmgr;
907 	/* Find first free vdev id */
908 	while ((id < objmgr->max_vdev_count) &&
909 		(objmgr->wlan_vdev_id_map[map_index] & (1<<(id - adjust_ix)))) {
910 		id++;
911 		/*
912 		 * The map is two DWORDS(32 bits), so, map_index
913 		 * adjust_ix derived based on the id value
914 		 */
915 		if (id == ((map_index + 1) * map_entry_size)) {
916 			map_index++;
917 			adjust_ix = map_index * map_entry_size;
918 		}
919 	}
920 	/* If no free slot, return failure */
921 	if (id == objmgr->max_vdev_count) {
922 		status = QDF_STATUS_E_FAILURE;
923 	} else {
924 		/* set free vdev id index */
925 		objmgr->wlan_vdev_id_map[map_index] |= (1<<(id-adjust_ix));
926 		/* store vdev pointer in vdev list */
927 		objmgr->wlan_vdev_list[id] = vdev;
928 		/* increment vdev counter */
929 		objmgr->wlan_vdev_count++;
930 		/* save vdev id */
931 		vdev->vdev_objmgr.vdev_id = id;
932 		status = QDF_STATUS_SUCCESS;
933 	}
934 	wlan_psoc_obj_unlock(psoc);
935 
936 	return status;
937 }
938 
939 QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc,
940 					struct wlan_objmgr_vdev *vdev)
941 {
942 	struct wlan_objmgr_psoc_objmgr *objmgr;
943 	uint8_t id = 0;
944 	uint8_t map_index = 0;
945 	uint8_t map_entry_size = 32;
946 	uint8_t adjust_ix = 0;
947 
948 	id = vdev->vdev_objmgr.vdev_id;
949 	/* Invalid vdev id */
950 	if (id >= wlan_psoc_get_max_vdev_count(psoc))
951 		return QDF_STATUS_E_FAILURE;
952 	/*
953 	 * Derive map_index and adjust_ix to find actual DWORD
954 	 * the id map is present
955 	 */
956 	while ((id - adjust_ix) >= map_entry_size) {
957 		map_index++;
958 		adjust_ix = map_index * map_entry_size;
959 	}
960 	wlan_psoc_obj_lock(psoc);
961 	objmgr = &psoc->soc_objmgr;
962 	/* unset bit, to free the slot */
963 	objmgr->wlan_vdev_id_map[map_index] &= ~(1<<(id-adjust_ix));
964 	/* reset VDEV pointer to NULL in VDEV list array */
965 	objmgr->wlan_vdev_list[id] = NULL;
966 	/* decrement vdev count */
967 	objmgr->wlan_vdev_count--;
968 	vdev->vdev_objmgr.vdev_id = 0xff;
969 	wlan_psoc_obj_unlock(psoc);
970 
971 	return QDF_STATUS_SUCCESS;
972 }
973 
974 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc(
975 			struct wlan_objmgr_psoc *psoc,
976 			enum QDF_OPMODE opmode,
977 			wlan_objmgr_ref_dbgid dbg_id)
978 {
979 	struct wlan_objmgr_vdev *vdev = NULL;
980 	int vdev_cnt = 0;
981 	uint16_t max_vdev_cnt;
982 
983 	/* if PSOC is NULL, return */
984 	if (psoc == NULL)
985 		return NULL;
986 
987 	wlan_psoc_obj_lock(psoc);
988 
989 	max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc);
990 	/* retrieve vdev pointer from vdev list */
991 	while (vdev_cnt < max_vdev_cnt) {
992 		vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt];
993 		vdev_cnt++;
994 		if (vdev == NULL)
995 			continue;
996 		wlan_vdev_obj_lock(vdev);
997 		if (vdev->vdev_mlme.vdev_opmode == opmode) {
998 			wlan_vdev_obj_unlock(vdev);
999 			if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
1000 							QDF_STATUS_SUCCESS) {
1001 				vdev = NULL;
1002 				continue;
1003 			}
1004 			break;
1005 		}
1006 		wlan_vdev_obj_unlock(vdev);
1007 	}
1008 	wlan_psoc_obj_unlock(psoc);
1009 
1010 	return vdev;
1011 }
1012 
1013 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc(
1014 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
1015 			wlan_objmgr_ref_dbgid dbg_id)
1016 {
1017 	struct wlan_objmgr_vdev *vdev;
1018 
1019 	/* if PSOC is NULL, return */
1020 	if (psoc == NULL)
1021 		return NULL;
1022 	/* vdev id is invalid */
1023 	if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc))
1024 		return NULL;
1025 
1026 	wlan_psoc_obj_lock(psoc);
1027 	/* retrieve vdev pointer from vdev list */
1028 	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
1029 	if (vdev != NULL) {
1030 		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
1031 							QDF_STATUS_SUCCESS)
1032 			vdev = NULL;
1033 	}
1034 	wlan_psoc_obj_unlock(psoc);
1035 
1036 	return vdev;
1037 }
1038 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc);
1039 
1040 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state(
1041 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
1042 			wlan_objmgr_ref_dbgid dbg_id)
1043 {
1044 	struct wlan_objmgr_vdev *vdev;
1045 
1046 	/* if PSOC is NULL, return */
1047 	if (psoc == NULL)
1048 		return NULL;
1049 	/* vdev id is invalid */
1050 	if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc))
1051 		return NULL;
1052 
1053 	wlan_psoc_obj_lock(psoc);
1054 	/* retrieve vdev pointer from vdev list */
1055 	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
1056 	if (vdev != NULL)
1057 		wlan_objmgr_vdev_get_ref(vdev, dbg_id);
1058 
1059 	wlan_psoc_obj_unlock(psoc);
1060 
1061 	return vdev;
1062 }
1063 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state);
1064 
1065 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc(
1066 		struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1067 		uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1068 {
1069 	struct wlan_objmgr_vdev *vdev;
1070 	struct wlan_objmgr_pdev *pdev;
1071 
1072 	/* if PSOC is NULL, return */
1073 	if (psoc == NULL)
1074 		return NULL;
1075 
1076 	if (!macaddr)
1077 		return NULL;
1078 
1079 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
1080 	if (!pdev) {
1081 		obj_mgr_err("pdev is null");
1082 		return NULL;
1083 	}
1084 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, macaddr, dbg_id);
1085 	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
1086 
1087 	return vdev;
1088 }
1089 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc);
1090 
1091 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state(
1092 		struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1093 		uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1094 {
1095 	struct wlan_objmgr_vdev *vdev;
1096 	struct wlan_objmgr_pdev *pdev;
1097 
1098 	/* if PSOC is NULL, return */
1099 	if (psoc == NULL)
1100 		return NULL;
1101 
1102 	if (!macaddr)
1103 		return NULL;
1104 
1105 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
1106 	if (!pdev) {
1107 		obj_mgr_err("pdev is null");
1108 		return NULL;
1109 	}
1110 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(pdev, macaddr, dbg_id);
1111 	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
1112 
1113 	return vdev;
1114 }
1115 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state);
1116 
1117 static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list,
1118 				struct wlan_objmgr_peer *obj)
1119 {
1120 	qdf_list_insert_back(obj_list, &obj->psoc_peer);
1121 }
1122 
1123 static QDF_STATUS wlan_obj_psoc_peerlist_remove_peer(
1124 				qdf_list_t *obj_list,
1125 				struct wlan_objmgr_peer *peer)
1126 {
1127 	qdf_list_node_t *psoc_node = NULL;
1128 
1129 	if (peer == NULL)
1130 		return QDF_STATUS_E_FAILURE;
1131 	/* get vdev list node element */
1132 	psoc_node = &peer->psoc_peer;
1133 	/* list is empty, return failure */
1134 	if (qdf_list_remove_node(obj_list, psoc_node) != QDF_STATUS_SUCCESS)
1135 		return QDF_STATUS_E_FAILURE;
1136 
1137 	return QDF_STATUS_SUCCESS;
1138 }
1139 
1140 static QDF_STATUS wlan_peer_bssid_match(struct wlan_objmgr_peer *peer,
1141 				     uint8_t *bssid)
1142 {
1143 	struct wlan_objmgr_vdev *vdev = wlan_peer_get_vdev(peer);
1144 	uint8_t *peer_bssid = wlan_vdev_mlme_get_macaddr(vdev);
1145 
1146 	if (WLAN_ADDR_EQ(peer_bssid, bssid) == QDF_STATUS_SUCCESS)
1147 		return QDF_STATUS_SUCCESS;
1148 	else
1149 		return QDF_STATUS_E_FAILURE;
1150 }
1151 
1152 /**
1153  * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer
1154  * from psoc peer list
1155  * @psoc: PSOC object
1156  * @macaddr: MAC address
1157  *
1158  * API to finds peer object pointer of logically deleted peer
1159  *
1160  * Return: peer pointer
1161  *         NULL on FAILURE
1162  */
1163 static struct wlan_objmgr_peer *
1164 			wlan_obj_psoc_peerlist_get_peer_logically_deleted(
1165 				qdf_list_t *obj_list, uint8_t *macaddr,
1166 				wlan_objmgr_ref_dbgid dbg_id)
1167 {
1168 	struct wlan_objmgr_peer *peer;
1169 	struct wlan_objmgr_peer *peer_temp;
1170 
1171 	/* Iterate through hash list to get the peer */
1172 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1173 	while (peer != NULL) {
1174 		/* For peer, macaddr is key */
1175 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1176 			== QDF_STATUS_SUCCESS) {
1177 			/* Return peer in logically deleted state */
1178 			if (peer->obj_state ==
1179 					WLAN_OBJ_STATE_LOGICALLY_DELETED) {
1180 				wlan_objmgr_peer_get_ref(peer, dbg_id);
1181 
1182 				return peer;
1183 			}
1184 
1185 		}
1186 		/* Move to next peer */
1187 		peer_temp = peer;
1188 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1189 	}
1190 
1191 	/* Not found, return NULL */
1192 	return NULL;
1193 }
1194 
1195 /**
1196  * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list
1197  * @psoc: PSOC object
1198  * @macaddr: MAC address
1199  *
1200  * API to finds peer object pointer by MAC addr from hash list
1201  *
1202  * Return: peer pointer
1203  *         NULL on FAILURE
1204  */
1205 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer(
1206 		qdf_list_t *obj_list, uint8_t *macaddr,
1207 		wlan_objmgr_ref_dbgid dbg_id)
1208 {
1209 	struct wlan_objmgr_peer *peer;
1210 	struct wlan_objmgr_peer *peer_temp;
1211 
1212 	/* Iterate through hash list to get the peer */
1213 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1214 	while (peer != NULL) {
1215 		/* For peer, macaddr is key */
1216 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1217 				== QDF_STATUS_SUCCESS) {
1218 			if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
1219 					QDF_STATUS_SUCCESS) {
1220 				return peer;
1221 			}
1222 		}
1223 		/* Move to next peer */
1224 		peer_temp = peer;
1225 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1226 	}
1227 
1228 	/* Not found, return NULL */
1229 	return NULL;
1230 }
1231 
1232 /**
1233  * wlan_obj_psoc_peerlist_get_peer_by_pdev_id() - get peer from psoc peer list
1234  * @psoc: PSOC object
1235  * @macaddr: MAC address
1236  * #pdev_id: Pdev id
1237  *
1238  * API to finds peer object pointer by MAC addr and pdev id from hash list
1239  *
1240  * Return: peer pointer
1241  *         NULL on FAILURE
1242  */
1243 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id(
1244 				qdf_list_t *obj_list, uint8_t *macaddr,
1245 				uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id)
1246 {
1247 	struct wlan_objmgr_peer *peer;
1248 	struct wlan_objmgr_peer *peer_temp;
1249 
1250 	/* Iterate through hash list to get the peer */
1251 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1252 	while (peer != NULL) {
1253 		/* For peer, macaddr is key */
1254 		if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1255 			== QDF_STATUS_SUCCESS) &&
1256 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1257 			if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
1258 							QDF_STATUS_SUCCESS) {
1259 				return peer;
1260 			}
1261 		}
1262 		/* Move to next peer */
1263 		peer_temp = peer;
1264 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1265 	}
1266 
1267 	/* Not found, return NULL */
1268 	return NULL;
1269 }
1270 
1271 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state(
1272 				qdf_list_t *obj_list, uint8_t *macaddr,
1273 				uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id)
1274 {
1275 	struct wlan_objmgr_peer *peer;
1276 	struct wlan_objmgr_peer *peer_temp;
1277 
1278 	/* Iterate through hash list to get the peer */
1279 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1280 	while (peer != NULL) {
1281 		/* For peer, macaddr and pdev_id is key */
1282 		if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1283 			== QDF_STATUS_SUCCESS) &&
1284 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1285 			wlan_objmgr_peer_get_ref(peer, dbg_id);
1286 
1287 			return peer;
1288 		}
1289 		/* Move to next peer */
1290 		peer_temp = peer;
1291 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1292 	}
1293 
1294 	/* Not found, return NULL */
1295 	return NULL;
1296 }
1297 
1298 /**
1299  * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - get peer
1300  *                                           from psoc peer list using
1301  *                                           mac and vdev self mac
1302  * @obj_list: peer object list
1303  * @macaddr: MAC address
1304  * @bssid: BSSID address
1305  * @dbg_id: id of the caller
1306  *
1307  * API to finds peer object pointer by MAC addr and BSSID from
1308  * peer hash list for a node which is in logically deleted state,
1309  * bssid check is done on matching peer
1310  *
1311  * Caller to free the list allocated in this function
1312  *
1313  * Return: list of peer pointers
1314  *         NULL on FAILURE
1315  */
1316 static qdf_list_t
1317 	*wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid(
1318 				qdf_list_t *obj_list, uint8_t *macaddr,
1319 				uint8_t *bssid, uint8_t pdev_id,
1320 				wlan_objmgr_ref_dbgid dbg_id)
1321 {
1322 	struct wlan_objmgr_peer *peer;
1323 	struct wlan_objmgr_peer *peer_temp;
1324 	struct wlan_logically_del_peer *peer_list = NULL;
1325 	qdf_list_t *logical_del_peer_list = NULL;
1326 	bool lock_released = false;
1327 
1328 	logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list));
1329 	if (!logical_del_peer_list) {
1330 		obj_mgr_err("failed to allocate list");
1331 		return NULL;
1332 	}
1333 
1334 	qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS);
1335 
1336 	/* Iterate through hash list to get the peer */
1337 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1338 	while (peer != NULL) {
1339 		wlan_peer_obj_lock(peer);
1340 		/* For peer, macaddr and pdev id are keys */
1341 		if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1342 			== QDF_STATUS_SUCCESS) &&
1343 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1344 			/*
1345 			 *  if BSSID not NULL,
1346 			 *  then match is requested by caller, check BSSID
1347 			 *  (vdev mac == bssid) --  return peer
1348 			 *  (vdev mac != bssid) --  perform next iteration
1349 			 */
1350 			if ((bssid == NULL) ||
1351 				(wlan_peer_bssid_match(peer, bssid) ==
1352 				 QDF_STATUS_SUCCESS)) {
1353 				/* Return peer in logically deleted state */
1354 				if ((peer->obj_state ==
1355 					WLAN_OBJ_STATE_LOGICALLY_DELETED) &&
1356 				     qdf_atomic_read(
1357 						&peer->peer_objmgr.ref_cnt)) {
1358 
1359 					wlan_objmgr_peer_get_ref(peer, dbg_id);
1360 					wlan_peer_obj_unlock(peer);
1361 					lock_released = true;
1362 
1363 					peer_list =
1364 					qdf_mem_malloc(
1365 					sizeof(struct wlan_logically_del_peer));
1366 					if (peer_list == NULL) {
1367 						wlan_objmgr_peer_release_ref(peer, dbg_id);
1368 						/* Lock is already released */
1369 						obj_mgr_alert("Mem alloc failed");
1370 						WLAN_OBJMGR_BUG(0);
1371 						break;
1372 					}
1373 
1374 					peer_list->peer = peer;
1375 
1376 					qdf_list_insert_front(
1377 						logical_del_peer_list,
1378 							&peer_list->list);
1379 				}
1380 			}
1381 		}
1382 
1383 		if (!lock_released)
1384 			wlan_peer_obj_unlock(peer);
1385 
1386 		/* Move to next peer */
1387 		peer_temp = peer;
1388 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1389 		lock_released = false;
1390 	}
1391 
1392 	/* Not found, return NULL */
1393 	if (qdf_list_empty(logical_del_peer_list)) {
1394 		qdf_mem_free(logical_del_peer_list);
1395 		return NULL;
1396 	} else {
1397 		return logical_del_peer_list;
1398 	}
1399 
1400 }
1401 
1402 /**
1403  * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer from psoc peer
1404  *                                                    list using mac and vdev
1405  *                                                    self mac
1406  * @psoc: PSOC object
1407  * @macaddr: MAC address
1408  * @bssid: BSSID address
1409  *
1410  * API to finds peer object pointer by MAC addr and BSSID from
1411  * peer hash list, bssid check is done on matching peer
1412  *
1413  * Return: peer pointer
1414  *         NULL on FAILURE
1415  */
1416 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid(
1417 					qdf_list_t *obj_list, uint8_t *macaddr,
1418 					uint8_t *bssid, uint8_t pdev_id,
1419 					wlan_objmgr_ref_dbgid dbg_id)
1420 {
1421 	struct wlan_objmgr_peer *peer;
1422 	struct wlan_objmgr_peer *peer_temp;
1423 
1424 	/* Iterate through hash list to get the peer */
1425 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1426 	while (peer != NULL) {
1427 		/* For peer, macaddr is key */
1428 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1429 			== QDF_STATUS_SUCCESS) {
1430 			/*
1431 			 *  BSSID match is requested by caller, check BSSID
1432 			 *  (vdev mac == bssid) --  return peer
1433 			 *  (vdev mac != bssid) --  perform next iteration
1434 			 */
1435 			if ((wlan_peer_bssid_match(peer, bssid) ==
1436 				QDF_STATUS_SUCCESS) &&
1437 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1438 				if (wlan_objmgr_peer_try_get_ref(peer, dbg_id)
1439 					== QDF_STATUS_SUCCESS) {
1440 					return peer;
1441 				}
1442 			}
1443 		}
1444 		/* Move to next peer */
1445 		peer_temp = peer;
1446 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1447 	}
1448 	/* Not found, return NULL */
1449 	return NULL;
1450 }
1451 
1452 static struct wlan_objmgr_peer
1453 		*wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state(
1454 					qdf_list_t *obj_list, uint8_t *macaddr,
1455 					uint8_t *bssid,
1456 					uint8_t pdev_id,
1457 					wlan_objmgr_ref_dbgid dbg_id)
1458 {
1459 	struct wlan_objmgr_peer *peer;
1460 	struct wlan_objmgr_peer *peer_temp;
1461 
1462 	/* Iterate through hash list to get the peer */
1463 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1464 	while (peer != NULL) {
1465 		/* For peer, macaddr is key */
1466 		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
1467 			== QDF_STATUS_SUCCESS) {
1468 			/*
1469 			 *  BSSID match is requested by caller, check BSSID
1470 			 *  (vdev mac == bssid) --  return peer
1471 			 *  (vdev mac != bssid) --  perform next iteration
1472 			 */
1473 			if ((wlan_peer_bssid_match(peer, bssid) ==
1474 				QDF_STATUS_SUCCESS) &&
1475 				(wlan_peer_get_pdev_id(peer) == pdev_id)) {
1476 				wlan_objmgr_peer_get_ref(peer, dbg_id);
1477 
1478 				return peer;
1479 			}
1480 		}
1481 		/* Move to next peer */
1482 		peer_temp = peer;
1483 		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
1484 	}
1485 
1486 	/* Not found, return NULL */
1487 	return NULL;
1488 }
1489 
1490 QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc,
1491 					 struct wlan_objmgr_peer *peer)
1492 {
1493 	struct wlan_objmgr_psoc_objmgr *objmgr;
1494 	uint8_t hash_index;
1495 	struct wlan_peer_list *peer_list;
1496 
1497 	wlan_psoc_obj_lock(psoc);
1498 	objmgr = &psoc->soc_objmgr;
1499 	/* Max temporary peer limit is reached, return failure */
1500 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) {
1501 		if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) {
1502 			wlan_psoc_obj_unlock(psoc);
1503 			return QDF_STATUS_E_FAILURE;
1504 		}
1505 	} else {
1506 		/* Max peer limit is reached, return failure */
1507 		if (objmgr->wlan_peer_count
1508 			>= wlan_psoc_get_max_peer_count(psoc)) {
1509 			wlan_psoc_obj_unlock(psoc);
1510 			return QDF_STATUS_E_FAILURE;
1511 		}
1512 	}
1513 
1514 	/* Derive hash index from mac address */
1515 	hash_index = WLAN_PEER_HASH(peer->macaddr);
1516 	peer_list = &objmgr->peer_list;
1517 	/* psoc lock should be taken before list lock */
1518 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1519 	/* add peer to hash peer list */
1520 	wlan_obj_psoc_peerlist_add_tail(
1521 			&peer_list->peer_hash[hash_index],
1522 							peer);
1523 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1524 	/* Increment peer count */
1525 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
1526 		objmgr->temp_peer_count++;
1527 	else
1528 		objmgr->wlan_peer_count++;
1529 
1530 	wlan_psoc_obj_unlock(psoc);
1531 
1532 	return QDF_STATUS_SUCCESS;
1533 }
1534 
1535 QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc,
1536 						struct wlan_objmgr_peer *peer)
1537 {
1538 	struct wlan_objmgr_psoc_objmgr *objmgr;
1539 	uint8_t hash_index;
1540 	struct wlan_peer_list *peer_list;
1541 
1542 	wlan_psoc_obj_lock(psoc);
1543 	objmgr = &psoc->soc_objmgr;
1544 	/* if list is empty, return */
1545 	if (objmgr->wlan_peer_count == 0) {
1546 		wlan_psoc_obj_unlock(psoc);
1547 		return QDF_STATUS_E_FAILURE;
1548 	}
1549 	/* Get hash index, to locate the actual peer list */
1550 	hash_index = WLAN_PEER_HASH(peer->macaddr);
1551 	peer_list = &objmgr->peer_list;
1552 	/* psoc lock should be taken before list lock */
1553 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1554 	/* removes the peer from peer_list */
1555 	if (wlan_obj_psoc_peerlist_remove_peer(
1556 				&peer_list->peer_hash[hash_index],
1557 						peer) ==
1558 				QDF_STATUS_E_FAILURE) {
1559 		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1560 		wlan_psoc_obj_unlock(psoc);
1561 		obj_mgr_err("Failed to detach peer");
1562 		return QDF_STATUS_E_FAILURE;
1563 	}
1564 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1565 	/* Decrement peer count */
1566 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
1567 		objmgr->temp_peer_count--;
1568 	else
1569 		objmgr->wlan_peer_count--;
1570 	wlan_psoc_obj_unlock(psoc);
1571 
1572 	return QDF_STATUS_SUCCESS;
1573 }
1574 
1575 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted(
1576 			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
1577 			wlan_objmgr_ref_dbgid dbg_id)
1578 {
1579 	struct wlan_objmgr_psoc_objmgr *objmgr;
1580 	uint8_t hash_index;
1581 	struct wlan_objmgr_peer *peer = NULL;
1582 	struct wlan_peer_list *peer_list;
1583 
1584 	/* psoc lock should be taken before peer list lock */
1585 	wlan_psoc_obj_lock(psoc);
1586 	objmgr = &psoc->soc_objmgr;
1587 	/* List is empty, return NULL */
1588 	if (objmgr->wlan_peer_count == 0) {
1589 		wlan_psoc_obj_unlock(psoc);
1590 		return NULL;
1591 	}
1592 	/* reduce the search window, with hash key */
1593 	hash_index = WLAN_PEER_HASH(macaddr);
1594 	peer_list = &objmgr->peer_list;
1595 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1596 	/* Iterate through peer list, get peer */
1597 	peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted(
1598 		&peer_list->peer_hash[hash_index], macaddr, dbg_id);
1599 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1600 	wlan_psoc_obj_unlock(psoc);
1601 
1602 	return peer;
1603 }
1604 
1605 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac(
1606 		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
1607 		wlan_objmgr_ref_dbgid dbg_id)
1608 {
1609 	struct wlan_objmgr_psoc_objmgr *objmgr;
1610 	uint8_t hash_index;
1611 	struct wlan_objmgr_peer *peer = NULL;
1612 	struct wlan_peer_list *peer_list;
1613 
1614 	if (!macaddr)
1615 		return NULL;
1616 
1617 	/* psoc lock should be taken before peer list lock */
1618 	wlan_psoc_obj_lock(psoc);
1619 	objmgr = &psoc->soc_objmgr;
1620 	/* List is empty, return NULL */
1621 	if (objmgr->wlan_peer_count == 0) {
1622 		wlan_psoc_obj_unlock(psoc);
1623 		return NULL;
1624 	}
1625 	/* reduce the search window, with hash key */
1626 	hash_index = WLAN_PEER_HASH(macaddr);
1627 	peer_list = &objmgr->peer_list;
1628 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1629 	/* Iterate through peer list, get peer */
1630 	peer = wlan_obj_psoc_peerlist_get_peer(
1631 			&peer_list->peer_hash[hash_index], macaddr, dbg_id);
1632 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1633 	wlan_psoc_obj_unlock(psoc);
1634 
1635 	return peer;
1636 }
1637 qdf_export_symbol(wlan_objmgr_get_peer_by_mac);
1638 
1639 struct wlan_objmgr_peer *wlan_objmgr_get_peer(
1640 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1641 			uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1642 {
1643 	struct wlan_objmgr_psoc_objmgr *objmgr;
1644 	uint8_t hash_index;
1645 	struct wlan_objmgr_peer *peer = NULL;
1646 	struct wlan_peer_list *peer_list;
1647 
1648 	if (pdev_id >= WLAN_UMAC_MAX_PDEVS)
1649 		QDF_ASSERT(0);
1650 
1651 	if (!macaddr)
1652 		return NULL;
1653 
1654 	/* psoc lock should be taken before peer list lock */
1655 	wlan_psoc_obj_lock(psoc);
1656 	objmgr = &psoc->soc_objmgr;
1657 	/* List is empty, return NULL */
1658 	if (objmgr->wlan_peer_count == 0) {
1659 		wlan_psoc_obj_unlock(psoc);
1660 		return NULL;
1661 	}
1662 	/* reduce the search window, with hash key */
1663 	hash_index = WLAN_PEER_HASH(macaddr);
1664 	peer_list = &objmgr->peer_list;
1665 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1666 	/* Iterate through peer list, get peer */
1667 	peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id(
1668 		&peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id);
1669 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1670 	wlan_psoc_obj_unlock(psoc);
1671 
1672 	return peer;
1673 }
1674 qdf_export_symbol(wlan_objmgr_get_peer);
1675 
1676 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock(
1677 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1678 			uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id)
1679 {
1680 	struct wlan_objmgr_psoc_objmgr *objmgr;
1681 	uint8_t hash_index;
1682 	struct wlan_objmgr_peer *peer = NULL;
1683 	struct wlan_peer_list *peer_list;
1684 
1685 	/* psoc lock should be taken before peer list lock */
1686 	objmgr = &psoc->soc_objmgr;
1687 	/* List is empty, return NULL */
1688 	if (objmgr->wlan_peer_count == 0)
1689 		return NULL;
1690 
1691 	/* reduce the search window, with hash key */
1692 	hash_index = WLAN_PEER_HASH(macaddr);
1693 	peer_list = &objmgr->peer_list;
1694 	/* Iterate through peer list, get peer */
1695 	peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id(
1696 		&peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id);
1697 
1698 	return peer;
1699 }
1700 qdf_export_symbol(wlan_objmgr_get_peer_nolock);
1701 
1702 
1703 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state(
1704 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1705 			uint8_t *macaddr, 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_no_state(
1726 		&peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id);
1727 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1728 	wlan_psoc_obj_unlock(psoc);
1729 
1730 	return peer;
1731 }
1732 qdf_export_symbol(wlan_objmgr_get_peer_no_state);
1733 
1734 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev(
1735 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1736 			uint8_t *bssid, uint8_t *macaddr,
1737 			wlan_objmgr_ref_dbgid dbg_id)
1738 {
1739 	struct wlan_objmgr_psoc_objmgr *objmgr;
1740 	uint8_t hash_index;
1741 	struct wlan_objmgr_peer *peer = NULL;
1742 	struct wlan_peer_list *peer_list;
1743 
1744 	/* psoc lock should be taken before peer list lock */
1745 	wlan_psoc_obj_lock(psoc);
1746 	objmgr = &psoc->soc_objmgr;
1747 	/* List is empty, return NULL */
1748 	if (objmgr->wlan_peer_count == 0) {
1749 		wlan_psoc_obj_unlock(psoc);
1750 		return NULL;
1751 	}
1752 	/* reduce the search window, with hash key */
1753 	hash_index = WLAN_PEER_HASH(macaddr);
1754 	peer_list = &objmgr->peer_list;
1755 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1756 	/* Iterate through peer list, get peer */
1757 	peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid(
1758 		&peer_list->peer_hash[hash_index], macaddr, bssid,
1759 		pdev_id, dbg_id);
1760 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1761 	wlan_psoc_obj_unlock(psoc);
1762 
1763 	return peer;
1764 }
1765 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev);
1766 
1767 
1768 /**
1769  * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - get peer from psoc
1770  *                                                           peer list using
1771  *                                                           mac and vdev
1772  *                                                           self mac
1773  * @psoc: PSOC object
1774  * @pdev_id: Pdev id
1775  * @macaddr: MAC address
1776  * @bssid: BSSID address. NULL mac means search all.
1777  * @dbg_id: id of the caller
1778  *
1779  * API to finds peer object pointer by MAC addr and BSSID from
1780  * peer hash list, bssid check is done on matching peer
1781  *
1782  * Return: list of peer pointer pointers
1783  *         NULL on FAILURE
1784  */
1785 
1786 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev(
1787 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1788 			uint8_t *bssid, uint8_t *macaddr,
1789 			wlan_objmgr_ref_dbgid dbg_id)
1790 {
1791 	struct wlan_objmgr_psoc_objmgr *objmgr;
1792 	uint8_t hash_index;
1793 	struct wlan_peer_list *peer_list = NULL;
1794 	qdf_list_t *logical_del_peer_list = NULL;
1795 
1796 	/* psoc lock should be taken before peer list lock */
1797 	wlan_psoc_obj_lock(psoc);
1798 	objmgr = &psoc->soc_objmgr;
1799 	/* List is empty, return NULL */
1800 	if (objmgr->wlan_peer_count == 0) {
1801 		wlan_psoc_obj_unlock(psoc);
1802 		return NULL;
1803 	}
1804 	/* reduce the search window, with hash key */
1805 	hash_index = WLAN_PEER_HASH(macaddr);
1806 	peer_list = &objmgr->peer_list;
1807 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1808 
1809 	/* Iterate through peer list, get peer */
1810 	logical_del_peer_list =
1811 		wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid(
1812 			&peer_list->peer_hash[hash_index], macaddr,
1813 			bssid, pdev_id, dbg_id);
1814 
1815 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1816 	wlan_psoc_obj_unlock(psoc);
1817 
1818 	return logical_del_peer_list;
1819 }
1820 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev);
1821 
1822 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state(
1823 			struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1824 			uint8_t *bssid, uint8_t *macaddr,
1825 			wlan_objmgr_ref_dbgid dbg_id)
1826 {
1827 	struct wlan_objmgr_psoc_objmgr *objmgr;
1828 	uint8_t hash_index;
1829 	struct wlan_objmgr_peer *peer = NULL;
1830 	struct wlan_peer_list *peer_list;
1831 
1832 	/* psoc lock should be taken before peer list lock */
1833 	wlan_psoc_obj_lock(psoc);
1834 	objmgr = &psoc->soc_objmgr;
1835 	/* List is empty, return NULL */
1836 	if (objmgr->wlan_peer_count == 0) {
1837 		wlan_psoc_obj_unlock(psoc);
1838 		return NULL;
1839 	}
1840 	/* reduce the search window, with hash key */
1841 	hash_index = WLAN_PEER_HASH(macaddr);
1842 	peer_list = &objmgr->peer_list;
1843 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1844 	/* Iterate through peer list, get peer */
1845 	peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state(
1846 		&peer_list->peer_hash[hash_index], macaddr, bssid,
1847 		pdev_id, dbg_id);
1848 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1849 	wlan_psoc_obj_unlock(psoc);
1850 
1851 	return peer;
1852 }
1853 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state);
1854 
1855 void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc,
1856 					enum wlan_umac_comp_id id)
1857 {
1858 	void *comp_private_obj;
1859 
1860 	/* component id is invalid */
1861 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
1862 		QDF_BUG(0);
1863 		return NULL;
1864 	}
1865 
1866 	if (psoc == NULL) {
1867 		QDF_BUG(0);
1868 		return NULL;
1869 	}
1870 
1871 	comp_private_obj = psoc->soc_comp_priv_obj[id];
1872 
1873 	return comp_private_obj;
1874 }
1875 qdf_export_symbol(wlan_objmgr_psoc_get_comp_private_obj);
1876 
1877 void wlan_objmgr_psoc_get_ref(struct wlan_objmgr_psoc *psoc,
1878 						wlan_objmgr_ref_dbgid id)
1879 {
1880 	if (psoc == NULL) {
1881 		obj_mgr_err("psoc obj is NULL for id:%d", id);
1882 		QDF_ASSERT(0);
1883 		return;
1884 	}
1885 	/* Increment ref count */
1886 	qdf_atomic_inc(&psoc->soc_objmgr.ref_cnt);
1887 	qdf_atomic_inc(&psoc->soc_objmgr.ref_id_dbg[id]);
1888 	return;
1889 }
1890 qdf_export_symbol(wlan_objmgr_psoc_get_ref);
1891 
1892 QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc,
1893 						wlan_objmgr_ref_dbgid id)
1894 {
1895 	if (psoc == NULL) {
1896 		obj_mgr_err("psoc obj is NULL for id:%d", id);
1897 		QDF_ASSERT(0);
1898 		return QDF_STATUS_E_FAILURE;
1899 	}
1900 
1901 	wlan_psoc_obj_lock(psoc);
1902 	if (psoc->obj_state != WLAN_OBJ_STATE_CREATED) {
1903 		wlan_psoc_obj_unlock(psoc);
1904 		if (psoc->soc_objmgr.print_cnt++ <=
1905 				WLAN_OBJMGR_RATELIMIT_THRESH)
1906 			obj_mgr_err(
1907 			"[Ref id: %d] psoc is not in Created state(%d)",
1908 					id, psoc->obj_state);
1909 
1910 		return QDF_STATUS_E_RESOURCES;
1911 	}
1912 
1913 	/* Increment ref count */
1914 	wlan_objmgr_psoc_get_ref(psoc, id);
1915 	wlan_psoc_obj_unlock(psoc);
1916 
1917 	return QDF_STATUS_SUCCESS;
1918 }
1919 qdf_export_symbol(wlan_objmgr_psoc_try_get_ref);
1920 
1921 void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc,
1922 						wlan_objmgr_ref_dbgid id)
1923 {
1924 	if (psoc == NULL) {
1925 		obj_mgr_err("psoc obj is NULL for id:%d", id);
1926 		QDF_ASSERT(0);
1927 		return;
1928 	}
1929 
1930 	if (!qdf_atomic_read(&psoc->soc_objmgr.ref_id_dbg[id])) {
1931 		obj_mgr_err("psoc ref cnt was not taken by %d", id);
1932 		wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg);
1933 		WLAN_OBJMGR_BUG(0);
1934 	}
1935 
1936 	if (!qdf_atomic_read(&psoc->soc_objmgr.ref_cnt)) {
1937 		obj_mgr_err("psoc ref cnt is 0");
1938 		WLAN_OBJMGR_BUG(0);
1939 		return;
1940 	}
1941 
1942 	qdf_atomic_dec(&psoc->soc_objmgr.ref_id_dbg[id]);
1943 	/* Decrement ref count, free psoc, if ref count == 0 */
1944 	if (qdf_atomic_dec_and_test(&psoc->soc_objmgr.ref_cnt))
1945 		wlan_objmgr_psoc_obj_destroy(psoc);
1946 
1947 	return;
1948 }
1949 qdf_export_symbol(wlan_objmgr_psoc_release_ref);
1950 
1951 static void wlan_objmgr_psoc_peer_ref_print(struct wlan_objmgr_psoc *psoc,
1952 					 void *obj, void *args)
1953 {
1954 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
1955 	WLAN_OBJ_STATE obj_state;
1956 	uint8_t vdev_id;
1957 	uint8_t *macaddr;
1958 
1959 	wlan_peer_obj_lock(peer);
1960 	macaddr = wlan_peer_get_macaddr(peer);
1961 	obj_state = peer->obj_state;
1962 	vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
1963 	wlan_peer_obj_unlock(peer);
1964 
1965 	obj_mgr_alert("Peer MAC:%02x:%02x:%02x:%02x:%02x:%02x state:%d vdev_id:%d",
1966 		  macaddr[0], macaddr[1], macaddr[2], macaddr[3],
1967 		  macaddr[4], macaddr[5], obj_state, vdev_id);
1968 	wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg);
1969 }
1970 
1971 static void wlan_objmgr_psoc_vdev_ref_print(struct wlan_objmgr_psoc *psoc,
1972 					 void *obj, void *args)
1973 {
1974 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
1975 	WLAN_OBJ_STATE obj_state;
1976 	uint8_t id;
1977 
1978 	wlan_vdev_obj_lock(vdev);
1979 	id = wlan_vdev_get_id(vdev);
1980 	obj_state =  vdev->obj_state;
1981 	wlan_vdev_obj_unlock(vdev);
1982 	obj_mgr_alert("Vdev ID is %d, state %d", id, obj_state);
1983 
1984 	wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg);
1985 }
1986 
1987 static void wlan_objmgr_psoc_pdev_ref_print(struct wlan_objmgr_psoc *psoc,
1988 					 void *obj, void *args)
1989 {
1990 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
1991 	uint8_t id;
1992 
1993 	wlan_pdev_obj_lock(pdev);
1994 	id = wlan_objmgr_pdev_get_pdev_id(pdev);
1995 	wlan_pdev_obj_unlock(pdev);
1996 	obj_mgr_alert("pdev ID is %d", id);
1997 
1998 	wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg);
1999 }
2000 
2001 QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc(
2002 		struct wlan_objmgr_psoc *psoc)
2003 {
2004 	obj_mgr_alert("Ref counts of PEER");
2005 	wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PEER_OP,
2006 				wlan_objmgr_psoc_peer_ref_print, NULL);
2007 	obj_mgr_alert("Ref counts of VDEV");
2008 	wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_VDEV_OP,
2009 				wlan_objmgr_psoc_vdev_ref_print, NULL);
2010 	obj_mgr_alert("Ref counts of PDEV");
2011 	wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PDEV_OP,
2012 				wlan_objmgr_psoc_pdev_ref_print, NULL);
2013 
2014 	obj_mgr_alert(" Ref counts of PSOC");
2015 	wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg);
2016 
2017 	return QDF_STATUS_SUCCESS;
2018 }
2019 qdf_export_symbol(wlan_objmgr_print_ref_all_objects_per_psoc);
2020 
2021 QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc,
2022 		struct wlan_objmgr_psoc_user_config *user_config_data)
2023 {
2024 	if (user_config_data == NULL) {
2025 		obj_mgr_err("user_config_data is NULL");
2026 		QDF_BUG(0);
2027 		return QDF_STATUS_E_FAILURE;
2028 	}
2029 	wlan_psoc_obj_lock(psoc);
2030 	qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data,
2031 		     sizeof(psoc->soc_nif.user_config));
2032 	wlan_psoc_obj_unlock(psoc);
2033 
2034 	return QDF_STATUS_SUCCESS;
2035 }
2036