diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index ddcc4bb835..d2bf4baf24 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/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 diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 8b101d99be..ac6aed75b4 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/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 diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 3fb7647551..12f2d90c1f 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/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;