[PATCH v2] net: phy: fix duplicate eth_phy binding
Marek Vasut
marek.vasut at mailbox.org
Tue Apr 21 00:59:11 CEST 2026
On 4/16/26 9:12 AM, Vinay Tilak, Pranav wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
>
> Hi Marek,
>
>> -----Original Message-----
>> From: Marek Vasut <marek.vasut at mailbox.org>
>> Sent: Wednesday, April 8, 2026 10:02 PM
>> To: Vinay Tilak, Pranav <Pranav.VinayTilak at amd.com>; u-boot at lists.denx.de;
>> Simek, Michal <michal.simek at amd.com>
>> Cc: git (AMD-Xilinx) <git at amd.com>; Begari, Padmarao
>> <Padmarao.Begari at amd.com>; Jerome Forissier
>> <jerome.forissier at arm.com>; Tom Rini <trini at konsulko.com>; Peng Fan
>> <peng.fan at nxp.com>; Lucien.Jheng <lucienzx159 at gmail.com>; Yao Zi
>> <me at ziyao.cc>; SkyLake.Huang <skylake.huang at mediatek.com>; Siddharth
>> Vadapalli <s-vadapalli at ti.com>; Marek Vasut
>> <marek.vasut+renesas at mailbox.org>; Ramon Fried <rfried.dev at gmail.com>
>> Subject: Re: [PATCH v2] net: phy: fix duplicate eth_phy binding
>>
>> On 4/8/26 10:58 AM, Pranav Tilak wrote:
>>> When both CONFIG_PHY_ETHERNET_ID and CONFIG_DM_ETH_PHY are
>> enabled,
>>> eth_phy_binds_nodes() called from eth_post_bind() already binds the
>>> ethernet PHY node to eth_phy_generic_drv. However,
>>> phy_connect_phy_id() called via zynq_phy_init() -> phy_connect()
>>> cannot attach to the already bound PHY device and creates a second
>>> instance, resulting in duplicate entries in the dm tree:
>>>
>>> Fix this by guarding the phy_connect_phy_id() call in phy_connect()
>>> with uclass_get_device_by_phandle() to skip re-binding if the PHY node
>>> is already registered in UCLASS_ETH_PHY.
>>>
>>> Fixes: 68a4d1506109 ("net: phy: Bind ETH_PHY uclass driver to each new
>>> PHY")
>>> Signed-off-by: Pranav Tilak <pranav.vinaytilak at amd.com>
>>> ---
>>> Changes in v2:
>>> - Move duplicate binding check to caller phy_connect()
>>> - Update commit description
>>>
>>> drivers/net/phy/phy.c | 9 +++++++--
>>> 1 file changed, 7 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index
>>> d7e0c4fe02d..cfca8328f1c 100644
>>> --- a/drivers/net/phy/phy.c
>>> +++ b/drivers/net/phy/phy.c
>>> @@ -938,8 +938,13 @@ struct phy_device *phy_connect(struct mii_dev
>> *bus, int addr,
>>> #endif
>>>
>>> #ifdef CONFIG_PHY_ETHERNET_ID
>>> - if (!phydev)
>>> - phydev = phy_connect_phy_id(bus, dev, addr);
>>> + if (!phydev) {
>>> + struct udevice *phy_dev;
>>> +
>>> + if (uclass_get_device_by_phandle(UCLASS_ETH_PHY, dev,
>>> + "phy-handle", &phy_dev))
>>> + phydev = phy_connect_phy_id(bus, dev, addr);
>> Shouldn't this binding check be closer to the beginning of phy_connect() ?
>> Basically check whether the PHY driver is already bound at the beginning, and
>> if so, you are done. I don't think that test is specific to
>> CONFIG_PHY_ETHERNET_ID, is it ?
>
> The check is placed inside phy_connect_phy_id() because that is the only code path that calls device_bind_driver_to_node() on the PHY node, which creates the duplicate.
The device_bind_driver_to_node() in phy_connect_phy_id() is called only
under very specific conditions -- if IS_ENABLED(CONFIG_DM_ETH_PHY) and
phy-handle property exists and points to a valid node. The DM_ETH_PHY
test is not covered here.
But that is besides the point. I think phy_connect() should figure out
whether any PHY is already connected, and if it is, simply exit early.
This sounds to me like a more generic solution.
> The other paths (phy_connect_fixed, NCSI, phy_connect_gmii2rgmii) do not bind the PHY node and are not affected.
I worry this is only a matter of time, hence it would be good to have a
generic solution which covers all the PHY options.
More information about the U-Boot
mailing list