# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/02/19 19:17:14-05:00 jeffpc@optonline.net 
#   64network related clean up of net/code/dev.c
# 
# net/core/dev.c
#   2004/02/19 19:17:05-05:00 jeffpc@optonline.net +10 -16
#   Clean up, to minimize the size of the patch from vanilla
# 
# ChangeSet
#   2004/02/19 16:24:37-05:00 jeffpc@optonline.net 
#   [NET] Make /proc/net/dev native and /proc/net/dev64 64-bit
# 
# net/core/dev.c
#   2004/02/19 16:24:28-05:00 jeffpc@optonline.net +78 -6
#   Make /proc/net/dev native and /proc/net/dev64 64-bit
# 
# ChangeSet
#   2004/02/19 13:35:43-05:00 jeffpc@optonline.net 
#   Merge optonline.net:/home/jeffpc/linux/linux-watch64
#   into optonline.net:/home/jeffpc/linux/linux-64network
# 
# net/core/net-sysfs.c
#   2004/02/19 13:35:32-05:00 jeffpc@optonline.net +0 -0
#   Auto merged
# 
# net/core/dev.c
#   2004/02/19 13:35:32-05:00 jeffpc@optonline.net +0 -0
#   Auto merged
# 
# include/linux/netdevice.h
#   2004/02/19 13:35:31-05:00 jeffpc@optonline.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/01/09 06:47:00-05:00 jeffpc@jeff.home 
#   Merge jeff.home:/home/jeffpc/linux/linux-watch64
#   into jeff.home:/home/jeffpc/linux/linux-64network
# 
# include/linux/netdevice.h
#   2004/01/09 06:46:56-05:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/01/03 23:11:07-05:00 jeffpc@jeff.home 
#   Merge jeff.home:/home/jeffpc/linux/linux-watch64
#   into jeff.home:/home/jeffpc/linux/linux-64network
# 
# net/core/dev.c
#   2004/01/03 23:11:02-05:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# ChangeSet
#   2003/12/28 22:35:24-05:00 jeffpc@optonline.net 
#   Manual Merge
# 
# include/linux/netdevice.h
#   2003/12/28 22:35:18-05:00 jeffpc@optonline.net +1 -0
#   Extra space
# 
# net/core/net-sysfs.c
#   2003/12/28 22:31:34-05:00 jeffpc@optonline.net +0 -0
#   Auto merged
# 
# net/core/dev.c
#   2003/12/28 22:31:34-05:00 jeffpc@optonline.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2003/10/16 22:43:47-04:00 jeffpc@jeff.home 
#   Merge jeff.home:/home/jeffpc/linux/linux-watch64
#   into jeff.home:/home/jeffpc/linux/linux-64network
# 
# net/core/dev.c
#   2003/10/16 22:43:42-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# include/linux/netdevice.h
#   2003/10/16 22:43:42-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# ChangeSet
#   2003/10/03 21:13:10-04:00 jeffpc@jeff.home 
#   Merge jeff.home:/home/jeffpc/linux/linux-watch64
#   into jeff.home:/home/jeffpc/linux/linux-64network
# 
# net/core/dev.c
#   2003/10/03 21:13:05-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# ChangeSet
#   2003/09/27 23:00:40-04:00 jeffpc@jeff.home 
#   Merge jeff.home:/home/jeffpc/linux/linux-watch64
#   into jeff.home:/home/jeffpc/linux/linux-64network
# 
# net/core/net-sysfs.c
#   2003/09/27 23:00:27-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# net/core/dev.c
#   2003/09/27 23:00:27-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# include/linux/netdevice.h
#   2003/09/27 23:00:26-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# ChangeSet
#   2003/09/25 22:52:20-04:00 jeffpc@jeff.home 
#   #include is a good thing (tm)
# 
# net/core/net-sysfs.c
#   2003/09/25 22:52:13-04:00 jeffpc@jeff.home +1 -0
#   #include is a good thing (tm)
# 
# ChangeSet
#   2003/09/25 22:40:03-04:00 jeffpc@jeff.home 
#   FIX: need to return a pointer not the value itself
# 
# net/core/net-sysfs.c
#   2003/09/25 22:39:55-04:00 jeffpc@jeff.home +1 -1
#   FIX: need to return a pointer not the value itself
# 
# ChangeSet
#   2003/09/23 17:45:39-04:00 jeffpc@jeff.home 
#   sysfs support
# 
# net/core/net-sysfs.c
#   2003/09/23 17:45:29-04:00 jeffpc@jeff.home +3 -2
#   sysfs support
# 
# ChangeSet
#   2003/09/23 06:56:37-04:00 jeffpc@jeff.home 
#   Merge jeff.home:/home/jeffpc/linux/linux-watch64
#   into jeff.home:/home/jeffpc/linux/linux-64network
# 
# net/core/dev.c
#   2003/09/23 06:56:33-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# include/linux/netdevice.h
#   2003/09/23 06:56:33-04:00 jeffpc@jeff.home +0 -0
#   Auto merged
# 
# ChangeSet
#   2003/09/21 11:42:14-04:00 jeffpc@jeff.home 
#   Added copyright notice
# 
# net/core/dev.c
#   2003/09/21 11:42:07-04:00 jeffpc@jeff.home +2 -0
#   Added copyright notice
# 
# include/linux/netdevice.h
#   2003/09/21 11:42:07-04:00 jeffpc@jeff.home +1 -0
#   Added copyright notice
# 
# ChangeSet
#   2003/09/21 11:08:57-04:00 jeffpc@jeff.home 
#   64network.patch
# 
# net/core/dev.c
#   2003/09/20 23:10:18-04:00 jeffpc@jeff.home +125 -18
#   Import patch 64network.patch
# 
# include/linux/netdevice.h
#   2003/09/20 23:12:39-04:00 jeffpc@jeff.home +3 -0
#   Import patch 64network.patch
# 
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	Thu Feb 19 19:18:12 2004
+++ b/include/linux/netdevice.h	Thu Feb 19 19:18:12 2004
@@ -14,6 +14,7 @@
  *		Alan Cox, <Alan.Cox@linux.org>
  *		Bjorn Ekwall. <bj0rn@blox.se>
  *              Pekka Riikonen <priikone@poseidon.pspt.fi>
+ *		Josef "Jeff" Sipek <jeffpc@optonline.net>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -922,6 +923,10 @@
 #ifdef CONFIG_SYSCTL
 extern char *net_sysctl_strdup(const char *s);
 #endif
+
+/* Register/unregister all the members of struct net_device_stats with watch64 */
+inline void		net_register_stats64(struct net_device_stats* stats);
+inline void		net_unregister_stats64(struct net_device_stats* stats);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Thu Feb 19 19:18:11 2004
+++ b/net/core/dev.c	Thu Feb 19 19:18:12 2004
@@ -18,6 +18,7 @@
  *		Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
  *		Adam Sulmicki <adam@cfar.umd.edu>
  *              Pekka Riikonen <priikone@poesidon.pspt.fi>
+ *		Josef "Jeff" Sipek <jeffpc@optonline.net>
  *
  *	Changes:
  *              D.J. Barrow     :       Fixed bug where dev->refcnt gets set
@@ -70,6 +71,7 @@
  *              			indefinitely on dev->refcnt
  * 		J Hadi Salim	:	- Backlog queue sampling
  *				        - netif_rx() feedback
+ *	Josef "Jeff" Sipek	:	Added watch64 calls for network statistics
  */
 
 #include <asm/uaccess.h>
@@ -105,6 +107,7 @@
 #include <linux/kmod.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/watch64.h>
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -2045,9 +2048,11 @@
 
 		seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
 				"%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
-			   dev->name, stats->rx_bytes, stats->rx_packets,
+			   dev->name, stats->rx_bytes,
+			   stats->rx_packets,
 			   stats->rx_errors,
-			   stats->rx_dropped + stats->rx_missed_errors,
+			   stats->rx_dropped +
+			     stats->rx_missed_errors,
 			   stats->rx_fifo_errors,
 			   stats->rx_length_errors + stats->rx_over_errors +
 			     stats->rx_crc_errors + stats->rx_frame_errors,
@@ -2064,6 +2069,49 @@
 		seq_printf(seq, "%6s: No statistics available.\n", dev->name);
 }
 
+static void dev_seq_printf_stats64(struct seq_file *seq, struct net_device *dev)
+{
+	if (dev->get_stats) {
+		struct net_device_stats *stats = dev->get_stats(dev);
+
+		seq_printf(seq, "%6s:%8llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
+				"%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
+			   dev->name, watch64_getval(&stats->rx_bytes,NULL),
+			   watch64_getval(&stats->rx_packets,NULL),
+			   watch64_getval(&stats->rx_errors,NULL),
+			   watch64_getval(&stats->rx_dropped,NULL) +
+			     watch64_getval(&stats->rx_missed_errors,NULL),
+			   watch64_getval(&stats->rx_fifo_errors,NULL),
+			   watch64_getval(&stats->rx_length_errors,NULL) + 
+			     watch64_getval(&stats->rx_over_errors,NULL) +
+			     watch64_getval(&stats->rx_crc_errors,NULL) +
+			     watch64_getval(&stats->rx_frame_errors,NULL),
+			   watch64_getval(&stats->rx_compressed,NULL),
+			   watch64_getval(&stats->multicast,NULL),
+			   watch64_getval(&stats->tx_bytes,NULL),
+			   watch64_getval(&stats->tx_packets,NULL),
+			   watch64_getval(&stats->tx_errors,NULL),
+			   watch64_getval(&stats->tx_dropped,NULL),
+			   watch64_getval(&stats->tx_fifo_errors,NULL),
+			   watch64_getval(&stats->collisions,NULL),
+			   watch64_getval(&stats->tx_carrier_errors,NULL) +
+			     watch64_getval(&stats->tx_aborted_errors,NULL) +
+			     watch64_getval(&stats->tx_window_errors,NULL) +
+			     watch64_getval(&stats->tx_heartbeat_errors,NULL),
+			   watch64_getval(&stats->tx_compressed,NULL));
+	} else
+		seq_printf(seq, "%6s: No statistics available.\n", dev->name);
+}
+
+static void dev_seq_show_header(struct seq_file *seq)
+{
+	seq_puts(seq, "Inter-|   Receive                            "
+		      "                    |  Transmit\n"
+		      " face |bytes    packets errs drop fifo frame "
+		      "compressed multicast|bytes    packets errs "
+		      "drop fifo colls carrier compressed\n");
+}
+
 /*
  *	Called from the PROCfs module. This now uses the new arbitrary sized
  *	/proc/net interface to create /proc/net/dev
@@ -2071,16 +2119,21 @@
 static int dev_seq_show(struct seq_file *seq, void *v)
 {
 	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, "Inter-|   Receive                            "
-			      "                    |  Transmit\n"
-			      " face |bytes    packets errs drop fifo frame "
-			      "compressed multicast|bytes    packets errs "
-			      "drop fifo colls carrier compressed\n");
+		dev_seq_show_header(seq);
 	else
 		dev_seq_printf_stats(seq, v);
 	return 0;
 }
 
+static int dev_seq_show64(struct seq_file *seq, void *v)
+{
+	if (v == SEQ_START_TOKEN)
+		dev_seq_show_header(seq);
+	else
+		dev_seq_printf_stats64(seq, v);
+	return 0;
+}
+
 static struct netif_rx_stats *softnet_get_online(loff_t *pos)
 {
 	struct netif_rx_stats *rc = NULL;
@@ -2133,11 +2186,23 @@
 	.show  = dev_seq_show,
 };
 
+static struct seq_operations dev_seq_ops64 = {
+	.start = dev_seq_start,
+	.next  = dev_seq_next,
+	.stop  = dev_seq_stop,
+	.show  = dev_seq_show64,
+};
+
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
 	return seq_open(file, &dev_seq_ops);
 }
 
+static int dev_seq_open64(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &dev_seq_ops64);
+}
+
 static struct file_operations dev_seq_fops = {
 	.owner	 = THIS_MODULE,
 	.open    = dev_seq_open,
@@ -2146,6 +2211,14 @@
 	.release = seq_release,
 };
 
+static struct file_operations dev_seq_fops64 = {
+	.owner	 = THIS_MODULE,
+	.open    = dev_seq_open64,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
 static struct seq_operations softnet_seq_ops = {
 	.start = softnet_seq_start,
 	.next  = softnet_seq_next,
@@ -2178,8 +2251,10 @@
 
 	if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
 		goto out;
-	if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
+	if (!proc_net_fops_create("dev64", S_IRUGO, &dev_seq_fops64))
 		goto out_dev;
+	if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
+		goto out_dev64;
 	if (wireless_proc_init())
 		goto out_softnet;
 	rc = 0;
@@ -2187,6 +2262,8 @@
 	return rc;
 out_softnet:
 	proc_net_remove("softnet_stat");
+out_dev64:
+	proc_net_remove("dev64");
 out_dev:
 	proc_net_remove("dev");
 	goto out;
@@ -2869,6 +2946,9 @@
 	 *	device is present.
 	 */
 
+	if (dev->get_stats)
+		net_register_stats64(dev->get_stats(dev));
+	
 	set_bit(__LINK_STATE_PRESENT, &dev->state);
 
 	dev->next = NULL;
@@ -2881,7 +2961,7 @@
 	dev_hold(dev);
 	dev->reg_state = NETREG_REGISTERING;
 	write_unlock_bh(&dev_base_lock);
-
+	
 	/* Notify protocols, that a new device appeared. */
 	notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
 
@@ -3094,6 +3174,9 @@
 	/* If device is running, close it first. */
 	if (dev->flags & IFF_UP)
 		dev_close(dev);
+		
+	if (dev->get_stats)
+		net_unregister_stats64(dev->get_stats(dev));
 
 	/* And unlink it from device chain. */
 	for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) {
@@ -3151,6 +3234,98 @@
 	return 0;
 }
 
+/*
+ *	Register all the members of the net_device_stats structure
+ *
+ */
+ 
+inline void net_register_stats64(struct net_device_stats* stats)
+{
+	if (!stats)
+		return;
+
+	watch64_register(&stats->tx_packets,0);
+	watch64_enable  (&stats->tx_packets,NULL);
+	watch64_register(&stats->rx_packets,0);
+	watch64_enable  (&stats->rx_packets,NULL);
+	watch64_register(&stats->tx_bytes,0);
+	watch64_enable  (&stats->tx_bytes,NULL);
+	watch64_register(&stats->rx_bytes,0);
+	watch64_enable  (&stats->rx_bytes,NULL);
+	watch64_register(&stats->tx_errors,0);
+	watch64_enable  (&stats->tx_errors,NULL);
+	watch64_register(&stats->rx_errors,0);
+	watch64_enable  (&stats->rx_errors,NULL);
+	watch64_register(&stats->tx_dropped,0);
+	watch64_enable  (&stats->tx_dropped,NULL);
+	watch64_register(&stats->rx_dropped,0);
+	watch64_enable  (&stats->rx_dropped,NULL);
+	watch64_register(&stats->multicast,0);
+	watch64_enable  (&stats->multicast,NULL);
+	watch64_register(&stats->collisions,0);
+	watch64_enable  (&stats->collisions,NULL);
+	watch64_register(&stats->rx_length_errors,0);
+	watch64_enable  (&stats->rx_length_errors,NULL);
+	watch64_register(&stats->rx_over_errors,0);
+	watch64_enable  (&stats->rx_over_errors,NULL);
+	watch64_register(&stats->rx_crc_errors,0);
+	watch64_enable  (&stats->rx_crc_errors,NULL);
+	watch64_register(&stats->rx_frame_errors,0);
+	watch64_enable  (&stats->rx_frame_errors,NULL);
+	watch64_register(&stats->rx_fifo_errors,0);
+	watch64_enable  (&stats->rx_fifo_errors,NULL);
+	watch64_register(&stats->rx_missed_errors,0);
+	watch64_enable  (&stats->rx_missed_errors,NULL);
+	watch64_register(&stats->tx_aborted_errors,0);
+	watch64_enable  (&stats->tx_aborted_errors,NULL);
+	watch64_register(&stats->tx_carrier_errors,0);
+	watch64_enable  (&stats->tx_carrier_errors,NULL);
+	watch64_register(&stats->tx_fifo_errors,0);
+	watch64_enable  (&stats->tx_fifo_errors,NULL);
+	watch64_register(&stats->tx_heartbeat_errors,0);
+	watch64_enable  (&stats->tx_heartbeat_errors,NULL);
+	watch64_register(&stats->tx_window_errors,0);
+	watch64_enable  (&stats->tx_window_errors,NULL);
+	watch64_register(&stats->rx_compressed,0);
+	watch64_enable  (&stats->rx_compressed,NULL);
+	watch64_register(&stats->tx_compressed,0);
+	watch64_enable  (&stats->tx_compressed,NULL);
+}
+
+/*
+ *	Unregister all the members of the net_device_stats structure
+ *
+ */
+ 
+inline void net_unregister_stats64(struct net_device_stats* stats)
+{
+	if (!stats)
+		return;
+
+	watch64_unregister(&stats->tx_packets,0);
+	watch64_unregister(&stats->rx_packets,0);
+	watch64_unregister(&stats->tx_bytes,0);
+	watch64_unregister(&stats->rx_bytes,0);
+	watch64_unregister(&stats->tx_errors,0);
+	watch64_unregister(&stats->rx_errors,0);
+	watch64_unregister(&stats->tx_dropped,0);
+	watch64_unregister(&stats->rx_dropped,0);
+	watch64_unregister(&stats->multicast,0);
+	watch64_unregister(&stats->collisions,0);
+	watch64_unregister(&stats->rx_length_errors,0);
+	watch64_unregister(&stats->rx_over_errors,0);
+	watch64_unregister(&stats->rx_crc_errors,0);
+	watch64_unregister(&stats->rx_frame_errors,0);
+	watch64_unregister(&stats->rx_fifo_errors,0);
+	watch64_unregister(&stats->rx_missed_errors,0);
+	watch64_unregister(&stats->tx_aborted_errors,0);
+	watch64_unregister(&stats->tx_carrier_errors,0);
+	watch64_unregister(&stats->tx_fifo_errors,0);
+	watch64_unregister(&stats->tx_heartbeat_errors,0);
+	watch64_unregister(&stats->tx_window_errors,0);
+	watch64_unregister(&stats->rx_compressed,0);
+	watch64_unregister(&stats->tx_compressed,0);
+}
 
 /*
  *	Initialize the DEV module. At boot time this walks the device list and
diff -Nru a/net/core/net-sysfs.c b/net/core/net-sysfs.c
--- a/net/core/net-sysfs.c	Thu Feb 19 19:18:12 2004
+++ b/net/core/net-sysfs.c	Thu Feb 19 19:18:12 2004
@@ -16,6 +16,7 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
+#include <linux/watch64.h>
 
 #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
@@ -23,6 +24,7 @@
 static const char *fmt_hex = "%#x\n";
 static const char *fmt_dec = "%d\n";
 static const char *fmt_ulong = "%lu\n";
+static const char *fmt_ullong = "%llu\n";
 
 static inline int dev_isalive(const struct net_device *dev) 
 {
@@ -204,8 +206,8 @@
 	read_lock(&dev_base_lock);
 	if (dev_isalive(dev) && dev->get_stats &&
 	    (stats = (*dev->get_stats)(dev))) 
-		ret = sprintf(buf, fmt_ulong,
-			      *(unsigned long *)(((u8 *) stats) + offset));
+		ret = sprintf(buf, fmt_ullong,
+			      watch64_getval((unsigned long *)(((u8 *) stats) + offset),NULL));
 
 	read_unlock(&dev_base_lock);
 	return ret;

