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