From: Jonathan Matthew Subject: Re: iavf patch [1/4]: Add support of TSO To: Yuichiro NAITO Cc: tech@openbsd.org Date: Tue, 20 May 2025 19:45:14 +1000 On Fri, Feb 07, 2025 at 04:20:06PM +0900, Yuichiro NAITO wrote: > After my previous mail, iavf check-sum offload patch has been committed. > > https://marc.info/?l=openbsd-tech&m=173226223303941&w=2 > > I rebased proceeding patches for OpenBSD current. > I will send the patches one by one, please apply by the order of mails. > > This patch enables TSO feature. There is no difference from before. > > OK? Thanks, and apologies for the delay in looking at this. I've committed your diff with some changes to update the TCP TSO counters as we do in other drivers. > > diff --git a/sys/dev/pci/if_iavf.c b/sys/dev/pci/if_iavf.c > index 70309635646..4d40592e41a 100644 > --- a/sys/dev/pci/if_iavf.c > +++ b/sys/dev/pci/if_iavf.c > @@ -82,6 +82,8 @@ > #include > #include > > +#define IAVF_MAX_DMA_SEG_SIZE ((16 * 1024) - 1) > + > #define I40E_MASK(mask, shift) ((mask) << (shift)) > #define I40E_AQ_LARGE_BUF 512 > > @@ -388,6 +390,10 @@ struct iavf_tx_desc { > #define IAVF_TX_DESC_BSIZE_MASK \ > (IAVF_TX_DESC_BSIZE_MAX << IAVF_TX_DESC_BSIZE_SHIFT) > > +#define IAVF_TX_CTX_DESC_CMD_TSO 0x10 > +#define IAVF_TX_CTX_DESC_TLEN_SHIFT 30 > +#define IAVF_TX_CTX_DESC_MSS_SHIFT 50 > + > #define IAVF_TX_DESC_L2TAG1_SHIFT 48 > #define IAVF_TX_DESC_L2TAG1_MASK (0xffff << IAVF_TX_DESC_L2TAG1_SHIFT) > } __packed __aligned(16); > @@ -899,6 +905,7 @@ iavf_attach(struct device *parent, struct device *self, void *aux) > ifp->if_capabilities |= IFCAP_CSUM_IPv4 | > IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4 | > IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; > + ifp->if_capabilities |= IFCAP_TSOv4 | IFCAP_TSOv6; > > ifmedia_init(&sc->sc_media, 0, iavf_media_change, iavf_media_status); > > @@ -1565,7 +1572,7 @@ iavf_txr_alloc(struct iavf_softc *sc, unsigned int qid) > txm = &maps[i]; > > if (bus_dmamap_create(sc->sc_dmat, > - IAVF_HARDMTU, IAVF_TX_PKT_DESCS, IAVF_HARDMTU, 0, > + MAXMCLBYTES, IAVF_TX_PKT_DESCS, IAVF_MAX_DMA_SEG_SIZE, 0, > BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, > &txm->txm_map) != 0) > goto uncreate; > @@ -1661,7 +1668,7 @@ iavf_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m) > } > > static uint64_t > -iavf_tx_offload(struct mbuf *m) > +iavf_tx_offload(struct mbuf *m, struct iavf_tx_ring *txr, unsigned int prod) > { > struct ether_extracted ext; > uint64_t hlen; > @@ -1676,7 +1683,7 @@ iavf_tx_offload(struct mbuf *m) > #endif > > if (!ISSET(m->m_pkthdr.csum_flags, > - M_IPV4_CSUM_OUT|M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)) > + M_IPV4_CSUM_OUT|M_TCP_CSUM_OUT|M_UDP_CSUM_OUT|M_TCP_TSO)) > return (offload); > > ether_extract_headers(m, &ext); > @@ -1708,6 +1715,32 @@ iavf_tx_offload(struct mbuf *m) > << IAVF_TX_DESC_L4LEN_SHIFT; > } > > + if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)) { > + if (ext.tcp && m->m_pkthdr.ph_mss > 0) { > + struct iavf_tx_desc *ring, *txd; > + uint64_t cmd = 0, paylen, outlen; > + > + hlen += ext.tcphlen; > + > + /* > + * The MSS should not be set to a lower value than 64 > + * or larger than 9668 bytes. > + */ > + outlen = MIN(9668, MAX(64, m->m_pkthdr.ph_mss)); > + paylen = m->m_pkthdr.len - ETHER_HDR_LEN - hlen; > + ring = IAVF_DMA_KVA(&txr->txr_mem); > + txd = &ring[prod]; > + > + cmd |= IAVF_TX_DESC_DTYPE_CONTEXT; > + cmd |= IAVF_TX_CTX_DESC_CMD_TSO; > + cmd |= paylen << IAVF_TX_CTX_DESC_TLEN_SHIFT; > + cmd |= outlen << IAVF_TX_CTX_DESC_MSS_SHIFT; > + > + htolem64(&txd->addr, 0); > + htolem64(&txd->cmd, cmd); > + } > + } > + > return offload; > } > > @@ -1748,7 +1781,8 @@ iavf_start(struct ifqueue *ifq) > mask = sc->sc_tx_ring_ndescs - 1; > > for (;;) { > - if (free <= IAVF_TX_PKT_DESCS) { > + /* We need one extra descriptor for TSO packets. */ > + if (free <= (IAVF_TX_PKT_DESCS + 1)) { > ifq_set_oactive(ifq); > break; > } > @@ -1757,11 +1791,17 @@ iavf_start(struct ifqueue *ifq) > if (m == NULL) > break; > > - offload = iavf_tx_offload(m); > + offload = iavf_tx_offload(m, txr, prod); > > txm = &txr->txr_maps[prod]; > map = txm->txm_map; > > + if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)) { > + prod++; > + prod &= mask; > + free--; > + } > + > if (iavf_load_mbuf(sc->sc_dmat, map, m) != 0) { > ifq->ifq_errors++; > m_freem(m); > > -- > Yuichiro NAITO (naito.yuichiro@gmail.com) >