aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-09-18 23:04:57 -0400
committerLennert Buytenhek <buytenh@marvell.com>2008-09-18 23:13:54 -0400
commit4ff3495a51c7226376d8013c5742d1d5e54876a7 (patch)
tree51b85dd78a89de6f57e9cc96e0de05347ab0eb41 /drivers/net/mv643xx_eth.c
parent4df89bd5a5fc33860f15f5f001a78f2b3f150725 (diff)
mv643xx_eth: enforce frequent hardware statistics polling
If we don't poll the hardware statistics counters at least once every ~34 seconds, overflow might occur without us noticing. So, set up a timer to poll the statistics counters at least once every 30 seconds. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 9522c449cce..d0ecc440aac 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -356,7 +356,10 @@ struct mv643xx_eth_private {
356 356
357 int phy_addr; 357 int phy_addr;
358 358
359 struct timer_list mib_counters_timer;
360 spinlock_t mib_counters_lock;
359 struct mib_counters mib_counters; 361 struct mib_counters mib_counters;
362
360 struct work_struct tx_timeout_task; 363 struct work_struct tx_timeout_task;
361 struct mii_if_info mii; 364 struct mii_if_info mii;
362 365
@@ -1176,6 +1179,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
1176{ 1179{
1177 struct mib_counters *p = &mp->mib_counters; 1180 struct mib_counters *p = &mp->mib_counters;
1178 1181
1182 spin_lock(&mp->mib_counters_lock);
1179 p->good_octets_received += mib_read(mp, 0x00); 1183 p->good_octets_received += mib_read(mp, 0x00);
1180 p->good_octets_received += (u64)mib_read(mp, 0x04) << 32; 1184 p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
1181 p->bad_octets_received += mib_read(mp, 0x08); 1185 p->bad_octets_received += mib_read(mp, 0x08);
@@ -1208,6 +1212,16 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
1208 p->bad_crc_event += mib_read(mp, 0x74); 1212 p->bad_crc_event += mib_read(mp, 0x74);
1209 p->collision += mib_read(mp, 0x78); 1213 p->collision += mib_read(mp, 0x78);
1210 p->late_collision += mib_read(mp, 0x7c); 1214 p->late_collision += mib_read(mp, 0x7c);
1215 spin_unlock(&mp->mib_counters_lock);
1216
1217 mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);
1218}
1219
1220static void mib_counters_timer_wrapper(unsigned long _mp)
1221{
1222 struct mv643xx_eth_private *mp = (void *)_mp;
1223
1224 mib_counters_update(mp);
1211} 1225}
1212 1226
1213 1227
@@ -2148,6 +2162,8 @@ static int mv643xx_eth_stop(struct net_device *dev)
2148 wrl(mp, INT_MASK(mp->port_num), 0x00000000); 2162 wrl(mp, INT_MASK(mp->port_num), 0x00000000);
2149 rdl(mp, INT_MASK(mp->port_num)); 2163 rdl(mp, INT_MASK(mp->port_num));
2150 2164
2165 del_timer_sync(&mp->mib_counters_timer);
2166
2151 napi_disable(&mp->napi); 2167 napi_disable(&mp->napi);
2152 2168
2153 del_timer_sync(&mp->rx_oom); 2169 del_timer_sync(&mp->rx_oom);
@@ -2625,6 +2641,19 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
2625 } 2641 }
2626 init_pscr(mp, pd->speed, pd->duplex); 2642 init_pscr(mp, pd->speed, pd->duplex);
2627 2643
2644
2645 mib_counters_clear(mp);
2646
2647 init_timer(&mp->mib_counters_timer);
2648 mp->mib_counters_timer.data = (unsigned long)mp;
2649 mp->mib_counters_timer.function = mib_counters_timer_wrapper;
2650 mp->mib_counters_timer.expires = jiffies + 30 * HZ;
2651 add_timer(&mp->mib_counters_timer);
2652
2653 spin_lock_init(&mp->mib_counters_lock);
2654
2655 INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);
2656
2628 netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128); 2657 netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128);
2629 2658
2630 init_timer(&mp->rx_oom); 2659 init_timer(&mp->rx_oom);