Browse Source

qcacmn: Parse and update qdf module params

Read the file wifi_module_param.ini, in which wifi module params
are present and compare these module params with qdf module params
in qdf module init function.

If any of the module params belongs to qdf module is present,
then that particular module param is updted during qdf module init.

Change-Id: I76ef876f6c7be3cdffd93b6050a190438d60bf39
Adwait Nayak 4 years ago
parent
commit
c2c89243d8

+ 43 - 1
qdf/inc/qdf_file.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-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
@@ -50,5 +50,47 @@ QDF_STATUS qdf_file_read(const char *path, char **out_buf);
  */
 void qdf_file_buf_free(char *file_buf);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * qdf_module_param_file_read() - read the entire contents of a file
+ * @path: the full path of the file to read
+ * @out_buf: double pointer for referring to the file contents buffer
+ *
+ * This API allocates a new buffer before qdf_mem_init() is being called.
+ * Thus, this API helps to allocate memory which is being used before qdf
+ * memory tracking framework is available. Buffer is null-terminated,
+ * containing the contents of the file at @path. On success, @out_buf
+ * points to this new buffer, otherwise @out_buf is set to NULL.
+ *
+ * Consumers must free the allocated buffer by calling
+ * qdf_module_param_file_free().
+ *
+ * Return: QDF_STATUS
+ */
+
+QDF_STATUS qdf_module_param_file_read(const char *path, char **out_buf);
+
+/**
+ * qdf_module_param_file_free() - free a previously allocated file buffer
+ * @file_buf: pointer to the file buffer to free. The buffer allocated in
+ * qdf_module_param_file_read is not tracked by qdf framework.
+ *
+ * This API is used in conjunction with qdf_module_param_file_read().
+ *
+ * Return: None
+ */
+void qdf_module_param_file_free(char *file_buf);
+#else
+static inline
+QDF_STATUS qdf_module_param_file_read(const char *path, char **out_buf)
+{
+	return QDF_STATUS_E_INVAL;
+}
+
+static inline
+void qdf_module_param_file_free(char *file_buf)
+{
+}
+#endif
 #endif /* __QDF_FILE_H */
 

+ 47 - 1
qdf/inc/qdf_mem.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-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
@@ -94,6 +94,14 @@ void qdf_mem_init(void);
  */
 void qdf_mem_exit(void);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+#define qdf_untracked_mem_malloc(size) \
+	__qdf_untracked_mem_malloc(size, __func__, __LINE__)
+
+#define qdf_untracked_mem_free(ptr) \
+	__qdf_untracked_mem_free(ptr)
+#endif
+
 #define QDF_MEM_FUNC_NAME_SIZE 48
 
 #ifdef MEMORY_DEBUG
@@ -104,6 +112,18 @@ void qdf_mem_exit(void);
  */
 bool qdf_mem_debug_config_get(void);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * qdf_mem_debug_disabled_set() - Set mem_debug_disabled
+ * @str_value: value of the module param
+ *
+ * This function will set qdf module param mem_debug_disabled
+ *
+ * Return: QDF_STATUS_SUCCESS on Success
+ */
+QDF_STATUS qdf_mem_debug_disabled_config_set(const char *str_value);
+#endif
+
 /**
  * qdf_mem_malloc_debug() - debug version of QDF memory allocation API
  * @size: Number of bytes of memory to allocate.
@@ -245,6 +265,12 @@ static inline bool qdf_mem_debug_config_get(void)
 	return false;
 }
 
+static inline
+QDF_STATUS qdf_mem_debug_disabled_config_set(const char *str_value)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * qdf_mem_malloc() - allocation QDF memory
  * @size: Number of bytes of memory to allocate.
@@ -304,6 +330,26 @@ void qdf_mem_multi_pages_free(qdf_device_t osdev,
 
 #endif /* MEMORY_DEBUG */
 
+/**
+ * qdf_prealloc_disabled_config_get() - Get the user configuration of
+ *                                      prealloc_disabled
+ *
+ * Return: value of prealloc_disabled qdf module argument
+ */
+bool qdf_prealloc_disabled_config_get(void);
+
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * qdf_prealloc_disabled_config_set() - Set prealloc_disabled
+ * @str_value: value of the module param
+ *
+ * This function will set qdf module param prealloc_disabled
+ *
+ * Return: QDF_STATUS_SUCCESS on Success
+ */
+QDF_STATUS qdf_prealloc_disabled_config_set(const char *str_value);
+#endif
+
 /**
  * qdf_mem_multi_pages_zero() - zero out each page memory
  * @pages: Multi page information storage

+ 44 - 0
qdf/inc/qdf_trace.h

@@ -538,6 +538,8 @@ enum qdf_dpt_debugfs_state {
 	QDF_DPT_DEBUGFS_STATE_SHOW_COMPLETE,
 };
 
+#define QDF_WIFI_MODULE_PARAMS_FILE "wifi_module_param.ini"
+
 typedef void (*tp_qdf_trace_cb)(void *p_mac, tp_qdf_trace_record, uint16_t);
 typedef void (*tp_qdf_state_info_cb) (char **buf, uint16_t *size);
 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
@@ -1426,6 +1428,24 @@ int qdf_print_ctrl_register(const struct category_info *cinfo,
 			    void *custom_ctx,
 			    const char *pctrl_name);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * qdf_update_module_param() - Update qdf module params
+ *
+ *
+ * Read the file which has wifi module params, parse and update
+ * qdf module params.
+ *
+ * Return: void
+ */
+void qdf_initialize_module_param_from_ini(void);
+#else
+static inline
+void qdf_initialize_module_param_from_ini(void)
+{
+}
+#endif
+
 /**
  * qdf_shared_print_ctrl_init() - Initialize the shared print ctrl obj with
  *                                all categories set to the default level
@@ -1566,6 +1586,30 @@ bool qdf_print_get_node_flag(unsigned int idx);
 
 #endif
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * qdf_module_param_handler() - Function to store module params
+ *
+ * @context : NULL, unused.
+ * @key : Name of the module param
+ * @value: Value of the module param
+ *
+ * Handler function to be called from qdf_ini_parse()
+ * function when a valid parameter is found in a file.
+ *
+ * Return : QDF_STATUS_SUCCESS on Success
+ */
+QDF_STATUS qdf_module_param_handler(void *context, const char *key,
+				    const char *value);
+#else
+static inline
+QDF_STATUS qdf_module_param_handler(void *context, const char *key,
+				    const char *value)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /**
  * qdf_logging_init() - Initialize msg logging functionality
  *

+ 31 - 1
qdf/linux/src/i_qdf_mem.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-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
@@ -495,6 +495,36 @@ void *__qdf_mem_malloc(qdf_size_t size, const char *func, uint32_t line);
  */
 void __qdf_mem_free(void *ptr);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * __qdf_untracked_mem_malloc() - allocates non-QDF memory
+ * @size: Number of bytes of memory to allocate.
+ *
+ * @func: Function name of the call site
+ * @line: line number of the call site
+ *
+ * This function will dynamically allocate the specified number of bytes of
+ * memory. Memory allocated is not tracked by qdf memory debug framework.
+ *
+ * Return:
+ * Upon successful allocation, returns a non-NULL pointer to the allocated
+ * memory.  If this function is unable to allocate the amount of memory
+ * specified (for any reason) it returns NULL.
+ */
+void *__qdf_untracked_mem_malloc(qdf_size_t size, const char *func,
+				 uint32_t line);
+
+/**
+ * __qdf_untracked_mem_free() - free non-QDF memory
+ * @ptr: Pointer to the starting address of the memory to be freed.
+ *
+ * This function will free the memory pointed to by 'ptr'.
+ * Return: None
+ */
+
+void __qdf_untracked_mem_free(void *ptr);
+#endif
+
 /**
  * __qdf_mem_free_consistent() - free consistent qdf memory
  * @osdev: OS device handle

+ 39 - 0
qdf/linux/src/qdf_file.c

@@ -82,3 +82,42 @@ void qdf_file_buf_free(char *file_buf)
 }
 qdf_export_symbol(qdf_file_buf_free);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+QDF_STATUS qdf_module_param_file_read(const char *path, char **out_buf)
+{
+	int errno;
+	const struct firmware *fw;
+	char *buf;
+
+	*out_buf = NULL;
+	errno = qdf_firmware_request_nowarn(&fw, path, NULL);
+	if (errno) {
+		qdf_err("Failed to read file %s", path);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* qdf_untracked_mem_malloc zeros new memory; +1 size
+	 * ensures null-termination
+	 */
+	buf = qdf_untracked_mem_malloc(fw->size + 1);
+	if (!buf) {
+		release_firmware(fw);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	qdf_mem_copy(buf, fw->data, fw->size);
+	release_firmware(fw);
+	*out_buf = buf;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void qdf_module_param_file_free(char *file_buf)
+{
+	QDF_BUG(file_buf);
+	if (!file_buf)
+		return;
+
+	qdf_untracked_mem_free(file_buf);
+}
+#endif

+ 78 - 2
qdf/linux/src/qdf_mem.c

@@ -493,10 +493,41 @@ static int qdf_err_printer(void *priv, const char *fmt, ...)
 
 #endif /* MEMORY_DEBUG */
 
-u_int8_t prealloc_disabled = 1;
-qdf_declare_param(prealloc_disabled, byte);
+bool prealloc_disabled = 1;
+qdf_declare_param(prealloc_disabled, bool);
 qdf_export_symbol(prealloc_disabled);
 
+/**
+ * qdf_prealloc_disabled_config_get() - Get the user configuration of
+ *                                       prealloc_disabled
+ *
+ * Return: value of prealloc_disabled qdf module argument
+ */
+bool qdf_prealloc_disabled_config_get(void)
+{
+	return prealloc_disabled;
+}
+
+qdf_export_symbol(qdf_prealloc_disabled_config_get);
+
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+/**
+ * qdf_prealloc_disabled_config_set() - Set prealloc_disabled
+ * @str_value: value of the module param
+ *
+ * This function will set qdf module param prealloc_disabled
+ *
+ * Return: QDF_STATUS_SUCCESS on Success
+ */
+QDF_STATUS qdf_prealloc_disabled_config_set(const char *str_value)
+{
+	QDF_STATUS status;
+
+	status = qdf_bool_parse(str_value, &prealloc_disabled);
+	return status;
+}
+#endif
+
 #if defined WLAN_DEBUGFS
 
 /* Debugfs root directory for qdf_mem */
@@ -1404,6 +1435,24 @@ bool qdf_mem_debug_config_get(void)
 }
 #endif /* DISABLE_MEM_DBG_LOAD_CONFIG */
 
+/**
+ * qdf_mem_debug_disabled_set() - Set mem_debug_disabled
+ * @str_value: value of the module param
+ *
+ * This function will se qdf module param mem_debug_disabled
+ *
+ * Return: QDF_STATUS_SUCCESS on Success
+ */
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+QDF_STATUS qdf_mem_debug_disabled_config_set(const char *str_value)
+{
+	QDF_STATUS status;
+
+	status = qdf_bool_parse(str_value, &mem_debug_disabled);
+	return status;
+}
+#endif
+
 /**
  * qdf_mem_debug_init() - initialize qdf memory debug functionality
  *
@@ -2019,6 +2068,33 @@ void *__qdf_mem_malloc(size_t size, const char *func, uint32_t line)
 
 qdf_export_symbol(__qdf_mem_malloc);
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+void __qdf_untracked_mem_free(void *ptr)
+{
+	if (!ptr)
+		return;
+
+	kfree(ptr);
+}
+
+void *__qdf_untracked_mem_malloc(size_t size, const char *func, uint32_t line)
+{
+	void *ptr;
+
+	if (!size || size > QDF_MEM_MAX_MALLOC) {
+		qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func,
+			     line);
+		return NULL;
+	}
+
+	ptr = kzalloc(size, qdf_mem_malloc_flags());
+	if (!ptr)
+		return NULL;
+
+	return ptr;
+}
+#endif
+
 void *qdf_aligned_malloc_fl(uint32_t *size,
 			    void **vaddr_unaligned,
 				qdf_dma_addr_t *paddr_unaligned,

+ 2 - 1
qdf/linux/src/qdf_module.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, 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
@@ -48,6 +48,7 @@ static int __init qdf_mod_init(void)
 int qdf_mod_init(void)
 #endif
 {
+	qdf_initialize_module_param_from_ini();
 	qdf_shared_print_ctrl_init();
 	qdf_debugfs_init();
 	qdf_mem_init();

+ 81 - 0
qdf/linux/src/qdf_trace.c

@@ -25,8 +25,10 @@
 /* Include Files */
 #include "qdf_str.h"
 #include <qdf_trace.h>
+#include <qdf_parse.h>
 #include <qdf_module.h>
 #include <qdf_util.h>
+#include <qdf_mem.h>
 
 /* macro to map qdf trace levels into the bitmask */
 #define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level)))
@@ -103,6 +105,28 @@ static struct s_qdf_dp_trace_data g_qdf_dp_trace_data;
 static tp_qdf_dp_trace_cb qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX + 1];
 #endif
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+#define QDF_PARAM_STR_LENGTH 40
+
+enum qdf_num_module_param {
+	MEM_DEBUG_DISABLED,
+	QDF_DBG_MASK,
+	PREALLOC_DISABLED,
+	QDF_LOG_DUMP_AT_KERNEL_ENABLE,
+	QDF_DBG_ARR,
+	QDF_LOG_FLUSH_TIMER_PERIOD,
+	QDF_PARAM_MAX,
+};
+
+static char qdf_module_param[QDF_PARAM_MAX][QDF_PARAM_STR_LENGTH] = {
+	"mem_debug_disabled",
+	"qdf_dbg_mask",
+	"prealloc_disabled",
+	"qdf_log_dump_at_kernel_enable",
+	"qdf_dbg_arr",
+	"qdf_log_flush_timer_period",
+};
+#endif
 /**
  * qdf_snprintf() - wrapper function to snprintf
  * @str_buffer: string Buffer
@@ -3804,6 +3828,63 @@ void qdf_shared_print_ctrl_init(void)
 qdf_export_symbol(qdf_shared_print_ctrl_init);
 #endif
 
+#ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
+QDF_STATUS qdf_module_param_handler(void *context, const char *str_param,
+				    const char *str_value)
+{
+	QDF_STATUS status;
+	uint16_t param = 0;
+
+	while (param < QDF_PARAM_MAX) {
+		if (qdf_str_eq(qdf_module_param[param], str_param)) {
+			switch (param) {
+			case MEM_DEBUG_DISABLED:
+			status = qdf_mem_debug_disabled_config_set(str_value);
+				break;
+			case QDF_DBG_MASK:
+			status = qdf_int32_parse(str_value, &qdf_dbg_mask);
+				break;
+			case PREALLOC_DISABLED:
+			status = qdf_prealloc_disabled_config_set(str_value);
+				break;
+			case QDF_LOG_DUMP_AT_KERNEL_ENABLE:
+			status = qdf_bool_parse(str_value,
+						&qdf_log_dump_at_kernel_enable);
+				break;
+			case QDF_DBG_ARR:
+			qdf_dbg_arr[0] = (char *)str_value;
+				break;
+			case QDF_LOG_FLUSH_TIMER_PERIOD:
+			status = qdf_uint32_parse(str_value,
+						  &qdf_log_flush_timer_period);
+				break;
+			default:
+				break;
+			}
+			if (QDF_IS_STATUS_SUCCESS(status))
+				return QDF_STATUS_SUCCESS;
+		}
+		param++;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void qdf_initialize_module_param_from_ini(void)
+{
+	QDF_STATUS status;
+	char *path = QDF_WIFI_MODULE_PARAMS_FILE;
+
+	status = qdf_ini_parse(path, NULL, qdf_module_param_handler, NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
+				"Failed to parse *.ini file @ %s; status:%d",
+				path, status);
+		return;
+	}
+}
+#endif
+
 QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
 						QDF_MODULE_ID category,
 						QDF_TRACE_LEVEL verbose,

+ 8 - 2
qdf/src/qdf_parse.c

@@ -32,7 +32,10 @@ QDF_STATUS qdf_ini_parse(const char *ini_path, void *context,
 	char *cursor;
 	int ini_read_count = 0;
 
-	status = qdf_file_read(ini_path, &fbuf);
+	if (qdf_str_eq(QDF_WIFI_MODULE_PARAMS_FILE, ini_path))
+		status = qdf_module_param_file_read(ini_path, &fbuf);
+	else
+		status = qdf_file_read(ini_path, &fbuf);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		qdf_err("Failed to read *.ini file @ %s", ini_path);
 		return status;
@@ -132,7 +135,10 @@ QDF_STATUS qdf_ini_parse(const char *ini_path, void *context,
 	}
 
 free_fbuf:
-	qdf_file_buf_free(fbuf);
+	if (qdf_str_eq(QDF_WIFI_MODULE_PARAMS_FILE, ini_path))
+		qdf_module_param_file_free(fbuf);
+	else
+		qdf_file_buf_free(fbuf);
 
 	return status;
 }