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 --- |