xref: /haiku/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.h (revision 675ffabd70492a962f8c0288a32208c22ce5de18)
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>
40 extern "C" {
41 #	endif
42 
43 
44 #include <sys/kernel.h>
45 #include <sys/mutex.h>
46 #include <sys/sysctl.h>
47 #include <sys/taskqueue.h>
48 
49 
50 #define IEEE80211_CRYPTO_MODULE(name, version) \
51 	void \
52 	ieee80211_crypto_##name##_load() { \
53 		ieee80211_crypto_register(&name); \
54 	} \
55 \
56 \
57 	void \
58 	ieee80211_crypto_##name##_unload() \
59 	{ \
60 		ieee80211_crypto_unregister(&name); \
61 	}
62 
63 
64 /*
65  * Common state locking definitions.
66  */
67 typedef struct {
68 	char		name[16];		/* e.g. "ath0_com_lock" */
69 	struct mtx	mtx;
70 } ieee80211_com_lock_t;
71 #define	IEEE80211_LOCK_INIT(_ic, _name) do {				\
72 	ieee80211_com_lock_t *cl = &(_ic)->ic_comlock;			\
73 	snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name);	\
74 	mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE);	\
75 } while (0)
76 #define	IEEE80211_LOCK_OBJ(_ic)	(&(_ic)->ic_comlock.mtx)
77 #define	IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic))
78 #define	IEEE80211_LOCK(_ic)	   mtx_lock(IEEE80211_LOCK_OBJ(_ic))
79 #define	IEEE80211_UNLOCK(_ic)	   mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
80 #define	IEEE80211_LOCK_ASSERT(_ic) \
81 	mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
82 
83 /*
84  * Node locking definitions.
85  */
86 typedef struct {
87 	char		name[16];		/* e.g. "ath0_node_lock" */
88 	struct mtx	mtx;
89 } ieee80211_node_lock_t;
90 #define	IEEE80211_NODE_LOCK_INIT(_nt, _name) do {			\
91 	ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock;		\
92 	snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name);	\
93 	mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE);	\
94 } while (0)
95 #define	IEEE80211_NODE_LOCK_OBJ(_nt)	(&(_nt)->nt_nodelock.mtx)
96 #define	IEEE80211_NODE_LOCK_DESTROY(_nt) \
97 	mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt))
98 #define	IEEE80211_NODE_LOCK(_nt) \
99 	mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt))
100 #define	IEEE80211_NODE_IS_LOCKED(_nt) \
101 	mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt))
102 #define	IEEE80211_NODE_UNLOCK(_nt) \
103 	mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt))
104 #define	IEEE80211_NODE_LOCK_ASSERT(_nt)	\
105 	mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED)
106 
107 /*
108  * Node table iteration locking definitions; this protects the
109  * scan generation # used to iterate over the station table
110  * while grabbing+releasing the node lock.
111  */
112 typedef struct {
113 	char		name[16];		/* e.g. "ath0_scan_lock" */
114 	struct mtx	mtx;
115 } ieee80211_scan_lock_t;
116 #define	IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do {		\
117 	ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock;		\
118 	snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name);	\
119 	mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF);			\
120 } while (0)
121 #define	IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)	(&(_nt)->nt_scanlock.mtx)
122 #define	IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \
123 	mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
124 #define	IEEE80211_NODE_ITERATE_LOCK(_nt) \
125 	mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
126 #define	IEEE80211_NODE_ITERATE_UNLOCK(_nt) \
127 	mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
128 
129 /*
130  * Power-save queue definitions.
131  */
132 typedef struct mtx ieee80211_psq_lock_t;
133 #define	IEEE80211_PSQ_INIT(_psq, _name) \
134 	mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF)
135 #define	IEEE80211_PSQ_DESTROY(_psq)	mtx_destroy(&(_psq)->psq_lock)
136 #define	IEEE80211_PSQ_LOCK(_psq)	mtx_lock(&(_psq)->psq_lock)
137 #define	IEEE80211_PSQ_UNLOCK(_psq)	mtx_unlock(&(_psq)->psq_lock)
138 
139 #ifndef IF_PREPEND_LIST
140 #define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {	\
141 	(mtail)->m_nextpkt = (ifq)->ifq_head;			\
142 	if ((ifq)->ifq_tail == NULL)				\
143 		(ifq)->ifq_tail = (mtail);			\
144 	(ifq)->ifq_head = (mhead);				\
145 	(ifq)->ifq_len += (mcount);				\
146 } while (0)
147 #define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do {		\
148 	IF_LOCK(ifq);						\
149 	_IF_PREPEND_LIST(ifq, mhead, mtail, mcount);		\
150 	IF_UNLOCK(ifq);						\
151 } while (0)
152 #endif /* IF_PREPEND_LIST */
153 
154 /*
155  * Age queue definitions.
156  */
157 typedef struct mtx ieee80211_ageq_lock_t;
158 #define	IEEE80211_AGEQ_INIT(_aq, _name) \
159 	mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF)
160 #define	IEEE80211_AGEQ_DESTROY(_aq)	mtx_destroy(&(_aq)->aq_lock)
161 #define	IEEE80211_AGEQ_LOCK(_aq)	mtx_lock(&(_aq)->aq_lock)
162 #define	IEEE80211_AGEQ_UNLOCK(_aq)	mtx_unlock(&(_aq)->aq_lock)
163 
164 /*
165  * Node reference counting definitions.
166  *
167  * ieee80211_node_initref	initialize the reference count to 1
168  * ieee80211_node_incref	add a reference
169  * ieee80211_node_decref	remove a reference
170  * ieee80211_node_dectestref	remove a reference and return 1 if this
171  *				is the last reference, otherwise 0
172  * ieee80211_node_refcnt	reference count for printing (only)
173  */
174 #include <machine/atomic.h>
175 
176 #define ieee80211_node_initref(_ni) \
177 	do { ((_ni)->ni_refcnt = 1); } while (0)
178 #define ieee80211_node_incref(_ni) \
179 	atomic_add_int(&(_ni)->ni_refcnt, 1)
180 #define	ieee80211_node_decref(_ni) \
181 	atomic_subtract_int(&(_ni)->ni_refcnt, 1)
182 struct ieee80211_node;
183 int	ieee80211_node_dectestref(struct ieee80211_node *ni);
184 #define	ieee80211_node_refcnt(_ni)	(_ni)->ni_refcnt
185 
186 struct ifqueue;
187 struct ieee80211vap;
188 void	ieee80211_drain_ifq(struct ifqueue *);
189 void	ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
190 
191 void	ieee80211_vap_destroy(struct ieee80211vap *);
192 
193 #define	IFNET_IS_UP_RUNNING(_ifp) \
194 	(((_ifp)->if_flags & IFF_UP) && \
195 	 ((_ifp)->if_drv_flags & IFF_DRV_RUNNING))
196 
197 #define	msecs_to_ticks(ms)	(((ms)*hz)/1000)
198 #define	ticks_to_msecs(t)	(1000*(t) / hz)
199 #define	ticks_to_secs(t)	((t) / hz)
200 #define time_after(a,b) 	((long long)(b) - (long long)(a) < 0)
201 #define time_before(a,b)	time_after(b,a)
202 #define time_after_eq(a,b)	((long long)(a) - (long long)(b) >= 0)
203 #define time_before_eq(a,b)	time_after_eq(b,a)
204 
205 struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
206 
207 /* tx path usage */
208 #define	M_ENCAP		M_PROTO1		/* 802.11 encap done */
209 #define	M_EAPOL		M_PROTO3		/* PAE/EAPOL frame */
210 #define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */
211 #define	M_MORE_DATA	M_PROTO5		/* more data frames to follow */
212 #define	M_FF		M_PROTO6		/* fast frame */
213 #define	M_TXCB		M_PROTO7		/* do tx complete callback */
214 #define	M_AMPDU_MPDU	M_PROTO8		/* ok for A-MPDU aggregation */
215 #define	M_80211_TX \
216 	(M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\
217 	 M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU)
218 
219 /* rx path usage */
220 #define	M_AMPDU		M_PROTO1		/* A-MPDU subframe */
221 #define	M_WEP		M_PROTO2		/* WEP done by hardware */
222 #if 0
223 #define	M_AMPDU_MPDU	M_PROTO8		/* A-MPDU re-order done */
224 #endif
225 #define	M_80211_RX	(M_AMPDU|M_WEP|M_AMPDU_MPDU)
226 
227 /*
228  * Store WME access control bits in the vlan tag.
229  * This is safe since it's done after the packet is classified
230  * (where we use any previous tag) and because it's passed
231  * directly in to the driver and there's no chance someone
232  * else will clobber them on us.
233  */
234 #define	M_WME_SETAC(m, ac) \
235 	((m)->m_pkthdr.ether_vtag = (ac))
236 #define	M_WME_GETAC(m)	((m)->m_pkthdr.ether_vtag)
237 
238 /*
239  * Mbufs on the power save queue are tagged with an age and
240  * timed out.  We reuse the hardware checksum field in the
241  * mbuf packet header to store this data.
242  */
243 #define	M_AGE_SET(m,v)		(m->m_pkthdr.csum_data = v)
244 #define	M_AGE_GET(m)		(m->m_pkthdr.csum_data)
245 #define	M_AGE_SUB(m,adj)	(m->m_pkthdr.csum_data -= adj)
246 
247 /*
248  * Store the sequence number.
249  */
250 #define	M_SEQNO_SET(m, seqno) \
251 	((m)->m_pkthdr.tso_segsz = (seqno))
252 #define	M_SEQNO_GET(m)	((m)->m_pkthdr.tso_segsz)
253 
254 #define	MTAG_ABI_NET80211	1132948340	/* net80211 ABI */
255 
256 struct ieee80211_cb {
257 	void	(*func)(struct ieee80211_node *, void *, int status);
258 	void	*arg;
259 };
260 #define	NET80211_TAG_CALLBACK	0	/* xmit complete callback */
261 
262 int	ieee80211_add_callback(struct mbuf *m,
263 		void (*func)(struct ieee80211_node *, void *, int), void *arg);
264 void	ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
265 
266 void	get_random_bytes(void *, size_t);
267 
268 struct ieee80211com;
269 
270 void	ieee80211_sysctl_attach(struct ieee80211com *);
271 void	ieee80211_sysctl_detach(struct ieee80211com *);
272 void	ieee80211_sysctl_vattach(struct ieee80211vap *);
273 void	ieee80211_sysctl_vdetach(struct ieee80211vap *);
274 
275 void	ieee80211_load_module(const char *);
276 
277 /*
278  * A "policy module" is an adjunct module to net80211 that provides
279  * functionality that typically includes policy decisions.  This
280  * modularity enables extensibility and vendor-supplied functionality.
281  */
282 #define	_IEEE80211_POLICY_MODULE(policy, name, version)			\
283 typedef void (*policy##_setup)(int);					\
284 SET_DECLARE(policy##_set, policy##_setup);
285 
286 /*
287  * Scanner modules provide scanning policy.
288  */
289 #define	IEEE80211_SCANNER_MODULE(name, version)
290 #define	IEEE80211_SCANNER_ALG(name, alg, v)
291 
292 
293 void	ieee80211_scan_sta_init(void);
294 void	ieee80211_scan_sta_uninit(void);
295 
296 
297 struct ieee80211req;
298 typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
299     struct ieee80211req *);
300 SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc);
301 #define	IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get)
302 
303 typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
304     struct ieee80211req *);
305 SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
306 #define	IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set)
307 
308 #ifdef __cplusplus
309 }
310 #endif
311 #endif /* _KERNEL */
312 
313 /*
314  * Structure prepended to raw packets sent through the bpf
315  * interface when set to DLT_IEEE802_11_RADIO.  This allows
316  * user applications to specify pretty much everything in
317  * an Atheros tx descriptor.  XXX need to generalize.
318  *
319  * XXX cannot be more than 14 bytes as it is copied to a sockaddr's
320  * XXX sa_data area.
321  */
322 struct ieee80211_bpf_params {
323 	uint8_t		ibp_vers;	/* version */
324 #define	IEEE80211_BPF_VERSION	0
325 	uint8_t		ibp_len;	/* header length in bytes */
326 	uint8_t		ibp_flags;
327 #define	IEEE80211_BPF_SHORTPRE	0x01	/* tx with short preamble */
328 #define	IEEE80211_BPF_NOACK	0x02	/* tx with no ack */
329 #define	IEEE80211_BPF_CRYPTO	0x04	/* tx with h/w encryption */
330 #define	IEEE80211_BPF_FCS	0x10	/* frame incldues FCS */
331 #define	IEEE80211_BPF_DATAPAD	0x20	/* frame includes data padding */
332 #define	IEEE80211_BPF_RTS	0x40	/* tx with RTS/CTS */
333 #define	IEEE80211_BPF_CTS	0x80	/* tx with CTS only */
334 	uint8_t		ibp_pri;	/* WME/WMM AC+tx antenna */
335 	uint8_t		ibp_try0;	/* series 1 try count */
336 	uint8_t		ibp_rate0;	/* series 1 IEEE tx rate */
337 	uint8_t		ibp_power;	/* tx power (device units) */
338 	uint8_t		ibp_ctsrate;	/* IEEE tx rate for CTS */
339 	uint8_t		ibp_try1;	/* series 2 try count */
340 	uint8_t		ibp_rate1;	/* series 2 IEEE tx rate */
341 	uint8_t		ibp_try2;	/* series 3 try count */
342 	uint8_t		ibp_rate2;	/* series 3 IEEE tx rate */
343 	uint8_t		ibp_try3;	/* series 4 try count */
344 	uint8_t		ibp_rate3;	/* series 4 IEEE tx rate */
345 };
346 
347 #endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */
348