/*
|
* RadioTap utility routines for WL and Apps
|
* This header file housing the define and function prototype use by
|
* both the wl driver, tools & Apps.
|
*
|
* Copyright (C) 2020, Broadcom.
|
*
|
* Unless you and Broadcom execute a separate written software license
|
* agreement governing use of this software, this software is licensed to you
|
* under the terms of the GNU General Public License version 2 (the "GPL"),
|
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
|
* following added to such license:
|
*
|
* As a special exception, the copyright holders of this software give you
|
* permission to link this software with independent modules, and to copy and
|
* distribute the resulting executable under terms of your choice, provided that
|
* you also meet, for each linked independent module, the terms and conditions of
|
* the license of that module. An independent module is a module which is not
|
* derived from this software. The special exception does not apply to any
|
* modifications of the software.
|
*
|
*
|
* <<Broadcom-WL-IPTag/Dual:>>
|
*/
|
|
#ifndef _BCMWIFI_RADIOTAP_H_
|
#define _BCMWIFI_RADIOTAP_H_
|
|
#include <ieee80211_radiotap.h>
|
#include <siutils.h>
|
#include <monitor.h>
|
#include <802.11.h>
|
#include <802.11ax.h>
|
#include "bcmwifi_monitor.h"
|
#include <bcmwifi_rspec.h>
|
#include <bcmwifi_rates.h>
|
|
/* This marks the start of a packed structure section. */
|
#include <packed_section_start.h>
|
/*
|
* RadioTap header specific implementation. Used by MacOS implementation only.
|
*/
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_hdr {
|
struct ieee80211_radiotap_header ieee_radiotap;
|
uint64 tsft;
|
uint8 flags;
|
union {
|
uint8 rate;
|
uint8 pad;
|
} u;
|
uint16 channel_freq;
|
uint16 channel_flags;
|
} BWL_POST_PACKED_STRUCT;
|
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_sna {
|
uint8 signal;
|
uint8 noise;
|
uint8 antenna;
|
} BWL_POST_PACKED_STRUCT;
|
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_xchan {
|
uint32 xchannel_flags;
|
uint16 xchannel_freq;
|
uint8 xchannel_channel;
|
uint8 xchannel_maxpower;
|
} BWL_POST_PACKED_STRUCT;
|
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_ampdu {
|
uint32 ref_num;
|
uint16 flags;
|
uint8 delimiter_crc;
|
uint8 reserved;
|
} BWL_POST_PACKED_STRUCT;
|
|
BWL_PRE_PACKED_STRUCT struct wl_htmcs {
|
uint8 mcs_known;
|
uint8 mcs_flags;
|
uint8 mcs_index;
|
uint8 pad; /* pad to 32 bit aligned */
|
} BWL_POST_PACKED_STRUCT;
|
|
BWL_PRE_PACKED_STRUCT struct wl_vhtmcs {
|
uint16 vht_known; /* IEEE80211_RADIOTAP_VHT */
|
uint8 vht_flags;
|
uint8 vht_bw;
|
uint8 vht_mcs_nss[4];
|
uint8 vht_coding;
|
uint8 vht_group_id;
|
uint16 vht_partial_aid;
|
} BWL_POST_PACKED_STRUCT;
|
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_ht_tail {
|
struct wl_radiotap_xchan xc;
|
struct wl_radiotap_ampdu ampdu;
|
union {
|
struct wl_htmcs ht;
|
struct wl_vhtmcs vht;
|
} u;
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct bsd_header_rx {
|
struct wl_radiotap_hdr hdr;
|
/*
|
* include extra space beyond wl_radiotap_ht size
|
* (larger of two structs in union):
|
* signal/noise/ant plus max of 3 pad for xchannel
|
* tail struct (xchannel and MCS info)
|
*/
|
uint8 pad[3];
|
uint8 ht[sizeof(struct wl_radiotap_ht_tail)];
|
} bsd_header_rx_t;
|
|
typedef struct radiotap_parse {
|
struct ieee80211_radiotap_header *hdr;
|
void *fields;
|
uint fields_len;
|
uint idx;
|
uint offset;
|
} radiotap_parse_t;
|
|
struct rtap_field {
|
uint len;
|
uint align;
|
};
|
|
/* he radiotap - https://www.radiotap.org/fields/HE.html */
|
#define HE_RADIOTAP_BSS_COLOR_SHIFT 0u
|
#define HE_RADIOTAP_BEAM_CHANGE_SHIFT 6u
|
#define HE_RADIOTAP_DL_UL_SHIFT 7u
|
#define HE_RADIOTAP_MCS_SHIFT 8u
|
#define HE_RADIOTAP_DCM_SHIFT 12u
|
#define HE_RADIOTAP_CODING_SHIFT 13u
|
#define HE_RADIOTAP_LDPC_SHIFT 14u
|
#define HE_RADIOTAP_STBC_SHIFT 15u
|
#define HE_RADIOTAP_SR_SHIFT 0u
|
#define HE_RADIOTAP_STAID_SHIFT 4u
|
#define HE_RADIOTAP_SR1_SHIFT 0u
|
#define HE_RADIOTAP_SR2_SHIFT 4u
|
#define HE_RADIOTAP_SR3_SHIFT 8u
|
#define HE_RADIOTAP_SR4_SHIFT 12u
|
#define HE_RADIOTAP_BW_SHIFT 0u
|
#define HE_RADIOTAP_RU_ALLOC_SHIFT 0u
|
#define HE_RADIOTAP_GI_SHIFT 4u
|
#define HE_RADIOTAP_LTF_SIZE_SHIFT 6u
|
#define HE_RADIOTAP_NUM_LTF_SHIFT 8u
|
#define HE_RADIOTAP_PADDING_SHIFT 12u
|
#define HE_RADIOTAP_TXBF_SHIFT 14u
|
#define HE_RADIOTAP_PE_SHIFT 15u
|
#define HE_RADIOTAP_NSTS_SHIFT 0u
|
#define HE_RADIOTAP_DOPPLER_SHIFT 4u
|
#define HE_RADIOTAP_TXOP_SHIFT 8u
|
#define HE_RADIOTAP_MIDAMBLE_SHIFT 15u
|
#define HE_RADIOTAP_DOPPLER_SET_NSTS_SHIFT 0u
|
#define HE_RADIOTAP_DOPPLER_NOTSET_NSTS_SHIFT 0u
|
|
/* he mu radiotap - https://www.radiotap.org/fields/HE-MU.html */
|
#define HE_RADIOTAP_SIGB_MCS_SHIFT 0u
|
#define HE_RADIOTAP_SIGB_MCS_KNOWN_SHIFT 4u
|
#define HE_RADIOTAP_SIGB_DCM_SHIFT 5u
|
#define HE_RADIOTAP_SIGB_DCM_KNOWN_SHIFT 6u
|
#define HE_RADIOTAP_SIGB_COMP_KNOWN_SHIFT 14u
|
#define HE_RADIOTAP_SIGB_COMP_SHIFT 3u
|
#define HE_RADIOTAP_SIGB_SYMB_SHIFT 18u
|
#define HE_RADIOTAP_BW_SIGA_SHIFT 0u
|
#define HE_RADIOTAP_BW_SIGA_KNOWN_SHIFT 2u
|
#define HE_RADIOTAP_SIGB_SYM_MU_MIMO_USER_SHIFT 4u
|
#define HE_RADIOTAP_PRE_PUNCR_SIGA_SHIFT 8u
|
#define HE_RADIOTAP_PRE_PUNCR_SIGA_KNOWN_SHIFT 10u
|
|
#define WL_RADIOTAP_BRCM_SNS 0x01
|
#define WL_RADIOTAP_BRCM_MCS 0x00000001
|
#define WL_RADIOTAP_LEGACY_SNS 0x02
|
#define WL_RADIOTAP_LEGACY_VHT 0x00000001
|
#define WL_RADIOTAP_BRCM_PAD_SNS 0x3
|
|
#define IEEE80211_RADIOTAP_HTMOD_40 0x01
|
#define IEEE80211_RADIOTAP_HTMOD_SGI 0x02
|
#define IEEE80211_RADIOTAP_HTMOD_GF 0x04
|
#define IEEE80211_RADIOTAP_HTMOD_LDPC 0x08
|
#define IEEE80211_RADIOTAP_HTMOD_STBC_MASK 0x30
|
#define IEEE80211_RADIOTAP_HTMOD_STBC_SHIFT 4
|
|
/* Dyanmic bandwidth for VHT signaled in NONHT */
|
#define WL_RADIOTAP_F_NONHT_VHT_DYN_BW 0x01
|
/* VHT BW is valid in NONHT */
|
#define WL_RADIOTAP_F_NONHT_VHT_BW 0x02
|
|
typedef struct ieee80211_radiotap_header ieee80211_radiotap_header_t;
|
|
/* VHT information in non-HT frames; primarily VHT b/w signaling
|
* in frames received at legacy rates.
|
*/
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_nonht_vht {
|
uint8 len; /* length of the field excluding 'len' field */
|
uint8 flags;
|
uint8 bw;
|
uint8 PAD; /* Add a pad so the next vendor entry, if any, will be 16 bit aligned */
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct wl_radiotap_nonht_vht wl_radiotap_nonht_vht_t;
|
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_basic {
|
uint32 tsft_l;
|
uint32 tsft_h;
|
uint8 flags;
|
uint8 rate; /* this field acts as a pad for non legacy packets */
|
uint16 channel_freq;
|
uint16 channel_flags;
|
uint8 signal;
|
uint8 noise;
|
int8 antenna;
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct wl_radiotap_basic wl_radiotap_basic_t;
|
|
/* radiotap standard - non-HT, non-VHT information with Broadcom vendor namespace extension
|
* that includes VHT information.
|
* Used with monitor type 3 when received by HT/Legacy PHY and received rate is legacy.
|
* Struct ieee80211_radiotap_header is of variable length due to possible
|
* extra it_present bitmap fields.
|
* It should not be included as a static length field here
|
*/
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_legacy {
|
wl_radiotap_basic_t basic;
|
uint8 PAD;
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct wl_radiotap_legacy wl_radiotap_legacy_t;
|
|
#define WL_RADIOTAP_LEGACY_SKIP_LEN htol16(sizeof(struct wl_radiotap_legacy) - \
|
OFFSETOF(struct wl_radiotap_legacy, nonht_vht))
|
|
#define WL_RADIOTAP_NONHT_VHT_LEN (sizeof(wl_radiotap_nonht_vht_t) - 1)
|
|
/* Radiotap standard that includes HT information. This is for use with monitor type 3
|
* whenever frame is received by HT-PHY, and received rate is non-VHT.
|
* Struct ieee80211_radiotap_header is of variable length due to possible
|
* extra it_present bitmap fields.
|
* It should not be included as a static length field here
|
*/
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_ht {
|
wl_radiotap_basic_t basic;
|
uint8 PAD[3];
|
uint32 xchannel_flags;
|
uint16 xchannel_freq;
|
uint8 xchannel_channel;
|
uint8 xchannel_maxpower;
|
uint8 mcs_known;
|
uint8 mcs_flags;
|
uint8 mcs_index;
|
uint8 PAD;
|
uint32 ampdu_ref_num; /* A-MPDU ID */
|
uint16 ampdu_flags; /* A-MPDU flags */
|
uint8 ampdu_delim_crc; /* Delimiter CRC if present in flags */
|
uint8 ampdu_reserved;
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct wl_radiotap_ht wl_radiotap_ht_t;
|
|
/* Radiotap standard that includes VHT information.
|
* This is for use with monitor type 3 whenever frame is
|
* received by HT-PHY (VHT-PHY), and received rate is VHT.
|
* Struct ieee80211_radiotap_header is of variable length due to possible
|
* extra it_present bitmap fields.
|
* It should not be included as a static length field here
|
*/
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_vht {
|
wl_radiotap_basic_t basic;
|
uint8 PAD[3];
|
uint32 ampdu_ref_num; /* A-MPDU ID */
|
uint16 ampdu_flags; /* A-MPDU flags */
|
uint8 ampdu_delim_crc; /* Delimiter CRC if present in flags */
|
uint8 ampdu_reserved;
|
uint16 vht_known; /* IEEE80211_RADIOTAP_VHT */
|
uint8 vht_flags; /* IEEE80211_RADIOTAP_VHT */
|
uint8 vht_bw; /* IEEE80211_RADIOTAP_VHT */
|
uint8 vht_mcs_nss[4]; /* IEEE80211_RADIOTAP_VHT */
|
uint8 vht_coding; /* IEEE80211_RADIOTAP_VHT */
|
uint8 vht_group_id; /* IEEE80211_RADIOTAP_VHT */
|
uint16 vht_partial_aid; /* IEEE80211_RADIOTAP_VHT */
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct wl_radiotap_vht wl_radiotap_vht_t;
|
|
/* Radiotap standard that includes HE information. */
|
BWL_PRE_PACKED_STRUCT struct wl_radiotap_he {
|
wl_radiotap_basic_t basic;
|
uint8 PAD[3];
|
uint32 ampdu_ref_num; /* A-MPDU ID */
|
uint16 ampdu_flags; /* A-MPDU flags */
|
uint8 ampdu_delim_crc; /* Delimiter CRC if present in flags */
|
uint8 ampdu_reserved;
|
uint16 data1;
|
uint16 data2;
|
uint16 data3;
|
uint16 data4;
|
uint16 data5;
|
uint16 data6;
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct wl_radiotap_he wl_radiotap_he_t;
|
|
BWL_PRE_PACKED_STRUCT struct radiotap_vendor_ns {
|
uint8 vend_oui[3];
|
uint8 sns;
|
uint16 skip_len;
|
} BWL_POST_PACKED_STRUCT;
|
|
typedef struct radiotap_vendor_ns radiotap_vendor_ns_t;
|
|
#define WL_RADIOTAP_PRESENT_BASIC \
|
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
|
(1 << IEEE80211_RADIOTAP_ANTENNA))
|
|
#define WL_RADIOTAP_PRESENT_LEGACY \
|
WL_RADIOTAP_PRESENT_BASIC | \
|
(1 << IEEE80211_RADIOTAP_RATE)
|
|
#define WL_RADIOTAP_PRESENT_HT \
|
WL_RADIOTAP_PRESENT_BASIC | \
|
((1 << IEEE80211_RADIOTAP_XCHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_MCS) | \
|
(1 << IEEE80211_RADIOTAP_AMPDU))
|
|
#define WL_RADIOTAP_PRESENT_VHT \
|
WL_RADIOTAP_PRESENT_BASIC | \
|
((1 << IEEE80211_RADIOTAP_AMPDU) | \
|
(1 << IEEE80211_RADIOTAP_VHT))
|
|
#define WL_RADIOTAP_PRESENT_HE \
|
WL_RADIOTAP_PRESENT_BASIC | \
|
((1 << IEEE80211_RADIOTAP_AMPDU) | \
|
(1 << IEEE80211_RADIOTAP_HE))
|
|
/* include/linux/if_arp.h
|
* #define ARPHRD_IEEE80211_PRISM 802 IEEE 802.11 + Prism2 header
|
* #define ARPHRD_IEEE80211_RADIOTAP 803 IEEE 802.11 + radiotap header
|
* include/net/ieee80211_radiotap.h
|
* radiotap structure
|
*/
|
|
#ifndef ARPHRD_IEEE80211_RADIOTAP
|
#define ARPHRD_IEEE80211_RADIOTAP 803
|
#endif
|
|
/* This marks the end of a packed structure section. */
|
#include <packed_section_end.h>
|
|
extern void wl_rtapParseInit(radiotap_parse_t *rtap, uint8 *rtap_header);
|
extern ratespec_t wl_calcRspecFromRTap(uint8 *rtap_header);
|
extern bool wl_rtapFlags(uint8 *rtap_header, uint8* flags);
|
extern uint wl_radiotap_rx(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
|
bsd_header_rx_t *bsd_header);
|
extern uint wl_radiotap_rx_legacy(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
|
ieee80211_radiotap_header_t* rtap_hdr);
|
extern uint wl_radiotap_rx_ht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
|
ieee80211_radiotap_header_t* rtap_hdr);
|
extern uint wl_radiotap_rx_vht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
|
ieee80211_radiotap_header_t* rtap_hdr);
|
extern uint wl_radiotap_rx_he(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
|
ieee80211_radiotap_header_t* rtap_hdr);
|
extern uint wl_radiotap_rx_eht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
|
ieee80211_radiotap_header_t *rtap_hdr);
|
|
/* Legacy phy radiotap header may include VHT bw signaling VS element */
|
#define MAX_RADIOTAP_LEGACY_SIZE (sizeof(wl_radiotap_legacy_t) + \
|
sizeof(radiotap_vendor_ns_t) + sizeof(wl_radiotap_nonht_vht_t))
|
|
/* RadioTap header starts with a fixed struct ieee80211_radiotap_header,
|
* followed by variable fields for the 4 encodings supported, HE, VHT, HT, and Legacy
|
*/
|
#define MAX_RADIOTAP_SIZE (sizeof(struct ieee80211_radiotap_header) + \
|
MAX(sizeof(wl_radiotap_he_t), \
|
MAX(sizeof(wl_radiotap_vht_t), \
|
MAX(sizeof(wl_radiotap_ht_t), MAX_RADIOTAP_LEGACY_SIZE))))
|
#define MAX_MON_PKT_SIZE (4096 + MAX_RADIOTAP_SIZE)
|
|
#endif /* _BCMWIFI_RADIOTAP_H_ */
|