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