if_ep.c revision 1020
1/* 2 * Copyright (c) 1993 Herb Peyerl <hpeyerl@novatel.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. The name of the author may not be used to endorse or promote products 11 * derived from this software withough specific prior written permission 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $ 25 * $Id: if_ep.c,v 1.5 1994/01/26 09:13:56 nate Exp $ 26 */ 27/* 28 * TODO: 29 * Multi-509 configs. 30 * don't pass unit into epstop. 31 * epintr returns an int for magnum. 0=not for me. 1=for me. -1=whoknows? 32 * deallocate mbufs when ifconfig'd down. 33 */ 34#include "ep.h" 35#if NEP > 0 36 37#include "bpfilter.h" 38 39#include <sys/param.h> 40#if defined(__FreeBSD__) 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#endif 44#include <sys/mbuf.h> 45#include <sys/socket.h> 46#include <sys/ioctl.h> 47#include <sys/errno.h> 48#include <sys/syslog.h> 49#if defined(__NetBSD__) 50#include <sys/select.h> 51#endif 52 53#include <net/if.h> 54#include <net/netisr.h> 55#include <net/if_dl.h> 56#include <net/if_types.h> 57#include <net/netisr.h> 58 59#ifdef INET 60#include <netinet/in.h> 61#include <netinet/in_systm.h> 62#include <netinet/in_var.h> 63#include <netinet/ip.h> 64#include <netinet/if_ether.h> 65#endif 66 67#ifdef NS 68#include <netns/ns.h> 69#include <netns/ns_if.h> 70#endif 71 72#if NBPFILTER > 0 73#include <net/bpf.h> 74#include <net/bpfdesc.h> 75#endif 76 77#include <machine/pio.h> 78 79#include <i386/isa/isa.h> 80#include <i386/isa/isa_device.h> 81#include <i386/isa/icu.h> 82#include <i386/isa/if_epreg.h> 83 84#define ETHER_MIN_LEN 64 85#define ETHER_MAX_LEN 1518 86#define ETHER_ADDR_LEN 6 87 88/* 89 * Ethernet software status per interface. 90 */ 91struct ep_softc { 92 struct arpcom arpcom; /* Ethernet common part */ 93 short ep_io_addr; /* i/o bus address */ 94 char ep_connectors; /* Connectors on this card. */ 95#define MAX_MBS 4 /* # of mbufs we keep around */ 96 struct mbuf *mb[MAX_MBS]; /* spare mbuf storage. */ 97 int next_mb; /* Which mbuf to use next. */ 98 int last_mb; /* Last mbuf. */ 99 int tx_start_thresh; /* Current TX_start_thresh. */ 100 caddr_t bpf; /* BPF "magic cookie" */ 101} ep_softc[NEP]; 102 103static int epprobe __P((struct isa_device *)); 104static int epattach __P((struct isa_device *)); 105static int epioctl __P((struct ifnet * ifp, int, caddr_t)); 106 107void epinit __P((int)); 108void epintr __P((int)); 109void epmbufqueue __P((caddr_t, int)); 110void epread __P((struct ep_softc *)); 111void epreset __P((int)); 112void epstart __P((struct ifnet *)); 113void epstop __P((int)); 114void epwatchdog __P((int)); 115 116struct isa_driver epdriver = { 117 epprobe, 118 epattach, 119 "ep" 120}; 121 122static int send_ID_sequence __P((u_short)); 123static u_short get_eeprom_data __P((int, int)); 124static int is_eeprom_busy __P((struct isa_device *)); 125 126/* 127 * Rudimentary support for multiple cards is here but is not 128 * currently handled. In the future we will have to add code 129 * for tagging the cards for later activation. We wanna do something 130 * about the id_port. We're limited due to current config procedure. 131 * Magnum config holds promise of a fix but we'll have to wait a bit. 132 */ 133int 134epprobe(is) 135 struct isa_device *is; 136{ 137 struct ep_softc *sc = &ep_softc[is->id_unit]; 138 u_short k; 139 int id_port = 0x100; /* XXX */ 140 141 outw(BASE + EP_COMMAND, GLOBAL_RESET); 142 DELAY(1000); 143 outb(id_port, 0xc0); /* Global reset to id_port. */ 144 DELAY(1000); 145 send_ID_sequence(id_port); 146 DELAY(1000); 147 148 /* 149 * MFG_ID should have 0x6d50. 150 * PROD_ID should be 0x9[0-f]50 151 */ 152 k = get_eeprom_data(id_port, EEPROM_MFG_ID); 153 if (k != MFG_ID) 154 return (0); 155 k = get_eeprom_data(id_port, EEPROM_PROD_ID); 156 if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) 157 return (0); 158 159 k = get_eeprom_data(id_port, EEPROM_ADDR_CFG); /* get addr cfg */ 160 k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */ 161 if (k != (u_short)is->id_iobase) 162 return (0); 163 164 k = get_eeprom_data(id_port, EEPROM_RESOURCE_CFG); 165 k >>= 12; 166 if (is->id_irq != (1 << ((k == 2) ? 9 : k))) 167 return (0); 168 169 outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG); 170 171 return (0x10); /* 16 bytes of I/O space used. */ 172} 173 174static int 175epattach(is) 176 struct isa_device *is; 177{ 178 struct ep_softc *sc = &ep_softc[is->id_unit]; 179 struct ifnet *ifp = &sc->arpcom.ac_if; 180 u_short i; 181 struct ifaddr *ifa; 182 struct sockaddr_dl *sdl; 183 184 sc->ep_io_addr = is->id_iobase; 185 186 printf("ep%d: ", is->id_unit); 187 188 sc->ep_connectors = 0; 189 i = inw(is->id_iobase + EP_W0_CONFIG_CTRL); 190 if (i & IS_AUI) { 191 printf("aui"); 192 sc->ep_connectors |= AUI; 193 } 194 if (i & IS_BNC) { 195 if (sc->ep_connectors) 196 printf("/"); 197 printf("bnc"); 198 sc->ep_connectors |= BNC; 199 } 200 if (i & IS_UTP) { 201 if (sc->ep_connectors) 202 printf("/"); 203 printf("utp"); 204 sc->ep_connectors |= UTP; 205 } 206 if (!sc->ep_connectors) 207 printf("no connectors!"); 208 209 /* 210 * Read the station address from the eeprom 211 */ 212 for (i = 0; i < 3; i++) { 213 u_short *p; 214 GO_WINDOW(0); 215 if (is_eeprom_busy(is)) 216 return(0); 217 outw(BASE + EP_W0_EEPROM_COMMAND, READ_EEPROM | i); 218 if (is_eeprom_busy(is)) 219 return(0); 220 p =(u_short *)&sc->arpcom.ac_enaddr[i*2]; 221 *p = htons(inw(BASE + EP_W0_EEPROM_DATA)); 222 GO_WINDOW(2); 223 outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(*p)); 224 } 225 printf(" address %s\n", ether_sprintf(sc->arpcom.ac_enaddr)); 226 227 ifp->if_unit = is->id_unit; 228 ifp->if_name = "ep"; 229 ifp->if_mtu = ETHERMTU; 230 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 231 ifp->if_init = epinit; 232 ifp->if_output = ether_output; 233 ifp->if_start = epstart; 234 ifp->if_ioctl = epioctl; 235 ifp->if_watchdog = epwatchdog; 236 237 if_attach(ifp); 238 239 /* 240 * Fill the hardware address into ifa_addr if we find an 241 * AF_LINK entry. We need to do this so bpf's can get the hardware 242 * addr of this card. netstat likes this too! 243 */ 244 ifa = ifp->if_addrlist; 245 while ((ifa != 0) && (ifa->ifa_addr != 0) && 246 (ifa->ifa_addr->sa_family != AF_LINK)) 247 ifa = ifa->ifa_next; 248 249 if ((ifa != 0) && (ifa->ifa_addr != 0)) { 250 sdl = (struct sockaddr_dl *) ifa->ifa_addr; 251 sdl->sdl_type = IFT_ETHER; 252 sdl->sdl_alen = ETHER_ADDR_LEN; 253 sdl->sdl_slen = 0; 254 bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN); 255 } 256#if NBPFILTER > 0 257 bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 258#endif 259 return 1; 260} 261 262 263/* 264 * The order in here seems important. Otherwise we may not receive 265 * interrupts. ?! 266 */ 267void 268epinit(unit) 269 int unit; 270{ 271 register struct ep_softc *sc = &ep_softc[unit]; 272 register struct ifnet *ifp = &sc->arpcom.ac_if; 273 int s, i; 274 275 if (ifp->if_addrlist == (struct ifaddr *) 0) 276 return; 277 278 s = splimp(); 279 while (inb(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) 280 ; 281 282 GO_WINDOW(0); 283 284 /* Disable the card */ 285 outw(BASE + EP_W0_CONFIG_CTRL, 0); 286 287 /* Enable the card */ 288 outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ); 289 290 GO_WINDOW(2); 291 292 /* Reload the ether_addr. */ 293 for (i = 0; i < 6; i++) 294 outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]); 295 296 outw(BASE + EP_COMMAND, RX_RESET); 297 outw(BASE + EP_COMMAND, TX_RESET); 298 299 /* Window 1 is operating window */ 300 GO_WINDOW(1); 301 for (i = 0; i < 31; i++) 302 inb(BASE + EP_W1_TX_STATUS); 303 304 /* get rid of stray intr's */ 305 outw(BASE + EP_COMMAND, ACK_INTR | 0xff); 306 307 outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE | 308 S_TX_COMPLETE | S_TX_AVAIL); 309 outw(BASE + EP_COMMAND, SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE | 310 S_TX_COMPLETE | S_TX_AVAIL); 311 312 outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | 313 FIL_GROUP | FIL_BRDCST); 314 315 /* 316 * you can `ifconfig (link0|-link0) ep0' to get the following 317 * behaviour: 318 * -link0 disable AUI/UTP. enable BNC. 319 * link0 disable BNC. enable AUI. if the card has a UTP 320 * connector, that is enabled too. not sure, but it 321 * seems you have to be careful to not plug things 322 * into both AUI & UTP. 323 */ 324#if defined(__NetBSD__) 325 if (!(ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & BNC)) { 326#else 327 if (!(ifp->if_flags & IFF_ALTPHYS) && (sc->ep_connectors & BNC)) { 328#endif 329 outw(BASE + EP_COMMAND, START_TRANSCEIVER); 330 DELAY(1000); 331 } 332#if defined(__NetBSD__) 333 if ((ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & UTP)) { 334#else 335 if ((ifp->if_flags & IFF_ALTPHYS) && (sc->ep_connectors & UTP)) { 336#endif 337 GO_WINDOW(4); 338 outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP); 339 GO_WINDOW(1); 340 } 341 342 outw(BASE + EP_COMMAND, RX_ENABLE); 343 outw(BASE + EP_COMMAND, TX_ENABLE); 344 345 ifp->if_flags |= IFF_RUNNING; 346 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */ 347 sc->tx_start_thresh = 20; /* probably a good starting point. */ 348 /* 349 * Store up a bunch of mbuf's for use later. (MAX_MBS). First we 350 * free up any that we had in case we're being called from intr or 351 * somewhere else. 352 */ 353 sc->last_mb = 0; 354 sc->next_mb = 0; 355 epmbufqueue((caddr_t)sc, 0); 356 357 epstart(ifp); 358 359 splx(s); 360} 361 362static const char padmap[] = {0, 3, 2, 1}; 363 364void 365epstart(ifp) 366 struct ifnet *ifp; 367{ 368 register struct ep_softc *sc = &ep_softc[ifp->if_unit]; 369 struct mbuf *m, *top; 370 int s, len, pad; 371 372 s = splimp(); 373 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) { 374 splx(s); 375 return; 376 } 377 378startagain: 379 /* Sneak a peek at the next packet */ 380 m = sc->arpcom.ac_if.if_snd.ifq_head; 381 if (m == 0) { 382 splx(s); 383 return; 384 } 385#if 0 386 len = m->m_pkthdr.len; 387#else 388 for (len = 0, top = m; m; m = m->m_next) 389 len += m->m_len; 390#endif 391 392 pad = padmap[len & 3]; 393 394 /* 395 * The 3c509 automatically pads short packets to minimum ethernet 396 * length, but we drop packets that are too large. Perhaps we should 397 * truncate them instead? 398 */ 399 if (len + pad > ETHER_MAX_LEN) { 400 /* packet is obviously too large: toss it */ 401 ++sc->arpcom.ac_if.if_oerrors; 402 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 403 m_freem(m); 404 goto readcheck; 405 } 406 407 if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) { 408 /* no room in FIFO */ 409 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4)); 410 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE; 411 splx(s); 412 return; 413 } 414 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 415 if (m == 0) { /* not really needed */ 416 splx(s); 417 return; 418 } 419 outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 420 (len / 4 + sc->tx_start_thresh)); 421 422 outw(BASE + EP_W1_TX_PIO_WR_1, len); 423 outw(BASE + EP_W1_TX_PIO_WR_1, 0xffff); /* Second dword meaningless */ 424 425 for (top = m; m != 0; m = m->m_next) { 426 outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len/2); 427 if (m->m_len & 1) 428 outb(BASE + EP_W1_TX_PIO_WR_1, 429 *(mtod(m, caddr_t) + m->m_len - 1)); 430 } 431 while (pad--) 432 outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */ 433 434#if NBPFILTER > 0 435 if (sc->bpf) { 436 u_short etype; 437 int off, datasize, resid; 438 struct ether_header *eh; 439 struct trailer_header { 440 u_short ether_type; 441 u_short ether_residual; 442 } trailer_header; 443 char ether_packet[ETHER_MAX_LEN]; 444 char *ep; 445 446 ep = ether_packet; 447 448 /* 449 * We handle trailers below: 450 * Copy ether header first, then residual data, 451 * then data. Put all this in a temporary buffer 452 * 'ether_packet' and send off to bpf. Since the 453 * system has generated this packet, we assume 454 * that all of the offsets in the packet are 455 * correct; if they're not, the system will almost 456 * certainly crash in m_copydata. 457 * We make no assumptions about how the data is 458 * arranged in the mbuf chain (i.e. how much 459 * data is in each mbuf, if mbuf clusters are 460 * used, etc.), which is why we use m_copydata 461 * to get the ether header rather than assume 462 * that this is located in the first mbuf. 463 */ 464 /* copy ether header */ 465 m_copydata(top, 0, sizeof(struct ether_header), ep); 466 eh = (struct ether_header *) ep; 467 ep += sizeof(struct ether_header); 468 eh->ether_type = etype = ntohs(eh->ether_type); 469 if (etype >= ETHERTYPE_TRAIL && 470 etype < ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER) { 471 datasize = ((etype - ETHERTYPE_TRAIL) << 9); 472 off = datasize + sizeof(struct ether_header); 473 474 /* copy trailer_header into a data structure */ 475 m_copydata(top, off, sizeof(struct trailer_header), 476 &trailer_header.ether_type); 477 478 /* copy residual data */ 479 resid = trailer_header.ether_residual - 480 sizeof(struct trailer_header); 481 resid = ntohs(resid); 482 m_copydata(top, off + sizeof(struct trailer_header), 483 resid, ep); 484 ep += resid; 485 486 /* copy data */ 487 m_copydata(top, sizeof(struct ether_header), 488 datasize, ep); 489 ep += datasize; 490 491 /* restore original ether packet type */ 492 eh->ether_type = trailer_header.ether_type; 493 494 bpf_tap(sc->bpf, ether_packet, ep - ether_packet); 495 } else 496 bpf_mtap(sc->bpf, top); 497 } 498#endif 499 500 m_freem(top); 501 ++sc->arpcom.ac_if.if_opackets; 502 503 /* 504 * Is another packet coming in? We don't want to overflow the 505 * tiny RX fifo. 506 */ 507readcheck: 508 if (inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK) { 509 splx(s); 510 return; 511 } 512 goto startagain; 513} 514 515void 516epintr(unit) 517 int unit; 518{ 519 int status, i; 520 register struct ep_softc *sc = &ep_softc[unit]; 521 struct ifnet *ifp = &sc->arpcom.ac_if; 522 struct mbuf *m; 523 524 status = 0; 525checkintr: 526 status = inw(BASE + EP_STATUS) & 527 (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE); 528 if (status == 0) { 529 /* No interrupts. */ 530 outw(BASE + EP_COMMAND, C_INTR_LATCH); 531 return; 532 } 533 /* important that we do this first. */ 534 outw(BASE + EP_COMMAND, ACK_INTR | status); 535 536 if (status & S_TX_AVAIL) { 537 status &= ~S_TX_AVAIL; 538 inw(BASE + EP_W1_FREE_TX); 539 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 540 epstart(&sc->arpcom.ac_if); 541 } 542 if (status & S_RX_COMPLETE) { 543 status &= ~S_RX_COMPLETE; 544 epread(sc); 545 } 546 if (status & S_CARD_FAILURE) { 547 printf("ep%d: reset (status: %x)\n", unit, status); 548 outw(BASE + EP_COMMAND, C_INTR_LATCH); 549 epinit(unit); 550 return; 551 } 552 if (status & S_TX_COMPLETE) { 553 status &= ~S_TX_COMPLETE; 554 /* 555 * We need to read TX_STATUS until we get a 0 status in 556 * order to turn off the interrupt flag. 557 */ 558 while ((i = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE) { 559 outw(BASE + EP_W1_TX_STATUS, 0x0); 560 if (i & (TXS_MAX_COLLISION | TXS_JABBER | TXS_UNDERRUN)) { 561 if (i & TXS_MAX_COLLISION) 562 ++sc->arpcom.ac_if.if_collisions; 563 if (i & (TXS_JABBER | TXS_UNDERRUN)) { 564 outw(BASE + EP_COMMAND, TX_RESET); 565 if (i & TXS_UNDERRUN) { 566 if (sc->tx_start_thresh < ETHER_MAX_LEN) { 567 sc->tx_start_thresh += 20; 568 outw(BASE + EP_COMMAND, 569 SET_TX_START_THRESH | 570 sc->tx_start_thresh); 571 } 572 } 573 } 574 outw(BASE + EP_COMMAND, TX_ENABLE); 575 ++sc->arpcom.ac_if.if_oerrors; 576 } 577 } 578 epstart(ifp); 579 } 580 goto checkintr; 581} 582 583void 584epread(sc) 585 register struct ep_softc *sc; 586{ 587 struct ether_header *eh; 588 struct mbuf *mcur, *m, *m0, *top; 589 int totlen, lenthisone; 590 int save_totlen; 591 u_short etype; 592 int off, resid; 593 int count, spinwait; 594 int i; 595 596 totlen = inw(BASE + EP_W1_RX_STATUS); 597 off = 0; 598 top = 0; 599 600 if (totlen & ERR_RX) { 601 ++sc->arpcom.ac_if.if_ierrors; 602 goto out; 603 } 604 save_totlen = totlen &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */ 605 606 m = sc->mb[sc->next_mb]; 607 sc->mb[sc->next_mb] = 0; 608 609 if (m == 0) { 610 MGETHDR(m, M_DONTWAIT, MT_DATA); 611 if (m == 0) 612 goto out; 613 } else { 614 /* Convert one of our saved mbuf's */ 615 sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 616 m->m_data = m->m_pktdat; 617 m->m_flags = M_PKTHDR; 618 } 619 620 top = m0 = m; /* We assign top so we can "goto out" */ 621#define EROUND ((sizeof(struct ether_header) + 3) & ~3) 622#define EOFF (EROUND - sizeof(struct ether_header)) 623 m0->m_data += EOFF; 624 /* Read what should be the header. */ 625 insw(BASE + EP_W1_RX_PIO_RD_1, 626 mtod(m0, caddr_t), sizeof(struct ether_header) / 2); 627 m->m_len = sizeof(struct ether_header); 628 totlen -= sizeof(struct ether_header); 629 /* 630 * mostly deal with trailer here. (untested) 631 * We do this in a couple of parts. First we check for a trailer, if 632 * we have one we convert the mbuf back to a regular mbuf and set the offset and 633 * subtract sizeof(struct ether_header) from the pktlen. 634 * After we've read the packet off the interface (all except for the trailer 635 * header, we then get a header mbuf, read the trailer into it, and fix up 636 * the mbuf pointer chain. 637 */ 638 eh = mtod(m, struct ether_header *); 639 eh->ether_type = etype = ntohs((u_short) eh->ether_type); 640 if (etype >= ETHERTYPE_TRAIL && 641 etype < ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER) { 642 m->m_data = m->m_dat; /* Convert back to regular mbuf. */ 643 m->m_flags = 0; /* This sucks but non-trailers are the norm */ 644 off = (etype - ETHERTYPE_TRAIL) * 512; 645 if (off >= ETHERMTU) { 646 m_freem(m); 647 return; /* sanity */ 648 } 649 totlen -= sizeof(struct ether_header); /* We don't read the trailer */ 650 m->m_data += 2 * sizeof(u_short); /* Get rid of type & len */ 651 } 652 while (totlen > 0) { 653 lenthisone = min(totlen, M_TRAILINGSPACE(m)); 654 if (lenthisone == 0) { /* no room in this one */ 655 mcur = m; 656 m = sc->mb[sc->next_mb]; 657 sc->mb[sc->next_mb] = 0; 658 if (!m) { 659 MGET(m, M_DONTWAIT, MT_DATA); 660 if (m == 0) 661 goto out; 662 } else { 663 timeout(epmbufqueue, (caddr_t)sc, 0); 664 sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 665 } 666 if (totlen >= MINCLSIZE) 667 MCLGET(m, M_DONTWAIT); 668 m->m_len = 0; 669 mcur->m_next = m; 670 lenthisone = min(totlen, M_TRAILINGSPACE(m)); 671 } 672 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, 673 lenthisone / 2); 674 m->m_len += lenthisone; 675 if (lenthisone & 1) 676 *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1); 677 totlen -= lenthisone; 678 } 679 if (off) { 680 top = sc->mb[sc->next_mb]; 681 sc->mb[sc->next_mb] = 0; 682 if (top == 0) { 683 MGETHDR(m, M_DONTWAIT, MT_DATA); 684 if (top == 0) 685 goto out; 686 } else { 687 /* Convert one of our saved mbuf's */ 688 sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 689 top->m_data = top->m_pktdat; 690 top->m_flags = M_PKTHDR; 691 } 692 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, 693 sizeof(struct ether_header)); 694 top->m_next = m0; 695 top->m_len = sizeof(struct ether_header); 696 /* XXX Accomodate for type and len from beginning of trailer */ 697 top->m_pkthdr.len = save_totlen - (2 * sizeof(u_short)); 698 } else { 699 top = m0; 700 top->m_pkthdr.len = save_totlen; 701 } 702 703 top->m_pkthdr.rcvif = &sc->arpcom.ac_if; 704 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); 705 while (inb(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) 706 ; 707 ++sc->arpcom.ac_if.if_ipackets; 708#if NBPFILTER > 0 709 if (sc->bpf) { 710 bpf_mtap(sc->bpf, top); 711 712 /* 713 * Note that the interface cannot be in promiscuous mode if 714 * there are no BPF listeners. And if we are in promiscuous 715 * mode, we have to check if this packet is really ours. 716 */ 717 if ((sc->ep_ac.ac_if.if_flags & IFF_PROMISC) && 718 (eh->ether_dhost[0] & 1) == 0 && 719 bcmp(eh->ether_dhost, sc->ep_ac.ac_enaddr, 720 sizeof(eh->ether_dhost)) != 0 && 721 bcmp(eh->ether_dhost, etherbroadcastaddr, 722 sizeof(eh->ether_dhost)) != 0) { 723 m_freem(top); 724 return; 725 } 726 } 727#endif 728 m_adj(top, sizeof(struct ether_header)); 729 ether_input(&sc->arpcom.ac_if, eh, top); 730 return; 731 732out: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); 733 while (inb(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) 734 ; 735 if (top) 736 m_freem(top); 737 738 return; 739} 740 741 742/* 743 * Look familiar? 744 */ 745static int 746epioctl(ifp, cmd, data) 747 register struct ifnet *ifp; 748 int cmd; 749 caddr_t data; 750{ 751 register struct ifaddr *ifa = (struct ifaddr *) data; 752 struct ep_softc *sc = &ep_softc[ifp->if_unit]; 753 struct ifreq *ifr = (struct ifreq *) data; 754 int s, error = 0; 755 756 switch (cmd) { 757 case SIOCSIFADDR: 758 ifp->if_flags |= IFF_UP; 759 switch (ifa->ifa_addr->sa_family) { 760#ifdef INET 761 case AF_INET: 762 epinit(ifp->if_unit); /* before arpwhohas */ 763 ((struct arpcom *) ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr; 764 arpwhohas((struct arpcom *) ifp, &IA_SIN(ifa)->sin_addr); 765 break; 766#endif 767#ifdef NS 768 case AF_NS: 769 { 770 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 771 772 if (ns_nullhost(*ina)) 773 ina->x_host = 774 *(union ns_host *)(sc->arpcom.ac_enaddr); 775 else { 776 ifp->if_flags &= ~IFF_RUNNING; 777 bcopy((caddr_t) ina->x_host.c_host, 778 (caddr_t)sc->arpcom.ns_addr 779 sizeof(sc->arpcom.ac_enaddr)); 780 } 781 epinit(ifp->if_unit); 782 break; 783 } 784#endif 785 default: 786 epinit(ifp->if_unit); 787 break; 788 } 789 break; 790 case SIOCSIFFLAGS: 791 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { 792 ifp->if_flags &= ~IFF_RUNNING; 793 epstop(ifp->if_unit); 794 break; 795 } 796 if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0) 797 epinit(ifp->if_unit); 798 break; 799#ifdef notdef 800 case SIOCGHWADDR: 801 bcopy((caddr_t) sc->sc_addr, (caddr_t) &ifr->ifr_data, 802 sizeof(sc->sc_addr)); 803 break; 804#endif 805 default: 806 error = EINVAL; 807 } 808 return (error); 809} 810 811void 812epreset(unit) 813 int unit; 814{ 815 int s = splimp(); 816 817 epstop(unit); 818 epinit(unit); 819 splx(s); 820 return; 821} 822 823void 824epwatchdog(unit) 825 int unit; 826{ 827 struct ep_softc *sc = &ep_softc[unit]; 828 829 log(LOG_ERR, "ep%d: watchdog\n", unit); 830 ++sc->arpcom.ac_if.if_oerrors; 831 832 epreset(unit); 833} 834 835void 836epstop(unit) 837 int unit; 838{ 839 struct ep_softc *sc = &ep_softc[unit]; 840 841 outw(BASE + EP_COMMAND, RX_DISABLE); 842 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); 843 while (inb(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) 844 ; 845 outw(BASE + EP_COMMAND, TX_DISABLE); 846 outw(BASE + EP_COMMAND, STOP_TRANSCEIVER); 847 outw(BASE + EP_COMMAND, RX_RESET); 848 outw(BASE + EP_COMMAND, TX_RESET); 849 outw(BASE + EP_COMMAND, C_INTR_LATCH); 850 outw(BASE + EP_COMMAND, SET_RD_0_MASK); 851 outw(BASE + EP_COMMAND, SET_INTR_MASK); 852 outw(BASE + EP_COMMAND, SET_RX_FILTER); 853 return; 854} 855 856 857/* 858 * This is adapted straight from the book. There's probably a better way. 859 */ 860static int 861send_ID_sequence(port) 862 u_short port; 863{ 864 char cx, al; 865 866 cx = 0x0ff; 867 al = 0x0ff; 868 869 outb(port, 0x0); 870 DELAY(1000); 871 outb(port, 0x0); 872 DELAY(1000); 873 874loop1: cx--; 875 outb(port, al); 876 if (!(al & 0x80)) { 877 al = al << 1; 878 goto loop1; 879 } 880 al = al << 1; 881 al ^= 0xcf; 882 if (cx) 883 goto loop1; 884 885 return(1); 886} 887 888 889/* 890 * We get eeprom data from the id_port given an offset into the 891 * eeprom. Basically; after the ID_sequence is sent to all of 892 * the cards; they enter the ID_CMD state where they will accept 893 * command requests. 0x80-0xbf loads the eeprom data. We then 894 * read the port 16 times and with every read; the cards check 895 * for contention (ie: if one card writes a 0 bit and another 896 * writes a 1 bit then the host sees a 0. At the end of the cycle; 897 * each card compares the data on the bus; if there is a difference 898 * then that card goes into ID_WAIT state again). In the meantime; 899 * one bit of data is returned in the AX register which is conveniently 900 * returned to us by inb(). Hence; we read 16 times getting one 901 * bit of data with each read. 902 */ 903static u_short 904get_eeprom_data(id_port, offset) 905 int id_port; 906 int offset; 907{ 908 int i, data = 0; 909 outb(id_port, 0x80 + offset); 910 DELAY(1000); 911 for (i = 0; i < 16; i++) 912 data = (data << 1) | (inw(id_port) & 1); 913 return (data); 914} 915 916static int 917is_eeprom_busy(is) 918 struct isa_device *is; 919{ 920 int i = 0, j; 921 register struct ep_softc *sc = &ep_softc[is->id_unit]; 922 923 while (i++ < 100) { 924 j = inw(BASE + EP_W0_EEPROM_COMMAND); 925 if (j & EEPROM_BUSY) 926 DELAY(100); 927 else 928 break; 929 } 930 if (i >= 100) { 931 printf("\nep%d: eeprom failed to come ready.\n", is->id_unit); 932 return (1); 933 } 934 if (j & EEPROM_TST_MODE) { 935 printf("\nep%d: 3c509 in test mode. Erase pencil mark!\n", is->id_unit); 936 return (1); 937 } 938 return (0); 939} 940 941void 942epmbufqueue(sp, dummy_arg) 943 caddr_t sp; 944 int dummy_arg; 945{ 946 struct ep_softc *sc = (struct ep_softc *)sp; 947 int i; 948 949 if (sc->mb[sc->last_mb]) 950 return; 951 i = sc->last_mb; 952 do { 953 MGET(sc->mb[i], M_DONTWAIT, MT_DATA); 954 if (!sc->mb[i]) 955 break; 956 i = (i + 1) % MAX_MBS; 957 } while (i != sc->next_mb); 958 sc->last_mb = i; 959 return; 960} 961 962#endif /* NEP > 0 */ 963