From 0dd8357f8fab1d82aa8fc8267261203f393d5a1f Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Wed, 15 Jan 2014 08:38:35 +0000 Subject: i40e: remove ptp_tx_work timestamp work item This patch removes the unnecessary ptp_tx_work item. It conflicts with the interrupt-based handler, and will cause spurious warning messages to be displayed in the kernel log. Since the hardware can properly trigger an interrupt, we do not need to poll for an available timestamp in a work queue any more. Signed-off-by: Jacob Keller Acked-by: Jesse Brandeburg Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 9478ddc66caf..ece7ae99b03a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1825,9 +1825,6 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb, *cd_type_cmd_tso_mss |= (u64)I40E_TX_CTX_DESC_TSYN << I40E_TXD_CTX_QW1_CMD_SHIFT; - pf->ptp_tx_start = jiffies; - schedule_work(&pf->ptp_tx_work); - return 1; } -- cgit v1.2.3 From 1c112a6475c157d2f59cace533e3ce825ce49024 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 4 Apr 2014 04:43:06 +0000 Subject: i40e: add required include On some architectures, this header must be explicitly included. Change-ID: I4bc2eb0531956a7b676489f79d347d55cfe12421 Signed-off-by: Mitch Williams Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 4 ---- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index a46571c1e9f1..ef5bb11557e5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -97,10 +97,6 @@ #define STRINGIFY(foo) #foo #define XSTRINGIFY(bar) STRINGIFY(bar) -#ifndef ARCH_HAS_PREFETCH -#define prefetch(X) -#endif - #define I40E_RX_DESC(R, i) \ ((ring_is_16byte_desc_enabled(R)) \ ? (union i40e_32byte_rx_desc *) \ diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index ece7ae99b03a..8d0ef445fa44 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -24,6 +24,7 @@ * ******************************************************************************/ +#include #include "i40e.h" #include "i40e_prototype.h" -- cgit v1.2.3 From b2d36c03ef0ad2d373fa5db2dcc54f8ee5d65545 Mon Sep 17 00:00:00 2001 From: Kevin Scott Date: Wed, 9 Apr 2014 05:58:59 +0000 Subject: i40e/i40evf: Remove reserved PCTYPE defines Patch to remove PCTYPE definitions which are now reserved. Change-ID: I66c1c16a45a16f4894b2983101ab2a48ce03f1f4 Signed-off-by: Kevin Scott Signed-off-by: Shannon Nelson Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 24 +++++++-------------- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 29 +++++++++++--------------- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 5 ----- drivers/net/ethernet/intel/i40e/i40e_type.h | 10 +++------ drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 5 ----- drivers/net/ethernet/intel/i40evf/i40e_type.h | 10 +++------ 6 files changed, 26 insertions(+), 57 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index a7bf14953c95..8a6fef27a6d3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1288,16 +1288,12 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc) case UDP_V4_FLOW: switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { case 0: - hena &= - ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4)); + hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) | + ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4)); break; case (RXH_L4_B_0_1 | RXH_L4_B_2_3): - hena |= - (((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4)); + hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) | + ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4)); break; default: return -EINVAL; @@ -1306,16 +1302,12 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc) case UDP_V6_FLOW: switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { case 0: - hena &= - ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6)); + hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | + ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6)); break; case (RXH_L4_B_0_1 | RXH_L4_B_2_3): - hena |= - (((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) | - ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6)); + hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | + ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6)); break; default: return -EINVAL; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 8d0ef445fa44..1ecd9aa9470a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -184,7 +184,6 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi, struct iphdr *ip; bool err = false; int ret; - int i; static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0, 0x45, 0, 0, 0x1c, 0, 0, 0x40, 0, 0x40, 0x11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -200,21 +199,17 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi, ip->saddr = fd_data->src_ip[0]; udp->source = fd_data->src_port; - for (i = I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP; - i <= I40E_FILTER_PCTYPE_NONF_IPV4_UDP; i++) { - fd_data->pctype = i; - ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add); - - if (ret) { - dev_info(&pf->pdev->dev, - "Filter command send failed for PCTYPE %d (ret = %d)\n", - fd_data->pctype, ret); - err = true; - } else { - dev_info(&pf->pdev->dev, - "Filter OK for PCTYPE %d (ret = %d)\n", - fd_data->pctype, ret); - } + fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; + ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add); + if (ret) { + dev_info(&pf->pdev->dev, + "Filter command send failed for PCTYPE %d (ret = %d)\n", + fd_data->pctype, ret); + err = true; + } else { + dev_info(&pf->pdev->dev, + "Filter OK for PCTYPE %d (ret = %d)\n", + fd_data->pctype, ret); } return err ? -EOPNOTSUPP : 0; @@ -263,7 +258,7 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi, } } - fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN; + fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add); if (ret) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index d5349698e513..71fbba9431eb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -69,16 +69,11 @@ enum i40e_dyn_idx_t { /* Supported RSS offloads */ #define I40E_DEFAULT_RSS_HENA ( \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) | \ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) | \ diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index c4df8bac2db1..0fe158c64246 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -866,18 +866,14 @@ struct i40e_filter_program_desc { /* Packet Classifier Types for filters */ enum i40e_filter_pctype { - /* Note: Values 0-28 are reserved for future use */ - I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP = 29, - I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP = 30, + /* Note: Values 0-30 are reserved for future use */ I40E_FILTER_PCTYPE_NONF_IPV4_UDP = 31, - I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN = 32, + /* Note: Value 32 is reserved for future use */ I40E_FILTER_PCTYPE_NONF_IPV4_TCP = 33, I40E_FILTER_PCTYPE_NONF_IPV4_SCTP = 34, I40E_FILTER_PCTYPE_NONF_IPV4_OTHER = 35, I40E_FILTER_PCTYPE_FRAG_IPV4 = 36, - /* Note: Values 37-38 are reserved for future use */ - I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP = 39, - I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP = 40, + /* Note: Values 37-40 are reserved for future use */ I40E_FILTER_PCTYPE_NONF_IPV6_UDP = 41, I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN = 42, I40E_FILTER_PCTYPE_NONF_IPV6_TCP = 43, diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h index d0119d0a9fcf..a23c34e3d0f6 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h @@ -69,16 +69,11 @@ enum i40e_dyn_idx_t { /* Supported RSS offloads */ #define I40E_DEFAULT_RSS_HENA ( \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) | \ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | \ - ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN) | \ ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) | \ diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h index fb5371ad1cb9..c854cca6f203 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_type.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h @@ -866,18 +866,14 @@ struct i40e_filter_program_desc { /* Packet Classifier Types for filters */ enum i40e_filter_pctype { - /* Note: Values 0-28 are reserved for future use */ - I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP = 29, - I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP = 30, + /* Note: Values 0-30 are reserved for future use */ I40E_FILTER_PCTYPE_NONF_IPV4_UDP = 31, - I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN = 32, + /* Note: Value 32 is reserved for future use */ I40E_FILTER_PCTYPE_NONF_IPV4_TCP = 33, I40E_FILTER_PCTYPE_NONF_IPV4_SCTP = 34, I40E_FILTER_PCTYPE_NONF_IPV4_OTHER = 35, I40E_FILTER_PCTYPE_FRAG_IPV4 = 36, - /* Note: Values 37-38 are reserved for future use */ - I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP = 39, - I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP = 40, + /* Note: Values 37-40 are reserved for future use */ I40E_FILTER_PCTYPE_NONF_IPV6_UDP = 41, I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN = 42, I40E_FILTER_PCTYPE_NONF_IPV6_TCP = 43, -- cgit v1.2.3 From 89132783016ae770a5e1f1cc7660dc312e386a85 Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Wed, 9 Apr 2014 05:59:01 +0000 Subject: i40e: Use the new i40e_get_fd_cnt_all function in other places We have a function to calculate this, so update the code to use the function. Change-ID: Ia345b6fe6ec7f0b2dcf1199471b0d0f959ad3908 Signed-off-by: Anjali Singhai Jain Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 75bd99e3bac8..44fea89c384d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -4712,8 +4712,7 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf) (pf->flags & I40E_FLAG_FD_SB_ENABLED)) return; fcnt_prog = i40e_get_current_fd_count(pf); - fcnt_avail = pf->hw.fdir_shared_filter_count + - pf->fdir_pf_filter_count; + fcnt_avail = i40e_get_fd_cnt_all(pf); if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) { if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) && (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 1ecd9aa9470a..5a2218762db1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -451,9 +451,7 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring, /* filter programming failed most likely due to table full */ fcnt_prog = i40e_get_current_fd_count(pf); - fcnt_avail = pf->hw.fdir_shared_filter_count + - pf->fdir_pf_filter_count; - + fcnt_avail = i40e_get_fd_cnt_all(pf); /* If ATR is running fcnt_prog can quickly change, * if we are very close to full, it makes sense to disable * FD ATR/SB and then re-enable it when there is room. -- cgit v1.2.3 From d3a90b70d8ffe6dd82a3fa22515a2ebc399aca28 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 16 Apr 2014 01:21:40 +0000 Subject: i40e: don't use OR to check a value A couple of FD checks ended up using bitwise OR to check a value, which ends up always being evaluated to true. This should fix the issue. Thanks to DaveJ for noticing and reporting the issue! CC: Dave Jones Reported-by: Dave Jones Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 5a2218762db1..1fe28ca18296 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -458,13 +458,13 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring, */ if (fcnt_prog >= (fcnt_avail - I40E_FDIR_BUFFER_FULL_MARGIN)) { /* Turn off ATR first */ - if (pf->flags | I40E_FLAG_FD_ATR_ENABLED) { + if (pf->flags & I40E_FLAG_FD_ATR_ENABLED) { pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED; dev_warn(&pdev->dev, "FD filter space full, ATR for further flows will be turned off\n"); pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED; pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT; - } else if (pf->flags | I40E_FLAG_FD_SB_ENABLED) { + } else if (pf->flags & I40E_FLAG_FD_SB_ENABLED) { pf->flags &= ~I40E_FLAG_FD_SB_ENABLED; dev_warn(&pdev->dev, "FD filter space full, new ntuple rules will not be added\n"); pf->auto_disable_flags |= -- cgit v1.2.3 From 980093ebf777f95459eabcf0ca7a29db7e9a10f7 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Sat, 10 May 2014 04:49:12 +0000 Subject: i40e/i40evf: fix TSO accounting The TSO logic in the transmit path had some assumptions that have been broken now that the kernel can send as much as 32kB in a single skb->frag[.] entry, even on a system with 4kB pages. This fixes the assumptions and allows the kernel to operate as efficiently as possible with both SENDFILE and SEND. In addition, the hardware limit of data contained in a descriptor is changed to the next power of two below where it currently is in order to align to a power of two value, preventing a single byte of data in a descriptor. Change-ID: I6af1f0b87c1458e10644dbd47541591075a52651 Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 7 +------ drivers/net/ethernet/intel/i40e/i40e_txrx.h | 4 ++-- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 7 +------ drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 4 ++-- 4 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 1fe28ca18296..d1a9a0512b93 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2170,9 +2170,7 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) static int i40e_xmit_descriptor_count(struct sk_buff *skb, struct i40e_ring *tx_ring) { -#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD unsigned int f; -#endif int count = 0; /* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD, @@ -2181,12 +2179,9 @@ static int i40e_xmit_descriptor_count(struct sk_buff *skb, * + 1 desc for context descriptor, * otherwise try next time */ -#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); -#else - count += skb_shinfo(skb)->nr_frags; -#endif + count += TXD_USE_COUNT(skb_headlen(skb)); if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) { tx_ring->tx_stats.tx_busy++; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 30e5fe35fa3d..0277894fe1c4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -117,11 +117,11 @@ enum i40e_dyn_idx_t { #define i40e_rx_desc i40e_32byte_rx_desc #define I40E_MIN_TX_LEN 17 -#define I40E_MAX_DATA_PER_TXD 16383 /* aka 16kB - 1 */ +#define I40E_MAX_DATA_PER_TXD 8192 /* Tx Descriptors needed, worst case */ #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD) -#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4) +#define DESC_NEEDED (MAX_SKB_FRAGS + 4) #define I40E_TX_FLAGS_CSUM (u32)(1) #define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1) diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 82d6844245b5..ae089df7df19 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1511,9 +1511,7 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) static int i40e_xmit_descriptor_count(struct sk_buff *skb, struct i40e_ring *tx_ring) { -#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD unsigned int f; -#endif int count = 0; /* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD, @@ -1522,12 +1520,9 @@ static int i40e_xmit_descriptor_count(struct sk_buff *skb, * + 1 desc for context descriptor, * otherwise try next time */ -#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); -#else - count += skb_shinfo(skb)->nr_frags; -#endif + count += TXD_USE_COUNT(skb_headlen(skb)); if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) { tx_ring->tx_stats.tx_busy++; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h index e297a3aba0f2..30d248bc5d19 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h @@ -117,11 +117,11 @@ enum i40e_dyn_idx_t { #define i40e_rx_desc i40e_32byte_rx_desc #define I40E_MIN_TX_LEN 17 -#define I40E_MAX_DATA_PER_TXD 16383 /* aka 16kB - 1 */ +#define I40E_MAX_DATA_PER_TXD 8192 /* Tx Descriptors needed, worst case */ #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD) -#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4) +#define DESC_NEEDED (MAX_SKB_FRAGS + 4) #define I40E_TX_FLAGS_CSUM (u32)(1) #define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1) -- cgit v1.2.3 From 505682cd7baba79b52f6c9df49224307fb6d34ef Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 20 May 2014 08:01:37 +0000 Subject: i40e: allow for more VSIs The number of VSIs that the firmware reports to us is a guaranteed minimum, not an absolute maximum. The hardware actually supports far more than the reported value, which we often need. To allow for this, we allocate space for a larger number of VSIs than is guaranteed by the firmware, with the knowledge that we may fail to get them all in the future. Note that we are just allocating pointers here, the actual (much larger) VSI structures are allocated on demand. Change-ID: I6f4e535ce39d3bf417aef78306e04fbc7505140e Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 2 + drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 6 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 68 ++++++++++++++------------ drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 5 files changed, 45 insertions(+), 35 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index dc6d7c6fb060..ebeaf95b9521 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -72,6 +72,7 @@ #define I40E_MIN_NUM_DESCRIPTORS 64 #define I40E_MIN_MSIX 2 #define I40E_DEFAULT_NUM_VMDQ_VSI 8 /* max 256 VSIs */ +#define I40E_MIN_VSI_ALLOC 51 /* LAN, ATR, FCOE, 32 VF, 16 VMDQ */ #define I40E_DEFAULT_QUEUES_PER_VMDQ 2 /* max 16 qps */ #define I40E_DEFAULT_QUEUES_PER_VF 4 #define I40E_DEFAULT_QUEUES_PER_TC 1 /* should be a power of 2 */ @@ -215,6 +216,7 @@ struct i40e_pf { u16 rss_size; /* num queues in the RSS array */ u16 rss_size_max; /* HW defined max RSS queues */ u16 fdir_pf_filter_count; /* num of guaranteed filters for this PF */ + u16 num_alloc_vsi; /* num VSIs this driver supports */ u8 atr_sample_rate; bool wol_en; diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c index 6e8103abfd0d..871831a535d0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c @@ -232,7 +232,7 @@ static void i40e_dcbnl_del_app(struct i40e_pf *pf, struct i40e_ieee_app_priority_table *app) { int v, err; - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v] && pf->vsi[v]->netdev) { err = i40e_dcbnl_vsi_del_app(pf->vsi[v], app); if (err) diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 1bd0adb38735..cffdfc21290f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -45,7 +45,7 @@ static struct i40e_vsi *i40e_dbg_find_vsi(struct i40e_pf *pf, int seid) if (seid < 0) dev_info(&pf->pdev->dev, "%d: bad seid\n", seid); else - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) if (pf->vsi[i] && (pf->vsi[i]->seid == seid)) return pf->vsi[i]; @@ -843,7 +843,7 @@ static void i40e_dbg_dump_vsi_no_seid(struct i40e_pf *pf) { int i; - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) if (pf->vsi[i]) dev_info(&pf->pdev->dev, "dump vsi[%d]: %d\n", i, pf->vsi[i]->seid); @@ -1526,7 +1526,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp, cnt = sscanf(&cmd_buf[15], "%i", &vsi_seid); if (cnt == 0) { int i; - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) i40e_vsi_reset_stats(pf->vsi[i]); dev_info(&pf->pdev->dev, "vsi clear stats called for all vsi's\n"); } else if (cnt == 1) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ab0b6e101c1b..d9a6c692f150 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -652,7 +652,7 @@ static void i40e_update_link_xoff_rx(struct i40e_pf *pf) return; /* Clear the __I40E_HANG_CHECK_ARMED bit for all Tx rings */ - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { struct i40e_vsi *vsi = pf->vsi[v]; if (!vsi || !vsi->tx_rings[0]) @@ -706,7 +706,7 @@ static void i40e_update_prio_xoff_rx(struct i40e_pf *pf) } /* Clear the __I40E_HANG_CHECK_ARMED bit for Tx rings */ - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { struct i40e_vsi *vsi = pf->vsi[v]; if (!vsi || !vsi->tx_rings[0]) @@ -1734,7 +1734,7 @@ static void i40e_sync_filters_subtask(struct i40e_pf *pf) return; pf->flags &= ~I40E_FLAG_FILTER_SYNC; - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v] && (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED)) i40e_sync_vsi_filters(pf->vsi[v]); @@ -3524,7 +3524,7 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf) int i; i40e_put_lump(pf->irq_pile, 0, I40E_PILE_VALID_BIT-1); - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) if (pf->vsi[i]) i40e_vsi_free_q_vectors(pf->vsi[i]); i40e_reset_interrupt_capability(pf); @@ -3614,7 +3614,7 @@ static void i40e_pf_quiesce_all_vsi(struct i40e_pf *pf) { int v; - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v]) i40e_quiesce_vsi(pf->vsi[v]); } @@ -3628,7 +3628,7 @@ static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf) { int v; - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v]) i40e_unquiesce_vsi(pf->vsi[v]); } @@ -4069,7 +4069,7 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf) } /* Update each VSI */ - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (!pf->vsi[v]) continue; @@ -4592,7 +4592,7 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags) /* Find the VSI(s) that requested a re-init */ dev_info(&pf->pdev->dev, "VSI reinit requested\n"); - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { struct i40e_vsi *vsi = pf->vsi[v]; if (vsi != NULL && test_bit(__I40E_REINIT_REQUESTED, &vsi->state)) { @@ -4919,7 +4919,7 @@ static void i40e_veb_link_event(struct i40e_veb *veb, bool link_up) i40e_veb_link_event(pf->veb[i], link_up); /* ... now the local VSIs */ - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) if (pf->vsi[i] && (pf->vsi[i]->uplink_seid == veb->seid)) i40e_vsi_link_event(pf->vsi[i], link_up); } @@ -4976,7 +4976,7 @@ static void i40e_check_hang_subtask(struct i40e_pf *pf) * for each q_vector * force an interrupt */ - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { struct i40e_vsi *vsi = pf->vsi[v]; int armed = 0; @@ -5026,7 +5026,7 @@ static void i40e_watchdog_subtask(struct i40e_pf *pf) /* Update the stats for active netdevs so the network stack * can look at updated numbers whenever it cares to */ - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) if (pf->vsi[i] && pf->vsi[i]->netdev) i40e_update_stats(pf->vsi[i]); @@ -5278,7 +5278,7 @@ static int i40e_reconstitute_veb(struct i40e_veb *veb) int ret; /* build VSI that owns this VEB, temporarily attached to base VEB */ - for (v = 0; v < pf->hw.func_caps.num_vsis && !ctl_vsi; v++) { + for (v = 0; v < pf->num_alloc_vsi && !ctl_vsi; v++) { if (pf->vsi[v] && pf->vsi[v]->veb_idx == veb->idx && pf->vsi[v]->flags & I40E_VSI_FLAG_VEB_OWNER) { @@ -5308,7 +5308,7 @@ static int i40e_reconstitute_veb(struct i40e_veb *veb) goto end_reconstitute; /* create the remaining VSIs attached to this VEB */ - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (!pf->vsi[v] || pf->vsi[v] == ctl_vsi) continue; @@ -5421,7 +5421,7 @@ static void i40e_fdir_sb_setup(struct i40e_pf *pf) /* find existing VSI and see if it needs configuring */ vsi = NULL; - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) { vsi = pf->vsi[i]; break; @@ -5451,7 +5451,7 @@ static void i40e_fdir_teardown(struct i40e_pf *pf) int i; i40e_fdir_filter_exit(pf); - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) { i40e_vsi_release(pf->vsi[i]); break; @@ -5480,7 +5480,7 @@ static int i40e_prep_for_reset(struct i40e_pf *pf) /* quiesce the VSIs and their queues that are not already DOWN */ i40e_pf_quiesce_all_vsi(pf); - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v]) pf->vsi[v]->seid = 0; } @@ -5960,15 +5960,15 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type) * find next empty vsi slot, looping back around if necessary */ i = pf->next_vsi; - while (i < pf->hw.func_caps.num_vsis && pf->vsi[i]) + while (i < pf->num_alloc_vsi && pf->vsi[i]) i++; - if (i >= pf->hw.func_caps.num_vsis) { + if (i >= pf->num_alloc_vsi) { i = 0; while (i < pf->next_vsi && pf->vsi[i]) i++; } - if (i < pf->hw.func_caps.num_vsis && !pf->vsi[i]) { + if (i < pf->num_alloc_vsi && !pf->vsi[i]) { vsi_idx = i; /* Found one! */ } else { ret = -ENODEV; @@ -7229,7 +7229,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi) * the orphan VEBs yet. We'll wait for an explicit remove request * from up the network stack. */ - for (n = 0, i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (n = 0, i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->uplink_seid == uplink_seid && (pf->vsi[i]->flags & I40E_VSI_FLAG_VEB_OWNER) == 0) { @@ -7408,7 +7408,7 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, if (!veb && uplink_seid != pf->mac_seid) { - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->seid == uplink_seid) { vsi = pf->vsi[i]; break; @@ -7651,7 +7651,7 @@ static void i40e_switch_branch_release(struct i40e_veb *branch) * NOTE: Removing the last VSI on a VEB has the SIDE EFFECT of removing * the VEB itself, so don't use (*branch) after this loop. */ - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (!pf->vsi[i]) continue; if (pf->vsi[i]->uplink_seid == branch_seid && @@ -7703,7 +7703,7 @@ void i40e_veb_release(struct i40e_veb *veb) pf = veb->pf; /* find the remaining VSI and check for extras */ - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->uplink_seid == veb->seid) { n++; vsi = pf->vsi[i]; @@ -7815,10 +7815,10 @@ struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, } /* make sure there is such a vsi and uplink */ - for (vsi_idx = 0; vsi_idx < pf->hw.func_caps.num_vsis; vsi_idx++) + for (vsi_idx = 0; vsi_idx < pf->num_alloc_vsi; vsi_idx++) if (pf->vsi[vsi_idx] && pf->vsi[vsi_idx]->seid == vsi_seid) break; - if (vsi_idx >= pf->hw.func_caps.num_vsis && vsi_seid != 0) { + if (vsi_idx >= pf->num_alloc_vsi && vsi_seid != 0) { dev_info(&pf->pdev->dev, "vsi seid %d not found\n", vsi_seid); return NULL; @@ -8484,10 +8484,18 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) i40e_determine_queue_usage(pf); i40e_init_interrupt_scheme(pf); - /* Set up the *vsi struct based on the number of VSIs in the HW, - * and set up our local tracking of the MAIN PF vsi. + /* The number of VSIs reported by the FW is the minimum guaranteed + * to us; HW supports far more and we share the remaining pool with + * the other PFs. We allocate space for more than the guarantee with + * the understanding that we might not get them all later. */ - len = sizeof(struct i40e_vsi *) * pf->hw.func_caps.num_vsis; + if (pf->hw.func_caps.num_vsis < I40E_MIN_VSI_ALLOC) + pf->num_alloc_vsi = I40E_MIN_VSI_ALLOC; + else + pf->num_alloc_vsi = pf->hw.func_caps.num_vsis; + + /* Set up the *vsi struct and our local tracking of the MAIN PF vsi. */ + len = sizeof(struct i40e_vsi *) * pf->num_alloc_vsi; pf->vsi = kzalloc(len, GFP_KERNEL); if (!pf->vsi) { err = -ENOMEM; @@ -8500,7 +8508,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_vsis; } /* if FDIR VSI was set up, start it now */ - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) { i40e_vsi_open(pf->vsi[i]); break; @@ -8695,7 +8703,7 @@ static void i40e_remove(struct pci_dev *pdev) /* Clear all dynamic memory lists of rings, q_vectors, and VSIs */ i40e_clear_interrupt_scheme(pf); - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) { + for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i]) { i40e_vsi_clear_rings(pf->vsi[i]); i40e_vsi_clear(pf->vsi[i]); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index d1a9a0512b93..2622a86de64b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -62,7 +62,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet, /* find existing FDIR VSI */ vsi = NULL; - for (i = 0; i < pf->hw.func_caps.num_vsis; i++) + for (i = 0; i < pf->num_alloc_vsi; i++) if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) vsi = pf->vsi[i]; if (!vsi) -- cgit v1.2.3 From 8a3c91cce3d32d3fa1e3b64d41b241103a62fd62 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 20 May 2014 08:01:43 +0000 Subject: i40e/i40evf: add PPRS bit to error bits and fix bug in Rx checksum The driver was not marking packets with bad checksums correctly, especially IPv6 packets with a bad checksum. To do this correctly we need a define that may be set by hardware in rare cases. Change-ID: I1a997b72b491ded27a78ac3bce1197b2d2611130 Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 1 + drivers/net/ethernet/intel/i40e/i40e_txrx.c | 74 +++++++++++++++++++------- drivers/net/ethernet/intel/i40e/i40e_type.h | 3 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 74 +++++++++++++++++++------- drivers/net/ethernet/intel/i40evf/i40e_type.h | 3 +- 5 files changed, 115 insertions(+), 40 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index df3917b68c99..b16c25111552 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -119,6 +119,7 @@ static struct i40e_stats i40e_gstrings_stats[] = { I40E_PF_STAT("mac_local_faults", stats.mac_local_faults), I40E_PF_STAT("mac_remote_faults", stats.mac_remote_faults), I40E_PF_STAT("tx_timeout", tx_timeout_count), + I40E_PF_STAT("rx_csum_bad", hw_csum_rx_error), I40E_PF_STAT("rx_length_errors", stats.rx_length_errors), I40E_PF_STAT("link_xon_rx", stats.link_xon_rx), I40E_PF_STAT("link_xoff_rx", stats.link_xoff_rx), diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 2622a86de64b..d84f4275f470 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1193,10 +1193,12 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, u32 rx_error, u16 rx_ptype) { + struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(rx_ptype); + bool ipv4 = false, ipv6 = false; bool ipv4_tunnel, ipv6_tunnel; __wsum rx_udp_csum; - __sum16 csum; struct iphdr *iph; + __sum16 csum; ipv4_tunnel = (rx_ptype > I40E_RX_PTYPE_GRENAT4_MAC_PAY3) && (rx_ptype < I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4); @@ -1207,29 +1209,57 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, skb->ip_summed = CHECKSUM_NONE; /* Rx csum enabled and ip headers found? */ - if (!(vsi->netdev->features & NETIF_F_RXCSUM && - rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT))) + if (!(vsi->netdev->features & NETIF_F_RXCSUM)) + return; + + /* did the hardware decode the packet and checksum? */ + if (!(rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT))) + return; + + /* both known and outer_ip must be set for the below code to work */ + if (!(decoded.known && decoded.outer_ip)) return; + if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP && + decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4) + ipv4 = true; + else if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP && + decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6) + ipv6 = true; + + if (ipv4 && + (rx_error & ((1 << I40E_RX_DESC_ERROR_IPE_SHIFT) | + (1 << I40E_RX_DESC_ERROR_EIPE_SHIFT)))) + goto checksum_fail; + /* likely incorrect csum if alternate IP extension headers found */ - if (rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT)) + if (ipv6 && + decoded.inner_prot == I40E_RX_PTYPE_INNER_PROT_TCP && + rx_error & (1 << I40E_RX_DESC_ERROR_L4E_SHIFT) && + rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT)) + /* don't increment checksum err here, non-fatal err */ return; - /* IP or L4 or outmost IP checksum error */ - if (rx_error & ((1 << I40E_RX_DESC_ERROR_IPE_SHIFT) | - (1 << I40E_RX_DESC_ERROR_L4E_SHIFT) | - (1 << I40E_RX_DESC_ERROR_EIPE_SHIFT))) { - vsi->back->hw_csum_rx_error++; + /* there was some L4 error, count error and punt packet to the stack */ + if (rx_error & (1 << I40E_RX_DESC_ERROR_L4E_SHIFT)) + goto checksum_fail; + + /* handle packets that were not able to be checksummed due + * to arrival speed, in this case the stack can compute + * the csum. + */ + if (rx_error & (1 << I40E_RX_DESC_ERROR_PPRS_SHIFT)) return; - } + /* If VXLAN traffic has an outer UDPv4 checksum we need to check + * it in the driver, hardware does not do it for us. + * Since L3L4P bit was set we assume a valid IHL value (>=5) + * so the total length of IPv4 header is IHL*4 bytes + * The UDP_0 bit *may* bet set if the *inner* header is UDP + */ if (ipv4_tunnel && + (decoded.inner_prot != I40E_RX_PTYPE_INNER_PROT_UDP) && !(rx_status & (1 << I40E_RX_DESC_STATUS_UDP_0_SHIFT))) { - /* If VXLAN traffic has an outer UDPv4 checksum we need to check - * it in the driver, hardware does not do it for us. - * Since L3L4P bit was set we assume a valid IHL value (>=5) - * so the total length of IPv4 header is IHL*4 bytes - */ skb->transport_header = skb->mac_header + sizeof(struct ethhdr) + (ip_hdr(skb)->ihl * 4); @@ -1246,13 +1276,16 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, (skb->len - skb_transport_offset(skb)), IPPROTO_UDP, rx_udp_csum); - if (udp_hdr(skb)->check != csum) { - vsi->back->hw_csum_rx_error++; - return; - } + if (udp_hdr(skb)->check != csum) + goto checksum_fail; } skb->ip_summed = CHECKSUM_UNNECESSARY; + + return; + +checksum_fail: + vsi->back->hw_csum_rx_error++; } /** @@ -1429,6 +1462,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) /* ERR_MASK will only have valid bits if EOP set */ if (unlikely(rx_error & (1 << I40E_RX_DESC_ERROR_RXE_SHIFT))) { dev_kfree_skb_any(skb); + /* TODO: shouldn't we increment a counter indicating the + * drop? + */ goto next_desc; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 6c977d2d48e4..42bfb2aed765 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -541,7 +541,8 @@ enum i40e_rx_desc_error_bits { I40E_RX_DESC_ERROR_IPE_SHIFT = 3, I40E_RX_DESC_ERROR_L4E_SHIFT = 4, I40E_RX_DESC_ERROR_EIPE_SHIFT = 5, - I40E_RX_DESC_ERROR_OVERSIZE_SHIFT = 6 + I40E_RX_DESC_ERROR_OVERSIZE_SHIFT = 6, + I40E_RX_DESC_ERROR_PPRS_SHIFT = 7 }; enum i40e_rx_desc_error_l3l4e_fcoe_masks { diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index ae089df7df19..48ebb6cd69f2 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -728,10 +728,12 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, u32 rx_error, u16 rx_ptype) { + struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(rx_ptype); + bool ipv4 = false, ipv6 = false; bool ipv4_tunnel, ipv6_tunnel; __wsum rx_udp_csum; - __sum16 csum; struct iphdr *iph; + __sum16 csum; ipv4_tunnel = (rx_ptype > I40E_RX_PTYPE_GRENAT4_MAC_PAY3) && (rx_ptype < I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4); @@ -742,29 +744,57 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, skb->ip_summed = CHECKSUM_NONE; /* Rx csum enabled and ip headers found? */ - if (!(vsi->netdev->features & NETIF_F_RXCSUM && - rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT))) + if (!(vsi->netdev->features & NETIF_F_RXCSUM)) + return; + + /* did the hardware decode the packet and checksum? */ + if (!(rx_status & (1 << I40E_RX_DESC_STATUS_L3L4P_SHIFT))) + return; + + /* both known and outer_ip must be set for the below code to work */ + if (!(decoded.known && decoded.outer_ip)) return; + if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP && + decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4) + ipv4 = true; + else if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP && + decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6) + ipv6 = true; + + if (ipv4 && + (rx_error & ((1 << I40E_RX_DESC_ERROR_IPE_SHIFT) | + (1 << I40E_RX_DESC_ERROR_EIPE_SHIFT)))) + goto checksum_fail; + /* likely incorrect csum if alternate IP extension headers found */ - if (rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT)) + if (ipv6 && + decoded.inner_prot == I40E_RX_PTYPE_INNER_PROT_TCP && + rx_error & (1 << I40E_RX_DESC_ERROR_L4E_SHIFT) && + rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT)) + /* don't increment checksum err here, non-fatal err */ return; - /* IP or L4 or outmost IP checksum error */ - if (rx_error & ((1 << I40E_RX_DESC_ERROR_IPE_SHIFT) | - (1 << I40E_RX_DESC_ERROR_L4E_SHIFT) | - (1 << I40E_RX_DESC_ERROR_EIPE_SHIFT))) { - vsi->back->hw_csum_rx_error++; + /* there was some L4 error, count error and punt packet to the stack */ + if (rx_error & (1 << I40E_RX_DESC_ERROR_L4E_SHIFT)) + goto checksum_fail; + + /* handle packets that were not able to be checksummed due + * to arrival speed, in this case the stack can compute + * the csum. + */ + if (rx_error & (1 << I40E_RX_DESC_ERROR_PPRS_SHIFT)) return; - } + /* If VXLAN traffic has an outer UDPv4 checksum we need to check + * it in the driver, hardware does not do it for us. + * Since L3L4P bit was set we assume a valid IHL value (>=5) + * so the total length of IPv4 header is IHL*4 bytes + * The UDP_0 bit *may* bet set if the *inner* header is UDP + */ if (ipv4_tunnel && + (decoded.inner_prot != I40E_RX_PTYPE_INNER_PROT_UDP) && !(rx_status & (1 << I40E_RX_DESC_STATUS_UDP_0_SHIFT))) { - /* If VXLAN traffic has an outer UDPv4 checksum we need to check - * it in the driver, hardware does not do it for us. - * Since L3L4P bit was set we assume a valid IHL value (>=5) - * so the total length of IPv4 header is IHL*4 bytes - */ skb->transport_header = skb->mac_header + sizeof(struct ethhdr) + (ip_hdr(skb)->ihl * 4); @@ -781,13 +811,16 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, (skb->len - skb_transport_offset(skb)), IPPROTO_UDP, rx_udp_csum); - if (udp_hdr(skb)->check != csum) { - vsi->back->hw_csum_rx_error++; - return; - } + if (udp_hdr(skb)->check != csum) + goto checksum_fail; } skb->ip_summed = CHECKSUM_UNNECESSARY; + + return; + +checksum_fail: + vsi->back->hw_csum_rx_error++; } /** @@ -956,6 +989,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) /* ERR_MASK will only have valid bits if EOP set */ if (unlikely(rx_error & (1 << I40E_RX_DESC_ERROR_RXE_SHIFT))) { dev_kfree_skb_any(skb); + /* TODO: shouldn't we increment a counter indicating the + * drop? + */ goto next_desc; } diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h index e3c9ebbe7ca2..0a7914d11b6a 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_type.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h @@ -541,7 +541,8 @@ enum i40e_rx_desc_error_bits { I40E_RX_DESC_ERROR_IPE_SHIFT = 3, I40E_RX_DESC_ERROR_L4E_SHIFT = 4, I40E_RX_DESC_ERROR_EIPE_SHIFT = 5, - I40E_RX_DESC_ERROR_OVERSIZE_SHIFT = 6 + I40E_RX_DESC_ERROR_OVERSIZE_SHIFT = 6, + I40E_RX_DESC_ERROR_PPRS_SHIFT = 7 }; enum i40e_rx_desc_error_l3l4e_fcoe_masks { -- cgit v1.2.3 From 433c47de1368cf07a7cb8d9148a4d36d824b89f8 Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Thu, 22 May 2014 06:32:17 +0000 Subject: i40e/i40evf: Add Flow director stats to PF stats Add members to stat struct to keep track of Flow director ATR and SideBand filter packet matches. Change-ID: Ibbb31a53c7adcc2bb96991dd80565442a2f2513c Signed-off-by: Anjali Singhai Jain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 13 +++++++++++++ drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 5 ++++- drivers/net/ethernet/intel/i40e/i40e_main.c | 12 ++++++++++++ drivers/net/ethernet/intel/i40e/i40e_txrx.c | 7 ++++++- drivers/net/ethernet/intel/i40e/i40e_type.h | 3 +++ drivers/net/ethernet/intel/i40evf/i40e_type.h | 3 +++ 6 files changed, 41 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c') diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 5a8bbaafe500..65985846345d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -154,6 +154,17 @@ struct i40e_lump_tracking { #define I40E_FDIR_BUFFER_FULL_MARGIN 10 #define I40E_FDIR_BUFFER_HEAD_ROOM 200 +enum i40e_fd_stat_idx { + I40E_FD_STAT_ATR, + I40E_FD_STAT_SB, + I40E_FD_STAT_PF_COUNT +}; +#define I40E_FD_STAT_PF_IDX(pf_id) ((pf_id) * I40E_FD_STAT_PF_COUNT) +#define I40E_FD_ATR_STAT_IDX(pf_id) \ + (I40E_FD_STAT_PF_IDX(pf_id) + I40E_FD_STAT_ATR) +#define I40E_FD_SB_STAT_IDX(pf_id) \ + (I40E_FD_STAT_PF_IDX(pf_id) + I40E_FD_STAT_SB) + struct i40e_fdir_filter { struct hlist_node fdir_node; /* filter ipnut set */ @@ -223,6 +234,8 @@ struct i40e_pf { struct hlist_head fdir_filter_list; u16 fdir_pf_active_filters; + u16 fd_sb_cnt_idx; + u16 fd_atr_cnt_idx; #ifdef CONFIG_I40E_VXLAN __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index c7718631ed02..e33016620e28 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -145,6 +145,9 @@ static struct i40e_stats i40e_gstrings_stats[] = { I40E_PF_STAT("rx_jabber", stats.rx_jabber), I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests), I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), + I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match), + I40E_PF_STAT("fdir_sb_match", stats.fd_sb_match), + /* LPI stats */ I40E_PF_STAT("tx_lpi_status", stats.tx_lpi_status), I40E_PF_STAT("rx_lpi_status", stats.rx_lpi_status), @@ -1581,7 +1584,7 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi, input->pctype = 0; input->dest_vsi = vsi->id; input->fd_status = I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID; - input->cnt_index = 0; + input->cnt_index = pf->fd_sb_cnt_idx; input->flow_type = fsp->flow_type; input->ip4_proto = fsp->h_u.usr_ip4_spec.proto; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index e3916d00d403..06e0a5226ce1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1013,6 +1013,14 @@ static void i40e_update_pf_stats(struct i40e_pf *pf) pf->stat_offsets_loaded, &osd->rx_jabber, &nsd->rx_jabber); + /* FDIR stats */ + i40e_stat_update32(hw, I40E_GLQF_PCNT(pf->fd_atr_cnt_idx), + pf->stat_offsets_loaded, + &osd->fd_atr_match, &nsd->fd_atr_match); + i40e_stat_update32(hw, I40E_GLQF_PCNT(pf->fd_sb_cnt_idx), + pf->stat_offsets_loaded, + &osd->fd_sb_match, &nsd->fd_sb_match); + val = rd32(hw, I40E_PRTPM_EEE_STAT); nsd->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >> @@ -6604,8 +6612,12 @@ static int i40e_sw_init(struct i40e_pf *pf) (pf->hw.func_caps.fd_filters_best_effort > 0)) { pf->flags |= I40E_FLAG_FD_ATR_ENABLED; pf->atr_sample_rate = I40E_DEFAULT_ATR_SAMPLE_RATE; + /* Setup a counter for fd_atr per pf */ + pf->fd_atr_cnt_idx = I40E_FD_ATR_STAT_IDX(pf->hw.pf_id); if (!(pf->flags & I40E_FLAG_MFP_ENABLED)) { pf->flags |= I40E_FLAG_FD_SB_ENABLED; + /* Setup a counter for fd_sb per pf */ + pf->fd_sb_cnt_idx = I40E_FD_SB_STAT_IDX(pf->hw.pf_id); } else { dev_info(&pf->pdev->dev, "Flow Director Sideband mode Disabled in MFP mode\n"); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index d84f4275f470..e49f31dbd5d8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -121,7 +121,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet, dcc |= I40E_TXD_FLTR_QW1_CNT_ENA_MASK; dcc |= ((u32)fdir_data->cnt_index << I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & - I40E_TXD_FLTR_QW1_CNTINDEX_MASK; + I40E_TXD_FLTR_QW1_CNTINDEX_MASK; } fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dcc); @@ -1695,6 +1695,11 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, dtype_cmd |= I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID << I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT; + dtype_cmd |= I40E_TXD_FLTR_QW1_CNT_ENA_MASK; + dtype_cmd |= + ((u32)pf->fd_atr_cnt_idx << I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & + I40E_TXD_FLTR_QW1_CNTINDEX_MASK; + fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype); fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dtype_cmd); } diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index bb5b05503e56..9d39ff23c5fb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -1023,6 +1023,9 @@ struct i40e_hw_port_stats { u64 tx_size_big; /* ptc9522 */ u64 mac_short_packet_dropped; /* mspdc */ u64 checksum_error; /* xec */ + /* flow director stats */ + u64 fd_atr_match; + u64 fd_sb_match; /* EEE LPI */ u32 tx_lpi_status; u32 rx_lpi_status; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h index 92fae7387708..d3cf5a69de54 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_type.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h @@ -1023,6 +1023,9 @@ struct i40e_hw_port_stats { u64 tx_size_big; /* ptc9522 */ u64 mac_short_packet_dropped; /* mspdc */ u64 checksum_error; /* xec */ + /* flow director stats */ + u64 fd_atr_match; + u64 fd_sb_match; /* EEE LPI */ u32 tx_lpi_status; u32 rx_lpi_status; -- cgit v1.2.3