1 From patchwork Wed May 21 22:45:36 2025
2 Content-Type: text/plain; charset="utf-8"
4 Content-Transfer-Encoding: 7bit
5 X-Patchwork-Submitter: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
6 X-Patchwork-Id: 14096125
7 X-Patchwork-Delegate: quic_jjohnson@quicinc.com
8 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com
10 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
11 (No client certificate requested)
12 by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A17F1B0F20
13 for <linux-wireless@vger.kernel.org>; Wed, 21 May 2025 22:45:59 +0000 (UTC)
14 Authentication-Results: smtp.subspace.kernel.org;
15 arc=none smtp.client-ip=205.220.180.131
16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
17 t=1747867562; cv=none;
18 b=bEGfSmKJAIERqJyK0yJndcYM+a7cpfrIkMLoGUTFvAkrcwqnlh3F9AqLbcb8fKznhfaQKFVRUdpVGSjFaplFVSp20RuXvPC2NLb0eKZrz5qS/4geTMxY/BeWuVN+i3ouoQzfYz8Vq6sTqLE5d6b650cCVf8hpY+VZ3ZTNWxVvdA=
19 ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
20 s=arc-20240116; t=1747867562; c=relaxed/simple;
21 bh=hBxlXRYYCPbv8+evEatym1UfdpOfENFUVDWgibN+XTg=;
22 h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:
23 MIME-Version:Content-Type;
24 b=U32JKi6TAoRF/9e1cv0vPGUM6BaRhoFXM0b36j5PBpvKQmRXKDF/UNScd5EJnrFOPlgjPD7GOc+TdHqsFGk/7pNucA1++GU00SZ0q/223zg5dCsYLmfLrRu3G22WZS2hWuNKuUPFJEFFLEJ8UQWKtFB0oWsQcx+Oj1mWPbBrDU8=
25 ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
26 dmarc=pass (p=none dis=none) header.from=quicinc.com;
27 spf=pass smtp.mailfrom=quicinc.com;
28 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
29 header.b=bzVTzUcl; arc=none smtp.client-ip=205.220.180.131
30 Authentication-Results: smtp.subspace.kernel.org;
31 dmarc=pass (p=none dis=none) header.from=quicinc.com
32 Authentication-Results: smtp.subspace.kernel.org;
33 spf=pass smtp.mailfrom=quicinc.com
34 Authentication-Results: smtp.subspace.kernel.org;
35 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
37 Received: from pps.filterd (m0279868.ppops.net [127.0.0.1])
38 by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
40 Wed, 21 May 2025 22:45:55 GMT
41 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
42 cc:content-transfer-encoding:content-type:date:from:in-reply-to
43 :message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
44 cpcIGD4iPSOaZzDkHZpoGs5Kor0sF3EnocHYcBOazgM=; b=bzVTzUclt3RkLn9A
45 YI8+MC64RjF5llUqmQ0G53D8sAQZ+95fc92X/ZrZvnyr7X0FBI+gU05yKzNuv4M5
46 XcIWK7Y8gjr55i9w18cWHGW2Q/JGC8pJlx0A/SEAMIMXeeEmgJqdKowT2wMjzIIH
47 wb7JmE9d6z6ZKcgQYx9KICXaaEFQ9uxyRyjlJMMEJ3zb7MjxZPCCGtCI31Aqczpk
48 B3X+1UgRT+OJzV6vIF0kdn/sjU69iZNHoPAUDYqInWCs2lPLMUO5mckhOG3fH8s6
49 jmhgpwlpUYx18jawRUpklvujXfFiDV4daXLeUKzL5b08f5OcSRvd7+iOytudYgr0
51 Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
53 by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 46rwfb4b3w-1
54 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
55 Wed, 21 May 2025 22:45:55 +0000 (GMT)
56 Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
58 by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
60 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
61 Wed, 21 May 2025 22:45:54 GMT
62 Received: from ath12k-linux2.qualcomm.com (10.80.80.8) by
63 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
64 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
65 15.2.1544.9; Wed, 21 May 2025 15:45:53 -0700
66 From: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
67 To: <ath12k@lists.infradead.org>
68 CC: <linux-wireless@vger.kernel.org>,
69 Pradeep Kumar Chitrapu
70 <quic_pradeepc@quicinc.com>,
71 Muna Sinada <quic_msinada@quicinc.com>
72 Subject: [PATCH ath-next V14 6/9] wifi: ath12k: add support for setting fixed
74 Date: Wed, 21 May 2025 15:45:36 -0700
75 Message-ID: <20250521224539.355985-7-quic_pradeepc@quicinc.com>
76 X-Mailer: git-send-email 2.43.0
77 In-Reply-To: <20250521224539.355985-1-quic_pradeepc@quicinc.com>
78 References: <20250521224539.355985-1-quic_pradeepc@quicinc.com>
80 X-Mailing-List: linux-wireless@vger.kernel.org
81 List-Id: <linux-wireless.vger.kernel.org>
82 List-Subscribe: <mailto:linux-wireless+subscribe@vger.kernel.org>
83 List-Unsubscribe: <mailto:linux-wireless+unsubscribe@vger.kernel.org>
85 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To
86 nalasex01a.na.qualcomm.com (10.47.209.196)
87 X-QCInternal: smtphost
88 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
90 X-Proofpoint-ORIG-GUID: 7uuxK_kl_b0JzKZoWIyq_ZYKeKL3it15
91 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNTIxMDIyNiBTYWx0ZWRfX7sjoM15po0tB
92 FcR1nwzr8TocaDYnIXgl13rA+kjwsizlMt/N5cu8dCWo9YQKqFNy42Z2VEYmoDRw7dBnYnsMIL/
93 wwv4hQYQslnxilRJaX/MVQ50/xxhSry8NrKA2QXvIg3btmiW4gQfrn3+k1Rm3o/gAGv2Yz4R8lw
94 YBPHVdQkgGJXYgsiB/b+copbnU621GYiYrCW6yUQHHIiwzjMljzzsk+9Koc6yeVByyPj86P80y7
95 2C8L1vuRAy8gCMSScMB9CyQ6+tLCKa1W2bhA0Oxz/+RGEXbujS4NDXCWz+EqIaYS5HXuD32pODy
96 O2wMURrbgE5PJIjjvpAdtqZL65QVaoVK1LWU6Co0NtHytEjuaZmr1hbb4hVDAtQio2Bw/K8yCM+
97 ikcJ1sGkE78mu/U7gQjG6g0Z71Q/w13jBOz+RIocPFi2FyEjy5KDFmUBzY+jDCIRLi06R8sP
98 X-Proofpoint-GUID: 7uuxK_kl_b0JzKZoWIyq_ZYKeKL3it15
99 X-Authority-Analysis: v=2.4 cv=dLCmmPZb c=1 sm=1 tr=0 ts=682e57a3 cx=c_pps
100 a=ouPCqIW2jiPt+lZRy3xVPw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17
101 a=GEpy-HfZoHoA:10 a=dt9VzEwgFbYA:10 a=COk6AnOGAAAA:8 a=KygRlO7-s-l5tpycOzUA:9
102 a=TjNXssC_j7lpFel5tvFf:22
103 X-Proofpoint-Virus-Version: vendor=baseguard
104 engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40
105 definitions=2025-05-21_07,2025-05-20_03,2025-03-28_01
106 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
107 mlxscore=0 clxscore=1015 adultscore=0 bulkscore=0 phishscore=0 suspectscore=0
108 impostorscore=0 malwarescore=0 lowpriorityscore=0 mlxlogscore=999 spamscore=0
109 priorityscore=1501 classifier=spam authscore=0 authtc=n/a authcc=
110 route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505160000
111 definitions=main-2505210226
113 Add support to set fixed HE rate/GI/LTF values using nl80211.
114 Reuse parts of the existing code path already used for HT/VHT
115 to implement the new helpers symmetrically, similar to how
118 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
120 Co-developed-by: Muna Sinada <quic_msinada@quicinc.com>
121 Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
122 Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
124 drivers/net/wireless/ath/ath12k/mac.c | 650 +++++++++++++++++++++++---
125 drivers/net/wireless/ath/ath12k/wmi.h | 27 ++
126 2 files changed, 625 insertions(+), 52 deletions(-)
128 --- a/drivers/net/wireless/ath/ath12k/mac.c
129 +++ b/drivers/net/wireless/ath/ath12k/mac.c
130 @@ -518,6 +518,18 @@ ath12k_mac_max_vht_nss(const u16 *vht_mc
135 +ath12k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
139 + for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--)
140 + if (he_mcs_mask[nss])
146 static u8 ath12k_parse_mpdudensity(u8 mpdudensity)
148 /* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing":
149 @@ -2135,9 +2147,15 @@ static void ath12k_peer_assoc_h_ht(struc
150 arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG;
153 - if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
154 - if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 |
155 - IEEE80211_HT_CAP_SGI_40))
156 + /* As firmware handles these two flags (IEEE80211_HT_CAP_SGI_20
157 + * and IEEE80211_HT_CAP_SGI_40) for enabling SGI, reset both
158 + * flags if guard interval is to force Long GI
160 + if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_FORCE_LGI) {
161 + arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40);
163 + /* Enable SGI flag if either SGI_20 or SGI_40 is supported */
164 + if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40))
165 arg->peer_rate_caps |= WMI_HOST_RC_SGI_FLAG;
168 @@ -2260,11 +2278,12 @@ static void ath12k_peer_assoc_h_vht(stru
169 struct ieee80211_link_sta *link_sta;
170 struct cfg80211_chan_def def;
171 enum nl80211_band band;
172 - const u16 *vht_mcs_mask;
178 + int i, vht_nss, nss_idx;
179 + bool user_rate_valid = true;
181 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
183 @@ -2317,6 +2336,25 @@ static void ath12k_peer_assoc_h_vht(stru
184 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160)
187 + vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask);
189 + if (vht_nss > link_sta->rx_nss) {
190 + user_rate_valid = false;
191 + for (nss_idx = link_sta->rx_nss - 1; nss_idx >= 0; nss_idx--) {
192 + if (vht_mcs_mask[nss_idx]) {
193 + user_rate_valid = true;
199 + if (!user_rate_valid) {
200 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
201 + "Setting vht range MCS value to peer supported nss:%d for peer %pM\n",
202 + link_sta->rx_nss, arsta->addr);
203 + vht_mcs_mask[link_sta->rx_nss - 1] = vht_mcs_mask[vht_nss - 1];
206 /* Calculate peer NSS capability from VHT capabilities if STA
209 @@ -2356,6 +2394,72 @@ static void ath12k_peer_assoc_h_vht(stru
210 /* TODO: rxnss_override */
213 +static int ath12k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)
215 + switch ((mcs_map >> (2 * nss)) & 0x3) {
216 + case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1;
217 + case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1;
218 + case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1;
223 +static u16 ath12k_peer_assoc_h_he_limit(u16 tx_mcs_set,
224 + const u16 *he_mcs_limit)
231 + for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
232 + mcs_map = ath12k_mac_get_max_he_mcs_map(tx_mcs_set, nss) &
236 + idx_limit = fls(mcs_map) - 1;
240 + switch (idx_limit) {
242 + mcs = IEEE80211_HE_MCS_SUPPORT_0_7;
246 + mcs = IEEE80211_HE_MCS_SUPPORT_0_9;
250 + mcs = IEEE80211_HE_MCS_SUPPORT_0_11;
256 + mcs = IEEE80211_HE_MCS_NOT_SUPPORTED;
260 + tx_mcs_set &= ~(0x3 << (nss * 2));
261 + tx_mcs_set |= mcs << (nss * 2);
268 +ath12k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
272 + for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++)
273 + if (he_mcs_mask[nss])
279 static void ath12k_peer_assoc_h_he(struct ath12k *ar,
280 struct ath12k_link_vif *arvif,
281 struct ath12k_link_sta *arsta,
282 @@ -2366,18 +2470,28 @@ static void ath12k_peer_assoc_h_he(struc
283 const struct ieee80211_sta_he_cap *he_cap;
284 struct ieee80211_bss_conf *link_conf;
285 struct ieee80211_link_sta *link_sta;
286 + struct cfg80211_chan_def def;
288 u8 ampdu_factor, max_nss;
289 u8 rx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED;
290 u8 rx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED;
291 u16 mcs_160_map, mcs_80_map;
292 + u8 link_id = arvif->link_id;
295 + enum nl80211_band band;
298 + u16 he_tx_mcs = 0, v = 0;
299 + int he_nss, nss_idx;
300 + bool user_rate_valid = true;
302 + if (WARN_ON(ath12k_mac_vif_link_chan(vif, link_id, &def)))
305 link_conf = ath12k_mac_get_link_bss_conf(arvif);
307 ath12k_warn(ar->ab, "unable to access bss link conf in peer assoc he for vif %pM link %u",
308 - vif->addr, arvif->link_id);
309 + vif->addr, link_id);
313 @@ -2392,6 +2506,12 @@ static void ath12k_peer_assoc_h_he(struc
317 + band = def.chan->band;
318 + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
320 + if (ath12k_peer_assoc_h_he_masked(he_mcs_mask))
325 support_160 = !!(he_cap->he_cap_elem.phy_cap_info[0] &
326 @@ -2497,25 +2617,47 @@ static void ath12k_peer_assoc_h_he(struc
327 if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ)
328 arg->twt_requester = true;
330 + he_nss = ath12k_mac_max_he_nss(he_mcs_mask);
332 + if (he_nss > link_sta->rx_nss) {
333 + user_rate_valid = false;
334 + for (nss_idx = link_sta->rx_nss - 1; nss_idx >= 0; nss_idx--) {
335 + if (he_mcs_mask[nss_idx]) {
336 + user_rate_valid = true;
342 + if (!user_rate_valid) {
343 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
344 + "Setting he range MCS value to peer supported nss:%d for peer %pM\n",
345 + link_sta->rx_nss, arsta->addr);
346 + he_mcs_mask[link_sta->rx_nss - 1] = he_mcs_mask[he_nss - 1];
349 switch (link_sta->bandwidth) {
350 case IEEE80211_STA_RX_BW_160:
351 if (he_cap->he_cap_elem.phy_cap_info[0] &
352 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
353 - v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80);
354 + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
355 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
357 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80);
358 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
360 arg->peer_he_mcs_count++;
363 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
364 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
366 - v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160);
367 + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
368 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
370 arg->peer_he_mcs_count++;
376 @@ -2523,11 +2665,36 @@ static void ath12k_peer_assoc_h_he(struc
377 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
379 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
380 + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask);
381 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
383 arg->peer_he_mcs_count++;
389 + /* Calculate peer NSS capability from HE capabilities if STA
392 + for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) {
393 + he_mcs = he_tx_mcs >> (2 * i) & 3;
395 + /* In case of fixed rates, MCS Range in he_tx_mcs might have
396 + * unsupported range, with he_mcs_mask set, so check either of them
399 + if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED ||
404 + max_nss = min(max_nss, ar->num_tx_chains);
405 + arg->peer_nss = min(link_sta->rx_nss, max_nss);
407 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
408 + "mac he peer %pM nss %d mcs cnt %d\n",
409 + arsta->addr, arg->peer_nss, arg->peer_he_mcs_count);
412 static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar,
413 @@ -2863,6 +3030,7 @@ static void ath12k_peer_assoc_h_phymode(
414 enum nl80211_band band;
415 const u8 *ht_mcs_mask;
416 const u16 *vht_mcs_mask;
417 + const u16 *he_mcs_mask;
418 enum wmi_phy_mode phymode = MODE_UNKNOWN;
420 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
421 @@ -2876,6 +3044,7 @@ static void ath12k_peer_assoc_h_phymode(
422 band = def.chan->band;
423 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
424 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
425 + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
427 link_sta = ath12k_mac_get_link_sta(arsta);
429 @@ -2891,7 +3060,8 @@ static void ath12k_peer_assoc_h_phymode(
430 phymode = MODE_11BE_EHT40_2G;
432 phymode = MODE_11BE_EHT20_2G;
433 - } else if (link_sta->he_cap.has_he) {
434 + } else if (link_sta->he_cap.has_he &&
435 + !ath12k_peer_assoc_h_he_masked(he_mcs_mask)) {
436 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_80)
437 phymode = MODE_11AX_HE80_2G;
438 else if (link_sta->bandwidth == IEEE80211_STA_RX_BW_40)
439 @@ -2921,7 +3091,8 @@ static void ath12k_peer_assoc_h_phymode(
440 /* Check EHT first */
441 if (link_sta->eht_cap.has_eht) {
442 phymode = ath12k_mac_get_phymode_eht(ar, link_sta);
443 - } else if (link_sta->he_cap.has_he) {
444 + } else if (link_sta->he_cap.has_he &&
445 + !ath12k_peer_assoc_h_he_masked(he_mcs_mask)) {
446 phymode = ath12k_mac_get_phymode_he(ar, link_sta);
447 } else if (link_sta->vht_cap.vht_supported &&
448 !ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
449 @@ -4190,10 +4361,13 @@ static struct ath12k_link_vif *ath12k_ma
451 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
452 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
453 + arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI;
454 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
455 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
456 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
457 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
458 + memset(arvif->bitrate_mask.control[i].he_mcs, 0xff,
459 + sizeof(arvif->bitrate_mask.control[i].he_mcs));
462 /* Allocate Default Queue now and reassign during actual vdev create */
463 @@ -5083,6 +5257,20 @@ ath12k_mac_bitrate_mask_num_vht_rates(st
467 +ath12k_mac_bitrate_mask_num_he_rates(struct ath12k *ar,
468 + enum nl80211_band band,
469 + const struct cfg80211_bitrate_mask *mask)
474 + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++)
475 + num_rates += hweight16(mask->control[band].he_mcs[i]);
481 ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_link_vif *arvif,
482 struct ath12k_link_sta *arsta,
483 const struct cfg80211_bitrate_mask *mask,
484 @@ -5128,6 +5316,60 @@ ath12k_mac_set_peer_vht_fixed_rate(struc
489 +ath12k_mac_set_peer_he_fixed_rate(struct ath12k_link_vif *arvif,
490 + struct ath12k_link_sta *arsta,
491 + const struct cfg80211_bitrate_mask *mask,
492 + enum nl80211_band band)
494 + struct ath12k *ar = arvif->ar;
498 + struct ath12k_sta *ahsta = arsta->ahsta;
499 + struct ieee80211_sta *sta;
501 + lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
503 + sta = ath12k_ahsta_to_sta(ahsta);
506 + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
507 + if (hweight16(mask->control[band].he_mcs[i]) == 1) {
509 + he_rate = ffs(mask->control[band].he_mcs[i]) - 1;
514 + ath12k_warn(ar->ab, "No single HE Fixed rate found to set for %pM",
519 + /* Avoid updating invalid nss as fixed rate*/
520 + if (nss > sta->deflink.rx_nss)
523 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
524 + "Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates",
527 + rate_code = ATH12K_HW_RATE_CODE(he_rate, nss - 1,
528 + WMI_RATE_PREAMBLE_HE);
530 + ret = ath12k_wmi_set_peer_param(ar, arsta->addr,
532 + WMI_PEER_PARAM_FIXED_RATE,
535 + ath12k_warn(ar->ab,
536 + "failed to update STA %pM Fixed Rate %d: %d\n",
537 + arsta->addr, rate_code, ret);
542 static int ath12k_mac_station_assoc(struct ath12k *ar,
543 struct ath12k_link_vif *arvif,
544 struct ath12k_link_sta *arsta,
545 @@ -5140,7 +5382,7 @@ static int ath12k_mac_station_assoc(stru
546 struct cfg80211_chan_def def;
547 enum nl80211_band band;
548 struct cfg80211_bitrate_mask *mask;
550 + u8 num_vht_rates, num_he_rates;
551 u8 link_id = arvif->link_id;
553 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
554 @@ -5180,9 +5422,10 @@ static int ath12k_mac_station_assoc(stru
557 num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask);
558 + num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask);
560 - /* If single VHT rate is configured (by set_bitrate_mask()),
561 - * peer_assoc will disable VHT. This is now enabled by a peer specific
562 + /* If single VHT/HE rate is configured (by set_bitrate_mask()),
563 + * peer_assoc will disable VHT/HE. This is now enabled by a peer specific
565 * Note that all other rates and NSS will be disabled for this peer.
567 @@ -5193,8 +5436,9 @@ static int ath12k_mac_station_assoc(stru
570 if (link_sta->vht_cap.vht_supported && num_vht_rates == 1) {
571 - ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, arsta, mask,
573 + ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, arsta, mask, band);
574 + } else if (link_sta->he_cap.has_he && num_he_rates == 1) {
575 + ret = ath12k_mac_set_peer_he_fixed_rate(arvif, arsta, mask, band);
579 @@ -5258,8 +5502,9 @@ static void ath12k_sta_rc_update_wk(stru
580 enum nl80211_band band;
581 const u8 *ht_mcs_mask;
582 const u16 *vht_mcs_mask;
583 - u32 changed, bw, nss, smps, bw_prev;
584 - int err, num_vht_rates;
585 + const u16 *he_mcs_mask;
586 + u32 changed, bw, nss, mac_nss, smps, bw_prev;
587 + int err, num_vht_rates, num_he_rates;
588 const struct cfg80211_bitrate_mask *mask;
589 enum wmi_phy_mode peer_phymode;
590 struct ath12k_link_sta *arsta;
591 @@ -5279,6 +5524,7 @@ static void ath12k_sta_rc_update_wk(stru
592 band = def.chan->band;
593 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
594 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
595 + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
597 spin_lock_bh(&ar->data_lock);
599 @@ -5293,8 +5539,10 @@ static void ath12k_sta_rc_update_wk(stru
600 spin_unlock_bh(&ar->data_lock);
602 nss = max_t(u32, 1, nss);
603 - nss = min(nss, max(ath12k_mac_max_ht_nss(ht_mcs_mask),
604 - ath12k_mac_max_vht_nss(vht_mcs_mask)));
605 + mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask),
606 + ath12k_mac_max_vht_nss(vht_mcs_mask),
607 + ath12k_mac_max_he_nss(he_mcs_mask));
608 + nss = min(nss, mac_nss);
610 struct ath12k_wmi_peer_assoc_arg *peer_arg __free(kfree) =
611 kzalloc(sizeof(*peer_arg), GFP_KERNEL);
612 @@ -5377,6 +5625,8 @@ static void ath12k_sta_rc_update_wk(stru
613 mask = &arvif->bitrate_mask;
614 num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band,
616 + num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band,
619 /* Peer_assoc_prepare will reject vht rates in
620 * bitrate_mask if its not available in range format and
621 @@ -5399,11 +5649,24 @@ static void ath12k_sta_rc_update_wk(stru
622 if (link_sta->vht_cap.vht_supported && num_vht_rates == 1) {
623 ath12k_mac_set_peer_vht_fixed_rate(arvif, arsta, mask,
625 + } else if (link_sta->he_cap.has_he && num_he_rates == 1) {
626 + ath12k_mac_set_peer_he_fixed_rate(arvif, arsta, mask, band);
628 - /* If the peer is non-VHT or no fixed VHT rate
629 + /* If the peer is non-VHT/HE or no fixed VHT/HE rate
630 * is provided in the new bitrate mask we set the
631 - * other rates using peer_assoc command.
632 + * other rates using peer_assoc command. Also clear
633 + * the peer fixed rate settings as it has higher proprity
636 + err = ath12k_wmi_set_peer_param(ar, arsta->addr,
638 + WMI_PEER_PARAM_FIXED_RATE,
639 + WMI_FIXED_RATE_NONE);
641 + ath12k_warn(ar->ab,
642 + "failed to disable peer fixed rate for STA %pM ret %d\n",
645 ath12k_peer_assoc_prepare(ar, arvif, arsta,
648 @@ -9903,19 +10166,40 @@ ath12k_mac_has_single_legacy_rate(struct
649 if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask))
652 + if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask))
655 return num_rates == 1;
659 +ath12k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
661 + if (he_cap->he_cap_elem.phy_cap_info[0] &
662 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
663 + return he_cap->he_mcs_nss_supp.tx_mcs_80p80;
665 + if (he_cap->he_cap_elem.phy_cap_info[0] &
666 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
667 + return he_cap->he_mcs_nss_supp.tx_mcs_160;
669 + return he_cap->he_mcs_nss_supp.tx_mcs_80;
673 ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar,
674 + struct ieee80211_vif *vif,
675 enum nl80211_band band,
676 const struct cfg80211_bitrate_mask *mask,
679 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
680 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
681 + const struct ieee80211_sta_he_cap *he_cap;
682 + u16 he_mcs_map = 0;
685 + u8 he_nss_mask = 0;
688 /* No need to consider legacy here. Basic rates are always present
689 @@ -9942,7 +10226,24 @@ ath12k_mac_bitrate_mask_get_single_nss(s
693 - if (ht_nss_mask != vht_nss_mask)
694 + he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);
698 + he_mcs_map = le16_to_cpu(ath12k_mac_get_tx_mcs_map(he_cap));
700 + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
701 + if (mask->control[band].he_mcs[i] == 0)
704 + if (mask->control[band].he_mcs[i] ==
705 + ath12k_mac_get_max_he_mcs_map(he_mcs_map, i))
706 + he_nss_mask |= BIT(i);
711 + if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask)
714 if (ht_nss_mask == 0)
715 @@ -9989,54 +10290,182 @@ ath12k_mac_get_single_legacy_rate(struct
719 -static int ath12k_mac_set_fixed_rate_params(struct ath12k_link_vif *arvif,
720 - u32 rate, u8 nss, u8 sgi, u8 ldpc)
722 +ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 he_gi, u8 he_ltf)
724 struct ath12k *ar = arvif->ar;
728 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
730 - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02x nss %u sgi %u\n",
731 - arvif->vdev_id, rate, nss, sgi);
732 + /* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */
733 + if (he_gi && he_gi != 0xFF)
736 - vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
737 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
739 + WMI_VDEV_PARAM_SGI, he_gi);
741 - ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",
743 + ath12k_warn(ar->ab, "failed to set HE GI:%d, error:%d\n",
748 + if (he_ltf != 0xFF)
751 - vdev_param = WMI_VDEV_PARAM_NSS;
752 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
754 + WMI_VDEV_PARAM_HE_LTF, he_ltf);
756 - ath12k_warn(ar->ab, "failed to set nss param %d: %d\n",
758 + ath12k_warn(ar->ab, "failed to set HE LTF:%d, error:%d\n",
766 +ath12k_mac_set_auto_rate_gi_ltf(struct ath12k_link_vif *arvif, u16 he_gi, u8 he_ltf)
768 + struct ath12k *ar = arvif->ar;
772 + if (he_gi != 0xFF) {
774 + case NL80211_RATE_INFO_HE_GI_0_8:
775 + he_gi = WMI_AUTORATE_800NS_GI;
777 + case NL80211_RATE_INFO_HE_GI_1_6:
778 + he_gi = WMI_AUTORATE_1600NS_GI;
780 + case NL80211_RATE_INFO_HE_GI_3_2:
781 + he_gi = WMI_AUTORATE_3200NS_GI;
784 + ath12k_warn(ar->ab, "Invalid GI\n");
789 + if (he_ltf != 0xFF) {
791 + case NL80211_RATE_INFO_HE_1XLTF:
792 + he_ltf = WMI_HE_AUTORATE_LTF_1X;
794 + case NL80211_RATE_INFO_HE_2XLTF:
795 + he_ltf = WMI_HE_AUTORATE_LTF_2X;
797 + case NL80211_RATE_INFO_HE_4XLTF:
798 + he_ltf = WMI_HE_AUTORATE_LTF_4X;
801 + ath12k_warn(ar->ab, "Invalid LTF\n");
806 + he_ar_gi_ltf = he_gi | he_ltf;
808 - vdev_param = WMI_VDEV_PARAM_SGI;
809 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
811 + WMI_VDEV_PARAM_AUTORATE_MISC_CFG,
814 - ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n",
816 + ath12k_warn(ar->ab,
817 + "failed to set HE autorate GI:%u, LTF:%u params, error:%d\n",
818 + he_gi, he_ltf, ret);
822 - vdev_param = WMI_VDEV_PARAM_LDPC;
826 +static u32 ath12k_mac_nlgi_to_wmigi(enum nl80211_txrate_gi gi)
829 + case NL80211_TXRATE_DEFAULT_GI:
830 + return WMI_GI_400_NS;
831 + case NL80211_TXRATE_FORCE_LGI:
832 + return WMI_GI_800_NS;
834 + return WMI_GI_400_NS;
838 +static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif,
839 + u32 rate, u8 nss, u8 sgi, u8 ldpc,
840 + u8 he_gi, u8 he_ltf, bool he_fixed_rate)
842 + struct ieee80211_bss_conf *link_conf;
843 + struct ath12k *ar = arvif->ar;
849 + lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
851 + link_conf = ath12k_mac_get_link_bss_conf(arvif);
855 + he_support = link_conf->he_support;
857 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
858 + "mac set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x\n",
859 + arvif->vdev_id, rate, nss, sgi, ldpc);
861 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
862 + "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi,
863 + he_ltf, he_fixed_rate);
866 + vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
867 + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
870 + ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",
876 + vdev_param = WMI_VDEV_PARAM_NSS;
878 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
882 + ath12k_warn(ar->ab, "failed to set nss param %d: %d\n",
887 + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
888 + WMI_VDEV_PARAM_LDPC, ldpc);
890 ath12k_warn(ar->ab, "failed to set ldpc param %d: %d\n",
897 + ret = ath12k_mac_set_fixed_rate_gi_ltf(arvif, he_gi, he_ltf);
899 + ret = ath12k_mac_set_auto_rate_gi_ltf(arvif, he_gi, he_ltf);
903 + vdev_param = WMI_VDEV_PARAM_SGI;
904 + param_value = ath12k_mac_nlgi_to_wmigi(sgi);
905 + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
906 + vdev_param, param_value);
908 + ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n",
917 @@ -10065,6 +10494,31 @@ ath12k_mac_vht_mcs_range_present(struct
922 +ath12k_mac_he_mcs_range_present(struct ath12k *ar,
923 + enum nl80211_band band,
924 + const struct cfg80211_bitrate_mask *mask)
929 + for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
930 + he_mcs = mask->control[band].he_mcs[i];
946 static void ath12k_mac_set_bitrate_mask_iter(void *data,
947 struct ieee80211_sta *sta)
949 @@ -10073,7 +10527,10 @@ static void ath12k_mac_set_bitrate_mask_
950 struct ath12k_link_sta *arsta;
951 struct ath12k *ar = arvif->ar;
953 - arsta = rcu_dereference(ahsta->link[arvif->link_id]);
954 + lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
956 + arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy,
957 + ahsta->link[arvif->link_id]);
958 if (!arsta || arsta->arvif != arvif)
961 @@ -10111,6 +10568,61 @@ static void ath12k_mac_disable_peer_fixe
966 +ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band band,
967 + const struct cfg80211_bitrate_mask *mask,
968 + unsigned int link_id)
970 + bool he_fixed_rate = false, vht_fixed_rate = false;
971 + const u16 *vht_mcs_mask, *he_mcs_mask;
972 + struct ieee80211_link_sta *link_sta;
973 + struct ath12k_peer *peer, *tmp;
974 + u8 vht_nss, he_nss;
977 + vht_mcs_mask = mask->control[band].vht_mcs;
978 + he_mcs_mask = mask->control[band].he_mcs;
980 + if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1)
981 + vht_fixed_rate = true;
983 + if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1)
984 + he_fixed_rate = true;
986 + if (!vht_fixed_rate && !he_fixed_rate)
989 + vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask);
990 + he_nss = ath12k_mac_max_he_nss(he_mcs_mask);
993 + spin_lock_bh(&ar->ab->base_lock);
994 + list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) {
996 + link_sta = rcu_dereference(peer->sta->link[link_id]);
1002 + if (vht_fixed_rate && (!link_sta->vht_cap.vht_supported ||
1003 + link_sta->rx_nss < vht_nss)) {
1007 + if (he_fixed_rate && (!link_sta->he_cap.has_he ||
1008 + link_sta->rx_nss < he_nss)) {
1015 + spin_unlock_bh(&ar->ab->base_lock);
1016 + rcu_read_unlock();
1021 ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
1022 struct ieee80211_vif *vif,
1023 @@ -10123,13 +10635,17 @@ ath12k_mac_op_set_bitrate_mask(struct ie
1024 enum nl80211_band band;
1025 const u8 *ht_mcs_mask;
1026 const u16 *vht_mcs_mask;
1027 + const u16 *he_mcs_mask;
1038 + bool he_fixed_rate = false;
1040 lockdep_assert_wiphy(hw->wiphy);
1042 @@ -10144,14 +10660,18 @@ ath12k_mac_op_set_bitrate_mask(struct ie
1043 band = def.chan->band;
1044 ht_mcs_mask = mask->control[band].ht_mcs;
1045 vht_mcs_mask = mask->control[band].vht_mcs;
1046 + he_mcs_mask = mask->control[band].he_mcs;
1047 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
1049 sgi = mask->control[band].gi;
1050 - if (sgi == NL80211_TXRATE_FORCE_LGI) {
1051 + if (sgi == NL80211_TXRATE_FORCE_SGI) {
1056 + he_gi = mask->control[band].he_gi;
1057 + he_ltf = mask->control[band].he_ltf;
1059 /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it
1060 * requires passing at least one of used basic rates along with them.
1061 * Fixed rate setting across different preambles(legacy, HT, VHT) is
1062 @@ -10168,18 +10688,31 @@ ath12k_mac_op_set_bitrate_mask(struct ie
1063 arvif->vdev_id, ret);
1067 ieee80211_iterate_stations_mtx(hw,
1068 ath12k_mac_disable_peer_fixed_rate,
1070 - } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask,
1071 + } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, vif, band, mask,
1073 rate = WMI_FIXED_RATE_NONE;
1075 + arvif->bitrate_mask = *mask;
1077 + ieee80211_iterate_stations_atomic(hw,
1078 + ath12k_mac_set_bitrate_mask_iter,
1081 rate = WMI_FIXED_RATE_NONE;
1082 - nss = min_t(u32, ar->num_tx_chains,
1083 - max(ath12k_mac_max_ht_nss(ht_mcs_mask),
1084 - ath12k_mac_max_vht_nss(vht_mcs_mask)));
1086 + if (!ath12k_mac_validate_fixed_rate_settings(ar, band,
1087 + mask, arvif->link_id))
1088 + ath12k_warn(ar->ab,
1089 + "failed to update fixed rate settings due to mcs/nss incompatibility\n");
1091 + mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask),
1092 + ath12k_mac_max_vht_nss(vht_mcs_mask),
1093 + ath12k_mac_max_he_nss(he_mcs_mask));
1094 + nss = min_t(u32, ar->num_tx_chains, mac_nss);
1096 /* If multiple rates across different preambles are given
1097 * we can reconfigure this info with all peers using PEER_ASSOC
1098 @@ -10211,9 +10744,21 @@ ath12k_mac_op_set_bitrate_mask(struct ie
1101 "Setting more than one MCS Value in bitrate mask not supported\n");
1107 + num_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask);
1108 + if (num_rates == 1)
1109 + he_fixed_rate = true;
1111 + if (!ath12k_mac_he_mcs_range_present(ar, band, mask) &&
1113 + ath12k_warn(ar->ab,
1114 + "Setting more than one HE MCS Value in bitrate mask not supported\n");
1118 ieee80211_iterate_stations_mtx(hw,
1119 ath12k_mac_disable_peer_fixed_rate,
1121 @@ -10224,9 +10769,10 @@ ath12k_mac_op_set_bitrate_mask(struct ie
1125 - ret = ath12k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
1126 + ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi,
1127 + he_ltf, he_fixed_rate);
1129 - ath12k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n",
1130 + ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n",
1131 arvif->vdev_id, ret);
1134 --- a/drivers/net/wireless/ath/ath12k/wmi.h
1135 +++ b/drivers/net/wireless/ath/ath12k/wmi.h
1136 @@ -220,6 +220,22 @@ enum WMI_HOST_WLAN_BAND {
1137 WMI_HOST_WLAN_2G_5G_CAP = 3,
1140 +/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command.
1141 + * Used only for HE auto rate mode.
1144 + /* HE LTF related configuration */
1145 + WMI_HE_AUTORATE_LTF_1X = BIT(0),
1146 + WMI_HE_AUTORATE_LTF_2X = BIT(1),
1147 + WMI_HE_AUTORATE_LTF_4X = BIT(2),
1149 + /* HE GI related configuration */
1150 + WMI_AUTORATE_400NS_GI = BIT(8),
1151 + WMI_AUTORATE_800NS_GI = BIT(9),
1152 + WMI_AUTORATE_1600NS_GI = BIT(10),
1153 + WMI_AUTORATE_3200NS_GI = BIT(11),
1156 enum wmi_cmd_group {
1157 /* 0 to 2 are reserved */
1158 WMI_GRP_START = 0x3,
1159 @@ -1145,7 +1161,9 @@ enum wmi_tlv_vdev_param {
1160 WMI_VDEV_PARAM_HE_RANGE_EXT,
1161 WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
1162 WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
1163 + WMI_VDEV_PARAM_HE_LTF = 0x74,
1164 WMI_VDEV_PARAM_BA_MODE = 0x7e,
1165 + WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80,
1166 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
1167 WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99,
1168 WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
1169 @@ -3579,6 +3597,15 @@ struct wmi_force_fw_hang_cmd {
1170 __le32 delay_time_ms;
1173 +/* Param values to be sent for WMI_VDEV_PARAM_SGI param_id
1174 + * which are used in 11n, 11ac systems
1175 + * @WMI_GI_800_NS - Always uses 0.8us (Long GI)
1176 + * @WMI_GI_400_NS - Firmware switches between 0.4us (Short GI)
1177 + * and 0.8us (Long GI) based on packet error rate.
1179 +#define WMI_GI_800_NS 0
1180 +#define WMI_GI_400_NS 1
1182 struct wmi_vdev_set_param_cmd {