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