/** * 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); }
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; }
/** * 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; }
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(ð->phy->lock, flags); eth->link[i] = 0; if (eth->soc->mdio_adjust_link) eth->soc->mdio_adjust_link(eth, i); spin_unlock_irqrestore(ð->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); } }
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; }
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; }