Skip to content

Commit cbc17e7

Browse files
Wei Fangkuba-moo
authored andcommitted
net: fec: Set mac_managed_pm during probe
Setting mac_managed_pm during interface up is too late. In situations where the link is not brought up yet and the system suspends the regular PHY power management will run. Since the FEC ETHEREN control bit is cleared (automatically) on suspend the controller is off in resume. When the regular PHY power management resume path runs in this context it will write to the MII_DATA register but nothing will be transmitted on the MDIO bus. This can be observed by the following log: fec 5b040000.ethernet eth0: MDIO read timeout Microchip LAN87xx T1 5b040000.ethernet-1:04: PM: dpm_run_callback(): mdio_bus_phy_resume+0x0/0xc8 returns -110 Microchip LAN87xx T1 5b040000.ethernet-1:04: PM: failed to resume: error -110 The data written will however remain in the MII_DATA register. When the link later is set to administrative up it will trigger a call to fec_restart() which will restore the MII_SPEED register. This triggers the quirk explained in f166f89 ("net: ethernet: fec: Replace interrupt driven MDIO with polled IO") causing an extra MII_EVENT. This extra event desynchronizes all the MDIO register reads, causing them to complete too early. Leading all reads to read as 0 because fec_enet_mdio_wait() returns too early. When a Microchip LAN8700R PHY is connected to the FEC, the 0 reads causes the PHY to be initialized incorrectly and the PHY will not transmit any ethernet signal in this state. It cannot be brought out of this state without a power cycle of the PHY. Fixes: 557d5dc ("net: fec: use mac-managed PHY PM") Closes: https://lore.kernel.org/netdev/[email protected]/ Signed-off-by: Wei Fang <[email protected]> [jernberg: commit message] Signed-off-by: John Ernberg <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0a6380c commit cbc17e7

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

drivers/net/ethernet/freescale/fec_main.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,8 +2454,6 @@ static int fec_enet_mii_probe(struct net_device *ndev)
24542454
fep->link = 0;
24552455
fep->full_duplex = 0;
24562456

2457-
phy_dev->mac_managed_pm = true;
2458-
24592457
phy_attached_info(phy_dev);
24602458

24612459
return 0;
@@ -2467,10 +2465,12 @@ static int fec_enet_mii_init(struct platform_device *pdev)
24672465
struct net_device *ndev = platform_get_drvdata(pdev);
24682466
struct fec_enet_private *fep = netdev_priv(ndev);
24692467
bool suppress_preamble = false;
2468+
struct phy_device *phydev;
24702469
struct device_node *node;
24712470
int err = -ENXIO;
24722471
u32 mii_speed, holdtime;
24732472
u32 bus_freq;
2473+
int addr;
24742474

24752475
/*
24762476
* The i.MX28 dual fec interfaces are not equal.
@@ -2584,6 +2584,13 @@ static int fec_enet_mii_init(struct platform_device *pdev)
25842584
goto err_out_free_mdiobus;
25852585
of_node_put(node);
25862586

2587+
/* find all the PHY devices on the bus and set mac_managed_pm to true */
2588+
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
2589+
phydev = mdiobus_get_phy(fep->mii_bus, addr);
2590+
if (phydev)
2591+
phydev->mac_managed_pm = true;
2592+
}
2593+
25872594
mii_cnt++;
25882595

25892596
/* save fec0 mii_bus */

0 commit comments

Comments
 (0)