summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2012-08-29 03:49:50 +0000
committerJoe Hershberger <joe.hershberger@ni.com>2012-09-27 12:22:10 -0500
commit67449098a86be18cbdb27345bebe8da57e5d8899 (patch)
tree7cb193f9f974c316d238a145c26975f645988ef6
parentbc1ce150b95bc51390add7fb8b74c535d1b5673c (diff)
downloadu-boot-imx-67449098a86be18cbdb27345bebe8da57e5d8899.zip
u-boot-imx-67449098a86be18cbdb27345bebe8da57e5d8899.tar.gz
u-boot-imx-67449098a86be18cbdb27345bebe8da57e5d8899.tar.bz2
FEC: Rework the TX wait mechanism
The mechanism waiting for transmission to finish in fec_send() now relies on the E-bit being cleared in the TX buffer descriptor. In case of data cache being on, this means invalidation of data cache above this TX buffer descriptor on each test for the E-bit being cleared. Apparently, there is another way to check if the transmission did complete. This is by checking the TDAR bit in the X_DES_ACTIVE register. Reading a register does not need any data cache invalidation, which is beneficial. Rework the sequence that wait for completion of the transmission so that the TDAR bit is tested first and afterwards check the E-bit being clear. This cuts down the number of cache invalidation calls to one. 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>
-rw-r--r--drivers/net/fec_mxc.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 6f071e9..6ede464 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -768,19 +768,21 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
* invalidate data cache to see what's really in RAM. Also, we need
* barrier here.
*/
- invalidate_dcache_range(addr, addr + size);
- while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
- udelay(1);
- invalidate_dcache_range(addr, addr + size);
- if (!timeout--) {
- ret = -EINVAL;
+ while (--timeout) {
+ if (!(readl(&fec->eth->x_des_active) & (1 << 24)))
break;
- }
}
- debug("fec_send: status 0x%x index %d\n",
+ if (!timeout)
+ ret = -EINVAL;
+
+ invalidate_dcache_range(addr, addr + size);
+ if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
+ ret = -EINVAL;
+
+ debug("fec_send: status 0x%x index %d ret %i\n",
readw(&fec->tbd_base[fec->tbd_index].status),
- fec->tbd_index);
+ fec->tbd_index, ret);
/* for next transmission use the other buffer */
if (fec->tbd_index)
fec->tbd_index = 0;