if_ndis.c (124278) | if_ndis.c (124409) |
---|---|
1/* 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. 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 --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. 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 --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/if_ndis/if_ndis.c 124278 2004-01-09 06:53:49Z wpaul $"); | 34__FBSDID("$FreeBSD: head/sys/dev/if_ndis/if_ndis.c 124409 2004-01-12 03:49:20Z wpaul $"); |
35 36#include "opt_bdg.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/mbuf.h> 42#include <sys/malloc.h> --- 16 unchanged lines hidden (view full) --- 59#include <machine/bus.h> 60#include <machine/resource.h> 61#include <sys/bus.h> 62#include <sys/rman.h> 63 64#include <net80211/ieee80211_var.h> 65#include <net80211/ieee80211_ioctl.h> 66 | 35 36#include "opt_bdg.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/mbuf.h> 42#include <sys/malloc.h> --- 16 unchanged lines hidden (view full) --- 59#include <machine/bus.h> 60#include <machine/resource.h> 61#include <sys/bus.h> 62#include <sys/rman.h> 63 64#include <net80211/ieee80211_var.h> 65#include <net80211/ieee80211_ioctl.h> 66 |
67#include <dev/wi/if_wavelan_ieee.h> 68 |
|
67#include <dev/pci/pcireg.h> 68#include <dev/pci/pcivar.h> 69 70#include <compat/ndis/pe_var.h> 71#include <compat/ndis/resource_var.h> 72#include <compat/ndis/ndis_var.h> 73#include <compat/ndis/cfg_var.h> 74#include <dev/if_ndis/if_ndisvar.h> --- 32 unchanged lines hidden (view full) --- 107 108static void ndis_intr (void *); 109static void ndis_intrtask (void *, int); 110static void ndis_tick (void *); 111static void ndis_ticktask (void *, int); 112static void ndis_start (struct ifnet *); 113static void ndis_starttask (void *, int); 114static int ndis_ioctl (struct ifnet *, u_long, caddr_t); | 69#include <dev/pci/pcireg.h> 70#include <dev/pci/pcivar.h> 71 72#include <compat/ndis/pe_var.h> 73#include <compat/ndis/resource_var.h> 74#include <compat/ndis/ndis_var.h> 75#include <compat/ndis/cfg_var.h> 76#include <dev/if_ndis/if_ndisvar.h> --- 32 unchanged lines hidden (view full) --- 109 110static void ndis_intr (void *); 111static void ndis_intrtask (void *, int); 112static void ndis_tick (void *); 113static void ndis_ticktask (void *, int); 114static void ndis_start (struct ifnet *); 115static void ndis_starttask (void *, int); 116static int ndis_ioctl (struct ifnet *, u_long, caddr_t); |
117static int ndis_wi_ioctl_get (struct ifnet *, u_long, caddr_t); 118static int ndis_wi_ioctl_set (struct ifnet *, u_long, caddr_t); |
|
115static void ndis_init (void *); 116static void ndis_stop (struct ndis_softc *); 117static void ndis_watchdog (struct ifnet *); 118static void ndis_shutdown (device_t); 119static int ndis_ifmedia_upd (struct ifnet *); 120static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *); | 119static void ndis_init (void *); 120static void ndis_stop (struct ndis_softc *); 121static void ndis_watchdog (struct ifnet *); 122static void ndis_shutdown (device_t); 123static int ndis_ifmedia_upd (struct ifnet *); 124static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *); |
125static int ndis_get_assoc (struct ndis_softc *, ndis_wlan_bssid_ex *); |
|
121static void ndis_getstate_80211 (struct ndis_softc *); 122static void ndis_setstate_80211 (struct ndis_softc *); | 126static void ndis_getstate_80211 (struct ndis_softc *); 127static void ndis_setstate_80211 (struct ndis_softc *); |
128static void ndis_media_status (struct ifnet *, struct ifmediareq *); |
|
123 124static void ndis_reset (struct ndis_softc *); 125static void ndis_setmulti (struct ndis_softc *); 126static void ndis_map_sclist (void *, bus_dma_segment_t *, 127 int, bus_size_t, int); 128 | 129 130static void ndis_reset (struct ndis_softc *); 131static void ndis_setmulti (struct ndis_softc *); 132static void ndis_map_sclist (void *, bus_dma_segment_t *, 133 int, bus_size_t, int); 134 |
129#ifdef NDIS_USEIOSPACE 130#define NDIS_RES SYS_RES_IOPORT 131#define NDIS_RID NDIS_PCI_LOIO 132#else 133#define NDIS_RES SYS_RES_MEMORY 134#define NDIS_RID NDIS_PCI_LOMEM 135#endif | 135extern struct mtx_pool *ndis_mtxpool; |
136 137static device_method_t ndis_methods[] = { 138 /* Device interface */ 139 DEVMETHOD(device_probe, ndis_probe), 140 DEVMETHOD(device_attach, ndis_attach), 141 DEVMETHOD(device_detach, ndis_detach), 142 DEVMETHOD(device_shutdown, ndis_shutdown), 143 --- 90 unchanged lines hidden (view full) --- 234 struct resource_list *rl; 235 struct resource_list_entry *rle; 236 237 238 sc = device_get_softc(dev); 239 unit = device_get_unit(dev); 240 sc->ndis_dev = dev; 241 | 136 137static device_method_t ndis_methods[] = { 138 /* Device interface */ 139 DEVMETHOD(device_probe, ndis_probe), 140 DEVMETHOD(device_attach, ndis_attach), 141 DEVMETHOD(device_detach, ndis_detach), 142 DEVMETHOD(device_shutdown, ndis_shutdown), 143 --- 90 unchanged lines hidden (view full) --- 234 struct resource_list *rl; 235 struct resource_list_entry *rle; 236 237 238 sc = device_get_softc(dev); 239 unit = device_get_unit(dev); 240 sc->ndis_dev = dev; 241 |
242 mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 243 MTX_DEF | MTX_RECURSE); | 242 sc->ndis_mtx = mtx_pool_alloc(ndis_mtxpool); |
244 245 /* 246 * Map control/status registers. 247 */ | 243 244 /* 245 * Map control/status registers. 246 */ |
247 |
|
248 pci_enable_busmaster(dev); 249 250 rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); 251 if (rl != NULL) { 252 SLIST_FOREACH(rle, rl, link) { 253 switch (rle->type) { 254 case SYS_RES_IOPORT: 255 sc->ndis_io_rid = rle->rid; 256 sc->ndis_res_io = bus_alloc_resource(dev, 257 SYS_RES_IOPORT, &sc->ndis_io_rid, 258 0, ~0, 1, RF_ACTIVE); 259 if (sc->ndis_res_io == NULL) { 260 device_printf(dev, | 248 pci_enable_busmaster(dev); 249 250 rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); 251 if (rl != NULL) { 252 SLIST_FOREACH(rle, rl, link) { 253 switch (rle->type) { 254 case SYS_RES_IOPORT: 255 sc->ndis_io_rid = rle->rid; 256 sc->ndis_res_io = bus_alloc_resource(dev, 257 SYS_RES_IOPORT, &sc->ndis_io_rid, 258 0, ~0, 1, RF_ACTIVE); 259 if (sc->ndis_res_io == NULL) { 260 device_printf(dev, |
261 "couldn't map iospace"); | 261 "couldn't map iospace\n"); |
262 error = ENXIO; 263 goto fail; 264 } 265 break; 266 case SYS_RES_MEMORY: 267 if (sc->ndis_res_altmem != NULL && 268 sc->ndis_res_mem != NULL) { 269 device_printf(dev, | 262 error = ENXIO; 263 goto fail; 264 } 265 break; 266 case SYS_RES_MEMORY: 267 if (sc->ndis_res_altmem != NULL && 268 sc->ndis_res_mem != NULL) { 269 device_printf(dev, |
270 "too many memory resources"); | 270 "too many memory resources\n"); |
271 error = ENXIO; 272 goto fail; 273 } 274 if (rle->rid == PCIR_BAR(2)) { 275 sc->ndis_altmem_rid = rle->rid; 276 sc->ndis_res_altmem = 277 bus_alloc_resource(dev, 278 SYS_RES_MEMORY, 279 &sc->ndis_altmem_rid, 280 0, ~0, 1, RF_ACTIVE); 281 if (sc->ndis_res_altmem == NULL) { 282 device_printf(dev, | 271 error = ENXIO; 272 goto fail; 273 } 274 if (rle->rid == PCIR_BAR(2)) { 275 sc->ndis_altmem_rid = rle->rid; 276 sc->ndis_res_altmem = 277 bus_alloc_resource(dev, 278 SYS_RES_MEMORY, 279 &sc->ndis_altmem_rid, 280 0, ~0, 1, RF_ACTIVE); 281 if (sc->ndis_res_altmem == NULL) { 282 device_printf(dev, |
283 "couldn't map alt memory"); | 283 "couldn't map alt " 284 "memory\n"); |
284 error = ENXIO; 285 goto fail; 286 } 287 } else { 288 sc->ndis_mem_rid = rle->rid; 289 sc->ndis_res_mem = 290 bus_alloc_resource(dev, 291 SYS_RES_MEMORY, 292 &sc->ndis_mem_rid, 293 0, ~0, 1, RF_ACTIVE); 294 if (sc->ndis_res_mem == NULL) { 295 device_printf(dev, | 285 error = ENXIO; 286 goto fail; 287 } 288 } else { 289 sc->ndis_mem_rid = rle->rid; 290 sc->ndis_res_mem = 291 bus_alloc_resource(dev, 292 SYS_RES_MEMORY, 293 &sc->ndis_mem_rid, 294 0, ~0, 1, RF_ACTIVE); 295 if (sc->ndis_res_mem == NULL) { 296 device_printf(dev, |
296 "couldn't map memory"); | 297 "couldn't map memory\n"); |
297 error = ENXIO; 298 goto fail; 299 } 300 } 301 break; 302 case SYS_RES_IRQ: 303 rid = rle->rid; 304 sc->ndis_irq = bus_alloc_resource(dev, 305 SYS_RES_IRQ, &rid, 0, ~0, 1, 306 RF_SHAREABLE | RF_ACTIVE); 307 if (sc->ndis_irq == NULL) { 308 device_printf(dev, | 298 error = ENXIO; 299 goto fail; 300 } 301 } 302 break; 303 case SYS_RES_IRQ: 304 rid = rle->rid; 305 sc->ndis_irq = bus_alloc_resource(dev, 306 SYS_RES_IRQ, &rid, 0, ~0, 1, 307 RF_SHAREABLE | RF_ACTIVE); 308 if (sc->ndis_irq == NULL) { 309 device_printf(dev, |
309 "couldn't map interrupt"); | 310 "couldn't map interrupt\n"); |
310 error = ENXIO; 311 goto fail; 312 } 313 break; 314 default: 315 break; 316 } 317 sc->ndis_rescnt++; --- 8 unchanged lines hidden (view full) --- 326 error = bus_setup_intr(dev, sc->ndis_irq, INTR_TYPE_NET, 327 ndis_intr, sc, &sc->ndis_intrhand); 328 329 if (error) { 330 device_printf(dev, "couldn't set up irq\n"); 331 goto fail; 332 } 333 | 311 error = ENXIO; 312 goto fail; 313 } 314 break; 315 default: 316 break; 317 } 318 sc->ndis_rescnt++; --- 8 unchanged lines hidden (view full) --- 327 error = bus_setup_intr(dev, sc->ndis_irq, INTR_TYPE_NET, 328 ndis_intr, sc, &sc->ndis_intrhand); 329 330 if (error) { 331 device_printf(dev, "couldn't set up irq\n"); 332 goto fail; 333 } 334 |
334 mtx_init(&sc->ndis_intrmtx, device_get_nameunit(dev), "ndisisrlock", 335 MTX_DEF | MTX_RECURSE); | 335 sc->ndis_intrmtx = mtx_pool_alloc(ndis_mtxpool); |
336 TASK_INIT(&sc->ndis_intrtask, 0, ndis_intrtask, sc); 337 TASK_INIT(&sc->ndis_ticktask, 0, ndis_ticktask, sc); 338 TASK_INIT(&sc->ndis_starttask, 0, ndis_starttask, sc); 339 340 /* 341 * Allocate the parent bus DMA tag appropriate for PCI. 342 */ 343#define NDIS_NSEG_NEW 32 --- 131 unchanged lines hidden (view full) --- 475 ifp->if_ioctl = ndis_ioctl; 476 ifp->if_output = ether_output; 477 ifp->if_start = ndis_start; 478 ifp->if_watchdog = ndis_watchdog; 479 ifp->if_init = ndis_init; 480 ifp->if_baudrate = 10000000; 481 ifp->if_snd.ifq_maxlen = 50; 482 | 336 TASK_INIT(&sc->ndis_intrtask, 0, ndis_intrtask, sc); 337 TASK_INIT(&sc->ndis_ticktask, 0, ndis_ticktask, sc); 338 TASK_INIT(&sc->ndis_starttask, 0, ndis_starttask, sc); 339 340 /* 341 * Allocate the parent bus DMA tag appropriate for PCI. 342 */ 343#define NDIS_NSEG_NEW 32 --- 131 unchanged lines hidden (view full) --- 475 ifp->if_ioctl = ndis_ioctl; 476 ifp->if_output = ether_output; 477 ifp->if_start = ndis_start; 478 ifp->if_watchdog = ndis_watchdog; 479 ifp->if_init = ndis_init; 480 ifp->if_baudrate = 10000000; 481 ifp->if_snd.ifq_maxlen = 50; 482 |
483 /* 484 * Call MI attach routine. 485 */ 486 ether_ifattach(ifp, eaddr); 487 | |
488 /* Do media setup */ 489 if (sc->ndis_80211) { 490 struct ieee80211com *ic = (void *)ifp; | 483 /* Do media setup */ 484 if (sc->ndis_80211) { 485 struct ieee80211com *ic = (void *)ifp; |
486 ndis_80211_config config; |
|
491 ndis_80211_rates rates; | 487 ndis_80211_rates rates; |
488 struct ndis_80211_nettype_list *ntl; |
|
492 uint32_t arg; 493 int r; 494 495 ic->ic_phytype = IEEE80211_T_DS; 496 ic->ic_opmode = IEEE80211_M_STA; | 489 uint32_t arg; 490 int r; 491 492 ic->ic_phytype = IEEE80211_T_DS; 493 ic->ic_opmode = IEEE80211_M_STA; |
497 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS; 498 ic->ic_state = IEEE80211_S_RUN; | 494 ic->ic_caps = IEEE80211_C_IBSS; 495 ic->ic_state = IEEE80211_S_ASSOC; |
499 ic->ic_modecaps = (1<<IEEE80211_MODE_AUTO); | 496 ic->ic_modecaps = (1<<IEEE80211_MODE_AUTO); |
497 len = 0; 498 r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, 499 NULL, &len); 500 if (r != ENOSPC) 501 goto nonettypes; 502 ntl = malloc(len, M_DEVBUF, M_WAITOK); 503 r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, 504 ntl, &len); 505 if (r != 0) { 506 free(ntl, M_DEVBUF); 507 goto nonettypes; 508 } 509 510 for (i = 0; i < ntl->ntl_items; i++) { 511 switch (ntl->ntl_type[i]) { 512 case NDIS_80211_NETTYPE_11FH: 513 ic->ic_modecaps |= (1<<IEEE80211_MODE_11B); 514 break; 515 case NDIS_80211_NETTYPE_11DS: 516 ic->ic_modecaps |= (1<<IEEE80211_MODE_11B); 517 break; 518 case NDIS_80211_NETTYPE_11OFDM5: 519 ic->ic_modecaps |= (1<<IEEE80211_MODE_11A); 520 break; 521 case NDIS_80211_NETTYPE_11OFDM24: 522 ic->ic_modecaps |= (1<<IEEE80211_MODE_11G); 523 break; 524 default: 525 break; 526 } 527 } 528 free(ntl, M_DEVBUF); 529nonettypes: |
|
500 len = sizeof(rates); 501 bzero((char *)&rates, len); 502 r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, 503 (void *)rates, &len); 504 if (r) 505 device_printf (dev, "get rates failed: 0x%x\n", r); 506 /* | 530 len = sizeof(rates); 531 bzero((char *)&rates, len); 532 r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, 533 (void *)rates, &len); 534 if (r) 535 device_printf (dev, "get rates failed: 0x%x\n", r); 536 /* |
507 * We need a way to distinguish between 802.11b cards 508 * and 802.11g cards. Unfortunately, Microsoft doesn't 509 * really give us one, so we have to apply a bit of a 510 * heuristic here. If we ask for supported rates, and 511 * we get 8 of them, then we know this isn't just a 512 * plain 802.11b card, since those only support up to 513 * 4 rates. This doesn't help us distinguish 802.11g 514 * from 802.11a or turbo cards though. | 537 * Since the supported rates only up to 8 can be supported, 538 * if this is not 802.11b we're just going to be faking it 539 * all up to heck. |
515 */ 516#define SETRATE(x, y) \ | 540 */ 541#define SETRATE(x, y) \ |
517 ic->ic_sup_rates[x].rs_rates[ic->ic_sup_rates[x].rs_nrates] = (y); | 542 ic->ic_sup_rates[x].rs_rates[ic->ic_sup_rates[x].rs_nrates] = (y) |
518#define INCRATE(x) \ | 543#define INCRATE(x) \ |
519 ic->ic_sup_rates[x].rs_nrates++; | 544 ic->ic_sup_rates[x].rs_nrates++ |
520 | 545 |
521 if (rates[7]) { 522 ic->ic_curmode = IEEE80211_MODE_11G; 523 ic->ic_modecaps |= (1<<IEEE80211_MODE_11G)| 524 (1<<IEEE80211_MODE_11B); | 546 ic->ic_curmode = IEEE80211_MODE_AUTO; 547 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11A)) 548 ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0; 549 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11B)) |
525 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; | 550 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; |
551 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) |
|
526 ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0; | 552 ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0; |
527 for (i = 0; i < len; i++) { 528 switch(rates[i] & IEEE80211_RATE_VAL) { 529 case 2: 530 case 4: 531 case 11: 532 case 22: 533 SETRATE(IEEE80211_MODE_11B, rates[i]); 534 INCRATE(IEEE80211_MODE_11B); 535 break; 536 default: | 553 for (i = 0; i < len; i++) { 554 switch (rates[i] & IEEE80211_RATE_VAL) { 555 case 2: 556 case 4: 557 case 11: 558 case 10: 559 case 22: 560 if (!(ic->ic_modecaps & 561 (1<<IEEE80211_MODE_11B))) { 562 /* Lazy-init 802.11b. */ 563 ic->ic_modecaps |= 564 (1<<IEEE80211_MODE_11B); 565 ic->ic_sup_rates[IEEE80211_MODE_11B]. 566 rs_nrates = 0; 567 } 568 SETRATE(IEEE80211_MODE_11B, rates[i]); 569 INCRATE(IEEE80211_MODE_11B); 570 break; 571 default: 572 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11A)) { 573 SETRATE(IEEE80211_MODE_11A, rates[i]); 574 INCRATE(IEEE80211_MODE_11A); 575 } 576 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) { |
537 SETRATE(IEEE80211_MODE_11G, rates[i]); 538 INCRATE(IEEE80211_MODE_11G); | 577 SETRATE(IEEE80211_MODE_11G, rates[i]); 578 INCRATE(IEEE80211_MODE_11G); |
539 break; | |
540 } | 579 } |
580 break; |
|
541 } | 581 } |
582 } |
|
542 | 583 |
543 /* Now cheat by filling in the 54Mbps rates. */ 544 | 584 /* 585 * If the hardware supports 802.11g, it most 586 * likely supports 802.11b and all of the 587 * 802.11b and 802.11g speeds, so maybe we can 588 * just cheat here. Just how in the heck do 589 * we detect turbo modes, though? 590 */ 591 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) { |
545 SETRATE(IEEE80211_MODE_11G, 47); 546 INCRATE(IEEE80211_MODE_11G); 547 SETRATE(IEEE80211_MODE_11G, 72); 548 INCRATE(IEEE80211_MODE_11G); 549 SETRATE(IEEE80211_MODE_11G, 96); 550 INCRATE(IEEE80211_MODE_11G); 551 SETRATE(IEEE80211_MODE_11G, 108); 552 INCRATE(IEEE80211_MODE_11G); | 592 SETRATE(IEEE80211_MODE_11G, 47); 593 INCRATE(IEEE80211_MODE_11G); 594 SETRATE(IEEE80211_MODE_11G, 72); 595 INCRATE(IEEE80211_MODE_11G); 596 SETRATE(IEEE80211_MODE_11G, 96); 597 INCRATE(IEEE80211_MODE_11G); 598 SETRATE(IEEE80211_MODE_11G, 108); 599 INCRATE(IEEE80211_MODE_11G); |
553 } else { 554 ic->ic_curmode = IEEE80211_MODE_11B; 555 ic->ic_modecaps |= (1<<IEEE80211_MODE_11B); 556 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; 557 for (i = 0; i < len; i++) { 558 if (!rates[i]) 559 break; 560 SETRATE(IEEE80211_MODE_11B, rates[i]); 561 INCRATE(IEEE80211_MODE_11B); 562 } | |
563 } | 600 } |
601 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11A)) { 602 SETRATE(IEEE80211_MODE_11A, 47); 603 INCRATE(IEEE80211_MODE_11A); 604 SETRATE(IEEE80211_MODE_11A, 72); 605 INCRATE(IEEE80211_MODE_11A); 606 SETRATE(IEEE80211_MODE_11A, 96); 607 INCRATE(IEEE80211_MODE_11A); 608 SETRATE(IEEE80211_MODE_11A, 108); 609 INCRATE(IEEE80211_MODE_11A); 610 } |
|
564#undef SETRATE 565#undef INCRATE 566 /* | 611#undef SETRATE 612#undef INCRATE 613 /* |
567 * The Microsoft API has no support for getting/setting 568 * channels, so we lie like a rug here. If you wan to 569 * select a channel, use the sysctl/registry interface. | 614 * Taking yet more guesses here. |
570 */ | 615 */ |
571 for (i = 1; i < 11; i++) { | 616 for (i = 1; i < IEEE80211_CHAN_MAX; i++) { 617 int chanflag = 0; 618 619 if (ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates) 620 chanflag |= IEEE80211_CHAN_G; 621 if (i <= 14) 622 chanflag |= IEEE80211_CHAN_B; 623 if (chanflag == 0) 624 break; |
572 ic->ic_channels[i].ic_freq = | 625 ic->ic_channels[i].ic_freq = |
573 ieee80211_ieee2mhz(i, IEEE80211_CHAN_B); 574 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B; | 626 ieee80211_ieee2mhz(i, chanflag); 627 ic->ic_channels[i].ic_flags = chanflag; |
575 } 576 577 i = sizeof(arg); 578 r = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &i); 579 if (arg != NDIS_80211_WEPSTAT_NOTSUPPORTED) 580 ic->ic_caps |= IEEE80211_C_WEP; | 628 } 629 630 i = sizeof(arg); 631 r = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &i); 632 if (arg != NDIS_80211_WEPSTAT_NOTSUPPORTED) 633 ic->ic_caps |= IEEE80211_C_WEP; |
581 ieee80211_node_attach(ifp); | 634 i = sizeof(arg); 635 r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i); 636 if (r == 0) 637 ic->ic_caps |= IEEE80211_C_PMGT; 638 i = sizeof(config); 639 r = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &i); 640 if (r == 0) { 641 int chan; 642 chan = ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0); 643 if (chan < 0 || chan >= IEEE80211_CHAN_MAX) { 644 ic->ic_ibss_chan = &ic->ic_channels[1]; 645 } else 646 ic->ic_ibss_chan = &ic->ic_channels[chan]; 647 } else { 648 device_printf(sc->ndis_dev, "couldn't retrieve " 649 "channel info: %d\n", r); 650 ic->ic_ibss_chan = &ic->ic_channels[1]; 651 } 652 bcopy(eaddr, &ic->ic_myaddr, sizeof(eaddr)); 653 ieee80211_ifattach(ifp); |
582 ieee80211_media_init(ifp, ieee80211_media_change, | 654 ieee80211_media_init(ifp, ieee80211_media_change, |
583 ieee80211_media_status); 584 ic->ic_ibss_chan = &ic->ic_channels[1]; 585 ic->ic_bss->ni_chan = &ic->ic_channels[1]; | 655 ndis_media_status); 656 ic->ic_bss->ni_chan = ic->ic_ibss_chan; |
586 } else { 587 ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, 588 ndis_ifmedia_sts); 589 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 590 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 591 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); 592 ifmedia_add(&sc->ifmedia, 593 IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); 594 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); 595 ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO); | 657 } else { 658 ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, 659 ndis_ifmedia_sts); 660 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 661 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 662 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); 663 ifmedia_add(&sc->ifmedia, 664 IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); 665 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); 666 ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO); |
667 ether_ifattach(ifp, eaddr); |
|
596 } 597 598 /* Override the status handler so we can detect link changes. */ 599 sc->ndis_block.nmb_status_func = ndis_linksts; 600 sc->ndis_block.nmb_statusdone_func = ndis_linksts_done; 601fail: 602 if (error) 603 ndis_detach(dev); --- 23 unchanged lines hidden (view full) --- 627 628 sc = device_get_softc(dev); 629 KASSERT(mtx_initialized(&sc->ndis_mtx), ("ndis mutex not initialized")); 630 NDIS_LOCK(sc); 631 ifp = &sc->arpcom.ac_if; 632 ifp->if_flags &= ~IFF_UP; 633 634 if (device_is_attached(dev)) { | 668 } 669 670 /* Override the status handler so we can detect link changes. */ 671 sc->ndis_block.nmb_status_func = ndis_linksts; 672 sc->ndis_block.nmb_statusdone_func = ndis_linksts_done; 673fail: 674 if (error) 675 ndis_detach(dev); --- 23 unchanged lines hidden (view full) --- 699 700 sc = device_get_softc(dev); 701 KASSERT(mtx_initialized(&sc->ndis_mtx), ("ndis mutex not initialized")); 702 NDIS_LOCK(sc); 703 ifp = &sc->arpcom.ac_if; 704 ifp->if_flags &= ~IFF_UP; 705 706 if (device_is_attached(dev)) { |
635 if (sc->ndis_80211) { 636 ifmedia_removeall(&sc->ic.ic_media); 637 ieee80211_node_detach(ifp); 638 } | |
639 NDIS_UNLOCK(sc); 640 ndis_stop(sc); | 707 NDIS_UNLOCK(sc); 708 ndis_stop(sc); |
641 ether_ifdetach(ifp); | 709 if (sc->ndis_80211) 710 ieee80211_ifdetach(ifp); 711 else 712 ether_ifdetach(ifp); |
642 } else 643 NDIS_UNLOCK(sc); 644 645 bus_generic_detach(dev); 646 647 if (sc->ndis_intrhand) 648 bus_teardown_intr(dev, sc->ndis_irq, sc->ndis_intrhand); 649 if (sc->ndis_irq) --- 12 unchanged lines hidden (view full) --- 662 ndis_destroy_dma(sc); 663 664 ndis_unload_driver((void *)ifp); 665 666 bus_dma_tag_destroy(sc->ndis_parent_tag); 667 668 sysctl_ctx_free(&sc->ndis_ctx); 669 | 713 } else 714 NDIS_UNLOCK(sc); 715 716 bus_generic_detach(dev); 717 718 if (sc->ndis_intrhand) 719 bus_teardown_intr(dev, sc->ndis_irq, sc->ndis_intrhand); 720 if (sc->ndis_irq) --- 12 unchanged lines hidden (view full) --- 733 ndis_destroy_dma(sc); 734 735 ndis_unload_driver((void *)ifp); 736 737 bus_dma_tag_destroy(sc->ndis_parent_tag); 738 739 sysctl_ctx_free(&sc->ndis_ctx); 740 |
670 mtx_destroy(&sc->ndis_intrmtx); 671 mtx_destroy(&sc->ndis_mtx); 672 | |
673 return(0); 674} 675 676/* 677 * A frame has been uploaded: pass the resulting mbuf chain up to 678 * the higher level protocols. 679 * 680 * When handling received NDIS packets, the 'status' field in the --- 123 unchanged lines hidden (view full) --- 804 ifp = block->nmb_ifp; 805 sc = ifp->if_softc; 806 807 if (!(ifp->if_flags & IFF_UP)) 808 return; 809 810 switch (block->nmb_getstat) { 811 case NDIS_STATUS_MEDIA_CONNECT: | 741 return(0); 742} 743 744/* 745 * A frame has been uploaded: pass the resulting mbuf chain up to 746 * the higher level protocols. 747 * 748 * When handling received NDIS packets, the 'status' field in the --- 123 unchanged lines hidden (view full) --- 872 ifp = block->nmb_ifp; 873 sc = ifp->if_softc; 874 875 if (!(ifp->if_flags & IFF_UP)) 876 return; 877 878 switch (block->nmb_getstat) { 879 case NDIS_STATUS_MEDIA_CONNECT: |
812 sc->ndis_link = 1; 813 device_printf(sc->ndis_dev, "link up\n"); 814 if (sc->ndis_80211) 815 ndis_getstate_80211(sc); | 880 taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask); |
816 taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask); 817 break; 818 case NDIS_STATUS_MEDIA_DISCONNECT: | 881 taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask); 882 break; 883 case NDIS_STATUS_MEDIA_DISCONNECT: |
819 device_printf(sc->ndis_dev, "link down\n"); | |
820 if (sc->ndis_80211) 821 ndis_getstate_80211(sc); | 884 if (sc->ndis_80211) 885 ndis_getstate_80211(sc); |
822 sc->ndis_link = 0; | 886 taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask); |
823 break; 824 default: 825 break; 826 } 827 828 return; 829} 830 --- 6 unchanged lines hidden (view full) --- 837 struct ifnet *ifp; 838 839 sc = arg; 840 ifp = &sc->arpcom.ac_if; 841 842 NDIS_LOCK(sc); 843 ndis_intrhand(sc); 844 NDIS_UNLOCK(sc); | 887 break; 888 default: 889 break; 890 } 891 892 return; 893} 894 --- 6 unchanged lines hidden (view full) --- 901 struct ifnet *ifp; 902 903 sc = arg; 904 ifp = &sc->arpcom.ac_if; 905 906 NDIS_LOCK(sc); 907 ndis_intrhand(sc); 908 NDIS_UNLOCK(sc); |
845 mtx_lock(&sc->ndis_intrmtx); | 909 mtx_lock(sc->ndis_intrmtx); |
846 ndis_enable_intr(sc); | 910 ndis_enable_intr(sc); |
847 mtx_unlock(&sc->ndis_intrmtx); | 911 mtx_unlock(sc->ndis_intrmtx); |
848 849 if (ifp->if_snd.ifq_head != NULL) 850 ndis_start(ifp); 851 852 return; 853} 854 855static void --- 6 unchanged lines hidden (view full) --- 862 int call_isr = 0; 863 864 sc = arg; 865 ifp = &sc->arpcom.ac_if; 866 867 if (!(ifp->if_flags & IFF_UP)) 868 return; 869 | 912 913 if (ifp->if_snd.ifq_head != NULL) 914 ndis_start(ifp); 915 916 return; 917} 918 919static void --- 6 unchanged lines hidden (view full) --- 926 int call_isr = 0; 927 928 sc = arg; 929 ifp = &sc->arpcom.ac_if; 930 931 if (!(ifp->if_flags & IFF_UP)) 932 return; 933 |
870 mtx_lock(&sc->ndis_intrmtx); | 934 mtx_lock(sc->ndis_intrmtx); |
871 if (sc->ndis_block.nmb_interrupt->ni_isrreq == TRUE) 872 ndis_isr(sc, &is_our_intr, &call_isr); 873 else { 874 ndis_disable_intr(sc); 875 call_isr = 1; 876 } | 935 if (sc->ndis_block.nmb_interrupt->ni_isrreq == TRUE) 936 ndis_isr(sc, &is_our_intr, &call_isr); 937 else { 938 ndis_disable_intr(sc); 939 call_isr = 1; 940 } |
877 mtx_unlock(&sc->ndis_intrmtx); | 941 mtx_unlock(sc->ndis_intrmtx); |
878 879 if (is_our_intr || call_isr) 880 taskqueue_enqueue(taskqueue_swi, &sc->ndis_intrtask); 881 882 return; 883} 884 885static void 886ndis_tick(xsc) 887 void *xsc; 888{ 889 struct ndis_softc *sc; 890 sc = xsc; 891 taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask); | 942 943 if (is_our_intr || call_isr) 944 taskqueue_enqueue(taskqueue_swi, &sc->ndis_intrtask); 945 946 return; 947} 948 949static void 950ndis_tick(xsc) 951 void *xsc; 952{ 953 struct ndis_softc *sc; 954 sc = xsc; 955 taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask); |
956 sc->ndis_stat_ch = timeout(ndis_tick, sc, hz * 957 sc->ndis_block.nmb_checkforhangsecs); 958 |
|
892} 893 894static void 895ndis_ticktask(xsc, pending) 896 void *xsc; 897 int pending; 898{ 899 struct ndis_softc *sc; --- 5 unchanged lines hidden (view full) --- 905 sc = xsc; 906 907 len = sizeof(linkstate); 908 error = ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS, 909 (void *)&linkstate, &len); 910 911 NDIS_LOCK(sc); 912 | 959} 960 961static void 962ndis_ticktask(xsc, pending) 963 void *xsc; 964 int pending; 965{ 966 struct ndis_softc *sc; --- 5 unchanged lines hidden (view full) --- 972 sc = xsc; 973 974 len = sizeof(linkstate); 975 error = ndis_get_info(sc, OID_GEN_MEDIA_CONNECT_STATUS, 976 (void *)&linkstate, &len); 977 978 NDIS_LOCK(sc); 979 |
913 if (linkstate == nmc_connected) | 980 if (sc->ndis_link == 0 && linkstate == nmc_connected) { 981 device_printf(sc->ndis_dev, "link up\n"); |
914 sc->ndis_link = 1; | 982 sc->ndis_link = 1; |
983 if (sc->ndis_80211) 984 ndis_getstate_80211(sc); 985 } |
|
915 | 986 |
987 if (sc->ndis_link == 1 && linkstate == nmc_disconnected) { 988 device_printf(sc->ndis_dev, "link down\n"); 989 sc->ndis_link = 0; 990 } 991 992 NDIS_UNLOCK(sc); 993 |
|
916 hangfunc = sc->ndis_chars.nmc_checkhang_func; 917 918 if (hangfunc != NULL) { 919 rval = hangfunc(sc->ndis_block.nmb_miniportadapterctx); 920 if (rval == TRUE) 921 ndis_reset_nic(sc); 922 } 923 | 994 hangfunc = sc->ndis_chars.nmc_checkhang_func; 995 996 if (hangfunc != NULL) { 997 rval = hangfunc(sc->ndis_block.nmb_miniportadapterctx); 998 if (rval == TRUE) 999 ndis_reset_nic(sc); 1000 } 1001 |
924 sc->ndis_stat_ch = timeout(ndis_tick, sc, hz * 925 sc->ndis_block.nmb_checkforhangsecs); 926 927 NDIS_UNLOCK(sc); 928 | |
929 return; 930} 931 932static void 933ndis_map_sclist(arg, segs, nseg, mapsize, error) 934 void *arg; 935 bus_dma_segment_t *segs; 936 int nseg; --- 286 unchanged lines hidden (view full) --- 1223} 1224 1225static void 1226ndis_setstate_80211(sc) 1227 struct ndis_softc *sc; 1228{ 1229 struct ieee80211com *ic; 1230 ndis_80211_ssid ssid; | 1002 return; 1003} 1004 1005static void 1006ndis_map_sclist(arg, segs, nseg, mapsize, error) 1007 void *arg; 1008 bus_dma_segment_t *segs; 1009 int nseg; --- 286 unchanged lines hidden (view full) --- 1296} 1297 1298static void 1299ndis_setstate_80211(sc) 1300 struct ndis_softc *sc; 1301{ 1302 struct ieee80211com *ic; 1303 ndis_80211_ssid ssid; |
1304 ndis_80211_config config; |
|
1231 ndis_80211_wep wep; 1232 int i, rval = 0, len; 1233 uint32_t arg; 1234 struct ifnet *ifp; 1235 1236 ic = &sc->ic; 1237 ifp = &sc->ic.ic_ac.ac_if; 1238 --- 17 unchanged lines hidden (view full) --- 1256 1257 rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len); 1258 1259 if (rval) 1260 device_printf (sc->ndis_dev, "set infra failed: %d\n", rval); 1261 1262 /* Set WEP */ 1263 | 1305 ndis_80211_wep wep; 1306 int i, rval = 0, len; 1307 uint32_t arg; 1308 struct ifnet *ifp; 1309 1310 ic = &sc->ic; 1311 ifp = &sc->ic.ic_ac.ac_if; 1312 --- 17 unchanged lines hidden (view full) --- 1330 1331 rval = ndis_set_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len); 1332 1333 if (rval) 1334 device_printf (sc->ndis_dev, "set infra failed: %d\n", rval); 1335 1336 /* Set WEP */ 1337 |
1338#ifdef IEEE80211_F_WEPON |
|
1264 if (ic->ic_flags & IEEE80211_F_WEPON) { | 1339 if (ic->ic_flags & IEEE80211_F_WEPON) { |
1340#else 1341 if (ic->ic_wep_mode >= IEEE80211_WEP_ON) { 1342#endif |
|
1265 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1266 if (ic->ic_nw_keys[i].wk_len) { 1267 bzero((char *)&wep, sizeof(wep)); 1268 wep.nw_keylen = ic->ic_nw_keys[i].wk_len; 1269#ifdef notdef 1270 /* 5 and 13 are the only valid key lengths */ 1271 if (ic->ic_nw_keys[i].wk_len < 5) 1272 wep.nw_keylen = 5; --- 17 unchanged lines hidden (view full) --- 1290 } 1291 } 1292 arg = NDIS_80211_WEPSTAT_ENABLED; 1293 len = sizeof(arg); 1294 rval = ndis_set_info(sc, OID_802_11_WEP_STATUS, &arg, &len); 1295 if (rval) 1296 device_printf(sc->ndis_dev, 1297 "enable WEP failed: %d\n", rval); | 1343 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1344 if (ic->ic_nw_keys[i].wk_len) { 1345 bzero((char *)&wep, sizeof(wep)); 1346 wep.nw_keylen = ic->ic_nw_keys[i].wk_len; 1347#ifdef notdef 1348 /* 5 and 13 are the only valid key lengths */ 1349 if (ic->ic_nw_keys[i].wk_len < 5) 1350 wep.nw_keylen = 5; --- 17 unchanged lines hidden (view full) --- 1368 } 1369 } 1370 arg = NDIS_80211_WEPSTAT_ENABLED; 1371 len = sizeof(arg); 1372 rval = ndis_set_info(sc, OID_802_11_WEP_STATUS, &arg, &len); 1373 if (rval) 1374 device_printf(sc->ndis_dev, 1375 "enable WEP failed: %d\n", rval); |
1376#ifndef IEEE80211_F_WEPON 1377 if (ic->ic_wep_mode != IEEE80211_WEP_8021X && 1378 ic->ic_wep_mode != IEEE80211_WEP_ON) 1379 arg = NDIS_80211_PRIVFILT_ACCEPTALL; 1380 else 1381#endif 1382 arg = NDIS_80211_PRIVFILT_8021XWEP; 1383 len = sizeof(arg); 1384 rval = ndis_set_info(sc, OID_802_11_PRIVACY_FILTER, &arg, &len); 1385#ifdef IEEE80211_WEP_8021X /*IEEE80211_F_WEPON*/ 1386 /* Accept that we only have "shared" and 802.1x modes. */ 1387 if (rval == 0) { 1388 if (arg == NDIS_80211_PRIVFILT_ACCEPTALL) 1389 ic->ic_wep_mode = IEEE80211_WEP_MIXED; 1390 else 1391 ic->ic_wep_mode = IEEE80211_WEP_8021X; 1392 } 1393#endif |
|
1298 } else { 1299 arg = NDIS_80211_WEPSTAT_DISABLED; 1300 len = sizeof(arg); 1301 ndis_set_info(sc, OID_802_11_WEP_STATUS, &arg, &len); 1302 } 1303 | 1394 } else { 1395 arg = NDIS_80211_WEPSTAT_DISABLED; 1396 len = sizeof(arg); 1397 ndis_set_info(sc, OID_802_11_WEP_STATUS, &arg, &len); 1398 } 1399 |
1304 | |
1305 /* Set SSID. */ 1306 1307 len = sizeof(ssid); 1308 bzero((char *)&ssid, len); 1309 ssid.ns_ssidlen = ic->ic_des_esslen; 1310 if (ssid.ns_ssidlen == 0) { 1311 ssid.ns_ssidlen = 1; 1312 } else 1313 bcopy(ic->ic_des_essid, ssid.ns_ssid, ssid.ns_ssidlen); 1314 rval = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len); 1315 1316 if (rval) 1317 device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval); 1318 | 1400 /* Set SSID. */ 1401 1402 len = sizeof(ssid); 1403 bzero((char *)&ssid, len); 1404 ssid.ns_ssidlen = ic->ic_des_esslen; 1405 if (ssid.ns_ssidlen == 0) { 1406 ssid.ns_ssidlen = 1; 1407 } else 1408 bcopy(ic->ic_des_essid, ssid.ns_ssid, ssid.ns_ssidlen); 1409 rval = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len); 1410 1411 if (rval) 1412 device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval); 1413 |
1414 len = sizeof(config); 1415 rval = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &len); 1416 if (rval == 0) { 1417 int chan; 1418 1419 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 1420 if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) { 1421 config.nc_dsconfig = 1422 ic->ic_bss->ni_chan->ic_freq * 1000; 1423 rval = ndis_set_info(sc, OID_802_11_CONFIGURATION, 1424 &config, &len); 1425 if (rval) 1426 device_printf(sc->ndis_dev, "couldn't change " 1427 "DS config to %ukHz: %d\n", 1428 config.nc_dsconfig, rval); 1429 } 1430 } else 1431 device_printf(sc->ndis_dev, "couldn't retrieve " 1432 "channel info: %d\n", rval); 1433 |
|
1319 return; 1320} 1321 1322static void | 1434 return; 1435} 1436 1437static void |
1438ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1439{ 1440 struct ieee80211com *ic = (void *)ifp; 1441 struct ieee80211_node *ni = NULL; 1442 1443 imr->ifm_status = IFM_AVALID; 1444 imr->ifm_active = IFM_IEEE80211; 1445 if (ic->ic_state == IEEE80211_S_RUN) 1446 imr->ifm_status |= IFM_ACTIVE; 1447 imr->ifm_active |= IFM_AUTO; 1448 switch (ic->ic_opmode) { 1449 case IEEE80211_M_STA: 1450 ni = ic->ic_bss; 1451 /* calculate rate subtype */ 1452 imr->ifm_active |= ieee80211_rate2media(ic, 1453 ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode); 1454 break; 1455 case IEEE80211_M_IBSS: 1456 ni = ic->ic_bss; 1457 /* calculate rate subtype */ 1458 imr->ifm_active |= ieee80211_rate2media(ic, 1459 ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode); 1460 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1461 break; 1462 case IEEE80211_M_AHDEMO: 1463 /* should not come here */ 1464 break; 1465 case IEEE80211_M_HOSTAP: 1466 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 1467 break; 1468 case IEEE80211_M_MONITOR: 1469 imr->ifm_active |= IFM_IEEE80211_MONITOR; 1470 break; 1471 } 1472 switch (ic->ic_curmode) { 1473 case IEEE80211_MODE_11A: 1474 imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A); 1475 break; 1476 case IEEE80211_MODE_11B: 1477 imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11B); 1478 break; 1479 case IEEE80211_MODE_11G: 1480 imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11G); 1481 break; 1482 case IEEE80211_MODE_TURBO: 1483 imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A) 1484 | IFM_IEEE80211_TURBO; 1485 break; 1486 } 1487} 1488 1489static int 1490ndis_get_assoc(sc, assoc) 1491 struct ndis_softc *sc; 1492 ndis_wlan_bssid_ex *assoc; 1493{ 1494 ndis_80211_bssid_list_ex *bl; 1495 ndis_wlan_bssid_ex *bs; 1496 ndis_80211_macaddr bssid; 1497 int i, len, error; 1498 1499 len = sizeof(bssid); 1500 error = ndis_get_info(sc, OID_802_11_BSSID, &bssid, &len); 1501 if (error) { 1502 device_printf(sc->ndis_dev, "failed to get bssid"); 1503 return(ENOENT); 1504 } 1505 len = 0; 1506 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); 1507 if (error != ENOSPC) { 1508 device_printf(sc->ndis_dev, "bssid_list failed"); 1509 return (error); 1510 } 1511 1512 bl = malloc(len, M_TEMP, M_NOWAIT); 1513 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); 1514 if (error) { 1515 free(bl, M_TEMP); 1516 device_printf(sc->ndis_dev, "bssid_list failed"); 1517 return (error); 1518 } 1519 1520 bs = (ndis_wlan_bssid_ex *)&bl->nblx_bssid[0]; 1521 for (i = 0; i < bl->nblx_items; i++) { 1522 if (bcmp(bs->nwbx_macaddr, bssid, sizeof(bssid)) == 0) { 1523 bcopy((char *)bs, (char *)assoc, bs->nwbx_len); 1524 free(bl, M_TEMP); 1525 return(0); 1526 } 1527 bs = (ndis_wlan_bssid_ex *)((char *)bs + bs->nwbx_len); 1528 } 1529 1530 free(bl, M_TEMP); 1531 return(ENOENT); 1532} 1533 1534static void |
|
1323ndis_getstate_80211(sc) 1324 struct ndis_softc *sc; 1325{ 1326 struct ieee80211com *ic; 1327 ndis_80211_ssid ssid; | 1535ndis_getstate_80211(sc) 1536 struct ndis_softc *sc; 1537{ 1538 struct ieee80211com *ic; 1539 ndis_80211_ssid ssid; |
1540 ndis_80211_config config; 1541 ndis_wlan_bssid_ex bs; |
|
1328 int rval, len, i = 0; 1329 uint32_t arg; 1330 struct ifnet *ifp; 1331 1332 ic = &sc->ic; 1333 ifp = &sc->ic.ic_ac.ac_if; 1334 1335 if (!(ifp->if_flags & IFF_UP)) 1336 return; 1337 1338 if (sc->ndis_link) 1339 ic->ic_state = IEEE80211_S_RUN; 1340 else 1341 ic->ic_state = IEEE80211_S_ASSOC; | 1542 int rval, len, i = 0; 1543 uint32_t arg; 1544 struct ifnet *ifp; 1545 1546 ic = &sc->ic; 1547 ifp = &sc->ic.ic_ac.ac_if; 1548 1549 if (!(ifp->if_flags & IFF_UP)) 1550 return; 1551 1552 if (sc->ndis_link) 1553 ic->ic_state = IEEE80211_S_RUN; 1554 else 1555 ic->ic_state = IEEE80211_S_ASSOC; |
1342/* 1343 len = sizeof(arg); 1344 rval = ndis_get_info(sc, OID_802_11_INFRASTRUCTURE_MODE, &arg, &len); | |
1345 | 1556 |
1346 if (rval) 1347 device_printf (sc->ndis_dev, "get infra failed: %d\n", rval); | |
1348 | 1557 |
1349 switch(arg) { 1350 case NDIS_80211_NET_INFRA_IBSS: 1351 ic->ic_opmode = IEEE80211_M_IBSS; 1352 break; 1353 case NDIS_80211_NET_INFRA_BSS: 1354 ic->ic_opmode = IEEE80211_M_STA; 1355 break; 1356 default: 1357 break; | 1558 /* 1559 * If we're associated, retrieve info on the current bssid. 1560 */ 1561 if (ndis_get_assoc(sc, &bs) == 0) { 1562 switch(bs.nwbx_nettype) { 1563 case NDIS_80211_NETTYPE_11FH: 1564 case NDIS_80211_NETTYPE_11DS: 1565 ic->ic_curmode = IEEE80211_MODE_11B; 1566 break; 1567 case NDIS_80211_NETTYPE_11OFDM5: 1568 ic->ic_curmode = IEEE80211_MODE_11A; 1569 break; 1570 case NDIS_80211_NETTYPE_11OFDM24: 1571 ic->ic_curmode = IEEE80211_MODE_11G; 1572 break; 1573 default: 1574 device_printf(sc->ndis_dev, 1575 "unknown nettype %d\n", arg); 1576 break; 1577 } |
1358 } | 1578 } |
1359*/ | 1579 |
1360 len = sizeof(ssid); 1361 bzero((char *)&ssid, len); 1362 rval = ndis_get_info(sc, OID_802_11_SSID, &ssid, &len); 1363 1364 if (rval) 1365 device_printf (sc->ndis_dev, "get ssid failed: %d\n", rval); 1366 bcopy(ssid.ns_ssid, ic->ic_bss->ni_essid, ssid.ns_ssidlen); 1367 ic->ic_bss->ni_esslen = ssid.ns_ssidlen; 1368 1369 len = sizeof(arg); 1370 rval = ndis_get_info(sc, OID_GEN_LINK_SPEED, &arg, &len); 1371 1372 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11B)) { 1373 ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B]; 1374 for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) { 1375 if ((ic->ic_bss->ni_rates.rs_rates[i] & | 1580 len = sizeof(ssid); 1581 bzero((char *)&ssid, len); 1582 rval = ndis_get_info(sc, OID_802_11_SSID, &ssid, &len); 1583 1584 if (rval) 1585 device_printf (sc->ndis_dev, "get ssid failed: %d\n", rval); 1586 bcopy(ssid.ns_ssid, ic->ic_bss->ni_essid, ssid.ns_ssidlen); 1587 ic->ic_bss->ni_esslen = ssid.ns_ssidlen; 1588 1589 len = sizeof(arg); 1590 rval = ndis_get_info(sc, OID_GEN_LINK_SPEED, &arg, &len); 1591 1592 if (ic->ic_modecaps & (1<<IEEE80211_MODE_11B)) { 1593 ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B]; 1594 for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) { 1595 if ((ic->ic_bss->ni_rates.rs_rates[i] & |
1376 IEEE80211_RATE_VAL) == (arg / 10000) * 2) | 1596 IEEE80211_RATE_VAL) == arg / 5000) |
1377 break; 1378 } 1379 } 1380 1381 if (i == ic->ic_bss->ni_rates.rs_nrates && 1382 ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) { 1383 ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G]; 1384 for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) { 1385 if ((ic->ic_bss->ni_rates.rs_rates[i] & | 1597 break; 1598 } 1599 } 1600 1601 if (i == ic->ic_bss->ni_rates.rs_nrates && 1602 ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) { 1603 ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G]; 1604 for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) { 1605 if ((ic->ic_bss->ni_rates.rs_rates[i] & |
1386 IEEE80211_RATE_VAL) == (arg / 10000) * 2) | 1606 IEEE80211_RATE_VAL) == arg / 5000) |
1387 break; 1388 } 1389 } 1390 1391 if (i == ic->ic_bss->ni_rates.rs_nrates) | 1607 break; 1608 } 1609 } 1610 1611 if (i == ic->ic_bss->ni_rates.rs_nrates) |
1392 device_printf (sc->ndis_dev, "no matching rate for: %d\n", 1393 (arg / 10000) * 2); | 1612 device_printf(sc->ndis_dev, "no matching rate for: %d\n", 1613 arg / 5000); |
1394 else 1395 ic->ic_bss->ni_txrate = i; 1396 | 1614 else 1615 ic->ic_bss->ni_txrate = i; 1616 |
1397 len = sizeof(arg); 1398 rval = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &len); | 1617 if (ic->ic_caps & IEEE80211_C_PMGT) { 1618 len = sizeof(arg); 1619 rval = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &len); |
1399 | 1620 |
1400 if (rval) 1401 device_printf (sc->ndis_dev, 1402 "get power mode failed: %d\n", rval); 1403 if (arg == NDIS_80211_POWERMODE_CAM) 1404 ic->ic_flags &= ~IEEE80211_F_PMGTON; 1405 else 1406 ic->ic_flags |= IEEE80211_F_PMGTON; 1407 | 1621 if (rval) 1622 device_printf(sc->ndis_dev, 1623 "get power mode failed: %d\n", rval); 1624 if (arg == NDIS_80211_POWERMODE_CAM) 1625 ic->ic_flags &= ~IEEE80211_F_PMGTON; 1626 else 1627 ic->ic_flags |= IEEE80211_F_PMGTON; 1628 } 1629 1630 len = sizeof(config); 1631 rval = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &len); 1632 if (rval == 0) { 1633 int chan; 1634 1635 chan = ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0); 1636 if (chan < 0 || chan >= IEEE80211_CHAN_MAX) { 1637 if (ifp->if_flags & IFF_DEBUG) 1638 device_printf(sc->ndis_dev, "current channel " 1639 "(%uMHz) out of bounds\n", 1640 config.nc_dsconfig / 1000); 1641 ic->ic_bss->ni_chan = &ic->ic_channels[1]; 1642 } else 1643 ic->ic_bss->ni_chan = &ic->ic_channels[chan]; 1644 } else 1645 device_printf(sc->ndis_dev, "couldn't retrieve " 1646 "channel info: %d\n", rval); 1647 |
1408/* 1409 len = sizeof(arg); 1410 rval = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &len); 1411 1412 if (rval) 1413 device_printf (sc->ndis_dev, 1414 "get wep status failed: %d\n", rval); 1415 --- 51 unchanged lines hidden (view full) --- 1467 ndis_setmulti(sc); 1468 error = 0; 1469 break; 1470 case SIOCGIFMEDIA: 1471 case SIOCSIFMEDIA: 1472 if (sc->ndis_80211) { 1473 error = ieee80211_ioctl(ifp, command, data); 1474 if (error == ENETRESET) { | 1648/* 1649 len = sizeof(arg); 1650 rval = ndis_get_info(sc, OID_802_11_WEP_STATUS, &arg, &len); 1651 1652 if (rval) 1653 device_printf (sc->ndis_dev, 1654 "get wep status failed: %d\n", rval); 1655 --- 51 unchanged lines hidden (view full) --- 1707 ndis_setmulti(sc); 1708 error = 0; 1709 break; 1710 case SIOCGIFMEDIA: 1711 case SIOCSIFMEDIA: 1712 if (sc->ndis_80211) { 1713 error = ieee80211_ioctl(ifp, command, data); 1714 if (error == ENETRESET) { |
1475 ndis_setstate_80211(sc); | 1715 /*ndis_setstate_80211(sc);*/ 1716 ndis_init(sc); |
1476 error = 0; 1477 } 1478 } else 1479 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); 1480 break; | 1717 error = 0; 1718 } 1719 } else 1720 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); 1721 break; |
1722 case SIOCGIFGENERIC: 1723 case SIOCSIFGENERIC: 1724 if (sc->ndis_80211 && ifp->if_flags & IFF_UP) { 1725 if (command == SIOCGIFGENERIC) 1726 error = ndis_wi_ioctl_get(ifp, command, data); 1727 else 1728 error = ndis_wi_ioctl_set(ifp, command, data); 1729 } else 1730 error = ENOTTY; 1731 if (error != ENOTTY) 1732 break; |
|
1481 default: 1482 if (sc->ndis_80211) { 1483 error = ieee80211_ioctl(ifp, command, data); 1484 if (error == ENETRESET) { 1485 ndis_setstate_80211(sc); 1486 error = 0; 1487 } 1488 } else 1489 error = ether_ioctl(ifp, command, data); 1490 break; 1491 } 1492 1493 /*NDIS_UNLOCK(sc);*/ 1494 1495 return(error); 1496} 1497 | 1733 default: 1734 if (sc->ndis_80211) { 1735 error = ieee80211_ioctl(ifp, command, data); 1736 if (error == ENETRESET) { 1737 ndis_setstate_80211(sc); 1738 error = 0; 1739 } 1740 } else 1741 error = ether_ioctl(ifp, command, data); 1742 break; 1743 } 1744 1745 /*NDIS_UNLOCK(sc);*/ 1746 1747 return(error); 1748} 1749 |
1750static int 1751ndis_wi_ioctl_get(ifp, command, data) 1752 struct ifnet *ifp; 1753 u_long command; 1754 caddr_t data; 1755{ 1756 struct wi_req wreq; 1757 struct ifreq *ifr; 1758 struct ndis_softc *sc; 1759 ndis_80211_bssid_list_ex *bl; 1760 ndis_wlan_bssid_ex *wb; 1761 struct wi_apinfo *api; 1762 int error, i, j, len, maxaps; 1763 1764 sc = ifp->if_softc; 1765 ifr = (struct ifreq *)data; 1766 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1767 if (error) 1768 return (error); 1769 1770 switch (wreq.wi_type) { 1771 case WI_RID_READ_APS: 1772 len = 0; 1773 error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, 1774 NULL, &len); 1775 if (error == 0) 1776 tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2); 1777 len = 0; 1778 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); 1779 if (error != ENOSPC) 1780 break; 1781 bl = malloc(len, M_DEVBUF, M_WAITOK); 1782 error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); 1783 if (error) { 1784 free(bl, M_DEVBUF); 1785 break; 1786 } 1787 maxaps = (2 * wreq.wi_len - sizeof(int)) / sizeof(*api); 1788 maxaps = MIN(maxaps, bl->nblx_items); 1789 wreq.wi_len = (maxaps * sizeof(*api) + sizeof(int)) / 2; 1790 *(int *)&wreq.wi_val = maxaps; 1791 api = (struct wi_apinfo *)&((int *)&wreq.wi_val)[1]; 1792 wb = bl->nblx_bssid; 1793 while (maxaps--) { 1794 bzero(api, sizeof(*api)); 1795 bcopy(&wb->nwbx_macaddr, &api->bssid, 1796 sizeof(api->bssid)); 1797 api->namelen = wb->nwbx_ssid.ns_ssidlen; 1798 bcopy(&wb->nwbx_ssid.ns_ssid, &api->name, api->namelen); 1799 if (wb->nwbx_privacy) 1800 api->capinfo |= IEEE80211_CAPINFO_PRIVACY; 1801 /* XXX Where can we get noise information? */ 1802 api->signal = wb->nwbx_rssi + 149; /* XXX */ 1803 api->quality = api->signal; 1804 api->channel = 1805 ieee80211_mhz2ieee(wb->nwbx_config.nc_dsconfig / 1806 1000, 0); 1807 /* In "auto" infrastructure mode, this is useless. */ 1808 if (wb->nwbx_netinfra == NDIS_80211_NET_INFRA_IBSS) 1809 api->capinfo |= IEEE80211_CAPINFO_IBSS; 1810 if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) { 1811 j = sizeof(ndis_80211_rates_ex); 1812 /* handle other extended things */ 1813 } else 1814 j = sizeof(ndis_80211_rates); 1815 for (i = api->rate = 0; i < j; i++) 1816 api->rate = MAX(api->rate, 5 * 1817 (wb->nwbx_supportedrates[i] & 0x7f)); 1818 api++; 1819 wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); 1820 } 1821 free(bl, M_DEVBUF); 1822 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1823 break; 1824 default: 1825 error = ENOTTY; 1826 break; 1827 } 1828 return (error); 1829} 1830 1831static int 1832ndis_wi_ioctl_set(ifp, command, data) 1833 struct ifnet *ifp; 1834 u_long command; 1835 caddr_t data; 1836{ 1837 struct wi_req wreq; 1838 struct ifreq *ifr; 1839 struct ndis_softc *sc; 1840 uint32_t foo; 1841 int error, len; 1842 1843 error = suser(curthread); 1844 if (error) 1845 return (error); 1846 1847 sc = ifp->if_softc; 1848 ifr = (struct ifreq *)data; 1849 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1850 if (error) 1851 return (error); 1852 1853 switch (wreq.wi_type) { 1854 case WI_RID_SCAN_APS: 1855 case WI_RID_SCAN_REQ: /* arguments ignored */ 1856 len = sizeof(foo); 1857 foo = 0; 1858 error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN, &foo, 1859 &len); 1860 break; 1861 default: 1862 error = ENOTTY; 1863 break; 1864 } 1865 return (error); 1866} 1867 |
|
1498static void 1499ndis_watchdog(ifp) 1500 struct ifnet *ifp; 1501{ 1502 struct ndis_softc *sc; 1503 1504 sc = ifp->if_softc; 1505 --- 19 unchanged lines hidden (view full) --- 1525 struct ndis_softc *sc; 1526{ 1527 struct ifnet *ifp; 1528 1529/* NDIS_LOCK(sc);*/ 1530 ifp = &sc->arpcom.ac_if; 1531 ifp->if_timer = 0; 1532 | 1868static void 1869ndis_watchdog(ifp) 1870 struct ifnet *ifp; 1871{ 1872 struct ndis_softc *sc; 1873 1874 sc = ifp->if_softc; 1875 --- 19 unchanged lines hidden (view full) --- 1895 struct ndis_softc *sc; 1896{ 1897 struct ifnet *ifp; 1898 1899/* NDIS_LOCK(sc);*/ 1900 ifp = &sc->arpcom.ac_if; 1901 ifp->if_timer = 0; 1902 |
1903 sc->ndis_link = 0; |
|
1533 untimeout(ndis_tick, sc, sc->ndis_stat_ch); 1534 1535 ndis_halt_nic(sc); 1536 1537 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1538 /*NDIS_UNLOCK(sc);*/ 1539 1540 return; --- 17 unchanged lines hidden --- | 1904 untimeout(ndis_tick, sc, sc->ndis_stat_ch); 1905 1906 ndis_halt_nic(sc); 1907 1908 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1909 /*NDIS_UNLOCK(sc);*/ 1910 1911 return; --- 17 unchanged lines hidden --- |