diff --git a/Kbuild b/Kbuild index d37e7eaab18e..7a54c35642c9 100644 --- a/Kbuild +++ b/Kbuild @@ -105,6 +105,7 @@ HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_csr.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_connect.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_offload.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_roam.o +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_config.o ifeq ($(CONFIG_WLAN_MWS_INFO_DEBUGFS), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_coex.o endif diff --git a/core/hdd/inc/wlan_hdd_debugfs_config.h b/core/hdd/inc/wlan_hdd_debugfs_config.h new file mode 100644 index 000000000000..d0fa1ab4d1a2 --- /dev/null +++ b/core/hdd/inc/wlan_hdd_debugfs_config.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 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_debugfs_config.h + * + * WLAN Host Device Driver implementation to update + * debugfs with ini configs + */ + +#ifndef _WLAN_HDD_DEBUGFS_CONFIG_H +#define _WLAN_HDD_DEBUGFS_CONFIG_H + +#ifdef WLAN_DEBUGFS +/** + * hdd_debugfs_ini_config_init() - API to initialize ini config file + * @hdd_ctx: hdd context + * + * Return: 0 on success and errno on failure + */ +int hdd_debugfs_ini_config_init(struct hdd_context *hdd_ctx); + +/** + * hdd_debugfs_ini_config_deinit() - API to deinit ini config file + * @hdd_ctx: hdd context + * + * Return: None + */ +void hdd_debugfs_ini_config_deinit(struct hdd_context *hdd_ctx); +#else +static inline int hdd_debugfs_ini_config_init(struct hdd_context *hdd_ctx) +{ + return 0; +} + +static inline void hdd_debugfs_ini_config_deinit(struct hdd_context *hdd_ctx) +{ +} +#endif /* WLAN_DEBUGFS */ +#endif /* _WLAN_HDD_DEBUGFS_CONFIG_H */ diff --git a/core/hdd/src/wlan_hdd_debugfs_config.c b/core/hdd/src/wlan_hdd_debugfs_config.c new file mode 100644 index 000000000000..2e57b0db6863 --- /dev/null +++ b/core/hdd/src/wlan_hdd_debugfs_config.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2019 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_debugfs_config.c + * + * WLAN Host Device Driver implementation to update + * debugfs with ini configs + */ + +#include "wlan_hdd_main.h" +#include "osif_psoc_sync.h" +#include "cfg_ucfg_api.h" +#include "wlan_hdd_debugfs_config.h" + +#define DEBUGFS_CONFIG_BUF_SIZE (4096 * 8) + +/** + * struct ini_config_buf - the buffer struct to save ini configs + * @len: buffer len + * @result: the pointer to buffer + */ +struct ini_config_buf { + ssize_t len; + uint8_t result[DEBUGFS_CONFIG_BUF_SIZE]; +}; + +/** + * wlan_hdd_config_update() - Update userspace with local statistics buffer + * @buf: userspace buffer (to which data is being copied into) + * @count: max data that can be copied into buf + * @pos: offset (where data should be copied into) + * @ini_config: buffer structure for ini config info + * + * This function should copies ini configs into debugfs entry. + * + * Return: number of characters copied; 0 on no-copy + */ +static ssize_t wlan_hdd_config_update(char __user *buf, size_t count, + loff_t *pos, + struct ini_config_buf *ini_config) +{ + ssize_t ret_cnt; + + ret_cnt = simple_read_from_buffer(buf, count, pos, ini_config->result, + ini_config->len); + hdd_debug("ini config read req: count: %zu, pos: %lld", count, *pos); + + return ret_cnt; +} + +/** + * wlan_hdd_config_get() - Function to save ini config to buffer + * @hdd_ctx: hdd context used to register the debugfs file + * @ini_config: buffer structure for ini config info + * + * Return: Errno + */ +static int wlan_hdd_config_get(struct hdd_context *hdd_ctx, + struct ini_config_buf *ini_config) +{ + QDF_STATUS status; + + status = ucfg_cfg_ini_config_print(hdd_ctx->psoc, ini_config->result, + &ini_config->len, + DEBUGFS_CONFIG_BUF_SIZE); + return qdf_status_to_os_return(status); +} + +/** + * __wlan_hdd_read_config_debugfs() - function to get ini conifg + * @file: file pointer + * @buf: buffer + * @count: count + * @pos: position pointer + * + * Return: Number of bytes read on success, error number otherwise + */ +static ssize_t __wlan_hdd_read_config_debugfs(struct file *file, + char __user *buf, size_t count, + loff_t *pos) +{ + struct ini_config_buf *ini_config; + ssize_t err_size; + + ini_config = (struct ini_config_buf *)file->private_data; + if (!ini_config) + return -ENOMEM; + + err_size = wlan_hdd_config_update(buf, count, pos, ini_config); + + return err_size; +} + +/** + * wlan_hdd_read_config_debugfs() - wrapper function to get ini conifg + * @file: file pointer + * @buf: buffer + * @count: count + * @pos: position pointer + * + * Return: Number of bytes read on success, error number otherwise + */ +static ssize_t wlan_hdd_read_config_debugfs(struct file *file, + char __user *buf, size_t count, + loff_t *pos) +{ + struct hdd_context *hdd_ctx = file_inode(file)->i_private; + struct osif_psoc_sync *psoc_sync; + ssize_t err_size; + + err_size = wlan_hdd_validate_context(hdd_ctx); + if (err_size) + return err_size; + + err_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), + &psoc_sync); + if (err_size) + return err_size; + + err_size = __wlan_hdd_read_config_debugfs(file, buf, count, pos); + + osif_psoc_sync_op_stop(psoc_sync); + + return err_size; +} + +/** + * __wlan_hdd_open_config_debugfs() - function to open config debugfs + * @inode: Pointer to inode structure + * @file: file pointer + * + * Return: Errno + */ +static int __wlan_hdd_open_config_debugfs(struct inode *inode, + struct file *file) +{ + struct hdd_context *hdd_ctx = file_inode(file)->i_private; + struct ini_config_buf *ini_config; + ssize_t errno; + void *buf; + + buf = qdf_mem_malloc(sizeof(*ini_config)); + if (!buf) + return -ENOMEM; + + ini_config = (struct ini_config_buf *)buf; + errno = wlan_hdd_config_get(hdd_ctx, ini_config); + if (errno) { + qdf_mem_free(buf); + return errno; + } + + file->private_data = buf; + return 0; +} + +/** + * wlan_hdd_open_config_debugfs() - wrapper function to open config debugfs + * @inode: Pointer to inode structure + * @file: file pointer + * + * Return: Errno + */ +static int wlan_hdd_open_config_debugfs(struct inode *inode, struct file *file) +{ + struct hdd_context *hdd_ctx = file_inode(file)->i_private; + struct osif_psoc_sync *psoc_sync; + ssize_t errno; + + 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 = __wlan_hdd_open_config_debugfs(inode, file); + + osif_psoc_sync_op_stop(psoc_sync); + return errno; +} + +/** + * wlan_hdd_release_config_debugfs() - wrapper to release + * @inode: Pointer to inode structure + * @file: file pointer + * + * Return: Errno + */ +static int wlan_hdd_release_config_debugfs(struct inode *inode, + struct file *file) +{ + qdf_mem_free(file->private_data); + file->private_data = NULL; + + return 0; +} + +static const struct file_operations fops_config_debugfs = { + .read = wlan_hdd_read_config_debugfs, + .open = wlan_hdd_open_config_debugfs, + .release = wlan_hdd_release_config_debugfs, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +int hdd_debugfs_ini_config_init(struct hdd_context *hdd_ctx) +{ + if (!debugfs_create_file("ini_config", 0444, qdf_debugfs_get_root(), + hdd_ctx, &fops_config_debugfs)) + return -EINVAL; + + return 0; +} + +void hdd_debugfs_ini_config_deinit(struct hdd_context *hdd_ctx) +{ + /* + * Config ini doesn't have a directory it is removed + * as part of qdf remove + */ +} diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index fef9d8dda3d0..8d6bf1871635 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -170,6 +170,7 @@ #include #include #include +#include #include "wlan_blm_ucfg_api.h" #include "ol_txrx.h" #include "wlan_hdd_sta_info.h" @@ -7724,6 +7725,7 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx) hdd_enter(); + hdd_debugfs_ini_config_deinit(hdd_ctx); hdd_debugfs_mws_coex_info_deinit(hdd_ctx); hdd_psoc_idle_timer_stop(hdd_ctx); @@ -12751,6 +12753,7 @@ int hdd_wlan_startup(struct hdd_context *hdd_ctx) ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); hdd_debugfs_mws_coex_info_init(hdd_ctx); + hdd_debugfs_ini_config_init(hdd_ctx); wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev); hdd_exit();