[PATCH] net: ethernet: mtk_eth_soc: allocate dummy netdev before registering netdevs
From: Sandeep Haemoon <hidden>
Date: 2026-09-15 19:03:05
Also in:
stable
Subsystem:
mediatek ethernet driver, networking drivers, the rest · Maintainers:
Felix Fietkau, Lorenzo Bianconi, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sandeep Haemoon <redacted> Date: Tue, 15 Sep 2026 22:00:00 +0300 Subject: [PATCH] net: ethernet: mtk_eth_soc: allocate dummy netdev before registering netdevs The DMA ring and NAPI are shared between the multiple MAC netdevs and are carried by an internal "dummy" netdev (eth->dummy_dev). mtk_probe() creates that dummy device only after the MAC netdevs have been registered, so for a brief window the netdevs are visible to the network core while eth->dummy_dev is still NULL. If anything brings the first netdev up during that window (e.g. netifd opening the WAN link the instant the interface is registered), mtk_open() takes the first-open path and runs mtk_start_dma() -> mtk_dma_init() -> mtk_rx_alloc(), which calls __xdp_rxq_info_reg() with eth->dummy_dev == NULL. That triggers WARNING: CPU: ... Missing net_device from driver in net/core/xdp.c and returns -ENODEV, so mtk_open() fails and the interface (e.g. the WAN port on MediaTek MT7988) stays down until it is manually brought up after probe has completed. Allocate the dummy netdev and add the shared tx/rx NAPI to it before registering the MAC netdevs, and free it from the probe error path instead of the now-unneeded err_unreg_netdev cleanup. Signed-off-by: Sandeep Haemoon <redacted> --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 31 ++++++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index fd7a49a..ae6a19b 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c@@ -5337,6 +5337,22 @@ static int mtk_probe(struct platform_device *pdev) } } + /* we run 2 devices on the same DMA ring so we need a dummy device + * for NAPI to work. Allocate it before registering the netdevs so a + * concurrent ndo_open (e.g. netifd bringing the first netdev up) never + * observes eth->dummy_dev == NULL, which would make mtk_rx_alloc() -> + * __xdp_rxq_info_reg() warn ("Missing net_device from driver", + * net/core/xdp.c) and leave the interface down on boot. + */ + eth->dummy_dev = alloc_netdev_dummy(0); + if (!eth->dummy_dev) { + err = -ENOMEM; + dev_err(eth->dev, "failed to allocated dummy device\n"); + goto err_deinit_ppe; + } + netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx); + netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx); + for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue;
@@ -5351,17 +5367,6 @@ static int mtk_probe(struct platform_device *pdev) eth->netdev[i]->base_addr, eth->irq[MTK_FE_IRQ_SHARED]); } - /* we run 2 devices on the same DMA ring so we need a dummy device - * for NAPI to work - */ - eth->dummy_dev = alloc_netdev_dummy(0); - if (!eth->dummy_dev) { - err = -ENOMEM; - dev_err(eth->dev, "failed to allocated dummy device\n"); - goto err_unreg_netdev; - } - netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx); - netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx); platform_set_drvdata(pdev, eth); schedule_delayed_work(ð->reset.monitor_work,
@@ -5369,9 +5374,9 @@ static int mtk_probe(struct platform_device *pdev) return 0; -err_unreg_netdev: - mtk_unreg_dev(eth); err_deinit_ppe: + if (eth->dummy_dev) + free_netdev(eth->dummy_dev); mtk_ppe_deinit(eth); mtk_mdio_cleanup(eth); err_free_dev:
--
2.39.2