Add copyright
[unix-history] / usr / src / sys / vax / if / if_ec.c
index 88488e3..7889ef1 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_ec.c 6.2     84/03/20        */
+/*     if_ec.c 6.8     85/05/04        */
 
 #include "ec.h"
 
 
 #include "ec.h"
 
@@ -7,41 +7,45 @@
  */
 #include "../machine/pte.h"
 
  */
 #include "../machine/pte.h"
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/mbuf.h"
-#include "../h/buf.h"
-#include "../h/protosw.h"
-#include "../h/socket.h"
-#include "../h/vmmac.h"
-#include "../h/ioctl.h"
-#include "../h/errno.h"
+#include "param.h"
+#include "systm.h"
+#include "mbuf.h"
+#include "buf.h"
+#include "protosw.h"
+#include "socket.h"
+#include "vmmac.h"
+#include "ioctl.h"
+#include "errno.h"
 
 #include "../net/if.h"
 #include "../net/netisr.h"
 #include "../net/route.h"
 #include "../netinet/in.h"
 #include "../netinet/in_systm.h"
 
 #include "../net/if.h"
 #include "../net/netisr.h"
 #include "../net/route.h"
 #include "../netinet/in.h"
 #include "../netinet/in_systm.h"
+#include "../netinet/in_var.h"
 #include "../netinet/ip.h"
 #include "../netinet/ip_var.h"
 #include "../netinet/if_ether.h"
 #include "../netinet/ip.h"
 #include "../netinet/ip_var.h"
 #include "../netinet/if_ether.h"
+#ifdef PUP
 #include "../netpup/pup.h"
 #include "../netpup/pup.h"
+#endif
 
 #include "../vax/cpu.h"
 #include "../vax/mtpr.h"
 
 #include "../vax/cpu.h"
 #include "../vax/mtpr.h"
-#include "../vaxif/if_ecreg.h"
-#include "../vaxif/if_uba.h"
+#include "if_ecreg.h"
+#include "if_uba.h"
 #include "../vaxuba/ubareg.h"
 #include "../vaxuba/ubavar.h"
 
 #include "../vaxuba/ubareg.h"
 #include "../vaxuba/ubavar.h"
 
-#define        ECMEM   0000000
+#if CLSIZE == 2
+#define ECBUFSIZE      32              /* on-board memory, clusters */
+#endif
 
 
-int    ecprobe(), ecattach(), ecrint(), ecxint(), eccollide();
+int    ecubamem(), ecprobe(), ecattach(), ecrint(), ecxint(), eccollide();
 struct uba_device *ecinfo[NEC];
 u_short ecstd[] = { 0 };
 struct uba_driver ecdriver =
 struct uba_device *ecinfo[NEC];
 u_short ecstd[] = { 0 };
 struct uba_driver ecdriver =
-       { ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo };
-#define        ECUNIT(x)       minor(x)
+       { ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo, 0, 0, 0, ecubamem };
 
 int    ecinit(),ecioctl(),ecoutput(),ecreset();
 struct mbuf *ecget();
 
 int    ecinit(),ecioctl(),ecoutput(),ecreset();
 struct mbuf *ecget();
@@ -71,59 +75,88 @@ struct      ec_softc {
 } ec_softc[NEC];
 
 /*
 } ec_softc[NEC];
 
 /*
- * Do output DMA to determine interface presence and
- * interrupt vector.  DMA is too short to disturb other hosts.
+ * Configure on-board memory for an interface.
+ * Called from autoconfig and after a uba reset.
+ * The address of the memory on the uba is supplied in the device flags.
  */
  */
-ecprobe(reg)
-       caddr_t reg;
+ecubamem(ui, uban)
+       register struct uba_device *ui;
 {
 {
-       register int br, cvec;          /* r11, r10 value-result */
-       register struct ecdevice *addr = (struct ecdevice *)reg;
-       register caddr_t ecbuf = (caddr_t) &umem[numuba][ECMEM];
+       register caddr_t ecbuf = (caddr_t) &umem[uban][ui->ui_flags];
+       register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
 
 
-#ifdef lint
-       br = 0; cvec = br; br = cvec;
-       ecrint(0); ecxint(0); eccollide(0);
+       /*
+        * Make sure csr is there (we run before ecprobe).
+        */
+       if (badaddr((caddr_t)addr, 2))
+               return (-1);
+#if VAX780
+       if (cpu == VAX_780 && uba_hd[uban].uh_uba->uba_sr) {
+               uba_hd[uban].uh_uba->uba_sr = uba_hd[uban].uh_uba->uba_sr;
+               return (-1);
+       }
 #endif
        /*
         * Make sure memory is turned on
         */
        addr->ec_rcr = EC_AROM;
        /*
 #endif
        /*
         * Make sure memory is turned on
         */
        addr->ec_rcr = EC_AROM;
        /*
-        * Disable map registers for ec unibus space,
-        * but don't allocate yet.
+        * Tell the system that the board has memory here, so it won't
+        * attempt to allocate the addresses later.
         */
         */
-       (void) ubamem(numuba, ECMEM, 32*2, 0);
+       if (ubamem(uban, ui->ui_flags, ECBUFSIZE*CLSIZE, 1) == 0) {
+               printf("ec%d: cannot reserve uba addresses\n", ui->ui_unit);
+               addr->ec_rcr = EC_MDISAB;       /* disable memory */
+               return (-1);
+       }
        /*
         * Check for existence of buffers on Unibus.
         */
        if (badaddr((caddr_t)ecbuf, 2)) {
        /*
         * Check for existence of buffers on Unibus.
         */
        if (badaddr((caddr_t)ecbuf, 2)) {
-       bad1:
-               printf("ec: buffer mem not found\n");
-       bad2:
-               (void) ubamem(numuba, 0, 0, 0); /* reenable map (780 only) */
+bad:
+               printf("ec%d: buffer mem not found\n", ui->ui_unit);
+               (void) ubamem(uban, ui->ui_flags, ECBUFSIZE*2, 0);
                addr->ec_rcr = EC_MDISAB;       /* disable memory */
                addr->ec_rcr = EC_MDISAB;       /* disable memory */
-               return (0);
+               return (-1);
        }
 #if VAX780
        }
 #if VAX780
-       if (cpu == VAX_780 && uba_hd[numuba].uh_uba->uba_sr) {
-               uba_hd[numuba].uh_uba->uba_sr = uba_hd[numuba].uh_uba->uba_sr;
-               goto bad1;
+       if (cpu == VAX_780 && uba_hd[uban].uh_uba->uba_sr) {
+               uba_hd[uban].uh_uba->uba_sr = uba_hd[uban].uh_uba->uba_sr;
+               goto bad;
        }
 #endif
        }
 #endif
+       if (ui->ui_alive == 0)          /* Only printf from autoconfig */
+               printf("ec%d: mem %x-%x\n", ui->ui_unit,
+                       ui->ui_flags, ui->ui_flags + ECBUFSIZE*CLBYTES - 1);
+       ui->ui_type = 1;                /* Memory on, allocated */
+       return (0);
+}
+
+/*
+ * Do output DMA to determine interface presence and
+ * interrupt vector.  DMA is too short to disturb other hosts.
+ */
+ecprobe(reg, ui)
+       caddr_t reg;
+       struct uba_device *ui;
+{
+       register int br, cvec;          /* r11, r10 value-result */
+       register struct ecdevice *addr = (struct ecdevice *)reg;
+       register caddr_t ecbuf = (caddr_t) &umem[ui->ui_ubanum][ui->ui_flags];
+
+#ifdef lint
+       br = 0; cvec = br; br = cvec;
+       ecrint(0); ecxint(0); eccollide(0);
+#endif
 
        /*
 
        /*
-        * Tell the system that the board has memory here, so it won't
-        * attempt to allocate the addresses later.
+        * Check that buffer memory was found and enabled.
         */
         */
-       if (ubamem(numuba, ECMEM, 32*2, 1) == 0) {
-               printf("ecprobe: cannot reserve uba addresses\n");
-               goto bad2;
-       }
-
+       if (ui->ui_type == 0)
+               return(0);
        /*
         * Make a one byte packet in what should be buffer #0.
        /*
         * Make a one byte packet in what should be buffer #0.
-        * Submit it for sending.  This whould cause an xmit interrupt.
+        * Submit it for sending.  This should cause an xmit interrupt.
         * The xmit interrupt vector is 8 bytes after the receive vector,
         * so adjust for this before returning.
         */
         * The xmit interrupt vector is 8 bytes after the receive vector,
         * so adjust for this before returning.
         */
@@ -155,7 +188,6 @@ ecattach(ui)
        struct ec_softc *es = &ec_softc[ui->ui_unit];
        register struct ifnet *ifp = &es->es_if;
        register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
        struct ec_softc *es = &ec_softc[ui->ui_unit];
        register struct ifnet *ifp = &es->es_if;
        register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
-       struct sockaddr_in *sin;
        int i, j;
        u_char *cp;
 
        int i, j;
        u_char *cp;
 
@@ -170,7 +202,7 @@ ecattach(ui)
        addr->ec_rcr = EC_AROM;
        cp = es->es_addr;
 #define        NEXTBIT addr->ec_rcr = EC_AROM|EC_ASTEP; addr->ec_rcr = EC_AROM
        addr->ec_rcr = EC_AROM;
        cp = es->es_addr;
 #define        NEXTBIT addr->ec_rcr = EC_AROM|EC_ASTEP; addr->ec_rcr = EC_AROM
-       for (i=0; i<6; i++) {
+       for (i=0; i < sizeof (es->es_addr); i++) {
                *cp = 0;
                for (j=0; j<=4; j+=4) {
                        *cp |= ((addr->ec_rcr >> 8) & 0xf) << j;
                *cp = 0;
                for (j=0; j<=4; j+=4) {
                        *cp |= ((addr->ec_rcr >> 8) & 0xf) << j;
@@ -178,15 +210,14 @@ ecattach(ui)
                }
                cp++;
        }
                }
                cp++;
        }
-       sin = (struct sockaddr_in *)&es->es_if.if_addr;
-       sin->sin_family = AF_INET;
-       sin->sin_addr = arpmyaddr((struct arpcom *)0);
        ifp->if_init = ecinit;
        ifp->if_ioctl = ecioctl;
        ifp->if_output = ecoutput;
        ifp->if_reset = ecreset;
        ifp->if_init = ecinit;
        ifp->if_ioctl = ecioctl;
        ifp->if_output = ecoutput;
        ifp->if_reset = ecreset;
+       ifp->if_flags = IFF_BROADCAST;
        for (i=0; i<16; i++)
        for (i=0; i<16; i++)
-               es->es_buf[i] = (u_char *)&umem[ui->ui_ubanum][ECMEM+2048*i];
+               es->es_buf[i] 
+                   = (u_char *)&umem[ui->ui_ubanum][ui->ui_flags + 2048*i];
        if_attach(ifp);
 }
 
        if_attach(ifp);
 }
 
@@ -203,7 +234,6 @@ ecreset(unit, uban)
            ui->ui_ubanum != uban)
                return;
        printf(" ec%d", unit);
            ui->ui_ubanum != uban)
                return;
        printf(" ec%d", unit);
-       (void) ubamem(uban, ECMEM, 32*2, 0);    /* mr disable (no alloc) */
        ec_softc[unit].es_if.if_flags &= ~IFF_RUNNING;
        ecinit(unit);
 }
        ec_softc[unit].es_if.if_flags &= ~IFF_RUNNING;
        ecinit(unit);
 }
@@ -218,11 +248,10 @@ ecinit(unit)
        struct ec_softc *es = &ec_softc[unit];
        struct ecdevice *addr;
        register struct ifnet *ifp = &es->es_if;
        struct ec_softc *es = &ec_softc[unit];
        struct ecdevice *addr;
        register struct ifnet *ifp = &es->es_if;
-       register struct sockaddr_in *sin;
        int i, s;
 
        int i, s;
 
-       sin = (struct sockaddr_in *)&ifp->if_addr;
-       if (sin->sin_addr.s_addr == 0)          /* address still unknown */
+       /* not yet, if address still unknown */
+       if (ifp->if_addrlist == (struct ifaddr *)0)
                return;
 
        /*
                return;
 
        /*
@@ -230,21 +259,18 @@ ecinit(unit)
         * Writing into the rcr also makes sure the memory
         * is turned on.
         */
         * Writing into the rcr also makes sure the memory
         * is turned on.
         */
-       if ((es->es_if.if_flags & IFF_RUNNING) == 0) {
+       if ((ifp->if_flags & IFF_RUNNING) == 0) {
                addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
                s = splimp();
                for (i = ECRHBF; i >= ECRLBF; i--)
                        addr->ec_rcr = EC_READ | i;
                es->es_oactive = 0;
                es->es_mask = ~0;
                addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
                s = splimp();
                for (i = ECRHBF; i >= ECRLBF; i--)
                        addr->ec_rcr = EC_READ | i;
                es->es_oactive = 0;
                es->es_mask = ~0;
-               es->es_if.if_flags |= IFF_UP|IFF_RUNNING;
+               es->es_if.if_flags |= IFF_RUNNING;
                if (es->es_if.if_snd.ifq_head)
                        ecstart(unit);
                splx(s);
        }
                if (es->es_if.if_snd.ifq_head)
                        ecstart(unit);
                splx(s);
        }
-       if_rtinit(&es->es_if, RTF_UP);
-       arpattach(&es->es_ac);
-       arpwhohas(&es->es_ac, &sin->sin_addr);
 }
 
 /*
 }
 
 /*
@@ -255,10 +281,8 @@ ecinit(unit)
  * to send off of the interface queue, and map it to the interface
  * before starting the output.
  */
  * to send off of the interface queue, and map it to the interface
  * before starting the output.
  */
-ecstart(dev)
-       dev_t dev;
+ecstart(unit)
 {
 {
-        int unit = ECUNIT(dev);
        struct ec_softc *es = &ec_softc[unit];
        struct ecdevice *addr;
        struct mbuf *m;
        struct ec_softc *es = &ec_softc[unit];
        struct ecdevice *addr;
        struct mbuf *m;
@@ -419,7 +443,7 @@ ecread(unit)
        /*
         * Get input data length.
         * Get pointer to ethernet header (in input buffer).
        /*
         * Get input data length.
         * Get pointer to ethernet header (in input buffer).
-        * Deal with trailer protocol: if type is PUP trailer
+        * Deal with trailer protocol: if type is trailer type
         * 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.
         */
@@ -427,9 +451,9 @@ ecread(unit)
        ec = (struct ether_header *)(ecbuf + ECRDOFF);
        ec->ether_type = ntohs((u_short)ec->ether_type);
 #define        ecdataaddr(ec, off, type)       ((type)(((caddr_t)((ec)+1)+(off))))
        ec = (struct ether_header *)(ecbuf + ECRDOFF);
        ec->ether_type = ntohs((u_short)ec->ether_type);
 #define        ecdataaddr(ec, off, type)       ((type)(((caddr_t)((ec)+1)+(off))))
-       if (ec->ether_type >= ETHERPUP_TRAIL &&
-           ec->ether_type < ETHERPUP_TRAIL+ETHERPUP_NTRAILER) {
-               off = (ec->ether_type - ETHERPUP_TRAIL) * 512;
+       if (ec->ether_type >= ETHERTYPE_TRAIL &&
+           ec->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
+               off = (ec->ether_type - ETHERTYPE_TRAIL) * 512;
                if (off >= ETHERMTU)
                        goto setup;             /* sanity */
                ec->ether_type = ntohs(*ecdataaddr(ec, off, u_short *));
                if (off >= ETHERMTU)
                        goto setup;             /* sanity */
                ec->ether_type = ntohs(*ecdataaddr(ec, off, u_short *));
@@ -458,12 +482,12 @@ ecread(unit)
        switch (ec->ether_type) {
 
 #ifdef INET
        switch (ec->ether_type) {
 
 #ifdef INET
-       case ETHERPUP_IPTYPE:
+       case ETHERTYPE_IP:
                schednetisr(NETISR_IP);
                inq = &ipintrq;
                break;
 
                schednetisr(NETISR_IP);
                inq = &ipintrq;
                break;
 
-       case ETHERPUP_ARPTYPE:
+       case ETHERTYPE_ARP:
                arpinput(&es->es_ac, m);
                goto setup;
 #endif
                arpinput(&es->es_ac, m);
                goto setup;
 #endif
@@ -501,7 +525,7 @@ ecoutput(ifp, m0, dst)
        struct sockaddr *dst;
 {
        int type, s, error;
        struct sockaddr *dst;
 {
        int type, s, error;
-       u_char edst[6];
+       u_char edst[6];
        struct in_addr idst;
        register struct ec_softc *es = &ec_softc[ifp->if_unit];
        register struct mbuf *m = m0;
        struct in_addr idst;
        register struct ec_softc *es = &ec_softc[ifp->if_unit];
        register struct mbuf *m = m0;
@@ -516,28 +540,29 @@ ecoutput(ifp, m0, dst)
                idst = ((struct sockaddr_in *)dst)->sin_addr;
                if (!arpresolve(&es->es_ac, m, &idst, edst))
                        return (0);     /* if not yet resolved */
                idst = ((struct sockaddr_in *)dst)->sin_addr;
                if (!arpresolve(&es->es_ac, m, &idst, edst))
                        return (0);     /* if not yet resolved */
-               if (in_lnaof(idst) == INADDR_ANY)
+               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;
                /* need per host negotiation */
                if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
                if (off > 0 && (off & 0x1ff) == 0 &&
                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                /* need per host negotiation */
                if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
                if (off > 0 && (off & 0x1ff) == 0 &&
                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
-                       type = ETHERPUP_TRAIL + (off>>9);
+                       type = ETHERTYPE_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 *) = ntohs((u_short)ETHERPUP_IPTYPE);
+                       *mtod(m, u_short *) = ntohs((u_short)ETHERTYPE_IP);
                        *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);
                        goto gottrailertype;
                }
                        *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);
                        goto gottrailertype;
                }
-               type = ETHERPUP_IPTYPE;
+               type = ETHERTYPE_IP;
                off = 0;
                goto gottype;
 #endif
 
        case AF_UNSPEC:
                ec = (struct ether_header *)dst->sa_data;
                off = 0;
                goto gottype;
 #endif
 
        case AF_UNSPEC:
                ec = (struct ether_header *)dst->sa_data;
-               bcopy((caddr_t)ec->ether_dhost, (caddr_t)edst, sizeof (edst));
+               bcopy((caddr_t)ec->ether_dhost, (caddr_t)edst, sizeof (edst));
                type = ec->ether_type;
                goto gottype;
 
                type = ec->ether_type;
                goto gottype;
 
@@ -580,9 +605,10 @@ gottype:
                m->m_len += sizeof (struct ether_header);
        }
        ec = mtod(m, struct ether_header *);
                m->m_len += sizeof (struct ether_header);
        }
        ec = mtod(m, struct ether_header *);
-       bcopy((caddr_t)edst, (caddr_t)ec->ether_dhost, sizeof (edst));
+       bcopy((caddr_t)edst, (caddr_t)ec->ether_dhost, sizeof (edst));
+       bcopy((caddr_t)es->es_addr, (caddr_t)ec->ether_shost,
+           sizeof(ec->ether_shost));
        ec->ether_type = htons((u_short)type);
        ec->ether_type = htons((u_short)type);
-       bcopy((caddr_t)es->es_addr, (caddr_t)ec->ether_shost, 6);
 
        /*
         * Queue message on interface, and start output if interface
 
        /*
         * Queue message on interface, and start output if interface
@@ -746,16 +772,22 @@ ecioctl(ifp, cmd, data)
        int cmd;
        caddr_t data;
 {
        int cmd;
        caddr_t data;
 {
-       register struct ifreq *ifr = (struct ifreq *)data;
+       register struct ifaddr *ifa = (struct ifaddr *)data;
        int s = splimp(), error = 0;
 
        switch (cmd) {
 
        case SIOCSIFADDR:
        int s = splimp(), error = 0;
 
        switch (cmd) {
 
        case SIOCSIFADDR:
-               if (ifp->if_flags & IFF_RUNNING)
-                       if_rtinit(ifp, -1);     /* delete previous route */
-               ecsetaddr(ifp, (struct sockaddr_in *)&ifr->ifr_addr);
+               ifp->if_flags |= IFF_UP;
                ecinit(ifp->if_unit);
                ecinit(ifp->if_unit);
+
+               switch (ifa->ifa_addr.sa_family) {
+               case AF_INET:
+                       ((struct arpcom *)ifp)->ac_ipaddr =
+                               IA_SIN(ifa)->sin_addr;
+                       arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
+                       break;
+               }
                break;
 
        default:
                break;
 
        default:
@@ -764,17 +796,3 @@ ecioctl(ifp, cmd, data)
        splx(s);
        return (error);
 }
        splx(s);
        return (error);
 }
-
-ecsetaddr(ifp, sin)
-       register struct ifnet *ifp;
-       register struct sockaddr_in *sin;
-{
-
-       ifp->if_addr = *(struct sockaddr *)sin;
-       ifp->if_net = in_netof(sin->sin_addr);
-       ifp->if_host[0] = in_lnaof(sin->sin_addr);
-       sin = (struct sockaddr_in *)&ifp->if_broadaddr;
-       sin->sin_family = AF_INET;
-       sin->sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY);
-       ifp->if_flags |= IFF_BROADCAST;
-}