From: jan Date: Mon, 27 Jun 2022 15:11:23 +0000 (+0000) Subject: Introduce Large Receive Offloading of TCP segment offloading for ix(4). It is X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=bde39c359d9e72963516d6eecdca33fbe33904e4;p=openbsd Introduce Large Receive Offloading of TCP segment offloading for ix(4). It is disabled by default. Also add a tso option to ifconfig(8) to enable and disable this feature. ok deraadt --- diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index cc5a6995cdd..4daccdb1d69 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ifconfig.8,v 1.382 2022/05/14 07:22:10 denis Exp $ +.\" $OpenBSD: ifconfig.8,v 1.383 2022/06/27 15:11:23 jan Exp $ .\" $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $ .\" $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $ .\" @@ -31,7 +31,7 @@ .\" .\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94 .\" -.Dd $Mdocdate: May 14 2022 $ +.Dd $Mdocdate: June 27 2022 $ .Dt IFCONFIG 8 .Os .Sh NAME @@ -279,6 +279,8 @@ tag. As CSUM_TCPv4, but supports IPv6 datagrams. .It Sy CSUM_UDPv6 As above, for UDP. +.It Sy TSO +The device supports TCP segment offloading (TSO). .It Sy WOL The device supports Wake on LAN (WoL). .It Sy hardmtu @@ -486,6 +488,22 @@ Query and display information and diagnostics from GBIC and SFP modules installed in an interface. It is only supported by drivers implementing the necessary functionality on hardware which supports it. +.It Cm tso +Enable TCP segmentation offloading (TSO) if its supported by the hardware; see +.Cm hwfeatures . +TSO enabled NICs modify received TCP/IP packets. +This will also affect traffic of upper layer interfaces +.Po +e.g., +.Xr vlan 4 , +.Xr aggr 4 , +.Xr carp 4 , +etc. +.Pc . +Changing this option will re-initialize the network interface. +.It Cm -tso +Disable TSO. +TSO is disabled by default. .It Cm up Mark an interface .Dq up . diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index ed05d8f2659..ea3b29dbe2f 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.454 2022/04/07 16:41:13 naddy Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.455 2022/06/27 15:11:23 jan Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -126,7 +126,7 @@ #define HWFEATURESBITS \ "\024\1CSUM_IPv4\2CSUM_TCPv4\3CSUM_UDPv4" \ "\5VLAN_MTU\6VLAN_HWTAGGING\10CSUM_TCPv6" \ - "\11CSUM_UDPv6\20WOL" + "\11CSUM_UDPv6\17TSO\20WOL" struct ifencap { unsigned int ife_flags; @@ -470,6 +470,8 @@ const struct cmd { { "-soii", IFXF_INET6_NOSOII, 0, setifxflags }, { "monitor", IFXF_MONITOR, 0, setifxflags }, { "-monitor", -IFXF_MONITOR, 0, setifxflags }, + { "tso", IFXF_TSO, 0, setifxflags }, + { "-tso", -IFXF_TSO, 0, setifxflags }, #ifndef SMALL { "hwfeatures", NEXTARG0, 0, printifhwfeatures }, { "metric", NEXTARG, 0, setifmetric }, @@ -673,7 +675,7 @@ const struct cmd { "\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX" \ "\15LINK0\16LINK1\17LINK2\20MULTICAST" \ "\23AUTOCONF6TEMP\24MPLS\25WOL\26AUTOCONF6\27INET6_NOSOII" \ - "\30AUTOCONF4" "\31MONITOR" + "\30AUTOCONF4" "\31MONITOR" "\32TSO" int getinfo(struct ifreq *, int); void getsock(int); diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 924b605c742..cb233034d23 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.185 2022/03/15 11:22:10 jan Exp $ */ +/* $OpenBSD: if_ix.c,v 1.186 2022/06/27 15:11:23 jan Exp $ */ /****************************************************************************** @@ -160,8 +160,6 @@ void ixgbe_dma_free(struct ix_softc *, struct ixgbe_dma_alloc *); static int ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *, uint32_t *, uint32_t *); -int ixgbe_tso_setup(struct tx_ring *, struct mbuf *, uint32_t *, - uint32_t *); void ixgbe_set_ivar(struct ix_softc *, uint8_t, uint8_t, int8_t); void ixgbe_configure_ivars(struct ix_softc *); uint8_t *ixgbe_mc_array_itr(struct ixgbe_hw *, uint8_t **, uint32_t *); @@ -1924,6 +1922,9 @@ ixgbe_setup_interface(struct ix_softc *sc) ifp->if_capabilities |= IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; ifp->if_capabilities |= IFCAP_CSUM_IPv4; + if (sc->hw.mac.type != ixgbe_mac_82598EB) + ifp->if_capabilities |= IFCAP_TSO; + /* * Specify the media types supported by this sc and register * callbacks to update media and link information @@ -2868,9 +2869,10 @@ fail: void ixgbe_initialize_receive_units(struct ix_softc *sc) { + struct ifnet *ifp = &sc->arpcom.ac_if; struct rx_ring *rxr = sc->rx_rings; struct ixgbe_hw *hw = &sc->hw; - uint32_t bufsz, fctrl, srrctl, rxcsum; + uint32_t bufsz, fctrl, srrctl, rxcsum, rdrxctl; uint32_t hlreg; int i; @@ -2894,6 +2896,19 @@ ixgbe_initialize_receive_units(struct ix_softc *sc) hlreg |= IXGBE_HLREG0_JUMBOEN; IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg); + if (ISSET(ifp->if_xflags, IFXF_TSO)) { + rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + + /* This field has to be set to zero. */ + rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; + + /* Enable TSO Receive Offloading */ + rdrxctl |= IXGBE_RDRXCTL_RSCACKC; + rdrxctl |= IXGBE_RDRXCTL_FCOE_WRFIX; + + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); + } + bufsz = (sc->rx_mbuf_sz - ETHER_ALIGN) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; for (i = 0; i < sc->num_queues; i++, rxr++) { @@ -2910,6 +2925,16 @@ ixgbe_initialize_receive_units(struct ix_softc *sc) srrctl = bufsz | IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl); + if (ISSET(ifp->if_xflags, IFXF_TSO)) { + rdrxctl = IXGBE_READ_REG(&sc->hw, IXGBE_RSCCTL(i)); + + /* Enable TSO Receive Side Coalescing */ + rdrxctl |= IXGBE_RSCCTL_RSCEN; + rdrxctl |= IXGBE_RSCCTL_MAXDESC_16; + + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(i), rdrxctl); + } + /* Setup the HW Rx Head and Tail Descriptor Pointers */ IXGBE_WRITE_REG(hw, IXGBE_RDH(i), 0); IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0); @@ -3175,7 +3200,7 @@ ixgbe_rxeof(struct rx_ring *rxr) sendmp = mp; sendmp->m_pkthdr.len = mp->m_len; #if NVLAN > 0 - if (staterr & IXGBE_RXD_STAT_VP) { + if (sc->vlan_stripping && staterr & IXGBE_RXD_STAT_VP) { sendmp->m_pkthdr.ether_vtag = vtag; sendmp->m_flags |= M_VLANTAG; } @@ -3248,8 +3273,20 @@ ixgbe_rx_checksum(uint32_t staterr, struct mbuf * mp, uint32_t ptype) void ixgbe_setup_vlan_hw_support(struct ix_softc *sc) { - uint32_t ctrl; - int i; + struct ifnet *ifp = &sc->arpcom.ac_if; + uint32_t ctrl; + int i; + + /* + * We have to disable VLAN striping when using TCP offloading, due to a + * firmware bug. + */ + if (ISSET(ifp->if_xflags, IFXF_TSO)) { + sc->vlan_stripping = 0; + return; + } + + sc->vlan_stripping = 1; /* * A soft reset zero's out the VFTA, so diff --git a/sys/dev/pci/if_ix.h b/sys/dev/pci/if_ix.h index fdae408fdea..41d756110c7 100644 --- a/sys/dev/pci/if_ix.h +++ b/sys/dev/pci/if_ix.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.h,v 1.44 2022/01/09 05:42:52 jsg Exp $ */ +/* $OpenBSD: if_ix.h,v 1.45 2022/06/27 15:11:23 jan Exp $ */ /****************************************************************************** @@ -225,6 +225,7 @@ struct ix_softc { struct ifmedia media; struct intrmap *sc_intrmap; int if_flags; + int vlan_stripping; uint16_t num_vlans; uint16_t num_queues; diff --git a/sys/net/if.c b/sys/net/if.c index 58af5730cde..c12943d6af9 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.653 2022/06/07 22:18:34 sashan Exp $ */ +/* $OpenBSD: if.c,v 1.654 2022/06/27 15:11:23 jan Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -2019,6 +2019,38 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) ifr->ifr_flags &= ~IFXF_WOL; error = ENOTSUP; } + + if (ISSET(ifp->if_capabilities, IFCAP_TSO) && + ISSET(ifr->ifr_flags, IFXF_TSO) != + ISSET(ifp->if_xflags, IFXF_TSO)) { + struct ifreq ifrq; + + s = splnet(); + + if (ISSET(ifr->ifr_flags, IFXF_TSO)) + ifp->if_xflags |= IFXF_TSO; + else + ifp->if_xflags &= ~IFXF_TSO; + + NET_ASSERT_LOCKED(); /* for ioctl */ + KERNEL_ASSERT_LOCKED(); /* for if_flags */ + + if (ISSET(ifp->if_flags, IFF_UP)) { + /* go down for a moment... */ + ifp->if_flags &= ~IFF_UP; + ifrq.ifr_flags = ifp->if_flags; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, + (caddr_t)&ifrq); + + /* ... and up again */ + ifp->if_flags |= IFF_UP; + ifrq.ifr_flags = ifp->if_flags; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, + (caddr_t)&ifrq); + } + + splx(s); + } #endif if (error == 0) diff --git a/sys/net/if.h b/sys/net/if.h index 42d0328480e..278679be2ef 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.208 2021/03/11 19:53:40 florian Exp $ */ +/* $OpenBSD: if.h,v 1.209 2022/06/27 15:11:23 jan Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -231,6 +231,7 @@ struct if_status_description { #define IFXF_INET6_NOSOII 0x40 /* [N] don't do RFC 7217 */ #define IFXF_AUTOCONF4 0x80 /* [N] v4 autoconf (aka dhcp) enabled */ #define IFXF_MONITOR 0x100 /* [N] only used for bpf */ +#define IFXF_TSO 0x200 /* [N] TCP segment offloading */ #define IFXF_CANTCHANGE \ (IFXF_MPSAFE|IFXF_CLONED) @@ -250,6 +251,7 @@ struct if_status_description { #define IFCAP_VLAN_HWTAGGING 0x00000020 /* hardware VLAN tag support */ #define IFCAP_CSUM_TCPv6 0x00000080 /* can do IPv6/TCP checksums */ #define IFCAP_CSUM_UDPv6 0x00000100 /* can do IPv6/UDP checksums */ +#define IFCAP_TSO 0x00004000 /* TCP segment offloading */ #define IFCAP_WOL 0x00008000 /* can do wake on lan */ #define IFCAP_CSUM_MASK (IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | \