diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h index acf65caddc88..31cb46ade8e6 100644 --- a/qdf/inc/qdf_types.h +++ b/qdf/inc/qdf_types.h @@ -862,6 +862,10 @@ QDF_STATUS qdf_ipv6_parse(const char *ipv6_str, struct qdf_ipv6_addr *out_addr); #define QDF_MAX_NUM_CHAN (128) +#define QDF_BCAST_MAC_ADDR (0xFF) +#define QDF_MCAST_IPV4_MAC_ADDR (0x01) +#define QDF_MCAST_IPV6_MAC_ADDR (0x33) + /** * struct qdf_tso_frag_t - fragments of a single TCP segment * @paddr_low_32: Lower 32 bits of the buffer pointer diff --git a/umac/cp_stats/core/src/wlan_cp_stats_comp_handler.c b/umac/cp_stats/core/src/wlan_cp_stats_comp_handler.c index 33f26b814b13..8e547b517d4d 100644 --- a/umac/cp_stats/core/src/wlan_cp_stats_comp_handler.c +++ b/umac/cp_stats/core/src/wlan_cp_stats_comp_handler.c @@ -25,6 +25,7 @@ #include "wlan_cp_stats_comp_handler.h" #include "wlan_cp_stats_defs.h" #include +#include static QDF_STATUS wlan_cp_stats_psoc_comp_obj_config diff --git a/umac/cp_stats/core/src/wlan_cp_stats_defs.h b/umac/cp_stats/core/src/wlan_cp_stats_defs.h index a64193a7b8c6..66d8f3250561 100644 --- a/umac/cp_stats/core/src/wlan_cp_stats_defs.h +++ b/umac/cp_stats/core/src/wlan_cp_stats_defs.h @@ -41,11 +41,15 @@ * @psoc_obj: pointer to psoc * @psoc_comp_priv_obj[]: component's private object pointers * @psoc_cp_stats_lock: lock to protect object + * @cmn_stats: stats common for AP and STA devices + * @obj_stats: stats specific to AP or STA devices */ struct psoc_cp_stats { struct wlan_objmgr_psoc *psoc_obj; void *psoc_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS]; qdf_spinlock_t psoc_cp_stats_lock; + struct psoc_cmn_cp_stats *cmn_stats; + void *obj_stats; }; /** @@ -242,14 +246,18 @@ static inline struct psoc_cp_stats *wlan_cp_stats_get_psoc_stats_obj(struct wlan_objmgr_psoc *psoc) { - struct psoc_cp_stats *psoc_cs = NULL; + struct cp_stats_context *csc; - if (psoc) { - psoc_cs = wlan_objmgr_psoc_get_comp_private_obj - (psoc, WLAN_UMAC_COMP_CP_STATS); - } + if (!psoc) + return NULL; - return psoc_cs; + csc = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_CP_STATS); + + if (!csc) + return NULL; + + return csc->psoc_cs; } /** diff --git a/umac/cp_stats/core/src/wlan_cp_stats_obj_mgr_handler.c b/umac/cp_stats/core/src/wlan_cp_stats_obj_mgr_handler.c index f77bb157bfdb..d8dd04170d21 100644 --- a/umac/cp_stats/core/src/wlan_cp_stats_obj_mgr_handler.c +++ b/umac/cp_stats/core/src/wlan_cp_stats_obj_mgr_handler.c @@ -28,7 +28,12 @@ #include "wlan_cp_stats_defs.h" #include "wlan_cp_stats_da_api.h" #include "wlan_cp_stats_ol_api.h" + +#include "wlan_cp_stats_defs.h" +#include "wlan_cp_stats_ic_ucfg_handler.h" + #include +#include "wlan_cp_stats_utils_api.h" QDF_STATUS wlan_cp_stats_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg) @@ -108,6 +113,7 @@ wlan_cp_stats_psoc_obj_create_handler_return: qdf_mem_free(csc); csc = NULL; } + return status; } cp_stats_debug("cp stats context attach at psoc"); @@ -132,6 +138,8 @@ wlan_cp_stats_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg) wlan_objmgr_psoc_component_obj_detach(psoc, WLAN_UMAC_COMP_CP_STATS, csc); + if (csc->cp_stats_psoc_obj_deinit) + csc->cp_stats_psoc_obj_deinit(csc->psoc_cs); qdf_mem_free(csc->psoc_cs); if (csc->cp_stats_ctx_deinit) csc->cp_stats_ctx_deinit(csc); diff --git a/umac/cp_stats/core/src/wlan_cp_stats_ol_api.c b/umac/cp_stats/core/src/wlan_cp_stats_ol_api.c index 22205710ee97..049592e3d15e 100644 --- a/umac/cp_stats/core/src/wlan_cp_stats_ol_api.c +++ b/umac/cp_stats/core/src/wlan_cp_stats_ol_api.c @@ -30,6 +30,9 @@ #include "wlan_cp_stats_cmn_api_i.h" #include +#include "wlan_cp_stats_ic_ucfg_handler.h" +#include + QDF_STATUS wlan_cp_stats_psoc_obj_init_ol(struct psoc_cp_stats *psoc_cs) { qdf_spinlock_create(&psoc_cs->psoc_cp_stats_lock); 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 ec652176655d..049948dfa46f 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 @@ -34,4 +34,61 @@ #ifndef __WLAN_CP_STATS_MC_DEFS_H__ #define __WLAN_CP_STATS_MC_DEFS_H__ + +/** + * struct wake_lock_stats - wake lock stats structure + * @ucast_wake_up_count: Unicast wakeup count + * @bcast_wake_up_count: Broadcast wakeup count + * @ipv4_mcast_wake_up_count: ipv4 multicast wakeup count + * @ipv6_mcast_wake_up_count: ipv6 multicast wakeup count + * @ipv6_mcast_ra_stats: ipv6 multicast ra stats + * @ipv6_mcast_ns_stats: ipv6 multicast ns stats + * @ipv6_mcast_na_stats: ipv6 multicast na stats + * @icmpv4_count: ipv4 icmp packet count + * @icmpv6_count: ipv6 icmp packet count + * @rssi_breach_wake_up_count: rssi breach wakeup count + * @low_rssi_wake_up_count: low rssi wakeup count + * @gscan_wake_up_count: gscan wakeup count + * @pno_complete_wake_up_count: pno complete wakeup count + * @pno_match_wake_up_count: pno match wakeup count + * @oem_response_wake_up_count: oem response wakeup count + * @pwr_save_fail_detected: pwr save fail detected wakeup count + * @scan_11d 11d scan wakeup count + */ +struct wake_lock_stats { + uint32_t ucast_wake_up_count; + uint32_t bcast_wake_up_count; + uint32_t ipv4_mcast_wake_up_count; + uint32_t ipv6_mcast_wake_up_count; + uint32_t ipv6_mcast_ra_stats; + uint32_t ipv6_mcast_ns_stats; + uint32_t ipv6_mcast_na_stats; + uint32_t icmpv4_count; + uint32_t icmpv6_count; + uint32_t rssi_breach_wake_up_count; + uint32_t low_rssi_wake_up_count; + uint32_t gscan_wake_up_count; + uint32_t pno_complete_wake_up_count; + uint32_t pno_match_wake_up_count; + uint32_t oem_response_wake_up_count; + uint32_t pwr_save_fail_detected; + uint32_t scan_11d; +}; + +/** + * struct psoc_mc_cp_stats - psoc specific stats + * @wow_unspecified_wake_up_count: number of non-wow related wake ups + */ +struct psoc_mc_cp_stats { + uint32_t wow_unspecified_wake_up_count; +}; + +/** + * struct vdev_mc_cp_stats - vdev specific stats + * @wow_stats: wake_lock stats for vdev + */ +struct vdev_mc_cp_stats { + struct wake_lock_stats wow_stats; +}; + #endif /* __WLAN_CP_STATS_MC_DEFS_H__ */ diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_tgt_api.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_tgt_api.h index 275d8e275d83..0cf29ec7a7c0 100644 --- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_tgt_api.h +++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_tgt_api.h @@ -26,6 +26,20 @@ #ifdef QCA_SUPPORT_CP_STATS +/** + * tgt_mc_cp_stats_inc_wake_lock_stats() : API to increment wake lock stats + * given the wake reason code + * @psoc: pointer to psoc object + * @reason: wake reason + * @stats: vdev wow stats to update + * @unspecified_wake_count: unspecified wake count to update + * + * Return : status of operation + */ +QDF_STATUS tgt_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc, + uint32_t reason, struct wake_lock_stats *stats, + uint32_t *unspecified_wake_count); + #endif /* QCA_SUPPORT_CP_STATS */ #endif /* __WLAN_CP_STATS_MC_TGT_API_H__ */ 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 f7e05527dee7..950ea778ac5c 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 @@ -27,6 +27,88 @@ #ifdef QCA_SUPPORT_CP_STATS +#include +#include +#include + +struct psoc_cp_stats; +struct vdev_cp_stats; + +/** + * ucfg_mc_cp_stats_get_psoc_wake_lock_stats() : API to get wake lock stats from + * psoc + * @psoc: pointer to psoc object + * @stats: stats object to populate + * + * Return : status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_get_psoc_wake_lock_stats( + struct wlan_objmgr_psoc *psoc, + struct wake_lock_stats *stats); + +/** + * ucfg_mc_cp_stats_get_vdev_wake_lock_stats() : API to get wake lock stats from + * vdev + * @vdev: pointer to vdev object + * @stats: stats object to populate + * + * Return : status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_get_vdev_wake_lock_stats( + struct wlan_objmgr_vdev *vdev, + struct wake_lock_stats *stats); + +/** + * ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol() : API to increment wake + * lock stats given the protocol of the packet that was received. + * @psoc: pointer to psoc object + * @vdev_id: vdev_id for which the packet was received + * @protocol: protocol of the packet that was received + * + * Return : status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum qdf_proto_subtype protocol); + +/** + * ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol() : API to increment wake + * lock stats given destnation of packet that was received. + * @psoc: pointer to psoc object + * @dest_mac: destinamtion mac address of packet that was received + * + * Return : status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *dest_mac); + +/** + * ucfg_mc_cp_stats_inc_wake_lock_stats() : API to increment wake lock stats + * given wake reason. + * @psoc: pointer to psoc object + * @vdev_id: vdev_id on with WOW was received + * @reason: reason of WOW + * + * Return : status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint32_t reason); + +/** + * ucfg_mc_cp_stats_write_wow_stats() - Writes WOW stats to buffer + * @psoc: pointer to psoc object + * @buffer: The char buffer to write to + * @max_len: The maximum number of chars to write + * @ret: number of bytes written + * + * Return - status of operation + */ +QDF_STATUS ucfg_mc_cp_stats_write_wow_stats( + struct wlan_objmgr_psoc *psoc, + char *buffer, uint16_t max_len, int *ret); + #endif /* QCA_SUPPORT_CP_STATS */ #endif /* __WLAN_CP_STATS_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 60df38b1cecd..24ebfc4ec96f 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 @@ -23,3 +23,26 @@ * from southbound interface */ +#include "target_if_cp_stats.h" +#include "wlan_cp_stats_mc_defs.h" +#include "wlan_cp_stats_tgt_api.h" +#include "wlan_cp_stats_mc_tgt_api.h" +#include "../../core/src/wlan_cp_stats_defs.h" +#include + + +QDF_STATUS tgt_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc, + uint32_t reason, + struct wake_lock_stats *stats, + uint32_t *unspecified_wake_count) +{ + struct wlan_lmac_if_cp_stats_tx_ops *tx_ops; + + tx_ops = target_if_cp_stats_get_tx_ops(psoc); + if (!tx_ops) + return QDF_STATUS_E_NULL_VALUE; + + tx_ops->inc_wake_lock_stats(reason, stats, unspecified_wake_count); + + 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 317acf75aa8f..c979592eefd8 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 @@ -17,8 +17,383 @@ */ /** - * DOC: wlan_cp_stats_mc_ucfg_api.h + * DOC: wlan_cp_stats_mc_ucfg_api.c * * This file provide API definitions required for northbound interaction */ +#include +#include +#include +#include +#include "../../core/src/wlan_cp_stats_defs.h" +#include "../../core/src/wlan_cp_stats_cmn_api_i.h" + +QDF_STATUS wlan_cp_stats_psoc_cs_init(struct psoc_cp_stats *psoc_cs) +{ + psoc_cs->obj_stats = qdf_mem_malloc(sizeof(struct psoc_mc_cp_stats)); + if (!psoc_cs->obj_stats) { + cp_stats_err("malloc failed"); + return QDF_STATUS_E_NOMEM; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_psoc_cs_deinit(struct psoc_cp_stats *psoc_cs) +{ + qdf_mem_free(psoc_cs->obj_stats); + psoc_cs->obj_stats = NULL; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_vdev_cs_init(struct vdev_cp_stats *vdev_cs) +{ + vdev_cs->vdev_stats = qdf_mem_malloc(sizeof(struct vdev_mc_cp_stats)); + if (!vdev_cs->vdev_stats) { + cp_stats_err("malloc failed"); + return QDF_STATUS_E_NOMEM; + } + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_vdev_cs_deinit(struct vdev_cp_stats *vdev_cs) +{ + qdf_mem_free(vdev_cs->vdev_stats); + vdev_cs->vdev_stats = NULL; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_pdev_cs_init(struct pdev_cp_stats *pdev_cs) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_pdev_cs_deinit(struct pdev_cp_stats *pdev_cs) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_peer_cs_init(struct peer_cp_stats *peer_cs) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cp_stats_peer_cs_deinit(struct peer_cp_stats *peer_cs) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum qdf_proto_subtype protocol) +{ + struct wlan_objmgr_vdev *vdev; + struct wake_lock_stats *stats; + struct vdev_mc_cp_stats *vdev_mc_stats; + struct vdev_cp_stats *vdev_cp_stats_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_CP_STATS_ID); + if (!vdev) { + cp_stats_err("vdev numm for vdev_id: %d", vdev_id); + return QDF_STATUS_E_NULL_VALUE; + } + + 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"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + 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; + stats = &vdev_mc_stats->wow_stats; + switch (protocol) { + case QDF_PROTO_ICMP_RES: + stats->icmpv4_count++; + break; + case QDF_PROTO_ICMPV6_REQ: + case QDF_PROTO_ICMPV6_RES: + case QDF_PROTO_ICMPV6_RS: + stats->icmpv6_count++; + break; + case QDF_PROTO_ICMPV6_RA: + stats->icmpv6_count++; + stats->ipv6_mcast_ra_stats++; + break; + case QDF_PROTO_ICMPV6_NS: + stats->icmpv6_count++; + stats->ipv6_mcast_ns_stats++; + break; + case QDF_PROTO_ICMPV6_NA: + stats->icmpv6_count++; + stats->ipv6_mcast_na_stats++; + break; + default: + break; + } + + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *dest_mac) +{ + struct wlan_objmgr_vdev *vdev; + struct wake_lock_stats *stats; + struct vdev_mc_cp_stats *vdev_mc_stats; + struct vdev_cp_stats *vdev_cp_stats_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_CP_STATS_ID); + if (!vdev) { + cp_stats_err("vdev numm for vdev_id: %d", vdev_id); + return QDF_STATUS_E_NULL_VALUE; + } + + 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"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + 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; + stats = &vdev_mc_stats->wow_stats; + switch (*dest_mac) { + case QDF_BCAST_MAC_ADDR: + stats->bcast_wake_up_count++; + break; + case QDF_MCAST_IPV4_MAC_ADDR: + stats->ipv4_mcast_wake_up_count++; + break; + case QDF_MCAST_IPV6_MAC_ADDR: + stats->ipv6_mcast_wake_up_count++; + break; + default: + stats->ucast_wake_up_count++; + break; + } + + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint32_t reason) +{ + struct wake_lock_stats *stats; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_vdev *vdev = NULL; + struct psoc_mc_cp_stats *psoc_mc_stats; + struct psoc_cp_stats *psoc_cp_stats_priv; + struct vdev_mc_cp_stats *vdev_mc_stats; + struct vdev_cp_stats *vdev_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; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_CP_STATS_ID); + if (!vdev) { + cp_stats_err("vdev numm for vdev_id: %d", vdev_id); + return QDF_STATUS_E_NULL_VALUE; + } + + 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"); + status = QDF_STATUS_E_NULL_VALUE; + goto release_vdev_ref; + } + + wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv); + wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv); + + psoc_mc_stats = psoc_cp_stats_priv->obj_stats; + vdev_mc_stats = vdev_cp_stats_priv->vdev_stats; + stats = &vdev_mc_stats->wow_stats; + status = tgt_mc_cp_stats_inc_wake_lock_stats(psoc, reason, stats, + &psoc_mc_stats->wow_unspecified_wake_up_count); + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); + wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); + +release_vdev_ref: + if (vdev) + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + + return status; +} + +/** + * vdev_iterator() - iterator function to collect wake_lock_stats from all vdev + * @psoc: pointer to psoc object + * @vdev: pointer to vdev object + * @arg: stats object pointer passed as arg + * + * Return - none + */ +static void vdev_iterator(struct wlan_objmgr_psoc *psoc, void *vdev, void *arg) +{ + struct wake_lock_stats *vdev_stats; + struct wake_lock_stats *stats = arg; + struct vdev_mc_cp_stats *vdev_mc_stats; + struct vdev_cp_stats *vdev_cp_stats_priv; + + vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev); + if (NULL == vdev_cp_stats_priv) { + cp_stats_err("vdev cp stats object is null"); + return; + } + + wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv); + vdev_mc_stats = vdev_cp_stats_priv->vdev_stats; + vdev_stats = &vdev_mc_stats->wow_stats; + stats->ucast_wake_up_count += vdev_stats->ucast_wake_up_count; + stats->bcast_wake_up_count += vdev_stats->bcast_wake_up_count; + stats->ipv4_mcast_wake_up_count += vdev_stats->ipv4_mcast_wake_up_count; + stats->ipv6_mcast_wake_up_count += vdev_stats->ipv6_mcast_wake_up_count; + stats->ipv6_mcast_ra_stats += vdev_stats->ipv6_mcast_ra_stats; + stats->ipv6_mcast_ns_stats += vdev_stats->ipv6_mcast_ns_stats; + stats->ipv6_mcast_na_stats += vdev_stats->ipv6_mcast_na_stats; + stats->icmpv4_count += vdev_stats->icmpv4_count; + stats->icmpv6_count += vdev_stats->icmpv6_count; + stats->rssi_breach_wake_up_count += + vdev_stats->rssi_breach_wake_up_count; + stats->low_rssi_wake_up_count += vdev_stats->low_rssi_wake_up_count; + stats->gscan_wake_up_count += vdev_stats->gscan_wake_up_count; + stats->pno_complete_wake_up_count += + vdev_stats->pno_complete_wake_up_count; + stats->pno_match_wake_up_count += vdev_stats->pno_match_wake_up_count; + stats->oem_response_wake_up_count += + vdev_stats->oem_response_wake_up_count; + stats->pwr_save_fail_detected += vdev_stats->pwr_save_fail_detected; + stats->scan_11d += vdev_stats->scan_11d; + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); +} + +QDF_STATUS ucfg_mc_cp_stats_get_psoc_wake_lock_stats( + struct wlan_objmgr_psoc *psoc, + struct wake_lock_stats *stats) +{ + struct psoc_cp_stats *psoc_cp_stats_priv; + struct psoc_mc_cp_stats *psoc_mc_stats; + + psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc); + if (NULL == 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; + /* iterate through all vdevs, and get wow stats from vdev_cs object */ + wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, vdev_iterator, + stats, true, WLAN_CP_STATS_ID); + wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_mc_cp_stats_get_vdev_wake_lock_stats( + struct wlan_objmgr_vdev *vdev, + struct wake_lock_stats *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 (NULL == 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; + qdf_mem_copy(stats, &vdev_mc_stats->wow_stats, sizeof(*stats)); + wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_mc_cp_stats_write_wow_stats( + struct wlan_objmgr_psoc *psoc, + char *buffer, uint16_t max_len, int *ret) +{ + QDF_STATUS status; + uint32_t unspecified_wake_count; + struct wake_lock_stats wow_stats = {0}; + 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; + } + + /* get stats from psoc */ + status = ucfg_mc_cp_stats_get_psoc_wake_lock_stats(psoc, &wow_stats); + if (QDF_IS_STATUS_ERROR(status)) { + cp_stats_err("Failed to get WoW stats"); + return status; + } + + wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv); + psoc_mc_stats = psoc_cp_stats_priv->obj_stats; + unspecified_wake_count = psoc_mc_stats->wow_unspecified_wake_up_count; + wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv); + + *ret = qdf_scnprintf(buffer, max_len, + "WoW Wake Reasons\n" + "\tunspecified wake count: %u\n" + "\tunicast: %u\n" + "\tbroadcast: %u\n" + "\tIPv4 multicast: %u\n" + "\tIPv6 multicast: %u\n" + "\tIPv6 multicast RA: %u\n" + "\tIPv6 multicast NS: %u\n" + "\tIPv6 multicast NA: %u\n" + "\tICMPv4: %u\n" + "\tICMPv6: %u\n" + "\tRSSI Breach: %u\n" + "\tLow RSSI: %u\n" + "\tG-Scan: %u\n" + "\tPNO Complete: %u\n" + "\tPNO Match: %u\n" + "\tOEM rsp wake_count: %u\n" + "\twake count due to pwr_save_fail_detected: %u\n" + "\twake count due to 11d scan: %u\n", + unspecified_wake_count, + wow_stats.ucast_wake_up_count, + wow_stats.bcast_wake_up_count, + wow_stats.ipv4_mcast_wake_up_count, + wow_stats.ipv6_mcast_wake_up_count, + wow_stats.ipv6_mcast_ra_stats, + wow_stats.ipv6_mcast_ns_stats, + wow_stats.ipv6_mcast_na_stats, + wow_stats.icmpv4_count, + wow_stats.icmpv6_count, + wow_stats.rssi_breach_wake_up_count, + wow_stats.low_rssi_wake_up_count, + wow_stats.gscan_wake_up_count, + wow_stats.pno_complete_wake_up_count, + wow_stats.pno_match_wake_up_count, + wow_stats.oem_response_wake_up_count, + wow_stats.pwr_save_fail_detected, + wow_stats.scan_11d); + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 0bbe001f3fc4..ac564fc21f31 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -73,7 +73,8 @@ struct scheduler_msg; #ifdef QCA_SUPPORT_CP_STATS #include -#endif +#include +#endif /* QCA_SUPPORT_CP_STATS */ #ifdef QCA_SUPPORT_CP_STATS /** @@ -85,6 +86,11 @@ struct scheduler_msg; struct wlan_lmac_if_cp_stats_tx_ops { QDF_STATUS (*cp_stats_attach)(struct wlan_objmgr_psoc *psoc); QDF_STATUS (*cp_stats_detach)(struct wlan_objmgr_psoc *posc); +#ifdef CONFIG_MCL + void (*inc_wake_lock_stats)(uint32_t reason, + struct wake_lock_stats *stats, + uint32_t *unspecified_wake_count); +#endif }; /**