From: Josep Orga Date: Tue, 4 May 2021 11:36:32 +0000 (+0200) Subject: net: ethernet: fec_main: Add reset during fec_enet_open. X-Git-Tag: rel_imx_4.19.35_1.1.0-somdevices.2 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=d6f14c3485bc3f1c70676da53a41e45c5a2b5953;p=linux.git net: ethernet: fec_main: Add reset during fec_enet_open. ยท Added reset to have PHY working correctly. Signed-off-by: Josep Orga --- diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index b5ec76c2ca3f..5a07ba785d93 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -593,6 +593,7 @@ struct fec_enet_private { int phy_reset_gpio; bool active_high; bool phy_reset_in_suspend; + u32 phy_reset_duration; struct napi_struct napi; int csum_flags; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 1de1801dfab5..01d655d57666 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1925,6 +1925,23 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, return ret; } +static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + + if (!fep->phy_reset_gpio) + return; + + gpio_set_value_cansleep(fep->phy_reset_gpio, fep->active_high); + + if (fep->phy_reset_duration > 20) + msleep(fep->phy_reset_duration); + else + usleep_range(fep->phy_reset_duration * 1000, fep->phy_reset_duration * 1000 + 1000); + + gpio_set_value_cansleep(fep->phy_reset_gpio, !fep->active_high); +} + static int fec_enet_clk_enable(struct net_device *ndev, bool enable) { struct fec_enet_private *fep = netdev_priv(ndev); @@ -3101,7 +3118,7 @@ fec_enet_open(struct net_device *ndev) * phy_reset_after_clk_enable() before because the PHY wasn't probed. */ if (reset_again) - phy_reset_after_clk_enable(ndev->phydev); + fec_enet_phy_reset_after_clk_enable(ndev); if (fep->quirks & FEC_QUIRK_ERR006687) imx6q_cpuidle_fec_irqs_used(); @@ -3520,7 +3537,7 @@ static void fec_reset_phy_init(void) static int fec_reset_phy(struct platform_device *pdev) { int err; - int msec = 1, phy_post_delay = 0; + int phy_post_delay = 0; struct device_node *np = pdev->dev.of_node; struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); @@ -3528,10 +3545,10 @@ static int fec_reset_phy(struct platform_device *pdev) if (!np) return 0; - err = of_property_read_u32(np, "phy-reset-duration", &msec); + err = of_property_read_u32(np, "phy-reset-duration", &fep->phy_reset_duration); /* A sane reset duration should not be longer than 1s */ - if (!err && msec > 1000) - msec = 1; + if (err || fep->phy_reset_duration > 1000) + fep->phy_reset_duration = 1; fep->phy_reset_gpio = of_get_named_gpio(np, "phy-reset-gpios", 0); if (fep->phy_reset_gpio == -EPROBE_DEFER) @@ -3559,10 +3576,10 @@ static int fec_reset_phy(struct platform_device *pdev) fep->phy_reset_in_suspend = of_property_read_bool(np, "phy-reset-in-suspend"); - if (msec > 20) - msleep(msec); + if (fep->phy_reset_duration > 20) + msleep(fep->phy_reset_duration); else - usleep_range(msec * 1000, msec * 1000 + 1000); + usleep_range(fep->phy_reset_duration * 1000, fep->phy_reset_duration * 1000 + 1000); gpio_set_value_cansleep(fep->phy_reset_gpio, !fep->active_high);