Use m_defrag in fxp to make it nicer and simpler.

works for me with
fxp0 at pci6 dev 6 function 0 "Intel 8255x" rev 0x08, i82559: apic 6 int 21, 
address 00:d0:b7:4c:36:c4
inphy0 at fxp0 phy 1: i82555 10/100 PHY, rev. 4

It would be possible to drop the mbuf on error and then the ifq_deq_begin
and ifq_deq_rollback dance could be even more simplified.
-- 
:wq Claudio

Index: dev/ic/fxp.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/fxp.c,v
retrieving revision 1.127
diff -u -p -r1.127 fxp.c
--- dev/ic/fxp.c        25 Nov 2015 03:09:58 -0000      1.127
+++ dev/ic/fxp.c        1 Dec 2015 13:52:53 -0000
@@ -673,8 +673,8 @@ fxp_start(struct ifnet *ifp)
        struct fxp_softc *sc = ifp->if_softc;
        struct fxp_txsw *txs = sc->sc_cbt_prod;
        struct fxp_cb_tx *txc;
-       struct mbuf *m0, *m = NULL;
-       int cnt = sc->sc_cbt_cnt, seg;
+       struct mbuf *m0;
+       int cnt = sc->sc_cbt_cnt, seg, error;
 
        if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
                return;
@@ -691,38 +691,22 @@ fxp_start(struct ifnet *ifp)
                if (m0 == NULL)
                        break;
 
-               if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
-                   m0, BUS_DMA_NOWAIT) != 0) {
-                       MGETHDR(m, M_DONTWAIT, MT_DATA);
-                       if (m == NULL) {
-                               ifq_deq_rollback(&ifp->if_snd, m0);
-                               break;
-                       }
-                       if (m0->m_pkthdr.len > MHLEN) {
-                               MCLGET(m, M_DONTWAIT);
-                               if (!(m->m_flags & M_EXT)) {
-                                       m_freem(m);
-                                       ifq_deq_rollback(&ifp->if_snd, m0);
-                                       break;
-                               }
-                       }
-                       m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
-                       m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
-                       if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
-                           m, BUS_DMA_NOWAIT) != 0) {
-                               m_freem(m);
+               error = bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
+                   m0, BUS_DMA_NOWAIT);
+               if (error == EFBIG) {
+                       if (m_defrag(m0, M_DONTWAIT)) {
                                ifq_deq_rollback(&ifp->if_snd, m0);
                                break;
                        }
+                       error = bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
+                           m0, BUS_DMA_NOWAIT);
                }
-
-               ifq_deq_commit(&ifp->if_snd, m0);
-               if (m != NULL) {
-                       m_freem(m0);
-                       m0 = m;
-                       m = NULL;
+               if (error != 0) {
+                       ifq_deq_rollback(&ifp->if_snd, m0);
+                       break;
                }
 
+               ifq_deq_commit(&ifp->if_snd, m0);
                txs->tx_mbuf = m0;
 
 #if NBPFILTER > 0

Reply via email to