xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2016-2020 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 Peer object
20  */
21 #include <wlan_objmgr_cmn.h>
22 #include <wlan_objmgr_global_obj.h>
23 #include <wlan_objmgr_psoc_obj.h>
24 #include <wlan_objmgr_pdev_obj.h>
25 #include <wlan_objmgr_vdev_obj.h>
26 #include <wlan_objmgr_peer_obj.h>
27 #include <wlan_objmgr_debug.h>
28 #include <qdf_mem.h>
29 #include <qdf_module.h>
30 #include "wlan_objmgr_global_obj_i.h"
31 #include "wlan_objmgr_psoc_obj_i.h"
32 #include "wlan_objmgr_pdev_obj_i.h"
33 #include "wlan_objmgr_vdev_obj_i.h"
34 
35 
36 /**
37  ** APIs to Create/Delete Peer object APIs
38  */
39 static QDF_STATUS wlan_objmgr_peer_object_status(
40 		struct wlan_objmgr_peer *peer)
41 {
42 	uint8_t id;
43 	QDF_STATUS status = QDF_STATUS_SUCCESS;
44 
45 	wlan_peer_obj_lock(peer);
46 	/* Iterate through all components to derive the object status */
47 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
48 		/* If component disabled, Ignore */
49 		if (peer->obj_status[id] == QDF_STATUS_COMP_DISABLED)
50 			continue;
51 		/* If component operates in Async, status is Partially created,
52 			break */
53 		else if (peer->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
54 			if (!peer->peer_comp_priv_obj[id]) {
55 				status = QDF_STATUS_COMP_ASYNC;
56 				break;
57 			}
58 		/* If component failed to allocate its object, treat it as
59 			failure, complete object need to be cleaned up */
60 		} else if ((peer->obj_status[id] == QDF_STATUS_E_NOMEM) ||
61 			(peer->obj_status[id] == QDF_STATUS_E_FAILURE)) {
62 			obj_mgr_err("Peer comp object(id:%d) alloc fail", id);
63 			status = QDF_STATUS_E_FAILURE;
64 			break;
65 		}
66 	}
67 	wlan_peer_obj_unlock(peer);
68 	return status;
69 }
70 
71 static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer)
72 {
73 	struct wlan_objmgr_psoc *psoc;
74 	struct wlan_objmgr_vdev *vdev;
75 	uint8_t *macaddr;
76 	uint8_t vdev_id;
77 	bool peer_free_notify = true;
78 
79 	if (!peer) {
80 		obj_mgr_err("PEER is NULL");
81 		return QDF_STATUS_E_FAILURE;
82 	}
83 
84 	macaddr = wlan_peer_get_macaddr(peer);
85 
86 	vdev = wlan_peer_get_vdev(peer);
87 	if (!vdev) {
88 		obj_mgr_err(
89 			"VDEV is NULL for peer("QDF_MAC_ADDR_FMT")",
90 				QDF_MAC_ADDR_REF(macaddr));
91 		return QDF_STATUS_E_FAILURE;
92 	}
93 
94 	/* Notify peer free only for non self peer*/
95 	if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
96 			 wlan_vdev_mlme_get_macaddr(vdev)) ==
97 				QDF_STATUS_SUCCESS)
98 		peer_free_notify = false;
99 
100 	vdev_id = wlan_vdev_get_id(vdev);
101 
102 	/* get PSOC from VDEV, if it is NULL, return */
103 	psoc = wlan_vdev_get_psoc(vdev);
104 	if (!psoc) {
105 		obj_mgr_err(
106 			"PSOC is NULL for peer("QDF_MAC_ADDR_FMT")",
107 				QDF_MAC_ADDR_REF(macaddr));
108 		return QDF_STATUS_E_FAILURE;
109 	}
110 
111 	/* Decrement ref count for BSS peer, so that BSS peer deletes last*/
112 	if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) ||
113 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP) ||
114 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_CLI))
115 		wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev),
116 					     WLAN_OBJMGR_ID);
117 
118 	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
119 
120 	/* Detach peer from VDEV's peer list */
121 	if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) {
122 		obj_mgr_err(
123 		"Peer("QDF_MAC_ADDR_FMT") VDEV detach fail, vdev id: %d",
124 			QDF_MAC_ADDR_REF(macaddr), vdev_id);
125 		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
126 		return QDF_STATUS_E_FAILURE;
127 	}
128 	/* Detach peer from PSOC's peer list */
129 	if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) {
130 		obj_mgr_err(
131 		"Peer("QDF_MAC_ADDR_FMT") PSOC detach failure",
132 			QDF_MAC_ADDR_REF(macaddr));
133 		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
134 		return QDF_STATUS_E_FAILURE;
135 	}
136 	wlan_objmgr_peer_trace_del_ref_list(peer);
137 	wlan_objmgr_peer_trace_deinit_lock(peer);
138 	qdf_spinlock_destroy(&peer->peer_lock);
139 	qdf_mem_free(peer);
140 
141 	if (peer_free_notify)
142 		wlan_objmgr_vdev_peer_freed_notify(vdev);
143 
144 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
145 
146 	return QDF_STATUS_SUCCESS;
147 
148 }
149 
150 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
151 static void
152 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer)
153 {
154 	uint8_t id;
155 
156 	for (id = 0; id < WLAN_REF_ID_MAX; id++)
157 		qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]);
158 }
159 #else
160 static inline void
161 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) {}
162 #endif
163 
164 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
165 			struct wlan_objmgr_vdev *vdev,
166 			enum wlan_peer_type type,
167 			uint8_t *macaddr)
168 {
169 	struct wlan_objmgr_peer *peer;
170 	struct wlan_objmgr_psoc *psoc;
171 	wlan_objmgr_peer_create_handler handler;
172 	wlan_objmgr_peer_status_handler stat_handler;
173 	void *arg;
174 	QDF_STATUS obj_status;
175 	uint8_t id;
176 
177 	if (!vdev) {
178 		obj_mgr_err(
179 			"VDEV is NULL for peer ("QDF_MAC_ADDR_FMT")",
180 				QDF_MAC_ADDR_REF(macaddr));
181 		return NULL;
182 	}
183 	/* Get psoc, if psoc is NULL, return */
184 	psoc = wlan_vdev_get_psoc(vdev);
185 	if (!psoc) {
186 		obj_mgr_err(
187 			"PSOC is NULL for peer ("QDF_MAC_ADDR_FMT")",
188 				QDF_MAC_ADDR_REF(macaddr));
189 		return NULL;
190 	}
191 	/* Allocate memory for peer object */
192 	peer = qdf_mem_malloc(sizeof(*peer));
193 	if (!peer)
194 		return NULL;
195 
196 	peer->obj_state = WLAN_OBJ_STATE_ALLOCATED;
197 	qdf_atomic_init(&peer->peer_objmgr.ref_cnt);
198 	wlan_objmgr_peer_init_ref_id_debug(peer);
199 	wlan_objmgr_peer_trace_init_lock(peer);
200 	wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID);
201 	/* set vdev to peer */
202 	wlan_peer_set_vdev(peer, vdev);
203 	/* set peer type */
204 	wlan_peer_set_peer_type(peer, type);
205 	/* set mac address of peer */
206 	wlan_peer_set_macaddr(peer, macaddr);
207 	/* initialize peer state */
208 	wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE);
209 	wlan_peer_mlme_reset_seq_num(peer);
210 	peer->peer_objmgr.print_cnt = 0;
211 
212 	qdf_spinlock_create(&peer->peer_lock);
213 	/* Attach peer to psoc, psoc maintains the node table for the device */
214 	if (wlan_objmgr_psoc_peer_attach(psoc, peer) !=
215 					QDF_STATUS_SUCCESS) {
216 		obj_mgr_warn(
217 		"Peer("QDF_MAC_ADDR_FMT") PSOC attach failure",
218 				QDF_MAC_ADDR_REF(macaddr));
219 		qdf_spinlock_destroy(&peer->peer_lock);
220 		wlan_objmgr_peer_trace_deinit_lock(peer);
221 		qdf_mem_free(peer);
222 		return NULL;
223 	}
224 	/* Attach peer to vdev peer table */
225 	if (wlan_objmgr_vdev_peer_attach(vdev, peer) !=
226 					QDF_STATUS_SUCCESS) {
227 		obj_mgr_warn(
228 		"Peer("QDF_MAC_ADDR_FMT") VDEV attach failure",
229 				QDF_MAC_ADDR_REF(macaddr));
230 		/* if attach fails, detach from psoc table before free */
231 		wlan_objmgr_psoc_peer_detach(psoc, peer);
232 		qdf_spinlock_destroy(&peer->peer_lock);
233 		wlan_objmgr_peer_trace_deinit_lock(peer);
234 		qdf_mem_free(peer);
235 		return NULL;
236 	}
237 	wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id(
238 			wlan_vdev_get_pdev(vdev)));
239 	/* Increment ref count for BSS peer, so that BSS peer deletes last*/
240 	if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP)
241 				    || (type == WLAN_PEER_P2P_CLI))
242 		wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev),
243 					 WLAN_OBJMGR_ID);
244 	/* TODO init other parameters */
245 	/* Invoke registered create handlers */
246 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
247 		handler = g_umac_glb_obj->peer_create_handler[id];
248 		arg = g_umac_glb_obj->peer_create_handler_arg[id];
249 		if (handler)
250 			peer->obj_status[id] = handler(peer, arg);
251 		else
252 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
253 	}
254 	/* derive the object status */
255 	obj_status = wlan_objmgr_peer_object_status(peer);
256 	/* If SUCCESS, Object is created */
257 	if (obj_status == QDF_STATUS_SUCCESS) {
258 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
259 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
260 			stat_handler = g_umac_glb_obj->peer_status_handler[id];
261 			arg = g_umac_glb_obj->peer_status_handler_arg[id];
262 			if (stat_handler)
263 				stat_handler(peer, arg,
264 					     QDF_STATUS_SUCCESS);
265 		}
266 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
267 		/* If any component operates in different context, update it
268 		as partially created */
269 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
270 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
271 		/* Clean up the peer */
272 		obj_mgr_err(
273 		"Peer("QDF_MAC_ADDR_FMT") comp object alloc fail",
274 				QDF_MAC_ADDR_REF(macaddr));
275 		wlan_objmgr_peer_obj_delete(peer);
276 		return NULL;
277 	}
278 
279 	obj_mgr_debug("Created peer " QDF_MAC_ADDR_FMT " type %d",
280 		      QDF_MAC_ADDR_REF(macaddr), type);
281 
282 	return peer;
283 }
284 
285 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer)
286 {
287 	uint8_t id;
288 	wlan_objmgr_peer_destroy_handler handler;
289 	QDF_STATUS obj_status;
290 	void *arg;
291 	uint8_t *macaddr;
292 
293 	if (!peer) {
294 		obj_mgr_err("PEER is NULL");
295 		return QDF_STATUS_E_FAILURE;
296 	}
297 	wlan_objmgr_notify_destroy(peer, WLAN_PEER_OP);
298 
299 	macaddr = wlan_peer_get_macaddr(peer);
300 
301 	obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_FMT,
302 		      QDF_MAC_ADDR_REF(macaddr));
303 
304 	if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
305 		obj_mgr_err("PEER object del is not invoked obj_state:%d peer "
306 			    QDF_MAC_ADDR_FMT, peer->obj_state,
307 			    QDF_MAC_ADDR_REF(macaddr));
308 		WLAN_OBJMGR_BUG(0);
309 	}
310 
311 	/* Invoke registered destroy handlers */
312 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
313 		handler = g_umac_glb_obj->peer_destroy_handler[id];
314 		arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
315 		if (handler &&
316 		    (peer->obj_status[id] == QDF_STATUS_SUCCESS ||
317 		     peer->obj_status[id] == QDF_STATUS_COMP_ASYNC))
318 			peer->obj_status[id] = handler(peer, arg);
319 		else
320 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
321 	}
322 	/* Derive the object status */
323 	obj_status = wlan_objmgr_peer_object_status(peer);
324 	if (obj_status == QDF_STATUS_E_FAILURE) {
325 		/* If it status is failure, memory will not be freed */
326 		QDF_BUG(0);
327 		return QDF_STATUS_E_FAILURE;
328 	}
329 	/* few components deletion is in progress */
330 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
331 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
332 		return QDF_STATUS_COMP_ASYNC;
333 	}
334 
335 	/* Free the peer object */
336 	return wlan_objmgr_peer_obj_free(peer);
337 }
338 
339 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer)
340 {
341 	uint8_t print_idx;
342 	uint8_t *macaddr;
343 
344 	if (!peer) {
345 		obj_mgr_err("PEER is NULL");
346 		return QDF_STATUS_E_FAILURE;
347 	}
348 
349 	wlan_peer_obj_lock(peer);
350 	macaddr = wlan_peer_get_macaddr(peer);
351 	wlan_peer_obj_unlock(peer);
352 
353 	obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_FMT,
354 		      QDF_MAC_ADDR_REF(macaddr));
355 
356 	print_idx = qdf_get_pidx();
357 	wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_DEBUG);
358 	/**
359 	 * Update VDEV object state to LOGICALLY DELETED
360 	 * It prevents further access of this object
361 	 */
362 	wlan_peer_obj_lock(peer);
363 	peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
364 	wlan_peer_obj_unlock(peer);
365 	wlan_objmgr_notify_log_delete(peer, WLAN_PEER_OP);
366 	wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID);
367 
368 	return QDF_STATUS_SUCCESS;
369 }
370 qdf_export_symbol(wlan_objmgr_peer_obj_delete);
371 /**
372  ** APIs to attach/detach component objects
373  */
374 QDF_STATUS wlan_objmgr_peer_component_obj_attach(
375 		struct wlan_objmgr_peer *peer,
376 		enum wlan_umac_comp_id id,
377 		void *comp_priv_obj,
378 		QDF_STATUS status)
379 {
380 	wlan_objmgr_peer_status_handler s_hler;
381 	void *arg;
382 	uint8_t i;
383 	QDF_STATUS obj_status;
384 
385 	/* component id is invalid */
386 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
387 		return QDF_STATUS_MAXCOMP_FAIL;
388 
389 	wlan_peer_obj_lock(peer);
390 	/* If there is a valid entry, return failure,
391 	valid object needs to be freed first */
392 	if (peer->peer_comp_priv_obj[id]) {
393 		wlan_peer_obj_unlock(peer);
394 		return QDF_STATUS_E_FAILURE;
395 	}
396 	/* Assign component object private pointer(can be NULL also), status */
397 	peer->peer_comp_priv_obj[id] = comp_priv_obj;
398 	peer->obj_status[id] = status;
399 	wlan_peer_obj_unlock(peer);
400 
401 	if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
402 		return QDF_STATUS_SUCCESS;
403 
404 	/* If PEER object status is partially created means, this API is
405 	invoked with differnt context. this block should be executed for async
406 	components only */
407 	/* Derive status */
408 	obj_status = wlan_objmgr_peer_object_status(peer);
409 	/* STATUS_SUCCESS means, object is CREATED */
410 	if (obj_status == QDF_STATUS_SUCCESS)
411 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
412 	/* update state as CREATION failed, caller has to delete the
413 	PEER object */
414 	else if (obj_status == QDF_STATUS_E_FAILURE)
415 		peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
416 	/* Notify components about the CREATION success/failure */
417 	if ((obj_status == QDF_STATUS_SUCCESS) ||
418 	    (obj_status == QDF_STATUS_E_FAILURE)) {
419 		/* nofity object status */
420 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
421 			s_hler = g_umac_glb_obj->peer_status_handler[i];
422 			arg = g_umac_glb_obj->peer_status_handler_arg[i];
423 			if (s_hler)
424 				s_hler(peer, arg, obj_status);
425 		}
426 	}
427 	return QDF_STATUS_SUCCESS;
428 }
429 
430 QDF_STATUS wlan_objmgr_peer_component_obj_detach(
431 		struct wlan_objmgr_peer *peer,
432 		enum wlan_umac_comp_id id,
433 		void *comp_priv_obj)
434 {
435 	QDF_STATUS obj_status;
436 
437 	/* component id is invalid */
438 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
439 		return QDF_STATUS_MAXCOMP_FAIL;
440 
441 	wlan_peer_obj_lock(peer);
442 	/* If there is a invalid entry, return failure */
443 	if (peer->peer_comp_priv_obj[id] != comp_priv_obj) {
444 		peer->obj_status[id] = QDF_STATUS_E_FAILURE;
445 		wlan_peer_obj_unlock(peer);
446 		return QDF_STATUS_E_FAILURE;
447 	}
448 	/* Reset the pointer to NULL */
449 	peer->peer_comp_priv_obj[id] = NULL;
450 	peer->obj_status[id] = QDF_STATUS_SUCCESS;
451 	wlan_peer_obj_unlock(peer);
452 
453 	/* If PEER object status is partially destroyed means, this API is
454 	invoked with differnt context, this block should be executed for async
455 	components only */
456 	if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
457 	    (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
458 		/* Derive object status */
459 		obj_status = wlan_objmgr_peer_object_status(peer);
460 		if (obj_status == QDF_STATUS_SUCCESS) {
461 			/*Update the status as Deleted, if full object
462 				deletion is in progress */
463 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
464 				peer->obj_state = WLAN_OBJ_STATE_DELETED;
465 			/* Move to creation state, since this component
466 			deletion alone requested */
467 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
468 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
469 		/* Object status is failure */
470 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
471 			/*Update the status as Deletion failed, if full object
472 				deletion is in progress */
473 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
474 				peer->obj_state =
475 					WLAN_OBJ_STATE_DELETION_FAILED;
476 			/* Move to creation state, since this component
477 			deletion alone requested (do not block other
478 			components) */
479 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
480 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
481 		}
482 
483 			/* Delete peer object */
484 		if ((obj_status == QDF_STATUS_SUCCESS)  &&
485 		    (peer->obj_state == WLAN_OBJ_STATE_DELETED)) {
486 			/* Free the peer object */
487 			return wlan_objmgr_peer_obj_free(peer);
488 		}
489 	}
490 
491 	return QDF_STATUS_SUCCESS;
492 }
493 
494 
495 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation(
496 		struct wlan_objmgr_peer *peer,
497 		enum wlan_umac_comp_id id)
498 {
499 	wlan_objmgr_peer_create_handler handler;
500 	void *arg;
501 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
502 
503 	/* Component id is invalid */
504 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
505 		return QDF_STATUS_MAXCOMP_FAIL;
506 
507 	wlan_peer_obj_lock(peer);
508 	/* If component object is already created, delete old
509 		component object, then invoke creation */
510 	if (peer->peer_comp_priv_obj[id]) {
511 		wlan_peer_obj_unlock(peer);
512 		return QDF_STATUS_E_FAILURE;
513 	}
514 	wlan_peer_obj_unlock(peer);
515 
516 	/* Invoke registered create handlers */
517 	handler = g_umac_glb_obj->peer_create_handler[id];
518 	arg = g_umac_glb_obj->peer_create_handler_arg[id];
519 	if (handler)
520 		peer->obj_status[id] = handler(peer, arg);
521 	else
522 		return QDF_STATUS_E_FAILURE;
523 
524 	/* If object status is created, then only handle this object status */
525 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
526 		/* Derive object status */
527 		obj_status = wlan_objmgr_peer_object_status(peer);
528 		/* Move PDEV object state to Partially created state */
529 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
530 			/*TODO atomic */
531 			peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
532 		}
533 	}
534 
535 	return obj_status;
536 }
537 
538 
539 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion(
540 		struct wlan_objmgr_peer *peer,
541 		enum wlan_umac_comp_id id)
542 {
543 	wlan_objmgr_peer_destroy_handler handler;
544 	void *arg;
545 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
546 
547 	/* component id is invalid */
548 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
549 		return QDF_STATUS_MAXCOMP_FAIL;
550 
551 	wlan_peer_obj_lock(peer);
552 	/* Component object was never created, invalid operation */
553 	if (!peer->peer_comp_priv_obj[id]) {
554 		wlan_peer_obj_unlock(peer);
555 		return QDF_STATUS_E_FAILURE;
556 	}
557 
558 	wlan_peer_obj_unlock(peer);
559 
560 	/* Invoke registered destroy handlers */
561 	handler = g_umac_glb_obj->peer_destroy_handler[id];
562 	arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
563 	if (handler)
564 		peer->obj_status[id] = handler(peer, arg);
565 	else
566 		return QDF_STATUS_E_FAILURE;
567 
568 	/* If object status is created, then only handle this object status */
569 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
570 		obj_status = wlan_objmgr_peer_object_status(peer);
571 			/* move object state to DEL progress */
572 		if (obj_status == QDF_STATUS_COMP_ASYNC)
573 			peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
574 	}
575 	return obj_status;
576 }
577 
578 void *wlan_objmgr_peer_get_comp_private_obj(
579 		struct wlan_objmgr_peer *peer,
580 		enum wlan_umac_comp_id id)
581 {
582 	void *comp_priv_obj;
583 
584 	/* component id is invalid */
585 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
586 		QDF_BUG(0);
587 		return NULL;
588 	}
589 
590 	if (!peer) {
591 		QDF_BUG(0);
592 		return NULL;
593 	}
594 
595 	comp_priv_obj = peer->peer_comp_priv_obj[id];
596 	return comp_priv_obj;
597 }
598 qdf_export_symbol(wlan_objmgr_peer_get_comp_private_obj);
599 
600 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
601 static inline void
602 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer,
603 				  wlan_objmgr_ref_dbgid id)
604 {
605 	qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]);
606 }
607 #else
608 static inline void
609 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer,
610 				  wlan_objmgr_ref_dbgid id) {}
611 #endif
612 
613 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
614 static QDF_STATUS
615 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer,
616 				      wlan_objmgr_ref_dbgid id)
617 {
618 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) {
619 		uint8_t *macaddr;
620 
621 		macaddr = wlan_peer_get_macaddr(peer);
622 		obj_mgr_err(
623 		"peer("QDF_MAC_ADDR_FMT") ref was not taken by %d",
624 			QDF_MAC_ADDR_REF(macaddr), id);
625 		wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg,
626 					  QDF_TRACE_LEVEL_FATAL);
627 		WLAN_OBJMGR_BUG(0);
628 		return QDF_STATUS_E_FAILURE;
629 	}
630 
631 	qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]);
632 	return QDF_STATUS_SUCCESS;
633 }
634 #else
635 static QDF_STATUS
636 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer,
637 				      wlan_objmgr_ref_dbgid id)
638 {
639 	return QDF_STATUS_SUCCESS;
640 }
641 #endif
642 
643 #ifdef WLAN_OBJMGR_REF_ID_TRACE
644 static inline void
645 wlan_objmgr_peer_ref_trace(struct wlan_objmgr_peer *peer,
646 			   wlan_objmgr_ref_dbgid id,
647 			   const char *func, int line)
648 {
649 	struct wlan_objmgr_trace *trace;
650 
651 	trace = &peer->peer_objmgr.trace;
652 
653 	if (func)
654 		wlan_objmgr_trace_ref(&trace->references[id].head,
655 				      trace, func, line);
656 }
657 
658 static inline void
659 wlan_objmgr_peer_deref_trace(struct wlan_objmgr_peer *peer,
660 			     wlan_objmgr_ref_dbgid id,
661 			     const char *func, int line)
662 {
663 	struct wlan_objmgr_trace *trace;
664 
665 	trace = &peer->peer_objmgr.trace;
666 	if (func)
667 		wlan_objmgr_trace_ref(&trace->dereferences[id].head,
668 				      trace, func, line);
669 }
670 #endif
671 
672 #ifdef WLAN_OBJMGR_REF_ID_TRACE
673 void wlan_objmgr_peer_get_ref_debug(struct wlan_objmgr_peer *peer,
674 				    wlan_objmgr_ref_dbgid id,
675 				    const char *func, int line)
676 {
677 	if (!peer) {
678 		obj_mgr_err("peer obj is NULL for %d", id);
679 		QDF_ASSERT(0);
680 		return;
681 	}
682 	/* Increment ref count */
683 	qdf_atomic_inc(&peer->peer_objmgr.ref_cnt);
684 	wlan_objmgr_peer_get_debug_id_ref(peer, id);
685 
686 	wlan_objmgr_peer_ref_trace(peer, id, func, line);
687 	return;
688 }
689 
690 qdf_export_symbol(wlan_objmgr_peer_get_ref_debug);
691 #else
692 void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer,
693 			      wlan_objmgr_ref_dbgid id)
694 {
695 	if (!peer) {
696 		obj_mgr_err("peer obj is NULL for %d", id);
697 		QDF_ASSERT(0);
698 		return;
699 	}
700 	/* Increment ref count */
701 	qdf_atomic_inc(&peer->peer_objmgr.ref_cnt);
702 	wlan_objmgr_peer_get_debug_id_ref(peer, id);
703 }
704 
705 qdf_export_symbol(wlan_objmgr_peer_get_ref);
706 #endif
707 
708 #ifdef WLAN_OBJMGR_REF_ID_TRACE
709 QDF_STATUS wlan_objmgr_peer_try_get_ref_debug(struct wlan_objmgr_peer *peer,
710 					      wlan_objmgr_ref_dbgid id,
711 					      const char *func, int line)
712 {
713 	if (!peer) {
714 		obj_mgr_err("peer obj is NULL for %d", id);
715 		QDF_ASSERT(0);
716 		return QDF_STATUS_E_FAILURE;
717 	}
718 
719 	wlan_peer_obj_lock(peer);
720 	if (peer->obj_state != WLAN_OBJ_STATE_CREATED) {
721 		wlan_peer_obj_unlock(peer);
722 		if (peer->peer_objmgr.print_cnt++ <=
723 				WLAN_OBJMGR_RATELIMIT_THRESH) {
724 			uint8_t *macaddr;
725 
726 			macaddr = wlan_peer_get_macaddr(peer);
727 			obj_mgr_debug(
728 			"peer(" QDF_MAC_ADDR_FMT ") not in Created st(%d)",
729 			QDF_MAC_ADDR_REF(macaddr),
730 			peer->obj_state);
731 		}
732 		return QDF_STATUS_E_RESOURCES;
733 	}
734 
735 	wlan_objmgr_peer_get_ref_debug(peer, id, func, line);
736 	wlan_peer_obj_unlock(peer);
737 
738 	return QDF_STATUS_SUCCESS;
739 }
740 
741 qdf_export_symbol(wlan_objmgr_peer_try_get_ref_debug);
742 #else
743 QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer,
744 					wlan_objmgr_ref_dbgid id)
745 {
746 	if (!peer) {
747 		obj_mgr_err("peer obj is NULL for %d", id);
748 		QDF_ASSERT(0);
749 		return QDF_STATUS_E_FAILURE;
750 	}
751 
752 	wlan_peer_obj_lock(peer);
753 	if (peer->obj_state != WLAN_OBJ_STATE_CREATED) {
754 		wlan_peer_obj_unlock(peer);
755 		if (peer->peer_objmgr.print_cnt++ <=
756 				WLAN_OBJMGR_RATELIMIT_THRESH) {
757 			uint8_t *macaddr;
758 
759 			macaddr = wlan_peer_get_macaddr(peer);
760 			obj_mgr_debug(
761 			"peer(" QDF_MAC_ADDR_FMT ") not in Created st(%d)",
762 			QDF_MAC_ADDR_REF(macaddr),
763 			peer->obj_state);
764 		}
765 		return QDF_STATUS_E_RESOURCES;
766 	}
767 
768 	wlan_objmgr_peer_get_ref(peer, id);
769 	wlan_peer_obj_unlock(peer);
770 
771 	return QDF_STATUS_SUCCESS;
772 }
773 
774 qdf_export_symbol(wlan_objmgr_peer_try_get_ref);
775 #endif
776 
777 #ifdef WLAN_OBJMGR_REF_ID_TRACE
778 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc_debug(
779 					struct wlan_peer_list *peer_list,
780 					uint8_t hash_index,
781 					struct wlan_objmgr_peer *peer,
782 					wlan_objmgr_ref_dbgid dbg_id,
783 					const char *func, int line)
784 {
785 	struct wlan_objmgr_peer *peer_next = NULL;
786 	qdf_list_node_t *psoc_node = NULL;
787 	qdf_list_node_t *prev_psoc_node = NULL;
788 	qdf_list_t *obj_list;
789 
790 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
791 	obj_list = &peer_list->peer_hash[hash_index];
792 
793 	prev_psoc_node = &peer->psoc_peer;
794 	while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) ==
795 						QDF_STATUS_SUCCESS) {
796 		peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer,
797 					     psoc_peer);
798 
799 		if (wlan_objmgr_peer_try_get_ref_debug(peer_next, dbg_id,
800 						       func, line) ==
801 				QDF_STATUS_SUCCESS) {
802 			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
803 			return peer_next;
804 		}
805 
806 		prev_psoc_node = psoc_node;
807 	}
808 
809 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
810 
811 	return NULL;
812 }
813 #else
814 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc(
815 					struct wlan_peer_list *peer_list,
816 					uint8_t hash_index,
817 					struct wlan_objmgr_peer *peer,
818 					wlan_objmgr_ref_dbgid dbg_id)
819 {
820 	struct wlan_objmgr_peer *peer_next = NULL;
821 	qdf_list_node_t *psoc_node = NULL;
822 	qdf_list_node_t *prev_psoc_node = NULL;
823 	qdf_list_t *obj_list;
824 
825 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
826 	obj_list = &peer_list->peer_hash[hash_index];
827 
828 	prev_psoc_node = &peer->psoc_peer;
829 	while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) ==
830 						QDF_STATUS_SUCCESS) {
831 		peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer,
832 					     psoc_peer);
833 
834 		if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) ==
835 				QDF_STATUS_SUCCESS) {
836 			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
837 			return peer_next;
838 		}
839 
840 		prev_psoc_node = psoc_node;
841 	}
842 
843 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
844 
845 	return NULL;
846 }
847 #endif
848 
849 #ifdef WLAN_OBJMGR_REF_ID_TRACE
850 struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head_debug(
851 				struct wlan_objmgr_vdev *vdev,
852 				qdf_list_t *peer_list,
853 				wlan_objmgr_ref_dbgid dbg_id,
854 				const char *func, int line)
855 {
856 	struct wlan_objmgr_peer *peer;
857 	qdf_list_node_t *vdev_node = NULL;
858 	qdf_list_node_t *prev_vdev_node = NULL;
859 
860 	wlan_vdev_obj_lock(vdev);
861 
862 	if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) {
863 		wlan_vdev_obj_unlock(vdev);
864 		return NULL;
865 	}
866 
867 	do {
868 		peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer,
869 					vdev_peer);
870 
871 		if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id,
872 						       func, line) ==
873 				QDF_STATUS_SUCCESS) {
874 			wlan_vdev_obj_unlock(vdev);
875 			return peer;
876 		}
877 
878 		prev_vdev_node = vdev_node;
879 	} while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) ==
880 							QDF_STATUS_SUCCESS);
881 
882 	wlan_vdev_obj_unlock(vdev);
883 
884 	return NULL;
885 }
886 #else
887 struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head(
888 				struct wlan_objmgr_vdev *vdev,
889 				qdf_list_t *peer_list,
890 				wlan_objmgr_ref_dbgid dbg_id)
891 {
892 	struct wlan_objmgr_peer *peer;
893 	qdf_list_node_t *vdev_node = NULL;
894 	qdf_list_node_t *prev_vdev_node = NULL;
895 
896 	wlan_vdev_obj_lock(vdev);
897 
898 	if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) {
899 		wlan_vdev_obj_unlock(vdev);
900 		return NULL;
901 	}
902 
903 	do {
904 		peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer,
905 						vdev_peer);
906 
907 		if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
908 				QDF_STATUS_SUCCESS) {
909 			wlan_vdev_obj_unlock(vdev);
910 			return peer;
911 		}
912 
913 		prev_vdev_node = vdev_node;
914 	} while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) ==
915 							QDF_STATUS_SUCCESS);
916 
917 	wlan_vdev_obj_unlock(vdev);
918 
919 	return NULL;
920 }
921 #endif
922 
923 #ifdef WLAN_OBJMGR_REF_ID_TRACE
924 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev_debug(
925 					struct wlan_objmgr_vdev *vdev,
926 					qdf_list_t *peer_list,
927 					struct wlan_objmgr_peer *peer,
928 					wlan_objmgr_ref_dbgid dbg_id,
929 					const char *func, int line)
930 {
931 	struct wlan_objmgr_peer *peer_next;
932 	qdf_list_node_t *vdev_node = NULL;
933 	qdf_list_node_t *prev_vdev_node = NULL;
934 
935 	if (!peer)
936 		return NULL;
937 
938 	wlan_vdev_obj_lock(vdev);
939 
940 	prev_vdev_node = &peer->vdev_peer;
941 	while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) ==
942 						QDF_STATUS_SUCCESS) {
943 		peer_next = qdf_container_of(vdev_node, struct wlan_objmgr_peer,
944 					     vdev_peer);
945 
946 		if (wlan_objmgr_peer_try_get_ref_debug(peer_next, dbg_id,
947 						       func, line) ==
948 				QDF_STATUS_SUCCESS) {
949 			wlan_vdev_obj_unlock(vdev);
950 			return peer_next;
951 		}
952 
953 		prev_vdev_node = vdev_node;
954 	}
955 
956 	wlan_vdev_obj_unlock(vdev);
957 
958 	return NULL;
959 }
960 #else
961 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev(
962 					struct wlan_objmgr_vdev *vdev,
963 					qdf_list_t *peer_list,
964 					struct wlan_objmgr_peer *peer,
965 					wlan_objmgr_ref_dbgid dbg_id)
966 {
967 	struct wlan_objmgr_peer *peer_next;
968 	qdf_list_node_t *vdev_node = NULL;
969 	qdf_list_node_t *prev_vdev_node = NULL;
970 
971 	if (!peer)
972 		return NULL;
973 
974 	wlan_vdev_obj_lock(vdev);
975 
976 	prev_vdev_node = &peer->vdev_peer;
977 	while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) ==
978 						QDF_STATUS_SUCCESS) {
979 		peer_next = qdf_container_of(vdev_node, struct wlan_objmgr_peer,
980 					vdev_peer);
981 
982 		if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) ==
983 				QDF_STATUS_SUCCESS) {
984 			wlan_vdev_obj_unlock(vdev);
985 			return peer_next;
986 		}
987 
988 		prev_vdev_node = vdev_node;
989 	}
990 
991 	wlan_vdev_obj_unlock(vdev);
992 
993 	return NULL;
994 }
995 #endif
996 
997 #ifdef WLAN_OBJMGR_REF_ID_TRACE
998 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head_debug(
999 					struct wlan_peer_list *peer_list,
1000 					uint8_t hash_index,
1001 					wlan_objmgr_ref_dbgid dbg_id,
1002 					const char *func, int line)
1003 {
1004 	struct wlan_objmgr_peer *peer;
1005 	qdf_list_node_t *psoc_node = NULL;
1006 	qdf_list_node_t *prev_psoc_node = NULL;
1007 	qdf_list_t *obj_list;
1008 
1009 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1010 	obj_list = &peer_list->peer_hash[hash_index];
1011 
1012 	if (qdf_list_peek_front(obj_list, &psoc_node) != QDF_STATUS_SUCCESS) {
1013 		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1014 		return NULL;
1015 	}
1016 
1017 	do {
1018 		peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer,
1019 					psoc_peer);
1020 		if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id,
1021 						       func, line) ==
1022 				QDF_STATUS_SUCCESS) {
1023 			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1024 			return peer;
1025 		}
1026 
1027 		prev_psoc_node = psoc_node;
1028 	} while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) ==
1029 						QDF_STATUS_SUCCESS);
1030 
1031 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1032 	return NULL;
1033 }
1034 #else
1035 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head(
1036 					struct wlan_peer_list *peer_list,
1037 					uint8_t hash_index,
1038 					wlan_objmgr_ref_dbgid dbg_id)
1039 {
1040 	struct wlan_objmgr_peer *peer;
1041 	qdf_list_node_t *psoc_node = NULL;
1042 	qdf_list_node_t *prev_psoc_node = NULL;
1043 	qdf_list_t *obj_list;
1044 
1045 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1046 	obj_list = &peer_list->peer_hash[hash_index];
1047 
1048 	if (qdf_list_peek_front(obj_list, &psoc_node) != QDF_STATUS_SUCCESS) {
1049 		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1050 		return NULL;
1051 	}
1052 
1053 	do {
1054 		peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer,
1055 						psoc_peer);
1056 		if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
1057 				QDF_STATUS_SUCCESS) {
1058 			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1059 			return peer;
1060 		}
1061 
1062 		prev_psoc_node = psoc_node;
1063 	} while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) ==
1064 						QDF_STATUS_SUCCESS);
1065 
1066 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1067 	return NULL;
1068 }
1069 #endif
1070 
1071 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1072 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref_debug(
1073 					struct wlan_peer_list *peer_list,
1074 					uint8_t hash_index,
1075 					wlan_objmgr_ref_dbgid dbg_id,
1076 					const char *func, int line)
1077 {
1078 	struct wlan_objmgr_peer *peer;
1079 	qdf_list_t *obj_list;
1080 
1081 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1082 	obj_list = &peer_list->peer_hash[hash_index];
1083 
1084 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1085 
1086 	/* This API is invoked by caller, only when caller need to access the
1087 	 * peer object, though object is not in active state, this API should be
1088 	 * used carefully, where multiple object frees are not triggered
1089 	 */
1090 	if (peer)
1091 		wlan_objmgr_peer_get_ref_debug(peer, dbg_id, func, line);
1092 
1093 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1094 
1095 	return peer;
1096 }
1097 #else
1098 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref(
1099 					struct wlan_peer_list *peer_list,
1100 					uint8_t hash_index,
1101 					wlan_objmgr_ref_dbgid dbg_id)
1102 {
1103 	struct wlan_objmgr_peer *peer;
1104 	qdf_list_t *obj_list;
1105 
1106 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1107 	obj_list = &peer_list->peer_hash[hash_index];
1108 
1109 	peer = wlan_psoc_peer_list_peek_head(obj_list);
1110 
1111 	/* This API is invoked by caller, only when caller need to access the
1112 	 * peer object, though object is not in active state, this API should be
1113 	 * used carefully, where multiple object frees are not triggered
1114 	 */
1115 	if (peer)
1116 		wlan_objmgr_peer_get_ref(peer, dbg_id);
1117 
1118 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1119 
1120 	return peer;
1121 }
1122 #endif
1123 
1124 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1125 struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref_debug(
1126 			struct wlan_peer_list *peer_list, uint8_t hash_index,
1127 			struct wlan_objmgr_peer *peer,
1128 			wlan_objmgr_ref_dbgid dbg_id,
1129 			const char *func, int line)
1130 {
1131 	qdf_list_t *obj_list;
1132 	struct wlan_objmgr_peer *peer_next;
1133 
1134 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1135 	obj_list = &peer_list->peer_hash[hash_index];
1136 
1137 	peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer);
1138 	/* This API is invoked by caller, only when caller need to access the
1139 	 * peer object, though object is not in active state, this API should be
1140 	 * used carefully, where multiple free on object are not triggered
1141 	 */
1142 	if (peer_next)
1143 		wlan_objmgr_peer_get_ref_debug(peer_next, dbg_id, func, line);
1144 
1145 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1146 
1147 	return peer_next;
1148 }
1149 #else
1150 struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref(
1151 			struct wlan_peer_list *peer_list, uint8_t hash_index,
1152 			struct wlan_objmgr_peer *peer,
1153 			wlan_objmgr_ref_dbgid dbg_id)
1154 {
1155 	qdf_list_t *obj_list;
1156 	struct wlan_objmgr_peer *peer_next;
1157 
1158 	qdf_spin_lock_bh(&peer_list->peer_list_lock);
1159 	obj_list = &peer_list->peer_hash[hash_index];
1160 
1161 	peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer);
1162 	/* This API is invoked by caller, only when caller need to access the
1163 	 * peer object, though object is not in active state, this API should be
1164 	 * used carefully, where multiple free on object are not triggered
1165 	 */
1166 	if (peer_next)
1167 		wlan_objmgr_peer_get_ref(peer_next, dbg_id);
1168 
1169 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
1170 
1171 	return peer_next;
1172 }
1173 #endif
1174 
1175 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1176 void wlan_objmgr_peer_release_ref_debug(struct wlan_objmgr_peer *peer,
1177 					wlan_objmgr_ref_dbgid id,
1178 					const char *func, int line)
1179 {
1180 	QDF_STATUS status;
1181 
1182 	if (!peer) {
1183 		obj_mgr_err("peer obj is NULL for %d", id);
1184 		QDF_ASSERT(0);
1185 		return;
1186 	}
1187 
1188 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
1189 		uint8_t *macaddr;
1190 
1191 		macaddr = wlan_peer_get_macaddr(peer);
1192 		obj_mgr_err("peer("QDF_MAC_ADDR_FMT") ref cnt is 0",
1193 				QDF_MAC_ADDR_REF(macaddr));
1194 		WLAN_OBJMGR_BUG(0);
1195 		return;
1196 	}
1197 
1198 	status = wlan_objmgr_peer_release_debug_id_ref(peer, id);
1199 	if (QDF_IS_STATUS_ERROR(status))
1200 		return;
1201 
1202 	wlan_objmgr_peer_deref_trace(peer, id, func, line);
1203 	/* Provide synchronization from the access to add peer
1204 	 * to logically deleted peer list.
1205 	 */
1206 	wlan_peer_obj_lock(peer);
1207 	/* Decrement ref count, free peer object, if ref count == 0 */
1208 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
1209 		wlan_peer_obj_unlock(peer);
1210 		wlan_objmgr_peer_obj_destroy(peer);
1211 	} else {
1212 		wlan_peer_obj_unlock(peer);
1213 	}
1214 
1215 	return;
1216 }
1217 
1218 qdf_export_symbol(wlan_objmgr_peer_release_ref_debug);
1219 #else
1220 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer,
1221 				  wlan_objmgr_ref_dbgid id)
1222 {
1223 	QDF_STATUS status;
1224 
1225 	if (!peer) {
1226 		obj_mgr_err("peer obj is NULL for %d", id);
1227 		QDF_ASSERT(0);
1228 		return;
1229 	}
1230 
1231 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
1232 		uint8_t *macaddr;
1233 
1234 		macaddr = wlan_peer_get_macaddr(peer);
1235 		obj_mgr_err("peer("QDF_MAC_ADDR_FMT") ref cnt is 0",
1236 			    QDF_MAC_ADDR_REF(macaddr));
1237 		WLAN_OBJMGR_BUG(0);
1238 		return;
1239 	}
1240 
1241 	status = wlan_objmgr_peer_release_debug_id_ref(peer, id);
1242 	if (QDF_IS_STATUS_ERROR(status))
1243 		return;
1244 
1245 	/* Provide synchronization from the access to add peer
1246 	 * to logically deleted peer list.
1247 	 */
1248 	wlan_peer_obj_lock(peer);
1249 	/* Decrement ref count, free peer object, if ref count == 0 */
1250 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
1251 		wlan_peer_obj_unlock(peer);
1252 		wlan_objmgr_peer_obj_destroy(peer);
1253 	} else {
1254 		wlan_peer_obj_unlock(peer);
1255 	}
1256 }
1257 
1258 qdf_export_symbol(wlan_objmgr_peer_release_ref);
1259 #endif
1260 
1261 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
1262 void
1263 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer,
1264 			       QDF_TRACE_LEVEL log_level)
1265 {
1266 	wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, log_level);
1267 }
1268 
1269 uint32_t
1270 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer,
1271 				  enum wlan_umac_comp_id id)
1272 {
1273 	return qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id]);
1274 }
1275 #else
1276 void
1277 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer,
1278 			       QDF_TRACE_LEVEL log_level)
1279 {
1280 	uint32_t pending_ref;
1281 
1282 	pending_ref = qdf_atomic_read(&peer->peer_objmgr.ref_cnt);
1283 	obj_mgr_log_level(log_level, "Pending refs -- %d", pending_ref);
1284 }
1285 
1286 uint32_t
1287 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer,
1288 				  enum wlan_umac_comp_id id)
1289 {
1290 	return 0;
1291 }
1292 #endif
1293