From 81919eb7e495d364fa8ddee463c8a4f66b629396 Mon Sep 17 00:00:00 2001 From: Max Plekh Date: Sun, 27 Sep 2026 18:18:36 +0300 Subject: [PATCH] bmips: enetsw: fix probe after EPROBE_DEFER Since the MAC lookup started returning -EPROBE_DEFER, a probe that defers while its nvmem provider (e.g. a mac-base cell in the CFE partition) isn't ready yet leaves the power domain devices attached by genpd_dev_pm_attach_by_id() behind. The next probe then fails to re-create them: sysfs: cannot create duplicate filename '/devices/genpd:0:1000d800.ethernet' bcm6368-enetsw 1000d800.ethernet: error getting pm 0 bcm6368-enetsw 1000d800.ethernet: probe with driver bcm6368-enetsw failed with error -22 leaving the board without ethernet and the DSA switch deferred forever. Look up the MAC first, before anything that isn't device-managed has been set up, so a deferred probe can simply be retried. Seen on a BCM6328 (BeWAN A2100N) with kernel 6.18. Fixes: ed545519eeff ("bmips: enet: handle EPROBE_DEFER for the MAC address") Signed-off-by: Max Plekh Link: https://github.com/openwrt/openwrt/pull/25454 Signed-off-by: Hauke Mehrtens --- .../net/ethernet/broadcom/bcm6368-enetsw.c | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c b/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c index 0c443c845f4..225bed9b038 100644 --- a/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c +++ b/target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c @@ -938,6 +938,24 @@ static int bcm6368_enetsw_probe(struct platform_device *pdev) priv->pdev = pdev; priv->net_dev = ndev; + /* + * Look up the MAC first: an nvmem provider that isn't ready yet makes + * this return -EPROBE_DEFER, which must happen before the power + * domains are attached below, as those aren't released on defer and + * re-attaching them on the next probe fails with -EEXIST. + */ + ret = of_get_mac_address(node, dev_addr); + if (ret == -EPROBE_DEFER) + return ret; + + if (is_valid_ether_addr(dev_addr)) { + dev_addr_set(ndev, dev_addr); + dev_info(dev, "mtd mac %pM\n", dev_addr); + } else { + eth_hw_addr_random(ndev); + dev_info(dev, "random mac\n"); + } + priv->num_pms = of_count_phandle_with_args(node, "power-domains", "#power-domain-cells"); if (priv->num_pms > 1) { @@ -1010,18 +1028,6 @@ static int bcm6368_enetsw_probe(struct platform_device *pdev) priv->tx_ring_size = ENETSW_DEF_TX_DESC; priv->copybreak = ENETSW_DEF_CPY_BREAK; - ret = of_get_mac_address(node, dev_addr); - if (ret == -EPROBE_DEFER) - return ret; - - if (is_valid_ether_addr(dev_addr)) { - dev_addr_set(ndev, dev_addr); - dev_info(dev, "mtd mac %pM\n", dev_addr); - } else { - eth_hw_addr_random(ndev); - dev_info(dev, "random mac\n"); - } - priv->rx_buf_size = ALIGN(ENETSW_MAX_FRAME, ENETSW_DMA_MAXBURST * 4);