From 3c0b97bfbe52fc9bc8d73ff730440d63a30c6766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Tue, 22 Feb 2022 16:55:24 +0100 Subject: [PATCH] TEST: net: dsa: realtek: rtl8366rb: provoke stray reg access Test for Linus to see if RTL8366RB also suffers from corrupted PHY register access. Set module parameter stray_access=1 to enable stray register read/write in critical sections of the PHY register read/write procedures. --- drivers/net/dsa/realtek/rtl8366rb.c | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c index fb6565e68401..d4bd826e7f39 100644 --- a/drivers/net/dsa/realtek/rtl8366rb.c +++ b/drivers/net/dsa/realtek/rtl8366rb.c @@ -1643,6 +1643,38 @@ static int rtl8366rb_enable_vlan4k(struct realtek_priv *priv, bool enable) enable ? RTL8366RB_SGCR_EN_VLAN_4KTB : 0); } +static bool stray_access = false; +module_param(stray_access, bool, 0644); +MODULE_PARM_DESC(stray_access, "do stray reg access during PHY read/write"); + +static void rtl8366rb_stray_reg_access(struct realtek_priv *priv) +{ + u32 val; + int ret; + + if (!stray_access) + return; + + /* Read some crap */ + ret = regmap_read(priv->map, RTL8366RB_CHIP_ID_REG, &val); + if (ret) + dev_warn(priv->dev, "XXX stray read CHIP_ID_REG failed: %d\n", + ret); + else + dev_dbg(priv->dev, "XXX stray read CHIP_ID_REG: %04x\n", val); + + /* Write some crap (same value as it should already have) */ + val = BIT(priv->cpu_port); + ret = regmap_write(priv->map, RTL8368RB_CPU_CTRL_REG, val); + if (ret) + dev_warn(priv->dev, "XXX stray write CPU_CTRL_REG failed: %d\n", + ret); + else + dev_dbg(priv->dev, "XXX stray write CPU_CTRL_REG: %04x\n", val); + + return; +} + static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum) { u32 val; @@ -1657,6 +1689,8 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum) if (ret) return ret; + rtl8366rb_stray_reg_access(priv); + reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum; ret = regmap_write(priv->map, reg, 0); @@ -1667,6 +1701,8 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum) return ret; } + rtl8366rb_stray_reg_access(priv); + ret = regmap_read(priv->map, RTL8366RB_PHY_ACCESS_DATA_REG, &val); if (ret) return ret; @@ -1691,6 +1727,8 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum, if (ret) return ret; + rtl8366rb_stray_reg_access(priv); + reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum; dev_dbg(priv->dev, "write PHY%d register 0x%04x @ %04x, val -> %04x\n", -- 2.35.1