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