From 048a3467052d00c42041231e11127fe147f6e7c5 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 29 Sep 2025 11:46:15 +0100 Subject: [PATCH] [gve] Add concept of operating mode The GVE family supports two incompatible descriptor queue formats: * GQI: in-order descriptor queues * DQO: out-of-order descriptor queues and two addressing modes: * QPL: pre-registered queue page list addressing * RDA: raw DMA addressing All four combinations (GQI-QPL, GQI-RDA, DQO-QPL, and DQO-RDA) are theoretically supported by the Linux driver, which is essentially the only public reference provided by Google. The original versions of the GVE NIC supported only GQI-QPL mode, and so the iPXE driver is written to target this mode, on the assumption that it would continue to be supported by all models of the GVE NIC. This assumption turns out to be incorrect: Google does not deem it necessary to retain backwards compatibility. Some newer machine types (such as a4-highgpu-8g) support only the DQO-RDA operating mode. Add a definition of operating mode, and pass this as an explicit parameter to the "configure device resources" admin queue command. We choose a representation that subtracts one from the value passed in this command, since this happens to allow us to decompose the mode into two independent bits (one representing the use of DQO descriptor format, one representing the use of QPL addressing). Signed-off-by: Michael Brown --- src/drivers/net/gve.c | 22 ++++++++++++++++++++++ src/drivers/net/gve.h | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/drivers/net/gve.c b/src/drivers/net/gve.c index e0badd78a..4ac8d2a8a 100644 --- a/src/drivers/net/gve.c +++ b/src/drivers/net/gve.c @@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include +#include #include #include #include @@ -182,6 +183,21 @@ static int gve_reset ( struct gve_nic *gve ) { ****************************************************************************** */ +/** + * Get operating mode name (for debugging) + * + * @v mode Operating mode + * @ret name Mode name + */ +static inline const char * gve_mode_name ( unsigned int mode ) { + static char buf[ 8 /* "XXX-XXX" + NUL */ ]; + + snprintf ( buf, sizeof ( buf ), "%s-%s", + ( ( mode & GVE_MODE_DQO ) ? "DQO" : "GQI" ), + ( ( mode & GVE_MODE_QPL ) ? "QPL" : "RDA" ) ); + return buf; +} + /** * Allocate admin queue * @@ -489,6 +505,11 @@ static int gve_describe ( struct gve_nic *gve ) { } DBGC ( gve, "GVE %p supports options %#08x\n", gve, gve->options ); + /* Select preferred operating mode */ + gve->mode = GVE_MODE_QPL; + DBGC ( gve, "GVE %p using %s mode\n", + gve, gve_mode_name ( gve->mode ) ); + return 0; } @@ -516,6 +537,7 @@ static int gve_configure ( struct gve_nic *gve ) { cmd->conf.num_events = cpu_to_be32 ( events->count ); cmd->conf.num_irqs = cpu_to_be32 ( GVE_IRQ_COUNT ); cmd->conf.irq_stride = cpu_to_be32 ( sizeof ( irqs->irq[0] ) ); + cmd->conf.format = GVE_FORMAT ( gve->mode ); /* Issue command */ if ( ( rc = gve_admin ( gve ) ) != 0 ) diff --git a/src/drivers/net/gve.h b/src/drivers/net/gve.h index ca43d6060..78f085671 100644 --- a/src/drivers/net/gve.h +++ b/src/drivers/net/gve.h @@ -214,8 +214,17 @@ struct gve_admin_configure { uint32_t num_irqs; /** IRQ doorbell stride */ uint32_t irq_stride; + /** MSI-X base index */ + uint32_t msix_base; + /** Descriptor queue format */ + uint8_t format; + /** Reserved */ + uint8_t reserved[7]; } __attribute__ (( packed )); +/** Descriptor queue format */ +#define GVE_FORMAT( mode ) ( (mode) + 1 ) + /** Register page list command */ #define GVE_ADMIN_REGISTER 0x0003 @@ -691,6 +700,8 @@ struct gve_nic { struct gve_scratch scratch; /** Supported options */ uint32_t options; + /** Operating mode */ + unsigned int mode; /** Transmit queue */ struct gve_queue tx; @@ -711,6 +722,15 @@ struct gve_nic { uint32_t activity; }; +/** Operating mode + * + * These values are chosen to allow for easy transformation to a queue + * format identifier as used for the "Configure device resources" + * command. + */ +#define GVE_MODE_QPL 0x01 /**< Use registered queue pages */ +#define GVE_MODE_DQO 0x02 /**< Use out-of-order queues */ + /** Maximum time to wait for admin queue commands */ #define GVE_ADMIN_MAX_WAIT_MS 500 -- 2.47.3