ret = priv->wait_func(priv->wait_func_data); if (ret) goto out;
cmd = unimac_mdio_readl(priv, MDIO_CMD);
/* Some broken devices are known not to release the line during * turn-around, e.g: Broadcom BCM53125 external switches, so check for * that condition here and ignore the MDIO controller read failure * indication.
*/ if (!(bus->phy_ignore_ta_mask & 1 << phy_id) && (cmd & MDIO_READ_FAIL)) {
ret = -EIO; goto out;
}
ret = cmd & 0xffff;
out:
clk_disable_unprepare(priv->clk); return ret;
}
staticint unimac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
{ struct unimac_mdio_priv *priv = bus->priv;
u32 cmd; int ret;
ret = clk_prepare_enable(priv->clk); if (ret) return ret;
ret = priv->wait_func(priv->wait_func_data);
clk_disable_unprepare(priv->clk);
return ret;
}
/* Workaround for integrated BCM7xxx Gigabit PHYs which have a problem with * their internal MDIO management controller making them fail to successfully * be read from or written to for the first transaction. We insert a dummy * BMSR read here to make sure that phy_get_device() and get_phy_id() can * correctly read the PHY MII_PHYSID1/2 registers and successfully register a * PHY device for this peripheral. * * Once the PHY driver is registered, we can workaround subsequent reads from * there (e.g: during system-wide power management). * * bus->reset is invoked before mdiobus_scan during mdiobus_register and is * therefore the right location to stick that workaround. Since we do not want * to read from non-existing PHYs, we either use bus->phy_mask or do a manual * Device Tree scan to limit the search area.
*/ staticint unimac_mdio_reset(struct mii_bus *bus)
{ struct device_node *np = bus->dev.of_node; struct device_node *child;
u32 read_mask = 0; int addr;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) return -EINVAL;
/* Just ioremap, as this MDIO block is usually integrated into an * Ethernet MAC controller register range
*/
priv->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (!priv->base) {
dev_err(&pdev->dev, "failed to remap register\n"); return -ENOMEM;
}
if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
priv->clk_freq = 0;
priv->mii_bus = mdiobus_alloc(); if (!priv->mii_bus) return -ENOMEM;
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.