/*
 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
 /**
  * DOC: Public APIs to perform operations on Global objects
  */

#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include <qdf_mem.h>
#include "wlan_objmgr_global_obj_i.h"
#include "wlan_objmgr_psoc_obj_i.h"
#include "wlan_objmgr_pdev_obj_i.h"

/**
 ** APIs to Create/Delete Global object APIs
 */
static QDF_STATUS wlan_objmgr_psoc_object_status(
			struct wlan_objmgr_psoc *psoc)
{
	uint8_t id;
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	wlan_psoc_obj_lock(psoc);
	/* Iterate through all components to derive the object status */
	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
		/* If component disabled, Ignore */
		if (psoc->obj_status[id] == QDF_STATUS_COMP_DISABLED)
			continue;
		/* If component operates in Async, status is Partially created,
		 * break
		 */
		else if (psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
			if (psoc->soc_comp_priv_obj[id] == NULL) {
				status = QDF_STATUS_COMP_ASYNC;
				break;
			}
		/*
		 * If component failed to allocate its object, treat it as
		 * failure, complete object need to be cleaned up
		 */
		} else if ((psoc->obj_status[id] == QDF_STATUS_E_NOMEM) ||
			(psoc->obj_status[id] == QDF_STATUS_E_FAILURE)) {
			status = QDF_STATUS_E_FAILURE;
			break;
		}
	}
	wlan_psoc_obj_unlock(psoc);

	return status;
}

static void wlan_objmgr_psoc_peer_list_init(struct wlan_peer_list *peer_list)
{
	uint8_t i;

	qdf_spinlock_create(&peer_list->peer_list_lock);
	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
		qdf_list_create(&peer_list->peer_hash[i],
				WLAN_UMAC_PSOC_MAX_PEERS);
}

static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list)
{
	uint8_t i;

	/* deinit the lock */
	qdf_spinlock_destroy(&peer_list->peer_list_lock);
	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
		qdf_list_destroy(&peer_list->peer_hash[i]);
}

static QDF_STATUS wlan_objmgr_psoc_obj_free(struct wlan_objmgr_psoc *psoc)
{
	struct wlan_psoc_host_service_ext_param *ext_param =
		&(psoc->ext_service_param.service_ext_param);

	/* Detach PSOC from global object's psoc list  */
	if (wlan_objmgr_psoc_object_detach(psoc) == QDF_STATUS_E_FAILURE) {
		obj_mgr_err("PSOC object detach failed");
		return QDF_STATUS_E_FAILURE;
	}
	wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list);
	wlan_objmgr_ext_service_ready_chainmask_table_free(ext_param);

	qdf_spinlock_destroy(&psoc->psoc_lock);
	qdf_mem_free(psoc);

	return QDF_STATUS_SUCCESS;
}

struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version,
						WLAN_DEV_TYPE dev_type)
{
	uint8_t id;
	struct wlan_objmgr_psoc *psoc = NULL;
	wlan_objmgr_psoc_create_handler handler;
	wlan_objmgr_psoc_status_handler stat_handler;
	struct wlan_objmgr_psoc_objmgr *objmgr;
	QDF_STATUS obj_status;
	void *arg;

	psoc = qdf_mem_malloc(sizeof(*psoc));
	if (psoc == NULL) {
		obj_mgr_err("PSOC allocation failed");
		return NULL;
	}
	qdf_spinlock_create(&psoc->psoc_lock);
	/* Initialize with default values */
	objmgr = &psoc->soc_objmgr;
	objmgr->wlan_pdev_count = 0;
	objmgr->wlan_vdev_count = 0;
	objmgr->max_vdev_count = WLAN_UMAC_PSOC_MAX_VDEVS;
	objmgr->wlan_peer_count = 0;
	qdf_atomic_init(&objmgr->ref_cnt);
	objmgr->print_cnt = 0;
	/* set phy version, dev_type in psoc */
	wlan_psoc_set_nif_phy_version(psoc, phy_version);
	wlan_psoc_set_dev_type(psoc, dev_type);
	/* Initialize peer list */
	wlan_objmgr_psoc_peer_list_init(&objmgr->peer_list);
	wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID);
	/* Invoke registered create handlers */
	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
		handler = g_umac_glb_obj->psoc_create_handler[id];
		arg = g_umac_glb_obj->psoc_create_handler_arg[id];
		if (handler != NULL)
			psoc->obj_status[id] = handler(psoc, arg);
		else
			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
	}
	/* Derive object status */
	obj_status = wlan_objmgr_psoc_object_status(psoc);

	if (obj_status == QDF_STATUS_SUCCESS) {
		/* Object status is SUCCESS, Object is created */
		psoc->obj_state = WLAN_OBJ_STATE_CREATED;
		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
			stat_handler = g_umac_glb_obj->psoc_status_handler[id];
			arg = g_umac_glb_obj->psoc_status_handler_arg[id];
			if (stat_handler != NULL)
				stat_handler(psoc, arg,
					     QDF_STATUS_SUCCESS);
		}
	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
		/*
		 * Few components operates in Asynchrous communction
		 * Object state partially created
		 */
		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
	} else if (obj_status == QDF_STATUS_E_FAILURE) {
		/* Component object failed to be created, clean up the object */
		obj_mgr_err("PSOC component objects allocation failed");
		/* Clean up the psoc */
		wlan_objmgr_psoc_obj_delete(psoc);
		return NULL;
	}

	if (wlan_objmgr_psoc_object_attach(psoc) !=
				QDF_STATUS_SUCCESS) {
		obj_mgr_err("PSOC object attach failed");
		wlan_objmgr_psoc_obj_delete(psoc);
		return NULL;
	}

	return psoc;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_obj_create);

static QDF_STATUS wlan_objmgr_psoc_obj_destroy(struct wlan_objmgr_psoc *psoc)
{
	uint8_t id;
	wlan_objmgr_psoc_destroy_handler handler;
	QDF_STATUS obj_status;
	void *arg;

	if (psoc == NULL) {
		obj_mgr_err("psoc is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	if (psoc->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
		obj_mgr_err("psoc object delete is not invoked");
		WLAN_OBJMGR_BUG(0);
	}

	/* Invoke registered create handlers */
	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
		handler = g_umac_glb_obj->psoc_destroy_handler[id];
		arg = g_umac_glb_obj->psoc_destroy_handler_arg[id];
		if (handler != NULL)
			psoc->obj_status[id] = handler(psoc, arg);
		else
			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
	}
	/* Derive object status */
	obj_status = wlan_objmgr_psoc_object_status(psoc);

	if (obj_status == QDF_STATUS_E_FAILURE) {
		obj_mgr_err("PSOC component object free failed");
		/* Ideally should not happen
		 * This leads to memleak, BUG_ON to find which component
		 * delete notification failed and fix it.
		 */
		QDF_BUG(0);
		return QDF_STATUS_E_FAILURE;
	}
	/* Deletion is in progress */
	if (obj_status == QDF_STATUS_COMP_ASYNC) {
		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
		return QDF_STATUS_COMP_ASYNC;
	}

	/* Free psoc object */
	return wlan_objmgr_psoc_obj_free(psoc);
}


QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc)
{
	uint8_t print_idx;

	if (psoc == NULL) {
		obj_mgr_err("psoc is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	print_idx = qdf_get_pidx();

	if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR,
		QDF_TRACE_LEVEL_DEBUG)) {
		obj_mgr_debug("Logically deleting the psoc");
		wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg);
	}

	/*
	 * Update PSOC object state to LOGICALLY DELETED
	 * It prevents further access of this object
	 */
	wlan_psoc_obj_lock(psoc);
	psoc->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
	wlan_psoc_obj_unlock(psoc);
	wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID);

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_obj_delete);

QDF_STATUS wlan_objmgr_psoc_component_obj_attach(
		struct wlan_objmgr_psoc *psoc,
		enum wlan_umac_comp_id id,
		void *comp_priv_obj,
		QDF_STATUS status)
{
	wlan_objmgr_psoc_status_handler stat_handler;
	void *arg = NULL;
	QDF_STATUS obj_status;
	uint8_t i;

	/* component id is invalid */
	if (id >= WLAN_UMAC_MAX_COMPONENTS)
		return QDF_STATUS_MAXCOMP_FAIL;

	wlan_psoc_obj_lock(psoc);
	/* If there is a valid entry, return failure */
	if (psoc->soc_comp_priv_obj[id] != NULL) {
		wlan_psoc_obj_unlock(psoc);
		return QDF_STATUS_E_FAILURE;
	}
	/* Save component's pointer and status */
	psoc->soc_comp_priv_obj[id] = comp_priv_obj;
	psoc->obj_status[id] = status;

	wlan_psoc_obj_unlock(psoc);

	if (psoc->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
		return QDF_STATUS_SUCCESS;
	/* If PSOC object status is partially created means, this API is
	 * invoked with differnt context, this block should be executed for
	 * async components only
	 */
	/* Derive status */
	obj_status = wlan_objmgr_psoc_object_status(psoc);
	/* STATUS_SUCCESS means, object is CREATED */
	if (obj_status == QDF_STATUS_SUCCESS)
		psoc->obj_state = WLAN_OBJ_STATE_CREATED;
	/* update state as CREATION failed, caller has to delete the
	 * PSOC object
	 */
	else if (obj_status == QDF_STATUS_E_FAILURE)
		psoc->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;

	/* Notify components about the CREATION success/failure */
	if ((obj_status == QDF_STATUS_SUCCESS) ||
	    (obj_status == QDF_STATUS_E_FAILURE)) {
		/* nofity object status */
		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
			stat_handler = g_umac_glb_obj->psoc_status_handler[i];
			arg = g_umac_glb_obj->psoc_status_handler_arg[i];
			if (stat_handler != NULL)
				stat_handler(psoc, arg, obj_status);
		}
	}

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_component_obj_attach);

QDF_STATUS wlan_objmgr_psoc_component_obj_detach(
		struct wlan_objmgr_psoc *psoc,
		enum wlan_umac_comp_id id,
		void *comp_priv_obj)
{
	QDF_STATUS obj_status;

	/* component id is invalid */
	if (id >= WLAN_UMAC_MAX_COMPONENTS)
		return QDF_STATUS_MAXCOMP_FAIL;

	wlan_psoc_obj_lock(psoc);
	/* If there is a valid entry, return failure */
	if (psoc->soc_comp_priv_obj[id] != comp_priv_obj) {
		psoc->obj_status[id] = QDF_STATUS_E_FAILURE;
		wlan_psoc_obj_unlock(psoc);
		return QDF_STATUS_E_FAILURE;
	}
	/* Reset pointers to NULL, update the status*/
	psoc->soc_comp_priv_obj[id] = NULL;
	psoc->obj_status[id] = QDF_STATUS_SUCCESS;
	wlan_psoc_obj_unlock(psoc);

	/* If PSOC object status is partially created means, this API is
	 * invoked with differnt context, this block should be executed for
	 * async components only
	 */
	if ((psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
	    (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
		/* Derive object status */
		obj_status = wlan_objmgr_psoc_object_status(psoc);
		if (obj_status == QDF_STATUS_SUCCESS) {
			/* Update the status as Deleted, if full object
			 * deletion is in progress
			 */
			if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
				psoc->obj_state = WLAN_OBJ_STATE_DELETED;

			/* Move to creation state, since this component
			 * deletion alone requested
			 */
			if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
				psoc->obj_state = WLAN_OBJ_STATE_CREATED;
		/* Object status is failure */
		} else if (obj_status == QDF_STATUS_E_FAILURE) {
			/* Update the status as Deletion failed, if full object
			 * deletion is in progress
			 */
			if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
				psoc->obj_state =
					WLAN_OBJ_STATE_DELETION_FAILED;

			/* Move to creation state, since this component
			 * deletion alone requested (do not block other
			 * components)
			 */
			if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
				psoc->obj_state = WLAN_OBJ_STATE_CREATED;
		}

		/* Delete psoc object */
		if ((obj_status == QDF_STATUS_SUCCESS)  &&
		    (psoc->obj_state == WLAN_OBJ_STATE_DELETED)) {
			/* Free psoc object */
			return wlan_objmgr_psoc_obj_free(psoc);
		}
	}

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_component_obj_detach);

QDF_STATUS wlan_objmgr_iterate_obj_list(
		struct wlan_objmgr_psoc *psoc,
		enum wlan_objmgr_obj_type obj_type,
		wlan_objmgr_op_handler handler,
		void *arg, uint8_t lock_free_op,
		wlan_objmgr_ref_dbgid dbg_id)
{
	uint16_t obj_id;
	uint8_t i;
	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
	struct wlan_peer_list *peer_list;
	qdf_list_t *obj_list;
	struct wlan_objmgr_pdev *pdev;
	struct wlan_objmgr_vdev *vdev;
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_next;

	/* If caller requests for lock free opeation, do not acquire,
	 * handler will handle the synchronization
	 */
	if (!lock_free_op)
		wlan_psoc_obj_lock(psoc);

	switch (obj_type) {
	case WLAN_PDEV_OP:
		/* Iterate through PDEV list, invoke handler for each pdev */
		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
			pdev = objmgr->wlan_pdev_list[obj_id];
			if ((pdev != NULL) &&
			    (pdev->obj_state !=
				WLAN_OBJ_STATE_LOGICALLY_DELETED)) {
				wlan_objmgr_pdev_get_ref(pdev, dbg_id);
				handler(psoc, (void *)pdev, arg);
				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
			}
		}
		break;
	case WLAN_VDEV_OP:
		/* Iterate through VDEV list, invoke handler for each vdev */
		for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
			vdev = objmgr->wlan_vdev_list[obj_id];
			if ((vdev != NULL) &&
			    (vdev->obj_state !=
				WLAN_OBJ_STATE_LOGICALLY_DELETED)) {
				wlan_objmgr_vdev_get_ref(vdev, dbg_id);
				handler(psoc, vdev, arg);
				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
			}
		}
		break;
	case WLAN_PEER_OP:
		/* Iterate through PEER list, invoke handler for each peer */
		peer_list = &objmgr->peer_list;
		/* psoc lock should be taken before list lock */
		if (!lock_free_op)
			qdf_spin_lock_bh(&peer_list->peer_list_lock);
		/* Since peer list has sublist, iterate through sublists */
		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
			obj_list = &peer_list->peer_hash[i];
			peer = wlan_psoc_peer_list_peek_head(obj_list);
			while (peer) {
				/* Get next peer */
				peer_next = wlan_peer_get_next_peer_of_psoc(
								obj_list, peer);
				if (wlan_objmgr_peer_try_get_ref(peer, dbg_id)
						== QDF_STATUS_SUCCESS) {
					handler(psoc, (void *)peer, arg);
					wlan_objmgr_peer_release_ref(peer,
								     dbg_id);
				}
				peer = peer_next;
			}
		}
		if (!lock_free_op)
			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
		break;
	default:
		break;
	}
	if (!lock_free_op)
		wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_iterate_obj_list);

QDF_STATUS wlan_objmgr_iterate_obj_list_all(
		struct wlan_objmgr_psoc *psoc,
		enum wlan_objmgr_obj_type obj_type,
		wlan_objmgr_op_handler handler,
		void *arg, uint8_t lock_free_op,
		wlan_objmgr_ref_dbgid dbg_id)
{
	uint16_t obj_id;
	uint8_t i;
	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
	struct wlan_peer_list *peer_list;
	qdf_list_t *obj_list;
	struct wlan_objmgr_pdev *pdev;
	struct wlan_objmgr_vdev *vdev;
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_next;

	/* If caller requests for lock free opeation, do not acquire,
	 * handler will handle the synchronization
	 */
	if (!lock_free_op)
		wlan_psoc_obj_lock(psoc);

	switch (obj_type) {
	case WLAN_PDEV_OP:
		/* Iterate through PDEV list, invoke handler for each pdev */
		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
			pdev = objmgr->wlan_pdev_list[obj_id];
			if (pdev != NULL) {
				wlan_objmgr_pdev_get_ref(pdev, dbg_id);
				handler(psoc, (void *)pdev, arg);
				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
			}
		}
		break;
	case WLAN_VDEV_OP:
		/* Iterate through VDEV list, invoke handler for each vdev */
		for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
			vdev = objmgr->wlan_vdev_list[obj_id];
			if (vdev != NULL) {
				wlan_objmgr_vdev_get_ref(vdev, dbg_id);
				handler(psoc, vdev, arg);
				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
			}
		}
		break;
	case WLAN_PEER_OP:
		/* Iterate through PEER list, invoke handler for each peer */
		peer_list = &objmgr->peer_list;
		/* psoc lock should be taken before list lock */
		if (!lock_free_op)
			qdf_spin_lock_bh(&peer_list->peer_list_lock);
		/* Since peer list has sublist, iterate through sublists */
		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
			obj_list = &peer_list->peer_hash[i];
			peer = wlan_psoc_peer_list_peek_head(obj_list);
			while (peer) {
				/* Get next peer */
				peer_next = wlan_peer_get_next_peer_of_psoc(
								obj_list, peer);
				wlan_objmgr_peer_get_ref(peer, dbg_id);
				handler(psoc, (void *)peer, arg);
				wlan_objmgr_peer_release_ref(peer, dbg_id);
				peer = peer_next;
			}
		}
		if (!lock_free_op)
			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
		break;
	default:
		break;
	}
	if (!lock_free_op)
		wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_iterate_obj_list_all);

static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc,
					 void *obj, void *args)
{
	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;

	wlan_objmgr_peer_obj_delete(peer);
}

static void wlan_objmgr_psoc_vdev_delete(struct wlan_objmgr_psoc *psoc,
					 void *obj, void *args)
{
	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;

	wlan_objmgr_vdev_obj_delete(vdev);
}

static void wlan_objmgr_psoc_pdev_delete(struct wlan_objmgr_psoc *psoc,
					 void *obj, void *args)
{
	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;

	wlan_objmgr_pdev_obj_delete(pdev);
}

QDF_STATUS wlan_objmgr_free_all_objects_per_psoc(
		struct wlan_objmgr_psoc *psoc)
{
	/* Free all peers */
	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
				     wlan_objmgr_psoc_peer_delete, NULL, 1,
				     WLAN_OBJMGR_ID);
	/* Free all vdevs */
	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
				     wlan_objmgr_psoc_vdev_delete, NULL, 1,
				     WLAN_OBJMGR_ID);
	/* Free all PDEVs */
	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
				     wlan_objmgr_psoc_pdev_delete, NULL, 1,
				     WLAN_OBJMGR_ID);

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_creation(
		struct wlan_objmgr_psoc *psoc,
		enum wlan_umac_comp_id id)
{
	wlan_objmgr_psoc_create_handler handler;
	void *arg;
	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;

	/* Component id is invalid */
	if (id >= WLAN_UMAC_MAX_COMPONENTS)
		return QDF_STATUS_MAXCOMP_FAIL;

	wlan_psoc_obj_lock(psoc);
	/* If component object is already created, delete old
	 * component object, then invoke creation
	 */
	if (psoc->soc_comp_priv_obj[id] != NULL) {
		wlan_psoc_obj_unlock(psoc);
		return QDF_STATUS_E_FAILURE;
	}
	wlan_psoc_obj_unlock(psoc);
	/* Invoke registered create handlers */
	handler = g_umac_glb_obj->psoc_create_handler[id];
	arg = g_umac_glb_obj->psoc_create_handler_arg[id];
	if (handler != NULL)
		psoc->obj_status[id] = handler(psoc, arg);
	else
		return QDF_STATUS_E_FAILURE;

	/* If object status is created, then only handle this object status */
	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
		/* Derive object status */
		obj_status = wlan_objmgr_psoc_object_status(psoc);
		/* Move PSOC object state to Partially created state */
		if (obj_status == QDF_STATUS_COMP_ASYNC) {
			/*TODO atomic */
			psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
		}
	}

	return obj_status;
}

QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_deletion(
		struct wlan_objmgr_psoc *psoc,
		enum wlan_umac_comp_id id)
{
	wlan_objmgr_psoc_destroy_handler handler;
	void *arg;
	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;

	/* component id is invalid */
	if (id >= WLAN_UMAC_MAX_COMPONENTS)
		return QDF_STATUS_MAXCOMP_FAIL;

	wlan_psoc_obj_lock(psoc);
	/* Component object was never created, invalid operation */
	if (psoc->soc_comp_priv_obj[id] == NULL) {
		wlan_psoc_obj_unlock(psoc);
		return QDF_STATUS_E_FAILURE;
	}
	wlan_psoc_obj_unlock(psoc);
	/* Invoke registered create handlers */
	handler = g_umac_glb_obj->psoc_destroy_handler[id];
	arg = g_umac_glb_obj->psoc_destroy_handler_arg[id];
	if (handler != NULL)
		psoc->obj_status[id] = handler(psoc, arg);
	else
		return QDF_STATUS_E_FAILURE;

	/* If object status is created, then only handle this object status */
	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
		obj_status = wlan_objmgr_psoc_object_status(psoc);
			/* move object state to DEL progress */
		if (obj_status == QDF_STATUS_COMP_ASYNC)
			psoc->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
	}

	return obj_status;
}

/* Util APIs */

QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc,
					struct wlan_objmgr_pdev *pdev)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t id = 0;
	QDF_STATUS status;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/*
	 * Derive pdev id from pdev map
	 * First free pdev id is assigned
	 */
	while ((id < WLAN_UMAC_MAX_PDEVS) &&
			(objmgr->wlan_pdev_id_map & (1<<id)))
		id++;

	if (id == WLAN_UMAC_MAX_PDEVS) {
		status = QDF_STATUS_E_FAILURE;
	} else {
		/* Update the map for reserving the id */
		objmgr->wlan_pdev_id_map |= (1<<id);
		/* store pdev in pdev list */
		objmgr->wlan_pdev_list[id] = pdev;
		/* Increment pdev count */
		objmgr->wlan_pdev_count++;
		/* save pdev id */
		pdev->pdev_objmgr.wlan_pdev_id = id;
		status = QDF_STATUS_SUCCESS;
		/* Inrement psoc ref count to block its free before pdev */
		wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID);
	}
	wlan_psoc_obj_unlock(psoc);

	return status;
}

QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc,
						struct wlan_objmgr_pdev *pdev)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t id;

	id = pdev->pdev_objmgr.wlan_pdev_id;
	/* If id is invalid, return */
	if (id >= WLAN_UMAC_MAX_PDEVS)
		return QDF_STATUS_E_FAILURE;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* Free pdev id slot */
	objmgr->wlan_pdev_id_map &= ~(1<<id);
	objmgr->wlan_pdev_list[id] = NULL;
	objmgr->wlan_pdev_count--;
	pdev->pdev_objmgr.wlan_pdev_id = 0xff;
	wlan_psoc_obj_unlock(psoc);
	/* Release ref count of psoc */
	wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID);

	return QDF_STATUS_SUCCESS;
}

struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id(
		struct wlan_objmgr_psoc *psoc, uint8_t id,
		wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	struct wlan_objmgr_pdev *pdev = NULL;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* get pdev from pdev list */
	pdev = objmgr->wlan_pdev_list[id];
	/* Do not return object, if it is not CREATED state */
	if (pdev != NULL) {
		if (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) !=
							QDF_STATUS_SUCCESS)
			pdev = NULL;
	}

	wlan_psoc_obj_unlock(psoc);

	return pdev;
}
EXPORT_SYMBOL(wlan_objmgr_get_pdev_by_id);

struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id_no_state(
		struct wlan_objmgr_psoc *psoc, uint8_t id,
		wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	struct wlan_objmgr_pdev *pdev = NULL;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* get pdev from pdev list */
	pdev = objmgr->wlan_pdev_list[id];
	/* Do not return object, if it is not CREATED state */
	if (pdev != NULL)
		wlan_objmgr_pdev_get_ref(pdev, dbg_id);

	wlan_psoc_obj_unlock(psoc);

	return pdev;
}
QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc,
					struct wlan_objmgr_vdev *vdev)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t id = 0;
	uint8_t map_index = 0;
	uint8_t map_entry_size = 32;
	uint8_t adjust_ix = 0;
	QDF_STATUS status;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* Find first free vdev id */
	while ((id < objmgr->max_vdev_count) &&
		(objmgr->wlan_vdev_id_map[map_index] & (1<<(id - adjust_ix)))) {
		id++;
		/*
		 * The map is two DWORDS(32 bits), so, map_index
		 * adjust_ix derived based on the id value
		 */
		if (id == ((map_index + 1) * map_entry_size)) {
			map_index++;
			adjust_ix = map_index * map_entry_size;
		}
	}
	/* If no free slot, return failure */
	if (id == objmgr->max_vdev_count) {
		status = QDF_STATUS_E_FAILURE;
	} else {
		/* set free vdev id index */
		objmgr->wlan_vdev_id_map[map_index] |= (1<<(id-adjust_ix));
		/* store vdev pointer in vdev list */
		objmgr->wlan_vdev_list[id] = vdev;
		/* increment vdev counter */
		objmgr->wlan_vdev_count++;
		/* save vdev id */
		vdev->vdev_objmgr.vdev_id = id;
		status = QDF_STATUS_SUCCESS;
	}
	wlan_psoc_obj_unlock(psoc);

	return status;
}

QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc,
					struct wlan_objmgr_vdev *vdev)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t id = 0;
	uint8_t map_index = 0;
	uint8_t map_entry_size = 32;
	uint8_t adjust_ix = 0;

	id = vdev->vdev_objmgr.vdev_id;
	/* Invalid vdev id */
	if (id >= WLAN_UMAC_PSOC_MAX_VDEVS)
		return QDF_STATUS_E_FAILURE;
	/*
	 * Derive map_index and adjust_ix to find actual DWORD
	 * the id map is present
	 */
	while ((id - adjust_ix) >= map_entry_size) {
		map_index++;
		adjust_ix = map_index * map_entry_size;
	}
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* unset bit, to free the slot */
	objmgr->wlan_vdev_id_map[map_index] &= ~(1<<(id-adjust_ix));
	/* reset VDEV pointer to NULL in VDEV list array */
	objmgr->wlan_vdev_list[id] = NULL;
	/* decrement vdev count */
	objmgr->wlan_vdev_count--;
	vdev->vdev_objmgr.vdev_id = 0xff;
	wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}

struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc(
			struct wlan_objmgr_psoc *psoc,
			enum QDF_OPMODE opmode,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_vdev *vdev = NULL;
	int vdev_cnt = 0;

	/* if PSOC is NULL, return */
	if (psoc == NULL)
		return NULL;

	wlan_psoc_obj_lock(psoc);

	/* retrieve vdev pointer from vdev list */
	while (vdev_cnt < WLAN_UMAC_PSOC_MAX_VDEVS) {
		vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt];
		vdev_cnt++;
		if (vdev == NULL)
			continue;
		wlan_vdev_obj_lock(vdev);
		if (vdev->vdev_mlme.vdev_opmode == opmode) {
			wlan_vdev_obj_unlock(vdev);
			if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
							QDF_STATUS_SUCCESS) {
				vdev = NULL;
				continue;
			}
			break;
		}
		wlan_vdev_obj_unlock(vdev);
	}
	wlan_psoc_obj_unlock(psoc);

	return vdev;
}

struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc(
			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_vdev *vdev;

	/* if PSOC is NULL, return */
	if (psoc == NULL)
		return NULL;
	/* vdev id is invalid */
	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
		return NULL;

	wlan_psoc_obj_lock(psoc);
	/* retrieve vdev pointer from vdev list */
	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
	if (vdev != NULL) {
		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
							QDF_STATUS_SUCCESS)
			vdev = NULL;
	}
	wlan_psoc_obj_unlock(psoc);

	return vdev;
}
EXPORT_SYMBOL(wlan_objmgr_get_vdev_by_id_from_psoc);

struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state(
			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_vdev *vdev;

	/* if PSOC is NULL, return */
	if (psoc == NULL)
		return NULL;
	/* vdev id is invalid */
	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
		return NULL;

	wlan_psoc_obj_lock(psoc);
	/* retrieve vdev pointer from vdev list */
	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
	if (vdev != NULL)
		wlan_objmgr_vdev_get_ref(vdev, dbg_id);

	wlan_psoc_obj_unlock(psoc);

	return vdev;
}
EXPORT_SYMBOL(wlan_objmgr_get_vdev_by_id_from_psoc_no_state);

struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc(
		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
		wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_vdev *vdev;
	uint8_t id;

	/* if PSOC is NULL, return */
	if (psoc == NULL)
		return NULL;

	wlan_psoc_obj_lock(psoc);
	/* Iterate through PSOC's vdev list */
	for (id = 0; id < WLAN_UMAC_PSOC_MAX_VDEVS; id++) {
		vdev = psoc->soc_objmgr.wlan_vdev_list[id];
		if (vdev == NULL)
			continue;
		/* MAC address matches, break */
		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
			== QDF_STATUS_SUCCESS) {
			if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
							QDF_STATUS_SUCCESS)
				vdev = NULL;

			wlan_psoc_obj_unlock(psoc);

			return vdev;
		}
	}
	wlan_psoc_obj_unlock(psoc);

	return NULL;
}
EXPORT_SYMBOL(wlan_objmgr_get_vdev_by_macaddr_from_psoc);

struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state(
		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
		wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_vdev *vdev;
	uint8_t id;

	/* if PSOC is NULL, return */
	if (psoc == NULL)
		return NULL;

	wlan_psoc_obj_lock(psoc);
	/* Iterate through PSOC's vdev list */
	for (id = 0; id < WLAN_UMAC_PSOC_MAX_VDEVS; id++) {
		vdev = psoc->soc_objmgr.wlan_vdev_list[id];
		if (vdev == NULL)
			continue;
		/* MAC address matches, break */
		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
			== QDF_STATUS_SUCCESS) {
			wlan_objmgr_vdev_get_ref(vdev, dbg_id);
			wlan_psoc_obj_unlock(psoc);

			return vdev;
		}
	}
	wlan_psoc_obj_unlock(psoc);

	return NULL;
}
EXPORT_SYMBOL(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state);

static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list,
				struct wlan_objmgr_peer *obj)
{
	qdf_list_insert_back(obj_list, &obj->psoc_peer);
}

static QDF_STATUS wlan_obj_psoc_peerlist_remove_peer(
				qdf_list_t *obj_list,
				struct wlan_objmgr_peer *peer)
{
	qdf_list_node_t *psoc_node = NULL;

	if (peer == NULL)
		return QDF_STATUS_E_FAILURE;
	/* get vdev list node element */
	psoc_node = &peer->psoc_peer;
	/* list is empty, return failure */
	if (qdf_list_remove_node(obj_list, psoc_node) != QDF_STATUS_SUCCESS)
		return QDF_STATUS_E_FAILURE;

	return QDF_STATUS_SUCCESS;
}

static QDF_STATUS wlan_peer_bssid_match(struct wlan_objmgr_peer *peer,
				     uint8_t *bssid)
{
	struct wlan_objmgr_vdev *vdev = wlan_peer_get_vdev(peer);
	uint8_t *peer_bssid = wlan_vdev_mlme_get_macaddr(vdev);

	if (WLAN_ADDR_EQ(peer_bssid, bssid) == QDF_STATUS_SUCCESS)
		return QDF_STATUS_SUCCESS;
	else
		return QDF_STATUS_E_FAILURE;
}

/**
 * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer
 * from psoc peer list
 * @psoc: PSOC object
 * @macaddr: MAC address
 *
 * API to finds peer object pointer of logically deleted peer
 *
 * Return: peer pointer
 *         NULL on FAILURE
 */
static struct wlan_objmgr_peer *
			wlan_obj_psoc_peerlist_get_peer_logically_deleted(
				qdf_list_t *obj_list, uint8_t *macaddr,
				wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_temp;

	/* Iterate through hash list to get the peer */
	peer = wlan_psoc_peer_list_peek_head(obj_list);
	while (peer != NULL) {
		/* For peer, macaddr is key */
		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
			== QDF_STATUS_SUCCESS) {
			/* Return peer in logically deleted state */
			if (peer->obj_state ==
					WLAN_OBJ_STATE_LOGICALLY_DELETED) {
				wlan_objmgr_peer_get_ref(peer, dbg_id);

				return peer;
			}

		}
		/* Move to next peer */
		peer_temp = peer;
		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
	}

	/* Not found, return NULL */
	return NULL;
}

/**
 * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list
 * @psoc: PSOC object
 * @macaddr: MAC address
 *
 * API to finds peer object pointer by MAC addr from hash list
 *
 * Return: peer pointer
 *         NULL on FAILURE
 */
static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer(
				qdf_list_t *obj_list, uint8_t *macaddr,
				wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_temp;

	/* Iterate through hash list to get the peer */
	peer = wlan_psoc_peer_list_peek_head(obj_list);
	while (peer != NULL) {
		/* For peer, macaddr is key */
		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
			== QDF_STATUS_SUCCESS) {
			if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
							QDF_STATUS_SUCCESS) {
				return peer;
			}
		}
		/* Move to next peer */
		peer_temp = peer;
		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
	}

	/* Not found, return NULL */
	return NULL;
}

static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state(
				qdf_list_t *obj_list, uint8_t *macaddr,
				wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_temp;

	/* Iterate through hash list to get the peer */
	peer = wlan_psoc_peer_list_peek_head(obj_list);
	while (peer != NULL) {
		/* For peer, macaddr is key */
		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
			== QDF_STATUS_SUCCESS) {
			wlan_objmgr_peer_get_ref(peer, dbg_id);

			return peer;
		}
		/* Move to next peer */
		peer_temp = peer;
		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
	}

	/* Not found, return NULL */
	return NULL;
}

/**
 * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - get peer
 *                                           from psoc peer list using
 *                                           mac and vdev self mac
 * @obj_list: peer object list
 * @macaddr: MAC address
 * @bssid: BSSID address
 * @dbg_id: id of the caller
 *
 * API to finds peer object pointer by MAC addr and BSSID from
 * peer hash list for a node which is in logically deleted state,
 * bssid check is done on matching peer
 *
 * Caller to free the list allocated in this function
 *
 * Return: list of peer pointers
 *         NULL on FAILURE
 */
static qdf_list_t
	*wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid(
				qdf_list_t *obj_list, uint8_t *macaddr,
				uint8_t *bssid,
				wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_temp;
	struct wlan_logically_del_peer *peer_list = NULL;
	qdf_list_t *logical_del_peer_list = NULL;
	bool lock_released = false;

	logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list));
	if (!logical_del_peer_list) {
		obj_mgr_err("failed to allocate list");
		return NULL;
	}

	qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS);

	/* Iterate through hash list to get the peer */
	peer = wlan_psoc_peer_list_peek_head(obj_list);
	while (peer != NULL) {
		wlan_peer_obj_lock(peer);
		/* For peer, macaddr is key */
		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
			== QDF_STATUS_SUCCESS) {
			/*
			 *  if BSSID not NULL,
			 *  then match is requested by caller, check BSSID
			 *  (vdev mac == bssid) --  return peer
			 *  (vdev mac != bssid) --  perform next iteration
			 */
			if ((bssid == NULL) ||
				(wlan_peer_bssid_match(peer, bssid) ==
				 QDF_STATUS_SUCCESS)) {
				/* Return peer in logically deleted state */
				if ((peer->obj_state ==
					WLAN_OBJ_STATE_LOGICALLY_DELETED) &&
				     qdf_atomic_read(
						&peer->peer_objmgr.ref_cnt)) {

					wlan_objmgr_peer_get_ref(peer, dbg_id);
					wlan_peer_obj_unlock(peer);
					lock_released = true;

					peer_list =
					qdf_mem_malloc(
					sizeof(struct wlan_logically_del_peer));
					if (peer_list == NULL) {
						/* Lock is already released */
						obj_mgr_err("Mem alloc failed");
						break;
					}

					peer_list->peer = peer;

					qdf_list_insert_front(
						logical_del_peer_list,
							&peer_list->list);
				}
			}
		}

		if (!lock_released)
			wlan_peer_obj_unlock(peer);

		/* Move to next peer */
		peer_temp = peer;
		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
		lock_released = false;
	}

	/* Not found, return NULL */
	if (qdf_list_empty(logical_del_peer_list)) {
		qdf_mem_free(logical_del_peer_list);
		return NULL;
	} else {
		return logical_del_peer_list;
	}

}

/**
 * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer from psoc peer
 *                                                    list using mac and vdev
 *                                                    self mac
 * @psoc: PSOC object
 * @macaddr: MAC address
 * @bssid: BSSID address
 *
 * API to finds peer object pointer by MAC addr and BSSID from
 * peer hash list, bssid check is done on matching peer
 *
 * Return: peer pointer
 *         NULL on FAILURE
 */
static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid(
					qdf_list_t *obj_list, uint8_t *macaddr,
					uint8_t *bssid,
					wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_temp;

	/* Iterate through hash list to get the peer */
	peer = wlan_psoc_peer_list_peek_head(obj_list);
	while (peer != NULL) {
		/* For peer, macaddr is key */
		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
			== QDF_STATUS_SUCCESS) {
			/*
			 *  BSSID match is requested by caller, check BSSID
			 *  (vdev mac == bssid) --  return peer
			 *  (vdev mac != bssid) --  perform next iteration
			 */
			if (wlan_peer_bssid_match(peer, bssid) ==
							QDF_STATUS_SUCCESS) {
				if (wlan_objmgr_peer_try_get_ref(peer, dbg_id)
					== QDF_STATUS_SUCCESS) {
					return peer;
				}
			}
		}
		/* Move to next peer */
		peer_temp = peer;
		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
	}
	/* Not found, return NULL */
	return NULL;
}

static struct wlan_objmgr_peer
		*wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state(
					qdf_list_t *obj_list, uint8_t *macaddr,
					uint8_t *bssid,
					wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_peer *peer;
	struct wlan_objmgr_peer *peer_temp;

	/* Iterate through hash list to get the peer */
	peer = wlan_psoc_peer_list_peek_head(obj_list);
	while (peer != NULL) {
		/* For peer, macaddr is key */
		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
			== QDF_STATUS_SUCCESS) {
			/*
			 *  BSSID match is requested by caller, check BSSID
			 *  (vdev mac == bssid) --  return peer
			 *  (vdev mac != bssid) --  perform next iteration
			 */
			if (wlan_peer_bssid_match(peer, bssid) ==
							QDF_STATUS_SUCCESS) {
				wlan_objmgr_peer_get_ref(peer, dbg_id);

				return peer;
			}
		}
		/* Move to next peer */
		peer_temp = peer;
		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
	}

	/* Not found, return NULL */
	return NULL;
}

QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc,
					 struct wlan_objmgr_peer *peer)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_peer_list *peer_list;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* Max peer limit is reached, return failure */
	if (objmgr->wlan_peer_count >= WLAN_UMAC_PSOC_MAX_PEERS) {
		wlan_psoc_obj_unlock(psoc);
		return QDF_STATUS_E_FAILURE;
	}
	/* Derive hash index from mac address */
	hash_index = WLAN_PEER_HASH(peer->macaddr);
	peer_list = &objmgr->peer_list;
	/* psoc lock should be taken before list lock */
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* add peer to hash peer list */
	wlan_obj_psoc_peerlist_add_tail(
			&peer_list->peer_hash[hash_index],
							peer);
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	/* Increment peer count */
	objmgr->wlan_peer_count++;
	wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc,
						struct wlan_objmgr_peer *peer)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_peer_list *peer_list;

	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* if list is empty, return */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return QDF_STATUS_E_FAILURE;
	}
	/* Get hash index, to locate the actual peer list */
	hash_index = WLAN_PEER_HASH(peer->macaddr);
	peer_list = &objmgr->peer_list;
	/* psoc lock should be taken before list lock */
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* removes the peer from peer_list */
	if (wlan_obj_psoc_peerlist_remove_peer(
				&peer_list->peer_hash[hash_index],
						peer) ==
				QDF_STATUS_E_FAILURE) {
		qdf_spin_unlock_bh(&peer_list->peer_list_lock);
		wlan_psoc_obj_unlock(psoc);
		obj_mgr_err("Failed to detach peer");
		return QDF_STATUS_E_FAILURE;
	}
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	/* Decrement peer count */
	objmgr->wlan_peer_count--;
	wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}

struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_objmgr_peer *peer = NULL;
	struct wlan_peer_list *peer_list;

	/* psoc lock should be taken before peer list lock */
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return NULL;
	}
	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* Iterate through peer list, get peer */
	peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted(
		&peer_list->peer_hash[hash_index], macaddr, dbg_id);
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	wlan_psoc_obj_unlock(psoc);

	return peer;
}

struct wlan_objmgr_peer *wlan_objmgr_get_peer(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_objmgr_peer *peer = NULL;
	struct wlan_peer_list *peer_list;

	/* psoc lock should be taken before peer list lock */
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return NULL;
	}
	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* Iterate through peer list, get peer */
	peer = wlan_obj_psoc_peerlist_get_peer(
		&peer_list->peer_hash[hash_index], macaddr, dbg_id);
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	wlan_psoc_obj_unlock(psoc);

	return peer;
}
EXPORT_SYMBOL(wlan_objmgr_get_peer);

struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_objmgr_peer *peer = NULL;
	struct wlan_peer_list *peer_list;

	/* psoc lock should be taken before peer list lock */
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0)
		return NULL;

	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	/* Iterate through peer list, get peer */
	peer = wlan_obj_psoc_peerlist_get_peer(
		&peer_list->peer_hash[hash_index], macaddr, dbg_id);

	return peer;
}
EXPORT_SYMBOL(wlan_objmgr_get_peer_nolock);


struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_objmgr_peer *peer = NULL;
	struct wlan_peer_list *peer_list;

	/* psoc lock should be taken before peer list lock */
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return NULL;
	}
	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* Iterate through peer list, get peer */
	peer = wlan_obj_psoc_peerlist_get_peer_no_state(
		&peer_list->peer_hash[hash_index], macaddr, dbg_id);
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	wlan_psoc_obj_unlock(psoc);

	return peer;
}
EXPORT_SYMBOL(wlan_objmgr_get_peer_no_state);

struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			uint8_t *bssid, wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_objmgr_peer *peer = NULL;
	struct wlan_peer_list *peer_list;

	/* psoc lock should be taken before peer list lock */
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return NULL;
	}
	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* Iterate through peer list, get peer */
	peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid(
		&peer_list->peer_hash[hash_index], macaddr, bssid, dbg_id);
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	wlan_psoc_obj_unlock(psoc);

	return peer;
}
EXPORT_SYMBOL(wlan_objmgr_get_peer_by_mac_n_vdev);


/**
 * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - get peer from psoc
 *                                                           peer list using
 *                                                           mac and vdev
 *                                                           self mac
 * @psoc: PSOC object
 * @macaddr: MAC address
 * @bssid: BSSID address. NULL mac means search all.
 * @dbg_id: id of the caller
 *
 * API to finds peer object pointer by MAC addr and BSSID from
 * peer hash list, bssid check is done on matching peer
 *
 * Return: list of peer pointer pointers
 *         NULL on FAILURE
 */

qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			uint8_t *bssid, wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_peer_list *peer_list = NULL;
	qdf_list_t *logical_del_peer_list = NULL;

	/* psoc lock should be taken before peer list lock */
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return NULL;
	}
	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	qdf_spin_lock_bh(&peer_list->peer_list_lock);

	/* Iterate through peer list, get peer */
	logical_del_peer_list =
		wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid(
			&peer_list->peer_hash[hash_index], macaddr,
			bssid, dbg_id);

	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	wlan_psoc_obj_unlock(psoc);

	return logical_del_peer_list;
}
EXPORT_SYMBOL(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev);

struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state(
			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr,
			uint8_t *bssid, wlan_objmgr_ref_dbgid dbg_id)
{
	struct wlan_objmgr_psoc_objmgr *objmgr;
	uint8_t hash_index;
	struct wlan_objmgr_peer *peer = NULL;
	struct wlan_peer_list *peer_list;

	/* psoc lock should be taken before peer list lock */
	wlan_psoc_obj_lock(psoc);
	objmgr = &psoc->soc_objmgr;
	/* List is empty, return NULL */
	if (objmgr->wlan_peer_count == 0) {
		wlan_psoc_obj_unlock(psoc);
		return NULL;
	}
	/* reduce the search window, with hash key */
	hash_index = WLAN_PEER_HASH(macaddr);
	peer_list = &objmgr->peer_list;
	qdf_spin_lock_bh(&peer_list->peer_list_lock);
	/* Iterate through peer list, get peer */
	peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state(
		&peer_list->peer_hash[hash_index], macaddr, bssid, dbg_id);
	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
	wlan_psoc_obj_unlock(psoc);

	return peer;
}
EXPORT_SYMBOL(wlan_objmgr_get_peer_by_mac_n_vdev_no_state);

void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc,
					enum wlan_umac_comp_id id)
{
	void *comp_private_obj;

	/* component id is invalid */
	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
		QDF_BUG(0);
		return NULL;
	}

	if (psoc == NULL) {
		QDF_BUG(0);
		return NULL;
	}

	comp_private_obj = psoc->soc_comp_priv_obj[id];

	return comp_private_obj;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_get_comp_private_obj);

void wlan_objmgr_psoc_get_ref(struct wlan_objmgr_psoc *psoc,
						wlan_objmgr_ref_dbgid id)
{
	if (psoc == NULL) {
		obj_mgr_err("psoc obj is NULL for id:%d", id);
		QDF_ASSERT(0);
		return;
	}
	/* Increment ref count */
	qdf_atomic_inc(&psoc->soc_objmgr.ref_cnt);
	qdf_atomic_inc(&psoc->soc_objmgr.ref_id_dbg[id]);
	return;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_get_ref);

QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc,
						wlan_objmgr_ref_dbgid id)
{
	if (psoc == NULL) {
		obj_mgr_err("psoc obj is NULL for id:%d", id);
		QDF_ASSERT(0);
		return QDF_STATUS_E_FAILURE;
	}

	wlan_psoc_obj_lock(psoc);
	if (psoc->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) {
		wlan_psoc_obj_unlock(psoc);
		if (psoc->soc_objmgr.print_cnt++ <=
				WLAN_OBJMGR_RATELIMIT_THRESH)
			obj_mgr_err("[Ref id: %d] psoc is in L-Del state", id);

		return QDF_STATUS_E_RESOURCES;
	}

	/* Increment ref count */
	wlan_objmgr_psoc_get_ref(psoc, id);
	wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_try_get_ref);

void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc,
						wlan_objmgr_ref_dbgid id)
{
	if (psoc == NULL) {
		obj_mgr_err("psoc obj is NULL for id:%d", id);
		QDF_ASSERT(0);
		return;
	}

	if (!qdf_atomic_read(&psoc->soc_objmgr.ref_id_dbg[id])) {
		obj_mgr_err("psoc ref cnt was not taken by %d", id);
		wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg);
		WLAN_OBJMGR_BUG(0);
	}

	if (!qdf_atomic_read(&psoc->soc_objmgr.ref_cnt)) {
		obj_mgr_err("psoc ref cnt is 0");
		WLAN_OBJMGR_BUG(0);
		return;
	}

	qdf_atomic_dec(&psoc->soc_objmgr.ref_id_dbg[id]);
	/* Decrement ref count, free psoc, if ref count == 0 */
	if (qdf_atomic_dec_and_test(&psoc->soc_objmgr.ref_cnt))
		wlan_objmgr_psoc_obj_destroy(psoc);

	return;
}
EXPORT_SYMBOL(wlan_objmgr_psoc_release_ref);

static void wlan_objmgr_psoc_peer_ref_print(struct wlan_objmgr_psoc *psoc,
					 void *obj, void *args)
{
	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
	uint8_t *macaddr;

	wlan_peer_obj_lock(peer);
	macaddr = wlan_peer_get_macaddr(peer);
	wlan_peer_obj_unlock(peer);

	obj_mgr_info("Peer MAC is %02x:%02x:%02x:%02x:%02x:%02x",
		  macaddr[0], macaddr[1], macaddr[2], macaddr[3],
		  macaddr[4], macaddr[5]);
	wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg);
}

static void wlan_objmgr_psoc_vdev_ref_print(struct wlan_objmgr_psoc *psoc,
					 void *obj, void *args)
{
	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
	uint8_t id;

	wlan_vdev_obj_lock(vdev);
	id = wlan_vdev_get_id(vdev);
	wlan_vdev_obj_unlock(vdev);
	obj_mgr_info("Vdev ID is %d", id);

	wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg);
}

static void wlan_objmgr_psoc_pdev_ref_print(struct wlan_objmgr_psoc *psoc,
					 void *obj, void *args)
{
	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
	uint8_t id;

	wlan_pdev_obj_lock(pdev);
	id = wlan_objmgr_pdev_get_pdev_id(pdev);
	wlan_pdev_obj_unlock(pdev);
	obj_mgr_info("pdev ID is %d", id);

	wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg);
}

QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc(
		struct wlan_objmgr_psoc *psoc)
{
	obj_mgr_info("Ref counts of PEER");
	wlan_objmgr_iterate_obj_list_all(psoc, WLAN_PEER_OP,
				wlan_objmgr_psoc_peer_ref_print, NULL, 1,
				WLAN_OBJMGR_ID);
	obj_mgr_info("Ref counts of VDEV");
	wlan_objmgr_iterate_obj_list_all(psoc, WLAN_VDEV_OP,
				wlan_objmgr_psoc_vdev_ref_print, NULL, 1,
				WLAN_OBJMGR_ID);
	obj_mgr_info("Ref counts of PDEV");
	wlan_objmgr_iterate_obj_list_all(psoc, WLAN_PDEV_OP,
				wlan_objmgr_psoc_pdev_ref_print, NULL, 1,
				WLAN_OBJMGR_ID);

	obj_mgr_info(" Ref counts of PSOC");
	wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg);

	return QDF_STATUS_SUCCESS;
}
EXPORT_SYMBOL(wlan_objmgr_print_ref_all_objects_per_psoc);

QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc,
		struct wlan_objmgr_psoc_user_config *user_config_data)
{
	if (user_config_data == NULL) {
		obj_mgr_err("user_config_data is NULL");
		QDF_BUG(0);
		return QDF_STATUS_E_FAILURE;
	}
	wlan_psoc_obj_lock(psoc);
	qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data,
				sizeof(psoc->soc_nif.user_config));
	wlan_psoc_obj_unlock(psoc);

	return QDF_STATUS_SUCCESS;
}
