From 5a834c1f9e8ba6995c24bb93da4e766af9374f5b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 25 Aug 2014 11:26:19 +0200 Subject: [PATCH] net: cpsw: am335x: Drop constant link checking from rx/tx path's 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 Tested-by: Samuel Egli Tested-by: Heiko Schocher Cc: Vladimir Koutny Cc: Mugunthan V N Cc: Joe Hershberger Cc: Tom Rini --- 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 8ec5161ec6..52f8da67e1 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.39.5