From d97e74976982a35168c7f131cce0d93537337a26 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 14 Mar 2013 05:12:01 +0000 Subject: net: fec: restart the FEC when PHY speed changes Proviously we would only restart the FEC when PHY link or duplex state changed. PHY does not always bring down the link for speed changes, in which case we would not detect any change and keep FEC running. Switching link speed without restarting the FEC results in the FEC being stuck in an indefinite state, generating error conditions for every packet. Signed-off-by: Lucas Stach Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers/net/ethernet/freescale/fec.c') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 069a155d16e..61d2e6202bf 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -934,24 +934,28 @@ static void fec_enet_adjust_link(struct net_device *ndev) goto spin_unlock; } - /* Duplex link change */ if (phy_dev->link) { - if (fep->full_duplex != phy_dev->duplex) { - fec_restart(ndev, phy_dev->duplex); - /* prevent unnecessary second fec_restart() below */ + if (!fep->link) { fep->link = phy_dev->link; status_change = 1; } - } - /* Link on or off change */ - if (phy_dev->link != fep->link) { - fep->link = phy_dev->link; - if (phy_dev->link) + if (fep->full_duplex != phy_dev->duplex) + status_change = 1; + + if (phy_dev->speed != fep->speed) { + fep->speed = phy_dev->speed; + status_change = 1; + } + + /* if any of the above changed restart the FEC */ + if (status_change) fec_restart(ndev, phy_dev->duplex); - else + } else { + if (fep->link) { fec_stop(ndev); - status_change = 1; + status_change = 1; + } } spin_unlock: -- cgit v1.2.3-70-g09d2 From 3f104c38259dcb3e5443c246f0805bc04d887cc3 Mon Sep 17 00:00:00 2001 From: Georg Hofmann Date: Thu, 14 Mar 2013 06:54:09 +0000 Subject: net: fec: fix missing napi_disable call Commit dc975382d2ef36be7e78fac3717927de1a5abcd8 introduces napi support but never calls napi_disable. This will generate a kernel oops (kernel BUG at include/linux/netdevice.h:473!) every time, when ndo_stop is called followed by ndo_start. Add the missing napi_diable call. Signed-off-by: Georg Hofmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/ethernet/freescale/fec.c') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 61d2e6202bf..e3f39372ce2 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1441,6 +1441,7 @@ fec_enet_close(struct net_device *ndev) struct fec_enet_private *fep = netdev_priv(ndev); /* Don't know what to do yet. */ + napi_disable(&fep->napi); fep->opened = 0; netif_stop_queue(ndev); fec_stop(ndev); -- cgit v1.2.3-70-g09d2