Exemple #1
0
/* slave device setup *******************************************************/
static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
				struct net_device *slave_dev)
{
	struct dsa_switch *ds = p->parent;
	struct dsa_chip_data *cd = ds->pd;
	struct device_node *phy_dn, *port_dn;
	bool phy_is_fixed = false;
	u32 phy_flags = 0;
	int mode, ret;

	port_dn = cd->port_dn[p->port];
	mode = of_get_phy_mode(port_dn);
	if (mode < 0)
		mode = PHY_INTERFACE_MODE_NA;
	p->phy_interface = mode;

	phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
	if (of_phy_is_fixed_link(port_dn)) {
		/* In the case of a fixed PHY, the DT node associated
		 * to the fixed PHY is the Port DT node
		 */
		ret = of_phy_register_fixed_link(port_dn);
		if (ret) {
			netdev_err(slave_dev, "failed to register fixed PHY\n");
			return ret;
		}
		phy_is_fixed = true;
		phy_dn = port_dn;
	}

	if (ds->drv->get_phy_flags)
		phy_flags = ds->drv->get_phy_flags(ds, p->port);

	if (phy_dn)
		p->phy = of_phy_connect(slave_dev, phy_dn,
					dsa_slave_adjust_link, phy_flags,
					p->phy_interface);

	if (p->phy && phy_is_fixed)
		fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update);

	/* We could not connect to a designated PHY, so use the switch internal
	 * MDIO bus instead
	 */
	if (!p->phy) {
		p->phy = ds->slave_mii_bus->phy_map[p->port];
		if (!p->phy)
			return -ENODEV;

		/* Use already configured phy mode */
		p->phy_interface = p->phy->interface;
		phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
				   p->phy_interface);
	} else {
		netdev_info(slave_dev, "attached PHY at address %d [%s]\n",
			    p->phy->addr, p->phy->drv->name);
	}

	return 0;
}
Exemple #2
0
static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
{
	u32 reg;

	if (!GENET_IS_V5(priv)) {
		/* Speed settings are set in bcmgenet_mii_setup() */
		reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
		reg |= LED_ACT_SOURCE_MAC;
		bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
	}

	if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
		fixed_phy_set_link_update(priv->dev->phydev,
					  bcmgenet_fixed_phy_link_update);
}
Exemple #3
0
static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
				struct net_device *slave_dev)
{
	struct dsa_switch *ds = p->parent;
	struct dsa_chip_data *cd = ds->pd;
	struct device_node *phy_dn, *port_dn;
	bool phy_is_fixed = false;
	u32 phy_flags = 0;
	int mode, ret;

	port_dn = cd->port_dn[p->port];
	mode = of_get_phy_mode(port_dn);
	if (mode < 0)
		mode = PHY_INTERFACE_MODE_NA;
	p->phy_interface = mode;

	phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
	if (of_phy_is_fixed_link(port_dn)) {
		/* In the case of a fixed PHY, the DT node associated
		 * to the fixed PHY is the Port DT node
		 */
		ret = of_phy_register_fixed_link(port_dn);
		if (ret) {
			netdev_err(slave_dev, "failed to register fixed PHY: %d\n", ret);
			return ret;
		}
		phy_is_fixed = true;
		phy_dn = port_dn;
	}

	if (ds->drv->get_phy_flags)
		phy_flags = ds->drv->get_phy_flags(ds, p->port);

	if (phy_dn) {
		int phy_id = of_mdio_parse_addr(&slave_dev->dev, phy_dn);

		/* If this PHY address is part of phys_mii_mask, which means
		 * that we need to divert reads and writes to/from it, then we
		 * want to bind this device using the slave MII bus created by
		 * DSA to make that happen.
		 */
		if (!phy_is_fixed && phy_id >= 0 &&
		    (ds->phys_mii_mask & (1 << phy_id))) {
			ret = dsa_slave_phy_connect(p, slave_dev, phy_id);
			if (ret) {
				netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret);
				return ret;
			}
		} else {
			p->phy = of_phy_connect(slave_dev, phy_dn,
						dsa_slave_adjust_link,
						phy_flags,
						p->phy_interface);
		}
	}

	if (p->phy && phy_is_fixed)
		fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update);

	/* We could not connect to a designated PHY, so use the switch internal
	 * MDIO bus instead
	 */
	if (!p->phy) {
		ret = dsa_slave_phy_connect(p, slave_dev, p->port);
		if (ret) {
			netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret);
			return ret;
		}
	}

	phy_attached_info(p->phy);

	return 0;
}
Exemple #4
0
static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
{
	struct device *kdev = &priv->pdev->dev;
	struct bcmgenet_platform_data *pd = kdev->platform_data;
	struct mii_bus *mdio = priv->mii_bus;
	struct phy_device *phydev;
	int ret;

	if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) {
		/*
		 * Internal or external PHY with MDIO access
		 */
		if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
			mdio->phy_mask = ~(1 << pd->phy_address);
		else
			mdio->phy_mask = 0;

		ret = mdiobus_register(mdio);
		if (ret) {
			dev_err(kdev, "failed to register MDIO bus\n");
			return ret;
		}

		if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
			phydev = mdio->phy_map[pd->phy_address];
		else
			phydev = phy_find_first(mdio);

		if (!phydev) {
			dev_err(kdev, "failed to register PHY device\n");
			mdiobus_unregister(mdio);
			return -ENODEV;
		}
	} else {
		/*
		 * MoCA port or no MDIO access.
		 * Use fixed PHY to represent the link layer.
		 */
		struct fixed_phy_status fphy_status = {
			.link = 1,
			.speed = pd->phy_speed,
			.duplex = pd->phy_duplex,
			.pause = 0,
			.asym_pause = 0,
		};

		phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
		if (!phydev || IS_ERR(phydev)) {
			dev_err(kdev, "failed to register fixed PHY device\n");
			return -ENODEV;
		}

		if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) {
			ret = fixed_phy_set_link_update(
				phydev, bcmgenet_fixed_phy_link_update);
			if (!ret)
				phydev->link = 0;
		}
	}

	priv->phydev = phydev;
	priv->phy_interface = pd->phy_interface;

	return 0;
}

static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
{
	struct device_node *dn = priv->pdev->dev.of_node;

	if (dn)
		return bcmgenet_mii_of_init(priv);
	else
		return bcmgenet_mii_pd_init(priv);
}

int bcmgenet_mii_init(struct net_device *dev)
{
	struct bcmgenet_priv *priv = netdev_priv(dev);
	int ret;

	ret = bcmgenet_mii_alloc(priv);
	if (ret)
		return ret;

	ret = bcmgenet_mii_bus_init(priv);
	if (ret)
		goto out_free;

	ret = bcmgenet_mii_probe(dev);
	if (ret)
		goto out;

	return 0;

out:
	of_node_put(priv->phy_dn);
	mdiobus_unregister(priv->mii_bus);
out_free:
	kfree(priv->mii_bus->irq);
	mdiobus_free(priv->mii_bus);
	return ret;
}

void bcmgenet_mii_exit(struct net_device *dev)
{
	struct bcmgenet_priv *priv = netdev_priv(dev);

	of_node_put(priv->phy_dn);
	mdiobus_unregister(priv->mii_bus);
	kfree(priv->mii_bus->irq);
	mdiobus_free(priv->mii_bus);
}