if_an.c revision 175446
1/*- 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32/* 33 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 34 * 35 * Written by Bill Paul <wpaul@ctr.columbia.edu> 36 * Electrical Engineering Department 37 * Columbia University, New York City 38 */ 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD: head/sys/dev/an/if_an.c 175446 2008-01-18 16:34:18Z ambrisko $"); 42 43/* 44 * The Aironet 4500/4800 series cards come 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/dev/an/if_an_pci.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 ISA card looks to the host like a PCMCIA controller with 57 * a PCMCIA WaveLAN card inserted. This means that even desktop 58 * machines need to be configured with PCMCIA support in order to 59 * use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand 60 * actually look like normal ISA and PCI devices to the host, so 61 * no PCMCIA controller support is needed 62 * 63 * The latter point results in a small gotcha. The Aironet PCMCIA 64 * cards can be configured for one of two operating modes depending 65 * on how the Vpp1 and Vpp2 programming voltages are set when the 66 * card is activated. In order to put the card in proper PCMCIA 67 * operation (where the CIS table is visible and the interface is 68 * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be 69 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages, 70 * which leaves the card in ISA/PCI mode, which prevents it from 71 * being activated as an PCMCIA device. 72 * 73 * Note that some PCMCIA controller software packages for Windows NT 74 * fail to set the voltages as well. 75 * 76 * The Aironet devices can operate in both station mode and access point 77 * mode. Typically, when programmed for station mode, the card can be set 78 * to automatically perform encapsulation/decapsulation of Ethernet II 79 * and 802.3 frames within 802.11 frames so that the host doesn't have 80 * to do it itself. This driver doesn't program the card that way: the 81 * driver handles all of the encapsulation/decapsulation itself. 82 */ 83 84#include "opt_inet.h" 85 86#ifdef INET 87#define ANCACHE /* enable signal strength cache */ 88#endif 89 90#include <sys/param.h> 91#include <sys/ctype.h> 92#include <sys/systm.h> 93#include <sys/sockio.h> 94#include <sys/mbuf.h> 95#include <sys/priv.h> 96#include <sys/proc.h> 97#include <sys/kernel.h> 98#include <sys/socket.h> 99#ifdef ANCACHE 100#include <sys/syslog.h> 101#endif 102#include <sys/sysctl.h> 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/lock.h> 110#include <sys/mutex.h> 111#include <machine/resource.h> 112#include <sys/malloc.h> 113 114#include <net/if.h> 115#include <net/if_arp.h> 116#include <net/if_dl.h> 117#include <net/ethernet.h> 118#include <net/if_types.h> 119#include <net/if_media.h> 120 121#include <net80211/ieee80211_var.h> 122#include <net80211/ieee80211_ioctl.h> 123 124#ifdef INET 125#include <netinet/in.h> 126#include <netinet/in_systm.h> 127#include <netinet/in_var.h> 128#include <netinet/ip.h> 129#endif 130 131#include <net/bpf.h> 132 133#include <machine/md_var.h> 134 135#include <dev/an/if_aironet_ieee.h> 136#include <dev/an/if_anreg.h> 137 138/* These are global because we need them in sys/pci/if_an_p.c. */ 139static void an_reset(struct an_softc *); 140static int an_init_mpi350_desc(struct an_softc *); 141static int an_ioctl(struct ifnet *, u_long, caddr_t); 142static void an_init(void *); 143static int an_init_tx_ring(struct an_softc *); 144static void an_start(struct ifnet *); 145static void an_watchdog(struct ifnet *); 146static void an_rxeof(struct an_softc *); 147static void an_txeof(struct an_softc *, int); 148 149static void an_promisc(struct an_softc *, int); 150static int an_cmd(struct an_softc *, int, int); 151static int an_cmd_struct(struct an_softc *, struct an_command *, 152 struct an_reply *); 153static int an_read_record(struct an_softc *, struct an_ltv_gen *); 154static int an_write_record(struct an_softc *, struct an_ltv_gen *); 155static int an_read_data(struct an_softc *, int, int, caddr_t, int); 156static int an_write_data(struct an_softc *, int, int, caddr_t, int); 157static int an_seek(struct an_softc *, int, int, int); 158static int an_alloc_nicmem(struct an_softc *, int, int *); 159static int an_dma_malloc(struct an_softc *, bus_size_t, struct an_dma_alloc *, 160 int); 161static void an_dma_free(struct an_softc *, struct an_dma_alloc *); 162static void an_dma_malloc_cb(void *, bus_dma_segment_t *, int, int); 163static void an_stats_update(void *); 164static void an_setdef(struct an_softc *, struct an_req *); 165#ifdef ANCACHE 166static void an_cache_store(struct an_softc *, struct ether_header *, 167 struct mbuf *, u_int8_t, u_int8_t); 168#endif 169 170/* function definitions for use with the Cisco's Linux configuration 171 utilities 172*/ 173 174static int readrids(struct ifnet*, struct aironet_ioctl*); 175static int writerids(struct ifnet*, struct aironet_ioctl*); 176static int flashcard(struct ifnet*, struct aironet_ioctl*); 177 178static int cmdreset(struct ifnet *); 179static int setflashmode(struct ifnet *); 180static int flashgchar(struct ifnet *,int,int); 181static int flashpchar(struct ifnet *,int,int); 182static int flashputbuf(struct ifnet *); 183static int flashrestart(struct ifnet *); 184static int WaitBusy(struct ifnet *, int); 185static int unstickbusy(struct ifnet *); 186 187static void an_dump_record (struct an_softc *,struct an_ltv_gen *, 188 char *); 189 190static int an_media_change (struct ifnet *); 191static void an_media_status (struct ifnet *, struct ifmediareq *); 192 193static int an_dump = 0; 194static int an_cache_mode = 0; 195 196#define DBM 0 197#define PERCENT 1 198#define RAW 2 199 200static char an_conf[256]; 201static char an_conf_cache[256]; 202 203/* sysctl vars */ 204 205SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD, 0, "Wireless driver parameters"); 206 207/* XXX violate ethernet/netgraph callback hooks */ 208extern void (*ng_ether_attach_p)(struct ifnet *ifp); 209extern void (*ng_ether_detach_p)(struct ifnet *ifp); 210 211static int 212sysctl_an_dump(SYSCTL_HANDLER_ARGS) 213{ 214 int error, r, last; 215 char *s = an_conf; 216 217 last = an_dump; 218 219 switch (an_dump) { 220 case 0: 221 strcpy(an_conf, "off"); 222 break; 223 case 1: 224 strcpy(an_conf, "type"); 225 break; 226 case 2: 227 strcpy(an_conf, "dump"); 228 break; 229 default: 230 snprintf(an_conf, 5, "%x", an_dump); 231 break; 232 } 233 234 error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req); 235 236 if (strncmp(an_conf,"off", 3) == 0) { 237 an_dump = 0; 238 } 239 if (strncmp(an_conf,"dump", 4) == 0) { 240 an_dump = 1; 241 } 242 if (strncmp(an_conf,"type", 4) == 0) { 243 an_dump = 2; 244 } 245 if (*s == 'f') { 246 r = 0; 247 for (;;s++) { 248 if ((*s >= '0') && (*s <= '9')) { 249 r = r * 16 + (*s - '0'); 250 } else if ((*s >= 'a') && (*s <= 'f')) { 251 r = r * 16 + (*s - 'a' + 10); 252 } else { 253 break; 254 } 255 } 256 an_dump = r; 257 } 258 if (an_dump != last) 259 printf("Sysctl changed for Aironet driver\n"); 260 261 return error; 262} 263 264SYSCTL_PROC(_hw_an, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, 265 0, sizeof(an_conf), sysctl_an_dump, "A", ""); 266 267static int 268sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS) 269{ 270 int error, last; 271 272 last = an_cache_mode; 273 274 switch (an_cache_mode) { 275 case 1: 276 strcpy(an_conf_cache, "per"); 277 break; 278 case 2: 279 strcpy(an_conf_cache, "raw"); 280 break; 281 default: 282 strcpy(an_conf_cache, "dbm"); 283 break; 284 } 285 286 error = sysctl_handle_string(oidp, an_conf_cache, 287 sizeof(an_conf_cache), req); 288 289 if (strncmp(an_conf_cache,"dbm", 3) == 0) { 290 an_cache_mode = 0; 291 } 292 if (strncmp(an_conf_cache,"per", 3) == 0) { 293 an_cache_mode = 1; 294 } 295 if (strncmp(an_conf_cache,"raw", 3) == 0) { 296 an_cache_mode = 2; 297 } 298 299 return error; 300} 301 302SYSCTL_PROC(_hw_an, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW, 303 0, sizeof(an_conf_cache), sysctl_an_cache_mode, "A", ""); 304 305/* 306 * Setup the lock for PCI attachment since it skips the an_probe 307 * function. We need to setup the lock in an_probe since some 308 * operations need the lock. So we might as well create the 309 * lock in the probe. 310 */ 311int 312an_pci_probe(device_t dev) 313{ 314 struct an_softc *sc = device_get_softc(dev); 315 316 mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 317 MTX_DEF | MTX_RECURSE); 318 319 return(0); 320} 321 322/* 323 * We probe for an Aironet 4500/4800 card by attempting to 324 * read the default SSID list. On reset, the first entry in 325 * the SSID list will contain the name "tsunami." If we don't 326 * find this, then there's no card present. 327 */ 328int 329an_probe(device_t dev) 330{ 331 struct an_softc *sc = device_get_softc(dev); 332 struct an_ltv_ssidlist_new ssid; 333 int error; 334 335 bzero((char *)&ssid, sizeof(ssid)); 336 337 error = an_alloc_port(dev, 0, AN_IOSIZ); 338 if (error != 0) 339 return (0); 340 341 /* can't do autoprobing */ 342 if (rman_get_start(sc->port_res) == -1) 343 return(0); 344 345 /* 346 * We need to fake up a softc structure long enough 347 * to be able to issue commands and call some of the 348 * other routines. 349 */ 350 sc->an_bhandle = rman_get_bushandle(sc->port_res); 351 sc->an_btag = rman_get_bustag(sc->port_res); 352 sc->an_unit = device_get_unit(dev); 353 354 ssid.an_len = sizeof(ssid); 355 ssid.an_type = AN_RID_SSIDLIST; 356 357 /* Make sure interrupts are disabled. */ 358 sc->mpi350 = 0; 359 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0); 360 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF); 361 362 mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 363 MTX_DEF | MTX_RECURSE); 364 AN_LOCK(sc); 365 an_reset(sc); 366 367 if (an_cmd(sc, AN_CMD_READCFG, 0)) { 368 AN_UNLOCK(sc); 369 goto fail; 370 } 371 372 if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) { 373 AN_UNLOCK(sc); 374 goto fail; 375 } 376 377 /* See if the ssid matches what we expect ... but doesn't have to */ 378 if (strcmp(ssid.an_entry[0].an_ssid, AN_DEF_SSID)) { 379 AN_UNLOCK(sc); 380 goto fail; 381 } 382 383 AN_UNLOCK(sc); 384 return(AN_IOSIZ); 385fail: 386 mtx_destroy(&sc->an_mtx); 387 return(0); 388} 389 390/* 391 * Allocate a port resource with the given resource id. 392 */ 393int 394an_alloc_port(device_t dev, int rid, int size) 395{ 396 struct an_softc *sc = device_get_softc(dev); 397 struct resource *res; 398 399 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 400 0ul, ~0ul, size, RF_ACTIVE); 401 if (res) { 402 sc->port_rid = rid; 403 sc->port_res = res; 404 return (0); 405 } else { 406 return (ENOENT); 407 } 408} 409 410/* 411 * Allocate a memory resource with the given resource id. 412 */ 413int an_alloc_memory(device_t dev, int rid, int size) 414{ 415 struct an_softc *sc = device_get_softc(dev); 416 struct resource *res; 417 418 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 419 0ul, ~0ul, size, RF_ACTIVE); 420 if (res) { 421 sc->mem_rid = rid; 422 sc->mem_res = res; 423 sc->mem_used = size; 424 return (0); 425 } else { 426 return (ENOENT); 427 } 428} 429 430/* 431 * Allocate a auxilary memory resource with the given resource id. 432 */ 433int an_alloc_aux_memory(device_t dev, int rid, int size) 434{ 435 struct an_softc *sc = device_get_softc(dev); 436 struct resource *res; 437 438 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 439 0ul, ~0ul, size, RF_ACTIVE); 440 if (res) { 441 sc->mem_aux_rid = rid; 442 sc->mem_aux_res = res; 443 sc->mem_aux_used = size; 444 return (0); 445 } else { 446 return (ENOENT); 447 } 448} 449 450/* 451 * Allocate an irq resource with the given resource id. 452 */ 453int 454an_alloc_irq(device_t dev, int rid, int flags) 455{ 456 struct an_softc *sc = device_get_softc(dev); 457 struct resource *res; 458 459 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 460 (RF_ACTIVE | flags)); 461 if (res) { 462 sc->irq_rid = rid; 463 sc->irq_res = res; 464 return (0); 465 } else { 466 return (ENOENT); 467 } 468} 469 470static void 471an_dma_malloc_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) 472{ 473 bus_addr_t *paddr = (bus_addr_t*) arg; 474 *paddr = segs->ds_addr; 475} 476 477/* 478 * Alloc DMA memory and set the pointer to it 479 */ 480static int 481an_dma_malloc(struct an_softc *sc, bus_size_t size, struct an_dma_alloc *dma, 482 int mapflags) 483{ 484 int r; 485 486 r = bus_dmamap_create(sc->an_dtag, BUS_DMA_NOWAIT, &dma->an_dma_map); 487 if (r != 0) 488 goto fail_0; 489 490 r = bus_dmamem_alloc(sc->an_dtag, (void**) &dma->an_dma_vaddr, 491 BUS_DMA_NOWAIT, &dma->an_dma_map); 492 if (r != 0) 493 goto fail_1; 494 495 r = bus_dmamap_load(sc->an_dtag, dma->an_dma_map, dma->an_dma_vaddr, 496 size, 497 an_dma_malloc_cb, 498 &dma->an_dma_paddr, 499 mapflags | BUS_DMA_NOWAIT); 500 if (r != 0) 501 goto fail_2; 502 503 dma->an_dma_size = size; 504 return (0); 505 506fail_2: 507 bus_dmamap_unload(sc->an_dtag, dma->an_dma_map); 508fail_1: 509 bus_dmamem_free(sc->an_dtag, dma->an_dma_vaddr, dma->an_dma_map); 510fail_0: 511 bus_dmamap_destroy(sc->an_dtag, dma->an_dma_map); 512 dma->an_dma_map = NULL; 513 return (r); 514} 515 516static void 517an_dma_free(struct an_softc *sc, struct an_dma_alloc *dma) 518{ 519 bus_dmamap_unload(sc->an_dtag, dma->an_dma_map); 520 bus_dmamem_free(sc->an_dtag, dma->an_dma_vaddr, dma->an_dma_map); 521 dma->an_dma_vaddr = 0; 522 bus_dmamap_destroy(sc->an_dtag, dma->an_dma_map); 523} 524 525/* 526 * Release all resources 527 */ 528void 529an_release_resources(device_t dev) 530{ 531 struct an_softc *sc = device_get_softc(dev); 532 int i; 533 534 if (sc->port_res) { 535 bus_release_resource(dev, SYS_RES_IOPORT, 536 sc->port_rid, sc->port_res); 537 sc->port_res = 0; 538 } 539 if (sc->mem_res) { 540 bus_release_resource(dev, SYS_RES_MEMORY, 541 sc->mem_rid, sc->mem_res); 542 sc->mem_res = 0; 543 } 544 if (sc->mem_aux_res) { 545 bus_release_resource(dev, SYS_RES_MEMORY, 546 sc->mem_aux_rid, sc->mem_aux_res); 547 sc->mem_aux_res = 0; 548 } 549 if (sc->irq_res) { 550 bus_release_resource(dev, SYS_RES_IRQ, 551 sc->irq_rid, sc->irq_res); 552 sc->irq_res = 0; 553 } 554 if (sc->an_rid_buffer.an_dma_paddr) { 555 an_dma_free(sc, &sc->an_rid_buffer); 556 } 557 for (i = 0; i < AN_MAX_RX_DESC; i++) 558 if (sc->an_rx_buffer[i].an_dma_paddr) { 559 an_dma_free(sc, &sc->an_rx_buffer[i]); 560 } 561 for (i = 0; i < AN_MAX_TX_DESC; i++) 562 if (sc->an_tx_buffer[i].an_dma_paddr) { 563 an_dma_free(sc, &sc->an_tx_buffer[i]); 564 } 565 if (sc->an_dtag) { 566 bus_dma_tag_destroy(sc->an_dtag); 567 } 568 569} 570 571int 572an_init_mpi350_desc(struct an_softc *sc) 573{ 574 struct an_command cmd_struct; 575 struct an_reply reply; 576 struct an_card_rid_desc an_rid_desc; 577 struct an_card_rx_desc an_rx_desc; 578 struct an_card_tx_desc an_tx_desc; 579 int i, desc; 580 581 AN_LOCK_ASSERT(sc); 582 if(!sc->an_rid_buffer.an_dma_paddr) 583 an_dma_malloc(sc, AN_RID_BUFFER_SIZE, 584 &sc->an_rid_buffer, 0); 585 for (i = 0; i < AN_MAX_RX_DESC; i++) 586 if(!sc->an_rx_buffer[i].an_dma_paddr) 587 an_dma_malloc(sc, AN_RX_BUFFER_SIZE, 588 &sc->an_rx_buffer[i], 0); 589 for (i = 0; i < AN_MAX_TX_DESC; i++) 590 if(!sc->an_tx_buffer[i].an_dma_paddr) 591 an_dma_malloc(sc, AN_TX_BUFFER_SIZE, 592 &sc->an_tx_buffer[i], 0); 593 594 /* 595 * Allocate RX descriptor 596 */ 597 bzero(&reply,sizeof(reply)); 598 cmd_struct.an_cmd = AN_CMD_ALLOC_DESC; 599 cmd_struct.an_parm0 = AN_DESCRIPTOR_RX; 600 cmd_struct.an_parm1 = AN_RX_DESC_OFFSET; 601 cmd_struct.an_parm2 = AN_MAX_RX_DESC; 602 if (an_cmd_struct(sc, &cmd_struct, &reply)) { 603 printf("an%d: failed to allocate RX descriptor\n", 604 sc->an_unit); 605 return(EIO); 606 } 607 608 for (desc = 0; desc < AN_MAX_RX_DESC; desc++) { 609 bzero(&an_rx_desc, sizeof(an_rx_desc)); 610 an_rx_desc.an_valid = 1; 611 an_rx_desc.an_len = AN_RX_BUFFER_SIZE; 612 an_rx_desc.an_done = 0; 613 an_rx_desc.an_phys = sc->an_rx_buffer[desc].an_dma_paddr; 614 615 for (i = 0; i < sizeof(an_rx_desc) / 4; i++) 616 CSR_MEM_AUX_WRITE_4(sc, AN_RX_DESC_OFFSET 617 + (desc * sizeof(an_rx_desc)) 618 + (i * 4), 619 ((u_int32_t *)(void *)&an_rx_desc)[i]); 620 } 621 622 /* 623 * Allocate TX descriptor 624 */ 625 626 bzero(&reply,sizeof(reply)); 627 cmd_struct.an_cmd = AN_CMD_ALLOC_DESC; 628 cmd_struct.an_parm0 = AN_DESCRIPTOR_TX; 629 cmd_struct.an_parm1 = AN_TX_DESC_OFFSET; 630 cmd_struct.an_parm2 = AN_MAX_TX_DESC; 631 if (an_cmd_struct(sc, &cmd_struct, &reply)) { 632 printf("an%d: failed to allocate TX descriptor\n", 633 sc->an_unit); 634 return(EIO); 635 } 636 637 for (desc = 0; desc < AN_MAX_TX_DESC; desc++) { 638 bzero(&an_tx_desc, sizeof(an_tx_desc)); 639 an_tx_desc.an_offset = 0; 640 an_tx_desc.an_eoc = 0; 641 an_tx_desc.an_valid = 0; 642 an_tx_desc.an_len = 0; 643 an_tx_desc.an_phys = sc->an_tx_buffer[desc].an_dma_paddr; 644 645 for (i = 0; i < sizeof(an_tx_desc) / 4; i++) 646 CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET 647 + (desc * sizeof(an_tx_desc)) 648 + (i * 4), 649 ((u_int32_t *)(void *)&an_tx_desc)[i]); 650 } 651 652 /* 653 * Allocate RID descriptor 654 */ 655 656 bzero(&reply,sizeof(reply)); 657 cmd_struct.an_cmd = AN_CMD_ALLOC_DESC; 658 cmd_struct.an_parm0 = AN_DESCRIPTOR_HOSTRW; 659 cmd_struct.an_parm1 = AN_HOST_DESC_OFFSET; 660 cmd_struct.an_parm2 = 1; 661 if (an_cmd_struct(sc, &cmd_struct, &reply)) { 662 printf("an%d: failed to allocate host descriptor\n", 663 sc->an_unit); 664 return(EIO); 665 } 666 667 bzero(&an_rid_desc, sizeof(an_rid_desc)); 668 an_rid_desc.an_valid = 1; 669 an_rid_desc.an_len = AN_RID_BUFFER_SIZE; 670 an_rid_desc.an_rid = 0; 671 an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr; 672 673 for (i = 0; i < sizeof(an_rid_desc) / 4; i++) 674 CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, 675 ((u_int32_t *)(void *)&an_rid_desc)[i]); 676 677 return(0); 678} 679 680int 681an_attach(struct an_softc *sc, int unit, int flags) 682{ 683 struct ifnet *ifp; 684 int error = EIO; 685 int i, nrate, mword; 686 u_int8_t r; 687 688 ifp = sc->an_ifp = if_alloc(IFT_ETHER); 689 if (ifp == NULL) { 690 printf("an%d: can not if_alloc()\n", sc->an_unit); 691 goto fail; 692 } 693 694 sc->an_gone = 0; 695 sc->an_associated = 0; 696 sc->an_monitor = 0; 697 sc->an_was_monitor = 0; 698 sc->an_flash_buffer = NULL; 699 700 /* Reset the NIC. */ 701 AN_LOCK(sc); 702 an_reset(sc); 703 if (sc->mpi350) { 704 error = an_init_mpi350_desc(sc); 705 if (error) 706 goto fail; 707 } 708 709 /* Load factory config */ 710 if (an_cmd(sc, AN_CMD_READCFG, 0)) { 711 printf("an%d: failed to load config data\n", sc->an_unit); 712 goto fail; 713 } 714 715 /* Read the current configuration */ 716 sc->an_config.an_type = AN_RID_GENCONFIG; 717 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 718 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 719 printf("an%d: read record failed\n", sc->an_unit); 720 goto fail; 721 } 722 723 /* Read the card capabilities */ 724 sc->an_caps.an_type = AN_RID_CAPABILITIES; 725 sc->an_caps.an_len = sizeof(struct an_ltv_caps); 726 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) { 727 printf("an%d: read record failed\n", sc->an_unit); 728 goto fail; 729 } 730 731 /* Read ssid list */ 732 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 733 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new); 734 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 735 printf("an%d: read record failed\n", sc->an_unit); 736 goto fail; 737 } 738 739 /* Read AP list */ 740 sc->an_aplist.an_type = AN_RID_APLIST; 741 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 742 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 743 printf("an%d: read record failed\n", sc->an_unit); 744 goto fail; 745 } 746 747#ifdef ANCACHE 748 /* Read the RSSI <-> dBm map */ 749 sc->an_have_rssimap = 0; 750 if (sc->an_caps.an_softcaps & 8) { 751 sc->an_rssimap.an_type = AN_RID_RSSI_MAP; 752 sc->an_rssimap.an_len = sizeof(struct an_ltv_rssi_map); 753 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_rssimap)) { 754 printf("an%d: unable to get RSSI <-> dBM map\n", sc->an_unit); 755 } else { 756 printf("an%d: got RSSI <-> dBM map\n", sc->an_unit); 757 sc->an_have_rssimap = 1; 758 } 759 } else { 760 printf("an%d: no RSSI <-> dBM map\n", sc->an_unit); 761 } 762#endif 763 AN_UNLOCK(sc); 764 765 ifp->if_softc = sc; 766 sc->an_unit = unit; 767 if_initname(ifp, device_get_name(sc->an_dev), 768 device_get_unit(sc->an_dev)); 769 ifp->if_mtu = ETHERMTU; 770 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 771 ifp->if_ioctl = an_ioctl; 772 ifp->if_start = an_start; 773 ifp->if_watchdog = an_watchdog; 774 ifp->if_init = an_init; 775 ifp->if_baudrate = 10000000; 776 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 777 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 778 IFQ_SET_READY(&ifp->if_snd); 779 780 bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename)); 781 bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename, 782 sizeof(AN_DEFAULT_NODENAME) - 1); 783 784 bzero(sc->an_ssidlist.an_entry[0].an_ssid, 785 sizeof(sc->an_ssidlist.an_entry[0].an_ssid)); 786 bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_entry[0].an_ssid, 787 sizeof(AN_DEFAULT_NETNAME) - 1); 788 sc->an_ssidlist.an_entry[0].an_len = strlen(AN_DEFAULT_NETNAME); 789 790 sc->an_config.an_opmode = 791 AN_OPMODE_INFRASTRUCTURE_STATION; 792 793 sc->an_tx_rate = 0; 794 bzero((char *)&sc->an_stats, sizeof(sc->an_stats)); 795 796 nrate = 8; 797 798 ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status); 799 if_printf(ifp, "supported rates: "); 800#define ADD(s, o) ifmedia_add(&sc->an_ifmedia, \ 801 IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL) 802 ADD(IFM_AUTO, 0); 803 ADD(IFM_AUTO, IFM_IEEE80211_ADHOC); 804 for (i = 0; i < nrate; i++) { 805 r = sc->an_caps.an_rates[i]; 806 mword = ieee80211_rate2media(NULL, r, IEEE80211_T_DS); 807 if (mword == 0) 808 continue; 809 printf("%s%d%sMbps", (i != 0 ? " " : ""), 810 (r & IEEE80211_RATE_VAL) / 2, ((r & 0x1) != 0 ? ".5" : "")); 811 ADD(mword, 0); 812 ADD(mword, IFM_IEEE80211_ADHOC); 813 } 814 printf("\n"); 815 ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, 816 IFM_AUTO, 0, 0)); 817#undef ADD 818 819 /* 820 * Call MI attach routine. 821 */ 822 823 ether_ifattach(ifp, sc->an_caps.an_oemaddr); 824 callout_init_mtx(&sc->an_stat_ch, &sc->an_mtx, 0); 825 826 return(0); 827fail: 828 AN_UNLOCK(sc); 829 mtx_destroy(&sc->an_mtx); 830 if (ifp != NULL) 831 if_free(ifp); 832 return(error); 833} 834 835int 836an_detach(device_t dev) 837{ 838 struct an_softc *sc = device_get_softc(dev); 839 struct ifnet *ifp = sc->an_ifp; 840 841 if (sc->an_gone) { 842 device_printf(dev,"already unloaded\n"); 843 return(0); 844 } 845 AN_LOCK(sc); 846 an_stop(sc); 847 sc->an_gone = 1; 848 ifmedia_removeall(&sc->an_ifmedia); 849 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 850 AN_UNLOCK(sc); 851 ether_ifdetach(ifp); 852 bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); 853 callout_drain(&sc->an_stat_ch); 854 if_free(ifp); 855 an_release_resources(dev); 856 mtx_destroy(&sc->an_mtx); 857 return (0); 858} 859 860static void 861an_rxeof(struct an_softc *sc) 862{ 863 struct ifnet *ifp; 864 struct ether_header *eh; 865 struct ieee80211_frame *ih; 866 struct an_rxframe rx_frame; 867 struct an_rxframe_802_3 rx_frame_802_3; 868 struct mbuf *m; 869 int len, id, error = 0, i, count = 0; 870 int ieee80211_header_len; 871 u_char *bpf_buf; 872 u_short fc1; 873 struct an_card_rx_desc an_rx_desc; 874 u_int8_t *buf; 875 876 AN_LOCK_ASSERT(sc); 877 878 ifp = sc->an_ifp; 879 880 if (!sc->mpi350) { 881 id = CSR_READ_2(sc, AN_RX_FID); 882 883 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 884 /* read raw 802.11 packet */ 885 bpf_buf = sc->buf_802_11; 886 887 /* read header */ 888 if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame, 889 sizeof(rx_frame))) { 890 ifp->if_ierrors++; 891 return; 892 } 893 894 /* 895 * skip beacon by default since this increases the 896 * system load a lot 897 */ 898 899 if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) && 900 (rx_frame.an_frame_ctl & 901 IEEE80211_FC0_SUBTYPE_BEACON)) { 902 return; 903 } 904 905 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 906 len = rx_frame.an_rx_payload_len 907 + sizeof(rx_frame); 908 /* Check for insane frame length */ 909 if (len > sizeof(sc->buf_802_11)) { 910 printf("an%d: oversized packet " 911 "received (%d, %d)\n", 912 sc->an_unit, len, MCLBYTES); 913 ifp->if_ierrors++; 914 return; 915 } 916 917 bcopy((char *)&rx_frame, 918 bpf_buf, sizeof(rx_frame)); 919 920 error = an_read_data(sc, id, sizeof(rx_frame), 921 (caddr_t)bpf_buf+sizeof(rx_frame), 922 rx_frame.an_rx_payload_len); 923 } else { 924 fc1=rx_frame.an_frame_ctl >> 8; 925 ieee80211_header_len = 926 sizeof(struct ieee80211_frame); 927 if ((fc1 & IEEE80211_FC1_DIR_TODS) && 928 (fc1 & IEEE80211_FC1_DIR_FROMDS)) { 929 ieee80211_header_len += ETHER_ADDR_LEN; 930 } 931 932 len = rx_frame.an_rx_payload_len 933 + ieee80211_header_len; 934 /* Check for insane frame length */ 935 if (len > sizeof(sc->buf_802_11)) { 936 printf("an%d: oversized packet " 937 "received (%d, %d)\n", 938 sc->an_unit, len, MCLBYTES); 939 ifp->if_ierrors++; 940 return; 941 } 942 943 ih = (struct ieee80211_frame *)bpf_buf; 944 945 bcopy((char *)&rx_frame.an_frame_ctl, 946 (char *)ih, ieee80211_header_len); 947 948 error = an_read_data(sc, id, sizeof(rx_frame) + 949 rx_frame.an_gaplen, 950 (caddr_t)ih +ieee80211_header_len, 951 rx_frame.an_rx_payload_len); 952 } 953 /* dump raw 802.11 packet to bpf and skip ip stack */ 954 BPF_TAP(ifp, bpf_buf, len); 955 } else { 956 MGETHDR(m, M_DONTWAIT, MT_DATA); 957 if (m == NULL) { 958 ifp->if_ierrors++; 959 return; 960 } 961 MCLGET(m, M_DONTWAIT); 962 if (!(m->m_flags & M_EXT)) { 963 m_freem(m); 964 ifp->if_ierrors++; 965 return; 966 } 967 m->m_pkthdr.rcvif = ifp; 968 /* Read Ethernet encapsulated packet */ 969 970#ifdef ANCACHE 971 /* Read NIC frame header */ 972 if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, 973 sizeof(rx_frame))) { 974 m_freem(m); 975 ifp->if_ierrors++; 976 return; 977 } 978#endif 979 /* Read in the 802_3 frame header */ 980 if (an_read_data(sc, id, 0x34, 981 (caddr_t)&rx_frame_802_3, 982 sizeof(rx_frame_802_3))) { 983 m_freem(m); 984 ifp->if_ierrors++; 985 return; 986 } 987 if (rx_frame_802_3.an_rx_802_3_status != 0) { 988 m_freem(m); 989 ifp->if_ierrors++; 990 return; 991 } 992 /* Check for insane frame length */ 993 len = rx_frame_802_3.an_rx_802_3_payload_len; 994 if (len > sizeof(sc->buf_802_11)) { 995 m_freem(m); 996 printf("an%d: oversized packet " 997 "received (%d, %d)\n", 998 sc->an_unit, len, MCLBYTES); 999 ifp->if_ierrors++; 1000 return; 1001 } 1002 m->m_pkthdr.len = m->m_len = 1003 rx_frame_802_3.an_rx_802_3_payload_len + 12; 1004 1005 eh = mtod(m, struct ether_header *); 1006 1007 bcopy((char *)&rx_frame_802_3.an_rx_dst_addr, 1008 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 1009 bcopy((char *)&rx_frame_802_3.an_rx_src_addr, 1010 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 1011 1012 /* in mbuf header type is just before payload */ 1013 error = an_read_data(sc, id, 0x44, 1014 (caddr_t)&(eh->ether_type), 1015 rx_frame_802_3.an_rx_802_3_payload_len); 1016 1017 if (error) { 1018 m_freem(m); 1019 ifp->if_ierrors++; 1020 return; 1021 } 1022 ifp->if_ipackets++; 1023 1024 /* Receive packet. */ 1025#ifdef ANCACHE 1026 an_cache_store(sc, eh, m, 1027 rx_frame.an_rx_signal_strength, 1028 rx_frame.an_rsvd0); 1029#endif 1030 AN_UNLOCK(sc); 1031 (*ifp->if_input)(ifp, m); 1032 AN_LOCK(sc); 1033 } 1034 1035 } else { /* MPI-350 */ 1036 for (count = 0; count < AN_MAX_RX_DESC; count++){ 1037 for (i = 0; i < sizeof(an_rx_desc) / 4; i++) 1038 ((u_int32_t *)(void *)&an_rx_desc)[i] 1039 = CSR_MEM_AUX_READ_4(sc, 1040 AN_RX_DESC_OFFSET 1041 + (count * sizeof(an_rx_desc)) 1042 + (i * 4)); 1043 1044 if (an_rx_desc.an_done && !an_rx_desc.an_valid) { 1045 buf = sc->an_rx_buffer[count].an_dma_vaddr; 1046 1047 MGETHDR(m, M_DONTWAIT, MT_DATA); 1048 if (m == NULL) { 1049 ifp->if_ierrors++; 1050 return; 1051 } 1052 MCLGET(m, M_DONTWAIT); 1053 if (!(m->m_flags & M_EXT)) { 1054 m_freem(m); 1055 ifp->if_ierrors++; 1056 return; 1057 } 1058 m->m_pkthdr.rcvif = ifp; 1059 /* Read Ethernet encapsulated packet */ 1060 1061 /* 1062 * No ANCACHE support since we just get back 1063 * an Ethernet packet no 802.11 info 1064 */ 1065#if 0 1066#ifdef ANCACHE 1067 /* Read NIC frame header */ 1068 bcopy(buf, (caddr_t)&rx_frame, 1069 sizeof(rx_frame)); 1070#endif 1071#endif 1072 /* Check for insane frame length */ 1073 len = an_rx_desc.an_len + 12; 1074 if (len > MCLBYTES) { 1075 m_freem(m); 1076 printf("an%d: oversized packet " 1077 "received (%d, %d)\n", 1078 sc->an_unit, len, MCLBYTES); 1079 ifp->if_ierrors++; 1080 return; 1081 } 1082 1083 m->m_pkthdr.len = m->m_len = 1084 an_rx_desc.an_len + 12; 1085 1086 eh = mtod(m, struct ether_header *); 1087 1088 bcopy(buf, (char *)eh, 1089 m->m_pkthdr.len); 1090 1091 ifp->if_ipackets++; 1092 1093 /* Receive packet. */ 1094#if 0 1095#ifdef ANCACHE 1096 an_cache_store(sc, eh, m, 1097 rx_frame.an_rx_signal_strength, 1098 rx_frame.an_rsvd0); 1099#endif 1100#endif 1101 AN_UNLOCK(sc); 1102 (*ifp->if_input)(ifp, m); 1103 AN_LOCK(sc); 1104 1105 an_rx_desc.an_valid = 1; 1106 an_rx_desc.an_len = AN_RX_BUFFER_SIZE; 1107 an_rx_desc.an_done = 0; 1108 an_rx_desc.an_phys = 1109 sc->an_rx_buffer[count].an_dma_paddr; 1110 1111 for (i = 0; i < sizeof(an_rx_desc) / 4; i++) 1112 CSR_MEM_AUX_WRITE_4(sc, 1113 AN_RX_DESC_OFFSET 1114 + (count * sizeof(an_rx_desc)) 1115 + (i * 4), 1116 ((u_int32_t *)(void *)&an_rx_desc)[i]); 1117 1118 } else { 1119 printf("an%d: Didn't get valid RX packet " 1120 "%x %x %d\n", 1121 sc->an_unit, 1122 an_rx_desc.an_done, 1123 an_rx_desc.an_valid, an_rx_desc.an_len); 1124 } 1125 } 1126 } 1127} 1128 1129static void 1130an_txeof(struct an_softc *sc, int status) 1131{ 1132 struct ifnet *ifp; 1133 int id, i; 1134 1135 AN_LOCK_ASSERT(sc); 1136 ifp = sc->an_ifp; 1137 1138 ifp->if_timer = 0; 1139 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1140 1141 if (!sc->mpi350) { 1142 id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350)); 1143 1144 if (status & AN_EV_TX_EXC) { 1145 ifp->if_oerrors++; 1146 } else 1147 ifp->if_opackets++; 1148 1149 for (i = 0; i < AN_TX_RING_CNT; i++) { 1150 if (id == sc->an_rdata.an_tx_ring[i]) { 1151 sc->an_rdata.an_tx_ring[i] = 0; 1152 break; 1153 } 1154 } 1155 1156 AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT); 1157 } else { /* MPI 350 */ 1158 id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350)); 1159 if (!sc->an_rdata.an_tx_empty){ 1160 if (status & AN_EV_TX_EXC) { 1161 ifp->if_oerrors++; 1162 } else 1163 ifp->if_opackets++; 1164 AN_INC(sc->an_rdata.an_tx_cons, AN_MAX_TX_DESC); 1165 if (sc->an_rdata.an_tx_prod == 1166 sc->an_rdata.an_tx_cons) 1167 sc->an_rdata.an_tx_empty = 1; 1168 } 1169 } 1170 1171 return; 1172} 1173 1174/* 1175 * We abuse the stats updater to check the current NIC status. This 1176 * is important because we don't want to allow transmissions until 1177 * the NIC has synchronized to the current cell (either as the master 1178 * in an ad-hoc group, or as a station connected to an access point). 1179 * 1180 * Note that this function will be called via callout(9) with a lock held. 1181 */ 1182static void 1183an_stats_update(void *xsc) 1184{ 1185 struct an_softc *sc; 1186 struct ifnet *ifp; 1187 1188 sc = xsc; 1189 AN_LOCK_ASSERT(sc); 1190 ifp = sc->an_ifp; 1191 1192 sc->an_status.an_type = AN_RID_STATUS; 1193 sc->an_status.an_len = sizeof(struct an_ltv_status); 1194 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_status)) 1195 return; 1196 1197 if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC) 1198 sc->an_associated = 1; 1199 else 1200 sc->an_associated = 0; 1201 1202 /* Don't do this while we're transmitting */ 1203 if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { 1204 callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc); 1205 return; 1206 } 1207 1208 sc->an_stats.an_len = sizeof(struct an_ltv_stats); 1209 sc->an_stats.an_type = AN_RID_32BITS_CUM; 1210 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len)) 1211 return; 1212 1213 callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc); 1214 1215 return; 1216} 1217 1218void 1219an_intr(void *xsc) 1220{ 1221 struct an_softc *sc; 1222 struct ifnet *ifp; 1223 u_int16_t status; 1224 1225 sc = (struct an_softc*)xsc; 1226 1227 AN_LOCK(sc); 1228 1229 if (sc->an_gone) { 1230 AN_UNLOCK(sc); 1231 return; 1232 } 1233 1234 ifp = sc->an_ifp; 1235 1236 /* Disable interrupts. */ 1237 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0); 1238 1239 status = CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)); 1240 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), ~AN_INTRS(sc->mpi350)); 1241 1242 if (status & AN_EV_MIC) { 1243 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_MIC); 1244 } 1245 1246 if (status & AN_EV_LINKSTAT) { 1247 if (CSR_READ_2(sc, AN_LINKSTAT(sc->mpi350)) 1248 == AN_LINKSTAT_ASSOCIATED) 1249 sc->an_associated = 1; 1250 else 1251 sc->an_associated = 0; 1252 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_LINKSTAT); 1253 } 1254 1255 if (status & AN_EV_RX) { 1256 an_rxeof(sc); 1257 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_RX); 1258 } 1259 1260 if (sc->mpi350 && status & AN_EV_TX_CPY) { 1261 an_txeof(sc, status); 1262 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX_CPY); 1263 } 1264 1265 if (status & AN_EV_TX) { 1266 an_txeof(sc, status); 1267 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX); 1268 } 1269 1270 if (status & AN_EV_TX_EXC) { 1271 an_txeof(sc, status); 1272 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX_EXC); 1273 } 1274 1275 if (status & AN_EV_ALLOC) 1276 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC); 1277 1278 /* Re-enable interrupts. */ 1279 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350)); 1280 1281 if ((ifp->if_flags & IFF_UP) && !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1282 an_start(ifp); 1283 1284 AN_UNLOCK(sc); 1285 1286 return; 1287} 1288 1289 1290static int 1291an_cmd_struct(struct an_softc *sc, struct an_command *cmd, 1292 struct an_reply *reply) 1293{ 1294 int i; 1295 1296 AN_LOCK_ASSERT(sc); 1297 for (i = 0; i != AN_TIMEOUT; i++) { 1298 if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { 1299 DELAY(1000); 1300 } else 1301 break; 1302 } 1303 1304 if( i == AN_TIMEOUT) { 1305 printf("BUSY\n"); 1306 return(ETIMEDOUT); 1307 } 1308 1309 CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), cmd->an_parm0); 1310 CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), cmd->an_parm1); 1311 CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), cmd->an_parm2); 1312 CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd->an_cmd); 1313 1314 for (i = 0; i < AN_TIMEOUT; i++) { 1315 if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD) 1316 break; 1317 DELAY(1000); 1318 } 1319 1320 reply->an_resp0 = CSR_READ_2(sc, AN_RESP0(sc->mpi350)); 1321 reply->an_resp1 = CSR_READ_2(sc, AN_RESP1(sc->mpi350)); 1322 reply->an_resp2 = CSR_READ_2(sc, AN_RESP2(sc->mpi350)); 1323 reply->an_status = CSR_READ_2(sc, AN_STATUS(sc->mpi350)); 1324 1325 if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) 1326 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 1327 AN_EV_CLR_STUCK_BUSY); 1328 1329 /* Ack the command */ 1330 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD); 1331 1332 if (i == AN_TIMEOUT) 1333 return(ETIMEDOUT); 1334 1335 return(0); 1336} 1337 1338static int 1339an_cmd(struct an_softc *sc, int cmd, int val) 1340{ 1341 int i, s = 0; 1342 1343 AN_LOCK_ASSERT(sc); 1344 CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), val); 1345 CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), 0); 1346 CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), 0); 1347 CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd); 1348 1349 for (i = 0; i < AN_TIMEOUT; i++) { 1350 if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD) 1351 break; 1352 else { 1353 if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) == cmd) 1354 CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd); 1355 } 1356 } 1357 1358 for (i = 0; i < AN_TIMEOUT; i++) { 1359 CSR_READ_2(sc, AN_RESP0(sc->mpi350)); 1360 CSR_READ_2(sc, AN_RESP1(sc->mpi350)); 1361 CSR_READ_2(sc, AN_RESP2(sc->mpi350)); 1362 s = CSR_READ_2(sc, AN_STATUS(sc->mpi350)); 1363 if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE)) 1364 break; 1365 } 1366 1367 /* Ack the command */ 1368 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD); 1369 1370 if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) 1371 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CLR_STUCK_BUSY); 1372 1373 if (i == AN_TIMEOUT) 1374 return(ETIMEDOUT); 1375 1376 return(0); 1377} 1378 1379/* 1380 * This reset sequence may look a little strange, but this is the 1381 * most reliable method I've found to really kick the NIC in the 1382 * head and force it to reboot correctly. 1383 */ 1384static void 1385an_reset(struct an_softc *sc) 1386{ 1387 if (sc->an_gone) 1388 return; 1389 1390 AN_LOCK_ASSERT(sc); 1391 an_cmd(sc, AN_CMD_ENABLE, 0); 1392 an_cmd(sc, AN_CMD_FW_RESTART, 0); 1393 an_cmd(sc, AN_CMD_NOOP2, 0); 1394 1395 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) 1396 printf("an%d: reset failed\n", sc->an_unit); 1397 1398 an_cmd(sc, AN_CMD_DISABLE, 0); 1399 1400 return; 1401} 1402 1403/* 1404 * Read an LTV record from the NIC. 1405 */ 1406static int 1407an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) 1408{ 1409 struct an_ltv_gen *an_ltv; 1410 struct an_card_rid_desc an_rid_desc; 1411 struct an_command cmd; 1412 struct an_reply reply; 1413 u_int16_t *ptr; 1414 u_int8_t *ptr2; 1415 int i, len; 1416 1417 AN_LOCK_ASSERT(sc); 1418 if (ltv->an_len < 4 || ltv->an_type == 0) 1419 return(EINVAL); 1420 1421 if (!sc->mpi350){ 1422 /* Tell the NIC to enter record read mode. */ 1423 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) { 1424 printf("an%d: RID access failed\n", sc->an_unit); 1425 return(EIO); 1426 } 1427 1428 /* Seek to the record. */ 1429 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) { 1430 printf("an%d: seek to record failed\n", sc->an_unit); 1431 return(EIO); 1432 } 1433 1434 /* 1435 * Read the length and record type and make sure they 1436 * match what we expect (this verifies that we have enough 1437 * room to hold all of the returned data). 1438 * Length includes type but not length. 1439 */ 1440 len = CSR_READ_2(sc, AN_DATA1); 1441 if (len > (ltv->an_len - 2)) { 1442 printf("an%d: record length mismatch -- expected %d, " 1443 "got %d for Rid %x\n", sc->an_unit, 1444 ltv->an_len - 2, len, ltv->an_type); 1445 len = ltv->an_len - 2; 1446 } else { 1447 ltv->an_len = len + 2; 1448 } 1449 1450 /* Now read the data. */ 1451 len -= 2; /* skip the type */ 1452 ptr = <v->an_val; 1453 for (i = len; i > 1; i -= 2) 1454 *ptr++ = CSR_READ_2(sc, AN_DATA1); 1455 if (i) { 1456 ptr2 = (u_int8_t *)ptr; 1457 *ptr2 = CSR_READ_1(sc, AN_DATA1); 1458 } 1459 } else { /* MPI-350 */ 1460 if (!sc->an_rid_buffer.an_dma_vaddr) 1461 return(EIO); 1462 an_rid_desc.an_valid = 1; 1463 an_rid_desc.an_len = AN_RID_BUFFER_SIZE; 1464 an_rid_desc.an_rid = 0; 1465 an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr; 1466 bzero(sc->an_rid_buffer.an_dma_vaddr, AN_RID_BUFFER_SIZE); 1467 1468 bzero(&cmd, sizeof(cmd)); 1469 bzero(&reply, sizeof(reply)); 1470 cmd.an_cmd = AN_CMD_ACCESS|AN_ACCESS_READ; 1471 cmd.an_parm0 = ltv->an_type; 1472 1473 for (i = 0; i < sizeof(an_rid_desc) / 4; i++) 1474 CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, 1475 ((u_int32_t *)(void *)&an_rid_desc)[i]); 1476 1477 if (an_cmd_struct(sc, &cmd, &reply) 1478 || reply.an_status & AN_CMD_QUAL_MASK) { 1479 printf("an%d: failed to read RID %x %x %x %x %x, %d\n", 1480 sc->an_unit, ltv->an_type, 1481 reply.an_status, 1482 reply.an_resp0, 1483 reply.an_resp1, 1484 reply.an_resp2, 1485 i); 1486 return(EIO); 1487 } 1488 1489 an_ltv = (struct an_ltv_gen *)sc->an_rid_buffer.an_dma_vaddr; 1490 if (an_ltv->an_len + 2 < an_rid_desc.an_len) { 1491 an_rid_desc.an_len = an_ltv->an_len; 1492 } 1493 1494 len = an_rid_desc.an_len; 1495 if (len > (ltv->an_len - 2)) { 1496 printf("an%d: record length mismatch -- expected %d, " 1497 "got %d for Rid %x\n", sc->an_unit, 1498 ltv->an_len - 2, len, ltv->an_type); 1499 len = ltv->an_len - 2; 1500 } else { 1501 ltv->an_len = len + 2; 1502 } 1503 bcopy(&an_ltv->an_type, 1504 <v->an_val, 1505 len); 1506 } 1507 1508 if (an_dump) 1509 an_dump_record(sc, ltv, "Read"); 1510 1511 return(0); 1512} 1513 1514/* 1515 * Same as read, except we inject data instead of reading it. 1516 */ 1517static int 1518an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) 1519{ 1520 struct an_card_rid_desc an_rid_desc; 1521 struct an_command cmd; 1522 struct an_reply reply; 1523 u_int16_t *ptr; 1524 u_int8_t *ptr2; 1525 int i, len; 1526 1527 AN_LOCK_ASSERT(sc); 1528 if (an_dump) 1529 an_dump_record(sc, ltv, "Write"); 1530 1531 if (!sc->mpi350){ 1532 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) 1533 return(EIO); 1534 1535 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) 1536 return(EIO); 1537 1538 /* 1539 * Length includes type but not length. 1540 */ 1541 len = ltv->an_len - 2; 1542 CSR_WRITE_2(sc, AN_DATA1, len); 1543 1544 len -= 2; /* skip the type */ 1545 ptr = <v->an_val; 1546 for (i = len; i > 1; i -= 2) 1547 CSR_WRITE_2(sc, AN_DATA1, *ptr++); 1548 if (i) { 1549 ptr2 = (u_int8_t *)ptr; 1550 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 1551 } 1552 1553 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) 1554 return(EIO); 1555 } else { 1556 /* MPI-350 */ 1557 1558 for (i = 0; i != AN_TIMEOUT; i++) { 1559 if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) 1560 & AN_CMD_BUSY) { 1561 DELAY(10); 1562 } else 1563 break; 1564 } 1565 if (i == AN_TIMEOUT) { 1566 printf("BUSY\n"); 1567 } 1568 1569 an_rid_desc.an_valid = 1; 1570 an_rid_desc.an_len = ltv->an_len - 2; 1571 an_rid_desc.an_rid = ltv->an_type; 1572 an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr; 1573 1574 bcopy(<v->an_type, sc->an_rid_buffer.an_dma_vaddr, 1575 an_rid_desc.an_len); 1576 1577 bzero(&cmd,sizeof(cmd)); 1578 bzero(&reply,sizeof(reply)); 1579 cmd.an_cmd = AN_CMD_ACCESS|AN_ACCESS_WRITE; 1580 cmd.an_parm0 = ltv->an_type; 1581 1582 for (i = 0; i < sizeof(an_rid_desc) / 4; i++) 1583 CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, 1584 ((u_int32_t *)(void *)&an_rid_desc)[i]); 1585 1586 DELAY(100000); 1587 1588 if ((i = an_cmd_struct(sc, &cmd, &reply))) { 1589 printf("an%d: failed to write RID 1 %x %x %x %x %x, %d\n", 1590 sc->an_unit, ltv->an_type, 1591 reply.an_status, 1592 reply.an_resp0, 1593 reply.an_resp1, 1594 reply.an_resp2, 1595 i); 1596 return(EIO); 1597 } 1598 1599 1600 if (reply.an_status & AN_CMD_QUAL_MASK) { 1601 printf("an%d: failed to write RID 2 %x %x %x %x %x, %d\n", 1602 sc->an_unit, ltv->an_type, 1603 reply.an_status, 1604 reply.an_resp0, 1605 reply.an_resp1, 1606 reply.an_resp2, 1607 i); 1608 return(EIO); 1609 } 1610 DELAY(100000); 1611 } 1612 1613 return(0); 1614} 1615 1616static void 1617an_dump_record(struct an_softc *sc, struct an_ltv_gen *ltv, char *string) 1618{ 1619 u_int8_t *ptr2; 1620 int len; 1621 int i; 1622 int count = 0; 1623 char buf[17], temp; 1624 1625 len = ltv->an_len - 4; 1626 printf("an%d: RID %4x, Length %4d, Mode %s\n", 1627 sc->an_unit, ltv->an_type, ltv->an_len - 4, string); 1628 1629 if (an_dump == 1 || (an_dump == ltv->an_type)) { 1630 printf("an%d:\t", sc->an_unit); 1631 bzero(buf,sizeof(buf)); 1632 1633 ptr2 = (u_int8_t *)<v->an_val; 1634 for (i = len; i > 0; i--) { 1635 printf("%02x ", *ptr2); 1636 1637 temp = *ptr2++; 1638 if (isprint(temp)) 1639 buf[count] = temp; 1640 else 1641 buf[count] = '.'; 1642 if (++count == 16) { 1643 count = 0; 1644 printf("%s\n",buf); 1645 printf("an%d:\t", sc->an_unit); 1646 bzero(buf,sizeof(buf)); 1647 } 1648 } 1649 for (; count != 16; count++) { 1650 printf(" "); 1651 } 1652 printf(" %s\n",buf); 1653 } 1654} 1655 1656static int 1657an_seek(struct an_softc *sc, int id, int off, int chan) 1658{ 1659 int i; 1660 int selreg, offreg; 1661 1662 switch (chan) { 1663 case AN_BAP0: 1664 selreg = AN_SEL0; 1665 offreg = AN_OFF0; 1666 break; 1667 case AN_BAP1: 1668 selreg = AN_SEL1; 1669 offreg = AN_OFF1; 1670 break; 1671 default: 1672 printf("an%d: invalid data path: %x\n", sc->an_unit, chan); 1673 return(EIO); 1674 } 1675 1676 CSR_WRITE_2(sc, selreg, id); 1677 CSR_WRITE_2(sc, offreg, off); 1678 1679 for (i = 0; i < AN_TIMEOUT; i++) { 1680 if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR))) 1681 break; 1682 } 1683 1684 if (i == AN_TIMEOUT) 1685 return(ETIMEDOUT); 1686 1687 return(0); 1688} 1689 1690static int 1691an_read_data(struct an_softc *sc, int id, int off, caddr_t buf, int len) 1692{ 1693 int i; 1694 u_int16_t *ptr; 1695 u_int8_t *ptr2; 1696 1697 if (off != -1) { 1698 if (an_seek(sc, id, off, AN_BAP1)) 1699 return(EIO); 1700 } 1701 1702 ptr = (u_int16_t *)buf; 1703 for (i = len; i > 1; i -= 2) 1704 *ptr++ = CSR_READ_2(sc, AN_DATA1); 1705 if (i) { 1706 ptr2 = (u_int8_t *)ptr; 1707 *ptr2 = CSR_READ_1(sc, AN_DATA1); 1708 } 1709 1710 return(0); 1711} 1712 1713static int 1714an_write_data(struct an_softc *sc, int id, int off, caddr_t buf, int len) 1715{ 1716 int i; 1717 u_int16_t *ptr; 1718 u_int8_t *ptr2; 1719 1720 if (off != -1) { 1721 if (an_seek(sc, id, off, AN_BAP0)) 1722 return(EIO); 1723 } 1724 1725 ptr = (u_int16_t *)buf; 1726 for (i = len; i > 1; i -= 2) 1727 CSR_WRITE_2(sc, AN_DATA0, *ptr++); 1728 if (i) { 1729 ptr2 = (u_int8_t *)ptr; 1730 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 1731 } 1732 1733 return(0); 1734} 1735 1736/* 1737 * Allocate a region of memory inside the NIC and zero 1738 * it out. 1739 */ 1740static int 1741an_alloc_nicmem(struct an_softc *sc, int len, int *id) 1742{ 1743 int i; 1744 1745 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 1746 printf("an%d: failed to allocate %d bytes on NIC\n", 1747 sc->an_unit, len); 1748 return(ENOMEM); 1749 } 1750 1751 for (i = 0; i < AN_TIMEOUT; i++) { 1752 if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_ALLOC) 1753 break; 1754 } 1755 1756 if (i == AN_TIMEOUT) 1757 return(ETIMEDOUT); 1758 1759 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC); 1760 *id = CSR_READ_2(sc, AN_ALLOC_FID); 1761 1762 if (an_seek(sc, *id, 0, AN_BAP0)) 1763 return(EIO); 1764 1765 for (i = 0; i < len / 2; i++) 1766 CSR_WRITE_2(sc, AN_DATA0, 0); 1767 1768 return(0); 1769} 1770 1771static void 1772an_setdef(struct an_softc *sc, struct an_req *areq) 1773{ 1774 struct ifnet *ifp; 1775 struct an_ltv_genconfig *cfg; 1776 struct an_ltv_ssidlist_new *ssid; 1777 struct an_ltv_aplist *ap; 1778 struct an_ltv_gen *sp; 1779 1780 ifp = sc->an_ifp; 1781 1782 AN_LOCK_ASSERT(sc); 1783 switch (areq->an_type) { 1784 case AN_RID_GENCONFIG: 1785 cfg = (struct an_ltv_genconfig *)areq; 1786 1787 bcopy((char *)&cfg->an_macaddr, IF_LLADDR(sc->an_ifp), 1788 ETHER_ADDR_LEN); 1789 1790 bcopy((char *)cfg, (char *)&sc->an_config, 1791 sizeof(struct an_ltv_genconfig)); 1792 break; 1793 case AN_RID_SSIDLIST: 1794 ssid = (struct an_ltv_ssidlist_new *)areq; 1795 bcopy((char *)ssid, (char *)&sc->an_ssidlist, 1796 sizeof(struct an_ltv_ssidlist_new)); 1797 break; 1798 case AN_RID_APLIST: 1799 ap = (struct an_ltv_aplist *)areq; 1800 bcopy((char *)ap, (char *)&sc->an_aplist, 1801 sizeof(struct an_ltv_aplist)); 1802 break; 1803 case AN_RID_TX_SPEED: 1804 sp = (struct an_ltv_gen *)areq; 1805 sc->an_tx_rate = sp->an_val; 1806 1807 /* Read the current configuration */ 1808 sc->an_config.an_type = AN_RID_GENCONFIG; 1809 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 1810 an_read_record(sc, (struct an_ltv_gen *)&sc->an_config); 1811 cfg = &sc->an_config; 1812 1813 /* clear other rates and set the only one we want */ 1814 bzero(cfg->an_rates, sizeof(cfg->an_rates)); 1815 cfg->an_rates[0] = sc->an_tx_rate; 1816 1817 /* Save the new rate */ 1818 sc->an_config.an_type = AN_RID_GENCONFIG; 1819 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 1820 break; 1821 case AN_RID_WEP_TEMP: 1822 /* Cache the temp keys */ 1823 bcopy(areq, 1824 &sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex], 1825 sizeof(struct an_ltv_key)); 1826 case AN_RID_WEP_PERM: 1827 case AN_RID_LEAPUSERNAME: 1828 case AN_RID_LEAPPASSWORD: 1829 AN_UNLOCK(sc); 1830 an_init(sc); 1831 AN_LOCK(sc); 1832 1833 /* Disable the MAC. */ 1834 an_cmd(sc, AN_CMD_DISABLE, 0); 1835 1836 /* Write the key */ 1837 an_write_record(sc, (struct an_ltv_gen *)areq); 1838 1839 /* Turn the MAC back on. */ 1840 an_cmd(sc, AN_CMD_ENABLE, 0); 1841 1842 break; 1843 case AN_RID_MONITOR_MODE: 1844 cfg = (struct an_ltv_genconfig *)areq; 1845 bpfdetach(ifp); 1846 if (ng_ether_detach_p != NULL) 1847 (*ng_ether_detach_p) (ifp); 1848 sc->an_monitor = cfg->an_len; 1849 1850 if (sc->an_monitor & AN_MONITOR) { 1851 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 1852 bpfattach(ifp, DLT_AIRONET_HEADER, 1853 sizeof(struct ether_header)); 1854 } else { 1855 bpfattach(ifp, DLT_IEEE802_11, 1856 sizeof(struct ether_header)); 1857 } 1858 } else { 1859 bpfattach(ifp, DLT_EN10MB, 1860 sizeof(struct ether_header)); 1861 if (ng_ether_attach_p != NULL) 1862 (*ng_ether_attach_p) (ifp); 1863 } 1864 break; 1865 default: 1866 printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type); 1867 return; 1868 } 1869 1870 1871 /* Reinitialize the card. */ 1872 if (ifp->if_flags) { 1873 AN_UNLOCK(sc); 1874 an_init(sc); 1875 AN_LOCK(sc); 1876 } 1877 1878 return; 1879} 1880 1881/* 1882 * Derived from Linux driver to enable promiscious mode. 1883 */ 1884 1885static void 1886an_promisc(struct an_softc *sc, int promisc) 1887{ 1888 AN_LOCK_ASSERT(sc); 1889 if (sc->an_was_monitor) { 1890 an_reset(sc); 1891 if (sc->mpi350) 1892 an_init_mpi350_desc(sc); 1893 } 1894 if (sc->an_monitor || sc->an_was_monitor) { 1895 AN_UNLOCK(sc); 1896 an_init(sc); 1897 AN_LOCK(sc); 1898 } 1899 1900 sc->an_was_monitor = sc->an_monitor; 1901 an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0); 1902 1903 return; 1904} 1905 1906static int 1907an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 1908{ 1909 int error = 0; 1910 int len; 1911 int i, max; 1912 struct an_softc *sc; 1913 struct ifreq *ifr; 1914 struct thread *td = curthread; 1915 struct ieee80211req *ireq; 1916 struct ieee80211_channel ch; 1917 u_int8_t tmpstr[IEEE80211_NWID_LEN*2]; 1918 u_int8_t *tmpptr; 1919 struct an_ltv_genconfig *config; 1920 struct an_ltv_key *key; 1921 struct an_ltv_status *status; 1922 struct an_ltv_ssidlist_new *ssids; 1923 int mode; 1924 struct aironet_ioctl l_ioctl; 1925 1926 sc = ifp->if_softc; 1927 ifr = (struct ifreq *)data; 1928 ireq = (struct ieee80211req *)data; 1929 1930 config = (struct an_ltv_genconfig *)&sc->areq; 1931 key = (struct an_ltv_key *)&sc->areq; 1932 status = (struct an_ltv_status *)&sc->areq; 1933 ssids = (struct an_ltv_ssidlist_new *)&sc->areq; 1934 1935 if (sc->an_gone) { 1936 error = ENODEV; 1937 goto out; 1938 } 1939 1940 switch (command) { 1941 case SIOCSIFFLAGS: 1942 AN_LOCK(sc); 1943 if (ifp->if_flags & IFF_UP) { 1944 if (ifp->if_drv_flags & IFF_DRV_RUNNING && 1945 ifp->if_flags & IFF_PROMISC && 1946 !(sc->an_if_flags & IFF_PROMISC)) { 1947 an_promisc(sc, 1); 1948 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && 1949 !(ifp->if_flags & IFF_PROMISC) && 1950 sc->an_if_flags & IFF_PROMISC) { 1951 an_promisc(sc, 0); 1952 } else { 1953 AN_UNLOCK(sc); 1954 an_init(sc); 1955 AN_LOCK(sc); 1956 } 1957 } else { 1958 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1959 AN_UNLOCK(sc); 1960 an_stop(sc); 1961 AN_LOCK(sc); 1962 } 1963 } 1964 AN_UNLOCK(sc); 1965 sc->an_if_flags = ifp->if_flags; 1966 error = 0; 1967 break; 1968 case SIOCSIFMEDIA: 1969 case SIOCGIFMEDIA: 1970 error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command); 1971 break; 1972 case SIOCADDMULTI: 1973 case SIOCDELMULTI: 1974 /* The Aironet has no multicast filter. */ 1975 error = 0; 1976 break; 1977 case SIOCGAIRONET: 1978 error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); 1979 if (error != 0) 1980 break; 1981 AN_LOCK(sc); 1982#ifdef ANCACHE 1983 if (sc->areq.an_type == AN_RID_ZERO_CACHE) { 1984 error = priv_check(td, PRIV_DRIVER); 1985 if (error) 1986 break; 1987 sc->an_sigitems = sc->an_nextitem = 0; 1988 break; 1989 } else if (sc->areq.an_type == AN_RID_READ_CACHE) { 1990 char *pt = (char *)&sc->areq.an_val; 1991 bcopy((char *)&sc->an_sigitems, (char *)pt, 1992 sizeof(int)); 1993 pt += sizeof(int); 1994 sc->areq.an_len = sizeof(int) / 2; 1995 bcopy((char *)&sc->an_sigcache, (char *)pt, 1996 sizeof(struct an_sigcache) * sc->an_sigitems); 1997 sc->areq.an_len += ((sizeof(struct an_sigcache) * 1998 sc->an_sigitems) / 2) + 1; 1999 } else 2000#endif 2001 if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { 2002 AN_UNLOCK(sc); 2003 error = EINVAL; 2004 break; 2005 } 2006 AN_UNLOCK(sc); 2007 error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq)); 2008 break; 2009 case SIOCSAIRONET: 2010 if ((error = priv_check(td, PRIV_DRIVER))) 2011 goto out; 2012 AN_LOCK(sc); 2013 error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); 2014 if (error != 0) 2015 break; 2016 an_setdef(sc, &sc->areq); 2017 AN_UNLOCK(sc); 2018 break; 2019 case SIOCGPRIVATE_0: /* used by Cisco client utility */ 2020 if ((error = priv_check(td, PRIV_DRIVER))) 2021 goto out; 2022 error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); 2023 if (error) 2024 goto out; 2025 mode = l_ioctl.command; 2026 2027 AN_LOCK(sc); 2028 if (mode >= AIROGCAP && mode <= AIROGSTATSD32) { 2029 error = readrids(ifp, &l_ioctl); 2030 } else if (mode >= AIROPCAP && mode <= AIROPLEAPUSR) { 2031 error = writerids(ifp, &l_ioctl); 2032 } else if (mode >= AIROFLSHRST && mode <= AIRORESTART) { 2033 error = flashcard(ifp, &l_ioctl); 2034 } else { 2035 error =-1; 2036 } 2037 AN_UNLOCK(sc); 2038 if (!error) { 2039 /* copy out the updated command info */ 2040 error = copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl)); 2041 } 2042 break; 2043 case SIOCGPRIVATE_1: /* used by Cisco client utility */ 2044 if ((error = priv_check(td, PRIV_DRIVER))) 2045 goto out; 2046 error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); 2047 if (error) 2048 goto out; 2049 l_ioctl.command = 0; 2050 error = AIROMAGIC; 2051 (void) copyout(&error, l_ioctl.data, sizeof(error)); 2052 error = 0; 2053 break; 2054 case SIOCG80211: 2055 sc->areq.an_len = sizeof(sc->areq); 2056 /* was that a good idea DJA we are doing a short-cut */ 2057 switch (ireq->i_type) { 2058 case IEEE80211_IOC_SSID: 2059 AN_LOCK(sc); 2060 if (ireq->i_val == -1) { 2061 sc->areq.an_type = AN_RID_STATUS; 2062 if (an_read_record(sc, 2063 (struct an_ltv_gen *)&sc->areq)) { 2064 error = EINVAL; 2065 AN_UNLOCK(sc); 2066 break; 2067 } 2068 len = status->an_ssidlen; 2069 tmpptr = status->an_ssid; 2070 } else if (ireq->i_val >= 0) { 2071 sc->areq.an_type = AN_RID_SSIDLIST; 2072 if (an_read_record(sc, 2073 (struct an_ltv_gen *)&sc->areq)) { 2074 error = EINVAL; 2075 AN_UNLOCK(sc); 2076 break; 2077 } 2078 max = (sc->areq.an_len - 4) 2079 / sizeof(struct an_ltv_ssid_entry); 2080 if ( max > MAX_SSIDS ) { 2081 printf("To many SSIDs only using " 2082 "%d of %d\n", 2083 MAX_SSIDS, max); 2084 max = MAX_SSIDS; 2085 } 2086 if (ireq->i_val > max) { 2087 error = EINVAL; 2088 AN_UNLOCK(sc); 2089 break; 2090 } else { 2091 len = ssids->an_entry[ireq->i_val].an_len; 2092 tmpptr = ssids->an_entry[ireq->i_val].an_ssid; 2093 } 2094 } else { 2095 error = EINVAL; 2096 AN_UNLOCK(sc); 2097 break; 2098 } 2099 if (len > IEEE80211_NWID_LEN) { 2100 error = EINVAL; 2101 AN_UNLOCK(sc); 2102 break; 2103 } 2104 AN_UNLOCK(sc); 2105 ireq->i_len = len; 2106 bzero(tmpstr, IEEE80211_NWID_LEN); 2107 bcopy(tmpptr, tmpstr, len); 2108 error = copyout(tmpstr, ireq->i_data, 2109 IEEE80211_NWID_LEN); 2110 break; 2111 case IEEE80211_IOC_NUMSSIDS: 2112 AN_LOCK(sc); 2113 sc->areq.an_len = sizeof(sc->areq); 2114 sc->areq.an_type = AN_RID_SSIDLIST; 2115 if (an_read_record(sc, 2116 (struct an_ltv_gen *)&sc->areq)) { 2117 AN_UNLOCK(sc); 2118 error = EINVAL; 2119 break; 2120 } 2121 max = (sc->areq.an_len - 4) 2122 / sizeof(struct an_ltv_ssid_entry); 2123 AN_UNLOCK(sc); 2124 if ( max > MAX_SSIDS ) { 2125 printf("To many SSIDs only using " 2126 "%d of %d\n", 2127 MAX_SSIDS, max); 2128 max = MAX_SSIDS; 2129 } 2130 ireq->i_val = max; 2131 break; 2132 case IEEE80211_IOC_WEP: 2133 AN_LOCK(sc); 2134 sc->areq.an_type = AN_RID_ACTUALCFG; 2135 if (an_read_record(sc, 2136 (struct an_ltv_gen *)&sc->areq)) { 2137 error = EINVAL; 2138 AN_UNLOCK(sc); 2139 break; 2140 } 2141 AN_UNLOCK(sc); 2142 if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { 2143 if (config->an_authtype & 2144 AN_AUTHTYPE_ALLOW_UNENCRYPTED) 2145 ireq->i_val = IEEE80211_WEP_MIXED; 2146 else 2147 ireq->i_val = IEEE80211_WEP_ON; 2148 } else { 2149 ireq->i_val = IEEE80211_WEP_OFF; 2150 } 2151 break; 2152 case IEEE80211_IOC_WEPKEY: 2153 /* 2154 * XXX: I'm not entierly convinced this is 2155 * correct, but it's what is implemented in 2156 * ancontrol so it will have to do until we get 2157 * access to actual Cisco code. 2158 */ 2159 if (ireq->i_val < 0 || ireq->i_val > 8) { 2160 error = EINVAL; 2161 break; 2162 } 2163 len = 0; 2164 if (ireq->i_val < 5) { 2165 AN_LOCK(sc); 2166 sc->areq.an_type = AN_RID_WEP_TEMP; 2167 for (i = 0; i < 5; i++) { 2168 if (an_read_record(sc, 2169 (struct an_ltv_gen *)&sc->areq)) { 2170 error = EINVAL; 2171 break; 2172 } 2173 if (key->kindex == 0xffff) 2174 break; 2175 if (key->kindex == ireq->i_val) 2176 len = key->klen; 2177 /* Required to get next entry */ 2178 sc->areq.an_type = AN_RID_WEP_PERM; 2179 } 2180 AN_UNLOCK(sc); 2181 if (error != 0) { 2182 break; 2183 } 2184 } 2185 /* We aren't allowed to read the value of the 2186 * key from the card so we just output zeros 2187 * like we would if we could read the card, but 2188 * denied the user access. 2189 */ 2190 bzero(tmpstr, len); 2191 ireq->i_len = len; 2192 error = copyout(tmpstr, ireq->i_data, len); 2193 break; 2194 case IEEE80211_IOC_NUMWEPKEYS: 2195 ireq->i_val = 9; /* include home key */ 2196 break; 2197 case IEEE80211_IOC_WEPTXKEY: 2198 /* 2199 * For some strange reason, you have to read all 2200 * keys before you can read the txkey. 2201 */ 2202 AN_LOCK(sc); 2203 sc->areq.an_type = AN_RID_WEP_TEMP; 2204 for (i = 0; i < 5; i++) { 2205 if (an_read_record(sc, 2206 (struct an_ltv_gen *) &sc->areq)) { 2207 error = EINVAL; 2208 break; 2209 } 2210 if (key->kindex == 0xffff) { 2211 break; 2212 } 2213 /* Required to get next entry */ 2214 sc->areq.an_type = AN_RID_WEP_PERM; 2215 } 2216 if (error != 0) { 2217 AN_UNLOCK(sc); 2218 break; 2219 } 2220 2221 sc->areq.an_type = AN_RID_WEP_PERM; 2222 key->kindex = 0xffff; 2223 if (an_read_record(sc, 2224 (struct an_ltv_gen *)&sc->areq)) { 2225 error = EINVAL; 2226 AN_UNLOCK(sc); 2227 break; 2228 } 2229 ireq->i_val = key->mac[0]; 2230 /* 2231 * Check for home mode. Map home mode into 2232 * 5th key since that is how it is stored on 2233 * the card 2234 */ 2235 sc->areq.an_len = sizeof(struct an_ltv_genconfig); 2236 sc->areq.an_type = AN_RID_GENCONFIG; 2237 if (an_read_record(sc, 2238 (struct an_ltv_gen *)&sc->areq)) { 2239 error = EINVAL; 2240 AN_UNLOCK(sc); 2241 break; 2242 } 2243 if (config->an_home_product & AN_HOME_NETWORK) 2244 ireq->i_val = 4; 2245 AN_UNLOCK(sc); 2246 break; 2247 case IEEE80211_IOC_AUTHMODE: 2248 AN_LOCK(sc); 2249 sc->areq.an_type = AN_RID_ACTUALCFG; 2250 if (an_read_record(sc, 2251 (struct an_ltv_gen *)&sc->areq)) { 2252 error = EINVAL; 2253 AN_UNLOCK(sc); 2254 break; 2255 } 2256 AN_UNLOCK(sc); 2257 if ((config->an_authtype & AN_AUTHTYPE_MASK) == 2258 AN_AUTHTYPE_NONE) { 2259 ireq->i_val = IEEE80211_AUTH_NONE; 2260 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 2261 AN_AUTHTYPE_OPEN) { 2262 ireq->i_val = IEEE80211_AUTH_OPEN; 2263 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 2264 AN_AUTHTYPE_SHAREDKEY) { 2265 ireq->i_val = IEEE80211_AUTH_SHARED; 2266 } else 2267 error = EINVAL; 2268 break; 2269 case IEEE80211_IOC_STATIONNAME: 2270 AN_LOCK(sc); 2271 sc->areq.an_type = AN_RID_ACTUALCFG; 2272 if (an_read_record(sc, 2273 (struct an_ltv_gen *)&sc->areq)) { 2274 error = EINVAL; 2275 AN_UNLOCK(sc); 2276 break; 2277 } 2278 AN_UNLOCK(sc); 2279 ireq->i_len = sizeof(config->an_nodename); 2280 tmpptr = config->an_nodename; 2281 bzero(tmpstr, IEEE80211_NWID_LEN); 2282 bcopy(tmpptr, tmpstr, ireq->i_len); 2283 error = copyout(tmpstr, ireq->i_data, 2284 IEEE80211_NWID_LEN); 2285 break; 2286 case IEEE80211_IOC_CHANNEL: 2287 AN_LOCK(sc); 2288 sc->areq.an_type = AN_RID_STATUS; 2289 if (an_read_record(sc, 2290 (struct an_ltv_gen *)&sc->areq)) { 2291 error = EINVAL; 2292 AN_UNLOCK(sc); 2293 break; 2294 } 2295 AN_UNLOCK(sc); 2296 ireq->i_val = status->an_cur_channel; 2297 break; 2298 case IEEE80211_IOC_CURCHAN: 2299 AN_LOCK(sc); 2300 sc->areq.an_type = AN_RID_STATUS; 2301 if (an_read_record(sc, 2302 (struct an_ltv_gen *)&sc->areq)) { 2303 error = EINVAL; 2304 AN_UNLOCK(sc); 2305 break; 2306 } 2307 AN_UNLOCK(sc); 2308 bzero(&ch, sizeof(ch)); 2309 ch.ic_freq = ieee80211_ieee2mhz(status->an_cur_channel, 2310 IEEE80211_CHAN_B); 2311 ch.ic_flags = IEEE80211_CHAN_B; 2312 ch.ic_ieee = status->an_cur_channel; 2313 error = copyout(&ch, ireq->i_data, sizeof(ch)); 2314 break; 2315 case IEEE80211_IOC_POWERSAVE: 2316 AN_LOCK(sc); 2317 sc->areq.an_type = AN_RID_ACTUALCFG; 2318 if (an_read_record(sc, 2319 (struct an_ltv_gen *)&sc->areq)) { 2320 error = EINVAL; 2321 AN_UNLOCK(sc); 2322 break; 2323 } 2324 AN_UNLOCK(sc); 2325 if (config->an_psave_mode == AN_PSAVE_NONE) { 2326 ireq->i_val = IEEE80211_POWERSAVE_OFF; 2327 } else if (config->an_psave_mode == AN_PSAVE_CAM) { 2328 ireq->i_val = IEEE80211_POWERSAVE_CAM; 2329 } else if (config->an_psave_mode == AN_PSAVE_PSP) { 2330 ireq->i_val = IEEE80211_POWERSAVE_PSP; 2331 } else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) { 2332 ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM; 2333 } else 2334 error = EINVAL; 2335 break; 2336 case IEEE80211_IOC_POWERSAVESLEEP: 2337 AN_LOCK(sc); 2338 sc->areq.an_type = AN_RID_ACTUALCFG; 2339 if (an_read_record(sc, 2340 (struct an_ltv_gen *)&sc->areq)) { 2341 error = EINVAL; 2342 AN_UNLOCK(sc); 2343 break; 2344 } 2345 AN_UNLOCK(sc); 2346 ireq->i_val = config->an_listen_interval; 2347 break; 2348 } 2349 break; 2350 case SIOCS80211: 2351 if ((error = priv_check(td, PRIV_NET80211_MANAGE))) 2352 goto out; 2353 AN_LOCK(sc); 2354 sc->areq.an_len = sizeof(sc->areq); 2355 /* 2356 * We need a config structure for everything but the WEP 2357 * key management and SSIDs so we get it now so avoid 2358 * duplicating this code every time. 2359 */ 2360 if (ireq->i_type != IEEE80211_IOC_SSID && 2361 ireq->i_type != IEEE80211_IOC_WEPKEY && 2362 ireq->i_type != IEEE80211_IOC_WEPTXKEY) { 2363 sc->areq.an_type = AN_RID_GENCONFIG; 2364 if (an_read_record(sc, 2365 (struct an_ltv_gen *)&sc->areq)) { 2366 error = EINVAL; 2367 AN_UNLOCK(sc); 2368 break; 2369 } 2370 } 2371 switch (ireq->i_type) { 2372 case IEEE80211_IOC_SSID: 2373 sc->areq.an_len = sizeof(sc->areq); 2374 sc->areq.an_type = AN_RID_SSIDLIST; 2375 if (an_read_record(sc, 2376 (struct an_ltv_gen *)&sc->areq)) { 2377 error = EINVAL; 2378 AN_UNLOCK(sc); 2379 break; 2380 } 2381 if (ireq->i_len > IEEE80211_NWID_LEN) { 2382 error = EINVAL; 2383 AN_UNLOCK(sc); 2384 break; 2385 } 2386 max = (sc->areq.an_len - 4) 2387 / sizeof(struct an_ltv_ssid_entry); 2388 if ( max > MAX_SSIDS ) { 2389 printf("To many SSIDs only using " 2390 "%d of %d\n", 2391 MAX_SSIDS, max); 2392 max = MAX_SSIDS; 2393 } 2394 if (ireq->i_val > max) { 2395 error = EINVAL; 2396 AN_UNLOCK(sc); 2397 break; 2398 } else { 2399 error = copyin(ireq->i_data, 2400 ssids->an_entry[ireq->i_val].an_ssid, 2401 ireq->i_len); 2402 ssids->an_entry[ireq->i_val].an_len 2403 = ireq->i_len; 2404 sc->areq.an_len = sizeof(sc->areq); 2405 sc->areq.an_type = AN_RID_SSIDLIST; 2406 an_setdef(sc, &sc->areq); 2407 AN_UNLOCK(sc); 2408 break; 2409 } 2410 break; 2411 case IEEE80211_IOC_WEP: 2412 switch (ireq->i_val) { 2413 case IEEE80211_WEP_OFF: 2414 config->an_authtype &= 2415 ~(AN_AUTHTYPE_PRIVACY_IN_USE | 2416 AN_AUTHTYPE_ALLOW_UNENCRYPTED); 2417 break; 2418 case IEEE80211_WEP_ON: 2419 config->an_authtype |= 2420 AN_AUTHTYPE_PRIVACY_IN_USE; 2421 config->an_authtype &= 2422 ~AN_AUTHTYPE_ALLOW_UNENCRYPTED; 2423 break; 2424 case IEEE80211_WEP_MIXED: 2425 config->an_authtype |= 2426 AN_AUTHTYPE_PRIVACY_IN_USE | 2427 AN_AUTHTYPE_ALLOW_UNENCRYPTED; 2428 break; 2429 default: 2430 error = EINVAL; 2431 break; 2432 } 2433 if (error != EINVAL) 2434 an_setdef(sc, &sc->areq); 2435 AN_UNLOCK(sc); 2436 break; 2437 case IEEE80211_IOC_WEPKEY: 2438 if (ireq->i_val < 0 || ireq->i_val > 8 || 2439 ireq->i_len > 13) { 2440 error = EINVAL; 2441 AN_UNLOCK(sc); 2442 break; 2443 } 2444 error = copyin(ireq->i_data, tmpstr, 13); 2445 if (error != 0) { 2446 AN_UNLOCK(sc); 2447 break; 2448 } 2449 /* 2450 * Map the 9th key into the home mode 2451 * since that is how it is stored on 2452 * the card 2453 */ 2454 bzero(&sc->areq, sizeof(struct an_ltv_key)); 2455 sc->areq.an_len = sizeof(struct an_ltv_key); 2456 key->mac[0] = 1; /* The others are 0. */ 2457 if (ireq->i_val < 4) { 2458 sc->areq.an_type = AN_RID_WEP_TEMP; 2459 key->kindex = ireq->i_val; 2460 } else { 2461 sc->areq.an_type = AN_RID_WEP_PERM; 2462 key->kindex = ireq->i_val - 4; 2463 } 2464 key->klen = ireq->i_len; 2465 bcopy(tmpstr, key->key, key->klen); 2466 an_setdef(sc, &sc->areq); 2467 AN_UNLOCK(sc); 2468 break; 2469 case IEEE80211_IOC_WEPTXKEY: 2470 if (ireq->i_val < 0 || ireq->i_val > 4) { 2471 error = EINVAL; 2472 AN_UNLOCK(sc); 2473 break; 2474 } 2475 2476 /* 2477 * Map the 5th key into the home mode 2478 * since that is how it is stored on 2479 * the card 2480 */ 2481 sc->areq.an_len = sizeof(struct an_ltv_genconfig); 2482 sc->areq.an_type = AN_RID_ACTUALCFG; 2483 if (an_read_record(sc, 2484 (struct an_ltv_gen *)&sc->areq)) { 2485 error = EINVAL; 2486 AN_UNLOCK(sc); 2487 break; 2488 } 2489 AN_UNLOCK(sc); 2490 if (ireq->i_val == 4) { 2491 config->an_home_product |= AN_HOME_NETWORK; 2492 ireq->i_val = 0; 2493 } else { 2494 config->an_home_product &= ~AN_HOME_NETWORK; 2495 } 2496 2497 sc->an_config.an_home_product 2498 = config->an_home_product; 2499 2500 /* update configuration */ 2501 an_init(sc); 2502 2503 bzero(&sc->areq, sizeof(struct an_ltv_key)); 2504 AN_LOCK(sc); 2505 sc->areq.an_len = sizeof(struct an_ltv_key); 2506 sc->areq.an_type = AN_RID_WEP_PERM; 2507 key->kindex = 0xffff; 2508 key->mac[0] = ireq->i_val; 2509 an_setdef(sc, &sc->areq); 2510 AN_UNLOCK(sc); 2511 break; 2512 case IEEE80211_IOC_AUTHMODE: 2513 switch (ireq->i_val) { 2514 case IEEE80211_AUTH_NONE: 2515 config->an_authtype = AN_AUTHTYPE_NONE | 2516 (config->an_authtype & ~AN_AUTHTYPE_MASK); 2517 break; 2518 case IEEE80211_AUTH_OPEN: 2519 config->an_authtype = AN_AUTHTYPE_OPEN | 2520 (config->an_authtype & ~AN_AUTHTYPE_MASK); 2521 break; 2522 case IEEE80211_AUTH_SHARED: 2523 config->an_authtype = AN_AUTHTYPE_SHAREDKEY | 2524 (config->an_authtype & ~AN_AUTHTYPE_MASK); 2525 break; 2526 default: 2527 error = EINVAL; 2528 } 2529 if (error != EINVAL) { 2530 an_setdef(sc, &sc->areq); 2531 } 2532 AN_UNLOCK(sc); 2533 break; 2534 case IEEE80211_IOC_STATIONNAME: 2535 if (ireq->i_len > 16) { 2536 error = EINVAL; 2537 AN_UNLOCK(sc); 2538 break; 2539 } 2540 bzero(config->an_nodename, 16); 2541 error = copyin(ireq->i_data, 2542 config->an_nodename, ireq->i_len); 2543 an_setdef(sc, &sc->areq); 2544 AN_UNLOCK(sc); 2545 break; 2546 case IEEE80211_IOC_CHANNEL: 2547 /* 2548 * The actual range is 1-14, but if you set it 2549 * to 0 you get the default so we let that work 2550 * too. 2551 */ 2552 if (ireq->i_val < 0 || ireq->i_val >14) { 2553 error = EINVAL; 2554 AN_UNLOCK(sc); 2555 break; 2556 } 2557 config->an_ds_channel = ireq->i_val; 2558 an_setdef(sc, &sc->areq); 2559 AN_UNLOCK(sc); 2560 break; 2561 case IEEE80211_IOC_POWERSAVE: 2562 switch (ireq->i_val) { 2563 case IEEE80211_POWERSAVE_OFF: 2564 config->an_psave_mode = AN_PSAVE_NONE; 2565 break; 2566 case IEEE80211_POWERSAVE_CAM: 2567 config->an_psave_mode = AN_PSAVE_CAM; 2568 break; 2569 case IEEE80211_POWERSAVE_PSP: 2570 config->an_psave_mode = AN_PSAVE_PSP; 2571 break; 2572 case IEEE80211_POWERSAVE_PSP_CAM: 2573 config->an_psave_mode = AN_PSAVE_PSP_CAM; 2574 break; 2575 default: 2576 error = EINVAL; 2577 break; 2578 } 2579 an_setdef(sc, &sc->areq); 2580 AN_UNLOCK(sc); 2581 break; 2582 case IEEE80211_IOC_POWERSAVESLEEP: 2583 config->an_listen_interval = ireq->i_val; 2584 an_setdef(sc, &sc->areq); 2585 AN_UNLOCK(sc); 2586 break; 2587 } 2588 2589 /* 2590 if (!error) { 2591 AN_LOCK(sc); 2592 an_setdef(sc, &sc->areq); 2593 AN_UNLOCK(sc); 2594 } 2595 */ 2596 break; 2597 default: 2598 error = ether_ioctl(ifp, command, data); 2599 break; 2600 } 2601out: 2602 2603 return(error != 0); 2604} 2605 2606static int 2607an_init_tx_ring(struct an_softc *sc) 2608{ 2609 int i; 2610 int id; 2611 2612 if (sc->an_gone) 2613 return (0); 2614 2615 if (!sc->mpi350) { 2616 for (i = 0; i < AN_TX_RING_CNT; i++) { 2617 if (an_alloc_nicmem(sc, 1518 + 2618 0x44, &id)) 2619 return(ENOMEM); 2620 sc->an_rdata.an_tx_fids[i] = id; 2621 sc->an_rdata.an_tx_ring[i] = 0; 2622 } 2623 } 2624 2625 sc->an_rdata.an_tx_prod = 0; 2626 sc->an_rdata.an_tx_cons = 0; 2627 sc->an_rdata.an_tx_empty = 1; 2628 2629 return(0); 2630} 2631 2632static void 2633an_init(void *xsc) 2634{ 2635 struct an_softc *sc = xsc; 2636 struct ifnet *ifp = sc->an_ifp; 2637 2638 AN_LOCK(sc); 2639 2640 if (sc->an_gone) { 2641 AN_UNLOCK(sc); 2642 return; 2643 } 2644 2645 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 2646 an_stop(sc); 2647 2648 sc->an_associated = 0; 2649 2650 /* Allocate the TX buffers */ 2651 if (an_init_tx_ring(sc)) { 2652 an_reset(sc); 2653 if (sc->mpi350) 2654 an_init_mpi350_desc(sc); 2655 if (an_init_tx_ring(sc)) { 2656 printf("an%d: tx buffer allocation " 2657 "failed\n", sc->an_unit); 2658 AN_UNLOCK(sc); 2659 return; 2660 } 2661 } 2662 2663 /* Set our MAC address. */ 2664 bcopy((char *)IF_LLADDR(sc->an_ifp), 2665 (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN); 2666 2667 if (ifp->if_flags & IFF_BROADCAST) 2668 sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR; 2669 else 2670 sc->an_config.an_rxmode = AN_RXMODE_ADDR; 2671 2672 if (ifp->if_flags & IFF_MULTICAST) 2673 sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR; 2674 2675 if (ifp->if_flags & IFF_PROMISC) { 2676 if (sc->an_monitor & AN_MONITOR) { 2677 if (sc->an_monitor & AN_MONITOR_ANY_BSS) { 2678 sc->an_config.an_rxmode |= 2679 AN_RXMODE_80211_MONITOR_ANYBSS | 2680 AN_RXMODE_NO_8023_HEADER; 2681 } else { 2682 sc->an_config.an_rxmode |= 2683 AN_RXMODE_80211_MONITOR_CURBSS | 2684 AN_RXMODE_NO_8023_HEADER; 2685 } 2686 } 2687 } 2688 2689 if (sc->an_have_rssimap) 2690 sc->an_config.an_rxmode |= AN_RXMODE_NORMALIZED_RSSI; 2691 2692 /* Set the ssid list */ 2693 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 2694 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new); 2695 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 2696 printf("an%d: failed to set ssid list\n", sc->an_unit); 2697 AN_UNLOCK(sc); 2698 return; 2699 } 2700 2701 /* Set the AP list */ 2702 sc->an_aplist.an_type = AN_RID_APLIST; 2703 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 2704 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 2705 printf("an%d: failed to set AP list\n", sc->an_unit); 2706 AN_UNLOCK(sc); 2707 return; 2708 } 2709 2710 /* Set the configuration in the NIC */ 2711 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 2712 sc->an_config.an_type = AN_RID_GENCONFIG; 2713 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 2714 printf("an%d: failed to set configuration\n", sc->an_unit); 2715 AN_UNLOCK(sc); 2716 return; 2717 } 2718 2719 /* Enable the MAC */ 2720 if (an_cmd(sc, AN_CMD_ENABLE, 0)) { 2721 printf("an%d: failed to enable MAC\n", sc->an_unit); 2722 AN_UNLOCK(sc); 2723 return; 2724 } 2725 2726 if (ifp->if_flags & IFF_PROMISC) 2727 an_cmd(sc, AN_CMD_SET_MODE, 0xffff); 2728 2729 /* enable interrupts */ 2730 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350)); 2731 2732 ifp->if_drv_flags |= IFF_DRV_RUNNING; 2733 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 2734 2735 callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc); 2736 AN_UNLOCK(sc); 2737 2738 return; 2739} 2740 2741static void 2742an_start(struct ifnet *ifp) 2743{ 2744 struct an_softc *sc; 2745 struct mbuf *m0 = NULL; 2746 struct an_txframe_802_3 tx_frame_802_3; 2747 struct ether_header *eh; 2748 int id, idx, i; 2749 unsigned char txcontrol; 2750 struct an_card_tx_desc an_tx_desc; 2751 u_int8_t *buf; 2752 2753 sc = ifp->if_softc; 2754 2755 if (sc->an_gone) 2756 return; 2757 2758 if (ifp->if_drv_flags & IFF_DRV_OACTIVE) 2759 return; 2760 2761 if (!sc->an_associated) 2762 return; 2763 2764 /* We can't send in monitor mode so toss any attempts. */ 2765 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 2766 for (;;) { 2767 IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); 2768 if (m0 == NULL) 2769 break; 2770 m_freem(m0); 2771 } 2772 return; 2773 } 2774 2775 idx = sc->an_rdata.an_tx_prod; 2776 2777 AN_LOCK(sc); 2778 if (!sc->mpi350) { 2779 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 2780 2781 while (sc->an_rdata.an_tx_ring[idx] == 0) { 2782 IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); 2783 if (m0 == NULL) 2784 break; 2785 2786 id = sc->an_rdata.an_tx_fids[idx]; 2787 eh = mtod(m0, struct ether_header *); 2788 2789 bcopy((char *)&eh->ether_dhost, 2790 (char *)&tx_frame_802_3.an_tx_dst_addr, 2791 ETHER_ADDR_LEN); 2792 bcopy((char *)&eh->ether_shost, 2793 (char *)&tx_frame_802_3.an_tx_src_addr, 2794 ETHER_ADDR_LEN); 2795 2796 /* minus src/dest mac & type */ 2797 tx_frame_802_3.an_tx_802_3_payload_len = 2798 m0->m_pkthdr.len - 12; 2799 2800 m_copydata(m0, sizeof(struct ether_header) - 2 , 2801 tx_frame_802_3.an_tx_802_3_payload_len, 2802 (caddr_t)&sc->an_txbuf); 2803 2804 txcontrol = AN_TXCTL_8023; 2805 /* write the txcontrol only */ 2806 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 2807 sizeof(txcontrol)); 2808 2809 /* 802_3 header */ 2810 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 2811 sizeof(struct an_txframe_802_3)); 2812 2813 /* in mbuf header type is just before payload */ 2814 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 2815 tx_frame_802_3.an_tx_802_3_payload_len); 2816 2817 /* 2818 * If there's a BPF listner, bounce a copy of 2819 * this frame to him. 2820 */ 2821 BPF_MTAP(ifp, m0); 2822 2823 m_freem(m0); 2824 m0 = NULL; 2825 2826 sc->an_rdata.an_tx_ring[idx] = id; 2827 if (an_cmd(sc, AN_CMD_TX, id)) 2828 printf("an%d: xmit failed\n", sc->an_unit); 2829 2830 AN_INC(idx, AN_TX_RING_CNT); 2831 2832 /* 2833 * Set a timeout in case the chip goes out to lunch. 2834 */ 2835 ifp->if_timer = 5; 2836 } 2837 } else { /* MPI-350 */ 2838 /* Disable interrupts. */ 2839 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0); 2840 2841 while (sc->an_rdata.an_tx_empty || 2842 idx != sc->an_rdata.an_tx_cons) { 2843 IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); 2844 if (m0 == NULL) { 2845 break; 2846 } 2847 buf = sc->an_tx_buffer[idx].an_dma_vaddr; 2848 2849 eh = mtod(m0, struct ether_header *); 2850 2851 /* DJA optimize this to limit bcopy */ 2852 bcopy((char *)&eh->ether_dhost, 2853 (char *)&tx_frame_802_3.an_tx_dst_addr, 2854 ETHER_ADDR_LEN); 2855 bcopy((char *)&eh->ether_shost, 2856 (char *)&tx_frame_802_3.an_tx_src_addr, 2857 ETHER_ADDR_LEN); 2858 2859 /* minus src/dest mac & type */ 2860 tx_frame_802_3.an_tx_802_3_payload_len = 2861 m0->m_pkthdr.len - 12; 2862 2863 m_copydata(m0, sizeof(struct ether_header) - 2 , 2864 tx_frame_802_3.an_tx_802_3_payload_len, 2865 (caddr_t)&sc->an_txbuf); 2866 2867 txcontrol = AN_TXCTL_8023; 2868 /* write the txcontrol only */ 2869 bcopy((caddr_t)&txcontrol, &buf[0x08], 2870 sizeof(txcontrol)); 2871 2872 /* 802_3 header */ 2873 bcopy((caddr_t)&tx_frame_802_3, &buf[0x34], 2874 sizeof(struct an_txframe_802_3)); 2875 2876 /* in mbuf header type is just before payload */ 2877 bcopy((caddr_t)&sc->an_txbuf, &buf[0x44], 2878 tx_frame_802_3.an_tx_802_3_payload_len); 2879 2880 2881 bzero(&an_tx_desc, sizeof(an_tx_desc)); 2882 an_tx_desc.an_offset = 0; 2883 an_tx_desc.an_eoc = 1; 2884 an_tx_desc.an_valid = 1; 2885 an_tx_desc.an_len = 0x44 + 2886 tx_frame_802_3.an_tx_802_3_payload_len; 2887 an_tx_desc.an_phys 2888 = sc->an_tx_buffer[idx].an_dma_paddr; 2889 for (i = 0; i < sizeof(an_tx_desc) / 4 ; i++) { 2890 CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET 2891 /* zero for now */ 2892 + (0 * sizeof(an_tx_desc)) 2893 + (i * 4), 2894 ((u_int32_t *)(void *)&an_tx_desc)[i]); 2895 } 2896 2897 /* 2898 * If there's a BPF listner, bounce a copy of 2899 * this frame to him. 2900 */ 2901 BPF_MTAP(ifp, m0); 2902 2903 m_freem(m0); 2904 m0 = NULL; 2905 AN_INC(idx, AN_MAX_TX_DESC); 2906 sc->an_rdata.an_tx_empty = 0; 2907 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC); 2908 2909 /* 2910 * Set a timeout in case the chip goes out to lunch. 2911 */ 2912 ifp->if_timer = 5; 2913 } 2914 2915 /* Re-enable interrupts. */ 2916 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350)); 2917 } 2918 AN_UNLOCK(sc); 2919 2920 if (m0 != NULL) 2921 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 2922 2923 sc->an_rdata.an_tx_prod = idx; 2924 2925 return; 2926} 2927 2928void 2929an_stop(struct an_softc *sc) 2930{ 2931 struct ifnet *ifp; 2932 int i; 2933 2934 AN_LOCK(sc); 2935 2936 if (sc->an_gone) { 2937 AN_UNLOCK(sc); 2938 return; 2939 } 2940 2941 ifp = sc->an_ifp; 2942 2943 an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0); 2944 CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0); 2945 an_cmd(sc, AN_CMD_DISABLE, 0); 2946 2947 for (i = 0; i < AN_TX_RING_CNT; i++) 2948 an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]); 2949 2950 callout_stop(&sc->an_stat_ch); 2951 2952 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE); 2953 2954 if (sc->an_flash_buffer) { 2955 free(sc->an_flash_buffer, M_DEVBUF); 2956 sc->an_flash_buffer = NULL; 2957 } 2958 2959 AN_UNLOCK(sc); 2960 2961 return; 2962} 2963 2964static void 2965an_watchdog(struct ifnet *ifp) 2966{ 2967 struct an_softc *sc; 2968 2969 sc = ifp->if_softc; 2970 AN_LOCK(sc); 2971 2972 if (sc->an_gone) { 2973 AN_UNLOCK(sc); 2974 return; 2975 } 2976 2977 printf("an%d: device timeout\n", sc->an_unit); 2978 2979 an_reset(sc); 2980 if (sc->mpi350) 2981 an_init_mpi350_desc(sc); 2982 AN_UNLOCK(sc); 2983 an_init(sc); 2984 2985 ifp->if_oerrors++; 2986 2987 return; 2988} 2989 2990void 2991an_shutdown(device_t dev) 2992{ 2993 struct an_softc *sc; 2994 2995 sc = device_get_softc(dev); 2996 an_stop(sc); 2997 sc->an_gone = 1; 2998 2999 return; 3000} 3001 3002void 3003an_resume(device_t dev) 3004{ 3005 struct an_softc *sc; 3006 struct ifnet *ifp; 3007 int i; 3008 3009 sc = device_get_softc(dev); 3010 AN_LOCK(sc); 3011 ifp = sc->an_ifp; 3012 3013 sc->an_gone = 0; 3014 an_reset(sc); 3015 if (sc->mpi350) 3016 an_init_mpi350_desc(sc); 3017 an_init(sc); 3018 3019 /* Recovery temporary keys */ 3020 for (i = 0; i < 4; i++) { 3021 sc->areq.an_type = AN_RID_WEP_TEMP; 3022 sc->areq.an_len = sizeof(struct an_ltv_key); 3023 bcopy(&sc->an_temp_keys[i], 3024 &sc->areq, sizeof(struct an_ltv_key)); 3025 an_setdef(sc, &sc->areq); 3026 } 3027 3028 if (ifp->if_flags & IFF_UP) 3029 an_start(ifp); 3030 AN_UNLOCK(sc); 3031 3032 return; 3033} 3034 3035#ifdef ANCACHE 3036/* Aironet signal strength cache code. 3037 * store signal/noise/quality on per MAC src basis in 3038 * a small fixed cache. The cache wraps if > MAX slots 3039 * used. The cache may be zeroed out to start over. 3040 * Two simple filters exist to reduce computation: 3041 * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used 3042 * to ignore some packets. It defaults to ip only. 3043 * it could be used to focus on broadcast, non-IP 802.11 beacons. 3044 * 2. multicast/broadcast only. This may be used to 3045 * ignore unicast packets and only cache signal strength 3046 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 3047 * beacons and not unicast traffic. 3048 * 3049 * The cache stores (MAC src(index), IP src (major clue), signal, 3050 * quality, noise) 3051 * 3052 * No apologies for storing IP src here. It's easy and saves much 3053 * trouble elsewhere. The cache is assumed to be INET dependent, 3054 * although it need not be. 3055 * 3056 * Note: the Aironet only has a single byte of signal strength value 3057 * in the rx frame header, and it's not scaled to anything sensible. 3058 * This is kind of lame, but it's all we've got. 3059 */ 3060 3061#ifdef documentation 3062 3063int an_sigitems; /* number of cached entries */ 3064struct an_sigcache an_sigcache[MAXANCACHE]; /* array of cache entries */ 3065int an_nextitem; /* index/# of entries */ 3066 3067 3068#endif 3069 3070/* control variables for cache filtering. Basic idea is 3071 * to reduce cost (e.g., to only Mobile-IP agent beacons 3072 * which are broadcast or multicast). Still you might 3073 * want to measure signal strength anth unicast ping packets 3074 * on a pt. to pt. ant. setup. 3075 */ 3076/* set true if you want to limit cache items to broadcast/mcast 3077 * only packets (not unicast). Useful for mobile-ip beacons which 3078 * are broadcast/multicast at network layer. Default is all packets 3079 * so ping/unicast anll work say anth pt. to pt. antennae setup. 3080 */ 3081static int an_cache_mcastonly = 0; 3082SYSCTL_INT(_hw_an, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, 3083 &an_cache_mcastonly, 0, ""); 3084 3085/* set true if you want to limit cache items to IP packets only 3086*/ 3087static int an_cache_iponly = 1; 3088SYSCTL_INT(_hw_an, OID_AUTO, an_cache_iponly, CTLFLAG_RW, 3089 &an_cache_iponly, 0, ""); 3090 3091/* 3092 * an_cache_store, per rx packet store signal 3093 * strength in MAC (src) indexed cache. 3094 */ 3095static void 3096an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m, 3097 u_int8_t rx_rssi, u_int8_t rx_quality) 3098{ 3099 struct ip *ip = 0; 3100 int i; 3101 static int cache_slot = 0; /* use this cache entry */ 3102 static int wrapindex = 0; /* next "free" cache entry */ 3103 int type_ipv4 = 0; 3104 3105 /* filters: 3106 * 1. ip only 3107 * 2. configurable filter to throw out unicast packets, 3108 * keep multicast only. 3109 */ 3110 3111 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) { 3112 type_ipv4 = 1; 3113 } 3114 3115 /* filter for ip packets only 3116 */ 3117 if ( an_cache_iponly && !type_ipv4) { 3118 return; 3119 } 3120 3121 /* filter for broadcast/multicast only 3122 */ 3123 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 3124 return; 3125 } 3126 3127#ifdef SIGDEBUG 3128 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 3129 rx_rssi & 0xffff, rx_rssi >> 8, rx_rssi & 0xff); 3130#endif 3131 3132 /* find the ip header. we want to store the ip_src 3133 * address. 3134 */ 3135 if (type_ipv4) { 3136 ip = mtod(m, struct ip *); 3137 } 3138 3139 /* do a linear search for a matching MAC address 3140 * in the cache table 3141 * . MAC address is 6 bytes, 3142 * . var w_nextitem holds total number of entries already cached 3143 */ 3144 for (i = 0; i < sc->an_nextitem; i++) { 3145 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 3146 /* Match!, 3147 * so we already have this entry, 3148 * update the data 3149 */ 3150 break; 3151 } 3152 } 3153 3154 /* did we find a matching mac address? 3155 * if yes, then overwrite a previously existing cache entry 3156 */ 3157 if (i < sc->an_nextitem ) { 3158 cache_slot = i; 3159 } 3160 /* else, have a new address entry,so 3161 * add this new entry, 3162 * if table full, then we need to replace LRU entry 3163 */ 3164 else { 3165 3166 /* check for space in cache table 3167 * note: an_nextitem also holds number of entries 3168 * added in the cache table 3169 */ 3170 if ( sc->an_nextitem < MAXANCACHE ) { 3171 cache_slot = sc->an_nextitem; 3172 sc->an_nextitem++; 3173 sc->an_sigitems = sc->an_nextitem; 3174 } 3175 /* no space found, so simply wrap anth wrap index 3176 * and "zap" the next entry 3177 */ 3178 else { 3179 if (wrapindex == MAXANCACHE) { 3180 wrapindex = 0; 3181 } 3182 cache_slot = wrapindex++; 3183 } 3184 } 3185 3186 /* invariant: cache_slot now points at some slot 3187 * in cache. 3188 */ 3189 if (cache_slot < 0 || cache_slot >= MAXANCACHE) { 3190 log(LOG_ERR, "an_cache_store, bad index: %d of " 3191 "[0..%d], gross cache error\n", 3192 cache_slot, MAXANCACHE); 3193 return; 3194 } 3195 3196 /* store items in cache 3197 * .ip source address 3198 * .mac src 3199 * .signal, etc. 3200 */ 3201 if (type_ipv4) { 3202 sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 3203 } 3204 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 3205 3206 3207 switch (an_cache_mode) { 3208 case DBM: 3209 if (sc->an_have_rssimap) { 3210 sc->an_sigcache[cache_slot].signal = 3211 - sc->an_rssimap.an_entries[rx_rssi].an_rss_dbm; 3212 sc->an_sigcache[cache_slot].quality = 3213 - sc->an_rssimap.an_entries[rx_quality].an_rss_dbm; 3214 } else { 3215 sc->an_sigcache[cache_slot].signal = rx_rssi - 100; 3216 sc->an_sigcache[cache_slot].quality = rx_quality - 100; 3217 } 3218 break; 3219 case PERCENT: 3220 if (sc->an_have_rssimap) { 3221 sc->an_sigcache[cache_slot].signal = 3222 sc->an_rssimap.an_entries[rx_rssi].an_rss_pct; 3223 sc->an_sigcache[cache_slot].quality = 3224 sc->an_rssimap.an_entries[rx_quality].an_rss_pct; 3225 } else { 3226 if (rx_rssi > 100) 3227 rx_rssi = 100; 3228 if (rx_quality > 100) 3229 rx_quality = 100; 3230 sc->an_sigcache[cache_slot].signal = rx_rssi; 3231 sc->an_sigcache[cache_slot].quality = rx_quality; 3232 } 3233 break; 3234 case RAW: 3235 sc->an_sigcache[cache_slot].signal = rx_rssi; 3236 sc->an_sigcache[cache_slot].quality = rx_quality; 3237 break; 3238 } 3239 3240 sc->an_sigcache[cache_slot].noise = 0; 3241 3242 return; 3243} 3244#endif 3245 3246static int 3247an_media_change(struct ifnet *ifp) 3248{ 3249 struct an_softc *sc = ifp->if_softc; 3250 struct an_ltv_genconfig *cfg; 3251 int otype = sc->an_config.an_opmode; 3252 int orate = sc->an_tx_rate; 3253 3254 sc->an_tx_rate = ieee80211_media2rate( 3255 IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)); 3256 if (sc->an_tx_rate < 0) 3257 sc->an_tx_rate = 0; 3258 3259 AN_LOCK(sc); 3260 if (orate != sc->an_tx_rate) { 3261 /* Read the current configuration */ 3262 sc->an_config.an_type = AN_RID_GENCONFIG; 3263 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 3264 an_read_record(sc, (struct an_ltv_gen *)&sc->an_config); 3265 cfg = &sc->an_config; 3266 3267 /* clear other rates and set the only one we want */ 3268 bzero(cfg->an_rates, sizeof(cfg->an_rates)); 3269 cfg->an_rates[0] = sc->an_tx_rate; 3270 3271 /* Save the new rate */ 3272 sc->an_config.an_type = AN_RID_GENCONFIG; 3273 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 3274 } 3275 3276 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 3277 sc->an_config.an_opmode &= ~AN_OPMODE_INFRASTRUCTURE_STATION; 3278 else 3279 sc->an_config.an_opmode |= AN_OPMODE_INFRASTRUCTURE_STATION; 3280 AN_UNLOCK(sc); 3281 3282 if (otype != sc->an_config.an_opmode || 3283 orate != sc->an_tx_rate) 3284 an_init(sc); 3285 3286 return(0); 3287} 3288 3289static void 3290an_media_status(struct ifnet *ifp, struct ifmediareq *imr) 3291{ 3292 struct an_ltv_status status; 3293 struct an_softc *sc = ifp->if_softc; 3294 3295 imr->ifm_active = IFM_IEEE80211; 3296 3297 AN_LOCK(sc); 3298 status.an_len = sizeof(status); 3299 status.an_type = AN_RID_STATUS; 3300 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 3301 /* If the status read fails, just lie. */ 3302 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 3303 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 3304 } 3305 AN_UNLOCK(sc); 3306 3307 if (sc->an_tx_rate == 0) { 3308 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 3309 } 3310 3311 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 3312 imr->ifm_active |= IFM_IEEE80211_ADHOC; 3313 imr->ifm_active |= ieee80211_rate2media(NULL, 3314 status.an_current_tx_rate, IEEE80211_T_DS); 3315 imr->ifm_status = IFM_AVALID; 3316 if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED) 3317 imr->ifm_status |= IFM_ACTIVE; 3318} 3319 3320/********************** Cisco utility support routines *************/ 3321 3322/* 3323 * ReadRids & WriteRids derived from Cisco driver additions to Ben Reed's 3324 * Linux driver 3325 */ 3326 3327static int 3328readrids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) 3329{ 3330 unsigned short rid; 3331 struct an_softc *sc; 3332 int error; 3333 3334 switch (l_ioctl->command) { 3335 case AIROGCAP: 3336 rid = AN_RID_CAPABILITIES; 3337 break; 3338 case AIROGCFG: 3339 rid = AN_RID_GENCONFIG; 3340 break; 3341 case AIROGSLIST: 3342 rid = AN_RID_SSIDLIST; 3343 break; 3344 case AIROGVLIST: 3345 rid = AN_RID_APLIST; 3346 break; 3347 case AIROGDRVNAM: 3348 rid = AN_RID_DRVNAME; 3349 break; 3350 case AIROGEHTENC: 3351 rid = AN_RID_ENCAPPROTO; 3352 break; 3353 case AIROGWEPKTMP: 3354 rid = AN_RID_WEP_TEMP; 3355 break; 3356 case AIROGWEPKNV: 3357 rid = AN_RID_WEP_PERM; 3358 break; 3359 case AIROGSTAT: 3360 rid = AN_RID_STATUS; 3361 break; 3362 case AIROGSTATSD32: 3363 rid = AN_RID_32BITS_DELTA; 3364 break; 3365 case AIROGSTATSC32: 3366 rid = AN_RID_32BITS_CUM; 3367 break; 3368 default: 3369 rid = 999; 3370 break; 3371 } 3372 3373 if (rid == 999) /* Is bad command */ 3374 return -EINVAL; 3375 3376 sc = ifp->if_softc; 3377 sc->areq.an_len = AN_MAX_DATALEN; 3378 sc->areq.an_type = rid; 3379 3380 an_read_record(sc, (struct an_ltv_gen *)&sc->areq); 3381 3382 l_ioctl->len = sc->areq.an_len - 4; /* just data */ 3383 3384 AN_UNLOCK(sc); 3385 /* the data contains the length at first */ 3386 if (copyout(&(sc->areq.an_len), l_ioctl->data, 3387 sizeof(sc->areq.an_len))) { 3388 error = -EFAULT; 3389 goto lock_exit; 3390 } 3391 /* Just copy the data back */ 3392 if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, 3393 l_ioctl->len)) { 3394 error = -EFAULT; 3395 goto lock_exit; 3396 } 3397 error = 0; 3398lock_exit: 3399 AN_LOCK(sc); 3400 return (error); 3401} 3402 3403static int 3404writerids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) 3405{ 3406 struct an_softc *sc; 3407 int rid, command, error; 3408 3409 sc = ifp->if_softc; 3410 AN_LOCK_ASSERT(sc); 3411 rid = 0; 3412 command = l_ioctl->command; 3413 3414 switch (command) { 3415 case AIROPSIDS: 3416 rid = AN_RID_SSIDLIST; 3417 break; 3418 case AIROPCAP: 3419 rid = AN_RID_CAPABILITIES; 3420 break; 3421 case AIROPAPLIST: 3422 rid = AN_RID_APLIST; 3423 break; 3424 case AIROPCFG: 3425 rid = AN_RID_GENCONFIG; 3426 break; 3427 case AIROPMACON: 3428 an_cmd(sc, AN_CMD_ENABLE, 0); 3429 return 0; 3430 break; 3431 case AIROPMACOFF: 3432 an_cmd(sc, AN_CMD_DISABLE, 0); 3433 return 0; 3434 break; 3435 case AIROPSTCLR: 3436 /* 3437 * This command merely clears the counts does not actually 3438 * store any data only reads rid. But as it changes the cards 3439 * state, I put it in the writerid routines. 3440 */ 3441 3442 rid = AN_RID_32BITS_DELTACLR; 3443 sc = ifp->if_softc; 3444 sc->areq.an_len = AN_MAX_DATALEN; 3445 sc->areq.an_type = rid; 3446 3447 an_read_record(sc, (struct an_ltv_gen *)&sc->areq); 3448 l_ioctl->len = sc->areq.an_len - 4; /* just data */ 3449 3450 AN_UNLOCK(sc); 3451 /* the data contains the length at first */ 3452 error = copyout(&(sc->areq.an_len), l_ioctl->data, 3453 sizeof(sc->areq.an_len)); 3454 if (error) { 3455 AN_LOCK(sc); 3456 return -EFAULT; 3457 } 3458 /* Just copy the data */ 3459 error = copyout(&(sc->areq.an_val), l_ioctl->data + 2, 3460 l_ioctl->len); 3461 AN_LOCK(sc); 3462 if (error) 3463 return -EFAULT; 3464 return 0; 3465 break; 3466 case AIROPWEPKEY: 3467 rid = AN_RID_WEP_TEMP; 3468 break; 3469 case AIROPWEPKEYNV: 3470 rid = AN_RID_WEP_PERM; 3471 break; 3472 case AIROPLEAPUSR: 3473 rid = AN_RID_LEAPUSERNAME; 3474 break; 3475 case AIROPLEAPPWD: 3476 rid = AN_RID_LEAPPASSWORD; 3477 break; 3478 default: 3479 return -EOPNOTSUPP; 3480 } 3481 3482 if (rid) { 3483 if (l_ioctl->len > sizeof(sc->areq.an_val) + 4) 3484 return -EINVAL; 3485 sc->areq.an_len = l_ioctl->len + 4; /* add type & length */ 3486 sc->areq.an_type = rid; 3487 3488 /* Just copy the data back */ 3489 AN_UNLOCK(sc); 3490 error = copyin((l_ioctl->data) + 2, &sc->areq.an_val, 3491 l_ioctl->len); 3492 AN_LOCK(sc); 3493 if (error) 3494 return -EFAULT; 3495 3496 an_cmd(sc, AN_CMD_DISABLE, 0); 3497 an_write_record(sc, (struct an_ltv_gen *)&sc->areq); 3498 an_cmd(sc, AN_CMD_ENABLE, 0); 3499 return 0; 3500 } 3501 return -EOPNOTSUPP; 3502} 3503 3504/* 3505 * General Flash utilities derived from Cisco driver additions to Ben Reed's 3506 * Linux driver 3507 */ 3508 3509#define FLASH_DELAY(_sc, x) msleep(ifp, &(_sc)->an_mtx, PZERO, \ 3510 "flash", ((x) / hz) + 1); 3511#define FLASH_COMMAND 0x7e7e 3512#define FLASH_SIZE 32 * 1024 3513 3514static int 3515unstickbusy(struct ifnet *ifp) 3516{ 3517 struct an_softc *sc = ifp->if_softc; 3518 3519 if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { 3520 CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 3521 AN_EV_CLR_STUCK_BUSY); 3522 return 1; 3523 } 3524 return 0; 3525} 3526 3527/* 3528 * Wait for busy completion from card wait for delay uSec's Return true for 3529 * success meaning command reg is clear 3530 */ 3531 3532static int 3533WaitBusy(struct ifnet *ifp, int uSec) 3534{ 3535 int statword = 0xffff; 3536 int delay = 0; 3537 struct an_softc *sc = ifp->if_softc; 3538 3539 while ((statword & AN_CMD_BUSY) && delay <= (1000 * 100)) { 3540 FLASH_DELAY(sc, 10); 3541 delay += 10; 3542 statword = CSR_READ_2(sc, AN_COMMAND(sc->mpi350)); 3543 3544 if ((AN_CMD_BUSY & statword) && (delay % 200)) { 3545 unstickbusy(ifp); 3546 } 3547 } 3548 3549 return 0 == (AN_CMD_BUSY & statword); 3550} 3551 3552/* 3553 * STEP 1) Disable MAC and do soft reset on card. 3554 */ 3555 3556static int 3557cmdreset(struct ifnet *ifp) 3558{ 3559 int status; 3560 struct an_softc *sc = ifp->if_softc; 3561 3562 an_stop(sc); 3563 3564 AN_LOCK(sc); 3565 an_cmd(sc, AN_CMD_DISABLE, 0); 3566 3567 if (!(status = WaitBusy(ifp, AN_TIMEOUT))) { 3568 printf("an%d: Waitbusy hang b4 RESET =%d\n", 3569 sc->an_unit, status); 3570 AN_UNLOCK(sc); 3571 return -EBUSY; 3572 } 3573 CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), AN_CMD_FW_RESTART); 3574 3575 FLASH_DELAY(sc, 1000); /* WAS 600 12/7/00 */ 3576 3577 3578 if (!(status = WaitBusy(ifp, 100))) { 3579 printf("an%d: Waitbusy hang AFTER RESET =%d\n", 3580 sc->an_unit, status); 3581 AN_UNLOCK(sc); 3582 return -EBUSY; 3583 } 3584 AN_UNLOCK(sc); 3585 return 0; 3586} 3587 3588/* 3589 * STEP 2) Put the card in legendary flash mode 3590 */ 3591 3592static int 3593setflashmode(struct ifnet *ifp) 3594{ 3595 int status; 3596 struct an_softc *sc = ifp->if_softc; 3597 3598 CSR_WRITE_2(sc, AN_SW0(sc->mpi350), FLASH_COMMAND); 3599 CSR_WRITE_2(sc, AN_SW1(sc->mpi350), FLASH_COMMAND); 3600 CSR_WRITE_2(sc, AN_SW0(sc->mpi350), FLASH_COMMAND); 3601 CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), FLASH_COMMAND); 3602 3603 /* 3604 * mdelay(500); // 500ms delay 3605 */ 3606 3607 FLASH_DELAY(sc, 500); 3608 3609 if (!(status = WaitBusy(ifp, AN_TIMEOUT))) { 3610 printf("Waitbusy hang after setflash mode\n"); 3611 return -EIO; 3612 } 3613 return 0; 3614} 3615 3616/* 3617 * Get a character from the card matching matchbyte Step 3) 3618 */ 3619 3620static int 3621flashgchar(struct ifnet *ifp, int matchbyte, int dwelltime) 3622{ 3623 int rchar; 3624 unsigned char rbyte = 0; 3625 int success = -1; 3626 struct an_softc *sc = ifp->if_softc; 3627 3628 3629 do { 3630 rchar = CSR_READ_2(sc, AN_SW1(sc->mpi350)); 3631 3632 if (dwelltime && !(0x8000 & rchar)) { 3633 dwelltime -= 10; 3634 FLASH_DELAY(sc, 10); 3635 continue; 3636 } 3637 rbyte = 0xff & rchar; 3638 3639 if ((rbyte == matchbyte) && (0x8000 & rchar)) { 3640 CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0); 3641 success = 1; 3642 break; 3643 } 3644 if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar) 3645 break; 3646 CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0); 3647 3648 } while (dwelltime > 0); 3649 return success; 3650} 3651 3652/* 3653 * Put character to SWS0 wait for dwelltime x 50us for echo . 3654 */ 3655 3656static int 3657flashpchar(struct ifnet *ifp, int byte, int dwelltime) 3658{ 3659 int echo; 3660 int pollbusy, waittime; 3661 struct an_softc *sc = ifp->if_softc; 3662 3663 byte |= 0x8000; 3664 3665 if (dwelltime == 0) 3666 dwelltime = 200; 3667 3668 waittime = dwelltime; 3669 3670 /* 3671 * Wait for busy bit d15 to go false indicating buffer empty 3672 */ 3673 do { 3674 pollbusy = CSR_READ_2(sc, AN_SW0(sc->mpi350)); 3675 3676 if (pollbusy & 0x8000) { 3677 FLASH_DELAY(sc, 50); 3678 waittime -= 50; 3679 continue; 3680 } else 3681 break; 3682 } 3683 while (waittime >= 0); 3684 3685 /* timeout for busy clear wait */ 3686 3687 if (waittime <= 0) { 3688 printf("an%d: flash putchar busywait timeout! \n", 3689 sc->an_unit); 3690 return -1; 3691 } 3692 /* 3693 * Port is clear now write byte and wait for it to echo back 3694 */ 3695 do { 3696 CSR_WRITE_2(sc, AN_SW0(sc->mpi350), byte); 3697 FLASH_DELAY(sc, 50); 3698 dwelltime -= 50; 3699 echo = CSR_READ_2(sc, AN_SW1(sc->mpi350)); 3700 } while (dwelltime >= 0 && echo != byte); 3701 3702 3703 CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0); 3704 3705 return echo == byte; 3706} 3707 3708/* 3709 * Transfer 32k of firmware data from user buffer to our buffer and send to 3710 * the card 3711 */ 3712 3713static int 3714flashputbuf(struct ifnet *ifp) 3715{ 3716 unsigned short *bufp; 3717 int nwords; 3718 struct an_softc *sc = ifp->if_softc; 3719 3720 /* Write stuff */ 3721 3722 bufp = sc->an_flash_buffer; 3723 3724 if (!sc->mpi350) { 3725 CSR_WRITE_2(sc, AN_AUX_PAGE, 0x100); 3726 CSR_WRITE_2(sc, AN_AUX_OFFSET, 0); 3727 3728 for (nwords = 0; nwords != FLASH_SIZE / 2; nwords++) { 3729 CSR_WRITE_2(sc, AN_AUX_DATA, bufp[nwords] & 0xffff); 3730 } 3731 } else { 3732 for (nwords = 0; nwords != FLASH_SIZE / 4; nwords++) { 3733 CSR_MEM_AUX_WRITE_4(sc, 0x8000, 3734 ((u_int32_t *)bufp)[nwords] & 0xffff); 3735 } 3736 } 3737 3738 CSR_WRITE_2(sc, AN_SW0(sc->mpi350), 0x8000); 3739 3740 return 0; 3741} 3742 3743/* 3744 * After flashing restart the card. 3745 */ 3746 3747static int 3748flashrestart(struct ifnet *ifp) 3749{ 3750 int status = 0; 3751 struct an_softc *sc = ifp->if_softc; 3752 3753 FLASH_DELAY(sc, 1024); /* Added 12/7/00 */ 3754 3755 AN_UNLOCK(sc); 3756 an_init(sc); 3757 AN_LOCK(sc); 3758 3759 FLASH_DELAY(sc, 1024); /* Added 12/7/00 */ 3760 return status; 3761} 3762 3763/* 3764 * Entry point for flash ioclt. 3765 */ 3766 3767static int 3768flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) 3769{ 3770 int z = 0, status; 3771 struct an_softc *sc; 3772 3773 sc = ifp->if_softc; 3774 if (sc->mpi350) { 3775 printf("an%d: flashing not supported on MPI 350 yet\n", 3776 sc->an_unit); 3777 return(-1); 3778 } 3779 status = l_ioctl->command; 3780 3781 switch (l_ioctl->command) { 3782 case AIROFLSHRST: 3783 return cmdreset(ifp); 3784 break; 3785 case AIROFLSHSTFL: 3786 if (sc->an_flash_buffer) { 3787 free(sc->an_flash_buffer, M_DEVBUF); 3788 sc->an_flash_buffer = NULL; 3789 } 3790 sc->an_flash_buffer = malloc(FLASH_SIZE, M_DEVBUF, M_WAITOK); 3791 if (sc->an_flash_buffer) 3792 return setflashmode(ifp); 3793 else 3794 return ENOBUFS; 3795 break; 3796 case AIROFLSHGCHR: /* Get char from aux */ 3797 AN_UNLOCK(sc); 3798 status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len); 3799 AN_LOCK(sc); 3800 if (status) 3801 return status; 3802 z = *(int *)&sc->areq; 3803 if ((status = flashgchar(ifp, z, 8000)) == 1) 3804 return 0; 3805 else 3806 return -1; 3807 case AIROFLSHPCHR: /* Send char to card. */ 3808 AN_UNLOCK(sc); 3809 status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len); 3810 AN_LOCK(sc); 3811 if (status) 3812 return status; 3813 z = *(int *)&sc->areq; 3814 if ((status = flashpchar(ifp, z, 8000)) == -1) 3815 return -EIO; 3816 else 3817 return 0; 3818 break; 3819 case AIROFLPUTBUF: /* Send 32k to card */ 3820 if (l_ioctl->len > FLASH_SIZE) { 3821 printf("an%d: Buffer to big, %x %x\n", sc->an_unit, 3822 l_ioctl->len, FLASH_SIZE); 3823 return -EINVAL; 3824 } 3825 AN_UNLOCK(sc); 3826 status = copyin(l_ioctl->data, sc->an_flash_buffer, l_ioctl->len); 3827 AN_LOCK(sc); 3828 if (status) 3829 return status; 3830 3831 if ((status = flashputbuf(ifp)) != 0) 3832 return -EIO; 3833 else 3834 return 0; 3835 break; 3836 case AIRORESTART: 3837 if ((status = flashrestart(ifp)) != 0) { 3838 printf("an%d: FLASHRESTART returned %d\n", 3839 sc->an_unit, status); 3840 return -EIO; 3841 } else 3842 return 0; 3843 3844 break; 3845 default: 3846 return -EINVAL; 3847 } 3848 3849 return -EINVAL; 3850} 3851