Commit 8d15f364 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Steffen Klassert
Browse files

net/mlx5e: Create hardware IPsec packet offload objects



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: default avatarRaed Salem <raeds@nvidia.com>
Reviewed-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 8518d05b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
+1 −2
Original line number Diff line number Diff line
@@ -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 {
+37 −0
Original line number Diff line number Diff line
@@ -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 =