summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2012-08-29 03:49:49 +0000
committerJoe Hershberger <joe.hershberger@ni.com>2012-09-27 12:22:09 -0500
commitbc1ce150b95bc51390add7fb8b74c535d1b5673c (patch)
tree960c3156eb39d01c9e6cb45caa1792f082607053 /drivers
parentefe24d2e17996f00b8803623c53cfe4baede9349 (diff)
downloadu-boot-imx-bc1ce150b95bc51390add7fb8b74c535d1b5673c.zip
u-boot-imx-bc1ce150b95bc51390add7fb8b74c535d1b5673c.tar.gz
u-boot-imx-bc1ce150b95bc51390add7fb8b74c535d1b5673c.tar.bz2
FEC: Remove endless loop in the FEC driver
The FEC hardware sometimes errors out on data transfer and hangs in the tightloop adjusted by this patch. So add timeout into the tightloop to make such a hang recoverable. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Joe Hershberger <joe.hershberger@ni.com> Cc: Fabio Estevam <festevam@gmail.com> Cc: Otavio Salvador <otavio@ossystems.com.br> Cc: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/fec_mxc.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index bc44d38..6f071e9 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -35,6 +35,12 @@
DECLARE_GLOBAL_DATA_PTR;
+/*
+ * Timeout the transfer after 5 mS. This is usually a bit more, since
+ * the code in the tightloops this timeout is used in adds some overhead.
+ */
+#define FEC_XFER_TIMEOUT 5000
+
#ifndef CONFIG_MII
#error "CONFIG_MII has to be defined!"
#endif
@@ -697,6 +703,8 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
unsigned int status;
uint32_t size, end;
uint32_t addr;
+ int timeout = FEC_XFER_TIMEOUT;
+ int ret = 0;
/*
* This routine transmits one frame. This routine only accepts
@@ -764,6 +772,10 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
udelay(1);
invalidate_dcache_range(addr, addr + size);
+ if (!timeout--) {
+ ret = -EINVAL;
+ break;
+ }
}
debug("fec_send: status 0x%x index %d\n",
@@ -775,7 +787,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
else
fec->tbd_index = 1;
- return 0;
+ return ret;
}
/**