Browse Source

qcacld-3.0: create a sysfs to display stats on console

Add a sysfs to display DP stats on console. Sysfs file
displays requested stats on console and wlan logs.

Change-Id: Ifd56d1bf6f578a4ce3f1d963040e6d3cd138c64a
CRs-Fixed: 3035860
sandhu 3 years ago
parent
commit
cff5dc24a9

+ 4 - 1
Kbuild

@@ -413,6 +413,9 @@ ifeq ($(CONFIG_WLAN_DUMP_IN_PROGRESS), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dump_in_progress.o
 endif
 endif
+ifeq ($(CONFIG_WLAN_SYSFS_DP_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_txrx_stats_console.o
+endif
 
 ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_fw_state.o
@@ -3095,7 +3098,7 @@ cppflags-$(CONFIG_WLAN_SYSFS_STA_INFO) += -DWLAN_SYSFS_STA_INFO
 cppflags-$(CONFIG_WLAN_DL_MODES) += -DCONFIG_WLAN_DL_MODES
 cppflags-$(CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT) += -DFEATURE_WPSS_THERMAL_MITIGATION
 cppflags-$(CONFIG_WLAN_DUMP_IN_PROGRESS) += -DCONFIG_WLAN_DUMP_IN_PROGRESS
-
+cppflags-$(CONFIG_WLAN_SYSFS_DP_STATS) += -DWLAN_SYSFS_DP_STATS
 
 cppflags-$(CONFIG_WIFI_MONITOR_SUPPORT) += -DWIFI_MONITOR_SUPPORT
 cppflags-$(CONFIG_QCA_MONITOR_PKT_SUPPORT) += -DQCA_MONITOR_PKT_SUPPORT

+ 1 - 0
configs/default_defconfig

@@ -107,6 +107,7 @@ ifeq ($(CONFIG_CNSS_WCN7850), y)
 	CONFIG_DP_HW_COOKIE_CONVERT_EXCEPTION := y
 	CONFIG_WLAN_FEATURE_NEAR_FULL_IRQ := y
 	CONFIG_WLAN_FEATURE_REDUCE_RX_THREADS := y
+	CONFIG_WLAN_SYSFS_DP_STATS := y
 endif
 
 ifeq (y,$(findstring y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM)))

+ 3 - 0
core/hdd/src/wlan_hdd_sysfs.c

@@ -77,6 +77,7 @@
 #include <wlan_hdd_sysfs_dl_modes.h>
 #include <wlan_hdd_sysfs_swlm.h>
 #include <wlan_hdd_sysfs_dump_in_progress.h>
+#include <wlan_hdd_sysfs_txrx_stats_console.h>
 #include "wma_api.h"
 #include "wlan_hdd_eht.h"
 
@@ -849,12 +850,14 @@ void hdd_create_sysfs_files(struct hdd_context *hdd_ctx)
 		hdd_sysfs_dp_aggregation_create(driver_kobject);
 		hdd_sysfs_dp_swlm_create(driver_kobject);
 		hdd_sysfs_create_wakeup_logs_to_console();
+		hdd_sysfs_dp_txrx_stats_sysfs_create(driver_kobject);
 	}
 }
 
 void hdd_destroy_sysfs_files(void)
 {
 	if  (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) {
+		hdd_sysfs_dp_txrx_stats_sysfs_destroy(driver_kobject);
 		hdd_sysfs_destroy_wakeup_logs_to_console();
 		hdd_sysfs_dp_swlm_destroy(driver_kobject);
 		hdd_sysfs_dp_aggregation_destroy(driver_kobject);

+ 240 - 0
core/hdd/src/wlan_hdd_sysfs_txrx_stats_console.c

@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2021, 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 above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_sysfs_txrx_stats_console.c
+ *
+ * implementation for creating sysfs files:
+ *
+ * txrx_stats
+ */
+
+#include <wlan_hdd_includes.h>
+#include "osif_psoc_sync.h"
+#include <wlan_hdd_sysfs.h>
+#include <wlan_hdd_sysfs_txrx_stats_console.h>
+#include <cds_api.h>
+#include <qdf_status.h>
+
+#ifdef WLAN_SYSFS_DP_STATS
+
+#define HDD_WLAN_SYSFS_TXRX_STATS_USER_CMD_SIZE (10)
+#define SYSFS_INPUT_BUF_SIZE			PAGE_SIZE
+
+/*
+ * __hdd_wlan_txrx_stats_store() - Calls into dp layer to
+ * update the sysfs config values.
+ * @hdd_ctx: hdd context
+ * @buf: input buffer from user space
+ * @count: input buffer size
+ *
+ * Return: Return the size of input buffer.
+ */
+static ssize_t
+__hdd_wlan_txrx_stats_store(struct hdd_context *hdd_ctx,
+			    const char  *buf, size_t count)
+{
+	char buf_local[HDD_WLAN_SYSFS_TXRX_STATS_USER_CMD_SIZE + 1];
+	char *sptr, *token;
+	uint32_t stat_type_requested;
+	uint32_t mac_id;
+	int ret;
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!soc) {
+		hdd_err_rl("soc is NULL");
+		return -EINVAL;
+	}
+
+	if (count > HDD_WLAN_SYSFS_TXRX_STATS_USER_CMD_SIZE)
+		return -EINVAL;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+
+	if (ret)
+		return -EINVAL;
+
+	sptr = buf_local;
+	/* get mac id */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &stat_type_requested))
+		return -EINVAL;
+
+	/* get stat type requested */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &mac_id))
+		return -EINVAL;
+
+	if (!soc->ops->cmn_drv_ops->txrx_sysfs_set_stat_type) {
+		hdd_err("txrx_sysfs_set_stat_type is NULL");
+		return -EINVAL;
+	}
+
+	soc->ops->cmn_drv_ops->txrx_sysfs_set_stat_type(soc,
+							stat_type_requested,
+							mac_id);
+
+	return count;
+}
+
+/*
+ * __hdd_wlan_txrx_stats_show() - Calls into dp to fill stats.
+ * @buf: output buffer
+ *
+ * Return: output buffer size.
+ */
+static ssize_t
+__hdd_wlan_txrx_stats_show(char *buf)
+{
+	uint32_t size_of_output = 0;
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!soc) {
+		hdd_err_rl("hdd dp_soc cds_get_context returned NULL");
+		return -EINVAL;
+	}
+
+	if (!soc->ops->cmn_drv_ops->txrx_sysfs_fill_stats) {
+		hdd_err_rl("txrx_sysfs_fill_stats is NULL");
+		return -EINVAL;
+	}
+	soc->ops->cmn_drv_ops->txrx_sysfs_fill_stats(soc,
+						     buf,
+						     SYSFS_INPUT_BUF_SIZE);
+	size_of_output = strlen(buf);
+	return size_of_output;
+}
+
+/*
+ * hdd_sysfs_dp_txrx_stats_show() - Registered as sysfs show function.
+ * @kobj: kernel object
+ * @att: kobject attribute
+ * @buf: output buffer to be filled
+ *
+ * Return: Returns the length of the output buffer.
+ */
+static ssize_t
+hdd_sysfs_dp_txrx_stats_show(struct kobject *kobj,
+			     struct kobj_attribute *attr,
+			     char *buf)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct osif_psoc_sync *psoc_sync = NULL;
+	ssize_t length = 0;
+	ssize_t errno = 0;
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	errno = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
+	if (errno)
+		return errno;
+
+	length = __hdd_wlan_txrx_stats_show(buf);
+
+	osif_psoc_sync_op_stop(psoc_sync);
+
+	return length;
+}
+
+/*
+ * hdd_sysfs_dp_txrx_stats_store() - Registered as sysfs write function.
+ * @kobj: kernel object
+ * @att: kobject attribute
+ * @buf: input buffer from user space
+ * @count:  size of the input buffer
+ *
+ * Return: Returns the length of the input buffer.
+ */
+static ssize_t
+hdd_sysfs_dp_txrx_stats_store(struct kobject *kobj,
+			      struct kobj_attribute *attr,
+			      const char *buf,
+			      size_t count)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct osif_psoc_sync *psoc_sync = NULL;
+	ssize_t errno = 0;
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	errno = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
+	if (errno)
+		return errno;
+
+	errno = __hdd_wlan_txrx_stats_store(hdd_ctx, buf, count);
+
+	osif_psoc_sync_op_stop(psoc_sync);
+
+	return errno;
+}
+
+static struct kobj_attribute dp_txrx_stats_attribute =
+	__ATTR(txrx_stats, 0664,  hdd_sysfs_dp_txrx_stats_show,
+	       hdd_sysfs_dp_txrx_stats_store);
+
+/*
+ * hdd_sysfs_dp_txrx_stats_sysfs_create() - Initialize sysfs file.
+ * @driver_kobject: driver kobject
+ *
+ * Return: return sysfs int val.
+ */
+int hdd_sysfs_dp_txrx_stats_sysfs_create(struct kobject *driver_kobject)
+{
+	int error = 0;
+
+	if (!driver_kobject) {
+		hdd_err("could not get driver kobject");
+		return -EINVAL;
+	}
+
+	error = sysfs_create_file(driver_kobject,
+				  &dp_txrx_stats_attribute.attr);
+
+	if (error)
+		hdd_err("failed to create txrx_stats sysfs file");
+
+	return error;
+}
+
+/*
+ * hdd_sysfs_dp_txrx_stats_sysfs_destroy() - Sysfs deinitialize.
+ * @driver_kobject: driver kobject
+ *
+ * Return: void
+ */
+void
+hdd_sysfs_dp_txrx_stats_sysfs_destroy(struct kobject *driver_kobject)
+{
+	if (!driver_kobject) {
+		hdd_err("failed to get driver kobject");
+		return;
+	}
+
+	sysfs_remove_file(driver_kobject, &dp_txrx_stats_attribute.attr);
+}
+#endif /* WLAN_SYSFS_DP_STATS */

+ 70 - 0
core/hdd/src/wlan_hdd_sysfs_txrx_stats_console.h

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2021, 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 above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_sysfs_txrx_stats
+ *
+ * implementation for creating sysfs files:
+ *
+ * txrx_stats
+ */
+
+int
+hdd_sysfs_dp_txrx_stats_sysfs_create(struct kobject *drv_kobj);
+
+void
+hdd_sysfs_dp_txrx_stats_sysfs_destroy(struct kobject *drv_kobj);
+
+#ifdef WLAN_SYSFS_DP_STATS
+
+/**
+ * hdd_sysfs_dp_txrx_stats_sysfs_create() - API to create txrx stats related
+ * sysfs entry.
+ * @drv_kobj: sysfs driver kobject
+ *
+ * file path: /sys/kernel/wifi/txrx_stats
+ *
+ * Return: 0 on success and errno on failure
+ */
+
+int
+hdd_sysfs_dp_txrx_stats_sysfs_create(struct kobject *drv_kobj);
+
+/**
+ * hdd_sysfs_dp_txrx_stats_sysfs_destroy() - API to destroy txrx stats
+ * related sysfs entry.
+ * @drv_kobj: sysfs driver kobject
+ *
+ * Return: None
+ */
+
+void
+hdd_sysfs_dp_txrx_stats_sysfs_destroy(struct kobject *drv_kobj);
+
+#else /* WLAN_SYSFS_DP_STATS */
+
+int
+hdd_sysfs_dp_txrx_stats_sysfs_create(struct kobject *drv_kobj)
+{
+	return 0;
+}
+
+void
+hdd_sysfs_dp_txrx_stats_sysfs_destroy(struct kobject *drv_kobj)
+{
+}
+
+#endif /* WLAN_SYSFS_DP_STATS */