Commit 75fe2b7a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-phy-introduce-phy-ports-representation'

Maxime Chevallier says:

====================
net: phy: Introduce PHY ports representation

A few important notes:

 - This is only a first phase. It instantiates the port, and leverage
   that to make the MAC <-> PHY <-> SFP usecase simpler.

 - Next phase will deal with controlling the port state, as well as the
   netlink uAPI for that.

 - The end-goal is to enable support for complex port MUX. This
   preliminary work focuses on PHY-driven ports, but this will be
   extended to support muxing at the MII level (Multi-phy, or compo PHY
   + SFP as found on Turris Omnia for example).

 - The naming is definitely not set in stone. I named that "phy_port",
   but this may convey the false sense that this is phylib-specific.
   Even the word "port" is not that great, as it already has several
   different meanings in the net world (switch port, devlink port,
   etc.). I used the term "connector" in the binding.

A bit of history on that work :

The end goal that I personnaly want to achieve is :

            + PHY - RJ45
            |
 MAC - MUX -+ PHY - RJ45

After many discussions here on netdev@, but also at netdevconf[1] and
LPC[2], there appears to be several analoguous designs that exist out
there.

[1] : https://netdevconf.info/0x17/sessions/talk/improving-multi-phy-and-multi-port-interfaces.html
[2] : https://lpc.events/event/18/contributions/1964/ (video isn't the
right one)

Take the MAchiatobin, it has 2 interfaces that looks like this :

 MAC - PHY -+ RJ45
            |
	    + SFP - Whatever the module does

Now, looking at the Turris Omnia, we have :

 MAC - MUX -+ PHY - RJ45
            |
	    + SFP - Whatever the module does

We can find more example of this kind of designs, the common part is
that we expose multiple front-facing media ports. This is what this
current work aims at supporting. As of right now, it does'nt add any
support for muxing, but this will come later on.

This first phase focuses on phy-driven ports only, but there are already
quite some challenges already. For one, we can't really autodetect how
many ports are sitting behind a PHY. That's why this series introduces a
new binding. Describing ports in DT should however be a last-resort
thing when we need to clear some ambiguity about the PHY media-side.

The only use-cases that we have today for multi-port PHYs are combo PHYs
that drive both a Copper port and an SFP (the Macchiatobin case). This
in itself is challenging and this series only addresses part of this
support, by registering a phy_port for the PHY <-> SFP connection. The
SFP module should in the end be considered as a port as well, but that's
not yet the case.

However, because now PHYs can register phy_ports for every media-side
interface they have, they can register the capabilities of their ports,
which allows making the PHY-driver SFP case much more generic.
====================

Link: https://patch.msgid.link/20260108080041.553250-1-maxime.chevallier@bootlin.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 8d48d92e 62518b5b
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/ethernet-connector.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Generic Ethernet Connector

maintainers:
  - Maxime Chevallier <maxime.chevallier@bootlin.com>

description:
  An Ethernet Connector represents the output of a network component such as
  a PHY, an Ethernet controller with no PHY, or an SFP module.

properties:

  pairs:
    description:
      Defines the number of BaseT pairs that are used on the connector.
    $ref: /schemas/types.yaml#/definitions/uint32
    enum: [1, 2, 4]

  media:
    description:
      The mediums, as defined in 802.3, that can be used on the port.
    enum:
      - BaseT
      - BaseK
      - BaseS
      - BaseC
      - BaseL
      - BaseD
      - BaseE
      - BaseF
      - BaseV
      - BaseMLD

required:
  - media

allOf:
  - if:
      properties:
        media:
          const: BaseT
    then:
      required:
        - pairs
    else:
      properties:
        pairs: false

additionalProperties: true

...
+18 −0
Original line number Diff line number Diff line
@@ -281,6 +281,17 @@ properties:

    additionalProperties: false

  mdi:
    type: object

    patternProperties:
      '^connector-[0-9]+$':
        $ref: /schemas/net/ethernet-connector.yaml#

        unevaluatedProperties: false

    additionalProperties: false

required:
  - reg

@@ -317,5 +328,12 @@ examples:
                    default-state = "keep";
                };
            };
            /* Fast Ethernet port, with only 2 pairs wired */
            mdi {
                connector-0 {
                    pairs = <2>;
                    media = "BaseT";
                };
            };
        };
    };
+8 −1
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ properties:
       is disabled.
       In fiber mode, auto-negotiation is disabled and the PHY can only work in
       100base-fx (full and half duplex) modes.
       This property is deprecated, for details please refer to
       Documentation/devicetree/bindings/net/ethernet-connector.yaml
    deprecated: true

  rx-internal-delay-ps:
    description: |
@@ -141,7 +144,11 @@ examples:
        tx-internal-delay-ps = <1>;
        ti,gpio2-clk-out = "xi";
        mac-termination-ohms = <43>;
        mdi {
          connector-0 {
            media = "BaseF";
          };
        };
      };
    };

...
+1 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ Contents:
   packet_mmap
   phonet
   phy-link-topology
   phy-port
   pktgen
   plip
   ppp_generic
+111 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0
.. _phy_port:

=================
Ethernet ports
=================

This document is a basic description of the phy_port infrastructure,
introduced to represent physical interfaces of Ethernet devices.

Without phy_port, we already have quite a lot of information about what the
media-facing interface of a NIC can do and looks like, through the
:c:type:`struct ethtool_link_ksettings <ethtool_link_ksettings>` attributes,
which includes :

 - What the NIC can do through the :c:member:`supported` field
 - What the Link Partner advertises through :c:member:`lp_advertising`
 - Which features we're advertising through :c:member:`advertising`

We also have info about the number of pairs and the PORT type. These settings
are built by aggregating together information reported by various devices that
are sitting on the link :

  - The NIC itself, through the :c:member:`get_link_ksettings` callback
  - Precise information from the MAC and PCS by using phylink in the MAC driver
  - Information reported by the PHY device
  - Information reported by an SFP module (which can itself include a PHY)

This model however starts showing its limitations when we consider devices that
have more than one media interface. In such a case, only information about the
actively used interface is reported, and it's not possible to know what the
other interfaces can do. In fact, we have very little information about whether
or not there are any other media interfaces.

The goal of the phy_port representation is to provide a way of representing a
physical interface of a NIC, regardless of what is driving the port (NIC through
a firmware, SFP module, Ethernet PHY).

Multi-port interfaces examples
==============================

Several cases of multi-interface NICs have been observed so far :

Internal MII Mux::

  +------------------+
  | SoC              |
  |          +-----+ |           +-----+
  | +-----+  |     |-------------| PHY |
  | | MAC |--| Mux | |   +-----+ +-----+
  | +-----+  |     |-----| SFP |
  |          +-----+ |   +-----+
  +------------------+

Internal Mux with internal PHY::

  +------------------------+
  | SoC                    |
  |          +-----+ +-----+
  | +-----+  |     |-| PHY |
  | | MAC |--| Mux | +-----+   +-----+
  | +-----+  |     |-----------| SFP |
  |          +-----+       |   +-----+
  +------------------------+

External Mux::

  +---------+
  | SoC     |  +-----+  +-----+
  |         |  |     |--| PHY |
  | +-----+ |  |     |  +-----+
  | | MAC |----| Mux |  +-----+
  | +-----+ |  |     |--| PHY |
  |         |  +-----+  +-----+
  |         |     |
  |    GPIO-------+
  +---------+

Double-port PHY::

  +---------+
  | SoC     | +-----+
  |         | |     |--- RJ45
  | +-----+ | |     |
  | | MAC |---| PHY |   +-----+
  | +-----+ | |     |---| SFP |
  +---------+ +-----+   +-----+

phy_port aims at providing a path to support all the above topologies, by
representing the media interfaces in a way that's agnostic to what's driving
the interface. the struct phy_port object has its own set of callback ops, and
will eventually be able to report its own ksettings::

             _____      +------+
            (     )-----| Port |
 +-----+   (       )    +------+
 | MAC |--(   ???   )
 +-----+   (       )    +------+
            (_____)-----| Port |
                        +------+

Next steps
==========

As of writing this documentation, only ports controlled by PHY devices are
supported. The next steps will be to add the Netlink API to expose these
to userspace and add support for raw ports (controlled by some firmware, and directly
managed by the NIC driver).

Another parallel task is the introduction of a MII muxing framework to allow the
control of non-PHY driver multi-port setups.
Loading