From: Richard Dawe <rich@phekda.gotadsl.co.uk>
To: Francois Romieu <romieu@fr.zoreil.com>, Jon Mason <jdmason@us.ibm.com>
Cc: netdev@oss.sgi.com
Subject: [PATCH]: r8169: Expose hardware stats via ethtool
Date: Sat, 26 Feb 2005 14:53:55 +0000 [thread overview]
Message-ID: <42208D83.80803@phekda.gotadsl.co.uk> (raw)
[-- Attachment #1: Type: text/plain, Size: 1559 bytes --]
Hi Francois and Jon!
Please find attached a patch that adds the hardware statistics ethtool
operations to the r8169 driver. It's against 2.6.11-rc5.
Signed-Off-By: Richard Dawe <rich@phekda.gotadsl.co.uk>
Basically it's a port of the 8139cp stats routines to r8169. In 8139cp
the stats buffer is in the ring buffers' DMA mapping. In this patch for
r8169 it has its own DMA mapping.
One problem: Bogus stats are generated when I insert the module but
don't bring it up. E.g.: if I do this on FC3 (eth0 == r8169):
<--(Using 2.6.11-rc5's r8169 driver here)-->
service network stop
rmmod r8169
insmod /path/to/new/r8169.ko
ethtool -S eth0
I get this:
NIC statistics:
tx_ok: 18446604436244066304
rx_ok: 4096
tx_err: 0
rx_err: 0
rx_fifo: 4
frame_align: 1
tx_ok_1col: 488917820
tx_ok_mcol: 0
rx_ok_phys: 18446604435732824074
rx_ok_bcast: 18446744071565939505
rx_ok_mcast: 0
tx_abort: 18446604435732824064
tx_underrun: 18446604436090647520
If I then bring the interface up ("ifconfig eth0 up"), I get valid stats.
Any suggestions on how to fix this? I tried a couple of things:
* Return in get_ethtool_stats if !netif_running(). Made no difference.
* Zero the stats after creating the DMA mapping with
pci_alloc_consistent(). Made no difference.
I wonder if 8139cp has the same problem?
Thanks, bye, Rich =]
--
Richard Dawe [ http://homepages.nildram.co.uk/~phekda/richdawe/ ]
"You can't evaluate a man by logic alone."
-- McCoy, "I, Mudd", Star Trek
[-- Attachment #2: r8169-ethtool-stats.diff --]
[-- Type: text/plain, Size: 4982 bytes --]
--- linux-2.6.11-rc5/drivers/net/r8169.c.orig 2005-02-24 16:40:30.000000000 +0000
+++ linux-2.6.11-rc5/drivers/net/r8169.c 2005-02-26 14:28:37.000000000 +0000
@@ -128,6 +128,7 @@ static int multicast_filter_limit = 32;
#define RX_BUF_SIZE 1536 /* Rx Buffer size */
#define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
+#define R8169_STATS_BYTES 64
#define RTL8169_TX_TIMEOUT (6*HZ)
#define RTL8169_PHY_TIMEOUT (10*HZ)
@@ -187,6 +188,8 @@ static int use_dac;
enum RTL8169_registers {
MAC0 = 0, /* Ethernet hardware address. */
MAR0 = 8, /* Multicast filter. */
+ StatsAddrLow = 0x10,
+ StatsAddrHigh = 0x14,
TxDescStartAddrLow = 0x20,
TxDescStartAddrHigh = 0x24,
TxHDescStartAddrLow = 0x28,
@@ -255,6 +258,9 @@ enum RTL8169_register_content {
Cfg9346_Lock = 0x00,
Cfg9346_Unlock = 0xC0,
+ /* StatsAddr register */
+ DumpStats = (1 << 3),
+
/* rx_mode_bits */
AcceptErr = 0x20,
AcceptRunt = 0x10,
@@ -380,6 +386,22 @@ struct ring_info {
u8 __pad[sizeof(void *) - sizeof(u32)];
};
+struct rtl8169_stats {
+ u64 tx_ok;
+ u64 rx_ok;
+ u64 tx_err;
+ u32 rx_err;
+ u16 rx_fifo;
+ u16 frame_align;
+ u32 tx_ok_1col;
+ u32 tx_ok_mcol;
+ u64 rx_ok_phys;
+ u64 rx_ok_bcast;
+ u32 rx_ok_mcast;
+ u16 tx_abort;
+ u16 tx_underrun;
+} __attribute__((packed));
+
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
@@ -404,6 +426,8 @@ struct rtl8169_private {
u16 intr_mask;
int phy_auto_nego_reg;
int phy_1000_ctrl_reg;
+ struct rtl8169_stats *nic_stats;
+ dma_addr_t nic_stats_addr;
#ifdef CONFIG_R8169_VLAN
struct vlan_group *vlgrp;
#endif
@@ -871,6 +895,68 @@ static void rtl8169_get_regs(struct net_
spin_unlock_irqrestore(&tp->lock, flags);
}
+static const char rtl8169_gstrings_stats[][ETH_GSTRING_LEN] = {
+ "tx_ok", "rx_ok", "tx_err", "rx_err",
+ "rx_fifo", "frame_align", "tx_ok_1col", "tx_ok_mcol",
+ "rx_ok_phys", "rx_ok_bcast", "rx_ok_mcast", "tx_abort",
+ "tx_underrun",
+};
+#define RTL8169_STATS_LEN sizeof(rtl8169_gstrings_stats) / ETH_GSTRING_LEN
+
+static int rtl8169_get_stats_count(struct net_device *dev)
+{
+ return RTL8169_STATS_LEN;
+}
+
+static void rtl8169_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+{
+ switch(stringset) {
+ case ETH_SS_STATS:
+ memcpy(data, *rtl8169_gstrings_stats, sizeof(rtl8169_gstrings_stats));
+ break;
+ }
+}
+
+static void rtl8169_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct rtl8169_private *tp = netdev_priv(netdev);
+ void __iomem *ioaddr = tp->mmio_addr;
+ int work = 100;
+ int i;
+
+ /* begin NIC statistics dump */
+ RTL_W32(StatsAddrHigh, tp->nic_stats_addr >> 32);
+ RTL_W32(StatsAddrLow, (tp->nic_stats_addr & 0xffffffff) | DumpStats);
+ RTL_R32(StatsAddrLow);
+
+ while (work-- > 0) {
+ if ((RTL_R32(StatsAddrLow) & DumpStats) == 0)
+ break;
+ cpu_relax();
+ }
+
+ if (RTL_R32(StatsAddrLow) & DumpStats)
+ return; /* no stats - took too long */
+
+ i = 0;
+ data[i++] = le64_to_cpu(tp->nic_stats->tx_ok);
+ data[i++] = le64_to_cpu(tp->nic_stats->rx_ok);
+ data[i++] = le64_to_cpu(tp->nic_stats->tx_err);
+ data[i++] = le32_to_cpu(tp->nic_stats->rx_err);
+ data[i++] = le16_to_cpu(tp->nic_stats->rx_fifo);
+ data[i++] = le16_to_cpu(tp->nic_stats->frame_align);
+ data[i++] = le32_to_cpu(tp->nic_stats->tx_ok_1col);
+ data[i++] = le32_to_cpu(tp->nic_stats->tx_ok_mcol);
+ data[i++] = le64_to_cpu(tp->nic_stats->rx_ok_phys);
+ data[i++] = le64_to_cpu(tp->nic_stats->rx_ok_bcast);
+ data[i++] = le32_to_cpu(tp->nic_stats->rx_ok_mcast);
+ data[i++] = le16_to_cpu(tp->nic_stats->tx_abort);
+ data[i++] = le16_to_cpu(tp->nic_stats->tx_underrun);
+ if (i != RTL8169_STATS_LEN)
+ BUG();
+}
+
static struct ethtool_ops rtl8169_ethtool_ops = {
.get_drvinfo = rtl8169_get_drvinfo,
.get_regs_len = rtl8169_get_regs_len,
@@ -886,6 +972,9 @@ static struct ethtool_ops rtl8169_ethtoo
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
.get_regs = rtl8169_get_regs,
+ .get_strings = rtl8169_get_strings,
+ .get_stats_count = rtl8169_get_stats_count,
+ .get_ethtool_stats = rtl8169_get_ethtool_stats,
};
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1531,6 +1620,11 @@ static int rtl8169_open(struct net_devic
if (retval < 0)
goto err_free_rx;
+ tp->nic_stats = pci_alloc_consistent(pdev, R8169_STATS_BYTES,
+ &tp->nic_stats_addr);
+ if (!tp->nic_stats)
+ goto err_free_nic_stats;
+
INIT_WORK(&tp->task, NULL, dev);
rtl8169_hw_start(dev);
@@ -1541,6 +1635,10 @@ static int rtl8169_open(struct net_devic
out:
return retval;
+err_free_nic_stats:
+ pci_free_consistent(pdev, R8169_STATS_BYTES, tp->nic_stats,
+ tp->nic_stats_addr);
+
err_free_rx:
pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
tp->RxPhyAddr);
next reply other threads:[~2005-02-26 14:53 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-26 14:53 Richard Dawe [this message]
2005-02-26 15:57 ` [PATCH]: r8169: Expose hardware stats via ethtool Jeff Garzik
2005-02-27 22:46 ` Richard Dawe
2005-02-26 17:32 ` Jon Mason
2005-02-26 18:02 ` Jeff Garzik
2005-02-26 18:03 ` Jeff Garzik
2005-02-26 18:12 ` Francois Romieu
2005-02-27 22:53 ` Richard Dawe
2005-02-27 22:59 ` Jeff Garzik
2005-02-28 2:31 ` Jon Mason
2005-02-28 2:58 ` Jeff Garzik
2005-02-28 4:16 ` Ben Greear
2005-03-05 13:53 ` Richard Dawe
2005-02-26 18:36 ` Jon Mason
2005-02-26 18:26 ` Francois Romieu
2005-02-27 22:44 ` Richard Dawe
2005-02-27 19:28 ` Jon Mason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42208D83.80803@phekda.gotadsl.co.uk \
--to=rich@phekda.gotadsl.co.uk \
--cc=jdmason@us.ibm.com \
--cc=netdev@oss.sgi.com \
--cc=romieu@fr.zoreil.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).