diff options
author | Quentin Schulz | 2018-10-31 11:20:38 +0100 |
---|---|---|
committer | Joe Hershberger | 2018-11-05 10:41:58 -0600 |
commit | b5bca65e19ff63efbed8056b2651cec25192277a (patch) | |
tree | 5d5ccf9ffa1eea2ba19acdb210bd8a4af87596df /drivers/net/phy/mscc.c | |
parent | 04087fc4946684a8fa5da3d52ee25fc86e91aaaf (diff) |
net: phy: mscc: factorize part of config function for VSC8584
Part of the config is common between the VSC8584 and the VSC8574, so to
prepare for the upcoming support of VSC8574, use the phy_device.priv
pointer that will keep the function that holds code that is PHY-specific
and that should be called during config function.
Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers/net/phy/mscc.c')
-rw-r--r-- | drivers/net/phy/mscc.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c index 86d882dd088..c1b73c6348d 100644 --- a/drivers/net/phy/mscc.c +++ b/drivers/net/phy/mscc.c @@ -251,6 +251,10 @@ vsc_phy_clk_slew { VSC_PHY_CLK_SLEW_RATE_7, }; +struct vsc85xx_priv { + int (*config_pre)(struct phy_device *phydev); +}; + static void vsc8584_csr_write(struct mii_dev *bus, int phy0, u16 addr, u32 val) { bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, @@ -447,11 +451,28 @@ static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch, return 0; } -static int vsc8584_config_pre_init(struct mii_dev *bus, int phy0) +static int vsc8584_config_pre_init(struct phy_device *phydev) { - u16 reg, crc; + struct mii_dev *bus = phydev->bus; + u16 reg, crc, phy0, addr; int ret; + if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) { + pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n"); + return 0; + } + + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_EXT1); + addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4); + addr >>= PHY_CNTL_4_ADDR_POS; + + reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL); + if (reg & PHY_ADDR_REVERSED) + phy0 = phydev->addr + addr; + else + phy0 = phydev->addr - addr; + bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STD); @@ -909,32 +930,22 @@ static int vsc8541_config(struct phy_device *phydev) return genphy_config_aneg(phydev); } -static int vsc8584_config(struct phy_device *phydev) +static int vsc8584_config_init(struct phy_device *phydev) { + struct vsc85xx_priv *priv = phydev->priv; int ret; u16 addr; u16 reg_val; u16 val; - u16 base_addr; phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT1); addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4); addr >>= PHY_CNTL_4_ADDR_POS; - val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL); - if (val & PHY_ADDR_REVERSED) - base_addr = phydev->addr + addr; - else - base_addr = phydev->addr - addr; - - if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) { - pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n"); - } else { - ret = vsc8584_config_pre_init(phydev->bus, base_addr); - if (ret) - return ret; - } + ret = priv->config_pre(phydev); + if (ret) + return ret; phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_GPIO); @@ -999,6 +1010,17 @@ static int vsc8584_config(struct phy_device *phydev) return genphy_config(phydev); } +static struct vsc85xx_priv vsc8584_priv = { + .config_pre = vsc8584_config_pre_init, +}; + +static int vsc8584_config(struct phy_device *phydev) +{ + phydev->priv = &vsc8584_priv; + + return vsc8584_config_init(phydev); +} + static struct phy_driver VSC8530_driver = { .name = "Microsemi VSC8530", .uid = PHY_ID_VSC8530, |