new mbufs (enp tested, ace not)
[unix-history] / usr / src / sys / tahoe / if / if_enp.c
index ac042aa..e818caa 100644 (file)
@@ -1,12 +1,29 @@
-/*     if_enp.c        1.2     86/11/29        */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Computer Consoles Inc.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)if_enp.c    7.4 (Berkeley) %G%
+ */
 
 #include "enp.h"
 #if NENP > 0
 /*
 
 #include "enp.h"
 #if NENP > 0
 /*
- * Modified 3Com Ethernet Controller interface
- * enp modifications added S. F. Holmgren
- *
- * UNTESTED WITH 4.3
+ * CMC ENP-20 Ethernet Controller.
  */
 #include "param.h"
 #include "systm.h"
  */
 #include "param.h"
 #include "systm.h"
 #include "../tahoevba/vbavar.h"
 #include "../tahoeif/if_enpreg.h"
 
 #include "../tahoevba/vbavar.h"
 #include "../tahoeif/if_enpreg.h"
 
-#define        ENPVEC  0xc1
 #define ENPSTART       0xf02000        /* standard enp start addr */
 #define        ENPUNIT(dev)    (minor(dev))    /* for enp ram devices */
 #define ENPSTART       0xf02000        /* standard enp start addr */
 #define        ENPUNIT(dev)    (minor(dev))    /* for enp ram devices */
+/* macros for dealing with longs in i/o space */
+#define        ENPGETLONG(a)   ((((u_short *)(a))[0] << 16)|(((u_short *)(a))[1]))
+#define        ENPSETLONG(a,v) \
+   { register u_short *wp = (u_short *)(a); \
+     wp[0] = ((u_short *)&(v))[0]; wp[1] = ((u_short *)&(v))[1];}
 
 int    enpprobe(), enpattach(), enpintr();
 
 int    enpprobe(), enpattach(), enpintr();
-long   enpstd[] = { 0xf41000, 0xf61000, 0 };
+long   enpstd[] = { 0xfff41000, 0xfff61000, 0 };
 struct  vba_device *enpinfo[NENP];
 struct  vba_driver enpdriver = 
     { enpprobe, 0, enpattach, 0, enpstd, "enp", enpinfo, "enp-20", 0 };
 
 struct  vba_device *enpinfo[NENP];
 struct  vba_driver enpdriver = 
     { enpprobe, 0, enpattach, 0, enpstd, "enp", enpinfo, "enp-20", 0 };
 
-int    enpinit(), enpioctl(), enpreset(), enpoutput();
+int    enpinit(), enpioctl(), enpreset(), enpoutput(), enpstart();
 struct  mbuf *enpget();
 
 /*
 struct  mbuf *enpget();
 
 /*
@@ -67,11 +88,8 @@ struct  mbuf *enpget();
 struct  enp_softc {
        struct  arpcom es_ac;           /* common ethernet structures */
 #define es_if          es_ac.ac_if
 struct  enp_softc {
        struct  arpcom es_ac;           /* common ethernet structures */
 #define es_if          es_ac.ac_if
-#define es_enaddr      es_ac.ac_enaddr
-       short   es_flags;               /* flags for devices */
+#define es_addr        es_ac.ac_enaddr
        short   es_ivec;                /* interrupt vector */
        short   es_ivec;                /* interrupt vector */
-       struct  pte *es_map;            /* map for dual ported memory */
-       caddr_t es_ram;                 /* virtual address of mapped memory */
 } enp_softc[NENP]; 
 extern struct ifnet loif;
 
 } enp_softc[NENP]; 
 extern struct ifnet loif;
 
@@ -84,9 +102,10 @@ enpprobe(reg, vi)
        struct enp_softc *es = &enp_softc[vi->ui_unit];
 
 #ifdef lint
        struct enp_softc *es = &enp_softc[vi->ui_unit];
 
 #ifdef lint
+       br = 0; cvec = br; br = cvec;
        enpintr(0);
 #endif
        enpintr(0);
 #endif
-       if (badaddr(addr, 2) || badaddr(&addr->enp_ram[0], 2))
+       if (badaddr((caddr_t)addr, 2) || badaddr((caddr_t)&addr->enp_ram[0], 2))
                return (0);
        es->es_ivec = --vi->ui_hd->vh_lastiv;
        addr->enp_state = S_ENPRESET;           /* reset by VERSAbus reset */
                return (0);
        es->es_ivec = --vi->ui_hd->vh_lastiv;
        addr->enp_state = S_ENPRESET;           /* reset by VERSAbus reset */
@@ -104,28 +123,16 @@ enpattach(ui)
 {
        struct enp_softc *es = &enp_softc[ui->ui_unit];
        register struct ifnet *ifp = &es->es_if;
 {
        struct enp_softc *es = &enp_softc[ui->ui_unit];
        register struct ifnet *ifp = &es->es_if;
-       register struct enpdevice *addr = (struct enpdevice *)ui->ui_addr;
 
        ifp->if_unit = ui->ui_unit;
        ifp->if_name = "enp";
        ifp->if_mtu = ETHERMTU;
 
        ifp->if_unit = ui->ui_unit;
        ifp->if_name = "enp";
        ifp->if_mtu = ETHERMTU;
-       /*
-        * Get station's addresses.
-        */
-       enpcopy(&addr->enp_addr.e_baseaddr, es->es_enaddr,
-           sizeof (es->es_enaddr));
-       printf("enp%d: hardware address %s\n", ui->ui_unit,
-           ether_sprintf(es->es_enaddr));
-       /*
-        * Allocate and map ram.
-        */
-       vbmemalloc(128, ((caddr_t)addr)+0x1000, &es->es_map, &es->es_ram);
-
        ifp->if_init = enpinit;
        ifp->if_ioctl = enpioctl;
        ifp->if_init = enpinit;
        ifp->if_ioctl = enpioctl;
-       ifp->if_output = enpoutput;
+       ifp->if_output = enoutput;
+       ifp->if_start = enpstart;
        ifp->if_reset = enpreset;
        ifp->if_reset = enpreset;
-       ifp->if_flags = IFF_BROADCAST;
+       ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
        if_attach(ifp);
 }
 
        if_attach(ifp);
 }
 
@@ -163,7 +170,6 @@ enpinit(unit)
                s = splimp();
                RESET_ENP(addr);
                DELAY(200000);
                s = splimp();
                RESET_ENP(addr);
                DELAY(200000);
-               addr->enp_intrvec = es->es_ivec;
                es->es_if.if_flags |= IFF_RUNNING;
                splx(s);
        }
                es->es_if.if_flags |= IFF_RUNNING;
                splx(s);
        }
@@ -179,28 +185,27 @@ enpintr(unit)
        register BCB *bcbp;
 
        addr = (struct enpdevice *)enpinfo[unit]->ui_addr;
        register BCB *bcbp;
 
        addr = (struct enpdevice *)enpinfo[unit]->ui_addr;
+#if ENP == 30
        if (!IS_ENP_INTR(addr))
                return;
        ACK_ENP_INTR(addr);
        if (!IS_ENP_INTR(addr))
                return;
        ACK_ENP_INTR(addr);
-       while ((bcbp = (BCB *)ringget(&addr->enp_tohost )) != 0) {
-               (void) enpread(&enp_softc[unit], bcbp, unit);
-               ringput(&addr->enp_enpfree, bcbp); 
+#endif
+       while ((bcbp = (BCB *)ringget((RING *)&addr->enp_tohost )) != 0) {
+               enpread(&enp_softc[unit], bcbp);
+               (void) ringput((RING *)&addr->enp_enpfree, bcbp); 
        }
 }
 
 /*
  * Read input packet, examine its packet type, and enqueue it.
  */
        }
 }
 
 /*
  * Read input packet, examine its packet type, and enqueue it.
  */
-enpread(es, bcbp, unit)
+enpread(es, bcbp)
        struct enp_softc *es;
        register BCB *bcbp;
        struct enp_softc *es;
        register BCB *bcbp;
-       int unit;
 {
        register struct ether_header *enp;
        struct mbuf *m;
 {
        register struct ether_header *enp;
        struct mbuf *m;
-       long int s;
-       int len, off, resid, enptype;
-       register struct ifqueue *inq;
+       int s, len, off, resid;
 
        es->es_if.if_ipackets++; 
        /*
 
        es->es_if.if_ipackets++; 
        /*
@@ -211,7 +216,7 @@ enpread(es, bcbp, unit)
         * Remember that type was trailer by setting off.
         */
        len = bcbp->b_msglen - sizeof (struct ether_header);
         * Remember that type was trailer by setting off.
         */
        len = bcbp->b_msglen - sizeof (struct ether_header);
-       enp = (struct ether_header *)bcbp->b_addr;
+       enp = (struct ether_header *)ENPGETLONG(&bcbp->b_addr);
 #define enpdataaddr(enp, off, type) \
     ((type)(((caddr_t)(((char *)enp)+sizeof (struct ether_header))+(off))))
        enp->ether_type = ntohs((u_short)enp->ether_type);
 #define enpdataaddr(enp, off, type) \
     ((type)(((caddr_t)(((char *)enp)+sizeof (struct ether_header))+(off))))
        enp->ether_type = ntohs((u_short)enp->ether_type);
@@ -219,237 +224,81 @@ enpread(es, bcbp, unit)
            enp->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
                off = (enp->ether_type - ETHERTYPE_TRAIL) * 512;
                if (off >= ETHERMTU)
            enp->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
                off = (enp->ether_type - ETHERTYPE_TRAIL) * 512;
                if (off >= ETHERMTU)
-                       goto setup;
+                       return;
                enp->ether_type = ntohs(*enpdataaddr(enp, off, u_short *));
                resid = ntohs(*(enpdataaddr(enp, off+2, u_short *)));
                if (off + resid > len)
                enp->ether_type = ntohs(*enpdataaddr(enp, off, u_short *));
                resid = ntohs(*(enpdataaddr(enp, off+2, u_short *)));
                if (off + resid > len)
-                       goto setup;
+                       return;
                len = off + resid;
        } else
                off = 0;
        if (len == 0)
                len = off + resid;
        } else
                off = 0;
        if (len == 0)
-               goto setup;
+               return;
 
        /*
         * Pull packet off interface.  Off is nonzero if packet
         * has trailing header; enpget will then force this header
 
        /*
         * Pull packet off interface.  Off is nonzero if packet
         * has trailing header; enpget will then force this header
-        * information to be at the front, but we still have to drop
-        * the type and length which are at the front of any trailer data.
+        * information to be at the front.
         */
         */
-       m = enpget(bcbp->b_addr, len, off, &es->es_if);
+       m = enpget((u_char *)enp, len, off, &es->es_if);
        if (m == 0)
        if (m == 0)
-               goto setup;
-       if (off) {
-               struct ifnet *ifp;
-
-               ifp = *(mtod(m, struct ifnet **));
-               m->m_off += 2 * sizeof (u_short);
-               m->m_len -= 2 * sizeof (u_short);
-               *(mtod(m, struct ifnet **)) = ifp;
-       }
-       switch (enp->ether_type) {
-
-#ifdef INET
-       case ETHERTYPE_IP:
-               schednetisr(NETISR_IP);
-               inq = &ipintrq;
-               break;
-#endif
-       case ETHERTYPE_ARP:
-               arpinput(&es->es_ac, m);
-               goto setup;
-
-#ifdef NS
-       case ETHERTYPE_NS:
-               schednetisr(NETISR_NS);
-               inq = &nsintrq;
-               break;
-#endif
-       default:
-               m_freem(m);
-               goto setup;
-       }
-       if (IF_QFULL(inq)) {
-               IF_DROP(inq);
-               m_freem(m);
-               goto setup;
-       }
-       s = splimp();
-       IF_ENQUEUE(inq, m);
-       splx(s);
-setup:
-       return (0);
+               return;
+       en_doproto(&es->es_if, enp, m);
 }
 
 }
 
-/*
- * Ethernet output routine. (called by user)
- * Encapsulate a packet of type family for the local net.
- * Use trailer local net encapsulation if enough data in first
- * packet leaves a multiple of 512 bytes of data in remainder.
- * If destination is this address or broadcast, send packet to
- * loop device to kludge around the fact that 3com interfaces can't
- * talk to themselves.
- */
-enpoutput(ifp, m0, dst)
+enpstart(ifp)
        struct ifnet *ifp;
        struct ifnet *ifp;
-       struct mbuf *m0;
-       struct sockaddr *dst;
 {
 {
-       register struct enp_softc *es = &enp_softc[ifp->if_unit];
-       register struct mbuf *m = m0;
-       register struct ether_header *enp;
-       register int off, i;
-       struct mbuf *mcopy = (struct mbuf *)0;
-       int type, s, error, usetrailers;
-       u_char edst[6];
-       struct in_addr idst;
-
-       if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
-               error = ENETDOWN;
-               goto bad;
-       }
-       switch (dst->sa_family) {
-#ifdef INET
-       case AF_INET:
-               idst = ((struct sockaddr_in *)dst)->sin_addr;
-               if (!arpresolve(&es->es_ac, m, &idst, edst, &usetrailers))
-                       return (0);     /* if not yet resolved */
-               if (!bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr,
-                   sizeof (edst)))
-                       mcopy = m_copy(m, 0, (int)M_COPYALL);
-               off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
-               if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
-                   m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
-                       type = ETHERTYPE_TRAIL + (off>>9);
-                       m->m_off -= 2 * sizeof (u_short);
-                       m->m_len += 2 * sizeof (u_short);
-                       *mtod(m, u_short *) = ETHERTYPE_IP;
-                       *(mtod(m, u_short *) + 1) = m->m_len;
-                       goto gottrailertype;
-               }
-               type = ETHERTYPE_IP;
-               off = 0;
-               goto gottype;
-#endif
-#ifdef NS
-       case AF_NS:
-               bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
-                   (caddr_t)edst, sizeof (edst));
-               if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof (edst)))
-                       mcopy = m_copy(m, 0, (int)M_COPYALL);
-               else if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost,
-                   sizeof (edst)))
-                       return (looutput(&loif, m, dst));
-               type = ETHERTYPE_NS;
-               off = 0;
-               goto gottype;
-#endif
-       case AF_UNSPEC:
-               enp = (struct ether_header *)dst->sa_data;
-               bcopy((caddr_t)enp->ether_dhost, (caddr_t)edst, sizeof (edst));
-               type = enp->ether_type;
-               goto gottype;
-
-       default:
-               log(LOG_ERR, "enp%d: can't handle af%d\n",
-                   ifp->if_unit, dst->sa_family);
-               error = EAFNOSUPPORT;
-               goto bad;
-       }
-
-gottrailertype:
-       /*
-        * Packet to be sent as trailer: move first packet
-        * (control information) to end of chain.
-        */
-       while (m->m_next)
-               m = m->m_next;
-       m->m_next = m0;
-       m = m0->m_next;
-       m0->m_next = 0;
-       m0 = m;
-
-gottype:
-       /*
-         * Add local net header.  If no space in first mbuf,
-         * allocate another.
-         */
-       if (m->m_off > MMAXOFF ||
-           MMINOFF + sizeof (struct ether_header) > m->m_off) {
-               m = m_get(M_DONTWAIT, MT_HEADER);
-               if (m == 0) {
-                       error = ENOBUFS;
-                       goto bad;
-               }
-               m->m_next = m0;
-               m->m_off = MMINOFF;
-               m->m_len = sizeof (struct ether_header);
-       } else {
-               m->m_off -= sizeof (struct ether_header);
-               m->m_len += sizeof (struct ether_header);
-       }
-       enp = mtod(m, struct ether_header *);
-       bcopy((caddr_t)edst, (caddr_t)enp->ether_dhost, sizeof (edst));
-       bcopy((caddr_t)es->es_enaddr, (caddr_t)enp->ether_shost,
-           sizeof (es->es_enaddr));
-       enp->ether_type = htons((u_short)type);
 
 
-       /*
-        * Queue message on interface if possible 
-        */
-       s = splimp();   
-       if (enpput(ifp->if_unit, m)) {
-               error = ENOBUFS;
-               goto qfull;
-       }
-       splx(s);        
-       es->es_if.if_opackets++; 
-       return (mcopy ? looutput(&loif, mcopy, dst) : 0);
-qfull:
-       splx(s);        
-       m0 = m;
-bad:
-       m_freem(m0);
-       if (mcopy)
-               m_freem(mcopy);
-       return (error);
+       if (enpput(ifp))
+               return (ENOBUFS);
+       else
+               return (0);
 }
 
 /*
  * Routine to copy from mbuf chain to transmitter buffer on the VERSAbus.
  */
 }
 
 /*
  * Routine to copy from mbuf chain to transmitter buffer on the VERSAbus.
  */
-enpput(unit, m)
-       int unit;
-       struct mbuf *m;
+enpput(ifp)
+struct ifnet *ifp;
 {
        register BCB *bcbp;
        register struct enpdevice *addr;
        register struct mbuf *mp;
        register u_char *bp;
        register u_int len;
 {
        register BCB *bcbp;
        register struct enpdevice *addr;
        register struct mbuf *mp;
        register u_char *bp;
        register u_int len;
-       u_char *mcp;
+       int unit = ifp->if_unit, ret = 1;
+       struct mbuf *m;
 
        addr = (struct enpdevice *)enpinfo[unit]->ui_addr;
 
        addr = (struct enpdevice *)enpinfo[unit]->ui_addr;
-       if (ringempty(&addr->enp_hostfree)) 
-               return (1);     
-       bcbp = (BCB *)ringget(&addr->enp_hostfree);
+again:
+       if (ringempty((RING *)&addr->enp_hostfree))  {
+       /*      ifp->if_flags |= IFF_OACTIVE; */
+               return (ret);
+       }
+       IF_DEQUEUE(&ifp->if_snd, m);
+       if (m == 0) {
+               ifp->if_flags &= ~IFF_OACTIVE;
+               return (0);
+       }
+       bcbp = (BCB *)ringget((RING *)&addr->enp_hostfree);
        bcbp->b_len = 0;
        bcbp->b_len = 0;
-       bp = (u_char *)bcbp->b_addr;
+       bp = (u_char *)ENPGETLONG(&bcbp->b_addr);
        for (mp = m; mp; mp = mp->m_next) {
                len = mp->m_len;
                if (len == 0)
                        continue;
        for (mp = m; mp; mp = mp->m_next) {
                len = mp->m_len;
                if (len == 0)
                        continue;
-               mcp = mtod(mp, u_char *);
-               enpcopy(mcp, bp, len);
+               enpcopy(mtod(mp, u_char *), bp, len);
                bp += len;
                bcbp->b_len += len;
        }
                bp += len;
                bcbp->b_len += len;
        }
-       bcbp->b_len = max(ETHERMIN, bcbp->b_len);
+       bcbp->b_len = max(ETHERMIN+sizeof (struct ether_header), bcbp->b_len);
        bcbp->b_reserved = 0;
        bcbp->b_reserved = 0;
-       if (ringput(&addr->enp_toenp, bcbp) == 1)
+       if (ringput((RING *)&addr->enp_toenp, bcbp) == 1)
                INTR_ENP(addr);
        m_freem(m);
                INTR_ENP(addr);
        m_freem(m);
-       return (0);
+       ret = 0;
+       goto again;
 }
 
 /*
 }
 
 /*
@@ -459,72 +308,74 @@ enpput(unit, m)
  * mbufs have even lengths.
  */
 struct mbuf *
  * mbufs have even lengths.
  */
 struct mbuf *
-enpget(rxbuf, totlen, off0, ifp)
+enpget(rxbuf, totlen, off, ifp)
        u_char *rxbuf;
        u_char *rxbuf;
-       int totlen, off0;
+       int totlen, off;
        struct ifnet *ifp;
 {
        struct ifnet *ifp;
 {
-       register u_char *cp, *mcp;
+       register u_char *cp;
        register struct mbuf *m;
        struct mbuf *top = 0, **mp = &top;
        register struct mbuf *m;
        struct mbuf *top = 0, **mp = &top;
-       int len, off = off0;
+       int len;
+       u_char *packet_end;
+
+       rxbuf += sizeof (struct ether_header);
+       cp = rxbuf;
+       packet_end = cp + totlen;
+       if (off) {
+               off += 2 * sizeof(u_short);
+               totlen -= 2 *sizeof(u_short);
+               cp = rxbuf + off;
+       }
+
+       MGETHDR(m, M_DONTWAIT, MT_DATA);
+       if (m == 0)
+               return (0);
+       m->m_pkthdr.rcvif = ifp;
+       m->m_pkthdr.len = totlen;
+       m->m_len = MHLEN;
 
 
-       cp = rxbuf + sizeof (struct ether_header);
        while (totlen > 0) {
        while (totlen > 0) {
-               MGET(m, M_DONTWAIT, MT_DATA);
-               if (m == 0) 
-                       goto bad;
-               if (off) {
-                       len = totlen - off;
-                       cp = rxbuf + sizeof (struct ether_header) + off;
-               } else
-                       len = totlen;
-               if (len >= NBPG) {
-                       struct mbuf *p;
-
-                       MCLGET(m);
-                       if (m->m_len == CLBYTES)
-                               m->m_len = len = MIN(len, CLBYTES);
+               if (top) {
+                       MGET(m, M_DONTWAIT, MT_DATA);
+                       if (m == 0) {
+                               m_freem(top);
+                               return (0);
+                       }
+                       m->m_len = MLEN;
+               }
+               len = min(totlen, (packet_end - cp));
+               if (len >= MINCLSIZE) {
+                       MCLGET(m, M_DONTWAIT);
+                       if (m->m_flags & M_EXT)
+                               m->m_len = len = min(len, MCLBYTES);
                        else
                        else
-                               m->m_len = len = MIN(MLEN, len);
+                               len = m->m_len;
                } else {
                } else {
-                       m->m_len = len = MIN(MLEN, len);
-                       m->m_off = MMINOFF;
-               }
-               mcp = mtod(m, u_char *);
-               if (ifp) {
                        /*
                        /*
-                        * Prepend interface pointer to first mbuf.
+                        * Place initial small packet/header at end of mbuf.
                         */
                         */
-                       *(mtod(m, struct ifnet **)) = ifp;
-                       mcp += sizeof (ifp);
-                       len -= sizeof (ifp);
-                       ifp = (struct ifnet *)0;
+                       if (len < m->m_len) {
+                               if (top == 0 && len + max_linkhdr <= m->m_len)
+                                       m->m_data += max_linkhdr;
+                               m->m_len = len;
+                       } else
+                               len = m->m_len;
                }
                }
-               enpcopy(cp, mcp, len);
-               cp += len;
+               enpcopy(cp, mtod(m, u_char *), (u_int)len);
                *mp = m;
                mp = &m->m_next;
                *mp = m;
                mp = &m->m_next;
-               if (off == 0) {
-                       totlen -= len;
-                       continue;
-               }
-               off += len;
-               if (off == totlen) {
-                       cp = rxbuf + sizeof (struct ether_header);
-                       off = 0;
-                       totlen = off0;
-               }
+               totlen -= len;
+               cp += len;
+               if (cp == packet_end)
+                       cp = rxbuf;
        }
        return (top);
        }
        return (top);
-bad:
-       m_freem(top);
-       return (0);
 }
 
 enpcopy(from, to, cnt)
 }
 
 enpcopy(from, to, cnt)
-       register char *from, *to;
-       register cnt;
+       register u_char *from, *to;
+       register u_int cnt;
 {
        register c;
        register short *f, *t;
 {
        register c;
        register short *f, *t;
@@ -541,12 +392,12 @@ enpcopy(from, to, cnt)
                        *t++ = *f++;
                cnt &= 1;
                if (cnt) {                      /* odd len */
                        *t++ = *f++;
                cnt &= 1;
                if (cnt) {                      /* odd len */
-                       from = (char *)f;
-                       to = (char *)t;
+                       from = (u_char *)f;
+                       to = (u_char *)t;
                        *to = *from;
                }
        }
                        *to = *from;
                }
        }
-       while (cnt-- > 0)       /* one of the address(es) must be odd */
+       while ((int)cnt-- > 0)  /* one of the address(es) must be odd */
                *to++ = *from++;
 }
 
                *to++ = *from++;
 }
 
@@ -587,7 +438,7 @@ enpioctl(ifp, cmd, data)
                                enpsetaddr(ifp->if_unit, addr,
                                    ina->x_host.c_host);
                        } else
                                enpsetaddr(ifp->if_unit, addr,
                                    ina->x_host.c_host);
                        } else
-                               ina->x_host = *(union ns_host *)es->es_enaddr;
+                               ina->x_host = *(union ns_host *)es->es_addr;
                        enpinit(ifp->if_unit);
                        break;
                }
                        enpinit(ifp->if_unit);
                        break;
                }
@@ -619,59 +470,75 @@ enpsetaddr(unit, addr, enaddr)
        struct enpdevice *addr;
        u_char *enaddr;
 {
        struct enpdevice *addr;
        u_char *enaddr;
 {
-       u_char *cp;
-       int i, code;
-
-       cp = &addr->enp_addr.e_baseaddr.ea_addr[0];
-       for (i = 0; i < 6; i++)
-               *cp++ = ~*enaddr++;
-       enpcopy(&addr->enp_addr.e_listsize, &code, sizeof (code)); 
-       code |= E_ADDR_SUPP;
-       enpcopy(&code, &addr->enp_addr.e_listsize, sizeof (code)); 
+
+       enpcopy(enaddr, addr->enp_addr.e_baseaddr.ea_addr,
+           sizeof (struct ether_addr));
        enpinit(unit);
        enpinit(unit);
+       enpgetaddr(unit, addr);
+}
+
+enpgetaddr(unit, addr)
+       int unit;
+       struct enpdevice *addr;
+{
+       struct enp_softc *es = &enp_softc[unit];
+
+       enpcopy(addr->enp_addr.e_baseaddr.ea_addr, es->es_addr,
+           sizeof (struct ether_addr));
+       printf("enp%d: hardware address %s\n",
+           unit, ether_sprintf(es->es_addr));
 }
 
 /* 
  * Routines to synchronize enp and host.
  */
 }
 
 /* 
  * Routines to synchronize enp and host.
  */
+#ifdef notdef
 static
 ringinit(rp, size)
        register RING *rp;
 {
 static
 ringinit(rp, size)
        register RING *rp;
 {
-       register int i;
-       register short *sp; 
 
        rp->r_rdidx = rp->r_wrtidx = 0;
        rp->r_size = size;
 }
 
 static
 
        rp->r_rdidx = rp->r_wrtidx = 0;
        rp->r_size = size;
 }
 
 static
-ringempty(rp)
+ringfull(rp)
        register RING *rp;
 {
        register RING *rp;
 {
+       register short idx;
 
 
-       return (rp->r_rdidx == rp->r_wrtidx);
+       idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
+       return (idx == rp->r_rdidx);
 }
 
 static
 }
 
 static
-ringfull(rp)
+fir(rp)
        register RING *rp;
 {
        register RING *rp;
 {
-       register short idx;
 
 
-       idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
-       return (idx == rp->r_rdidx);
+       return (rp->r_rdidx != rp->r_wrtidx ? rp->r_slot[rp->r_rdidx] : 0);
+}
+#endif
+
+static
+ringempty(rp)
+       register RING *rp;
+{
+
+       return (rp->r_rdidx == rp->r_wrtidx);
 }
 
 static
 ringput(rp, v)
        register RING *rp;
 }
 
 static
 ringput(rp, v)
        register RING *rp;
+       BCB *v;
 {
        register int idx;
 
        idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
        if (idx != rp->r_rdidx) {
 {
        register int idx;
 
        idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
        if (idx != rp->r_rdidx) {
-               rp->r_slot[rp->r_wrtidx] = v;
+               ENPSETLONG(&rp->r_slot[rp->r_wrtidx], v);
                rp->r_wrtidx = idx;
                if ((idx -= rp->r_rdidx) < 0)
                        idx += rp->r_size;
                rp->r_wrtidx = idx;
                if ((idx -= rp->r_rdidx) < 0)
                        idx += rp->r_size;
@@ -687,20 +554,12 @@ ringget(rp)
        register int i = 0;
 
        if (rp->r_rdidx != rp->r_wrtidx) {
        register int i = 0;
 
        if (rp->r_rdidx != rp->r_wrtidx) {
-               i = rp->r_slot[rp->r_rdidx];
+               i = ENPGETLONG(&rp->r_slot[rp->r_rdidx]);
                rp->r_rdidx = (++rp->r_rdidx) & (rp->r_size-1);
        }
        return (i);
 }
 
                rp->r_rdidx = (++rp->r_rdidx) & (rp->r_size-1);
        }
        return (i);
 }
 
-static
-fir(rp)
-       register RING *rp;
-{
-
-       return (rp->r_rdidx != rp->r_wrtidx ? rp->r_slot[rp->r_rdidx] : 0);
-}
-
 /*
  * ENP Ram device.
  */
 /*
  * ENP Ram device.
  */
@@ -719,6 +578,7 @@ enpr_open(dev)
        return (0);
 }
 
        return (0);
 }
 
+/*ARGSUSED*/
 enpr_close(dev)
        dev_t dev;
 {
 enpr_close(dev)
        dev_t dev;
 {
@@ -732,18 +592,17 @@ enpr_read(dev, uio)
 {
        register struct iovec *iov;
        struct enpdevice *addr;
 {
        register struct iovec *iov;
        struct enpdevice *addr;
-       int error;
 
        if (uio->uio_offset > RAM_SIZE)
                return (ENODEV);
 
        if (uio->uio_offset > RAM_SIZE)
                return (ENODEV);
+       iov = uio->uio_iov;
        if (uio->uio_offset + iov->iov_len > RAM_SIZE)
                iov->iov_len = RAM_SIZE - uio->uio_offset;
        addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr;
        if (uio->uio_offset + iov->iov_len > RAM_SIZE)
                iov->iov_len = RAM_SIZE - uio->uio_offset;
        addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr;
-       iov = uio->uio_iov;
-       error = useracc(iov->iov_base, iov->iov_len, 0);
-       if (error)
-               return (error);
-       enpcopy(&addr->enp_ram[uio->uio_offset], iov->iov_base, iov->iov_len);
+       if (useracc(iov->iov_base, (unsigned)iov->iov_len, 0) == 0)
+               return (EFAULT);
+       enpcopy((u_char *)&addr->enp_ram[uio->uio_offset],
+           (u_char *)iov->iov_base, (u_int)iov->iov_len);
        uio->uio_resid -= iov->iov_len;
        iov->iov_len = 0;
        return (0);
        uio->uio_resid -= iov->iov_len;
        iov->iov_len = 0;
        return (0);
@@ -755,7 +614,6 @@ enpr_write(dev, uio)
 {
        register struct enpdevice *addr;
        register struct iovec *iov;
 {
        register struct enpdevice *addr;
        register struct iovec *iov;
-       register error;
 
        addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr;
        iov = uio->uio_iov;
 
        addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr;
        iov = uio->uio_iov;
@@ -763,42 +621,48 @@ enpr_write(dev, uio)
                return (ENODEV);
        if (uio->uio_offset + iov->iov_len > RAM_SIZE)
                iov->iov_len = RAM_SIZE - uio->uio_offset;
                return (ENODEV);
        if (uio->uio_offset + iov->iov_len > RAM_SIZE)
                iov->iov_len = RAM_SIZE - uio->uio_offset;
-       error =  useracc(iov->iov_base, iov->iov_len, 1);
-       if (error)
-               return (error);
-       enpcopy(iov->iov_base, &addr->enp_ram[uio->uio_offset], iov->iov_len);
+       if (useracc(iov->iov_base, (unsigned)iov->iov_len, 1) == 0)
+               return (EFAULT);
+       enpcopy((u_char *)iov->iov_base,
+           (u_char *)&addr->enp_ram[uio->uio_offset], (u_int)iov->iov_len);
        uio->uio_resid -= iov->iov_len;
        iov->iov_len = 0;
        return (0);
 }
 
        uio->uio_resid -= iov->iov_len;
        iov->iov_len = 0;
        return (0);
 }
 
+/*ARGSUSED*/
 enpr_ioctl(dev, cmd, data)
        dev_t dev;
        caddr_t data;
 {
 enpr_ioctl(dev, cmd, data)
        dev_t dev;
        caddr_t data;
 {
-       register struct enpdevice *addr;
        register unit = ENPUNIT(dev);
        register unit = ENPUNIT(dev);
-       register struct vba_device *ui;
+       struct enpdevice *addr;
 
        addr = (struct enpdevice *)enpinfo[unit]->ui_addr;
        switch(cmd) {
 
        case ENPIOGO:
 
        addr = (struct enpdevice *)enpinfo[unit]->ui_addr;
        switch(cmd) {
 
        case ENPIOGO:
-/* not needed if prom based version */
-               addr->enp_base = (int)addr;
+               ENPSETLONG(&addr->enp_base, addr);
                addr->enp_intrvec = enp_softc[unit].es_ivec;
                ENP_GO(addr, ENPSTART);
                DELAY(200000);
                enpinit(unit);
                addr->enp_intrvec = enp_softc[unit].es_ivec;
                ENP_GO(addr, ENPSTART);
                DELAY(200000);
                enpinit(unit);
-               addr->enp_state = S_ENPRUN;  /* it is running now */
-/* end of not needed */
+               /*
+                * Fetch Ethernet address after link level
+                * is booted (firmware copies manufacturer's
+                * address from on-board ROM).
+                */
+               enpgetaddr(unit, addr);
+               addr->enp_state = S_ENPRUN;
                break;
 
        case ENPIORESET:
                RESET_ENP(addr);
                break;
 
        case ENPIORESET:
                RESET_ENP(addr);
-               addr->enp_state = S_ENPRESET;  /* it is reset now */
+               addr->enp_state = S_ENPRESET;
                DELAY(100000);
                break;
                DELAY(100000);
                break;
+       default:
+               return (EINVAL);
        }
        return (0);
 }
        }
        return (0);
 }