diff --git a/Kbuild b/Kbuild index c7b56fa162b3..e854d52246ae 100644 --- a/Kbuild +++ b/Kbuild @@ -229,6 +229,10 @@ ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_fw_state.o endif +ifeq ($(CONFIG_QCACLD_FEATURE_COEX_CONFIG), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_coex_config.o +endif + ifeq ($(CONFIG_QCACLD_FEATURE_MPTA_HELPER), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_mpta_helper.o endif @@ -2511,6 +2515,9 @@ cppflags-$(CONFIG_WLAN_DYNAMIC_CVM) += -DFEATURE_WLAN_DYNAMIC_CVM #Flag to enable get firmware state feature cppflags-$(CONFIG_QCACLD_FEATURE_FW_STATE) += -DFEATURE_FW_STATE +#Flag to enable set coex configuration feature +cppflags-$(CONFIG_QCACLD_FEATURE_COEX_CONFIG) += -DFEATURE_COEX_CONFIG + #Flag to enable MPTA helper feature cppflags-$(CONFIG_QCACLD_FEATURE_MPTA_HELPER) += -DFEATURE_MPTA_HELPER diff --git a/configs/default_defconfig b/configs/default_defconfig index 7d4dc6798b32..be3bf4f3f2b4 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -121,6 +121,9 @@ CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := n #Flag to enable get firmware state CONFIG_QCACLD_FEATURE_FW_STATE := y +#Flag to enable set coex configuration +CONFIG_QCACLD_FEATURE_COEX_CONFIG := y + ifeq ($(CONFIG_ARCH_MSM8998), y) CONFIG_QCACLD_FEATURE_METERING := y endif diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 7b757fc4bc8a..fc4c4b39f003 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -137,6 +137,7 @@ #include "wlan_fwol_ucfg_api.h" #include "wlan_cfg80211_crypto.h" #include "wlan_scan_ucfg_api.h" +#include "wlan_hdd_coex_config.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -12709,6 +12710,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { FEATURE_ACTIVE_TOS_VENDOR_COMMANDS FEATURE_NAN_VENDOR_COMMANDS FEATURE_FW_STATE_COMMANDS + FEATURE_COEX_CONFIG_COMMANDS FEATURE_MPTA_HELPER_COMMANDS }; diff --git a/core/hdd/src/wlan_hdd_coex_config.c b/core/hdd/src/wlan_hdd_coex_config.c new file mode 100644 index 000000000000..fe2755fc18a4 --- /dev/null +++ b/core/hdd/src/wlan_hdd_coex_config.c @@ -0,0 +1,186 @@ +/* + * 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_coex_config.c + * + * The implementation of coex configuration + * + */ + +#include "wlan_hdd_main.h" +#include "wmi_unified_param.h" +#include "wlan_hdd_coex_config.h" +#include "qca_vendor.h" +#include "wlan_osif_request_manager.h" +#include "osif_sync.h" + +static const struct nla_policy +coex_config_three_way_policy[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX + 1] = { + [QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE] = { + .type = NLA_U32}, + [QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1] = {.type = NLA_U32}, + [QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2] = {.type = NLA_U32}, + [QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3] = {.type = NLA_U32}, + [QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4] = {.type = NLA_U32}, +}; + +static const uint32_t +config_type_to_wmi_tbl[QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_TYPE_MAX] = { + [QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_RESET] = + WMI_COEX_CONFIG_THREE_WAY_COEX_RESET, + [QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_START] = + WMI_COEX_CONFIG_THREE_WAY_COEX_START, +}; + +/** + * __wlan_hdd_cfg80211_set_coex_config() - set coex configuration + * parameters + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to limit off-channel command parameters. + * @data_len: the length in byte of limit off-channel command parameters. + * + * Return: An error code or 0 on success. + */ +static int __wlan_hdd_cfg80211_set_coex_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev); + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX + 1]; + uint32_t config_type; + struct coex_config_params coex_cfg_params = {0}; + int errno; + QDF_STATUS status; + + hdd_enter(); + + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno != 0) + return errno; + + if (wlan_cfg80211_nla_parse(tb, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX, + data, data_len, + coex_config_three_way_policy)) { + hdd_err("Invalid coex config ATTR"); + return -EINVAL; + } + + if (!tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE]) { + hdd_err("coex config - attr config_type failed"); + return -EINVAL; + } + + config_type = nla_get_u32( + tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE]); + if (config_type >= QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_TYPE_MAX) { + hdd_err("config_type value %d exceeded Max value %d", + config_type, + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_TYPE_MAX); + return -EINVAL; + } + coex_cfg_params.config_type = config_type_to_wmi_tbl[config_type]; + if (coex_cfg_params.config_type < + WMI_COEX_CONFIG_THREE_WAY_DELAY_PARA || + coex_cfg_params.config_type > + WMI_COEX_CONFIG_THREE_WAY_COEX_START) { + hdd_err("config_type_wmi val error %d", + coex_cfg_params.config_type); + return -EINVAL; + } + + hdd_debug("config_type %d, config_type_wmi %d", + config_type, coex_cfg_params.config_type); + + if (!tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1]) { + hdd_err("coex config - attr priority1 failed"); + return -EINVAL; + } + coex_cfg_params.config_arg1 = nla_get_u32( + tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1]); + + hdd_debug("priority1 0x%x", coex_cfg_params.config_arg1); + + if (!tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2]) { + hdd_err("coex config - attr priority2 failed"); + return -EINVAL; + } + coex_cfg_params.config_arg2 = nla_get_u32( + tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2]); + + hdd_debug("priority2 0x%x", coex_cfg_params.config_arg2); + + if (!tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3]) { + hdd_err("coex config - attr priority3 failed"); + return -EINVAL; + } + coex_cfg_params.config_arg3 = nla_get_u32( + tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3]); + + hdd_debug("priority3 0x%x", coex_cfg_params.config_arg3); + + if (!tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4]) { + hdd_err("coex config - attr priority4 failed"); + return -EINVAL; + } + coex_cfg_params.config_arg4 = nla_get_u32( + tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4]); + + hdd_debug("priority4 0x%x", coex_cfg_params.config_arg4); + + coex_cfg_params.vdev_id = adapter->vdev_id; + status = sme_send_coex_config_cmd(&coex_cfg_params); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to send coex config params"); + return -EINVAL; + } + + return 0; +} + +/** + * wlan_hdd_cfg80211_set_coex_config() - set coex configuration + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to limit off-channel command parameters. + * @data_len: the length in byte of limit off-channel command parameters. + * + * + * Return: An error code or 0 on success. + */ +int wlan_hdd_cfg80211_set_coex_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_set_coex_config(wiphy, wdev, + data, data_len); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} diff --git a/core/hdd/src/wlan_hdd_coex_config.h b/core/hdd/src/wlan_hdd_coex_config.h new file mode 100644 index 000000000000..fbba0d03160b --- /dev/null +++ b/core/hdd/src/wlan_hdd_coex_config.h @@ -0,0 +1,57 @@ +/* + * 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_coex_config.h + * + * Add Vendor subcommand QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG + */ + +#ifndef __WLAN_HDD_COEX_CONFIG_H +#define __WLAN_HDD_COEX_CONFIG_H + +#ifdef FEATURE_COEX_CONFIG +#include + +/** + * wlan_hdd_cfg80211_set_coex_config() - set coex configuration + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to limit off-channel command parameters. + * @data_len: the length in byte of limit off-channel command parameters. + * + * Return: An error code or 0 on success. + */ +int wlan_hdd_cfg80211_set_coex_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +#define FEATURE_COEX_CONFIG_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG,\ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV | \ + WIPHY_VENDOR_CMD_NEED_RUNNING, \ + .doit = wlan_hdd_cfg80211_set_coex_config \ +}, +#else /* FEATURE_COEX_CONFIG */ +#define FEATURE_COEX_CONFIG_COMMANDS +#endif /* FEATURE_COEX_CONFIG */ + +#endif /* __WLAN_HDD_COEX_CONFIG_H */