aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/fec_main.c
diff options
context:
space:
mode:
authorDavid S. Miller <[email protected]>2017-12-13 11:22:54 -0500
committerDavid S. Miller <[email protected]>2017-12-13 11:22:54 -0500
commitf93ea3bf151daea735a3dd6bb8c3d386ee2ebac3 (patch)
tree251b3f0f1e9d6b490d0d3bac90e94dc78f645a0e /drivers/net/ethernet/freescale/fec_main.c
parent9cca5d2f1be941c2fbe0ac192a139fe1b93d2c3c (diff)
parent1b0a83ac04e383e3bed21332962b90710fcf2828 (diff)
Merge branch 'fec-fix-refclk-enable-for-SMSC-LAN8710-20'
Richard Leitner says: ==================== net: fec: fix refclk enable for SMSC LAN8710/20 This patch series fixes the use of the SMSC LAN8710/20 with a Freescale ETH when the refclk is generated by the FSL. This patchset depends on the "phylib: Add device reset GPIO support" patch submitted by Geert Uytterhoeven/Sergei Shtylyov, which was merged to net-next as commit bafbdd527d56 ("phylib: Add device reset GPIO support"). Changes v5: - fix reset delay calculation (max_t instead of min_t) Changes v4: - simplify dts parsing - simplify reset delay evaluation and execution - fec: ensure to only reset once during fec_enet_open() - remove dependency notes from commit message - add reviews and acks Changes v3: - use phylib to hard-reset the PHY - implement reset delays in phylib - add new phylib API & flag (PHY_RST_AFTER_CLK_EN) to determine if a PHY is affected Changes v2: - simplify and fix fec_reset_phy function to support multiple calls - include: linux: phy: harmonize phy_id{,_mask} type - reset the phy instead of not turning the clock on and off (which would have caused a power consumption regression) ==================== Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 610573855213..2d1b06579c1a 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1862,6 +1862,8 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
ret = clk_prepare_enable(fep->clk_ref);
if (ret)
goto failed_clk_ref;
+
+ phy_reset_after_clk_enable(ndev->phydev);
} else {
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_enet_out);
@@ -2834,6 +2836,7 @@ fec_enet_open(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
int ret;
+ bool reset_again;
ret = pm_runtime_get_sync(&fep->pdev->dev);
if (ret < 0)
@@ -2844,6 +2847,17 @@ fec_enet_open(struct net_device *ndev)
if (ret)
goto clk_enable;
+ /* During the first fec_enet_open call the PHY isn't probed at this
+ * point. Therefore the phy_reset_after_clk_enable() call within
+ * fec_enet_clk_enable() fails. As we need this reset in order to be
+ * sure the PHY is working correctly we check if we need to reset again
+ * later when the PHY is probed
+ */
+ if (ndev->phydev && ndev->phydev->drv)
+ reset_again = false;
+ else
+ reset_again = true;
+
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
@@ -2860,6 +2874,12 @@ fec_enet_open(struct net_device *ndev)
if (ret)
goto err_enet_mii_probe;
+ /* Call phy_reset_after_clk_enable() again if it failed during
+ * phy_reset_after_clk_enable() before because the PHY wasn't probed.
+ */
+ if (reset_again)
+ phy_reset_after_clk_enable(ndev->phydev);
+
if (fep->quirks & FEC_QUIRK_ERR006687)
imx6q_cpuidle_fec_irqs_used();