Commit c7112ebd authored by Ronak Doshi's avatar Ronak Doshi Committed by Paolo Abeni

vmxnet3: add command to set ring buffer sizes

This patch adds a new command to set ring buffer sizes. This is
required to pass the buffer size information to passthrough devices.
For performance reasons, with version7 and later, ring1 will contain
only mtu size buffers (bound to 3K). Packets > 3K will use both ring1
and ring2.

Also, ring sizes are round down to power of 2 and ring2 default
size is increased to 512.
Signed-off-by: default avatarRonak Doshi <doshir@vmware.com>
Acked-by: default avatarGuolin Yang <gyang@vmware.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 2c5a5748
...@@ -99,6 +99,9 @@ enum { ...@@ -99,6 +99,9 @@ enum {
VMXNET3_CMD_SET_COALESCE, VMXNET3_CMD_SET_COALESCE,
VMXNET3_CMD_REGISTER_MEMREGS, VMXNET3_CMD_REGISTER_MEMREGS,
VMXNET3_CMD_SET_RSS_FIELDS, VMXNET3_CMD_SET_RSS_FIELDS,
VMXNET3_CMD_RESERVED4,
VMXNET3_CMD_RESERVED5,
VMXNET3_CMD_SET_RING_BUFFER_SIZE,
VMXNET3_CMD_FIRST_GET = 0xF00D0000, VMXNET3_CMD_FIRST_GET = 0xF00D0000,
VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET, VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
...@@ -743,6 +746,13 @@ enum Vmxnet3_RSSField { ...@@ -743,6 +746,13 @@ enum Vmxnet3_RSSField {
VMXNET3_RSS_FIELDS_ESPIP6 = 0x0020, 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. /* If the command data <= 16 bytes, use the shared memory directly.
* otherwise, use variable length configuration descriptor. * otherwise, use variable length configuration descriptor.
*/ */
...@@ -750,6 +760,7 @@ union Vmxnet3_CmdInfo { ...@@ -750,6 +760,7 @@ union Vmxnet3_CmdInfo {
struct Vmxnet3_VariableLenConfDesc varConf; struct Vmxnet3_VariableLenConfDesc varConf;
struct Vmxnet3_SetPolling setPolling; struct Vmxnet3_SetPolling setPolling;
enum Vmxnet3_RSSField setRssFields; enum Vmxnet3_RSSField setRssFields;
struct Vmxnet3_RingBufferSize ringBufSize;
__le64 data[2]; __le64 data[2];
}; };
......
...@@ -2680,6 +2680,23 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) ...@@ -2680,6 +2680,23 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
/* the rest are already zeroed */ /* 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 static void
vmxnet3_init_coalesce(struct vmxnet3_adapter *adapter) vmxnet3_init_coalesce(struct vmxnet3_adapter *adapter)
{ {
...@@ -2818,6 +2835,7 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) ...@@ -2818,6 +2835,7 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
goto activate_err; goto activate_err;
} }
vmxnet3_init_bufsize(adapter);
vmxnet3_init_coalesce(adapter); vmxnet3_init_coalesce(adapter);
vmxnet3_init_rssfields(adapter); vmxnet3_init_rssfields(adapter);
...@@ -2991,19 +3009,29 @@ static void ...@@ -2991,19 +3009,29 @@ static void
vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter) vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
{ {
size_t sz, i, ring0_size, ring1_size, comp_size; size_t sz, i, ring0_size, ring1_size, comp_size;
if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE - /* With version7 ring1 will have only T0 buffers */
VMXNET3_MAX_ETH_HDR_SIZE) { if (!VMXNET3_VERSION_GE_7(adapter)) {
adapter->skb_buf_size = adapter->netdev->mtu + if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
VMXNET3_MAX_ETH_HDR_SIZE; VMXNET3_MAX_ETH_HDR_SIZE) {
if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE) adapter->skb_buf_size = adapter->netdev->mtu +
adapter->skb_buf_size = VMXNET3_MIN_T0_BUF_SIZE; VMXNET3_MAX_ETH_HDR_SIZE;
if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE)
adapter->rx_buf_per_pkt = 1; 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 { } else {
adapter->skb_buf_size = VMXNET3_MAX_SKB_BUF_SIZE; adapter->skb_buf_size = min((int)adapter->netdev->mtu + VMXNET3_MAX_ETH_HDR_SIZE,
sz = adapter->netdev->mtu - VMXNET3_MAX_SKB_BUF_SIZE + VMXNET3_MAX_SKB_BUF_SIZE);
VMXNET3_MAX_ETH_HDR_SIZE; adapter->rx_buf_per_pkt = 1;
adapter->rx_buf_per_pkt = 1 + (sz + PAGE_SIZE - 1) / PAGE_SIZE; adapter->ringBufSize.ring1BufSizeType0 = cpu_to_le16(adapter->skb_buf_size);
adapter->ringBufSize.ring1BufSizeType1 = 0;
adapter->ringBufSize.ring2BufSizeType1 = cpu_to_le16(PAGE_SIZE);
} }
/* /*
...@@ -3019,6 +3047,11 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter) ...@@ -3019,6 +3047,11 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
ring1_size = (ring1_size + sz - 1) / sz * sz; ring1_size = (ring1_size + sz - 1) / sz * sz;
ring1_size = min_t(u32, ring1_size, VMXNET3_RX_RING2_MAX_SIZE / ring1_size = min_t(u32, ring1_size, VMXNET3_RX_RING2_MAX_SIZE /
sz * sz); 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; comp_size = ring0_size + ring1_size;
for (i = 0; i < adapter->num_rx_queues; i++) { for (i = 0; i < adapter->num_rx_queues; i++) {
......
...@@ -718,6 +718,13 @@ vmxnet3_set_ringparam(struct net_device *netdev, ...@@ -718,6 +718,13 @@ vmxnet3_set_ringparam(struct net_device *netdev,
new_rx_ring2_size = min_t(u32, new_rx_ring2_size, new_rx_ring2_size = min_t(u32, new_rx_ring2_size,
VMXNET3_RX_RING2_MAX_SIZE); VMXNET3_RX_RING2_MAX_SIZE);
/* For v7 and later, keep ring size power of 2 for UPT */
if (VMXNET3_VERSION_GE_7(adapter)) {
new_tx_ring_size = rounddown_pow_of_two(new_tx_ring_size);
new_rx_ring_size = rounddown_pow_of_two(new_rx_ring_size);
new_rx_ring2_size = rounddown_pow_of_two(new_rx_ring2_size);
}
/* rx data ring buffer size has to be a multiple of /* rx data ring buffer size has to be a multiple of
* VMXNET3_RXDATA_DESC_SIZE_ALIGN * VMXNET3_RXDATA_DESC_SIZE_ALIGN
*/ */
......
...@@ -408,6 +408,7 @@ struct vmxnet3_adapter { ...@@ -408,6 +408,7 @@ struct vmxnet3_adapter {
dma_addr_t pm_conf_pa; dma_addr_t pm_conf_pa;
dma_addr_t rss_conf_pa; dma_addr_t rss_conf_pa;
bool queuesExtEnabled; bool queuesExtEnabled;
struct Vmxnet3_RingBufferSize ringBufSize;
u32 devcap_supported[8]; u32 devcap_supported[8];
u32 ptcap_supported[8]; u32 ptcap_supported[8];
u32 dev_caps[8]; u32 dev_caps[8];
...@@ -449,7 +450,7 @@ struct vmxnet3_adapter { ...@@ -449,7 +450,7 @@ struct vmxnet3_adapter {
/* must be a multiple of VMXNET3_RING_SIZE_ALIGN */ /* must be a multiple of VMXNET3_RING_SIZE_ALIGN */
#define VMXNET3_DEF_TX_RING_SIZE 512 #define VMXNET3_DEF_TX_RING_SIZE 512
#define VMXNET3_DEF_RX_RING_SIZE 1024 #define VMXNET3_DEF_RX_RING_SIZE 1024
#define VMXNET3_DEF_RX_RING2_SIZE 256 #define VMXNET3_DEF_RX_RING2_SIZE 512
#define VMXNET3_DEF_RXDATA_DESC_SIZE 128 #define VMXNET3_DEF_RXDATA_DESC_SIZE 128
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment