sundance: Add initial ethtool stats support
Subsystems (2)
PATCH 1/1 sundance: Add initial ethtool stats support
Add initial ethtool statistics support
--- drivers/net/sundance.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-)
drivers/net/sundance.c +46 -0
@@ -1564,6 +1564,18 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_packets" }, + {"tx_bytes" }, + {"rx_packets" }, + {"rx_bytes" }, + {"tx_errors" }, + {"tx_dropped" }, + {"rx_errors" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
@@ -1622,6 +1634,37 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{ +memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct net_device_stats *netdev_stats =get_stats (dev); +int i =0 ; + + data[i++] = netdev_stats->tx_packets; + data[i++] = netdev_stats->tx_bytes; + data[i++] = netdev_stats->rx_packets; + data[i++] = netdev_stats->rx_bytes; + data[i++] = netdev_stats->tx_errors; + data[i++] = netdev_stats->tx_dropped; + data[i++] = netdev_stats->rx_errors; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,
@@ -1631,6 +1674,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Signature · 1 line
1.7.0
PATCH 1/1 sundance: get_stats proper locking
Quoted 1 line · Denis Kirjanov
Add initial ethtool statistics support
OK, I guess its time to add proper locking into sundance after all ;)
[PATCH net-next] sundance: get_stats proper locking
sundance get_stats() should not be run concurrently, add a lock to avoid potential losses.
Note: Remove unused rx_lock field
--- drivers/net/sundance.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/sundance.c +6 -4
@@ -365,7 +365,6 @@ struct netdev_private {struct timer_list timer;/* Media monitoring timer. */ /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; -spinlock_t rx_lock;/* Group with Tx control cache line. */ int msg_enable;int chip_id;unsigned int cur_rx, dirty_rx;/* Producer/consumer ring indices */
@@ -390,6 +389,7 @@ struct netdev_private {unsigned char phys[MII_CNT ];/* MII device addresses, only first one used. */ struct pci_dev *pci_dev;void __iomem *base; +spinlock_t statlock; };/* The station address location in the EEPROM. */
@@ -514,6 +514,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, np->chip_id = chip_idx; np->msg_enable = (1 << debug) -1 ;spin_lock_init (&np->lock); +spin_lock_init (&np->statlock);tasklet_init (&np->rx_tasklet, rx_poll, (unsigned long )dev);tasklet_init (&np->tx_tasklet, tx_poll, (unsigned long )dev);
@@ -1486,10 +1487,9 @@ static struct net_device_stats *get_stats(struct net_device *dev)struct netdev_private *np =netdev_priv (dev);void __iomem *ioaddr = np->base;int i; +unsigned long flags; -/* We should lock this segment of code for SMP eventually, although -the vulnerability window is very small and statistics are -non-critical. */ +spin_lock_irqsave (&np->statlock, flags);/* The chip only need report frame silently dropped. */ dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK);
@@ -1506,6 +1506,8 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsLow); dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsHigh) <<16 ; +spin_unlock_irqrestore (&np->statlock, flags); +return &dev->stats; }
Quoted 31 lines · Denis Kirjanov
Add initial ethtool statistics support
Signed-off-by Denis Kirjanov <[email protected]>--- drivers/net/sundance.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-)drivers/net/sundance.c +12
-0@@ -1564,6 +1564,18 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_packets" }, + {"tx_bytes" }, + {"rx_packets" }, + {"rx_bytes" }, + {"tx_errors" }, + {"tx_dropped" }, + {"rx_errors" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
drivers/net/sundance.c static void set_msglevel(struct net_device *dev, u32 val) · line 1639
Quoted 6 lines
drivers/net/sundance.c +3
-0@@ -1622,6 +1634,37 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{
if (stringset != ETH_SS_STATS) return;
Quoted 41 lines
drivers/net/sundance.c +31
-0+memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct net_device_stats *netdev_stats =get_stats (dev); +int i =0 ; + + data[i++] = netdev_stats->tx_packets; + data[i++] = netdev_stats->tx_bytes; + data[i++] = netdev_stats->rx_packets; + data[i++] = netdev_stats->rx_bytes; + data[i++] = netdev_stats->tx_errors; + data[i++] = netdev_stats->tx_dropped; + data[i++] = netdev_stats->rx_errors; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,@@ -1631,6 +1674,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Quoted 1 line · Denis Kirjanov
Add initial ethtool statistics support
[...]
Quoted 4 lines
drivers/net/sundance.c +4
-0+static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct net_device_stats *netdev_stats =get_stats (dev);
drivers/net/sundance.c static void set_msglevel(struct net_device *dev, u32 val) · line 1666
Quoted 10 lines
drivers/net/sundance.c +10
-0+int i =0 ; + + data[i++] = netdev_stats->tx_packets; + data[i++] = netdev_stats->tx_bytes; + data[i++] = netdev_stats->rx_packets; + data[i++] = netdev_stats->rx_bytes; + data[i++] = netdev_stats->tx_errors; + data[i++] = netdev_stats->tx_dropped; + data[i++] = netdev_stats->rx_errors; +}
[...]
There is no point in adding ethtool stats that merely mirror the baseline net device stats.
Ben.
Signature · 3 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked.
Quoted 19 lines · Ben Hutchings
Quoted 1 line · Denis Kirjanov
Add initial ethtool statistics support
[...]
Quoted 14 lines
drivers/net/sundance.c +14
-0+static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct net_device_stats *netdev_stats =get_stats (dev); +int i =0 ; + + data[i++] = netdev_stats->tx_packets; + data[i++] = netdev_stats->tx_bytes; + data[i++] = netdev_stats->rx_packets; + data[i++] = netdev_stats->rx_bytes; + data[i++] = netdev_stats->tx_errors; + data[i++] = netdev_stats->tx_dropped; + data[i++] = netdev_stats->rx_errors; +}[...]
Quoted 2 lines
There is no point in adding ethtool stats that merely mirror the baseline net device stats.
Fair enough,
I'll add extra stats shortly
Quoted 2 lines
Ben.
Re: [PATCH net-next] sundance: get_stats proper locking
In reply to Eric DumazetFrom: Eric Dumazet <[email protected]>
Date: Sat, 09 Oct 2010 14:17:01 +0200
Quoted 5 lines · Denis Kirjanov
Quoted 1 line
Add initial ethtool statistics support
OK, I guess its time to add proper locking into sundance after all ;)
Quoted 8 lines
[PATCH net-next] sundance:
get_statsproper lockingsundance
get_stats()should not be run concurrently, add a lock to avoid potential losses.Note: Remove unused
rx_lockfieldSigned-off-by Eric Dumazet <[email protected]>
Applied.
Quoted 19 lines · Ben Hutchings
Quoted 1 line · Denis Kirjanov
Add initial ethtool statistics support
[...]
Quoted 14 lines
(quoted diff) +14
-0+static void get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct net_device_stats *netdev_stats = get_stats(dev); + int i = 0; + + data[i++] = netdev_stats->tx_packets; + data[i++] = netdev_stats->tx_bytes; + data[i++] = netdev_stats->rx_packets; + data[i++] = netdev_stats->rx_bytes; + data[i++] = netdev_stats->tx_errors; + data[i++] = netdev_stats->tx_dropped; + data[i++] = netdev_stats->rx_errors; +}[...]
Quoted 5 lines
There is no point in adding ethtool stats that merely mirror the baseline net device stats.
Ben.
[PATCH -next v2] sundance: Add ethtool stats support
Add ethtool stats support
---
V2:
check for the ETH_SS_STATS in get_string()
use xstats struct for ethtool stats
drivers/net/sundance.c | 90 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 83 insertions(+), 7 deletions(-)
drivers/net/sundance.c +83 -7
@@ -363,6 +363,19 @@ struct netdev_private {dma_addr_t tx_ring_dma;dma_addr_t rx_ring_dma;struct timer_list timer;/* Media monitoring timer. */ +/* ethtool extra stats */ +struct { +unsigned long tx_multiple_collisions; +unsigned long tx_single_collisions; +unsigned long tx_late_collisions; +unsigned long tx_deffered; +unsigned long tx_deffered_excessive; +unsigned long tx_aborted; +unsigned long tx_bcasts; +unsigned long rx_bcasts; +unsigned long tx_mcasts; +unsigned long rx_mcasts; + } xstats;/* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock;int msg_enable;
@@ -1486,7 +1499,6 @@ static struct net_device_stats *get_stats(struct net_device *dev) {struct netdev_private *np =netdev_priv (dev);void __iomem *ioaddr = np->base; -int i;unsigned long flags;spin_lock_irqsave (&np->statlock, flags);
@@ -1494,13 +1506,23 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError); -ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + np->xstats.tx_multiple_collisions +=ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_single_collisions +=ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_late_collisions +=ioread8 (ioaddr + StatsLateColl); + dev->stats.collisions += np->xstats.tx_multiple_collisions + + np->xstats.tx_single_collisions + + np->xstats.tx_late_collisions; + + np->xstats.tx_deffered +=ioread8 (ioaddr + StatsTxDefer); + np->xstats.tx_deffered_excessive +=ioread8 (ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted +=ioread8 (ioaddr + StatsTxAbort); + np->xstats.tx_bcasts +=ioread8 (ioaddr + StatsBcastTx); + np->xstats.rx_bcasts +=ioread8 (ioaddr + StatsBcastRx); + np->xstats.tx_mcasts +=ioread8 (ioaddr + StatsMcastTx); + np->xstats.rx_mcasts +=ioread8 (ioaddr + StatsMcastRx); + dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsLow); dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsHigh) <<16 ; dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsLow);
@@ -1566,6 +1588,21 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_multiple_collisions" }, + {"tx_single_collisions" }, + {"tx_late_collisions" }, + {"tx_deffered" }, + {"tx_deffered_excessive" }, + {"tx_aborted" }, + {"tx_bcasts" }, + {"rx_bcasts" }, + {"tx_mcasts" }, + {"rx_mcasts" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
@@ -1624,6 +1661,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{ +if (stringset ==ETH_SS_STATS ) +memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct netdev_private *np =netdev_priv (dev); +int i =0 ; + +get_stats (dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_deffered; + data[i++] = np->xstats.tx_deffered_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,
@@ -1633,6 +1706,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Signature · 1 line
1.7.0
Jeff Garzik
Acked-byQuoted 30 lines · Denis Kirjanov
Quoted 19 lines · Ben Hutchings
Quoted 1 line · Denis Kirjanov
Add initial ethtool statistics support
[...]
Quoted 14 lines
(quoted diff) +14
-0+static void get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct net_device_stats *netdev_stats = get_stats(dev); + int i = 0; + + data[i++] = netdev_stats->tx_packets; + data[i++] = netdev_stats->tx_bytes; + data[i++] = netdev_stats->rx_packets; + data[i++] = netdev_stats->rx_bytes; + data[i++] = netdev_stats->tx_errors; + data[i++] = netdev_stats->tx_dropped; + data[i++] = netdev_stats->rx_errors; +}[...]
Quoted 5 lines
There is no point in adding ethtool stats that merely mirror the baseline net device stats.
Ben.
[PATCH -next v2] sundance: Add ethtool stats support
Add ethtool stats support
Quoted 8 lines
Signed-off-by Denis Kirjanov<[email protected]>---
V2:
check for theETH_SS_STATSinget_string()
use xstats struct for ethtool stats
drivers/net/sundance.c| 90 ++++++++++++++++++++++++++++++++++++++++++++----1 files changed, 83 insertions(+), 7 deletions(-)
glad somebody tackled this...
David Miller
maintainerFrom: Denis Kirjanov <[email protected]>
Date: Sat, 09 Oct 2010 23:41:32 +0400
drivers/net/sundance.c struct netdev_private { · line 378
Quoted 13 lines
drivers/net/sundance.c +13
-0+/* ethtool extra stats */ +struct { +unsigned long tx_multiple_collisions; +unsigned long tx_single_collisions; +unsigned long tx_late_collisions; +unsigned long tx_deffered; +unsigned long tx_deffered_excessive; +unsigned long tx_aborted; +unsigned long tx_bcasts; +unsigned long rx_bcasts; +unsigned long tx_mcasts; +unsigned long rx_mcasts; + } xstats;
I think these should be "u64".
Quoted 19 lines · David Miller
From: Denis Kirjanov <[email protected]>
Date: Sat, 09 Oct 2010 23:41:32 +0400Review
Quoted 13 lines
(quoted diff) +13
-0+ /* ethtool extra stats */ + struct { + unsigned long tx_multiple_collisions; + unsigned long tx_single_collisions; + unsigned long tx_late_collisions; + unsigned long tx_deffered; + unsigned long tx_deffered_excessive; + unsigned long tx_aborted; + unsigned long tx_bcasts; + unsigned long rx_bcasts; + unsigned long tx_mcasts; + unsigned long rx_mcasts; + } xstats;I think these should be "u64".
[PATCH -next v3] sundance: Add ethtool stats support Add ethtool stats support
---
V2:
check for the ETH_SS_STATS in get_string()
use xstats struct for ethtool stats
V3:
make counters 64-bits wide
drivers/net/sundance.c | 90 ++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 83 insertions(+), 7 deletions(-)
drivers/net/sundance.c +83 -7
@@ -363,6 +363,19 @@ struct netdev_private {dma_addr_t tx_ring_dma;dma_addr_t rx_ring_dma;struct timer_list timer;/* Media monitoring timer. */ +/* ethtool extra stats */ +struct { +u64 tx_multiple_collisions; +u64 tx_single_collisions; +u64 tx_late_collisions; +u64 tx_deffered; +u64 tx_deffered_excessive; +u64 tx_aborted; +u64 tx_bcasts; +u64 rx_bcasts; +u64 tx_mcasts; +u64 rx_mcasts; + } xstats;/* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock;int msg_enable;
@@ -1486,7 +1499,6 @@ static struct net_device_stats *get_stats(struct net_device *dev) {struct netdev_private *np =netdev_priv (dev);void __iomem *ioaddr = np->base; -int i;unsigned long flags;spin_lock_irqsave (&np->statlock, flags);
@@ -1494,13 +1506,23 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError); -ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + np->xstats.tx_multiple_collisions +=ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_single_collisions +=ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_late_collisions +=ioread8 (ioaddr + StatsLateColl); + dev->stats.collisions += np->xstats.tx_multiple_collisions + + np->xstats.tx_single_collisions + + np->xstats.tx_late_collisions; + + np->xstats.tx_deffered +=ioread8 (ioaddr + StatsTxDefer); + np->xstats.tx_deffered_excessive +=ioread8 (ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted +=ioread8 (ioaddr + StatsTxAbort); + np->xstats.tx_bcasts +=ioread8 (ioaddr + StatsBcastTx); + np->xstats.rx_bcasts +=ioread8 (ioaddr + StatsBcastRx); + np->xstats.tx_mcasts +=ioread8 (ioaddr + StatsMcastTx); + np->xstats.rx_mcasts +=ioread8 (ioaddr + StatsMcastRx); + dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsLow); dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsHigh) <<16 ; dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsLow);
@@ -1566,6 +1588,21 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_multiple_collisions" }, + {"tx_single_collisions" }, + {"tx_late_collisions" }, + {"tx_deffered" }, + {"tx_deffered_excessive" }, + {"tx_aborted" }, + {"tx_bcasts" }, + {"rx_bcasts" }, + {"tx_mcasts" }, + {"rx_mcasts" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
@@ -1624,6 +1661,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{ +if (stringset ==ETH_SS_STATS ) +memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct netdev_private *np =netdev_priv (dev); +int i =0 ; + +get_stats (dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_deffered; + data[i++] = np->xstats.tx_deffered_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,
@@ -1633,6 +1706,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Signature · 1 line
1.7.0
drivers/net/sundance.c
Quoted 1 line · Denis Kirjanov
drivers/net/sundance.c +0
-0
Hi Denis.
Just a few trivial misspellings of deffered -> deferred
Quoted 4 lines
index 4283cc5..159f7e7 100644
drivers/net/sundance.c struct netdev_private { · line 372
Quoted 10 lines
drivers/net/sundance.c +7
-0@@ -363,6 +363,19 @@ struct netdev_private {dma_addr_t tx_ring_dma;dma_addr_t rx_ring_dma;struct timer_list timer;/* Media monitoring timer. */ +/* ethtool extra stats */ +struct { +u64 tx_multiple_collisions; +u64 tx_single_collisions; +u64 tx_late_collisions; +u64 tx_deffered; +u64 tx_deffered_excessive;
1
drivers/net/sundance.c static struct net_device_stats *get_stats(struct net_device *dev) · line 1519
Quoted 2 lines
drivers/net/sundance.c +2
-0+ np->xstats.tx_deffered +=ioread8 (ioaddr + StatsTxDefer); + np->xstats.tx_deffered_excessive +=ioread8 (ioaddr + StatsTxXSDefer);
2
drivers/net/sundance.c static int __set_mac_addr(struct net_device *dev) · line 1598
Quoted 8 lines
drivers/net/sundance.c +8
-0+static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_multiple_collisions" }, + {"tx_single_collisions" }, + {"tx_late_collisions" }, + {"tx_deffered" }, + {"tx_deffered_excessive" },
3
drivers/net/sundance.c static void set_msglevel(struct net_device *dev, u32 val) · line 1692
Quoted 2 lines
drivers/net/sundance.c +2
-0+ data[i++] = np->xstats.tx_deffered; + data[i++] = np->xstats.tx_deffered_excessive;
4
Quoted 7 lines · Joe Perches
drivers/net/sundance.c
Quoted 1 line · Denis Kirjanov
drivers/net/sundance.c +0
-0Hi Denis.
Just a few trivial misspellings of deffered -> deferred
Hi Joe,
thanks for pointing that out.
[PATCH -next v4] sundance: Add ethtool stats support
Add ethtool stats support
---
V2:
check for the ETH_SS_STATS in get_string()
use xstats struct for ethtool stats
V3:
make counters 64-bits wide
V4:
fixed some misspellings
drivers/net/sundance.c | 90 ++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 83 insertions(+), 7 deletions(-)
drivers/net/sundance.c +83 -7
@@ -363,6 +363,19 @@ struct netdev_private {dma_addr_t tx_ring_dma;dma_addr_t rx_ring_dma;struct timer_list timer;/* Media monitoring timer. */ +/* ethtool extra stats */ +struct { +u64 tx_multiple_collisions; +u64 tx_single_collisions; +u64 tx_late_collisions; +u64 tx_defered; +u64 tx_defered_excessive; +u64 tx_aborted; +u64 tx_bcasts; +u64 rx_bcasts; +u64 tx_mcasts; +u64 rx_mcasts; + } xstats;/* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock;int msg_enable;
@@ -1486,7 +1499,6 @@ static struct net_device_stats *get_stats(struct net_device *dev) {struct netdev_private *np =netdev_priv (dev);void __iomem *ioaddr = np->base; -int i;unsigned long flags;spin_lock_irqsave (&np->statlock, flags);
@@ -1494,13 +1506,23 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError); -ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + np->xstats.tx_multiple_collisions +=ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_single_collisions +=ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_late_collisions +=ioread8 (ioaddr + StatsLateColl); + dev->stats.collisions += np->xstats.tx_multiple_collisions + + np->xstats.tx_single_collisions + + np->xstats.tx_late_collisions; + + np->xstats.tx_defered +=ioread8 (ioaddr + StatsTxDefer); + np->xstats.tx_defered_excessive +=ioread8 (ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted +=ioread8 (ioaddr + StatsTxAbort); + np->xstats.tx_bcasts +=ioread8 (ioaddr + StatsBcastTx); + np->xstats.rx_bcasts +=ioread8 (ioaddr + StatsBcastRx); + np->xstats.tx_mcasts +=ioread8 (ioaddr + StatsMcastTx); + np->xstats.rx_mcasts +=ioread8 (ioaddr + StatsMcastRx); + dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsLow); dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsHigh) <<16 ; dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsLow);
@@ -1566,6 +1588,21 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_multiple_collisions" }, + {"tx_single_collisions" }, + {"tx_late_collisions" }, + {"tx_defered" }, + {"tx_defered_excessive" }, + {"tx_aborted" }, + {"tx_bcasts" }, + {"rx_bcasts" }, + {"tx_mcasts" }, + {"rx_mcasts" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
@@ -1624,6 +1661,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{ +if (stringset ==ETH_SS_STATS ) +memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct netdev_private *np =netdev_priv (dev); +int i =0 ; + +get_stats (dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_defered; + data[i++] = np->xstats.tx_defered_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,
@@ -1633,6 +1706,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Signature · 1 line
1.7.0
Quoted 8 lines · Denis Kirjanov
drivers/net/sundance.c +0
-3@@ -1494,13 +1506,23 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError);
drivers/net/sundance.c static struct net_device_stats *get_stats(struct net_device *dev) · line 1516
Quoted 10 lines
drivers/net/sundance.c +7
-3-ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + np->xstats.tx_multiple_collisions +=ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_single_collisions +=ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_late_collisions +=ioread8 (ioaddr + StatsLateColl); + dev->stats.collisions += np->xstats.tx_multiple_collisions + + np->xstats.tx_single_collisions + + np->xstats.tx_late_collisions;
Oh well..., really ?
Each time we are calling get_stats(), you do
dev->stats.collisions += (number of accumulated collisions since device is up)
instead of
dev->stats.collisions += (number of accumulated collisions since last time we read counters)
Can you see the problem ?
Quoted 29 lines · Eric Dumazet
Quoted 8 lines · Denis Kirjanov
drivers/net/sundance.c +0
-3@@ -1494,13 +1506,23 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError);drivers/net/sundance.c static struct net_device_stats *get_stats(struct net_device *dev) · line 1516
Quoted 10 lines
drivers/net/sundance.c +7
-3-ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + np->xstats.tx_multiple_collisions +=ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_single_collisions +=ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_late_collisions +=ioread8 (ioaddr + StatsLateColl); + dev->stats.collisions += np->xstats.tx_multiple_collisions + + np->xstats.tx_single_collisions + + np->xstats.tx_late_collisions;Oh well..., really ?
Each time we are calling
get_stats(), you do
dev->stats.collisions+= (number of accumulated collisions since device is up)
Quoted 7 lines
instead of
dev->stats.collisions+= (number of accumulated collisions since last time we read counters)Can you see the problem ?
Oops, thanks Eric!
I'll fix it up and resend
Quoted 2 lines
Quoted 26 lines · Eric Dumazet
Quoted 8 lines · Denis Kirjanov
(quoted diff) +0
-3@@ -1494,13 +1506,23 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK); dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK); - dev->stats.collisions += ioread8(ioaddr + StatsLateColl); - dev->stats.collisions += ioread8(ioaddr + StatsMultiColl); - dev->stats.collisions += ioread8(ioaddr + StatsOneColl); dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);Review static struct net_device_stats *get_stats(struct net_device *dev) · line 1516
Quoted 10 lines
(quoted diff) +7
-3- ioread8(ioaddr + StatsTxDefer); - for (i = StatsTxDefer; i <= StatsMcastRx; i++) - ioread8(ioaddr + i); + + np->xstats.tx_multiple_collisions += ioread8(ioaddr + StatsMultiColl); + np->xstats.tx_single_collisions += ioread8(ioaddr + StatsOneColl); + np->xstats.tx_late_collisions += ioread8(ioaddr + StatsLateColl); + dev->stats.collisions += np->xstats.tx_multiple_collisions + + np->xstats.tx_single_collisions + + np->xstats.tx_late_collisions;Oh well..., really ?
Each time we are calling
get_stats(), you do
Quoted 7 lines
dev->stats.collisions+= (number of accumulated collisions since device is up)instead of
dev->stats.collisions+= (number of accumulated collisions since last time we read counters)
Ok, this is a fixed patch.
Thanks.
Subject: [PATCH -next V5] sundance: Add ethtool stats support
Add ethtool stats support
---
V2:
check for the ETH_SS_STATS in get_string()
use xstats struct for ethtool stats
V3:
make counters 64-bits wide
V4:
fixed some misspellings
V5:
fixed issue with collisions counting
drivers/net/sundance.c | 94 ++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 87 insertions(+), 7 deletions(-)
drivers/net/sundance.c +87 -7
@@ -363,6 +363,19 @@ struct netdev_private {dma_addr_t tx_ring_dma;dma_addr_t rx_ring_dma;struct timer_list timer;/* Media monitoring timer. */ +/* ethtool extra stats */ +struct { +u64 tx_multiple_collisions; +u64 tx_single_collisions; +u64 tx_late_collisions; +u64 tx_defered; +u64 tx_defered_excessive; +u64 tx_aborted; +u64 tx_bcasts; +u64 rx_bcasts; +u64 tx_mcasts; +u64 rx_mcasts; + } xstats;/* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock;int msg_enable;
@@ -1486,21 +1499,34 @@ static struct net_device_stats *get_stats(struct net_device *dev) {struct netdev_private *np =netdev_priv (dev);void __iomem *ioaddr = np->base; -int i;unsigned long flags; +u8 late_coll, single_coll, mult_coll;spin_lock_irqsave (&np->statlock, flags);/* The chip only need report frame silently dropped. */ dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError); -ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + mult_coll =ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_multiple_collisions += mult_coll; + single_coll =ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_single_collisions += single_coll; + late_coll =ioread8 (ioaddr + StatsLateColl); + np->xstats.tx_late_collisions += late_coll; + dev->stats.collisions += mult_coll + + single_coll + + late_coll; + + np->xstats.tx_defered +=ioread8 (ioaddr + StatsTxDefer); + np->xstats.tx_defered_excessive +=ioread8 (ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted +=ioread8 (ioaddr + StatsTxAbort); + np->xstats.tx_bcasts +=ioread8 (ioaddr + StatsBcastTx); + np->xstats.rx_bcasts +=ioread8 (ioaddr + StatsBcastRx); + np->xstats.tx_mcasts +=ioread8 (ioaddr + StatsMcastTx); + np->xstats.rx_mcasts +=ioread8 (ioaddr + StatsMcastRx); + dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsLow); dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsHigh) <<16 ; dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsLow);
@@ -1566,6 +1592,21 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_multiple_collisions" }, + {"tx_single_collisions" }, + {"tx_late_collisions" }, + {"tx_defered" }, + {"tx_defered_excessive" }, + {"tx_aborted" }, + {"tx_bcasts" }, + {"rx_bcasts" }, + {"tx_mcasts" }, + {"rx_mcasts" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
@@ -1624,6 +1665,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{ +if (stringset ==ETH_SS_STATS ) +memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct netdev_private *np =netdev_priv (dev); +int i =0 ; + +get_stats (dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_defered; + data[i++] = np->xstats.tx_defered_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,
@@ -1633,6 +1710,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Signature · 1 line
1.7.0
drivers/net/sundance.c struct netdev_private { · line 372
Quoted 2 lines · Denis Kirjanov
drivers/net/sundance.c +2
-0+u64 tx_defered; +u64 tx_defered_excessive;
Joe said correct english word is "deferred", not "defered"
Quoted 5 lines · Eric Dumazet
Review
Quoted 2 lines · Denis Kirjanov
(quoted diff) +2
-0+ u64 tx_defered; + u64 tx_defered_excessive;
PATCH -next v5] sundance: Add ethtool stats support
Add ethtool stats support.
---
V2:
check for the ETH_SS_STATS in get_string()
use xstats struct for ethtool stats
V3:
make counters 64-bits wide
V4:
fixed some misspellings
V5:
fixed issue with collisions counting
drivers/net/sundance.c | 94 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 87 insertions(+), 7 deletions(-)
drivers/net/sundance.c +87 -7
@@ -363,6 +363,19 @@ struct netdev_private {dma_addr_t tx_ring_dma;dma_addr_t rx_ring_dma;struct timer_list timer;/* Media monitoring timer. */ +/* ethtool extra stats */ +struct { +u64 tx_multiple_collisions; +u64 tx_single_collisions; +u64 tx_late_collisions; +u64 tx_deferred; +u64 tx_deferred_excessive; +u64 tx_aborted; +u64 tx_bcasts; +u64 rx_bcasts; +u64 tx_mcasts; +u64 rx_mcasts; + } xstats;/* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock;int msg_enable;
@@ -1486,21 +1499,34 @@ static struct net_device_stats *get_stats(struct net_device *dev) {struct netdev_private *np =netdev_priv (dev);void __iomem *ioaddr = np->base; -int i;unsigned long flags; +u8 late_coll, single_coll, mult_coll;spin_lock_irqsave (&np->statlock, flags);/* The chip only need report frame silently dropped. */ dev->stats.rx_missed_errors +=ioread8 (ioaddr + RxMissed); dev->stats.tx_packets +=ioread16 (ioaddr + TxFramesOK); dev->stats.rx_packets +=ioread16 (ioaddr + RxFramesOK); - dev->stats.collisions +=ioread8 (ioaddr + StatsLateColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsMultiColl); - dev->stats.collisions +=ioread8 (ioaddr + StatsOneColl); dev->stats.tx_carrier_errors +=ioread8 (ioaddr + StatsCarrierError); -ioread8 (ioaddr + StatsTxDefer); -for (i = StatsTxDefer; i <= StatsMcastRx; i++) -ioread8 (ioaddr + i); + + mult_coll =ioread8 (ioaddr + StatsMultiColl); + np->xstats.tx_multiple_collisions += mult_coll; + single_coll =ioread8 (ioaddr + StatsOneColl); + np->xstats.tx_single_collisions += single_coll; + late_coll =ioread8 (ioaddr + StatsLateColl); + np->xstats.tx_late_collisions += late_coll; + dev->stats.collisions += mult_coll + + single_coll + + late_coll; + + np->xstats.tx_deferred +=ioread8 (ioaddr + StatsTxDefer); + np->xstats.tx_deferred_excessive +=ioread8 (ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted +=ioread8 (ioaddr + StatsTxAbort); + np->xstats.tx_bcasts +=ioread8 (ioaddr + StatsBcastTx); + np->xstats.rx_bcasts +=ioread8 (ioaddr + StatsBcastRx); + np->xstats.tx_mcasts +=ioread8 (ioaddr + StatsMcastTx); + np->xstats.rx_mcasts +=ioread8 (ioaddr + StatsMcastRx); + dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsLow); dev->stats.tx_bytes +=ioread16 (ioaddr + TxOctetsHigh) <<16 ; dev->stats.rx_bytes +=ioread16 (ioaddr + RxOctetsLow);
@@ -1566,6 +1592,21 @@ static int __set_mac_addr(struct net_device *dev)return 0 ; } +static const struct { +const char name[ETH_GSTRING_LEN ]; +} sundance_stats[] = { + {"tx_multiple_collisions" }, + {"tx_single_collisions" }, + {"tx_late_collisions" }, + {"tx_deferred" }, + {"tx_deferred_excessive" }, + {"tx_aborted" }, + {"tx_bcasts" }, + {"rx_bcasts" }, + {"tx_mcasts" }, + {"rx_mcasts" }, +}; +static int check_if_running (struct net_device *dev) {if (!netif_running (dev))
@@ -1624,6 +1665,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings (struct net_device *dev,u32 stringset, +u8 *data) +{ +if (stringset ==ETH_SS_STATS ) +memcpy (data, sundance_stats,sizeof (sundance_stats)); +} + +static int get_sset_count (struct net_device *dev,int sset) +{ +switch (sset) { +case ETH_SS_STATS : +return ARRAY_SIZE (sundance_stats); +default : +return -EOPNOTSUPP ; + } +} + +static void get_ethtool_stats (struct net_device *dev, +struct ethtool_stats *stats,u64 *data) +{ +struct netdev_private *np =netdev_priv (dev); +int i =0 ; + +get_stats (dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_deferred; + data[i++] = np->xstats.tx_deferred_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} +static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo,
@@ -1633,6 +1710,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, };static int netdev_ioctl (struct net_device *dev,struct ifreq *rq,int cmd)
Signature · 1 line
1.7.0
Eric Dumazet
Acked-byQuoted 6 lines · Denis Kirjanov
Quoted 5 lines · Eric Dumazet
Review
Quoted 2 lines · Denis Kirjanov
(quoted diff) +2
-0+ u64 tx_defered; + u64 tx_defered_excessive;
Quoted 6 lines
PATCH -next v5] sundance: Add ethtool stats support
Add ethtool stats support.
Signed-off-by Denis Kirjanov <[email protected]>---