Add trivial net device statistics (TX and RX packet count), reported

via UNDI API and also by ifstat command; may be useful for debugging.
pull/1/head
Michael Brown 2007-07-03 00:15:53 +01:00
parent 071356d976
commit 4968caab82
4 changed files with 38 additions and 10 deletions

View File

@ -128,6 +128,17 @@ struct ll_protocol {
const uint8_t *ll_broadcast; 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 * A network device
* *
@ -215,6 +226,8 @@ struct net_device {
struct list_head tx_queue; struct list_head tx_queue;
/** RX packet queue */ /** RX packet queue */
struct list_head rx_queue; struct list_head rx_queue;
/** Device statistics */
struct net_device_stats stats;
/** Driver private data */ /** Driver private data */
void *priv; void *priv;

View File

@ -343,28 +343,33 @@ PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
/* PXENV_UNDI_GET_STATISTICS /* PXENV_UNDI_GET_STATISTICS
* *
* Status: won't implement (would require driver API changes for no * Status: working
* real benefit)
*/ */
PXENV_EXIT_t pxenv_undi_get_statistics ( struct s_PXENV_UNDI_GET_STATISTICS PXENV_EXIT_t pxenv_undi_get_statistics ( struct s_PXENV_UNDI_GET_STATISTICS
*undi_get_statistics ) { *undi_get_statistics ) {
DBG ( "PXENV_UNDI_GET_STATISTICS" ); DBG ( "PXENV_UNDI_GET_STATISTICS" );
undi_get_statistics->Status = PXENV_STATUS_UNSUPPORTED; undi_get_statistics->XmtGoodFrames = pxe_netdev->stats.tx_count;
return PXENV_EXIT_FAILURE; 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 /* PXENV_UNDI_CLEAR_STATISTICS
* *
* Status: won't implement (would require driver API changes for no * Status: working
* real benefit)
*/ */
PXENV_EXIT_t pxenv_undi_clear_statistics ( struct s_PXENV_UNDI_CLEAR_STATISTICS PXENV_EXIT_t pxenv_undi_clear_statistics ( struct s_PXENV_UNDI_CLEAR_STATISTICS
*undi_clear_statistics ) { *undi_clear_statistics ) {
DBG ( "PXENV_UNDI_CLEAR_STATISTICS" ); DBG ( "PXENV_UNDI_CLEAR_STATISTICS" );
undi_clear_statistics->Status = PXENV_STATUS_UNSUPPORTED; memset ( &pxe_netdev->stats, 0, sizeof ( pxe_netdev->stats ) );
return PXENV_EXIT_FAILURE;
undi_clear_statistics->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
} }
/* PXENV_UNDI_INITIATE_DIAGS /* PXENV_UNDI_INITIATE_DIAGS

View 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.next != NULL );
assert ( iobuf->list.prev != NULL ); assert ( iobuf->list.prev != NULL );
/* Dequeue and free I/O buffer */
list_del ( &iobuf->list ); list_del ( &iobuf->list );
free_iob ( iobuf ); 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 ) { void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n", DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
netdev, iobuf, iobuf->data, iob_len ( iobuf ) ); netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
/* Enqueue packet */
list_add_tail ( &iobuf->list, &netdev->rx_queue ); list_add_tail ( &iobuf->list, &netdev->rx_queue );
/* Update statistics counter */
netdev->stats.rx_count++;
} }
/** /**

View File

@ -61,7 +61,8 @@ void ifclose ( struct net_device *netdev ) {
* @v netdev Network device * @v netdev Network device
*/ */
void ifstat ( struct net_device *netdev ) { 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->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 );
} }