[U-Boot] [PATCH] net: cpsw: am335x: Drop constant link checking from rx/tx path's

Stefan Roese sr at denx.de
Mon Aug 25 11:26:19 CEST 2014


We noticed on the DXR2 platform (AM335x with a SMSC LAN9303 switch connected
to the CPSW MAC) that the network performance in U-Boot is quite poor. Only
when the transfer is started without a cable connected, and the cable is
plugged after the first timeout "T" occured, an increased in performance
can be seen. Debugging has revealed, that the cpsw driver has constant
link checking builtin into the rx and tx functions. This results in the
bad performance and seems to be unnecessary. The link has already been
checked in the init function, before the transfer is started. This usually
is sufficient.

BTW: I have seen no other network driver in U-Boot so far, that constantly
checks for link in the rx / tx functions.

The performance numbers on the DXR2 board are:

0.56 MiB/s	cpsw_check_link() in rx and tx path
0.87 MiB/s	cpsw_check_link() only in tx path
1.0  MiB/s	cpsw_check_link() only in rx path
2.7  MiB/s	no cpsw_check_link() in rx and tx path

So with this patch the network performance on DXR2 increases from 0.56
to 2.7 MiB/s (nearly 5 times as fast).

Signed-off-by: Stefan Roese <sr at denx.de>
Tested-by: Samuel Egli <samuel.egli at siemens.com>
Tested-by: Heiko Schocher <hs at denx.de>
Cc: Vladimir Koutny <vladimir.koutny at streamunlimited.com>
Cc: Mugunthan V N <mugunthanvnm at ti.com>
Cc: Joe Hershberger <joe.hershberger at gmail.com>
Cc: Tom Rini <trini at ti.com>
---
 drivers/net/cpsw.c | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 8ec5161..52f8da6 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -235,7 +235,6 @@ struct cpsw_priv {
 	struct phy_device		*phydev;
 	struct mii_dev			*bus;
 
-	u32				mdio_link;
 	u32				phy_mask;
 };
 
@@ -613,19 +612,8 @@ static int cpsw_update_link(struct cpsw_priv *priv)
 
 	for_active_slave(slave, priv)
 		cpsw_slave_update_link(slave, priv, &link);
-	priv->mdio_link = readl(&mdio_regs->link);
-	return link;
-}
-
-static int cpsw_check_link(struct cpsw_priv *priv)
-{
-	u32 link = 0;
 
-	link = __raw_readl(&mdio_regs->link) & priv->phy_mask;
-	if ((link) && (link == priv->mdio_link))
-		return 1;
-
-	return cpsw_update_link(priv);
+	return link;
 }
 
 static inline u32  cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
@@ -891,9 +879,6 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length)
 	int len;
 	int timeout = CPDMA_TIMEOUT;
 
-	if (!cpsw_check_link(priv))
-		return -EIO;
-
 	flush_dcache_range((unsigned long)packet,
 			   (unsigned long)packet + length);
 
@@ -916,8 +901,6 @@ static int cpsw_recv(struct eth_device *dev)
 	void *buffer;
 	int len;
 
-	cpsw_check_link(priv);
-
 	while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
 		invalidate_dcache_range((unsigned long)buffer,
 					(unsigned long)buffer + PKTSIZE_ALIGN);
-- 
2.1.0



More information about the U-Boot mailing list