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