Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/iflib.c
Show First 20 Lines • Show All 3,106 Lines • ▼ Show 20 Lines | calc_next_txd(iflib_txq_t txq, int cidx, uint8_t qid) | ||||
return (next < end ? next : start); | return (next < end ? next : start); | ||||
} | } | ||||
/* | /* | ||||
* Pad an mbuf to ensure a minimum ethernet frame size. | * Pad an mbuf to ensure a minimum ethernet frame size. | ||||
* min_frame_size is the frame size (less CRC) to pad the mbuf to | * min_frame_size is the frame size (less CRC) to pad the mbuf to | ||||
*/ | */ | ||||
static __noinline int | static __noinline int | ||||
iflib_ether_pad(device_t dev, struct mbuf *m_head, uint16_t min_frame_size) | iflib_ether_pad(device_t dev, struct mbuf **m_head, uint16_t min_frame_size) | ||||
{ | { | ||||
/* | /* | ||||
* 18 is enough bytes to pad an ARP packet to 46 bytes, and | * 18 is enough bytes to pad an ARP packet to 46 bytes, and | ||||
* and ARP message is the smallest common payload I can think of | * and ARP message is the smallest common payload I can think of | ||||
*/ | */ | ||||
static char pad[18]; /* just zeros */ | static char pad[18]; /* just zeros */ | ||||
int n; | int n; | ||||
struct mbuf *new_head; | |||||
for (n = min_frame_size - m_head->m_pkthdr.len; | if (!M_WRITABLE(*m_head)) { | ||||
new_head = m_dup(*m_head, M_NOWAIT); | |||||
if (new_head == NULL) { | |||||
device_printf(dev, "cannot pad short frame, m_dup() failed"); | |||||
return ENOMEM; | |||||
} | |||||
m_freem(*m_head); | |||||
*m_head = new_head; | |||||
} | |||||
for (n = min_frame_size - (*m_head)->m_pkthdr.len; | |||||
n > 0; n -= sizeof(pad)) | n > 0; n -= sizeof(pad)) | ||||
if (!m_append(m_head, min(n, sizeof(pad)), pad)) | if (!m_append(*m_head, min(n, sizeof(pad)), pad)) | ||||
break; | break; | ||||
if (n > 0) { | if (n > 0) { | ||||
m_freem(m_head); | m_freem(*m_head); | ||||
device_printf(dev, "cannot pad short frame\n"); | device_printf(dev, "cannot pad short frame\n"); | ||||
DBG_COUNTER_INC(encap_pad_mbuf_fail); | DBG_COUNTER_INC(encap_pad_mbuf_fail); | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | iflib_encap(iflib_txq_t txq, struct mbuf **m_headp) | ||||
if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { | if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { | ||||
desc_tag = txq->ift_tso_desc_tag; | desc_tag = txq->ift_tso_desc_tag; | ||||
max_segs = scctx->isc_tx_tso_segments_max; | max_segs = scctx->isc_tx_tso_segments_max; | ||||
} else { | } else { | ||||
desc_tag = txq->ift_desc_tag; | desc_tag = txq->ift_desc_tag; | ||||
max_segs = scctx->isc_tx_nsegments; | max_segs = scctx->isc_tx_nsegments; | ||||
} | } | ||||
m_head = *m_headp; | |||||
if ((sctx->isc_flags & IFLIB_NEED_ETHER_PAD) && | if ((sctx->isc_flags & IFLIB_NEED_ETHER_PAD) && | ||||
__predict_false(m_head->m_pkthdr.len < scctx->isc_min_frame_size)) { | __predict_false(m_head->m_pkthdr.len < scctx->isc_min_frame_size)) { | ||||
err = iflib_ether_pad(ctx->ifc_dev, m_head, scctx->isc_min_frame_size); | err = iflib_ether_pad(ctx->ifc_dev, m_headp, scctx->isc_min_frame_size); | ||||
if (err) | if (err) | ||||
return err; | return err; | ||||
} | } | ||||
m_head = *m_headp; | |||||
pkt_info_zero(&pi); | pkt_info_zero(&pi); | ||||
pi.ipi_mflags = (m_head->m_flags & (M_VLANTAG|M_BCAST|M_MCAST)); | pi.ipi_mflags = (m_head->m_flags & (M_VLANTAG|M_BCAST|M_MCAST)); | ||||
pi.ipi_pidx = pidx; | pi.ipi_pidx = pidx; | ||||
pi.ipi_qsidx = txq->ift_id; | pi.ipi_qsidx = txq->ift_id; | ||||
pi.ipi_len = m_head->m_pkthdr.len; | pi.ipi_len = m_head->m_pkthdr.len; | ||||
pi.ipi_csum_flags = m_head->m_pkthdr.csum_flags; | pi.ipi_csum_flags = m_head->m_pkthdr.csum_flags; | ||||
pi.ipi_vtag = (m_head->m_flags & M_VLANTAG) ? m_head->m_pkthdr.ether_vtag : 0; | pi.ipi_vtag = (m_head->m_flags & M_VLANTAG) ? m_head->m_pkthdr.ether_vtag : 0; | ||||
▲ Show 20 Lines • Show All 2,623 Lines • Show Last 20 Lines |