netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: fec: restart the FEC when PHY speed changes
@ 2013-03-14 15:12 Lucas Stach
  2013-03-15  4:37 ` Frank Li
  2013-03-15 12:47 ` David Miller
  0 siblings, 2 replies; 3+ messages in thread
From: Lucas Stach @ 2013-03-14 15:12 UTC (permalink / raw)
  To: netdev; +Cc: Frank Li, David S. Miller, Lucas Stach

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 <l.stach@pengutronix.de>
---
 drivers/net/ethernet/freescale/fec.c |   26 +++++++++++++++-----------
 drivers/net/ethernet/freescale/fec.h |    1 +
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 069a155..61d2e62 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:
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index f539007..eb43729 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -240,6 +240,7 @@ struct fec_enet_private {
 	phy_interface_t	phy_interface;
 	int	link;
 	int	full_duplex;
+	int	speed;
 	struct	completion mdio_done;
 	int	irq[FEC_IRQ_NUM];
 	int	bufdesc_ex;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] net: fec: restart the FEC when PHY speed changes
  2013-03-14 15:12 [PATCH] net: fec: restart the FEC when PHY speed changes Lucas Stach
@ 2013-03-15  4:37 ` Frank Li
  2013-03-15 12:47 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: Frank Li @ 2013-03-15  4:37 UTC (permalink / raw)
  To: Lucas Stach; +Cc: netdev, Frank Li, David S. Miller

Acked

2013/3/14 Lucas Stach <l.stach@pengutronix.de>:
> 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 <l.stach@pengutronix.de>
> ---
>  drivers/net/ethernet/freescale/fec.c |   26 +++++++++++++++-----------
>  drivers/net/ethernet/freescale/fec.h |    1 +
>  2 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
> index 069a155..61d2e62 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:
> diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
> index f539007..eb43729 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -240,6 +240,7 @@ struct fec_enet_private {
>         phy_interface_t phy_interface;
>         int     link;
>         int     full_duplex;
> +       int     speed;
>         struct  completion mdio_done;
>         int     irq[FEC_IRQ_NUM];
>         int     bufdesc_ex;
> --
> 1.7.10.4
>
> --
> 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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] net: fec: restart the FEC when PHY speed changes
  2013-03-14 15:12 [PATCH] net: fec: restart the FEC when PHY speed changes Lucas Stach
  2013-03-15  4:37 ` Frank Li
@ 2013-03-15 12:47 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2013-03-15 12:47 UTC (permalink / raw)
  To: l.stach; +Cc: netdev, Frank.Li

From: Lucas Stach <l.stach@pengutronix.de>
Date: Thu, 14 Mar 2013 16:12:01 +0100

> 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 <l.stach@pengutronix.de>

Applied.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-03-15 12:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-14 15:12 [PATCH] net: fec: restart the FEC when PHY speed changes Lucas Stach
2013-03-15  4:37 ` Frank Li
2013-03-15 12:47 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).