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