summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2007-07-03 01:15:53 +0200
committerMichael Brown2007-07-03 01:15:53 +0200
commit4968caab8288664d4fd21417f312f3c5a05df155 (patch)
tree6c5ecf09777ba61dc056e9253df17ea309885a7d
parentEnsure that pxe_netdev is set before starting up PXE NBP. (diff)
downloadipxe-4968caab8288664d4fd21417f312f3c5a05df155.tar.gz
ipxe-4968caab8288664d4fd21417f312f3c5a05df155.tar.xz
ipxe-4968caab8288664d4fd21417f312f3c5a05df155.zip
Add trivial net device statistics (TX and RX packet count), reported
via UNDI API and also by ifstat command; may be useful for debugging.
-rw-r--r--src/include/gpxe/netdevice.h13
-rw-r--r--src/interface/pxe/pxe_undi.c21
-rw-r--r--src/net/netdevice.c9
-rw-r--r--src/usr/ifmgmt.c5
4 files changed, 38 insertions, 10 deletions
diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h
index 0060e7d5..c0df7c96 100644
--- a/src/include/gpxe/netdevice.h
+++ b/src/include/gpxe/netdevice.h
@@ -129,6 +129,17 @@ struct ll_protocol {
};
/**
+ * Network device statistics
+ *
+ */
+struct net_device_stats {
+ /** Count of successfully completed transmissions */
+ unsigned int tx_count;
+ /** Count of successfully received packets */
+ unsigned int rx_count;
+};
+
+/**
* A network device
*
* This structure represents a piece of networking hardware. It has
@@ -215,6 +226,8 @@ struct net_device {
struct list_head tx_queue;
/** RX packet queue */
struct list_head rx_queue;
+ /** Device statistics */
+ struct net_device_stats stats;
/** Driver private data */
void *priv;
diff --git a/src/interface/pxe/pxe_undi.c b/src/interface/pxe/pxe_undi.c
index f456a0b1..4e7529a3 100644
--- a/src/interface/pxe/pxe_undi.c
+++ b/src/interface/pxe/pxe_undi.c
@@ -343,28 +343,33 @@ PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
/* PXENV_UNDI_GET_STATISTICS
*
- * Status: won't implement (would require driver API changes for no
- * real benefit)
+ * Status: working
*/
PXENV_EXIT_t pxenv_undi_get_statistics ( struct s_PXENV_UNDI_GET_STATISTICS
*undi_get_statistics ) {
DBG ( "PXENV_UNDI_GET_STATISTICS" );
- undi_get_statistics->Status = PXENV_STATUS_UNSUPPORTED;
- return PXENV_EXIT_FAILURE;
+ undi_get_statistics->XmtGoodFrames = pxe_netdev->stats.tx_count;
+ undi_get_statistics->RcvGoodFrames = pxe_netdev->stats.rx_count;
+ undi_get_statistics->RcvCRCErrors = 0;
+ undi_get_statistics->RcvResourceErrors = 0;
+
+ undi_get_statistics->Status = PXENV_STATUS_SUCCESS;
+ return PXENV_EXIT_SUCCESS;
}
/* PXENV_UNDI_CLEAR_STATISTICS
*
- * Status: won't implement (would require driver API changes for no
- * real benefit)
+ * Status: working
*/
PXENV_EXIT_t pxenv_undi_clear_statistics ( struct s_PXENV_UNDI_CLEAR_STATISTICS
*undi_clear_statistics ) {
DBG ( "PXENV_UNDI_CLEAR_STATISTICS" );
- undi_clear_statistics->Status = PXENV_STATUS_UNSUPPORTED;
- return PXENV_EXIT_FAILURE;
+ memset ( &pxe_netdev->stats, 0, sizeof ( pxe_netdev->stats ) );
+
+ undi_clear_statistics->Status = PXENV_STATUS_SUCCESS;
+ return PXENV_EXIT_SUCCESS;
}
/* PXENV_UNDI_INITIATE_DIAGS
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index 294f0786..8a099107 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -95,8 +95,12 @@ void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf ) {
assert ( iobuf->list.next != NULL );
assert ( iobuf->list.prev != NULL );
+ /* Dequeue and free I/O buffer */
list_del ( &iobuf->list );
free_iob ( iobuf );
+
+ /* Update statistics counter */
+ netdev->stats.tx_count++;
}
/**
@@ -140,7 +144,12 @@ static void netdev_tx_flush ( struct net_device *netdev ) {
void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
+
+ /* Enqueue packet */
list_add_tail ( &iobuf->list, &netdev->rx_queue );
+
+ /* Update statistics counter */
+ netdev->stats.rx_count++;
}
/**
diff --git a/src/usr/ifmgmt.c b/src/usr/ifmgmt.c
index ff5b34a6..a43c4ca0 100644
--- a/src/usr/ifmgmt.c
+++ b/src/usr/ifmgmt.c
@@ -61,7 +61,8 @@ void ifclose ( struct net_device *netdev ) {
* @v netdev Network device
*/
void ifstat ( struct net_device *netdev ) {
- printf ( "%s: %s on %s (%s)\n",
+ printf ( "%s: %s on %s (%s) TX:%d RX:%d\n",
netdev->name, netdev_hwaddr ( netdev ), netdev->dev->name,
- ( ( netdev->state & NETDEV_OPEN ) ? "open" : "closed" ) );
+ ( ( netdev->state & NETDEV_OPEN ) ? "open" : "closed" ),
+ netdev->stats.tx_count, netdev->stats.rx_count );
}