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