drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
Extension
.c
Size
18790 bytes
Lines
625
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

is_mdev_legacy_mode(mdev))) {
		if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
					      reformat_add_esp_trasport) &&
		    MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
					      reformat_del_esp_trasport) &&
		    MLX5_CAP_FLOWTABLE_NIC_RX(mdev, decap))
			caps |= MLX5_IPSEC_CAP_PACKET_OFFLOAD;

		if (IS_ENABLED(CONFIG_MLX5_CLS_ACT) &&
		    ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
		      MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) ||
		     MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level)))
			caps |= MLX5_IPSEC_CAP_PRIO;

		if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
					      reformat_l2_to_l3_esp_tunnel) &&
		    MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
					      reformat_l3_esp_tunnel_to_l2))
			caps |= MLX5_IPSEC_CAP_TUNNEL;

		if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
					      reformat_add_esp_transport_over_udp) &&
		    MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
					      reformat_del_esp_transport_over_udp))
			caps |= MLX5_IPSEC_CAP_ESPINUDP;
	}

	if (mlx5_get_roce_state(mdev) && mlx5_ipsec_fs_is_mpv_roce_supported(mdev) &&
	    MLX5_CAP_GEN_2(mdev, flow_table_type_2_type) & MLX5_FT_NIC_RX_2_NIC_RX_RDMA &&
	    MLX5_CAP_GEN_2(mdev, flow_table_type_2_type) & MLX5_FT_NIC_TX_RDMA_2_NIC_TX)
		caps |= MLX5_IPSEC_CAP_ROCE;

	if (!caps)
		return 0;

	if (MLX5_CAP_IPSEC(mdev, ipsec_esn))
		caps |= MLX5_IPSEC_CAP_ESN;

	/* We can accommodate up to 2^24 different IPsec objects
	 * because we use up to 24 bit in flow table metadata
	 * to hold the IPsec Object unique handle.
	 */
	WARN_ON_ONCE(MLX5_CAP_IPSEC(mdev, log_max_ipsec_offload) > 24);
	return caps;
}
EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);

static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
				     struct mlx5e_ipsec_sa_entry *sa_entry)
{
	struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
	void *aso_ctx;

	aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
	if (attrs->replay_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_esn.replay_window);
			MLX5_SET(ipsec_aso, aso_ctx, mode,
				 MLX5_IPSEC_ASO_REPLAY_PROTECTION);
		}
		MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
			 attrs->replay_esn.esn);
	}

	/* 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);
		if (!attrs->replay_esn.trigger)
			MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
				 sa_entry->esn_state.esn);
	}

	if (attrs->lft.hard_packet_limit != XFRM_INF) {
		MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt,
			 attrs->lft.hard_packet_limit);
		MLX5_SET(ipsec_aso, aso_ctx, hard_lft_arm, 1);
		MLX5_SET(ipsec_aso, aso_ctx, remove_flow_enable, 1);

Annotation

Implementation Notes