All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-05  9:46 ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:46 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh

A new revision of the series which incorporates changes that Marek
suggested. Specifically, the changes are:

1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
   default interface rather than re-using port_max_speed_mode()

2. Patch 4 - if no default interface is provided, use the supported
   interface mask to search for the first interface that gives the
   fastest speed.

3. Patch 5 - now also removes the port_max_speed_mode() method

 drivers/net/dsa/b53/b53_common.c       |   3 +-
 drivers/net/dsa/bcm_sf2.c              |   3 +-
 drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
 drivers/net/dsa/lantiq_gswip.c         |   6 +-
 drivers/net/dsa/microchip/ksz_common.c |   3 +-
 drivers/net/dsa/mt7530.c               |   3 +-
 drivers/net/dsa/mv88e6xxx/chip.c       | 136 +++++++++++++++---------------
 drivers/net/dsa/mv88e6xxx/chip.h       |   6 +-
 drivers/net/dsa/mv88e6xxx/port.c       |  32 -------
 drivers/net/dsa/mv88e6xxx/port.h       |   5 --
 drivers/net/dsa/ocelot/felix.c         |   3 +-
 drivers/net/dsa/qca/ar9331.c           |   3 +-
 drivers/net/dsa/qca8k.c                |   3 +-
 drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
 drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
 drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
 drivers/net/phy/phylink.c              | 150 ++++++++++++++++++++++++++++++---
 include/linux/phylink.h                |   5 ++
 include/net/dsa.h                      |   3 +-
 net/dsa/port.c                         |  47 +++++++----
 20 files changed, 270 insertions(+), 153 deletions(-)

On Wed, Jun 29, 2022 at 01:49:57PM +0100, Russell King (Oracle) wrote:
> Mostly the same as the previous RFC, except:
> 
> 1) incldues the phylink_validate_mask_caps() function
> 2) has Marek's idea of searching the supported_interfaces bitmap for the
>    fastest interface we can use
> 3) includes a final patch to add a print which will be useful to hear
>    from people testing it.
> 
> Some of the questions from the original RFC remain though, so I've
> included that text below. I'm guessing as they remain unanswered that
> no one has any opinions on them?
> 
>  drivers/net/dsa/b53/b53_common.c       |   3 +-
>  drivers/net/dsa/bcm_sf2.c              |   3 +-
>  drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
>  drivers/net/dsa/lantiq_gswip.c         |   6 +-
>  drivers/net/dsa/microchip/ksz_common.c |   3 +-
>  drivers/net/dsa/mt7530.c               |   3 +-
>  drivers/net/dsa/mv88e6xxx/chip.c       |  53 ++++--------
>  drivers/net/dsa/ocelot/felix.c         |   3 +-
>  drivers/net/dsa/qca/ar9331.c           |   3 +-
>  drivers/net/dsa/qca8k.c                |   3 +-
>  drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
>  drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
>  drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
>  drivers/net/phy/phylink.c              | 148 ++++++++++++++++++++++++++++++---
>  include/linux/phylink.h                |   5 ++
>  include/net/dsa.h                      |   3 +-
>  net/dsa/port.c                         |  47 +++++++----
>  17 files changed, 215 insertions(+), 80 deletions(-)
> 
> On Fri, Jun 24, 2022 at 12:41:26PM +0100, Russell King (Oracle) wrote:
> > Hi,
> > 
> > Currently, the core DSA code conditionally uses phylink for CPU and DSA
> > ports depending on whether the firmware specifies a fixed-link or a PHY.
> > If either of these are specified, then phylink is used for these ports,
> > otherwise phylink is not, and we rely on the DSA drivers to "do the
> > right thing". However, this detail is not mentioned in the DT binding,
> > but Andrew has said that this behaviour has always something that DSA
> > wants.
> > 
> > mv88e6xxx has had support for this for a long time with its "SPEED_MAX"
> > thing, which I recently reworked to make use of the mac_capabilities in
> > preparation to solving this more fully.
> > 
> > This series is an experiment to solve this properly, and it does this
> > in two steps.
> > 
> > The first step consists of the first two patches. Phylink needs to
> > know the PHY interface mode that is being used so it can (a) pass the
> > right mode into the MAC/PCS etc and (b) know the properties of the
> > link and therefore which speeds can be supported across it.
> > 
> > In order to achieve this, the DSA phylink_get_caps() method has an
> > extra argument added to it so that DSA drivers can report the
> > interface mode that they will be using for this port back to the core
> > DSA code, thereby allowing phylink to be initialised with the correct
> > interface mode.
> > 
> > Note that this can only be used for CPU and DSA ports as "user" ports
> > need a different behaviour - they rely on getting the interface mode
> > from phylib, which will only happen if phylink is initialised with
> > PHY_INTERFACE_MODE_NA. Unfortunately, changing this behaviour is likely
> > to cause widespread regressions.
> > 
> > Obvious questions:
> > 1. Should phylink_get_caps() be augmented in this way, or should it be
> >    a separate method?
> > 
> > 2. DSA has traditionally used "interface mode for the maximum supported
> >    speed on this port" where the interface mode is programmable (via
> >    its internal port_max_speed_mode() method) but this is only present
> >    for a few of the sub-drivers. Is reporting the current interface
> >    mode correct where this method is not implemented?
> > 
> > The second step is to introduce a function that allows phylink to be
> > reconfigured after creation time to operate at max-speed fixed-link
> > mode for the PHY interface mode, also using the MAC capabilities to
> > determine the speed and duplex mode we should be using.
> > 
> > Obvious questions:
> > 1. Should we be allowing half-duplex for this?
> > 2. If we do allow half-duplex, should we prefer fastest speed over
> >    duplex setting, or should we prefer fastest full-duplex speed
> >    over any half-duplex?
> > 3. How do we sanely switch DSA from its current behaviour to always
> >    using phylink for these ports without breakage - this is the
> >    difficult one, because it's not obvious which drivers have been
> >    coded to either work around this quirk of the DSA implementation.
> >    For example, if we start forcing the link down before calling
> >    dsa_port_phylink_create(), and we then fail to set max-fixed-link,
> >    then the CPU/DSA port is going to fail, and we're going to have
> >    lots of regressions.
> > 
> > Please look at the patches and make suggestions on how we can proceed
> > to clean up this quirk of DSA.
> 
> -- 
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-05  9:46 ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:46 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh

A new revision of the series which incorporates changes that Marek
suggested. Specifically, the changes are:

1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
   default interface rather than re-using port_max_speed_mode()

2. Patch 4 - if no default interface is provided, use the supported
   interface mask to search for the first interface that gives the
   fastest speed.

3. Patch 5 - now also removes the port_max_speed_mode() method

 drivers/net/dsa/b53/b53_common.c       |   3 +-
 drivers/net/dsa/bcm_sf2.c              |   3 +-
 drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
 drivers/net/dsa/lantiq_gswip.c         |   6 +-
 drivers/net/dsa/microchip/ksz_common.c |   3 +-
 drivers/net/dsa/mt7530.c               |   3 +-
 drivers/net/dsa/mv88e6xxx/chip.c       | 136 +++++++++++++++---------------
 drivers/net/dsa/mv88e6xxx/chip.h       |   6 +-
 drivers/net/dsa/mv88e6xxx/port.c       |  32 -------
 drivers/net/dsa/mv88e6xxx/port.h       |   5 --
 drivers/net/dsa/ocelot/felix.c         |   3 +-
 drivers/net/dsa/qca/ar9331.c           |   3 +-
 drivers/net/dsa/qca8k.c                |   3 +-
 drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
 drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
 drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
 drivers/net/phy/phylink.c              | 150 ++++++++++++++++++++++++++++++---
 include/linux/phylink.h                |   5 ++
 include/net/dsa.h                      |   3 +-
 net/dsa/port.c                         |  47 +++++++----
 20 files changed, 270 insertions(+), 153 deletions(-)

On Wed, Jun 29, 2022 at 01:49:57PM +0100, Russell King (Oracle) wrote:
> Mostly the same as the previous RFC, except:
> 
> 1) incldues the phylink_validate_mask_caps() function
> 2) has Marek's idea of searching the supported_interfaces bitmap for the
>    fastest interface we can use
> 3) includes a final patch to add a print which will be useful to hear
>    from people testing it.
> 
> Some of the questions from the original RFC remain though, so I've
> included that text below. I'm guessing as they remain unanswered that
> no one has any opinions on them?
> 
>  drivers/net/dsa/b53/b53_common.c       |   3 +-
>  drivers/net/dsa/bcm_sf2.c              |   3 +-
>  drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
>  drivers/net/dsa/lantiq_gswip.c         |   6 +-
>  drivers/net/dsa/microchip/ksz_common.c |   3 +-
>  drivers/net/dsa/mt7530.c               |   3 +-
>  drivers/net/dsa/mv88e6xxx/chip.c       |  53 ++++--------
>  drivers/net/dsa/ocelot/felix.c         |   3 +-
>  drivers/net/dsa/qca/ar9331.c           |   3 +-
>  drivers/net/dsa/qca8k.c                |   3 +-
>  drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
>  drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
>  drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
>  drivers/net/phy/phylink.c              | 148 ++++++++++++++++++++++++++++++---
>  include/linux/phylink.h                |   5 ++
>  include/net/dsa.h                      |   3 +-
>  net/dsa/port.c                         |  47 +++++++----
>  17 files changed, 215 insertions(+), 80 deletions(-)
> 
> On Fri, Jun 24, 2022 at 12:41:26PM +0100, Russell King (Oracle) wrote:
> > Hi,
> > 
> > Currently, the core DSA code conditionally uses phylink for CPU and DSA
> > ports depending on whether the firmware specifies a fixed-link or a PHY.
> > If either of these are specified, then phylink is used for these ports,
> > otherwise phylink is not, and we rely on the DSA drivers to "do the
> > right thing". However, this detail is not mentioned in the DT binding,
> > but Andrew has said that this behaviour has always something that DSA
> > wants.
> > 
> > mv88e6xxx has had support for this for a long time with its "SPEED_MAX"
> > thing, which I recently reworked to make use of the mac_capabilities in
> > preparation to solving this more fully.
> > 
> > This series is an experiment to solve this properly, and it does this
> > in two steps.
> > 
> > The first step consists of the first two patches. Phylink needs to
> > know the PHY interface mode that is being used so it can (a) pass the
> > right mode into the MAC/PCS etc and (b) know the properties of the
> > link and therefore which speeds can be supported across it.
> > 
> > In order to achieve this, the DSA phylink_get_caps() method has an
> > extra argument added to it so that DSA drivers can report the
> > interface mode that they will be using for this port back to the core
> > DSA code, thereby allowing phylink to be initialised with the correct
> > interface mode.
> > 
> > Note that this can only be used for CPU and DSA ports as "user" ports
> > need a different behaviour - they rely on getting the interface mode
> > from phylib, which will only happen if phylink is initialised with
> > PHY_INTERFACE_MODE_NA. Unfortunately, changing this behaviour is likely
> > to cause widespread regressions.
> > 
> > Obvious questions:
> > 1. Should phylink_get_caps() be augmented in this way, or should it be
> >    a separate method?
> > 
> > 2. DSA has traditionally used "interface mode for the maximum supported
> >    speed on this port" where the interface mode is programmable (via
> >    its internal port_max_speed_mode() method) but this is only present
> >    for a few of the sub-drivers. Is reporting the current interface
> >    mode correct where this method is not implemented?
> > 
> > The second step is to introduce a function that allows phylink to be
> > reconfigured after creation time to operate at max-speed fixed-link
> > mode for the PHY interface mode, also using the MAC capabilities to
> > determine the speed and duplex mode we should be using.
> > 
> > Obvious questions:
> > 1. Should we be allowing half-duplex for this?
> > 2. If we do allow half-duplex, should we prefer fastest speed over
> >    duplex setting, or should we prefer fastest full-duplex speed
> >    over any half-duplex?
> > 3. How do we sanely switch DSA from its current behaviour to always
> >    using phylink for these ports without breakage - this is the
> >    difficult one, because it's not obvious which drivers have been
> >    coded to either work around this quirk of the DSA implementation.
> >    For example, if we start forcing the link down before calling
> >    dsa_port_phylink_create(), and we then fail to set max-fixed-link,
> >    then the CPU/DSA port is going to fail, and we're going to have
> >    lots of regressions.
> > 
> > Please look at the patches and make suggestions on how we can proceed
> > to clean up this quirk of DSA.
> 
> -- 
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 1/5] net: dsa: add support for retrieving the interface mode
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-05  9:47   ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:47 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

DSA port bindings allow for an optional phy interface mode. When an
interface mode is not specified, DSA uses the NA interface mode type.

However, phylink needs to know the parameters of the link, and this
will become especially important when using phylink for ports that
are devoid of all properties except the required "reg" property, so
that phylink can select the maximum supported link settings. Without
knowing the interface mode, phylink can't truely know the maximum
link speed.

Update the prototype for the phylink_get_caps method to allow drivers
to report this information back to DSA, and update all DSA
implementations function declarations to cater for this change. No
code is added to the implementations.

Reviewed-by: Marek Behún <kabel@kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/b53/b53_common.c       |  3 ++-
 drivers/net/dsa/bcm_sf2.c              |  3 ++-
 drivers/net/dsa/hirschmann/hellcreek.c |  3 ++-
 drivers/net/dsa/lantiq_gswip.c         |  6 ++++--
 drivers/net/dsa/microchip/ksz_common.c |  3 ++-
 drivers/net/dsa/mt7530.c               |  3 ++-
 drivers/net/dsa/mv88e6xxx/chip.c       |  3 ++-
 drivers/net/dsa/ocelot/felix.c         |  3 ++-
 drivers/net/dsa/qca/ar9331.c           |  3 ++-
 drivers/net/dsa/qca8k.c                |  3 ++-
 drivers/net/dsa/realtek/rtl8365mb.c    |  3 ++-
 drivers/net/dsa/sja1105/sja1105_main.c |  3 ++-
 drivers/net/dsa/xrs700x/xrs700x.c      |  3 ++-
 include/net/dsa.h                      |  3 ++-
 net/dsa/port.c                         | 23 +++++++++++++++++------
 15 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 48cf344750ff..fe75b84ab791 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1310,7 +1310,8 @@ void b53_port_event(struct dsa_switch *ds, int port)
 EXPORT_SYMBOL(b53_port_event);
 
 static void b53_phylink_get_caps(struct dsa_switch *ds, int port,
-				 struct phylink_config *config)
+				 struct phylink_config *config,
+				 phy_interface_t *default_interface)
 {
 	struct b53_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index be0edfa093d0..18a3847bd82b 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -713,7 +713,8 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port)
 }
 
 static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
-				struct phylink_config *config)
+				struct phylink_config *config,
+				phy_interface_t *default_interface)
 {
 	unsigned long *interfaces = config->supported_interfaces;
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
index ac1f3b3a7040..ff78f580bb14 100644
--- a/drivers/net/dsa/hirschmann/hellcreek.c
+++ b/drivers/net/dsa/hirschmann/hellcreek.c
@@ -1462,7 +1462,8 @@ static void hellcreek_teardown(struct dsa_switch *ds)
 }
 
 static void hellcreek_phylink_get_caps(struct dsa_switch *ds, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	struct hellcreek *hellcreek = ds->priv;
 
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index e531b93f3cb2..a43dabfa5453 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -1492,7 +1492,8 @@ static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 }
 
 static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
-					  struct phylink_config *config)
+					  struct phylink_config *config,
+					  phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0:
@@ -1525,7 +1526,8 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
 }
 
 static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
-					  struct phylink_config *config)
+					  struct phylink_config *config,
+					  phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0:
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 28d7cb2ce98f..4329e29a1695 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -721,7 +721,8 @@ static int ksz_check_device_id(struct ksz_device *dev)
 }
 
 static void ksz_phylink_get_caps(struct dsa_switch *ds, int port,
-				 struct phylink_config *config)
+				 struct phylink_config *config,
+				 phy_interface_t *default_interface)
 {
 	struct ksz_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 835807911be0..dab308e454e3 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2914,7 +2914,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 }
 
 static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
-				    struct phylink_config *config)
+				    struct phylink_config *config,
+				    phy_interface_t *default_interface)
 {
 	struct mt7530_priv *priv = ds->priv;
 
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 37b649501500..f98be98551ef 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -819,7 +819,8 @@ static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 }
 
 static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
-			       struct phylink_config *config)
+			       struct phylink_config *config,
+			       phy_interface_t *default_interface)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 859196898a7d..0c1ac902b110 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -937,7 +937,8 @@ static int felix_vlan_del(struct dsa_switch *ds, int port,
 }
 
 static void felix_phylink_get_caps(struct dsa_switch *ds, int port,
-				   struct phylink_config *config)
+				   struct phylink_config *config,
+				   phy_interface_t *default_interface)
 {
 	struct ocelot *ocelot = ds->priv;
 
diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c
index 0796b7cf8cae..19e95dabe5b9 100644
--- a/drivers/net/dsa/qca/ar9331.c
+++ b/drivers/net/dsa/qca/ar9331.c
@@ -501,7 +501,8 @@ static enum dsa_tag_protocol ar9331_sw_get_tag_protocol(struct dsa_switch *ds,
 }
 
 static void ar9331_sw_phylink_get_caps(struct dsa_switch *ds, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 		MAC_10 | MAC_100;
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 1cbb05b0323f..beccd8338c81 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -1749,7 +1749,8 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 }
 
 static void qca8k_phylink_get_caps(struct dsa_switch *ds, int port,
-				   struct phylink_config *config)
+				   struct phylink_config *config,
+				   phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0: /* 1st CPU port */
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index da31d8b839ac..7bf420c2b083 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -1024,7 +1024,8 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port,
 }
 
 static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	const struct rtl8365mb_extint *extint =
 		rtl8365mb_get_port_extint(ds->priv, port);
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index b253e27bcfb4..e15033177643 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1390,7 +1390,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
 }
 
 static void sja1105_phylink_get_caps(struct dsa_switch *ds, int port,
-				     struct phylink_config *config)
+				     struct phylink_config *config,
+				     phy_interface_t *default_interface)
 {
 	struct sja1105_private *priv = ds->priv;
 	struct sja1105_xmii_params_entry *mii;
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index 3887ed33c5fe..214a1dd670c2 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -443,7 +443,8 @@ static void xrs700x_teardown(struct dsa_switch *ds)
 }
 
 static void xrs700x_phylink_get_caps(struct dsa_switch *ds, int port,
-				     struct phylink_config *config)
+				     struct phylink_config *config,
+				     phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0:
diff --git a/include/net/dsa.h b/include/net/dsa.h
index b902b31bebce..7c6870d2c607 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -852,7 +852,8 @@ struct dsa_switch_ops {
 	 * PHYLINK integration
 	 */
 	void	(*phylink_get_caps)(struct dsa_switch *ds, int port,
-				    struct phylink_config *config);
+				    struct phylink_config *config,
+				    phy_interface_t *default_interface);
 	void	(*phylink_validate)(struct dsa_switch *ds, int port,
 				    unsigned long *supported,
 				    struct phylink_link_state *state);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 3738f2d40a0b..35b4e1f8dc05 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1524,13 +1524,9 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
 int dsa_port_phylink_create(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
-	phy_interface_t mode;
+	phy_interface_t mode, def_mode;
 	int err;
 
-	err = of_get_phy_mode(dp->dn, &mode);
-	if (err)
-		mode = PHY_INTERFACE_MODE_NA;
-
 	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
 	 * an indicator of a legacy phylink driver.
 	 */
@@ -1538,8 +1534,23 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 	    ds->ops->phylink_mac_an_restart)
 		dp->pl_config.legacy_pre_march2020 = true;
 
+	def_mode = PHY_INTERFACE_MODE_NA;
 	if (ds->ops->phylink_get_caps)
-		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
+		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config,
+					  &def_mode);
+
+	err = of_get_phy_mode(dp->dn, &mode);
+	if (err) {
+		/* We must not set the default mode for user ports as a PHY
+		 * overrides the NA mode in phylink. Setting it here would
+		 * prevent the interface mode being updated.
+		 */
+		if (dp->type == DSA_PORT_TYPE_CPU ||
+		    dp->type == DSA_PORT_TYPE_DSA)
+			mode = def_mode;
+		else
+			mode = PHY_INTERFACE_MODE_NA;
+	}
 
 	dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
 				mode, &dsa_port_phylink_mac_ops);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 1/5] net: dsa: add support for retrieving the interface mode
@ 2022-07-05  9:47   ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:47 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

DSA port bindings allow for an optional phy interface mode. When an
interface mode is not specified, DSA uses the NA interface mode type.

However, phylink needs to know the parameters of the link, and this
will become especially important when using phylink for ports that
are devoid of all properties except the required "reg" property, so
that phylink can select the maximum supported link settings. Without
knowing the interface mode, phylink can't truely know the maximum
link speed.

Update the prototype for the phylink_get_caps method to allow drivers
to report this information back to DSA, and update all DSA
implementations function declarations to cater for this change. No
code is added to the implementations.

Reviewed-by: Marek Behún <kabel@kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/b53/b53_common.c       |  3 ++-
 drivers/net/dsa/bcm_sf2.c              |  3 ++-
 drivers/net/dsa/hirschmann/hellcreek.c |  3 ++-
 drivers/net/dsa/lantiq_gswip.c         |  6 ++++--
 drivers/net/dsa/microchip/ksz_common.c |  3 ++-
 drivers/net/dsa/mt7530.c               |  3 ++-
 drivers/net/dsa/mv88e6xxx/chip.c       |  3 ++-
 drivers/net/dsa/ocelot/felix.c         |  3 ++-
 drivers/net/dsa/qca/ar9331.c           |  3 ++-
 drivers/net/dsa/qca8k.c                |  3 ++-
 drivers/net/dsa/realtek/rtl8365mb.c    |  3 ++-
 drivers/net/dsa/sja1105/sja1105_main.c |  3 ++-
 drivers/net/dsa/xrs700x/xrs700x.c      |  3 ++-
 include/net/dsa.h                      |  3 ++-
 net/dsa/port.c                         | 23 +++++++++++++++++------
 15 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 48cf344750ff..fe75b84ab791 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1310,7 +1310,8 @@ void b53_port_event(struct dsa_switch *ds, int port)
 EXPORT_SYMBOL(b53_port_event);
 
 static void b53_phylink_get_caps(struct dsa_switch *ds, int port,
-				 struct phylink_config *config)
+				 struct phylink_config *config,
+				 phy_interface_t *default_interface)
 {
 	struct b53_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index be0edfa093d0..18a3847bd82b 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -713,7 +713,8 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port)
 }
 
 static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
-				struct phylink_config *config)
+				struct phylink_config *config,
+				phy_interface_t *default_interface)
 {
 	unsigned long *interfaces = config->supported_interfaces;
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
index ac1f3b3a7040..ff78f580bb14 100644
--- a/drivers/net/dsa/hirschmann/hellcreek.c
+++ b/drivers/net/dsa/hirschmann/hellcreek.c
@@ -1462,7 +1462,8 @@ static void hellcreek_teardown(struct dsa_switch *ds)
 }
 
 static void hellcreek_phylink_get_caps(struct dsa_switch *ds, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	struct hellcreek *hellcreek = ds->priv;
 
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index e531b93f3cb2..a43dabfa5453 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -1492,7 +1492,8 @@ static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 }
 
 static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
-					  struct phylink_config *config)
+					  struct phylink_config *config,
+					  phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0:
@@ -1525,7 +1526,8 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
 }
 
 static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
-					  struct phylink_config *config)
+					  struct phylink_config *config,
+					  phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0:
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 28d7cb2ce98f..4329e29a1695 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -721,7 +721,8 @@ static int ksz_check_device_id(struct ksz_device *dev)
 }
 
 static void ksz_phylink_get_caps(struct dsa_switch *ds, int port,
-				 struct phylink_config *config)
+				 struct phylink_config *config,
+				 phy_interface_t *default_interface)
 {
 	struct ksz_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 835807911be0..dab308e454e3 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2914,7 +2914,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 }
 
 static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
-				    struct phylink_config *config)
+				    struct phylink_config *config,
+				    phy_interface_t *default_interface)
 {
 	struct mt7530_priv *priv = ds->priv;
 
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 37b649501500..f98be98551ef 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -819,7 +819,8 @@ static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 }
 
 static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
-			       struct phylink_config *config)
+			       struct phylink_config *config,
+			       phy_interface_t *default_interface)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 859196898a7d..0c1ac902b110 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -937,7 +937,8 @@ static int felix_vlan_del(struct dsa_switch *ds, int port,
 }
 
 static void felix_phylink_get_caps(struct dsa_switch *ds, int port,
-				   struct phylink_config *config)
+				   struct phylink_config *config,
+				   phy_interface_t *default_interface)
 {
 	struct ocelot *ocelot = ds->priv;
 
diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c
index 0796b7cf8cae..19e95dabe5b9 100644
--- a/drivers/net/dsa/qca/ar9331.c
+++ b/drivers/net/dsa/qca/ar9331.c
@@ -501,7 +501,8 @@ static enum dsa_tag_protocol ar9331_sw_get_tag_protocol(struct dsa_switch *ds,
 }
 
 static void ar9331_sw_phylink_get_caps(struct dsa_switch *ds, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 		MAC_10 | MAC_100;
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 1cbb05b0323f..beccd8338c81 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -1749,7 +1749,8 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 }
 
 static void qca8k_phylink_get_caps(struct dsa_switch *ds, int port,
-				   struct phylink_config *config)
+				   struct phylink_config *config,
+				   phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0: /* 1st CPU port */
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index da31d8b839ac..7bf420c2b083 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -1024,7 +1024,8 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port,
 }
 
 static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	const struct rtl8365mb_extint *extint =
 		rtl8365mb_get_port_extint(ds->priv, port);
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index b253e27bcfb4..e15033177643 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1390,7 +1390,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
 }
 
 static void sja1105_phylink_get_caps(struct dsa_switch *ds, int port,
-				     struct phylink_config *config)
+				     struct phylink_config *config,
+				     phy_interface_t *default_interface)
 {
 	struct sja1105_private *priv = ds->priv;
 	struct sja1105_xmii_params_entry *mii;
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index 3887ed33c5fe..214a1dd670c2 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -443,7 +443,8 @@ static void xrs700x_teardown(struct dsa_switch *ds)
 }
 
 static void xrs700x_phylink_get_caps(struct dsa_switch *ds, int port,
-				     struct phylink_config *config)
+				     struct phylink_config *config,
+				     phy_interface_t *default_interface)
 {
 	switch (port) {
 	case 0:
diff --git a/include/net/dsa.h b/include/net/dsa.h
index b902b31bebce..7c6870d2c607 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -852,7 +852,8 @@ struct dsa_switch_ops {
 	 * PHYLINK integration
 	 */
 	void	(*phylink_get_caps)(struct dsa_switch *ds, int port,
-				    struct phylink_config *config);
+				    struct phylink_config *config,
+				    phy_interface_t *default_interface);
 	void	(*phylink_validate)(struct dsa_switch *ds, int port,
 				    unsigned long *supported,
 				    struct phylink_link_state *state);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 3738f2d40a0b..35b4e1f8dc05 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1524,13 +1524,9 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
 int dsa_port_phylink_create(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
-	phy_interface_t mode;
+	phy_interface_t mode, def_mode;
 	int err;
 
-	err = of_get_phy_mode(dp->dn, &mode);
-	if (err)
-		mode = PHY_INTERFACE_MODE_NA;
-
 	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
 	 * an indicator of a legacy phylink driver.
 	 */
@@ -1538,8 +1534,23 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 	    ds->ops->phylink_mac_an_restart)
 		dp->pl_config.legacy_pre_march2020 = true;
 
+	def_mode = PHY_INTERFACE_MODE_NA;
 	if (ds->ops->phylink_get_caps)
-		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
+		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config,
+					  &def_mode);
+
+	err = of_get_phy_mode(dp->dn, &mode);
+	if (err) {
+		/* We must not set the default mode for user ports as a PHY
+		 * overrides the NA mode in phylink. Setting it here would
+		 * prevent the interface mode being updated.
+		 */
+		if (dp->type == DSA_PORT_TYPE_CPU ||
+		    dp->type == DSA_PORT_TYPE_DSA)
+			mode = def_mode;
+		else
+			mode = PHY_INTERFACE_MODE_NA;
+	}
 
 	dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
 				mode, &dsa_port_phylink_mac_ops);
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 2/5] net: dsa: mv88e6xxx: report the default interface mode for the port
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-05  9:47   ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:47 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

Report the maximum speed interface mode for the port, or if we don't
have that information, the hardware configured interface mode for
the port.

This allows phylink to know which interface mode CPU and DSA ports
are operating, which will be necessary when we want to select the
maximum speed for the port (required for such ports without a PHY or
fixed-link specified in firmware.)

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 83 +++++++++++++++++++++++---------
 drivers/net/dsa/mv88e6xxx/chip.h |  3 +-
 2 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index f98be98551ef..877407bc09de 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -578,7 +578,8 @@ static const u8 mv88e6185_phy_interface_modes[] = {
 };
 
 static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	u8 cmode = chip->ports[port].cmode;
 
@@ -588,23 +589,29 @@ static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
 	} else {
 		if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
-		    mv88e6185_phy_interface_modes[cmode])
+		    mv88e6185_phy_interface_modes[cmode]) {
 			__set_bit(mv88e6185_phy_interface_modes[cmode],
 				  config->supported_interfaces);
+			*default_interface =
+				mv88e6185_phy_interface_modes[cmode];
+		}
 
 		config->mac_capabilities |= MAC_1000FD;
 	}
 }
 
 static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	u8 cmode = chip->ports[port].cmode;
 
 	if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
-	    mv88e6185_phy_interface_modes[cmode])
+	    mv88e6185_phy_interface_modes[cmode]) {
 		__set_bit(mv88e6185_phy_interface_modes[cmode],
 			  config->supported_interfaces);
+		*default_interface = mv88e6185_phy_interface_modes[cmode];
+	}
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
 				   MAC_1000FD;
@@ -616,6 +623,7 @@ static const u8 mv88e6xxx_phy_interface_modes[] = {
 	[MV88E6XXX_PORT_STS_CMODE_GMII]		= PHY_INTERFACE_MODE_GMII,
 	[MV88E6XXX_PORT_STS_CMODE_RMII_PHY]	= PHY_INTERFACE_MODE_RMII,
 	[MV88E6XXX_PORT_STS_CMODE_RMII]		= PHY_INTERFACE_MODE_RMII,
+	[MV88E6XXX_PORT_STS_CMODE_RGMII]	= PHY_INTERFACE_MODE_RGMII,
 	[MV88E6XXX_PORT_STS_CMODE_100BASEX]	= PHY_INTERFACE_MODE_100BASEX,
 	[MV88E6XXX_PORT_STS_CMODE_1000BASEX]	= PHY_INTERFACE_MODE_1000BASEX,
 	[MV88E6XXX_PORT_STS_CMODE_SGMII]	= PHY_INTERFACE_MODE_SGMII,
@@ -625,22 +633,32 @@ static const u8 mv88e6xxx_phy_interface_modes[] = {
 	 */
 };
 
-static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported)
+static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported,
+				      phy_interface_t *default_interface)
 {
+	phy_interface_t interface;
+
 	if (cmode < ARRAY_SIZE(mv88e6xxx_phy_interface_modes) &&
-	    mv88e6xxx_phy_interface_modes[cmode])
-		__set_bit(mv88e6xxx_phy_interface_modes[cmode], supported);
-	else if (cmode == MV88E6XXX_PORT_STS_CMODE_RGMII)
-		phy_interface_set_rgmii(supported);
+	    mv88e6xxx_phy_interface_modes[cmode]) {
+		interface = mv88e6xxx_phy_interface_modes[cmode];
+		if (interface == PHY_INTERFACE_MODE_RGMII)
+			phy_interface_set_rgmii(supported);
+		else
+			__set_bit(interface, supported);
+		if (default_interface)
+			*default_interface = interface;
+	}
 }
 
 static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
 }
@@ -676,13 +694,15 @@ static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
 }
 
 static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 	int err, cmode;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
 				   MAC_1000FD;
@@ -702,19 +722,21 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 			dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
 				port);
 		else
-			mv88e6xxx_translate_cmode(cmode, supported);
+			mv88e6xxx_translate_cmode(cmode, supported, NULL);
 unlock:
 		mv88e6xxx_reg_unlock(chip);
 	}
 }
 
 static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	/* No ethtool bits for 200Mbps */
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
@@ -726,17 +748,21 @@ static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
 		__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
 
+		*default_interface = PHY_INTERFACE_MODE_2500BASEX;
+
 		config->mac_capabilities |= MAC_2500FD;
 	}
 }
 
 static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	/* No ethtool bits for 200Mbps */
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
@@ -748,16 +774,19 @@ static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
 		__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
 
+		*default_interface = PHY_INTERFACE_MODE_2500BASEX;
+
 		config->mac_capabilities |= MAC_2500FD;
 	}
 }
 
 static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-					struct phylink_config *config)
+					struct phylink_config *config,
+					phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
-	mv88e6390_phylink_get_caps(chip, port, config);
+	mv88e6390_phylink_get_caps(chip, port, config, default_interface);
 
 	/* For the 6x90X, ports 2-7 can be in automedia mode.
 	 * (Note that 6x90 doesn't support RXAUI nor XAUI).
@@ -783,18 +812,22 @@ static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_XAUI, supported);
 		__set_bit(PHY_INTERFACE_MODE_RXAUI, supported);
 
+		*default_interface = PHY_INTERFACE_MODE_XAUI;
+
 		config->mac_capabilities |= MAC_10000FD;
 	}
 }
 
 static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-					struct phylink_config *config)
+					struct phylink_config *config,
+					phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 	bool is_6191x =
 		chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
 
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
 				   MAC_1000FD;
@@ -812,6 +845,8 @@ static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 			/* FIXME: USXGMII is not supported yet */
 			/* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
 
+			*default_interface = PHY_INTERFACE_MODE_10GBASER;
+
 			config->mac_capabilities |= MAC_2500FD | MAC_5000FD |
 				MAC_10000FD;
 		}
@@ -823,8 +858,10 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
 			       phy_interface_t *default_interface)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
+	u8 cmode = chip->ports[port].cmode;
 
-	chip->info->ops->phylink_get_caps(chip, port, config);
+	chip->info->ops->phylink_get_caps(chip, port, config,
+					  default_interface);
 
 	/* Internal ports need GMII for PHYLIB */
 	if (mv88e6xxx_phy_is_internal(ds, port))
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index e693154cf803..4518c17c1b9b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -643,7 +643,8 @@ struct mv88e6xxx_ops {
 
 	/* Phylink */
 	void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
-				 struct phylink_config *config);
+				 struct phylink_config *config,
+				 phy_interface_t *default_interface);
 
 	/* Max Frame Size */
 	int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 2/5] net: dsa: mv88e6xxx: report the default interface mode for the port
@ 2022-07-05  9:47   ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:47 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

Report the maximum speed interface mode for the port, or if we don't
have that information, the hardware configured interface mode for
the port.

This allows phylink to know which interface mode CPU and DSA ports
are operating, which will be necessary when we want to select the
maximum speed for the port (required for such ports without a PHY or
fixed-link specified in firmware.)

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 83 +++++++++++++++++++++++---------
 drivers/net/dsa/mv88e6xxx/chip.h |  3 +-
 2 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index f98be98551ef..877407bc09de 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -578,7 +578,8 @@ static const u8 mv88e6185_phy_interface_modes[] = {
 };
 
 static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	u8 cmode = chip->ports[port].cmode;
 
@@ -588,23 +589,29 @@ static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
 	} else {
 		if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
-		    mv88e6185_phy_interface_modes[cmode])
+		    mv88e6185_phy_interface_modes[cmode]) {
 			__set_bit(mv88e6185_phy_interface_modes[cmode],
 				  config->supported_interfaces);
+			*default_interface =
+				mv88e6185_phy_interface_modes[cmode];
+		}
 
 		config->mac_capabilities |= MAC_1000FD;
 	}
 }
 
 static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	u8 cmode = chip->ports[port].cmode;
 
 	if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
-	    mv88e6185_phy_interface_modes[cmode])
+	    mv88e6185_phy_interface_modes[cmode]) {
 		__set_bit(mv88e6185_phy_interface_modes[cmode],
 			  config->supported_interfaces);
+		*default_interface = mv88e6185_phy_interface_modes[cmode];
+	}
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
 				   MAC_1000FD;
@@ -616,6 +623,7 @@ static const u8 mv88e6xxx_phy_interface_modes[] = {
 	[MV88E6XXX_PORT_STS_CMODE_GMII]		= PHY_INTERFACE_MODE_GMII,
 	[MV88E6XXX_PORT_STS_CMODE_RMII_PHY]	= PHY_INTERFACE_MODE_RMII,
 	[MV88E6XXX_PORT_STS_CMODE_RMII]		= PHY_INTERFACE_MODE_RMII,
+	[MV88E6XXX_PORT_STS_CMODE_RGMII]	= PHY_INTERFACE_MODE_RGMII,
 	[MV88E6XXX_PORT_STS_CMODE_100BASEX]	= PHY_INTERFACE_MODE_100BASEX,
 	[MV88E6XXX_PORT_STS_CMODE_1000BASEX]	= PHY_INTERFACE_MODE_1000BASEX,
 	[MV88E6XXX_PORT_STS_CMODE_SGMII]	= PHY_INTERFACE_MODE_SGMII,
@@ -625,22 +633,32 @@ static const u8 mv88e6xxx_phy_interface_modes[] = {
 	 */
 };
 
-static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported)
+static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported,
+				      phy_interface_t *default_interface)
 {
+	phy_interface_t interface;
+
 	if (cmode < ARRAY_SIZE(mv88e6xxx_phy_interface_modes) &&
-	    mv88e6xxx_phy_interface_modes[cmode])
-		__set_bit(mv88e6xxx_phy_interface_modes[cmode], supported);
-	else if (cmode == MV88E6XXX_PORT_STS_CMODE_RGMII)
-		phy_interface_set_rgmii(supported);
+	    mv88e6xxx_phy_interface_modes[cmode]) {
+		interface = mv88e6xxx_phy_interface_modes[cmode];
+		if (interface == PHY_INTERFACE_MODE_RGMII)
+			phy_interface_set_rgmii(supported);
+		else
+			__set_bit(interface, supported);
+		if (default_interface)
+			*default_interface = interface;
+	}
 }
 
 static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
 }
@@ -676,13 +694,15 @@ static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
 }
 
 static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 	int err, cmode;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
 				   MAC_1000FD;
@@ -702,19 +722,21 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 			dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
 				port);
 		else
-			mv88e6xxx_translate_cmode(cmode, supported);
+			mv88e6xxx_translate_cmode(cmode, supported, NULL);
 unlock:
 		mv88e6xxx_reg_unlock(chip);
 	}
 }
 
 static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	/* No ethtool bits for 200Mbps */
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
@@ -726,17 +748,21 @@ static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
 		__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
 
+		*default_interface = PHY_INTERFACE_MODE_2500BASEX;
+
 		config->mac_capabilities |= MAC_2500FD;
 	}
 }
 
 static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+				       struct phylink_config *config,
+				       phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
 	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	/* No ethtool bits for 200Mbps */
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
@@ -748,16 +774,19 @@ static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
 		__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
 
+		*default_interface = PHY_INTERFACE_MODE_2500BASEX;
+
 		config->mac_capabilities |= MAC_2500FD;
 	}
 }
 
 static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-					struct phylink_config *config)
+					struct phylink_config *config,
+					phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 
-	mv88e6390_phylink_get_caps(chip, port, config);
+	mv88e6390_phylink_get_caps(chip, port, config, default_interface);
 
 	/* For the 6x90X, ports 2-7 can be in automedia mode.
 	 * (Note that 6x90 doesn't support RXAUI nor XAUI).
@@ -783,18 +812,22 @@ static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 		__set_bit(PHY_INTERFACE_MODE_XAUI, supported);
 		__set_bit(PHY_INTERFACE_MODE_RXAUI, supported);
 
+		*default_interface = PHY_INTERFACE_MODE_XAUI;
+
 		config->mac_capabilities |= MAC_10000FD;
 	}
 }
 
 static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-					struct phylink_config *config)
+					struct phylink_config *config,
+					phy_interface_t *default_interface)
 {
 	unsigned long *supported = config->supported_interfaces;
 	bool is_6191x =
 		chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
 
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported,
+				  default_interface);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
 				   MAC_1000FD;
@@ -812,6 +845,8 @@ static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 			/* FIXME: USXGMII is not supported yet */
 			/* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
 
+			*default_interface = PHY_INTERFACE_MODE_10GBASER;
+
 			config->mac_capabilities |= MAC_2500FD | MAC_5000FD |
 				MAC_10000FD;
 		}
@@ -823,8 +858,10 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
 			       phy_interface_t *default_interface)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
+	u8 cmode = chip->ports[port].cmode;
 
-	chip->info->ops->phylink_get_caps(chip, port, config);
+	chip->info->ops->phylink_get_caps(chip, port, config,
+					  default_interface);
 
 	/* Internal ports need GMII for PHYLIB */
 	if (mv88e6xxx_phy_is_internal(ds, port))
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index e693154cf803..4518c17c1b9b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -643,7 +643,8 @@ struct mv88e6xxx_ops {
 
 	/* Phylink */
 	void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
-				 struct phylink_config *config);
+				 struct phylink_config *config,
+				 phy_interface_t *default_interface);
 
 	/* Max Frame Size */
 	int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu);
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 3/5] net: phylink: split out interface to caps translation
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-05  9:47   ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:47 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

phylink_get_linkmodes() translates the interface mode into a set of
speed and duplex capabilities which are masked with the MAC modes
to then derive the link modes that are available.

Split out the initial transformation into a new function
phylink_interface_to_caps(), which will be useful when setting the
maximum fixed link speed.

Reviewed-by: Marek Behún <kabel@kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 48f0b9b39491..2069fc902e19 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -296,18 +296,7 @@ static void phylink_caps_to_linkmodes(unsigned long *linkmodes,
 	}
 }
 
-/**
- * phylink_get_linkmodes() - get acceptable link modes
- * @linkmodes: ethtool linkmode mask (must be already initialised)
- * @interface: phy interface mode defined by &typedef phy_interface_t
- * @mac_capabilities: bitmask of MAC capabilities
- *
- * Set all possible pause, speed and duplex linkmodes in @linkmodes that
- * are supported by the @interface mode and @mac_capabilities. @linkmodes
- * must have been initialised previously.
- */
-void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
-			   unsigned long mac_capabilities)
+static unsigned long phylink_interface_to_caps(phy_interface_t interface)
 {
 	unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
 
@@ -381,6 +370,24 @@ void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
 		break;
 	}
 
+	return caps;
+}
+
+/**
+ * phylink_get_linkmodes() - get acceptable link modes
+ * @linkmodes: ethtool linkmode mask (must be already initialised)
+ * @interface: phy interface mode defined by &typedef phy_interface_t
+ * @mac_capabilities: bitmask of MAC capabilities
+ *
+ * Set all possible pause, speed and duplex linkmodes in @linkmodes that
+ * are supported by the @interface mode and @mac_capabilities. @linkmodes
+ * must have been initialised previously.
+ */
+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
+			   unsigned long mac_capabilities)
+{
+	unsigned long caps = phylink_interface_to_caps(interface);
+
 	phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities);
 }
 EXPORT_SYMBOL_GPL(phylink_get_linkmodes);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 3/5] net: phylink: split out interface to caps translation
@ 2022-07-05  9:47   ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:47 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

phylink_get_linkmodes() translates the interface mode into a set of
speed and duplex capabilities which are masked with the MAC modes
to then derive the link modes that are available.

Split out the initial transformation into a new function
phylink_interface_to_caps(), which will be useful when setting the
maximum fixed link speed.

Reviewed-by: Marek Behún <kabel@kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 48f0b9b39491..2069fc902e19 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -296,18 +296,7 @@ static void phylink_caps_to_linkmodes(unsigned long *linkmodes,
 	}
 }
 
-/**
- * phylink_get_linkmodes() - get acceptable link modes
- * @linkmodes: ethtool linkmode mask (must be already initialised)
- * @interface: phy interface mode defined by &typedef phy_interface_t
- * @mac_capabilities: bitmask of MAC capabilities
- *
- * Set all possible pause, speed and duplex linkmodes in @linkmodes that
- * are supported by the @interface mode and @mac_capabilities. @linkmodes
- * must have been initialised previously.
- */
-void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
-			   unsigned long mac_capabilities)
+static unsigned long phylink_interface_to_caps(phy_interface_t interface)
 {
 	unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
 
@@ -381,6 +370,24 @@ void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
 		break;
 	}
 
+	return caps;
+}
+
+/**
+ * phylink_get_linkmodes() - get acceptable link modes
+ * @linkmodes: ethtool linkmode mask (must be already initialised)
+ * @interface: phy interface mode defined by &typedef phy_interface_t
+ * @mac_capabilities: bitmask of MAC capabilities
+ *
+ * Set all possible pause, speed and duplex linkmodes in @linkmodes that
+ * are supported by the @interface mode and @mac_capabilities. @linkmodes
+ * must have been initialised previously.
+ */
+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
+			   unsigned long mac_capabilities)
+{
+	unsigned long caps = phylink_interface_to_caps(interface);
+
 	phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities);
 }
 EXPORT_SYMBOL_GPL(phylink_get_linkmodes);
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 4/5] net: phylink: add phylink_set_max_fixed_link()
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-05  9:48   ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:48 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

Add a function for DSA to use to configure phylink, in the absence of
any other configuration, to a fixed link operating at the maximum
supported link speed.

This is needed so we can support phylink usage on CPU and DSA ports.

We use the default interface that the DSA driver provides (if any)
otherwise we attempt to find the first supported interface that gives
the maximum speed for the link.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 119 ++++++++++++++++++++++++++++++++++++++
 include/linux/phylink.h   |   5 ++
 2 files changed, 124 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2069fc902e19..7ed3b2c3a359 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1333,6 +1333,125 @@ void phylink_destroy(struct phylink *pl)
 }
 EXPORT_SYMBOL_GPL(phylink_destroy);
 
+static struct {
+	unsigned long fd_mask;
+	unsigned long hd_mask;
+	int speed;
+} phylink_caps_speeds[] = {
+	{ MAC_400000FD, 0,          SPEED_400000 },
+	{ MAC_200000FD, 0,          SPEED_200000 },
+	{ MAC_100000FD, 0,          SPEED_100000 },
+	{ MAC_56000FD,  0,          SPEED_56000  },
+	{ MAC_50000FD,  0,          SPEED_50000  },
+	{ MAC_40000FD,  0,          SPEED_40000  },
+	{ MAC_25000FD,  0,          SPEED_40000  },
+	{ MAC_20000FD,  0,          SPEED_20000  },
+	{ MAC_10000FD,  0,          SPEED_10000  },
+	{ MAC_5000FD,   0,          SPEED_5000   },
+	{ MAC_2500FD,   0,          SPEED_2500   },
+	{ MAC_1000FD,   MAC_1000HD, SPEED_1000   },
+	{ MAC_100FD,    MAC_100HD,  SPEED_100    },
+	{ MAC_10FD,     MAC_10HD,   SPEED_10     },
+};
+
+/**
+ * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Set a maximum speed fixed-link configuration for the chosen interface
+ * mode and MAC capabilities for the phylink instance. If the interface mode
+ * is PHY_INTERFACE_MODE_NA, then search the supported interfaces bitmap for
+ * the first interface that gives the fastest supported speed.
+ *
+ * This is only valid for use immediately after phylink_create(). Must not
+ * be used at any other time.
+ *
+ * The user must have initialised mac_capabilities and set a valid interface.
+ */
+int phylink_set_max_fixed_link(struct phylink *pl)
+{
+	phy_interface_t intf, interface;
+	unsigned long caps, max_caps;
+	unsigned long *interfaces;
+	int speed, duplex;
+	int i;
+
+	interface = pl->link_interface;
+
+	phylink_dbg(pl, "sif=%*pbl if=%d(%s) cap=%lx\n",
+		    (int)PHY_INTERFACE_MODE_MAX,
+		    pl->config->supported_interfaces,
+		    interface, phy_modes(interface),
+		    pl->config->mac_capabilities);
+
+	/* If we are not in PHY mode, or have a PHY, or have a SFP bus,
+	 * then we must not default to a fixed link.
+	 */
+	if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
+		return -EBUSY;
+
+	if (interface != PHY_INTERFACE_MODE_NA) {
+		/* Get the speed/duplex capabilities and reduce according to the
+		 * specified interface mode.
+		 */
+		caps = pl->config->mac_capabilities;
+		caps &= phylink_interface_to_caps(interface);
+	} else {
+		interfaces = pl->config->supported_interfaces;
+		max_caps = 0;
+
+		/* Find the supported interface mode which gives the maximum
+		 * speed.
+		 */
+		for_each_set_bit(intf, interfaces, PHY_INTERFACE_MODE_MAX) {
+			caps = pl->config->mac_capabilities;
+			caps &= phylink_interface_to_caps(intf);
+			if (caps > max_caps) {
+				max_caps = caps;
+				interface = intf;
+			}
+		}
+
+		caps = max_caps;
+	}
+
+	caps &= ~(MAC_SYM_PAUSE | MAC_ASYM_PAUSE);
+
+	/* If there are no capabilities, then we are not using this default. */
+	if (!caps)
+		return -EINVAL;
+
+	/* Decode to fastest speed and duplex */
+	duplex = DUPLEX_UNKNOWN;
+	speed = SPEED_UNKNOWN;
+	for (i = 0; i < ARRAY_SIZE(phylink_caps_speeds); i++) {
+		if (caps & phylink_caps_speeds[i].fd_mask) {
+			duplex = DUPLEX_FULL;
+			speed = phylink_caps_speeds[i].speed;
+			break;
+		} else if (caps & phylink_caps_speeds[i].hd_mask) {
+			duplex = DUPLEX_HALF;
+			speed = phylink_caps_speeds[i].speed;
+			break;
+		}
+	}
+
+	/* If we didn't find anything, bail. */
+	if (speed == SPEED_UNKNOWN)
+		return -EINVAL;
+
+	pl->link_interface = interface;
+	pl->link_config.interface = interface;
+	pl->link_config.speed = speed;
+	pl->link_config.duplex = duplex;
+	pl->link_config.link = 1;
+	pl->cfg_link_an_mode = MLO_AN_FIXED;
+	pl->cur_link_an_mode = MLO_AN_FIXED;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(phylink_set_max_fixed_link);
+
 static void phylink_phy_change(struct phy_device *phydev, bool up)
 {
 	struct phylink *pl = phydev->phylink;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6d06896fc20d..9e2fb476d19c 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -23,6 +23,9 @@ enum {
 
 	MAC_SYM_PAUSE	= BIT(0),
 	MAC_ASYM_PAUSE	= BIT(1),
+	/* These speed bits must be sorted according to speed for
+	 * phylink_set_max_fixed_link()
+	 */
 	MAC_10HD	= BIT(2),
 	MAC_10FD	= BIT(3),
 	MAC_10		= MAC_10HD | MAC_10FD,
@@ -529,6 +532,8 @@ struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
 			       const struct phylink_mac_ops *mac_ops);
 void phylink_destroy(struct phylink *);
 
+int phylink_set_max_fixed_link(struct phylink *pl);
+
 int phylink_connect_phy(struct phylink *, struct phy_device *);
 int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags);
 int phylink_fwnode_phy_connect(struct phylink *pl,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 4/5] net: phylink: add phylink_set_max_fixed_link()
@ 2022-07-05  9:48   ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:48 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

Add a function for DSA to use to configure phylink, in the absence of
any other configuration, to a fixed link operating at the maximum
supported link speed.

This is needed so we can support phylink usage on CPU and DSA ports.

We use the default interface that the DSA driver provides (if any)
otherwise we attempt to find the first supported interface that gives
the maximum speed for the link.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 119 ++++++++++++++++++++++++++++++++++++++
 include/linux/phylink.h   |   5 ++
 2 files changed, 124 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2069fc902e19..7ed3b2c3a359 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1333,6 +1333,125 @@ void phylink_destroy(struct phylink *pl)
 }
 EXPORT_SYMBOL_GPL(phylink_destroy);
 
+static struct {
+	unsigned long fd_mask;
+	unsigned long hd_mask;
+	int speed;
+} phylink_caps_speeds[] = {
+	{ MAC_400000FD, 0,          SPEED_400000 },
+	{ MAC_200000FD, 0,          SPEED_200000 },
+	{ MAC_100000FD, 0,          SPEED_100000 },
+	{ MAC_56000FD,  0,          SPEED_56000  },
+	{ MAC_50000FD,  0,          SPEED_50000  },
+	{ MAC_40000FD,  0,          SPEED_40000  },
+	{ MAC_25000FD,  0,          SPEED_40000  },
+	{ MAC_20000FD,  0,          SPEED_20000  },
+	{ MAC_10000FD,  0,          SPEED_10000  },
+	{ MAC_5000FD,   0,          SPEED_5000   },
+	{ MAC_2500FD,   0,          SPEED_2500   },
+	{ MAC_1000FD,   MAC_1000HD, SPEED_1000   },
+	{ MAC_100FD,    MAC_100HD,  SPEED_100    },
+	{ MAC_10FD,     MAC_10HD,   SPEED_10     },
+};
+
+/**
+ * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Set a maximum speed fixed-link configuration for the chosen interface
+ * mode and MAC capabilities for the phylink instance. If the interface mode
+ * is PHY_INTERFACE_MODE_NA, then search the supported interfaces bitmap for
+ * the first interface that gives the fastest supported speed.
+ *
+ * This is only valid for use immediately after phylink_create(). Must not
+ * be used at any other time.
+ *
+ * The user must have initialised mac_capabilities and set a valid interface.
+ */
+int phylink_set_max_fixed_link(struct phylink *pl)
+{
+	phy_interface_t intf, interface;
+	unsigned long caps, max_caps;
+	unsigned long *interfaces;
+	int speed, duplex;
+	int i;
+
+	interface = pl->link_interface;
+
+	phylink_dbg(pl, "sif=%*pbl if=%d(%s) cap=%lx\n",
+		    (int)PHY_INTERFACE_MODE_MAX,
+		    pl->config->supported_interfaces,
+		    interface, phy_modes(interface),
+		    pl->config->mac_capabilities);
+
+	/* If we are not in PHY mode, or have a PHY, or have a SFP bus,
+	 * then we must not default to a fixed link.
+	 */
+	if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
+		return -EBUSY;
+
+	if (interface != PHY_INTERFACE_MODE_NA) {
+		/* Get the speed/duplex capabilities and reduce according to the
+		 * specified interface mode.
+		 */
+		caps = pl->config->mac_capabilities;
+		caps &= phylink_interface_to_caps(interface);
+	} else {
+		interfaces = pl->config->supported_interfaces;
+		max_caps = 0;
+
+		/* Find the supported interface mode which gives the maximum
+		 * speed.
+		 */
+		for_each_set_bit(intf, interfaces, PHY_INTERFACE_MODE_MAX) {
+			caps = pl->config->mac_capabilities;
+			caps &= phylink_interface_to_caps(intf);
+			if (caps > max_caps) {
+				max_caps = caps;
+				interface = intf;
+			}
+		}
+
+		caps = max_caps;
+	}
+
+	caps &= ~(MAC_SYM_PAUSE | MAC_ASYM_PAUSE);
+
+	/* If there are no capabilities, then we are not using this default. */
+	if (!caps)
+		return -EINVAL;
+
+	/* Decode to fastest speed and duplex */
+	duplex = DUPLEX_UNKNOWN;
+	speed = SPEED_UNKNOWN;
+	for (i = 0; i < ARRAY_SIZE(phylink_caps_speeds); i++) {
+		if (caps & phylink_caps_speeds[i].fd_mask) {
+			duplex = DUPLEX_FULL;
+			speed = phylink_caps_speeds[i].speed;
+			break;
+		} else if (caps & phylink_caps_speeds[i].hd_mask) {
+			duplex = DUPLEX_HALF;
+			speed = phylink_caps_speeds[i].speed;
+			break;
+		}
+	}
+
+	/* If we didn't find anything, bail. */
+	if (speed == SPEED_UNKNOWN)
+		return -EINVAL;
+
+	pl->link_interface = interface;
+	pl->link_config.interface = interface;
+	pl->link_config.speed = speed;
+	pl->link_config.duplex = duplex;
+	pl->link_config.link = 1;
+	pl->cfg_link_an_mode = MLO_AN_FIXED;
+	pl->cur_link_an_mode = MLO_AN_FIXED;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(phylink_set_max_fixed_link);
+
 static void phylink_phy_change(struct phy_device *phydev, bool up)
 {
 	struct phylink *pl = phydev->phylink;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6d06896fc20d..9e2fb476d19c 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -23,6 +23,9 @@ enum {
 
 	MAC_SYM_PAUSE	= BIT(0),
 	MAC_ASYM_PAUSE	= BIT(1),
+	/* These speed bits must be sorted according to speed for
+	 * phylink_set_max_fixed_link()
+	 */
 	MAC_10HD	= BIT(2),
 	MAC_10FD	= BIT(3),
 	MAC_10		= MAC_10HD | MAC_10FD,
@@ -529,6 +532,8 @@ struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
 			       const struct phylink_mac_ops *mac_ops);
 void phylink_destroy(struct phylink *);
 
+int phylink_set_max_fixed_link(struct phylink *pl);
+
 int phylink_connect_phy(struct phylink *, struct phy_device *);
 int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags);
 int phylink_fwnode_phy_connect(struct phylink *pl,
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-05  9:48   ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:48 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

Currently, we only use phylink for CPU and DSA ports if there is a
fixed-link specification, or a PHY specified. The reason for this
behaviour is that when neither is specified, there was no way for
phylink to know the link parameters.

Now that we have phylink_set_max_link_speed() (which has become
possible through the addition of mac_capabilities) we now have the
ability to know the maximum link speed for a specific link, and can
use phylink for this case as well.

However, we need all DSA drivers to provide mac_capabilities for this
to work, and either report the default interface to be used for a port
or have filled in supported_interfaces, so that we can select a maximum
speed appropriate for the interface mode that hardware may have
configured for the port. Any drivers that do not meet these
requirements are likely to break.

This is especially important with the conversion of DSA drivers to
phylink_pcs, as the PCS code only gets called if we are using
phylink for the port.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 50 ++++----------------------------
 drivers/net/dsa/mv88e6xxx/chip.h |  3 --
 drivers/net/dsa/mv88e6xxx/port.c | 32 --------------------
 drivers/net/dsa/mv88e6xxx/port.h |  5 ----
 net/dsa/port.c                   | 24 ++++++++-------
 5 files changed, 18 insertions(+), 96 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 877407bc09de..7fd89239a7a7 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3315,9 +3315,8 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
 {
 	struct device_node *phy_handle = NULL;
 	struct dsa_switch *ds = chip->ds;
-	phy_interface_t mode;
 	struct dsa_port *dp;
-	int tx_amp, speed;
+	int tx_amp;
 	int err;
 	u16 reg;
 
@@ -3326,40 +3325,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
 
 	dp = dsa_to_port(ds, port);
 
-	/* MAC Forcing register: don't force link, speed, duplex or flow control
-	 * state to any particular values on physical ports, but force the CPU
-	 * port and all DSA ports to their maximum bandwidth and full duplex.
-	 */
-	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
-		unsigned long caps = dp->pl_config.mac_capabilities;
-
-		if (chip->info->ops->port_max_speed_mode)
-			mode = chip->info->ops->port_max_speed_mode(port);
-		else
-			mode = PHY_INTERFACE_MODE_NA;
-
-		if (caps & MAC_10000FD)
-			speed = SPEED_10000;
-		else if (caps & MAC_5000FD)
-			speed = SPEED_5000;
-		else if (caps & MAC_2500FD)
-			speed = SPEED_2500;
-		else if (caps & MAC_1000)
-			speed = SPEED_1000;
-		else if (caps & MAC_100)
-			speed = SPEED_100;
-		else
-			speed = SPEED_10;
-
-		err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
-					       speed, DUPLEX_FULL,
-					       PAUSE_OFF, mode);
-	} else {
-		err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
-					       SPEED_UNFORCED, DUPLEX_UNFORCED,
-					       PAUSE_ON,
-					       PHY_INTERFACE_MODE_NA);
-	}
+	err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
+				       SPEED_UNFORCED, DUPLEX_UNFORCED,
+				       PAUSE_ON,
+				       PHY_INTERFACE_MODE_NA);
 	if (err)
 		return err;
 
@@ -4307,7 +4276,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
 	.port_tag_remap = mv88e6095_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4700,7 +4668,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4763,7 +4730,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4826,7 +4792,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
 	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
@@ -4991,7 +4956,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5142,7 +5106,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
 	.port_tag_remap = mv88e6095_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5365,7 +5328,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5432,7 +5394,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5498,7 +5459,6 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6393x_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6393x_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6393x_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 4518c17c1b9b..a3b7cfe3eb23 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -502,9 +502,6 @@ struct mv88e6xxx_ops {
 	int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex);
 
-	/* What interface mode should be used for maximum speed? */
-	phy_interface_t (*port_max_speed_mode)(int port);
-
 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
 
 	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 90c55f23b7c9..47e21f3c437a 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -333,14 +333,6 @@ int mv88e6341_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 					       duplex);
 }
 
-phy_interface_t mv88e6341_port_max_speed_mode(int port)
-{
-	if (port == 5)
-		return PHY_INTERFACE_MODE_2500BASEX;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
 int mv88e6352_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				    int speed, int duplex)
@@ -372,14 +364,6 @@ int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 					       duplex);
 }
 
-phy_interface_t mv88e6390_port_max_speed_mode(int port)
-{
-	if (port == 9 || port == 10)
-		return PHY_INTERFACE_MODE_2500BASEX;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
 int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex)
@@ -394,14 +378,6 @@ int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 					       duplex);
 }
 
-phy_interface_t mv88e6390x_port_max_speed_mode(int port)
-{
-	if (port == 9 || port == 10)
-		return PHY_INTERFACE_MODE_XAUI;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 /* Support 10, 100, 200, 1000, 2500, 5000, 10000 Mbps (e.g. 88E6393X)
  * Function mv88e6xxx_port_set_speed_duplex() can't be used as the register
  * values for speeds 2500 & 5000 conflict.
@@ -491,14 +467,6 @@ int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 	return 0;
 }
 
-phy_interface_t mv88e6393x_port_max_speed_mode(int port)
-{
-	if (port == 0 || port == 9 || port == 10)
-		return PHY_INTERFACE_MODE_10GBASER;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 				    phy_interface_t mode, bool force)
 {
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index cb04243f37c1..2a5741a44e97 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -357,11 +357,6 @@ int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex);
 
-phy_interface_t mv88e6341_port_max_speed_mode(int port);
-phy_interface_t mv88e6390_port_max_speed_mode(int port);
-phy_interface_t mv88e6390x_port_max_speed_mode(int port);
-phy_interface_t mv88e6393x_port_max_speed_mode(int port);
-
 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
 
 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 35b4e1f8dc05..34487e62eb03 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
 	phy_interface_t mode, def_mode;
+	struct device_node *phy_np;
 	int err;
 
 	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
@@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 		return PTR_ERR(dp->pl);
 	}
 
+	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
+		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
+		of_node_put(phy_np);
+		if (!phy_np)
+			err = phylink_set_max_fixed_link(dp->pl);
+	}
+
 	return 0;
 }
 
@@ -1663,20 +1671,14 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
 int dsa_port_link_register_of(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
-	struct device_node *phy_np;
 	int port = dp->index;
 
 	if (!ds->ops->adjust_link) {
-		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
-		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
-			if (ds->ops->phylink_mac_link_down)
-				ds->ops->phylink_mac_link_down(ds, port,
-					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
-			of_node_put(phy_np);
-			return dsa_port_phylink_register(dp);
-		}
-		of_node_put(phy_np);
-		return 0;
+		if (ds->ops->phylink_mac_link_down)
+			ds->ops->phylink_mac_link_down(ds, port,
+				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
+
+		return dsa_port_phylink_register(dp);
 	}
 
 	dev_warn(ds->dev,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-05  9:48   ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-05  9:48 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin __ipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Vladimir Oltean, Woojung Huh,
	Marek Behún

Currently, we only use phylink for CPU and DSA ports if there is a
fixed-link specification, or a PHY specified. The reason for this
behaviour is that when neither is specified, there was no way for
phylink to know the link parameters.

Now that we have phylink_set_max_link_speed() (which has become
possible through the addition of mac_capabilities) we now have the
ability to know the maximum link speed for a specific link, and can
use phylink for this case as well.

However, we need all DSA drivers to provide mac_capabilities for this
to work, and either report the default interface to be used for a port
or have filled in supported_interfaces, so that we can select a maximum
speed appropriate for the interface mode that hardware may have
configured for the port. Any drivers that do not meet these
requirements are likely to break.

This is especially important with the conversion of DSA drivers to
phylink_pcs, as the PCS code only gets called if we are using
phylink for the port.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 50 ++++----------------------------
 drivers/net/dsa/mv88e6xxx/chip.h |  3 --
 drivers/net/dsa/mv88e6xxx/port.c | 32 --------------------
 drivers/net/dsa/mv88e6xxx/port.h |  5 ----
 net/dsa/port.c                   | 24 ++++++++-------
 5 files changed, 18 insertions(+), 96 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 877407bc09de..7fd89239a7a7 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3315,9 +3315,8 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
 {
 	struct device_node *phy_handle = NULL;
 	struct dsa_switch *ds = chip->ds;
-	phy_interface_t mode;
 	struct dsa_port *dp;
-	int tx_amp, speed;
+	int tx_amp;
 	int err;
 	u16 reg;
 
@@ -3326,40 +3325,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
 
 	dp = dsa_to_port(ds, port);
 
-	/* MAC Forcing register: don't force link, speed, duplex or flow control
-	 * state to any particular values on physical ports, but force the CPU
-	 * port and all DSA ports to their maximum bandwidth and full duplex.
-	 */
-	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
-		unsigned long caps = dp->pl_config.mac_capabilities;
-
-		if (chip->info->ops->port_max_speed_mode)
-			mode = chip->info->ops->port_max_speed_mode(port);
-		else
-			mode = PHY_INTERFACE_MODE_NA;
-
-		if (caps & MAC_10000FD)
-			speed = SPEED_10000;
-		else if (caps & MAC_5000FD)
-			speed = SPEED_5000;
-		else if (caps & MAC_2500FD)
-			speed = SPEED_2500;
-		else if (caps & MAC_1000)
-			speed = SPEED_1000;
-		else if (caps & MAC_100)
-			speed = SPEED_100;
-		else
-			speed = SPEED_10;
-
-		err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
-					       speed, DUPLEX_FULL,
-					       PAUSE_OFF, mode);
-	} else {
-		err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
-					       SPEED_UNFORCED, DUPLEX_UNFORCED,
-					       PAUSE_ON,
-					       PHY_INTERFACE_MODE_NA);
-	}
+	err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
+				       SPEED_UNFORCED, DUPLEX_UNFORCED,
+				       PAUSE_ON,
+				       PHY_INTERFACE_MODE_NA);
 	if (err)
 		return err;
 
@@ -4307,7 +4276,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
 	.port_tag_remap = mv88e6095_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4700,7 +4668,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4763,7 +4730,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4826,7 +4792,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
 	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
@@ -4991,7 +4956,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5142,7 +5106,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
 	.port_tag_remap = mv88e6095_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5365,7 +5328,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5432,7 +5394,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6352_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5498,7 +5459,6 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
 	.port_sync_link = mv88e6xxx_port_sync_link,
 	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
 	.port_set_speed_duplex = mv88e6393x_port_set_speed_duplex,
-	.port_max_speed_mode = mv88e6393x_port_max_speed_mode,
 	.port_tag_remap = mv88e6390_port_tag_remap,
 	.port_set_policy = mv88e6393x_port_set_policy,
 	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 4518c17c1b9b..a3b7cfe3eb23 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -502,9 +502,6 @@ struct mv88e6xxx_ops {
 	int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex);
 
-	/* What interface mode should be used for maximum speed? */
-	phy_interface_t (*port_max_speed_mode)(int port);
-
 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
 
 	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 90c55f23b7c9..47e21f3c437a 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -333,14 +333,6 @@ int mv88e6341_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 					       duplex);
 }
 
-phy_interface_t mv88e6341_port_max_speed_mode(int port)
-{
-	if (port == 5)
-		return PHY_INTERFACE_MODE_2500BASEX;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
 int mv88e6352_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				    int speed, int duplex)
@@ -372,14 +364,6 @@ int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 					       duplex);
 }
 
-phy_interface_t mv88e6390_port_max_speed_mode(int port)
-{
-	if (port == 9 || port == 10)
-		return PHY_INTERFACE_MODE_2500BASEX;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
 int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex)
@@ -394,14 +378,6 @@ int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 					       duplex);
 }
 
-phy_interface_t mv88e6390x_port_max_speed_mode(int port)
-{
-	if (port == 9 || port == 10)
-		return PHY_INTERFACE_MODE_XAUI;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 /* Support 10, 100, 200, 1000, 2500, 5000, 10000 Mbps (e.g. 88E6393X)
  * Function mv88e6xxx_port_set_speed_duplex() can't be used as the register
  * values for speeds 2500 & 5000 conflict.
@@ -491,14 +467,6 @@ int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 	return 0;
 }
 
-phy_interface_t mv88e6393x_port_max_speed_mode(int port)
-{
-	if (port == 0 || port == 9 || port == 10)
-		return PHY_INTERFACE_MODE_10GBASER;
-
-	return PHY_INTERFACE_MODE_NA;
-}
-
 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 				    phy_interface_t mode, bool force)
 {
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index cb04243f37c1..2a5741a44e97 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -357,11 +357,6 @@ int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex);
 
-phy_interface_t mv88e6341_port_max_speed_mode(int port);
-phy_interface_t mv88e6390_port_max_speed_mode(int port);
-phy_interface_t mv88e6390x_port_max_speed_mode(int port);
-phy_interface_t mv88e6393x_port_max_speed_mode(int port);
-
 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
 
 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 35b4e1f8dc05..34487e62eb03 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
 	phy_interface_t mode, def_mode;
+	struct device_node *phy_np;
 	int err;
 
 	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
@@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 		return PTR_ERR(dp->pl);
 	}
 
+	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
+		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
+		of_node_put(phy_np);
+		if (!phy_np)
+			err = phylink_set_max_fixed_link(dp->pl);
+	}
+
 	return 0;
 }
 
@@ -1663,20 +1671,14 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
 int dsa_port_link_register_of(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
-	struct device_node *phy_np;
 	int port = dp->index;
 
 	if (!ds->ops->adjust_link) {
-		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
-		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
-			if (ds->ops->phylink_mac_link_down)
-				ds->ops->phylink_mac_link_down(ds, port,
-					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
-			of_node_put(phy_np);
-			return dsa_port_phylink_register(dp);
-		}
-		of_node_put(phy_np);
-		return 0;
+		if (ds->ops->phylink_mac_link_down)
+			ds->ops->phylink_mac_link_down(ds, port,
+				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
+
+		return dsa_port_phylink_register(dp);
 	}
 
 	dev_warn(ds->dev,
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 2/5] net: dsa: mv88e6xxx: report the default interface mode for the port
  2022-07-05  9:47   ` Russell King (Oracle)
@ 2022-07-05 10:55     ` Marek Behún
  -1 siblings, 0 replies; 65+ messages in thread
From: Marek Behún @ 2022-07-05 10:55 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Vladimir Oltean, Woojung Huh

On Tue, 05 Jul 2022 10:47:52 +0100
"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk> wrote:

> Report the maximum speed interface mode for the port, or if we don't
> have that information, the hardware configured interface mode for
> the port.
> 
> This allows phylink to know which interface mode CPU and DSA ports
> are operating, which will be necessary when we want to select the
> maximum speed for the port (required for such ports without a PHY or
> fixed-link specified in firmware.)
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Reviewed-by: Marek Behún <kabel@kernel.org>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 2/5] net: dsa: mv88e6xxx: report the default interface mode for the port
@ 2022-07-05 10:55     ` Marek Behún
  0 siblings, 0 replies; 65+ messages in thread
From: Marek Behún @ 2022-07-05 10:55 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Vladimir Oltean, Woojung Huh

On Tue, 05 Jul 2022 10:47:52 +0100
"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk> wrote:

> Report the maximum speed interface mode for the port, or if we don't
> have that information, the hardware configured interface mode for
> the port.
> 
> This allows phylink to know which interface mode CPU and DSA ports
> are operating, which will be necessary when we want to select the
> maximum speed for the port (required for such ports without a PHY or
> fixed-link specified in firmware.)
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Reviewed-by: Marek Behún <kabel@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 4/5] net: phylink: add phylink_set_max_fixed_link()
  2022-07-05  9:48   ` Russell King (Oracle)
@ 2022-07-05 10:58     ` Marek Behún
  -1 siblings, 0 replies; 65+ messages in thread
From: Marek Behún @ 2022-07-05 10:58 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Vladimir Oltean, Woojung Huh

On Tue, 05 Jul 2022 10:48:02 +0100
"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk> wrote:

> Add a function for DSA to use to configure phylink, in the absence of
> any other configuration, to a fixed link operating at the maximum
> supported link speed.
> 
> This is needed so we can support phylink usage on CPU and DSA ports.
> 
> We use the default interface that the DSA driver provides (if any)
> otherwise we attempt to find the first supported interface that gives
> the maximum speed for the link.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Reviewed-by: Marek Behún <kabel@kernel.org>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 4/5] net: phylink: add phylink_set_max_fixed_link()
@ 2022-07-05 10:58     ` Marek Behún
  0 siblings, 0 replies; 65+ messages in thread
From: Marek Behún @ 2022-07-05 10:58 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Vladimir Oltean, Woojung Huh

On Tue, 05 Jul 2022 10:48:02 +0100
"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk> wrote:

> Add a function for DSA to use to configure phylink, in the absence of
> any other configuration, to a fixed link operating at the maximum
> supported link speed.
> 
> This is needed so we can support phylink usage on CPU and DSA ports.
> 
> We use the default interface that the DSA driver provides (if any)
> otherwise we attempt to find the first supported interface that gives
> the maximum speed for the link.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Reviewed-by: Marek Behún <kabel@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-05 16:42   ` Florian Fainelli
  -1 siblings, 0 replies; 65+ messages in thread
From: Florian Fainelli @ 2022-07-05 16:42 UTC (permalink / raw)
  To: Russell King (Oracle), Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, George McCollister,
	Hauke Mehrtens, Jakub Kicinski, Kurt Kanzenbach, Landen Chao,
	Linus Walleij, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

On 7/5/22 02:46, Russell King (Oracle) wrote:
> A new revision of the series which incorporates changes that Marek
> suggested. Specifically, the changes are:
> 
> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>     default interface rather than re-using port_max_speed_mode()
> 
> 2. Patch 4 - if no default interface is provided, use the supported
>     interface mask to search for the first interface that gives the
>     fastest speed.
> 
> 3. Patch 5 - now also removes the port_max_speed_mode() method

This was tested with bcm_sf2.c and b53_srab.b and did not cause 
regressions, however we do have a 'fixed-link' property for the CPU port 
(always have had one), so there was no regression expected.

See answers to your RFC v1 below.

> 
>   drivers/net/dsa/b53/b53_common.c       |   3 +-
>   drivers/net/dsa/bcm_sf2.c              |   3 +-
>   drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
>   drivers/net/dsa/lantiq_gswip.c         |   6 +-
>   drivers/net/dsa/microchip/ksz_common.c |   3 +-
>   drivers/net/dsa/mt7530.c               |   3 +-
>   drivers/net/dsa/mv88e6xxx/chip.c       | 136 +++++++++++++++---------------
>   drivers/net/dsa/mv88e6xxx/chip.h       |   6 +-
>   drivers/net/dsa/mv88e6xxx/port.c       |  32 -------
>   drivers/net/dsa/mv88e6xxx/port.h       |   5 --
>   drivers/net/dsa/ocelot/felix.c         |   3 +-
>   drivers/net/dsa/qca/ar9331.c           |   3 +-
>   drivers/net/dsa/qca8k.c                |   3 +-
>   drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
>   drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
>   drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
>   drivers/net/phy/phylink.c              | 150 ++++++++++++++++++++++++++++++---
>   include/linux/phylink.h                |   5 ++
>   include/net/dsa.h                      |   3 +-
>   net/dsa/port.c                         |  47 +++++++----
>   20 files changed, 270 insertions(+), 153 deletions(-)
> 
> On Wed, Jun 29, 2022 at 01:49:57PM +0100, Russell King (Oracle) wrote:
>> Mostly the same as the previous RFC, except:
>>
>> 1) incldues the phylink_validate_mask_caps() function
>> 2) has Marek's idea of searching the supported_interfaces bitmap for the
>>     fastest interface we can use
>> 3) includes a final patch to add a print which will be useful to hear
>>     from people testing it.
>>
>> Some of the questions from the original RFC remain though, so I've
>> included that text below. I'm guessing as they remain unanswered that
>> no one has any opinions on them?
>>
>>   drivers/net/dsa/b53/b53_common.c       |   3 +-
>>   drivers/net/dsa/bcm_sf2.c              |   3 +-
>>   drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
>>   drivers/net/dsa/lantiq_gswip.c         |   6 +-
>>   drivers/net/dsa/microchip/ksz_common.c |   3 +-
>>   drivers/net/dsa/mt7530.c               |   3 +-
>>   drivers/net/dsa/mv88e6xxx/chip.c       |  53 ++++--------
>>   drivers/net/dsa/ocelot/felix.c         |   3 +-
>>   drivers/net/dsa/qca/ar9331.c           |   3 +-
>>   drivers/net/dsa/qca8k.c                |   3 +-
>>   drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
>>   drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
>>   drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
>>   drivers/net/phy/phylink.c              | 148 ++++++++++++++++++++++++++++++---
>>   include/linux/phylink.h                |   5 ++
>>   include/net/dsa.h                      |   3 +-
>>   net/dsa/port.c                         |  47 +++++++----
>>   17 files changed, 215 insertions(+), 80 deletions(-)
>>
>> On Fri, Jun 24, 2022 at 12:41:26PM +0100, Russell King (Oracle) wrote:
>>> Hi,
>>>
>>> Currently, the core DSA code conditionally uses phylink for CPU and DSA
>>> ports depending on whether the firmware specifies a fixed-link or a PHY.
>>> If either of these are specified, then phylink is used for these ports,
>>> otherwise phylink is not, and we rely on the DSA drivers to "do the
>>> right thing". However, this detail is not mentioned in the DT binding,
>>> but Andrew has said that this behaviour has always something that DSA
>>> wants.
>>>
>>> mv88e6xxx has had support for this for a long time with its "SPEED_MAX"
>>> thing, which I recently reworked to make use of the mac_capabilities in
>>> preparation to solving this more fully.
>>>
>>> This series is an experiment to solve this properly, and it does this
>>> in two steps.
>>>
>>> The first step consists of the first two patches. Phylink needs to
>>> know the PHY interface mode that is being used so it can (a) pass the
>>> right mode into the MAC/PCS etc and (b) know the properties of the
>>> link and therefore which speeds can be supported across it.
>>>
>>> In order to achieve this, the DSA phylink_get_caps() method has an
>>> extra argument added to it so that DSA drivers can report the
>>> interface mode that they will be using for this port back to the core
>>> DSA code, thereby allowing phylink to be initialised with the correct
>>> interface mode.
>>>
>>> Note that this can only be used for CPU and DSA ports as "user" ports
>>> need a different behaviour - they rely on getting the interface mode
>>> from phylib, which will only happen if phylink is initialised with
>>> PHY_INTERFACE_MODE_NA. Unfortunately, changing this behaviour is likely
>>> to cause widespread regressions.
>>>
>>> Obvious questions:
>>> 1. Should phylink_get_caps() be augmented in this way, or should it be
>>>     a separate method?
>>>
>>> 2. DSA has traditionally used "interface mode for the maximum supported
>>>     speed on this port" where the interface mode is programmable (via
>>>     its internal port_max_speed_mode() method) but this is only present
>>>     for a few of the sub-drivers. Is reporting the current interface
>>>     mode correct where this method is not implemented?
>>>
>>> The second step is to introduce a function that allows phylink to be
>>> reconfigured after creation time to operate at max-speed fixed-link
>>> mode for the PHY interface mode, also using the MAC capabilities to
>>> determine the speed and duplex mode we should be using.
>>>
>>> Obvious questions:
>>> 1. Should we be allowing half-duplex for this?

Except for testing, not sure I do see a point as it should not be a 
configuration being used at all?

>>> 2. If we do allow half-duplex, should we prefer fastest speed over
>>>     duplex setting, or should we prefer fastest full-duplex speed
>>>     over any half-duplex?

I would opt for fastest speed over duplex setting.

>>> 3. How do we sanely switch DSA from its current behaviour to always
>>>     using phylink for these ports without breakage - this is the
>>>     difficult one, because it's not obvious which drivers have been
>>>     coded to either work around this quirk of the DSA implementation.
>>>     For example, if we start forcing the link down before calling
>>>     dsa_port_phylink_create(), and we then fail to set max-fixed-link,
>>>     then the CPU/DSA port is going to fail, and we're going to have
>>>     lots of regressions.

Good question, we already have a legacy_pre_march2020 behavior for a 
piece of infrastructure code that is not so old, I doubt that we would 
want to add more of that type of quirk.
-- 
Florian

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-05 16:42   ` Florian Fainelli
  0 siblings, 0 replies; 65+ messages in thread
From: Florian Fainelli @ 2022-07-05 16:42 UTC (permalink / raw)
  To: Russell King (Oracle), Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, George McCollister,
	Hauke Mehrtens, Jakub Kicinski, Kurt Kanzenbach, Landen Chao,
	Linus Walleij, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

On 7/5/22 02:46, Russell King (Oracle) wrote:
> A new revision of the series which incorporates changes that Marek
> suggested. Specifically, the changes are:
> 
> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>     default interface rather than re-using port_max_speed_mode()
> 
> 2. Patch 4 - if no default interface is provided, use the supported
>     interface mask to search for the first interface that gives the
>     fastest speed.
> 
> 3. Patch 5 - now also removes the port_max_speed_mode() method

This was tested with bcm_sf2.c and b53_srab.b and did not cause 
regressions, however we do have a 'fixed-link' property for the CPU port 
(always have had one), so there was no regression expected.

See answers to your RFC v1 below.

> 
>   drivers/net/dsa/b53/b53_common.c       |   3 +-
>   drivers/net/dsa/bcm_sf2.c              |   3 +-
>   drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
>   drivers/net/dsa/lantiq_gswip.c         |   6 +-
>   drivers/net/dsa/microchip/ksz_common.c |   3 +-
>   drivers/net/dsa/mt7530.c               |   3 +-
>   drivers/net/dsa/mv88e6xxx/chip.c       | 136 +++++++++++++++---------------
>   drivers/net/dsa/mv88e6xxx/chip.h       |   6 +-
>   drivers/net/dsa/mv88e6xxx/port.c       |  32 -------
>   drivers/net/dsa/mv88e6xxx/port.h       |   5 --
>   drivers/net/dsa/ocelot/felix.c         |   3 +-
>   drivers/net/dsa/qca/ar9331.c           |   3 +-
>   drivers/net/dsa/qca8k.c                |   3 +-
>   drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
>   drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
>   drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
>   drivers/net/phy/phylink.c              | 150 ++++++++++++++++++++++++++++++---
>   include/linux/phylink.h                |   5 ++
>   include/net/dsa.h                      |   3 +-
>   net/dsa/port.c                         |  47 +++++++----
>   20 files changed, 270 insertions(+), 153 deletions(-)
> 
> On Wed, Jun 29, 2022 at 01:49:57PM +0100, Russell King (Oracle) wrote:
>> Mostly the same as the previous RFC, except:
>>
>> 1) incldues the phylink_validate_mask_caps() function
>> 2) has Marek's idea of searching the supported_interfaces bitmap for the
>>     fastest interface we can use
>> 3) includes a final patch to add a print which will be useful to hear
>>     from people testing it.
>>
>> Some of the questions from the original RFC remain though, so I've
>> included that text below. I'm guessing as they remain unanswered that
>> no one has any opinions on them?
>>
>>   drivers/net/dsa/b53/b53_common.c       |   3 +-
>>   drivers/net/dsa/bcm_sf2.c              |   3 +-
>>   drivers/net/dsa/hirschmann/hellcreek.c |   3 +-
>>   drivers/net/dsa/lantiq_gswip.c         |   6 +-
>>   drivers/net/dsa/microchip/ksz_common.c |   3 +-
>>   drivers/net/dsa/mt7530.c               |   3 +-
>>   drivers/net/dsa/mv88e6xxx/chip.c       |  53 ++++--------
>>   drivers/net/dsa/ocelot/felix.c         |   3 +-
>>   drivers/net/dsa/qca/ar9331.c           |   3 +-
>>   drivers/net/dsa/qca8k.c                |   3 +-
>>   drivers/net/dsa/realtek/rtl8365mb.c    |   3 +-
>>   drivers/net/dsa/sja1105/sja1105_main.c |   3 +-
>>   drivers/net/dsa/xrs700x/xrs700x.c      |   3 +-
>>   drivers/net/phy/phylink.c              | 148 ++++++++++++++++++++++++++++++---
>>   include/linux/phylink.h                |   5 ++
>>   include/net/dsa.h                      |   3 +-
>>   net/dsa/port.c                         |  47 +++++++----
>>   17 files changed, 215 insertions(+), 80 deletions(-)
>>
>> On Fri, Jun 24, 2022 at 12:41:26PM +0100, Russell King (Oracle) wrote:
>>> Hi,
>>>
>>> Currently, the core DSA code conditionally uses phylink for CPU and DSA
>>> ports depending on whether the firmware specifies a fixed-link or a PHY.
>>> If either of these are specified, then phylink is used for these ports,
>>> otherwise phylink is not, and we rely on the DSA drivers to "do the
>>> right thing". However, this detail is not mentioned in the DT binding,
>>> but Andrew has said that this behaviour has always something that DSA
>>> wants.
>>>
>>> mv88e6xxx has had support for this for a long time with its "SPEED_MAX"
>>> thing, which I recently reworked to make use of the mac_capabilities in
>>> preparation to solving this more fully.
>>>
>>> This series is an experiment to solve this properly, and it does this
>>> in two steps.
>>>
>>> The first step consists of the first two patches. Phylink needs to
>>> know the PHY interface mode that is being used so it can (a) pass the
>>> right mode into the MAC/PCS etc and (b) know the properties of the
>>> link and therefore which speeds can be supported across it.
>>>
>>> In order to achieve this, the DSA phylink_get_caps() method has an
>>> extra argument added to it so that DSA drivers can report the
>>> interface mode that they will be using for this port back to the core
>>> DSA code, thereby allowing phylink to be initialised with the correct
>>> interface mode.
>>>
>>> Note that this can only be used for CPU and DSA ports as "user" ports
>>> need a different behaviour - they rely on getting the interface mode
>>> from phylib, which will only happen if phylink is initialised with
>>> PHY_INTERFACE_MODE_NA. Unfortunately, changing this behaviour is likely
>>> to cause widespread regressions.
>>>
>>> Obvious questions:
>>> 1. Should phylink_get_caps() be augmented in this way, or should it be
>>>     a separate method?
>>>
>>> 2. DSA has traditionally used "interface mode for the maximum supported
>>>     speed on this port" where the interface mode is programmable (via
>>>     its internal port_max_speed_mode() method) but this is only present
>>>     for a few of the sub-drivers. Is reporting the current interface
>>>     mode correct where this method is not implemented?
>>>
>>> The second step is to introduce a function that allows phylink to be
>>> reconfigured after creation time to operate at max-speed fixed-link
>>> mode for the PHY interface mode, also using the MAC capabilities to
>>> determine the speed and duplex mode we should be using.
>>>
>>> Obvious questions:
>>> 1. Should we be allowing half-duplex for this?

Except for testing, not sure I do see a point as it should not be a 
configuration being used at all?

>>> 2. If we do allow half-duplex, should we prefer fastest speed over
>>>     duplex setting, or should we prefer fastest full-duplex speed
>>>     over any half-duplex?

I would opt for fastest speed over duplex setting.

>>> 3. How do we sanely switch DSA from its current behaviour to always
>>>     using phylink for these ports without breakage - this is the
>>>     difficult one, because it's not obvious which drivers have been
>>>     coded to either work around this quirk of the DSA implementation.
>>>     For example, if we start forcing the link down before calling
>>>     dsa_port_phylink_create(), and we then fail to set max-fixed-link,
>>>     then the CPU/DSA port is going to fail, and we're going to have
>>>     lots of regressions.

Good question, we already have a legacy_pre_march2020 behavior for a 
piece of infrastructure code that is not so old, I doubt that we would 
want to add more of that type of quirk.
-- 
Florian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-05 16:42   ` Florian Fainelli
@ 2022-07-06 10:14     ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-06 10:14 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Russell King (Oracle),
	Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh

Hi Florian,

On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
> On 7/5/22 02:46, Russell King (Oracle) wrote:
> > A new revision of the series which incorporates changes that Marek
> > suggested. Specifically, the changes are:
> > 
> > 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
> >     default interface rather than re-using port_max_speed_mode()
> > 
> > 2. Patch 4 - if no default interface is provided, use the supported
> >     interface mask to search for the first interface that gives the
> >     fastest speed.
> > 
> > 3. Patch 5 - now also removes the port_max_speed_mode() method
> 
> This was tested with bcm_sf2.c and b53_srab.b and did not cause regressions,
> however we do have a 'fixed-link' property for the CPU port (always have had
> one), so there was no regression expected.

What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?
Just to make sure I'm simply not seeing something, I compiled and then
decompiled the dtb. We have:

		ethernet@5000 {
			reg = <0x5000 0x1000>;
			phandle = <0x03>;

			mdio {
				#address-cells = <0x01>;
				#size-cells = <0x00>;

				switch@1e {
					compatible = "brcm,bcm53125";
					reg = <0x1e>;
					status = "okay";

					ports {
						#address-cells = <0x01>;
						#size-cells = <0x00>;

						port@0 {
							reg = <0x00>;
							label = "wan";
						};

						port@1 {
							reg = <0x01>;
							label = "lan1";
						};

						port@2 {
							reg = <0x02>;
							label = "lan2";
						};

						port@3 {
							reg = <0x03>;
							label = "lan3";
						};

						port@4 {
							reg = <0x04>;
							label = "lan4";
						};

						port@5 {
							reg = <0x05>;
							label = "cpu";
							ethernet = <0x03>; <- CPU port with no phy-handle, no fixed-link
						};
					};
				};
			};
		};

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-06 10:14     ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-06 10:14 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Russell King (Oracle),
	Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh

Hi Florian,

On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
> On 7/5/22 02:46, Russell King (Oracle) wrote:
> > A new revision of the series which incorporates changes that Marek
> > suggested. Specifically, the changes are:
> > 
> > 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
> >     default interface rather than re-using port_max_speed_mode()
> > 
> > 2. Patch 4 - if no default interface is provided, use the supported
> >     interface mask to search for the first interface that gives the
> >     fastest speed.
> > 
> > 3. Patch 5 - now also removes the port_max_speed_mode() method
> 
> This was tested with bcm_sf2.c and b53_srab.b and did not cause regressions,
> however we do have a 'fixed-link' property for the CPU port (always have had
> one), so there was no regression expected.

What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?
Just to make sure I'm simply not seeing something, I compiled and then
decompiled the dtb. We have:

		ethernet@5000 {
			reg = <0x5000 0x1000>;
			phandle = <0x03>;

			mdio {
				#address-cells = <0x01>;
				#size-cells = <0x00>;

				switch@1e {
					compatible = "brcm,bcm53125";
					reg = <0x1e>;
					status = "okay";

					ports {
						#address-cells = <0x01>;
						#size-cells = <0x00>;

						port@0 {
							reg = <0x00>;
							label = "wan";
						};

						port@1 {
							reg = <0x01>;
							label = "lan1";
						};

						port@2 {
							reg = <0x02>;
							label = "lan2";
						};

						port@3 {
							reg = <0x03>;
							label = "lan3";
						};

						port@4 {
							reg = <0x04>;
							label = "lan4";
						};

						port@5 {
							reg = <0x05>;
							label = "cpu";
							ethernet = <0x03>; <- CPU port with no phy-handle, no fixed-link
						};
					};
				};
			};
		};

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-05  9:48   ` Russell King (Oracle)
@ 2022-07-06 10:26     ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-06 10:26 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

Hello,

On Tue, Jul 05, 2022 at 10:48:07AM +0100, Russell King (Oracle) wrote:
> diff --git a/net/dsa/port.c b/net/dsa/port.c
> index 35b4e1f8dc05..34487e62eb03 100644
> --- a/net/dsa/port.c
> +++ b/net/dsa/port.c
> @@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
>  {
>  	struct dsa_switch *ds = dp->ds;
>  	phy_interface_t mode, def_mode;
> +	struct device_node *phy_np;
>  	int err;
>  
>  	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
> @@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
>  		return PTR_ERR(dp->pl);
>  	}
>  
> +	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
> +		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> +		of_node_put(phy_np);
> +		if (!phy_np)
> +			err = phylink_set_max_fixed_link(dp->pl);

Can we please limit phylink_set_max_link_speed() to just the CPU ports
where a fixed-link property is also missing, not just a phy-handle?
Although to be entirely correct, we can also have MLO_AN_INBAND, which
wouldn't be covered by these 2 checks and would still represent a valid
DT binding.

> +	}
> +
>  	return 0;
>  }
>  
> @@ -1663,20 +1671,14 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
>  int dsa_port_link_register_of(struct dsa_port *dp)
>  {
>  	struct dsa_switch *ds = dp->ds;
> -	struct device_node *phy_np;
>  	int port = dp->index;
>  
>  	if (!ds->ops->adjust_link) {
> -		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> -		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
> -			if (ds->ops->phylink_mac_link_down)
> -				ds->ops->phylink_mac_link_down(ds, port,
> -					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
> -			of_node_put(phy_np);
> -			return dsa_port_phylink_register(dp);
> -		}
> -		of_node_put(phy_np);
> -		return 0;
> +		if (ds->ops->phylink_mac_link_down)
> +			ds->ops->phylink_mac_link_down(ds, port,
> +				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);

Can you please align these arguments to the open bracket?

> +
> +		return dsa_port_phylink_register(dp);
>  	}
>  
>  	dev_warn(ds->dev,
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-06 10:26     ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-06 10:26 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

Hello,

On Tue, Jul 05, 2022 at 10:48:07AM +0100, Russell King (Oracle) wrote:
> diff --git a/net/dsa/port.c b/net/dsa/port.c
> index 35b4e1f8dc05..34487e62eb03 100644
> --- a/net/dsa/port.c
> +++ b/net/dsa/port.c
> @@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
>  {
>  	struct dsa_switch *ds = dp->ds;
>  	phy_interface_t mode, def_mode;
> +	struct device_node *phy_np;
>  	int err;
>  
>  	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
> @@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
>  		return PTR_ERR(dp->pl);
>  	}
>  
> +	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
> +		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> +		of_node_put(phy_np);
> +		if (!phy_np)
> +			err = phylink_set_max_fixed_link(dp->pl);

Can we please limit phylink_set_max_link_speed() to just the CPU ports
where a fixed-link property is also missing, not just a phy-handle?
Although to be entirely correct, we can also have MLO_AN_INBAND, which
wouldn't be covered by these 2 checks and would still represent a valid
DT binding.

> +	}
> +
>  	return 0;
>  }
>  
> @@ -1663,20 +1671,14 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
>  int dsa_port_link_register_of(struct dsa_port *dp)
>  {
>  	struct dsa_switch *ds = dp->ds;
> -	struct device_node *phy_np;
>  	int port = dp->index;
>  
>  	if (!ds->ops->adjust_link) {
> -		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> -		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
> -			if (ds->ops->phylink_mac_link_down)
> -				ds->ops->phylink_mac_link_down(ds, port,
> -					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
> -			of_node_put(phy_np);
> -			return dsa_port_phylink_register(dp);
> -		}
> -		of_node_put(phy_np);
> -		return 0;
> +		if (ds->ops->phylink_mac_link_down)
> +			ds->ops->phylink_mac_link_down(ds, port,
> +				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);

Can you please align these arguments to the open bracket?

> +
> +		return dsa_port_phylink_register(dp);
>  	}
>  
>  	dev_warn(ds->dev,
> -- 
> 2.30.2
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 2/5] net: dsa: mv88e6xxx: report the default interface mode for the port
  2022-07-05  9:47   ` Russell King (Oracle)
  (?)
  (?)
@ 2022-07-06 11:04   ` kernel test robot
  -1 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2022-07-06 11:04 UTC (permalink / raw)
  To: Russell King (Oracle); +Cc: llvm, kbuild-all

Hi "Russell,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on net-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Russell-King-Oracle/net-dsa-add-support-for-retrieving-the-interface-mode/20220705-175304
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 874bdbfe624e577687c2053a26aab44715c68453
config: x86_64-randconfig-a012-20220704 (https://download.01.org/0day-ci/archive/20220706/202207061812.FVnuLMD9-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f553287b588916de09c66e3e32bf75e5060f967f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/9423b094f4b1e0c313bbdd0e65cd0824b51e3016
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Russell-King-Oracle/net-dsa-add-support-for-retrieving-the-interface-mode/20220705-175304
        git checkout 9423b094f4b1e0c313bbdd0e65cd0824b51e3016
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/net/dsa/mv88e6xxx/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/dsa/mv88e6xxx/chip.c:861:5: warning: unused variable 'cmode' [-Wunused-variable]
           u8 cmode = chip->ports[port].cmode;
              ^
   1 warning generated.


vim +/cmode +861 drivers/net/dsa/mv88e6xxx/chip.c

   855	
   856	static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
   857				       struct phylink_config *config,
   858				       phy_interface_t *default_interface)
   859	{
   860		struct mv88e6xxx_chip *chip = ds->priv;
 > 861		u8 cmode = chip->ports[port].cmode;
   862	
   863		chip->info->ops->phylink_get_caps(chip, port, config,
   864						  default_interface);
   865	
   866		/* Internal ports need GMII for PHYLIB */
   867		if (mv88e6xxx_phy_is_internal(ds, port))
   868			__set_bit(PHY_INTERFACE_MODE_GMII,
   869				  config->supported_interfaces);
   870	}
   871	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-06 10:26     ` Vladimir Oltean
@ 2022-07-06 16:24       ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-06 16:24 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> Hello,
> 
> On Tue, Jul 05, 2022 at 10:48:07AM +0100, Russell King (Oracle) wrote:
> > diff --git a/net/dsa/port.c b/net/dsa/port.c
> > index 35b4e1f8dc05..34487e62eb03 100644
> > --- a/net/dsa/port.c
> > +++ b/net/dsa/port.c
> > @@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  {
> >  	struct dsa_switch *ds = dp->ds;
> >  	phy_interface_t mode, def_mode;
> > +	struct device_node *phy_np;
> >  	int err;
> >  
> >  	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
> > @@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  		return PTR_ERR(dp->pl);
> >  	}
> >  
> > +	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
> > +		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +		of_node_put(phy_np);
> > +		if (!phy_np)
> > +			err = phylink_set_max_fixed_link(dp->pl);
> 
> Can we please limit phylink_set_max_link_speed() to just the CPU ports
> where a fixed-link property is also missing, not just a phy-handle?
> Although to be entirely correct, we can also have MLO_AN_INBAND, which
> wouldn't be covered by these 2 checks and would still represent a valid
> DT binding.

phylink_set_max_fixed_link() already excludes itself:

        if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
                return -EBUSY;

intentionally so that if there is anything specified for the port, be
that a fixed link or in-band, then phylink_set_max_fixed_link() errors
out with -EBUSY.

The only case that it can't detect is if there is a PHY that may be
added to phylink at a later time, and that is what the check above
is for.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-06 16:24       ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-06 16:24 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> Hello,
> 
> On Tue, Jul 05, 2022 at 10:48:07AM +0100, Russell King (Oracle) wrote:
> > diff --git a/net/dsa/port.c b/net/dsa/port.c
> > index 35b4e1f8dc05..34487e62eb03 100644
> > --- a/net/dsa/port.c
> > +++ b/net/dsa/port.c
> > @@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  {
> >  	struct dsa_switch *ds = dp->ds;
> >  	phy_interface_t mode, def_mode;
> > +	struct device_node *phy_np;
> >  	int err;
> >  
> >  	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
> > @@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  		return PTR_ERR(dp->pl);
> >  	}
> >  
> > +	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
> > +		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +		of_node_put(phy_np);
> > +		if (!phy_np)
> > +			err = phylink_set_max_fixed_link(dp->pl);
> 
> Can we please limit phylink_set_max_link_speed() to just the CPU ports
> where a fixed-link property is also missing, not just a phy-handle?
> Although to be entirely correct, we can also have MLO_AN_INBAND, which
> wouldn't be covered by these 2 checks and would still represent a valid
> DT binding.

phylink_set_max_fixed_link() already excludes itself:

        if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
                return -EBUSY;

intentionally so that if there is anything specified for the port, be
that a fixed link or in-band, then phylink_set_max_fixed_link() errors
out with -EBUSY.

The only case that it can't detect is if there is a PHY that may be
added to phylink at a later time, and that is what the check above
is for.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-06 10:14     ` Vladimir Oltean
@ 2022-07-06 16:27       ` Florian Fainelli
  -1 siblings, 0 replies; 65+ messages in thread
From: Florian Fainelli @ 2022-07-06 16:27 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh

On 7/6/22 03:14, Vladimir Oltean wrote:
> Hi Florian,
> 
> On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
>> On 7/5/22 02:46, Russell King (Oracle) wrote:
>>> A new revision of the series which incorporates changes that Marek
>>> suggested. Specifically, the changes are:
>>>
>>> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>>>      default interface rather than re-using port_max_speed_mode()
>>>
>>> 2. Patch 4 - if no default interface is provided, use the supported
>>>      interface mask to search for the first interface that gives the
>>>      fastest speed.
>>>
>>> 3. Patch 5 - now also removes the port_max_speed_mode() method
>>
>> This was tested with bcm_sf2.c and b53_srab.b and did not cause regressions,
>> however we do have a 'fixed-link' property for the CPU port (always have had
>> one), so there was no regression expected.
> 
> What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?

You found one of the devices that I do not have access to and did not 
test, thanks. We do expect to run the port at 2GBits/sec on these 
devices however there is no "official" way to advertise that a port can 
run at 2Gbits/sec, as this is not even a "sanctioned" speed. I do have a 
similar device however, so let me run some more tests, we won't see a 
regression however since we do not use the NATP accelerator which would 
be the reason to run the port at 2Gbits/sec.
-- 
Florian

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-06 16:27       ` Florian Fainelli
  0 siblings, 0 replies; 65+ messages in thread
From: Florian Fainelli @ 2022-07-06 16:27 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh

On 7/6/22 03:14, Vladimir Oltean wrote:
> Hi Florian,
> 
> On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
>> On 7/5/22 02:46, Russell King (Oracle) wrote:
>>> A new revision of the series which incorporates changes that Marek
>>> suggested. Specifically, the changes are:
>>>
>>> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>>>      default interface rather than re-using port_max_speed_mode()
>>>
>>> 2. Patch 4 - if no default interface is provided, use the supported
>>>      interface mask to search for the first interface that gives the
>>>      fastest speed.
>>>
>>> 3. Patch 5 - now also removes the port_max_speed_mode() method
>>
>> This was tested with bcm_sf2.c and b53_srab.b and did not cause regressions,
>> however we do have a 'fixed-link' property for the CPU port (always have had
>> one), so there was no regression expected.
> 
> What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?

You found one of the devices that I do not have access to and did not 
test, thanks. We do expect to run the port at 2GBits/sec on these 
devices however there is no "official" way to advertise that a port can 
run at 2Gbits/sec, as this is not even a "sanctioned" speed. I do have a 
similar device however, so let me run some more tests, we won't see a 
regression however since we do not use the NATP accelerator which would 
be the reason to run the port at 2Gbits/sec.
-- 
Florian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-06 17:22   ` Kurt Kanzenbach
  -1 siblings, 0 replies; 65+ messages in thread
From: Kurt Kanzenbach @ 2022-07-06 17:22 UTC (permalink / raw)
  To: Russell King (Oracle), Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski, Landen Chao,
	Linus Walleij, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

[-- Attachment #1: Type: text/plain, Size: 603 bytes --]

Hi Russell,

On Tue Jul 05 2022, Russell King wrote:
> A new revision of the series which incorporates changes that Marek
> suggested. Specifically, the changes are:
>
> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>    default interface rather than re-using port_max_speed_mode()
>
> 2. Patch 4 - if no default interface is provided, use the supported
>    interface mask to search for the first interface that gives the
>    fastest speed.
>
> 3. Patch 5 - now also removes the port_max_speed_mode() method

Tested with hellcreek driver and no problems observed.

Thanks,
Kurt

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-06 17:22   ` Kurt Kanzenbach
  0 siblings, 0 replies; 65+ messages in thread
From: Kurt Kanzenbach @ 2022-07-06 17:22 UTC (permalink / raw)
  To: Russell King (Oracle), Andrew Lunn, Heiner Kallweit
  Cc: Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski, Landen Chao,
	Linus Walleij, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh


[-- Attachment #1.1: Type: text/plain, Size: 603 bytes --]

Hi Russell,

On Tue Jul 05 2022, Russell King wrote:
> A new revision of the series which incorporates changes that Marek
> suggested. Specifically, the changes are:
>
> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>    default interface rather than re-using port_max_speed_mode()
>
> 2. Patch 4 - if no default interface is provided, use the supported
>    interface mask to search for the first interface that gives the
>    fastest speed.
>
> 3. Patch 5 - now also removes the port_max_speed_mode() method

Tested with hellcreek driver and no problems observed.

Thanks,
Kurt

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-06 16:27       ` Florian Fainelli
@ 2022-07-06 19:05         ` Hauke Mehrtens
  -1 siblings, 0 replies; 65+ messages in thread
From: Hauke Mehrtens @ 2022-07-06 19:05 UTC (permalink / raw)
  To: Florian Fainelli, Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, George McCollister, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Woojung Huh

On 7/6/22 18:27, Florian Fainelli wrote:
> On 7/6/22 03:14, Vladimir Oltean wrote:
>> Hi Florian,
>>
>> On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
>>> On 7/5/22 02:46, Russell King (Oracle) wrote:
>>>> A new revision of the series which incorporates changes that Marek
>>>> suggested. Specifically, the changes are:
>>>>
>>>> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>>>>      default interface rather than re-using port_max_speed_mode()
>>>>
>>>> 2. Patch 4 - if no default interface is provided, use the supported
>>>>      interface mask to search for the first interface that gives the
>>>>      fastest speed.
>>>>
>>>> 3. Patch 5 - now also removes the port_max_speed_mode() method
>>>
>>> This was tested with bcm_sf2.c and b53_srab.b and did not cause 
>>> regressions,
>>> however we do have a 'fixed-link' property for the CPU port (always 
>>> have had
>>> one), so there was no regression expected.
>>
>> What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?
> 
> You found one of the devices that I do not have access to and did not 
> test, thanks. We do expect to run the port at 2GBits/sec on these 
> devices however there is no "official" way to advertise that a port can 
> run at 2Gbits/sec, as this is not even a "sanctioned" speed. I do have a 
> similar device however, so let me run some more tests, we won't see a 
> regression however since we do not use the NATP accelerator which would 
> be the reason to run the port at 2Gbits/sec.

I will try this change on some devices with the lantiq gswip driver at 
the weekend.

On the SoC supported by the lantiq gswip driver the switch is integrated 
in the SoC and there is a internal link with more than 1GBit/s 
connecting the switch to the rest of the system. I think it is also 
around 2GBit/s. We can not configure the interface speed or many other 
interface settings for the link between the switch and the CPU. How 
should the device tree ideally look for this setup?

Hauke

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-06 19:05         ` Hauke Mehrtens
  0 siblings, 0 replies; 65+ messages in thread
From: Hauke Mehrtens @ 2022-07-06 19:05 UTC (permalink / raw)
  To: Florian Fainelli, Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, George McCollister, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, Linus Walleij, linux-arm-kernel,
	linux-mediatek, Matthias Brugger, netdev, Paolo Abeni, Sean Wang,
	UNGLinuxDriver, Vivien Didelot, Woojung Huh

On 7/6/22 18:27, Florian Fainelli wrote:
> On 7/6/22 03:14, Vladimir Oltean wrote:
>> Hi Florian,
>>
>> On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
>>> On 7/5/22 02:46, Russell King (Oracle) wrote:
>>>> A new revision of the series which incorporates changes that Marek
>>>> suggested. Specifically, the changes are:
>>>>
>>>> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>>>>      default interface rather than re-using port_max_speed_mode()
>>>>
>>>> 2. Patch 4 - if no default interface is provided, use the supported
>>>>      interface mask to search for the first interface that gives the
>>>>      fastest speed.
>>>>
>>>> 3. Patch 5 - now also removes the port_max_speed_mode() method
>>>
>>> This was tested with bcm_sf2.c and b53_srab.b and did not cause 
>>> regressions,
>>> however we do have a 'fixed-link' property for the CPU port (always 
>>> have had
>>> one), so there was no regression expected.
>>
>> What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?
> 
> You found one of the devices that I do not have access to and did not 
> test, thanks. We do expect to run the port at 2GBits/sec on these 
> devices however there is no "official" way to advertise that a port can 
> run at 2Gbits/sec, as this is not even a "sanctioned" speed. I do have a 
> similar device however, so let me run some more tests, we won't see a 
> regression however since we do not use the NATP accelerator which would 
> be the reason to run the port at 2Gbits/sec.

I will try this change on some devices with the lantiq gswip driver at 
the weekend.

On the SoC supported by the lantiq gswip driver the switch is integrated 
in the SoC and there is a internal link with more than 1GBit/s 
connecting the switch to the rest of the system. I think it is also 
around 2GBit/s. We can not configure the interface speed or many other 
interface settings for the link between the switch and the CPU. How 
should the device tree ideally look for this setup?

Hauke

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-06 19:05         ` Hauke Mehrtens
@ 2022-07-06 20:24           ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-06 20:24 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: Florian Fainelli, Vladimir Oltean, Andrew Lunn, Heiner Kallweit,
	Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, George McCollister,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh

On Wed, Jul 06, 2022 at 09:05:22PM +0200, Hauke Mehrtens wrote:
> On 7/6/22 18:27, Florian Fainelli wrote:
> > On 7/6/22 03:14, Vladimir Oltean wrote:
> > > Hi Florian,
> > > 
> > > On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
> > > > On 7/5/22 02:46, Russell King (Oracle) wrote:
> > > > > A new revision of the series which incorporates changes that Marek
> > > > > suggested. Specifically, the changes are:
> > > > > 
> > > > > 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
> > > > >      default interface rather than re-using port_max_speed_mode()
> > > > > 
> > > > > 2. Patch 4 - if no default interface is provided, use the supported
> > > > >      interface mask to search for the first interface that gives the
> > > > >      fastest speed.
> > > > > 
> > > > > 3. Patch 5 - now also removes the port_max_speed_mode() method
> > > > 
> > > > This was tested with bcm_sf2.c and b53_srab.b and did not cause
> > > > regressions,
> > > > however we do have a 'fixed-link' property for the CPU port
> > > > (always have had
> > > > one), so there was no regression expected.
> > > 
> > > What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?
> > 
> > You found one of the devices that I do not have access to and did not
> > test, thanks. We do expect to run the port at 2GBits/sec on these
> > devices however there is no "official" way to advertise that a port can
> > run at 2Gbits/sec, as this is not even a "sanctioned" speed. I do have a
> > similar device however, so let me run some more tests, we won't see a
> > regression however since we do not use the NATP accelerator which would
> > be the reason to run the port at 2Gbits/sec.
> 
> I will try this change on some devices with the lantiq gswip driver at the
> weekend.
> 
> On the SoC supported by the lantiq gswip driver the switch is integrated in
> the SoC and there is a internal link with more than 1GBit/s connecting the
> switch to the rest of the system. I think it is also around 2GBit/s. We can
> not configure the interface speed or many other interface settings for the
> link between the switch and the CPU. How should the device tree ideally look
> for this setup?

I think this falls into Andrew's "don't specify anything" category,
which means that we should default to the maximum speed for the
port - which is in this case quite clearly fixed at whatever the
internal link actually is.

From the get_caps() function, the fastest speed apparently supported is
1Gbps. I'm guessing the CPU port is one of ports 2..5 on xrx200 and
1..5 on xrx300 - in which case, PHY_INTERFACE_MODE_INTERNAL is likely
to be selected, which seems appropriate given what you've said above.
(PHY_INTERFACE_MODE_INTERNAL will be the first interface type found
that will give the highest speed as it permits any speed given in the
mac_capabilities.)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-06 20:24           ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-06 20:24 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: Florian Fainelli, Vladimir Oltean, Andrew Lunn, Heiner Kallweit,
	Alexandre Belloni, Alvin Šipraga, Claudiu Manoil,
	David S. Miller, DENG Qingfang, Eric Dumazet, George McCollister,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh

On Wed, Jul 06, 2022 at 09:05:22PM +0200, Hauke Mehrtens wrote:
> On 7/6/22 18:27, Florian Fainelli wrote:
> > On 7/6/22 03:14, Vladimir Oltean wrote:
> > > Hi Florian,
> > > 
> > > On Tue, Jul 05, 2022 at 09:42:33AM -0700, Florian Fainelli wrote:
> > > > On 7/5/22 02:46, Russell King (Oracle) wrote:
> > > > > A new revision of the series which incorporates changes that Marek
> > > > > suggested. Specifically, the changes are:
> > > > > 
> > > > > 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
> > > > >      default interface rather than re-using port_max_speed_mode()
> > > > > 
> > > > > 2. Patch 4 - if no default interface is provided, use the supported
> > > > >      interface mask to search for the first interface that gives the
> > > > >      fastest speed.
> > > > > 
> > > > > 3. Patch 5 - now also removes the port_max_speed_mode() method
> > > > 
> > > > This was tested with bcm_sf2.c and b53_srab.b and did not cause
> > > > regressions,
> > > > however we do have a 'fixed-link' property for the CPU port
> > > > (always have had
> > > > one), so there was no regression expected.
> > > 
> > > What about arch/arm/boot/dts/bcm47189-tenda-ac9.dts?
> > 
> > You found one of the devices that I do not have access to and did not
> > test, thanks. We do expect to run the port at 2GBits/sec on these
> > devices however there is no "official" way to advertise that a port can
> > run at 2Gbits/sec, as this is not even a "sanctioned" speed. I do have a
> > similar device however, so let me run some more tests, we won't see a
> > regression however since we do not use the NATP accelerator which would
> > be the reason to run the port at 2Gbits/sec.
> 
> I will try this change on some devices with the lantiq gswip driver at the
> weekend.
> 
> On the SoC supported by the lantiq gswip driver the switch is integrated in
> the SoC and there is a internal link with more than 1GBit/s connecting the
> switch to the rest of the system. I think it is also around 2GBit/s. We can
> not configure the interface speed or many other interface settings for the
> link between the switch and the CPU. How should the device tree ideally look
> for this setup?

I think this falls into Andrew's "don't specify anything" category,
which means that we should default to the maximum speed for the
port - which is in this case quite clearly fixed at whatever the
internal link actually is.

From the get_caps() function, the fastest speed apparently supported is
1Gbps. I'm guessing the CPU port is one of ports 2..5 on xrx200 and
1..5 on xrx300 - in which case, PHY_INTERFACE_MODE_INTERNAL is likely
to be selected, which seems appropriate given what you've said above.
(PHY_INTERFACE_MODE_INTERNAL will be the first interface type found
that will give the highest speed as it permits any speed given in the
mac_capabilities.)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-05  9:46 ` Russell King (Oracle)
@ 2022-07-06 22:46   ` Linus Walleij
  -1 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2022-07-06 22:46 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

On Tue, Jul 5, 2022 at 11:47 AM Russell King (Oracle)
<linux@armlinux.org.uk> wrote:

> A new revision of the series which incorporates changes that Marek
> suggested. Specifically, the changes are:
>
> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>    default interface rather than re-using port_max_speed_mode()
>
> 2. Patch 4 - if no default interface is provided, use the supported
>    interface mask to search for the first interface that gives the
>    fastest speed.
>
> 3. Patch 5 - now also removes the port_max_speed_mode() method

Pulled in the patch set on top of net-next and tested on the
D-Link DIR-685 with the RTL8366RB switch with no
regressions, so:
Tested-by: Linus Walleij <linus.walleij@linaro.org>

The plan is to enhance the phylink handling in the RTL8366RB
on top of Russell's patch in some time.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-06 22:46   ` Linus Walleij
  0 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2022-07-06 22:46 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

On Tue, Jul 5, 2022 at 11:47 AM Russell King (Oracle)
<linux@armlinux.org.uk> wrote:

> A new revision of the series which incorporates changes that Marek
> suggested. Specifically, the changes are:
>
> 1. Patch 2 - use the phylink_get_caps method in mv88e6xxx to get the
>    default interface rather than re-using port_max_speed_mode()
>
> 2. Patch 4 - if no default interface is provided, use the supported
>    interface mask to search for the first interface that gives the
>    fastest speed.
>
> 3. Patch 5 - now also removes the port_max_speed_mode() method

Pulled in the patch set on top of net-next and tested on the
D-Link DIR-685 with the RTL8366RB switch with no
regressions, so:
Tested-by: Linus Walleij <linus.walleij@linaro.org>

The plan is to enhance the phylink handling in the RTL8366RB
on top of Russell's patch in some time.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-06 16:24       ` Russell King (Oracle)
@ 2022-07-07 10:09         ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 10:09 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > where a fixed-link property is also missing, not just a phy-handle?
> > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > wouldn't be covered by these 2 checks and would still represent a valid
> > DT binding.
> 
> phylink_set_max_fixed_link() already excludes itself:
> 
>         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
>                 return -EBUSY;
> 
> intentionally so that if there is anything specified for the port, be
> that a fixed link or in-band, then phylink_set_max_fixed_link() errors
> out with -EBUSY.
> 
> The only case that it can't detect is if there is a PHY that may be
> added to phylink at a later time, and that is what the check above
> is for.

I've updated the function description to mention this detail:

+/**
+ * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Set a maximum speed fixed-link configuration for the chosen interface mode
+ * and MAC capabilities for the phylink instance if the instance has not
+ * already been configured with a SFP, fixed link, or in-band AN mode. If the
+ * interface mode is PHY_INTERFACE_MODE_NA, then search the supported
+ * interfaces bitmap for the first interface that gives the fastest supported
+ * speed.

Does this address your concern?

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 10:09         ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 10:09 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > where a fixed-link property is also missing, not just a phy-handle?
> > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > wouldn't be covered by these 2 checks and would still represent a valid
> > DT binding.
> 
> phylink_set_max_fixed_link() already excludes itself:
> 
>         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
>                 return -EBUSY;
> 
> intentionally so that if there is anything specified for the port, be
> that a fixed link or in-band, then phylink_set_max_fixed_link() errors
> out with -EBUSY.
> 
> The only case that it can't detect is if there is a PHY that may be
> added to phylink at a later time, and that is what the check above
> is for.

I've updated the function description to mention this detail:

+/**
+ * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Set a maximum speed fixed-link configuration for the chosen interface mode
+ * and MAC capabilities for the phylink instance if the instance has not
+ * already been configured with a SFP, fixed link, or in-band AN mode. If the
+ * interface mode is PHY_INTERFACE_MODE_NA, then search the supported
+ * interfaces bitmap for the first interface that gives the fastest supported
+ * speed.

Does this address your concern?

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-06 10:26     ` Vladimir Oltean
@ 2022-07-07 11:00       ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 11:00 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> Hello,
> 
> On Tue, Jul 05, 2022 at 10:48:07AM +0100, Russell King (Oracle) wrote:
> > diff --git a/net/dsa/port.c b/net/dsa/port.c
> > index 35b4e1f8dc05..34487e62eb03 100644
> > --- a/net/dsa/port.c
> > +++ b/net/dsa/port.c
> > @@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  {
> >  	struct dsa_switch *ds = dp->ds;
> >  	phy_interface_t mode, def_mode;
> > +	struct device_node *phy_np;
> >  	int err;
> >  
> >  	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
> > @@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  		return PTR_ERR(dp->pl);
> >  	}
> >  
> > +	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
> > +		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +		of_node_put(phy_np);
> > +		if (!phy_np)
> > +			err = phylink_set_max_fixed_link(dp->pl);
> 
> Can we please limit phylink_set_max_link_speed() to just the CPU ports
> where a fixed-link property is also missing, not just a phy-handle?
> Although to be entirely correct, we can also have MLO_AN_INBAND, which
> wouldn't be covered by these 2 checks and would still represent a valid
> DT binding.

More importantly, we need your input on Ocelot, which you are listed as
a maintainer for, and Ocelot is the only DSA driver that does stuff
differently (due to the rate adapting PCS). It doesn't set
mac_capabilities, and therefore phylink_set_max_fixed_link() will not
work here.

Has Ocelot ever made use of this DSA feature where, when nothing is
specified for a CPU or DSA port, we use an effective fixed-link setup
with an interface mode that gives the highest speed? Or does this not
apply to this DSA driver?

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 11:00       ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 11:00 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> Hello,
> 
> On Tue, Jul 05, 2022 at 10:48:07AM +0100, Russell King (Oracle) wrote:
> > diff --git a/net/dsa/port.c b/net/dsa/port.c
> > index 35b4e1f8dc05..34487e62eb03 100644
> > --- a/net/dsa/port.c
> > +++ b/net/dsa/port.c
> > @@ -1525,6 +1525,7 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  {
> >  	struct dsa_switch *ds = dp->ds;
> >  	phy_interface_t mode, def_mode;
> > +	struct device_node *phy_np;
> >  	int err;
> >  
> >  	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
> > @@ -1559,6 +1560,13 @@ int dsa_port_phylink_create(struct dsa_port *dp)
> >  		return PTR_ERR(dp->pl);
> >  	}
> >  
> > +	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) {
> > +		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +		of_node_put(phy_np);
> > +		if (!phy_np)
> > +			err = phylink_set_max_fixed_link(dp->pl);
> 
> Can we please limit phylink_set_max_link_speed() to just the CPU ports
> where a fixed-link property is also missing, not just a phy-handle?
> Although to be entirely correct, we can also have MLO_AN_INBAND, which
> wouldn't be covered by these 2 checks and would still represent a valid
> DT binding.

More importantly, we need your input on Ocelot, which you are listed as
a maintainer for, and Ocelot is the only DSA driver that does stuff
differently (due to the rate adapting PCS). It doesn't set
mac_capabilities, and therefore phylink_set_max_fixed_link() will not
work here.

Has Ocelot ever made use of this DSA feature where, when nothing is
specified for a CPU or DSA port, we use an effective fixed-link setup
with an interface mode that gives the highest speed? Or does this not
apply to this DSA driver?

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
  2022-07-06 22:46   ` Linus Walleij
@ 2022-07-07 13:46     ` Linus Walleij
  -1 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2022-07-07 13:46 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

On Thu, Jul 7, 2022 at 12:46 AM Linus Walleij <linus.walleij@linaro.org> wrote:

> Pulled in the patch set on top of net-next and tested on the
> D-Link DIR-685 with the RTL8366RB switch with no
> regressions, so:
> Tested-by: Linus Walleij <linus.walleij@linaro.org>
>
> The plan is to enhance the phylink handling in the RTL8366RB
> on top of Russell's patch in some time.

I developed a patch like this and tested it, it works great and the DSA
core now properly configures all the links (as expected).

I will send this out once Russell's patches are finalized and merged.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next v2 0/5] net: dsa: always use phylink
@ 2022-07-07 13:46     ` Linus Walleij
  0 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2022-07-07 13:46 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin Šipraga, Claudiu Manoil, David S. Miller,
	DENG Qingfang, Eric Dumazet, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jakub Kicinski,
	Kurt Kanzenbach, Landen Chao, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Vladimir Oltean, Woojung Huh

On Thu, Jul 7, 2022 at 12:46 AM Linus Walleij <linus.walleij@linaro.org> wrote:

> Pulled in the patch set on top of net-next and tested on the
> D-Link DIR-685 with the RTL8366RB switch with no
> regressions, so:
> Tested-by: Linus Walleij <linus.walleij@linaro.org>
>
> The plan is to enhance the phylink handling in the RTL8366RB
> on top of Russell's patch in some time.

I developed a patch like this and tested it, it works great and the DSA
core now properly configures all the links (as expected).

I will send this out once Russell's patches are finalized and merged.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 10:09         ` Russell King (Oracle)
@ 2022-07-07 15:27           ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 15:27 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 11:09:43AM +0100, Russell King (Oracle) wrote:
> On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> > On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > > where a fixed-link property is also missing, not just a phy-handle?
> > > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > > wouldn't be covered by these 2 checks and would still represent a valid
> > > DT binding.
> > 
> > phylink_set_max_fixed_link() already excludes itself:
> > 
> >         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
                                                      ~~~~~~~~~~

If not NULL, this is an SFP PHY, right? In other words, it's supposed to protect from
phylink_sfp_connect_phy() - code involuntarily triggered by phylink_create() ->
phylink_register_sfp() - and not from calls to phylink_{,fwnode_}connect_phy()
that were initiated by the phylink user between phylink_create() and
phylink_set_max_fixed_link(), correct? Those are specified as invalid in the
kerneldoc and that's about it - that's not what the checking is for, correct?

But if so, why even check for pl->phydev, if you check for pl->sfp_bus?

> >                 return -EBUSY;
> > 
> > intentionally so that if there is anything specified for the port, be
> > that a fixed link or in-band, then phylink_set_max_fixed_link() errors
> > out with -EBUSY.
> > 
> > The only case that it can't detect is if there is a PHY that may be
> > added to phylink at a later time, and that is what the check above
> > is for.

Here by "PHY added at a later time", you do mean calling phylink_{,fwnode_}connect_phy()
after phylink_set_max_fixed_link(), right?

So this is what I don't understand. If we've called phylink_set_max_fixed_link()
we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
predicts if it's going to call either of those connect_phy() functions,
and calls phylink_set_max_fixed_link() only if it won't. Right?

You've structured the checks in this "distributed" way because phylink
can't really predict whether phylink_{,fwnode_}connect_phy() will be
called after phylink_set_max_fixed_link(), right? I mean, it can
probably predict the fwnode_ variant, but not phylink_connect_phy, and
this is why it is up to the caller to decide when to call and when not to.

> I've updated the function description to mention this detail:
> 
> +/**
> + * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
> + * @pl: a pointer to a &struct phylink returned from phylink_create()
> + *
> + * Set a maximum speed fixed-link configuration for the chosen interface mode
> + * and MAC capabilities for the phylink instance if the instance has not
> + * already been configured with a SFP, fixed link, or in-band AN mode. If the
> + * interface mode is PHY_INTERFACE_MODE_NA, then search the supported
> + * interfaces bitmap for the first interface that gives the fastest supported
> + * speed.
> 
> Does this address your concern?
> 
> Thanks.

Not really, no, sorry, it just confuses me more. It should maybe also
say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
is going to be called later.

Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
based on the following?

(1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
(2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
(3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
    condition from phylink_fwnode_phy_connect():

	phy_fwnode = fwnode_get_phy_node(fwnode);
	if (IS_ERR(phy_fwnode)) {
		if (pl->cfg_link_an_mode == MLO_AN_PHY)
			return -ENODEV; <- here
		return 0;
	}

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 15:27           ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 15:27 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 11:09:43AM +0100, Russell King (Oracle) wrote:
> On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> > On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > > where a fixed-link property is also missing, not just a phy-handle?
> > > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > > wouldn't be covered by these 2 checks and would still represent a valid
> > > DT binding.
> > 
> > phylink_set_max_fixed_link() already excludes itself:
> > 
> >         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
                                                      ~~~~~~~~~~

If not NULL, this is an SFP PHY, right? In other words, it's supposed to protect from
phylink_sfp_connect_phy() - code involuntarily triggered by phylink_create() ->
phylink_register_sfp() - and not from calls to phylink_{,fwnode_}connect_phy()
that were initiated by the phylink user between phylink_create() and
phylink_set_max_fixed_link(), correct? Those are specified as invalid in the
kerneldoc and that's about it - that's not what the checking is for, correct?

But if so, why even check for pl->phydev, if you check for pl->sfp_bus?

> >                 return -EBUSY;
> > 
> > intentionally so that if there is anything specified for the port, be
> > that a fixed link or in-band, then phylink_set_max_fixed_link() errors
> > out with -EBUSY.
> > 
> > The only case that it can't detect is if there is a PHY that may be
> > added to phylink at a later time, and that is what the check above
> > is for.

Here by "PHY added at a later time", you do mean calling phylink_{,fwnode_}connect_phy()
after phylink_set_max_fixed_link(), right?

So this is what I don't understand. If we've called phylink_set_max_fixed_link()
we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
predicts if it's going to call either of those connect_phy() functions,
and calls phylink_set_max_fixed_link() only if it won't. Right?

You've structured the checks in this "distributed" way because phylink
can't really predict whether phylink_{,fwnode_}connect_phy() will be
called after phylink_set_max_fixed_link(), right? I mean, it can
probably predict the fwnode_ variant, but not phylink_connect_phy, and
this is why it is up to the caller to decide when to call and when not to.

> I've updated the function description to mention this detail:
> 
> +/**
> + * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
> + * @pl: a pointer to a &struct phylink returned from phylink_create()
> + *
> + * Set a maximum speed fixed-link configuration for the chosen interface mode
> + * and MAC capabilities for the phylink instance if the instance has not
> + * already been configured with a SFP, fixed link, or in-band AN mode. If the
> + * interface mode is PHY_INTERFACE_MODE_NA, then search the supported
> + * interfaces bitmap for the first interface that gives the fastest supported
> + * speed.
> 
> Does this address your concern?
> 
> Thanks.

Not really, no, sorry, it just confuses me more. It should maybe also
say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
is going to be called later.

Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
based on the following?

(1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
(2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
(3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
    condition from phylink_fwnode_phy_connect():

	phy_fwnode = fwnode_get_phy_node(fwnode);
	if (IS_ERR(phy_fwnode)) {
		if (pl->cfg_link_an_mode == MLO_AN_PHY)
			return -ENODEV; <- here
		return 0;
	}

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 11:00       ` Russell King (Oracle)
@ 2022-07-07 15:43         ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 15:43 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 12:00:54PM +0100, Russell King (Oracle) wrote:
> More importantly, we need your input on Ocelot, which you are listed as
> a maintainer for, and Ocelot is the only DSA driver that does stuff
> differently (due to the rate adapting PCS). It doesn't set
> mac_capabilities, and therefore phylink_set_max_fixed_link() will not
> work here.
> 
> Has Ocelot ever made use of this DSA feature where, when nothing is
> specified for a CPU or DSA port, we use an effective fixed-link setup
> with an interface mode that gives the highest speed? Or does this not
> apply to this DSA driver?
> 
> Thanks.

I'm fine with both the ocelot and sja1105 drivers.

The ocelot driver has 3 users:

- felix_vsc9959 (arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi) on NXP
  LS1028A, where the CPU ports have and have always had a fixed-link
  node in the SoC dtsi. LS1028A based boards should include the SoC
  dtsi. If other board DT writers don't do that or if they delete the
  fixed-link node from the CPU ports, that's not my problem and I don't
  really want to help them.

- seville_vsc9953 (arch/powerpc/boot/dts/fsl/t1040si-post.dtsi) on NXP
  T1040. Same thing, embedded switch, not my fault if the fixed-link
  disappears from the SoC dtsi.

- Colin Foster's SPI-controlled VSC7512 (still downstream). He has an
  Ethernet cable connecting the CPU port to a Beaglebone Black, so he
  has a phy-handle on the CPU port, so definitely not nothing. I believe
  his work hasn't made it to production in any case, so enforcing
  validation now shouldn't bother him too much if at all.

As for sja1105, there is DT validation that checks for the presence of
all required properties in sja1105_parse_ports_node().

There is some DT validation in felix_parse_ports_node() too, but it
doesn't check that all specifiers that phylink might use are there.
I'd really like to add some validation before I gain any involuntary
users, but all open-coded constructs I can come up with are clumsy.
What would you suggest, if I explicitly don't want to rely on
context-specific phylink interpretation of empty OF nodes, and rather
error out?

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 15:43         ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 15:43 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 12:00:54PM +0100, Russell King (Oracle) wrote:
> More importantly, we need your input on Ocelot, which you are listed as
> a maintainer for, and Ocelot is the only DSA driver that does stuff
> differently (due to the rate adapting PCS). It doesn't set
> mac_capabilities, and therefore phylink_set_max_fixed_link() will not
> work here.
> 
> Has Ocelot ever made use of this DSA feature where, when nothing is
> specified for a CPU or DSA port, we use an effective fixed-link setup
> with an interface mode that gives the highest speed? Or does this not
> apply to this DSA driver?
> 
> Thanks.

I'm fine with both the ocelot and sja1105 drivers.

The ocelot driver has 3 users:

- felix_vsc9959 (arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi) on NXP
  LS1028A, where the CPU ports have and have always had a fixed-link
  node in the SoC dtsi. LS1028A based boards should include the SoC
  dtsi. If other board DT writers don't do that or if they delete the
  fixed-link node from the CPU ports, that's not my problem and I don't
  really want to help them.

- seville_vsc9953 (arch/powerpc/boot/dts/fsl/t1040si-post.dtsi) on NXP
  T1040. Same thing, embedded switch, not my fault if the fixed-link
  disappears from the SoC dtsi.

- Colin Foster's SPI-controlled VSC7512 (still downstream). He has an
  Ethernet cable connecting the CPU port to a Beaglebone Black, so he
  has a phy-handle on the CPU port, so definitely not nothing. I believe
  his work hasn't made it to production in any case, so enforcing
  validation now shouldn't bother him too much if at all.

As for sja1105, there is DT validation that checks for the presence of
all required properties in sja1105_parse_ports_node().

There is some DT validation in felix_parse_ports_node() too, but it
doesn't check that all specifiers that phylink might use are there.
I'd really like to add some validation before I gain any involuntary
users, but all open-coded constructs I can come up with are clumsy.
What would you suggest, if I explicitly don't want to rely on
context-specific phylink interpretation of empty OF nodes, and rather
error out?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 15:27           ` Vladimir Oltean
@ 2022-07-07 15:48             ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 15:48 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 06:27:27PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 11:09:43AM +0100, Russell King (Oracle) wrote:
> > On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> > > On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > > > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > > > where a fixed-link property is also missing, not just a phy-handle?
> > > > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > > > wouldn't be covered by these 2 checks and would still represent a valid
> > > > DT binding.
> > > 
> > > phylink_set_max_fixed_link() already excludes itself:
> > > 
> > >         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
>                                                       ~~~~~~~~~~
> 
> If not NULL, this is an SFP PHY, right? In other words, it's supposed to protect from
> phylink_sfp_connect_phy() - code involuntarily triggered by phylink_create() ->
> phylink_register_sfp() - and not from calls to phylink_{,fwnode_}connect_phy()
> that were initiated by the phylink user between phylink_create() and
> phylink_set_max_fixed_link(), correct? Those are specified as invalid in the
> kerneldoc and that's about it - that's not what the checking is for, correct?

No, it's not to do with sfps at all, but to do with enforcing the
pre-conditions for the function - that entire line is checking that
(a) we are in a sane state to be called, and (b) there is no
configuration initialisation beyond the default done by
phylink_create() - in other words, there is no in-band or fixed-link
specified.

Let's go through this step by step.

1. pl->cfg_link_an_mode != MLO_AN_PHY
   The default value for cfg_link_an_mode is MLO_AN_PHY. If it's
   anything other than that, then a fixed-link or in-band mode has
   been specified, and we don't want to override that. So this call
   needs to fail.

2. pl->phydev
   If a PHY has been attached, then the pre-condition for calling this
   function immediately after phylink_create() has been violated,
   because the only way it can be non-NULL is if someone's called one of
   the phylink functions that connects a PHY. Note: SFPs will not set
   their PHY here, because, for them to discover that there's a PHY, the
   network interface needs to be up, and it will never be up here... but
   in any case...

3. pl->sfp_bus
   If we have a SFP bus, then we definitely are not going to be
   operating in this default fixed-link mode - because the SFP is going
   to want to set its own parameters.

> > >                 return -EBUSY;
> > > 
> > > intentionally so that if there is anything specified for the port, be
> > > that a fixed link or in-band, then phylink_set_max_fixed_link() errors
> > > out with -EBUSY.
> > > 
> > > The only case that it can't detect is if there is a PHY that may be
> > > added to phylink at a later time, and that is what the check above
> > > is for.
> 
> Here by "PHY added at a later time", you do mean calling phylink_{,fwnode_}connect_phy()
> after phylink_set_max_fixed_link(), right?

Correct.

> So this is what I don't understand. If we've called phylink_set_max_fixed_link()
> we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
> silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
> predicts if it's going to call either of those connect_phy() functions,
> and calls phylink_set_max_fixed_link() only if it won't. Right?
> 
> You've structured the checks in this "distributed" way because phylink
> can't really predict whether phylink_{,fwnode_}connect_phy() will be
> called after phylink_set_max_fixed_link(), right? I mean, it can
> probably predict the fwnode_ variant, but not phylink_connect_phy, and
> this is why it is up to the caller to decide when to call and when not to.

phylink has no idea whether phylink_fwnode_connect_phy() will be called
with the same fwnode as phylink_create(), so it really can't make any
assumptions about whether there will be a PHY or not.

> 
> > I've updated the function description to mention this detail:
> > 
> > +/**
> > + * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
> > + * @pl: a pointer to a &struct phylink returned from phylink_create()
> > + *
> > + * Set a maximum speed fixed-link configuration for the chosen interface mode
> > + * and MAC capabilities for the phylink instance if the instance has not
> > + * already been configured with a SFP, fixed link, or in-band AN mode. If the
> > + * interface mode is PHY_INTERFACE_MODE_NA, then search the supported
> > + * interfaces bitmap for the first interface that gives the fastest supported
> > + * speed.
> > 
> > Does this address your concern?
> > 
> > Thanks.
> 
> Not really, no, sorry, it just confuses me more.

I find that happens a lot when I try to add more documentation to
clarify things. I sometimes get to the point of deciding its better
_not_ to write any documentation, because documentation just ends up
being confusing and people want more and more detail.

I've got to the point in some case where I've had to spell out which
keys to press on the keyboard for people to formulate the "[PATCH ...]"
thing correctly, because if you put it in quotes, you get people who
will include the quotes even if you tell them not to.

I hate documentation, I seem incapable of writing it in a way people can
understand.

> It should maybe also
> say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
> is going to be called later.

It's already a precondition that phylink_{,fwnode_}connect_phy() fail if
we're in fixed-link mode (because PHYs have never been supported when in
fixed-link mode - if one remembers, the old fixed-link code used to
provide its own emulation of a PHY to make fixed-links work.) So PHYs
and fixed-links have always been mutually exclusive before phylink, and
continue to be so with phylink.

> Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> based on the following?
> 
> (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
>     condition from phylink_fwnode_phy_connect():
> 
> 	phy_fwnode = fwnode_get_phy_node(fwnode);
> 	if (IS_ERR(phy_fwnode)) {
> 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> 			return -ENODEV; <- here
> 		return 0;
> 	}

My question in response would be - why should this DSA specific behaviour
be handled completely internally within phylink, when it's a DSA
specific behaviour? Why do we need boolean flags for this?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 15:48             ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 15:48 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 06:27:27PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 11:09:43AM +0100, Russell King (Oracle) wrote:
> > On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> > > On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > > > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > > > where a fixed-link property is also missing, not just a phy-handle?
> > > > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > > > wouldn't be covered by these 2 checks and would still represent a valid
> > > > DT binding.
> > > 
> > > phylink_set_max_fixed_link() already excludes itself:
> > > 
> > >         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
>                                                       ~~~~~~~~~~
> 
> If not NULL, this is an SFP PHY, right? In other words, it's supposed to protect from
> phylink_sfp_connect_phy() - code involuntarily triggered by phylink_create() ->
> phylink_register_sfp() - and not from calls to phylink_{,fwnode_}connect_phy()
> that were initiated by the phylink user between phylink_create() and
> phylink_set_max_fixed_link(), correct? Those are specified as invalid in the
> kerneldoc and that's about it - that's not what the checking is for, correct?

No, it's not to do with sfps at all, but to do with enforcing the
pre-conditions for the function - that entire line is checking that
(a) we are in a sane state to be called, and (b) there is no
configuration initialisation beyond the default done by
phylink_create() - in other words, there is no in-band or fixed-link
specified.

Let's go through this step by step.

1. pl->cfg_link_an_mode != MLO_AN_PHY
   The default value for cfg_link_an_mode is MLO_AN_PHY. If it's
   anything other than that, then a fixed-link or in-band mode has
   been specified, and we don't want to override that. So this call
   needs to fail.

2. pl->phydev
   If a PHY has been attached, then the pre-condition for calling this
   function immediately after phylink_create() has been violated,
   because the only way it can be non-NULL is if someone's called one of
   the phylink functions that connects a PHY. Note: SFPs will not set
   their PHY here, because, for them to discover that there's a PHY, the
   network interface needs to be up, and it will never be up here... but
   in any case...

3. pl->sfp_bus
   If we have a SFP bus, then we definitely are not going to be
   operating in this default fixed-link mode - because the SFP is going
   to want to set its own parameters.

> > >                 return -EBUSY;
> > > 
> > > intentionally so that if there is anything specified for the port, be
> > > that a fixed link or in-band, then phylink_set_max_fixed_link() errors
> > > out with -EBUSY.
> > > 
> > > The only case that it can't detect is if there is a PHY that may be
> > > added to phylink at a later time, and that is what the check above
> > > is for.
> 
> Here by "PHY added at a later time", you do mean calling phylink_{,fwnode_}connect_phy()
> after phylink_set_max_fixed_link(), right?

Correct.

> So this is what I don't understand. If we've called phylink_set_max_fixed_link()
> we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
> silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
> predicts if it's going to call either of those connect_phy() functions,
> and calls phylink_set_max_fixed_link() only if it won't. Right?
> 
> You've structured the checks in this "distributed" way because phylink
> can't really predict whether phylink_{,fwnode_}connect_phy() will be
> called after phylink_set_max_fixed_link(), right? I mean, it can
> probably predict the fwnode_ variant, but not phylink_connect_phy, and
> this is why it is up to the caller to decide when to call and when not to.

phylink has no idea whether phylink_fwnode_connect_phy() will be called
with the same fwnode as phylink_create(), so it really can't make any
assumptions about whether there will be a PHY or not.

> 
> > I've updated the function description to mention this detail:
> > 
> > +/**
> > + * phylink_set_max_fixed_link() - set a fixed link configuration for phylink
> > + * @pl: a pointer to a &struct phylink returned from phylink_create()
> > + *
> > + * Set a maximum speed fixed-link configuration for the chosen interface mode
> > + * and MAC capabilities for the phylink instance if the instance has not
> > + * already been configured with a SFP, fixed link, or in-band AN mode. If the
> > + * interface mode is PHY_INTERFACE_MODE_NA, then search the supported
> > + * interfaces bitmap for the first interface that gives the fastest supported
> > + * speed.
> > 
> > Does this address your concern?
> > 
> > Thanks.
> 
> Not really, no, sorry, it just confuses me more.

I find that happens a lot when I try to add more documentation to
clarify things. I sometimes get to the point of deciding its better
_not_ to write any documentation, because documentation just ends up
being confusing and people want more and more detail.

I've got to the point in some case where I've had to spell out which
keys to press on the keyboard for people to formulate the "[PATCH ...]"
thing correctly, because if you put it in quotes, you get people who
will include the quotes even if you tell them not to.

I hate documentation, I seem incapable of writing it in a way people can
understand.

> It should maybe also
> say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
> is going to be called later.

It's already a precondition that phylink_{,fwnode_}connect_phy() fail if
we're in fixed-link mode (because PHYs have never been supported when in
fixed-link mode - if one remembers, the old fixed-link code used to
provide its own emulation of a PHY to make fixed-links work.) So PHYs
and fixed-links have always been mutually exclusive before phylink, and
continue to be so with phylink.

> Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> based on the following?
> 
> (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
>     condition from phylink_fwnode_phy_connect():
> 
> 	phy_fwnode = fwnode_get_phy_node(fwnode);
> 	if (IS_ERR(phy_fwnode)) {
> 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> 			return -ENODEV; <- here
> 		return 0;
> 	}

My question in response would be - why should this DSA specific behaviour
be handled completely internally within phylink, when it's a DSA
specific behaviour? Why do we need boolean flags for this?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 15:43         ` Vladimir Oltean
@ 2022-07-07 16:32           ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 16:32 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 06:43:03PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 12:00:54PM +0100, Russell King (Oracle) wrote:
> > More importantly, we need your input on Ocelot, which you are listed as
> > a maintainer for, and Ocelot is the only DSA driver that does stuff
> > differently (due to the rate adapting PCS). It doesn't set
> > mac_capabilities, and therefore phylink_set_max_fixed_link() will not
> > work here.
> > 
> > Has Ocelot ever made use of this DSA feature where, when nothing is
> > specified for a CPU or DSA port, we use an effective fixed-link setup
> > with an interface mode that gives the highest speed? Or does this not
> > apply to this DSA driver?
> > 
> > Thanks.
> 
> I'm fine with both the ocelot and sja1105 drivers.
> 
> The ocelot driver has 3 users:
> 
> - felix_vsc9959 (arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi) on NXP
>   LS1028A, where the CPU ports have and have always had a fixed-link
>   node in the SoC dtsi. LS1028A based boards should include the SoC
>   dtsi. If other board DT writers don't do that or if they delete the
>   fixed-link node from the CPU ports, that's not my problem and I don't
>   really want to help them.
> 
> - seville_vsc9953 (arch/powerpc/boot/dts/fsl/t1040si-post.dtsi) on NXP
>   T1040. Same thing, embedded switch, not my fault if the fixed-link
>   disappears from the SoC dtsi.

Great, so I'll mark ocelot is safe.

> - Colin Foster's SPI-controlled VSC7512 (still downstream). He has an
>   Ethernet cable connecting the CPU port to a Beaglebone Black, so he
>   has a phy-handle on the CPU port, so definitely not nothing. I believe
>   his work hasn't made it to production in any case, so enforcing
>   validation now shouldn't bother him too much if at all.

Ok, thanks.

> As for sja1105, there is DT validation that checks for the presence of
> all required properties in sja1105_parse_ports_node().

Looking at those, it requires all of:

- a phy mode to be specified (as determined by of_get_phy_mode())
- a phy-handle or of_phy_is_fixed_link() to return true

otherwise it errors out.

> There is some DT validation in felix_parse_ports_node() too, but it
> doesn't check that all specifiers that phylink might use are there.

Phylink (correction, fwnode_get_phy_node() which is not part of phylink
anymore) will look for phy-handle, phy, or phy-device. This is I don't
see that there's any incompatibility between what the driver is doing
and what phylink does.

If there's a fixed-link property, then sja1105_parse_ports_node() is
happy, and so will phylink. If there's a phy-handle, the same is true.
If there's a "phy" or "phy-device" then sja1105_parse_ports_node()
errors out. That's completely fine.

"phy" and "phy-device" are the backwards compatibility for DT - I
believe one of them is the ePAPR specified property that we in Linux
have decided to only fall back on if there's not our more modern
"phy-handle" property.

It seems We have a lot of users of "phy" in DT today, so we can't drop
that from generic code such as phylink, but I haven't found any users
of "phy-device".

> I'd really like to add some validation before I gain any involuntary
> users, but all open-coded constructs I can come up with are clumsy.
> What would you suggest, if I explicitly don't want to rely on
> context-specific phylink interpretation of empty OF nodes, and rather
> error out?

So I also don't see a problem - sja1105 rejects DTs that fail to
describe a port using at least one of a phy-handle, a fixed-link, or
a managed in-band link, and I don't think it needs to do further
validation, certainly not for the phy describing properties that
the kernel has chosen to deprecate for new implementations.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 16:32           ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 16:32 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 06:43:03PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 12:00:54PM +0100, Russell King (Oracle) wrote:
> > More importantly, we need your input on Ocelot, which you are listed as
> > a maintainer for, and Ocelot is the only DSA driver that does stuff
> > differently (due to the rate adapting PCS). It doesn't set
> > mac_capabilities, and therefore phylink_set_max_fixed_link() will not
> > work here.
> > 
> > Has Ocelot ever made use of this DSA feature where, when nothing is
> > specified for a CPU or DSA port, we use an effective fixed-link setup
> > with an interface mode that gives the highest speed? Or does this not
> > apply to this DSA driver?
> > 
> > Thanks.
> 
> I'm fine with both the ocelot and sja1105 drivers.
> 
> The ocelot driver has 3 users:
> 
> - felix_vsc9959 (arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi) on NXP
>   LS1028A, where the CPU ports have and have always had a fixed-link
>   node in the SoC dtsi. LS1028A based boards should include the SoC
>   dtsi. If other board DT writers don't do that or if they delete the
>   fixed-link node from the CPU ports, that's not my problem and I don't
>   really want to help them.
> 
> - seville_vsc9953 (arch/powerpc/boot/dts/fsl/t1040si-post.dtsi) on NXP
>   T1040. Same thing, embedded switch, not my fault if the fixed-link
>   disappears from the SoC dtsi.

Great, so I'll mark ocelot is safe.

> - Colin Foster's SPI-controlled VSC7512 (still downstream). He has an
>   Ethernet cable connecting the CPU port to a Beaglebone Black, so he
>   has a phy-handle on the CPU port, so definitely not nothing. I believe
>   his work hasn't made it to production in any case, so enforcing
>   validation now shouldn't bother him too much if at all.

Ok, thanks.

> As for sja1105, there is DT validation that checks for the presence of
> all required properties in sja1105_parse_ports_node().

Looking at those, it requires all of:

- a phy mode to be specified (as determined by of_get_phy_mode())
- a phy-handle or of_phy_is_fixed_link() to return true

otherwise it errors out.

> There is some DT validation in felix_parse_ports_node() too, but it
> doesn't check that all specifiers that phylink might use are there.

Phylink (correction, fwnode_get_phy_node() which is not part of phylink
anymore) will look for phy-handle, phy, or phy-device. This is I don't
see that there's any incompatibility between what the driver is doing
and what phylink does.

If there's a fixed-link property, then sja1105_parse_ports_node() is
happy, and so will phylink. If there's a phy-handle, the same is true.
If there's a "phy" or "phy-device" then sja1105_parse_ports_node()
errors out. That's completely fine.

"phy" and "phy-device" are the backwards compatibility for DT - I
believe one of them is the ePAPR specified property that we in Linux
have decided to only fall back on if there's not our more modern
"phy-handle" property.

It seems We have a lot of users of "phy" in DT today, so we can't drop
that from generic code such as phylink, but I haven't found any users
of "phy-device".

> I'd really like to add some validation before I gain any involuntary
> users, but all open-coded constructs I can come up with are clumsy.
> What would you suggest, if I explicitly don't want to rely on
> context-specific phylink interpretation of empty OF nodes, and rather
> error out?

So I also don't see a problem - sja1105 rejects DTs that fail to
describe a port using at least one of a phy-handle, a fixed-link, or
a managed in-band link, and I don't think it needs to do further
validation, certainly not for the phy describing properties that
the kernel has chosen to deprecate for new implementations.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 15:48             ` Russell King (Oracle)
@ 2022-07-07 16:38               ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 16:38 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 04:48:12PM +0100, Russell King (Oracle) wrote:
> On Thu, Jul 07, 2022 at 06:27:27PM +0300, Vladimir Oltean wrote:
> > On Thu, Jul 07, 2022 at 11:09:43AM +0100, Russell King (Oracle) wrote:
> > > On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> > > > On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > > > > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > > > > where a fixed-link property is also missing, not just a phy-handle?
> > > > > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > > > > wouldn't be covered by these 2 checks and would still represent a valid
> > > > > DT binding.
> > > > 
> > > > phylink_set_max_fixed_link() already excludes itself:
> > > > 
> > > >         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
> >                                                       ~~~~~~~~~~
> > 
> > If not NULL, this is an SFP PHY, right? In other words, it's supposed to protect from
> > phylink_sfp_connect_phy() - code involuntarily triggered by phylink_create() ->
> > phylink_register_sfp() - and not from calls to phylink_{,fwnode_}connect_phy()
> > that were initiated by the phylink user between phylink_create() and
> > phylink_set_max_fixed_link(), correct? Those are specified as invalid in the
> > kerneldoc and that's about it - that's not what the checking is for, correct?
> 
> No, it's not to do with sfps at all, but to do with enforcing the
> pre-conditions for the function - that entire line is checking that
> (a) we are in a sane state to be called, and (b) there is no
> configuration initialisation beyond the default done by
> phylink_create() - in other words, there is no in-band or fixed-link
> specified.
> 
> Let's go through this step by step.
> 
> 1. pl->cfg_link_an_mode != MLO_AN_PHY
>    The default value for cfg_link_an_mode is MLO_AN_PHY. If it's
>    anything other than that, then a fixed-link or in-band mode has
>    been specified, and we don't want to override that. So this call
>    needs to fail.

Thanks for the explanation.

Yes, I noticed that phylink_set_max_fixed_link() relies on the fact that
pl->cfg_link_an_mode has the unset value of 0, which coincidentally is
MLO_AN_PHY.

> 2. pl->phydev
>    If a PHY has been attached, then the pre-condition for calling this
>    function immediately after phylink_create() has been violated,
>    because the only way it can be non-NULL is if someone's called one of
>    the phylink functions that connects a PHY. Note: SFPs will not set
>    their PHY here, because, for them to discover that there's a PHY, the
>    network interface needs to be up, and it will never be up here... but
>    in any case...

Ok, so this does check for a precondition that the caller did something
correctly. But it doesn't (and can't) check that all preconditions and
postconditions are satisfied. That's one of my irks, why bother checking
the easy to satisfy precondition (which depends on the code organization,
static information, easy to check), and give up on the hard one (which
depends on the device tree blob, dynamic information, not so easy).

> > So this is what I don't understand. If we've called phylink_set_max_fixed_link()
> > we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
> > silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
> > predicts if it's going to call either of those connect_phy() functions,
> > and calls phylink_set_max_fixed_link() only if it won't. Right?
> > 
> > You've structured the checks in this "distributed" way because phylink
> > can't really predict whether phylink_{,fwnode_}connect_phy() will be
> > called after phylink_set_max_fixed_link(), right? I mean, it can
> > probably predict the fwnode_ variant, but not phylink_connect_phy, and
> > this is why it is up to the caller to decide when to call and when not to.
> 
> phylink has no idea whether phylink_fwnode_connect_phy() will be called
> with the same fwnode as phylink_create(), so it really can't make any
> assumptions about whether there will be a PHY or not.

This is interesting. Is there a use case for passing a different
fwnode_handle to the 2 functions?

> > It should maybe also
> > say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
> > is going to be called later.
> 
> It's already a precondition that phylink_{,fwnode_}connect_phy() fail if
> we're in fixed-link mode (because PHYs have never been supported when in
> fixed-link mode - if one remembers, the old fixed-link code used to
> provide its own emulation of a PHY to make fixed-links work.) So PHYs
> and fixed-links have always been mutually exclusive before phylink, and
> continue to be so with phylink.

Define "fail" exactly, because if I look in phylink_fwnode_phy_connect(), I see:

	/* Fixed links and 802.3z are handled without needing a PHY */
	if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
	    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
	     phy_interface_mode_is_8023z(pl->link_interface)))
		return 0; <- does this count as failure?

This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
without checking whether it has a fixed-link or a PHY, because it
doesn't fail even if it doesn't do anything.

In fact I've wanted to make a correction to my previous phrasing that
"this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
going to be called later". The correction is "... with a phy-handle".

> > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > based on the following?
> > 
> > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> >     condition from phylink_fwnode_phy_connect():
> > 
> > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > 	if (IS_ERR(phy_fwnode)) {
> > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > 			return -ENODEV; <- here
> > 		return 0;
> > 	}
> 
> My question in response would be - why should this DSA specific behaviour
> be handled completely internally within phylink, when it's a DSA
> specific behaviour? Why do we need boolean flags for this?

Because the end result will be simpler if we respect the separation of
concerns that continues to exist, and it's still phylink's business to
say what is and isn't valid. DSA still isn't aware of the bindings
required by phylink, it just passes its fwnode to it. Practically
speaking, I wouldn't be scratching my head as to why we're checking for
half the prerequisites of phylink_set_max_fixed_link() in one place and
for the other half in another.

True, through this patch set DSA is creating its own context specific
extension of phylink bindings, but arguably those existed before DSA was
even integrated with phylink, and we're just fixing something now we
didn't realize at the time we'd need to do.

I can reverse the question, why would phylink even want to be involved
in how the max fixed link parameters are deduced, and it doesn't just
require that a fixed-link software node is constructed somehow
(irrelevant to phylink how), and phylink is just modified to find and
work with that if it exists? Isn't it for the exact same reason,
separation of concerns, that it's easiest for phylink to figure out what
is the most appropriate maximum fixed-link configuration?

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 16:38               ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 16:38 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 04:48:12PM +0100, Russell King (Oracle) wrote:
> On Thu, Jul 07, 2022 at 06:27:27PM +0300, Vladimir Oltean wrote:
> > On Thu, Jul 07, 2022 at 11:09:43AM +0100, Russell King (Oracle) wrote:
> > > On Wed, Jul 06, 2022 at 05:24:09PM +0100, Russell King (Oracle) wrote:
> > > > On Wed, Jul 06, 2022 at 01:26:21PM +0300, Vladimir Oltean wrote:
> > > > > Can we please limit phylink_set_max_link_speed() to just the CPU ports
> > > > > where a fixed-link property is also missing, not just a phy-handle?
> > > > > Although to be entirely correct, we can also have MLO_AN_INBAND, which
> > > > > wouldn't be covered by these 2 checks and would still represent a valid
> > > > > DT binding.
> > > > 
> > > > phylink_set_max_fixed_link() already excludes itself:
> > > > 
> > > >         if (pl->cfg_link_an_mode != MLO_AN_PHY || pl->phydev || pl->sfp_bus)
> >                                                       ~~~~~~~~~~
> > 
> > If not NULL, this is an SFP PHY, right? In other words, it's supposed to protect from
> > phylink_sfp_connect_phy() - code involuntarily triggered by phylink_create() ->
> > phylink_register_sfp() - and not from calls to phylink_{,fwnode_}connect_phy()
> > that were initiated by the phylink user between phylink_create() and
> > phylink_set_max_fixed_link(), correct? Those are specified as invalid in the
> > kerneldoc and that's about it - that's not what the checking is for, correct?
> 
> No, it's not to do with sfps at all, but to do with enforcing the
> pre-conditions for the function - that entire line is checking that
> (a) we are in a sane state to be called, and (b) there is no
> configuration initialisation beyond the default done by
> phylink_create() - in other words, there is no in-band or fixed-link
> specified.
> 
> Let's go through this step by step.
> 
> 1. pl->cfg_link_an_mode != MLO_AN_PHY
>    The default value for cfg_link_an_mode is MLO_AN_PHY. If it's
>    anything other than that, then a fixed-link or in-band mode has
>    been specified, and we don't want to override that. So this call
>    needs to fail.

Thanks for the explanation.

Yes, I noticed that phylink_set_max_fixed_link() relies on the fact that
pl->cfg_link_an_mode has the unset value of 0, which coincidentally is
MLO_AN_PHY.

> 2. pl->phydev
>    If a PHY has been attached, then the pre-condition for calling this
>    function immediately after phylink_create() has been violated,
>    because the only way it can be non-NULL is if someone's called one of
>    the phylink functions that connects a PHY. Note: SFPs will not set
>    their PHY here, because, for them to discover that there's a PHY, the
>    network interface needs to be up, and it will never be up here... but
>    in any case...

Ok, so this does check for a precondition that the caller did something
correctly. But it doesn't (and can't) check that all preconditions and
postconditions are satisfied. That's one of my irks, why bother checking
the easy to satisfy precondition (which depends on the code organization,
static information, easy to check), and give up on the hard one (which
depends on the device tree blob, dynamic information, not so easy).

> > So this is what I don't understand. If we've called phylink_set_max_fixed_link()
> > we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
> > silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
> > predicts if it's going to call either of those connect_phy() functions,
> > and calls phylink_set_max_fixed_link() only if it won't. Right?
> > 
> > You've structured the checks in this "distributed" way because phylink
> > can't really predict whether phylink_{,fwnode_}connect_phy() will be
> > called after phylink_set_max_fixed_link(), right? I mean, it can
> > probably predict the fwnode_ variant, but not phylink_connect_phy, and
> > this is why it is up to the caller to decide when to call and when not to.
> 
> phylink has no idea whether phylink_fwnode_connect_phy() will be called
> with the same fwnode as phylink_create(), so it really can't make any
> assumptions about whether there will be a PHY or not.

This is interesting. Is there a use case for passing a different
fwnode_handle to the 2 functions?

> > It should maybe also
> > say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
> > is going to be called later.
> 
> It's already a precondition that phylink_{,fwnode_}connect_phy() fail if
> we're in fixed-link mode (because PHYs have never been supported when in
> fixed-link mode - if one remembers, the old fixed-link code used to
> provide its own emulation of a PHY to make fixed-links work.) So PHYs
> and fixed-links have always been mutually exclusive before phylink, and
> continue to be so with phylink.

Define "fail" exactly, because if I look in phylink_fwnode_phy_connect(), I see:

	/* Fixed links and 802.3z are handled without needing a PHY */
	if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
	    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
	     phy_interface_mode_is_8023z(pl->link_interface)))
		return 0; <- does this count as failure?

This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
without checking whether it has a fixed-link or a PHY, because it
doesn't fail even if it doesn't do anything.

In fact I've wanted to make a correction to my previous phrasing that
"this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
going to be called later". The correction is "... with a phy-handle".

> > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > based on the following?
> > 
> > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> >     condition from phylink_fwnode_phy_connect():
> > 
> > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > 	if (IS_ERR(phy_fwnode)) {
> > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > 			return -ENODEV; <- here
> > 		return 0;
> > 	}
> 
> My question in response would be - why should this DSA specific behaviour
> be handled completely internally within phylink, when it's a DSA
> specific behaviour? Why do we need boolean flags for this?

Because the end result will be simpler if we respect the separation of
concerns that continues to exist, and it's still phylink's business to
say what is and isn't valid. DSA still isn't aware of the bindings
required by phylink, it just passes its fwnode to it. Practically
speaking, I wouldn't be scratching my head as to why we're checking for
half the prerequisites of phylink_set_max_fixed_link() in one place and
for the other half in another.

True, through this patch set DSA is creating its own context specific
extension of phylink bindings, but arguably those existed before DSA was
even integrated with phylink, and we're just fixing something now we
didn't realize at the time we'd need to do.

I can reverse the question, why would phylink even want to be involved
in how the max fixed link parameters are deduced, and it doesn't just
require that a fixed-link software node is constructed somehow
(irrelevant to phylink how), and phylink is just modified to find and
work with that if it exists? Isn't it for the exact same reason,
separation of concerns, that it's easiest for phylink to figure out what
is the most appropriate maximum fixed-link configuration?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 16:32           ` Russell King (Oracle)
@ 2022-07-07 16:50             ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 16:50 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 05:32:57PM +0100, Russell King (Oracle) wrote:
> Great, so I'll mark ocelot is safe.

Yes, please.

> > As for sja1105, there is DT validation that checks for the presence of
> > all required properties in sja1105_parse_ports_node().
> 
> Looking at those, it requires all of:
> 
> - a phy mode to be specified (as determined by of_get_phy_mode())
> - a phy-handle or of_phy_is_fixed_link() to return true
> 
> otherwise it errors out.

I know. The problem with this ad-hoc validation is that it doesn't cover
the pure MLO_AN_INBAND:

	managed = "in-band-status";

so it is more restrictive than it needs to be. Also it doesn't recognize
the presence of an SFP bus in MLO_AN_PHY mode.

That is part 1 of my problem. I want to have validation that I'm
providing phylink with all the right things it may need, but I don't
want to make the driver code super clunky. By checking just the presence of
either phy-handle or fixed-link I am rejecting valid phylink configurations.
What I need is a validation function that is actually in sync with
phylink, not just ad-hoc.

> > There is some DT validation in felix_parse_ports_node() too, but it
> > doesn't check that all specifiers that phylink might use are there.
> 
> Phylink (correction, fwnode_get_phy_node() which is not part of phylink
> anymore) will look for phy-handle, phy, or phy-device. This is I don't
> see that there's any incompatibility between what the driver is doing
> and what phylink does.
> 
> If there's a fixed-link property, then sja1105_parse_ports_node() is
> happy, and so will phylink. If there's a phy-handle, the same is true.
> If there's a "phy" or "phy-device" then sja1105_parse_ports_node()
> errors out. That's completely fine.
> 
> "phy" and "phy-device" are the backwards compatibility for DT - I
> believe one of them is the ePAPR specified property that we in Linux
> have decided to only fall back on if there's not our more modern
> "phy-handle" property.
> 
> It seems We have a lot of users of "phy" in DT today, so we can't drop
> that from generic code such as phylink, but I haven't found any users
> of "phy-device".
> 
> > I'd really like to add some validation before I gain any involuntary
> > users, but all open-coded constructs I can come up with are clumsy.
> > What would you suggest, if I explicitly don't want to rely on
> > context-specific phylink interpretation of empty OF nodes, and rather
> > error out?
> 
> So I also don't see a problem - sja1105 rejects DTs that fail to
> describe a port using at least one of a phy-handle, a fixed-link, or
> a managed in-band link, and I don't think it needs to do further
> validation, certainly not for the phy describing properties that
> the kernel has chosen to deprecate for new implementations.

And this is part 2 of my problem, ocelot/felix doesn't have validation
at all except for phy-mode, because if it were to simply copy the
phy-handle/fixed-link either/or logic from sja1105, it would break some
customer boards with SFP cages. But without that validation, I am
exposing this driver to configurations I don't want it to support (CPU
ports with empty OF nodes, i.o.w. what this patch set is about).

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 16:50             ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 16:50 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 05:32:57PM +0100, Russell King (Oracle) wrote:
> Great, so I'll mark ocelot is safe.

Yes, please.

> > As for sja1105, there is DT validation that checks for the presence of
> > all required properties in sja1105_parse_ports_node().
> 
> Looking at those, it requires all of:
> 
> - a phy mode to be specified (as determined by of_get_phy_mode())
> - a phy-handle or of_phy_is_fixed_link() to return true
> 
> otherwise it errors out.

I know. The problem with this ad-hoc validation is that it doesn't cover
the pure MLO_AN_INBAND:

	managed = "in-band-status";

so it is more restrictive than it needs to be. Also it doesn't recognize
the presence of an SFP bus in MLO_AN_PHY mode.

That is part 1 of my problem. I want to have validation that I'm
providing phylink with all the right things it may need, but I don't
want to make the driver code super clunky. By checking just the presence of
either phy-handle or fixed-link I am rejecting valid phylink configurations.
What I need is a validation function that is actually in sync with
phylink, not just ad-hoc.

> > There is some DT validation in felix_parse_ports_node() too, but it
> > doesn't check that all specifiers that phylink might use are there.
> 
> Phylink (correction, fwnode_get_phy_node() which is not part of phylink
> anymore) will look for phy-handle, phy, or phy-device. This is I don't
> see that there's any incompatibility between what the driver is doing
> and what phylink does.
> 
> If there's a fixed-link property, then sja1105_parse_ports_node() is
> happy, and so will phylink. If there's a phy-handle, the same is true.
> If there's a "phy" or "phy-device" then sja1105_parse_ports_node()
> errors out. That's completely fine.
> 
> "phy" and "phy-device" are the backwards compatibility for DT - I
> believe one of them is the ePAPR specified property that we in Linux
> have decided to only fall back on if there's not our more modern
> "phy-handle" property.
> 
> It seems We have a lot of users of "phy" in DT today, so we can't drop
> that from generic code such as phylink, but I haven't found any users
> of "phy-device".
> 
> > I'd really like to add some validation before I gain any involuntary
> > users, but all open-coded constructs I can come up with are clumsy.
> > What would you suggest, if I explicitly don't want to rely on
> > context-specific phylink interpretation of empty OF nodes, and rather
> > error out?
> 
> So I also don't see a problem - sja1105 rejects DTs that fail to
> describe a port using at least one of a phy-handle, a fixed-link, or
> a managed in-band link, and I don't think it needs to do further
> validation, certainly not for the phy describing properties that
> the kernel has chosen to deprecate for new implementations.

And this is part 2 of my problem, ocelot/felix doesn't have validation
at all except for phy-mode, because if it were to simply copy the
phy-handle/fixed-link either/or logic from sja1105, it would break some
customer boards with SFP cages. But without that validation, I am
exposing this driver to configurations I don't want it to support (CPU
ports with empty OF nodes, i.o.w. what this patch set is about).

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 16:38               ` Vladimir Oltean
@ 2022-07-07 17:15                 ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 17:15 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 07:38:31PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 04:48:12PM +0100, Russell King (Oracle) wrote:
> > Let's go through this step by step.
> > 
> > 1. pl->cfg_link_an_mode != MLO_AN_PHY
> >    The default value for cfg_link_an_mode is MLO_AN_PHY. If it's
> >    anything other than that, then a fixed-link or in-band mode has
> >    been specified, and we don't want to override that. So this call
> >    needs to fail.
> 
> Thanks for the explanation.
> 
> Yes, I noticed that phylink_set_max_fixed_link() relies on the fact that
> pl->cfg_link_an_mode has the unset value of 0, which coincidentally is
> MLO_AN_PHY.
> 
> > 2. pl->phydev
> >    If a PHY has been attached, then the pre-condition for calling this
> >    function immediately after phylink_create() has been violated,
> >    because the only way it can be non-NULL is if someone's called one of
> >    the phylink functions that connects a PHY. Note: SFPs will not set
> >    their PHY here, because, for them to discover that there's a PHY, the
> >    network interface needs to be up, and it will never be up here... but
> >    in any case...
> 
> Ok, so this does check for a precondition that the caller did something
> correctly. But it doesn't (and can't) check that all preconditions and
> postconditions are satisfied. That's one of my irks, why bother checking
> the easy to satisfy precondition (which depends on the code organization,
> static information, easy to check), and give up on the hard one (which
> depends on the device tree blob, dynamic information, not so easy).

So what you're asking is: why bother doing any checks if you can't do
all of them?

My response would be: isn't best effort better than doing nothing?

In my mind, it is best effort, because:

a) if you've called it when the preconditions (with the exception of a
future PHY) are not satisfied, then it fails with -EBUSY.
b) if this call succeeds, then it locks out the future ability to bind
a PHY.

So, if one forgets to check whether there'll be a future PHY, and call
this anyway, then a future attempt to bind a PHY to phylink fails and
you get a failure.

Considering that we are only talking about DSA making use of this (no
other network driver has this behaviour) and this is being handled by
core DSA code, we could label this up as "this is for DSA use only."

> > > So this is what I don't understand. If we've called phylink_set_max_fixed_link()
> > > we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
> > > silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
> > > predicts if it's going to call either of those connect_phy() functions,
> > > and calls phylink_set_max_fixed_link() only if it won't. Right?
> > > 
> > > You've structured the checks in this "distributed" way because phylink
> > > can't really predict whether phylink_{,fwnode_}connect_phy() will be
> > > called after phylink_set_max_fixed_link(), right? I mean, it can
> > > probably predict the fwnode_ variant, but not phylink_connect_phy, and
> > > this is why it is up to the caller to decide when to call and when not to.
> > 
> > phylink has no idea whether phylink_fwnode_connect_phy() will be called
> > with the same fwnode as phylink_create(), so it really can't make any
> > assumptions about whether there will be a PHY or not.
> 
> This is interesting. Is there a use case for passing a different
> fwnode_handle to the 2 functions?

That depends on the driver. It looks like
drivers/net/ethernet/ti/am65-cpsw-nuss.c may well pass in different nodes
in the firmware tree.

> > > It should maybe also
> > > say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
> > > is going to be called later.
> > 
> > It's already a precondition that phylink_{,fwnode_}connect_phy() fail if
> > we're in fixed-link mode (because PHYs have never been supported when in
> > fixed-link mode - if one remembers, the old fixed-link code used to
> > provide its own emulation of a PHY to make fixed-links work.) So PHYs
> > and fixed-links have always been mutually exclusive before phylink, and
> > continue to be so with phylink.
> 
> Define "fail" exactly, because if I look in phylink_fwnode_phy_connect(), I see:
> 
> 	/* Fixed links and 802.3z are handled without needing a PHY */
> 	if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
> 	    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
> 	     phy_interface_mode_is_8023z(pl->link_interface)))
> 		return 0; <- does this count as failure?

Sorry, yes, that is correct - it ignores the attempt (so drivers don't
have to conditionalise the call for this everywhere.)

> This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
> without checking whether it has a fixed-link or a PHY, because it
> doesn't fail even if it doesn't do anything.
> 
> In fact I've wanted to make a correction to my previous phrasing that
> "this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
> going to be called later". The correction is "... with a phy-handle".

I'm not sure that clarification makes sense when talking about
phylink_connect_phy(), so I think if you're clarifying it with a
firmware property, you're only talking about
phylink_fwnode_connect_phy() now?

> > > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > > based on the following?
> > > 
> > > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> > >     condition from phylink_fwnode_phy_connect():
> > > 
> > > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > > 	if (IS_ERR(phy_fwnode)) {
> > > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > > 			return -ENODEV; <- here
> > > 		return 0;
> > > 	}
> > 
> > My question in response would be - why should this DSA specific behaviour
> > be handled completely internally within phylink, when it's a DSA
> > specific behaviour? Why do we need boolean flags for this?
> 
> Because the end result will be simpler if we respect the separation of
> concerns that continues to exist, and it's still phylink's business to
> say what is and isn't valid. DSA still isn't aware of the bindings
> required by phylink, it just passes its fwnode to it. Practically
> speaking, I wouldn't be scratching my head as to why we're checking for
> half the prerequisites of phylink_set_max_fixed_link() in one place and
> for the other half in another.
> 
> True, through this patch set DSA is creating its own context specific
> extension of phylink bindings, but arguably those existed before DSA was
> even integrated with phylink, and we're just fixing something now we
> didn't realize at the time we'd need to do.
> 
> I can reverse the question, why would phylink even want to be involved
> in how the max fixed link parameters are deduced, and it doesn't just
> require that a fixed-link software node is constructed somehow
> (irrelevant to phylink how), and phylink is just modified to find and
> work with that if it exists? Isn't it for the exact same reason,
> separation of concerns, that it's easiest for phylink to figure out what
> is the most appropriate maximum fixed-link configuration?

If that could be done, I'd love it, because then we don't have this in
phylink at all, and it can all be a DSA problem to solve. It also means
that others won't be tempted to use the interface incorrectly.

I'm not sure how practical that is when we have both DT and ACPI to deal
with, and ACPI is certainly out of my knowledge area to be able to
construct a software node to specify a fixed-link. Maybe it can be done
at the fwnode layer? I don't know.

Do you have a handy example of what you're suggesting?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 17:15                 ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 17:15 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 07:38:31PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 04:48:12PM +0100, Russell King (Oracle) wrote:
> > Let's go through this step by step.
> > 
> > 1. pl->cfg_link_an_mode != MLO_AN_PHY
> >    The default value for cfg_link_an_mode is MLO_AN_PHY. If it's
> >    anything other than that, then a fixed-link or in-band mode has
> >    been specified, and we don't want to override that. So this call
> >    needs to fail.
> 
> Thanks for the explanation.
> 
> Yes, I noticed that phylink_set_max_fixed_link() relies on the fact that
> pl->cfg_link_an_mode has the unset value of 0, which coincidentally is
> MLO_AN_PHY.
> 
> > 2. pl->phydev
> >    If a PHY has been attached, then the pre-condition for calling this
> >    function immediately after phylink_create() has been violated,
> >    because the only way it can be non-NULL is if someone's called one of
> >    the phylink functions that connects a PHY. Note: SFPs will not set
> >    their PHY here, because, for them to discover that there's a PHY, the
> >    network interface needs to be up, and it will never be up here... but
> >    in any case...
> 
> Ok, so this does check for a precondition that the caller did something
> correctly. But it doesn't (and can't) check that all preconditions and
> postconditions are satisfied. That's one of my irks, why bother checking
> the easy to satisfy precondition (which depends on the code organization,
> static information, easy to check), and give up on the hard one (which
> depends on the device tree blob, dynamic information, not so easy).

So what you're asking is: why bother doing any checks if you can't do
all of them?

My response would be: isn't best effort better than doing nothing?

In my mind, it is best effort, because:

a) if you've called it when the preconditions (with the exception of a
future PHY) are not satisfied, then it fails with -EBUSY.
b) if this call succeeds, then it locks out the future ability to bind
a PHY.

So, if one forgets to check whether there'll be a future PHY, and call
this anyway, then a future attempt to bind a PHY to phylink fails and
you get a failure.

Considering that we are only talking about DSA making use of this (no
other network driver has this behaviour) and this is being handled by
core DSA code, we could label this up as "this is for DSA use only."

> > > So this is what I don't understand. If we've called phylink_set_max_fixed_link()
> > > we've changed pl->cfg_link_an_mode to MLO_AN_FIXED and this will
> > > silently break future calls to phylink_{,fwnode_}connect_phy(), so DSA
> > > predicts if it's going to call either of those connect_phy() functions,
> > > and calls phylink_set_max_fixed_link() only if it won't. Right?
> > > 
> > > You've structured the checks in this "distributed" way because phylink
> > > can't really predict whether phylink_{,fwnode_}connect_phy() will be
> > > called after phylink_set_max_fixed_link(), right? I mean, it can
> > > probably predict the fwnode_ variant, but not phylink_connect_phy, and
> > > this is why it is up to the caller to decide when to call and when not to.
> > 
> > phylink has no idea whether phylink_fwnode_connect_phy() will be called
> > with the same fwnode as phylink_create(), so it really can't make any
> > assumptions about whether there will be a PHY or not.
> 
> This is interesting. Is there a use case for passing a different
> fwnode_handle to the 2 functions?

That depends on the driver. It looks like
drivers/net/ethernet/ti/am65-cpsw-nuss.c may well pass in different nodes
in the firmware tree.

> > > It should maybe also
> > > say that this function shouldn't be called if phylink_{,fwnode_}connect_phy()
> > > is going to be called later.
> > 
> > It's already a precondition that phylink_{,fwnode_}connect_phy() fail if
> > we're in fixed-link mode (because PHYs have never been supported when in
> > fixed-link mode - if one remembers, the old fixed-link code used to
> > provide its own emulation of a PHY to make fixed-links work.) So PHYs
> > and fixed-links have always been mutually exclusive before phylink, and
> > continue to be so with phylink.
> 
> Define "fail" exactly, because if I look in phylink_fwnode_phy_connect(), I see:
> 
> 	/* Fixed links and 802.3z are handled without needing a PHY */
> 	if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
> 	    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
> 	     phy_interface_mode_is_8023z(pl->link_interface)))
> 		return 0; <- does this count as failure?

Sorry, yes, that is correct - it ignores the attempt (so drivers don't
have to conditionalise the call for this everywhere.)

> This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
> without checking whether it has a fixed-link or a PHY, because it
> doesn't fail even if it doesn't do anything.
> 
> In fact I've wanted to make a correction to my previous phrasing that
> "this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
> going to be called later". The correction is "... with a phy-handle".

I'm not sure that clarification makes sense when talking about
phylink_connect_phy(), so I think if you're clarifying it with a
firmware property, you're only talking about
phylink_fwnode_connect_phy() now?

> > > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > > based on the following?
> > > 
> > > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> > >     condition from phylink_fwnode_phy_connect():
> > > 
> > > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > > 	if (IS_ERR(phy_fwnode)) {
> > > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > > 			return -ENODEV; <- here
> > > 		return 0;
> > > 	}
> > 
> > My question in response would be - why should this DSA specific behaviour
> > be handled completely internally within phylink, when it's a DSA
> > specific behaviour? Why do we need boolean flags for this?
> 
> Because the end result will be simpler if we respect the separation of
> concerns that continues to exist, and it's still phylink's business to
> say what is and isn't valid. DSA still isn't aware of the bindings
> required by phylink, it just passes its fwnode to it. Practically
> speaking, I wouldn't be scratching my head as to why we're checking for
> half the prerequisites of phylink_set_max_fixed_link() in one place and
> for the other half in another.
> 
> True, through this patch set DSA is creating its own context specific
> extension of phylink bindings, but arguably those existed before DSA was
> even integrated with phylink, and we're just fixing something now we
> didn't realize at the time we'd need to do.
> 
> I can reverse the question, why would phylink even want to be involved
> in how the max fixed link parameters are deduced, and it doesn't just
> require that a fixed-link software node is constructed somehow
> (irrelevant to phylink how), and phylink is just modified to find and
> work with that if it exists? Isn't it for the exact same reason,
> separation of concerns, that it's easiest for phylink to figure out what
> is the most appropriate maximum fixed-link configuration?

If that could be done, I'd love it, because then we don't have this in
phylink at all, and it can all be a DSA problem to solve. It also means
that others won't be tempted to use the interface incorrectly.

I'm not sure how practical that is when we have both DT and ACPI to deal
with, and ACPI is certainly out of my knowledge area to be able to
construct a software node to specify a fixed-link. Maybe it can be done
at the fwnode layer? I don't know.

Do you have a handy example of what you're suggesting?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 17:15                 ` Russell King (Oracle)
@ 2022-07-07 19:37                   ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 19:37 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 06:15:46PM +0100, Russell King (Oracle) wrote:
> > This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
> > without checking whether it has a fixed-link or a PHY, because it
> > doesn't fail even if it doesn't do anything.
> > 
> > In fact I've wanted to make a correction to my previous phrasing that
> > "this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
> > going to be called later". The correction is "... with a phy-handle".
> 
> I'm not sure that clarification makes sense when talking about
> phylink_connect_phy(), so I think if you're clarifying it with a
> firmware property, you're only talking about
> phylink_fwnode_connect_phy() now?

Yes, it's super hard to verbalize, and this is the reason why I didn't
add "... with a phy-handle" in the first place.

I wanted to say: phylink_connect_phy(), OR phylink_fwnode_connect_phy()
WITH a phy-handle. I shouldn't have conflated them in the first place.

> > > > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > > > based on the following?
> > > > 
> > > > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > > > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > > > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> > > >     condition from phylink_fwnode_phy_connect():
> > > > 
> > > > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > > > 	if (IS_ERR(phy_fwnode)) {
> > > > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > > > 			return -ENODEV; <- here
> > > > 		return 0;
> > > > 	}
> > > 
> > > My question in response would be - why should this DSA specific behaviour
> > > be handled completely internally within phylink, when it's a DSA
> > > specific behaviour? Why do we need boolean flags for this?
> > 
> > Because the end result will be simpler if we respect the separation of
> > concerns that continues to exist, and it's still phylink's business to
> > say what is and isn't valid. DSA still isn't aware of the bindings
> > required by phylink, it just passes its fwnode to it. Practically
> > speaking, I wouldn't be scratching my head as to why we're checking for
> > half the prerequisites of phylink_set_max_fixed_link() in one place and
> > for the other half in another.
> > 
> > True, through this patch set DSA is creating its own context specific
> > extension of phylink bindings, but arguably those existed before DSA was
> > even integrated with phylink, and we're just fixing something now we
> > didn't realize at the time we'd need to do.
> > 
> > I can reverse the question, why would phylink even want to be involved
> > in how the max fixed link parameters are deduced, and it doesn't just
> > require that a fixed-link software node is constructed somehow
> > (irrelevant to phylink how), and phylink is just modified to find and
> > work with that if it exists? Isn't it for the exact same reason,
> > separation of concerns, that it's easiest for phylink to figure out what
> > is the most appropriate maximum fixed-link configuration?
> 
> If that could be done, I'd love it, because then we don't have this in
> phylink at all, and it can all be a DSA problem to solve. It also means
> that others won't be tempted to use the interface incorrectly.
> 
> I'm not sure how practical that is when we have both DT and ACPI to deal
> with, and ACPI is certainly out of my knowledge area to be able to
> construct a software node to specify a fixed-link. Maybe it can be done
> at the fwnode layer? I don't know.

I don't want to be misunderstood. I brought up software nodes because
I'm sure you must have thought about this too, before proposing what you
did here. And unless there's a technical reason against software nodes
(which there doesn't appear to be, but I don't want to get ahead of
myself), I figured you must be OK with phylink absorbing the logic, case
in which I just don't understand why you are pushing back on a proposal
how to make phylink absorb the logic completely.

> Do you have a handy example of what you're suggesting?

No, I didn't, but I thought, how hard can it be, and here's a hacked up
attempt on one of my boards:

From 5d002f03c91b357be304d41f7422969d0dd89f5b Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Thu, 7 Jul 2022 21:04:32 +0300
Subject: [PATCH] dsa_port_fixup_broken_dt

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 arch/arm/boot/dts/ls1021a-tsn.dts      |  5 --
 drivers/base/swnode.c                  | 14 +++-
 drivers/net/dsa/sja1105/sja1105_main.c |  4 +-
 include/linux/property.h               |  4 ++
 net/dsa/dsa_priv.h                     |  2 +-
 net/dsa/port.c                         | 99 +++++++++++++++++++++-----
 net/dsa/slave.c                        |  2 +-
 7 files changed, 100 insertions(+), 30 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a-tsn.dts b/arch/arm/boot/dts/ls1021a-tsn.dts
index 1ea32fff4120..c577f90057c7 100644
--- a/arch/arm/boot/dts/ls1021a-tsn.dts
+++ b/arch/arm/boot/dts/ls1021a-tsn.dts
@@ -94,11 +94,6 @@ port@4 {
 				rx-internal-delay-ps = <0>;
 				tx-internal-delay-ps = <0>;
 				reg = <4>;
-
-				fixed-link {
-					speed = <1000>;
-					full-duplex;
-				};
 			};
 		};
 	};
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 0a482212c7e8..b2ea08f0e898 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -972,8 +972,9 @@ void software_node_unregister(const struct software_node *node)
 EXPORT_SYMBOL_GPL(software_node_unregister);
 
 struct fwnode_handle *
-fwnode_create_software_node(const struct property_entry *properties,
-			    const struct fwnode_handle *parent)
+fwnode_create_named_software_node(const struct property_entry *properties,
+				  const struct fwnode_handle *parent,
+				  const char *name)
 {
 	struct fwnode_handle *fwnode;
 	struct software_node *node;
@@ -991,6 +992,7 @@ fwnode_create_software_node(const struct property_entry *properties,
 		return ERR_CAST(node);
 
 	node->parent = p ? p->node : NULL;
+	node->name = name;
 
 	fwnode = swnode_register(node, p, 1);
 	if (IS_ERR(fwnode))
@@ -998,6 +1000,14 @@ fwnode_create_software_node(const struct property_entry *properties,
 
 	return fwnode;
 }
+EXPORT_SYMBOL_GPL(fwnode_create_named_software_node);
+
+struct fwnode_handle *
+fwnode_create_software_node(const struct property_entry *properties,
+			    const struct fwnode_handle *parent)
+{
+	return fwnode_create_named_software_node(properties, parent, NULL);
+}
 EXPORT_SYMBOL_GPL(fwnode_create_software_node);
 
 void fwnode_remove_software_node(struct fwnode_handle *fwnode)
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index b253e27bcfb4..6c7deebc8d76 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1218,8 +1218,8 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv,
 			if (!of_phy_is_fixed_link(child)) {
 				dev_err(dev, "phy-handle or fixed-link "
 					"properties missing!\n");
-				of_node_put(child);
-				return -ENODEV;
+//				of_node_put(child);
+//				return -ENODEV;
 			}
 			/* phy-handle is missing, but fixed-link isn't.
 			 * So it's a fixed link. Default to PHY role.
diff --git a/include/linux/property.h b/include/linux/property.h
index a5b429d623f6..23330ae2b1fa 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -492,6 +492,10 @@ void software_node_unregister(const struct software_node *node);
 struct fwnode_handle *
 fwnode_create_software_node(const struct property_entry *properties,
 			    const struct fwnode_handle *parent);
+struct fwnode_handle *
+fwnode_create_named_software_node(const struct property_entry *properties,
+				  const struct fwnode_handle *parent,
+				  const char *name);
 void fwnode_remove_software_node(struct fwnode_handle *fwnode);
 
 int device_add_software_node(struct device *dev, const struct software_node *node);
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index d9722e49864b..95c4e13e2dbf 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -284,7 +284,7 @@ int dsa_port_mrp_add_ring_role(const struct dsa_port *dp,
 			       const struct switchdev_obj_ring_role_mrp *mrp);
 int dsa_port_mrp_del_ring_role(const struct dsa_port *dp,
 			       const struct switchdev_obj_ring_role_mrp *mrp);
-int dsa_port_phylink_create(struct dsa_port *dp);
+int dsa_port_phylink_create(struct dsa_port *dp, struct fwnode_handle *fwnode);
 int dsa_port_link_register_of(struct dsa_port *dp);
 void dsa_port_link_unregister_of(struct dsa_port *dp);
 int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 3738f2d40a0b..4ed9075468f4 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1521,15 +1521,14 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
 	.mac_link_up = dsa_port_phylink_mac_link_up,
 };
 
-int dsa_port_phylink_create(struct dsa_port *dp)
+int dsa_port_phylink_create(struct dsa_port *dp, struct fwnode_handle *fwnode)
 {
 	struct dsa_switch *ds = dp->ds;
 	phy_interface_t mode;
 	int err;
 
-	err = of_get_phy_mode(dp->dn, &mode);
-	if (err)
-		mode = PHY_INTERFACE_MODE_NA;
+	err = fwnode_get_phy_mode(fwnode);
+	mode = err < 0 ? PHY_INTERFACE_MODE_NA : err;
 
 	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
 	 * an indicator of a legacy phylink driver.
@@ -1541,8 +1540,8 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 	if (ds->ops->phylink_get_caps)
 		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
 
-	dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
-				mode, &dsa_port_phylink_mac_ops);
+	dp->pl = phylink_create(&dp->pl_config, fwnode, mode,
+				&dsa_port_phylink_mac_ops);
 	if (IS_ERR(dp->pl)) {
 		pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
 		return PTR_ERR(dp->pl);
@@ -1627,16 +1626,19 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
 	struct device_node *port_dn = dp->dn;
+	struct fwnode_handle *fwnode;
 	int err;
 
 	dp->pl_config.dev = ds->dev;
 	dp->pl_config.type = PHYLINK_DEV;
 
-	err = dsa_port_phylink_create(dp);
+	fwnode = port_dn->fwnode.secondary ? : of_fwnode_handle(port_dn);
+
+	err = dsa_port_phylink_create(dp, fwnode);
 	if (err)
 		return err;
 
-	err = phylink_of_phy_connect(dp->pl, port_dn, 0);
+	err = phylink_fwnode_phy_connect(dp->pl, fwnode, 0);
 	if (err && err != -ENODEV) {
 		pr_err("could not attach to PHY: %d\n", err);
 		goto err_phy_connect;
@@ -1649,23 +1651,82 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
 	return err;
 }
 
+static int dsa_port_fixup_broken_dt(struct dsa_port *dp)
+{
+	struct property_entry fixed_link_props[] = {
+		PROPERTY_ENTRY_BOOL("full-duplex"),
+		PROPERTY_ENTRY_U32("speed", 1000), /* TODO determine actual speed */
+		{},
+	};
+	struct property_entry port_props[3] = {};
+	struct fwnode_handle *fixed_link_fwnode;
+	struct fwnode_handle *new_port_fwnode;
+	struct device_node *dn = dp->dn;
+	phy_interface_t mode;
+	int err;
+
+	if (of_parse_phandle(dn, "phy-handle", 0) ||
+	    of_phy_is_fixed_link(dn))
+		/* Nothing broken, nothing to fix.
+		 * TODO: As discussed with Russell, maybe phylink could provide
+		 * a more comprehensive helper to determine what constitutes a
+		 * valid fwnode binding than this guerilla kludge.
+		 */
+		return 0;
+
+	err = of_get_phy_mode(dn, &mode);
+	if (err)
+		/* TODO this may be missing too, ask the driver for the
+		 * max-speed interface mode for this port
+		 */
+		mode = PHY_INTERFACE_MODE_NA;
+
+	port_props[0] = PROPERTY_ENTRY_U32("reg", dp->index);
+	port_props[1] = PROPERTY_ENTRY_STRING("phy-mode", phy_modes(mode));
+
+	new_port_fwnode = fwnode_create_software_node(port_props, NULL);
+	if (IS_ERR(new_port_fwnode))
+		return PTR_ERR(new_port_fwnode);
+
+	/* Node needs to be named so that phylink's call to
+	 * fwnode_get_named_child_node() finds it.
+	 */
+	fixed_link_fwnode = fwnode_create_named_software_node(fixed_link_props,
+							      new_port_fwnode,
+							      "fixed-link");
+	if (IS_ERR(fixed_link_fwnode)) {
+		fwnode_remove_software_node(new_port_fwnode);
+		return PTR_ERR(fixed_link_fwnode);
+	}
+
+	/* set_secondary_fwnode() takes a struct device as argument,
+	 * and we have none for a port. TODO we need to free this.
+	 */
+	dn->fwnode.secondary = new_port_fwnode;
+
+	return 0;
+}
+
 int dsa_port_link_register_of(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
-	struct device_node *phy_np;
 	int port = dp->index;
+	int err;
+
+	err = dsa_port_fixup_broken_dt(dp);
+	if (err) {
+		dev_err(ds->dev,
+			"Failed to fix up broken DT for shared port %d: %pe\n",
+			dp->index, ERR_PTR(err));
+		return err;
+	}
 
 	if (!ds->ops->adjust_link) {
-		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
-		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
-			if (ds->ops->phylink_mac_link_down)
-				ds->ops->phylink_mac_link_down(ds, port,
-					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
-			of_node_put(phy_np);
-			return dsa_port_phylink_register(dp);
-		}
-		of_node_put(phy_np);
-		return 0;
+		if (ds->ops->phylink_mac_link_down)
+			ds->ops->phylink_mac_link_down(ds, port, MLO_AN_FIXED,
+						       PHY_INTERFACE_MODE_NA);
+
+		return dsa_port_phylink_register(dp);
 	}
 
 	dev_warn(ds->dev,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ad6a6663feeb..f243e73cb522 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2245,7 +2245,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev)
 		dp->pl_config.poll_fixed_state = true;
 	}
 
-	ret = dsa_port_phylink_create(dp);
+	ret = dsa_port_phylink_create(dp, of_fwnode_handle(dp->dn));
 	if (ret)
 		return ret;
 
-- 
2.25.1


It boots and works:

[    4.315754] sja1105 spi0.1: configuring for fixed/rgmii link mode
[    4.322653] sja1105 spi0.1 swp5 (uninitialized): PHY [mdio@2d24000:06] driver [Broadcom BCM5464] (irq=POLL)
[    4.334796] sja1105 spi0.1 swp2 (uninitialized): PHY [mdio@2d24000:03] driver [Broadcom BCM5464] (irq=POLL)
[    4.345853] sja1105 spi0.1 swp3 (uninitialized): PHY [mdio@2d24000:04] driver [Broadcom BCM5464] (irq=POLL)
[    4.356859] sja1105 spi0.1 swp4 (uninitialized): PHY [mdio@2d24000:05] driver [Broadcom BCM5464] (irq=POLL)
[    4.367245] device eth2 entered promiscuous mode
[    4.371864] DSA: tree 0 setup
[    4.376971] sja1105 spi0.1: Link is Up - 1Gbps/Full - flow control off
(...)
root@black:~# ip link set swp2 up && dhclient -i swp2 && ip addr show swp2
[   64.762756] fsl-gianfar soc:ethernet@2d90000 eth2: Link is Up - 1Gbps/Full - flow control off
[   64.771530] sja1105 spi0.1 swp2: configuring for phy/rgmii-id link mode
[   68.955048] sja1105 spi0.1 swp2: Link is Up - 1Gbps/Full - flow control off
12: swp2@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:1f:7b:63:02:48 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.68/24 brd 10.0.0.255 scope global dynamic swp2
       valid_lft 600sec preferred_lft 600sec

It's by far the messiest patch I've posted to the list (in the interest
of responding quickly), but if you study the code you can obviously see
what's missing, basically I've hardcoded the speed to 1000 and I'm
copying the phy-mode from the real DT node.

Unfortunately I don't have the time (and most importantly the interest)
in pushing this any further than that. If you want to take this from
here and integrate it with phylink_get_caps() I'd be glad to review
the result. Otherwise, feel free to continue with phylink_set_max_fixed_link().

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 19:37                   ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 19:37 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 06:15:46PM +0100, Russell King (Oracle) wrote:
> > This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
> > without checking whether it has a fixed-link or a PHY, because it
> > doesn't fail even if it doesn't do anything.
> > 
> > In fact I've wanted to make a correction to my previous phrasing that
> > "this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
> > going to be called later". The correction is "... with a phy-handle".
> 
> I'm not sure that clarification makes sense when talking about
> phylink_connect_phy(), so I think if you're clarifying it with a
> firmware property, you're only talking about
> phylink_fwnode_connect_phy() now?

Yes, it's super hard to verbalize, and this is the reason why I didn't
add "... with a phy-handle" in the first place.

I wanted to say: phylink_connect_phy(), OR phylink_fwnode_connect_phy()
WITH a phy-handle. I shouldn't have conflated them in the first place.

> > > > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > > > based on the following?
> > > > 
> > > > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > > > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > > > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> > > >     condition from phylink_fwnode_phy_connect():
> > > > 
> > > > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > > > 	if (IS_ERR(phy_fwnode)) {
> > > > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > > > 			return -ENODEV; <- here
> > > > 		return 0;
> > > > 	}
> > > 
> > > My question in response would be - why should this DSA specific behaviour
> > > be handled completely internally within phylink, when it's a DSA
> > > specific behaviour? Why do we need boolean flags for this?
> > 
> > Because the end result will be simpler if we respect the separation of
> > concerns that continues to exist, and it's still phylink's business to
> > say what is and isn't valid. DSA still isn't aware of the bindings
> > required by phylink, it just passes its fwnode to it. Practically
> > speaking, I wouldn't be scratching my head as to why we're checking for
> > half the prerequisites of phylink_set_max_fixed_link() in one place and
> > for the other half in another.
> > 
> > True, through this patch set DSA is creating its own context specific
> > extension of phylink bindings, but arguably those existed before DSA was
> > even integrated with phylink, and we're just fixing something now we
> > didn't realize at the time we'd need to do.
> > 
> > I can reverse the question, why would phylink even want to be involved
> > in how the max fixed link parameters are deduced, and it doesn't just
> > require that a fixed-link software node is constructed somehow
> > (irrelevant to phylink how), and phylink is just modified to find and
> > work with that if it exists? Isn't it for the exact same reason,
> > separation of concerns, that it's easiest for phylink to figure out what
> > is the most appropriate maximum fixed-link configuration?
> 
> If that could be done, I'd love it, because then we don't have this in
> phylink at all, and it can all be a DSA problem to solve. It also means
> that others won't be tempted to use the interface incorrectly.
> 
> I'm not sure how practical that is when we have both DT and ACPI to deal
> with, and ACPI is certainly out of my knowledge area to be able to
> construct a software node to specify a fixed-link. Maybe it can be done
> at the fwnode layer? I don't know.

I don't want to be misunderstood. I brought up software nodes because
I'm sure you must have thought about this too, before proposing what you
did here. And unless there's a technical reason against software nodes
(which there doesn't appear to be, but I don't want to get ahead of
myself), I figured you must be OK with phylink absorbing the logic, case
in which I just don't understand why you are pushing back on a proposal
how to make phylink absorb the logic completely.

> Do you have a handy example of what you're suggesting?

No, I didn't, but I thought, how hard can it be, and here's a hacked up
attempt on one of my boards:

From 5d002f03c91b357be304d41f7422969d0dd89f5b Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Thu, 7 Jul 2022 21:04:32 +0300
Subject: [PATCH] dsa_port_fixup_broken_dt

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 arch/arm/boot/dts/ls1021a-tsn.dts      |  5 --
 drivers/base/swnode.c                  | 14 +++-
 drivers/net/dsa/sja1105/sja1105_main.c |  4 +-
 include/linux/property.h               |  4 ++
 net/dsa/dsa_priv.h                     |  2 +-
 net/dsa/port.c                         | 99 +++++++++++++++++++++-----
 net/dsa/slave.c                        |  2 +-
 7 files changed, 100 insertions(+), 30 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a-tsn.dts b/arch/arm/boot/dts/ls1021a-tsn.dts
index 1ea32fff4120..c577f90057c7 100644
--- a/arch/arm/boot/dts/ls1021a-tsn.dts
+++ b/arch/arm/boot/dts/ls1021a-tsn.dts
@@ -94,11 +94,6 @@ port@4 {
 				rx-internal-delay-ps = <0>;
 				tx-internal-delay-ps = <0>;
 				reg = <4>;
-
-				fixed-link {
-					speed = <1000>;
-					full-duplex;
-				};
 			};
 		};
 	};
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 0a482212c7e8..b2ea08f0e898 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -972,8 +972,9 @@ void software_node_unregister(const struct software_node *node)
 EXPORT_SYMBOL_GPL(software_node_unregister);
 
 struct fwnode_handle *
-fwnode_create_software_node(const struct property_entry *properties,
-			    const struct fwnode_handle *parent)
+fwnode_create_named_software_node(const struct property_entry *properties,
+				  const struct fwnode_handle *parent,
+				  const char *name)
 {
 	struct fwnode_handle *fwnode;
 	struct software_node *node;
@@ -991,6 +992,7 @@ fwnode_create_software_node(const struct property_entry *properties,
 		return ERR_CAST(node);
 
 	node->parent = p ? p->node : NULL;
+	node->name = name;
 
 	fwnode = swnode_register(node, p, 1);
 	if (IS_ERR(fwnode))
@@ -998,6 +1000,14 @@ fwnode_create_software_node(const struct property_entry *properties,
 
 	return fwnode;
 }
+EXPORT_SYMBOL_GPL(fwnode_create_named_software_node);
+
+struct fwnode_handle *
+fwnode_create_software_node(const struct property_entry *properties,
+			    const struct fwnode_handle *parent)
+{
+	return fwnode_create_named_software_node(properties, parent, NULL);
+}
 EXPORT_SYMBOL_GPL(fwnode_create_software_node);
 
 void fwnode_remove_software_node(struct fwnode_handle *fwnode)
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index b253e27bcfb4..6c7deebc8d76 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1218,8 +1218,8 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv,
 			if (!of_phy_is_fixed_link(child)) {
 				dev_err(dev, "phy-handle or fixed-link "
 					"properties missing!\n");
-				of_node_put(child);
-				return -ENODEV;
+//				of_node_put(child);
+//				return -ENODEV;
 			}
 			/* phy-handle is missing, but fixed-link isn't.
 			 * So it's a fixed link. Default to PHY role.
diff --git a/include/linux/property.h b/include/linux/property.h
index a5b429d623f6..23330ae2b1fa 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -492,6 +492,10 @@ void software_node_unregister(const struct software_node *node);
 struct fwnode_handle *
 fwnode_create_software_node(const struct property_entry *properties,
 			    const struct fwnode_handle *parent);
+struct fwnode_handle *
+fwnode_create_named_software_node(const struct property_entry *properties,
+				  const struct fwnode_handle *parent,
+				  const char *name);
 void fwnode_remove_software_node(struct fwnode_handle *fwnode);
 
 int device_add_software_node(struct device *dev, const struct software_node *node);
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index d9722e49864b..95c4e13e2dbf 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -284,7 +284,7 @@ int dsa_port_mrp_add_ring_role(const struct dsa_port *dp,
 			       const struct switchdev_obj_ring_role_mrp *mrp);
 int dsa_port_mrp_del_ring_role(const struct dsa_port *dp,
 			       const struct switchdev_obj_ring_role_mrp *mrp);
-int dsa_port_phylink_create(struct dsa_port *dp);
+int dsa_port_phylink_create(struct dsa_port *dp, struct fwnode_handle *fwnode);
 int dsa_port_link_register_of(struct dsa_port *dp);
 void dsa_port_link_unregister_of(struct dsa_port *dp);
 int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 3738f2d40a0b..4ed9075468f4 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1521,15 +1521,14 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
 	.mac_link_up = dsa_port_phylink_mac_link_up,
 };
 
-int dsa_port_phylink_create(struct dsa_port *dp)
+int dsa_port_phylink_create(struct dsa_port *dp, struct fwnode_handle *fwnode)
 {
 	struct dsa_switch *ds = dp->ds;
 	phy_interface_t mode;
 	int err;
 
-	err = of_get_phy_mode(dp->dn, &mode);
-	if (err)
-		mode = PHY_INTERFACE_MODE_NA;
+	err = fwnode_get_phy_mode(fwnode);
+	mode = err < 0 ? PHY_INTERFACE_MODE_NA : err;
 
 	/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
 	 * an indicator of a legacy phylink driver.
@@ -1541,8 +1540,8 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 	if (ds->ops->phylink_get_caps)
 		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
 
-	dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
-				mode, &dsa_port_phylink_mac_ops);
+	dp->pl = phylink_create(&dp->pl_config, fwnode, mode,
+				&dsa_port_phylink_mac_ops);
 	if (IS_ERR(dp->pl)) {
 		pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
 		return PTR_ERR(dp->pl);
@@ -1627,16 +1626,19 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
 	struct device_node *port_dn = dp->dn;
+	struct fwnode_handle *fwnode;
 	int err;
 
 	dp->pl_config.dev = ds->dev;
 	dp->pl_config.type = PHYLINK_DEV;
 
-	err = dsa_port_phylink_create(dp);
+	fwnode = port_dn->fwnode.secondary ? : of_fwnode_handle(port_dn);
+
+	err = dsa_port_phylink_create(dp, fwnode);
 	if (err)
 		return err;
 
-	err = phylink_of_phy_connect(dp->pl, port_dn, 0);
+	err = phylink_fwnode_phy_connect(dp->pl, fwnode, 0);
 	if (err && err != -ENODEV) {
 		pr_err("could not attach to PHY: %d\n", err);
 		goto err_phy_connect;
@@ -1649,23 +1651,82 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
 	return err;
 }
 
+static int dsa_port_fixup_broken_dt(struct dsa_port *dp)
+{
+	struct property_entry fixed_link_props[] = {
+		PROPERTY_ENTRY_BOOL("full-duplex"),
+		PROPERTY_ENTRY_U32("speed", 1000), /* TODO determine actual speed */
+		{},
+	};
+	struct property_entry port_props[3] = {};
+	struct fwnode_handle *fixed_link_fwnode;
+	struct fwnode_handle *new_port_fwnode;
+	struct device_node *dn = dp->dn;
+	phy_interface_t mode;
+	int err;
+
+	if (of_parse_phandle(dn, "phy-handle", 0) ||
+	    of_phy_is_fixed_link(dn))
+		/* Nothing broken, nothing to fix.
+		 * TODO: As discussed with Russell, maybe phylink could provide
+		 * a more comprehensive helper to determine what constitutes a
+		 * valid fwnode binding than this guerilla kludge.
+		 */
+		return 0;
+
+	err = of_get_phy_mode(dn, &mode);
+	if (err)
+		/* TODO this may be missing too, ask the driver for the
+		 * max-speed interface mode for this port
+		 */
+		mode = PHY_INTERFACE_MODE_NA;
+
+	port_props[0] = PROPERTY_ENTRY_U32("reg", dp->index);
+	port_props[1] = PROPERTY_ENTRY_STRING("phy-mode", phy_modes(mode));
+
+	new_port_fwnode = fwnode_create_software_node(port_props, NULL);
+	if (IS_ERR(new_port_fwnode))
+		return PTR_ERR(new_port_fwnode);
+
+	/* Node needs to be named so that phylink's call to
+	 * fwnode_get_named_child_node() finds it.
+	 */
+	fixed_link_fwnode = fwnode_create_named_software_node(fixed_link_props,
+							      new_port_fwnode,
+							      "fixed-link");
+	if (IS_ERR(fixed_link_fwnode)) {
+		fwnode_remove_software_node(new_port_fwnode);
+		return PTR_ERR(fixed_link_fwnode);
+	}
+
+	/* set_secondary_fwnode() takes a struct device as argument,
+	 * and we have none for a port. TODO we need to free this.
+	 */
+	dn->fwnode.secondary = new_port_fwnode;
+
+	return 0;
+}
+
 int dsa_port_link_register_of(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
-	struct device_node *phy_np;
 	int port = dp->index;
+	int err;
+
+	err = dsa_port_fixup_broken_dt(dp);
+	if (err) {
+		dev_err(ds->dev,
+			"Failed to fix up broken DT for shared port %d: %pe\n",
+			dp->index, ERR_PTR(err));
+		return err;
+	}
 
 	if (!ds->ops->adjust_link) {
-		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
-		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
-			if (ds->ops->phylink_mac_link_down)
-				ds->ops->phylink_mac_link_down(ds, port,
-					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
-			of_node_put(phy_np);
-			return dsa_port_phylink_register(dp);
-		}
-		of_node_put(phy_np);
-		return 0;
+		if (ds->ops->phylink_mac_link_down)
+			ds->ops->phylink_mac_link_down(ds, port, MLO_AN_FIXED,
+						       PHY_INTERFACE_MODE_NA);
+
+		return dsa_port_phylink_register(dp);
 	}
 
 	dev_warn(ds->dev,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ad6a6663feeb..f243e73cb522 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2245,7 +2245,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev)
 		dp->pl_config.poll_fixed_state = true;
 	}
 
-	ret = dsa_port_phylink_create(dp);
+	ret = dsa_port_phylink_create(dp, of_fwnode_handle(dp->dn));
 	if (ret)
 		return ret;
 
-- 
2.25.1


It boots and works:

[    4.315754] sja1105 spi0.1: configuring for fixed/rgmii link mode
[    4.322653] sja1105 spi0.1 swp5 (uninitialized): PHY [mdio@2d24000:06] driver [Broadcom BCM5464] (irq=POLL)
[    4.334796] sja1105 spi0.1 swp2 (uninitialized): PHY [mdio@2d24000:03] driver [Broadcom BCM5464] (irq=POLL)
[    4.345853] sja1105 spi0.1 swp3 (uninitialized): PHY [mdio@2d24000:04] driver [Broadcom BCM5464] (irq=POLL)
[    4.356859] sja1105 spi0.1 swp4 (uninitialized): PHY [mdio@2d24000:05] driver [Broadcom BCM5464] (irq=POLL)
[    4.367245] device eth2 entered promiscuous mode
[    4.371864] DSA: tree 0 setup
[    4.376971] sja1105 spi0.1: Link is Up - 1Gbps/Full - flow control off
(...)
root@black:~# ip link set swp2 up && dhclient -i swp2 && ip addr show swp2
[   64.762756] fsl-gianfar soc:ethernet@2d90000 eth2: Link is Up - 1Gbps/Full - flow control off
[   64.771530] sja1105 spi0.1 swp2: configuring for phy/rgmii-id link mode
[   68.955048] sja1105 spi0.1 swp2: Link is Up - 1Gbps/Full - flow control off
12: swp2@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:1f:7b:63:02:48 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.68/24 brd 10.0.0.255 scope global dynamic swp2
       valid_lft 600sec preferred_lft 600sec

It's by far the messiest patch I've posted to the list (in the interest
of responding quickly), but if you study the code you can obviously see
what's missing, basically I've hardcoded the speed to 1000 and I'm
copying the phy-mode from the real DT node.

Unfortunately I don't have the time (and most importantly the interest)
in pushing this any further than that. If you want to take this from
here and integrate it with phylink_get_caps() I'd be glad to review
the result. Otherwise, feel free to continue with phylink_set_max_fixed_link().

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 19:37                   ` Vladimir Oltean
@ 2022-07-07 20:23                     ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 20:23 UTC (permalink / raw)
  To: Vladimir Oltean, Andrew Lunn
  Cc: Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 10:37:53PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 06:15:46PM +0100, Russell King (Oracle) wrote:
> > > This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
> > > without checking whether it has a fixed-link or a PHY, because it
> > > doesn't fail even if it doesn't do anything.
> > > 
> > > In fact I've wanted to make a correction to my previous phrasing that
> > > "this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
> > > going to be called later". The correction is "... with a phy-handle".
> > 
> > I'm not sure that clarification makes sense when talking about
> > phylink_connect_phy(), so I think if you're clarifying it with a
> > firmware property, you're only talking about
> > phylink_fwnode_connect_phy() now?
> 
> Yes, it's super hard to verbalize, and this is the reason why I didn't
> add "... with a phy-handle" in the first place.
> 
> I wanted to say: phylink_connect_phy(), OR phylink_fwnode_connect_phy()
> WITH a phy-handle. I shouldn't have conflated them in the first place.

Ah, right, because I interpreted it quite differently!

> > > > > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > > > > based on the following?
> > > > > 
> > > > > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > > > > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > > > > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> > > > >     condition from phylink_fwnode_phy_connect():
> > > > > 
> > > > > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > > > > 	if (IS_ERR(phy_fwnode)) {
> > > > > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > > > > 			return -ENODEV; <- here
> > > > > 		return 0;
> > > > > 	}
> > > > 
> > > > My question in response would be - why should this DSA specific behaviour
> > > > be handled completely internally within phylink, when it's a DSA
> > > > specific behaviour? Why do we need boolean flags for this?
> > > 
> > > Because the end result will be simpler if we respect the separation of
> > > concerns that continues to exist, and it's still phylink's business to
> > > say what is and isn't valid. DSA still isn't aware of the bindings
> > > required by phylink, it just passes its fwnode to it. Practically
> > > speaking, I wouldn't be scratching my head as to why we're checking for
> > > half the prerequisites of phylink_set_max_fixed_link() in one place and
> > > for the other half in another.
> > > 
> > > True, through this patch set DSA is creating its own context specific
> > > extension of phylink bindings, but arguably those existed before DSA was
> > > even integrated with phylink, and we're just fixing something now we
> > > didn't realize at the time we'd need to do.
> > > 
> > > I can reverse the question, why would phylink even want to be involved
> > > in how the max fixed link parameters are deduced, and it doesn't just
> > > require that a fixed-link software node is constructed somehow
> > > (irrelevant to phylink how), and phylink is just modified to find and
> > > work with that if it exists? Isn't it for the exact same reason,
> > > separation of concerns, that it's easiest for phylink to figure out what
> > > is the most appropriate maximum fixed-link configuration?
> > 
> > If that could be done, I'd love it, because then we don't have this in
> > phylink at all, and it can all be a DSA problem to solve. It also means
> > that others won't be tempted to use the interface incorrectly.
> > 
> > I'm not sure how practical that is when we have both DT and ACPI to deal
> > with, and ACPI is certainly out of my knowledge area to be able to
> > construct a software node to specify a fixed-link. Maybe it can be done
> > at the fwnode layer? I don't know.
> 
> I don't want to be misunderstood. I brought up software nodes because
> I'm sure you must have thought about this too, before proposing what you
> did here. And unless there's a technical reason against software nodes
> (which there doesn't appear to be, but I don't want to get ahead of
> myself), I figured you must be OK with phylink absorbing the logic, case
> in which I just don't understand why you are pushing back on a proposal
> how to make phylink absorb the logic completely.

The reason I hadn't is because switching DSA to fwnode brings with it
issues for ACPI, and Andrew wants to be very careful about ACPI in
networking - and I think quite rightly. As soon as one switches from
DT APIs to fwnode APIs, you basically permit people an easy path to
re-use DT properties in ACPI-land without the ACPI issues being first
considered.

So, I think if we did go this route, we need Andrew's input.

> > Do you have a handy example of what you're suggesting?
> 
> No, I didn't, but I thought, how hard can it be, and here's a hacked up
> attempt on one of my boards:

Thanks - that looks like something that should be possible to do, and
way better than trying to shoe-horn this into phylink.

My only comment would be that Andrew would disagree with you about this
being "fixing up broken DT" - he has actively encouraged some drivers
to adopt this "default" mode, which means it's anything but "broken"
but it really is part of the DSA firmware description.

> [    4.315754] sja1105 spi0.1: configuring for fixed/rgmii link mode
> [    4.322653] sja1105 spi0.1 swp5 (uninitialized): PHY [mdio@2d24000:06] driver [Broadcom BCM5464] (irq=POLL)
> [    4.334796] sja1105 spi0.1 swp2 (uninitialized): PHY [mdio@2d24000:03] driver [Broadcom BCM5464] (irq=POLL)
> [    4.345853] sja1105 spi0.1 swp3 (uninitialized): PHY [mdio@2d24000:04] driver [Broadcom BCM5464] (irq=POLL)
> [    4.356859] sja1105 spi0.1 swp4 (uninitialized): PHY [mdio@2d24000:05] driver [Broadcom BCM5464] (irq=POLL)
> [    4.367245] device eth2 entered promiscuous mode
> [    4.371864] DSA: tree 0 setup
> [    4.376971] sja1105 spi0.1: Link is Up - 1Gbps/Full - flow control off
> (...)
> root@black:~# ip link set swp2 up && dhclient -i swp2 && ip addr show swp2
> [   64.762756] fsl-gianfar soc:ethernet@2d90000 eth2: Link is Up - 1Gbps/Full - flow control off
> [   64.771530] sja1105 spi0.1 swp2: configuring for phy/rgmii-id link mode
> [   68.955048] sja1105 spi0.1 swp2: Link is Up - 1Gbps/Full - flow control off
> 12: swp2@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
>     link/ether 00:1f:7b:63:02:48 brd ff:ff:ff:ff:ff:ff
>     inet 10.0.0.68/24 brd 10.0.0.255 scope global dynamic swp2
>        valid_lft 600sec preferred_lft 600sec
> 
> It's by far the messiest patch I've posted to the list (in the interest
> of responding quickly), but if you study the code you can obviously see
> what's missing, basically I've hardcoded the speed to 1000 and I'm
> copying the phy-mode from the real DT node.

Yep - there's at least one other property we need to carry over from the
DT node, which is the "ethernet" property.

> Unfortunately I don't have the time (and most importantly the interest)
> in pushing this any further than that. If you want to take this from
> here and integrate it with phylink_get_caps() I'd be glad to review
> the result. Otherwise, feel free to continue with phylink_set_max_fixed_link().

I think this could be a much better solution to this problem, quite
simply because we then don't end up with phylink_set_max_fixed_link()
which could be abused - and this keeps the complexity where it should
be, in the DSA code.

As I say, though, I think we need Andrew's input on this. Andrew?

I'll look at turning this into a proper solution tomorrow if Andrew is
okay with the fwnode change.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 20:23                     ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-07 20:23 UTC (permalink / raw)
  To: Vladimir Oltean, Andrew Lunn
  Cc: Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 10:37:53PM +0300, Vladimir Oltean wrote:
> On Thu, Jul 07, 2022 at 06:15:46PM +0100, Russell King (Oracle) wrote:
> > > This is why dsa_port_phylink_register() calls phylink_of_phy_connect()
> > > without checking whether it has a fixed-link or a PHY, because it
> > > doesn't fail even if it doesn't do anything.
> > > 
> > > In fact I've wanted to make a correction to my previous phrasing that
> > > "this function shouldn't be called if phylink_{,fwnode_}connect_phy() is
> > > going to be called later". The correction is "... with a phy-handle".
> > 
> > I'm not sure that clarification makes sense when talking about
> > phylink_connect_phy(), so I think if you're clarifying it with a
> > firmware property, you're only talking about
> > phylink_fwnode_connect_phy() now?
> 
> Yes, it's super hard to verbalize, and this is the reason why I didn't
> add "... with a phy-handle" in the first place.
> 
> I wanted to say: phylink_connect_phy(), OR phylink_fwnode_connect_phy()
> WITH a phy-handle. I shouldn't have conflated them in the first place.

Ah, right, because I interpreted it quite differently!

> > > > > Can phylink absorb all this logic, and automatically call phylink_set_max_fixed_link()
> > > > > based on the following?
> > > > > 
> > > > > (1) struct phylink_config gets extended with a bool fallback_max_fixed_link.
> > > > > (2) DSA CPU and DSA ports set this to true in dsa_port_phylink_register().
> > > > > (3) phylink_set_max_fixed_link() is hooked into this -ENODEV error
> > > > >     condition from phylink_fwnode_phy_connect():
> > > > > 
> > > > > 	phy_fwnode = fwnode_get_phy_node(fwnode);
> > > > > 	if (IS_ERR(phy_fwnode)) {
> > > > > 		if (pl->cfg_link_an_mode == MLO_AN_PHY)
> > > > > 			return -ENODEV; <- here
> > > > > 		return 0;
> > > > > 	}
> > > > 
> > > > My question in response would be - why should this DSA specific behaviour
> > > > be handled completely internally within phylink, when it's a DSA
> > > > specific behaviour? Why do we need boolean flags for this?
> > > 
> > > Because the end result will be simpler if we respect the separation of
> > > concerns that continues to exist, and it's still phylink's business to
> > > say what is and isn't valid. DSA still isn't aware of the bindings
> > > required by phylink, it just passes its fwnode to it. Practically
> > > speaking, I wouldn't be scratching my head as to why we're checking for
> > > half the prerequisites of phylink_set_max_fixed_link() in one place and
> > > for the other half in another.
> > > 
> > > True, through this patch set DSA is creating its own context specific
> > > extension of phylink bindings, but arguably those existed before DSA was
> > > even integrated with phylink, and we're just fixing something now we
> > > didn't realize at the time we'd need to do.
> > > 
> > > I can reverse the question, why would phylink even want to be involved
> > > in how the max fixed link parameters are deduced, and it doesn't just
> > > require that a fixed-link software node is constructed somehow
> > > (irrelevant to phylink how), and phylink is just modified to find and
> > > work with that if it exists? Isn't it for the exact same reason,
> > > separation of concerns, that it's easiest for phylink to figure out what
> > > is the most appropriate maximum fixed-link configuration?
> > 
> > If that could be done, I'd love it, because then we don't have this in
> > phylink at all, and it can all be a DSA problem to solve. It also means
> > that others won't be tempted to use the interface incorrectly.
> > 
> > I'm not sure how practical that is when we have both DT and ACPI to deal
> > with, and ACPI is certainly out of my knowledge area to be able to
> > construct a software node to specify a fixed-link. Maybe it can be done
> > at the fwnode layer? I don't know.
> 
> I don't want to be misunderstood. I brought up software nodes because
> I'm sure you must have thought about this too, before proposing what you
> did here. And unless there's a technical reason against software nodes
> (which there doesn't appear to be, but I don't want to get ahead of
> myself), I figured you must be OK with phylink absorbing the logic, case
> in which I just don't understand why you are pushing back on a proposal
> how to make phylink absorb the logic completely.

The reason I hadn't is because switching DSA to fwnode brings with it
issues for ACPI, and Andrew wants to be very careful about ACPI in
networking - and I think quite rightly. As soon as one switches from
DT APIs to fwnode APIs, you basically permit people an easy path to
re-use DT properties in ACPI-land without the ACPI issues being first
considered.

So, I think if we did go this route, we need Andrew's input.

> > Do you have a handy example of what you're suggesting?
> 
> No, I didn't, but I thought, how hard can it be, and here's a hacked up
> attempt on one of my boards:

Thanks - that looks like something that should be possible to do, and
way better than trying to shoe-horn this into phylink.

My only comment would be that Andrew would disagree with you about this
being "fixing up broken DT" - he has actively encouraged some drivers
to adopt this "default" mode, which means it's anything but "broken"
but it really is part of the DSA firmware description.

> [    4.315754] sja1105 spi0.1: configuring for fixed/rgmii link mode
> [    4.322653] sja1105 spi0.1 swp5 (uninitialized): PHY [mdio@2d24000:06] driver [Broadcom BCM5464] (irq=POLL)
> [    4.334796] sja1105 spi0.1 swp2 (uninitialized): PHY [mdio@2d24000:03] driver [Broadcom BCM5464] (irq=POLL)
> [    4.345853] sja1105 spi0.1 swp3 (uninitialized): PHY [mdio@2d24000:04] driver [Broadcom BCM5464] (irq=POLL)
> [    4.356859] sja1105 spi0.1 swp4 (uninitialized): PHY [mdio@2d24000:05] driver [Broadcom BCM5464] (irq=POLL)
> [    4.367245] device eth2 entered promiscuous mode
> [    4.371864] DSA: tree 0 setup
> [    4.376971] sja1105 spi0.1: Link is Up - 1Gbps/Full - flow control off
> (...)
> root@black:~# ip link set swp2 up && dhclient -i swp2 && ip addr show swp2
> [   64.762756] fsl-gianfar soc:ethernet@2d90000 eth2: Link is Up - 1Gbps/Full - flow control off
> [   64.771530] sja1105 spi0.1 swp2: configuring for phy/rgmii-id link mode
> [   68.955048] sja1105 spi0.1 swp2: Link is Up - 1Gbps/Full - flow control off
> 12: swp2@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
>     link/ether 00:1f:7b:63:02:48 brd ff:ff:ff:ff:ff:ff
>     inet 10.0.0.68/24 brd 10.0.0.255 scope global dynamic swp2
>        valid_lft 600sec preferred_lft 600sec
> 
> It's by far the messiest patch I've posted to the list (in the interest
> of responding quickly), but if you study the code you can obviously see
> what's missing, basically I've hardcoded the speed to 1000 and I'm
> copying the phy-mode from the real DT node.

Yep - there's at least one other property we need to carry over from the
DT node, which is the "ethernet" property.

> Unfortunately I don't have the time (and most importantly the interest)
> in pushing this any further than that. If you want to take this from
> here and integrate it with phylink_get_caps() I'd be glad to review
> the result. Otherwise, feel free to continue with phylink_set_max_fixed_link().

I think this could be a much better solution to this problem, quite
simply because we then don't end up with phylink_set_max_fixed_link()
which could be abused - and this keeps the complexity where it should
be, in the DSA code.

As I say, though, I think we need Andrew's input on this. Andrew?

I'll look at turning this into a proper solution tomorrow if Andrew is
okay with the fwnode change.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 20:23                     ` Russell King (Oracle)
@ 2022-07-07 21:48                       ` Vladimir Oltean
  -1 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 21:48 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 09:23:46PM +0100, Russell King (Oracle) wrote:
> > > I'm not sure how practical that is when we have both DT and ACPI to deal
> > > with, and ACPI is certainly out of my knowledge area to be able to
> > > construct a software node to specify a fixed-link. Maybe it can be done
> > > at the fwnode layer? I don't know.
> > 
> > I don't want to be misunderstood. I brought up software nodes because
> > I'm sure you must have thought about this too, before proposing what you
> > did here. And unless there's a technical reason against software nodes
> > (which there doesn't appear to be, but I don't want to get ahead of
> > myself), I figured you must be OK with phylink absorbing the logic, case
> > in which I just don't understand why you are pushing back on a proposal
> > how to make phylink absorb the logic completely.
> 
> The reason I hadn't is because switching DSA to fwnode brings with it
> issues for ACPI, and Andrew wants to be very careful about ACPI in
> networking - and I think quite rightly. As soon as one switches from
> DT APIs to fwnode APIs, you basically permit people an easy path to
> re-use DT properties in ACPI-land without the ACPI issues being first
> considered.
> Yep - there's at least one other property we need to carry over from the
> DT node, which is the "ethernet" property.

I've cropped only these segments because there is something I apparently
need to highlight. What my patch does is _not_ at the device fwnode
level (in fact, DSA ports do not have a struct device, only the switch does),
but indeed at the most crude fwnode_handle level. And the fwnode_handles
I'm creating using the software_node API are not connected in any way
with the device. I'm not replacing the device's fwnodes with prosthetic
ones. The fact that I wrote "dn->fwnode.secondary = new_port_fwnode;" is
just a cheap hack to minimize the patch delta so I wouldn't have to
transport the software fwnode_handle from one place to another within
dsa_port_link_register_of(). This should definitely dissapear in the
final solution. In fact, as long as phylink doesn't keep a reference on
the fwnode after phylink_create() or phylink_fwnode_phy_connect(), I'm
pretty sure that the software node can even be deallocated during the
probing stage, no need to keep it for the entire lifetime of the device.

Therefore, no, we don't need the "ethernet" phandle in the software node
we create, because we just use that to pass it to phylink. We still keep
our original OF node for the rest of the activities. We don't even need
the "reg" u32 property, I just added that for no reason (I wasn't
completely sure what the API offers, then I didn't remove it).

So the concern that this software node can be abused for a transition to
ACPI is quite overestimated. Nothing in DSA is "switched to fwnode" per se,
and the creation of a fwnode is just part of "speaking the software node
language", which phylink already happily understands and so, needs no
change. Just my 2 cents.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-07 21:48                       ` Vladimir Oltean
  0 siblings, 0 replies; 65+ messages in thread
From: Vladimir Oltean @ 2022-07-07 21:48 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

On Thu, Jul 07, 2022 at 09:23:46PM +0100, Russell King (Oracle) wrote:
> > > I'm not sure how practical that is when we have both DT and ACPI to deal
> > > with, and ACPI is certainly out of my knowledge area to be able to
> > > construct a software node to specify a fixed-link. Maybe it can be done
> > > at the fwnode layer? I don't know.
> > 
> > I don't want to be misunderstood. I brought up software nodes because
> > I'm sure you must have thought about this too, before proposing what you
> > did here. And unless there's a technical reason against software nodes
> > (which there doesn't appear to be, but I don't want to get ahead of
> > myself), I figured you must be OK with phylink absorbing the logic, case
> > in which I just don't understand why you are pushing back on a proposal
> > how to make phylink absorb the logic completely.
> 
> The reason I hadn't is because switching DSA to fwnode brings with it
> issues for ACPI, and Andrew wants to be very careful about ACPI in
> networking - and I think quite rightly. As soon as one switches from
> DT APIs to fwnode APIs, you basically permit people an easy path to
> re-use DT properties in ACPI-land without the ACPI issues being first
> considered.
> Yep - there's at least one other property we need to carry over from the
> DT node, which is the "ethernet" property.

I've cropped only these segments because there is something I apparently
need to highlight. What my patch does is _not_ at the device fwnode
level (in fact, DSA ports do not have a struct device, only the switch does),
but indeed at the most crude fwnode_handle level. And the fwnode_handles
I'm creating using the software_node API are not connected in any way
with the device. I'm not replacing the device's fwnodes with prosthetic
ones. The fact that I wrote "dn->fwnode.secondary = new_port_fwnode;" is
just a cheap hack to minimize the patch delta so I wouldn't have to
transport the software fwnode_handle from one place to another within
dsa_port_link_register_of(). This should definitely dissapear in the
final solution. In fact, as long as phylink doesn't keep a reference on
the fwnode after phylink_create() or phylink_fwnode_phy_connect(), I'm
pretty sure that the software node can even be deallocated during the
probing stage, no need to keep it for the entire lifetime of the device.

Therefore, no, we don't need the "ethernet" phandle in the software node
we create, because we just use that to pass it to phylink. We still keep
our original OF node for the rest of the activities. We don't even need
the "reg" u32 property, I just added that for no reason (I wasn't
completely sure what the API offers, then I didn't remove it).

So the concern that this software node can be abused for a transition to
ACPI is quite overestimated. Nothing in DSA is "switched to fwnode" per se,
and the creation of a fwnode is just part of "speaking the software node
language", which phylink already happily understands and so, needs no
change. Just my 2 cents.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-07 19:37                   ` Vladimir Oltean
@ 2022-07-08 15:25                     ` Russell King (Oracle)
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-08 15:25 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

Hi,

On Thu, Jul 07, 2022 at 10:37:53PM +0300, Vladimir Oltean wrote:
> +static int dsa_port_fixup_broken_dt(struct dsa_port *dp)

As I mentioned, I doubt that Andrew considers this "broken DT" as he's
been promoting this as a standard DSA feature.

> +{
> +	struct property_entry fixed_link_props[] = {
> +		PROPERTY_ENTRY_BOOL("full-duplex"),
> +		PROPERTY_ENTRY_U32("speed", 1000), /* TODO determine actual speed */
> +		{},
> +	};
> +	struct property_entry port_props[3] = {};
> +	struct fwnode_handle *fixed_link_fwnode;
> +	struct fwnode_handle *new_port_fwnode;
> +	struct device_node *dn = dp->dn;
> +	phy_interface_t mode;
> +	int err;
> +
> +	if (of_parse_phandle(dn, "phy-handle", 0) ||
> +	    of_phy_is_fixed_link(dn))
> +		/* Nothing broken, nothing to fix.
> +		 * TODO: As discussed with Russell, maybe phylink could provide
> +		 * a more comprehensive helper to determine what constitutes a
> +		 * valid fwnode binding than this guerilla kludge.
> +		 */
> +		return 0;

I think this is sufficient. Yes, phylink accepts "phy" and "phy-device"
because it has to for compatibility with other drivers, but the binding
document for DSA quite clearly states that "phy-handle" is what DSA
accepts, so DT in the kernel will be validated against the yaml file
and enforce correctness here.

We do need to check for "sfp" being present as well.

> +
> +	err = of_get_phy_mode(dn, &mode);
> +	if (err)
> +		/* TODO this may be missing too, ask the driver for the
> +		 * max-speed interface mode for this port
> +		 */
> +		mode = PHY_INTERFACE_MODE_NA;

I think it would be easier to omit the phy-mode property in the swnode
if it isn't present in DT, because then we can handle that in
dsa_port_phylink_create() as I've done in my patch series via the
ds->ops->phylink_get_caps() method.

> +
> +	port_props[0] = PROPERTY_ENTRY_U32("reg", dp->index);

You said in one of your other replies that this node we're constructing
is only for phylink, do we need the "reg" property? phylink doesn't care
about it.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-08 15:25                     ` Russell King (Oracle)
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King (Oracle) @ 2022-07-08 15:25 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Heiner Kallweit, Alexandre Belloni, Alvin __ipraga,
	Claudiu Manoil, David S. Miller, DENG Qingfang, Eric Dumazet,
	Florian Fainelli, George McCollister, Hauke Mehrtens,
	Jakub Kicinski, Kurt Kanzenbach, Landen Chao, Linus Walleij,
	linux-arm-kernel, linux-mediatek, Matthias Brugger, netdev,
	Paolo Abeni, Sean Wang, UNGLinuxDriver, Vivien Didelot,
	Woojung Huh, Marek Behún

Hi,

On Thu, Jul 07, 2022 at 10:37:53PM +0300, Vladimir Oltean wrote:
> +static int dsa_port_fixup_broken_dt(struct dsa_port *dp)

As I mentioned, I doubt that Andrew considers this "broken DT" as he's
been promoting this as a standard DSA feature.

> +{
> +	struct property_entry fixed_link_props[] = {
> +		PROPERTY_ENTRY_BOOL("full-duplex"),
> +		PROPERTY_ENTRY_U32("speed", 1000), /* TODO determine actual speed */
> +		{},
> +	};
> +	struct property_entry port_props[3] = {};
> +	struct fwnode_handle *fixed_link_fwnode;
> +	struct fwnode_handle *new_port_fwnode;
> +	struct device_node *dn = dp->dn;
> +	phy_interface_t mode;
> +	int err;
> +
> +	if (of_parse_phandle(dn, "phy-handle", 0) ||
> +	    of_phy_is_fixed_link(dn))
> +		/* Nothing broken, nothing to fix.
> +		 * TODO: As discussed with Russell, maybe phylink could provide
> +		 * a more comprehensive helper to determine what constitutes a
> +		 * valid fwnode binding than this guerilla kludge.
> +		 */
> +		return 0;

I think this is sufficient. Yes, phylink accepts "phy" and "phy-device"
because it has to for compatibility with other drivers, but the binding
document for DSA quite clearly states that "phy-handle" is what DSA
accepts, so DT in the kernel will be validated against the yaml file
and enforce correctness here.

We do need to check for "sfp" being present as well.

> +
> +	err = of_get_phy_mode(dn, &mode);
> +	if (err)
> +		/* TODO this may be missing too, ask the driver for the
> +		 * max-speed interface mode for this port
> +		 */
> +		mode = PHY_INTERFACE_MODE_NA;

I think it would be easier to omit the phy-mode property in the swnode
if it isn't present in DT, because then we can handle that in
dsa_port_phylink_create() as I've done in my patch series via the
ds->ops->phylink_get_caps() method.

> +
> +	port_props[0] = PROPERTY_ENTRY_U32("reg", dp->index);

You said in one of your other replies that this node we're constructing
is only for phylink, do we need the "reg" property? phylink doesn't care
about it.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
  2022-07-08 15:25                     ` Russell King (Oracle)
@ 2022-07-08 15:40                       ` Marek Behún
  -1 siblings, 0 replies; 65+ messages in thread
From: Marek Behún @ 2022-07-08 15:40 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Vladimir Oltean, Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin __ipraga, Claudiu Manoil, David S. Miller, DENG Qingfang,
	Eric Dumazet, Florian Fainelli, George McCollister,
	Hauke Mehrtens, Jakub Kicinski, Kurt Kanzenbach, Landen Chao,
	Linus Walleij, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Woojung Huh

On Fri, 8 Jul 2022 16:25:03 +0100
"Russell King (Oracle)" <linux@armlinux.org.uk> wrote:

> Hi,
> 
> On Thu, Jul 07, 2022 at 10:37:53PM +0300, Vladimir Oltean wrote:
> > +static int dsa_port_fixup_broken_dt(struct dsa_port *dp)  
> 
> As I mentioned, I doubt that Andrew considers this "broken DT" as he's
> been promoting this as a standard DSA feature.
> 
> > +{
> > +	struct property_entry fixed_link_props[] = {
> > +		PROPERTY_ENTRY_BOOL("full-duplex"),
> > +		PROPERTY_ENTRY_U32("speed", 1000), /* TODO determine actual speed */
> > +		{},
> > +	};
> > +	struct property_entry port_props[3] = {};
> > +	struct fwnode_handle *fixed_link_fwnode;
> > +	struct fwnode_handle *new_port_fwnode;
> > +	struct device_node *dn = dp->dn;
> > +	phy_interface_t mode;
> > +	int err;
> > +
> > +	if (of_parse_phandle(dn, "phy-handle", 0) ||
> > +	    of_phy_is_fixed_link(dn))
> > +		/* Nothing broken, nothing to fix.
> > +		 * TODO: As discussed with Russell, maybe phylink could provide
> > +		 * a more comprehensive helper to determine what constitutes a
> > +		 * valid fwnode binding than this guerilla kludge.
> > +		 */
> > +		return 0;  
> 
> I think this is sufficient. Yes, phylink accepts "phy" and "phy-device"
> because it has to for compatibility with other drivers, but the binding
> document for DSA quite clearly states that "phy-handle" is what DSA
> accepts, so DT in the kernel will be validated against the yaml file
> and enforce correctness here.
> 
> We do need to check for "sfp" being present as well.
> 
> > +
> > +	err = of_get_phy_mode(dn, &mode);
> > +	if (err)
> > +		/* TODO this may be missing too, ask the driver for the
> > +		 * max-speed interface mode for this port
> > +		 */
> > +		mode = PHY_INTERFACE_MODE_NA;  
> 
> I think it would be easier to omit the phy-mode property in the swnode
> if it isn't present in DT, because then we can handle that in
> dsa_port_phylink_create() as I've done in my patch series via the
> ds->ops->phylink_get_caps() method.
> 
> > +
> > +	port_props[0] = PROPERTY_ENTRY_U32("reg", dp->index);  
> 
> You said in one of your other replies that this node we're constructing
> is only for phylink, do we need the "reg" property? phylink doesn't care
> about it.

We don't. Vladimir wrote: "We don't even need the "reg" u32 property, I
just added that for no reason (I wasn't completely sure what the API
offers, then I didn't remove it)."

Marek

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports
@ 2022-07-08 15:40                       ` Marek Behún
  0 siblings, 0 replies; 65+ messages in thread
From: Marek Behún @ 2022-07-08 15:40 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Vladimir Oltean, Andrew Lunn, Heiner Kallweit, Alexandre Belloni,
	Alvin __ipraga, Claudiu Manoil, David S. Miller, DENG Qingfang,
	Eric Dumazet, Florian Fainelli, George McCollister,
	Hauke Mehrtens, Jakub Kicinski, Kurt Kanzenbach, Landen Chao,
	Linus Walleij, linux-arm-kernel, linux-mediatek,
	Matthias Brugger, netdev, Paolo Abeni, Sean Wang, UNGLinuxDriver,
	Vivien Didelot, Woojung Huh

On Fri, 8 Jul 2022 16:25:03 +0100
"Russell King (Oracle)" <linux@armlinux.org.uk> wrote:

> Hi,
> 
> On Thu, Jul 07, 2022 at 10:37:53PM +0300, Vladimir Oltean wrote:
> > +static int dsa_port_fixup_broken_dt(struct dsa_port *dp)  
> 
> As I mentioned, I doubt that Andrew considers this "broken DT" as he's
> been promoting this as a standard DSA feature.
> 
> > +{
> > +	struct property_entry fixed_link_props[] = {
> > +		PROPERTY_ENTRY_BOOL("full-duplex"),
> > +		PROPERTY_ENTRY_U32("speed", 1000), /* TODO determine actual speed */
> > +		{},
> > +	};
> > +	struct property_entry port_props[3] = {};
> > +	struct fwnode_handle *fixed_link_fwnode;
> > +	struct fwnode_handle *new_port_fwnode;
> > +	struct device_node *dn = dp->dn;
> > +	phy_interface_t mode;
> > +	int err;
> > +
> > +	if (of_parse_phandle(dn, "phy-handle", 0) ||
> > +	    of_phy_is_fixed_link(dn))
> > +		/* Nothing broken, nothing to fix.
> > +		 * TODO: As discussed with Russell, maybe phylink could provide
> > +		 * a more comprehensive helper to determine what constitutes a
> > +		 * valid fwnode binding than this guerilla kludge.
> > +		 */
> > +		return 0;  
> 
> I think this is sufficient. Yes, phylink accepts "phy" and "phy-device"
> because it has to for compatibility with other drivers, but the binding
> document for DSA quite clearly states that "phy-handle" is what DSA
> accepts, so DT in the kernel will be validated against the yaml file
> and enforce correctness here.
> 
> We do need to check for "sfp" being present as well.
> 
> > +
> > +	err = of_get_phy_mode(dn, &mode);
> > +	if (err)
> > +		/* TODO this may be missing too, ask the driver for the
> > +		 * max-speed interface mode for this port
> > +		 */
> > +		mode = PHY_INTERFACE_MODE_NA;  
> 
> I think it would be easier to omit the phy-mode property in the swnode
> if it isn't present in DT, because then we can handle that in
> dsa_port_phylink_create() as I've done in my patch series via the
> ds->ops->phylink_get_caps() method.
> 
> > +
> > +	port_props[0] = PROPERTY_ENTRY_U32("reg", dp->index);  
> 
> You said in one of your other replies that this node we're constructing
> is only for phylink, do we need the "reg" property? phylink doesn't care
> about it.

We don't. Vladimir wrote: "We don't even need the "reg" u32 property, I
just added that for no reason (I wasn't completely sure what the API
offers, then I didn't remove it)."

Marek

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2022-07-08 15:41 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-05  9:46 [PATCH RFC net-next v2 0/5] net: dsa: always use phylink Russell King (Oracle)
2022-07-05  9:46 ` Russell King (Oracle)
2022-07-05  9:47 ` [PATCH RFC net-next 1/5] net: dsa: add support for retrieving the interface mode Russell King (Oracle)
2022-07-05  9:47   ` Russell King (Oracle)
2022-07-05  9:47 ` [PATCH RFC net-next 2/5] net: dsa: mv88e6xxx: report the default interface mode for the port Russell King (Oracle)
2022-07-05  9:47   ` Russell King (Oracle)
2022-07-05 10:55   ` Marek Behún
2022-07-05 10:55     ` Marek Behún
2022-07-06 11:04   ` kernel test robot
2022-07-05  9:47 ` [PATCH RFC net-next 3/5] net: phylink: split out interface to caps translation Russell King (Oracle)
2022-07-05  9:47   ` Russell King (Oracle)
2022-07-05  9:48 ` [PATCH RFC net-next 4/5] net: phylink: add phylink_set_max_fixed_link() Russell King (Oracle)
2022-07-05  9:48   ` Russell King (Oracle)
2022-07-05 10:58   ` Marek Behún
2022-07-05 10:58     ` Marek Behún
2022-07-05  9:48 ` [PATCH RFC net-next 5/5] net: dsa: always use phylink for CPU and DSA ports Russell King (Oracle)
2022-07-05  9:48   ` Russell King (Oracle)
2022-07-06 10:26   ` Vladimir Oltean
2022-07-06 10:26     ` Vladimir Oltean
2022-07-06 16:24     ` Russell King (Oracle)
2022-07-06 16:24       ` Russell King (Oracle)
2022-07-07 10:09       ` Russell King (Oracle)
2022-07-07 10:09         ` Russell King (Oracle)
2022-07-07 15:27         ` Vladimir Oltean
2022-07-07 15:27           ` Vladimir Oltean
2022-07-07 15:48           ` Russell King (Oracle)
2022-07-07 15:48             ` Russell King (Oracle)
2022-07-07 16:38             ` Vladimir Oltean
2022-07-07 16:38               ` Vladimir Oltean
2022-07-07 17:15               ` Russell King (Oracle)
2022-07-07 17:15                 ` Russell King (Oracle)
2022-07-07 19:37                 ` Vladimir Oltean
2022-07-07 19:37                   ` Vladimir Oltean
2022-07-07 20:23                   ` Russell King (Oracle)
2022-07-07 20:23                     ` Russell King (Oracle)
2022-07-07 21:48                     ` Vladimir Oltean
2022-07-07 21:48                       ` Vladimir Oltean
2022-07-08 15:25                   ` Russell King (Oracle)
2022-07-08 15:25                     ` Russell King (Oracle)
2022-07-08 15:40                     ` Marek Behún
2022-07-08 15:40                       ` Marek Behún
2022-07-07 11:00     ` Russell King (Oracle)
2022-07-07 11:00       ` Russell King (Oracle)
2022-07-07 15:43       ` Vladimir Oltean
2022-07-07 15:43         ` Vladimir Oltean
2022-07-07 16:32         ` Russell King (Oracle)
2022-07-07 16:32           ` Russell King (Oracle)
2022-07-07 16:50           ` Vladimir Oltean
2022-07-07 16:50             ` Vladimir Oltean
2022-07-05 16:42 ` [PATCH RFC net-next v2 0/5] net: dsa: always use phylink Florian Fainelli
2022-07-05 16:42   ` Florian Fainelli
2022-07-06 10:14   ` Vladimir Oltean
2022-07-06 10:14     ` Vladimir Oltean
2022-07-06 16:27     ` Florian Fainelli
2022-07-06 16:27       ` Florian Fainelli
2022-07-06 19:05       ` Hauke Mehrtens
2022-07-06 19:05         ` Hauke Mehrtens
2022-07-06 20:24         ` Russell King (Oracle)
2022-07-06 20:24           ` Russell King (Oracle)
2022-07-06 17:22 ` Kurt Kanzenbach
2022-07-06 17:22   ` Kurt Kanzenbach
2022-07-06 22:46 ` Linus Walleij
2022-07-06 22:46   ` Linus Walleij
2022-07-07 13:46   ` Linus Walleij
2022-07-07 13:46     ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.