16d0f2b48SAugustin Cavalier /* 26d0f2b48SAugustin Cavalier * Copyright 2009, Colin Günther, coling@gmx.de. All rights reserved. 36d0f2b48SAugustin Cavalier * Copyright 2018, Haiku, Inc. All rights reserved. 46d0f2b48SAugustin Cavalier * Distributed under the terms of the MIT License. 56d0f2b48SAugustin Cavalier */ 6753c7e08SAugustin Cavalier /*- 7753c7e08SAugustin Cavalier * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting 8753c7e08SAugustin Cavalier * All rights reserved. 9753c7e08SAugustin Cavalier * 10753c7e08SAugustin Cavalier * Redistribution and use in source and binary forms, with or without 11753c7e08SAugustin Cavalier * modification, are permitted provided that the following conditions 12753c7e08SAugustin Cavalier * are met: 13753c7e08SAugustin Cavalier * 1. Redistributions of source code must retain the above copyright 14753c7e08SAugustin Cavalier * notice, this list of conditions and the following disclaimer. 15753c7e08SAugustin Cavalier * 2. Redistributions in binary form must reproduce the above copyright 16753c7e08SAugustin Cavalier * notice, this list of conditions and the following disclaimer in the 17753c7e08SAugustin Cavalier * documentation and/or other materials provided with the distribution. 18753c7e08SAugustin Cavalier * 19753c7e08SAugustin Cavalier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20753c7e08SAugustin Cavalier * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21753c7e08SAugustin Cavalier * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22753c7e08SAugustin Cavalier * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23753c7e08SAugustin Cavalier * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24753c7e08SAugustin Cavalier * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25753c7e08SAugustin Cavalier * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26753c7e08SAugustin Cavalier * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27753c7e08SAugustin Cavalier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28753c7e08SAugustin Cavalier * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29753c7e08SAugustin Cavalier */ 30753c7e08SAugustin Cavalier #ifndef _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ 31753c7e08SAugustin Cavalier #define _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ 32753c7e08SAugustin Cavalier 33753c7e08SAugustin Cavalier 34753c7e08SAugustin Cavalier #include <stdint.h> 35753c7e08SAugustin Cavalier 36753c7e08SAugustin Cavalier 37753c7e08SAugustin Cavalier #ifdef _KERNEL 38753c7e08SAugustin Cavalier 39753c7e08SAugustin Cavalier # ifdef __cplusplus 40753c7e08SAugustin Cavalier // Those includes are needed to avoid C/C++ function export clashes 41753c7e08SAugustin Cavalier # include <new> 42753c7e08SAugustin Cavalier # include <thread.h> 43753c7e08SAugustin Cavalier extern "C" { 44753c7e08SAugustin Cavalier # endif 45753c7e08SAugustin Cavalier 46753c7e08SAugustin Cavalier #include <sys/kernel.h> 47753c7e08SAugustin Cavalier #include <sys/mutex.h> 48753c7e08SAugustin Cavalier #include <sys/sysctl.h> 49753c7e08SAugustin Cavalier #include <sys/taskqueue.h> 505cad57c4SJérôme Duval #include <sys/time.h> 51753c7e08SAugustin Cavalier 52753c7e08SAugustin Cavalier 535cad57c4SJérôme Duval #ifdef DEBUGNET 545cad57c4SJérôme Duval #include <net/debugnet.h> 555cad57c4SJérôme Duval #endif 565cad57c4SJérôme Duval 575cad57c4SJérôme Duval /* 585cad57c4SJérôme Duval * priv(9) NET80211 checks. 595cad57c4SJérôme Duval */ 605cad57c4SJérôme Duval struct ieee80211vap; 615cad57c4SJérôme Duval int ieee80211_priv_check_vap_getkey(u_long, struct ieee80211vap *, 625cad57c4SJérôme Duval struct ifnet *); 635cad57c4SJérôme Duval int ieee80211_priv_check_vap_manage(u_long, struct ieee80211vap *, 645cad57c4SJérôme Duval struct ifnet *); 655cad57c4SJérôme Duval int ieee80211_priv_check_vap_setmac(u_long, struct ieee80211vap *, 665cad57c4SJérôme Duval struct ifnet *); 675cad57c4SJérôme Duval int ieee80211_priv_check_create_vap(u_long, struct ieee80211vap *, 685cad57c4SJérôme Duval struct ifnet *); 695cad57c4SJérôme Duval 70753c7e08SAugustin Cavalier /* 71753c7e08SAugustin Cavalier * Common state locking definitions. 72753c7e08SAugustin Cavalier */ 73753c7e08SAugustin Cavalier typedef struct { 74753c7e08SAugustin Cavalier char name[16]; /* e.g. "ath0_com_lock" */ 75753c7e08SAugustin Cavalier struct mtx mtx; 76753c7e08SAugustin Cavalier } ieee80211_com_lock_t; 77753c7e08SAugustin Cavalier #define IEEE80211_LOCK_INIT(_ic, _name) do { \ 78753c7e08SAugustin Cavalier ieee80211_com_lock_t *cl = &(_ic)->ic_comlock; \ 79753c7e08SAugustin Cavalier snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name); \ 80753c7e08SAugustin Cavalier mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE); \ 81753c7e08SAugustin Cavalier } while (0) 82753c7e08SAugustin Cavalier #define IEEE80211_LOCK_OBJ(_ic) (&(_ic)->ic_comlock.mtx) 83753c7e08SAugustin Cavalier #define IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic)) 84753c7e08SAugustin Cavalier #define IEEE80211_LOCK(_ic) mtx_lock(IEEE80211_LOCK_OBJ(_ic)) 85753c7e08SAugustin Cavalier #define IEEE80211_UNLOCK(_ic) mtx_unlock(IEEE80211_LOCK_OBJ(_ic)) 86753c7e08SAugustin Cavalier #define IEEE80211_LOCK_ASSERT(_ic) \ 87753c7e08SAugustin Cavalier mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED) 88753c7e08SAugustin Cavalier #define IEEE80211_UNLOCK_ASSERT(_ic) \ 89753c7e08SAugustin Cavalier mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_NOTOWNED) 90753c7e08SAugustin Cavalier 91753c7e08SAugustin Cavalier /* 92753c7e08SAugustin Cavalier * Transmit lock. 93753c7e08SAugustin Cavalier * 94753c7e08SAugustin Cavalier * This is a (mostly) temporary lock designed to serialise all of the 95753c7e08SAugustin Cavalier * transmission operations throughout the stack. 96753c7e08SAugustin Cavalier */ 97753c7e08SAugustin Cavalier typedef struct { 98753c7e08SAugustin Cavalier char name[16]; /* e.g. "ath0_tx_lock" */ 99753c7e08SAugustin Cavalier struct mtx mtx; 100753c7e08SAugustin Cavalier } ieee80211_tx_lock_t; 101753c7e08SAugustin Cavalier #define IEEE80211_TX_LOCK_INIT(_ic, _name) do { \ 102753c7e08SAugustin Cavalier ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock; \ 103753c7e08SAugustin Cavalier snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name); \ 104753c7e08SAugustin Cavalier mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF); \ 105753c7e08SAugustin Cavalier } while (0) 106753c7e08SAugustin Cavalier #define IEEE80211_TX_LOCK_OBJ(_ic) (&(_ic)->ic_txlock.mtx) 107753c7e08SAugustin Cavalier #define IEEE80211_TX_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic)) 108753c7e08SAugustin Cavalier #define IEEE80211_TX_LOCK(_ic) mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic)) 109753c7e08SAugustin Cavalier #define IEEE80211_TX_UNLOCK(_ic) mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic)) 110753c7e08SAugustin Cavalier #define IEEE80211_TX_LOCK_ASSERT(_ic) \ 111753c7e08SAugustin Cavalier mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED) 112753c7e08SAugustin Cavalier #define IEEE80211_TX_UNLOCK_ASSERT(_ic) \ 113753c7e08SAugustin Cavalier mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED) 114753c7e08SAugustin Cavalier 115753c7e08SAugustin Cavalier /* 116753c7e08SAugustin Cavalier * Stageq / ni_tx_superg lock 117753c7e08SAugustin Cavalier */ 118753c7e08SAugustin Cavalier typedef struct { 119753c7e08SAugustin Cavalier char name[16]; /* e.g. "ath0_ff_lock" */ 120753c7e08SAugustin Cavalier struct mtx mtx; 121753c7e08SAugustin Cavalier } ieee80211_ff_lock_t; 122753c7e08SAugustin Cavalier #define IEEE80211_FF_LOCK_INIT(_ic, _name) do { \ 123753c7e08SAugustin Cavalier ieee80211_ff_lock_t *fl = &(_ic)->ic_fflock; \ 124753c7e08SAugustin Cavalier snprintf(fl->name, sizeof(fl->name), "%s_ff_lock", _name); \ 125753c7e08SAugustin Cavalier mtx_init(&fl->mtx, fl->name, NULL, MTX_DEF); \ 126753c7e08SAugustin Cavalier } while (0) 127753c7e08SAugustin Cavalier #define IEEE80211_FF_LOCK_OBJ(_ic) (&(_ic)->ic_fflock.mtx) 128753c7e08SAugustin Cavalier #define IEEE80211_FF_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_FF_LOCK_OBJ(_ic)) 129753c7e08SAugustin Cavalier #define IEEE80211_FF_LOCK(_ic) mtx_lock(IEEE80211_FF_LOCK_OBJ(_ic)) 130753c7e08SAugustin Cavalier #define IEEE80211_FF_UNLOCK(_ic) mtx_unlock(IEEE80211_FF_LOCK_OBJ(_ic)) 131753c7e08SAugustin Cavalier #define IEEE80211_FF_LOCK_ASSERT(_ic) \ 132753c7e08SAugustin Cavalier mtx_assert(IEEE80211_FF_LOCK_OBJ(_ic), MA_OWNED) 133753c7e08SAugustin Cavalier 134753c7e08SAugustin Cavalier /* 135753c7e08SAugustin Cavalier * Node locking definitions. 136753c7e08SAugustin Cavalier */ 137753c7e08SAugustin Cavalier typedef struct { 138753c7e08SAugustin Cavalier char name[16]; /* e.g. "ath0_node_lock" */ 139753c7e08SAugustin Cavalier struct mtx mtx; 140753c7e08SAugustin Cavalier } ieee80211_node_lock_t; 141753c7e08SAugustin Cavalier #define IEEE80211_NODE_LOCK_INIT(_nt, _name) do { \ 142753c7e08SAugustin Cavalier ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock; \ 143753c7e08SAugustin Cavalier snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name); \ 144753c7e08SAugustin Cavalier mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE); \ 145753c7e08SAugustin Cavalier } while (0) 146753c7e08SAugustin Cavalier #define IEEE80211_NODE_LOCK_OBJ(_nt) (&(_nt)->nt_nodelock.mtx) 147753c7e08SAugustin Cavalier #define IEEE80211_NODE_LOCK_DESTROY(_nt) \ 148753c7e08SAugustin Cavalier mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt)) 149753c7e08SAugustin Cavalier #define IEEE80211_NODE_LOCK(_nt) \ 150753c7e08SAugustin Cavalier mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt)) 151753c7e08SAugustin Cavalier #define IEEE80211_NODE_IS_LOCKED(_nt) \ 152753c7e08SAugustin Cavalier mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt)) 153753c7e08SAugustin Cavalier #define IEEE80211_NODE_UNLOCK(_nt) \ 154753c7e08SAugustin Cavalier mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt)) 155753c7e08SAugustin Cavalier #define IEEE80211_NODE_LOCK_ASSERT(_nt) \ 156753c7e08SAugustin Cavalier mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED) 157753c7e08SAugustin Cavalier 158753c7e08SAugustin Cavalier /* 159753c7e08SAugustin Cavalier * Node table iteration locking definitions; this protects the 160753c7e08SAugustin Cavalier * scan generation # used to iterate over the station table 161753c7e08SAugustin Cavalier * while grabbing+releasing the node lock. 162753c7e08SAugustin Cavalier */ 163753c7e08SAugustin Cavalier typedef struct { 164753c7e08SAugustin Cavalier char name[16]; /* e.g. "ath0_scan_lock" */ 165753c7e08SAugustin Cavalier struct mtx mtx; 166753c7e08SAugustin Cavalier } ieee80211_scan_lock_t; 167753c7e08SAugustin Cavalier #define IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do { \ 168753c7e08SAugustin Cavalier ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock; \ 169753c7e08SAugustin Cavalier snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name); \ 170753c7e08SAugustin Cavalier mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF); \ 171753c7e08SAugustin Cavalier } while (0) 172753c7e08SAugustin Cavalier #define IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt) (&(_nt)->nt_scanlock.mtx) 173753c7e08SAugustin Cavalier #define IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \ 174753c7e08SAugustin Cavalier mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) 175753c7e08SAugustin Cavalier #define IEEE80211_NODE_ITERATE_LOCK(_nt) \ 176753c7e08SAugustin Cavalier mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) 177753c7e08SAugustin Cavalier #define IEEE80211_NODE_ITERATE_UNLOCK(_nt) \ 178753c7e08SAugustin Cavalier mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) 179753c7e08SAugustin Cavalier 180753c7e08SAugustin Cavalier /* 181753c7e08SAugustin Cavalier * Power-save queue definitions. 182753c7e08SAugustin Cavalier */ 183753c7e08SAugustin Cavalier typedef struct mtx ieee80211_psq_lock_t; 184753c7e08SAugustin Cavalier #define IEEE80211_PSQ_INIT(_psq, _name) \ 185753c7e08SAugustin Cavalier mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF) 186753c7e08SAugustin Cavalier #define IEEE80211_PSQ_DESTROY(_psq) mtx_destroy(&(_psq)->psq_lock) 187753c7e08SAugustin Cavalier #define IEEE80211_PSQ_LOCK(_psq) mtx_lock(&(_psq)->psq_lock) 188753c7e08SAugustin Cavalier #define IEEE80211_PSQ_UNLOCK(_psq) mtx_unlock(&(_psq)->psq_lock) 189753c7e08SAugustin Cavalier 190753c7e08SAugustin Cavalier #ifndef IF_PREPEND_LIST 191753c7e08SAugustin Cavalier #define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \ 192753c7e08SAugustin Cavalier (mtail)->m_nextpkt = (ifq)->ifq_head; \ 193753c7e08SAugustin Cavalier if ((ifq)->ifq_tail == NULL) \ 194753c7e08SAugustin Cavalier (ifq)->ifq_tail = (mtail); \ 195753c7e08SAugustin Cavalier (ifq)->ifq_head = (mhead); \ 196753c7e08SAugustin Cavalier (ifq)->ifq_len += (mcount); \ 197753c7e08SAugustin Cavalier } while (0) 198753c7e08SAugustin Cavalier #define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \ 199753c7e08SAugustin Cavalier IF_LOCK(ifq); \ 200753c7e08SAugustin Cavalier _IF_PREPEND_LIST(ifq, mhead, mtail, mcount); \ 201753c7e08SAugustin Cavalier IF_UNLOCK(ifq); \ 202753c7e08SAugustin Cavalier } while (0) 203753c7e08SAugustin Cavalier #endif /* IF_PREPEND_LIST */ 204753c7e08SAugustin Cavalier 205753c7e08SAugustin Cavalier /* 206753c7e08SAugustin Cavalier * Age queue definitions. 207753c7e08SAugustin Cavalier */ 208753c7e08SAugustin Cavalier typedef struct mtx ieee80211_ageq_lock_t; 209753c7e08SAugustin Cavalier #define IEEE80211_AGEQ_INIT(_aq, _name) \ 210753c7e08SAugustin Cavalier mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF) 211753c7e08SAugustin Cavalier #define IEEE80211_AGEQ_DESTROY(_aq) mtx_destroy(&(_aq)->aq_lock) 212753c7e08SAugustin Cavalier #define IEEE80211_AGEQ_LOCK(_aq) mtx_lock(&(_aq)->aq_lock) 213753c7e08SAugustin Cavalier #define IEEE80211_AGEQ_UNLOCK(_aq) mtx_unlock(&(_aq)->aq_lock) 214753c7e08SAugustin Cavalier 215753c7e08SAugustin Cavalier /* 216753c7e08SAugustin Cavalier * Scan table definitions. 217753c7e08SAugustin Cavalier */ 218753c7e08SAugustin Cavalier typedef struct mtx ieee80211_scan_table_lock_t; 219753c7e08SAugustin Cavalier #define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \ 220753c7e08SAugustin Cavalier mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF) 221753c7e08SAugustin Cavalier #define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock) 222753c7e08SAugustin Cavalier #define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock) 223753c7e08SAugustin Cavalier #define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock) 224753c7e08SAugustin Cavalier 225753c7e08SAugustin Cavalier typedef struct mtx ieee80211_scan_iter_lock_t; 226753c7e08SAugustin Cavalier #define IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \ 227753c7e08SAugustin Cavalier mtx_init(&(_st)->st_scanlock, _name, "802.11 scangen", MTX_DEF) 228753c7e08SAugustin Cavalier #define IEEE80211_SCAN_ITER_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_scanlock) 229753c7e08SAugustin Cavalier #define IEEE80211_SCAN_ITER_LOCK(_st) mtx_lock(&(_st)->st_scanlock) 230753c7e08SAugustin Cavalier #define IEEE80211_SCAN_ITER_UNLOCK(_st) mtx_unlock(&(_st)->st_scanlock) 231753c7e08SAugustin Cavalier 232753c7e08SAugustin Cavalier /* 233753c7e08SAugustin Cavalier * Mesh node/routing definitions. 234753c7e08SAugustin Cavalier */ 235753c7e08SAugustin Cavalier typedef struct mtx ieee80211_rte_lock_t; 236753c7e08SAugustin Cavalier #define MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \ 237753c7e08SAugustin Cavalier mtx_init(&(rt)->rt_lock, _name, "802.11s route entry", MTX_DEF) 238753c7e08SAugustin Cavalier #define MESH_RT_ENTRY_LOCK_DESTROY(_rt) \ 239753c7e08SAugustin Cavalier mtx_destroy(&(_rt)->rt_lock) 240753c7e08SAugustin Cavalier #define MESH_RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock) 241753c7e08SAugustin Cavalier #define MESH_RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED) 242753c7e08SAugustin Cavalier #define MESH_RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock) 243753c7e08SAugustin Cavalier 244753c7e08SAugustin Cavalier typedef struct mtx ieee80211_rt_lock_t; 245753c7e08SAugustin Cavalier #define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock) 246753c7e08SAugustin Cavalier #define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED) 247753c7e08SAugustin Cavalier #define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock) 248753c7e08SAugustin Cavalier #define MESH_RT_LOCK_INIT(ms, name) \ 249753c7e08SAugustin Cavalier mtx_init(&(ms)->ms_rt_lock, name, "802.11s routing table", MTX_DEF) 250753c7e08SAugustin Cavalier #define MESH_RT_LOCK_DESTROY(ms) \ 251753c7e08SAugustin Cavalier mtx_destroy(&(ms)->ms_rt_lock) 252753c7e08SAugustin Cavalier 253753c7e08SAugustin Cavalier /* 254753c7e08SAugustin Cavalier * Node reference counting definitions. 255753c7e08SAugustin Cavalier * 256753c7e08SAugustin Cavalier * ieee80211_node_initref initialize the reference count to 1 257753c7e08SAugustin Cavalier * ieee80211_node_incref add a reference 258753c7e08SAugustin Cavalier * ieee80211_node_decref remove a reference 259753c7e08SAugustin Cavalier * ieee80211_node_dectestref remove a reference and return 1 if this 260753c7e08SAugustin Cavalier * is the last reference, otherwise 0 261753c7e08SAugustin Cavalier * ieee80211_node_refcnt reference count for printing (only) 262753c7e08SAugustin Cavalier */ 263753c7e08SAugustin Cavalier #include <machine/atomic.h> 264753c7e08SAugustin Cavalier 2655cad57c4SJérôme Duval struct ieee80211vap; 2665cad57c4SJérôme Duval int ieee80211_com_vincref(struct ieee80211vap *); 2675cad57c4SJérôme Duval void ieee80211_com_vdecref(struct ieee80211vap *); 2685cad57c4SJérôme Duval void ieee80211_com_vdetach(struct ieee80211vap *); 2695cad57c4SJérôme Duval 270753c7e08SAugustin Cavalier #define ieee80211_node_initref(_ni) \ 271753c7e08SAugustin Cavalier do { ((_ni)->ni_refcnt = 1); } while (0) 272753c7e08SAugustin Cavalier #define ieee80211_node_incref(_ni) \ 273753c7e08SAugustin Cavalier atomic_add_int(&(_ni)->ni_refcnt, 1) 274753c7e08SAugustin Cavalier #define ieee80211_node_decref(_ni) \ 275753c7e08SAugustin Cavalier atomic_subtract_int(&(_ni)->ni_refcnt, 1) 276753c7e08SAugustin Cavalier struct ieee80211_node; 277753c7e08SAugustin Cavalier int ieee80211_node_dectestref(struct ieee80211_node *ni); 278753c7e08SAugustin Cavalier #define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt 279753c7e08SAugustin Cavalier 280753c7e08SAugustin Cavalier struct ifqueue; 281753c7e08SAugustin Cavalier void ieee80211_drain_ifq(struct ifqueue *); 282753c7e08SAugustin Cavalier void ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *); 283753c7e08SAugustin Cavalier 284753c7e08SAugustin Cavalier void ieee80211_vap_destroy(struct ieee80211vap *); 2855cad57c4SJérôme Duval const char * ieee80211_get_vap_ifname(struct ieee80211vap *); 286753c7e08SAugustin Cavalier 287753c7e08SAugustin Cavalier #define IFNET_IS_UP_RUNNING(_ifp) \ 288753c7e08SAugustin Cavalier (((_ifp)->if_flags & IFF_UP) && \ 289753c7e08SAugustin Cavalier ((_ifp)->if_drv_flags & IFF_DRV_RUNNING)) 290753c7e08SAugustin Cavalier 291c70ec71dSAugustin Cavalier #define msecs_to_ticks(ms) MSEC_2_TICKS(ms) 292c70ec71dSAugustin Cavalier #define ticks_to_msecs(t) TICKS_2_MSEC(t) 293753c7e08SAugustin Cavalier #define ticks_to_secs(t) ((t) / hz) 2946d0f2b48SAugustin Cavalier 2955cad57c4SJérôme Duval #define ieee80211_time_after(a,b) ((int)(b) - (int)(a) < 0) 296753c7e08SAugustin Cavalier #define ieee80211_time_before(a,b) ieee80211_time_after(b,a) 2975cad57c4SJérôme Duval #define ieee80211_time_after_eq(a,b) ((int)(a) - (int)(b) >= 0) 298753c7e08SAugustin Cavalier #define ieee80211_time_before_eq(a,b) ieee80211_time_after_eq(b,a) 299753c7e08SAugustin Cavalier 300753c7e08SAugustin Cavalier struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen); 301753c7e08SAugustin Cavalier 302753c7e08SAugustin Cavalier /* tx path usage */ 303753c7e08SAugustin Cavalier #define M_ENCAP M_PROTO1 /* 802.11 encap done */ 304753c7e08SAugustin Cavalier #define M_EAPOL M_PROTO3 /* PAE/EAPOL frame */ 305753c7e08SAugustin Cavalier #define M_PWR_SAV M_PROTO4 /* bypass PS handling */ 306753c7e08SAugustin Cavalier #define M_MORE_DATA M_PROTO5 /* more data frames to follow */ 3076d0f2b48SAugustin Cavalier #define M_FF M_PROTO6 /* fast frame / A-MSDU */ 308753c7e08SAugustin Cavalier #define M_TXCB M_PROTO7 /* do tx complete callback */ 309753c7e08SAugustin Cavalier #define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */ 310753c7e08SAugustin Cavalier #define M_FRAG M_PROTO9 /* frame fragmentation */ 311753c7e08SAugustin Cavalier #define M_FIRSTFRAG M_PROTO10 /* first frame fragment */ 312753c7e08SAugustin Cavalier #define M_LASTFRAG M_PROTO11 /* last frame fragment */ 3136d0f2b48SAugustin Cavalier 314753c7e08SAugustin Cavalier #define M_80211_TX \ 3156d0f2b48SAugustin Cavalier (M_ENCAP|M_EAPOL|M_PWR_SAV|M_MORE_DATA|M_FF|M_TXCB| \ 3166d0f2b48SAugustin Cavalier M_AMPDU_MPDU|M_FRAG|M_FIRSTFRAG|M_LASTFRAG) 317753c7e08SAugustin Cavalier 318753c7e08SAugustin Cavalier /* rx path usage */ 319753c7e08SAugustin Cavalier #define M_AMPDU M_PROTO1 /* A-MPDU subframe */ 320753c7e08SAugustin Cavalier #define M_WEP M_PROTO2 /* WEP done by hardware */ 321753c7e08SAugustin Cavalier #if 0 322753c7e08SAugustin Cavalier #define M_AMPDU_MPDU M_PROTO8 /* A-MPDU re-order done */ 323753c7e08SAugustin Cavalier #endif 324753c7e08SAugustin Cavalier #define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU) 325753c7e08SAugustin Cavalier 3266d0f2b48SAugustin Cavalier #define IEEE80211_MBUF_TX_FLAG_BITS \ 3276d0f2b48SAugustin Cavalier M_FLAG_BITS \ 3286d0f2b48SAugustin Cavalier "\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \ 3296d0f2b48SAugustin Cavalier "\24M_AMPDU_MPDU\25M_FRAG\26M_FIRSTFRAG\27M_LASTFRAG" 3306d0f2b48SAugustin Cavalier 3316d0f2b48SAugustin Cavalier #define IEEE80211_MBUF_RX_FLAG_BITS \ 3326d0f2b48SAugustin Cavalier M_FLAG_BITS \ 3336d0f2b48SAugustin Cavalier "\15M_AMPDU\16M_WEP\24M_AMPDU_MPDU" 3346d0f2b48SAugustin Cavalier 335753c7e08SAugustin Cavalier /* 336753c7e08SAugustin Cavalier * Store WME access control bits in the vlan tag. 337753c7e08SAugustin Cavalier * This is safe since it's done after the packet is classified 338753c7e08SAugustin Cavalier * (where we use any previous tag) and because it's passed 339753c7e08SAugustin Cavalier * directly in to the driver and there's no chance someone 340753c7e08SAugustin Cavalier * else will clobber them on us. 341753c7e08SAugustin Cavalier */ 342753c7e08SAugustin Cavalier #define M_WME_SETAC(m, ac) \ 343753c7e08SAugustin Cavalier ((m)->m_pkthdr.ether_vtag = (ac)) 344753c7e08SAugustin Cavalier #define M_WME_GETAC(m) ((m)->m_pkthdr.ether_vtag) 345753c7e08SAugustin Cavalier 346753c7e08SAugustin Cavalier /* 347753c7e08SAugustin Cavalier * Mbufs on the power save queue are tagged with an age and 348753c7e08SAugustin Cavalier * timed out. We reuse the hardware checksum field in the 349753c7e08SAugustin Cavalier * mbuf packet header to store this data. 350753c7e08SAugustin Cavalier */ 351753c7e08SAugustin Cavalier #define M_AGE_SET(m,v) (m->m_pkthdr.csum_data = v) 352753c7e08SAugustin Cavalier #define M_AGE_GET(m) (m->m_pkthdr.csum_data) 353753c7e08SAugustin Cavalier #define M_AGE_SUB(m,adj) (m->m_pkthdr.csum_data -= adj) 354753c7e08SAugustin Cavalier 355753c7e08SAugustin Cavalier /* 356753c7e08SAugustin Cavalier * Store the sequence number. 357753c7e08SAugustin Cavalier */ 358753c7e08SAugustin Cavalier #define M_SEQNO_SET(m, seqno) \ 359753c7e08SAugustin Cavalier ((m)->m_pkthdr.tso_segsz = (seqno)) 360753c7e08SAugustin Cavalier #define M_SEQNO_GET(m) ((m)->m_pkthdr.tso_segsz) 361753c7e08SAugustin Cavalier 362753c7e08SAugustin Cavalier #define MTAG_ABI_NET80211 1132948340 /* net80211 ABI */ 363753c7e08SAugustin Cavalier 364753c7e08SAugustin Cavalier struct ieee80211_cb { 365753c7e08SAugustin Cavalier void (*func)(struct ieee80211_node *, void *, int status); 366753c7e08SAugustin Cavalier void *arg; 367753c7e08SAugustin Cavalier }; 368753c7e08SAugustin Cavalier #define NET80211_TAG_CALLBACK 0 /* xmit complete callback */ 369cf552543SAugustin Cavalier #define NET80211_TAG_XMIT_PARAMS 1 370cf552543SAugustin Cavalier /* See below; this is after the bpf_params definition */ 371753c7e08SAugustin Cavalier #define NET80211_TAG_RECV_PARAMS 2 372cf552543SAugustin Cavalier #define NET80211_TAG_TOA_PARAMS 3 373753c7e08SAugustin Cavalier 374753c7e08SAugustin Cavalier int ieee80211_add_callback(struct mbuf *m, 375753c7e08SAugustin Cavalier void (*func)(struct ieee80211_node *, void *, int), void *arg); 376753c7e08SAugustin Cavalier void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int); 377753c7e08SAugustin Cavalier 378753c7e08SAugustin Cavalier void get_random_bytes(void *, size_t); 379753c7e08SAugustin Cavalier 380753c7e08SAugustin Cavalier struct ieee80211com; 381753c7e08SAugustin Cavalier 382753c7e08SAugustin Cavalier int ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m); 383753c7e08SAugustin Cavalier int ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m); 384753c7e08SAugustin Cavalier 385*86021fd4SAugustin Cavalier void net80211_get_random_bytes(void *, size_t); 386*86021fd4SAugustin Cavalier 387753c7e08SAugustin Cavalier void ieee80211_sysctl_attach(struct ieee80211com *); 388753c7e08SAugustin Cavalier void ieee80211_sysctl_detach(struct ieee80211com *); 389753c7e08SAugustin Cavalier void ieee80211_sysctl_vattach(struct ieee80211vap *); 390753c7e08SAugustin Cavalier void ieee80211_sysctl_vdetach(struct ieee80211vap *); 391753c7e08SAugustin Cavalier 392753c7e08SAugustin Cavalier void ieee80211_load_module(const char *); 393753c7e08SAugustin Cavalier 394753c7e08SAugustin Cavalier /* 395753c7e08SAugustin Cavalier * A "policy module" is an adjunct module to net80211 that provides 396753c7e08SAugustin Cavalier * functionality that typically includes policy decisions. This 397753c7e08SAugustin Cavalier * modularity enables extensibility and vendor-supplied functionality. 398753c7e08SAugustin Cavalier */ 3996d0f2b48SAugustin Cavalier #define _IEEE80211_POLICY_MODULE(policy, name, version, load, unload) \ 4006d0f2b48SAugustin Cavalier static void ieee80211_##policy##_##name##_load() { load; } \ 4016d0f2b48SAugustin Cavalier static void ieee80211_##policy##_##name##_unload() { unload; } \ 4026d0f2b48SAugustin Cavalier SYSINIT(ieee80211_##policy##_##name, SI_SUB_DRIVERS, SI_ORDER_ANY, \ 4036d0f2b48SAugustin Cavalier ieee80211_##policy##_##name##_load, NULL); \ 4046d0f2b48SAugustin Cavalier SYSUNINIT(ieee80211_##policy##_##name, SI_SUB_DRIVERS, SI_ORDER_ANY, \ 4056d0f2b48SAugustin Cavalier ieee80211_##policy##_##name##_unload, NULL) 406753c7e08SAugustin Cavalier 407753c7e08SAugustin Cavalier /* 408753c7e08SAugustin Cavalier * Authenticator modules handle 802.1x/WPA authentication. 409753c7e08SAugustin Cavalier */ 4106d0f2b48SAugustin Cavalier #define IEEE80211_AUTH_MODULE(name, version) 411753c7e08SAugustin Cavalier #define IEEE80211_AUTH_ALG(name, alg, v) \ 4126d0f2b48SAugustin Cavalier _IEEE80211_POLICY_MODULE(auth, alg, v, \ 4136d0f2b48SAugustin Cavalier ieee80211_authenticator_register(alg, &v), \ 4146d0f2b48SAugustin Cavalier ieee80211_authenticator_unregister(alg)) 4156d0f2b48SAugustin Cavalier 4166d0f2b48SAugustin Cavalier /* 4176d0f2b48SAugustin Cavalier * Crypto modules implement cipher support. 4186d0f2b48SAugustin Cavalier */ 4196d0f2b48SAugustin Cavalier #define IEEE80211_CRYPTO_MODULE(name, version) \ 4206d0f2b48SAugustin Cavalier _IEEE80211_POLICY_MODULE(crypto, name, version, \ 4216d0f2b48SAugustin Cavalier ieee80211_crypto_register(&name), \ 4226d0f2b48SAugustin Cavalier ieee80211_crypto_unregister(&name)) 423753c7e08SAugustin Cavalier 424753c7e08SAugustin Cavalier /* 425753c7e08SAugustin Cavalier * Scanner modules provide scanning policy. 426753c7e08SAugustin Cavalier */ 427753c7e08SAugustin Cavalier #define IEEE80211_SCANNER_MODULE(name, version) 4286d0f2b48SAugustin Cavalier #define IEEE80211_SCANNER_ALG(name, alg, v) \ 4296d0f2b48SAugustin Cavalier _IEEE80211_POLICY_MODULE(scan, alg, v, \ 4306d0f2b48SAugustin Cavalier ieee80211_scanner_register(alg, &v), \ 4316d0f2b48SAugustin Cavalier ieee80211_scanner_unregister(alg, &v)) 432753c7e08SAugustin Cavalier 433753c7e08SAugustin Cavalier /* 434753c7e08SAugustin Cavalier * Rate control modules provide tx rate control support. 435753c7e08SAugustin Cavalier */ 4366d0f2b48SAugustin Cavalier #define IEEE80211_RATECTL_MODULE(alg, version) 437753c7e08SAugustin Cavalier #define IEEE80211_RATECTL_ALG(name, alg, v) \ 4386d0f2b48SAugustin Cavalier _IEEE80211_POLICY_MODULE(ratectl, alg, v, \ 4396d0f2b48SAugustin Cavalier ieee80211_ratectl_register(alg, &v), \ 4406d0f2b48SAugustin Cavalier ieee80211_ratectl_unregister(alg)) 441753c7e08SAugustin Cavalier 442753c7e08SAugustin Cavalier 443753c7e08SAugustin Cavalier struct ieee80211req; 444753c7e08SAugustin Cavalier typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *, 445753c7e08SAugustin Cavalier struct ieee80211req *); 446753c7e08SAugustin Cavalier SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc); 447753c7e08SAugustin Cavalier #define IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get) 448753c7e08SAugustin Cavalier 449753c7e08SAugustin Cavalier typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *, 450753c7e08SAugustin Cavalier struct ieee80211req *); 451753c7e08SAugustin Cavalier SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc); 452753c7e08SAugustin Cavalier #define IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set) 453753c7e08SAugustin Cavalier 4545cad57c4SJérôme Duval #ifdef DEBUGNET 4555cad57c4SJérôme Duval typedef void debugnet80211_init_t(struct ieee80211com *, int *nrxr, int *ncl, 4565cad57c4SJérôme Duval int *clsize); 4575cad57c4SJérôme Duval typedef void debugnet80211_event_t(struct ieee80211com *, enum debugnet_ev); 4585cad57c4SJérôme Duval typedef int debugnet80211_poll_t(struct ieee80211com *, int); 4595cad57c4SJérôme Duval 4605cad57c4SJérôme Duval struct debugnet80211_methods { 4615cad57c4SJérôme Duval debugnet80211_init_t *dn8_init; 4625cad57c4SJérôme Duval debugnet80211_event_t *dn8_event; 4635cad57c4SJérôme Duval debugnet80211_poll_t *dn8_poll; 4645cad57c4SJérôme Duval }; 4655cad57c4SJérôme Duval 4665cad57c4SJérôme Duval #define DEBUGNET80211_DEFINE(driver) \ 4675cad57c4SJérôme Duval static debugnet80211_init_t driver##_debugnet80211_init; \ 4685cad57c4SJérôme Duval static debugnet80211_event_t driver##_debugnet80211_event; \ 4695cad57c4SJérôme Duval static debugnet80211_poll_t driver##_debugnet80211_poll; \ 4705cad57c4SJérôme Duval \ 4715cad57c4SJérôme Duval static struct debugnet80211_methods driver##_debugnet80211_methods = { \ 4725cad57c4SJérôme Duval .dn8_init = driver##_debugnet80211_init, \ 4735cad57c4SJérôme Duval .dn8_event = driver##_debugnet80211_event, \ 4745cad57c4SJérôme Duval .dn8_poll = driver##_debugnet80211_poll, \ 4755cad57c4SJérôme Duval } 4765cad57c4SJérôme Duval #define DEBUGNET80211_SET(ic, driver) \ 4775cad57c4SJérôme Duval (ic)->ic_debugnet_meth = &driver##_debugnet80211_methods 4785cad57c4SJérôme Duval #else 4795cad57c4SJérôme Duval #define DEBUGNET80211_DEFINE(driver) 4805cad57c4SJérôme Duval #define DEBUGNET80211_SET(ic, driver) 4815cad57c4SJérôme Duval #endif /* DEBUGNET */ 4825cad57c4SJérôme Duval 483753c7e08SAugustin Cavalier /* 484753c7e08SAugustin Cavalier * Structure prepended to raw packets sent through the bpf 485753c7e08SAugustin Cavalier * interface when set to DLT_IEEE802_11_RADIO. This allows 486753c7e08SAugustin Cavalier * user applications to specify pretty much everything in 487753c7e08SAugustin Cavalier * an Atheros tx descriptor. XXX need to generalize. 488753c7e08SAugustin Cavalier * 489753c7e08SAugustin Cavalier * XXX cannot be more than 14 bytes as it is copied to a sockaddr's 490753c7e08SAugustin Cavalier * XXX sa_data area. 491753c7e08SAugustin Cavalier */ 492753c7e08SAugustin Cavalier struct ieee80211_bpf_params { 493753c7e08SAugustin Cavalier uint8_t ibp_vers; /* version */ 494753c7e08SAugustin Cavalier #define IEEE80211_BPF_VERSION 0 495753c7e08SAugustin Cavalier uint8_t ibp_len; /* header length in bytes */ 496753c7e08SAugustin Cavalier uint8_t ibp_flags; 497753c7e08SAugustin Cavalier #define IEEE80211_BPF_SHORTPRE 0x01 /* tx with short preamble */ 498753c7e08SAugustin Cavalier #define IEEE80211_BPF_NOACK 0x02 /* tx with no ack */ 499753c7e08SAugustin Cavalier #define IEEE80211_BPF_CRYPTO 0x04 /* tx with h/w encryption */ 500753c7e08SAugustin Cavalier #define IEEE80211_BPF_FCS 0x10 /* frame incldues FCS */ 501753c7e08SAugustin Cavalier #define IEEE80211_BPF_DATAPAD 0x20 /* frame includes data padding */ 502753c7e08SAugustin Cavalier #define IEEE80211_BPF_RTS 0x40 /* tx with RTS/CTS */ 503753c7e08SAugustin Cavalier #define IEEE80211_BPF_CTS 0x80 /* tx with CTS only */ 504753c7e08SAugustin Cavalier uint8_t ibp_pri; /* WME/WMM AC+tx antenna */ 505753c7e08SAugustin Cavalier uint8_t ibp_try0; /* series 1 try count */ 506753c7e08SAugustin Cavalier uint8_t ibp_rate0; /* series 1 IEEE tx rate */ 507753c7e08SAugustin Cavalier uint8_t ibp_power; /* tx power (device units) */ 508753c7e08SAugustin Cavalier uint8_t ibp_ctsrate; /* IEEE tx rate for CTS */ 509753c7e08SAugustin Cavalier uint8_t ibp_try1; /* series 2 try count */ 510753c7e08SAugustin Cavalier uint8_t ibp_rate1; /* series 2 IEEE tx rate */ 511753c7e08SAugustin Cavalier uint8_t ibp_try2; /* series 3 try count */ 512753c7e08SAugustin Cavalier uint8_t ibp_rate2; /* series 3 IEEE tx rate */ 513753c7e08SAugustin Cavalier uint8_t ibp_try3; /* series 4 try count */ 514753c7e08SAugustin Cavalier uint8_t ibp_rate3; /* series 4 IEEE tx rate */ 515753c7e08SAugustin Cavalier }; 516753c7e08SAugustin Cavalier 517753c7e08SAugustin Cavalier int ieee80211_add_xmit_params(struct mbuf *m, const struct ieee80211_bpf_params *params); 518753c7e08SAugustin Cavalier int ieee80211_get_xmit_params(struct mbuf *m, struct ieee80211_bpf_params *params); 519753c7e08SAugustin Cavalier 520753c7e08SAugustin Cavalier struct ieee80211_tx_params { 521753c7e08SAugustin Cavalier struct ieee80211_bpf_params params; 522753c7e08SAugustin Cavalier }; 523753c7e08SAugustin Cavalier 5246d0f2b48SAugustin Cavalier struct ieee80211_rx_params; 5256d0f2b48SAugustin Cavalier struct ieee80211_rx_stats; 526753c7e08SAugustin Cavalier 527753c7e08SAugustin Cavalier int ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs); 528753c7e08SAugustin Cavalier int ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs); 5296d0f2b48SAugustin Cavalier const struct ieee80211_rx_stats * ieee80211_get_rx_params_ptr(struct mbuf *m); 530753c7e08SAugustin Cavalier 531cf552543SAugustin Cavalier struct ieee80211_toa_params { 532cf552543SAugustin Cavalier int request_id; 533cf552543SAugustin Cavalier }; 534cf552543SAugustin Cavalier int ieee80211_add_toa_params(struct mbuf *m, const struct ieee80211_toa_params *p); 535cf552543SAugustin Cavalier int ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p); 536cf552543SAugustin Cavalier 537753c7e08SAugustin Cavalier #ifdef __cplusplus 538753c7e08SAugustin Cavalier } 539753c7e08SAugustin Cavalier #endif 540753c7e08SAugustin Cavalier #endif /* _KERNEL */ 541753c7e08SAugustin Cavalier 542753c7e08SAugustin Cavalier #define IEEE80211_MALLOC malloc 543753c7e08SAugustin Cavalier #define IEEE80211_FREE free 544753c7e08SAugustin Cavalier 545753c7e08SAugustin Cavalier /* XXX TODO: get rid of WAITOK, fix all the users of it? */ 546753c7e08SAugustin Cavalier #define IEEE80211_M_NOWAIT M_NOWAIT 547753c7e08SAugustin Cavalier #define IEEE80211_M_WAITOK M_WAITOK 548753c7e08SAugustin Cavalier #define IEEE80211_M_ZERO M_ZERO 549753c7e08SAugustin Cavalier 550753c7e08SAugustin Cavalier #endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */ 551