xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
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 
78 	if (!peer) {
79 		obj_mgr_err("PEER is NULL");
80 		return QDF_STATUS_E_FAILURE;
81 	}
82 
83 	macaddr = wlan_peer_get_macaddr(peer);
84 
85 	vdev = wlan_peer_get_vdev(peer);
86 	if (!vdev) {
87 		obj_mgr_err(
88 			"VDEV is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)",
89 				macaddr[0], macaddr[1], macaddr[2],
90 				macaddr[3], macaddr[4], macaddr[5]);
91 		return QDF_STATUS_E_FAILURE;
92 	}
93 
94 	vdev_id = wlan_vdev_get_id(vdev);
95 
96 	/* get PSOC from VDEV, if it is NULL, return */
97 	psoc = wlan_vdev_get_psoc(vdev);
98 	if (!psoc) {
99 		obj_mgr_err(
100 			"PSOC is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)",
101 				macaddr[0], macaddr[1], macaddr[2],
102 				macaddr[3], macaddr[4], macaddr[5]);
103 		return QDF_STATUS_E_FAILURE;
104 	}
105 
106 	/* Decrement ref count for BSS peer, so that BSS peer deletes last*/
107 	if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) ||
108 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP) ||
109 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_CLI))
110 		wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev),
111 					     WLAN_OBJMGR_ID);
112 
113 	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
114 
115 	/* Detach peer from VDEV's peer list */
116 	if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) {
117 		obj_mgr_err(
118 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d",
119 			macaddr[0], macaddr[1], macaddr[2],
120 			macaddr[3], macaddr[4], macaddr[5], vdev_id);
121 		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
122 		return QDF_STATUS_E_FAILURE;
123 	}
124 	/* Detach peer from PSOC's peer list */
125 	if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) {
126 		obj_mgr_err(
127 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure",
128 			macaddr[0], macaddr[1], macaddr[2],
129 			macaddr[3], macaddr[4], macaddr[5]);
130 		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
131 		return QDF_STATUS_E_FAILURE;
132 	}
133 	wlan_objmgr_peer_trace_del_ref_list(peer);
134 	wlan_objmgr_peer_trace_deinit_lock(peer);
135 	qdf_spinlock_destroy(&peer->peer_lock);
136 	qdf_mem_free(peer);
137 
138 	wlan_objmgr_vdev_peer_freed_notify(vdev);
139 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
140 
141 	return QDF_STATUS_SUCCESS;
142 
143 }
144 
145 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
146 static void
147 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer)
148 {
149 	uint8_t id;
150 
151 	for (id = 0; id < WLAN_REF_ID_MAX; id++)
152 		qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]);
153 }
154 #else
155 static inline void
156 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) {}
157 #endif
158 
159 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
160 			struct wlan_objmgr_vdev *vdev,
161 			enum wlan_peer_type type,
162 			uint8_t *macaddr)
163 {
164 	struct wlan_objmgr_peer *peer;
165 	struct wlan_objmgr_psoc *psoc;
166 	wlan_objmgr_peer_create_handler handler;
167 	wlan_objmgr_peer_status_handler stat_handler;
168 	void *arg;
169 	QDF_STATUS obj_status;
170 	uint8_t id;
171 
172 	if (!vdev) {
173 		obj_mgr_err(
174 			"VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)",
175 				macaddr[0], macaddr[1], macaddr[2],
176 				macaddr[3], macaddr[4], macaddr[5]);
177 		return NULL;
178 	}
179 	/* Get psoc, if psoc is NULL, return */
180 	psoc = wlan_vdev_get_psoc(vdev);
181 	if (!psoc) {
182 		obj_mgr_err(
183 			"PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)",
184 				macaddr[0], macaddr[1], macaddr[2],
185 				macaddr[3], macaddr[4], macaddr[5]);
186 		return NULL;
187 	}
188 	/* Allocate memory for peer object */
189 	peer = qdf_mem_malloc(sizeof(*peer));
190 	if (!peer)
191 		return NULL;
192 
193 	peer->obj_state = WLAN_OBJ_STATE_ALLOCATED;
194 	qdf_atomic_init(&peer->peer_objmgr.ref_cnt);
195 	wlan_objmgr_peer_init_ref_id_debug(peer);
196 	wlan_objmgr_peer_trace_init_lock(peer);
197 	wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID);
198 	/* set vdev to peer */
199 	wlan_peer_set_vdev(peer, vdev);
200 	/* set peer type */
201 	wlan_peer_set_peer_type(peer, type);
202 	/* set mac address of peer */
203 	wlan_peer_set_macaddr(peer, macaddr);
204 	/* initialize peer state */
205 	wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE);
206 	wlan_peer_mlme_reset_seq_num(peer);
207 	peer->peer_objmgr.print_cnt = 0;
208 
209 	qdf_spinlock_create(&peer->peer_lock);
210 	/* Attach peer to psoc, psoc maintains the node table for the device */
211 	if (wlan_objmgr_psoc_peer_attach(psoc, peer) !=
212 					QDF_STATUS_SUCCESS) {
213 		obj_mgr_warn(
214 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure",
215 				macaddr[0], macaddr[1], macaddr[2],
216 				macaddr[3], macaddr[4], macaddr[5]);
217 		qdf_spinlock_destroy(&peer->peer_lock);
218 		wlan_objmgr_peer_trace_deinit_lock(peer);
219 		qdf_mem_free(peer);
220 		return NULL;
221 	}
222 	/* Attach peer to vdev peer table */
223 	if (wlan_objmgr_vdev_peer_attach(vdev, peer) !=
224 					QDF_STATUS_SUCCESS) {
225 		obj_mgr_warn(
226 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure",
227 				macaddr[0], macaddr[1], macaddr[2],
228 				macaddr[3], macaddr[4], macaddr[5]);
229 		/* if attach fails, detach from psoc table before free */
230 		wlan_objmgr_psoc_peer_detach(psoc, peer);
231 		qdf_spinlock_destroy(&peer->peer_lock);
232 		wlan_objmgr_peer_trace_deinit_lock(peer);
233 		qdf_mem_free(peer);
234 		return NULL;
235 	}
236 	wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id(
237 			wlan_vdev_get_pdev(vdev)));
238 	/* Increment ref count for BSS peer, so that BSS peer deletes last*/
239 	if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP)
240 				    || (type == WLAN_PEER_P2P_CLI))
241 		wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev),
242 					 WLAN_OBJMGR_ID);
243 	/* TODO init other parameters */
244 	/* Invoke registered create handlers */
245 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
246 		handler = g_umac_glb_obj->peer_create_handler[id];
247 		arg = g_umac_glb_obj->peer_create_handler_arg[id];
248 		if (handler)
249 			peer->obj_status[id] = handler(peer, arg);
250 		else
251 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
252 	}
253 	/* derive the object status */
254 	obj_status = wlan_objmgr_peer_object_status(peer);
255 	/* If SUCCESS, Object is created */
256 	if (obj_status == QDF_STATUS_SUCCESS) {
257 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
258 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
259 			stat_handler = g_umac_glb_obj->peer_status_handler[id];
260 			arg = g_umac_glb_obj->peer_status_handler_arg[id];
261 			if (stat_handler)
262 				stat_handler(peer, arg,
263 					     QDF_STATUS_SUCCESS);
264 		}
265 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
266 		/* If any component operates in different context, update it
267 		as partially created */
268 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
269 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
270 		/* Clean up the peer */
271 		obj_mgr_err(
272 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail",
273 				macaddr[0], macaddr[1], macaddr[2],
274 				macaddr[3], macaddr[4], macaddr[5]);
275 		wlan_objmgr_peer_obj_delete(peer);
276 		return NULL;
277 	}
278 
279 	obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR " type %d",
280 		      QDF_MAC_ADDR_ARRAY(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_STR,
302 		      QDF_MAC_ADDR_ARRAY(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_STR, peer->obj_state,
307 			    QDF_MAC_ADDR_ARRAY(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_STR,
354 		      QDF_MAC_ADDR_ARRAY(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(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d",
624 			macaddr[0], macaddr[1], macaddr[2],
625 			macaddr[3], macaddr[4], macaddr[5], 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_STR ") not in Created st(%d)",
730 			QDF_MAC_ADDR_ARRAY(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_STR ") not in Created st(%d)",
763 			QDF_MAC_ADDR_ARRAY(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(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0",
1194 				macaddr[0], macaddr[1], macaddr[2],
1195 				macaddr[3], macaddr[4], macaddr[5]);
1196 		WLAN_OBJMGR_BUG(0);
1197 		return;
1198 	}
1199 
1200 	status = wlan_objmgr_peer_release_debug_id_ref(peer, id);
1201 	if (QDF_IS_STATUS_ERROR(status))
1202 		return;
1203 
1204 	wlan_objmgr_peer_deref_trace(peer, id, func, line);
1205 	/* Provide synchronization from the access to add peer
1206 	 * to logically deleted peer list.
1207 	 */
1208 	wlan_peer_obj_lock(peer);
1209 	/* Decrement ref count, free peer object, if ref count == 0 */
1210 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
1211 		wlan_peer_obj_unlock(peer);
1212 		wlan_objmgr_peer_obj_destroy(peer);
1213 	} else {
1214 		wlan_peer_obj_unlock(peer);
1215 	}
1216 
1217 	return;
1218 }
1219 
1220 qdf_export_symbol(wlan_objmgr_peer_release_ref_debug);
1221 #else
1222 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer,
1223 				  wlan_objmgr_ref_dbgid id)
1224 {
1225 	QDF_STATUS status;
1226 
1227 	if (!peer) {
1228 		obj_mgr_err("peer obj is NULL for %d", id);
1229 		QDF_ASSERT(0);
1230 		return;
1231 	}
1232 
1233 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
1234 		uint8_t *macaddr;
1235 
1236 		macaddr = wlan_peer_get_macaddr(peer);
1237 		obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0",
1238 			    macaddr[0], macaddr[1], macaddr[2],
1239 			    macaddr[3], macaddr[4], macaddr[5]);
1240 		WLAN_OBJMGR_BUG(0);
1241 		return;
1242 	}
1243 
1244 	status = wlan_objmgr_peer_release_debug_id_ref(peer, id);
1245 	if (QDF_IS_STATUS_ERROR(status))
1246 		return;
1247 
1248 	/* Provide synchronization from the access to add peer
1249 	 * to logically deleted peer list.
1250 	 */
1251 	wlan_peer_obj_lock(peer);
1252 	/* Decrement ref count, free peer object, if ref count == 0 */
1253 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
1254 		wlan_peer_obj_unlock(peer);
1255 		wlan_objmgr_peer_obj_destroy(peer);
1256 	} else {
1257 		wlan_peer_obj_unlock(peer);
1258 	}
1259 }
1260 
1261 qdf_export_symbol(wlan_objmgr_peer_release_ref);
1262 #endif
1263 
1264 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
1265 void
1266 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer,
1267 			       QDF_TRACE_LEVEL log_level)
1268 {
1269 	wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, log_level);
1270 }
1271 
1272 uint32_t
1273 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer,
1274 				  enum wlan_umac_comp_id id)
1275 {
1276 	return qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id]);
1277 }
1278 #else
1279 void
1280 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer,
1281 			       QDF_TRACE_LEVEL log_level)
1282 {
1283 	uint32_t pending_ref;
1284 
1285 	pending_ref = qdf_atomic_read(&peer->peer_objmgr.ref_cnt);
1286 	obj_mgr_log_level(log_level, "Pending refs -- %d", pending_ref);
1287 }
1288 
1289 uint32_t
1290 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer,
1291 				  enum wlan_umac_comp_id id)
1292 {
1293 	return 0;
1294 }
1295 #endif
1296