Commit 97f568d8 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik

8139cp: safer spin loop for get_statistics

The spin loop in 8139cp is limited to 100 iterations when pulling hardware
stats. There is no allowance for processor speed so on a fast machine, the
stats may not be available that fast. Also, if the board doesn't return
soon enough make sure turn the address back off to prevent later updates
when memory has gone away.
parent 223d4727
...@@ -1516,22 +1516,22 @@ static void cp_get_ethtool_stats (struct net_device *dev, ...@@ -1516,22 +1516,22 @@ static void cp_get_ethtool_stats (struct net_device *dev,
struct ethtool_stats *estats, u64 *tmp_stats) struct ethtool_stats *estats, u64 *tmp_stats)
{ {
struct cp_private *cp = netdev_priv(dev); struct cp_private *cp = netdev_priv(dev);
unsigned int work = 100;
int i; int i;
memset(cp->nic_stats, 0, sizeof(struct cp_dma_stats));
/* begin NIC statistics dump */ /* begin NIC statistics dump */
cpw32(StatsAddr + 4, (cp->nic_stats_dma >> 16) >> 16); cpw32(StatsAddr + 4, (cp->nic_stats_dma >> 16) >> 16);
cpw32(StatsAddr, (cp->nic_stats_dma & 0xffffffff) | DumpStats); cpw32(StatsAddr, (cp->nic_stats_dma & 0xffffffff) | DumpStats);
cpr32(StatsAddr); cpr32(StatsAddr);
while (work-- > 0) { for (i = 0; i < 1000; i++) {
if ((cpr32(StatsAddr) & DumpStats) == 0) if ((cpr32(StatsAddr) & DumpStats) == 0)
break; break;
cpu_relax(); udelay(10);
} }
cpw32(StatsAddr, 0);
if (cpr32(StatsAddr) & DumpStats) cpw32(StatsAddr + 4, 0);
return /* -EIO */;
i = 0; i = 0;
tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok); tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment