VMXNET3_CMD_SET_COALESCE,
        VMXNET3_CMD_REGISTER_MEMREGS,
        VMXNET3_CMD_SET_RSS_FIELDS,
+       VMXNET3_CMD_RESERVED4,
+       VMXNET3_CMD_RESERVED5,
+       VMXNET3_CMD_SET_RING_BUFFER_SIZE,
 
        VMXNET3_CMD_FIRST_GET = 0xF00D0000,
        VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
        VMXNET3_RSS_FIELDS_ESPIP6 = 0x0020,
 };
 
+struct Vmxnet3_RingBufferSize {
+       __le16             ring1BufSizeType0;
+       __le16             ring1BufSizeType1;
+       __le16             ring2BufSizeType1;
+       __le16             pad;
+};
+
 /* If the command data <= 16 bytes, use the shared memory directly.
  * otherwise, use variable length configuration descriptor.
  */
        struct Vmxnet3_VariableLenConfDesc      varConf;
        struct Vmxnet3_SetPolling               setPolling;
        enum   Vmxnet3_RSSField                 setRssFields;
+       struct Vmxnet3_RingBufferSize           ringBufSize;
        __le64                                  data[2];
 };
 
 
        /* the rest are already zeroed */
 }
 
+static void
+vmxnet3_init_bufsize(struct vmxnet3_adapter *adapter)
+{
+       struct Vmxnet3_DriverShared *shared = adapter->shared;
+       union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
+       unsigned long flags;
+
+       if (!VMXNET3_VERSION_GE_7(adapter))
+               return;
+
+       cmdInfo->ringBufSize = adapter->ringBufSize;
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_SET_RING_BUFFER_SIZE);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+}
+
 static void
 vmxnet3_init_coalesce(struct vmxnet3_adapter *adapter)
 {
                goto activate_err;
        }
 
+       vmxnet3_init_bufsize(adapter);
        vmxnet3_init_coalesce(adapter);
        vmxnet3_init_rssfields(adapter);
 
 vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
 {
        size_t sz, i, ring0_size, ring1_size, comp_size;
-       if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
-                                   VMXNET3_MAX_ETH_HDR_SIZE) {
-               adapter->skb_buf_size = adapter->netdev->mtu +
-                                       VMXNET3_MAX_ETH_HDR_SIZE;
-               if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE)
-                       adapter->skb_buf_size = VMXNET3_MIN_T0_BUF_SIZE;
-
-               adapter->rx_buf_per_pkt = 1;
+       /* With version7 ring1 will have only T0 buffers */
+       if (!VMXNET3_VERSION_GE_7(adapter)) {
+               if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
+                                           VMXNET3_MAX_ETH_HDR_SIZE) {
+                       adapter->skb_buf_size = adapter->netdev->mtu +
+                                               VMXNET3_MAX_ETH_HDR_SIZE;
+                       if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE)
+                               adapter->skb_buf_size = VMXNET3_MIN_T0_BUF_SIZE;
+
+                       adapter->rx_buf_per_pkt = 1;
+               } else {
+                       adapter->skb_buf_size = VMXNET3_MAX_SKB_BUF_SIZE;
+                       sz = adapter->netdev->mtu - VMXNET3_MAX_SKB_BUF_SIZE +
+                                                   VMXNET3_MAX_ETH_HDR_SIZE;
+                       adapter->rx_buf_per_pkt = 1 + (sz + PAGE_SIZE - 1) / PAGE_SIZE;
+               }
        } else {
-               adapter->skb_buf_size = VMXNET3_MAX_SKB_BUF_SIZE;
-               sz = adapter->netdev->mtu - VMXNET3_MAX_SKB_BUF_SIZE +
-                                           VMXNET3_MAX_ETH_HDR_SIZE;
-               adapter->rx_buf_per_pkt = 1 + (sz + PAGE_SIZE - 1) / PAGE_SIZE;
+               adapter->skb_buf_size = min((int)adapter->netdev->mtu + VMXNET3_MAX_ETH_HDR_SIZE,
+                                           VMXNET3_MAX_SKB_BUF_SIZE);
+               adapter->rx_buf_per_pkt = 1;
+               adapter->ringBufSize.ring1BufSizeType0 = cpu_to_le16(adapter->skb_buf_size);
+               adapter->ringBufSize.ring1BufSizeType1 = 0;
+               adapter->ringBufSize.ring2BufSizeType1 = cpu_to_le16(PAGE_SIZE);
        }
 
        /*
        ring1_size = (ring1_size + sz - 1) / sz * sz;
        ring1_size = min_t(u32, ring1_size, VMXNET3_RX_RING2_MAX_SIZE /
                           sz * sz);
+       /* For v7 and later, keep ring size power of 2 for UPT */
+       if (VMXNET3_VERSION_GE_7(adapter)) {
+               ring0_size = rounddown_pow_of_two(ring0_size);
+               ring1_size = rounddown_pow_of_two(ring1_size);
+       }
        comp_size = ring0_size + ring1_size;
 
        for (i = 0; i < adapter->num_rx_queues; i++) {