[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <34647edacab660b4cabed9733d2d3ef22bc041ac.1768273593.git.daniel@makrotopia.org>
Date: Tue, 13 Jan 2026 03:11:54 +0000
From: Daniel Golle <daniel@...rotopia.org>
To: Felix Fietkau <nbd@....name>, John Crispin <john@...ozen.org>,
Sean Wang <sean.wang@...iatek.com>,
Lorenzo Bianconi <lorenzo@...nel.org>,
Bc-bocun Chen <bc-bocun.chen@...iatek.com>,
Rex Lu <rex.lu@...iatek.com>,
Mason-cw Chang <Mason-cw.Chang@...iatek.com>,
Andrew Lunn <andrew+netdev@...n.ch>,
"David S. Miller" <davem@...emloft.net>,
Andrew Lunn <andrew@...n.ch>, Vladimir Oltean <olteanv@...il.com>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
Matthias Brugger <matthias.bgg@...il.com>,
AngeloGioacchino Del Regno <angelogioacchino.delregno@...labora.com>,
netdev@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-mediatek@...ts.infradead.org
Subject: [PATCH net-next RFC] net: ethernet: mtk_eth_soc: support using
non-MediaTek DSA switches
MediaTek's Ethernet Frame Engine is tailored for use with their
switches. This broke checksum and VLAN offloading when attaching a
DSA switch which does not use MediaTek special tag format.
As a work-around, make sure checksum offloading is disabled and
make sure bits instructing the FE to parse or modify MTK special
tags aren't set if the attached DSA switch isn't using the
MediaTek special tag format.
Note that this currently also disables checksum and VLAN offloading
when using DSA switches using 802.1Q-based tags, though that those
do work fine and can benefit from the offloading features of the
Ethernet Frame Engine. This is why more feedback from DSA maintainers
regarding this issue would be very welcome.
Signed-off-by: Daniel Golle <daniel@...rotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 44 +++++++++++++++------
1 file changed, 31 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e68997a29191b..654b707ee27a1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1459,6 +1459,26 @@ static void setup_tx_buf(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
}
}
+static bool mtk_uses_dsa(struct net_device *dev)
+{
+#if IS_ENABLED(CONFIG_NET_DSA)
+ return netdev_uses_dsa(dev) &&
+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK;
+#else
+ return false;
+#endif
+}
+
+static bool non_mtk_uses_dsa(struct net_device *dev)
+{
+#if IS_ENABLED(CONFIG_NET_DSA)
+ return netdev_uses_dsa(dev) &&
+ dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK;
+#else
+ return false;
+#endif
+}
+
static void mtk_tx_set_dma_desc_v1(struct net_device *dev, void *txd,
struct mtk_tx_dma_desc_info *info)
{
@@ -1531,7 +1551,7 @@ static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd,
/* tx checksum offload */
if (info->csum)
data |= TX_DMA_CHKSUM_V2;
- if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
+ if (mtk_is_netsys_v3_or_greater(eth) && mtk_uses_dsa(dev))
data |= TX_DMA_SPTAG_V3;
}
WRITE_ONCE(desc->txd5, data);
@@ -2350,7 +2370,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
* hardware treats the MTK special tag as a VLAN and untags it.
*/
if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) &&
- netdev_uses_dsa(netdev)) {
+ mtk_uses_dsa(netdev)) {
unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
if (port < ARRAY_SIZE(eth->dsa_meta) &&
@@ -3192,6 +3212,14 @@ static netdev_features_t mtk_fix_features(struct net_device *dev,
}
}
+ if ((features & NETIF_F_IP_CSUM) &&
+ non_mtk_uses_dsa(dev))
+ features &= ~NETIF_F_IP_CSUM;
+
+ if ((features & NETIF_F_IPV6_CSUM) &&
+ non_mtk_uses_dsa(dev))
+ features &= ~NETIF_F_IPV6_CSUM;
+
return features;
}
@@ -3508,23 +3536,13 @@ static void mtk_gdm_config(struct mtk_eth *eth, u32 id, u32 config)
val |= config;
- if (eth->netdev[id] && netdev_uses_dsa(eth->netdev[id]))
+ if (eth->netdev[id] && mtk_uses_dsa(eth->netdev[id]))
val |= MTK_GDMA_SPECIAL_TAG;
mtk_w32(eth, val, MTK_GDMA_FWD_CFG(id));
}
-static bool mtk_uses_dsa(struct net_device *dev)
-{
-#if IS_ENABLED(CONFIG_NET_DSA)
- return netdev_uses_dsa(dev) &&
- dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK;
-#else
- return false;
-#endif
-}
-
static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr)
{
struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier);
--
2.52.0
Powered by blists - more mailing lists