mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 04:09:55 -04:00
Merge branch 'net-dsa-mt7530-fix-remaining-swallowed-mdio-access-errors'
Daniel Golle says: ==================== net: dsa: mt7530: fix remaining swallowed MDIO access errors The original series, "net: dsa: mt7530: fix swallowed MDIO read errors", landed on net as its v1 [1] just before its v2 [2] was sent. This series started from the fixes in that original v2 which its v1 had not already carried: the two standalone patches that original v2 grew from the Sashiko AI review of its v1 (the mtk-lynxi read check and the regmap IRQ serialization), plus, split into patches of their own, the companion fixes original v2 had folded into the already-applied patches -- the unchecked bus->read() in core_rmw() and the unchecked PHY_IAC command writes in the MT7531 indirect PHY access functions. The Sashiko AI review of this series' own v1 [3] then flagged two more swallowed MDIO errors of the same kind, added here as patches of their own: the unchecked CORE_PLL_GROUP4 read-modify-write in mt7531_setup(), and the unchecked ATC/VTCR command-register writes in mt7530_fdb_cmd() and mt7530_vlan_cmd(). The remaining non-fix changes from the original v2, dropping a redundant read-back and improving the poll failure messages, will follow via net-next. [1] https://lore.kernel.org/netdev/cover.1785213071.git.daniel@makrotopia.org/ [2] https://lore.kernel.org/netdev/cover.1785368701.git.daniel@makrotopia.org/ [3] https://lore.kernel.org/netdev/cover.1785427248.git.daniel@makrotopia.org/ ==================== Link: https://patch.msgid.link/cover.1785811140.git.daniel@makrotopia.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -124,8 +124,12 @@ core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
goto err;
|
||||
|
||||
/* Read the content of the MMD's selected register */
|
||||
val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
ret = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MII_MMD_DATA);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
val = ret;
|
||||
|
||||
val &= ~mask;
|
||||
val |= set;
|
||||
/* Write the data into MMD's selected register */
|
||||
@@ -181,14 +185,18 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mt7530_mutex_lock(priv);
|
||||
|
||||
mt7530_mii_write(priv, reg, val);
|
||||
ret = mt7530_mii_write(priv, reg, val);
|
||||
|
||||
mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32
|
||||
@@ -245,7 +253,9 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
|
||||
|
||||
/* Set the command operating upon the MAC address entries */
|
||||
val = ATC_BUSY | ATC_MAT(0) | cmd;
|
||||
mt7530_write(priv, MT7530_ATC, val);
|
||||
ret = mt7530_write(priv, MT7530_ATC, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt7530_mutex_lock(priv);
|
||||
|
||||
@@ -561,7 +571,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
|
||||
|
||||
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
|
||||
MT7531_MDIO_DEV_ADDR(devad) | regnum;
|
||||
mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -572,7 +584,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
|
||||
|
||||
reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) |
|
||||
MT7531_MDIO_DEV_ADDR(devad);
|
||||
mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -606,7 +620,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
|
||||
|
||||
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
|
||||
MT7531_MDIO_DEV_ADDR(devad) | regnum;
|
||||
mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -617,7 +633,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
|
||||
|
||||
reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) |
|
||||
MT7531_MDIO_DEV_ADDR(devad) | data;
|
||||
mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -650,7 +668,9 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
|
||||
val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) |
|
||||
MT7531_MDIO_REG_ADDR(regnum);
|
||||
|
||||
mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
|
||||
ret = mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -685,7 +705,9 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
|
||||
reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) |
|
||||
MT7531_MDIO_REG_ADDR(regnum) | data;
|
||||
|
||||
mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, reg,
|
||||
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -1616,7 +1638,9 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
|
||||
int ret;
|
||||
|
||||
val = VTCR_BUSY | VTCR_FUNC(cmd) | vid;
|
||||
mt7530_write(priv, MT7530_VTCR, val);
|
||||
ret = mt7530_write(priv, MT7530_VTCR, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt7530_mutex_lock(priv);
|
||||
|
||||
@@ -2295,6 +2319,21 @@ static const struct regmap_irq mt7530_irqs[] = {
|
||||
REGMAP_IRQ_REG_LINE(31, 32), /* ACL */
|
||||
};
|
||||
|
||||
/* Serialize regmap-irq's mask sync like every other regmap user */
|
||||
static int mt7530_irq_mask_sync(int index, unsigned int mask_buf_def,
|
||||
unsigned int mask_buf, void *irq_drv_data)
|
||||
{
|
||||
struct mt7530_priv *priv = irq_drv_data;
|
||||
int ret;
|
||||
|
||||
mt7530_mutex_lock(priv);
|
||||
ret = regmap_update_bits(priv->regmap, MT7530_SYS_INT_EN,
|
||||
mask_buf_def, ~mask_buf);
|
||||
mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct regmap_irq_chip mt7530_regmap_irq_chip = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.status_base = MT7530_SYS_INT_STS,
|
||||
@@ -2304,12 +2343,14 @@ static const struct regmap_irq_chip mt7530_regmap_irq_chip = {
|
||||
.irqs = mt7530_irqs,
|
||||
.num_irqs = ARRAY_SIZE(mt7530_irqs),
|
||||
.num_regs = 1,
|
||||
.handle_mask_sync = mt7530_irq_mask_sync,
|
||||
};
|
||||
|
||||
static int
|
||||
mt7530_setup_irq(struct mt7530_priv *priv)
|
||||
{
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
struct regmap_irq_chip *chip;
|
||||
struct device *dev = priv->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
int irq, ret;
|
||||
@@ -2329,10 +2370,17 @@ mt7530_setup_irq(struct mt7530_priv *priv)
|
||||
if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
|
||||
mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
|
||||
|
||||
chip = devm_kmemdup(dev, &mt7530_regmap_irq_chip, sizeof(*chip),
|
||||
GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->irq_drv_data = priv;
|
||||
|
||||
ret = devm_regmap_add_irq_chip_fwnode(dev, dev_fwnode(dev),
|
||||
priv->regmap, irq,
|
||||
IRQF_ONESHOT,
|
||||
0, &mt7530_regmap_irq_chip,
|
||||
0, chip,
|
||||
&irq_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2765,14 +2813,20 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
* phy_[read,write]_mmd_indirect is called, we provide our own
|
||||
* mt7531_ind_mmd_phy_[read,write] to complete this function.
|
||||
*/
|
||||
val = mt7531_ind_c45_phy_read(priv,
|
||||
ret = mt7531_ind_c45_phy_read(priv,
|
||||
MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MDIO_MMD_VEND2, CORE_PLL_GROUP4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val = ret;
|
||||
val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
|
||||
val &= ~MT7531_PHY_PLL_OFF;
|
||||
mt7531_ind_c45_phy_write(priv,
|
||||
MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
|
||||
ret = mt7531_ind_c45_phy_write(priv,
|
||||
MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Disable EEE advertisement on the switch PHYs. */
|
||||
for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
|
||||
|
||||
@@ -113,8 +113,11 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
|
||||
unsigned int bm, adv;
|
||||
|
||||
/* Read the BMSR and LPA */
|
||||
regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
|
||||
regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
|
||||
if (regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm) ||
|
||||
regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv)) {
|
||||
state->link = false;
|
||||
return;
|
||||
}
|
||||
|
||||
phylink_mii_c22_pcs_decode_state(state, neg_mode,
|
||||
FIELD_GET(SGMII_BMSR, bm),
|
||||
|
||||
Reference in New Issue
Block a user