*/
static int gve_create_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
const struct gve_queue_type *type = queue->type;
+ const struct gve_queue_stride *stride = &queue->stride;
union gve_admin_command *cmd;
struct gve_buffer *buf;
unsigned int db_off;
/* Reset queue */
queue->prod = 0;
queue->cons = 0;
- memset ( queue->desc.raw, 0, ( queue->count * type->desc_len ) );
- memset ( queue->cmplt.raw, 0, ( queue->count * type->cmplt_len ) );
+ memset ( queue->desc.raw, 0, ( queue->count * stride->desc ) );
+ memset ( queue->cmplt.raw, 0, ( queue->count * stride->cmplt ) );
for ( i = 0 ; i < queue->fill ; i++ )
queue->tag[i] = i;
/* Pre-populate descriptor offsets */
- buf = ( queue->desc.raw + type->desc_len - sizeof ( *buf ) );
+ buf = ( queue->desc.raw + stride->desc - sizeof ( *buf ) );
for ( i = 0 ; i < queue->count ; i++ ) {
tag = ( i & ( queue->fill - 1 ) );
buf->addr = cpu_to_be64 ( gve_address ( queue, tag ) );
- buf = ( ( ( void * ) buf ) + type->desc_len );
+ buf = ( ( ( void * ) buf ) + stride->desc );
}
/* Construct request */
*/
static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
const struct gve_queue_type *type = queue->type;
+ struct gve_queue_stride *stride = &queue->stride;
struct dma_device *dma = gve->dma;
- size_t desc_len = ( queue->count * type->desc_len );
- size_t cmplt_len = ( queue->count * type->cmplt_len );
- size_t res_len = sizeof ( *queue->res );
+ size_t desc_len;
+ size_t cmplt_len;
+ size_t res_len;
int rc;
/* Sanity checks */
goto err_sanity;
}
+ /* Set queue strides and calculate total lengths */
+ *stride = type->stride.gqi;
+ desc_len = ( queue->count * stride->desc );
+ cmplt_len = ( queue->count * stride->cmplt );
+ res_len = sizeof ( *queue->res );
+
/* Calculate maximum fill level */
assert ( ( type->fill & ( type->fill - 1 ) ) == 0 );
queue->fill = type->fill;
* @v queue Descriptor queue
*/
static void gve_free_queue ( struct gve_nic *gve, struct gve_queue *queue ) {
- const struct gve_queue_type *type = queue->type;
- size_t desc_len = ( queue->count * type->desc_len );
- size_t cmplt_len = ( queue->count * type->cmplt_len );
+ const struct gve_queue_stride *stride = &queue->stride;
+ size_t desc_len = ( queue->count * stride->desc );
+ size_t cmplt_len = ( queue->count * stride->cmplt );
size_t res_len = sizeof ( *queue->res );
/* Free queue resources */
.qpl = GVE_TX_QPL,
.irq = GVE_TX_IRQ,
.fill = GVE_TX_FILL,
- .desc_len = sizeof ( struct gve_gqi_tx_descriptor ),
+ .stride = {
+ .gqi = {
+ .desc = sizeof ( struct gve_gqi_tx_descriptor ),
+ },
+ },
.create = GVE_ADMIN_CREATE_TX,
.destroy = GVE_ADMIN_DESTROY_TX,
};
.qpl = GVE_RX_QPL,
.irq = GVE_RX_IRQ,
.fill = GVE_RX_FILL,
- .desc_len = sizeof ( struct gve_gqi_rx_descriptor ),
- .cmplt_len = sizeof ( struct gve_gqi_rx_completion ),
+ .stride = {
+ .gqi = {
+ .desc = sizeof ( struct gve_gqi_rx_descriptor ),
+ .cmplt = sizeof ( struct gve_gqi_rx_completion ),
+ },
+ },
.create = GVE_ADMIN_CREATE_RX,
.destroy = GVE_ADMIN_DESTROY_RX,
};
/** Padding at the start of all received packets */
#define GVE_RX_PAD 2
+/** Queue strides */
+struct gve_queue_stride {
+ /** Descriptor ring stride */
+ uint8_t desc;
+ /** Completion ring stride */
+ uint8_t cmplt;
+};
+
/** A descriptor queue */
struct gve_queue {
/** Descriptor ring */
/** Queue type */
const struct gve_queue_type *type;
+ /** Queue strides */
+ struct gve_queue_stride stride;
/** Number of descriptors (must be a power of two) */
unsigned int count;
/** Maximum fill level (must be a power of two) */
uint8_t irq;
/** Maximum fill level */
uint8_t fill;
- /** Descriptor size */
- uint8_t desc_len;
- /** Completion size */
- uint8_t cmplt_len;
+ /** Queue strides */
+ struct {
+ /** In-order queue strides */
+ struct gve_queue_stride gqi;
+ } stride;
/** Command to create queue */
uint8_t create;
/** Command to destroy queue */