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