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