diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 78d6b3737a26..4d5577935b13 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -290,6 +290,7 @@ struct stmmac_priv { int wolopts; int wol_irq; int clk_csr; + u32 gmii_address_bus_config; struct timer_list eee_ctrl_timer; int lpi_irq; u32 tx_lpi_timer; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 6acce54b5d55..4294262c208d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -104,9 +104,7 @@ static int stmmac_xgmac2_mdio_read(struct stmmac_priv *priv, u32 addr, if (ret) goto err_disable_clks; - value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) - & priv->hw->mii.clk_csr_mask; - value |= MII_XGMAC_READ; + value |= priv->gmii_address_bus_config | MII_XGMAC_READ; /* Wait until any existing MII operation is complete */ ret = stmmac_mdio_wait(priv->ioaddr + mii_data, MII_XGMAC_BUSY); @@ -174,10 +172,7 @@ static int stmmac_xgmac2_mdio_write(struct stmmac_priv *priv, u32 addr, if (ret) goto err_disable_clks; - value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) - & priv->hw->mii.clk_csr_mask; - value |= phydata; - value |= MII_XGMAC_WRITE; + value |= priv->gmii_address_bus_config | phydata | MII_XGMAC_WRITE; /* Wait until any existing MII operation is complete */ ret = stmmac_mdio_wait(priv->ioaddr + mii_data, MII_XGMAC_BUSY); @@ -241,8 +236,7 @@ static u32 stmmac_mdio_format_addr(struct stmmac_priv *priv, return ((pa << mii_regs->addr_shift) & mii_regs->addr_mask) | ((gr << mii_regs->reg_shift) & mii_regs->reg_mask) | - ((priv->clk_csr << mii_regs->clk_csr_shift) & - mii_regs->clk_csr_mask) | + priv->gmii_address_bus_config | MII_BUSY; } @@ -517,6 +511,18 @@ void stmmac_pcs_clean(struct net_device *ndev) priv->hw->xpcs = NULL; } +static void stmmac_mdio_bus_config(struct stmmac_priv *priv, u32 value) +{ + value <<= priv->hw->mii.clk_csr_shift; + + if (value & ~priv->hw->mii.clk_csr_mask) + dev_warn(priv->device, + "clk_csr value out of range (0x%08x exceeds mask 0x%08x), truncating\n", + value, priv->hw->mii.clk_csr_mask); + + priv->gmii_address_bus_config = value & priv->hw->mii.clk_csr_mask; +} + /** * stmmac_mdio_register * @ndev: net device structure @@ -537,6 +543,8 @@ int stmmac_mdio_register(struct net_device *ndev) if (!mdio_bus_data) return 0; + stmmac_mdio_bus_config(priv, priv->clk_csr); + new_bus = mdiobus_alloc(); if (!new_bus) return -ENOMEM;