1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * PHY device list allow maintaining a list of PHY devices that are
4  * part of a netdevice's link topology. PHYs can for example be chained,
5  * as is the case when using a PHY that exposes an SFP module, on which an
6  * SFP transceiver that embeds a PHY is connected.
7  *
8  * This list can then be used by userspace to leverage individual PHY
9  * capabilities.
10  */
11 #ifndef __PHY_LINK_TOPOLOGY_H
12 #define __PHY_LINK_TOPOLOGY_H
13 
14 #include <linux/ethtool.h>
15 #include <linux/phy_link_topology_core.h>
16 
17 struct xarray;
18 struct phy_device;
19 struct net_device;
20 struct sfp_bus;
21 
22 struct phy_device_node {
23 	enum phy_upstream upstream_type;
24 
25 	union {
26 		struct net_device	*netdev;
27 		struct phy_device	*phydev;
28 	} upstream;
29 
30 	struct sfp_bus *parent_sfp_bus;
31 
32 	struct phy_device *phy;
33 };
34 
35 struct phy_link_topology {
36 	struct xarray phys;
37 	u32 next_phy_index;
38 };
39 
40 static inline struct phy_device *
41 phy_link_topo_get_phy(struct phy_link_topology *topo, u32 phyindex)
42 {
43 	struct phy_device_node *pdn = xa_load(&topo->phys, phyindex);
44 
45 	if (pdn)
46 		return pdn->phy;
47 
48 	return NULL;
49 }
50 
51 #if IS_REACHABLE(CONFIG_PHYLIB)
52 int phy_link_topo_add_phy(struct phy_link_topology *topo,
53 			  struct phy_device *phy,
54 			  enum phy_upstream upt, void *upstream);
55 
56 void phy_link_topo_del_phy(struct phy_link_topology *lt, struct phy_device *phy);
57 
58 #else
59 static inline int phy_link_topo_add_phy(struct phy_link_topology *topo,
60 					struct phy_device *phy,
61 					enum phy_upstream upt, void *upstream)
62 {
63 	return 0;
64 }
65 
66 static inline void phy_link_topo_del_phy(struct phy_link_topology *topo,
67 					 struct phy_device *phy)
68 {
69 }
70 #endif
71 
72 #endif /* __PHY_LINK_TOPOLOGY_H */
73