From nobody Mon Apr 27 12:32:54 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B45FF209F53 for ; Wed, 16 Apr 2025 16:14:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820090; cv=none; b=DTdJ23Uwvfoe64dqO1lrZ3n3or4zsUZWuw8rtYACiqyC0beMI1bVggfe/AHJb/EvLvvi3+jOJCXWWmqliggVDfZaQx7ISBqGd9lIzDi+h8ffBnXrh/AGmp3tl+gq3IT/ru4kdAXlCXporPtylRvmUkSt3pArZmIL61f+vsqa7Kc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820090; c=relaxed/simple; bh=5/b0fdmjcYFYBChxB9yhX8Hr5ATMJeAQw5pX8rQ4bXg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=u2qZWGcRxuYUGYy4RSSPKLn78Zm9mBqMLzjKMWJ1qfCTNUyliDjbabP+9bMRKgzhhb1YHuzl7KwG6CV4x9txF9jYMG0hrav4EbAKtREsTj769BzCXcOlU7iZfP27YQoUadFD1JXqmzxfZDnCdfevbXAvu4NJtUlylEOAazsQm28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1u55PN-0002G0-D7; Wed, 16 Apr 2025 18:14:41 +0200 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac]) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1u55PN-000c9F-0L; Wed, 16 Apr 2025 18:14:41 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1u55PN-00CGQI-06; Wed, 16 Apr 2025 18:14:41 +0200 From: Oleksij Rempel To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Maxime Chevallier Subject: [PATCH net-next v1 1/4] net: selftests: drop test index from net_selftest_get_strings() Date: Wed, 16 Apr 2025 18:14:36 +0200 Message-Id: <20250416161439.2922994-2-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250416161439.2922994-1-o.rempel@pengutronix.de> References: <20250416161439.2922994-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The test index is redundant and reduces available space for test names, which are already limited to ETH_GSTRING_LEN (32 bytes). Removing the index improves readability in tools like `ethtool -t`, especially when longer test names are used. Before this change: 3. PHY internal loopback, enab 7. PHY internal loopback, disa After this change: PHY internal loopback, enable PHY internal loopback, disable Signed-off-by: Oleksij Rempel Reviewed-by: Simon Horman --- net/core/selftests.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/core/selftests.c b/net/core/selftests.c index 35f807ea9952..3c3e2b2a22c9 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -408,8 +408,7 @@ void net_selftest_get_strings(u8 *data) int i; =20 for (i =3D 0; i < net_selftest_get_count(); i++) - ethtool_sprintf(&data, "%2d. %s", i + 1, - net_selftests[i].name); + ethtool_sprintf(&data, "%s", net_selftests[i].name); } EXPORT_SYMBOL_GPL(net_selftest_get_strings); =20 --=20 2.39.5 From nobody Mon Apr 27 12:32:54 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E4D5208979 for ; Wed, 16 Apr 2025 16:14:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820090; cv=none; b=rVa7ny6MQASGBr7NkYUMWIjO2iY9N1KBzNzzOCpD7egOeEsy4ARCQ5gqXeLGPVpxepOvmtVGlEYfq3b2qisC0Yy9U3kk5lKnvopGxMMR95QkSWIdom41iSDQbRqHN7w//rfc8oVqFcbsMJ4yPiVf/7ZX258mmCLTZ32JNfnn/6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820090; c=relaxed/simple; bh=fNwmiRH0XeANoL4dIy3nW032Ca/tIxxGRC/mGgAzepg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rXJqnV+FeA3G4DXAdVHvuWsWuAbDG7mO97jLUWtl/kEJnkvMeNGGCUk3qkaZxAF/5nAXgihwW5VrRKHcujP8O4eZHLC90xXGFL1N+z9UnY9tKg63nUBqxEhSD6hFtSGA5hLLe/Gng6SVWZ+55ZLyx2LiNZhBXsDLIPW0wcEDXpo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1u55PN-0002G1-D7; Wed, 16 Apr 2025 18:14:41 +0200 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac]) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1u55PN-000c9G-0O; Wed, 16 Apr 2025 18:14:41 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1u55PN-00CGQS-0B; Wed, 16 Apr 2025 18:14:41 +0200 From: Oleksij Rempel To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Maxime Chevallier Subject: [PATCH net-next v1 2/4] net: selftest: prepare for detailed error handling in net_test_get_skb() Date: Wed, 16 Apr 2025 18:14:37 +0200 Message-Id: <20250416161439.2922994-3-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250416161439.2922994-1-o.rempel@pengutronix.de> References: <20250416161439.2922994-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Replace NULL return with ERR_PTR(-ENOMEM) in net_test_get_skb() and update the caller to use IS_ERR/PTR_ERR. This prepares the code for follow-up changes that will return more specific error codes from net_test_get_skb(). Signed-off-by: Oleksij Rempel Reviewed-by: Simon Horman --- net/core/selftests.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/selftests.c b/net/core/selftests.c index 3c3e2b2a22c9..34e751d885d7 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -74,7 +74,7 @@ static struct sk_buff *net_test_get_skb(struct net_device= *ndev, =20 skb =3D netdev_alloc_skb(ndev, size); if (!skb) - return NULL; + return ERR_PTR(-ENOMEM); =20 prefetchw(skb->data); =20 @@ -267,8 +267,8 @@ static int __net_test_loopback(struct net_device *ndev, dev_add_pack(&tpriv->pt); =20 skb =3D net_test_get_skb(ndev, attr); - if (!skb) { - ret =3D -ENOMEM; + if (IS_ERR(skb)) { + ret =3D PTR_ERR(skb); goto cleanup; } =20 --=20 2.39.5 From nobody Mon Apr 27 12:32:54 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BAA24210F59 for ; Wed, 16 Apr 2025 16:14:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820091; cv=none; b=VMJGBoJNxj55WkKht6o9dRAIbSGd7xL2SviAOcjGnJ9QOTN3wzzjRbAbpel1m2oIynv0FF50T2WkrAvr1D/XTBoZPGMgq+ufNQza4sIi4oGwj852H9BrelsRFOCPmu4XnR0it7OkTz3/8vEqTjrVeBMRmBGE6lj1zKHis6Rkn1E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820091; c=relaxed/simple; bh=lVi5qcUYCb6GCjGsEfgk84V0wF5w6QFo0FtxiPgItJ4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=ljaPqKk0ci/ib/8d4izZOi1IaExGXJ5XU4lgnJD5S9ZShywuLzrpmcK3g+bzBN6AK8YW3n2/5L0iCQ7EkIdC2LNhF8svkZqzrLIknlpH6Sqdo+VT4VIzzomplJpOhO2Th0OtIk8ICgGNJTcxbEk9EhZBr3TRWKbU6TG8Wl9O7D4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1u55PN-0002G2-D7; Wed, 16 Apr 2025 18:14:41 +0200 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac]) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1u55PN-000c9H-0U; Wed, 16 Apr 2025 18:14:41 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1u55PN-00CGQd-0F; Wed, 16 Apr 2025 18:14:41 +0200 From: Oleksij Rempel To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Maxime Chevallier Subject: [PATCH net-next v1 3/4] net: selftest: add checksum mode support and SW checksum handling Date: Wed, 16 Apr 2025 18:14:38 +0200 Message-Id: <20250416161439.2922994-4-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250416161439.2922994-1-o.rempel@pengutronix.de> References: <20250416161439.2922994-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Introduce `enum net_test_checksum_mode` to support both CHECKSUM_COMPLETE and CHECKSUM_PARTIAL modes in selftest packet generation. Add helpers to calculate and apply software checksums for TCP/UDP in CHECKSUM_COMPLETE mode, and refactor checksum handling into a dedicated function `net_test_set_checksum()`. Update PHY loopback tests to use CHECKSUM_COMPLETE by default to avoid hardware offload dependencies and improve reliability. Also rename loopback test names to clarify checksum type and transport. Signed-off-by: Oleksij Rempel --- net/core/selftests.c | 218 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 206 insertions(+), 12 deletions(-) diff --git a/net/core/selftests.c b/net/core/selftests.c index 34e751d885d7..5d7ff6f829b5 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -14,6 +14,11 @@ #include #include =20 +enum net_test_checksum_mode { + NET_TEST_CHECKSUM_COMPLETE, + NET_TEST_CHECKSUM_PARTIAL, +}; + struct net_packet_attrs { const unsigned char *src; const unsigned char *dst; @@ -27,6 +32,7 @@ struct net_packet_attrs { int max_size; u8 id; u16 queue_mapping; + enum net_test_checksum_mode csum_mode; }; =20 struct net_test_priv { @@ -51,6 +57,133 @@ static u8 net_test_next_id; #define NET_TEST_PKT_MAGIC 0xdeadcafecafedeadULL #define NET_LB_TIMEOUT msecs_to_jiffies(200) =20 +/** + * net_test_setup_sw_csum - Compute and apply software checksum + * (CHECKSUM_COMPLETE) + * @skb: Socket buffer with transport header set + * @iph: Pointer to IPv4 header inside skb + * + * This function computes and fills the transport layer checksum (TCP or U= DP), + * and sets skb->ip_summed =3D CHECKSUM_COMPLETE. + * + * Returns 0 on success, or negative error code on failure. + */ +static int net_test_setup_sw_csum(struct sk_buff *skb, + struct iphdr *iph) +{ + int transport_offset =3D skb_transport_offset(skb); + int transport_len =3D skb->len - transport_offset; + __be16 final_csum; + __wsum csum; + + switch (iph->protocol) { + case IPPROTO_TCP: + if (!pskb_may_pull(skb, + transport_offset + sizeof(struct tcphdr))) + return -EFAULT; + + tcp_hdr(skb)->check =3D 0; + break; + case IPPROTO_UDP: + if (!pskb_may_pull(skb, + transport_offset + sizeof(struct udphdr))) + return -EFAULT; + + udp_hdr(skb)->check =3D 0; + break; + default: + pr_err("net_selftest: unsupported proto for sw csum: %u\n", + iph->protocol); + return -EINVAL; + } + + csum =3D skb_checksum(skb, transport_offset, transport_len, 0); + final_csum =3D csum_tcpudp_magic(iph->saddr, iph->daddr, transport_len, + iph->protocol, csum); + + if (iph->protocol =3D=3D IPPROTO_UDP && final_csum =3D=3D 0) + final_csum =3D CSUM_MANGLED_0; + + if (iph->protocol =3D=3D IPPROTO_TCP) + tcp_hdr(skb)->check =3D final_csum; + else + udp_hdr(skb)->check =3D final_csum; + + skb->ip_summed =3D CHECKSUM_COMPLETE; + + return 0; +} + +/** + * net_test_setup_hw_csum - Setup skb for hardware checksum offload + * (CHECKSUM_PARTIAL) + * @skb: Socket buffer to prepare + * @iph: Pointer to IPv4 header inside skb + * + * This function sets skb fields and clears transport checksum field + * so that the NIC or driver can compute the checksum during transmit. + * + * Returns 0 on success, or negative error code on failure. + */ +static int net_test_setup_hw_csum(struct sk_buff *skb, struct iphdr *iph) +{ + u16 csum_offset; + + skb->ip_summed =3D CHECKSUM_PARTIAL; + skb->csum =3D 0; + + switch (iph->protocol) { + case IPPROTO_TCP: + if (!tcp_hdr(skb)) + return -EINVAL; + tcp_hdr(skb)->check =3D 0; + csum_offset =3D offsetof(struct tcphdr, check); + break; + case IPPROTO_UDP: + if (!udp_hdr(skb)) + return -EINVAL; + udp_hdr(skb)->check =3D 0; + csum_offset =3D offsetof(struct udphdr, check); + break; + default: + pr_err("net_selftest: unsupported proto for hw csum: %u\n", + iph->protocol); + return -EINVAL; + } + + skb->csum_start =3D skb_transport_header(skb) - skb->head; + skb->csum_offset =3D csum_offset; + + return 0; +} + +/** + * net_test_set_checksum - Apply requested checksum mode to skb + * @skb: Socket buffer containing the packet + * @attr: Packet attributes including desired checksum mode + * @iph: Pointer to the IP header within skb + * + * This function sets up the skb's checksum handling based on + * attr->csum_mode by calling the appropriate helper. + * + * Returns 0 on success, or negative error code on failure. + */ +static int net_test_set_checksum(struct sk_buff *skb, + struct net_packet_attrs *attr, + struct iphdr *iph) +{ + switch (attr->csum_mode) { + case NET_TEST_CHECKSUM_COMPLETE: + return net_test_setup_sw_csum(skb, iph); + case NET_TEST_CHECKSUM_PARTIAL: + return net_test_setup_hw_csum(skb, iph); + default: + pr_err("net_selftest: invalid checksum mode: %d\n", + attr->csum_mode); + return -EINVAL; + } +} + static struct sk_buff *net_test_get_skb(struct net_device *ndev, struct net_packet_attrs *attr) { @@ -61,6 +194,7 @@ static struct sk_buff *net_test_get_skb(struct net_devic= e *ndev, struct ethhdr *ehdr; struct iphdr *ihdr; int iplen, size; + int ret; =20 size =3D attr->size + NET_TEST_PKT_SIZE; =20 @@ -157,15 +291,10 @@ static struct sk_buff *net_test_get_skb(struct net_de= vice *ndev, memset(pad, 0, pad_len); } =20 - skb->csum =3D 0; - skb->ip_summed =3D CHECKSUM_PARTIAL; - if (attr->tcp) { - thdr->check =3D ~tcp_v4_check(skb->len, ihdr->saddr, - ihdr->daddr, 0); - skb->csum_start =3D skb_transport_header(skb) - skb->head; - skb->csum_offset =3D offsetof(struct tcphdr, check); - } else { - udp4_hwcsum(skb, ihdr->saddr, ihdr->daddr); + ret =3D net_test_set_checksum(skb, attr, ihdr); + if (ret < 0) { + kfree_skb(skb); + return ERR_PTR(ret); } =20 skb->protocol =3D htons(ETH_P_IP); @@ -318,29 +447,94 @@ static int net_test_phy_loopback_disable(struct net_d= evice *ndev) return phy_loopback(ndev->phydev, false, 0); } =20 +/** + * net_test_phy_loopback_udp - Basic PHY loopback test using UDP with SW + * checksum + * @ndev: The network device to test + * + * Sends and receives a minimal UDP packet through the device's internal + * PHY loopback path. The transport checksum is computed in software + * (CHECKSUM_COMPLETE), ensuring test validity regardless of hardware + * checksum offload support. + * + * Expected packet path: + * Test code =E2=86=92 MAC driver =E2=86=92 MAC HW =E2=86=92 xMII =E2=86= =92 PHY =E2=86=92 + * internal PHY loopback =E2=86=92 xMII =E2=86=92 MAC HW =E2=86=92 MAC d= river =E2=86=92 test code + * + * The test frame includes Ethernet (14B), IPv4 (20B), UDP (8B), and a + * minimal payload (13B), totaling 55 bytes before padding/FCS. Most + * MACs will pad this to 60 bytes before appending the FCS. + * + * Returns 0 on success, or negative error code on failure. + */ static int net_test_phy_loopback_udp(struct net_device *ndev) { struct net_packet_attrs attr =3D { }; =20 attr.dst =3D ndev->dev_addr; + attr.tcp =3D false; + attr.csum_mode =3D NET_TEST_CHECKSUM_COMPLETE; + return __net_test_loopback(ndev, &attr); } =20 +/** + * net_test_phy_loopback_udp_mtu - PHY loopback test using UDP MTU-sized f= rame + * with SW checksum + * @ndev: The network device to test + * + * Sends and receives a UDP packet through the device's internal PHY loopb= ack + * path. The packet uses software checksum calculation (CHECKSUM_COMPLETE), + * and the total L2 frame size is padded to match the device MTU. + * + * This tests the loopback path with larger frames and ensures checksum + * correctness regardless of hardware offload support. + * + * Expected packet path: + * Test code =E2=86=92 MAC driver =E2=86=92 MAC HW =E2=86=92 xMII =E2=86= =92 PHY =E2=86=92 + * internal PHY loopback =E2=86=92 xMII =E2=86=92 MAC HW =E2=86=92 MAC d= river =E2=86=92 test code + * + * Returns 0 on success, or negative error code on failure. + */ static int net_test_phy_loopback_udp_mtu(struct net_device *ndev) { struct net_packet_attrs attr =3D { }; =20 attr.dst =3D ndev->dev_addr; attr.max_size =3D ndev->mtu; + attr.tcp =3D false; + attr.csum_mode =3D NET_TEST_CHECKSUM_COMPLETE; + return __net_test_loopback(ndev, &attr); } =20 +/** + * net_test_phy_loopback_tcp - PHY loopback test using TCP with SW checksum + * @ndev: The network device to test + * + * Sends and receives a minimal TCP packet through the device's internal + * PHY loopback path. The checksum is computed in software + * (CHECKSUM_COMPLETE), avoiding reliance on hardware checksum offload, + * which may behave inconsistently with TCP in some loopback setups. + * + * Expected packet path: + * Test code =E2=86=92 MAC driver =E2=86=92 MAC HW =E2=86=92 xMII =E2=86= =92 PHY =E2=86=92 + * internal PHY loopback =E2=86=92 xMII =E2=86=92 MAC HW =E2=86=92 MAC d= river =E2=86=92 test code + * + * The generated test frame includes Ethernet (14B), IPv4 (20B), TCP (20B), + * and a small payload (13B), totaling 67 bytes before FCS. Since the total + * exceeds the Ethernet minimum, MAC padding is typically not applied. + * + * Returns 0 on success, or negative error code on failure. + */ static int net_test_phy_loopback_tcp(struct net_device *ndev) { struct net_packet_attrs attr =3D { }; =20 attr.dst =3D ndev->dev_addr; attr.tcp =3D true; + attr.csum_mode =3D NET_TEST_CHECKSUM_COMPLETE; + return __net_test_loopback(ndev, &attr); } =20 @@ -359,13 +553,13 @@ static const struct net_test { .name =3D "PHY internal loopback, enable ", .fn =3D net_test_phy_loopback_enable, }, { - .name =3D "PHY internal loopback, UDP ", + .name =3D "PHY loopback UDP (SW csum) ", .fn =3D net_test_phy_loopback_udp, }, { - .name =3D "PHY internal loopback, MTU ", + .name =3D "PHY loopback UDP MTU (SW csum)", .fn =3D net_test_phy_loopback_udp_mtu, }, { - .name =3D "PHY internal loopback, TCP ", + .name =3D "PHY loopback TCP (SW csum) ", .fn =3D net_test_phy_loopback_tcp, }, { /* This test should be done after all PHY loopback test */ --=20 2.39.5 From nobody Mon Apr 27 12:32:54 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FA7C1ADC78 for ; Wed, 16 Apr 2025 16:14:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820089; cv=none; b=oO9TsaBIld0jKK0hB6tmAJtxeIcrwDSZfDh6mncifEA343xCmB9IE8Btjt0EK0rgEuKrV2sTxQ6/RoDTOKqjrJtdLKbdGNX0tO22u2qB0s/YPK+s7KBIlxFM9iI7ISqhAMKvqQumvV6eDmwGqOv8GGPNoZSinHgvQ9QFFm4qfNY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744820089; c=relaxed/simple; bh=m7JdAv/gR2wOm1IwxWiecnlj3I4dJwl5VssYK1xzS+k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=Z+WicRTGwp0L71FZVXB+3mORH548S5ZWuOaARXlicQxfZH6LfmpRo0qR+Pc83T0Wz3B0g4PtEyS5OntP6PYVqGZQKYjHn9hkWOJToGcTvnLGxr2/F10kmHpygNQ00ngPOoQx+StaO4T9VmYj9RmF/DTLeiHhFZMPMVGbTNmzHco= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1u55PN-0002G3-D7; Wed, 16 Apr 2025 18:14:41 +0200 Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac]) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1u55PN-000c9K-0W; Wed, 16 Apr 2025 18:14:41 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1u55PN-00CGQn-0J; Wed, 16 Apr 2025 18:14:41 +0200 From: Oleksij Rempel To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Maxime Chevallier Subject: [PATCH net-next v1 4/4] net: selftest: add PHY loopback tests with HW checksum offload Date: Wed, 16 Apr 2025 18:14:39 +0200 Message-Id: <20250416161439.2922994-5-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250416161439.2922994-1-o.rempel@pengutronix.de> References: <20250416161439.2922994-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Introduce two new PHY loopback tests that validate hardware checksum offload functionality using UDP and TCP packets. These tests set csum_mode =3D CHECKSUM_PARTIAL, allowing the NIC to compute transport checksums. Tests are only executed if the device advertises NETIF_F_HW_CSUM support. If not, they are skipped with -EOPNOTSUPP. Also register the tests under descriptive names in the test list. Signed-off-by: Oleksij Rempel Reviewed-by: Simon Horman --- net/core/selftests.c | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/net/core/selftests.c b/net/core/selftests.c index 5d7ff6f829b5..07140242a390 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -538,6 +538,79 @@ static int net_test_phy_loopback_tcp(struct net_device= *ndev) return __net_test_loopback(ndev, &attr); } =20 +/** + * net_test_phy_loopback_udp_hwcsum - PHY loopback test using UDP with HW + * checksum + * @ndev: The network device to test + * + * Sends and receives a UDP packet through the device's internal PHY loopb= ack + * path. The packet is configured for hardware checksum offload + * (CHECKSUM_PARTIAL), allowing the NIC to compute the transport checksum. + * + * Expected packet path: + * Test code =E2=86=92 MAC driver =E2=86=92 MAC HW =E2=86=92 xMII =E2=86= =92 PHY =E2=86=92 + * internal PHY loopback =E2=86=92 xMII =E2=86=92 MAC HW =E2=86=92 MAC d= river =E2=86=92 test code + * + * The test frame includes Ethernet (14B), IPv4 (20B), UDP (8B), and a + * small payload (13B), totaling 55 bytes before MAC padding/FCS. Most + * MACs pad this to the minimum Ethernet payload (60 bytes before FCS). + * + * If the device does not support NETIF_F_HW_CSUM, the test is skipped + * and -EOPNOTSUPP is returned. + * + * Returns 0 on success, or negative error code on failure. + */ +static int net_test_phy_loopback_udp_hwcsum(struct net_device *ndev) +{ + struct net_packet_attrs attr =3D { }; + + if (!(ndev->features & NETIF_F_HW_CSUM)) + return -EOPNOTSUPP; + + attr.dst =3D ndev->dev_addr; + attr.tcp =3D false; + attr.csum_mode =3D NET_TEST_CHECKSUM_PARTIAL; + + return __net_test_loopback(ndev, &attr); +} + +/** + * net_test_phy_loopback_tcp_hwcsum - PHY loopback test using TCP with HW + * checksum + * @ndev: The network device to test + * + * Sends and receives a TCP packet through the device's internal PHY loopb= ack + * path. The packet is configured for hardware checksum offload + * (CHECKSUM_PARTIAL), allowing the NIC to compute the transport checksum. + * + * Expected packet path: + * Test code =E2=86=92 MAC driver =E2=86=92 MAC HW =E2=86=92 xMII =E2=86= =92 PHY =E2=86=92 + * internal PHY loopback =E2=86=92 xMII =E2=86=92 MAC HW =E2=86=92 MAC d= river =E2=86=92 test code + * (via packet_type handler) + * + * The test frame includes Ethernet (14B), IPv4 (20B), TCP (20B), + * and a small payload (13B), totaling 67 bytes before FCS. + * No additional padding is required. + * + * If the device does not support NETIF_F_HW_CSUM, the test is skipped + * and -EOPNOTSUPP is returned. + * + * Returns 0 on success, or negative error code on failure. + */ +static int net_test_phy_loopback_tcp_hwcsum(struct net_device *ndev) +{ + struct net_packet_attrs attr =3D { }; + + if (!(ndev->features & NETIF_F_HW_CSUM)) + return -EOPNOTSUPP; + + attr.dst =3D ndev->dev_addr; + attr.tcp =3D true; + attr.csum_mode =3D NET_TEST_CHECKSUM_PARTIAL; + + return __net_test_loopback(ndev, &attr); +} + static const struct net_test { char name[ETH_GSTRING_LEN]; int (*fn)(struct net_device *ndev); @@ -561,6 +634,13 @@ static const struct net_test { }, { .name =3D "PHY loopback TCP (SW csum) ", .fn =3D net_test_phy_loopback_tcp, + }, { + /* Conditional HW checksum tests */ + .name =3D "PHY loopback UDP (HW csum) ", + .fn =3D net_test_phy_loopback_udp_hwcsum, + }, { + .name =3D "PHY loopback TCP (HW csum) ", + .fn =3D net_test_phy_loopback_tcp_hwcsum, }, { /* This test should be done after all PHY loopback test */ .name =3D "PHY internal loopback, disable", --=20 2.39.5