xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/include/bcmwifi_radiotap.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * RadioTap utility routines for WL and Apps
3  * This header file housing the define and function prototype use by
4  * both the wl driver, tools & Apps.
5  *
6  * Copyright (C) 2020, Broadcom.
7  *
8  *      Unless you and Broadcom execute a separate written software license
9  * agreement governing use of this software, this software is licensed to you
10  * under the terms of the GNU General Public License version 2 (the "GPL"),
11  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12  * following added to such license:
13  *
14  *      As a special exception, the copyright holders of this software give you
15  * permission to link this software with independent modules, and to copy and
16  * distribute the resulting executable under terms of your choice, provided that
17  * you also meet, for each linked independent module, the terms and conditions of
18  * the license of that module.  An independent module is a module which is not
19  * derived from this software.  The special exception does not apply to any
20  * modifications of the software.
21  *
22  *
23  * <<Broadcom-WL-IPTag/Dual:>>
24  */
25 
26 #ifndef _BCMWIFI_RADIOTAP_H_
27 #define _BCMWIFI_RADIOTAP_H_
28 
29 #include <ieee80211_radiotap.h>
30 #include <siutils.h>
31 #include <monitor.h>
32 #include <802.11.h>
33 #include <802.11ax.h>
34 #include "bcmwifi_monitor.h"
35 #include <bcmwifi_rspec.h>
36 #include <bcmwifi_rates.h>
37 
38 /* This marks the start of a packed structure section. */
39 #include <packed_section_start.h>
40 /*
41  * RadioTap header specific implementation. Used by MacOS implementation only.
42  */
43 BWL_PRE_PACKED_STRUCT struct wl_radiotap_hdr {
44 	struct ieee80211_radiotap_header ieee_radiotap;
45 	uint64 tsft;
46 	uint8 flags;
47 	union {
48 		uint8 rate;
49 		uint8 pad;
50 	} u;
51 	uint16 channel_freq;
52 	uint16 channel_flags;
53 } BWL_POST_PACKED_STRUCT;
54 
55 BWL_PRE_PACKED_STRUCT struct wl_radiotap_sna {
56 	uint8 signal;
57 	uint8 noise;
58 	uint8 antenna;
59 } BWL_POST_PACKED_STRUCT;
60 
61 BWL_PRE_PACKED_STRUCT struct wl_radiotap_xchan {
62 	uint32 xchannel_flags;
63 	uint16 xchannel_freq;
64 	uint8 xchannel_channel;
65 	uint8 xchannel_maxpower;
66 } BWL_POST_PACKED_STRUCT;
67 
68 BWL_PRE_PACKED_STRUCT struct wl_radiotap_ampdu {
69 	uint32 ref_num;
70 	uint16 flags;
71 	uint8 delimiter_crc;
72 	uint8 reserved;
73 } BWL_POST_PACKED_STRUCT;
74 
75 BWL_PRE_PACKED_STRUCT struct wl_htmcs {
76 	uint8 mcs_known;
77 	uint8 mcs_flags;
78 	uint8 mcs_index;
79 	uint8 pad;		/* pad to 32 bit aligned */
80 } BWL_POST_PACKED_STRUCT;
81 
82 BWL_PRE_PACKED_STRUCT struct wl_vhtmcs {
83 	uint16 vht_known;	/* IEEE80211_RADIOTAP_VHT */
84 	uint8 vht_flags;
85 	uint8 vht_bw;
86 	uint8 vht_mcs_nss[4];
87 	uint8 vht_coding;
88 	uint8 vht_group_id;
89 	uint16 vht_partial_aid;
90 } BWL_POST_PACKED_STRUCT;
91 
92 BWL_PRE_PACKED_STRUCT struct wl_radiotap_ht_tail {
93 	struct wl_radiotap_xchan xc;
94 	struct wl_radiotap_ampdu ampdu;
95 	union {
96 		struct wl_htmcs ht;
97 		struct wl_vhtmcs vht;
98 	} u;
99 } BWL_POST_PACKED_STRUCT;
100 
101 typedef struct bsd_header_rx {
102 	struct wl_radiotap_hdr hdr;
103 	/*
104 	 * include extra space beyond wl_radiotap_ht size
105 	 * (larger of two structs in union):
106 	 *   signal/noise/ant plus max of 3 pad for xchannel
107 	 *   tail struct (xchannel and MCS info)
108 	 */
109 	uint8 pad[3];
110 	uint8 ht[sizeof(struct wl_radiotap_ht_tail)];
111 } bsd_header_rx_t;
112 
113 typedef struct radiotap_parse {
114 	struct ieee80211_radiotap_header *hdr;
115 	void *fields;
116 	uint fields_len;
117 	uint idx;
118 	uint offset;
119 } radiotap_parse_t;
120 
121 struct rtap_field {
122 	uint len;
123 	uint align;
124 };
125 
126 /* he radiotap - https://www.radiotap.org/fields/HE.html */
127 #define HE_RADIOTAP_BSS_COLOR_SHIFT		0u
128 #define HE_RADIOTAP_BEAM_CHANGE_SHIFT		6u
129 #define HE_RADIOTAP_DL_UL_SHIFT			7u
130 #define HE_RADIOTAP_MCS_SHIFT			8u
131 #define HE_RADIOTAP_DCM_SHIFT			12u
132 #define HE_RADIOTAP_CODING_SHIFT		13u
133 #define HE_RADIOTAP_LDPC_SHIFT			14u
134 #define HE_RADIOTAP_STBC_SHIFT			15u
135 #define HE_RADIOTAP_SR_SHIFT			0u
136 #define HE_RADIOTAP_STAID_SHIFT			4u
137 #define HE_RADIOTAP_SR1_SHIFT			0u
138 #define HE_RADIOTAP_SR2_SHIFT			4u
139 #define HE_RADIOTAP_SR3_SHIFT			8u
140 #define HE_RADIOTAP_SR4_SHIFT			12u
141 #define HE_RADIOTAP_BW_SHIFT			0u
142 #define HE_RADIOTAP_RU_ALLOC_SHIFT		0u
143 #define HE_RADIOTAP_GI_SHIFT			4u
144 #define HE_RADIOTAP_LTF_SIZE_SHIFT		6u
145 #define HE_RADIOTAP_NUM_LTF_SHIFT		8u
146 #define HE_RADIOTAP_PADDING_SHIFT		12u
147 #define HE_RADIOTAP_TXBF_SHIFT			14u
148 #define HE_RADIOTAP_PE_SHIFT			15u
149 #define HE_RADIOTAP_NSTS_SHIFT			0u
150 #define HE_RADIOTAP_DOPPLER_SHIFT		4u
151 #define HE_RADIOTAP_TXOP_SHIFT			8u
152 #define HE_RADIOTAP_MIDAMBLE_SHIFT		15u
153 #define HE_RADIOTAP_DOPPLER_SET_NSTS_SHIFT	0u
154 #define HE_RADIOTAP_DOPPLER_NOTSET_NSTS_SHIFT	0u
155 
156 /* he mu radiotap - https://www.radiotap.org/fields/HE-MU.html */
157 #define HE_RADIOTAP_SIGB_MCS_SHIFT		0u
158 #define HE_RADIOTAP_SIGB_MCS_KNOWN_SHIFT	4u
159 #define HE_RADIOTAP_SIGB_DCM_SHIFT		5u
160 #define HE_RADIOTAP_SIGB_DCM_KNOWN_SHIFT	6u
161 #define HE_RADIOTAP_SIGB_COMP_KNOWN_SHIFT	14u
162 #define HE_RADIOTAP_SIGB_COMP_SHIFT		3u
163 #define HE_RADIOTAP_SIGB_SYMB_SHIFT		18u
164 #define HE_RADIOTAP_BW_SIGA_SHIFT		0u
165 #define HE_RADIOTAP_BW_SIGA_KNOWN_SHIFT		2u
166 #define HE_RADIOTAP_SIGB_SYM_MU_MIMO_USER_SHIFT	4u
167 #define HE_RADIOTAP_PRE_PUNCR_SIGA_SHIFT	8u
168 #define HE_RADIOTAP_PRE_PUNCR_SIGA_KNOWN_SHIFT	10u
169 
170 #define WL_RADIOTAP_BRCM_SNS			0x01
171 #define WL_RADIOTAP_BRCM_MCS			0x00000001
172 #define WL_RADIOTAP_LEGACY_SNS			0x02
173 #define WL_RADIOTAP_LEGACY_VHT			0x00000001
174 #define WL_RADIOTAP_BRCM_PAD_SNS		0x3
175 
176 #define IEEE80211_RADIOTAP_HTMOD_40		0x01
177 #define IEEE80211_RADIOTAP_HTMOD_SGI		0x02
178 #define IEEE80211_RADIOTAP_HTMOD_GF		0x04
179 #define IEEE80211_RADIOTAP_HTMOD_LDPC		0x08
180 #define IEEE80211_RADIOTAP_HTMOD_STBC_MASK	0x30
181 #define IEEE80211_RADIOTAP_HTMOD_STBC_SHIFT	4
182 
183 /* Dyanmic bandwidth for VHT signaled in NONHT */
184 #define WL_RADIOTAP_F_NONHT_VHT_DYN_BW		0x01
185 /* VHT BW is valid in NONHT */
186 #define WL_RADIOTAP_F_NONHT_VHT_BW		0x02
187 
188 typedef struct ieee80211_radiotap_header ieee80211_radiotap_header_t;
189 
190 /* VHT information in non-HT frames; primarily VHT b/w signaling
191  * in frames received at legacy rates.
192  */
193 BWL_PRE_PACKED_STRUCT struct wl_radiotap_nonht_vht {
194 	uint8 len;	/* length of the field excluding 'len' field */
195 	uint8 flags;
196 	uint8 bw;
197 	uint8 PAD;	/* Add a pad so the next vendor entry, if any, will be 16 bit aligned */
198 } BWL_POST_PACKED_STRUCT;
199 
200 typedef struct wl_radiotap_nonht_vht wl_radiotap_nonht_vht_t;
201 
202 BWL_PRE_PACKED_STRUCT struct wl_radiotap_basic {
203 	uint32 tsft_l;
204 	uint32 tsft_h;
205 	uint8  flags;
206 	uint8  rate; /* this field acts as a pad for non legacy packets */
207 	uint16 channel_freq;
208 	uint16 channel_flags;
209 	uint8  signal;
210 	uint8  noise;
211 	int8   antenna;
212 } BWL_POST_PACKED_STRUCT;
213 
214 typedef struct wl_radiotap_basic wl_radiotap_basic_t;
215 
216 /* radiotap standard - non-HT, non-VHT information with Broadcom vendor namespace extension
217  * that includes VHT information.
218  * Used with monitor type 3 when received by HT/Legacy PHY and received rate is legacy.
219  * Struct ieee80211_radiotap_header is of variable length due to possible
220  * extra it_present bitmap fields.
221  * It should not be included as a static length field here
222  */
223 BWL_PRE_PACKED_STRUCT struct wl_radiotap_legacy {
224 	wl_radiotap_basic_t basic;
225 	uint8 PAD;
226 } BWL_POST_PACKED_STRUCT;
227 
228 typedef struct wl_radiotap_legacy wl_radiotap_legacy_t;
229 
230 #define WL_RADIOTAP_LEGACY_SKIP_LEN htol16(sizeof(struct wl_radiotap_legacy) - \
231 	OFFSETOF(struct wl_radiotap_legacy, nonht_vht))
232 
233 #define WL_RADIOTAP_NONHT_VHT_LEN (sizeof(wl_radiotap_nonht_vht_t) - 1)
234 
235 /* Radiotap standard that includes HT information. This is for use with monitor type 3
236  * whenever frame is received by HT-PHY, and received rate is non-VHT.
237  * Struct ieee80211_radiotap_header is of variable length due to possible
238  * extra it_present bitmap fields.
239  * It should not be included as a static length field here
240  */
241 BWL_PRE_PACKED_STRUCT struct wl_radiotap_ht {
242 	wl_radiotap_basic_t basic;
243 	uint8  PAD[3];
244 	uint32 xchannel_flags;
245 	uint16 xchannel_freq;
246 	uint8  xchannel_channel;
247 	uint8  xchannel_maxpower;
248 	uint8  mcs_known;
249 	uint8  mcs_flags;
250 	uint8  mcs_index;
251 	uint8  PAD;
252 	uint32 ampdu_ref_num;		/* A-MPDU ID */
253 	uint16 ampdu_flags;		/* A-MPDU flags */
254 	uint8  ampdu_delim_crc;		/* Delimiter CRC if present in flags */
255 	uint8  ampdu_reserved;
256 } BWL_POST_PACKED_STRUCT;
257 
258 typedef struct wl_radiotap_ht wl_radiotap_ht_t;
259 
260 /* Radiotap standard that includes VHT information.
261  * This is for use with monitor type 3 whenever frame is
262  * received by HT-PHY (VHT-PHY), and received rate is VHT.
263  * Struct ieee80211_radiotap_header is of variable length due to possible
264  * extra it_present bitmap fields.
265  * It should not be included as a static length field here
266  */
267 BWL_PRE_PACKED_STRUCT struct wl_radiotap_vht {
268 	wl_radiotap_basic_t basic;
269 	uint8  PAD[3];
270 	uint32 ampdu_ref_num;		/* A-MPDU ID */
271 	uint16 ampdu_flags;		/* A-MPDU flags */
272 	uint8  ampdu_delim_crc;		/* Delimiter CRC if present in flags */
273 	uint8  ampdu_reserved;
274 	uint16 vht_known;		/* IEEE80211_RADIOTAP_VHT */
275 	uint8  vht_flags;		/* IEEE80211_RADIOTAP_VHT */
276 	uint8  vht_bw;			/* IEEE80211_RADIOTAP_VHT */
277 	uint8  vht_mcs_nss[4];		/* IEEE80211_RADIOTAP_VHT */
278 	uint8  vht_coding;		/* IEEE80211_RADIOTAP_VHT */
279 	uint8  vht_group_id;		/* IEEE80211_RADIOTAP_VHT */
280 	uint16 vht_partial_aid;		/* IEEE80211_RADIOTAP_VHT */
281 } BWL_POST_PACKED_STRUCT;
282 
283 typedef struct wl_radiotap_vht wl_radiotap_vht_t;
284 
285 /* Radiotap standard that includes HE information. */
286 BWL_PRE_PACKED_STRUCT struct wl_radiotap_he {
287 	wl_radiotap_basic_t basic;
288 	uint8  PAD[3];
289 	uint32 ampdu_ref_num;		/* A-MPDU ID */
290 	uint16 ampdu_flags;		/* A-MPDU flags */
291 	uint8  ampdu_delim_crc;		/* Delimiter CRC if present in flags */
292 	uint8  ampdu_reserved;
293 	uint16 data1;
294 	uint16 data2;
295 	uint16 data3;
296 	uint16 data4;
297 	uint16 data5;
298 	uint16 data6;
299 } BWL_POST_PACKED_STRUCT;
300 
301 typedef struct wl_radiotap_he wl_radiotap_he_t;
302 
303 BWL_PRE_PACKED_STRUCT struct radiotap_vendor_ns {
304 	uint8 vend_oui[3];
305 	uint8 sns;
306 	uint16 skip_len;
307 } BWL_POST_PACKED_STRUCT;
308 
309 typedef struct radiotap_vendor_ns radiotap_vendor_ns_t;
310 
311 #define WL_RADIOTAP_PRESENT_BASIC			\
312 	((1 << IEEE80211_RADIOTAP_TSFT) |		\
313 	 (1 << IEEE80211_RADIOTAP_FLAGS) |		\
314 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |		\
315 	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |	\
316 	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |	\
317 	 (1 << IEEE80211_RADIOTAP_ANTENNA))
318 
319 #define WL_RADIOTAP_PRESENT_LEGACY			\
320 	WL_RADIOTAP_PRESENT_BASIC |			\
321 	(1 << IEEE80211_RADIOTAP_RATE)
322 
323 #define WL_RADIOTAP_PRESENT_HT				\
324 	WL_RADIOTAP_PRESENT_BASIC |			\
325 	((1 << IEEE80211_RADIOTAP_XCHANNEL) |		\
326 	 (1 << IEEE80211_RADIOTAP_MCS) |		\
327 	 (1 << IEEE80211_RADIOTAP_AMPDU))
328 
329 #define WL_RADIOTAP_PRESENT_VHT			        \
330 	WL_RADIOTAP_PRESENT_BASIC |			\
331 	((1 << IEEE80211_RADIOTAP_AMPDU) |		\
332 	 (1 << IEEE80211_RADIOTAP_VHT))
333 
334 #define WL_RADIOTAP_PRESENT_HE				\
335 	WL_RADIOTAP_PRESENT_BASIC |			\
336 	((1 << IEEE80211_RADIOTAP_AMPDU) |		\
337 	 (1 << IEEE80211_RADIOTAP_HE))
338 
339 /* include/linux/if_arp.h
340  *	#define ARPHRD_IEEE80211_PRISM 802 IEEE 802.11 + Prism2 header
341  *	#define ARPHRD_IEEE80211_RADIOTAP 803 IEEE 802.11 + radiotap header
342  * include/net/ieee80211_radiotap.h
343  *	radiotap structure
344  */
345 
346 #ifndef ARPHRD_IEEE80211_RADIOTAP
347 #define ARPHRD_IEEE80211_RADIOTAP 803
348 #endif
349 
350 /* This marks the end of a packed structure section. */
351 #include <packed_section_end.h>
352 
353 extern void wl_rtapParseInit(radiotap_parse_t *rtap, uint8 *rtap_header);
354 extern ratespec_t wl_calcRspecFromRTap(uint8 *rtap_header);
355 extern bool wl_rtapFlags(uint8 *rtap_header, uint8* flags);
356 extern uint wl_radiotap_rx(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
357 	bsd_header_rx_t *bsd_header);
358 extern uint wl_radiotap_rx_legacy(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
359 	ieee80211_radiotap_header_t* rtap_hdr);
360 extern uint wl_radiotap_rx_ht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
361 	ieee80211_radiotap_header_t* rtap_hdr);
362 extern uint wl_radiotap_rx_vht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
363         ieee80211_radiotap_header_t* rtap_hdr);
364 extern uint wl_radiotap_rx_he(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
365         ieee80211_radiotap_header_t* rtap_hdr);
366 extern uint wl_radiotap_rx_eht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
367 	ieee80211_radiotap_header_t *rtap_hdr);
368 
369 /* Legacy phy radiotap header may include VHT bw signaling VS element */
370 #define MAX_RADIOTAP_LEGACY_SIZE (sizeof(wl_radiotap_legacy_t) + \
371 				  sizeof(radiotap_vendor_ns_t) + sizeof(wl_radiotap_nonht_vht_t))
372 
373 /* RadioTap header starts with a fixed struct ieee80211_radiotap_header,
374  * followed by variable fields for the 4 encodings supported, HE, VHT, HT, and Legacy
375  */
376 #define MAX_RADIOTAP_SIZE	(sizeof(struct ieee80211_radiotap_header) +     \
377 				 MAX(sizeof(wl_radiotap_he_t),                  \
378 				     MAX(sizeof(wl_radiotap_vht_t),             \
379 				         MAX(sizeof(wl_radiotap_ht_t), MAX_RADIOTAP_LEGACY_SIZE))))
380 #define MAX_MON_PKT_SIZE	(4096 + MAX_RADIOTAP_SIZE)
381 
382 #endif	/* _BCMWIFI_RADIOTAP_H_ */
383