]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/linuxkpi/common/include/linux/ieee80211.h
Merge bmake-20220208
[FreeBSD/FreeBSD.git] / sys / compat / linuxkpi / common / include / linux / ieee80211.h
1 /*-
2  * Copyright (c) 2020-2021 The FreeBSD Foundation
3  *
4  * This software was developed by Björn Zeeb under sponsorship from
5  * the FreeBSD Foundation.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 #ifndef _LINUXKPI_LINUX_IEEE80211_H
32 #define _LINUXKPI_LINUX_IEEE80211_H
33
34 #include <sys/types.h>
35 #include <net80211/ieee80211.h>
36
37 #include <asm/unaligned.h>
38 #include <linux/bitops.h>
39 #include <linux/if_ether.h>
40
41 /* linux_80211.c */
42 extern int debug_80211;
43
44
45 #define IEEE80211_CCMP_HDR_LEN                  8       /* 802.11i .. net80211 comment */
46 #define IEEE80211_CCMP_PN_LEN                   6
47 #define IEEE80211_CCMP_MIC_LEN                  8       /* || 16 */
48 #define IEEE80211_GCMP_HDR_LEN                  8
49 #define IEEE80211_GCMP_PN_LEN                   6
50 #define IEEE80211_GMAC_PN_LEN                   6
51
52 #define IEEE80211_MAX_PN_LEN                    16
53
54 #define IEEE80211_INVAL_HW_QUEUE                ((uint8_t)-1)
55
56 #define IEEE80211_MAX_AMPDU_BUF_HT              0x40
57 #define IEEE80211_MAX_AMPDU_BUF                 256     /* for HE? */
58
59 #define IEEE80211_MAX_DATA_LEN                  (2300 + IEEE80211_CRC_LEN)
60
61 #define IEEE80211_MAX_MPDU_LEN_HT_BA            4095    /* 9.3.2.1 Format of Data frames; non-VHT non-DMG STA */
62 #define IEEE80211_MAX_MPDU_LEN_HT_3839          3839
63 #define IEEE80211_MAX_MPDU_LEN_VHT_3895         3895
64 #define IEEE80211_MAX_MPDU_LEN_VHT_7991         7991
65 #define IEEE80211_MAX_MPDU_LEN_VHT_11454        11454
66
67 #define IEEE80211_MAX_RTS_THRESHOLD             2346    /* net80211::IEEE80211_RTS_MAX */
68
69 #define IEEE80211_MIN_ACTION_SIZE               23      /* ? */
70
71 /* Wi-Fi Peer-to-Peer (P2P) Technical Specification */
72 #define IEEE80211_P2P_OPPPS_CTWINDOW_MASK       0x7f
73 #define IEEE80211_P2P_OPPPS_ENABLE_BIT          BIT(7)
74
75 #define IEEE80211_QOS_CTL_TAG1D_MASK            0x0007
76 #define IEEE80211_QOS_CTL_EOSP                  0x0010
77 #define IEEE80211_QOS_CTL_A_MSDU_PRESENT        0x0080  /* 9.2.4.5.1, Table 9-6 QoS Control Field */
78
79 #define IEEE80211_RATE_SHORT_PREAMBLE           BIT(0)
80
81 enum ieee80211_rate_control_changed_flags {
82         IEEE80211_RC_BW_CHANGED                 = BIT(0),
83         IEEE80211_RC_NSS_CHANGED                = BIT(1),
84         IEEE80211_RC_SUPP_RATES_CHANGED         = BIT(2),
85 };
86
87 #define IEEE80211_SCTL_FRAG                     IEEE80211_SEQ_FRAG_MASK
88 #define IEEE80211_SCTL_SEQ                      IEEE80211_SEQ_SEQ_MASK
89
90 #define IEEE80211_TKIP_ICV_LEN                  4
91 #define IEEE80211_TKIP_IV_LEN                   8       /* WEP + KID + EXT */
92
93 #define IEEE80211_VHT_EXT_NSS_BW_CAPABLE        (1 << 13)       /* assigned to tx_highest */
94
95 #define IEEE80211_VHT_MAX_AMPDU_1024K           7       /* 9.4.2.56.3 A-MPDU Parameters field, Table 9-163 */
96
97 #define IEEE80211_WEP_IV_LEN                    3       /* net80211: IEEE80211_WEP_IVLEN */
98 #define IEEE80211_WEP_ICV_LEN                   4
99
100 #define WLAN_AUTH_OPEN                          __LINE__ /* TODO FIXME brcmfmac */
101 #define WLAN_CAPABILITY_IBSS                    __LINE__ /* TODO FIXME no longer used? */
102 #define WLAN_CAPABILITY_SHORT_PREAMBLE          __LINE__ /* TODO FIXME brcmfmac */
103 #define WLAN_CAPABILITY_SHORT_SLOT_TIME         __LINE__ /* TODO FIXME brcmfmac */
104
105
106 #define WLAN_MAX_KEY_LEN                        32 /* TODO FIXME brcmfmac */
107 #define WLAN_PMKID_LEN                          16 /* TODO FIXME brcmfmac */
108
109 #define WLAN_KEY_LEN_CCMP                       16
110 #define WLAN_KEY_LEN_GCMP_256                   32
111
112 /* 9.4.2.56.3, Table 9-163 Subfields of the A-MPDU Parameters field */
113 enum ieee80211_min_mpdu_start_spacing {
114         IEEE80211_HT_MPDU_DENSITY_NONE          = 0,
115         IEEE80211_HT_MPDU_DENSITY_4             = 5,    /* 4us */
116         IEEE80211_HT_MPDU_DENSITY_16            = 7,    /* 16us */
117 };
118
119 /* 9.4.2.57, Table 9-168, HT Operation element fields and subfields */
120 #define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT   0x0080  /* B24.. */
121
122 #define IEEE80211_FCTL_STYPE                    IEEE80211_FC0_SUBTYPE_MASK
123 #define IEEE80211_FCTL_ORDER                    (IEEE80211_FC1_ORDER << 8)
124
125 #define IEEE80211_STYPE_ASSOC_REQ               IEEE80211_FC0_SUBTYPE_ASSOC_REQ
126 #define IEEE80211_STYPE_REASSOC_REQ             IEEE80211_FC0_SUBTYPE_REASSOC_REQ
127 #define IEEE80211_STYPE_PROBE_REQ               IEEE80211_FC0_SUBTYPE_PROBE_REQ
128 #define IEEE80211_STYPE_DISASSOC                IEEE80211_FC0_SUBTYPE_DISASSOC
129 #define IEEE80211_STYPE_AUTH                    IEEE80211_FC0_SUBTYPE_AUTH
130 #define IEEE80211_STYPE_DEAUTH                  IEEE80211_FC0_SUBTYPE_DEAUTH
131 #define IEEE80211_STYPE_ACTION                  IEEE80211_FC0_SUBTYPE_ACTION
132
133 #define IEEE80211_NUM_ACS                       4       /* net8021::WME_NUM_AC */
134
135 #define IEEE80211_MAX_SSID_LEN                  32      /* 9.4.2.2 SSID element, net80211: IEEE80211_NWID_LEN */
136
137
138 /* Figure 9-27, BAR Control field */
139 #define IEEE80211_BAR_CTRL_TID_INFO_MASK        0xf000
140 #define IEEE80211_BAR_CTRL_TID_INFO_SHIFT       12
141
142 #define IEEE80211_PPE_THRES_INFO_PPET_SIZE              1 /* TODO FIXME ax? */
143 #define IEEE80211_PPE_THRES_NSS_MASK                    2 /* TODO FIXME ax? */
144 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS        3 /* TODO FIXME ax? */
145 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK       8 /* TODO FIXME ax? */
146
147 #define IEEE80211_HT_OP_MODE_PROTECTION                 0x03    /* MASK */
148 #define IEEE80211_HT_OP_MODE_PROTECTION_NONE            0x00
149 #define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ           0x01
150 #define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED     0x02
151 #define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER       0x03
152
153
154 /* 9.6.13.1, Table 9-342 TDLS Action field values. */
155 enum ieee80211_tdls_action_code {
156         WLAN_TDLS_SETUP_REQUEST                 = 0,
157         WLAN_TDLS_SETUP_RESPONSE                = 1,
158         WLAN_TDLS_SETUP_CONFIRM                 = 2,
159         WLAN_TDLS_TEARDOWN                      = 3,
160         WLAN_TDLS_PEER_TRAFFIC_INDICATION       = 4,
161         WLAN_TDLS_CHANNEL_SWITCH_REQUEST        = 5,
162         WLAN_TDLS_CHANNEL_SWITCH_RESPONSE       = 6,
163         WLAN_TDLS_PEER_PSM_REQUEST              = 7,
164         WLAN_TDLS_PEER_PSM_RESPONSE             = 8,
165         WLAN_TDLS_PEER_TRAFFIC_RESPONSE         = 9,
166         WLAN_TDLS_DISCOVERY_REQUEST             = 10,
167         /* 11-255 reserved */
168 };
169
170 /* 9.4.2.27, Table 9-135. Extended Capabilities field. */
171 /* This is split up into octets CAPA1 = octet 1, ... */
172 #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING                    BIT(2  % 8)
173 #define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT                      BIT(22 % 8)
174 #define WLAN_EXT_CAPA8_OPMODE_NOTIF                             BIT(62 % 8)
175 #define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT                   BIT(5)          /* XXX */
176 #define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT     BIT(7)          /* XXX */
177
178
179 /* iwlwifi/mvm/utils:: for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_VI; ac++) */
180 /* Would be so much easier if we'd define constants to the same. */
181 enum ieee80211_ac_numbers {
182         IEEE80211_AC_VO = 0,                    /* net80211::WME_AC_VO */
183         IEEE80211_AC_VI = 1,                    /* net80211::WME_AC_VI */
184         IEEE80211_AC_BE = 2,                    /* net80211::WME_AC_BE */
185         IEEE80211_AC_BK = 3,                    /* net80211::WME_AC_BK */
186 };
187
188 #define IEEE80211_MAX_QUEUES                    16      /* Assume IEEE80211_NUM_TIDS for the moment. */
189
190 #define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO      1
191 #define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI      2
192 #define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK      4
193 #define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE      8
194 #define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL     0xf
195
196 struct vht_mcs {
197         uint16_t        rx_mcs_map;
198         uint16_t        rx_highest;
199         uint16_t        tx_mcs_map;
200         uint16_t        tx_highest;
201 };
202
203 struct ieee80211_vht_cap {
204         struct vht_mcs                          supp_mcs;;
205         __le32                                  vht_cap_info;
206 };
207
208 enum ieee80211_ht_max_ampdu_len {
209         IEEE80211_HT_MAX_AMPDU_64K
210 };
211
212 enum ieee80211_ampdu_mlme_action {
213         IEEE80211_AMPDU_RX_START,
214         IEEE80211_AMPDU_RX_STOP,
215         IEEE80211_AMPDU_TX_OPERATIONAL,
216         IEEE80211_AMPDU_TX_START,
217         IEEE80211_AMPDU_TX_START_DELAY_ADDBA,
218         IEEE80211_AMPDU_TX_START_IMMEDIATE,
219         IEEE80211_AMPDU_TX_STOP_CONT,
220         IEEE80211_AMPDU_TX_STOP_FLUSH,
221         IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
222 };
223
224 enum ieee80211_chanctx_switch_mode {
225         CHANCTX_SWMODE_REASSIGN_VIF,
226         CHANCTX_SWMODE_SWAP_CONTEXTS,
227 };
228
229 enum ieee80211_chanctx_change_flags {
230         IEEE80211_CHANCTX_CHANGE_MIN_WIDTH      = BIT(0),
231         IEEE80211_CHANCTX_CHANGE_RADAR          = BIT(1),
232         IEEE80211_CHANCTX_CHANGE_RX_CHAINS      = BIT(2),
233         IEEE80211_CHANCTX_CHANGE_WIDTH          = BIT(3),
234 };
235
236 enum ieee80211_frame_release_type {
237         IEEE80211_FRAME_RELEASE_PSPOLL          = 1,
238         IEEE80211_FRAME_RELEASE_UAPSD           = 2,
239 };
240
241 enum ieee80211_p2p_attr_ids {
242         IEEE80211_P2P_ATTR_DEVICE_ID,
243         IEEE80211_P2P_ATTR_DEVICE_INFO,
244         IEEE80211_P2P_ATTR_GROUP_ID,
245         IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
246 };
247
248 enum ieee80211_reconfig_type {
249         IEEE80211_RECONFIG_TYPE_RESTART,
250         IEEE80211_RECONFIG_TYPE_SUSPEND,
251 };
252
253 enum ieee80211_roc_type {
254         IEEE80211_ROC_TYPE_MGMT_TX,
255         IEEE80211_ROC_TYPE_NORMAL,
256 };
257
258 enum ieee80211_smps_mode {
259         IEEE80211_SMPS_OFF,
260         IEEE80211_SMPS_STATIC,
261         IEEE80211_SMPS_DYNAMIC,
262         IEEE80211_SMPS_AUTOMATIC,
263         IEEE80211_SMPS_NUM_MODES,
264 };
265
266 /* net80211::IEEE80211_S_* different but represents the state machine. */
267 /* Note: order here is important! */
268 enum ieee80211_sta_state {
269         IEEE80211_STA_NOTEXIST,
270         IEEE80211_STA_NONE,
271         IEEE80211_STA_AUTH,
272         IEEE80211_STA_ASSOC,
273         IEEE80211_STA_AUTHORIZED,               /* 802.1x */
274 };
275
276 enum ieee80211_sta_rx_bw {
277         IEEE80211_STA_RX_BW_20,
278         IEEE80211_STA_RX_BW_40,
279         IEEE80211_STA_RX_BW_80,
280         IEEE80211_STA_RX_BW_160,
281 };
282
283 enum ieee80211_tx_info_flags {
284         /* XXX TODO .. right shift numbers - not sure where that came from? */
285         IEEE80211_TX_CTL_AMPDU                  = BIT(0),
286         IEEE80211_TX_CTL_ASSIGN_SEQ             = BIT(1),
287         IEEE80211_TX_CTL_NO_ACK                 = BIT(2),
288         IEEE80211_TX_CTL_SEND_AFTER_DTIM        = BIT(3),
289         IEEE80211_TX_CTL_TX_OFFCHAN             = BIT(4),
290         IEEE80211_TX_CTL_REQ_TX_STATUS          = BIT(5),
291         IEEE80211_TX_STATUS_EOSP                = BIT(6),
292         IEEE80211_TX_STAT_ACK                   = BIT(7),
293         IEEE80211_TX_STAT_AMPDU                 = BIT(8),
294         IEEE80211_TX_STAT_AMPDU_NO_BACK         = BIT(9),
295         IEEE80211_TX_STAT_TX_FILTERED           = BIT(10),
296         IEEE80211_TX_STAT_NOACK_TRANSMITTED     = BIT(11),
297 };
298
299 enum ieee80211_tx_control_flags {
300         /* XXX TODO .. right shift numbers */
301         IEEE80211_TX_CTRL_PORT_CTRL_PROTO       = BIT(0),
302 };
303
304 enum ieee80211_tx_rate_flags {
305         /* XXX TODO .. right shift numbers */
306         IEEE80211_TX_RC_40_MHZ_WIDTH            = BIT(0),
307         IEEE80211_TX_RC_80_MHZ_WIDTH            = BIT(1),
308         IEEE80211_TX_RC_160_MHZ_WIDTH           = BIT(2),
309         IEEE80211_TX_RC_GREEN_FIELD             = BIT(3),
310         IEEE80211_TX_RC_MCS                     = BIT(4),
311         IEEE80211_TX_RC_SHORT_GI                = BIT(5),
312         IEEE80211_TX_RC_VHT_MCS                 = BIT(6),
313 };
314
315 #define IEEE80211_HT_CTL_LEN    4
316
317 struct ieee80211_hdr {          /* net80211::ieee80211_frame */
318         __le16          frame_control;
319         __le16          duration_id;
320         uint8_t         addr1[ETH_ALEN];
321         uint8_t         addr2[ETH_ALEN];
322         uint8_t         addr3[ETH_ALEN];
323         __le16          seq_ctrl;
324         uint8_t         addr4[ETH_ALEN];
325 };
326
327 struct ieee80211_vendor_ie {
328 };
329
330 /* 9.3.3.2 Format of Management frames */
331 struct ieee80211_mgmt {
332         __le16          frame_control;
333         __le16          duration_id;
334         uint8_t         da[ETH_ALEN];
335         uint8_t         sa[ETH_ALEN];
336         uint8_t         bssid[ETH_ALEN];
337         __le16          seq_ctrl;
338         union {
339                 /* 9.3.3.3 Beacon frame format */
340                 struct {
341                         uint64_t        timestamp;
342                         uint16_t        beacon_int;
343                         uint16_t        capab_info;
344                         uint8_t         variable[0];
345                 } beacon;
346                 /* 9.3.3.10 Probe Request frame format */
347                 struct {
348                         uint8_t         variable[0];
349                 } probe_req;
350                 /* 9.3.3.11 Probe Response frame format */
351                 struct {
352                         uint64_t        timestamp;
353                         uint16_t        beacon_int;
354                         uint16_t        capab_info;
355                         uint8_t         variable[0];
356                 } probe_resp;
357                 /* 9.3.3.14 Action frame format */
358                 struct {
359                         /* 9.4.1.11 Action field */
360                         uint8_t         category;
361                         /* 9.6.8 Public Action details */
362                         union {
363                                 /* 9.6.8.33 Fine Timing Measurement frame format */
364                                 struct {
365                                         uint8_t dialog_token;
366                                         uint8_t follow_up;
367                                         uint8_t tod[6];
368                                         uint8_t toa[6];
369                                         uint16_t tod_error;
370                                         uint16_t toa_error;
371                                         uint8_t variable[0];
372                                 } ftm;
373                         } u;
374                 } action;
375         } u;
376 };
377
378 #define MHZ_TO_KHZ(_f)          ((_f) * 1000)
379 #define DBI_TO_MBI(_g)          ((_g) * 100)
380 #define MBI_TO_DBI(_x)          ((_x) / 100)
381 #define DBM_TO_MBM(_g)          ((_g) * 100)
382 #define MBM_TO_DBM(_x)          ((_x) / 100)
383
384 #define IEEE80211_SEQ_TO_SN(_seqn)      (((_seqn) & IEEE80211_SEQ_SEQ_MASK) >> \
385                                             IEEE80211_SEQ_SEQ_SHIFT)
386
387 /* Time unit (TU) to .. See net80211: IEEE80211_DUR_TU */
388 #define TU_TO_JIFFIES(_tu)      (usecs_to_jiffies(_tu) * 1024)
389 #define TU_TO_EXP_TIME(_tu)     (jiffies + TU_TO_JIFFIES(_tu))
390
391 /* 9.4.2.21.1, Table 9-82. */
392 #define IEEE80211_SPCT_MSR_RPRT_TYPE_LCI        8
393 #define IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC      11
394
395 /* 9.4.2.1, Table 9-77. Element IDs. */
396 enum ieee80211_eid {
397         WLAN_EID_SSID                           = 0,
398         WLAN_EID_SUPP_RATES                     = 1,
399         WLAN_EID_DS_PARAMS                      = 3,
400         WLAN_EID_TIM                            = 5,
401         WLAN_EID_COUNTRY                        = 7, /* IEEE80211_ELEMID_COUNTRY */
402         WLAN_EID_REQUEST                        = 10,
403         WLAN_EID_CHANNEL_SWITCH                 = 37,
404         WLAN_EID_MEASURE_REPORT                 = 39,
405         WLAN_EID_RSN                            = 48, /* IEEE80211_ELEMID_RSN */
406         WLAN_EID_EXT_SUPP_RATES                 = 50,
407         WLAN_EID_EXT_CHANSWITCH_ANN             = 60,
408         WLAN_EID_EXT_CAPABILITY                 = 127,
409         WLAN_EID_VENDOR_SPECIFIC                = 221,
410 };
411
412 /* 9.4.1.7, Table 9-45. Reason codes. */
413 enum ieee80211_reason_code {
414         /* reserved                             = 0, */
415         WLAN_REASON_UNSPECIFIED                 = 1,
416         WLAN_REASON_DEAUTH_LEAVING              = 3,    /* LEAVING_NETWORK_DEAUTH */
417         WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED   = 26,
418 };
419
420 /* 9.4.1.9, Table 9-46. Status codes. */
421 enum ieee80211_status_code {
422         WLAN_STATUS_SUCCESS                     = 0,
423         WLAN_STATUS_AUTH_TIMEOUT                = 16,   /* REJECTED_SEQUENCE_TIMEOUT */
424 };
425
426 /* net80211: IEEE80211_IS_CTL() */
427 static __inline bool
428 ieee80211_is_ctl(__le16 fc)
429 {
430         __le16 v;
431
432         fc &= htole16(IEEE80211_FC0_TYPE_MASK);
433         v = htole16(IEEE80211_FC0_TYPE_CTL);
434
435         return (fc == v);
436 }
437
438 /* net80211: IEEE80211_IS_DATA() */
439 static __inline bool
440 ieee80211_is_data(__le16 fc)
441 {
442         __le16 v;
443
444         fc &= htole16(IEEE80211_FC0_TYPE_MASK);
445         v = htole16(IEEE80211_FC0_TYPE_DATA);
446
447         return (fc == v);
448 }
449
450 /* net80211: IEEE80211_IS_QOSDATA() */
451 static __inline bool
452 ieee80211_is_data_qos(__le16 fc)
453 {
454         __le16 v;
455
456         fc &= htole16(IEEE80211_FC0_SUBTYPE_QOS | IEEE80211_FC0_TYPE_MASK |
457             IEEE80211_FC0_VERSION_MASK);
458         v = htole16(IEEE80211_FC0_QOSDATA);
459
460         return (fc == v);
461 }
462
463 /* net80211: IEEE80211_IS_MGMT() */
464 static __inline bool
465 ieee80211_is_mgmt(__le16 fc)
466 {
467         __le16 v;
468
469         fc &= htole16(IEEE80211_FC0_TYPE_MASK);
470         v = htole16(IEEE80211_FC0_TYPE_MGT);
471
472         return (fc == v);
473 }
474
475
476 /* Derived from net80211::ieee80211_anyhdrsize. */
477 static __inline unsigned int
478 ieee80211_hdrlen(__le16 fc)
479 {
480         unsigned int size;
481
482         if (ieee80211_is_ctl(fc)) {
483                 switch (fc & htole16(IEEE80211_FC0_SUBTYPE_MASK)) {
484                 case htole16(IEEE80211_FC0_SUBTYPE_CTS):
485                 case htole16(IEEE80211_FC0_SUBTYPE_ACK):
486                         return sizeof(struct ieee80211_frame_ack);
487                 case htole16(IEEE80211_FC0_SUBTYPE_BAR):
488                         return sizeof(struct ieee80211_frame_bar);
489                 }
490                 return (sizeof(struct ieee80211_frame_min));
491         }
492
493         size = sizeof(struct ieee80211_frame);
494         if (ieee80211_is_data(fc)) {
495                 if ((fc & htole16(IEEE80211_FC1_DIR_MASK << 8)) ==
496                     htole16(IEEE80211_FC1_DIR_DSTODS << 8))
497                         size += IEEE80211_ADDR_LEN;
498                 if ((fc & htole16(IEEE80211_FC0_SUBTYPE_QOS |
499                     IEEE80211_FC0_TYPE_MASK)) ==
500                     htole16(IEEE80211_FC0_SUBTYPE_QOS |
501                     IEEE80211_FC0_TYPE_DATA))
502                         size += sizeof(uint16_t);
503         }
504
505         if (ieee80211_is_mgmt(fc)) {
506 #ifdef __notyet__
507                 if (debug_80211 > 0)
508                         printf("XXX-BZ %s: TODO? fc %#04x size %u\n",
509                             __func__, fc, size);
510 #endif
511                 ;
512         }
513
514         return (size);
515 }
516
517 #endif  /* _LINUXKPI_LINUX_IEEE80211_H */