if_wi.c revision 74838
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 * $FreeBSD: head/sys/dev/wi/if_wi.c 74838 2001-03-27 05:03:49Z alfred $ 33 */ 34 35/* 36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City 41 */ 42 43/* 44 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 45 * from Lucent. Unlike the older cards, the new ones are programmed 46 * entirely via a firmware-driven controller called the Hermes. 47 * Unfortunately, Lucent will not release the Hermes programming manual 48 * without an NDA (if at all). What they do release is an API library 49 * called the HCF (Hardware Control Functions) which is supposed to 50 * do the device-specific operations of a device driver for you. The 51 * publically available version of the HCF library (the 'HCF Light') is 52 * a) extremely gross, b) lacks certain features, particularly support 53 * for 802.11 frames, and c) is contaminated by the GNU Public License. 54 * 55 * This driver does not use the HCF or HCF Light at all. Instead, it 56 * programs the Hermes controller directly, using information gleaned 57 * from the HCF Light code and corresponding documentation. 58 * 59 * This driver supports both the PCMCIA and ISA versions of the 60 * WaveLAN/IEEE cards. Note however that the ISA card isn't really 61 * anything of the sort: it's actually a PCMCIA bridge adapter 62 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 63 * inserted. Consequently, you need to use the pccard support for 64 * both the ISA and PCMCIA adapters. 65 */ 66 67#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 68#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ 69#define WICACHE /* turn on signal strength cache code */ 70 71#include <sys/param.h> 72#include <sys/systm.h> 73#include <sys/sockio.h> 74#include <sys/mbuf.h> 75#include <sys/kernel.h> 76#include <sys/socket.h> 77#include <sys/module.h> 78#include <sys/bus.h> 79#include <sys/syslog.h> 80#include <sys/sysctl.h> 81 82#include <machine/bus.h> 83#include <machine/resource.h> 84#include <machine/md_var.h> 85#include <machine/bus_pio.h> 86#include <sys/rman.h> 87 88#include <net/if.h> 89#include <net/if_arp.h> 90#include <net/ethernet.h> 91#include <net/if_dl.h> 92#include <net/if_media.h> 93#include <net/if_types.h> 94 95#include <netinet/in.h> 96#include <netinet/in_systm.h> 97#include <netinet/in_var.h> 98#include <netinet/ip.h> 99#include <netinet/if_ether.h> 100 101#include <net/bpf.h> 102 103#include <dev/pccard/pccardvar.h> 104#include <dev/pccard/pccarddevs.h> 105 106#include <dev/wi/if_wavelan_ieee.h> 107#include <dev/wi/if_wireg.h> 108 109#include "card_if.h" 110 111#if !defined(lint) 112static const char rcsid[] = 113 "$FreeBSD: head/sys/dev/wi/if_wi.c 74838 2001-03-27 05:03:49Z alfred $"; 114#endif 115 116#ifdef foo 117static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 }; 118#endif 119 120static void wi_intr __P((void *)); 121static void wi_reset __P((struct wi_softc *)); 122static int wi_ioctl __P((struct ifnet *, u_long, caddr_t)); 123static void wi_init __P((void *)); 124static void wi_start __P((struct ifnet *)); 125static void wi_stop __P((struct wi_softc *)); 126static void wi_watchdog __P((struct ifnet *)); 127static void wi_rxeof __P((struct wi_softc *)); 128static void wi_txeof __P((struct wi_softc *, int)); 129static void wi_update_stats __P((struct wi_softc *)); 130static void wi_setmulti __P((struct wi_softc *)); 131 132static int wi_cmd __P((struct wi_softc *, int, int)); 133static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *)); 134static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *)); 135static int wi_read_data __P((struct wi_softc *, int, 136 int, caddr_t, int)); 137static int wi_write_data __P((struct wi_softc *, int, 138 int, caddr_t, int)); 139static int wi_seek __P((struct wi_softc *, int, int, int)); 140static int wi_alloc_nicmem __P((struct wi_softc *, int, int *)); 141static void wi_inquire __P((void *)); 142static void wi_setdef __P((struct wi_softc *, struct wi_req *)); 143static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int)); 144 145#ifdef WICACHE 146static 147void wi_cache_store __P((struct wi_softc *, struct ether_header *, 148 struct mbuf *, unsigned short)); 149#endif 150 151static int wi_pccard_match __P((device_t)); 152static int wi_pccard_probe __P((device_t)); 153static int wi_pccard_attach __P((device_t)); 154static int wi_pccard_detach __P((device_t)); 155static void wi_shutdown __P((device_t)); 156 157static int wi_alloc __P((device_t)); 158static void wi_free __P((device_t)); 159 160static device_method_t wi_pccard_methods[] = { 161 /* Device interface */ 162 DEVMETHOD(device_probe, pccard_compat_probe), 163 DEVMETHOD(device_attach, pccard_compat_attach), 164 DEVMETHOD(device_detach, wi_pccard_detach), 165 DEVMETHOD(device_shutdown, wi_shutdown), 166 167 /* Card interface */ 168 DEVMETHOD(card_compat_match, wi_pccard_match), 169 DEVMETHOD(card_compat_probe, wi_pccard_probe), 170 DEVMETHOD(card_compat_attach, wi_pccard_attach), 171 172 { 0, 0 } 173}; 174 175static driver_t wi_pccard_driver = { 176 "wi", 177 wi_pccard_methods, 178 sizeof(struct wi_softc) 179}; 180 181static devclass_t wi_pccard_devclass; 182 183DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_pccard_devclass, 0, 0); 184 185static const struct pccard_product wi_pccard_products[] = { 186 { PCCARD_STR_LUCENT_WAVELAN_IEEE, PCCARD_VENDOR_LUCENT, 187 PCCARD_PRODUCT_LUCENT_WAVELAN_IEEE, 0, 188 PCCARD_CIS_LUCENT_WAVELAN_IEEE }, 189}; 190 191static int wi_pccard_match(dev) 192 device_t dev; 193{ 194 const struct pccard_product *pp; 195 196 if ((pp = pccard_product_lookup(dev, wi_pccard_products, 197 sizeof(wi_pccard_products[0]), NULL)) != NULL) { 198 device_set_desc(dev, pp->pp_name); 199 return 0; 200 } 201 return ENXIO; 202} 203 204static int wi_pccard_probe(dev) 205 device_t dev; 206{ 207 struct wi_softc *sc; 208 int error; 209 210 sc = device_get_softc(dev); 211 sc->wi_gone = 0; 212 213 error = wi_alloc(dev); 214 if (error) 215 return (error); 216 217 device_set_desc(dev, "WaveLAN/IEEE 802.11"); 218 wi_free(dev); 219 220 /* Make sure interrupts are disabled. */ 221 CSR_WRITE_2(sc, WI_INT_EN, 0); 222 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 223 224 return (0); 225} 226 227static int wi_pccard_detach(dev) 228 device_t dev; 229{ 230 struct wi_softc *sc; 231 struct ifnet *ifp; 232 233 sc = device_get_softc(dev); 234 WI_LOCK(sc); 235 ifp = &sc->arpcom.ac_if; 236 237 if (sc->wi_gone) { 238 device_printf(dev, "already unloaded\n"); 239 WI_UNLOCK(sc); 240 return(ENODEV); 241 } 242 243 wi_stop(sc); 244 245 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); 246 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); 247 wi_free(dev); 248 sc->wi_gone = 1; 249 250 device_printf(dev, "unload\n"); 251 WI_UNLOCK(sc); 252 mtx_destroy(&sc->wi_mtx); 253 254 return(0); 255} 256 257static int wi_pccard_attach(device_t dev) 258{ 259 struct wi_softc *sc; 260 struct wi_ltv_macaddr mac; 261 struct wi_ltv_gen gen; 262 struct ifnet *ifp; 263 int error; 264 u_int32_t flags; 265 266 sc = device_get_softc(dev); 267 ifp = &sc->arpcom.ac_if; 268 269 /* 270 * XXX: quick hack to support Prism II chip. 271 * Currently, we need to set a flags in pccard.conf to specify 272 * which type chip is used. 273 * 274 * We need to replace this code in a future. 275 * It is better to use CIS than using a flag. 276 */ 277 flags = device_get_flags(dev); 278#define WI_FLAGS_PRISM2 0x10000 279 if (flags & WI_FLAGS_PRISM2) { 280 sc->wi_prism2 = 1; 281 if (bootverbose) { 282 device_printf(dev, "found PrismII chip\n"); 283 } 284 } 285 else { 286 sc->wi_prism2 = 0; 287 if (bootverbose) { 288 device_printf(dev, "found Lucent chip\n"); 289 } 290 } 291 292 error = wi_alloc(dev); 293 if (error) { 294 device_printf(dev, "wi_alloc() failed! (%d)\n", error); 295 return (error); 296 } 297 298 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 299 wi_intr, sc, &sc->wi_intrhand); 300 301 if (error) { 302 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 303 wi_free(dev); 304 return (error); 305 } 306 307 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_DEF | MTX_RECURSE); 308 WI_LOCK(sc); 309 310 /* Reset the NIC. */ 311 wi_reset(sc); 312 313 /* Read the station address. */ 314 mac.wi_type = WI_RID_MAC_NODE; 315 mac.wi_len = 4; 316 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 317 bcopy((char *)&mac.wi_mac_addr, 318 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 319 320 device_printf(dev, "Ethernet address: %6D\n", 321 sc->arpcom.ac_enaddr, ":"); 322 323 ifp->if_softc = sc; 324 ifp->if_unit = sc->wi_unit; 325 ifp->if_name = "wi"; 326 ifp->if_mtu = ETHERMTU; 327 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 328 ifp->if_ioctl = wi_ioctl; 329 ifp->if_output = ether_output; 330 ifp->if_start = wi_start; 331 ifp->if_watchdog = wi_watchdog; 332 ifp->if_init = wi_init; 333 ifp->if_baudrate = 10000000; 334 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 335 336 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 337 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name, 338 sizeof(WI_DEFAULT_NODENAME) - 1); 339 340 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 341 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name, 342 sizeof(WI_DEFAULT_NETNAME) - 1); 343 344 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 345 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name, 346 sizeof(WI_DEFAULT_IBSS) - 1); 347 348 sc->wi_portnum = WI_DEFAULT_PORT; 349 sc->wi_ptype = WI_PORTTYPE_BSS; 350 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY; 351 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH; 352 sc->wi_tx_rate = WI_DEFAULT_TX_RATE; 353 sc->wi_max_data_len = WI_DEFAULT_DATALEN; 354 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS; 355 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED; 356 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP; 357 358 /* 359 * Read the default channel from the NIC. This may vary 360 * depending on the country where the NIC was purchased, so 361 * we can't hard-code a default and expect it to work for 362 * everyone. 363 */ 364 gen.wi_type = WI_RID_OWN_CHNL; 365 gen.wi_len = 2; 366 wi_read_record(sc, &gen); 367 sc->wi_channel = gen.wi_val; 368 369 /* 370 * Find out if we support WEP on this card. 371 */ 372 gen.wi_type = WI_RID_WEP_AVAIL; 373 gen.wi_len = 2; 374 wi_read_record(sc, &gen); 375 sc->wi_has_wep = gen.wi_val; 376 377 if (bootverbose) { 378 device_printf(sc->dev, 379 __FUNCTION__ ":wi_has_wep = %d\n", 380 sc->wi_has_wep); 381 } 382 383 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 384 385 wi_init(sc); 386 wi_stop(sc); 387 388 /* 389 * Call MI attach routine. 390 */ 391 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 392 callout_handle_init(&sc->wi_stat_ch); 393 WI_UNLOCK(sc); 394 395 return(0); 396} 397 398static void wi_rxeof(sc) 399 struct wi_softc *sc; 400{ 401 struct ifnet *ifp; 402 struct ether_header *eh; 403 struct wi_frame rx_frame; 404 struct mbuf *m; 405 int id; 406 407 ifp = &sc->arpcom.ac_if; 408 409 id = CSR_READ_2(sc, WI_RX_FID); 410 411 /* First read in the frame header */ 412 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) { 413 ifp->if_ierrors++; 414 return; 415 } 416 417 if (rx_frame.wi_status & WI_STAT_ERRSTAT) { 418 ifp->if_ierrors++; 419 return; 420 } 421 422 MGETHDR(m, M_DONTWAIT, MT_DATA); 423 if (m == NULL) { 424 ifp->if_ierrors++; 425 return; 426 } 427 MCLGET(m, M_DONTWAIT); 428 if (!(m->m_flags & M_EXT)) { 429 m_freem(m); 430 ifp->if_ierrors++; 431 return; 432 } 433 434 eh = mtod(m, struct ether_header *); 435 m->m_pkthdr.rcvif = ifp; 436 437 if (rx_frame.wi_status == WI_STAT_1042 || 438 rx_frame.wi_status == WI_STAT_TUNNEL || 439 rx_frame.wi_status == WI_STAT_WMP_MSG) { 440 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { 441 device_printf(sc->dev, "oversized packet received " 442 "(wi_dat_len=%d, wi_status=0x%x)\n", 443 rx_frame.wi_dat_len, rx_frame.wi_status); 444 m_freem(m); 445 ifp->if_ierrors++; 446 return; 447 } 448 m->m_pkthdr.len = m->m_len = 449 rx_frame.wi_dat_len + WI_SNAPHDR_LEN; 450 451 bcopy((char *)&rx_frame.wi_addr1, 452 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 453 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) { 454 bcopy((char *)&rx_frame.wi_addr2, 455 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 456 } else { 457 bcopy((char *)&rx_frame.wi_addr3, 458 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 459 } 460 bcopy((char *)&rx_frame.wi_type, 461 (char *)&eh->ether_type, sizeof(u_int16_t)); 462 463 if (wi_read_data(sc, id, WI_802_11_OFFSET, 464 mtod(m, caddr_t) + sizeof(struct ether_header), 465 m->m_len + 2)) { 466 m_freem(m); 467 ifp->if_ierrors++; 468 return; 469 } 470 } else { 471 if((rx_frame.wi_dat_len + 472 sizeof(struct ether_header)) > MCLBYTES) { 473 device_printf(sc->dev, "oversized packet received " 474 "(wi_dat_len=%d, wi_status=0x%x)\n", 475 rx_frame.wi_dat_len, rx_frame.wi_status); 476 m_freem(m); 477 ifp->if_ierrors++; 478 return; 479 } 480 m->m_pkthdr.len = m->m_len = 481 rx_frame.wi_dat_len + sizeof(struct ether_header); 482 483 if (wi_read_data(sc, id, WI_802_3_OFFSET, 484 mtod(m, caddr_t), m->m_len + 2)) { 485 m_freem(m); 486 ifp->if_ierrors++; 487 return; 488 } 489 } 490 491 ifp->if_ipackets++; 492 493 /* Receive packet. */ 494 m_adj(m, sizeof(struct ether_header)); 495#ifdef WICACHE 496 wi_cache_store(sc, eh, m, rx_frame.wi_q_info); 497#endif 498 ether_input(ifp, eh, m); 499} 500 501static void wi_txeof(sc, status) 502 struct wi_softc *sc; 503 int status; 504{ 505 struct ifnet *ifp; 506 507 ifp = &sc->arpcom.ac_if; 508 509 ifp->if_timer = 0; 510 ifp->if_flags &= ~IFF_OACTIVE; 511 512 if (status & WI_EV_TX_EXC) 513 ifp->if_oerrors++; 514 else 515 ifp->if_opackets++; 516 517 return; 518} 519 520void wi_inquire(xsc) 521 void *xsc; 522{ 523 struct wi_softc *sc; 524 struct ifnet *ifp; 525 526 sc = xsc; 527 ifp = &sc->arpcom.ac_if; 528 529 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 530 531 /* Don't do this while we're transmitting */ 532 if (ifp->if_flags & IFF_OACTIVE) 533 return; 534 535 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS); 536 537 return; 538} 539 540void wi_update_stats(sc) 541 struct wi_softc *sc; 542{ 543 struct wi_ltv_gen gen; 544 u_int16_t id; 545 struct ifnet *ifp; 546 u_int32_t *ptr; 547 int i; 548 u_int16_t t; 549 550 ifp = &sc->arpcom.ac_if; 551 552 id = CSR_READ_2(sc, WI_INFO_FID); 553 554 wi_read_data(sc, id, 0, (char *)&gen, 4); 555 556 if (gen.wi_type != WI_INFO_COUNTERS || 557 gen.wi_len > (sizeof(sc->wi_stats) / 4) + 1) 558 return; 559 560 ptr = (u_int32_t *)&sc->wi_stats; 561 562 for (i = 0; i < gen.wi_len - 1; i++) { 563 t = CSR_READ_2(sc, WI_DATA1); 564#ifdef WI_HERMES_STATS_WAR 565 if (t > 0xF000) 566 t = ~t & 0xFFFF; 567#endif 568 ptr[i] += t; 569 } 570 571 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 572 sc->wi_stats.wi_tx_multi_retries + 573 sc->wi_stats.wi_tx_retry_limit; 574 575 return; 576} 577 578static void wi_intr(xsc) 579 void *xsc; 580{ 581 struct wi_softc *sc = xsc; 582 struct ifnet *ifp; 583 u_int16_t status; 584 585 WI_LOCK(sc); 586 587 ifp = &sc->arpcom.ac_if; 588 589 if (!(ifp->if_flags & IFF_UP)) { 590 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 591 CSR_WRITE_2(sc, WI_INT_EN, 0); 592 WI_UNLOCK(sc); 593 return; 594 } 595 596 /* Disable interrupts. */ 597 CSR_WRITE_2(sc, WI_INT_EN, 0); 598 599 status = CSR_READ_2(sc, WI_EVENT_STAT); 600 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS); 601 602 if (status & WI_EV_RX) { 603 wi_rxeof(sc); 604 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); 605 } 606 607 if (status & WI_EV_TX) { 608 wi_txeof(sc, status); 609 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX); 610 } 611 612 if (status & WI_EV_ALLOC) { 613 int id; 614 id = CSR_READ_2(sc, WI_ALLOC_FID); 615 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 616 if (id == sc->wi_tx_data_id) 617 wi_txeof(sc, status); 618 } 619 620 if (status & WI_EV_INFO) { 621 wi_update_stats(sc); 622 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); 623 } 624 625 if (status & WI_EV_TX_EXC) { 626 wi_txeof(sc, status); 627 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC); 628 } 629 630 if (status & WI_EV_INFO_DROP) { 631 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP); 632 } 633 634 /* Re-enable interrupts. */ 635 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 636 637 if (ifp->if_snd.ifq_head != NULL) 638 wi_start(ifp); 639 640 WI_UNLOCK(sc); 641 642 return; 643} 644 645static int wi_cmd(sc, cmd, val) 646 struct wi_softc *sc; 647 int cmd; 648 int val; 649{ 650 int i, s = 0; 651 652 /* wait for the busy bit to clear */ 653 for (i = 0; i < WI_TIMEOUT; i++) { 654 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) { 655 break; 656 } 657 DELAY(10*1000); /* 10 m sec */ 658 } 659 660 if (i == WI_TIMEOUT) { 661 return(ETIMEDOUT); 662 } 663 664 CSR_WRITE_2(sc, WI_PARAM0, val); 665 CSR_WRITE_2(sc, WI_PARAM1, 0); 666 CSR_WRITE_2(sc, WI_PARAM2, 0); 667 CSR_WRITE_2(sc, WI_COMMAND, cmd); 668 669 for (i = 0; i < WI_TIMEOUT; i++) { 670 /* 671 * Wait for 'command complete' bit to be 672 * set in the event status register. 673 */ 674 s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD; 675 if (s) { 676 /* Ack the event and read result code. */ 677 s = CSR_READ_2(sc, WI_STATUS); 678 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 679#ifdef foo 680 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK)) 681 return(EIO); 682#endif 683 if (s & WI_STAT_CMD_RESULT) 684 return(EIO); 685 break; 686 } 687 } 688 689 if (i == WI_TIMEOUT) 690 return(ETIMEDOUT); 691 692 return(0); 693} 694 695static void wi_reset(sc) 696 struct wi_softc *sc; 697{ 698#ifdef foo 699 wi_cmd(sc, WI_CMD_INI, 0); 700 DELAY(100000); 701 wi_cmd(sc, WI_CMD_INI, 0); 702#endif 703 DELAY(100000); 704 if (wi_cmd(sc, WI_CMD_INI, 0)) 705 device_printf(sc->dev, "init failed\n"); 706 CSR_WRITE_2(sc, WI_INT_EN, 0); 707 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 708 709 /* Calibrate timer. */ 710 WI_SETVAL(WI_RID_TICK_TIME, 8); 711 712 return; 713} 714 715/* 716 * Read an LTV record from the NIC. 717 */ 718static int wi_read_record(sc, ltv) 719 struct wi_softc *sc; 720 struct wi_ltv_gen *ltv; 721{ 722 u_int16_t *ptr; 723 int i, len, code; 724 struct wi_ltv_gen *oltv, p2ltv; 725 726 oltv = ltv; 727 if (sc->wi_prism2) { 728 switch (ltv->wi_type) { 729 case WI_RID_ENCRYPTION: 730 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 731 p2ltv.wi_len = 2; 732 ltv = &p2ltv; 733 break; 734 case WI_RID_TX_CRYPT_KEY: 735 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 736 p2ltv.wi_len = 2; 737 ltv = &p2ltv; 738 break; 739 } 740 } 741 742 /* Tell the NIC to enter record read mode. */ 743 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type)) 744 return(EIO); 745 746 /* Seek to the record. */ 747 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 748 return(EIO); 749 750 /* 751 * Read the length and record type and make sure they 752 * match what we expect (this verifies that we have enough 753 * room to hold all of the returned data). 754 */ 755 len = CSR_READ_2(sc, WI_DATA1); 756 if (len > ltv->wi_len) 757 return(ENOSPC); 758 code = CSR_READ_2(sc, WI_DATA1); 759 if (code != ltv->wi_type) 760 return(EIO); 761 762 ltv->wi_len = len; 763 ltv->wi_type = code; 764 765 /* Now read the data. */ 766 ptr = <v->wi_val; 767 for (i = 0; i < ltv->wi_len - 1; i++) 768 ptr[i] = CSR_READ_2(sc, WI_DATA1); 769 770 if (sc->wi_prism2) { 771 switch (oltv->wi_type) { 772 case WI_RID_TX_RATE: 773 case WI_RID_CUR_TX_RATE: 774 switch (ltv->wi_val) { 775 case 1: oltv->wi_val = 1; break; 776 case 2: oltv->wi_val = 2; break; 777 case 3: oltv->wi_val = 6; break; 778 case 4: oltv->wi_val = 5; break; 779 case 7: oltv->wi_val = 7; break; 780 case 8: oltv->wi_val = 11; break; 781 case 15: oltv->wi_val = 3; break; 782 default: oltv->wi_val = 0x100 + ltv->wi_val; break; 783 } 784 break; 785 case WI_RID_ENCRYPTION: 786 oltv->wi_len = 2; 787 if (ltv->wi_val & 0x01) 788 oltv->wi_val = 1; 789 else 790 oltv->wi_val = 0; 791 break; 792 case WI_RID_TX_CRYPT_KEY: 793 oltv->wi_len = 2; 794 oltv->wi_val = ltv->wi_val; 795 break; 796 } 797 } 798 799 return(0); 800} 801 802/* 803 * Same as read, except we inject data instead of reading it. 804 */ 805static int wi_write_record(sc, ltv) 806 struct wi_softc *sc; 807 struct wi_ltv_gen *ltv; 808{ 809 u_int16_t *ptr; 810 int i; 811 struct wi_ltv_gen p2ltv; 812 813 if (sc->wi_prism2) { 814 switch (ltv->wi_type) { 815 case WI_RID_TX_RATE: 816 p2ltv.wi_type = WI_RID_TX_RATE; 817 p2ltv.wi_len = 2; 818 switch (ltv->wi_val) { 819 case 1: p2ltv.wi_val = 1; break; 820 case 2: p2ltv.wi_val = 2; break; 821 case 3: p2ltv.wi_val = 15; break; 822 case 5: p2ltv.wi_val = 4; break; 823 case 6: p2ltv.wi_val = 3; break; 824 case 7: p2ltv.wi_val = 7; break; 825 case 11: p2ltv.wi_val = 8; break; 826 default: return EINVAL; 827 } 828 ltv = &p2ltv; 829 break; 830 case WI_RID_ENCRYPTION: 831 p2ltv.wi_type = WI_RID_P2_ENCRYPTION; 832 p2ltv.wi_len = 2; 833 if (ltv->wi_val) 834 p2ltv.wi_val = 0x03; 835 else 836 p2ltv.wi_val = 0x90; 837 ltv = &p2ltv; 838 break; 839 case WI_RID_TX_CRYPT_KEY: 840 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; 841 p2ltv.wi_len = 2; 842 p2ltv.wi_val = ltv->wi_val; 843 ltv = &p2ltv; 844 break; 845 case WI_RID_DEFLT_CRYPT_KEYS: 846 { 847 int error; 848 struct wi_ltv_str ws; 849 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv; 850 for (i = 0; i < 4; i++) { 851 ws.wi_len = 4; 852 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; 853 memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5); 854 ws.wi_str[5] = '\0'; 855 error = wi_write_record(sc, 856 (struct wi_ltv_gen *)&ws); 857 if (error) 858 return error; 859 } 860 return 0; 861 } 862 } 863 } 864 865 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) 866 return(EIO); 867 868 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len); 869 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type); 870 871 ptr = <v->wi_val; 872 for (i = 0; i < ltv->wi_len - 1; i++) 873 CSR_WRITE_2(sc, WI_DATA1, ptr[i]); 874 875 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type)) 876 return(EIO); 877 878 return(0); 879} 880 881static int wi_seek(sc, id, off, chan) 882 struct wi_softc *sc; 883 int id, off, chan; 884{ 885 int i; 886 int selreg, offreg; 887 888 switch (chan) { 889 case WI_BAP0: 890 selreg = WI_SEL0; 891 offreg = WI_OFF0; 892 break; 893 case WI_BAP1: 894 selreg = WI_SEL1; 895 offreg = WI_OFF1; 896 break; 897 default: 898 device_printf(sc->dev, "invalid data path: %x\n", chan); 899 return(EIO); 900 } 901 902 CSR_WRITE_2(sc, selreg, id); 903 CSR_WRITE_2(sc, offreg, off); 904 905 for (i = 0; i < WI_TIMEOUT; i++) { 906 if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR))) 907 break; 908 } 909 910 if (i == WI_TIMEOUT) 911 return(ETIMEDOUT); 912 913 return(0); 914} 915 916static int wi_read_data(sc, id, off, buf, len) 917 struct wi_softc *sc; 918 int id, off; 919 caddr_t buf; 920 int len; 921{ 922 int i; 923 u_int16_t *ptr; 924 925 if (wi_seek(sc, id, off, WI_BAP1)) 926 return(EIO); 927 928 ptr = (u_int16_t *)buf; 929 for (i = 0; i < len / 2; i++) 930 ptr[i] = CSR_READ_2(sc, WI_DATA1); 931 932 return(0); 933} 934 935/* 936 * According to the comments in the HCF Light code, there is a bug in 937 * the Hermes (or possibly in certain Hermes firmware revisions) where 938 * the chip's internal autoincrement counter gets thrown off during 939 * data writes: the autoincrement is missed, causing one data word to 940 * be overwritten and subsequent words to be written to the wrong memory 941 * locations. The end result is that we could end up transmitting bogus 942 * frames without realizing it. The workaround for this is to write a 943 * couple of extra guard words after the end of the transfer, then 944 * attempt to read then back. If we fail to locate the guard words where 945 * we expect them, we preform the transfer over again. 946 */ 947static int wi_write_data(sc, id, off, buf, len) 948 struct wi_softc *sc; 949 int id, off; 950 caddr_t buf; 951 int len; 952{ 953 int i; 954 u_int16_t *ptr; 955#ifdef WI_HERMES_AUTOINC_WAR 956 int retries; 957 958 retries = WI_TIMEOUT >> 4; 959again: 960#endif 961 962 if (wi_seek(sc, id, off, WI_BAP0)) 963 return(EIO); 964 965 ptr = (u_int16_t *)buf; 966 for (i = 0; i < (len / 2); i++) 967 CSR_WRITE_2(sc, WI_DATA0, ptr[i]); 968 969#ifdef WI_HERMES_AUTOINC_WAR 970 CSR_WRITE_2(sc, WI_DATA0, 0x1234); 971 CSR_WRITE_2(sc, WI_DATA0, 0x5678); 972 973 if (wi_seek(sc, id, off + len, WI_BAP0)) 974 return(EIO); 975 976 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || 977 CSR_READ_2(sc, WI_DATA0) != 0x5678) 978 { 979 if (--retries >= 0) 980 goto again; 981 device_printf(sc->dev, "wi_write_data device timeout\n"); 982 return (EIO); 983 } 984#endif 985 986 return(0); 987} 988 989/* 990 * Allocate a region of memory inside the NIC and zero 991 * it out. 992 */ 993static int wi_alloc_nicmem(sc, len, id) 994 struct wi_softc *sc; 995 int len; 996 int *id; 997{ 998 int i; 999 1000 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) { 1001 device_printf(sc->dev, "failed to allocate %d bytes on NIC\n", len); 1002 return(ENOMEM); 1003 } 1004 1005 for (i = 0; i < WI_TIMEOUT; i++) { 1006 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 1007 break; 1008 } 1009 1010 if (i == WI_TIMEOUT) 1011 return(ETIMEDOUT); 1012 1013 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); 1014 *id = CSR_READ_2(sc, WI_ALLOC_FID); 1015 1016 if (wi_seek(sc, *id, 0, WI_BAP0)) 1017 return(EIO); 1018 1019 for (i = 0; i < len / 2; i++) 1020 CSR_WRITE_2(sc, WI_DATA0, 0); 1021 1022 return(0); 1023} 1024 1025static void wi_setmulti(sc) 1026 struct wi_softc *sc; 1027{ 1028 struct ifnet *ifp; 1029 int i = 0; 1030 struct ifmultiaddr *ifma; 1031 struct wi_ltv_mcast mcast; 1032 1033 ifp = &sc->arpcom.ac_if; 1034 1035 bzero((char *)&mcast, sizeof(mcast)); 1036 1037 mcast.wi_type = WI_RID_MCAST; 1038 mcast.wi_len = (3 * 16) + 1; 1039 1040 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 1041 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1042 return; 1043 } 1044 1045 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1046 if (ifma->ifma_addr->sa_family != AF_LINK) 1047 continue; 1048 if (i < 16) { 1049 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 1050 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN); 1051 i++; 1052 } else { 1053 bzero((char *)&mcast, sizeof(mcast)); 1054 break; 1055 } 1056 } 1057 1058 mcast.wi_len = (i * 3) + 1; 1059 wi_write_record(sc, (struct wi_ltv_gen *)&mcast); 1060 1061 return; 1062} 1063 1064static void wi_setdef(sc, wreq) 1065 struct wi_softc *sc; 1066 struct wi_req *wreq; 1067{ 1068 struct sockaddr_dl *sdl; 1069 struct ifaddr *ifa; 1070 struct ifnet *ifp; 1071 1072 ifp = &sc->arpcom.ac_if; 1073 1074 switch(wreq->wi_type) { 1075 case WI_RID_MAC_NODE: 1076 ifa = ifnet_addrs[ifp->if_index - 1]; 1077 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1078 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr, 1079 ETHER_ADDR_LEN); 1080 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); 1081 break; 1082 case WI_RID_PORTTYPE: 1083 sc->wi_ptype = wreq->wi_val[0]; 1084 break; 1085 case WI_RID_TX_RATE: 1086 sc->wi_tx_rate = wreq->wi_val[0]; 1087 break; 1088 case WI_RID_MAX_DATALEN: 1089 sc->wi_max_data_len = wreq->wi_val[0]; 1090 break; 1091 case WI_RID_RTS_THRESH: 1092 sc->wi_rts_thresh = wreq->wi_val[0]; 1093 break; 1094 case WI_RID_SYSTEM_SCALE: 1095 sc->wi_ap_density = wreq->wi_val[0]; 1096 break; 1097 case WI_RID_CREATE_IBSS: 1098 sc->wi_create_ibss = wreq->wi_val[0]; 1099 break; 1100 case WI_RID_OWN_CHNL: 1101 sc->wi_channel = wreq->wi_val[0]; 1102 break; 1103 case WI_RID_NODENAME: 1104 bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); 1105 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30); 1106 break; 1107 case WI_RID_DESIRED_SSID: 1108 bzero(sc->wi_net_name, sizeof(sc->wi_net_name)); 1109 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30); 1110 break; 1111 case WI_RID_OWN_SSID: 1112 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name)); 1113 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30); 1114 break; 1115 case WI_RID_PM_ENABLED: 1116 sc->wi_pm_enabled = wreq->wi_val[0]; 1117 break; 1118 case WI_RID_MAX_SLEEP: 1119 sc->wi_max_sleep = wreq->wi_val[0]; 1120 break; 1121 case WI_RID_ENCRYPTION: 1122 sc->wi_use_wep = wreq->wi_val[0]; 1123 break; 1124 case WI_RID_TX_CRYPT_KEY: 1125 sc->wi_tx_key = wreq->wi_val[0]; 1126 break; 1127 case WI_RID_DEFLT_CRYPT_KEYS: 1128 bcopy((char *)wreq, (char *)&sc->wi_keys, 1129 sizeof(struct wi_ltv_keys)); 1130 break; 1131 default: 1132 break; 1133 } 1134 1135 /* Reinitialize WaveLAN. */ 1136 wi_init(sc); 1137 1138 return; 1139} 1140 1141static int wi_ioctl(ifp, command, data) 1142 struct ifnet *ifp; 1143 u_long command; 1144 caddr_t data; 1145{ 1146 int error = 0; 1147 struct wi_softc *sc; 1148 struct wi_req wreq; 1149 struct ifreq *ifr; 1150 struct proc *p = curproc; 1151 1152 sc = ifp->if_softc; 1153 WI_LOCK(sc); 1154 ifr = (struct ifreq *)data; 1155 1156 if (sc->wi_gone) { 1157 error = ENODEV; 1158 goto out; 1159 } 1160 1161 switch(command) { 1162 case SIOCSIFADDR: 1163 case SIOCGIFADDR: 1164 case SIOCSIFMTU: 1165 error = ether_ioctl(ifp, command, data); 1166 break; 1167 case SIOCSIFFLAGS: 1168 if (ifp->if_flags & IFF_UP) { 1169 if (ifp->if_flags & IFF_RUNNING && 1170 ifp->if_flags & IFF_PROMISC && 1171 !(sc->wi_if_flags & IFF_PROMISC)) { 1172 WI_SETVAL(WI_RID_PROMISC, 1); 1173 } else if (ifp->if_flags & IFF_RUNNING && 1174 !(ifp->if_flags & IFF_PROMISC) && 1175 sc->wi_if_flags & IFF_PROMISC) { 1176 WI_SETVAL(WI_RID_PROMISC, 0); 1177 } else 1178 wi_init(sc); 1179 } else { 1180 if (ifp->if_flags & IFF_RUNNING) { 1181 wi_stop(sc); 1182 } 1183 } 1184 sc->wi_if_flags = ifp->if_flags; 1185 error = 0; 1186 break; 1187 case SIOCADDMULTI: 1188 case SIOCDELMULTI: 1189 wi_setmulti(sc); 1190 error = 0; 1191 break; 1192 case SIOCGWAVELAN: 1193 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1194 if (error) 1195 break; 1196 /* Don't show WEP keys to non-root users. */ 1197 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(p)) 1198 break; 1199 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1200 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1201 sizeof(sc->wi_stats)); 1202 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; 1203 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) { 1204 bcopy((char *)&sc->wi_keys, (char *)&wreq, 1205 sizeof(struct wi_ltv_keys)); 1206 } 1207#ifdef WICACHE 1208 else if (wreq.wi_type == WI_RID_ZERO_CACHE) { 1209 sc->wi_sigitems = sc->wi_nextitem = 0; 1210 } else if (wreq.wi_type == WI_RID_READ_CACHE) { 1211 char *pt = (char *)&wreq.wi_val; 1212 bcopy((char *)&sc->wi_sigitems, 1213 (char *)pt, sizeof(int)); 1214 pt += (sizeof (int)); 1215 wreq.wi_len = sizeof(int) / 2; 1216 bcopy((char *)&sc->wi_sigcache, (char *)pt, 1217 sizeof(struct wi_sigcache) * sc->wi_sigitems); 1218 wreq.wi_len += ((sizeof(struct wi_sigcache) * 1219 sc->wi_sigitems) / 2) + 1; 1220 } 1221#endif 1222 else { 1223 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { 1224 error = EINVAL; 1225 break; 1226 } 1227 } 1228 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1229 break; 1230 case SIOCSWAVELAN: 1231 if ((error = suser(p))) 1232 goto out; 1233 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1234 if (error) 1235 break; 1236 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1237 error = EINVAL; 1238 break; 1239 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) { 1240 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val, 1241 wreq.wi_len); 1242 } else { 1243 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq); 1244 if (!error) 1245 wi_setdef(sc, &wreq); 1246 } 1247 break; 1248 default: 1249 error = EINVAL; 1250 break; 1251 } 1252out: 1253 WI_UNLOCK(sc); 1254 1255 return(error); 1256} 1257 1258static void wi_init(xsc) 1259 void *xsc; 1260{ 1261 struct wi_softc *sc = xsc; 1262 struct ifnet *ifp = &sc->arpcom.ac_if; 1263 struct wi_ltv_macaddr mac; 1264 int id = 0; 1265 1266 WI_LOCK(sc); 1267 1268 if (sc->wi_gone) { 1269 WI_UNLOCK(sc); 1270 return; 1271 } 1272 1273 if (ifp->if_flags & IFF_RUNNING) 1274 wi_stop(sc); 1275 1276 wi_reset(sc); 1277 1278 /* Program max data length. */ 1279 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len); 1280 1281 /* Enable/disable IBSS creation. */ 1282 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss); 1283 1284 /* Set the port type. */ 1285 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype); 1286 1287 /* Program the RTS/CTS threshold. */ 1288 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh); 1289 1290 /* Program the TX rate */ 1291 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate); 1292 1293 /* Access point density */ 1294 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density); 1295 1296 /* Power Management Enabled */ 1297 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled); 1298 1299 /* Power Managment Max Sleep */ 1300 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); 1301 1302 /* Specify the IBSS name */ 1303 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name); 1304 1305 /* Specify the network name */ 1306 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name); 1307 1308 /* Specify the frequency to use */ 1309 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel); 1310 1311 /* Program the nodename. */ 1312 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name); 1313 1314 /* Set our MAC address. */ 1315 mac.wi_len = 4; 1316 mac.wi_type = WI_RID_MAC_NODE; 1317 bcopy((char *)&sc->arpcom.ac_enaddr, 1318 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN); 1319 wi_write_record(sc, (struct wi_ltv_gen *)&mac); 1320 1321 /* Configure WEP. */ 1322 if (sc->wi_has_wep) { 1323 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); 1324 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); 1325 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; 1326 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS; 1327 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys); 1328 } 1329 1330 /* Initialize promisc mode. */ 1331 if (ifp->if_flags & IFF_PROMISC) { 1332 WI_SETVAL(WI_RID_PROMISC, 1); 1333 } else { 1334 WI_SETVAL(WI_RID_PROMISC, 0); 1335 } 1336 1337 /* Set multicast filter. */ 1338 wi_setmulti(sc); 1339 1340 /* Enable desired port */ 1341 wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0); 1342 1343 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id)) 1344 device_printf(sc->dev, "tx buffer allocation failed\n"); 1345 sc->wi_tx_data_id = id; 1346 1347 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id)) 1348 device_printf(sc->dev, "mgmt. buffer allocation failed\n"); 1349 sc->wi_tx_mgmt_id = id; 1350 1351 /* enable interrupts */ 1352 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 1353 1354 ifp->if_flags |= IFF_RUNNING; 1355 ifp->if_flags &= ~IFF_OACTIVE; 1356 1357 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60); 1358 WI_UNLOCK(sc); 1359 1360 return; 1361} 1362 1363static void wi_start(ifp) 1364 struct ifnet *ifp; 1365{ 1366 struct wi_softc *sc; 1367 struct mbuf *m0; 1368 struct wi_frame tx_frame; 1369 struct ether_header *eh; 1370 int id; 1371 1372 sc = ifp->if_softc; 1373 WI_LOCK(sc); 1374 1375 if (sc->wi_gone) { 1376 WI_UNLOCK(sc); 1377 return; 1378 } 1379 1380 if (ifp->if_flags & IFF_OACTIVE) { 1381 WI_UNLOCK(sc); 1382 return; 1383 } 1384 1385 IF_DEQUEUE(&ifp->if_snd, m0); 1386 if (m0 == NULL) { 1387 WI_UNLOCK(sc); 1388 return; 1389 } 1390 1391 bzero((char *)&tx_frame, sizeof(tx_frame)); 1392 id = sc->wi_tx_data_id; 1393 eh = mtod(m0, struct ether_header *); 1394 1395 /* 1396 * Use RFC1042 encoding for IP and ARP datagrams, 1397 * 802.3 for anything else. 1398 */ 1399 if (ntohs(eh->ether_type) > 1518) { 1400 bcopy((char *)&eh->ether_dhost, 1401 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN); 1402 bcopy((char *)&eh->ether_shost, 1403 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN); 1404 bcopy((char *)&eh->ether_dhost, 1405 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN); 1406 bcopy((char *)&eh->ether_shost, 1407 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN); 1408 1409 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN; 1410 tx_frame.wi_frame_ctl = WI_FTYPE_DATA; 1411 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0); 1412 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1); 1413 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1414 tx_frame.wi_type = eh->ether_type; 1415 1416 m_copydata(m0, sizeof(struct ether_header), 1417 m0->m_pkthdr.len - sizeof(struct ether_header), 1418 (caddr_t)&sc->wi_txbuf); 1419 1420 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1421 sizeof(struct wi_frame)); 1422 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf, 1423 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2); 1424 } else { 1425 tx_frame.wi_dat_len = m0->m_pkthdr.len; 1426 1427 eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN); 1428 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf); 1429 1430 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, 1431 sizeof(struct wi_frame)); 1432 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf, 1433 m0->m_pkthdr.len + 2); 1434 } 1435 1436 /* 1437 * If there's a BPF listner, bounce a copy of 1438 * this frame to him. 1439 */ 1440 if (ifp->if_bpf) 1441 bpf_mtap(ifp, m0); 1442 1443 m_freem(m0); 1444 1445 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) 1446 device_printf(sc->dev, "xmit failed\n"); 1447 1448 ifp->if_flags |= IFF_OACTIVE; 1449 1450 /* 1451 * Set a timeout in case the chip goes out to lunch. 1452 */ 1453 ifp->if_timer = 5; 1454 1455 WI_UNLOCK(sc); 1456 return; 1457} 1458 1459static int wi_mgmt_xmit(sc, data, len) 1460 struct wi_softc *sc; 1461 caddr_t data; 1462 int len; 1463{ 1464 struct wi_frame tx_frame; 1465 int id; 1466 struct wi_80211_hdr *hdr; 1467 caddr_t dptr; 1468 1469 if (sc->wi_gone) 1470 return(ENODEV); 1471 1472 hdr = (struct wi_80211_hdr *)data; 1473 dptr = data + sizeof(struct wi_80211_hdr); 1474 1475 bzero((char *)&tx_frame, sizeof(tx_frame)); 1476 id = sc->wi_tx_mgmt_id; 1477 1478 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl, 1479 sizeof(struct wi_80211_hdr)); 1480 1481 tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN; 1482 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN); 1483 1484 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 1485 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 1486 (len - sizeof(struct wi_80211_hdr)) + 2); 1487 1488 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) { 1489 device_printf(sc->dev, "xmit failed\n"); 1490 return(EIO); 1491 } 1492 1493 return(0); 1494} 1495 1496static void wi_stop(sc) 1497 struct wi_softc *sc; 1498{ 1499 struct ifnet *ifp; 1500 1501 WI_LOCK(sc); 1502 1503 if (sc->wi_gone) { 1504 WI_UNLOCK(sc); 1505 return; 1506 } 1507 1508 ifp = &sc->arpcom.ac_if; 1509 1510 /* 1511 * If the card is gone and the memory port isn't mapped, we will 1512 * (hopefully) get 0xffff back from the status read, which is not 1513 * a valid status value. 1514 */ 1515 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) { 1516 CSR_WRITE_2(sc, WI_INT_EN, 0); 1517 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0); 1518 } 1519 1520 untimeout(wi_inquire, sc, sc->wi_stat_ch); 1521 1522 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 1523 1524 WI_UNLOCK(sc); 1525 return; 1526} 1527 1528static void wi_watchdog(ifp) 1529 struct ifnet *ifp; 1530{ 1531 struct wi_softc *sc; 1532 1533 sc = ifp->if_softc; 1534 1535 device_printf(sc->dev,"device timeout\n"); 1536 1537 wi_init(sc); 1538 1539 ifp->if_oerrors++; 1540 1541 return; 1542} 1543 1544static int wi_alloc(dev) 1545 device_t dev; 1546{ 1547 struct wi_softc *sc = device_get_softc(dev); 1548 int rid; 1549 1550 rid = 0; 1551 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 1552 0, ~0, (1 << 6), 1553 rman_make_alignment_flags(1 << 6) | RF_ACTIVE); 1554 if (!sc->iobase) { 1555 device_printf(dev, "No I/O space?!\n"); 1556 return (ENXIO); 1557 } 1558 1559 rid = 0; 1560 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1561 0, ~0, 1, RF_ACTIVE); 1562 if (!sc->irq) { 1563 device_printf(dev, "No irq?!\n"); 1564 return (ENXIO); 1565 } 1566 1567 sc->dev = dev; 1568 sc->wi_unit = device_get_unit(dev); 1569 sc->wi_io_addr = rman_get_start(sc->iobase); 1570 sc->wi_btag = rman_get_bustag(sc->iobase); 1571 sc->wi_bhandle = rman_get_bushandle(sc->iobase); 1572 1573 return (0); 1574} 1575 1576static void wi_free(dev) 1577 device_t dev; 1578{ 1579 struct wi_softc *sc = device_get_softc(dev); 1580 1581 if (sc->iobase != NULL) 1582 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->iobase); 1583 if (sc->irq != NULL) 1584 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); 1585 1586 return; 1587} 1588 1589static void wi_shutdown(dev) 1590 device_t dev; 1591{ 1592 struct wi_softc *sc; 1593 1594 sc = device_get_softc(dev); 1595 wi_stop(sc); 1596 1597 return; 1598} 1599 1600#ifdef WICACHE 1601/* wavelan signal strength cache code. 1602 * store signal/noise/quality on per MAC src basis in 1603 * a small fixed cache. The cache wraps if > MAX slots 1604 * used. The cache may be zeroed out to start over. 1605 * Two simple filters exist to reduce computation: 1606 * 1. ip only (literally 0x800) which may be used 1607 * to ignore some packets. It defaults to ip only. 1608 * it could be used to focus on broadcast, non-IP 802.11 beacons. 1609 * 2. multicast/broadcast only. This may be used to 1610 * ignore unicast packets and only cache signal strength 1611 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 1612 * beacons and not unicast traffic. 1613 * 1614 * The cache stores (MAC src(index), IP src (major clue), signal, 1615 * quality, noise) 1616 * 1617 * No apologies for storing IP src here. It's easy and saves much 1618 * trouble elsewhere. The cache is assumed to be INET dependent, 1619 * although it need not be. 1620 */ 1621 1622#ifdef documentation 1623 1624int wi_sigitems; /* number of cached entries */ 1625struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */ 1626int wi_nextitem; /* index/# of entries */ 1627 1628 1629#endif 1630 1631/* control variables for cache filtering. Basic idea is 1632 * to reduce cost (e.g., to only Mobile-IP agent beacons 1633 * which are broadcast or multicast). Still you might 1634 * want to measure signal strength with unicast ping packets 1635 * on a pt. to pt. ant. setup. 1636 */ 1637/* set true if you want to limit cache items to broadcast/mcast 1638 * only packets (not unicast). Useful for mobile-ip beacons which 1639 * are broadcast/multicast at network layer. Default is all packets 1640 * so ping/unicast will work say with pt. to pt. antennae setup. 1641 */ 1642static int wi_cache_mcastonly = 0; 1643SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW, 1644 &wi_cache_mcastonly, 0, ""); 1645 1646/* set true if you want to limit cache items to IP packets only 1647*/ 1648static int wi_cache_iponly = 1; 1649SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW, 1650 &wi_cache_iponly, 0, ""); 1651 1652/* 1653 * Original comments: 1654 * ----------------- 1655 * wi_cache_store, per rx packet store signal 1656 * strength in MAC (src) indexed cache. 1657 * 1658 * follows linux driver in how signal strength is computed. 1659 * In ad hoc mode, we use the rx_quality field. 1660 * signal and noise are trimmed to fit in the range from 47..138. 1661 * rx_quality field MSB is signal strength. 1662 * rx_quality field LSB is noise. 1663 * "quality" is (signal - noise) as is log value. 1664 * note: quality CAN be negative. 1665 * 1666 * In BSS mode, we use the RID for communication quality. 1667 * TBD: BSS mode is currently untested. 1668 * 1669 * Bill's comments: 1670 * --------------- 1671 * Actually, we use the rx_quality field all the time for both "ad-hoc" 1672 * and BSS modes. Why? Because reading an RID is really, really expensive: 1673 * there's a bunch of PIO operations that have to be done to read a record 1674 * from the NIC, and reading the comms quality RID each time a packet is 1675 * received can really hurt performance. We don't have to do this anyway: 1676 * the comms quality field only reflects the values in the rx_quality field 1677 * anyway. The comms quality RID is only meaningful in infrastructure mode, 1678 * but the values it contains are updated based on the rx_quality from 1679 * frames received from the access point. 1680 * 1681 * Also, according to Lucent, the signal strength and noise level values 1682 * can be converted to dBms by subtracting 149, so I've modified the code 1683 * to do that instead of the scaling it did originally. 1684 */ 1685static 1686void wi_cache_store (struct wi_softc *sc, struct ether_header *eh, 1687 struct mbuf *m, unsigned short rx_quality) 1688{ 1689 struct ip *ip = 0; 1690 int i; 1691 static int cache_slot = 0; /* use this cache entry */ 1692 static int wrapindex = 0; /* next "free" cache entry */ 1693 int sig, noise; 1694 int sawip=0; 1695 1696 /* filters: 1697 * 1. ip only 1698 * 2. configurable filter to throw out unicast packets, 1699 * keep multicast only. 1700 */ 1701 1702 if ((ntohs(eh->ether_type) == 0x800)) { 1703 sawip = 1; 1704 } 1705 1706 /* filter for ip packets only 1707 */ 1708 if (wi_cache_iponly && !sawip) { 1709 return; 1710 } 1711 1712 /* filter for broadcast/multicast only 1713 */ 1714 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 1715 return; 1716 } 1717 1718#ifdef SIGDEBUG 1719 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit, 1720 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 1721#endif 1722 1723 /* find the ip header. we want to store the ip_src 1724 * address. 1725 */ 1726 if (sawip) { 1727 ip = mtod(m, struct ip *); 1728 } 1729 1730 /* do a linear search for a matching MAC address 1731 * in the cache table 1732 * . MAC address is 6 bytes, 1733 * . var w_nextitem holds total number of entries already cached 1734 */ 1735 for(i = 0; i < sc->wi_nextitem; i++) { 1736 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) { 1737 /* Match!, 1738 * so we already have this entry, 1739 * update the data 1740 */ 1741 break; 1742 } 1743 } 1744 1745 /* did we find a matching mac address? 1746 * if yes, then overwrite a previously existing cache entry 1747 */ 1748 if (i < sc->wi_nextitem ) { 1749 cache_slot = i; 1750 } 1751 /* else, have a new address entry,so 1752 * add this new entry, 1753 * if table full, then we need to replace LRU entry 1754 */ 1755 else { 1756 1757 /* check for space in cache table 1758 * note: wi_nextitem also holds number of entries 1759 * added in the cache table 1760 */ 1761 if ( sc->wi_nextitem < MAXWICACHE ) { 1762 cache_slot = sc->wi_nextitem; 1763 sc->wi_nextitem++; 1764 sc->wi_sigitems = sc->wi_nextitem; 1765 } 1766 /* no space found, so simply wrap with wrap index 1767 * and "zap" the next entry 1768 */ 1769 else { 1770 if (wrapindex == MAXWICACHE) { 1771 wrapindex = 0; 1772 } 1773 cache_slot = wrapindex++; 1774 } 1775 } 1776 1777 /* invariant: cache_slot now points at some slot 1778 * in cache. 1779 */ 1780 if (cache_slot < 0 || cache_slot >= MAXWICACHE) { 1781 log(LOG_ERR, "wi_cache_store, bad index: %d of " 1782 "[0..%d], gross cache error\n", 1783 cache_slot, MAXWICACHE); 1784 return; 1785 } 1786 1787 /* store items in cache 1788 * .ip source address 1789 * .mac src 1790 * .signal, etc. 1791 */ 1792 if (sawip) { 1793 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 1794 } 1795 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6); 1796 1797 sig = (rx_quality >> 8) & 0xFF; 1798 noise = rx_quality & 0xFF; 1799 sc->wi_sigcache[cache_slot].signal = sig - 149; 1800 sc->wi_sigcache[cache_slot].noise = noise - 149; 1801 sc->wi_sigcache[cache_slot].quality = sig - noise; 1802 1803 return; 1804} 1805#endif 1806