net/mlx5e: Create hardware IPsec packet offload objects
authorLeon Romanovsky <leonro@nvidia.com>
Fri, 2 Dec 2022 20:10:31 +0000 (22:10 +0200)
committerSteffen Klassert <steffen.klassert@secunet.com>
Tue, 6 Dec 2022 13:02:24 +0000 (14:02 +0100)
Create initial hardware IPsec packet offload object and connect it
to advanced steering operation (ASO) context and queue, so the data
path can communicate with the stack.

Reviewed-by: Raed Salem <raeds@nvidia.com>
Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c

index d2c814e7af974482ff6c0336f5eee3aadb3032c7..c5bccc0df60d3d5e914b2fa7a67785e7c1cd1f03 100644 (file)
@@ -176,6 +176,7 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
        memcpy(&attrs->saddr, x->props.saddr.a6, sizeof(attrs->saddr));
        memcpy(&attrs->daddr, x->id.daddr.a6, sizeof(attrs->daddr));
        attrs->family = x->props.family;
+       attrs->type = x->xso.type;
 }
 
 static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
index 8e2f88f269ac7c176837ecf3817bd6c367929a28..2c9aedf6b0efb9da6cb9886ab33dc85392c9e05a 100644 (file)
@@ -73,6 +73,7 @@ struct mlx5_accel_esp_xfrm_attrs {
        u8 dir : 2;
        u8 esn_overlap : 1;
        u8 esn_trigger : 1;
+       u8 type : 2;
        u8 family;
        u32 replay_window;
 };
@@ -102,8 +103,6 @@ struct mlx5e_ipsec_aso {
        u8 ctx[MLX5_ST_SZ_BYTES(ipsec_aso)];
        dma_addr_t dma_addr;
        struct mlx5_aso *aso;
-       u32 pdn;
-       u32 mkey;
 };
 
 struct mlx5e_ipsec {
index 7fef5de55229ad3076b089d3a34c1f4dcc8d7214..fc88454aaf8d7e94d1c85156267432898d4ac245 100644 (file)
@@ -53,6 +53,38 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
 }
 EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);
 
+static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
+                                    struct mlx5_accel_esp_xfrm_attrs *attrs)
+{
+       void *aso_ctx;
+
+       aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
+       if (attrs->esn_trigger) {
+               MLX5_SET(ipsec_aso, aso_ctx, esn_event_arm, 1);
+
+               if (attrs->dir == XFRM_DEV_OFFLOAD_IN) {
+                       MLX5_SET(ipsec_aso, aso_ctx, window_sz,
+                                attrs->replay_window / 64);
+                       MLX5_SET(ipsec_aso, aso_ctx, mode,
+                                MLX5_IPSEC_ASO_REPLAY_PROTECTION);
+                       }
+       }
+
+       /* ASO context */
+       MLX5_SET(ipsec_obj, obj, ipsec_aso_access_pd, pdn);
+       MLX5_SET(ipsec_obj, obj, full_offload, 1);
+       MLX5_SET(ipsec_aso, aso_ctx, valid, 1);
+       /* MLX5_IPSEC_ASO_REG_C_4_5 is type C register that is used
+        * in flow steering to perform matching against. Please be
+        * aware that this register was chosen arbitrary and can't
+        * be used in other places as long as IPsec packet offload
+        * active.
+        */
+       MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5);
+       if (attrs->dir == XFRM_DEV_OFFLOAD_OUT)
+               MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN);
+}
+
 static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
 {
        struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
@@ -61,6 +93,7 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
        u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
        u32 in[MLX5_ST_SZ_DW(create_ipsec_obj_in)] = {};
        void *obj, *salt_p, *salt_iv_p;
+       struct mlx5e_hw_objs *res;
        int err;
 
        obj = MLX5_ADDR_OF(create_ipsec_obj_in, in, ipsec_object);
@@ -87,6 +120,10 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
        MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
                 MLX5_GENERAL_OBJECT_TYPES_IPSEC);
 
+       res = &mdev->mlx5e_res.hw_objs;
+       if (attrs->type == XFRM_DEV_OFFLOAD_PACKET)
+               mlx5e_ipsec_packet_setup(obj, res->pdn, attrs);
+
        err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
        if (!err)
                sa_entry->ipsec_obj_id =