sun merge
[unix-history] / usr / src / sys / vax / if / if_il.c
index 6c1dc41..677401c 100644 (file)
@@ -1,35 +1,38 @@
-/*     if_il.c 4.9     82/06/23        */
+/*     if_il.c 4.17    82/12/17        */
 
 #include "il.h"
 
 /*
  * Interlan Ethernet Communications Controller interface
  */
 
 #include "il.h"
 
 /*
  * Interlan Ethernet Communications Controller interface
  */
+#include "../machine/pte.h"
+
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/mbuf.h"
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/mbuf.h"
-#include "../h/pte.h"
 #include "../h/buf.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/buf.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
-#include "../h/ubareg.h"
-#include "../h/ubavar.h"
-#include "../h/ilreg.h"
-#include "../h/cpu.h"
-#include "../h/mtpr.h"
 #include "../h/vmmac.h"
 #include "../h/vmmac.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
-#include "../net/if.h"
-#include "../net/if_il.h"
-#include "../net/if_uba.h"
-#include "../net/ip.h"
-#include "../net/ip_var.h"
-#include "../net/pup.h"
-#include "../net/route.h"
 #include <errno.h>
 
 #include <errno.h>
 
-#define        ILMTU   1500
+#include "../net/if.h"
+#include "../net/netisr.h"
+#include "../net/route.h"
+#include "../netinet/in.h"
+#include "../netinet/in_systm.h"
+#include "../netinet/ip.h"
+#include "../netinet/ip_var.h"
+#include "../netpup/pup.h"
+
+#include "../vax/cpu.h"
+#include "../vax/mtpr.h"
+#include "../vaxif/if_ether.h"
+#include "../vaxif/if_il.h"
+#include "../vaxif/if_ilreg.h"
+#include "../vaxif/if_uba.h"
+#include "../vaxuba/ubareg.h"
+#include "../vaxuba/ubavar.h"
 
 int    ilprobe(), ilattach(), ilrint(), ilcint();
 struct uba_device *ilinfo[NIL];
 
 int    ilprobe(), ilattach(), ilrint(), ilcint();
 struct uba_device *ilinfo[NIL];
@@ -78,7 +81,7 @@ ilprobe(reg)
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
-       ilrint(0); ilcint(0); ilwatch(0);
+       i = 0; ilrint(i); ilcint(i); ilwatch(i);
 #endif
 
        addr->il_csr = ILC_OFFLINE|IL_CIE;
 #endif
 
        addr->il_csr = ILC_OFFLINE|IL_CIE;
@@ -105,7 +108,7 @@ ilattach(ui)
 
        ifp->if_unit = ui->ui_unit;
        ifp->if_name = "il";
 
        ifp->if_unit = ui->ui_unit;
        ifp->if_name = "il";
-       ifp->if_mtu = ILMTU;
+       ifp->if_mtu = ETHERMTU;
        ifp->if_net = ui->ui_flags;
 
        /*
        ifp->if_net = ui->ui_flags;
 
        /*
@@ -119,7 +122,7 @@ ilattach(ui)
                printf("il%d: reset failed, csr=%b\n", ui->ui_unit,
                        addr->il_csr, IL_BITS);
        
                printf("il%d: reset failed, csr=%b\n", ui->ui_unit,
                        addr->il_csr, IL_BITS);
        
-       is->is_ubaddr = uballoc(ui->ui_ubanum, &is->is_stats,
+       is->is_ubaddr = uballoc(ui->ui_ubanum, (caddr_t)&is->is_stats,
                sizeof (struct il_stats), 0);
        addr->il_bar = is->is_ubaddr & 0xffff;
        addr->il_bcr = sizeof (struct il_stats);
                sizeof (struct il_stats), 0);
        addr->il_bar = is->is_ubaddr & 0xffff;
        addr->il_bcr = sizeof (struct il_stats);
@@ -151,7 +154,7 @@ ilattach(ui)
 
        ifp->if_init = ilinit;
        ifp->if_output = iloutput;
 
        ifp->if_init = ilinit;
        ifp->if_output = iloutput;
-       ifp->if_ubareset = ilreset;
+       ifp->if_reset = ilreset;
        ifp->if_watchdog = ilwatch;
        is->is_scaninterval = ILWATCHINTERVAL;
        ifp->if_timer = is->is_scaninterval;
        ifp->if_watchdog = ilwatch;
        is->is_scaninterval = ILWATCHINTERVAL;
        ifp->if_timer = is->is_scaninterval;
@@ -191,15 +194,26 @@ ilinit(unit)
        int s;
 
        if (if_ubainit(&is->is_ifuba, ui->ui_ubanum,
        int s;
 
        if (if_ubainit(&is->is_ifuba, ui->ui_ubanum,
-           sizeof (struct il_rheader), (int)btoc(ILMTU)) == 0) { 
+           sizeof (struct il_rheader), (int)btoc(ETHERMTU)) == 0) { 
                printf("il%d: can't initialize\n", unit);
                is->is_if.if_flags &= ~IFF_UP;
                return;
        }
                printf("il%d: can't initialize\n", unit);
                is->is_if.if_flags &= ~IFF_UP;
                return;
        }
-       is->is_ubaddr = uballoc(ui->ui_ubanum, &is->is_stats,
+       is->is_ubaddr = uballoc(ui->ui_ubanum, (caddr_t)&is->is_stats,
                sizeof (struct il_stats), 0);
        addr = (struct ildevice *)ui->ui_addr;
 
                sizeof (struct il_stats), 0);
        addr = (struct ildevice *)ui->ui_addr;
 
+       /*
+        * Turn off source address insertion (it's faster this way),
+        * and set board online.
+        */
+       s = splimp();
+       addr->il_csr = ILC_CISA;
+       while ((addr->il_csr & IL_CDONE) == 0)
+               ;
+       addr->il_csr = ILC_ONLINE;
+       while ((addr->il_csr & IL_CDONE) == 0)
+               ;
        /*
         * Set board online.
         * Hang receive buffer and start any pending
        /*
         * Set board online.
         * Hang receive buffer and start any pending
@@ -212,7 +226,7 @@ ilinit(unit)
        while ((addr->il_csr & IL_CDONE) == 0)
                ;
        addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
        while ((addr->il_csr & IL_CDONE) == 0)
                ;
        addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
-       addr->il_bcr = sizeof(struct il_rheader) + ILMTU + 6;
+       addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
        addr->il_csr =
                ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
        while ((addr->il_csr & IL_CDONE) == 0)
        addr->il_csr =
                ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
        while ((addr->il_csr & IL_CDONE) == 0)
@@ -233,7 +247,7 @@ ilinit(unit)
 ilstart(dev)
        dev_t dev;
 {
 ilstart(dev)
        dev_t dev;
 {
-        int unit = ILUNIT(dev), dest, len;
+        int unit = ILUNIT(dev), len;
        struct uba_device *ui = ilinfo[unit];
        register struct il_softc *is = &il_softc[unit];
        register struct ildevice *addr;
        struct uba_device *ui = ilinfo[unit];
        register struct il_softc *is = &il_softc[unit];
        register struct ildevice *addr;
@@ -245,13 +259,22 @@ ilstart(dev)
        if (m == 0) {
                if ((is->is_flags & ILF_STATPENDING) == 0)
                        return;
        if (m == 0) {
                if ((is->is_flags & ILF_STATPENDING) == 0)
                        return;
-               addr->il_bar = is->is_ubaddr & 0xfff;
+               addr->il_bar = is->is_ubaddr & 0xffff;
                addr->il_bcr = sizeof (struct il_stats);
                csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT|IL_RIE|IL_CIE;
                is->is_flags &= ~ILF_STATPENDING;
                goto startcmd;
        }
        len = if_wubaput(&is->is_ifuba, m);
                addr->il_bcr = sizeof (struct il_stats);
                csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT|IL_RIE|IL_CIE;
                is->is_flags &= ~ILF_STATPENDING;
                goto startcmd;
        }
        len = if_wubaput(&is->is_ifuba, m);
+       /*
+        * Ensure minimum packet length.
+        * This makes the safe assumtion that there are no virtual holes
+        * after the data.
+        * For security, it might be wise to zero out the added bytes,
+        * but we're mainly interested in speed at the moment.
+        */
+       if (len - sizeof(struct ether_header) < ETHERMIN)
+               len = ETHERMIN + sizeof(struct ether_header);
        if (is->is_ifuba.ifu_flags & UBA_NEEDBDP)
                UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_w.ifrw_bdp);
        addr->il_bar = is->is_ifuba.ifu_w.ifrw_info & 0xffff;
        if (is->is_ifuba.ifu_flags & UBA_NEEDBDP)
                UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_w.ifrw_bdp);
        addr->il_bar = is->is_ifuba.ifu_w.ifrw_info & 0xffff;
@@ -274,7 +297,7 @@ ilcint(unit)
        register struct il_softc *is = &il_softc[unit];
        struct uba_device *ui = ilinfo[unit];
        register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
        register struct il_softc *is = &il_softc[unit];
        struct uba_device *ui = ilinfo[unit];
        register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
-       short status;
+       short csr;
 
        if ((is->is_flags & ILF_OACTIVE) == 0) {
                printf("il%d: stray xmit interrupt, csr=%b\n", unit,
 
        if ((is->is_flags & ILF_OACTIVE) == 0) {
                printf("il%d: stray xmit interrupt, csr=%b\n", unit,
@@ -282,13 +305,14 @@ ilcint(unit)
                return;
        }
 
                return;
        }
 
+       csr = addr->il_csr;
        /*
         * Hang receive buffer if it couldn't
         * be done earlier (in ilrint).
         */
        if (is->is_flags & ILF_RCVPENDING) {
                addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
        /*
         * Hang receive buffer if it couldn't
         * be done earlier (in ilrint).
         */
        if (is->is_flags & ILF_RCVPENDING) {
                addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
-               addr->il_bcr = sizeof(struct il_rheader) + ILMTU + 6;
+               addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
                addr->il_csr =
                  ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
                while ((addr->il_csr & IL_CDONE) == 0)
                addr->il_csr =
                  ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
                while ((addr->il_csr & IL_CDONE) == 0)
@@ -296,17 +320,17 @@ ilcint(unit)
                is->is_flags &= ~ILF_RCVPENDING;
        }
        is->is_flags &= ~ILF_OACTIVE;
                is->is_flags &= ~ILF_RCVPENDING;
        }
        is->is_flags &= ~ILF_OACTIVE;
-       status = addr->il_csr & IL_STATUS;
+       csr &= IL_STATUS;
        switch (is->is_lastcmd) {
 
        case ILC_XMIT:
                is->is_if.if_opackets++;
        switch (is->is_lastcmd) {
 
        case ILC_XMIT:
                is->is_if.if_opackets++;
-               if (status > ILERR_RETRIES)
+               if (csr > ILERR_RETRIES)
                        is->is_if.if_oerrors++;
                break;
 
        case ILC_STAT:
                        is->is_if.if_oerrors++;
                break;
 
        case ILC_STAT:
-               if (status == ILERR_SUCCESS)
+               if (csr == ILERR_SUCCESS)
                        iltotal(is);
                break;
        }
                        iltotal(is);
                break;
        }
@@ -341,7 +365,8 @@ ilrint(unit)
                UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_r.ifrw_bdp);
        il = (struct il_rheader *)(is->is_ifuba.ifu_r.ifrw_addr);
        len = il->ilr_length - sizeof(struct il_rheader);
                UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_r.ifrw_bdp);
        il = (struct il_rheader *)(is->is_ifuba.ifu_r.ifrw_addr);
        len = il->ilr_length - sizeof(struct il_rheader);
-       if ((il->ilr_status&(ILFSTAT_A|ILFSTAT_C)) || len < 46 || len > ILMTU) {
+       if ((il->ilr_status&(ILFSTAT_A|ILFSTAT_C)) || len < 46 ||
+           len > ETHERMTU) {
                is->is_if.if_ierrors++;
 #ifdef notdef
                if (is->is_if.if_ierrors % 100 == 0)
                is->is_if.if_ierrors++;
 #ifdef notdef
                if (is->is_if.if_ierrors % 100 == 0)
@@ -355,14 +380,15 @@ ilrint(unit)
         * get true type from first 16-bit word past data.
         * Remember that type was trailer by setting off.
         */
         * get true type from first 16-bit word past data.
         * Remember that type was trailer by setting off.
         */
+       il->ilr_type = ntohs((u_short)il->ilr_type);
 #define        ildataaddr(il, off, type)       ((type)(((caddr_t)((il)+1)+(off))))
 #define        ildataaddr(il, off, type)       ((type)(((caddr_t)((il)+1)+(off))))
-       if (il->ilr_type >= ILPUP_TRAIL &&
-           il->ilr_type < ILPUP_TRAIL+ILPUP_NTRAILER) {
-               off = (il->ilr_type - ILPUP_TRAIL) * 512;
-               if (off >= ILMTU)
+       if (il->ilr_type >= ETHERPUP_TRAIL &&
+           il->ilr_type < ETHERPUP_TRAIL+ETHERPUP_NTRAILER) {
+               off = (il->ilr_type - ETHERPUP_TRAIL) * 512;
+               if (off >= ETHERMTU)
                        goto setup;             /* sanity */
                        goto setup;             /* sanity */
-               il->ilr_type = *ildataaddr(il, off, u_short *);
-               resid = *(ildataaddr(il, off+2, u_short *));
+               il->ilr_type = ntohs(*ildataaddr(il, off, u_short *));
+               resid = ntohs(*(ildataaddr(il, off+2, u_short *)));
                if (off + resid > len)
                        goto setup;             /* sanity */
                len = off + resid;
                if (off + resid > len)
                        goto setup;             /* sanity */
                len = off + resid;
@@ -387,7 +413,7 @@ ilrint(unit)
        switch (il->ilr_type) {
 
 #ifdef INET
        switch (il->ilr_type) {
 
 #ifdef INET
-       case ILPUP_IPTYPE:
+       case ETHERPUP_IPTYPE:
                schednetisr(NETISR_IP);
                inq = &ipintrq;
                break;
                schednetisr(NETISR_IP);
                inq = &ipintrq;
                break;
@@ -415,7 +441,7 @@ setup:
                return;
        }
        addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
                return;
        }
        addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
-       addr->il_bcr = sizeof(struct il_rheader) + ILMTU + 6;
+       addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
        addr->il_csr =
                ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
        while ((addr->il_csr & IL_CDONE) == 0)
        addr->il_csr =
                ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
        while ((addr->il_csr & IL_CDONE) == 0)
@@ -436,8 +462,8 @@ iloutput(ifp, m0, dst)
        int type, dest, s, error;
        register struct il_softc *is = &il_softc[ifp->if_unit];
        register struct mbuf *m = m0;
        int type, dest, s, error;
        register struct il_softc *is = &il_softc[ifp->if_unit];
        register struct mbuf *m = m0;
-       register struct il_xheader *il;
-       register int off, i;
+       register struct ether_header *il;
+       register int off;
 
        switch (dst->sa_family) {
 
 
        switch (dst->sa_family) {
 
@@ -447,14 +473,14 @@ iloutput(ifp, m0, dst)
                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                if (off > 0 && (off & 0x1ff) == 0 &&
                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                if (off > 0 && (off & 0x1ff) == 0 &&
                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
-                       type = ILPUP_TRAIL + (off>>9);
+                       type = ETHERPUP_TRAIL + (off>>9);
                        m->m_off -= 2 * sizeof (u_short);
                        m->m_len += 2 * sizeof (u_short);
                        m->m_off -= 2 * sizeof (u_short);
                        m->m_len += 2 * sizeof (u_short);
-                       *mtod(m, u_short *) = ILPUP_IPTYPE;
-                       *(mtod(m, u_short *) + 1) = m->m_len;
+                       *mtod(m, u_short *) = htons((u_short)ETHERPUP_IPTYPE);
+                       *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
                        goto gottrailertype;
                }
                        goto gottrailertype;
                }
-               type = ILPUP_IPTYPE;
+               type = ETHERPUP_IPTYPE;
                off = 0;
                goto gottype;
 #endif
                off = 0;
                goto gottype;
 #endif
@@ -484,31 +510,32 @@ gottype:
         * allocate another.
         */
        if (m->m_off > MMAXOFF ||
         * allocate another.
         */
        if (m->m_off > MMAXOFF ||
-           MMINOFF + sizeof (struct il_xheader) > m->m_off) {
-               m = m_get(M_DONTWAIT);
+           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;
                if (m == 0) {
                        error = ENOBUFS;
                        goto bad;
                }
                m->m_next = m0;
                m->m_off = MMINOFF;
-               m->m_len = sizeof (struct il_xheader);
+               m->m_len = sizeof (struct ether_header);
        } else {
        } else {
-               m->m_off -= sizeof (struct il_xheader);
-               m->m_len += sizeof (struct il_xheader);
+               m->m_off -= sizeof (struct ether_header);
+               m->m_len += sizeof (struct ether_header);
        }
        }
-       il = mtod(m, struct il_xheader *);
+       il = mtod(m, struct ether_header *);
        if ((dest &~ 0xff) == 0)
        if ((dest &~ 0xff) == 0)
-               bcopy(ilbroadcastaddr, il->ilx_dhost, 6);
+               bcopy((caddr_t)ilbroadcastaddr, (caddr_t)il->ether_dhost, 6);
        else {
                u_char *to = dest & 0x8000 ? is->is_stats.ils_addr : il_ectop;
 
        else {
                u_char *to = dest & 0x8000 ? is->is_stats.ils_addr : il_ectop;
 
-               bcopy(to, il->ilx_dhost, 3);
-               il->ilx_dhost[3] = (dest>>8) & 0x7f;
-               il->ilx_dhost[4] = (dest>>16) & 0xff;
-               il->ilx_dhost[5] = (dest>>24) & 0xff;
+               bcopy((caddr_t)to, (caddr_t)il->ether_dhost, 3);
+               il->ether_dhost[3] = (dest>>8) & 0x7f;
+               il->ether_dhost[4] = (dest>>16) & 0xff;
+               il->ether_dhost[5] = (dest>>24) & 0xff;
        }
        }
-       il->ilx_type = type;
+       bcopy((caddr_t)is->is_stats.ils_addr, (caddr_t)il->ether_shost, 6);
+       il->ether_type = htons((u_short)type);
 
        /*
         * Queue message on interface, and start output if interface
 
        /*
         * Queue message on interface, and start output if interface