xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c (revision 4865edfd190c086bbe2c69aae12a8226f877b91e)
1 /*
2  * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18  /**
19  * DOC: Public APIs to perform operations on 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] == NULL) {
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 == NULL) {
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 == NULL) {
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 == NULL) {
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 	/* Detach peer from VDEV's peer list */
113 	if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) {
114 		obj_mgr_err(
115 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d",
116 			macaddr[0], macaddr[1], macaddr[2],
117 			macaddr[3], macaddr[4], macaddr[5], vdev_id);
118 		return QDF_STATUS_E_FAILURE;
119 	}
120 	/* Detach peer from PSOC's peer list */
121 	if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) {
122 		obj_mgr_err(
123 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure",
124 			macaddr[0], macaddr[1], macaddr[2],
125 			macaddr[3], macaddr[4], macaddr[5]);
126 		return QDF_STATUS_E_FAILURE;
127 	}
128 	qdf_spinlock_destroy(&peer->peer_lock);
129 	qdf_mem_free(peer);
130 
131 	return QDF_STATUS_SUCCESS;
132 
133 }
134 
135 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
136 			struct wlan_objmgr_vdev *vdev,
137 			enum wlan_peer_type type,
138 			uint8_t *macaddr)
139 {
140 	struct wlan_objmgr_peer *peer;
141 	struct wlan_objmgr_psoc *psoc;
142 	wlan_objmgr_peer_create_handler handler;
143 	wlan_objmgr_peer_status_handler stat_handler;
144 	void *arg;
145 	QDF_STATUS obj_status;
146 	uint8_t id;
147 
148 	if (vdev == NULL) {
149 		obj_mgr_err(
150 			"VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)",
151 				macaddr[0], macaddr[1], macaddr[2],
152 				macaddr[3], macaddr[4], macaddr[5]);
153 		return NULL;
154 	}
155 	/* Get psoc, if psoc is NULL, return */
156 	psoc = wlan_vdev_get_psoc(vdev);
157 	if (psoc == NULL) {
158 		obj_mgr_err(
159 			"PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)",
160 				macaddr[0], macaddr[1], macaddr[2],
161 				macaddr[3], macaddr[4], macaddr[5]);
162 		return NULL;
163 	}
164 	/* Allocate memory for peer object */
165 	peer = qdf_mem_malloc(sizeof(*peer));
166 	if (peer == NULL) {
167 		obj_mgr_err(
168 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) allocation failure",
169 				macaddr[0], macaddr[1], macaddr[2],
170 				macaddr[3], macaddr[4], macaddr[5]);
171 		return NULL;
172 	}
173 	peer->obj_state = WLAN_OBJ_STATE_ALLOCATED;
174 	qdf_atomic_init(&peer->peer_objmgr.ref_cnt);
175 	for (id = 0; id < WLAN_REF_ID_MAX; id++)
176 		qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]);
177 	wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID);
178 	/* set vdev to peer */
179 	wlan_peer_set_vdev(peer, vdev);
180 	/* set peer type */
181 	wlan_peer_set_peer_type(peer, type);
182 	/* set mac address of peer */
183 	wlan_peer_set_macaddr(peer, macaddr);
184 	/* initialize peer state */
185 	wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE);
186 	wlan_peer_mlme_reset_seq_num(peer);
187 	peer->peer_objmgr.print_cnt = 0;
188 
189 	qdf_spinlock_create(&peer->peer_lock);
190 	/* Attach peer to psoc, psoc maintains the node table for the device */
191 	if (wlan_objmgr_psoc_peer_attach(psoc, peer) !=
192 					QDF_STATUS_SUCCESS) {
193 		obj_mgr_warn(
194 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure",
195 				macaddr[0], macaddr[1], macaddr[2],
196 				macaddr[3], macaddr[4], macaddr[5]);
197 		qdf_spinlock_destroy(&peer->peer_lock);
198 		qdf_mem_free(peer);
199 		return NULL;
200 	}
201 	/* Attach peer to vdev peer table */
202 	if (wlan_objmgr_vdev_peer_attach(vdev, peer) !=
203 					QDF_STATUS_SUCCESS) {
204 		obj_mgr_warn(
205 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure",
206 				macaddr[0], macaddr[1], macaddr[2],
207 				macaddr[3], macaddr[4], macaddr[5]);
208 		/* if attach fails, detach from psoc table before free */
209 		wlan_objmgr_psoc_peer_detach(psoc, peer);
210 		qdf_spinlock_destroy(&peer->peer_lock);
211 		qdf_mem_free(peer);
212 		return NULL;
213 	}
214 	wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id(
215 			wlan_vdev_get_pdev(vdev)));
216 	/* Increment ref count for BSS peer, so that BSS peer deletes last*/
217 	if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP)
218 				    || (type == WLAN_PEER_P2P_CLI))
219 		wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev),
220 					 WLAN_OBJMGR_ID);
221 	/* TODO init other parameters */
222 	/* Invoke registered create handlers */
223 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
224 		handler = g_umac_glb_obj->peer_create_handler[id];
225 		arg = g_umac_glb_obj->peer_create_handler_arg[id];
226 		if (handler != NULL)
227 			peer->obj_status[id] = handler(peer, arg);
228 		else
229 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
230 	}
231 	/* derive the object status */
232 	obj_status = wlan_objmgr_peer_object_status(peer);
233 	/* If SUCCESS, Object is created */
234 	if (obj_status == QDF_STATUS_SUCCESS) {
235 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
236 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
237 			stat_handler = g_umac_glb_obj->peer_status_handler[id];
238 			arg = g_umac_glb_obj->peer_status_handler_arg[id];
239 			if (stat_handler != NULL)
240 				stat_handler(peer, arg,
241 					     QDF_STATUS_SUCCESS);
242 		}
243 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
244 		/* If any component operates in different context, update it
245 		as partially created */
246 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
247 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
248 		/* Clean up the peer */
249 		obj_mgr_err(
250 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail",
251 				macaddr[0], macaddr[1], macaddr[2],
252 				macaddr[3], macaddr[4], macaddr[5]);
253 		wlan_objmgr_peer_obj_delete(peer);
254 		return NULL;
255 	}
256 
257 	obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR,
258 		      QDF_MAC_ADDR_ARRAY(macaddr));
259 
260 	return peer;
261 }
262 
263 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer)
264 {
265 	uint8_t id;
266 	wlan_objmgr_peer_destroy_handler handler;
267 	QDF_STATUS obj_status;
268 	void *arg;
269 	uint8_t *macaddr;
270 
271 	if (peer == NULL) {
272 		obj_mgr_err("PEER is NULL");
273 		return QDF_STATUS_E_FAILURE;
274 	}
275 	wlan_objmgr_notify_destroy(peer, WLAN_PEER_OP);
276 
277 	macaddr = wlan_peer_get_macaddr(peer);
278 
279 	obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_STR,
280 		      QDF_MAC_ADDR_ARRAY(macaddr));
281 
282 	if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
283 		obj_mgr_err("PEER object del is not invoked obj_state:%d peer "
284 			    QDF_MAC_ADDR_STR, peer->obj_state,
285 			    QDF_MAC_ADDR_ARRAY(macaddr));
286 		WLAN_OBJMGR_BUG(0);
287 	}
288 
289 	/* Invoke registered destroy handlers */
290 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
291 		handler = g_umac_glb_obj->peer_destroy_handler[id];
292 		arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
293 		if (handler != NULL)
294 			peer->obj_status[id] = handler(peer, arg);
295 		else
296 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
297 	}
298 	/* Derive the object status */
299 	obj_status = wlan_objmgr_peer_object_status(peer);
300 	if (obj_status == QDF_STATUS_E_FAILURE) {
301 		/* If it status is failure, memory will not be freed */
302 		QDF_BUG(0);
303 		return QDF_STATUS_E_FAILURE;
304 	}
305 	/* few components deletion is in progress */
306 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
307 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
308 		return QDF_STATUS_COMP_ASYNC;
309 	}
310 
311 	/* Free the peer object */
312 	return wlan_objmgr_peer_obj_free(peer);
313 }
314 
315 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer)
316 {
317 	uint8_t print_idx;
318 	uint8_t *macaddr;
319 
320 	if (peer == NULL) {
321 		obj_mgr_err("PEER is NULL");
322 		return QDF_STATUS_E_FAILURE;
323 	}
324 
325 	wlan_peer_obj_lock(peer);
326 	macaddr = wlan_peer_get_macaddr(peer);
327 	wlan_peer_obj_unlock(peer);
328 
329 	obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_STR,
330 		      QDF_MAC_ADDR_ARRAY(macaddr));
331 
332 	print_idx = qdf_get_pidx();
333 	if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR,
334 		QDF_TRACE_LEVEL_DEBUG)) {
335 		wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg);
336 	}
337 
338 	/**
339 	 * Update VDEV object state to LOGICALLY DELETED
340 	 * It prevents further access of this object
341 	 */
342 	wlan_peer_obj_lock(peer);
343 	peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
344 	wlan_peer_obj_unlock(peer);
345 	wlan_objmgr_notify_log_delete(peer, WLAN_PEER_OP);
346 	wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID);
347 
348 	return QDF_STATUS_SUCCESS;
349 }
350 qdf_export_symbol(wlan_objmgr_peer_obj_delete);
351 /**
352  ** APIs to attach/detach component objects
353  */
354 QDF_STATUS wlan_objmgr_peer_component_obj_attach(
355 		struct wlan_objmgr_peer *peer,
356 		enum wlan_umac_comp_id id,
357 		void *comp_priv_obj,
358 		QDF_STATUS status)
359 {
360 	wlan_objmgr_peer_status_handler s_hler;
361 	void *arg;
362 	uint8_t i;
363 	QDF_STATUS obj_status;
364 
365 	/* component id is invalid */
366 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
367 		return QDF_STATUS_MAXCOMP_FAIL;
368 
369 	wlan_peer_obj_lock(peer);
370 	/* If there is a valid entry, return failure,
371 	valid object needs to be freed first */
372 	if (peer->peer_comp_priv_obj[id] != NULL) {
373 		wlan_peer_obj_unlock(peer);
374 		return QDF_STATUS_E_FAILURE;
375 	}
376 	/* Assign component object private pointer(can be NULL also), status */
377 	peer->peer_comp_priv_obj[id] = comp_priv_obj;
378 	peer->obj_status[id] = status;
379 	wlan_peer_obj_unlock(peer);
380 
381 	if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
382 		return QDF_STATUS_SUCCESS;
383 
384 	/* If PEER object status is partially created means, this API is
385 	invoked with differnt context. this block should be executed for async
386 	components only */
387 	/* Derive status */
388 	obj_status = wlan_objmgr_peer_object_status(peer);
389 	/* STATUS_SUCCESS means, object is CREATED */
390 	if (obj_status == QDF_STATUS_SUCCESS)
391 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
392 	/* update state as CREATION failed, caller has to delete the
393 	PEER object */
394 	else if (obj_status == QDF_STATUS_E_FAILURE)
395 		peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
396 	/* Notify components about the CREATION success/failure */
397 	if ((obj_status == QDF_STATUS_SUCCESS) ||
398 	    (obj_status == QDF_STATUS_E_FAILURE)) {
399 		/* nofity object status */
400 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
401 			s_hler = g_umac_glb_obj->peer_status_handler[i];
402 			arg = g_umac_glb_obj->peer_status_handler_arg[i];
403 			if (s_hler != NULL)
404 				s_hler(peer, arg, obj_status);
405 		}
406 	}
407 	return QDF_STATUS_SUCCESS;
408 }
409 
410 QDF_STATUS wlan_objmgr_peer_component_obj_detach(
411 		struct wlan_objmgr_peer *peer,
412 		enum wlan_umac_comp_id id,
413 		void *comp_priv_obj)
414 {
415 	QDF_STATUS obj_status;
416 
417 	/* component id is invalid */
418 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
419 		return QDF_STATUS_MAXCOMP_FAIL;
420 
421 	wlan_peer_obj_lock(peer);
422 	/* If there is a invalid entry, return failure */
423 	if (peer->peer_comp_priv_obj[id] != comp_priv_obj) {
424 		peer->obj_status[id] = QDF_STATUS_E_FAILURE;
425 		wlan_peer_obj_unlock(peer);
426 		return QDF_STATUS_E_FAILURE;
427 	}
428 	/* Reset the pointer to NULL */
429 	peer->peer_comp_priv_obj[id] = NULL;
430 	peer->obj_status[id] = QDF_STATUS_SUCCESS;
431 	wlan_peer_obj_unlock(peer);
432 
433 	/* If PEER object status is partially destroyed means, this API is
434 	invoked with differnt context, this block should be executed for async
435 	components only */
436 	if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
437 	    (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
438 		/* Derive object status */
439 		obj_status = wlan_objmgr_peer_object_status(peer);
440 		if (obj_status == QDF_STATUS_SUCCESS) {
441 			/*Update the status as Deleted, if full object
442 				deletion is in progress */
443 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
444 				peer->obj_state = WLAN_OBJ_STATE_DELETED;
445 			/* Move to creation state, since this component
446 			deletion alone requested */
447 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
448 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
449 		/* Object status is failure */
450 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
451 			/*Update the status as Deletion failed, if full object
452 				deletion is in progress */
453 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
454 				peer->obj_state =
455 					WLAN_OBJ_STATE_DELETION_FAILED;
456 			/* Move to creation state, since this component
457 			deletion alone requested (do not block other
458 			components) */
459 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
460 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
461 		}
462 
463 			/* Delete peer object */
464 		if ((obj_status == QDF_STATUS_SUCCESS)  &&
465 		    (peer->obj_state == WLAN_OBJ_STATE_DELETED)) {
466 			/* Free the peer object */
467 			return wlan_objmgr_peer_obj_free(peer);
468 		}
469 	}
470 
471 	return QDF_STATUS_SUCCESS;
472 }
473 
474 
475 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation(
476 		struct wlan_objmgr_peer *peer,
477 		enum wlan_umac_comp_id id)
478 {
479 	wlan_objmgr_peer_create_handler handler;
480 	void *arg;
481 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
482 
483 	/* Component id is invalid */
484 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
485 		return QDF_STATUS_MAXCOMP_FAIL;
486 
487 	wlan_peer_obj_lock(peer);
488 	/* If component object is already created, delete old
489 		component object, then invoke creation */
490 	if (peer->peer_comp_priv_obj[id] != NULL) {
491 		wlan_peer_obj_unlock(peer);
492 		return QDF_STATUS_E_FAILURE;
493 	}
494 	wlan_peer_obj_unlock(peer);
495 
496 	/* Invoke registered create handlers */
497 	handler = g_umac_glb_obj->peer_create_handler[id];
498 	arg = g_umac_glb_obj->peer_create_handler_arg[id];
499 	if (handler != NULL)
500 		peer->obj_status[id] = handler(peer, arg);
501 	else
502 		return QDF_STATUS_E_FAILURE;
503 
504 	/* If object status is created, then only handle this object status */
505 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
506 		/* Derive object status */
507 		obj_status = wlan_objmgr_peer_object_status(peer);
508 		/* Move PDEV object state to Partially created state */
509 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
510 			/*TODO atomic */
511 			peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
512 		}
513 	}
514 
515 	return obj_status;
516 }
517 
518 
519 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion(
520 		struct wlan_objmgr_peer *peer,
521 		enum wlan_umac_comp_id id)
522 {
523 	wlan_objmgr_peer_destroy_handler handler;
524 	void *arg;
525 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
526 
527 	/* component id is invalid */
528 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
529 		return QDF_STATUS_MAXCOMP_FAIL;
530 
531 	wlan_peer_obj_lock(peer);
532 	/* Component object was never created, invalid operation */
533 	if (peer->peer_comp_priv_obj[id] == NULL) {
534 		wlan_peer_obj_unlock(peer);
535 		return QDF_STATUS_E_FAILURE;
536 	}
537 
538 	wlan_peer_obj_unlock(peer);
539 
540 	/* Invoke registered destroy handlers */
541 	handler = g_umac_glb_obj->peer_destroy_handler[id];
542 	arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
543 	if (handler != NULL)
544 		peer->obj_status[id] = handler(peer, arg);
545 	else
546 		return QDF_STATUS_E_FAILURE;
547 
548 	/* If object status is created, then only handle this object status */
549 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
550 		obj_status = wlan_objmgr_peer_object_status(peer);
551 			/* move object state to DEL progress */
552 		if (obj_status == QDF_STATUS_COMP_ASYNC)
553 			peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
554 	}
555 	return obj_status;
556 }
557 
558 void *wlan_objmgr_peer_get_comp_private_obj(
559 		struct wlan_objmgr_peer *peer,
560 		enum wlan_umac_comp_id id)
561 {
562 	void *comp_priv_obj;
563 
564 	/* component id is invalid */
565 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
566 		QDF_BUG(0);
567 		return NULL;
568 	}
569 
570 	if (peer == NULL) {
571 		QDF_BUG(0);
572 		return NULL;
573 	}
574 
575 	comp_priv_obj = peer->peer_comp_priv_obj[id];
576 	return comp_priv_obj;
577 }
578 qdf_export_symbol(wlan_objmgr_peer_get_comp_private_obj);
579 
580 void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer,
581 					wlan_objmgr_ref_dbgid id)
582 {
583 	if (peer == NULL) {
584 		obj_mgr_err("peer obj is NULL for %d", id);
585 		QDF_ASSERT(0);
586 		return;
587 	}
588 	/* Increment ref count */
589 	qdf_atomic_inc(&peer->peer_objmgr.ref_cnt);
590 	qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]);
591 
592 	return;
593 }
594 qdf_export_symbol(wlan_objmgr_peer_get_ref);
595 
596 QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer,
597 						 wlan_objmgr_ref_dbgid id)
598 {
599 
600 	uint8_t *macaddr;
601 
602 	if (peer == NULL) {
603 		obj_mgr_err("peer obj is NULL for %d", id);
604 		QDF_ASSERT(0);
605 		return QDF_STATUS_E_FAILURE;
606 	}
607 
608 	wlan_peer_obj_lock(peer);
609 	macaddr = wlan_peer_get_macaddr(peer);
610 	if (peer->obj_state != WLAN_OBJ_STATE_CREATED) {
611 		wlan_peer_obj_unlock(peer);
612 		if (peer->peer_objmgr.print_cnt++ <=
613 				WLAN_OBJMGR_RATELIMIT_THRESH)
614 			obj_mgr_warn(
615 			"peer(" QDF_MAC_ADDR_STR ") not in Created st(%d)",
616 			QDF_MAC_ADDR_ARRAY(macaddr),
617 				peer->obj_state);
618 		return QDF_STATUS_E_RESOURCES;
619 	}
620 
621 	wlan_objmgr_peer_get_ref(peer, id);
622 	wlan_peer_obj_unlock(peer);
623 
624 	return QDF_STATUS_SUCCESS;
625 }
626 qdf_export_symbol(wlan_objmgr_peer_try_get_ref);
627 
628 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer,
629 						 wlan_objmgr_ref_dbgid id)
630 {
631 
632 	uint8_t *macaddr;
633 
634 	if (peer == NULL) {
635 		obj_mgr_err("peer obj is NULL for %d", id);
636 		QDF_ASSERT(0);
637 		return;
638 	}
639 
640 	macaddr = wlan_peer_get_macaddr(peer);
641 
642 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) {
643 		obj_mgr_err(
644 		"peer(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d",
645 			macaddr[0], macaddr[1], macaddr[2],
646 			macaddr[3], macaddr[4], macaddr[5], id);
647 		wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg);
648 		WLAN_OBJMGR_BUG(0);
649 	}
650 
651 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
652 		obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0",
653 				macaddr[0], macaddr[1], macaddr[2],
654 				macaddr[3], macaddr[4], macaddr[5]);
655 		WLAN_OBJMGR_BUG(0);
656 		return;
657 	}
658 	qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]);
659 
660 	/* Provide synchronization from the access to add peer
661 	 * to logically deleted peer list.
662 	 */
663 	wlan_peer_obj_lock(peer);
664 	/* Decrement ref count, free peer object, if ref count == 0 */
665 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
666 		wlan_peer_obj_unlock(peer);
667 		wlan_objmgr_peer_obj_destroy(peer);
668 	} else {
669 		wlan_peer_obj_unlock(peer);
670 	}
671 
672 	return;
673 }
674 qdf_export_symbol(wlan_objmgr_peer_release_ref);
675