6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Eggers ceggers@arri.de
[ Upstream commit 0005b2dc43f96b93fc5b0850d7ca3f7aeac9129c ]
The 'phy' parameter supplied to lan9303_phy_read/_write was sometimes a DSA port number and sometimes a PHY address. This isn't a problem as long as they are equal. But if the external phy_addr_sel_strap pin is wired to 'high', the PHY addresses change from 0-1-2 to 1-2-3 (CPU, slave0, slave1). In this case, lan9303_phy_read/_write must translate between DSA port numbers and the corresponding PHY address.
Fixes: a1292595e006 ("net: dsa: add new DSA switch driver for the SMSC-LAN9303") Signed-off-by: Christian Eggers ceggers@arri.de Reviewed-by: Michal Kubiak michal.kubiak@intel.com Reviewed-by: Florian Fainelli florian.fainelli@broadcom.com Reviewed-by: Vladimir Oltean olteanv@gmail.com Link: https://patch.msgid.link/20240703145718.19951-1-ceggers@arri.de Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/lan9303-core.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c index ee67adeb2cdbf..24ef219e6f565 100644 --- a/drivers/net/dsa/lan9303-core.c +++ b/drivers/net/dsa/lan9303-core.c @@ -1048,31 +1048,31 @@ static int lan9303_get_sset_count(struct dsa_switch *ds, int port, int sset) return ARRAY_SIZE(lan9303_mib); }
-static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum) +static int lan9303_phy_read(struct dsa_switch *ds, int port, int regnum) { struct lan9303 *chip = ds->priv; int phy_base = chip->phy_addr_base;
- if (phy == phy_base) + if (port == 0) return lan9303_virt_phy_reg_read(chip, regnum); - if (phy > phy_base + 2) + if (port > 2) return -ENODEV;
- return chip->ops->phy_read(chip, phy, regnum); + return chip->ops->phy_read(chip, phy_base + port, regnum); }
-static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum, +static int lan9303_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) { struct lan9303 *chip = ds->priv; int phy_base = chip->phy_addr_base;
- if (phy == phy_base) + if (port == 0) return lan9303_virt_phy_reg_write(chip, regnum, val); - if (phy > phy_base + 2) + if (port > 2) return -ENODEV;
- return chip->ops->phy_write(chip, phy, regnum, val); + return chip->ops->phy_write(chip, phy_base + port, regnum, val); }
static int lan9303_port_enable(struct dsa_switch *ds, int port, @@ -1100,7 +1100,7 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port) vlan_vid_del(dsa_port_to_master(dp), htons(ETH_P_8021Q), port);
lan9303_disable_processing_port(chip, port); - lan9303_phy_write(ds, chip->phy_addr_base + port, MII_BMCR, BMCR_PDOWN); + lan9303_phy_write(ds, port, MII_BMCR, BMCR_PDOWN); }
static int lan9303_port_bridge_join(struct dsa_switch *ds, int port, @@ -1355,8 +1355,6 @@ static const struct dsa_switch_ops lan9303_switch_ops = {
static int lan9303_register_switch(struct lan9303 *chip) { - int base; - chip->ds = devm_kzalloc(chip->dev, sizeof(*chip->ds), GFP_KERNEL); if (!chip->ds) return -ENOMEM; @@ -1365,8 +1363,7 @@ static int lan9303_register_switch(struct lan9303 *chip) chip->ds->num_ports = LAN9303_NUM_PORTS; chip->ds->priv = chip; chip->ds->ops = &lan9303_switch_ops; - base = chip->phy_addr_base; - chip->ds->phys_mii_mask = GENMASK(LAN9303_NUM_PORTS - 1 + base, base); + chip->ds->phys_mii_mask = GENMASK(LAN9303_NUM_PORTS - 1, 0);
return dsa_register_switch(chip->ds); }