if_wi.c revision 90580
1/* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 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/* 34 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. 35 * 36 * Written by Bill Paul <wpaul@ctr.columbia.edu> 37 * Electrical Engineering Department 38 * Columbia University, New York City 39 */ 40 41/* 42 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 43 * from Lucent. Unlike the older cards, the new ones are programmed 44 * entirely via a firmware-driven controller called the Hermes. 45 * Unfortunately, Lucent will not release the Hermes programming manual 46 * without an NDA (if at all). What they do release is an API library 47 * called the HCF (Hardware Control Functions) which is supposed to 48 * do the device-specific operations of a device driver for you. The 49 * publically available version of the HCF library (the 'HCF Light') is 50 * a) extremely gross, b) lacks certain features, particularly support 51 * for 802.11 frames, and c) is contaminated by the GNU Public License. 52 * 53 * This driver does not use the HCF or HCF Light at all. Instead, it 54 * programs the Hermes controller directly, using information gleaned 55 * from the HCF Light code and corresponding documentation. 56 * 57 * This driver supports both the PCMCIA and ISA versions of the 58 * WaveLAN/IEEE cards. Note however that the ISA card isn't really 59 * anything of the sort: it's actually a PCMCIA bridge adapter 60 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 61 * inserted. Consequently, you need to use the pccard support for 62 * both the ISA and PCMCIA adapters. 63 */ 64 65#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 66#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ 67#define WICACHE /* turn on signal strength cache code */ 68 69#include "pci.h" 70 71#include <sys/param.h> 72#include <sys/systm.h> 73#include <sys/sockio.h> 74#include <sys/mbuf.h> 75#include <sys/proc.h> 76#include <sys/kernel.h> 77#include <sys/socket.h> 78#include <sys/module.h> 79#include <sys/bus.h> 80#include <sys/syslog.h> 81#include <sys/sysctl.h> 82 83#include <machine/bus.h> 84#include <machine/resource.h> 85#include <machine/md_var.h> 86#include <machine/bus_pio.h> 87#include <sys/rman.h> 88 89#if NPCI > 0 90#include <pci/pcireg.h> 91#include <pci/pcivar.h> 92#endif 93 94#include <net/if.h> 95#include <net/if_arp.h> 96#include <net/ethernet.h> 97#include <net/if_dl.h> 98#include <net/if_media.h> 99#include <net/if_types.h> 100#include <net/if_ieee80211.h> 101 102#include <netinet/in.h> 103#include <netinet/in_systm.h> 104#include <netinet/in_var.h> 105#include <netinet/ip.h> 106#include <netinet/if_ether.h> 107 108#include <net/bpf.h> 109 110#include <dev/pccard/pccardvar.h> 111#include <dev/pccard/pccarddevs.h> 112 113#include <dev/wi/if_wavelan_ieee.h> 114#include <dev/wi/if_wireg.h> 115 116#include "card_if.h" 117 118#if !defined(lint) 119static const char rcsid[] = 120 "$FreeBSD: head/sys/dev/wi/if_wi.c 90580 2002-02-12 17:52:11Z brooks $"; 121#endif 122 123#ifdef foo 124static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 }; 125#endif 126 127/* 128 * The following is for compatibility with NetBSD, but should really be 129 * brought in from NetBSD en toto. 130 */ 131#define le16toh(a) (a) 132#define LE16TOH(a) 133 134static void wi_intr __P((void *)); 135static void wi_reset __P((struct wi_softc *)); 136static int wi_ioctl __P((struct ifnet *, u_long, caddr_t)); 137static void wi_init __P((void *)); 138static void wi_start __P((struct ifnet *)); 139static void wi_stop __P((struct wi_softc *)); 140static void wi_watchdog __P((struct ifnet *)); 141static void wi_rxeof __P((struct wi_softc *)); 142static void wi_txeof __P((struct wi_softc *, int)); 143static void wi_update_stats __P((struct wi_softc *)); 144static void wi_setmulti __P((struct wi_softc *)); 145 146static int wi_cmd __P((struct wi_softc *, int, int)); 147static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *)); 148static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *)); 149static int wi_read_data __P((struct wi_softc *, int, 150 int, caddr_t, int)); 151static int wi_write_data __P((struct wi_softc *, int, 152 int, caddr_t, int)); 153static int wi_seek __P((struct wi_softc *, int, int, int)); 154static int wi_alloc_nicmem __P((struct wi_softc *, int, int *)); 155static void wi_inquire __P((void *)); 156static void wi_setdef __P((struct wi_softc *, struct wi_req *)); 157static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int)); 158 159#ifdef WICACHE 160static 161void wi_cache_store __P((struct wi_softc *, struct ether_header *, 162 struct mbuf *, unsigned short)); 163#endif 164 165static int wi_generic_attach __P((device_t)); 166static int wi_pccard_match __P((device_t)); 167static int wi_pccard_probe __P((device_t)); 168static int wi_pccard_attach __P((device_t)); 169#if NPCI > 0 170static int wi_pci_probe __P((device_t)); 171static int wi_pci_attach __P((device_t)); 172#endif 173static int wi_pccard_detach __P((device_t)); 174static void wi_shutdown __P((device_t)); 175 176static int wi_alloc __P((device_t, int)); 177static void wi_free __P((device_t)); 178 179static int wi_get_cur_ssid __P((struct wi_softc *, char *, int *)); 180static void wi_get_id __P((struct wi_softc *, device_t)); 181static int wi_media_change __P((struct ifnet *)); 182static void wi_media_status __P((struct ifnet *, struct ifmediareq *)); 183 184static device_method_t wi_pccard_methods[] = { 185 /* Device interface */ 186 DEVMETHOD(device_probe, pccard_compat_probe), 187 DEVMETHOD(device_attach, pccard_compat_attach), 188 DEVMETHOD(device_detach, wi_pccard_detach), 189 DEVMETHOD(device_shutdown, wi_shutdown), 190 191 /* Card interface */ 192 DEVMETHOD(card_compat_match, wi_pccard_match), 193 DEVMETHOD(card_compat_probe, wi_pccard_probe), 194 DEVMETHOD(card_compat_attach, wi_pccard_attach), 195 196 { 0, 0 } 197}; 198 199#if NPCI > 0 200static device_method_t wi_pci_methods[] = { 201 /* Device interface */ 202 DEVMETHOD(device_probe, wi_pci_probe), 203 DEVMETHOD(device_attach, wi_pci_attach), 204 DEVMETHOD(device_detach, wi_pccard_detach), 205 DEVMETHOD(device_shutdown, wi_shutdown), 206 207 { 0, 0 } 208}; 209#endif 210 211static driver_t wi_pccard_driver = { 212 "wi", 213 wi_pccard_methods, 214 sizeof(struct wi_softc) 215}; 216 217#if NPCI > 0 218static driver_t wi_pci_driver = { 219 "wi", 220 wi_pci_methods, 221 sizeof(struct wi_softc) 222}; 223 224static struct { 225 unsigned int vendor,device; 226 int bus_type; 227 char *desc; 228} pci_ids[] = { 229 {0x1638, 0x1100, WI_BUS_PCI_PLX, "PRISM2STA PCI WaveLAN/IEEE 802.11"}, 230 {0x1385, 0x4100, WI_BUS_PCI_PLX, "Netgear MA301 PCI IEEE 802.11b"}, 231 {0x16ab, 0x1101, WI_BUS_PCI_PLX, "GLPRISM2 PCI WaveLAN/IEEE 802.11"}, 232 {0x16ab, 0x1102, WI_BUS_PCI_PLX, "Linksys WDT11 PCI IEEE 802.11b"}, 233 {0x1260, 0x3873, WI_BUS_PCI_NATIVE, "Linksys WMP11 PCI Prism2.5"}, 234 {0, 0, NULL} 235}; 236#endif 237 238static devclass_t wi_devclass; 239 240DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_devclass, 0, 0); 241#if NPCI > 0 242DRIVER_MODULE(if_wi, pci, wi_pci_driver, wi_devclass, 0, 0); 243#endif 244 245static const struct pccard_product wi_pccard_products[] = { 246 PCMCIA_CARD(3COM, 3CRWE737A, 0), 247 PCMCIA_CARD(BUFFALO, WLI_PCM_S11, 0), 248 PCMCIA_CARD(BUFFALO, WLI_CF_S11G, 0), 249 PCMCIA_CARD(COMPAQ, NC5004, 0), 250 PCMCIA_CARD(CONTEC, FX_DS110_PCC, 0), 251 PCMCIA_CARD(COREGA, WIRELESS_LAN_PCC_11, 0), 252 PCMCIA_CARD(COREGA, WIRELESS_LAN_PCCA_11, 0), 253 PCMCIA_CARD(COREGA, WIRELESS_LAN_PCCB_11, 0), 254 PCMCIA_CARD(ELSA, XI300_IEEE, 0), 255 PCMCIA_CARD(ELSA, XI800_IEEE, 0), 256 PCMCIA_CARD(EMTAC, WLAN, 0), 257 PCMCIA_CARD(GEMTEK, WLAN, 0), 258 PCMCIA_CARD(INTEL, PRO_WLAN_2011, 0), 259 PCMCIA_CARD(INTERSIL, PRISM2, 0), 260 PCMCIA_CARD(IODATA2, WNB11PCM, 0), 261 PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NANOSPEED_PRISM2, 0), 262 PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NEC_CMZ_RT_WP, 0), 263 PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NTT_ME_WLAN, 0), 264 PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, SMC_2632W, 0), 265 /* Must be after other LUCENT ones because it is less specific */ 266 PCMCIA_CARD(LUCENT, WAVELAN_IEEE, 0), 267 PCMCIA_CARD(LINKSYS2, IWN, 0), 268 PCMCIA_CARD(SAMSUNG, SWL_2000N, 0), 269 PCMCIA_CARD(TDK, LAK_CD011WL, 0), 270 { NULL } 271}; 272 273static int 274wi_pccard_match(dev) 275 device_t dev; 276{ 277 const struct pccard_product *pp; 278 279 if ((pp = pccard_product_lookup(dev, wi_pccard_products, 280 sizeof(wi_pccard_products[0]), NULL)) != NULL) { 281 device_set_desc(dev, pp->pp_name); 282 return 0; 283 } 284 return ENXIO; 285} 286 287static int 288wi_pccard_probe(dev) 289 device_t dev; 290{ 291 struct wi_softc *sc; 292 int error; 293 294 sc = device_get_softc(dev); 295 sc->wi_gone = 0; 296 sc->wi_bus_type = WI_BUS_PCCARD; 297 298 error = wi_alloc(dev, 0); 299 if (error) 300 return (error); 301 302 wi_free(dev); 303 304 /* Make sure interrupts are disabled. */ 305 CSR_WRITE_2(sc, WI_INT_EN, 0); 306 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 307 308 return (0); 309} 310 311#if NPCI > 0 312static int 313wi_pci_probe(dev) 314 device_t dev; 315{ 316 struct wi_softc *sc; 317 int i; 318 319 sc = device_get_softc(dev); 320 for(i=0; pci_ids[i].vendor != 0; i++) { 321 if ((pci_get_vendor(dev) == pci_ids[i].vendor) && 322 (pci_get_device(dev) == pci_ids[i].device)) { 323 sc->wi_prism2 = 1; 324 sc->wi_bus_type = pci_ids[i].bus_type; 325 device_set_desc(dev, pci_ids[i].desc); 326 return (0); 327 } 328 } 329 return(ENXIO); 330} 331#endif 332 333static int 334wi_pccard_detach(dev) 335 device_t dev; 336{ 337 struct wi_softc *sc; 338 struct ifnet *ifp; 339 340 sc = device_get_softc(dev); 341 WI_LOCK(sc); 342 ifp = &sc->arpcom.ac_if; 343 344 if (sc->wi_gone) { 345 device_printf(dev, "already unloaded\n"); 346 WI_UNLOCK(sc); 347 return(ENODEV); 348 } 349 350 wi_stop(sc); 351 352 /* Delete all remaining media. */ 353 ifmedia_removeall(&sc->ifmedia); 354 355 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); 356 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); 357 wi_free(dev); 358 sc->wi_gone = 1; 359 360 WI_UNLOCK(sc); 361 mtx_destroy(&sc->wi_mtx); 362 363 return(0); 364} 365 366static int 367wi_pccard_attach(device_t dev) 368{ 369 struct wi_softc *sc; 370 int error; 371 372 sc = device_get_softc(dev); 373 374 error = wi_alloc(dev, 0); 375 if (error) { 376 device_printf(dev, "wi_alloc() failed! (%d)\n", error); 377 return (error); 378 } 379 return (wi_generic_attach(dev)); 380} 381 382#if NPCI > 0 383static int 384wi_pci_attach(device_t dev) 385{ 386 struct wi_softc *sc; 387 u_int32_t command, wanted; 388 u_int16_t reg; 389 int error; 390 int timeout; 391 392 sc = device_get_softc(dev); 393 394 command = pci_read_config(dev, PCIR_COMMAND, 4); 395 wanted = PCIM_CMD_PORTEN|PCIM_CMD_MEMEN; 396 command |= wanted; 397 pci_write_config(dev, PCIR_COMMAND, command, 4); 398 command = pci_read_config(dev, PCIR_COMMAND, 4); 399 if ((command & wanted) != wanted) { 400 device_printf(dev, "wi_pci_attach() failed to enable pci!\n"); 401 return (ENXIO); 402 } 403 404 if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { 405 error = wi_alloc(dev, WI_PCI_IORES); 406 if (error) 407 return (error); 408 409 /* Make sure interrupts are disabled. */ 410 CSR_WRITE_2(sc, WI_INT_EN, 0); 411 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 412 413 /* We have to do a magic PLX poke to enable interrupts */ 414 sc->local_rid = WI_PCI_LOCALRES; 415 sc->local = bus_alloc_resource(dev, SYS_RES_IOPORT, 416 &sc->local_rid, 0, ~0, 1, RF_ACTIVE); 417 sc->wi_localtag = rman_get_bustag(sc->local); 418 sc->wi_localhandle = rman_get_bushandle(sc->local); 419 command = bus_space_read_4(sc->wi_localtag, sc->wi_localhandle, 420 WI_LOCAL_INTCSR); 421 command |= WI_LOCAL_INTEN; 422 bus_space_write_4(sc->wi_localtag, sc->wi_localhandle, 423 WI_LOCAL_INTCSR, command); 424 bus_release_resource(dev, SYS_RES_IOPORT, sc->local_rid, 425 sc->local); 426 sc->local = NULL; 427 428 sc->mem_rid = WI_PCI_MEMRES; 429 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, 430 0, ~0, 1, RF_ACTIVE); 431 if (sc->mem == NULL) { 432 device_printf(dev, "couldn't allocate memory\n"); 433 wi_free(dev); 434 return (ENXIO); 435 } 436 sc->wi_bmemtag = rman_get_bustag(sc->mem); 437 sc->wi_bmemhandle = rman_get_bushandle(sc->mem); 438 439 /* 440 * From Linux driver: 441 * Write COR to enable PC card 442 * This is a subset of the protocol that the pccard bus code 443 * would do. 444 */ 445 CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE); 446 reg = CSM_READ_1(sc, WI_COR_OFFSET); 447 if (reg != WI_COR_VALUE) { 448 device_printf(dev, "CSM_READ_1(WI_COR_OFFSET) " 449 "wanted %d, got %d\n", WI_COR_VALUE, reg); 450 wi_free(dev); 451 return (ENXIO); 452 } 453 } else { 454 error = wi_alloc(dev, WI_PCI_LMEMRES); 455 if (error) 456 return (error); 457 458 CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0080); 459 DELAY(250000); 460 461 CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0000); 462 DELAY(500000); 463 464 timeout=2000000; 465 while ((--timeout > 0) && 466 (CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) 467 DELAY(10); 468 469 if (timeout == 0) { 470 device_printf(dev, "couldn't reset prism2.5 core.\n"); 471 wi_free(dev); 472 return(ENXIO); 473 } 474 } 475 476 CSR_WRITE_2(sc, WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC); 477 reg = CSR_READ_2(sc, WI_HFA384X_SWSUPPORT0_OFF); 478 if (reg != WI_PRISM2STA_MAGIC) { 479 device_printf(dev, 480 "CSR_READ_2(WI_HFA384X_SWSUPPORT0_OFF) " 481 "wanted %d, got %d\n", WI_PRISM2STA_MAGIC, reg); 482 wi_free(dev); 483 return (ENXIO); 484 } 485 486 error = wi_generic_attach(dev); 487 if (error != 0) 488 return (error); 489 490 return (0); 491} 492#endif 493 494static int 495wi_generic_attach(device_t dev) 496{ 497 struct wi_softc *sc; 498 struct wi_ltv_macaddr mac; 499 struct wi_ltv_gen gen; 500 struct ifnet *ifp; 501 int error; 502 503 sc = device_get_softc(dev); 504 ifp = &sc->arpcom.ac_if; 505 506 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 507 wi_intr, sc, &sc->wi_intrhand); 508 509 if (error) { 510 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 511 wi_free(dev); 512 return (error); 513 } 514 515 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_DEF | MTX_RECURSE); 516 WI_LOCK(sc); 517 518 /* Reset the NIC. */ 519 wi_reset(sc); 520 521 /* 522 * Read the station address. 523 * And do it twice. I've seen PRISM-based cards that return 524 * an error when trying to read it the first time, which causes 525 * the probe to fail. 526 */ 527 mac.wi_type = WI_RID_MAC_NODE; 528 mac.wi_len = 4; 529 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 530 if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) { 531 device_printf(dev, "mac read failed %d\n", error); 532 wi_free(dev); 533 return (error); 534 } 535 bcopy((char *)&mac.wi_mac_addr, 536 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 537 538 device_printf(dev, "802.11 address: %6D\n", sc->arpcom.ac_enaddr, ":"); 539 540 wi_get_id(sc, dev); 541 542 ifp->if_softc = sc; 543 ifp->if_unit = sc->wi_unit; 544 ifp->if_name = "wi"; 545 ifp->if_mtu = ETHERMTU; 546 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 547 ifp->if_ioctl = wi_ioctl; 548 ifp->if_output = ether_output; 549 ifp->if_start = wi_start; 550 ifp->if_watchdog = wi_watchdog; 551 ifp->if_init = wi_init; 552 ifp->if_baudrate = 10000000; 553 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 554 555 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 556 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name, 557 sizeof(WI_DEFAULT_NODENAME) - 1); 558 559 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 560 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name, 561 sizeof(WI_DEFAULT_NETNAME) - 1); 562 563 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 564 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name, 565 sizeof(WI_DEFAULT_IBSS) - 1); 566 567 sc->wi_portnum = WI_DEFAULT_PORT; 568 sc->wi_ptype = WI_PORTTYPE_BSS; 569 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY; 570 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH; 571 sc->wi_tx_rate = WI_DEFAULT_TX_RATE; 572 sc->wi_max_data_len = WI_DEFAULT_DATALEN; 573 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS; 574 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED; 575 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP; 576 577 /* 578 * Read the default channel from the NIC. This may vary 579 * depending on the country where the NIC was purchased, so 580 * we can't hard-code a default and expect it to work for 581 * everyone. 582 */ 583 gen.wi_type = WI_RID_OWN_CHNL; 584 gen.wi_len = 2; 585 wi_read_record(sc, &gen); 586 sc->wi_channel = gen.wi_val; 587 588 /* 589 * Find out if we support WEP on this card. 590 */ 591 gen.wi_type = WI_RID_WEP_AVAIL; 592 gen.wi_len = 2; 593 wi_read_record(sc, &gen); 594 sc->wi_has_wep = gen.wi_val; 595 596 if (bootverbose) { 597 device_printf(sc->dev, 598 "%s:wi_has_wep = %d\n", 599 __func__, sc->wi_has_wep); 600 } 601 602 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 603 604 wi_init(sc); 605 wi_stop(sc); 606 607 ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status); 608 /* XXX: Should read from card capabilities */ 609#define ADD(m, c) ifmedia_add(&sc->ifmedia, (m), (c), NULL) 610 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 611 IFM_IEEE80211_ADHOC, 0), 0); 612 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 613 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 614 IFM_IEEE80211_ADHOC, 0), 0); 615 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 616 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 617 IFM_IEEE80211_ADHOC, 0), 0); 618 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 619 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 620 IFM_IEEE80211_ADHOC, 0), 0); 621 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 622 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 623 IFM_IEEE80211_ADHOC, 0), 0); 624 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 625#undef ADD 626 ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 627 0, 0)); 628 629 630 /* 631 * Call MI attach routine. 632 */ 633 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 634 callout_handle_init(&sc->wi_stat_ch); 635 WI_UNLOCK(sc); 636 637 return(0); 638} 639 640static void 641wi_get_id(sc, dev) 642 struct wi_softc *sc; 643 device_t dev; 644{ 645 struct wi_ltv_ver ver; 646 647 /* getting chip identity */ 648 memset(&ver, 0, sizeof(ver)); 649 ver.wi_type = WI_RID_CARDID; 650 ver.wi_len = 5; 651 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 652 device_printf(dev, "using "); 653 switch (le16toh(ver.wi_ver[0])) { 654 case WI_NIC_EVB2: 655 printf("RF:PRISM2 MAC:HFA3841"); 656 sc->wi_prism2 = 1; 657 break; 658 case WI_NIC_HWB3763: 659 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B"); 660 sc->wi_prism2 = 1; 661 break; 662 case WI_NIC_HWB3163: 663 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A"); 664 sc->wi_prism2 = 1; 665 break; 666 case WI_NIC_HWB3163B: 667 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B"); 668 sc->wi_prism2 = 1; 669 break; 670 case WI_NIC_EVB3: 671 printf("RF:PRISM2 MAC:HFA3842"); 672 sc->wi_prism2 = 1; 673 break; 674 case WI_NIC_HWB1153: 675 printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153"); 676 sc->wi_prism2 = 1; 677 break; 678 case WI_NIC_P2_SST: 679 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash"); 680 sc->wi_prism2 = 1; 681 break; 682 case WI_NIC_PRISM2_5: 683 printf("RF:PRISM2.5 MAC:ISL3873"); 684 sc->wi_prism2 = 1; 685 break; 686 case WI_NIC_3874A: 687 printf("RF:PRISM2.5 MAC:ISL3874A(PCI)"); 688 sc->wi_prism2 = 1; 689 break; 690 default: 691 printf("Lucent chip or unknown chip\n"); 692 sc->wi_prism2 = 0; 693 break; 694 } 695 696 if (sc->wi_prism2) { 697 /* try to get prism2 firm version */ 698 memset(&ver, 0, sizeof(ver)); 699 ver.wi_type = WI_RID_IDENT; 700 ver.wi_len = 5; 701 wi_read_record(sc, (struct wi_ltv_gen *)&ver); 702 LE16TOH(ver.wi_ver[1]); 703 LE16TOH(ver.wi_ver[2]); 704 LE16TOH(ver.wi_ver[3]); 705 printf(", Firmware: %d.%d variant %d\n", ver.wi_ver[2], 706 ver.wi_ver[3], ver.wi_ver[1]); 707 sc->wi_prism2_ver = ver.wi_ver[2] * 100 + 708 ver.wi_ver[3] * 10 + ver.wi_ver[1]; 709 } 710 711 return; 712} 713 714static void 715wi_rxeof(sc) 716 struct wi_softc *sc; 717{ 718 struct ifnet *ifp; 719 struct ether_header *eh; 720 struct wi_frame rx_frame; 721 struct mbuf *m; 722 int id; 723 724 ifp = &sc->arpcom.ac_if; 725 726 id = CSR_READ_2(sc, WI_RX_FID); 727 728 /* First read in the frame header */ 729 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) { 730 ifp->if_ierrors++; 731 return; 732 } 733 734 if (rx_frame.wi_status & WI_STAT_ERRSTAT) { 735 ifp->if_ierrors++; 736 return; 737 } 738 739 MGETHDR(m, M_DONTWAIT, MT_DATA); 740 if (m == NULL) { 741 ifp->if_ierrors++; 742 return; 743 } 744 MCLGET(m, M_DONTWAIT); 745 if (!(m->m_flags & M_EXT)) { 746 m_freem(m); 747 ifp->if_ierrors++; 748 return; 749 } 750 751 eh = mtod(m, struct ether_header *); 752 m->m_pkthdr.rcvif = ifp; 753 754 if (rx_frame.wi_status == WI_STAT_1042 || 755 rx_frame.wi_status == WI_STAT_TUNNEL || 756 rx_frame.wi_status == WI_STAT_WMP_MSG) { 757 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { 758 device_printf(sc->dev, "oversized packet received " 759 "(wi_dat_len=%d, wi_status=0x%x)\n", 760 rx_frame.wi_dat_len, rx_frame.wi_status); 761 m_freem(m); 762 ifp->if_ierrors++; 763 return; 764 } 765 m->m_pkthdr.len = m->m_len = 766 rx_frame.wi_dat_len + WI_SNAPHDR_LEN; 767 768#if 0 769 bcopy((char *)&rx_frame.wi_addr1, 770 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 771 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) { 772 bcopy((char *)&rx_frame.wi_addr2, 773 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 774 } else { 775 bcopy((char *)&rx_frame.wi_addr3, 776 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 777 } 778#else 779 bcopy((char *)&rx_frame.wi_dst_addr, 780 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 781 bcopy((char *)&rx_frame.wi_src_addr, 782 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 783#endif 784 785 bcopy((char *)&rx_frame.wi_type, 786 (char *)&eh->ether_type, ETHER_TYPE_LEN); 787 788 if (wi_read_data(sc, id, WI_802_11_OFFSET, 789 mtod(m, caddr_t) + sizeof(struct ether_header), 790 m->m_len + 2)) { 791 m_freem(m); 792 ifp->if_ierrors++; 793 return; 794 } 795 } else { 796 if((rx_frame.wi_dat_len + 797 sizeof(struct ether_header)) > MCLBYTES) { 798 device_printf(sc->dev, "oversized packet received " 799 "(wi_dat_len=%d, wi_status=0x%x)\n", 800 rx_frame.wi_dat_len, rx_frame.wi_status); 801 m_freem(m); 802 ifp->if_ierrors++; 803 return; 804 } 805 m->m_pkthdr.len = m->m_len = 806 rx_frame.wi_dat_len + sizeof(struct ether_header); 807 808 if (wi_read_data(sc, id, WI_802_3_OFFSET, 809 mtod(m, caddr_t), m->m_len + 2)) { 810 m_freem(m); 811 ifp->if_ierrors++; 812 return; 813 } 814 } 815 816 ifp->if_ipackets++; 817 818 /* Receive packet. */ 819 m_adj(m, sizeof(struct ether_header)); 820#ifdef WICACHE 821 wi_cache_store(sc, eh, m, rx_frame.wi_q_info); 822#endif 823 ether_input(ifp, eh, m); 824} 825 826static void 827wi_txeof(sc, status) 828 struct wi_softc *sc; 829 int status; 830{ 831 struct ifnet *ifp; 832 833 ifp = &sc->arpcom.ac_if; 834 835 ifp->if_timer = 0; 836 ifp->if_flags &= ~IFF_OACTIVE; 837 838 if (status & WI_EV_TX_EXC) 839 ifp->if_oerrors++; 840 else 841 ifp->if_opackets++; 842 843 return; 844} 845 846void 847wi_inquire(xsc) 848 void *xsc; 849{ 850 struct wi_softc *sc; 851 struct ifnet *ifp; 852 853 sc = xsc; 854 ifp = &sc->arpcom.ac_if; 855 856 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 857 858 /* Don't do this while we're transmitting */ 859 if (ifp->if_flags & IFF_OACTIVE) 860 return; 861 862 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS); 863 864 return; 865} 866 867void 868wi_update_stats(sc) 869 struct wi_softc *sc; 870{ 871 struct wi_ltv_gen gen; 872 u_int16_t id; 873 struct ifnet *ifp; 874 u_int32_t *ptr; 875 int len, i; 876 u_int16_t t; 877 878 ifp = &sc->arpcom.ac_if; 879 880 id = CSR_READ_2(sc, WI_INFO_FID); 881 882 wi_read_data(sc, id, 0, (char *)&gen, 4); 883 884 if (gen.wi_type != WI_INFO_COUNTERS) 885 return; 886 887 len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ? 888 gen.wi_len - 1 : sizeof(sc->wi_stats) / 4; 889 ptr = (u_int32_t *)&sc->wi_stats; 890 891 for (i = 0; i < len - 1; i++) { 892 t = CSR_READ_2(sc, WI_DATA1); 893#ifdef WI_HERMES_STATS_WAR 894 if (t > 0xF000) 895 t = ~t & 0xFFFF; 896#endif 897 ptr[i] += t; 898 } 899 900 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 901 sc->wi_stats.wi_tx_multi_retries + 902 sc->wi_stats.wi_tx_retry_limit; 903 904 return; 905} 906 907static void 908wi_intr(xsc) 909 void *xsc; 910{ 911 struct wi_softc *sc = xsc; 912 struct ifnet *ifp; 913 u_int16_t status; 914 915 WI_LOCK(sc); 916 917 ifp = &sc->arpcom.ac_if; 918 919 if (sc->wi_gone || !(ifp->if_flags & IFF_UP)) { 920 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 921 CSR_WRITE_2(sc, WI_INT_EN, 0); 922 WI_UNLOCK(sc); 923 return; 924 } 925 926 /* Disable interrupts. */ 927 CSR_WRITE_2(sc, WI_INT_EN, 0); 928 929 status = CSR_READ_2(sc, WI_EVENT_STAT); 930 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS); 931 932 if (status & WI_EV_RX) { 933 wi_rxeof(sc); 934 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); 935 } 936 937 if (status & WI_EV_TX) { 938 wi_txeof(sc, status); 939 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX); 940 } 941 942 if (status & WI_EV_ALLOC) { 943 int id; 944 945 id = CSR_READ_2(sc, WI_ALLOC_FID); 946 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 947 if (id == sc->wi_tx_data_id) 948 wi_txeof(sc, status); 949 } 950 951 if (status & WI_EV_INFO) { 952 wi_update_stats(sc); 953 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); 954 } 955 956 if (status & WI_EV_TX_EXC) { 957 wi_txeof(sc, status); 958 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC); 959 } 960 961 if (status & WI_EV_INFO_DROP) { 962 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP); 963 } 964 965 /* Re-enable interrupts. */ 966 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 967 968 if (ifp->if_snd.ifq_head != NULL) { 969 wi_start(ifp); 970 } 971 972 WI_UNLOCK(sc); 973 974 return; 975} 976 977static int 978wi_cmd(sc, cmd, val) 979 struct wi_softc *sc; 980 int cmd; 981 int val; 982{ 983 int i, s = 0; 984 985 /* wait for the busy bit to clear */ 986 for (i = 500; i > 0; i--) { /* 5s */ 987 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) { 988 break; 989 } 990 DELAY(10*1000); /* 10 m sec */ 991 } 992 if (i == 0) { 993 device_printf(sc->dev, "wi_cmd: busy bit won't clear.\n" ); 994 return(ETIMEDOUT); 995 } 996 997 CSR_WRITE_2(sc, WI_PARAM0, val); 998 CSR_WRITE_2(sc, WI_PARAM1, 0); 999 CSR_WRITE_2(sc, WI_PARAM2, 0); 1000 CSR_WRITE_2(sc, WI_COMMAND, cmd); 1001 1002 for (i = 0; i < WI_TIMEOUT; i++) { 1003 /* 1004 * Wait for 'command complete' bit to be 1005 * set in the event status register. 1006 */ 1007 s = CSR_READ_2(sc, WI_EVENT_STAT); 1008 if (s & WI_EV_CMD) { 1009 /* Ack the event and read result code. */ 1010 s = CSR_READ_2(sc, WI_STATUS); 1011 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 1012#ifdef foo 1013 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK)) 1014 return(EIO); 1015#endif 1016 if (s & WI_STAT_CMD_RESULT) 1017 return(EIO); 1018 break; 1019 } 1020 DELAY(WI_DELAY); 1021 } 1022 1023 if (i == WI_TIMEOUT) { 1024 device_printf(sc->dev, 1025 "timeout in wi_cmd %x; event status %x\n", cmd, s); 1026 return(ETIMEDOUT); 1027 } 1028 1029 return(0); 1030} 1031 1032static void 1033wi_reset(sc) 1034 struct wi_softc *sc; 1035{ 1036#define WI_INIT_TRIES 5 1037 int i; 1038 1039 for (i = 0; i < WI_INIT_TRIES; i++) { 1040 if (wi_cmd(sc, WI_CMD_INI, 0) == 0) 1041 break; 1042 DELAY(WI_DELAY * 1000); 1043 } 1044 if (i == WI_INIT_TRIES) 1045 device_printf(sc->dev, "init failed\n"); 1046 1047 CSR_WRITE_2(sc, WI_INT_EN, 0); 1048 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 1049 1050 /* Calibrate timer. */ 1051 WI_SETVAL(WI_RID_TICK_TIME, 8); 1052 1053 return; 1054} 1055 1056/* 1057 * Read an LTV record from the NIC. 1058 */ 1059static int 1060wi_read_record(sc, ltv) 1061 struct wi_softc *sc; 1062 struct wi_ltv_gen *ltv; 1063{ 1064 u_int16_t *ptr; 1065 int i, len, code; 1066 struct wi_ltv_gen *oltv, p2ltv; 1067 1068 oltv = ltv; 1069 if (sc->wi_prism2) { 1070 switch (ltv->wi_type) { 1071 case WI_RID_ENCRYPTION: 1072 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 1073 p2ltv.wi_len = 2; 1074 ltv = &p2ltv; 1075 break; 1076 case WI_RID_TX_CRYPT_KEY: 1077 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 1078 p2ltv.wi_len = 2; 1079 ltv = &p2ltv; 1080 break; 1081 } 1082 } 1083 1084 /* Tell the NIC to enter record read mode. */ 1085 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type)) 1086 return(EIO); 1087 1088 /* Seek to the record. */ 1089 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 1090 return(EIO); 1091 1092 /* 1093 * Read the length and record type and make sure they 1094 * match what we expect (this verifies that we have enough 1095 * room to hold all of the returned data). 1096 */ 1097 len = CSR_READ_2(sc, WI_DATA1); 1098 if (len > ltv->wi_len) 1099 return(ENOSPC); 1100 code = CSR_READ_2(sc, WI_DATA1); 1101 if (code != ltv->wi_type) 1102 return(EIO); 1103 1104 ltv->wi_len = len; 1105 ltv->wi_type = code; 1106 1107 /* Now read the data. */ 1108 ptr = <v->wi_val; 1109 for (i = 0; i < ltv->wi_len - 1; i++) 1110 ptr[i] = CSR_READ_2(sc, WI_DATA1); 1111 1112 if (sc->wi_prism2) { 1113 switch (oltv->wi_type) { 1114 case WI_RID_TX_RATE: 1115 case WI_RID_CUR_TX_RATE: 1116 switch (ltv->wi_val) { 1117 case 1: oltv->wi_val = 1; break; 1118 case 2: oltv->wi_val = 2; break; 1119 case 3: oltv->wi_val = 6; break; 1120 case 4: oltv->wi_val = 5; break; 1121 case 7: oltv->wi_val = 7; break; 1122 case 8: oltv->wi_val = 11; break; 1123 case 15: oltv->wi_val = 3; break; 1124 default: oltv->wi_val = 0x100 + ltv->wi_val; break; 1125 } 1126 break; 1127 case WI_RID_ENCRYPTION: 1128 oltv->wi_len = 2; 1129 if (ltv->wi_val & 0x01) 1130 oltv->wi_val = 1; 1131 else 1132 oltv->wi_val = 0; 1133 break; 1134 case WI_RID_TX_CRYPT_KEY: 1135 oltv->wi_len = 2; 1136 oltv->wi_val = ltv->wi_val; 1137 break; 1138 } 1139 } 1140 1141 return(0); 1142} 1143 1144/* 1145 * Same as read, except we inject data instead of reading it. 1146 */ 1147static int 1148wi_write_record(sc, ltv) 1149 struct wi_softc *sc; 1150 struct wi_ltv_gen *ltv; 1151{ 1152 u_int16_t *ptr; 1153 int i; 1154 struct wi_ltv_gen p2ltv; 1155 1156 if (sc->wi_prism2) { 1157 switch (ltv->wi_type) { 1158 case WI_RID_TX_RATE: 1159 p2ltv.wi_type = WI_RID_TX_RATE; 1160 p2ltv.wi_len = 2; 1161 switch (ltv->wi_val) { 1162 case 1: p2ltv.wi_val = 1; break; 1163 case 2: p2ltv.wi_val = 2; break; 1164 case 3: p2ltv.wi_val = 15; break; 1165 case 5: p2ltv.wi_val = 4; break; 1166 case 6: p2ltv.wi_val = 3; break; 1167 case 7: p2ltv.wi_val = 7; break; 1168 case 11: p2ltv.wi_val = 8; break; 1169 default: return EINVAL; 1170 } 1171 ltv = &p2ltv; 1172 break; 1173 case WI_RID_ENCRYPTION: 1174 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 1175 p2ltv.wi_len = 2; 1176 if (ltv->wi_val) 1177 p2ltv.wi_val = 0x03; 1178 else 1179 p2ltv.wi_val = 0x90; 1180 ltv = &p2ltv; 1181 break; 1182 case WI_RID_TX_CRYPT_KEY: 1183 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 1184 p2ltv.wi_len = 2; 1185 p2ltv.wi_val = ltv->wi_val; 1186 ltv = &p2ltv; 1187 break; 1188 case WI_RID_DEFLT_CRYPT_KEYS: 1189 { 1190 int error; 1191 struct wi_ltv_str ws; 1192 struct wi_ltv_keys *wk = 1193 (struct wi_ltv_keys *)ltv; 1194 1195 for (i = 0; i < 4; i++) { 1196 ws.wi_len = 4; 1197 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; 1198 memcpy(ws.wi_str, 1199 &wk->wi_keys[i].wi_keydat, 5); 1200 ws.wi_str[5] = '\0'; 1201 error = wi_write_record(sc, 1202 (struct wi_ltv_gen *)&ws); 1203 if (error) 1204 return error; 1205 } 1206 return 0; 1207 } 1208 } 1209 } 1210 1211 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 1212 return(EIO); 1213 1214 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len); 1215 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type); 1216 1217 ptr = <v->wi_val; 1218 for (i = 0; i < ltv->wi_len - 1; i++) 1219 CSR_WRITE_2(sc, WI_DATA1, ptr[i]); 1220 1221 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type)) 1222 return(EIO); 1223 1224 return(0); 1225} 1226 1227static int 1228wi_seek(sc, id, off, chan) 1229 struct wi_softc *sc; 1230 int id, off, chan; 1231{ 1232 int i; 1233 int selreg, offreg; 1234 int status; 1235 1236 switch (chan) { 1237 case WI_BAP0: 1238 selreg = WI_SEL0; 1239 offreg = WI_OFF0; 1240 break; 1241 case WI_BAP1: 1242 selreg = WI_SEL1; 1243 offreg = WI_OFF1; 1244 break; 1245 default: 1246 device_printf(sc->dev, "invalid data path: %x\n", chan); 1247 return(EIO); 1248 } 1249 1250 CSR_WRITE_2(sc, selreg, id); 1251 CSR_WRITE_2(sc, offreg, off); 1252 1253 for (i = 0; i < WI_TIMEOUT; i++) { 1254 status = CSR_READ_2(sc, offreg); 1255 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR))) 1256 break; 1257 DELAY(WI_DELAY); 1258 } 1259 1260 if (i == WI_TIMEOUT) { 1261 device_printf(sc->dev, "timeout in wi_seek to %x/%x; last status %x\n", 1262 id, off, status); 1263 return(ETIMEDOUT); 1264 } 1265 1266 return(0); 1267} 1268 1269static int 1270wi_read_data(sc, id, off, buf, len) 1271 struct wi_softc *sc; 1272 int id, off; 1273 caddr_t buf; 1274 int len; 1275{ 1276 int i; 1277 u_int16_t *ptr; 1278 1279 if (wi_seek(sc, id, off, WI_BAP1)) 1280 return(EIO); 1281 1282 ptr = (u_int16_t *)buf; 1283 for (i = 0; i < len / 2; i++) 1284 ptr[i] = CSR_READ_2(sc, WI_DATA1); 1285 1286 return(0); 1287} 1288 1289/* 1290 * According to the comments in the HCF Light code, there is a bug in 1291 * the Hermes (or possibly in certain Hermes firmware revisions) where 1292 * the chip's internal autoincrement counter gets thrown off during 1293 * data writes: the autoincrement is missed, causing one data word to 1294 * be overwritten and subsequent words to be written to the wrong memory 1295 * locations. The end result is that we could end up transmitting bogus 1296 * frames without realizing it. The workaround for this is to write a 1297 * couple of extra guard words after the end of the transfer, then 1298 * attempt to read then back. If we fail to locate the guard words where 1299 * we expect them, we preform the transfer over again. 1300 */ 1301static int 1302wi_write_data(sc, id, off, buf, len) 1303 struct wi_softc *sc; 1304 int id, off; 1305 caddr_t buf; 1306 int len; 1307{ 1308 int i; 1309 u_int16_t *ptr; 1310#ifdef WI_HERMES_AUTOINC_WAR 1311 int retries; 1312 1313 retries = 512; 1314again: 1315#endif 1316 1317 if (wi_seek(sc, id, off, WI_BAP0)) 1318 return(EIO); 1319 1320 ptr = (u_int16_t *)buf; 1321 for (i = 0; i < (len / 2); i++) 1322 CSR_WRITE_2(sc, WI_DATA0, ptr[i]); 1323 1324#ifdef WI_HERMES_AUTOINC_WAR 1325 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 1326 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 1327 1328 if (wi_seek(sc, id, off + len, WI_BAP0)) 1329 return(EIO); 1330 1331 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 1332 CSR_READ_2(sc, WI_DATA0) != 0x5678) { 1333 if (--retries >= 0) 1334 goto again; 1335 device_printf(sc->dev, "wi_write_data device timeout\n"); 1336 return (EIO); 1337 } 1338#endif 1339 1340 return(0); 1341} 1342 1343/* 1344 * Allocate a region of memory inside the NIC and zero 1345 * it out. 1346 */ 1347static int 1348wi_alloc_nicmem(sc, len, id) 1349 struct wi_softc *sc; 1350 int len; 1351 int *id; 1352{ 1353 int i; 1354 1355 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) { 1356 device_printf(sc->dev, 1357 "failed to allocate %d bytes on NIC\n", len); 1358 return(ENOMEM); 1359 } 1360 1361 for (i = 0; i < WI_TIMEOUT; i++) { 1362 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 1363 break; 1364 DELAY(WI_DELAY); 1365 } 1366 1367 if (i == WI_TIMEOUT) { 1368 device_printf(sc->dev, "time out allocating memory on card\n"); 1369 return(ETIMEDOUT); 1370 } 1371 1372 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 1373 *id = CSR_READ_2(sc, WI_ALLOC_FID); 1374 1375 if (wi_seek(sc, *id, 0, WI_BAP0)) { 1376 device_printf(sc->dev, "seek failed while allocating memory on card\n"); 1377 return(EIO); 1378 } 1379 1380 for (i = 0; i < len / 2; i++) 1381 CSR_WRITE_2(sc, WI_DATA0, 0); 1382 1383 return(0); 1384} 1385 1386static void 1387wi_setmulti(sc) 1388 struct wi_softc *sc; 1389{ 1390 struct ifnet *ifp; 1391 int i = 0; 1392 struct ifmultiaddr *ifma; 1393 struct wi_ltv_mcast mcast; 1394 1395 ifp = &sc->arpcom.ac_if; 1396 1397 bzero((char *)&mcast, sizeof(mcast)); 1398 1399 mcast.wi_type = WI_RID_MCAST; 1400 mcast.wi_len = (3 * 16) + 1; 1401 1402 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 1403 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1404 return; 1405 } 1406 1407 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1408 if (ifma->ifma_addr->sa_family != AF_LINK) 1409 continue; 1410 if (i < 16) { 1411 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 1412 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN); 1413 i++; 1414 } else { 1415 bzero((char *)&mcast, sizeof(mcast)); 1416 break; 1417 } 1418 } 1419 1420 mcast.wi_len = (i * 3) + 1; 1421 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1422 1423 return; 1424} 1425 1426static void 1427wi_setdef(sc, wreq) 1428 struct wi_softc *sc; 1429 struct wi_req *wreq; 1430{ 1431 struct sockaddr_dl *sdl; 1432 struct ifaddr *ifa; 1433 struct ifnet *ifp; 1434 1435 ifp = &sc->arpcom.ac_if; 1436 1437 switch(wreq->wi_type) { 1438 case WI_RID_MAC_NODE: 1439 ifa = ifaddr_byindex(ifp->if_index); 1440 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1441 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr, 1442 ETHER_ADDR_LEN); 1443 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); 1444 break; 1445 case WI_RID_PORTTYPE: 1446 sc->wi_ptype = wreq->wi_val[0]; 1447 break; 1448 case WI_RID_TX_RATE: 1449 sc->wi_tx_rate = wreq->wi_val[0]; 1450 break; 1451 case WI_RID_MAX_DATALEN: 1452 sc->wi_max_data_len = wreq->wi_val[0]; 1453 break; 1454 case WI_RID_RTS_THRESH: 1455 sc->wi_rts_thresh = wreq->wi_val[0]; 1456 break; 1457 case WI_RID_SYSTEM_SCALE: 1458 sc->wi_ap_density = wreq->wi_val[0]; 1459 break; 1460 case WI_RID_CREATE_IBSS: 1461 sc->wi_create_ibss = wreq->wi_val[0]; 1462 break; 1463 case WI_RID_OWN_CHNL: 1464 sc->wi_channel = wreq->wi_val[0]; 1465 break; 1466 case WI_RID_NODENAME: 1467 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 1468 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30); 1469 break; 1470 case WI_RID_DESIRED_SSID: 1471 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 1472 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30); 1473 break; 1474 case WI_RID_OWN_SSID: 1475 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 1476 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30); 1477 break; 1478 case WI_RID_PM_ENABLED: 1479 sc->wi_pm_enabled = wreq->wi_val[0]; 1480 break; 1481 case WI_RID_MAX_SLEEP: 1482 sc->wi_max_sleep = wreq->wi_val[0]; 1483 break; 1484 case WI_RID_ENCRYPTION: 1485 sc->wi_use_wep = wreq->wi_val[0]; 1486 break; 1487 case WI_RID_TX_CRYPT_KEY: 1488 sc->wi_tx_key = wreq->wi_val[0]; 1489 break; 1490 case WI_RID_DEFLT_CRYPT_KEYS: 1491 bcopy((char *)wreq, (char *)&sc->wi_keys, 1492 sizeof(struct wi_ltv_keys)); 1493 break; 1494 default: 1495 break; 1496 } 1497 1498 /* Reinitialize WaveLAN. */ 1499 wi_init(sc); 1500 1501 return; 1502} 1503 1504static int 1505wi_ioctl(ifp, command, data) 1506 struct ifnet *ifp; 1507 u_long command; 1508 caddr_t data; 1509{ 1510 int error = 0; 1511 int len; 1512 u_int8_t tmpkey[14]; 1513 char tmpssid[IEEE80211_NWID_LEN]; 1514 struct wi_softc *sc; 1515 struct wi_req wreq; 1516 struct ifreq *ifr; 1517 struct ieee80211req *ireq; 1518 struct proc *p = curproc; 1519 1520 sc = ifp->if_softc; 1521 WI_LOCK(sc); 1522 ifr = (struct ifreq *)data; 1523 ireq = (struct ieee80211req *)data; 1524 1525 if (sc->wi_gone) { 1526 error = ENODEV; 1527 goto out; 1528 } 1529 1530 switch(command) { 1531 case SIOCSIFADDR: 1532 case SIOCGIFADDR: 1533 case SIOCSIFMTU: 1534 error = ether_ioctl(ifp, command, data); 1535 break; 1536 case SIOCSIFFLAGS: 1537 if (ifp->if_flags & IFF_UP) { 1538 if (ifp->if_flags & IFF_RUNNING && 1539 ifp->if_flags & IFF_PROMISC && 1540 !(sc->wi_if_flags & IFF_PROMISC)) { 1541 WI_SETVAL(WI_RID_PROMISC, 1); 1542 } else if (ifp->if_flags & IFF_RUNNING && 1543 !(ifp->if_flags & IFF_PROMISC) && 1544 sc->wi_if_flags & IFF_PROMISC) { 1545 WI_SETVAL(WI_RID_PROMISC, 0); 1546 } else 1547 wi_init(sc); 1548 } else { 1549 if (ifp->if_flags & IFF_RUNNING) { 1550 wi_stop(sc); 1551 } 1552 } 1553 sc->wi_if_flags = ifp->if_flags; 1554 error = 0; 1555 break; 1556 case SIOCSIFMEDIA: 1557 case SIOCGIFMEDIA: 1558 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); 1559 break; 1560 case SIOCADDMULTI: 1561 case SIOCDELMULTI: 1562 wi_setmulti(sc); 1563 error = 0; 1564 break; 1565 case SIOCGWAVELAN: 1566 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1567 if (error) 1568 break; 1569 /* Don't show WEP keys to non-root users. */ 1570 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(p)) 1571 break; 1572 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1573 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1574 sizeof(sc->wi_stats)); 1575 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; 1576 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) { 1577 bcopy((char *)&sc->wi_keys, (char *)&wreq, 1578 sizeof(struct wi_ltv_keys)); 1579 } 1580#ifdef WICACHE 1581 else if (wreq.wi_type == WI_RID_ZERO_CACHE) { 1582 sc->wi_sigitems = sc->wi_nextitem = 0; 1583 } else if (wreq.wi_type == WI_RID_READ_CACHE) { 1584 char *pt = (char *)&wreq.wi_val; 1585 bcopy((char *)&sc->wi_sigitems, 1586 (char *)pt, sizeof(int)); 1587 pt += (sizeof (int)); 1588 wreq.wi_len = sizeof(int) / 2; 1589 bcopy((char *)&sc->wi_sigcache, (char *)pt, 1590 sizeof(struct wi_sigcache) * sc->wi_sigitems); 1591 wreq.wi_len += ((sizeof(struct wi_sigcache) * 1592 sc->wi_sigitems) / 2) + 1; 1593 } 1594#endif 1595 else { 1596 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { 1597 error = EINVAL; 1598 break; 1599 } 1600 } 1601 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1602 break; 1603 case SIOCSWAVELAN: 1604 if ((error = suser(p))) 1605 goto out; 1606 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1607 if (error) 1608 break; 1609 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1610 error = EINVAL; 1611 break; 1612 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) { 1613 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val, 1614 wreq.wi_len); 1615 } else { 1616 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1617 if (!error) 1618 wi_setdef(sc, &wreq); 1619 } 1620 break; 1621 case SIOCG80211: 1622 switch(ireq->i_type) { 1623 case IEEE80211_IOC_SSID: 1624 if(ireq->i_val == -1) { 1625 bzero(tmpssid, IEEE80211_NWID_LEN); 1626 error = wi_get_cur_ssid(sc, tmpssid, &len); 1627 if (error != 0) 1628 break; 1629 error = copyout(tmpssid, ireq->i_data, 1630 IEEE80211_NWID_LEN); 1631 ireq->i_len = len; 1632 } else if (ireq->i_val == 0) { 1633 error = copyout(sc->wi_net_name, 1634 ireq->i_data, 1635 IEEE80211_NWID_LEN); 1636 ireq->i_len = IEEE80211_NWID_LEN; 1637 } else 1638 error = EINVAL; 1639 break; 1640 case IEEE80211_IOC_NUMSSIDS: 1641 ireq->i_val = 1; 1642 break; 1643 case IEEE80211_IOC_WEP: 1644 if(!sc->wi_has_wep) { 1645 ireq->i_val = IEEE80211_WEP_NOSUP; 1646 } else { 1647 if(sc->wi_use_wep) { 1648 ireq->i_val = 1649 IEEE80211_WEP_MIXED; 1650 } else { 1651 ireq->i_val = 1652 IEEE80211_WEP_OFF; 1653 } 1654 } 1655 break; 1656 case IEEE80211_IOC_WEPKEY: 1657 if(!sc->wi_has_wep || 1658 ireq->i_val < 0 || ireq->i_val > 3) { 1659 error = EINVAL; 1660 break; 1661 } 1662 len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen; 1663 if (suser(p)) 1664 bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 1665 tmpkey, len); 1666 else 1667 bzero(tmpkey, len); 1668 1669 ireq->i_len = len; 1670 error = copyout(tmpkey, ireq->i_data, len); 1671 1672 break; 1673 case IEEE80211_IOC_NUMWEPKEYS: 1674 if(!sc->wi_has_wep) 1675 error = EINVAL; 1676 else 1677 ireq->i_val = 4; 1678 break; 1679 case IEEE80211_IOC_WEPTXKEY: 1680 if(!sc->wi_has_wep) 1681 error = EINVAL; 1682 else 1683 ireq->i_val = sc->wi_tx_key; 1684 break; 1685 case IEEE80211_IOC_AUTHMODE: 1686 ireq->i_val = IEEE80211_AUTH_NONE; 1687 break; 1688 case IEEE80211_IOC_STATIONNAME: 1689 error = copyout(sc->wi_node_name, 1690 ireq->i_data, IEEE80211_NWID_LEN); 1691 ireq->i_len = IEEE80211_NWID_LEN; 1692 break; 1693 case IEEE80211_IOC_CHANNEL: 1694 wreq.wi_type = WI_RID_CURRENT_CHAN; 1695 wreq.wi_len = WI_MAX_DATALEN; 1696 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) 1697 error = EINVAL; 1698 else { 1699 ireq->i_val = wreq.wi_val[0]; 1700 } 1701 break; 1702 case IEEE80211_IOC_POWERSAVE: 1703 if(sc->wi_pm_enabled) 1704 ireq->i_val = IEEE80211_POWERSAVE_ON; 1705 else 1706 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1707 break; 1708 case IEEE80211_IOC_POWERSAVESLEEP: 1709 ireq->i_val = sc->wi_max_sleep; 1710 break; 1711 default: 1712 error = EINVAL; 1713 } 1714 break; 1715 case SIOCS80211: 1716 if ((error = suser(p))) 1717 goto out; 1718 switch(ireq->i_type) { 1719 case IEEE80211_IOC_SSID: 1720 if (ireq->i_val != 0 || 1721 ireq->i_len > IEEE80211_NWID_LEN) { 1722 error = EINVAL; 1723 break; 1724 } 1725 /* We set both of them */ 1726 bzero(sc->wi_net_name, IEEE80211_NWID_LEN); 1727 error = copyin(ireq->i_data, 1728 sc->wi_net_name, ireq->i_len); 1729 bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN); 1730 break; 1731 case IEEE80211_IOC_WEP: 1732 /* 1733 * These cards only support one mode so 1734 * we just turn wep on what ever is 1735 * passed in if it's not OFF. 1736 */ 1737 if (ireq->i_val == IEEE80211_WEP_OFF) { 1738 sc->wi_use_wep = 0; 1739 } else { 1740 sc->wi_use_wep = 1; 1741 } 1742 break; 1743 case IEEE80211_IOC_WEPKEY: 1744 if (ireq->i_val < 0 || ireq->i_val > 3 || 1745 ireq->i_len > 13) { 1746 error = EINVAL; 1747 break; 1748 } 1749 bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13); 1750 error = copyin(ireq->i_data, 1751 sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 1752 ireq->i_len); 1753 if(error) 1754 break; 1755 sc->wi_keys.wi_keys[ireq->i_val].wi_keylen = 1756 ireq->i_len; 1757 break; 1758 case IEEE80211_IOC_WEPTXKEY: 1759 if (ireq->i_val < 0 || ireq->i_val > 3) { 1760 error = EINVAL; 1761 break; 1762 } 1763 sc->wi_tx_key = ireq->i_val; 1764 break; 1765 case IEEE80211_IOC_AUTHMODE: 1766 error = EINVAL; 1767 break; 1768 case IEEE80211_IOC_STATIONNAME: 1769 if (ireq->i_len > 32) { 1770 error = EINVAL; 1771 break; 1772 } 1773 bzero(sc->wi_node_name, 32); 1774 error = copyin(ireq->i_data, 1775 sc->wi_node_name, ireq->i_len); 1776 break; 1777 case IEEE80211_IOC_CHANNEL: 1778 /* 1779 * The actual range is 1-14, but if you 1780 * set it to 0 you get the default. So 1781 * we let that work too. 1782 */ 1783 if (ireq->i_val < 0 || ireq->i_val > 14) { 1784 error = EINVAL; 1785 break; 1786 } 1787 sc->wi_channel = ireq->i_val; 1788 break; 1789 case IEEE80211_IOC_POWERSAVE: 1790 switch (ireq->i_val) { 1791 case IEEE80211_POWERSAVE_OFF: 1792 sc->wi_pm_enabled = 0; 1793 break; 1794 case IEEE80211_POWERSAVE_ON: 1795 sc->wi_pm_enabled = 1; 1796 break; 1797 default: 1798 error = EINVAL; 1799 break; 1800 } 1801 break; 1802 case IEEE80211_IOC_POWERSAVESLEEP: 1803 if (ireq->i_val < 0) { 1804 error = EINVAL; 1805 break; 1806 } 1807 sc->wi_max_sleep = ireq->i_val; 1808 break; 1809 default: 1810 error = EINVAL; 1811 break; 1812 } 1813 1814 /* Reinitialize WaveLAN. */ 1815 wi_init(sc); 1816 1817 break; 1818 default: 1819 error = EINVAL; 1820 break; 1821 } 1822out: 1823 WI_UNLOCK(sc); 1824 1825 return(error); 1826} 1827 1828static void 1829wi_init(xsc) 1830 void *xsc; 1831{ 1832 struct wi_softc *sc = xsc; 1833 struct ifnet *ifp = &sc->arpcom.ac_if; 1834 struct wi_ltv_macaddr mac; 1835 int id = 0; 1836 1837 WI_LOCK(sc); 1838 1839 if (sc->wi_gone) { 1840 WI_UNLOCK(sc); 1841 return; 1842 } 1843 1844 if (ifp->if_flags & IFF_RUNNING) 1845 wi_stop(sc); 1846 1847 wi_reset(sc); 1848 1849 /* Program max data length. */ 1850 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len); 1851 1852 /* Enable/disable IBSS creation. */ 1853 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss); 1854 1855 /* Set the port type. */ 1856 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype); 1857 1858 /* Program the RTS/CTS threshold. */ 1859 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh); 1860 1861 /* Program the TX rate */ 1862 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate); 1863 1864 /* Access point density */ 1865 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density); 1866 1867 /* Power Management Enabled */ 1868 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled); 1869 1870 /* Power Managment Max Sleep */ 1871 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); 1872 1873 /* Specify the IBSS name */ 1874 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name); 1875 1876 /* Specify the network name */ 1877 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name); 1878 1879 /* Specify the frequency to use */ 1880 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel); 1881 1882 /* Program the nodename. */ 1883 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name); 1884 1885 /* Set our MAC address. */ 1886 mac.wi_len = 4; 1887 mac.wi_type = WI_RID_MAC_NODE; 1888 bcopy((char *)&sc->arpcom.ac_enaddr, 1889 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN); 1890 wi_write_record(sc, (struct wi_ltv_gen *)&mac); 1891 1892 /* Configure WEP. */ 1893 if (sc->wi_has_wep) { 1894 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); 1895 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); 1896 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; 1897 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS; 1898 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys); 1899 } 1900 1901 /* Initialize promisc mode. */ 1902 if (ifp->if_flags & IFF_PROMISC) { 1903 WI_SETVAL(WI_RID_PROMISC, 1); 1904 } else { 1905 WI_SETVAL(WI_RID_PROMISC, 0); 1906 } 1907 1908 /* Set multicast filter. */ 1909 wi_setmulti(sc); 1910 1911 /* Enable desired port */ 1912 wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0); 1913 1914 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id)) 1915 device_printf(sc->dev, "tx buffer allocation failed\n"); 1916 sc->wi_tx_data_id = id; 1917 1918 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id)) 1919 device_printf(sc->dev, "mgmt. buffer allocation failed\n"); 1920 sc->wi_tx_mgmt_id = id; 1921 1922 /* enable interrupts */ 1923 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 1924 1925 ifp->if_flags |= IFF_RUNNING; 1926 ifp->if_flags &= ~IFF_OACTIVE; 1927 1928 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 1929 WI_UNLOCK(sc); 1930 1931 return; 1932} 1933 1934static void 1935wi_start(ifp) 1936 struct ifnet *ifp; 1937{ 1938 struct wi_softc *sc; 1939 struct mbuf *m0; 1940 struct wi_frame tx_frame; 1941 struct ether_header *eh; 1942 int id; 1943 1944 sc = ifp->if_softc; 1945 WI_LOCK(sc); 1946 1947 if (sc->wi_gone) { 1948 WI_UNLOCK(sc); 1949 return; 1950 } 1951 1952 if (ifp->if_flags & IFF_OACTIVE) { 1953 WI_UNLOCK(sc); 1954 return; 1955 } 1956 1957 IF_DEQUEUE(&ifp->if_snd, m0); 1958 if (m0 == NULL) { 1959 WI_UNLOCK(sc); 1960 return; 1961 } 1962 1963 bzero((char *)&tx_frame, sizeof(tx_frame)); 1964 id = sc->wi_tx_data_id; 1965 eh = mtod(m0, struct ether_header *); 1966 1967 /* 1968 * Use RFC1042 encoding for IP and ARP datagrams, 1969 * 802.3 for anything else. 1970 */ 1971 if (ntohs(eh->ether_type) > ETHER_MAX_LEN) { 1972 bcopy((char *)&eh->ether_dhost, 1973 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN); 1974 bcopy((char *)&eh->ether_shost, 1975 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 1976 bcopy((char *)&eh->ether_dhost, 1977 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN); 1978 bcopy((char *)&eh->ether_shost, 1979 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN); 1980 1981 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN; 1982 tx_frame.wi_frame_ctl = WI_FTYPE_DATA; 1983 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0); 1984 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1); 1985 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1986 tx_frame.wi_type = eh->ether_type; 1987 1988 m_copydata(m0, sizeof(struct ether_header), 1989 m0->m_pkthdr.len - sizeof(struct ether_header), 1990 (caddr_t)&sc->wi_txbuf); 1991 1992 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1993 sizeof(struct wi_frame)); 1994 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf, 1995 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2); 1996 } else { 1997 tx_frame.wi_dat_len = m0->m_pkthdr.len; 1998 1999 eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 2000 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf); 2001 2002 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 2003 sizeof(struct wi_frame)); 2004 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf, 2005 m0->m_pkthdr.len + 2); 2006 } 2007 2008 /* 2009 * If there's a BPF listner, bounce a copy of 2010 * this frame to him. 2011 */ 2012 if (ifp->if_bpf) 2013 bpf_mtap(ifp, m0); 2014 2015 m_freem(m0); 2016 2017 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) 2018 device_printf(sc->dev, "xmit failed\n"); 2019 2020 ifp->if_flags |= IFF_OACTIVE; 2021 2022 /* 2023 * Set a timeout in case the chip goes out to lunch. 2024 */ 2025 ifp->if_timer = 5; 2026 2027 WI_UNLOCK(sc); 2028 return; 2029} 2030 2031static int 2032wi_mgmt_xmit(sc, data, len) 2033 struct wi_softc *sc; 2034 caddr_t data; 2035 int len; 2036{ 2037 struct wi_frame tx_frame; 2038 int id; 2039 struct wi_80211_hdr *hdr; 2040 caddr_t dptr; 2041 2042 if (sc->wi_gone) 2043 return(ENODEV); 2044 2045 hdr = (struct wi_80211_hdr *)data; 2046 dptr = data + sizeof(struct wi_80211_hdr); 2047 2048 bzero((char *)&tx_frame, sizeof(tx_frame)); 2049 id = sc->wi_tx_mgmt_id; 2050 2051 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl, 2052 sizeof(struct wi_80211_hdr)); 2053 2054 tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN; 2055 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN); 2056 2057 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 2058 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 2059 (len - sizeof(struct wi_80211_hdr)) + 2); 2060 2061 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) { 2062 device_printf(sc->dev, "xmit failed\n"); 2063 return(EIO); 2064 } 2065 2066 return(0); 2067} 2068 2069static void 2070wi_stop(sc) 2071 struct wi_softc *sc; 2072{ 2073 struct ifnet *ifp; 2074 2075 WI_LOCK(sc); 2076 2077 if (sc->wi_gone) { 2078 WI_UNLOCK(sc); 2079 return; 2080 } 2081 2082 ifp = &sc->arpcom.ac_if; 2083 2084 /* 2085 * If the card is gone and the memory port isn't mapped, we will 2086 * (hopefully) get 0xffff back from the status read, which is not 2087 * a valid status value. 2088 */ 2089 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) { 2090 CSR_WRITE_2(sc, WI_INT_EN, 0); 2091 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0); 2092 } 2093 2094 untimeout(wi_inquire, sc, sc->wi_stat_ch); 2095 2096 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 2097 2098 WI_UNLOCK(sc); 2099 return; 2100} 2101 2102static void 2103wi_watchdog(ifp) 2104 struct ifnet *ifp; 2105{ 2106 struct wi_softc *sc; 2107 2108 sc = ifp->if_softc; 2109 2110 device_printf(sc->dev, "watchdog timeout\n"); 2111 2112 wi_init(sc); 2113 2114 ifp->if_oerrors++; 2115 2116 return; 2117} 2118 2119static int 2120wi_alloc(dev, rid) 2121 device_t dev; 2122 int rid; 2123{ 2124 struct wi_softc *sc = device_get_softc(dev); 2125 2126 if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { 2127 sc->iobase_rid = rid; 2128 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, 2129 &sc->iobase_rid, 0, ~0, (1 << 6), 2130 rman_make_alignment_flags(1 << 6) | RF_ACTIVE); 2131 if (!sc->iobase) { 2132 device_printf(dev, "No I/O space?!\n"); 2133 return (ENXIO); 2134 } 2135 2136 sc->wi_io_addr = rman_get_start(sc->iobase); 2137 sc->wi_btag = rman_get_bustag(sc->iobase); 2138 sc->wi_bhandle = rman_get_bushandle(sc->iobase); 2139 } else { 2140 sc->mem_rid = rid; 2141 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, 2142 &sc->mem_rid, 0, ~0, 1, RF_ACTIVE); 2143 2144 if (!sc->mem) { 2145 device_printf(dev, "No Mem space on prism2.5?\n"); 2146 return (ENXIO); 2147 } 2148 2149 sc->wi_btag = rman_get_bustag(sc->mem); 2150 sc->wi_bhandle = rman_get_bushandle(sc->mem); 2151 } 2152 2153 2154 sc->irq_rid = 0; 2155 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 2156 0, ~0, 1, RF_ACTIVE | 2157 ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE)); 2158 2159 if (!sc->irq) { 2160 wi_free(dev); 2161 device_printf(dev, "No irq?!\n"); 2162 return (ENXIO); 2163 } 2164 2165 sc->dev = dev; 2166 sc->wi_unit = device_get_unit(dev); 2167 2168 return (0); 2169} 2170 2171static void 2172wi_free(dev) 2173 device_t dev; 2174{ 2175 struct wi_softc *sc = device_get_softc(dev); 2176 2177 if (sc->iobase != NULL) { 2178 bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase); 2179 sc->iobase = NULL; 2180 } 2181 if (sc->irq != NULL) { 2182 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); 2183 sc->irq = NULL; 2184 } 2185 if (sc->mem != NULL) { 2186 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); 2187 sc->mem = NULL; 2188 } 2189 2190 return; 2191} 2192 2193static void 2194wi_shutdown(dev) 2195 device_t dev; 2196{ 2197 struct wi_softc *sc; 2198 2199 sc = device_get_softc(dev); 2200 wi_stop(sc); 2201 2202 return; 2203} 2204 2205#ifdef WICACHE 2206/* wavelan signal strength cache code. 2207 * store signal/noise/quality on per MAC src basis in 2208 * a small fixed cache. The cache wraps if > MAX slots 2209 * used. The cache may be zeroed out to start over. 2210 * Two simple filters exist to reduce computation: 2211 * 1. ip only (literally 0x800) which may be used 2212 * to ignore some packets. It defaults to ip only. 2213 * it could be used to focus on broadcast, non-IP 802.11 beacons. 2214 * 2. multicast/broadcast only. This may be used to 2215 * ignore unicast packets and only cache signal strength 2216 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2217 * beacons and not unicast traffic. 2218 * 2219 * The cache stores (MAC src(index), IP src (major clue), signal, 2220 * quality, noise) 2221 * 2222 * No apologies for storing IP src here. It's easy and saves much 2223 * trouble elsewhere. The cache is assumed to be INET dependent, 2224 * although it need not be. 2225 */ 2226 2227#ifdef documentation 2228 2229int wi_sigitems; /* number of cached entries */ 2230struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */ 2231int wi_nextitem; /* index/# of entries */ 2232 2233 2234#endif 2235 2236/* control variables for cache filtering. Basic idea is 2237 * to reduce cost (e.g., to only Mobile-IP agent beacons 2238 * which are broadcast or multicast). Still you might 2239 * want to measure signal strength with unicast ping packets 2240 * on a pt. to pt. ant. setup. 2241 */ 2242/* set true if you want to limit cache items to broadcast/mcast 2243 * only packets (not unicast). Useful for mobile-ip beacons which 2244 * are broadcast/multicast at network layer. Default is all packets 2245 * so ping/unicast will work say with pt. to pt. antennae setup. 2246 */ 2247static int wi_cache_mcastonly = 0; 2248SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW, 2249 &wi_cache_mcastonly, 0, ""); 2250 2251/* set true if you want to limit cache items to IP packets only 2252*/ 2253static int wi_cache_iponly = 1; 2254SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW, 2255 &wi_cache_iponly, 0, ""); 2256 2257/* 2258 * Original comments: 2259 * ----------------- 2260 * wi_cache_store, per rx packet store signal 2261 * strength in MAC (src) indexed cache. 2262 * 2263 * follows linux driver in how signal strength is computed. 2264 * In ad hoc mode, we use the rx_quality field. 2265 * signal and noise are trimmed to fit in the range from 47..138. 2266 * rx_quality field MSB is signal strength. 2267 * rx_quality field LSB is noise. 2268 * "quality" is (signal - noise) as is log value. 2269 * note: quality CAN be negative. 2270 * 2271 * In BSS mode, we use the RID for communication quality. 2272 * TBD: BSS mode is currently untested. 2273 * 2274 * Bill's comments: 2275 * --------------- 2276 * Actually, we use the rx_quality field all the time for both "ad-hoc" 2277 * and BSS modes. Why? Because reading an RID is really, really expensive: 2278 * there's a bunch of PIO operations that have to be done to read a record 2279 * from the NIC, and reading the comms quality RID each time a packet is 2280 * received can really hurt performance. We don't have to do this anyway: 2281 * the comms quality field only reflects the values in the rx_quality field 2282 * anyway. The comms quality RID is only meaningful in infrastructure mode, 2283 * but the values it contains are updated based on the rx_quality from 2284 * frames received from the access point. 2285 * 2286 * Also, according to Lucent, the signal strength and noise level values 2287 * can be converted to dBms by subtracting 149, so I've modified the code 2288 * to do that instead of the scaling it did originally. 2289 */ 2290static void 2291wi_cache_store(struct wi_softc *sc, struct ether_header *eh, 2292 struct mbuf *m, unsigned short rx_quality) 2293{ 2294 struct ip *ip = 0; 2295 int i; 2296 static int cache_slot = 0; /* use this cache entry */ 2297 static int wrapindex = 0; /* next "free" cache entry */ 2298 int sig, noise; 2299 int sawip=0; 2300 2301 /* filters: 2302 * 1. ip only 2303 * 2. configurable filter to throw out unicast packets, 2304 * keep multicast only. 2305 */ 2306 2307 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) { 2308 sawip = 1; 2309 } 2310 2311 /* filter for ip packets only 2312 */ 2313 if (wi_cache_iponly && !sawip) { 2314 return; 2315 } 2316 2317 /* filter for broadcast/multicast only 2318 */ 2319 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2320 return; 2321 } 2322 2323#ifdef SIGDEBUG 2324 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit, 2325 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2326#endif 2327 2328 /* find the ip header. we want to store the ip_src 2329 * address. 2330 */ 2331 if (sawip) { 2332 ip = mtod(m, struct ip *); 2333 } 2334 2335 /* do a linear search for a matching MAC address 2336 * in the cache table 2337 * . MAC address is 6 bytes, 2338 * . var w_nextitem holds total number of entries already cached 2339 */ 2340 for(i = 0; i < sc->wi_nextitem; i++) { 2341 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) { 2342 /* Match!, 2343 * so we already have this entry, 2344 * update the data 2345 */ 2346 break; 2347 } 2348 } 2349 2350 /* did we find a matching mac address? 2351 * if yes, then overwrite a previously existing cache entry 2352 */ 2353 if (i < sc->wi_nextitem ) { 2354 cache_slot = i; 2355 } 2356 /* else, have a new address entry,so 2357 * add this new entry, 2358 * if table full, then we need to replace LRU entry 2359 */ 2360 else { 2361 2362 /* check for space in cache table 2363 * note: wi_nextitem also holds number of entries 2364 * added in the cache table 2365 */ 2366 if ( sc->wi_nextitem < MAXWICACHE ) { 2367 cache_slot = sc->wi_nextitem; 2368 sc->wi_nextitem++; 2369 sc->wi_sigitems = sc->wi_nextitem; 2370 } 2371 /* no space found, so simply wrap with wrap index 2372 * and "zap" the next entry 2373 */ 2374 else { 2375 if (wrapindex == MAXWICACHE) { 2376 wrapindex = 0; 2377 } 2378 cache_slot = wrapindex++; 2379 } 2380 } 2381 2382 /* invariant: cache_slot now points at some slot 2383 * in cache. 2384 */ 2385 if (cache_slot < 0 || cache_slot >= MAXWICACHE) { 2386 log(LOG_ERR, "wi_cache_store, bad index: %d of " 2387 "[0..%d], gross cache error\n", 2388 cache_slot, MAXWICACHE); 2389 return; 2390 } 2391 2392 /* store items in cache 2393 * .ip source address 2394 * .mac src 2395 * .signal, etc. 2396 */ 2397 if (sawip) { 2398 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 2399 } 2400 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6); 2401 2402 sig = (rx_quality >> 8) & 0xFF; 2403 noise = rx_quality & 0xFF; 2404 sc->wi_sigcache[cache_slot].signal = sig - 149; 2405 sc->wi_sigcache[cache_slot].noise = noise - 149; 2406 sc->wi_sigcache[cache_slot].quality = sig - noise; 2407 2408 return; 2409} 2410#endif 2411 2412static int 2413wi_get_cur_ssid(sc, ssid, len) 2414 struct wi_softc *sc; 2415 char *ssid; 2416 int *len; 2417{ 2418 int error = 0; 2419 struct wi_req wreq; 2420 2421 wreq.wi_len = WI_MAX_DATALEN; 2422 switch (sc->wi_ptype) { 2423 case WI_PORTTYPE_ADHOC: 2424 wreq.wi_type = WI_RID_CURRENT_SSID; 2425 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2426 if (error != 0) 2427 break; 2428 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) { 2429 error = EINVAL; 2430 break; 2431 } 2432 *len = wreq.wi_val[0]; 2433 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN); 2434 break; 2435 case WI_PORTTYPE_BSS: 2436 wreq.wi_type = WI_RID_COMMQUAL; 2437 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2438 if (error != 0) 2439 break; 2440 if (wreq.wi_val[0] != 0) /* associated */ { 2441 wreq.wi_type = WI_RID_CURRENT_SSID; 2442 wreq.wi_len = WI_MAX_DATALEN; 2443 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq); 2444 if (error != 0) 2445 break; 2446 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) { 2447 error = EINVAL; 2448 break; 2449 } 2450 *len = wreq.wi_val[0]; 2451 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN); 2452 } else { 2453 *len = IEEE80211_NWID_LEN; 2454 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN); 2455 } 2456 break; 2457 default: 2458 error = EINVAL; 2459 break; 2460 } 2461 2462 return error; 2463} 2464 2465static int 2466wi_media_change(ifp) 2467 struct ifnet *ifp; 2468{ 2469 struct wi_softc *sc = ifp->if_softc; 2470 int otype = sc->wi_ptype; 2471 int orate = sc->wi_tx_rate; 2472 2473 if ((sc->ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2474 sc->wi_ptype = WI_PORTTYPE_ADHOC; 2475 else 2476 sc->wi_ptype = WI_PORTTYPE_BSS; 2477 2478 switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) { 2479 case IFM_IEEE80211_DS1: 2480 sc->wi_tx_rate = 1; 2481 break; 2482 case IFM_IEEE80211_DS2: 2483 sc->wi_tx_rate = 2; 2484 break; 2485 case IFM_IEEE80211_DS5: 2486 sc->wi_tx_rate = 5; 2487 break; 2488 case IFM_IEEE80211_DS11: 2489 sc->wi_tx_rate = 11; 2490 break; 2491 case IFM_AUTO: 2492 sc->wi_tx_rate = 3; 2493 break; 2494 } 2495 2496 if (otype != sc->wi_ptype || 2497 orate != sc->wi_tx_rate) 2498 wi_init(sc); 2499 2500 return(0); 2501} 2502 2503static void 2504wi_media_status(ifp, imr) 2505 struct ifnet *ifp; 2506 struct ifmediareq *imr; 2507{ 2508 struct wi_req wreq; 2509 struct wi_softc *sc = ifp->if_softc; 2510 2511 if (sc->wi_tx_rate == 3) { 2512 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2513 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) 2514 imr->ifm_active |= IFM_IEEE80211_ADHOC; 2515 wreq.wi_type = WI_RID_CUR_TX_RATE; 2516 wreq.wi_len = WI_MAX_DATALEN; 2517 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) { 2518 switch(wreq.wi_val[0]) { 2519 case 1: 2520 imr->ifm_active |= IFM_IEEE80211_DS1; 2521 break; 2522 case 2: 2523 imr->ifm_active |= IFM_IEEE80211_DS2; 2524 break; 2525 case 6: 2526 imr->ifm_active |= IFM_IEEE80211_DS5; 2527 break; 2528 case 11: 2529 imr->ifm_active |= IFM_IEEE80211_DS11; 2530 break; 2531 } 2532 } 2533 } else { 2534 imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media; 2535 } 2536 2537 imr->ifm_status = IFM_AVALID; 2538 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) 2539 /* 2540 * XXX: It would be nice if we could give some actually 2541 * useful status like whether we joined another IBSS or 2542 * created one ourselves. 2543 */ 2544 imr->ifm_status |= IFM_ACTIVE; 2545 else { 2546 wreq.wi_type = WI_RID_COMMQUAL; 2547 wreq.wi_len = WI_MAX_DATALEN; 2548 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 && 2549 wreq.wi_val[0] != 0) 2550 imr->ifm_status |= IFM_ACTIVE; 2551 } 2552} 2553