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