net: ethernet: fec_main: Add reset during fec_enet_open. rel_imx_4.19.35_1.1.0-somdevices.2
authorJosep Orga <jorga@somdevices.com>
Tue, 4 May 2021 11:36:32 +0000 (13:36 +0200)
committerJosep Orga <jorga@somdevices.com>
Tue, 4 May 2021 11:36:32 +0000 (13:36 +0200)
ยท Added reset to have PHY working correctly.

Signed-off-by: Josep Orga <jorga@somdevices.com>
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c

index b5ec76c..5a07ba7 100644 (file)
@@ -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;
index 1de1801..01d655d 100644 (file)
@@ -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);