From 2964abb447258e8408062974b5a17f12f218dd11 Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 2 Apr 2024 20:59:48 +0000 Subject: [PATCH] Implement and enable TSO in vmx(4) Tested with IPv4/IPv6 and vlan(4). ok jmatthew@ --- sys/dev/pci/if_vmx.c | 45 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c index d94e052f0b9..81bb0834cff 100644 --- a/sys/dev/pci/if_vmx.c +++ b/sys/dev/pci/if_vmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vmx.c,v 1.82 2024/02/29 22:09:33 jan Exp $ */ +/* $OpenBSD: if_vmx.c,v 1.83 2024/04/02 20:59:48 jan Exp $ */ /* * Copyright (c) 2013 Tsubai Masanari @@ -34,11 +34,14 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include @@ -407,6 +410,8 @@ vmxnet3_attach(struct device *parent, struct device *self, void *aux) ifp->if_capabilities |= IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; } + ifp->if_capabilities |= IFCAP_TSOv4 | IFCAP_TSOv6; + #if NVLAN > 0 if (sc->sc_ds->upt_features & UPT1_F_VLAN) ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; @@ -579,8 +584,8 @@ vmxnet3_alloc_txring(struct vmxnet3_softc *sc, int queue, int intr) comp_ring->txcd = VMX_DMA_KVA(&comp_ring->dmamem); for (idx = 0; idx < NTXDESC; idx++) { - if (bus_dmamap_create(sc->sc_dmat, JUMBO_LEN, NTXSEGS, - VMXNET3_TX_LEN_M + 1, 0, BUS_DMA_NOWAIT, &ring->dmap[idx])) + if (bus_dmamap_create(sc->sc_dmat, MAXMCLBYTES, NTXSEGS, + VMXNET3_TX_LEN_M, 0, BUS_DMA_NOWAIT, &ring->dmap[idx])) return -1; } @@ -1440,13 +1445,41 @@ vmxnet3_tx_offload(struct vmxnet3_txdesc *sop, struct mbuf *m) offset = hdrlen + offsetof(struct tcphdr, th_sum); else if (ext.udp) offset = hdrlen + offsetof(struct udphdr, uh_sum); + else + return; + + if (!ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)) { + hdrlen &= VMXNET3_TX_HLEN_M; + offset &= VMXNET3_TX_OP_M; + + sop->tx_word3 |= htole32(VMXNET3_OM_CSUM << VMXNET3_TX_OM_S); + sop->tx_word3 |= htole32(hdrlen << VMXNET3_TX_HLEN_S); + sop->tx_word2 |= htole32(offset << VMXNET3_TX_OP_S); + return; + } + + /* + * TCP Segmentation Offload + */ + + if (ext.tcp == NULL) { + tcpstat_inc(tcps_outbadtso); + return; + } + + if (ext.ip4) + ext.ip4->ip_sum = 0; + + hdrlen += ext.tcphlen; hdrlen &= VMXNET3_TX_HLEN_M; - offset &= VMXNET3_TX_OP_M; - sop->tx_word3 |= htole32(VMXNET3_OM_CSUM << VMXNET3_TX_OM_S); + sop->tx_word3 |= htole32(VMXNET3_OM_TSO << VMXNET3_TX_OM_S); sop->tx_word3 |= htole32(hdrlen << VMXNET3_TX_HLEN_S); - sop->tx_word2 |= htole32(offset << VMXNET3_TX_OP_S); + sop->tx_word2 |= htole32(m->m_pkthdr.ph_mss << VMXNET3_TX_OP_S); + + tcpstat_add(tcps_outpkttso, (m->m_pkthdr.len - hdrlen + + m->m_pkthdr.ph_mss - 1) / m->m_pkthdr.ph_mss); } void -- 2.20.1