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