diff mbox

davinci_mdio: Fix MDIO timeout check

Message ID 1334586925-11348-1-git-send-email-christian.riesch@omicron.at
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Christian Riesch April 16, 2012, 2:35 p.m. UTC
Under heavy load (flood ping) it is possible for the MDIO timeout to
expire before the loop checks the GO bit again. This patch adds an
additional check whether the operation was done before actually
returning -ETIMEDOUT.

To reproduce this bug, flood ping the device, e.g., ping -f -l 1000
After some time, a "timed out waiting for user access" warning
may appear. And even worse, link may go down since the PHY reported a
timeout.

Signed-off-by: Christian Riesch <christian.riesch@omicron.at>
Cc: <stable@vger.kernel.org>
Cc: Cyril Chemparathy <cyril@ti.com>
---
 drivers/net/ethernet/ti/davinci_mdio.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

Comments

David Miller April 18, 2012, 2:32 a.m. UTC | #1
From: Christian Riesch <christian.riesch@omicron.at>
Date: Mon, 16 Apr 2012 16:35:25 +0200

> Under heavy load (flood ping) it is possible for the MDIO timeout to
> expire before the loop checks the GO bit again. This patch adds an
> additional check whether the operation was done before actually
> returning -ETIMEDOUT.
> 
> To reproduce this bug, flood ping the device, e.g., ping -f -l 1000
> After some time, a "timed out waiting for user access" warning
> may appear. And even worse, link may go down since the PHY reported a
> timeout.
> 
> Signed-off-by: Christian Riesch <christian.riesch@omicron.at>
> Cc: <stable@vger.kernel.org>
> Cc: Cyril Chemparathy <cyril@ti.com>

Applied.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 2757c7d..e4e4708 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -181,6 +181,11 @@  static inline int wait_for_user_access(struct davinci_mdio_data *data)
 		__davinci_mdio_reset(data);
 		return -EAGAIN;
 	}
+
+	reg = __raw_readl(&regs->user[0].access);
+	if ((reg & USERACCESS_GO) == 0)
+		return 0;
+
 	dev_err(data->dev, "timed out waiting for user access\n");
 	return -ETIMEDOUT;
 }