All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support
@ 2024-12-16 17:32 Paul Greenwalt
  2024-12-17  1:56 ` Jakub Kicinski
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Paul Greenwalt @ 2024-12-16 17:32 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: kuba, Paul Greenwalt, Alice Michael, Eric Joyner

E830 supports raw receive and generic transmit checksum offloads.

Raw receive checksum support is provided by hardware calculating the
checksum over the whole packet, regardless of type. The calculated
checksum is provided to driver in the Rx flex descriptor. Then the driver
assigns the checksum to skb->csum and sets skb->ip_summed to
CHECKSUM_COMPLETE.

Generic transmit checksum support is provided by hardware calculating the
checksum given two offsets: the start offset to begin checksum calculation,
and the offset to insert the calculated checksum in the packet. Support is
advertised to the stack using NETIF_F_HW_CSUM feature.

E830 has the following limitations when both generic transmit checksum
offload and TCP Segmentation Offload (TSO) are enabled:

1. Inner packet header modification is not supported. This restriction
   includes the inability to alter TCP flags, such as the push flag. As a
   result, this limitation can impact the receiver's ability to coalesce
   packets, potentially degrading network throughput.
2. The Maximum Segment Size (MSS) is limited to 1023 bytes, which prevents
   support of Maximum Transmission Unit (MTU) greater than 1063 bytes.

Therefore NETIF_F_HW_CSUM and NETIF_F_ALL_TSO features are mutually
exclusive. NETIF_F_HW_CSUM hardware feature support is indicated but is not
enabled by default. Instead, IP checksums and NETIF_F_ALL_TSO are the
defaults. Enforcement of mutual exclusivity of NETIF_F_HW_CSUM and
NETIF_F_ALL_TSO is done in ice_set_features(). Mutual exclusivity
of IP checksums and NETIF_F_HW_CSUM is handled by netdev_fix_features().

When NETIF_F_HW_CSUM is requested the provided skb->csum_start and
skb->csum_offset are passed to hardware in the Tx context descriptor
generic checksum (GCS) parameters. Hardware calculates the 1's complement
from skb->csum_start to the end of the packet, and inserts the result in
the packet at skb->csum_offset.

Co-developed-by: Alice Michael <alice.michael@intel.com>
Signed-off-by: Alice Michael <alice.michael@intel.com>
Co-developed-by: Eric Joyner <eric.joyner@intel.com>
Signed-off-by: Eric Joyner <eric.joyner@intel.com>
Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
---
Changelog:
v1->v2
- Update commit message with additional details.
- Add newlines, and add params around
- Return early from ice_fix_features() to avoid extra indentation and
  large if block.
- Move and change some defines.
- replace htons and le16_t_cpu with swap16.
- Use FIELD_PREP where possible.
- Removed checksum valid bit check STATUS1_L2TAG2P_S. This check is not
  needed since there is no situation which will return an error.
v2->v3
- Minor fixes in commit message.
- Removed unused register defines in ice_hw_autogen.h.
- Moved GCS and TSO feature fix to helper function
  ice_fix_features_gcs(), and updated logic.
- Update to align naming with related flags.
v3->v4
- Move a check for GCS and TSO mutual exclusivity from
  ice_fix_features() to ice_set_features().
v4->v5
- Remove lingering GCS and TSO mutual exclusivity comments and code in
  ice_fix_features().
- Remove unused variable ICE_TX_FLAGS_RING_GCS.
- Remove Tested-by and Signed-off-by tag due to changes to patch.
- Use ICE_TX_GCS_DESC_TYPE_M and ICE_TX_GCS_DESC_CSUM_PSH in
  ice_tx_csum() to set the GCS decriptor field type.
---
 drivers/net/ethernet/intel/ice/ice.h          |  1 +
 .../net/ethernet/intel/ice/ice_lan_tx_rx.h    |  9 +++++--
 drivers/net/ethernet/intel/ice/ice_lib.c      |  8 +++++-
 drivers/net/ethernet/intel/ice/ice_main.c     | 12 +++++++++
 drivers/net/ethernet/intel/ice/ice_txrx.c     | 27 ++++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_txrx.h     |  2 ++
 drivers/net/ethernet/intel/ice/ice_txrx_lib.c | 26 ++++++++++++++++++
 7 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 2f5d6f974185..0d2c80578633 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -203,6 +203,7 @@ enum ice_feature {
 	ICE_F_SMA_CTRL,
 	ICE_F_CGU,
 	ICE_F_GNSS,
+	ICE_F_GCS,
 	ICE_F_ROCE_LAG,
 	ICE_F_SRIOV_LAG,
 	ICE_F_MBX_LIMIT,
diff --git a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
index 611577ebc29d..5b98222fe27f 100644
--- a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
+++ b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
@@ -229,7 +229,7 @@ struct ice_32b_rx_flex_desc_nic {
 	__le16 status_error1;
 	u8 flexi_flags2;
 	u8 ts_low;
-	__le16 l2tag2_1st;
+	__le16 raw_csum;
 	__le16 l2tag2_2nd;
 
 	/* Qword 3 */
@@ -500,10 +500,15 @@ enum ice_tx_desc_len_fields {
 struct ice_tx_ctx_desc {
 	__le32 tunneling_params;
 	__le16 l2tag2;
-	__le16 rsvd;
+	__le16 gcs;
 	__le64 qw1;
 };
 
+#define ICE_TX_GCS_DESC_START_M		GENMASK(7, 0)
+#define ICE_TX_GCS_DESC_OFFSET_M	GENMASK(11, 8)
+#define ICE_TX_GCS_DESC_TYPE_M		GENMASK(14, 12)
+#define ICE_TX_GCS_DESC_CSUM_PSH	1
+
 #define ICE_TXD_CTX_QW1_CMD_S	4
 #define ICE_TXD_CTX_QW1_CMD_M	(0x7FUL << ICE_TXD_CTX_QW1_CMD_S)
 
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index e07fc8851e1d..23d4b0677b21 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1420,6 +1420,10 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
 		ring->dev = dev;
 		ring->count = vsi->num_rx_desc;
 		ring->cached_phctime = pf->ptp.cached_phc_time;
+
+		if (ice_is_feature_supported(pf, ICE_F_GCS))
+			ring->flags |= ICE_RX_FLAGS_RING_GCS;
+
 		WRITE_ONCE(vsi->rx_rings[i], ring);
 	}
 
@@ -3883,8 +3887,10 @@ void ice_init_feature_support(struct ice_pf *pf)
 		break;
 	}
 
-	if (pf->hw.mac_type == ICE_MAC_E830)
+	if (pf->hw.mac_type == ICE_MAC_E830) {
 		ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
+		ice_set_feature_support(pf, ICE_F_GCS);
+	}
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 89fa3d53d317..aa63c421595b 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -6567,6 +6567,18 @@ ice_set_features(struct net_device *netdev, netdev_features_t features)
 	if (changed & NETIF_F_LOOPBACK)
 		ret = ice_set_loopback(vsi, !!(features & NETIF_F_LOOPBACK));
 
+	/* Due to E830 hardware limitations, TSO (NETIF_F_ALL_TSO) with GCS
+	 * (NETIF_F_HW_CSUM) is not supported.
+	 */
+	if (ice_is_feature_supported(pf, ICE_F_GCS) &&
+	    ((features & NETIF_F_HW_CSUM) && (features & NETIF_F_ALL_TSO))) {
+		if (netdev->features & NETIF_F_HW_CSUM)
+			dev_err(ice_pf_to_dev(pf), "To enable TSO, you must first disable HW checksum.\n");
+		else
+			dev_err(ice_pf_to_dev(pf), "To enable HW checksum, you must first disable TSO.\n");
+		return -EIO;
+	}
+
 	return ret;
 }
 
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
index 5d2d7736fd5f..85ae16f5ecc0 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -1753,6 +1753,7 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first,
 static
 int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
 {
+	const struct ice_tx_ring *tx_ring = off->tx_ring;
 	u32 l4_len = 0, l3_len = 0, l2_len = 0;
 	struct sk_buff *skb = first->skb;
 	union {
@@ -1902,6 +1903,30 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
 	l3_len = l4.hdr - ip.hdr;
 	offset |= (l3_len / 4) << ICE_TX_DESC_LEN_IPLEN_S;
 
+	if ((tx_ring->netdev->features & NETIF_F_HW_CSUM) &&
+	    !(first->tx_flags & ICE_TX_FLAGS_TSO) &&
+	    !skb_csum_is_sctp(skb)) {
+		/* Set GCS */
+		u16 csum_start = (skb->csum_start - skb->mac_header) / 2;
+		u16 csum_offset = skb->csum_offset / 2;
+		u16 gcs_params;
+
+		gcs_params = FIELD_PREP(ICE_TX_GCS_DESC_START_M, csum_start) |
+			     FIELD_PREP(ICE_TX_GCS_DESC_OFFSET_M, csum_offset) |
+			     FIELD_PREP(ICE_TX_GCS_DESC_TYPE_M |
+					ICE_TX_GCS_DESC_CSUM_PSH);
+
+		/* Unlike legacy HW checksums, GCS requires a context
+		 * descriptor.
+		 */
+		off->cd_qw1 |= ICE_TX_DESC_DTYPE_CTX;
+		off->cd_gcs_params = gcs_params;
+		/* Fill out CSO info in data descriptors */
+		off->td_offset |= offset;
+		off->td_cmd |= cmd;
+		return 1;
+	}
+
 	/* Enable L4 checksum offloads */
 	switch (l4_proto) {
 	case IPPROTO_TCP:
@@ -2383,7 +2408,7 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
 		/* setup context descriptor */
 		cdesc->tunneling_params = cpu_to_le32(offload.cd_tunnel_params);
 		cdesc->l2tag2 = cpu_to_le16(offload.cd_l2tag2);
-		cdesc->rsvd = cpu_to_le16(0);
+		cdesc->gcs = cpu_to_le16(offload.cd_gcs_params);
 		cdesc->qw1 = cpu_to_le64(offload.cd_qw1);
 	}
 
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
index cb347c852ba9..5b0b54ac5c00 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
@@ -193,6 +193,7 @@ struct ice_tx_offload_params {
 	u32 td_l2tag1;
 	u32 cd_tunnel_params;
 	u16 cd_l2tag2;
+	u16 cd_gcs_params;
 	u8 header_len;
 };
 
@@ -367,6 +368,7 @@ struct ice_rx_ring {
 #define ICE_RX_FLAGS_RING_BUILD_SKB	BIT(1)
 #define ICE_RX_FLAGS_CRC_STRIP_DIS	BIT(2)
 #define ICE_RX_FLAGS_MULTIDEV		BIT(3)
+#define ICE_RX_FLAGS_RING_GCS		BIT(4)
 	u8 flags;
 	/* CL5 - 5th cacheline starts here */
 	struct xdp_rxq_info xdp_rxq;
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
index 2719f0e20933..45cfaabc41cb 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
@@ -80,6 +80,23 @@ ice_rx_hash_to_skb(const struct ice_rx_ring *rx_ring,
 		libeth_rx_pt_set_hash(skb, hash, decoded);
 }
 
+/**
+ * ice_rx_gcs - Set generic checksum in skb
+ * @skb: skb currently being received and modified
+ * @rx_desc: receive descriptor
+ */
+static void ice_rx_gcs(struct sk_buff *skb,
+		       const union ice_32b_rx_flex_desc *rx_desc)
+{
+	const struct ice_32b_rx_flex_desc_nic *desc;
+	u16 csum;
+
+	desc = (struct ice_32b_rx_flex_desc_nic *)rx_desc;
+	skb->ip_summed = CHECKSUM_COMPLETE;
+	csum = (__force u16)desc->raw_csum;
+	skb->csum = csum_unfold((__force __sum16)swab16(csum));
+}
+
 /**
  * ice_rx_csum - Indicate in skb if checksum is good
  * @ring: the ring we care about
@@ -107,6 +124,15 @@ ice_rx_csum(struct ice_rx_ring *ring, struct sk_buff *skb,
 	rx_status0 = le16_to_cpu(rx_desc->wb.status_error0);
 	rx_status1 = le16_to_cpu(rx_desc->wb.status_error1);
 
+	if ((ring->flags & ICE_RX_FLAGS_RING_GCS) &&
+	    rx_desc->wb.rxdid == ICE_RXDID_FLEX_NIC &&
+	    (decoded.inner_prot == LIBETH_RX_PT_INNER_TCP ||
+	     decoded.inner_prot == LIBETH_RX_PT_INNER_UDP ||
+	     decoded.inner_prot == LIBETH_RX_PT_INNER_ICMP)) {
+		ice_rx_gcs(skb, rx_desc);
+		return;
+	}
+
 	/* check if HW has decoded the packet and checksum */
 	if (!(rx_status0 & BIT(ICE_RX_FLEX_DESC_STATUS0_L3L4P_S)))
 		return;
-- 
2.45.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support
  2024-12-16 17:32 [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support Paul Greenwalt
@ 2024-12-17  1:56 ` Jakub Kicinski
  2024-12-17  8:04 ` kernel test robot
  2024-12-17  8:15 ` kernel test robot
  2 siblings, 0 replies; 4+ messages in thread
From: Jakub Kicinski @ 2024-12-17  1:56 UTC (permalink / raw)
  To: Paul Greenwalt; +Cc: intel-wired-lan, Alice Michael, Eric Joyner

On Mon, 16 Dec 2024 12:32:12 -0500 Paul Greenwalt wrote:
> Cc: kuba@kernel.org

Please don't CC me on iwl-next patches unless you also cc netdev@.
Makes the patches got into the wrong inbox..

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support
  2024-12-16 17:32 [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support Paul Greenwalt
  2024-12-17  1:56 ` Jakub Kicinski
@ 2024-12-17  8:04 ` kernel test robot
  2024-12-17  8:15 ` kernel test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2024-12-17  8:04 UTC (permalink / raw)
  To: Paul Greenwalt; +Cc: oe-kbuild-all

Hi Paul,

kernel test robot noticed the following build errors:

[auto build test ERROR on tnguy-next-queue/dev-queue]

url:    https://github.com/intel-lab-lkp/linux/commits/Paul-Greenwalt/ice-Add-E830-checksum-offload-support/20241217-092509
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue
patch link:    https://lore.kernel.org/r/20241216173212.1157855-1-paul.greenwalt%40intel.com
patch subject: [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support
config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20241217/202412171534.OeVkFxup-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241217/202412171534.OeVkFxup-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202412171534.OeVkFxup-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/net/ethernet/intel/ice/ice_txrx.c: In function 'ice_tx_csum':
>> drivers/net/ethernet/intel/ice/ice_txrx.c:1917:65: error: macro "FIELD_PREP" requires 2 arguments, but only 1 given
    1917 |                                         ICE_TX_GCS_DESC_CSUM_PSH);
         |                                                                 ^
   In file included from include/linux/fortify-string.h:5,
                    from include/linux/string.h:389,
                    from include/linux/bitmap.h:13,
                    from include/linux/cpumask.h:12,
                    from include/linux/smp.h:13,
                    from include/linux/lockdep.h:14,
                    from include/linux/spinlock.h:63,
                    from include/linux/mmzone.h:8,
                    from include/linux/gfp.h:7,
                    from include/linux/mm.h:7,
                    from drivers/net/ethernet/intel/ice/ice_txrx.c:6:
   include/linux/bitfield.h:113:9: note: macro "FIELD_PREP" defined here
     113 | #define FIELD_PREP(_mask, _val)                                         \
         |         ^~~~~~~~~~
>> drivers/net/ethernet/intel/ice/ice_txrx.c:1916:30: error: 'FIELD_PREP' undeclared (first use in this function)
    1916 |                              FIELD_PREP(ICE_TX_GCS_DESC_TYPE_M |
         |                              ^~~~~~~~~~
   drivers/net/ethernet/intel/ice/ice_txrx.c:1916:30: note: each undeclared identifier is reported only once for each function it appears in


vim +/FIELD_PREP +1917 drivers/net/ethernet/intel/ice/ice_txrx.c

  1745	
  1746	/**
  1747	 * ice_tx_csum - Enable Tx checksum offloads
  1748	 * @first: pointer to the first descriptor
  1749	 * @off: pointer to struct that holds offload parameters
  1750	 *
  1751	 * Returns 0 or error (negative) if checksum offload can't happen, 1 otherwise.
  1752	 */
  1753	static
  1754	int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
  1755	{
  1756		const struct ice_tx_ring *tx_ring = off->tx_ring;
  1757		u32 l4_len = 0, l3_len = 0, l2_len = 0;
  1758		struct sk_buff *skb = first->skb;
  1759		union {
  1760			struct iphdr *v4;
  1761			struct ipv6hdr *v6;
  1762			unsigned char *hdr;
  1763		} ip;
  1764		union {
  1765			struct tcphdr *tcp;
  1766			unsigned char *hdr;
  1767		} l4;
  1768		__be16 frag_off, protocol;
  1769		unsigned char *exthdr;
  1770		u32 offset, cmd = 0;
  1771		u8 l4_proto = 0;
  1772	
  1773		if (skb->ip_summed != CHECKSUM_PARTIAL)
  1774			return 0;
  1775	
  1776		protocol = vlan_get_protocol(skb);
  1777	
  1778		if (eth_p_mpls(protocol)) {
  1779			ip.hdr = skb_inner_network_header(skb);
  1780			l4.hdr = skb_checksum_start(skb);
  1781		} else {
  1782			ip.hdr = skb_network_header(skb);
  1783			l4.hdr = skb_transport_header(skb);
  1784		}
  1785	
  1786		/* compute outer L2 header size */
  1787		l2_len = ip.hdr - skb->data;
  1788		offset = (l2_len / 2) << ICE_TX_DESC_LEN_MACLEN_S;
  1789	
  1790		/* set the tx_flags to indicate the IP protocol type. this is
  1791		 * required so that checksum header computation below is accurate.
  1792		 */
  1793		if (ip.v4->version == 4)
  1794			first->tx_flags |= ICE_TX_FLAGS_IPV4;
  1795		else if (ip.v6->version == 6)
  1796			first->tx_flags |= ICE_TX_FLAGS_IPV6;
  1797	
  1798		if (skb->encapsulation) {
  1799			bool gso_ena = false;
  1800			u32 tunnel = 0;
  1801	
  1802			/* define outer network header type */
  1803			if (first->tx_flags & ICE_TX_FLAGS_IPV4) {
  1804				tunnel |= (first->tx_flags & ICE_TX_FLAGS_TSO) ?
  1805					  ICE_TX_CTX_EIPT_IPV4 :
  1806					  ICE_TX_CTX_EIPT_IPV4_NO_CSUM;
  1807				l4_proto = ip.v4->protocol;
  1808			} else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
  1809				int ret;
  1810	
  1811				tunnel |= ICE_TX_CTX_EIPT_IPV6;
  1812				exthdr = ip.hdr + sizeof(*ip.v6);
  1813				l4_proto = ip.v6->nexthdr;
  1814				ret = ipv6_skip_exthdr(skb, exthdr - skb->data,
  1815						       &l4_proto, &frag_off);
  1816				if (ret < 0)
  1817					return -1;
  1818			}
  1819	
  1820			/* define outer transport */
  1821			switch (l4_proto) {
  1822			case IPPROTO_UDP:
  1823				tunnel |= ICE_TXD_CTX_UDP_TUNNELING;
  1824				first->tx_flags |= ICE_TX_FLAGS_TUNNEL;
  1825				break;
  1826			case IPPROTO_GRE:
  1827				tunnel |= ICE_TXD_CTX_GRE_TUNNELING;
  1828				first->tx_flags |= ICE_TX_FLAGS_TUNNEL;
  1829				break;
  1830			case IPPROTO_IPIP:
  1831			case IPPROTO_IPV6:
  1832				first->tx_flags |= ICE_TX_FLAGS_TUNNEL;
  1833				l4.hdr = skb_inner_network_header(skb);
  1834				break;
  1835			default:
  1836				if (first->tx_flags & ICE_TX_FLAGS_TSO)
  1837					return -1;
  1838	
  1839				skb_checksum_help(skb);
  1840				return 0;
  1841			}
  1842	
  1843			/* compute outer L3 header size */
  1844			tunnel |= ((l4.hdr - ip.hdr) / 4) <<
  1845				  ICE_TXD_CTX_QW0_EIPLEN_S;
  1846	
  1847			/* switch IP header pointer from outer to inner header */
  1848			ip.hdr = skb_inner_network_header(skb);
  1849	
  1850			/* compute tunnel header size */
  1851			tunnel |= ((ip.hdr - l4.hdr) / 2) <<
  1852				   ICE_TXD_CTX_QW0_NATLEN_S;
  1853	
  1854			gso_ena = skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL;
  1855			/* indicate if we need to offload outer UDP header */
  1856			if ((first->tx_flags & ICE_TX_FLAGS_TSO) && !gso_ena &&
  1857			    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
  1858				tunnel |= ICE_TXD_CTX_QW0_L4T_CS_M;
  1859	
  1860			/* record tunnel offload values */
  1861			off->cd_tunnel_params |= tunnel;
  1862	
  1863			/* set DTYP=1 to indicate that it's an Tx context descriptor
  1864			 * in IPsec tunnel mode with Tx offloads in Quad word 1
  1865			 */
  1866			off->cd_qw1 |= (u64)ICE_TX_DESC_DTYPE_CTX;
  1867	
  1868			/* switch L4 header pointer from outer to inner */
  1869			l4.hdr = skb_inner_transport_header(skb);
  1870			l4_proto = 0;
  1871	
  1872			/* reset type as we transition from outer to inner headers */
  1873			first->tx_flags &= ~(ICE_TX_FLAGS_IPV4 | ICE_TX_FLAGS_IPV6);
  1874			if (ip.v4->version == 4)
  1875				first->tx_flags |= ICE_TX_FLAGS_IPV4;
  1876			if (ip.v6->version == 6)
  1877				first->tx_flags |= ICE_TX_FLAGS_IPV6;
  1878		}
  1879	
  1880		/* Enable IP checksum offloads */
  1881		if (first->tx_flags & ICE_TX_FLAGS_IPV4) {
  1882			l4_proto = ip.v4->protocol;
  1883			/* the stack computes the IP header already, the only time we
  1884			 * need the hardware to recompute it is in the case of TSO.
  1885			 */
  1886			if (first->tx_flags & ICE_TX_FLAGS_TSO)
  1887				cmd |= ICE_TX_DESC_CMD_IIPT_IPV4_CSUM;
  1888			else
  1889				cmd |= ICE_TX_DESC_CMD_IIPT_IPV4;
  1890	
  1891		} else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
  1892			cmd |= ICE_TX_DESC_CMD_IIPT_IPV6;
  1893			exthdr = ip.hdr + sizeof(*ip.v6);
  1894			l4_proto = ip.v6->nexthdr;
  1895			if (l4.hdr != exthdr)
  1896				ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_proto,
  1897						 &frag_off);
  1898		} else {
  1899			return -1;
  1900		}
  1901	
  1902		/* compute inner L3 header size */
  1903		l3_len = l4.hdr - ip.hdr;
  1904		offset |= (l3_len / 4) << ICE_TX_DESC_LEN_IPLEN_S;
  1905	
  1906		if ((tx_ring->netdev->features & NETIF_F_HW_CSUM) &&
  1907		    !(first->tx_flags & ICE_TX_FLAGS_TSO) &&
  1908		    !skb_csum_is_sctp(skb)) {
  1909			/* Set GCS */
  1910			u16 csum_start = (skb->csum_start - skb->mac_header) / 2;
  1911			u16 csum_offset = skb->csum_offset / 2;
  1912			u16 gcs_params;
  1913	
  1914			gcs_params = FIELD_PREP(ICE_TX_GCS_DESC_START_M, csum_start) |
  1915				     FIELD_PREP(ICE_TX_GCS_DESC_OFFSET_M, csum_offset) |
> 1916				     FIELD_PREP(ICE_TX_GCS_DESC_TYPE_M |
> 1917						ICE_TX_GCS_DESC_CSUM_PSH);
  1918	
  1919			/* Unlike legacy HW checksums, GCS requires a context
  1920			 * descriptor.
  1921			 */
  1922			off->cd_qw1 |= ICE_TX_DESC_DTYPE_CTX;
  1923			off->cd_gcs_params = gcs_params;
  1924			/* Fill out CSO info in data descriptors */
  1925			off->td_offset |= offset;
  1926			off->td_cmd |= cmd;
  1927			return 1;
  1928		}
  1929	
  1930		/* Enable L4 checksum offloads */
  1931		switch (l4_proto) {
  1932		case IPPROTO_TCP:
  1933			/* enable checksum offloads */
  1934			cmd |= ICE_TX_DESC_CMD_L4T_EOFT_TCP;
  1935			l4_len = l4.tcp->doff;
  1936			offset |= l4_len << ICE_TX_DESC_LEN_L4_LEN_S;
  1937			break;
  1938		case IPPROTO_UDP:
  1939			/* enable UDP checksum offload */
  1940			cmd |= ICE_TX_DESC_CMD_L4T_EOFT_UDP;
  1941			l4_len = (sizeof(struct udphdr) >> 2);
  1942			offset |= l4_len << ICE_TX_DESC_LEN_L4_LEN_S;
  1943			break;
  1944		case IPPROTO_SCTP:
  1945			/* enable SCTP checksum offload */
  1946			cmd |= ICE_TX_DESC_CMD_L4T_EOFT_SCTP;
  1947			l4_len = sizeof(struct sctphdr) >> 2;
  1948			offset |= l4_len << ICE_TX_DESC_LEN_L4_LEN_S;
  1949			break;
  1950	
  1951		default:
  1952			if (first->tx_flags & ICE_TX_FLAGS_TSO)
  1953				return -1;
  1954			skb_checksum_help(skb);
  1955			return 0;
  1956		}
  1957	
  1958		off->td_cmd |= cmd;
  1959		off->td_offset |= offset;
  1960		return 1;
  1961	}
  1962	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support
  2024-12-16 17:32 [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support Paul Greenwalt
  2024-12-17  1:56 ` Jakub Kicinski
  2024-12-17  8:04 ` kernel test robot
@ 2024-12-17  8:15 ` kernel test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2024-12-17  8:15 UTC (permalink / raw)
  To: Paul Greenwalt; +Cc: llvm, oe-kbuild-all

Hi Paul,

kernel test robot noticed the following build errors:

[auto build test ERROR on tnguy-next-queue/dev-queue]

url:    https://github.com/intel-lab-lkp/linux/commits/Paul-Greenwalt/ice-Add-E830-checksum-offload-support/20241217-092509
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue
patch link:    https://lore.kernel.org/r/20241216173212.1157855-1-paul.greenwalt%40intel.com
patch subject: [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20241217/202412171627.IkiDlzsr-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241217/202412171627.IkiDlzsr-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202412171627.IkiDlzsr-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/net/ethernet/intel/ice/ice_txrx.c:6:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/ethernet/intel/ice/ice_txrx.c:1917:30: error: too few arguments provided to function-like macro invocation
    1917 |                                         ICE_TX_GCS_DESC_CSUM_PSH);
         |                                                                 ^
   include/linux/bitfield.h:113:9: note: macro 'FIELD_PREP' defined here
     113 | #define FIELD_PREP(_mask, _val)                                         \
         |         ^
>> drivers/net/ethernet/intel/ice/ice_txrx.c:1916:9: error: use of undeclared identifier 'FIELD_PREP'
    1916 |                              FIELD_PREP(ICE_TX_GCS_DESC_TYPE_M |
         |                              ^
   4 warnings and 2 errors generated.


vim +1917 drivers/net/ethernet/intel/ice/ice_txrx.c

  1745	
  1746	/**
  1747	 * ice_tx_csum - Enable Tx checksum offloads
  1748	 * @first: pointer to the first descriptor
  1749	 * @off: pointer to struct that holds offload parameters
  1750	 *
  1751	 * Returns 0 or error (negative) if checksum offload can't happen, 1 otherwise.
  1752	 */
  1753	static
  1754	int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
  1755	{
  1756		const struct ice_tx_ring *tx_ring = off->tx_ring;
  1757		u32 l4_len = 0, l3_len = 0, l2_len = 0;
  1758		struct sk_buff *skb = first->skb;
  1759		union {
  1760			struct iphdr *v4;
  1761			struct ipv6hdr *v6;
  1762			unsigned char *hdr;
  1763		} ip;
  1764		union {
  1765			struct tcphdr *tcp;
  1766			unsigned char *hdr;
  1767		} l4;
  1768		__be16 frag_off, protocol;
  1769		unsigned char *exthdr;
  1770		u32 offset, cmd = 0;
  1771		u8 l4_proto = 0;
  1772	
  1773		if (skb->ip_summed != CHECKSUM_PARTIAL)
  1774			return 0;
  1775	
  1776		protocol = vlan_get_protocol(skb);
  1777	
  1778		if (eth_p_mpls(protocol)) {
  1779			ip.hdr = skb_inner_network_header(skb);
  1780			l4.hdr = skb_checksum_start(skb);
  1781		} else {
  1782			ip.hdr = skb_network_header(skb);
  1783			l4.hdr = skb_transport_header(skb);
  1784		}
  1785	
  1786		/* compute outer L2 header size */
  1787		l2_len = ip.hdr - skb->data;
  1788		offset = (l2_len / 2) << ICE_TX_DESC_LEN_MACLEN_S;
  1789	
  1790		/* set the tx_flags to indicate the IP protocol type. this is
  1791		 * required so that checksum header computation below is accurate.
  1792		 */
  1793		if (ip.v4->version == 4)
  1794			first->tx_flags |= ICE_TX_FLAGS_IPV4;
  1795		else if (ip.v6->version == 6)
  1796			first->tx_flags |= ICE_TX_FLAGS_IPV6;
  1797	
  1798		if (skb->encapsulation) {
  1799			bool gso_ena = false;
  1800			u32 tunnel = 0;
  1801	
  1802			/* define outer network header type */
  1803			if (first->tx_flags & ICE_TX_FLAGS_IPV4) {
  1804				tunnel |= (first->tx_flags & ICE_TX_FLAGS_TSO) ?
  1805					  ICE_TX_CTX_EIPT_IPV4 :
  1806					  ICE_TX_CTX_EIPT_IPV4_NO_CSUM;
  1807				l4_proto = ip.v4->protocol;
  1808			} else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
  1809				int ret;
  1810	
  1811				tunnel |= ICE_TX_CTX_EIPT_IPV6;
  1812				exthdr = ip.hdr + sizeof(*ip.v6);
  1813				l4_proto = ip.v6->nexthdr;
  1814				ret = ipv6_skip_exthdr(skb, exthdr - skb->data,
  1815						       &l4_proto, &frag_off);
  1816				if (ret < 0)
  1817					return -1;
  1818			}
  1819	
  1820			/* define outer transport */
  1821			switch (l4_proto) {
  1822			case IPPROTO_UDP:
  1823				tunnel |= ICE_TXD_CTX_UDP_TUNNELING;
  1824				first->tx_flags |= ICE_TX_FLAGS_TUNNEL;
  1825				break;
  1826			case IPPROTO_GRE:
  1827				tunnel |= ICE_TXD_CTX_GRE_TUNNELING;
  1828				first->tx_flags |= ICE_TX_FLAGS_TUNNEL;
  1829				break;
  1830			case IPPROTO_IPIP:
  1831			case IPPROTO_IPV6:
  1832				first->tx_flags |= ICE_TX_FLAGS_TUNNEL;
  1833				l4.hdr = skb_inner_network_header(skb);
  1834				break;
  1835			default:
  1836				if (first->tx_flags & ICE_TX_FLAGS_TSO)
  1837					return -1;
  1838	
  1839				skb_checksum_help(skb);
  1840				return 0;
  1841			}
  1842	
  1843			/* compute outer L3 header size */
  1844			tunnel |= ((l4.hdr - ip.hdr) / 4) <<
  1845				  ICE_TXD_CTX_QW0_EIPLEN_S;
  1846	
  1847			/* switch IP header pointer from outer to inner header */
  1848			ip.hdr = skb_inner_network_header(skb);
  1849	
  1850			/* compute tunnel header size */
  1851			tunnel |= ((ip.hdr - l4.hdr) / 2) <<
  1852				   ICE_TXD_CTX_QW0_NATLEN_S;
  1853	
  1854			gso_ena = skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL;
  1855			/* indicate if we need to offload outer UDP header */
  1856			if ((first->tx_flags & ICE_TX_FLAGS_TSO) && !gso_ena &&
  1857			    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
  1858				tunnel |= ICE_TXD_CTX_QW0_L4T_CS_M;
  1859	
  1860			/* record tunnel offload values */
  1861			off->cd_tunnel_params |= tunnel;
  1862	
  1863			/* set DTYP=1 to indicate that it's an Tx context descriptor
  1864			 * in IPsec tunnel mode with Tx offloads in Quad word 1
  1865			 */
  1866			off->cd_qw1 |= (u64)ICE_TX_DESC_DTYPE_CTX;
  1867	
  1868			/* switch L4 header pointer from outer to inner */
  1869			l4.hdr = skb_inner_transport_header(skb);
  1870			l4_proto = 0;
  1871	
  1872			/* reset type as we transition from outer to inner headers */
  1873			first->tx_flags &= ~(ICE_TX_FLAGS_IPV4 | ICE_TX_FLAGS_IPV6);
  1874			if (ip.v4->version == 4)
  1875				first->tx_flags |= ICE_TX_FLAGS_IPV4;
  1876			if (ip.v6->version == 6)
  1877				first->tx_flags |= ICE_TX_FLAGS_IPV6;
  1878		}
  1879	
  1880		/* Enable IP checksum offloads */
  1881		if (first->tx_flags & ICE_TX_FLAGS_IPV4) {
  1882			l4_proto = ip.v4->protocol;
  1883			/* the stack computes the IP header already, the only time we
  1884			 * need the hardware to recompute it is in the case of TSO.
  1885			 */
  1886			if (first->tx_flags & ICE_TX_FLAGS_TSO)
  1887				cmd |= ICE_TX_DESC_CMD_IIPT_IPV4_CSUM;
  1888			else
  1889				cmd |= ICE_TX_DESC_CMD_IIPT_IPV4;
  1890	
  1891		} else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
  1892			cmd |= ICE_TX_DESC_CMD_IIPT_IPV6;
  1893			exthdr = ip.hdr + sizeof(*ip.v6);
  1894			l4_proto = ip.v6->nexthdr;
  1895			if (l4.hdr != exthdr)
  1896				ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_proto,
  1897						 &frag_off);
  1898		} else {
  1899			return -1;
  1900		}
  1901	
  1902		/* compute inner L3 header size */
  1903		l3_len = l4.hdr - ip.hdr;
  1904		offset |= (l3_len / 4) << ICE_TX_DESC_LEN_IPLEN_S;
  1905	
  1906		if ((tx_ring->netdev->features & NETIF_F_HW_CSUM) &&
  1907		    !(first->tx_flags & ICE_TX_FLAGS_TSO) &&
  1908		    !skb_csum_is_sctp(skb)) {
  1909			/* Set GCS */
  1910			u16 csum_start = (skb->csum_start - skb->mac_header) / 2;
  1911			u16 csum_offset = skb->csum_offset / 2;
  1912			u16 gcs_params;
  1913	
  1914			gcs_params = FIELD_PREP(ICE_TX_GCS_DESC_START_M, csum_start) |
  1915				     FIELD_PREP(ICE_TX_GCS_DESC_OFFSET_M, csum_offset) |
> 1916				     FIELD_PREP(ICE_TX_GCS_DESC_TYPE_M |
> 1917						ICE_TX_GCS_DESC_CSUM_PSH);
  1918	
  1919			/* Unlike legacy HW checksums, GCS requires a context
  1920			 * descriptor.
  1921			 */
  1922			off->cd_qw1 |= ICE_TX_DESC_DTYPE_CTX;
  1923			off->cd_gcs_params = gcs_params;
  1924			/* Fill out CSO info in data descriptors */
  1925			off->td_offset |= offset;
  1926			off->td_cmd |= cmd;
  1927			return 1;
  1928		}
  1929	
  1930		/* Enable L4 checksum offloads */
  1931		switch (l4_proto) {
  1932		case IPPROTO_TCP:
  1933			/* enable checksum offloads */
  1934			cmd |= ICE_TX_DESC_CMD_L4T_EOFT_TCP;
  1935			l4_len = l4.tcp->doff;
  1936			offset |= l4_len << ICE_TX_DESC_LEN_L4_LEN_S;
  1937			break;
  1938		case IPPROTO_UDP:
  1939			/* enable UDP checksum offload */
  1940			cmd |= ICE_TX_DESC_CMD_L4T_EOFT_UDP;
  1941			l4_len = (sizeof(struct udphdr) >> 2);
  1942			offset |= l4_len << ICE_TX_DESC_LEN_L4_LEN_S;
  1943			break;
  1944		case IPPROTO_SCTP:
  1945			/* enable SCTP checksum offload */
  1946			cmd |= ICE_TX_DESC_CMD_L4T_EOFT_SCTP;
  1947			l4_len = sizeof(struct sctphdr) >> 2;
  1948			offset |= l4_len << ICE_TX_DESC_LEN_L4_LEN_S;
  1949			break;
  1950	
  1951		default:
  1952			if (first->tx_flags & ICE_TX_FLAGS_TSO)
  1953				return -1;
  1954			skb_checksum_help(skb);
  1955			return 0;
  1956		}
  1957	
  1958		off->td_cmd |= cmd;
  1959		off->td_offset |= offset;
  1960		return 1;
  1961	}
  1962	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-12-17  8:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-16 17:32 [Intel-wired-lan] [PATCH iwl-next v5] ice: Add E830 checksum offload support Paul Greenwalt
2024-12-17  1:56 ` Jakub Kicinski
2024-12-17  8:04 ` kernel test robot
2024-12-17  8:15 ` kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.