diff mbox series

[net-next,v2,08/12] net: phy: at803x: move specific at8031 WOL bits to dedicated function

Message ID 20231201001423.20989-9-ansuelsmth@gmail.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: phy: at803x: cleanup | 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;
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 success Errors and warnings before: 1115 this patch: 1115
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 1142 this patch: 1142
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 success Errors and warnings before: 1142 this patch: 1142
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 65 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Christian Marangi Dec. 1, 2023, 12:14 a.m. UTC
Move specific at8031 WOL enable/disable to dedicated function to make
at803x_set_wol more generic.

This is needed in preparation for PHY driver split as qca8081 share the
same function to toggle WOL settings.

In this new implementation WOL module in at8031 is enabled after the
generic interrupt is setup. This should not cause any problem as the
WOL_INT has a separate implementation and only relay on MAC bits.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

Comments

Paolo Abeni Dec. 5, 2023, 9:32 a.m. UTC | #1
On Fri, 2023-12-01 at 01:14 +0100, Christian Marangi wrote:
> Move specific at8031 WOL enable/disable to dedicated function to make
> at803x_set_wol more generic.
> 
> This is needed in preparation for PHY driver split as qca8081 share the
> same function to toggle WOL settings.
> 
> In this new implementation WOL module in at8031 is enabled after the
> generic interrupt is setup. This should not cause any problem as the
> WOL_INT has a separate implementation and only relay on MAC bits.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>  drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index 02ac71f98466..2de7a59c0faa 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c
> @@ -466,27 +466,11 @@ static int at803x_set_wol(struct phy_device *phydev,
>  			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
>  				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
>  
> -		/* Enable WOL function for 1588 */
> -		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
> -			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> -					     AT803X_PHY_MMD3_WOL_CTRL,
> -					     0, AT803X_WOL_EN);
> -			if (ret)
> -				return ret;
> -		}
>  		/* Enable WOL interrupt */
>  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
>  		if (ret)
>  			return ret;
>  	} else {
> -		/* Disable WoL function for 1588 */
> -		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
> -			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> -					     AT803X_PHY_MMD3_WOL_CTRL,
> -					     AT803X_WOL_EN, 0);
> -			if (ret)
> -				return ret;
> -		}
>  		/* Disable WOL interrupt */
>  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
>  		if (ret)
> @@ -1611,6 +1595,30 @@ static int at8031_config_init(struct phy_device *phydev)
>  	return at803x_config_init(phydev);
>  }
>  
> +static int at8031_set_wol(struct phy_device *phydev,
> +			  struct ethtool_wolinfo *wol)
> +{
> +	int ret;
> +
> +	/* First setup MAC address and enable WOL interrupt */
> +	ret = at803x_set_wol(phydev, wol);
> +	if (ret)
> +		return ret;
> +
> +	if (wol->wolopts & WAKE_MAGIC)
> +		/* Enable WOL function for 1588 */
> +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> +				     AT803X_PHY_MMD3_WOL_CTRL,
> +				     0, AT803X_WOL_EN);
> +	else
> +		/* Disable WoL function for 1588 */
> +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> +				     AT803X_PHY_MMD3_WOL_CTRL,
> +				     AT803X_WOL_EN, 0);
> +
> +	return ret;

If I read correctly, the above changes the order of some WoL
initialization steps: now WOL_CTRL is touched after
AT803X_INTR_ENABLE_WOL. Is that correct?

Thanks,

Paolo
Christian Marangi Dec. 5, 2023, 2:43 p.m. UTC | #2
On Tue, Dec 05, 2023 at 10:32:55AM +0100, Paolo Abeni wrote:
> On Fri, 2023-12-01 at 01:14 +0100, Christian Marangi wrote:
> > Move specific at8031 WOL enable/disable to dedicated function to make
> > at803x_set_wol more generic.
> > 
> > This is needed in preparation for PHY driver split as qca8081 share the
> > same function to toggle WOL settings.
> > 
> > In this new implementation WOL module in at8031 is enabled after the
> > generic interrupt is setup. This should not cause any problem as the
> > WOL_INT has a separate implementation and only relay on MAC bits.
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> >  drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++----------------
> >  1 file changed, 25 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> > index 02ac71f98466..2de7a59c0faa 100644
> > --- a/drivers/net/phy/at803x.c
> > +++ b/drivers/net/phy/at803x.c
> > @@ -466,27 +466,11 @@ static int at803x_set_wol(struct phy_device *phydev,
> >  			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
> >  				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
> >  
> > -		/* Enable WOL function for 1588 */
> > -		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
> > -			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > -					     AT803X_PHY_MMD3_WOL_CTRL,
> > -					     0, AT803X_WOL_EN);
> > -			if (ret)
> > -				return ret;
> > -		}
> >  		/* Enable WOL interrupt */
> >  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
> >  		if (ret)
> >  			return ret;
> >  	} else {
> > -		/* Disable WoL function for 1588 */
> > -		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
> > -			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > -					     AT803X_PHY_MMD3_WOL_CTRL,
> > -					     AT803X_WOL_EN, 0);
> > -			if (ret)
> > -				return ret;
> > -		}
> >  		/* Disable WOL interrupt */
> >  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
> >  		if (ret)
> > @@ -1611,6 +1595,30 @@ static int at8031_config_init(struct phy_device *phydev)
> >  	return at803x_config_init(phydev);
> >  }
> >  
> > +static int at8031_set_wol(struct phy_device *phydev,
> > +			  struct ethtool_wolinfo *wol)
> > +{
> > +	int ret;
> > +
> > +	/* First setup MAC address and enable WOL interrupt */
> > +	ret = at803x_set_wol(phydev, wol);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (wol->wolopts & WAKE_MAGIC)
> > +		/* Enable WOL function for 1588 */
> > +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > +				     AT803X_PHY_MMD3_WOL_CTRL,
> > +				     0, AT803X_WOL_EN);
> > +	else
> > +		/* Disable WoL function for 1588 */
> > +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > +				     AT803X_PHY_MMD3_WOL_CTRL,
> > +				     AT803X_WOL_EN, 0);
> > +
> > +	return ret;
> 
> If I read correctly, the above changes the order of some WoL
> initialization steps: now WOL_CTRL is touched after
> AT803X_INTR_ENABLE_WOL. Is that correct?

Correct, as it was pointed out, in the previous revision the WOL was
enabled before setting the MAC leaving some timeframe where we had
interrupt that could be triggered by invalind MAC (and also in case MAC
setup was failing the WOL was laved enabled)

The current change should be safe enough as the WOL module is enabled at
the end of all the required setup preventing any kind of
misconfiguration if something fails before.
Russell King (Oracle) Dec. 5, 2023, 2:58 p.m. UTC | #3
On Tue, Dec 05, 2023 at 10:32:55AM +0100, Paolo Abeni wrote:
> On Fri, 2023-12-01 at 01:14 +0100, Christian Marangi wrote:
> > Move specific at8031 WOL enable/disable to dedicated function to make
> > at803x_set_wol more generic.
> > 
> > This is needed in preparation for PHY driver split as qca8081 share the
> > same function to toggle WOL settings.
> > 
> > In this new implementation WOL module in at8031 is enabled after the
> > generic interrupt is setup. This should not cause any problem as the
> > WOL_INT has a separate implementation and only relay on MAC bits.
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> >  drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++----------------
> >  1 file changed, 25 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> > index 02ac71f98466..2de7a59c0faa 100644
> > --- a/drivers/net/phy/at803x.c
> > +++ b/drivers/net/phy/at803x.c
> > @@ -466,27 +466,11 @@ static int at803x_set_wol(struct phy_device *phydev,
> >  			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
> >  				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
> >  
> > -		/* Enable WOL function for 1588 */
> > -		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
> > -			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > -					     AT803X_PHY_MMD3_WOL_CTRL,
> > -					     0, AT803X_WOL_EN);
> > -			if (ret)
> > -				return ret;
> > -		}
> >  		/* Enable WOL interrupt */
> >  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
> >  		if (ret)
> >  			return ret;
> >  	} else {
> > -		/* Disable WoL function for 1588 */
> > -		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
> > -			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > -					     AT803X_PHY_MMD3_WOL_CTRL,
> > -					     AT803X_WOL_EN, 0);
> > -			if (ret)
> > -				return ret;
> > -		}
> >  		/* Disable WOL interrupt */
> >  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
> >  		if (ret)
> > @@ -1611,6 +1595,30 @@ static int at8031_config_init(struct phy_device *phydev)
> >  	return at803x_config_init(phydev);
> >  }
> >  
> > +static int at8031_set_wol(struct phy_device *phydev,
> > +			  struct ethtool_wolinfo *wol)
> > +{
> > +	int ret;
> > +
> > +	/* First setup MAC address and enable WOL interrupt */
> > +	ret = at803x_set_wol(phydev, wol);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (wol->wolopts & WAKE_MAGIC)
> > +		/* Enable WOL function for 1588 */
> > +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > +				     AT803X_PHY_MMD3_WOL_CTRL,
> > +				     0, AT803X_WOL_EN);
> > +	else
> > +		/* Disable WoL function for 1588 */
> > +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
> > +				     AT803X_PHY_MMD3_WOL_CTRL,
> > +				     AT803X_WOL_EN, 0);
> > +
> > +	return ret;
> 
> If I read correctly, the above changes the order of some WoL
> initialization steps: now WOL_CTRL is touched after
> AT803X_INTR_ENABLE_WOL. Is that correct?

It is fine.

AT803X_INTR_ENABLE_WOL enables or disables whether the INT pin (which
is used for any interrupt from the PHY) is used to signal WOL - it's
the interrupt enable for the WoL function.

The MMD3 WOL_EN bit controls whether the WoL function is enabled, and
thus whether the WOL_INT pin will signal WoL. WOL_EN should not be
set until we have initialised the WoL function, and thus that needs
to happen _after_ the MAC address has been programmed.

Clearing WOL_EN afterwards is not a problem because it will already
have been setup, or is in its power-on default state.
diff mbox series

Patch

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 02ac71f98466..2de7a59c0faa 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -466,27 +466,11 @@  static int at803x_set_wol(struct phy_device *phydev,
 			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
 				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
 
-		/* Enable WOL function for 1588 */
-		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-					     AT803X_PHY_MMD3_WOL_CTRL,
-					     0, AT803X_WOL_EN);
-			if (ret)
-				return ret;
-		}
 		/* Enable WOL interrupt */
 		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
 		if (ret)
 			return ret;
 	} else {
-		/* Disable WoL function for 1588 */
-		if (phydev->drv->phy_id == ATH8031_PHY_ID) {
-			ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
-					     AT803X_PHY_MMD3_WOL_CTRL,
-					     AT803X_WOL_EN, 0);
-			if (ret)
-				return ret;
-		}
 		/* Disable WOL interrupt */
 		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
 		if (ret)
@@ -1611,6 +1595,30 @@  static int at8031_config_init(struct phy_device *phydev)
 	return at803x_config_init(phydev);
 }
 
+static int at8031_set_wol(struct phy_device *phydev,
+			  struct ethtool_wolinfo *wol)
+{
+	int ret;
+
+	/* First setup MAC address and enable WOL interrupt */
+	ret = at803x_set_wol(phydev, wol);
+	if (ret)
+		return ret;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		/* Enable WOL function for 1588 */
+		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
+				     AT803X_PHY_MMD3_WOL_CTRL,
+				     0, AT803X_WOL_EN);
+	else
+		/* Disable WoL function for 1588 */
+		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
+				     AT803X_PHY_MMD3_WOL_CTRL,
+				     AT803X_WOL_EN, 0);
+
+	return ret;
+}
+
 static int qca83xx_config_init(struct phy_device *phydev)
 {
 	u8 switch_revision;
@@ -2123,7 +2131,7 @@  static struct phy_driver at803x_driver[] = {
 	.config_init		= at8031_config_init,
 	.config_aneg		= at803x_config_aneg,
 	.soft_reset		= genphy_soft_reset,
-	.set_wol		= at803x_set_wol,
+	.set_wol		= at8031_set_wol,
 	.get_wol		= at803x_get_wol,
 	.suspend		= at803x_suspend,
 	.resume			= at803x_resume,