Blame SOURCES/0066-Revert-iwlwifi-mvm-move-he-RX-handling-to-a-separate.patch

deb259
From 5e0d3511c1ef2ec98f93491b5f6da2b16051c8aa Mon Sep 17 00:00:00 2001
deb259
From: Eugene Syromiatnikov <esyr@redhat.com>
deb259
Date: Thu, 5 Sep 2019 18:53:20 +0200
deb259
Subject: [PATCH 37/43] Revert "iwlwifi: mvm: move he RX handling to a separate
deb259
 function"
deb259
deb259
This reverts commit c630b477caf78998cdcd5766956817d8721c23c9.
deb259
---
deb259
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 582 +++++++++++++-------------
deb259
 1 file changed, 296 insertions(+), 286 deletions(-)
deb259
deb259
Index: src/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
deb259
===================================================================
deb259
--- src.orig/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c	2019-09-06 01:25:46.568278388 +0200
deb259
+++ src/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c	2019-09-06 01:25:46.739276207 +0200
deb259
@@ -903,289 +903,6 @@
deb259
 	ether_addr_copy(addr, mac_addr);
deb259
 }
deb259
 
deb259
-static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
deb259
-			  struct iwl_rx_mpdu_desc *desc,
deb259
-			  u32 rate_n_flags, u16 phy_info, int queue)
deb259
-{
deb259
-	struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
deb259
-	/* this is invalid e.g. because puncture type doesn't allow 0b11 */
deb259
-#define HE_PHY_DATA_INVAL ((u64)-1)
deb259
-	u64 he_phy_data = HE_PHY_DATA_INVAL;
deb259
-	struct ieee80211_radiotap_he *he = NULL;
deb259
-	struct ieee80211_radiotap_he_mu *he_mu = NULL;
deb259
-	u32 he_type = 0xffffffff;
deb259
-	u8 stbc;
deb259
-
deb259
-	static const struct ieee80211_radiotap_he known = {
deb259
-		.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
deb259
-				     IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN |
deb259
-				     IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |
deb259
-				     IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN),
deb259
-		.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN |
deb259
-				     IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN),
deb259
-	};
deb259
-	static const struct ieee80211_radiotap_he_mu mu_known = {
deb259
-		.flags1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN |
deb259
-				      IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN |
deb259
-				      IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN |
deb259
-				      IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN),
deb259
-		.flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN),
deb259
-	};
deb259
-	unsigned int radiotap_len = 0;
deb259
-	bool overload = phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD;
deb259
-
deb259
-	he = skb_put_data(skb, &known, sizeof(known));
deb259
-	radiotap_len += sizeof(known);
deb259
-	rx_status->flag |= RX_FLAG_RADIOTAP_HE;
deb259
-
deb259
-	he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
deb259
-
deb259
-	if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) {
deb259
-		if (mvm->trans->cfg->device_family >=
deb259
-				IWL_DEVICE_FAMILY_22560)
deb259
-			he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
deb259
-		else
deb259
-			he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
deb259
-
deb259
-		if (he_type == RATE_MCS_HE_TYPE_MU) {
deb259
-			he_mu = skb_put_data(skb, &mu_known,
deb259
-					     sizeof(mu_known));
deb259
-			radiotap_len += sizeof(mu_known);
deb259
-			rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
deb259
-		}
deb259
-	}
deb259
-
deb259
-	/* temporarily hide the radiotap data */
deb259
-	__skb_pull(skb, radiotap_len);
deb259
-
deb259
-	if (overload && he_type == RATE_MCS_HE_TYPE_SU) {
deb259
-		he->data1 |=
deb259
-			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN);
deb259
-		if (FIELD_GET(IWL_RX_HE_PHY_UPLINK, he_phy_data))
deb259
-			he->data3 |=
deb259
-				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
deb259
-
deb259
-		if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
deb259
-			rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
deb259
-			rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
deb259
-			if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data))
deb259
-				rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
deb259
-		}
deb259
-	} else if (overload && he_mu && he_phy_data != HE_PHY_DATA_INVAL) {
deb259
-		he_mu->flags1 |=
deb259
-			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK,
deb259
-						  he_phy_data),
deb259
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
deb259
-		he_mu->flags1 |=
deb259
-			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_DCM,
deb259
-						  he_phy_data),
deb259
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
deb259
-		he_mu->flags1 |=
deb259
-			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_MCS_MASK,
deb259
-						  he_phy_data),
deb259
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
deb259
-		he_mu->flags2 |=
deb259
-			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_COMPRESSION,
deb259
-						  he_phy_data),
deb259
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
deb259
-		he_mu->flags2 |=
deb259
-			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK,
deb259
-						  he_phy_data),
deb259
-					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
deb259
-	}
deb259
-
deb259
-	if (he_phy_data != HE_PHY_DATA_INVAL) {
deb259
-		he->data1 |=
deb259
-			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
deb259
-		he->data3 |=
deb259
-			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK,
deb259
-						  he_phy_data),
deb259
-					 IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
deb259
-	}
deb259
-
deb259
-	/* update aggregation data for monitor sake on default queue */
deb259
-	if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
deb259
-		bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE;
deb259
-
deb259
-		/* toggle is switched whenever new aggregation starts */
deb259
-		if (toggle_bit != mvm->ampdu_toggle &&
deb259
-		    he_phy_data != HE_PHY_DATA_INVAL &&
deb259
-		    (he_type == RATE_MCS_HE_TYPE_MU ||
deb259
-		     he_type == RATE_MCS_HE_TYPE_SU)) {
deb259
-			rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
deb259
-			if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
deb259
-				      he_phy_data))
deb259
-				rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
deb259
-		}
deb259
-	}
deb259
-
deb259
-	if (he_type == RATE_MCS_HE_TYPE_EXT_SU &&
deb259
-	    rate_n_flags & RATE_MCS_HE_106T_MSK) {
deb259
-		rx_status->bw = RATE_INFO_BW_HE_RU;
deb259
-		rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
deb259
-	}
deb259
-	if (he_mu) {
deb259
-		/*
deb259
-		 * Unfortunately, we have to leave the mac80211 data
deb259
-		 * incorrect for the case that we receive an HE-MU
deb259
-		 * transmission and *don't* have the he_mu pointer,
deb259
-		 * i.e. we don't have the phy data (due to the bits
deb259
-		 * being used for TSF). This shouldn't happen though
deb259
-		 * as management frames where we need the TSF/timers
deb259
-		 * are not be transmitted in HE-MU, I think.
deb259
-		 */
deb259
-		u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
deb259
-		u8 offs = 0;
deb259
-
deb259
-		rx_status->bw = RATE_INFO_BW_HE_RU;
deb259
-
deb259
-		switch (ru) {
deb259
-		case 0 ... 36:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
deb259
-			offs = ru;
deb259
-			break;
deb259
-		case 37 ... 52:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
deb259
-			offs = ru - 37;
deb259
-			break;
deb259
-		case 53 ... 60:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
deb259
-			offs = ru - 53;
deb259
-			break;
deb259
-		case 61 ... 64:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
deb259
-			offs = ru - 61;
deb259
-			break;
deb259
-		case 65 ... 66:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
deb259
-			offs = ru - 65;
deb259
-			break;
deb259
-		case 67:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
deb259
-			break;
deb259
-		case 68:
deb259
-			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
deb259
-			break;
deb259
-		}
deb259
-		he->data2 |=
deb259
-			le16_encode_bits(offs,
deb259
-					 IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
deb259
-		he->data2 |=
deb259
-			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN);
deb259
-		if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80)
deb259
-			he->data2 |=
deb259
-				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
deb259
-	} else if (he) {
deb259
-		he->data1 |=
deb259
-			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN);
deb259
-	}
deb259
-
deb259
-	stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS;
deb259
-	rx_status->nss =
deb259
-		((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
deb259
-					RATE_VHT_MCS_NSS_POS) + 1;
deb259
-	rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
deb259
-	rx_status->encoding = RX_ENC_HE;
deb259
-	rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
deb259
-	if (rate_n_flags & RATE_MCS_BF_MSK)
deb259
-		rx_status->enc_flags |= RX_ENC_FLAG_BF;
deb259
-
deb259
-	rx_status->he_dcm =
deb259
-		!!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK);
deb259
-
deb259
-#define CHECK_TYPE(F)							\
deb259
-	BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F !=	\
deb259
-		     (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS))
deb259
-
deb259
-	CHECK_TYPE(SU);
deb259
-	CHECK_TYPE(EXT_SU);
deb259
-	CHECK_TYPE(MU);
deb259
-	CHECK_TYPE(TRIG);
deb259
-
deb259
-	he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS);
deb259
-
deb259
-	if (rate_n_flags & RATE_MCS_BF_POS)
deb259
-		he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF);
deb259
-
deb259
-	switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >>
deb259
-		RATE_MCS_HE_GI_LTF_POS) {
deb259
-	case 0:
deb259
-		rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
deb259
-		break;
deb259
-	case 1:
deb259
-		rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
deb259
-		break;
deb259
-	case 2:
deb259
-		rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
deb259
-		break;
deb259
-	case 3:
deb259
-		if (rate_n_flags & RATE_MCS_SGI_MSK)
deb259
-			rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
deb259
-		else
deb259
-			rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
deb259
-		break;
deb259
-	}
deb259
-
deb259
-	switch (he_type) {
deb259
-	case RATE_MCS_HE_TYPE_SU: {
deb259
-		u16 val;
deb259
-
deb259
-		/* LTF syms correspond to streams */
deb259
-		he->data2 |=
deb259
-			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
deb259
-		switch (rx_status->nss) {
deb259
-		case 1:
deb259
-			val = 0;
deb259
-			break;
deb259
-		case 2:
deb259
-			val = 1;
deb259
-			break;
deb259
-		case 3:
deb259
-		case 4:
deb259
-			val = 2;
deb259
-			break;
deb259
-		case 5:
deb259
-		case 6:
deb259
-			val = 3;
deb259
-			break;
deb259
-		case 7:
deb259
-		case 8:
deb259
-			val = 4;
deb259
-			break;
deb259
-		default:
deb259
-			WARN_ONCE(1, "invalid nss: %d\n",
deb259
-				  rx_status->nss);
deb259
-			val = 0;
deb259
-		}
deb259
-		he->data5 |=
deb259
-			le16_encode_bits(val,
deb259
-					 IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
deb259
-		}
deb259
-		break;
deb259
-	case RATE_MCS_HE_TYPE_MU: {
deb259
-		u16 val;
deb259
-
deb259
-		if (he_phy_data == HE_PHY_DATA_INVAL)
deb259
-			break;
deb259
-
deb259
-		val = FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK,
deb259
-				he_phy_data);
deb259
-
deb259
-		he->data2 |=
deb259
-			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
deb259
-		he->data5 |=
deb259
-			cpu_to_le16(FIELD_PREP(
deb259
-				IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS,
deb259
-				val));
deb259
-		}
deb259
-		break;
deb259
-	case RATE_MCS_HE_TYPE_EXT_SU:
deb259
-	case RATE_MCS_HE_TYPE_TRIG:
deb259
-		/* not supported */
deb259
-		break;
deb259
-	}
deb259
-}
deb259
-
deb259
 void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
deb259
 			struct iwl_rx_cmd_buffer *rxb, int queue)
deb259
 {
deb259
@@ -1199,6 +916,12 @@
deb259
 	struct ieee80211_sta *sta = NULL;
deb259
 	struct sk_buff *skb;
deb259
 	u8 crypt_len = 0, channel, energy_a, energy_b;
deb259
+	struct ieee80211_radiotap_he *he = NULL;
deb259
+	struct ieee80211_radiotap_he_mu *he_mu = NULL;
deb259
+	u32 he_type = 0xffffffff;
deb259
+	/* this is invalid e.g. because puncture type doesn't allow 0b11 */
deb259
+#define HE_PHY_DATA_INVAL ((u64)-1)
deb259
+	u64 he_phy_data = HE_PHY_DATA_INVAL;
deb259
 	size_t desc_size;
deb259
 	bool csi = false;
deb259
 
deb259
@@ -1243,8 +966,48 @@
deb259
 
deb259
 	rx_status = IEEE80211_SKB_RXCB(skb);
deb259
 
deb259
-	if (rate_n_flags & RATE_MCS_HE_MSK)
deb259
-		iwl_mvm_rx_he(mvm, skb, desc, rate_n_flags, phy_info, queue);
deb259
+	if (rate_n_flags & RATE_MCS_HE_MSK) {
deb259
+		static const struct ieee80211_radiotap_he known = {
deb259
+			.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
deb259
+					     IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN |
deb259
+					     IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |
deb259
+					     IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN),
deb259
+			.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN |
deb259
+					     IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN),
deb259
+		};
deb259
+		static const struct ieee80211_radiotap_he_mu mu_known = {
deb259
+			.flags1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN |
deb259
+					      IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN |
deb259
+					      IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN |
deb259
+					      IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN),
deb259
+			.flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN),
deb259
+		};
deb259
+		unsigned int radiotap_len = 0;
deb259
+
deb259
+		he = skb_put_data(skb, &known, sizeof(known));
deb259
+		radiotap_len += sizeof(known);
deb259
+		rx_status->flag |= RX_FLAG_RADIOTAP_HE;
deb259
+
deb259
+		he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
deb259
+
deb259
+		if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) {
deb259
+			if (mvm->trans->cfg->device_family >=
deb259
+			    IWL_DEVICE_FAMILY_22560)
deb259
+				he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
deb259
+			else
deb259
+				he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
deb259
+
deb259
+			if (he_type == RATE_MCS_HE_TYPE_MU) {
deb259
+				he_mu = skb_put_data(skb, &mu_known,
deb259
+						     sizeof(mu_known));
deb259
+				radiotap_len += sizeof(mu_known);
deb259
+				rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
deb259
+			}
deb259
+		}
deb259
+
deb259
+		/* temporarily hide the radiotap data */
deb259
+		__skb_pull(skb, radiotap_len);
deb259
+	}
deb259
 
deb259
 	rx_status = IEEE80211_SKB_RXCB(skb);
deb259
 
deb259
@@ -1281,6 +1044,65 @@
deb259
 		rx_status->mactime = tsf_on_air_rise;
deb259
 		/* TSF as indicated by the firmware is at INA time */
deb259
 		rx_status->flag |= RX_FLAG_MACTIME_PLCP_START;
deb259
+	} else if (he_type == RATE_MCS_HE_TYPE_SU) {
deb259
+		u64 he_phy_data;
deb259
+
deb259
+		if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
deb259
+			he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
deb259
+		else
deb259
+			he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
deb259
+
deb259
+		he->data1 |=
deb259
+			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN);
deb259
+		if (FIELD_GET(IWL_RX_HE_PHY_UPLINK,
deb259
+			      he_phy_data))
deb259
+			he->data3 |=
deb259
+				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
deb259
+
deb259
+		if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
deb259
+			rx_status->ampdu_reference = mvm->ampdu_ref;
deb259
+			mvm->ampdu_ref++;
deb259
+
deb259
+			rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
deb259
+			rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
deb259
+			if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
deb259
+				      he_phy_data))
deb259
+				rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
deb259
+		}
deb259
+	} else if (he_mu && he_phy_data != HE_PHY_DATA_INVAL) {
deb259
+		he_mu->flags1 |=
deb259
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK,
deb259
+						   he_phy_data),
deb259
+					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
deb259
+		he_mu->flags1 |=
deb259
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_DCM,
deb259
+						   he_phy_data),
deb259
+					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
deb259
+		he_mu->flags1 |=
deb259
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_MCS_MASK,
deb259
+						   he_phy_data),
deb259
+					 IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
deb259
+		he_mu->flags2 |=
deb259
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_COMPRESSION,
deb259
+						   he_phy_data),
deb259
+					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
deb259
+		he_mu->flags2 |=
deb259
+			le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK,
deb259
+						   he_phy_data),
deb259
+					 IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
deb259
+	}
deb259
+
deb259
+	if (he_phy_data != HE_PHY_DATA_INVAL &&
deb259
+	    (he_type == RATE_MCS_HE_TYPE_SU ||
deb259
+	     he_type == RATE_MCS_HE_TYPE_MU)) {
deb259
+		u8 bss_color = FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK,
deb259
+					 he_phy_data);
deb259
+
deb259
+		if (bss_color) {
deb259
+			he->data1 |=
deb259
+				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
deb259
+			he->data3 |= cpu_to_le16(bss_color);
deb259
+		}
deb259
 	}
deb259
 
deb259
 	rx_status->device_timestamp = gp2_on_air_rise;
deb259
@@ -1312,6 +1134,16 @@
deb259
 			if (mvm->ampdu_ref == 0)
deb259
 				mvm->ampdu_ref++;
deb259
 			mvm->ampdu_toggle = toggle_bit;
deb259
+
deb259
+			if (he_phy_data != HE_PHY_DATA_INVAL &&
deb259
+			    (he_type == RATE_MCS_HE_TYPE_MU ||
deb259
+			     he_type == RATE_MCS_HE_TYPE_SU)) {
deb259
+				rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
deb259
+				if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
deb259
+					      he_phy_data))
deb259
+					rx_status->flag |=
deb259
+						RX_FLAG_AMPDU_EOF_BIT;
deb259
+			}
deb259
 		}
deb259
 		rx_status->ampdu_reference = mvm->ampdu_ref;
deb259
 	}
deb259
@@ -1434,6 +1266,70 @@
deb259
 		break;
deb259
 	}
deb259
 
deb259
+	if (he_type == RATE_MCS_HE_TYPE_EXT_SU &&
deb259
+	    rate_n_flags & RATE_MCS_HE_106T_MSK) {
deb259
+		rx_status->bw = RATE_INFO_BW_HE_RU;
deb259
+		rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
deb259
+	}
deb259
+
deb259
+	if (rate_n_flags & RATE_MCS_HE_MSK &&
deb259
+	    phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD &&
deb259
+	    he_type == RATE_MCS_HE_TYPE_MU) {
deb259
+		/*
deb259
+		 * Unfortunately, we have to leave the mac80211 data
deb259
+		 * incorrect for the case that we receive an HE-MU
deb259
+		 * transmission and *don't* have the he_mu pointer,
deb259
+		 * i.e. we don't have the phy data (due to the bits
deb259
+		 * being used for TSF). This shouldn't happen though
deb259
+		 * as management frames where we need the TSF/timers
deb259
+		 * are not be transmitted in HE-MU, I think.
deb259
+		 */
deb259
+		u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
deb259
+		u8 offs = 0;
deb259
+
deb259
+		rx_status->bw = RATE_INFO_BW_HE_RU;
deb259
+
deb259
+		switch (ru) {
deb259
+		case 0 ... 36:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
deb259
+			offs = ru;
deb259
+			break;
deb259
+		case 37 ... 52:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
deb259
+			offs = ru - 37;
deb259
+			break;
deb259
+		case 53 ... 60:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
deb259
+			offs = ru - 53;
deb259
+			break;
deb259
+		case 61 ... 64:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
deb259
+			offs = ru - 61;
deb259
+			break;
deb259
+		case 65 ... 66:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
deb259
+			offs = ru - 65;
deb259
+			break;
deb259
+		case 67:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
deb259
+			break;
deb259
+		case 68:
deb259
+			rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
deb259
+			break;
deb259
+		}
deb259
+		he->data2 |=
deb259
+			le16_encode_bits(offs,
deb259
+					 IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
deb259
+		he->data2 |=
deb259
+			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN);
deb259
+		if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80)
deb259
+			he->data2 |=
deb259
+				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
deb259
+	} else if (he) {
deb259
+		he->data1 |=
deb259
+			cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN);
deb259
+	}
deb259
+
deb259
 	if (!(rate_n_flags & RATE_MCS_CCK_MSK) &&
deb259
 	    rate_n_flags & RATE_MCS_SGI_MSK)
deb259
 		rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
deb259
@@ -1458,7 +1354,120 @@
deb259
 		rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
deb259
 		if (rate_n_flags & RATE_MCS_BF_MSK)
deb259
 			rx_status->enc_flags |= RX_ENC_FLAG_BF;
deb259
-	} else if (!(rate_n_flags & RATE_MCS_HE_MSK)) {
deb259
+	} else if (he) {
deb259
+		u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
deb259
+				RATE_MCS_STBC_POS;
deb259
+		rx_status->nss =
deb259
+			((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
deb259
+						RATE_VHT_MCS_NSS_POS) + 1;
deb259
+		rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
deb259
+		rx_status->encoding = RX_ENC_HE;
deb259
+		rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
deb259
+		if (rate_n_flags & RATE_MCS_BF_MSK)
deb259
+			rx_status->enc_flags |= RX_ENC_FLAG_BF;
deb259
+
deb259
+		rx_status->he_dcm =
deb259
+			!!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK);
deb259
+
deb259
+#define CHECK_TYPE(F)							\
deb259
+	BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F !=	\
deb259
+		     (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS))
deb259
+
deb259
+		CHECK_TYPE(SU);
deb259
+		CHECK_TYPE(EXT_SU);
deb259
+		CHECK_TYPE(MU);
deb259
+		CHECK_TYPE(TRIG);
deb259
+
deb259
+		he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS);
deb259
+
deb259
+		if (rate_n_flags & RATE_MCS_BF_POS)
deb259
+			he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF);
deb259
+
deb259
+		switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >>
deb259
+			RATE_MCS_HE_GI_LTF_POS) {
deb259
+		case 0:
deb259
+			rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
deb259
+			break;
deb259
+		case 1:
deb259
+			rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
deb259
+			break;
deb259
+		case 2:
deb259
+			rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
deb259
+			break;
deb259
+		case 3:
deb259
+			if (rate_n_flags & RATE_MCS_SGI_MSK)
deb259
+				rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
deb259
+			else
deb259
+				rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
deb259
+			break;
deb259
+		}
deb259
+
deb259
+		switch (he_type) {
deb259
+		case RATE_MCS_HE_TYPE_SU: {
deb259
+			u16 val;
deb259
+
deb259
+			/* LTF syms correspond to streams */
deb259
+			he->data2 |=
deb259
+				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
deb259
+			switch (rx_status->nss) {
deb259
+			case 1:
deb259
+				val = 0;
deb259
+				break;
deb259
+			case 2:
deb259
+				val = 1;
deb259
+				break;
deb259
+			case 3:
deb259
+			case 4:
deb259
+				val = 2;
deb259
+				break;
deb259
+			case 5:
deb259
+			case 6:
deb259
+				val = 3;
deb259
+				break;
deb259
+			case 7:
deb259
+			case 8:
deb259
+				val = 4;
deb259
+				break;
deb259
+			default:
deb259
+				WARN_ONCE(1, "invalid nss: %d\n",
deb259
+					  rx_status->nss);
deb259
+				val = 0;
deb259
+			}
deb259
+			he->data5 |=
deb259
+				le16_encode_bits(val,
deb259
+						 IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
deb259
+			}
deb259
+			break;
deb259
+		case RATE_MCS_HE_TYPE_MU: {
deb259
+			u16 val;
deb259
+			u64 he_phy_data;
deb259
+
deb259
+			if (mvm->trans->cfg->device_family >=
deb259
+			    IWL_DEVICE_FAMILY_22560)
deb259
+				he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
deb259
+			else
deb259
+				he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
deb259
+
deb259
+			if (he_phy_data == HE_PHY_DATA_INVAL)
deb259
+				break;
deb259
+
deb259
+			val = FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK,
deb259
+					he_phy_data);
deb259
+
deb259
+			he->data2 |=
deb259
+				cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
deb259
+			he->data5 |=
deb259
+				cpu_to_le16(FIELD_PREP(
deb259
+					IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS,
deb259
+					val));
deb259
+			}
deb259
+			break;
deb259
+		case RATE_MCS_HE_TYPE_EXT_SU:
deb259
+		case RATE_MCS_HE_TYPE_TRIG:
deb259
+			/* not supported yet */
deb259
+			break;
deb259
+		}
deb259
+	} else {
deb259
 		int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
deb259
 							       rx_status->band);
deb259
 
deb259
@@ -1469,6 +1478,7 @@
deb259
 			goto out;
deb259
 		}
deb259
 		rx_status->rate_idx = rate;
deb259
+
deb259
 	}
deb259
 
deb259
 	/* management stuff on default queue */