Driver: Vmxnet3: Make Rx ring 2 size configurable
[firefly-linux-kernel-4.4.55.git] / drivers / net / vmxnet3 / vmxnet3_ethtool.c
index b7b53329d5751676b6a9daf4c9cff9bb4ce923ad..8a5a90eeb4f9ebe9dca18562af7f8d6b991d1c6b 100644 (file)
@@ -447,12 +447,12 @@ vmxnet3_get_ringparam(struct net_device *netdev,
        param->rx_max_pending = VMXNET3_RX_RING_MAX_SIZE;
        param->tx_max_pending = VMXNET3_TX_RING_MAX_SIZE;
        param->rx_mini_max_pending = 0;
-       param->rx_jumbo_max_pending = 0;
+       param->rx_jumbo_max_pending = VMXNET3_RX_RING2_MAX_SIZE;
 
        param->rx_pending = adapter->rx_ring_size;
        param->tx_pending = adapter->tx_ring_size;
        param->rx_mini_pending = 0;
-       param->rx_jumbo_pending = 0;
+       param->rx_jumbo_pending = adapter->rx_ring2_size;
 }
 
 
@@ -461,7 +461,7 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                      struct ethtool_ringparam *param)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-       u32 new_tx_ring_size, new_rx_ring_size;
+       u32 new_tx_ring_size, new_rx_ring_size, new_rx_ring2_size;
        u32 sz;
        int err = 0;
 
@@ -473,6 +473,10 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                                                VMXNET3_RX_RING_MAX_SIZE)
                return -EINVAL;
 
+       if (param->rx_jumbo_pending == 0 ||
+           param->rx_jumbo_pending > VMXNET3_RX_RING2_MAX_SIZE)
+               return -EINVAL;
+
        /* if adapter not yet initialized, do nothing */
        if (adapter->rx_buf_per_pkt == 0) {
                netdev_err(netdev, "adapter not completely initialized, "
@@ -500,8 +504,15 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                                                           sz) != 0)
                return -EINVAL;
 
-       if (new_tx_ring_size == adapter->tx_queue[0].tx_ring.size &&
-           new_rx_ring_size == adapter->rx_queue[0].rx_ring[0].size) {
+       /* ring2 has to be a multiple of VMXNET3_RING_SIZE_ALIGN */
+       new_rx_ring2_size = (param->rx_jumbo_pending + VMXNET3_RING_SIZE_MASK) &
+                               ~VMXNET3_RING_SIZE_MASK;
+       new_rx_ring2_size = min_t(u32, new_rx_ring2_size,
+                                 VMXNET3_RX_RING2_MAX_SIZE);
+
+       if (new_tx_ring_size == adapter->tx_ring_size &&
+           new_rx_ring_size == adapter->rx_ring_size &&
+           new_rx_ring2_size == adapter->rx_ring2_size) {
                return 0;
        }
 
@@ -522,7 +533,7 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                vmxnet3_rq_destroy_all(adapter);
 
                err = vmxnet3_create_queues(adapter, new_tx_ring_size,
-                       new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE);
+                       new_rx_ring_size, new_rx_ring2_size);
 
                if (err) {
                        /* failed, most likely because of OOM, try default
@@ -530,11 +541,12 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                        netdev_err(netdev, "failed to apply new sizes, "
                                   "try the default ones\n");
                        new_rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
+                       new_rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE;
                        new_tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;
                        err = vmxnet3_create_queues(adapter,
                                                    new_tx_ring_size,
                                                    new_rx_ring_size,
-                                                   VMXNET3_DEF_RX_RING_SIZE);
+                                                   new_rx_ring2_size);
                        if (err) {
                                netdev_err(netdev, "failed to create queues "
                                           "with default sizes. Closing it\n");
@@ -549,6 +561,7 @@ vmxnet3_set_ringparam(struct net_device *netdev,
        }
        adapter->tx_ring_size = new_tx_ring_size;
        adapter->rx_ring_size = new_rx_ring_size;
+       adapter->rx_ring2_size = new_rx_ring2_size;
 
 out:
        clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);