Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d97e7497 authored by Lucas Stach's avatar Lucas Stach Committed by David S. Miller
Browse files

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: default avatarLucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cca7af38
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -934,25 +934,29 @@ 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;
		}

		if (fep->full_duplex != phy_dev->duplex)
			status_change = 1;

		if (phy_dev->speed != fep->speed) {
			fep->speed = phy_dev->speed;
			status_change = 1;
		}

	/* Link on or off change */
	if (phy_dev->link != fep->link) {
		fep->link = phy_dev->link;
		if (phy_dev->link)
		/* 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;
		}
	}

spin_unlock:
	spin_unlock_irqrestore(&fep->hw_lock, flags);
+1 −0
Original line number Diff line number Diff line
@@ -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;