qcacmn: Add EHT radiotap header fields

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

Change-Id: If988753b497cc2feb79f358afea2674effd8270c
CRs-Fixed: 3092818
This commit is contained in:
Rakesh Pillai
2021-12-10 02:04:36 -08:00
committed by Madan Koyyalamudi
parent 6ee7701aab
commit 1c6617edf5
3 changed files with 325 additions and 27 deletions

View File

@@ -212,6 +212,8 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
#define RADIOTAP_HE_FLAGS_LEN (12 + 1) #define RADIOTAP_HE_FLAGS_LEN (12 + 1)
#define RADIOTAP_HE_MU_FLAGS_LEN (8 + 1) #define RADIOTAP_HE_MU_FLAGS_LEN (8 + 1)
#define RADIOTAP_HE_MU_OTHER_FLAGS_LEN (18 + 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_FIXED_HEADER_LEN 17
#define RADIOTAP_HT_FLAGS_LEN 3 #define RADIOTAP_HT_FLAGS_LEN 3
#define RADIOTAP_AMPDU_STATUS_LEN (8 + 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_HE_MU_OTHER_FLAGS_LEN + \
RADIOTAP_VENDOR_NS_LEN + \ RADIOTAP_VENDOR_NS_LEN + \
RADIOTAP_HEADER_EXT_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 * 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_flags: HE (11ax) flags, only present in HE frames
* @he_mu_flags: HE-MU (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 * @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_A1_known: HE (11ax) sig A1 known field
* @he_sig_A2_known: HE (11ax) sig A2 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: HE (11ax) sig B common field
* @he_sig_b_common_known: HE (11ax) sig B common known 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_a_info: L_SIG_A value coming in Rx descriptor
* @l_sig_b_info: L_SIG_B 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 * @rate: Rate in terms 500Kbps
* @rtap_flags: Bit map of available fields in the radiotap * @rtap_flags: Bit map of available fields in the radiotap
* @ant_signal_db: Rx packet RSSI * @ant_signal_db: Rx packet RSSI
@@ -319,6 +326,12 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
* @punctured_bw: puntured bw * @punctured_bw: puntured bw
* @rx_user_status: pointer to mon_rx_user_status, when set update * @rx_user_status: pointer to mon_rx_user_status, when set update
* radiotap header will use userinfo from this structure. * 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 { struct mon_rx_status {
uint64_t tsft; uint64_t tsft;
@@ -333,12 +346,15 @@ struct mon_rx_status {
uint16_t he_flags; uint16_t he_flags;
uint16_t he_mu_flags; uint16_t he_mu_flags;
uint16_t he_mu_other_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_A1_known;
uint16_t he_sig_A2_known; uint16_t he_sig_A2_known;
uint16_t he_sig_b_common; uint16_t he_sig_b_common;
uint16_t he_sig_b_common_known; uint16_t he_sig_b_common_known;
uint32_t l_sig_a_info; uint32_t l_sig_a_info;
uint32_t l_sig_b_info; uint32_t l_sig_b_info;
uint8_t num_eht_user_info_valid;
uint8_t rate; uint8_t rate;
uint8_t rtap_flags; uint8_t rtap_flags;
uint8_t ant_signal_db; uint8_t ant_signal_db;
@@ -411,6 +427,12 @@ struct mon_rx_status {
uint8_t punctured_bw; uint8_t punctured_bw;
#endif #endif
struct mon_rx_user_status *rx_user_status; 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_DCM_KNOWN 0x40
#define QDF_MON_STATUS_STA_CODING_KNOWN 0x80 #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 * enum qdf_proto_type - protocol type
* @QDF_PROTO_TYPE_DHCP - DHCP * @QDF_PROTO_TYPE_DHCP - DHCP

View File

@@ -80,6 +80,9 @@ typedef struct sk_buff_head __qdf_nbuf_queue_head_t;
#define IEEE80211_RADIOTAP_HE_MU_OTHER 25 #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 */ /* mark the first packet after wow wakeup */
#define QDF_MARK_FIRST_WAKEUP_PACKET 0x80000000 #define QDF_MARK_FIRST_WAKEUP_PACKET 0x80000000

View File

@@ -4813,6 +4813,102 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status,
return rtap_len; 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_TX_STATUS 0
#define IEEE80211_RADIOTAP_RETRY_COUNT 1 #define IEEE80211_RADIOTAP_RETRY_COUNT 1
#define IEEE80211_RADIOTAP_EXTENSION2 2 #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; uint8_t length = rtap_len;
struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath; struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath;
struct qdf_radiotap_ext2 *rtap_ext2; struct qdf_radiotap_ext2 *rtap_ext2;
uint32_t *rtap_ext = NULL;
struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status;
/* per user info */ /* 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 */ /* 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_hdr_len += RADIOTAP_HEADER_EXT_LEN;
rtap_len = rtap_hdr_len; rtap_len = rtap_hdr_len;
radiotap_ext1_hdr_present = true;
} }
length = rtap_len; length = rtap_len;
/* IEEE80211_RADIOTAP_TSFT __le64 microseconds*/ /* 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]); put_unaligned_le64(rx_status->tsft, &rtap_buf[rtap_len]);
rtap_len += 8; rtap_len += 8;
/* IEEE80211_RADIOTAP_FLAGS u8 */ /* IEEE80211_RADIOTAP_FLAGS u8 */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS); it_present_val |= (1 << IEEE80211_RADIOTAP_FLAGS);
if (rx_status->rs_fcs_err) if (rx_status->rs_fcs_err)
rx_status->rtap_flags |= IEEE80211_RADIOTAP_F_BADFCS; 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 */ /* IEEE80211_RADIOTAP_RATE u8 500kb/s */
if (!rx_status->ht_flags && !rx_status->vht_flags && if (!rx_status->ht_flags && !rx_status->vht_flags &&
!rx_status->he_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; rtap_buf[rtap_len] = rx_status->rate;
} else } else
rtap_buf[rtap_len] = 0; rtap_buf[rtap_len] = 0;
rtap_len += 1; rtap_len += 1;
/* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap */ /* 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]); put_unaligned_le16(rx_status->chan_freq, &rtap_buf[rtap_len]);
rtap_len += 2; rtap_len += 2;
/* Channel flags. */ /* 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 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from one milliwatt
* (dBm) * (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. * rssi_comb is int dB, need to convert it to dBm.
* normalize value to noise floor of -96 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; rtap_len += 1;
/* RX signal noise floor */ /* 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_buf[rtap_len] = (uint8_t)rx_status->chan_noise_floor;
rtap_len += 1; rtap_len += 1;
/* IEEE80211_RADIOTAP_ANTENNA u8 antenna index */ /* 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_buf[rtap_len] = rx_status->nr_ant;
rtap_len += 1; rtap_len += 1;
@@ -4959,7 +5062,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->ht_flags) { if (rx_status->ht_flags) {
length = rtap_len; length = rtap_len;
/* IEEE80211_RADIOTAP_VHT u8, u8, u8 */ /* 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 | rtap_buf[rtap_len] = IEEE80211_RADIOTAP_MCS_HAVE_BW |
IEEE80211_RADIOTAP_MCS_HAVE_MCS | IEEE80211_RADIOTAP_MCS_HAVE_MCS |
IEEE80211_RADIOTAP_MCS_HAVE_GI; 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) { if (rx_status->rs_flags & IEEE80211_AMPDU_FLAG) {
/* IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 */ /* 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_len = qdf_nbuf_update_radiotap_ampdu_flags(rx_status,
rtap_buf, rtap_buf,
rtap_len); rtap_len);
@@ -4993,7 +5096,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->vht_flags) { if (rx_status->vht_flags) {
length = rtap_len; length = rtap_len;
/* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 */ /* 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_len = qdf_nbuf_update_radiotap_vht_flags(rx_status,
rtap_buf, rtap_buf,
rtap_len); rtap_len);
@@ -5007,7 +5110,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->he_flags) { if (rx_status->he_flags) {
length = rtap_len; length = rtap_len;
/* IEEE80211_RADIOTAP_HE */ /* 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_len = qdf_nbuf_update_radiotap_he_flags(rx_status,
rtap_buf, rtap_buf,
rtap_len); rtap_len);
@@ -5021,7 +5124,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->he_mu_flags) { if (rx_status->he_mu_flags) {
length = rtap_len; length = rtap_len;
/* IEEE80211_RADIOTAP_HE-MU */ /* 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_len = qdf_nbuf_update_radiotap_he_mu_flags(rx_status,
rtap_buf, rtap_buf,
rtap_len); 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) { if (rx_status->he_mu_other_flags) {
length = rtap_len; length = rtap_len;
/* IEEE80211_RADIOTAP_HE-MU-OTHER */ /* 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 = rtap_len =
qdf_nbuf_update_radiotap_he_mu_other_flags(rx_status, qdf_nbuf_update_radiotap_he_mu_other_flags(rx_status,
rtap_buf, rtap_buf,
@@ -5051,7 +5154,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
/* /*
* Radiotap Vendor Namespace * 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 *) radiotap_vendor_ns_ath = (struct qdf_radiotap_vendor_ns_ath *)
(rtap_buf + rtap_len); (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); cpu_to_le32(rx_status->ppdu_timestamp);
rtap_len += sizeof(*radiotap_vendor_ns_ath); 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 */ /* Add Extension to Radiotap Header & corresponding data */
if (rx_status->add_rtap_ext) { if (rx_status->add_rtap_ext) {
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT); it_present_val |= (1 << IEEE80211_RADIOTAP_TX_STATUS);
rtap_ext = (uint32_t *)&rthdr->it_present; it_present_val |= (1 << IEEE80211_RADIOTAP_RETRY_COUNT);
rtap_ext++;
*rtap_ext = cpu_to_le32(1 << IEEE80211_RADIOTAP_TX_STATUS);
*rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RETRY_COUNT);
rtap_buf[rtap_len] = rx_status->tx_status; rtap_buf[rtap_len] = rx_status->tx_status;
rtap_len += 1; rtap_len += 1;
@@ -5089,10 +5197,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
/* Add Extension2 to Radiotap Header */ /* Add Extension2 to Radiotap Header */
if (rx_status->add_rtap_ext2) { if (rx_status->add_rtap_ext2) {
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT); it_present_val |= (1 << IEEE80211_RADIOTAP_EXTENSION2);
rtap_ext = (uint32_t *)&rthdr->it_present;
rtap_ext++;
*rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXTENSION2);
rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len); rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len);
rtap_ext2->ppdu_id = rx_status->ppdu_id; 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); 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_len = cpu_to_le16(rtap_len);
rthdr->it_present = cpu_to_le32(rthdr->it_present);
if (headroom_sz < rtap_len) { if (headroom_sz < rtap_len) {
qdf_debug("DEBUG: Not enough space to update radiotap"); qdf_debug("DEBUG: Not enough space to update radiotap");
return 0; return 0;
} }
qdf_nbuf_push_head(nbuf, rtap_len); qdf_nbuf_push_head(nbuf, rtap_len);
qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len); qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len);
return rtap_len; return rtap_len;