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