Commit 1a2b60f6 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Saeed Mahameed says:

====================
mlx5-dr-2021-01-29

Add support for Connect-X6DX Software steering

This series adds SW Steering support for Connect-X6DX.

Since the STE and actions formats are different on this new HW,
we implemented the HW specific STEv1 layer on the infrastructure
implemented in previous mlx5 DR patchset to support all the
functionalities as previous devices.

Most of the code in this series very is low level HW specific, we
implement the function pointers for the generic SW steering layer.

* tag 'mlx5-dr-2021-01-29' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5: DR, Allow SW steering for sw_owner_v2 devices
  net/mlx5: DR, Copy all 64B whenever replacing STE in the head of miss-list
  net/mlx5: DR, Use HW specific logic API when writing STE
  net/mlx5: DR, Use the right size when writing partial STE into HW
  net/mlx5: DR, Add STEv1 modify header logic
  net/mlx5: DR, Add STEv1 action apply logic
  net/mlx5: DR, Add STEv1 setters and getters
  net/mlx5: DR, Allow native protocol support for HW STEv1
  net/mlx5: DR, Add HW STEv1 match logic
  net/mlx5: DR, Add match STEv1 structs to ifc
  net/mlx5: DR, Fix potential shift wrapping of 32-bit value
====================

Link: https://lore.kernel.org/r/20210130022618.317351-1-saeed@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f222a993 64f45c0f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o
					steering/dr_matcher.o steering/dr_rule.o \
					steering/dr_icm_pool.o steering/dr_buddy.o \
					steering/dr_ste.o steering/dr_send.o \
					steering/dr_ste_v0.o \
					steering/dr_ste_v0.o steering/dr_ste_v1.o \
					steering/dr_cmd.o steering/dr_fw.o \
					steering/dr_action.o steering/fs_dr.o
#
+11 −6
Original line number Diff line number Diff line
@@ -78,9 +78,9 @@ int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev,
	caps->uplink_icm_address_tx =
		MLX5_CAP64_ESW_FLOWTABLE(mdev,
					 sw_steering_uplink_icm_address_tx);
	caps->sw_owner =
		MLX5_CAP_ESW_FLOWTABLE_FDB(mdev,
					   sw_owner);
	caps->sw_owner_v2 = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner_v2);
	if (!caps->sw_owner_v2)
		caps->sw_owner = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner);

	return 0;
}
@@ -113,11 +113,16 @@ int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
	caps->nic_tx_allow_address =
		MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_allow_icm_address);

	caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner);
	caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level);
	caps->rx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner_v2);
	caps->tx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner_v2);

	if (!caps->rx_sw_owner_v2)
		caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner);
	if (!caps->tx_sw_owner_v2)
		caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner);

	caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level);

	caps->log_icm_size = MLX5_CAP_DEV_MEM(mdev, log_steering_sw_icm_size);
	caps->hdr_modify_icm_addr =
		MLX5_CAP64_DEV_MEM(mdev, header_modify_sw_icm_start_address);
+9 −8
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@
#include <linux/mlx5/eswitch.h>
#include "dr_types.h"

#define DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, dmn_type)	\
	((dmn)->info.caps.dmn_type##_sw_owner ||	\
	 ((dmn)->info.caps.dmn_type##_sw_owner_v2 &&	\
	  (dmn)->info.caps.sw_format_ver <= MLX5_STEERING_FORMAT_CONNECTX_6DX))

static int dr_domain_init_cache(struct mlx5dr_domain *dmn)
{
	/* Per vport cached FW FT for checksum recalculation, this
@@ -187,6 +192,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev,
		return ret;

	dmn->info.caps.fdb_sw_owner = dmn->info.caps.esw_caps.sw_owner;
	dmn->info.caps.fdb_sw_owner_v2 = dmn->info.caps.esw_caps.sw_owner_v2;
	dmn->info.caps.esw_rx_drop_address = dmn->info.caps.esw_caps.drop_icm_address_rx;
	dmn->info.caps.esw_tx_drop_address = dmn->info.caps.esw_caps.drop_icm_address_tx;

@@ -229,18 +235,13 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev,
	if (ret)
		return ret;

	if (dmn->info.caps.sw_format_ver != MLX5_STEERING_FORMAT_CONNECTX_5) {
		mlx5dr_err(dmn, "SW steering is not supported on this device\n");
		return -EOPNOTSUPP;
	}

	ret = dr_domain_query_fdb_caps(mdev, dmn);
	if (ret)
		return ret;

	switch (dmn->type) {
	case MLX5DR_DOMAIN_TYPE_NIC_RX:
		if (!dmn->info.caps.rx_sw_owner)
		if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, rx))
			return -ENOTSUPP;

		dmn->info.supp_sw_steering = true;
@@ -249,7 +250,7 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev,
		dmn->info.rx.drop_icm_addr = dmn->info.caps.nic_rx_drop_address;
		break;
	case MLX5DR_DOMAIN_TYPE_NIC_TX:
		if (!dmn->info.caps.tx_sw_owner)
		if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, tx))
			return -ENOTSUPP;

		dmn->info.supp_sw_steering = true;
@@ -261,7 +262,7 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev,
		if (!dmn->info.caps.eswitch_manager)
			return -ENOTSUPP;

		if (!dmn->info.caps.fdb_sw_owner)
		if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, fdb))
			return -ENOTSUPP;

		dmn->info.rx.ste_type = MLX5DR_STE_TYPE_RX;
+8 −4
Original line number Diff line number Diff line
@@ -113,7 +113,8 @@ dr_mask_is_vxlan_gpe_set(struct mlx5dr_match_misc3 *misc3)
static bool
dr_matcher_supp_vxlan_gpe(struct mlx5dr_cmd_caps *caps)
{
	return caps->flex_protocols & MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED;
	return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
	       (caps->flex_protocols & MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED);
}

static bool
@@ -135,7 +136,8 @@ static bool dr_mask_is_tnl_geneve_set(struct mlx5dr_match_misc *misc)
static bool
dr_matcher_supp_tnl_geneve(struct mlx5dr_cmd_caps *caps)
{
	return caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_ENABLED;
	return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
	       (caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_ENABLED);
}

static bool
@@ -148,12 +150,14 @@ dr_mask_is_tnl_geneve(struct mlx5dr_match_param *mask,

static int dr_matcher_supp_icmp_v4(struct mlx5dr_cmd_caps *caps)
{
	return caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED;
	return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
	       (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED);
}

static int dr_matcher_supp_icmp_v6(struct mlx5dr_cmd_caps *caps)
{
	return caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED;
	return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
	       (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED);
}

static bool dr_mask_is_icmpv6_set(struct mlx5dr_match_misc3 *misc3)
+11 −6
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ static int dr_rule_append_to_miss_list(struct mlx5dr_ste_ctx *ste_ctx,
				 mlx5dr_ste_get_icm_addr(new_last_ste));
	list_add_tail(&new_last_ste->miss_list_node, miss_list);

	mlx5dr_send_fill_and_append_ste_send_info(last_ste, DR_STE_SIZE_REDUCED,
	mlx5dr_send_fill_and_append_ste_send_info(last_ste, DR_STE_SIZE_CTRL,
						  0, last_ste->hw_ste,
						  ste_info_last, send_list, true);

@@ -106,14 +106,19 @@ dr_rule_handle_one_ste_in_update_list(struct mlx5dr_ste_send_info *ste_info,
	int ret;

	list_del(&ste_info->send_list);

	/* Copy data to ste, only reduced size or control, the last 16B (mask)
	 * is already written to the hw.
	 */
	if (ste_info->size == DR_STE_SIZE_CTRL)
		memcpy(ste_info->ste->hw_ste, ste_info->data, DR_STE_SIZE_CTRL);
	else
		memcpy(ste_info->ste->hw_ste, ste_info->data, DR_STE_SIZE_REDUCED);

	ret = mlx5dr_send_postsend_ste(dmn, ste_info->ste, ste_info->data,
				       ste_info->size, ste_info->offset);
	if (ret)
		goto out;
	/* Copy data to ste, only reduced size, the last 16B (mask)
	 * is already written to the hw.
	 */
	memcpy(ste_info->ste->hw_ste, ste_info->data, DR_STE_SIZE_REDUCED);

out:
	kfree(ste_info);
@@ -456,7 +461,7 @@ dr_rule_rehash_htbl(struct mlx5dr_rule *rule,
		ste_to_update = cur_htbl->pointing_ste;
	}

	mlx5dr_send_fill_and_append_ste_send_info(ste_to_update, DR_STE_SIZE_REDUCED,
	mlx5dr_send_fill_and_append_ste_send_info(ste_to_update, DR_STE_SIZE_CTRL,
						  0, ste_to_update->hw_ste, ste_info,
						  update_list, false);

Loading