wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/020-ath11k-add-btcoex-config.patch
John Crispin 8cd26b4b50 ipq807x: update to 11.4-CS
Signed-off-by: John Crispin <john@phrozen.org>
2021-09-14 09:16:23 +02:00

613 lines
19 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/Makefile
+++ b/drivers/net/wireless/ath/ath11k/Makefile
@@ -17,7 +17,8 @@ ath11k-y += core.o \
peer.o \
dbring.o \
hw.o \
- wow.o
+ wow.o \
+ vendor.o
ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -452,6 +452,16 @@ struct ath11k_per_peer_tx_stats {
#define ATH11K_FLUSH_TIMEOUT (5 * HZ)
#define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ)
+struct ath11k_coex_info {
+ bool coex_support;
+ u32 pta_num;
+ u32 coex_mode;
+ u32 bt_active_time_slot;
+ u32 bt_priority_time_slot;
+ u32 coex_algo_type;
+ u32 pta_priority;
+};
+
struct ath11k {
struct ath11k_base *ab;
struct ath11k_pdev *pdev;
@@ -570,6 +580,8 @@ struct ath11k {
struct ath11k_per_peer_tx_stats cached_stats;
u32 last_ppdu_id;
u32 cached_ppdu_id;
+
+ struct ath11k_coex_info coex;
#ifdef CPTCFG_ATH11K_DEBUGFS
struct ath11k_debug debug;
#endif
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5,6 +5,7 @@
#include <net/mac80211.h>
#include <linux/etherdevice.h>
+#include <linux/of.h>
#include "mac.h"
#include "core.h"
#include "debug.h"
@@ -15,6 +16,7 @@
#include "testmode.h"
#include "peer.h"
#include "debugfs_sta.h"
+#include "vendor.h"
#define CHAN2G(_channel, _freq, _flags) { \
.band = NL80211_BAND_2GHZ, \
@@ -6091,6 +6093,91 @@ static void ath11k_mac_op_sta_statistics
sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
}
+#define ATH11K_WLAN_PRIO_MAX 0x63
+#define ATH11K_WLAN_PRIO_WEIGHT 0xff
+
+int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif,
+ int coex, u32 wlan_prio_mask, u8 wlan_weight)
+{
+ struct coex_config_arg coex_config;
+ int ret;
+
+ if (ar->state != ATH11K_STATE_ON &&
+ ar->state != ATH11K_STATE_RESTARTED)
+ return -ENETDOWN;
+
+ if (coex == -1 || !(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags) ^ coex))
+ goto next;
+
+ coex_config.vdev_id = arvif->vdev_id;
+ if (coex == 1) {
+ coex_config.config_type = WMI_COEX_CONFIG_PTA_INTERFACE;
+ coex_config.pta_num = ar->coex.pta_num;
+ coex_config.coex_mode = ar->coex.coex_mode;
+ coex_config.bt_txrx_time = ar->coex.bt_active_time_slot;
+ coex_config.bt_priority_time = ar->coex.bt_priority_time_slot;
+ coex_config.pta_algorithm = ar->coex.coex_algo_type;
+ coex_config.pta_priority = ar->coex.pta_priority;
+ ret = ath11k_send_coex_config_cmd(ar, &coex_config);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to set coex config vdev_id %d ret %d\n",
+ coex_config.vdev_id, ret);
+ goto out;
+ }
+ }
+
+ memset(&coex_config, 0, sizeof(struct coex_config_arg));
+ coex_config.vdev_id = arvif->vdev_id;
+ coex_config.config_type = WMI_COEX_CONFIG_BTC_ENABLE;
+ coex_config.coex_enable = coex;
+ ret = ath11k_send_coex_config_cmd(ar, &coex_config);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to set coex config vdev_id %d ret %d\n",
+ coex_config.vdev_id, ret);
+ goto out;
+ }
+
+ if (coex)
+ set_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags);
+ else
+ clear_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags);
+
+next:
+ if (!wlan_prio_mask) {
+ ret = 0;
+ goto out;
+ }
+
+ if (!(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags))) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (wlan_prio_mask > ATH11K_WLAN_PRIO_MAX ||
+ wlan_weight > ATH11K_WLAN_PRIO_WEIGHT) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memset(&coex_config, 0, sizeof(struct coex_config_arg));
+ coex_config.vdev_id = arvif->vdev_id;
+ coex_config.config_type = WMI_COEX_CONFIG_WLAN_PKT_PRIORITY;
+ coex_config.wlan_pkt_type = wlan_prio_mask;
+ coex_config.wlan_pkt_weight = wlan_weight;
+ ret = ath11k_send_coex_config_cmd(ar, &coex_config);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to set coex config vdev_id %d ret %d\n",
+ coex_config.vdev_id, ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
static const struct ieee80211_ops ath11k_ops = {
.tx = ath11k_mac_op_tx,
.start = ath11k_mac_op_start,
@@ -6301,6 +6388,56 @@ static int ath11k_mac_setup_iface_combin
return 0;
}
+static void ath11k_mac_fetch_coex_info(struct ath11k *ar)
+{
+ struct ath11k_pdev_cap *cap = &ar->pdev->cap;
+ struct ath11k_base *ab = ar->ab;
+ struct device *dev = ab->dev;
+
+ ar->coex.coex_support = false;
+
+ if (!(cap->supported_bands & WMI_HOST_WLAN_2G_CAP))
+ return;
+
+ if (of_property_read_u32(dev->of_node, "qcom,pta-num",
+ &ar->coex.pta_num)) {
+ ath11k_err(ab, "No qcom,pta_num entry in dev-tree.\n");
+ }
+
+ if (of_property_read_u32(dev->of_node, "qcom,coex-mode",
+ &ar->coex.coex_mode)) {
+ ath11k_err(ab, "No qcom,coex_mode entry in dev-tree.\n");
+ }
+
+ if (of_property_read_u32(dev->of_node, "qcom,bt-active-time",
+ &ar->coex.bt_active_time_slot)) {
+ ath11k_err(ab, "No qcom,bt-active-time entry in dev-tree.\n");
+ }
+
+ if (of_property_read_u32(dev->of_node, "qcom,bt-priority-time",
+ &ar->coex.bt_priority_time_slot)) {
+ ath11k_err(ab, "No qcom,bt-priority-time entry in dev-tree.\n");
+ }
+
+ if (of_property_read_u32(dev->of_node, "qcom,coex-algo",
+ &ar->coex.coex_algo_type)) {
+ ath11k_err(ab, "No qcom,coex-algo entry in dev-tree.\n");
+ }
+
+ if (of_property_read_u32(dev->of_node, "qcom,pta-priority",
+ &ar->coex.pta_priority)) {
+ ath11k_err(ab, "No qcom,pta-priority entry in dev-tree.\n");
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "coex pta_num %u coex_mode %u"
+ " bt_active_time_slot %u bt_priority_time_slot %u"
+ " coex_algorithm %u pta_priority %u\n", ar->coex.pta_num,
+ ar->coex.coex_mode, ar->coex.bt_active_time_slot,
+ ar->coex.bt_priority_time_slot, ar->coex.coex_algo_type,
+ ar->coex.pta_priority);
+ ar->coex.coex_support = true;
+}
+
static const u8 ath11k_if_types_ext_capa[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
@@ -6494,6 +6631,7 @@ static int __ath11k_mac_register(struct
}
ath11k_reg_init(ar);
+ ath11k_vendor_register(ar);
if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
ar->hw->netdev_features = NETIF_F_HW_CSUM;
@@ -6624,6 +6762,7 @@ int ath11k_mac_allocate(struct ath11k_ba
*/
ath11k_wmi_pdev_attach(ab, i);
+ ath11k_mac_fetch_coex_info(ar);
ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask;
ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask;
ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask);
--- a/drivers/net/wireless/ath/ath11k/mac.h
+++ b/drivers/net/wireless/ath/ath11k/mac.h
@@ -139,8 +139,9 @@ void __ath11k_mac_scan_finish(struct ath
void ath11k_mac_scan_finish(struct ath11k *ar);
struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id);
-struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab,
- u32 vdev_id);
+struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id);
+int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif,
+ int coex, u32 wlan_prio_mask, u8 wlan_weight);
struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id);
struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id);
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/vendor.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ */
+
+#include <net/netlink.h>
+#include <net/mac80211.h>
+#include "core.h"
+#include "vendor.h"
+#include "debug.h"
+
+static const struct nla_policy
+ath11k_vendor_btcoex_config_policy[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+ath11k_vendor_wlan_prio_policy[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 },
+};
+
+static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ struct ieee80211_vif *vif;
+ struct ath11k_vif *arvif;
+ struct ath11k *ar;
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1];
+ struct nlattr *tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1];
+ struct nlattr *wlan_prio;
+ enum qca_wlan_priority_type wlan_prio_mask = 0;
+ int ret, coex = -1, rem_conf;
+ u8 wlan_weight = 0;
+
+ if (!wdev)
+ return -EINVAL;
+
+ vif = wdev_to_ieee80211_vif(wdev);
+ if (!vif)
+ return -EINVAL;
+
+ arvif = (struct ath11k_vif *)vif->drv_priv;
+ if (!arvif)
+ return -EINVAL;
+
+ ar = arvif->ar;
+
+ mutex_lock(&ar->conf_mutex);
+
+ ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX, data, data_len,
+ ath11k_vendor_btcoex_config_policy, NULL);
+ if (ret) {
+ ath11k_warn(ar->ab, "invalid BTCOEX config policy attribute\n");
+ goto out;
+ }
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] &&
+ !tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) {
+ ath11k_warn(ar->ab, "invalid BTCOEX config attributes\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]) {
+ coex = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]);
+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight);
+ if (ret)
+ goto out;
+ }
+ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) {
+ nla_for_each_nested(wlan_prio,
+ tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY],
+ rem_conf) {
+ ret =
+ nla_parse_nested(tb_wlan_prio, QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX,
+ wlan_prio, ath11k_vendor_wlan_prio_policy,
+ NULL);
+ if (ret)
+ goto out;
+ wlan_prio_mask =
+ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK]);
+ if (tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT])
+ wlan_weight =
+ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]);
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+ "BTCOEX enable %u WLAN Priority %u wlan weight %u\n",
+ coex, wlan_prio_mask, wlan_weight);
+
+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight);
+ if (ret)
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+}
+
+static struct wiphy_vendor_command ath11k_vendor_commands[] = {
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = ath11k_vendor_btcoex_configure,
+ .policy = ath11k_vendor_btcoex_config_policy
+ }
+};
+
+int ath11k_vendor_register(struct ath11k *ar)
+{
+ ar->hw->wiphy->vendor_commands = ath11k_vendor_commands;
+ ar->hw->wiphy->n_vendor_commands = ARRAY_SIZE(ath11k_vendor_commands);
+
+ return 0;
+}
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/vendor.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: ISC */
+/*
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef ATH11K_VENDOR_H
+#define ATH11K_VENDOR_H
+
+#define QCA_NL80211_VENDOR_ID 0x001374
+
+enum qca_nl80211_vendor_subcmds {
+ /* QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG: This command is used to
+ * enable/disable BTCOEX and set priority for different type of WLAN
+ * traffic over BT low priority traffic. This uses attributes in
+ * enum qca-vendor_attr_btcoex_config.
+ */
+ QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG = 182,
+};
+
+/*
+ * enum qca_wlan_priority_type - priority mask
+ * This enum defines priority mask that user can configure
+ * over BT traffic type which can be passed through
+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY attribute.
+ *
+ * @QCA_WLAN_PRIORITY_BE: Bit mask for WLAN Best effort traffic
+ * @QCA_WLAN_PRIORITY_BK: Bit mask for WLAN Background traffic
+ * @QCA_WLAN_PRIORITY_VI: Bit mask for WLAN Video traffic
+ * @QCA_WLAN_PRIORITY_VO: Bit mask for WLAN Voice traffic
+ * @QCA_WLAN_PRIORITY_BEACON: Bit mask for WLAN BEACON frame
+ * @QCA_WLAN_PRIORITY_MGMT: Bit mask for WLAN Management frame
+*/
+enum qca_wlan_priority_type {
+ QCA_WLAN_PRIORITY_BE = BIT(0),
+ QCA_WLAN_PRIORITY_BK = BIT(1),
+ QCA_WLAN_PRIORITY_VI = BIT(2),
+ QCA_WLAN_PRIORITY_VO = BIT(3),
+ QCA_WLAN_PRIORITY_BEACON = BIT(4),
+ QCA_WLAN_PRIORITY_MGMT = BIT(5),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_wlan_prio - Used to configure
+ * WLAN priority mask and its respective weight value.
+ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK - This is u8 attribute
+ * used to pass traffic type mask value see %qca_wlan_priority_type
+ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT - This is u8 attribute
+ * accepts value between 0 and 255 and used to configure weight for
+ * traffic type mentioned in %QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK.
+ */
+enum qca_wlan_vendor_attr_wlan_prio {
+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK = 1,
+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT = 2,
+
+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST,
+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX =
+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1,
+};
+
+
+
+/**
+ * enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command
+ * The use can enable/disable BTCOEX and configure WLAN priority for
+ * different traffic type over BT.
+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE, enable/disable BTCOEX
+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY, This is a nested
+ * attribute pass the attributes in %qca_wlan_vendor_attr_wlan_prio.
+ */
+enum qca_wlan_vendor_attr_btcoex_config {
+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE = 1,
+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY = 2,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST,
+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX =
+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST - 1
+};
+
+int ath11k_vendor_register(struct ath11k *ar);
+#endif /* QCA_VENDOR_H */
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1489,6 +1489,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct
return ret;
}
+static void ath11k_wmi_copy_coex_config(struct ath11k *ar, struct wmi_coex_config_cmd *cmd,
+ struct coex_config_arg *coex_config)
+{
+ if (coex_config->config_type == WMI_COEX_CONFIG_BTC_ENABLE) {
+ cmd->coex_enable = coex_config->coex_enable;
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI coex config type %u vdev id %d coex_enable %u\n",
+ coex_config->config_type, coex_config->vdev_id,
+ coex_config->coex_enable);
+ }
+
+ if (coex_config->config_type == WMI_COEX_CONFIG_WLAN_PKT_PRIORITY) {
+ cmd->wlan_pkt_type = coex_config->wlan_pkt_type;
+ cmd->wlan_pkt_weight = coex_config->wlan_pkt_weight;
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI coex config type %u vdev id %d wlan pkt type 0x%x wlan pkt weight %u\n",
+ coex_config->config_type, coex_config->vdev_id,
+ coex_config->wlan_pkt_type, coex_config->wlan_pkt_weight);
+ }
+
+ if (coex_config->config_type == WMI_COEX_CONFIG_PTA_INTERFACE) {
+ cmd->pta_num = coex_config->pta_num;
+ cmd->coex_mode = coex_config->coex_mode;
+ cmd->bt_txrx_time = coex_config->bt_txrx_time;
+ cmd->bt_priority_time = coex_config->bt_priority_time;
+ cmd->pta_algorithm = coex_config->pta_algorithm;
+ cmd->pta_priority = coex_config->pta_priority;
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI coex config type %u vdev id %d pta num %u coex mode %u bt_txrx_time %u bt_priority_time %u pta alogrithm %u pta priority %u\n",
+ coex_config->config_type, coex_config->vdev_id,
+ coex_config->pta_num, coex_config->coex_mode,
+ coex_config->bt_txrx_time, coex_config->bt_priority_time,
+ coex_config->pta_algorithm, coex_config->pta_priority);
+ }
+}
+
+int ath11k_send_coex_config_cmd(struct ath11k *ar,
+ struct coex_config_arg *coex_config)
+{
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
+ struct wmi_coex_config_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_coex_config_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_COEX_CONFIG_CMD) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+
+ cmd->vdev_id = coex_config->vdev_id;
+ cmd->config_type = coex_config->config_type;
+ ath11k_wmi_copy_coex_config(ar, cmd, coex_config);
+
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_COEX_CONFIG_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to send WMI_COEX_CONFIG_CMD cmd\n");
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar,
struct stats_request_params *param)
{
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -4735,6 +4735,79 @@ struct wmi_wmm_params_arg {
u8 no_ack;
};
+enum wmi_coex_config_type {
+ WMI_COEX_CONFIG_PAGE_P2P_TDM = 1,
+ WMI_COEX_CONFIG_PAGE_STA_TDM = 2,
+ WMI_COEX_CONFIG_PAGE_SAP_TDM = 3,
+ WMI_COEX_CONFIG_DURING_WLAN_CONN = 4,
+ WMI_COEX_CONFIG_BTC_ENABLE = 5,
+ WMI_COEX_CONFIG_COEX_DBG = 6,
+ WMI_COEX_CONFIG_PAGE_P2P_STA_TDM = 7,
+ WMI_COEX_CONFIG_INQUIRY_P2P_TDM = 8,
+ WMI_COEX_CONFIG_INQUIRY_STA_TDM = 9,
+ WMI_COEX_CONFIG_INQUIRY_SAP_TDM = 10,
+ WMI_COEX_CONFIG_INQUIRY_P2P_STA_TDM = 11,
+ WMI_COEX_CONFIG_TX_POWER = 12,
+ WMI_COEX_CONFIG_PTA_CONFIG = 13,
+ WMI_COEX_CONFIG_AP_TDM = 14,
+ WMI_COEX_CONFIG_WLAN_SCAN_PRIORITY = 15,
+ WMI_COEX_CONFIG_WLAN_PKT_PRIORITY = 16,
+ WMI_COEX_CONFIG_PTA_INTERFACE = 17,
+};
+
+struct coex_config_arg {
+ u32 vdev_id;
+ u32 config_type;
+ union {
+ struct {
+ u32 coex_enable;
+ };
+
+ struct {
+ u32 pta_num;
+ u32 coex_mode;
+ u32 bt_txrx_time;
+ u32 bt_priority_time;
+ u32 pta_algorithm;
+ u32 pta_priority;
+ };
+
+ struct {
+ u32 wlan_pkt_type;
+ u32 wlan_pkt_type_continued;
+ u32 wlan_pkt_weight;
+ u32 bt_pkt_weight;
+ };
+ };
+};
+
+struct wmi_coex_config_cmd {
+ u32 tlv_header;
+ u32 vdev_id;
+ u32 config_type;
+ union {
+ struct {
+ u32 coex_enable;
+ } __packed;
+
+ struct {
+ u32 pta_num;
+ u32 coex_mode;
+ u32 bt_txrx_time;
+ u32 bt_priority_time;
+ u32 pta_algorithm;
+ u32 pta_priority;
+ } __packed;
+
+ struct {
+ u32 wlan_pkt_type;
+ u32 wlan_pkt_type_continued;
+ u32 wlan_pkt_weight;
+ u32 bt_pkt_weight;
+ } __packed;
+ } __packed;
+} __packed;
+
struct wmi_vdev_set_wmm_params_cmd {
u32 tlv_header;
u32 vdev_id;
@@ -5351,6 +5424,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e
u32 *bitmap);
int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar,
u32 *bitmap);
+int ath11k_send_coex_config_cmd(struct ath11k *ar,
+ struct coex_config_arg *coex_config);
int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
u8 bss_color, u32 period,
bool enable);