From 08df65447c1dcc2364ea345302bf2d59caae6bc3 Mon Sep 17 00:00:00 2001 From: Arun Kumar Khandavalli Date: Wed, 13 May 2020 22:18:09 +0530 Subject: [PATCH] qcacld-3.0: Add the sysfs entry for policy manager commands Previously pm_cinfo,pm_pcl would be queried via iwpriv --> iwpriv wlan0 pm_cinfo it is now changed to support via sysfs: --> cat /sys/class/net/wifi/pm_cinfo --> echo 1 > /sys/kernel/wifi/pm_pcl Change-Id: I437eb6d4e9424f3aed9d1cf218333371c9a9f93b CRs-Fixed: 2684258 --- Kbuild | 1 + core/hdd/inc/wlan_hdd_sysfs_policy_mgr.h | 84 ++++++++++ core/hdd/src/wlan_hdd_sysfs.c | 5 + core/hdd/src/wlan_hdd_sysfs_policy_mgr.c | 201 +++++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 core/hdd/inc/wlan_hdd_sysfs_policy_mgr.h create mode 100644 core/hdd/src/wlan_hdd_sysfs_policy_mgr.c diff --git a/Kbuild b/Kbuild index 0fd81e66a0bc..3a3769dbe159 100644 --- a/Kbuild +++ b/Kbuild @@ -361,6 +361,7 @@ endif ifeq ($(CONFIG_REMOVE_PKT_LOG), n) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_pktlog.o endif +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_policy_mgr.o endif ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y) diff --git a/core/hdd/inc/wlan_hdd_sysfs_policy_mgr.h b/core/hdd/inc/wlan_hdd_sysfs_policy_mgr.h new file mode 100644 index 000000000000..316044e7a565 --- /dev/null +++ b/core/hdd/inc/wlan_hdd_sysfs_policy_mgr.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011-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. + */ +#ifndef WLAN_HDD_SYSFS_POLICY_MGR_H +#define WLAN_HDD_SYSFS_POLICY_MGR_H + + #ifdef WLAN_SYSFS + +/** + * hdd_sysfs_pm_cinfo_create(): Initialize pm_cinfo specific sysfs + * @driver_kobject: Driver Kobject + * + * Function to initialize pm_cinfo specific mode syfs files. + * + * Return: NONE + */ +void hdd_sysfs_pm_cinfo_create(struct kobject *driver_kobject); + +/** + * hdd_sysfs_pm_cinfo_destroy(): Remove pm_cinfo sysfs file + * @driver_kobject: Driver Kobject + * + * Function to remove pm_cinfo specific mode syfs files. + * + * Return: NONE + */ +void hdd_sysfs_pm_cinfo_destroy(struct kobject *driver_kobject); + +/** + * hdd_sysfs_pm_pcl_create() - API to create pm_pcl + * @driver_kobject: sysfs driver kobject + * + * file path: /sys/kernel/wifi/pm_pcl + * + * usage: + * echo [arg_0] > pm_pcl + * + * Return: 0 on success and errno on failure + */ +int hdd_sysfs_pm_pcl_create(struct kobject *driver_kobject); + +/** + * hdd_sysfs_pm_pcl_destroy() - + * API to destroy pm_pcl + * + * Return: none + */ +void +hdd_sysfs_pm_pcl_destroy(struct kobject *driver_kobject); +#else +static inline int +hdd_sysfs_pm_pcl_create(struct kobject *driver_kobject) +{ + return 0; +} + +static inline void +hdd_sysfs_pm_pcl_destroy(struct kobject *driver_kobject) +{ +} + +static inline +void hdd_sysfs_pm_cinfo_create(struct kobject *driver_kobject) +{ +} + +static inline +void hdd_sysfs_pm_cinfo_destroy(struct kobject *driver_kobject) +{ +} +#endif +#endif diff --git a/core/hdd/src/wlan_hdd_sysfs.c b/core/hdd/src/wlan_hdd_sysfs.c index 18755761c4e5..c27bf6a0ace7 100644 --- a/core/hdd/src/wlan_hdd_sysfs.c +++ b/core/hdd/src/wlan_hdd_sysfs.c @@ -72,6 +72,7 @@ #include #include #include +#include #define MAX_PSOC_ID_SIZE 10 @@ -773,12 +774,16 @@ void hdd_create_sysfs_files(struct hdd_context *hdd_ctx) hdd_sysfs_dp_trace_create(driver_kobject); hdd_sysfs_thermal_cfg_create(driver_kobject); hdd_sysfs_pktlog_create(driver_kobject); + hdd_sysfs_pm_cinfo_create(driver_kobject); + hdd_sysfs_pm_pcl_create(driver_kobject); } } void hdd_destroy_sysfs_files(void) { if (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) { + hdd_sysfs_pm_pcl_destroy(driver_kobject); + hdd_sysfs_pm_cinfo_destroy(driver_kobject); hdd_sysfs_pktlog_destroy(driver_kobject); hdd_sysfs_thermal_cfg_destroy(driver_kobject); hdd_sysfs_dp_trace_destroy(driver_kobject); diff --git a/core/hdd/src/wlan_hdd_sysfs_policy_mgr.c b/core/hdd/src/wlan_hdd_sysfs_policy_mgr.c new file mode 100644 index 000000000000..028fc3814bd3 --- /dev/null +++ b/core/hdd/src/wlan_hdd_sysfs_policy_mgr.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2011-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. + */ + +#include +#include +#include +#include "osif_sync.h" +#include + +static ssize_t hdd_pm_cinfo_show(struct hdd_context *hdd_ctx) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t i = 0, len = 0; + + hdd_enter(); + + if (!wlan_hdd_validate_modules_state(hdd_ctx)) + return -EINVAL; + + conn_info = policy_mgr_get_conn_info(&len); + pr_info("+--------------------------+\n"); + for (i = 0; i < len; i++) { + pr_info("|table_index[%d]\t\t\n", i); + pr_info("|\t|vdev_id - %-10d|\n", conn_info->vdev_id); + pr_info("|\t|freq - %-10d|\n", conn_info->freq); + pr_info("|\t|bw - %-10d|\n", conn_info->bw); + pr_info("|\t|mode - %-10d|\n", conn_info->mode); + pr_info("|\t|mac - %-10d|\n", conn_info->mac); + pr_info("|\t|in_use - %-10d|\n", conn_info->in_use); + pr_info("+--------------------------+\n"); + conn_info++; + } + + hdd_exit(); + return 0; +} + +static ssize_t hdd_sysfs_pm_cminfo_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + ssize_t err_size; + + if (wlan_hdd_validate_context(hdd_ctx)) + return 0; + + err_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), + &psoc_sync); + if (err_size) + return err_size; + + err_size = hdd_pm_cinfo_show(hdd_ctx); + + osif_psoc_sync_op_stop(psoc_sync); + return err_size; +} + +static ssize_t +__hdd_sysfs_pm_pcl_store(struct hdd_context *hdd_ctx, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1]; + uint8_t weight_list[NUM_CHANNELS] = {0}; + uint32_t pcl[NUM_CHANNELS] = {0}; + uint32_t pcl_len = 0, val, i = 0; + char *sptr, *token; + QDF_STATUS status; + int 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; + } + + sptr = buf_local; + hdd_debug("pm_pcl: count %zu buf_local:(%s)", + count, buf_local); + + /* Get val */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou32(token, 0, &val)) + return -EINVAL; + + if (!hdd_ctx->config->is_unit_test_framework_enabled) { + hdd_warn_rl("UT framework is disabled"); + return -EINVAL; + } + + status = policy_mgr_get_pcl(hdd_ctx->psoc, val, + pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); + + if (status != QDF_STATUS_SUCCESS) + hdd_err("can't get pcl policy manager"); + + hdd_debug("PCL Freq list for role[%d] is {", val); + for (i = 0 ; i < pcl_len; i++) + hdd_debug(" %d, ", pcl[i]); + hdd_debug("}--------->\n"); + + return count; +} + +static ssize_t +hdd_sysfs_pm_pcl_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + ssize_t errno_size; + int ret; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) + return ret; + + errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), + &psoc_sync); + if (errno_size) + return errno_size; + + errno_size = __hdd_sysfs_pm_pcl_store(hdd_ctx, attr, + buf, count); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno_size; +} + +static struct kobj_attribute pm_pcl_attribute = + __ATTR(pm_pcl, 0220, NULL, + hdd_sysfs_pm_pcl_store); + +static struct kobj_attribute pm_cinfo_attribute = + __ATTR(pm_cinfo, 0440, + hdd_sysfs_pm_cminfo_show, NULL); + +int hdd_sysfs_pm_pcl_create(struct kobject *driver_kobject) +{ + int error; + + if (!driver_kobject) { + hdd_err("could not get driver kobject!"); + return -EINVAL; + } + + error = sysfs_create_file(driver_kobject, + &pm_pcl_attribute.attr); + if (error) + hdd_err("could not create pm_pcl sysfs file"); + + return error; +} + +void +hdd_sysfs_pm_pcl_destroy(struct kobject *driver_kobject) +{ + if (!driver_kobject) { + hdd_err("could not get driver kobject!"); + return; + } + sysfs_remove_file(driver_kobject, &pm_pcl_attribute.attr); +} + +void hdd_sysfs_pm_cinfo_create(struct kobject *driver_kobject) +{ + if (sysfs_create_file(driver_kobject, &pm_cinfo_attribute.attr)) + hdd_err("Failed to create pktlog sysfs entry"); +} + +void hdd_sysfs_pm_cinfo_destroy(struct kobject *driver_kobject) +{ + sysfs_remove_file(driver_kobject, &pm_cinfo_attribute.attr); +}