diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 0c803b444c..c57a1c78d3 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -19572,6 +19572,8 @@ static QDF_STATUS hdd_component_init(void) if (QDF_IS_STATUS_ERROR(status)) goto afc_deinit; + hdd_register_cstats_ops(); + return QDF_STATUS_SUCCESS; afc_deinit: diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 61c7604ff4..4592fc0c04 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -49,6 +49,15 @@ #include "wlan_hdd_eht.h" #include "wlan_dp_ucfg_api.h" #include "wlan_cm_roam_ucfg_api.h" +#include +#include +#ifdef CNSS_GENL +#ifdef CONFIG_CNSS_OUT_OF_TREE +#include "cnss_nl.h" +#else +#include +#endif +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) #define HDD_INFO_SIGNAL STATION_INFO_SIGNAL @@ -11549,3 +11558,73 @@ QDF_STATUS hdd_tx_latency_register_cb(void *soc) hdd_tx_latency_stats_cb); } #endif + +#ifdef WLAN_CHIPSET_STATS +#ifdef CNSS_GENL +static int nl_srv_bcast_cstats(struct sk_buff *skb) +{ + return nl_srv_bcast(skb, CLD80211_MCGRP_HOST_LOGS, ANI_NL_MSG_LOG); +} +#else +static int nl_srv_bcast_cstats(struct sk_buff *skb) +{ + return nl_srv_bcast(skb); +} +#endif + +int hdd_cstats_send_data_to_userspace(char *buff, unsigned int len, + enum cstats_types type) +{ + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + tAniNlHdr *wnl; + static int nlmsg_seq; + int tot_msg_len; + int ret = -1; + + if (type == CSTATS_HOST_TYPE) { + *(unsigned short *)(buff) = ANI_NL_MSG_CSTATS_HOST_LOG_TYPE; + *(unsigned short *)(buff + 2) = len - sizeof(tAniHdr); + } else if (type == CSTATS_FW_TYPE) { + *(unsigned short *)(buff) = ANI_NL_MSG_CSTATS_FW_LOG_TYPE; + *(unsigned short *)(buff + 2) = len - sizeof(tAniHdr); + } + + skb = dev_alloc_skb(MAX_CSTATS_NODE_LENGTH); + if (!skb) { + qdf_err("dev_alloc_skb() failed"); + return -ENOMEM; + } + + tot_msg_len = NLMSG_SPACE(len + sizeof(wnl->radio)); + + nlh = nlmsg_put(skb, 0, nlmsg_seq++, + ANI_NL_MSG_LOG, + len + sizeof(wnl->radio), NLM_F_REQUEST); + if (!nlh) { + qdf_err("nlmsg_put() failed for msg size[%d]", tot_msg_len); + dev_kfree_skb(skb); + return -EINVAL; + } + + wnl = (tAniNlHdr *)nlh; + wnl->radio = 0; + + memcpy(nlmsg_data(nlh) + sizeof(wnl->radio), buff, len); + + ret = nl_srv_bcast_cstats(skb); + if (ret < 0) + qdf_err("Send Failed %d", ret); + + return ret; +} + +struct cstats_tx_rx_ops cstats_ops = { + .cstats_send_data_to_usr = hdd_cstats_send_data_to_userspace, +}; + +void hdd_register_cstats_ops(void) +{ + ucfg_cp_stats_cstats_register_tx_rx_ops(&cstats_ops); +} +#endif diff --git a/core/hdd/src/wlan_hdd_stats.h b/core/hdd/src/wlan_hdd_stats.h index 36fa673a5d..6fecfd0921 100644 --- a/core/hdd/src/wlan_hdd_stats.h +++ b/core/hdd/src/wlan_hdd_stats.h @@ -31,6 +31,7 @@ #ifdef WLAN_FEATURE_11BE_MLO #include "wlan_mlo_mgr_cmn.h" #endif +#include #define INVALID_MCS_IDX 255 @@ -808,4 +809,36 @@ hdd_tx_latency_record_ingress_ts(struct hdd_adapter *adapter, #define FEATURE_TX_LATENCY_STATS_COMMANDS #define FEATURE_TX_LATENCY_STATS_EVENTS #endif + +#ifdef WLAN_CHIPSET_STATS +/** + * hdd_cstats_send_data_to_userspace() - Send chipsset stats to userspace + * + * @buff: Buffer to be sent + * @len: length of the buffer + * @type: Chipset stats type + * + * Return: 0 on success -ve value on error + */ +int hdd_cstats_send_data_to_userspace(char *buff, unsigned int len, + enum cstats_types type); + +/** + * hdd_register_cstats_ops() - Register chipset stats ops + * + * Return: void + */ +void hdd_register_cstats_ops(void); +#else +static inline void hdd_register_cstats_ops(void) +{ +} + +static inline int +hdd_cstats_send_data_to_userspace(char *buff, unsigned int len, + enum cstats_types type) +{ + return 0; +} +#endif #endif /* end #if !defined(WLAN_HDD_STATS_H) */