diff --git a/Kbuild b/Kbuild index 260e94f87e..66837efab7 100644 --- a/Kbuild +++ b/Kbuild @@ -272,6 +272,7 @@ endif ifeq ($(CONFIG_FEATURE_UNIT_TEST_SUSPEND), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_suspend_resume.o endif +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_unit_test.o endif ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y) diff --git a/core/hdd/inc/wlan_hdd_debugfs_unit_test.h b/core/hdd/inc/wlan_hdd_debugfs_unit_test.h index 0bb173b1e8..6031b42880 100644 --- a/core/hdd/inc/wlan_hdd_debugfs_unit_test.h +++ b/core/hdd/inc/wlan_hdd_debugfs_unit_test.h @@ -48,28 +48,4 @@ wlan_hdd_debugfs_unit_test_host_create(struct hdd_context *hdd_ctx) return 0; } #endif - -#ifdef WLAN_DEBUGFS -/** - * hdd_debugfs_unit_test_target_create() - API to create unit_test_target file - * @adapter: hdd adapter - * - * this file is created per adapter. - * file path: /sys/kernel/debug/wlan_xx/unit_test_target - * (wlan_xx is adapter name) - * usage: - * echo [module_id] [arg_num] [arg_0] [arg_xx] ... >unit_test_target - * echo '5' '2' '2' '1'>unit_test_target - * echo "5 2 2 1">unit_test_target //using one null space as delimiter - * - * Return: 0 on success and errno on failure - */ -int wlan_hdd_debugfs_unit_test_target_create(struct hdd_adapter *adapter); -#else -static inline int -wlan_hdd_debugfs_unit_test_target_create(struct hdd_adapter *adapter) -{ - return 0; -} -#endif /* WLAN_DEBUGFS */ #endif /* _WLAN_HDD_DEBUGFS_UNIT_TEST_H */ diff --git a/core/hdd/src/wlan_hdd_debugfs.c b/core/hdd/src/wlan_hdd_debugfs.c index f7e4482f6e..cad86d8270 100644 --- a/core/hdd/src/wlan_hdd_debugfs.c +++ b/core/hdd/src/wlan_hdd_debugfs.c @@ -556,9 +556,6 @@ QDF_STATUS hdd_debugfs_init(struct hdd_adapter *adapter) if (wlan_hdd_create_ll_stats_file(adapter)) return QDF_STATUS_E_FAILURE; - if (wlan_hdd_debugfs_unit_test_target_create(adapter)) - return QDF_STATUS_E_FAILURE; - return QDF_STATUS_SUCCESS; } diff --git a/core/hdd/src/wlan_hdd_debugfs_unit_test.c b/core/hdd/src/wlan_hdd_debugfs_unit_test.c index 681eb5c620..1e65c96d86 100644 --- a/core/hdd/src/wlan_hdd_debugfs_unit_test.c +++ b/core/hdd/src/wlan_hdd_debugfs_unit_test.c @@ -28,13 +28,8 @@ #include "wlan_dsc_test.h" #include "wlan_hdd_unit_test.h" #include "wlan_hdd_debugfs_unit_test.h" -#include "wlan_module_ids.h" #include "wma.h" -/* strlen("5 1 1") + 1(\n) */ -#define MIN_USER_COMMAND_SIZE_UNIT_TEST_TARGET 6 -#define MAX_USER_COMMAND_SIZE_UNIT_TEST_TARGET 256 - #ifdef WLAN_UNIT_TEST /* strlen("all") + 1(\n) */ #define MIN_USER_COMMAND_SIZE_UNIT_TEST_HOST 4 @@ -140,161 +135,3 @@ int wlan_hdd_debugfs_unit_test_host_create(struct hdd_context *hdd_ctx) return 0; } #endif /* WLAN_UNIT_TEST */ - -/** - * __wlan_hdd_write_unit_test_target_debugfs() - * - target unit test debugfs handler - * - * @net_dev: net_device context used to register the debugfs file - * @buf: text being written to the debugfs - * @count: size of @buf - * @ppos: (unused) offset into the virtual file system - * - * Return: number of bytes processed - */ -static ssize_t __wlan_hdd_write_unit_test_target_debugfs( - struct net_device *net_dev, - const char __user *buf, size_t count, - loff_t *ppos) -{ - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); - struct hdd_context *hdd_ctx; - char buf_local[MAX_USER_COMMAND_SIZE_UNIT_TEST_TARGET + 1]; - char *sptr, *token; - uint32_t apps_args[WMA_MAX_NUM_ARGS]; - int module_id, args_num, ret, i; - QDF_STATUS status; - - if (hdd_validate_adapter(adapter)) { - hdd_err_rl("adapter validate fail"); - return -EINVAL; - } - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - ret = wlan_hdd_validate_context(hdd_ctx); - if (ret != 0) - return ret; - - if (!wlan_hdd_validate_modules_state(hdd_ctx)) - return -EINVAL; - - if (count < MIN_USER_COMMAND_SIZE_UNIT_TEST_TARGET || - count > MAX_USER_COMMAND_SIZE_UNIT_TEST_TARGET) { - hdd_err_rl("Command length (%zu) is invalid, expected [%d, %d]", - count, - MIN_USER_COMMAND_SIZE_UNIT_TEST_TARGET, - MAX_USER_COMMAND_SIZE_UNIT_TEST_TARGET); - return -EINVAL; - } - - /* Get command from user */ - if (copy_from_user(buf_local, buf, count)) - return -EFAULT; - /* default 'echo' cmd takes new line character to here*/ - if (buf_local[count - 1] == '\n') - buf_local[count - 1] = '\0'; - else - buf_local[count] = '\0'; - - sptr = buf_local; - hdd_nofl_info("unit_test: count %zu buf_local:(%s) net_devname %s", - count, buf_local, net_dev->name); - - /* Get module_id */ - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &module_id)) - return -EINVAL; - - /* Get args_num */ - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - if (kstrtou32(token, 0, &args_num)) - return -EINVAL; - - if (module_id < WLAN_MODULE_ID_MIN || - module_id >= WLAN_MODULE_ID_MAX) { - hdd_err_rl("Invalid MODULE ID %d", module_id); - return -EINVAL; - } - if (args_num > WMA_MAX_NUM_ARGS) { - hdd_err_rl("Too many args %d", args_num); - return -EINVAL; - } - - for (i = 0; i < args_num; i++) { - token = strsep(&sptr, " "); - if (!token) { - hdd_err_rl("not enough args(%d), expected args_num:%d", - i, args_num); - return -EINVAL; - } - if (kstrtou32(token, 0, &apps_args[i])) - return -EINVAL; - } - - status = sme_send_unit_test_cmd(adapter->vdev_id, - module_id, - args_num, - &apps_args[0]); - if (status != QDF_STATUS_SUCCESS) { - hdd_err_rl("sme_send_unit_test_cmd returned %d", status); - return -EINVAL; - } - - return count; -} - -/** - * wlan_hdd_write_unit_test_target_debugfs() - * - wrapper for __wlan_hdd_write_unit_test_target_debugfs - * - * @file: file pointer - * @buf: buffer - * @count: count - * @ppos: position pointer - * - * Return: number of bytes processed or errno - */ -static ssize_t wlan_hdd_write_unit_test_target_debugfs( - struct file *file, - const char __user *buf, - size_t count, loff_t *ppos) -{ - struct net_device *net_dev = file_inode(file)->i_private; - struct osif_vdev_sync *vdev_sync; - ssize_t errno_size; - - errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync); - if (errno_size) - return errno_size; - - errno_size = __wlan_hdd_write_unit_test_target_debugfs( - net_dev, buf, count, ppos); - if (errno_size < 0) - hdd_err_rl("errno_size %zd", errno_size); - - osif_vdev_sync_op_stop(vdev_sync); - - return errno_size; -} - -static const struct file_operations fops_unit_test_target_debugfs = { - .write = wlan_hdd_write_unit_test_target_debugfs, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -int wlan_hdd_debugfs_unit_test_target_create(struct hdd_adapter *adapter) -{ - struct net_device *net_dev = adapter->dev; - - if (!debugfs_create_file("unit_test_target", 00400 | 00200, - adapter->debugfs_phy, - net_dev, &fops_unit_test_target_debugfs)) - return -EINVAL; - - return 0; -} diff --git a/core/hdd/src/wlan_hdd_sysfs.c b/core/hdd/src/wlan_hdd_sysfs.c index 5bd403c31a..ca8c1e81b0 100644 --- a/core/hdd/src/wlan_hdd_sysfs.c +++ b/core/hdd/src/wlan_hdd_sysfs.c @@ -41,6 +41,7 @@ #include #include "wlan_hdd_sysfs_crash_inject.h" #include "wlan_hdd_sysfs_suspend_resume.h" +#include "wlan_hdd_sysfs_unit_test.h" #define MAX_PSOC_ID_SIZE 10 @@ -616,11 +617,13 @@ hdd_sysfs_create_sta_adapter_root_obj(struct hdd_adapter *adapter) hdd_sysfs_crash_inject_create(adapter); hdd_sysfs_suspend_create(adapter); hdd_sysfs_resume_create(adapter); + hdd_sysfs_unit_test_target_create(adapter); } static void hdd_sysfs_destroy_sta_adapter_root_obj(struct hdd_adapter *adapter) { + hdd_sysfs_unit_test_target_destroy(adapter); hdd_sysfs_resume_destroy(adapter); hdd_sysfs_suspend_destroy(adapter); hdd_sysfs_crash_inject_destroy(adapter); @@ -634,11 +637,13 @@ hdd_sysfs_create_sap_adapter_root_obj(struct hdd_adapter *adapter) hdd_sysfs_crash_inject_create(adapter); hdd_sysfs_suspend_create(adapter); hdd_sysfs_resume_create(adapter); + hdd_sysfs_unit_test_target_create(adapter); } static void hdd_sysfs_destroy_sap_adapter_root_obj(struct hdd_adapter *adapter) { + hdd_sysfs_unit_test_target_destroy(adapter); hdd_sysfs_resume_destroy(adapter); hdd_sysfs_suspend_destroy(adapter); hdd_sysfs_crash_inject_destroy(adapter); diff --git a/core/hdd/src/wlan_hdd_sysfs_unit_test.c b/core/hdd/src/wlan_hdd_sysfs_unit_test.c new file mode 100644 index 0000000000..2436b19980 --- /dev/null +++ b/core/hdd/src/wlan_hdd_sysfs_unit_test.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020, 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_unit_test.c + * + * WLAN Host Device Driver implementation to create sysfs + * unit_test_target + */ +#include "wlan_hdd_main.h" +#include "osif_psoc_sync.h" +#include "osif_vdev_sync.h" +#include "wlan_dsc_test.h" +#include "wlan_hdd_sysfs.h" +#include "wlan_hdd_sysfs_unit_test.h" +#include "wlan_module_ids.h" +#include "wma.h" + +#define MAX_USER_COMMAND_SIZE_UNIT_TEST_TARGET 256 + +static ssize_t __hdd_sysfs_unit_test_target_store( + struct net_device *net_dev, + const char __user *buf, size_t count) +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); + struct hdd_context *hdd_ctx; + char buf_local[MAX_USER_COMMAND_SIZE_UNIT_TEST_TARGET + 1]; + char *sptr, *token; + uint32_t apps_args[WMA_MAX_NUM_ARGS]; + int module_id, args_num, ret, i; + QDF_STATUS status; + + if (hdd_validate_adapter(adapter)) { + hdd_err_rl("adapter validate fail"); + return -EINVAL; + } + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) + return ret; + + 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) { + hdd_err_rl("invalid input"); + return ret; + } + + hdd_nofl_info("unit_test_target: count %zu buf_local:(%s) net_devname %s", + count, buf_local, net_dev->name); + + sptr = buf_local; + /* Get module_id */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou32(token, 0, &module_id)) + return -EINVAL; + + /* Get args_num */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou32(token, 0, &args_num)) + return -EINVAL; + + if (module_id < WLAN_MODULE_ID_MIN || + module_id >= WLAN_MODULE_ID_MAX) { + hdd_err_rl("Invalid MODULE ID %d", module_id); + return -EINVAL; + } + if (args_num > WMA_MAX_NUM_ARGS) { + hdd_err_rl("Too many args %d", args_num); + return -EINVAL; + } + + for (i = 0; i < args_num; i++) { + token = strsep(&sptr, " "); + if (!token) { + hdd_err_rl("not enough args(%d), expected args_num:%d", + i, args_num); + return -EINVAL; + } + if (kstrtou32(token, 0, &apps_args[i])) + return -EINVAL; + } + + status = sme_send_unit_test_cmd(adapter->vdev_id, + module_id, + args_num, + &apps_args[0]); + if (status != QDF_STATUS_SUCCESS) { + hdd_err_rl("sme_send_unit_test_cmd returned %d", status); + return -EINVAL; + } + + return count; +} + +static ssize_t hdd_sysfs_unit_test_target_store(struct device *dev, + struct device_attribute *attr, + char const *buf, size_t count) +{ + struct net_device *net_dev = container_of(dev, struct net_device, dev); + struct osif_vdev_sync *vdev_sync; + ssize_t errno_size; + + errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync); + if (errno_size) + return errno_size; + + errno_size = __hdd_sysfs_unit_test_target_store( + net_dev, buf, count); + if (errno_size < 0) + hdd_err_rl("errno_size %zd", errno_size); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno_size; +} + +static DEVICE_ATTR(unit_test_target, 0220, + NULL, hdd_sysfs_unit_test_target_store); + +int hdd_sysfs_unit_test_target_create(struct hdd_adapter *adapter) +{ + int error; + + error = device_create_file(&adapter->dev->dev, + &dev_attr_unit_test_target); + if (error) + hdd_err("could not create unit_test_target sysfs file"); + + return error; +} + +void hdd_sysfs_unit_test_target_destroy(struct hdd_adapter *adapter) +{ + device_remove_file(&adapter->dev->dev, &dev_attr_unit_test_target); +} + diff --git a/core/hdd/src/wlan_hdd_sysfs_unit_test.h b/core/hdd/src/wlan_hdd_sysfs_unit_test.h new file mode 100644 index 0000000000..0d74a0ebe7 --- /dev/null +++ b/core/hdd/src/wlan_hdd_sysfs_unit_test.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, 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_unit_test.h + * + * implementation for creating sysfs file unit_test_target + */ + +#ifndef _WLAN_HDD_SYSFS_UNIT_TEST_H +#define _WLAN_HDD_SYSFS_UNIT_TEST_H + +#if defined(WLAN_SYSFS) +/** + * hdd_sysfs_unit_test_target_create() - API to create unit_test_target file + * @adapter: hdd adapter + * + * this file is created per adapter. + * file path: /sys/class/net/wlan_xx/unit_test_target + * (wlan_xx is adapter name) + * usage: + * echo [module_id] [arg_num] [arg_0] [arg_xx] ... >unit_test_target + * echo 5 2 2 1 >unit_test_target + * + * Return: 0 on success and errno on failure + */ +int hdd_sysfs_unit_test_target_create(struct hdd_adapter *adapter); + +/** + * hdd_sysfs_unit_test_target_destroy() - + * API to destroy unit_test_target sys file + * @adapter: pointer to adapter + * + * Return: none + */ +void hdd_sysfs_unit_test_target_destroy(struct hdd_adapter *adapter); +#else +static inline int +hdd_sysfs_unit_test_target_create(struct hdd_adapter *adapter) +{ + return 0; +} + +static inline void +hdd_sysfs_unit_test_target_destroy(struct hdd_adapter *adapter) +{ +} +#endif +#endif /* #ifndef _WLAN_HDD_SYSFS_UNIT_TEST_H */