Add trivial net device statistics (TX and RX packet count), reported
authorMichael Brown <mcb30@etherboot.org>
Mon, 2 Jul 2007 23:15:53 +0000 (00:15 +0100)
committerMichael Brown <mcb30@etherboot.org>
Mon, 2 Jul 2007 23:15:53 +0000 (00:15 +0100)
via UNDI API and also by ifstat command; may be useful for debugging.

src/include/gpxe/netdevice.h
src/interface/pxe/pxe_undi.c
src/net/netdevice.c
src/usr/ifmgmt.c

index 0060e7d..c0df7c9 100644 (file)
@@ -128,6 +128,17 @@ struct ll_protocol {
        const uint8_t *ll_broadcast;
 };
 
+/**
+ * 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
  *
@@ -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;
index f456a0b..4e7529a 100644 (file)
@@ -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
index 294f078..8a09910 100644 (file)
@@ -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++;
 }
 
 /**
index ff5b34a..a43c4ca 100644 (file)
@@ -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 );
 }