Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/qbus Redo previous in a better way:



details:   https://anonhg.NetBSD.org/src/rev/4b84c30eacef
branches:  trunk
changeset: 541721:4b84c30eacef
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Jan 17 15:45:59 2003 +0000

description:
Redo previous in a better way:
allocate a static buffer, which is added at the end of short packets
to pad the buffer to ETHER_MIN_LEN - ETHER_CRC_LEN.
While I'm there fix 2 bugs:
in qeinit(), unload the right dmamap if bus_dmamap_load fails
in qestart, don't dmamap_load the mbuf if its len is 0.
Tested on simh-vax.

diffstat:

 sys/dev/qbus/if_qe.c |  78 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 57 insertions(+), 21 deletions(-)

diffs (194 lines):

diff -r 78c8f652187b -r 4b84c30eacef sys/dev/qbus/if_qe.c
--- a/sys/dev/qbus/if_qe.c      Fri Jan 17 15:41:05 2003 +0000
+++ b/sys/dev/qbus/if_qe.c      Fri Jan 17 15:45:59 2003 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: if_qe.c,v 1.56 2003/01/15 22:10:25 bouyer Exp $ */
+/*      $NetBSD: if_qe.c,v 1.57 2003/01/17 15:45:59 bouyer Exp $ */
 /*
  * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
  *
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_qe.c,v 1.56 2003/01/15 22:10:25 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_qe.c,v 1.57 2003/01/17 15:45:59 bouyer Exp $");
 
 #include "opt_inet.h"
 #include "bpfilter.h"
@@ -95,6 +95,7 @@
        struct mbuf*    sc_rxmbuf[RXDESCS];
        bus_dmamap_t    sc_xmtmap[TXDESCS];
        bus_dmamap_t    sc_rcvmap[RXDESCS];
+       bus_dmamap_t    sc_nulldmamap;  /* ethernet padding buffer      */
        struct ubinfo   sc_ui;
        int             sc_intvec;      /* Interrupt vector             */
        int             sc_nexttx;
@@ -125,6 +126,8 @@
 #define        LOWORD(x)       ((int)(x) & 0xffff)
 #define        HIWORD(x)       (((int)(x) >> 16) & 0x3f)
 
+#define        ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
+
 /*
  * Check for present DEQNA. Done by sending a fake setup packet
  * and wait for interrupt.
@@ -215,6 +218,7 @@
        struct  qe_ring *rp;
        u_int8_t enaddr[ETHER_ADDR_LEN];
        int i, error;
+       char *nullbuf;
 
        sc->sc_iot = ua->ua_iot;
        sc->sc_ioh = ua->ua_ioh;
@@ -224,7 +228,7 @@
          * Allocate DMA safe memory for descriptors and setup memory.
          */
 
-       sc->sc_ui.ui_size = sizeof(struct qe_cdata);
+       sc->sc_ui.ui_size = sizeof(struct qe_cdata) + ETHER_PAD_LEN;
        if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) {
                printf(": unable to ubmemalloc(), error = %d\n", error);
                return;
@@ -235,7 +239,8 @@
        /*
         * Zero the newly allocated memory.
         */
-       bzero(sc->sc_qedata, sizeof(struct qe_cdata));
+       bzero(sc->sc_qedata, sizeof(struct qe_cdata) + ETHER_PAD_LEN);
+       nullbuf = ((char*)sc->sc_qedata) + sizeof(struct qe_cdata);
        /*
         * Create the transmit descriptor DMA maps. We take advantage
         * of the fact that the Qbus address space is big, and therefore 
@@ -275,6 +280,21 @@
                }
        }
 
+       if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1,
+           ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT,&sc->sc_nulldmamap)) != 0) {
+               printf("%s: unable to create pad buffer DMA map, "
+                   "error = %d\n", sc->sc_dev.dv_xname, error);
+               goto fail_6;
+       }
+       if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap,
+           nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) {
+               printf("%s: unable to load pad buffer DMA map, "
+                   "error = %d\n", sc->sc_dev.dv_xname, error);
+               goto fail_7;
+       }
+       bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN,
+           BUS_DMASYNC_PREWRITE);
+
        /*
         * Create ring loops of the buffer chains.
         * This is only done once.
@@ -338,10 +358,12 @@
         * Free any resources we've allocated during the failed attach
         * attempt.  Do this in reverse order and fall through.
         */
+ fail_7:
+       bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap);
  fail_6:
        for (i = 0; i < RXDESCS; i++) {
                if (sc->sc_rxmbuf[i] != NULL) {
-                       bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
+                       bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
                        m_freem(sc->sc_rxmbuf[i]);
                }
        }
@@ -427,7 +449,7 @@
        struct qe_cdata *qc = sc->sc_qedata;
        paddr_t buffer;
        struct mbuf *m, *m0;
-       int idx, len, s, i, totlen, error;
+       int idx, len, s, i, totlen, buflen, error;
        short orword, csr;
 
        if ((QE_RCSR(QE_CSR_CSR) & QE_RCV_ENABLE) == 0)
@@ -452,6 +474,11 @@
                for (m0 = m, i = 0; m0; m0 = m0->m_next)
                        if (m0->m_len)
                                i++;
+               if (m->m_pkthdr.len < ETHER_PAD_LEN) {
+                       buflen = ETHER_PAD_LEN;
+                       i++;
+               } else
+                       buflen = m->m_pkthdr.len;
                if (i >= TXDESCS)
                        panic("qestart");
 
@@ -471,20 +498,26 @@
                 * Loop around and set it.
                 */
                totlen = 0;
-               for (m0 = m; m0; m0 = m0->m_next) {
-                       error = bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[idx],
-                           mtod(m0, void *), m0->m_len, 0, 0);
-                       buffer = sc->sc_xmtmap[idx]->dm_segs[0].ds_addr;
-                       len = m0->m_len;
-                       if (len == 0)
-                               continue;
+               for (m0 = m; ; m0 = m0->m_next) {
+                       if (m0) {
+                               if (m0->m_len == 0)
+                                       continue;
+                               error = bus_dmamap_load(sc->sc_dmat,
+                                   sc->sc_xmtmap[idx], mtod(m0, void *),
+                                   m0->m_len, 0, 0);
+                               buffer = sc->sc_xmtmap[idx]->dm_segs[0].ds_addr;
+                               len = m0->m_len;
+                       } else if (totlen < ETHER_PAD_LEN) {
+                               buffer = sc->sc_nulldmamap->dm_segs[0].ds_addr;
+                               len = ETHER_PAD_LEN - totlen;
+                       } else {
+                               break;
+                       }
 
                        totlen += len;
                        /* Word alignment calc */
                        orword = 0;
-                       if (totlen == m->m_pkthdr.len) {
-                               if (totlen < ETHER_MIN_LEN)
-                                       len += (ETHER_MIN_LEN - totlen);
+                       if (totlen == buflen) {
                                orword |= QE_EOMSG;
                                sc->sc_txmbuf[idx] = m;
                        }
@@ -494,8 +527,6 @@
                                orword |= QE_ODDBEGIN;
                        if ((buffer + len) & 1)
                                orword |= QE_ODDEND;
-                       if (len > m0->m_len) {
-                               memset(buffer + m0->m_len, 0, len - m0->m_len);
                        qc->qc_xmit[idx].qe_buf_len = -(len/2);
                        qc->qc_xmit[idx].qe_addr_lo = LOWORD(buffer);
                        qc->qc_xmit[idx].qe_addr_hi = HIWORD(buffer);
@@ -505,9 +536,11 @@
                        if (++idx == TXDESCS)
                                idx = 0;
                        sc->sc_inq++;
+                       if (m0 == NULL)
+                               break;
                }
 #ifdef DIAGNOSTIC
-               if (totlen != m->m_pkthdr.len)
+               if (totlen != buflen)
                        panic("qestart: len fault");
 #endif
 
@@ -583,10 +616,13 @@
 
                        if (qc->qc_xmit[idx].qe_addr_hi & QE_SETUP)
                                continue;
-                       bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[idx]);
+                       if (sc->sc_txmbuf[idx] == NULL ||
+                           sc->sc_txmbuf[idx]->m_pkthdr.len < ETHER_PAD_LEN)
+                               bus_dmamap_unload(sc->sc_dmat,
+                                   sc->sc_xmtmap[idx]);
                        if (sc->sc_txmbuf[idx]) {
                                m_freem(sc->sc_txmbuf[idx]);
-                               sc->sc_txmbuf[idx] = 0;
+                               sc->sc_txmbuf[idx] = NULL;
                        }
                }
                ifp->if_timer = 0;



Home | Main Index | Thread Index | Old Index