/* * B53 register access through MII registers * * Copyright (C) 2011-2013 Jonas Gorski <jogo@openwrt.org> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
if (dev->current_page != page) { /* set page number */
v = (page << 8) | REG_MII_PAGE_ENABLE;
ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR,
REG_MII_PAGE, v); if (ret) return ret;
dev->current_page = page;
}
/* set register address */
v = (reg << 8) | op;
ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, REG_MII_ADDR, v); if (ret) return ret;
/* check if operation completed */ for (i = 0; i < 5; ++i) {
v = mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR,
REG_MII_ADDR); if (!(v & (REG_MII_ADDR_WRITE | REG_MII_ADDR_READ))) break;
usleep_range(10, 100);
}
for (i = 0; i < 2; i++) { int ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR,
REG_MII_DATA0 + i,
temp & 0xffff); if (ret) return ret;
temp >>= 16;
}
for (i = 0; i < 3; i++) { int ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR,
REG_MII_DATA0 + i,
temp & 0xffff); if (ret) return ret;
temp >>= 16;
}
for (i = 0; i < 4; i++) { int ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR,
REG_MII_DATA0 + i,
temp & 0xffff); if (ret) return ret;
temp >>= 16;
}
/* allow the generic PHY driver to take over the non-management MDIO * addresses
*/ if (mdiodev->addr != BRCM_PSEUDO_PHY_ADDR && mdiodev->addr != 0) {
dev_err(&mdiodev->dev, "leaving address %d to PHY\n",
mdiodev->addr); return -ENODEV;
}
/* read the first port's id */
phy_id = mdiobus_read(mdiodev->bus, 0, 2) << 16;
phy_id |= mdiobus_read(mdiodev->bus, 0, 3);
/* First probe will come from SWITCH_MDIO controller on the 7445D0 * switch, which will conflict with the 7445 integrated switch * pseudo-phy (we end-up programming both). In that case, we return * -EPROBE_DEFER for the first time we get here, and wait until we come * back with the slave MDIO bus which has the correct indirection * layer setup
*/ if (of_machine_is_compatible("brcm,bcm7445d0") &&
strcmp(mdiodev->bus->name, "sf2 user mii")) return -EPROBE_DEFER;
dev = b53_switch_alloc(&mdiodev->dev, &b53_mdio_ops, mdiodev->bus); if (!dev) return -ENOMEM;
/* we don't use page 0xff, so force a page set */
dev->current_page = 0xff;
dev->bus = mdiodev->bus;
dev_set_drvdata(&mdiodev->dev, dev);
ret = b53_switch_register(dev); if (ret) return dev_err_probe(&mdiodev->dev, ret, "failed to register switch\n");
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.