1 /* $NetBSD: an.c,v 1.8 2000/12/14 06:27:24 thorpej Exp $ */ 2 /* 3 * Copyright (c) 1997, 1998, 1999 4 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Bill Paul. 17 * 4. Neither the name of the author nor the names of any co-contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $ 34 */ 35 36 /* 37 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 38 * 39 * Written by Bill Paul <wpaul@ctr.columbia.edu> 40 * Electrical Engineering Department 41 * Columbia University, New York City 42 */ 43 44 /* 45 * The Aironet 4500/4800 series cards some in PCMCIA, ISA and PCI form. 46 * This driver supports all three device types (PCI devices are supported 47 * through an extra PCI shim: /sys/pci/if_an_p.c). ISA devices can be 48 * supported either using hard-coded IO port/IRQ settings or via Plug 49 * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates. 50 * The 4800 devices support 1, 2, 5.5 and 11Mbps rates. 51 * 52 * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially 53 * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA 54 * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are 55 * a couple of important differences though: 56 * 57 * - Lucent doesn't currently offer a PCI card, however Aironet does 58 * - Lucent ISA card looks to the host like a PCMCIA controller with 59 * a PCMCIA WaveLAN card inserted. This means that even desktop 60 * machines need to be configured with PCMCIA support in order to 61 * use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand 62 * actually look like normal ISA and PCI devices to the host, so 63 * no PCMCIA controller support is needed 64 * 65 * The latter point results in a small gotcha. The Aironet PCMCIA 66 * cards can be configured for one of two operating modes depending 67 * on how the Vpp1 and Vpp2 programming voltages are set when the 68 * card is activated. In order to put the card in proper PCMCIA 69 * operation (where the CIS table is visible and the interface is 70 * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be 71 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages, 72 * which leaves the card in ISA/PCI mode, which prevents it from 73 * being activated as an PCMCIA device. Consequently, /sys/pccard/pccard.c 74 * has to be patched slightly in order to enable the Vpp voltages in 75 * order to make the Aironet PCMCIA cards work. 76 * 77 * Note that some PCMCIA controller software packages for Windows NT 78 * fail to set the voltages as well. 79 * 80 * The Aironet devices can operate in both station mode and access point 81 * mode. Typically, when programmed for station mode, the card can be set 82 * to automatically perform encapsulation/decapsulation of Ethernet II 83 * and 802.3 frames within 802.11 frames so that the host doesn't have 84 * to do it itself. This driver doesn't program the card that way: the 85 * driver handles all of the encapsulation/decapsulation itself. 86 */ 87 88 /* 89 * Ported to NetBSD from FreeBSD by Atsushi Onoe at the San Diego 90 * IETF meeting. 91 */ 92 93 #include "opt_inet.h" 94 #include "bpfilter.h" 95 96 #ifdef INET 97 #define ANCACHE /* enable signal strength cache */ 98 #endif 99 100 #include <sys/param.h> 101 #include <sys/callout.h> 102 #include <sys/systm.h> 103 #include <sys/sockio.h> 104 #include <sys/mbuf.h> 105 #include <sys/kernel.h> 106 #include <sys/ucred.h> 107 #include <sys/socket.h> 108 #include <sys/device.h> 109 #ifdef ANCACHE 110 #include <sys/syslog.h> 111 #include <sys/sysctl.h> 112 #endif 113 114 #include <machine/bus.h> 115 116 #include <net/if.h> 117 #include <net/if_arp.h> 118 #include <net/if_dl.h> 119 #include <net/if_ether.h> 120 #include <net/if_ieee80211.h> 121 #include <net/if_types.h> 122 #include <net/if_media.h> 123 124 #ifdef INET 125 #include <netinet/in.h> 126 #include <netinet/in_systm.h> 127 #include <netinet/in_var.h> 128 #include <netinet/ip.h> 129 #endif 130 131 #if NBPFILTER > 0 132 #include <net/bpf.h> 133 #endif 134 135 #include <dev/ic/anreg.h> 136 #include <dev/ic/anvar.h> 137 138 #if !defined(lint) 139 static const char rcsid[] = 140 "$FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $"; 141 #endif 142 143 /* These are global because we need them in sys/pci/if_an_p.c. */ 144 static void an_reset __P((struct an_softc *)); 145 static int an_ioctl __P((struct ifnet *, u_long, caddr_t)); 146 static int an_init __P((struct ifnet *)); 147 static void an_stop __P((struct ifnet *, int)); 148 static int an_init_tx_ring __P((struct an_softc *)); 149 static void an_start __P((struct ifnet *)); 150 static void an_watchdog __P((struct ifnet *)); 151 static void an_rxeof __P((struct an_softc *)); 152 static void an_txeof __P((struct an_softc *, int)); 153 154 static void an_promisc __P((struct an_softc *, int)); 155 static int an_cmd __P((struct an_softc *, int, int)); 156 static int an_read_record __P((struct an_softc *, struct an_ltv_gen *)); 157 static int an_write_record __P((struct an_softc *, struct an_ltv_gen *)); 158 static int an_read_data __P((struct an_softc *, int, 159 int, caddr_t, int)); 160 static int an_write_data __P((struct an_softc *, int, 161 int, caddr_t, int)); 162 static int an_seek __P((struct an_softc *, int, int, int)); 163 static int an_alloc_nicmem __P((struct an_softc *, int, int *)); 164 static void an_stats_update __P((void *)); 165 static void an_setdef __P((struct an_softc *, struct an_req *)); 166 #ifdef ANCACHE 167 static void an_cache_store __P((struct an_softc *, struct ether_header *, 168 struct mbuf *, unsigned short)); 169 #endif 170 #ifdef IFM_IEEE80211 171 static int an_media_change __P((struct ifnet *ifp)); 172 static void an_media_status __P((struct ifnet *ifp, struct ifmediareq *imr)); 173 #endif 174 175 /* 176 * We probe for an Aironet 4500/4800 card by attempting to 177 * read the default SSID list. On reset, the first entry in 178 * the SSID list will contain the name "tsunami." If we don't 179 * find this, then there's no card present. 180 */ 181 int an_probe(sc) 182 struct an_softc *sc; 183 { 184 struct an_ltv_ssidlist ssid; 185 186 bzero((char *)&ssid, sizeof(ssid)); 187 188 ssid.an_len = sizeof(ssid); 189 ssid.an_type = AN_RID_SSIDLIST; 190 191 /* Make sure interrupts are disabled. */ 192 CSR_WRITE_2(sc, AN_INT_EN, 0); 193 CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF); 194 195 an_reset(sc); 196 197 if (an_cmd(sc, AN_CMD_READCFG, 0)) 198 return ENXIO; 199 200 if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) 201 return ENXIO; 202 203 /* See if the ssid matches what we expect ... but doesn't have to */ 204 if (strcmp(ssid.an_ssid1, AN_DEF_SSID)) 205 return ENXIO; 206 207 return 0; 208 } 209 210 int an_attach(sc) 211 struct an_softc *sc; 212 { 213 struct ifnet *ifp = &sc->arpcom.ec_if; 214 #ifdef IFM_IEEE80211 215 int i, mtype; 216 struct ifmediareq imr; 217 #endif 218 219 sc->an_associated = 0; 220 221 /* Reset the NIC. */ 222 an_reset(sc); 223 224 /* Load factory config */ 225 if (an_cmd(sc, AN_CMD_READCFG, 0)) { 226 printf("%s: failed to load config data\n", sc->an_dev.dv_xname); 227 return(EIO); 228 } 229 230 /* Read the current configuration */ 231 sc->an_config.an_type = AN_RID_GENCONFIG; 232 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 233 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 234 printf("%s: read record failed\n", sc->an_dev.dv_xname); 235 return(EIO); 236 } 237 238 /* Read the card capabilities */ 239 sc->an_caps.an_type = AN_RID_CAPABILITIES; 240 sc->an_caps.an_len = sizeof(struct an_ltv_caps); 241 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) { 242 printf("%s: read record failed\n", sc->an_dev.dv_xname); 243 return(EIO); 244 } 245 246 /* Read ssid list */ 247 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 248 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist); 249 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 250 printf("%s: read record failed\n", sc->an_dev.dv_xname); 251 return(EIO); 252 } 253 254 /* Read AP list */ 255 sc->an_aplist.an_type = AN_RID_APLIST; 256 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 257 if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 258 printf("%s: read record failed\n", sc->an_dev.dv_xname); 259 return(EIO); 260 } 261 262 printf("%s: 802.11 address: %s\n", sc->an_dev.dv_xname, 263 ether_sprintf(sc->an_caps.an_oemaddr)); 264 265 ifp->if_softc = sc; 266 ifp->if_flags = 267 IFF_BROADCAST | IFF_NOTRAILERS | IFF_SIMPLEX | IFF_MULTICAST; 268 ifp->if_ioctl = an_ioctl; 269 ifp->if_start = an_start; 270 ifp->if_init = an_init; 271 ifp->if_stop = an_stop; 272 ifp->if_watchdog = an_watchdog; 273 IFQ_SET_READY(&ifp->if_snd); 274 275 memcpy(ifp->if_xname, sc->an_dev.dv_xname, IFNAMSIZ); 276 277 bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename)); 278 bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename, 279 sizeof(AN_DEFAULT_NODENAME) - 1); 280 281 bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1)); 282 bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1, 283 sizeof(AN_DEFAULT_NETNAME) - 1); 284 sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME); 285 286 sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION; 287 288 sc->an_tx_rate = 0; 289 bzero((char *)&sc->an_stats, sizeof(sc->an_stats)); 290 291 /* 292 * Call MI attach routine. 293 */ 294 if_attach(ifp); 295 ether_ifattach(ifp, sc->an_caps.an_oemaddr); 296 297 #ifdef IFM_IEEE80211 298 ifmedia_init(&sc->sc_media, 0, an_media_change, an_media_status); 299 ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 300 0, 0), 0, NULL); 301 ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 302 IFM_IEEE80211_ADHOC, 0), 0, NULL); 303 for (i = 0; i < sizeof(sc->an_caps.an_rates); i++) { 304 switch (sc->an_caps.an_rates[i]) { 305 case AN_RATE_1MBPS: 306 mtype = IFM_IEEE80211_DS1; 307 break; 308 case AN_RATE_2MBPS: 309 mtype = IFM_IEEE80211_DS2; 310 break; 311 case AN_RATE_5_5MBPS: 312 mtype = IFM_IEEE80211_DS5; 313 break; 314 case AN_RATE_11MBPS: 315 mtype = IFM_IEEE80211_DS11; 316 break; 317 default: 318 continue; 319 } 320 ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, mtype, 321 0, 0), 0, NULL); 322 ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, mtype, 323 IFM_IEEE80211_ADHOC, 0), 0, NULL); 324 } 325 an_media_status(ifp, &imr); 326 ifmedia_set(&sc->sc_media, imr.ifm_active); 327 #endif 328 callout_init(&sc->an_stat_ch); 329 330 return(0); 331 } 332 333 int 334 an_detach(sc) 335 struct an_softc *sc; 336 { 337 struct ifnet *ifp = &sc->arpcom.ec_if; 338 int s; 339 340 s = splnet(); 341 an_stop(ifp, 1); 342 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); 343 ether_ifdetach(ifp); 344 if_detach(ifp); 345 splx(s); 346 return 0; 347 } 348 349 int 350 an_activate(self, act) 351 struct device *self; 352 enum devact act; 353 { 354 struct an_softc *sc = (struct an_softc *)self; 355 int s, error = 0; 356 357 s = splnet(); 358 switch (act) { 359 case DVACT_ACTIVATE: 360 error = EOPNOTSUPP; 361 break; 362 363 case DVACT_DEACTIVATE: 364 if_deactivate(&sc->arpcom.ec_if); 365 break; 366 } 367 splx(s); 368 369 return error; 370 } 371 372 static void an_rxeof(sc) 373 struct an_softc *sc; 374 { 375 struct ifnet *ifp; 376 struct ether_header *eh; 377 #ifdef ANCACHE 378 struct an_rxframe rx_frame; 379 #endif 380 struct an_rxframe_802_3 rx_frame_802_3; 381 struct mbuf *m; 382 int id, error = 0; 383 384 ifp = &sc->arpcom.ec_if; 385 386 id = CSR_READ_2(sc, AN_RX_FID); 387 388 MGETHDR(m, M_DONTWAIT, MT_DATA); 389 if (m == NULL) { 390 ifp->if_ierrors++; 391 return; 392 } 393 MCLGET(m, M_DONTWAIT); 394 if (!(m->m_flags & M_EXT)) { 395 m_freem(m); 396 ifp->if_ierrors++; 397 return; 398 } 399 400 m->m_pkthdr.rcvif = ifp; 401 402 eh = mtod(m, struct ether_header *); 403 404 #ifdef ANCACHE 405 /* Read NIC frame header */ 406 if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) { 407 ifp->if_ierrors++; 408 return; 409 } 410 #endif 411 /* Read in the 802_3 frame header */ 412 if (an_read_data(sc, id, 0x34, (caddr_t)&rx_frame_802_3, 413 sizeof(rx_frame_802_3))) { 414 ifp->if_ierrors++; 415 return; 416 } 417 418 if (rx_frame_802_3.an_rx_802_3_status != 0) { 419 ifp->if_ierrors++; 420 return; 421 } 422 423 /* Check for insane frame length */ 424 if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) { 425 ifp->if_ierrors++; 426 return; 427 } 428 429 m->m_pkthdr.len = m->m_len = 430 rx_frame_802_3.an_rx_802_3_payload_len + 12; 431 432 433 bcopy((char *)&rx_frame_802_3.an_rx_dst_addr, 434 (char *)&eh->ether_dhost, ETHER_ADDR_LEN); 435 bcopy((char *)&rx_frame_802_3.an_rx_src_addr, 436 (char *)&eh->ether_shost, ETHER_ADDR_LEN); 437 438 /* in mbuf header type is just before payload */ 439 error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type), 440 rx_frame_802_3.an_rx_802_3_payload_len); 441 442 if (error) { 443 m_freem(m); 444 ifp->if_ierrors++; 445 return; 446 } 447 448 ifp->if_ipackets++; 449 450 /* Receive packet. */ 451 #ifdef ANCACHE 452 an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength); 453 #endif 454 #if NBPFILTER > 0 455 if (ifp->if_bpf) 456 bpf_mtap(ifp->if_bpf, m); 457 #endif 458 (*ifp->if_input)(ifp, m); 459 } 460 461 static void an_txeof(sc, status) 462 struct an_softc *sc; 463 int status; 464 { 465 struct ifnet *ifp; 466 int id; 467 468 /* TX DONE enable lan monitor DJA 469 an_enable_sniff(); 470 */ 471 472 ifp = &sc->arpcom.ec_if; 473 474 ifp->if_timer = 0; 475 ifp->if_flags &= ~IFF_OACTIVE; 476 477 id = CSR_READ_2(sc, AN_TX_CMP_FID); 478 479 if (status & AN_EV_TX_EXC) { 480 ifp->if_oerrors++; 481 } else 482 ifp->if_opackets++; 483 484 #if 0 /*XXX*/ 485 if (id != sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons]) 486 printf("%s: id mismatch: expected %x, got %x\n", 487 sc->an_dev.dv_xname, 488 sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons], id); 489 #endif 490 491 sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons] = 0; 492 AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT); 493 494 return; 495 } 496 497 /* 498 * We abuse the stats updater to check the current NIC status. This 499 * is important because we don't want to allow transmissions until 500 * the NIC has synchronized to the current cell (either as the master 501 * in an ad-hoc group, or as a station connected to an access point). 502 */ 503 void an_stats_update(xsc) 504 void *xsc; 505 { 506 struct an_softc *sc; 507 struct ifnet *ifp; 508 509 sc = xsc; 510 ifp = &sc->arpcom.ec_if; 511 512 sc->an_status.an_type = AN_RID_STATUS; 513 sc->an_status.an_len = sizeof(struct an_ltv_status); 514 an_read_record(sc, (struct an_ltv_gen *)&sc->an_status); 515 516 if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC) 517 sc->an_associated = 1; 518 else 519 sc->an_associated = 0; 520 521 /* Don't do this while we're transmitting */ 522 if (ifp->if_flags & IFF_OACTIVE) { 523 callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc); 524 return; 525 } 526 527 sc->an_stats.an_len = sizeof(struct an_ltv_stats); 528 sc->an_stats.an_type = AN_RID_32BITS_CUM; 529 an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len); 530 531 callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc); 532 533 return; 534 } 535 536 int an_intr(xsc) 537 void *xsc; 538 { 539 struct an_softc *sc; 540 struct ifnet *ifp; 541 u_int16_t status; 542 543 sc = (struct an_softc*)xsc; 544 545 if (!sc->sc_enabled) 546 return 0; 547 548 ifp = &sc->arpcom.ec_if; 549 550 if (!(ifp->if_flags & IFF_UP)) { 551 CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF); 552 CSR_WRITE_2(sc, AN_INT_EN, 0); 553 return 0; 554 } 555 556 /* Disable interrupts. */ 557 CSR_WRITE_2(sc, AN_INT_EN, 0); 558 559 status = CSR_READ_2(sc, AN_EVENT_STAT); 560 CSR_WRITE_2(sc, AN_EVENT_ACK, ~AN_INTRS); 561 562 if (status & AN_EV_AWAKE) { 563 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_AWAKE); 564 } 565 566 if (status & AN_EV_LINKSTAT) { 567 if (CSR_READ_2(sc, AN_LINKSTAT) == AN_LINKSTAT_ASSOCIATED) 568 sc->an_associated = 1; 569 else 570 sc->an_associated = 0; 571 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT); 572 } 573 574 if (status & AN_EV_RX) { 575 an_rxeof(sc); 576 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); 577 } 578 579 if (status & AN_EV_TX) { 580 an_txeof(sc, status); 581 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX); 582 } 583 584 if (status & AN_EV_TX_EXC) { 585 an_txeof(sc, status); 586 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX_EXC); 587 } 588 589 if (status & AN_EV_ALLOC) 590 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 591 592 /* Re-enable interrupts. */ 593 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 594 595 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 596 an_start(ifp); 597 598 return 1; 599 } 600 601 static int an_cmd(sc, cmd, val) 602 struct an_softc *sc; 603 int cmd; 604 int val; 605 { 606 int i, s = 0; 607 608 CSR_WRITE_2(sc, AN_PARAM0, val); 609 CSR_WRITE_2(sc, AN_PARAM1, 0); 610 CSR_WRITE_2(sc, AN_PARAM2, 0); 611 CSR_WRITE_2(sc, AN_COMMAND, cmd); 612 613 for (i = 0; i < AN_TIMEOUT; i++) { 614 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD) 615 break; 616 else { 617 if (CSR_READ_2(sc, AN_COMMAND) == cmd) 618 CSR_WRITE_2(sc, AN_COMMAND, cmd); 619 } 620 } 621 622 for (i = 0; i < AN_TIMEOUT; i++) { 623 CSR_READ_2(sc, AN_RESP0); 624 CSR_READ_2(sc, AN_RESP1); 625 CSR_READ_2(sc, AN_RESP2); 626 s = CSR_READ_2(sc, AN_STATUS); 627 if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE)) 628 break; 629 } 630 631 /* Ack the command */ 632 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD); 633 634 if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) 635 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY); 636 637 if (i == AN_TIMEOUT) 638 return(ETIMEDOUT); 639 640 return(0); 641 } 642 643 /* 644 * This reset sequence may look a little strange, but this is the 645 * most reliable method I've found to really kick the NIC in the 646 * head and force it to reboot correctly. 647 */ 648 static void an_reset(sc) 649 struct an_softc *sc; 650 { 651 if (!sc->sc_enabled) 652 return; 653 654 an_cmd(sc, AN_CMD_ENABLE, 0); 655 an_cmd(sc, AN_CMD_FW_RESTART, 0); 656 an_cmd(sc, AN_CMD_NOOP2, 0); 657 658 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) 659 printf("%s: reset failed\n", sc->an_dev.dv_xname); 660 661 an_cmd(sc, AN_CMD_DISABLE, 0); 662 663 return; 664 } 665 666 /* 667 * Read an LTV record from the NIC. 668 */ 669 static int an_read_record(sc, ltv) 670 struct an_softc *sc; 671 struct an_ltv_gen *ltv; 672 { 673 u_int16_t *ptr; 674 int i, len; 675 676 if (ltv->an_len == 0 || ltv->an_type == 0) 677 return(EINVAL); 678 679 /* Tell the NIC to enter record read mode. */ 680 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) { 681 printf("%s: RID access failed\n", sc->an_dev.dv_xname); 682 return(EIO); 683 } 684 685 /* Seek to the record. */ 686 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) { 687 printf("%s: seek to record failed\n", sc->an_dev.dv_xname); 688 return(EIO); 689 } 690 691 /* 692 * Read the length and record type and make sure they 693 * match what we expect (this verifies that we have enough 694 * room to hold all of the returned data). 695 */ 696 len = CSR_READ_2(sc, AN_DATA1); 697 if (len > ltv->an_len) { 698 printf("%s: record length mismatch -- expected %d, " 699 "got %d\n", sc->an_dev.dv_xname, ltv->an_len, len); 700 return(ENOSPC); 701 } 702 703 ltv->an_len = len; 704 705 /* Now read the data. */ 706 ptr = <v->an_val; 707 for (i = 0; i < (ltv->an_len - 2) >> 1; i++) 708 ptr[i] = CSR_READ_2(sc, AN_DATA1); 709 710 return(0); 711 } 712 713 /* 714 * Same as read, except we inject data instead of reading it. 715 */ 716 static int an_write_record(sc, ltv) 717 struct an_softc *sc; 718 struct an_ltv_gen *ltv; 719 { 720 u_int16_t *ptr; 721 int i; 722 723 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) 724 return(EIO); 725 726 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) 727 return(EIO); 728 729 CSR_WRITE_2(sc, AN_DATA1, ltv->an_len-2); 730 731 ptr = <v->an_val; 732 for (i = 0; i < (ltv->an_len - 4) >> 1; i++) 733 CSR_WRITE_2(sc, AN_DATA1, ptr[i]); 734 735 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) 736 return(EIO); 737 738 return(0); 739 } 740 741 static int an_seek(sc, id, off, chan) 742 struct an_softc *sc; 743 int id, off, chan; 744 { 745 int i; 746 int selreg, offreg; 747 748 switch (chan) { 749 case AN_BAP0: 750 selreg = AN_SEL0; 751 offreg = AN_OFF0; 752 break; 753 case AN_BAP1: 754 selreg = AN_SEL1; 755 offreg = AN_OFF1; 756 break; 757 default: 758 printf("%s: invalid data path: %x\n", sc->an_dev.dv_xname, chan); 759 return(EIO); 760 } 761 762 CSR_WRITE_2(sc, selreg, id); 763 CSR_WRITE_2(sc, offreg, off); 764 765 for (i = 0; i < AN_TIMEOUT; i++) { 766 if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR))) 767 break; 768 } 769 770 if (i == AN_TIMEOUT) 771 return(ETIMEDOUT); 772 773 return(0); 774 } 775 776 static int an_read_data(sc, id, off, buf, len) 777 struct an_softc *sc; 778 int id, off; 779 caddr_t buf; 780 int len; 781 { 782 int i; 783 u_int16_t *ptr; 784 u_int8_t *ptr2; 785 786 if (off != -1) { 787 if (an_seek(sc, id, off, AN_BAP1)) 788 return(EIO); 789 } 790 791 ptr = (u_int16_t *)buf; 792 for (i = 0; i < len / 2; i++) 793 ptr[i] = CSR_READ_2(sc, AN_DATA1); 794 i*=2; 795 if (i<len){ 796 ptr2 = (u_int8_t *)buf; 797 ptr2[i] = CSR_READ_1(sc, AN_DATA1); 798 } 799 800 return(0); 801 } 802 803 static int an_write_data(sc, id, off, buf, len) 804 struct an_softc *sc; 805 int id, off; 806 caddr_t buf; 807 int len; 808 { 809 int i; 810 u_int16_t *ptr; 811 u_int8_t *ptr2; 812 813 if (off != -1) { 814 if (an_seek(sc, id, off, AN_BAP0)) 815 return(EIO); 816 } 817 818 ptr = (u_int16_t *)buf; 819 for (i = 0; i < (len / 2); i++) 820 CSR_WRITE_2(sc, AN_DATA0, ptr[i]); 821 i*=2; 822 if (i<len){ 823 ptr2 = (u_int8_t *)buf; 824 CSR_WRITE_1(sc, AN_DATA0, ptr2[i]); 825 } 826 827 return(0); 828 } 829 830 /* 831 * Allocate a region of memory inside the NIC and zero 832 * it out. 833 */ 834 static int an_alloc_nicmem(sc, len, id) 835 struct an_softc *sc; 836 int len; 837 int *id; 838 { 839 int i; 840 841 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 842 printf("%s: failed to allocate %d bytes on NIC\n", 843 sc->an_dev.dv_xname, len); 844 return(ENOMEM); 845 } 846 847 for (i = 0; i < AN_TIMEOUT; i++) { 848 if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC) 849 break; 850 } 851 852 if (i == AN_TIMEOUT) 853 return(ETIMEDOUT); 854 855 CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC); 856 *id = CSR_READ_2(sc, AN_ALLOC_FID); 857 858 if (an_seek(sc, *id, 0, AN_BAP0)) 859 return(EIO); 860 861 for (i = 0; i < len / 2; i++) 862 CSR_WRITE_2(sc, AN_DATA0, 0); 863 864 return(0); 865 } 866 867 static void an_setdef(sc, areq) 868 struct an_softc *sc; 869 struct an_req *areq; 870 { 871 struct ifnet *ifp; 872 struct an_ltv_genconfig *cfg; 873 struct an_ltv_ssidlist *ssid; 874 struct an_ltv_aplist *ap; 875 struct an_ltv_gen *sp; 876 877 ifp = &sc->arpcom.ec_if; 878 879 switch (areq->an_type) { 880 case AN_RID_GENCONFIG: 881 cfg = (struct an_ltv_genconfig *)areq; 882 883 bcopy((char *)&cfg->an_macaddr, 884 (char *)&sc->an_caps.an_oemaddr, ETHER_ADDR_LEN); 885 bcopy((char *)&cfg->an_macaddr, LLADDR(ifp->if_sadl), 886 ETHER_ADDR_LEN); 887 888 bcopy((char *)cfg, (char *)&sc->an_config, 889 sizeof(struct an_ltv_genconfig)); 890 break; 891 case AN_RID_SSIDLIST: 892 ssid = (struct an_ltv_ssidlist *)areq; 893 bcopy((char *)ssid, (char *)&sc->an_ssidlist, 894 sizeof(struct an_ltv_ssidlist)); 895 break; 896 case AN_RID_APLIST: 897 ap = (struct an_ltv_aplist *)areq; 898 bcopy((char *)ap, (char *)&sc->an_aplist, 899 sizeof(struct an_ltv_aplist)); 900 break; 901 case AN_RID_TX_SPEED: 902 sp = (struct an_ltv_gen *)areq; 903 sc->an_tx_rate = sp->an_val; 904 break; 905 case AN_RID_WEP_VOLATILE: 906 memcpy(&sc->an_temp_keys, areq, sizeof(sc->an_temp_keys)); 907 908 /* Disable the MAC. */ 909 an_cmd(sc, AN_CMD_DISABLE, 0); 910 911 /* Just write the Key, we don't want to save it */ 912 an_write_record(sc, (struct an_ltv_gen *)areq); 913 914 /* Turn the MAC back on. */ 915 an_cmd(sc, AN_CMD_ENABLE, 0); 916 917 break; 918 case AN_RID_WEP_PERSISTENT: 919 920 /* Disable the MAC. */ 921 an_cmd(sc, AN_CMD_DISABLE, 0); 922 923 /* Just write the Key, the card will save it in this mode */ 924 an_write_record(sc, (struct an_ltv_gen *)areq); 925 926 /* Turn the MAC back on. */ 927 an_cmd(sc, AN_CMD_ENABLE, 0); 928 929 break; 930 default: 931 printf("%s: unknown RID: %x\n", sc->an_dev.dv_xname, areq->an_type); 932 return; 933 break; 934 } 935 936 937 /* Reinitialize the card. */ 938 if (ifp->if_flags & IFF_UP) 939 an_init(ifp); 940 941 return; 942 } 943 944 /* 945 * We can't change the NIC configuration while the MAC is enabled, 946 * so in order to turn on RX monitor mode, we have to turn the MAC 947 * off first. 948 */ 949 static void an_promisc(sc, promisc) 950 struct an_softc *sc; 951 int promisc; 952 { 953 /* Disable the MAC. */ 954 an_cmd(sc, AN_CMD_DISABLE, 0); 955 956 /* Set RX mode. */ 957 if (promisc && 958 !(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS) 959 ) { 960 sc->an_rxmode = sc->an_config.an_rxmode; 961 /* kills card DJA, if in sniff mode can't TX packets 962 sc->an_config.an_rxmode |= 963 AN_RXMODE_LAN_MONITOR_CURBSS; 964 */ 965 } else { 966 sc->an_config.an_rxmode = sc->an_rxmode; 967 } 968 969 /* Transfer the configuration to the NIC */ 970 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 971 sc->an_config.an_type = AN_RID_GENCONFIG; 972 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 973 printf("%s: failed to set configuration\n", sc->an_dev.dv_xname); 974 return; 975 } 976 /* Turn the MAC back on. */ 977 an_cmd(sc, AN_CMD_ENABLE, 0); 978 979 return; 980 } 981 982 static int an_ioctl(ifp, command, data) 983 struct ifnet *ifp; 984 u_long command; 985 caddr_t data; 986 { 987 int i; 988 int error = 0; 989 struct an_softc *sc; 990 struct an_req areq; 991 struct ifreq *ifr; 992 struct an_ltv_wepkey *akey; 993 struct ieee80211_nwid nwid; 994 struct ieee80211_nwkey *nwkey; 995 struct ieee80211_power *power; 996 997 sc = ifp->if_softc; 998 ifr = (struct ifreq *)data; 999 1000 switch(command) { 1001 case SIOCSIFFLAGS: 1002 if ((ifp->if_flags & sc->an_if_flags & 1003 (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { 1004 if (ifp->if_flags & IFF_PROMISC && 1005 !(sc->an_if_flags & IFF_PROMISC)) { 1006 an_promisc(sc, 1); 1007 break; 1008 } 1009 if (!(ifp->if_flags & IFF_PROMISC) && 1010 sc->an_if_flags & IFF_PROMISC) { 1011 an_promisc(sc, 0); 1012 break; 1013 } 1014 } 1015 error = ether_ioctl(ifp, command, data); 1016 sc->an_if_flags = ifp->if_flags; 1017 break; 1018 case SIOCGAIRONET: 1019 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1020 if (error) 1021 break; 1022 #ifdef ANCACHE 1023 if (areq.an_type == AN_RID_ZERO_CACHE) { 1024 sc->an_sigitems = sc->an_nextitem = 0; 1025 break; 1026 } else if (areq.an_type == AN_RID_READ_CACHE) { 1027 char *pt = (char *)&areq.an_val; 1028 bcopy((char *)&sc->an_sigitems, (char *)pt, 1029 sizeof(int)); 1030 pt += sizeof(int); 1031 areq.an_len = sizeof(int) / 2; 1032 bcopy((char *)&sc->an_sigcache, (char *)pt, 1033 sizeof(struct an_sigcache) * sc->an_sigitems); 1034 areq.an_len += ((sizeof(struct an_sigcache) * 1035 sc->an_sigitems) / 2) + 1; 1036 } else 1037 #endif 1038 if (an_read_record(sc, (struct an_ltv_gen *)&areq)) { 1039 error = EINVAL; 1040 break; 1041 } 1042 error = copyout(&areq, ifr->ifr_data, sizeof(areq)); 1043 break; 1044 case SIOCSAIRONET: 1045 if ((error = suser(curproc->p_ucred, &curproc->p_acflag))) 1046 goto out; 1047 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1048 if (error) 1049 break; 1050 an_setdef(sc, &areq); 1051 break; 1052 case SIOCS80211NWID: 1053 error = copyin(ifr->ifr_data, &nwid, sizeof(nwid)); 1054 if (error) 1055 break; 1056 if (nwid.i_len > IEEE80211_NWID_LEN) { 1057 error = EINVAL; 1058 break; 1059 } 1060 if (sc->an_ssidlist.an_ssid1_len == nwid.i_len && 1061 memcmp(sc->an_ssidlist.an_ssid1, nwid.i_nwid, nwid.i_len) 1062 == 0) 1063 break; 1064 memset(sc->an_ssidlist.an_ssid1, 0, IEEE80211_NWID_LEN); 1065 sc->an_ssidlist.an_ssid1_len = nwid.i_len; 1066 memcpy(sc->an_ssidlist.an_ssid1, nwid.i_nwid, nwid.i_len); 1067 if (sc->sc_enabled) 1068 an_init(ifp); 1069 break; 1070 case SIOCG80211NWID: 1071 memset(&nwid, 0, sizeof(nwid)); 1072 if ((ifp->if_flags & IFF_RUNNING) && sc->an_associated) { 1073 nwid.i_len = sc->an_status.an_ssidlen; 1074 memcpy(nwid.i_nwid, sc->an_status.an_ssid, nwid.i_len); 1075 } else { 1076 nwid.i_len = sc->an_ssidlist.an_ssid1_len; 1077 memcpy(nwid.i_nwid, sc->an_ssidlist.an_ssid1, 1078 nwid.i_len); 1079 } 1080 error = copyout(&nwid, ifr->ifr_data, sizeof(nwid)); 1081 break; 1082 case SIOCS80211NWKEY: 1083 nwkey = (struct ieee80211_nwkey *)data; 1084 sc->an_config.an_authtype &= AN_AUTHTYPE_MASK; 1085 if (nwkey->i_wepon) 1086 sc->an_config.an_authtype |= (AN_AUTHTYPE_MASK + 1); 1087 akey = (struct an_ltv_wepkey *)&areq; 1088 memset(akey, 0, sizeof(struct an_ltv_wepkey)); 1089 akey->an_type = AN_RID_WEP_VOLATILE; 1090 akey->an_len = sizeof(struct an_ltv_wepkey); 1091 akey->an_key_index = 0; 1092 akey->an_mac_addr[0] = 1; /* default mac */ 1093 akey->an_key_len = nwkey->i_key[0].i_keylen; 1094 if (akey->an_key_len > sizeof(akey->an_key)) { 1095 error = EINVAL; 1096 break; 1097 } 1098 if (nwkey->i_key[0].i_keydat != NULL) { 1099 if ((error = copyin(nwkey->i_key[0].i_keydat, 1100 akey->an_key, akey->an_key_len)) != 0) 1101 break; 1102 } 1103 memcpy(&sc->an_temp_keys, akey, sizeof(struct an_ltv_wepkey)); 1104 if (sc->sc_enabled) 1105 an_init(ifp); 1106 break; 1107 case SIOCG80211NWKEY: 1108 nwkey = (struct ieee80211_nwkey *)data; 1109 nwkey->i_wepon = 1110 sc->an_config.an_authtype & ~AN_AUTHTYPE_MASK ? 1 : 0; 1111 nwkey->i_defkid = 1; 1112 if (nwkey->i_key[0].i_keydat == NULL) 1113 break; 1114 /* do not show any keys to non-root user */ 1115 if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0) 1116 break; 1117 akey = &sc->an_temp_keys; 1118 nwkey->i_key[0].i_keylen = akey->an_key_len; 1119 for (i = 1; i < IEEE80211_WEP_NKID; i++) 1120 nwkey->i_key[i].i_keylen = 0; 1121 error = copyout(akey->an_key, nwkey->i_key[0].i_keydat, 1122 akey->an_key_len); 1123 break; 1124 case SIOCS80211POWER: 1125 power = (struct ieee80211_power *)data; 1126 sc->an_config.an_psave_mode = power->i_enabled ? 1127 AN_PSAVE_PSP : AN_PSAVE_NONE; 1128 sc->an_config.an_listen_interval = power->i_maxsleep; 1129 if (sc->sc_enabled) 1130 an_init(ifp); 1131 break; 1132 case SIOCG80211POWER: 1133 power = (struct ieee80211_power *)data; 1134 power->i_enabled = 1135 sc->an_config.an_psave_mode != AN_PSAVE_NONE ? 1 : 0; 1136 power->i_maxsleep = sc->an_config.an_listen_interval; 1137 break; 1138 #ifdef IFM_IEEE80211 1139 case SIOCSIFMEDIA: 1140 case SIOCGIFMEDIA: 1141 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command); 1142 break; 1143 #endif 1144 default: 1145 error = ether_ioctl(ifp, command, data); 1146 break; 1147 } 1148 out: 1149 return(error); 1150 } 1151 1152 #ifdef IFM_IEEE80211 1153 static int 1154 an_media_change(ifp) 1155 struct ifnet *ifp; 1156 { 1157 struct an_softc *sc = ifp->if_softc; 1158 struct ifmedia_entry *ime; 1159 int error; 1160 1161 error = 0; 1162 ime = sc->sc_media.ifm_cur; 1163 switch (IFM_SUBTYPE(ime->ifm_media)) { 1164 case IFM_AUTO: 1165 sc->an_tx_rate = 0; 1166 break; 1167 case IFM_IEEE80211_DS1: 1168 sc->an_tx_rate = AN_RATE_1MBPS; 1169 break; 1170 case IFM_IEEE80211_DS2: 1171 sc->an_tx_rate = AN_RATE_2MBPS; 1172 break; 1173 case IFM_IEEE80211_DS5: 1174 sc->an_tx_rate = AN_RATE_5_5MBPS; 1175 break; 1176 case IFM_IEEE80211_DS11: 1177 sc->an_tx_rate = AN_RATE_11MBPS; 1178 break; 1179 } 1180 if (ime->ifm_media & IFM_IEEE80211_ADHOC) 1181 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; 1182 else 1183 sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION; 1184 /* 1185 * XXX: how to set txrate for the firmware? 1186 * There is a struct defined as an_txframe, which is used nowhere. 1187 * Perhaps we need to change the transmit mode from 802.3 to native. 1188 */ 1189 if (sc->sc_enabled) 1190 an_init(ifp); 1191 return error; 1192 } 1193 1194 static void 1195 an_media_status(ifp, imr) 1196 struct ifnet *ifp; 1197 struct ifmediareq *imr; 1198 { 1199 struct an_softc *sc = ifp->if_softc; 1200 1201 imr->ifm_status = IFM_AVALID; 1202 if (sc->an_associated) 1203 imr->ifm_status |= IFM_ACTIVE; 1204 imr->ifm_active = IFM_IEEE80211; 1205 switch (sc->an_tx_rate) { 1206 case 0: 1207 imr->ifm_active |= IFM_AUTO; 1208 break; 1209 case AN_RATE_1MBPS: 1210 imr->ifm_active |= IFM_IEEE80211_DS1; 1211 break; 1212 case AN_RATE_2MBPS: 1213 imr->ifm_active |= IFM_IEEE80211_DS2; 1214 break; 1215 case AN_RATE_5_5MBPS: 1216 imr->ifm_active |= IFM_IEEE80211_DS5; 1217 break; 1218 case AN_RATE_11MBPS: 1219 imr->ifm_active |= IFM_IEEE80211_DS11; 1220 break; 1221 } 1222 if ((sc->an_config.an_opmode & 0x0f) == AN_OPMODE_IBSS_ADHOC) 1223 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1224 } 1225 #endif /* IFM_IEEE80211 */ 1226 1227 static int an_init_tx_ring(sc) 1228 struct an_softc *sc; 1229 { 1230 int i; 1231 int id; 1232 1233 if (!sc->sc_enabled) 1234 return (0); 1235 1236 for (i = 0; i < AN_TX_RING_CNT; i++) { 1237 if (an_alloc_nicmem(sc, 1518 + 1238 0x44, &id)) 1239 return(ENOMEM); 1240 sc->an_rdata.an_tx_fids[i] = id; 1241 sc->an_rdata.an_tx_ring[i] = 0; 1242 } 1243 1244 sc->an_rdata.an_tx_prod = 0; 1245 sc->an_rdata.an_tx_cons = 0; 1246 1247 return(0); 1248 } 1249 1250 static int an_init(ifp) 1251 struct ifnet *ifp; 1252 { 1253 struct an_softc *sc = (struct an_softc *)ifp->if_softc; 1254 1255 if (ifp->if_flags & IFF_RUNNING) 1256 an_stop(ifp, 0); 1257 1258 sc->an_associated = 0; 1259 1260 if (!sc->sc_enabled) { 1261 if (sc->sc_enable) 1262 (*sc->sc_enable)(sc); 1263 sc->sc_enabled = 1; 1264 } 1265 1266 /* Allocate the TX buffers */ 1267 if (an_init_tx_ring(sc)) { 1268 an_reset(sc); 1269 if (an_init_tx_ring(sc)) { 1270 printf("%s: tx buffer allocation " 1271 "failed\n", sc->an_dev.dv_xname); 1272 return ENOMEM; 1273 } 1274 } 1275 1276 /* Set our MAC address. */ 1277 bcopy((char *)&sc->an_caps.an_oemaddr, 1278 (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN); 1279 1280 if (ifp->if_flags & IFF_BROADCAST) 1281 sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR; 1282 else 1283 sc->an_config.an_rxmode = AN_RXMODE_ADDR; 1284 1285 if (ifp->if_flags & IFF_MULTICAST) 1286 sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR; 1287 1288 /* Initialize promisc mode. */ 1289 /* Kills card DJA can't TX packet in sniff mode 1290 if (ifp->if_flags & IFF_PROMISC) 1291 sc->an_config.an_rxmode |= AN_RXMODE_LAN_MONITOR_CURBSS; 1292 */ 1293 1294 sc->an_rxmode = sc->an_config.an_rxmode; 1295 1296 /* Set the ssid list */ 1297 sc->an_ssidlist.an_type = AN_RID_SSIDLIST; 1298 sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist); 1299 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) { 1300 printf("%s: failed to set ssid list\n", sc->an_dev.dv_xname); 1301 return ENXIO; 1302 } 1303 1304 /* Set the AP list */ 1305 sc->an_aplist.an_type = AN_RID_APLIST; 1306 sc->an_aplist.an_len = sizeof(struct an_ltv_aplist); 1307 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) { 1308 printf("%s: failed to set AP list\n", sc->an_dev.dv_xname); 1309 return ENXIO; 1310 } 1311 1312 /* Set the configuration in the NIC */ 1313 sc->an_config.an_len = sizeof(struct an_ltv_genconfig); 1314 sc->an_config.an_type = AN_RID_GENCONFIG; 1315 if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) { 1316 printf("%s: failed to set configuration\n", sc->an_dev.dv_xname); 1317 return ENXIO; 1318 } 1319 1320 /* Set the WEP Keys */ 1321 if ((sc->an_config.an_authtype & ~AN_AUTHTYPE_MASK) != 0) { 1322 sc->an_temp_keys.an_len = sizeof(struct an_ltv_wepkey); 1323 sc->an_temp_keys.an_type = AN_RID_WEP_VOLATILE; 1324 an_write_record(sc, (struct an_ltv_gen *)&sc->an_temp_keys); 1325 } 1326 1327 /* Enable the MAC */ 1328 if (an_cmd(sc, AN_CMD_ENABLE, 0)) { 1329 printf("%s: failed to enable MAC\n", sc->an_dev.dv_xname); 1330 return ENXIO; 1331 } 1332 1333 /* enable interrupts */ 1334 CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS); 1335 1336 ifp->if_flags |= IFF_RUNNING; 1337 ifp->if_flags &= ~IFF_OACTIVE; 1338 1339 callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc); 1340 return 0; 1341 } 1342 1343 static void an_start(ifp) 1344 struct ifnet *ifp; 1345 { 1346 struct an_softc *sc; 1347 struct mbuf *m0 = NULL; 1348 struct an_txframe_802_3 tx_frame_802_3; 1349 struct ether_header *eh; 1350 int id; 1351 int idx; 1352 unsigned char txcontrol; 1353 1354 sc = ifp->if_softc; 1355 1356 if (!sc->sc_enabled) 1357 return; 1358 1359 if (ifp->if_flags & IFF_OACTIVE) 1360 return; 1361 1362 if (!sc->an_associated) 1363 return; 1364 1365 idx = sc->an_rdata.an_tx_prod; 1366 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 1367 1368 while(sc->an_rdata.an_tx_ring[idx] == 0) { 1369 IFQ_DEQUEUE(&ifp->if_snd, m0); 1370 if (m0 == NULL) 1371 break; 1372 1373 id = sc->an_rdata.an_tx_fids[idx]; 1374 eh = mtod(m0, struct ether_header *); 1375 1376 bcopy((char *)&eh->ether_dhost, 1377 (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); 1378 bcopy((char *)&eh->ether_shost, 1379 (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); 1380 1381 tx_frame_802_3.an_tx_802_3_payload_len = 1382 m0->m_pkthdr.len - 12; /* minus src/dest mac & type */ 1383 1384 m_copydata(m0, sizeof(struct ether_header) - 2 , 1385 tx_frame_802_3.an_tx_802_3_payload_len, 1386 (caddr_t)&sc->an_txbuf); 1387 1388 txcontrol=AN_TXCTL_8023; 1389 /* write the txcontrol only */ 1390 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 1391 sizeof(txcontrol)); 1392 1393 /* 802_3 header */ 1394 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 1395 sizeof(struct an_txframe_802_3)); 1396 1397 /* in mbuf header type is just before payload */ 1398 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 1399 tx_frame_802_3.an_tx_802_3_payload_len); 1400 #if NBPFILTER > 0 1401 /* 1402 * If there's a BPF listner, bounce a copy of 1403 * this frame to him. 1404 */ 1405 if (ifp->if_bpf) 1406 bpf_mtap(ifp->if_bpf, m0); 1407 #endif 1408 1409 m_freem(m0); 1410 m0 = NULL; 1411 1412 /* TX START disable lan monitor ? DJA 1413 an_disable_sniff(): 1414 */ 1415 sc->an_rdata.an_tx_ring[idx] = id; 1416 if (an_cmd(sc, AN_CMD_TX, id)) 1417 printf("%s: xmit failed\n", sc->an_dev.dv_xname); 1418 1419 AN_INC(idx, AN_TX_RING_CNT); 1420 } 1421 1422 if (m0 != NULL) 1423 ifp->if_flags |= IFF_OACTIVE; 1424 1425 sc->an_rdata.an_tx_prod = idx; 1426 1427 /* 1428 * Set a timeout in case the chip goes out to lunch. 1429 */ 1430 ifp->if_timer = 5; 1431 1432 return; 1433 } 1434 1435 void an_stop(ifp, disable) 1436 struct ifnet *ifp; 1437 int disable; 1438 { 1439 struct an_softc *sc = (struct an_softc *)ifp->if_softc; 1440 int i; 1441 1442 callout_stop(&sc->an_stat_ch); 1443 if (!sc->sc_enabled) 1444 return; 1445 1446 an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0); 1447 CSR_WRITE_2(sc, AN_INT_EN, 0); 1448 an_cmd(sc, AN_CMD_DISABLE, 0); 1449 1450 for (i = 0; i < AN_TX_RING_CNT; i++) 1451 an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]); 1452 1453 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 1454 1455 if (disable) { 1456 if (sc->sc_disable) 1457 (*sc->sc_disable)(sc); 1458 sc->sc_enabled = 0; 1459 } 1460 1461 return; 1462 } 1463 1464 static void an_watchdog(ifp) 1465 struct ifnet *ifp; 1466 { 1467 struct an_softc *sc; 1468 1469 sc = ifp->if_softc; 1470 if (!sc->sc_enabled) 1471 return; 1472 1473 printf("%s: device timeout\n", sc->an_dev.dv_xname); 1474 1475 an_reset(sc); 1476 an_init(ifp); 1477 1478 ifp->if_oerrors++; 1479 return; 1480 } 1481 1482 void an_shutdown(dev) 1483 struct device * dev; 1484 { 1485 struct an_softc *sc = (struct an_softc *)dev; 1486 an_stop(&sc->arpcom.ec_if, 1); 1487 1488 return; 1489 } 1490 1491 #ifdef ANCACHE 1492 /* Aironet signal strength cache code. 1493 * store signal/noise/quality on per MAC src basis in 1494 * a small fixed cache. The cache wraps if > MAX slots 1495 * used. The cache may be zeroed out to start over. 1496 * Two simple filters exist to reduce computation: 1497 * 1. ip only (literally 0x800) which may be used 1498 * to ignore some packets. It defaults to ip only. 1499 * it could be used to focus on broadcast, non-IP 802.11 beacons. 1500 * 2. multicast/broadcast only. This may be used to 1501 * ignore unicast packets and only cache signal strength 1502 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 1503 * beacons and not unicast traffic. 1504 * 1505 * The cache stores (MAC src(index), IP src (major clue), signal, 1506 * quality, noise) 1507 * 1508 * No apologies for storing IP src here. It's easy and saves much 1509 * trouble elsewhere. The cache is assumed to be INET dependent, 1510 * although it need not be. 1511 * 1512 * Note: the Aironet only has a single byte of signal strength value 1513 * in the rx frame header, and it's not scaled to anything sensible. 1514 * This is kind of lame, but it's all we've got. 1515 */ 1516 1517 #ifdef documentation 1518 1519 int an_sigitems; /* number of cached entries */ 1520 struct an_sigcache an_sigcache[MAXANCACHE]; /* array of cache entries */ 1521 int an_nextitem; /* index/# of entries */ 1522 1523 1524 #endif 1525 1526 /* control variables for cache filtering. Basic idea is 1527 * to reduce cost (e.g., to only Mobile-IP agent beacons 1528 * which are broadcast or multicast). Still you might 1529 * want to measure signal strength anth unicast ping packets 1530 * on a pt. to pt. ant. setup. 1531 */ 1532 /* set true if you want to limit cache items to broadcast/mcast 1533 * only packets (not unicast). Useful for mobile-ip beacons which 1534 * are broadcast/multicast at network layer. Default is all packets 1535 * so ping/unicast anll work say anth pt. to pt. antennae setup. 1536 */ 1537 static int an_cache_mcastonly = 0; 1538 #if 0 1539 SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, 1540 &an_cache_mcastonly, 0, ""); 1541 #endif 1542 1543 /* set true if you want to limit cache items to IP packets only 1544 */ 1545 static int an_cache_iponly = 1; 1546 #if 0 1547 SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, 1548 &an_cache_iponly, 0, ""); 1549 #endif 1550 1551 /* 1552 * an_cache_store, per rx packet store signal 1553 * strength in MAC (src) indexed cache. 1554 */ 1555 static 1556 void an_cache_store (sc, eh, m, rx_quality) 1557 struct an_softc *sc; 1558 struct ether_header *eh; 1559 struct mbuf *m; 1560 unsigned short rx_quality; 1561 { 1562 struct ip *ip = 0; 1563 int i; 1564 static int cache_slot = 0; /* use this cache entry */ 1565 static int wrapindex = 0; /* next "free" cache entry */ 1566 int saanp=0; 1567 1568 /* filters: 1569 * 1. ip only 1570 * 2. configurable filter to throw out unicast packets, 1571 * keep multicast only. 1572 */ 1573 1574 if ((ntohs(eh->ether_type) == 0x800)) { 1575 saanp = 1; 1576 } 1577 1578 /* filter for ip packets only 1579 */ 1580 if ( an_cache_iponly && !saanp) { 1581 return; 1582 } 1583 1584 /* filter for broadcast/multicast only 1585 */ 1586 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 1587 return; 1588 } 1589 1590 #ifdef SIGDEBUG 1591 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 1592 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 1593 #endif 1594 1595 /* find the ip header. we want to store the ip_src 1596 * address. 1597 */ 1598 if (saanp) { 1599 ip = mtod(m, struct ip *); 1600 } 1601 1602 /* do a linear search for a matching MAC address 1603 * in the cache table 1604 * . MAC address is 6 bytes, 1605 * . var w_nextitem holds total number of entries already cached 1606 */ 1607 for(i = 0; i < sc->an_nextitem; i++) { 1608 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 1609 /* Match!, 1610 * so we already have this entry, 1611 * update the data 1612 */ 1613 break; 1614 } 1615 } 1616 1617 /* did we find a matching mac address? 1618 * if yes, then overwrite a previously existing cache entry 1619 */ 1620 if (i < sc->an_nextitem ) { 1621 cache_slot = i; 1622 } 1623 /* else, have a new address entry,so 1624 * add this new entry, 1625 * if table full, then we need to replace LRU entry 1626 */ 1627 else { 1628 1629 /* check for space in cache table 1630 * note: an_nextitem also holds number of entries 1631 * added in the cache table 1632 */ 1633 if ( sc->an_nextitem < MAXANCACHE ) { 1634 cache_slot = sc->an_nextitem; 1635 sc->an_nextitem++; 1636 sc->an_sigitems = sc->an_nextitem; 1637 } 1638 /* no space found, so simply wrap anth wrap index 1639 * and "zap" the next entry 1640 */ 1641 else { 1642 if (wrapindex == MAXANCACHE) { 1643 wrapindex = 0; 1644 } 1645 cache_slot = wrapindex++; 1646 } 1647 } 1648 1649 /* invariant: cache_slot now points at some slot 1650 * in cache. 1651 */ 1652 if (cache_slot < 0 || cache_slot >= MAXANCACHE) { 1653 log(LOG_ERR, "an_cache_store, bad index: %d of " 1654 "[0..%d], gross cache error\n", 1655 cache_slot, MAXANCACHE); 1656 return; 1657 } 1658 1659 /* store items in cache 1660 * .ip source address 1661 * .mac src 1662 * .signal, etc. 1663 */ 1664 if (saanp) { 1665 sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 1666 } 1667 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 1668 1669 sc->an_sigcache[cache_slot].signal = rx_quality; 1670 1671 return; 1672 } 1673 #endif 1674