[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 <mcb30@ipxe.org>
pull/92/head
Michael Brown 2019-04-24 16:25:47 +01:00
parent 7676924571
commit f460a436ca
2 changed files with 42 additions and 23 deletions

View File

@ -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 ); base_count = INTELXL_CTX_RX_BASE_COUNT ( address, INTELXL_RX_NUM_DESC );
ctx.rx.base_count = cpu_to_le64 ( base_count ); ctx.rx.base_count = cpu_to_le64 ( base_count );
ctx.rx.len = cpu_to_le16 ( INTELXL_CTX_RX_LEN ( intelxl->mfs ) ); 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 ) ); ctx.rx.mfs = cpu_to_le16 ( INTELXL_CTX_RX_MFS ( intelxl->mfs ) );
/* Program context */ /* Program context */
@ -1101,20 +1101,20 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl,
int rc; int rc;
/* Allocate descriptor ring */ /* Allocate descriptor ring */
ring->desc = malloc_dma ( ring->len, INTELXL_ALIGN ); ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN );
if ( ! ring->desc ) { if ( ! ring->desc.raw ) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_alloc; goto err_alloc;
} }
/* Initialise descriptor ring */ /* Initialise descriptor ring */
memset ( ring->desc, 0, ring->len ); memset ( ring->desc.raw, 0, ring->len );
/* Reset tail pointer */ /* Reset tail pointer */
writel ( 0, ( ring_regs + INTELXL_QXX_TAIL ) ); writel ( 0, ( ring_regs + INTELXL_QXX_TAIL ) );
/* Program queue context */ /* Program queue context */
address = virt_to_bus ( ring->desc ); address = virt_to_bus ( ring->desc.raw );
if ( ( rc = ring->context ( intelxl, address ) ) != 0 ) if ( ( rc = ring->context ( intelxl, address ) ) != 0 )
goto err_context; goto err_context;
@ -1135,7 +1135,7 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl,
intelxl_disable_ring ( intelxl, ring ); intelxl_disable_ring ( intelxl, ring );
err_enable: err_enable:
err_context: err_context:
free_dma ( ring->desc, ring->len ); free_dma ( ring->desc.raw, ring->len );
err_alloc: err_alloc:
return rc; return rc;
} }
@ -1157,8 +1157,8 @@ static void intelxl_destroy_ring ( struct intelxl_nic *intelxl,
} }
/* Free descriptor ring */ /* Free descriptor ring */
free_dma ( ring->desc, ring->len ); free_dma ( ring->desc.raw, ring->len );
ring->desc = NULL; ring->desc.raw = NULL;
} }
/** /**
@ -1186,7 +1186,7 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) {
/* Get next receive descriptor */ /* Get next receive descriptor */
rx_idx = ( intelxl->rx.prod++ % INTELXL_RX_NUM_DESC ); 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 */ /* Populate receive descriptor */
address = virt_to_bus ( iobuf->data ); 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_idx = ( intelxl->tx.prod++ % INTELXL_TX_NUM_DESC );
tx_tail = ( 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 */ /* Populate transmit descriptor */
address = virt_to_bus ( iobuf->data ); address = virt_to_bus ( iobuf->data );
@ -1387,7 +1387,7 @@ static void intelxl_poll_tx ( struct net_device *netdev ) {
/* Get next transmit descriptor */ /* Get next transmit descriptor */
tx_idx = ( intelxl->tx.cons % INTELXL_TX_NUM_DESC ); 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 */ /* Stop if descriptor is still in use */
if ( ! ( tx_wb->flags & INTELXL_TX_WB_FL_DD ) ) 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 */ /* Get next receive descriptor */
rx_idx = ( intelxl->rx.cons % INTELXL_RX_NUM_DESC ); 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 */ /* Stop if descriptor is still in use */
if ( ! ( rx_wb->flags & cpu_to_le32 ( INTELXL_RX_WB_FL_DD ) ) ) 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_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT,
&intelxl_admin_offsets ); &intelxl_admin_offsets );
intelxl_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC, intelxl_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC,
sizeof ( intelxl->tx.desc.tx[0] ),
intelxl_context_tx ); intelxl_context_tx );
intelxl_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC, intelxl_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC,
sizeof ( intelxl->rx.desc.rx[0] ),
intelxl_context_rx ); intelxl_context_rx );
/* Fix up PCI device */ /* Fix up PCI device */

View File

@ -502,6 +502,9 @@ struct intelxl_context_rx {
/** Receive queue data buffer length */ /** Receive queue data buffer length */
#define INTELXL_CTX_RX_LEN( len ) ( (len) >> 1 ) #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 */ /** Strip CRC from received packets */
#define INTELXL_CTX_RX_FL_CRCSTRIP 0x20 #define INTELXL_CTX_RX_FL_CRCSTRIP 0x20
@ -605,6 +608,14 @@ struct intelxl_tx_writeback_descriptor {
/** Transmit writeback descriptor complete */ /** Transmit writeback descriptor complete */
#define INTELXL_TX_WB_FL_DD 0x01 #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 */ /** Receive data descriptor */
struct intelxl_rx_data_descriptor { struct intelxl_rx_data_descriptor {
/** Buffer address */ /** Buffer address */
@ -612,7 +623,7 @@ struct intelxl_rx_data_descriptor {
/** Flags */ /** Flags */
uint32_t flags; uint32_t flags;
/** Reserved */ /** Reserved */
uint8_t reserved[4]; uint8_t reserved[20];
} __attribute__ (( packed )); } __attribute__ (( packed ));
/** Receive writeback descriptor */ /** Receive writeback descriptor */
@ -627,6 +638,8 @@ struct intelxl_rx_writeback_descriptor {
uint32_t flags; uint32_t flags;
/** Length */ /** Length */
uint32_t len; uint32_t len;
/** Reserved */
uint8_t reserved_c[16];
} __attribute__ (( packed )); } __attribute__ (( packed ));
/** Receive writeback descriptor complete */ /** Receive writeback descriptor complete */
@ -642,21 +655,24 @@ struct intelxl_rx_writeback_descriptor {
#define INTELXL_RX_WB_LEN(len) ( ( (len) >> 6 ) & 0x3fff ) #define INTELXL_RX_WB_LEN(len) ( ( (len) >> 6 ) & 0x3fff )
/** Packet descriptor */ /** Packet descriptor */
union intelxl_descriptor { union intelxl_rx_descriptor {
/** Transmit data descriptor */
struct intelxl_tx_data_descriptor tx;
/** Transmit writeback descriptor */
struct intelxl_tx_writeback_descriptor tx_wb;
/** Receive data descriptor */ /** Receive data descriptor */
struct intelxl_rx_data_descriptor rx; struct intelxl_rx_data_descriptor data;
/** Receive writeback descriptor */ /** Receive writeback descriptor */
struct intelxl_rx_writeback_descriptor rx_wb; struct intelxl_rx_writeback_descriptor wb;
}; };
/** Descriptor ring */ /** Descriptor ring */
struct intelxl_ring { struct intelxl_ring {
/** Descriptors */ /** 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 */ /** Producer index */
unsigned int prod; unsigned int prod;
/** Consumer index */ /** Consumer index */
@ -679,14 +695,15 @@ struct intelxl_ring {
* *
* @v ring Descriptor ring * @v ring Descriptor ring
* @v count Number of descriptors * @v count Number of descriptors
* @v len Length of a single descriptor
* @v context Method to program queue context * @v context Method to program queue context
*/ */
static inline __attribute__ (( always_inline)) void 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, int ( * context ) ( struct intelxl_nic *intelxl,
physaddr_t address ) ) { physaddr_t address ) ) {
ring->len = ( count * sizeof ( ring->desc[0] ) ); ring->len = ( count * len );
ring->context = context; ring->context = context;
} }