ixgbe patch to provide NIC's tx/rx counters via ethtool
authorBen Greear <greearb@candelatech.com>
Wed, 30 Sep 2009 12:08:16 +0000 (12:08 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 1 Oct 2009 03:02:59 +0000 (20:02 -0700)
When LRO is enabled, the received packet and byte counters represent the
LRO'd packets, not the packets/bytes on the wire.  The Intel 82599 NIC has
registers that keep count of the physical packets.  Add these counters to
the ethtool stats.  The byte counters are 36-bit, but the high 4 bits were
being ignored in the 2.6.31 ixgbe driver:  Read those as well to allow
longer time between polling the stats to detect wraps.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_main.c

index 53b0a6680254fdbd816692f0a88e1616f312a7aa..fa314cb005a4dcf15ce8884c0da5e9987f1e2604 100644 (file)
@@ -53,6 +53,10 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
        {"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)},
        {"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)},
+       {"rx_pkts_nic", IXGBE_STAT(stats.gprc)},
+       {"tx_pkts_nic", IXGBE_STAT(stats.gptc)},
+       {"rx_bytes_nic", IXGBE_STAT(stats.gorc)},
+       {"tx_bytes_nic", IXGBE_STAT(stats.gotc)},
        {"lsc_int", IXGBE_STAT(lsc_int)},
        {"tx_busy", IXGBE_STAT(tx_busy)},
        {"non_eop_descs", IXGBE_STAT(non_eop_descs)},
index c19818303629a04ba8c6144053ba9caf71d7aebd..9609673992094982c4369aa7c6358d3172520098 100644 (file)
@@ -4449,10 +4449,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 
        /* 82598 hardware only has a 32 bit counter in the high register */
        if (hw->mac.type == ixgbe_mac_82599EB) {
+               u64 tmp;
                adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
-               IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
+               tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */
+               adapter->stats.gorc += (tmp << 32);
                adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
-               IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
+               tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */
+               adapter->stats.gotc += (tmp << 32);
                adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
                IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
                adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);