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 357b86244ec5..ac1f2d9c7b70 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 @@ -173,10 +173,12 @@ struct cca_stats { /** * struct psoc_mc_cp_stats: psoc specific stats + * @is_cp_stats_suspended: is cp stats suspended or not * @pending: details of pending requests * @wow_unspecified_wake_up_count: number of non-wow related wake ups */ struct psoc_mc_cp_stats { + bool is_cp_stats_suspended; struct pending_stats_requests pending; uint32_t wow_unspecified_wake_up_count; }; 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 29cb310f9951..484fe2085c53 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 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 @@ -205,5 +205,16 @@ QDF_STATUS ucfg_mc_cp_stats_cca_stats_get(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev, enum tx_rate_info flags); +#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD +/** + * ucfg_mc_cp_stats_register_pmo_handler() - API to register pmo handler + * + * Return: none + */ +void ucfg_mc_cp_stats_register_pmo_handler(void); +#else +void static inline ucfg_mc_cp_stats_register_pmo_handler(void) { }; +#endif + #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_ucfg_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c index 409c4d8d087c..c4958d08f44c 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 @@ -30,6 +30,9 @@ #include "../../core/src/wlan_cp_stats_defs.h" #include "../../core/src/wlan_cp_stats_defs.h" #include "../../core/src/wlan_cp_stats_cmn_api_i.h" +#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD +#include +#endif QDF_STATUS wlan_cp_stats_psoc_cs_init(struct psoc_cp_stats *psoc_cs) { @@ -510,6 +513,11 @@ QDF_STATUS ucfg_mc_cp_stats_set_pending_req(struct wlan_objmgr_psoc *psoc, wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv); psoc_mc_stats = psoc_cp_stats_priv->obj_stats; + if (psoc_mc_stats->is_cp_stats_suspended) { + cp_stats_debug("cp stats is suspended try again after resume"); + wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); + return QDF_STATUS_E_AGAIN; + } psoc_mc_stats->pending.type_map |= (1 << type); psoc_mc_stats->pending.req[type] = *req; wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); @@ -622,3 +630,67 @@ QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } + +#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD +static QDF_STATUS +ucfg_mc_cp_stats_suspend_req_handler(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mc_cp_stats *psoc_mc_stats; + struct psoc_cp_stats *psoc_cp_stats_priv; + + psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc); + if (!psoc_cp_stats_priv) { + cp_stats_err("psoc cp stats object is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv); + psoc_mc_stats = psoc_cp_stats_priv->obj_stats; + psoc_mc_stats->is_cp_stats_suspended = true; + wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +ucfg_mc_cp_stats_resume_req_handler(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mc_cp_stats *psoc_mc_stats; + struct psoc_cp_stats *psoc_cp_stats_priv; + + psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc); + if (!psoc_cp_stats_priv) { + cp_stats_err("psoc cp stats object is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv); + psoc_mc_stats = psoc_cp_stats_priv->obj_stats; + psoc_mc_stats->is_cp_stats_suspended = false; + wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +ucfg_mc_cp_stats_resume_handler(struct wlan_objmgr_psoc *psoc, + void *arg) +{ + return ucfg_mc_cp_stats_resume_req_handler(psoc); +} + +static QDF_STATUS +ucfg_mc_cp_stats_suspend_handler(struct wlan_objmgr_psoc *psoc, + void *arg) +{ + return ucfg_mc_cp_stats_suspend_req_handler(psoc); +} + +void ucfg_mc_cp_stats_register_pmo_handler(void) +{ + pmo_register_suspend_handler(WLAN_UMAC_COMP_CP_STATS, + ucfg_mc_cp_stats_suspend_handler, NULL); + pmo_register_resume_handler(WLAN_UMAC_COMP_CP_STATS, + ucfg_mc_cp_stats_resume_handler, NULL); +} +#endif