From 68c1fb2d30209757f9a9f6e5ea587ea3bb8724c0 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 22 Feb 2018 11:09:55 -0800 Subject: [PATCH 1/6] ixgbe: check for 128-bit authentication Make sure the Security Association is using a 128-bit authentication, since that's the only size that the hardware offload supports. Signed-off-by: Shannon Nelson Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 16 +++++++++++----- drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c index 93eacddb6704..8b7dbc8057eb 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -423,15 +423,21 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs, const char aes_gcm_name[] = "rfc4106(gcm(aes))"; int key_len; - if (xs->aead) { - key_data = &xs->aead->alg_key[0]; - key_len = xs->aead->alg_key_len; - alg_name = xs->aead->alg_name; - } else { + if (!xs->aead) { netdev_err(dev, "Unsupported IPsec algorithm\n"); return -EINVAL; } + if (xs->aead->alg_icv_len != IXGBE_IPSEC_AUTH_BITS) { + netdev_err(dev, "IPsec offload requires %d bit authentication\n", + IXGBE_IPSEC_AUTH_BITS); + return -EINVAL; + } + + key_data = &xs->aead->alg_key[0]; + key_len = xs->aead->alg_key_len; + alg_name = xs->aead->alg_name; + if (strcmp(alg_name, aes_gcm_name)) { netdev_err(dev, "Unsupported IPsec algorithm - please use %s\n", aes_gcm_name); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h index da3ce7849e85..87d2800b94ab 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h @@ -32,6 +32,7 @@ #define IXGBE_IPSEC_MAX_RX_IP_COUNT 128 #define IXGBE_IPSEC_BASE_RX_INDEX 0 #define IXGBE_IPSEC_BASE_TX_INDEX IXGBE_IPSEC_MAX_SA_COUNT +#define IXGBE_IPSEC_AUTH_BITS 128 #define IXGBE_RXTXIDX_IPS_EN 0x00000001 #define IXGBE_RXIDX_TBL_SHIFT 1 From 0ae418e6e25baadf3b75c7572d5b4fa5b749e1e3 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 22 Feb 2018 11:09:56 -0800 Subject: [PATCH 2/6] ixgbe: fix ipsec trailer length Fix up the Tx trailer length calculation. We can't believe the trailer len from the xstate information because it was calculated before the packet was put together and padding added. This bit of code finds the padding value in the trailer, adds it to the authentication length, and saves it so later we can put it into the Tx descriptor to tell the device where to stop the checksum calculation. Fixes: 592594704761 ("ixgbe: process the Tx ipsec offload") Signed-off-by: Shannon Nelson Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c index 8b7dbc8057eb..8623013e517e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -789,11 +789,33 @@ int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring, itd->flags = 0; if (xs->id.proto == IPPROTO_ESP) { + struct sk_buff *skb = first->skb; + int ret, authlen, trailerlen; + u8 padlen; + itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP | IXGBE_ADVTXD_TUCMD_L4T_TCP; if (first->protocol == htons(ETH_P_IP)) itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4; - itd->trailer_len = xs->props.trailer_len; + + /* The actual trailer length is authlen (16 bytes) plus + * 2 bytes for the proto and the padlen values, plus + * padlen bytes of padding. This ends up not the same + * as the static value found in xs->props.trailer_len (21). + * + * The "correct" way to get the auth length would be to use + * authlen = crypto_aead_authsize(xs->data); + * but since we know we only have one size to worry about + * we can let the compiler use the constant and save us a + * few CPU cycles. + */ + authlen = IXGBE_IPSEC_AUTH_BITS / 8; + + ret = skb_copy_bits(skb, skb->len - (authlen + 2), &padlen, 1); + if (unlikely(ret)) + return 0; + trailerlen = authlen + 2 + padlen; + itd->trailer_len = trailerlen; } if (tsa->encrypt) itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN; From 5c4aa458634f545e75845b5a20276ffe1c43459e Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 22 Feb 2018 11:09:57 -0800 Subject: [PATCH 3/6] ixgbe: remove unneeded ipsec state free callback With commit 7f05b467a735 ("xfrm: check for xdo_dev_state_free") we no longer need to add an empty callback function to the driver, so now let's remove the useless code. Signed-off-by: Shannon Nelson Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c index 8623013e517e..f2254528dcfc 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -724,23 +724,10 @@ static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) return true; } -/** - * ixgbe_ipsec_free - called by xfrm garbage collections - * @xs: pointer to transformer state struct - * - * We don't have any garbage to collect, so we shouldn't bother - * implementing this function, but the XFRM code doesn't check for - * existence before calling the API callback. - **/ -static void ixgbe_ipsec_free(struct xfrm_state *xs) -{ -} - static const struct xfrmdev_ops ixgbe_xfrmdev_ops = { .xdo_dev_state_add = ixgbe_ipsec_add_sa, .xdo_dev_state_delete = ixgbe_ipsec_del_sa, .xdo_dev_offload_ok = ixgbe_ipsec_offload_ok, - .xdo_dev_state_free = ixgbe_ipsec_free, }; /** From e656805c1b7888c3e79cf26b040b83e6cfd102d6 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Wed, 28 Feb 2018 03:59:09 -0800 Subject: [PATCH 4/6] ixgbe: Add receive length error counter ixgbe enabled rlec counter and the rx_error used it. We can export the counter directly via ethtool -S ethX. Signed-off-by: Tonghao Zhang Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 89edb9fae6f0..c0e6ab42e0e1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -97,6 +97,7 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = { {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(tx_heartbeat_errors)}, {"tx_timeout_count", IXGBE_STAT(tx_timeout_count)}, {"tx_restart_queue", IXGBE_STAT(restart_queue)}, + {"rx_length_errors", IXGBE_STAT(stats.rlec)}, {"rx_long_length_errors", IXGBE_STAT(stats.roc)}, {"rx_short_length_errors", IXGBE_STAT(stats.ruc)}, {"tx_flow_control_xon", IXGBE_STAT(stats.lxontxc)}, From 954b54dea0ebfd2ead48e6bb12a165025227f4b3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 1 Mar 2018 00:17:36 +0100 Subject: [PATCH 5/6] ixgbevf: fix unused variable warning The new ixgbevf_set_rx_buffer_len() function causes a harmless warnings in configurations with large page size: drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c: In function 'ixgbevf_set_rx_buffer_len': drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:1758:15: error: unused variable 'max_frame' [-Werror=unused-variable] This rephrases the code so that the compiler can see the use of that variable, making it slightly easier to read in the process. Fixes: f15c5ba5b6cd ("ixgbevf: add support for using order 1 pages to receive large frames") Signed-off-by: Arnd Bergmann Tested-by: Andrew Bowers Acked-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index f37307131eb6..4da449e0a4ba 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1766,12 +1766,12 @@ static void ixgbevf_set_rx_buffer_len(struct ixgbevf_adapter *adapter, set_ring_build_skb_enabled(rx_ring); -#if (PAGE_SIZE < 8192) - if (max_frame <= IXGBEVF_MAX_FRAME_BUILD_SKB) - return; + if (PAGE_SIZE < 8192) { + if (max_frame <= IXGBEVF_MAX_FRAME_BUILD_SKB) + return; - set_ring_uses_large_buffer(rx_ring); -#endif + set_ring_uses_large_buffer(rx_ring); + } } /** From b03254d797b6b5b7f50a94be0805510114b4d6d1 Mon Sep 17 00:00:00 2001 From: Paul Greenwalt Date: Thu, 8 Mar 2018 07:26:08 -0500 Subject: [PATCH 6/6] ixgbe: fix disabling hide VLAN on VF reset If port VLAN is enabled, set PFQDE.HIDE_VLAN during VF reset. Setting only PFQDE.PFQDE during VF reset was clearing PFQDE.HIDE_VLAN. Signed-off-by: Paul Greenwalt Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 27a70a52f3c9..008aa073a679 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -831,7 +831,11 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); /* force drop enable for all VF Rx queues */ - ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE); + reg = IXGBE_QDE_ENABLE; + if (adapter->vfinfo[vf].pf_vlan) + reg |= IXGBE_QDE_HIDE_VLAN; + + ixgbe_write_qde(adapter, vf, reg); /* enable receive for vf */ reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));