Browse Source

cnss2: Add support to configure log level

Add support to configure log level for dmesg and
ipc logging. Default log level is set to DEBUG
for ipc logging and INFO for dmesg logging.
Change default behavior of cnss_pr_dbg and
cnss_pr_vdbg API to not print in dmesg.

Change-Id: I6bb9d0bd297be20e66f563c16bb2f3f9d39d2be6
CRs-Fixed: 3499975
Nirav Shah 1 year ago
parent
commit
1e15d131ea
2 changed files with 131 additions and 15 deletions
  1. 103 8
      cnss2/debug.c
  2. 28 7
      cnss2/debug.h

+ 103 - 8
cnss2/debug.c

@@ -13,10 +13,33 @@
 
 #define MMIO_REG_ACCESS_MEM_TYPE		0xFF
 #define MMIO_REG_RAW_ACCESS_MEM_TYPE		0xFE
+#define DEFAULT_KERNEL_LOG_LEVEL		INFO_LOG
+#define DEFAULT_IPC_LOG_LEVEL			DEBUG_LOG
+
+enum log_level cnss_kernel_log_level = DEFAULT_KERNEL_LOG_LEVEL;
 
 #if IS_ENABLED(CONFIG_IPC_LOGGING)
 void *cnss_ipc_log_context;
 void *cnss_ipc_log_long_context;
+enum log_level cnss_ipc_log_level = DEFAULT_IPC_LOG_LEVEL;
+
+static int cnss_set_ipc_log_level(u32 val)
+{
+	if (val < MAX_LOG) {
+		cnss_ipc_log_level = val;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static u32 cnss_get_ipc_log_level(void)
+{
+	return cnss_ipc_log_level;
+}
+#else
+static int cnss_set_ipc_log_level(int val) { return -EINVAL; }
+static u32 cnss_get_ipc_log_level(void) { return MAX_LOG; }
 #endif
 
 static int cnss_pin_connect_show(struct seq_file *s, void *data)
@@ -757,7 +780,12 @@ static ssize_t cnss_control_params_debug_write(struct file *fp,
 		plat_priv->ctrl_params.bdf_type = val;
 	else if (strcmp(cmd, "time_sync_period") == 0)
 		plat_priv->ctrl_params.time_sync_period = val;
-	else
+	else if (strcmp(cmd, "kern_log_level") == 0) {
+		if (val < MAX_LOG)
+			cnss_kernel_log_level = val;
+	} else if (strcmp(cmd, "ipc_log_level") == 0) {
+		return cnss_set_ipc_log_level(val) ? -EINVAL : count;
+	} else
 		return -EINVAL;
 
 	return count;
@@ -832,6 +860,7 @@ static int cnss_show_quirks_state(struct seq_file *s,
 static int cnss_control_params_debug_show(struct seq_file *s, void *data)
 {
 	struct cnss_plat_data *cnss_priv = s->private;
+	u32 ipc_log_level;
 
 	seq_puts(s, "\nUsage: echo <params_name> <value> > <debugfs_path>/cnss/control_params\n");
 	seq_puts(s, "<params_name> can be one of below:\n");
@@ -850,6 +879,11 @@ static int cnss_control_params_debug_show(struct seq_file *s, void *data)
 	seq_printf(s, "bdf_type: %u\n", cnss_priv->ctrl_params.bdf_type);
 	seq_printf(s, "time_sync_period: %u\n",
 		   cnss_priv->ctrl_params.time_sync_period);
+	seq_printf(s, "kern_log_level: %u\n", cnss_kernel_log_level);
+
+	ipc_log_level = cnss_get_ipc_log_level();
+	if (ipc_log_level != MAX_LOG)
+		seq_printf(s, "ipc_log_level: %u\n", ipc_log_level);
 
 	return 0;
 }
@@ -1027,7 +1061,8 @@ void cnss_debugfs_destroy(struct cnss_plat_data *plat_priv)
 
 #if IS_ENABLED(CONFIG_IPC_LOGGING)
 void cnss_debug_ipc_log_print(void *log_ctx, char *process, const char *fn,
-			      const char *log_level, char *fmt, ...)
+			      enum log_level kern_log_level,
+			      enum log_level ipc_log_level, char *fmt, ...)
 {
 	struct va_format vaf;
 	va_list va_args;
@@ -1036,10 +1071,40 @@ void cnss_debug_ipc_log_print(void *log_ctx, char *process, const char *fn,
 	vaf.fmt = fmt;
 	vaf.va = &va_args;
 
-	if (log_level)
-		printk("%scnss: %pV", log_level, &vaf);
+	if (kern_log_level <= cnss_kernel_log_level) {
+		switch (kern_log_level) {
+		case EMERG_LOG:
+			pr_emerg("cnss: %pV", &vaf);
+			break;
+		case ALERT_LOG:
+			pr_alert("cnss: %pV", &vaf);
+			break;
+		case CRIT_LOG:
+			pr_crit("cnss: %pV", &vaf);
+			break;
+		case ERR_LOG:
+			pr_err("cnss: %pV", &vaf);
+			break;
+		case WARNING_LOG:
+			pr_warn("cnss: %pV", &vaf);
+			break;
+		case NOTICE_LOG:
+			pr_notice("cnss: %pV", &vaf);
+			break;
+		case INFO_LOG:
+			pr_info("cnss: %pV", &vaf);
+			break;
+		case DEBUG_LOG:
+		case DEBUG_HI_LOG:
+			pr_debug("cnss: %pV", &vaf);
+			break;
+		default:
+			break;
+		}
+	}
 
-	ipc_log_string(log_ctx, "[%s] %s: %pV", process, fn, &vaf);
+	if (ipc_log_level <= cnss_ipc_log_level)
+		ipc_log_string(log_ctx, "[%s] %s: %pV", process, fn, &vaf);
 
 	va_end(va_args);
 }
@@ -1080,7 +1145,8 @@ static void cnss_ipc_logging_deinit(void)
 static int cnss_ipc_logging_init(void) { return 0; }
 static void cnss_ipc_logging_deinit(void) {}
 void cnss_debug_ipc_log_print(void *log_ctx, char *process, const char *fn,
-			      const char *log_level, char *fmt, ...)
+			      enum log_level kern_log_level,
+			      enum log_level ipc_log_level, char *fmt, ...)
 {
 	struct va_format vaf;
 	va_list va_args;
@@ -1089,8 +1155,37 @@ void cnss_debug_ipc_log_print(void *log_ctx, char *process, const char *fn,
 	vaf.fmt = fmt;
 	vaf.va = &va_args;
 
-	if (log_level)
-		printk("%scnss: %pV", log_level, &vaf);
+	if (kern_log_level <= cnss_kernel_log_level) {
+		switch (kern_log_level) {
+		case EMERG_LOG:
+			pr_emerg("cnss: %pV", &vaf);
+			break;
+		case ALERT_LOG:
+			pr_alert("cnss: %pV", &vaf);
+			break;
+		case CRIT_LOG:
+			pr_crit("cnss: %pV", &vaf);
+			break;
+		case ERR_LOG:
+			pr_err("cnss: %pV", &vaf);
+			break;
+		case WARNING_LOG:
+			pr_warn("cnss: %pV", &vaf);
+			break;
+		case NOTICE_LOG:
+			pr_notice("cnss: %pV", &vaf);
+			break;
+		case INFO_LOG:
+			pr_info("cnss: %pV", &vaf);
+			break;
+		case DEBUG_LOG:
+		case DEBUG_HI_LOG:
+			pr_debug("cnss: %pV", &vaf);
+			break;
+		default:
+			break;
+		}
+	}
 
 	va_end(va_args);
 }

+ 28 - 7
cnss2/debug.h

@@ -1,17 +1,34 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */
+/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */
 
 #ifndef _CNSS_DEBUG_H
 #define _CNSS_DEBUG_H
 
 #include <linux/printk.h>
 
+enum log_level {
+	EMERG_LOG = 0,
+	ALERT_LOG = 1,
+	CRIT_LOG = 2,
+	ERR_LOG = 3,
+	WARNING_LOG = 4,
+	NOTICE_LOG = 5,
+	INFO_LOG = 6,
+	DEBUG_LOG = 7,
+	DEBUG_HI_LOG = 8,
+	MAX_LOG = 9,
+};
+
+extern enum log_level cnss_kernel_log_level;
+
 #if IS_ENABLED(CONFIG_IPC_LOGGING)
 #include <linux/ipc_logging.h>
 #include <asm/current.h>
 
 extern void *cnss_ipc_log_context;
 extern void *cnss_ipc_log_long_context;
+extern enum log_level cnss_ipc_log_level;
 
 #ifdef CONFIG_CNSS2_DEBUG
 #define CNSS_IPC_LOG_PAGES              100
@@ -35,27 +52,30 @@ extern void *cnss_ipc_log_long_context;
 
 #define cnss_pr_err(_fmt, ...) \
 	cnss_debug_log_print(proc_name, __func__, \
-			     KERN_ERR, _fmt, ##__VA_ARGS__)
+			     ERR_LOG, ERR_LOG, _fmt, ##__VA_ARGS__)
 
 #define cnss_pr_warn(_fmt, ...) \
 	cnss_debug_log_print(proc_name, __func__, \
-			     KERN_WARNING, _fmt, ##__VA_ARGS__)
+			     WARNING_LOG, WARNING_LOG, _fmt, ##__VA_ARGS__)
 
 #define cnss_pr_info(_fmt, ...) \
 	cnss_debug_log_print(proc_name, __func__, \
-			     KERN_INFO, _fmt, ##__VA_ARGS__)
+			     INFO_LOG, INFO_LOG, _fmt, ##__VA_ARGS__)
 
 #define cnss_pr_dbg(_fmt, ...) \
 	cnss_debug_log_print(proc_name, __func__, \
-			     KERN_DEBUG, _fmt, ##__VA_ARGS__)
+			     DEBUG_LOG, DEBUG_LOG, _fmt, ##__VA_ARGS__)
 
 #define cnss_pr_vdbg(_fmt, ...) \
 	cnss_debug_log_long_print(proc_name, __func__, \
-				  KERN_DEBUG, _fmt, ##__VA_ARGS__)
+				  DEBUG_LOG, DEBUG_LOG, _fmt, ##__VA_ARGS__)
 
 #define cnss_pr_buf(_fmt, ...) \
 	cnss_debug_log_long_print(proc_name, __func__, \
-				  NULL, _fmt, ##__VA_ARGS__)
+				  DEBUG_HI_LOG, DEBUG_LOG, _fmt, ##__VA_ARGS__)
+#define cnss_pr_dbg_buf(_fmt, ...) \
+	cnss_debug_log_long_print(proc_name, __func__, \
+				  DEBUG_HI_LOG, DEBUG_HI_LOG, _fmt, ##__VA_ARGS__)
 
 #ifdef CONFIG_CNSS2_DEBUG
 #define CNSS_ASSERT(_condition) do {					\
@@ -83,5 +103,6 @@ void cnss_debug_deinit(void);
 int cnss_debugfs_create(struct cnss_plat_data *plat_priv);
 void cnss_debugfs_destroy(struct cnss_plat_data *plat_priv);
 void cnss_debug_ipc_log_print(void *log_ctx, char *process, const char *fn,
-			      const char *log_level, char *fmt, ...);
+			      enum log_level kern_log_level,
+			      enum log_level ipc_log_level, char *fmt, ...);
 #endif /* _CNSS_DEBUG_H */