From 3f8da985aa81e31b6e9482970f6ec594aecca552 Mon Sep 17 00:00:00 2001 From: Carl Henrik Lunde Date: Wed, 16 Sep 2015 11:10:04 +0100 Subject: [PATCH] [vmxnet3] Avoid completely filling the TX descriptor ring Modified-by: Michael Brown Signed-off-by: Michael Brown --- src/drivers/net/vmxnet3.c | 13 +++++++++---- src/drivers/net/vmxnet3.h | 3 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/drivers/net/vmxnet3.c b/src/drivers/net/vmxnet3.c index 8d4f4b843..6a54dbf89 100644 --- a/src/drivers/net/vmxnet3.c +++ b/src/drivers/net/vmxnet3.c @@ -92,19 +92,24 @@ static int vmxnet3_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct vmxnet3_nic *vmxnet = netdev_priv ( netdev ); struct vmxnet3_tx_desc *tx_desc; + unsigned int fill; unsigned int desc_idx; unsigned int generation; /* Check that we have a free transmit descriptor */ - desc_idx = ( vmxnet->count.tx_prod % VMXNET3_NUM_TX_DESC ); - generation = ( ( vmxnet->count.tx_prod & VMXNET3_NUM_TX_DESC ) ? - 0 : cpu_to_le32 ( VMXNET3_TXF_GEN ) ); - if ( vmxnet->tx_iobuf[desc_idx] ) { + fill = ( vmxnet->count.tx_prod - vmxnet->count.tx_cons ); + if ( fill >= VMXNET3_TX_FILL ) { DBGC ( vmxnet, "VMXNET3 %p out of transmit descriptors\n", vmxnet ); return -ENOBUFS; } + /* Locate transmit descriptor */ + desc_idx = ( vmxnet->count.tx_prod % VMXNET3_NUM_TX_DESC ); + generation = ( ( vmxnet->count.tx_prod & VMXNET3_NUM_TX_DESC ) ? + 0 : cpu_to_le32 ( VMXNET3_TXF_GEN ) ); + assert ( vmxnet->tx_iobuf[desc_idx] == NULL ); + /* Increment producer counter */ vmxnet->count.tx_prod++; diff --git a/src/drivers/net/vmxnet3.h b/src/drivers/net/vmxnet3.h index a1671d9dd..5e1e0cb6e 100644 --- a/src/drivers/net/vmxnet3.h +++ b/src/drivers/net/vmxnet3.h @@ -493,6 +493,9 @@ struct vmxnet3_nic { /** MTU size */ #define VMXNET3_MTU ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* FCS */ ) +/** Transmit ring maximum fill level */ +#define VMXNET3_TX_FILL ( VMXNET3_NUM_TX_DESC - 1 ) + /** Receive ring maximum fill level */ #define VMXNET3_RX_FILL 8