ieee80211_netbsd.h revision 1.14.4.3 1 /* $NetBSD: ieee80211_netbsd.h,v 1.14.4.3 2008/02/23 14:31:31 skrll Exp $ */
2 /*-
3 * Copyright (c) 2003-2005 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: src/sys/net80211/ieee80211_freebsd.h,v 1.6 2005/08/08 18:46:36 sam Exp $
29 */
30 #ifndef _NET80211_IEEE80211_NETBSD_H_
31 #define _NET80211_IEEE80211_NETBSD_H_
32
33 #ifdef _KERNEL
34 #define IASSERT(__cond, __complaint) \
35 do { \
36 if (!(__cond)) \
37 panic __complaint ; \
38 } while (/*CONSTCOND*/0)
39
40 void if_printf(struct ifnet *, const char *, ...)
41 __attribute__((__format__(__printf__,2,3)));
42
43 #define IEEE80211_LOCK_INIT_IMPL(_ic, _name, _member) \
44 mutex_init(&(_ic)->_member, MUTEX_DEFAULT, IPL_NET)
45 #define IEEE80211_LOCK_IMPL(_ic, _member) \
46 mutex_enter(&(_ic)->_member)
47 #define IEEE80211_IS_LOCKED_IMPL(_ic, _member) \
48 mutex_owned(&(_ic)->_member)
49 #define IEEE80211_UNLOCK_IMPL(_ic, _member) \
50 mutex_exit(&(_ic)->_member)
51 #define IEEE80211_LOCK_ASSERT_IMPL(_ic, _member) \
52 IASSERT(mutex_owned(&(_ic)->_member), \
53 ("%s: IEEE80211_LOCK not held", __func__))
54 #define IEEE80211_LOCK_DESTROY_IMPL(_ic, _member) \
55 mutex_destroy(&(_ic)->_member)
56
57 /*
58 * Common state locking definitions.
59 */
60 typedef kmutex_t ieee80211_com_lock_t;
61 #define IEEE80211_LOCK_INIT(_ic, _name) \
62 IEEE80211_LOCK_INIT_IMPL(_ic, _name, ic_comlock)
63 #define IEEE80211_LOCK_DESTROY(_ic) \
64 IEEE80211_LOCK_DESTROY_IMPL(_ic, ic_comlock)
65 #define IEEE80211_LOCK(_ic) \
66 IEEE80211_LOCK_IMPL(_ic, ic_comlock)
67 #define IEEE80211_UNLOCK(_ic)\
68 IEEE80211_UNLOCK_IMPL(_ic, ic_comlock)
69 #define IEEE80211_LOCK_ASSERT(_ic) \
70 IEEE80211_LOCK_ASSERT_IMPL(_ic, ic_comlock)
71
72 /*
73 * Beacon locking definitions.
74 */
75 typedef kmutex_t ieee80211_beacon_lock_t;
76 #define IEEE80211_BEACON_LOCK_INIT(_ic, _name) \
77 IEEE80211_LOCK_INIT_IMPL(_ic, _name, ic_beaconlock)
78 #define IEEE80211_BEACON_LOCK_DESTROY(_ic) \
79 IEEE80211_LOCK_DESTROY_IMPL(_ic, ic_beaconlock)
80 #define IEEE80211_BEACON_LOCK(_ic) \
81 IEEE80211_LOCK_IMPL(_ic, ic_beaconlock)
82 #define IEEE80211_BEACON_UNLOCK(_ic) \
83 IEEE80211_UNLOCK_IMPL(_ic, ic_beaconlock)
84 #define IEEE80211_BEACON_LOCK_ASSERT(_ic) \
85 IEEE80211_LOCK_ASSERT_IMPL(_ic, ic_beaconlock)
86
87 /*
88 * Node locking definitions.
89 * NB: MTX_DUPOK is because we don't generate per-interface strings.
90 */
91 typedef kmutex_t ieee80211_node_lock_t;
92 #define IEEE80211_NODE_LOCK_INIT(_nt, _name) \
93 IEEE80211_LOCK_INIT_IMPL(_nt, _name, nt_nodelock)
94 #define IEEE80211_NODE_LOCK_DESTROY(_nt) \
95 IEEE80211_LOCK_DESTROY_IMPL(_nt, nt_nodelock)
96 #define IEEE80211_NODE_LOCK(_nt) \
97 IEEE80211_LOCK_IMPL(_nt, nt_nodelock)
98 #define IEEE80211_NODE_IS_LOCKED(_nt) \
99 IEEE80211_IS_LOCKED_IMPL(_nt, nt_nodelock)
100 #define IEEE80211_NODE_UNLOCK(_nt) \
101 IEEE80211_UNLOCK_IMPL(_nt, nt_nodelock)
102 #define IEEE80211_NODE_LOCK_ASSERT(_nt) \
103 IEEE80211_LOCK_ASSERT_IMPL(_nt, nt_nodelock)
104
105 /*
106 * Node table scangen locking definitions.
107 */
108 typedef kmutex_t ieee80211_scan_lock_t;
109 #define IEEE80211_SCAN_LOCK_INIT(_nt, _name) \
110 IEEE80211_LOCK_INIT_IMPL(_nt, _name, nt_scanlock)
111 #define IEEE80211_SCAN_LOCK_DESTROY(_nt) \
112 IEEE80211_LOCK_DESTROY_IMPL(_nt, nt_scanlock)
113 #define IEEE80211_SCAN_LOCK(_nt) \
114 IEEE80211_LOCK_IMPL(_nt, nt_scanlock)
115 #define IEEE80211_SCAN_UNLOCK(_nt) \
116 IEEE80211_UNLOCK_IMPL(_nt, nt_scanlock)
117 #define IEEE80211_SCAN_LOCK_ASSERT(_nt) \
118 IEEE80211_LOCK_ASSERT_IMPL(_nt, nt_scanlock)
119
120 /*
121 * Scan table locking definitions.
122 */
123 typedef kmutex_t ieee80211_scantable_lock_t;
124 #define IEEE80211_SCANTABLE_LOCK_INIT(_st, _name) \
125 IEEE80211_LOCK_INIT_IMPL(_st, _name, st_lock)
126 #define IEEE80211_SCANTABLE_LOCK_DESTROY(_st) \
127 IEEE80211_LOCK_DESTROY_IMPL(_st, st_lock)
128 #define IEEE80211_SCANTABLE_LOCK(_st) \
129 IEEE80211_LOCK_IMPL(_st, st_lock)
130 #define IEEE80211_SCANTABLE_UNLOCK(_st) \
131 IEEE80211_UNLOCK_IMPL(_st, st_lock)
132 #define IEEE80211_SCANTABLE_LOCK_ASSERT(_st) \
133 IEEE80211_LOCK_ASSERT_IMPL(_st, st_lock)
134
135 /*
136 * Scan table scangen locking definitions.
137 */
138 typedef kmutex_t ieee80211_scangen_lock_t;
139 #define IEEE80211_SCANGEN_LOCK_INIT(_st, _name) \
140 IEEE80211_LOCK_INIT_IMPL(_st, _name, st_scanlock)
141 #define IEEE80211_SCANGEN_LOCK_DESTROY(_st) \
142 IEEE80211_LOCK_DESTROY_IMPL(_st, st_scanlock)
143 #define IEEE80211_SCANGEN_LOCK(_st) \
144 IEEE80211_LOCK_IMPL(_st, st_scanlock)
145 #define IEEE80211_SCANGEN_UNLOCK(_st) \
146 IEEE80211_UNLOCK_IMPL(_st, st_scanlock)
147 #define IEEE80211_SCANGEN_LOCK_ASSERT(_st) \
148 IEEE80211_LOCK_ASSERT_IMPL(_st, st_scanlock)
149
150 /*
151 * Per-node power-save queue definitions.
152 */
153 #define IEEE80211_NODE_SAVEQ_INIT(_ni, _name) do { \
154 (_ni)->ni_savedq.ifq_maxlen = IEEE80211_PS_MAX_QUEUE; \
155 } while (0)
156 #define IEEE80211_NODE_SAVEQ_DESTROY(_ni)
157 #define IEEE80211_NODE_SAVEQ_QLEN(_ni) ((_ni)->ni_savedq.ifq_len)
158 #define IEEE80211_NODE_SAVEQ_LOCK(_ni)
159 #define IEEE80211_NODE_SAVEQ_UNLOCK(_ni)
160 #define IEEE80211_NODE_SAVEQ_DEQUEUE(_ni, _m, _qlen) do { \
161 IEEE80211_NODE_SAVEQ_LOCK(_ni); \
162 IF_DEQUEUE(&(_ni)->ni_savedq, _m); \
163 (_qlen) = IEEE80211_NODE_SAVEQ_QLEN(_ni); \
164 IEEE80211_NODE_SAVEQ_UNLOCK(_ni); \
165 } while (0)
166 #define IEEE80211_NODE_SAVEQ_DRAIN(_ni, _qlen) do { \
167 IEEE80211_NODE_SAVEQ_LOCK(_ni); \
168 (_qlen) = IEEE80211_NODE_SAVEQ_QLEN(_ni); \
169 IF_PURGE(&(_ni)->ni_savedq); \
170 IEEE80211_NODE_SAVEQ_UNLOCK(_ni); \
171 } while (0)
172 /* XXX could be optimized */
173 #define _IEEE80211_NODE_SAVEQ_DEQUEUE_HEAD(_ni, _m) do { \
174 IF_DEQUEUE(&(_ni)->ni_savedq, m); \
175 } while (0)
176 #define _IEEE80211_NODE_SAVEQ_ENQUEUE(_ni, _m, _qlen, _age) do {\
177 (_m)->m_nextpkt = NULL; \
178 if ((_ni)->ni_savedq.ifq_tail != NULL) { \
179 _age -= M_AGE_GET((_ni)->ni_savedq.ifq_tail); \
180 (_ni)->ni_savedq.ifq_tail->m_nextpkt = (_m); \
181 } else { \
182 (_ni)->ni_savedq.ifq_head = (_m); \
183 } \
184 M_AGE_SET(_m, _age); \
185 (_ni)->ni_savedq.ifq_tail = (_m); \
186 (_qlen) = ++(_ni)->ni_savedq.ifq_len; \
187 } while (0)
188
189 #define IEEE80211_TAPQ_INIT(_tap) do { \
190 (_tap)->txa_q.ifq_maxlen = IEEE80211_AGGR_BAWMAX; \
191 } while (0)
192 #define IEEE80211_TAPQ_DESTROY(_tap)
193
194 #define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \
195 (mtail)->m_nextpkt = (ifq)->ifq_head; \
196 if ((ifq)->ifq_tail == NULL) \
197 (ifq)->ifq_tail = (mtail); \
198 (ifq)->ifq_head = (mhead); \
199 (ifq)->ifq_len += (mcount); \
200 } while (0)
201
202 /*
203 * 802.1x MAC ACL database locking definitions.
204 */
205 typedef kmutex_t acl_lock_t;
206 #define ACL_LOCK_INIT(_as, _name) \
207 IEEE80211_LOCK_INIT_IMPL(_as, _name, as_lock)
208 #define ACL_LOCK_DESTROY(_as) \
209 IEEE80211_LOCK_DESTROY_IMPL(_as, as_lock)
210 #define ACL_LOCK(_as) IEEE80211_LOCK_IMPL(_as, as_lock)
211 #define ACL_UNLOCK(_as) IEEE80211_UNLOCK_IMPL(_as, as_lock)
212 #define ACL_LOCK_ASSERT(_as) IEEE80211_LOCK_ASSERT_IMPL(_as, as_lock)
213
214 /*
215 * Node reference counting definitions.
216 *
217 * ieee80211_node_initref initialize the reference count to 1
218 * ieee80211_node_incref add a reference
219 * ieee80211_node_decref remove a reference
220 * ieee80211_node_dectestref remove a reference and return 1 if this
221 * is the last reference, otherwise 0
222 * ieee80211_node_refcnt reference count for printing (only)
223 */
224
225 #define ieee80211_node_initref(_ni) \
226 do { ((_ni)->ni_refcnt = 1); } while (0)
227 #define ieee80211_node_incref(_ni) \
228 do { (_ni)->ni_refcnt++; } while (0)
229 #define ieee80211_node_decref(_ni) \
230 do { (_ni)->ni_refcnt--; } while (0)
231 struct ieee80211_node;
232 int ieee80211_node_dectestref(struct ieee80211_node *ni);
233 #define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt
234
235 struct ifqueue;
236 void ieee80211_drain_ifq(struct ifqueue *);
237
238 #define msecs_to_ticks(ms) (((ms)*hz)/1000)
239 #define ticks_to_msecs(t) ((t) / hz)
240 #define time_after(a,b) ((long)(b) - (long)(a) < 0)
241 #define time_before(a,b) time_after(b,a)
242 #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
243 #define time_before_eq(a,b) time_after_eq(b,a)
244
245 struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int, u_int pktlen);
246
247 /* tx path usage */
248 #define M_PWR_SAV M_PROTO1 /* bypass PS handling */
249 #define M_MORE_DATA M_LINK3 /* more data frames to follow */
250 #define M_FRAG M_LINK4 /* 802.11 fragment */
251 #define M_FIRSTFRAG M_LINK5 /* first 802.11 fragment */
252 #define M_FF M_LINK6 /* "fast frames" */
253
254 /* rx path usage */
255 #define M_AMPDU M_PROTO1 /* A-MPDU processing done */
256 #define M_WEP M_LINK3 /* WEP done by hardware */ /* XXXNH */
257 #define M_80211_RX (M_AMPDU|M_WEP)
258
259 #ifdef __FreeBSD__
260 /* tx path usage */
261 #define M_LINK0 M_PROTO1 /* WEP requested */
262 #define M_PWR_SAV M_PROTO4 /* bypass PS handling */
263 #define M_MORE_DATA M_PROTO5 /* more data frames to follow */
264 #define M_FF 0x20000 /* fast frame */
265 #define M_TXCB 0x40000 /* do tx complete callback */
266 #define M_80211_TX (0x60000|M_PROTO1|M_WME_AC_MASK|M_PROTO4|M_PROTO5)
267
268 /* rx path usage */
269 #define M_AMPDU M_PROTO1 /* A-MPDU processing done */
270 #define M_WEP M_PROTO2 /* WEP done by hardware */
271 #define M_80211_RX (M_AMPDU|M_WEP)
272 #endif
273
274 /*
275 * Encode WME access control bits in the PROTO flags.
276 * This is safe since it's passed directly in to the
277 * driver and there's no chance someone else will clobber
278 * them on us.
279 */
280 #define M_WME_AC_MASK (M_LINK1|M_LINK2)
281 /* XXX 5 is wrong if M_LINK* are redefined */
282 #define M_WME_AC_SHIFT 13
283
284 #define M_WME_SETAC(m, ac) \
285 ((m)->m_flags = ((m)->m_flags &~ M_WME_AC_MASK) | \
286 ((ac) << M_WME_AC_SHIFT))
287 #define M_WME_GETAC(m) (((m)->m_flags >> M_WME_AC_SHIFT) & 0x3)
288
289 /*
290 * Mbufs on the power save queue are tagged with an age and
291 * timed out. We reuse the hardware checksum field in the
292 * mbuf packet header to store this data.
293 */
294 #define M_AGE_SET(m,v) (m->m_pkthdr.csum_data = v)
295 #define M_AGE_GET(m) (m->m_pkthdr.csum_data)
296 #define M_AGE_SUB(m,adj) (m->m_pkthdr.csum_data -= adj)
297
298 struct ieee80211_cb {
299 void (*func)(struct ieee80211_node *, void *, int status);
300 void *arg;
301 };
302 #define NET80211_TAG_CALLBACK 0 /* xmit complete callback */
303 int ieee80211_add_callback(struct mbuf *m,
304 void (*func)(struct ieee80211_node *, void *, int), void *arg);
305 void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
306
307 struct ieee80211com;
308 #endif /* _KERNEL */
309
310 /* XXX this stuff belongs elsewhere */
311 /*
312 * Message formats for messages from the net80211 layer to user
313 * applications via the routing socket. These messages are appended
314 * to an if_announcemsghdr structure.
315 */
316 struct ieee80211_join_event {
317 uint8_t iev_addr[6];
318 };
319
320 struct ieee80211_leave_event {
321 uint8_t iev_addr[6];
322 };
323
324 struct ieee80211_replay_event {
325 uint8_t iev_src[6]; /* src MAC */
326 uint8_t iev_dst[6]; /* dst MAC */
327 uint8_t iev_cipher; /* cipher type */
328 uint8_t iev_keyix; /* key id/index */
329 uint64_t iev_keyrsc; /* RSC from key */
330 uint64_t iev_rsc; /* RSC from frame */
331 };
332
333 struct ieee80211_michael_event {
334 uint8_t iev_src[6]; /* src MAC */
335 uint8_t iev_dst[6]; /* dst MAC */
336 uint8_t iev_cipher; /* cipher type */
337 uint8_t iev_keyix; /* key id/index */
338 };
339
340 #define RTM_IEEE80211_ASSOC 100 /* station associate (bss mode) */
341 #define RTM_IEEE80211_REASSOC 101 /* station re-associate (bss mode) */
342 #define RTM_IEEE80211_DISASSOC 102 /* station disassociate (bss mode) */
343 #define RTM_IEEE80211_JOIN 103 /* station join (ap mode) */
344 #define RTM_IEEE80211_LEAVE 104 /* station leave (ap mode) */
345 #define RTM_IEEE80211_SCAN 105 /* scan complete, results available */
346 #define RTM_IEEE80211_REPLAY 106 /* sequence counter replay detected */
347 #define RTM_IEEE80211_MICHAEL 107 /* Michael MIC failure detected */
348 #define RTM_IEEE80211_REJOIN 108 /* station re-associate (ap mode) */
349
350 #ifdef _KERNEL
351 #define __offsetof offsetof
352 #define ticks hardclock_ticks
353 #define ovbcopy(__src, __dst, __n) ((void)memmove(__dst, __src, __n))
354
355 #define TAILQ_FOREACH_SAFE(var, head, field, nextvar) \
356 for (var = TAILQ_FIRST(head); \
357 var != NULL && (nextvar = TAILQ_NEXT(var, field), 1); \
358 var = nextvar)
359
360 void if_printf(struct ifnet *, const char *, ...);
361 void m_align(struct mbuf *, int);
362 int m_append(struct mbuf *, int, const void *);
363 void get_random_bytes(void *, size_t);
364
365 void ieee80211_sysctl_attach(struct ieee80211com *);
366 void ieee80211_sysctl_detach(struct ieee80211com *);
367 void ieee80211_load_module(const char *);
368
369 void net80211_init(void);
370 #define IEEE80211_CRYPTO_SETUP(name) \
371 static void name(void); \
372 __link_set_add_text(ieee80211_funcs, name); \
373 static void name(void)
374 #endif /* _KERNEL */
375
376 #endif /* !_NET80211_IEEE80211_NETBSD_H_ */
377