Blob Blame History Raw
From 31fdae686b7a84c5e47e9ab298dfdbaec1ccaeb9 Mon Sep 17 00:00:00 2001
From: Eugene Syromiatnikov <esyr@redhat.com>
Date: Thu, 5 Sep 2019 18:45:30 +0200
Subject: [PATCH 14/43] Revert "iwlwifi: mvm: change PHY data RX for HE
 radiotap"

This reverts commit bdf180c8d375ee75493d79ae384dd1f9686fc974.
---
 drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 190 +++++--------
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c  | 367 +++++++++++++------------
 2 files changed, 261 insertions(+), 296 deletions(-)

Index: src/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
===================================================================
--- src.orig/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h	2019-06-27 14:54:04.122678470 +0200
+++ src/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h	2019-09-06 01:25:42.865325621 +0200
@@ -343,98 +343,66 @@
 	IWL_RX_MPDU_PHY_PHY_INDEX_MASK		= 0xf0,
 };
 
-/* TSF overload low dword */
-enum iwl_rx_phy_data0 {
-	/* info type: HE any */
-	IWL_RX_PHY_DATA0_HE_BEAM_CHNG				= 0x00000001,
-	IWL_RX_PHY_DATA0_HE_UPLINK				= 0x00000002,
-	IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK			= 0x000000fc,
-	IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK			= 0x00000f00,
-	/* 1 bit reserved */
-	IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK			= 0x000fe000,
-	IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM			= 0x00100000,
-	IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK			= 0x00600000,
-	IWL_RX_PHY_DATA0_HE_PE_DISAMBIG				= 0x00800000,
-	IWL_RX_PHY_DATA0_HE_DOPPLER				= 0x01000000,
+/*
+ * enum iwl_rx_he_phy - HE PHY data
+ */
+enum iwl_rx_he_phy {
+	IWL_RX_HE_PHY_BEAM_CHNG			= BIT(0),
+	IWL_RX_HE_PHY_UPLINK			= BIT(1),
+	IWL_RX_HE_PHY_BSS_COLOR_MASK		= 0xfc,
+	IWL_RX_HE_PHY_SPATIAL_REUSE_MASK	= 0xf00,
+	IWL_RX_HE_PHY_SU_EXT_BW10		= BIT(12),
+	IWL_RX_HE_PHY_TXOP_DUR_MASK		= 0xfe000,
+	IWL_RX_HE_PHY_LDPC_EXT_SYM		= BIT(20),
+	IWL_RX_HE_PHY_PRE_FEC_PAD_MASK		= 0x600000,
+	IWL_RX_HE_PHY_PE_DISAMBIG		= BIT(23),
+	IWL_RX_HE_PHY_DOPPLER			= BIT(24),
 	/* 6 bits reserved */
-	IWL_RX_PHY_DATA0_HE_DELIM_EOF				= 0x80000000,
-};
-
-enum iwl_rx_phy_info_type {
-	IWL_RX_PHY_INFO_TYPE_NONE				= 0,
-	IWL_RX_PHY_INFO_TYPE_CCK				= 1,
-	IWL_RX_PHY_INFO_TYPE_OFDM_LGCY				= 2,
-	IWL_RX_PHY_INFO_TYPE_HT					= 3,
-	IWL_RX_PHY_INFO_TYPE_VHT_SU				= 4,
-	IWL_RX_PHY_INFO_TYPE_VHT_MU				= 5,
-	IWL_RX_PHY_INFO_TYPE_HE_SU				= 6,
-	IWL_RX_PHY_INFO_TYPE_HE_MU				= 7,
-	IWL_RX_PHY_INFO_TYPE_HE_TB				= 8,
-	IWL_RX_PHY_INFO_TYPE_HE_MU_EXT				= 9,
-	IWL_RX_PHY_INFO_TYPE_HE_TB_EXT				= 10,
-};
+	IWL_RX_HE_PHY_DELIM_EOF			= BIT(31),
 
-/* TSF overload high dword */
-enum iwl_rx_phy_data1 {
-	/*
-	 * check this first - if TSF overload is set,
-	 * see &enum iwl_rx_phy_info_type
-	 */
-	IWL_RX_PHY_DATA1_INFO_TYPE_MASK				= 0xf0000000,
-
-	/* info type: HT/VHT/HE any */
-	IWL_RX_PHY_DATA1_LSIG_LEN_MASK				= 0x0fff0000,
-
-	/* info type: HE MU/MU-EXT */
-	IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION			= 0x00000001,
-	IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK	= 0x0000001e,
-
-	/* info type: HE any */
-	IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK			= 0x000000e0,
-	IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80			= 0x00000100,
+	/* second dword - common data */
+	IWL_RX_HE_PHY_HE_LTF_NUM_MASK		= 0xe000000000ULL,
+	IWL_RX_HE_PHY_RU_ALLOC_SEC80		= BIT_ULL(32 + 8),
 	/* trigger encoded */
-	IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK			= 0x0000fe00,
-
-	/* info type: HE TB/TX-EXT */
-	IWL_RX_PHY_DATA1_HE_TB_PILOT_TYPE			= 0x00000001,
-	IWL_RX_PHY_DATA1_HE_TB_LOW_SS_MASK			= 0x0000000e,
+	IWL_RX_HE_PHY_RU_ALLOC_MASK		= 0xfe0000000000ULL,
+	IWL_RX_HE_PHY_INFO_TYPE_MASK		= 0xf000000000000000ULL,
+	IWL_RX_HE_PHY_INFO_TYPE_SU		= 0x0, /* TSF low valid (first DW) */
+	IWL_RX_HE_PHY_INFO_TYPE_MU		= 0x1, /* TSF low/high valid (both DWs) */
+	IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO	= 0x2, /* same + SIGB-common0/1/2 valid */
+	IWL_RX_HE_PHY_INFO_TYPE_TB		= 0x3, /* TSF low/high valid (both DWs) */
+
+	/* second dword - MU data */
+	IWL_RX_HE_PHY_MU_SIGB_COMPRESSION		= BIT_ULL(32 + 0),
+	IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK	= 0x1e00000000ULL,
+	IWL_RX_HE_PHY_MU_SIGB_MCS_MASK			= 0xf000000000000ULL,
+	IWL_RX_HE_PHY_MU_SIGB_DCM			= BIT_ULL(32 + 21),
+	IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK	= 0xc0000000000000ULL,
+
+	/* second dword - TB data */
+	IWL_RX_HE_PHY_TB_PILOT_TYPE			= BIT_ULL(32 + 0),
+	IWL_RX_HE_PHY_TB_LOW_SS_MASK			= 0xe00000000ULL
 };
 
-/* goes into Metadata DW 7 */
-enum iwl_rx_phy_data2 {
-	/* info type: HE MU-EXT */
+enum iwl_rx_he_sigb_common0 {
 	/* the a1/a2/... is what the PHY/firmware calls the values */
-	IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0		= 0x000000ff, /* a1 */
-	IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2		= 0x0000ff00, /* a2 */
-	IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0		= 0x00ff0000, /* b1 */
-	IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2		= 0xff000000, /* b2 */
-
-	/* info type: HE TB-EXT */
-	IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1		= 0x0000000f,
-	IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2		= 0x000000f0,
-	IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3		= 0x00000f00,
-	IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4		= 0x0000f000,
+	IWL_RX_HE_SIGB_COMMON0_CH1_RU0		= 0x000000ff, /* a1 */
+	IWL_RX_HE_SIGB_COMMON0_CH1_RU2		= 0x0000ff00, /* a2 */
+	IWL_RX_HE_SIGB_COMMON0_CH2_RU0		= 0x00ff0000, /* b1 */
+	IWL_RX_HE_SIGB_COMMON0_CH2_RU2		= 0xff000000, /* b2 */
 };
 
-/* goes into Metadata DW 8 */
-enum iwl_rx_phy_data3 {
-	/* info type: HE MU-EXT */
-	IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1		= 0x000000ff, /* c1 */
-	IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3		= 0x0000ff00, /* c2 */
-	IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1		= 0x00ff0000, /* d1 */
-	IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3		= 0xff000000, /* d2 */
+enum iwl_rx_he_sigb_common1 {
+	IWL_RX_HE_SIGB_COMMON1_CH1_RU1		= 0x000000ff, /* c1 */
+	IWL_RX_HE_SIGB_COMMON1_CH1_RU3		= 0x0000ff00, /* c2 */
+	IWL_RX_HE_SIGB_COMMON1_CH2_RU1		= 0x00ff0000, /* d1 */
+	IWL_RX_HE_SIGB_COMMON1_CH2_RU3		= 0xff000000, /* d2 */
 };
 
-/* goes into Metadata DW 4 high 16 bits */
-enum iwl_rx_phy_data4 {
-	/* info type: HE MU-EXT */
-	IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU			= 0x0001,
-	IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU			= 0x0002,
-	IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK			= 0x0004,
-	IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK			= 0x0008,
-	IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK		= 0x00f0,
-	IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM			= 0x0100,
-	IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK	= 0x0600,
+enum iwl_rx_he_sigb_common2 {
+	IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU	= 0x0001,
+	IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU	= 0x0002,
+	IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK	= 0x0004,
+	IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK	= 0x0008,
 };
 
 /**
@@ -449,9 +417,9 @@
 		__le32 rss_hash;
 
 		/**
-		 * @phy_data2: depends on info type (see @phy_data1)
+		 * @sigb_common0: for HE sniffer, HE-SIG-B common part 0
 		 */
-		__le32 phy_data2;
+		__le32 sigb_common0;
 	};
 
 	/* DW8 - carries filter_match only when rpa_en == 1 */
@@ -462,9 +430,9 @@
 		__le32 filter_match;
 
 		/**
-		 * @phy_data3: depends on info type (see @phy_data1)
+		 * @sigb_common1: for HE sniffer, HE-SIG-B common part 1
 		 */
-		__le32 phy_data3;
+		__le32 sigb_common1;
 	};
 
 	/* DW9 */
@@ -502,19 +470,12 @@
 		 * %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set
 		 */
 		__le64 tsf_on_air_rise;
-
-		struct {
-			/**
-			 * @phy_data0: depends on info_type, see @phy_data1
-			 */
-			__le32 phy_data0;
-			/**
-			 * @phy_data1: valid only if
-			 * %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set,
-			 * see &enum iwl_rx_phy_data1.
-			 */
-			__le32 phy_data1;
-		};
+		/**
+		 * @he_phy_data:
+		 * HE PHY data, see &enum iwl_rx_he_phy, valid
+		 * only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set
+		 */
+		__le64 he_phy_data;
 	};
 } __packed;
 
@@ -530,9 +491,9 @@
 		__le32 filter_match;
 
 		/**
-		 * @phy_data2: depends on info type (see @phy_data1)
+		 * @sigb_common0: for HE sniffer, HE-SIG-B common part 0
 		 */
-		__le32 phy_data2;
+		__le32 sigb_common0;
 	};
 
 	/* DW8 - carries rss_hash only when rpa_en == 1 */
@@ -543,9 +504,9 @@
 		__le32 rss_hash;
 
 		/**
-		 * @phy_data3: depends on info type (see @phy_data1)
+		 * @sigb_common1: for HE sniffer, HE-SIG-B common part 1
 		 */
-		__le32 phy_data3;
+		__le32 sigb_common1;
 	};
 	/* DW9 */
 	/**
@@ -593,19 +554,12 @@
 		 * %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set
 		 */
 		__le64 tsf_on_air_rise;
-
-		struct {
-			/**
-			 * @phy_data0: depends on info_type, see @phy_data1
-			 */
-			__le32 phy_data0;
-			/**
-			 * @phy_data1: valid only if
-			 * %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set,
-			 * see &enum iwl_rx_phy_data1.
-			 */
-			__le32 phy_data1;
-		};
+		/**
+		 * @he_phy_data:
+		 * HE PHY data, see &enum iwl_rx_he_phy, valid
+		 * only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set
+		 */
+		__le64 he_phy_data;
 	};
 	/* DW16 & DW17 */
 	/**
@@ -657,9 +611,9 @@
 		__le16 l3l4_flags;
 
 		/**
-		 * @phy_data4: depends on info type, see phy_data1
+		 * @sigb_common2: for HE sniffer, HE-SIG-B common part 2
 		 */
-		__le16 phy_data4;
+		__le16 sigb_common2;
 	};
 	/* DW5 */
 	/**
Index: src/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
===================================================================
--- src.orig/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c	2019-09-06 01:25:42.700327726 +0200
+++ src/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c	2019-09-06 01:25:42.865325621 +0200
@@ -903,65 +903,68 @@
 	ether_addr_copy(addr, mac_addr);
 }
 
-struct iwl_mvm_rx_phy_data {
-	__le32 d0, d1, d2, d3;
-	__le16 d4;
-};
-
-static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm,
-				     struct iwl_mvm_rx_phy_data *phy_data,
-				     u32 rate_n_flags,
-				     struct ieee80211_radiotap_he_mu *he_mu)
+static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm,
+				   struct iwl_rx_mpdu_desc *desc,
+				   u32 rate_n_flags,
+				   struct ieee80211_radiotap_he_mu *he_mu)
 {
-	u32 phy_data2 = le32_to_cpu(phy_data->d2);
-	u32 phy_data3 = le32_to_cpu(phy_data->d3);
-	u16 phy_data4 = le16_to_cpu(phy_data->d4);
+	u32 sigb0, sigb1;
+	u16 sigb2;
 
-	if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK, phy_data4)) {
+	if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+		sigb0 = le32_to_cpu(desc->v3.sigb_common0);
+		sigb1 = le32_to_cpu(desc->v3.sigb_common1);
+	} else {
+		sigb0 = le32_to_cpu(desc->v1.sigb_common0);
+		sigb1 = le32_to_cpu(desc->v1.sigb_common1);
+	}
+
+	sigb2 = le16_to_cpu(desc->sigb_common2);
+
+	if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK, sigb2)) {
 		he_mu->flags1 |=
 			cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN |
 				    IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN);
 
 		he_mu->flags1 |=
-			le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU,
-						   phy_data4),
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU,
+						   sigb2),
 					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU);
 
-		he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0,
-					     phy_data2);
-		he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1,
-					     phy_data3);
-		he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2,
-					     phy_data2);
-		he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3,
-					     phy_data3);
+		he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU0,
+					     sigb0);
+		he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU1,
+					     sigb1);
+		he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU2,
+					     sigb0);
+		he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU3,
+					     sigb1);
 	}
 
-	if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK, phy_data4) &&
+	if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2) &&
 	    (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) {
 		he_mu->flags1 |=
 			cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN |
 				    IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN);
 
 		he_mu->flags2 |=
-			le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU,
-						   phy_data4),
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU,
+						   sigb2),
 					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU);
 
-		he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0,
-					     phy_data2);
-		he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1,
-					     phy_data3);
-		he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2,
-					     phy_data2);
-		he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3,
-					     phy_data3);
+		he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU0,
+					     sigb0);
+		he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU1,
+					     sigb1);
+		he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU2,
+					     sigb0);
+		he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU3,
+					     sigb1);
 	}
 }
 
 static void
-iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
-			       u32 rate_n_flags,
+iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
 			       struct ieee80211_radiotap_he *he,
 			       struct ieee80211_radiotap_he_mu *he_mu,
 			       struct ieee80211_rx_status *rx_status)
@@ -974,7 +977,7 @@
 	 * happen though as management frames where we need
 	 * the TSF/timers are not be transmitted in HE-MU.
 	 */
-	u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK);
+	u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
 	u8 offs = 0;
 
 	rx_status->bw = RATE_INFO_BW_HE_RU;
@@ -1013,7 +1016,7 @@
 				      IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
 	he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN |
 				 IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN);
-	if (phy_data->d1 & cpu_to_le32(IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80))
+	if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80)
 		he->data2 |=
 			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
 
@@ -1033,124 +1036,105 @@
 }
 
 static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
-				       struct iwl_mvm_rx_phy_data *phy_data,
+				       struct iwl_rx_mpdu_desc *desc,
 				       struct ieee80211_radiotap_he *he,
 				       struct ieee80211_radiotap_he_mu *he_mu,
 				       struct ieee80211_rx_status *rx_status,
-				       u32 rate_n_flags, int queue)
+				       u64 he_phy_data, u32 rate_n_flags,
+				       int queue)
 {
-	enum iwl_rx_phy_info_type info_type;
-
-	info_type = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
-
-	switch (info_type) {
-	case IWL_RX_PHY_INFO_TYPE_NONE:
-	case IWL_RX_PHY_INFO_TYPE_CCK:
-	case IWL_RX_PHY_INFO_TYPE_OFDM_LGCY:
-		return;
-	case IWL_RX_PHY_INFO_TYPE_HT:
-	case IWL_RX_PHY_INFO_TYPE_VHT_SU:
-	case IWL_RX_PHY_INFO_TYPE_VHT_MU:
-		/* TODO: we have LSIG-LEN, where do we put it? */
-		return;
-	case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
-		he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN);
-		he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1),
-					      IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1);
-		he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2),
-					      IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2);
-		he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3),
-					      IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3);
-		he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4),
-					      IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4);
-		/* fall through */
-	case IWL_RX_PHY_INFO_TYPE_HE_SU:
-	case IWL_RX_PHY_INFO_TYPE_HE_MU:
-	case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
-	case IWL_RX_PHY_INFO_TYPE_HE_TB:
-		/* HE common */
-		he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
-		he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |
-					 IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
-		he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK),
-					      IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
-		he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_UPLINK),
-					      IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
-		he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM),
-					      IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
-		he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK),
-					      IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
-		he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK),
-					      IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
-		he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_PE_DISAMBIG),
-					      IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
-		he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d1,
-							    IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK),
-					      IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
-		he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK),
-					      IEEE80211_RADIOTAP_HE_DATA6_TXOP);
-		he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_DOPPLER),
-					      IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
-		break;
-	}
+	u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
+	bool sigb_data;
+	u16 d1known = IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
+		      IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
+		      IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
+		      IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
+		      IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN;
+	u16 d2known = IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
+		      IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
+		      IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN;
+
+	he->data1 |= cpu_to_le16(d1known);
+	he->data2 |= cpu_to_le16(d2known);
+	he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
+	he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_UPLINK,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
+	he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_LDPC_EXT_SYM,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
+	he->data4 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SPATIAL_REUSE_MASK,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
+	he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PRE_FEC_PAD_MASK,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
+	he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PE_DISAMBIG,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
+	he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_TXOP_DUR_MASK,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA6_TXOP);
+	he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_DOPPLER,
+						he_phy_data),
+				      IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
 
-	switch (info_type) {
-	case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
+	switch (he_type) {
+	case RATE_MCS_HE_TYPE_MU:
 		he_mu->flags1 |=
-			le16_encode_bits(le16_get_bits(phy_data->d4,
-						       IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM),
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_DCM,
+						   he_phy_data),
 					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
 		he_mu->flags1 |=
-			le16_encode_bits(le16_get_bits(phy_data->d4,
-						       IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK),
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_MCS_MASK,
+						   he_phy_data),
 					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
 		he_mu->flags2 |=
-			le16_encode_bits(le16_get_bits(phy_data->d4,
-						       IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK),
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
-		iwl_mvm_decode_he_mu_ext(mvm, phy_data, rate_n_flags, he_mu);
-		/* fall through */
-	case IWL_RX_PHY_INFO_TYPE_HE_MU:
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK,
+						  he_phy_data),
+					IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
 		he_mu->flags2 |=
-			le16_encode_bits(le32_get_bits(phy_data->d1,
-						       IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK),
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
-		he_mu->flags2 |=
-			le16_encode_bits(le32_get_bits(phy_data->d1,
-						       IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION),
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_COMPRESSION,
+						   he_phy_data),
 					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
+		he_mu->flags2 |=
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK,
+						   he_phy_data),
+					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
+
+		sigb_data = FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK,
+				      he_phy_data) ==
+				IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO;
+		if (sigb_data)
+			iwl_mvm_decode_he_sigb(mvm, desc, rate_n_flags, he_mu);
 		/* fall through */
-	case IWL_RX_PHY_INFO_TYPE_HE_TB:
-	case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
-		iwl_mvm_decode_he_phy_ru_alloc(phy_data, rate_n_flags,
-					       he, he_mu, rx_status);
+	case RATE_MCS_HE_TYPE_TRIG:
+		he->data2 |=
+			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
+		he->data5 |=
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK,
+						   he_phy_data),
+					 IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
+		break;
+	case RATE_MCS_HE_TYPE_SU:
+	case RATE_MCS_HE_TYPE_EXT_SU:
+		he->data1 |=
+			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN);
+		he->data3 |=
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BEAM_CHNG,
+						   he_phy_data),
+					 IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE);
 		break;
-	case IWL_RX_PHY_INFO_TYPE_HE_SU:
-		he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN);
-		he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
-							    IWL_RX_PHY_DATA0_HE_BEAM_CHNG),
-					      IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE);
+	}
+
+	switch (FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data)) {
+	case IWL_RX_HE_PHY_INFO_TYPE_MU:
+	case IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO:
+	case IWL_RX_HE_PHY_INFO_TYPE_TB:
+		iwl_mvm_decode_he_phy_ru_alloc(he_phy_data, rate_n_flags,
+					       he, he_mu, rx_status);
 		break;
 	default:
 		/* nothing */
@@ -1163,6 +1147,9 @@
 			  u32 rate_n_flags, u16 phy_info, int queue)
 {
 	struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
+	/* this is invalid e.g. because puncture type doesn't allow 0b11 */
+#define HE_PHY_DATA_INVAL ((u64)-1)
+	u64 he_phy_data = HE_PHY_DATA_INVAL;
 	struct ieee80211_radiotap_he *he = NULL;
 	struct ieee80211_radiotap_he_mu *he_mu = NULL;
 	u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
@@ -1184,66 +1171,54 @@
 				      IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
 	};
 	unsigned int radiotap_len = 0;
-	struct iwl_mvm_rx_phy_data phy_data = {
-		.d4 = desc->phy_data4,
-	};
-	enum iwl_rx_phy_info_type info_type = IWL_RX_PHY_INFO_TYPE_NONE;
-
-	if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
-		phy_data.d0 = desc->v3.phy_data0;
-		phy_data.d1 = desc->v3.phy_data1;
-		phy_data.d2 = desc->v3.phy_data2;
-		phy_data.d3 = desc->v3.phy_data3;
-	} else {
-		phy_data.d0 = desc->v1.phy_data0;
-		phy_data.d1 = desc->v1.phy_data1;
-		phy_data.d2 = desc->v1.phy_data2;
-		phy_data.d3 = desc->v1.phy_data3;
-	}
-
-	if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
-		info_type = le32_get_bits(phy_data.d1,
-					  IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
 
 	he = skb_put_data(skb, &known, sizeof(known));
 	radiotap_len += sizeof(known);
 	rx_status->flag |= RX_FLAG_RADIOTAP_HE;
 
-	if (info_type == IWL_RX_PHY_INFO_TYPE_HE_MU ||
-	    info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) {
-		he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
-		radiotap_len += sizeof(mu_known);
-		rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
+	if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) {
+		if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+			he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
+		else
+			he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
+
+		if (he_type == RATE_MCS_HE_TYPE_MU) {
+			he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
+			radiotap_len += sizeof(mu_known);
+			rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
+		}
 	}
 
 	/* temporarily hide the radiotap data */
 	__skb_pull(skb, radiotap_len);
 
-	if (info_type == IWL_RX_PHY_INFO_TYPE_HE_SU) {
+	if (he_phy_data != HE_PHY_DATA_INVAL &&
+	    he_type == RATE_MCS_HE_TYPE_SU) {
 		/* report the AMPDU-EOF bit on single frames */
 		if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
 			rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
 			rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
-			if (phy_data.d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
+			if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data))
 				rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
 		}
 	}
 
-	if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
-		iwl_mvm_decode_he_phy_data(mvm, &phy_data, he, he_mu, rx_status,
-					   rate_n_flags, queue);
+	if (he_phy_data != HE_PHY_DATA_INVAL)
+		iwl_mvm_decode_he_phy_data(mvm, desc, he, he_mu, rx_status,
+					   he_phy_data, rate_n_flags, queue);
 
 	/* update aggregation data for monitor sake on default queue */
-	if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) &&
-	    (phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
+	if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
 		bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE;
 
 		/* toggle is switched whenever new aggregation starts */
 		if (toggle_bit != mvm->ampdu_toggle &&
+		    he_phy_data != HE_PHY_DATA_INVAL &&
 		    (he_type == RATE_MCS_HE_TYPE_MU ||
 		     he_type == RATE_MCS_HE_TYPE_SU)) {
 			rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
-			if (phy_data.d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
+			if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
+				      he_phy_data))
 				rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
 		}
 	}
@@ -1326,8 +1301,44 @@
 		break;
 	}
 
-	he->data5 |= le16_encode_bits(ltf,
-				      IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
+	he->data5 |= le16_encode_bits(ltf, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
+
+	if (he_type == RATE_MCS_HE_TYPE_SU ||
+	    he_type == RATE_MCS_HE_TYPE_EXT_SU) {
+		u16 val;
+
+		/* LTF syms correspond to streams */
+		he->data2 |=
+			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
+		switch (rx_status->nss) {
+		case 1:
+			val = 0;
+			break;
+		case 2:
+			val = 1;
+			break;
+		case 3:
+		case 4:
+			val = 2;
+			break;
+		case 5:
+		case 6:
+			val = 3;
+			break;
+		case 7:
+		case 8:
+			val = 4;
+			break;
+		default:
+			WARN_ONCE(1, "invalid nss: %d\n",
+				  rx_status->nss);
+			val = 0;
+		}
+
+		he->data5 |=
+			le16_encode_bits(val,
+					 IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
+	}
 }
 
 void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,