All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] cfg80211/nl80211: add support for EHT
@ 2021-12-22  9:04 Veerendranath Jakkam
  2021-12-22  9:04 ` [PATCH 1/6] ieee80211: add EHT capabilities element definitions Veerendranath Jakkam
                   ` (5 more replies)
  0 siblings, 6 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

This patch series adds support for EHT and 320 MHz channel width in
cfg80211 and also add userspace API to send rate information out,
conforming with P802.11be_D1.3.

Jia Ding (1):
  cfg80211: Add support for EHT 320 MHz channel width

Sriram R (1):
  nl80211: add support for 320MHz channel limitation

Veerendranath Jakkam (1):
  nl80211: add EHT MCS support

Vikram Kandukuri (3):
  ieee80211: add EHT capabilities element definitions
  nl80211: add support to advertise driver's EHT capabilities
  nl80211: add support to send EHT capabilities from userspace

 include/linux/ieee80211.h    | 702 +++++++++++++++++++++++++++++++++++++++++++
 include/net/cfg80211.h       |  79 +++++
 include/uapi/linux/nl80211.h |  89 ++++++
 net/wireless/chan.c          |  91 +++++-
 net/wireless/nl80211.c       |  67 ++++-
 net/wireless/reg.c           |   6 +
 net/wireless/util.c          | 131 ++++++++
 7 files changed, 1155 insertions(+), 10 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [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

* [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, &params);
+
 	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

* [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 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
  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: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-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

* 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 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

* 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 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

end of thread, other threads:[~2022-02-10 16:29 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2022-02-10  5:14   ` Aloka Dixit (QUIC)
2022-02-10  8:26     ` Johannes Berg
2022-02-10 11:17       ` Johannes Berg
2022-02-10 15:57         ` Aloka Dixit (QUIC)
2022-02-10 16:29           ` Johannes Berg
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-04  8:11       ` Johannes Berg
2022-02-04 14:37         ` Veerendranath Jakkam
2022-02-04 14:43           ` Johannes Berg
2022-02-04 17:43             ` Veerendranath Jakkam
2022-02-04 17:45               ` Johannes Berg
2022-02-04 18:28                 ` Veerendranath Jakkam
2022-02-03 12:47   ` Johannes Berg
2022-02-04  7:18     ` Veerendranath Jakkam
2021-12-22  9:04 ` [PATCH 4/6] cfg80211: Add support for EHT 320 MHz channel width 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
2022-02-04 14:53   ` Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.