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