[PATCH 2/3] net: amd-xgbe: add ARP offload ethtool self-test

Raju Rangoju posted 3 patches 4 days, 13 hours ago
[PATCH 2/3] net: amd-xgbe: add ARP offload ethtool self-test
Posted by Raju Rangoju 4 days, 13 hours ago
Add an ethtool self-test to verify the hardware ARP offload
functionality. The test validates that the MAC correctly responds
to ARP requests without CPU intervention.

Test procedure:
1. Check for aoe (ARP Offload Engine) hardware capability
2. Create an ARP request packet with test IP addresses
3. Enable ARP offload with the target IP address
4. Transmit the ARP request in PHY loopback mode
5. Verify that an ARP reply is received from the hardware
6. Clean up and restore configuration

The test requires the device to be in PHY loopback mode and runs as part
of offline ethtool self-test suite.

Usage:
  $ ethtool -t <interface>

Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
---
 drivers/net/ethernet/amd/xgbe/xgbe-selftest.c | 117 ++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c b/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c
index 55e5e467facd..ae4825578c59 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c
@@ -9,8 +9,10 @@
 #include <linux/crc32.h>
 #include <linux/ip.h>
 #include <linux/udp.h>
+#include <linux/if_arp.h>
 #include <net/tcp.h>
 #include <net/udp.h>
+#include <net/arp.h>
 #include <net/checksum.h>
 #include <net/selftests.h>
 
@@ -152,6 +154,117 @@ static int __xgbe_test_loopback(struct xgbe_prv_data *pdata,
 	return ret;
 }
 
+static int xgbe_test_arp_validate(struct sk_buff *skb,
+				  struct net_device *ndev,
+				  struct packet_type *pt,
+				  struct net_device *orig_ndev)
+{
+	struct net_test_priv *tdata = pt->af_packet_priv;
+	struct ethhdr *eth_hdr;
+	struct arphdr *ah;
+
+	skb = skb_unshare(skb, GFP_ATOMIC);
+	if (!skb)
+		goto out;
+	if (skb_linearize(skb))
+		goto out;
+
+	eth_hdr = (struct ethhdr *)skb_mac_header(skb);
+
+	/* Verify the reply is destined to our test source MAC */
+	if (!ether_addr_equal_unaligned(eth_hdr->h_dest, tdata->packet->src))
+		goto out;
+
+	/* Verify this is an ARP packet */
+	if (eth_hdr->h_proto != htons(ETH_P_ARP))
+		goto out;
+
+	ah = arp_hdr(skb);
+
+	/* Verify this is an ARP reply */
+	if (ah->ar_op != htons(ARPOP_REPLY))
+		goto out;
+
+	tdata->ok = true;
+	complete(&tdata->comp);
+out:
+	kfree_skb(skb);
+	return 0;
+}
+
+static int xgbe_test_arpoffload(struct xgbe_prv_data *pdata)
+{
+	unsigned char src[ETH_ALEN] = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
+	unsigned char bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+	struct net_packet_attrs attr = {};
+	struct net_test_priv *tdata;
+	struct sk_buff *skb = NULL;
+	u32 dst_ip = 0xabcdefab;
+	u32 src_ip = 0xefdcbaef;
+	int ret;
+
+	/* Check if ARP offload is supported */
+	if (!pdata->hw_feat.aoe)
+		return -EOPNOTSUPP;
+
+	tdata = kzalloc(sizeof(*tdata), GFP_KERNEL);
+	if (!tdata)
+		return -ENOMEM;
+
+	tdata->ok = false;
+	init_completion(&tdata->comp);
+
+	tdata->pt.type = htons(ETH_P_ARP);
+	tdata->pt.func = xgbe_test_arp_validate;
+	tdata->pt.dev = pdata->netdev;
+	tdata->pt.af_packet_priv = tdata;
+	tdata->packet = &attr;
+	dev_add_pack(&tdata->pt);
+
+	attr.src = src;
+	attr.ip_src = src_ip;
+	attr.dst = bcast;
+	attr.ip_dst = dst_ip;
+
+	/* Create ARP request packet */
+	skb = arp_create(ARPOP_REQUEST, ETH_P_ARP, htonl(dst_ip),
+			 pdata->netdev,	htonl(src_ip), NULL, src, bcast);
+	if (!skb) {
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	skb->pkt_type = PACKET_HOST;
+	skb->dev = pdata->netdev;
+	skb->protocol = htons(ETH_P_ARP);
+
+	/* Enable ARP offload */
+	xgbe_enable_arp_offload(pdata, dst_ip);
+
+	ret = dev_set_promiscuity(pdata->netdev, 1);
+	if (ret) {
+		kfree_skb(skb);
+		goto cleanup;
+	}
+
+	ret = dev_direct_xmit(skb, 0);
+	if (ret)
+		goto cleanup_promisc;
+
+	/* Wait for ARP reply */
+	wait_for_completion_timeout(&tdata->comp, NET_LB_TIMEOUT);
+	ret = tdata->ok ? 0 : -ETIMEDOUT;
+
+cleanup_promisc:
+	dev_set_promiscuity(pdata->netdev, -1);
+cleanup:
+	xgbe_disable_arp_offload(pdata);
+	dev_remove_pack(&tdata->pt);
+free:
+	kfree(tdata);
+	return ret;
+}
+
 static int xgbe_test_mac_loopback(struct xgbe_prv_data *pdata)
 {
 	struct net_packet_attrs attr = {};
@@ -251,6 +364,10 @@ static const struct xgbe_test xgbe_selftests[] = {
 		.name = "Jumbo Frame    ",
 		.lb = XGBE_LOOPBACK_PHY,
 		.fn = xgbe_test_jumbo,
+	}, {
+		.name = "ARP Offload    ",
+		.lb = XGBE_LOOPBACK_PHY,
+		.fn = xgbe_test_arpoffload,
 	},
 };
 
-- 
2.34.1
Re: [PATCH 2/3] net: amd-xgbe: add ARP offload ethtool self-test
Posted by kernel test robot 4 days, 2 hours ago
Hi Raju,

kernel test robot noticed the following build errors:

[auto build test ERROR on net/main]
[also build test ERROR on net-next/main linus/master v6.19-rc8 next-20260202]
[cannot apply to horms-ipvs/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Raju-Rangoju/net-amd-xgbe-add-hardware-ARP-offload-support/20260202-235023
base:   net/main
patch link:    https://lore.kernel.org/r/20260202153542.1727429-3-Raju.Rangoju%40amd.com
patch subject: [PATCH 2/3] net: amd-xgbe: add ARP offload ethtool self-test
config: powerpc-randconfig-002-20260203 (https://download.01.org/0day-ci/archive/20260203/202602030920.SWN7cwzT-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260203/202602030920.SWN7cwzT-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/202602030920.SWN7cwzT-lkp@intel.com/

All errors (new ones prefixed by >>):

   powerpc-linux-ld: drivers/net/ethernet/amd/xgbe/xgbe-selftest.o: in function `xgbe_test_arpoffload':
>> drivers/net/ethernet/amd/xgbe/xgbe-selftest.c:230: undefined reference to `arp_create'
   powerpc-linux-ld: net/core/selftests.o: in function `net_test_get_skb':
   net/core/selftests.c:104: undefined reference to `ip_send_check'
   powerpc-linux-ld: net/core/selftests.c:148: undefined reference to `udp4_hwcsum'

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for HOTPLUG_CPU
   Depends on [n]: SMP [=y] && (PPC_PSERIES [=n] || PPC_PMAC [=n] || PPC_POWERNV [=n] || FSL_SOC_BOOKE [=n])
   Selected by [y]:
   - PM_SLEEP_SMP [=y] && SMP [=y] && (ARCH_SUSPEND_POSSIBLE [=n] || ARCH_HIBERNATION_POSSIBLE [=y]) && PM_SLEEP [=y]
   WARNING: unmet direct dependencies detected for NET_SELFTESTS
   Depends on [n]: NET [=y] && PHYLIB [=y] && INET [=n]
   Selected by [y]:
   - AMD_XGBE [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_AMD [=y] && (OF_ADDRESS [=y] || ACPI || PCI [=n]) && HAS_IOMEM [=y] && (X86 || ARM64 || COMPILE_TEST [=y]) && PTP_1588_CLOCK_OPTIONAL [=y]


vim +230 drivers/net/ethernet/amd/xgbe/xgbe-selftest.c

   194	
   195	static int xgbe_test_arpoffload(struct xgbe_prv_data *pdata)
   196	{
   197		unsigned char src[ETH_ALEN] = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
   198		unsigned char bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
   199		struct net_packet_attrs attr = {};
   200		struct net_test_priv *tdata;
   201		struct sk_buff *skb = NULL;
   202		u32 dst_ip = 0xabcdefab;
   203		u32 src_ip = 0xefdcbaef;
   204		int ret;
   205	
   206		/* Check if ARP offload is supported */
   207		if (!pdata->hw_feat.aoe)
   208			return -EOPNOTSUPP;
   209	
   210		tdata = kzalloc(sizeof(*tdata), GFP_KERNEL);
   211		if (!tdata)
   212			return -ENOMEM;
   213	
   214		tdata->ok = false;
   215		init_completion(&tdata->comp);
   216	
   217		tdata->pt.type = htons(ETH_P_ARP);
   218		tdata->pt.func = xgbe_test_arp_validate;
   219		tdata->pt.dev = pdata->netdev;
   220		tdata->pt.af_packet_priv = tdata;
   221		tdata->packet = &attr;
   222		dev_add_pack(&tdata->pt);
   223	
   224		attr.src = src;
   225		attr.ip_src = src_ip;
   226		attr.dst = bcast;
   227		attr.ip_dst = dst_ip;
   228	
   229		/* Create ARP request packet */
 > 230		skb = arp_create(ARPOP_REQUEST, ETH_P_ARP, htonl(dst_ip),
   231				 pdata->netdev,	htonl(src_ip), NULL, src, bcast);
   232		if (!skb) {
   233			ret = -ENOMEM;
   234			goto free;
   235		}
   236	
   237		skb->pkt_type = PACKET_HOST;
   238		skb->dev = pdata->netdev;
   239		skb->protocol = htons(ETH_P_ARP);
   240	
   241		/* Enable ARP offload */
   242		xgbe_enable_arp_offload(pdata, dst_ip);
   243	
   244		ret = dev_set_promiscuity(pdata->netdev, 1);
   245		if (ret) {
   246			kfree_skb(skb);
   247			goto cleanup;
   248		}
   249	
   250		ret = dev_direct_xmit(skb, 0);
   251		if (ret)
   252			goto cleanup_promisc;
   253	
   254		/* Wait for ARP reply */
   255		wait_for_completion_timeout(&tdata->comp, NET_LB_TIMEOUT);
   256		ret = tdata->ok ? 0 : -ETIMEDOUT;
   257	
   258	cleanup_promisc:
   259		dev_set_promiscuity(pdata->netdev, -1);
   260	cleanup:
   261		xgbe_disable_arp_offload(pdata);
   262		dev_remove_pack(&tdata->pt);
   263	free:
   264		kfree(tdata);
   265		return ret;
   266	}
   267	

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