+ forcedeth-config-statistics.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     forcedeth config: statistics

has been added to the -mm tree.  Its filename is

     forcedeth-config-statistics.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: forcedeth config: statistics
From: Ayaz Abdulla <aabdulla@xxxxxxxxxx>


This patch exposes statistic counters through ethtool support.

Signed-off-by: Ayaz Abdulla <aabdulla@xxxxxxxxxx>
Cc: Manfred Spraul <manfred@xxxxxxxxxxxxxxxx>
Cc: Jeff Garzik <jeff@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 drivers/net/forcedeth.c |  210 +++++++++++++++++++++++++++++++++++++-
 1 files changed, 207 insertions(+), 3 deletions(-)

diff -puN drivers/net/forcedeth.c~forcedeth-config-statistics drivers/net/forcedeth.c
--- 25/drivers/net/forcedeth.c~forcedeth-config-statistics	Fri Jun  2 15:58:04 2006
+++ 25-akpm/drivers/net/forcedeth.c	Fri Jun  2 15:58:04 2006
@@ -165,6 +165,7 @@
 #define DEV_HAS_MSI_X           0x0080  /* device supports MSI-X */
 #define DEV_HAS_POWER_CNTRL     0x0100  /* device supports power savings */
 #define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
+#define DEV_HAS_STATISTICS      0x0400  /* device supports hw statistics */
 
 enum {
 	NvRegIrqStatus = 0x000,
@@ -333,6 +334,33 @@ enum {
 #define NVREG_POWERSTATE_D1		0x0001
 #define NVREG_POWERSTATE_D2		0x0002
 #define NVREG_POWERSTATE_D3		0x0003
+	NvRegTxCnt = 0x280,
+	NvRegTxZeroReXmt = 0x284,
+	NvRegTxOneReXmt = 0x288,
+	NvRegTxManyReXmt = 0x28c,
+	NvRegTxLateCol = 0x290,
+	NvRegTxUnderflow = 0x294,
+	NvRegTxLossCarrier = 0x298,
+	NvRegTxExcessDef = 0x29c,
+	NvRegTxRetryErr = 0x2a0,
+	NvRegRxFrameErr = 0x2a4,
+	NvRegRxExtraByte = 0x2a8,
+	NvRegRxLateCol = 0x2ac,
+	NvRegRxRunt = 0x2b0,
+	NvRegRxFrameTooLong = 0x2b4,
+	NvRegRxOverflow = 0x2b8,
+	NvRegRxFCSErr = 0x2bc,
+	NvRegRxFrameAlignErr = 0x2c0,
+	NvRegRxLenErr = 0x2c4,
+	NvRegRxUnicast = 0x2c8,
+	NvRegRxMulticast = 0x2cc,
+	NvRegRxBroadcast = 0x2d0,
+	NvRegTxDef = 0x2d4,
+	NvRegTxFrame = 0x2d8,
+	NvRegRxCnt = 0x2dc,
+	NvRegTxPause = 0x2e0,
+	NvRegRxPause = 0x2e4,
+	NvRegRxDropFrame = 0x2e8,
 	NvRegVlanControl = 0x300,
 #define NVREG_VLANCONTROL_ENABLE	0x2000
 	NvRegMSIXMap0 = 0x3e0,
@@ -481,6 +509,7 @@ typedef union _ring_type {
 #define OOM_REFILL	(1+HZ/20)
 #define POLL_WAIT	(1+HZ/100)
 #define LINK_TIMEOUT	(3*HZ)
+#define STATS_INTERVAL	(10*HZ)
 
 /*
  * desc_ver values:
@@ -535,6 +564,82 @@ typedef union _ring_type {
 #define NV_MSI_X_VECTOR_RX    0x0
 #define NV_MSI_X_VECTOR_TX    0x1
 #define NV_MSI_X_VECTOR_OTHER 0x2
+/* statistics */
+#define NV_STATS_COUNT_SW 10
+
+struct nv_ethtool_str {
+	char name[ETH_GSTRING_LEN];
+};
+
+static const struct nv_ethtool_str nv_estats_str[] = {
+	{ "tx_dropped" },
+	{ "tx_fifo_errors" },
+	{ "tx_carrier_errors" },
+	{ "tx_packets" },
+	{ "tx_bytes" },
+	{ "rx_crc_errors" },
+	{ "rx_over_errors" },
+	{ "rx_errors_total" },
+	{ "rx_packets" },
+	{ "rx_bytes" },
+
+	/* hardware counters */
+	{ "tx_zero_rexmt" },
+	{ "tx_one_rexmt" },
+	{ "tx_many_rexmt" },
+	{ "tx_late_collision" },
+	{ "tx_excess_deferral" },
+	{ "tx_retry_error" },
+	{ "rx_frame_error" },
+	{ "rx_extra_byte" },
+	{ "rx_late_collision" },
+	{ "rx_runt" },
+	{ "rx_frame_too_long" },
+	{ "rx_frame_align_error" },
+	{ "rx_length_error" },
+	{ "rx_unicast" },
+	{ "rx_multicast" },
+	{ "rx_broadcast" },
+	{ "tx_deferral" },
+	{ "tx_pause" },
+	{ "rx_pause" },
+	{ "rx_drop_frame" }
+};
+
+struct nv_ethtool_stats {
+	u64 tx_dropped;
+	u64 tx_fifo_errors;
+	u64 tx_carrier_errors;
+	u64 tx_packets;
+	u64 tx_bytes;
+	u64 rx_crc_errors;
+	u64 rx_over_errors;
+	u64 rx_errors_total;
+	u64 rx_packets;
+	u64 rx_bytes;
+
+	/* hardware counters */
+	u64 tx_zero_rexmt;
+	u64 tx_one_rexmt;
+	u64 tx_many_rexmt;
+	u64 tx_late_collision;
+	u64 tx_excess_deferral;
+	u64 tx_retry_error;
+	u64 rx_frame_error;
+	u64 rx_extra_byte;
+	u64 rx_late_collision;
+	u64 rx_runt;
+	u64 rx_frame_too_long;
+	u64 rx_frame_align_error;
+	u64 rx_length_error;
+	u64 rx_unicast;
+	u64 rx_multicast;
+	u64 rx_broadcast;
+	u64 tx_deferral;
+	u64 tx_pause;
+	u64 rx_pause;
+	u64 rx_drop_frame;
+};
 
 /*
  * SMP locking:
@@ -554,6 +659,7 @@ struct fe_priv {
 	/* General data:
 	 * Locking: spin_lock(&np->lock); */
 	struct net_device_stats stats;
+	struct nv_ethtool_stats estats;
 	int in_shutdown;
 	u32 linkspeed;
 	int duplex;
@@ -588,6 +694,7 @@ struct fe_priv {
 	unsigned int pkt_limit;
 	struct timer_list oom_kick;
 	struct timer_list nic_poll;
+	struct timer_list stats_poll;
 	u32 nic_poll_irq;
 	int rx_ring_size;
 
@@ -2471,6 +2578,63 @@ static void nv_poll_controller(struct ne
 }
 #endif
 
+static void nv_do_stats_poll(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct fe_priv *np = netdev_priv(dev);
+	u8 __iomem *base = get_hwbase(dev);
+
+	spin_lock_irq(&np->lock);
+
+	np->estats.tx_dropped = np->stats.tx_dropped;
+	np->estats.rx_errors_total = np->stats.rx_errors;
+	np->estats.rx_packets = np->stats.rx_packets;
+	if (np->driver_data & DEV_HAS_STATISTICS) {
+		np->estats.tx_packets += readl(base + NvRegTxFrame);
+		np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow);
+		np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier);
+		np->estats.tx_bytes += readl(base + NvRegTxCnt);
+		np->estats.rx_bytes += readl(base + NvRegRxCnt);
+		np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr);
+		np->estats.rx_over_errors += readl(base + NvRegRxOverflow);
+	} else {
+		np->estats.tx_packets = np->stats.tx_packets;
+		np->estats.tx_fifo_errors = np->stats.tx_fifo_errors;
+		np->estats.tx_carrier_errors = np->stats.tx_carrier_errors;
+		np->estats.tx_bytes = np->stats.tx_bytes;
+		np->estats.rx_bytes = np->stats.rx_bytes;
+		np->estats.rx_crc_errors = np->stats.rx_crc_errors;
+		np->estats.rx_over_errors = np->stats.rx_over_errors;
+	}
+
+	if (np->driver_data & DEV_HAS_STATISTICS) {
+		np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt);
+		np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt);
+		np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt);
+		np->estats.tx_late_collision += readl(base + NvRegTxLateCol);
+		np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef);
+		np->estats.tx_retry_error += readl(base + NvRegTxRetryErr);
+		np->estats.rx_frame_error += readl(base + NvRegRxFrameErr);
+		np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte);
+		np->estats.rx_late_collision += readl(base + NvRegRxLateCol);
+		np->estats.rx_runt += readl(base + NvRegRxRunt);
+		np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong);
+		np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr);
+		np->estats.rx_length_error += readl(base + NvRegRxLenErr);
+		np->estats.rx_unicast += readl(base + NvRegRxUnicast);
+		np->estats.rx_multicast += readl(base + NvRegRxMulticast);
+		np->estats.rx_broadcast += readl(base + NvRegRxBroadcast);
+		np->estats.tx_deferral += readl(base + NvRegTxDef);
+		np->estats.tx_pause += readl(base + NvRegTxPause);
+		np->estats.rx_pause += readl(base + NvRegRxPause);
+		np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame);
+	}
+
+	if (!np->in_shutdown)
+		mod_timer(&np->stats_poll, jiffies + STATS_INTERVAL);
+	spin_unlock_irq(&np->lock);
+}
+
 static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	struct fe_priv *np = netdev_priv(dev);
@@ -3103,6 +3267,35 @@ static int nv_set_tso(struct net_device 
 }
 #endif
 
+static int nv_get_stats_count(struct net_device *dev)
+{
+	struct fe_priv *np = netdev_priv(dev);
+
+	if (np->driver_data & DEV_HAS_STATISTICS)
+		return (sizeof(struct nv_ethtool_stats)/sizeof(u64));
+	else
+		return NV_STATS_COUNT_SW;
+}
+
+static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *buffer)
+{
+	struct fe_priv *np = netdev_priv(dev);
+
+	/* update stats */
+	nv_do_stats_poll((unsigned long)dev);
+
+	memcpy(buffer, &np->estats, nv_get_stats_count(dev)*sizeof(u64));
+}
+
+static void nv_get_strings(struct net_device *dev, u32 stringset, u8 *buffer)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(buffer, &nv_estats_str, nv_get_stats_count(dev)*sizeof(struct nv_ethtool_str));
+		break;
+	}
+}
+
 static struct ethtool_ops ops = {
 	.get_drvinfo = nv_get_drvinfo,
 	.get_link = ethtool_op_get_link,
@@ -3132,6 +3325,9 @@ static struct ethtool_ops ops = {
 	.get_tso = ethtool_op_get_tso,
 	.set_tso = nv_set_tso,
 #endif
+	.get_strings = nv_get_strings,
+	.get_stats_count = nv_get_stats_count,
+	.get_ethtool_stats = nv_get_ethtool_stats,
 };
 
 static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
@@ -3434,6 +3630,10 @@ static int nv_open(struct net_device *de
 	}
 	if (oom)
 		mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
+
+	/* start statistics timer */
+	mod_timer(&np->stats_poll, jiffies + STATS_INTERVAL);
+
 	spin_unlock_irq(&np->lock);
 
 	return 0;
@@ -3454,6 +3654,7 @@ static int nv_close(struct net_device *d
 
 	del_timer_sync(&np->oom_kick);
 	del_timer_sync(&np->nic_poll);
+	del_timer_sync(&np->stats_poll);
 
 	netif_stop_queue(dev);
 	spin_lock_irq(&np->lock);
@@ -3513,6 +3714,9 @@ static int __devinit nv_probe(struct pci
 	init_timer(&np->nic_poll);
 	np->nic_poll.data = (unsigned long) dev;
 	np->nic_poll.function = &nv_do_nic_poll;	/* timer handler */
+	init_timer(&np->stats_poll);
+	np->stats_poll.data = (unsigned long) dev;
+	np->stats_poll.function = &nv_do_stats_poll;	/* timer handler */
 
 	err = pci_enable_device(pci_dev);
 	if (err) {
@@ -3527,7 +3731,7 @@ static int __devinit nv_probe(struct pci
 	if (err < 0)
 		goto out_disable;
 
-	if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL))
+	if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS))
 		np->register_size = NV_PCI_REGSZ_VER2;
 	else
 		np->register_size = NV_PCI_REGSZ_VER1;
@@ -3883,11 +4087,11 @@ static struct pci_device_id pci_tbl[] = 
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS,
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS,
 	},
 	{0,},
 };
_

Patches currently in -mm which might be from aabdulla@xxxxxxxxxx are

implement-get--set-tso-for-forcedeth-driver.patch
git-netdev-all.patch
forcedeth-config-ring-sizes.patch
forcedeth-config-flow-control.patch
forcedeth-config-phy.patch
forcedeth-config-wol.patch
forcedeth-config-csum.patch
forcedeth-config-tso.patch
forcedeth-config-statistics.patch
forcedeth-config-diagnostics.patch
forcedeth-config-module-parameters.patch
forcedeth-config-version.patch
forcedeth-new-device-ids.patch
lock-validator-forcedethc-fix.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux