diff mbox series

[for-next,04/11] net/mlx5: IPSec, Add command V2 support

Message ID 20180308012614.26451-5-saeedm@mellanox.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [for-next,01/11] net/mlx5: Use MLX5_IPSEC_DEV macro for ipsec caps | expand

Commit Message

Saeed Mahameed March 8, 2018, 1:26 a.m. UTC
From: Aviad Yehezkel <aviadye@mellanox.com>

This patch adds V2 command support.
New fpga devices support extended features (udp encap, esn etc...), this
features require new hardware sadb format therefore we have a new version
of commands to manipulate it.

Signed-off-by: Yossef Efraim <yossefe@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/accel/ipsec.c  |  9 +++-
 .../net/ethernet/mellanox/mlx5/core/accel/ipsec.h  | 21 ++++++--
 .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c   | 60 ++++++++++------------
 .../net/ethernet/mellanox/mlx5/core/fpga/ipsec.c   | 11 ++--
 .../net/ethernet/mellanox/mlx5/core/fpga/ipsec.h   |  5 +-
 include/linux/mlx5/mlx5_ifc_fpga.h                 |  4 +-
 6 files changed, 66 insertions(+), 44 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
index 53e69edaedde..b88ae12d9066 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
@@ -40,10 +40,17 @@ 
 void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
 				   struct mlx5_accel_ipsec_sa *cmd)
 {
+	int cmd_size;
+
 	if (!MLX5_IPSEC_DEV(mdev))
 		return ERR_PTR(-EOPNOTSUPP);
 
-	return mlx5_fpga_ipsec_sa_cmd_exec(mdev, cmd);
+	if (mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_V2_CMD)
+		cmd_size = sizeof(*cmd);
+	else
+		cmd_size = sizeof(cmd->ipsec_sa_v1);
+
+	return mlx5_fpga_ipsec_sa_cmd_exec(mdev, cmd, cmd_size);
 }
 
 int mlx5_accel_ipsec_sa_cmd_wait(void *ctx)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
index 4da9611a753d..14a2e95e82c3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
@@ -44,6 +44,7 @@  enum {
 	MLX5_ACCEL_IPSEC_ESP = BIT(3),
 	MLX5_ACCEL_IPSEC_LSO = BIT(4),
 	MLX5_ACCEL_IPSEC_NO_TRAILER = BIT(5),
+	MLX5_ACCEL_IPSEC_V2_CMD = BIT(7),
 };
 
 #define MLX5_IPSEC_SADB_IP_AH       BIT(7)
@@ -56,6 +57,9 @@  enum {
 enum {
 	MLX5_IPSEC_CMD_ADD_SA = 0,
 	MLX5_IPSEC_CMD_DEL_SA = 1,
+	MLX5_IPSEC_CMD_ADD_SA_V2 = 2,
+	MLX5_IPSEC_CMD_DEL_SA_V2 = 3,
+	MLX5_IPSEC_CMD_MOD_SA_V2 = 4,
 	MLX5_IPSEC_CMD_SET_CAP = 5,
 };
 
@@ -68,7 +72,7 @@  enum mlx5_accel_ipsec_enc_mode {
 #define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \
 			      MLX5_ACCEL_IPSEC_DEVICE)
 
-struct mlx5_accel_ipsec_sa {
+struct mlx5_accel_ipsec_sa_v1 {
 	__be32 cmd;
 	u8 key_enc[32];
 	u8 key_auth[32];
@@ -88,10 +92,19 @@  struct mlx5_accel_ipsec_sa {
 	__be32 sw_sa_handle;
 	__be16 tfclen;
 	u8 enc_mode;
-	u8 sip_masklen;
-	u8 dip_masklen;
+	u8 reserved1[2];
 	u8 flags;
-	u8 reserved[2];
+	u8 reserved2[2];
+};
+
+struct mlx5_accel_ipsec_sa {
+	struct mlx5_accel_ipsec_sa_v1 ipsec_sa_v1;
+	__be16 udp_sp;
+	__be16 udp_dp;
+	u8 reserved1[4];
+	__be32 esn;
+	__be16 vid;     /* only 12 bits, rest is reserved */
+	__be16 reserved2;
 } __packed;
 
 /**
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
index 460a613059fe..a8c3fe7cff0f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -133,50 +133,46 @@  static void mlx5e_ipsec_build_hw_sa(u32 op, struct mlx5e_ipsec_sa_entry *sa_entr
 
 	memset(hw_sa, 0, sizeof(*hw_sa));
 
-	if (op == MLX5_IPSEC_CMD_ADD_SA) {
-		crypto_data_len = (x->aead->alg_key_len + 7) / 8;
-		key_len = crypto_data_len - 4; /* 4 bytes salt at end */
-		aead = x->data;
-		geniv_ctx = crypto_aead_ctx(aead);
-		ivsize = crypto_aead_ivsize(aead);
-
-		memcpy(&hw_sa->key_enc, x->aead->alg_key, key_len);
-		/* Duplicate 128 bit key twice according to HW layout */
-		if (key_len == 16)
-			memcpy(&hw_sa->key_enc[16], x->aead->alg_key, key_len);
-		memcpy(&hw_sa->gcm.salt_iv, geniv_ctx->salt, ivsize);
-		hw_sa->gcm.salt = *((__be32 *)(x->aead->alg_key + key_len));
-	}
-
-	hw_sa->cmd = htonl(op);
-	hw_sa->flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN;
+	crypto_data_len = (x->aead->alg_key_len + 7) / 8;
+	key_len = crypto_data_len - 4; /* 4 bytes salt at end */
+	aead = x->data;
+	geniv_ctx = crypto_aead_ctx(aead);
+	ivsize = crypto_aead_ivsize(aead);
+
+	memcpy(&hw_sa->ipsec_sa_v1.key_enc, x->aead->alg_key, key_len);
+	/* Duplicate 128 bit key twice according to HW layout */
+	if (key_len == 16)
+		memcpy(&hw_sa->ipsec_sa_v1.key_enc[16], x->aead->alg_key, key_len);
+	memcpy(&hw_sa->ipsec_sa_v1.gcm.salt_iv, geniv_ctx->salt, ivsize);
+	hw_sa->ipsec_sa_v1.gcm.salt = *((__be32 *)(x->aead->alg_key + key_len));
+
+	hw_sa->ipsec_sa_v1.cmd = htonl(op);
+	hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN;
 	if (x->props.family == AF_INET) {
-		hw_sa->sip[3] = x->props.saddr.a4;
-		hw_sa->dip[3] = x->id.daddr.a4;
-		hw_sa->sip_masklen = 32;
-		hw_sa->dip_masklen = 32;
+		hw_sa->ipsec_sa_v1.sip[3] = x->props.saddr.a4;
+		hw_sa->ipsec_sa_v1.dip[3] = x->id.daddr.a4;
 	} else {
-		memcpy(hw_sa->sip, x->props.saddr.a6, sizeof(hw_sa->sip));
-		memcpy(hw_sa->dip, x->id.daddr.a6, sizeof(hw_sa->dip));
-		hw_sa->sip_masklen = 128;
-		hw_sa->dip_masklen = 128;
-		hw_sa->flags |= MLX5_IPSEC_SADB_IPV6;
+		memcpy(hw_sa->ipsec_sa_v1.sip, x->props.saddr.a6,
+		       sizeof(hw_sa->ipsec_sa_v1.sip));
+		memcpy(hw_sa->ipsec_sa_v1.dip, x->id.daddr.a6,
+		       sizeof(hw_sa->ipsec_sa_v1.dip));
+		hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IPV6;
 	}
-	hw_sa->spi = x->id.spi;
-	hw_sa->sw_sa_handle = htonl(sa_entry->handle);
+	hw_sa->ipsec_sa_v1.spi = x->id.spi;
+	hw_sa->ipsec_sa_v1.sw_sa_handle = htonl(sa_entry->handle);
 	switch (x->id.proto) {
 	case IPPROTO_ESP:
-		hw_sa->flags |= MLX5_IPSEC_SADB_IP_ESP;
+		hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IP_ESP;
 		break;
 	case IPPROTO_AH:
-		hw_sa->flags |= MLX5_IPSEC_SADB_IP_AH;
+		hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IP_AH;
 		break;
 	default:
 		break;
 	}
-	hw_sa->enc_mode = mlx5e_ipsec_enc_mode(x);
+	hw_sa->ipsec_sa_v1.enc_mode = mlx5e_ipsec_enc_mode(x);
 	if (!(x->xso.flags & XFRM_OFFLOAD_INBOUND))
-		hw_sa->flags |= MLX5_IPSEC_SADB_DIR_SX;
+		hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_DIR_SX;
 }
 
 static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
index 3b10d46dc821..fa5b5a0888ec 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
@@ -223,9 +223,9 @@  static int mlx5_fpga_ipsec_cmd_wait(void *ctx)
 }
 
 void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
-				  struct mlx5_accel_ipsec_sa *cmd)
+				  struct mlx5_accel_ipsec_sa *cmd, int cmd_size)
 {
-	return mlx5_fpga_ipsec_cmd_exec(mdev, cmd, sizeof(*cmd));
+	return mlx5_fpga_ipsec_cmd_exec(mdev, cmd, cmd_size);
 }
 
 int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx)
@@ -239,9 +239,9 @@  int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx)
 		goto out;
 
 	sa = (struct mlx5_accel_ipsec_sa *)&context->command;
-	if (sa->sw_sa_handle != context->resp.sw_sa_handle) {
+	if (sa->ipsec_sa_v1.sw_sa_handle != context->resp.sw_sa_handle) {
 		mlx5_fpga_err(context->dev, "mismatch SA handle. cmd 0x%08x vs resp 0x%08x\n",
-			      ntohl(sa->sw_sa_handle),
+			      ntohl(sa->ipsec_sa_v1.sw_sa_handle),
 			      ntohl(context->resp.sw_sa_handle));
 		res = -EIO;
 	}
@@ -276,6 +276,9 @@  u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev)
 	if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, rx_no_trailer))
 		ret |= MLX5_ACCEL_IPSEC_NO_TRAILER;
 
+	if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, v2_command))
+		ret |= MLX5_ACCEL_IPSEC_V2_CMD;
+
 	return ret;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
index 26a3e4b56972..e5ec29f56532 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
@@ -39,7 +39,7 @@ 
 #ifdef CONFIG_MLX5_FPGA
 
 void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
-				  struct mlx5_accel_ipsec_sa *cmd);
+				  struct mlx5_accel_ipsec_sa *cmd, int cmd_size);
 int mlx5_fpga_ipsec_sa_cmd_wait(void *context);
 
 u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev);
@@ -53,7 +53,8 @@  void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev);
 #else
 
 static inline void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
-						struct mlx5_accel_ipsec_sa *cmd)
+						struct mlx5_accel_ipsec_sa *cmd,
+						int cmd_size)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
diff --git a/include/linux/mlx5/mlx5_ifc_fpga.h b/include/linux/mlx5/mlx5_ifc_fpga.h
index 643544db180b..dd7e4538159c 100644
--- a/include/linux/mlx5/mlx5_ifc_fpga.h
+++ b/include/linux/mlx5/mlx5_ifc_fpga.h
@@ -373,7 +373,9 @@  struct mlx5_ifc_fpga_destroy_qp_out_bits {
 struct mlx5_ifc_ipsec_extended_cap_bits {
 	u8         encapsulation[0x20];
 
-	u8         reserved_0[0x14];
+	u8         reserved_0[0x12];
+	u8         v2_command[0x1];
+	u8         udp_encap[0x1];
 	u8         rx_no_trailer[0x1];
 	u8         ipv4_fragment[0x1];
 	u8         ipv6[0x1];