ieee80211_freebsd.h revision 248069
1138568Ssam/*-
2178354Ssam * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting
3138568Ssam * All rights reserved.
4138568Ssam *
5138568Ssam * Redistribution and use in source and binary forms, with or without
6138568Ssam * modification, are permitted provided that the following conditions
7138568Ssam * are met:
8138568Ssam * 1. Redistributions of source code must retain the above copyright
9138568Ssam *    notice, this list of conditions and the following disclaimer.
10138568Ssam * 2. Redistributions in binary form must reproduce the above copyright
11138568Ssam *    notice, this list of conditions and the following disclaimer in the
12138568Ssam *    documentation and/or other materials provided with the distribution.
13138568Ssam *
14138568Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15138568Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16138568Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17138568Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18138568Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19138568Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20138568Ssam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21138568Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22138568Ssam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23138568Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24138568Ssam *
25138568Ssam * $FreeBSD: head/sys/net80211/ieee80211_freebsd.h 248069 2013-03-08 20:23:55Z adrian $
26138568Ssam */
27138568Ssam#ifndef _NET80211_IEEE80211_FREEBSD_H_
28138568Ssam#define _NET80211_IEEE80211_FREEBSD_H_
29138568Ssam
30165911Ssam#ifdef _KERNEL
31178354Ssam#include <sys/param.h>
32178354Ssam#include <sys/lock.h>
33178354Ssam#include <sys/mutex.h>
34178354Ssam#include <sys/rwlock.h>
35192473Ssam#include <sys/sysctl.h>
36191746Sthompsa#include <sys/taskqueue.h>
37178354Ssam
38138568Ssam/*
39170530Ssam * Common state locking definitions.
40170530Ssam */
41179388Ssamtypedef struct {
42179388Ssam	char		name[16];		/* e.g. "ath0_com_lock" */
43179388Ssam	struct mtx	mtx;
44179388Ssam} ieee80211_com_lock_t;
45179388Ssam#define	IEEE80211_LOCK_INIT(_ic, _name) do {				\
46179388Ssam	ieee80211_com_lock_t *cl = &(_ic)->ic_comlock;			\
47179388Ssam	snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name);	\
48179388Ssam	mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE);	\
49179388Ssam} while (0)
50179388Ssam#define	IEEE80211_LOCK_OBJ(_ic)	(&(_ic)->ic_comlock.mtx)
51179388Ssam#define	IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic))
52179388Ssam#define	IEEE80211_LOCK(_ic)	   mtx_lock(IEEE80211_LOCK_OBJ(_ic))
53179388Ssam#define	IEEE80211_UNLOCK(_ic)	   mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
54170530Ssam#define	IEEE80211_LOCK_ASSERT(_ic) \
55179388Ssam	mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
56243532Sadrian#define	IEEE80211_UNLOCK_ASSERT(_ic) \
57243532Sadrian	mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_NOTOWNED)
58170530Ssam
59170530Ssam/*
60248069Sadrian * Transmit lock.
61248069Sadrian *
62248069Sadrian * This is a (mostly) temporary lock designed to serialise all of the
63248069Sadrian * transmission operations throughout the stack.
64248069Sadrian */
65248069Sadriantypedef struct {
66248069Sadrian	char		name[16];		/* e.g. "ath0_com_lock" */
67248069Sadrian	struct mtx	mtx;
68248069Sadrian} ieee80211_tx_lock_t;
69248069Sadrian#define	IEEE80211_TX_LOCK_INIT(_ic, _name) do {				\
70248069Sadrian	ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock;			\
71248069Sadrian	snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name);	\
72248069Sadrian	mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF);	\
73248069Sadrian} while (0)
74248069Sadrian#define	IEEE80211_TX_LOCK_OBJ(_ic)	(&(_ic)->ic_txlock.mtx)
75248069Sadrian#define	IEEE80211_TX_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic))
76248069Sadrian#define	IEEE80211_TX_LOCK(_ic)	   mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic))
77248069Sadrian#define	IEEE80211_TX_UNLOCK(_ic)	   mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic))
78248069Sadrian#define	IEEE80211_TX_LOCK_ASSERT(_ic) \
79248069Sadrian	mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED)
80248069Sadrian#define	IEEE80211_TX_UNLOCK_ASSERT(_ic) \
81248069Sadrian	mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED)
82248069Sadrian
83248069Sadrian/*
84138568Ssam * Node locking definitions.
85138568Ssam */
86178354Ssamtypedef struct {
87178354Ssam	char		name[16];		/* e.g. "ath0_node_lock" */
88178354Ssam	struct mtx	mtx;
89178354Ssam} ieee80211_node_lock_t;
90178354Ssam#define	IEEE80211_NODE_LOCK_INIT(_nt, _name) do {			\
91178354Ssam	ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock;		\
92178354Ssam	snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name);	\
93179388Ssam	mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE);	\
94178354Ssam} while (0)
95179388Ssam#define	IEEE80211_NODE_LOCK_OBJ(_nt)	(&(_nt)->nt_nodelock.mtx)
96178354Ssam#define	IEEE80211_NODE_LOCK_DESTROY(_nt) \
97179388Ssam	mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt))
98178354Ssam#define	IEEE80211_NODE_LOCK(_nt) \
99179388Ssam	mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt))
100178354Ssam#define	IEEE80211_NODE_IS_LOCKED(_nt) \
101179388Ssam	mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt))
102178354Ssam#define	IEEE80211_NODE_UNLOCK(_nt) \
103179388Ssam	mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt))
104178354Ssam#define	IEEE80211_NODE_LOCK_ASSERT(_nt)	\
105179388Ssam	mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED)
106138568Ssam
107138568Ssam/*
108178354Ssam * Node table iteration locking definitions; this protects the
109178354Ssam * scan generation # used to iterate over the station table
110178354Ssam * while grabbing+releasing the node lock.
111138568Ssam */
112178354Ssamtypedef struct {
113178354Ssam	char		name[16];		/* e.g. "ath0_scan_lock" */
114178354Ssam	struct mtx	mtx;
115178354Ssam} ieee80211_scan_lock_t;
116178354Ssam#define	IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do {		\
117178354Ssam	ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock;		\
118178354Ssam	snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name);	\
119179388Ssam	mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF);			\
120178354Ssam} while (0)
121179388Ssam#define	IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)	(&(_nt)->nt_scanlock.mtx)
122178354Ssam#define	IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \
123179388Ssam	mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
124178354Ssam#define	IEEE80211_NODE_ITERATE_LOCK(_nt) \
125179388Ssam	mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
126178354Ssam#define	IEEE80211_NODE_ITERATE_UNLOCK(_nt) \
127179388Ssam	mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
128138568Ssam
129138568Ssam/*
130184288Ssam * Power-save queue definitions.
131138568Ssam */
132184288Ssamtypedef struct mtx ieee80211_psq_lock_t;
133184288Ssam#define	IEEE80211_PSQ_INIT(_psq, _name) \
134195379Ssam	mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF)
135184288Ssam#define	IEEE80211_PSQ_DESTROY(_psq)	mtx_destroy(&(_psq)->psq_lock)
136184288Ssam#define	IEEE80211_PSQ_LOCK(_psq)	mtx_lock(&(_psq)->psq_lock)
137184288Ssam#define	IEEE80211_PSQ_UNLOCK(_psq)	mtx_unlock(&(_psq)->psq_lock)
138138568Ssam
139167284Ssam#ifndef IF_PREPEND_LIST
140167284Ssam#define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {	\
141167284Ssam	(mtail)->m_nextpkt = (ifq)->ifq_head;			\
142167284Ssam	if ((ifq)->ifq_tail == NULL)				\
143167284Ssam		(ifq)->ifq_tail = (mtail);			\
144167284Ssam	(ifq)->ifq_head = (mhead);				\
145167284Ssam	(ifq)->ifq_len += (mcount);				\
146167284Ssam} while (0)
147167284Ssam#define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {		\
148167284Ssam	IF_LOCK(ifq);						\
149167284Ssam	_IF_PREPEND_LIST(ifq, mhead, mtail, mcount);		\
150167284Ssam	IF_UNLOCK(ifq);						\
151167284Ssam} while (0)
152167284Ssam#endif /* IF_PREPEND_LIST */
153195379Ssam
154195379Ssam/*
155195379Ssam * Age queue definitions.
156195379Ssam */
157195379Ssamtypedef struct mtx ieee80211_ageq_lock_t;
158195379Ssam#define	IEEE80211_AGEQ_INIT(_aq, _name) \
159195379Ssam	mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF)
160195379Ssam#define	IEEE80211_AGEQ_DESTROY(_aq)	mtx_destroy(&(_aq)->aq_lock)
161195379Ssam#define	IEEE80211_AGEQ_LOCK(_aq)	mtx_lock(&(_aq)->aq_lock)
162195379Ssam#define	IEEE80211_AGEQ_UNLOCK(_aq)	mtx_unlock(&(_aq)->aq_lock)
163167284Ssam
164138568Ssam/*
165138568Ssam * 802.1x MAC ACL database locking definitions.
166138568Ssam */
167138568Ssamtypedef struct mtx acl_lock_t;
168138568Ssam#define	ACL_LOCK_INIT(_as, _name) \
169138568Ssam	mtx_init(&(_as)->as_lock, _name, "802.11 ACL", MTX_DEF)
170138568Ssam#define	ACL_LOCK_DESTROY(_as)		mtx_destroy(&(_as)->as_lock)
171138568Ssam#define	ACL_LOCK(_as)			mtx_lock(&(_as)->as_lock)
172138568Ssam#define	ACL_UNLOCK(_as)			mtx_unlock(&(_as)->as_lock)
173138568Ssam#define	ACL_LOCK_ASSERT(_as) \
174138568Ssam	mtx_assert((&(_as)->as_lock), MA_OWNED)
175138568Ssam
176138568Ssam/*
177206617Srpaulo * Scan table definitions.
178206617Srpaulo */
179206617Srpaulotypedef struct mtx ieee80211_scan_table_lock_t;
180206617Srpaulo#define	IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
181206617Srpaulo	mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF)
182206617Srpaulo#define	IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st)	mtx_destroy(&(_st)->st_lock)
183206617Srpaulo#define	IEEE80211_SCAN_TABLE_LOCK(_st)		mtx_lock(&(_st)->st_lock)
184206617Srpaulo#define	IEEE80211_SCAN_TABLE_UNLOCK(_st)	mtx_unlock(&(_st)->st_lock)
185206617Srpaulo
186206617Srpaulo/*
187138568Ssam * Node reference counting definitions.
188138568Ssam *
189138568Ssam * ieee80211_node_initref	initialize the reference count to 1
190138568Ssam * ieee80211_node_incref	add a reference
191138568Ssam * ieee80211_node_decref	remove a reference
192138568Ssam * ieee80211_node_dectestref	remove a reference and return 1 if this
193138568Ssam *				is the last reference, otherwise 0
194138568Ssam * ieee80211_node_refcnt	reference count for printing (only)
195138568Ssam */
196138568Ssam#include <machine/atomic.h>
197138568Ssam
198138568Ssam#define ieee80211_node_initref(_ni) \
199138568Ssam	do { ((_ni)->ni_refcnt = 1); } while (0)
200138568Ssam#define ieee80211_node_incref(_ni) \
201138568Ssam	atomic_add_int(&(_ni)->ni_refcnt, 1)
202138568Ssam#define	ieee80211_node_decref(_ni) \
203138568Ssam	atomic_subtract_int(&(_ni)->ni_refcnt, 1)
204138568Ssamstruct ieee80211_node;
205144618Ssamint	ieee80211_node_dectestref(struct ieee80211_node *ni);
206138568Ssam#define	ieee80211_node_refcnt(_ni)	(_ni)->ni_refcnt
207138568Ssam
208165904Ssamstruct ifqueue;
209178354Ssamstruct ieee80211vap;
210165894Ssamvoid	ieee80211_drain_ifq(struct ifqueue *);
211178354Ssamvoid	ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
212165894Ssam
213178354Ssamvoid	ieee80211_vap_destroy(struct ieee80211vap *);
214178354Ssam
215178354Ssam#define	IFNET_IS_UP_RUNNING(_ifp) \
216178354Ssam	(((_ifp)->if_flags & IFF_UP) && \
217178354Ssam	 ((_ifp)->if_drv_flags & IFF_DRV_RUNNING))
218178354Ssam
219171022Ssam#define	msecs_to_ticks(ms)	(((ms)*hz)/1000)
220178354Ssam#define	ticks_to_msecs(t)	(1000*(t) / hz)
221178354Ssam#define	ticks_to_secs(t)	((t) / hz)
222170530Ssam#define time_after(a,b) 	((long)(b) - (long)(a) < 0)
223170530Ssam#define time_before(a,b)	time_after(b,a)
224170530Ssam#define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
225170530Ssam#define time_before_eq(a,b)	time_after_eq(b,a)
226170530Ssam
227170530Ssamstruct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
228172054Ssam
229170530Ssam/* tx path usage */
230184286Ssam#define	M_ENCAP		M_PROTO1		/* 802.11 encap done */
231178354Ssam#define	M_EAPOL		M_PROTO3		/* PAE/EAPOL frame */
232138568Ssam#define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */
233147789Ssam#define	M_MORE_DATA	M_PROTO5		/* more data frames to follow */
234178354Ssam#define	M_FF		M_PROTO6		/* fast frame */
235178354Ssam#define	M_TXCB		M_PROTO7		/* do tx complete callback */
236183247Ssam#define	M_AMPDU_MPDU	M_PROTO8		/* ok for A-MPDU aggregation */
237178354Ssam#define	M_80211_TX \
238190672Ssam	(M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\
239188554Ssam	 M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU)
240172054Ssam
241170530Ssam/* rx path usage */
242183247Ssam#define	M_AMPDU		M_PROTO1		/* A-MPDU subframe */
243172054Ssam#define	M_WEP		M_PROTO2		/* WEP done by hardware */
244183247Ssam#if 0
245183247Ssam#define	M_AMPDU_MPDU	M_PROTO8		/* A-MPDU re-order done */
246183247Ssam#endif
247183247Ssam#define	M_80211_RX	(M_AMPDU|M_WEP|M_AMPDU_MPDU)
248195618Srpaulo
249195618Srpaulo#define	IEEE80211_MBUF_TX_FLAG_BITS \
250195618Srpaulo	"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_ENCAP\6M_WEP\7M_EAPOL" \
251195618Srpaulo	"\10M_PWR_SAV\11M_MORE_DATA\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG" \
252195618Srpaulo	"\16M_LASTFRAG\17M_SKIP_FIREWALL\20M_FREELIST\21M_VLANTAG\22M_PROMISC" \
253195618Srpaulo	"\23M_NOFREE\24M_FF\25M_TXCB\26M_AMPDU_MPDU\27M_FLOWID"
254195618Srpaulo
255195618Srpaulo#define	IEEE80211_MBUF_RX_FLAG_BITS \
256195618Srpaulo	"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_AMPDU\6M_WEP\7M_PROTO3" \
257195618Srpaulo	"\10M_PROTO4\11M_PROTO5\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG" \
258195618Srpaulo	"\16M_LASTFRAG\17M_SKIP_FIREWALL\20M_FREELIST\21M_VLANTAG\22M_PROMISC" \
259195618Srpaulo	"\23M_NOFREE\24M_PROTO6\25M_PROTO7\26M_AMPDU_MPDU\27M_FLOWID"
260195618Srpaulo
261138568Ssam/*
262178354Ssam * Store WME access control bits in the vlan tag.
263178354Ssam * This is safe since it's done after the packet is classified
264178354Ssam * (where we use any previous tag) and because it's passed
265178354Ssam * directly in to the driver and there's no chance someone
266178354Ssam * else will clobber them on us.
267138568Ssam */
268138568Ssam#define	M_WME_SETAC(m, ac) \
269178354Ssam	((m)->m_pkthdr.ether_vtag = (ac))
270178354Ssam#define	M_WME_GETAC(m)	((m)->m_pkthdr.ether_vtag)
271138568Ssam
272138568Ssam/*
273138568Ssam * Mbufs on the power save queue are tagged with an age and
274138568Ssam * timed out.  We reuse the hardware checksum field in the
275138568Ssam * mbuf packet header to store this data.
276138568Ssam */
277138568Ssam#define	M_AGE_SET(m,v)		(m->m_pkthdr.csum_data = v)
278138568Ssam#define	M_AGE_GET(m)		(m->m_pkthdr.csum_data)
279138568Ssam#define	M_AGE_SUB(m,adj)	(m->m_pkthdr.csum_data -= adj)
280138568Ssam
281191571Ssam/*
282191571Ssam * Store the sequence number.
283191571Ssam */
284191571Ssam#define	M_SEQNO_SET(m, seqno) \
285191571Ssam	((m)->m_pkthdr.tso_segsz = (seqno))
286191571Ssam#define	M_SEQNO_GET(m)	((m)->m_pkthdr.tso_segsz)
287191571Ssam
288170530Ssam#define	MTAG_ABI_NET80211	1132948340	/* net80211 ABI */
289170530Ssam
290170530Ssamstruct ieee80211_cb {
291170530Ssam	void	(*func)(struct ieee80211_node *, void *, int status);
292170530Ssam	void	*arg;
293170530Ssam};
294170530Ssam#define	NET80211_TAG_CALLBACK	0	/* xmit complete callback */
295170530Ssamint	ieee80211_add_callback(struct mbuf *m,
296170530Ssam		void (*func)(struct ieee80211_node *, void *, int), void *arg);
297170530Ssamvoid	ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
298170530Ssam
299248069Sadrianstruct ieee80211com;
300248069Sadrianint	ieee80211_parent_transmit(struct ieee80211com *, struct mbuf *);
301248069Sadrianint	ieee80211_vap_transmit(struct ieee80211vap *, struct mbuf *);
302248069Sadrian
303144618Ssamvoid	get_random_bytes(void *, size_t);
304138568Ssam
305138568Ssamvoid	ieee80211_sysctl_attach(struct ieee80211com *);
306138568Ssamvoid	ieee80211_sysctl_detach(struct ieee80211com *);
307178354Ssamvoid	ieee80211_sysctl_vattach(struct ieee80211vap *);
308178354Ssamvoid	ieee80211_sysctl_vdetach(struct ieee80211vap *);
309138568Ssam
310192473SsamSYSCTL_DECL(_net_wlan);
311192473Ssamint	ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS);
312192473Ssam
313138568Ssamvoid	ieee80211_load_module(const char *);
314170530Ssam
315178354Ssam/*
316178354Ssam * A "policy module" is an adjunct module to net80211 that provides
317178354Ssam * functionality that typically includes policy decisions.  This
318178354Ssam * modularity enables extensibility and vendor-supplied functionality.
319178354Ssam */
320178354Ssam#define	_IEEE80211_POLICY_MODULE(policy, name, version)			\
321178354Ssamtypedef void (*policy##_setup)(int);					\
322178354SsamSET_DECLARE(policy##_set, policy##_setup);				\
323170530Ssamstatic int								\
324178354Ssamwlan_##name##_modevent(module_t mod, int type, void *unused)		\
325170530Ssam{									\
326178354Ssam	policy##_setup * const *iter, f;				\
327170530Ssam	switch (type) {							\
328170530Ssam	case MOD_LOAD:							\
329178354Ssam		SET_FOREACH(iter, policy##_set) {			\
330178354Ssam			f = (void*) *iter;				\
331178354Ssam			f(type);					\
332178354Ssam		}							\
333170530Ssam		return 0;						\
334170530Ssam	case MOD_UNLOAD:						\
335170530Ssam	case MOD_QUIESCE:						\
336170530Ssam		if (nrefs) {						\
337170530Ssam			printf("wlan_##name: still in use (%u dynamic refs)\n",\
338170530Ssam				nrefs);					\
339170530Ssam			return EBUSY;					\
340170530Ssam		}							\
341178354Ssam		if (type == MOD_UNLOAD) {				\
342178354Ssam			SET_FOREACH(iter, policy##_set) {		\
343178354Ssam				f = (void*) *iter;			\
344178354Ssam				f(type);				\
345178354Ssam			}						\
346178354Ssam		}							\
347170530Ssam		return 0;						\
348170530Ssam	}								\
349170530Ssam	return EINVAL;							\
350170530Ssam}									\
351170530Ssamstatic moduledata_t name##_mod = {					\
352170530Ssam	"wlan_" #name,							\
353178354Ssam	wlan_##name##_modevent,						\
354241394Skevlo	0								\
355170530Ssam};									\
356170530SsamDECLARE_MODULE(wlan_##name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
357170530SsamMODULE_VERSION(wlan_##name, version);					\
358170530SsamMODULE_DEPEND(wlan_##name, wlan, 1, 1, 1)
359178354Ssam
360178354Ssam/*
361178354Ssam * Crypto modules implement cipher support.
362178354Ssam */
363178354Ssam#define	IEEE80211_CRYPTO_MODULE(name, version)				\
364178354Ssam_IEEE80211_POLICY_MODULE(crypto, name, version);			\
365178354Ssamstatic void								\
366178354Ssamname##_modevent(int type)						\
367178354Ssam{									\
368178354Ssam	if (type == MOD_LOAD)						\
369178354Ssam		ieee80211_crypto_register(&name);			\
370178354Ssam	else								\
371178354Ssam		ieee80211_crypto_unregister(&name);			\
372178354Ssam}									\
373178354SsamTEXT_SET(crypto##_set, name##_modevent)
374178354Ssam
375178354Ssam/*
376178354Ssam * Scanner modules provide scanning policy.
377178354Ssam */
378178354Ssam#define	IEEE80211_SCANNER_MODULE(name, version)				\
379178354Ssam	_IEEE80211_POLICY_MODULE(scanner, name, version)
380178354Ssam
381178354Ssam#define	IEEE80211_SCANNER_ALG(name, alg, v)				\
382178354Ssamstatic void								\
383178354Ssamname##_modevent(int type)						\
384178354Ssam{									\
385178354Ssam	if (type == MOD_LOAD)						\
386178354Ssam		ieee80211_scanner_register(alg, &v);			\
387178354Ssam	else								\
388178354Ssam		ieee80211_scanner_unregister(alg, &v);			\
389178354Ssam}									\
390178354SsamTEXT_SET(scanner_set, name##_modevent);					\
391178354Ssam
392178354Ssam/*
393178354Ssam * ACL modules implement acl policy.
394178354Ssam */
395178354Ssam#define	IEEE80211_ACL_MODULE(name, alg, version)			\
396178354Ssam_IEEE80211_POLICY_MODULE(acl, name, version);				\
397178354Ssamstatic void								\
398178354Ssamalg##_modevent(int type)						\
399178354Ssam{									\
400178354Ssam	if (type == MOD_LOAD)						\
401178354Ssam		ieee80211_aclator_register(&alg);			\
402178354Ssam	else								\
403178354Ssam		ieee80211_aclator_unregister(&alg);			\
404178354Ssam}									\
405178354SsamTEXT_SET(acl_set, alg##_modevent);					\
406178354Ssam
407178354Ssam/*
408178354Ssam * Authenticator modules handle 802.1x/WPA authentication.
409178354Ssam */
410178354Ssam#define	IEEE80211_AUTH_MODULE(name, version)				\
411178354Ssam	_IEEE80211_POLICY_MODULE(auth, name, version)
412178354Ssam
413178354Ssam#define	IEEE80211_AUTH_ALG(name, alg, v)				\
414178354Ssamstatic void								\
415178354Ssamname##_modevent(int type)						\
416178354Ssam{									\
417178354Ssam	if (type == MOD_LOAD)						\
418178354Ssam		ieee80211_authenticator_register(alg, &v);		\
419178354Ssam	else								\
420178354Ssam		ieee80211_authenticator_unregister(alg);		\
421178354Ssam}									\
422178354SsamTEXT_SET(auth_set, name##_modevent)
423178354Ssam
424178354Ssam/*
425178354Ssam * Rate control modules provide tx rate control support.
426178354Ssam */
427206358Srpaulo#define	IEEE80211_RATECTL_MODULE(alg, version)				\
428206358Srpaulo	_IEEE80211_POLICY_MODULE(ratectl, alg, version);		\
429206358Srpaulo
430206358Srpaulo#define	IEEE80211_RATECTL_ALG(name, alg, v)				\
431178354Ssamstatic void								\
432178354Ssamalg##_modevent(int type)						\
433178354Ssam{									\
434206358Srpaulo	if (type == MOD_LOAD)						\
435206358Srpaulo		ieee80211_ratectl_register(alg, &v);			\
436206358Srpaulo	else								\
437206358Srpaulo		ieee80211_ratectl_unregister(alg);			\
438178354Ssam}									\
439206358SrpauloTEXT_SET(ratectl##_set, alg##_modevent)
440138568Ssam
441190384Ssamstruct ieee80211req;
442190384Ssamtypedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
443190384Ssam    struct ieee80211req *);
444190384SsamSET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc);
445190384Ssam#define	IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get)
446190384Ssam
447190384Ssamtypedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
448190384Ssam    struct ieee80211req *);
449190384SsamSET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
450190384Ssam#define	IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set)
451190394Ssam#endif /* _KERNEL */
452190384Ssam
453138568Ssam/* XXX this stuff belongs elsewhere */
454138568Ssam/*
455138568Ssam * Message formats for messages from the net80211 layer to user
456138568Ssam * applications via the routing socket.  These messages are appended
457138568Ssam * to an if_announcemsghdr structure.
458138568Ssam */
459138568Ssamstruct ieee80211_join_event {
460138568Ssam	uint8_t		iev_addr[6];
461138568Ssam};
462138568Ssam
463138568Ssamstruct ieee80211_leave_event {
464138568Ssam	uint8_t		iev_addr[6];
465138568Ssam};
466138568Ssam
467138568Ssamstruct ieee80211_replay_event {
468138568Ssam	uint8_t		iev_src[6];	/* src MAC */
469138568Ssam	uint8_t		iev_dst[6];	/* dst MAC */
470138568Ssam	uint8_t		iev_cipher;	/* cipher type */
471138568Ssam	uint8_t		iev_keyix;	/* key id/index */
472138568Ssam	uint64_t	iev_keyrsc;	/* RSC from key */
473138568Ssam	uint64_t	iev_rsc;	/* RSC from frame */
474138568Ssam};
475138568Ssam
476138568Ssamstruct ieee80211_michael_event {
477138568Ssam	uint8_t		iev_src[6];	/* src MAC */
478138568Ssam	uint8_t		iev_dst[6];	/* dst MAC */
479138568Ssam	uint8_t		iev_cipher;	/* cipher type */
480138568Ssam	uint8_t		iev_keyix;	/* key id/index */
481138568Ssam};
482138568Ssam
483178354Ssamstruct ieee80211_wds_event {
484178354Ssam	uint8_t		iev_addr[6];
485178354Ssam};
486178354Ssam
487178354Ssamstruct ieee80211_csa_event {
488178354Ssam	uint32_t	iev_flags;	/* channel flags */
489178354Ssam	uint16_t	iev_freq;	/* setting in Mhz */
490178354Ssam	uint8_t		iev_ieee;	/* IEEE channel number */
491178354Ssam	uint8_t		iev_mode;	/* CSA mode */
492178354Ssam	uint8_t		iev_count;	/* CSA count */
493178354Ssam};
494178354Ssam
495178354Ssamstruct ieee80211_cac_event {
496178354Ssam	uint32_t	iev_flags;	/* channel flags */
497178354Ssam	uint16_t	iev_freq;	/* setting in Mhz */
498178354Ssam	uint8_t		iev_ieee;	/* IEEE channel number */
499178354Ssam	/* XXX timestamp? */
500178354Ssam	uint8_t		iev_type;	/* IEEE80211_NOTIFY_CAC_* */
501178354Ssam};
502178354Ssam
503178354Ssamstruct ieee80211_radar_event {
504178354Ssam	uint32_t	iev_flags;	/* channel flags */
505178354Ssam	uint16_t	iev_freq;	/* setting in Mhz */
506178354Ssam	uint8_t		iev_ieee;	/* IEEE channel number */
507178354Ssam	/* XXX timestamp? */
508178354Ssam};
509178354Ssam
510178354Ssamstruct ieee80211_auth_event {
511178354Ssam	uint8_t		iev_addr[6];
512178354Ssam};
513178354Ssam
514178354Ssamstruct ieee80211_deauth_event {
515178354Ssam	uint8_t		iev_addr[6];
516178354Ssam};
517178354Ssam
518178354Ssamstruct ieee80211_country_event {
519178354Ssam	uint8_t		iev_addr[6];
520178354Ssam	uint8_t		iev_cc[2];	/* ISO country code */
521178354Ssam};
522178354Ssam
523178354Ssamstruct ieee80211_radio_event {
524178354Ssam	uint8_t		iev_state;	/* 1 on, 0 off */
525178354Ssam};
526178354Ssam
527138568Ssam#define	RTM_IEEE80211_ASSOC	100	/* station associate (bss mode) */
528138568Ssam#define	RTM_IEEE80211_REASSOC	101	/* station re-associate (bss mode) */
529138568Ssam#define	RTM_IEEE80211_DISASSOC	102	/* station disassociate (bss mode) */
530138568Ssam#define	RTM_IEEE80211_JOIN	103	/* station join (ap mode) */
531138568Ssam#define	RTM_IEEE80211_LEAVE	104	/* station leave (ap mode) */
532138568Ssam#define	RTM_IEEE80211_SCAN	105	/* scan complete, results available */
533138568Ssam#define	RTM_IEEE80211_REPLAY	106	/* sequence counter replay detected */
534138568Ssam#define	RTM_IEEE80211_MICHAEL	107	/* Michael MIC failure detected */
535144302Ssam#define	RTM_IEEE80211_REJOIN	108	/* station re-associate (ap mode) */
536178354Ssam#define	RTM_IEEE80211_WDS	109	/* WDS discovery (ap mode) */
537178354Ssam#define	RTM_IEEE80211_CSA	110	/* Channel Switch Announcement event */
538178354Ssam#define	RTM_IEEE80211_RADAR	111	/* radar event */
539178354Ssam#define	RTM_IEEE80211_CAC	112	/* Channel Availability Check event */
540178354Ssam#define	RTM_IEEE80211_DEAUTH	113	/* station deauthenticate */
541178354Ssam#define	RTM_IEEE80211_AUTH	114	/* station authenticate (ap mode) */
542178354Ssam#define	RTM_IEEE80211_COUNTRY	115	/* discovered country code (sta mode) */
543178354Ssam#define	RTM_IEEE80211_RADIO	116	/* RF kill switch state change */
544138568Ssam
545160690Ssam/*
546160690Ssam * Structure prepended to raw packets sent through the bpf
547160690Ssam * interface when set to DLT_IEEE802_11_RADIO.  This allows
548160690Ssam * user applications to specify pretty much everything in
549160690Ssam * an Atheros tx descriptor.  XXX need to generalize.
550160690Ssam *
551160690Ssam * XXX cannot be more than 14 bytes as it is copied to a sockaddr's
552160690Ssam * XXX sa_data area.
553160690Ssam */
554160690Ssamstruct ieee80211_bpf_params {
555160690Ssam	uint8_t		ibp_vers;	/* version */
556160690Ssam#define	IEEE80211_BPF_VERSION	0
557160690Ssam	uint8_t		ibp_len;	/* header length in bytes */
558160690Ssam	uint8_t		ibp_flags;
559160690Ssam#define	IEEE80211_BPF_SHORTPRE	0x01	/* tx with short preamble */
560160690Ssam#define	IEEE80211_BPF_NOACK	0x02	/* tx with no ack */
561160690Ssam#define	IEEE80211_BPF_CRYPTO	0x04	/* tx with h/w encryption */
562160690Ssam#define	IEEE80211_BPF_FCS	0x10	/* frame incldues FCS */
563160690Ssam#define	IEEE80211_BPF_DATAPAD	0x20	/* frame includes data padding */
564160690Ssam#define	IEEE80211_BPF_RTS	0x40	/* tx with RTS/CTS */
565160690Ssam#define	IEEE80211_BPF_CTS	0x80	/* tx with CTS only */
566160690Ssam	uint8_t		ibp_pri;	/* WME/WMM AC+tx antenna */
567160690Ssam	uint8_t		ibp_try0;	/* series 1 try count */
568160690Ssam	uint8_t		ibp_rate0;	/* series 1 IEEE tx rate */
569160690Ssam	uint8_t		ibp_power;	/* tx power (device units) */
570160690Ssam	uint8_t		ibp_ctsrate;	/* IEEE tx rate for CTS */
571160690Ssam	uint8_t		ibp_try1;	/* series 2 try count */
572160690Ssam	uint8_t		ibp_rate1;	/* series 2 IEEE tx rate */
573160690Ssam	uint8_t		ibp_try2;	/* series 3 try count */
574160690Ssam	uint8_t		ibp_rate2;	/* series 3 IEEE tx rate */
575160690Ssam	uint8_t		ibp_try3;	/* series 4 try count */
576160690Ssam	uint8_t		ibp_rate3;	/* series 4 IEEE tx rate */
577160690Ssam};
578138568Ssam#endif /* _NET80211_IEEE80211_FREEBSD_H_ */
579