1*55139Storek /*- 2*55139Storek * Copyright (c) 1982, 1992 The Regents of the University of California. 3*55139Storek * All rights reserved. 4*55139Storek * 5*55139Storek * %sccs.include.redist.c% 6*55139Storek * 7*55139Storek * @(#)if_le.c 7.1 (Berkeley) 07/13/92 8*55139Storek * 9*55139Storek * from: $Header: if_le.c,v 1.17 92/07/10 06:45:17 torek Exp $ 10*55139Storek */ 11*55139Storek 12*55139Storek #include "bpfilter.h" 13*55139Storek 14*55139Storek /* 15*55139Storek * AMD 7990 LANCE 16*55139Storek * 17*55139Storek * This driver will generate and accept tailer encapsulated packets even 18*55139Storek * though it buys us nothing. The motivation was to avoid incompatibilities 19*55139Storek * with VAXen, SUNs, and others that handle and benefit from them. 20*55139Storek * This reasoning is dubious. 21*55139Storek */ 22*55139Storek #include "sys/param.h" 23*55139Storek #include "sys/device.h" 24*55139Storek #include "sys/systm.h" 25*55139Storek #include "sys/kernel.h" 26*55139Storek #include "sys/mbuf.h" 27*55139Storek #include "sys/buf.h" 28*55139Storek #include "sys/socket.h" 29*55139Storek #include "sys/syslog.h" 30*55139Storek #include "sys/ioctl.h" 31*55139Storek #include "sys/malloc.h" 32*55139Storek #include "sys/errno.h" 33*55139Storek 34*55139Storek #include "../net/if.h" 35*55139Storek #include "../net/netisr.h" 36*55139Storek #include "../net/route.h" 37*55139Storek #if NBPFILTER > 0 38*55139Storek #include "sys/select.h" 39*55139Storek #include "../net/bpf.h" 40*55139Storek #include "../net/bpfdesc.h" 41*55139Storek #endif 42*55139Storek 43*55139Storek #ifdef INET 44*55139Storek #include "../netinet/in.h" 45*55139Storek #include "../netinet/in_systm.h" 46*55139Storek #include "../netinet/in_var.h" 47*55139Storek #include "../netinet/ip.h" 48*55139Storek #include "../netinet/if_ether.h" 49*55139Storek #endif 50*55139Storek 51*55139Storek #ifdef NS 52*55139Storek #include "../netns/ns.h" 53*55139Storek #include "../netns/ns_if.h" 54*55139Storek #endif 55*55139Storek 56*55139Storek #ifdef APPLETALK 57*55139Storek #include "../netddp/atalk.h" 58*55139Storek #endif 59*55139Storek 60*55139Storek #include "machine/autoconf.h" 61*55139Storek #include "machine/cpu.h" 62*55139Storek #include "machine/pmap.h" 63*55139Storek 64*55139Storek #include "if_lereg.h" 65*55139Storek #include "sbusvar.h" 66*55139Storek 67*55139Storek /* DVMA address to LANCE address -- the Sbus/MMU will resupply the 0xff */ 68*55139Storek #define LANCE_ADDR(x) ((int)(x) & ~0xff000000) 69*55139Storek 70*55139Storek int ledebug = 0; /* console error messages */ 71*55139Storek 72*55139Storek #ifdef PACKETSTATS 73*55139Storek long lexpacketsizes[LEMTU+1]; 74*55139Storek long lerpacketsizes[LEMTU+1]; 75*55139Storek #endif 76*55139Storek 77*55139Storek /* Per interface statistics */ 78*55139Storek /* XXX this should go in something like if_levar.h */ 79*55139Storek struct lestats { 80*55139Storek long lexints; /* transmitter interrupts */ 81*55139Storek long lerints; /* receiver interrupts */ 82*55139Storek long lerbufs; /* total buffers received during interrupts */ 83*55139Storek long lerhits; /* times current rbuf was full */ 84*55139Storek long lerscans; /* rbufs scanned before finding first full */ 85*55139Storek }; 86*55139Storek 87*55139Storek /* 88*55139Storek * Ethernet software status per interface. 89*55139Storek * 90*55139Storek * Each interface is referenced by a network interface structure, 91*55139Storek * le_if, which the routing code uses to locate the interface. 92*55139Storek * This structure contains the output queue for the interface, its address, ... 93*55139Storek */ 94*55139Storek struct le_softc { 95*55139Storek struct device sc_dev; /* base device */ 96*55139Storek struct sbusdev sc_sd; /* sbus device */ 97*55139Storek struct intrhand sc_ih; /* interrupt vectoring */ 98*55139Storek int sc_interrupts; /* number of interrupts taken */ 99*55139Storek 100*55139Storek struct arpcom sc_ac; /* common Ethernet structures */ 101*55139Storek #define sc_if sc_ac.ac_if /* network-visible interface */ 102*55139Storek #define sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */ 103*55139Storek volatile struct lereg1 *sc_r1; /* LANCE registers */ 104*55139Storek volatile struct lereg2 *sc_r2; /* dual-port RAM */ 105*55139Storek int sc_rmd; /* predicted next rmd to process */ 106*55139Storek int sc_runt; 107*55139Storek int sc_jab; 108*55139Storek int sc_merr; 109*55139Storek int sc_babl; 110*55139Storek int sc_cerr; 111*55139Storek int sc_miss; 112*55139Storek int sc_xint; 113*55139Storek int sc_xown; 114*55139Storek int sc_uflo; 115*55139Storek int sc_rxlen; 116*55139Storek int sc_rxoff; 117*55139Storek int sc_txoff; 118*55139Storek int sc_busy; 119*55139Storek short sc_iflags; 120*55139Storek struct lestats sc_lestats; /* per interface statistics */ 121*55139Storek #if NBPFILTER > 0 122*55139Storek caddr_t sc_bpf; 123*55139Storek #endif 124*55139Storek }; 125*55139Storek 126*55139Storek 127*55139Storek /* autoconfiguration driver */ 128*55139Storek void leattach(struct device *, struct device *, void *); 129*55139Storek struct cfdriver lecd = 130*55139Storek { NULL, "le", matchbyname, leattach, DV_IFNET, sizeof(struct le_softc) }; 131*55139Storek 132*55139Storek /* Forwards */ 133*55139Storek void leattach(struct device *, struct device *, void *); 134*55139Storek #ifdef MULTICAST 135*55139Storek void lesetladrf(struct le_softc *); 136*55139Storek #endif 137*55139Storek void lereset(struct device *); 138*55139Storek int leinit(int); 139*55139Storek int lestart(struct ifnet *); 140*55139Storek int leintr(void *); 141*55139Storek void lexint(struct le_softc *); 142*55139Storek void lerint(struct le_softc *); 143*55139Storek void leread(struct le_softc *, char *, int); 144*55139Storek int leput(char *, struct mbuf *); 145*55139Storek struct mbuf *leget(char *, int, int, struct ifnet *); 146*55139Storek int leioctl(struct ifnet *, int, caddr_t); 147*55139Storek void leerror(struct le_softc *, int); 148*55139Storek void lererror(struct le_softc *, char *); 149*55139Storek void lexerror(struct le_softc *); 150*55139Storek 151*55139Storek /* 152*55139Storek * Interface exists: make available by filling in network interface 153*55139Storek * record. System will initialize the interface when it is ready 154*55139Storek * to accept packets. 155*55139Storek */ 156*55139Storek void 157*55139Storek leattach(parent, self, args) 158*55139Storek struct device *parent; 159*55139Storek struct device *self; 160*55139Storek void *args; 161*55139Storek { 162*55139Storek register struct le_softc *sc = (struct le_softc *)self; 163*55139Storek register struct sbus_attach_args *sa = args; 164*55139Storek register volatile struct lereg2 *ler2; 165*55139Storek struct ifnet *ifp = &sc->sc_if; 166*55139Storek register int a, pri; 167*55139Storek #define ISQUADALIGN(a) ((((long) a) & 0x3) == 0) 168*55139Storek 169*55139Storek /* XXX the following declarations should be elsewhere */ 170*55139Storek extern void myetheraddr(u_char *); 171*55139Storek extern caddr_t dvma_malloc(size_t); 172*55139Storek 173*55139Storek if (sa->sa_ra.ra_nintr != 1) { 174*55139Storek printf(": expected 1 interrupt, got %d\n", sa->sa_ra.ra_nintr); 175*55139Storek return; 176*55139Storek } 177*55139Storek pri = sa->sa_ra.ra_intr[0].int_pri; 178*55139Storek printf(" pri %d", pri); 179*55139Storek sc->sc_r1 = (volatile struct lereg1 *) 180*55139Storek mapiodev(sa->sa_ra.ra_paddr, sizeof(struct lereg1)); 181*55139Storek ler2 = sc->sc_r2 = (volatile struct lereg2 *) 182*55139Storek dvma_malloc(sizeof(struct lereg2)); 183*55139Storek if (!ISQUADALIGN(ler2)) 184*55139Storek printf("? not quad aligned (0x%x)\n", ler2); 185*55139Storek 186*55139Storek myetheraddr(sc->sc_addr); 187*55139Storek printf(": hardware address %s\n", ether_sprintf(sc->sc_addr)); 188*55139Storek 189*55139Storek /* 190*55139Storek * Setup for transmit/receive 191*55139Storek * 192*55139Storek * According to Van, some versions of the Lance only use this 193*55139Storek * address to receive packets; it doesn't put them in 194*55139Storek * output packets. We'll want to make sure that lestart() 195*55139Storek * installs the address. 196*55139Storek */ 197*55139Storek ler2->ler2_padr[0] = sc->sc_addr[1]; 198*55139Storek ler2->ler2_padr[1] = sc->sc_addr[0]; 199*55139Storek ler2->ler2_padr[2] = sc->sc_addr[3]; 200*55139Storek ler2->ler2_padr[3] = sc->sc_addr[2]; 201*55139Storek ler2->ler2_padr[4] = sc->sc_addr[5]; 202*55139Storek ler2->ler2_padr[5] = sc->sc_addr[4]; 203*55139Storek a = LANCE_ADDR(&ler2->ler2_rmd); 204*55139Storek if (!ISQUADALIGN(a)) 205*55139Storek printf("rdra not quad aligned (0x%x)\n", a); 206*55139Storek ler2->ler2_rlen = LE_RLEN | (a >> 16); 207*55139Storek ler2->ler2_rdra = a; 208*55139Storek a = LANCE_ADDR(&ler2->ler2_tmd); 209*55139Storek if (!ISQUADALIGN(a)) 210*55139Storek printf("tdra not quad aligned (0x%x)\n", a); 211*55139Storek ler2->ler2_tlen = LE_TLEN | (a >> 16); 212*55139Storek ler2->ler2_tdra = a; 213*55139Storek 214*55139Storek /* 215*55139Storek * Link into sbus, and establish interrupt handler. 216*55139Storek */ 217*55139Storek sc->sc_sd.sd_reset = lereset; 218*55139Storek sbus_establish(&sc->sc_sd, &sc->sc_dev); 219*55139Storek sc->sc_ih.ih_fun = leintr; 220*55139Storek sc->sc_ih.ih_arg = sc; 221*55139Storek intr_establish(pri, &sc->sc_ih); 222*55139Storek 223*55139Storek ifp->if_unit = sc->sc_dev.dv_unit; 224*55139Storek ifp->if_name = "le"; 225*55139Storek ifp->if_mtu = ETHERMTU; 226*55139Storek ifp->if_init = leinit; 227*55139Storek ifp->if_ioctl = leioctl; 228*55139Storek ifp->if_output = ether_output; 229*55139Storek ifp->if_start = lestart; 230*55139Storek #ifdef MULTICAST 231*55139Storek ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 232*55139Storek #else 233*55139Storek ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 234*55139Storek #endif 235*55139Storek #ifdef IFF_NOTRAILERS 236*55139Storek /* XXX still compile when the blasted things are gone... */ 237*55139Storek ifp->if_flags |= IFF_NOTRAILERS; 238*55139Storek #endif 239*55139Storek #if NBPFILTER > 0 240*55139Storek bpfattach(&sc->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 241*55139Storek #endif 242*55139Storek if_attach(ifp); 243*55139Storek } 244*55139Storek 245*55139Storek #ifdef MULTICAST 246*55139Storek /* 247*55139Storek * Setup the logical address filter 248*55139Storek */ 249*55139Storek void 250*55139Storek lesetladrf(sc) 251*55139Storek register struct le_softc *sc; 252*55139Storek { 253*55139Storek register volatile struct lereg2 *ler2 = sc->sc_r2; 254*55139Storek register struct ifnet *ifp = &sc->sc_if; 255*55139Storek register struct ether_multi *enm; 256*55139Storek register u_char *cp; 257*55139Storek register u_long crc; 258*55139Storek register u_long c; 259*55139Storek register int i, len; 260*55139Storek struct ether_multistep step; 261*55139Storek 262*55139Storek /* 263*55139Storek * Set up multicast address filter by passing all multicast 264*55139Storek * addresses through a crc generator, and then using the high 265*55139Storek * order 6 bits as a index into the 64 bit logical address 266*55139Storek * filter. The high order two bits select the word, while the 267*55139Storek * rest of the bits select the bit within the word. 268*55139Storek */ 269*55139Storek 270*55139Storek ler2->ler2_ladrf[0] = 0; 271*55139Storek ler2->ler2_ladrf[1] = 0; 272*55139Storek ifp->if_flags &= ~IFF_ALLMULTI; 273*55139Storek ETHER_FIRST_MULTI(step, &sc->sc_ac, enm); 274*55139Storek while (enm != NULL) { 275*55139Storek if (bcmp((caddr_t)&enm->enm_addrlo, 276*55139Storek (caddr_t)&enm->enm_addrhi, sizeof(enm->enm_addrlo)) == 0) { 277*55139Storek /* 278*55139Storek * We must listen to a range of multicast 279*55139Storek * addresses. For now, just accept all 280*55139Storek * multicasts, rather than trying to set only 281*55139Storek * those filter bits needed to match the range. 282*55139Storek * (At this time, the only use of address 283*55139Storek * ranges is for IP multicast routing, for 284*55139Storek * which the range is big enough to require all 285*55139Storek * bits set.) 286*55139Storek */ 287*55139Storek ler2->ler2_ladrf[0] = 0xffffffff; 288*55139Storek ler2->ler2_ladrf[1] = 0xffffffff; 289*55139Storek ifp->if_flags |= IFF_ALLMULTI; 290*55139Storek return; 291*55139Storek } 292*55139Storek 293*55139Storek cp = (unsigned char *)&enm->enm_addrlo; 294*55139Storek c = *cp; 295*55139Storek crc = 0xffffffff; 296*55139Storek len = 6; 297*55139Storek while (len-- > 0) { 298*55139Storek c = *cp; 299*55139Storek for (i = 0; i < 8; i++) { 300*55139Storek if ((c & 0x01) ^ (crc & 0x01)) { 301*55139Storek crc >>= 1; 302*55139Storek crc = crc ^ 0xedb88320; 303*55139Storek } 304*55139Storek else 305*55139Storek crc >>= 1; 306*55139Storek c >>= 1; 307*55139Storek } 308*55139Storek cp++; 309*55139Storek } 310*55139Storek /* Just want the 6 most significant bits. */ 311*55139Storek crc = crc >> 26; 312*55139Storek 313*55139Storek /* Turn on the corresponding bit in the filter. */ 314*55139Storek ler2->ler2_ladrf[crc >> 5] |= 1 << (crc & 0x1f); 315*55139Storek 316*55139Storek ETHER_NEXT_MULTI(step, enm); 317*55139Storek } 318*55139Storek } 319*55139Storek #endif 320*55139Storek 321*55139Storek void 322*55139Storek lereset(dev) 323*55139Storek struct device *dev; 324*55139Storek { 325*55139Storek register struct le_softc *sc = (struct le_softc *)dev; 326*55139Storek register volatile struct lereg1 *ler1 = sc->sc_r1; 327*55139Storek register volatile struct lereg2 *ler2 = sc->sc_r2; 328*55139Storek register int i, a, timo, stat; 329*55139Storek 330*55139Storek #if NBPFILTER > 0 331*55139Storek if (sc->sc_if.if_flags & IFF_PROMISC) 332*55139Storek ler2->ler2_mode = LE_MODE_NORMAL | LE_MODE_PROM; 333*55139Storek else 334*55139Storek #endif 335*55139Storek ler2->ler2_mode = LE_MODE_NORMAL; 336*55139Storek ler1->ler1_rap = LE_CSR0; 337*55139Storek ler1->ler1_rdp = LE_C0_STOP; 338*55139Storek 339*55139Storek /* Setup the logical address filter */ 340*55139Storek #ifdef MULTICAST 341*55139Storek lesetladrf(sc); 342*55139Storek #else 343*55139Storek ler2->ler2_ladrf[0] = 0; 344*55139Storek ler2->ler2_ladrf[1] = 0; 345*55139Storek #endif 346*55139Storek 347*55139Storek /* init receive and transmit rings */ 348*55139Storek a = LANCE_ADDR(&ler2->ler2_rbuf[0][0]); 349*55139Storek if (!ISQUADALIGN(a)) 350*55139Storek printf("rbuf not quad aligned (0x%x)\n", a); 351*55139Storek for (i = 0; i < LERBUF; i++) { 352*55139Storek a = LANCE_ADDR(&ler2->ler2_rbuf[i][0]); 353*55139Storek ler2->ler2_rmd[i].rmd0 = a; 354*55139Storek ler2->ler2_rmd[i].rmd1_hadr = a >> 16; 355*55139Storek ler2->ler2_rmd[i].rmd1_bits = LE_R1_OWN; 356*55139Storek ler2->ler2_rmd[i].rmd2 = -LEMTU; 357*55139Storek ler2->ler2_rmd[i].rmd3 = 0; 358*55139Storek } 359*55139Storek a = LANCE_ADDR(&ler2->ler2_tbuf[0][0]); 360*55139Storek if (!ISQUADALIGN(a)) 361*55139Storek printf("tbuf not quad aligned (0x%x)\n", a); 362*55139Storek for (i = 0; i < LETBUF; i++) { 363*55139Storek a = LANCE_ADDR(&ler2->ler2_tbuf[i][0]); 364*55139Storek ler2->ler2_tmd[i].tmd0 = a; 365*55139Storek ler2->ler2_tmd[i].tmd1_hadr = a >> 16; 366*55139Storek ler2->ler2_tmd[i].tmd1_bits = 0; 367*55139Storek ler2->ler2_tmd[i].tmd2 = 0; 368*55139Storek ler2->ler2_tmd[i].tmd3 = 0; 369*55139Storek } 370*55139Storek 371*55139Storek bzero(&ler2->ler2_rbuf[0][0], (LERBUF + LETBUF) * LEMTU); 372*55139Storek /* lance will stuff packet into receive buffer 0 next */ 373*55139Storek sc->sc_rmd = 0; 374*55139Storek 375*55139Storek /* tell the chip where to find the initialization block */ 376*55139Storek a = LANCE_ADDR(&ler2->ler2_mode); 377*55139Storek ler1->ler1_rap = LE_CSR1; 378*55139Storek ler1->ler1_rdp = a; 379*55139Storek ler1->ler1_rap = LE_CSR2; 380*55139Storek ler1->ler1_rdp = a >> 16; 381*55139Storek ler1->ler1_rap = LE_CSR3; 382*55139Storek ler1->ler1_rdp = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON; 383*55139Storek ler1->ler1_rap = LE_CSR0; 384*55139Storek ler1->ler1_rdp = LE_C0_INIT; 385*55139Storek timo = 100000; 386*55139Storek while (((stat = ler1->ler1_rdp) & (LE_C0_ERR | LE_C0_IDON)) == 0) { 387*55139Storek if (--timo == 0) { 388*55139Storek printf("%s: init timeout, stat=%b\n", 389*55139Storek sc->sc_dev.dv_xname, stat, LE_C0_BITS); 390*55139Storek break; 391*55139Storek } 392*55139Storek } 393*55139Storek if (stat & LE_C0_ERR) 394*55139Storek printf("%s: init failed, stat=%b\n", 395*55139Storek sc->sc_dev.dv_xname, stat, LE_C0_BITS); 396*55139Storek else 397*55139Storek ler1->ler1_rdp = LE_C0_IDON; /* clear IDON */ 398*55139Storek ler1->ler1_rdp = LE_C0_STRT | LE_C0_INEA; 399*55139Storek sc->sc_if.if_flags &= ~IFF_OACTIVE; 400*55139Storek } 401*55139Storek 402*55139Storek /* 403*55139Storek * Initialization of interface 404*55139Storek */ 405*55139Storek int 406*55139Storek leinit(unit) 407*55139Storek int unit; 408*55139Storek { 409*55139Storek register struct le_softc *sc = lecd.cd_devs[unit]; 410*55139Storek register struct ifnet *ifp = &sc->sc_if; 411*55139Storek register int s; 412*55139Storek 413*55139Storek /* not yet, if address still unknown */ 414*55139Storek if (ifp->if_addrlist == (struct ifaddr *)0) 415*55139Storek return (0); 416*55139Storek if ((ifp->if_flags & IFF_RUNNING) == 0) { 417*55139Storek s = splimp(); 418*55139Storek ifp->if_flags |= IFF_RUNNING; 419*55139Storek lereset((struct device *)sc); 420*55139Storek lestart(ifp); 421*55139Storek splx(s); 422*55139Storek } 423*55139Storek return (0); 424*55139Storek } 425*55139Storek 426*55139Storek /* 427*55139Storek * Start output on interface. Get another datagram to send 428*55139Storek * off of the interface queue, and copy it to the interface 429*55139Storek * before starting the output. 430*55139Storek */ 431*55139Storek int 432*55139Storek lestart(ifp) 433*55139Storek register struct ifnet *ifp; 434*55139Storek { 435*55139Storek register struct le_softc *sc = lecd.cd_devs[ifp->if_unit]; 436*55139Storek register volatile struct letmd *tmd; 437*55139Storek register struct mbuf *m; 438*55139Storek register int len; 439*55139Storek 440*55139Storek if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 441*55139Storek return (0); 442*55139Storek IF_DEQUEUE(&sc->sc_if.if_snd, m); 443*55139Storek if (m == 0) 444*55139Storek return (0); 445*55139Storek len = leput(sc->sc_r2->ler2_tbuf[0], m); 446*55139Storek #if NBPFILTER > 0 447*55139Storek /* 448*55139Storek * If bpf is listening on this interface, let it 449*55139Storek * see the packet before we commit it to the wire. 450*55139Storek */ 451*55139Storek if (sc->sc_bpf) 452*55139Storek bpf_tap(sc->sc_bpf, sc->sc_r2->ler2_tbuf[0], len); 453*55139Storek #endif 454*55139Storek 455*55139Storek #ifdef PACKETSTATS 456*55139Storek if (len <= LEMTU) 457*55139Storek lexpacketsizes[len]++; 458*55139Storek #endif 459*55139Storek tmd = sc->sc_r2->ler2_tmd; 460*55139Storek tmd->tmd3 = 0; 461*55139Storek tmd->tmd2 = -len; 462*55139Storek tmd->tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP; 463*55139Storek sc->sc_if.if_flags |= IFF_OACTIVE; 464*55139Storek return (0); 465*55139Storek } 466*55139Storek 467*55139Storek int 468*55139Storek leintr(dev) 469*55139Storek register void *dev; 470*55139Storek { 471*55139Storek register struct le_softc *sc = dev; 472*55139Storek register volatile struct lereg1 *ler1 = sc->sc_r1; 473*55139Storek register int csr0; 474*55139Storek 475*55139Storek csr0 = ler1->ler1_rdp; 476*55139Storek if ((csr0 & LE_C0_INTR) == 0) 477*55139Storek return (0); 478*55139Storek sc->sc_interrupts++; 479*55139Storek 480*55139Storek if (csr0 & LE_C0_ERR) { 481*55139Storek leerror(sc, csr0); 482*55139Storek if (csr0 & LE_C0_MERR) { 483*55139Storek sc->sc_merr++; 484*55139Storek lereset((struct device *)sc); 485*55139Storek return (1); 486*55139Storek } 487*55139Storek if (csr0 & LE_C0_BABL) 488*55139Storek sc->sc_babl++; 489*55139Storek if (csr0 & LE_C0_CERR) 490*55139Storek sc->sc_cerr++; 491*55139Storek if (csr0 & LE_C0_MISS) 492*55139Storek sc->sc_miss++; 493*55139Storek ler1->ler1_rdp = LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_INEA; 494*55139Storek } 495*55139Storek if ((csr0 & LE_C0_RXON) == 0) { 496*55139Storek sc->sc_rxoff++; 497*55139Storek lereset((struct device *)sc); 498*55139Storek return (1); 499*55139Storek } 500*55139Storek if ((csr0 & LE_C0_TXON) == 0) { 501*55139Storek sc->sc_txoff++; 502*55139Storek lereset((struct device *)sc); 503*55139Storek return (1); 504*55139Storek } 505*55139Storek if (csr0 & LE_C0_RINT) { 506*55139Storek /* interrupt is cleared in lerint */ 507*55139Storek lerint(sc); 508*55139Storek } 509*55139Storek if (csr0 & LE_C0_TINT) { 510*55139Storek ler1->ler1_rdp = LE_C0_TINT|LE_C0_INEA; 511*55139Storek lexint(sc); 512*55139Storek } 513*55139Storek return (1); 514*55139Storek } 515*55139Storek 516*55139Storek /* 517*55139Storek * Ethernet interface transmitter interrupt. 518*55139Storek * Start another output if more data to send. 519*55139Storek */ 520*55139Storek void 521*55139Storek lexint(sc) 522*55139Storek register struct le_softc *sc; 523*55139Storek { 524*55139Storek register volatile struct letmd *tmd = sc->sc_r2->ler2_tmd; 525*55139Storek 526*55139Storek sc->sc_lestats.lexints++; 527*55139Storek if ((sc->sc_if.if_flags & IFF_OACTIVE) == 0) { 528*55139Storek sc->sc_xint++; 529*55139Storek return; 530*55139Storek } 531*55139Storek if (tmd->tmd1_bits & LE_T1_OWN) { 532*55139Storek sc->sc_xown++; 533*55139Storek return; 534*55139Storek } 535*55139Storek if (tmd->tmd1_bits & LE_T1_ERR) { 536*55139Storek err: 537*55139Storek lexerror(sc); 538*55139Storek sc->sc_if.if_oerrors++; 539*55139Storek if (tmd->tmd3 & (LE_T3_BUFF|LE_T3_UFLO)) { 540*55139Storek sc->sc_uflo++; 541*55139Storek lereset((struct device *)sc); 542*55139Storek } else if (tmd->tmd3 & LE_T3_LCOL) 543*55139Storek sc->sc_if.if_collisions++; 544*55139Storek else if (tmd->tmd3 & LE_T3_RTRY) 545*55139Storek sc->sc_if.if_collisions += 16; 546*55139Storek } 547*55139Storek else if (tmd->tmd3 & LE_T3_BUFF) 548*55139Storek /* XXX documentation says BUFF not included in ERR */ 549*55139Storek goto err; 550*55139Storek else if (tmd->tmd1_bits & LE_T1_ONE) 551*55139Storek sc->sc_if.if_collisions++; 552*55139Storek else if (tmd->tmd1_bits & LE_T1_MORE) 553*55139Storek /* what is the real number? */ 554*55139Storek sc->sc_if.if_collisions += 2; 555*55139Storek else 556*55139Storek sc->sc_if.if_opackets++; 557*55139Storek sc->sc_if.if_flags &= ~IFF_OACTIVE; 558*55139Storek lestart(&sc->sc_if); 559*55139Storek } 560*55139Storek 561*55139Storek #define LENEXTRMP \ 562*55139Storek if (++bix == LERBUF) bix = 0, rmd = sc->sc_r2->ler2_rmd; else ++rmd 563*55139Storek 564*55139Storek /* 565*55139Storek * Ethernet interface receiver interrupt. 566*55139Storek * If input error just drop packet. 567*55139Storek * Decapsulate packet based on type and pass to type specific 568*55139Storek * higher-level input routine. 569*55139Storek */ 570*55139Storek void 571*55139Storek lerint(sc) 572*55139Storek register struct le_softc *sc; 573*55139Storek { 574*55139Storek register int bix = sc->sc_rmd; 575*55139Storek register volatile struct lermd *rmd = &sc->sc_r2->ler2_rmd[bix]; 576*55139Storek 577*55139Storek sc->sc_lestats.lerints++; 578*55139Storek /* 579*55139Storek * Out of sync with hardware, should never happen? 580*55139Storek */ 581*55139Storek if (rmd->rmd1_bits & LE_R1_OWN) { 582*55139Storek do { 583*55139Storek sc->sc_lestats.lerscans++; 584*55139Storek LENEXTRMP; 585*55139Storek } while ((rmd->rmd1_bits & LE_R1_OWN) && bix != sc->sc_rmd); 586*55139Storek if (bix == sc->sc_rmd) 587*55139Storek printf("%s: RINT with no buffer\n", 588*55139Storek sc->sc_dev.dv_xname); 589*55139Storek } else 590*55139Storek sc->sc_lestats.lerhits++; 591*55139Storek 592*55139Storek /* 593*55139Storek * Process all buffers with valid data 594*55139Storek */ 595*55139Storek while ((rmd->rmd1_bits & LE_R1_OWN) == 0) { 596*55139Storek int len = rmd->rmd3; 597*55139Storek 598*55139Storek /* Clear interrupt to avoid race condition */ 599*55139Storek sc->sc_r1->ler1_rdp = LE_C0_RINT|LE_C0_INEA; 600*55139Storek 601*55139Storek if (rmd->rmd1_bits & LE_R1_ERR) { 602*55139Storek sc->sc_rmd = bix; 603*55139Storek lererror(sc, "bad packet"); 604*55139Storek sc->sc_if.if_ierrors++; 605*55139Storek } else if ((rmd->rmd1_bits & (LE_R1_STP|LE_R1_ENP)) != 606*55139Storek (LE_R1_STP|LE_R1_ENP)) { 607*55139Storek /* XXX make a define for LE_R1_STP|LE_R1_ENP? */ 608*55139Storek /* 609*55139Storek * Find the end of the packet so we can see how long 610*55139Storek * it was. We still throw it away. 611*55139Storek */ 612*55139Storek do { 613*55139Storek sc->sc_r1->ler1_rdp = LE_C0_RINT|LE_C0_INEA; 614*55139Storek rmd->rmd3 = 0; 615*55139Storek rmd->rmd1_bits = LE_R1_OWN; 616*55139Storek LENEXTRMP; 617*55139Storek } while (!(rmd->rmd1_bits & 618*55139Storek (LE_R1_OWN|LE_R1_ERR|LE_R1_STP|LE_R1_ENP))); 619*55139Storek sc->sc_rmd = bix; 620*55139Storek lererror(sc, "chained buffer"); 621*55139Storek sc->sc_rxlen++; 622*55139Storek /* 623*55139Storek * If search terminated without successful completion 624*55139Storek * we reset the hardware (conservative). 625*55139Storek */ 626*55139Storek if ((rmd->rmd1_bits & 627*55139Storek (LE_R1_OWN|LE_R1_ERR|LE_R1_STP|LE_R1_ENP)) != 628*55139Storek LE_R1_ENP) { 629*55139Storek lereset((struct device *)sc); 630*55139Storek return; 631*55139Storek } 632*55139Storek } else { 633*55139Storek leread(sc, sc->sc_r2->ler2_rbuf[bix], len); 634*55139Storek #ifdef PACKETSTATS 635*55139Storek lerpacketsizes[len]++; 636*55139Storek #endif 637*55139Storek sc->sc_lestats.lerbufs++; 638*55139Storek } 639*55139Storek rmd->rmd3 = 0; 640*55139Storek rmd->rmd1_bits = LE_R1_OWN; 641*55139Storek LENEXTRMP; 642*55139Storek } 643*55139Storek sc->sc_rmd = bix; 644*55139Storek } 645*55139Storek 646*55139Storek void 647*55139Storek leread(sc, pkt, len) 648*55139Storek register struct le_softc *sc; 649*55139Storek char *pkt; 650*55139Storek int len; 651*55139Storek { 652*55139Storek register struct ether_header *et; 653*55139Storek register struct ifnet *ifp = &sc->sc_if; 654*55139Storek struct mbuf *m; 655*55139Storek struct ifqueue *inq; 656*55139Storek int flags; 657*55139Storek 658*55139Storek ifp->if_ipackets++; 659*55139Storek et = (struct ether_header *)pkt; 660*55139Storek et->ether_type = ntohs((u_short)et->ether_type); 661*55139Storek /* adjust input length to account for header and CRC */ 662*55139Storek len -= sizeof(struct ether_header) + 4; 663*55139Storek 664*55139Storek if (len <= 0) { 665*55139Storek if (ledebug) 666*55139Storek log(LOG_WARNING, 667*55139Storek "%s: ierror(runt packet): from %s: len=%d\n", 668*55139Storek sc->sc_dev.dv_xname, 669*55139Storek ether_sprintf(et->ether_shost), len); 670*55139Storek sc->sc_runt++; 671*55139Storek ifp->if_ierrors++; 672*55139Storek return; 673*55139Storek } 674*55139Storek 675*55139Storek /* Setup mbuf flags we'll need later */ 676*55139Storek flags = 0; 677*55139Storek if (bcmp((caddr_t)etherbroadcastaddr, 678*55139Storek (caddr_t)et->ether_dhost, sizeof(etherbroadcastaddr)) == 0) 679*55139Storek flags |= M_BCAST; 680*55139Storek if (et->ether_dhost[0] & 1) 681*55139Storek flags |= M_MCAST; 682*55139Storek 683*55139Storek #if NBPFILTER > 0 684*55139Storek /* 685*55139Storek * Check if there's a bpf filter listening on this interface. 686*55139Storek * If so, hand off the raw packet to enet. 687*55139Storek */ 688*55139Storek if (sc->sc_bpf) { 689*55139Storek bpf_tap(sc->sc_bpf, pkt, len + sizeof(struct ether_header)); 690*55139Storek 691*55139Storek /* 692*55139Storek * Keep the packet if it's a broadcast or has our 693*55139Storek * physical ethernet address (or if we support 694*55139Storek * multicast and it's one). 695*55139Storek */ 696*55139Storek if ( 697*55139Storek #ifdef MULTICAST 698*55139Storek (flags & (M_BCAST | M_MCAST)) == 0 && 699*55139Storek #else 700*55139Storek (flags & M_BCAST) == 0 && 701*55139Storek #endif 702*55139Storek bcmp(et->ether_dhost, sc->sc_addr, 703*55139Storek sizeof(et->ether_dhost)) != 0) 704*55139Storek return; 705*55139Storek } 706*55139Storek #endif 707*55139Storek m = leget(pkt, len, 0, ifp); 708*55139Storek if (m == 0) 709*55139Storek return; 710*55139Storek 711*55139Storek /* XXX this code comes from ether_input() */ 712*55139Storek ifp->if_lastchange = time; 713*55139Storek ifp->if_ibytes += m->m_pkthdr.len + sizeof (*et); 714*55139Storek if (flags) { 715*55139Storek m->m_flags |= flags; 716*55139Storek ifp->if_imcasts++; 717*55139Storek } 718*55139Storek /* XXX end of code from ether_input() */ 719*55139Storek 720*55139Storek switch (et->ether_type) { 721*55139Storek 722*55139Storek #ifdef INET 723*55139Storek case ETHERTYPE_IP: 724*55139Storek schednetisr(NETISR_IP); 725*55139Storek inq = &ipintrq; 726*55139Storek break; 727*55139Storek 728*55139Storek case ETHERTYPE_ARP: 729*55139Storek schednetisr(NETISR_ARP); 730*55139Storek inq = &arpintrq; 731*55139Storek break; 732*55139Storek #endif 733*55139Storek #ifdef NS 734*55139Storek case ETHERTYPE_NS: 735*55139Storek schednetisr(NETISR_NS); 736*55139Storek inq = &nsintrq; 737*55139Storek break; 738*55139Storek #endif 739*55139Storek 740*55139Storek #ifdef UTAHONLY 741*55139Storek #ifdef APPLETALK 742*55139Storek case ETHERTYPE_APPLETALK: 743*55139Storek schednetisr(NETISR_DDP); 744*55139Storek inq = &ddpintq; 745*55139Storek break; 746*55139Storek 747*55139Storek case ETHERTYPE_AARP: 748*55139Storek aarpinput(&sc->sc_ac, m); 749*55139Storek return; 750*55139Storek #endif 751*55139Storek #endif 752*55139Storek default: 753*55139Storek m_freem(m); 754*55139Storek return; 755*55139Storek } 756*55139Storek 757*55139Storek if (IF_QFULL(inq)) { 758*55139Storek IF_DROP(inq); 759*55139Storek m_freem(m); 760*55139Storek return; 761*55139Storek } 762*55139Storek IF_ENQUEUE(inq, m); 763*55139Storek } 764*55139Storek 765*55139Storek /* 766*55139Storek * Routine to copy from mbuf chain to transmit 767*55139Storek * buffer in board local memory. 768*55139Storek * 769*55139Storek * ### this can be done by remapping in some cases 770*55139Storek */ 771*55139Storek int 772*55139Storek leput(lebuf, m) 773*55139Storek register char *lebuf; 774*55139Storek register struct mbuf *m; 775*55139Storek { 776*55139Storek register struct mbuf *mp; 777*55139Storek register int len, tlen = 0; 778*55139Storek 779*55139Storek for (mp = m; mp; mp = mp->m_next) { 780*55139Storek len = mp->m_len; 781*55139Storek if (len == 0) 782*55139Storek continue; 783*55139Storek tlen += len; 784*55139Storek bcopy(mtod(mp, char *), lebuf, len); 785*55139Storek lebuf += len; 786*55139Storek } 787*55139Storek m_freem(m); 788*55139Storek if (tlen < LEMINSIZE) { 789*55139Storek bzero(lebuf, LEMINSIZE - tlen); 790*55139Storek tlen = LEMINSIZE; 791*55139Storek } 792*55139Storek return (tlen); 793*55139Storek } 794*55139Storek 795*55139Storek /* 796*55139Storek * Routine to copy from board local memory into mbufs. 797*55139Storek */ 798*55139Storek struct mbuf * 799*55139Storek leget(lebuf, totlen, off0, ifp) 800*55139Storek char *lebuf; 801*55139Storek int totlen, off0; 802*55139Storek struct ifnet *ifp; 803*55139Storek { 804*55139Storek register struct mbuf *m; 805*55139Storek struct mbuf *top = 0, **mp = ⊤ 806*55139Storek register int off = off0, len; 807*55139Storek register char *cp; 808*55139Storek char *epkt; 809*55139Storek 810*55139Storek lebuf += sizeof(struct ether_header); 811*55139Storek cp = lebuf; 812*55139Storek epkt = cp + totlen; 813*55139Storek if (off) { 814*55139Storek cp += off + 2 * sizeof(u_short); 815*55139Storek totlen -= 2 * sizeof(u_short); 816*55139Storek } 817*55139Storek 818*55139Storek MGETHDR(m, M_DONTWAIT, MT_DATA); 819*55139Storek if (m == 0) 820*55139Storek return (0); 821*55139Storek m->m_pkthdr.rcvif = ifp; 822*55139Storek m->m_pkthdr.len = totlen; 823*55139Storek m->m_len = MHLEN; 824*55139Storek 825*55139Storek while (totlen > 0) { 826*55139Storek if (top) { 827*55139Storek MGET(m, M_DONTWAIT, MT_DATA); 828*55139Storek if (m == 0) { 829*55139Storek m_freem(top); 830*55139Storek return (0); 831*55139Storek } 832*55139Storek m->m_len = MLEN; 833*55139Storek } 834*55139Storek len = min(totlen, epkt - cp); 835*55139Storek if (len >= MINCLSIZE) { 836*55139Storek MCLGET(m, M_DONTWAIT); 837*55139Storek if (m->m_flags & M_EXT) 838*55139Storek m->m_len = len = min(len, MCLBYTES); 839*55139Storek else 840*55139Storek len = m->m_len; 841*55139Storek } else { 842*55139Storek /* 843*55139Storek * Place initial small packet/header at end of mbuf. 844*55139Storek */ 845*55139Storek if (len < m->m_len) { 846*55139Storek if (top == 0 && len + max_linkhdr <= m->m_len) 847*55139Storek m->m_data += max_linkhdr; 848*55139Storek m->m_len = len; 849*55139Storek } else 850*55139Storek len = m->m_len; 851*55139Storek } 852*55139Storek bcopy(cp, mtod(m, caddr_t), (unsigned)len); 853*55139Storek cp += len; 854*55139Storek *mp = m; 855*55139Storek mp = &m->m_next; 856*55139Storek totlen -= len; 857*55139Storek if (cp == epkt) 858*55139Storek cp = lebuf; 859*55139Storek } 860*55139Storek return (top); 861*55139Storek } 862*55139Storek 863*55139Storek /* 864*55139Storek * Process an ioctl request. 865*55139Storek */ 866*55139Storek int 867*55139Storek leioctl(ifp, cmd, data) 868*55139Storek register struct ifnet *ifp; 869*55139Storek int cmd; 870*55139Storek caddr_t data; 871*55139Storek { 872*55139Storek register struct ifaddr *ifa; 873*55139Storek register struct le_softc *sc = lecd.cd_devs[ifp->if_unit]; 874*55139Storek register volatile struct lereg1 *ler1; 875*55139Storek int s = splimp(), error = 0; 876*55139Storek 877*55139Storek switch (cmd) { 878*55139Storek 879*55139Storek case SIOCSIFADDR: 880*55139Storek ifa = (struct ifaddr *)data; 881*55139Storek ifp->if_flags |= IFF_UP; 882*55139Storek switch (ifa->ifa_addr->sa_family) { 883*55139Storek #ifdef INET 884*55139Storek case AF_INET: 885*55139Storek (void)leinit(ifp->if_unit); /* before arpwhohas */ 886*55139Storek ((struct arpcom *)ifp)->ac_ipaddr = 887*55139Storek IA_SIN(ifa)->sin_addr; 888*55139Storek arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 889*55139Storek break; 890*55139Storek #endif 891*55139Storek #ifdef NS 892*55139Storek case AF_NS: 893*55139Storek { 894*55139Storek register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 895*55139Storek 896*55139Storek if (ns_nullhost(*ina)) 897*55139Storek ina->x_host = *(union ns_host *)(sc->sc_addr); 898*55139Storek else { 899*55139Storek /* 900*55139Storek * The manual says we can't change the address 901*55139Storek * while the receiver is armed, 902*55139Storek * so reset everything 903*55139Storek */ 904*55139Storek ifp->if_flags &= ~IFF_RUNNING; 905*55139Storek bcopy((caddr_t)ina->x_host.c_host, 906*55139Storek (caddr_t)sc->sc_addr, sizeof(sc->sc_addr)); 907*55139Storek } 908*55139Storek (void)leinit(ifp->if_unit); /* does le_setaddr() */ 909*55139Storek break; 910*55139Storek } 911*55139Storek #endif 912*55139Storek default: 913*55139Storek (void)leinit(ifp->if_unit); 914*55139Storek break; 915*55139Storek } 916*55139Storek break; 917*55139Storek 918*55139Storek case SIOCSIFFLAGS: 919*55139Storek ler1 = sc->sc_r1; 920*55139Storek if ((ifp->if_flags & IFF_UP) == 0 && 921*55139Storek ifp->if_flags & IFF_RUNNING) { 922*55139Storek ler1->ler1_rdp = LE_C0_STOP; 923*55139Storek ifp->if_flags &= ~IFF_RUNNING; 924*55139Storek } else if (ifp->if_flags & IFF_UP && 925*55139Storek (ifp->if_flags & IFF_RUNNING) == 0) 926*55139Storek (void)leinit(ifp->if_unit); 927*55139Storek /* 928*55139Storek * If the state of the promiscuous bit changes, the interface 929*55139Storek * must be reset to effect the change. 930*55139Storek */ 931*55139Storek if (((ifp->if_flags ^ sc->sc_iflags) & IFF_PROMISC) && 932*55139Storek (ifp->if_flags & IFF_RUNNING)) { 933*55139Storek sc->sc_iflags = ifp->if_flags; 934*55139Storek lereset((struct device *)sc); 935*55139Storek lestart(ifp); 936*55139Storek } 937*55139Storek break; 938*55139Storek 939*55139Storek #ifdef MULTICAST 940*55139Storek case SIOCADDMULTI: 941*55139Storek case SIOCDELMULTI: 942*55139Storek /* Update our multicast list */ 943*55139Storek error = (cmd == SIOCADDMULTI) ? 944*55139Storek ether_addmulti((struct ifreq *)data, &sc->sc_ac) : 945*55139Storek ether_delmulti((struct ifreq *)data, &sc->sc_ac); 946*55139Storek 947*55139Storek if (error == ENETRESET) { 948*55139Storek /* 949*55139Storek * Multicast list has changed; set the hardware 950*55139Storek * filter accordingly. 951*55139Storek */ 952*55139Storek lereset((struct device *)sc); 953*55139Storek error = 0; 954*55139Storek } 955*55139Storek break; 956*55139Storek #endif 957*55139Storek 958*55139Storek default: 959*55139Storek error = EINVAL; 960*55139Storek } 961*55139Storek splx(s); 962*55139Storek return (error); 963*55139Storek } 964*55139Storek 965*55139Storek void 966*55139Storek leerror(sc, stat) 967*55139Storek register struct le_softc *sc; 968*55139Storek int stat; 969*55139Storek { 970*55139Storek if (!ledebug) 971*55139Storek return; 972*55139Storek 973*55139Storek /* 974*55139Storek * Not all transceivers implement heartbeat 975*55139Storek * so we only log CERR once. 976*55139Storek */ 977*55139Storek if ((stat & LE_C0_CERR) && sc->sc_cerr) 978*55139Storek return; 979*55139Storek log(LOG_WARNING, "%s: error: stat=%b\n", 980*55139Storek sc->sc_dev.dv_xname, stat, LE_C0_BITS); 981*55139Storek } 982*55139Storek 983*55139Storek void 984*55139Storek lererror(sc, msg) 985*55139Storek register struct le_softc *sc; 986*55139Storek char *msg; 987*55139Storek { 988*55139Storek register volatile struct lermd *rmd; 989*55139Storek int len; 990*55139Storek 991*55139Storek if (!ledebug) 992*55139Storek return; 993*55139Storek 994*55139Storek rmd = &sc->sc_r2->ler2_rmd[sc->sc_rmd]; 995*55139Storek len = rmd->rmd3; 996*55139Storek log(LOG_WARNING, "%s: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n", 997*55139Storek sc->sc_dev.dv_xname, msg, len > 11 ? 998*55139Storek ether_sprintf((u_char *)&sc->sc_r2->ler2_rbuf[sc->sc_rmd][6]) : 999*55139Storek "unknown", 1000*55139Storek sc->sc_rmd, len, rmd->rmd1_bits, LE_R1_BITS); 1001*55139Storek } 1002*55139Storek 1003*55139Storek void 1004*55139Storek lexerror(sc) 1005*55139Storek register struct le_softc *sc; 1006*55139Storek { 1007*55139Storek register volatile struct letmd *tmd; 1008*55139Storek register int len, tmd3, tdr; 1009*55139Storek 1010*55139Storek if (!ledebug) 1011*55139Storek return; 1012*55139Storek 1013*55139Storek tmd = sc->sc_r2->ler2_tmd; 1014*55139Storek tmd3 = tmd->tmd3; 1015*55139Storek tdr = tmd3 & LE_T3_TDR_MASK; 1016*55139Storek len = -tmd->tmd2; 1017*55139Storek log(LOG_WARNING, 1018*55139Storek "%s: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b, tdr=%d (%d nsecs)\n", 1019*55139Storek sc->sc_dev.dv_xname, len > 5 ? 1020*55139Storek ether_sprintf((u_char *)&sc->sc_r2->ler2_tbuf[0][0]) : "unknown", 1021*55139Storek 0, len, 1022*55139Storek tmd->tmd1_bits, LE_T1_BITS, 1023*55139Storek tmd3, LE_T3_BITS, tdr, tdr * 100); 1024*55139Storek } 1025