if_an.c revision 90990
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 90990 2002-02-20 18:23:59Z brooks $ 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 90990 2002-02-20 18:23:59Z brooks $"; 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 /* We can't send in monitor mode so toss any attempts. */ 1972 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { 1973 for (;;) { 1974 IF_DEQUEUE(&ifp->if_snd, m0); 1975 if (m0 == NULL) 1976 break; 1977 m_freem(m0); 1978 } 1979 return; 1980 } 1981 1982 idx = sc->an_rdata.an_tx_prod; 1983 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 1984 1985 while (sc->an_rdata.an_tx_ring[idx] == 0) { 1986 IF_DEQUEUE(&ifp->if_snd, m0); 1987 if (m0 == NULL) 1988 break; 1989 1990 id = sc->an_rdata.an_tx_fids[idx]; 1991 eh = mtod(m0, struct ether_header *); 1992 1993 bcopy((char *)&eh->ether_dhost, 1994 (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); 1995 bcopy((char *)&eh->ether_shost, 1996 (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); 1997 1998 tx_frame_802_3.an_tx_802_3_payload_len = 1999 m0->m_pkthdr.len - 12; /* minus src/dest mac & type */ 2000 2001 m_copydata(m0, sizeof(struct ether_header) - 2 , 2002 tx_frame_802_3.an_tx_802_3_payload_len, 2003 (caddr_t)&sc->an_txbuf); 2004 2005 txcontrol = AN_TXCTL_8023; 2006 /* write the txcontrol only */ 2007 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 2008 sizeof(txcontrol)); 2009 2010 /* 802_3 header */ 2011 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 2012 sizeof(struct an_txframe_802_3)); 2013 2014 /* in mbuf header type is just before payload */ 2015 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 2016 tx_frame_802_3.an_tx_802_3_payload_len); 2017 2018 /* 2019 * If there's a BPF listner, bounce a copy of 2020 * this frame to him. 2021 */ 2022 if (ifp->if_bpf) 2023 bpf_mtap(ifp, m0); 2024 2025 m_freem(m0); 2026 m0 = NULL; 2027 2028 sc->an_rdata.an_tx_ring[idx] = id; 2029 if (an_cmd(sc, AN_CMD_TX, id)) 2030 printf("an%d: xmit failed\n", sc->an_unit); 2031 2032 AN_INC(idx, AN_TX_RING_CNT); 2033 } 2034 2035 if (m0 != NULL) 2036 ifp->if_flags |= IFF_OACTIVE; 2037 2038 sc->an_rdata.an_tx_prod = idx; 2039 2040 /* 2041 * Set a timeout in case the chip goes out to lunch. 2042 */ 2043 ifp->if_timer = 5; 2044 2045 return; 2046} 2047 2048void 2049an_stop(sc) 2050 struct an_softc *sc; 2051{ 2052 struct ifnet *ifp; 2053 int i; 2054 2055 AN_LOCK(sc); 2056 2057 if (sc->an_gone) { 2058 AN_UNLOCK(sc); 2059 return; 2060 } 2061 2062 ifp = &sc->arpcom.ac_if; 2063 2064 an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0); 2065 CSR_WRITE_2(sc, AN_INT_EN, 0); 2066 an_cmd(sc, AN_CMD_DISABLE, 0); 2067 2068 for (i = 0; i < AN_TX_RING_CNT; i++) 2069 an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]); 2070 2071 untimeout(an_stats_update, sc, sc->an_stat_ch); 2072 2073 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 2074 2075 AN_UNLOCK(sc); 2076 2077 return; 2078} 2079 2080static void 2081an_watchdog(ifp) 2082 struct ifnet *ifp; 2083{ 2084 struct an_softc *sc; 2085 2086 sc = ifp->if_softc; 2087 AN_LOCK(sc); 2088 2089 if (sc->an_gone) { 2090 AN_UNLOCK(sc); 2091 return; 2092 } 2093 2094 printf("an%d: device timeout\n", sc->an_unit); 2095 2096 an_reset(sc); 2097 an_init(sc); 2098 2099 ifp->if_oerrors++; 2100 AN_UNLOCK(sc); 2101 2102 return; 2103} 2104 2105void 2106an_shutdown(dev) 2107 device_t dev; 2108{ 2109 struct an_softc *sc; 2110 2111 sc = device_get_softc(dev); 2112 an_stop(sc); 2113 2114 return; 2115} 2116 2117#ifdef ANCACHE 2118/* Aironet signal strength cache code. 2119 * store signal/noise/quality on per MAC src basis in 2120 * a small fixed cache. The cache wraps if > MAX slots 2121 * used. The cache may be zeroed out to start over. 2122 * Two simple filters exist to reduce computation: 2123 * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used 2124 * to ignore some packets. It defaults to ip only. 2125 * it could be used to focus on broadcast, non-IP 802.11 beacons. 2126 * 2. multicast/broadcast only. This may be used to 2127 * ignore unicast packets and only cache signal strength 2128 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2129 * beacons and not unicast traffic. 2130 * 2131 * The cache stores (MAC src(index), IP src (major clue), signal, 2132 * quality, noise) 2133 * 2134 * No apologies for storing IP src here. It's easy and saves much 2135 * trouble elsewhere. The cache is assumed to be INET dependent, 2136 * although it need not be. 2137 * 2138 * Note: the Aironet only has a single byte of signal strength value 2139 * in the rx frame header, and it's not scaled to anything sensible. 2140 * This is kind of lame, but it's all we've got. 2141 */ 2142 2143#ifdef documentation 2144 2145int an_sigitems; /* number of cached entries */ 2146struct an_sigcache an_sigcache[MAXANCACHE]; /* array of cache entries */ 2147int an_nextitem; /* index/# of entries */ 2148 2149 2150#endif 2151 2152/* control variables for cache filtering. Basic idea is 2153 * to reduce cost (e.g., to only Mobile-IP agent beacons 2154 * which are broadcast or multicast). Still you might 2155 * want to measure signal strength anth unicast ping packets 2156 * on a pt. to pt. ant. setup. 2157 */ 2158/* set true if you want to limit cache items to broadcast/mcast 2159 * only packets (not unicast). Useful for mobile-ip beacons which 2160 * are broadcast/multicast at network layer. Default is all packets 2161 * so ping/unicast anll work say anth pt. to pt. antennae setup. 2162 */ 2163static int an_cache_mcastonly = 0; 2164SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, 2165 &an_cache_mcastonly, 0, ""); 2166 2167/* set true if you want to limit cache items to IP packets only 2168*/ 2169static int an_cache_iponly = 1; 2170SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, 2171 &an_cache_iponly, 0, ""); 2172 2173/* 2174 * an_cache_store, per rx packet store signal 2175 * strength in MAC (src) indexed cache. 2176 */ 2177static void 2178an_cache_store (sc, eh, m, rx_quality) 2179 struct an_softc *sc; 2180 struct ether_header *eh; 2181 struct mbuf *m; 2182 unsigned short rx_quality; 2183{ 2184 struct ip *ip = 0; 2185 int i; 2186 static int cache_slot = 0; /* use this cache entry */ 2187 static int wrapindex = 0; /* next "free" cache entry */ 2188 int type_ipv4 = 0; 2189 2190 /* filters: 2191 * 1. ip only 2192 * 2. configurable filter to throw out unicast packets, 2193 * keep multicast only. 2194 */ 2195 2196 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) { 2197 type_ipv4 = 1; 2198 } 2199 2200 /* filter for ip packets only 2201 */ 2202 if ( an_cache_iponly && !type_ipv4) { 2203 return; 2204 } 2205 2206 /* filter for broadcast/multicast only 2207 */ 2208 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2209 return; 2210 } 2211 2212#ifdef SIGDEBUG 2213 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 2214 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2215#endif 2216 2217 /* find the ip header. we want to store the ip_src 2218 * address. 2219 */ 2220 if (type_ipv4) { 2221 ip = mtod(m, struct ip *); 2222 } 2223 2224 /* do a linear search for a matching MAC address 2225 * in the cache table 2226 * . MAC address is 6 bytes, 2227 * . var w_nextitem holds total number of entries already cached 2228 */ 2229 for (i = 0; i < sc->an_nextitem; i++) { 2230 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 2231 /* Match!, 2232 * so we already have this entry, 2233 * update the data 2234 */ 2235 break; 2236 } 2237 } 2238 2239 /* did we find a matching mac address? 2240 * if yes, then overwrite a previously existing cache entry 2241 */ 2242 if (i < sc->an_nextitem ) { 2243 cache_slot = i; 2244 } 2245 /* else, have a new address entry,so 2246 * add this new entry, 2247 * if table full, then we need to replace LRU entry 2248 */ 2249 else { 2250 2251 /* check for space in cache table 2252 * note: an_nextitem also holds number of entries 2253 * added in the cache table 2254 */ 2255 if ( sc->an_nextitem < MAXANCACHE ) { 2256 cache_slot = sc->an_nextitem; 2257 sc->an_nextitem++; 2258 sc->an_sigitems = sc->an_nextitem; 2259 } 2260 /* no space found, so simply wrap anth wrap index 2261 * and "zap" the next entry 2262 */ 2263 else { 2264 if (wrapindex == MAXANCACHE) { 2265 wrapindex = 0; 2266 } 2267 cache_slot = wrapindex++; 2268 } 2269 } 2270 2271 /* invariant: cache_slot now points at some slot 2272 * in cache. 2273 */ 2274 if (cache_slot < 0 || cache_slot >= MAXANCACHE) { 2275 log(LOG_ERR, "an_cache_store, bad index: %d of " 2276 "[0..%d], gross cache error\n", 2277 cache_slot, MAXANCACHE); 2278 return; 2279 } 2280 2281 /* store items in cache 2282 * .ip source address 2283 * .mac src 2284 * .signal, etc. 2285 */ 2286 if (type_ipv4) { 2287 sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 2288 } 2289 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 2290 2291 sc->an_sigcache[cache_slot].signal = rx_quality; 2292 2293 return; 2294} 2295#endif 2296 2297static int 2298an_media_change(ifp) 2299 struct ifnet *ifp; 2300{ 2301 struct an_softc *sc = ifp->if_softc; 2302 int otype = sc->an_config.an_opmode; 2303 int orate = sc->an_tx_rate; 2304 2305 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2306 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; 2307 else 2308 sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION; 2309 2310 switch (IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)) { 2311 case IFM_IEEE80211_DS1: 2312 sc->an_tx_rate = AN_RATE_1MBPS; 2313 break; 2314 case IFM_IEEE80211_DS2: 2315 sc->an_tx_rate = AN_RATE_2MBPS; 2316 break; 2317 case IFM_IEEE80211_DS5: 2318 sc->an_tx_rate = AN_RATE_5_5MBPS; 2319 break; 2320 case IFM_IEEE80211_DS11: 2321 sc->an_tx_rate = AN_RATE_11MBPS; 2322 break; 2323 case IFM_AUTO: 2324 sc->an_tx_rate = 0; 2325 break; 2326 } 2327 2328 if (otype != sc->an_config.an_opmode || 2329 orate != sc->an_tx_rate) 2330 an_init(sc); 2331 2332 return(0); 2333} 2334 2335static void 2336an_media_status(ifp, imr) 2337 struct ifnet *ifp; 2338 struct ifmediareq *imr; 2339{ 2340 struct an_ltv_status status; 2341 struct an_softc *sc = ifp->if_softc; 2342 2343 status.an_len = sizeof(status); 2344 status.an_type = AN_RID_STATUS; 2345 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 2346 /* If the status read fails, just lie. */ 2347 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2348 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 2349 } 2350 2351 if (sc->an_tx_rate == 0) { 2352 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2353 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2354 imr->ifm_active |= IFM_IEEE80211_ADHOC; 2355 switch (status.an_current_tx_rate) { 2356 case AN_RATE_1MBPS: 2357 imr->ifm_active |= IFM_IEEE80211_DS1; 2358 break; 2359 case AN_RATE_2MBPS: 2360 imr->ifm_active |= IFM_IEEE80211_DS2; 2361 break; 2362 case AN_RATE_5_5MBPS: 2363 imr->ifm_active |= IFM_IEEE80211_DS5; 2364 break; 2365 case AN_RATE_11MBPS: 2366 imr->ifm_active |= IFM_IEEE80211_DS11; 2367 break; 2368 } 2369 } else { 2370 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2371 } 2372 2373 imr->ifm_status = IFM_AVALID; 2374 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2375 imr->ifm_status |= IFM_ACTIVE; 2376 else 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