Message ID | 20210514210015.18142-5-ansuelsmth@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | ba5707ec58cfb6853dff41c2aae72deb6a03d389 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Multiple improvement to qca8k stability | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | fail | Series longer than 15 patches |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | success | CCed 7 of 7 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 79 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
On Fri, May 14, 2021 at 10:59:54PM +0200, Ansuel Smith wrote: > With a remote possibility, the set_page function can fail. Since this is > a critical part of the write/read qca8k regs, propagate the error and > terminate any read/write operation. > > Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> > Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 3c882d325fdf..c9830286fd6d 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -127,16 +127,23 @@ qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) "failed to write qca8k 32bit register\n"); } -static void +static int qca8k_set_page(struct mii_bus *bus, u16 page) { + int ret; + if (page == qca8k_current_page) - return; + return 0; - if (bus->write(bus, 0x18, 0, page) < 0) + ret = bus->write(bus, 0x18, 0, page); + if (ret < 0) { dev_err_ratelimited(&bus->dev, "failed to set qca8k page\n"); + return ret; + } + qca8k_current_page = page; + return 0; } static u32 @@ -150,11 +157,14 @@ qca8k_read(struct qca8k_priv *priv, u32 reg) mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - qca8k_set_page(bus, page); + val = qca8k_set_page(bus, page); + if (val < 0) + goto exit; + val = qca8k_mii_read32(bus, 0x10 | r2, r1); +exit: mutex_unlock(&bus->mdio_lock); - return val; } @@ -163,14 +173,19 @@ qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) { struct mii_bus *bus = priv->bus; u16 r1, r2, page; + int ret; qca8k_split_addr(reg, &r1, &r2, &page); mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - qca8k_set_page(bus, page); + ret = qca8k_set_page(bus, page); + if (ret < 0) + goto exit; + qca8k_mii_write32(bus, 0x10 | r2, r1, val); +exit: mutex_unlock(&bus->mdio_lock); } @@ -185,12 +200,16 @@ qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 val) mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - qca8k_set_page(bus, page); + ret = qca8k_set_page(bus, page); + if (ret < 0) + goto exit; + ret = qca8k_mii_read32(bus, 0x10 | r2, r1); ret &= ~mask; ret |= val; qca8k_mii_write32(bus, 0x10 | r2, r1, ret); +exit: mutex_unlock(&bus->mdio_lock); return ret;