]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: fec: Refactor MAC reset to function
authorCsókás, Bence <csokas.bence@prolan.hu>
Fri, 7 Feb 2025 12:12:55 +0000 (13:12 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 11 Feb 2025 09:55:25 +0000 (10:55 +0100)
The core is reset both in `fec_restart()` (called on link-up) and
`fec_stop()` (going to sleep, driver remove etc.). These two functions
had their separate implementations, which was at first only a register
write and a `udelay()` (and the accompanying block comment). However,
since then we got soft-reset (MAC disable) and Wake-on-LAN support, which
meant that these implementations diverged, often causing bugs.

For instance, as of now, `fec_stop()` does not check for
`FEC_QUIRK_NO_HARD_RESET`, meaning the MII/RMII mode is cleared on eg.
a PM power-down event; and `fec_restart()` missed the refactor renaming
the "magic" constant `1` to `FEC_ECR_RESET`.

To harmonize current implementations, and eliminate this source of
potential future bugs, refactor implementation to a common function.

Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Csókás, Bence <csokas.bence@prolan.hu>
Link: https://patch.msgid.link/20250207121255.161146-2-csokas.bence@prolan.hu
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/freescale/fec_main.c

index f7c4ce8e9a265597f7e50a0431296c51d76c3abf..a86cfebedaa8b5b4bccb65e50cfeeeb3b8346399 100644 (file)
@@ -1093,6 +1093,29 @@ static void fec_enet_enable_ring(struct net_device *ndev)
        }
 }
 
+/* Whack a reset.  We should wait for this.
+ * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
+ * instead of reset MAC itself.
+ */
+static void fec_ctrl_reset(struct fec_enet_private *fep, bool allow_wol)
+{
+       u32 val;
+
+       if (!allow_wol || !(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
+               if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES ||
+                   ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) {
+                       writel(0, fep->hwp + FEC_ECNTRL);
+               } else {
+                       writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL);
+                       udelay(10);
+               }
+       } else {
+               val = readl(fep->hwp + FEC_ECNTRL);
+               val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
+               writel(val, fep->hwp + FEC_ECNTRL);
+       }
+}
+
 /*
  * This function is called to start or restart the FEC during a link
  * change, transmit timeout, or to reconfigure the FEC.  The network
@@ -1109,17 +1132,7 @@ fec_restart(struct net_device *ndev)
        if (fep->bufdesc_ex)
                fec_ptp_save_state(fep);
 
-       /* Whack a reset.  We should wait for this.
-        * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
-        * instead of reset MAC itself.
-        */
-       if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES ||
-           ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) {
-               writel(0, fep->hwp + FEC_ECNTRL);
-       } else {
-               writel(1, fep->hwp + FEC_ECNTRL);
-               udelay(10);
-       }
+       fec_ctrl_reset(fep, false);
 
        /*
         * enet-mac reset will reset mac address registers too,
@@ -1373,22 +1386,7 @@ fec_stop(struct net_device *ndev)
        if (fep->bufdesc_ex)
                fec_ptp_save_state(fep);
 
-       /* Whack a reset.  We should wait for this.
-        * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
-        * instead of reset MAC itself.
-        */
-       if (!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
-               if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) {
-                       writel(0, fep->hwp + FEC_ECNTRL);
-               } else {
-                       writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL);
-                       udelay(10);
-               }
-       } else {
-               val = readl(fep->hwp + FEC_ECNTRL);
-               val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
-               writel(val, fep->hwp + FEC_ECNTRL);
-       }
+       fec_ctrl_reset(fep, true);
        writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
        writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);