| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- .. SPDX-License-Identifier: GPL-2.0
- .. _phy_link_topology:
- =================
- PHY link topology
- =================
- Overview
- ========
- The PHY link topology representation in the networking stack aims at representing
- the hardware layout for any given Ethernet link.
- An Ethernet interface from userspace's point of view is nothing but a
- :c:type:`struct net_device <net_device>`, which exposes configuration options
- through the legacy ioctls and the ethtool netlink commands. The base assumption
- when designing these configuration APIs were that the link looks something like ::
- +-----------------------+ +----------+ +--------------+
- | Ethernet Controller / | | Ethernet | | Connector / |
- | MAC | ------ | PHY | ---- | Port | ---... to LP
- +-----------------------+ +----------+ +--------------+
- struct net_device struct phy_device
- Commands that needs to configure the PHY will go through the net_device.phydev
- field to reach the PHY and perform the relevant configuration.
- This assumption falls apart in more complex topologies that can arise when,
- for example, using SFP transceivers (although that's not the only specific case).
- Here, we have 2 basic scenarios. Either the MAC is able to output a serialized
- interface, that can directly be fed to an SFP cage, such as SGMII, 1000BaseX,
- 10GBaseR, etc.
- The link topology then looks like this (when an SFP module is inserted) ::
- +-----+ SGMII +------------+
- | MAC | ------- | SFP Module |
- +-----+ +------------+
- Knowing that some modules embed a PHY, the actual link is more like ::
- +-----+ SGMII +--------------+
- | MAC | -------- | PHY (on SFP) |
- +-----+ +--------------+
- In this case, the SFP PHY is handled by phylib, and registered by phylink through
- its SFP upstream ops.
- Now some Ethernet controllers aren't able to output a serialized interface, so
- we can't directly connect them to an SFP cage. However, some PHYs can be used
- as media-converters, to translate the non-serialized MAC MII interface to a
- serialized MII interface fed to the SFP ::
- +-----+ RGMII +-----------------------+ SGMII +--------------+
- | MAC | ------- | PHY (media converter) | ------- | PHY (on SFP) |
- +-----+ +-----------------------+ +--------------+
- This is where the model of having a single net_device.phydev pointer shows its
- limitations, as we now have 2 PHYs on the link.
- The phy_link topology framework aims at providing a way to keep track of every
- PHY on the link, for use by both kernel drivers and subsystems, but also to
- report the topology to userspace, allowing to target individual PHYs in configuration
- commands.
- API
- ===
- The :c:type:`struct phy_link_topology <phy_link_topology>` is a per-netdevice
- resource, that gets initialized at netdevice creation. Once it's initialized,
- it is then possible to register PHYs to the topology through :
- :c:func:`phy_link_topo_add_phy`
- Besides registering the PHY to the topology, this call will also assign a unique
- index to the PHY, which can then be reported to userspace to refer to this PHY
- (akin to the ifindex). This index is a u32, ranging from 1 to U32_MAX. The value
- 0 is reserved to indicate the PHY doesn't belong to any topology yet.
- The PHY can then be removed from the topology through
- :c:func:`phy_link_topo_del_phy`
- These function are already hooked into the phylib subsystem, so all PHYs that
- are linked to a net_device through :c:func:`phy_attach_direct` will automatically
- join the netdev's topology.
- PHYs that are on a SFP module will also be automatically registered IF the SFP
- upstream is phylink (so, no media-converter).
- PHY drivers that can be used as SFP upstream need to call :c:func:`phy_sfp_attach_phy`
- and :c:func:`phy_sfp_detach_phy`, which can be used as a
- .attach_phy / .detach_phy implementation for the
- :c:type:`struct sfp_upstream_ops <sfp_upstream_ops>`.
- UAPI
- ====
- There exist a set of netlink commands to query the link topology from userspace,
- see ``Documentation/networking/ethtool-netlink.rst``.
- The whole point of having a topology representation is to assign the phyindex
- field in :c:type:`struct phy_device <phy_device>`. This index is reported to
- userspace using the ``ETHTOOL_MSG_PHY_GET`` ethtnl command. Performing a DUMP operation
- will result in all PHYs from all net_device being listed. The DUMP command
- accepts either a ``ETHTOOL_A_HEADER_DEV_INDEX`` or ``ETHTOOL_A_HEADER_DEV_NAME``
- to be passed in the request to filter the DUMP to a single net_device.
- The retrieved index can then be passed as a request parameter using the
- ``ETHTOOL_A_HEADER_PHY_INDEX`` field in the following ethnl commands :
- * ``ETHTOOL_MSG_STRSET_GET`` to get the stats string set from a given PHY
- * ``ETHTOOL_MSG_CABLE_TEST_ACT`` and ``ETHTOOL_MSG_CABLE_TEST_ACT``, to perform
- cable testing on a given PHY on the link (most likely the outermost PHY)
- * ``ETHTOOL_MSG_PSE_SET`` and ``ETHTOOL_MSG_PSE_GET`` for PHY-controlled PoE and PSE settings
- * ``ETHTOOL_MSG_PLCA_GET_CFG``, ``ETHTOOL_MSG_PLCA_SET_CFG`` and ``ETHTOOL_MSG_PLCA_GET_STATUS``
- to set the PLCA (Physical Layer Collision Avoidance) parameters
- Note that the PHY index can be passed to other requests, which will silently
- ignore it if present and irrelevant.
|