From f460a436caa46045442e0d368b2913f7f25dd0b2 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 24 Apr 2019 16:25:47 +0100 Subject: [intelxl] Use 32-byte receive descriptors The physical function driver does not allow the virtual function to request the use of 16-byte receive descriptors. Switch to using 32-byte receive descriptors. Signed-off-by: Michael Brown --- src/drivers/net/intelxl.c | 26 ++++++++++++++------------ src/drivers/net/intelxl.h | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index 5cf89aa1..a218bdbd 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -1018,7 +1018,7 @@ static int intelxl_context_rx ( struct intelxl_nic *intelxl, base_count = INTELXL_CTX_RX_BASE_COUNT ( address, INTELXL_RX_NUM_DESC ); ctx.rx.base_count = cpu_to_le64 ( base_count ); ctx.rx.len = cpu_to_le16 ( INTELXL_CTX_RX_LEN ( intelxl->mfs ) ); - ctx.rx.flags = INTELXL_CTX_RX_FL_CRCSTRIP; + ctx.rx.flags = ( INTELXL_CTX_RX_FL_DSIZE | INTELXL_CTX_RX_FL_CRCSTRIP ); ctx.rx.mfs = cpu_to_le16 ( INTELXL_CTX_RX_MFS ( intelxl->mfs ) ); /* Program context */ @@ -1101,20 +1101,20 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl, int rc; /* Allocate descriptor ring */ - ring->desc = malloc_dma ( ring->len, INTELXL_ALIGN ); - if ( ! ring->desc ) { + ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN ); + if ( ! ring->desc.raw ) { rc = -ENOMEM; goto err_alloc; } /* Initialise descriptor ring */ - memset ( ring->desc, 0, ring->len ); + memset ( ring->desc.raw, 0, ring->len ); /* Reset tail pointer */ writel ( 0, ( ring_regs + INTELXL_QXX_TAIL ) ); /* Program queue context */ - address = virt_to_bus ( ring->desc ); + address = virt_to_bus ( ring->desc.raw ); if ( ( rc = ring->context ( intelxl, address ) ) != 0 ) goto err_context; @@ -1135,7 +1135,7 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl, intelxl_disable_ring ( intelxl, ring ); err_enable: err_context: - free_dma ( ring->desc, ring->len ); + free_dma ( ring->desc.raw, ring->len ); err_alloc: return rc; } @@ -1157,8 +1157,8 @@ static void intelxl_destroy_ring ( struct intelxl_nic *intelxl, } /* Free descriptor ring */ - free_dma ( ring->desc, ring->len ); - ring->desc = NULL; + free_dma ( ring->desc.raw, ring->len ); + ring->desc.raw = NULL; } /** @@ -1186,7 +1186,7 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) { /* Get next receive descriptor */ rx_idx = ( intelxl->rx.prod++ % INTELXL_RX_NUM_DESC ); - rx = &intelxl->rx.desc[rx_idx].rx; + rx = &intelxl->rx.desc.rx[rx_idx].data; /* Populate receive descriptor */ address = virt_to_bus ( iobuf->data ); @@ -1351,7 +1351,7 @@ static int intelxl_transmit ( struct net_device *netdev, } tx_idx = ( intelxl->tx.prod++ % INTELXL_TX_NUM_DESC ); tx_tail = ( intelxl->tx.prod % INTELXL_TX_NUM_DESC ); - tx = &intelxl->tx.desc[tx_idx].tx; + tx = &intelxl->tx.desc.tx[tx_idx].data; /* Populate transmit descriptor */ address = virt_to_bus ( iobuf->data ); @@ -1387,7 +1387,7 @@ static void intelxl_poll_tx ( struct net_device *netdev ) { /* Get next transmit descriptor */ tx_idx = ( intelxl->tx.cons % INTELXL_TX_NUM_DESC ); - tx_wb = &intelxl->tx.desc[tx_idx].tx_wb; + tx_wb = &intelxl->tx.desc.tx[tx_idx].wb; /* Stop if descriptor is still in use */ if ( ! ( tx_wb->flags & INTELXL_TX_WB_FL_DD ) ) @@ -1419,7 +1419,7 @@ static void intelxl_poll_rx ( struct net_device *netdev ) { /* Get next receive descriptor */ rx_idx = ( intelxl->rx.cons % INTELXL_RX_NUM_DESC ); - rx_wb = &intelxl->rx.desc[rx_idx].rx_wb; + rx_wb = &intelxl->rx.desc.rx[rx_idx].wb; /* Stop if descriptor is still in use */ if ( ! ( rx_wb->flags & cpu_to_le32 ( INTELXL_RX_WB_FL_DD ) ) ) @@ -1544,8 +1544,10 @@ static int intelxl_probe ( struct pci_device *pci ) { intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT, &intelxl_admin_offsets ); intelxl_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC, + sizeof ( intelxl->tx.desc.tx[0] ), intelxl_context_tx ); intelxl_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC, + sizeof ( intelxl->rx.desc.rx[0] ), intelxl_context_rx ); /* Fix up PCI device */ diff --git a/src/drivers/net/intelxl.h b/src/drivers/net/intelxl.h index 6bd5e3e8..883728e3 100644 --- a/src/drivers/net/intelxl.h +++ b/src/drivers/net/intelxl.h @@ -502,6 +502,9 @@ struct intelxl_context_rx { /** Receive queue data buffer length */ #define INTELXL_CTX_RX_LEN( len ) ( (len) >> 1 ) +/** Use 32-byte receive descriptors */ +#define INTELXL_CTX_RX_FL_DSIZE 0x10 + /** Strip CRC from received packets */ #define INTELXL_CTX_RX_FL_CRCSTRIP 0x20 @@ -605,6 +608,14 @@ struct intelxl_tx_writeback_descriptor { /** Transmit writeback descriptor complete */ #define INTELXL_TX_WB_FL_DD 0x01 +/** Transmit descriptor */ +union intelxl_tx_descriptor { + /** Transmit data descriptor */ + struct intelxl_tx_data_descriptor data; + /** Transmit writeback descriptor */ + struct intelxl_tx_writeback_descriptor wb; +}; + /** Receive data descriptor */ struct intelxl_rx_data_descriptor { /** Buffer address */ @@ -612,7 +623,7 @@ struct intelxl_rx_data_descriptor { /** Flags */ uint32_t flags; /** Reserved */ - uint8_t reserved[4]; + uint8_t reserved[20]; } __attribute__ (( packed )); /** Receive writeback descriptor */ @@ -627,6 +638,8 @@ struct intelxl_rx_writeback_descriptor { uint32_t flags; /** Length */ uint32_t len; + /** Reserved */ + uint8_t reserved_c[16]; } __attribute__ (( packed )); /** Receive writeback descriptor complete */ @@ -642,21 +655,24 @@ struct intelxl_rx_writeback_descriptor { #define INTELXL_RX_WB_LEN(len) ( ( (len) >> 6 ) & 0x3fff ) /** Packet descriptor */ -union intelxl_descriptor { - /** Transmit data descriptor */ - struct intelxl_tx_data_descriptor tx; - /** Transmit writeback descriptor */ - struct intelxl_tx_writeback_descriptor tx_wb; +union intelxl_rx_descriptor { /** Receive data descriptor */ - struct intelxl_rx_data_descriptor rx; + struct intelxl_rx_data_descriptor data; /** Receive writeback descriptor */ - struct intelxl_rx_writeback_descriptor rx_wb; + struct intelxl_rx_writeback_descriptor wb; }; /** Descriptor ring */ struct intelxl_ring { /** Descriptors */ - union intelxl_descriptor *desc; + union { + /** Transmit descriptors */ + union intelxl_tx_descriptor *tx; + /** Receive descriptors */ + union intelxl_rx_descriptor *rx; + /** Raw data */ + void *raw; + } desc; /** Producer index */ unsigned int prod; /** Consumer index */ @@ -679,14 +695,15 @@ struct intelxl_ring { * * @v ring Descriptor ring * @v count Number of descriptors + * @v len Length of a single descriptor * @v context Method to program queue context */ static inline __attribute__ (( always_inline)) void -intelxl_init_ring ( struct intelxl_ring *ring, unsigned int count, +intelxl_init_ring ( struct intelxl_ring *ring, unsigned int count, size_t len, int ( * context ) ( struct intelxl_nic *intelxl, physaddr_t address ) ) { - ring->len = ( count * sizeof ( ring->desc[0] ) ); + ring->len = ( count * len ); ring->context = context; } -- cgit v1.2.3-55-g7522