if_an.c revision 106937
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 * $FreeBSD: head/sys/dev/an/if_an.c 106937 2002-11-14 23:54:55Z sam $ 33 */ 34 35/* 36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City 41 */ 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/systm.h> 92#include <sys/sockio.h> 93#include <sys/mbuf.h> 94#include <sys/proc.h> 95#include <sys/kernel.h> 96#include <sys/socket.h> 97#ifdef ANCACHE 98#include <sys/syslog.h> 99#include <sys/sysctl.h> 100#endif 101 102#include <sys/module.h> 103#include <sys/sysctl.h> 104#include <sys/bus.h> 105#include <machine/bus.h> 106#include <sys/rman.h> 107#include <sys/lock.h> 108#include <sys/mutex.h> 109#include <machine/resource.h> 110 111#include <net/if.h> 112#include <net/if_arp.h> 113#include <net/ethernet.h> 114#include <net/if_dl.h> 115#include <net/if_types.h> 116#include <net/if_ieee80211.h> 117#include <net/if_media.h> 118 119#ifdef INET 120#include <netinet/in.h> 121#include <netinet/in_systm.h> 122#include <netinet/in_var.h> 123#include <netinet/ip.h> 124#endif 125 126#include <net/bpf.h> 127 128#include <machine/md_var.h> 129 130#include <dev/an/if_aironet_ieee.h> 131#include <dev/an/if_anreg.h> 132 133#if !defined(lint) 134static const char rcsid[] = 135 "$FreeBSD: head/sys/dev/an/if_an.c 106937 2002-11-14 23:54:55Z sam $"; 136#endif 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_ioctl (struct ifnet *, u_long, caddr_t); 141static void an_init (void *); 142static int an_init_tx_ring (struct an_softc *); 143static void an_start (struct ifnet *); 144static void an_watchdog (struct ifnet *); 145static void an_rxeof (struct an_softc *); 146static void an_txeof (struct an_softc *, int); 147 148static void an_promisc (struct an_softc *, int); 149static int an_cmd (struct an_softc *, int, int); 150static int an_read_record (struct an_softc *, struct an_ltv_gen *); 151static int an_write_record (struct an_softc *, struct an_ltv_gen *); 152static int an_read_data (struct an_softc *, int, int, caddr_t, int); 153static int an_write_data (struct an_softc *, int, int, caddr_t, int); 154static int an_seek (struct an_softc *, int, int, int); 155static int an_alloc_nicmem (struct an_softc *, int, int *); 156static void an_stats_update (void *); 157static void an_setdef (struct an_softc *, struct an_req *); 158#ifdef ANCACHE 159static void an_cache_store (struct an_softc *, struct ether_header *, 160 struct mbuf *, unsigned short); 161#endif 162 163/* function definitions for use with the Cisco's Linux configuration 164 utilities 165*/ 166 167static int readrids(struct ifnet*, struct aironet_ioctl*); 168static int writerids(struct ifnet*, struct aironet_ioctl*); 169static int flashcard(struct ifnet*, struct aironet_ioctl*); 170 171static int cmdreset(struct ifnet *); 172static int setflashmode(struct ifnet *); 173static int flashgchar(struct ifnet *,int,int); 174static int flashpchar(struct ifnet *,int,int); 175static int flashputbuf(struct ifnet *); 176static int flashrestart(struct ifnet *); 177static int WaitBusy(struct ifnet *, int); 178static int unstickbusy(struct ifnet *); 179 180static void an_dump_record (struct an_softc *,struct an_ltv_gen *, 181 char *); 182 183static int an_media_change (struct ifnet *); 184static void an_media_status (struct ifnet *, struct ifmediareq *); 185 186static int an_dump = 0; 187 188static char an_conf[256]; 189 190/* sysctl vars */ 191SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID"); 192 193/* XXX violate ethernet/netgraph callback hooks */ 194extern void (*ng_ether_attach_p)(struct ifnet *ifp); 195extern void (*ng_ether_detach_p)(struct ifnet *ifp); 196 197static int 198sysctl_an_dump(SYSCTL_HANDLER_ARGS) 199{ 200 int error, r, last; 201 char *s = an_conf; 202 203 last = an_dump; 204 bzero(an_conf, sizeof(an_conf)); 205 206 switch (an_dump) { 207 case 0: 208 strcat(an_conf, "off"); 209 break; 210 case 1: 211 strcat(an_conf, "type"); 212 break; 213 case 2: 214 strcat(an_conf, "dump"); 215 break; 216 default: 217 snprintf(an_conf, 5, "%x", an_dump); 218 break; 219 } 220 221 error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req); 222 223 if (strncmp(an_conf,"off", 4) == 0) { 224 an_dump = 0; 225 } 226 if (strncmp(an_conf,"dump", 4) == 0) { 227 an_dump = 1; 228 } 229 if (strncmp(an_conf,"type", 4) == 0) { 230 an_dump = 2; 231 } 232 if (*s == 'f') { 233 r = 0; 234 for (;;s++) { 235 if ((*s >= '0') && (*s <= '9')) { 236 r = r * 16 + (*s - '0'); 237 } else if ((*s >= 'a') && (*s <= 'f')) { 238 r = r * 16 + (*s - 'a' + 10); 239 } else { 240 break; 241 } 242 } 243 an_dump = r; 244 } 245 if (an_dump != last) 246 printf("Sysctl changed for Aironet driver\n"); 247 248 return error; 249} 250 251SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, 252 0, sizeof(an_conf), sysctl_an_dump, "A", ""); 253 254/* 255 * We probe for an Aironet 4500/4800 card by attempting to 256 * read the default SSID list. On reset, the first entry in 257 * the SSID list will contain the name "tsunami." If we don't 258 * find this, then there's no card present. 259 */ 260int 261an_probe(dev) 262 device_t dev; 263{ 264 struct an_softc *sc = device_get_softc(dev); 265 struct an_ltv_ssidlist ssid; 266 int error; 267 268 bzero((char *)&ssid, sizeof(ssid)); 269 270 error = an_alloc_port(dev, 0, AN_IOSIZ); 271 if (error != 0) 272 return (0); 273 274 /* can't do autoprobing */ 275 if (rman_get_start(sc->port_res) == -1) 276 return(0); 277 278 /* 279 * We need to fake up a softc structure long enough 280 * to be able to issue commands and call some of the 281 * other routines. 282 */ 283 sc->an_bhandle = rman_get_bushandle(sc->port_res); 284 sc->an_btag = rman_get_bustag(sc->port_res); 285 sc->an_unit = device_get_unit(dev); 286 287 ssid.an_len = sizeof(ssid); 288 ssid.an_type = AN_RID_SSIDLIST; 289 290 /* Make sure interrupts are disabled. */ 291 CSR_WRITE_2(sc, AN_INT_EN, 0); 292 CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF); 293 294 an_reset(sc); 295 296 if (an_cmd(sc, AN_CMD_READCFG, 0)) 297 return(0); 298 299 if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) 300 return(0); 301 302 /* See if the ssid matches what we expect ... but doesn't have to */ 303 if (strcmp(ssid.an_ssid1, AN_DEF_SSID)) 304 return(0); 305 306 return(AN_IOSIZ); 307} 308 309/* 310 * Allocate a port resource with the given resource id. 311 */ 312int 313an_alloc_port(dev, rid, size) 314 device_t dev; 315 int rid; 316 int size; 317{ 318 struct an_softc *sc = device_get_softc(dev); 319 struct resource *res; 320 321 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 322 0ul, ~0ul, size, RF_ACTIVE); 323 if (res) { 324 sc->port_rid = rid; 325 sc->port_res = res; 326 return (0); 327 } else { 328 return (ENOENT); 329 } 330} 331 332/* 333 * Allocate an irq resource with the given resource id. 334 */ 335int 336an_alloc_irq(dev, rid, flags) 337 device_t dev; 338 int rid; 339 int flags; 340{ 341 struct an_softc *sc = device_get_softc(dev); 342 struct resource *res; 343 344 res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 345 0ul, ~0ul, 1, (RF_ACTIVE | flags)); 346 if (res) { 347 sc->irq_rid = rid; 348 sc->irq_res = res; 349 return (0); 350 } else { 351 return (ENOENT); 352 } 353} 354 355/* 356 * Release all resources 357 */ 358void 359an_release_resources(dev) 360 device_t dev; 361{ 362 struct an_softc *sc = device_get_softc(dev); 363 364 if (sc->port_res) { 365 bus_release_resource(dev, SYS_RES_IOPORT, 366 sc->port_rid, sc->port_res); 367 sc->port_res = 0; 368 } 369 if (sc->irq_res) { 370 bus_release_resource(dev, SYS_RES_IRQ, 371 sc->irq_rid, sc->irq_res); 372 sc->irq_res = 0; 373 } 374} 375 376int 377an_attach(sc, unit, flags) 378 struct an_softc *sc; 379 int unit; 380 int flags; 381{ 382 struct ifnet *ifp = &sc->arpcom.ac_if; 383 384 mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_NETWORK_LOCK, 385 MTX_DEF | MTX_RECURSE); 386 AN_LOCK(sc); 387 388 sc->an_gone = 0; 389 sc->an_associated = 0; 390 sc->an_monitor = 0; 391 sc->an_was_monitor = 0; 392 393 /* Reset the NIC. */ 394 an_reset(sc); 395 396 /* Load factory config */ 397 if (an_cmd(sc, AN_CMD_READCFG, 0)) { 398 printf("an%d: failed to load config data\n", sc->an_unit); 399 AN_UNLOCK(sc); 400 mtx_destroy(&sc->an_mtx); 401 return(EIO); 402 } 403 404 /* Read the current configuration */ 405 sc->an_config.an_type = AN_RID_GENCONFIG; 406 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 407 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 408 printf("an%d: read record failed\n", sc->an_unit); 409 AN_UNLOCK(sc); 410 mtx_destroy(&sc->an_mtx); 411 return(EIO); 412 } 413 414 /* Read the card capabilities */ 415 sc->an_caps.an_type = AN_RID_CAPABILITIES; 416 sc->an_caps.an_len = sizeof(struct an_ltv_caps); 417 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) { 418 printf("an%d: read record failed\n", sc->an_unit); 419 AN_UNLOCK(sc); 420 mtx_destroy(&sc->an_mtx); 421 return(EIO); 422 } 423 424 /* Read ssid list */ 425 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 426 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist); 427 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 428 printf("an%d: read record failed\n", sc->an_unit); 429 AN_UNLOCK(sc); 430 mtx_destroy(&sc->an_mtx); 431 return(EIO); 432 } 433 434 /* Read AP list */ 435 sc->an_aplist.an_type = AN_RID_APLIST; 436 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 437 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 438 printf("an%d: read record failed\n", sc->an_unit); 439 AN_UNLOCK(sc); 440 mtx_destroy(&sc->an_mtx); 441 return(EIO); 442 } 443 444 bcopy((char *)&sc->an_caps.an_oemaddr, 445 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 446 447 printf("an%d: Ethernet address: %6D\n", sc->an_unit, 448 sc->arpcom.ac_enaddr, ":"); 449 450 ifp->if_softc = sc; 451 ifp->if_unit = sc->an_unit = unit; 452 ifp->if_name = "an"; 453 ifp->if_mtu = ETHERMTU; 454 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 455 ifp->if_ioctl = an_ioctl; 456 ifp->if_output = ether_output; 457 ifp->if_start = an_start; 458 ifp->if_watchdog = an_watchdog; 459 ifp->if_init = an_init; 460 ifp->if_baudrate = 10000000; 461 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 462 463 bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename)); 464 bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename, 465 sizeof(AN_DEFAULT_NODENAME) - 1); 466 467 bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1)); 468 bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1, 469 sizeof(AN_DEFAULT_NETNAME) - 1); 470 sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME); 471 472 sc->an_config.an_opmode = 473 AN_OPMODE_INFRASTRUCTURE_STATION; 474 475 sc->an_tx_rate = 0; 476 bzero((char *)&sc->an_stats, sizeof(sc->an_stats)); 477 478 ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status); 479#define ADD(m, c) ifmedia_add(&sc->an_ifmedia, (m), (c), NULL) 480 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 481 IFM_IEEE80211_ADHOC, 0), 0); 482 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 483 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 484 IFM_IEEE80211_ADHOC, 0), 0); 485 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 486 if (sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) { 487 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 488 IFM_IEEE80211_ADHOC, 0), 0); 489 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 490 } 491 if (sc->an_caps.an_rates[3] == AN_RATE_11MBPS) { 492 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 493 IFM_IEEE80211_ADHOC, 0), 0); 494 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 495 } 496 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 497 IFM_IEEE80211_ADHOC, 0), 0); 498 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 499#undef ADD 500 ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 501 0, 0)); 502 503 /* 504 * Call MI attach routine. 505 */ 506 ether_ifattach(ifp, sc->arpcom.ac_enaddr); 507 callout_handle_init(&sc->an_stat_ch); 508 AN_UNLOCK(sc); 509 510 return(0); 511} 512 513static void 514an_rxeof(sc) 515 struct an_softc *sc; 516{ 517 struct ifnet *ifp; 518 struct ether_header *eh; 519 struct ieee80211_frame *ih; 520 struct an_rxframe rx_frame; 521 struct an_rxframe_802_3 rx_frame_802_3; 522 struct mbuf *m; 523 int len, id, error = 0; 524 int ieee80211_header_len; 525 u_char *bpf_buf; 526 u_short fc1; 527 528 ifp = &sc->arpcom.ac_if; 529 530 id = CSR_READ_2(sc, AN_RX_FID); 531 532 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 533 /* read raw 802.11 packet */ 534 bpf_buf = sc->buf_802_11; 535 536 /* read header */ 537 if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame, 538 sizeof(rx_frame))) { 539 ifp->if_ierrors++; 540 return; 541 } 542 543 /* 544 * skip beacon by default since this increases the 545 * system load a lot 546 */ 547 548 if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) && 549 (rx_frame.an_frame_ctl & IEEE80211_FC0_SUBTYPE_BEACON)) { 550 return; 551 } 552 553 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 554 len = rx_frame.an_rx_payload_len 555 + sizeof(rx_frame); 556 /* Check for insane frame length */ 557 if (len > sizeof(sc->buf_802_11)) { 558 printf("an%d: oversized packet received (%d, %d)\n", 559 sc->an_unit, len, MCLBYTES); 560 ifp->if_ierrors++; 561 return; 562 } 563 564 bcopy((char *)&rx_frame, 565 bpf_buf, sizeof(rx_frame)); 566 567 error = an_read_data(sc, id, sizeof(rx_frame), 568 (caddr_t)bpf_buf+sizeof(rx_frame), 569 rx_frame.an_rx_payload_len); 570 } else { 571 fc1=rx_frame.an_frame_ctl >> 8; 572 ieee80211_header_len = sizeof(struct ieee80211_frame); 573 if ((fc1 & IEEE80211_FC1_DIR_TODS) && 574 (fc1 & IEEE80211_FC1_DIR_FROMDS)) { 575 ieee80211_header_len += ETHER_ADDR_LEN; 576 } 577 578 len = rx_frame.an_rx_payload_len 579 + ieee80211_header_len; 580 /* Check for insane frame length */ 581 if (len > sizeof(sc->buf_802_11)) { 582 printf("an%d: oversized packet received (%d, %d)\n", 583 sc->an_unit, len, MCLBYTES); 584 ifp->if_ierrors++; 585 return; 586 } 587 588 ih = (struct ieee80211_frame *)bpf_buf; 589 590 bcopy((char *)&rx_frame.an_frame_ctl, 591 (char *)ih, ieee80211_header_len); 592 593 error = an_read_data(sc, id, sizeof(rx_frame) + 594 rx_frame.an_gaplen, 595 (caddr_t)ih +ieee80211_header_len, 596 rx_frame.an_rx_payload_len); 597 } 598 /* dump raw 802.11 packet to bpf and skip ip stack */ 599 BPF_TAP(ifp, bpf_buf, len); 600 } else { 601 MGETHDR(m, M_DONTWAIT, MT_DATA); 602 if (m == NULL) { 603 ifp->if_ierrors++; 604 return; 605 } 606 MCLGET(m, M_DONTWAIT); 607 if (!(m->m_flags & M_EXT)) { 608 m_freem(m); 609 ifp->if_ierrors++; 610 return; 611 } 612 m->m_pkthdr.rcvif = ifp; 613 /* Read Ethernet encapsulated packet */ 614 615#ifdef ANCACHE 616 /* Read NIC frame header */ 617 if (an_read_data(sc, id, 0, (caddr_t) & rx_frame, sizeof(rx_frame))) { 618 ifp->if_ierrors++; 619 return; 620 } 621#endif 622 /* Read in the 802_3 frame header */ 623 if (an_read_data(sc, id, 0x34, (caddr_t) & rx_frame_802_3, 624 sizeof(rx_frame_802_3))) { 625 ifp->if_ierrors++; 626 return; 627 } 628 if (rx_frame_802_3.an_rx_802_3_status != 0) { 629 ifp->if_ierrors++; 630 return; 631 } 632 /* Check for insane frame length */ 633 if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) { 634 ifp->if_ierrors++; 635 return; 636 } 637 m->m_pkthdr.len = m->m_len = 638 rx_frame_802_3.an_rx_802_3_payload_len + 12; 639 640 eh = mtod(m, struct ether_header *); 641 642 bcopy((char *)&rx_frame_802_3.an_rx_dst_addr, 643 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 644 bcopy((char *)&rx_frame_802_3.an_rx_src_addr, 645 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 646 647 /* in mbuf header type is just before payload */ 648 error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type), 649 rx_frame_802_3.an_rx_802_3_payload_len); 650 651 if (error) { 652 m_freem(m); 653 ifp->if_ierrors++; 654 return; 655 } 656 ifp->if_ipackets++; 657 658 /* Receive packet. */ 659#ifdef ANCACHE 660 an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength); 661#endif 662 (*ifp->if_input)(ifp, m); 663 } 664} 665 666static void 667an_txeof(sc, status) 668 struct an_softc *sc; 669 int status; 670{ 671 struct ifnet *ifp; 672 int id, i; 673 674 ifp = &sc->arpcom.ac_if; 675 676 ifp->if_timer = 0; 677 ifp->if_flags &= ~IFF_OACTIVE; 678 679 id = CSR_READ_2(sc, AN_TX_CMP_FID); 680 681 if (status & AN_EV_TX_EXC) { 682 ifp->if_oerrors++; 683 } else 684 ifp->if_opackets++; 685 686 for (i = 0; i < AN_TX_RING_CNT; i++) { 687 if (id == sc->an_rdata.an_tx_ring[i]) { 688 sc->an_rdata.an_tx_ring[i] = 0; 689 break; 690 } 691 } 692 693 AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT); 694 695 return; 696} 697 698/* 699 * We abuse the stats updater to check the current NIC status. This 700 * is important because we don't want to allow transmissions until 701 * the NIC has synchronized to the current cell (either as the master 702 * in an ad-hoc group, or as a station connected to an access point). 703 */ 704static void 705an_stats_update(xsc) 706 void *xsc; 707{ 708 struct an_softc *sc; 709 struct ifnet *ifp; 710 711 sc = xsc; 712 AN_LOCK(sc); 713 ifp = &sc->arpcom.ac_if; 714 715 sc->an_status.an_type = AN_RID_STATUS; 716 sc->an_status.an_len = sizeof(struct an_ltv_status); 717 an_read_record(sc, (struct an_ltv_gen *)&sc->an_status); 718 719 if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC) 720 sc->an_associated = 1; 721 else 722 sc->an_associated = 0; 723 724 /* Don't do this while we're transmitting */ 725 if (ifp->if_flags & IFF_OACTIVE) { 726 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 727 AN_UNLOCK(sc); 728 return; 729 } 730 731 sc->an_stats.an_len = sizeof(struct an_ltv_stats); 732 sc->an_stats.an_type = AN_RID_32BITS_CUM; 733 an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len); 734 735 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 736 AN_UNLOCK(sc); 737 738 return; 739} 740 741void 742an_intr(xsc) 743 void *xsc; 744{ 745 struct an_softc *sc; 746 struct ifnet *ifp; 747 u_int16_t status; 748 749 sc = (struct an_softc*)xsc; 750 751 AN_LOCK(sc); 752 753 if (sc->an_gone) { 754 AN_UNLOCK(sc); 755 return; 756 } 757 758 ifp = &sc->arpcom.ac_if; 759 760 /* Disable interrupts. */ 761 CSR_WRITE_2(sc, AN_INT_EN, 0); 762 763 status = CSR_READ_2(sc, AN_EVENT_STAT); 764 CSR_WRITE_2(sc, AN_EVENT_ACK, ~AN_INTRS); 765 766 if (status & AN_EV_AWAKE) { 767 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_AWAKE); 768 } 769 770 if (status & AN_EV_LINKSTAT) { 771 if (CSR_READ_2(sc, AN_LINKSTAT) == AN_LINKSTAT_ASSOCIATED) 772 sc->an_associated = 1; 773 else 774 sc->an_associated = 0; 775 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT); 776 } 777 778 if (status & AN_EV_RX) { 779 an_rxeof(sc); 780 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 781 } 782 783 if (status & AN_EV_TX) { 784 an_txeof(sc, status); 785 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX); 786 } 787 788 if (status & AN_EV_TX_EXC) { 789 an_txeof(sc, status); 790 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX_EXC); 791 } 792 793 if (status & AN_EV_ALLOC) 794 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 795 796 /* Re-enable interrupts. */ 797 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 798 799 if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL)) 800 an_start(ifp); 801 802 AN_UNLOCK(sc); 803 804 return; 805} 806 807static int 808an_cmd(sc, cmd, val) 809 struct an_softc *sc; 810 int cmd; 811 int val; 812{ 813 int i, s = 0; 814 815 CSR_WRITE_2(sc, AN_PARAM0, val); 816 CSR_WRITE_2(sc, AN_PARAM1, 0); 817 CSR_WRITE_2(sc, AN_PARAM2, 0); 818 CSR_WRITE_2(sc, AN_COMMAND, cmd); 819 820 for (i = 0; i < AN_TIMEOUT; i++) { 821 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD) 822 break; 823 else { 824 if (CSR_READ_2(sc, AN_COMMAND) == cmd) 825 CSR_WRITE_2(sc, AN_COMMAND, cmd); 826 } 827 } 828 829 for (i = 0; i < AN_TIMEOUT; i++) { 830 CSR_READ_2(sc, AN_RESP0); 831 CSR_READ_2(sc, AN_RESP1); 832 CSR_READ_2(sc, AN_RESP2); 833 s = CSR_READ_2(sc, AN_STATUS); 834 if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE)) 835 break; 836 } 837 838 /* Ack the command */ 839 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD); 840 841 if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) 842 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY); 843 844 if (i == AN_TIMEOUT) 845 return(ETIMEDOUT); 846 847 return(0); 848} 849 850/* 851 * This reset sequence may look a little strange, but this is the 852 * most reliable method I've found to really kick the NIC in the 853 * head and force it to reboot correctly. 854 */ 855static void 856an_reset(sc) 857 struct an_softc *sc; 858{ 859 if (sc->an_gone) 860 return; 861 862 an_cmd(sc, AN_CMD_ENABLE, 0); 863 an_cmd(sc, AN_CMD_FW_RESTART, 0); 864 an_cmd(sc, AN_CMD_NOOP2, 0); 865 866 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) 867 printf("an%d: reset failed\n", sc->an_unit); 868 869 an_cmd(sc, AN_CMD_DISABLE, 0); 870 871 return; 872} 873 874/* 875 * Read an LTV record from the NIC. 876 */ 877static int 878an_read_record(sc, ltv) 879 struct an_softc *sc; 880 struct an_ltv_gen *ltv; 881{ 882 u_int16_t *ptr; 883 u_int8_t *ptr2; 884 int i, len; 885 886 if (ltv->an_len < 4 || ltv->an_type == 0) 887 return(EINVAL); 888 889 /* Tell the NIC to enter record read mode. */ 890 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) { 891 printf("an%d: RID access failed\n", sc->an_unit); 892 return(EIO); 893 } 894 895 /* Seek to the record. */ 896 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) { 897 printf("an%d: seek to record failed\n", sc->an_unit); 898 return(EIO); 899 } 900 901 /* 902 * Read the length and record type and make sure they 903 * match what we expect (this verifies that we have enough 904 * room to hold all of the returned data). 905 * Length includes type but not length. 906 */ 907 len = CSR_READ_2(sc, AN_DATA1); 908 if (len > (ltv->an_len - 2)) { 909 printf("an%d: record length mismatch -- expected %d, " 910 "got %d for Rid %x\n", sc->an_unit, 911 ltv->an_len - 2, len, ltv->an_type); 912 len = ltv->an_len - 2; 913 } else { 914 ltv->an_len = len + 2; 915 } 916 917 /* Now read the data. */ 918 len -= 2; /* skip the type */ 919 ptr = <v->an_val; 920 for (i = len; i > 1; i -= 2) 921 *ptr++ = CSR_READ_2(sc, AN_DATA1); 922 if (i) { 923 ptr2 = (u_int8_t *)ptr; 924 *ptr2 = CSR_READ_1(sc, AN_DATA1); 925 } 926 if (an_dump) 927 an_dump_record(sc, ltv, "Read"); 928 929 return(0); 930} 931 932/* 933 * Same as read, except we inject data instead of reading it. 934 */ 935static int 936an_write_record(sc, ltv) 937 struct an_softc *sc; 938 struct an_ltv_gen *ltv; 939{ 940 u_int16_t *ptr; 941 u_int8_t *ptr2; 942 int i, len; 943 944 if (an_dump) 945 an_dump_record(sc, ltv, "Write"); 946 947 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) 948 return(EIO); 949 950 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) 951 return(EIO); 952 953 /* 954 * Length includes type but not length. 955 */ 956 len = ltv->an_len - 2; 957 CSR_WRITE_2(sc, AN_DATA1, len); 958 959 len -= 2; /* skip the type */ 960 ptr = <v->an_val; 961 for (i = len; i > 1; i -= 2) 962 CSR_WRITE_2(sc, AN_DATA1, *ptr++); 963 if (i) { 964 ptr2 = (u_int8_t *)ptr; 965 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 966 } 967 968 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) 969 return(EIO); 970 971 return(0); 972} 973 974static void 975an_dump_record(sc, ltv, string) 976 struct an_softc *sc; 977 struct an_ltv_gen *ltv; 978 char *string; 979{ 980 u_int8_t *ptr2; 981 int len; 982 int i; 983 int count = 0; 984 char buf[17], temp; 985 986 len = ltv->an_len - 4; 987 printf("an%d: RID %4x, Length %4d, Mode %s\n", 988 sc->an_unit, ltv->an_type, ltv->an_len - 4, string); 989 990 if (an_dump == 1 || (an_dump == ltv->an_type)) { 991 printf("an%d:\t", sc->an_unit); 992 bzero(buf,sizeof(buf)); 993 994 ptr2 = (u_int8_t *)<v->an_val; 995 for (i = len; i > 0; i--) { 996 printf("%02x ", *ptr2); 997 998 temp = *ptr2++; 999 if (temp >= ' ' && temp <= '~') 1000 buf[count] = temp; 1001 else if (temp >= 'A' && temp <= 'Z') 1002 buf[count] = temp; 1003 else 1004 buf[count] = '.'; 1005 if (++count == 16) { 1006 count = 0; 1007 printf("%s\n",buf); 1008 printf("an%d:\t", sc->an_unit); 1009 bzero(buf,sizeof(buf)); 1010 } 1011 } 1012 for (; count != 16; count++) { 1013 printf(" "); 1014 } 1015 printf(" %s\n",buf); 1016 } 1017} 1018 1019static int 1020an_seek(sc, id, off, chan) 1021 struct an_softc *sc; 1022 int id, off, chan; 1023{ 1024 int i; 1025 int selreg, offreg; 1026 1027 switch (chan) { 1028 case AN_BAP0: 1029 selreg = AN_SEL0; 1030 offreg = AN_OFF0; 1031 break; 1032 case AN_BAP1: 1033 selreg = AN_SEL1; 1034 offreg = AN_OFF1; 1035 break; 1036 default: 1037 printf("an%d: invalid data path: %x\n", sc->an_unit, chan); 1038 return(EIO); 1039 } 1040 1041 CSR_WRITE_2(sc, selreg, id); 1042 CSR_WRITE_2(sc, offreg, off); 1043 1044 for (i = 0; i < AN_TIMEOUT; i++) { 1045 if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR))) 1046 break; 1047 } 1048 1049 if (i == AN_TIMEOUT) 1050 return(ETIMEDOUT); 1051 1052 return(0); 1053} 1054 1055static int 1056an_read_data(sc, id, off, buf, len) 1057 struct an_softc *sc; 1058 int id, off; 1059 caddr_t buf; 1060 int len; 1061{ 1062 int i; 1063 u_int16_t *ptr; 1064 u_int8_t *ptr2; 1065 1066 if (off != -1) { 1067 if (an_seek(sc, id, off, AN_BAP1)) 1068 return(EIO); 1069 } 1070 1071 ptr = (u_int16_t *)buf; 1072 for (i = len; i > 1; i -= 2) 1073 *ptr++ = CSR_READ_2(sc, AN_DATA1); 1074 if (i) { 1075 ptr2 = (u_int8_t *)ptr; 1076 *ptr2 = CSR_READ_1(sc, AN_DATA1); 1077 } 1078 1079 return(0); 1080} 1081 1082static int 1083an_write_data(sc, id, off, buf, len) 1084 struct an_softc *sc; 1085 int id, off; 1086 caddr_t buf; 1087 int len; 1088{ 1089 int i; 1090 u_int16_t *ptr; 1091 u_int8_t *ptr2; 1092 1093 if (off != -1) { 1094 if (an_seek(sc, id, off, AN_BAP0)) 1095 return(EIO); 1096 } 1097 1098 ptr = (u_int16_t *)buf; 1099 for (i = len; i > 1; i -= 2) 1100 CSR_WRITE_2(sc, AN_DATA0, *ptr++); 1101 if (i) { 1102 ptr2 = (u_int8_t *)ptr; 1103 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 1104 } 1105 1106 return(0); 1107} 1108 1109/* 1110 * Allocate a region of memory inside the NIC and zero 1111 * it out. 1112 */ 1113static int 1114an_alloc_nicmem(sc, len, id) 1115 struct an_softc *sc; 1116 int len; 1117 int *id; 1118{ 1119 int i; 1120 1121 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 1122 printf("an%d: failed to allocate %d bytes on NIC\n", 1123 sc->an_unit, len); 1124 return(ENOMEM); 1125 } 1126 1127 for (i = 0; i < AN_TIMEOUT; i++) { 1128 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC) 1129 break; 1130 } 1131 1132 if (i == AN_TIMEOUT) 1133 return(ETIMEDOUT); 1134 1135 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 1136 *id = CSR_READ_2(sc, AN_ALLOC_FID); 1137 1138 if (an_seek(sc, *id, 0, AN_BAP0)) 1139 return(EIO); 1140 1141 for (i = 0; i < len / 2; i++) 1142 CSR_WRITE_2(sc, AN_DATA0, 0); 1143 1144 return(0); 1145} 1146 1147static void 1148an_setdef(sc, areq) 1149 struct an_softc *sc; 1150 struct an_req *areq; 1151{ 1152 struct sockaddr_dl *sdl; 1153 struct ifaddr *ifa; 1154 struct ifnet *ifp; 1155 struct an_ltv_genconfig *cfg; 1156 struct an_ltv_ssidlist *ssid; 1157 struct an_ltv_aplist *ap; 1158 struct an_ltv_gen *sp; 1159 1160 ifp = &sc->arpcom.ac_if; 1161 1162 switch (areq->an_type) { 1163 case AN_RID_GENCONFIG: 1164 cfg = (struct an_ltv_genconfig *)areq; 1165 1166 ifa = ifaddr_byindex(ifp->if_index); 1167 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1168 bcopy((char *)&cfg->an_macaddr, (char *)&sc->arpcom.ac_enaddr, 1169 ETHER_ADDR_LEN); 1170 bcopy((char *)&cfg->an_macaddr, LLADDR(sdl), ETHER_ADDR_LEN); 1171 1172 bcopy((char *)cfg, (char *)&sc->an_config, 1173 sizeof(struct an_ltv_genconfig)); 1174 break; 1175 case AN_RID_SSIDLIST: 1176 ssid = (struct an_ltv_ssidlist *)areq; 1177 bcopy((char *)ssid, (char *)&sc->an_ssidlist, 1178 sizeof(struct an_ltv_ssidlist)); 1179 break; 1180 case AN_RID_APLIST: 1181 ap = (struct an_ltv_aplist *)areq; 1182 bcopy((char *)ap, (char *)&sc->an_aplist, 1183 sizeof(struct an_ltv_aplist)); 1184 break; 1185 case AN_RID_TX_SPEED: 1186 sp = (struct an_ltv_gen *)areq; 1187 sc->an_tx_rate = sp->an_val; 1188 break; 1189 case AN_RID_WEP_TEMP: 1190 case AN_RID_WEP_PERM: 1191 case AN_RID_LEAPUSERNAME: 1192 case AN_RID_LEAPPASSWORD: 1193 /* Disable the MAC. */ 1194 an_cmd(sc, AN_CMD_DISABLE, 0); 1195 1196 /* Write the key */ 1197 an_write_record(sc, (struct an_ltv_gen *)areq); 1198 1199 /* Turn the MAC back on. */ 1200 an_cmd(sc, AN_CMD_ENABLE, 0); 1201 1202 break; 1203 case AN_RID_MONITOR_MODE: 1204 cfg = (struct an_ltv_genconfig *)areq; 1205 bpfdetach(ifp); 1206 if (ng_ether_detach_p != NULL) 1207 (*ng_ether_detach_p) (ifp); 1208 sc->an_monitor = cfg->an_len; 1209 1210 if (sc->an_monitor & AN_MONITOR) { 1211 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 1212 bpfattach(ifp, DLT_AIRONET_HEADER, 1213 sizeof(struct ether_header)); 1214 } else { 1215 bpfattach(ifp, DLT_IEEE802_11, 1216 sizeof(struct ether_header)); 1217 } 1218 } else { 1219 bpfattach(ifp, DLT_EN10MB, 1220 sizeof(struct ether_header)); 1221 if (ng_ether_attach_p != NULL) 1222 (*ng_ether_attach_p) (ifp); 1223 } 1224 break; 1225 default: 1226 printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type); 1227 return; 1228 break; 1229 } 1230 1231 1232 /* Reinitialize the card. */ 1233 if (ifp->if_flags) 1234 an_init(sc); 1235 1236 return; 1237} 1238 1239/* 1240 * Derived from Linux driver to enable promiscious mode. 1241 */ 1242 1243static void 1244an_promisc(sc, promisc) 1245 struct an_softc *sc; 1246 int promisc; 1247{ 1248 if (sc->an_was_monitor) 1249 an_reset(sc); 1250 if (sc->an_monitor || sc->an_was_monitor) 1251 an_init(sc); 1252 1253 sc->an_was_monitor = sc->an_monitor; 1254 an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0); 1255 1256 return; 1257} 1258 1259static int 1260an_ioctl(ifp, command, data) 1261 struct ifnet *ifp; 1262 u_long command; 1263 caddr_t data; 1264{ 1265 int error = 0; 1266 int len; 1267 int i; 1268 struct an_softc *sc; 1269 struct ifreq *ifr; 1270 struct thread *td = curthread; 1271 struct ieee80211req *ireq; 1272 u_int8_t tmpstr[IEEE80211_NWID_LEN*2]; 1273 u_int8_t *tmpptr; 1274 struct an_ltv_genconfig *config; 1275 struct an_ltv_key *key; 1276 struct an_ltv_status *status; 1277 struct an_ltv_ssidlist *ssids; 1278 int mode; 1279 struct aironet_ioctl l_ioctl; 1280 1281 sc = ifp->if_softc; 1282 AN_LOCK(sc); 1283 ifr = (struct ifreq *)data; 1284 ireq = (struct ieee80211req *)data; 1285 1286 config = (struct an_ltv_genconfig *)&sc->areq; 1287 key = (struct an_ltv_key *)&sc->areq; 1288 status = (struct an_ltv_status *)&sc->areq; 1289 ssids = (struct an_ltv_ssidlist *)&sc->areq; 1290 1291 if (sc->an_gone) { 1292 error = ENODEV; 1293 goto out; 1294 } 1295 1296 switch (command) { 1297 case SIOCSIFFLAGS: 1298 if (ifp->if_flags & IFF_UP) { 1299 if (ifp->if_flags & IFF_RUNNING && 1300 ifp->if_flags & IFF_PROMISC && 1301 !(sc->an_if_flags & IFF_PROMISC)) { 1302 an_promisc(sc, 1); 1303 } else if (ifp->if_flags & IFF_RUNNING && 1304 !(ifp->if_flags & IFF_PROMISC) && 1305 sc->an_if_flags & IFF_PROMISC) { 1306 an_promisc(sc, 0); 1307 } else 1308 an_init(sc); 1309 } else { 1310 if (ifp->if_flags & IFF_RUNNING) 1311 an_stop(sc); 1312 } 1313 sc->an_if_flags = ifp->if_flags; 1314 error = 0; 1315 break; 1316 case SIOCSIFMEDIA: 1317 case SIOCGIFMEDIA: 1318 error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command); 1319 break; 1320 case SIOCADDMULTI: 1321 case SIOCDELMULTI: 1322 /* The Aironet has no multicast filter. */ 1323 error = 0; 1324 break; 1325 case SIOCGAIRONET: 1326 error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); 1327 if (error != 0) 1328 break; 1329#ifdef ANCACHE 1330 if (sc->areq.an_type == AN_RID_ZERO_CACHE) { 1331 sc->an_sigitems = sc->an_nextitem = 0; 1332 break; 1333 } else if (sc->areq.an_type == AN_RID_READ_CACHE) { 1334 char *pt = (char *)&sc->areq.an_val; 1335 bcopy((char *)&sc->an_sigitems, (char *)pt, 1336 sizeof(int)); 1337 pt += sizeof(int); 1338 sc->areq.an_len = sizeof(int) / 2; 1339 bcopy((char *)&sc->an_sigcache, (char *)pt, 1340 sizeof(struct an_sigcache) * sc->an_sigitems); 1341 sc->areq.an_len += ((sizeof(struct an_sigcache) * 1342 sc->an_sigitems) / 2) + 1; 1343 } else 1344#endif 1345 if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { 1346 error = EINVAL; 1347 break; 1348 } 1349 error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq)); 1350 break; 1351 case SIOCSAIRONET: 1352 if ((error = suser(td))) 1353 goto out; 1354 error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); 1355 if (error != 0) 1356 break; 1357 an_setdef(sc, &sc->areq); 1358 break; 1359 case SIOCGPRIVATE_0: /* used by Cisco client utility */ 1360 if ((error = suser(td))) 1361 goto out; 1362 copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); 1363 mode = l_ioctl.command; 1364 1365 if (mode >= AIROGCAP && mode <= AIROGSTATSD32) { 1366 error = readrids(ifp, &l_ioctl); 1367 }else if (mode >= AIROPCAP && mode <= AIROPLEAPUSR) { 1368 error = writerids(ifp, &l_ioctl); 1369 }else if (mode >= AIROFLSHRST && mode <= AIRORESTART) { 1370 error = flashcard(ifp, &l_ioctl); 1371 }else{ 1372 error =-1; 1373 } 1374 1375 /* copy out the updated command info */ 1376 copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl)); 1377 1378 break; 1379 case SIOCGPRIVATE_1: /* used by Cisco client utility */ 1380 if ((error = suser(td))) 1381 goto out; 1382 copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); 1383 l_ioctl.command = 0; 1384 error = AIROMAGIC; 1385 copyout(&error, l_ioctl.data, sizeof(error)); 1386 error = 0; 1387 break; 1388 case SIOCG80211: 1389 sc->areq.an_len = sizeof(sc->areq); 1390 /* was that a good idea DJA we are doing a short-cut */ 1391 switch (ireq->i_type) { 1392 case IEEE80211_IOC_SSID: 1393 if (ireq->i_val == -1) { 1394 sc->areq.an_type = AN_RID_STATUS; 1395 if (an_read_record(sc, 1396 (struct an_ltv_gen *)&sc->areq)) { 1397 error = EINVAL; 1398 break; 1399 } 1400 len = status->an_ssidlen; 1401 tmpptr = status->an_ssid; 1402 } else if (ireq->i_val >= 0) { 1403 sc->areq.an_type = AN_RID_SSIDLIST; 1404 if (an_read_record(sc, 1405 (struct an_ltv_gen *)&sc->areq)) { 1406 error = EINVAL; 1407 break; 1408 } 1409 if (ireq->i_val == 0) { 1410 len = ssids->an_ssid1_len; 1411 tmpptr = ssids->an_ssid1; 1412 } else if (ireq->i_val == 1) { 1413 len = ssids->an_ssid2_len; 1414 tmpptr = ssids->an_ssid2; 1415 } else if (ireq->i_val == 2) { 1416 len = ssids->an_ssid3_len; 1417 tmpptr = ssids->an_ssid3; 1418 } else { 1419 error = EINVAL; 1420 break; 1421 } 1422 } else { 1423 error = EINVAL; 1424 break; 1425 } 1426 if (len > IEEE80211_NWID_LEN) { 1427 error = EINVAL; 1428 break; 1429 } 1430 ireq->i_len = len; 1431 bzero(tmpstr, IEEE80211_NWID_LEN); 1432 bcopy(tmpptr, tmpstr, len); 1433 error = copyout(tmpstr, ireq->i_data, 1434 IEEE80211_NWID_LEN); 1435 break; 1436 case IEEE80211_IOC_NUMSSIDS: 1437 ireq->i_val = 3; 1438 break; 1439 case IEEE80211_IOC_WEP: 1440 sc->areq.an_type = AN_RID_ACTUALCFG; 1441 if (an_read_record(sc, 1442 (struct an_ltv_gen *)&sc->areq)) { 1443 error = EINVAL; 1444 break; 1445 } 1446 if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { 1447 if (config->an_authtype & 1448 AN_AUTHTYPE_ALLOW_UNENCRYPTED) 1449 ireq->i_val = IEEE80211_WEP_MIXED; 1450 else 1451 ireq->i_val = IEEE80211_WEP_ON; 1452 } else { 1453 ireq->i_val = IEEE80211_WEP_OFF; 1454 } 1455 break; 1456 case IEEE80211_IOC_WEPKEY: 1457 /* 1458 * XXX: I'm not entierly convinced this is 1459 * correct, but it's what is implemented in 1460 * ancontrol so it will have to do until we get 1461 * access to actual Cisco code. 1462 */ 1463 if (ireq->i_val < 0 || ireq->i_val > 8) { 1464 error = EINVAL; 1465 break; 1466 } 1467 len = 0; 1468 if (ireq->i_val < 5) { 1469 sc->areq.an_type = AN_RID_WEP_TEMP; 1470 for (i = 0; i < 5; i++) { 1471 if (an_read_record(sc, 1472 (struct an_ltv_gen *)&sc->areq)) { 1473 error = EINVAL; 1474 break; 1475 } 1476 if (key->kindex == 0xffff) 1477 break; 1478 if (key->kindex == ireq->i_val) 1479 len = key->klen; 1480 /* Required to get next entry */ 1481 sc->areq.an_type = AN_RID_WEP_PERM; 1482 } 1483 if (error != 0) 1484 break; 1485 } 1486 /* We aren't allowed to read the value of the 1487 * key from the card so we just output zeros 1488 * like we would if we could read the card, but 1489 * denied the user access. 1490 */ 1491 bzero(tmpstr, len); 1492 ireq->i_len = len; 1493 error = copyout(tmpstr, ireq->i_data, len); 1494 break; 1495 case IEEE80211_IOC_NUMWEPKEYS: 1496 ireq->i_val = 9; /* include home key */ 1497 break; 1498 case IEEE80211_IOC_WEPTXKEY: 1499 /* 1500 * For some strange reason, you have to read all 1501 * keys before you can read the txkey. 1502 */ 1503 sc->areq.an_type = AN_RID_WEP_TEMP; 1504 for (i = 0; i < 5; i++) { 1505 if (an_read_record(sc, 1506 (struct an_ltv_gen *) &sc->areq)) { 1507 error = EINVAL; 1508 break; 1509 } 1510 if (key->kindex == 0xffff) 1511 break; 1512 /* Required to get next entry */ 1513 sc->areq.an_type = AN_RID_WEP_PERM; 1514 } 1515 if (error != 0) 1516 break; 1517 1518 sc->areq.an_type = AN_RID_WEP_PERM; 1519 key->kindex = 0xffff; 1520 if (an_read_record(sc, 1521 (struct an_ltv_gen *)&sc->areq)) { 1522 error = EINVAL; 1523 break; 1524 } 1525 ireq->i_val = key->mac[0]; 1526 /* 1527 * Check for home mode. Map home mode into 1528 * 5th key since that is how it is stored on 1529 * the card 1530 */ 1531 sc->areq.an_len = sizeof(struct an_ltv_genconfig); 1532 sc->areq.an_type = AN_RID_GENCONFIG; 1533 if (an_read_record(sc, 1534 (struct an_ltv_gen *)&sc->areq)) { 1535 error = EINVAL; 1536 break; 1537 } 1538 if (config->an_home_product & AN_HOME_NETWORK) 1539 ireq->i_val = 4; 1540 break; 1541 case IEEE80211_IOC_AUTHMODE: 1542 sc->areq.an_type = AN_RID_ACTUALCFG; 1543 if (an_read_record(sc, 1544 (struct an_ltv_gen *)&sc->areq)) { 1545 error = EINVAL; 1546 break; 1547 } 1548 if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1549 AN_AUTHTYPE_NONE) { 1550 ireq->i_val = IEEE80211_AUTH_NONE; 1551 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1552 AN_AUTHTYPE_OPEN) { 1553 ireq->i_val = IEEE80211_AUTH_OPEN; 1554 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1555 AN_AUTHTYPE_SHAREDKEY) { 1556 ireq->i_val = IEEE80211_AUTH_SHARED; 1557 } else 1558 error = EINVAL; 1559 break; 1560 case IEEE80211_IOC_STATIONNAME: 1561 sc->areq.an_type = AN_RID_ACTUALCFG; 1562 if (an_read_record(sc, 1563 (struct an_ltv_gen *)&sc->areq)) { 1564 error = EINVAL; 1565 break; 1566 } 1567 ireq->i_len = sizeof(config->an_nodename); 1568 tmpptr = config->an_nodename; 1569 bzero(tmpstr, IEEE80211_NWID_LEN); 1570 bcopy(tmpptr, tmpstr, ireq->i_len); 1571 error = copyout(tmpstr, ireq->i_data, 1572 IEEE80211_NWID_LEN); 1573 break; 1574 case IEEE80211_IOC_CHANNEL: 1575 sc->areq.an_type = AN_RID_STATUS; 1576 if (an_read_record(sc, 1577 (struct an_ltv_gen *)&sc->areq)) { 1578 error = EINVAL; 1579 break; 1580 } 1581 ireq->i_val = status->an_cur_channel; 1582 break; 1583 case IEEE80211_IOC_POWERSAVE: 1584 sc->areq.an_type = AN_RID_ACTUALCFG; 1585 if (an_read_record(sc, 1586 (struct an_ltv_gen *)&sc->areq)) { 1587 error = EINVAL; 1588 break; 1589 } 1590 if (config->an_psave_mode == AN_PSAVE_NONE) { 1591 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1592 } else if (config->an_psave_mode == AN_PSAVE_CAM) { 1593 ireq->i_val = IEEE80211_POWERSAVE_CAM; 1594 } else if (config->an_psave_mode == AN_PSAVE_PSP) { 1595 ireq->i_val = IEEE80211_POWERSAVE_PSP; 1596 } else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) { 1597 ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM; 1598 } else 1599 error = EINVAL; 1600 break; 1601 case IEEE80211_IOC_POWERSAVESLEEP: 1602 sc->areq.an_type = AN_RID_ACTUALCFG; 1603 if (an_read_record(sc, 1604 (struct an_ltv_gen *)&sc->areq)) { 1605 error = EINVAL; 1606 break; 1607 } 1608 ireq->i_val = config->an_listen_interval; 1609 break; 1610 } 1611 break; 1612 case SIOCS80211: 1613 if ((error = suser(td))) 1614 goto out; 1615 sc->areq.an_len = sizeof(sc->areq); 1616 /* 1617 * We need a config structure for everything but the WEP 1618 * key management and SSIDs so we get it now so avoid 1619 * duplicating this code every time. 1620 */ 1621 if (ireq->i_type != IEEE80211_IOC_SSID && 1622 ireq->i_type != IEEE80211_IOC_WEPKEY && 1623 ireq->i_type != IEEE80211_IOC_WEPTXKEY) { 1624 sc->areq.an_type = AN_RID_GENCONFIG; 1625 if (an_read_record(sc, 1626 (struct an_ltv_gen *)&sc->areq)) { 1627 error = EINVAL; 1628 break; 1629 } 1630 } 1631 switch (ireq->i_type) { 1632 case IEEE80211_IOC_SSID: 1633 sc->areq.an_type = AN_RID_SSIDLIST; 1634 if (an_read_record(sc, 1635 (struct an_ltv_gen *)&sc->areq)) { 1636 error = EINVAL; 1637 break; 1638 } 1639 if (ireq->i_len > IEEE80211_NWID_LEN) { 1640 error = EINVAL; 1641 break; 1642 } 1643 switch (ireq->i_val) { 1644 case 0: 1645 error = copyin(ireq->i_data, 1646 ssids->an_ssid1, ireq->i_len); 1647 ssids->an_ssid1_len = ireq->i_len; 1648 break; 1649 case 1: 1650 error = copyin(ireq->i_data, 1651 ssids->an_ssid2, ireq->i_len); 1652 ssids->an_ssid2_len = ireq->i_len; 1653 break; 1654 case 2: 1655 error = copyin(ireq->i_data, 1656 ssids->an_ssid3, ireq->i_len); 1657 ssids->an_ssid3_len = ireq->i_len; 1658 break; 1659 default: 1660 error = EINVAL; 1661 break; 1662 } 1663 break; 1664 case IEEE80211_IOC_WEP: 1665 switch (ireq->i_val) { 1666 case IEEE80211_WEP_OFF: 1667 config->an_authtype &= 1668 ~(AN_AUTHTYPE_PRIVACY_IN_USE | 1669 AN_AUTHTYPE_ALLOW_UNENCRYPTED); 1670 break; 1671 case IEEE80211_WEP_ON: 1672 config->an_authtype |= 1673 AN_AUTHTYPE_PRIVACY_IN_USE; 1674 config->an_authtype &= 1675 ~AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1676 break; 1677 case IEEE80211_WEP_MIXED: 1678 config->an_authtype |= 1679 AN_AUTHTYPE_PRIVACY_IN_USE | 1680 AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1681 break; 1682 default: 1683 error = EINVAL; 1684 break; 1685 } 1686 break; 1687 case IEEE80211_IOC_WEPKEY: 1688 if (ireq->i_val < 0 || ireq->i_val > 7 || 1689 ireq->i_len > 13) { 1690 error = EINVAL; 1691 break; 1692 } 1693 error = copyin(ireq->i_data, tmpstr, 13); 1694 if (error != 0) 1695 break; 1696 bzero(&sc->areq, sizeof(struct an_ltv_key)); 1697 sc->areq.an_len = sizeof(struct an_ltv_key); 1698 key->mac[0] = 1; /* The others are 0. */ 1699 key->kindex = ireq->i_val % 4; 1700 if (ireq->i_val < 4) 1701 sc->areq.an_type = AN_RID_WEP_TEMP; 1702 else 1703 sc->areq.an_type = AN_RID_WEP_PERM; 1704 key->klen = ireq->i_len; 1705 bcopy(tmpstr, key->key, key->klen); 1706 break; 1707 case IEEE80211_IOC_WEPTXKEY: 1708 /* 1709 * Map the 5th key into the home mode 1710 * since that is how it is stored on 1711 * the card 1712 */ 1713 if (ireq->i_val < 0 || ireq->i_val > 4) { 1714 error = EINVAL; 1715 break; 1716 } 1717 sc->areq.an_len = sizeof(struct an_ltv_genconfig); 1718 sc->areq.an_type = AN_RID_ACTUALCFG; 1719 if (an_read_record(sc, 1720 (struct an_ltv_gen *)&sc->areq)) { 1721 error = EINVAL; 1722 break; 1723 } 1724 if (ireq->i_val == 4) { 1725 config->an_home_product |= AN_HOME_NETWORK; 1726 ireq->i_val = 0; 1727 } else { 1728 config->an_home_product &= ~AN_HOME_NETWORK; 1729 } 1730 1731 sc->an_config.an_home_product 1732 = config->an_home_product; 1733 an_write_record(sc, (struct an_ltv_gen *)&sc->areq); 1734 1735 bzero(&sc->areq, sizeof(struct an_ltv_key)); 1736 sc->areq.an_len = sizeof(struct an_ltv_key); 1737 sc->areq.an_type = AN_RID_WEP_PERM; 1738 key->kindex = 0xffff; 1739 key->mac[0] = ireq->i_val; 1740 break; 1741 case IEEE80211_IOC_AUTHMODE: 1742 switch (ireq->i_val) { 1743 case IEEE80211_AUTH_NONE: 1744 config->an_authtype = AN_AUTHTYPE_NONE | 1745 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1746 break; 1747 case IEEE80211_AUTH_OPEN: 1748 config->an_authtype = AN_AUTHTYPE_OPEN | 1749 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1750 break; 1751 case IEEE80211_AUTH_SHARED: 1752 config->an_authtype = AN_AUTHTYPE_SHAREDKEY | 1753 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1754 break; 1755 default: 1756 error = EINVAL; 1757 } 1758 break; 1759 case IEEE80211_IOC_STATIONNAME: 1760 if (ireq->i_len > 16) { 1761 error = EINVAL; 1762 break; 1763 } 1764 bzero(config->an_nodename, 16); 1765 error = copyin(ireq->i_data, 1766 config->an_nodename, ireq->i_len); 1767 break; 1768 case IEEE80211_IOC_CHANNEL: 1769 /* 1770 * The actual range is 1-14, but if you set it 1771 * to 0 you get the default so we let that work 1772 * too. 1773 */ 1774 if (ireq->i_val < 0 || ireq->i_val >14) { 1775 error = EINVAL; 1776 break; 1777 } 1778 config->an_ds_channel = ireq->i_val; 1779 break; 1780 case IEEE80211_IOC_POWERSAVE: 1781 switch (ireq->i_val) { 1782 case IEEE80211_POWERSAVE_OFF: 1783 config->an_psave_mode = AN_PSAVE_NONE; 1784 break; 1785 case IEEE80211_POWERSAVE_CAM: 1786 config->an_psave_mode = AN_PSAVE_CAM; 1787 break; 1788 case IEEE80211_POWERSAVE_PSP: 1789 config->an_psave_mode = AN_PSAVE_PSP; 1790 break; 1791 case IEEE80211_POWERSAVE_PSP_CAM: 1792 config->an_psave_mode = AN_PSAVE_PSP_CAM; 1793 break; 1794 default: 1795 error = EINVAL; 1796 break; 1797 } 1798 break; 1799 case IEEE80211_IOC_POWERSAVESLEEP: 1800 config->an_listen_interval = ireq->i_val; 1801 break; 1802 } 1803 1804 if (!error) 1805 an_setdef(sc, &sc->areq); 1806 break; 1807 default: 1808 error = ether_ioctl(ifp, command, data); 1809 break; 1810 } 1811out: 1812 AN_UNLOCK(sc); 1813 1814 return(error != 0); 1815} 1816 1817static int 1818an_init_tx_ring(sc) 1819 struct an_softc *sc; 1820{ 1821 int i; 1822 int id; 1823 1824 if (sc->an_gone) 1825 return (0); 1826 1827 for (i = 0; i < AN_TX_RING_CNT; i++) { 1828 if (an_alloc_nicmem(sc, 1518 + 1829 0x44, &id)) 1830 return(ENOMEM); 1831 sc->an_rdata.an_tx_fids[i] = id; 1832 sc->an_rdata.an_tx_ring[i] = 0; 1833 } 1834 1835 sc->an_rdata.an_tx_prod = 0; 1836 sc->an_rdata.an_tx_cons = 0; 1837 1838 return(0); 1839} 1840 1841static void 1842an_init(xsc) 1843 void *xsc; 1844{ 1845 struct an_softc *sc = xsc; 1846 struct ifnet *ifp = &sc->arpcom.ac_if; 1847 1848 AN_LOCK(sc); 1849 1850 if (sc->an_gone) { 1851 AN_UNLOCK(sc); 1852 return; 1853 } 1854 1855 if (ifp->if_flags & IFF_RUNNING) 1856 an_stop(sc); 1857 1858 sc->an_associated = 0; 1859 1860 /* Allocate the TX buffers */ 1861 if (an_init_tx_ring(sc)) { 1862 an_reset(sc); 1863 if (an_init_tx_ring(sc)) { 1864 printf("an%d: tx buffer allocation " 1865 "failed\n", sc->an_unit); 1866 AN_UNLOCK(sc); 1867 return; 1868 } 1869 } 1870 1871 /* Set our MAC address. */ 1872 bcopy((char *)&sc->arpcom.ac_enaddr, 1873 (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN); 1874 1875 if (ifp->if_flags & IFF_BROADCAST) 1876 sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR; 1877 else 1878 sc->an_config.an_rxmode = AN_RXMODE_ADDR; 1879 1880 if (ifp->if_flags & IFF_MULTICAST) 1881 sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR; 1882 1883 if (ifp->if_flags & IFF_PROMISC) { 1884 if (sc->an_monitor & AN_MONITOR) { 1885 if (sc->an_monitor & AN_MONITOR_ANY_BSS) { 1886 sc->an_config.an_rxmode |= 1887 AN_RXMODE_80211_MONITOR_ANYBSS | 1888 AN_RXMODE_NO_8023_HEADER; 1889 } else { 1890 sc->an_config.an_rxmode |= 1891 AN_RXMODE_80211_MONITOR_CURBSS | 1892 AN_RXMODE_NO_8023_HEADER; 1893 } 1894 } 1895 } 1896 1897 /* Set the ssid list */ 1898 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 1899 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist); 1900 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 1901 printf("an%d: failed to set ssid list\n", sc->an_unit); 1902 AN_UNLOCK(sc); 1903 return; 1904 } 1905 1906 /* Set the AP list */ 1907 sc->an_aplist.an_type = AN_RID_APLIST; 1908 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 1909 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 1910 printf("an%d: failed to set AP list\n", sc->an_unit); 1911 AN_UNLOCK(sc); 1912 return; 1913 } 1914 1915 /* Set the configuration in the NIC */ 1916 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 1917 sc->an_config.an_type = AN_RID_GENCONFIG; 1918 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 1919 printf("an%d: failed to set configuration\n", sc->an_unit); 1920 AN_UNLOCK(sc); 1921 return; 1922 } 1923 1924 /* Enable the MAC */ 1925 if (an_cmd(sc, AN_CMD_ENABLE, 0)) { 1926 printf("an%d: failed to enable MAC\n", sc->an_unit); 1927 AN_UNLOCK(sc); 1928 return; 1929 } 1930 1931 if (ifp->if_flags & IFF_PROMISC) 1932 an_cmd(sc, AN_CMD_SET_MODE, 0xffff); 1933 1934 /* enable interrupts */ 1935 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 1936 1937 ifp->if_flags |= IFF_RUNNING; 1938 ifp->if_flags &= ~IFF_OACTIVE; 1939 1940 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 1941 AN_UNLOCK(sc); 1942 1943 return; 1944} 1945 1946static void 1947an_start(ifp) 1948 struct ifnet *ifp; 1949{ 1950 struct an_softc *sc; 1951 struct mbuf *m0 = NULL; 1952 struct an_txframe_802_3 tx_frame_802_3; 1953 struct ether_header *eh; 1954 int id; 1955 int idx; 1956 unsigned char txcontrol; 1957 1958 sc = ifp->if_softc; 1959 1960 if (sc->an_gone) 1961 return; 1962 1963 if (ifp->if_flags & IFF_OACTIVE) 1964 return; 1965 1966 if (!sc->an_associated) 1967 return; 1968 1969 /* We can't send in monitor mode so toss any attempts. */ 1970 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 1971 for (;;) { 1972 IF_DEQUEUE(&ifp->if_snd, m0); 1973 if (m0 == NULL) 1974 break; 1975 m_freem(m0); 1976 } 1977 return; 1978 } 1979 1980 idx = sc->an_rdata.an_tx_prod; 1981 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 1982 1983 while (sc->an_rdata.an_tx_ring[idx] == 0) { 1984 IF_DEQUEUE(&ifp->if_snd, m0); 1985 if (m0 == NULL) 1986 break; 1987 1988 id = sc->an_rdata.an_tx_fids[idx]; 1989 eh = mtod(m0, struct ether_header *); 1990 1991 bcopy((char *)&eh->ether_dhost, 1992 (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); 1993 bcopy((char *)&eh->ether_shost, 1994 (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); 1995 1996 tx_frame_802_3.an_tx_802_3_payload_len = 1997 m0->m_pkthdr.len - 12; /* minus src/dest mac & type */ 1998 1999 m_copydata(m0, sizeof(struct ether_header) - 2 , 2000 tx_frame_802_3.an_tx_802_3_payload_len, 2001 (caddr_t)&sc->an_txbuf); 2002 2003 txcontrol = AN_TXCTL_8023; 2004 /* write the txcontrol only */ 2005 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 2006 sizeof(txcontrol)); 2007 2008 /* 802_3 header */ 2009 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 2010 sizeof(struct an_txframe_802_3)); 2011 2012 /* in mbuf header type is just before payload */ 2013 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 2014 tx_frame_802_3.an_tx_802_3_payload_len); 2015 2016 /* 2017 * If there's a BPF listner, bounce a copy of 2018 * this frame to him. 2019 */ 2020 BPF_MTAP(ifp, m0); 2021 2022 m_freem(m0); 2023 m0 = NULL; 2024 2025 sc->an_rdata.an_tx_ring[idx] = id; 2026 if (an_cmd(sc, AN_CMD_TX, id)) 2027 printf("an%d: xmit failed\n", sc->an_unit); 2028 2029 AN_INC(idx, AN_TX_RING_CNT); 2030 } 2031 2032 if (m0 != NULL) 2033 ifp->if_flags |= IFF_OACTIVE; 2034 2035 sc->an_rdata.an_tx_prod = idx; 2036 2037 /* 2038 * Set a timeout in case the chip goes out to lunch. 2039 */ 2040 ifp->if_timer = 5; 2041 2042 return; 2043} 2044 2045void 2046an_stop(sc) 2047 struct an_softc *sc; 2048{ 2049 struct ifnet *ifp; 2050 int i; 2051 2052 AN_LOCK(sc); 2053 2054 if (sc->an_gone) { 2055 AN_UNLOCK(sc); 2056 return; 2057 } 2058 2059 ifp = &sc->arpcom.ac_if; 2060 2061 an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0); 2062 CSR_WRITE_2(sc, AN_INT_EN, 0); 2063 an_cmd(sc, AN_CMD_DISABLE, 0); 2064 2065 for (i = 0; i < AN_TX_RING_CNT; i++) 2066 an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]); 2067 2068 untimeout(an_stats_update, sc, sc->an_stat_ch); 2069 2070 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 2071 2072 AN_UNLOCK(sc); 2073 2074 return; 2075} 2076 2077static void 2078an_watchdog(ifp) 2079 struct ifnet *ifp; 2080{ 2081 struct an_softc *sc; 2082 2083 sc = ifp->if_softc; 2084 AN_LOCK(sc); 2085 2086 if (sc->an_gone) { 2087 AN_UNLOCK(sc); 2088 return; 2089 } 2090 2091 printf("an%d: device timeout\n", sc->an_unit); 2092 2093 an_reset(sc); 2094 an_init(sc); 2095 2096 ifp->if_oerrors++; 2097 AN_UNLOCK(sc); 2098 2099 return; 2100} 2101 2102void 2103an_shutdown(dev) 2104 device_t dev; 2105{ 2106 struct an_softc *sc; 2107 2108 sc = device_get_softc(dev); 2109 an_stop(sc); 2110 2111 return; 2112} 2113 2114#ifdef ANCACHE 2115/* Aironet signal strength cache code. 2116 * store signal/noise/quality on per MAC src basis in 2117 * a small fixed cache. The cache wraps if > MAX slots 2118 * used. The cache may be zeroed out to start over. 2119 * Two simple filters exist to reduce computation: 2120 * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used 2121 * to ignore some packets. It defaults to ip only. 2122 * it could be used to focus on broadcast, non-IP 802.11 beacons. 2123 * 2. multicast/broadcast only. This may be used to 2124 * ignore unicast packets and only cache signal strength 2125 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2126 * beacons and not unicast traffic. 2127 * 2128 * The cache stores (MAC src(index), IP src (major clue), signal, 2129 * quality, noise) 2130 * 2131 * No apologies for storing IP src here. It's easy and saves much 2132 * trouble elsewhere. The cache is assumed to be INET dependent, 2133 * although it need not be. 2134 * 2135 * Note: the Aironet only has a single byte of signal strength value 2136 * in the rx frame header, and it's not scaled to anything sensible. 2137 * This is kind of lame, but it's all we've got. 2138 */ 2139 2140#ifdef documentation 2141 2142int an_sigitems; /* number of cached entries */ 2143struct an_sigcache an_sigcache[MAXANCACHE]; /* array of cache entries */ 2144int an_nextitem; /* index/# of entries */ 2145 2146 2147#endif 2148 2149/* control variables for cache filtering. Basic idea is 2150 * to reduce cost (e.g., to only Mobile-IP agent beacons 2151 * which are broadcast or multicast). Still you might 2152 * want to measure signal strength anth unicast ping packets 2153 * on a pt. to pt. ant. setup. 2154 */ 2155/* set true if you want to limit cache items to broadcast/mcast 2156 * only packets (not unicast). Useful for mobile-ip beacons which 2157 * are broadcast/multicast at network layer. Default is all packets 2158 * so ping/unicast anll work say anth pt. to pt. antennae setup. 2159 */ 2160static int an_cache_mcastonly = 0; 2161SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, 2162 &an_cache_mcastonly, 0, ""); 2163 2164/* set true if you want to limit cache items to IP packets only 2165*/ 2166static int an_cache_iponly = 1; 2167SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, 2168 &an_cache_iponly, 0, ""); 2169 2170/* 2171 * an_cache_store, per rx packet store signal 2172 * strength in MAC (src) indexed cache. 2173 */ 2174static void 2175an_cache_store (sc, eh, m, rx_quality) 2176 struct an_softc *sc; 2177 struct ether_header *eh; 2178 struct mbuf *m; 2179 unsigned short rx_quality; 2180{ 2181 struct ip *ip = 0; 2182 int i; 2183 static int cache_slot = 0; /* use this cache entry */ 2184 static int wrapindex = 0; /* next "free" cache entry */ 2185 int type_ipv4 = 0; 2186 2187 /* filters: 2188 * 1. ip only 2189 * 2. configurable filter to throw out unicast packets, 2190 * keep multicast only. 2191 */ 2192 2193 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) { 2194 type_ipv4 = 1; 2195 } 2196 2197 /* filter for ip packets only 2198 */ 2199 if ( an_cache_iponly && !type_ipv4) { 2200 return; 2201 } 2202 2203 /* filter for broadcast/multicast only 2204 */ 2205 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2206 return; 2207 } 2208 2209#ifdef SIGDEBUG 2210 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 2211 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2212#endif 2213 2214 /* find the ip header. we want to store the ip_src 2215 * address. 2216 */ 2217 if (type_ipv4) { 2218 ip = mtod(m, struct ip *); 2219 } 2220 2221 /* do a linear search for a matching MAC address 2222 * in the cache table 2223 * . MAC address is 6 bytes, 2224 * . var w_nextitem holds total number of entries already cached 2225 */ 2226 for (i = 0; i < sc->an_nextitem; i++) { 2227 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 2228 /* Match!, 2229 * so we already have this entry, 2230 * update the data 2231 */ 2232 break; 2233 } 2234 } 2235 2236 /* did we find a matching mac address? 2237 * if yes, then overwrite a previously existing cache entry 2238 */ 2239 if (i < sc->an_nextitem ) { 2240 cache_slot = i; 2241 } 2242 /* else, have a new address entry,so 2243 * add this new entry, 2244 * if table full, then we need to replace LRU entry 2245 */ 2246 else { 2247 2248 /* check for space in cache table 2249 * note: an_nextitem also holds number of entries 2250 * added in the cache table 2251 */ 2252 if ( sc->an_nextitem < MAXANCACHE ) { 2253 cache_slot = sc->an_nextitem; 2254 sc->an_nextitem++; 2255 sc->an_sigitems = sc->an_nextitem; 2256 } 2257 /* no space found, so simply wrap anth wrap index 2258 * and "zap" the next entry 2259 */ 2260 else { 2261 if (wrapindex == MAXANCACHE) { 2262 wrapindex = 0; 2263 } 2264 cache_slot = wrapindex++; 2265 } 2266 } 2267 2268 /* invariant: cache_slot now points at some slot 2269 * in cache. 2270 */ 2271 if (cache_slot < 0 || cache_slot >= MAXANCACHE) { 2272 log(LOG_ERR, "an_cache_store, bad index: %d of " 2273 "[0..%d], gross cache error\n", 2274 cache_slot, MAXANCACHE); 2275 return; 2276 } 2277 2278 /* store items in cache 2279 * .ip source address 2280 * .mac src 2281 * .signal, etc. 2282 */ 2283 if (type_ipv4) { 2284 sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 2285 } 2286 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 2287 2288 sc->an_sigcache[cache_slot].signal = rx_quality; 2289 2290 return; 2291} 2292#endif 2293 2294static int 2295an_media_change(ifp) 2296 struct ifnet *ifp; 2297{ 2298 struct an_softc *sc = ifp->if_softc; 2299 int otype = sc->an_config.an_opmode; 2300 int orate = sc->an_tx_rate; 2301 2302 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2303 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; 2304 else 2305 sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION; 2306 2307 switch (IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)) { 2308 case IFM_IEEE80211_DS1: 2309 sc->an_tx_rate = AN_RATE_1MBPS; 2310 break; 2311 case IFM_IEEE80211_DS2: 2312 sc->an_tx_rate = AN_RATE_2MBPS; 2313 break; 2314 case IFM_IEEE80211_DS5: 2315 sc->an_tx_rate = AN_RATE_5_5MBPS; 2316 break; 2317 case IFM_IEEE80211_DS11: 2318 sc->an_tx_rate = AN_RATE_11MBPS; 2319 break; 2320 case IFM_AUTO: 2321 sc->an_tx_rate = 0; 2322 break; 2323 } 2324 2325 if (otype != sc->an_config.an_opmode || 2326 orate != sc->an_tx_rate) 2327 an_init(sc); 2328 2329 return(0); 2330} 2331 2332static void 2333an_media_status(ifp, imr) 2334 struct ifnet *ifp; 2335 struct ifmediareq *imr; 2336{ 2337 struct an_ltv_status status; 2338 struct an_softc *sc = ifp->if_softc; 2339 2340 status.an_len = sizeof(status); 2341 status.an_type = AN_RID_STATUS; 2342 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 2343 /* If the status read fails, just lie. */ 2344 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2345 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 2346 } 2347 2348 if (sc->an_tx_rate == 0) { 2349 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2350 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2351 imr->ifm_active |= IFM_IEEE80211_ADHOC; 2352 switch (status.an_current_tx_rate) { 2353 case AN_RATE_1MBPS: 2354 imr->ifm_active |= IFM_IEEE80211_DS1; 2355 break; 2356 case AN_RATE_2MBPS: 2357 imr->ifm_active |= IFM_IEEE80211_DS2; 2358 break; 2359 case AN_RATE_5_5MBPS: 2360 imr->ifm_active |= IFM_IEEE80211_DS5; 2361 break; 2362 case AN_RATE_11MBPS: 2363 imr->ifm_active |= IFM_IEEE80211_DS11; 2364 break; 2365 } 2366 } else { 2367 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2368 } 2369 2370 imr->ifm_status = IFM_AVALID; 2371 if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED) 2372 imr->ifm_status |= IFM_ACTIVE; 2373} 2374 2375/********************** Cisco utility support routines *************/ 2376 2377/* 2378 * ReadRids & WriteRids derived from Cisco driver additions to Ben Reed's 2379 * Linux driver 2380 */ 2381 2382static int 2383readrids(ifp, l_ioctl) 2384 struct ifnet *ifp; 2385 struct aironet_ioctl *l_ioctl; 2386{ 2387 unsigned short rid; 2388 struct an_softc *sc; 2389 2390 switch (l_ioctl->command) { 2391 case AIROGCAP: 2392 rid = AN_RID_CAPABILITIES; 2393 break; 2394 case AIROGCFG: 2395 rid = AN_RID_GENCONFIG; 2396 break; 2397 case AIROGSLIST: 2398 rid = AN_RID_SSIDLIST; 2399 break; 2400 case AIROGVLIST: 2401 rid = AN_RID_APLIST; 2402 break; 2403 case AIROGDRVNAM: 2404 rid = AN_RID_DRVNAME; 2405 break; 2406 case AIROGEHTENC: 2407 rid = AN_RID_ENCAPPROTO; 2408 break; 2409 case AIROGWEPKTMP: 2410 rid = AN_RID_WEP_TEMP; 2411 break; 2412 case AIROGWEPKNV: 2413 rid = AN_RID_WEP_PERM; 2414 break; 2415 case AIROGSTAT: 2416 rid = AN_RID_STATUS; 2417 break; 2418 case AIROGSTATSD32: 2419 rid = AN_RID_32BITS_DELTA; 2420 break; 2421 case AIROGSTATSC32: 2422 rid = AN_RID_32BITS_CUM; 2423 break; 2424 default: 2425 rid = 999; 2426 break; 2427 } 2428 2429 if (rid == 999) /* Is bad command */ 2430 return -EINVAL; 2431 2432 sc = ifp->if_softc; 2433 sc->areq.an_len = AN_MAX_DATALEN; 2434 sc->areq.an_type = rid; 2435 2436 an_read_record(sc, (struct an_ltv_gen *)&sc->areq); 2437 2438 l_ioctl->len = sc->areq.an_len - 4; /* just data */ 2439 2440 /* the data contains the length at first */ 2441 if (copyout(&(sc->areq.an_len), l_ioctl->data, 2442 sizeof(sc->areq.an_len))) { 2443 return -EFAULT; 2444 } 2445 /* Just copy the data back */ 2446 if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, 2447 l_ioctl->len)) { 2448 return -EFAULT; 2449 } 2450 return 0; 2451} 2452 2453static int 2454writerids(ifp, l_ioctl) 2455 struct ifnet *ifp; 2456 struct aironet_ioctl *l_ioctl; 2457{ 2458 struct an_softc *sc; 2459 int rid, command; 2460 2461 sc = ifp->if_softc; 2462 rid = 0; 2463 command = l_ioctl->command; 2464 2465 switch (command) { 2466 case AIROPSIDS: 2467 rid = AN_RID_SSIDLIST; 2468 break; 2469 case AIROPCAP: 2470 rid = AN_RID_CAPABILITIES; 2471 break; 2472 case AIROPAPLIST: 2473 rid = AN_RID_APLIST; 2474 break; 2475 case AIROPCFG: 2476 rid = AN_RID_GENCONFIG; 2477 break; 2478 case AIROPMACON: 2479 an_cmd(sc, AN_CMD_ENABLE, 0); 2480 return 0; 2481 break; 2482 case AIROPMACOFF: 2483 an_cmd(sc, AN_CMD_DISABLE, 0); 2484 return 0; 2485 break; 2486 case AIROPSTCLR: 2487 /* 2488 * This command merely clears the counts does not actually 2489 * store any data only reads rid. But as it changes the cards 2490 * state, I put it in the writerid routines. 2491 */ 2492 2493 rid = AN_RID_32BITS_DELTACLR; 2494 sc = ifp->if_softc; 2495 sc->areq.an_len = AN_MAX_DATALEN; 2496 sc->areq.an_type = rid; 2497 2498 an_read_record(sc, (struct an_ltv_gen *)&sc->areq); 2499 l_ioctl->len = sc->areq.an_len - 4; /* just data */ 2500 2501 /* the data contains the length at first */ 2502 if (copyout(&(sc->areq.an_len), l_ioctl->data, 2503 sizeof(sc->areq.an_len))) { 2504 return -EFAULT; 2505 } 2506 /* Just copy the data */ 2507 if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, 2508 l_ioctl->len)) { 2509 return -EFAULT; 2510 } 2511 return 0; 2512 break; 2513 case AIROPWEPKEY: 2514 rid = AN_RID_WEP_TEMP; 2515 break; 2516 case AIROPWEPKEYNV: 2517 rid = AN_RID_WEP_PERM; 2518 break; 2519 case AIROPLEAPUSR: 2520 rid = AN_RID_LEAPUSERNAME; 2521 break; 2522 case AIROPLEAPPWD: 2523 rid = AN_RID_LEAPPASSWORD; 2524 break; 2525 default: 2526 return -EOPNOTSUPP; 2527 } 2528 2529 if (rid) { 2530 if (l_ioctl->len > sizeof(sc->areq.an_val) + 4) 2531 return -EINVAL; 2532 sc->areq.an_len = l_ioctl->len + 4; /* add type & length */ 2533 sc->areq.an_type = rid; 2534 2535 /* Just copy the data back */ 2536 copyin((l_ioctl->data) + 2, &sc->areq.an_val, 2537 l_ioctl->len); 2538 2539 an_cmd(sc, AN_CMD_DISABLE, 0); 2540 an_write_record(sc, (struct an_ltv_gen *)&sc->areq); 2541 an_cmd(sc, AN_CMD_ENABLE, 0); 2542 return 0; 2543 } 2544 return -EOPNOTSUPP; 2545} 2546 2547/* 2548 * General Flash utilities derived from Cisco driver additions to Ben Reed's 2549 * Linux driver 2550 */ 2551 2552#define FLASH_DELAY(x) tsleep(ifp, PZERO, "flash", ((x) / hz) + 1); 2553 2554static int 2555unstickbusy(ifp) 2556 struct ifnet *ifp; 2557{ 2558 struct an_softc *sc = ifp->if_softc; 2559 2560 if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) { 2561 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY); 2562 return 1; 2563 } 2564 return 0; 2565} 2566 2567/* 2568 * Wait for busy completion from card wait for delay uSec's Return true for 2569 * success meaning command reg is clear 2570 */ 2571 2572static int 2573WaitBusy(ifp, uSec) 2574 struct ifnet *ifp; 2575 int uSec; 2576{ 2577 int statword = 0xffff; 2578 int delay = 0; 2579 struct an_softc *sc = ifp->if_softc; 2580 2581 while ((statword & AN_CMD_BUSY) && delay <= (1000 * 100)) { 2582 FLASH_DELAY(10); 2583 delay += 10; 2584 statword = CSR_READ_2(sc, AN_COMMAND); 2585 2586 if ((AN_CMD_BUSY & statword) && (delay % 200)) { 2587 unstickbusy(ifp); 2588 } 2589 } 2590 2591 return 0 == (AN_CMD_BUSY & statword); 2592} 2593 2594/* 2595 * STEP 1) Disable MAC and do soft reset on card. 2596 */ 2597 2598static int 2599cmdreset(ifp) 2600 struct ifnet *ifp; 2601{ 2602 int status; 2603 struct an_softc *sc = ifp->if_softc; 2604 2605 an_stop(sc); 2606 2607 an_cmd(sc, AN_CMD_DISABLE, 0); 2608 2609 if (!(status = WaitBusy(ifp, 600))) { 2610 printf("an%d: Waitbusy hang b4 RESET =%d\n", 2611 sc->an_unit, status); 2612 return -EBUSY; 2613 } 2614 CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_FW_RESTART); 2615 2616 FLASH_DELAY(1000); /* WAS 600 12/7/00 */ 2617 2618 2619 if (!(status = WaitBusy(ifp, 100))) { 2620 printf("an%d: Waitbusy hang AFTER RESET =%d\n", 2621 sc->an_unit, status); 2622 return -EBUSY; 2623 } 2624 return 0; 2625} 2626 2627/* 2628 * STEP 2) Put the card in legendary flash mode 2629 */ 2630#define FLASH_COMMAND 0x7e7e 2631 2632static int 2633setflashmode(ifp) 2634 struct ifnet *ifp; 2635{ 2636 int status; 2637 struct an_softc *sc = ifp->if_softc; 2638 2639 CSR_WRITE_2(sc, AN_SW0, FLASH_COMMAND); 2640 CSR_WRITE_2(sc, AN_SW1, FLASH_COMMAND); 2641 CSR_WRITE_2(sc, AN_SW0, FLASH_COMMAND); 2642 CSR_WRITE_2(sc, AN_COMMAND, FLASH_COMMAND); 2643 2644 /* 2645 * mdelay(500); // 500ms delay 2646 */ 2647 2648 FLASH_DELAY(500); 2649 2650 if (!(status = WaitBusy(ifp, 600))) { 2651 printf("Waitbusy hang after setflash mode\n"); 2652 return -EIO; 2653 } 2654 return 0; 2655} 2656 2657/* 2658 * Get a character from the card matching matchbyte Step 3) 2659 */ 2660 2661static int 2662flashgchar(ifp, matchbyte, dwelltime) 2663 struct ifnet *ifp; 2664 int matchbyte; 2665 int dwelltime; 2666{ 2667 int rchar; 2668 unsigned char rbyte = 0; 2669 int success = -1; 2670 struct an_softc *sc = ifp->if_softc; 2671 2672 2673 do { 2674 rchar = CSR_READ_2(sc, AN_SW1); 2675 2676 if (dwelltime && !(0x8000 & rchar)) { 2677 dwelltime -= 10; 2678 FLASH_DELAY(10); 2679 continue; 2680 } 2681 rbyte = 0xff & rchar; 2682 2683 if ((rbyte == matchbyte) && (0x8000 & rchar)) { 2684 CSR_WRITE_2(sc, AN_SW1, 0); 2685 success = 1; 2686 break; 2687 } 2688 if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar) 2689 break; 2690 CSR_WRITE_2(sc, AN_SW1, 0); 2691 2692 } while (dwelltime > 0); 2693 return success; 2694} 2695 2696/* 2697 * Put character to SWS0 wait for dwelltime x 50us for echo . 2698 */ 2699 2700static int 2701flashpchar(ifp, byte, dwelltime) 2702 struct ifnet *ifp; 2703 int byte; 2704 int dwelltime; 2705{ 2706 int echo; 2707 int pollbusy, waittime; 2708 struct an_softc *sc = ifp->if_softc; 2709 2710 byte |= 0x8000; 2711 2712 if (dwelltime == 0) 2713 dwelltime = 200; 2714 2715 waittime = dwelltime; 2716 2717 /* 2718 * Wait for busy bit d15 to go false indicating buffer empty 2719 */ 2720 do { 2721 pollbusy = CSR_READ_2(sc, AN_SW0); 2722 2723 if (pollbusy & 0x8000) { 2724 FLASH_DELAY(50); 2725 waittime -= 50; 2726 continue; 2727 } else 2728 break; 2729 } 2730 while (waittime >= 0); 2731 2732 /* timeout for busy clear wait */ 2733 2734 if (waittime <= 0) { 2735 printf("an%d: flash putchar busywait timeout! \n", 2736 sc->an_unit); 2737 return -1; 2738 } 2739 /* 2740 * Port is clear now write byte and wait for it to echo back 2741 */ 2742 do { 2743 CSR_WRITE_2(sc, AN_SW0, byte); 2744 FLASH_DELAY(50); 2745 dwelltime -= 50; 2746 echo = CSR_READ_2(sc, AN_SW1); 2747 } while (dwelltime >= 0 && echo != byte); 2748 2749 2750 CSR_WRITE_2(sc, AN_SW1, 0); 2751 2752 return echo == byte; 2753} 2754 2755/* 2756 * Transfer 32k of firmware data from user buffer to our buffer and send to 2757 * the card 2758 */ 2759 2760static char flashbuffer[1024 * 38]; /* RAW Buffer for flash will be 2761 * dynamic next */ 2762 2763static int 2764flashputbuf(ifp) 2765 struct ifnet *ifp; 2766{ 2767 unsigned short *bufp; 2768 int nwords; 2769 struct an_softc *sc = ifp->if_softc; 2770 2771 /* Write stuff */ 2772 2773 bufp = (unsigned short *)flashbuffer; 2774 2775 CSR_WRITE_2(sc, AN_AUX_PAGE, 0x100); 2776 CSR_WRITE_2(sc, AN_AUX_OFFSET, 0); 2777 2778 for (nwords = 0; nwords != 16384; nwords++) { 2779 CSR_WRITE_2(sc, AN_AUX_DATA, bufp[nwords] & 0xffff); 2780 } 2781 2782 CSR_WRITE_2(sc, AN_SW0, 0x8000); 2783 2784 return 0; 2785} 2786 2787/* 2788 * After flashing restart the card. 2789 */ 2790 2791static int 2792flashrestart(ifp) 2793 struct ifnet *ifp; 2794{ 2795 int status = 0; 2796 struct an_softc *sc = ifp->if_softc; 2797 2798 FLASH_DELAY(1024); /* Added 12/7/00 */ 2799 2800 an_init(sc); 2801 2802 FLASH_DELAY(1024); /* Added 12/7/00 */ 2803 return status; 2804} 2805 2806/* 2807 * Entry point for flash ioclt. 2808 */ 2809 2810static int 2811flashcard(ifp, l_ioctl) 2812 struct ifnet *ifp; 2813 struct aironet_ioctl *l_ioctl; 2814{ 2815 int z = 0, status; 2816 struct an_softc *sc; 2817 2818 sc = ifp->if_softc; 2819 status = l_ioctl->command; 2820 2821 switch (l_ioctl->command) { 2822 case AIROFLSHRST: 2823 return cmdreset(ifp); 2824 break; 2825 case AIROFLSHSTFL: 2826 return setflashmode(ifp); 2827 break; 2828 case AIROFLSHGCHR: /* Get char from aux */ 2829 copyin(l_ioctl->data, &sc->areq, l_ioctl->len); 2830 z = *(int *)&sc->areq; 2831 if ((status = flashgchar(ifp, z, 8000)) == 1) 2832 return 0; 2833 else 2834 return -1; 2835 break; 2836 case AIROFLSHPCHR: /* Send char to card. */ 2837 copyin(l_ioctl->data, &sc->areq, l_ioctl->len); 2838 z = *(int *)&sc->areq; 2839 if ((status = flashpchar(ifp, z, 8000)) == -1) 2840 return -EIO; 2841 else 2842 return 0; 2843 break; 2844 case AIROFLPUTBUF: /* Send 32k to card */ 2845 if (l_ioctl->len > sizeof(flashbuffer)) { 2846 printf("an%d: Buffer to big, %x %zx\n", sc->an_unit, 2847 l_ioctl->len, sizeof(flashbuffer)); 2848 return -EINVAL; 2849 } 2850 copyin(l_ioctl->data, &flashbuffer, l_ioctl->len); 2851 2852 if ((status = flashputbuf(ifp)) != 0) 2853 return -EIO; 2854 else 2855 return 0; 2856 break; 2857 case AIRORESTART: 2858 if ((status = flashrestart(ifp)) != 0) { 2859 printf("an%d: FLASHRESTART returned %d\n", 2860 sc->an_unit, status); 2861 return -EIO; 2862 } else 2863 return 0; 2864 2865 break; 2866 default: 2867 return -EINVAL; 2868 } 2869 2870 return -EINVAL; 2871} 2872 2873