From 469290648005e13b819a19353032ca53dda4378f Mon Sep 17 00:00:00 2001 From: Albert Jakiela Date: Wed, 6 Jul 2022 16:40:20 +0200 Subject: [PATCH] e6000sw: add readphy and writephy wrappers New functions take lock and give lock after operation. Removed locking and unlocking within other methods, to prevent from recursive locking on non recursive lock. Tested on EspressoBin. Reviewed by: mw Obtained from: Semihalf Differential Revision: https://reviews.freebsd.org/D35656 --- sys/dev/etherswitch/e6000sw/e6000sw.c | 55 ++++++++++++++++++--------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c index 7374fe2d74e..d096c31b349 100644 --- a/sys/dev/etherswitch/e6000sw/e6000sw.c +++ b/sys/dev/etherswitch/e6000sw/e6000sw.c @@ -112,6 +112,8 @@ static int e6000sw_read_xmdio(device_t, int, int, int); static int e6000sw_write_xmdio(device_t, int, int, int, int); static int e6000sw_readphy(device_t, int, int); static int e6000sw_writephy(device_t, int, int, int); +static int e6000sw_readphy_locked(device_t, int, int); +static int e6000sw_writephy_locked(device_t, int, int, int); static etherswitch_info_t* e6000sw_getinfo(device_t); static int e6000sw_getconf(device_t, etherswitch_conf_t *); static int e6000sw_setconf(device_t, etherswitch_conf_t *); @@ -159,8 +161,8 @@ static device_method_t e6000sw_methods[] = { DEVMETHOD(bus_add_child, device_add_child_ordered), /* mii interface */ - DEVMETHOD(miibus_readreg, e6000sw_readphy), - DEVMETHOD(miibus_writereg, e6000sw_writephy), + DEVMETHOD(miibus_readreg, e6000sw_readphy_locked), + DEVMETHOD(miibus_writereg, e6000sw_writephy_locked), /* etherswitch interface */ DEVMETHOD(etherswitch_getinfo, e6000sw_getinfo), @@ -654,29 +656,41 @@ e6000sw_write_xmdio(device_t dev, int phy, int devaddr, int devreg, int val) return (0); } +static int e6000sw_readphy(device_t dev, int phy, int reg) +{ + e6000sw_softc_t *sc; + int ret; + + sc = device_get_softc(dev); + E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); + + E6000SW_LOCK(sc); + ret = e6000sw_readphy_locked(dev, phy, reg); + E6000SW_UNLOCK(sc); + + return (ret); +} + /* * PHY registers are paged. Put page index in reg 22 (accessible from every * page), then access specific register. */ static int -e6000sw_readphy(device_t dev, int phy, int reg) +e6000sw_readphy_locked(device_t dev, int phy, int reg) { e6000sw_softc_t *sc; uint32_t val; sc = device_get_softc(dev); - E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); + E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) { device_printf(dev, "Wrong register address.\n"); return (EINVAL); } - E6000SW_LOCK(sc); - if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { device_printf(dev, "Timeout while waiting for switch\n"); - E6000SW_UNLOCK(sc); return (ETIMEDOUT); } @@ -685,35 +699,44 @@ e6000sw_readphy(device_t dev, int phy, int reg) ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK)); if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { device_printf(dev, "Timeout while waiting for switch\n"); - E6000SW_UNLOCK(sc); return (ETIMEDOUT); } val = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG); - E6000SW_UNLOCK(sc); - return (val & PHY_DATA_MASK); } +static int e6000sw_writephy(device_t dev, int phy, int reg, int data) +{ + e6000sw_softc_t *sc; + int ret; + + sc = device_get_softc(dev); + E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); + + E6000SW_LOCK(sc); + ret = e6000sw_writephy_locked(dev, phy, reg, data); + E6000SW_UNLOCK(sc); + + return (ret); +} + static int -e6000sw_writephy(device_t dev, int phy, int reg, int data) +e6000sw_writephy_locked(device_t dev, int phy, int reg, int data) { e6000sw_softc_t *sc; sc = device_get_softc(dev); - E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); + E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) { device_printf(dev, "Wrong register address.\n"); return (EINVAL); } - E6000SW_LOCK(sc); - if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { device_printf(dev, "Timeout while waiting for switch\n"); - E6000SW_UNLOCK(sc); return (ETIMEDOUT); } @@ -723,8 +746,6 @@ e6000sw_writephy(device_t dev, int phy, int reg, int data) SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) | ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK)); - E6000SW_UNLOCK(sc); - return (0); }