]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
mac80211: ath12k: add patches for 160MHz support
authorMantas Pucka <mantas@8devices.com>
Fri, 4 Apr 2025 12:02:17 +0000 (15:02 +0300)
committerChristian Marangi <ansuelsmth@gmail.com>
Sat, 12 Apr 2025 08:38:53 +0000 (10:38 +0200)
Add series enabling 160MHz channels on ath12k

Signed-off-by: Mantas Pucka <mantas@8devices.com>
Link: https://github.com/openwrt/openwrt/pull/18459
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
package/kernel/mac80211/patches/ath12k/104-1-wifi-ath12k-push-HE-MU-MIMO-params-to-hardware.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-2-wifi-ath12k-push-EHT-MU-MIMO-params-to-hardware.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-3-wifi-ath12k-move-HE-MCS-mapper-to-a-separate-function.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-4-wifi-ath12k-generate-rx-and-tx-mcs-maps-for-supported-HE-mcs.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-5-wifi-ath12k-fix-TX-and-RX-MCS-rate-configurations-in-HE-mode.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-6-wifi-ath12k-add-support-for-setting-fixed-HE-rate-GI-LTF.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-7-wifi-ath12k-clean-up-80P80-support.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-8-wifi-ath12k-add-support-for-160-MHz-bandwidth.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath12k/104-9-wifi-ath12k-add-extended-NSS-bandwidth-support-for-160-MHz.patch [new file with mode: 0644]

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 (file)
index 0000000..8c0e67a
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807212
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Muna Sinada <quic_msinada@quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..65ef65f
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807210
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Muna Sinada <quic_msinada@quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..bc2710a
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807213
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Muna Sinada <quic_msinada@quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..3577889
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807215
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Muna Sinada <quic_msinada@quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..e1d109c
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807211
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Jeff Johnson <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..d44e927
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807217
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Muna Sinada <quic_msinada@quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..a2792bf
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807218
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Jeff Johnson <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..f9b6c40
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807216
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        P Praneesh <quic_ppranees@quicinc.com>,
+        "Jeff
+ Johnson" <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
+Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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 (file)
index 0000000..b7d8bcd
--- /dev/null
@@ -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@quicinc.com>
+X-Patchwork-Id: 13807214
+X-Patchwork-Delegate: quic_jjohnson@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@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@quicinc.com>
+To: <ath12k@lists.infradead.org>
+CC: <linux-wireless@vger.kernel.org>,
+        Pradeep Kumar Chitrapu
+       <quic_pradeepc@quicinc.com>,
+        Jeff Johnson <quic_jjohnson@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@quicinc.com>
+X-Mailer: git-send-email 2.34.1
+In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com>
+Precedence: bulk
+X-Mailing-List: linux-wireless@vger.kernel.org
+List-Id: <linux-wireless.vger.kernel.org>
+List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-wireless+unsubscribe@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@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@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,