net/mlx5: IPSec, Add command V2 support
authorAviad Yehezkel <aviadye@mellanox.com>
Tue, 16 Jan 2018 14:12:22 +0000 (16:12 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Wed, 7 Mar 2018 23:53:18 +0000 (15:53 -0800)
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>
drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
include/linux/mlx5/mlx5_ifc_fpga.h

index 53e69edaedde2354e35dd7f64959e13b03228ddc..b88ae12d906675272a260d59b296ec33cea775db 100644 (file)
 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)
index 4da9611a753de3e5d9cc1b6953c17edf9e735885..14a2e95e82c310a5e3b863f1d48a22d1ba811096 100644 (file)
@@ -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;
 
 /**
index 460a613059fe9824bf725b9def3989f9adae5747..a8c3fe7cff0f5b045efbe3aca1bdf3daa965ae8f 100644 (file)
@@ -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)
index 3b10d46dc821847a3b4e8aec5b4ac187494ac476..fa5b5a0888ecd3c687647343894fc90a27f02322 100644 (file)
@@ -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;
 }
 
index 26a3e4b56972863efae5e45a28e88df0cf42ad32..e5ec29f56532bd183d0e4fee613a18dcf8e0ab9a 100644 (file)
@@ -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);
 }
index 643544db180b95e89467352cb2c4eb22667f8a73..dd7e4538159c728cd3516b4d22f1dc211b9f8150 100644 (file)
@@ -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];