]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[vmxnet3] Avoid completely filling the TX descriptor ring
authorCarl Henrik Lunde <chlunde@ping.uio.no>
Wed, 16 Sep 2015 10:10:04 +0000 (11:10 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 16 Sep 2015 10:10:30 +0000 (11:10 +0100)
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/vmxnet3.c
src/drivers/net/vmxnet3.h

index 8d4f4b84348787f18e54b6693c9ac33f32233918..6a54dbf890c16d731e5d9390c490d279550d05b7 100644 (file)
@@ -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++;
 
index a1671d9ddee9b368fda646a7043c22c2036987d7..5e1e0cb6e839f081d93b44074e604c5718e1b9a9 100644 (file)
@@ -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