staticvoid stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr, int phyreg, u32 *hw_addr)
{
u32 tmp = 0;
if (priv->synopsys_id < DWXGMAC_CORE_2_20) { /* Until ver 2.20 XGMAC does not support C22 addr >= 4. Those *bitsabovebit3ofXGMAC_MDIO_C22Pregisterarereserved.
*/
tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
tmp &= ~MII_XGMAC_C22P_MASK;
} /* Set port as Clause 22 */
tmp |= BIT(phyaddr);
writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
ret = pm_runtime_resume_and_get(priv->device); if (ret < 0) return ret;
/* Wait until any existing MII operation is complete */ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
ret = -EBUSY; goto err_disable_clks;
}
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
value |= MII_XGMAC_READ;
/* Wait until any existing MII operation is complete */ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
ret = -EBUSY; goto err_disable_clks;
}
/* Set the MII address register to read */
writel(addr, priv->ioaddr + mii_address);
writel(value, priv->ioaddr + mii_data);
/* Wait until any existing MII operation is complete */ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
ret = -EBUSY; goto err_disable_clks;
}
/* Read the data from the MII data register */
ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
err_disable_clks:
pm_runtime_put(priv->device);
return ret;
}
staticint stmmac_xgmac2_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg)
{ struct net_device *ndev = bus->priv; struct stmmac_priv *priv;
u32 addr;
priv = netdev_priv(ndev);
/* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ if (priv->synopsys_id < DWXGMAC_CORE_2_20 &&
phyaddr > MII_XGMAC_MAX_C22ADDR) return -ENODEV;
ret = pm_runtime_resume_and_get(priv->device); if (ret < 0) return ret;
/* Wait until any existing MII operation is complete */ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
ret = -EBUSY; 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;
/* Wait until any existing MII operation is complete */ if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
ret = -EBUSY; goto err_disable_clks;
}
/* Set the MII address register to write */
writel(addr, priv->ioaddr + mii_address);
writel(value, priv->ioaddr + mii_data);
/* Wait until any existing MII operation is complete */
ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp,
!(tmp & MII_XGMAC_BUSY), 100, 10000);
/* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ if (priv->synopsys_id < DWXGMAC_CORE_2_20 &&
phyaddr > MII_XGMAC_MAX_C22ADDR) return -ENODEV;
/* Wait until any existing MII operation is complete */ if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), 100, 10000)) return -EBUSY;
/* Set the MII address register to write */
writel(data, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
/* Wait until any existing MII operation is complete */ return readl_poll_timeout(priv->ioaddr + mii_address, v,
!(v & MII_BUSY), 100, 10000);
}
/** *stmmac_mdio_write_c22 *@bus:pointstothemii_busstructure *@phyaddr:MIIaddr *@phyreg:MIIreg *@phydata:phydata *Description:itwritesthedataintotheMIIregisterfromwithinthedevice.
*/ staticint stmmac_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg,
u16 phydata)
{ struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); int ret, data = phydata;
u32 value = MII_BUSY;
ret = pm_runtime_resume_and_get(priv->device); if (ret < 0) return ret;
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask; if (priv->plat->has_gmac4)
value |= MII_GMAC4_WRITE; else
value |= MII_WRITE;
ret = stmmac_mdio_write(priv, data, value);
pm_runtime_put(priv->device);
return ret;
}
/** *stmmac_mdio_write_c45 *@bus:pointstothemii_busstructure *@phyaddr:MIIaddr *@phyreg:MIIreg *@devad:deviceaddresstoread *@phydata:phydata *Description:itwritesthedataintotheMIIregisterfromwithinthedevice.
*/ staticint stmmac_mdio_write_c45(struct mii_bus *bus, int phyaddr, int devad, int phyreg, u16 phydata)
{ struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); int ret, data = phydata;
u32 value = MII_BUSY;
ret = pm_runtime_get_sync(priv->device); if (ret < 0) {
pm_runtime_put_noidle(priv->device); return ret;
}
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
value |= MII_GMAC4_WRITE;
value |= MII_GMAC4_C45E;
value &= ~priv->hw->mii.reg_mask;
value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
if (delays[0])
msleep(DIV_ROUND_UP(delays[0], 1000));
gpiod_set_value_cansleep(reset_gpio, 1); if (delays[1])
msleep(DIV_ROUND_UP(delays[1], 1000));
gpiod_set_value_cansleep(reset_gpio, 0); if (delays[2])
msleep(DIV_ROUND_UP(delays[2], 1000));
} #endif
/* This is a workaround for problems with the STE101P PHY. *Itdoesn'tcompleteitsresetuntilatleastoneclockcycle *onMDC,soperformadummymdioread.TobeupdatedforGMAC4 *ifneeded.
*/ if (!priv->plat->has_gmac4)
writel(0, priv->ioaddr + mii_address); #endif return0;
}
int stmmac_pcs_setup(struct net_device *ndev)
{ struct fwnode_handle *devnode, *pcsnode; struct dw_xpcs *xpcs = NULL; struct stmmac_priv *priv; int addr, ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.