Author: fabient
Date: Mon Jul  7 08:22:39 2014
New Revision: 268359
URL: http://svnweb.freebsd.org/changeset/base/268359

Log:
  Optim and Fix for mge driver:
  - add missing rcvif in mbuf
  - add missing ipacket stat
  - remove uncessary mbuf copy on output path
  - fix deadlock of the TX engine in case of error
  
  Obtained from:        NETASQ
  MFC after:    2 weeks

Modified:
  head/sys/dev/mge/if_mge.c

Modified: head/sys/dev/mge/if_mge.c
==============================================================================
--- head/sys/dev/mge/if_mge.c   Mon Jul  7 06:37:14 2014        (r268358)
+++ head/sys/dev/mge/if_mge.c   Mon Jul  7 08:22:39 2014        (r268359)
@@ -1140,6 +1140,8 @@ mge_intr_rx_locked(struct mge_softc *sc,
                        mb->m_pkthdr.len -= 2;
                        mb->m_data += 2;
 
+                       mb->m_pkthdr.rcvif = ifp;
+
                        mge_offload_process_frame(ifp, mb, status,
                            bufsize);
 
@@ -1159,6 +1161,8 @@ mge_intr_rx_locked(struct mge_softc *sc,
                        count -= 1;
        }
 
+       ifp->if_ipackets += rx_npkts;
+
        return (rx_npkts);
 }
 
@@ -1437,12 +1441,6 @@ mge_encap(struct mge_softc *sc, struct m
 
        ifp = sc->ifp;
 
-       /* Check for free descriptors */
-       if (sc->tx_desc_used_count + 1 >= MGE_TX_DESC_NUM) {
-               /* No free descriptors */
-               return (-1);
-       }
-
        /* Fetch unused map */
        desc_no = sc->tx_desc_curr;
        dw = &sc->mge_tx_desc[desc_no];
@@ -1451,9 +1449,16 @@ mge_encap(struct mge_softc *sc, struct m
        /* Create mapping in DMA memory */
        error = bus_dmamap_load_mbuf_sg(sc->mge_tx_dtag, mapp, m0, segs, &nsegs,
            BUS_DMA_NOWAIT);
-       if (error != 0 || nsegs != 1 ) {
+       if (error != 0) {
+               m_freem(m0);
+               return (error);
+       }
+
+       /* Only one segment is supported. */
+       if (nsegs != 1) {
                bus_dmamap_unload(sc->mge_tx_dtag, mapp);
-               return ((error != 0) ? error : -1);
+               m_freem(m0);
+               return (-1);
        }
 
        bus_dmamap_sync(sc->mge_tx_dtag, mapp, BUS_DMASYNC_PREWRITE);
@@ -1553,15 +1558,33 @@ mge_start_locked(struct ifnet *ifp)
                if (m0 == NULL)
                        break;
 
-               mtmp = m_defrag(m0, M_NOWAIT);
-               if (mtmp)
-                       m0 = mtmp;
+               if (m0->m_pkthdr.csum_flags & (CSUM_IP|CSUM_TCP|CSUM_UDP) ||
+                   m0->m_flags & M_VLANTAG) {
+                       if (M_WRITABLE(m0) == 0) {
+                               mtmp = m_dup(m0, M_NOWAIT);
+                               m_freem(m0);
+                               if (mtmp == NULL)
+                                       continue;
+                               m0 = mtmp;
+                       }
+               }
+               /* The driver support only one DMA fragment. */
+               if (m0->m_next != NULL) {
+                       mtmp = m_defrag(m0, M_NOWAIT);
+                       if (mtmp)
+                               m0 = mtmp;
+               }
 
-               if (mge_encap(sc, m0)) {
+               /* Check for free descriptors */
+               if (sc->tx_desc_used_count + 1 >= MGE_TX_DESC_NUM) {
                        IF_PREPEND(&ifp->if_snd, m0);
                        ifp->if_drv_flags |= IFF_DRV_OACTIVE;
                        break;
                }
+
+               if (mge_encap(sc, m0) != 0)
+                       break;
+
                queued++;
                BPF_MTAP(ifp, m0);
        }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to