ieee80211_freebsd.h revision 144302
1163611Sphk/*-
2163611Sphk * Copyright (c) 2003-2005 Sam Leffler, Errno Consulting
3163611Sphk * All rights reserved.
4163611Sphk *
5163611Sphk * Redistribution and use in source and binary forms, with or without
6163611Sphk * modification, are permitted provided that the following conditions
7163611Sphk * are met:
8163611Sphk * 1. Redistributions of source code must retain the above copyright
9163611Sphk *    notice, this list of conditions and the following disclaimer.
10163611Sphk * 2. Redistributions in binary form must reproduce the above copyright
11163611Sphk *    notice, this list of conditions and the following disclaimer in the
12163611Sphk *    documentation and/or other materials provided with the distribution.
13163611Sphk * 3. The name of the author may not be used to endorse or promote products
14163611Sphk *    derived from this software without specific prior written permission.
15163611Sphk *
16163611Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17163611Sphk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18163611Sphk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19163611Sphk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20163611Sphk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21163611Sphk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22163611Sphk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23163611Sphk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24163611Sphk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25163611Sphk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26163611Sphk *
27163611Sphk * $FreeBSD: head/sys/net80211/ieee80211_freebsd.h 144302 2005-03-29 19:36:42Z sam $
28163611Sphk */
29163611Sphk#ifndef _NET80211_IEEE80211_FREEBSD_H_
30163611Sphk#define _NET80211_IEEE80211_FREEBSD_H_
31163611Sphk
32163611Sphk/*
33163611Sphk * Beacon locking definitions.
34163611Sphk */
35163611Sphktypedef struct mtx ieee80211_beacon_lock_t;
36163611Sphk#define	IEEE80211_BEACON_LOCK_INIT(_ic, _name) \
37163611Sphk	mtx_init(&(_ic)->ic_beaconlock, _name, "802.11 beacon lock", MTX_DEF)
38163611Sphk#define	IEEE80211_BEACON_LOCK_DESTROY(_ic) mtx_destroy(&(_ic)->ic_beaconlock)
39163611Sphk#define	IEEE80211_BEACON_LOCK(_ic)	   mtx_lock(&(_ic)->ic_beaconlock)
40163611Sphk#define	IEEE80211_BEACON_UNLOCK(_ic)	   mtx_unlock(&(_ic)->ic_beaconlock)
41163611Sphk#define	IEEE80211_BEACON_LOCK_ASSERT(_ic) \
42163611Sphk	mtx_assert(&(_ic)->ic_beaconlock, MA_OWNED)
43163611Sphk
44163611Sphk/*
45163611Sphk * Node locking definitions.
46163611Sphk */
47163611Sphktypedef struct mtx ieee80211_node_lock_t;
48275985Simp#define	IEEE80211_NODE_LOCK_INIT(_nt, _name) \
49163611Sphk	mtx_init(&(_nt)->nt_nodelock, _name, "802.11 node table", MTX_DEF)
50163611Sphk#define	IEEE80211_NODE_LOCK_DESTROY(_nt)	mtx_destroy(&(_nt)->nt_nodelock)
51163646Sphk#define	IEEE80211_NODE_LOCK(_nt)		mtx_lock(&(_nt)->nt_nodelock)
52264620Skib#define	IEEE80211_NODE_UNLOCK(_nt)		mtx_unlock(&(_nt)->nt_nodelock)
53163611Sphk#define	IEEE80211_NODE_LOCK_ASSERT(_nt) \
54264694Sian	mtx_assert(&(_nt)->nt_nodelock, MA_OWNED)
55163611Sphk
56163611Sphk/*
57163611Sphk * Node table scangen locking definitions.
58163611Sphk */
59163611Sphktypedef struct mtx ieee80211_scan_lock_t;
60163611Sphk#define	IEEE80211_SCAN_LOCK_INIT(_nt, _name) \
61163611Sphk	mtx_init(&(_nt)->nt_scanlock, _name, "802.11 scangen", MTX_DEF)
62163611Sphk#define	IEEE80211_SCAN_LOCK_DESTROY(_nt)	mtx_destroy(&(_nt)->nt_scanlock)
63163611Sphk#define	IEEE80211_SCAN_LOCK(_nt)		mtx_lock(&(_nt)->nt_scanlock)
64163611Sphk#define	IEEE80211_SCAN_UNLOCK(_nt)		mtx_unlock(&(_nt)->nt_scanlock)
65163611Sphk#define	IEEE80211_SCAN_LOCK_ASSERT(_nt) \
66163611Sphk	mtx_assert(&(_nt)->nt_scanlock, MA_OWNED)
67163611Sphk
68163611Sphk/*
69163611Sphk * Per-node power-save queue definitions.
70163611Sphk */
71163611Sphk#define	IEEE80211_NODE_SAVEQ_INIT(_ni, _name) do {		\
72163611Sphk	mtx_init(&(_ni)->ni_savedq.ifq_mtx, _name, "802.11 ps queue", MTX_DEF);\
73163611Sphk	(_ni)->ni_savedq.ifq_maxlen = IEEE80211_PS_MAX_QUEUE;	\
74163611Sphk} while (0)
75163611Sphk#define	IEEE80211_NODE_SAVEQ_DESTROY(_ni) \
76163611Sphk	mtx_destroy(&(_ni)->ni_savedq.ifq_mtx)
77163611Sphk#define	IEEE80211_NODE_SAVEQ_QLEN(_ni) \
78163611Sphk	_IF_QLEN(&(_ni)->ni_savedq)
79163611Sphk#define	IEEE80211_NODE_SAVEQ_LOCK(_ni) do {	\
80163611Sphk	IF_LOCK(&(_ni)->ni_savedq);				\
81163611Sphk} while (0)
82163611Sphk#define	IEEE80211_NODE_SAVEQ_UNLOCK(_ni) do {	\
83163611Sphk	IF_UNLOCK(&(_ni)->ni_savedq);				\
84163611Sphk} while (0)
85163611Sphk#define	IEEE80211_NODE_SAVEQ_DEQUEUE(_ni, _m, _qlen) do {	\
86163611Sphk	IEEE80211_NODE_SAVEQ_LOCK(_ni);				\
87163611Sphk	_IF_DEQUEUE(&(_ni)->ni_savedq, _m);			\
88163611Sphk	(_qlen) = IEEE80211_NODE_SAVEQ_QLEN(_ni);		\
89163611Sphk	IEEE80211_NODE_SAVEQ_UNLOCK(_ni);			\
90163611Sphk} while (0)
91163611Sphk#define	IEEE80211_NODE_SAVEQ_DRAIN(_ni, _qlen) do {		\
92163611Sphk	IEEE80211_NODE_SAVEQ_LOCK(_ni);				\
93163611Sphk	(_qlen) = IEEE80211_NODE_SAVEQ_QLEN(_ni);		\
94163611Sphk	_IF_DRAIN(&(_ni)->ni_savedq);				\
95163611Sphk	IEEE80211_NODE_SAVEQ_UNLOCK(_ni);			\
96163611Sphk} while (0)
97163611Sphk/* XXX could be optimized */
98163611Sphk#define	_IEEE80211_NODE_SAVEQ_DEQUEUE_HEAD(_ni, _m) do {	\
99163611Sphk	_IF_DEQUEUE(&(_ni)->ni_savedq, m);			\
100163611Sphk} while (0)
101163611Sphk#define	_IEEE80211_NODE_SAVEQ_ENQUEUE(_ni, _m, _qlen, _age) do {\
102163611Sphk	(_m)->m_nextpkt = NULL;					\
103163611Sphk	if ((_ni)->ni_savedq.ifq_tail != NULL) { 		\
104163611Sphk		_age -= M_AGE_GET((_ni)->ni_savedq.ifq_tail);	\
105163611Sphk		(_ni)->ni_savedq.ifq_tail->m_nextpkt = (_m);	\
106163611Sphk	} else { 						\
107163611Sphk		(_ni)->ni_savedq.ifq_head = (_m); 		\
108163611Sphk	}							\
109163611Sphk	M_AGE_SET(_m, _age);					\
110163611Sphk	(_ni)->ni_savedq.ifq_tail = (_m); 			\
111163611Sphk	(_qlen) = ++(_ni)->ni_savedq.ifq_len; 			\
112163611Sphk} while (0)
113163611Sphk
114163611Sphk/*
115163611Sphk * 802.1x MAC ACL database locking definitions.
116163611Sphk */
117163611Sphktypedef struct mtx acl_lock_t;
118163611Sphk#define	ACL_LOCK_INIT(_as, _name) \
119163611Sphk	mtx_init(&(_as)->as_lock, _name, "802.11 ACL", MTX_DEF)
120163611Sphk#define	ACL_LOCK_DESTROY(_as)		mtx_destroy(&(_as)->as_lock)
121163611Sphk#define	ACL_LOCK(_as)			mtx_lock(&(_as)->as_lock)
122163611Sphk#define	ACL_UNLOCK(_as)			mtx_unlock(&(_as)->as_lock)
123163611Sphk#define	ACL_LOCK_ASSERT(_as) \
124163611Sphk	mtx_assert((&(_as)->as_lock), MA_OWNED)
125163611Sphk
126163611Sphk/*
127163611Sphk * Node reference counting definitions.
128163611Sphk *
129163611Sphk * ieee80211_node_initref	initialize the reference count to 1
130163611Sphk * ieee80211_node_incref	add a reference
131163611Sphk * ieee80211_node_decref	remove a reference
132163611Sphk * ieee80211_node_dectestref	remove a reference and return 1 if this
133163611Sphk *				is the last reference, otherwise 0
134163611Sphk * ieee80211_node_refcnt	reference count for printing (only)
135163611Sphk */
136163611Sphk#include <machine/atomic.h>
137163611Sphk
138331503Sian#define ieee80211_node_initref(_ni) \
139331503Sian	do { ((_ni)->ni_refcnt = 1); } while (0)
140163611Sphk#define ieee80211_node_incref(_ni) \
141163611Sphk	atomic_add_int(&(_ni)->ni_refcnt, 1)
142163611Sphk#define	ieee80211_node_decref(_ni) \
143163611Sphk	atomic_subtract_int(&(_ni)->ni_refcnt, 1)
144163611Sphkstruct ieee80211_node;
145163646Sphkextern	int ieee80211_node_dectestref(struct ieee80211_node *ni);
146163646Sphk#define	ieee80211_node_refcnt(_ni)	(_ni)->ni_refcnt
147163611Sphk
148163611Sphkextern	struct mbuf *ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen);
149163611Sphk#define	M_LINK0		M_PROTO1		/* WEP requested */
150163611Sphk#define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */
151163611Sphk/*
152163611Sphk * Encode WME access control bits in the PROTO flags.
153163611Sphk * This is safe since it's passed directly in to the
154163611Sphk * driver and there's no chance someone else will clobber
155163611Sphk * them on us.
156163611Sphk */
157163611Sphk#define	M_WME_AC_MASK	(M_PROTO2|M_PROTO3)
158163611Sphk/* XXX 5 is wrong if M_PROTO* are redefined */
159163611Sphk#define	M_WME_AC_SHIFT	5
160163611Sphk
161163611Sphk#define	M_WME_SETAC(m, ac) \
162163611Sphk	((m)->m_flags = ((m)->m_flags &~ M_WME_AC_MASK) | \
163163611Sphk		((ac) << M_WME_AC_SHIFT))
164163611Sphk#define	M_WME_GETAC(m)	(((m)->m_flags >> M_WME_AC_SHIFT) & 0x3)
165163611Sphk
166163611Sphk/*
167163611Sphk * Mbufs on the power save queue are tagged with an age and
168163611Sphk * timed out.  We reuse the hardware checksum field in the
169163611Sphk * mbuf packet header to store this data.
170163611Sphk */
171163611Sphk#define	M_AGE_SET(m,v)		(m->m_pkthdr.csum_data = v)
172163611Sphk#define	M_AGE_GET(m)		(m->m_pkthdr.csum_data)
173163611Sphk#define	M_AGE_SUB(m,adj)	(m->m_pkthdr.csum_data -= adj)
174163611Sphk
175163611Sphkextern	void get_random_bytes(void *, size_t);
176163611Sphk
177163611Sphkstruct ieee80211com;
178163611Sphk
179163611Sphkvoid	ieee80211_sysctl_attach(struct ieee80211com *);
180163611Sphkvoid	ieee80211_sysctl_detach(struct ieee80211com *);
181163611Sphk
182163611Sphkvoid	ieee80211_load_module(const char *);
183163611Sphk
184163611Sphk/* XXX this stuff belongs elsewhere */
185163611Sphk/*
186163611Sphk * Message formats for messages from the net80211 layer to user
187163611Sphk * applications via the routing socket.  These messages are appended
188163611Sphk * to an if_announcemsghdr structure.
189163611Sphk */
190163611Sphkstruct ieee80211_join_event {
191163611Sphk	uint8_t		iev_addr[6];
192163611Sphk};
193163611Sphk
194163611Sphkstruct ieee80211_leave_event {
195163611Sphk	uint8_t		iev_addr[6];
196163611Sphk};
197163611Sphk
198163611Sphkstruct ieee80211_replay_event {
199163611Sphk	uint8_t		iev_src[6];	/* src MAC */
200163611Sphk	uint8_t		iev_dst[6];	/* dst MAC */
201163611Sphk	uint8_t		iev_cipher;	/* cipher type */
202163611Sphk	uint8_t		iev_keyix;	/* key id/index */
203163611Sphk	uint64_t	iev_keyrsc;	/* RSC from key */
204163611Sphk	uint64_t	iev_rsc;	/* RSC from frame */
205163611Sphk};
206163611Sphk
207163611Sphkstruct ieee80211_michael_event {
208163611Sphk	uint8_t		iev_src[6];	/* src MAC */
209163611Sphk	uint8_t		iev_dst[6];	/* dst MAC */
210163611Sphk	uint8_t		iev_cipher;	/* cipher type */
211163611Sphk	uint8_t		iev_keyix;	/* key id/index */
212163611Sphk};
213163611Sphk
214163611Sphk#define	RTM_IEEE80211_ASSOC	100	/* station associate (bss mode) */
215163611Sphk#define	RTM_IEEE80211_REASSOC	101	/* station re-associate (bss mode) */
216163611Sphk#define	RTM_IEEE80211_DISASSOC	102	/* station disassociate (bss mode) */
217163611Sphk#define	RTM_IEEE80211_JOIN	103	/* station join (ap mode) */
218163611Sphk#define	RTM_IEEE80211_LEAVE	104	/* station leave (ap mode) */
219331503Sian#define	RTM_IEEE80211_SCAN	105	/* scan complete, results available */
220331503Sian#define	RTM_IEEE80211_REPLAY	106	/* sequence counter replay detected */
221163611Sphk#define	RTM_IEEE80211_MICHAEL	107	/* Michael MIC failure detected */
222163611Sphk#define	RTM_IEEE80211_REJOIN	108	/* station re-associate (ap mode) */
223163611Sphk
224163611Sphk#endif /* _NET80211_IEEE80211_FREEBSD_H_ */
225163611Sphk