xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c (revision bea437e2293c3d4fb1b5704fcf633aedac996962)
1 /*
2  * Copyright (c) 2016-2019 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 <qdf_mem.h>
28 #include <qdf_module.h>
29 #include "wlan_objmgr_global_obj_i.h"
30 #include "wlan_objmgr_psoc_obj_i.h"
31 #include "wlan_objmgr_pdev_obj_i.h"
32 #include "wlan_objmgr_vdev_obj_i.h"
33 
34 
35 /**
36  ** APIs to Create/Delete Peer object APIs
37  */
38 static QDF_STATUS wlan_objmgr_peer_object_status(
39 		struct wlan_objmgr_peer *peer)
40 {
41 	uint8_t id;
42 	QDF_STATUS status = QDF_STATUS_SUCCESS;
43 
44 	wlan_peer_obj_lock(peer);
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 (peer->obj_status[id] == QDF_STATUS_COMP_DISABLED)
49 			continue;
50 		/* If component operates in Async, status is Partially created,
51 			break */
52 		else if (peer->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
53 			if (!peer->peer_comp_priv_obj[id]) {
54 				status = QDF_STATUS_COMP_ASYNC;
55 				break;
56 			}
57 		/* If component failed to allocate its object, treat it as
58 			failure, complete object need to be cleaned up */
59 		} else if ((peer->obj_status[id] == QDF_STATUS_E_NOMEM) ||
60 			(peer->obj_status[id] == QDF_STATUS_E_FAILURE)) {
61 			obj_mgr_err("Peer comp object(id:%d) alloc fail", id);
62 			status = QDF_STATUS_E_FAILURE;
63 			break;
64 		}
65 	}
66 	wlan_peer_obj_unlock(peer);
67 	return status;
68 }
69 
70 static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer)
71 {
72 	struct wlan_objmgr_psoc *psoc;
73 	struct wlan_objmgr_vdev *vdev;
74 	uint8_t *macaddr;
75 	uint8_t vdev_id;
76 
77 	if (!peer) {
78 		obj_mgr_err("PEER is NULL");
79 		return QDF_STATUS_E_FAILURE;
80 	}
81 
82 	macaddr = wlan_peer_get_macaddr(peer);
83 
84 	vdev = wlan_peer_get_vdev(peer);
85 	if (!vdev) {
86 		obj_mgr_err(
87 			"VDEV is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)",
88 				macaddr[0], macaddr[1], macaddr[2],
89 				macaddr[3], macaddr[4], macaddr[5]);
90 		return QDF_STATUS_E_FAILURE;
91 	}
92 
93 	vdev_id = wlan_vdev_get_id(vdev);
94 
95 	/* get PSOC from VDEV, if it is NULL, return */
96 	psoc = wlan_vdev_get_psoc(vdev);
97 	if (!psoc) {
98 		obj_mgr_err(
99 			"PSOC is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)",
100 				macaddr[0], macaddr[1], macaddr[2],
101 				macaddr[3], macaddr[4], macaddr[5]);
102 		return QDF_STATUS_E_FAILURE;
103 	}
104 
105 	/* Decrement ref count for BSS peer, so that BSS peer deletes last*/
106 	if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) ||
107 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP) ||
108 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_CLI))
109 		wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev),
110 					     WLAN_OBJMGR_ID);
111 
112 	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
113 
114 	/* Detach peer from VDEV's peer list */
115 	if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) {
116 		obj_mgr_err(
117 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d",
118 			macaddr[0], macaddr[1], macaddr[2],
119 			macaddr[3], macaddr[4], macaddr[5], vdev_id);
120 		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
121 		return QDF_STATUS_E_FAILURE;
122 	}
123 	/* Detach peer from PSOC's peer list */
124 	if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) {
125 		obj_mgr_err(
126 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure",
127 			macaddr[0], macaddr[1], macaddr[2],
128 			macaddr[3], macaddr[4], macaddr[5]);
129 		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
130 		return QDF_STATUS_E_FAILURE;
131 	}
132 	wlan_objmgr_peer_trace_del_ref_list(peer);
133 	wlan_objmgr_peer_trace_deinit_lock(peer);
134 	qdf_spinlock_destroy(&peer->peer_lock);
135 	qdf_mem_free(peer);
136 
137 	wlan_objmgr_vdev_peer_freed_notify(vdev);
138 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
139 
140 	return QDF_STATUS_SUCCESS;
141 
142 }
143 
144 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
145 static void
146 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer)
147 {
148 	uint8_t id;
149 
150 	for (id = 0; id < WLAN_REF_ID_MAX; id++)
151 		qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]);
152 }
153 #else
154 static inline void
155 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) {}
156 #endif
157 
158 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
159 			struct wlan_objmgr_vdev *vdev,
160 			enum wlan_peer_type type,
161 			uint8_t *macaddr)
162 {
163 	struct wlan_objmgr_peer *peer;
164 	struct wlan_objmgr_psoc *psoc;
165 	wlan_objmgr_peer_create_handler handler;
166 	wlan_objmgr_peer_status_handler stat_handler;
167 	void *arg;
168 	QDF_STATUS obj_status;
169 	uint8_t id;
170 
171 	if (!vdev) {
172 		obj_mgr_err(
173 			"VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)",
174 				macaddr[0], macaddr[1], macaddr[2],
175 				macaddr[3], macaddr[4], macaddr[5]);
176 		return NULL;
177 	}
178 	/* Get psoc, if psoc is NULL, return */
179 	psoc = wlan_vdev_get_psoc(vdev);
180 	if (!psoc) {
181 		obj_mgr_err(
182 			"PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)",
183 				macaddr[0], macaddr[1], macaddr[2],
184 				macaddr[3], macaddr[4], macaddr[5]);
185 		return NULL;
186 	}
187 	/* Allocate memory for peer object */
188 	peer = qdf_mem_malloc(sizeof(*peer));
189 	if (!peer)
190 		return NULL;
191 
192 	peer->obj_state = WLAN_OBJ_STATE_ALLOCATED;
193 	qdf_atomic_init(&peer->peer_objmgr.ref_cnt);
194 	wlan_objmgr_peer_init_ref_id_debug(peer);
195 	wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID);
196 	/* set vdev to peer */
197 	wlan_peer_set_vdev(peer, vdev);
198 	/* set peer type */
199 	wlan_peer_set_peer_type(peer, type);
200 	/* set mac address of peer */
201 	wlan_peer_set_macaddr(peer, macaddr);
202 	/* initialize peer state */
203 	wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE);
204 	wlan_peer_mlme_reset_seq_num(peer);
205 	peer->peer_objmgr.print_cnt = 0;
206 
207 	qdf_spinlock_create(&peer->peer_lock);
208 	wlan_objmgr_peer_trace_init_lock(peer);
209 	/* Attach peer to psoc, psoc maintains the node table for the device */
210 	if (wlan_objmgr_psoc_peer_attach(psoc, peer) !=
211 					QDF_STATUS_SUCCESS) {
212 		obj_mgr_warn(
213 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure",
214 				macaddr[0], macaddr[1], macaddr[2],
215 				macaddr[3], macaddr[4], macaddr[5]);
216 		qdf_spinlock_destroy(&peer->peer_lock);
217 		wlan_objmgr_peer_trace_deinit_lock(peer);
218 		qdf_mem_free(peer);
219 		return NULL;
220 	}
221 	/* Attach peer to vdev peer table */
222 	if (wlan_objmgr_vdev_peer_attach(vdev, peer) !=
223 					QDF_STATUS_SUCCESS) {
224 		obj_mgr_warn(
225 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure",
226 				macaddr[0], macaddr[1], macaddr[2],
227 				macaddr[3], macaddr[4], macaddr[5]);
228 		/* if attach fails, detach from psoc table before free */
229 		wlan_objmgr_psoc_peer_detach(psoc, peer);
230 		qdf_spinlock_destroy(&peer->peer_lock);
231 		wlan_objmgr_peer_trace_deinit_lock(peer);
232 		qdf_mem_free(peer);
233 		return NULL;
234 	}
235 	wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id(
236 			wlan_vdev_get_pdev(vdev)));
237 	/* Increment ref count for BSS peer, so that BSS peer deletes last*/
238 	if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP)
239 				    || (type == WLAN_PEER_P2P_CLI))
240 		wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev),
241 					 WLAN_OBJMGR_ID);
242 	/* TODO init other parameters */
243 	/* Invoke registered create handlers */
244 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
245 		handler = g_umac_glb_obj->peer_create_handler[id];
246 		arg = g_umac_glb_obj->peer_create_handler_arg[id];
247 		if (handler)
248 			peer->obj_status[id] = handler(peer, arg);
249 		else
250 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
251 	}
252 	/* derive the object status */
253 	obj_status = wlan_objmgr_peer_object_status(peer);
254 	/* If SUCCESS, Object is created */
255 	if (obj_status == QDF_STATUS_SUCCESS) {
256 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
257 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
258 			stat_handler = g_umac_glb_obj->peer_status_handler[id];
259 			arg = g_umac_glb_obj->peer_status_handler_arg[id];
260 			if (stat_handler)
261 				stat_handler(peer, arg,
262 					     QDF_STATUS_SUCCESS);
263 		}
264 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
265 		/* If any component operates in different context, update it
266 		as partially created */
267 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
268 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
269 		/* Clean up the peer */
270 		obj_mgr_err(
271 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail",
272 				macaddr[0], macaddr[1], macaddr[2],
273 				macaddr[3], macaddr[4], macaddr[5]);
274 		wlan_objmgr_peer_obj_delete(peer);
275 		return NULL;
276 	}
277 
278 	obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR,
279 		      QDF_MAC_ADDR_ARRAY(macaddr));
280 
281 	return peer;
282 }
283 
284 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer)
285 {
286 	uint8_t id;
287 	wlan_objmgr_peer_destroy_handler handler;
288 	QDF_STATUS obj_status;
289 	void *arg;
290 	uint8_t *macaddr;
291 
292 	if (!peer) {
293 		obj_mgr_err("PEER is NULL");
294 		return QDF_STATUS_E_FAILURE;
295 	}
296 	wlan_objmgr_notify_destroy(peer, WLAN_PEER_OP);
297 
298 	macaddr = wlan_peer_get_macaddr(peer);
299 
300 	obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_STR,
301 		      QDF_MAC_ADDR_ARRAY(macaddr));
302 
303 	if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
304 		obj_mgr_err("PEER object del is not invoked obj_state:%d peer "
305 			    QDF_MAC_ADDR_STR, peer->obj_state,
306 			    QDF_MAC_ADDR_ARRAY(macaddr));
307 		WLAN_OBJMGR_BUG(0);
308 	}
309 
310 	/* Invoke registered destroy handlers */
311 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
312 		handler = g_umac_glb_obj->peer_destroy_handler[id];
313 		arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
314 		if (handler &&
315 		    (peer->obj_status[id] == QDF_STATUS_SUCCESS ||
316 		     peer->obj_status[id] == QDF_STATUS_COMP_ASYNC))
317 			peer->obj_status[id] = handler(peer, arg);
318 		else
319 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
320 	}
321 	/* Derive the object status */
322 	obj_status = wlan_objmgr_peer_object_status(peer);
323 	if (obj_status == QDF_STATUS_E_FAILURE) {
324 		/* If it status is failure, memory will not be freed */
325 		QDF_BUG(0);
326 		return QDF_STATUS_E_FAILURE;
327 	}
328 	/* few components deletion is in progress */
329 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
330 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
331 		return QDF_STATUS_COMP_ASYNC;
332 	}
333 
334 	/* Free the peer object */
335 	return wlan_objmgr_peer_obj_free(peer);
336 }
337 
338 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer)
339 {
340 	uint8_t print_idx;
341 	uint8_t *macaddr;
342 
343 	if (!peer) {
344 		obj_mgr_err("PEER is NULL");
345 		return QDF_STATUS_E_FAILURE;
346 	}
347 
348 	wlan_peer_obj_lock(peer);
349 	macaddr = wlan_peer_get_macaddr(peer);
350 	wlan_peer_obj_unlock(peer);
351 
352 	obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_STR,
353 		      QDF_MAC_ADDR_ARRAY(macaddr));
354 
355 	print_idx = qdf_get_pidx();
356 	wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_DEBUG);
357 	/**
358 	 * Update VDEV object state to LOGICALLY DELETED
359 	 * It prevents further access of this object
360 	 */
361 	wlan_peer_obj_lock(peer);
362 	peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
363 	wlan_peer_obj_unlock(peer);
364 	wlan_objmgr_notify_log_delete(peer, WLAN_PEER_OP);
365 	wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID);
366 
367 	return QDF_STATUS_SUCCESS;
368 }
369 qdf_export_symbol(wlan_objmgr_peer_obj_delete);
370 /**
371  ** APIs to attach/detach component objects
372  */
373 QDF_STATUS wlan_objmgr_peer_component_obj_attach(
374 		struct wlan_objmgr_peer *peer,
375 		enum wlan_umac_comp_id id,
376 		void *comp_priv_obj,
377 		QDF_STATUS status)
378 {
379 	wlan_objmgr_peer_status_handler s_hler;
380 	void *arg;
381 	uint8_t i;
382 	QDF_STATUS obj_status;
383 
384 	/* component id is invalid */
385 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
386 		return QDF_STATUS_MAXCOMP_FAIL;
387 
388 	wlan_peer_obj_lock(peer);
389 	/* If there is a valid entry, return failure,
390 	valid object needs to be freed first */
391 	if (peer->peer_comp_priv_obj[id]) {
392 		wlan_peer_obj_unlock(peer);
393 		return QDF_STATUS_E_FAILURE;
394 	}
395 	/* Assign component object private pointer(can be NULL also), status */
396 	peer->peer_comp_priv_obj[id] = comp_priv_obj;
397 	peer->obj_status[id] = status;
398 	wlan_peer_obj_unlock(peer);
399 
400 	if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
401 		return QDF_STATUS_SUCCESS;
402 
403 	/* If PEER object status is partially created means, this API is
404 	invoked with differnt context. this block should be executed for async
405 	components only */
406 	/* Derive status */
407 	obj_status = wlan_objmgr_peer_object_status(peer);
408 	/* STATUS_SUCCESS means, object is CREATED */
409 	if (obj_status == QDF_STATUS_SUCCESS)
410 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
411 	/* update state as CREATION failed, caller has to delete the
412 	PEER object */
413 	else if (obj_status == QDF_STATUS_E_FAILURE)
414 		peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
415 	/* Notify components about the CREATION success/failure */
416 	if ((obj_status == QDF_STATUS_SUCCESS) ||
417 	    (obj_status == QDF_STATUS_E_FAILURE)) {
418 		/* nofity object status */
419 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
420 			s_hler = g_umac_glb_obj->peer_status_handler[i];
421 			arg = g_umac_glb_obj->peer_status_handler_arg[i];
422 			if (s_hler)
423 				s_hler(peer, arg, obj_status);
424 		}
425 	}
426 	return QDF_STATUS_SUCCESS;
427 }
428 
429 QDF_STATUS wlan_objmgr_peer_component_obj_detach(
430 		struct wlan_objmgr_peer *peer,
431 		enum wlan_umac_comp_id id,
432 		void *comp_priv_obj)
433 {
434 	QDF_STATUS obj_status;
435 
436 	/* component id is invalid */
437 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
438 		return QDF_STATUS_MAXCOMP_FAIL;
439 
440 	wlan_peer_obj_lock(peer);
441 	/* If there is a invalid entry, return failure */
442 	if (peer->peer_comp_priv_obj[id] != comp_priv_obj) {
443 		peer->obj_status[id] = QDF_STATUS_E_FAILURE;
444 		wlan_peer_obj_unlock(peer);
445 		return QDF_STATUS_E_FAILURE;
446 	}
447 	/* Reset the pointer to NULL */
448 	peer->peer_comp_priv_obj[id] = NULL;
449 	peer->obj_status[id] = QDF_STATUS_SUCCESS;
450 	wlan_peer_obj_unlock(peer);
451 
452 	/* If PEER object status is partially destroyed means, this API is
453 	invoked with differnt context, this block should be executed for async
454 	components only */
455 	if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
456 	    (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
457 		/* Derive object status */
458 		obj_status = wlan_objmgr_peer_object_status(peer);
459 		if (obj_status == QDF_STATUS_SUCCESS) {
460 			/*Update the status as Deleted, if full object
461 				deletion is in progress */
462 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
463 				peer->obj_state = WLAN_OBJ_STATE_DELETED;
464 			/* Move to creation state, since this component
465 			deletion alone requested */
466 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
467 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
468 		/* Object status is failure */
469 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
470 			/*Update the status as Deletion failed, if full object
471 				deletion is in progress */
472 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
473 				peer->obj_state =
474 					WLAN_OBJ_STATE_DELETION_FAILED;
475 			/* Move to creation state, since this component
476 			deletion alone requested (do not block other
477 			components) */
478 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
479 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
480 		}
481 
482 			/* Delete peer object */
483 		if ((obj_status == QDF_STATUS_SUCCESS)  &&
484 		    (peer->obj_state == WLAN_OBJ_STATE_DELETED)) {
485 			/* Free the peer object */
486 			return wlan_objmgr_peer_obj_free(peer);
487 		}
488 	}
489 
490 	return QDF_STATUS_SUCCESS;
491 }
492 
493 
494 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation(
495 		struct wlan_objmgr_peer *peer,
496 		enum wlan_umac_comp_id id)
497 {
498 	wlan_objmgr_peer_create_handler handler;
499 	void *arg;
500 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
501 
502 	/* Component id is invalid */
503 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
504 		return QDF_STATUS_MAXCOMP_FAIL;
505 
506 	wlan_peer_obj_lock(peer);
507 	/* If component object is already created, delete old
508 		component object, then invoke creation */
509 	if (peer->peer_comp_priv_obj[id]) {
510 		wlan_peer_obj_unlock(peer);
511 		return QDF_STATUS_E_FAILURE;
512 	}
513 	wlan_peer_obj_unlock(peer);
514 
515 	/* Invoke registered create handlers */
516 	handler = g_umac_glb_obj->peer_create_handler[id];
517 	arg = g_umac_glb_obj->peer_create_handler_arg[id];
518 	if (handler)
519 		peer->obj_status[id] = handler(peer, arg);
520 	else
521 		return QDF_STATUS_E_FAILURE;
522 
523 	/* If object status is created, then only handle this object status */
524 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
525 		/* Derive object status */
526 		obj_status = wlan_objmgr_peer_object_status(peer);
527 		/* Move PDEV object state to Partially created state */
528 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
529 			/*TODO atomic */
530 			peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
531 		}
532 	}
533 
534 	return obj_status;
535 }
536 
537 
538 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion(
539 		struct wlan_objmgr_peer *peer,
540 		enum wlan_umac_comp_id id)
541 {
542 	wlan_objmgr_peer_destroy_handler handler;
543 	void *arg;
544 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
545 
546 	/* component id is invalid */
547 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
548 		return QDF_STATUS_MAXCOMP_FAIL;
549 
550 	wlan_peer_obj_lock(peer);
551 	/* Component object was never created, invalid operation */
552 	if (!peer->peer_comp_priv_obj[id]) {
553 		wlan_peer_obj_unlock(peer);
554 		return QDF_STATUS_E_FAILURE;
555 	}
556 
557 	wlan_peer_obj_unlock(peer);
558 
559 	/* Invoke registered destroy handlers */
560 	handler = g_umac_glb_obj->peer_destroy_handler[id];
561 	arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
562 	if (handler)
563 		peer->obj_status[id] = handler(peer, arg);
564 	else
565 		return QDF_STATUS_E_FAILURE;
566 
567 	/* If object status is created, then only handle this object status */
568 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
569 		obj_status = wlan_objmgr_peer_object_status(peer);
570 			/* move object state to DEL progress */
571 		if (obj_status == QDF_STATUS_COMP_ASYNC)
572 			peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
573 	}
574 	return obj_status;
575 }
576 
577 void *wlan_objmgr_peer_get_comp_private_obj(
578 		struct wlan_objmgr_peer *peer,
579 		enum wlan_umac_comp_id id)
580 {
581 	void *comp_priv_obj;
582 
583 	/* component id is invalid */
584 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
585 		QDF_BUG(0);
586 		return NULL;
587 	}
588 
589 	if (!peer) {
590 		QDF_BUG(0);
591 		return NULL;
592 	}
593 
594 	comp_priv_obj = peer->peer_comp_priv_obj[id];
595 	return comp_priv_obj;
596 }
597 qdf_export_symbol(wlan_objmgr_peer_get_comp_private_obj);
598 
599 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
600 static inline void
601 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer,
602 				  wlan_objmgr_ref_dbgid id)
603 {
604 	qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]);
605 }
606 #else
607 static inline void
608 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer,
609 				  wlan_objmgr_ref_dbgid id) {}
610 #endif
611 
612 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
613 static QDF_STATUS
614 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer,
615 				      wlan_objmgr_ref_dbgid id)
616 {
617 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) {
618 		uint8_t *macaddr;
619 
620 		macaddr = wlan_peer_get_macaddr(peer);
621 		obj_mgr_err(
622 		"peer(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d",
623 			macaddr[0], macaddr[1], macaddr[2],
624 			macaddr[3], macaddr[4], macaddr[5], 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_STR ") not in Created st(%d)",
729 			QDF_MAC_ADDR_ARRAY(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_STR ") not in Created st(%d)",
762 			QDF_MAC_ADDR_ARRAY(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(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0",
1193 				macaddr[0], macaddr[1], macaddr[2],
1194 				macaddr[3], macaddr[4], macaddr[5]);
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(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0",
1237 			    macaddr[0], macaddr[1], macaddr[2],
1238 			    macaddr[3], macaddr[4], macaddr[5]);
1239 		WLAN_OBJMGR_BUG(0);
1240 		return;
1241 	}
1242 
1243 	status = wlan_objmgr_peer_release_debug_id_ref(peer, id);
1244 	if (QDF_IS_STATUS_ERROR(status))
1245 		return;
1246 
1247 	/* Provide synchronization from the access to add peer
1248 	 * to logically deleted peer list.
1249 	 */
1250 	wlan_peer_obj_lock(peer);
1251 	/* Decrement ref count, free peer object, if ref count == 0 */
1252 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
1253 		wlan_peer_obj_unlock(peer);
1254 		wlan_objmgr_peer_obj_destroy(peer);
1255 	} else {
1256 		wlan_peer_obj_unlock(peer);
1257 	}
1258 }
1259 
1260 qdf_export_symbol(wlan_objmgr_peer_release_ref);
1261 #endif
1262 
1263 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
1264 void
1265 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer,
1266 			       QDF_TRACE_LEVEL log_level)
1267 {
1268 	wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, log_level);
1269 }
1270 
1271 uint32_t
1272 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer,
1273 				  enum wlan_umac_comp_id id)
1274 {
1275 	return qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id]);
1276 }
1277 #else
1278 void
1279 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer,
1280 			       QDF_TRACE_LEVEL log_level)
1281 {
1282 	uint32_t pending_ref;
1283 
1284 	pending_ref = qdf_atomic_read(&peer->peer_objmgr.ref_cnt);
1285 	obj_mgr_log_level(log_level, "Pending refs -- %d", pending_ref);
1286 }
1287 
1288 uint32_t
1289 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer,
1290 				  enum wlan_umac_comp_id id)
1291 {
1292 	return 0;
1293 }
1294 #endif
1295