diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h index 4e2abdf496c3..623a90212f08 100644 --- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h +++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h @@ -125,6 +125,16 @@ struct pending_stats_requests { struct request_info req[TYPE_MAX]; }; +/** + * struct cca_stats - cca stats + * @congestion: the congestion percentage = (busy_time/total_time)*100 + * for the interval from when the vdev was started to the current time + * (or the time at which the vdev was stopped). + */ +struct cca_stats { + uint32_t congestion; +}; + /** * struct psoc_mc_cp_stats: psoc specific stats * @pending: details of pending requests @@ -144,11 +154,13 @@ struct pdev_mc_cp_stats { }; /** - * struct vdev_mc_cp_stats - vdev specific stats - * @wow_stats: wake_lock stats for vdev + * struct vdev_mc_cp_stats - vdev specific stats + * @wow_stats: wake_lock stats for vdev + * @cca: cca stats */ struct vdev_mc_cp_stats { struct wake_lock_stats wow_stats; + struct cca_stats cca; }; /** @@ -165,18 +177,30 @@ struct peer_mc_cp_stats { uint8_t peer_macaddr[WLAN_MACADDR_LEN]; }; +/** + * struct congestion_stats_event: congestion stats event param + * @vdev_id: vdev_id of the event + * @congestion: the congestion percentage + */ +struct congestion_stats_event { + uint8_t vdev_id; + uint32_t congestion; +}; + /** * struct stats_event - parameters populated by stats event * @num_pdev_stats: num pdev stats * @pdev_stats: if populated array indicating pdev stats (index = pdev_id) * @num_peer_stats: num peer stats * @peer_stats: if populated array indicating peer stats + * @cca_stats: if populated indicates congestion stats */ struct stats_event { uint32_t num_pdev_stats; struct pdev_mc_cp_stats *pdev_stats; uint32_t num_peer_stats; struct peer_mc_cp_stats *peer_stats; + struct congestion_stats_event *cca_stats; }; #endif /* CONFIG_MCL */ diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h index 065c5a8c6ba2..d47f4f1025eb 100644 --- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h +++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h @@ -185,5 +185,15 @@ QDF_STATUS ucfg_mc_cp_stats_get_pending_req(struct wlan_objmgr_psoc *psoc, */ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev); +/** + * ucfg_mc_cp_stats_cca_stats_get() - API to fetch cca stats + * @vdev: pointer to vdev object + * @cca_stats: pointer to cca info + * + * Return - status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_cca_stats_get(struct wlan_objmgr_vdev *vdev, + struct cca_stats *cca_stats); + #endif /* QCA_SUPPORT_CP_STATS */ #endif /* __WLAN_CP_STATS_MC_UCFG_API_H__ */ diff --git a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c index 86cb62127618..5cf37abf99ba 100644 --- a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c +++ b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c @@ -325,6 +325,39 @@ static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc, ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS); } +static void tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc *psoc, + struct stats_event *ev) +{ + struct wlan_objmgr_vdev *vdev; + struct vdev_mc_cp_stats *vdev_mc_stats; + struct vdev_cp_stats *vdev_cp_stats_priv; + + if (!ev->cca_stats) + return; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + ev->cca_stats->vdev_id, + WLAN_CP_STATS_ID); + if (!vdev) { + cp_stats_err("vdev is null"); + return; + } + + vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev); + if (!vdev_cp_stats_priv) { + cp_stats_err("vdev cp stats object is null"); + goto end; + } + + wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv); + vdev_mc_stats = vdev_cp_stats_priv->vdev_stats; + vdev_mc_stats->cca.congestion = ev->cca_stats->congestion; + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); + +end: + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); +} + QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc, struct stats_event *ev) { @@ -334,6 +367,8 @@ QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc, if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_PEER_STATS)) tgt_mc_cp_stats_extract_peer_stats(psoc, ev, false); + tgt_mc_cp_stats_extract_cca_stats(psoc, ev); + return QDF_STATUS_SUCCESS; } diff --git a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c index d364ee4837d6..4568836c811d 100644 --- a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c +++ b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c @@ -532,10 +532,28 @@ QDF_STATUS ucfg_mc_cp_stats_get_pending_req(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS ucfg_mc_cp_stats_cca_stats_get(struct wlan_objmgr_vdev *vdev, + struct cca_stats *cca_stats) +{ + struct vdev_cp_stats *vdev_cp_stats_priv; + struct vdev_mc_cp_stats *vdev_mc_stats; + + vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev); + if (!vdev_cp_stats_priv) { + cp_stats_err("vdev cp stats object is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv); + vdev_mc_stats = vdev_cp_stats_priv->vdev_stats; + cca_stats->congestion = vdev_mc_stats->cca.congestion; + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); + return QDF_STATUS_SUCCESS; +} + void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev) { qdf_mem_free(ev->pdev_stats); qdf_mem_free(ev->peer_stats); qdf_mem_zero(ev, sizeof(*ev)); } -