if_an.c revision 83270
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/an/if_an.c 83270 2001-09-10 02:36:18Z brooks $ 33 */ 34 35/* 36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI 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 Aironet 4500/4800 series cards some in PCMCIA, ISA and PCI form. 45 * This driver supports all three device types (PCI devices are supported 46 * through an extra PCI shim: /sys/pci/if_an_p.c). ISA devices can be 47 * supported either using hard-coded IO port/IRQ settings or via Plug 48 * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates. 49 * The 4800 devices support 1, 2, 5.5 and 11Mbps rates. 50 * 51 * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially 52 * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA 53 * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are 54 * a couple of important differences though: 55 * 56 * - Lucent doesn't currently offer a PCI card, however Aironet does 57 * - Lucent ISA card looks to the host like a PCMCIA controller with 58 * a PCMCIA WaveLAN card inserted. This means that even desktop 59 * machines need to be configured with PCMCIA support in order to 60 * use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand 61 * actually look like normal ISA and PCI devices to the host, so 62 * no PCMCIA controller support is needed 63 * 64 * The latter point results in a small gotcha. The Aironet PCMCIA 65 * cards can be configured for one of two operating modes depending 66 * on how the Vpp1 and Vpp2 programming voltages are set when the 67 * card is activated. In order to put the card in proper PCMCIA 68 * operation (where the CIS table is visible and the interface is 69 * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be 70 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages, 71 * which leaves the card in ISA/PCI mode, which prevents it from 72 * being activated as an PCMCIA device. Consequently, /sys/pccard/pccard.c 73 * has to be patched slightly in order to enable the Vpp voltages in 74 * order to make the Aironet PCMCIA cards work. 75 * 76 * Note that some PCMCIA controller software packages for Windows NT 77 * fail to set the voltages as well. 78 * 79 * The Aironet devices can operate in both station mode and access point 80 * mode. Typically, when programmed for station mode, the card can be set 81 * to automatically perform encapsulation/decapsulation of Ethernet II 82 * and 802.3 frames within 802.11 frames so that the host doesn't have 83 * to do it itself. This driver doesn't program the card that way: the 84 * driver handles all of the encapsulation/decapsulation itself. 85 */ 86 87#include "opt_inet.h" 88 89#ifdef INET 90#define ANCACHE /* enable signal strength cache */ 91#endif 92 93#include <sys/param.h> 94#include <sys/systm.h> 95#include <sys/sockio.h> 96#include <sys/mbuf.h> 97#include <sys/kernel.h> 98#include <sys/socket.h> 99#ifdef ANCACHE 100#include <sys/syslog.h> 101#include <sys/sysctl.h> 102#endif 103 104#include <sys/module.h> 105#include <sys/sysctl.h> 106#include <sys/bus.h> 107#include <machine/bus.h> 108#include <sys/rman.h> 109#include <sys/mutex.h> 110#include <machine/resource.h> 111 112#include <net/if.h> 113#include <net/if_arp.h> 114#include <net/ethernet.h> 115#include <net/if_dl.h> 116#include <net/if_types.h> 117#include <net/if_ieee80211.h> 118#include <net/if_media.h> 119 120#ifdef INET 121#include <netinet/in.h> 122#include <netinet/in_systm.h> 123#include <netinet/in_var.h> 124#include <netinet/ip.h> 125#endif 126 127#include <net/bpf.h> 128 129#include <machine/md_var.h> 130 131#include <dev/an/if_aironet_ieee.h> 132#include <dev/an/if_anreg.h> 133 134#if !defined(lint) 135static const char rcsid[] = 136 "$FreeBSD: head/sys/dev/an/if_an.c 83270 2001-09-10 02:36:18Z brooks $"; 137#endif 138 139/* These are global because we need them in sys/pci/if_an_p.c. */ 140static void an_reset __P((struct an_softc *)); 141static int an_ioctl __P((struct ifnet *, u_long, caddr_t)); 142static void an_init __P((void *)); 143static int an_init_tx_ring __P((struct an_softc *)); 144static void an_start __P((struct ifnet *)); 145static void an_watchdog __P((struct ifnet *)); 146static void an_rxeof __P((struct an_softc *)); 147static void an_txeof __P((struct an_softc *, int)); 148 149static void an_promisc __P((struct an_softc *, int)); 150static int an_cmd __P((struct an_softc *, int, int)); 151static int an_read_record __P((struct an_softc *, struct an_ltv_gen *)); 152static int an_write_record __P((struct an_softc *, struct an_ltv_gen *)); 153static int an_read_data __P((struct an_softc *, int, 154 int, caddr_t, int)); 155static int an_write_data __P((struct an_softc *, int, 156 int, caddr_t, int)); 157static int an_seek __P((struct an_softc *, int, int, int)); 158static int an_alloc_nicmem __P((struct an_softc *, int, int *)); 159static void an_stats_update __P((void *)); 160static void an_setdef __P((struct an_softc *, struct an_req *)); 161#ifdef ANCACHE 162static void an_cache_store __P((struct an_softc *, struct ether_header *, 163 struct mbuf *, unsigned short)); 164#endif 165 166static void an_dump_record __P((struct an_softc *,struct an_ltv_gen *, 167 char *)); 168 169static int an_media_change __P((struct ifnet *)); 170static void an_media_status __P((struct ifnet *, struct ifmediareq *)); 171 172static int an_dump = 0; 173static char an_conf[256]; 174 175/* sysctl vars */ 176SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID"); 177 178static int 179sysctl_an_dump(SYSCTL_HANDLER_ARGS) 180{ 181 int error, r, last; 182 char *s = an_conf; 183 184 last = an_dump; 185 bzero(an_conf, sizeof(an_conf)); 186 187 switch (an_dump) { 188 case 0: 189 strcat(an_conf, "off"); 190 break; 191 case 1: 192 strcat(an_conf, "type"); 193 break; 194 case 2: 195 strcat(an_conf, "dump"); 196 break; 197 default: 198 snprintf(an_conf, 5, "%x", an_dump); 199 break; 200 } 201 202 error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req); 203 204 if (strncmp(an_conf,"off", 4) == 0) { 205 an_dump = 0; 206 } 207 if (strncmp(an_conf,"dump", 4) == 0) { 208 an_dump = 1; 209 } 210 if (strncmp(an_conf,"type", 4) == 0) { 211 an_dump = 2; 212 } 213 if (*s == 'f') { 214 r = 0; 215 for (;;s++) { 216 if ((*s >= '0') && (*s <= '9')) { 217 r = r * 16 + (*s - '0'); 218 } else if ((*s >= 'a') && (*s <= 'f')) { 219 r = r * 16 + (*s - 'a' + 10); 220 } else { 221 break; 222 } 223 } 224 an_dump = r; 225 } 226 if (an_dump != last) 227 printf("Sysctl changed for Aironet driver\n"); 228 229 return error; 230} 231 232SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, 233 0, sizeof(an_conf), sysctl_an_dump, "A", ""); 234 235/* 236 * We probe for an Aironet 4500/4800 card by attempting to 237 * read the default SSID list. On reset, the first entry in 238 * the SSID list will contain the name "tsunami." If we don't 239 * find this, then there's no card present. 240 */ 241int 242an_probe(dev) 243 device_t dev; 244{ 245 struct an_softc *sc = device_get_softc(dev); 246 struct an_ltv_ssidlist ssid; 247 int error; 248 249 bzero((char *)&ssid, sizeof(ssid)); 250 251 error = an_alloc_port(dev, 0, AN_IOSIZ); 252 if (error != 0) 253 return (0); 254 255 /* can't do autoprobing */ 256 if (rman_get_start(sc->port_res) == -1) 257 return(0); 258 259 /* 260 * We need to fake up a softc structure long enough 261 * to be able to issue commands and call some of the 262 * other routines. 263 */ 264 sc->an_bhandle = rman_get_bushandle(sc->port_res); 265 sc->an_btag = rman_get_bustag(sc->port_res); 266 sc->an_unit = device_get_unit(dev); 267 268 ssid.an_len = sizeof(ssid); 269 ssid.an_type = AN_RID_SSIDLIST; 270 271 /* Make sure interrupts are disabled. */ 272 CSR_WRITE_2(sc, AN_INT_EN, 0); 273 CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF); 274 275 an_reset(sc); 276 277 if (an_cmd(sc, AN_CMD_READCFG, 0)) 278 return(0); 279 280 if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) 281 return(0); 282 283 /* See if the ssid matches what we expect ... but doesn't have to */ 284 if (strcmp(ssid.an_ssid1, AN_DEF_SSID)) 285 return(0); 286 287 return(AN_IOSIZ); 288} 289 290/* 291 * Allocate a port resource with the given resource id. 292 */ 293int 294an_alloc_port(dev, rid, size) 295 device_t dev; 296 int rid; 297 int size; 298{ 299 struct an_softc *sc = device_get_softc(dev); 300 struct resource *res; 301 302 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 303 0ul, ~0ul, size, RF_ACTIVE); 304 if (res) { 305 sc->port_rid = rid; 306 sc->port_res = res; 307 return (0); 308 } else { 309 return (ENOENT); 310 } 311} 312 313/* 314 * Allocate an irq resource with the given resource id. 315 */ 316int 317an_alloc_irq(dev, rid, flags) 318 device_t dev; 319 int rid; 320 int flags; 321{ 322 struct an_softc *sc = device_get_softc(dev); 323 struct resource *res; 324 325 res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 326 0ul, ~0ul, 1, (RF_ACTIVE | flags)); 327 if (res) { 328 sc->irq_rid = rid; 329 sc->irq_res = res; 330 return (0); 331 } else { 332 return (ENOENT); 333 } 334} 335 336/* 337 * Release all resources 338 */ 339void 340an_release_resources(dev) 341 device_t dev; 342{ 343 struct an_softc *sc = device_get_softc(dev); 344 345 if (sc->port_res) { 346 bus_release_resource(dev, SYS_RES_IOPORT, 347 sc->port_rid, sc->port_res); 348 sc->port_res = 0; 349 } 350 if (sc->irq_res) { 351 bus_release_resource(dev, SYS_RES_IRQ, 352 sc->irq_rid, sc->irq_res); 353 sc->irq_res = 0; 354 } 355} 356 357int 358an_attach(sc, unit, flags) 359 struct an_softc *sc; 360 int unit; 361 int flags; 362{ 363 struct ifnet *ifp = &sc->arpcom.ac_if; 364 365 mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_DEF | 366 MTX_RECURSE); 367 AN_LOCK(sc); 368 369 sc->an_gone = 0; 370 sc->an_associated = 0; 371 sc->an_monitor = 0; 372 sc->an_was_monitor = 0; 373 374 /* Reset the NIC. */ 375 an_reset(sc); 376 377 /* Load factory config */ 378 if (an_cmd(sc, AN_CMD_READCFG, 0)) { 379 printf("an%d: failed to load config data\n", sc->an_unit); 380 AN_UNLOCK(sc); 381 mtx_destroy(&sc->an_mtx); 382 return(EIO); 383 } 384 385 /* Read the current configuration */ 386 sc->an_config.an_type = AN_RID_GENCONFIG; 387 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 388 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 389 printf("an%d: read record failed\n", sc->an_unit); 390 AN_UNLOCK(sc); 391 mtx_destroy(&sc->an_mtx); 392 return(EIO); 393 } 394 395 /* Read the card capabilities */ 396 sc->an_caps.an_type = AN_RID_CAPABILITIES; 397 sc->an_caps.an_len = sizeof(struct an_ltv_caps); 398 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) { 399 printf("an%d: read record failed\n", sc->an_unit); 400 AN_UNLOCK(sc); 401 mtx_destroy(&sc->an_mtx); 402 return(EIO); 403 } 404 405 /* Read ssid list */ 406 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 407 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist); 408 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 409 printf("an%d: read record failed\n", sc->an_unit); 410 AN_UNLOCK(sc); 411 mtx_destroy(&sc->an_mtx); 412 return(EIO); 413 } 414 415 /* Read AP list */ 416 sc->an_aplist.an_type = AN_RID_APLIST; 417 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 418 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 419 printf("an%d: read record failed\n", sc->an_unit); 420 AN_UNLOCK(sc); 421 mtx_destroy(&sc->an_mtx); 422 return(EIO); 423 } 424 425 bcopy((char *)&sc->an_caps.an_oemaddr, 426 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 427 428 printf("an%d: Ethernet address: %6D\n", sc->an_unit, 429 sc->arpcom.ac_enaddr, ":"); 430 431 ifp->if_softc = sc; 432 ifp->if_unit = sc->an_unit = unit; 433 ifp->if_name = "an"; 434 ifp->if_mtu = ETHERMTU; 435 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 436 ifp->if_ioctl = an_ioctl; 437 ifp->if_output = ether_output; 438 ifp->if_start = an_start; 439 ifp->if_watchdog = an_watchdog; 440 ifp->if_init = an_init; 441 ifp->if_baudrate = 10000000; 442 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 443 444 bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename)); 445 bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename, 446 sizeof(AN_DEFAULT_NODENAME) - 1); 447 448 bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1)); 449 bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1, 450 sizeof(AN_DEFAULT_NETNAME) - 1); 451 sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME); 452 453 sc->an_config.an_opmode = 454 AN_OPMODE_INFRASTRUCTURE_STATION; 455 456 sc->an_tx_rate = 0; 457 bzero((char *)&sc->an_stats, sizeof(sc->an_stats)); 458 459 ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status); 460#define ADD(m, c) ifmedia_add(&sc->an_ifmedia, (m), (c), NULL) 461 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 462 IFM_IEEE80211_ADHOC, 0), 0); 463 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 464 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 465 IFM_IEEE80211_ADHOC, 0), 0); 466 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 467 if (sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) { 468 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 469 IFM_IEEE80211_ADHOC, 0), 0); 470 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 471 } 472 if (sc->an_caps.an_rates[3] == AN_RATE_11MBPS) { 473 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 474 IFM_IEEE80211_ADHOC, 0), 0); 475 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 476 } 477 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 478 IFM_IEEE80211_ADHOC, 0), 0); 479 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 480#undef ADD 481 ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 482 0, 0)); 483 484 /* 485 * Call MI attach routine. 486 */ 487 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 488 callout_handle_init(&sc->an_stat_ch); 489 AN_UNLOCK(sc); 490 491 return(0); 492} 493 494static void 495an_rxeof(sc) 496 struct an_softc *sc; 497{ 498 struct ifnet *ifp; 499 struct ether_header *eh; 500 struct ieee80211_frame *ih; 501 struct an_rxframe rx_frame; 502 struct an_rxframe_802_3 rx_frame_802_3; 503 struct mbuf *m; 504 int len, id, error = 0; 505 int ieee80211_header_len; 506 u_char *bpf_buf; 507 u_short fc1; 508 509 ifp = &sc->arpcom.ac_if; 510 511 id = CSR_READ_2(sc, AN_RX_FID); 512 513 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 514 /* read raw 802.11 packet */ 515 bpf_buf = sc->buf_802_11; 516 517 /* read header */ 518 if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame, 519 sizeof(rx_frame))) { 520 ifp->if_ierrors++; 521 return; 522 } 523 524 /* 525 * skip beacon by default since this increases the 526 * system load a lot 527 */ 528 529 if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) && 530 (rx_frame.an_frame_ctl & IEEE80211_FC0_SUBTYPE_BEACON)) { 531 return; 532 } 533 534 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 535 len = rx_frame.an_rx_payload_len 536 + sizeof(rx_frame); 537 /* Check for insane frame length */ 538 if (len > sizeof(sc->buf_802_11)) { 539 printf("an%d: oversized packet received (%d, %d)\n", 540 sc->an_unit, len, MCLBYTES); 541 ifp->if_ierrors++; 542 return; 543 } 544 545 bcopy((char *)&rx_frame, 546 bpf_buf, sizeof(rx_frame)); 547 548 error = an_read_data(sc, id, sizeof(rx_frame), 549 (caddr_t)bpf_buf+sizeof(rx_frame), 550 rx_frame.an_rx_payload_len); 551 } else { 552 fc1=rx_frame.an_frame_ctl >> 8; 553 ieee80211_header_len = sizeof(struct ieee80211_frame); 554 if ((fc1 & IEEE80211_FC1_DIR_TODS) && 555 (fc1 & IEEE80211_FC1_DIR_FROMDS)) { 556 ieee80211_header_len += ETHER_ADDR_LEN; 557 } 558 559 len = rx_frame.an_rx_payload_len 560 + ieee80211_header_len; 561 /* Check for insane frame length */ 562 if (len > sizeof(sc->buf_802_11)) { 563 printf("an%d: oversized packet received (%d, %d)\n", 564 sc->an_unit, len, MCLBYTES); 565 ifp->if_ierrors++; 566 return; 567 } 568 569 ih = (struct ieee80211_frame *)bpf_buf; 570 571 bcopy((char *)&rx_frame.an_frame_ctl, 572 (char *)ih, ieee80211_header_len); 573 574 error = an_read_data(sc, id, sizeof(rx_frame) + 575 rx_frame.an_gaplen, 576 (caddr_t)ih +ieee80211_header_len, 577 rx_frame.an_rx_payload_len); 578 } 579 /* dump raw 802.11 packet to bpf and skip ip stack */ 580 if (ifp->if_bpf != NULL) { 581 bpf_tap(ifp, bpf_buf, len); 582 } 583 } else { 584 MGETHDR(m, M_DONTWAIT, MT_DATA); 585 if (m == NULL) { 586 ifp->if_ierrors++; 587 return; 588 } 589 MCLGET(m, M_DONTWAIT); 590 if (!(m->m_flags & M_EXT)) { 591 m_freem(m); 592 ifp->if_ierrors++; 593 return; 594 } 595 m->m_pkthdr.rcvif = ifp; 596 /* Read Ethenet encapsulated packet */ 597 598#ifdef ANCACHE 599 /* Read NIC frame header */ 600 if (an_read_data(sc, id, 0, (caddr_t) & rx_frame, sizeof(rx_frame))) { 601 ifp->if_ierrors++; 602 return; 603 } 604#endif 605 /* Read in the 802_3 frame header */ 606 if (an_read_data(sc, id, 0x34, (caddr_t) & rx_frame_802_3, 607 sizeof(rx_frame_802_3))) { 608 ifp->if_ierrors++; 609 return; 610 } 611 if (rx_frame_802_3.an_rx_802_3_status != 0) { 612 ifp->if_ierrors++; 613 return; 614 } 615 /* Check for insane frame length */ 616 if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) { 617 ifp->if_ierrors++; 618 return; 619 } 620 m->m_pkthdr.len = m->m_len = 621 rx_frame_802_3.an_rx_802_3_payload_len + 12; 622 623 eh = mtod(m, struct ether_header *); 624 625 bcopy((char *)&rx_frame_802_3.an_rx_dst_addr, 626 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 627 bcopy((char *)&rx_frame_802_3.an_rx_src_addr, 628 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 629 630 /* in mbuf header type is just before payload */ 631 error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type), 632 rx_frame_802_3.an_rx_802_3_payload_len); 633 634 if (error) { 635 m_freem(m); 636 ifp->if_ierrors++; 637 return; 638 } 639 ifp->if_ipackets++; 640 641 /* Receive packet. */ 642 m_adj(m, sizeof(struct ether_header)); 643#ifdef ANCACHE 644 an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength); 645#endif 646 ether_input(ifp, eh, m); 647 } 648} 649 650static void 651an_txeof(sc, status) 652 struct an_softc *sc; 653 int status; 654{ 655 struct ifnet *ifp; 656 int id, i; 657 658 ifp = &sc->arpcom.ac_if; 659 660 ifp->if_timer = 0; 661 ifp->if_flags &= ~IFF_OACTIVE; 662 663 id = CSR_READ_2(sc, AN_TX_CMP_FID); 664 665 if (status & AN_EV_TX_EXC) { 666 ifp->if_oerrors++; 667 } else 668 ifp->if_opackets++; 669 670 for (i = 0; i < AN_TX_RING_CNT; i++) { 671 if (id == sc->an_rdata.an_tx_ring[i]) { 672 sc->an_rdata.an_tx_ring[i] = 0; 673 break; 674 } 675 } 676 677 AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT); 678 679 return; 680} 681 682/* 683 * We abuse the stats updater to check the current NIC status. This 684 * is important because we don't want to allow transmissions until 685 * the NIC has synchronized to the current cell (either as the master 686 * in an ad-hoc group, or as a station connected to an access point). 687 */ 688void 689an_stats_update(xsc) 690 void *xsc; 691{ 692 struct an_softc *sc; 693 struct ifnet *ifp; 694 695 sc = xsc; 696 AN_LOCK(sc); 697 ifp = &sc->arpcom.ac_if; 698 699 sc->an_status.an_type = AN_RID_STATUS; 700 sc->an_status.an_len = sizeof(struct an_ltv_status); 701 an_read_record(sc, (struct an_ltv_gen *)&sc->an_status); 702 703 if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC) 704 sc->an_associated = 1; 705 else 706 sc->an_associated = 0; 707 708 /* Don't do this while we're transmitting */ 709 if (ifp->if_flags & IFF_OACTIVE) { 710 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 711 AN_UNLOCK(sc); 712 return; 713 } 714 715 sc->an_stats.an_len = sizeof(struct an_ltv_stats); 716 sc->an_stats.an_type = AN_RID_32BITS_CUM; 717 an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len); 718 719 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 720 AN_UNLOCK(sc); 721 722 return; 723} 724 725void 726an_intr(xsc) 727 void *xsc; 728{ 729 struct an_softc *sc; 730 struct ifnet *ifp; 731 u_int16_t status; 732 733 sc = (struct an_softc*)xsc; 734 735 AN_LOCK(sc); 736 737 if (sc->an_gone) { 738 AN_UNLOCK(sc); 739 return; 740 } 741 742 ifp = &sc->arpcom.ac_if; 743 744 /* Disable interrupts. */ 745 CSR_WRITE_2(sc, AN_INT_EN, 0); 746 747 status = CSR_READ_2(sc, AN_EVENT_STAT); 748 CSR_WRITE_2(sc, AN_EVENT_ACK, ~AN_INTRS); 749 750 if (status & AN_EV_AWAKE) { 751 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_AWAKE); 752 } 753 754 if (status & AN_EV_LINKSTAT) { 755 if (CSR_READ_2(sc, AN_LINKSTAT) == AN_LINKSTAT_ASSOCIATED) 756 sc->an_associated = 1; 757 else 758 sc->an_associated = 0; 759 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT); 760 } 761 762 if (status & AN_EV_RX) { 763 an_rxeof(sc); 764 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 765 } 766 767 if (status & AN_EV_TX) { 768 an_txeof(sc, status); 769 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX); 770 } 771 772 if (status & AN_EV_TX_EXC) { 773 an_txeof(sc, status); 774 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX_EXC); 775 } 776 777 if (status & AN_EV_ALLOC) 778 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 779 780 /* Re-enable interrupts. */ 781 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 782 783 if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL)) 784 an_start(ifp); 785 786 AN_UNLOCK(sc); 787 788 return; 789} 790 791static int 792an_cmd(sc, cmd, val) 793 struct an_softc *sc; 794 int cmd; 795 int val; 796{ 797 int i, s = 0; 798 799 CSR_WRITE_2(sc, AN_PARAM0, val); 800 CSR_WRITE_2(sc, AN_PARAM1, 0); 801 CSR_WRITE_2(sc, AN_PARAM2, 0); 802 CSR_WRITE_2(sc, AN_COMMAND, cmd); 803 804 for (i = 0; i < AN_TIMEOUT; i++) { 805 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD) 806 break; 807 else { 808 if (CSR_READ_2(sc, AN_COMMAND) == cmd) 809 CSR_WRITE_2(sc, AN_COMMAND, cmd); 810 } 811 } 812 813 for (i = 0; i < AN_TIMEOUT; i++) { 814 CSR_READ_2(sc, AN_RESP0); 815 CSR_READ_2(sc, AN_RESP1); 816 CSR_READ_2(sc, AN_RESP2); 817 s = CSR_READ_2(sc, AN_STATUS); 818 if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE)) 819 break; 820 } 821 822 /* Ack the command */ 823 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD); 824 825 if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) 826 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY); 827 828 if (i == AN_TIMEOUT) 829 return(ETIMEDOUT); 830 831 return(0); 832} 833 834/* 835 * This reset sequence may look a little strange, but this is the 836 * most reliable method I've found to really kick the NIC in the 837 * head and force it to reboot correctly. 838 */ 839static void 840an_reset(sc) 841 struct an_softc *sc; 842{ 843 if (sc->an_gone) 844 return; 845 846 an_cmd(sc, AN_CMD_ENABLE, 0); 847 an_cmd(sc, AN_CMD_FW_RESTART, 0); 848 an_cmd(sc, AN_CMD_NOOP2, 0); 849 850 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) 851 printf("an%d: reset failed\n", sc->an_unit); 852 853 an_cmd(sc, AN_CMD_DISABLE, 0); 854 855 return; 856} 857 858/* 859 * Read an LTV record from the NIC. 860 */ 861static int 862an_read_record(sc, ltv) 863 struct an_softc *sc; 864 struct an_ltv_gen *ltv; 865{ 866 u_int16_t *ptr; 867 u_int8_t *ptr2; 868 int i, len; 869 870 if (ltv->an_len < 4 || ltv->an_type == 0) 871 return(EINVAL); 872 873 /* Tell the NIC to enter record read mode. */ 874 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) { 875 printf("an%d: RID access failed\n", sc->an_unit); 876 return(EIO); 877 } 878 879 /* Seek to the record. */ 880 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) { 881 printf("an%d: seek to record failed\n", sc->an_unit); 882 return(EIO); 883 } 884 885 /* 886 * Read the length and record type and make sure they 887 * match what we expect (this verifies that we have enough 888 * room to hold all of the returned data). 889 * Length includes type but not length. 890 */ 891 len = CSR_READ_2(sc, AN_DATA1); 892 if (len > (ltv->an_len - 2)) { 893 printf("an%d: record length mismatch -- expected %d, " 894 "got %d for Rid %x\n", sc->an_unit, 895 ltv->an_len - 2, len, ltv->an_type); 896 len = ltv->an_len - 2; 897 } else { 898 ltv->an_len = len + 2; 899 } 900 901 /* Now read the data. */ 902 len -= 2; /* skip the type */ 903 ptr = <v->an_val; 904 for (i = len; i > 1; i -= 2) 905 *ptr++ = CSR_READ_2(sc, AN_DATA1); 906 if (i) { 907 ptr2 = (u_int8_t *)ptr; 908 *ptr2 = CSR_READ_1(sc, AN_DATA1); 909 } 910 if (an_dump) 911 an_dump_record(sc, ltv, "Read"); 912 913 return(0); 914} 915 916/* 917 * Same as read, except we inject data instead of reading it. 918 */ 919static int 920an_write_record(sc, ltv) 921 struct an_softc *sc; 922 struct an_ltv_gen *ltv; 923{ 924 u_int16_t *ptr; 925 u_int8_t *ptr2; 926 int i, len; 927 928 if (an_dump) 929 an_dump_record(sc, ltv, "Write"); 930 931 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) 932 return(EIO); 933 934 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) 935 return(EIO); 936 937 /* 938 * Length includes type but not length. 939 */ 940 len = ltv->an_len - 2; 941 CSR_WRITE_2(sc, AN_DATA1, len); 942 943 len -= 2; /* skip the type */ 944 ptr = <v->an_val; 945 for (i = len; i > 1; i -= 2) 946 CSR_WRITE_2(sc, AN_DATA1, *ptr++); 947 if (i) { 948 ptr2 = (u_int8_t *)ptr; 949 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 950 } 951 952 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) 953 return(EIO); 954 955 return(0); 956} 957 958static void 959an_dump_record(sc, ltv, string) 960 struct an_softc *sc; 961 struct an_ltv_gen *ltv; 962 char *string; 963{ 964 u_int8_t *ptr2; 965 int len; 966 int i; 967 int count = 0; 968 char buf[17], temp; 969 970 len = ltv->an_len - 4; 971 printf("an%d: RID %4x, Length %4d, Mode %s\n", 972 sc->an_unit, ltv->an_type, ltv->an_len - 4, string); 973 974 if (an_dump == 1 || (an_dump == ltv->an_type)) { 975 printf("an%d:\t", sc->an_unit); 976 bzero(buf,sizeof(buf)); 977 978 ptr2 = (u_int8_t *)<v->an_val; 979 for (i = len; i > 0; i--) { 980 printf("%02x ", *ptr2); 981 982 temp = *ptr2++; 983 if (temp >= ' ' && temp <= '~') 984 buf[count] = temp; 985 else if (temp >= 'A' && temp <= 'Z') 986 buf[count] = temp; 987 else 988 buf[count] = '.'; 989 if (++count == 16) { 990 count = 0; 991 printf("%s\n",buf); 992 printf("an%d:\t", sc->an_unit); 993 bzero(buf,sizeof(buf)); 994 } 995 } 996 for (; count != 16; count++) { 997 printf(" "); 998 } 999 printf(" %s\n",buf); 1000 } 1001} 1002 1003static int 1004an_seek(sc, id, off, chan) 1005 struct an_softc *sc; 1006 int id, off, chan; 1007{ 1008 int i; 1009 int selreg, offreg; 1010 1011 switch (chan) { 1012 case AN_BAP0: 1013 selreg = AN_SEL0; 1014 offreg = AN_OFF0; 1015 break; 1016 case AN_BAP1: 1017 selreg = AN_SEL1; 1018 offreg = AN_OFF1; 1019 break; 1020 default: 1021 printf("an%d: invalid data path: %x\n", sc->an_unit, chan); 1022 return(EIO); 1023 } 1024 1025 CSR_WRITE_2(sc, selreg, id); 1026 CSR_WRITE_2(sc, offreg, off); 1027 1028 for (i = 0; i < AN_TIMEOUT; i++) { 1029 if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR))) 1030 break; 1031 } 1032 1033 if (i == AN_TIMEOUT) 1034 return(ETIMEDOUT); 1035 1036 return(0); 1037} 1038 1039static int 1040an_read_data(sc, id, off, buf, len) 1041 struct an_softc *sc; 1042 int id, off; 1043 caddr_t buf; 1044 int len; 1045{ 1046 int i; 1047 u_int16_t *ptr; 1048 u_int8_t *ptr2; 1049 1050 if (off != -1) { 1051 if (an_seek(sc, id, off, AN_BAP1)) 1052 return(EIO); 1053 } 1054 1055 ptr = (u_int16_t *)buf; 1056 for (i = len; i > 1; i -= 2) 1057 *ptr++ = CSR_READ_2(sc, AN_DATA1); 1058 if (i) { 1059 ptr2 = (u_int8_t *)ptr; 1060 *ptr2 = CSR_READ_1(sc, AN_DATA1); 1061 } 1062 1063 return(0); 1064} 1065 1066static int 1067an_write_data(sc, id, off, buf, len) 1068 struct an_softc *sc; 1069 int id, off; 1070 caddr_t buf; 1071 int len; 1072{ 1073 int i; 1074 u_int16_t *ptr; 1075 u_int8_t *ptr2; 1076 1077 if (off != -1) { 1078 if (an_seek(sc, id, off, AN_BAP0)) 1079 return(EIO); 1080 } 1081 1082 ptr = (u_int16_t *)buf; 1083 for (i = len; i > 1; i -= 2) 1084 CSR_WRITE_2(sc, AN_DATA0, *ptr++); 1085 if (i) { 1086 ptr2 = (u_int8_t *)ptr; 1087 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 1088 } 1089 1090 return(0); 1091} 1092 1093/* 1094 * Allocate a region of memory inside the NIC and zero 1095 * it out. 1096 */ 1097static int 1098an_alloc_nicmem(sc, len, id) 1099 struct an_softc *sc; 1100 int len; 1101 int *id; 1102{ 1103 int i; 1104 1105 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 1106 printf("an%d: failed to allocate %d bytes on NIC\n", 1107 sc->an_unit, len); 1108 return(ENOMEM); 1109 } 1110 1111 for (i = 0; i < AN_TIMEOUT; i++) { 1112 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC) 1113 break; 1114 } 1115 1116 if (i == AN_TIMEOUT) 1117 return(ETIMEDOUT); 1118 1119 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 1120 *id = CSR_READ_2(sc, AN_ALLOC_FID); 1121 1122 if (an_seek(sc, *id, 0, AN_BAP0)) 1123 return(EIO); 1124 1125 for (i = 0; i < len / 2; i++) 1126 CSR_WRITE_2(sc, AN_DATA0, 0); 1127 1128 return(0); 1129} 1130 1131static void 1132an_setdef(sc, areq) 1133 struct an_softc *sc; 1134 struct an_req *areq; 1135{ 1136 struct sockaddr_dl *sdl; 1137 struct ifaddr *ifa; 1138 struct ifnet *ifp; 1139 struct an_ltv_genconfig *cfg; 1140 struct an_ltv_ssidlist *ssid; 1141 struct an_ltv_aplist *ap; 1142 struct an_ltv_gen *sp; 1143 1144 ifp = &sc->arpcom.ac_if; 1145 1146 switch (areq->an_type) { 1147 case AN_RID_GENCONFIG: 1148 cfg = (struct an_ltv_genconfig *)areq; 1149 1150 ifa = ifaddr_byindex(ifp->if_index); 1151 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1152 bcopy((char *)&cfg->an_macaddr, (char *)&sc->arpcom.ac_enaddr, 1153 ETHER_ADDR_LEN); 1154 bcopy((char *)&cfg->an_macaddr, LLADDR(sdl), ETHER_ADDR_LEN); 1155 1156 bcopy((char *)cfg, (char *)&sc->an_config, 1157 sizeof(struct an_ltv_genconfig)); 1158 break; 1159 case AN_RID_SSIDLIST: 1160 ssid = (struct an_ltv_ssidlist *)areq; 1161 bcopy((char *)ssid, (char *)&sc->an_ssidlist, 1162 sizeof(struct an_ltv_ssidlist)); 1163 break; 1164 case AN_RID_APLIST: 1165 ap = (struct an_ltv_aplist *)areq; 1166 bcopy((char *)ap, (char *)&sc->an_aplist, 1167 sizeof(struct an_ltv_aplist)); 1168 break; 1169 case AN_RID_TX_SPEED: 1170 sp = (struct an_ltv_gen *)areq; 1171 sc->an_tx_rate = sp->an_val; 1172 break; 1173 case AN_RID_WEP_TEMP: 1174 case AN_RID_WEP_PERM: 1175 /* Disable the MAC. */ 1176 an_cmd(sc, AN_CMD_DISABLE, 0); 1177 1178 /* Write the key */ 1179 an_write_record(sc, (struct an_ltv_gen *)areq); 1180 1181 /* Turn the MAC back on. */ 1182 an_cmd(sc, AN_CMD_ENABLE, 0); 1183 1184 break; 1185 case AN_RID_MONITOR_MODE: 1186 cfg = (struct an_ltv_genconfig *)areq; 1187 bpfdetach(ifp); 1188 if (ng_ether_detach_p != NULL) 1189 (*ng_ether_detach_p) (ifp); 1190 sc->an_monitor = cfg->an_len; 1191 1192 if (sc->an_monitor & AN_MONITOR) { 1193 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 1194 bpfattach(ifp, DLT_AIRONET_HEADER, 1195 sizeof(struct ether_header)); 1196 } else { 1197 bpfattach(ifp, DLT_IEEE802_11, 1198 sizeof(struct ether_header)); 1199 } 1200 } else { 1201 bpfattach(ifp, DLT_EN10MB, 1202 sizeof(struct ether_header)); 1203 if (ng_ether_attach_p != NULL) 1204 (*ng_ether_attach_p) (ifp); 1205 } 1206 break; 1207 default: 1208 printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type); 1209 return; 1210 break; 1211 } 1212 1213 1214 /* Reinitialize the card. */ 1215 if (ifp->if_flags) 1216 an_init(sc); 1217 1218 return; 1219} 1220 1221/* 1222 * Derived from Linux driver to enable promiscious mode. 1223 */ 1224 1225static void 1226an_promisc(sc, promisc) 1227 struct an_softc *sc; 1228 int promisc; 1229{ 1230 if (sc->an_was_monitor) 1231 an_reset(sc); 1232 if (sc->an_monitor || sc->an_was_monitor) 1233 an_init(sc); 1234 1235 sc->an_was_monitor = sc->an_monitor; 1236 an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0); 1237 1238 return; 1239} 1240 1241static int 1242an_ioctl(ifp, command, data) 1243 struct ifnet *ifp; 1244 u_long command; 1245 caddr_t data; 1246{ 1247 int error = 0; 1248 int len; 1249 int i; 1250 struct an_softc *sc; 1251 struct an_req areq; 1252 struct ifreq *ifr; 1253 struct proc *p = curproc; 1254 struct ieee80211req *ireq; 1255 u_int8_t tmpstr[IEEE80211_NWID_LEN*2]; 1256 u_int8_t *tmpptr; 1257 struct an_ltv_genconfig *config; 1258 struct an_ltv_key *key; 1259 struct an_ltv_status *status; 1260 struct an_ltv_ssidlist *ssids; 1261 1262 sc = ifp->if_softc; 1263 AN_LOCK(sc); 1264 ifr = (struct ifreq *)data; 1265 ireq = (struct ieee80211req *)data; 1266 1267 config = (struct an_ltv_genconfig *)&areq; 1268 key = (struct an_ltv_key *)&areq; 1269 status = (struct an_ltv_status *)&areq; 1270 ssids = (struct an_ltv_ssidlist *)&areq; 1271 1272 if (sc->an_gone) { 1273 error = ENODEV; 1274 goto out; 1275 } 1276 1277 switch (command) { 1278 case SIOCSIFADDR: 1279 case SIOCGIFADDR: 1280 case SIOCSIFMTU: 1281 error = ether_ioctl(ifp, command, data); 1282 break; 1283 case SIOCSIFFLAGS: 1284 if (ifp->if_flags & IFF_UP) { 1285 if (ifp->if_flags & IFF_RUNNING && 1286 ifp->if_flags & IFF_PROMISC && 1287 !(sc->an_if_flags & IFF_PROMISC)) { 1288 an_promisc(sc, 1); 1289 } else if (ifp->if_flags & IFF_RUNNING && 1290 !(ifp->if_flags & IFF_PROMISC) && 1291 sc->an_if_flags & IFF_PROMISC) { 1292 an_promisc(sc, 0); 1293 } else 1294 an_init(sc); 1295 } else { 1296 if (ifp->if_flags & IFF_RUNNING) 1297 an_stop(sc); 1298 } 1299 sc->an_if_flags = ifp->if_flags; 1300 error = 0; 1301 break; 1302 case SIOCSIFMEDIA: 1303 case SIOCGIFMEDIA: 1304 error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command); 1305 break; 1306 case SIOCADDMULTI: 1307 case SIOCDELMULTI: 1308 /* The Aironet has no multicast filter. */ 1309 error = 0; 1310 break; 1311 case SIOCGAIRONET: 1312 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1313 if (error != 0) 1314 break; 1315#ifdef ANCACHE 1316 if (areq.an_type == AN_RID_ZERO_CACHE) { 1317 sc->an_sigitems = sc->an_nextitem = 0; 1318 break; 1319 } else if (areq.an_type == AN_RID_READ_CACHE) { 1320 char *pt = (char *)&areq.an_val; 1321 bcopy((char *)&sc->an_sigitems, (char *)pt, 1322 sizeof(int)); 1323 pt += sizeof(int); 1324 areq.an_len = sizeof(int) / 2; 1325 bcopy((char *)&sc->an_sigcache, (char *)pt, 1326 sizeof(struct an_sigcache) * sc->an_sigitems); 1327 areq.an_len += ((sizeof(struct an_sigcache) * 1328 sc->an_sigitems) / 2) + 1; 1329 } else 1330#endif 1331 if (an_read_record(sc, (struct an_ltv_gen *)&areq)) { 1332 error = EINVAL; 1333 break; 1334 } 1335 error = copyout(&areq, ifr->ifr_data, sizeof(areq)); 1336 break; 1337 case SIOCSAIRONET: 1338 if ((error = suser(p))) 1339 goto out; 1340 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1341 if (error != 0) 1342 break; 1343 an_setdef(sc, &areq); 1344 break; 1345 case SIOCG80211: 1346 areq.an_len = sizeof(areq); 1347 switch (ireq->i_type) { 1348 case IEEE80211_IOC_SSID: 1349 if (ireq->i_val == -1) { 1350 areq.an_type = AN_RID_STATUS; 1351 if (an_read_record(sc, 1352 (struct an_ltv_gen *)&areq)) { 1353 error = EINVAL; 1354 break; 1355 } 1356 len = status->an_ssidlen; 1357 tmpptr = status->an_ssid; 1358 } else if (ireq->i_val >= 0) { 1359 areq.an_type = AN_RID_SSIDLIST; 1360 if (an_read_record(sc, 1361 (struct an_ltv_gen *)&areq)) { 1362 error = EINVAL; 1363 break; 1364 } 1365 if (ireq->i_val == 0) { 1366 len = ssids->an_ssid1_len; 1367 tmpptr = ssids->an_ssid1; 1368 } else if (ireq->i_val == 1) { 1369 len = ssids->an_ssid2_len; 1370 tmpptr = ssids->an_ssid3; 1371 } else if (ireq->i_val == 1) { 1372 len = ssids->an_ssid3_len; 1373 tmpptr = ssids->an_ssid3; 1374 } else { 1375 error = EINVAL; 1376 break; 1377 } 1378 } else { 1379 error = EINVAL; 1380 break; 1381 } 1382 if (len > IEEE80211_NWID_LEN) { 1383 error = EINVAL; 1384 break; 1385 } 1386 ireq->i_len = len; 1387 bzero(tmpstr, IEEE80211_NWID_LEN); 1388 bcopy(tmpptr, tmpstr, len); 1389 error = copyout(tmpstr, ireq->i_data, 1390 IEEE80211_NWID_LEN); 1391 break; 1392 case IEEE80211_IOC_NUMSSIDS: 1393 ireq->i_val = 3; 1394 break; 1395 case IEEE80211_IOC_WEP: 1396 areq.an_type = AN_RID_ACTUALCFG; 1397 if (an_read_record(sc, 1398 (struct an_ltv_gen *)&areq)) { 1399 error = EINVAL; 1400 break; 1401 } 1402 if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { 1403 if (config->an_authtype & 1404 AN_AUTHTYPE_ALLOW_UNENCRYPTED) 1405 ireq->i_val = IEEE80211_WEP_MIXED; 1406 else 1407 ireq->i_val = IEEE80211_WEP_ON; 1408 } else { 1409 ireq->i_val = IEEE80211_WEP_OFF; 1410 } 1411 break; 1412 case IEEE80211_IOC_WEPKEY: 1413 /* 1414 * XXX: I'm not entierly convinced this is 1415 * correct, but it's what is implemented in 1416 * ancontrol so it will have to do until we get 1417 * access to actual Cisco code. 1418 */ 1419 if (ireq->i_val < 0 || ireq->i_val > 7) { 1420 error = EINVAL; 1421 break; 1422 } 1423 len = 0; 1424 if (ireq->i_val < 4) { 1425 areq.an_type = AN_RID_WEP_TEMP; 1426 for (i = 0; i < 5; i++) { 1427 if (an_read_record(sc, 1428 (struct an_ltv_gen *)&areq)) { 1429 error = EINVAL; 1430 break; 1431 } 1432 if (key->kindex == 0xffff) 1433 break; 1434 if (key->kindex == ireq->i_val) 1435 len = key->klen; 1436 /* Required to get next entry */ 1437 areq.an_type = AN_RID_WEP_PERM; 1438 } 1439 if (error != 0) 1440 break; 1441 } 1442 /* We aren't allowed to read the value of the 1443 * key from the card so we just output zeros 1444 * like we would if we could read the card, but 1445 * denied the user access. 1446 */ 1447 bzero(tmpstr, len); 1448 ireq->i_len = len; 1449 error = copyout(tmpstr, ireq->i_data, len); 1450 break; 1451 case IEEE80211_IOC_NUMWEPKEYS: 1452 ireq->i_val = 8; 1453 break; 1454 case IEEE80211_IOC_WEPTXKEY: 1455 /* 1456 * For some strange reason, you have to read all 1457 * keys before you can read the txkey. 1458 */ 1459 areq.an_type = AN_RID_WEP_TEMP; 1460 for (i = 0; i < 5; i++) { 1461 if (an_read_record(sc, 1462 (struct an_ltv_gen *)&areq)) { 1463 error = EINVAL; 1464 break; 1465 } 1466 if (key->kindex == 0xffff) 1467 break; 1468 /* Required to get next entry */ 1469 areq.an_type = AN_RID_WEP_PERM; 1470 } 1471 if (error != 0) 1472 break; 1473 1474 areq.an_type = AN_RID_WEP_PERM; 1475 key->kindex = 0xffff; 1476 if (an_read_record(sc, 1477 (struct an_ltv_gen *)&areq)) { 1478 error = EINVAL; 1479 break; 1480 } 1481 ireq->i_val = key->mac[0]; 1482 break; 1483 case IEEE80211_IOC_AUTHMODE: 1484 areq.an_type = AN_RID_ACTUALCFG; 1485 if (an_read_record(sc, 1486 (struct an_ltv_gen *)&areq)) { 1487 error = EINVAL; 1488 break; 1489 } 1490 if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1491 AN_AUTHTYPE_NONE) { 1492 ireq->i_val = IEEE80211_AUTH_NONE; 1493 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1494 AN_AUTHTYPE_OPEN) { 1495 ireq->i_val = IEEE80211_AUTH_OPEN; 1496 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1497 AN_AUTHTYPE_SHAREDKEY) { 1498 ireq->i_val = IEEE80211_AUTH_SHARED; 1499 } else 1500 error = EINVAL; 1501 break; 1502 case IEEE80211_IOC_STATIONNAME: 1503 areq.an_type = AN_RID_ACTUALCFG; 1504 if (an_read_record(sc, 1505 (struct an_ltv_gen *)&areq)) { 1506 error = EINVAL; 1507 break; 1508 } 1509 ireq->i_len = sizeof(config->an_nodename); 1510 tmpptr = config->an_nodename; 1511 bzero(tmpstr, IEEE80211_NWID_LEN); 1512 bcopy(tmpptr, tmpstr, ireq->i_len); 1513 error = copyout(tmpstr, ireq->i_data, 1514 IEEE80211_NWID_LEN); 1515 break; 1516 case IEEE80211_IOC_CHANNEL: 1517 areq.an_type = AN_RID_STATUS; 1518 if (an_read_record(sc, 1519 (struct an_ltv_gen *)&areq)) { 1520 error = EINVAL; 1521 break; 1522 } 1523 ireq->i_val = status->an_cur_channel; 1524 break; 1525 case IEEE80211_IOC_POWERSAVE: 1526 areq.an_type = AN_RID_ACTUALCFG; 1527 if (an_read_record(sc, 1528 (struct an_ltv_gen *)&areq)) { 1529 error = EINVAL; 1530 break; 1531 } 1532 if (config->an_psave_mode == AN_PSAVE_NONE) { 1533 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1534 } else if (config->an_psave_mode == AN_PSAVE_CAM) { 1535 ireq->i_val = IEEE80211_POWERSAVE_CAM; 1536 } else if (config->an_psave_mode == AN_PSAVE_PSP) { 1537 ireq->i_val = IEEE80211_POWERSAVE_PSP; 1538 } else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) { 1539 ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM; 1540 } else 1541 error = EINVAL; 1542 break; 1543 case IEEE80211_IOC_POWERSAVESLEEP: 1544 areq.an_type = AN_RID_ACTUALCFG; 1545 if (an_read_record(sc, 1546 (struct an_ltv_gen *)&areq)) { 1547 error = EINVAL; 1548 break; 1549 } 1550 ireq->i_val = config->an_listen_interval; 1551 break; 1552 } 1553 break; 1554 case SIOCS80211: 1555 if ((error = suser(p))) 1556 goto out; 1557 areq.an_len = sizeof(areq); 1558 /* 1559 * We need a config structure for everything but the WEP 1560 * key management and SSIDs so we get it now so avoid 1561 * duplicating this code every time. 1562 */ 1563 if (ireq->i_type != IEEE80211_IOC_SSID && 1564 ireq->i_type != IEEE80211_IOC_WEPKEY && 1565 ireq->i_type != IEEE80211_IOC_WEPTXKEY) { 1566 areq.an_type = AN_RID_GENCONFIG; 1567 if (an_read_record(sc, 1568 (struct an_ltv_gen *)&areq)) { 1569 error = EINVAL; 1570 break; 1571 } 1572 } 1573 switch (ireq->i_type) { 1574 case IEEE80211_IOC_SSID: 1575 areq.an_type = AN_RID_SSIDLIST; 1576 if (an_read_record(sc, 1577 (struct an_ltv_gen *)&areq)) { 1578 error = EINVAL; 1579 break; 1580 } 1581 if (ireq->i_len > IEEE80211_NWID_LEN) { 1582 error = EINVAL; 1583 break; 1584 } 1585 switch (ireq->i_val) { 1586 case 0: 1587 error = copyin(ireq->i_data, 1588 ssids->an_ssid1, ireq->i_len); 1589 ssids->an_ssid1_len = ireq->i_len; 1590 break; 1591 case 1: 1592 error = copyin(ireq->i_data, 1593 ssids->an_ssid2, ireq->i_len); 1594 ssids->an_ssid2_len = ireq->i_len; 1595 break; 1596 case 2: 1597 error = copyin(ireq->i_data, 1598 ssids->an_ssid3, ireq->i_len); 1599 ssids->an_ssid3_len = ireq->i_len; 1600 break; 1601 default: 1602 error = EINVAL; 1603 break; 1604 } 1605 break; 1606 case IEEE80211_IOC_WEP: 1607 switch (ireq->i_val) { 1608 case IEEE80211_WEP_OFF: 1609 config->an_authtype &= 1610 ~(AN_AUTHTYPE_PRIVACY_IN_USE | 1611 AN_AUTHTYPE_ALLOW_UNENCRYPTED); 1612 break; 1613 case IEEE80211_WEP_ON: 1614 config->an_authtype |= 1615 AN_AUTHTYPE_PRIVACY_IN_USE; 1616 config->an_authtype &= 1617 ~AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1618 break; 1619 case IEEE80211_WEP_MIXED: 1620 config->an_authtype |= 1621 AN_AUTHTYPE_PRIVACY_IN_USE | 1622 AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1623 break; 1624 default: 1625 error = EINVAL; 1626 break; 1627 } 1628 break; 1629 case IEEE80211_IOC_WEPKEY: 1630 if (ireq->i_val < 0 || ireq->i_val > 7 || 1631 ireq->i_len > 13) { 1632 error = EINVAL; 1633 break; 1634 } 1635 error = copyin(ireq->i_data, tmpstr, 13); 1636 if (error != 0) 1637 break; 1638 bzero(&areq, sizeof(struct an_ltv_key)); 1639 areq.an_len = sizeof(struct an_ltv_key); 1640 key->mac[0] = 1; /* The others are 0. */ 1641 key->kindex = ireq->i_val % 4; 1642 if (ireq->i_val < 4) 1643 areq.an_type = AN_RID_WEP_TEMP; 1644 else 1645 areq.an_type = AN_RID_WEP_PERM; 1646 key->klen = ireq->i_len; 1647 bcopy(tmpstr, key->key, key->klen); 1648 break; 1649 case IEEE80211_IOC_WEPTXKEY: 1650 if (ireq->i_val < 0 || ireq->i_val > 3) { 1651 error = EINVAL; 1652 break; 1653 } 1654 bzero(&areq, sizeof(struct an_ltv_key)); 1655 areq.an_len = sizeof(struct an_ltv_key); 1656 areq.an_type = AN_RID_WEP_PERM; 1657 key->kindex = 0xffff; 1658 key->mac[0] = ireq->i_val; 1659 break; 1660 case IEEE80211_IOC_AUTHMODE: 1661 switch (ireq->i_val) { 1662 case IEEE80211_AUTH_NONE: 1663 config->an_authtype = AN_AUTHTYPE_NONE | 1664 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1665 break; 1666 case IEEE80211_AUTH_OPEN: 1667 config->an_authtype = AN_AUTHTYPE_OPEN | 1668 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1669 break; 1670 case IEEE80211_AUTH_SHARED: 1671 config->an_authtype = AN_AUTHTYPE_SHAREDKEY | 1672 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1673 break; 1674 default: 1675 error = EINVAL; 1676 } 1677 break; 1678 case IEEE80211_IOC_STATIONNAME: 1679 if (ireq->i_len > 16) { 1680 error = EINVAL; 1681 break; 1682 } 1683 bzero(config->an_nodename, 16); 1684 error = copyin(ireq->i_data, 1685 config->an_nodename, ireq->i_len); 1686 break; 1687 case IEEE80211_IOC_CHANNEL: 1688 /* 1689 * The actual range is 1-14, but if you set it 1690 * to 0 you get the default so we let that work 1691 * too. 1692 */ 1693 if (ireq->i_val < 0 || ireq->i_val >14) { 1694 error = EINVAL; 1695 break; 1696 } 1697 config->an_ds_channel = ireq->i_val; 1698 break; 1699 case IEEE80211_IOC_POWERSAVE: 1700 switch (ireq->i_val) { 1701 case IEEE80211_POWERSAVE_OFF: 1702 config->an_psave_mode = AN_PSAVE_NONE; 1703 break; 1704 case IEEE80211_POWERSAVE_CAM: 1705 config->an_psave_mode = AN_PSAVE_CAM; 1706 break; 1707 case IEEE80211_POWERSAVE_PSP: 1708 config->an_psave_mode = AN_PSAVE_PSP; 1709 break; 1710 case IEEE80211_POWERSAVE_PSP_CAM: 1711 config->an_psave_mode = AN_PSAVE_PSP_CAM; 1712 break; 1713 default: 1714 error = EINVAL; 1715 break; 1716 } 1717 break; 1718 case IEEE80211_IOC_POWERSAVESLEEP: 1719 config->an_listen_interval = ireq->i_val; 1720 break; 1721 } 1722 1723 if (!error) 1724 an_setdef(sc, &areq); 1725 break; 1726 default: 1727 error = EINVAL; 1728 break; 1729 } 1730out: 1731 AN_UNLOCK(sc); 1732 1733 return(error != 0); 1734} 1735 1736static int 1737an_init_tx_ring(sc) 1738 struct an_softc *sc; 1739{ 1740 int i; 1741 int id; 1742 1743 if (sc->an_gone) 1744 return (0); 1745 1746 for (i = 0; i < AN_TX_RING_CNT; i++) { 1747 if (an_alloc_nicmem(sc, 1518 + 1748 0x44, &id)) 1749 return(ENOMEM); 1750 sc->an_rdata.an_tx_fids[i] = id; 1751 sc->an_rdata.an_tx_ring[i] = 0; 1752 } 1753 1754 sc->an_rdata.an_tx_prod = 0; 1755 sc->an_rdata.an_tx_cons = 0; 1756 1757 return(0); 1758} 1759 1760static void 1761an_init(xsc) 1762 void *xsc; 1763{ 1764 struct an_softc *sc = xsc; 1765 struct ifnet *ifp = &sc->arpcom.ac_if; 1766 1767 AN_LOCK(sc); 1768 1769 if (sc->an_gone) { 1770 AN_UNLOCK(sc); 1771 return; 1772 } 1773 1774 if (ifp->if_flags & IFF_RUNNING) 1775 an_stop(sc); 1776 1777 sc->an_associated = 0; 1778 1779 /* Allocate the TX buffers */ 1780 if (an_init_tx_ring(sc)) { 1781 an_reset(sc); 1782 if (an_init_tx_ring(sc)) { 1783 printf("an%d: tx buffer allocation " 1784 "failed\n", sc->an_unit); 1785 AN_UNLOCK(sc); 1786 return; 1787 } 1788 } 1789 1790 /* Set our MAC address. */ 1791 bcopy((char *)&sc->arpcom.ac_enaddr, 1792 (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN); 1793 1794 if (ifp->if_flags & IFF_BROADCAST) 1795 sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR; 1796 else 1797 sc->an_config.an_rxmode = AN_RXMODE_ADDR; 1798 1799 if (ifp->if_flags & IFF_MULTICAST) 1800 sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR; 1801 1802 if (ifp->if_flags & IFF_PROMISC) { 1803 if (sc->an_monitor & AN_MONITOR) { 1804 if (sc->an_monitor & AN_MONITOR_ANY_BSS) { 1805 sc->an_config.an_rxmode |= 1806 AN_RXMODE_80211_MONITOR_ANYBSS | 1807 AN_RXMODE_NO_8023_HEADER; 1808 } else { 1809 sc->an_config.an_rxmode |= 1810 AN_RXMODE_80211_MONITOR_CURBSS | 1811 AN_RXMODE_NO_8023_HEADER; 1812 } 1813 } 1814 } 1815 1816 /* Set the ssid list */ 1817 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 1818 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist); 1819 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 1820 printf("an%d: failed to set ssid list\n", sc->an_unit); 1821 AN_UNLOCK(sc); 1822 return; 1823 } 1824 1825 /* Set the AP list */ 1826 sc->an_aplist.an_type = AN_RID_APLIST; 1827 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 1828 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 1829 printf("an%d: failed to set AP list\n", sc->an_unit); 1830 AN_UNLOCK(sc); 1831 return; 1832 } 1833 1834 /* Set the configuration in the NIC */ 1835 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 1836 sc->an_config.an_type = AN_RID_GENCONFIG; 1837 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 1838 printf("an%d: failed to set configuration\n", sc->an_unit); 1839 AN_UNLOCK(sc); 1840 return; 1841 } 1842 1843 /* Enable the MAC */ 1844 if (an_cmd(sc, AN_CMD_ENABLE, 0)) { 1845 printf("an%d: failed to enable MAC\n", sc->an_unit); 1846 AN_UNLOCK(sc); 1847 return; 1848 } 1849 1850 if (ifp->if_flags & IFF_PROMISC) 1851 an_cmd(sc, AN_CMD_SET_MODE, 0xffff); 1852 1853 /* enable interrupts */ 1854 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 1855 1856 ifp->if_flags |= IFF_RUNNING; 1857 ifp->if_flags &= ~IFF_OACTIVE; 1858 1859 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 1860 AN_UNLOCK(sc); 1861 1862 return; 1863} 1864 1865static void 1866an_start(ifp) 1867 struct ifnet *ifp; 1868{ 1869 struct an_softc *sc; 1870 struct mbuf *m0 = NULL; 1871 struct an_txframe_802_3 tx_frame_802_3; 1872 struct ether_header *eh; 1873 int id; 1874 int idx; 1875 unsigned char txcontrol; 1876 1877 sc = ifp->if_softc; 1878 1879 if (sc->an_gone) 1880 return; 1881 1882 if (ifp->if_flags & IFF_OACTIVE) 1883 return; 1884 1885 if (!sc->an_associated) 1886 return; 1887 1888 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 1889 for (;;) { 1890 IF_DEQUEUE(&ifp->if_snd, m0); 1891 if (m0 == NULL) 1892 break; 1893 } 1894 return; 1895 } 1896 1897 idx = sc->an_rdata.an_tx_prod; 1898 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 1899 1900 while (sc->an_rdata.an_tx_ring[idx] == 0) { 1901 IF_DEQUEUE(&ifp->if_snd, m0); 1902 if (m0 == NULL) 1903 break; 1904 1905 id = sc->an_rdata.an_tx_fids[idx]; 1906 eh = mtod(m0, struct ether_header *); 1907 1908 bcopy((char *)&eh->ether_dhost, 1909 (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); 1910 bcopy((char *)&eh->ether_shost, 1911 (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); 1912 1913 tx_frame_802_3.an_tx_802_3_payload_len = 1914 m0->m_pkthdr.len - 12; /* minus src/dest mac & type */ 1915 1916 m_copydata(m0, sizeof(struct ether_header) - 2 , 1917 tx_frame_802_3.an_tx_802_3_payload_len, 1918 (caddr_t)&sc->an_txbuf); 1919 1920 txcontrol = AN_TXCTL_8023; 1921 /* write the txcontrol only */ 1922 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 1923 sizeof(txcontrol)); 1924 1925 /* 802_3 header */ 1926 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 1927 sizeof(struct an_txframe_802_3)); 1928 1929 /* in mbuf header type is just before payload */ 1930 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 1931 tx_frame_802_3.an_tx_802_3_payload_len); 1932 1933 /* 1934 * If there's a BPF listner, bounce a copy of 1935 * this frame to him. 1936 */ 1937 if (ifp->if_bpf) 1938 bpf_mtap(ifp, m0); 1939 1940 m_freem(m0); 1941 m0 = NULL; 1942 1943 sc->an_rdata.an_tx_ring[idx] = id; 1944 if (an_cmd(sc, AN_CMD_TX, id)) 1945 printf("an%d: xmit failed\n", sc->an_unit); 1946 1947 AN_INC(idx, AN_TX_RING_CNT); 1948 } 1949 1950 if (m0 != NULL) 1951 ifp->if_flags |= IFF_OACTIVE; 1952 1953 sc->an_rdata.an_tx_prod = idx; 1954 1955 /* 1956 * Set a timeout in case the chip goes out to lunch. 1957 */ 1958 ifp->if_timer = 5; 1959 1960 return; 1961} 1962 1963void 1964an_stop(sc) 1965 struct an_softc *sc; 1966{ 1967 struct ifnet *ifp; 1968 int i; 1969 1970 AN_LOCK(sc); 1971 1972 if (sc->an_gone) { 1973 AN_UNLOCK(sc); 1974 return; 1975 } 1976 1977 ifp = &sc->arpcom.ac_if; 1978 1979 an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0); 1980 CSR_WRITE_2(sc, AN_INT_EN, 0); 1981 an_cmd(sc, AN_CMD_DISABLE, 0); 1982 1983 for (i = 0; i < AN_TX_RING_CNT; i++) 1984 an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]); 1985 1986 untimeout(an_stats_update, sc, sc->an_stat_ch); 1987 1988 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 1989 1990 AN_UNLOCK(sc); 1991 1992 return; 1993} 1994 1995static void 1996an_watchdog(ifp) 1997 struct ifnet *ifp; 1998{ 1999 struct an_softc *sc; 2000 2001 sc = ifp->if_softc; 2002 AN_LOCK(sc); 2003 2004 if (sc->an_gone) { 2005 AN_UNLOCK(sc); 2006 return; 2007 } 2008 2009 printf("an%d: device timeout\n", sc->an_unit); 2010 2011 an_reset(sc); 2012 an_init(sc); 2013 2014 ifp->if_oerrors++; 2015 AN_UNLOCK(sc); 2016 2017 return; 2018} 2019 2020void 2021an_shutdown(dev) 2022 device_t dev; 2023{ 2024 struct an_softc *sc; 2025 2026 sc = device_get_softc(dev); 2027 an_stop(sc); 2028 2029 return; 2030} 2031 2032#ifdef ANCACHE 2033/* Aironet signal strength cache code. 2034 * store signal/noise/quality on per MAC src basis in 2035 * a small fixed cache. The cache wraps if > MAX slots 2036 * used. The cache may be zeroed out to start over. 2037 * Two simple filters exist to reduce computation: 2038 * 1. ip only (literally 0x800) which may be used 2039 * to ignore some packets. It defaults to ip only. 2040 * it could be used to focus on broadcast, non-IP 802.11 beacons. 2041 * 2. multicast/broadcast only. This may be used to 2042 * ignore unicast packets and only cache signal strength 2043 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2044 * beacons and not unicast traffic. 2045 * 2046 * The cache stores (MAC src(index), IP src (major clue), signal, 2047 * quality, noise) 2048 * 2049 * No apologies for storing IP src here. It's easy and saves much 2050 * trouble elsewhere. The cache is assumed to be INET dependent, 2051 * although it need not be. 2052 * 2053 * Note: the Aironet only has a single byte of signal strength value 2054 * in the rx frame header, and it's not scaled to anything sensible. 2055 * This is kind of lame, but it's all we've got. 2056 */ 2057 2058#ifdef documentation 2059 2060int an_sigitems; /* number of cached entries */ 2061struct an_sigcache an_sigcache[MAXANCACHE]; /* array of cache entries */ 2062int an_nextitem; /* index/# of entries */ 2063 2064 2065#endif 2066 2067/* control variables for cache filtering. Basic idea is 2068 * to reduce cost (e.g., to only Mobile-IP agent beacons 2069 * which are broadcast or multicast). Still you might 2070 * want to measure signal strength anth unicast ping packets 2071 * on a pt. to pt. ant. setup. 2072 */ 2073/* set true if you want to limit cache items to broadcast/mcast 2074 * only packets (not unicast). Useful for mobile-ip beacons which 2075 * are broadcast/multicast at network layer. Default is all packets 2076 * so ping/unicast anll work say anth pt. to pt. antennae setup. 2077 */ 2078static int an_cache_mcastonly = 0; 2079SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, 2080 &an_cache_mcastonly, 0, ""); 2081 2082/* set true if you want to limit cache items to IP packets only 2083*/ 2084static int an_cache_iponly = 1; 2085SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, 2086 &an_cache_iponly, 0, ""); 2087 2088/* 2089 * an_cache_store, per rx packet store signal 2090 * strength in MAC (src) indexed cache. 2091 */ 2092static void 2093an_cache_store (sc, eh, m, rx_quality) 2094 struct an_softc *sc; 2095 struct ether_header *eh; 2096 struct mbuf *m; 2097 unsigned short rx_quality; 2098{ 2099 struct ip *ip = 0; 2100 int i; 2101 static int cache_slot = 0; /* use this cache entry */ 2102 static int wrapindex = 0; /* next "free" cache entry */ 2103 int saanp = 0; 2104 2105 /* filters: 2106 * 1. ip only 2107 * 2. configurable filter to throw out unicast packets, 2108 * keep multicast only. 2109 */ 2110 2111 if ((ntohs(eh->ether_type) == 0x800)) { 2112 saanp = 1; 2113 } 2114 2115 /* filter for ip packets only 2116 */ 2117 if ( an_cache_iponly && !saanp) { 2118 return; 2119 } 2120 2121 /* filter for broadcast/multicast only 2122 */ 2123 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2124 return; 2125 } 2126 2127#ifdef SIGDEBUG 2128 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 2129 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2130#endif 2131 2132 /* find the ip header. we want to store the ip_src 2133 * address. 2134 */ 2135 if (saanp) { 2136 ip = mtod(m, struct ip *); 2137 } 2138 2139 /* do a linear search for a matching MAC address 2140 * in the cache table 2141 * . MAC address is 6 bytes, 2142 * . var w_nextitem holds total number of entries already cached 2143 */ 2144 for (i = 0; i < sc->an_nextitem; i++) { 2145 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 2146 /* Match!, 2147 * so we already have this entry, 2148 * update the data 2149 */ 2150 break; 2151 } 2152 } 2153 2154 /* did we find a matching mac address? 2155 * if yes, then overwrite a previously existing cache entry 2156 */ 2157 if (i < sc->an_nextitem ) { 2158 cache_slot = i; 2159 } 2160 /* else, have a new address entry,so 2161 * add this new entry, 2162 * if table full, then we need to replace LRU entry 2163 */ 2164 else { 2165 2166 /* check for space in cache table 2167 * note: an_nextitem also holds number of entries 2168 * added in the cache table 2169 */ 2170 if ( sc->an_nextitem < MAXANCACHE ) { 2171 cache_slot = sc->an_nextitem; 2172 sc->an_nextitem++; 2173 sc->an_sigitems = sc->an_nextitem; 2174 } 2175 /* no space found, so simply wrap anth wrap index 2176 * and "zap" the next entry 2177 */ 2178 else { 2179 if (wrapindex == MAXANCACHE) { 2180 wrapindex = 0; 2181 } 2182 cache_slot = wrapindex++; 2183 } 2184 } 2185 2186 /* invariant: cache_slot now points at some slot 2187 * in cache. 2188 */ 2189 if (cache_slot < 0 || cache_slot >= MAXANCACHE) { 2190 log(LOG_ERR, "an_cache_store, bad index: %d of " 2191 "[0..%d], gross cache error\n", 2192 cache_slot, MAXANCACHE); 2193 return; 2194 } 2195 2196 /* store items in cache 2197 * .ip source address 2198 * .mac src 2199 * .signal, etc. 2200 */ 2201 if (saanp) { 2202 sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 2203 } 2204 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 2205 2206 sc->an_sigcache[cache_slot].signal = rx_quality; 2207 2208 return; 2209} 2210#endif 2211 2212static int 2213an_media_change(ifp) 2214 struct ifnet *ifp; 2215{ 2216 struct an_softc *sc = ifp->if_softc; 2217 int otype = sc->an_config.an_opmode; 2218 int orate = sc->an_tx_rate; 2219 2220 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2221 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; 2222 else 2223 sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION; 2224 2225 switch (IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)) { 2226 case IFM_IEEE80211_DS1: 2227 sc->an_tx_rate = AN_RATE_1MBPS; 2228 break; 2229 case IFM_IEEE80211_DS2: 2230 sc->an_tx_rate = AN_RATE_2MBPS; 2231 break; 2232 case IFM_IEEE80211_DS5: 2233 sc->an_tx_rate = AN_RATE_5_5MBPS; 2234 break; 2235 case IFM_IEEE80211_DS11: 2236 sc->an_tx_rate = AN_RATE_11MBPS; 2237 break; 2238 case IFM_AUTO: 2239 sc->an_tx_rate = 0; 2240 break; 2241 } 2242 2243 if (otype != sc->an_config.an_opmode || 2244 orate != sc->an_tx_rate) 2245 an_init(sc); 2246 2247 return(0); 2248} 2249 2250static void 2251an_media_status(ifp, imr) 2252 struct ifnet *ifp; 2253 struct ifmediareq *imr; 2254{ 2255 struct an_ltv_status status; 2256 struct an_softc *sc = ifp->if_softc; 2257 2258 status.an_len = sizeof(status); 2259 status.an_type = AN_RID_STATUS; 2260 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 2261 /* If the status read fails, just lie. */ 2262 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2263 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 2264 } 2265 2266 if (sc->an_tx_rate == 0) { 2267 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2268 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2269 imr->ifm_active |= IFM_IEEE80211_ADHOC; 2270 switch (status.an_current_tx_rate) { 2271 case AN_RATE_1MBPS: 2272 imr->ifm_active |= IFM_IEEE80211_DS1; 2273 break; 2274 case AN_RATE_2MBPS: 2275 imr->ifm_active |= IFM_IEEE80211_DS2; 2276 break; 2277 case AN_RATE_5_5MBPS: 2278 imr->ifm_active |= IFM_IEEE80211_DS5; 2279 break; 2280 case AN_RATE_11MBPS: 2281 imr->ifm_active |= IFM_IEEE80211_DS11; 2282 break; 2283 } 2284 } else { 2285 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2286 } 2287 2288 imr->ifm_status = IFM_AVALID; 2289 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2290 imr->ifm_status |= IFM_ACTIVE; 2291 else if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED) 2292 imr->ifm_status |= IFM_ACTIVE; 2293} 2294