diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 9522c449ccea..d0ecc440aac2 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 | |||
1220 | static 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); |