xref: /freebsd/sys/net80211/ieee80211_freebsd.h (revision 0861daf511dc9a573d71f5c3c1d0233745a8712b)
18a1b9b6aSSam Leffler /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni  *
4b032f27cSSam Leffler  * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting
58a1b9b6aSSam Leffler  * All rights reserved.
68a1b9b6aSSam Leffler  *
78a1b9b6aSSam Leffler  * Redistribution and use in source and binary forms, with or without
88a1b9b6aSSam Leffler  * modification, are permitted provided that the following conditions
98a1b9b6aSSam Leffler  * are met:
108a1b9b6aSSam Leffler  * 1. Redistributions of source code must retain the above copyright
118a1b9b6aSSam Leffler  *    notice, this list of conditions and the following disclaimer.
128a1b9b6aSSam Leffler  * 2. Redistributions in binary form must reproduce the above copyright
138a1b9b6aSSam Leffler  *    notice, this list of conditions and the following disclaimer in the
148a1b9b6aSSam Leffler  *    documentation and/or other materials provided with the distribution.
158a1b9b6aSSam Leffler  *
168a1b9b6aSSam Leffler  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
178a1b9b6aSSam Leffler  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
188a1b9b6aSSam Leffler  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
198a1b9b6aSSam Leffler  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
208a1b9b6aSSam Leffler  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
218a1b9b6aSSam Leffler  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
228a1b9b6aSSam Leffler  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
238a1b9b6aSSam Leffler  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
248a1b9b6aSSam Leffler  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
258a1b9b6aSSam Leffler  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
268a1b9b6aSSam Leffler  */
278a1b9b6aSSam Leffler #ifndef _NET80211_IEEE80211_FREEBSD_H_
288a1b9b6aSSam Leffler #define _NET80211_IEEE80211_FREEBSD_H_
298a1b9b6aSSam Leffler 
305675beddSSam Leffler #ifdef _KERNEL
3188a75510SAndriy Voskoboinyk #include <sys/param.h>
326fe391f4SGleb Smirnoff #include <sys/systm.h>
336fe391f4SGleb Smirnoff #include <sys/counter.h>
34b032f27cSSam Leffler #include <sys/lock.h>
35b032f27cSSam Leffler #include <sys/mutex.h>
36b032f27cSSam Leffler #include <sys/rwlock.h>
37f6ac5011SSam Leffler #include <sys/sysctl.h>
385efea30fSAndrew Thompson #include <sys/taskqueue.h>
399df9e936SAndriy Voskoboinyk #include <sys/time.h>
40b032f27cSSam Leffler 
41479ab044SConrad Meyer #include <net/debugnet.h>
42479ab044SConrad Meyer 
438a1b9b6aSSam Leffler /*
4401e57940SBjoern A. Zeeb  * priv(9) NET80211 checks.
4501e57940SBjoern A. Zeeb  */
4601e57940SBjoern A. Zeeb struct ieee80211vap;
4701e57940SBjoern A. Zeeb int ieee80211_priv_check_vap_getkey(u_long, struct ieee80211vap *,
4801e57940SBjoern A. Zeeb     struct ifnet *);
4901e57940SBjoern A. Zeeb int ieee80211_priv_check_vap_manage(u_long, struct ieee80211vap *,
5001e57940SBjoern A. Zeeb     struct ifnet *);
5101e57940SBjoern A. Zeeb int ieee80211_priv_check_vap_setmac(u_long, struct ieee80211vap *,
5201e57940SBjoern A. Zeeb     struct ifnet *);
5301e57940SBjoern A. Zeeb int ieee80211_priv_check_create_vap(u_long, struct ieee80211vap *,
5401e57940SBjoern A. Zeeb     struct ifnet *);
5501e57940SBjoern A. Zeeb 
5601e57940SBjoern A. Zeeb /*
5768e8e04eSSam Leffler  * Common state locking definitions.
5868e8e04eSSam Leffler  */
59978359b3SSam Leffler typedef struct {
60978359b3SSam Leffler 	char		name[16];		/* e.g. "ath0_com_lock" */
61978359b3SSam Leffler 	struct mtx	mtx;
62978359b3SSam Leffler } ieee80211_com_lock_t;
63978359b3SSam Leffler #define	IEEE80211_LOCK_INIT(_ic, _name) do {				\
64978359b3SSam Leffler 	ieee80211_com_lock_t *cl = &(_ic)->ic_comlock;			\
65978359b3SSam Leffler 	snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name);	\
66978359b3SSam Leffler 	mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE);	\
67978359b3SSam Leffler } while (0)
68978359b3SSam Leffler #define	IEEE80211_LOCK_OBJ(_ic)	(&(_ic)->ic_comlock.mtx)
69978359b3SSam Leffler #define	IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic))
70978359b3SSam Leffler #define	IEEE80211_LOCK(_ic)	   mtx_lock(IEEE80211_LOCK_OBJ(_ic))
71978359b3SSam Leffler #define	IEEE80211_UNLOCK(_ic)	   mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
7268e8e04eSSam Leffler #define	IEEE80211_LOCK_ASSERT(_ic) \
73978359b3SSam Leffler 	mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
743845e367SAdrian Chadd #define	IEEE80211_UNLOCK_ASSERT(_ic) \
753845e367SAdrian Chadd 	mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_NOTOWNED)
76054c5ddfSBjoern A. Zeeb #define	IEEE80211_IS_LOCKED(_ic) \
77054c5ddfSBjoern A. Zeeb 	mtx_owned(IEEE80211_LOCK_OBJ(_ic))
7868e8e04eSSam Leffler 
7968e8e04eSSam Leffler /*
805cda6006SAdrian Chadd  * Transmit lock.
815cda6006SAdrian Chadd  *
825cda6006SAdrian Chadd  * This is a (mostly) temporary lock designed to serialise all of the
835cda6006SAdrian Chadd  * transmission operations throughout the stack.
845cda6006SAdrian Chadd  */
855cda6006SAdrian Chadd typedef struct {
86f10bbaa7SAndriy Voskoboinyk 	char		name[16];		/* e.g. "ath0_tx_lock" */
875cda6006SAdrian Chadd 	struct mtx	mtx;
885cda6006SAdrian Chadd } ieee80211_tx_lock_t;
895cda6006SAdrian Chadd #define	IEEE80211_TX_LOCK_INIT(_ic, _name) do {				\
905cda6006SAdrian Chadd 	ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock;			\
915cda6006SAdrian Chadd 	snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name);	\
925cda6006SAdrian Chadd 	mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF);	\
935cda6006SAdrian Chadd } while (0)
945cda6006SAdrian Chadd #define	IEEE80211_TX_LOCK_OBJ(_ic)	(&(_ic)->ic_txlock.mtx)
955cda6006SAdrian Chadd #define	IEEE80211_TX_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic))
965cda6006SAdrian Chadd #define	IEEE80211_TX_LOCK(_ic)	   mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic))
975cda6006SAdrian Chadd #define	IEEE80211_TX_UNLOCK(_ic)	   mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic))
985cda6006SAdrian Chadd #define	IEEE80211_TX_LOCK_ASSERT(_ic) \
995cda6006SAdrian Chadd 	mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED)
1005cda6006SAdrian Chadd #define	IEEE80211_TX_UNLOCK_ASSERT(_ic) \
1015cda6006SAdrian Chadd 	mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED)
1025cda6006SAdrian Chadd 
1035cda6006SAdrian Chadd /*
104cdc0cf21SAndriy Voskoboinyk  * Stageq / ni_tx_superg lock
105cdc0cf21SAndriy Voskoboinyk  */
106cdc0cf21SAndriy Voskoboinyk typedef struct {
107cdc0cf21SAndriy Voskoboinyk 	char		name[16];		/* e.g. "ath0_ff_lock" */
108cdc0cf21SAndriy Voskoboinyk 	struct mtx	mtx;
109cdc0cf21SAndriy Voskoboinyk } ieee80211_ff_lock_t;
110cdc0cf21SAndriy Voskoboinyk #define IEEE80211_FF_LOCK_INIT(_ic, _name) do {				\
111cdc0cf21SAndriy Voskoboinyk 	ieee80211_ff_lock_t *fl = &(_ic)->ic_fflock;			\
112cdc0cf21SAndriy Voskoboinyk 	snprintf(fl->name, sizeof(fl->name), "%s_ff_lock", _name);	\
113cdc0cf21SAndriy Voskoboinyk 	mtx_init(&fl->mtx, fl->name, NULL, MTX_DEF);			\
114cdc0cf21SAndriy Voskoboinyk } while (0)
115cdc0cf21SAndriy Voskoboinyk #define IEEE80211_FF_LOCK_OBJ(_ic)	(&(_ic)->ic_fflock.mtx)
116cdc0cf21SAndriy Voskoboinyk #define IEEE80211_FF_LOCK_DESTROY(_ic)	mtx_destroy(IEEE80211_FF_LOCK_OBJ(_ic))
117cdc0cf21SAndriy Voskoboinyk #define IEEE80211_FF_LOCK(_ic)		mtx_lock(IEEE80211_FF_LOCK_OBJ(_ic))
118cdc0cf21SAndriy Voskoboinyk #define IEEE80211_FF_UNLOCK(_ic)	mtx_unlock(IEEE80211_FF_LOCK_OBJ(_ic))
119cdc0cf21SAndriy Voskoboinyk #define IEEE80211_FF_LOCK_ASSERT(_ic) \
120cdc0cf21SAndriy Voskoboinyk 	mtx_assert(IEEE80211_FF_LOCK_OBJ(_ic), MA_OWNED)
121cdc0cf21SAndriy Voskoboinyk 
122cdc0cf21SAndriy Voskoboinyk /*
1238a1b9b6aSSam Leffler  * Node locking definitions.
1248a1b9b6aSSam Leffler  */
125b032f27cSSam Leffler typedef struct {
126b032f27cSSam Leffler 	char		name[16];		/* e.g. "ath0_node_lock" */
127b032f27cSSam Leffler 	struct mtx	mtx;
128b032f27cSSam Leffler } ieee80211_node_lock_t;
129b032f27cSSam Leffler #define	IEEE80211_NODE_LOCK_INIT(_nt, _name) do {			\
130b032f27cSSam Leffler 	ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock;		\
131b032f27cSSam Leffler 	snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name);	\
132978359b3SSam Leffler 	mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE);	\
133b032f27cSSam Leffler } while (0)
134978359b3SSam Leffler #define	IEEE80211_NODE_LOCK_OBJ(_nt)	(&(_nt)->nt_nodelock.mtx)
135b032f27cSSam Leffler #define	IEEE80211_NODE_LOCK_DESTROY(_nt) \
136978359b3SSam Leffler 	mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt))
137b032f27cSSam Leffler #define	IEEE80211_NODE_LOCK(_nt) \
138978359b3SSam Leffler 	mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt))
139b032f27cSSam Leffler #define	IEEE80211_NODE_IS_LOCKED(_nt) \
140978359b3SSam Leffler 	mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt))
141b032f27cSSam Leffler #define	IEEE80211_NODE_UNLOCK(_nt) \
142978359b3SSam Leffler 	mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt))
1438a1b9b6aSSam Leffler #define	IEEE80211_NODE_LOCK_ASSERT(_nt)	\
144978359b3SSam Leffler 	mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED)
1458a1b9b6aSSam Leffler 
1468a1b9b6aSSam Leffler /*
14763092fceSSam Leffler  * Power-save queue definitions.
1488a1b9b6aSSam Leffler  */
14963092fceSSam Leffler typedef struct mtx ieee80211_psq_lock_t;
15063092fceSSam Leffler #define	IEEE80211_PSQ_INIT(_psq, _name) \
1515b16c28cSSam Leffler 	mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF)
15263092fceSSam Leffler #define	IEEE80211_PSQ_DESTROY(_psq)	mtx_destroy(&(_psq)->psq_lock)
15363092fceSSam Leffler #define	IEEE80211_PSQ_LOCK(_psq)	mtx_lock(&(_psq)->psq_lock)
15463092fceSSam Leffler #define	IEEE80211_PSQ_UNLOCK(_psq)	mtx_unlock(&(_psq)->psq_lock)
1558a1b9b6aSSam Leffler 
1563c419c1bSSam Leffler #ifndef IF_PREPEND_LIST
1573c419c1bSSam Leffler #define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {	\
1583c419c1bSSam Leffler 	(mtail)->m_nextpkt = (ifq)->ifq_head;			\
1593c419c1bSSam Leffler 	if ((ifq)->ifq_tail == NULL)				\
1603c419c1bSSam Leffler 		(ifq)->ifq_tail = (mtail);			\
1613c419c1bSSam Leffler 	(ifq)->ifq_head = (mhead);				\
1623c419c1bSSam Leffler 	(ifq)->ifq_len += (mcount);				\
1633c419c1bSSam Leffler } while (0)
1643c419c1bSSam Leffler #define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {		\
1653c419c1bSSam Leffler 	IF_LOCK(ifq);						\
1663c419c1bSSam Leffler 	_IF_PREPEND_LIST(ifq, mhead, mtail, mcount);		\
1673c419c1bSSam Leffler 	IF_UNLOCK(ifq);						\
1683c419c1bSSam Leffler } while (0)
1693c419c1bSSam Leffler #endif /* IF_PREPEND_LIST */
1703c419c1bSSam Leffler 
1715b16c28cSSam Leffler /*
1725b16c28cSSam Leffler  * Age queue definitions.
1735b16c28cSSam Leffler  */
1745b16c28cSSam Leffler typedef struct mtx ieee80211_ageq_lock_t;
1755b16c28cSSam Leffler #define	IEEE80211_AGEQ_INIT(_aq, _name) \
1765b16c28cSSam Leffler 	mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF)
1775b16c28cSSam Leffler #define	IEEE80211_AGEQ_DESTROY(_aq)	mtx_destroy(&(_aq)->aq_lock)
1785b16c28cSSam Leffler #define	IEEE80211_AGEQ_LOCK(_aq)	mtx_lock(&(_aq)->aq_lock)
1795b16c28cSSam Leffler #define	IEEE80211_AGEQ_UNLOCK(_aq)	mtx_unlock(&(_aq)->aq_lock)
180b032f27cSSam Leffler 
1818a1b9b6aSSam Leffler /*
1828a1b9b6aSSam Leffler  * 802.1x MAC ACL database locking definitions.
1838a1b9b6aSSam Leffler  */
1848a1b9b6aSSam Leffler typedef struct mtx acl_lock_t;
1858a1b9b6aSSam Leffler #define	ACL_LOCK_INIT(_as, _name) \
1868a1b9b6aSSam Leffler 	mtx_init(&(_as)->as_lock, _name, "802.11 ACL", MTX_DEF)
1878a1b9b6aSSam Leffler #define	ACL_LOCK_DESTROY(_as)		mtx_destroy(&(_as)->as_lock)
1888a1b9b6aSSam Leffler #define	ACL_LOCK(_as)			mtx_lock(&(_as)->as_lock)
1898a1b9b6aSSam Leffler #define	ACL_UNLOCK(_as)			mtx_unlock(&(_as)->as_lock)
1908a1b9b6aSSam Leffler #define	ACL_LOCK_ASSERT(_as) \
1918a1b9b6aSSam Leffler 	mtx_assert((&(_as)->as_lock), MA_OWNED)
1928a1b9b6aSSam Leffler 
1938a1b9b6aSSam Leffler /*
19420c3b3faSRui Paulo  * Scan table definitions.
19520c3b3faSRui Paulo  */
19620c3b3faSRui Paulo typedef struct mtx ieee80211_scan_table_lock_t;
19720c3b3faSRui Paulo #define	IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
19820c3b3faSRui Paulo 	mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF)
19920c3b3faSRui Paulo #define	IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st)	mtx_destroy(&(_st)->st_lock)
20020c3b3faSRui Paulo #define	IEEE80211_SCAN_TABLE_LOCK(_st)		mtx_lock(&(_st)->st_lock)
20120c3b3faSRui Paulo #define	IEEE80211_SCAN_TABLE_UNLOCK(_st)	mtx_unlock(&(_st)->st_lock)
20220c3b3faSRui Paulo 
203b6b2fb59SAdrian Chadd typedef struct mtx ieee80211_scan_iter_lock_t;
204b6b2fb59SAdrian Chadd #define	IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \
205b6b2fb59SAdrian Chadd 	mtx_init(&(_st)->st_scanlock, _name, "802.11 scangen", MTX_DEF)
206b6b2fb59SAdrian Chadd #define	IEEE80211_SCAN_ITER_LOCK_DESTROY(_st)	mtx_destroy(&(_st)->st_scanlock)
207b6b2fb59SAdrian Chadd #define	IEEE80211_SCAN_ITER_LOCK(_st)		mtx_lock(&(_st)->st_scanlock)
208b6b2fb59SAdrian Chadd #define	IEEE80211_SCAN_ITER_UNLOCK(_st)	mtx_unlock(&(_st)->st_scanlock)
209b6b2fb59SAdrian Chadd 
21020c3b3faSRui Paulo /*
21171f9dd12SAdrian Chadd  * Mesh node/routing definitions.
21271f9dd12SAdrian Chadd  */
21371f9dd12SAdrian Chadd typedef struct mtx ieee80211_rte_lock_t;
21471f9dd12SAdrian Chadd #define	MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \
21571f9dd12SAdrian Chadd 	mtx_init(&(rt)->rt_lock, _name, "802.11s route entry", MTX_DEF)
21671f9dd12SAdrian Chadd #define	MESH_RT_ENTRY_LOCK_DESTROY(_rt) \
21771f9dd12SAdrian Chadd 	mtx_destroy(&(_rt)->rt_lock)
21871f9dd12SAdrian Chadd #define	MESH_RT_ENTRY_LOCK(rt)	mtx_lock(&(rt)->rt_lock)
21971f9dd12SAdrian Chadd #define	MESH_RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
22071f9dd12SAdrian Chadd #define	MESH_RT_ENTRY_UNLOCK(rt)	mtx_unlock(&(rt)->rt_lock)
22171f9dd12SAdrian Chadd 
22271f9dd12SAdrian Chadd typedef struct mtx ieee80211_rt_lock_t;
22371f9dd12SAdrian Chadd #define	MESH_RT_LOCK(ms)	mtx_lock(&(ms)->ms_rt_lock)
22471f9dd12SAdrian Chadd #define	MESH_RT_LOCK_ASSERT(ms)	mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
22571f9dd12SAdrian Chadd #define	MESH_RT_UNLOCK(ms)	mtx_unlock(&(ms)->ms_rt_lock)
22671f9dd12SAdrian Chadd #define	MESH_RT_LOCK_INIT(ms, name) \
22771f9dd12SAdrian Chadd 	mtx_init(&(ms)->ms_rt_lock, name, "802.11s routing table", MTX_DEF)
22871f9dd12SAdrian Chadd #define	MESH_RT_LOCK_DESTROY(ms) \
22971f9dd12SAdrian Chadd 	mtx_destroy(&(ms)->ms_rt_lock)
23071f9dd12SAdrian Chadd 
23171f9dd12SAdrian Chadd /*
2328a1b9b6aSSam Leffler  * Node reference counting definitions.
2338a1b9b6aSSam Leffler  *
2348a1b9b6aSSam Leffler  * ieee80211_node_initref	initialize the reference count to 1
2358a1b9b6aSSam Leffler  * ieee80211_node_incref	add a reference
2368a1b9b6aSSam Leffler  * ieee80211_node_decref	remove a reference
2378a1b9b6aSSam Leffler  * ieee80211_node_dectestref	remove a reference and return 1 if this
2388a1b9b6aSSam Leffler  *				is the last reference, otherwise 0
2398a1b9b6aSSam Leffler  * ieee80211_node_refcnt	reference count for printing (only)
2408a1b9b6aSSam Leffler  */
2418a1b9b6aSSam Leffler #include <machine/atomic.h>
2428a1b9b6aSSam Leffler 
243dab61567SAndriy Voskoboinyk struct ieee80211vap;
244dab61567SAndriy Voskoboinyk int	ieee80211_com_vincref(struct ieee80211vap *);
245dab61567SAndriy Voskoboinyk void	ieee80211_com_vdecref(struct ieee80211vap *);
246dab61567SAndriy Voskoboinyk void	ieee80211_com_vdetach(struct ieee80211vap *);
247dab61567SAndriy Voskoboinyk 
2488a1b9b6aSSam Leffler #define ieee80211_node_initref(_ni) \
2498a1b9b6aSSam Leffler 	do { ((_ni)->ni_refcnt = 1); } while (0)
2508a1b9b6aSSam Leffler #define ieee80211_node_incref(_ni) \
2518a1b9b6aSSam Leffler 	atomic_add_int(&(_ni)->ni_refcnt, 1)
2528a1b9b6aSSam Leffler #define	ieee80211_node_decref(_ni) \
2538a1b9b6aSSam Leffler 	atomic_subtract_int(&(_ni)->ni_refcnt, 1)
2548a1b9b6aSSam Leffler struct ieee80211_node;
2550942c81cSSam Leffler int	ieee80211_node_dectestref(struct ieee80211_node *ni);
2568a1b9b6aSSam Leffler #define	ieee80211_node_refcnt(_ni)	(_ni)->ni_refcnt
2578a1b9b6aSSam Leffler 
25837c970e4SSam Leffler struct ifqueue;
259915f1482SSam Leffler void	ieee80211_drain_ifq(struct ifqueue *);
260b032f27cSSam Leffler void	ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
261b032f27cSSam Leffler 
262b032f27cSSam Leffler void	ieee80211_vap_destroy(struct ieee80211vap *);
26324a366afSAdrian Chadd const char *	ieee80211_get_vap_ifname(struct ieee80211vap *);
264b032f27cSSam Leffler 
265b032f27cSSam Leffler #define	IFNET_IS_UP_RUNNING(_ifp)				\
266ed987e16SAdrian Chadd 	(((if_getflags(_ifp) & IFF_UP) != 0) &&			\
267ed987e16SAdrian Chadd 	 ((if_getdrvflags(_ifp) & IFF_DRV_RUNNING) != 0))
268915f1482SSam Leffler 
2699df9e936SAndriy Voskoboinyk #define	msecs_to_ticks(ms)	MSEC_2_TICKS(ms)
2709df9e936SAndriy Voskoboinyk #define	ticks_to_msecs(t)	TICKS_2_MSEC(t)
271b032f27cSSam Leffler #define	ticks_to_secs(t)	((t) / hz)
27280d65398SAdrian Chadd 
27367a26c98SAdrian Chadd #define ieee80211_time_after(a,b) 	((int)(b) - (int)(a) < 0)
274b8e29e06SAdrian Chadd #define ieee80211_time_before(a,b)	ieee80211_time_after(b,a)
27567a26c98SAdrian Chadd #define ieee80211_time_after_eq(a,b)	((int)(a) - (int)(b) >= 0)
276b8e29e06SAdrian Chadd #define ieee80211_time_before_eq(a,b)	ieee80211_time_after_eq(b,a)
27768e8e04eSSam Leffler 
27868e8e04eSSam Leffler struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
279b1acbdbbSSam Leffler 
28068e8e04eSSam Leffler /* tx path usage */
281c1af44bdSSam Leffler #define	M_ENCAP		M_PROTO1		/* 802.11 encap done */
282b032f27cSSam Leffler #define	M_EAPOL		M_PROTO3		/* PAE/EAPOL frame */
2838a1b9b6aSSam Leffler #define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */
284bc5627d9SSam Leffler #define	M_MORE_DATA	M_PROTO5		/* more data frames to follow */
28522e6904eSAdrian Chadd #define	M_FF		M_PROTO6		/* fast frame / A-MSDU */
286b032f27cSSam Leffler #define	M_TXCB		M_PROTO7		/* do tx complete callback */
28745f856e3SSam Leffler #define	M_AMPDU_MPDU	M_PROTO8		/* ok for A-MPDU aggregation */
2887100b4d0SAndre Oppermann #define	M_FRAG		M_PROTO9		/* frame fragmentation */
2897100b4d0SAndre Oppermann #define	M_FIRSTFRAG	M_PROTO10		/* first frame fragment */
2907100b4d0SAndre Oppermann #define	M_LASTFRAG	M_PROTO11		/* last frame fragment */
291b1051653SAdrian Chadd 
292b032f27cSSam Leffler #define	M_80211_TX \
2937100b4d0SAndre Oppermann 	(M_ENCAP|M_EAPOL|M_PWR_SAV|M_MORE_DATA|M_FF|M_TXCB| \
2947100b4d0SAndre Oppermann 	 M_AMPDU_MPDU|M_FRAG|M_FIRSTFRAG|M_LASTFRAG)
295b1acbdbbSSam Leffler 
29668e8e04eSSam Leffler /* rx path usage */
29745f856e3SSam Leffler #define	M_AMPDU		M_PROTO1		/* A-MPDU subframe */
298b1acbdbbSSam Leffler #define	M_WEP		M_PROTO2		/* WEP done by hardware */
29945f856e3SSam Leffler #if 0
30045f856e3SSam Leffler #define	M_AMPDU_MPDU	M_PROTO8		/* A-MPDU re-order done */
30145f856e3SSam Leffler #endif
30245f856e3SSam Leffler #define	M_80211_RX	(M_AMPDU|M_WEP|M_AMPDU_MPDU)
30359aa14a9SRui Paulo 
30459aa14a9SRui Paulo #define	IEEE80211_MBUF_TX_FLAG_BITS \
3055fc98a78SAndre Oppermann 	M_FLAG_BITS \
3065fc98a78SAndre Oppermann 	"\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
3075fc98a78SAndre Oppermann 	"\24M_AMPDU_MPDU\25M_FRAG\26M_FIRSTFRAG\27M_LASTFRAG"
30859aa14a9SRui Paulo 
30959aa14a9SRui Paulo #define	IEEE80211_MBUF_RX_FLAG_BITS \
3105fc98a78SAndre Oppermann 	M_FLAG_BITS \
3115fc98a78SAndre Oppermann 	"\15M_AMPDU\16M_WEP\24M_AMPDU_MPDU"
31259aa14a9SRui Paulo 
3138a1b9b6aSSam Leffler /*
314b032f27cSSam Leffler  * Store WME access control bits in the vlan tag.
315b032f27cSSam Leffler  * This is safe since it's done after the packet is classified
316b032f27cSSam Leffler  * (where we use any previous tag) and because it's passed
317b032f27cSSam Leffler  * directly in to the driver and there's no chance someone
318b032f27cSSam Leffler  * else will clobber them on us.
3198a1b9b6aSSam Leffler  */
3208a1b9b6aSSam Leffler #define	M_WME_SETAC(m, ac) \
321b032f27cSSam Leffler 	((m)->m_pkthdr.ether_vtag = (ac))
322b032f27cSSam Leffler #define	M_WME_GETAC(m)	((m)->m_pkthdr.ether_vtag)
3238a1b9b6aSSam Leffler 
3248a1b9b6aSSam Leffler /*
3258a1b9b6aSSam Leffler  * Mbufs on the power save queue are tagged with an age and
3268a1b9b6aSSam Leffler  * timed out.  We reuse the hardware checksum field in the
3278a1b9b6aSSam Leffler  * mbuf packet header to store this data.
3288a1b9b6aSSam Leffler  */
3298a1b9b6aSSam Leffler #define	M_AGE_SET(m,v)		(m->m_pkthdr.csum_data = v)
3308a1b9b6aSSam Leffler #define	M_AGE_GET(m)		(m->m_pkthdr.csum_data)
3318a1b9b6aSSam Leffler #define	M_AGE_SUB(m,adj)	(m->m_pkthdr.csum_data -= adj)
3328a1b9b6aSSam Leffler 
3339a841c7fSSam Leffler /*
3349a841c7fSSam Leffler  * Store the sequence number.
3359a841c7fSSam Leffler  */
3369a841c7fSSam Leffler #define	M_SEQNO_SET(m, seqno) \
3379a841c7fSSam Leffler 	((m)->m_pkthdr.tso_segsz = (seqno))
3389a841c7fSSam Leffler #define	M_SEQNO_GET(m)	((m)->m_pkthdr.tso_segsz)
3399a841c7fSSam Leffler 
34068e8e04eSSam Leffler #define	MTAG_ABI_NET80211	1132948340	/* net80211 ABI */
34168e8e04eSSam Leffler 
34268e8e04eSSam Leffler struct ieee80211_cb {
34368e8e04eSSam Leffler 	void	(*func)(struct ieee80211_node *, void *, int status);
34468e8e04eSSam Leffler 	void	*arg;
34568e8e04eSSam Leffler };
34668e8e04eSSam Leffler #define	NET80211_TAG_CALLBACK	0	/* xmit complete callback */
34768e8e04eSSam Leffler int	ieee80211_add_callback(struct mbuf *m,
34868e8e04eSSam Leffler 		void (*func)(struct ieee80211_node *, void *, int), void *arg);
34968e8e04eSSam Leffler void	ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
35068e8e04eSSam Leffler 
3519afc11b2SAdrian Chadd #define	NET80211_TAG_XMIT_PARAMS	1
3529afc11b2SAdrian Chadd /* See below; this is after the bpf_params definition */
3539afc11b2SAdrian Chadd 
354b86fd7bcSAdrian Chadd #define	NET80211_TAG_RECV_PARAMS	2
355b86fd7bcSAdrian Chadd 
356c028fb50SAdrian Chadd #define	NET80211_TAG_TOA_PARAMS		3
357c028fb50SAdrian Chadd 
3588a1b9b6aSSam Leffler struct ieee80211com;
359e7495198SAdrian Chadd int	ieee80211_parent_xmitpkt(struct ieee80211com *, struct mbuf *);
360e7495198SAdrian Chadd int	ieee80211_vap_xmitpkt(struct ieee80211vap *, struct mbuf *);
3615cda6006SAdrian Chadd 
362af7d9f8eSBjoern A. Zeeb void	net80211_get_random_bytes(void *, size_t);
3638a1b9b6aSSam Leffler 
3648a1b9b6aSSam Leffler void	ieee80211_sysctl_attach(struct ieee80211com *);
3658a1b9b6aSSam Leffler void	ieee80211_sysctl_detach(struct ieee80211com *);
366b032f27cSSam Leffler void	ieee80211_sysctl_vattach(struct ieee80211vap *);
367b032f27cSSam Leffler void	ieee80211_sysctl_vdetach(struct ieee80211vap *);
3688a1b9b6aSSam Leffler 
369f6ac5011SSam Leffler SYSCTL_DECL(_net_wlan);
370f6ac5011SSam Leffler int	ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS);
371f6ac5011SSam Leffler 
3728a1b9b6aSSam Leffler void	ieee80211_load_module(const char *);
37368e8e04eSSam Leffler 
374b032f27cSSam Leffler /*
375b032f27cSSam Leffler  * A "policy module" is an adjunct module to net80211 that provides
376b032f27cSSam Leffler  * functionality that typically includes policy decisions.  This
377b032f27cSSam Leffler  * modularity enables extensibility and vendor-supplied functionality.
378b032f27cSSam Leffler  */
379b032f27cSSam Leffler #define	_IEEE80211_POLICY_MODULE(policy, name, version)			\
380b032f27cSSam Leffler typedef void (*policy##_setup)(int);					\
381b032f27cSSam Leffler SET_DECLARE(policy##_set, policy##_setup);				\
38268e8e04eSSam Leffler static int								\
383b032f27cSSam Leffler wlan_##name##_modevent(module_t mod, int type, void *unused)		\
38468e8e04eSSam Leffler {									\
385b032f27cSSam Leffler 	policy##_setup * const *iter, f;				\
38668e8e04eSSam Leffler 	switch (type) {							\
38768e8e04eSSam Leffler 	case MOD_LOAD:							\
388b032f27cSSam Leffler 		SET_FOREACH(iter, policy##_set) {			\
389b032f27cSSam Leffler 			f = (void*) *iter;				\
390b032f27cSSam Leffler 			f(type);					\
391b032f27cSSam Leffler 		}							\
39268e8e04eSSam Leffler 		return 0;						\
39368e8e04eSSam Leffler 	case MOD_UNLOAD:						\
39468e8e04eSSam Leffler 	case MOD_QUIESCE:						\
39568e8e04eSSam Leffler 		if (nrefs) {						\
396fc4d77c3SAdrian Chadd 			printf("wlan_" #name ": still in use "		\
397fc4d77c3SAdrian Chadd 				"(%u dynamic refs)\n", nrefs);		\
39868e8e04eSSam Leffler 			return EBUSY;					\
39968e8e04eSSam Leffler 		}							\
400b032f27cSSam Leffler 		if (type == MOD_UNLOAD) {				\
401b032f27cSSam Leffler 			SET_FOREACH(iter, policy##_set) {		\
402b032f27cSSam Leffler 				f = (void*) *iter;			\
403b032f27cSSam Leffler 				f(type);				\
404b032f27cSSam Leffler 			}						\
405b032f27cSSam Leffler 		}							\
40668e8e04eSSam Leffler 		return 0;						\
40768e8e04eSSam Leffler 	}								\
40868e8e04eSSam Leffler 	return EINVAL;							\
40968e8e04eSSam Leffler }									\
41068e8e04eSSam Leffler static moduledata_t name##_mod = {					\
41168e8e04eSSam Leffler 	"wlan_" #name,							\
412b032f27cSSam Leffler 	wlan_##name##_modevent,						\
4139823d527SKevin Lo 	0								\
41468e8e04eSSam Leffler };									\
41568e8e04eSSam Leffler DECLARE_MODULE(wlan_##name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
41668e8e04eSSam Leffler MODULE_VERSION(wlan_##name, version);					\
41768e8e04eSSam Leffler MODULE_DEPEND(wlan_##name, wlan, 1, 1, 1)
418b032f27cSSam Leffler 
419b032f27cSSam Leffler /*
420b032f27cSSam Leffler  * Crypto modules implement cipher support.
421b032f27cSSam Leffler  */
422dcf6ab2fSAdrian Chadd #define	IEEE80211_CRYPTO_MODULE_ADD(name)				\
423b032f27cSSam Leffler static void								\
424b032f27cSSam Leffler name##_modevent(int type)						\
425b032f27cSSam Leffler {									\
426b032f27cSSam Leffler 	if (type == MOD_LOAD)						\
427b032f27cSSam Leffler 		ieee80211_crypto_register(&name);			\
428b032f27cSSam Leffler 	else								\
429b032f27cSSam Leffler 		ieee80211_crypto_unregister(&name);			\
430b032f27cSSam Leffler }									\
431b032f27cSSam Leffler TEXT_SET(crypto##_set, name##_modevent)
432b032f27cSSam Leffler 
433dcf6ab2fSAdrian Chadd #define	IEEE80211_CRYPTO_MODULE(name, version)				\
434dcf6ab2fSAdrian Chadd 	_IEEE80211_POLICY_MODULE(crypto, name, version);		\
435dcf6ab2fSAdrian Chadd 	IEEE80211_CRYPTO_MODULE_ADD(name)
436dcf6ab2fSAdrian Chadd 
437b032f27cSSam Leffler /*
438b032f27cSSam Leffler  * Scanner modules provide scanning policy.
439b032f27cSSam Leffler  */
440b032f27cSSam Leffler #define	IEEE80211_SCANNER_MODULE(name, version)				\
441b032f27cSSam Leffler 	_IEEE80211_POLICY_MODULE(scanner, name, version)
442b032f27cSSam Leffler 
443b032f27cSSam Leffler #define	IEEE80211_SCANNER_ALG(name, alg, v)				\
444b032f27cSSam Leffler static void								\
445b032f27cSSam Leffler name##_modevent(int type)						\
446b032f27cSSam Leffler {									\
447b032f27cSSam Leffler 	if (type == MOD_LOAD)						\
448b032f27cSSam Leffler 		ieee80211_scanner_register(alg, &v);			\
449b032f27cSSam Leffler 	else								\
450b032f27cSSam Leffler 		ieee80211_scanner_unregister(alg, &v);			\
451b032f27cSSam Leffler }									\
452b032f27cSSam Leffler TEXT_SET(scanner_set, name##_modevent);					\
453b032f27cSSam Leffler 
454b032f27cSSam Leffler /*
455b032f27cSSam Leffler  * ACL modules implement acl policy.
456b032f27cSSam Leffler  */
457b032f27cSSam Leffler #define	IEEE80211_ACL_MODULE(name, alg, version)			\
458b032f27cSSam Leffler _IEEE80211_POLICY_MODULE(acl, name, version);				\
459b032f27cSSam Leffler static void								\
460b032f27cSSam Leffler alg##_modevent(int type)						\
461b032f27cSSam Leffler {									\
462b032f27cSSam Leffler 	if (type == MOD_LOAD)						\
463b032f27cSSam Leffler 		ieee80211_aclator_register(&alg);			\
464b032f27cSSam Leffler 	else								\
465b032f27cSSam Leffler 		ieee80211_aclator_unregister(&alg);			\
466b032f27cSSam Leffler }									\
467b032f27cSSam Leffler TEXT_SET(acl_set, alg##_modevent);					\
468b032f27cSSam Leffler 
469b032f27cSSam Leffler /*
470b032f27cSSam Leffler  * Authenticator modules handle 802.1x/WPA authentication.
471b032f27cSSam Leffler  */
472b032f27cSSam Leffler #define	IEEE80211_AUTH_MODULE(name, version)				\
473b032f27cSSam Leffler 	_IEEE80211_POLICY_MODULE(auth, name, version)
474b032f27cSSam Leffler 
475b032f27cSSam Leffler #define	IEEE80211_AUTH_ALG(name, alg, v)				\
476b032f27cSSam Leffler static void								\
477b032f27cSSam Leffler name##_modevent(int type)						\
478b032f27cSSam Leffler {									\
479b032f27cSSam Leffler 	if (type == MOD_LOAD)						\
480b032f27cSSam Leffler 		ieee80211_authenticator_register(alg, &v);		\
481b032f27cSSam Leffler 	else								\
482b032f27cSSam Leffler 		ieee80211_authenticator_unregister(alg);		\
483b032f27cSSam Leffler }									\
484b032f27cSSam Leffler TEXT_SET(auth_set, name##_modevent)
485b032f27cSSam Leffler 
486b032f27cSSam Leffler /*
487b032f27cSSam Leffler  * Rate control modules provide tx rate control support.
488b032f27cSSam Leffler  */
489b6108616SRui Paulo #define	IEEE80211_RATECTL_MODULE(alg, version)				\
490b6108616SRui Paulo 	_IEEE80211_POLICY_MODULE(ratectl, alg, version);		\
491b6108616SRui Paulo 
492b6108616SRui Paulo #define	IEEE80211_RATECTL_ALG(name, alg, v)				\
493b032f27cSSam Leffler static void								\
494b032f27cSSam Leffler alg##_modevent(int type)						\
495b032f27cSSam Leffler {									\
496b6108616SRui Paulo 	if (type == MOD_LOAD)						\
497b6108616SRui Paulo 		ieee80211_ratectl_register(alg, &v);			\
498b6108616SRui Paulo 	else								\
499b6108616SRui Paulo 		ieee80211_ratectl_unregister(alg);			\
500b032f27cSSam Leffler }									\
501b6108616SRui Paulo TEXT_SET(ratectl##_set, alg##_modevent)
5028a1b9b6aSSam Leffler 
5038c4e758aSSam Leffler struct ieee80211req;
5048c4e758aSSam Leffler typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
5058c4e758aSSam Leffler     struct ieee80211req *);
5068c4e758aSSam Leffler SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc);
5078c4e758aSSam Leffler #define	IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get)
5088c4e758aSSam Leffler 
5098c4e758aSSam Leffler typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
5108c4e758aSSam Leffler     struct ieee80211req *);
5118c4e758aSSam Leffler SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
5128c4e758aSSam Leffler #define	IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set)
513479ab044SConrad Meyer 
514479ab044SConrad Meyer #ifdef DEBUGNET
515479ab044SConrad Meyer typedef void debugnet80211_init_t(struct ieee80211com *, int *nrxr, int *ncl,
516479ab044SConrad Meyer     int *clsize);
517479ab044SConrad Meyer typedef void debugnet80211_event_t(struct ieee80211com *, enum debugnet_ev);
518479ab044SConrad Meyer typedef int debugnet80211_poll_t(struct ieee80211com *, int);
519479ab044SConrad Meyer 
520479ab044SConrad Meyer struct debugnet80211_methods {
521479ab044SConrad Meyer 	debugnet80211_init_t		*dn8_init;
522479ab044SConrad Meyer 	debugnet80211_event_t		*dn8_event;
523479ab044SConrad Meyer 	debugnet80211_poll_t		*dn8_poll;
524479ab044SConrad Meyer };
525479ab044SConrad Meyer 
526479ab044SConrad Meyer #define	DEBUGNET80211_DEFINE(driver)					\
527479ab044SConrad Meyer 	static debugnet80211_init_t driver##_debugnet80211_init;		\
528479ab044SConrad Meyer 	static debugnet80211_event_t driver##_debugnet80211_event;	\
529479ab044SConrad Meyer 	static debugnet80211_poll_t driver##_debugnet80211_poll;		\
530479ab044SConrad Meyer 									\
531479ab044SConrad Meyer 	static struct debugnet80211_methods driver##_debugnet80211_methods = { \
532479ab044SConrad Meyer 		.dn8_init = driver##_debugnet80211_init,			\
533479ab044SConrad Meyer 		.dn8_event = driver##_debugnet80211_event,		\
534479ab044SConrad Meyer 		.dn8_poll = driver##_debugnet80211_poll,			\
535479ab044SConrad Meyer 	}
536479ab044SConrad Meyer #define DEBUGNET80211_SET(ic, driver)					\
537479ab044SConrad Meyer 	(ic)->ic_debugnet_meth = &driver##_debugnet80211_methods
538479ab044SConrad Meyer #else
539479ab044SConrad Meyer #define DEBUGNET80211_DEFINE(driver)
540479ab044SConrad Meyer #define DEBUGNET80211_SET(ic, driver)
541479ab044SConrad Meyer #endif /* DEBUGNET */
542479ab044SConrad Meyer 
543e035e866SAdrian Chadd void ieee80211_vap_sync_mac_address(struct ieee80211vap *);
544e035e866SAdrian Chadd void ieee80211_vap_copy_mac_address(struct ieee80211vap *);
5453f6a84ffSAdrian Chadd void ieee80211_vap_deliver_data(struct ieee80211vap *, struct mbuf *);
546ed987e16SAdrian Chadd bool ieee80211_vap_ifp_check_is_monitor(struct ieee80211vap *);
547ed987e16SAdrian Chadd bool ieee80211_vap_ifp_check_is_simplex(struct ieee80211vap *);
548ed987e16SAdrian Chadd bool ieee80211_vap_ifp_check_is_running(struct ieee80211vap *);
549ed987e16SAdrian Chadd void ieee80211_vap_ifp_set_running_state(struct ieee80211vap *, bool);
550a278d11aSAdrian Chadd const uint8_t * ieee80211_vap_get_broadcast_address(struct ieee80211vap *);
551e035e866SAdrian Chadd 
552*0861daf5SAdrian Chadd void	net80211_printf(const char *fmt, ...) __printflike(1, 2);
553*0861daf5SAdrian Chadd void	net80211_vap_printf(const struct ieee80211vap *, const char *fmt, ...)
554*0861daf5SAdrian Chadd 	    __printflike(2, 3);
555*0861daf5SAdrian Chadd void	net80211_ic_printf(const struct ieee80211com *, const char *fmt, ...)
556*0861daf5SAdrian Chadd 	    __printflike(2, 3);
557*0861daf5SAdrian Chadd 
558694f48d3SSam Leffler #endif /* _KERNEL */
5598c4e758aSSam Leffler 
5608a1b9b6aSSam Leffler /* XXX this stuff belongs elsewhere */
5618a1b9b6aSSam Leffler /*
5628a1b9b6aSSam Leffler  * Message formats for messages from the net80211 layer to user
5638a1b9b6aSSam Leffler  * applications via the routing socket.  These messages are appended
5648a1b9b6aSSam Leffler  * to an if_announcemsghdr structure.
5658a1b9b6aSSam Leffler  */
5668a1b9b6aSSam Leffler struct ieee80211_join_event {
5678a1b9b6aSSam Leffler 	uint8_t		iev_addr[6];
5688a1b9b6aSSam Leffler };
5698a1b9b6aSSam Leffler 
5708a1b9b6aSSam Leffler struct ieee80211_leave_event {
5718a1b9b6aSSam Leffler 	uint8_t		iev_addr[6];
5728a1b9b6aSSam Leffler };
5738a1b9b6aSSam Leffler 
5748a1b9b6aSSam Leffler struct ieee80211_replay_event {
5758a1b9b6aSSam Leffler 	uint8_t		iev_src[6];	/* src MAC */
5768a1b9b6aSSam Leffler 	uint8_t		iev_dst[6];	/* dst MAC */
5778a1b9b6aSSam Leffler 	uint8_t		iev_cipher;	/* cipher type */
5788a1b9b6aSSam Leffler 	uint8_t		iev_keyix;	/* key id/index */
5798a1b9b6aSSam Leffler 	uint64_t	iev_keyrsc;	/* RSC from key */
5808a1b9b6aSSam Leffler 	uint64_t	iev_rsc;	/* RSC from frame */
5818a1b9b6aSSam Leffler };
5828a1b9b6aSSam Leffler 
5838a1b9b6aSSam Leffler struct ieee80211_michael_event {
5848a1b9b6aSSam Leffler 	uint8_t		iev_src[6];	/* src MAC */
5858a1b9b6aSSam Leffler 	uint8_t		iev_dst[6];	/* dst MAC */
5868a1b9b6aSSam Leffler 	uint8_t		iev_cipher;	/* cipher type */
5878a1b9b6aSSam Leffler 	uint8_t		iev_keyix;	/* key id/index */
5888a1b9b6aSSam Leffler };
5898a1b9b6aSSam Leffler 
590b032f27cSSam Leffler struct ieee80211_wds_event {
591b032f27cSSam Leffler 	uint8_t		iev_addr[6];
592b032f27cSSam Leffler };
593b032f27cSSam Leffler 
594b032f27cSSam Leffler struct ieee80211_csa_event {
595b032f27cSSam Leffler 	uint32_t	iev_flags;	/* channel flags */
596b032f27cSSam Leffler 	uint16_t	iev_freq;	/* setting in Mhz */
597b032f27cSSam Leffler 	uint8_t		iev_ieee;	/* IEEE channel number */
598b032f27cSSam Leffler 	uint8_t		iev_mode;	/* CSA mode */
599b032f27cSSam Leffler 	uint8_t		iev_count;	/* CSA count */
600b032f27cSSam Leffler };
601b032f27cSSam Leffler 
602b032f27cSSam Leffler struct ieee80211_cac_event {
603b032f27cSSam Leffler 	uint32_t	iev_flags;	/* channel flags */
604b032f27cSSam Leffler 	uint16_t	iev_freq;	/* setting in Mhz */
605b032f27cSSam Leffler 	uint8_t		iev_ieee;	/* IEEE channel number */
606b032f27cSSam Leffler 	/* XXX timestamp? */
607b032f27cSSam Leffler 	uint8_t		iev_type;	/* IEEE80211_NOTIFY_CAC_* */
608b032f27cSSam Leffler };
609b032f27cSSam Leffler 
610b032f27cSSam Leffler struct ieee80211_radar_event {
611b032f27cSSam Leffler 	uint32_t	iev_flags;	/* channel flags */
612b032f27cSSam Leffler 	uint16_t	iev_freq;	/* setting in Mhz */
613b032f27cSSam Leffler 	uint8_t		iev_ieee;	/* IEEE channel number */
614b032f27cSSam Leffler 	/* XXX timestamp? */
615b032f27cSSam Leffler };
616b032f27cSSam Leffler 
617b032f27cSSam Leffler struct ieee80211_auth_event {
618b032f27cSSam Leffler 	uint8_t		iev_addr[6];
619b032f27cSSam Leffler };
620b032f27cSSam Leffler 
621b032f27cSSam Leffler struct ieee80211_deauth_event {
622b032f27cSSam Leffler 	uint8_t		iev_addr[6];
623b032f27cSSam Leffler };
624b032f27cSSam Leffler 
625b032f27cSSam Leffler struct ieee80211_country_event {
626b032f27cSSam Leffler 	uint8_t		iev_addr[6];
627b032f27cSSam Leffler 	uint8_t		iev_cc[2];	/* ISO country code */
628b032f27cSSam Leffler };
629b032f27cSSam Leffler 
630b032f27cSSam Leffler struct ieee80211_radio_event {
631b032f27cSSam Leffler 	uint8_t		iev_state;	/* 1 on, 0 off */
632b032f27cSSam Leffler };
633b032f27cSSam Leffler 
6348a1b9b6aSSam Leffler #define	RTM_IEEE80211_ASSOC	100	/* station associate (bss mode) */
6358a1b9b6aSSam Leffler #define	RTM_IEEE80211_REASSOC	101	/* station re-associate (bss mode) */
6368a1b9b6aSSam Leffler #define	RTM_IEEE80211_DISASSOC	102	/* station disassociate (bss mode) */
6378a1b9b6aSSam Leffler #define	RTM_IEEE80211_JOIN	103	/* station join (ap mode) */
6388a1b9b6aSSam Leffler #define	RTM_IEEE80211_LEAVE	104	/* station leave (ap mode) */
6398a1b9b6aSSam Leffler #define	RTM_IEEE80211_SCAN	105	/* scan complete, results available */
6408a1b9b6aSSam Leffler #define	RTM_IEEE80211_REPLAY	106	/* sequence counter replay detected */
6418a1b9b6aSSam Leffler #define	RTM_IEEE80211_MICHAEL	107	/* Michael MIC failure detected */
6420fc5fe12SSam Leffler #define	RTM_IEEE80211_REJOIN	108	/* station re-associate (ap mode) */
643b032f27cSSam Leffler #define	RTM_IEEE80211_WDS	109	/* WDS discovery (ap mode) */
644b032f27cSSam Leffler #define	RTM_IEEE80211_CSA	110	/* Channel Switch Announcement event */
645b032f27cSSam Leffler #define	RTM_IEEE80211_RADAR	111	/* radar event */
646b032f27cSSam Leffler #define	RTM_IEEE80211_CAC	112	/* Channel Availability Check event */
647b032f27cSSam Leffler #define	RTM_IEEE80211_DEAUTH	113	/* station deauthenticate */
648b032f27cSSam Leffler #define	RTM_IEEE80211_AUTH	114	/* station authenticate (ap mode) */
649b032f27cSSam Leffler #define	RTM_IEEE80211_COUNTRY	115	/* discovered country code (sta mode) */
650b032f27cSSam Leffler #define	RTM_IEEE80211_RADIO	116	/* RF kill switch state change */
6518a1b9b6aSSam Leffler 
652246b5467SSam Leffler /*
653246b5467SSam Leffler  * Structure prepended to raw packets sent through the bpf
654246b5467SSam Leffler  * interface when set to DLT_IEEE802_11_RADIO.  This allows
655246b5467SSam Leffler  * user applications to specify pretty much everything in
656246b5467SSam Leffler  * an Atheros tx descriptor.  XXX need to generalize.
657246b5467SSam Leffler  *
658246b5467SSam Leffler  * XXX cannot be more than 14 bytes as it is copied to a sockaddr's
659246b5467SSam Leffler  * XXX sa_data area.
660246b5467SSam Leffler  */
661246b5467SSam Leffler struct ieee80211_bpf_params {
662246b5467SSam Leffler 	uint8_t		ibp_vers;	/* version */
663246b5467SSam Leffler #define	IEEE80211_BPF_VERSION	0
664246b5467SSam Leffler 	uint8_t		ibp_len;	/* header length in bytes */
665246b5467SSam Leffler 	uint8_t		ibp_flags;
666246b5467SSam Leffler #define	IEEE80211_BPF_SHORTPRE	0x01	/* tx with short preamble */
667246b5467SSam Leffler #define	IEEE80211_BPF_NOACK	0x02	/* tx with no ack */
668246b5467SSam Leffler #define	IEEE80211_BPF_CRYPTO	0x04	/* tx with h/w encryption */
669246b5467SSam Leffler #define	IEEE80211_BPF_FCS	0x10	/* frame incldues FCS */
670246b5467SSam Leffler #define	IEEE80211_BPF_DATAPAD	0x20	/* frame includes data padding */
671246b5467SSam Leffler #define	IEEE80211_BPF_RTS	0x40	/* tx with RTS/CTS */
672246b5467SSam Leffler #define	IEEE80211_BPF_CTS	0x80	/* tx with CTS only */
673246b5467SSam Leffler 	uint8_t		ibp_pri;	/* WME/WMM AC+tx antenna */
674246b5467SSam Leffler 	uint8_t		ibp_try0;	/* series 1 try count */
675246b5467SSam Leffler 	uint8_t		ibp_rate0;	/* series 1 IEEE tx rate */
676246b5467SSam Leffler 	uint8_t		ibp_power;	/* tx power (device units) */
677246b5467SSam Leffler 	uint8_t		ibp_ctsrate;	/* IEEE tx rate for CTS */
678246b5467SSam Leffler 	uint8_t		ibp_try1;	/* series 2 try count */
679246b5467SSam Leffler 	uint8_t		ibp_rate1;	/* series 2 IEEE tx rate */
680246b5467SSam Leffler 	uint8_t		ibp_try2;	/* series 3 try count */
681246b5467SSam Leffler 	uint8_t		ibp_rate2;	/* series 3 IEEE tx rate */
682246b5467SSam Leffler 	uint8_t		ibp_try3;	/* series 4 try count */
683246b5467SSam Leffler 	uint8_t		ibp_rate3;	/* series 4 IEEE tx rate */
684246b5467SSam Leffler };
685b9b53389SAdrian Chadd 
6865148474eSAndrew Turner #ifdef _KERNEL
6879afc11b2SAdrian Chadd struct ieee80211_tx_params {
6889afc11b2SAdrian Chadd 	struct ieee80211_bpf_params params;
6899afc11b2SAdrian Chadd };
6909afc11b2SAdrian Chadd int	ieee80211_add_xmit_params(struct mbuf *m,
6919afc11b2SAdrian Chadd 	    const struct ieee80211_bpf_params *);
6929afc11b2SAdrian Chadd int	ieee80211_get_xmit_params(struct mbuf *m,
6939afc11b2SAdrian Chadd 	    struct ieee80211_bpf_params *);
694b86fd7bcSAdrian Chadd 
695617f8b10SAdrian Chadd struct ieee80211_rx_params;
696617f8b10SAdrian Chadd struct ieee80211_rx_stats;
697b86fd7bcSAdrian Chadd 
698b86fd7bcSAdrian Chadd int	ieee80211_add_rx_params(struct mbuf *m,
699b86fd7bcSAdrian Chadd 	    const struct ieee80211_rx_stats *rxs);
700b86fd7bcSAdrian Chadd int	ieee80211_get_rx_params(struct mbuf *m,
701b86fd7bcSAdrian Chadd 	    struct ieee80211_rx_stats *rxs);
702d24ac5fbSAdrian Chadd const struct ieee80211_rx_stats * ieee80211_get_rx_params_ptr(struct mbuf *m);
703c028fb50SAdrian Chadd 
704c028fb50SAdrian Chadd struct ieee80211_toa_params {
705c028fb50SAdrian Chadd 	int request_id;
706c028fb50SAdrian Chadd };
707c028fb50SAdrian Chadd int	ieee80211_add_toa_params(struct mbuf *m,
708c028fb50SAdrian Chadd 	    const struct ieee80211_toa_params *p);
709c028fb50SAdrian Chadd int	ieee80211_get_toa_params(struct mbuf *m,
710c028fb50SAdrian Chadd 	    struct ieee80211_toa_params *p);
71136c8d0deSAdrian Chadd 
71236c8d0deSAdrian Chadd #define	IEEE80211_F_SURVEY_TIME		0x00000001
71336c8d0deSAdrian Chadd #define	IEEE80211_F_SURVEY_TIME_BUSY	0x00000002
71436c8d0deSAdrian Chadd #define	IEEE80211_F_SURVEY_NOISE_DBM	0x00000004
7154869f594SAdrian Chadd #define	IEEE80211_F_SURVEY_TSC		0x00000008
71636c8d0deSAdrian Chadd struct ieee80211_channel_survey {
71736c8d0deSAdrian Chadd 	uint32_t s_flags;
71836c8d0deSAdrian Chadd 	uint32_t s_time;
71936c8d0deSAdrian Chadd 	uint32_t s_time_busy;
7204869f594SAdrian Chadd 	int32_t s_noise;
7214869f594SAdrian Chadd 	uint64_t s_tsc;
72236c8d0deSAdrian Chadd };
72336c8d0deSAdrian Chadd 
7245148474eSAndrew Turner #endif /* _KERNEL */
7259afc11b2SAdrian Chadd 
726b9b53389SAdrian Chadd /*
727b9b53389SAdrian Chadd  * Malloc API.  Other BSD operating systems have slightly
728b9b53389SAdrian Chadd  * different malloc/free namings (eg DragonflyBSD.)
729b9b53389SAdrian Chadd  */
730b9b53389SAdrian Chadd #define	IEEE80211_MALLOC	malloc
731b9b53389SAdrian Chadd #define	IEEE80211_FREE		free
732b9b53389SAdrian Chadd 
733b9b53389SAdrian Chadd /* XXX TODO: get rid of WAITOK, fix all the users of it? */
734b9b53389SAdrian Chadd #define	IEEE80211_M_NOWAIT	M_NOWAIT
735b9b53389SAdrian Chadd #define	IEEE80211_M_WAITOK	M_WAITOK
736b9b53389SAdrian Chadd #define	IEEE80211_M_ZERO	M_ZERO
737b9b53389SAdrian Chadd 
738b9b53389SAdrian Chadd /* XXX TODO: the type fields */
739b9b53389SAdrian Chadd 
7408a1b9b6aSSam Leffler #endif /* _NET80211_IEEE80211_FREEBSD_H_ */
741