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