1*54000Sfujita /* 2*54000Sfujita * Copyright (c) 1982, 1990, 1992 The Regents of the University of California. 3*54000Sfujita * All rights reserved. 4*54000Sfujita * 5*54000Sfujita * %sccs.include.redist.c% 6*54000Sfujita * 7*54000Sfujita * @(#)if_le.c 7.1 (Berkeley) 06/15/92 8*54000Sfujita */ 9*54000Sfujita 10*54000Sfujita #include "le.h" 11*54000Sfujita #if NLE > 0 12*54000Sfujita 13*54000Sfujita #include "bpfilter.h" 14*54000Sfujita 15*54000Sfujita /* 16*54000Sfujita * AMD 7990 LANCE 17*54000Sfujita * 18*54000Sfujita * This driver will generate and accept tailer encapsulated packets even 19*54000Sfujita * though it buys us nothing. The motivation was to avoid incompatibilities 20*54000Sfujita * with VAXen, SUNs, and others that handle and benefit from them. 21*54000Sfujita * This reasoning is dubious. 22*54000Sfujita */ 23*54000Sfujita #include "sys/param.h" 24*54000Sfujita #include "sys/proc.h" 25*54000Sfujita #include "sys/systm.h" 26*54000Sfujita #include "sys/mbuf.h" 27*54000Sfujita #include "sys/buf.h" 28*54000Sfujita #include "sys/protosw.h" 29*54000Sfujita #include "sys/socket.h" 30*54000Sfujita #include "sys/syslog.h" 31*54000Sfujita #include "sys/ioctl.h" 32*54000Sfujita #include "sys/errno.h" 33*54000Sfujita 34*54000Sfujita #include "net/if.h" 35*54000Sfujita #include "net/netisr.h" 36*54000Sfujita #include "net/route.h" 37*54000Sfujita 38*54000Sfujita #ifdef INET 39*54000Sfujita #include "netinet/in.h" 40*54000Sfujita #include "netinet/in_systm.h" 41*54000Sfujita #include "netinet/in_var.h" 42*54000Sfujita #include "netinet/ip.h" 43*54000Sfujita #include "netinet/if_ether.h" 44*54000Sfujita #endif 45*54000Sfujita 46*54000Sfujita #ifdef NS 47*54000Sfujita #include "netns/ns.h" 48*54000Sfujita #include "netns/ns_if.h" 49*54000Sfujita #endif 50*54000Sfujita 51*54000Sfujita #ifdef ISO 52*54000Sfujita extern char all_es_snpa[], all_is_snpa[], all_l1is_snpa[], all_l2is_snpa[]; 53*54000Sfujita #endif 54*54000Sfujita 55*54000Sfujita #include "../include/cpu.h" 56*54000Sfujita #include "../include/mtpr.h" 57*54000Sfujita #include "device.h" 58*54000Sfujita #include "if_lereg.h" 59*54000Sfujita 60*54000Sfujita #if NBPFILTER > 0 61*54000Sfujita #include "../net/bpf.h" 62*54000Sfujita #include "../net/bpfdesc.h" 63*54000Sfujita char hprmp_multi[] = { 9, 0, 9, 0, 0, 4}; 64*54000Sfujita #endif 65*54000Sfujita 66*54000Sfujita 67*54000Sfujita int leattach(); 68*54000Sfujita struct driver ledriver = { 69*54000Sfujita leattach, "le", 70*54000Sfujita }; 71*54000Sfujita 72*54000Sfujita int ledebug = 0; /* console error messages */ 73*54000Sfujita 74*54000Sfujita int leintr(), leinit(), leioctl(), lestart(), ether_output(); 75*54000Sfujita struct mbuf *m_devget(); 76*54000Sfujita extern struct ifnet loif; 77*54000Sfujita 78*54000Sfujita /* 79*54000Sfujita * Ethernet software status per interface. 80*54000Sfujita * 81*54000Sfujita * Each interface is referenced by a network interface structure, 82*54000Sfujita * le_if, which the routing code uses to locate the interface. 83*54000Sfujita * This structure contains the output queue for the interface, its address, ... 84*54000Sfujita */ 85*54000Sfujita struct le_softc { 86*54000Sfujita struct arpcom sc_ac; /* common Ethernet structures */ 87*54000Sfujita #define sc_if sc_ac.ac_if /* network-visible interface */ 88*54000Sfujita #define sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */ 89*54000Sfujita struct lereg1 *sc_r1; /* LANCE registers */ 90*54000Sfujita struct lereg2 *sc_r2; /* dual-port RAM */ 91*54000Sfujita int sc_rmd; /* predicted next rmd to process */ 92*54000Sfujita int sc_runt; 93*54000Sfujita int sc_jab; 94*54000Sfujita int sc_merr; 95*54000Sfujita int sc_babl; 96*54000Sfujita int sc_cerr; 97*54000Sfujita int sc_miss; 98*54000Sfujita int sc_xint; 99*54000Sfujita int sc_xown; 100*54000Sfujita int sc_uflo; 101*54000Sfujita int sc_rxlen; 102*54000Sfujita int sc_rxoff; 103*54000Sfujita int sc_txoff; 104*54000Sfujita int sc_busy; 105*54000Sfujita short sc_iflags; 106*54000Sfujita caddr_t sc_bpf; 107*54000Sfujita int sc_tmd; /* predicted next tmd to process */ 108*54000Sfujita int sc_txcnt; /* transmissions in progress */ 109*54000Sfujita int sc_txbad; 110*54000Sfujita int sc_txbusy; 111*54000Sfujita } le_softc[NLE]; 112*54000Sfujita 113*54000Sfujita /* access LANCE registers */ 114*54000Sfujita #define LERDWR(cntl, src, dst) (dst) = (src) 115*54000Sfujita 116*54000Sfujita #define LE_IPL 3 117*54000Sfujita 118*54000Sfujita /* 119*54000Sfujita * Interface exists: make available by filling in network interface 120*54000Sfujita * record. System will initialize the interface when it is ready 121*54000Sfujita * to accept packets. 122*54000Sfujita */ 123*54000Sfujita leattach(hd) 124*54000Sfujita struct hp_device *hd; 125*54000Sfujita { 126*54000Sfujita register struct lereg2 *ler2; 127*54000Sfujita struct lereg2 *lemem = (struct lereg2 *) 0; 128*54000Sfujita struct le_softc *le = &le_softc[hd->hp_unit]; 129*54000Sfujita struct ifnet *ifp = &le->sc_if; 130*54000Sfujita char *cp; 131*54000Sfujita int i; 132*54000Sfujita 133*54000Sfujita le->sc_r1 = (struct lereg1 *) hd->hp_addr; 134*54000Sfujita ler2 = le->sc_r2 = (struct lereg2 *) 0x71000000; 135*54000Sfujita 136*54000Sfujita hd->hp_ipl = LE_IPL; 137*54000Sfujita 138*54000Sfujita /* 139*54000Sfujita * Read the ethernet address off the board, one nibble at a time. 140*54000Sfujita */ 141*54000Sfujita #ifdef NOROM 142*54000Sfujita cp = "00000a02456c"; 143*54000Sfujita #else 144*54000Sfujita cp = (char *) 0x4101FFE0; 145*54000Sfujita #endif 146*54000Sfujita for (i = 0; i < sizeof(le->sc_addr); i++) { 147*54000Sfujita le->sc_addr[i] = (*cp < 'A' ? (*cp & 0xF) : (*cp & 0xF) + 9) << 4; 148*54000Sfujita cp++; 149*54000Sfujita le->sc_addr[i] |= (*cp < 'A' ? (*cp & 0xF) : (*cp & 0xF) + 9); 150*54000Sfujita cp++; 151*54000Sfujita } 152*54000Sfujita printf("le%d: hardware address %s\n", hd->hp_unit, 153*54000Sfujita ether_sprintf(le->sc_addr)); 154*54000Sfujita 155*54000Sfujita /* 156*54000Sfujita * Setup for transmit/receive 157*54000Sfujita */ 158*54000Sfujita ler2->ler2_mode = LE_MODE; 159*54000Sfujita #if defined(ISO) || NBPFILTER > 0 160*54000Sfujita ler2->ler2_ladrf0 = 0xffffffff; 161*54000Sfujita ler2->ler2_ladrf1 = 0xffffffff; 162*54000Sfujita #else 163*54000Sfujita ler2->ler2_ladrf0 = 0; 164*54000Sfujita ler2->ler2_ladrf1 = 0; 165*54000Sfujita #endif 166*54000Sfujita ler2->ler2_rlen = LE_RLEN; 167*54000Sfujita ler2->ler2_rdra = (int)lemem->ler2_rmd; 168*54000Sfujita ler2->ler2_tlen = LE_TLEN; 169*54000Sfujita ler2->ler2_tdra = (int)lemem->ler2_tmd; 170*54000Sfujita 171*54000Sfujita ifp->if_unit = hd->hp_unit; 172*54000Sfujita ifp->if_name = "le"; 173*54000Sfujita ifp->if_mtu = ETHERMTU; 174*54000Sfujita ifp->if_init = leinit; 175*54000Sfujita ifp->if_ioctl = leioctl; 176*54000Sfujita ifp->if_output = ether_output; 177*54000Sfujita ifp->if_start = lestart; 178*54000Sfujita ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 179*54000Sfujita #if NBPFILTER > 0 180*54000Sfujita bpfattach(&le->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 181*54000Sfujita #endif 182*54000Sfujita if_attach(ifp); 183*54000Sfujita return (1); 184*54000Sfujita } 185*54000Sfujita 186*54000Sfujita ledrinit(ler2, le) 187*54000Sfujita register struct lereg2 *ler2; 188*54000Sfujita register struct le_softc *le; 189*54000Sfujita { 190*54000Sfujita register struct lereg2 *lemem = (struct lereg2 *) 0; 191*54000Sfujita register int i; 192*54000Sfujita 193*54000Sfujita ler2->ler2_padr[0] = le->sc_addr[1]; 194*54000Sfujita ler2->ler2_padr[1] = le->sc_addr[0]; 195*54000Sfujita ler2->ler2_padr[2] = le->sc_addr[3]; 196*54000Sfujita ler2->ler2_padr[3] = le->sc_addr[2]; 197*54000Sfujita ler2->ler2_padr[4] = le->sc_addr[5]; 198*54000Sfujita ler2->ler2_padr[5] = le->sc_addr[4]; 199*54000Sfujita for (i = 0; i < LERBUF; i++) { 200*54000Sfujita ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i]; 201*54000Sfujita ler2->ler2_rmd[i].rmd1 = LE_OWN; 202*54000Sfujita ler2->ler2_rmd[i].rmd2 = -LEMTU; 203*54000Sfujita ler2->ler2_rmd[i].rmd3 = 0; 204*54000Sfujita } 205*54000Sfujita for (i = 0; i < LETBUF; i++) { 206*54000Sfujita ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i]; 207*54000Sfujita ler2->ler2_tmd[i].tmd1 = 0; 208*54000Sfujita ler2->ler2_tmd[i].tmd2 = 0; 209*54000Sfujita ler2->ler2_tmd[i].tmd3 = 0; 210*54000Sfujita } 211*54000Sfujita } 212*54000Sfujita 213*54000Sfujita lereset(unit) 214*54000Sfujita register int unit; 215*54000Sfujita { 216*54000Sfujita register struct le_softc *le = &le_softc[unit]; 217*54000Sfujita register struct lereg1 *ler1 = le->sc_r1; 218*54000Sfujita register struct lereg2 *lemem = (struct lereg2 *) 0; 219*54000Sfujita register int timo = 100000; 220*54000Sfujita register int stat; 221*54000Sfujita 222*54000Sfujita #ifdef lint 223*54000Sfujita stat = unit; 224*54000Sfujita #endif 225*54000Sfujita #if NBPFILTER > 0 226*54000Sfujita if (le->sc_if.if_flags & IFF_PROMISC) 227*54000Sfujita /* set the promiscuous bit */ 228*54000Sfujita le->sc_r2->ler2_mode = LE_MODE|0x8000; 229*54000Sfujita else 230*54000Sfujita le->sc_r2->ler2_mode = LE_MODE; 231*54000Sfujita #endif 232*54000Sfujita LERDWR(ler0, LE_CSR0, ler1->ler1_rap); 233*54000Sfujita LERDWR(ler0, LE_STOP, ler1->ler1_rdp); 234*54000Sfujita ledrinit(le->sc_r2, le); 235*54000Sfujita le->sc_txcnt = le->sc_tmd = le->sc_rmd = 0; 236*54000Sfujita LERDWR(ler0, LE_CSR1, ler1->ler1_rap); 237*54000Sfujita LERDWR(ler0, (int)&lemem->ler2_mode, ler1->ler1_rdp); 238*54000Sfujita LERDWR(ler0, LE_CSR2, ler1->ler1_rap); 239*54000Sfujita LERDWR(ler0, 0, ler1->ler1_rdp); 240*54000Sfujita LERDWR(ler0, LE_CSR0, ler1->ler1_rap); 241*54000Sfujita LERDWR(ler0, LE_INIT, ler1->ler1_rdp); 242*54000Sfujita do { 243*54000Sfujita if (--timo == 0) { 244*54000Sfujita printf("le%d: init timeout, stat = 0x%x\n", 245*54000Sfujita unit, stat); 246*54000Sfujita break; 247*54000Sfujita } 248*54000Sfujita LERDWR(ler0, ler1->ler1_rdp, stat); 249*54000Sfujita } while ((stat & LE_IDON) == 0); 250*54000Sfujita LERDWR(ler0, LE_STOP, ler1->ler1_rdp); 251*54000Sfujita LERDWR(ler0, LE_CSR3, ler1->ler1_rap); 252*54000Sfujita LERDWR(ler0, LE_BSWP, ler1->ler1_rdp); 253*54000Sfujita LERDWR(ler0, LE_CSR0, ler1->ler1_rap); 254*54000Sfujita LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp); 255*54000Sfujita le->sc_if.if_flags &= ~IFF_OACTIVE; 256*54000Sfujita } 257*54000Sfujita 258*54000Sfujita /* 259*54000Sfujita * Initialization of interface 260*54000Sfujita */ 261*54000Sfujita leinit(unit) 262*54000Sfujita int unit; 263*54000Sfujita { 264*54000Sfujita register struct ifnet *ifp = &le_softc[unit].sc_if; 265*54000Sfujita register struct ifaddr *ifa; 266*54000Sfujita int s; 267*54000Sfujita 268*54000Sfujita /* not yet, if address still unknown */ 269*54000Sfujita for (ifa = ifp->if_addrlist;; ifa = ifa->ifa_next) 270*54000Sfujita if (ifa == 0) 271*54000Sfujita return; 272*54000Sfujita else if (ifa->ifa_addr && ifa->ifa_addr->sa_family != AF_LINK) 273*54000Sfujita break; 274*54000Sfujita if ((ifp->if_flags & IFF_RUNNING) == 0) { 275*54000Sfujita s = splimp(); 276*54000Sfujita ifp->if_flags |= IFF_RUNNING; 277*54000Sfujita lereset(unit); 278*54000Sfujita (void) lestart(ifp); 279*54000Sfujita splx(s); 280*54000Sfujita } 281*54000Sfujita } 282*54000Sfujita 283*54000Sfujita /* 284*54000Sfujita * Start output on interface. Get another datagram to send 285*54000Sfujita * off of the interface queue, and copy it to the interface 286*54000Sfujita * before starting the output. 287*54000Sfujita */ 288*54000Sfujita lestart(ifp) 289*54000Sfujita struct ifnet *ifp; 290*54000Sfujita { 291*54000Sfujita register struct le_softc *le = &le_softc[ifp->if_unit]; 292*54000Sfujita register struct letmd *tmd; 293*54000Sfujita register struct mbuf *m; 294*54000Sfujita int len; 295*54000Sfujita 296*54000Sfujita again: 297*54000Sfujita if ((le->sc_if.if_flags & IFF_RUNNING) == 0) 298*54000Sfujita return (0); 299*54000Sfujita IF_DEQUEUE(&le->sc_if.if_snd, m); 300*54000Sfujita if (m == 0) 301*54000Sfujita return (0); 302*54000Sfujita tmd = le->sc_r2->ler2_tmd + le->sc_tmd; 303*54000Sfujita if (tmd->tmd1 & LE_OWN) 304*54000Sfujita return (le->sc_txbusy++, 0); 305*54000Sfujita len = leput(le->sc_r2->ler2_tbuf[le->sc_tmd], m); 306*54000Sfujita #if NBPFILTER > 0 307*54000Sfujita /* 308*54000Sfujita * If bpf is listening on this interface, let it 309*54000Sfujita * see the packet before we commit it to the wire. 310*54000Sfujita */ 311*54000Sfujita if (le->sc_bpf) 312*54000Sfujita bpf_tap(le->sc_bpf, le->sc_r2->ler2_tbuf[le->sc_tmd], len); 313*54000Sfujita #endif 314*54000Sfujita tmd->tmd3 = 0; 315*54000Sfujita tmd->tmd2 = -len; 316*54000Sfujita if (++le->sc_tmd >= LETBUF) 317*54000Sfujita le->sc_tmd = 0; 318*54000Sfujita if (++le->sc_txcnt >= LETBUF) { 319*54000Sfujita le->sc_txcnt = LETBUF; 320*54000Sfujita le->sc_if.if_flags |= IFF_OACTIVE; 321*54000Sfujita tmd->tmd1 = LE_OWN | LE_STP | LE_ENP; 322*54000Sfujita } else { 323*54000Sfujita tmd->tmd1 = LE_OWN | LE_STP | LE_ENP; 324*54000Sfujita goto again; 325*54000Sfujita } 326*54000Sfujita return (0); 327*54000Sfujita } 328*54000Sfujita 329*54000Sfujita void 330*54000Sfujita _leintr() 331*54000Sfujita { 332*54000Sfujita register int i; 333*54000Sfujita 334*54000Sfujita for (i = 0; i < NLE; i++) { 335*54000Sfujita leintr(i); 336*54000Sfujita } 337*54000Sfujita } 338*54000Sfujita 339*54000Sfujita int 340*54000Sfujita leintr(unit) 341*54000Sfujita register int unit; 342*54000Sfujita { 343*54000Sfujita register struct le_softc *le = &le_softc[unit]; 344*54000Sfujita register struct lereg1 *ler1; 345*54000Sfujita register int stat; 346*54000Sfujita 347*54000Sfujita ler1 = le->sc_r1; 348*54000Sfujita LERDWR(ler0, ler1->ler1_rdp, stat); 349*54000Sfujita if (stat & LE_SERR) { 350*54000Sfujita leerror(unit, stat); 351*54000Sfujita if (stat & LE_MERR) { 352*54000Sfujita le->sc_merr++; 353*54000Sfujita lereset(unit); 354*54000Sfujita return(1); 355*54000Sfujita } 356*54000Sfujita if (stat & LE_BABL) 357*54000Sfujita le->sc_babl++; 358*54000Sfujita if (stat & LE_CERR) 359*54000Sfujita le->sc_cerr++; 360*54000Sfujita if (stat & LE_MISS) 361*54000Sfujita le->sc_miss++; 362*54000Sfujita LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp); 363*54000Sfujita } 364*54000Sfujita if ((stat & LE_RXON) == 0) { 365*54000Sfujita le->sc_rxoff++; 366*54000Sfujita lereset(unit); 367*54000Sfujita return(1); 368*54000Sfujita } 369*54000Sfujita if ((stat & LE_TXON) == 0) { 370*54000Sfujita le->sc_txoff++; 371*54000Sfujita lereset(unit); 372*54000Sfujita return(1); 373*54000Sfujita } 374*54000Sfujita if (stat & LE_RINT) { 375*54000Sfujita /* interrupt is cleared in lerint */ 376*54000Sfujita lerint(unit); 377*54000Sfujita } 378*54000Sfujita if (stat & LE_TINT) { 379*54000Sfujita LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp); 380*54000Sfujita lexint(unit); 381*54000Sfujita } 382*54000Sfujita return(1); 383*54000Sfujita } 384*54000Sfujita 385*54000Sfujita /* 386*54000Sfujita * Ethernet interface transmitter interrupt. 387*54000Sfujita * Start another output if more data to send. 388*54000Sfujita */ 389*54000Sfujita lexint(unit) 390*54000Sfujita register int unit; 391*54000Sfujita { 392*54000Sfujita register struct le_softc *le = &le_softc[unit]; 393*54000Sfujita register struct letmd *tmd; 394*54000Sfujita int i, loopcount = 0; 395*54000Sfujita 396*54000Sfujita if (le->sc_txcnt == 0) { 397*54000Sfujita le->sc_xint++; 398*54000Sfujita return; 399*54000Sfujita } 400*54000Sfujita again: 401*54000Sfujita if ((i = le->sc_tmd - le->sc_txcnt) < 0) i += LETBUF; 402*54000Sfujita tmd = le->sc_r2->ler2_tmd + i; 403*54000Sfujita if (tmd->tmd1 & LE_OWN) { 404*54000Sfujita if (loopcount) 405*54000Sfujita goto out; 406*54000Sfujita le->sc_xown++; 407*54000Sfujita return; 408*54000Sfujita } 409*54000Sfujita if (tmd->tmd1 & LE_ERR) { 410*54000Sfujita err: 411*54000Sfujita lexerror(unit); 412*54000Sfujita le->sc_if.if_oerrors++; 413*54000Sfujita if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) { 414*54000Sfujita le->sc_uflo++; 415*54000Sfujita lereset(unit); 416*54000Sfujita } 417*54000Sfujita else if (tmd->tmd3 & LE_LCOL) 418*54000Sfujita le->sc_if.if_collisions++; 419*54000Sfujita else if (tmd->tmd3 & LE_RTRY) 420*54000Sfujita le->sc_if.if_collisions += 16; 421*54000Sfujita } 422*54000Sfujita else if (tmd->tmd3 & LE_TBUFF) 423*54000Sfujita /* XXX documentation says BUFF not included in ERR */ 424*54000Sfujita goto err; 425*54000Sfujita else if (tmd->tmd1 & LE_ONE) 426*54000Sfujita le->sc_if.if_collisions++; 427*54000Sfujita else if (tmd->tmd1 & LE_MORE) 428*54000Sfujita /* what is the real number? */ 429*54000Sfujita le->sc_if.if_collisions += 2; 430*54000Sfujita else 431*54000Sfujita le->sc_if.if_opackets++; 432*54000Sfujita loopcount++; 433*54000Sfujita if (--le->sc_txcnt > 0) 434*54000Sfujita goto again; 435*54000Sfujita if (le->sc_txcnt < 0) { 436*54000Sfujita le->sc_txbad++; 437*54000Sfujita le->sc_txcnt = 0; 438*54000Sfujita } 439*54000Sfujita out: 440*54000Sfujita le->sc_if.if_flags &= ~IFF_OACTIVE; 441*54000Sfujita (void) lestart(&le->sc_if); 442*54000Sfujita } 443*54000Sfujita 444*54000Sfujita #define LENEXTRMP \ 445*54000Sfujita if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd 446*54000Sfujita 447*54000Sfujita /* 448*54000Sfujita * Ethernet interface receiver interrupt. 449*54000Sfujita * If input error just drop packet. 450*54000Sfujita * Decapsulate packet based on type and pass to type specific 451*54000Sfujita * higher-level input routine. 452*54000Sfujita */ 453*54000Sfujita lerint(unit) 454*54000Sfujita int unit; 455*54000Sfujita { 456*54000Sfujita register struct le_softc *le = &le_softc[unit]; 457*54000Sfujita register int bix = le->sc_rmd; 458*54000Sfujita register struct lermd *rmd = &le->sc_r2->ler2_rmd[bix]; 459*54000Sfujita 460*54000Sfujita /* 461*54000Sfujita * Out of sync with hardware, should never happen? 462*54000Sfujita */ 463*54000Sfujita if (rmd->rmd1 & LE_OWN) { 464*54000Sfujita LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp); 465*54000Sfujita return; 466*54000Sfujita } 467*54000Sfujita 468*54000Sfujita /* 469*54000Sfujita * Process all buffers with valid data 470*54000Sfujita */ 471*54000Sfujita while ((rmd->rmd1 & LE_OWN) == 0) { 472*54000Sfujita int len = rmd->rmd3; 473*54000Sfujita 474*54000Sfujita /* Clear interrupt to avoid race condition */ 475*54000Sfujita LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp); 476*54000Sfujita 477*54000Sfujita if (rmd->rmd1 & LE_ERR) { 478*54000Sfujita le->sc_rmd = bix; 479*54000Sfujita lererror(unit, "bad packet"); 480*54000Sfujita le->sc_if.if_ierrors++; 481*54000Sfujita } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) { 482*54000Sfujita /* 483*54000Sfujita * Find the end of the packet so we can see how long 484*54000Sfujita * it was. We still throw it away. 485*54000Sfujita */ 486*54000Sfujita do { 487*54000Sfujita LERDWR(le->sc_r0, LE_RINT|LE_INEA, 488*54000Sfujita le->sc_r1->ler1_rdp); 489*54000Sfujita rmd->rmd3 = 0; 490*54000Sfujita rmd->rmd1 = LE_OWN; 491*54000Sfujita LENEXTRMP; 492*54000Sfujita } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP))); 493*54000Sfujita le->sc_rmd = bix; 494*54000Sfujita lererror(unit, "chained buffer"); 495*54000Sfujita le->sc_rxlen++; 496*54000Sfujita /* 497*54000Sfujita * If search terminated without successful completion 498*54000Sfujita * we reset the hardware (conservative). 499*54000Sfujita */ 500*54000Sfujita if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) != 501*54000Sfujita LE_ENP) { 502*54000Sfujita lereset(unit); 503*54000Sfujita return; 504*54000Sfujita } 505*54000Sfujita } else 506*54000Sfujita leread(unit, le->sc_r2->ler2_rbuf[bix], len); 507*54000Sfujita rmd->rmd3 = 0; 508*54000Sfujita rmd->rmd1 = LE_OWN; 509*54000Sfujita LENEXTRMP; 510*54000Sfujita } 511*54000Sfujita le->sc_rmd = bix; 512*54000Sfujita } 513*54000Sfujita 514*54000Sfujita leread(unit, buf, len) 515*54000Sfujita int unit; 516*54000Sfujita char *buf; 517*54000Sfujita int len; 518*54000Sfujita { 519*54000Sfujita register struct le_softc *le = &le_softc[unit]; 520*54000Sfujita register struct ether_header *et; 521*54000Sfujita struct mbuf *m; 522*54000Sfujita int off, resid; 523*54000Sfujita 524*54000Sfujita le->sc_if.if_ipackets++; 525*54000Sfujita et = (struct ether_header *)buf; 526*54000Sfujita et->ether_type = ntohs((u_short)et->ether_type); 527*54000Sfujita /* adjust input length to account for header and CRC */ 528*54000Sfujita len = len - sizeof(struct ether_header) - 4; 529*54000Sfujita 530*54000Sfujita #define ledataaddr(et, off, type) ((type)(((caddr_t)((et)+1)+(off)))) 531*54000Sfujita if (et->ether_type >= ETHERTYPE_TRAIL && 532*54000Sfujita et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 533*54000Sfujita off = (et->ether_type - ETHERTYPE_TRAIL) * 512; 534*54000Sfujita if (off >= ETHERMTU) 535*54000Sfujita return; /* sanity */ 536*54000Sfujita et->ether_type = ntohs(*ledataaddr(et, off, u_short *)); 537*54000Sfujita resid = ntohs(*(ledataaddr(et, off+2, u_short *))); 538*54000Sfujita if (off + resid > len) 539*54000Sfujita return; /* sanity */ 540*54000Sfujita len = off + resid; 541*54000Sfujita } else 542*54000Sfujita off = 0; 543*54000Sfujita 544*54000Sfujita if (len <= 0) { 545*54000Sfujita if (ledebug) 546*54000Sfujita log(LOG_WARNING, 547*54000Sfujita "le%d: ierror(runt packet): from %s: len=%d\n", 548*54000Sfujita unit, ether_sprintf(et->ether_shost), len); 549*54000Sfujita le->sc_runt++; 550*54000Sfujita le->sc_if.if_ierrors++; 551*54000Sfujita return; 552*54000Sfujita } 553*54000Sfujita #if NBPFILTER > 0 554*54000Sfujita /* 555*54000Sfujita * Check if there's a bpf filter listening on this interface. 556*54000Sfujita * If so, hand off the raw packet to bpf, which must deal with 557*54000Sfujita * trailers in its own way. 558*54000Sfujita */ 559*54000Sfujita if (le->sc_bpf) 560*54000Sfujita bpf_tap(le->sc_bpf, buf, len + sizeof(struct ether_header)); 561*54000Sfujita #endif 562*54000Sfujita #if defined(ISO) || NBPFILTER > 0 563*54000Sfujita /* 564*54000Sfujita * Note that the interface cannot be in promiscuous mode if 565*54000Sfujita * there are no bpf listeners. If we are in promiscuous 566*54000Sfujita * mode, we have to check if this packet is really ours. 567*54000Sfujita * However, there may be appropriate multicate addresses involved 568*54000Sfujita */ 569*54000Sfujita #define NOT_TO(p) (bcmp(et->ether_dhost, p, sizeof(et->ether_dhost)) != 0) 570*54000Sfujita if (et->ether_dhost[0] & 1) { 571*54000Sfujita if (NOT_TO(etherbroadcastaddr) && NOT_TO(hprmp_multi) 572*54000Sfujita #ifdef ISO 573*54000Sfujita && NOT_TO(all_es_snpa) && NOT_TO(all_is_snpa) 574*54000Sfujita && NOT_TO(all_l1is_snpa) && NOT_TO(all_l2is_snpa) 575*54000Sfujita #endif 576*54000Sfujita ) return; 577*54000Sfujita } else if ((le->sc_if.if_flags & IFF_PROMISC) && NOT_TO(le->sc_addr)) 578*54000Sfujita return; 579*54000Sfujita #endif 580*54000Sfujita /* 581*54000Sfujita * Pull packet off interface. Off is nonzero if packet 582*54000Sfujita * has trailing header; m_devget will then force this header 583*54000Sfujita * information to be at the front, but we still have to drop 584*54000Sfujita * the type and length which are at the front of any trailer data. 585*54000Sfujita */ 586*54000Sfujita m = m_devget((char *)(et + 1), len, off, &le->sc_if, 0); 587*54000Sfujita if (m == 0) 588*54000Sfujita return; 589*54000Sfujita ether_input(&le->sc_if, et, m); 590*54000Sfujita } 591*54000Sfujita 592*54000Sfujita /* 593*54000Sfujita * Routine to copy from mbuf chain to transmit 594*54000Sfujita * buffer in board local memory. 595*54000Sfujita */ 596*54000Sfujita leput(lebuf, m) 597*54000Sfujita register char *lebuf; 598*54000Sfujita register struct mbuf *m; 599*54000Sfujita { 600*54000Sfujita register struct mbuf *mp; 601*54000Sfujita register int len, tlen = 0; 602*54000Sfujita 603*54000Sfujita for (mp = m; mp; mp = mp->m_next) { 604*54000Sfujita len = mp->m_len; 605*54000Sfujita if (len == 0) 606*54000Sfujita continue; 607*54000Sfujita tlen += len; 608*54000Sfujita bcopy(mtod(mp, char *), lebuf, len); 609*54000Sfujita lebuf += len; 610*54000Sfujita } 611*54000Sfujita m_freem(m); 612*54000Sfujita if (tlen < LEMINSIZE) { 613*54000Sfujita bzero(lebuf, LEMINSIZE - tlen); 614*54000Sfujita tlen = LEMINSIZE; 615*54000Sfujita } 616*54000Sfujita return(tlen); 617*54000Sfujita } 618*54000Sfujita 619*54000Sfujita /* 620*54000Sfujita * Process an ioctl request. 621*54000Sfujita */ 622*54000Sfujita leioctl(ifp, cmd, data) 623*54000Sfujita register struct ifnet *ifp; 624*54000Sfujita int cmd; 625*54000Sfujita caddr_t data; 626*54000Sfujita { 627*54000Sfujita register struct ifaddr *ifa = (struct ifaddr *)data; 628*54000Sfujita struct le_softc *le = &le_softc[ifp->if_unit]; 629*54000Sfujita struct lereg1 *ler1 = le->sc_r1; 630*54000Sfujita int s = splimp(), error = 0; 631*54000Sfujita 632*54000Sfujita switch (cmd) { 633*54000Sfujita 634*54000Sfujita case SIOCSIFADDR: 635*54000Sfujita ifp->if_flags |= IFF_UP; 636*54000Sfujita switch (ifa->ifa_addr->sa_family) { 637*54000Sfujita #ifdef INET 638*54000Sfujita case AF_INET: 639*54000Sfujita leinit(ifp->if_unit); /* before arpwhohas */ 640*54000Sfujita ((struct arpcom *)ifp)->ac_ipaddr = 641*54000Sfujita IA_SIN(ifa)->sin_addr; 642*54000Sfujita arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 643*54000Sfujita break; 644*54000Sfujita #endif 645*54000Sfujita #ifdef NS 646*54000Sfujita case AF_NS: 647*54000Sfujita { 648*54000Sfujita register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 649*54000Sfujita 650*54000Sfujita if (ns_nullhost(*ina)) 651*54000Sfujita ina->x_host = *(union ns_host *)(le->sc_addr); 652*54000Sfujita else { 653*54000Sfujita /* 654*54000Sfujita * The manual says we can't change the address 655*54000Sfujita * while the receiver is armed, 656*54000Sfujita * so reset everything 657*54000Sfujita */ 658*54000Sfujita ifp->if_flags &= ~IFF_RUNNING; 659*54000Sfujita LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp); 660*54000Sfujita bcopy((caddr_t)ina->x_host.c_host, 661*54000Sfujita (caddr_t)le->sc_addr, sizeof(le->sc_addr)); 662*54000Sfujita } 663*54000Sfujita leinit(ifp->if_unit); /* does le_setaddr() */ 664*54000Sfujita break; 665*54000Sfujita } 666*54000Sfujita #endif 667*54000Sfujita default: 668*54000Sfujita leinit(ifp->if_unit); 669*54000Sfujita break; 670*54000Sfujita } 671*54000Sfujita break; 672*54000Sfujita 673*54000Sfujita case SIOCSIFFLAGS: 674*54000Sfujita if ((ifp->if_flags & IFF_UP) == 0 && 675*54000Sfujita ifp->if_flags & IFF_RUNNING) { 676*54000Sfujita LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp); 677*54000Sfujita ifp->if_flags &= ~IFF_RUNNING; 678*54000Sfujita } else if (ifp->if_flags & IFF_UP && 679*54000Sfujita (ifp->if_flags & IFF_RUNNING) == 0) 680*54000Sfujita leinit(ifp->if_unit); 681*54000Sfujita /* 682*54000Sfujita * If the state of the promiscuous bit changes, the interface 683*54000Sfujita * must be reset to effect the change. 684*54000Sfujita */ 685*54000Sfujita if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) && 686*54000Sfujita (ifp->if_flags & IFF_RUNNING)) { 687*54000Sfujita le->sc_iflags = ifp->if_flags; 688*54000Sfujita lereset(ifp->if_unit); 689*54000Sfujita lestart(ifp); 690*54000Sfujita } 691*54000Sfujita break; 692*54000Sfujita 693*54000Sfujita default: 694*54000Sfujita error = EINVAL; 695*54000Sfujita } 696*54000Sfujita splx(s); 697*54000Sfujita return (error); 698*54000Sfujita } 699*54000Sfujita 700*54000Sfujita leerror(unit, stat) 701*54000Sfujita int unit; 702*54000Sfujita int stat; 703*54000Sfujita { 704*54000Sfujita if (!ledebug) 705*54000Sfujita return; 706*54000Sfujita 707*54000Sfujita /* 708*54000Sfujita * Not all transceivers implement heartbeat 709*54000Sfujita * so we only log CERR once. 710*54000Sfujita */ 711*54000Sfujita if ((stat & LE_CERR) && le_softc[unit].sc_cerr) 712*54000Sfujita return; 713*54000Sfujita log(LOG_WARNING, 714*54000Sfujita "le%d: error: stat=%b\n", unit, 715*54000Sfujita stat, 716*54000Sfujita "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT"); 717*54000Sfujita } 718*54000Sfujita 719*54000Sfujita lererror(unit, msg) 720*54000Sfujita int unit; 721*54000Sfujita char *msg; 722*54000Sfujita { 723*54000Sfujita register struct le_softc *le = &le_softc[unit]; 724*54000Sfujita register struct lermd *rmd; 725*54000Sfujita int len; 726*54000Sfujita 727*54000Sfujita if (!ledebug) 728*54000Sfujita return; 729*54000Sfujita 730*54000Sfujita rmd = &le->sc_r2->ler2_rmd[le->sc_rmd]; 731*54000Sfujita len = rmd->rmd3; 732*54000Sfujita log(LOG_WARNING, 733*54000Sfujita "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n", 734*54000Sfujita unit, msg, 735*54000Sfujita len > 11 ? 736*54000Sfujita ether_sprintf((u_char *)&le->sc_r2->ler2_rbuf[le->sc_rmd][6]) : 737*54000Sfujita "unknown", 738*54000Sfujita le->sc_rmd, len, 739*54000Sfujita rmd->rmd1, 740*54000Sfujita "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP"); 741*54000Sfujita } 742*54000Sfujita 743*54000Sfujita lexerror(unit) 744*54000Sfujita int unit; 745*54000Sfujita { 746*54000Sfujita register struct le_softc *le = &le_softc[unit]; 747*54000Sfujita register struct letmd *tmd; 748*54000Sfujita int len; 749*54000Sfujita 750*54000Sfujita if (!ledebug) 751*54000Sfujita return; 752*54000Sfujita 753*54000Sfujita tmd = le->sc_r2->ler2_tmd; 754*54000Sfujita len = -tmd->tmd2; 755*54000Sfujita log(LOG_WARNING, 756*54000Sfujita "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n", 757*54000Sfujita unit, 758*54000Sfujita len > 5 ? 759*54000Sfujita ether_sprintf((u_char *)&le->sc_r2->ler2_tbuf[0][0]) : 760*54000Sfujita "unknown", 761*54000Sfujita 0, len, 762*54000Sfujita tmd->tmd1, 763*54000Sfujita "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP", 764*54000Sfujita tmd->tmd3, 765*54000Sfujita "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY"); 766*54000Sfujita } 767*54000Sfujita #endif 768