From 47a966444409b661624c8a70dce9f35b02fe9e28 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Mon, 5 Sep 2022 04:25:56 +0200 Subject: [PATCH] ramips: ethernet: ralink: do a reset of the ethernet & switch together 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 --- .../drivers/net/ethernet/ralink/esw_rt3050.c | 20 +++---------------- .../drivers/net/ethernet/ralink/esw_rt3050.h | 3 +++ .../drivers/net/ethernet/ralink/soc_rt3050.c | 17 ++++++++++++++++ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c index fe787fe92f..253122dbee 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c @@ -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) { diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h index c9650209cf..8b342eae43 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h @@ -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 diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c index 435f007477..e081c4b8b8 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c @@ -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, -- 2.30.2