--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -214,6 +214,8 @@ struct wmi_ops {
 	struct sk_buff *(*gen_peer_set_smart_ant_train_info)(struct ath10k *ar,
 			u32 vdev_id, const u8 *mac_addr,
 			const struct wmi_peer_sant_set_train_arg *arg);
+	struct sk_buff *(*gen_set_coex_param)(struct ath10k *ar,
+					      u32 wlan_traffic_priority);
 };
 
 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1538,4 +1540,22 @@ ath10k_wmi_peer_set_smart_ant_train_info
 	return ath10k_wmi_cmd_send(ar, skb,
 			ar->wmi.cmd->peer_set_smart_ant_train_info_cmdid);
 }
+
+static inline int
+ath10k_wmi_set_coex_param(struct ath10k *ar, u32 wlan_traffic_priority)
+{
+	struct sk_buff *skb;
+
+	if (!ar->wmi.ops->gen_set_coex_param)
+		return -EOPNOTSUPP;
+
+	skb = ar->wmi.ops->gen_set_coex_param(ar, wlan_traffic_priority);
+
+	if(IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	return ath10k_wmi_cmd_send(ar, skb,
+				   ar->wmi.cmd->set_coex_param_cmdid);
+}
+
 #endif
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -729,6 +729,7 @@ static struct wmi_cmd_map wmi_10_4_cmd_m
 	.pdev_bss_chan_info_request_cmdid =
 			WMI_10_4_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
 	.ext_resource_cfg_cmdid = WMI_10_4_EXT_RESOURCE_CFG_CMDID,
+	.set_coex_param_cmdid = WMI_10_4_BTCOEX_CFG_CMDID,
 };
 
 /* MAIN WMI VDEV param map */
@@ -8104,6 +8105,26 @@ ath10k_wmi_op_gen_set_smart_ant_train_in
 	return skb;
 }
 
+static struct sk_buff *
+ath10k_wmi_10_4_op_gen_set_coex_param(struct ath10k *ar,
+				      u32 wlan_traffic_priority)
+{
+	struct wmi_set_coex_param_10_4_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	cmd = (struct wmi_set_coex_param_10_4_cmd *)skb->data;
+	cmd->wlan_traffic_priority = __cpu_to_le32(wlan_traffic_priority);
+
+	ath10k_dbg(ar, ATH10K_DBG_WMI,
+		   "Wlan_traffic_priority :%u\n", wlan_traffic_priority);
+
+	return skb;
+}
+
 static const struct wmi_ops wmi_ops = {
 	.rx = ath10k_wmi_op_rx,
 	.map_svc = wmi_main_svc_map,
@@ -8478,6 +8499,7 @@ static const struct wmi_ops wmi_10_4_ops
 	.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
 	.gen_echo = ath10k_wmi_op_gen_echo,
 	.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
+	.gen_set_coex_param = ath10k_wmi_10_4_op_gen_set_coex_param,
 };
 
 int ath10k_wmi_attach(struct ath10k *ar)
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -184,6 +184,8 @@ enum wmi_service {
 	WMI_SERVICE_TX_MODE_PUSH_ONLY,
 	WMI_SERVICE_TX_MODE_PUSH_PULL,
 	WMI_SERVICE_TX_MODE_DYNAMIC,
+	WMI_SERVICE_VDEV_RX_FILTER,
+	WMI_SERVICE_BTCOEX,
 
 	/* keep last */
 	WMI_SERVICE_MAX,
@@ -310,6 +312,8 @@ enum wmi_10_4_service {
 	WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
 	WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
 	WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
+	WMI_10_4_SERVICE_VDEV_RX_FILTER,
+	WMI_10_4_SERVICE_BTCOEX,
 };
 
 static inline char *wmi_service_name(int service_id)
@@ -408,6 +412,7 @@ static inline char *wmi_service_name(int
 	SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY);
 	SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
 	SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
+	SVCSTR(WMI_SERVICE_BTCOEX);
 	default:
 		return NULL;
 	}
@@ -663,6 +668,8 @@ static inline void wmi_10_4_svc_map(cons
 	       WMI_SERVICE_TX_MODE_PUSH_PULL, len);
 	SVCMAP(WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
 	       WMI_SERVICE_TX_MODE_DYNAMIC, len);
+	SVCMAP(WMI_10_4_SERVICE_BTCOEX,
+	       WMI_SERVICE_BTCOEX, len);
 }
 
 #undef SVCMAP
@@ -842,6 +849,7 @@ struct wmi_cmd_map {
 	u32 peer_set_smart_tx_ant_cmdid;
 	u32 peer_smart_ant_fb_config_cmdid;
 	u32 peer_set_smart_ant_train_info_cmdid;
+	u32 set_coex_param_cmdid;
 };
 
 /*
@@ -1651,6 +1659,11 @@ enum wmi_10_4_cmd_id {
 	WMI_10_4_EXT_RESOURCE_CFG_CMDID,
 	WMI_10_4_VDEV_SET_IE_CMDID,
 	WMI_10_4_SET_LTEU_CONFIG_CMDID,
+	WMI_10_4_ATF_SSID_GROUPING_REQUEST_CMDID,
+	WMI_10_4_PEER_ATF_EXT_REQUEST_CMDID,
+	WMI_10_4_SET_PERIODIC_CHANNEL_STATS_CONFIG,
+	WMI_10_4_PEER_BWF_REQUEST_CMDID,
+	WMI_10_4_BTCOEX_CFG_CMDID,
 	WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
 };
 
@@ -2728,6 +2741,10 @@ struct wmi_ext_resource_config_10_4_cmd
 	__le32 fw_feature_bitmap;
 };
 
+struct wmi_set_coex_param_10_4_cmd {
+	__le32 wlan_traffic_priority;
+} __packed;
+
 /* strucutre describing host memory chunk. */
 struct host_memory_chunk {
 	/* id of the request that is passed up in service ready */
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -2182,6 +2182,8 @@ static const struct file_operations fops
 	.open = simple_open
 };
 
+#define ATH10K_DEFAULT_WLAN_PRIORITY_OVER_BT 0x38
+
 static ssize_t ath10k_write_btcoex(struct file *file,
 				   const char __user *ubuf,
 				   size_t count, loff_t *ppos)
@@ -2234,6 +2236,9 @@ static ssize_t ath10k_write_btcoex(struc
 	else
 		clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
 
+	ar->debug.wlan_traffic_priority =
+					ATH10K_DEFAULT_WLAN_PRIORITY_OVER_BT;
+
 	ret = count;
 
 exit:
@@ -2263,6 +2268,103 @@ static const struct file_operations fops
 	.open = simple_open
 };
 
+static ssize_t ath10k_write_btcoex_priority(struct file *file,
+					    const char __user *ubuf,
+					    size_t count, loff_t *ppos)
+{
+	struct ath10k *ar = file->private_data;
+	u32 wlan_traffic_priority;
+	int ret;
+
+	if (kstrtou32_from_user(ubuf, count, 0, &wlan_traffic_priority))
+		return -EINVAL;
+
+	if (wlan_traffic_priority > 0x3f)
+		return -E2BIG;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags))) {
+		ret = count;
+		goto exit;
+	}
+
+	if (ar->state != ATH10K_STATE_ON &&
+	    ar->state != ATH10K_STATE_RESTARTED) {
+		ret = -ENETDOWN;
+		goto exit;
+	}
+
+	ret = ath10k_wmi_set_coex_param(ar, wlan_traffic_priority);
+
+	if (ret) {
+		ath10k_warn(ar, "failed to set wlan priority %d\n", ret);
+		goto exit;
+	}
+
+	ar->debug.wlan_traffic_priority = wlan_traffic_priority;
+
+	ret = count;
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+#define ATH10K_BE_TRAFFIC_OVER_BT	BIT(0)
+#define ATH10K_BK_TRAFFIC_OVER_BT	BIT(1)
+#define ATH10K_VI_TRAFFIC_OVER_BT	BIT(2)
+#define ATH10K_VO_TRAFFIC_OVER_BT	BIT(3)
+#define ATH10K_BEACON_TRAFFIC_OVER_BT	BIT(4)
+#define ATH10K_MGMT_TRAFFIC_OVER_BT	BIT(5)
+
+static ssize_t ath10k_read_btcoex_priority(struct file *file, char __user *ubuf,
+				       size_t count, loff_t *ppos)
+{
+	char buf[100] = "";
+	struct ath10k *ar = file->private_data;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags))) {
+		strcpy (buf, "BTCOEX is disabled\n");
+		goto exit;
+	}
+
+	if (!ar->debug.wlan_traffic_priority) {
+	    strcpy(buf, "BT has higher priority than any of the WLAN frames");
+	} else {
+	strcat(buf, "Following frame(s) have higher priority than BT traffic\n");
+		if (ar->debug.wlan_traffic_priority &
+				ATH10K_BE_TRAFFIC_OVER_BT)
+			strcat(buf, "Best Effort\n");
+		if (ar->debug.wlan_traffic_priority &
+				ATH10K_BK_TRAFFIC_OVER_BT)
+			strcat(buf, "Background\n");
+		if (ar->debug.wlan_traffic_priority &
+				ATH10K_VI_TRAFFIC_OVER_BT)
+			strcat(buf, "Video\n");
+		if (ar->debug.wlan_traffic_priority &
+				ATH10K_VO_TRAFFIC_OVER_BT)
+			strcat(buf, "Voice\n");
+		if (ar->debug.wlan_traffic_priority &
+				ATH10K_BEACON_TRAFFIC_OVER_BT)
+			strcat(buf, "Beacon\n");
+		if (ar->debug.wlan_traffic_priority &
+				ATH10K_MGMT_TRAFFIC_OVER_BT)
+			strcat(buf, "Mgmt\n");
+	}
+
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return simple_read_from_buffer(ubuf, count, ppos, buf, strlen(buf));
+}
+
+static const struct file_operations fops_btcoex_priority = {
+	.read = ath10k_read_btcoex_priority,
+	.write = ath10k_write_btcoex_priority,
+	.open = simple_open
+};
+
 static ssize_t ath10k_write_peer_stats(struct file *file,
 				       const char __user *ubuf,
 				       size_t count, loff_t *ppos)
@@ -2512,10 +2614,17 @@ int ath10k_debug_register(struct ath10k
 	debugfs_create_file("tpc_stats", S_IRUSR,
 			    ar->debug.debugfs_phy, ar, &fops_tpc_stats);
 
-	if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
+	if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map)) {
 		debugfs_create_file("btcoex", S_IRUGO | S_IWUSR,
 				    ar->debug.debugfs_phy, ar, &fops_btcoex);
 
+		if (test_bit(WMI_SERVICE_BTCOEX, ar->wmi.svc_map))
+			debugfs_create_file("btcoex_priority",
+				S_IRUGO | S_IWUSR,
+				ar->debug.debugfs_phy, ar, &fops_btcoex_priority);
+
+	}
+
 	if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map))
 		debugfs_create_file("peer_stats", S_IRUGO | S_IWUSR,
 				    ar->debug.debugfs_phy, ar,
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -537,6 +537,7 @@ struct ath10k_debug {
 	u32 reg_addr;
 	u32 nf_cal_period;
 	void *cal_data;
+	u32 wlan_traffic_priority;
 
 	struct ath10k_fw_crash_data *fw_crash_data;
 #ifdef CPTCFG_ATH10K_PKTLOG
