qcacmn: Add API to fetch logically deleted peer list of a vdev
Add API to fetch the logically deleted peer list for a given vdev
and also add change to move peer delete request and response
related stats from pdev to vdev layer
Change-Id: Ibaac286a1e6ca86988b223055c15a6b9ba6cf4b9
CRs-Fixed: 2448111
diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h
index 1aa243b..952cd01 100644
--- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h
+++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h
@@ -484,6 +484,25 @@
void *arg, wlan_objmgr_ref_dbgid dbg_id);
/**
+ * wlan_objmgr_vdev_get_log_del_peer_list() - vdev logically deleted peer list
+ * @vdev: vdev object
+ * @dbg_id: id of the caller
+ *
+ * API to be used for populating the list of logically deleted peers from the
+ * vdev's peer list
+ *
+ * The caller of this function should free the memory allocated for the
+ * peerlist and the peer member in the list
+ * Also the peer ref release is handled by the caller
+ *
+ * Return: list of peer pointers
+ * NULL on FAILURE
+ */
+qdf_list_t *wlan_objmgr_vdev_get_log_del_peer_list(
+ struct wlan_objmgr_vdev *vdev,
+ wlan_objmgr_ref_dbgid dbg_id);
+
+/**
* wlan_objmgr_trigger_vdev_comp_priv_object_creation() - vdev
* comp object creation
* @vdev: VDEV object
diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c
index 2f61e34..ead4027 100644
--- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c
+++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c
@@ -523,6 +523,110 @@
return QDF_STATUS_SUCCESS;
}
+/**
+ * wlan_obj_vdev_populate_logically_del_peerlist() - get peer
+ * from vdev peer list
+ * @obj_list: peer object list
+ * @vdev_obj: vdev object mgr substructure
+ * @dbg_id: id of the caller
+ *
+ * API to finds peer object pointer by vdev from peer hash list for a node
+ * which is in logically deleted state
+ *
+ * Caller to free the list allocated in this function
+ *
+ * Return: list of peer pointers
+ * NULL on FAILURE
+ */
+static qdf_list_t *wlan_obj_vdev_populate_logically_del_peerlist(
+ qdf_list_t *obj_list,
+ struct wlan_objmgr_vdev_objmgr *vdev_obj,
+ wlan_objmgr_ref_dbgid dbg_id)
+{
+ struct wlan_objmgr_peer *peer;
+ struct wlan_objmgr_peer *peer_next;
+ struct wlan_logically_del_peer *peer_list;
+ qdf_list_t *logical_del_peerlist;
+ bool lock_released = false;
+
+ logical_del_peerlist = qdf_mem_malloc(sizeof(*logical_del_peerlist));
+ if (!logical_del_peerlist)
+ return NULL;
+
+ qdf_list_create(logical_del_peerlist, vdev_obj->max_peer_count);
+
+ peer = wlan_vdev_peer_list_peek_head(obj_list);
+ while (peer) {
+ wlan_peer_obj_lock(peer);
+ peer_next = wlan_peer_get_next_peer_of_vdev(obj_list, peer);
+ 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(*peer_list));
+ if (!peer_list) {
+ wlan_objmgr_peer_release_ref(peer, dbg_id);
+ WLAN_OBJMGR_BUG(0);
+ break;
+ }
+
+ peer_list->peer = peer;
+ qdf_list_insert_front(logical_del_peerlist,
+ &peer_list->list);
+ }
+
+ if (!lock_released)
+ wlan_peer_obj_unlock(peer);
+
+ peer = peer_next;
+ lock_released = false;
+ }
+
+ /* Not found, return NULL */
+ if (qdf_list_empty(logical_del_peerlist)) {
+ qdf_mem_free(logical_del_peerlist);
+ return NULL;
+ }
+
+ return logical_del_peerlist;
+}
+
+qdf_list_t *wlan_objmgr_vdev_get_log_del_peer_list(
+ struct wlan_objmgr_vdev *vdev,
+ wlan_objmgr_ref_dbgid dbg_id)
+{
+ qdf_list_t *peer_list;
+ qdf_list_t *log_del_peer_list = NULL;
+
+ if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
+ obj_mgr_err("Invalid state vdev:%d state:%d",
+ wlan_vdev_get_id(vdev), vdev->obj_state);
+ return NULL;
+ }
+
+ wlan_vdev_obj_lock(vdev);
+ if (vdev->vdev_objmgr.wlan_peer_count == 0) {
+ wlan_vdev_obj_unlock(vdev);
+ return NULL;
+ }
+
+ wlan_objmgr_vdev_get_ref(vdev, dbg_id);
+ peer_list = &vdev->vdev_objmgr.wlan_peer_list;
+ if (peer_list) {
+ log_del_peer_list =
+ wlan_obj_vdev_populate_logically_del_peerlist(
+ peer_list, &vdev->vdev_objmgr,
+ dbg_id);
+ }
+
+ wlan_objmgr_vdev_release_ref(vdev, dbg_id);
+ wlan_vdev_obj_unlock(vdev);
+
+ return log_del_peer_list;
+}
+
QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_creation(
struct wlan_objmgr_vdev *vdev,
enum wlan_umac_comp_id id)