diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 079acea..8aa6240 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -22,6 +22,7 @@
 
 #include <common.h>
 #include <asm/errno.h>
+#include <linux/netdevice.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/cdc.h>
 #include <linux/usb/gadget.h>
@@ -175,6 +176,7 @@ struct eth_dev {
 	struct usb_request	*tx_req, *rx_req;
 
 	struct eth_device	*net;
+	struct net_device_stats	stats;
 	unsigned int		tx_qlen;
 
 	unsigned		zlp:1;
@@ -1271,7 +1273,31 @@ static int rx_submit(struct eth_dev *dev, struct usb_request *req,
 
 static void rx_complete(struct usb_ep *ep, struct usb_request *req)
 {
+	struct eth_dev	*dev = ep->driver_data;
+
 	debug("%s: status %d\n", __func__, req->status);
+	switch (req->status) {
+	/* normal completion */
+	case 0:
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += req->length;
+		break;
+
+	/* software-driven interface shutdown */
+	case -ECONNRESET:		/* unlink */
+	case -ESHUTDOWN:		/* disconnect etc */
+	/* for hardware automagic (such as pxa) */
+	case -ECONNABORTED:		/* endpoint reset */
+		break;
+
+	/* data overrun */
+	case -EOVERFLOW:
+		dev->stats.rx_over_errors++;
+		/* FALLTHROUGH */
+	default:
+		dev->stats.rx_errors++;
+		break;
+	}
 
 	packet_received = 1;
 }
@@ -1300,7 +1326,22 @@ fail1:
 
 static void tx_complete(struct usb_ep *ep, struct usb_request *req)
 {
+	struct eth_dev	*dev = ep->driver_data;
+
 	debug("%s: status %s\n", __func__, (req->status) ? "failed" : "ok");
+	switch (req->status) {
+	default:
+		dev->stats.tx_errors++;
+		debug("tx err %d\n", req->status);
+		/* FALLTHROUGH */
+	case -ECONNRESET:		/* unlink */
+	case -ESHUTDOWN:		/* disconnect etc */
+		break;
+	case 0:
+		dev->stats.tx_bytes += req->length;
+	}
+	dev->stats.tx_packets++;
+
 	packet_sent = 1;
 }
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
new file mode 100644
index 0000000..870d8b4
--- /dev/null
+++ b/include/linux/netdevice.h
@@ -0,0 +1,65 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		Definitions for the Interfaces handler.
+ *
+ * Version:	@(#)dev.h	1.0.10	08/12/93
+ *
+ * Authors:	Ross Biro
+ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *		Corey Minyard <wf-rch!minyard@relay.EU.net>
+ *		Donald J. Becker, <becker@cesdis.gsfc.nasa.gov>
+ *		Alan Cox, <Alan.Cox@linux.org>
+ *		Bjorn Ekwall. <bj0rn@blox.se>
+ *              Pekka Riikonen <priikone@poseidon.pspt.fi>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ *		Moved to /usr/include/linux for NET3
+ */
+#ifndef _LINUX_NETDEVICE_H
+#define _LINUX_NETDEVICE_H
+
+/*
+ *	Network device statistics. Akin to the 2.0 ether stats but
+ *	with byte counters.
+ */
+
+struct net_device_stats {
+	unsigned long	rx_packets;		/* total packets received	*/
+	unsigned long	tx_packets;		/* total packets transmitted	*/
+	unsigned long	rx_bytes;		/* total bytes received		*/
+	unsigned long	tx_bytes;		/* total bytes transmitted	*/
+	unsigned long	rx_errors;		/* bad packets received		*/
+	unsigned long	tx_errors;		/* packet transmit problems	*/
+	unsigned long	rx_dropped;		/* no space in linux buffers	*/
+	unsigned long	tx_dropped;		/* no space available in linux	*/
+	unsigned long	multicast;		/* multicast packets received	*/
+	unsigned long	collisions;
+
+	/* detailed rx_errors: */
+	unsigned long	rx_length_errors;
+	unsigned long	rx_over_errors;		/* receiver ring buff overflow	*/
+	unsigned long	rx_crc_errors;		/* recved pkt with crc error	*/
+	unsigned long	rx_frame_errors;	/* recv'd frame alignment error	*/
+	unsigned long	rx_fifo_errors;		/* recv'r fifo overrun		*/
+	unsigned long	rx_missed_errors;	/* receiver missed packet	*/
+
+	/* detailed tx_errors */
+	unsigned long	tx_aborted_errors;
+	unsigned long	tx_carrier_errors;
+	unsigned long	tx_fifo_errors;
+	unsigned long	tx_heartbeat_errors;
+	unsigned long	tx_window_errors;
+
+	/* for cslip etc */
+	unsigned long	rx_compressed;
+	unsigned long	tx_compressed;
+};
+
+#endif	/* _LINUX_NETDEVICE_H */
