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