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)
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,
};
#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];
__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;
/**
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)
}
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)
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;
}
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;
}