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