1/*-
2 * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * $FreeBSD$
26 */
27#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_
28#define _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_
29
30
31#include <stdint.h>
32
33
34#ifdef _KERNEL
35
36#	ifdef __cplusplus
37// Those includes are needed to avoid C/C++ function export clashes
38#		include <new>
39#		include <thread.h>
40extern "C" {
41#	endif
42
43#define INVARIANTS 1
44
45#include <sys/kernel.h>
46#include <sys/mutex.h>
47#include <sys/sysctl.h>
48#include <sys/taskqueue.h>
49
50
51#define IEEE80211_CRYPTO_MODULE(name, version) \
52	void \
53	ieee80211_crypto_##name##_load() { \
54		ieee80211_crypto_register(&name); \
55	} \
56\
57\
58	void \
59	ieee80211_crypto_##name##_unload() \
60	{ \
61		ieee80211_crypto_unregister(&name); \
62	}
63
64
65/*
66 * Common state locking definitions.
67 */
68typedef struct {
69	char		name[16];		/* e.g. "ath0_com_lock" */
70	struct mtx	mtx;
71} ieee80211_com_lock_t;
72#define	IEEE80211_LOCK_INIT(_ic, _name) do {				\
73	ieee80211_com_lock_t *cl = &(_ic)->ic_comlock;			\
74	snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name);	\
75	mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE);	\
76} while (0)
77#define	IEEE80211_LOCK_OBJ(_ic)	(&(_ic)->ic_comlock.mtx)
78#define	IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic))
79#define	IEEE80211_LOCK(_ic)	   mtx_lock(IEEE80211_LOCK_OBJ(_ic))
80#define	IEEE80211_UNLOCK(_ic)	   mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
81#define	IEEE80211_LOCK_ASSERT(_ic) \
82	mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
83
84/*
85 * Node locking definitions.
86 */
87typedef struct {
88	char		name[16];		/* e.g. "ath0_node_lock" */
89	struct mtx	mtx;
90} ieee80211_node_lock_t;
91#define	IEEE80211_NODE_LOCK_INIT(_nt, _name) do {			\
92	ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock;		\
93	snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name);	\
94	mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE);	\
95} while (0)
96#define	IEEE80211_NODE_LOCK_OBJ(_nt)	(&(_nt)->nt_nodelock.mtx)
97#define	IEEE80211_NODE_LOCK_DESTROY(_nt) \
98	mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt))
99#define	IEEE80211_NODE_LOCK(_nt) \
100	mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt))
101#define	IEEE80211_NODE_IS_LOCKED(_nt) \
102	mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt))
103#define	IEEE80211_NODE_UNLOCK(_nt) \
104	mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt))
105#define	IEEE80211_NODE_LOCK_ASSERT(_nt)	\
106	mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED)
107
108/*
109 * Node table iteration locking definitions; this protects the
110 * scan generation # used to iterate over the station table
111 * while grabbing+releasing the node lock.
112 */
113typedef struct {
114	char		name[16];		/* e.g. "ath0_scan_lock" */
115	struct mtx	mtx;
116} ieee80211_scan_lock_t;
117#define	IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do {		\
118	ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock;		\
119	snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name);	\
120	mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF);			\
121} while (0)
122#define	IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)	(&(_nt)->nt_scanlock.mtx)
123#define	IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \
124	mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
125#define	IEEE80211_NODE_ITERATE_LOCK(_nt) \
126	mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
127#define	IEEE80211_NODE_ITERATE_UNLOCK(_nt) \
128	mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
129
130/*
131 * Power-save queue definitions.
132 */
133typedef struct mtx ieee80211_psq_lock_t;
134#define	IEEE80211_PSQ_INIT(_psq, _name) \
135	mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF)
136#define	IEEE80211_PSQ_DESTROY(_psq)	mtx_destroy(&(_psq)->psq_lock)
137#define	IEEE80211_PSQ_LOCK(_psq)	mtx_lock(&(_psq)->psq_lock)
138#define	IEEE80211_PSQ_UNLOCK(_psq)	mtx_unlock(&(_psq)->psq_lock)
139
140#ifndef IF_PREPEND_LIST
141#define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {	\
142	(mtail)->m_nextpkt = (ifq)->ifq_head;			\
143	if ((ifq)->ifq_tail == NULL)				\
144		(ifq)->ifq_tail = (mtail);			\
145	(ifq)->ifq_head = (mhead);				\
146	(ifq)->ifq_len += (mcount);				\
147} while (0)
148#define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {		\
149	IF_LOCK(ifq);						\
150	_IF_PREPEND_LIST(ifq, mhead, mtail, mcount);		\
151	IF_UNLOCK(ifq);						\
152} while (0)
153#endif /* IF_PREPEND_LIST */
154
155/*
156 * Age queue definitions.
157 */
158typedef struct mtx ieee80211_ageq_lock_t;
159#define	IEEE80211_AGEQ_INIT(_aq, _name) \
160	mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF)
161#define	IEEE80211_AGEQ_DESTROY(_aq)	mtx_destroy(&(_aq)->aq_lock)
162#define	IEEE80211_AGEQ_LOCK(_aq)	mtx_lock(&(_aq)->aq_lock)
163#define	IEEE80211_AGEQ_UNLOCK(_aq)	mtx_unlock(&(_aq)->aq_lock)
164
165/*
166 * Scan table definitions.
167 */
168typedef struct mtx ieee80211_scan_table_lock_t;
169#define	IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
170	mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF)
171#define	IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st)	mtx_destroy(&(_st)->st_lock)
172#define	IEEE80211_SCAN_TABLE_LOCK(_st)		mtx_lock(&(_st)->st_lock)
173#define	IEEE80211_SCAN_TABLE_UNLOCK(_st)	mtx_unlock(&(_st)->st_lock)
174
175/*
176 * Node reference counting definitions.
177 *
178 * ieee80211_node_initref	initialize the reference count to 1
179 * ieee80211_node_incref	add a reference
180 * ieee80211_node_decref	remove a reference
181 * ieee80211_node_dectestref	remove a reference and return 1 if this
182 *				is the last reference, otherwise 0
183 * ieee80211_node_refcnt	reference count for printing (only)
184 */
185#include <machine/atomic.h>
186
187#define ieee80211_node_initref(_ni) \
188	do { ((_ni)->ni_refcnt = 1); } while (0)
189#define ieee80211_node_incref(_ni) \
190	atomic_add_int(&(_ni)->ni_refcnt, 1)
191#define	ieee80211_node_decref(_ni) \
192	atomic_subtract_int(&(_ni)->ni_refcnt, 1)
193struct ieee80211_node;
194int	ieee80211_node_dectestref(struct ieee80211_node *ni);
195#define	ieee80211_node_refcnt(_ni)	(_ni)->ni_refcnt
196
197struct ifqueue;
198struct ieee80211vap;
199void	ieee80211_drain_ifq(struct ifqueue *);
200void	ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
201
202void	ieee80211_vap_destroy(struct ieee80211vap *);
203
204#define	IFNET_IS_UP_RUNNING(_ifp) \
205	(((_ifp)->if_flags & IFF_UP) && \
206	 ((_ifp)->if_drv_flags & IFF_DRV_RUNNING))
207
208#define	msecs_to_ticks(ms)	(((ms)*hz)/1000)
209#define	ticks_to_msecs(t)	(1000*(t) / hz)
210#define	ticks_to_secs(t)	((t) / hz)
211#define time_after(a,b) 	((long long)(b) - (long long)(a) < 0)
212#define time_before(a,b)	time_after(b,a)
213#define time_after_eq(a,b)	((long long)(a) - (long long)(b) >= 0)
214#define time_before_eq(a,b)	time_after_eq(b,a)
215
216struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
217
218/* tx path usage */
219#define	M_ENCAP		M_PROTO1		/* 802.11 encap done */
220#define	M_EAPOL		M_PROTO3		/* PAE/EAPOL frame */
221#define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */
222#define	M_MORE_DATA	M_PROTO5		/* more data frames to follow */
223#define	M_FF		M_PROTO6		/* fast frame */
224#define	M_TXCB		M_PROTO7		/* do tx complete callback */
225#define	M_AMPDU_MPDU	M_PROTO8		/* ok for A-MPDU aggregation */
226#define	M_80211_TX \
227	(M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\
228	 M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU)
229
230/* rx path usage */
231#define	M_AMPDU		M_PROTO1		/* A-MPDU subframe */
232#define	M_WEP		M_PROTO2		/* WEP done by hardware */
233#if 0
234#define	M_AMPDU_MPDU	M_PROTO8		/* A-MPDU re-order done */
235#endif
236#define	M_80211_RX	(M_AMPDU|M_WEP|M_AMPDU_MPDU)
237
238/*
239 * Store WME access control bits in the vlan tag.
240 * This is safe since it's done after the packet is classified
241 * (where we use any previous tag) and because it's passed
242 * directly in to the driver and there's no chance someone
243 * else will clobber them on us.
244 */
245#define	M_WME_SETAC(m, ac) \
246	((m)->m_pkthdr.ether_vtag = (ac))
247#define	M_WME_GETAC(m)	((m)->m_pkthdr.ether_vtag)
248
249/*
250 * Mbufs on the power save queue are tagged with an age and
251 * timed out.  We reuse the hardware checksum field in the
252 * mbuf packet header to store this data.
253 */
254#define	M_AGE_SET(m,v)		(m->m_pkthdr.csum_data = v)
255#define	M_AGE_GET(m)		(m->m_pkthdr.csum_data)
256#define	M_AGE_SUB(m,adj)	(m->m_pkthdr.csum_data -= adj)
257
258/*
259 * Store the sequence number.
260 */
261#define	M_SEQNO_SET(m, seqno) \
262	((m)->m_pkthdr.tso_segsz = (seqno))
263#define	M_SEQNO_GET(m)	((m)->m_pkthdr.tso_segsz)
264
265#define	MTAG_ABI_NET80211	1132948340	/* net80211 ABI */
266
267struct ieee80211_cb {
268	void	(*func)(struct ieee80211_node *, void *, int status);
269	void	*arg;
270};
271#define	NET80211_TAG_CALLBACK	0	/* xmit complete callback */
272
273int	ieee80211_add_callback(struct mbuf *m,
274		void (*func)(struct ieee80211_node *, void *, int), void *arg);
275void	ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
276
277void	get_random_bytes(void *, size_t);
278
279struct ieee80211com;
280
281void	ieee80211_sysctl_attach(struct ieee80211com *);
282void	ieee80211_sysctl_detach(struct ieee80211com *);
283void	ieee80211_sysctl_vattach(struct ieee80211vap *);
284void	ieee80211_sysctl_vdetach(struct ieee80211vap *);
285
286void	ieee80211_load_module(const char *);
287
288/*
289 * A "policy module" is an adjunct module to net80211 that provides
290 * functionality that typically includes policy decisions.  This
291 * modularity enables extensibility and vendor-supplied functionality.
292 */
293#define	_IEEE80211_POLICY_MODULE(policy, name, version)			\
294typedef void (*policy##_setup)(int);					\
295SET_DECLARE(policy##_set, policy##_setup);
296
297/*
298 * Authenticator modules handle 802.1x/WPA authentication.
299 */
300#define	IEEE80211_AUTH_MODULE(name, version)				\
301	_IEEE80211_POLICY_MODULE(auth, name, version)
302
303#define	IEEE80211_AUTH_ALG(name, alg, v)				\
304static void								\
305name##_modevent(int type)						\
306{									\
307	if (type == MOD_LOAD)						\
308		ieee80211_authenticator_register(alg, &v);		\
309	else								\
310		ieee80211_authenticator_unregister(alg);		\
311}									\
312TEXT_SET(auth_set, name##_modevent)
313
314/*
315 * Scanner modules provide scanning policy.
316 */
317#define	IEEE80211_SCANNER_MODULE(name, version)
318#define	IEEE80211_SCANNER_ALG(name, alg, v)
319
320
321void	ieee80211_scan_sta_init(void);
322void	ieee80211_scan_sta_uninit(void);
323
324
325/*
326 * Rate control modules provide tx rate control support.
327 */
328#define	IEEE80211_RATECTL_MODULE(alg, version)				\
329	_IEEE80211_POLICY_MODULE(ratectl, alg, version);		\
330
331#define IEEE80211_RATECTL_ALG(name, alg, v) \
332	void \
333	ieee80211_ratectl_##name##_load() { \
334		ieee80211_ratectl_register(alg, &v); \
335	} \
336\
337\
338	void \
339	ieee80211_ratectl_##name##_unload() \
340	{ \
341		ieee80211_ratectl_unregister(alg); \
342	}
343
344
345struct ieee80211req;
346typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
347    struct ieee80211req *);
348SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc);
349#define	IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get)
350
351typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
352    struct ieee80211req *);
353SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
354#define	IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set)
355
356#ifdef __cplusplus
357}
358#endif
359#endif /* _KERNEL */
360
361/*
362 * Structure prepended to raw packets sent through the bpf
363 * interface when set to DLT_IEEE802_11_RADIO.  This allows
364 * user applications to specify pretty much everything in
365 * an Atheros tx descriptor.  XXX need to generalize.
366 *
367 * XXX cannot be more than 14 bytes as it is copied to a sockaddr's
368 * XXX sa_data area.
369 */
370struct ieee80211_bpf_params {
371	uint8_t		ibp_vers;	/* version */
372#define	IEEE80211_BPF_VERSION	0
373	uint8_t		ibp_len;	/* header length in bytes */
374	uint8_t		ibp_flags;
375#define	IEEE80211_BPF_SHORTPRE	0x01	/* tx with short preamble */
376#define	IEEE80211_BPF_NOACK	0x02	/* tx with no ack */
377#define	IEEE80211_BPF_CRYPTO	0x04	/* tx with h/w encryption */
378#define	IEEE80211_BPF_FCS	0x10	/* frame incldues FCS */
379#define	IEEE80211_BPF_DATAPAD	0x20	/* frame includes data padding */
380#define	IEEE80211_BPF_RTS	0x40	/* tx with RTS/CTS */
381#define	IEEE80211_BPF_CTS	0x80	/* tx with CTS only */
382	uint8_t		ibp_pri;	/* WME/WMM AC+tx antenna */
383	uint8_t		ibp_try0;	/* series 1 try count */
384	uint8_t		ibp_rate0;	/* series 1 IEEE tx rate */
385	uint8_t		ibp_power;	/* tx power (device units) */
386	uint8_t		ibp_ctsrate;	/* IEEE tx rate for CTS */
387	uint8_t		ibp_try1;	/* series 2 try count */
388	uint8_t		ibp_rate1;	/* series 2 IEEE tx rate */
389	uint8_t		ibp_try2;	/* series 3 try count */
390	uint8_t		ibp_rate2;	/* series 3 IEEE tx rate */
391	uint8_t		ibp_try3;	/* series 4 try count */
392	uint8_t		ibp_rate3;	/* series 4 IEEE tx rate */
393};
394
395#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */
396