4cc56d9be694f94c370db58c4510d3e6b97c6be2
[dragonfly.git] / sys / netproto / 802_11 / wlan / ieee80211_dragonfly.c
1 /*-
2  * Copyright (c) 2003-2009 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: head/sys/net80211/ieee80211_freebsd.c 202612 2010-01-19 05:00:57Z thompsa $
26  * $DragonFly$
27  */
28
29 /*
30  * IEEE 802.11 support (DragonFlyBSD-specific code)
31  */
32 #include "opt_wlan.h"
33
34 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/systm.h> 
37 #include <sys/linker.h>
38 #include <sys/mbuf.h>   
39 #include <sys/module.h>
40 #include <sys/proc.h>
41 #include <sys/sysctl.h>
42
43 #include <sys/socket.h>
44
45 #include <net/bpf.h>
46 #include <net/if.h>
47 #include <net/if_dl.h>
48 #include <net/if_clone.h>
49 #include <net/if_media.h>
50 #include <net/if_types.h>
51 #include <net/ethernet.h>
52 #include <net/route.h>
53 #include <net/ifq_var.h>
54
55 #include <netproto/802_11/ieee80211_var.h>
56 #include <netproto/802_11/ieee80211_input.h>
57
58 SYSCTL_NODE(_net, OID_AUTO, wlan, CTLFLAG_RD, 0, "IEEE 80211 parameters");
59
60 #ifdef IEEE80211_DEBUG
61 int     ieee80211_debug = 0;
62 SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
63             0, "debugging printfs");
64 #endif
65
66 MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state");
67
68
69 static void     wlan_clone_destroy(struct ifnet *);
70 static int      wlan_clone_create(struct if_clone *, int, caddr_t);
71
72 static struct if_clone wlan_cloner = 
73         IF_CLONE_INITIALIZER("wlan", wlan_clone_create, wlan_clone_destroy,
74             0, IF_MAXUNIT);
75
76
77 /*
78  * Allocate/free com structure in conjunction with ifnet;
79  * these routines are registered with if_register_com_alloc
80  * below and are called automatically by the ifnet code
81  * when the ifnet of the parent device is created.
82  */
83 static void *
84 wlan_alloc(u_char type, struct ifnet *ifp)
85 {
86         struct ieee80211com *ic;
87
88         ic = kmalloc(sizeof(struct ieee80211com), M_80211_COM, M_WAITOK|M_ZERO);
89         ic->ic_ifp = ifp;
90
91         return (ic);
92 }
93
94 static void
95 wlan_free(void *ic, u_char type)
96 {
97         kfree(ic, M_80211_COM);
98 }
99
100 static int
101 wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
102 {
103         struct ieee80211_clone_params cp;
104         struct ieee80211vap *vap;
105         struct ieee80211com *ic;
106         struct ifnet *ifp;
107         int error;
108
109         error = copyin(params, &cp, sizeof(cp));
110         if (error)
111                 return error;
112         ifp = ifunit(cp.icp_parent);
113         if (ifp == NULL)
114                 return ENXIO;
115         /* XXX move printfs to DIAGNOSTIC before release */
116         if (ifp->if_type != IFT_IEEE80211) {
117                 if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__);
118                 return ENXIO;
119         }
120         if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
121                 if_printf(ifp, "%s: invalid opmode %d\n",
122                     __func__, cp.icp_opmode);
123                 return EINVAL;
124         }
125         ic = ifp->if_l2com;
126         if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
127                 if_printf(ifp, "%s mode not supported\n",
128                     ieee80211_opmode_name[cp.icp_opmode]);
129                 return EOPNOTSUPP;
130         }
131         if ((cp.icp_flags & IEEE80211_CLONE_TDMA) &&
132 #ifdef IEEE80211_SUPPORT_TDMA
133             (ic->ic_caps & IEEE80211_C_TDMA) == 0
134 #else
135             (1)
136 #endif
137         ) {
138                 if_printf(ifp, "TDMA not supported\n");
139                 return EOPNOTSUPP;
140         }
141         vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
142                         cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
143                         cp.icp_flags & IEEE80211_CLONE_MACADDR ?
144                             cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
145         return (vap == NULL ? EIO : 0);
146 }
147
148 static void
149 wlan_clone_destroy(struct ifnet *ifp)
150 {
151         struct ieee80211vap *vap = ifp->if_softc;
152         struct ieee80211com *ic = vap->iv_ic;
153
154         ic->ic_vap_delete(vap);
155 }
156
157 void
158 ieee80211_vap_destroy(struct ieee80211vap *vap)
159 {
160         if_clone_destroy(vap->iv_ifp->if_xname);
161 }
162
163 int
164 ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS)
165 {
166         int msecs = ticks_to_msecs(*(int *)arg1);
167         int error, t;
168
169         error = sysctl_handle_int(oidp, &msecs, 0, req);
170         if (error || !req->newptr)
171                 return error;
172         t = msecs_to_ticks(msecs);
173         *(int *)arg1 = (t < 1) ? 1 : t;
174         return 0;
175 }
176
177 static int
178 ieee80211_sysctl_inact(SYSCTL_HANDLER_ARGS)
179 {
180         int inact = (*(int *)arg1) * IEEE80211_INACT_WAIT;
181         int error;
182
183         error = sysctl_handle_int(oidp, &inact, 0, req);
184         if (error || !req->newptr)
185                 return error;
186         *(int *)arg1 = inact / IEEE80211_INACT_WAIT;
187         return 0;
188 }
189
190 static int
191 ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS)
192 {
193         struct ieee80211com *ic = arg1;
194         const char *name = ic->ic_ifp->if_xname;
195
196         return SYSCTL_OUT(req, name, strlen(name));
197 }
198
199 static int
200 ieee80211_sysctl_radar(SYSCTL_HANDLER_ARGS)
201 {
202         struct ieee80211com *ic = arg1;
203         int t = 0, error;
204
205         error = sysctl_handle_int(oidp, &t, 0, req);
206         if (error || !req->newptr)
207                 return error;
208         IEEE80211_LOCK(ic);
209         ieee80211_dfs_notify_radar(ic, ic->ic_curchan);
210         IEEE80211_UNLOCK(ic);
211         return 0;
212 }
213
214 void
215 ieee80211_sysctl_attach(struct ieee80211com *ic)
216 {
217 }
218
219 void
220 ieee80211_sysctl_detach(struct ieee80211com *ic)
221 {
222 }
223
224 void
225 ieee80211_sysctl_vattach(struct ieee80211vap *vap)
226 {
227         struct ifnet *ifp = vap->iv_ifp;
228         struct sysctl_ctx_list *ctx;
229         struct sysctl_oid *oid;
230         char num[14];                   /* sufficient for 32 bits */
231
232         ctx = (struct sysctl_ctx_list *) kmalloc(sizeof(struct sysctl_ctx_list),
233                 M_DEVBUF, M_INTWAIT | M_ZERO);
234         if (ctx == NULL) {
235                 if_printf(ifp, "%s: cannot allocate sysctl context!\n",
236                         __func__);
237                 return;
238         }
239         sysctl_ctx_init(ctx);
240         ksnprintf(num, sizeof(num), "%u", ifp->if_dunit);
241         oid = SYSCTL_ADD_NODE(ctx, &SYSCTL_NODE_CHILDREN(_net, wlan),
242                 OID_AUTO, num, CTLFLAG_RD, NULL, "");
243         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
244                 "%parent", CTLFLAG_RD, vap->iv_ic, 0,
245                 ieee80211_sysctl_parent, "A", "parent device");
246         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
247                 "driver_caps", CTLFLAG_RW, &vap->iv_caps, 0,
248                 "driver capabilities");
249 #ifdef IEEE80211_DEBUG
250         vap->iv_debug = ieee80211_debug;
251         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
252                 "debug", CTLFLAG_RW, &vap->iv_debug, 0,
253                 "control debugging printfs");
254 #endif
255         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
256                 "bmiss_max", CTLFLAG_RW, &vap->iv_bmiss_max, 0,
257                 "consecutive beacon misses before scanning");
258         /* XXX inherit from tunables */
259         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
260                 "inact_run", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_run, 0,
261                 ieee80211_sysctl_inact, "I",
262                 "station inactivity timeout (sec)");
263         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
264                 "inact_probe", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_probe, 0,
265                 ieee80211_sysctl_inact, "I",
266                 "station inactivity probe timeout (sec)");
267         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
268                 "inact_auth", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_auth, 0,
269                 ieee80211_sysctl_inact, "I",
270                 "station authentication timeout (sec)");
271         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
272                 "inact_init", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_init, 0,
273                 ieee80211_sysctl_inact, "I",
274                 "station initial state timeout (sec)");
275         if (vap->iv_htcaps & IEEE80211_HTC_HT) {
276                 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
277                         "ampdu_mintraffic_bk", CTLFLAG_RW,
278                         &vap->iv_ampdu_mintraffic[WME_AC_BK], 0,
279                         "BK traffic tx aggr threshold (pps)");
280                 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
281                         "ampdu_mintraffic_be", CTLFLAG_RW,
282                         &vap->iv_ampdu_mintraffic[WME_AC_BE], 0,
283                         "BE traffic tx aggr threshold (pps)");
284                 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
285                         "ampdu_mintraffic_vo", CTLFLAG_RW,
286                         &vap->iv_ampdu_mintraffic[WME_AC_VO], 0,
287                         "VO traffic tx aggr threshold (pps)");
288                 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
289                         "ampdu_mintraffic_vi", CTLFLAG_RW,
290                         &vap->iv_ampdu_mintraffic[WME_AC_VI], 0,
291                         "VI traffic tx aggr threshold (pps)");
292         }
293         if (vap->iv_caps & IEEE80211_C_DFS) {
294                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
295                         "radar", CTLTYPE_INT | CTLFLAG_RW, vap->iv_ic, 0,
296                         ieee80211_sysctl_radar, "I", "simulate radar event");
297         }
298         vap->iv_sysctl = ctx;
299         vap->iv_oid = oid;
300 }
301
302 void
303 ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
304 {
305
306         if (vap->iv_sysctl != NULL) {
307                 sysctl_ctx_free(vap->iv_sysctl);
308                 kfree(vap->iv_sysctl, M_DEVBUF);
309                 vap->iv_sysctl = NULL;
310         }
311 }
312
313 int
314 ieee80211_node_dectestref(struct ieee80211_node *ni)
315 {
316         /* XXX need equivalent of atomic_dec_and_test */
317         atomic_subtract_int(&ni->ni_refcnt, 1);
318         return atomic_cmpset_int(&ni->ni_refcnt, 0, 1);
319 }
320
321 void
322 ieee80211_drain_ifq(struct ifqueue *ifq)
323 {
324         struct ieee80211_node *ni;
325         struct mbuf *m;
326
327         for (;;) {
328                 IF_DEQUEUE(ifq, m);
329                 if (m == NULL)
330                         break;
331
332                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
333                 KASSERT(ni != NULL, ("frame w/o node"));
334                 ieee80211_free_node(ni);
335                 m->m_pkthdr.rcvif = NULL;
336
337                 m_freem(m);
338         }
339 }
340
341 void
342 ieee80211_flush_ifq(struct ifqueue *ifq, struct ieee80211vap *vap)
343 {
344         struct ieee80211_node *ni;
345         struct mbuf *m, **mprev;
346
347         IF_LOCK(ifq);
348         mprev = &ifq->ifq_head;
349         while ((m = *mprev) != NULL) {
350                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
351                 if (ni != NULL && ni->ni_vap == vap) {
352                         *mprev = m->m_nextpkt;          /* remove from list */
353                         ifq->ifq_len--;
354
355                         m_freem(m);
356                         ieee80211_free_node(ni);        /* reclaim ref */
357                 } else
358                         mprev = &m->m_nextpkt;
359         }
360         /* recalculate tail ptr */
361         m = ifq->ifq_head;
362         for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt)
363                 ;
364         ifq->ifq_tail = m;
365         IF_UNLOCK(ifq);
366 }
367
368 /*
369  * As above, for mbufs allocated with m_gethdr/MGETHDR
370  * or initialized by M_COPY_PKTHDR.
371  */
372 #define MC_ALIGN(m, len)                                                \
373 do {                                                                    \
374         (m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) - 1);        \
375 } while (/* CONSTCOND */ 0)
376
377 /*
378  * Allocate and setup a management frame of the specified
379  * size.  We return the mbuf and a pointer to the start
380  * of the contiguous data area that's been reserved based
381  * on the packet length.  The data area is forced to 32-bit
382  * alignment and the buffer length to a multiple of 4 bytes.
383  * This is done mainly so beacon frames (that require this)
384  * can use this interface too.
385  */
386 struct mbuf *
387 ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen)
388 {
389         struct mbuf *m;
390         u_int len;
391
392         /*
393          * NB: we know the mbuf routines will align the data area
394          *     so we don't need to do anything special.
395          */
396         len = roundup2(headroom + pktlen, 4);
397         KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len));
398         if (len < MINCLSIZE) {
399                 m = m_gethdr(MB_DONTWAIT, MT_DATA);
400                 /*
401                  * Align the data in case additional headers are added.
402                  * This should only happen when a WEP header is added
403                  * which only happens for shared key authentication mgt
404                  * frames which all fit in MHLEN.
405                  */
406                 if (m != NULL)
407                         MH_ALIGN(m, len);
408         } else {
409                 m = m_getcl(MB_DONTWAIT, MT_DATA, M_PKTHDR);
410                 if (m != NULL)
411                         MC_ALIGN(m, len);
412         }
413         if (m != NULL) {
414                 m->m_data += headroom;
415                 *frm = m->m_data;
416         }
417         return m;
418 }
419
420 /*
421  * Re-align the payload in the mbuf.  This is mainly used (right now)
422  * to handle IP header alignment requirements on certain architectures.
423  */
424 struct mbuf *
425 ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align)
426 {
427         int pktlen, space;
428         struct mbuf *n = NULL;
429
430         pktlen = m->m_pkthdr.len;
431         space = pktlen + align;
432         if (space < MINCLSIZE)
433                 n = m_gethdr(MB_DONTWAIT, MT_DATA);
434 #ifdef notyet
435         else {
436                 n = m_getjcl(MB_DONTWAIT, MT_DATA, M_PKTHDR,
437                     space <= MCLBYTES ?     MCLBYTES :
438 #if MJUMPAGESIZE != MCLBYTES
439                     space <= MJUMPAGESIZE ? MJUMPAGESIZE :
440 #endif
441                     space <= MJUM9BYTES ?   MJUM9BYTES : MJUM16BYTES);
442         }
443 #endif
444         if (__predict_true(n != NULL)) {
445                 m_move_pkthdr(n, m);
446                 n->m_data = (caddr_t)(ALIGN(n->m_data + align) - align);
447                 m_copydata(m, 0, pktlen, mtod(n, caddr_t));
448                 n->m_len = pktlen;
449         } else {
450                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
451                     mtod(m, const struct ieee80211_frame *), NULL,
452                     "%s", "no mbuf to realign");
453                 vap->iv_stats.is_rx_badalign++;
454         }
455         m_freem(m);
456         return n;
457 }
458
459 int
460 ieee80211_add_callback(struct mbuf *m,
461         void (*func)(struct ieee80211_node *, void *, int), void *arg)
462 {
463         struct m_tag *mtag;
464         struct ieee80211_cb *cb;
465
466         mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_CALLBACK,
467                         sizeof(struct ieee80211_cb), M_INTWAIT);
468         if (mtag == NULL)
469                 return 0;
470
471         cb = (struct ieee80211_cb *)(mtag+1);
472         cb->func = func;
473         cb->arg = arg;
474         m_tag_prepend(m, mtag);
475         m->m_flags |= M_TXCB;
476         return 1;
477 }
478
479 void
480 ieee80211_process_callback(struct ieee80211_node *ni,
481         struct mbuf *m, int status)
482 {
483         struct m_tag *mtag;
484
485         mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, NULL);
486         if (mtag != NULL) {
487                 struct ieee80211_cb *cb = (struct ieee80211_cb *)(mtag+1);
488                 cb->func(ni, cb->arg, status);
489         }
490 }
491
492 #include <sys/libkern.h>
493
494 void
495 get_random_bytes(void *p, size_t n)
496 {
497         uint8_t *dp = p;
498
499         while (n > 0) {
500                 uint32_t v = karc4random();
501                 size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n;
502                 bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n);
503                 dp += sizeof(uint32_t), n -= nb;
504         }
505 }
506
507 /*
508  * Helper function for events that pass just a single mac address.
509  */
510 static void
511 notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN])
512 {
513         struct ieee80211_join_event iev;
514
515         memset(&iev, 0, sizeof(iev));
516         IEEE80211_ADDR_COPY(iev.iev_addr, mac);
517         rt_ieee80211msg(ifp, op, &iev, sizeof(iev));
518 }
519
520 void
521 ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
522 {
523         struct ieee80211vap *vap = ni->ni_vap;
524         struct ifnet *ifp = vap->iv_ifp;
525
526         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode join",
527             (ni == vap->iv_bss) ? "bss " : "");
528
529         if (ni == vap->iv_bss) {
530                 notify_macaddr(ifp, newassoc ?
531                     RTM_IEEE80211_ASSOC : RTM_IEEE80211_REASSOC, ni->ni_bssid);
532                 if_link_state_change(ifp);
533         } else {
534                 notify_macaddr(ifp, newassoc ?
535                     RTM_IEEE80211_JOIN : RTM_IEEE80211_REJOIN, ni->ni_macaddr);
536         }
537 }
538
539 void
540 ieee80211_notify_node_leave(struct ieee80211_node *ni)
541 {
542         struct ieee80211vap *vap = ni->ni_vap;
543         struct ifnet *ifp = vap->iv_ifp;
544
545         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode leave",
546             (ni == vap->iv_bss) ? "bss " : "");
547
548         if (ni == vap->iv_bss) {
549                 rt_ieee80211msg(ifp, RTM_IEEE80211_DISASSOC, NULL, 0);
550                 if_link_state_change(ifp);
551         } else {
552                 /* fire off wireless event station leaving */
553                 notify_macaddr(ifp, RTM_IEEE80211_LEAVE, ni->ni_macaddr);
554         }
555 }
556
557 void
558 ieee80211_notify_scan_done(struct ieee80211vap *vap)
559 {
560         struct ifnet *ifp = vap->iv_ifp;
561
562         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s\n", "notify scan done");
563
564         /* dispatch wireless event indicating scan completed */
565         rt_ieee80211msg(ifp, RTM_IEEE80211_SCAN, NULL, 0);
566 }
567
568 void
569 ieee80211_notify_replay_failure(struct ieee80211vap *vap,
570         const struct ieee80211_frame *wh, const struct ieee80211_key *k,
571         u_int64_t rsc, int tid)
572 {
573         struct ifnet *ifp = vap->iv_ifp;
574
575         IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
576             "%s replay detected <rsc %ju, csc %ju, keyix %u rxkeyix %u>",
577             k->wk_cipher->ic_name, (intmax_t) rsc,
578             (intmax_t) k->wk_keyrsc[tid],
579             k->wk_keyix, k->wk_rxkeyix);
580
581         if (ifp != NULL) {              /* NB: for cipher test modules */
582                 struct ieee80211_replay_event iev;
583
584                 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
585                 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
586                 iev.iev_cipher = k->wk_cipher->ic_cipher;
587                 if (k->wk_rxkeyix != IEEE80211_KEYIX_NONE)
588                         iev.iev_keyix = k->wk_rxkeyix;
589                 else
590                         iev.iev_keyix = k->wk_keyix;
591                 iev.iev_keyrsc = k->wk_keyrsc[tid];
592                 iev.iev_rsc = rsc;
593                 rt_ieee80211msg(ifp, RTM_IEEE80211_REPLAY, &iev, sizeof(iev));
594         }
595 }
596
597 void
598 ieee80211_notify_michael_failure(struct ieee80211vap *vap,
599         const struct ieee80211_frame *wh, u_int keyix)
600 {
601         struct ifnet *ifp = vap->iv_ifp;
602
603         IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
604             "michael MIC verification failed <keyix %u>", keyix);
605         vap->iv_stats.is_rx_tkipmic++;
606
607         if (ifp != NULL) {              /* NB: for cipher test modules */
608                 struct ieee80211_michael_event iev;
609
610                 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
611                 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
612                 iev.iev_cipher = IEEE80211_CIPHER_TKIP;
613                 iev.iev_keyix = keyix;
614                 rt_ieee80211msg(ifp, RTM_IEEE80211_MICHAEL, &iev, sizeof(iev));
615         }
616 }
617
618 void
619 ieee80211_notify_wds_discover(struct ieee80211_node *ni)
620 {
621         struct ieee80211vap *vap = ni->ni_vap;
622         struct ifnet *ifp = vap->iv_ifp;
623
624         notify_macaddr(ifp, RTM_IEEE80211_WDS, ni->ni_macaddr);
625 }
626
627 void
628 ieee80211_notify_csa(struct ieee80211com *ic,
629         const struct ieee80211_channel *c, int mode, int count)
630 {
631         struct ifnet *ifp = ic->ic_ifp;
632         struct ieee80211_csa_event iev;
633
634         memset(&iev, 0, sizeof(iev));
635         iev.iev_flags = c->ic_flags;
636         iev.iev_freq = c->ic_freq;
637         iev.iev_ieee = c->ic_ieee;
638         iev.iev_mode = mode;
639         iev.iev_count = count;
640         rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
641 }
642
643 void
644 ieee80211_notify_radar(struct ieee80211com *ic,
645         const struct ieee80211_channel *c)
646 {
647         struct ifnet *ifp = ic->ic_ifp;
648         struct ieee80211_radar_event iev;
649
650         memset(&iev, 0, sizeof(iev));
651         iev.iev_flags = c->ic_flags;
652         iev.iev_freq = c->ic_freq;
653         iev.iev_ieee = c->ic_ieee;
654         rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
655 }
656
657 void
658 ieee80211_notify_cac(struct ieee80211com *ic,
659         const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
660 {
661         struct ifnet *ifp = ic->ic_ifp;
662         struct ieee80211_cac_event iev;
663
664         memset(&iev, 0, sizeof(iev));
665         iev.iev_flags = c->ic_flags;
666         iev.iev_freq = c->ic_freq;
667         iev.iev_ieee = c->ic_ieee;
668         iev.iev_type = type;
669         rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
670 }
671
672 void
673 ieee80211_notify_node_deauth(struct ieee80211_node *ni)
674 {
675         struct ieee80211vap *vap = ni->ni_vap;
676         struct ifnet *ifp = vap->iv_ifp;
677
678         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node deauth");
679
680         notify_macaddr(ifp, RTM_IEEE80211_DEAUTH, ni->ni_macaddr);
681 }
682
683 void
684 ieee80211_notify_node_auth(struct ieee80211_node *ni)
685 {
686         struct ieee80211vap *vap = ni->ni_vap;
687         struct ifnet *ifp = vap->iv_ifp;
688
689         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node auth");
690
691         notify_macaddr(ifp, RTM_IEEE80211_AUTH, ni->ni_macaddr);
692 }
693
694 void
695 ieee80211_notify_country(struct ieee80211vap *vap,
696         const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2])
697 {
698         struct ifnet *ifp = vap->iv_ifp;
699         struct ieee80211_country_event iev;
700
701         memset(&iev, 0, sizeof(iev));
702         IEEE80211_ADDR_COPY(iev.iev_addr, bssid);
703         iev.iev_cc[0] = cc[0];
704         iev.iev_cc[1] = cc[1];
705         rt_ieee80211msg(ifp, RTM_IEEE80211_COUNTRY, &iev, sizeof(iev));
706 }
707
708 void
709 ieee80211_notify_radio(struct ieee80211com *ic, int state)
710 {
711         struct ifnet *ifp = ic->ic_ifp;
712         struct ieee80211_radio_event iev;
713
714         memset(&iev, 0, sizeof(iev));
715         iev.iev_state = state;
716         rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
717 }
718
719 int
720 ieee80211_handoff(struct ifnet *dst_ifp, struct mbuf *m)
721 {
722         struct mbuf *m0;
723
724         /* We may be sending a fragment so traverse the mbuf */
725         for (; m; m = m0) {
726                 struct altq_pktattr pktattr;
727
728                 m0 = m->m_nextpkt;
729                 m->m_nextpkt = NULL;
730
731                 if (ifq_is_enabled(&dst_ifp->if_snd))
732                         altq_etherclassify(&dst_ifp->if_snd, m, &pktattr);
733
734                 ifq_dispatch(dst_ifp, m, &pktattr);
735         }
736
737         return (0);
738 }
739
740 /* IEEE Std 802.11a-1999, page 9, table 79 */
741 #define IEEE80211_OFDM_SYM_TIME                 4
742 #define IEEE80211_OFDM_PREAMBLE_TIME            16
743 #define IEEE80211_OFDM_SIGNAL_TIME              4
744 /* IEEE Std 802.11g-2003, page 44 */
745 #define IEEE80211_OFDM_SIGNAL_EXT_TIME          6
746
747 /* IEEE Std 802.11a-1999, page 7, figure 107 */
748 #define IEEE80211_OFDM_PLCP_SERVICE_NBITS       16
749 #define IEEE80211_OFDM_TAIL_NBITS               6
750
751 #define IEEE80211_OFDM_NBITS(frmlen) \
752         (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \
753         ((frmlen) * NBBY) + \
754         IEEE80211_OFDM_TAIL_NBITS)
755
756 #define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \
757         (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
758
759 #define IEEE80211_OFDM_NSYMS(kbps, frmlen) \
760         howmany(IEEE80211_OFDM_NBITS((frmlen)), \
761         IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
762
763 #define IEEE80211_OFDM_TXTIME(kbps, frmlen) \
764         (IEEE80211_OFDM_PREAMBLE_TIME + \
765         IEEE80211_OFDM_SIGNAL_TIME + \
766         (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
767
768 /* IEEE Std 802.11b-1999, page 28, subclause 18.3.4 */
769 #define IEEE80211_CCK_PREAMBLE_LEN      144
770 #define IEEE80211_CCK_PLCP_HDR_TIME     48
771 #define IEEE80211_CCK_SHPREAMBLE_LEN    72
772 #define IEEE80211_CCK_SHPLCP_HDR_TIME   24
773
774 #define IEEE80211_CCK_NBITS(frmlen)     ((frmlen) * NBBY)
775 #define IEEE80211_CCK_TXTIME(kbps, frmlen) \
776         (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
777
778 uint16_t
779 ieee80211_txtime(struct ieee80211_node *ni, u_int len, uint8_t rs_rate,
780                 uint32_t flags)
781 {
782         struct ieee80211vap *vap = ni->ni_vap;
783         uint16_t txtime;
784         int rate;
785
786         rs_rate &= IEEE80211_RATE_VAL;
787         rate = rs_rate * 500;   /* ieee80211 rate -> kbps */
788
789         if (vap->iv_ic->ic_phytype == IEEE80211_T_OFDM) {
790                 /*
791                  * IEEE Std 802.11a-1999, page 37, equation (29)
792                  * IEEE Std 802.11g-2003, page 44, equation (42)
793                  */
794                 txtime = IEEE80211_OFDM_TXTIME(rate, len);
795                 if (vap->iv_ic->ic_curmode == IEEE80211_MODE_11G)
796                         txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
797         } else {
798                 /*
799                  * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
800                  * IEEE Std 802.11g-2003, page 45, equation (43)
801                  */
802                 if (vap->iv_ic->ic_phytype == IEEE80211_T_OFDM_QUARTER+1)
803                         ++len;
804                 txtime = IEEE80211_CCK_TXTIME(rate, len);
805
806                 /*
807                  * Short preamble is not applicable for DS 1Mbits/s
808                  */
809                 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
810                         txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
811                                 IEEE80211_CCK_SHPLCP_HDR_TIME;
812                 } else {
813                         txtime += IEEE80211_CCK_PREAMBLE_LEN +
814                         IEEE80211_CCK_PLCP_HDR_TIME;
815                 }
816         }
817         return txtime;
818 }
819
820 void
821 ieee80211_load_module(const char *modname)
822 {
823
824 #ifdef notyet
825         (void)kern_kldload(curthread, modname, NULL);
826 #else
827         kprintf("%s: load the %s module by hand for now.\n", __func__, modname);
828 #endif
829 }
830
831 static eventhandler_tag wlan_bpfevent;
832 static eventhandler_tag wlan_ifllevent;
833
834 static void
835 bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
836 {
837         /* NB: identify vap's by if_start */
838         if (dlt == DLT_IEEE802_11_RADIO && ifp->if_start == ieee80211_start) {
839                 struct ieee80211vap *vap = ifp->if_softc;
840                 /*
841                  * Track bpf radiotap listener state.  We mark the vap
842                  * to indicate if any listener is present and the com
843                  * to indicate if any listener exists on any associated
844                  * vap.  This flag is used by drivers to prepare radiotap
845                  * state only when needed.
846                  */
847                 if (attach) {
848                         ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF);
849                         if (vap->iv_opmode == IEEE80211_M_MONITOR)
850                                 atomic_add_int(&vap->iv_ic->ic_montaps, 1);
851                 } else if (!vap->iv_rawbpf) {
852                         ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF);
853                         if (vap->iv_opmode == IEEE80211_M_MONITOR)
854                                 atomic_subtract_int(&vap->iv_ic->ic_montaps, 1);
855                 }
856         }
857 }
858
859 static void
860 wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
861 {
862         struct ieee80211com *ic = ifp->if_l2com;
863         struct ieee80211vap *vap, *next;
864
865         if (ifp->if_type != IFT_IEEE80211 || ic == NULL)
866                 return;
867
868         IEEE80211_LOCK(ic);
869         TAILQ_FOREACH_MUTABLE(vap, &ic->ic_vaps, iv_next, next) {
870                 /*
871                  * If the MAC address has changed on the parent and it was
872                  * copied to the vap on creation then re-sync.
873                  */
874                 if (vap->iv_ic == ic &&
875                     (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) {
876                         IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
877                         IEEE80211_UNLOCK(ic);
878                         if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp),
879                             IEEE80211_ADDR_LEN);
880                         IEEE80211_LOCK(ic);
881                 }
882         }
883         IEEE80211_UNLOCK(ic);
884 }
885
886 /*
887  * Module glue.
888  *
889  * NB: the module name is "wlan" for compatibility with NetBSD.
890  */
891 static int
892 wlan_modevent(module_t mod, int type, void *unused)
893 {
894         switch (type) {
895         case MOD_LOAD:
896                 if (bootverbose)
897                         kprintf("wlan: <802.11 Link Layer>\n");
898                 wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
899                     bpf_track, 0, EVENTHANDLER_PRI_ANY);
900                 if (wlan_bpfevent == NULL)
901                         return ENOMEM;
902                 wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
903                     wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
904                 if (wlan_ifllevent == NULL) {
905                         EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
906                         return ENOMEM;
907                 }
908                 if_clone_attach(&wlan_cloner);
909                 if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
910                 return 0;
911         case MOD_UNLOAD:
912                 if_deregister_com_alloc(IFT_IEEE80211);
913                 if_clone_detach(&wlan_cloner);
914                 EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
915                 EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
916                 return 0;
917         }
918         return EINVAL;
919 }
920
921 static moduledata_t wlan_mod = {
922         "wlan",
923         wlan_modevent,
924         0
925 };
926 DECLARE_MODULE(wlan, wlan_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
927 MODULE_VERSION(wlan, 1);
928 MODULE_DEPEND(wlan, ether, 1, 1, 1);