[openwrt/openwrt] mac80211: ath12k: add patches for 160MHz support

LEDE Commits lede-commits at lists.infradead.org
Sat Apr 12 01:39:10 PDT 2025


ansuel pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/9e3a2466f6944c77276aa6e7cd3f98dc6ffdadf1

commit 9e3a2466f6944c77276aa6e7cd3f98dc6ffdadf1
Author: Mantas Pucka <mantas at 8devices.com>
AuthorDate: Fri Apr 4 15:02:17 2025 +0300

    mac80211: ath12k: add patches for 160MHz support
    
    Add series enabling 160MHz channels on ath12k
    
    Signed-off-by: Mantas Pucka <mantas at 8devices.com>
    Link: https://github.com/openwrt/openwrt/pull/18459
    Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 ...ath12k-push-HE-MU-MIMO-params-to-hardware.patch |  469 +++++++++
 ...th12k-push-EHT-MU-MIMO-params-to-hardware.patch |  222 ++++
 ...move-HE-MCS-mapper-to-a-separate-function.patch |  162 +++
 ...e-rx-and-tx-mcs-maps-for-supported-HE-mcs.patch |  186 ++++
 ...and-RX-MCS-rate-configurations-in-HE-mode.patch |  141 +++
 ...-support-for-setting-fixed-HE-rate-GI-LTF.patch | 1095 ++++++++++++++++++++
 .../104-7-wifi-ath12k-clean-up-80P80-support.patch |  254 +++++
 ...-ath12k-add-support-for-160-MHz-bandwidth.patch |  399 +++++++
 ...xtended-NSS-bandwidth-support-for-160-MHz.patch |  191 ++++
 9 files changed, 3119 insertions(+)

diff --git a/package/kernel/mac80211/patches/ath12k/104-1-wifi-ath12k-push-HE-MU-MIMO-params-to-hardware.patch b/package/kernel/mac80211/patches/ath12k/104-1-wifi-ath12k-push-HE-MU-MIMO-params-to-hardware.patch
new file mode 100644
index 0000000000..8c0e67a8bf
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-1-wifi-ath12k-push-HE-MU-MIMO-params-to-hardware.patch
@@ -0,0 +1,469 @@
+From patchwork Wed Sep 18 21:20:48 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807212
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com
+ [205.220.168.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id A06681CA6B9
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:13 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.168.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694475; cv=none;
+ b=HjUnHV2ZbMRZne/OD71kC1p0zBs+1+LVanM+3YbUfCnjvvtSry2r0Dj0HBjHnId1ltZw0ebTJaEZDcXBybkc2yiiGRlcH5s4feXisp9WApElGptz2Qn1SEtO3VDLKyE5m56eJftK/dpin6HPZGOk3hMBHkxoo966Jp4vlC9e2rY=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694475; c=relaxed/simple;
+	bh=lJX5iM2Ahf/ROaeR2Kk4suhcbwA47aOSPqyQsesg4A0=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=RYEWdi9+UZKYtzHKfAF5xdIOkpdgQjBK8hE1SX/f0rJDxozjZe1jDY28C+kzN4uhSwcBSwr7pZjMLL8LELNITE6fIk/zDY5UAO/jdeUPBnTrmrckzZOwaCFIQ1nt6ssDZDfpJADBjCIuMXB7HNChH3qSMlmYTV9QTDxpBK0fQxM=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=EtpV59A6; arc=none smtp.client-ip=205.220.168.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="EtpV59A6"
+Received: from pps.filterd (m0279862.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48IL3WbX003099;
+	Wed, 18 Sep 2024 21:21:07 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	3ukRiLVgAcc9GoJxAaFrgsHYImZ/9ZPgSlMf75Ew/1Y=; b=EtpV59A6K8yD5o5B
+	8JSYPL7TI2tnIQciUmyLNJig3DWGn3AZbFqPjgTYUgoQLHjsNWd+WRAKx13tQhSW
+	peq0OW9986uI1TFVpaw0pwVXoBiStEI5MH/7ThiA5nIAI4hYBI6+iiwL7qWpboSL
+	UrG9sWI35wsgcjedTtrzR2QfpeTAvlnReoac/49o5GAysu1oGDN79VAAP7tDZbO2
+	trx/XdQmW/8iqtRR3Idhjcod6B6ovXKkmAZUHzhp4zRupTUsKOU84X3aTYZQLN/B
+	46HuFZSlOJEB/63Co7I2K8YfQT3FikP2mkrIsDwH78Y2OekhXJWFe7dU4SsX6nh6
+	sIXVxA==
+Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4gd387e-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:07 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL6rr020545
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:06 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:06 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Muna Sinada <quic_msinada at quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 1/9] wifi: ath12k: push HE MU-MIMO params to hardware
+Date: Wed, 18 Sep 2024 14:20:48 -0700
+Message-ID: <20240918212056.4137076-2-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-ORIG-GUID: QTgqLsl2p5OGLwWEQsGrsmA8q68U11H8
+X-Proofpoint-GUID: QTgqLsl2p5OGLwWEQsGrsmA8q68U11H8
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ malwarescore=0 suspectscore=0
+ bulkscore=0 clxscore=1015 spamscore=0 adultscore=0 lowpriorityscore=0
+ mlxlogscore=999 impostorscore=0 mlxscore=0 priorityscore=1501 phishscore=0
+ classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000
+ definitions=main-2409180140
+
+Currently, only the HE IE in management frames is updated with
+respect to MU-MIMO configurations, but this change is not
+reflected in the hardware. Add support to propagate MU-MIMO
+configurations to the hardware as well.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Co-developed-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 215 +++++++++++++++++---------
+ drivers/net/wireless/ath/ath12k/mac.h |  15 ++
+ drivers/net/wireless/ath/ath12k/wmi.h |  28 +---
+ 3 files changed, 156 insertions(+), 102 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -2851,6 +2851,108 @@ static int ath12k_setup_peer_smps(struct
+ 					 ath12k_smps_map[smps]);
+ }
+ 
++static int ath12k_mac_set_he_txbf_conf(struct ath12k_vif *arvif)
++{
++	struct ath12k *ar = arvif->ar;
++	u32 param = WMI_VDEV_PARAM_SET_HEMU_MODE;
++	u32 value = 0;
++	int ret;
++
++	if (!arvif->vif->bss_conf.he_support)
++		return 0;
++
++	if (arvif->vif->bss_conf.he_su_beamformer) {
++		value |= u32_encode_bits(HE_SU_BFER_ENABLE, HE_MODE_SU_TX_BFER);
++		if (arvif->vif->bss_conf.he_mu_beamformer &&
++		    arvif->vdev_type == WMI_VDEV_TYPE_AP)
++			value |= u32_encode_bits(HE_MU_BFER_ENABLE, HE_MODE_MU_TX_BFER);
++	}
++
++	if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) {
++		value |= u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) |
++			 u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA);
++
++		if (arvif->vif->bss_conf.he_full_ul_mumimo)
++			value |= u32_encode_bits(HE_UL_MUMIMO_ENABLE, HE_MODE_UL_MUMIMO);
++
++		if (arvif->vif->bss_conf.he_su_beamformee)
++			value |= u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE);
++	}
++
++	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value);
++	if (ret) {
++		ath12k_warn(ar->ab, "failed to set vdev %d HE MU mode: %d\n",
++			    arvif->vdev_id, ret);
++		return ret;
++	}
++
++	param = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE;
++	value =	u32_encode_bits(HE_VHT_SOUNDING_MODE_ENABLE, HE_VHT_SOUNDING_MODE) |
++		u32_encode_bits(HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE,
++				HE_TRIG_NONTRIG_SOUNDING_MODE);
++	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
++					    param, value);
++	if (ret) {
++		ath12k_warn(ar->ab, "failed to set vdev %d sounding mode: %d\n",
++			    arvif->vdev_id, ret);
++		return ret;
++	}
++
++	return 0;
++}
++
++static int ath12k_mac_vif_recalc_sta_he_txbf(struct ath12k *ar,
++					     struct ieee80211_vif *vif,
++					     struct ieee80211_sta_he_cap *he_cap,
++					     int *hemode)
++{
++	struct ieee80211_he_cap_elem he_cap_elem = {};
++	struct ieee80211_sta_he_cap *cap_band;
++	struct cfg80211_chan_def def;
++
++	if (!vif->bss_conf.he_support)
++		return 0;
++
++	if (vif->type != NL80211_IFTYPE_STATION)
++		return -EINVAL;
++
++	if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
++		return -EINVAL;
++
++	if (def.chan->band == NL80211_BAND_2GHZ)
++		cap_band = &ar->mac.iftype[NL80211_BAND_2GHZ][vif->type].he_cap;
++	else
++		cap_band = &ar->mac.iftype[NL80211_BAND_5GHZ][vif->type].he_cap;
++
++	memcpy(&he_cap_elem, &cap_band->he_cap_elem, sizeof(he_cap_elem));
++
++	*hemode = 0;
++	if (HECAP_PHY_SUBFME_GET(he_cap_elem.phy_cap_info)) {
++		if (HECAP_PHY_SUBFMR_GET(he_cap->he_cap_elem.phy_cap_info))
++			*hemode |= u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE);
++		if (HECAP_PHY_MUBFMR_GET(he_cap->he_cap_elem.phy_cap_info))
++			*hemode |= u32_encode_bits(HE_MU_BFEE_ENABLE, HE_MODE_MU_TX_BFEE);
++	}
++
++	if (vif->type != NL80211_IFTYPE_MESH_POINT) {
++		*hemode |= u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) |
++			  u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA);
++
++		if (HECAP_PHY_ULMUMIMO_GET(he_cap_elem.phy_cap_info))
++			if (HECAP_PHY_ULMUMIMO_GET(he_cap->he_cap_elem.phy_cap_info))
++				*hemode |= u32_encode_bits(HE_UL_MUMIMO_ENABLE,
++							  HE_MODE_UL_MUMIMO);
++
++		if (u32_get_bits(*hemode, HE_MODE_MU_TX_BFEE))
++			*hemode |= u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE);
++
++		if (u32_get_bits(*hemode, HE_MODE_MU_TX_BFER))
++			*hemode |= u32_encode_bits(HE_SU_BFER_ENABLE, HE_MODE_SU_TX_BFER);
++	}
++
++	return 0;
++}
++
+ static void ath12k_bss_assoc(struct ath12k *ar,
+ 			     struct ath12k_vif *arvif,
+ 			     struct ieee80211_bss_conf *bss_conf)
+@@ -2858,9 +2960,11 @@ static void ath12k_bss_assoc(struct ath1
+ 	struct ieee80211_vif *vif = arvif->vif;
+ 	struct ath12k_wmi_vdev_up_params params = {};
+ 	struct ath12k_wmi_peer_assoc_arg peer_arg;
++	struct ieee80211_sta_he_cap he_cap;
+ 	struct ieee80211_sta *ap_sta;
+ 	struct ath12k_peer *peer;
+ 	bool is_auth = false;
++	u32 hemode = 0;
+ 	int ret;
+ 
+ 	lockdep_assert_held(&ar->conf_mutex);
+@@ -2880,8 +2984,29 @@ static void ath12k_bss_assoc(struct ath1
+ 
+ 	ath12k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg, false);
+ 
++	/* he_cap here is updated at assoc success for sta mode only */
++	he_cap = ap_sta->deflink.he_cap;
++
++	/* ap_sta->deflink.he_cap must be protected by rcu_read_lock */
++	ret = ath12k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap, &hemode);
++	if (ret) {
++		ath12k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM: %d\n",
++			    arvif->vdev_id, bss_conf->bssid, ret);
++		rcu_read_unlock();
++		return;
++	}
++
+ 	rcu_read_unlock();
+ 
++	/* keep this before ath12k_wmi_send_peer_assoc_cmd() */
++	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
++					    WMI_VDEV_PARAM_SET_HEMU_MODE, hemode);
++	if (ret) {
++		ath12k_warn(ar->ab, "failed to submit vdev param txbf 0x%x: %d\n",
++			    hemode, ret);
++		return;
++	}
++
+ 	ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
+ 	if (ret) {
+ 		ath12k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n",
+@@ -3220,6 +3345,13 @@ static void ath12k_mac_bss_info_changed(
+ 		ether_addr_copy(arvif->bssid, info->bssid);
+ 
+ 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
++		if (info->enable_beacon) {
++			ret = ath12k_mac_set_he_txbf_conf(arvif);
++			if (ret)
++				ath12k_warn(ar->ab,
++					    "failed to set HE TXBF config for vdev: %d\n",
++					    arvif->vdev_id);
++		}
+ 		ath12k_control_beaconing(arvif, info);
+ 
+ 		if (arvif->is_up && vif->bss_conf.he_support &&
+@@ -5351,11 +5483,14 @@ static void ath12k_mac_copy_he_cap(struc
+ 
+ 	he_cap_elem->mac_cap_info[1] &=
+ 		IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
+-
++	he_cap_elem->phy_cap_info[0] &=
++		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
++		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
++		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
++	he_cap_elem->phy_cap_info[0] &=
++		~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
+ 	he_cap_elem->phy_cap_info[5] &=
+ 		~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;
+-	he_cap_elem->phy_cap_info[5] &=
+-		~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
+ 	he_cap_elem->phy_cap_info[5] |= num_tx_chains - 1;
+ 
+ 	switch (iftype) {
+@@ -6317,71 +6452,6 @@ static int ath12k_mac_setup_vdev_create_
+ 	return 0;
+ }
+ 
+-static u32
+-ath12k_mac_prepare_he_mode(struct ath12k_pdev *pdev, u32 viftype)
+-{
+-	struct ath12k_pdev_cap *pdev_cap = &pdev->cap;
+-	struct ath12k_band_cap *cap_band = NULL;
+-	u32 *hecap_phy_ptr = NULL;
+-	u32 hemode;
+-
+-	if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP)
+-		cap_band = &pdev_cap->band[NL80211_BAND_2GHZ];
+-	else
+-		cap_band = &pdev_cap->band[NL80211_BAND_5GHZ];
+-
+-	hecap_phy_ptr = &cap_band->he_cap_phy_info[0];
+-
+-	hemode = u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE) |
+-		 u32_encode_bits(HECAP_PHY_SUBFMR_GET(hecap_phy_ptr),
+-				 HE_MODE_SU_TX_BFER) |
+-		 u32_encode_bits(HECAP_PHY_ULMUMIMO_GET(hecap_phy_ptr),
+-				 HE_MODE_UL_MUMIMO);
+-
+-	/* TODO: WDS and other modes */
+-	if (viftype == NL80211_IFTYPE_AP) {
+-		hemode |= u32_encode_bits(HECAP_PHY_MUBFMR_GET(hecap_phy_ptr),
+-					  HE_MODE_MU_TX_BFER) |
+-			  u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) |
+-			  u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA);
+-	} else {
+-		hemode |= u32_encode_bits(HE_MU_BFEE_ENABLE, HE_MODE_MU_TX_BFEE);
+-	}
+-
+-	return hemode;
+-}
+-
+-static int ath12k_set_he_mu_sounding_mode(struct ath12k *ar,
+-					  struct ath12k_vif *arvif)
+-{
+-	u32 param_id, param_value;
+-	struct ath12k_base *ab = ar->ab;
+-	int ret;
+-
+-	param_id = WMI_VDEV_PARAM_SET_HEMU_MODE;
+-	param_value = ath12k_mac_prepare_he_mode(ar->pdev, arvif->vif->type);
+-	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+-					    param_id, param_value);
+-	if (ret) {
+-		ath12k_warn(ab, "failed to set vdev %d HE MU mode: %d param_value %x\n",
+-			    arvif->vdev_id, ret, param_value);
+-		return ret;
+-	}
+-	param_id = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE;
+-	param_value =
+-		u32_encode_bits(HE_VHT_SOUNDING_MODE_ENABLE, HE_VHT_SOUNDING_MODE) |
+-		u32_encode_bits(HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE,
+-				HE_TRIG_NONTRIG_SOUNDING_MODE);
+-	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+-					    param_id, param_value);
+-	if (ret) {
+-		ath12k_warn(ab, "failed to set vdev %d HE MU mode: %d\n",
+-			    arvif->vdev_id, ret);
+-		return ret;
+-	}
+-	return ret;
+-}
+-
+ static void ath12k_mac_update_vif_offload(struct ath12k_vif *arvif)
+ {
+ 	struct ieee80211_vif *vif = arvif->vif;
+@@ -7339,7 +7409,6 @@ ath12k_mac_vdev_start_restart(struct ath
+ 	struct ath12k_base *ab = ar->ab;
+ 	struct wmi_vdev_start_req_arg arg = {};
+ 	const struct cfg80211_chan_def *chandef = &ctx->def;
+-	int he_support = arvif->vif->bss_conf.he_support;
+ 	int ret;
+ 
+ 	lockdep_assert_held(&ar->conf_mutex);
+@@ -7395,14 +7464,6 @@ ath12k_mac_vdev_start_restart(struct ath
+ 		spin_unlock_bh(&ab->base_lock);
+ 
+ 		/* TODO: Notify if secondary 80Mhz also needs radar detection */
+-		if (he_support) {
+-			ret = ath12k_set_he_mu_sounding_mode(ar, arvif);
+-			if (ret) {
+-				ath12k_warn(ar->ab, "failed to set he mode vdev %i\n",
+-					    arg.vdev_id);
+-				return ret;
+-			}
+-		}
+ 	}
+ 
+ 	arg.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR);
+--- a/drivers/net/wireless/ath/ath12k/mac.h
++++ b/drivers/net/wireless/ath/ath12k/mac.h
+@@ -41,6 +41,21 @@ struct ath12k_generic_iter {
+ #define ATH12K_TX_POWER_MAX_VAL	70
+ #define ATH12K_TX_POWER_MIN_VAL	0
+ 
++#define HECAP_PHY_SUBFMR_GET(hecap_phy) \
++	u8_get_bits(hecap_phy[3], IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER)
++
++#define HECAP_PHY_SUBFME_GET(hecap_phy) \
++	u8_get_bits(hecap_phy[4], IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE)
++
++#define HECAP_PHY_MUBFMR_GET(hecap_phy) \
++	u8_get_bits(hecap_phy[4], IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)
++
++#define HECAP_PHY_ULMUMIMO_GET(hecap_phy) \
++	u8_get_bits(hecap_phy[2], IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO)
++
++#define HECAP_PHY_ULOFDMA_GET(hecap_phy) \
++	u8_get_bits(hecap_phy[2], IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO)
++
+ enum ath12k_supported_bw {
+ 	ATH12K_BW_20    = 0,
+ 	ATH12K_BW_40    = 1,
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -2995,31 +2995,6 @@ struct ath12k_wmi_rx_reorder_queue_remov
+ #define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2)
+ #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3)
+ 
+-#define HECAP_PHYDWORD_0	0
+-#define HECAP_PHYDWORD_1	1
+-#define HECAP_PHYDWORD_2	2
+-
+-#define HECAP_PHY_SU_BFER		BIT(31)
+-#define HECAP_PHY_SU_BFEE		BIT(0)
+-#define HECAP_PHY_MU_BFER		BIT(1)
+-#define HECAP_PHY_UL_MUMIMO		BIT(22)
+-#define HECAP_PHY_UL_MUOFDMA		BIT(23)
+-
+-#define HECAP_PHY_SUBFMR_GET(hecap_phy) \
+-	u32_get_bits(hecap_phy[HECAP_PHYDWORD_0], HECAP_PHY_SU_BFER)
+-
+-#define HECAP_PHY_SUBFME_GET(hecap_phy) \
+-	u32_get_bits(hecap_phy[HECAP_PHYDWORD_1], HECAP_PHY_SU_BFEE)
+-
+-#define HECAP_PHY_MUBFMR_GET(hecap_phy) \
+-	u32_get_bits(hecap_phy[HECAP_PHYDWORD_1], HECAP_PHY_MU_BFER)
+-
+-#define HECAP_PHY_ULMUMIMO_GET(hecap_phy) \
+-	u32_get_bits(hecap_phy[HECAP_PHYDWORD_0], HECAP_PHY_UL_MUMIMO)
+-
+-#define HECAP_PHY_ULOFDMA_GET(hecap_phy) \
+-	u32_get_bits(hecap_phy[HECAP_PHYDWORD_0], HECAP_PHY_UL_MUOFDMA)
+-
+ #define HE_MODE_SU_TX_BFEE	BIT(0)
+ #define HE_MODE_SU_TX_BFER	BIT(1)
+ #define HE_MODE_MU_TX_BFEE	BIT(2)
+@@ -3031,8 +3006,11 @@ struct ath12k_wmi_rx_reorder_queue_remov
+ #define HE_DL_MUOFDMA_ENABLE	1
+ #define HE_UL_MUOFDMA_ENABLE	1
+ #define HE_DL_MUMIMO_ENABLE	1
++#define HE_UL_MUMIMO_ENABLE	1
+ #define HE_MU_BFEE_ENABLE	1
+ #define HE_SU_BFEE_ENABLE	1
++#define HE_MU_BFER_ENABLE	1
++#define HE_SU_BFER_ENABLE	1
+ 
+ #define HE_VHT_SOUNDING_MODE_ENABLE		1
+ #define HE_SU_MU_SOUNDING_MODE_ENABLE		1
diff --git a/package/kernel/mac80211/patches/ath12k/104-2-wifi-ath12k-push-EHT-MU-MIMO-params-to-hardware.patch b/package/kernel/mac80211/patches/ath12k/104-2-wifi-ath12k-push-EHT-MU-MIMO-params-to-hardware.patch
new file mode 100644
index 0000000000..65ef65fa7f
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-2-wifi-ath12k-push-EHT-MU-MIMO-params-to-hardware.patch
@@ -0,0 +1,222 @@
+From patchwork Wed Sep 18 21:20:49 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807210
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com
+ [205.220.168.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id B81C317967F
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:12 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.168.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694474; cv=none;
+ b=SYN3tI9xaTiXuxK7CUAD6gXBOqoyS1qZxAGNOXDt4yS1Q6oU0YiwQonIkVrnux7/DC3bCm2JScN5vIxVzkGOkFztaIHlZMM/TRsp6GzSIbZdasVpxySumoe965kRna+5fYAmf4i3wJupfj9p6509u7j6kXzz1ZxlSStR4wLObcE=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694474; c=relaxed/simple;
+	bh=yQPaApb7knqLxhkxSrizMfAanw18TDUbxBPbfnhzlV0=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=W+Rk8/tiKUvP6A8WYQFxi97//4Yj4m/rYPXAg0YP+6K+GXDcFK2VD+yEzmymA/fsenli+7ZEJ1zH6XgzLe4+1QFctCYGnq1LPoD01a4AIF8VqJGVdgs6e1ZwCKv8AOLkZUb09QkmM8Ur4R1xFhc4oVqhlvm3NMc24NERWmxzGjI=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=XJxqlj7h; arc=none smtp.client-ip=205.220.168.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="XJxqlj7h"
+Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48IHKWuA006417;
+	Wed, 18 Sep 2024 21:21:08 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	hcoreX5pgczyblwh1gpL6Ax4OV0yrVpAaKX7psGXczI=; b=XJxqlj7hhoW4GYMB
+	+B9r7ajbqV+ZxP+/1uDt5veOBY8aQgsorBoEbZFKm+ccV0u5SQJ/fFSomLg8QYpE
+	iojXUyYsGJMsXSPW+OdC0DQ2JrhDEHWFQa/6c3C0sdBE5IGgTa8YiAmYAx/A1ti1
+	ruMNSyT8H/xEKkR953axz1DOGJZfp9dCtOM5Xw6nrqpeUEYBShgvQ+1LLXqrH8U4
+	qUlYW2vKFKJgZUe97nwRrwOiunhTD4M2ARe6xHqZ7bL+2bW27sRTSI69vGrcEdKM
+	Ied7A8KmlUAN5BBsOj5MeKAaoy0+h4iY/9W3JgDfOu+LwjuAaKzgPNrttmPehdhJ
+	Q8q0JQ==
+Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4kjk65k-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:07 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL7IZ032342
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:07 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:06 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Muna Sinada <quic_msinada at quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 2/9] wifi: ath12k: push EHT MU-MIMO params to hardware
+Date: Wed, 18 Sep 2024 14:20:49 -0700
+Message-ID: <20240918212056.4137076-3-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-GUID: DiIEaDHD4453WG2b31qitb3_i0JkAM4u
+X-Proofpoint-ORIG-GUID: DiIEaDHD4453WG2b31qitb3_i0JkAM4u
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ bulkscore=0 adultscore=0
+ suspectscore=0 mlxscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0
+ phishscore=0 impostorscore=0 mlxlogscore=999 priorityscore=1501
+ spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
+ engine=8.19.0-2408220000 definitions=main-2409180140
+
+Currently, only the EHT IE in management frames is updated with
+respect to MU-MIMO configurations, but this change is not
+reflected in the hardware. Add support to propagate MU-MIMO
+configurations to the hardware as well for AP mode. Similar
+support for STA mode will be added in future.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Co-developed-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 50 +++++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath12k/wmi.h | 21 +++++++++++
+ 2 files changed, 71 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -2953,6 +2953,50 @@ static int ath12k_mac_vif_recalc_sta_he_
+ 	return 0;
+ }
+ 
++static int ath12k_mac_set_eht_txbf_conf(struct ath12k_vif *arvif)
++{
++	u32 param = WMI_VDEV_PARAM_SET_EHT_MU_MODE;
++	struct ath12k *ar = arvif->ar;
++	u32 value = 0;
++	int ret;
++
++	if (!arvif->vif->bss_conf.eht_support)
++		return 0;
++
++	if (arvif->vif->bss_conf.eht_su_beamformer) {
++		value |= u32_encode_bits(EHT_SU_BFER_ENABLE, EHT_MODE_SU_TX_BFER);
++		if (arvif->vif->bss_conf.eht_mu_beamformer &&
++		    arvif->vdev_type == WMI_VDEV_TYPE_AP)
++			value |= u32_encode_bits(EHT_MU_BFER_ENABLE,
++						 EHT_MODE_MU_TX_BFER) |
++				 u32_encode_bits(EHT_DL_MUOFDMA_ENABLE,
++						 EHT_MODE_DL_OFDMA_MUMIMO) |
++				 u32_encode_bits(EHT_UL_MUOFDMA_ENABLE,
++						 EHT_MODE_UL_OFDMA_MUMIMO);
++	}
++
++	if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) {
++		value |= u32_encode_bits(EHT_DL_MUOFDMA_ENABLE, EHT_MODE_DL_OFDMA) |
++			 u32_encode_bits(EHT_UL_MUOFDMA_ENABLE, EHT_MODE_UL_OFDMA);
++
++		if (arvif->vif->bss_conf.eht_80mhz_full_bw_ul_mumimo)
++			value |= u32_encode_bits(EHT_UL_MUMIMO_ENABLE, EHT_MODE_MUMIMO);
++
++		if (arvif->vif->bss_conf.eht_su_beamformee)
++			value |= u32_encode_bits(EHT_SU_BFEE_ENABLE,
++						 EHT_MODE_SU_TX_BFEE);
++	}
++
++	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value);
++	if (ret) {
++		ath12k_warn(ar->ab, "failed to set vdev %d EHT MU mode: %d\n",
++			    arvif->vdev_id, ret);
++		return ret;
++	}
++
++	return 0;
++}
++
+ static void ath12k_bss_assoc(struct ath12k *ar,
+ 			     struct ath12k_vif *arvif,
+ 			     struct ieee80211_bss_conf *bss_conf)
+@@ -3351,6 +3395,12 @@ static void ath12k_mac_bss_info_changed(
+ 				ath12k_warn(ar->ab,
+ 					    "failed to set HE TXBF config for vdev: %d\n",
+ 					    arvif->vdev_id);
++
++			ret = ath12k_mac_set_eht_txbf_conf(arvif);
++			if (ret)
++				ath12k_warn(ar->ab,
++					    "failed to set EHT TXBF config for vdev: %d\n",
++					    arvif->vdev_id);
+ 		}
+ 		ath12k_control_beaconing(arvif, info);
+ 
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -1139,6 +1139,7 @@ enum wmi_tlv_vdev_param {
+ 	WMI_VDEV_PARAM_BSS_COLOR,
+ 	WMI_VDEV_PARAM_SET_HEMU_MODE,
+ 	WMI_VDEV_PARAM_HEOPS_0_31 = 0x8003,
++	WMI_VDEV_PARAM_SET_EHT_MU_MODE = 0x8005,
+ };
+ 
+ enum wmi_tlv_peer_flags {
+@@ -3012,6 +3013,26 @@ struct ath12k_wmi_rx_reorder_queue_remov
+ #define HE_MU_BFER_ENABLE	1
+ #define HE_SU_BFER_ENABLE	1
+ 
++#define EHT_MODE_SU_TX_BFEE		BIT(0)
++#define EHT_MODE_SU_TX_BFER		BIT(1)
++#define EHT_MODE_MU_TX_BFEE		BIT(2)
++#define EHT_MODE_MU_TX_BFER		BIT(3)
++#define EHT_MODE_DL_OFDMA		BIT(4)
++#define EHT_MODE_UL_OFDMA		BIT(5)
++#define EHT_MODE_MUMIMO			BIT(6)
++#define EHT_MODE_DL_OFDMA_TXBF		BIT(7)
++#define EHT_MODE_DL_OFDMA_MUMIMO	BIT(8)
++#define EHT_MODE_UL_OFDMA_MUMIMO	BIT(9)
++
++#define EHT_DL_MUOFDMA_ENABLE    1
++#define EHT_UL_MUOFDMA_ENABLE    1
++#define EHT_DL_MUMIMO_ENABLE     1
++#define EHT_UL_MUMIMO_ENABLE     1
++#define EHT_MU_BFEE_ENABLE       1
++#define EHT_SU_BFEE_ENABLE       1
++#define EHT_MU_BFER_ENABLE       1
++#define EHT_SU_BFER_ENABLE       1
++
+ #define HE_VHT_SOUNDING_MODE_ENABLE		1
+ #define HE_SU_MU_SOUNDING_MODE_ENABLE		1
+ #define HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE	1
diff --git a/package/kernel/mac80211/patches/ath12k/104-3-wifi-ath12k-move-HE-MCS-mapper-to-a-separate-function.patch b/package/kernel/mac80211/patches/ath12k/104-3-wifi-ath12k-move-HE-MCS-mapper-to-a-separate-function.patch
new file mode 100644
index 0000000000..bc2710a57d
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-3-wifi-ath12k-move-HE-MCS-mapper-to-a-separate-function.patch
@@ -0,0 +1,162 @@
+From patchwork Wed Sep 18 21:20:50 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807213
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com
+ [205.220.180.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B2B11CB312
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:14 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.180.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694475; cv=none;
+ b=uo8JC/iAnxSCZyXzNFarViwWJNwY+JldG9aDgn6LOK7yCxMusODCN3rw4mSCs0sLxHrfxFouDKWpiKeM7hGb/fzQzU2eh6bHNvzhjOqaTjAsJo7sVGj4L2QK1UPb2ZxMke35L51ztNTVhAc7IS17sn6blDZnU+1+RGRKXskHc78=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694475; c=relaxed/simple;
+	bh=nhEu2OadboIpWVwShgMmYabjiVuEo2mUKJhJlcUzvgI=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=iPc43CIgA4O9RfgxO3cfBBvDShW3nh4Q/MVoL1JTtx8u/9t1CeFY7KstjtKiPdJ6vxx0yhZwXcwCRFfbZdfRduyybDRKPmgqN/VogzkwizBSFWBL41H02pCvee2mV3poTyZz9CnCJ5L7An5k7ARI3Eo6EwsgaAYIncO/tU2Jsao=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=iXyzdRBT; arc=none smtp.client-ip=205.220.180.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="iXyzdRBT"
+Received: from pps.filterd (m0279869.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48I90GrT001584;
+	Wed, 18 Sep 2024 21:21:09 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	aj0umwCwR0cGrc/Vc7qz7QRYcnU4amMo6KwLL9RZRaA=; b=iXyzdRBTMie5qv2n
+	KocnG3cRtZjxDUMbNTj+in3o4zrIU5RFumLb3ZmgpbCZD9jcmxkc9fcTdtwxUz8e
+	LTodO1mKSkqtOufy45keXIYYJN3lxfFsZtA5bcmG+QCJZJmPaTpMaf9L9Us9e+JZ
+	Ngjh4JNR3UIXn5+UvNGrRNEWeAlCrwf9Z5bWl1mQmwmkVVuH3nMu1IyPidF3tzRk
+	AdQTPkPtpnoGlYwEWL/noPAYTf4OuZrqPCAj31iBfZvq2RjAdWtPx/ayYEQsNKCu
+	xoBLKjb8hppxfGqn06TpV73nTxvhEDwnwBTwfgrr+xVeKvwz6Mrh8aoYBdUeFUAh
+	OiuxDA==
+Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4hf38cn-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:08 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL7e8005093
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:07 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:07 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Muna Sinada <quic_msinada at quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 3/9] wifi: ath12k: move HE MCS mapper to a separate
+ function
+Date: Wed, 18 Sep 2024 14:20:50 -0700
+Message-ID: <20240918212056.4137076-4-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-ORIG-GUID: zHmCiFNBcWNOH7v_I9cuj0l6gmfKvBVa
+X-Proofpoint-GUID: zHmCiFNBcWNOH7v_I9cuj0l6gmfKvBVa
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ priorityscore=1501 mlxscore=0
+ suspectscore=0 bulkscore=0 lowpriorityscore=0 spamscore=0 clxscore=1015
+ mlxlogscore=999 adultscore=0 malwarescore=0 phishscore=0 impostorscore=0
+ classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000
+ definitions=main-2409180140
+
+Refactor the HE MCS mapper functionality in
+ath12k_mac_copy_he_cap() into a new function.
+
+This helps improve readability, extensibility and will be used
+when adding support for 160 MHz bandwidth in subsequent patches.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Co-developed-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -5518,12 +5518,24 @@ static __le16 ath12k_mac_setup_he_6ghz_c
+ 	return cpu_to_le16(bcap->he_6ghz_capa);
+ }
+ 
++static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap,
++				    struct ieee80211_sta_he_cap *he_cap)
++{
++	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
++
++	mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
++	mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
++	mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
++	mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
++	mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
++	mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
++}
++
+ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
+ 				   int iftype, u8 num_tx_chains,
+ 				   struct ieee80211_sta_he_cap *he_cap)
+ {
+ 	struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem;
+-	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
+ 
+ 	he_cap->has_he = true;
+ 	memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info,
+@@ -5561,13 +5573,7 @@ static void ath12k_mac_copy_he_cap(struc
+ 		break;
+ 	}
+ 
+-	mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
+-	mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
+-	mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-	mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-	mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-	mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-
++	ath12k_mac_set_hemcsmap(band_cap, he_cap);
+ 	memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
+ 	if (he_cap_elem->phy_cap_info[6] &
+ 	    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
diff --git a/package/kernel/mac80211/patches/ath12k/104-4-wifi-ath12k-generate-rx-and-tx-mcs-maps-for-supported-HE-mcs.patch b/package/kernel/mac80211/patches/ath12k/104-4-wifi-ath12k-generate-rx-and-tx-mcs-maps-for-supported-HE-mcs.patch
new file mode 100644
index 0000000000..3577889612
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-4-wifi-ath12k-generate-rx-and-tx-mcs-maps-for-supported-HE-mcs.patch
@@ -0,0 +1,186 @@
+From patchwork Wed Sep 18 21:20:51 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807215
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com
+ [205.220.180.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id A88651CB32C
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:14 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.180.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694476; cv=none;
+ b=Lkqx2oSLyeGRxKcm+N4Vmg+KOuwHpt6xhgWj9SpyWNXxxWkVExVyHvPrWaP/u4OXd0YjYBJC3Dg0NJYY9WJyL0A3RP8GK++s9CiRloNaEmEjI71S/f3+0HVXu5bCmi8cyiIMFzCpAcNuZ67J7r/WxvNRbeox3iZHmXK1WFUb4Hs=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694476; c=relaxed/simple;
+	bh=nv4kc89H7eGC0FLgCwC70zFDhNkClMNiRf5HjDZHHuQ=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=B1oJWv7vHZKRChjamOFJnRzQVtL7qBs7/Ho9GojLQtHyCKtrCEOJt/lWvhkqISf48/5MaQOCdkHhCrQT/eHP9hZ1wnCdeOKXh6Wmk/QYt9yEcc0X6HT5wUxgpaA3PooH/cMlJCX0c8hyhT7XBm6vWnPwQjt/FnLTubA3uj+X8oE=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=WweZPnje; arc=none smtp.client-ip=205.220.180.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="WweZPnje"
+Received: from pps.filterd (m0279872.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48IACJst031540;
+	Wed, 18 Sep 2024 21:21:09 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	ARu9Fu0s66NeuLm2pdCBchANS+rlgd275Q/E4KE2T1o=; b=WweZPnjehL/ZQW57
+	4JHJDsl8A5hyljMaJrVPdmZwNktTurJPMpD5z0akqx2dq3bfjzx2rx5NAtMb831x
+	ieysvT1ApK5V32fmb9xzG7FMIU3DH4eqr/9ApZbHFVPTglHrVoVzHJLps3I+Ts5P
+	gi1dsIAdwTai7hW1FchcW/pZ2kJMq6zN7oljoFs7pc1CvzHfIJowQM8gFfslkqlL
+	lvm9A9knvnUlkrEvzgpoZfZxm/91t9bQzkQDTX91wRc0oGR/9liT+z4Sdum2rLwb
+	fri8rhQIw8w1ExGM1nzChPaajmDIsE86ODjDL2xBbd/DcdsVvOYl8ewJ8AX45qNs
+	+LpHtg==
+Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4j6uagq-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:09 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL8gM005103
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:08 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:07 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Muna Sinada <quic_msinada at quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 4/9] wifi: ath12k: generate rx and tx mcs maps for
+ supported HE mcs
+Date: Wed, 18 Sep 2024 14:20:51 -0700
+Message-ID: <20240918212056.4137076-5-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-ORIG-GUID: wHJ63GZpWGKZ4XSyQZiVlsARNAgr5CQM
+X-Proofpoint-GUID: wHJ63GZpWGKZ4XSyQZiVlsARNAgr5CQM
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ phishscore=0 mlxlogscore=999
+ mlxscore=0 malwarescore=0 bulkscore=0 priorityscore=1501 clxscore=1015
+ adultscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 impostorscore=0
+ classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000
+ definitions=main-2409180140
+
+Generate rx and tx mcs maps in ath12k_mac_set_hemcsmap() based
+on number of supported tx/rx chains and set them in supported
+mcs/nss for HE capabilities.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Co-developed-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 40 ++++++++++++++++++++-------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -5518,20 +5518,40 @@ static __le16 ath12k_mac_setup_he_6ghz_c
+ 	return cpu_to_le16(bcap->he_6ghz_capa);
+ }
+ 
+-static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap,
++static void ath12k_mac_set_hemcsmap(struct ath12k *ar,
++				    struct ath12k_pdev_cap *cap,
+ 				    struct ieee80211_sta_he_cap *he_cap)
+ {
+ 	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
++	u16 txmcs_map, rxmcs_map;
++	u32 i;
+ 
+-	mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
+-	mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
+-	mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-	mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-	mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+-	mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
++	rxmcs_map = 0;
++	txmcs_map = 0;
++	for (i = 0; i < 8; i++) {
++		if (i < ar->num_tx_chains &&
++		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
++			txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
++		else
++			txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
++
++		if (i < ar->num_rx_chains &&
++		    (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
++			rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
++		else
++			rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
++	}
++
++	mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff);
++	mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff);
++	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff);
++	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff);
++	mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff);
++	mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff);
+ }
+ 
+-static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
++static void ath12k_mac_copy_he_cap(struct ath12k *ar,
++				   struct ath12k_band_cap *band_cap,
+ 				   int iftype, u8 num_tx_chains,
+ 				   struct ieee80211_sta_he_cap *he_cap)
+ {
+@@ -5573,7 +5593,7 @@ static void ath12k_mac_copy_he_cap(struc
+ 		break;
+ 	}
+ 
+-	ath12k_mac_set_hemcsmap(band_cap, he_cap);
++	ath12k_mac_set_hemcsmap(ar, &ar->pdev->cap, he_cap);
+ 	memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
+ 	if (he_cap_elem->phy_cap_info[6] &
+ 	    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
+@@ -5762,7 +5782,7 @@ static int ath12k_mac_copy_sband_iftype_
+ 
+ 		data[idx].types_mask = BIT(i);
+ 
+-		ath12k_mac_copy_he_cap(band_cap, i, ar->num_tx_chains, he_cap);
++		ath12k_mac_copy_he_cap(ar, band_cap, i, ar->num_tx_chains, he_cap);
+ 		if (band == NL80211_BAND_6GHZ) {
+ 			data[idx].he_6ghz_capa.capa =
+ 				ath12k_mac_setup_he_6ghz_cap(cap, band_cap);
diff --git a/package/kernel/mac80211/patches/ath12k/104-5-wifi-ath12k-fix-TX-and-RX-MCS-rate-configurations-in-HE-mode.patch b/package/kernel/mac80211/patches/ath12k/104-5-wifi-ath12k-fix-TX-and-RX-MCS-rate-configurations-in-HE-mode.patch
new file mode 100644
index 0000000000..e1d109cd56
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-5-wifi-ath12k-fix-TX-and-RX-MCS-rate-configurations-in-HE-mode.patch
@@ -0,0 +1,141 @@
+From patchwork Wed Sep 18 21:20:52 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807211
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com
+ [205.220.168.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77FB41CA6AC
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:13 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.168.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694475; cv=none;
+ b=RN/ddoo5Vh8RVGeYZ8k8lXTOb7bzs7wSIAQGFjyvpfc9NICOpTDXpM3ai/D/fFtXLR8mFmYa4uIMFdrWML1x/UjZtd+jJnNyL/jo4/t5+ONN0nU4brd/dW7fv/biqLA6CkFbjnw01XnInXLzGT8IIm4NvxBkMy/RVj0tC33y7os=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694475; c=relaxed/simple;
+	bh=bsvgv033jSAPUVmS0VlMcScTn/1aM6tw3aACOOiqxvA=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=rDT2TKhzEg9vR1RSVstUP/e9Z+sWhPbag7vxjm3nmkSJBFS5bR72jSO3YnpEGSQLOgd0c+ou8ce0GQOHHZBEpr8VlMP4o6SK8T3BVg4yPiHhqLzwadektVXzAofZ0K+caSvYUjsPvDd2wH1xDyUPHgvr/DjsPh8bhO1MP80pTYk=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=DbZeRJ9u; arc=none smtp.client-ip=205.220.168.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="DbZeRJ9u"
+Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48I9TNqc020283;
+	Wed, 18 Sep 2024 21:21:09 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	azR+5F3oXqRD0oIXJq+q0F3HbuiVUYwPuvX5vVskhnw=; b=DbZeRJ9uo40mL5rR
+	p0cASEsdLU8yr/aYeIXTSWCHBf5P73m5S26EYVv6MqTdcnmRT7flYyQWzotNV+gg
+	oHJpR7L5sN+omhK+7gDPRcm5j29/U9+7rMG7I0JwrfR6KbUUNJkrg+omW45ZdRPS
+	/92XJynSBDgzEGETs0AjLe+PLPW4Ucnncc+YscEVm/dtR4f5vQBYwGdCwv4IuczO
+	FJrEmDh3mj7m6JtNVV+A3LT5qS7PCAbiS7qhTAkDfhH9gDZJuUTO2b6ByyO4UkWp
+	afB41wIc4KUDYsTHkThkApxxp0vHfJJLGCweUi+YKYaqvQETgLhHx/UkSRdoRBII
+	N708pg==
+Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4kjk65m-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:09 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL8Gi009579
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:08 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:08 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Jeff Johnson <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 5/9] wifi: ath12k: fix TX and RX MCS rate configurations in
+ HE mode
+Date: Wed, 18 Sep 2024 14:20:52 -0700
+Message-ID: <20240918212056.4137076-6-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-GUID: JNJY4yItbZ8HP8WQjm82lNqNLkxUdf1v
+X-Proofpoint-ORIG-GUID: JNJY4yItbZ8HP8WQjm82lNqNLkxUdf1v
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ bulkscore=0 adultscore=0
+ suspectscore=0 mlxscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0
+ phishscore=0 impostorscore=0 mlxlogscore=999 priorityscore=1501
+ spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
+ engine=8.19.0-2408220000 definitions=main-2409180140
+
+Currently, the TX and RX MCS rate configurations per peer are
+reversed when sent to the firmware. As a result, RX MCS rates
+are configured for TX, and vice versa. This commit rectifies
+the configuration to match what the firmware expects.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/wmi.c | 4 ++--
+ drivers/net/wireless/ath/ath12k/wmi.h | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -2140,8 +2140,8 @@ int ath12k_wmi_send_peer_assoc_cmd(struc
+ 		he_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_HE_RATE_SET,
+ 							    sizeof(*he_mcs));
+ 
+-		he_mcs->rx_mcs_set = cpu_to_le32(arg->peer_he_rx_mcs_set[i]);
+-		he_mcs->tx_mcs_set = cpu_to_le32(arg->peer_he_tx_mcs_set[i]);
++		he_mcs->rx_mcs_set = cpu_to_le32(arg->peer_he_tx_mcs_set[i]);
++		he_mcs->tx_mcs_set = cpu_to_le32(arg->peer_he_rx_mcs_set[i]);
+ 		ptr += sizeof(*he_mcs);
+ 	}
+ 
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -3953,7 +3953,9 @@ struct ath12k_wmi_vht_rate_set_params {
+ 
+ struct ath12k_wmi_he_rate_set_params {
+ 	__le32 tlv_header;
++	/* MCS at which the peer can receive */
+ 	__le32 rx_mcs_set;
++	/* MCS at which the peer can transmit */
+ 	__le32 tx_mcs_set;
+ } __packed;
+ 
diff --git a/package/kernel/mac80211/patches/ath12k/104-6-wifi-ath12k-add-support-for-setting-fixed-HE-rate-GI-LTF.patch b/package/kernel/mac80211/patches/ath12k/104-6-wifi-ath12k-add-support-for-setting-fixed-HE-rate-GI-LTF.patch
new file mode 100644
index 0000000000..d44e92751c
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-6-wifi-ath12k-add-support-for-setting-fixed-HE-rate-GI-LTF.patch
@@ -0,0 +1,1095 @@
+From patchwork Wed Sep 18 21:20:53 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807217
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com
+ [205.220.168.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01CB41CB521
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:15 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.168.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694478; cv=none;
+ b=CCnmzPX7wAnXz6jkBGnfJkO3OTVTa1pEVXaY+i3jcRKLwLmYLBkbQB7d5qZASnEWRw4vJRXQbpKaSNlechv1fw+VqQci5hz7GrwDmSDWwFwNKynwUkaS+V6CUoPkxGmvijlkSH5/Sp7n4JBdH9MZdY9ACaPCGZlgpTeAiRpgqyQ=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694478; c=relaxed/simple;
+	bh=mOCMplbDFdsxafoM0lh9GOTg8poXfVWSA2JaaPzd5gg=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=m9Y3ZEQjhVcT6ObjX34KItzxLUdCbzQDCo4za4qtMsxHQCEQSny2a/lTtWTbAB42n+JZkBRjC1xrrdmRnXSxy58EZpvKNutjY0YonbJ/hMfa97U5qRTD/50prvNqxkFINPijMCNMgKsnCBz6tfcB78j3qnEvZjNP4eV4rbTicUg=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=lKsSrYSp; arc=none smtp.client-ip=205.220.168.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="lKsSrYSp"
+Received: from pps.filterd (m0279864.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48IINFa1032091;
+	Wed, 18 Sep 2024 21:21:09 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	97aZlelAxnf1oZWK/vk3qg6OISdr4sArbqi18OQE/2Y=; b=lKsSrYSpewbykrq1
+	6WJRbLR0y481zo+GgIgfHUNcpF2NhItbbS8mgWYFPaMaoohciRsbAYdFFZrc9BG3
+	9IyAzZvpFzBox/oaJjDm/zLc2GVYMSGtwO3W0mMk2uVXU7ZB8dBDNimtsLmXTa1t
+	jyV6n0wj3jlGU1kDYu6zPgrcxWF1NnScnosftToVpHqM7TLfDaj8EJWuzsJnau2A
+	CUOS2o9wPZPAScyeL91kJOHtJddltuJrvLFxbi4gGZW7dWUus99UjFzGTAan/JVK
+	yb5Xr8iEzP2141KqZ9FMQqwqYOGc10t+yYXPMep/fo1mfziiB5kQ0tRtaWQ01Auw
+	uPa6OQ==
+Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4geb5e1-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:09 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL8jN020567
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:08 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:08 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Muna Sinada <quic_msinada at quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 6/9] wifi: ath12k: add support for setting fixed HE
+ rate/GI/LTF
+Date: Wed, 18 Sep 2024 14:20:53 -0700
+Message-ID: <20240918212056.4137076-7-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-GUID: GGIeqOgMFye5oFp39WDjK5DZ7YoCK3Ap
+X-Proofpoint-ORIG-GUID: GGIeqOgMFye5oFp39WDjK5DZ7YoCK3Ap
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ malwarescore=0
+ mlxlogscore=999 impostorscore=0 bulkscore=0 clxscore=1015
+ lowpriorityscore=0 adultscore=0 phishscore=0 suspectscore=0
+ priorityscore=1501 mlxscore=0 spamscore=0 classifier=spam adjust=0
+ reason=mlx scancount=1 engine=8.19.0-2408220000
+ definitions=main-2409180140
+
+Add support to set fixed HE rate/GI/LTF values using nl80211.
+Reuse parts of the existing code path already used for HT/VHT
+to implement the new helpers symmetrically, similar to how
+HT/VHT is handled.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Co-developed-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada at quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 604 ++++++++++++++++++++++++--
+ drivers/net/wireless/ath/ath12k/wmi.h |  18 +
+ 2 files changed, 574 insertions(+), 48 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -441,6 +441,18 @@ ath12k_mac_max_vht_nss(const u16 *vht_mc
+ 	return 1;
+ }
+ 
++static u32
++ath12k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
++{
++	int nss;
++
++	for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--)
++		if (he_mcs_mask[nss])
++			return nss + 1;
++
++	return 1;
++}
++
+ static u8 ath12k_parse_mpdudensity(u8 mpdudensity)
+ {
+ /*  From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing":
+@@ -1916,6 +1928,14 @@ static void ath12k_peer_assoc_h_ht(struc
+ 		arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG;
+ 	}
+ 
++	/* As firmware handles these two flags (IEEE80211_HT_CAP_SGI_20
++	 * and IEEE80211_HT_CAP_SGI_40) for enabling SGI, reset both
++	 * flags if guard interval is Default GI
++	 */
++	if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI)
++		arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 |
++				IEEE80211_HT_CAP_SGI_40);
++
+ 	if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
+ 		if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 |
+ 		    IEEE80211_HT_CAP_SGI_40))
+@@ -2039,11 +2059,12 @@ static void ath12k_peer_assoc_h_vht(stru
+ 	struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
+ 	struct cfg80211_chan_def def;
+ 	enum nl80211_band band;
+-	const u16 *vht_mcs_mask;
++	u16 *vht_mcs_mask;
+ 	u16 tx_mcs_map;
+ 	u8 ampdu_factor;
+ 	u8 max_nss, vht_mcs;
+-	int i;
++	int i, vht_nss, nss_idx;
++	bool user_rate_valid = true;
+ 
+ 	if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
+ 		return;
+@@ -2086,6 +2107,25 @@ static void ath12k_peer_assoc_h_vht(stru
+ 	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)
+ 		arg->bw_160 = true;
+ 
++	vht_nss =  ath12k_mac_max_vht_nss(vht_mcs_mask);
++
++	if (vht_nss > sta->deflink.rx_nss) {
++		user_rate_valid = false;
++		for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) {
++			if (vht_mcs_mask[nss_idx]) {
++				user_rate_valid = true;
++				break;
++			}
++		}
++	}
++
++	if (!user_rate_valid) {
++		ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++			   "Setting vht range MCS value to peer supported nss:%d for peer %pM\n",
++			   sta->deflink.rx_nss, sta->deflink.addr);
++		vht_mcs_mask[sta->deflink.rx_nss - 1] = vht_mcs_mask[vht_nss - 1];
++	}
++
+ 	/* Calculate peer NSS capability from VHT capabilities if STA
+ 	 * supports VHT.
+ 	 */
+@@ -2125,23 +2165,105 @@ static void ath12k_peer_assoc_h_vht(stru
+ 	/* TODO: rxnss_override */
+ }
+ 
++static int ath12k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)
++{
++	switch ((mcs_map >> (2 * nss)) & 0x3) {
++	case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1;
++	case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1;
++	case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1;
++	}
++	return 0;
++}
++
++static u16 ath12k_peer_assoc_h_he_limit(u16 tx_mcs_set,
++					const u16 *he_mcs_limit)
++{
++	int idx_limit;
++	int nss;
++	u16 mcs_map;
++	u16 mcs;
++
++	for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
++		mcs_map = ath12k_mac_get_max_he_mcs_map(tx_mcs_set, nss) &
++			he_mcs_limit[nss];
++
++		if (mcs_map)
++			idx_limit = fls(mcs_map) - 1;
++		else
++			idx_limit = -1;
++
++		switch (idx_limit) {
++		case 0 ... 7:
++			mcs = IEEE80211_HE_MCS_SUPPORT_0_7;
++			break;
++		case 8:
++		case 9:
++			mcs = IEEE80211_HE_MCS_SUPPORT_0_9;
++			break;
++		case 10:
++		case 11:
++			mcs = IEEE80211_HE_MCS_SUPPORT_0_11;
++			break;
++		default:
++			WARN_ON(1);
++			fallthrough;
++		case -1:
++			mcs = IEEE80211_HE_MCS_NOT_SUPPORTED;
++			break;
++		}
++
++		tx_mcs_set &= ~(0x3 << (nss * 2));
++		tx_mcs_set |= mcs << (nss * 2);
++	}
++
++	return tx_mcs_set;
++}
++
++static bool
++ath12k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
++{
++	int nss;
++
++	for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++)
++		if (he_mcs_mask[nss])
++			return false;
++
++	return true;
++}
++
+ static void ath12k_peer_assoc_h_he(struct ath12k *ar,
+ 				   struct ieee80211_vif *vif,
+ 				   struct ieee80211_sta *sta,
+ 				   struct ath12k_wmi_peer_assoc_arg *arg)
+ {
+ 	const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
++	struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
++	struct cfg80211_chan_def def;
+ 	int i;
+ 	u8 ampdu_factor, max_nss;
+ 	u8 rx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED;
+ 	u8 rx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED;
+ 	u16 mcs_160_map, mcs_80_map;
+ 	bool support_160;
+-	u16 v;
++	enum nl80211_band band;
++	u16 *he_mcs_mask;
++	u8 he_mcs;
++	u16 he_tx_mcs = 0, v = 0;
++	int he_nss, nss_idx;
++	bool user_rate_valid = true;
++
++	if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
++		return;
+ 
+ 	if (!he_cap->has_he)
+ 		return;
+ 
++	band = def.chan->band;
++	he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
++
++	if (ath12k_peer_assoc_h_he_masked(he_mcs_mask))
++		return;
++
+ 	arg->he_flag = true;
+ 
+ 	support_160 = !!(he_cap->he_cap_elem.phy_cap_info[0] &
+@@ -2247,25 +2369,47 @@ static void ath12k_peer_assoc_h_he(struc
+ 	if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ)
+ 		arg->twt_requester = true;
+ 
++	he_nss = ath12k_mac_max_he_nss(he_mcs_mask);
++
++	if (he_nss > sta->deflink.rx_nss) {
++		user_rate_valid = false;
++		for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) {
++			if (he_mcs_mask[nss_idx]) {
++				user_rate_valid = true;
++				break;
++			}
++		}
++	}
++
++	if (!user_rate_valid) {
++		ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++			   "Setting he range MCS value to peer supported nss:%d for peer %pM\n",
++			   sta->deflink.rx_nss, sta->deflink.addr);
++		he_mcs_mask[sta->deflink.rx_nss - 1] = he_mcs_mask[he_nss - 1];
++	}
++
+ 	switch (sta->deflink.bandwidth) {
+ 	case IEEE80211_STA_RX_BW_160:
+ 		if (he_cap->he_cap_elem.phy_cap_info[0] &
+ 		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
+-			v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80);
++			v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
+ 			arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
+ 
+ 			v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80);
+ 			arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
+ 
+ 			arg->peer_he_mcs_count++;
++			he_tx_mcs = v;
+ 		}
+ 		v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
+ 		arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
+ 
+-		v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160);
++		v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
+ 		arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
+ 
+ 		arg->peer_he_mcs_count++;
++		if (!he_tx_mcs)
++			he_tx_mcs = v;
+ 		fallthrough;
+ 
+ 	default:
+@@ -2273,11 +2417,34 @@ static void ath12k_peer_assoc_h_he(struc
+ 		arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
+ 
+ 		v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
++		v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
+ 		arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
+ 
+ 		arg->peer_he_mcs_count++;
++		if (!he_tx_mcs)
++			he_tx_mcs = v;
+ 		break;
+ 	}
++
++	/* Calculate peer NSS capability from HE capabilities if STA
++	 * supports HE.
++	 */
++	for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) {
++		he_mcs = he_tx_mcs >> (2 * i) & 3;
++
++		/* In case of fixed rates, MCS Range in he_tx_mcs might have
++		 * unsupported range, with he_mcs_mask set, so check either of them
++		 * to find nss.
++		 */
++		if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED ||
++		    he_mcs_mask[i])
++			max_nss = i + 1;
++	}
++	arg->peer_nss = min(sta->deflink.rx_nss, max_nss);
++
++	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++		   "mac he peer %pM nss %d mcs cnt %d\n",
++		   sta->deflink.addr, arg->peer_nss, arg->peer_he_mcs_count);
+ }
+ 
+ static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar,
+@@ -2586,6 +2753,7 @@ static void ath12k_peer_assoc_h_phymode(
+ 	enum nl80211_band band;
+ 	const u8 *ht_mcs_mask;
+ 	const u16 *vht_mcs_mask;
++	const u16 *he_mcs_mask;
+ 	enum wmi_phy_mode phymode = MODE_UNKNOWN;
+ 
+ 	if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
+@@ -2594,6 +2762,7 @@ static void ath12k_peer_assoc_h_phymode(
+ 	band = def.chan->band;
+ 	ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
+ 	vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
++	he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
+ 
+ 	switch (band) {
+ 	case NL80211_BAND_2GHZ:
+@@ -2602,7 +2771,8 @@ static void ath12k_peer_assoc_h_phymode(
+ 				phymode = MODE_11BE_EHT40_2G;
+ 			else
+ 				phymode = MODE_11BE_EHT20_2G;
+-		} else if (sta->deflink.he_cap.has_he) {
++		} else if (sta->deflink.he_cap.has_he &&
++			   !ath12k_peer_assoc_h_he_masked(he_mcs_mask)) {
+ 			if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
+ 				phymode = MODE_11AX_HE80_2G;
+ 			else if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)
+@@ -2632,7 +2802,8 @@ static void ath12k_peer_assoc_h_phymode(
+ 		/* Check EHT first */
+ 		if (sta->deflink.eht_cap.has_eht) {
+ 			phymode = ath12k_mac_get_phymode_eht(ar, sta);
+-		} else if (sta->deflink.he_cap.has_he) {
++		} else if (sta->deflink.he_cap.has_he &&
++			   !ath12k_peer_assoc_h_he_masked(he_mcs_mask)) {
+ 			phymode = ath12k_mac_get_phymode_he(ar, sta);
+ 		} else if (sta->deflink.vht_cap.vht_supported &&
+ 		    !ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
+@@ -4311,6 +4482,20 @@ ath12k_mac_bitrate_mask_num_vht_rates(st
+ }
+ 
+ static int
++ath12k_mac_bitrate_mask_num_he_rates(struct ath12k *ar,
++				     enum nl80211_band band,
++				     const struct cfg80211_bitrate_mask *mask)
++{
++	int num_rates = 0;
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++)
++		num_rates += hweight16(mask->control[band].he_mcs[i]);
++
++	return num_rates;
++}
++
++static int
+ ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_vif *arvif,
+ 				   struct ieee80211_sta *sta,
+ 				   const struct cfg80211_bitrate_mask *mask,
+@@ -4356,6 +4541,57 @@ ath12k_mac_set_peer_vht_fixed_rate(struc
+ 	return ret;
+ }
+ 
++static int
++ath12k_mac_set_peer_he_fixed_rate(struct ath12k_vif *arvif,
++				  struct ieee80211_sta *sta,
++				  const struct cfg80211_bitrate_mask *mask,
++				  enum nl80211_band band)
++{
++	struct ath12k *ar = arvif->ar;
++	u8 he_rate, nss;
++	u32 rate_code;
++	int ret, i;
++
++	lockdep_assert_held(&ar->conf_mutex);
++
++	nss = 0;
++
++	for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
++		if (hweight16(mask->control[band].he_mcs[i]) == 1) {
++			nss = i + 1;
++			he_rate = ffs(mask->control[band].he_mcs[i]) - 1;
++		}
++	}
++
++	if (!nss) {
++		ath12k_warn(ar->ab, "No single HE Fixed rate found to set for %pM",
++			    sta->deflink.addr);
++		return -EINVAL;
++	}
++
++	/* Avoid updating invalid nss as fixed rate*/
++	if (nss > sta->deflink.rx_nss)
++		return -EINVAL;
++
++	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++		   "Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates",
++		   sta->deflink.addr);
++
++	rate_code = ATH12K_HW_RATE_CODE(he_rate, nss - 1,
++					WMI_RATE_PREAMBLE_HE);
++
++	ret = ath12k_wmi_set_peer_param(ar, sta->deflink.addr,
++					arvif->vdev_id,
++					WMI_PEER_PARAM_FIXED_RATE,
++					rate_code);
++	if (ret)
++		ath12k_warn(ar->ab,
++			    "failed to update STA %pM Fixed Rate %d: %d\n",
++			    sta->deflink.addr, rate_code, ret);
++
++	return ret;
++}
++
+ static int ath12k_station_assoc(struct ath12k *ar,
+ 				struct ieee80211_vif *vif,
+ 				struct ieee80211_sta *sta,
+@@ -4367,7 +4603,7 @@ static int ath12k_station_assoc(struct a
+ 	struct cfg80211_chan_def def;
+ 	enum nl80211_band band;
+ 	struct cfg80211_bitrate_mask *mask;
+-	u8 num_vht_rates;
++	u8 num_vht_rates, num_he_rates;
+ 
+ 	lockdep_assert_held(&ar->conf_mutex);
+ 
+@@ -4398,15 +4634,19 @@ static int ath12k_station_assoc(struct a
+ 	}
+ 
+ 	num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask);
++	num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask);
+ 
+-	/* If single VHT rate is configured (by set_bitrate_mask()),
+-	 * peer_assoc will disable VHT. This is now enabled by a peer specific
++	/* If single VHT/HE rate is configured (by set_bitrate_mask()),
++	 * peer_assoc will disable VHT/HE. This is now enabled by a peer specific
+ 	 * fixed param.
+ 	 * Note that all other rates and NSS will be disabled for this peer.
+ 	 */
+ 	if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) {
+-		ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
+-							 band);
++		ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band);
++		if (ret)
++			return ret;
++	} else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {
++		ret = ath12k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band);
+ 		if (ret)
+ 			return ret;
+ 	}
+@@ -4480,8 +4720,9 @@ static void ath12k_sta_rc_update_wk(stru
+ 	enum nl80211_band band;
+ 	const u8 *ht_mcs_mask;
+ 	const u16 *vht_mcs_mask;
+-	u32 changed, bw, nss, smps, bw_prev;
+-	int err, num_vht_rates;
++	const u16 *he_mcs_mask;
++	u32 changed, bw, nss, mac_nss, smps, bw_prev;
++	int err, num_vht_rates, num_he_rates;
+ 	const struct cfg80211_bitrate_mask *mask;
+ 	struct ath12k_wmi_peer_assoc_arg peer_arg;
+ 	enum wmi_phy_mode peer_phymode;
+@@ -4497,6 +4738,7 @@ static void ath12k_sta_rc_update_wk(stru
+ 	band = def.chan->band;
+ 	ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
+ 	vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
++	he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
+ 
+ 	spin_lock_bh(&ar->data_lock);
+ 
+@@ -4513,8 +4755,10 @@ static void ath12k_sta_rc_update_wk(stru
+ 	mutex_lock(&ar->conf_mutex);
+ 
+ 	nss = max_t(u32, 1, nss);
+-	nss = min(nss, max(ath12k_mac_max_ht_nss(ht_mcs_mask),
+-			   ath12k_mac_max_vht_nss(vht_mcs_mask)));
++	mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask),
++		       ath12k_mac_max_vht_nss(vht_mcs_mask),
++		       ath12k_mac_max_he_nss(he_mcs_mask));
++	nss = min(nss, mac_nss);
+ 
+ 	if (changed & IEEE80211_RC_BW_CHANGED) {
+ 		ath12k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg);
+@@ -4592,6 +4836,8 @@ static void ath12k_sta_rc_update_wk(stru
+ 		mask = &arvif->bitrate_mask;
+ 		num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band,
+ 								      mask);
++		num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band,
++								    mask);
+ 
+ 		/* Peer_assoc_prepare will reject vht rates in
+ 		 * bitrate_mask if its not available in range format and
+@@ -4607,11 +4853,24 @@ static void ath12k_sta_rc_update_wk(stru
+ 		if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) {
+ 			ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
+ 							   band);
++		} else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {
++			ath12k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band);
+ 		} else {
+-			/* If the peer is non-VHT or no fixed VHT rate
++			/* If the peer is non-VHT/HE or no fixed VHT/HE rate
+ 			 * is provided in the new bitrate mask we set the
+-			 * other rates using peer_assoc command.
++			 * other rates using peer_assoc command. Also clear
++			 * the peer fixed rate settings as it has higher proprity
++			 * than peer assoc
+ 			 */
++
++			err = ath12k_wmi_set_peer_param(ar, sta->deflink.addr,
++							arvif->vdev_id,
++							WMI_PEER_PARAM_FIXED_RATE,
++							WMI_FIXED_RATE_NONE);
++			if (err)
++				ath12k_warn(ar->ab,
++					    "failed to disable peer fixed rate for STA %pM ret %d\n",
++					    sta->deflink.addr, err);
+ 			ath12k_peer_assoc_prepare(ar, arvif->vif, sta,
+ 						  &peer_arg, true);
+ 
+@@ -7058,10 +7317,13 @@ static int ath12k_mac_op_add_interface(s
+ 
+ 	for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
+ 		arvif->bitrate_mask.control[i].legacy = 0xffffffff;
++		arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_FORCE_SGI;
+ 		memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
+ 		       sizeof(arvif->bitrate_mask.control[i].ht_mcs));
+ 		memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
+ 		       sizeof(arvif->bitrate_mask.control[i].vht_mcs));
++		memset(arvif->bitrate_mask.control[i].he_mcs, 0xff,
++		       sizeof(arvif->bitrate_mask.control[i].he_mcs));
+ 	}
+ 
+ 	/* Allocate Default Queue now and reassign during actual vdev create */
+@@ -8222,19 +8484,40 @@ ath12k_mac_has_single_legacy_rate(struct
+ 	if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask))
+ 		return false;
+ 
++	if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask))
++		return false;
++
+ 	return num_rates == 1;
+ }
+ 
++static __le16
++ath12k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
++{
++	if (he_cap->he_cap_elem.phy_cap_info[0] &
++	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
++		return he_cap->he_mcs_nss_supp.tx_mcs_80p80;
++
++	if (he_cap->he_cap_elem.phy_cap_info[0] &
++	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
++		return he_cap->he_mcs_nss_supp.tx_mcs_160;
++
++	return he_cap->he_mcs_nss_supp.tx_mcs_80;
++}
++
+ static bool
+ ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar,
++				       struct ieee80211_vif *vif,
+ 				       enum nl80211_band band,
+ 				       const struct cfg80211_bitrate_mask *mask,
+ 				       int *nss)
+ {
+ 	struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
+ 	u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
++	const struct ieee80211_sta_he_cap *he_cap;
++	u16 he_mcs_map = 0;
+ 	u8 ht_nss_mask = 0;
+ 	u8 vht_nss_mask = 0;
++	u8 he_nss_mask = 0;
+ 	int i;
+ 
+ 	/* No need to consider legacy here. Basic rates are always present
+@@ -8261,7 +8544,24 @@ ath12k_mac_bitrate_mask_get_single_nss(s
+ 			return false;
+ 	}
+ 
+-	if (ht_nss_mask != vht_nss_mask)
++	he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);
++	if (!he_cap)
++		return false;
++
++	he_mcs_map = le16_to_cpu(ath12k_mac_get_tx_mcs_map(he_cap));
++
++	for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
++		if (mask->control[band].he_mcs[i] == 0)
++			continue;
++
++		if (mask->control[band].he_mcs[i] ==
++		    ath12k_mac_get_max_he_mcs_map(he_mcs_map, i))
++			he_nss_mask |= BIT(i);
++		else
++			return false;
++	}
++
++	if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask)
+ 		return false;
+ 
+ 	if (ht_nss_mask == 0)
+@@ -8308,54 +8608,158 @@ ath12k_mac_get_single_legacy_rate(struct
+ 	return 0;
+ }
+ 
+-static int ath12k_mac_set_fixed_rate_params(struct ath12k_vif *arvif,
+-					    u32 rate, u8 nss, u8 sgi, u8 ldpc)
++static int
++ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_vif *arvif, u8 he_gi, u8 he_ltf)
+ {
+ 	struct ath12k *ar = arvif->ar;
+-	u32 vdev_param;
+ 	int ret;
+ 
+-	lockdep_assert_held(&ar->conf_mutex);
++	/* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */
++	if (he_gi && he_gi != 0xFF)
++		he_gi += 1;
+ 
+-	ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02x nss %u sgi %u\n",
+-		   arvif->vdev_id, rate, nss, sgi);
++	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
++					    WMI_VDEV_PARAM_SGI, he_gi);
++	if (ret) {
++		ath12k_warn(ar->ab, "failed to set HE GI:%d, error:%d\n",
++			    he_gi, ret);
++		return ret;
++	}
++	/* start from 1 */
++	if (he_ltf != 0xFF)
++		he_ltf += 1;
+ 
+-	vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
+ 	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+-					    vdev_param, rate);
++					    WMI_VDEV_PARAM_HE_LTF, he_ltf);
+ 	if (ret) {
+-		ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",
+-			    rate, ret);
++		ath12k_warn(ar->ab, "failed to set HE LTF:%d, error:%d\n",
++			    he_ltf, ret);
+ 		return ret;
+ 	}
++	return 0;
++}
++
++static int
++ath12k_mac_set_auto_rate_gi_ltf(struct ath12k_vif *arvif, u16 he_gi, u8 he_ltf)
++{
++	struct ath12k *ar = arvif->ar;
++	int ret;
++	u32 he_ar_gi_ltf;
++
++	if (he_gi != 0xFF) {
++		switch (he_gi) {
++		case NL80211_RATE_INFO_HE_GI_0_8:
++			he_gi = WMI_AUTORATE_800NS_GI;
++			break;
++		case NL80211_RATE_INFO_HE_GI_1_6:
++			he_gi = WMI_AUTORATE_1600NS_GI;
++			break;
++		case NL80211_RATE_INFO_HE_GI_3_2:
++			he_gi = WMI_AUTORATE_3200NS_GI;
++			break;
++		default:
++			ath12k_warn(ar->ab, "Invalid GI\n");
++			return -EINVAL;
++		}
++	}
++
++	if (he_ltf != 0xFF) {
++		switch (he_ltf) {
++		case NL80211_RATE_INFO_HE_1XLTF:
++			he_ltf = WMI_HE_AUTORATE_LTF_1X;
++			break;
++		case NL80211_RATE_INFO_HE_2XLTF:
++			he_ltf = WMI_HE_AUTORATE_LTF_2X;
++			break;
++		case NL80211_RATE_INFO_HE_4XLTF:
++			he_ltf = WMI_HE_AUTORATE_LTF_4X;
++			break;
++		default:
++			ath12k_warn(ar->ab, "Invalid LTF\n");
++			return -EINVAL;
++		}
++	}
++
++	he_ar_gi_ltf = he_gi | he_ltf;
+ 
+-	vdev_param = WMI_VDEV_PARAM_NSS;
+ 	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+-					    vdev_param, nss);
++					    WMI_VDEV_PARAM_AUTORATE_MISC_CFG,
++					    he_ar_gi_ltf);
+ 	if (ret) {
+-		ath12k_warn(ar->ab, "failed to set nss param %d: %d\n",
+-			    nss, ret);
++		ath12k_warn(ar->ab,
++			    "failed to set HE autorate GI:%u, LTF:%u params, error:%d\n",
++			    he_gi, he_ltf, ret);
+ 		return ret;
+ 	}
+ 
+-	vdev_param = WMI_VDEV_PARAM_SGI;
++	return 0;
++}
++
++static int ath12k_mac_set_rate_params(struct ath12k_vif *arvif,
++				      u32 rate, u8 nss, u8 sgi, u8 ldpc,
++				      u8 he_gi, u8 he_ltf, bool he_fixed_rate)
++{
++	struct ath12k *ar = arvif->ar;
++	u32 vdev_param;
++	int ret;
++
++	lockdep_assert_held(&ar->conf_mutex);
++
++	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++		   "mac set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x\n",
++		   arvif->vdev_id, rate, nss, sgi, ldpc);
++
++	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++		   "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi,
++		   he_ltf, he_fixed_rate);
++
++	if (!arvif->vif->bss_conf.he_support) {
++		vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
++		ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
++						    vdev_param, rate);
++		if (ret) {
++			ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",
++				    rate, ret);
++			return ret;
++		}
++	}
++
++	vdev_param = WMI_VDEV_PARAM_NSS;
++
+ 	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+-					    vdev_param, sgi);
++					    vdev_param, nss);
+ 	if (ret) {
+-		ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n",
+-			    sgi, ret);
++		ath12k_warn(ar->ab, "failed to set nss param %d: %d\n",
++			    nss, ret);
+ 		return ret;
+ 	}
+ 
+-	vdev_param = WMI_VDEV_PARAM_LDPC;
+ 	ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+-					    vdev_param, ldpc);
++					    WMI_VDEV_PARAM_LDPC, ldpc);
+ 	if (ret) {
+ 		ath12k_warn(ar->ab, "failed to set ldpc param %d: %d\n",
+ 			    ldpc, ret);
+ 		return ret;
+ 	}
+ 
++	if (arvif->vif->bss_conf.he_support) {
++		if (he_fixed_rate)
++			ret = ath12k_mac_set_fixed_rate_gi_ltf(arvif, he_gi, he_ltf);
++		else
++			ret = ath12k_mac_set_auto_rate_gi_ltf(arvif, he_gi, he_ltf);
++		if (ret)
++			return ret;
++	} else {
++		vdev_param = WMI_VDEV_PARAM_SGI;
++		ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
++						    vdev_param, sgi);
++		if (ret) {
++			ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n",
++				    sgi, ret);
++			return ret;
++		}
++	}
++
+ 	return 0;
+ }
+ 
+@@ -8384,6 +8788,31 @@ ath12k_mac_vht_mcs_range_present(struct
+ 	return true;
+ }
+ 
++static bool
++ath12k_mac_he_mcs_range_present(struct ath12k *ar,
++				enum nl80211_band band,
++				const struct cfg80211_bitrate_mask *mask)
++{
++	int i;
++	u16 he_mcs;
++
++	for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
++		he_mcs = mask->control[band].he_mcs[i];
++
++		switch (he_mcs) {
++		case 0:
++		case BIT(8) - 1:
++		case BIT(10) - 1:
++		case BIT(12) - 1:
++			break;
++		default:
++			return false;
++		}
++	}
++
++	return true;
++}
++
+ static void ath12k_mac_set_bitrate_mask_iter(void *data,
+ 					     struct ieee80211_sta *sta)
+ {
+@@ -8423,6 +8852,54 @@ static void ath12k_mac_disable_peer_fixe
+ }
+ 
+ static int
++ath12k_mac_validate_vht_he_fixed_rate_settings(struct ath12k *ar, enum nl80211_band band,
++					       const struct cfg80211_bitrate_mask *mask)
++{
++	bool he_fixed_rate = false, vht_fixed_rate = false;
++	struct ath12k_peer *peer;
++	const u16 *vht_mcs_mask, *he_mcs_mask;
++	u8 vht_nss, he_nss;
++	int ret = 0;
++
++	vht_mcs_mask = mask->control[band].vht_mcs;
++	he_mcs_mask = mask->control[band].he_mcs;
++
++	if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1)
++		vht_fixed_rate = true;
++
++	if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1)
++		he_fixed_rate = true;
++
++	if (!vht_fixed_rate && !he_fixed_rate)
++		return 0;
++
++	vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask);
++	he_nss =  ath12k_mac_max_he_nss(he_mcs_mask);
++
++	rcu_read_lock();
++	spin_lock_bh(&ar->ab->base_lock);
++	list_for_each_entry(peer, &ar->ab->peers, list) {
++		if (peer->sta) {
++			if (vht_fixed_rate &&
++			    (!peer->sta->deflink.vht_cap.vht_supported ||
++			    peer->sta->deflink.rx_nss < vht_nss)) {
++				ret = -EINVAL;
++				goto exit;
++			}
++			if (he_fixed_rate && (!peer->sta->deflink.he_cap.has_he ||
++					      peer->sta->deflink.rx_nss < he_nss)) {
++				ret = -EINVAL;
++				goto exit;
++			}
++		}
++	}
++exit:
++	spin_unlock_bh(&ar->ab->base_lock);
++	rcu_read_unlock();
++	return ret;
++}
++
++static int
+ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
+ 			       struct ieee80211_vif *vif,
+ 			       const struct cfg80211_bitrate_mask *mask)
+@@ -8433,13 +8910,17 @@ ath12k_mac_op_set_bitrate_mask(struct ie
+ 	enum nl80211_band band;
+ 	const u8 *ht_mcs_mask;
+ 	const u16 *vht_mcs_mask;
++	const u16 *he_mcs_mask;
++	u8 he_ltf = 0;
++	u8 he_gi = 0;
+ 	u32 rate;
+-	u8 nss;
++	u8 nss, mac_nss;
+ 	u8 sgi;
+ 	u8 ldpc;
+ 	int single_nss;
+ 	int ret;
+ 	int num_rates;
++	bool he_fixed_rate = false;
+ 
+ 	if (ath12k_mac_vif_chan(vif, &def))
+ 		return -EPERM;
+@@ -8447,6 +8928,7 @@ ath12k_mac_op_set_bitrate_mask(struct ie
+ 	band = def.chan->band;
+ 	ht_mcs_mask = mask->control[band].ht_mcs;
+ 	vht_mcs_mask = mask->control[band].vht_mcs;
++	he_mcs_mask = mask->control[band].he_mcs;
+ 	ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
+ 
+ 	sgi = mask->control[band].gi;
+@@ -8455,6 +8937,9 @@ ath12k_mac_op_set_bitrate_mask(struct ie
+ 		goto out;
+ 	}
+ 
++	he_gi = mask->control[band].he_gi;
++	he_ltf = mask->control[band].he_ltf;
++
+ 	/* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it
+ 	 * requires passing at least one of used basic rates along with them.
+ 	 * Fixed rate setting across different preambles(legacy, HT, VHT) is
+@@ -8474,15 +8959,27 @@ ath12k_mac_op_set_bitrate_mask(struct ie
+ 		ieee80211_iterate_stations_mtx(hw,
+ 					       ath12k_mac_disable_peer_fixed_rate,
+ 					       arvif);
+-	} else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask,
++	} else if (ath12k_mac_bitrate_mask_get_single_nss(ar, vif, band, mask,
+ 							  &single_nss)) {
+ 		rate = WMI_FIXED_RATE_NONE;
+ 		nss = single_nss;
++		mutex_lock(&ar->conf_mutex);
++		arvif->bitrate_mask = *mask;
++		ieee80211_iterate_stations_mtx(hw,
++					       ath12k_mac_set_bitrate_mask_iter,
++					       arvif);
++		mutex_unlock(&ar->conf_mutex);
+ 	} else {
+ 		rate = WMI_FIXED_RATE_NONE;
+-		nss = min_t(u32, ar->num_tx_chains,
+-			    max(ath12k_mac_max_ht_nss(ht_mcs_mask),
+-				ath12k_mac_max_vht_nss(vht_mcs_mask)));
++
++		if (!ath12k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask))
++			ath12k_warn(ar->ab,
++				    "could not update fixed rate settings to all peers due to mcs/nss incompatiblity\n");
++
++		mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask),
++			       ath12k_mac_max_vht_nss(vht_mcs_mask),
++			       ath12k_mac_max_he_nss(he_mcs_mask));
++		nss = min_t(u32, ar->num_tx_chains, mac_nss);
+ 
+ 		/* If multiple rates across different preambles are given
+ 		 * we can reconfigure this info with all peers using PEER_ASSOC
+@@ -8518,12 +9015,22 @@ ath12k_mac_op_set_bitrate_mask(struct ie
+ 			goto out;
+ 		}
+ 
++		num_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask);
++		if (num_rates == 1)
++			he_fixed_rate = true;
++
++		if (!ath12k_mac_he_mcs_range_present(ar, band, mask) &&
++		    num_rates > 1) {
++			ath12k_warn(ar->ab,
++				    "Setting more than one HE MCS Value in bitrate mask not supported\n");
++			return -EINVAL;
++		}
++
++		mutex_lock(&ar->conf_mutex);
+ 		ieee80211_iterate_stations_mtx(hw,
+ 					       ath12k_mac_disable_peer_fixed_rate,
+ 					       arvif);
+ 
+-		mutex_lock(&ar->conf_mutex);
+-
+ 		arvif->bitrate_mask = *mask;
+ 		ieee80211_iterate_stations_mtx(hw,
+ 					       ath12k_mac_set_bitrate_mask_iter,
+@@ -8534,9 +9041,10 @@ ath12k_mac_op_set_bitrate_mask(struct ie
+ 
+ 	mutex_lock(&ar->conf_mutex);
+ 
+-	ret = ath12k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
++	ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi,
++					 he_ltf, he_fixed_rate);
+ 	if (ret) {
+-		ath12k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n",
++		ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n",
+ 			    arvif->vdev_id, ret);
+ 	}
+ 
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -220,6 +220,22 @@ enum WMI_HOST_WLAN_BAND {
+ 	WMI_HOST_WLAN_2G_5G_CAP	= 3,
+ };
+ 
++/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command.
++ * Used only for HE auto rate mode.
++ */
++enum {
++	/* HE LTF related configuration */
++	WMI_HE_AUTORATE_LTF_1X = BIT(0),
++	WMI_HE_AUTORATE_LTF_2X = BIT(1),
++	WMI_HE_AUTORATE_LTF_4X = BIT(2),
++
++	/* HE GI related configuration */
++	WMI_AUTORATE_400NS_GI = BIT(8),
++	WMI_AUTORATE_800NS_GI = BIT(9),
++	WMI_AUTORATE_1600NS_GI = BIT(10),
++	WMI_AUTORATE_3200NS_GI = BIT(11),
++};
++
+ enum wmi_cmd_group {
+ 	/* 0 to 2 are reserved */
+ 	WMI_GRP_START = 0x3,
+@@ -1132,7 +1148,9 @@ enum wmi_tlv_vdev_param {
+ 	WMI_VDEV_PARAM_HE_RANGE_EXT,
+ 	WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
+ 	WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
++	WMI_VDEV_PARAM_HE_LTF = 0x74,
+ 	WMI_VDEV_PARAM_BA_MODE = 0x7e,
++	WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80,
+ 	WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
+ 	WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99,
+ 	WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
diff --git a/package/kernel/mac80211/patches/ath12k/104-7-wifi-ath12k-clean-up-80P80-support.patch b/package/kernel/mac80211/patches/ath12k/104-7-wifi-ath12k-clean-up-80P80-support.patch
new file mode 100644
index 0000000000..a2792bf6e7
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-7-wifi-ath12k-clean-up-80P80-support.patch
@@ -0,0 +1,254 @@
+From patchwork Wed Sep 18 21:20:54 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807218
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com
+ [205.220.168.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7A2C15853D
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:29 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.168.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694491; cv=none;
+ b=IDDUnQF/Tnpw/FvWitX7ofLgG/RwY2FyN79K1j9v3STIk2mbRSVtS7kUmHv83gWDgLeingrnJyz3kE7pWhAK5Zt+U/d3HoSbyXlaWdr1m98ZLPJnOIO51q8LBaUW4uPaZbMJiRGvTbhFw+0k6FNjQse034o2zQ5vHk1qETT9XsU=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694491; c=relaxed/simple;
+	bh=4Sbgjg6TXf4A547Y46Qiyw4U55YEFrIGdUXLZjEx5C0=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=Y+NDqrjfpb1iFWpY9XYrVbCXhYRTFGsK7MN6jcsgZur7Ro+ZQsyZfhkFA+t+Bb52hk2p2N7v1TAdqLDK2CiFXaWPy/JfESHATwktCnNG+8/UL3n0VIjl+qxGTWt3pS/aWzI6yQjM2FB6tKc4kMnGX//RrgXhEIrh1M4ROs3IpJ0=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=Kt1nBSex; arc=none smtp.client-ip=205.220.168.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="Kt1nBSex"
+Received: from pps.filterd (m0279866.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48IJrYUI005813;
+	Wed, 18 Sep 2024 21:21:27 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	7iZtYFy4NRmF2YHXqLd4zDMUbigsFxIkBQ6OeDD3zOs=; b=Kt1nBSex9R0mUQFv
+	fimFwEUDD2mzhj9KyoJnJsvbpzJOV9sBCCp3nPyxHNB66qzQUi/U904HE+wQ26S+
+	Dmo2aGOzcx4GHLU8agTSdb51h1ylcD1ulUXKpEqDIEkWv7leWNteXYTqoj2aUvXQ
+	MH261Yr4HRs5iWT53+FXUrPvY1eipkyG20XH2RcNT7XMMIT29hm5DRVTwU0kzAVU
+	/0hrrSBcgbTJP0KA5zSfO+bFE7fyWSxrjOzt7ugW9KdHlAj5iNAeePRUUlvqSGe7
+	07QprF1ixgWWpsIbUnZdd9UZLPKot8h5Vous/24QLAznqmj/FgipHLT6+Dy61eVq
+	L/T40w==
+Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4jdu9q1-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:27 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL9Ux020570
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:09 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:08 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Jeff Johnson <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 7/9] wifi: ath12k: clean up 80P80 support
+Date: Wed, 18 Sep 2024 14:20:54 -0700
+Message-ID: <20240918212056.4137076-8-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-ORIG-GUID: zOl2cVhwvoAFaH70WioUIdrk_oIr5c-T
+X-Proofpoint-GUID: zOl2cVhwvoAFaH70WioUIdrk_oIr5c-T
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ phishscore=0 impostorscore=0
+ clxscore=1015 adultscore=0 mlxscore=0 suspectscore=0 malwarescore=0
+ priorityscore=1501 spamscore=0 bulkscore=0 lowpriorityscore=0
+ mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1
+ engine=8.19.0-2408220000 definitions=main-2409180141
+
+Clean up unused 80P80 references as hardware does not support
+it. This is applicable to both QCN9274 and WCN7850.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 51 ++++++---------------------
+ drivers/net/wireless/ath/ath12k/wmi.c |  5 +--
+ drivers/net/wireless/ath/ath12k/wmi.h |  1 -
+ 3 files changed, 11 insertions(+), 46 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -206,7 +206,7 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12
+ 			[NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40,
+ 			[NL80211_CHAN_WIDTH_80] = MODE_11BE_EHT80,
+ 			[NL80211_CHAN_WIDTH_160] = MODE_11BE_EHT160,
+-			[NL80211_CHAN_WIDTH_80P80] = MODE_11BE_EHT80_80,
++			[NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN,
+ 			[NL80211_CHAN_WIDTH_320] = MODE_11BE_EHT320,
+ 	},
+ 	[NL80211_BAND_6GHZ] = {
+@@ -217,7 +217,7 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12
+ 			[NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40,
+ 			[NL80211_CHAN_WIDTH_80] = MODE_11BE_EHT80,
+ 			[NL80211_CHAN_WIDTH_160] = MODE_11BE_EHT160,
+-			[NL80211_CHAN_WIDTH_80P80] = MODE_11BE_EHT80_80,
++			[NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN,
+ 			[NL80211_CHAN_WIDTH_320] = MODE_11BE_EHT320,
+ 	},
+ 
+@@ -2390,17 +2390,6 @@ static void ath12k_peer_assoc_h_he(struc
+ 
+ 	switch (sta->deflink.bandwidth) {
+ 	case IEEE80211_STA_RX_BW_160:
+-		if (he_cap->he_cap_elem.phy_cap_info[0] &
+-		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
+-			v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
+-			arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
+-
+-			v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80);
+-			arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
+-
+-			arg->peer_he_mcs_count++;
+-			he_tx_mcs = v;
+-		}
+ 		v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
+ 		arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
+ 
+@@ -2658,16 +2647,11 @@ static enum wmi_phy_mode ath12k_mac_get_
+ 						    struct ieee80211_sta *sta)
+ {
+ 	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) {
+-		switch (sta->deflink.vht_cap.cap &
+-			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
+-		case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
++		if (sta->deflink.vht_cap.cap &
++		    IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
+ 			return MODE_11AC_VHT160;
+-		case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
+-			return MODE_11AC_VHT80_80;
+-		default:
+-			/* not sure if this is a valid case? */
+-			return MODE_11AC_VHT160;
+-		}
++
++		return MODE_UNKNOWN;
+ 	}
+ 
+ 	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
+@@ -2689,11 +2673,8 @@ static enum wmi_phy_mode ath12k_mac_get_
+ 		if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &
+ 		     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ 			return MODE_11AX_HE160;
+-		else if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &
+-		     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+-			return MODE_11AX_HE80_80;
+-		/* not sure if this is a valid case? */
+-		return MODE_11AX_HE160;
++
++		return MODE_UNKNOWN;
+ 	}
+ 
+ 	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
+@@ -2721,14 +2702,7 @@ static enum wmi_phy_mode ath12k_mac_get_
+ 		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ 			return MODE_11BE_EHT160;
+ 
+-		if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &
+-			 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+-			return MODE_11BE_EHT80_80;
+-
+-		ath12k_warn(ar->ab, "invalid EHT PHY capability info for 160 Mhz: %d\n",
+-			    sta->deflink.he_cap.he_cap_elem.phy_cap_info[0]);
+-
+-		return MODE_11BE_EHT160;
++		return MODE_UNKNOWN;
+ 	}
+ 
+ 	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
+@@ -5805,8 +5779,6 @@ static void ath12k_mac_set_hemcsmap(stru
+ 	mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff);
+ 	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff);
+ 	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff);
+-	mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff);
+-	mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff);
+ }
+ 
+ static void ath12k_mac_copy_he_cap(struct ath12k *ar,
+@@ -5828,6 +5800,7 @@ static void ath12k_mac_copy_he_cap(struc
+ 		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+ 		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
+ 		IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
++	/* 80PLUS80 is not supported */
+ 	he_cap_elem->phy_cap_info[0] &=
+ 		~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
+ 	he_cap_elem->phy_cap_info[5] &=
+@@ -8494,10 +8467,6 @@ static __le16
+ ath12k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
+ {
+ 	if (he_cap->he_cap_elem.phy_cap_info[0] &
+-	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+-		return he_cap->he_mcs_nss_supp.tx_mcs_80p80;
+-
+-	if (he_cap->he_cap_elem.phy_cap_info[0] &
+ 	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ 		return he_cap->he_mcs_nss_supp.tx_mcs_160;
+ 
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -986,10 +986,7 @@ static void ath12k_wmi_put_wmi_channel(s
+ 
+ 	chan->mhz = cpu_to_le32(arg->freq);
+ 	chan->band_center_freq1 = cpu_to_le32(arg->band_center_freq1);
+-	if (arg->mode == MODE_11AC_VHT80_80)
+-		chan->band_center_freq2 = cpu_to_le32(arg->band_center_freq2);
+-	else
+-		chan->band_center_freq2 = 0;
++	chan->band_center_freq2 = 0;
+ 
+ 	chan->info |= le32_encode_bits(arg->mode, WMI_CHAN_INFO_MODE);
+ 	if (arg->passive)
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -3633,7 +3633,6 @@ struct wmi_vdev_install_key_arg {
+ #define WMI_HOST_MAX_HE_RATE_SET		3
+ #define WMI_HECAP_TXRX_MCS_NSS_IDX_80		0
+ #define WMI_HECAP_TXRX_MCS_NSS_IDX_160		1
+-#define WMI_HECAP_TXRX_MCS_NSS_IDX_80_80	2
+ 
+ struct wmi_rate_set_arg {
+ 	u32 num_rates;
diff --git a/package/kernel/mac80211/patches/ath12k/104-8-wifi-ath12k-add-support-for-160-MHz-bandwidth.patch b/package/kernel/mac80211/patches/ath12k/104-8-wifi-ath12k-add-support-for-160-MHz-bandwidth.patch
new file mode 100644
index 0000000000..f9b6c4065d
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-8-wifi-ath12k-add-support-for-160-MHz-bandwidth.patch
@@ -0,0 +1,399 @@
+From patchwork Wed Sep 18 21:20:55 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807216
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com
+ [205.220.180.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id C64DB1CB518
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:15 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.180.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694477; cv=none;
+ b=aWI5JISgL9c0iB/8EAXYKF/Lb2sJoeG+v5+Va4eb/voqwiSQ4FtwPkCC00b9attXvu4dD9wEHGKPW8Uh2kb1tSTl0uNHxijRmLYK2VUWkLHsZ3Pd6VvGoTpbtmOTgsGklZHZiFd+jyWgGkHB4ZBkHSkG9JH6VR44MSIgNj8g14A=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694477; c=relaxed/simple;
+	bh=AYJpDHbXZ0n0NNHQi7/aGcqo7YfyoYhv+FrXZ143wMA=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=jD1C2mzFvENculg9HS0v02iWUDzrWXiuU5GXTyC/0BKAJirnQkOUdVm7u0AEPiMxfkktLT3QCJLuvnKu3ZqSXWNbc2zOdUHTyW12fKdDNHib1WYYySBnfqu4EmiJKGcTE57VFlVdbklngOCDTCqHvVgP7YitGg2fWLPqBP/4yhM=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=OMqc+btb; arc=none smtp.client-ip=205.220.180.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="OMqc+btb"
+Received: from pps.filterd (m0279872.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48I8sxTR020476;
+	Wed, 18 Sep 2024 21:21:11 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	dFohRj9vqwjJTRRYk31/1oJCFqLLKUuQ/verxCo/cGo=; b=OMqc+btbHl9cHSxO
+	NauW5WX4C34QsGL/4d03QTtCDlctfB5PRmINiP2/jGcVZk3NZWS3d2f5zjPY7+hd
+	uaUDslDMQwvAj1Jay/we1qNaFIPuzj4c9BbHqvvXa0WiCgQWpBC2h2jcFLXbeVHE
+	5bqH+plXU5cz1d2YbsRpCXsdUWL/+S3u6A6/qxj6UraJ1s/rkE4ndQe/AQuf96Ja
+	ylYiZPdtJJXzB6rPDN1bQsSET/PNXzIkrYTaDLF9A6688WU9izJdAjRcsu8oB8o1
+	U+yftDfoegI7+ZyTZ4JUnQs7zJp171L/qsF0U9RONZCIbSLN9pkTo6xp6CrHGeLQ
+	0tCmwQ==
+Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4j6uagr-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:10 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILL9IB009589
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:09 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:09 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        P Praneesh <quic_ppranees at quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 8/9] wifi: ath12k: add support for 160 MHz bandwidth
+Date: Wed, 18 Sep 2024 14:20:55 -0700
+Message-ID: <20240918212056.4137076-9-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-ORIG-GUID: wO0mnzqAAbcWYLNaoEhU3YfsdCyDJ2hk
+X-Proofpoint-GUID: wO0mnzqAAbcWYLNaoEhU3YfsdCyDJ2hk
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ phishscore=0 mlxlogscore=999
+ mlxscore=0 malwarescore=0 bulkscore=0 priorityscore=1501 clxscore=1015
+ adultscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 impostorscore=0
+ classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000
+ definitions=main-2409180140
+
+Add support to configure maximum NSS in 160 MHz bandwidth.
+Firmware advertises support for handling NSS ratio information
+as a part of service ready ext event using nss_ratio_enabled
+flag. Save this information in ath12k_pdev_cap to calculate
+NSS ratio.
+
+Additionally, reorder the code by moving
+ath12k_peer_assoc_h_phymode() before ath12k_peer_assoc_h_vht()
+to ensure that arg->peer_phymode correctly reflects the bandwidth
+in the max NSS calculation.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Co-developed-by: P Praneesh <quic_ppranees at quicinc.com>
+Signed-off-by: P Praneesh <quic_ppranees at quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/core.h |  2 +
+ drivers/net/wireless/ath/ath12k/mac.c  | 85 ++++++++++++++++++++++----
+ drivers/net/wireless/ath/ath12k/mac.h  |  2 +
+ drivers/net/wireless/ath/ath12k/wmi.c  | 19 +++++-
+ drivers/net/wireless/ath/ath12k/wmi.h  | 28 +++++++++
+ 5 files changed, 124 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/core.h
++++ b/drivers/net/wireless/ath/ath12k/core.h
+@@ -717,6 +717,8 @@ struct ath12k_pdev_cap {
+ 	u32 tx_chain_mask_shift;
+ 	u32 rx_chain_mask_shift;
+ 	struct ath12k_band_cap band[NUM_NL80211_BANDS];
++	bool nss_ratio_enabled;
++	u8 nss_ratio_info;
+ };
+ 
+ struct mlo_timestamp {
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -2050,6 +2050,34 @@ ath12k_peer_assoc_h_vht_limit(u16 tx_mcs
+ 	return tx_mcs_set;
+ }
+ 
++static u8 ath12k_get_nss_160mhz(struct ath12k *ar,
++				u8 max_nss)
++{
++	u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info;
++	u8 max_sup_nss = 0;
++
++	switch (nss_ratio_info) {
++	case WMI_NSS_RATIO_1BY2_NSS:
++		max_sup_nss = max_nss >> 1;
++		break;
++	case WMI_NSS_RATIO_3BY4_NSS:
++		ath12k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n");
++		break;
++	case WMI_NSS_RATIO_1_NSS:
++		max_sup_nss = max_nss;
++		break;
++	case WMI_NSS_RATIO_2_NSS:
++		ath12k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n");
++		break;
++	default:
++		ath12k_warn(ar->ab, "invalid nss ratio received from fw: %d\n",
++			    nss_ratio_info);
++		break;
++	}
++
++	return max_sup_nss;
++}
++
+ static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
+ 				    struct ieee80211_vif *vif,
+ 				    struct ieee80211_sta *sta,
+@@ -2065,6 +2093,7 @@ static void ath12k_peer_assoc_h_vht(stru
+ 	u8 max_nss, vht_mcs;
+ 	int i, vht_nss, nss_idx;
+ 	bool user_rate_valid = true;
++	u32 rx_nss, tx_nss, nss_160;
+ 
+ 	if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
+ 		return;
+@@ -2159,10 +2188,24 @@ static void ath12k_peer_assoc_h_vht(stru
+ 	/* TODO:  Check */
+ 	arg->tx_max_mcs_nss = 0xFF;
+ 
+-	ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
+-		   sta->addr, arg->peer_max_mpdu, arg->peer_flags);
++	if (arg->peer_phymode == MODE_11AC_VHT160) {
++		tx_nss = ath12k_get_nss_160mhz(ar, max_nss);
++		rx_nss = min(arg->peer_nss, tx_nss);
++		arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE;
+ 
+-	/* TODO: rxnss_override */
++		if (!rx_nss) {
++			ath12k_warn(ar->ab, "invalid max_nss\n");
++			return;
++		}
++
++		nss_160 = u32_encode_bits(rx_nss - 1, ATH12K_PEER_RX_NSS_160MHZ);
++		arg->peer_bw_rxnss_override |= nss_160;
++	}
++
++	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
++		   "mac vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n",
++		   sta->addr, arg->peer_max_mpdu, arg->peer_flags,
++		   arg->peer_bw_rxnss_override);
+ }
+ 
+ static int ath12k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)
+@@ -2251,6 +2294,7 @@ static void ath12k_peer_assoc_h_he(struc
+ 	u16 he_tx_mcs = 0, v = 0;
+ 	int he_nss, nss_idx;
+ 	bool user_rate_valid = true;
++	u32 rx_nss, tx_nss, nss_160;
+ 
+ 	if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
+ 		return;
+@@ -2429,11 +2473,28 @@ static void ath12k_peer_assoc_h_he(struc
+ 		    he_mcs_mask[i])
+ 			max_nss = i + 1;
+ 	}
++	max_nss = min(max_nss, ar->num_tx_chains);
+ 	arg->peer_nss = min(sta->deflink.rx_nss, max_nss);
+ 
++	if (arg->peer_phymode == MODE_11AX_HE160) {
++		tx_nss = ath12k_get_nss_160mhz(ar, max_nss);
++		rx_nss = min(arg->peer_nss, tx_nss);
++		arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE;
++
++		if (!rx_nss) {
++			ath12k_warn(ar->ab, "invalid max_nss\n");
++			return;
++		}
++
++		nss_160 = u32_encode_bits(rx_nss - 1, ATH12K_PEER_RX_NSS_160MHZ);
++		arg->peer_bw_rxnss_override |= nss_160;
++	}
++
+ 	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
+-		   "mac he peer %pM nss %d mcs cnt %d\n",
+-		   sta->deflink.addr, arg->peer_nss, arg->peer_he_mcs_count);
++		   "mac he peer %pM nss %d mcs cnt %d nss_override 0x%x\n",
++		   sta->deflink.addr, arg->peer_nss,
++		   arg->peer_he_mcs_count,
++		   arg->peer_bw_rxnss_override);
+ }
+ 
+ static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar,
+@@ -2965,13 +3026,13 @@ static void ath12k_peer_assoc_prepare(st
+ 	ath12k_peer_assoc_h_basic(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_crypto(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_rates(ar, vif, sta, arg);
++	ath12k_peer_assoc_h_phymode(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_ht(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_vht(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_he(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_he_6ghz(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_eht(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_qos(ar, vif, sta, arg);
+-	ath12k_peer_assoc_h_phymode(ar, vif, sta, arg);
+ 	ath12k_peer_assoc_h_smps(sta, arg);
+ 
+ 	/* TODO: amsdu_disable req? */
+@@ -5551,10 +5612,8 @@ ath12k_create_vht_cap(struct ath12k *ar,
+ 
+ 	ath12k_set_vht_txbf_cap(ar, &vht_cap.cap);
+ 
+-	/* TODO: Enable back VHT160 mode once association issues are fixed */
+-	/* Disabling VHT160 and VHT80+80 modes */
+-	vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+-	vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
++	/* 80P80 is not supported */
++	vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+ 
+ 	rxmcs_map = 0;
+ 	txmcs_map = 0;
+@@ -9710,7 +9769,8 @@ static int ath12k_mac_setup_iface_combin
+ 	combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+ 						BIT(NL80211_CHAN_WIDTH_20) |
+ 						BIT(NL80211_CHAN_WIDTH_40) |
+-						BIT(NL80211_CHAN_WIDTH_80);
++						BIT(NL80211_CHAN_WIDTH_80) |
++						BIT(NL80211_CHAN_WIDTH_160);
+ 
+ 	wiphy->iface_combinations = combinations;
+ 	wiphy->n_iface_combinations = 1;
+@@ -9926,6 +9986,9 @@ static int ath12k_mac_hw_register(struct
+ 	ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
+ 	ieee80211_hw_set(hw, REPORTS_LOW_ACK);
+ 
++	if (cap->nss_ratio_enabled)
++		ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
++
+ 	if ((ht_cap & WMI_HT_CAP_ENABLED) || ar->supports_6ghz) {
+ 		ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+ 		ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
+--- a/drivers/net/wireless/ath/ath12k/mac.h
++++ b/drivers/net/wireless/ath/ath12k/mac.h
+@@ -37,6 +37,8 @@ struct ath12k_generic_iter {
+ #define IEEE80211_DISABLE_VHT_MCS_SUPPORT_0_11	BIT(24)
+ 
+ #define ATH12K_CHAN_WIDTH_NUM			14
++#define ATH12K_BW_NSS_MAP_ENABLE		BIT(31)
++#define ATH12K_PEER_RX_NSS_160MHZ		GENMASK(2, 0)
+ 
+ #define ATH12K_TX_POWER_MAX_VAL	70
+ #define ATH12K_TX_POWER_MIN_VAL	0
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -525,6 +525,10 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(st
+ 		pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g);
+ 		pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_5g);
+ 		pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_5g);
++		pdev_cap->nss_ratio_enabled =
++			WMI_NSS_RATIO_EN_DIS_GET(mac_caps->nss_ratio);
++		pdev_cap->nss_ratio_info =
++			WMI_NSS_RATIO_INFO_GET(mac_caps->nss_ratio);
+ 	} else {
+ 		return -EINVAL;
+ 	}
+@@ -982,11 +986,24 @@ int ath12k_wmi_vdev_down(struct ath12k *
+ static void ath12k_wmi_put_wmi_channel(struct ath12k_wmi_channel_params *chan,
+ 				       struct wmi_vdev_start_req_arg *arg)
+ {
++	u32 center_freq1 = arg->band_center_freq1;
++
+ 	memset(chan, 0, sizeof(*chan));
+ 
+ 	chan->mhz = cpu_to_le32(arg->freq);
+ 	chan->band_center_freq1 = cpu_to_le32(arg->band_center_freq1);
+-	chan->band_center_freq2 = 0;
++	if (arg->mode == MODE_11AX_HE160) {
++		if (arg->freq > center_freq1)
++			chan->band_center_freq1 =
++					cpu_to_le32(center_freq1 + 40);
++		else
++			chan->band_center_freq1 =
++					cpu_to_le32(center_freq1 - 40);
++
++		chan->band_center_freq2 = cpu_to_le32(arg->band_center_freq1);
++	} else {
++		chan->band_center_freq2 = 0;
++	}
+ 
+ 	chan->info |= le32_encode_bits(arg->mode, WMI_CHAN_INFO_MODE);
+ 	if (arg->passive)
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -2264,6 +2264,21 @@ enum wmi_direct_buffer_module {
+ 	WMI_DIRECT_BUF_MAX
+ };
+ 
++/**
++ * enum wmi_nss_ratio - NSS ratio received from FW during service ready ext event
++ * @WMI_NSS_RATIO_1BY2_NSS: Max nss of 160MHz is equals to half of the max nss of 80MHz
++ * @WMI_NSS_RATIO_3BY4_NSS: Max nss of 160MHz is equals to 3/4 of the max nss of 80MHz
++ * @WMI_NSS_RATIO_1_NSS: Max nss of 160MHz is equals to the max nss of 80MHz
++ * @WMI_NSS_RATIO_2_NSS: Max nss of 160MHz is equals to two times the max nss of 80MHz
++ */
++
++enum wmi_nss_ratio {
++	WMI_NSS_RATIO_1BY2_NSS,
++	WMI_NSS_RATIO_3BY4_NSS,
++	WMI_NSS_RATIO_1_NSS,
++	WMI_NSS_RATIO_2_NSS
++};
++
+ struct ath12k_wmi_pdev_band_arg {
+ 	u32 pdev_id;
+ 	u32 start_freq;
+@@ -2580,6 +2595,12 @@ struct ath12k_wmi_hw_mode_cap_params {
+ } __packed;
+ 
+ #define WMI_MAX_HECAP_PHY_SIZE                 (3)
++#define WMI_NSS_RATIO_EN_DIS_BITPOS    BIT(0)
++#define WMI_NSS_RATIO_EN_DIS_GET(_val) \
++	le32_get_bits(_val, WMI_NSS_RATIO_EN_DIS_BITPOS)
++#define WMI_NSS_RATIO_INFO_BITPOS              GENMASK(4, 1)
++#define WMI_NSS_RATIO_INFO_GET(_val) \
++	le32_get_bits(_val, WMI_NSS_RATIO_INFO_BITPOS)
+ 
+ /* pdev_id is present in lower 16 bits of pdev_and_hw_link_ids in
+  * ath12k_wmi_mac_phy_caps_params & ath12k_wmi_caps_ext_params.
+@@ -2621,6 +2642,13 @@ struct ath12k_wmi_mac_phy_caps_params {
+ 	__le32 he_cap_info_2g_ext;
+ 	__le32 he_cap_info_5g_ext;
+ 	__le32 he_cap_info_internal;
++	__le32 wireless_modes;
++	__le32 low_2ghz_chan_freq;
++	__le32 high_2ghz_chan_freq;
++	__le32 low_5ghz_chan_freq;
++	__le32 high_5ghz_chan_freq;
++	__le32 nss_ratio;
++
+ } __packed;
+ 
+ struct ath12k_wmi_hal_reg_caps_ext_params {
diff --git a/package/kernel/mac80211/patches/ath12k/104-9-wifi-ath12k-add-extended-NSS-bandwidth-support-for-160-MHz.patch b/package/kernel/mac80211/patches/ath12k/104-9-wifi-ath12k-add-extended-NSS-bandwidth-support-for-160-MHz.patch
new file mode 100644
index 0000000000..b7d8bcd599
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath12k/104-9-wifi-ath12k-add-extended-NSS-bandwidth-support-for-160-MHz.patch
@@ -0,0 +1,191 @@
+From patchwork Wed Sep 18 21:20:56 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+X-Patchwork-Id: 13807214
+X-Patchwork-Delegate: quic_jjohnson at quicinc.com
+Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com
+ [205.220.168.131])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.subspace.kernel.org (Postfix) with ESMTPS id A44471CB32B
+	for <linux-wireless at vger.kernel.org>; Wed, 18 Sep 2024 21:21:14 +0000 (UTC)
+Authentication-Results: smtp.subspace.kernel.org;
+ arc=none smtp.client-ip=205.220.168.131
+ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
+	t=1726694476; cv=none;
+ b=YnQUUZ4IfmLtgtYCtYRGhH8uRGd6VL74IRylGv6Ihb2PMO/n5UdfZlDk/m9w0OH4/sSsqULSz2lupiSTwXCPxc+73uK+OUjIEmCfPlNdrtzK2naXyiXAASPqonpnRBnyoIFwaE8zj8AHUqk5TAajedqpK9EnOaboX2XGYVbe0yI=
+ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
+	s=arc-20240116; t=1726694476; c=relaxed/simple;
+	bh=TAPBD6g5pYNuC8Odk6t6JkL8GvKdG9H30IPHTEgA7C0=;
+	h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
+	 MIME-Version:Content-Type;
+ b=djAINL+wQRgQaGOI4fotrExnm1Yz5quwEW2I7s85hWLI3gB+HsjwPKWJypllDKm8W0FDcrsoZWFmOrfx0wJ5LIe+OtXJ4ijSG7xcJeGtgDXZ3hAA5ZBk/B+CD+g+NZ3c0mwkSKpUm5dUBPKi1+kJsPuVEwKeCmdMVj8QHSYMXPw=
+ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com;
+ spf=pass smtp.mailfrom=quicinc.com;
+ dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b=i4iTJD+Z; arc=none smtp.client-ip=205.220.168.131
+Authentication-Results: smtp.subspace.kernel.org;
+ dmarc=pass (p=none dis=none) header.from=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+ spf=pass smtp.mailfrom=quicinc.com
+Authentication-Results: smtp.subspace.kernel.org;
+	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
+ header.b="i4iTJD+Z"
+Received: from pps.filterd (m0279863.ppops.net [127.0.0.1])
+	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
+ 48I9VJ15022098;
+	Wed, 18 Sep 2024 21:21:11 GMT
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
+	cc:content-transfer-encoding:content-type:date:from:in-reply-to
+	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
+	2gwv4CbPGErAHv9NWtZrCSVk7NoZpHzKz9tuTs+8dV4=; b=i4iTJD+ZMXDp8Ul8
+	HTo5IL/NLwS3mnlutEaaL+juUKm+wsFdl/BeMp9CC4H/sapolIhM4Zje9t3H9K0R
+	+z1OxQDEekvWrrfUlikEaUHjOEwQ4YKSPJ+1uAIrbbA3REWeW5z39IITJ3dGU05N
+	hnfPQEiFcPgDbFQv0Iaf434znv8rbOow6dc+M1E6EjpGd92Mq80BpsJqP8Ee0RUr
+	WO3rsws1kXzFs6ELsg/FmC3l6eG9A4z9SUxcZ7QqTaz8aPOAZS/lclN0cOJT7VgK
+	7UNPGoDoJhTmHEX17W/rQR8RiV8c0hMciOuB1sfI7H/1uGkEPMjmfIsEdBjQ/9oa
+	DDiHrg==
+Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com
+ [129.46.96.20])
+	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4hfk92c-1
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:11 +0000 (GMT)
+Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
+ [10.47.209.196])
+	by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
+ 48ILLA0u011397
+	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
+	Wed, 18 Sep 2024 21:21:10 GMT
+Received: from ath12k-linux1.qualcomm.com (10.80.80.8) by
+ nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
+ (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
+ 15.2.1544.9; Wed, 18 Sep 2024 14:21:09 -0700
+From: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+To: <ath12k at lists.infradead.org>
+CC: <linux-wireless at vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+	<quic_pradeepc at quicinc.com>,
+        Jeff Johnson <quic_jjohnson at quicinc.com>
+Subject: [PATCH V8 9/9] wifi: ath12k: add extended NSS bandwidth support for
+ 160 MHz
+Date: Wed, 18 Sep 2024 14:20:56 -0700
+Message-ID: <20240918212056.4137076-10-quic_pradeepc at quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc at quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless at vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe at vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe at vger.kernel.org>
+MIME-Version: 1.0
+X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
+ nalasex01a.na.qualcomm.com (10.47.209.196)
+X-QCInternal: smtphost
+X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
+ signatures=585085
+X-Proofpoint-GUID: Mta6b5FqdCLrvsiUf1WwMHFr8SiJUh5L
+X-Proofpoint-ORIG-GUID: Mta6b5FqdCLrvsiUf1WwMHFr8SiJUh5L
+X-Proofpoint-Virus-Version: vendor=baseguard
+ engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29
+ definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01
+X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
+ priorityscore=1501
+ clxscore=1015 phishscore=0 malwarescore=0 mlxlogscore=999 mlxscore=0
+ impostorscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0
+ bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
+ engine=8.19.0-2408220000 definitions=main-2409180140
+
+Currently rx and tx MCS map for 160 MHz under HE capabilities
+are not updating properly, when 160 MHz is configured with NSS
+lesser than max NSS support. Fix this by utilizing
+nss_ratio_enabled and nss_ratio_info fields sent by firmware
+in service ready event.
+
+However, if firmware advertises EXT NSS BW support in VHT caps
+as 1(1x2) and when nss_ratio_info indicates 1:1, reset the EXT
+NSS BW Support in VHT caps to 0 which indicates 1x1. This is
+to avoid incorrectly choosing 1:2 NSS ratio when using the
+default VHT caps advertised by firmware.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc at quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 33 ++++++++++++++++++++++-----
+ 1 file changed, 27 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -2477,8 +2477,10 @@ static void ath12k_peer_assoc_h_he(struc
+ 	arg->peer_nss = min(sta->deflink.rx_nss, max_nss);
+ 
+ 	if (arg->peer_phymode == MODE_11AX_HE160) {
+-		tx_nss = ath12k_get_nss_160mhz(ar, max_nss);
++		tx_nss = ath12k_get_nss_160mhz(ar, ar->num_tx_chains);
+ 		rx_nss = min(arg->peer_nss, tx_nss);
++
++		arg->peer_nss = min(sta->deflink.rx_nss, ar->num_rx_chains);
+ 		arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE;
+ 
+ 		if (!rx_nss) {
+@@ -5635,6 +5637,12 @@ ath12k_create_vht_cap(struct ath12k *ar,
+ 	vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_map);
+ 	vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_map);
+ 
++	/* Check if the HW supports 1:1 NSS ratio and reset
++	 * EXT NSS BW Support field to 0 to indicate 1:1 ratio
++	 */
++	if (ar->pdev->cap.nss_ratio_info == WMI_NSS_RATIO_1_NSS)
++		vht_cap.cap &= ~IEEE80211_VHT_CAP_EXT_NSS_BW_MASK;
++
+ 	return vht_cap;
+ }
+ 
+@@ -5815,11 +5823,12 @@ static void ath12k_mac_set_hemcsmap(stru
+ 				    struct ieee80211_sta_he_cap *he_cap)
+ {
+ 	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
+-	u16 txmcs_map, rxmcs_map;
++	u8 maxtxnss_160 = ath12k_get_nss_160mhz(ar, ar->num_tx_chains);
++	u8 maxrxnss_160 = ath12k_get_nss_160mhz(ar, ar->num_rx_chains);
++	u16 txmcs_map_160 = 0, rxmcs_map_160 = 0;
++	u16 txmcs_map = 0, rxmcs_map = 0;
+ 	u32 i;
+ 
+-	rxmcs_map = 0;
+-	txmcs_map = 0;
+ 	for (i = 0; i < 8; i++) {
+ 		if (i < ar->num_tx_chains &&
+ 		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
+@@ -5832,12 +5841,24 @@ static void ath12k_mac_set_hemcsmap(stru
+ 			rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
+ 		else
+ 			rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
++
++		if (i < maxtxnss_160 &&
++		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
++			txmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
++		else
++			txmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
++
++		if (i < maxrxnss_160 &&
++		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
++			rxmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
++		else
++			rxmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
+ 	}
+ 
+ 	mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff);
+ 	mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff);
+-	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff);
+-	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff);
++	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map_160 & 0xffff);
++	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map_160 & 0xffff);
+ }
+ 
+ static void ath12k_mac_copy_he_cap(struct ath12k *ar,




More information about the lede-commits mailing list