Source-Changes-HG archive

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

[src/trunk]: src/sys/dev - Allocate mbuf dynamically on Tx and use bus_dmamap...



details:   https://anonhg.NetBSD.org/src/rev/c9fc0727f1d5
branches:  trunk
changeset: 485370:c9fc0727f1d5
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Wed Apr 26 14:02:34 2000 +0000

description:
- Allocate mbuf dynamically on Tx and use bus_dmamap_load_mbuf(9).
- Call bus_dmamap_sync(9) as appropriate.
- Leave only register declarations in rtl81x9reg.h and
  split other stuff into rtl81x9var.h.

bus_dma(9) code mostly taken from thorpej's if_rtp.c.

diffstat:

 sys/dev/cardbus/if_rl_cardbus.c |    3 +-
 sys/dev/ic/rtl81x9.c            |  194 ++++++++++++++++++++--------------------
 sys/dev/ic/rtl81x9reg.h         |  106 +---------------------
 sys/dev/ic/rtl81x9var.h         |  137 ++++++++++++++++++++++++++++
 sys/dev/pci/if_rl_pci.c         |    3 +-
 5 files changed, 239 insertions(+), 204 deletions(-)

diffs (truncated from 616 to 300 lines):

diff -r 73b677c5d3f1 -r c9fc0727f1d5 sys/dev/cardbus/if_rl_cardbus.c
--- a/sys/dev/cardbus/if_rl_cardbus.c   Wed Apr 26 13:38:13 2000 +0000
+++ b/sys/dev/cardbus/if_rl_cardbus.c   Wed Apr 26 14:02:34 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_rl_cardbus.c,v 1.4 2000/04/24 15:25:00 tsutsui Exp $        */
+/*     $NetBSD: if_rl_cardbus.c,v 1.5 2000/04/26 14:02:36 tsutsui Exp $        */
 /*
  * Copyright (c) 2000 Masanori Kanaoka
  * All rights reserved.
@@ -93,6 +93,7 @@
 #define RL_USEIOSPACE 
 
 #include <dev/ic/rtl81x9reg.h>
+#include <dev/ic/rtl81x9var.h>
 
 /*
  * Various supported device vendors/types and their names.
diff -r 73b677c5d3f1 -r c9fc0727f1d5 sys/dev/ic/rtl81x9.c
--- a/sys/dev/ic/rtl81x9.c      Wed Apr 26 13:38:13 2000 +0000
+++ b/sys/dev/ic/rtl81x9.c      Wed Apr 26 14:02:34 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtl81x9.c,v 1.3 2000/04/25 14:16:46 tsutsui Exp $      */
+/*     $NetBSD: rtl81x9.c,v 1.4 2000/04/26 14:02:34 tsutsui Exp $      */
 
 /*
  * Copyright (c) 1997, 1998
@@ -137,6 +137,7 @@
  */
 
 #include <dev/ic/rtl81x9reg.h>
+#include <dev/ic/rtl81x9var.h>
 
 #if defined DEBUG
 #define STATIC
@@ -144,8 +145,6 @@
 #define STATIC static
 #endif
 
-STATIC int rl_encap            __P((struct rl_softc *, struct mbuf * ));
-
 STATIC void rl_rxeof           __P((struct rl_softc *));
 STATIC void rl_txeof           __P((struct rl_softc *));
 STATIC void rl_start           __P((struct ifnet *));
@@ -174,7 +173,6 @@
 STATIC int rl_list_tx_init     __P((struct rl_softc *));
 
 STATIC int rl_ether_ioctl __P((struct ifnet *, u_long, caddr_t));
-STATIC int rl_allocsndbuf __P((struct rl_softc *, int));
 
 
 #define EE_SET(x)                                      \
@@ -650,6 +648,10 @@
        /* now program new ones */
        ETHER_FIRST_MULTI(step, &sc->ethercom, enm);
        while (enm != NULL) {
+               if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
+                   ETHER_ADDR_LEN) != 0)
+                       continue;
+
                h = rl_calchash(enm->enm_addrlo);
                if (h < 32)
                        hashes[0] |= (1 << h);
@@ -744,8 +746,14 @@
        }
 
        for (i = 0; i < RL_TX_LIST_CNT; i++)
-                    if (rl_allocsndbuf(sc, i))
-                            goto fail;
+               if ((error = bus_dmamap_create(sc->sc_dmat,
+                   MCLBYTES, 1,
+                   MCLBYTES, 0, BUS_DMA_NOWAIT,
+                   &sc->snd_dmamap[i])) != 0) {
+                       printf("%s: can't create snd buffer DMA map,"
+                           " error = %d\n", sc->sc_dev.dv_xname, error);
+                   goto fail;
+       }
 
        ifp = &sc->ethercom.ec_if;
        ifp->if_softc = sc;
@@ -873,7 +881,11 @@
 
        while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) {
                rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx;
+               bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx,
+                   sizeof(u_int32_t *), BUS_DMASYNC_POSTREAD);
                rxstat = le32toh(*(u_int32_t *)rxbufpos);
+               bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx,
+                   sizeof(u_int32_t *), BUS_DMASYNC_PREREAD);
 
                /*
                 * Here's a totally undocumented fact for you. When the
@@ -939,6 +951,9 @@
                if (rx_bytes > max_bytes)
                        break;
 
+               bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap,
+                   cur_rx + sizeof(u_int32_t), total_len, BUS_DMASYNC_POSTREAD);
+
                rxbufpos = sc->rl_cdata.rl_rx_buf +
                        ((cur_rx + sizeof(u_int32_t)) % RL_RXBUFLEN);
 
@@ -994,10 +1009,10 @@
                 */
                if (ifp->if_bpf) {
                        bpf_mtap(ifp->if_bpf, m);
-                       if (ifp->if_flags & IFF_PROMISC &&
-                               (bcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
-                                               ETHER_ADDR_LEN) &&
-                                       (eh->ether_dhost[0] & 1) == 0)) {
+                       if ((ifp->if_flags & IFF_PROMISC) != 0 &&
+                               ETHER_IS_MULTICAST(eh->ether_dhost) == 0 &&
+                               memcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
+                                               ETHER_ADDR_LEN) != 0) {
                                m_freem(m);
                                continue;
                        }
@@ -1005,6 +1020,10 @@
 #endif
                /* pass it on. */
                (*ifp->if_input)(ifp, m);
+
+               bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap,
+                   cur_rx + sizeof(u_int32_t),
+                   total_len, BUS_DMASYNC_PREREAD);
        }
 
        return;
@@ -1035,11 +1054,17 @@
                    RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT)))
                        break;
 
+               bus_dmamap_sync(sc->sc_dmat,
+                   sc->snd_dmamap[sc->rl_cdata.last_tx], 0,
+                   sc->snd_dmamap[sc->rl_cdata.last_tx]->dm_mapsize,
+                   BUS_DMASYNC_POSTWRITE);
+               bus_dmamap_unload(sc->sc_dmat,
+                   sc->snd_dmamap[sc->rl_cdata.last_tx]);
+               m_freem(RL_LAST_TXMBUF(sc));
+               RL_LAST_TXMBUF(sc) = NULL;
+
                ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
 
-               if (RL_LAST_TXMBUF(sc) != NULL) {
-                       RL_LAST_TXMBUF(sc) = NULL;
-               }
                if (txstat & RL_TXSTAT_TX_OK)
                        ifp->if_opackets++;
                else {
@@ -1106,84 +1131,6 @@
        return (handled);
 }
 
-STATIC int
-rl_allocsndbuf(sc, idx)
-       struct rl_softc *sc;
-       int idx;
-{
-       struct mbuf *m_new = NULL;
-       int error;
-
-       MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-       if (m_new == NULL) {
-               printf("%s: no memory for tx list", sc->sc_dev.dv_xname);
-               return(1);
-       }
-
-       MCLGET(m_new, M_DONTWAIT);
-       if (!(m_new->m_flags & M_EXT)) {
-               m_freem(m_new);
-               printf("%s: no memory for tx list", sc->sc_dev.dv_xname);
-               return(1);
-       }
-
-       if ((error = bus_dmamap_create(sc->sc_dmat,
-           MCLBYTES, 1,
-           MCLBYTES, 0, BUS_DMA_NOWAIT,
-           &sc->snd_dmamap[idx])) != 0) {
-               printf("%s: can't create snd buffer DMA map, error = %d\n",
-                      sc->sc_dev.dv_xname, error);
-               return (1);
-       }
-
-       if ((error = bus_dmamap_load(sc->sc_dmat, sc->snd_dmamap[idx],
-           mtod(m_new, caddr_t), MCLBYTES, NULL,
-           BUS_DMA_NOWAIT)) != 0) {
-               printf("%s: can't load snd buffer DMA map, error = %d\n",
-                      sc->sc_dev.dv_xname, error);
-               return (1);
-       }
-
-       sc->sndbuf[idx] = m_new;
-       return (0);
-}
-
-/*
- * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
- * pointers to the fragment pointers.
- */
-STATIC int rl_encap(sc, m_head)
-       struct rl_softc         *sc;
-       struct mbuf             *m_head;
-{
-       struct mbuf             *m_new;
-
-       /*
-        * The RealTek is brain damaged and wants longword-aligned
-        * TX buffers, plus we can only have one fragment buffer
-        * per packet. We have to copy pretty much all the time.
-        */
-
-       m_new = sc->sndbuf[sc->rl_cdata.cur_tx];
-
-       m_copydata(m_head, 0, m_head->m_pkthdr.len,     
-                               mtod(m_new, caddr_t));
-       m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
-       m_freem(m_head);
-       m_head = m_new;
-
-       /* Pad frames to at least 60 bytes. */
-       if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) {
-               m_head->m_pkthdr.len +=
-                       (RL_MIN_FRAMELEN - m_head->m_pkthdr.len);
-               m_head->m_len = m_head->m_pkthdr.len;
-       }
-
-       RL_CUR_TXMBUF(sc) = m_head;
-
-       return(0);
-}
-
 /*
  * Main transmit routine.
  */
@@ -1192,7 +1139,8 @@
        struct ifnet            *ifp;
 {
        struct rl_softc         *sc;
-       struct mbuf             *m_head = NULL;
+       struct mbuf             *m_head = NULL, *m_new;
+       int                     error, idx, len;
 
        sc = ifp->if_softc;
 
@@ -1201,7 +1149,50 @@
                if (m_head == NULL)
                        break;
 
-               rl_encap(sc, m_head);
+               idx = sc->rl_cdata.cur_tx;
+
+               /*
+                * Load the DMA map.  If this fails, the packet didn't
+                * fit in one DMA segment, and we need to copy.  Note,
+                * the packet must also be aligned.
+                */
+               if ((mtod(m_head, bus_addr_t) & 3) != 0 ||
+                   bus_dmamap_load_mbuf(sc->sc_dmat, sc->snd_dmamap[idx],
+                       m_head, BUS_DMA_NOWAIT) != 0) {
+                       MGETHDR(m_new, M_DONTWAIT, MT_DATA);
+                       if (m_new == NULL) {
+                               printf("%s: unable to allocate Tx mbuf\n",
+                                   sc->sc_dev.dv_xname);
+                               IF_PREPEND(&ifp->if_snd, m_new);
+                               break;
+                       }
+                       if (m_head->m_pkthdr.len > MHLEN) {
+                               MCLGET(m_new, M_DONTWAIT);
+                               if ((m_new->m_flags & M_EXT) == 0) {
+                                       printf("%s: unable to allocate Tx "
+                                           "cluster\n", sc->sc_dev.dv_xname);
+                                       m_freem(m_new);
+                                       IF_PREPEND(&ifp->if_snd, m_head);
+                                       break;
+                               }
+                       }
+                       m_copydata(m_head, 0, m_head->m_pkthdr.len,
+                           mtod(m_new, caddr_t));
+                       m_new->m_pkthdr.len = m_new->m_len =
+                           m_head->m_pkthdr.len;
+                       m_freem(m_head);
+                       m_head = m_new;
+                       error = bus_dmamap_load_mbuf(sc->sc_dmat,
+                           sc->snd_dmamap[idx], m_head, BUS_DMA_NOWAIT);
+                       if (error) {
+                               printf("%s: unable to load Tx buffer, "
+                                   "error = %d\n", sc->sc_dev.dv_xname, error);
+                               IF_PREPEND(&ifp->if_snd, m_head);
+                               break;
+                       }
+               }
+
+               RL_CUR_TXMBUF(sc) = m_head;
 
 #if NBPFILTER > 0
                /*
@@ -1214,10 +1205,17 @@
                /*
                 * Transmit the frame.
                 */
+               bus_dmamap_sync(sc->sc_dmat,



Home | Main Index | Thread Index | Old Index