Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/marvell Add workaround for infrequently encountered ...



details:   https://anonhg.NetBSD.org/src/rev/f8560305c0fd
branches:  trunk
changeset: 771317:f8560305c0fd
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Sat Nov 19 17:01:38 2011 +0000

description:
Add workaround for infrequently encountered DMA engine limitation.

diffstat:

 sys/dev/marvell/if_mvgbe.c |  35 ++++++++++++++++++++++++++++++++---
 1 files changed, 32 insertions(+), 3 deletions(-)

diffs (77 lines):

diff -r f58fe392fcb5 -r f8560305c0fd sys/dev/marvell/if_mvgbe.c
--- a/sys/dev/marvell/if_mvgbe.c        Sat Nov 19 16:41:55 2011 +0000
+++ b/sys/dev/marvell/if_mvgbe.c        Sat Nov 19 17:01:38 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_mvgbe.c,v 1.13 2011/09/06 19:38:23 rjs Exp $        */
+/*     $NetBSD: if_mvgbe.c,v 1.14 2011/11/19 17:01:38 jakllsch Exp $   */
 /*
  * Copyright (c) 2007, 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.13 2011/09/06 19:38:23 rjs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.14 2011/11/19 17:01:38 jakllsch Exp $");
 
 #include "rnd.h"
 
@@ -1517,6 +1517,7 @@
        bus_dmamap_t txmap;
        uint32_t first, current, last, cmdsts = 0;
        int m_csumflags, i;
+       bool needs_defrag = false;
 
        DPRINTFN(3, ("mvgbe_encap\n"));
 
@@ -1535,6 +1536,16 @@
         */
        m_csumflags = m_head->m_pkthdr.csum_flags;
 
+do_defrag:
+       if (__predict_false(needs_defrag == true)) {
+               /* A small unaligned segment was detected. */
+               struct mbuf *m_new;
+               m_new = m_defrag(m_head, M_DONTWAIT);
+               if (m_new == NULL)
+                       return EFBIG;
+               m_head = m_new;
+       }
+
        /*
         * Start packing the mbufs in this chain into
         * the fragment pointers. Stop when we run out
@@ -1545,6 +1556,25 @@
                return ENOBUFS;
        }
 
+       txseg = txmap->dm_segs;
+
+       if (__predict_true(needs_defrag == false)) {
+               /*
+                * Detect rarely encountered DMA limitation.
+                */
+               for (i = 0; i < txmap->dm_nsegs; i++) {
+                       if (((txseg[i].ds_addr & 7) != 0) &&
+                           (txseg[i].ds_len <= 8) &&
+                           (txseg[i].ds_len >= 1)
+                           ) {
+                               txseg = NULL;
+                               bus_dmamap_unload(sc->sc_dmat, txmap);
+                               needs_defrag = true;
+                               goto do_defrag;
+                       }
+               }
+       }
+
        /* Sync the DMA map. */
        bus_dmamap_sync(sc->sc_dmat, txmap, 0, txmap->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
@@ -1556,7 +1586,6 @@
                return ENOBUFS;
        }
 
-       txseg = txmap->dm_segs;
 
        DPRINTFN(2, ("mvgbe_encap: dm_nsegs=%d\n", txmap->dm_nsegs));
 



Home | Main Index | Thread Index | Old Index