drivers: net: Soft reset felix switch core
authorRadu Bulie <radu-andrei.bulie@nxp.com>
Sat, 27 Nov 2021 12:52:35 +0000 (14:52 +0200)
committerRamon Fried <rfried.dev@gmail.com>
Thu, 2 Dec 2021 06:34:01 +0000 (08:34 +0200)
It turns out that in custom designs if the system is reset
multiple times in conjunction with a slight increase in external
temperature, the felix  switch starts to behave in a strange way:
packets are no longer received on the ENECT interface connected
to the L2switch internal port (the TX side of internal port stops working
or the packets do not reach there. It is not very clear where
the packets remain blocked. None of the counters points to a disruption
in the L2switch)
The issue is not reproducible on NXP reference designs.

It was observed that by adding the switch core reset, the problem
goes aways, even if intensive testing in temperature chambers
is applied.

The current patch performs soft reset on the switch core to ensure proper
operation of the L2switch.

Signed-off-by: Radu Bulie <radu-andrei.bulie@nxp.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
drivers/net/mscc_eswitch/felix_switch.c

index 2df8dde..60b2e8f 100644 (file)
@@ -40,7 +40,9 @@
 #define FELIX_IS2                      0x060000
 #define FELIX_GMII(port)               (0x100000 + (port) * 0x10000)
 #define FELIX_QSYS                     0x200000
-
+#define FELIX_DEVCPU_GCB               0x070000
+#define FELIX_DEVCPU_GCB_SOFT_RST      (FELIX_DEVCPU_GCB + 0x00000004)
+#define SOFT_SWC_RST                   BIT(0)
 #define FELIX_SYS_SYSTEM               (FELIX_SYS + 0x00000E00)
 #define  FELIX_SYS_SYSTEM_EN           BIT(0)
 #define FELIX_SYS_RAM_CTRL             (FELIX_SYS + 0x00000F24)
@@ -237,6 +239,15 @@ static void felix_init(struct udevice *dev)
        void *base = priv->regs_base;
        int timeout = 100;
 
+       /* Switch core reset */
+       out_le32(base + FELIX_DEVCPU_GCB_SOFT_RST, SOFT_SWC_RST);
+       while (in_le32(base + FELIX_DEVCPU_GCB_SOFT_RST) & SOFT_SWC_RST &&
+              --timeout)
+               udelay(10);
+       if (in_le32(base + FELIX_DEVCPU_GCB_SOFT_RST) & SOFT_SWC_RST)
+               dev_err(dev, "Timeout waiting for switch core reset\n");
+       timeout = 100;
+
        /* Init core memories */
        out_le32(base + FELIX_SYS_RAM_CTRL, FELIX_SYS_RAM_CTRL_INIT);
        while (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT &&