restore keywords
[unix-history] / usr / src / sys / vax / if / if_ec.c
index 4dcf9f8..4303847 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_ec.c 4.7     82/05/07        */
+/*     if_ec.c 4.14    82/06/05        */
 
 #include "ec.h"
 #include "imp.h"
 
 #include "ec.h"
 #include "imp.h"
@@ -39,6 +39,7 @@ struct        uba_device *ecinfo[NEC];
 u_short ecstd[] = { 0 };
 struct uba_driver ecdriver =
        { ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo };
 u_short ecstd[] = { 0 };
 struct uba_driver ecdriver =
        { ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo };
+u_char ec_iltop[3] = { 0x02, 0x07, 0x01 };
 #define        ECUNIT(x)       minor(x)
 
 int    ecinit(),ecoutput(),ecreset();
 #define        ECUNIT(x)       minor(x)
 
 int    ecinit(),ecoutput(),ecreset();
@@ -62,10 +63,6 @@ struct       ec_softc {
        struct  ifnet es_if;            /* network-visible interface */
        struct  ifuba es_ifuba;         /* UNIBUS resources */
        short   es_mask;                /* mask for current output delay */
        struct  ifnet es_if;            /* network-visible interface */
        struct  ifuba es_ifuba;         /* UNIBUS resources */
        short   es_mask;                /* mask for current output delay */
-#ifdef notdef
-       short   es_delay;               /* current output delay */
-       long    es_lastx;               /* host last transmitted to */
-#endif
        short   es_oactive;             /* is output active? */
        caddr_t es_buf[16];             /* virtual addresses of buffers */
        u_char  es_enaddr[6];           /* board's ethernet address */
        short   es_oactive;             /* is output active? */
        caddr_t es_buf[16];             /* virtual addresses of buffers */
        u_char  es_enaddr[6];           /* board's ethernet address */
@@ -189,7 +186,7 @@ COUNT(ECATTACH);
 #if NIMP == 0
        /* here's one for you john baby.... */
        if (ui->ui_flags &~ 0xff)
 #if NIMP == 0
        /* here's one for you john baby.... */
        if (ui->ui_flags &~ 0xff)
-               eclhinit((ui->ui_flags &~ 0xff) | 0x0a);
+               eclhinit(&es->es_if, (ui->ui_flags &~ 0xff) | 0x0a);
 #endif
 }
 
 #endif
 }
 
@@ -223,14 +220,6 @@ ecinit(unit)
        register i;
        int s;
 
        register i;
        int s;
 
-#ifdef notdef
-       if (if_ubainit(&es->es_ifuba, ui->ui_ubanum,
-           sizeof (struct ec_header), (int)btoc(ECMTU)) == 0) { 
-               printf("ec%d: can't initialize\n", unit);
-               es->es_if.if_flags &= ~IFF_UP;
-               return;
-       }
-#endif
        addr = (struct ecdevice *)ui->ui_addr;
 
        /*
        addr = (struct ecdevice *)ui->ui_addr;
 
        /*
@@ -249,12 +238,6 @@ ecinit(unit)
        if_rtinit(&es->es_if, RTF_DIRECT|RTF_UP);
 }
 
        if_rtinit(&es->es_if, RTF_DIRECT|RTF_UP);
 }
 
-#ifdef notdef
-int    enalldelay = 0;
-int    eclastdel = 25;
-int    enlastmask = (~0) << 5;
-#endif
-
 /*
  * Start or restart output on interface.
  * If interface is already active, then this is a retransmit
 /*
  * Start or restart output on interface.
  * If interface is already active, then this is a retransmit
@@ -288,27 +271,8 @@ COUNT(ECSTART);
                es->es_oactive = 0;
                return;
        }
                es->es_oactive = 0;
                return;
        }
-#ifdef notdef
-       dest = mtod(m, struct ec_header *)->ec_dhost; /* wrong! */
-#endif
        ecput(es->es_buf[ECTBF], m);
 
        ecput(es->es_buf[ECTBF], m);
 
-#ifdef notdef
-       /*
-        * Ethernet cannot take back-to-back packets (no
-        * buffering in interface).  To avoid overrunning
-        * receivers, enforce a small delay (about 1ms) in interface:
-        *      * between all packets when ecalldelay
-        *      * whenever last packet was broadcast
-        *      * whenever this packet is to same host as last packet
-        */
-       if (enalldelay || es->es_lastx == 0 || es->es_lastx == dest) {
-               es->es_delay = eclastdel;
-               es->es_mask = eclastmask;
-       }
-       es->es_lastx = dest;
-#endif
-
 restart:
        /*
         * Start the output.
 restart:
        /*
         * Start the output.
@@ -346,9 +310,6 @@ COUNT(ECXINT);
                es->es_ifuba.ifu_xtofree = 0;
        }
        if (es->es_if.if_snd.ifq_head == 0) {
                es->es_ifuba.ifu_xtofree = 0;
        }
        if (es->es_if.if_snd.ifq_head == 0) {
-#ifdef notdef
-               es->es_lastx = 0; /* ? */
-#endif
                return;
        }
        ecstart(unit);
                return;
        }
        ecstart(unit);
@@ -422,11 +383,6 @@ ecdocoll(unit)
        addr->ec_xcr = EC_JINTEN|EC_XINTEN|EC_JCLR;
 }
 
        addr->ec_xcr = EC_JINTEN|EC_XINTEN|EC_JCLR;
 }
 
-#ifdef notdef
-struct sockaddr_pup pupsrc = { AF_PUP };
-struct sockaddr_pup pupdst = { AF_PUP };
-struct sockproto pupproto = { PF_PUP };
-#endif
 /*
  * Ethernet interface receiver interrupt.
  * If input error just drop packet.
 /*
  * Ethernet interface receiver interrupt.
  * If input error just drop packet.
@@ -442,9 +398,6 @@ ecrint(unit)
        struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
 COUNT(ECRINT);
 
        struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
 COUNT(ECRINT);
 
-#ifdef notdef
-       printf("ec%d: ecrint:%d\n", unit, addr->ec_rcr & 0xf);
-#endif
        while (addr->ec_rcr & EC_RDONE)
                ecread(unit);
 }
        while (addr->ec_rcr & EC_RDONE)
                ecread(unit);
 }
@@ -524,20 +477,6 @@ COUNT(ECREAD);
                schednetisr(NETISR_IP);
                inq = &ipintrq;
                break;
                schednetisr(NETISR_IP);
                inq = &ipintrq;
                break;
-#endif
-#ifdef notdef
-#ifdef PUP
-       case ECPUP_PUPTYPE: {
-               struct pup_header *pup = mtod(m, struct pup_header *);
-
-               pupproto.sp_protocol = pup->pup_type;
-               pupdst.spup_addr = pup->pup_dport;
-               pupsrc.spup_addr = pup->pup_sport;
-               raw_input(m, &pupproto, (struct sockaddr *)&pupsrc,
-                 (struct sockaddr *)&pupdst);
-               goto setup;
-       }
-#endif
 #endif
        default:
                m_freem(m);
 #endif
        default:
                m_freem(m);
@@ -605,15 +544,6 @@ COUNT(ECOUTPUT);
                type = ECPUP_IPTYPE;
                off = 0;
                goto gottype;
                type = ECPUP_IPTYPE;
                off = 0;
                goto gottype;
-#endif
-#ifdef notdef
-#ifdef PUP
-       case AF_PUP:
-               dest = ((struct sockaddr_pup *)dst)->spup_addr.pp_host;
-               type = ECPUP_PUPTYPE;
-               off = 0;
-               goto gottype;
-#endif
 #endif
 
        default:
 #endif
 
        default:
@@ -661,10 +591,16 @@ gottype:
                for (i=0; i<6; i++)
                        ec->ec_dhost[i] = 0xff;
        else {
                for (i=0; i<6; i++)
                        ec->ec_dhost[i] = 0xff;
        else {
-               ec->ec_dhost[0] = es->es_enaddr[0];
-               ec->ec_dhost[1] = es->es_enaddr[1];
-               ec->ec_dhost[2] = es->es_enaddr[2];
-               ec->ec_dhost[3] = (dest>>8) & 0xff;
+               if (dest & 0x8000) {
+                       ec->ec_dhost[0] = ec_iltop[0];
+                       ec->ec_dhost[1] = ec_iltop[1];
+                       ec->ec_dhost[2] = ec_iltop[2];
+               } else {
+                       ec->ec_dhost[0] = es->es_enaddr[0];
+                       ec->ec_dhost[1] = es->es_enaddr[1];
+                       ec->ec_dhost[2] = es->es_enaddr[2];
+               }
+               ec->ec_dhost[3] = (dest>>8) & 0x7f;
                ec->ec_dhost[4] = (dest>>16) & 0xff;
                ec->ec_dhost[5] = (dest>>24) & 0xff;
        }
                ec->ec_dhost[4] = (dest>>16) & 0xff;
                ec->ec_dhost[5] = (dest>>24) & 0xff;
        }
@@ -719,7 +655,19 @@ COUNT(ECPUT);
        mp = m;
        while (mp) {
                mcp = mtod(mp, char *);
        mp = m;
        while (mp) {
                mcp = mtod(mp, char *);
+               i = 0;
+               if ((int)bp&1) {
+                       *bp++ = *mcp++;
+                       i++;
+               }
                for (i=0; i<mp->m_len; i++)
                for (i=0; i<mp->m_len; i++)
+               while (i < mp->m_len) {
+                       *(short *)bp = *(short *)mcp;
+                       bp += 2;
+                       mcp += 2;
+                       i += 2;
+               }
+               if (mp->m_len&1)
                        *bp++ = *mcp++;
                mp = m_free(mp);
        }
                        *bp++ = *mcp++;
                mp = m_free(mp);
        }
@@ -730,6 +678,9 @@ COUNT(ECPUT);
 /*
  * Routine to copy from UNIBUS memory into mbufs.
  * Similar in spirit to if_rubaget.
 /*
  * Routine to copy from UNIBUS memory into mbufs.
  * Similar in spirit to if_rubaget.
+ *
+ * Warning: This makes the fairly safe assumption that
+ * mbufs have even lengths.
  */
 struct mbuf *
 ecget(ecbuf, totlen, off0)
  */
 struct mbuf *
 ecget(ecbuf, totlen, off0)
@@ -771,7 +722,12 @@ COUNT(ECGET);
                        m->m_off = MMINOFF;
                }
                mcp = mtod(m, char *);
                        m->m_off = MMINOFF;
                }
                mcp = mtod(m, char *);
-               for (i=0; i<len; i++)
+               for (i=0; i<len; i+=2) {
+                       *(short *)mcp = *(short *)cp;
+                       mcp += 2;
+                       cp += 2;
+               }
+               if (len&1)
                        *mcp++ = *cp++;
                *mp = m;
                mp = &m->m_next;
                        *mcp++ = *cp++;
                *mp = m;
                mp = &m->m_next;
@@ -802,15 +758,15 @@ bad:
  */
 
 struct ifnet eclhif;
  */
 
 struct ifnet eclhif;
-int    eclhoutput();
+int    looutput();
 
 /*
  * Called by localnet interface to allow logical
 
 /*
  * Called by localnet interface to allow logical
- * host interface to "attach".  Nothing should ever
- * be sent locally to this interface, it's purpose
+ * host interface to "attach", it's purpose
  * is simply to establish the host's arpanet address.
  */
  * is simply to establish the host's arpanet address.
  */
-eclhinit(addr)
+eclhinit(ecifp, addr)
+       struct ifnet *ecifp;
        int addr;
 {
        register struct ifnet *ifp = &eclhif;
        int addr;
 {
        register struct ifnet *ifp = &eclhif;
@@ -822,20 +778,12 @@ COUNT(ECLHINIT);
        sin = (struct sockaddr_in *)&ifp->if_addr;
        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = addr;
        sin = (struct sockaddr_in *)&ifp->if_addr;
        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = addr;
+       sin->sin_addr.s_lh = ecifp->if_host[0];
        ifp->if_net = sin->sin_addr.s_net;
        ifp->if_net = sin->sin_addr.s_net;
-       ifp->if_flags = IFF_UP;
-       ifp->if_output = eclhoutput;    /* should never be used */
+       ifp->if_dstaddr = ifp->if_addr;
+       ifp->if_flags = IFF_UP|IFF_POINTOPOINT;
+       ifp->if_output = looutput;
        if_attach(ifp);
        if_attach(ifp);
-}
-
-eclhoutput(ifp, m0, dst)
-       struct ifnet *ifp;
-       struct mbuf *m0;
-       struct sockaddr *dst;
-{
-COUNT(ECLHOUTPUT);
-       ifp->if_oerrors++;
-       m_freem(m0);
-       return (0);
+       rtinit(&ifp->if_addr, &ifp->if_addr, RTF_UP|RTF_DIRECT|RTF_HOST);
 }
 #endif
 }
 #endif