Deleted Added
full compact
ieee80211.c (284014) ieee80211.c (286410)
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2009 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:

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2009 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:

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211.c 284014 2015-06-05 06:49:08Z adrian $");
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211.c 286410 2015-08-07 11:43:14Z glebius $");
29
30/*
31 * IEEE 802.11 generic handler
32 */
33#include "opt_wlan.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/socket.h>
29
30/*
31 * IEEE 802.11 generic handler
32 */
33#include "opt_wlan.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/socket.h>
39#include <sys/sbuf.h>
39
40#include <machine/stdarg.h>
41
42#include <net/if.h>
43#include <net/if_var.h>
44#include <net/if_dl.h>
45#include <net/if_media.h>
46#include <net/if_types.h>

--- 39 unchanged lines hidden (view full) ---

86 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
87
88static void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag);
89static void ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag);
90static void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag);
91static int ieee80211_media_setup(struct ieee80211com *ic,
92 struct ifmedia *media, int caps, int addsta,
93 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
40
41#include <machine/stdarg.h>
42
43#include <net/if.h>
44#include <net/if_var.h>
45#include <net/if_dl.h>
46#include <net/if_media.h>
47#include <net/if_types.h>

--- 39 unchanged lines hidden (view full) ---

87 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
88
89static void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag);
90static void ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag);
91static void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag);
92static int ieee80211_media_setup(struct ieee80211com *ic,
93 struct ifmedia *media, int caps, int addsta,
94 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
94static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
95static int ieee80211com_media_change(struct ifnet *);
96static int media_status(enum ieee80211_opmode,
97 const struct ieee80211_channel *);
98static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
99
100MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
101
102/*
103 * Default supported rates for 802.11 operation (in IEEE .5Mb units).

--- 12 unchanged lines hidden (view full) ---

116 { 12, { B(2), B(4), B(11), B(22), 12, 18, 24, 36, 48, 72, 96, 108 } };
117#undef B
118
119/*
120 * Fill in 802.11 available channel set, mark
121 * all available channels as active, and pick
122 * a default channel if not already specified.
123 */
95static int media_status(enum ieee80211_opmode,
96 const struct ieee80211_channel *);
97static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
98
99MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
100
101/*
102 * Default supported rates for 802.11 operation (in IEEE .5Mb units).

--- 12 unchanged lines hidden (view full) ---

115 { 12, { B(2), B(4), B(11), B(22), 12, 18, 24, 36, 48, 72, 96, 108 } };
116#undef B
117
118/*
119 * Fill in 802.11 available channel set, mark
120 * all available channels as active, and pick
121 * a default channel if not already specified.
122 */
124static void
123void
125ieee80211_chan_init(struct ieee80211com *ic)
126{
127#define DEFAULTRATES(m, def) do { \
128 if (ic->ic_sup_rates[m].rs_nrates == 0) \
129 ic->ic_sup_rates[m] = def; \
130} while (0)
131 struct ieee80211_channel *c;
132 int i;

--- 100 unchanged lines hidden (view full) ---

233
234static void
235null_update_promisc(struct ieee80211com *ic)
236{
237
238 ic_printf(ic, "need promiscuous mode update callback\n");
239}
240
124ieee80211_chan_init(struct ieee80211com *ic)
125{
126#define DEFAULTRATES(m, def) do { \
127 if (ic->ic_sup_rates[m].rs_nrates == 0) \
128 ic->ic_sup_rates[m] = def; \
129} while (0)
130 struct ieee80211_channel *c;
131 int i;

--- 100 unchanged lines hidden (view full) ---

232
233static void
234null_update_promisc(struct ieee80211com *ic)
235{
236
237 ic_printf(ic, "need promiscuous mode update callback\n");
238}
239
241static int
242null_transmit(struct ifnet *ifp, struct mbuf *m)
243{
244 m_freem(m);
245 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
246 return EACCES; /* XXX EIO/EPERM? */
247}
248
249static int
250null_output(struct ifnet *ifp, struct mbuf *m,
251 const struct sockaddr *dst, struct route *ro)
252{
253 if_printf(ifp, "discard raw packet\n");
254 return null_transmit(ifp, m);
255}
256
257static void
240static void
258null_input(struct ifnet *ifp, struct mbuf *m)
259{
260 if_printf(ifp, "if_input should not be called\n");
261 m_freem(m);
262}
263
264static void
265null_update_chw(struct ieee80211com *ic)
266{
267
268 ic_printf(ic, "%s: need callback\n", __func__);
269}
270
271int
272ic_printf(struct ieee80211com *ic, const char * fmt, ...)
273{
274 va_list ap;
275 int retval;
276
277 retval = printf("%s: ", ic->ic_name);
278 va_start(ap, fmt);
279 retval += vprintf(fmt, ap);
280 va_end(ap);
281 return (retval);
282}
283
241null_update_chw(struct ieee80211com *ic)
242{
243
244 ic_printf(ic, "%s: need callback\n", __func__);
245}
246
247int
248ic_printf(struct ieee80211com *ic, const char * fmt, ...)
249{
250 va_list ap;
251 int retval;
252
253 retval = printf("%s: ", ic->ic_name);
254 va_start(ap, fmt);
255 retval += vprintf(fmt, ap);
256 va_end(ap);
257 return (retval);
258}
259
260static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head);
261static struct mtx ic_list_mtx;
262MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF);
263
264static int
265sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS)
266{
267 struct ieee80211com *ic;
268 struct sbuf *sb;
269 char *sp;
270 int error;
271
272 sb = sbuf_new_auto();
273 sp = "";
274 mtx_lock(&ic_list_mtx);
275 LIST_FOREACH(ic, &ic_head, ic_next) {
276 sbuf_printf(sb, "%s%s", sp, ic->ic_name);
277 sp = " ";
278 }
279 mtx_unlock(&ic_list_mtx);
280 sbuf_finish(sb);
281 error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
282 sbuf_delete(sb);
283 return (error);
284}
285
286SYSCTL_PROC(_net_wlan, OID_AUTO, devices,
287 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
288 sysctl_ieee80211coms, "A", "names of available 802.11 devices");
289
284/*
285 * Attach/setup the common net80211 state. Called by
286 * the driver on attach to prior to creating any vap's.
287 */
288void
290/*
291 * Attach/setup the common net80211 state. Called by
292 * the driver on attach to prior to creating any vap's.
293 */
294void
289ieee80211_ifattach(struct ieee80211com *ic,
290 const uint8_t macaddr[IEEE80211_ADDR_LEN])
295ieee80211_ifattach(struct ieee80211com *ic)
291{
296{
292 struct ifnet *ifp = ic->ic_ifp;
293 struct sockaddr_dl *sdl;
294 struct ifaddr *ifa;
295
297
296 KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
297
298 IEEE80211_LOCK_INIT(ic, ic->ic_name);
299 IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
300 TAILQ_INIT(&ic->ic_vaps);
301
302 /* Create a taskqueue for all state changes */
303 ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
304 taskqueue_thread_enqueue, &ic->ic_tq);
305 taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
306 ic->ic_name);
307 ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
308 ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
309 /*
310 * Fill in 802.11 available channel set, mark all
311 * available channels as active, and pick a default
312 * channel if not already specified.
313 */
298 IEEE80211_LOCK_INIT(ic, ic->ic_name);
299 IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
300 TAILQ_INIT(&ic->ic_vaps);
301
302 /* Create a taskqueue for all state changes */
303 ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
304 taskqueue_thread_enqueue, &ic->ic_tq);
305 taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
306 ic->ic_name);
307 ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
308 ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
309 /*
310 * Fill in 802.11 available channel set, mark all
311 * available channels as active, and pick a default
312 * channel if not already specified.
313 */
314 ieee80211_media_init(ic);
314 ieee80211_chan_init(ic);
315
316 ic->ic_update_mcast = null_update_mcast;
317 ic->ic_update_promisc = null_update_promisc;
318 ic->ic_update_chw = null_update_chw;
319
320 ic->ic_hash_key = arc4random();
321 ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
322 ic->ic_lintval = ic->ic_bintval;

--- 8 unchanged lines hidden (view full) ---

331#endif
332 ieee80211_ht_attach(ic);
333 ieee80211_scan_attach(ic);
334 ieee80211_regdomain_attach(ic);
335 ieee80211_dfs_attach(ic);
336
337 ieee80211_sysctl_attach(ic);
338
315
316 ic->ic_update_mcast = null_update_mcast;
317 ic->ic_update_promisc = null_update_promisc;
318 ic->ic_update_chw = null_update_chw;
319
320 ic->ic_hash_key = arc4random();
321 ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
322 ic->ic_lintval = ic->ic_bintval;

--- 8 unchanged lines hidden (view full) ---

331#endif
332 ieee80211_ht_attach(ic);
333 ieee80211_scan_attach(ic);
334 ieee80211_regdomain_attach(ic);
335 ieee80211_dfs_attach(ic);
336
337 ieee80211_sysctl_attach(ic);
338
339 ifp->if_addrlen = IEEE80211_ADDR_LEN;
340 ifp->if_hdrlen = 0;
341
342 CURVNET_SET(vnet0);
343
344 if_attach(ifp);
345
346 ifp->if_mtu = IEEE80211_MTU_MAX;
347 ifp->if_broadcastaddr = ieee80211broadcastaddr;
348 ifp->if_output = null_output;
349 ifp->if_input = null_input; /* just in case */
350 ifp->if_resolvemulti = NULL; /* NB: callers check */
351
352 ifa = ifaddr_byindex(ifp->if_index);
353 KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
354 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
355 sdl->sdl_type = IFT_ETHER; /* XXX IFT_IEEE80211? */
356 sdl->sdl_alen = IEEE80211_ADDR_LEN;
357 IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
358 ifa_free(ifa);
359
360 CURVNET_RESTORE();
339 mtx_lock(&ic_list_mtx);
340 LIST_INSERT_HEAD(&ic_head, ic, ic_next);
341 mtx_unlock(&ic_list_mtx);
361}
362
363/*
364 * Detach net80211 state on device detach. Tear down
365 * all vap's and reclaim all common state prior to the
366 * device state going away. Note we may call back into
367 * driver; it must be prepared for this.
368 */
369void
370ieee80211_ifdetach(struct ieee80211com *ic)
371{
342}
343
344/*
345 * Detach net80211 state on device detach. Tear down
346 * all vap's and reclaim all common state prior to the
347 * device state going away. Note we may call back into
348 * driver; it must be prepared for this.
349 */
350void
351ieee80211_ifdetach(struct ieee80211com *ic)
352{
372 struct ifnet *ifp = ic->ic_ifp;
373 struct ieee80211vap *vap;
374
353 struct ieee80211vap *vap;
354
375 /*
376 * This detaches the main interface, but not the vaps.
377 * Each VAP may be in a separate VIMAGE.
378 */
379 CURVNET_SET(ifp->if_vnet);
380 if_detach(ifp);
381 CURVNET_RESTORE();
355 mtx_lock(&ic_list_mtx);
356 LIST_REMOVE(ic, ic_next);
357 mtx_unlock(&ic_list_mtx);
382
383 /*
384 * The VAP is responsible for setting and clearing
385 * the VIMAGE context.
386 */
387 while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
388 ieee80211_vap_destroy(vap);
389 ieee80211_waitfor_parent(ic);

--- 7 unchanged lines hidden (view full) ---

397#endif
398 ieee80211_ht_detach(ic);
399 /* NB: must be called before ieee80211_node_detach */
400 ieee80211_proto_detach(ic);
401 ieee80211_crypto_detach(ic);
402 ieee80211_power_detach(ic);
403 ieee80211_node_detach(ic);
404
358
359 /*
360 * The VAP is responsible for setting and clearing
361 * the VIMAGE context.
362 */
363 while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
364 ieee80211_vap_destroy(vap);
365 ieee80211_waitfor_parent(ic);

--- 7 unchanged lines hidden (view full) ---

373#endif
374 ieee80211_ht_detach(ic);
375 /* NB: must be called before ieee80211_node_detach */
376 ieee80211_proto_detach(ic);
377 ieee80211_crypto_detach(ic);
378 ieee80211_power_detach(ic);
379 ieee80211_node_detach(ic);
380
405 /* XXX VNET needed? */
406 ifmedia_removeall(&ic->ic_media);
407 counter_u64_free(ic->ic_ierrors);
408 counter_u64_free(ic->ic_oerrors);
409
410 taskqueue_free(ic->ic_tq);
411 IEEE80211_TX_LOCK_DESTROY(ic);
412 IEEE80211_LOCK_DESTROY(ic);
413}
414
381 counter_u64_free(ic->ic_ierrors);
382 counter_u64_free(ic->ic_oerrors);
383
384 taskqueue_free(ic->ic_tq);
385 IEEE80211_TX_LOCK_DESTROY(ic);
386 IEEE80211_LOCK_DESTROY(ic);
387}
388
389struct ieee80211com *
390ieee80211_find_com(const char *name)
391{
392 struct ieee80211com *ic;
393
394 mtx_lock(&ic_list_mtx);
395 LIST_FOREACH(ic, &ic_head, ic_next)
396 if (strcmp(ic->ic_name, name) == 0)
397 break;
398 mtx_unlock(&ic_list_mtx);
399
400 return (ic);
401}
402
415/*
416 * Default reset method for use with the ioctl support. This
417 * method is invoked after any state change in the 802.11
418 * layer that should be propagated to the hardware but not
419 * require re-initialization of the 802.11 state machine (e.g
420 * rescanning for an ap). We always return ENETRESET which
421 * should cause the driver to re-initialize the device. Drivers
422 * can override this method to implement more optimized support.

--- 32 unchanged lines hidden (view full) ---

455/*
456 * Prepare a vap for use. Drivers use this call to
457 * setup net80211 state in new vap's prior attaching
458 * them with ieee80211_vap_attach (below).
459 */
460int
461ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
462 const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
403/*
404 * Default reset method for use with the ioctl support. This
405 * method is invoked after any state change in the 802.11
406 * layer that should be propagated to the hardware but not
407 * require re-initialization of the 802.11 state machine (e.g
408 * rescanning for an ap). We always return ENETRESET which
409 * should cause the driver to re-initialize the device. Drivers
410 * can override this method to implement more optimized support.

--- 32 unchanged lines hidden (view full) ---

443/*
444 * Prepare a vap for use. Drivers use this call to
445 * setup net80211 state in new vap's prior attaching
446 * them with ieee80211_vap_attach (below).
447 */
448int
449ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
450 const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
463 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
464 const uint8_t macaddr[IEEE80211_ADDR_LEN])
451 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN])
465{
466 struct ifnet *ifp;
467
468 ifp = if_alloc(IFT_ETHER);
469 if (ifp == NULL) {
470 ic_printf(ic, "%s: unable to allocate ifnet\n",
471 __func__);
472 return ENOMEM;

--- 12 unchanged lines hidden (view full) ---

485 vap->iv_flags = ic->ic_flags; /* propagate common flags */
486 vap->iv_flags_ext = ic->ic_flags_ext;
487 vap->iv_flags_ven = ic->ic_flags_ven;
488 vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
489 vap->iv_htcaps = ic->ic_htcaps;
490 vap->iv_htextcaps = ic->ic_htextcaps;
491 vap->iv_opmode = opmode;
492 vap->iv_caps |= ieee80211_opcap[opmode];
452{
453 struct ifnet *ifp;
454
455 ifp = if_alloc(IFT_ETHER);
456 if (ifp == NULL) {
457 ic_printf(ic, "%s: unable to allocate ifnet\n",
458 __func__);
459 return ENOMEM;

--- 12 unchanged lines hidden (view full) ---

472 vap->iv_flags = ic->ic_flags; /* propagate common flags */
473 vap->iv_flags_ext = ic->ic_flags_ext;
474 vap->iv_flags_ven = ic->ic_flags_ven;
475 vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
476 vap->iv_htcaps = ic->ic_htcaps;
477 vap->iv_htextcaps = ic->ic_htextcaps;
478 vap->iv_opmode = opmode;
479 vap->iv_caps |= ieee80211_opcap[opmode];
480 vap->iv_myaddr = ic->ic_macaddr;
493 switch (opmode) {
494 case IEEE80211_M_WDS:
495 /*
496 * WDS links must specify the bssid of the far end.
497 * For legacy operation this is a static relationship.
498 * For non-legacy operation the station must associate
499 * and be authorized to pass traffic. Plumbing the
500 * vap to the proper node happens when the vap

--- 50 unchanged lines hidden (view full) ---

551 vap->iv_bmissthreshold = IEEE80211_HWBMISS_DEFAULT;
552 vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT;
553 /*
554 * Install a default reset method for the ioctl support;
555 * the driver can override this.
556 */
557 vap->iv_reset = default_reset;
558
481 switch (opmode) {
482 case IEEE80211_M_WDS:
483 /*
484 * WDS links must specify the bssid of the far end.
485 * For legacy operation this is a static relationship.
486 * For non-legacy operation the station must associate
487 * and be authorized to pass traffic. Plumbing the
488 * vap to the proper node happens when the vap

--- 50 unchanged lines hidden (view full) ---

539 vap->iv_bmissthreshold = IEEE80211_HWBMISS_DEFAULT;
540 vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT;
541 /*
542 * Install a default reset method for the ioctl support;
543 * the driver can override this.
544 */
545 vap->iv_reset = default_reset;
546
559 IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr);
560
561 ieee80211_sysctl_vattach(vap);
562 ieee80211_crypto_vattach(vap);
563 ieee80211_node_vattach(vap);
564 ieee80211_power_vattach(vap);
565 ieee80211_proto_vattach(vap);
566#ifdef IEEE80211_SUPPORT_SUPERG
567 ieee80211_superg_vattach(vap);
568#endif

--- 7 unchanged lines hidden (view full) ---

576}
577
578/*
579 * Activate a vap. State should have been prepared with a
580 * call to ieee80211_vap_setup and by the driver. On return
581 * from this call the vap is ready for use.
582 */
583int
547 ieee80211_sysctl_vattach(vap);
548 ieee80211_crypto_vattach(vap);
549 ieee80211_node_vattach(vap);
550 ieee80211_power_vattach(vap);
551 ieee80211_proto_vattach(vap);
552#ifdef IEEE80211_SUPPORT_SUPERG
553 ieee80211_superg_vattach(vap);
554#endif

--- 7 unchanged lines hidden (view full) ---

562}
563
564/*
565 * Activate a vap. State should have been prepared with a
566 * call to ieee80211_vap_setup and by the driver. On return
567 * from this call the vap is ready for use.
568 */
569int
584ieee80211_vap_attach(struct ieee80211vap *vap,
585 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
570ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change,
571 ifm_stat_cb_t media_stat, const uint8_t macaddr[IEEE80211_ADDR_LEN])
586{
587 struct ifnet *ifp = vap->iv_ifp;
588 struct ieee80211com *ic = vap->iv_ic;
589 struct ifmediareq imr;
590 int maxrate;
591
592 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
593 "%s: %s parent %s flags 0x%x flags_ext 0x%x\n",

--- 11 unchanged lines hidden (view full) ---

605 vap->iv_opmode == IEEE80211_M_STA, media_change, media_stat);
606 ieee80211_media_status(ifp, &imr);
607 /* NB: strip explicit mode; we're actually in autoselect */
608 ifmedia_set(&vap->iv_media,
609 imr.ifm_active &~ (IFM_MMASK | IFM_IEEE80211_TURBO));
610 if (maxrate)
611 ifp->if_baudrate = IF_Mbps(maxrate);
612
572{
573 struct ifnet *ifp = vap->iv_ifp;
574 struct ieee80211com *ic = vap->iv_ic;
575 struct ifmediareq imr;
576 int maxrate;
577
578 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
579 "%s: %s parent %s flags 0x%x flags_ext 0x%x\n",

--- 11 unchanged lines hidden (view full) ---

591 vap->iv_opmode == IEEE80211_M_STA, media_change, media_stat);
592 ieee80211_media_status(ifp, &imr);
593 /* NB: strip explicit mode; we're actually in autoselect */
594 ifmedia_set(&vap->iv_media,
595 imr.ifm_active &~ (IFM_MMASK | IFM_IEEE80211_TURBO));
596 if (maxrate)
597 ifp->if_baudrate = IF_Mbps(maxrate);
598
613 ether_ifattach(ifp, vap->iv_myaddr);
599 ether_ifattach(ifp, macaddr);
600 vap->iv_myaddr = IF_LLADDR(ifp);
614 /* hook output method setup by ether_ifattach */
615 vap->iv_output = ifp->if_output;
616 ifp->if_output = ieee80211_output;
617 /* NB: if_mtu set by ether_ifattach to ETHERMTU */
618
619 IEEE80211_LOCK(ic);
620 TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
621 ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
622#ifdef IEEE80211_SUPPORT_SUPERG
623 ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
624#endif
625 ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
626 ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
627 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
628 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
601 /* hook output method setup by ether_ifattach */
602 vap->iv_output = ifp->if_output;
603 ifp->if_output = ieee80211_output;
604 /* NB: if_mtu set by ether_ifattach to ETHERMTU */
605
606 IEEE80211_LOCK(ic);
607 TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
608 ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
609#ifdef IEEE80211_SUPPORT_SUPERG
610 ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
611#endif
612 ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
613 ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
614 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
615 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
629 ieee80211_syncifflag_locked(ic, IFF_PROMISC);
630 ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
631 IEEE80211_UNLOCK(ic);
632
633 return 1;
634}
635
636/*
637 * Tear down vap state and reclaim the ifnet.
638 * The driver is assumed to have prepared for

--- 33 unchanged lines hidden (view full) ---

672 ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
673#endif
674 ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
675 ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
676 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
677 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
678 /* NB: this handles the bpfdetach done below */
679 ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
616 IEEE80211_UNLOCK(ic);
617
618 return 1;
619}
620
621/*
622 * Tear down vap state and reclaim the ifnet.
623 * The driver is assumed to have prepared for

--- 33 unchanged lines hidden (view full) ---

657 ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
658#endif
659 ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
660 ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
661 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
662 ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
663 /* NB: this handles the bpfdetach done below */
664 ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
680 ieee80211_syncifflag_locked(ic, IFF_PROMISC);
681 ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
665 if (vap->iv_ifflags & IFF_PROMISC)
666 ieee80211_promisc(vap, false);
667 if (vap->iv_ifflags & IFF_ALLMULTI)
668 ieee80211_allmulti(vap, false);
682 IEEE80211_UNLOCK(ic);
683
684 ifmedia_removeall(&vap->iv_media);
685
686 ieee80211_radiotap_vdetach(vap);
687 ieee80211_regdomain_vdetach(vap);
688 ieee80211_scan_vdetach(vap);
689#ifdef IEEE80211_SUPPORT_SUPERG

--- 8 unchanged lines hidden (view full) ---

698 ieee80211_sysctl_vdetach(vap);
699
700 if_free(ifp);
701
702 CURVNET_RESTORE();
703}
704
705/*
669 IEEE80211_UNLOCK(ic);
670
671 ifmedia_removeall(&vap->iv_media);
672
673 ieee80211_radiotap_vdetach(vap);
674 ieee80211_regdomain_vdetach(vap);
675 ieee80211_scan_vdetach(vap);
676#ifdef IEEE80211_SUPPORT_SUPERG

--- 8 unchanged lines hidden (view full) ---

685 ieee80211_sysctl_vdetach(vap);
686
687 if_free(ifp);
688
689 CURVNET_RESTORE();
690}
691
692/*
706 * Synchronize flag bit state in the parent ifnet structure
707 * according to the state of all vap ifnet's. This is used,
708 * for example, to handle IFF_PROMISC and IFF_ALLMULTI.
693 * Count number of vaps in promisc, and issue promisc on
694 * parent respectively.
709 */
710void
695 */
696void
711ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
697ieee80211_promisc(struct ieee80211vap *vap, bool on)
712{
698{
713 struct ifnet *ifp = ic->ic_ifp;
714 struct ieee80211vap *vap;
715 int bit, oflags;
699 struct ieee80211com *ic = vap->iv_ic;
716
700
717 IEEE80211_LOCK_ASSERT(ic);
701 /*
702 * XXX the bridge sets PROMISC but we don't want to
703 * enable it on the device, discard here so all the
704 * drivers don't need to special-case it
705 */
706 if (!(vap->iv_opmode == IEEE80211_M_MONITOR ||
707 (vap->iv_opmode == IEEE80211_M_AHDEMO &&
708 (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
709 return;
718
710
719 bit = 0;
720 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
721 if (vap->iv_ifp->if_flags & flag) {
722 /*
723 * XXX the bridge sets PROMISC but we don't want to
724 * enable it on the device, discard here so all the
725 * drivers don't need to special-case it
726 */
727 if (flag == IFF_PROMISC &&
728 !(vap->iv_opmode == IEEE80211_M_MONITOR ||
729 (vap->iv_opmode == IEEE80211_M_AHDEMO &&
730 (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
731 continue;
732 bit = 1;
733 break;
734 }
735 oflags = ifp->if_flags;
736 if (bit)
737 ifp->if_flags |= flag;
738 else
739 ifp->if_flags &= ~flag;
740 if ((ifp->if_flags ^ oflags) & flag) {
741 /* XXX should we return 1/0 and let caller do this? */
742 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
743 if (flag == IFF_PROMISC)
744 ieee80211_runtask(ic, &ic->ic_promisc_task);
745 else if (flag == IFF_ALLMULTI)
746 ieee80211_runtask(ic, &ic->ic_mcast_task);
747 }
711 IEEE80211_LOCK(ic);
712 if (on) {
713 if (++ic->ic_promisc == 1)
714 ieee80211_runtask(ic, &ic->ic_promisc_task);
715 } else {
716 KASSERT(ic->ic_promisc > 0, ("%s: ic %p not promisc",
717 __func__, ic));
718 if (--ic->ic_promisc == 0)
719 ieee80211_runtask(ic, &ic->ic_promisc_task);
748 }
720 }
721 IEEE80211_UNLOCK(ic);
749}
750
751/*
722}
723
724/*
725 * Count number of vaps in allmulti, and issue allmulti on
726 * parent respectively.
727 */
728void
729ieee80211_allmulti(struct ieee80211vap *vap, bool on)
730{
731 struct ieee80211com *ic = vap->iv_ic;
732
733 IEEE80211_LOCK(ic);
734 if (on) {
735 if (++ic->ic_allmulti == 1)
736 ieee80211_runtask(ic, &ic->ic_mcast_task);
737 } else {
738 KASSERT(ic->ic_allmulti > 0, ("%s: ic %p not allmulti",
739 __func__, ic));
740 if (--ic->ic_allmulti == 0)
741 ieee80211_runtask(ic, &ic->ic_mcast_task);
742 }
743 IEEE80211_UNLOCK(ic);
744}
745
746/*
752 * Synchronize flag bit state in the com structure
753 * according to the state of all vap's. This is used,
754 * for example, to handle state changes via ioctls.
755 */
756static void
757ieee80211_syncflag_locked(struct ieee80211com *ic, int flag)
758{
759 struct ieee80211vap *vap;

--- 469 unchanged lines hidden (view full) ---

1229 else
1230 rate = ieee80211_htrates[i].ht20_rate_800ns;
1231 if (rate > maxrate)
1232 maxrate = rate;
1233 }
1234 return maxrate;
1235}
1236
747 * Synchronize flag bit state in the com structure
748 * according to the state of all vap's. This is used,
749 * for example, to handle state changes via ioctls.
750 */
751static void
752ieee80211_syncflag_locked(struct ieee80211com *ic, int flag)
753{
754 struct ieee80211vap *vap;

--- 469 unchanged lines hidden (view full) ---

1224 else
1225 rate = ieee80211_htrates[i].ht20_rate_800ns;
1226 if (rate > maxrate)
1227 maxrate = rate;
1228 }
1229 return maxrate;
1230}
1231
1237void
1238ieee80211_media_init(struct ieee80211com *ic)
1239{
1240 struct ifnet *ifp = ic->ic_ifp;
1241 int maxrate;
1242
1243 /* NB: this works because the structure is initialized to zero */
1244 if (!LIST_EMPTY(&ic->ic_media.ifm_list)) {
1245 /*
1246 * We are re-initializing the channel list; clear
1247 * the existing media state as the media routines
1248 * don't suppress duplicates.
1249 */
1250 ifmedia_removeall(&ic->ic_media);
1251 }
1252 ieee80211_chan_init(ic);
1253
1254 /*
1255 * Recalculate media settings in case new channel list changes
1256 * the set of available modes.
1257 */
1258 maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1,
1259 ieee80211com_media_change, ieee80211com_media_status);
1260 /* NB: strip explicit mode; we're actually in autoselect */
1261 ifmedia_set(&ic->ic_media,
1262 media_status(ic->ic_opmode, ic->ic_curchan) &~
1263 (IFM_MMASK | IFM_IEEE80211_TURBO));
1264 if (maxrate)
1265 ifp->if_baudrate = IF_Mbps(maxrate);
1266
1267 /* XXX need to propagate new media settings to vap's */
1268}
1269
1270/* XXX inline or eliminate? */
1271const struct ieee80211_rateset *
1272ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
1273{
1274 /* XXX does this work for 11ng basic rates? */
1275 return &ic->ic_sup_rates[ieee80211_chan2mode(c)];
1276}
1277

--- 112 unchanged lines hidden (view full) ---

1390 else
1391 return 0;
1392 }
1393 /* XXX HT40 +/- */
1394 return 1;
1395}
1396
1397/*
1232/* XXX inline or eliminate? */
1233const struct ieee80211_rateset *
1234ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
1235{
1236 /* XXX does this work for 11ng basic rates? */
1237 return &ic->ic_sup_rates[ieee80211_chan2mode(c)];
1238}
1239

--- 112 unchanged lines hidden (view full) ---

1352 else
1353 return 0;
1354 }
1355 /* XXX HT40 +/- */
1356 return 1;
1357}
1358
1359/*
1398 * Handle a media change request on the underlying interface.
1399 */
1400int
1401ieee80211com_media_change(struct ifnet *ifp)
1402{
1403 return EINVAL;
1404}
1405
1406/*
1407 * Handle a media change request on the vap interface.
1408 */
1409int
1410ieee80211_media_change(struct ifnet *ifp)
1411{
1412 struct ieee80211vap *vap = ifp->if_softc;
1413 struct ifmedia_entry *ime = vap->iv_media.ifm_cur;
1414 uint16_t newmode;

--- 60 unchanged lines hidden (view full) ---

1475 if (IEEE80211_IS_CHAN_HT20(chan))
1476 status |= IFM_IEEE80211_HT20;
1477 if (IEEE80211_IS_CHAN_HT40(chan))
1478 status |= IFM_IEEE80211_HT40;
1479#endif
1480 return status;
1481}
1482
1360 * Handle a media change request on the vap interface.
1361 */
1362int
1363ieee80211_media_change(struct ifnet *ifp)
1364{
1365 struct ieee80211vap *vap = ifp->if_softc;
1366 struct ifmedia_entry *ime = vap->iv_media.ifm_cur;
1367 uint16_t newmode;

--- 60 unchanged lines hidden (view full) ---

1428 if (IEEE80211_IS_CHAN_HT20(chan))
1429 status |= IFM_IEEE80211_HT20;
1430 if (IEEE80211_IS_CHAN_HT40(chan))
1431 status |= IFM_IEEE80211_HT40;
1432#endif
1433 return status;
1434}
1435
1483static void
1484ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1485{
1486 struct ieee80211com *ic = ifp->if_l2com;
1487 struct ieee80211vap *vap;
1488
1489 imr->ifm_status = IFM_AVALID;
1490 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
1491 if (vap->iv_ifp->if_flags & IFF_UP) {
1492 imr->ifm_status |= IFM_ACTIVE;
1493 break;
1494 }
1495 imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);
1496 if (imr->ifm_status & IFM_ACTIVE)
1497 imr->ifm_current = imr->ifm_active;
1498}
1499
1500void
1501ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1502{
1503 struct ieee80211vap *vap = ifp->if_softc;
1504 struct ieee80211com *ic = vap->iv_ic;
1505 enum ieee80211_phymode mode;
1506
1507 imr->ifm_status = IFM_AVALID;

--- 370 unchanged lines hidden ---
1436void
1437ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1438{
1439 struct ieee80211vap *vap = ifp->if_softc;
1440 struct ieee80211com *ic = vap->iv_ic;
1441 enum ieee80211_phymode mode;
1442
1443 imr->ifm_status = IFM_AVALID;

--- 370 unchanged lines hidden ---