[U-Boot] [PATCH 2/3] FEC: Rework the TX wait mechanism

Marek Vasut marex at denx.de
Wed Aug 29 15:49:50 CEST 2012


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 at denx.de>
Cc: Joe Hershberger <joe.hershberger at ni.com>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Otavio Salvador <otavio at ossystems.com.br>
Cc: Stefano Babic <sbabic at denx.de>
---
 drivers/net/fec_mxc.c |   20 +++++++++++---------
 1 file 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;
-- 
1.7.10.4



More information about the U-Boot mailing list