Skip to content

Commit 5185ad6

Browse files
committed
Merge tag 'mlx5-updates-2017-06-27' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5-updates-2017-06-27 (Innova IPsec offload support) This patchset adds support for Innova IPSec network interface card. About Innova device: -------------------- Innova is a network card with a ConnectX chip and an FPGA chip as a bump-on-the-wire. Internal +----------+ Link +-----------------+ | +--------------+ FPGA | +------+ | ConnectX | | Shell +--+ QSFP | | +--------------+ +-------+ | | Port | +----------+ I2C | | SBU | | +------+ | +-------+ | +--+----------+---+ | | +--+--+ +---+---+ | DDR | | Flash | +-----+ +-------+ The FPGA synthesized logic is loaded from dedicated flash storage and has access to its own dedicated DDR RAM. The ConnectX chip firmware programs the FPGA by accessing its configuration space over either the slow internal I2C link or the high-speed internal link. The FPGA logic is divided into a "Shell" and a "Sandbox Unit" (SBU). mlx5_core driver (with CONFIG_MLX5_FPGA) handles all shell functionality, while other components may handle the various SBU functionalities. The driver opens high-speed reliable communication channels with the shell and the SBU over the internal link. These channels may be used for high-bandwidth configuration or for SBU-specific out-of-band data paths. About Innova IPSec device: -------------------------- Innova IPSec is a network card that allows offloading IPSec cryptography operations from the host CPU to the NIC. It is an Innova card with an IPSec SBU. The hardware keeps the database of IPSec Security Associations (SADB) in the FPGA's DDR memory. Internal +----------+ Link +-----------------+ | +--------------+ FPGA | +------+ | ConnectX | | Shell +--+ QSFP | | +--------------+ +-------+ | | Port | +----------+ Internal I2C | | IPSec | | +------+ | | SBU | | | +-------+ | +--+----------+---+ | | +--+--+ +---+---+ | DDR | | | | | | Flash | |SADB | | | +-----+ +-------+ Modes and ciphers: Currently the following modes and ciphers are supported: IPv4 and IPv6 ESP tunnel and transport modes AES 128 and 256 bit encryption, with GCM authentication (RFC4106) IV is generated using seqiv, in sync with Linux's geniv. More modes and ciphers may be added later. Notes: In the future similar functionality will be included in a single-chip NIC. About the driver: ----------------- Patches 1-4 prepare some existing driver code for the new feature: * Add support for reserved GIDs in the hardware GID table * Allow multiple modules to enable hardware RoCE support independently Patches 5-6 define structs and helper functions for QP work-queues. Patches 7-11 add various FPGA-related features required for Innova. IPSec. Patch 12 adds abstraction layer for Mellanox IPSec-offload capable devices. atches 13-16 add IPSec offload support to the mlx5 netdevice. This driver services the new IPSec offload API introduced in commit d77e38e ("xfrm: Add an IPsec hardware offloading API") Configuration Path: If Innova IPSec device is detected, the mlx5e netdevice gets the new NETIF_F_HW_ESP feature and the xdo callbacks, indicating ESP offload capabilities, and also the matching TX checksum and GSO features. The driver configures offloaded Security Associations (SAs) by sending an ADD_SA or DEL_SA message to the IPSec SBU, which updates the SADB in DDR. These messages and their responses are sent over a high-speed channel. Counters for ethtool are retrieved by the driver from the SBU. Data path: On receive path, the SBU decrypts ESP packets which match the offloaded SADB, but keeps them encapsulated. The SBU injects metadata (Mellanox owned ethertype) indicating that crypto-offload has taken place, the SA with which it was done, and the authentication result. The ConnectX chip performs RX checksum offload on the packet, and RSS using the ESP SPI value. The driver detects the special ethertype, and attaches a struct secpath to the RX SKB, including flags to indicate that crypto offload took place, the authentication result, and which xfrm_state was used for decryption, in the olen and ovec members. The RX SKB may have useful CHECKSUM_COMPLETE. A separate patchset will add support for that in the xfrm stack. On transmit path, the stack encapsulates the packet but does not encrypt it, and indicates in the SKB's secpath that crypto offload is to be performed and the SA to use to do so. The driver avoids performing crypto-offload for ESP fragments, and packets with IP options, as the SBU cannot currently do that. For eligible packets, the driver prepends a special ethertype with metadata instructing the hardware to perform crypto offload. The stack builds regular (non-GSO) SKBs so that they contain a placeholder for the ESP trailer. The driver trims it off, because the SBU automatically appends the trailer for offloaded packets. The ConnectX chip performs TX checksum offload on inner UDP or TCP packets, and GSO for TCP packets (duplicating the prepended metadata). The segmented packets then undergo encryption in the SBU before going on the wire. Performance: We measure single stream of TCP on Intel(R) Xeon(R) CPU E5-2643 v2 @3.50GHz Using AES-NI with ESP GSO we get constant 4.1 Gbps. Using crypto offload we get constant 18 Gbps. Note that these numbers require CHECKSUM_COMPLETE support in XFRM, which we submit separately. - Ilan Tayari ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 869684a + 164f16f commit 5185ad6

39 files changed

+4518
-127
lines changed

MAINTAINERS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8327,6 +8327,16 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/
83278327
F: drivers/net/ethernet/mellanox/mlx5/core/fpga/*
83288328
F: include/linux/mlx5/mlx5_ifc_fpga.h
83298329

8330+
MELLANOX ETHERNET INNOVA IPSEC DRIVER
8331+
M: Ilan Tayari <[email protected]>
8332+
R: Boris Pismenny <[email protected]>
8333+
8334+
S: Supported
8335+
W: http://www.mellanox.com
8336+
Q: http://patchwork.ozlabs.org/project/netdev/list/
8337+
F: drivers/net/ethernet/mellanox/mlx5/core/en_ipsec/*
8338+
F: drivers/net/ethernet/mellanox/mlx5/core/ipsec*
8339+
83308340
MELLANOX ETHERNET SWITCH DRIVERS
83318341
M: Jiri Pirko <[email protected]>
83328342
M: Ido Schimmel <[email protected]>

drivers/infiniband/hw/mlx5/main.c

Lines changed: 53 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -223,21 +223,23 @@ static int translate_eth_proto_oper(u32 eth_proto_oper, u8 *active_speed,
223223
return 0;
224224
}
225225

226-
static void mlx5_query_port_roce(struct ib_device *device, u8 port_num,
227-
struct ib_port_attr *props)
226+
static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
227+
struct ib_port_attr *props)
228228
{
229229
struct mlx5_ib_dev *dev = to_mdev(device);
230230
struct mlx5_core_dev *mdev = dev->mdev;
231231
struct net_device *ndev, *upper;
232232
enum ib_mtu ndev_ib_mtu;
233233
u16 qkey_viol_cntr;
234234
u32 eth_prot_oper;
235+
int err;
235236

236237
/* Possible bad flows are checked before filling out props so in case
237238
* of an error it will still be zeroed out.
238239
*/
239-
if (mlx5_query_port_eth_proto_oper(mdev, &eth_prot_oper, port_num))
240-
return;
240+
err = mlx5_query_port_eth_proto_oper(mdev, &eth_prot_oper, port_num);
241+
if (err)
242+
return err;
241243

242244
translate_eth_proto_oper(eth_prot_oper, &props->active_speed,
243245
&props->active_width);
@@ -258,7 +260,7 @@ static void mlx5_query_port_roce(struct ib_device *device, u8 port_num,
258260

259261
ndev = mlx5_ib_get_netdev(device, port_num);
260262
if (!ndev)
261-
return;
263+
return 0;
262264

263265
if (mlx5_lag_is_active(dev->mdev)) {
264266
rcu_read_lock();
@@ -281,89 +283,63 @@ static void mlx5_query_port_roce(struct ib_device *device, u8 port_num,
281283
dev_put(ndev);
282284

283285
props->active_mtu = min(props->max_mtu, ndev_ib_mtu);
286+
return 0;
284287
}
285288

286-
static void ib_gid_to_mlx5_roce_addr(const union ib_gid *gid,
287-
const struct ib_gid_attr *attr,
288-
void *mlx5_addr)
289+
static int set_roce_addr(struct mlx5_ib_dev *dev, u8 port_num,
290+
unsigned int index, const union ib_gid *gid,
291+
const struct ib_gid_attr *attr)
289292
{
290-
#define MLX5_SET_RA(p, f, v) MLX5_SET(roce_addr_layout, p, f, v)
291-
char *mlx5_addr_l3_addr = MLX5_ADDR_OF(roce_addr_layout, mlx5_addr,
292-
source_l3_address);
293-
void *mlx5_addr_mac = MLX5_ADDR_OF(roce_addr_layout, mlx5_addr,
294-
source_mac_47_32);
295-
296-
if (!gid)
297-
return;
293+
enum ib_gid_type gid_type = IB_GID_TYPE_IB;
294+
u8 roce_version = 0;
295+
u8 roce_l3_type = 0;
296+
bool vlan = false;
297+
u8 mac[ETH_ALEN];
298+
u16 vlan_id = 0;
298299

299-
ether_addr_copy(mlx5_addr_mac, attr->ndev->dev_addr);
300+
if (gid) {
301+
gid_type = attr->gid_type;
302+
ether_addr_copy(mac, attr->ndev->dev_addr);
300303

301-
if (is_vlan_dev(attr->ndev)) {
302-
MLX5_SET_RA(mlx5_addr, vlan_valid, 1);
303-
MLX5_SET_RA(mlx5_addr, vlan_id, vlan_dev_vlan_id(attr->ndev));
304+
if (is_vlan_dev(attr->ndev)) {
305+
vlan = true;
306+
vlan_id = vlan_dev_vlan_id(attr->ndev);
307+
}
304308
}
305309

306-
switch (attr->gid_type) {
310+
switch (gid_type) {
307311
case IB_GID_TYPE_IB:
308-
MLX5_SET_RA(mlx5_addr, roce_version, MLX5_ROCE_VERSION_1);
312+
roce_version = MLX5_ROCE_VERSION_1;
309313
break;
310314
case IB_GID_TYPE_ROCE_UDP_ENCAP:
311-
MLX5_SET_RA(mlx5_addr, roce_version, MLX5_ROCE_VERSION_2);
315+
roce_version = MLX5_ROCE_VERSION_2;
316+
if (ipv6_addr_v4mapped((void *)gid))
317+
roce_l3_type = MLX5_ROCE_L3_TYPE_IPV4;
318+
else
319+
roce_l3_type = MLX5_ROCE_L3_TYPE_IPV6;
312320
break;
313321

314322
default:
315-
WARN_ON(true);
323+
mlx5_ib_warn(dev, "Unexpected GID type %u\n", gid_type);
316324
}
317325

318-
if (attr->gid_type != IB_GID_TYPE_IB) {
319-
if (ipv6_addr_v4mapped((void *)gid))
320-
MLX5_SET_RA(mlx5_addr, roce_l3_type,
321-
MLX5_ROCE_L3_TYPE_IPV4);
322-
else
323-
MLX5_SET_RA(mlx5_addr, roce_l3_type,
324-
MLX5_ROCE_L3_TYPE_IPV6);
325-
}
326-
327-
if ((attr->gid_type == IB_GID_TYPE_IB) ||
328-
!ipv6_addr_v4mapped((void *)gid))
329-
memcpy(mlx5_addr_l3_addr, gid, sizeof(*gid));
330-
else
331-
memcpy(&mlx5_addr_l3_addr[12], &gid->raw[12], 4);
332-
}
333-
334-
static int set_roce_addr(struct ib_device *device, u8 port_num,
335-
unsigned int index,
336-
const union ib_gid *gid,
337-
const struct ib_gid_attr *attr)
338-
{
339-
struct mlx5_ib_dev *dev = to_mdev(device);
340-
u32 in[MLX5_ST_SZ_DW(set_roce_address_in)] = {0};
341-
u32 out[MLX5_ST_SZ_DW(set_roce_address_out)] = {0};
342-
void *in_addr = MLX5_ADDR_OF(set_roce_address_in, in, roce_address);
343-
enum rdma_link_layer ll = mlx5_ib_port_link_layer(device, port_num);
344-
345-
if (ll != IB_LINK_LAYER_ETHERNET)
346-
return -EINVAL;
347-
348-
ib_gid_to_mlx5_roce_addr(gid, attr, in_addr);
349-
350-
MLX5_SET(set_roce_address_in, in, roce_address_index, index);
351-
MLX5_SET(set_roce_address_in, in, opcode, MLX5_CMD_OP_SET_ROCE_ADDRESS);
352-
return mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
326+
return mlx5_core_roce_gid_set(dev->mdev, index, roce_version,
327+
roce_l3_type, gid->raw, mac, vlan,
328+
vlan_id);
353329
}
354330

355331
static int mlx5_ib_add_gid(struct ib_device *device, u8 port_num,
356332
unsigned int index, const union ib_gid *gid,
357333
const struct ib_gid_attr *attr,
358334
__always_unused void **context)
359335
{
360-
return set_roce_addr(device, port_num, index, gid, attr);
336+
return set_roce_addr(to_mdev(device), port_num, index, gid, attr);
361337
}
362338

363339
static int mlx5_ib_del_gid(struct ib_device *device, u8 port_num,
364340
unsigned int index, __always_unused void **context)
365341
{
366-
return set_roce_addr(device, port_num, index, NULL, NULL);
342+
return set_roce_addr(to_mdev(device), port_num, index, NULL, NULL);
367343
}
368344

369345
__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
@@ -978,20 +954,31 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u8 port,
978954
int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
979955
struct ib_port_attr *props)
980956
{
957+
unsigned int count;
958+
int ret;
959+
981960
switch (mlx5_get_vport_access_method(ibdev)) {
982961
case MLX5_VPORT_ACCESS_METHOD_MAD:
983-
return mlx5_query_mad_ifc_port(ibdev, port, props);
962+
ret = mlx5_query_mad_ifc_port(ibdev, port, props);
963+
break;
984964

985965
case MLX5_VPORT_ACCESS_METHOD_HCA:
986-
return mlx5_query_hca_port(ibdev, port, props);
966+
ret = mlx5_query_hca_port(ibdev, port, props);
967+
break;
987968

988969
case MLX5_VPORT_ACCESS_METHOD_NIC:
989-
mlx5_query_port_roce(ibdev, port, props);
990-
return 0;
970+
ret = mlx5_query_port_roce(ibdev, port, props);
971+
break;
991972

992973
default:
993-
return -EINVAL;
974+
ret = -EINVAL;
975+
}
976+
977+
if (!ret && props) {
978+
count = mlx5_core_reserved_gids_count(to_mdev(ibdev)->mdev);
979+
props->gid_tbl_len -= count;
994980
}
981+
return ret;
995982
}
996983

997984
static int mlx5_ib_query_gid(struct ib_device *ibdev, u8 port, int index,

drivers/net/ethernet/mellanox/mlx5/core/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ config MLX5_CORE
1111
Core driver for low level functionality of the ConnectX-4 and
1212
Connect-IB cards by Mellanox Technologies.
1313

14+
config MLX5_ACCEL
15+
bool
16+
1417
config MLX5_FPGA
1518
bool "Mellanox Technologies Innova support"
1619
depends on MLX5_CORE
20+
select MLX5_ACCEL
1721
---help---
1822
Build support for the Innova family of network cards by Mellanox
1923
Technologies. Innova network cards are comprised of a ConnectX chip
@@ -48,3 +52,15 @@ config MLX5_CORE_IPOIB
4852
default n
4953
---help---
5054
MLX5 IPoIB offloads & acceleration support.
55+
56+
config MLX5_EN_IPSEC
57+
bool "IPSec XFRM cryptography-offload accelaration"
58+
depends on MLX5_ACCEL
59+
depends on MLX5_CORE_EN
60+
depends on XFRM_OFFLOAD
61+
depends on INET_ESP_OFFLOAD || INET6_ESP_OFFLOAD
62+
default n
63+
---help---
64+
Build support for IPsec cryptography-offload accelaration in the NIC.
65+
Note: Support for hardware with this capability needs to be selected
66+
for this option to become available.

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ subdir-ccflags-y += -I$(src)
44
mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
55
health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o \
66
mad.o transobj.o vport.o sriov.o fs_cmd.o fs_core.o \
7-
fs_counters.o rl.o lag.o dev.o
7+
fs_counters.o rl.o lag.o dev.o lib/gid.o
88

9-
mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o
9+
mlx5_core-$(CONFIG_MLX5_ACCEL) += accel/ipsec.o
10+
11+
mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o \
12+
fpga/ipsec.o
1013

1114
mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \
1215
en_main.o en_common.o en_fs.o en_ethtool.o en_tx.o \
@@ -16,3 +19,6 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \
1619
mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o
1720

1821
mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib/ipoib.o ipoib/ethtool.o
22+
23+
mlx5_core-$(CONFIG_MLX5_EN_IPSEC) += en_accel/ipsec.o en_accel/ipsec_rxtx.o \
24+
en_accel/ipsec_stats.o
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) 2017 Mellanox Technologies. All rights reserved.
3+
*
4+
* This software is available to you under a choice of one of two
5+
* licenses. You may choose to be licensed under the terms of the GNU
6+
* General Public License (GPL) Version 2, available from the file
7+
* COPYING in the main directory of this source tree, or the
8+
* OpenIB.org BSD license below:
9+
*
10+
* Redistribution and use in source and binary forms, with or
11+
* without modification, are permitted provided that the following
12+
* conditions are met:
13+
*
14+
* - Redistributions of source code must retain the above
15+
* copyright notice, this list of conditions and the following
16+
* disclaimer.
17+
*
18+
* - Redistributions in binary form must reproduce the above
19+
* copyright notice, this list of conditions and the following
20+
* disclaimer in the documentation and/or other materials
21+
* provided with the distribution.
22+
*
23+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30+
* SOFTWARE.
31+
*
32+
*/
33+
34+
#include <linux/mlx5/device.h>
35+
36+
#include "accel/ipsec.h"
37+
#include "mlx5_core.h"
38+
#include "fpga/ipsec.h"
39+
40+
void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
41+
struct mlx5_accel_ipsec_sa *cmd)
42+
{
43+
if (!MLX5_IPSEC_DEV(mdev))
44+
return ERR_PTR(-EOPNOTSUPP);
45+
46+
return mlx5_fpga_ipsec_sa_cmd_exec(mdev, cmd);
47+
}
48+
49+
int mlx5_accel_ipsec_sa_cmd_wait(void *ctx)
50+
{
51+
return mlx5_fpga_ipsec_sa_cmd_wait(ctx);
52+
}
53+
54+
u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev)
55+
{
56+
return mlx5_fpga_ipsec_device_caps(mdev);
57+
}
58+
59+
unsigned int mlx5_accel_ipsec_counters_count(struct mlx5_core_dev *mdev)
60+
{
61+
return mlx5_fpga_ipsec_counters_count(mdev);
62+
}
63+
64+
int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
65+
unsigned int count)
66+
{
67+
return mlx5_fpga_ipsec_counters_read(mdev, counters, count);
68+
}
69+
70+
int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev)
71+
{
72+
return mlx5_fpga_ipsec_init(mdev);
73+
}
74+
75+
void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev)
76+
{
77+
mlx5_fpga_ipsec_cleanup(mdev);
78+
}

0 commit comments

Comments
 (0)