Re: [PATCH net-next v11 00/12] net: pcs: Introduce support for fwnode PCS

Christian Marangi <[email protected]>
Newsgroups org.infradead.lists.linux-mediatek,dev.linux.lists.llvm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
On Sun, Aug 09, 2026 at 07:44:55PM +0200, Andrew Lunn wrote:
> On Fri, Aug 07, 2026 at 03:12:42PM +0200, Christian Marangi wrote:
> > 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.
> 
> One of Russells complaints was the phylink has too many bits of code
> for ideas which did not work out and were replaced by new ways of
> doing things.
> 
> We want .mac_select_pcs to go away, this framework should replace it.
> Please could you convert one of the exist users of .mac_select_pcs, so
> we get an idea of what that involved. If that conversion is pretty
> mechanical, i think we should have a second patchset which converts
> all the current users, and then remove support for .mac_select_pcs.
> 
> Overall i think the direction of this patchset is good.
>

Thanks for the initial check.

Maxime converted one device with this and the patch delta was small... let
me copy those patch here. (it was referenced in v9)

I think the most annoying one will be stmmac with the 3 different PCS
implementation but we already handled that in a upcoming ipq50xx driver
currently present in OpenWrt mainline.

Maybe if Maxime is O.K. I can include his patch in this series.

From 38ad94b1e62bf3523097983dfb515f59b1634477 Mon Sep 17 00:00:00 2001
From: Maxime Chevallier <[email protected]>
Date: Tue, 21 Jul 2026 13:52:57 +0200
Subject: [PATCH] net: marvell: mvpp2: Convert to the new PCS API

Following the introduction of the PCS framework, port mvpp2 to the new
PCS API.

Signed-off-by: Maxime Chevallier <[email protected]>
---
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 161 +++++++++++-------
 1 file changed, 95 insertions(+), 66 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index ccc24a1301f2..8d9663c7a023 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6499,21 +6499,6 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
                writel(ctrl4, port->base + MVPP22_GMAC_CTRL_4_REG);
 }

-static struct phylink_pcs *mvpp2_select_pcs(struct phylink_config *config,
-                                           phy_interface_t interface)
-{
-       struct mvpp2_port *port = mvpp2_phylink_to_port(config);
-
-       /* Select the appropriate PCS operations depending on the
-        * configured interface mode. We will only switch to a mode
-        * that the validate() checks have already passed.
-        */
-       if (mvpp2_is_xlg(interface))
-               return &port->pcs_xlg;
-       else
-               return &port->pcs_gmac;
-}
-
 static int mvpp2_mac_prepare(struct phylink_config *config, unsigned int mode,
                             phy_interface_t interface)
 {
@@ -6786,7 +6771,6 @@ static int mvpp2_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
 }

 static const struct phylink_mac_ops mvpp2_phylink_ops = {
-       .mac_select_pcs = mvpp2_select_pcs,
        .mac_prepare = mvpp2_mac_prepare,
        .mac_config = mvpp2_mac_config,
        .mac_finish = mvpp2_mac_finish,
@@ -6808,7 +6792,10 @@ static void mvpp2_acpi_start(struct mvpp2_port *port)
        };
        struct phylink_pcs *pcs;

-       pcs = mvpp2_select_pcs(&port->phylink_config, port->phy_interface);
+       if (mvpp2_is_xlg(port->phy_interface))
+               pcs = &port->pcs_xlg;
+       else
+               pcs = &port->pcs_gmac;

        mvpp2_mac_prepare(&port->phylink_config, MLO_AN_INBAND,
                          port->phy_interface);
@@ -6823,6 +6810,78 @@ static void mvpp2_acpi_start(struct mvpp2_port *port)
                          SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false);
 }

+static int mvpp2_port_fill_pcs(struct phylink_config *config,
+                              struct phylink_pcs **available_pcs,
+                              unsigned int num_possible_pcs)
+{
+       struct mvpp2_port *port = mvpp2_phylink_to_port(config);
+
+       available_pcs[0] = &port->pcs_gmac;
+
+       if (mvpp2_port_supports_xlg(port)) {
+               if (num_possible_pcs < 2)
+                       return -EINVAL;
+
+               available_pcs[1] = &port->pcs_xlg;
+       }
+
+       return 0;
+}
+
+static void mvpp2_port_init_pcs_xlg(struct phylink_pcs *pcs, bool has_comphy,
+                                   phy_interface_t phy_mode)
+{
+       if (has_comphy) {
+               __set_bit(PHY_INTERFACE_MODE_5GBASER,
+                         pcs->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_10GBASER,
+                         pcs->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_XAUI,
+                         pcs->supported_interfaces);
+       } else if (phy_mode == PHY_INTERFACE_MODE_5GBASER) {
+               __set_bit(PHY_INTERFACE_MODE_5GBASER,
+                         pcs->supported_interfaces);
+       } else if (phy_mode == PHY_INTERFACE_MODE_10GBASER) {
+               __set_bit(PHY_INTERFACE_MODE_10GBASER,
+                         pcs->supported_interfaces);
+       } else if (phy_mode == PHY_INTERFACE_MODE_XAUI) {
+               __set_bit(PHY_INTERFACE_MODE_XAUI,
+                         pcs->supported_interfaces);
+       }
+}
+
+static void mvpp2_port_init_pcs_gmac(struct phylink_pcs *pcs, bool has_comphy,
+                                    phy_interface_t phy_mode)
+{
+       if (has_comphy) {
+               /* If a COMPHY is present, we can support any of the
+                * serdes modes and switch between them.
+                */
+               __set_bit(PHY_INTERFACE_MODE_SGMII,
+                         pcs->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_1000BASEX,
+                         pcs->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_2500BASEX,
+                         pcs->supported_interfaces);
+       } else if (phy_mode == PHY_INTERFACE_MODE_2500BASEX) {
+               /* No COMPHY, with only 2500BASE-X mode supported */
+               __set_bit(PHY_INTERFACE_MODE_2500BASEX,
+                         pcs->supported_interfaces);
+       } else if (phy_mode == PHY_INTERFACE_MODE_1000BASEX ||
+                  phy_mode == PHY_INTERFACE_MODE_SGMII) {
+               /* No COMPHY, we can switch between 1000BASE-X and SGMII
+                */
+               __set_bit(PHY_INTERFACE_MODE_1000BASEX,
+                         pcs->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_SGMII,
+                         pcs->supported_interfaces);
+       }
+
+       /* RGMII and MII are still routed through the gmac PCS */
+       phy_interface_set_rgmii(pcs->supported_interfaces);
+       __set_bit(PHY_INTERFACE_MODE_MII, pcs->supported_interfaces);
+}
+
 /* In order to ensure backward compatibility for ACPI, check if the port
  * firmware node comprises the necessary description allowing to use phylink.
  */
@@ -7082,28 +7141,17 @@ static int mvpp2_port_probe(struct platform_device *pdev,
                        port->phylink_config.mac_capabilities |=
                                MAC_SYM_PAUSE | MAC_ASYM_PAUSE;

-               if (mvpp2_port_supports_xlg(port)) {
-                       /* If a COMPHY is present, we can support any of
-                        * the serdes modes and switch between them.
-                        */
-                       if (comphy) {
-                               __set_bit(PHY_INTERFACE_MODE_5GBASER,
-                                         port->phylink_config.supported_interfaces);
-                               __set_bit(PHY_INTERFACE_MODE_10GBASER,
-                                         port->phylink_config.supported_interfaces);
-                               __set_bit(PHY_INTERFACE_MODE_XAUI,
-                                         port->phylink_config.supported_interfaces);
-                       } else if (phy_mode == PHY_INTERFACE_MODE_5GBASER) {
-                               __set_bit(PHY_INTERFACE_MODE_5GBASER,
-                                         port->phylink_config.supported_interfaces);
-                       } else if (phy_mode == PHY_INTERFACE_MODE_10GBASER) {
-                               __set_bit(PHY_INTERFACE_MODE_10GBASER,
-                                         port->phylink_config.supported_interfaces);
-                       } else if (phy_mode == PHY_INTERFACE_MODE_XAUI) {
-                               __set_bit(PHY_INTERFACE_MODE_XAUI,
-                                         port->phylink_config.supported_interfaces);
-                       }
+               if (!mvpp2_port_supports_xlg(port))
+                       port->phylink_config.num_possible_pcs = 1;
+               else
+                       port->phylink_config.num_possible_pcs = 2;
+
+               port->phylink_config.fill_available_pcs = mvpp2_port_fill_pcs;

+               mvpp2_port_init_pcs_xlg(&port->pcs_xlg, comphy, phy_mode);
+               mvpp2_port_init_pcs_gmac(&port->pcs_gmac, comphy, phy_mode);
+
+               if (mvpp2_port_supports_xlg(port)) {
                        if (comphy)
                                port->phylink_config.mac_capabilities |=
                                        MAC_10000FD | MAC_5000FD;
@@ -7115,35 +7163,16 @@ static int mvpp2_port_probe(struct platform_device *pdev,
                                        MAC_10000FD;
                }

-               if (mvpp2_port_supports_rgmii(port)) {
-                       phy_interface_set_rgmii(port->phylink_config.supported_interfaces);
-                       __set_bit(PHY_INTERFACE_MODE_MII,
-                                 port->phylink_config.supported_interfaces);
-               }
+               phy_interface_copy(port->phylink_config.pcs_interfaces,
+                                  port->pcs_gmac.supported_interfaces);

-               if (comphy) {
-                       /* If a COMPHY is present, we can support any of the
-                        * serdes modes and switch between them.
-                        */
-                       __set_bit(PHY_INTERFACE_MODE_SGMII,
-                                 port->phylink_config.supported_interfaces);
-                       __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-                                 port->phylink_config.supported_interfaces);
-                       __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-                                 port->phylink_config.supported_interfaces);
-               } else if (phy_mode == PHY_INTERFACE_MODE_2500BASEX) {
-                       /* No COMPHY, with only 2500BASE-X mode supported */
-                       __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-                                 port->phylink_config.supported_interfaces);
-               } else if (phy_mode == PHY_INTERFACE_MODE_1000BASEX ||
-                          phy_mode == PHY_INTERFACE_MODE_SGMII) {
-                       /* No COMPHY, we can switch between 1000BASE-X and SGMII
-                        */
-                       __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-                                 port->phylink_config.supported_interfaces);
-                       __set_bit(PHY_INTERFACE_MODE_SGMII,
-                                 port->phylink_config.supported_interfaces);
-               }
+               if (mvpp2_port_supports_xlg(port))
+                       phy_interface_or(port->phylink_config.pcs_interfaces,
+                                        port->phylink_config.pcs_interfaces,
+                                        port->pcs_xlg.supported_interfaces);
+
+               phy_interface_copy(port->phylink_config.supported_interfaces,
+                                  port->phylink_config.pcs_interfaces);

                phylink = phylink_create(&port->phylink_config, port_fwnode,
                                         phy_mode, &mvpp2_phylink_ops);
--
2.55.0



-- 
	Ansuel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.