예제 #1
0
/**
 * phy_disconnect - disable interrupts, stop state machine, and detach a PHY device
 * @phydev: target phy_device struct
 */
void phy_disconnect(struct phy_device *phydev)
{
	if (phydev->irq > 0)
		phy_stop_interrupts(phydev);

	phy_stop_machine(phydev);
	
	phydev->adjust_link = NULL;

	phy_detach(phydev);
}
예제 #2
0
int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
{
	int ret;

	ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface);
	if (ret)
		return ret;

	ret = phylink_bringup_phy(pl, phy);
	if (ret)
		phy_detach(phy);

	return ret;
}
예제 #3
0
/**
 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
 * @pl: a pointer to a &struct phylink returned from phylink_create()
 * @dn: a pointer to a &struct device_node.
 * @flags: PHY-specific flags to communicate to the PHY device driver
 *
 * Connect the phy specified in the device node @dn to the phylink instance
 * specified by @pl. Actions specified in phylink_connect_phy() will be
 * performed.
 *
 * Returns 0 on success or a negative errno.
 */
int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn,
			   u32 flags)
{
	struct device_node *phy_node;
	struct phy_device *phy_dev;
	int ret;

	/* Fixed links and 802.3z are handled without needing a PHY */
	if (pl->link_an_mode == MLO_AN_FIXED ||
	    (pl->link_an_mode == MLO_AN_INBAND &&
	     phy_interface_mode_is_8023z(pl->link_interface)))
		return 0;

	phy_node = of_parse_phandle(dn, "phy-handle", 0);
	if (!phy_node)
		phy_node = of_parse_phandle(dn, "phy", 0);
	if (!phy_node)
		phy_node = of_parse_phandle(dn, "phy-device", 0);

	if (!phy_node) {
		if (pl->link_an_mode == MLO_AN_PHY)
			return -ENODEV;
		return 0;
	}

	phy_dev = of_phy_attach(pl->netdev, phy_node, flags,
				pl->link_interface);
	/* We're done with the phy_node handle */
	of_node_put(phy_node);

	if (!phy_dev)
		return -ENODEV;

	ret = phylink_bringup_phy(pl, phy_dev);
	if (ret)
		phy_detach(phy_dev);

	return ret;
}
예제 #4
0
파일: mdio.c 프로젝트: Lyude/linux
static void mtk_phy_disconnect(struct mtk_mac *mac)
{
	struct mtk_eth *eth = mac->hw;
	unsigned long flags;
	int i;

	for (i = 0; i < 8; i++)
		if (eth->phy->phy_fixed[i]) {
			spin_lock_irqsave(&eth->phy->lock, flags);
			eth->link[i] = 0;
			if (eth->soc->mdio_adjust_link)
				eth->soc->mdio_adjust_link(eth, i);
			spin_unlock_irqrestore(&eth->phy->lock, flags);
		} else if (eth->phy->phy[i]) {
			phy_disconnect(eth->phy->phy[i]);
		} else if (eth->mii_bus) {
			struct phy_device *phy =
				mdiobus_get_phy(eth->mii_bus, i);

			if (phy)
				phy_detach(phy);
		}
}
예제 #5
0
static int __phylink_connect_phy(struct phylink *pl, struct phy_device *phy,
		phy_interface_t interface)
{
	int ret;

	if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
		    (pl->link_an_mode == MLO_AN_INBAND &&
		     phy_interface_mode_is_8023z(interface))))
		return -EINVAL;

	if (pl->phydev)
		return -EBUSY;

	ret = phy_attach_direct(pl->netdev, phy, 0, interface);
	if (ret)
		return ret;

	ret = phylink_bringup_phy(pl, phy);
	if (ret)
		phy_detach(phy);

	return ret;
}
예제 #6
0
int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn)
{
	struct device_node *phy_node;
	struct phy_device *phy_dev;
	int ret;

	/* Fixed links are handled without needing a PHY */
	if (pl->link_an_mode == MLO_AN_FIXED)
		return 0;

	phy_node = of_parse_phandle(dn, "phy-handle", 0);
	if (!phy_node)
		phy_node = of_parse_phandle(dn, "phy", 0);
	if (!phy_node)
		phy_node = of_parse_phandle(dn, "phy-device", 0);

	if (!phy_node) {
		if (pl->link_an_mode == MLO_AN_PHY) {
			netdev_err(pl->netdev, "unable to find PHY node\n");
			return -ENODEV;
		}
		return 0;
	}

	phy_dev = of_phy_attach(pl->netdev, phy_node, 0, pl->link_interface);
	/* We're done with the phy_node handle */
	of_node_put(phy_node);

	if (!phy_dev)
		return -ENODEV;

	ret = phylink_bringup_phy(pl, phy_dev);
	if (ret)
		phy_detach(phy_dev);

	return ret;
}