xref: /openbsd-src/sys/net80211/ieee80211_node.h (revision 71bfe67cdf74a034a6a40f6d9c047286b602383a)
1*71bfe67cSkevlo /*	$OpenBSD: ieee80211_node.h,v 1.95 2024/11/14 07:49:24 kevlo Exp $	*/
291b2158bSmillert /*	$NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $	*/
391b2158bSmillert 
491b2158bSmillert /*-
591b2158bSmillert  * Copyright (c) 2001 Atsushi Onoe
691b2158bSmillert  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
791b2158bSmillert  * All rights reserved.
891b2158bSmillert  *
991b2158bSmillert  * Redistribution and use in source and binary forms, with or without
1091b2158bSmillert  * modification, are permitted provided that the following conditions
1191b2158bSmillert  * are met:
1291b2158bSmillert  * 1. Redistributions of source code must retain the above copyright
1391b2158bSmillert  *    notice, this list of conditions and the following disclaimer.
1491b2158bSmillert  * 2. Redistributions in binary form must reproduce the above copyright
1591b2158bSmillert  *    notice, this list of conditions and the following disclaimer in the
1691b2158bSmillert  *    documentation and/or other materials provided with the distribution.
1791b2158bSmillert  * 3. The name of the author may not be used to endorse or promote products
1891b2158bSmillert  *    derived from this software without specific prior written permission.
1991b2158bSmillert  *
2091b2158bSmillert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2191b2158bSmillert  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2291b2158bSmillert  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2391b2158bSmillert  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2491b2158bSmillert  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2591b2158bSmillert  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2691b2158bSmillert  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2791b2158bSmillert  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2891b2158bSmillert  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2991b2158bSmillert  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3091b2158bSmillert  *
3191b2158bSmillert  * $FreeBSD: src/sys/net80211/ieee80211_node.h,v 1.10 2004/04/05 22:10:26 sam Exp $
3291b2158bSmillert  */
3391b2158bSmillert #ifndef _NET80211_IEEE80211_NODE_H_
3491b2158bSmillert #define _NET80211_IEEE80211_NODE_H_
3591b2158bSmillert 
369532dee0Smpi #include <sys/tree.h>
379532dee0Smpi 
3891b2158bSmillert #define	IEEE80211_PSCAN_WAIT	5		/* passive scan wait */
3991b2158bSmillert #define	IEEE80211_TRANS_WAIT	5		/* transition wait */
4091b2158bSmillert #define	IEEE80211_INACT_WAIT	5		/* inactivity timer interval */
4191b2158bSmillert #define	IEEE80211_INACT_MAX	(300/IEEE80211_INACT_WAIT)
4224464ca2Sstsp #define	IEEE80211_CACHE_SIZE	512
43cfaefb40Sstsp #define	IEEE80211_CACHE_WAIT	30
446a173c79Sstsp #define	IEEE80211_INACT_SCAN	10		/* for station mode */
4591b2158bSmillert 
4691b2158bSmillert struct ieee80211_rateset {
4791b2158bSmillert 	u_int8_t		rs_nrates;
4891b2158bSmillert 	u_int8_t		rs_rates[IEEE80211_RATE_MAXSIZE];
4991b2158bSmillert };
5091b2158bSmillert 
51f22d9adcSdamien extern const struct ieee80211_rateset ieee80211_std_rateset_11a;
52f22d9adcSdamien extern const struct ieee80211_rateset ieee80211_std_rateset_11b;
53f22d9adcSdamien extern const struct ieee80211_rateset ieee80211_std_rateset_11g;
54f2cd5b67Sderaadt 
55*71bfe67cSkevlo /* Index into ieee80211_std_ratesets_11n[] array. */
56b812c027Sstsp #define IEEE80211_HT_RATESET_SISO	0
57b812c027Sstsp #define IEEE80211_HT_RATESET_SISO_SGI	1
58b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO2	2
59b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO2_SGI	3
60b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO3	4
61b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO3_SGI	5
62b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO4	6
63b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO4_SGI	7
64ca785ca0Sstsp #define IEEE80211_HT_RATESET_SISO_40	8
65ca785ca0Sstsp #define IEEE80211_HT_RATESET_SISO_SGI40 9
66ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO2_40	10
67ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO2_SGI40 11
68ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO3_40	12
69ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO3_SGI40 13
70ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO4_40	14
71ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO4_SGI40 15
72ca785ca0Sstsp #define IEEE80211_HT_NUM_RATESETS	16
73b812c027Sstsp 
74b812c027Sstsp /* Maximum number of rates in a HT rateset. */
75b812c027Sstsp #define IEEE80211_HT_RATESET_MAX_NRATES	8
76b812c027Sstsp 
77b812c027Sstsp /* Number of MCS indices represented by struct ieee80211_ht_rateset. */
78b812c027Sstsp #define IEEE80211_HT_RATESET_NUM_MCS 32
79b812c027Sstsp 
80b812c027Sstsp struct ieee80211_ht_rateset {
81b812c027Sstsp 	uint32_t nrates;
82b812c027Sstsp 	uint32_t rates[IEEE80211_HT_RATESET_MAX_NRATES]; /* 500 kbit/s units */
83b812c027Sstsp 
84b812c027Sstsp 	/*
85b812c027Sstsp 	 * This bitmask can only express MCS 0 - MCS 31.
86b812c027Sstsp 	 * IEEE 802.11 defined 77 HT MCS in total but common hardware
87b812c027Sstsp 	 * implementations tend to support MCS index 0 through 31 only.
88b812c027Sstsp 	 */
89b812c027Sstsp 	uint32_t mcs_mask;
90b812c027Sstsp 
91b812c027Sstsp 	/* Range of MCS indices represented in this rateset. */
92b812c027Sstsp 	int min_mcs;
93b812c027Sstsp 	int max_mcs;
94b812c027Sstsp 
95ca785ca0Sstsp 	int chan40;
96b812c027Sstsp 	int sgi;
97b812c027Sstsp };
98b812c027Sstsp 
99b812c027Sstsp extern const struct ieee80211_ht_rateset ieee80211_std_ratesets_11n[];
100b812c027Sstsp 
101*71bfe67cSkevlo /* Index into ieee80211_std_ratesets_11ac[] array. */
10250d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO		0
10350d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_SGI		1
10450d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2		2
10550d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_SGI		3
10650d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_40		4
10750d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_40_SGI	5
10850d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_40		6
10950d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_40_SGI	7
11050d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_80		8
11150d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_80_SGI	9
11250d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_80		10
11350d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_80_SGI	11
11450d1a4aeSstsp #define IEEE80211_VHT_NUM_RATESETS		12
11550d1a4aeSstsp 
1168a82c5beSstsp /* Maximum number of rates in a VHT rateset. */
11750d1a4aeSstsp #define IEEE80211_VHT_RATESET_MAX_NRATES	10
11850d1a4aeSstsp 
11950d1a4aeSstsp struct ieee80211_vht_rateset {
120*71bfe67cSkevlo 	int idx; /* This rateset's index in ieee80211_std_ratesets_11ac[]. */
1218a82c5beSstsp 
12250d1a4aeSstsp 	uint32_t nrates;
12350d1a4aeSstsp 	uint32_t rates[IEEE80211_VHT_RATESET_MAX_NRATES]; /* 500 kbit/s units */
12450d1a4aeSstsp 
12550d1a4aeSstsp 	/* Number of spatial streams used by rates in this rateset. */
12650d1a4aeSstsp 	int num_ss;
12750d1a4aeSstsp 
1288a82c5beSstsp 	int chan40;
1298a82c5beSstsp 	int chan80;
13050d1a4aeSstsp 	int sgi;
13150d1a4aeSstsp };
13250d1a4aeSstsp 
13350d1a4aeSstsp extern const struct ieee80211_vht_rateset ieee80211_std_ratesets_11ac[];
13450d1a4aeSstsp 
1357ad39289Sreyk enum ieee80211_node_state {
1367ad39289Sreyk 	IEEE80211_STA_CACHE,	/* cached node */
1377ad39289Sreyk 	IEEE80211_STA_BSS,	/* ic->ic_bss, the network we joined */
1387ad39289Sreyk 	IEEE80211_STA_AUTH,	/* successfully authenticated */
1397ad39289Sreyk 	IEEE80211_STA_ASSOC,	/* successfully associated */
1407ad39289Sreyk 	IEEE80211_STA_COLLECT	/* This node remains in the cache while
1417ad39289Sreyk 				 * the driver sends a de-auth message;
1427ad39289Sreyk 				 * afterward it should be freed to make room
1437ad39289Sreyk 				 * for a new node.
1447ad39289Sreyk 				 */
1457ad39289Sreyk };
1467ad39289Sreyk 
1477ad39289Sreyk #define	ieee80211_node_newstate(__ni, __state)	\
1487ad39289Sreyk 	do {					\
1497ad39289Sreyk 		(__ni)->ni_state = (__state);	\
1507ad39289Sreyk 	} while (0)
1517ad39289Sreyk 
152361aed72Sdamien enum ieee80211_node_psstate {
153361aed72Sdamien 	IEEE80211_PS_AWAKE,
154361aed72Sdamien 	IEEE80211_PS_DOZE
155361aed72Sdamien };
156361aed72Sdamien 
157361aed72Sdamien #define	IEEE80211_PS_MAX_QUEUE	50	/* maximum saved packets */
158361aed72Sdamien 
159e03e709cSdamien /* Authenticator state machine: 4-Way Handshake (see 8.5.6.1.1) */
160aa17e3d5Sdamien enum {
161e03e709cSdamien 	RSNA_INITIALIZE,
162aa17e3d5Sdamien 	RSNA_AUTHENTICATION,
163aa17e3d5Sdamien 	RSNA_AUTHENTICATION_2,
164aa17e3d5Sdamien 	RSNA_INITPMK,
165aa17e3d5Sdamien 	RSNA_INITPSK,
166aa17e3d5Sdamien 	RSNA_PTKSTART,
167aa17e3d5Sdamien 	RSNA_PTKCALCNEGOTIATING,
168aa17e3d5Sdamien 	RSNA_PTKCALCNEGOTIATING_2,
169aa17e3d5Sdamien 	RSNA_PTKINITNEGOTIATING,
170aa17e3d5Sdamien 	RSNA_PTKINITDONE,
171aa17e3d5Sdamien 	RSNA_DISCONNECT,
172e03e709cSdamien 	RSNA_DISCONNECTED
173e03e709cSdamien };
174e03e709cSdamien 
175e03e709cSdamien /* Authenticator state machine: Group Key Handshake (see 8.5.6.1.2) */
176e03e709cSdamien enum {
177aa17e3d5Sdamien 	RSNA_IDLE,
178aa17e3d5Sdamien 	RSNA_REKEYNEGOTIATING,
179aa17e3d5Sdamien 	RSNA_REKEYESTABLISHED,
180e03e709cSdamien 	RSNA_KEYERROR
181aa17e3d5Sdamien };
182aa17e3d5Sdamien 
18398998980Sstsp /* Supplicant state machine: 4-Way Handshake (not documented in standard) */
18498998980Sstsp enum {
18598998980Sstsp 	RSNA_SUPP_INITIALIZE,		/* not expecting any messages */
18698998980Sstsp 	RSNA_SUPP_PTKSTART,		/* awaiting handshake message 1 */
18798998980Sstsp 	RSNA_SUPP_PTKNEGOTIATING,	/* got message 1 and derived PTK */
188fbf3f982Sstsp 	RSNA_SUPP_PTKDONE		/* got message 3 and authenticated AP */
18998998980Sstsp };
19098998980Sstsp 
19145eec175Sdamien struct ieee80211_rxinfo {
19245eec175Sdamien 	u_int32_t		rxi_flags;
19345eec175Sdamien 	u_int32_t		rxi_tstamp;
19445eec175Sdamien 	int			rxi_rssi;
1957307575aSstsp 	uint8_t			rxi_chan;
19645eec175Sdamien };
19745eec175Sdamien #define IEEE80211_RXI_HWDEC		0x00000001
19845eec175Sdamien #define IEEE80211_RXI_AMPDU_DONE	0x00000002
199ccc2d1c4Sstsp #define IEEE80211_RXI_HWDEC_SAME_PN	0x00000004
200ccc2d1c4Sstsp #define IEEE80211_RXI_SAME_SEQ		0x00000008
20145eec175Sdamien 
20245eec175Sdamien /* Block Acknowledgement Record */
203ec69e05aSdamien struct ieee80211_tx_ba {
20445eec175Sdamien 	struct ieee80211_node	*ba_ni;	/* backpointer for callbacks */
20545eec175Sdamien 	struct timeout		ba_to;
20645eec175Sdamien 	int			ba_timeout_val;
20745eec175Sdamien 	int			ba_state;
20845eec175Sdamien #define IEEE80211_BA_INIT	0
20945eec175Sdamien #define IEEE80211_BA_REQUESTED	1
21045eec175Sdamien #define IEEE80211_BA_AGREED	2
21145eec175Sdamien 
2123367136cSstsp 	/* ADDBA parameter set field for this BA agreement. */
2133367136cSstsp 	u_int16_t		ba_params;
2143367136cSstsp 
21520fce2ddSstsp 	/* These values are IEEE802.11 frame sequence numbers (0x0-0xfff) */
21645eec175Sdamien 	u_int16_t		ba_winstart;
21745eec175Sdamien 	u_int16_t		ba_winend;
21820fce2ddSstsp 
21920fce2ddSstsp 	/* Number of A-MPDU subframes in reorder buffer. */
22045eec175Sdamien 	u_int16_t		ba_winsize;
22120fce2ddSstsp #define IEEE80211_BA_MAX_WINSZ	64	/* corresponds to maximum ADDBA BUFSZ */
22245eec175Sdamien 
22345eec175Sdamien 	u_int8_t		ba_token;
224aefc44daSstsp 
225aefc44daSstsp 	/* Bitmap for ACK'd frames in the current BA window. */
226aefc44daSstsp 	uint64_t		ba_bitmap;
22745eec175Sdamien };
22845eec175Sdamien 
229ec69e05aSdamien struct ieee80211_rx_ba {
230ec69e05aSdamien 	struct ieee80211_node	*ba_ni;	/* backpointer for callbacks */
231ec69e05aSdamien 	struct {
232ec69e05aSdamien 		struct mbuf		*m;
233ec69e05aSdamien 		struct ieee80211_rxinfo	rxi;
234ec69e05aSdamien 	}			*ba_buf;
235ec69e05aSdamien 	struct timeout		ba_to;
236ec69e05aSdamien 	int			ba_timeout_val;
237ec69e05aSdamien 	int			ba_state;
2383367136cSstsp 	u_int16_t		ba_params;
239ec69e05aSdamien 	u_int16_t		ba_winstart;
240ec69e05aSdamien 	u_int16_t		ba_winend;
241ec69e05aSdamien 	u_int16_t		ba_winsize;
242ec69e05aSdamien 	u_int16_t		ba_head;
24320fce2ddSstsp 	struct timeout		ba_gap_to;
244580511faSstsp #define IEEE80211_BA_GAP_TIMEOUT	300 /* msec */
24520599cf9Sstsp 
24620599cf9Sstsp 	/*
24720599cf9Sstsp 	 * Counter for frames forced to wait in the reordering buffer
24820599cf9Sstsp 	 * due to a leading gap caused by one or more missing frames.
24920599cf9Sstsp 	 */
25020599cf9Sstsp 	int			ba_gapwait;
25120599cf9Sstsp 
2520b126c70Sstsp 	/* Counter for consecutive frames which missed the BA window. */
2530b126c70Sstsp 	int			ba_winmiss;
2540b126c70Sstsp 	/* Sequence number of previous frame which missed the BA window. */
2550b126c70Sstsp 	uint16_t		ba_missedsn;
2560b126c70Sstsp 	/* Window moves forward after this many frames have missed it. */
2570b126c70Sstsp #define IEEE80211_BA_MAX_WINMISS	8
25871c11c14Sstsp 
25971c11c14Sstsp 	uint8_t			ba_token;
260ec69e05aSdamien };
261ec69e05aSdamien 
26291b2158bSmillert /*
26391b2158bSmillert  * Node specific information.  Note that drivers are expected
26491b2158bSmillert  * to derive from this structure to add device-specific per-node
26591b2158bSmillert  * state.  This is done by overriding the ic_node_* methods in
26691b2158bSmillert  * the ieee80211com structure.
26791b2158bSmillert  */
26891b2158bSmillert struct ieee80211_node {
2698529d8f0Sdlg 	RBT_ENTRY(ieee80211_node)	ni_node;
2703ce67372Sreyk 
271e03e709cSdamien 	struct ieee80211com	*ni_ic;		/* back-pointer */
272e03e709cSdamien 
27391b2158bSmillert 	u_int			ni_refcnt;
27491b2158bSmillert 	u_int			ni_scangen;	/* gen# for timeout scan */
27591b2158bSmillert 
27691b2158bSmillert 	/* hardware */
27791b2158bSmillert 	u_int32_t		ni_rstamp;	/* recv timestamp */
27891b2158bSmillert 	u_int8_t		ni_rssi;	/* recv ssi */
27991b2158bSmillert 
2809a4d53fcSdamien 	/* header */
2819a4d53fcSdamien 	u_int8_t		ni_macaddr[IEEE80211_ADDR_LEN];
2829a4d53fcSdamien 	u_int8_t		ni_bssid[IEEE80211_ADDR_LEN];
2839a4d53fcSdamien 
28491b2158bSmillert 	/* beacon, probe response */
28591b2158bSmillert 	u_int8_t		ni_tstamp[8];	/* from last rcv'd beacon */
28691b2158bSmillert 	u_int16_t		ni_intval;	/* beacon interval */
28791b2158bSmillert 	u_int16_t		ni_capinfo;	/* capabilities */
28891b2158bSmillert 	u_int8_t		ni_esslen;
28991b2158bSmillert 	u_int8_t		ni_essid[IEEE80211_NWID_LEN];
29091b2158bSmillert 	struct ieee80211_rateset ni_rates;	/* negotiated rate set */
29191b2158bSmillert 	u_int8_t		*ni_country;	/* country information XXX */
29291b2158bSmillert 	struct ieee80211_channel *ni_chan;
29391b2158bSmillert 	u_int8_t		ni_erp;		/* 11g only */
29491b2158bSmillert 
29591b2158bSmillert 	/* DTIM and contention free period (CFP) */
296bacd9707Sstsp 	u_int8_t		ni_dtimcount;
29791b2158bSmillert 	u_int8_t		ni_dtimperiod;
298bacd9707Sstsp #ifdef notyet
29991b2158bSmillert 	u_int8_t		ni_cfpperiod;	/* # of DTIMs between CFPs */
30091b2158bSmillert 	u_int16_t		ni_cfpduremain;	/* remaining cfp duration */
30191b2158bSmillert 	u_int16_t		ni_cfpmaxduration;/* max CFP duration in TU */
30291b2158bSmillert 	u_int16_t		ni_nextdtim;	/* time to next DTIM */
30391b2158bSmillert 	u_int16_t		ni_timoffset;
30491b2158bSmillert #endif
30591b2158bSmillert 
30691b2158bSmillert 	/* power saving mode */
30791b2158bSmillert 	u_int8_t		ni_pwrsave;
308351e1934Sdlg 	struct mbuf_queue	ni_savedq;	/* packets queued for pspoll */
30991b2158bSmillert 
31005534718Sdamien 	/* RSN */
31145eec175Sdamien 	struct timeout		ni_eapol_to;
312aa17e3d5Sdamien 	u_int			ni_rsn_state;
31398998980Sstsp 	u_int			ni_rsn_supp_state;
314e03e709cSdamien 	u_int			ni_rsn_gstate;
315e03e709cSdamien 	u_int			ni_rsn_retries;
316b2709672Sstsp 	u_int			ni_supported_rsnprotos;
317e03e709cSdamien 	u_int			ni_rsnprotos;
318b2709672Sstsp 	u_int			ni_supported_rsnakms;
319e03e709cSdamien 	u_int			ni_rsnakms;
320e03e709cSdamien 	u_int			ni_rsnciphers;
321e03e709cSdamien 	enum ieee80211_cipher	ni_rsngroupcipher;
3223dc5ecc7Sdamien 	enum ieee80211_cipher	ni_rsngroupmgmtcipher;
32305534718Sdamien 	u_int16_t		ni_rsncaps;
324e03e709cSdamien 	enum ieee80211_cipher	ni_rsncipher;
325991765deSdamien 	u_int8_t		ni_nonce[EAPOL_KEY_NONCE_LEN];
326f91ff320Sdamien 	u_int8_t		ni_pmk[IEEE80211_PMK_LEN];
327f91ff320Sdamien 	u_int8_t		ni_pmkid[IEEE80211_PMKID_LEN];
328991765deSdamien 	u_int64_t		ni_replaycnt;
329692af90cSdamien 	u_int8_t		ni_replaycnt_ok;
330e03e709cSdamien 	u_int64_t		ni_reqreplaycnt;
331e03e709cSdamien 	u_int8_t		ni_reqreplaycnt_ok;
332991765deSdamien 	u_int8_t		*ni_rsnie;
3335e0cdda0Sdamien 	struct ieee80211_key	ni_pairwise_key;
334991765deSdamien 	struct ieee80211_ptk	ni_ptk;
335991765deSdamien 	u_int8_t		ni_key_count;
336e03e709cSdamien 	int			ni_port_valid;
33705534718Sdamien 
33845eec175Sdamien 	/* SA Query */
339199d5af3Sdamien 	u_int16_t		ni_sa_query_trid;
34045eec175Sdamien 	struct timeout		ni_sa_query_to;
34145eec175Sdamien 	int			ni_sa_query_count;
34245eec175Sdamien 
343fe8f5243Sstsp 	/* HT capabilities */
344fe8f5243Sstsp 	uint16_t		ni_htcaps;
345fe8f5243Sstsp 	uint8_t			ni_ampdu_param;
346fe8f5243Sstsp 	uint8_t			ni_rxmcs[howmany(80,NBBY)];
347fe8f5243Sstsp 	uint16_t		ni_max_rxrate;	/* in Mb/s, 0 <= rate <= 1023 */
348fe8f5243Sstsp 	uint8_t			ni_tx_mcs_set;
349fe8f5243Sstsp 	uint16_t		ni_htxcaps;
350fe8f5243Sstsp 	uint32_t		ni_txbfcaps;
351fe8f5243Sstsp 	uint8_t			ni_aselcaps;
352fe8f5243Sstsp 
353fe8f5243Sstsp 	/* HT operation */
354fe8f5243Sstsp 	uint8_t			ni_primary_chan; /* XXX corresponds to ni_chan */
355fe8f5243Sstsp 	uint8_t			ni_htop0;
356fe8f5243Sstsp 	uint16_t		ni_htop1;
357fe8f5243Sstsp 	uint16_t		ni_htop2;
358fe8f5243Sstsp 	uint8_t			ni_basic_mcs[howmany(128,NBBY)];
359fe8f5243Sstsp 
36050e8fe1cSstsp 	/* VHT capabilities */
36150e8fe1cSstsp 	uint32_t		ni_vhtcaps;
36250e8fe1cSstsp 	uint16_t		ni_vht_rxmcs;
36350e8fe1cSstsp 	uint16_t		ni_vht_rx_max_lgi_mbit_s;
36450e8fe1cSstsp 	uint16_t		ni_vht_txmcs;
36550e8fe1cSstsp 	uint16_t		ni_vht_tx_max_lgi_mbit_s;
36650e8fe1cSstsp 
36750e8fe1cSstsp 	/* VHT operation */
36850e8fe1cSstsp 	uint8_t			ni_vht_chan_width;
36950e8fe1cSstsp 	uint8_t			ni_vht_chan_center_freq_idx0;
37050e8fe1cSstsp 	uint8_t			ni_vht_chan_center_freq_idx1;
37150e8fe1cSstsp 	uint16_t		ni_vht_basic_mcs;
37250e8fe1cSstsp 
373aefc44daSstsp 	/* Timeout handlers which trigger Tx Block Ack negotiation. */
374aefc44daSstsp 	struct timeout		ni_addba_req_to[IEEE80211_NUM_TID];
375aefc44daSstsp 	int			ni_addba_req_intval[IEEE80211_NUM_TID];
376aefc44daSstsp #define IEEE80211_ADDBA_REQ_INTVAL_MAX 30	/* in seconds */
377aefc44daSstsp 
378ec69e05aSdamien 	/* Block Ack records */
379ec69e05aSdamien 	struct ieee80211_tx_ba	ni_tx_ba[IEEE80211_NUM_TID];
380ec69e05aSdamien 	struct ieee80211_rx_ba	ni_rx_ba[IEEE80211_NUM_TID];
3814c97d237Sstsp 
3824c97d237Sstsp 	int			ni_txmcs;	/* current MCS used for TX */
38350d1a4aeSstsp 	int			ni_vht_ss;	/* VHT # spatial streams */
38445eec175Sdamien 
38591b2158bSmillert 	/* others */
38691b2158bSmillert 	u_int16_t		ni_associd;	/* assoc response */
38791b2158bSmillert 	u_int16_t		ni_txseq;	/* seq to be transmitted */
38891b2158bSmillert 	u_int16_t		ni_rxseq;	/* seq previous received */
38932e88c03Sdamien 	u_int16_t		ni_qos_txseqs[IEEE80211_NUM_TID];
39032e88c03Sdamien 	u_int16_t		ni_qos_rxseqs[IEEE80211_NUM_TID];
39191b2158bSmillert 	int			ni_fails;	/* failure count to associate */
392799b58a5Sstsp 	uint32_t		ni_assoc_fail;	/* assoc failure reasons */
393799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_CHAN		0x01
394799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_IBSS		0x02
395799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_PRIVACY	0x04
396799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_BASIC_RATE	0x08
397799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_ESSID		0x10
398799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_BSSID		0x20
399799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_WPA_PROTO	0x40
400799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_WPA_KEY	0x80
401799b58a5Sstsp 
40291b2158bSmillert 	int			ni_inact;	/* inactivity mark count */
40391b2158bSmillert 	int			ni_txrate;	/* index to ni_rates[] */
4047ad39289Sreyk 	int			ni_state;
40505534718Sdamien 
40650d1a4aeSstsp 	u_int32_t		ni_flags;	/* special-purpose state */
407f91ff320Sdamien #define IEEE80211_NODE_ERP		0x0001
408f91ff320Sdamien #define IEEE80211_NODE_QOS		0x0002
409f91ff320Sdamien #define IEEE80211_NODE_REKEY		0x0004	/* GTK rekeying in progress */
410f91ff320Sdamien #define IEEE80211_NODE_RXPROT		0x0008	/* RX protection ON */
411f91ff320Sdamien #define IEEE80211_NODE_TXPROT		0x0010	/* TX protection ON */
41201ad6d9fSdamien #define IEEE80211_NODE_TXRXPROT	\
41301ad6d9fSdamien 	(IEEE80211_NODE_TXPROT | IEEE80211_NODE_RXPROT)
414f91ff320Sdamien #define IEEE80211_NODE_RXMGMTPROT	0x0020	/* RX MMPDU protection ON */
415f91ff320Sdamien #define IEEE80211_NODE_TXMGMTPROT	0x0040	/* TX MMPDU protection ON */
416f91ff320Sdamien #define IEEE80211_NODE_MFP		0x0080	/* MFP negotiated */
417f91ff320Sdamien #define IEEE80211_NODE_PMK		0x0100	/* ni_pmk set */
418f91ff320Sdamien #define IEEE80211_NODE_PMKID		0x0200	/* ni_pmkid set */
41945eec175Sdamien #define IEEE80211_NODE_HT		0x0400	/* HT negotiated */
42045eec175Sdamien #define IEEE80211_NODE_SA_QUERY		0x0800	/* SA Query in progress */
42145eec175Sdamien #define IEEE80211_NODE_SA_QUERY_FAILED	0x1000	/* last SA Query failed */
4222e40dd69Sstsp #define IEEE80211_NODE_RSN_NEW_PTK	0x2000	/* expecting a new PTK */
423b812c027Sstsp #define IEEE80211_NODE_HT_SGI20		0x4000	/* SGI on 20 MHz negotiated */
424b812c027Sstsp #define IEEE80211_NODE_HT_SGI40		0x8000	/* SGI on 40 MHz negotiated */
42550d1a4aeSstsp #define IEEE80211_NODE_VHT		0x10000	/* VHT negotiated */
4261c062f30Sstsp #define IEEE80211_NODE_HTCAP		0x20000	/* claims to support HT */
42750e8fe1cSstsp #define IEEE80211_NODE_VHTCAP		0x40000	/* claims to support VHT */
42850e8fe1cSstsp #define IEEE80211_NODE_VHT_SGI80	0x80000	/* SGI on 80 MHz negotiated */
42950e8fe1cSstsp #define IEEE80211_NODE_VHT_SGI160	0x100000 /* SGI on 160 MHz negotiated */
43006e069b5Sstsp 
43106e069b5Sstsp 	/* If not NULL, this function gets called when ni_refcnt hits zero. */
43206e069b5Sstsp 	void			(*ni_unref_cb)(struct ieee80211com *,
43306e069b5Sstsp 					struct ieee80211_node *);
43406e069b5Sstsp 	void *			ni_unref_arg;
43506e069b5Sstsp 	size_t 			ni_unref_arg_size;
43691b2158bSmillert };
43791b2158bSmillert 
4388529d8f0Sdlg RBT_HEAD(ieee80211_tree, ieee80211_node);
4393ce67372Sreyk 
440020402a2Sphessler struct ieee80211_ess_rbt {
441020402a2Sphessler 	RBT_ENTRY(ieee80211_ess_rbt)	 ess_rbt;
442020402a2Sphessler 	u_int8_t			 esslen;
443020402a2Sphessler 	u_int8_t			 essid[IEEE80211_NWID_LEN];
444020402a2Sphessler 	struct ieee80211_node		*ni2;
445020402a2Sphessler 	struct ieee80211_node		*ni5;
446020402a2Sphessler 	struct ieee80211_node		*ni;
447020402a2Sphessler };
448020402a2Sphessler 
449020402a2Sphessler RBT_HEAD(ieee80211_ess_tree, ieee80211_ess_rbt);
450020402a2Sphessler 
4512edbedcfSphessler static inline void
45226b1026eSstsp ieee80211_node_incref(struct ieee80211_node *ni)
45326b1026eSstsp {
45426b1026eSstsp 	int		s;
45591b2158bSmillert 
45626b1026eSstsp 	s = splnet();
45726b1026eSstsp 	ni->ni_refcnt++;
45826b1026eSstsp 	splx(s);
45926b1026eSstsp }
46026b1026eSstsp 
4612edbedcfSphessler static inline u_int
46291b2158bSmillert ieee80211_node_decref(struct ieee80211_node *ni)
46391b2158bSmillert {
46426b1026eSstsp 	u_int		refcnt;
46526b1026eSstsp 	int 		s;
46626b1026eSstsp 
46791b2158bSmillert 	s = splnet();
46891b2158bSmillert 	refcnt = --ni->ni_refcnt;
46991b2158bSmillert 	splx(s);
47091b2158bSmillert 	return refcnt;
47191b2158bSmillert }
47291b2158bSmillert 
4732edbedcfSphessler static inline struct ieee80211_node *
47491b2158bSmillert ieee80211_ref_node(struct ieee80211_node *ni)
47591b2158bSmillert {
47691b2158bSmillert 	ieee80211_node_incref(ni);
47791b2158bSmillert 	return ni;
47891b2158bSmillert }
47991b2158bSmillert 
4802edbedcfSphessler static inline void
48191b2158bSmillert ieee80211_unref_node(struct ieee80211_node **ni)
48291b2158bSmillert {
48391b2158bSmillert 	ieee80211_node_decref(*ni);
48491b2158bSmillert 	*ni = NULL;			/* guard against use */
48591b2158bSmillert }
48691b2158bSmillert 
48708e4cc2bSphessler /*
48808e4cc2bSphessler  * Check if the peer supports HT.
4891c062f30Sstsp  * Require a HT capabilities IE and at least one of the mandatory MCS.
49008e4cc2bSphessler  * MCS 0-7 are mandatory but some APs have particular MCS disabled.
49108e4cc2bSphessler  */
49208e4cc2bSphessler static inline int
49308e4cc2bSphessler ieee80211_node_supports_ht(struct ieee80211_node *ni)
49408e4cc2bSphessler {
4951c062f30Sstsp 	return ((ni->ni_flags & IEEE80211_NODE_HTCAP) &&
4961c062f30Sstsp 	    ni->ni_rxmcs[0] & 0xff);
49708e4cc2bSphessler }
49808e4cc2bSphessler 
499b812c027Sstsp /* Check if the peer supports HT short guard interval (SGI) on 20 MHz. */
500b812c027Sstsp static inline int
501b812c027Sstsp ieee80211_node_supports_ht_sgi20(struct ieee80211_node *ni)
502b812c027Sstsp {
503b812c027Sstsp 	return ieee80211_node_supports_ht(ni) &&
504b812c027Sstsp 	    (ni->ni_htcaps & IEEE80211_HTCAP_SGI20);
505b812c027Sstsp }
506b812c027Sstsp 
507b812c027Sstsp /* Check if the peer supports HT short guard interval (SGI) on 40 MHz. */
508b812c027Sstsp static inline int
509b812c027Sstsp ieee80211_node_supports_ht_sgi40(struct ieee80211_node *ni)
510b812c027Sstsp {
511b812c027Sstsp 	return ieee80211_node_supports_ht(ni) &&
512b812c027Sstsp 	    (ni->ni_htcaps & IEEE80211_HTCAP_SGI40);
513b812c027Sstsp }
514b812c027Sstsp 
515ca785ca0Sstsp /* Check if the peer can receive frames sent on a 40 MHz channel. */
516ca785ca0Sstsp static inline int
517ca785ca0Sstsp ieee80211_node_supports_ht_chan40(struct ieee80211_node *ni)
518ca785ca0Sstsp {
519ca785ca0Sstsp 	return (ieee80211_node_supports_ht(ni) &&
520ca785ca0Sstsp 	    (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) &&
521ca785ca0Sstsp 	    (ni->ni_htop0 & IEEE80211_HTOP0_CHW));
522ca785ca0Sstsp }
523ca785ca0Sstsp 
52450e8fe1cSstsp /*
52550e8fe1cSstsp  * Check if the peer supports VHT.
52650e8fe1cSstsp  * Require a VHT capabilities IE and support for VHT MCS with a single
52750e8fe1cSstsp  * spatial stream.
52850e8fe1cSstsp  */
52950e8fe1cSstsp static inline int
53050e8fe1cSstsp ieee80211_node_supports_vht(struct ieee80211_node *ni)
53150e8fe1cSstsp {
53250e8fe1cSstsp 	uint16_t rx_mcs;
53350e8fe1cSstsp 
53450e8fe1cSstsp 	rx_mcs = (ni->ni_vht_rxmcs & IEEE80211_VHT_MCS_FOR_SS_MASK(1)) >>
53550e8fe1cSstsp 	    IEEE80211_VHT_MCS_FOR_SS_SHIFT(1);
53650e8fe1cSstsp 
53750e8fe1cSstsp 	return ((ni->ni_flags & IEEE80211_NODE_VHTCAP) &&
53850e8fe1cSstsp 	    rx_mcs != IEEE80211_VHT_MCS_SS_NOT_SUPP);
53950e8fe1cSstsp }
54050e8fe1cSstsp 
54150e8fe1cSstsp /* Check if the peer supports VHT short guard interval (SGI) on 80 MHz. */
54250e8fe1cSstsp static inline int
54350e8fe1cSstsp ieee80211_node_supports_vht_sgi80(struct ieee80211_node *ni)
54450e8fe1cSstsp {
54550e8fe1cSstsp 	return ieee80211_node_supports_vht(ni) &&
54650e8fe1cSstsp 	    (ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI80);
54750e8fe1cSstsp }
54850e8fe1cSstsp 
54950e8fe1cSstsp /* Check if the peer supports VHT short guard interval (SGI) on 160 MHz. */
55050e8fe1cSstsp static inline int
55150e8fe1cSstsp ieee80211_node_supports_vht_sgi160(struct ieee80211_node *ni)
55250e8fe1cSstsp {
55350e8fe1cSstsp 	return ieee80211_node_supports_vht(ni) &&
55450e8fe1cSstsp 	    (ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI160);
55550e8fe1cSstsp }
55650e8fe1cSstsp 
55750e8fe1cSstsp /* Check if the peer can receive frames sent on an 80 MHz channel. */
55850e8fe1cSstsp static inline int
55950e8fe1cSstsp ieee80211_node_supports_vht_chan80(struct ieee80211_node *ni)
56050e8fe1cSstsp {
56150e8fe1cSstsp 	uint8_t cap_chan_width, op_chan_width;
56250e8fe1cSstsp 
56350e8fe1cSstsp 	if (!ieee80211_node_supports_vht(ni))
56450e8fe1cSstsp 		return 0;
56550e8fe1cSstsp 
56650e8fe1cSstsp 	cap_chan_width = (ni->ni_vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) >>
56750e8fe1cSstsp 	    IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT;
56850e8fe1cSstsp 	if (cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_80 &&
56950e8fe1cSstsp 	    cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160 &&
57050e8fe1cSstsp 	    cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160_8080)
57150e8fe1cSstsp 		return 0;
57250e8fe1cSstsp 
57350e8fe1cSstsp 	op_chan_width = (ni->ni_vht_chan_width &
57450e8fe1cSstsp 	    IEEE80211_VHTOP0_CHAN_WIDTH_MASK) >>
57550e8fe1cSstsp 	    IEEE80211_VHTOP0_CHAN_WIDTH_SHIFT;
57650e8fe1cSstsp 
57750e8fe1cSstsp 	return (op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80 ||
57850e8fe1cSstsp 	    op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_160 ||
57950e8fe1cSstsp 	    op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_8080);
58050e8fe1cSstsp }
58150e8fe1cSstsp 
5828a82c5beSstsp /* Check if the peer can receive frames sent on a 160 MHz channel. */
5838a82c5beSstsp static inline int
5848a82c5beSstsp ieee80211_node_supports_vht_chan160(struct ieee80211_node *ni)
5858a82c5beSstsp {
5868a82c5beSstsp 	uint8_t cap_chan_width, op_chan_width;
5878a82c5beSstsp 
5888a82c5beSstsp 	if (!ieee80211_node_supports_vht(ni))
5898a82c5beSstsp 		return 0;
5908a82c5beSstsp 
5918a82c5beSstsp 	cap_chan_width = (ni->ni_vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) >>
5928a82c5beSstsp 	    IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT;
5938a82c5beSstsp 	if (cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160)
5948a82c5beSstsp 		return 0;
5958a82c5beSstsp 
5968a82c5beSstsp 	op_chan_width = (ni->ni_vht_chan_width &
5978a82c5beSstsp 	    IEEE80211_VHTOP0_CHAN_WIDTH_MASK) >>
5988a82c5beSstsp 	    IEEE80211_VHTOP0_CHAN_WIDTH_SHIFT;
5998a82c5beSstsp 
6008a82c5beSstsp 	return (op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_160);
6018a82c5beSstsp }
6028a82c5beSstsp 
60391b2158bSmillert struct ieee80211com;
60491b2158bSmillert 
60571ca7184Sphessler typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
60691b2158bSmillert 
60771ca7184Sphessler void ieee80211_node_attach(struct ifnet *);
60871ca7184Sphessler void ieee80211_node_lateattach(struct ifnet *);
60971ca7184Sphessler void ieee80211_node_detach(struct ifnet *);
61091b2158bSmillert 
61171ca7184Sphessler void ieee80211_begin_scan(struct ifnet *);
61271ca7184Sphessler void ieee80211_next_scan(struct ifnet *);
61371ca7184Sphessler void ieee80211_end_scan(struct ifnet *);
61471ca7184Sphessler void ieee80211_reset_scan(struct ifnet *);
61571ca7184Sphessler struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *,
616f22d9adcSdamien 		const u_int8_t *);
61771ca7184Sphessler struct ieee80211_node *ieee80211_dup_bss(struct ieee80211com *,
618f22d9adcSdamien 		const u_int8_t *);
61971ca7184Sphessler struct ieee80211_node *ieee80211_find_node(struct ieee80211com *,
620f22d9adcSdamien 		const u_int8_t *);
621de9c1173Sstsp void ieee80211_node_tx_ba_clear(struct ieee80211_node *, int);
622aefc44daSstsp void ieee80211_ba_del(struct ieee80211_node *);
62371ca7184Sphessler struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *,
624f22d9adcSdamien 		const struct ieee80211_frame *);
62571ca7184Sphessler struct ieee80211_node *ieee80211_find_txnode(struct ieee80211com *,
626f22d9adcSdamien 		const u_int8_t *);
62771ca7184Sphessler void ieee80211_release_node(struct ieee80211com *,
62891b2158bSmillert 		struct ieee80211_node *);
6296a173c79Sstsp void ieee80211_node_cleanup(struct ieee80211com *, struct ieee80211_node *);
630d466420eSstsp void ieee80211_free_allnodes(struct ieee80211com *, int);
63171ca7184Sphessler void ieee80211_iterate_nodes(struct ieee80211com *,
63291b2158bSmillert 		ieee80211_iter_func *, void *);
63371ca7184Sphessler void ieee80211_clean_cached(struct ieee80211com *);
63471ca7184Sphessler void ieee80211_clean_nodes(struct ieee80211com *, int);
635fe8f5243Sstsp void ieee80211_setup_htcaps(struct ieee80211_node *, const uint8_t *,
636fe8f5243Sstsp     uint8_t);
6372040b0e1Sstsp void ieee80211_clear_htcaps(struct ieee80211_node *);
6387a831903Sstsp int ieee80211_setup_htop(struct ieee80211_node *, const uint8_t *,
639f9214ef6Sstsp     uint8_t, int);
64050e8fe1cSstsp void ieee80211_setup_vhtcaps(struct ieee80211_node *, const uint8_t *,
64150e8fe1cSstsp     uint8_t);
64250e8fe1cSstsp void ieee80211_clear_vhtcaps(struct ieee80211_node *);
64350e8fe1cSstsp int ieee80211_setup_vhtop(struct ieee80211_node *, const uint8_t *,
64450e8fe1cSstsp     uint8_t, int);
64571ca7184Sphessler int ieee80211_setup_rates(struct ieee80211com *,
6466de17962Sdamien 	    struct ieee80211_node *, const u_int8_t *, const u_int8_t *, int);
647aefc44daSstsp void ieee80211_node_trigger_addba_req(struct ieee80211_node *, int);
64871ca7184Sphessler int ieee80211_iserp_sta(const struct ieee80211_node *);
64971ca7184Sphessler void ieee80211_count_longslotsta(void *, struct ieee80211_node *);
65071ca7184Sphessler void ieee80211_count_nonerpsta(void *, struct ieee80211_node *);
65171ca7184Sphessler void ieee80211_count_pssta(void *, struct ieee80211_node *);
65271ca7184Sphessler void ieee80211_count_rekeysta(void *, struct ieee80211_node *);
65371ca7184Sphessler void ieee80211_node_join(struct ieee80211com *,
6540fd4e251Sreyk 		struct ieee80211_node *, int);
65571ca7184Sphessler void ieee80211_node_leave(struct ieee80211com *,
6560fd4e251Sreyk 		struct ieee80211_node *);
657799b58a5Sstsp int ieee80211_match_bss(struct ieee80211com *, struct ieee80211_node *, int);
658de9c1173Sstsp void ieee80211_node_tx_stopped(struct ieee80211com *, struct ieee80211_node *);
65940dc231eSstsp struct ieee80211_node *ieee80211_node_choose_bss(struct ieee80211com *, int,
66040dc231eSstsp 		struct ieee80211_node **);
66140dc231eSstsp void ieee80211_node_join_bss(struct ieee80211com *, struct ieee80211_node *);
66271ca7184Sphessler void ieee80211_create_ibss(struct ieee80211com* ,
66391b2158bSmillert 		struct ieee80211_channel *);
66471ca7184Sphessler void ieee80211_notify_dtim(struct ieee80211com *);
66571ca7184Sphessler void ieee80211_set_tim(struct ieee80211com *, int, int);
66626bb14d9Sphessler void ieee80211_free_node(struct ieee80211com *, struct ieee80211_node *);
6673ce67372Sreyk 
66871ca7184Sphessler int ieee80211_node_cmp(const struct ieee80211_node *,
669f22d9adcSdamien 		const struct ieee80211_node *);
670020402a2Sphessler int ieee80211_ess_cmp(const struct ieee80211_ess_rbt *,
671020402a2Sphessler 		const struct ieee80211_ess_rbt *);
6728529d8f0Sdlg RBT_PROTOTYPE(ieee80211_tree, ieee80211_node, ni_node, ieee80211_node_cmp);
673020402a2Sphessler RBT_PROTOTYPE(ieee80211_ess_tree, ieee80211_ess_rbt, ess_rbt, ieee80211_ess_cmp);
6743ce67372Sreyk 
67591b2158bSmillert #endif /* _NET80211_IEEE80211_NODE_H_ */
676