net: stmmac: Remove ARP offload code

dwmac can do ARP offloading, where the HW replies to incoming ARP
requests. This requires multiple steps to work well :
 - Program the local IP address in a dedicated register
 - Enable ARP offloading

This is halfway implemented in stmmac, as it's only ever used by
selftests, and these selftests are failing on at least 2 platforms :
stm32mp1, and jh7110.

There have been some attempts in the past to support this feature, but
this never made it upstream. Let's just remove the test and that code,
until someone actually wants that to work. We should likely have a
proper API for that so that drivers can use it.

Let's also not mention ARP offload in the stmmac documentation.

Leave the defines in place and the capability detection, this doesn't
hurt and gives some information about how the IP is synthesized.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260831071351.354255-1-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Maxime Chevallier authored and Paolo Abeni committed 2026-09-01 15:14:43 +02:00
1 parent 25c1f61110
commit 85ca3292d7
5 files changed
-153

No files matched your search

@@ -69,7 +69,6 @@ The following features are available in this driver:
- Pulse-Per-Second Output (PPS)
- MDIO Clause 22 / Clause 45 Interface
- MAC Loopback
- ARP Offloading
- Automatic CRC / PAD Insertion and Checking
- Checksum Offload for Received and Transmitted Packets
- Standard or Jumbo Ethernet Packets
@@ -779,22 +779,6 @@ static void dwmac4_sarc_configure(void __iomem *ioaddr, int val)
writel(value, ioaddr + GMAC_CONFIG);
}
static void dwmac4_set_arp_offload(struct mac_device_info *hw, bool en,
u32 addr)
{
void __iomem *ioaddr = hw->pcsr;
u32 value;
writel(addr, ioaddr + GMAC_ARP_ADDR);
value = readl(ioaddr + GMAC_CONFIG);
if (en)
value |= GMAC_CONFIG_ARPEN;
else
value &= ~GMAC_CONFIG_ARPEN;
writel(value, ioaddr + GMAC_CONFIG);
}
static int dwmac4_config_l3_filter(struct mac_device_info *hw, u32 filter_no,
bool en, bool ipv6, bool sa, bool inv,
u32 match)
@@ -926,7 +910,6 @@ const struct stmmac_ops dwmac4_ops = {
.set_filter = dwmac4_set_filter,
.set_mac_loopback = dwmac4_set_mac_loopback,
.sarc_configure = dwmac4_sarc_configure,
.set_arp_offload = dwmac4_set_arp_offload,
.config_l3_filter = dwmac4_config_l3_filter,
.config_l4_filter = dwmac4_config_l4_filter,
};
@@ -963,7 +946,6 @@ const struct stmmac_ops dwmac410_ops = {
.flex_pps_config = dwmac5_flex_pps_config,
.set_mac_loopback = dwmac4_set_mac_loopback,
.sarc_configure = dwmac4_sarc_configure,
.set_arp_offload = dwmac4_set_arp_offload,
.config_l3_filter = dwmac4_config_l3_filter,
.config_l4_filter = dwmac4_config_l4_filter,
.fpe_map_preemption_class = dwmac5_fpe_map_preemption_class,
@@ -1005,7 +987,6 @@ const struct stmmac_ops dwmac510_ops = {
.flex_pps_config = dwmac5_flex_pps_config,
.set_mac_loopback = dwmac4_set_mac_loopback,
.sarc_configure = dwmac4_sarc_configure,
.set_arp_offload = dwmac4_set_arp_offload,
.config_l3_filter = dwmac4_config_l3_filter,
.config_l4_filter = dwmac4_config_l4_filter,
.fpe_map_preemption_class = dwmac5_fpe_map_preemption_class,
@@ -1410,22 +1410,6 @@ static int dwxgmac2_config_l4_filter(struct mac_device_info *hw, u32 filter_no,
return 0;
}
static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
u32 addr)
{
void __iomem *ioaddr = hw->pcsr;
u32 value;
writel(addr, ioaddr + XGMAC_ARP_ADDR);
value = readl(ioaddr + XGMAC_RX_CONFIG);
if (en)
value |= XGMAC_CONFIG_ARPEN;
else
value &= ~XGMAC_CONFIG_ARPEN;
writel(value, ioaddr + XGMAC_RX_CONFIG);
}
const struct stmmac_ops dwxgmac210_ops = {
.core_init = dwxgmac2_core_init,
.irq_modify = dwxgmac2_irq_modify,
@@ -1464,7 +1448,6 @@ const struct stmmac_ops dwxgmac210_ops = {
.sarc_configure = dwxgmac2_sarc_configure,
.config_l3_filter = dwxgmac2_config_l3_filter,
.config_l4_filter = dwxgmac2_config_l4_filter,
.set_arp_offload = dwxgmac2_set_arp_offload,
.fpe_map_preemption_class = dwxgmac3_fpe_map_preemption_class,
};
@@ -1519,7 +1502,6 @@ const struct stmmac_ops dwxlgmac2_ops = {
.sarc_configure = dwxgmac2_sarc_configure,
.config_l3_filter = dwxgmac2_config_l3_filter,
.config_l4_filter = dwxgmac2_config_l4_filter,
.set_arp_offload = dwxgmac2_set_arp_offload,
.fpe_map_preemption_class = dwxgmac3_fpe_map_preemption_class,
};
@@ -407,7 +407,6 @@ struct stmmac_ops {
int (*config_l4_filter)(struct mac_device_info *hw, u32 filter_no,
bool en, bool udp, bool sa, bool inv,
u32 match);
void (*set_arp_offload)(struct mac_device_info *hw, bool en, u32 addr);
int (*fpe_map_preemption_class)(struct net_device *ndev,
struct netlink_ext_ack *extack,
u32 pclass);
@@ -491,8 +490,6 @@ struct stmmac_ops {
stmmac_do_callback(__priv, mac, config_l3_filter, __args)
#define stmmac_config_l4_filter(__priv, __args...) \
stmmac_do_callback(__priv, mac, config_l4_filter, __args)
#define stmmac_set_arp_offload(__priv, __args...) \
stmmac_do_void_callback(__priv, mac, set_arp_offload, __args)
#define stmmac_fpe_map_preemption_class(__priv, __args...) \
stmmac_do_void_callback(__priv, mac, fpe_map_preemption_class, __args)
@@ -215,24 +215,6 @@ static struct sk_buff *stmmac_test_get_udp_skb(struct stmmac_priv *priv,
return skb;
}
static struct sk_buff *stmmac_test_get_arp_skb(struct stmmac_priv *priv,
struct stmmac_packet_attrs *attr)
{
__be32 ip_src = htonl(attr->ip_src);
__be32 ip_dst = htonl(attr->ip_dst);
struct sk_buff *skb = NULL;
skb = arp_create(ARPOP_REQUEST, ETH_P_ARP, ip_dst, priv->dev, ip_src,
NULL, attr->src, attr->dst);
if (!skb)
return NULL;
skb->pkt_type = PACKET_HOST;
skb->dev = priv->dev;
return skb;
}
struct stmmac_test_priv {
struct stmmac_packet_attrs *packet;
struct packet_type pt;
@@ -1603,97 +1585,6 @@ static int stmmac_test_l4filt_sa_udp(struct stmmac_priv *priv)
return __stmmac_test_l4filt(priv, 0, dummy_port, 0, ~0, true);
}
static int stmmac_test_arp_validate(struct sk_buff *skb,
struct net_device *ndev,
struct packet_type *pt,
struct net_device *orig_ndev)
{
struct stmmac_test_priv *tpriv = pt->af_packet_priv;
struct ethhdr *ehdr;
struct arphdr *ahdr;
ehdr = (struct ethhdr *)skb_mac_header(skb);
if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->src))
goto out;
ahdr = arp_hdr(skb);
if (ahdr->ar_op != htons(ARPOP_REPLY))
goto out;
tpriv->ok = true;
complete(&tpriv->comp);
out:
kfree_skb(skb);
return 0;
}
static int stmmac_test_arpoffload(struct stmmac_priv *priv)
{
unsigned char src[ETH_ALEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
unsigned char dst[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct stmmac_packet_attrs attr = { };
struct stmmac_test_priv *tpriv;
struct sk_buff *skb = NULL;
u32 ip_addr = 0xdeadcafe;
u32 ip_src = 0xdeadbeef;
int ret;
if (!priv->dma_cap.arpoffsel)
return -EOPNOTSUPP;
tpriv = kzalloc_obj(*tpriv);
if (!tpriv)
return -ENOMEM;
tpriv->ok = false;
init_completion(&tpriv->comp);
tpriv->pt.type = htons(ETH_P_ARP);
tpriv->pt.func = stmmac_test_arp_validate;
tpriv->pt.dev = priv->dev;
tpriv->pt.af_packet_priv = tpriv;
tpriv->packet = &attr;
dev_add_pack(&tpriv->pt);
attr.src = src;
attr.ip_src = ip_src;
attr.dst = dst;
attr.ip_dst = ip_addr;
skb = stmmac_test_get_arp_skb(priv, &attr);
if (!skb) {
ret = -ENOMEM;
goto cleanup;
}
ret = stmmac_set_arp_offload(priv, priv->hw, true, ip_addr);
if (ret) {
kfree_skb(skb);
goto cleanup;
}
ret = dev_set_promiscuity(priv->dev, 1);
if (ret) {
kfree_skb(skb);
goto cleanup;
}
ret = dev_direct_xmit(skb, 0);
if (ret)
goto cleanup_promisc;
wait_for_completion_timeout(&tpriv->comp, STMMAC_LB_TIMEOUT);
ret = tpriv->ok ? 0 : -ETIMEDOUT;
cleanup_promisc:
dev_set_promiscuity(priv->dev, -1);
cleanup:
stmmac_set_arp_offload(priv, priv->hw, false, 0x0);
dev_remove_pack(&tpriv->pt);
kfree(tpriv);
return ret;
}
static int __stmmac_test_jumbo(struct stmmac_priv *priv, u16 queue)
{
struct stmmac_packet_attrs attr = { };
@@ -1911,9 +1802,6 @@ static const struct stmmac_test {
}, {
.name = "L4 SA UDP Filtering ",
.fn = stmmac_test_l4filt_sa_udp,
}, {
.name = "ARP Offload ",
.fn = stmmac_test_arpoffload,
}, {
.name = "Jumbo Frame ",
.fn = stmmac_test_jumbo,