first working version of BSD/tahoe ex driver; checkpoint other
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Sun, 23 Apr 1989 03:17:07 +0000 (19:17 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Sun, 23 Apr 1989 03:17:07 +0000 (19:17 -0800)
drivers as of first working iso/tp4 connection & before gnodes

SCCS-vsn: sys/tahoe/if/if_enp.c 7.5
SCCS-vsn: sys/tahoe/if/if_ace.c 7.4
SCCS-vsn: sys/tahoe/if/if_ex.c 7.2
SCCS-vsn: sys/tahoe/if/if_vba.c 1.2
SCCS-vsn: sys/tahoe/if/if_exreg.h 7.2

usr/src/sys/tahoe/if/if_ace.c
usr/src/sys/tahoe/if/if_enp.c
usr/src/sys/tahoe/if/if_ex.c
usr/src/sys/tahoe/if/if_exreg.h
usr/src/sys/tahoe/if/if_vba.c

index 6305aec..fa7cc80 100644 (file)
@@ -17,7 +17,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_ace.c    7.3 (Berkeley) %G%
+ *     @(#)if_ace.c    7.4 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -146,7 +146,6 @@ aceattach(ui)
        register struct ifnet *ifp = &is->is_if;
        register struct acedevice *addr = (struct acedevice *)ui->ui_addr;
        register short *wp, i;
        register struct ifnet *ifp = &is->is_if;
        register struct acedevice *addr = (struct acedevice *)ui->ui_addr;
        register short *wp, i;
-       extern enoutput();
 
        ifp->if_unit = unit;
        ifp->if_name = "ace";
 
        ifp->if_unit = unit;
        ifp->if_name = "ace";
@@ -173,7 +172,7 @@ aceattach(ui)
        }
 
        ifp->if_init = aceinit;
        }
 
        ifp->if_init = aceinit;
-       ifp->if_output = enoutput;
+       ifp->if_output = ether_output;
        ifp->if_start = acestart;
        ifp->if_ioctl = aceioctl;
        ifp->if_reset = acereset;
        ifp->if_start = acestart;
        ifp->if_ioctl = aceioctl;
        ifp->if_reset = acereset;
@@ -455,6 +454,7 @@ setup:
 aceput(txbuf, m)
        char *txbuf;
        struct mbuf *m;
 aceput(txbuf, m)
        char *txbuf;
        struct mbuf *m;
+#ifdef notdef
 {
        register u_char *bp, *mcp;
        register short *s1, *s2;
 {
        register u_char *bp, *mcp;
        register short *s1, *s2;
@@ -464,7 +464,7 @@ aceput(txbuf, m)
 
        total = mp->m_pkthdr.len;
        bp = (u_char *)txbuf;
 
        total = mp->m_pkthdr.len;
        bp = (u_char *)txbuf;
-       for (mp = m; (mp); mp = mp->m_next) {
+       for (mp = m; mp; mp = mp->m_next) {
                len = mp->m_len;
                if (len == 0)
                        continue;
                len = mp->m_len;
                if (len == 0)
                        continue;
@@ -475,14 +475,53 @@ aceput(txbuf, m)
                        --len;
                }
                if (len > 1 && (((int)mcp & 01)==0) && (((int)bp & 01)==0)) {
                        --len;
                }
                if (len > 1 && (((int)mcp & 01)==0) && (((int)bp & 01)==0)) {
-                       int l = len;
+                       int l = len & 1;
 
                        s1 = (short *)bp;
                        s2 = (short *)mcp;
                        len >>= 1;              /* count # of shorts */
                        while (len-- != 0)
                                movow(s1++, *s2++);
 
                        s1 = (short *)bp;
                        s2 = (short *)mcp;
                        len >>= 1;              /* count # of shorts */
                        while (len-- != 0)
                                movow(s1++, *s2++);
-                       len = l & 1;            /* # remaining bytes */
+                       len = l;                /* # remaining bytes */
+                       bp = (u_char *)s1;
+                       mcp = (u_char *)s2;
+               }
+               while (len-- != 0)
+                       movob(bp++, *mcp++);
+       }
+       m_freem(m);
+       return (total);
+}
+#else
+{
+       register u_char *bp, *mcp;
+       register short *s1, *s2;
+       register u_int len;
+       register struct mbuf *mp;
+       int total;
+
+       total = 0;
+       bp = (u_char *)txbuf;
+       for (mp = m; (mp); mp = mp->m_next) {
+               len = mp->m_len;
+               if (len == 0)
+                       continue;
+               total += len;
+               mcp = mtod(mp, u_char *);
+               if (((int)mcp & 01) && ((int)bp & 01)) {
+                       /* source & destination at odd addresses */
+                       movob(bp++, *mcp++);
+                       --len;
+               }
+               if (len > 1 && (((int)mcp & 01)==0) && (((int)bp & 01)==0)) {
+                       register u_int l;
+
+                       s1 = (short *)bp;
+                       s2 = (short *)mcp;
+                       l = len >> 1;           /* count # of shorts */
+                       while (l-- != 0)
+                               movow(s1++, *s2++);
+                       len &= 1;               /* # remaining bytes */
                        bp = (u_char *)s1;
                        mcp = (u_char *)s2;
                }
                        bp = (u_char *)s1;
                        mcp = (u_char *)s2;
                }
@@ -492,6 +531,7 @@ aceput(txbuf, m)
        m_freem(m);
        return (total);
 }
        m_freem(m);
        return (total);
 }
+#endif
 
 /*
  * Routine to copy from VERSAbus memory into mbufs.
 
 /*
  * Routine to copy from VERSAbus memory into mbufs.
@@ -499,7 +539,6 @@ aceput(txbuf, m)
  * Warning: This makes the fairly safe assumption that
  * mbufs have even lengths.
  */
  * Warning: This makes the fairly safe assumption that
  * mbufs have even lengths.
  */
-/*ARGSUSED*/
 struct mbuf *
 aceget(rxbuf, totlen, off, ifp)
        u_char *rxbuf;
 struct mbuf *
 aceget(rxbuf, totlen, off, ifp)
        u_char *rxbuf;
@@ -628,7 +667,7 @@ aceioctl(ifp, cmd, data)
 
        case SIOCSIFADDR:
                ifp->if_flags |= IFF_UP;
 
        case SIOCSIFADDR:
                ifp->if_flags |= IFF_UP;
-               switch (ifa->ifa_addr.sa_family) {
+               switch (ifa->ifa_addr->sa_family) {
 #ifdef INET
                case AF_INET:
                        aceinit(ifp->if_unit);  /* before arpwhohas */
 #ifdef INET
                case AF_INET:
                        aceinit(ifp->if_unit);  /* before arpwhohas */
index e818caa..f3da6a3 100644 (file)
@@ -17,7 +17,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_enp.c    7.4 (Berkeley) %G%
+ *     @(#)if_enp.c    7.5 (Berkeley) %G%
  */
 
 #include "enp.h"
  */
 
 #include "enp.h"
@@ -129,7 +129,7 @@ enpattach(ui)
        ifp->if_mtu = ETHERMTU;
        ifp->if_init = enpinit;
        ifp->if_ioctl = enpioctl;
        ifp->if_mtu = ETHERMTU;
        ifp->if_init = enpinit;
        ifp->if_ioctl = enpioctl;
-       ifp->if_output = enoutput;
+       ifp->if_output = ether_output;
        ifp->if_start = enpstart;
        ifp->if_reset = enpreset;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
        ifp->if_start = enpstart;
        ifp->if_reset = enpreset;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
@@ -243,7 +243,7 @@ enpread(es, bcbp)
        m = enpget((u_char *)enp, len, off, &es->es_if);
        if (m == 0)
                return;
        m = enpget((u_char *)enp, len, off, &es->es_if);
        if (m == 0)
                return;
-       en_doproto(&es->es_if, enp, m);
+       ether_input(&es->es_if, enp, m);
 }
 
 enpstart(ifp)
 }
 
 enpstart(ifp)
@@ -417,7 +417,7 @@ enpioctl(ifp, cmd, data)
 
        case SIOCSIFADDR:
                ifp->if_flags |= IFF_UP;
 
        case SIOCSIFADDR:
                ifp->if_flags |= IFF_UP;
-               switch (ifa->ifa_addr.sa_family) {
+               switch (ifa->ifa_addr->sa_family) {
 #ifdef INET
                case AF_INET:
                        enpinit(ifp->if_unit);
 #ifdef INET
                case AF_INET:
                        enpinit(ifp->if_unit);
index 80dd4f1..2ece6f7 100644 (file)
@@ -17,7 +17,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_ex.c     7.1 (Berkeley) %G%
+ *     @(#)if_ex.c     7.2 (Berkeley) %G%
  */
 
 #include "ex.h"
  */
 
 #include "ex.h"
 #include "../netns/ns_if.h"
 #endif
 
 #include "../netns/ns_if.h"
 #endif
 
+#ifdef ISO
+#include "../netiso/iso.h"
+#include "../netiso/iso_var.h"
+#include "../netiso/iso_snpac.h"
+extern struct snpa_cache all_es, all_is;
+#endif 
+
 #include "../tahoe/cpu.h"
 #include "../tahoe/pte.h"
 #include "../tahoe/mtpr.h"
 #include "../tahoe/cpu.h"
 #include "../tahoe/pte.h"
 #include "../tahoe/mtpr.h"
@@ -111,32 +118,42 @@ struct    ex_softc {
        struct  ex_msg  *xs_h2xnext;    /* host pointer to request queue */
        struct  ex_msg  *xs_x2hnext;    /* host pointer to reply queue */
        u_long          xs_qbaddr;      /* map info for structs below */
        struct  ex_msg  *xs_h2xnext;    /* host pointer to request queue */
        struct  ex_msg  *xs_x2hnext;    /* host pointer to reply queue */
        u_long          xs_qbaddr;      /* map info for structs below */
+       struct  ex_shm  {
        /* the following structures are always mapped in */
        /* the following structures are always mapped in */
-       u_short         xs_h2xhdr;      /* EXOS's request queue header */
-       u_short         xs_x2hhdr;      /* EXOS's reply queue header */
-       struct ex_msg   xs_h2xent[NH2X];/* request msg buffers */
-       struct ex_msg   xs_x2hent[NX2H];/* reply msg buffers */
-       struct confmsg  xs_cm;          /* configuration message */
-       struct stat_array xs_xsa;       /* EXOS writes stats here */
+       u_short         sm_h2xhdr;      /* EXOS's request queue header */
+       u_short         sm_x2hhdr;      /* EXOS's reply queue header */
+       struct ex_msg   sm_h2xent[NH2X];/* request msg buffers */
+       struct ex_msg   sm_x2hent[NX2H];/* reply msg buffers */
+       struct ex_conf  sm_cm;          /* configuration message */
+       struct ex_stat  sm_xsa; /* EXOS writes stats here */
        /* end mapped area */
        /* end mapped area */
-#define        BUSADDR(x)      ((0x3D000000 | ((u_long)(kvtophys(x))&0xFFFFFF)) + busoff)
-#define        P_BUSADDR(x)    ((0x3D000000 | ((u_long)(kvtophys(x))&0xFFFFF0)) + busoff)
-#define        INCORE_BASE(p)  (((u_long)(&(p)->xs_h2xhdr)) & 0xFFFFFFF0)
-#define        RVAL_OFF(n)     ((u_long)(&(ex_softc[0].n)) - INCORE_BASE(&ex_softc[0]))
-#define        LVAL_OFF(n)     ((u_long)(ex_softc[0].n) - INCORE_BASE(&ex_softc[0]))
-#define        H2XHDR_OFFSET   RVAL_OFF(xs_h2xhdr)
-#define        X2HHDR_OFFSET   RVAL_OFF(xs_x2hhdr)
-#define        H2XENT_OFFSET   LVAL_OFF(xs_h2xent)
-#define        X2HENT_OFFSET   LVAL_OFF(xs_x2hent)
-#define        CM_OFFSET       RVAL_OFF(xs_cm)
-#define        SA_OFFSET       RVAL_OFF(xs_xsa)
-#define FreePkBuf(b) (((b)->iff_mbuf = (struct mbuf *)xs->xs_pkblist),\
-                                                       (xs->xs_pkblist = b))
+       }               *xs_shm;        /* host pointer to shared area */
+#define        xs_h2xhdr       xs_shm->sm_h2xhdr
+#define        xs_x2hhdr       xs_shm->sm_x2hhdr
+#define        xs_h2xent       xs_shm->sm_h2xent
+#define        xs_x2hent       xs_shm->sm_x2hent
+#define        xs_cm           xs_shm->sm_cm
+#define        xs_xsa          xs_shm->sm_xsa
+#define        BUSADDR(x)      (0x3D000000 | (((u_long)kvtophys(x))&0xFFFFFF))
+#define        P_BUSADDR(x)    (0x3D000000 | (((u_long)kvtophys(x))&0xFFFFF0))
+#define        INCORE_BASE(p)  (((u_long)(p)->xs_shm) & 0xFFFFFFF0)
+/* we will arrange that the shared memory begins on a 16 byte boundary */
+#define        RVAL_OFF(n)     (((char *)&(((struct ex_shm *)0)->n))-(char *)0)
+#define        LVAL_OFF(n)     (((char *)(((struct ex_shm *)0)->n))-(char *)0)
+#define        H2XHDR_OFFSET   RVAL_OFF(sm_h2xhdr)
+#define        X2HHDR_OFFSET   RVAL_OFF(sm_x2hhdr)
+#define        H2XENT_OFFSET   LVAL_OFF(sm_h2xent)
+#define        X2HENT_OFFSET   LVAL_OFF(sm_x2hent)
+#define        CM_OFFSET       RVAL_OFF(sm_cm)
+#define        SA_OFFSET       RVAL_OFF(sm_xsa)
        struct          ifvba xs_vbinfo[NVBI];/* Bus Resources (low core) */
        struct          ifvba *xs_pkblist; /* free list of above */
        struct          ifvba xs_vbinfo[NVBI];/* Bus Resources (low core) */
        struct          ifvba *xs_pkblist; /* free list of above */
+#define GetPkBuf(b, v)  ((v = (b)->mb_pkb = xs->xs_pkblist),\
+                     (xs->xs_pkblist = (struct ifvba *)(v)->iff_mbuf))
+#define FreePkBuf(v) (((v)->iff_mbuf = (struct mbuf *)xs->xs_pkblist),\
+                                                       (xs->xs_pkblist = v))
        char            xs_nrec;        /* number of pending receive buffers */
        char            xs_ntrb;        /* number of pending transmit buffers */
        char            xs_nrec;        /* number of pending receive buffers */
        char            xs_ntrb;        /* number of pending transmit buffers */
-       char            pad[6];         /* make BUSADDR macros */
 } ex_softc[NEX];
 
 int ex_padcheck = sizeof (struct ex_softc);
 } ex_softc[NEX];
 
 int ex_padcheck = sizeof (struct ex_softc);
@@ -149,7 +166,7 @@ exprobe(reg, vi)
        register struct exdevice *exaddr = (struct exdevice *)reg;
        int     i;
 
        register struct exdevice *exaddr = (struct exdevice *)reg;
        int     i;
 
-       if (badaddr(exaddr, 2))
+       if (badaddr((caddr_t)exaddr, 2))
                return 0;
        /*
         * Reset EXOS and run self-test (should complete within 2 seconds).
                return 0;
        /*
         * Reset EXOS and run self-test (should complete within 2 seconds).
@@ -190,8 +207,14 @@ exattach(ui)
        ifp->if_output = ether_output;
        ifp->if_reset = exreset;
        ifp->if_start = exstart;
        ifp->if_output = ether_output;
        ifp->if_reset = exreset;
        ifp->if_start = exstart;
+       ifp->if_flags = IFF_BROADCAST;
 
 
-       if (if_vbareserve(xs->xs_vbinfo, NVBI, EXMAXRBUF) == 0)
+       /*
+        * Note: extra memory gets returned by if_vbareserve()
+        * first, so, being page alligned, it is also 16-byte alligned.
+        */
+       if (if_vbareserve(xs->xs_vbinfo, NVBI, EXMAXRBUF,
+                       (caddr_t *)&xs->xs_shm, sizeof(*xs->xs_shm)) == 0)
                return;
        /*
         * Temporarily map queues in order to configure EXOS
                return;
        /*
         * Temporarily map queues in order to configure EXOS
@@ -210,9 +233,7 @@ exattach(ui)
        bp->mb_status |= MH_EXOS;
        movow(&exaddr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
        bp->mb_status |= MH_EXOS;
        movow(&exaddr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
-       do {
-               uncache(&bp->mb_status);
-       } while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
+       while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
        printf("ex%d: HW %c.%c NX %c.%c, hardware address %s\n",
                ui->ui_unit, xs->xs_cm.cm_vc[2], xs->xs_cm.cm_vc[3],
                xs->xs_cm.cm_vc[0], xs->xs_cm.cm_vc[1],
        printf("ex%d: HW %c.%c NX %c.%c, hardware address %s\n",
                ui->ui_unit, xs->xs_cm.cm_vc[2], xs->xs_cm.cm_vc[3],
                xs->xs_cm.cm_vc[0], xs->xs_cm.cm_vc[1],
@@ -276,9 +297,8 @@ int unit;
        bp->mb_status |= MH_EXOS;
        movow(&exaddr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
        bp->mb_status |= MH_EXOS;
        movow(&exaddr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
-       do {
-               uncache(&bp->mb_status);
-       } while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
+       while ((bp->mb_status & MH_OWNER) == MH_EXOS) /* poll for reply */
+               ;
        bp->mb_length = MBDATALEN;
        bp->mb_status |= MH_EXOS;               /* free up buffer */
        movow(&exaddr->ex_portb, EX_NTRUPT);
        bp->mb_length = MBDATALEN;
        bp->mb_status |= MH_EXOS;               /* free up buffer */
        movow(&exaddr->ex_portb, EX_NTRUPT);
@@ -292,6 +312,10 @@ int unit;
        xs->xs_flags |= EX_RUNNING;
        if (xs->xs_flags & EX_SETADDR)
                ex_setaddr((u_char *)0, unit);
        xs->xs_flags |= EX_RUNNING;
        if (xs->xs_flags & EX_SETADDR)
                ex_setaddr((u_char *)0, unit);
+#ifdef ISO
+       ex_setmulti(all_es.sc_snpa, unit, 1);
+       ex_setmulti(all_is.sc_snpa, unit, 2);
+#endif
        exstart(&ex_softc[unit].xs_if);         /* start transmits */
        splx(s);                /* are interrupts disabled here, anyway? */
 }
        exstart(&ex_softc[unit].xs_if);         /* start transmits */
        splx(s);                /* are interrupts disabled here, anyway? */
 }
@@ -307,7 +331,7 @@ int itype;
        register int unit = ui->ui_unit;
        register struct ex_softc *xs = &ex_softc[unit];
        register struct exdevice *exaddr = (struct exdevice *) ui->ui_addr;
        register int unit = ui->ui_unit;
        register struct ex_softc *xs = &ex_softc[unit];
        register struct exdevice *exaddr = (struct exdevice *) ui->ui_addr;
-       register struct confmsg *cm = &xs->xs_cm;
+       register struct ex_conf *cm = &xs->xs_cm;
        register struct ex_msg  *bp;
        register struct ifvba *pkb;
        int     i;
        register struct ex_msg  *bp;
        register struct ifvba *pkb;
        int     i;
@@ -381,7 +405,7 @@ int itype;
        xs->xs_nrec = 0;
        xs->xs_ntrb = 0;
        xs->xs_pkblist =  xs->xs_vbinfo + NVBI - 1;
        xs->xs_nrec = 0;
        xs->xs_ntrb = 0;
        xs->xs_pkblist =  xs->xs_vbinfo + NVBI - 1;
-       for (pkb = xs->xs_pkblist; pkb >= xs->xs_vbinfo; pkb--)
+       for (pkb = xs->xs_pkblist; pkb > xs->xs_vbinfo; pkb--)
                pkb->iff_mbuf = (struct mbuf *)(pkb - 1);
        xs->xs_vbinfo[0].iff_mbuf = 0;
 
                pkb->iff_mbuf = (struct mbuf *)(pkb - 1);
        xs->xs_vbinfo[0].iff_mbuf = 0;
 
@@ -428,8 +452,8 @@ struct ifnet *ifp;
        register struct mbuf *m;
         int len;
        register struct ifvba *pkb;
        register struct mbuf *m;
         int len;
        register struct ifvba *pkb;
-       struct mbuf *m0;
-       register int nb, tlen;
+       struct mbuf *m0 = 0;
+       register int nb = 0, tlen = 0;
        union l_util {
                u_long  l;
                struct  i86_long i;
        union l_util {
                u_long  l;
                struct  i86_long i;
@@ -453,18 +477,23 @@ struct ifnet *ifp;
                return;
        }
        xs->xs_ntrb++;
                return;
        }
        xs->xs_ntrb++;
-       bp->mb_pkb = pkb = xs->xs_pkblist;
-       xs->xs_pkblist = (struct ifvba *)pkb->iff_mbuf;
-       nb = 0; tlen = 0; m0 = 0;
+       GetPkBuf(bp, pkb);
        pkb->iff_mbuf = m;      /* save mbuf pointer to free when done */
        /*
         * point directly to the first group of mbufs to be transmitted. The
         * hardware can only support NFRAGMENTS descriptors.
         */
        while (m && ((nb < NFRAGMENTS-1) || (m->m_next == 0)) ) {
        pkb->iff_mbuf = m;      /* save mbuf pointer to free when done */
        /*
         * point directly to the first group of mbufs to be transmitted. The
         * hardware can only support NFRAGMENTS descriptors.
         */
        while (m && ((nb < NFRAGMENTS-1) || (m->m_next == 0)) ) {
-               l_util.l = BUSADDR(mtod(m, char *));
+               l_util.l = BUSADDR(mtod(m, caddr_t));
                bp->mb_et.et_blks[nb].bb_len = (u_short)m->m_len;
                bp->mb_et.et_blks[nb].bb_addr = l_util.i;
                bp->mb_et.et_blks[nb].bb_len = (u_short)m->m_len;
                bp->mb_et.et_blks[nb].bb_addr = l_util.i;
+               if (l_util.l + m->m_len > BUSADDR(VB_MAXADDR24)) {
+                       /* Here, the phys memory for the mbuf is out
+                          of range for the vmebus to talk to it */
+                       if (m == pkb->iff_mbuf)
+                               pkb->iff_mbuf = 0;
+                       break;
+               }
                tlen += m->m_len;
                m0 = m;
                m = m->m_next;
                tlen += m->m_len;
                m0 = m;
                m = m->m_next;
@@ -482,7 +511,11 @@ struct ifnet *ifp;
         * transmit interrupt.
         */
        if (m) {
         * transmit interrupt.
         */
        if (m) {
-               len = if_vbaput(pkb->iff_buffer, m);
+               if (m == pkb->iff_mbuf) {
+                       printf("ex%d: exstart insanity\n", unit);
+                       pkb->iff_mbuf = 0;
+               }
+               len = if_vbaput(pkb->iff_buffer, m, 0);
                l_util.l = BUSADDR(pkb->iff_buffer);
                bp->mb_et.et_blks[nb].bb_len = (u_short)len;
                bp->mb_et.et_blks[nb].bb_addr = l_util.i;
                l_util.l = BUSADDR(pkb->iff_buffer);
                bp->mb_et.et_blks[nb].bb_len = (u_short)len;
                bp->mb_et.et_blks[nb].bb_addr = l_util.i;
@@ -491,12 +524,18 @@ struct ifnet *ifp;
        }
 
        /*
        }
 
        /*
-        * If the total length of the packet is too small, pad the last frag
+        * If the total length of the packet is too small,
+        * pad the last fragment.  (May run into very obscure problems)
         */
         */
-       if (tlen - sizeof(struct ether_header) < ETHERMIN) {
+       if (tlen < sizeof(struct ether_header) + ETHERMIN) {
                len = (ETHERMIN + sizeof(struct ether_header)) - tlen;
                bp->mb_et.et_blks[nb-1].bb_len += (u_short)len;
                tlen += len;
                len = (ETHERMIN + sizeof(struct ether_header)) - tlen;
                bp->mb_et.et_blks[nb-1].bb_len += (u_short)len;
                tlen += len;
+#ifdef notdef
+                if (l_util.l + m->m_len > BUSADDR(VB_MAXADDR24)) {
+                       must copy last frag into private buffer
+               }
+#endif
        }
 
        /* set number of fragments in descriptor */
        }
 
        /* set number of fragments in descriptor */
@@ -515,13 +554,15 @@ exintr(unit)
        register struct ex_msg *bp = xs->xs_x2hnext;
        struct vba_device *ui = exinfo[unit];
        struct exdevice *exaddr = (struct exdevice *)ui->ui_addr;
        register struct ex_msg *bp = xs->xs_x2hnext;
        struct vba_device *ui = exinfo[unit];
        struct exdevice *exaddr = (struct exdevice *)ui->ui_addr;
+       struct ex_msg *next_bp;
 
 
-       uncache(&bp->mb_status);
        while ((bp->mb_status & MH_OWNER) == MH_HOST) {
                switch (bp->mb_rqst) {
                    case LLRECEIVE:
        while ((bp->mb_status & MH_OWNER) == MH_HOST) {
                switch (bp->mb_rqst) {
                    case LLRECEIVE:
-                       if (--xs->xs_nrec < 0)
+                       if (--xs->xs_nrec < 0) {
+                               printf("ex%d: internal receive check\n", unit);
                                xs->xs_nrec = 0;
                                xs->xs_nrec = 0;
+                       }
                        exrecv(unit, bp);
                        FreePkBuf(bp->mb_pkb);
                        bp->mb_pkb = (struct ifvba *)0;
                        exrecv(unit, bp);
                        FreePkBuf(bp->mb_pkb);
                        bp->mb_pkb = (struct ifvba *)0;
@@ -530,10 +571,12 @@ exintr(unit)
 
                    case LLTRANSMIT:
                    case LLRTRANSMIT:
 
                    case LLTRANSMIT:
                    case LLRTRANSMIT:
-                       if (--xs->xs_ntrb < 0)
+                       if (--xs->xs_ntrb < 0) {
+                               printf("ex%d: internal transmit check\n", unit);
                                xs->xs_ntrb = 0;
                                xs->xs_ntrb = 0;
+                       }
                        xs->xs_if.if_opackets++;
                        xs->xs_if.if_opackets++;
-                       if (bp->mb_rply == LL_OK)
+                       if (bp->mb_rply == LL_OK || bp->mb_rply == LLXM_NSQE)
                                ;
                        else if (bp->mb_rply & LLXM_1RTRY)
                                xs->xs_if.if_collisions++;
                                ;
                        else if (bp->mb_rply & LLXM_1RTRY)
                                xs->xs_if.if_collisions++;
@@ -549,23 +592,31 @@ exintr(unit)
                        }
                        FreePkBuf(bp->mb_pkb);
                        bp->mb_pkb = (struct ifvba *)0;
                        }
                        FreePkBuf(bp->mb_pkb);
                        bp->mb_pkb = (struct ifvba *)0;
-                       exstart(&ex_softc[unit].xs_if);
+                       exstart(&xs->xs_if);
                        exhangrcv(unit);
                        break;
 
                    case LLNET_STSTCS:
                        xs->xs_if.if_ierrors += xs->xs_xsa.sa_crc;
                        xs->xs_flags &= ~EX_STATPENDING;
                        exhangrcv(unit);
                        break;
 
                    case LLNET_STSTCS:
                        xs->xs_if.if_ierrors += xs->xs_xsa.sa_crc;
                        xs->xs_flags &= ~EX_STATPENDING;
+                   case LLNET_ADDRS:
+                   case LLNET_RECV:
+                       if (bp->mb_rply == LL_OK || bp->mb_rply == LLXM_NSQE)
+                               ;
+                       else
+                               printf("ex%d: %s, request 0x%x, reply 0x%x\n",
+                                 unit, "unsucessful stat or address change",
+                                 bp->mb_rqst, bp->mb_rply);
                        break;
 
                    default:
                        printf("ex%d: unknown reply 0x%x", unit, bp->mb_rqst);
                }
                bp->mb_length = MBDATALEN;
                        break;
 
                    default:
                        printf("ex%d: unknown reply 0x%x", unit, bp->mb_rqst);
                }
                bp->mb_length = MBDATALEN;
+               next_bp = bp->mb_next;
                bp->mb_status |= MH_EXOS;       /* free up buffer */
                bp->mb_status |= MH_EXOS;       /* free up buffer */
+               bp = next_bp;                   /* paranoia about race */
                movow(&exaddr->ex_portb, EX_NTRUPT); /* tell EXOS about it */
                movow(&exaddr->ex_portb, EX_NTRUPT); /* tell EXOS about it */
-               bp = bp->mb_next;
-               uncache(&bp->mb_status);
        }
        xs->xs_x2hnext = bp;
 }
        }
        xs->xs_x2hnext = bp;
 }
@@ -583,7 +634,6 @@ int req;
        int s = splimp();
 
        bp = xs->xs_h2xnext;
        int s = splimp();
 
        bp = xs->xs_h2xnext;
-       uncache(&bp->mb_status);
        if ((bp->mb_status & MH_OWNER) == MH_EXOS) {
                splx(s);
                return (struct ex_msg *)0;
        if ((bp->mb_status & MH_OWNER) == MH_EXOS) {
                splx(s);
                return (struct ex_msg *)0;
@@ -681,9 +731,8 @@ exhangrcv(unit)
                if ((bp = exgetcbuf(xs, LLRECEIVE)) == (struct ex_msg *)0) {
                        break;
                }
                if ((bp = exgetcbuf(xs, LLRECEIVE)) == (struct ex_msg *)0) {
                        break;
                }
-               pkb = bp->mb_pkb = xs->xs_pkblist;
-               xs->xs_pkblist = (struct ifvba *)bp->mb_pkb->iff_mbuf;
-
+               GetPkBuf(bp, pkb);
+               pkb->iff_mbuf = 0;
                xs->xs_nrec += 1;
                bp->mb_er.er_nblock = 1;
                bp->mb_er.er_blks[0].bb_len = EXMAXRBUF;
                xs->xs_nrec += 1;
                bp->mb_er.er_nblock = 1;
                bp->mb_er.er_blks[0].bb_len = EXMAXRBUF;
@@ -797,44 +846,51 @@ ex_setaddr(physaddr, unit)
        int unit;
 {
        register struct ex_softc *xs = &ex_softc[unit];
        int unit;
 {
        register struct ex_softc *xs = &ex_softc[unit];
-       struct vba_device *ui = exinfo[unit];
-       register struct exdevice *addr= (struct exdevice *)ui->ui_addr;
-       register struct ex_msg *bp;
        
        if (physaddr) {
                xs->xs_flags |= EX_SETADDR;
                bcopy((caddr_t)physaddr, (caddr_t)xs->xs_addr, 6);
        }
        
        if (physaddr) {
                xs->xs_flags |= EX_SETADDR;
                bcopy((caddr_t)physaddr, (caddr_t)xs->xs_addr, 6);
        }
-       if (! (xs->xs_flags & EX_RUNNING))
+       ex_setmulti((u_char *)xs->xs_addr, unit, PHYSSLOT);
+}
+
+/*
+ * Enable multicast reception for unit.
+ */
+ex_setmulti(linkaddr, unit, slot)
+       u_char *linkaddr;
+       int unit, slot;
+{
+       register struct ex_softc *xs = &ex_softc[unit];
+       struct vba_device *ui = exinfo[unit];
+       register struct exdevice *addr= (struct exdevice *)ui->ui_addr;
+       register struct ex_msg *bp;
+       
+       if (!(xs->xs_flags & EX_RUNNING))
                return;
                return;
-       bp = exgetcbuf(xs);
-       bp->mb_rqst = LLNET_ADDRS;
+       bp = exgetcbuf(xs, LLNET_ADDRS);
        bp->mb_na.na_mask = READ_OBJ|WRITE_OBJ;
        bp->mb_na.na_mask = READ_OBJ|WRITE_OBJ;
-       bp->mb_na.na_slot = PHYSSLOT;
-       bcopy((caddr_t)xs->xs_addr, (caddr_t)bp->mb_na.na_addrs, 6);
+       bp->mb_na.na_slot = slot;
+       bcopy((caddr_t)linkaddr, (caddr_t)bp->mb_na.na_addrs, 6);
        bp->mb_status |= MH_EXOS;
        movow(&addr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
        bp->mb_status |= MH_EXOS;
        movow(&addr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
-       do {
-               uncache(&bp->mb_status);
-       } while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
+       while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
 #ifdef DEBUG
 #ifdef DEBUG
-       log(LOG_DEBUG, "ex%d: reset addr %s\n", ui->ui_unit,
-               ether_sprintf(bp->mb_na.na_addrs));
+       log(LOG_DEBUG, "ex%d: %s %s (slot %d)\n", unit,
+               (slot == PHYSSLOT ? "reset addr" : "add multicast"
+               ether_sprintf(bp->mb_na.na_addrs), slot);
 #endif
        /*
 #endif
        /*
-        * Now, re-enable reception on phys slot.
+        * Now, re-enable reception on slot.
         */
         */
-       bp = exgetcbuf(xs);
-       bp->mb_rqst = LLNET_RECV;
+       bp = exgetcbuf(xs, LLNET_RECV);
        bp->mb_nr.nr_mask = ENABLE_RCV|READ_OBJ|WRITE_OBJ;
        bp->mb_nr.nr_mask = ENABLE_RCV|READ_OBJ|WRITE_OBJ;
-       bp->mb_nr.nr_slot = PHYSSLOT;
+       bp->mb_nr.nr_slot = slot;
        bp->mb_status |= MH_EXOS;
        movow(&addr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
        bp->mb_status |= MH_EXOS;
        movow(&addr->ex_portb, EX_NTRUPT);
        bp = xs->xs_x2hnext;
-       do {
-               uncache(&bp->mb_status);
-       } while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
+       while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
                ;
 }
 #endif
                ;
 }
 #endif
index 36db058..ab47e20 100644 (file)
@@ -17,7 +17,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_exreg.h  7.1 (Berkeley) %G%
+ *     @(#)if_exreg.h  7.2 (Berkeley) %G%
  */
 
 struct exdevice {
  */
 
 struct exdevice {
@@ -61,7 +61,8 @@ struct exdevice {
 #define        LLXM_NCS        0x20    /* xmission failed, no carrier sense */
 #define        LLXM_LNGTH      0x40    /* xmission failed, bad packet length */
 #define        XMIT_BITS       "\7\7LENGTH\6CARRIER\5XCLSNS\4SQETST"
 #define        LLXM_NCS        0x20    /* xmission failed, no carrier sense */
 #define        LLXM_LNGTH      0x40    /* xmission failed, bad packet length */
 #define        XMIT_BITS       "\7\7LENGTH\6CARRIER\5XCLSNS\4SQETST"
-#define        LLXM_ERROR      (LLXM_NSQE|LLXM_CLSN|LLXM_NCS|LLXM_LNGTH)
+/*#define      LLXM_ERROR      (LLXM_NSQE|LLXM_CLSN|LLXM_NCS|LLXM_LNGTH)*/
+#define        LLXM_ERROR      (LLXM_CLSN|LLXM_NCS|LLXM_LNGTH)
 
 /* LLRECEIVE unique return codes */
 #define        LLRC_TRUNC      0x4     /* pkt received, but truncated to fit buffer */
 
 /* LLRECEIVE unique return codes */
 #define        LLRC_TRUNC      0x4     /* pkt received, but truncated to fit buffer */
@@ -103,11 +104,7 @@ struct exdevice {
 #define        MODE_HW         2       /* hardware-only multicast address filtering */
 #define        MODE_PROM       3       /* promiscuous reception */
 
 #define        MODE_HW         2       /* hardware-only multicast address filtering */
 #define        MODE_PROM       3       /* promiscuous reception */
 
-#ifdef  NEWEX
 #define        NFRAGMENTS 8    /* number fragments that the EXOS will scatter/gather */
 #define        NFRAGMENTS 8    /* number fragments that the EXOS will scatter/gather */
-#else  NEWEX
-#define        NFRAGMENTS 1    /* number fragments that the EXOS will scatter/gather */
-#endif  NEWEX
 #define        EXMAXRBUF 1518  /* per EXOS 202 manual 5.3.7 (maybe 1518 would do) */
 
 /*
 #define        EXMAXRBUF 1518  /* per EXOS 202 manual 5.3.7 (maybe 1518 would do) */
 
 /*
@@ -117,7 +114,7 @@ struct exdevice {
  * padding.  Be especially careful about VAX C longword alignment!
  */
 
  * padding.  Be especially careful about VAX C longword alignment!
  */
 
-struct stat_array {
+struct ex_stat {
        u_long  sa_fsent;       /* frames sent without errors */
        u_long  sa_xsclsn;      /* frames aborted excess collisions */
        u_long  sa_nsqe;        /* frames subject to heartbeat failure */
        u_long  sa_fsent;       /* frames sent without errors */
        u_long  sa_xsclsn;      /* frames aborted excess collisions */
        u_long  sa_nsqe;        /* frames subject to heartbeat failure */
@@ -223,7 +220,7 @@ struct      ex_msg {
 #define        mb_rply mb_nm.nm_rply
 #define        MBDATALEN (sizeof(union mb_all)+6)
 
 #define        mb_rply mb_nm.nm_rply
 #define        MBDATALEN (sizeof(union mb_all)+6)
 
-struct confmsg {
+struct ex_conf {
 /*00*/ u_short cm_1rsrv;       /* reserved, must be 1 */
 /*02*/ char    cm_vc[4];       /* returns ASCII version code */
 /*06*/ u_char  cm_cc;          /* returns config completion code */
 /*00*/ u_short cm_1rsrv;       /* reserved, must be 1 */
 /*02*/ char    cm_vc[4];       /* returns ASCII version code */
 /*06*/ u_char  cm_cc;          /* returns config completion code */
index c09d84b..51df8f7 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)if_vba.c    1.1 (Berkeley) %G%
+ *     @(#)if_vba.c    1.2 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
 
 #include "if_vba.h"
 
 
 #include "if_vba.h"
 
-if_vbareserve(ifvba0, n, size)
+if_vbareserve(ifvba0, n, bufsize, extra, extrasize)
 struct ifvba *ifvba0;
 register int n;
 struct ifvba *ifvba0;
 register int n;
-int size;
+int bufsize;
+caddr_t *extra;
+int extrasize;
 {
        register caddr_t cp;
        register struct pte *pte;
        register struct ifvba *ifvba = ifvba0;
        struct ifvba *vlim  = ifvba + n;
 
 {
        register caddr_t cp;
        register struct pte *pte;
        register struct ifvba *ifvba = ifvba0;
        struct ifvba *vlim  = ifvba + n;
 
-       n = roundup(n * size, NBPG);
+       n = roundup(extrasize + (n * bufsize), NBPG);
        cp = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT);
        cp = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT);
+       if ((n + kvtophys(cp)) > VB_MAXADDR24) {
+               free(cp, M_DEVBUF);
+               cp = 0;
+       }
        if (cp == 0) {
        if (cp == 0) {
-               printf("No memory for device buffer\n");
+               printf("No memory for device buffer(s)\n");
                return (0);
        }
        /*
                return (0);
        }
        /*
@@ -59,10 +65,14 @@ int size;
        for (n = btoc(n); n--; pte++)
                pte->pg_nc = 1;
        mtpr(TBIA, 0);
        for (n = btoc(n); n--; pte++)
                pte->pg_nc = 1;
        mtpr(TBIA, 0);
+       if (extra) {
+               *extra = cp;
+               cp += extrasize;
+       }
        for (; ifvba < vlim; ifvba++) {
                ifvba->iff_buffer = cp;
                ifvba->iff_physaddr = kvtophys(cp);
        for (; ifvba < vlim; ifvba++) {
                ifvba->iff_buffer = cp;
                ifvba->iff_physaddr = kvtophys(cp);
-               cp += size;
+               cp += bufsize;
        }
        return (1);
 }
        }
        return (1);
 }
@@ -74,15 +84,15 @@ int size;
  */
 struct mbuf *
 if_vbaget(rxbuf, totlen, off, ifp, flags)
  */
 struct mbuf *
 if_vbaget(rxbuf, totlen, off, ifp, flags)
-       u_char *rxbuf;
+       caddr_t rxbuf;
        int totlen, off, flags;
        struct ifnet *ifp;
 {
        int totlen, off, flags;
        struct ifnet *ifp;
 {
-       register u_char *cp;
+       register caddr_t cp;
        register struct mbuf *m;
        struct mbuf *top = 0, **mp = &top;
        int len;
        register struct mbuf *m;
        struct mbuf *top = 0, **mp = &top;
        int len;
-       u_char *packet_end;
+       caddr_t packet_end;
 
        rxbuf += sizeof (struct ether_header);
        cp = rxbuf;
 
        rxbuf += sizeof (struct ether_header);
        cp = rxbuf;
@@ -128,9 +138,9 @@ if_vbaget(rxbuf, totlen, off, ifp, flags)
                                len = m->m_len;
                }
                if (flags)
                                len = m->m_len;
                }
                if (flags)
-                       if_vba16copy(cp, mtod(m, u_char *), (u_int)len);
+                       if_vba16copy(cp, mtod(m, caddr_t), (u_int)len);
                else
                else
-                       bcopy(cp, mtod(m, u_char *), (u_int)len);
+                       bcopy(cp, mtod(m, caddr_t), (u_int)len);
 
                *mp = m;
                mp = &m->m_next;
 
                *mp = m;
                mp = &m->m_next;
@@ -143,17 +153,17 @@ if_vbaget(rxbuf, totlen, off, ifp, flags)
 }
 
 if_vbaput(ifu, m0, flags)
 }
 
 if_vbaput(ifu, m0, flags)
-register u_char *ifu;
-register struct mbuf *m0;
+caddr_t ifu;
+struct mbuf *m0;
 {
        register struct mbuf *m = m0;
 {
        register struct mbuf *m = m0;
-       register u_char *cp = ifu;
+       register caddr_t cp = ifu;
 
        while (m) {
                if (flags)
 
        while (m) {
                if (flags)
-                       if_vba16copy(mtod(m, u_char *), cp, m->m_len);
+                       if_vba16copy(mtod(m, caddr_t), cp, (u_int)m->m_len);
                else
                else
-                       bcopy(mtod(m, u_char *), cp, m->m_len);
+                       bcopy(mtod(m, caddr_t), cp, (u_int)m->m_len);
                cp += m->m_len;
                MFREE(m, m0);
                m = m0;
                cp += m->m_len;
                MFREE(m, m0);
                m = m0;
@@ -164,8 +174,8 @@ register struct mbuf *m0;
 }
 
 if_vba16copy(from, to, cnt)
 }
 
 if_vba16copy(from, to, cnt)
-       register u_char *from, *to;
-       register u_int cnt;
+       register caddr_t from, to;
+       register unsigned cnt;
 {
        register c;
        register short *f, *t;
 {
        register c;
        register short *f, *t;
@@ -182,8 +192,8 @@ if_vba16copy(from, to, cnt)
                        *t++ = *f++;
                cnt &= 1;
                if (cnt) {                      /* odd len */
                        *t++ = *f++;
                cnt &= 1;
                if (cnt) {                      /* odd len */
-                       from = (u_char *)f;
-                       to = (u_char *)t;
+                       from = (caddr_t)f;
+                       to = (caddr_t)t;
                        *to = *from;
                }
        }
                        *to = *from;
                }
        }