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