Download raw body.
igc(4) tso
I addressed your comment and also noticed that the diff broke with
previous convention of using the ISSET macro.
Is this ok?
mbuhl
Index: dev/pci/if_igc.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_igc.c,v
diff -u -p -r1.20 if_igc.c
--- dev/pci/if_igc.c 12 Apr 2024 19:27:43 -0000 1.20
+++ dev/pci/if_igc.c 2 May 2024 18:49:07 -0000
@@ -44,10 +44,14 @@
#include <net/if.h>
#include <net/if_media.h>
+#include <net/route.h>
#include <net/toeplitz.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
#if NBPFILTER > 0
#include <net/bpf.h>
@@ -796,6 +800,7 @@ igc_setup_interface(struct igc_softc *sc
ifp->if_capabilities |= IFCAP_CSUM_IPv4;
ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
ifp->if_capabilities |= IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6;
+ ifp->if_capabilities |= IFCAP_TSOv4 | IFCAP_TSOv6;
/* Initialize ifmedia structures. */
ifmedia_init(&sc->media, IFM_IMASK, igc_media_change, igc_media_status);
@@ -993,8 +998,6 @@ igc_start(struct ifqueue *ifq)
continue;
}
- olinfo_status = m->m_pkthdr.len << IGC_ADVTXD_PAYLEN_SHIFT;
-
bus_dmamap_sync(txr->txdma.dma_tag, map, 0,
map->dm_mapsize, BUS_DMASYNC_PREWRITE);
@@ -2025,12 +2028,15 @@ igc_tx_ctx_setup(struct tx_ring *txr, st
{
struct ether_extracted ext;
struct igc_adv_tx_context_desc *txdesc;
+ uint32_t mss_l4len_idx = 0;
uint32_t type_tucmd_mlhl = 0;
uint32_t vlan_macip_lens = 0;
int off = 0;
- ether_extract_headers(mp, &ext);
- vlan_macip_lens |= (sizeof(*ext.eh) << IGC_ADVTXD_MACLEN_SHIFT);
+ if (ISSET(mp->m_pkthdr.csum_flags, M_TCP_TSO))
+ *olinfo_status = 0;
+ else
+ *olinfo_status = mp->m_pkthdr.len << IGC_ADVTXD_PAYLEN_SHIFT;
/*
* In advanced descriptors the vlan tag must
@@ -2046,6 +2052,10 @@ igc_tx_ctx_setup(struct tx_ring *txr, st
}
#endif
+ ether_extract_headers(mp, &ext);
+
+ vlan_macip_lens |= (sizeof(*ext.eh) << IGC_ADVTXD_MACLEN_SHIFT);
+
if (ext.ip4) {
type_tucmd_mlhl |= IGC_ADVTXD_TUCMD_IPV4;
if (ISSET(mp->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT)) {
@@ -2056,6 +2066,9 @@ igc_tx_ctx_setup(struct tx_ring *txr, st
} else if (ext.ip6) {
type_tucmd_mlhl |= IGC_ADVTXD_TUCMD_IPV6;
#endif
+ } else {
+ if (ISSET(mp->m_pkthdr.csum_flags, M_TCP_TSO))
+ tcpstat_inc(tcps_outbadtso);
}
vlan_macip_lens |= ext.iphlen;
@@ -2075,6 +2088,29 @@ igc_tx_ctx_setup(struct tx_ring *txr, st
}
}
+ if (ISSET(mp->m_pkthdr.csum_flags, M_TCP_TSO)) {
+ if (ext.tcp) {
+ uint32_t hdrlen, thlen, paylen, outlen;
+
+ thlen = ext.tcphlen;
+
+ outlen = mp->m_pkthdr.ph_mss;
+ mss_l4len_idx |= outlen << IGC_ADVTXD_MSS_SHIFT;
+ mss_l4len_idx |= thlen << IGC_ADVTXD_L4LEN_SHIFT;
+
+ hdrlen = sizeof(*ext.eh) + ext.iphlen + thlen;
+ paylen = mp->m_pkthdr.len - hdrlen;
+ *olinfo_status |= paylen << IGC_ADVTXD_PAYLEN_SHIFT;
+
+ *cmd_type_len |= IGC_ADVTXD_DCMD_TSE;
+ off = 1;
+
+ tcpstat_add(tcps_outpkttso,
+ (paylen + outlen - 1) / outlen);
+ } else
+ tcpstat_inc(tcps_outbadtso);
+ }
+
if (off == 0)
return 0;
@@ -2085,7 +2121,7 @@ igc_tx_ctx_setup(struct tx_ring *txr, st
htolem32(&txdesc->vlan_macip_lens, vlan_macip_lens);
htolem32(&txdesc->type_tucmd_mlhl, type_tucmd_mlhl);
htolem32(&txdesc->seqnum_seed, 0);
- htolem32(&txdesc->mss_l4len_idx, 0);
+ htolem32(&txdesc->mss_l4len_idx, mss_l4len_idx);
return 1;
}
igc(4) tso