[PATCH] b44: expose counters through ethtool
authorFrancois Romieu <romieu@fr.zoreil.com>
Mon, 7 Nov 2005 00:51:34 +0000 (01:51 +0100)
committerJeff Garzik <jgarzik@pobox.com>
Mon, 7 Nov 2005 08:37:05 +0000 (03:37 -0500)
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
drivers/net/b44.c
drivers/net/b44.h

index 3b6428f..ac223fc 100644 (file)
@@ -106,6 +106,12 @@ static void b44_init_hw(struct b44 *);
 static int dma_desc_align_mask;
 static int dma_desc_sync_size;
 
+static const char b44_gstrings[][ETH_GSTRING_LEN] = {
+#define _B44(x...)     # x,
+B44_STAT_REG_DECLARE
+#undef _B44
+};
+
 static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
                                                 dma_addr_t dma_base,
                                                 unsigned long offset,
@@ -498,7 +504,10 @@ static void b44_stats_update(struct b44 *bp)
        for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
                *val++ += br32(bp, reg);
        }
-       val = &bp->hw_stats.rx_good_octets;
+
+       /* Pad */
+       reg += 8*4UL;
+
        for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
                *val++ += br32(bp, reg);
        }
@@ -1772,6 +1781,37 @@ static int b44_set_pauseparam(struct net_device *dev,
        return 0;
 }
 
+static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+       switch(stringset) {
+       case ETH_SS_STATS:
+               memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
+               break;
+       }
+}
+
+static int b44_get_stats_count(struct net_device *dev)
+{
+       return ARRAY_SIZE(b44_gstrings);
+}
+
+static void b44_get_ethtool_stats(struct net_device *dev,
+                                 struct ethtool_stats *stats, u64 *data)
+{
+       struct b44 *bp = netdev_priv(dev);
+       u32 *val = &bp->hw_stats.tx_good_octets;
+       u32 i;
+
+       spin_lock_irq(&bp->lock);
+
+       b44_stats_update(bp);
+
+       for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
+               *data++ = *val++;
+
+       spin_unlock_irq(&bp->lock);
+}
+
 static struct ethtool_ops b44_ethtool_ops = {
        .get_drvinfo            = b44_get_drvinfo,
        .get_settings           = b44_get_settings,
@@ -1784,6 +1824,9 @@ static struct ethtool_ops b44_ethtool_ops = {
        .set_pauseparam         = b44_set_pauseparam,
        .get_msglevel           = b44_get_msglevel,
        .set_msglevel           = b44_set_msglevel,
+       .get_strings            = b44_get_strings,
+       .get_stats_count        = b44_get_stats_count,
+       .get_ethtool_stats      = b44_get_ethtool_stats,
        .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
index 593cb0a..7afeaf6 100644 (file)
@@ -346,29 +346,63 @@ struct ring_info {
 
 #define B44_MCAST_TABLE_SIZE   32
 
+#define        B44_STAT_REG_DECLARE            \
+       _B44(tx_good_octets)            \
+       _B44(tx_good_pkts)              \
+       _B44(tx_octets)                 \
+       _B44(tx_pkts)                   \
+       _B44(tx_broadcast_pkts)         \
+       _B44(tx_multicast_pkts)         \
+       _B44(tx_len_64)                 \
+       _B44(tx_len_65_to_127)          \
+       _B44(tx_len_128_to_255)         \
+       _B44(tx_len_256_to_511)         \
+       _B44(tx_len_512_to_1023)        \
+       _B44(tx_len_1024_to_max)        \
+       _B44(tx_jabber_pkts)            \
+       _B44(tx_oversize_pkts)          \
+       _B44(tx_fragment_pkts)          \
+       _B44(tx_underruns)              \
+       _B44(tx_total_cols)             \
+       _B44(tx_single_cols)            \
+       _B44(tx_multiple_cols)          \
+       _B44(tx_excessive_cols)         \
+       _B44(tx_late_cols)              \
+       _B44(tx_defered)                \
+       _B44(tx_carrier_lost)           \
+       _B44(tx_pause_pkts)             \
+       _B44(rx_good_octets)            \
+       _B44(rx_good_pkts)              \
+       _B44(rx_octets)                 \
+       _B44(rx_pkts)                   \
+       _B44(rx_broadcast_pkts)         \
+       _B44(rx_multicast_pkts)         \
+       _B44(rx_len_64)                 \
+       _B44(rx_len_65_to_127)          \
+       _B44(rx_len_128_to_255)         \
+       _B44(rx_len_256_to_511)         \
+       _B44(rx_len_512_to_1023)        \
+       _B44(rx_len_1024_to_max)        \
+       _B44(rx_jabber_pkts)            \
+       _B44(rx_oversize_pkts)          \
+       _B44(rx_fragment_pkts)          \
+       _B44(rx_missed_pkts)            \
+       _B44(rx_crc_align_errs)         \
+       _B44(rx_undersize)              \
+       _B44(rx_crc_errs)               \
+       _B44(rx_align_errs)             \
+       _B44(rx_symbol_errs)            \
+       _B44(rx_pause_pkts)             \
+       _B44(rx_nonpause_pkts)
+
 /* SW copy of device statistics, kept up to date by periodic timer
- * which probes HW values.  Must have same relative layout as HW
- * register above, because b44_stats_update depends upon this.
+ * which probes HW values. Check b44_stats_update if you mess with
+ * the layout
  */
 struct b44_hw_stats {
-       u32 tx_good_octets, tx_good_pkts, tx_octets;
-       u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts;
-       u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255;
-       u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
-       u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
-       u32 tx_underruns, tx_total_cols, tx_single_cols;
-       u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
-       u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
-       u32 __pad1[8];
-
-       u32 rx_good_octets, rx_good_pkts, rx_octets;
-       u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
-       u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
-       u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
-       u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
-       u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
-       u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
-       u32 rx_pause_pkts, rx_nonpause_pkts;
+#define _B44(x)        u32 x;
+B44_STAT_REG_DECLARE
+#undef _B44
 };
 
 struct b44 {