diff mbox

gianfar: Reduce logging noise seen due to phy polling if link is down

Message ID 1425326607-21464-1-git-send-email-linux@roeck-us.net
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Guenter Roeck March 2, 2015, 8:03 p.m. UTC
Commit 6ce29b0e2a04 ("gianfar: Avoid unnecessary reg accesses in adjust_link()")
eliminates unnecessary calls to adjust_link for phy devices which don't support
interrupts and need polling. As part of that work, the 'new_state' local flag,
which was used to reduce logging noise on the console, was eliminated.

Unfortunately, that means that a 'Link is Down' log message will now be
issued continuously if a link is configured as UP, the link state is down,
and the associated phy requires polling. This occurs because priv->oldduplex
is -1 in this case, which always differs from phydev->duplex. In addition,
phydev->speed may also differ from priv->oldspeed.  gfar_update_link_state()
is therefore called each time a phy is polled, even if the link state did not
change.

Cc: Claudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/ethernet/freescale/gianfar.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Claudiu Manoil March 3, 2015, 2:42 p.m. UTC | #1
> -----Original Message-----
> From: Guenter Roeck [mailto:linux@roeck-us.net]
> Sent: Monday, March 02, 2015 10:03 PM
> 
[...]
> 
> Cc: Claudiu Manoil <claudiu.manoil@freescale.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
[...]
>  	if (unlikely(phydev->link != priv->oldlink ||
> -		     phydev->duplex != priv->oldduplex ||
> -		     phydev->speed != priv->oldspeed))
> +		     (phydev->link && (phydev->duplex != priv->oldduplex ||
> +				       phydev->speed != priv->oldspeed))))
>  		gfar_update_link_state(priv);
>  }

I did a quick check and, indeed, phydev->duplex or phydev->speed
may change even if phydev->link is 0.  I could reproduce the issue
with the following test for an eth with a polling mode phy:
1) initially link is up - autoneg on, speed 1000;
2) taking the link down - link down message printed only once;
3) turning autoneg to off for the same eth  - link down message
is printed continuously;

So, given this, I agree that the driver needs this protection before
accessing the phydev->duplex/speed fields, namely to check first whether
phydev->link is 1.  If link is 0, phydev->speed/duplex may be bogus.

Thanks for spotting this.

Reviewed-by: Claudiu Manoil <claudiu.manoil@freescale.com>

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller March 3, 2015, 7:37 p.m. UTC | #2
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon,  2 Mar 2015 12:03:27 -0800

> Commit 6ce29b0e2a04 ("gianfar: Avoid unnecessary reg accesses in adjust_link()")
> eliminates unnecessary calls to adjust_link for phy devices which don't support
> interrupts and need polling. As part of that work, the 'new_state' local flag,
> which was used to reduce logging noise on the console, was eliminated.
> 
> Unfortunately, that means that a 'Link is Down' log message will now be
> issued continuously if a link is configured as UP, the link state is down,
> and the associated phy requires polling. This occurs because priv->oldduplex
> is -1 in this case, which always differs from phydev->duplex. In addition,
> phydev->speed may also differ from priv->oldspeed.  gfar_update_link_state()
> is therefore called each time a phy is polled, even if the link state did not
> change.
> 
> Cc: Claudiu Manoil <claudiu.manoil@freescale.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

Applied, thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 43df788..178e540 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -3162,8 +3162,8 @@  static void adjust_link(struct net_device *dev)
 	struct phy_device *phydev = priv->phydev;
 
 	if (unlikely(phydev->link != priv->oldlink ||
-		     phydev->duplex != priv->oldduplex ||
-		     phydev->speed != priv->oldspeed))
+		     (phydev->link && (phydev->duplex != priv->oldduplex ||
+				       phydev->speed != priv->oldspeed))))
 		gfar_update_link_state(priv);
 }