Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/qbus Fix a transmit bug and get a little more out fr...



details:   https://anonhg.NetBSD.org/src/rev/7e6c218f1abc
branches:  trunk
changeset: 487501:7e6c218f1abc
user:      ragge <ragge%NetBSD.org@localhost>
date:      Thu Jun 08 19:58:49 2000 +0000

description:
Fix a transmit bug and get a little more out from the receive logic.

diffstat:

 sys/dev/qbus/if_de.c |  289 ++++++++++++++++++--------------------------------
 1 files changed, 105 insertions(+), 184 deletions(-)

diffs (truncated from 508 to 300 lines):

diff -r 38da123dc256 -r 7e6c218f1abc sys/dev/qbus/if_de.c
--- a/sys/dev/qbus/if_de.c      Thu Jun 08 19:01:44 2000 +0000
+++ b/sys/dev/qbus/if_de.c      Thu Jun 08 19:58:49 2000 +0000
@@ -1,4 +1,5 @@
-/*     $NetBSD: if_de.c,v 1.4 2000/06/05 00:09:18 matt Exp $   */
+/*     $NetBSD: if_de.c,v 1.5 2000/06/08 19:58:49 ragge Exp $  */
+
 /*
  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
@@ -49,7 +50,6 @@
  */
 
 #include "opt_inet.h"
-#include "opt_iso.h"
 #include "bpfilter.h"
 
 #include <sys/param.h>
@@ -127,16 +127,12 @@
        bus_dmamap_t sc_cmap;
        struct de_cdata *sc_dedata;     /* Control structure */
        struct de_cdata *sc_pdedata;    /* Bus-mapped control structure */
-#ifdef notdef
-       bus_dmamap_t sc_xmtmap[NXMT];   /* unibus xmit maps */
-       struct mbuf *sc_txmbuf[NXMT];
-#endif
        bus_dmamap_t sc_rcvmap[NRCV];   /* unibus receive maps */
        struct mbuf *sc_rxmbuf[NRCV];
-       int sc_nexttx;                  /* next tx descriptor to put data on */
-       int sc_nextrx;                  /* next rx descriptor for recv */
-       int sc_inq;                     /* # if xmit packets in queue */
-       int sc_lastack;                 /* Last handled rx descriptor */
+       int     sc_xindex;              /* UNA index into transmit chain */
+       int     sc_rindex;              /* UNA index into receive chain */
+       int     sc_xfree;               /* index for next transmit buffer */
+       int     sc_nxmit;               /* # of transmits in progress */
        void *sc_sh;                    /* shutdownhook cookie */
 };
 
@@ -148,10 +144,8 @@
 static void dereset(struct device *);
 static void destart(struct ifnet *);
 static void derecv(struct de_softc *);
-static void dexmit(struct de_softc *);
 static void deintr(void *);
 static int de_add_rxbuf(struct de_softc *, int);
-static void desetup(struct de_softc *sc);
 static void deshutdown(void *);
 
 struct cfattach de_ca = {
@@ -244,23 +238,6 @@
        bzero(sc->sc_dedata, sizeof(struct de_cdata));
        sc->sc_pdedata = (struct de_cdata *)sc->sc_cmap->dm_segs[0].ds_addr;
 
-#ifdef notdef
-       /*
-        * Create the transmit descriptor DMA maps.
-        *
-        * XXX - should allocate transmit map pages when needed, not here.
-        */
-       for (i = 0; i < NXMT; i++) {
-               if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
-                   MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
-                   &sc->sc_xmtmap[i]))) {
-                       printf(": unable to create tx DMA map %d, error = %d\n",
-                           i, error);
-                       goto fail_4;
-               }
-       }
-#endif
-
        /*
         * Create receive buffer DMA maps.
         */
@@ -301,15 +278,15 @@
        printf("\n%s: %s, hardware address %s\n", sc->sc_dev.dv_xname, c,
                ether_sprintf(myaddr));
 
-       uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr,
-               sc, &sc->sc_intrcnt);
+       uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc, 
+           &sc->sc_intrcnt);
        uba_reset_establish(dereset, &sc->sc_dev);
        evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
-               sc->sc_dev.dv_xname, "intr");
+           sc->sc_dev.dv_xname, "intr");
 
        strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
        ifp->if_softc = sc;
-       ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
+       ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI;
        ifp->if_ioctl = deioctl;
        ifp->if_start = destart;
        if_attach(ifp);
@@ -336,14 +313,7 @@
                if (sc->sc_rcvmap[i] != NULL)
                        bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
        }
-#ifdef notdef
-fail_4: 
-       for (i = 0; i < NXMT; i++) {
-               if (sc->sc_xmtmap[i] != NULL)
-                       bus_dmamap_destroy(sc->sc_dmat, sc->sc_xmtmap[i]);
-       }
-       bus_dmamap_unload(sc->sc_dmat, sc->sc_cmap);
-#endif
+
 fail_3:
        bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
 fail_2:
@@ -364,6 +334,7 @@
        struct de_softc *sc = (void *)dev;
 
        sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+       sc->sc_pdedata = NULL;  /* All mappings lost */
        DE_WCSR(DE_PCSR0, PCSR0_RSET);
        dewait(sc, "reset");
        deinit(sc);
@@ -410,9 +381,12 @@
        DE_WLOW(CMD_GETCMD);
        dewait(sc, "wtring");
 
-       desetup(sc);
+       sc->sc_dedata->dc_pcbb.pcbb0 = FC_WTMODE;
+       sc->sc_dedata->dc_pcbb.pcbb2 = MOD_TPAD|MOD_HDX|MOD_DRDC|MOD_ENAL;
+       DE_WLOW(CMD_GETCMD);
+       dewait(sc, "wtmode");
 
-       /* Link the transmit buffers to the descriptors */
+       /* set up the receive and transmit ring entries */
        for (i = 0; i < NXMT; i++) {
                dc->dc_xrent[i].r_flags = 0;
                dc->dc_xrent[i].r_segbl = LOWORD(&pdc->dc_xbuf[i][0]);
@@ -421,17 +395,14 @@
 
        for (i = 0; i < NRCV; i++)
                dc->dc_rrent[i].r_flags = RFLG_OWN;
-       sc->sc_nexttx = sc->sc_inq = sc->sc_lastack = sc->sc_nextrx = 0;
 
        /* start up the board (rah rah) */
        s = splnet();
+       sc->sc_rindex = sc->sc_xindex = sc->sc_xfree = sc->sc_nxmit = 0;
        sc->sc_if.if_flags |= IFF_RUNNING;
-       DE_WLOW(PCSR0_INTE);            /* Change to interrupts */
-       DELAY(500);
+       DE_WLOW(PCSR0_INTE);                    /* avoid interlock */
+       destart(&sc->sc_if);            /* queue output packets */
        DE_WLOW(CMD_START|PCSR0_INTE);
-       dewait(sc, "start");
-       DE_WLOW(CMD_PDMD|PCSR0_INTE);
-       dewait(sc, "initpoll");
        splx(s);
 }
 
@@ -446,54 +417,45 @@
 {
        struct de_softc *sc = ifp->if_softc;
        struct de_cdata *dc;
+       struct de_ring *rp;
        struct mbuf *m;
-       int idx, s, running;
+       int nxmit;
 
        /*
         * the following test is necessary, since
         * the code is not reentrant and we have
         * multiple transmission buffers.
         */
-       if (ifp->if_flags & IFF_OACTIVE) /* Too much to do already */
+       if (sc->sc_if.if_flags & IFF_OACTIVE)
                return;
-
-       if (ifp->if_snd.ifq_head == 0)   /* Nothing to do at all */
-               return;
-
-       s = splimp();
        dc = sc->sc_dedata;
-       running = (sc->sc_inq != 0);
-       while (sc->sc_inq < (NXMT - 1)) {
-
-               idx = sc->sc_nexttx;
-               IF_DEQUEUE(&ifp->if_snd, m);
+       for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) {
+               IF_DEQUEUE(&sc->sc_if.if_snd, m);
                if (m == 0)
-                       goto out;
+                       break;
+               rp = &dc->dc_xrent[sc->sc_xfree];
+               if (rp->r_flags & XFLG_OWN)
+                       panic("deuna xmit in progress");
+               m_copydata(m, 0, m->m_pkthdr.len, &dc->dc_xbuf[sc->sc_xfree][0]);
+               rp->r_slen = m->m_pkthdr.len;
+               rp->r_tdrerr = 0;
+               rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
 
 #if NBPFILTER > 0
                if (ifp->if_bpf)
                        bpf_mtap(ifp->if_bpf, m);
 #endif
-               m_copydata(m, 0, m->m_pkthdr.len, &dc->dc_xbuf[idx][0]);
-               dc->dc_xrent[idx].r_slen = m->m_pkthdr.len;
-               dc->dc_xrent[idx].r_tdrerr = 0;
-               dc->dc_xrent[idx].r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
+
                m_freem(m);
-
-               sc->sc_inq++;
-               if (++sc->sc_nexttx == NXMT)
-                       sc->sc_nexttx = 0;
-               ifp->if_timer = 5; /* If transmit logic dies */
+               sc->sc_xfree++;
+               if (sc->sc_xfree == NXMT)
+                       sc->sc_xfree = 0;
        }
-       if (sc->sc_inq == (NXMT - 1))
-               ifp->if_flags |= IFF_OACTIVE;
-
-out:   if (running == 0) {
-               DE_WLOW(PCSR0_INTE|CMD_PDMD);
-               dewait(sc, "poll");
+       if (sc->sc_nxmit != nxmit) {
+               sc->sc_nxmit = nxmit;
+               if (ifp->if_flags & IFF_RUNNING)
+                       DE_WLOW(PCSR0_INTE|CMD_PDMD);
        }
-
-       splx(s);
 }
 
 /*
@@ -502,79 +464,59 @@
 void
 deintr(void *arg)
 {
+       struct de_cdata *dc;
        struct de_softc *sc = arg;
-       short csr0, csr1;
+       struct de_ring *rp;
+       short csr0;
 
        /* save flags right away - clear out interrupt bits */
        csr0 = DE_RCSR(DE_PCSR0);
-       csr1 = DE_RCSR(DE_PCSR1);
        DE_WHIGH(csr0 >> 8);
 
-       if (csr0 & PCSR0_RXI)
-               derecv(sc);
 
-       if (csr0 & PCSR0_TXI)
-               dexmit(sc);
-
-       /* Should never end up here */
-       if (csr0 & PCSR0_PCEI) {
-               printf("%s: Port command error interrupt\n",
-                   sc->sc_dev.dv_xname);
-       }
-
-       if (csr0 & PCSR0_SERI) {
-               printf("%s: Status error interrupt\n", sc->sc_dev.dv_xname);
-       }
-
-       if (csr0 & PCSR0_RCBI) {
-               printf("%s: Receive buffer unavail interrupt\n", 
-                   sc->sc_dev.dv_xname);
-               DE_WLOW(PCSR0_INTE|CMD_PDMD);
-               dewait(sc, "repoll");
-       }
-       destart(&sc->sc_if);
-}
-
-void
-dexmit(struct de_softc *sc)
-{
-       struct ifnet *ifp = &sc->sc_if;
-       struct de_ring *rp;
+       sc->sc_if.if_flags |= IFF_OACTIVE;      /* prevent entering destart */
+       /*
+        * if receive, put receive buffer on mbuf
+        * and hang the request again
+        */
+       derecv(sc);
 
        /*
         * Poll transmit ring and check status.
+        * Be careful about loopback requests.
         * Then free buffer space and check for
         * more transmit requests.
         */
-       rp = &sc->sc_dedata->dc_xrent[sc->sc_lastack];
-       while ((rp->r_flags & XFLG_OWN) == 0) {
-               int idx = sc->sc_lastack;
-
-               if (idx == sc->sc_nexttx)
+       dc = sc->sc_dedata;
+       for ( ; sc->sc_nxmit > 0; sc->sc_nxmit--) {
+               rp = &dc->dc_xrent[sc->sc_xindex];
+               if (rp->r_flags & XFLG_OWN)
                        break;
-               if (rp->r_flags & XFLG_ENP)
-                       ifp->if_opackets++;



Home | Main Index | Thread Index | Old Index