--- a/drivers/net/ethernet/ramips/ramips_main.c +++ b/drivers/net/ethernet/ramips/ramips_main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "ramips_eth.h" @@ -406,12 +407,25 @@ ramips_mdio_reset(struct mii_bus *bus) static int ramips_mdio_init(struct raeth_priv *re) { + struct device_node *mii_np; int err; - int i; + + mii_np = of_get_child_by_name(re->of_node, "mdio-bus"); + if (!mii_np) { + dev_err(re->parent, "no %s child node found", "mdio-bus"); + return -ENODEV; + } + + if (!of_device_is_available(mii_np)) { + err = 0; + goto err_put_node; + } re->mii_bus = mdiobus_alloc(); - if (re->mii_bus == NULL) - return -ENOMEM; + if (re->mii_bus == NULL) { + err = -ENOMEM; + goto err_put_node; + } re->mii_bus->name = "ramips_mdio"; re->mii_bus->read = ramips_mdio_read; @@ -422,12 +436,7 @@ ramips_mdio_init(struct raeth_priv *re) re->mii_bus->parent = re->parent; snprintf(re->mii_bus->id, MII_BUS_ID_SIZE, "%s", "ramips_mdio"); - re->mii_bus->phy_mask = 0; - - for (i = 0; i < PHY_MAX_ADDR; i++) - re->mii_irq[i] = PHY_POLL; - - err = mdiobus_register(re->mii_bus); + err = of_mdiobus_register(re->mii_bus, mii_np); if (err) goto err_free_bus; @@ -435,13 +444,20 @@ ramips_mdio_init(struct raeth_priv *re) err_free_bus: kfree(re->mii_bus); +err_put_node: + of_node_put(mii_np); + re->mii_bus = NULL; return err; } static void ramips_mdio_cleanup(struct raeth_priv *re) { + if (!re->mii_bus) + return; + mdiobus_unregister(re->mii_bus); + of_node_put(re->mii_bus->dev.of_node); kfree(re->mii_bus); } @@ -474,106 +490,86 @@ ramips_phy_link_adjust(struct net_device } static int -ramips_phy_connect_multi(struct raeth_priv *re) +ramips_phy_connect_by_node(struct raeth_priv *re, struct device_node *phy_node) { - struct net_device *netdev = re->netdev; - struct phy_device *phydev = NULL; - int phy_addr; - int ret = 0; - - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { - if (!(re->phy_mask & (1 << phy_addr))) - continue; - - if (re->mii_bus->phy_map[phy_addr] == NULL) - continue; + struct phy_device *phydev; + int phy_mode; - RADEBUG("%s: PHY found at %s, uid=%08x\n", - netdev->name, - dev_name(&re->mii_bus->phy_map[phy_addr]->dev), - re->mii_bus->phy_map[phy_addr]->phy_id); - - if (phydev == NULL) - phydev = re->mii_bus->phy_map[phy_addr]; - } - - if (!phydev) { - netdev_err(netdev, "no PHY found with phy_mask=%08x\n", - re->phy_mask); - return -ENODEV; + phy_mode = of_get_phy_mode(re->of_node); + if (phy_mode < 0) { + dev_err(re->parent, "incorrect phy-mode\n"); + return -EINVAL; } - re->phy_dev = phy_connect(netdev, dev_name(&phydev->dev), - ramips_phy_link_adjust, 0, re->phy_if_mode); - - if (IS_ERR(re->phy_dev)) { - netdev_err(netdev, "could not connect to PHY at %s\n", - dev_name(&phydev->dev)); + phydev = of_phy_connect(re->netdev, phy_node, ramips_phy_link_adjust, + 0, phy_mode); + if (IS_ERR(phydev)) { + dev_err(re->parent, "could not connect to PHY\n"); return PTR_ERR(re->phy_dev); } phydev->supported &= PHY_GBIT_FEATURES; phydev->advertising = phydev->supported; - RADEBUG("%s: connected to PHY at %s [uid=%08x, driver=%s]\n", - netdev->name, dev_name(&phydev->dev), - phydev->phy_id, phydev->drv->name); + dev_info(re->parent, + "connected to PHY at %s [uid=%08x, driver=%s]\n", + dev_name(&phydev->dev), phydev->phy_id, + phydev->drv->name); + re->phy_dev = phydev; re->link = 0; re->speed = 0; re->duplex = -1; re->rx_fc = 0; re->tx_fc = 0; - return ret; + return 0; } static int -ramips_phy_connect_fixed(struct raeth_priv *re) +ramips_phy_connect_fixed(struct raeth_priv *re, const __be32 *link, int size) { - if (!re->speed) { - const __be32 *link; - int size; - - link = of_get_property(re->of_node, - "ralink,fixed-link", &size); - if (!link || size != (4 * sizeof(*link))) - return -ENOENT; - - re->speed = be32_to_cpup(link++); - re->duplex = be32_to_cpup(link++); - re->tx_fc = be32_to_cpup(link++); - re->rx_fc = be32_to_cpup(link++); + if (size != (4 * sizeof(*link))) { + dev_err(re->parent, "invalid fixed-link property\n"); + return -EINVAL; } + re->speed = be32_to_cpup(link++); + re->duplex = be32_to_cpup(link++); + re->tx_fc = be32_to_cpup(link++); + re->rx_fc = be32_to_cpup(link++); + switch (re->speed) { case SPEED_10: case SPEED_100: case SPEED_1000: break; default: - netdev_err(re->netdev, "invalid speed specified\n"); + dev_err(re->parent, "invalid link speed: %d\n", re->speed); return -EINVAL; } - pr_info("%s: using fixed link parameters\n", re->netdev->name); + dev_info(re->parent, "using fixed link parameters\n"); return 0; } static int ramips_phy_connect(struct raeth_priv *re) { - const __be32 *mask; - - mask = of_get_property(re->of_node, "ralink,phy-mask", NULL); - re->phy_if_mode = of_get_phy_mode(re->of_node); - - if (!re->phy_if_mode || !mask) - return ramips_phy_connect_fixed(re); - - re->phy_mask = be32_to_cpup(mask); - return ramips_phy_connect_multi(re); + struct device_node *phy_node; + const __be32 *p32; + int size; + + phy_node = of_parse_phandle(re->of_node, "phy-handle", 0); + if (phy_node) + return ramips_phy_connect_by_node(re, phy_node); + + p32 = of_get_property(re->of_node, "ralink,fixed-link", &size); + if (p32) + return ramips_phy_connect_fixed(re, p32, size); + dev_err(re->parent, "unable to get connection type\n"); + return -EINVAL; } static void