From 966791c66fedb9dde45465fad3025b78633373dd Mon Sep 17 00:00:00 2001
From: Rameshkumar Sundaram <ramess@codeaurora.org>
Date: Fri, 7 May 2021 17:24:50 +0530
Subject: [PATCH] ath11k: 6GHz Add support to send beacon in configured phymode

For 6GHz band, FW expects WMI_VDEV_PARAM_6GHZ_PARAMS with required bit values
set to transmit beacon, probe and FD frames in configured phy mode.
Without this param regardless of phy mode, 6GHz beacons are sent only in
20M bandwidth.

Hence adding support to send this vdev param during vdev creation and
phymode update events, so that beacons will be sent in configured phymode.

This command is also sent in 11AX_HE20 mode to unset non ht dup params of the vdev
if set earlier during phy mode changes.

Signed-off-by: Rameshkumar Sundaram <ramess@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/mac.c | 27 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/wmi.h |  8 ++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index cbd4813..454c7e6 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6934,6 +6934,29 @@ static void ath11k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
 	mutex_unlock(&ar->conf_mutex);
 }
 
+static int ath11k_mac_set_6g_nonht_dup_conf(struct ath11k_vif *arvif, const struct cfg80211_chan_def *chandef)
+{
+	struct ath11k *ar = arvif->ar;
+	int ret = 0;
+	bool is_nontx_ap = !!(arvif->vif->multiple_bssid.flags & IEEE80211_VIF_MBSS_NON_TRANSMITTING);
+	enum wmi_phy_mode mode = ath11k_phymodes[chandef->chan->band][chandef->width];
+
+	if ((arvif->vdev_type == WMI_VDEV_TYPE_AP) && !is_nontx_ap &&
+		(chandef->chan->band == NL80211_BAND_6GHZ)) {
+		int param_id = WMI_VDEV_PARAM_6GHZ_PARAMS;
+		uint8_t value = 0;
+		if (mode > MODE_11AX_HE20) {
+			value |= WMI_VDEV_6GHZ_BITMAP_NON_HT_DUPLICATE_BEACON;
+			value |= WMI_VDEV_6GHZ_BITMAP_NON_HT_DUPLICATE_BCAST_PROBE_RSP;
+			value |= WMI_VDEV_6GHZ_BITMAP_NON_HT_DUPLICATE_FD_FRAME;
+		}
+		ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Set 6GHz non-ht dup params for vdev %pM , vdev_id %d param %d value %d\n",
+				arvif->vif->addr, arvif->vdev_id, param_id, value);
+		ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param_id, value);
+        }
+	return ret;
+}
+
 static int
 ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
 			      const struct cfg80211_chan_def *chandef,
@@ -7054,6 +7077,10 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
 		ath11k_warn(ab, "failed to set txbf conf for vdev %d: %d\n",
 			    arvif->vdev_id, ret);
 
+	ret = ath11k_mac_set_6g_nonht_dup_conf(arvif, chandef);
+	if (ret)
+                ath11k_warn(ab, "failed to set 6G non-ht dup conf for vdev %d: %d\n",
+                            arvif->vdev_id, ret);
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 23c704d..d6ec11d 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2230,6 +2230,14 @@ enum {
 /* preablbe short */
 #define WMI_VDEV_PREAMBLE_SHORT         0x2
 
+/** 6GHZ params **/
+/* Control to enable/disable beacon tx in non-HT duplicate */
+#define WMI_VDEV_6GHZ_BITMAP_NON_HT_DUPLICATE_BEACON		BIT(0)
+/* Control to enable/disable broadcast probe response tx in non-HT duplicate */
+#define WMI_VDEV_6GHZ_BITMAP_NON_HT_DUPLICATE_BCAST_PROBE_RSP	BIT(1)
+/* Control to enable/disable FILS discovery frame tx in non-HT duplicate */
+#define WMI_VDEV_6GHZ_BITMAP_NON_HT_DUPLICATE_FD_FRAME		BIT(2)
+
 enum wmi_peer_smps_state {
 	WMI_PEER_SMPS_PS_NONE = 0x0,
 	WMI_PEER_SMPS_STATIC  = 0x1,
-- 
2.7.4

