BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / vax / if / if_dp.c
index beb5d64..f029aa3 100644 (file)
@@ -2,9 +2,35 @@
  * Copyright (c) 1990 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1990 Regents of the University of California.
  * All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. 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.
  *
  *
- *     @(#)if_dp.c     7.5 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)if_dp.c     7.9 (Berkeley) 6/27/91
  */
 
 #include "dp.h"
  */
 
 #include "dp.h"
 
 /* #define DEBUG       /* for base table dump on fatal error */
 
 
 /* #define DEBUG       /* for base table dump on fatal error */
 
-#include "machine/pte.h"
-
-#include "param.h"
-#include "systm.h"
-#include "mbuf.h"
-#include "buf.h"
-#include "ioctl.h"             /* must precede tty.h */
-#include "protosw.h"
-#include "socket.h"
-#include "socketvar.h"
-#include "syslog.h"
-#include "vmmac.h"
-#include "errno.h"
-#include "time.h"
-#include "kernel.h"
-
-#include "../net/if.h"
-#include "../net/netisr.h"
-#include "../net/route.h"
-
-#include "../vax/cpu.h"
-#include "../vax/mtpr.h"
+#include "../include/pte.h"
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/mbuf.h"
+#include "sys/buf.h"
+#include "sys/ioctl.h"         /* must precede tty.h */
+#include "sys/protosw.h"
+#include "sys/socket.h"
+#include "sys/socketvar.h"
+#include "sys/syslog.h"
+#include "sys/vmmac.h"
+#include "sys/errno.h"
+#include "sys/time.h"
+#include "sys/kernel.h"
+
+#include "net/if.h"
+#include "net/if_types.h"
+#include "net/netisr.h"
+#include "net/route.h"
+
+#include "../include/cpu.h"
+#include "../include/mtpr.h"
 
 #define        dzdevice dpdevice
 
 #define        dzdevice dpdevice
-#include "../vaxuba/pdma.h"
-#include "../vaxuba/ubavar.h"
+#include "../uba/pdma.h"
+#include "../uba/ubavar.h"
 
 
-#include "../netccitt/x25.h"
-#include "../netccitt/pk.h"
-#include "../netccitt/pk_var.h"
+#include "netccitt/x25.h"
+#include "netccitt/pk.h"
+#include "netccitt/pk_var.h"
 
 #include "if_dpreg.h"
 
 
 #include "if_dpreg.h"
 
@@ -61,7 +88,8 @@
  * Driver information for auto-configuration stuff.
  */
 int    dpprobe(), dpattach(), dpinit(), dpioctl(), dprint(), dpxint();
  * Driver information for auto-configuration stuff.
  */
 int    dpprobe(), dpattach(), dpinit(), dpioctl(), dprint(), dpxint();
-int    dpoutput(), dpreset(), dptimeout(), dpstart(), x25_ifoutput(), dptestoutput();
+int    dpoutput(), dpreset(), dptimeout(), dpstart(), dptestoutput();
+int    x25_ifoutput(), x25_rtrequest();
 
 struct uba_device *dpinfo[NDP];
 
 
 struct uba_device *dpinfo[NDP];
 
@@ -69,37 +97,11 @@ u_short     dpstd[] = { 0 };
 struct uba_driver dpdriver =
        { dpprobe, 0, dpattach, 0, dpstd, "dp", dpinfo };
 
 struct uba_driver dpdriver =
        { dpprobe, 0, dpattach, 0, dpstd, "dp", dpinfo };
 
-/*
- * debug info
- */
-struct dpstat {
-       long    start;
-       long    nohdr;
-       long    init;
-       long    rint;
-       long    xint;
-       long    reset;
-       long    ioctl;
-       long    down;
-       long    mchange;
-       long    timeout;
-       long    rsm;
-       long    rem;
-       long    rsmchr;
-       long    rga;
-} dpstat;
 /*
  * Pdma structures for fast interrupts.
  */
 struct pdma dppdma[2*NDP];
 
 /*
  * Pdma structures for fast interrupts.
  */
 struct pdma dppdma[2*NDP];
 
-/* error reporting intervals */
-#define DPI_RPNBFS     50
-#define DPI_RPDSC      1
-#define DPI_RPTMO      10
-#define DPI_RPDCK      10
-
-
 /*
  * DP software status per interface.
  *
 /*
  * DP software status per interface.
  *
@@ -117,21 +119,51 @@ struct dp_softc {
 #define DPF_ONLINE     0x02            /* device running (had a RDYO) */
 #define DPF_RESTART    0x04            /* software restart in progress */
 #define DPF_FLUSH      0x08            /* had a ROVR, flush ipkt when done */
 #define DPF_ONLINE     0x02            /* device running (had a RDYO) */
 #define DPF_RESTART    0x04            /* software restart in progress */
 #define DPF_FLUSH      0x08            /* had a ROVR, flush ipkt when done */
+#define DPF_X25UP      0x10            /* XXX -- someday we'll do PPP also */
        short   dp_ostate;              /* restarting, etc. */
        short   dp_istate;              /* not sure this is necessary */
 #define DPS_IDLE       0
 #define DPS_RESTART    1
 #define DPS_ACTIVE     2
 #define DPS_XEM                3               /* transmitting CRC, etc. */
        short   dp_ostate;              /* restarting, etc. */
        short   dp_istate;              /* not sure this is necessary */
 #define DPS_IDLE       0
 #define DPS_RESTART    1
 #define DPS_ACTIVE     2
 #define DPS_XEM                3               /* transmitting CRC, etc. */
-       int     dp_errors[4];           /* non-fatal error counters */
-#define dp_datck dp_errors[0]
-#define dp_timeo dp_errors[1]
-#define dp_nobuf dp_errors[2]
-#define dp_disc  dp_errors[3]
+       short   dp_olen;                /* length of last packet sent */
+       short   dp_ilen;                /* length of last packet recvd */
        char    dp_obuf[DP_MTU+8];
        char    dp_ibuf[DP_MTU+8];
 } dp_softc[NDP];
 
        char    dp_obuf[DP_MTU+8];
        char    dp_ibuf[DP_MTU+8];
 } dp_softc[NDP];
 
+/*
+ * Debug info
+ */
+struct dpstat {
+       long    start;
+       long    nohdr;
+       long    init;
+       long    rint;
+       long    xint;
+       long    reset;
+       long    ioctl;
+       long    down;
+       long    mchange;
+       long    timeout;
+       long    rsm;
+       long    rem;
+       long    remchr;
+       long    rga;
+       long    xem;
+       long    rovr;
+} dpstat;
+
+short dp_ilb = 0;
+short dp_log = 0;
+
+#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
+int dp_sizes[] = {
+       sizeof(dp_softc[0]), sizeof(struct ifnet),
+       _offsetof(struct dp_softc, dp_obuf[0]),
+       _offsetof(struct dp_softc, dp_ibuf[0]),
+       };
+
 dpprobe(reg, ui)
        caddr_t reg;
        struct  uba_device *ui;
 dpprobe(reg, ui)
        caddr_t reg;
        struct  uba_device *ui;
@@ -172,6 +204,9 @@ dpattach(ui)
        dp->dp_if.if_mtu = DP_MTU;
        dp->dp_if.if_init = dpinit;
        dp->dp_if.if_output = x25_ifoutput;
        dp->dp_if.if_mtu = DP_MTU;
        dp->dp_if.if_init = dpinit;
        dp->dp_if.if_output = x25_ifoutput;
+       dp->dp_if.if_type = IFT_X25;
+       dp->dp_if.if_hdrlen = 5;
+       dp->dp_if.if_addrlen = 8;
        dp->dp_if.if_start = dpstart;
        dp->dp_if.if_ioctl = dpioctl;
        dp->dp_if.if_reset = dpreset;
        dp->dp_if.if_start = dpstart;
        dp->dp_if.if_ioctl = dpioctl;
        dp->dp_if.if_reset = dpreset;
@@ -239,11 +274,12 @@ dpinit(unit)
        pdp->p_mem = pdp->p_end = dp->dp_ibuf + DP_MTU + 8;
 
        addr->dpclr = DP_CLR;
        pdp->p_mem = pdp->p_end = dp->dp_ibuf + DP_MTU + 8;
 
        addr->dpclr = DP_CLR;
-       DELAY(1000);
+       DELAY(5000);
        /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),
                            CRC = CCIIT, initially all ones, 2nd addr = 0 */
        addr->dpsar = DP_SSLM | DP_IDLE;
        /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),
                            CRC = CCIIT, initially all ones, 2nd addr = 0 */
        addr->dpsar = DP_SSLM | DP_IDLE;
-       addr->dpclr = 0;
+       addr->dpclr = DP_XE | dp_ilb;
+       addr->dptdsr = DP_XSM;
        /* enable receiver, receive interrupt, DTR, RTS */
        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
        dpstart(&dp->dp_if);
        /* enable receiver, receive interrupt, DTR, RTS */
        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
        dpstart(&dp->dp_if);
@@ -272,7 +308,7 @@ dpstart(ifp)
         */
        dpstat.start++;
        if ((dp->dp_if.if_flags & IFF_OACTIVE) ||
         */
        dpstat.start++;
        if ((dp->dp_if.if_flags & IFF_OACTIVE) ||
-           ! (dp->dp_if.if_flags & IFF_RUNNING))
+           (dp->dp_if.if_flags & IFF_RUNNING) == 0)
                goto out;
        IF_DEQUEUE(&dp->dp_if.if_snd, m);
        if (m == 0)
                goto out;
        IF_DEQUEUE(&dp->dp_if.if_snd, m);
        if (m == 0)
@@ -287,31 +323,36 @@ dpstart(ifp)
                m = m0;
                dpstat.nohdr++;
        }
                m = m0;
                dpstat.nohdr++;
        }
-       if (len == 0)
+       if (len < 2)
                goto out;
        if (len > DP_MTU) {
                error = EINVAL;
                goto out;
        }
                goto out;
        if (len > DP_MTU) {
                error = EINVAL;
                goto out;
        }
-       dppdma[2*unit].p_mem = 1 + (cp = dp->dp_obuf);
+       dppdma[2*unit].p_mem = cp = dp->dp_obuf;
        while (m) {
                struct mbuf *n;
                bcopy(mtod(m, caddr_t), (caddr_t)cp, m->m_len);
                cp += m->m_len;
                MFREE(m, n); m = n;
        }
        while (m) {
                struct mbuf *n;
                bcopy(mtod(m, caddr_t), (caddr_t)cp, m->m_len);
                cp += m->m_len;
                MFREE(m, n); m = n;
        }
-       dppdma[2*unit].p_end = cp;
+       dppdma[2*unit].p_end = cp - 1;
        dp->dp_if.if_flags |= IFF_OACTIVE;
        dp->dp_ostate = DPS_ACTIVE;
        dp->dp_if.if_collisions--;
        dp->dp_if.if_flags |= IFF_OACTIVE;
        dp->dp_ostate = DPS_ACTIVE;
        dp->dp_if.if_collisions--;
+       dp->dp_olen = len;
+       if (dp_log) {
+               register u_char *p = (u_char *)dp->dp_obuf;
+               log(LOG_DEBUG, "dpoutput(%d):%x %x %x %x %x\n",
+                       len, p[0], p[1], p[2], p[3], p[4]);
+       }
        addr->dpsar = DP_SSLM | DP_IDLE;
        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
        addr->dpsar = DP_SSLM | DP_IDLE;
        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
-       addr->dpclr = DP_XIE | DP_XE;
-       addr->dptdsr = DP_XSM | (0xff & *cp);
+       addr->dpclr = DP_XIE | DP_XE | dp_ilb;
+       addr->dptdsr = DP_XSM;
 out:
        return (error);
 }
 out:
        return (error);
 }
-long dp_rdsr;
 /*
  * Receive done or error interrupt
  */
 /*
  * Receive done or error interrupt
  */
@@ -323,7 +364,6 @@ register struct dpdevice *addr;
        short rdsr = addr->dprdsr, rcsr = pdma->p_arg;
 
        dpstat.rint++;
        short rdsr = addr->dprdsr, rcsr = pdma->p_arg;
 
        dpstat.rint++;
-dp_rdsr = rdsr;
        splx(dp->dp_ipl);
        if (rdsr & DP_RGA) {
                /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),
        splx(dp->dp_ipl);
        if (rdsr & DP_RGA) {
                /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),
@@ -339,23 +379,27 @@ dp_rdsr = rdsr;
                if (rcsr & DP_RDR) {
                    dp->dp_ibuf[0] = rdsr & DP_RBUF;
                    pdma->p_mem++;
                if (rcsr & DP_RDR) {
                    dp->dp_ibuf[0] = rdsr & DP_RBUF;
                    pdma->p_mem++;
-                   dpstat.rsmchr++;
                }
                dp->dp_flags &= ~DPF_FLUSH;
                return;
        }
        if (rdsr & DP_REM) { /* Received End of Message */
                dpstat.rem++;
                }
                dp->dp_flags &= ~DPF_FLUSH;
                return;
        }
        if (rdsr & DP_REM) { /* Received End of Message */
                dpstat.rem++;
+               if (rcsr & DP_RDR) {
+                   *(pdma->p_mem++) = rdsr;
+                   dpstat.remchr++;
+               }
+               dp->dp_ilen = pdma->p_mem - dp->dp_ibuf;
                if (rdsr & DP_REC || dp->dp_flags & DPF_FLUSH) {
                        dp->dp_if.if_ierrors++;
                } else
                if (rdsr & DP_REC || dp->dp_flags & DPF_FLUSH) {
                        dp->dp_if.if_ierrors++;
                } else
-                       dpinput(&dp->dp_if,
-                               pdma->p_mem - dp->dp_ibuf, dp->dp_ibuf);
+                       dpinput(&dp->dp_if, dp->dp_ilen, dp->dp_ibuf);
                pdma->p_mem = pdma->p_end;
                dp->dp_flags &= ~ DPF_FLUSH;
                return;
        }
        if (rdsr & DP_ROVR) {
                pdma->p_mem = pdma->p_end;
                dp->dp_flags &= ~ DPF_FLUSH;
                return;
        }
        if (rdsr & DP_ROVR) {
+               dpstat.rovr++;
                dp->dp_flags |= DPF_FLUSH;
                return;
        }
                dp->dp_flags |= DPF_FLUSH;
                return;
        }
@@ -369,10 +413,8 @@ dp_rdsr = rdsr;
        }
        dp->dp_flags |= DPF_FLUSH;
        if (pdma->p_mem != pdma->p_end)
        }
        dp->dp_flags |= DPF_FLUSH;
        if (pdma->p_mem != pdma->p_end)
-               log("dp%d: unexplained receiver interrupt\n", unit);
+               log(LOG_DEBUG, "dp%d: unexplained receiver interrupt\n", unit);
 }
 }
-int dp_fill;
-
 /*
  * Transmit complete or error interrupt
  */
 /*
  * Transmit complete or error interrupt
  */
@@ -386,7 +428,7 @@ register struct dpdevice *addr;
        splx(dp->dp_ipl);
        dpstat.xint++;
        if (addr->dptdsr & DP_XERR) {
        splx(dp->dp_ipl);
        dpstat.xint++;
        if (addr->dptdsr & DP_XERR) {
-               log("if_dp%d: data late\n", unit);
+               log(LOG_DEBUG, "if_dp%d: data late\n", unit);
        restart:
                pdma->p_mem = dp->dp_obuf;
                addr->dptdsr = DP_XSM;
        restart:
                pdma->p_mem = dp->dp_obuf;
                addr->dptdsr = DP_XSM;
@@ -397,33 +439,33 @@ register struct dpdevice *addr;
 
        case DPS_ACTIVE:
                if (pdma->p_mem != pdma->p_end) {
 
        case DPS_ACTIVE:
                if (pdma->p_mem != pdma->p_end) {
-                       log("if_dp%d: misc error in dpxint\n", unit);
+                       log(LOG_DEBUG, "if_dp%d: misc error in dpxint\n", unit);
                        goto restart;
                }
                        goto restart;
                }
-               addr->dpclr = DP_XIE; /* &= ~DP_XE */
-               addr->dptdsr = DP_XEM;
+               addr->dpsar = DP_IDLE|DP_SSLM;
+               addr->dpclr = DP_XE | DP_XIE | dp_ilb;
+               addr->dptdsr = DP_XEM | (0xff & pdma->p_mem[0]);
+               addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
                dp->dp_ostate = DPS_XEM;
                break;
 
        case DPS_XEM:
                dp->dp_ostate = DPS_XEM;
                break;
 
        case DPS_XEM:
+               dpstat.xem++;
                dp->dp_if.if_opackets++;
                dp->dp_if.if_opackets++;
+               dp->dp_ostate = DPS_IDLE;
                dp->dp_if.if_flags &= ~IFF_OACTIVE;
                if (dp->dp_if.if_snd.ifq_len)
                        dpstart(&dp->dp_if);
                else {
                dp->dp_if.if_flags &= ~IFF_OACTIVE;
                if (dp->dp_if.if_snd.ifq_len)
                        dpstart(&dp->dp_if);
                else {
-                       if (dp_fill) {
-                               addr->dpsar = DP_IDLE|DP_SSLM;
-                               addr->dptdsr = DP_XABO;
-                       } else {
-                               addr->dptdsr = 0;
-                       }
-                       addr->dpclr = 0;
-                       dp->dp_ostate = DPS_IDLE;
+                       addr->dpsar = DP_IDLE|DP_SSLM;
+                       addr->dpclr = DP_XE | dp_ilb;
+                       addr->dptdsr = DP_XSM;
+                       addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR|DP_RTS;
                }
                break;
 
        default:
                }
                break;
 
        default:
-               log("if_dp%d: impossible state in dpxint\n");
+               log(LOG_DEBUG, "if_dp%d: impossible state in dpxint\n");
        }
 }
 /*
        }
 }
 /*
@@ -504,9 +546,15 @@ caddr_t buffer;
        register struct ifqueue *inq;
        register struct mbuf *m;
        extern struct ifqueue hdintrq, ipintrq;
        register struct ifqueue *inq;
        register struct mbuf *m;
        extern struct ifqueue hdintrq, ipintrq;
-       int netisr;
+       int isr;
 
        ifp->if_ipackets++;
 
        ifp->if_ipackets++;
+       if (dp_log) {
+               register u_char *p = (u_char *)buffer;
+               log(LOG_DEBUG, "dpinput(%d):%x %x %x %x %x\n",
+                       len, p[0], p[1], p[2], p[3], p[4]);
+       }
+       
     {
        register struct ifaddr *ifa = ifp->if_addrlist;
        register u_char *cp = (u_char *)buffer;
     {
        register struct ifaddr *ifa = ifp->if_addrlist;
        register u_char *cp = (u_char *)buffer;
@@ -520,10 +568,10 @@ caddr_t buffer;
                buffer += 4;
                len -= 4;
                inq = &ipintrq;
                buffer += 4;
                len -= 4;
                inq = &ipintrq;
-               netisr = NETISR_IP;
+               isr = NETISR_IP;
        } else {
                inq = &hdintrq;
        } else {
                inq = &hdintrq;
-               netisr = NETISR_CCITT;
+               isr = NETISR_CCITT;
        }
     }
        if (len <= 0)
        }
     }
        if (len <= 0)
@@ -538,7 +586,7 @@ caddr_t buffer;
                m_freem(m);
        } else {
                IF_ENQUEUE(inq, m);
                m_freem(m);
        } else {
                IF_ENQUEUE(inq, m);
-               schednetisr(netisr);
+               schednetisr(isr);
        }
 }
 
        }
 }
 
@@ -556,26 +604,16 @@ dpioctl(ifp, cmd, data)
 
        dpstat.ioctl++;
        switch (cmd) {
 
        dpstat.ioctl++;
        switch (cmd) {
-
-       case SIOCSIFADDR:
-               ifp->if_flags |= IFF_UP;
-               switch (ifa->ifa_addr->sa_family) {
-               case AF_INET:
-                       ifp->if_output = dptestoutput;
-               default:
-                       dpinit(ifp->if_unit);
-                       break;
-               }
-               break;
-#ifdef CCITT
        case SIOCSIFCONF_X25:
                ifp->if_flags |= IFF_UP;
        case SIOCSIFCONF_X25:
                ifp->if_flags |= IFF_UP;
-               ifp->if_output = x25_ifoutput;
                error = hd_ctlinput(PRC_IFUP, ifa->ifa_addr);
                if (error == 0)
                        dpinit(ifp->if_unit);
                break;
                error = hd_ctlinput(PRC_IFUP, ifa->ifa_addr);
                if (error == 0)
                        dpinit(ifp->if_unit);
                break;
-#endif
+
+       case SIOCSIFADDR:
+               ifa->ifa_rtrequest = x25_rtrequest;
+               break;
 
        case SIOCSIFFLAGS:
                if ((ifp->if_flags & IFF_UP) == 0 &&
 
        case SIOCSIFFLAGS:
                if ((ifp->if_flags & IFF_UP) == 0 &&