diff mbox

net/fec on i.MX28: failure after network cable unplug or device down

Message ID 20111010131705.GA25293@pengutronix.de
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Uwe Kleine-König Oct. 10, 2011, 1:17 p.m. UTC
Hello,

I currently see the problem on two different i.MX28 based system
(Freescale's mx28evk and a Karo TX28) that after unplugging and
reconnection of the network cable or ifconfig down; ifconfig up; the
network is dead. That means nothing is sent or received anymore.

ifconfig up dies with:

	[   32.120000] FEC: MDIO read timeout
	[   32.120000] eth0: could not attach to PHY
	ifconfig: SIOCSIFFLAGS: Connection timed out

after unplugging the network cable I get:

	[   25.520000] PHY: 1:00 - Link is Down
	[   26.530000] FEC: MDIO read timeout

In both cases the mdio read operation doesn't fire the mii irq, though
the FEC_MII_DATA contains data that looks right and the interrupt
register (FEC_IEVENT) has the mii bit set and according to the mask
register (FEC_IMASK) the irq isn't masked.

When commenting out

	writel(1, fep->hwp + FEC_ECNTRL);

(i.e. don't reset the network unit) in fec_stop it works (but Wolfram
seems to remember that doing so breaks e.g. i.MX35. We have not checked
yet).

Strange enough with the reset commented out in fec_stop, fec_restart
resets the fec (when the cable is reconnected) but without breaking it.

I tried to restore more registers in fec_stop (most notably FEC_R_CNTRL
that has some mii fields) but without success.

Do you see this problem, too? Maybe do you have an idea to fix it?
Currently I use the following patch:

hardware without link then.

Best regards
Uwe

Comments

Lothar Waßmann Oct. 10, 2011, 1:52 p.m. UTC | #1
Hi,

Uwe Kleine-König writes:
> Hello,
> 
> I currently see the problem on two different i.MX28 based system
> (Freescale's mx28evk and a Karo TX28) that after unplugging and
> reconnection of the network cable or ifconfig down; ifconfig up; the
> network is dead. That means nothing is sent or received anymore.
> 
I already solved this problem (and some others too), but wasn't able
to send any patch yet.

The FEC of the i.MX28 requires the ETHER_EN bit in the ECR to be set
for the MII interface to work. Resetting the interface upon shutdown
is required though, because otherwise the receiver will remain active
and use the stale DMA descriptors in memory to store received packets!

Furthermore the (R)MII mode must be configured correctly in the RCR
register.

The current state of my patch is appended for reference.


Lothar Waßmann
--
diff mbox

Patch

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 5b631fe..8c1330f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -458,6 +458,8 @@  static void
 fec_stop(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	const struct platform_device_id *id_entry =
+				platform_get_device_id(fep->pdev);
 
 	/* We cannot expect a graceful transmit stop without link !!! */
 	if (fep->link) {
@@ -467,11 +469,13 @@  fec_stop(struct net_device *ndev)
 			printk("fec_stop : Graceful transmit stop did not complete !\n");
 	}
 
-	/* Whack a reset.  We should wait for this. */
-	writel(1, fep->hwp + FEC_ECNTRL);
-	udelay(10);
-	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
-	writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+	if (!(id_entry->driver_data & FEC_QUIRK_ENET_MAC)) {
+		/* Whack a reset.  We should wait for this. */
+		writel(1, fep->hwp + FEC_ECNTRL);
+		udelay(10);
+		writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
+		writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+	}
 }
 
but this feels wrong because sending and receiving isn't disabled in