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