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