DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 0/3] Add HWS mirroring support
@ 2023-09-28 13:09 Shun Hao
  2023-09-28 13:09 ` [PATCH v1 1/3] net/mlx5/hws: add creation of packet reformat DevX obj Shun Hao
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Shun Hao @ 2023-09-28 13:09 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

This patch series are to add the support of mirroring feature in HWS.
The main idea is to create DevX Flow table and FTE in it. The FTE may
have multiple different destinations of type Vport/TIR/Table. With this
multi-destination FTE, NIC can duplicate packets and forward to all
destinations.

Hamdan Igbaria (2):
  net/mlx5/hws: add creation of packet reformat DevX obj
  net/mlx5/hws: add mlx5dr obj struct to mlx5dr action

Shun Hao (1):
  net/mlx5/hws: add support for mirroring

 drivers/common/mlx5/mlx5_prm.h         |  62 +++++++++++-
 drivers/net/mlx5/hws/mlx5dr.h          |  34 +++++++
 drivers/net/mlx5/hws/mlx5dr_action.c   | 134 ++++++++++++++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_action.h   |   6 ++
 drivers/net/mlx5/hws/mlx5dr_cmd.c      | 123 +++++++++++++++++++++--
 drivers/net/mlx5/hws/mlx5dr_cmd.h      |  30 +++++-
 drivers/net/mlx5/hws/mlx5dr_debug.c    |   1 +
 drivers/net/mlx5/hws/mlx5dr_internal.h |   5 +
 drivers/net/mlx5/hws/mlx5dr_send.c     |   5 -
 drivers/net/mlx5/hws/mlx5dr_table.c    |   8 +-
 10 files changed, 384 insertions(+), 24 deletions(-)

-- 
2.20.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v1 1/3] net/mlx5/hws: add creation of packet reformat DevX obj
  2023-09-28 13:09 [PATCH v1 0/3] Add HWS mirroring support Shun Hao
@ 2023-09-28 13:09 ` Shun Hao
  2023-09-28 13:09 ` [PATCH v1 2/3] net/mlx5/hws: add mlx5dr obj struct to mlx5dr action Shun Hao
  2023-09-28 13:09 ` [PATCH v1 3/3] net/mlx5/hws: add support for mirroring Shun Hao
  2 siblings, 0 replies; 4+ messages in thread
From: Shun Hao @ 2023-09-28 13:09 UTC (permalink / raw)
  To: viacheslavo, matan, orika, Suanming Mou
  Cc: dev, rasland, Hamdan Igbaria, Alex Vesker

From: Hamdan Igbaria <hamdani@nvidia.com>

Add support for creation of packet reformat object,
via the ALLOC_PACKET_REFORMAT_CONTEXT command.

Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
Acked-by: Alex Vesker <valex@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h         | 39 +++++++++++++++++
 drivers/net/mlx5/hws/mlx5dr_cmd.c      | 60 ++++++++++++++++++++++++++
 drivers/net/mlx5/hws/mlx5dr_cmd.h      | 11 +++++
 drivers/net/mlx5/hws/mlx5dr_internal.h |  5 +++
 drivers/net/mlx5/hws/mlx5dr_send.c     |  5 ---
 5 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 51f426c614..6749f2c037 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1213,6 +1213,8 @@ enum {
 	MLX5_CMD_OP_CREATE_FLOW_GROUP = 0x933,
 	MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY = 0x936,
 	MLX5_CMD_OP_MODIFY_FLOW_TABLE = 0x93c,
+	MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT = 0x93d,
+	MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT = 0x93e,
 	MLX5_CMD_OP_ALLOC_FLOW_COUNTER = 0x939,
 	MLX5_CMD_OP_QUERY_FLOW_COUNTER = 0x93b,
 	MLX5_CMD_OP_CREATE_GENERAL_OBJECT = 0xa00,
@@ -5180,6 +5182,43 @@ struct mlx5_ifc_modify_flow_table_out_bits {
 	u8 reserved_at_40[0x60];
 };
 
+struct mlx5_ifc_packet_reformat_context_in_bits {
+	u8 reformat_type[0x8];
+	u8 reserved_at_8[0x4];
+	u8 reformat_param_0[0x4];
+	u8 reserved_at_16[0x6];
+	u8 reformat_data_size[0xa];
+
+	u8 reformat_param_1[0x8];
+	u8 reserved_at_40[0x8];
+	u8 reformat_data[6][0x8];
+
+	u8 more_reformat_data[][0x8];
+};
+
+struct mlx5_ifc_alloc_packet_reformat_context_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+
+	u8 reserved_at_40[0xa0];
+
+	u8 packet_reformat_context[];
+};
+
+struct mlx5_ifc_alloc_packet_reformat_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+
+	u8 syndrome[0x20];
+
+	u8 packet_reformat_id[0x20];
+
+	u8 reserved_at_60[0x20];
+};
+
 /* CQE format mask. */
 #define MLX5E_CQE_FORMAT_MASK 0xc
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c
index 7771aeb8cf..d20ec7f0c4 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.c
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c
@@ -779,6 +779,66 @@ mlx5dr_cmd_sq_create(struct ibv_context *ctx,
 	return devx_obj;
 }
 
+struct mlx5dr_devx_obj *
+mlx5dr_cmd_packet_reformat_create(struct ibv_context *ctx,
+				  struct mlx5dr_cmd_packet_reformat_create_attr *attr)
+{
+	uint32_t out[DEVX_ST_SZ_DW(alloc_packet_reformat_out)] = {0};
+	size_t insz, cmd_data_sz, cmd_total_sz;
+	struct mlx5dr_devx_obj *devx_obj;
+	void *prctx;
+	void *pdata;
+	void *in;
+
+	cmd_total_sz = DEVX_ST_SZ_BYTES(alloc_packet_reformat_context_in);
+	cmd_total_sz += DEVX_ST_SZ_BYTES(packet_reformat_context_in);
+	cmd_data_sz = DEVX_FLD_SZ_BYTES(packet_reformat_context_in, reformat_data);
+	insz = align(cmd_total_sz + attr->data_sz - cmd_data_sz, DW_SIZE);
+	in = simple_calloc(1, insz);
+	if (!in) {
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+
+	MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
+		 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
+
+	prctx = DEVX_ADDR_OF(alloc_packet_reformat_context_in, in,
+			     packet_reformat_context);
+	pdata = DEVX_ADDR_OF(packet_reformat_context_in, prctx, reformat_data);
+
+	MLX5_SET(packet_reformat_context_in, prctx, reformat_type, attr->type);
+	MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, attr->reformat_param_0);
+	MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, attr->data_sz);
+	memcpy(pdata, attr->data, attr->data_sz);
+
+	devx_obj = simple_malloc(sizeof(*devx_obj));
+	if (!devx_obj) {
+		DR_LOG(ERR, "Failed to allocate memory for packet reformat object");
+		rte_errno = ENOMEM;
+		goto out_free_in;
+	}
+
+	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, insz, out, sizeof(out));
+	if (!devx_obj->obj) {
+		DR_LOG(ERR, "Failed to create packet reformat");
+		rte_errno = errno;
+		goto out_free_devx;
+	}
+
+	devx_obj->id = MLX5_GET(alloc_packet_reformat_out, out, packet_reformat_id);
+
+	simple_free(in);
+
+	return devx_obj;
+
+out_free_devx:
+	simple_free(devx_obj);
+out_free_in:
+	simple_free(in);
+	return NULL;
+}
+
 int mlx5dr_cmd_sq_modify_rdy(struct mlx5dr_devx_obj *devx_obj)
 {
 	uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0};
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h
index e57013c309..ee427c1829 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.h
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h
@@ -155,6 +155,13 @@ struct mlx5dr_cmd_allow_other_vhca_access_attr {
 	uint8_t access_key[ACCESS_KEY_LEN];
 };
 
+struct mlx5dr_cmd_packet_reformat_create_attr {
+	uint8_t type;
+	size_t data_sz;
+	void *data;
+	uint8_t reformat_param_0;
+};
+
 struct mlx5dr_cmd_query_ft_caps {
 	uint8_t max_level;
 	uint8_t reparse;
@@ -270,6 +277,10 @@ mlx5dr_cmd_header_modify_pattern_create(struct ibv_context *ctx,
 					uint32_t pattern_length,
 					uint8_t *actions);
 
+struct mlx5dr_devx_obj *
+mlx5dr_cmd_packet_reformat_create(struct ibv_context *ctx,
+				  struct mlx5dr_cmd_packet_reformat_create_attr *attr);
+
 struct mlx5dr_devx_obj *
 mlx5dr_cmd_set_fte(struct ibv_context *ctx,
 		   uint32_t table_type,
diff --git a/drivers/net/mlx5/hws/mlx5dr_internal.h b/drivers/net/mlx5/hws/mlx5dr_internal.h
index c3c077667d..3770d28e62 100644
--- a/drivers/net/mlx5/hws/mlx5dr_internal.h
+++ b/drivers/net/mlx5/hws/mlx5dr_internal.h
@@ -91,4 +91,9 @@ static inline uint64_t roundup_pow_of_two(uint64_t n)
 	return n == 1 ? 1 : 1ULL << log2above(n);
 }
 
+static inline unsigned long align(unsigned long val, unsigned long align)
+{
+	return (val + align - 1) & ~(align - 1);
+}
+
 #endif /* MLX5DR_INTERNAL_H_ */
diff --git a/drivers/net/mlx5/hws/mlx5dr_send.c b/drivers/net/mlx5/hws/mlx5dr_send.c
index e58fdeb117..622d574bfa 100644
--- a/drivers/net/mlx5/hws/mlx5dr_send.c
+++ b/drivers/net/mlx5/hws/mlx5dr_send.c
@@ -668,11 +668,6 @@ static int mlx5dr_send_ring_create_sq_obj(struct mlx5dr_context *ctx,
 	return err;
 }
 
-static inline unsigned long align(unsigned long val, unsigned long align)
-{
-	return (val + align - 1) & ~(align - 1);
-}
-
 static int mlx5dr_send_ring_open_sq(struct mlx5dr_context *ctx,
 				    struct mlx5dr_send_engine *queue,
 				    struct mlx5dr_send_ring_sq *sq,
-- 
2.20.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v1 2/3] net/mlx5/hws: add mlx5dr obj struct to mlx5dr action
  2023-09-28 13:09 [PATCH v1 0/3] Add HWS mirroring support Shun Hao
  2023-09-28 13:09 ` [PATCH v1 1/3] net/mlx5/hws: add creation of packet reformat DevX obj Shun Hao
@ 2023-09-28 13:09 ` Shun Hao
  2023-09-28 13:09 ` [PATCH v1 3/3] net/mlx5/hws: add support for mirroring Shun Hao
  2 siblings, 0 replies; 4+ messages in thread
From: Shun Hao @ 2023-09-28 13:09 UTC (permalink / raw)
  To: viacheslavo, matan, orika, Suanming Mou
  Cc: dev, rasland, Hamdan Igbaria, Alex Vesker

From: Hamdan Igbaria <hamdani@nvidia.com>

Add mlx5dr_devx_obj struct to mlx5dr_action, so we could hold
the FT obj in dest table action.

Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
Acked-by: Alex Vesker <valex@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr_action.c | 2 ++
 drivers/net/mlx5/hws/mlx5dr_action.h | 3 +++
 drivers/net/mlx5/hws/mlx5dr_table.c  | 1 -
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index d38201d738..ba17d97517 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -785,6 +785,8 @@ mlx5dr_action_create_dest_table(struct mlx5dr_context *ctx,
 		ret = mlx5dr_action_create_stcs(action, tbl->ft);
 		if (ret)
 			goto free_action;
+
+		action->devx_dest.devx_obj = tbl->ft;
 	}
 
 	return action;
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h
index 314e289780..104c6880c1 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.h
+++ b/drivers/net/mlx5/hws/mlx5dr_action.h
@@ -148,6 +148,9 @@ struct mlx5dr_action {
 				struct {
 					struct mlx5dv_steering_anchor *sa;
 				} root_tbl;
+				struct {
+					struct mlx5dr_devx_obj *devx_obj;
+				} devx_dest;
 			};
 		};
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c
index f91f04d924..c26b22c248 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.c
+++ b/drivers/net/mlx5/hws/mlx5dr_table.c
@@ -68,7 +68,6 @@ static void mlx5dr_table_down_default_fdb_miss_tbl(struct mlx5dr_table *tbl)
 		return;
 
 	mlx5dr_cmd_forward_tbl_destroy(default_miss);
-
 	ctx->common_res[tbl_type].default_miss = NULL;
 }
 
-- 
2.20.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v1 3/3] net/mlx5/hws: add support for mirroring
  2023-09-28 13:09 [PATCH v1 0/3] Add HWS mirroring support Shun Hao
  2023-09-28 13:09 ` [PATCH v1 1/3] net/mlx5/hws: add creation of packet reformat DevX obj Shun Hao
  2023-09-28 13:09 ` [PATCH v1 2/3] net/mlx5/hws: add mlx5dr obj struct to mlx5dr action Shun Hao
@ 2023-09-28 13:09 ` Shun Hao
  2 siblings, 0 replies; 4+ messages in thread
From: Shun Hao @ 2023-09-28 13:09 UTC (permalink / raw)
  To: viacheslavo, matan, orika, Suanming Mou; +Cc: dev, rasland, Alex Vesker

This patch supports mirroring by adding an dest_array action. The action
accecpts a list containing multiple destination actions, and can duplicate
packet and forward to each destination in the list.

Signed-off-by: Shun Hao <shunh@nvidia.com>
Acked-by: Alex Vesker <valex@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h       |  23 ++++-
 drivers/net/mlx5/hws/mlx5dr.h        |  34 +++++++
 drivers/net/mlx5/hws/mlx5dr_action.c | 132 ++++++++++++++++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_action.h |   3 +
 drivers/net/mlx5/hws/mlx5dr_cmd.c    |  63 +++++++++++--
 drivers/net/mlx5/hws/mlx5dr_cmd.h    |  19 +++-
 drivers/net/mlx5/hws/mlx5dr_debug.c  |   1 +
 drivers/net/mlx5/hws/mlx5dr_table.c  |   7 +-
 8 files changed, 264 insertions(+), 18 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 6749f2c037..5d62dd8e84 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -2310,7 +2310,11 @@ struct mlx5_ifc_cmd_hca_cap_2_bits {
 };
 
 struct mlx5_ifc_esw_cap_bits {
-	u8 reserved_at_0[0x60];
+	u8 reserved_at_0[0x1d];
+	u8 merged_eswitch[0x1];
+	u8 reserved_at_1e[0x2];
+
+	u8 reserved_at_20[0x40];
 
 	u8 esw_manager_vport_number_valid[0x1];
 	u8 reserved_at_61[0xf];
@@ -5034,6 +5038,7 @@ struct mlx5_ifc_query_flow_table_out_bits {
 enum mlx5_flow_destination_type {
 	MLX5_FLOW_DESTINATION_TYPE_VPORT = 0x0,
 	MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1,
+	MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2,
 };
 
 enum mlx5_flow_context_action {
@@ -5073,6 +5078,19 @@ union mlx5_ifc_dest_format_flow_counter_list_auto_bits {
 	u8 reserved_at_0[0x40];
 };
 
+struct mlx5_ifc_extended_dest_format_bits {
+	struct mlx5_ifc_dest_format_bits destination_entry;
+
+	u8 packet_reformat_id[0x20];
+
+	u8 reserved_at_60[0x20];
+};
+
+#define MLX5_IFC_MULTI_PATH_FT_MAX_LEVEL 64
+
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
 struct mlx5_ifc_flow_context_bits {
 	u8 reserved_at_00[0x20];
 	u8 group_id[0x20];
@@ -5091,8 +5109,7 @@ struct mlx5_ifc_flow_context_bits {
 	u8 reserved_at_e0[0x40];
 	u8 encrypt_decrypt_obj_id[0x20];
 	u8 reserved_at_140[0x16c0];
-	/* Currently only one destnation */
-	union mlx5_ifc_dest_format_flow_counter_list_auto_bits destination[1];
+	union mlx5_ifc_dest_format_flow_counter_list_auto_bits destination[0];
 };
 
 struct mlx5_ifc_set_fte_in_bits {
diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index 184de8feaf..5eabbc34a4 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -46,6 +46,7 @@ enum mlx5dr_action_type {
 	MLX5DR_ACTION_TYP_ASO_METER,
 	MLX5DR_ACTION_TYP_ASO_CT,
 	MLX5DR_ACTION_TYP_DEST_ROOT,
+	MLX5DR_ACTION_TYP_DEST_ARRAY,
 	MLX5DR_ACTION_TYP_MAX,
 };
 
@@ -213,6 +214,20 @@ struct mlx5dr_rule_action {
 	};
 };
 
+struct mlx5dr_action_dest_attr {
+	/* Required action combination */
+	enum mlx5dr_action_type *action_type;
+
+	/* Required destination action to forward the packet */
+	struct mlx5dr_action *dest;
+
+	/* Optional reformat data */
+	struct {
+		size_t reformat_data_sz;
+		void *reformat_data;
+	} reformat;
+};
+
 /* Open a context used for direct rule insertion using hardware steering.
  * Each context can contain multiple tables of different types.
  *
@@ -604,6 +619,25 @@ mlx5dr_action_create_pop_vlan(struct mlx5dr_context *ctx, uint32_t flags);
 struct mlx5dr_action *
 mlx5dr_action_create_push_vlan(struct mlx5dr_context *ctx, uint32_t flags);
 
+/* Create a dest array action, this action can duplicate packets and forward to
+ * multiple destinations in the destination list.
+ * @param[in] ctx
+ *     The context in which the new action will be created.
+ * @param[in] num_dest
+ *     The number of dests attributes.
+ * @param[in] dests
+ *     The destination array. Each contains a destination action and can have
+ *     additional actions.
+ * @param[in] flags
+ *     Action creation flags. (enum mlx5dr_action_flags)
+ * @return pointer to mlx5dr_action on success NULL otherwise.
+ */
+struct mlx5dr_action *
+mlx5dr_action_create_dest_array(struct mlx5dr_context *ctx,
+				size_t num_dest,
+				struct mlx5dr_action_dest_attr *dests,
+				uint32_t flags);
+
 /* Create dest root table, this action will jump to root table according
  * the given priority.
  * @param[in] ctx
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index ba17d97517..e890ebb481 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -34,7 +34,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_MISS) |
 		BIT(MLX5DR_ACTION_TYP_TIR) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ROOT),
+		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
+		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 	[MLX5DR_TABLE_TYPE_NIC_TX] = {
@@ -71,7 +72,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_MISS) |
 		BIT(MLX5DR_ACTION_TYP_VPORT) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ROOT),
+		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
+		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 };
@@ -533,6 +535,7 @@ static void mlx5dr_action_fill_stc_attr(struct mlx5dr_action *action,
 		}
 		break;
 	case MLX5DR_ACTION_TYP_TBL:
+	case MLX5DR_ACTION_TYP_DEST_ARRAY:
 		attr->action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT;
 		attr->action_offset = MLX5DR_ACTION_OFFSET_HIT;
 		attr->dest_table_id = obj->id;
@@ -864,6 +867,8 @@ mlx5dr_action_create_dest_tir(struct mlx5dr_context *ctx,
 		ret = mlx5dr_action_create_stcs(action, cur_obj);
 		if (ret)
 			goto clean_obj;
+
+		action->devx_dest.devx_obj = cur_obj;
 	}
 
 	return action;
@@ -1696,6 +1701,124 @@ mlx5dr_action_create_modify_header(struct mlx5dr_context *ctx,
 	return NULL;
 }
 
+struct mlx5dr_action *
+mlx5dr_action_create_dest_array(struct mlx5dr_context *ctx,
+				size_t num_dest,
+				struct mlx5dr_action_dest_attr *dests,
+				uint32_t flags)
+{
+	struct mlx5dr_cmd_set_fte_dest *dest_list = NULL;
+	struct mlx5dr_cmd_ft_create_attr ft_attr = {0};
+	struct mlx5dr_cmd_set_fte_attr fte_attr = {0};
+	struct mlx5dr_cmd_forward_tbl *fw_island;
+	enum mlx5dr_table_type table_type;
+	struct mlx5dr_action *action;
+	uint32_t i;
+	int ret;
+
+	if (num_dest <= 1) {
+		rte_errno = EINVAL;
+		DR_LOG(ERR, "Action must have multiple dests");
+		return NULL;
+	}
+
+	if (flags == (MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_SHARED)) {
+		ft_attr.type = FS_FT_NIC_RX;
+		ft_attr.level = MLX5_IFC_MULTI_PATH_FT_MAX_LEVEL - 1;
+		table_type = MLX5DR_TABLE_TYPE_NIC_RX;
+	} else if (flags == (MLX5DR_ACTION_FLAG_HWS_FDB | MLX5DR_ACTION_FLAG_SHARED)) {
+		ft_attr.type = FS_FT_FDB;
+		ft_attr.level = ctx->caps->fdb_ft.max_level - 1;
+		table_type = MLX5DR_TABLE_TYPE_FDB;
+	} else {
+		DR_LOG(ERR, "Action flags not supported");
+		rte_errno = ENOTSUP;
+		return NULL;
+	}
+
+	if (mlx5dr_context_shared_gvmi_used(ctx)) {
+		DR_LOG(ERR, "Cannot use this action in shared GVMI context");
+		rte_errno = ENOTSUP;
+		return NULL;
+	}
+
+	dest_list = simple_calloc(num_dest, sizeof(*dest_list));
+	if (!dest_list) {
+		DR_LOG(ERR, "Failed to allocate memory for destinations");
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+
+	for (i = 0; i < num_dest; i++) {
+		enum mlx5dr_action_type *action_type = dests[i].action_type;
+
+		if (!mlx5dr_action_check_combo(dests[i].action_type, table_type)) {
+			DR_LOG(ERR, "Invalid combination of actions");
+			rte_errno = EINVAL;
+			goto free_dest_list;
+		}
+
+		for (; *action_type != MLX5DR_ACTION_TYP_LAST; action_type++) {
+			switch (*action_type) {
+			case MLX5DR_ACTION_TYP_TBL:
+				dest_list[i].destination_type =
+					MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+				dest_list[i].destination_id = dests[i].dest->devx_dest.devx_obj->id;
+				fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+				fte_attr.ignore_flow_level = 1;
+				break;
+			case MLX5DR_ACTION_TYP_VPORT:
+				dest_list[i].destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+				dest_list[i].destination_id = dests[i].dest->vport.vport_num;
+				fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+				if (ctx->caps->merged_eswitch) {
+					dest_list[i].ext_flags |=
+						MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID;
+					dest_list[i].esw_owner_vhca_id =
+						dests[i].dest->vport.esw_owner_vhca_id;
+				}
+				break;
+			case MLX5DR_ACTION_TYP_TIR:
+				dest_list[i].destination_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
+				dest_list[i].destination_id = dests[i].dest->devx_dest.devx_obj->id;
+				fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+				break;
+			default:
+				DR_LOG(ERR, "Unsupported action in dest_array");
+				rte_errno = ENOTSUP;
+				goto free_dest_list;
+			}
+		}
+	}
+	fte_attr.dests_num = num_dest;
+	fte_attr.dests = dest_list;
+
+	fw_island = mlx5dr_cmd_forward_tbl_create(ctx->ibv_ctx, &ft_attr, &fte_attr);
+	if (!fw_island)
+		goto free_dest_list;
+
+	action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_DEST_ARRAY);
+	if (!action)
+		goto destroy_fw_island;
+
+	ret = mlx5dr_action_create_stcs(action, fw_island->ft);
+	if (ret)
+		goto free_action;
+
+	action->dest_array.fw_island = fw_island;
+
+	simple_free(dest_list);
+	return action;
+
+free_action:
+	simple_free(action);
+destroy_fw_island:
+	mlx5dr_cmd_forward_tbl_destroy(fw_island);
+free_dest_list:
+	simple_free(dest_list);
+	return NULL;
+}
+
 struct mlx5dr_action *
 mlx5dr_action_create_dest_root(struct mlx5dr_context *ctx,
 			       uint16_t priority,
@@ -1778,6 +1901,10 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 		mlx5dr_action_destroy_stcs(action);
 		mlx5dr_action_put_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_POP);
 		break;
+	case MLX5DR_ACTION_TYP_DEST_ARRAY:
+		mlx5dr_action_destroy_stcs(action);
+		mlx5dr_cmd_forward_tbl_destroy(action->dest_array.fw_island);
+		break;
 	case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2:
 	case MLX5DR_ACTION_TYP_MODIFY_HDR:
 		for (i = 0; i < action->modify_header.num_of_patterns; i++) {
@@ -2285,6 +2412,7 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at)
 		case MLX5DR_ACTION_TYP_TIR:
 		case MLX5DR_ACTION_TYP_TBL:
 		case MLX5DR_ACTION_TYP_DEST_ROOT:
+		case MLX5DR_ACTION_TYP_DEST_ARRAY:
 		case MLX5DR_ACTION_TYP_VPORT:
 		case MLX5DR_ACTION_TYP_MISS:
 			/* Hit action */
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h
index 104c6880c1..efe07c9d47 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.h
+++ b/drivers/net/mlx5/hws/mlx5dr_action.h
@@ -151,6 +151,9 @@ struct mlx5dr_action {
 				struct {
 					struct mlx5dr_devx_obj *devx_obj;
 				} devx_dest;
+				struct {
+					struct mlx5dr_cmd_forward_tbl *fw_island;
+				} dest_array;
 			};
 		};
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c
index d20ec7f0c4..3b4545324e 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.c
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c
@@ -157,18 +157,31 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx,
 		   uint32_t group_id,
 		   struct mlx5dr_cmd_set_fte_attr *fte_attr)
 {
-	uint32_t in[MLX5_ST_SZ_DW(set_fte_in) + MLX5_ST_SZ_DW(dest_format)] = {0};
 	uint32_t out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
 	struct mlx5dr_devx_obj *devx_obj;
+	uint32_t dest_entry_sz;
+	uint32_t total_dest_sz;
 	void *in_flow_context;
 	uint32_t action_flags;
-	void *in_dests;
+	uint8_t *in_dests;
+	uint32_t inlen;
+	uint32_t *in;
+	uint32_t i;
+
+	dest_entry_sz = MLX5_ST_SZ_BYTES(dest_format);
+	total_dest_sz = dest_entry_sz * fte_attr->dests_num;
+	inlen = align((MLX5_ST_SZ_BYTES(set_fte_in) + total_dest_sz), DW_SIZE);
+	in = simple_calloc(1, inlen);
+	if (!in) {
+		rte_errno = ENOMEM;
+		return NULL;
+	}
 
 	devx_obj = simple_malloc(sizeof(*devx_obj));
 	if (!devx_obj) {
 		DR_LOG(ERR, "Failed to allocate memory for fte object");
 		rte_errno = ENOMEM;
-		return NULL;
+		goto free_in;
 	}
 
 	MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
@@ -178,19 +191,45 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx,
 	in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
 	MLX5_SET(flow_context, in_flow_context, group_id, group_id);
 	MLX5_SET(flow_context, in_flow_context, flow_source, fte_attr->flow_source);
+	MLX5_SET(set_fte_in, in, ignore_flow_level, fte_attr->ignore_flow_level);
 
 	action_flags = fte_attr->action_flags;
 	MLX5_SET(flow_context, in_flow_context, action, action_flags);
 
 	if (action_flags & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
-		/* Only destination_list_size of size 1 is supported */
-		MLX5_SET(flow_context, in_flow_context, destination_list_size, 1);
-		in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
-		MLX5_SET(dest_format, in_dests, destination_type, fte_attr->destination_type);
-		MLX5_SET(dest_format, in_dests, destination_id, fte_attr->destination_id);
+		in_dests = (uint8_t *)MLX5_ADDR_OF(flow_context, in_flow_context, destination);
+
+		for (i = 0; i < fte_attr->dests_num; i++) {
+			struct mlx5dr_cmd_set_fte_dest *dest = &fte_attr->dests[i];
+
+			switch (dest->destination_type) {
+			case MLX5_FLOW_DESTINATION_TYPE_VPORT:
+				if (dest->ext_flags & MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID) {
+					MLX5_SET(dest_format, in_dests,
+						 destination_eswitch_owner_vhca_id_valid, 1);
+					MLX5_SET(dest_format, in_dests,
+						 destination_eswitch_owner_vhca_id,
+						 dest->esw_owner_vhca_id);
+				}
+				/* Fall through */
+			case MLX5_FLOW_DESTINATION_TYPE_TIR:
+			case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
+				MLX5_SET(dest_format, in_dests, destination_type,
+					 dest->destination_type);
+				MLX5_SET(dest_format, in_dests, destination_id,
+					 dest->destination_id);
+				break;
+			default:
+				rte_errno = EOPNOTSUPP;
+				goto free_devx;
+			}
+
+			in_dests = in_dests + dest_entry_sz;
+		}
+		MLX5_SET(flow_context, in_flow_context, destination_list_size, fte_attr->dests_num);
 	}
 
-	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
+	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out));
 	if (!devx_obj->obj) {
 		DR_LOG(ERR, "Failed to create FTE (syndrome: %#x)",
 		       mlx5dr_cmd_get_syndrome(out));
@@ -198,10 +237,13 @@ mlx5dr_cmd_set_fte(struct ibv_context *ctx,
 		goto free_devx;
 	}
 
+	simple_free(in);
 	return devx_obj;
 
 free_devx:
 	simple_free(devx_obj);
+free_in:
+	simple_free(in);
 	return NULL;
 }
 
@@ -1224,6 +1266,9 @@ int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
 			caps->eswitch_manager_vport_number =
 			MLX5_GET(query_hca_cap_out, out,
 				 capability.esw_cap.esw_manager_vport_number);
+
+		caps->merged_eswitch = MLX5_GET(query_hca_cap_out, out,
+						capability.esw_cap.merged_eswitch);
 	}
 
 	ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h
index ee427c1829..37cb501c98 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.h
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h
@@ -5,11 +5,25 @@
 #ifndef MLX5DR_CMD_H_
 #define MLX5DR_CMD_H_
 
-struct mlx5dr_cmd_set_fte_attr {
-	uint32_t action_flags;
+enum mlx5dr_cmd_ext_dest_flags {
+	MLX5DR_CMD_EXT_DEST_REFORMAT = 1 << 0,
+	MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID = 1 << 1,
+};
+
+struct mlx5dr_cmd_set_fte_dest {
 	uint8_t destination_type;
 	uint32_t destination_id;
+	enum mlx5dr_cmd_ext_dest_flags ext_flags;
+	uint16_t esw_owner_vhca_id;
+};
+
+struct mlx5dr_cmd_set_fte_attr {
+	uint32_t action_flags;
+	uint8_t ignore_flow_level;
 	uint8_t flow_source;
+	uint32_t packet_reformat_id;
+	uint32_t dests_num;
+	struct mlx5dr_cmd_set_fte_dest *dests;
 };
 
 struct mlx5dr_cmd_ft_create_attr {
@@ -210,6 +224,7 @@ struct mlx5dr_cmd_query_caps {
 	struct mlx5dr_cmd_query_ft_caps nic_ft;
 	struct mlx5dr_cmd_query_ft_caps fdb_ft;
 	bool eswitch_manager;
+	uint8_t merged_eswitch;
 	uint32_t eswitch_manager_vport_number;
 	uint8_t log_header_modify_argument_granularity;
 	uint8_t log_header_modify_argument_max_alloc;
diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c
index 48810142a0..7ede8ec43f 100644
--- a/drivers/net/mlx5/hws/mlx5dr_debug.c
+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c
@@ -23,6 +23,7 @@ const char *mlx5dr_debug_action_type_str[] = {
 	[MLX5DR_ACTION_TYP_ASO_METER] = "ASO_METER",
 	[MLX5DR_ACTION_TYP_ASO_CT] = "ASO_CT",
 	[MLX5DR_ACTION_TYP_DEST_ROOT] = "DEST_ROOT",
+	[MLX5DR_ACTION_TYP_DEST_ARRAY] = "DEST_ARRAY",
 };
 
 static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c
index c26b22c248..c8d60e68f3 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.c
+++ b/drivers/net/mlx5/hws/mlx5dr_table.c
@@ -22,6 +22,7 @@ mlx5dr_table_up_default_fdb_miss_tbl(struct mlx5dr_table *tbl)
 	struct mlx5dr_cmd_ft_create_attr ft_attr = {0};
 	struct mlx5dr_cmd_set_fte_attr fte_attr = {0};
 	struct mlx5dr_cmd_forward_tbl *default_miss;
+	struct mlx5dr_cmd_set_fte_dest dest = {0};
 	struct mlx5dr_context *ctx = tbl->ctx;
 	uint8_t tbl_type = tbl->type;
 
@@ -37,9 +38,11 @@ mlx5dr_table_up_default_fdb_miss_tbl(struct mlx5dr_table *tbl)
 	ft_attr.level = tbl->ctx->caps->fdb_ft.max_level; /* The last level */
 	ft_attr.rtc_valid = false;
 
+	dest.destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+	dest.destination_id = ctx->caps->eswitch_manager_vport_number;
 	fte_attr.action_flags = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
-	fte_attr.destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
-	fte_attr.destination_id = ctx->caps->eswitch_manager_vport_number;
+	fte_attr.dests_num = 1;
+	fte_attr.dests = &dest;
 
 	default_miss = mlx5dr_cmd_forward_tbl_create(mlx5dr_context_get_local_ibv(ctx),
 						     &ft_attr, &fte_attr);
-- 
2.20.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-09-28 13:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-28 13:09 [PATCH v1 0/3] Add HWS mirroring support Shun Hao
2023-09-28 13:09 ` [PATCH v1 1/3] net/mlx5/hws: add creation of packet reformat DevX obj Shun Hao
2023-09-28 13:09 ` [PATCH v1 2/3] net/mlx5/hws: add mlx5dr obj struct to mlx5dr action Shun Hao
2023-09-28 13:09 ` [PATCH v1 3/3] net/mlx5/hws: add support for mirroring Shun Hao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).