diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index c31695e..8e2a48c 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -1008,6 +1008,25 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave) return 1; } +static void cpsw_phy_addr_update(struct cpsw_priv *priv) +{ + struct cpsw_platform_data *data = &priv->data; + u16 alive = mdio_regs->alive & GENMASK(15, 0); + int active = data->active_slave; + int new_addr = ffs(alive) - 1; + + /* + * If there is only one phy alive and its address does not match + * that of active slave, then phy address can safely be updated. + */ + if (hweight16(alive) == 1 && + data->slave_data[active].phy_addr != new_addr) { + printf("Updated phy address for CPSW#%d, old: %d, new: %d\n", + active, data->slave_data[active].phy_addr, new_addr); + data->slave_data[active].phy_addr = new_addr; + } +} + int _cpsw_register(struct cpsw_priv *priv) { struct cpsw_slave *slave; @@ -1034,6 +1053,9 @@ int _cpsw_register(struct cpsw_priv *priv) } cpsw_mdio_init(priv->dev->name, data->mdio_base, data->mdio_div); + + cpsw_phy_addr_update(priv); + priv->bus = miiphy_get_dev_by_name(priv->dev->name); for_active_slave(slave, priv) cpsw_phy_init(priv, slave); @@ -1458,6 +1480,13 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) return 0; } +int cpsw_get_slave_phy_addr(struct udevice *dev, int slave) +{ + struct cpsw_priv *priv = dev_get_priv(dev); + struct cpsw_platform_data *data = &priv->data; + + return data->slave_data[slave].phy_addr; +} static const struct udevice_id cpsw_eth_ids[] = { { .compatible = "ti,cpsw" }, diff --git a/include/cpsw.h b/include/cpsw.h index f135e7b..9f8ce88 100644 --- a/include/cpsw.h +++ b/include/cpsw.h @@ -54,5 +54,6 @@ struct cpsw_platform_data { int cpsw_register(struct cpsw_platform_data *data); int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr); +int cpsw_get_slave_phy_addr(struct udevice *dev, int slave); #endif /* _CPSW_H_ */