* [PATCH 1/6] ieee80211: add EHT capabilities element definitions
2021-12-22 9:04 [PATCH 0/6] cfg80211/nl80211: add support for EHT Veerendranath Jakkam
@ 2021-12-22 9:04 ` Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities Veerendranath Jakkam
` (4 subsequent siblings)
5 siblings, 0 replies; 23+ messages in thread
From: Veerendranath Jakkam @ 2021-12-22 9:04 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
From: Vikram Kandukuri <quic_vikram@quicinc.com>
Add definitions from P802.11be_D1.3, Section 9.4.2.313 EHT Capabilities
element and related helper functions.
Signed-off-by: Vikram Kandukuri <quic_vikram@quicinc.com>
Co-authored-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Co-authored-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
---
include/linux/ieee80211.h | 702 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 702 insertions(+)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 559b6c6..5137e7d 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -20,6 +20,7 @@
#include <linux/etherdevice.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
+#include <linux/bitfield.h>
/*
* DS bit usage
@@ -2606,6 +2607,706 @@ ieee80211_he_spr_size(const u8 *he_spr_ie)
#define IEEE80211_MAX_USF FIELD_MAX(LISTEN_INT_USF)
#define IEEE80211_MAX_UI FIELD_MAX(LISTEN_INT_UI)
+/**
+ * struct ieee80211_eht_cap_elem - EHT capabilities element
+ *
+ * @mac_cap_info: EHT MAC Capabilities Information
+ * @phy_cap_info: EHT PHY Capabilities Information
+ *
+ * This structure represents the "EHT capabilities element" fixed fields as
+ * described in P802.11be_D1.3 section 9.4.2.313.2 and 9.4.2.313.3.
+ */
+struct ieee80211_eht_cap_elem {
+ u8 mac_cap_info[2];
+ u8 phy_cap_info[8];
+} __packed;
+
+/* 802.11be EHT MAC capabilities from P802.11be_D1.3, section 9.4.2.313.2 */
+#define IEEE80211_EHT_MAC_CAP0_NSEP_PRIORITY_ACCESS BIT(0)
+#define IEEE80211_EHT_MAC_CAP0_EHT_OM_CONTROL BIT(1)
+#define IEEE80211_EHT_MAC_CAP0_TXOP_SHARING_MODE1 BIT(2)
+#define IEEE80211_EHT_MAC_CAP0_TXOP_SHARING_MODE2 BIT(3)
+#define IEEE80211_EHT_MAC_CAP0_RESTRICTED_TWT BIT(4)
+#define IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC BIT(5)
+
+#define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN GENMASK(7, 6)
+
+/**
+ * enum ieee80211_eht_max_mpdu_len - maximum MPDU length that STA is capable of
+ * receiving
+ * @EHT_MAX_MPDU_LEN_3895: maximum 3895 octets supported
+ * @EHT_MAX_MPDU_LEN_7991: maximum 7991 octets supported
+ * @EHT_MAX_MPDU_LEN_11454: maximum 11454 octets supported
+ */
+enum ieee80211_eht_max_mpdu_len {
+ EHT_MAX_MPDU_LEN_3895 = 0,
+ EHT_MAX_MPDU_LEN_7991,
+ EHT_MAX_MPDU_LEN_11454,
+};
+
+/**
+ * ieee80211_eht_set_max_mpdu_len - set maximum MPDU length that STA is capable
+ * of receiving
+ *
+ * @mac_cap_info: EHT MAC capabilities information field data
+ * @max_len: maximum MPDU length supported, see &enum ieee80211_eht_max_mpdu_len
+ *
+ * Set "Maximum MPDU Length" subfield as encoded in "EHT MAC Capabilities
+ * Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_max_mpdu_len(u8 *mac_cap_info,
+ enum ieee80211_eht_max_mpdu_len max_len)
+{
+ mac_cap_info[0] |= FIELD_PREP(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN,
+ max_len);
+}
+
+/**
+ * ieee80211_eht_get_max_mpdu_len - get maximum MPDU length that STA is capable
+ * of receiving
+ *
+ * @mac_cap_info: EHT MAC capabilities information field data
+ *
+ * Get "Maximum MPDU Length" subfield value from "EHT MAC Capabilities
+ * Information" field in EHT Capabilities element
+ *
+ * Return: maximum MPDU length supported, see &enum ieee80211_eht_max_mpdu_len
+ */
+static inline enum ieee80211_eht_max_mpdu_len
+ieee80211_eht_get_max_mpdu_len(const u8 *mac_cap_info)
+{
+ return FIELD_GET(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN, mac_cap_info[0]);
+}
+
+/* 802.11be EHT PHY capabilities from P802.11be_D1.3, section 9.4.2.313.3 */
+#define IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ BIT(1)
+#define IEEE80211_EHT_PHY_CAP0_NON_AP_20MHZ_ONLY_STA_242_RU_SUPPORT BIT(2)
+#define IEEE80211_EHT_PHY_CAP0_NDP_4x_LTF_AND_3_2US BIT(3)
+#define IEEE80211_EHT_PHY_CAP0_PARTIAL_BANDWIDTH_UL_MUMIMO BIT(4)
+#define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER BIT(5)
+#define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE BIT(6)
+
+/* Beamformee SS for under 80MHz is split between byte #1 and byte #2 */
+#define IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_MAX_STS_UPTO_80MHZ GENMASK(7, 7)
+#define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_UPTO_80MHZ GENMASK(1, 0)
+#define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_160MHZ GENMASK(4, 2)
+#define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_320MHZ GENMASK(7, 5)
+
+#define IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_UPTO_80MHZ \
+ GENMASK(2, 0)
+#define IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_160MHZ GENMASK(5, 3)
+
+/*
+ * Number of sounding dimensions supported for 320MHz is split
+ * between byte #2 and byte #3
+ */
+#define IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_320MHZ GENMASK(7, 6)
+#define IEEE80211_EHT_PHY_CAP3_BEAMFORMER_NUM_SND_DIM_320MHZ GENMASK(0, 0)
+
+#define IEEE80211_EHT_PHY_CAP3_NG16_SU_FEEDBACK BIT(1)
+#define IEEE80211_EHT_PHY_CAP3_NG16_MU_FEEDBACK BIT(2)
+
+#define IEEE80211_EHT_PHY_CAP3_CODEBOOK_SIZE_42_SU BIT(3)
+#define IEEE80211_EHT_PHY_CAP3_CODEBOOK_SIZE_75_MU BIT(4)
+
+#define IEEE80211_EHT_PHY_CAP3_TRIG_SU_BEAMFORMER_FB BIT(5)
+#define IEEE80211_EHT_PHY_CAP3_TRIG_MU_BEAMFORMER_FB BIT(6)
+#define IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FB BIT(7)
+
+#define IEEE80211_EHT_PHY_CAP4_PARTIAL_BANDWIDTH_DL_MUMIMO BIT(0)
+#define IEEE80211_EHT_PHY_CAP4_PSR_BASED_SR BIT(1)
+#define IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACTOR_AR BIT(2)
+#define IEEE80211_EHT_PHY_CAP4_MU_PPDU_4XLTF_AND_08_US_GI BIT(3)
+
+#define IEEE80211_EHT_PHY_CAP4_MAX_NC GENMASK(7, 4)
+
+#define IEEE80211_EHT_PHY_CAP5_NON_TRIGGERED_CQI_FEEDBACK BIT(0)
+#define IEEE80211_EHT_PHY_CAP5_TX_1024_4096_QAM_LESS_THAN_242_TONE_RU BIT(1)
+#define IEEE80211_EHT_PHY_CAP5_RX_1024_4096_QAM_LESS_THAN_242_TONE_RU BIT(2)
+#define IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT BIT(3)
+
+#define IEEE80211_EHT_PHY_CAP5_NOMINAL_PKT_PADDING GENMASK(5, 4)
+
+/* Maximum Number Of Supported EHT-LTFs is split between byte 5 and byte 6 */
+#define IEEE80211_EHT_PHY_CAP5_MAX_EHT_LTF_SUPP BIT(6)
+#define IEEE80211_EHT_PHY_CAP5_MAX_EHT_LTF_SUPP_SU GENMASK(7, 7)
+#define IEEE80211_EHT_PHY_CAP6_MAX_EHT_LTF_SUPP_SU_RESERVED GENMASK(0, 0)
+#define IEEE80211_EHT_PHY_CAP6_MAX_EHT_LTF_SUPP_MU GENMASK(2, 1)
+
+#define IEEE80211_EHT_PHY_CAP6_MCS15_52_26_TONE_106_26_TONE_SUPP BIT(3)
+#define IEEE80211_EHT_PHY_CAP6_MCS15_484_242_TONE_80MHZ_SUPP BIT(4)
+#define IEEE80211_EHT_PHY_CAP6_MCS15_996_484_TONE_160MHZ_SUPP BIT(5)
+#define IEEE80211_EHT_PHY_CAP6_MCS15_3X996_TONE_320MHZ_SUPP BIT(6)
+#define IEEE80211_EHT_PHY_CAP6_EHT_DUP_SUPP_6GHZ BIT(7)
+
+#define IEEE80211_EHT_PHY_CAP7_20MHZ_STA_NDP_WIDE_BW_SUPP BIT(0)
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_UNDER_80MHZ BIT(1)
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ BIT(2)
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ BIT(3)
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_MU_BEAMFORMER_UNDER_80MHZ BIT(4)
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_MU_BEAMFORMER_160MHZ BIT(5)
+#define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_MU_BEAMFORMER_320MHZ BIT(6)
+#define IEEE80211_EHT_PHY_CAP7_TB_SND_FB_RATE_LIMIT BIT(7)
+
+/**
+ * enum ieee80211_eht_beamformee_max_sts - maximum number of spatial streams
+ * that the STA is capable of receiving in an EHT sounding NDP. Minimal
+ * allowed spatial streams is 4.
+ * @EHT_BEAMFORMEE_MAX_STS_4: 4 spatial streams supported
+ * @EHT_BEAMFORMEE_MAX_STS_5: 5 spatial streams supported
+ * @EHT_BEAMFORMEE_MAX_STS_6: 6 spatial streams supported
+ * @EHT_BEAMFORMEE_MAX_STS_7: 7 spatial streams supported
+ * @EHT_BEAMFORMEE_MAX_STS_8: 8 spatial streams supported
+ */
+enum ieee80211_eht_beamformee_max_sts {
+ EHT_BEAMFORMEE_MAX_STS_4 = 3,
+ EHT_BEAMFORMEE_MAX_STS_5 = 4,
+ EHT_BEAMFORMEE_MAX_STS_6 = 5,
+ EHT_BEAMFORMEE_MAX_STS_7 = 6,
+ EHT_BEAMFORMEE_MAX_STS_8 = 7,
+};
+
+/**
+ * ieee80211_eht_beamformee_set_max_sts_upto_80mhz - set maximum number of
+ * spatial streams that the STA is capable of receiving in an EHT sounding
+ * NDP for bandwidths upto 80 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @max_sts: maximum number of spatial streams supported, see &enum
+ * ieee80211_eht_beamformee_max_sts
+ *
+ * Set "Beamformee SS upto 80 MHz" subfield as encoded in "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_beamformee_set_max_sts_upto_80mhz(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_beamformee_max_sts max_sts)
+{
+ phy_cap_info[0] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_MAX_STS_UPTO_80MHZ,
+ max_sts);
+
+ phy_cap_info[1] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_UPTO_80MHZ,
+ max_sts >> 1);
+}
+
+/**
+ * ieee80211_eht_beamformee_get_max_sts_upto_80mhz - get maximum number of
+ * spatial streams that the STA is capable of receiving in an EHT sounding
+ * NDP for bandwidths upto 80 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Beamformee SS upto 80 MHz" subfield value from "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ *
+ * Return: maximum number of spatial streams supported, see &enum
+ * ieee80211_eht_beamformee_max_sts
+ */
+static inline enum ieee80211_eht_beamformee_max_sts
+ieee80211_eht_beamformee_get_max_sts_upto_80mhz(const u8 *phy_cap_info)
+{
+
+ u8 max_sts = FIELD_GET(
+ IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_MAX_STS_UPTO_80MHZ,
+ phy_cap_info[0]);
+
+ max_sts += FIELD_GET(
+ IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_UPTO_80MHZ,
+ phy_cap_info[1]) << 1;
+
+ return max_sts;
+}
+
+/**
+ * ieee80211_eht_beamformee_set_max_sts_160mhz - set maximum number of spatial
+ * streams that the STA is capable of receiving in an EHT sounding NDP for
+ * bandwidth 160 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @max_sts: maximum number of spatial streams supported, see &enum
+ * ieee80211_eht_beamformee_max_sts
+ *
+ * Set "Beamformee SS for 160 MHz" subfield as encoded in "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_beamformee_set_max_sts_160mhz(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_beamformee_max_sts max_sts)
+{
+ phy_cap_info[1] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_160MHZ, max_sts);
+}
+
+/**
+ * ieee80211_eht_beamformee_get_max_sts_160mhz - get maximum number of spatial
+ * streams that the STA is capable of receiving in an EHT sounding NDP for
+ * bandwidth 160 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Beamformee SS for 160 MHz" subfield value from "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ *
+ * Return: maximum number of spatial streams supported, see &enum
+ * ieee80211_eht_beamformee_max_sts
+ */
+static inline enum ieee80211_eht_beamformee_max_sts
+ieee80211_eht_beamformee_get_max_sts_160mhz(const u8 *phy_cap_info)
+{
+
+ return FIELD_GET(IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_160MHZ,
+ phy_cap_info[1]);
+}
+
+/**
+ * ieee80211_eht_beamformee_set_max_sts_320mhz - set maximum number of spatial
+ * streams that the STA is capable of receiving in an EHT sounding NDP for
+ * bandwidth 320 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @max_sts: maximum number of spatial streams supported, see &enum
+ * ieee80211_eht_beamformee_max_sts
+ *
+ * Set "Beamformee SS for 320 MHz" subfield as encoded in "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_beamformee_set_max_sts_320mhz(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_beamformee_max_sts max_sts)
+{
+ phy_cap_info[1] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_320MHZ, max_sts);
+}
+
+/**
+ * ieee80211_eht_beamformee_get_max_sts_320mhz - get maximum number of spatial
+ * streams that the STA is capable of receiving in an EHT sounding NDP for
+ * bandwidth 320 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Beamformee SS for 320 MHz" subfield value from "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ *
+ * Return: maximum number of spatial streams supported, see &enum
+ * ieee80211_eht_beamformee_max_sts
+ */
+static inline enum ieee80211_eht_beamformee_max_sts
+ieee80211_eht_beamformee_get_max_sts_320mhz(const u8 *phy_cap_info)
+{
+
+ return FIELD_GET(IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_MAX_STS_320MHZ,
+ phy_cap_info[1]);
+}
+
+/**
+ * enum ieee80211_eht_beamformer_snd_dim - Beamformer number of supported
+ * sounding dimensions
+ * @EHT_BEAMFORMER_SND_DIM_1: 1 sounding dimension supported
+ * @EHT_BEAMFORMER_SND_DIM_2: 2 sounding dimensions supported
+ * @EHT_BEAMFORMER_SND_DIM_3: 3 sounding dimensions supported
+ * @EHT_BEAMFORMER_SND_DIM_4: 4 sounding dimensions supported
+ * @EHT_BEAMFORMER_SND_DIM_5: 5 sounding dimensions supported
+ * @EHT_BEAMFORMER_SND_DIM_6: 6 sounding dimensions supported
+ * @EHT_BEAMFORMER_SND_DIM_7: 7 sounding dimensions supported
+ * @EHT_BEAMFORMER_SND_DIM_8: 8 sounding dimensions supported
+ */
+enum ieee80211_eht_beamformer_snd_dim {
+ EHT_BEAMFORMER_SND_DIM_1 = 0,
+ EHT_BEAMFORMER_SND_DIM_2,
+ EHT_BEAMFORMER_SND_DIM_3,
+ EHT_BEAMFORMER_SND_DIM_4,
+ EHT_BEAMFORMER_SND_DIM_5,
+ EHT_BEAMFORMER_SND_DIM_6,
+ EHT_BEAMFORMER_SND_DIM_7,
+ EHT_BEAMFORMER_SND_DIM_8,
+};
+
+/**
+ * ieee80211_eht_set_snd_dim_upto_80mhz - set number of sounding dimensions
+ * supported upto 80 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @num_snd_dim: number of sounding dimensions supported, see &enum
+ * ieee80211_eht_beamformer_snd_dim
+ *
+ * Set "Number Of Sounding Dimensions for upto 80 MHz" subfield as encoded in
+ * "EHT PHY Capabilities Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_snd_dim_upto_80mhz(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_beamformer_snd_dim num_snd_dim)
+{
+ phy_cap_info[2] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_UPTO_80MHZ,
+ num_snd_dim);
+}
+
+/**
+ * ieee80211_eht_get_snd_dim_upto_80mhz - get number of sounding dimensions
+ * supported upto 80 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Number Of Sounding Dimensions upto 80 MHz" subfield value from "EHT PHY
+ * Capabilities Information" field in EHT Capabilities element
+ *
+ * Return: number of sounding dimensions supported, see &enum
+ * ieee80211_eht_beamformer_snd_dim
+ */
+static inline enum ieee80211_eht_beamformer_snd_dim
+ieee80211_eht_get_snd_dim_upto_80mhz(const u8 *phy_cap_info)
+{
+ return FIELD_GET(
+ IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_UPTO_80MHZ,
+ phy_cap_info[2]);
+}
+
+/**
+ * ieee80211_eht_set_snd_dim_160mhz - set number of sounding dimensions
+ * supported upto 160 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @num_snd_dim: number of sounding dimensions supported, see &enum
+ * ieee80211_eht_beamformer_snd_dim
+ *
+ * Set "Number Of Sounding Dimensions for 160 MHz" subfield as encoded in "EHT
+ * PHY Capabilities Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_snd_dim_160mhz(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_beamformer_snd_dim num_snd_dim)
+{
+ phy_cap_info[2] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_160MHZ,
+ num_snd_dim);
+}
+
+/**
+ * ieee80211_eht_get_snd_dim_160mhz - get number of sounding dimensions
+ * supported for 160 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Number Of Sounding Dimensions for 160 MHz" subfield value from "EHT PHY
+ * Capabilities Information" field in EHT Capabilities element
+ *
+ * Return: number of sounding dimensions supported, see &enum
+ * ieee80211_eht_beamformer_snd_dim
+ */
+static inline enum ieee80211_eht_beamformer_snd_dim
+ieee80211_eht_get_snd_dim_160mhz(const u8 *phy_cap_info)
+{
+ return FIELD_GET(
+ IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_160MHZ,
+ phy_cap_info[2]);
+}
+
+/**
+ * ieee80211_eht_set_snd_dim_320mhz - set number of sounding dimensions
+ * supported for 320 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @num_snd_dim: number of sounding dimensions supported, &enum
+ * ieee80211_eht_beamformer_snd_dim
+ *
+ * Set "Number Of Sounding Dimensions for 320 MHz" subfield as encoded in "EHT
+ * PHY Capabilities Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_max_snd_dim_320(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_beamformer_snd_dim num_snd_dim)
+{
+ phy_cap_info[2] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_320MHZ,
+ num_snd_dim);
+
+ phy_cap_info[3] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP3_BEAMFORMER_NUM_SND_DIM_320MHZ,
+ num_snd_dim >> 2);
+}
+
+/**
+ * ieee80211_eht_get_snd_dim_320mhz - get number of sounding dimensions
+ * supported for 320 MHz
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Number Of Sounding Dimensions for 320 MHz" subfield value from "EHT
+ * PHY Capabilities Information" field in EHT Capabilities element
+ *
+ * Return: number of sounding dimensions supported, &enum
+ * ieee80211_eht_beamformer_snd_dim
+ */
+static inline enum ieee80211_eht_beamformer_snd_dim
+ieee80211_eht_get_max_snd_dim_320(const u8 *phy_cap_info)
+{
+ u8 num_snd_dim =
+ FIELD_GET(IEEE80211_EHT_PHY_CAP2_BEAMFORMER_NUM_SND_DIM_320MHZ,
+ phy_cap_info[2]);
+
+ if (FIELD_GET(IEEE80211_EHT_PHY_CAP3_BEAMFORMER_NUM_SND_DIM_320MHZ,
+ phy_cap_info[3]))
+ num_snd_dim += 4;
+
+ return num_snd_dim;
+}
+
+/**
+ * enum ieee80211_eht_max_nc - maximum supported Nc definitions
+ * @EHT_MAX_NC_1: maximum 1 Nc supported
+ * @EHT_MAX_NC_2: maximum 2 Nc supported
+ * @EHT_MAX_NC_3: maximum 3 Nc supported
+ * @EHT_MAX_NC_4: maximum 4 Nc supported
+ * @EHT_MAX_NC_5: maximum 5 Nc supported
+ * @EHT_MAX_NC_6: maximum 6 Nc supported
+ * @EHT_MAX_NC_7: maximum 7 Nc supported
+ * @EHT_MAX_NC_8: maximum 8 Nc supported
+ */
+enum ieee80211_eht_max_nc {
+ EHT_MAX_NC_1 = 0,
+ EHT_MAX_NC_2,
+ EHT_MAX_NC_3,
+ EHT_MAX_NC_4,
+ EHT_MAX_NC_5,
+ EHT_MAX_NC_6,
+ EHT_MAX_NC_7,
+ EHT_MAX_NC_8,
+};
+
+/**
+ * ieee80211_eht_set_max_nc - set maximum supported Nc
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @max_nc: Maximum supported Nc, see &enum ieee80211_eht_max_nc
+ *
+ * Set "Max Nc" subfield as encoded in "EHT PHY Capabilities Information" field
+ * in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_max_nc(u8 *phy_cap_info, enum ieee80211_eht_max_nc max_nc)
+{
+ phy_cap_info[4] |= FIELD_PREP(IEEE80211_EHT_PHY_CAP4_MAX_NC, max_nc);
+}
+
+/**
+ * ieee80211_eht_get_max_nc - get maximum supported Nc
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Get "Max Nc" subfield value from "EHT PHY Capabilities Information" field
+ * in EHT Capabilities element
+ *
+ * Return: Max supported Nc, see &enum ieee80211_eht_max_nc
+ */
+static inline enum ieee80211_eht_max_nc
+ieee80211_eht_get_max_nc(const u8 *phy_cap_info)
+{
+ return FIELD_GET(IEEE80211_EHT_PHY_CAP4_MAX_NC, phy_cap_info[4]);
+}
+
+/**
+ * enum ieee80211_eht_nominal_pkt_padding - EHT nominal packet padding
+ * definitions
+ * @EHT_NOMINAL_PKT_PADDING_0US - 0 us common nominal packet padding
+ * @EHT_NOMINAL_PKT_PADDING_8US - 8 us common nominal packet padding
+ * @EHT_NOMINAL_PKT_PADDING_16US - 16 us common nominal packet padding
+ * @EHT_NOMINAL_PKT_PADDING_16US_OR_20US - 16 us common nominal packet padding
+ * for all modes with constellation <= 1024, nss <= 8, RU/MRU <= 2x996 and
+ * 20 us for all other modes
+ */
+enum ieee80211_eht_nominal_pkt_padding {
+ EHT_NOMINAL_PKT_PADDING_0US = 0,
+ EHT_NOMINAL_PKT_PADDING_8US,
+ EHT_NOMINAL_PKT_PADDING_16US,
+ EHT_NOMINAL_PKT_PADDING_16US_OR_20US,
+};
+
+/**
+ * ieee80211_eht_set_common_nominal_pkt_padding - set EHT common nominal packet
+ * padding.
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @nominal_pkt_pad: common nominal packet padding, see &enum
+ * ieee80211_eht_nominal_pkt_padding
+ *
+ * Set "Common Nominal Packet Padding" subfield as encoded in "EHT PHY
+ * Capabilities Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_common_nominal_pkt_padding(
+ u8 *phy_cap_info,
+ enum ieee80211_eht_nominal_pkt_padding nominal_pkt_pad)
+{
+ phy_cap_info[5] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP5_NOMINAL_PKT_PADDING, nominal_pkt_pad);
+}
+
+/**
+ * ieee80211_eht_get_common_nominal_pkt_padding - get EHT common nominal packet
+ * padding.
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ *
+ * Set "Common Nominal Packet Padding" subfield value from "EHT PHY Capabilities
+ * Information" field in EHT Capabilities element
+ *
+ * Return: EHT common nominal packet padding capability, see &enum
+ * ieee80211_eht_nominal_pkt_padding
+ */
+static inline enum ieee80211_eht_nominal_pkt_padding
+ieee80211_eht_get_common_nominal_pkt_padding(const u8 *phy_cap_info)
+{
+ return FIELD_GET(IEEE80211_EHT_PHY_CAP5_NOMINAL_PKT_PADDING,
+ phy_cap_info[5]);
+}
+
+/**
+ * enum ieee80211_eht_max_ltf_supp - EHT maximum LTF support definitions
+ * @EHT_MAX_4XLTF_SUPP - Maximum of four EHT-LTFs supported
+ * @EHT_MAX_8XLTF_SUPP - Maximum of eight EHT-LTFs supported
+ */
+enum ieee80211_eht_max_ltf_supp {
+ EHT_MAX_4XLTF_SUPP = 0,
+ EHT_MAX_8XLTF_SUPP,
+};
+
+/**
+ * ieee80211_eht_set_max_eht_ltf_supp - set maximum number of supported EHT-LTFs
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @mu: Multiple user configuration
+ * @max_ltf: Maximum number of EHT-LTFs supported, see &enum
+ * ieee80211_eht_max_ltf_supp
+ *
+ * Set "Maximum Number Of Supported EHT-LTFs" subfield as encoded in "EHT PHY
+ * Capabilities Information" field in EHT Capabilities element
+ */
+static inline void
+ieee80211_eht_set_max_eht_ltf_supp(u8 *phy_cap_info, bool mu,
+ enum ieee80211_eht_max_ltf_supp max_ltf)
+{
+
+ if (mu) {
+ phy_cap_info[6] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP6_MAX_EHT_LTF_SUPP_MU, max_ltf);
+ return;
+ }
+
+ phy_cap_info[5] |=
+ FIELD_PREP(IEEE80211_EHT_PHY_CAP5_MAX_EHT_LTF_SUPP_SU, max_ltf);
+}
+
+/**
+ * ieee80211_eht_get_max_eht_ltf_supp - get maximum number of supported EHT-LTFs
+ *
+ * @phy_cap_info: EHT PHY capabilities information field data
+ * @mu: Multiple user configuration
+ *
+ * Get "Maximum Number Of Supported EHT-LTFs" subfield value from "EHT PHY
+ * Capabilities Information" field in EHT Capabilities element
+ *
+ * Return: Maximum number of EHT-LTFs supported, see &enum
+ * ieee80211_eht_max_ltf_supp
+ */
+static inline enum ieee80211_eht_max_ltf_supp
+ieee80211_eht_get_max_eht_ltf_supp(const u8 *phy_cap_info, bool mu)
+{
+ if (mu)
+ return FIELD_GET(IEEE80211_EHT_PHY_CAP6_MAX_EHT_LTF_SUPP_MU,
+ phy_cap_info[6]);
+
+ return FIELD_GET(IEEE80211_EHT_PHY_CAP5_MAX_EHT_LTF_SUPP_SU,
+ phy_cap_info[5]);
+}
+
+/**
+ * ieee80211_eht_mcs_nss_size - Get EHT MCS NSS Support Field size
+ *
+ * @eht_cap: EHT capabilities element
+ * @he_cap: HE capabilities element
+ *
+ * Calculate Tx/Rx EHT MCS NSS Support Field size in EHT capabilities IE
+ *
+ * Return: EHT MCS NSS Support Field size
+ */
+static inline u8
+ieee80211_eht_mcs_nss_size(const struct ieee80211_eht_cap_elem *eht_cap,
+ const struct ieee80211_he_cap_elem *he_cap)
+{
+ if ((he_cap->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 |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)) == 0)
+ return 4;
+
+ if (eht_cap->phy_cap_info[0] & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ)
+ return 9;
+
+ if (he_cap->phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ return 6;
+
+ return 3;
+}
+
+/* EHT PPE Thresholds from P802.11be_D1.3, section 9.4.2.313.5 */
+#define IEEE80211_EHT_PPE_THRES0_NSS GENMASK(3, 0)
+
+/* RU Index Bitmask is split between byte 0 and byte 1 */
+#define IEEE80211_EHT_PPE_THRES0_RU_INDEX GENMASK(7, 4)
+#define IEEE80211_EHT_PPE_THRES1_RU_INDEX BIT(0)
+
+/* PPE Thresholds Information subfields size in number of bits */
+#define IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE 9
+#define IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE 6
+
+/**
+ * ieee80211_eht_ppe_size - Get EHT PPE Thresholds Info Field size
+ *
+ * @ppe_thres_hdr: Header bytes of PPE Thresholds field
+ * @phy_cap_info: EHT PHY capabilities information
+ *
+ * Calculate EHT PPE Thresholds Info Field size in EHT capabilities IE
+ *
+ * Return: EHT PPE Thresholds Info Field size
+ */
+static inline u8
+ieee80211_eht_ppe_size(const u8 *ppe_thres_hdr, const u8 *phy_cap_info)
+{
+ u8 n;
+
+ if ((phy_cap_info[5] &
+ IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) == 0)
+ return 0;
+
+ n = hweight8(FIELD_GET(IEEE80211_EHT_PPE_THRES0_RU_INDEX,
+ ppe_thres_hdr[0]));
+ n += hweight8(FIELD_GET(IEEE80211_EHT_PPE_THRES1_RU_INDEX,
+ ppe_thres_hdr[1]));
+
+ n *= (1 + FIELD_GET(IEEE80211_EHT_PPE_THRES0_NSS, ppe_thres_hdr[0]));
+
+ /**
+ * Each pair is 6 bits, and we need to add the 9 "header" bits to the
+ * total size.
+ */
+ n = (n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE) +
+ IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
+ n = DIV_ROUND_UP(n, 8);
+
+ return n;
+}
+
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
@@ -3054,6 +3755,7 @@ enum ieee80211_eid_ext {
WLAN_EID_EXT_SHORT_SSID_LIST = 58,
WLAN_EID_EXT_HE_6GHZ_CAPA = 59,
WLAN_EID_EXT_UL_MU_POWER_CAPA = 60,
+ WLAN_EID_EXT_EHT_CAPABILITY = 108,
};
/* Action category code */
--
2.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities
2021-12-22 9:04 [PATCH 0/6] cfg80211/nl80211: add support for EHT Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 1/6] ieee80211: add EHT capabilities element definitions Veerendranath Jakkam
@ 2021-12-22 9:04 ` Veerendranath Jakkam
2022-02-10 5:14 ` Aloka Dixit (QUIC)
2021-12-22 9:04 ` [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace Veerendranath Jakkam
` (3 subsequent siblings)
5 siblings, 1 reply; 23+ messages in thread
From: Veerendranath Jakkam @ 2021-12-22 9:04 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
From: Vikram Kandukuri <quic_vikram@quicinc.com>
Add nl80211 support to advertise EHT capabilities to the userspace.
Add new attributes in enum nl80211_band_iftype_attr to indicate EHT MAC
capabilities, PHY capabilities, supported MCC-NSS set and PPE threshold
fields.
Signed-off-by: Vikram Kandukuri <quic_vikram@quicinc.com>
Co-authored-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Co-authored-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
---
include/net/cfg80211.h | 56 ++++++++++++++++++++++++++++++++++++++++++++
include/uapi/linux/nl80211.h | 12 ++++++++++
net/wireless/nl80211.c | 17 ++++++++++++++
3 files changed, 85 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d19e48f..df197c6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -361,6 +361,28 @@ struct ieee80211_sta_he_cap {
};
/**
+ * struct ieee80211_sta_eht_cap - STA's EHT capabilities
+ *
+ * This structure describes parameters needed to describe 802.11be EHT
+ * capabilities for a STA.
+ *
+ * @has_eht: true if EHT data is valid.
+ * @eht_cap_elem: Fixed portion of the EHT capabilities element.
+ * @mcs_nss: The supported NSS/MCS combinations.
+ * @mcs_nss_len: Length of NSS/MCS combinations data.
+ * @ppe_thres: Holds the PPE Thresholds data.
+ * @ppe_thres_len: Length PPE Thresholds data.
+ */
+struct ieee80211_sta_eht_cap {
+ bool has_eht;
+ struct ieee80211_eht_cap_elem eht_cap_elem;
+ u8 *mcs_nss;
+ u8 mcs_nss_len;
+ u8 *ppe_thres;
+ u8 ppe_thres_len;
+};
+
+/**
* struct ieee80211_sband_iftype_data - sband data per interface type
*
* This structure encapsulates sband data that is relevant for the
@@ -374,6 +396,7 @@ struct ieee80211_sta_he_cap {
* @vendor_elems: vendor element(s) to advertise
* @vendor_elems.data: vendor element(s) data
* @vendor_elems.len: vendor element(s) length
+ * @eht_cap: holds the EHT capabilities.
*/
struct ieee80211_sband_iftype_data {
u16 types_mask;
@@ -383,6 +406,7 @@ struct ieee80211_sband_iftype_data {
const u8 *data;
unsigned int len;
} vendor_elems;
+ struct ieee80211_sta_eht_cap eht_cap;
};
/**
@@ -522,6 +546,38 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
}
/**
+ * ieee80211_get_eht_iftype_cap - return EHT capabilities for an sband's iftype
+ * @sband: the sband to search for the iftype on
+ * @iftype: enum nl80211_iftype
+ *
+ * Return: pointer to the struct ieee80211_sta_eht_cap, or NULL is none found
+ */
+static inline const struct ieee80211_sta_eht_cap *
+ieee80211_get_eht_iftype_cap(const struct ieee80211_supported_band *sband,
+ u8 iftype)
+{
+ const struct ieee80211_sband_iftype_data *data =
+ ieee80211_get_sband_iftype_data(sband, iftype);
+
+ if (data && data->eht_cap.has_eht)
+ return &data->eht_cap;
+
+ return NULL;
+}
+
+/**
+ * ieee80211_get_eht_sta_cap - return EHT capabilities for an sband's STA
+ * @sband: the sband to search for the STA on
+ *
+ * Return: pointer to the struct ieee80211_sta_eht_cap, or NULL is none found
+ */
+static inline const struct ieee80211_sta_eht_cap *
+ieee80211_get_eht_sta_cap(const struct ieee80211_supported_band *sband)
+{
+ return ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_STATION);
+}
+
+/**
* ieee80211_get_he_iftype_cap - return HE capabilities for an sband's iftype
* @sband: the sband to search for the iftype on
* @iftype: enum nl80211_iftype
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f1a9d65..a709f5c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3766,6 +3766,14 @@ enum nl80211_mpath_info {
* given for all 6 GHz band channels
* @NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS: vendor element capabilities that are
* advertised on this band/for this iftype (binary)
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC: EHT MAC capabilities as in EHT
+ * capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY: EHT PHY capabilities as in EHT
+ * capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET: EHT supported NSS/MCS as in EHT
+ * capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE: EHT PPE thresholds information as
+ * defined in EHT capabilities IE
* @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
* @NL80211_BAND_IFTYPE_ATTR_MAX: highest band attribute currently defined
*/
@@ -3779,6 +3787,10 @@ enum nl80211_band_iftype_attr {
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
/* keep last */
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 578bff9..0ece4d3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1729,6 +1729,7 @@ nl80211_send_iftype_data(struct sk_buff *msg,
const struct ieee80211_sband_iftype_data *iftdata)
{
const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
+ const struct ieee80211_sta_eht_cap *eht_cap = &iftdata->eht_cap;
if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
iftdata->types_mask))
@@ -1755,6 +1756,22 @@ nl80211_send_iftype_data(struct sk_buff *msg,
&iftdata->he_6ghz_capa))
return -ENOBUFS;
+ if (eht_cap->has_eht) {
+ if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
+ sizeof(eht_cap->eht_cap_elem.mac_cap_info),
+ eht_cap->eht_cap_elem.mac_cap_info) ||
+ nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
+ sizeof(eht_cap->eht_cap_elem.phy_cap_info),
+ eht_cap->eht_cap_elem.phy_cap_info) ||
+ (eht_cap->mcs_nss_len &&
+ nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
+ eht_cap->mcs_nss_len, eht_cap->mcs_nss)) ||
+ (eht_cap->ppe_thres_len &&
+ nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
+ eht_cap->ppe_thres_len, eht_cap->ppe_thres)))
+ return -ENOBUFS;
+ }
+
if (iftdata->vendor_elems.data && iftdata->vendor_elems.len &&
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
iftdata->vendor_elems.len, iftdata->vendor_elems.data))
--
2.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* RE: [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities
2021-12-22 9:04 ` [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities Veerendranath Jakkam
@ 2022-02-10 5:14 ` Aloka Dixit (QUIC)
2022-02-10 8:26 ` Johannes Berg
0 siblings, 1 reply; 23+ messages in thread
From: Aloka Dixit (QUIC) @ 2022-02-10 5:14 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, Vikram Kandukuri (QUIC), Aloka Dixit (QUIC),
Jia Ding (QUIC), Karthikeyan Periyasamy (QUIC),
Muna Sinada (QUIC), Sriram R (QUIC), Veerendranath Jakkam (QUIC),
Aloka Dixit
Hi Johannes,
Considering that 20MHz-only STA and one that supports other bandwidths will not occur at the same time,
instead of a separate field for struct ieee80211_eht_mcs_nss_supp_20mhz_only inside struct ieee80211_eht_mcs_nss_supp, we can use a byte array as we added in here:
https://patchwork.kernel.org/project/linux-wireless/patch/1640163883-12696-3-git-send-email-quic_vjakkam@quicinc.com/
Instead of length field with dynamic allocation we can have an array of size 9 bytes.
Anyway most operations still need to differentiate between 20MHz-only and other cases, it will just change how many bytes those operations process (4 vs 3,6,9).
What do you think?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities
2022-02-10 5:14 ` Aloka Dixit (QUIC)
@ 2022-02-10 8:26 ` Johannes Berg
2022-02-10 11:17 ` Johannes Berg
0 siblings, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-10 8:26 UTC (permalink / raw)
To: Aloka Dixit (QUIC)
Cc: linux-wireless, Vikram Kandukuri (QUIC), Jia Ding (QUIC),
Karthikeyan Periyasamy (QUIC), Muna Sinada (QUIC),
Sriram R (QUIC), Veerendranath Jakkam (QUIC),
Aloka Dixit
On Thu, 2022-02-10 at 05:14 +0000, Aloka Dixit (QUIC) wrote:
> Hi Johannes,
>
> Considering that 20MHz-only STA and one that supports other bandwidths will not occur at the same time,
> instead of a separate field for struct ieee80211_eht_mcs_nss_supp_20mhz_only inside struct ieee80211_eht_mcs_nss_supp, we can use a byte array as we added in here:
> https://patchwork.kernel.org/project/linux-wireless/patch/1640163883-12696-3-git-send-email-quic_vjakkam@quicinc.com/
> Instead of length field with dynamic allocation we can have an array of size 9 bytes.
>
We did something like that in our patches:
https://patchwork.kernel.org/project/linux-wireless/patch/20220204230119.b0eeb527d761.I2413a37c8f7d2d6d638038a3d95360a3fce0114d@changeid/
https://patchwork.kernel.org/project/linux-wireless/patch/20220204230119.1ee92202ac30.Id30a3ef2844b296efbd5486fe1da9ca36a95c5cf@changeid/
Not overlapping wastes like 4 bytes of memory, I think I can live with
that, vs. the extra complexity? If you overlap you need another bit to
indicate which one you're using ...
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities
2022-02-10 8:26 ` Johannes Berg
@ 2022-02-10 11:17 ` Johannes Berg
2022-02-10 15:57 ` Aloka Dixit (QUIC)
0 siblings, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-10 11:17 UTC (permalink / raw)
To: Aloka Dixit (QUIC)
Cc: linux-wireless, Vikram Kandukuri (QUIC), Jia Ding (QUIC),
Karthikeyan Periyasamy (QUIC), Muna Sinada (QUIC),
Sriram R (QUIC), Veerendranath Jakkam (QUIC),
Aloka Dixit
On Thu, 2022-02-10 at 09:26 +0100, Johannes Berg wrote:
> >
> > Considering that 20MHz-only STA and one that supports other bandwidths will not occur at the same time,
> > instead of a separate field for struct ieee80211_eht_mcs_nss_supp_20mhz_only inside struct ieee80211_eht_mcs_nss_supp, we can use a byte array as we added in here:
> > https://patchwork.kernel.org/project/linux-wireless/patch/1640163883-12696-3-git-send-email-quic_vjakkam@quicinc.com/
> > Instead of length field with dynamic allocation we can have an array of size 9 bytes.
> >
>
> We did something like that in our patches:
>
> https://patchwork.kernel.org/project/linux-wireless/patch/20220204230119.b0eeb527d761.I2413a37c8f7d2d6d638038a3d95360a3fce0114d@changeid/
> https://patchwork.kernel.org/project/linux-wireless/patch/20220204230119.1ee92202ac30.Id30a3ef2844b296efbd5486fe1da9ca36a95c5cf@changeid/
>
> Not overlapping wastes like 4 bytes of memory, I think I can live with
> that, vs. the extra complexity? If you overlap you need another bit to
> indicate which one you're using ...
>
OTOH, that means we need to unwrap it in userspace, which is also
strange ... So yeah I'm changing it to a union.
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities
2022-02-10 11:17 ` Johannes Berg
@ 2022-02-10 15:57 ` Aloka Dixit (QUIC)
2022-02-10 16:29 ` Johannes Berg
0 siblings, 1 reply; 23+ messages in thread
From: Aloka Dixit (QUIC) @ 2022-02-10 15:57 UTC (permalink / raw)
To: 'Johannes Berg', Aloka Dixit (QUIC)
Cc: linux-wireless, Vikram Kandukuri (QUIC), Jia Ding (QUIC),
Karthikeyan Periyasamy (QUIC), Muna Sinada (QUIC),
Sriram R (QUIC), Veerendranath Jakkam (QUIC),
Aloka Dixit
> We did something like that in our patches:
>
> https://patchwork.kernel.org/project/linux-wireless/patch/20220204230119.b0eeb527d761.I2413a37c8f7d2d6d638038a3d95360a3fce0114d@changeid/
> https://patchwork.kernel.org/project/linux-wireless/patch/20220204230119.1ee92202ac30.Id30a3ef2844b296efbd5486fe1da9ca36a95c5cf@changeid/
>
> Not overlapping wastes like 4 bytes of memory, I think I can live with
> that, vs. the extra complexity? If you overlap you need another bit to
> indicate which one you're using ...
>
OTOH, that means we need to unwrap it in userspace, which is also
strange ... So yeah I'm changing it to a union.
Johannes
My comment was actually about your Patches but realized I hadn't subscribed this email with the mailing list so never got emails for those.
So replied here (as I am in cc), just pasted wrong link 😊
But yeah, union would work.
Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities
2022-02-10 15:57 ` Aloka Dixit (QUIC)
@ 2022-02-10 16:29 ` Johannes Berg
0 siblings, 0 replies; 23+ messages in thread
From: Johannes Berg @ 2022-02-10 16:29 UTC (permalink / raw)
To: Aloka Dixit (QUIC)
Cc: linux-wireless, Vikram Kandukuri (QUIC), Jia Ding (QUIC),
Karthikeyan Periyasamy (QUIC), Muna Sinada (QUIC),
Sriram R (QUIC), Veerendranath Jakkam (QUIC),
Aloka Dixit
On Thu, 2022-02-10 at 15:57 +0000, Aloka Dixit (QUIC) wrote:
>
>
> My comment was actually about your Patches but realized I hadn't
> subscribed this email with the mailing list so never got emails for
> those.
Oh.
> So replied here (as I am in cc), just pasted wrong link 😊
Ah ok :)
>
> But yeah, union would work.
I'll also make all the pieces have the right size in nl80211.
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2021-12-22 9:04 [PATCH 0/6] cfg80211/nl80211: add support for EHT Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 1/6] ieee80211: add EHT capabilities element definitions Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 2/6] nl80211: add support to advertise driver's EHT capabilities Veerendranath Jakkam
@ 2021-12-22 9:04 ` Veerendranath Jakkam
2022-02-03 12:45 ` Johannes Berg
2022-02-03 12:47 ` Johannes Berg
2021-12-22 9:04 ` [PATCH 4/6] cfg80211: Add support for EHT 320 MHz channel width Veerendranath Jakkam
` (2 subsequent siblings)
5 siblings, 2 replies; 23+ messages in thread
From: Veerendranath Jakkam @ 2021-12-22 9:04 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
From: Vikram Kandukuri <quic_vikram@quicinc.com>
Add support to process EHT capabilities element passed by the userspace
in beacon template and store the pointer in struct cfg80211_ap_settings.
Add new attribute NL80211_ATTR_EHT_CAPABILITY to be used by the
userspace to pass EHT capabilities of a station trying to associate.
Signed-off-by: Vikram Kandukuri <quic_vikram@quicinc.com>
Co-authored-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Co-authored-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
---
include/net/cfg80211.h | 6 ++++++
include/uapi/linux/nl80211.h | 7 +++++++
net/wireless/nl80211.c | 29 ++++++++++++++++++++++++++---
3 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index df197c6..ce34dd7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1271,6 +1271,7 @@ struct cfg80211_unsol_bcast_probe_resp {
* @ht_cap: HT capabilities (or %NULL if HT isn't enabled)
* @vht_cap: VHT capabilities (or %NULL if VHT isn't enabled)
* @he_cap: HE capabilities (or %NULL if HE isn't enabled)
+ * @eht_cap: EHT capabilities (or %NULL if EHT isn't enabled)
* @ht_required: stations must support HT
* @vht_required: stations must support VHT
* @twt_responder: Enable Target Wait Time
@@ -1308,6 +1309,7 @@ struct cfg80211_ap_settings {
const struct ieee80211_vht_cap *vht_cap;
const struct ieee80211_he_cap_elem *he_cap;
const struct ieee80211_he_operation *he_oper;
+ const struct ieee80211_eht_cap_elem *eht_cap;
bool ht_required, vht_required, he_required, sae_h2e_required;
bool twt_responder;
u32 flags;
@@ -1473,6 +1475,8 @@ struct sta_txpwr {
* @airtime_weight: airtime scheduler weight for this station
* @txpwr: transmit power for an associated station
* @he_6ghz_capa: HE 6 GHz Band capabilities of station
+ * @eht_capa: EHT capabilities of station
+ * @eht_capa_len: the length of the EHT capabilities
*/
struct station_parameters {
const u8 *supported_rates;
@@ -1506,6 +1510,8 @@ struct station_parameters {
u16 airtime_weight;
struct sta_txpwr txpwr;
const struct ieee80211_he_6ghz_capa *he_6ghz_capa;
+ const struct ieee80211_eht_cap_elem *eht_capa;
+ u8 eht_capa_len;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index a709f5c..c221322 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2659,6 +2659,8 @@ enum nl80211_commands {
* enumerated in &enum nl80211_ap_settings_flags. This attribute shall be
* used with %NL80211_CMD_START_AP request.
*
+ * @NL80211_ATTR_EHT_CAPABILITY: EHT Capability information element.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3169,6 +3171,8 @@ enum nl80211_attrs {
NL80211_ATTR_AP_SETTINGS_FLAGS,
+ NL80211_ATTR_EHT_CAPABILITY,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3225,6 +3229,9 @@ enum nl80211_attrs {
#define NL80211_MAX_NR_CIPHER_SUITES 5
#define NL80211_MAX_NR_AKM_SUITES 2
+#define NL80211_EHT_MIN_CAPABILITY_LEN 10
+#define NL80211_EHT_MAX_CAPABILITY_LEN 81
+
#define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10
/* default RSSI threshold for scan results if none specified. */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0ece4d3..dba4002 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -778,6 +778,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
[NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG },
[NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 },
+ [NL80211_ATTR_EHT_CAPABILITY] =
+ NLA_POLICY_RANGE(NLA_BINARY,
+ NL80211_EHT_MIN_CAPABILITY_LEN,
+ NL80211_EHT_MAX_CAPABILITY_LEN),
};
/* policy for the key attributes */
@@ -5414,6 +5418,9 @@ static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
if (cap && cap->datalen >= sizeof(*params->he_oper) + 1)
params->he_oper = (void *)(cap->data + 1);
+ cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_CAPABILITY, ies, ies_len);
+ if (cap && cap->datalen >= sizeof(*params->eht_cap) + 1)
+ params->eht_cap = (void *)(cap->data + 1);
}
static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
@@ -6382,7 +6389,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
if (params->supported_rates)
return -EINVAL;
if (params->ext_capab || params->ht_capa || params->vht_capa ||
- params->he_capa)
+ params->he_capa || params->eht_capa)
return -EINVAL;
}
@@ -6567,6 +6574,17 @@ static int nl80211_parse_sta_channel_info(struct genl_info *info,
return 0;
}
+static void nl80211_parse_sta_eht_capa(struct genl_info *info,
+ struct station_parameters *params)
+{
+ if (info->attrs[NL80211_ATTR_EHT_CAPABILITY]) {
+ params->eht_capa =
+ nla_data(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
+ params->eht_capa_len =
+ nla_len(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
+ }
+}
+
static int nl80211_set_station_tdls(struct genl_info *info,
struct station_parameters *params)
{
@@ -6587,6 +6605,8 @@ static int nl80211_set_station_tdls(struct genl_info *info,
nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
}
+ nl80211_parse_sta_eht_capa(info, params);
+
err = nl80211_parse_sta_channel_info(info, params);
if (err)
return err;
@@ -6848,6 +6868,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params.he_6ghz_capa =
nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
+ nl80211_parse_sta_eht_capa(info, ¶ms);
+
if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
params.opmode_notif_used = true;
params.opmode_notif =
@@ -6891,8 +6913,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params.ht_capa = NULL;
params.vht_capa = NULL;
- /* HE requires WME */
- if (params.he_capa_len || params.he_6ghz_capa)
+ /* HE and EHT requires WME */
+ if (params.he_capa_len || params.he_6ghz_capa ||
+ params.eht_capa_len)
return -EINVAL;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2021-12-22 9:04 ` [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace Veerendranath Jakkam
@ 2022-02-03 12:45 ` Johannes Berg
2022-02-04 7:12 ` Veerendranath Jakkam
2022-02-03 12:47 ` Johannes Berg
1 sibling, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-03 12:45 UTC (permalink / raw)
To: Veerendranath Jakkam
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On Wed, 2021-12-22 at 14:34 +0530, Veerendranath Jakkam wrote:
>
> +#define NL80211_EHT_MIN_CAPABILITY_LEN 10
> +#define NL80211_EHT_MAX_CAPABILITY_LEN 81
>
How did you get to 81?
I calculate only 51, based on the assumption that we can only have
NSS==8. Even if you think NSS==16 (which I doubt), I get to 80 only?
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-03 12:45 ` Johannes Berg
@ 2022-02-04 7:12 ` Veerendranath Jakkam
2022-02-04 8:11 ` Johannes Berg
0 siblings, 1 reply; 23+ messages in thread
From: Veerendranath Jakkam @ 2022-02-04 7:12 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On 2/3/22 6:15 PM, Johannes Berg wrote:
> On Wed, 2021-12-22 at 14:34 +0530, Veerendranath Jakkam wrote:
>>
>> +#define NL80211_EHT_MIN_CAPABILITY_LEN 10
>> +#define NL80211_EHT_MAX_CAPABILITY_LEN 81
>>
> How did you get to 81?
>
> I calculate only 51, based on the assumption that we can only have
> NSS==8. Even if you think NSS==16 (which I doubt), I get to 80 only?
>
> johannes
I considered max values for NSS and RU Index Bitmask sub-fields in PPE
threshold field.
i.e. NSS=16, RU Index Bitmask = 0x11111 with this max PPE threshold info
sub-field length is 60 bytes
Max PPE thresholds field length = 4 bits (for NSS) + 5 bits (for RU
Index Bitmask) + 480 bits (PPE info) + 7 bits (PPE pad)= 62 bytes
EHT fixed fields length = 10 bytes
Max MCS-NSS Set field length = 9 bytes
So total max length would be 81 bytes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-04 7:12 ` Veerendranath Jakkam
@ 2022-02-04 8:11 ` Johannes Berg
2022-02-04 14:37 ` Veerendranath Jakkam
0 siblings, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-04 8:11 UTC (permalink / raw)
To: Veerendranath Jakkam
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On Fri, 2022-02-04 at 12:42 +0530, Veerendranath Jakkam wrote:
> >
> > I calculate only 51, based on the assumption that we can only have
> > NSS==8. Even if you think NSS==16 (which I doubt), I get to 80 only?
>
> So total max length would be 81 bytes
>
Right. Now I don't know how I got to 80...
Regardless, I don't think NSS>8 is actually valid, the PHY spec always
says it's max of 8, so I think we can safely limit to 51?
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-04 8:11 ` Johannes Berg
@ 2022-02-04 14:37 ` Veerendranath Jakkam
2022-02-04 14:43 ` Johannes Berg
0 siblings, 1 reply; 23+ messages in thread
From: Veerendranath Jakkam @ 2022-02-04 14:37 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On 2/4/22 1:41 PM, Johannes Berg wrote:
> On Fri, 2022-02-04 at 12:42 +0530, Veerendranath Jakkam wrote:
>>> I calculate only 51, based on the assumption that we can only have
>>> NSS==8. Even if you think NSS==16 (which I doubt), I get to 80 only?
>> So total max length would be 81 bytes
>>
> Right. Now I don't know how I got to 80...
>
> Regardless, I don't think NSS>8 is actually valid, the PHY spec always
> says it's max of 8, so I think we can safely limit to 51?
>
> johannes
There are some references for NSS > 8, ex: Table 9-33a, P802.11be_D1.3
hence I used 81.
Please let me know if you would like this to be changed to 51
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-04 14:37 ` Veerendranath Jakkam
@ 2022-02-04 14:43 ` Johannes Berg
2022-02-04 17:43 ` Veerendranath Jakkam
0 siblings, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-04 14:43 UTC (permalink / raw)
To: Veerendranath Jakkam
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On Fri, 2022-02-04 at 20:07 +0530, Veerendranath Jakkam wrote:
>
> There are some references for NSS > 8, ex: Table 9-33a, P802.11be_D1.3
> hence I used 81.
Right, the spec confuses me. In a lot of places it reserves enough space
for 8 < NSS <= 16, but then it has e.g. Table 36-40 with 4 bits, but
saying "for up to 8 spatial streams" (MU-MIMO). And even for OFDMA it
states in a lot of places that the maximum is only 8.
> Please let me know if you would like this to be changed to 51
>
Nah, don't worry. I think it probably doesn't even really *matter*, we
can safely leave it at 81 anyway (I had evidently miscalculated as 80
before, so I was confused).
We also already had some patches in this area, and I'm just working on a
combination - e.g. in your first patch I don't like the use of FIELD_GET
so much, preferring uXX_get_bits(), but Ilan already had patches here
that deal with that.
For many of the other patches, Ilan and you arrived at a literally bit-
identical version of things!
So I think I'm going to pick a couple of things from him and a couple of
things from you, and send out a combined series. Perhaps later today, if
I manage to get it done.
Also in your later nl80211 patch I'm thinking we should combine the
HE/EHT GI settings etc., there's no point duplicating all the enums,
though we might want to do some renaming.
Sounds OK?
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-04 14:43 ` Johannes Berg
@ 2022-02-04 17:43 ` Veerendranath Jakkam
2022-02-04 17:45 ` Johannes Berg
0 siblings, 1 reply; 23+ messages in thread
From: Veerendranath Jakkam @ 2022-02-04 17:43 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On 2/4/22 8:13 PM, Johannes Berg wrote:
> On Fri, 2022-02-04 at 20:07 +0530, Veerendranath Jakkam wrote:
>> There are some references for NSS > 8, ex: Table 9-33a, P802.11be_D1.3
>> hence I used 81.
> Right, the spec confuses me. In a lot of places it reserves enough space
> for 8 < NSS <= 16, but then it has e.g. Table 36-40 with 4 bits, but
> saying "for up to 8 spatial streams" (MU-MIMO). And even for OFDMA it
> states in a lot of places that the maximum is only 8.
>
>> Please let me know if you would like this to be changed to 51
>>
> Nah, don't worry. I think it probably doesn't even really *matter*, we
> can safely leave it at 81 anyway (I had evidently miscalculated as 80
> before, so I was confused).
>
> We also already had some patches in this area, and I'm just working on a
> combination - e.g. in your first patch I don't like the use of FIELD_GET
> so much, preferring uXX_get_bits(), but Ilan already had patches here
> that deal with that.
>
> For many of the other patches, Ilan and you arrived at a literally bit-
> identical version of things!
>
> So I think I'm going to pick a couple of things from him and a couple of
> things from you, and send out a combined series. Perhaps later today, if
> I manage to get it done.
Sure, Thanks for the update.
> Also in your later nl80211 patch I'm thinking we should combine the
> HE/EHT GI settings etc., there's no point duplicating all the enums,
> though we might want to do some renaming.
>
> Sounds OK?
>
> johannes
Yeah, This looks fine for me.
meanwhile I will upload new patch set with the suggested changes in last
patch.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-04 17:43 ` Veerendranath Jakkam
@ 2022-02-04 17:45 ` Johannes Berg
2022-02-04 18:28 ` Veerendranath Jakkam
0 siblings, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-04 17:45 UTC (permalink / raw)
To: Veerendranath Jakkam
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On Fri, 2022-02-04 at 23:13 +0530, Veerendranath Jakkam wrote:
>
>
> > Also in your later nl80211 patch I'm thinking we should combine the
> > HE/EHT GI settings etc., there's no point duplicating all the enums,
> > though we might want to do some renaming.
I actually just decided against that ... it gets messy because we still
need the attributes, and the GI is the only one that's entirely the
same, so I think probably duplicating that is more understandable (all
the EHT stuff belongs together)...
>
> meanwhile I will upload new patch set with the suggested changes in last
> patch.
No need. I'm doing rework on this, and we also have mac80211 assoc
patches, STA capabilities, etc. I'll send it all out soon.
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-04 17:45 ` Johannes Berg
@ 2022-02-04 18:28 ` Veerendranath Jakkam
0 siblings, 0 replies; 23+ messages in thread
From: Veerendranath Jakkam @ 2022-02-04 18:28 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On 2/4/22 11:15 PM, Johannes Berg wrote:
> On Fri, 2022-02-04 at 23:13 +0530, Veerendranath Jakkam wrote:
>>
>>> Also in your later nl80211 patch I'm thinking we should combine the
>>> HE/EHT GI settings etc., there's no point duplicating all the enums,
>>> though we might want to do some renaming.
> I actually just decided against that ... it gets messy because we still
> need the attributes, and the GI is the only one that's entirely the
> same, so I think probably duplicating that is more understandable (all
> the EHT stuff belongs together)...
>
>> meanwhile I will upload new patch set with the suggested changes in last
>> patch.
> No need. I'm doing rework on this, and we also have mac80211 assoc
> patches, STA capabilities, etc. I'll send it all out soon.
>
> johannes
Thank a lot for your assistance. Looking forward to see your patches.. :)
veeru
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2021-12-22 9:04 ` [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace Veerendranath Jakkam
2022-02-03 12:45 ` Johannes Berg
@ 2022-02-03 12:47 ` Johannes Berg
2022-02-04 7:18 ` Veerendranath Jakkam
1 sibling, 1 reply; 23+ messages in thread
From: Johannes Berg @ 2022-02-03 12:47 UTC (permalink / raw)
To: Veerendranath Jakkam
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On Wed, 2021-12-22 at 14:34 +0530, Veerendranath Jakkam wrote:
>
> +#define NL80211_EHT_MIN_CAPABILITY_LEN 10
>
And that's 13, no? You have to support 80 MHz.
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace
2022-02-03 12:47 ` Johannes Berg
@ 2022-02-04 7:18 ` Veerendranath Jakkam
0 siblings, 0 replies; 23+ messages in thread
From: Veerendranath Jakkam @ 2022-02-04 7:18 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On 2/3/22 6:17 PM, Johannes Berg wrote:
> On Wed, 2021-12-22 at 14:34 +0530, Veerendranath Jakkam wrote:
>> +#define NL80211_EHT_MIN_CAPABILITY_LEN 10
>>
> And that's 13, no? You have to support 80 MHz.
>
> johannes
I considered fixed fields lengths only for minimum length.
But I agree that we can include minimum possible length of MCS-NSS Set
field also.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 4/6] cfg80211: Add support for EHT 320 MHz channel width
2021-12-22 9:04 [PATCH 0/6] cfg80211/nl80211: add support for EHT Veerendranath Jakkam
` (2 preceding siblings ...)
2021-12-22 9:04 ` [PATCH 3/6] nl80211: add support to send EHT capabilities from userspace Veerendranath Jakkam
@ 2021-12-22 9:04 ` Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 5/6] nl80211: add support for 320MHz channel limitation Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 6/6] nl80211: add EHT MCS support Veerendranath Jakkam
5 siblings, 0 replies; 23+ messages in thread
From: Veerendranath Jakkam @ 2021-12-22 9:04 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
From: Jia Ding <quic_jiad@quicinc.com>
Add 320 MHz support in the channel def and center frequency validation
with compatible check.
Signed-off-by: Jia Ding <quic_jiad@quicinc.com>
Co-authored-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Co-authored-by: Muna Sinada <quic_msinada@quicinc.com>
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
Co-authored-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
---
include/net/cfg80211.h | 6 +++
include/uapi/linux/nl80211.h | 3 ++
net/wireless/chan.c | 91 ++++++++++++++++++++++++++++++++++++++++----
3 files changed, 93 insertions(+), 7 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ce34dd7..eeb2854 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -110,6 +110,11 @@ struct wiphy;
* @IEEE80211_CHAN_16MHZ: 16 MHz bandwidth is permitted
* on this channel.
*
+ * @IEEE80211_CHAN_NO_320MHZ: If the driver supports 320 MHz on the band,
+ * this flag indicates that a 320 MHz channel cannot use this
+ * channel as the control or any of the secondary channels.
+ * This may be due to the driver or due to regulatory bandwidth
+ * restrictions.
*/
enum ieee80211_channel_flags {
IEEE80211_CHAN_DISABLED = 1<<0,
@@ -131,6 +136,7 @@ enum ieee80211_channel_flags {
IEEE80211_CHAN_4MHZ = 1<<16,
IEEE80211_CHAN_8MHZ = 1<<17,
IEEE80211_CHAN_16MHZ = 1<<18,
+ IEEE80211_CHAN_NO_320MHZ = 1<<19,
};
#define IEEE80211_CHAN_NO_HT40 \
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c221322..e4ac7ab 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4691,6 +4691,8 @@ enum nl80211_key_mode {
* @NL80211_CHAN_WIDTH_4: 4 MHz OFDM channel
* @NL80211_CHAN_WIDTH_8: 8 MHz OFDM channel
* @NL80211_CHAN_WIDTH_16: 16 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_320: 320 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ * attribute must be provided as well
*/
enum nl80211_chan_width {
NL80211_CHAN_WIDTH_20_NOHT,
@@ -4706,6 +4708,7 @@ enum nl80211_chan_width {
NL80211_CHAN_WIDTH_4,
NL80211_CHAN_WIDTH_8,
NL80211_CHAN_WIDTH_16,
+ NL80211_CHAN_WIDTH_320,
};
/**
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index eb82205..8b7fb4a 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -181,6 +181,9 @@ static int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
case NL80211_CHAN_WIDTH_160:
mhz = 160;
break;
+ case NL80211_CHAN_WIDTH_320:
+ mhz = 320;
+ break;
default:
WARN_ON_ONCE(1);
return -1;
@@ -271,6 +274,17 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_16:
/* all checked above */
break;
+ case NL80211_CHAN_WIDTH_320:
+ if (chandef->center_freq1 == control_freq + 150 ||
+ chandef->center_freq1 == control_freq + 130 ||
+ chandef->center_freq1 == control_freq + 110 ||
+ chandef->center_freq1 == control_freq + 90 ||
+ chandef->center_freq1 == control_freq - 90 ||
+ chandef->center_freq1 == control_freq - 110 ||
+ chandef->center_freq1 == control_freq - 130 ||
+ chandef->center_freq1 == control_freq - 150)
+ break;
+ fallthrough;
case NL80211_CHAN_WIDTH_160:
if (chandef->center_freq1 == control_freq + 70 ||
chandef->center_freq1 == control_freq + 50 ||
@@ -307,7 +321,7 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
EXPORT_SYMBOL(cfg80211_chandef_valid);
static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
- u32 *pri40, u32 *pri80)
+ u32 *pri40, u32 *pri80, u32 *pri160)
{
int tmp;
@@ -315,9 +329,11 @@ static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
case NL80211_CHAN_WIDTH_40:
*pri40 = c->center_freq1;
*pri80 = 0;
+ *pri160 = 0;
break;
case NL80211_CHAN_WIDTH_80:
case NL80211_CHAN_WIDTH_80P80:
+ *pri160 = 0;
*pri80 = c->center_freq1;
/* n_P20 */
tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
@@ -327,6 +343,7 @@ static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
*pri40 = c->center_freq1 - 20 + 40 * tmp;
break;
case NL80211_CHAN_WIDTH_160:
+ *pri160 = c->center_freq1;
/* n_P20 */
tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
/* n_P40 */
@@ -337,6 +354,20 @@ static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
tmp /= 2;
*pri80 = c->center_freq1 - 40 + 80 * tmp;
break;
+ case NL80211_CHAN_WIDTH_320:
+ /* n_P20 */
+ tmp = (150 + c->chan->center_freq - c->center_freq1) / 20;
+ /* n_P40 */
+ tmp /= 2;
+ /* freq_P40 */
+ *pri40 = c->center_freq1 - 140 + 40 * tmp;
+ /* n_P80 */
+ tmp /= 2;
+ *pri80 = c->center_freq1 - 120 + 80 * tmp;
+ /* n_P160 */
+ tmp /= 2;
+ *pri160 = c->center_freq1 - 80 + 160 * tmp;
+ break;
default:
WARN_ON_ONCE(1);
}
@@ -346,7 +377,7 @@ const struct cfg80211_chan_def *
cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
const struct cfg80211_chan_def *c2)
{
- u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
+ u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80, c1_pri160, c2_pri160;
/* If they are identical, return */
if (cfg80211_chandef_identical(c1, c2))
@@ -381,14 +412,31 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
c2->width == NL80211_CHAN_WIDTH_20)
return c1;
- chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
- chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
+ chandef_primary_freqs(c1, &c1_pri40, &c1_pri80, &c1_pri160);
+ chandef_primary_freqs(c2, &c2_pri40, &c2_pri80, &c2_pri160);
if (c1_pri40 != c2_pri40)
return NULL;
- WARN_ON(!c1_pri80 && !c2_pri80);
- if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
+ if (c1->width == NL80211_CHAN_WIDTH_40)
+ return c2;
+
+ if (c2->width == NL80211_CHAN_WIDTH_40)
+ return c1;
+
+ if (c1_pri80 != c2_pri80)
+ return NULL;
+
+ if (c1->width == NL80211_CHAN_WIDTH_80 &&
+ c2->width > NL80211_CHAN_WIDTH_80)
+ return c2;
+
+ if (c2->width == NL80211_CHAN_WIDTH_80 &&
+ c1->width > NL80211_CHAN_WIDTH_80)
+ return c1;
+
+ WARN_ON(!c1_pri160 && !c2_pri160);
+ if (c1_pri160 && c2_pri160 && c1_pri160 != c2_pri160)
return NULL;
if (c1->width > c2->width)
@@ -960,7 +1008,10 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
struct ieee80211_sta_vht_cap *vht_cap;
struct ieee80211_edmg *edmg_cap;
u32 width, control_freq, cap;
- bool ext_nss_cap, support_80_80 = false;
+ bool ext_nss_cap, support_80_80 = false, support_320 = false;
+ const struct ieee80211_sband_iftype_data *iftd;
+ struct ieee80211_supported_band *sband;
+ int i;
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
return false;
@@ -1062,6 +1113,32 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
(vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)))
return false;
break;
+ case NL80211_CHAN_WIDTH_320:
+ prohibited_flags |= IEEE80211_CHAN_NO_320MHZ;
+ width = 320;
+
+ if (chandef->chan->band != NL80211_BAND_6GHZ)
+ return false;
+
+ sband = wiphy->bands[NL80211_BAND_6GHZ];
+ if (!sband)
+ return false;
+
+ for (i = 0; i < sband->n_iftype_data; i++) {
+ iftd = &sband->iftype_data[i];
+ if (!iftd->eht_cap.has_eht)
+ continue;
+
+ if (iftd->eht_cap.eht_cap_elem.phy_cap_info[0] &
+ IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ) {
+ support_320 = true;
+ break;
+ }
+ }
+
+ if (!support_320)
+ return false;
+ break;
default:
WARN_ON_ONCE(1);
return false;
--
2.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 5/6] nl80211: add support for 320MHz channel limitation
2021-12-22 9:04 [PATCH 0/6] cfg80211/nl80211: add support for EHT Veerendranath Jakkam
` (3 preceding siblings ...)
2021-12-22 9:04 ` [PATCH 4/6] cfg80211: Add support for EHT 320 MHz channel width Veerendranath Jakkam
@ 2021-12-22 9:04 ` Veerendranath Jakkam
2021-12-22 9:04 ` [PATCH 6/6] nl80211: add EHT MCS support Veerendranath Jakkam
5 siblings, 0 replies; 23+ messages in thread
From: Veerendranath Jakkam @ 2021-12-22 9:04 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
From: Sriram R <quic_srirrama@quicinc.com>
Add support to advertise drivers or regulatory limitations on 320 MHz
channels to userspace.
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Co-authored-by: Karthikeyan Periyasamy <quic_periyasia@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasia@quicinc.com>
Co-authored-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
---
include/uapi/linux/nl80211.h | 5 +++++
net/wireless/nl80211.c | 3 +++
net/wireless/reg.c | 6 ++++++
3 files changed, 14 insertions(+)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e4ac7ab..b985cb0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3942,6 +3942,8 @@ enum nl80211_wmm_rule {
* on this channel in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_16MHZ: 16 MHz operation is allowed
* on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_320MHZ: any 320 MHz channel using this channel
+ * as the primary or any of the secondary channels isn't possible
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
* currently defined
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
@@ -3978,6 +3980,7 @@ enum nl80211_frequency_attr {
NL80211_FREQUENCY_ATTR_4MHZ,
NL80211_FREQUENCY_ATTR_8MHZ,
NL80211_FREQUENCY_ATTR_16MHZ,
+ NL80211_FREQUENCY_ATTR_NO_320MHZ,
/* keep last */
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
@@ -4176,6 +4179,7 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
* @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
* @NL80211_RRF_NO_HE: HE operation not allowed
+ * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
*/
enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0,
@@ -4194,6 +4198,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_80MHZ = 1<<15,
NL80211_RRF_NO_160MHZ = 1<<16,
NL80211_RRF_NO_HE = 1<<17,
+ NL80211_RRF_NO_320MHZ = 1<<18,
};
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index dba4002..f31a464 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1152,6 +1152,9 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
if ((chan->flags & IEEE80211_CHAN_16MHZ) &&
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ))
goto nla_put_failure;
+ if ((chan->flags & IEEE80211_CHAN_NO_320MHZ) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_320MHZ))
+ goto nla_put_failure;
}
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ec25924..c76cd97 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1238,6 +1238,8 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
{
unsigned int bw = reg_get_max_bandwidth_from_range(rd, rule);
+ if (rule->flags & NL80211_RRF_NO_320MHZ)
+ bw = min_t(unsigned int, bw, MHZ_TO_KHZ(160));
if (rule->flags & NL80211_RRF_NO_160MHZ)
bw = min_t(unsigned int, bw, MHZ_TO_KHZ(80));
if (rule->flags & NL80211_RRF_NO_80MHZ)
@@ -1611,6 +1613,8 @@ static u32 map_regdom_flags(u32 rd_flags)
channel_flags |= IEEE80211_CHAN_NO_160MHZ;
if (rd_flags & NL80211_RRF_NO_HE)
channel_flags |= IEEE80211_CHAN_NO_HE;
+ if (rd_flags & NL80211_RRF_NO_320MHZ)
+ channel_flags |= IEEE80211_CHAN_NO_320MHZ;
return channel_flags;
}
@@ -1773,6 +1777,8 @@ static uint32_t reg_rule_to_chan_bw_flags(const struct ieee80211_regdomain *regd
bw_flags |= IEEE80211_CHAN_NO_80MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(160))
bw_flags |= IEEE80211_CHAN_NO_160MHZ;
+ if (max_bandwidth_khz < MHZ_TO_KHZ(320))
+ bw_flags |= IEEE80211_CHAN_NO_320MHZ;
}
return bw_flags;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 6/6] nl80211: add EHT MCS support
2021-12-22 9:04 [PATCH 0/6] cfg80211/nl80211: add support for EHT Veerendranath Jakkam
` (4 preceding siblings ...)
2021-12-22 9:04 ` [PATCH 5/6] nl80211: add support for 320MHz channel limitation Veerendranath Jakkam
@ 2021-12-22 9:04 ` Veerendranath Jakkam
2022-02-04 14:53 ` Johannes Berg
5 siblings, 1 reply; 23+ messages in thread
From: Veerendranath Jakkam @ 2021-12-22 9:04 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
Add support for reporting and calculating EHT bitrates.
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
---
include/net/cfg80211.h | 11 ++++
include/uapi/linux/nl80211.h | 62 ++++++++++++++++++++
net/wireless/nl80211.c | 18 ++++++
net/wireless/util.c | 131 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 222 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index eeb2854..56ead14 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1595,6 +1595,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
* @RATE_INFO_FLAGS_HE_MCS: HE MCS information
* @RATE_INFO_FLAGS_EDMG: 60GHz MCS in EDMG mode
* @RATE_INFO_FLAGS_EXTENDED_SC_DMG: 60GHz extended SC MCS
+ * @RATE_INFO_FLAGS_EHT_MCS: EHT MCS information
*/
enum rate_info_flags {
RATE_INFO_FLAGS_MCS = BIT(0),
@@ -1604,6 +1605,7 @@ enum rate_info_flags {
RATE_INFO_FLAGS_HE_MCS = BIT(4),
RATE_INFO_FLAGS_EDMG = BIT(5),
RATE_INFO_FLAGS_EXTENDED_SC_DMG = BIT(6),
+ RATE_INFO_FLAGS_EHT_MCS = BIT(7),
};
/**
@@ -1618,6 +1620,8 @@ enum rate_info_flags {
* @RATE_INFO_BW_80: 80 MHz bandwidth
* @RATE_INFO_BW_160: 160 MHz bandwidth
* @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation
+ * @RATE_INFO_BW_320: 320 MHz bandwidth
+ * @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT RU allocation
*/
enum rate_info_bw {
RATE_INFO_BW_20 = 0,
@@ -1627,6 +1631,8 @@ enum rate_info_bw {
RATE_INFO_BW_80,
RATE_INFO_BW_160,
RATE_INFO_BW_HE_RU,
+ RATE_INFO_BW_320,
+ RATE_INFO_BW_EHT_RU,
};
/**
@@ -1644,6 +1650,9 @@ enum rate_info_bw {
* @he_ru_alloc: HE RU allocation (from &enum nl80211_he_ru_alloc,
* only valid if bw is %RATE_INFO_BW_HE_RU)
* @n_bonded_ch: In case of EDMG the number of bonded channels (1-4)
+ * @eht_gi: EHT guard interval (from &enum nl80211_eht_gi)
+ * @eht_ru_alloc: EHT RU allocation (from &enum nl80211_eht_ru_alloc,
+ * only valid if bw is %RATE_INFO_BW_EHT_RU)
*/
struct rate_info {
u8 flags;
@@ -1655,6 +1664,8 @@ struct rate_info {
u8 he_dcm;
u8 he_ru_alloc;
u8 n_bonded_ch;
+ u8 eht_gi;
+ u8 eht_ru_alloc;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index b985cb0..76c70fc 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3400,6 +3400,56 @@ enum nl80211_he_ru_alloc {
};
/**
+ * enum nl80211_eht_gi - EHT guard interval
+ * @NL80211_RATE_INFO_EHT_GI_0_8: 0.8 usec
+ * @NL80211_RATE_INFO_EHT_GI_1_6: 1.6 usec
+ * @NL80211_RATE_INFO_EHT_GI_3_2: 3.2 usec
+ */
+enum nl80211_eht_gi {
+ NL80211_RATE_INFO_EHT_GI_0_8,
+ NL80211_RATE_INFO_EHT_GI_1_6,
+ NL80211_RATE_INFO_EHT_GI_3_2,
+};
+
+/**
+ * enum nl80211_eht_ru_alloc - EHT RU allocation values
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_26: 26-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_52: 52-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_52P26: 52+26-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_106: 106-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_106P26: 106+26 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_242: 242-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_484: 484-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_484P242: 484+242 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_996: 996-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_996P484: 996+484 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242: 996+484+242 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_2x996: 2x996-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484: 2x996+484 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_3x996: 3x996-tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484: 3x996+484 tone RU allocation
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC_4x996: 4x996-tone RU allocation
+ */
+enum nl80211_eht_ru_alloc {
+ NL80211_RATE_INFO_EHT_RU_ALLOC_26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_52,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_52P26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_106,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_106P26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_484P242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_4x996,
+};
+
+/**
* enum nl80211_rate_info - bitrate information
*
* These attribute types are used with %NL80211_STA_INFO_TXRATE
@@ -3438,6 +3488,13 @@ enum nl80211_he_ru_alloc {
* @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
* @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
* non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
+ * @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate
+ * @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15)
+ * @NL80211_RATE_INFO_EHT_NSS: EHT NSS value (u8, 1-8)
+ * @NL80211_RATE_INFO_EHT_GI: EHT guard interval identifier
+ * (u8, see &enum nl80211_eht_gi)
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC: EHT RU allocation, if not present then
+ * non-OFDMA was used (u8, see &enum nl80211_eht_ru_alloc)
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
*/
enum nl80211_rate_info {
@@ -3459,6 +3516,11 @@ enum nl80211_rate_info {
NL80211_RATE_INFO_HE_GI,
NL80211_RATE_INFO_HE_DCM,
NL80211_RATE_INFO_HE_RU_ALLOC,
+ NL80211_RATE_INFO_320_MHZ_WIDTH,
+ NL80211_RATE_INFO_EHT_MCS,
+ NL80211_RATE_INFO_EHT_NSS,
+ NL80211_RATE_INFO_EHT_GI,
+ NL80211_RATE_INFO_EHT_RU_ALLOC,
/* keep last */
__NL80211_RATE_INFO_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f31a464..10f4fc6 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5946,6 +5946,13 @@ bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
case RATE_INFO_BW_HE_RU:
rate_flg = 0;
WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
+ break;
+ case RATE_INFO_BW_320:
+ rate_flg = NL80211_RATE_INFO_320_MHZ_WIDTH;
+ break;
+ case RATE_INFO_BW_EHT_RU:
+ rate_flg = 0;
+ WARN_ON(!(info->flags & RATE_INFO_FLAGS_EHT_MCS));
}
if (rate_flg && nla_put_flag(msg, rate_flg))
@@ -5978,6 +5985,17 @@ bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
info->he_ru_alloc))
return false;
+ } else if (info->flags & RATE_INFO_FLAGS_EHT_MCS) {
+ if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_MCS, info->mcs))
+ return false;
+ if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_NSS, info->nss))
+ return false;
+ if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_GI, info->eht_gi))
+ return false;
+ if (info->bw == RATE_INFO_BW_EHT_RU &&
+ nla_put_u8(msg, NL80211_RATE_INFO_EHT_RU_ALLOC,
+ info->eht_ru_alloc))
+ return false;
}
nla_nest_end(msg, rate);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 41ea65d..327257c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1428,6 +1428,135 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
return result / 10000;
}
+static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate)
+{
+#define SCALE 6144
+ static const u32 mcs_divisors[16] = {
+ 102399, /* 16.666666... */
+ 51201, /* 8.333333... */
+ 34134, /* 5.555555... */
+ 25599, /* 4.166666... */
+ 17067, /* 2.777777... */
+ 12801, /* 2.083333... */
+ 11769, /* 1.851851... */
+ 10239, /* 1.666666... */
+ 8532, /* 1.388888... */
+ 7680, /* 1.250000... */
+ 6828, /* 1.111111... */
+ 6144, /* 1.000000... */
+ 5690, /* 0.926106... */
+ 5120, /* 0.833333... */
+ 409600, /* 66.666666... */
+ 204800, /* 33.333333... */
+ };
+ static const u32 rates_996[3] = { 480388888, 453700000, 408333333 };
+ static const u32 rates_484[3] = { 229411111, 216666666, 195000000 };
+ static const u32 rates_242[3] = { 114711111, 108333333, 97500000 };
+ static const u32 rates_106[3] = { 40000000, 37777777, 34000000 };
+ static const u32 rates_52[3] = { 18820000, 17777777, 16000000 };
+ static const u32 rates_26[3] = { 9411111, 8888888, 8000000 };
+ u64 tmp;
+ u32 result;
+
+ if (WARN_ON_ONCE(rate->mcs > 15))
+ return 0;
+ if (WARN_ON_ONCE(rate->eht_gi > NL80211_RATE_INFO_EHT_GI_3_2))
+ return 0;
+ if (WARN_ON_ONCE(rate->eht_ru_alloc >
+ NL80211_RATE_INFO_EHT_RU_ALLOC_4x996))
+ return 0;
+ if (WARN_ON_ONCE(rate->nss < 1 || rate->nss > 8))
+ return 0;
+
+ /* Bandwidth checks for MCS 14 */
+ if (rate->mcs == 14) {
+ if ((rate->bw != RATE_INFO_BW_EHT_RU &&
+ rate->bw != RATE_INFO_BW_80 &&
+ rate->bw != RATE_INFO_BW_160 &&
+ rate->bw != RATE_INFO_BW_320) ||
+ (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc != NL80211_RATE_INFO_EHT_RU_ALLOC_996 &&
+ rate->eht_ru_alloc != NL80211_RATE_INFO_EHT_RU_ALLOC_2x996 &&
+ rate->eht_ru_alloc != NL80211_RATE_INFO_EHT_RU_ALLOC_4x996)) {
+ WARN(1, "invalid EHT BW for MCS 14: bw:%d, ru:%d\n",
+ rate->bw, rate->eht_ru_alloc);
+ return 0;
+ }
+ }
+
+ if (rate->bw == RATE_INFO_BW_320 ||
+ (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_4x996))
+ result = 4 * rates_996[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484)
+ result = 3 * rates_996[rate->eht_gi] + rates_484[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_3x996)
+ result = 3 * rates_996[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484)
+ result = 2 * rates_996[rate->eht_gi] + rates_484[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_160 ||
+ (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_2x996))
+ result = 2 * rates_996[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc ==
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242)
+ result = rates_996[rate->eht_gi] + rates_484[rate->eht_gi]
+ + rates_242[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_996P484)
+ result = rates_996[rate->eht_gi] + rates_484[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_80 ||
+ (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_996))
+ result = rates_996[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_484P242)
+ result = rates_484[rate->eht_gi] + rates_242[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_40 ||
+ (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_484))
+ result = rates_484[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_20 ||
+ (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_242))
+ result = rates_242[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_106P26)
+ result = rates_106[rate->eht_gi] + rates_26[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_106)
+ result = rates_106[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_52P26)
+ result = rates_52[rate->eht_gi] + rates_26[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_52)
+ result = rates_52[rate->eht_gi];
+ else if (rate->bw == RATE_INFO_BW_EHT_RU &&
+ rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_26)
+ result = rates_26[rate->eht_gi];
+ else {
+ WARN(1, "invalid EHT MCS: bw:%d, ru:%d\n",
+ rate->bw, rate->eht_ru_alloc);
+ return 0;
+ }
+
+ /* now scale to the appropriate MCS */
+ tmp = result;
+ tmp *= SCALE;
+ do_div(tmp, mcs_divisors[rate->mcs]);
+ result = tmp;
+
+ /* and take NSS */
+ result = (result * rate->nss) / 8;
+
+ return result / 10000;
+}
+
u32 cfg80211_calculate_bitrate(struct rate_info *rate)
{
if (rate->flags & RATE_INFO_FLAGS_MCS)
@@ -1442,6 +1571,8 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
return cfg80211_calculate_bitrate_vht(rate);
if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
return cfg80211_calculate_bitrate_he(rate);
+ if (rate->flags & RATE_INFO_FLAGS_EHT_MCS)
+ return cfg80211_calculate_bitrate_eht(rate);
return rate->legacy;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 6/6] nl80211: add EHT MCS support
2021-12-22 9:04 ` [PATCH 6/6] nl80211: add EHT MCS support Veerendranath Jakkam
@ 2022-02-04 14:53 ` Johannes Berg
0 siblings, 0 replies; 23+ messages in thread
From: Johannes Berg @ 2022-02-04 14:53 UTC (permalink / raw)
To: Veerendranath Jakkam
Cc: linux-wireless, quic_vikram, quic_alokad, quic_jiad,
quic_periyasa, quic_msinada, quic_srirrama
On Wed, 2021-12-22 at 14:34 +0530, Veerendranath Jakkam wrote:
>
> + * @NL80211_RATE_INFO_EHT_NSS: EHT NSS value (u8, 1-8)
>
I'll note you also put 1-8 here ;-)
johannes
^ permalink raw reply [flat|nested] 23+ messages in thread