Commit 22c5e0bc authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-fec-fix-to-suspend-resume-with-mac_managed_pm'

John Ernberg says:

====================
net: fec: Fix to suspend / resume with mac_managed_pm

Since the introduction of mac_managed_pm in the FEC driver there were some
discrepancies regarding power management of the PHY.

This failed on our board that has a permanently powered Microchip LAN8700R
attached to the FEC. Although the root cause of the failure can be traced
back to f166f890 ("net: ethernet: fec: Replace interrupt driven MDIO
with polled IO") and probably even before that, we only started noticing
the problem going from 5.10 to 6.1.

Since 557d5dc8 ("net: fec: use mac-managed PHY PM") is actually a fix
to most of the power management sequencing problems that came with power
managing the MDIO bus which for the FEC meant adding a race with FEC
resume (and phy_start() if netif was running) and PHY resume.

That it worked before for us was probably just luck...

Thanks to Wei's response to my report at [1] I was able to pick up his
patch and start honing in on the remaining missing details.

[1]: https://lore.kernel.org/netdev/1f45bdbe-eab1-4e59-8f24-add177590d27@actia.se/

v3: https://lore.kernel.org/netdev/20240306133734.4144808-1-john.ernberg@actia.se/
v2: https://lore.kernel.org/netdev/20240229105256.2903095-1-john.ernberg@actia.se/
v1: https://lore.kernel.org/netdev/20240212105010.2258421-1-john.ernberg@actia.se/
====================

Link: https://lore.kernel.org/r/20240328155909.59613-1-john.ernberg@actia.se


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0a6380cb cbc17e78
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -2454,8 +2454,6 @@ static int fec_enet_mii_probe(struct net_device *ndev)
	fep->link = 0;
	fep->full_duplex = 0;

	phy_dev->mac_managed_pm = true;

	phy_attached_info(phy_dev);

	return 0;
@@ -2467,10 +2465,12 @@ static int fec_enet_mii_init(struct platform_device *pdev)
	struct net_device *ndev = platform_get_drvdata(pdev);
	struct fec_enet_private *fep = netdev_priv(ndev);
	bool suppress_preamble = false;
	struct phy_device *phydev;
	struct device_node *node;
	int err = -ENXIO;
	u32 mii_speed, holdtime;
	u32 bus_freq;
	int addr;

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

	/* find all the PHY devices on the bus and set mac_managed_pm to true */
	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
		phydev = mdiobus_get_phy(fep->mii_bus, addr);
		if (phydev)
			phydev->mac_managed_pm = true;
	}

	mii_cnt++;

	/* save fec0 mii_bus */