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