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