@@ -2085,7 +2085,10 @@ struct mlx5_ifc_flow_table_prop_layout_bits {
u8 reparse[0x1];
u8 reserved_at_6b[0x1];
u8 cross_vhca_object[0x1];
- u8 reserved_at_6d[0xb];
+ u8 reformat_l2_to_l3_audp_tunnel[0x1];
+ u8 reformat_l3_audp_tunnel_to_l2[0x1];
+ u8 ignore_flow_level_rtc_valid[0x1];
+ u8 reserved_at_70[0x8];
u8 log_max_ft_num[0x8];
u8 reserved_at_80[0x10];
u8 log_max_flow_counter[0x8];
@@ -237,6 +237,18 @@ mlx5dr_table_create(struct mlx5dr_context *ctx,
*/
int mlx5dr_table_destroy(struct mlx5dr_table *tbl);
+/* Set default miss table for mlx5dr_table by using another mlx5dr_table
+ * Traffic which all table matchers miss will be forwarded to miss table.
+ *
+ * @param[in] tbl
+ * source mlx5dr table
+ * @param[in] miss_tbl
+ * target (miss) mlx5dr table, or NULL to remove current miss table
+ * @return zero on success non zero otherwise.
+ */
+int mlx5dr_table_set_default_miss(struct mlx5dr_table *tbl,
+ struct mlx5dr_table *miss_tbl);
+
/* Create new match template based on items mask, the match template
* will be used for matcher creation.
*
@@ -581,7 +581,6 @@ mlx5dr_cmd_header_modify_pattern_create(struct ibv_context *ctx,
rte_errno = ENOMEM;
return NULL;
}
-
attr = MLX5_ADDR_OF(create_header_modify_pattern_in, in, hdr);
MLX5_SET(general_obj_in_cmd_hdr,
attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
@@ -1032,6 +1031,12 @@ int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
capability.flow_table_nic_cap.
flow_table_properties_nic_receive.reparse);
+ caps->nic_ft.ignore_flow_level_rtc_valid =
+ MLX5_GET(query_hca_cap_out,
+ out,
+ capability.flow_table_nic_cap.
+ flow_table_properties_nic_receive.ignore_flow_level_rtc_valid);
+
/* check cross-VHCA support in flow table properties */
res =
MLX5_GET(query_hca_cap_out, out,
@@ -158,6 +158,7 @@ struct mlx5dr_cmd_allow_other_vhca_access_attr {
struct mlx5dr_cmd_query_ft_caps {
uint8_t max_level;
uint8_t reparse;
+ uint8_t ignore_flow_level_rtc_valid;
};
struct mlx5dr_cmd_query_vport_caps {
@@ -331,11 +331,12 @@ static int mlx5dr_debug_dump_table(FILE *f, struct mlx5dr_table *tbl)
}
}
- ret = fprintf(f, ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 "\n",
+ ret = fprintf(f, ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 "\n",
mlx5dr_debug_icm_to_idx(icm_addr_0),
mlx5dr_debug_icm_to_idx(icm_addr_1),
mlx5dr_debug_icm_to_idx(local_icm_addr_0),
- mlx5dr_debug_icm_to_idx(local_icm_addr_1));
+ mlx5dr_debug_icm_to_idx(local_icm_addr_1),
+ (uint64_t)(uintptr_t)tbl->default_miss.miss_tbl);
if (ret < 0)
goto out_err;
@@ -43,29 +43,21 @@ static void mlx5dr_matcher_destroy_end_ft(struct mlx5dr_matcher *matcher)
mlx5dr_table_destroy_default_ft(matcher->tbl, matcher->end_ft);
}
-static int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx,
- uint32_t fw_ft_type,
- enum mlx5dr_table_type type,
- struct mlx5dr_devx_obj *devx_obj)
+int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx,
+ uint32_t fw_ft_type,
+ enum mlx5dr_table_type type,
+ struct mlx5dr_devx_obj *devx_obj)
{
- struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
int ret;
if (type != MLX5DR_TABLE_TYPE_FDB && !mlx5dr_context_shared_gvmi_used(ctx))
return 0;
- ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
- ft_attr.type = fw_ft_type;
- ft_attr.rtc_id_0 = 0;
- ft_attr.rtc_id_1 = 0;
-
- ret = mlx5dr_cmd_flow_table_modify(devx_obj, &ft_attr);
- if (ret) {
+ ret = mlx5dr_table_ft_set_next_rtc(devx_obj, fw_ft_type, NULL, NULL);
+ if (ret)
DR_LOG(ERR, "Failed to disconnect previous RTC");
- return ret;
- }
- return 0;
+ return ret;
}
static int mlx5dr_matcher_shared_point_end_ft(struct mlx5dr_matcher *matcher)
@@ -200,12 +192,10 @@ static int mlx5dr_matcher_shared_update_local_ft(struct mlx5dr_table *tbl)
static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
{
- struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
struct mlx5dr_table *tbl = matcher->tbl;
struct mlx5dr_matcher *prev = NULL;
struct mlx5dr_matcher *next = NULL;
struct mlx5dr_matcher *tmp_matcher;
- struct mlx5dr_devx_obj *ft;
int ret;
/* Find location in matcher list */
@@ -228,32 +218,30 @@ static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
LIST_INSERT_AFTER(prev, matcher, next);
connect:
- ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
- ft_attr.type = tbl->fw_ft_type;
-
- /* Connect to next */
if (next) {
- if (next->match_ste.rtc_0)
- ft_attr.rtc_id_0 = next->match_ste.rtc_0->id;
- if (next->match_ste.rtc_1)
- ft_attr.rtc_id_1 = next->match_ste.rtc_1->id;
-
- ret = mlx5dr_cmd_flow_table_modify(matcher->end_ft, &ft_attr);
+ /* Connect to next RTC */
+ ret = mlx5dr_table_ft_set_next_rtc(matcher->end_ft,
+ tbl->fw_ft_type,
+ next->match_ste.rtc_0,
+ next->match_ste.rtc_1);
if (ret) {
DR_LOG(ERR, "Failed to connect new matcher to next RTC");
goto remove_from_list;
}
+ } else {
+ /* Connect last matcher to next miss_tbl if exists */
+ ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl);
+ if (ret) {
+ DR_LOG(ERR, "Failed connect new matcher to miss_tbl");
+ goto remove_from_list;
+ }
}
- /* Connect to previous */
- ft = prev ? prev->end_ft : tbl->ft;
-
- if (matcher->match_ste.rtc_0)
- ft_attr.rtc_id_0 = matcher->match_ste.rtc_0->id;
- if (matcher->match_ste.rtc_1)
- ft_attr.rtc_id_1 = matcher->match_ste.rtc_1->id;
-
- ret = mlx5dr_cmd_flow_table_modify(ft, &ft_attr);
+ /* Connect to previous FT */
+ ret = mlx5dr_table_ft_set_next_rtc(prev ? prev->end_ft : tbl->ft,
+ tbl->fw_ft_type,
+ matcher->match_ste.rtc_0,
+ matcher->match_ste.rtc_1);
if (ret) {
DR_LOG(ERR, "Failed to connect new matcher to previous FT");
goto remove_from_list;
@@ -265,6 +253,22 @@ static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
goto remove_from_list;
}
+ if (prev) {
+ /* Reset next miss FT to default (drop refcount) */
+ ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev->end_ft);
+ if (ret) {
+ DR_LOG(ERR, "Failed to reset matcher ft default miss");
+ goto remove_from_list;
+ }
+ } else {
+ /* Update tables missing to current table */
+ ret = mlx5dr_table_update_connected_miss_tables(tbl);
+ if (ret) {
+ DR_LOG(ERR, "Fatal error, failed to update connected miss table");
+ goto remove_from_list;
+ }
+ }
+
return 0;
remove_from_list:
@@ -272,81 +276,97 @@ static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
return ret;
}
-static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)
+static int mlx5dr_last_matcher_disconnect(struct mlx5dr_table *tbl,
+ struct mlx5dr_devx_obj *prev_ft)
{
struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
+
+ if (tbl->default_miss.miss_tbl) {
+ /* Connect new last matcher to next miss_tbl if exists */
+ return mlx5dr_table_connect_to_miss_table(tbl,
+ tbl->default_miss.miss_tbl);
+ } else {
+ ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
+ ft_attr.type = tbl->fw_ft_type;
+ /* Matcher is last, point prev end FT to default miss */
+ mlx5dr_cmd_set_attr_connect_miss_tbl(tbl->ctx,
+ tbl->fw_ft_type,
+ tbl->type,
+ &ft_attr);
+ return mlx5dr_cmd_flow_table_modify(prev_ft, &ft_attr);
+ }
+}
+
+static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)
+{
+ struct mlx5dr_matcher *tmp_matcher, *prev_matcher;
struct mlx5dr_table *tbl = matcher->tbl;
- struct mlx5dr_matcher *tmp_matcher;
struct mlx5dr_devx_obj *prev_ft;
struct mlx5dr_matcher *next;
int ret;
- prev_ft = matcher->tbl->ft;
+ prev_ft = tbl->ft;
+ prev_matcher = LIST_FIRST(&tbl->head);
LIST_FOREACH(tmp_matcher, &tbl->head, next) {
if (tmp_matcher == matcher)
break;
prev_ft = tmp_matcher->end_ft;
+ prev_matcher = tmp_matcher;
}
next = matcher->next.le_next;
- ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
- ft_attr.type = matcher->tbl->fw_ft_type;
+ LIST_REMOVE(matcher, next);
if (next) {
- /* Connect previous end FT to next RTC if exists */
- if (next->match_ste.rtc_0)
- ft_attr.rtc_id_0 = next->match_ste.rtc_0->id;
- if (next->match_ste.rtc_1)
- ft_attr.rtc_id_1 = next->match_ste.rtc_1->id;
+ /* Connect previous end FT to next RTC */
+ ret = mlx5dr_table_ft_set_next_rtc(prev_ft,
+ tbl->fw_ft_type,
+ next->match_ste.rtc_0,
+ next->match_ste.rtc_1);
+ if (ret) {
+ DR_LOG(ERR, "Failed to disconnect matcher");
+ goto matcher_reconnect;
+ }
} else {
- /* Matcher is last, point prev end FT to default miss */
- mlx5dr_cmd_set_attr_connect_miss_tbl(tbl->ctx,
- tbl->fw_ft_type,
- tbl->type,
- &ft_attr);
- }
-
- ret = mlx5dr_cmd_flow_table_modify(prev_ft, &ft_attr);
- if (ret) {
- DR_LOG(ERR, "Failed to disconnect matcher");
- return ret;
- }
-
- LIST_REMOVE(matcher, next);
-
- if (!next) {
- /* ft no longer points to any RTC, drop refcount */
- ret = mlx5dr_matcher_free_rtc_pointing(tbl->ctx,
- tbl->fw_ft_type,
- tbl->type,
- prev_ft);
+ ret = mlx5dr_last_matcher_disconnect(tbl, prev_ft);
if (ret) {
- DR_LOG(ERR, "Failed to reset last RTC refcount");
- return ret;
+ DR_LOG(ERR, "Failed to disconnect last matcher");
+ goto matcher_reconnect;
}
}
ret = mlx5dr_matcher_shared_update_local_ft(tbl);
if (ret) {
DR_LOG(ERR, "Failed to update local_ft in shared table");
- return ret;
+ goto matcher_reconnect;
}
- if (!next) {
- /* ft no longer points to any RTC, drop refcount */
- ret = mlx5dr_matcher_free_rtc_pointing(tbl->ctx,
- tbl->fw_ft_type,
- tbl->type,
- prev_ft);
+ /* Removing first matcher, update connected miss tables if exists */
+ if (prev_ft == tbl->ft) {
+ ret = mlx5dr_table_update_connected_miss_tables(tbl);
if (ret) {
- DR_LOG(ERR, "Failed to reset last RTC refcount");
- return ret;
+ DR_LOG(ERR, "Fatal error, failed to update connected miss table");
+ goto matcher_reconnect;
}
}
+ ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev_ft);
+ if (ret) {
+ DR_LOG(ERR, "Fatal error, failed to restore matcher ft default miss");
+ goto matcher_reconnect;
+ }
+
return 0;
+
+matcher_reconnect:
+ if (LIST_EMPTY(&tbl->head))
+ LIST_INSERT_HEAD(&matcher->tbl->head, matcher, next);
+ else
+ LIST_INSERT_AFTER(prev_matcher, matcher, next);
+
+ return ret;
}
static bool mlx5dr_matcher_supp_fw_wqe(struct mlx5dr_matcher *matcher)
@@ -115,4 +115,9 @@ static inline bool mlx5dr_matcher_is_insert_by_idx(struct mlx5dr_matcher *matche
return matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX;
}
+int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx,
+ uint32_t fw_ft_type,
+ enum mlx5dr_table_type type,
+ struct mlx5dr_devx_obj *devx_obj);
+
#endif /* MLX5DR_MATCHER_H_ */
@@ -90,7 +90,7 @@ mlx5dr_table_connect_to_default_miss_tbl(struct mlx5dr_table *tbl,
ret = mlx5dr_cmd_flow_table_modify(ft, &ft_attr);
if (ret) {
DR_LOG(ERR, "Failed to connect FT to default FDB FT");
- return errno;
+ return ret;
}
return 0;
@@ -396,7 +396,7 @@ struct mlx5dr_table *mlx5dr_table_create(struct mlx5dr_context *ctx,
return NULL;
}
- tbl = simple_malloc(sizeof(*tbl));
+ tbl = simple_calloc(1, sizeof(*tbl));
if (!tbl) {
rte_errno = ENOMEM;
return NULL;
@@ -405,7 +405,6 @@ struct mlx5dr_table *mlx5dr_table_create(struct mlx5dr_context *ctx,
tbl->ctx = ctx;
tbl->type = attr->type;
tbl->level = attr->level;
- LIST_INIT(&tbl->head);
ret = mlx5dr_table_init(tbl);
if (ret) {
@@ -427,12 +426,223 @@ struct mlx5dr_table *mlx5dr_table_create(struct mlx5dr_context *ctx,
int mlx5dr_table_destroy(struct mlx5dr_table *tbl)
{
struct mlx5dr_context *ctx = tbl->ctx;
-
pthread_spin_lock(&ctx->ctrl_lock);
+ if (!LIST_EMPTY(&tbl->head)) {
+ DR_LOG(ERR, "Cannot destroy table containing matchers");
+ rte_errno = EBUSY;
+ goto unlock_err;
+ }
+
+ if (!LIST_EMPTY(&tbl->default_miss.head)) {
+ DR_LOG(ERR, "Cannot destroy table pointed by default miss");
+ rte_errno = EBUSY;
+ goto unlock_err;
+ }
+
LIST_REMOVE(tbl, next);
pthread_spin_unlock(&ctx->ctrl_lock);
mlx5dr_table_uninit(tbl);
simple_free(tbl);
return 0;
+
+unlock_err:
+ pthread_spin_unlock(&ctx->ctrl_lock);
+ return -rte_errno;
+}
+
+static struct mlx5dr_devx_obj *
+mlx5dr_table_get_last_ft(struct mlx5dr_table *tbl)
+{
+ struct mlx5dr_devx_obj *last_ft = tbl->ft;
+ struct mlx5dr_matcher *matcher;
+
+ LIST_FOREACH(matcher, &tbl->head, next)
+ last_ft = matcher->end_ft;
+
+ return last_ft;
+}
+
+int mlx5dr_table_ft_set_default_next_ft(struct mlx5dr_table *tbl,
+ struct mlx5dr_devx_obj *ft_obj)
+{
+ struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
+ int ret;
+
+ /* Due to FW limitation, resetting the flow table to default action will
+ * disconnect RTC when ignore_flow_level_rtc_valid is not supported.
+ */
+ if (!tbl->ctx->caps->nic_ft.ignore_flow_level_rtc_valid)
+ return 0;
+
+ if (tbl->type == MLX5DR_TABLE_TYPE_FDB)
+ return mlx5dr_table_connect_to_default_miss_tbl(tbl, ft_obj);
+
+ ft_attr.type = tbl->fw_ft_type;
+ ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION;
+ ft_attr.table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_DEFAULT;
+
+ ret = mlx5dr_cmd_flow_table_modify(ft_obj, &ft_attr);
+ if (ret) {
+ DR_LOG(ERR, "Failed to set FT default miss action");
+ return ret;
+ }
+
+ return 0;
+}
+
+int mlx5dr_table_ft_set_next_rtc(struct mlx5dr_devx_obj *ft,
+ uint32_t fw_ft_type,
+ struct mlx5dr_devx_obj *rtc_0,
+ struct mlx5dr_devx_obj *rtc_1)
+{
+ struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
+
+ ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
+ ft_attr.type = fw_ft_type;
+ ft_attr.rtc_id_0 = rtc_0 ? rtc_0->id : 0;
+ ft_attr.rtc_id_1 = rtc_1 ? rtc_1->id : 0;
+
+ return mlx5dr_cmd_flow_table_modify(ft, &ft_attr);
+}
+
+static int mlx5dr_table_ft_set_next_ft(struct mlx5dr_devx_obj *ft,
+ uint32_t fw_ft_type,
+ uint32_t next_ft_id)
+{
+ struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
+
+ ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION;
+ ft_attr.table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_GOTO_TBL;
+ ft_attr.type = fw_ft_type;
+ ft_attr.table_miss_id = next_ft_id;
+
+ return mlx5dr_cmd_flow_table_modify(ft, &ft_attr);
+}
+
+int mlx5dr_table_update_connected_miss_tables(struct mlx5dr_table *dst_tbl)
+{
+ struct mlx5dr_table *src_tbl;
+ int ret;
+
+ if (LIST_EMPTY(&dst_tbl->default_miss.head))
+ return 0;
+
+ LIST_FOREACH(src_tbl, &dst_tbl->default_miss.head, default_miss.next) {
+ ret = mlx5dr_table_connect_to_miss_table(src_tbl, dst_tbl);
+ if (ret) {
+ DR_LOG(ERR, "Failed to update source miss table, unexpected behavior");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int mlx5dr_table_connect_to_miss_table(struct mlx5dr_table *src_tbl,
+ struct mlx5dr_table *dst_tbl)
+{
+ struct mlx5dr_devx_obj *last_ft;
+ struct mlx5dr_matcher *matcher;
+ int ret;
+
+ last_ft = mlx5dr_table_get_last_ft(src_tbl);
+
+ if (dst_tbl) {
+ if (LIST_EMPTY(&dst_tbl->head)) {
+ /* Connect src_tbl last_ft to dst_tbl start anchor */
+ ret = mlx5dr_table_ft_set_next_ft(last_ft,
+ src_tbl->fw_ft_type,
+ dst_tbl->ft->id);
+ if (ret)
+ return ret;
+
+ /* Reset last_ft RTC to default RTC */
+ ret = mlx5dr_table_ft_set_next_rtc(last_ft,
+ src_tbl->fw_ft_type,
+ NULL, NULL);
+ if (ret)
+ return ret;
+ } else {
+ /* Connect src_tbl last_ft to first matcher RTC */
+ matcher = LIST_FIRST(&dst_tbl->head);
+ ret = mlx5dr_table_ft_set_next_rtc(last_ft,
+ src_tbl->fw_ft_type,
+ matcher->match_ste.rtc_0,
+ matcher->match_ste.rtc_1);
+ if (ret)
+ return ret;
+
+ /* Reset next miss FT to default */
+ ret = mlx5dr_table_ft_set_default_next_ft(src_tbl, last_ft);
+ if (ret)
+ return ret;
+ }
+ } else {
+ /* Reset next miss FT to default */
+ ret = mlx5dr_table_ft_set_default_next_ft(src_tbl, last_ft);
+ if (ret)
+ return ret;
+
+ /* Reset last_ft RTC to default RTC */
+ ret = mlx5dr_table_ft_set_next_rtc(last_ft,
+ src_tbl->fw_ft_type,
+ NULL, NULL);
+ if (ret)
+ return ret;
+ }
+
+ src_tbl->default_miss.miss_tbl = dst_tbl;
+
+ return 0;
+}
+
+static int mlx5dr_table_set_default_miss_not_valid(struct mlx5dr_table *tbl,
+ struct mlx5dr_table *miss_tbl)
+{
+ if (!tbl->ctx->caps->nic_ft.ignore_flow_level_rtc_valid ||
+ mlx5dr_context_shared_gvmi_used(tbl->ctx)) {
+ DR_LOG(ERR, "Default miss table is not supported");
+ rte_errno = EOPNOTSUPP;
+ return -rte_errno;
+ }
+
+ if (mlx5dr_table_is_root(tbl) ||
+ (miss_tbl && mlx5dr_table_is_root(miss_tbl)) ||
+ (miss_tbl && miss_tbl->type != tbl->type) ||
+ (miss_tbl && tbl->default_miss.miss_tbl)) {
+ DR_LOG(ERR, "Invalid arguments");
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+
+ return 0;
+}
+
+int mlx5dr_table_set_default_miss(struct mlx5dr_table *tbl,
+ struct mlx5dr_table *miss_tbl)
+{
+ struct mlx5dr_context *ctx = tbl->ctx;
+ int ret;
+
+ ret = mlx5dr_table_set_default_miss_not_valid(tbl, miss_tbl);
+ if (ret)
+ return ret;
+
+ pthread_spin_lock(&ctx->ctrl_lock);
+
+ ret = mlx5dr_table_connect_to_miss_table(tbl, miss_tbl);
+ if (ret)
+ goto out;
+
+ if (miss_tbl)
+ LIST_INSERT_HEAD(&miss_tbl->default_miss.head, tbl, default_miss.next);
+ else
+ LIST_REMOVE(tbl, default_miss.next);
+
+ pthread_spin_unlock(&ctx->ctrl_lock);
+ return 0;
+out:
+ pthread_spin_unlock(&ctx->ctrl_lock);
+ return -ret;
}
@@ -7,6 +7,14 @@
#define MLX5DR_ROOT_LEVEL 0
+struct mlx5dr_default_miss {
+ /* My miss table */
+ struct mlx5dr_table *miss_tbl;
+ LIST_ENTRY(mlx5dr_table) next;
+ /* Tables missing to my table */
+ LIST_HEAD(miss_table_head, mlx5dr_table) head;
+};
+
struct mlx5dr_table {
struct mlx5dr_context *ctx;
struct mlx5dr_devx_obj *ft;
@@ -16,6 +24,7 @@ struct mlx5dr_table {
uint32_t level;
LIST_HEAD(matcher_head, mlx5dr_matcher) head;
LIST_ENTRY(mlx5dr_table) next;
+ struct mlx5dr_default_miss default_miss;
};
static inline
@@ -43,4 +52,18 @@ struct mlx5dr_devx_obj *mlx5dr_table_create_default_ft(struct ibv_context *ibv,
void mlx5dr_table_destroy_default_ft(struct mlx5dr_table *tbl,
struct mlx5dr_devx_obj *ft_obj);
+
+int mlx5dr_table_connect_to_miss_table(struct mlx5dr_table *src_tbl,
+ struct mlx5dr_table *dst_tbl);
+
+int mlx5dr_table_update_connected_miss_tables(struct mlx5dr_table *dst_tbl);
+
+int mlx5dr_table_ft_set_default_next_ft(struct mlx5dr_table *tbl,
+ struct mlx5dr_devx_obj *ft_obj);
+
+int mlx5dr_table_ft_set_next_rtc(struct mlx5dr_devx_obj *ft,
+ uint32_t fw_ft_type,
+ struct mlx5dr_devx_obj *rtc_0,
+ struct mlx5dr_devx_obj *rtc_1);
+
#endif /* MLX5DR_TABLE_H_ */