|
@@ -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
|
|
|
+ */
|
|
|
+}
|