From a7f313e87f0b4df7f9f15b7f2f52dd0118a0b3f6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 14 Mar 2017 10:15:27 -0700 Subject: [PATCH] i40e/i40evf: Change the way we limit the maximum frame size for Rx This patch changes the way we handle the maximum frame size for the Rx path. Previously we were rounding up to 2K for a 1500 MTU and then brining the max frame size down to MTU plus a fixed amount. With this patch applied what we now do is limit the maximum frame to 1.5K minus the value for NET_IP_ALIGN for standard MTU, and for any MTU greater than 1500 we allow up to the maximum frame size. This makes the behavior more consistent with the other drivers such as igb which had similar logic. In addition it reduces the test matrix for MTU since we only have two max frame sizes that are handled for Rx now. Change-ID: I23a9d3c857e7df04b0ef28c64df63e659c013f3f Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Orabug: 26785018 (cherry picked from commit dab86afdbbd1bc5d5a89b67ed141d2f46c3b4191) Signed-off-by: Jack Vogel Reviewed-by: Kyle Fortin --- drivers/net/ethernet/intel/i40e/i40e_main.c | 33 ++++++++----------- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 4 +-- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 4 +-- drivers/net/ethernet/intel/i40evf/i40evf.h | 4 --- .../net/ethernet/intel/i40evf/i40evf_main.c | 16 ++++++++- .../ethernet/intel/i40evf/i40evf_virtchnl.c | 14 +++++--- 6 files changed, 40 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 6fcabd594dba..458d295767b0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3051,7 +3051,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) ring->rx_buf_len = vsi->rx_buf_len; - rx_ctx.dbuff = ring->rx_buf_len >> I40E_RXQ_CTX_DBUFF_SHIFT; + rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len, + BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT)); rx_ctx.base = (ring->dma / 128); rx_ctx.qlen = ring->count; @@ -3134,27 +3135,19 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi) int err = 0; u16 i; - if (vsi->netdev && (vsi->netdev->mtu > ETH_DATA_LEN)) - vsi->max_frame = vsi->netdev->mtu + ETH_HLEN - + ETH_FCS_LEN + VLAN_HLEN; - else - vsi->max_frame = I40E_RXBUFFER_2048; - - vsi->rx_buf_len = I40E_RXBUFFER_2048; - -#ifdef I40E_FCOE - /* setup rx buffer for FCoE */ - if ((vsi->type == I40E_VSI_FCOE) && - (vsi->back->flags & I40E_FLAG_FCOE_ENABLED)) { - vsi->rx_buf_len = I40E_RXBUFFER_3072; - vsi->max_frame = I40E_RXBUFFER_3072; + if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) { + vsi->max_frame = I40E_MAX_RXBUFFER; + vsi->rx_buf_len = I40E_RXBUFFER_2048; +#if (PAGE_SIZE < 8192) + } else if (vsi->netdev->mtu <= ETH_DATA_LEN) { + vsi->max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN; + vsi->rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN; +#endif + } else { + vsi->max_frame = I40E_MAX_RXBUFFER; + vsi->rx_buf_len = I40E_RXBUFFER_2048; } -#endif /* I40E_FCOE */ - /* round up for the chip's needs */ - vsi->rx_buf_len = ALIGN(vsi->rx_buf_len, - BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT)); - /* set up individual rings */ for (i = 0; i < vsi->num_queue_pairs && !err; i++) err = i40e_configure_rx_ring(vsi->rx_rings[i]); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 2419b90a3f72..c25839093656 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -117,10 +117,8 @@ enum i40e_dyn_idx_t { /* Supported Rx Buffer Sizes (a multiple of 128) */ #define I40E_RXBUFFER_256 256 +#define I40E_RXBUFFER_1536 1536 /* 128B aligned standard Ethernet frame */ #define I40E_RXBUFFER_2048 2048 -#define I40E_RXBUFFER_3072 3072 /* For FCoE MTU of 2158 */ -#define I40E_RXBUFFER_4096 4096 -#define I40E_RXBUFFER_8192 8192 #define I40E_MAX_RXBUFFER 9728 /* largest size for single descriptor */ /* NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN means we diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h index 5b6a2763cbd3..cade4f4e7e7f 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h @@ -104,10 +104,8 @@ enum i40e_dyn_idx_t { /* Supported Rx Buffer Sizes (a multiple of 128) */ #define I40E_RXBUFFER_256 256 +#define I40E_RXBUFFER_1536 1536 /* 128B aligned standard Ethernet frame */ #define I40E_RXBUFFER_2048 2048 -#define I40E_RXBUFFER_3072 3072 /* For FCoE MTU of 2158 */ -#define I40E_RXBUFFER_4096 4096 -#define I40E_RXBUFFER_8192 8192 #define I40E_MAX_RXBUFFER 9728 /* largest size for single descriptor */ /* NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN means we diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index 421402bdeaf4..8d3568f307b9 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -71,10 +71,6 @@ struct i40e_vsi { #define I40EVF_MAX_RXD 4096 #define I40EVF_MIN_RXD 64 #define I40EVF_REQ_DESCRIPTOR_MULTIPLE 32 - -/* Supported Rx Buffer Sizes */ -#define I40EVF_RXBUFFER_2048 2048 -#define I40EVF_MAX_RXBUFFER 16384 /* largest size for single descriptor */ #define I40EVF_MAX_AQ_BUF_SIZE 4096 #define I40EVF_AQ_LEN 32 #define I40EVF_AQ_MAX_ERR 20 /* times to try before resetting AQ */ diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 882839992f13..f7223bb09e56 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -687,12 +687,26 @@ static void i40evf_configure_tx(struct i40evf_adapter *adapter) **/ static void i40evf_configure_rx(struct i40evf_adapter *adapter) { + unsigned int rx_buf_len = I40E_RXBUFFER_2048; + struct net_device *netdev = adapter->netdev; struct i40e_hw *hw = &adapter->hw; int i; + /* Legacy Rx will always default to a 2048 buffer size. */ +#if (PAGE_SIZE < 8192) + if (!(adapter->flags & I40EVF_FLAG_LEGACY_RX)) { + /* We use a 1536 buffer size for configurations with + * standard Ethernet mtu. On x86 this gives us enough room + * for shared info and 192 bytes of padding. + */ + if (netdev->mtu <= ETH_DATA_LEN) + rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN; + } +#endif + for (i = 0; i < adapter->num_active_queues; i++) { adapter->rx_rings[i].tail = hw->hw_addr + I40E_QRX_TAIL1(i); - adapter->rx_rings[i].rx_buf_len = I40EVF_RXBUFFER_2048; + adapter->rx_rings[i].rx_buf_len = rx_buf_len; } } diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index 519b5cf2c48a..09dcf5b97bc2 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -233,7 +233,7 @@ void i40evf_configure_queues(struct i40evf_adapter *adapter) struct i40e_virtchnl_vsi_queue_config_info *vqci; struct i40e_virtchnl_queue_pair_info *vqpi; int pairs = adapter->num_active_queues; - int i, len; + int i, len, max_frame = I40E_MAX_RXBUFFER; if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { /* bail because we already have a command pending */ @@ -248,6 +248,11 @@ void i40evf_configure_queues(struct i40evf_adapter *adapter) if (!vqci) return; + /* Limit maximum frame size when jumbo frames is not enabled */ + if (!(adapter->flags & I40EVF_FLAG_LEGACY_RX) && + (adapter->netdev->mtu <= ETH_DATA_LEN)) + max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN; + vqci->vsi_id = adapter->vsi_res->vsi_id; vqci->num_queue_pairs = pairs; vqpi = vqci->qpair; @@ -263,9 +268,10 @@ void i40evf_configure_queues(struct i40evf_adapter *adapter) vqpi->rxq.queue_id = i; vqpi->rxq.ring_len = adapter->rx_rings[i].count; vqpi->rxq.dma_ring_addr = adapter->rx_rings[i].dma; - vqpi->rxq.max_pkt_size = adapter->netdev->mtu - + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; - vqpi->rxq.databuffer_size = adapter->rx_rings[i].rx_buf_len; + vqpi->rxq.max_pkt_size = max_frame; + vqpi->rxq.databuffer_size = + ALIGN(adapter->rx_rings[i].rx_buf_len, + BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT)); vqpi++; } -- 2.50.1