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