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