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