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