sun8i_emac_eth_probe() currently ignores errors from registering its MDIO bus, and sun8i_phy_init() ignores errors returned while configuring the attached PHY. A failed PHY configuration can therefore leave the Ethernet device registered even though it cannot operate.
Return both errors to the driver model. Retain the newly registered bus directly instead of looking it up again by name. Free an unregistered bus if registration fails, and release the PHY and unregister the bus if PHY setup fails. This lets a later probe retry without a stale MDIO bus referencing the private storage released after the failed probe. Signed-off-by: James Hilliard <[email protected]> --- drivers/net/sun8i_emac.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 41c52f56d7a..29562e14e16 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -353,9 +353,8 @@ static int sun8i_phy_init(struct emac_eth_dev *priv, void *dev) return -ENODEV; priv->phydev = phydev; - phy_config(priv->phydev); - return 0; + return phy_config(priv->phydev); } #define cache_clean_descriptor(desc) \ @@ -635,9 +634,11 @@ static int sun8i_mdio_reset(struct mii_dev *bus) return 0; } -static int sun8i_mdio_init(const char *name, struct udevice *priv) +static int sun8i_mdio_init(struct udevice *dev) { + struct emac_eth_dev *priv = dev_get_priv(dev); struct mii_dev *bus = mdio_alloc(); + int ret; if (!bus) { debug("Failed to allocate MDIO bus\n"); @@ -646,11 +647,18 @@ static int sun8i_mdio_init(const char *name, struct udevice *priv) bus->read = sun8i_mdio_read; bus->write = sun8i_mdio_write; - snprintf(bus->name, sizeof(bus->name), name); - bus->priv = (void *)priv; + snprintf(bus->name, sizeof(bus->name), "%s", dev->name); + bus->priv = dev; bus->reset = sun8i_mdio_reset; - return mdio_register(bus); + ret = mdio_register(bus); + if (ret) { + mdio_free(bus); + return ret; + } + priv->bus = bus; + + return 0; } static int sun8i_eth_free_pkt(struct udevice *dev, uchar *packet, @@ -707,10 +715,20 @@ static int sun8i_emac_eth_probe(struct udevice *dev) if (priv->phy_reg) regulator_set_enable(priv->phy_reg, true); - sun8i_mdio_init(dev->name, dev); - priv->bus = miiphy_get_dev_by_name(dev->name); + ret = sun8i_mdio_init(dev); + if (ret) + return ret; - return sun8i_phy_init(priv, dev); + ret = sun8i_phy_init(priv, dev); + if (ret) { + free(priv->phydev); + priv->phydev = NULL; + mdio_unregister(priv->bus); + mdio_free(priv->bus); + priv->bus = NULL; + } + + return ret; } static const struct eth_ops sun8i_emac_eth_ops = { -- 2.53.0
