Commit 65802f48 authored by Aviad Yehezkel's avatar Aviad Yehezkel Committed by Saeed Mahameed

net/mlx5: IPSec, Add command V2 support

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: default avatarYossef Efraim <yossefe@mellanox.com>
Signed-off-by: default avatarAviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 788a8210
...@@ -40,10 +40,17 @@ ...@@ -40,10 +40,17 @@
void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev, void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
struct mlx5_accel_ipsec_sa *cmd) struct mlx5_accel_ipsec_sa *cmd)
{ {
int cmd_size;
if (!MLX5_IPSEC_DEV(mdev)) if (!MLX5_IPSEC_DEV(mdev))
return ERR_PTR(-EOPNOTSUPP); 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) int mlx5_accel_ipsec_sa_cmd_wait(void *ctx)
......
...@@ -44,6 +44,7 @@ enum { ...@@ -44,6 +44,7 @@ enum {
MLX5_ACCEL_IPSEC_ESP = BIT(3), MLX5_ACCEL_IPSEC_ESP = BIT(3),
MLX5_ACCEL_IPSEC_LSO = BIT(4), MLX5_ACCEL_IPSEC_LSO = BIT(4),
MLX5_ACCEL_IPSEC_NO_TRAILER = BIT(5), MLX5_ACCEL_IPSEC_NO_TRAILER = BIT(5),
MLX5_ACCEL_IPSEC_V2_CMD = BIT(7),
}; };
#define MLX5_IPSEC_SADB_IP_AH BIT(7) #define MLX5_IPSEC_SADB_IP_AH BIT(7)
...@@ -56,6 +57,9 @@ enum { ...@@ -56,6 +57,9 @@ enum {
enum { enum {
MLX5_IPSEC_CMD_ADD_SA = 0, MLX5_IPSEC_CMD_ADD_SA = 0,
MLX5_IPSEC_CMD_DEL_SA = 1, 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, MLX5_IPSEC_CMD_SET_CAP = 5,
}; };
...@@ -68,7 +72,7 @@ enum mlx5_accel_ipsec_enc_mode { ...@@ -68,7 +72,7 @@ enum mlx5_accel_ipsec_enc_mode {
#define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \ #define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \
MLX5_ACCEL_IPSEC_DEVICE) MLX5_ACCEL_IPSEC_DEVICE)
struct mlx5_accel_ipsec_sa { struct mlx5_accel_ipsec_sa_v1 {
__be32 cmd; __be32 cmd;
u8 key_enc[32]; u8 key_enc[32];
u8 key_auth[32]; u8 key_auth[32];
...@@ -88,10 +92,19 @@ struct mlx5_accel_ipsec_sa { ...@@ -88,10 +92,19 @@ struct mlx5_accel_ipsec_sa {
__be32 sw_sa_handle; __be32 sw_sa_handle;
__be16 tfclen; __be16 tfclen;
u8 enc_mode; u8 enc_mode;
u8 sip_masklen; u8 reserved1[2];
u8 dip_masklen;
u8 flags; 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; } __packed;
/** /**
......
...@@ -133,50 +133,46 @@ static void mlx5e_ipsec_build_hw_sa(u32 op, struct mlx5e_ipsec_sa_entry *sa_entr ...@@ -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)); memset(hw_sa, 0, sizeof(*hw_sa));
if (op == MLX5_IPSEC_CMD_ADD_SA) { crypto_data_len = (x->aead->alg_key_len + 7) / 8;
crypto_data_len = (x->aead->alg_key_len + 7) / 8; key_len = crypto_data_len - 4; /* 4 bytes salt at end */
key_len = crypto_data_len - 4; /* 4 bytes salt at end */ aead = x->data;
aead = x->data; geniv_ctx = crypto_aead_ctx(aead);
geniv_ctx = crypto_aead_ctx(aead); ivsize = crypto_aead_ivsize(aead);
ivsize = crypto_aead_ivsize(aead);
memcpy(&hw_sa->ipsec_sa_v1.key_enc, x->aead->alg_key, key_len);
memcpy(&hw_sa->key_enc, x->aead->alg_key, key_len); /* Duplicate 128 bit key twice according to HW layout */
/* Duplicate 128 bit key twice according to HW layout */ if (key_len == 16)
if (key_len == 16) memcpy(&hw_sa->ipsec_sa_v1.key_enc[16], x->aead->alg_key, key_len);
memcpy(&hw_sa->key_enc[16], x->aead->alg_key, key_len); memcpy(&hw_sa->ipsec_sa_v1.gcm.salt_iv, geniv_ctx->salt, ivsize);
memcpy(&hw_sa->gcm.salt_iv, geniv_ctx->salt, ivsize); hw_sa->ipsec_sa_v1.gcm.salt = *((__be32 *)(x->aead->alg_key + key_len));
hw_sa->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;
hw_sa->cmd = htonl(op);
hw_sa->flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN;
if (x->props.family == AF_INET) { if (x->props.family == AF_INET) {
hw_sa->sip[3] = x->props.saddr.a4; hw_sa->ipsec_sa_v1.sip[3] = x->props.saddr.a4;
hw_sa->dip[3] = x->id.daddr.a4; hw_sa->ipsec_sa_v1.dip[3] = x->id.daddr.a4;
hw_sa->sip_masklen = 32;
hw_sa->dip_masklen = 32;
} else { } else {
memcpy(hw_sa->sip, x->props.saddr.a6, sizeof(hw_sa->sip)); memcpy(hw_sa->ipsec_sa_v1.sip, x->props.saddr.a6,
memcpy(hw_sa->dip, x->id.daddr.a6, sizeof(hw_sa->dip)); sizeof(hw_sa->ipsec_sa_v1.sip));
hw_sa->sip_masklen = 128; memcpy(hw_sa->ipsec_sa_v1.dip, x->id.daddr.a6,
hw_sa->dip_masklen = 128; sizeof(hw_sa->ipsec_sa_v1.dip));
hw_sa->flags |= MLX5_IPSEC_SADB_IPV6; hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IPV6;
} }
hw_sa->spi = x->id.spi; hw_sa->ipsec_sa_v1.spi = x->id.spi;
hw_sa->sw_sa_handle = htonl(sa_entry->handle); hw_sa->ipsec_sa_v1.sw_sa_handle = htonl(sa_entry->handle);
switch (x->id.proto) { switch (x->id.proto) {
case IPPROTO_ESP: case IPPROTO_ESP:
hw_sa->flags |= MLX5_IPSEC_SADB_IP_ESP; hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IP_ESP;
break; break;
case IPPROTO_AH: case IPPROTO_AH:
hw_sa->flags |= MLX5_IPSEC_SADB_IP_AH; hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IP_AH;
break; break;
default: default:
break; 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)) 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) static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
......
...@@ -223,9 +223,9 @@ static int mlx5_fpga_ipsec_cmd_wait(void *ctx) ...@@ -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, 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) int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx)
...@@ -239,9 +239,9 @@ int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx) ...@@ -239,9 +239,9 @@ int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx)
goto out; goto out;
sa = (struct mlx5_accel_ipsec_sa *)&context->command; 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", 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)); ntohl(context->resp.sw_sa_handle));
res = -EIO; res = -EIO;
} }
...@@ -276,6 +276,9 @@ u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev) ...@@ -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)) if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, rx_no_trailer))
ret |= MLX5_ACCEL_IPSEC_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; return ret;
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#ifdef CONFIG_MLX5_FPGA #ifdef CONFIG_MLX5_FPGA
void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev, 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); int mlx5_fpga_ipsec_sa_cmd_wait(void *context);
u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev); 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); ...@@ -53,7 +53,8 @@ void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev);
#else #else
static inline void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev, 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); return ERR_PTR(-EOPNOTSUPP);
} }
......
...@@ -373,7 +373,9 @@ struct mlx5_ifc_fpga_destroy_qp_out_bits { ...@@ -373,7 +373,9 @@ struct mlx5_ifc_fpga_destroy_qp_out_bits {
struct mlx5_ifc_ipsec_extended_cap_bits { struct mlx5_ifc_ipsec_extended_cap_bits {
u8 encapsulation[0x20]; 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 rx_no_trailer[0x1];
u8 ipv4_fragment[0x1]; u8 ipv4_fragment[0x1];
u8 ipv6[0x1]; u8 ipv6[0x1];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment