From cceadc831e728fde74c21813519962c648f5ca7c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Sun, 19 Apr 2020 10:27:57 +0200 Subject: net: phy: mscc: use mdiobus_get_phy() Don't use internal knowledge of the mdio bus core, instead use mdiobus_get_phy() which does the same thing. Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/mscc/mscc_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net/phy/mscc/mscc_main.c') diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index acddef79f4e8..5391acdece05 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -1292,7 +1292,7 @@ out: */ static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed) { - struct mdio_device **map = phydev->mdio.bus->mdio_map; + struct mii_bus *bus = phydev->mdio.bus; struct vsc8531_private *vsc8531; struct phy_device *phy; int i, addr; @@ -1306,11 +1306,10 @@ static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed) else addr = vsc8531->base_addr + i; - if (!map[addr]) + phy = mdiobus_get_phy(bus, addr); + if (!phy) continue; - phy = container_of(map[addr], struct phy_device, mdio); - if ((phy->phy_id & phydev->drv->phy_id_mask) != (phydev->drv->phy_id & phydev->drv->phy_id_mask)) continue; -- cgit v1.2.1 From deb04e9c0ff2b42cadf198c3204b13025c9bd72e Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 6 May 2020 16:53:15 +0200 Subject: net: phy: mscc: use phy_package_shared Use the new phy_package_shared common storage to ease the package initialization and to access the global registers. Signed-off-by: Michael Walle Tested-by: Vladimir Oltean Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/mscc/mscc_main.c | 101 +++++++++++++-------------------------- 1 file changed, 32 insertions(+), 69 deletions(-) (limited to 'drivers/net/phy/mscc/mscc_main.c') diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index 5391acdece05..6508d6536134 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -691,27 +691,23 @@ out_unlock: /* phydev->bus->mdio_lock should be locked when using this function */ static int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val) { - struct vsc8531_private *priv = phydev->priv; - if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) { dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n"); dump_stack(); } - return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val); + return __phy_package_write(phydev, regnum, val); } /* phydev->bus->mdio_lock should be locked when using this function */ static int phy_base_read(struct phy_device *phydev, u32 regnum) { - struct vsc8531_private *priv = phydev->priv; - if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) { dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n"); dump_stack(); } - return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum); + return __phy_package_read(phydev, regnum); } /* bus->mdio_lock should be locked when using this function */ @@ -1287,65 +1283,38 @@ out: return ret; } -/* Check if one PHY has already done the init of the parts common to all PHYs - * in the Quad PHY package. - */ -static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed) +static void vsc8584_get_base_addr(struct phy_device *phydev) { - struct mii_bus *bus = phydev->mdio.bus; - struct vsc8531_private *vsc8531; - struct phy_device *phy; - int i, addr; - - /* VSC8584 is a Quad PHY */ - for (i = 0; i < 4; i++) { - vsc8531 = phydev->priv; - - if (reversed) - addr = vsc8531->base_addr - i; - else - addr = vsc8531->base_addr + i; + struct vsc8531_private *vsc8531 = phydev->priv; + u16 val, addr; - phy = mdiobus_get_phy(bus, addr); - if (!phy) - continue; + mutex_lock(&phydev->mdio.bus->mdio_lock); + __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED); - if ((phy->phy_id & phydev->drv->phy_id_mask) != - (phydev->drv->phy_id & phydev->drv->phy_id_mask)) - continue; + addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4); + addr >>= PHY_CNTL_4_ADDR_POS; - vsc8531 = phy->priv; + val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL); - if (vsc8531 && vsc8531->pkg_init) - return true; - } + __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD); + mutex_unlock(&phydev->mdio.bus->mdio_lock); - return false; + if (val & PHY_ADDR_REVERSED) + vsc8531->base_addr = phydev->mdio.addr + addr; + else + vsc8531->base_addr = phydev->mdio.addr - addr; } static int vsc8584_config_init(struct phy_device *phydev) { struct vsc8531_private *vsc8531 = phydev->priv; - u16 addr, val; int ret, i; + u16 val; phydev->mdix_ctrl = ETH_TP_MDI_AUTO; mutex_lock(&phydev->mdio.bus->mdio_lock); - __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, - MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED); - addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, - MSCC_PHY_EXT_PHY_CNTL_4); - addr >>= PHY_CNTL_4_ADDR_POS; - - val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, - MSCC_PHY_ACTIPHY_CNTL); - if (val & PHY_ADDR_REVERSED) - vsc8531->base_addr = phydev->mdio.addr + addr; - else - vsc8531->base_addr = phydev->mdio.addr - addr; - /* Some parts of the init sequence are identical for every PHY in the * package. Some parts are modifying the GPIO register bank which is a * set of registers that are affecting all PHYs, a few resetting the @@ -1359,7 +1328,7 @@ static int vsc8584_config_init(struct phy_device *phydev) * do the correct init sequence for all PHYs that are package-critical * in this pre-init function. */ - if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) { + if (phy_package_init_once(phydev)) { /* The following switch statement assumes that the lowest * nibble of the phy_id_mask is always 0. This works because * the lowest nibble of the PHY_ID's below are also 0. @@ -1388,8 +1357,6 @@ static int vsc8584_config_init(struct phy_device *phydev) goto err; } - vsc8531->pkg_init = true; - phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_GPIO); @@ -1427,7 +1394,8 @@ static int vsc8584_config_init(struct phy_device *phydev) /* Disable SerDes for 100Base-FX */ ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF | - PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE | + PROC_CMD_FIBER_PORT(vsc8531->base_addr) | + PROC_CMD_FIBER_DISABLE | PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX); if (ret) @@ -1435,7 +1403,8 @@ static int vsc8584_config_init(struct phy_device *phydev) /* Disable SerDes for 1000Base-X */ ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF | - PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE | + PROC_CMD_FIBER_PORT(vsc8531->base_addr) | + PROC_CMD_FIBER_DISABLE | PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X); if (ret) @@ -1750,26 +1719,14 @@ static int vsc8514_config_init(struct phy_device *phydev) { struct vsc8531_private *vsc8531 = phydev->priv; unsigned long deadline; - u16 val, addr; int ret, i; + u16 val; u32 reg; phydev->mdix_ctrl = ETH_TP_MDI_AUTO; mutex_lock(&phydev->mdio.bus->mdio_lock); - __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED); - - addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4); - addr >>= PHY_CNTL_4_ADDR_POS; - - val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL); - - if (val & PHY_ADDR_REVERSED) - vsc8531->base_addr = phydev->mdio.addr + addr; - else - vsc8531->base_addr = phydev->mdio.addr - addr; - /* Some parts of the init sequence are identical for every PHY in the * package. Some parts are modifying the GPIO register bank which is a * set of registers that are affecting all PHYs, a few resetting the @@ -1781,11 +1738,9 @@ static int vsc8514_config_init(struct phy_device *phydev) * do the correct init sequence for all PHYs that are package-critical * in this pre-init function. */ - if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) + if (phy_package_init_once(phydev)) vsc8514_config_pre_init(phydev); - vsc8531->pkg_init = true; - phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_GPIO); @@ -1991,6 +1946,10 @@ static int vsc8514_probe(struct phy_device *phydev) phydev->priv = vsc8531; + vsc8584_get_base_addr(phydev); + devm_phy_package_join(&phydev->mdio.dev, phydev, + vsc8531->base_addr, 0); + vsc8531->nleds = 4; vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; vsc8531->hw_stats = vsc85xx_hw_stats; @@ -2046,6 +2005,10 @@ static int vsc8584_probe(struct phy_device *phydev) phydev->priv = vsc8531; + vsc8584_get_base_addr(phydev); + devm_phy_package_join(&phydev->mdio.dev, phydev, + vsc8531->base_addr, 0); + vsc8531->nleds = 4; vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; vsc8531->hw_stats = vsc8584_hw_stats; -- cgit v1.2.1 From 2684bda34786b6ae0944a4bacb7f59b5955979a8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Fri, 29 May 2020 11:49:09 +0200 Subject: net: phy: mscc: fix PHYs using the vsc8574_probe PHYs using the vsc8574_probe fail to be initialized and their config_init return -EIO leading to errors like: "could not attach PHY: -5". This is because when the conversion of the MSCC PHY driver to use the shared PHY package helpers was done, the base address retrieval and the base PHY read and write helpers in the driver were modified. In particular, the base address retrieval logic was moved from the config_init to the probe. But the vsc8574_probe was forgotten. This patch fixes it. Fixes: deb04e9c0ff2 ("net: phy: mscc: use phy_package_shared") Signed-off-by: Antoine Tenart Reviewed-by: Michael Walle Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/mscc/mscc_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/phy/mscc/mscc_main.c') diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index 550acf547ced..7ed0285206d0 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -1977,6 +1977,10 @@ static int vsc8574_probe(struct phy_device *phydev) phydev->priv = vsc8531; + vsc8584_get_base_addr(phydev); + devm_phy_package_join(&phydev->mdio.dev, phydev, + vsc8531->base_addr, 0); + vsc8531->nleds = 4; vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; vsc8531->hw_stats = vsc8584_hw_stats; -- cgit v1.2.1