summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/em/if_em.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c
index 3f8792a..1a41390 100644
--- a/sys/dev/em/if_em.c
+++ b/sys/dev/em/if_em.c
@@ -1486,20 +1486,45 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
tx_buffer = &adapter->tx_buffer_area[adapter->next_avail_tx_desc];
tx_buffer_last = tx_buffer;
map = tx_buffer->map;
- error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, m_head, segs, &nsegs,
- BUS_DMA_NOWAIT);
- if (error != 0) {
+ error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, *m_headp, segs,
+ &nsegs, BUS_DMA_NOWAIT);
+ if (error == EFBIG) {
+ struct mbuf *m;
+
+ m = m_defrag(*m_headp, M_DONTWAIT);
+ if (m == NULL) {
+ /* Assume m_defrag(9) used only m_get(9). */
+ adapter->mbuf_alloc_failed++;
+ m_freem(*m_headp);
+ *m_headp = NULL;
+ return (ENOBUFS);
+ }
+ *m_headp = m;
+ error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, *m_headp,
+ segs, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ adapter->no_tx_dma_setup++;
+ m_freem(*m_headp);
+ *m_headp = NULL;
+ return (error);
+ }
+ } else if (error != 0) {
adapter->no_tx_dma_setup++;
return (error);
}
- KASSERT(nsegs != 0, ("em_encap: empty packet"));
+ if (nsegs == 0) {
+ m_freem(*m_headp);
+ *m_headp = NULL;
+ return (EIO);
+ }
if (nsegs > adapter->num_tx_desc_avail) {
adapter->no_tx_desc_avail2++;
- error = ENOBUFS;
- goto encap_fail;
+ bus_dmamap_unload(adapter->txtag, map);
+ return (ENOBUFS);
}
+ m_head = *m_headp;
if (ifp->if_hwassist > 0)
em_transmit_checksum_setup(adapter, m_head, &txd_upper, &txd_lower);
else
@@ -1526,8 +1551,8 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
if (txd_used == adapter->num_tx_desc_avail) {
adapter->next_avail_tx_desc = txd_saved;
adapter->no_tx_desc_avail2++;
- error = ENOBUFS;
- goto encap_fail;
+ bus_dmamap_unload(adapter->txtag, map);
+ return (ENOBUFS);
}
tx_buffer = &adapter->tx_buffer_area[i];
current_tx_desc = &adapter->tx_desc_base[i];
@@ -1599,10 +1624,6 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
}
return (0);
-
-encap_fail:
- bus_dmamap_unload(adapter->txtag, map);
- return (error);
}
/*********************************************************************
OpenPOWER on IntegriCloud