[RFC PATCH net-next v2 00/11] net: pcs: Introduce support for fwnode PCS

Christian Marangi
2025-04-06T22:15:01Z

This series introduce a most awaited feature that is correctly
provide PCS with fwnode without having to use specific export symbol
and additional handling of PCS in phylink.

First the PCS fwnode:

The concept is to implement a producer-consumer API similar to other
subsystem like clock or PHY.

That seems to be the best solution to the problem as PCS driver needs
to be detached from phylink and implement a simple way to provide a
PCS while maintaining support for probe defer or driver removal.

To keep the implementation simple, the PCS driver devs needs some
collaboration to correctly implement this. This is O.K. as helper
to correctly implement this are provided hence it's really a matter
of following a pattern to correct follow removal of a PCS driver.

A PCS provider have to implement and call fwnode_pcs_add_provider() in
probe function and define an xlate function to define how the PCS
should be provided based on the requested interface and phandle spec
defined in fwnode (based on the #pcs-cells)

fwnode_pcs_get() is provided to provide a specific PCS declared in
fwnode at index.

A simple xlate function is provided for simple single PCS
implementation, fwnode_pcs_simple_get.

A PCS provider on driver removal should first call
fwnode_pcs_del_provider() to delete itself as a provider and then
release the PCS from phylink with phylink_release_pcs() under rtnl
lock.

This series also introduce handling of PCS in phylink and try
to deprecate .mac_select_pcs.

Phylink now might contain a linked list of available PCS and
those will be used for PCS selection on phylink_major_config.

MAC driver needs to define pcs_interfaces mask in phylink_config
for every interface that needs a dedicated PCS.

These PCS can be provided to phylink at phylink_create time
by setting the available_pcs and num_available_pcs in
phylink_config.
A helper to parse PCS from fwnode is provided
fwnode_phylink_pcs_parse() that will fill a preallocated array of
PCS.

phylink_create() will fill the internal PCS list with the passed
array of PCS. phylink_major_config and other user of .mac_select_pcs
are adapted to make use of this new PCS list.

The supported interface value is also moved internally to phylink
struct. This is to handle late removal and addition of PCS.

The supported interface mask in phylink is done by OR the
supported_interfaces in phylink_config with every PCS in PCS list.

PCS removal is supported by forcing a mac_config, refresh the
supported interfaces and run a phy_resolve().

PCS late addition is supported by introducing a global notifier
for PCS provider. If a phylink have the pcs_interfaces mask not
zero, it's registered to this notifier.

PCS provider will emit a global PCS add event to signal any
interface that a new PCS might be avialable.

The function will then check if the PCS is related to the MAC
fwnode and add it accordingly.

A user for this new implementation is provided as an Airoha PCS
driver. This was also tested downstream with the IPQ95xx QCOM SoC
and with the help of Daniel also on the various Mediatek MT7988
SoC with both SFP cage implementation and DSA attached.

Lots of tests were done with driver unbind/bind and with interface
up/down also by adding print to make sure major_config_fail gets
correctly triggered and reset once the PCS comes back.

The dedicated commits have longer description on the implementation
so it's suggested to also check there for additional info.

While this was developed there was a different version that was
proposed for the feature, this is posted with the hope of
implementing a more streamlined implementation and as a
continuation of v2 with the addressed request from Russell.

Changes v2:
- Switch to fwnode
- Implement PCS provider notifier
- Better split changes
- Move supported_interfaces to phylink
- Add circular dependency patch
- Rework handling with indirect addition/removal and
trigger of phylink_resolve()

Christian Marangi (11):
net: phylink: fix possible circular locking dep with config in-band
net: phylink: keep and use MAC supported_interfaces in phylink struct
net: phy: introduce phy_interface_copy helper
net: phylink: introduce internal phylink PCS handling
net: phylink: add phylink_release_pcs() to externally release a PCS
net: pcs: implement Firmware node support for PCS driver
net: phylink: support late PCS provider attach
dt-bindings: net: ethernet-controller: permit to define multiple PCS
net: pcs: airoha: add PCS driver for Airoha SoC
dt-bindings: net: pcs: Document support for Airoha Ethernet PCS
net: airoha: add phylink support for GDM2/3/4

.../bindings/net/ethernet-controller.yaml | 2 -
.../bindings/net/pcs/airoha,pcs.yaml | 112 +
drivers/net/ethernet/airoha/airoha_eth.c | 266 +-
drivers/net/ethernet/airoha/airoha_eth.h | 4 +
drivers/net/ethernet/airoha/airoha_regs.h | 12 +
drivers/net/pcs/Kconfig | 14 +
drivers/net/pcs/Makefile | 2 +
drivers/net/pcs/pcs-airoha.c | 2855 +++++++++++++++++
drivers/net/pcs/pcs.c | 235 ++
drivers/net/phy/phylink.c | 283 +-
include/linux/pcs/pcs-airoha.h | 26 +
include/linux/pcs/pcs-provider.h | 41 +
include/linux/pcs/pcs.h | 104 +
include/linux/phy.h | 5 +
include/linux/phylink.h | 12 +
15 files changed, 3942 insertions(+), 31 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml
create mode 100644 drivers/net/pcs/pcs-airoha.c
create mode 100644 drivers/net/pcs/pcs.c
create mode 100644 include/linux/pcs/pcs-airoha.h
create mode 100644 include/linux/pcs/pcs-provider.h
create mode 100644 include/linux/pcs/pcs.h

--
2.48.1