ramips: ethernet: ralink: do a reset of the ethernet & switch together
authorAlexander Couzens <lynxis@fe80.eu>
Mon, 5 Sep 2022 02:25:56 +0000 (04:25 +0200)
committerAlexander Couzens <lynxis@fe80.eu>
Mon, 5 Sep 2022 02:29:52 +0000 (04:29 +0200)
The ethernet and switch needs to have the reset at the same time to
ensure a DMA panic doesn't happen.
The DMA panic seems to only happen on the rt503x devices as the SoCs
can have different versions on the ethernet, switch and DMA cores.

Do a partial revert of the reset api change and ignore the reset controller.

Tested-on: zyxel_nbg-419n
Fixes: 8569bc5e0d1b ("ramips: ethernet: ralink: rewrite esw_rt3050 to support link states")
Fixes: 60fadae62b64 ("ramips: ethernet: ralink: move reset of the esw into the esw instead of fe")
Fixes: 694561ae601a ("ramips: ethernet: ralink: use the reset controller api for esw & ephy")
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c
target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h
target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c

index fe787fe92f909c4666825efe2514be6c1cdc5f31..253122dbee74eab682ce7bf2335fafad4b9ff7d0 100644 (file)
@@ -261,18 +261,6 @@ static inline void esw_rmw_raw(struct rt305x_esw *esw, unsigned reg,
        __raw_writel(t | val, esw->base + reg);
 }
 
-static void esw_reset(struct rt305x_esw *esw)
-{
-       if (!esw->rst_esw)
-               return;
-
-       reset_control_assert(esw->rst_esw);
-       usleep_range(60, 120);
-       reset_control_deassert(esw->rst_esw);
-       /* the esw takes long to reset otherwise the board hang */
-       msleep(10);
-}
-
 static void esw_reset_ephy(struct rt305x_esw *esw)
 {
        if (!esw->rst_ephy)
@@ -460,14 +448,12 @@ static void esw_set_gsc(struct rt305x_esw *esw)
 
 static int esw_apply_config(struct switch_dev *dev);
 
-static void esw_hw_init(struct rt305x_esw *esw)
+void rt3050_esw_hw_init(struct rt305x_esw *esw)
 {
        int i;
        u8 port_disable = 0;
        u8 port_map = RT305X_ESW_PMAP_LLLLLL;
 
-       esw_reset(esw);
-
        /* vodoo from original driver */
        esw_w32(esw, 0xC8A07850, RT305X_ESW_REG_FCT0);
        esw_w32(esw, 0x00000000, RT305X_ESW_REG_SGC2);
@@ -860,7 +846,7 @@ static int esw_reset_switch(struct switch_dev *dev)
        esw->global_vlan_enable = 0;
        memset(esw->ports, 0, sizeof(esw->ports));
        memset(esw->vlans, 0, sizeof(esw->vlans));
-       esw_hw_init(esw);
+       rt3050_esw_hw_init(esw);
 
        return 0;
 }
@@ -1496,7 +1482,7 @@ int rt3050_esw_init(struct fe_priv *priv)
        priv->soc->swpriv = esw;
        esw->priv = priv;
 
-       esw_hw_init(esw);
+       rt3050_esw_hw_init(esw);
 
        rgmii = of_get_property(np, "ralink,rgmii", NULL);
        if (rgmii && be32_to_cpu(*rgmii) == 1) {
index c9650209cfe124e63a082f0d317b94329b69f957..8b342eae437601650cf52d7e5d145f0e4975cbcc 100644 (file)
@@ -27,6 +27,9 @@ static inline void mtk_switch_exit(void) { }
 
 #endif
 
+struct rt305x_esw;
+
 int rt3050_esw_init(struct fe_priv *priv);
 int rt3050_esw_has_carrier(struct fe_priv *priv);
+void rt3050_esw_hw_init(struct rt305x_esw *esw);
 #endif
index 435f007477883e83d22a8334290da6d2a413baf3..e081c4b8b875a6658d0166b5573c5800bb07f7f8 100644 (file)
@@ -20,6 +20,9 @@
 #include "esw_rt3050.h"
 #include "mdio_rt2880.h"
 
+#define RT305X_RESET_FE         BIT(21)
+#define RT305X_RESET_ESW        BIT(23)
+
 static const u16 rt5350_reg_table[FE_REG_COUNT] = {
        [FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
        [FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
@@ -113,8 +116,21 @@ static void rt5350_tx_dma(struct fe_tx_dma *txd)
        txd->txd4 = 0;
 }
 
+/* rt5350 require a combined reset as long the DMA engines crashs.
+ * it might be possible to stop the DMA engine to prevent it.
+ */
+static void rt305x_fe_reset(struct fe_priv *priv)
+{
+       fe_reset(RT305X_RESET_FE | RT305X_RESET_ESW);
+
+       /* check if switch is alive */
+       if (priv->soc->swpriv)
+               rt3050_esw_hw_init(priv->soc->swpriv);
+}
+
 static struct fe_soc_data rt3050_data = {
        .init_data = rt305x_init_data,
+       .reset_fe = rt305x_fe_reset,
        .fwd_config = rt3050_fwd_config,
        .switch_init = rt3050_esw_init,
        .pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
@@ -126,6 +142,7 @@ static struct fe_soc_data rt3050_data = {
 
 static struct fe_soc_data rt5350_data = {
        .init_data = rt5350_init_data,
+       .reset_fe = rt305x_fe_reset,
        .reg_table = rt5350_reg_table,
        .set_mac = rt5350_set_mac,
        .fwd_config = rt5350_fwd_config,