From: Alexander Bluhm Subject: Re: ice(4) Tx checksum offloading To: tech@openbsd.org Date: Thu, 22 May 2025 22:23:04 +0900 On Tue, May 20, 2025 at 10:13:42PM +0200, Stefan Sperling wrote: > This patch adds support for Tx checksum offloading to the ice(4) driver. > > As with the earlier Rx patch, I have tested this diff both with and > without ice-ddp firmware loaded. It seems to work in both cases. > > The only case where software checksumming is still being used is when > I send iperf UDP packets over IPv6. Offloading UDP checkums works in > the IPv4 case, though, per counters shown by netstat -s. > Does this indicate a bug in this diff? Or is the IPv6 stack deciding to > clear M_UDP_CSUM_OUT in some cases for some reason? I could not yet see > anything wrong comparing my changes to ixl(4) and to FreeBSD ice(4). Works for me. I don't see software checksumming counters going up. Please commit, and I can have an eye on this in more test cases. OK bluhm@ > M sys/dev/pci/if_ice.c | 23+ 6- > > 1 file changed, 23 insertions(+), 6 deletions(-) > > commit - 2e4fc07e79d7ea65b71425f1af53c3c7c9d88bb3 > commit + 0f813f93bd053e12f651681399505c576b4cc14e > blob - ed64ea74bb85a0d5c2750114ed461c94028f295e > blob + 7cb43b5931c74d075d351458dff0c13b70c582ed > --- sys/dev/pci/if_ice.c > +++ sys/dev/pci/if_ice.c > @@ -84,6 +84,7 @@ > > #include > #include > +#include > > #define STRUCT_HACK_VAR_LEN > > @@ -13683,18 +13684,31 @@ ice_tx_setup_offload(struct mbuf *m0, struct ice_tx_qu > hlen = ext.iphlen; > > if (ext.ip4) { > - /* TODO: ipv4 checksum offload */ > - offload |= ICE_TX_DESC_CMD_IIPT_IPV4 << ICE_TXD_QW1_CMD_S; > + if (ISSET(m0->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT)) > + offload |= ICE_TX_DESC_CMD_IIPT_IPV4_CSUM << > + ICE_TXD_QW1_CMD_S; > + else > + offload |= ICE_TX_DESC_CMD_IIPT_IPV4 << > + ICE_TXD_QW1_CMD_S; > } else if (ext.ip6) > offload |= ICE_TX_DESC_CMD_IIPT_IPV6 << ICE_TXD_QW1_CMD_S; > + else > + return offload; > > offload |= ((ETHER_HDR_LEN >> 1) << ICE_TX_DESC_LEN_MACLEN_S) << > ICE_TXD_QW1_OFFSET_S; > - if (ext.ip4 || ext.ip6) > - offload |= ((hlen >> 2) << ICE_TX_DESC_LEN_IPLEN_S) << > - ICE_TXD_QW1_OFFSET_S; > + offload |= ((hlen >> 2) << ICE_TX_DESC_LEN_IPLEN_S) << > + ICE_TXD_QW1_OFFSET_S; > > - /* TODO: enable offloading features */ > + if (ext.tcp && ISSET(m0->m_pkthdr.csum_flags, M_TCP_CSUM_OUT)) { > + offload |= ICE_TX_DESC_CMD_L4T_EOFT_TCP << ICE_TXD_QW1_CMD_S; > + offload |= ((uint64_t)(ext.tcphlen >> 2) << > + ICE_TX_DESC_LEN_L4_LEN_S) << ICE_TXD_QW1_OFFSET_S; > + } else if (ext.udp && ISSET(m0->m_pkthdr.csum_flags, M_UDP_CSUM_OUT)) { > + offload |= ICE_TX_DESC_CMD_L4T_EOFT_UDP << ICE_TXD_QW1_CMD_S; > + offload |= ((uint64_t)(sizeof(*ext.udp) >> 2) << > + ICE_TX_DESC_LEN_L4_LEN_S) << ICE_TXD_QW1_OFFSET_S; > + } > > return offload; > } > @@ -29809,6 +29823,9 @@ ice_attach_hook(struct device *self) > #if NVLAN > 0 > ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; > #endif > + ifp->if_capabilities |= IFCAP_CSUM_IPv4 | > + IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4 | > + IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; > > if_attach(ifp); > ether_ifattach(ifp);