Skip to content

Commit e75e4e0

Browse files
minimaxwelldavem330
authored andcommitted
net: phy: add helpers to handle sfp phy connect/disconnect
There are a few PHY drivers that can handle SFP modules through their sfp_upstream_ops. Introduce Phylib helpers to keep track of connected SFP PHYs in a netdevice's namespace, by adding the SFP PHY to the upstream PHY's netdev's namespace. By doing so, these SFP PHYs can be enumerated and exposed to users, which will be able to use their capabilities. Signed-off-by: Maxime Chevallier <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0ec5ed6 commit e75e4e0

File tree

7 files changed

+60
-0
lines changed

7 files changed

+60
-0
lines changed

drivers/net/phy/marvell-88x2222.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ static const struct sfp_upstream_ops sfp_phy_ops = {
553553
.link_down = mv2222_sfp_link_down,
554554
.attach = phy_sfp_attach,
555555
.detach = phy_sfp_detach,
556+
.connect_phy = phy_sfp_connect_phy,
557+
.disconnect_phy = phy_sfp_disconnect_phy,
556558
};
557559

558560
static int mv2222_probe(struct phy_device *phydev)

drivers/net/phy/marvell.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3550,6 +3550,8 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = {
35503550
.module_remove = m88e1510_sfp_remove,
35513551
.attach = phy_sfp_attach,
35523552
.detach = phy_sfp_detach,
3553+
.connect_phy = phy_sfp_connect_phy,
3554+
.disconnect_phy = phy_sfp_disconnect_phy,
35533555
};
35543556

35553557
static int m88e1510_probe(struct phy_device *phydev)

drivers/net/phy/marvell10g.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,8 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
503503
static const struct sfp_upstream_ops mv3310_sfp_ops = {
504504
.attach = phy_sfp_attach,
505505
.detach = phy_sfp_detach,
506+
.connect_phy = phy_sfp_connect_phy,
507+
.disconnect_phy = phy_sfp_disconnect_phy,
506508
.module_insert = mv3310_sfp_insert,
507509
};
508510

drivers/net/phy/phy_device.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,14 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev)
277277

278278
static struct phy_driver genphy_driver;
279279

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+
280288
static LIST_HEAD(phy_fixup_list);
281289
static DEFINE_MUTEX(phy_fixup_lock);
282290

@@ -1370,6 +1378,46 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr,
13701378
}
13711379
static DEVICE_ATTR_RO(phy_standalone);
13721380

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+
13731421
/**
13741422
* phy_sfp_attach - attach the SFP bus to the PHY upstream network device
13751423
* @upstream: pointer to the phy device

drivers/net/phy/qcom/at803x.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,8 @@ static const struct sfp_upstream_ops at8031_sfp_ops = {
770770
.attach = phy_sfp_attach,
771771
.detach = phy_sfp_detach,
772772
.module_insert = at8031_sfp_insert,
773+
.connect_phy = phy_sfp_connect_phy,
774+
.disconnect_phy = phy_sfp_disconnect_phy,
773775
};
774776

775777
static int at8031_parse_dt(struct phy_device *phydev)

drivers/net/phy/qcom/qca807x.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ static const struct sfp_upstream_ops qca807x_sfp_ops = {
699699
.detach = phy_sfp_detach,
700700
.module_insert = qca807x_sfp_insert,
701701
.module_remove = qca807x_sfp_remove,
702+
.connect_phy = phy_sfp_connect_phy,
703+
.disconnect_phy = phy_sfp_disconnect_phy,
702704
};
703705

704706
static int qca807x_probe(struct phy_device *phydev)

include/linux/phy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,8 @@ int phy_suspend(struct phy_device *phydev);
17581758
int phy_resume(struct phy_device *phydev);
17591759
int __phy_resume(struct phy_device *phydev);
17601760
int phy_loopback(struct phy_device *phydev, bool enable);
1761+
int phy_sfp_connect_phy(void *upstream, struct phy_device *phy);
1762+
void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy);
17611763
void phy_sfp_attach(void *upstream, struct sfp_bus *bus);
17621764
void phy_sfp_detach(void *upstream, struct sfp_bus *bus);
17631765
int phy_sfp_probe(struct phy_device *phydev,

0 commit comments

Comments
 (0)