Message ID | 1425326607-21464-1-git-send-email-linux@roeck-us.net |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
> -----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
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 --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); }
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(-)