/* Reset the internal and external PHYs. */ static void gfar_init_phy(struct eth_device *dev) { struct gfar_private *priv = dev->priv; void __iomem *regs = priv->regs; uint64_t start; /* Assign a Physical address to the TBI */ out_be32(regs + GFAR_TBIPA_OFFSET, GFAR_TBIPA_VALUE); /* Reset MII (due to new addresses) */ out_be32(priv->phyregs + GFAR_MIIMCFG_OFFSET, GFAR_MIIMCFG_RESET); out_be32(priv->phyregs + GFAR_MIIMCFG_OFFSET, GFAR_MIIMCFG_INIT_VALUE); start = get_time_ns(); while (!is_timeout(start, 10 * MSECOND)) { if (!(in_be32(priv->phyregs + GFAR_MIIMMIND_OFFSET) & GFAR_MIIMIND_BUSY)) break; } gfar_local_mdio_write(priv->phyregs, priv->phyaddr, GFAR_MIIM_CR, GFAR_MIIM_CR_RST); start = get_time_ns(); while (!is_timeout(start, 10 * MSECOND)) { if (!(gfar_local_mdio_read(priv->phyregs, priv->phyaddr, GFAR_MIIM_CR) & GFAR_MIIM_CR_RST)) break; } if (in_be32(regs + GFAR_ECNTRL_OFFSET) & GFAR_ECNTRL_SGMII_MODE) gfar_configure_serdes(priv); }
/* Read the bus for PHY at addr mii_id, register regnum, and * return the value. Clears miimcom first. All PHY * configuration has to be done through the TSEC1 MIIM regs */ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; /* Read the local MII regs */ return(gfar_local_mdio_read(regs, mii_id, regnum)); }
/* Read a MII PHY register. */ static int gfar_miiphy_read(struct mii_bus *bus, int addr, int reg) { struct gfar_phy *phy = bus->priv; int ret; ret = gfar_local_mdio_read(phy->regs, addr, reg); if (ret == -EIO) dev_err(phy->dev, "Can't read PHY at address %d\n", addr); return ret; }
/* Read a MII PHY register. */ static int gfar_miiphy_read(struct mii_bus *bus, int addr, int reg) { struct device_d *dev = bus->parent; struct gfar_private *priv = bus->priv; int ret; ret = gfar_local_mdio_read(priv->phyregs, addr, reg); if (ret == -EIO) dev_err(dev, "Can't read PHY at address %d\n", addr); return ret; }
/* Reset the external PHYs. */ static void gfar_init_phy(struct eth_device *dev) { struct gfar_private *priv = dev->priv; struct gfar_phy *phy = priv->gfar_mdio; void __iomem *regs = priv->regs; uint64_t start; gfar_local_mdio_write(phy->regs, priv->phyaddr, GFAR_MIIM_CR, GFAR_MIIM_CR_RST); start = get_time_ns(); while (!is_timeout(start, 10 * MSECOND)) { if (!(gfar_local_mdio_read(phy->regs, priv->phyaddr, GFAR_MIIM_CR) & GFAR_MIIM_CR_RST)) break; } if (in_be32(regs + GFAR_ECNTRL_OFFSET) & GFAR_ECNTRL_SGMII_MODE) gfar_configure_serdes(priv); }