diff mbox series

[net-next,2/3] net: dsa: allow DSA switch drivers to provide their own phylink mac ops

Message ID E1rtn25-0065p0-2C@rmk-PC.armlinux.org.uk (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: dsa: allow phylink_mac_ops in DSA drivers | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 959 this patch: 960
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang fail Errors and warnings before: 959 this patch: 961
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 970 this patch: 971
netdev/checkpatch warning WARNING: line length of 82 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 1 this patch: 1
netdev/source_inline success Was 0 now: 0

Commit Message

Russell King (Oracle) April 8, 2024, 11:19 a.m. UTC
Rather than having a shim for each and every phylink MAC operation,
allow DSA switch drivers to provide their own ops structure.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
 include/net/dsa.h |  5 +++++
 net/dsa/port.c    | 29 ++++++++++++++++++++++++-----
 2 files changed, 29 insertions(+), 5 deletions(-)

Comments

Andrew Lunn April 8, 2024, 11:45 p.m. UTC | #1
On Mon, Apr 08, 2024 at 12:19:25PM +0100, Russell King (Oracle) wrote:
> Rather than having a shim for each and every phylink MAC operation,
> allow DSA switch drivers to provide their own ops structure.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew
Florian Fainelli April 8, 2024, 11:51 p.m. UTC | #2
On 4/8/24 04:19, Russell King (Oracle) wrote:
> Rather than having a shim for each and every phylink MAC operation,
> allow DSA switch drivers to provide their own ops structure.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
kernel test robot April 9, 2024, 3:15 a.m. UTC | #3
Hi Russell,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Russell-King-Oracle/net-dsa-introduce-dsa_phylink_to_port/20240408-232316
base:   net-next/main
patch link:    https://lore.kernel.org/r/E1rtn25-0065p0-2C%40rmk-PC.armlinux.org.uk
patch subject: [PATCH net-next 2/3] net: dsa: allow DSA switch drivers to provide their own phylink mac ops
config: arm-defconfig (https://download.01.org/0day-ci/archive/20240409/202404091147.pdi8izJ3-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240409/202404091147.pdi8izJ3-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404091147.pdi8izJ3-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> net/dsa/port.c:1981:6: warning: unused variable 'port' [-Wunused-variable]
           int port = dp->index;
               ^
   1 warning generated.


vim +/port +1981 net/dsa/port.c

3a506cb7012a98 Russell King (Oracle  2024-04-08  1975) 
770375ff331111 Vladimir Oltean       2022-08-18  1976  int dsa_shared_port_link_register_of(struct dsa_port *dp)
57ab1ca2159717 Vivien Didelot        2017-10-26  1977  {
0e27921816ad99 Ioana Ciornei         2019-05-28  1978  	struct dsa_switch *ds = dp->ds;
e09e9873152e3f Vladimir Oltean       2022-08-18  1979  	bool missing_link_description;
e09e9873152e3f Vladimir Oltean       2022-08-18  1980  	bool missing_phy_mode;
3be98b2d5fbca3 Andrew Lunn           2020-04-14 @1981  	int port = dp->index;
0e27921816ad99 Ioana Ciornei         2019-05-28  1982  
e09e9873152e3f Vladimir Oltean       2022-08-18  1983  	dsa_shared_port_validate_of(dp, &missing_phy_mode,
e09e9873152e3f Vladimir Oltean       2022-08-18  1984  				    &missing_link_description);
e09e9873152e3f Vladimir Oltean       2022-08-18  1985  
e09e9873152e3f Vladimir Oltean       2022-08-18  1986  	if ((missing_phy_mode || missing_link_description) &&
e09e9873152e3f Vladimir Oltean       2022-08-18  1987  	    !of_device_compatible_match(ds->dev->of_node,
e09e9873152e3f Vladimir Oltean       2022-08-18  1988  					dsa_switches_apply_workarounds))
e09e9873152e3f Vladimir Oltean       2022-08-18  1989  		return -EINVAL;
e09e9873152e3f Vladimir Oltean       2022-08-18  1990  
a20f997010c4ec Andrew Lunn           2020-03-11  1991  	if (!ds->ops->adjust_link) {
e09e9873152e3f Vladimir Oltean       2022-08-18  1992  		if (missing_link_description) {
e09e9873152e3f Vladimir Oltean       2022-08-18  1993  			dev_warn(ds->dev,
e09e9873152e3f Vladimir Oltean       2022-08-18  1994  				 "Skipping phylink registration for %s port %d\n",
e09e9873152e3f Vladimir Oltean       2022-08-18  1995  				 dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
e09e9873152e3f Vladimir Oltean       2022-08-18  1996  		} else {
3a506cb7012a98 Russell King (Oracle  2024-04-08  1997) 			dsa_shared_port_link_down(dp);
e09e9873152e3f Vladimir Oltean       2022-08-18  1998  
770375ff331111 Vladimir Oltean       2022-08-18  1999  			return dsa_shared_port_phylink_register(dp);
3be98b2d5fbca3 Andrew Lunn           2020-04-14  2000  		}
a20f997010c4ec Andrew Lunn           2020-03-11  2001  		return 0;
a20f997010c4ec Andrew Lunn           2020-03-11  2002  	}
0e27921816ad99 Ioana Ciornei         2019-05-28  2003  
0e27921816ad99 Ioana Ciornei         2019-05-28  2004  	dev_warn(ds->dev,
0e27921816ad99 Ioana Ciornei         2019-05-28  2005  		 "Using legacy PHYLIB callbacks. Please migrate to PHYLINK!\n");
0e27921816ad99 Ioana Ciornei         2019-05-28  2006  
33615367f378fe Sebastian Reichel     2018-01-23  2007  	if (of_phy_is_fixed_link(dp->dn))
770375ff331111 Vladimir Oltean       2022-08-18  2008  		return dsa_shared_port_fixed_link_register_of(dp);
33615367f378fe Sebastian Reichel     2018-01-23  2009  	else
770375ff331111 Vladimir Oltean       2022-08-18  2010  		return dsa_shared_port_setup_phy_of(dp, true);
33615367f378fe Sebastian Reichel     2018-01-23  2011  }
57ab1ca2159717 Vivien Didelot        2017-10-26  2012
Russell King (Oracle) April 9, 2024, 8:04 a.m. UTC | #4
On Tue, Apr 09, 2024 at 11:15:01AM +0800, kernel test robot wrote:
> All warnings (new ones prefixed by >>):
> 
> >> net/dsa/port.c:1981:6: warning: unused variable 'port' [-Wunused-variable]
>            int port = dp->index;
>                ^
>    1 warning generated.

Sigh... I don't get this warning when I build it. I guess that's because
unused variable warnings are normally turned off. I'll respin dropping
this.
Vladimir Oltean April 9, 2024, 12:37 p.m. UTC | #5
On Mon, Apr 08, 2024 at 12:19:25PM +0100, Russell King (Oracle) wrote:
> +static void dsa_shared_port_link_down(struct dsa_port *dp)
> +{
> +	struct dsa_switch *ds = dp->ds;
> +
> +	if (ds->phylink_mac_ops) {
> +		if (ds->phylink_mac_ops->mac_link_down)
> +			ds->phylink_mac_ops->mac_link_down(&dp->pl_config,
> +							   MLO_AN_FIXED,
> +							   PHY_INTERFACE_MODE_NA);
> +	} else {
> +		if (ds->ops->phylink_mac_link_down)
> +			ds->ops->phylink_mac_link_down(ds, dp->index,
> +				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
> +	}
> +}

Please roll this other change into the patch when respinning:

else {
	if { }
}

becomes

else if {}

Also please align the arguments of the phylink_mac_link_down() call with
the open parenthesis.
Vladimir Oltean April 9, 2024, 3:33 p.m. UTC | #6
On Tue, Apr 09, 2024 at 03:37:31PM +0300, Vladimir Oltean wrote:
> On Mon, Apr 08, 2024 at 12:19:25PM +0100, Russell King (Oracle) wrote:
> > +static void dsa_shared_port_link_down(struct dsa_port *dp)
> > +{
> > +	struct dsa_switch *ds = dp->ds;
> > +
> > +	if (ds->phylink_mac_ops) {
> > +		if (ds->phylink_mac_ops->mac_link_down)
> > +			ds->phylink_mac_ops->mac_link_down(&dp->pl_config,
> > +							   MLO_AN_FIXED,
> > +							   PHY_INTERFACE_MODE_NA);
> > +	} else {
> > +		if (ds->ops->phylink_mac_link_down)
> > +			ds->ops->phylink_mac_link_down(ds, dp->index,
> > +				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
> > +	}
> > +}
> 
> Please roll this other change into the patch when respinning:
> 
> else {
> 	if { }
> }
> 
> becomes
> 
> else if {}
> 
> Also please align the arguments of the phylink_mac_link_down() call with
> the open parenthesis.

Something like this:

static void dsa_shared_port_link_down(struct dsa_port *dp)
{
	struct dsa_switch *ds = dp->ds;

	if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down) {
		ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
						   PHY_INTERFACE_MODE_NA);
	} else if (ds->ops->phylink_mac_link_down) {
		ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
					       PHY_INTERFACE_MODE_NA);
	}
}
Russell King (Oracle) April 9, 2024, 4:29 p.m. UTC | #7
On Tue, Apr 09, 2024 at 06:33:46PM +0300, Vladimir Oltean wrote:
> On Tue, Apr 09, 2024 at 03:37:31PM +0300, Vladimir Oltean wrote:
> > On Mon, Apr 08, 2024 at 12:19:25PM +0100, Russell King (Oracle) wrote:
> > > +static void dsa_shared_port_link_down(struct dsa_port *dp)
> > > +{
> > > +	struct dsa_switch *ds = dp->ds;
> > > +
> > > +	if (ds->phylink_mac_ops) {
> > > +		if (ds->phylink_mac_ops->mac_link_down)
> > > +			ds->phylink_mac_ops->mac_link_down(&dp->pl_config,
> > > +							   MLO_AN_FIXED,
> > > +							   PHY_INTERFACE_MODE_NA);
> > > +	} else {
> > > +		if (ds->ops->phylink_mac_link_down)
> > > +			ds->ops->phylink_mac_link_down(ds, dp->index,
> > > +				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
> > > +	}
> > > +}
> > 
> > Please roll this other change into the patch when respinning:
> > 
> > else {
> > 	if { }
> > }
> > 
> > becomes
> > 
> > else if {}

This would destroy the symmetry that I think aids readability. I did
consider it at the time and decided against it.

> Something like this:
> 
> static void dsa_shared_port_link_down(struct dsa_port *dp)
> {
> 	struct dsa_switch *ds = dp->ds;
> 
> 	if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down) {
> 		ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
> 						   PHY_INTERFACE_MODE_NA);
> 	} else if (ds->ops->phylink_mac_link_down) {
> 		ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
> 					       PHY_INTERFACE_MODE_NA);
> 	}

This changes the logic - it allows driver authors to provide the
MAC operations, omit the mac_link_down() op _and_ an
ops->phylink_mac_link_down() function. This could lead to buggy
drivers since this will only happen in this path and none of the
others.

I want this to be an "either provide phylink_mac_ops, and thus
none of the phylink_mac_* ops in dsa_switch_ops will be called" or
"don't provide phylink_mac_ops and the phylink_mac_* ops in
dsa_switch_ops will be called". It's then completely clear cut
that it's one or the other, whereas the code above makes it
unclear.
Vladimir Oltean April 9, 2024, 4:52 p.m. UTC | #8
On Tue, Apr 09, 2024 at 05:29:23PM +0100, Russell King (Oracle) wrote:
> This changes the logic - it allows driver authors to provide the
> MAC operations, omit the mac_link_down() op _and_ an
> ops->phylink_mac_link_down() function. This could lead to buggy
> drivers since this will only happen in this path and none of the
> others.
> 
> I want this to be an "either provide phylink_mac_ops, and thus
> none of the phylink_mac_* ops in dsa_switch_ops will be called" or
> "don't provide phylink_mac_ops and the phylink_mac_* ops in
> dsa_switch_ops will be called". It's then completely clear cut
> that it's one or the other, whereas the code above makes it
> unclear.

If you want for the API transition to be self-documenting and clear,
it would be good to do that validation separately and more comprehensively
rather than just a fall-through for one single operation here.

If phylink_mac_link_ops is provided, the following ds->ops methods are
obsoleted and can't be provided at the same time (fail probing otherwise):

- phylink_mac_select_pcs()
- phylink_mac_prepare()
- phylink_mac_config()
- phylink_mac_finish()
- phylink_mac_link_down()
- phylink_mac_link_up()

Hopefully it makes it more clear that the following are _not_ obsoleted
by the dedicated phylink mac_ops:

- phylink_get_caps()
- phylink_fixed_state()

Then (after this validation), the simplified
"if (ops && ops->mac_link_down) else (ds->ops->phylink_mac_link_down)"
would be equivalent, because we've errored out on the case which has a
mix of old and new API.
Russell King (Oracle) April 9, 2024, 6:22 p.m. UTC | #9
On Tue, Apr 09, 2024 at 07:52:30PM +0300, Vladimir Oltean wrote:
> On Tue, Apr 09, 2024 at 05:29:23PM +0100, Russell King (Oracle) wrote:
> > This changes the logic - it allows driver authors to provide the
> > MAC operations, omit the mac_link_down() op _and_ an
> > ops->phylink_mac_link_down() function. This could lead to buggy
> > drivers since this will only happen in this path and none of the
> > others.
> > 
> > I want this to be an "either provide phylink_mac_ops, and thus
> > none of the phylink_mac_* ops in dsa_switch_ops will be called" or
> > "don't provide phylink_mac_ops and the phylink_mac_* ops in
> > dsa_switch_ops will be called". It's then completely clear cut
> > that it's one or the other, whereas the code above makes it
> > unclear.
> 
> If you want for the API transition to be self-documenting and clear,
> it would be good to do that validation separately and more comprehensively
> rather than just a fall-through for one single operation here.
> 
> If phylink_mac_link_ops is provided, the following ds->ops methods are
> obsoleted and can't be provided at the same time (fail probing otherwise):
> 
> - phylink_mac_select_pcs()
> - phylink_mac_prepare()
> - phylink_mac_config()
> - phylink_mac_finish()
> - phylink_mac_link_down()
> - phylink_mac_link_up()
> 
> Hopefully it makes it more clear that the following are _not_ obsoleted
> by the dedicated phylink mac_ops:
> 
> - phylink_get_caps()
> - phylink_fixed_state()
> 
> Then (after this validation), the simplified
> "if (ops && ops->mac_link_down) else (ds->ops->phylink_mac_link_down)"
> would be equivalent, because we've errored out on the case which has a
> mix of old and new API.

Okay. However, I can't predict when I'll get around to doing these
changes as my time is very limited over this week and next week - so
may be right before the merge window is due.

Maybe we should've done that for the ops->adjust_link vs
ops->phylink_mac_link_down/ops->phylink_mac_link_up as well.
diff mbox series

Patch

diff --git a/include/net/dsa.h b/include/net/dsa.h
index f228b479a5fd..7edfd8de8882 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -457,6 +457,11 @@  struct dsa_switch {
 	 */
 	const struct dsa_switch_ops	*ops;
 
+	/*
+	 * Allow a DSA switch driver to override the phylink MAC ops
+	 */
+	const struct phylink_mac_ops	*phylink_mac_ops;
+
 	/*
 	 * User mii_bus and devices for the individual ports.
 	 */
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 02bf1c306bdc..bfacf41344df 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1662,6 +1662,7 @@  static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
 
 int dsa_port_phylink_create(struct dsa_port *dp)
 {
+	const struct phylink_mac_ops *mac_ops;
 	struct dsa_switch *ds = dp->ds;
 	phy_interface_t mode;
 	struct phylink *pl;
@@ -1685,8 +1686,12 @@  int dsa_port_phylink_create(struct dsa_port *dp)
 		}
 	}
 
-	pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
-			    mode, &dsa_port_phylink_mac_ops);
+	mac_ops = &dsa_port_phylink_mac_ops;
+	if (ds->phylink_mac_ops)
+		mac_ops = ds->phylink_mac_ops;
+
+	pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
+			    mac_ops);
 	if (IS_ERR(pl)) {
 		pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
 		return PTR_ERR(pl);
@@ -1952,6 +1957,22 @@  static void dsa_shared_port_validate_of(struct dsa_port *dp,
 		dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
 }
 
+static void dsa_shared_port_link_down(struct dsa_port *dp)
+{
+	struct dsa_switch *ds = dp->ds;
+
+	if (ds->phylink_mac_ops) {
+		if (ds->phylink_mac_ops->mac_link_down)
+			ds->phylink_mac_ops->mac_link_down(&dp->pl_config,
+							   MLO_AN_FIXED,
+							   PHY_INTERFACE_MODE_NA);
+	} else {
+		if (ds->ops->phylink_mac_link_down)
+			ds->ops->phylink_mac_link_down(ds, dp->index,
+				MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
+	}
+}
+
 int dsa_shared_port_link_register_of(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
@@ -1973,9 +1994,7 @@  int dsa_shared_port_link_register_of(struct dsa_port *dp)
 				 "Skipping phylink registration for %s port %d\n",
 				 dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
 		} else {
-			if (ds->ops->phylink_mac_link_down)
-				ds->ops->phylink_mac_link_down(ds, port,
-					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
+			dsa_shared_port_link_down(dp);
 
 			return dsa_shared_port_phylink_register(dp);
 		}