]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:32 +0000 (11:13 +0200)
[ Upstream commit 67800d296191d0a9bde0a7776f99ca1ddfa0fc26 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/freescale/fec_main.c

index c5d5fa8d7dfddca88314ce782d546cf2bafb2c0a..17e9bddb9ddd58f6d49840ed06a5a73c70ee2cc2 100644 (file)
@@ -1098,6 +1098,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
@@ -1114,17 +1137,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,
@@ -1378,22 +1391,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);