Преглед изворни кода

qcacmn: Add EHT radiotap header fields

Add the EHT radiotap header definition and
support to parse these fields.

Change-Id: If988753b497cc2feb79f358afea2674effd8270c
CRs-Fixed: 3092818
Rakesh Pillai пре 3 година
родитељ
комит
1c6617edf5
3 измењених фајлова са 325 додато и 27 уклоњено
  1. 162 1
      qdf/inc/qdf_nbuf.h
  2. 3 0
      qdf/linux/src/i_qdf_nbuf.h
  3. 160 26
      qdf/linux/src/qdf_nbuf.c

+ 162 - 1
qdf/inc/qdf_nbuf.h

@@ -212,6 +212,8 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
 #define RADIOTAP_HE_FLAGS_LEN (12 + 1)
 #define RADIOTAP_HE_MU_FLAGS_LEN (8 + 1)
 #define RADIOTAP_HE_MU_OTHER_FLAGS_LEN (18 + 1)
+#define RADIOTAP_U_SIG_FLAGS_LEN (12 + 3)
+#define RADIOTAP_EHT_FLAGS_LEN (32 + 3)
 #define RADIOTAP_FIXED_HEADER_LEN 17
 #define RADIOTAP_HT_FLAGS_LEN 3
 #define RADIOTAP_AMPDU_STATUS_LEN (8 + 3)
@@ -234,7 +236,9 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
 				RADIOTAP_HE_MU_OTHER_FLAGS_LEN + \
 				RADIOTAP_VENDOR_NS_LEN + \
 				RADIOTAP_HEADER_EXT_LEN + \
-				RADIOTAP_HEADER_EXT2_LEN)
+				RADIOTAP_HEADER_EXT2_LEN + \
+				RADIOTAP_U_SIG_FLAGS_LEN + \
+				RADIOTAP_EHT_FLAGS_LEN)
 
 /**
  * struct mon_rx_status - This will have monitor mode rx_status extracted from
@@ -252,12 +256,15 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
  * @he_flags: HE (11ax) flags, only present in HE frames
  * @he_mu_flags: HE-MU (11ax) flags, only present in HE frames
  * @he_mu_other_flags: HE-MU-OTHER (11ax) flags, only present in HE frames
+ * @usig_flags: USIG flags, only present in 802.11BE and subsequent protocol
+ * @eht_flags: EHT (11be) flags, only present in EHT frames
  * @he_sig_A1_known: HE (11ax) sig A1 known field
  * @he_sig_A2_known: HE (11ax) sig A2 known field
  * @he_sig_b_common: HE (11ax) sig B common field
  * @he_sig_b_common_known: HE (11ax) sig B common known field
  * @l_sig_a_info: L_SIG_A value coming in Rx descriptor
  * @l_sig_b_info: L_SIG_B value coming in Rx descriptor
+ * @num_eht_user_info_valid: Number of valid EHT user info
  * @rate: Rate in terms 500Kbps
  * @rtap_flags: Bit map of available fields in the radiotap
  * @ant_signal_db: Rx packet RSSI
@@ -319,6 +326,12 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
  * @punctured_bw: puntured bw
  * @rx_user_status: pointer to mon_rx_user_status, when set update
  * radiotap header will use userinfo from this structure.
+ * @usig_common: U-SIG property of received frame
+ * @usig_value: U-SIG property of received frame
+ * @usig_mask: U-SIG property of received frame
+ * @eht_known: EHT property of received frame
+ * @eht_data: EHT property of received frame
+ * @eht_user_info: EHT USER property of received frame
  */
 struct mon_rx_status {
 	uint64_t tsft;
@@ -333,12 +346,15 @@ struct mon_rx_status {
 	uint16_t he_flags;
 	uint16_t he_mu_flags;
 	uint16_t he_mu_other_flags;
+	uint16_t usig_flags;
+	uint16_t eht_flags;
 	uint16_t he_sig_A1_known;
 	uint16_t he_sig_A2_known;
 	uint16_t he_sig_b_common;
 	uint16_t he_sig_b_common_known;
 	uint32_t l_sig_a_info;
 	uint32_t l_sig_b_info;
+	uint8_t  num_eht_user_info_valid;
 	uint8_t  rate;
 	uint8_t  rtap_flags;
 	uint8_t  ant_signal_db;
@@ -411,6 +427,12 @@ struct mon_rx_status {
 	uint8_t punctured_bw;
 #endif
 	struct mon_rx_user_status *rx_user_status;
+	uint32_t usig_common;
+	uint32_t usig_value;
+	uint32_t usig_mask;
+	uint32_t eht_known;
+	uint32_t eht_data[6];
+	uint32_t eht_user_info[4];
 };
 
 /**
@@ -740,6 +762,145 @@ struct qdf_radiotap_ext2 {
 #define QDF_MON_STATUS_STA_DCM_KNOWN 0x40
 #define QDF_MON_STATUS_STA_CODING_KNOWN 0x80
 
+/* U-SIG Common Mask */
+#define QDF_MON_STATUS_USIG_PHY_VERSION_KNOWN		0x00000001
+#define QDF_MON_STATUS_USIG_BW_KNOWN			0x00000002
+#define QDF_MON_STATUS_USIG_UL_DL_KNOWN			0x00000004
+#define QDF_MON_STATUS_USIG_BSS_COLOR_KNOWN		0x00000008
+#define QDF_MON_STATUS_USIG_TXOP_KNOWN			0x00000010
+
+#define QDF_MON_STATUS_USIG_PHY_VERSION_SHIFT		12
+#define QDF_MON_STATUS_USIG_BW_SHIFT			15
+#define QDF_MON_STATUS_USIG_UL_DL_SHIFT			18
+#define QDF_MON_STATUS_USIG_BSS_COLOR_SHIFT		19
+#define QDF_MON_STATUS_USIG_TXOP_SHIFT			25
+
+/* U-SIG MU/TB Value */
+#define QDF_MON_STATUS_USIG_DISREGARD_SHIFT			0
+#define QDF_MON_STATUS_USIG_PPDU_TYPE_N_COMP_MODE_SHIFT		6
+#define QDF_MON_STATUS_USIG_VALIDATE_SHIFT			8
+
+#define QDF_MON_STATUS_USIG_MU_VALIDATE1_SHIFT			5
+#define QDF_MON_STATUS_USIG_MU_PUNCTURE_CH_INFO_SHIFT		9
+#define QDF_MON_STATUS_USIG_MU_VALIDATE2_SHIFT			12
+#define QDF_MON_STATUS_USIG_MU_EHT_SIG_MCS_SHIFT		15
+#define QDF_MON_STATUS_USIG_MU_NUM_EHT_SIG_SYM_SHIFT		17
+
+#define QDF_MON_STATUS_USIG_TB_SPATIAL_REUSE_1_SHIFT		9
+#define QDF_MON_STATUS_USIG_TB_SPATIAL_REUSE_2_SHIFT		13
+#define QDF_MON_STATUS_USIG_TB_DISREGARD1_SHIFT			17
+
+#define QDF_MON_STATUS_USIG_CRC_SHIFT				22
+#define QDF_MON_STATUS_USIG_TAIL_SHIFT				26
+
+/* U-SIG MU/TB Mask */
+#define QDF_MON_STATUS_USIG_DISREGARD_KNOWN			0x00000001
+#define QDF_MON_STATUS_USIG_PPDU_TYPE_N_COMP_MODE_KNOWN		0x00000004
+#define QDF_MON_STATUS_USIG_VALIDATE_KNOWN			0x00000008
+
+#define QDF_MON_STATUS_USIG_MU_VALIDATE1_KNOWN			0x00000002
+#define QDF_MON_STATUS_USIG_MU_PUNCTURE_CH_INFO_KNOWN		0x00000010
+#define QDF_MON_STATUS_USIG_MU_VALIDATE2_KNOWN			0x00000020
+#define QDF_MON_STATUS_USIG_MU_EHT_SIG_MCS_KNOWN		0x00000040
+#define QDF_MON_STATUS_USIG_MU_NUM_EHT_SIG_SYM_KNOWN		0x00000080
+
+#define QDF_MON_STATUS_USIG_TB_SPATIAL_REUSE_1_KNOWN		0x00000010
+#define QDF_MON_STATUS_USIG_TB_SPATIAL_REUSE_2_KNOWN		0x00000020
+#define QDF_MON_STATUS_USIG_TB_DISREGARD1_KNOWN			0x00000040
+
+#define QDF_MON_STATUS_USIG_CRC_KNOWN				0x00000100
+#define QDF_MON_STATUS_USIG_TAIL_KNOWN				0x00000200
+
+/* EHT known Mask */
+#define QDF_MON_STATUS_EHT_CONTENT_CH_INDEX_KNOWN		0x00000001
+#define QDF_MON_STATUS_EHT_SPATIAL_REUSE_KNOWN			0x00000002
+#define QDF_MON_STATUS_EHT_GUARD_INTERVAL_KNOWN			0x00000004
+#define QDF_MON_STATUS_EHT_LTF_KNOWN				0x00000008
+#define QDF_MON_STATUS_EHT_EHT_LTF_KNOWN			0x00000010
+#define QDF_MON_STATUS_EHT_LDPC_EXTRA_SYMBOL_SEG_KNOWN		0x00000020
+#define QDF_MON_STATUS_EHT_PRE_FEC_PADDING_FACTOR_KNOWN		0x00000040
+#define QDF_MON_STATUS_EHT_PE_DISAMBIGUITY_KNOWN		0x00000080
+#define QDF_MON_STATUS_EHT_DISREARD_KNOWN			0x00000100
+#define QDF_MON_STATUS_EHT_CRC1_KNOWN				0x00002000
+#define QDF_MON_STATUS_EHT_TAIL1_KNOWN				0x00004000
+#define QDF_MON_STATUS_EHT_CRC2_KNOWN				0x00008000
+#define QDF_MON_STATUS_EHT_TAIL2_KNOWN				0x00010000
+#define QDF_MON_STATUS_EHT_RU_MRU_SIZE_KNOWN			0x00400000
+#define QDF_MON_STATUS_EHT_RU_MRU_INDEX_KNOWN			0x00800000
+#define QDF_MON_STATUS_EHT_TB_RU_ALLOCATION_KNOWN		0x01000000
+
+#define QDF_MON_STATUS_EHT_NUM_NON_OFDMA_USERS_KNOWN		0x00080000
+#define QDF_MON_STATUS_EHT_USER_ENC_BLOCK_CRC_KNOWN		0x00100000
+#define QDF_MON_STATUS_EHT_USER_ENC_BLOCK_TAIL_KNOWN		0x00200000
+
+#define QDF_MON_STATUS_EHT_NDP_DISREGARD_KNOWN			0x00000200
+#define QDF_MON_STATUS_EHT_NDP_NSS_KNOWN			0x00020000
+#define QDF_MON_STATUS_EHT_NDP_BEAMFORMED_KNOWN			0x00040000
+
+#define QDF_MON_STATUS_EHT_NUM_KNOWN_RU_ALLOCATIONS_SHIFT	10
+
+/* EHT data0 Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_CONTENT_CH_INDEX_SHIFT		0
+#define QDF_MON_STATUS_EHT_SPATIAL_REUSE_SHIFT			3
+#define QDF_MON_STATUS_EHT_GI_SHIFT				7
+#define QDF_MON_STATUS_EHT_LTF_SHIFT				9
+#define QDF_MON_STATUS_EHT_EHT_LTF_SHIFT			11
+#define QDF_MON_STATUS_EHT_LDPC_EXTRA_SYMBOL_SEG_SHIFT		14
+#define QDF_MON_STATUS_EHT_PRE_FEC_PADDING_FACTOR_SHIFT		15
+#define QDF_MON_STATUS_EHT_PE_DISAMBIGUITY_SHIFT		17
+#define QDF_MON_STATUS_EHT_NDP_DISREGARD_SHIFT			18
+#define QDF_MON_STATUS_EHT_DISREGARD_SHIFT			18
+#define QDF_MON_STATUS_EHT_CRC1_SHIFT				22
+#define QDF_MON_STATUS_EHT_TAIL1_SHIFT				26
+
+/* EHT data1 Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_RU_MRU_SIZE_SHIFT			0
+#define QDF_MON_STATUS_EHT_RU_MRU_INDEX_SHIFT			5
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION1_1_SHIFT		13
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION1_2_SHIFT		22
+
+/* EHT data2 Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION2_1_SHIFT		0
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION2_2_SHIFT		9
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION2_3_SHIFT		18
+
+/* EHT data3 Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION2_4_SHIFT		0
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION2_5_SHIFT		9
+#define QDF_MON_STATUS_EHT_RU_ALLOCATION2_6_SHIFT		18
+
+/* EHT data4 Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_CRC2_SHIFT				0
+#define QDF_MON_STATUS_EHT_TAIL2_SHIFT				4
+#define QDF_MON_STATUS_EHT_NDP_NSS_SHIFT			12
+#define QDF_MON_STATUS_EHT_NDP_BEAMFORMED_SHIFT			16
+#define QDF_MON_STATUS_EHT_NUM_NON_OFDMA_USERS_SHIFT		17
+#define QDF_MON_STATUS_EHT_USER_ENC_BLOCK_CRC_SHIFT		20
+#define QDF_MON_STATUS_EHT_USER_ENC_BLOCK_TAIL_SHIFT		24
+
+/* EHT data5 Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_TB_RU_PS160_SHIFT			0
+#define QDF_MON_STATUS_EHT_TB_RU_PS80_SHIFT			1
+#define QDF_MON_STATUS_EHT_TB_RU_B7_B1_SHIFT			2
+
+/* EHT user info Mask/SHIFT */
+#define QDF_MON_STATUS_EHT_USER_STA_ID_KNOWN			0x00000001
+#define QDF_MON_STATUS_EHT_USER_MCS_KNOWN			0x00000002
+#define QDF_MON_STATUS_EHT_USER_CODING_KNOWN			0x00000004
+#define QDF_MON_STATUS_EHT_USER_RESERVED_KNOWN			0x00000008
+#define QDF_MON_STATUS_EHT_USER_NSS_KNOWN			0x00000010
+#define QDF_MON_STATUS_EHT_USER_BEAMFORMING_KNOWN		0x00000020
+#define QDF_MON_STATUS_EHT_USER_SPATIAL_CONFIG_KNOWN		0x00000040
+
+#define QDF_MON_STATUS_EHT_USER_DATA_FOR_THIS_USER_SHIFT	7
+#define QDF_MON_STATUS_EHT_USER_STA_ID_SHIFT			8
+#define QDF_MON_STATUS_EHT_USER_CODING_SHIFT			19
+#define QDF_MON_STATUS_EHT_USER_MCS_SHIFT			20
+#define QDF_MON_STATUS_EHT_USER_NSS_SHIFT			24
+#define QDF_MON_STATUS_EHT_USER_RESERVED_SHIFT			28
+#define QDF_MON_STATUS_EHT_USER_BEAMFORMING_SHIFT		29
+#define QDF_MON_STATUS_EHT_USER_SPATIAL_CONFIG_SHIFT		24
+
 /**
  * enum qdf_proto_type - protocol type
  * @QDF_PROTO_TYPE_DHCP - DHCP

+ 3 - 0
qdf/linux/src/i_qdf_nbuf.h

@@ -80,6 +80,9 @@ typedef struct sk_buff_head __qdf_nbuf_queue_head_t;
 
 #define IEEE80211_RADIOTAP_HE_MU_OTHER 25
 
+#define IEEE80211_RADIOTAP_EXT1_USIG	1
+#define IEEE80211_RADIOTAP_EXT1_EHT	2
+
 /* mark the first packet after wow wakeup */
 #define QDF_MARK_FIRST_WAKEUP_PACKET   0x80000000
 

+ 160 - 26
qdf/linux/src/qdf_nbuf.c

@@ -4813,6 +4813,102 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status,
 	return rtap_len;
 }
 
+/**
+ * qdf_nbuf_update_radiotap_usig_flags() - Update radiotap header with USIG data
+ *						from rx_status
+ * @rx_status: Pointer to rx_status.
+ * @rtap_buf: buffer to which radiotap has to be updated
+ * @rtap_len: radiotap length
+ *
+ * API update Extra High Throughput (11be) fields in the radiotap header
+ *
+ * Return: length of rtap_len updated.
+ */
+static unsigned int
+qdf_nbuf_update_radiotap_usig_flags(struct mon_rx_status *rx_status,
+				    int8_t *rtap_buf, uint32_t rtap_len)
+{
+	/*
+	 * IEEE80211_RADIOTAP_USIG:
+	 *		u32, u32, u32
+	 */
+	rtap_len = qdf_align(rtap_len, 4);
+
+	put_unaligned_le32(rx_status->usig_common, &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->usig_value, &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->usig_mask, &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	qdf_rl_debug("U-SIG data %x %x %x",
+		     rx_status->usig_common, rx_status->usig_value,
+		     rx_status->usig_mask);
+
+	return rtap_len;
+}
+
+/**
+ * qdf_nbuf_update_radiotap_eht_flags() - Update radiotap header with EHT data
+ *					from rx_status
+ * @rx_status: Pointer to rx_status.
+ * @rtap_buf: buffer to which radiotap has to be updated
+ * @rtap_len: radiotap length
+ *
+ * API update Extra High Throughput (11be) fields in the radiotap header
+ *
+ * Return: length of rtap_len updated.
+ */
+static unsigned int
+qdf_nbuf_update_radiotap_eht_flags(struct mon_rx_status *rx_status,
+				   int8_t *rtap_buf, uint32_t rtap_len)
+{
+	uint32_t user;
+
+	/*
+	 * IEEE80211_RADIOTAP_EHT:
+	 *		u32, u32, u32, u32, u32, u32, u32, u16, [u32, u32, u32]
+	 */
+	rtap_len = qdf_align(rtap_len, 4);
+
+	put_unaligned_le32(rx_status->eht_known, &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->eht_data[0], &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->eht_data[1], &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->eht_data[2], &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->eht_data[3], &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->eht_data[4], &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	put_unaligned_le32(rx_status->eht_data[5], &rtap_buf[rtap_len]);
+	rtap_len += 4;
+
+	for (user = 0; user < rx_status->num_eht_user_info_valid; user++) {
+		put_unaligned_le32(rx_status->eht_user_info[user],
+				   &rtap_buf[rtap_len]);
+		rtap_len += 4;
+	}
+
+	qdf_rl_debug("EHT data %x %x %x %x %x %x %x",
+		     rx_status->eht_known, rx_status->eht_data[0],
+		     rx_status->eht_data[1], rx_status->eht_data[2],
+		     rx_status->eht_data[3], rx_status->eht_data[4],
+		     rx_status->eht_data[5]);
+
+	return rtap_len;
+}
+
 #define IEEE80211_RADIOTAP_TX_STATUS 0
 #define IEEE80211_RADIOTAP_RETRY_COUNT 1
 #define IEEE80211_RADIOTAP_EXTENSION2 2
@@ -4879,25 +4975,32 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	uint8_t length = rtap_len;
 	struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath;
 	struct qdf_radiotap_ext2 *rtap_ext2;
-	uint32_t *rtap_ext = NULL;
 	struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status;
 
 	/* per user info */
+	qdf_le32_t *it_present;
+	uint32_t it_present_val;
+	bool radiotap_ext1_hdr_present = false;
+
+	it_present = &rthdr->it_present;
 
 	/* Adding Extended Header space */
-	if (rx_status->add_rtap_ext) {
+	if (rx_status->add_rtap_ext || rx_status->add_rtap_ext2 ||
+	    rx_status->usig_flags || rx_status->eht_flags) {
 		rtap_hdr_len += RADIOTAP_HEADER_EXT_LEN;
 		rtap_len = rtap_hdr_len;
+		radiotap_ext1_hdr_present = true;
 	}
+
 	length = rtap_len;
 
 	/* IEEE80211_RADIOTAP_TSFT              __le64       microseconds*/
-	rthdr->it_present = (1 << IEEE80211_RADIOTAP_TSFT);
+	it_present_val = (1 << IEEE80211_RADIOTAP_TSFT);
 	put_unaligned_le64(rx_status->tsft, &rtap_buf[rtap_len]);
 	rtap_len += 8;
 
 	/* IEEE80211_RADIOTAP_FLAGS u8 */
-	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS);
+	it_present_val |= (1 << IEEE80211_RADIOTAP_FLAGS);
 
 	if (rx_status->rs_fcs_err)
 		rx_status->rtap_flags |= IEEE80211_RADIOTAP_F_BADFCS;
@@ -4908,14 +5011,14 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	/* IEEE80211_RADIOTAP_RATE  u8           500kb/s */
 	if (!rx_status->ht_flags && !rx_status->vht_flags &&
 	    !rx_status->he_flags) {
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_RATE);
 		rtap_buf[rtap_len] = rx_status->rate;
 	} else
 		rtap_buf[rtap_len] = 0;
 	rtap_len += 1;
 
 	/* IEEE80211_RADIOTAP_CHANNEL 2 x __le16   MHz, bitmap */
-	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
+	it_present_val |= (1 << IEEE80211_RADIOTAP_CHANNEL);
 	put_unaligned_le16(rx_status->chan_freq, &rtap_buf[rtap_len]);
 	rtap_len += 2;
 	/* Channel flags. */
@@ -4933,7 +5036,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8  decibels from one milliwatt
 	 *					(dBm)
 	 */
-	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
+	it_present_val |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
 	/*
 	 * rssi_comb is int dB, need to convert it to dBm.
 	 * normalize value to noise floor of -96 dBm
@@ -4942,12 +5045,12 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	rtap_len += 1;
 
 	/* RX signal noise floor */
-	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
+	it_present_val |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
 	rtap_buf[rtap_len] = (uint8_t)rx_status->chan_noise_floor;
 	rtap_len += 1;
 
 	/* IEEE80211_RADIOTAP_ANTENNA   u8      antenna index */
-	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA);
+	it_present_val |= (1 << IEEE80211_RADIOTAP_ANTENNA);
 	rtap_buf[rtap_len] = rx_status->nr_ant;
 	rtap_len += 1;
 
@@ -4959,7 +5062,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	if (rx_status->ht_flags) {
 		length = rtap_len;
 		/* IEEE80211_RADIOTAP_VHT u8, u8, u8 */
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_MCS);
 		rtap_buf[rtap_len] = IEEE80211_RADIOTAP_MCS_HAVE_BW |
 					IEEE80211_RADIOTAP_MCS_HAVE_MCS |
 					IEEE80211_RADIOTAP_MCS_HAVE_GI;
@@ -4984,7 +5087,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 
 	if (rx_status->rs_flags & IEEE80211_AMPDU_FLAG) {
 		/* IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 */
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_AMPDU_STATUS);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_AMPDU_STATUS);
 		rtap_len = qdf_nbuf_update_radiotap_ampdu_flags(rx_status,
 								rtap_buf,
 								rtap_len);
@@ -4993,7 +5096,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	if (rx_status->vht_flags) {
 		length = rtap_len;
 		/* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 */
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_VHT);
 		rtap_len = qdf_nbuf_update_radiotap_vht_flags(rx_status,
 								rtap_buf,
 								rtap_len);
@@ -5007,7 +5110,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	if (rx_status->he_flags) {
 		length = rtap_len;
 		/* IEEE80211_RADIOTAP_HE */
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_HE);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_HE);
 		rtap_len = qdf_nbuf_update_radiotap_he_flags(rx_status,
 								rtap_buf,
 								rtap_len);
@@ -5021,7 +5124,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	if (rx_status->he_mu_flags) {
 		length = rtap_len;
 		/* IEEE80211_RADIOTAP_HE-MU */
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_HE_MU);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_HE_MU);
 		rtap_len = qdf_nbuf_update_radiotap_he_mu_flags(rx_status,
 								rtap_buf,
 								rtap_len);
@@ -5035,7 +5138,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	if (rx_status->he_mu_other_flags) {
 		length = rtap_len;
 		/* IEEE80211_RADIOTAP_HE-MU-OTHER */
-		rthdr->it_present |= (1 << IEEE80211_RADIOTAP_HE_MU_OTHER);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_HE_MU_OTHER);
 		rtap_len =
 			qdf_nbuf_update_radiotap_he_mu_other_flags(rx_status,
 								rtap_buf,
@@ -5051,7 +5154,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 	/*
 	 * Radiotap Vendor Namespace
 	 */
-	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
+	it_present_val |= (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
 	radiotap_vendor_ns_ath = (struct qdf_radiotap_vendor_ns_ath *)
 					(rtap_buf + rtap_len);
 	/*
@@ -5073,13 +5176,18 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 				cpu_to_le32(rx_status->ppdu_timestamp);
 	rtap_len += sizeof(*radiotap_vendor_ns_ath);
 
+	/* Move to next it_present */
+	if (radiotap_ext1_hdr_present) {
+		it_present_val |= (1 << IEEE80211_RADIOTAP_EXT);
+		put_unaligned_le32(it_present_val, it_present);
+		it_present_val = 0;
+		it_present++;
+	}
+
 	/* Add Extension to Radiotap Header & corresponding data */
 	if (rx_status->add_rtap_ext) {
-		rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT);
-		rtap_ext = (uint32_t *)&rthdr->it_present;
-		rtap_ext++;
-		*rtap_ext = cpu_to_le32(1 << IEEE80211_RADIOTAP_TX_STATUS);
-		*rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RETRY_COUNT);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_TX_STATUS);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_RETRY_COUNT);
 
 		rtap_buf[rtap_len] = rx_status->tx_status;
 		rtap_len += 1;
@@ -5089,10 +5197,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 
 	/* Add Extension2 to Radiotap Header */
 	if (rx_status->add_rtap_ext2) {
-		rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT);
-		rtap_ext = (uint32_t *)&rthdr->it_present;
-		rtap_ext++;
-		*rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXTENSION2);
+		it_present_val |= (1 << IEEE80211_RADIOTAP_EXTENSION2);
 
 		rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len);
 		rtap_ext2->ppdu_id = rx_status->ppdu_id;
@@ -5118,13 +5223,42 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 		rtap_len += sizeof(*rtap_ext2);
 	}
 
+	if (rx_status->usig_flags) {
+		length = rtap_len;
+		/* IEEE80211_RADIOTAP_USIG */
+		it_present_val |= (1 << IEEE80211_RADIOTAP_EXT1_USIG);
+		rtap_len = qdf_nbuf_update_radiotap_usig_flags(rx_status,
+							       rtap_buf,
+							       rtap_len);
+
+		if ((rtap_len - length) > RADIOTAP_EHT_FLAGS_LEN) {
+			qdf_print("length is greater than RADIOTAP_EHT_FLAGS_LEN");
+			return 0;
+		}
+	}
+
+	if (rx_status->eht_flags) {
+		length = rtap_len;
+		/* IEEE80211_RADIOTAP_EHT */
+		it_present_val |= (1 << IEEE80211_RADIOTAP_EXT1_EHT);
+		rtap_len = qdf_nbuf_update_radiotap_eht_flags(rx_status,
+							      rtap_buf,
+							      rtap_len);
+
+		if ((rtap_len - length) > RADIOTAP_EHT_FLAGS_LEN) {
+			qdf_print("length is greater than RADIOTAP_EHT_FLAGS_LEN");
+			return 0;
+		}
+	}
+
+	put_unaligned_le32(it_present_val, it_present);
 	rthdr->it_len = cpu_to_le16(rtap_len);
-	rthdr->it_present = cpu_to_le32(rthdr->it_present);
 
 	if (headroom_sz < rtap_len) {
 		qdf_debug("DEBUG: Not enough space to update radiotap");
 		return 0;
 	}
+
 	qdf_nbuf_push_head(nbuf, rtap_len);
 	qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len);
 	return rtap_len;