BSD 4_3_Reno release
[unix-history] / usr / src / sys / tahoeif / if_ex.c
index 6d6e565..8812418 100644 (file)
@@ -1,8 +1,3 @@
-/*
- * This file is derived from a number of files, as denoted below,
- * to create an Excelan driver compatible with the 4.3BSD-tahoe release.
- */
-
 /*
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
 /*
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  * This code is derived from software contributed to Berkeley by
  * Excelan Inc.
  *
  * This code is derived from software contributed to Berkeley by
  * Excelan 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement:  This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software.  Neither the name of the University nor the names of
+ * its contributors may 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
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  *
- *     @(#)if_ex.c     7.2 (Berkeley) 4/22/89
+ *     @(#)if_ex.c     7.4 (Berkeley) 6/28/90
  */
 
 #include "ex.h"
  */
 
 #include "ex.h"
@@ -35,7 +33,6 @@
 #include "param.h"
 #include "systm.h"
 #include "mbuf.h"
 #include "param.h"
 #include "systm.h"
 #include "mbuf.h"
-#include "malloc.h"
 #include "buf.h"
 #include "protosw.h"
 #include "socket.h"
 #include "buf.h"
 #include "protosw.h"
 #include "socket.h"
 #include "../netns/ns_if.h"
 #endif
 
 #include "../netns/ns_if.h"
 #endif
 
+#ifdef ISO
+#include "../netiso/iso.h"
+#include "../netiso/iso_var.h"
+extern char all_es_snpa[], all_is_snpa[];
+#endif 
+
 #include "../tahoe/cpu.h"
 #include "../tahoe/pte.h"
 #include "../tahoe/mtpr.h"
 
 #include "../tahoevba/vbavar.h"
 #include "if_exreg.h"
 #include "../tahoe/cpu.h"
 #include "../tahoe/pte.h"
 #include "../tahoe/mtpr.h"
 
 #include "../tahoevba/vbavar.h"
 #include "if_exreg.h"
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     @(#)if_vba.h    1.1 (Berkeley) 3/9/89
- */
-
-struct ifvba {
-       struct  mbuf *iff_mbuf; /* associated mbuf to free */
-       caddr_t iff_buffer;     /* contiguous memory for data, kernel address */
-       u_long  iff_physaddr;   /* contiguous memory for data, phys address */
-};
-
-
-#ifdef KERNEL
-struct mbuf *if_vbaget();
-#endif
-
+#include "if_vba.h"
 
 
 #define        NH2X 32                 /* Host to eXcelan request buffers */
 
 
 #define        NH2X 32                 /* Host to eXcelan request buffers */
@@ -118,7 +92,7 @@ long exstd[] = { 0 };
 
 struct vba_driver exdriver =
        { exprobe, 0, exattach, exstart, exstd, "ex", exinfo };
 
 struct vba_driver exdriver =
        { exprobe, 0, exattach, exstart, exstd, "ex", exinfo };
-int    exinit(),exoutput(),exioctl(),exreset(),exwatch();
+int    exinit(),ether_output(),exioctl(),exreset(),exwatch();
 struct ex_msg *exgetcbuf();
 int    ex_ncall = 0;                   /* counts calls to exprobe */
 u_long busoff;
 struct ex_msg *exgetcbuf();
 int    ex_ncall = 0;                   /* counts calls to exprobe */
 u_long busoff;
@@ -232,8 +206,9 @@ exattach(ui)
        ifp->if_mtu = ETHERMTU;
        ifp->if_init = exinit;
        ifp->if_ioctl = exioctl;
        ifp->if_mtu = ETHERMTU;
        ifp->if_init = exinit;
        ifp->if_ioctl = exioctl;
-       ifp->if_output = exoutput;
+       ifp->if_output = ether_output;
        ifp->if_reset = exreset;
        ifp->if_reset = exreset;
+       ifp->if_start = exstart;
        ifp->if_flags = IFF_BROADCAST;
 
        /*
        ifp->if_flags = IFF_BROADCAST;
 
        /*
@@ -339,6 +314,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_snpa, unit, 1);
+       ex_setmulti(all_is_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? */
 }
@@ -538,7 +517,7 @@ struct ifnet *ifp;
                        printf("ex%d: exstart insanity\n", unit);
                        pkb->iff_mbuf = 0;
                }
                        printf("ex%d: exstart insanity\n", unit);
                        pkb->iff_mbuf = 0;
                }
-               len = if_vbaput(pkb->iff_buffer, m);
+               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;
@@ -683,9 +662,8 @@ register struct ex_msg *bp;
        register struct ex_softc *xs = &ex_softc[unit];
        register struct ether_header *eh;
        register struct mbuf *m;
        register struct ex_softc *xs = &ex_softc[unit];
        register struct ether_header *eh;
        register struct mbuf *m;
-       register struct ifqueue *inq;
        int len, off, resid;
        int len, off, resid;
-       struct ifnet *ifp = &xs->xs_if;
+       register struct ifqueue *inq;
        int s;
 
        xs->xs_if.if_ipackets++;
        int s;
 
        xs->xs_if.if_ipackets++;
@@ -726,45 +704,10 @@ register struct ex_msg *bp;
         * 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, but we still have to drop
         * the type and length which are at the front of any trailer data.
         */
-       m = if_vbaget(bp->mb_pkb->iff_buffer, len, off, ifp);
+       m = if_vbaget(bp->mb_pkb->iff_buffer, len, off, &xs->xs_if, 0);
        if (m == 0)
                return;
        if (m == 0)
                return;
-       if (off) {
-               m->m_off += 2 * sizeof (u_short);
-               m->m_len -= 2 * sizeof (u_short);
-               *(mtod(m, struct ifnet **)) = ifp;
-       }
-
-       switch (eh->ether_type) {
-#ifdef INET
-       case ETHERTYPE_IP:
-               schednetisr(NETISR_IP);
-               inq = &ipintrq;
-               break;
-
-       case ETHERTYPE_ARP:
-               arpinput((struct arpcom *)ifp, m);
-               return;
-#endif
-#ifdef NS
-       case ETHERTYPE_NS:
-               schednetisr(NETISR_NS);
-               inq = &nsintrq;
-               break;
-
-#endif
-       default:
-               m_freem(m);
-               return;
-       }
-
-       s = splimp();
-       if (IF_QFULL(inq)) {
-               IF_DROP(inq);
-               m_freem(m);
-       } else
-               IF_ENQUEUE(inq, m);
-       splx(s);
+       ether_input(&xs->xs_if, eh, m);
        return;
 }
 
        return;
 }
 
@@ -806,132 +749,9 @@ exhangrcv(unit)
 }
 
 /*
 }
 
 /*
- * Ethernet output routine.
- * 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.
- * Assumes that ifp is actually pointer to arpcom structure.
+ * Ethernet output routine is ether_output().
  */
 
  */
 
-exoutput(ifp, m0, dst)
-       register struct ifnet *ifp;
-       struct mbuf *m0;
-       struct sockaddr *dst;
-{
-       short type;
-       int s, error = 0;
-       u_char edst[6];
-       struct in_addr idst;
-       register struct mbuf *m = m0;
-       struct mbuf *mcopy = 0;
-       register struct ether_header *eh;
-       int usetrailers, off = 0, totlen;
-#define        ac ((struct arpcom *)ifp)
-
-       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(ac, m, &idst, edst, &usetrailers))
-                       return (0);     /* if not yet resolved */
-               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 *) = htons((u_short)ETHERTYPE_IP);
-                       *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
-                       goto gottrailertype;
-               }
-               type = ETHERTYPE_IP;
-               goto gottype;
-#endif
-#ifdef NS
-       case AF_NS:
-               type = ETHERTYPE_NS;
-               bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
-                   (caddr_t)edst, sizeof (edst));
-               goto gottype;
-#endif
-       case AF_UNSPEC:
-               eh = (struct ether_header *)dst->sa_data;
-               bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
-               type = eh->ether_type;
-               goto gottype;
-
-       default:
-               printf("%s%d: can't handle af%d\n", ifp->if_name, 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);
-       }
-       eh = mtod(m, struct ether_header *);
-       type = htons((u_short)type);
-       bcopy((caddr_t)&type,(caddr_t)&eh->ether_type,
-               sizeof(eh->ether_type));
-       bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
-       bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
-           sizeof(eh->ether_shost));
-       /*
-        * Queue message on interface, and start output if interface
-        * not yet active.
-        */
-       s = splimp();
-       if (IF_QFULL(&ifp->if_snd)) {
-               IF_DROP(&ifp->if_snd);
-               splx(s);
-               error = ENOBUFS;
-               goto bad;
-       }
-       IF_ENQUEUE(&ifp->if_snd, m);
-       error = exstart(ifp);
-       splx(s);
-       return (error);
-
-bad:
-       if (m)
-               m_freem(m);
-       return (error);
-}
-
 /*
  * Watchdog routine (currently not used). Might use this to get stats from EXOS.
  */
 /*
  * Watchdog routine (currently not used). Might use this to get stats from EXOS.
  */
@@ -979,7 +799,7 @@ exioctl(ifp, cmd, data)
                 ifp->if_flags |= IFF_UP;
                 exinit(ifp->if_unit);
 
                 ifp->if_flags |= IFF_UP;
                 exinit(ifp->if_unit);
 
-                switch (ifa->ifa_addr.sa_family) {
+                switch (ifa->ifa_addr->sa_family) {
 #ifdef INET
                case AF_INET:
                        ((struct arpcom *)ifp)->ac_ipaddr =
 #ifdef INET
                case AF_INET:
                        ((struct arpcom *)ifp)->ac_ipaddr =
@@ -1075,169 +895,4 @@ ex_setmulti(linkaddr, unit, slot)
        while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
                ;
 }
        while ((bp->mb_status & MH_OWNER) == MH_EXOS);/* poll for reply */
                ;
 }
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     @(#)if_vba.c    1.2 (Berkeley) 4/22/89
- */
-
-#ifdef notdef
-#include "param.h"
-#include "systm.h"
-#include "mbuf.h"
-#include "buf.h"
-#include "cmap.h"
-#include "vmmac.h"
-#include "socket.h"
-
-#include "../tahoe/mtpr.h"
-#include "../tahoe/pte.h"
-
-#include "../tahoevba/vbavar.h"
-
-#include "../net/if.h"
-#include "../netinet/in.h"
-#include "../netinet/if_ether.h"
-#endif
-
-static
-if_vbareserve(ifvba0, n, bufsize, extra, extrasize)
-struct ifvba *ifvba0;
-register int n;
-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;
-
-       n = roundup(extrasize + (n * bufsize), NBPG);
-       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) {
-               printf("No memory for device buffer(s)\n");
-               return (0);
-       }
-       /*
-        * Make raw buffer pages uncacheable.
-        */
-       pte = kvtopte(cp);
-       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);
-               cp += bufsize;
-       }
-       return (1);
-}
-/*
- * Routine to copy from VERSAbus memory into mbufs.
- *
- * Warning: This makes the fairly safe assumption that
- * mbufs have even lengths.
- */
-static struct mbuf *
-if_vbaget(rxbuf, totlen, off0, ifp)
-       u_char *rxbuf;
-       int totlen, off0;
-       struct ifnet *ifp;
-{
-       register u_char *cp, *mcp;
-       register struct mbuf *m;
-       struct mbuf *top = 0, **mp = &top;
-       int len, off = off0;
-
-       cp = rxbuf + sizeof (struct ether_header);
-       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) {
-                       MCLGET(m);
-                       if (m->m_len == CLBYTES)
-                               m->m_len = len = MIN(len, CLBYTES);
-                       else
-                               m->m_len = len = MIN(MLEN, len);
-               } 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.
-                        */
-                       *(mtod(m, struct ifnet **)) = ifp;
-                       mcp += sizeof (ifp);
-                       len -= sizeof (ifp);
-                       ifp = (struct ifnet *)0;
-               }
-               bcopy(cp, mcp, (u_int)len);
-               cp += len;
-               *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;
-               }
-       }
-       return (top);
-bad:
-       m_freem(top);
-       return (0);
-}
-
-static
-if_vbaput(ifu, m0)
-caddr_t ifu;
-struct mbuf *m0;
-{
-       register struct mbuf *m = m0;
-       register caddr_t cp = ifu;
-
-       while (m) {
-               bcopy(mtod(m, caddr_t), cp, (u_int)m->m_len);
-               cp += m->m_len;
-               MFREE(m, m0);
-               m = m0;
-       }
-       if ((int)cp & 1)
-               *cp++ = 0;
-       return (cp - ifu);
-}
 #endif
 #endif