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