Index: sys/dev/bnxt/if_bnxt.c =================================================================== --- sys/dev/bnxt/if_bnxt.c +++ sys/dev/bnxt/if_bnxt.c @@ -292,13 +292,14 @@ */ #define BNXT_DRIVER_VERSION "1.0.0.2" +#define BNXT_MIN_FRAME_SIZE 52 /* Frames must be padded to this size */ char bnxt_driver_version[] = BNXT_DRIVER_VERSION; extern struct if_txrx bnxt_txrx; static struct if_shared_ctx bnxt_sctx_init = { .isc_magic = IFLIB_MAGIC, .isc_driver = &bnxt_iflib_driver, .isc_nfl = 2, // Number of Free Lists - .isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ, + .isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ | IFLIB_NEED_ETHER_PAD, .isc_q_align = PAGE_SIZE, .isc_tx_maxsize = BNXT_TSO_SIZE, .isc_tx_maxsegsize = BNXT_TSO_SIZE, @@ -793,6 +794,7 @@ scctx->isc_tx_tso_size_max = BNXT_TSO_SIZE; scctx->isc_tx_tso_segsize_max = BNXT_TSO_SIZE; scctx->isc_vectors = softc->func.max_cp_rings; + scctx->isc_min_frame_size = BNXT_MIN_FRAME_SIZE; scctx->isc_txrx = &bnxt_txrx; if (scctx->isc_nrxd[0] < Index: sys/net/iflib.h =================================================================== --- sys/net/iflib.h +++ sys/net/iflib.h @@ -217,6 +217,8 @@ iflib_intr_mode_t isc_intr; uint16_t isc_max_frame_size; /* set at init time by driver */ + uint16_t isc_min_frame_size; /* set at init time by driver, only used if + IFLIB_NEED_ETHER_PAD is set. */ uint32_t isc_pause_frames; /* set by driver for iflib_timer to detect */ pci_vendor_info_t isc_vendor_info; /* set by iflib prior to attach_pre */ int isc_disable_msix; @@ -314,6 +316,10 @@ * Driver needs csum zeroed for offloading */ #define IFLIB_NEED_ZERO_CSUM 0x80 +/* + * Driver needs frames padded to some minimum length + */ +#define IFLIB_NEED_ETHER_PAD 0x100 Index: sys/net/iflib.c =================================================================== --- sys/net/iflib.c +++ sys/net/iflib.c @@ -627,11 +627,14 @@ static int iflib_encap_load_mbuf_fail; +static int iflib_encap_pad_mbuf_fail; static int iflib_encap_txq_avail_fail; static int iflib_encap_txd_encap_fail; SYSCTL_INT(_net_iflib, OID_AUTO, encap_load_mbuf_fail, CTLFLAG_RD, &iflib_encap_load_mbuf_fail, 0, "# busdma load failures"); +SYSCTL_INT(_net_iflib, OID_AUTO, encap_pad_mbuf_fail, CTLFLAG_RD, + &iflib_encap_pad_mbuf_fail, 0, "# runt frame pad failures"); SYSCTL_INT(_net_iflib, OID_AUTO, encap_txq_avail_fail, CTLFLAG_RD, &iflib_encap_txq_avail_fail, 0, "# txq avail failures"); SYSCTL_INT(_net_iflib, OID_AUTO, encap_txd_encap_fail, CTLFLAG_RD, @@ -684,9 +687,10 @@ iflib_fl_refills = iflib_fl_refills_large = iflib_tx_frees = iflib_txq_drain_flushing = iflib_txq_drain_oactive = iflib_txq_drain_notready = iflib_txq_drain_encapfail = - iflib_encap_load_mbuf_fail = iflib_encap_txq_avail_fail = - iflib_encap_txd_encap_fail = iflib_task_fn_rxs = iflib_rx_intr_enables = - iflib_fast_intrs = iflib_intr_link = iflib_intr_msix = iflib_rx_unavail = + iflib_encap_load_mbuf_fail = iflib_encap_pad_mbuf_fail = + iflib_encap_txq_avail_fail = iflib_encap_txd_encap_fail = + iflib_task_fn_rxs = iflib_rx_intr_enables = iflib_fast_intrs = + iflib_intr_link = iflib_intr_msix = iflib_rx_unavail = iflib_rx_ctx_inactive = iflib_rx_zero_len = iflib_rx_if_input = iflib_rx_mbuf_null = iflib_rxd_flush = 0; } @@ -3152,6 +3156,27 @@ max_segs = scctx->isc_tx_nsegments; } m_head = *m_headp; + if ((sctx->isc_flags & IFLIB_NEED_ETHER_PAD) && + m_head->m_pkthdr.len < scctx->isc_min_frame_size) { + /* + * 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 + */ + static char pad[18]; /* just zeros */ + int n; + + for (n = scctx->isc_min_frame_size - m_head->m_pkthdr.len; + n > 0; n -= sizeof(pad)) + if (!m_append(m_head, min(n, sizeof(pad)), pad)) + break; + + if (n > 0) { + device_printf(ctx->ifc_dev, "cannot pad short frame\n"); + m_freem(m_head); + DBG_COUNTER_INC(encap_pad_mbuf_fail); + return (0); + } + } pkt_info_zero(&pi); pi.ipi_mflags = (m_head->m_flags & (M_VLANTAG|M_BCAST|M_MCAST));