qcacld-3.0: Set Coex priorities among WLAN/BT/ZB
Coex priority on some scenarios need to be updated.
Host will transfer the chosen coex config attributes
by WMI command.
Change-Id: Ic28ad6af462b305ec9aaf3027d76bce9ae6320b1
CRs-Fixed: 2410493
diff --git a/Kbuild b/Kbuild
index c7b56fa..e854d52 100644
--- a/Kbuild
+++ b/Kbuild
@@ -229,6 +229,10 @@
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 @@
#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 7d4dc67..be3bf4f 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -121,6 +121,9 @@
#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 7b757fc..fc4c4b3 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 @@
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 0000000..fe2755f
--- /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 0000000..fbba0d0
--- /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 <net/cfg80211.h>
+
+/**
+ * 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 */