aboutsummaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-08-16 13:21:49 +0100
committerMichael Brown <mcb30@ipxe.org>2022-08-16 17:58:46 +0100
commitb52ea208411e65a6583c70c9efdc0cd8eda2d7d7 (patch)
treeda241423c845a8f75cbbd0e0ac0882f013452651 /src/drivers
parentcad1cc6b449b63415ffdad8e12f13df4256106fb (diff)
downloadipxe-b52ea208411e65a6583c70c9efdc0cd8eda2d7d7.zip
ipxe-b52ea208411e65a6583c70c9efdc0cd8eda2d7d7.tar.gz
ipxe-b52ea208411e65a6583c70c9efdc0cd8eda2d7d7.tar.bz2
[intelxl] Show virtual function packet statistics for debugging
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/net/intelxlvf.c59
-rw-r--r--src/drivers/net/intelxlvf.h29
2 files changed, 88 insertions, 0 deletions
diff --git a/src/drivers/net/intelxlvf.c b/src/drivers/net/intelxlvf.c
index 3567be4..c58520a 100644
--- a/src/drivers/net/intelxlvf.c
+++ b/src/drivers/net/intelxlvf.c
@@ -391,6 +391,57 @@ static int intelxlvf_admin_get_resources ( struct net_device *netdev ) {
return 0;
}
+/**
+ * Get statistics (for debugging)
+ *
+ * @v netdev Network device
+ * @ret rc Return status code
+ */
+static int intelxlvf_admin_stats ( struct net_device *netdev ) {
+ struct intelxl_nic *intelxl = netdev->priv;
+ struct intelxlvf_admin_descriptor *cmd;
+ union intelxlvf_admin_buffer *buf;
+ struct intelxlvf_admin_stats *tx;
+ struct intelxlvf_admin_stats *rx;
+ int rc;
+
+ /* Populate descriptor */
+ cmd = intelxlvf_admin_command_descriptor ( intelxl );
+ cmd->vopcode = cpu_to_le32 ( INTELXLVF_ADMIN_GET_STATS );
+ cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
+ cmd->len = cpu_to_le16 ( sizeof ( buf->queues ) );
+ buf = intelxlvf_admin_command_buffer ( intelxl );
+ buf->queues.vsi = cpu_to_le16 ( intelxl->vsi );
+ tx = &buf->stats.tx;
+ rx = &buf->stats.rx;
+
+ /* Issue command */
+ if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
+ return rc;
+ DBGC ( intelxl, "INTELXL %p TX bytes %#llx discards %#llx errors "
+ "%#llx\n", intelxl,
+ ( ( unsigned long long ) le64_to_cpu ( tx->bytes ) ),
+ ( ( unsigned long long ) le64_to_cpu ( tx->discards ) ),
+ ( ( unsigned long long ) le64_to_cpu ( tx->errors ) ) );
+ DBGC ( intelxl, "INTELXL %p TX unicasts %#llx multicasts %#llx "
+ "broadcasts %#llx\n", intelxl,
+ ( ( unsigned long long ) le64_to_cpu ( tx->unicasts ) ),
+ ( ( unsigned long long ) le64_to_cpu ( tx->multicasts ) ),
+ ( ( unsigned long long ) le64_to_cpu ( tx->broadcasts ) ) );
+ DBGC ( intelxl, "INTELXL %p RX bytes %#llx discards %#llx errors "
+ "%#llx\n", intelxl,
+ ( ( unsigned long long ) le64_to_cpu ( rx->bytes ) ),
+ ( ( unsigned long long ) le64_to_cpu ( rx->discards ) ),
+ ( ( unsigned long long ) le64_to_cpu ( rx->errors ) ) );
+ DBGC ( intelxl, "INTELXL %p RX unicasts %#llx multicasts %#llx "
+ "broadcasts %#llx\n", intelxl,
+ ( ( unsigned long long ) le64_to_cpu ( rx->unicasts ) ),
+ ( ( unsigned long long ) le64_to_cpu ( rx->multicasts ) ),
+ ( ( unsigned long long ) le64_to_cpu ( rx->broadcasts ) ) );
+
+ return 0;
+}
+
/******************************************************************************
*
* Network device interface
@@ -565,6 +616,10 @@ static int intelxlvf_open ( struct net_device *netdev ) {
if ( ( rc = intelxlvf_admin_promisc ( netdev ) ) != 0 )
goto err_promisc;
+ /* Reset statistics counters (if debugging) */
+ if ( DBG_LOG )
+ intelxlvf_admin_stats ( netdev );
+
return 0;
err_promisc:
@@ -588,6 +643,10 @@ static void intelxlvf_close ( struct net_device *netdev ) {
struct intelxl_nic *intelxl = netdev->priv;
int rc;
+ /* Show statistics (if debugging) */
+ if ( DBG_LOG )
+ intelxlvf_admin_stats ( netdev );
+
/* Disable queues */
if ( ( rc = intelxlvf_admin_queues ( netdev, 0 ) ) != 0 ) {
/* Leak memory; there's nothing else we can do */
diff --git a/src/drivers/net/intelxlvf.h b/src/drivers/net/intelxlvf.h
index 5c22275..c537f6a 100644
--- a/src/drivers/net/intelxlvf.h
+++ b/src/drivers/net/intelxlvf.h
@@ -253,6 +253,33 @@ struct intelxlvf_admin_promisc_buffer {
uint16_t flags;
} __attribute__ (( packed ));
+/** Admin Queue VF Get Statistics opcode */
+#define INTELXLVF_ADMIN_GET_STATS 0x0000000f
+
+/** VF statistics */
+struct intelxlvf_admin_stats {
+ /** Bytes */
+ uint64_t bytes;
+ /** Unicast packets */
+ uint64_t unicasts;
+ /** Multicast packets */
+ uint64_t multicasts;
+ /** Broadcast packets */
+ uint64_t broadcasts;
+ /** Discarded packets */
+ uint64_t discards;
+ /** Errors */
+ uint64_t errors;
+} __attribute__ (( packed ));
+
+/** Admin Queue VF Get Statistics data buffer */
+struct intelxlvf_admin_stats_buffer {
+ /** Receive statistics */
+ struct intelxlvf_admin_stats rx;
+ /** Transmit statistics */
+ struct intelxlvf_admin_stats tx;
+} __attribute__ (( packed ));
+
/** Admin queue data buffer */
union intelxlvf_admin_buffer {
/** Original 40 Gigabit Ethernet data buffer */
@@ -271,6 +298,8 @@ union intelxlvf_admin_buffer {
struct intelxlvf_admin_promisc_buffer promisc;
/** VF IRQ Map data buffer */
struct intelxlvf_admin_irq_map_buffer irq;
+ /** VF Get Statistics data buffer */
+ struct intelxlvf_admin_stats_buffer stats;
} __attribute__ (( packed ));
/** Admin queue descriptor */