blob: 77fc0e72e49091158787515a63887d5e33a02dc0 [file] [log] [blame]
/*
* 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_ */