phydev->attached_dev = dev;
        dev->phydev = phydev;
+
+       /* Some Ethernet drivers try to connect to a PHY device before
+        * calling register_netdevice() -> netdev_register_kobject() and
+        * does the dev->dev.kobj initialization. Here we only check for
+        * success which indicates that the network device kobject is
+        * ready. Once we do that we still need to keep track of whether
+        * links were successfully set up or not for phy_detach() to
+        * remove them accordingly.
+        */
+       phydev->sysfs_links = false;
+
        err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
                                "attached_dev");
-       if (err)
-               goto error;
+       if (!err) {
+               err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
+                                       "phydev");
+               if (err)
+                       goto error;
 
-       err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
-                               "phydev");
-       if (err)
-               goto error;
+               phydev->sysfs_links = true;
+       }
 
        phydev->dev_flags = flags;
 
        struct mii_bus *bus;
        int i;
 
-       sysfs_remove_link(&dev->dev.kobj, "phydev");
-       sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev");
+       if (phydev->sysfs_links) {
+               sysfs_remove_link(&dev->dev.kobj, "phydev");
+               sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev");
+       }
        phydev->attached_dev->phydev = NULL;
        phydev->attached_dev = NULL;
        phy_suspend(phydev);
 
  * is_pseudo_fixed_link: Set to true if this phy is an Ethernet switch, etc.
  * has_fixups: Set to true if this phy has fixups/quirks.
  * suspended: Set to true if this phy has been suspended successfully.
+ * sysfs_links: Internal boolean tracking sysfs symbolic links setup/removal.
  * state: state of the PHY for management purposes
  * dev_flags: Device-specific flags used by the PHY driver.
  * link_timeout: The number of timer firings to wait before the
        bool is_pseudo_fixed_link;
        bool has_fixups;
        bool suspended;
+       bool sysfs_links;
 
        enum phy_state state;