Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Feb 2025 20:27:09 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 6062817529c8 - stable/14 - LinuxKPI: 802.11: implement various VHT helper functions
Message-ID:  <202502242027.51OKR96p027233@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=6062817529c88812af89607a0bde14720c64cc16

commit 6062817529c88812af89607a0bde14720c64cc16
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-02-12 11:05:33 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-02-24 20:26:48 +0000

    LinuxKPI: 802.11: implement various VHT helper functions
    
    Implement ieee80211_rate_set_vht(), ieee80211_rate_get_vht_{mcs,nss}(),
    and ieee80211_get_vht_max_nss().
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 5778cbdae7616c09efa6ccdd8c611d82cbc75f00)
---
 sys/compat/linuxkpi/common/include/net/mac80211.h | 136 +++++++++++++++++++---
 1 file changed, 118 insertions(+), 18 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index 8872be569e44..f5d3e1036edc 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2020-2024 The FreeBSD Foundation
+ * Copyright (c) 2020-2025 The FreeBSD Foundation
  * Copyright (c) 2020-2022 Bjoern A. Zeeb
  *
  * This software was developed by Björn Zeeb under sponsorship from
@@ -34,6 +34,7 @@
 
 #include <asm/atomic64.h>
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
@@ -1876,26 +1877,133 @@ ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
 
 /* -------------------------------------------------------------------------- */
 
-static __inline void
-ieee80211_rate_set_vht(struct ieee80211_tx_rate *r, uint32_t f1, uint32_t f2)
+static inline void
+ieee80211_rate_set_vht(struct ieee80211_tx_rate *r, uint8_t mcs, uint8_t nss)
 {
-	TODO();
+
+	/* XXX-BZ make it KASSERTS? */
+	if (((mcs & 0xF0) != 0) || (((nss - 1) & 0xf8) != 0)) {
+		printf("%s:%d: mcs %#04x nss %#04x invalid\n",
+		     __func__, __LINE__, mcs, nss);
+		return;
+	}
+
+	r->idx = mcs;
+	r->idx |= ((nss - 1) << 4);
 }
 
-static __inline uint8_t
+static inline uint8_t
 ieee80211_rate_get_vht_nss(struct ieee80211_tx_rate *r)
 {
-	TODO();
-	return (0);
+	return (((r->idx >> 4) & 0x07) + 1);
 }
 
-static __inline uint8_t
+static inline uint8_t
 ieee80211_rate_get_vht_mcs(struct ieee80211_tx_rate *r)
 {
-	TODO();
-	return (0);
+	return (r->idx & 0x0f);
 }
 
+static inline int
+ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *vht_cap,
+    enum ieee80211_vht_chanwidth chanwidth,		/* defined in net80211. */
+    int mcs /* always 0 */, bool ext_nss_bw_cap /* always true */, int max_nss)
+{
+	enum ieee80211_vht_mcs_support mcs_s;
+	uint32_t supp_cw, ext_nss_bw;
+
+	switch (mcs) {
+	case 0 ... 7:
+		mcs_s = IEEE80211_VHT_MCS_SUPPORT_0_7;
+		break;
+	case 8:
+		mcs_s = IEEE80211_VHT_MCS_SUPPORT_0_8;
+		break;
+	case 9:
+		mcs_s = IEEE80211_VHT_MCS_SUPPORT_0_9;
+		break;
+	default:
+		printf("%s: unsupported mcs value %d\n", __func__, mcs);
+		return (0);
+	}
+
+	if (max_nss == 0) {
+		uint16_t map;
+
+		map = le16toh(vht_cap->supp_mcs.rx_mcs_map);
+		for (int i = 7; i >= 0; i--) {
+			uint8_t val;
+
+			val = (map >> (2 * i)) & 0x03;
+			if (val == IEEE80211_VHT_MCS_NOT_SUPPORTED)
+				continue;
+			if (val >= mcs_s) {
+				max_nss = i + 1;
+				break;
+			}
+		}
+	}
+
+	if (max_nss == 0)
+		return (0);
+
+	if ((le16toh(vht_cap->supp_mcs.tx_mcs_map) &
+	    IEEE80211_VHT_EXT_NSS_BW_CAPABLE) == 0)
+		return (max_nss);
+
+	supp_cw = le32_get_bits(vht_cap->vht_cap_info,
+	    IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
+	ext_nss_bw = le32_get_bits(vht_cap->vht_cap_info,
+	    IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
+
+	/* If requested as ext nss not supported assume ext_nss_bw 0. */
+	if (!ext_nss_bw_cap)
+		ext_nss_bw = 0;
+
+	/*
+	 * Cover 802.11-2016, Table 9-250.
+	 */
+
+	/* Unsupported settings. */
+	if (supp_cw == 3)
+		return (0);
+	if (supp_cw == 2 && (ext_nss_bw == 1 || ext_nss_bw == 2))
+		return (0);
+
+	/* Settings with factor != 1 or unsupported. */
+	switch (chanwidth) {
+	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
+		if (supp_cw == 0 && (ext_nss_bw == 0 || ext_nss_bw == 1))
+			return (0);
+		if (supp_cw == 1 && ext_nss_bw == 0)
+			return (0);
+		if ((supp_cw == 0 || supp_cw == 1) && ext_nss_bw == 2)
+			return (max_nss / 2);
+		if ((supp_cw == 0 || supp_cw == 1) && ext_nss_bw == 3)
+			return (3 * max_nss / 4);
+		break;
+	case IEEE80211_VHT_CHANWIDTH_160MHZ:
+		if (supp_cw == 0 && ext_nss_bw == 0)
+			return (0);
+		if (supp_cw == 0 && (ext_nss_bw == 1 || ext_nss_bw == 2))
+			return (max_nss / 2);
+		if (supp_cw == 0 && ext_nss_bw == 3)
+			return (3 * max_nss / 4);
+		if (supp_cw == 1 && ext_nss_bw == 3)
+			return (2 * max_nss);
+		break;
+	case IEEE80211_VHT_CHANWIDTH_80MHZ:
+	case IEEE80211_VHT_CHANWIDTH_USE_HT:
+		if ((supp_cw == 1 || supp_cw == 2) && ext_nss_bw == 3)
+			return (2 * max_nss);
+		break;
+	}
+
+	/* Everything else has a factor of 1. */
+	return (max_nss);
+}
+
+
 static __inline void
 ieee80211_reserve_tid(struct ieee80211_sta *sta, uint8_t tid)
 {
@@ -2239,14 +2347,6 @@ ieee80211_beacon_update_cntdwn(struct ieee80211_vif *vif, uint32_t link_id)
 	return (-1);
 }
 
-static __inline int
-ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *vht_cap, uint32_t chanwidth,
-    int x, bool t, int nss)
-{
-	TODO();
-	return (-1);
-}
-
 static __inline bool
 ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif, uint32_t link_id)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502242027.51OKR96p027233>