xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
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 	/* Increment ref count for BSS peer, so that BSS peer deletes last*/
215 	if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP)
216 				    || (type == WLAN_PEER_P2P_CLI))
217 		wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev),
218 					 WLAN_OBJMGR_ID);
219 	/* TODO init other parameters */
220 	/* Invoke registered create handlers */
221 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
222 		handler = g_umac_glb_obj->peer_create_handler[id];
223 		arg = g_umac_glb_obj->peer_create_handler_arg[id];
224 		if (handler != NULL)
225 			peer->obj_status[id] = handler(peer, arg);
226 		else
227 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
228 	}
229 	/* derive the object status */
230 	obj_status = wlan_objmgr_peer_object_status(peer);
231 	/* If SUCCESS, Object is created */
232 	if (obj_status == QDF_STATUS_SUCCESS) {
233 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
234 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
235 			stat_handler = g_umac_glb_obj->peer_status_handler[id];
236 			arg = g_umac_glb_obj->peer_status_handler_arg[id];
237 			if (stat_handler != NULL)
238 				stat_handler(peer, arg,
239 					     QDF_STATUS_SUCCESS);
240 		}
241 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
242 		/* If any component operates in different context, update it
243 		as partially created */
244 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
245 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
246 		/* Clean up the peer */
247 		obj_mgr_err(
248 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail",
249 				macaddr[0], macaddr[1], macaddr[2],
250 				macaddr[3], macaddr[4], macaddr[5]);
251 		wlan_objmgr_peer_obj_delete(peer);
252 		return NULL;
253 	}
254 
255 	obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR,
256 		      QDF_MAC_ADDR_ARRAY(macaddr));
257 
258 	return peer;
259 }
260 
261 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer)
262 {
263 	uint8_t id;
264 	wlan_objmgr_peer_destroy_handler handler;
265 	QDF_STATUS obj_status;
266 	void *arg;
267 	uint8_t *macaddr;
268 
269 	if (peer == NULL) {
270 		obj_mgr_err("PEER is NULL");
271 		return QDF_STATUS_E_FAILURE;
272 	}
273 	wlan_objmgr_notify_destroy(peer, WLAN_PEER_OP);
274 
275 	macaddr = wlan_peer_get_macaddr(peer);
276 
277 	obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_STR,
278 		      QDF_MAC_ADDR_ARRAY(macaddr));
279 
280 	if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
281 		obj_mgr_err(
282 		"peer(%02x:%02x:%02x:%02x:%02x:%02x) object del is not invoked",
283 			macaddr[0], macaddr[1], macaddr[2],
284 			macaddr[3], macaddr[4], macaddr[5]);
285 		WLAN_OBJMGR_BUG(0);
286 	}
287 
288 	/* Invoke registered destroy handlers */
289 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
290 		handler = g_umac_glb_obj->peer_destroy_handler[id];
291 		arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
292 		if (handler != NULL)
293 			peer->obj_status[id] = handler(peer, arg);
294 		else
295 			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
296 	}
297 	/* Derive the object status */
298 	obj_status = wlan_objmgr_peer_object_status(peer);
299 	if (obj_status == QDF_STATUS_E_FAILURE) {
300 		/* If it status is failure, memory will not be freed */
301 		QDF_BUG(0);
302 		return QDF_STATUS_E_FAILURE;
303 	}
304 	/* few components deletion is in progress */
305 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
306 		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
307 		return QDF_STATUS_COMP_ASYNC;
308 	}
309 
310 	/* Free the peer object */
311 	return wlan_objmgr_peer_obj_free(peer);
312 }
313 
314 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer)
315 {
316 	uint8_t print_idx;
317 	uint8_t *macaddr;
318 
319 	if (peer == NULL) {
320 		obj_mgr_err("PEER is NULL");
321 		return QDF_STATUS_E_FAILURE;
322 	}
323 
324 	wlan_peer_obj_lock(peer);
325 	macaddr = wlan_peer_get_macaddr(peer);
326 	wlan_peer_obj_unlock(peer);
327 
328 	obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_STR,
329 		      QDF_MAC_ADDR_ARRAY(macaddr));
330 
331 	print_idx = qdf_get_pidx();
332 	if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR,
333 		QDF_TRACE_LEVEL_DEBUG)) {
334 		wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg);
335 	}
336 
337 	/**
338 	 * Update VDEV object state to LOGICALLY DELETED
339 	 * It prevents further access of this object
340 	 */
341 	wlan_peer_obj_lock(peer);
342 	peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
343 	wlan_peer_obj_unlock(peer);
344 	wlan_objmgr_notify_log_delete(peer, WLAN_PEER_OP);
345 	wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID);
346 
347 	return QDF_STATUS_SUCCESS;
348 }
349 qdf_export_symbol(wlan_objmgr_peer_obj_delete);
350 /**
351  ** APIs to attach/detach component objects
352  */
353 QDF_STATUS wlan_objmgr_peer_component_obj_attach(
354 		struct wlan_objmgr_peer *peer,
355 		enum wlan_umac_comp_id id,
356 		void *comp_priv_obj,
357 		QDF_STATUS status)
358 {
359 	wlan_objmgr_peer_status_handler s_hler;
360 	void *arg;
361 	uint8_t i;
362 	QDF_STATUS obj_status;
363 
364 	/* component id is invalid */
365 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
366 		return QDF_STATUS_MAXCOMP_FAIL;
367 
368 	wlan_peer_obj_lock(peer);
369 	/* If there is a valid entry, return failure,
370 	valid object needs to be freed first */
371 	if (peer->peer_comp_priv_obj[id] != NULL) {
372 		wlan_peer_obj_unlock(peer);
373 		return QDF_STATUS_E_FAILURE;
374 	}
375 	/* Assign component object private pointer(can be NULL also), status */
376 	peer->peer_comp_priv_obj[id] = comp_priv_obj;
377 	peer->obj_status[id] = status;
378 	wlan_peer_obj_unlock(peer);
379 
380 	if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
381 		return QDF_STATUS_SUCCESS;
382 
383 	/* If PEER object status is partially created means, this API is
384 	invoked with differnt context. this block should be executed for async
385 	components only */
386 	/* Derive status */
387 	obj_status = wlan_objmgr_peer_object_status(peer);
388 	/* STATUS_SUCCESS means, object is CREATED */
389 	if (obj_status == QDF_STATUS_SUCCESS)
390 		peer->obj_state = WLAN_OBJ_STATE_CREATED;
391 	/* update state as CREATION failed, caller has to delete the
392 	PEER object */
393 	else if (obj_status == QDF_STATUS_E_FAILURE)
394 		peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
395 	/* Notify components about the CREATION success/failure */
396 	if ((obj_status == QDF_STATUS_SUCCESS) ||
397 	    (obj_status == QDF_STATUS_E_FAILURE)) {
398 		/* nofity object status */
399 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
400 			s_hler = g_umac_glb_obj->peer_status_handler[i];
401 			arg = g_umac_glb_obj->peer_status_handler_arg[i];
402 			if (s_hler != NULL)
403 				s_hler(peer, arg, obj_status);
404 		}
405 	}
406 	return QDF_STATUS_SUCCESS;
407 }
408 
409 QDF_STATUS wlan_objmgr_peer_component_obj_detach(
410 		struct wlan_objmgr_peer *peer,
411 		enum wlan_umac_comp_id id,
412 		void *comp_priv_obj)
413 {
414 	QDF_STATUS obj_status;
415 
416 	/* component id is invalid */
417 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
418 		return QDF_STATUS_MAXCOMP_FAIL;
419 
420 	wlan_peer_obj_lock(peer);
421 	/* If there is a invalid entry, return failure */
422 	if (peer->peer_comp_priv_obj[id] != comp_priv_obj) {
423 		peer->obj_status[id] = QDF_STATUS_E_FAILURE;
424 		wlan_peer_obj_unlock(peer);
425 		return QDF_STATUS_E_FAILURE;
426 	}
427 	/* Reset the pointer to NULL */
428 	peer->peer_comp_priv_obj[id] = NULL;
429 	peer->obj_status[id] = QDF_STATUS_SUCCESS;
430 	wlan_peer_obj_unlock(peer);
431 
432 	/* If PEER object status is partially destroyed means, this API is
433 	invoked with differnt context, this block should be executed for async
434 	components only */
435 	if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
436 	    (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
437 		/* Derive object status */
438 		obj_status = wlan_objmgr_peer_object_status(peer);
439 		if (obj_status == QDF_STATUS_SUCCESS) {
440 			/*Update the status as Deleted, if full object
441 				deletion is in progress */
442 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
443 				peer->obj_state = WLAN_OBJ_STATE_DELETED;
444 			/* Move to creation state, since this component
445 			deletion alone requested */
446 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
447 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
448 		/* Object status is failure */
449 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
450 			/*Update the status as Deletion failed, if full object
451 				deletion is in progress */
452 			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
453 				peer->obj_state =
454 					WLAN_OBJ_STATE_DELETION_FAILED;
455 			/* Move to creation state, since this component
456 			deletion alone requested (do not block other
457 			components) */
458 			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
459 				peer->obj_state = WLAN_OBJ_STATE_CREATED;
460 		}
461 
462 			/* Delete peer object */
463 		if ((obj_status == QDF_STATUS_SUCCESS)  &&
464 		    (peer->obj_state == WLAN_OBJ_STATE_DELETED)) {
465 			/* Free the peer object */
466 			return wlan_objmgr_peer_obj_free(peer);
467 		}
468 	}
469 
470 	return QDF_STATUS_SUCCESS;
471 }
472 
473 
474 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation(
475 		struct wlan_objmgr_peer *peer,
476 		enum wlan_umac_comp_id id)
477 {
478 	wlan_objmgr_peer_create_handler handler;
479 	void *arg;
480 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
481 
482 	/* Component id is invalid */
483 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
484 		return QDF_STATUS_MAXCOMP_FAIL;
485 
486 	wlan_peer_obj_lock(peer);
487 	/* If component object is already created, delete old
488 		component object, then invoke creation */
489 	if (peer->peer_comp_priv_obj[id] != NULL) {
490 		wlan_peer_obj_unlock(peer);
491 		return QDF_STATUS_E_FAILURE;
492 	}
493 	wlan_peer_obj_unlock(peer);
494 
495 	/* Invoke registered create handlers */
496 	handler = g_umac_glb_obj->peer_create_handler[id];
497 	arg = g_umac_glb_obj->peer_create_handler_arg[id];
498 	if (handler != NULL)
499 		peer->obj_status[id] = handler(peer, arg);
500 	else
501 		return QDF_STATUS_E_FAILURE;
502 
503 	/* If object status is created, then only handle this object status */
504 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
505 		/* Derive object status */
506 		obj_status = wlan_objmgr_peer_object_status(peer);
507 		/* Move PDEV object state to Partially created state */
508 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
509 			/*TODO atomic */
510 			peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
511 		}
512 	}
513 
514 	return obj_status;
515 }
516 
517 
518 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion(
519 		struct wlan_objmgr_peer *peer,
520 		enum wlan_umac_comp_id id)
521 {
522 	wlan_objmgr_peer_destroy_handler handler;
523 	void *arg;
524 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
525 
526 	/* component id is invalid */
527 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
528 		return QDF_STATUS_MAXCOMP_FAIL;
529 
530 	wlan_peer_obj_lock(peer);
531 	/* Component object was never created, invalid operation */
532 	if (peer->peer_comp_priv_obj[id] == NULL) {
533 		wlan_peer_obj_unlock(peer);
534 		return QDF_STATUS_E_FAILURE;
535 	}
536 
537 	wlan_peer_obj_unlock(peer);
538 
539 	/* Invoke registered destroy handlers */
540 	handler = g_umac_glb_obj->peer_destroy_handler[id];
541 	arg = g_umac_glb_obj->peer_destroy_handler_arg[id];
542 	if (handler != NULL)
543 		peer->obj_status[id] = handler(peer, arg);
544 	else
545 		return QDF_STATUS_E_FAILURE;
546 
547 	/* If object status is created, then only handle this object status */
548 	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
549 		obj_status = wlan_objmgr_peer_object_status(peer);
550 			/* move object state to DEL progress */
551 		if (obj_status == QDF_STATUS_COMP_ASYNC)
552 			peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
553 	}
554 	return obj_status;
555 }
556 
557 void *wlan_objmgr_peer_get_comp_private_obj(
558 		struct wlan_objmgr_peer *peer,
559 		enum wlan_umac_comp_id id)
560 {
561 	void *comp_priv_obj;
562 
563 	/* component id is invalid */
564 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
565 		QDF_BUG(0);
566 		return NULL;
567 	}
568 
569 	if (peer == NULL) {
570 		QDF_BUG(0);
571 		return NULL;
572 	}
573 
574 	comp_priv_obj = peer->peer_comp_priv_obj[id];
575 	return comp_priv_obj;
576 }
577 qdf_export_symbol(wlan_objmgr_peer_get_comp_private_obj);
578 
579 void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer,
580 					wlan_objmgr_ref_dbgid id)
581 {
582 	if (peer == NULL) {
583 		obj_mgr_err("peer obj is NULL for %d", id);
584 		QDF_ASSERT(0);
585 		return;
586 	}
587 	/* Increment ref count */
588 	qdf_atomic_inc(&peer->peer_objmgr.ref_cnt);
589 	qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]);
590 
591 	return;
592 }
593 qdf_export_symbol(wlan_objmgr_peer_get_ref);
594 
595 QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer,
596 						 wlan_objmgr_ref_dbgid id)
597 {
598 
599 	uint8_t *macaddr;
600 
601 	if (peer == NULL) {
602 		obj_mgr_err("peer obj is NULL for %d", id);
603 		QDF_ASSERT(0);
604 		return QDF_STATUS_E_FAILURE;
605 	}
606 
607 	wlan_peer_obj_lock(peer);
608 	macaddr = wlan_peer_get_macaddr(peer);
609 	if (peer->obj_state != WLAN_OBJ_STATE_CREATED) {
610 		wlan_peer_obj_unlock(peer);
611 		if (peer->peer_objmgr.print_cnt++ <=
612 				WLAN_OBJMGR_RATELIMIT_THRESH)
613 			obj_mgr_warn(
614 			"peer(" QDF_MAC_ADDR_STR ") not in Created st(%d)",
615 			QDF_MAC_ADDR_ARRAY(macaddr),
616 				peer->obj_state);
617 		return QDF_STATUS_E_RESOURCES;
618 	}
619 
620 	wlan_objmgr_peer_get_ref(peer, id);
621 	wlan_peer_obj_unlock(peer);
622 
623 	return QDF_STATUS_SUCCESS;
624 }
625 qdf_export_symbol(wlan_objmgr_peer_try_get_ref);
626 
627 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer,
628 						 wlan_objmgr_ref_dbgid id)
629 {
630 
631 	uint8_t *macaddr;
632 
633 	if (peer == NULL) {
634 		obj_mgr_err("peer obj is NULL for %d", id);
635 		QDF_ASSERT(0);
636 		return;
637 	}
638 
639 	macaddr = wlan_peer_get_macaddr(peer);
640 
641 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) {
642 		obj_mgr_err(
643 		"peer(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d",
644 			macaddr[0], macaddr[1], macaddr[2],
645 			macaddr[3], macaddr[4], macaddr[5], id);
646 		wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg);
647 		WLAN_OBJMGR_BUG(0);
648 	}
649 
650 	if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
651 		obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0",
652 				macaddr[0], macaddr[1], macaddr[2],
653 				macaddr[3], macaddr[4], macaddr[5]);
654 		WLAN_OBJMGR_BUG(0);
655 		return;
656 	}
657 	qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]);
658 
659 	/* Provide synchronization from the access to add peer
660 	 * to logically deleted peer list.
661 	 */
662 	wlan_peer_obj_lock(peer);
663 	/* Decrement ref count, free peer object, if ref count == 0 */
664 	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) {
665 		wlan_peer_obj_unlock(peer);
666 		wlan_objmgr_peer_obj_destroy(peer);
667 	} else {
668 		wlan_peer_obj_unlock(peer);
669 	}
670 
671 	return;
672 }
673 qdf_export_symbol(wlan_objmgr_peer_release_ref);
674