diff mbox series

[RFC,1/2] net: phy: dp83867: add w/a for packet errors seen with short cables

Message ID 20230425054429.3956535-2-s-vadapalli@ti.com (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series DP83867/DP83869 Ethernet PHY workaround/fix | expand

Checks

Context Check Description
netdev/series_format warning Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
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: 8 this patch: 8
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang success Errors and warnings before: 8 this patch: 8
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: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 28 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Siddharth Vadapalli April 25, 2023, 5:44 a.m. UTC
From: Grygorii Strashko <grygorii.strashko@ti.com>

Introduce the W/A for packet errors seen with short cables (<1m) between
two DP83867 PHYs.

The W/A recommended by DM requires FFE Equalizer Configuration tuning by
writing value 0x0E81 to DSP_FFE_CFG register (0x012C), surrounded by hard
and soft resets as follows:

write_reg(0x001F, 0x8000); //hard reset
write_reg(DSP_FFE_CFG, 0x0E81);
write_reg(0x001F, 0x4000); //soft reset

Since  DP83867 PHY DM says "Changing this register to 0x0E81, will not
affect Long Cable performance.", enable the W/A by default.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
---
 drivers/net/phy/dp83867.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Comments

Andrew Lunn April 25, 2023, 12:05 p.m. UTC | #1
On Tue, Apr 25, 2023 at 11:14:28AM +0530, Siddharth Vadapalli wrote:
> From: Grygorii Strashko <grygorii.strashko@ti.com>
> 
> Introduce the W/A for packet errors seen with short cables (<1m) between
> two DP83867 PHYs.
> 
> The W/A recommended by DM requires FFE Equalizer Configuration tuning by
> writing value 0x0E81 to DSP_FFE_CFG register (0x012C), surrounded by hard
> and soft resets as follows:
> 
> write_reg(0x001F, 0x8000); //hard reset
> write_reg(DSP_FFE_CFG, 0x0E81);
> write_reg(0x001F, 0x4000); //soft reset
> 
> Since  DP83867 PHY DM says "Changing this register to 0x0E81, will not
> affect Long Cable performance.", enable the W/A by default.
> 
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>

https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html

Please set the tree in the Subject line to be net.
Please also add a Fixes: tag, probably for the patch which added this driver.




> ---
>  drivers/net/phy/dp83867.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
> index 5821f04c69dc..ba60cf35872e 100644
> --- a/drivers/net/phy/dp83867.c
> +++ b/drivers/net/phy/dp83867.c
> @@ -42,6 +42,7 @@
>  #define DP83867_STRAP_STS1	0x006E
>  #define DP83867_STRAP_STS2	0x006f
>  #define DP83867_RGMIIDCTL	0x0086
> +#define DP83867_DSP_FFE_CFG	0X012C
>  #define DP83867_RXFCFG		0x0134
>  #define DP83867_RXFPMD1	0x0136
>  #define DP83867_RXFPMD2	0x0137
> @@ -934,8 +935,20 @@ static int dp83867_phy_reset(struct phy_device *phydev)
>  
>  	usleep_range(10, 20);
>  
> -	return phy_modify(phydev, MII_DP83867_PHYCTRL,
> +	err = phy_modify(phydev, MII_DP83867_PHYCTRL,
>  			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
> +	if (err < 0)
> +		return err;
> +
> +	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG, 0X0E81);

Maybe check the return code for errors?

      Andrew
Siddharth Vadapalli April 26, 2023, 5:09 a.m. UTC | #2
On 25/04/23 17:35, Andrew Lunn wrote:
> On Tue, Apr 25, 2023 at 11:14:28AM +0530, Siddharth Vadapalli wrote:
>> From: Grygorii Strashko <grygorii.strashko@ti.com>
>>
>> Introduce the W/A for packet errors seen with short cables (<1m) between
>> two DP83867 PHYs.
>>
>> The W/A recommended by DM requires FFE Equalizer Configuration tuning by
>> writing value 0x0E81 to DSP_FFE_CFG register (0x012C), surrounded by hard
>> and soft resets as follows:
>>
>> write_reg(0x001F, 0x8000); //hard reset
>> write_reg(DSP_FFE_CFG, 0x0E81);
>> write_reg(0x001F, 0x4000); //soft reset
>>
>> Since  DP83867 PHY DM says "Changing this register to 0x0E81, will not
>> affect Long Cable performance.", enable the W/A by default.
>>
>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>> Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
> 
> https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html
> 
> Please set the tree in the Subject line to be net.
> Please also add a Fixes: tag, probably for the patch which added this driver.

I will update the subject to "RFC PATCH net" and also add the "Fixes" tag in the
v2 series.

> 
> 
> 
> 
>> ---
>>  drivers/net/phy/dp83867.c | 15 ++++++++++++++-
>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
>> index 5821f04c69dc..ba60cf35872e 100644
>> --- a/drivers/net/phy/dp83867.c
>> +++ b/drivers/net/phy/dp83867.c
>> @@ -42,6 +42,7 @@
>>  #define DP83867_STRAP_STS1	0x006E
>>  #define DP83867_STRAP_STS2	0x006f
>>  #define DP83867_RGMIIDCTL	0x0086
>> +#define DP83867_DSP_FFE_CFG	0X012C
>>  #define DP83867_RXFCFG		0x0134
>>  #define DP83867_RXFPMD1	0x0136
>>  #define DP83867_RXFPMD2	0x0137
>> @@ -934,8 +935,20 @@ static int dp83867_phy_reset(struct phy_device *phydev)
>>  
>>  	usleep_range(10, 20);
>>  
>> -	return phy_modify(phydev, MII_DP83867_PHYCTRL,
>> +	err = phy_modify(phydev, MII_DP83867_PHYCTRL,
>>  			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
>> +	if (err < 0)
>> +		return err;
>> +
>> +	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG, 0X0E81);
> 
> Maybe check the return code for errors?

The return value of phy_write_mmd() doesn't have to be checked since it will be
zero for the following reasons:
The dp83867 driver does not have a custom .write_mmd method. Also, the dp83867
phy does not support clause 45. Due to this, within __phy_write_mmd(), the ELSE
statement will be executed, which results in the return value being zero.

> 
>       Andrew
Andrew Lunn April 26, 2023, 12:36 p.m. UTC | #3
> >> @@ -934,8 +935,20 @@ static int dp83867_phy_reset(struct phy_device *phydev)
> >>  
> >>  	usleep_range(10, 20);
> >>  
> >> -	return phy_modify(phydev, MII_DP83867_PHYCTRL,
> >> +	err = phy_modify(phydev, MII_DP83867_PHYCTRL,
> >>  			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
> >> +	if (err < 0)
> >> +		return err;
> >> +
> >> +	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG, 0X0E81);
> > 
> > Maybe check the return code for errors?
> 
> The return value of phy_write_mmd() doesn't have to be checked since it will be
> zero for the following reasons:
> The dp83867 driver does not have a custom .write_mmd method. Also, the dp83867
> phy does not support clause 45. Due to this, within __phy_write_mmd(), the ELSE
> statement will be executed, which results in the return value being zero.

Interesting.

I would actually say __phy_write_mmd() is broken, and should be
returning what __mdiobus_write() returns.

You should assume it will get fixed, and check the return value. And
it does no harm to check the return value.

    Andrew
Siddharth Vadapalli April 27, 2023, 4:02 a.m. UTC | #4
On 26/04/23 18:06, Andrew Lunn wrote:
>>>> @@ -934,8 +935,20 @@ static int dp83867_phy_reset(struct phy_device *phydev)
>>>>  
>>>>  	usleep_range(10, 20);
>>>>  
>>>> -	return phy_modify(phydev, MII_DP83867_PHYCTRL,
>>>> +	err = phy_modify(phydev, MII_DP83867_PHYCTRL,
>>>>  			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
>>>> +	if (err < 0)
>>>> +		return err;
>>>> +
>>>> +	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG, 0X0E81);
>>>
>>> Maybe check the return code for errors?
>>
>> The return value of phy_write_mmd() doesn't have to be checked since it will be
>> zero for the following reasons:
>> The dp83867 driver does not have a custom .write_mmd method. Also, the dp83867
>> phy does not support clause 45. Due to this, within __phy_write_mmd(), the ELSE
>> statement will be executed, which results in the return value being zero.
> 
> Interesting.
> 
> I would actually say __phy_write_mmd() is broken, and should be
> returning what __mdiobus_write() returns.
> 
> You should assume it will get fixed, and check the return value. And
> it does no harm to check the return value.

Thank you for clarifying. The reasoning behind the initial patch not checking
the return value was:
At all invocations of phy_write_mmd() in the dp83867 driver, at no place is the
return value checked, which led me to analyze why that was the case. I noticed
that it was due to the return value being guaranteed to be zero for this
particular driver.

Since the existing __phy_write_mmd() implementation is broken as pointed out by
you, I will update this patch to check the return value. Also, I will probably
add a cleanup patch as well, to fix this at all other invocations of
phy_write_mmd() in the driver.
diff mbox series

Patch

diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 5821f04c69dc..ba60cf35872e 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -42,6 +42,7 @@ 
 #define DP83867_STRAP_STS1	0x006E
 #define DP83867_STRAP_STS2	0x006f
 #define DP83867_RGMIIDCTL	0x0086
+#define DP83867_DSP_FFE_CFG	0X012C
 #define DP83867_RXFCFG		0x0134
 #define DP83867_RXFPMD1	0x0136
 #define DP83867_RXFPMD2	0x0137
@@ -934,8 +935,20 @@  static int dp83867_phy_reset(struct phy_device *phydev)
 
 	usleep_range(10, 20);
 
-	return phy_modify(phydev, MII_DP83867_PHYCTRL,
+	err = phy_modify(phydev, MII_DP83867_PHYCTRL,
 			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
+	if (err < 0)
+		return err;
+
+	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG, 0X0E81);
+
+	err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESTART);
+	if (err < 0)
+		return err;
+
+	usleep_range(10, 20);
+
+	return 0;
 }
 
 static void dp83867_link_change_notify(struct phy_device *phydev)