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