|
29 | 29 | #include <linux/phy.h> |
30 | 30 | #include <linux/phylib_stubs.h> |
31 | 31 | #include <linux/phy_led_triggers.h> |
| 32 | +#include <linux/phy_link_topology.h> |
32 | 33 | #include <linux/pse-pd/pse.h> |
33 | 34 | #include <linux/property.h> |
34 | 35 | #include <linux/rtnetlink.h> |
@@ -276,6 +277,14 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev) |
276 | 277 |
|
277 | 278 | static struct phy_driver genphy_driver; |
278 | 279 |
|
| 280 | +static struct phy_link_topology *phy_get_link_topology(struct phy_device *phydev) |
| 281 | +{ |
| 282 | + if (phydev->attached_dev) |
| 283 | + return phydev->attached_dev->link_topo; |
| 284 | + |
| 285 | + return NULL; |
| 286 | +} |
| 287 | + |
279 | 288 | static LIST_HEAD(phy_fixup_list); |
280 | 289 | static DEFINE_MUTEX(phy_fixup_lock); |
281 | 290 |
|
@@ -1369,6 +1378,46 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr, |
1369 | 1378 | } |
1370 | 1379 | static DEVICE_ATTR_RO(phy_standalone); |
1371 | 1380 |
|
| 1381 | +/** |
| 1382 | + * phy_sfp_connect_phy - Connect the SFP module's PHY to the upstream PHY |
| 1383 | + * @upstream: pointer to the upstream phy device |
| 1384 | + * @phy: pointer to the SFP module's phy device |
| 1385 | + * |
| 1386 | + * This helper allows keeping track of PHY devices on the link. It adds the |
| 1387 | + * SFP module's phy to the phy namespace of the upstream phy |
| 1388 | + */ |
| 1389 | +int phy_sfp_connect_phy(void *upstream, struct phy_device *phy) |
| 1390 | +{ |
| 1391 | + struct phy_device *phydev = upstream; |
| 1392 | + struct phy_link_topology *topo = phy_get_link_topology(phydev); |
| 1393 | + |
| 1394 | + if (topo) |
| 1395 | + return phy_link_topo_add_phy(topo, phy, PHY_UPSTREAM_PHY, phydev); |
| 1396 | + |
| 1397 | + return 0; |
| 1398 | +} |
| 1399 | +EXPORT_SYMBOL(phy_sfp_connect_phy); |
| 1400 | + |
| 1401 | +/** |
| 1402 | + * phy_sfp_disconnect_phy - Disconnect the SFP module's PHY from the upstream PHY |
| 1403 | + * @upstream: pointer to the upstream phy device |
| 1404 | + * @phy: pointer to the SFP module's phy device |
| 1405 | + * |
| 1406 | + * This helper allows keeping track of PHY devices on the link. It removes the |
| 1407 | + * SFP module's phy to the phy namespace of the upstream phy. As the module phy |
| 1408 | + * will be destroyed, re-inserting the same module will add a new phy with a |
| 1409 | + * new index. |
| 1410 | + */ |
| 1411 | +void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy) |
| 1412 | +{ |
| 1413 | + struct phy_device *phydev = upstream; |
| 1414 | + struct phy_link_topology *topo = phy_get_link_topology(phydev); |
| 1415 | + |
| 1416 | + if (topo) |
| 1417 | + phy_link_topo_del_phy(topo, phy); |
| 1418 | +} |
| 1419 | +EXPORT_SYMBOL(phy_sfp_disconnect_phy); |
| 1420 | + |
1372 | 1421 | /** |
1373 | 1422 | * phy_sfp_attach - attach the SFP bus to the PHY upstream network device |
1374 | 1423 | * @upstream: pointer to the phy device |
@@ -1511,6 +1560,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, |
1511 | 1560 |
|
1512 | 1561 | if (phydev->sfp_bus_attached) |
1513 | 1562 | dev->sfp_bus = phydev->sfp_bus; |
| 1563 | + |
| 1564 | + err = phy_link_topo_add_phy(dev->link_topo, phydev, |
| 1565 | + PHY_UPSTREAM_MAC, dev); |
| 1566 | + if (err) |
| 1567 | + goto error; |
1514 | 1568 | } |
1515 | 1569 |
|
1516 | 1570 | /* Some Ethernet drivers try to connect to a PHY device before |
@@ -1938,6 +1992,7 @@ void phy_detach(struct phy_device *phydev) |
1938 | 1992 | if (dev) { |
1939 | 1993 | phydev->attached_dev->phydev = NULL; |
1940 | 1994 | phydev->attached_dev = NULL; |
| 1995 | + phy_link_topo_del_phy(dev->link_topo, phydev); |
1941 | 1996 | } |
1942 | 1997 | phydev->phylink = NULL; |
1943 | 1998 |
|
|
0 commit comments