From b52ea208411e65a6583c70c9efdc0cd8eda2d7d7 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 16 Aug 2022 13:21:49 +0100 Subject: [intelxl] Show virtual function packet statistics for debugging Signed-off-by: Michael Brown --- src/drivers/net/intelxlvf.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/drivers/net/intelxlvf.h | 29 ++++++++++++++++++++++ 2 files changed, 88 insertions(+) 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 */ -- cgit v1.1