aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sundance.c
diff options
context:
space:
mode:
authorDenis Kirjanov <dkirjanov@kernel.org>2010-10-12 20:56:09 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-16 14:13:21 -0400
commit725a4a465c943ab0f91fcffc3846acbcdb704aac (patch)
tree0b2a49221b57efb26c4d519d17fac6caa949d583 /drivers/net/sundance.c
parent89980827c7a1e3c2b36895c22c6ef0e92aea6b0c (diff)
sundance: Add initial ethtool stats support
Add ethtool stats support. Signed-off-by: Denis Kirjanov <dkirjanov@kernel.org> Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sundance.c')
-rw-r--r--drivers/net/sundance.c94
1 files changed, 87 insertions, 7 deletions
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 4283cc52a8c9..3ed2a67bd6d3 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -363,6 +363,19 @@ struct netdev_private {
363 dma_addr_t tx_ring_dma; 363 dma_addr_t tx_ring_dma;
364 dma_addr_t rx_ring_dma; 364 dma_addr_t rx_ring_dma;
365 struct timer_list timer; /* Media monitoring timer. */ 365 struct timer_list timer; /* Media monitoring timer. */
366 /* ethtool extra stats */
367 struct {
368 u64 tx_multiple_collisions;
369 u64 tx_single_collisions;
370 u64 tx_late_collisions;
371 u64 tx_deferred;
372 u64 tx_deferred_excessive;
373 u64 tx_aborted;
374 u64 tx_bcasts;
375 u64 rx_bcasts;
376 u64 tx_mcasts;
377 u64 rx_mcasts;
378 } xstats;
366 /* Frequently used values: keep some adjacent for cache effect. */ 379 /* Frequently used values: keep some adjacent for cache effect. */
367 spinlock_t lock; 380 spinlock_t lock;
368 int msg_enable; 381 int msg_enable;
@@ -1486,21 +1499,34 @@ static struct net_device_stats *get_stats(struct net_device *dev)
1486{ 1499{
1487 struct netdev_private *np = netdev_priv(dev); 1500 struct netdev_private *np = netdev_priv(dev);
1488 void __iomem *ioaddr = np->base; 1501 void __iomem *ioaddr = np->base;
1489 int i;
1490 unsigned long flags; 1502 unsigned long flags;
1503 u8 late_coll, single_coll, mult_coll;
1491 1504
1492 spin_lock_irqsave(&np->statlock, flags); 1505 spin_lock_irqsave(&np->statlock, flags);
1493 /* The chip only need report frame silently dropped. */ 1506 /* The chip only need report frame silently dropped. */
1494 dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); 1507 dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed);
1495 dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK); 1508 dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
1496 dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK); 1509 dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
1497 dev->stats.collisions += ioread8(ioaddr + StatsLateColl);
1498 dev->stats.collisions += ioread8(ioaddr + StatsMultiColl);
1499 dev->stats.collisions += ioread8(ioaddr + StatsOneColl);
1500 dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError); 1510 dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
1501 ioread8(ioaddr + StatsTxDefer); 1511
1502 for (i = StatsTxDefer; i <= StatsMcastRx; i++) 1512 mult_coll = ioread8(ioaddr + StatsMultiColl);
1503 ioread8(ioaddr + i); 1513 np->xstats.tx_multiple_collisions += mult_coll;
1514 single_coll = ioread8(ioaddr + StatsOneColl);
1515 np->xstats.tx_single_collisions += single_coll;
1516 late_coll = ioread8(ioaddr + StatsLateColl);
1517 np->xstats.tx_late_collisions += late_coll;
1518 dev->stats.collisions += mult_coll
1519 + single_coll
1520 + late_coll;
1521
1522 np->xstats.tx_deferred += ioread8(ioaddr + StatsTxDefer);
1523 np->xstats.tx_deferred_excessive += ioread8(ioaddr + StatsTxXSDefer);
1524 np->xstats.tx_aborted += ioread8(ioaddr + StatsTxAbort);
1525 np->xstats.tx_bcasts += ioread8(ioaddr + StatsBcastTx);
1526 np->xstats.rx_bcasts += ioread8(ioaddr + StatsBcastRx);
1527 np->xstats.tx_mcasts += ioread8(ioaddr + StatsMcastTx);
1528 np->xstats.rx_mcasts += ioread8(ioaddr + StatsMcastRx);
1529
1504 dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow); 1530 dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
1505 dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16; 1531 dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
1506 dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow); 1532 dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
@@ -1566,6 +1592,21 @@ static int __set_mac_addr(struct net_device *dev)
1566 return 0; 1592 return 0;
1567} 1593}
1568 1594
1595static const struct {
1596 const char name[ETH_GSTRING_LEN];
1597} sundance_stats[] = {
1598 { "tx_multiple_collisions" },
1599 { "tx_single_collisions" },
1600 { "tx_late_collisions" },
1601 { "tx_deferred" },
1602 { "tx_deferred_excessive" },
1603 { "tx_aborted" },
1604 { "tx_bcasts" },
1605 { "rx_bcasts" },
1606 { "tx_mcasts" },
1607 { "rx_mcasts" },
1608};
1609
1569static int check_if_running(struct net_device *dev) 1610static int check_if_running(struct net_device *dev)
1570{ 1611{
1571 if (!netif_running(dev)) 1612 if (!netif_running(dev))
@@ -1624,6 +1665,42 @@ static void set_msglevel(struct net_device *dev, u32 val)
1624 np->msg_enable = val; 1665 np->msg_enable = val;
1625} 1666}
1626 1667
1668static void get_strings(struct net_device *dev, u32 stringset,
1669 u8 *data)
1670{
1671 if (stringset == ETH_SS_STATS)
1672 memcpy(data, sundance_stats, sizeof(sundance_stats));
1673}
1674
1675static int get_sset_count(struct net_device *dev, int sset)
1676{
1677 switch (sset) {
1678 case ETH_SS_STATS:
1679 return ARRAY_SIZE(sundance_stats);
1680 default:
1681 return -EOPNOTSUPP;
1682 }
1683}
1684
1685static void get_ethtool_stats(struct net_device *dev,
1686 struct ethtool_stats *stats, u64 *data)
1687{
1688 struct netdev_private *np = netdev_priv(dev);
1689 int i = 0;
1690
1691 get_stats(dev);
1692 data[i++] = np->xstats.tx_multiple_collisions;
1693 data[i++] = np->xstats.tx_single_collisions;
1694 data[i++] = np->xstats.tx_late_collisions;
1695 data[i++] = np->xstats.tx_deferred;
1696 data[i++] = np->xstats.tx_deferred_excessive;
1697 data[i++] = np->xstats.tx_aborted;
1698 data[i++] = np->xstats.tx_bcasts;
1699 data[i++] = np->xstats.rx_bcasts;
1700 data[i++] = np->xstats.tx_mcasts;
1701 data[i++] = np->xstats.rx_mcasts;
1702}
1703
1627static const struct ethtool_ops ethtool_ops = { 1704static const struct ethtool_ops ethtool_ops = {
1628 .begin = check_if_running, 1705 .begin = check_if_running,
1629 .get_drvinfo = get_drvinfo, 1706 .get_drvinfo = get_drvinfo,
@@ -1633,6 +1710,9 @@ static const struct ethtool_ops ethtool_ops = {
1633 .get_link = get_link, 1710 .get_link = get_link,
1634 .get_msglevel = get_msglevel, 1711 .get_msglevel = get_msglevel,
1635 .set_msglevel = set_msglevel, 1712 .set_msglevel = set_msglevel,
1713 .get_strings = get_strings,
1714 .get_sset_count = get_sset_count,
1715 .get_ethtool_stats = get_ethtool_stats,
1636}; 1716};
1637 1717
1638static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 1718static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)