]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: eth: create phylink before device registration 23375/head
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Thu, 14 May 2026 20:04:47 +0000 (22:04 +0200)
committerRobert Marko <robimarko@gmail.com>
Sun, 17 May 2026 10:23:34 +0000 (12:23 +0200)
As soon as devm_register_netdev returns, the network
interface is "live" and the kernel can call rteth_open().
If the interface is brought up immediately (e.g., by a
userspace script), rteth_open will attempt to call
phylink_start(ctrl->phylink), which will crash the
system because ctrl->phylink has not been assigned yet.

Reorder probing sequence.

While we are here sort the variables by length.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23375
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.18/drivers/net/ethernet/rtl838x_eth.c

index 4649285eb3ed2fb9916fb4439820b4741c7790ef..2beaefb08df97c0f26a5d4b64207bbc24e3428e9 100644 (file)
@@ -1499,13 +1499,12 @@ static const struct ethtool_ops rteth_ethtool_ops = {
 
 static int rteth_probe(struct platform_device *pdev)
 {
-       struct net_device *dev;
        struct device_node *dn = pdev->dev.of_node;
-       struct rteth_ctrl *ctrl;
        const struct rteth_config *cfg;
-       phy_interface_t phy_mode;
-       struct phylink *phylink;
        u8 mac_addr[ETH_ALEN] = {0};
+       phy_interface_t phy_mode;
+       struct rteth_ctrl *ctrl;
+       struct net_device *dev;
        int err = 0;
 
        pr_info("Probing RTL838X eth device pdev: %x, dev: %x\n",
@@ -1613,10 +1612,6 @@ static int rteth_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dev);
 
-       err = devm_register_netdev(&pdev->dev, dev);
-       if (err)
-               return err;
-
        phy_mode = PHY_INTERFACE_MODE_NA;
        err = of_get_phy_mode(dn, &phy_mode);
        if (err < 0) {
@@ -1631,14 +1626,16 @@ static int rteth_probe(struct platform_device *pdev)
 
        __set_bit(PHY_INTERFACE_MODE_INTERNAL, ctrl->phylink_config.supported_interfaces);
 
-       phylink = phylink_create(&ctrl->phylink_config, pdev->dev.fwnode,
-                                phy_mode, &rteth_mac_ops);
+       ctrl->phylink = phylink_create(&ctrl->phylink_config, pdev->dev.fwnode,
+                                      phy_mode, &rteth_mac_ops);
+       if (IS_ERR(ctrl->phylink))
+               return PTR_ERR(ctrl->phylink);
 
-       if (IS_ERR(phylink))
-               return PTR_ERR(phylink);
-       ctrl->phylink = phylink;
+       err = devm_register_netdev(&pdev->dev, dev);
+       if (err)
+               phylink_destroy(ctrl->phylink);
 
-       return 0;
+       return err;
 }
 
 static void rteth_remove(struct platform_device *pdev)