1c4676082SAlex Vesker /* SPDX-License-Identifier: BSD-3-Clause 2c4676082SAlex Vesker * Copyright (c) 2022 NVIDIA Corporation & Affiliates 3c4676082SAlex Vesker */ 4c4676082SAlex Vesker 5c4676082SAlex Vesker #include "mlx5dr_internal.h" 6c4676082SAlex Vesker 738b5bf64SYevgeny Kliteynik enum mlx5dr_matcher_rtc_type { 838b5bf64SYevgeny Kliteynik DR_MATCHER_RTC_TYPE_MATCH, 938b5bf64SYevgeny Kliteynik DR_MATCHER_RTC_TYPE_STE_ARRAY, 1038b5bf64SYevgeny Kliteynik DR_MATCHER_RTC_TYPE_MAX, 1138b5bf64SYevgeny Kliteynik }; 1238b5bf64SYevgeny Kliteynik 1338b5bf64SYevgeny Kliteynik static const char * const mlx5dr_matcher_rtc_type_str[] = { 1438b5bf64SYevgeny Kliteynik [DR_MATCHER_RTC_TYPE_MATCH] = "MATCH", 1538b5bf64SYevgeny Kliteynik [DR_MATCHER_RTC_TYPE_STE_ARRAY] = "STE_ARRAY", 1638b5bf64SYevgeny Kliteynik [DR_MATCHER_RTC_TYPE_MAX] = "UNKNOWN", 1738b5bf64SYevgeny Kliteynik }; 1838b5bf64SYevgeny Kliteynik 1938b5bf64SYevgeny Kliteynik static const char *mlx5dr_matcher_rtc_type_to_str(enum mlx5dr_matcher_rtc_type rtc_type) 2038b5bf64SYevgeny Kliteynik { 2138b5bf64SYevgeny Kliteynik if (rtc_type > DR_MATCHER_RTC_TYPE_MAX) 2238b5bf64SYevgeny Kliteynik rtc_type = DR_MATCHER_RTC_TYPE_MAX; 2338b5bf64SYevgeny Kliteynik return mlx5dr_matcher_rtc_type_str[rtc_type]; 2438b5bf64SYevgeny Kliteynik } 2538b5bf64SYevgeny Kliteynik 26c4676082SAlex Vesker static bool mlx5dr_matcher_requires_col_tbl(uint8_t log_num_of_rules) 27c4676082SAlex Vesker { 28c4676082SAlex Vesker /* Collision table concatenation is done only for large rule tables */ 29c4676082SAlex Vesker return log_num_of_rules > MLX5DR_MATCHER_ASSURED_RULES_TH; 30c4676082SAlex Vesker } 31c4676082SAlex Vesker 32c4676082SAlex Vesker static uint8_t mlx5dr_matcher_rules_to_tbl_depth(uint8_t log_num_of_rules) 33c4676082SAlex Vesker { 34c4676082SAlex Vesker if (mlx5dr_matcher_requires_col_tbl(log_num_of_rules)) 35c4676082SAlex Vesker return MLX5DR_MATCHER_ASSURED_MAIN_TBL_DEPTH; 36c4676082SAlex Vesker 37c4676082SAlex Vesker /* For small rule tables we use a single deep table to assure insertion */ 38c4676082SAlex Vesker return RTE_MIN(log_num_of_rules, MLX5DR_MATCHER_ASSURED_COL_TBL_DEPTH); 39c4676082SAlex Vesker } 40c4676082SAlex Vesker 41c4676082SAlex Vesker static void mlx5dr_matcher_destroy_end_ft(struct mlx5dr_matcher *matcher) 42c4676082SAlex Vesker { 43c4676082SAlex Vesker mlx5dr_table_destroy_default_ft(matcher->tbl, matcher->end_ft); 44c4676082SAlex Vesker } 45c4676082SAlex Vesker 46b81f95caSItamar Gozlan int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, 47ce946c7dSErez Shitrit uint32_t fw_ft_type, 4873be9af4SErez Shitrit enum mlx5dr_table_type type, 4973be9af4SErez Shitrit struct mlx5dr_devx_obj *devx_obj) 5073be9af4SErez Shitrit { 5173be9af4SErez Shitrit int ret; 5273be9af4SErez Shitrit 53ce946c7dSErez Shitrit if (type != MLX5DR_TABLE_TYPE_FDB && !mlx5dr_context_shared_gvmi_used(ctx)) 5473be9af4SErez Shitrit return 0; 5573be9af4SErez Shitrit 56b81f95caSItamar Gozlan ret = mlx5dr_table_ft_set_next_rtc(devx_obj, fw_ft_type, NULL, NULL); 57b81f95caSItamar Gozlan if (ret) 5873be9af4SErez Shitrit DR_LOG(ERR, "Failed to disconnect previous RTC"); 5973be9af4SErez Shitrit 60b81f95caSItamar Gozlan return ret; 6173be9af4SErez Shitrit } 6273be9af4SErez Shitrit 63ce946c7dSErez Shitrit static int mlx5dr_matcher_shared_point_end_ft(struct mlx5dr_matcher *matcher) 64ce946c7dSErez Shitrit { 65ce946c7dSErez Shitrit struct mlx5dr_cmd_ft_modify_attr ft_attr = {0}; 66ce946c7dSErez Shitrit int ret; 67ce946c7dSErez Shitrit 68ce946c7dSErez Shitrit mlx5dr_cmd_set_attr_connect_miss_tbl(matcher->tbl->ctx, 69ce946c7dSErez Shitrit matcher->tbl->fw_ft_type, 70ce946c7dSErez Shitrit matcher->tbl->type, 71ce946c7dSErez Shitrit &ft_attr); 72ce946c7dSErez Shitrit 73ce946c7dSErez Shitrit ret = mlx5dr_cmd_flow_table_modify(matcher->end_ft, &ft_attr); 74ce946c7dSErez Shitrit if (ret) { 75ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to connect new matcher to default miss alias RTC"); 76ce946c7dSErez Shitrit return ret; 77ce946c7dSErez Shitrit } 78ce946c7dSErez Shitrit 79ce946c7dSErez Shitrit ret = mlx5dr_matcher_free_rtc_pointing(matcher->tbl->ctx, 80ce946c7dSErez Shitrit matcher->tbl->fw_ft_type, 81ce946c7dSErez Shitrit matcher->tbl->type, 82ce946c7dSErez Shitrit matcher->end_ft); 83ce946c7dSErez Shitrit 84ce946c7dSErez Shitrit return ret; 85ce946c7dSErez Shitrit } 86ce946c7dSErez Shitrit 87ce946c7dSErez Shitrit static int mlx5dr_matcher_shared_create_alias_rtc(struct mlx5dr_matcher *matcher) 88ce946c7dSErez Shitrit { 89ce946c7dSErez Shitrit struct mlx5dr_context *ctx = matcher->tbl->ctx; 90ce946c7dSErez Shitrit int ret; 91ce946c7dSErez Shitrit 92ce946c7dSErez Shitrit ret = mlx5dr_matcher_create_aliased_obj(ctx, 93ce946c7dSErez Shitrit ctx->ibv_ctx, 94ce946c7dSErez Shitrit ctx->local_ibv_ctx, 95ce946c7dSErez Shitrit ctx->caps->shared_vhca_id, 96ce946c7dSErez Shitrit matcher->match_ste.rtc_0->id, 97ce946c7dSErez Shitrit MLX5_GENERAL_OBJ_TYPE_RTC, 98ce946c7dSErez Shitrit &matcher->match_ste.aliased_rtc_0); 99ce946c7dSErez Shitrit if (ret) { 100ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to allocate alias RTC"); 101ce946c7dSErez Shitrit return ret; 102ce946c7dSErez Shitrit } 103ce946c7dSErez Shitrit return 0; 104ce946c7dSErez Shitrit } 105ce946c7dSErez Shitrit 106ce946c7dSErez Shitrit static int mlx5dr_matcher_create_init_shared(struct mlx5dr_matcher *matcher) 107ce946c7dSErez Shitrit { 108ce946c7dSErez Shitrit if (!mlx5dr_context_shared_gvmi_used(matcher->tbl->ctx)) 109ce946c7dSErez Shitrit return 0; 110ce946c7dSErez Shitrit 111ce946c7dSErez Shitrit if (mlx5dr_matcher_shared_point_end_ft(matcher)) { 112ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to point shared matcher end flow table"); 113ce946c7dSErez Shitrit return rte_errno; 114ce946c7dSErez Shitrit } 115ce946c7dSErez Shitrit 116ce946c7dSErez Shitrit if (mlx5dr_matcher_shared_create_alias_rtc(matcher)) { 117ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to create alias RTC"); 118ce946c7dSErez Shitrit return rte_errno; 119ce946c7dSErez Shitrit } 120ce946c7dSErez Shitrit 121ce946c7dSErez Shitrit return 0; 122ce946c7dSErez Shitrit } 123ce946c7dSErez Shitrit 124ce946c7dSErez Shitrit static void mlx5dr_matcher_create_uninit_shared(struct mlx5dr_matcher *matcher) 125ce946c7dSErez Shitrit { 126ce946c7dSErez Shitrit if (!mlx5dr_context_shared_gvmi_used(matcher->tbl->ctx)) 127ce946c7dSErez Shitrit return; 128ce946c7dSErez Shitrit 129ce946c7dSErez Shitrit if (matcher->match_ste.aliased_rtc_0) { 130ce946c7dSErez Shitrit mlx5dr_cmd_destroy_obj(matcher->match_ste.aliased_rtc_0); 131ce946c7dSErez Shitrit matcher->match_ste.aliased_rtc_0 = NULL; 132ce946c7dSErez Shitrit } 133ce946c7dSErez Shitrit } 134ce946c7dSErez Shitrit 135ce946c7dSErez Shitrit static int mlx5dr_matcher_create_end_ft(struct mlx5dr_matcher *matcher) 136ce946c7dSErez Shitrit { 137ce946c7dSErez Shitrit struct mlx5dr_table *tbl = matcher->tbl; 138ce946c7dSErez Shitrit 139ce946c7dSErez Shitrit matcher->end_ft = mlx5dr_table_create_default_ft(tbl->ctx->ibv_ctx, tbl); 140ce946c7dSErez Shitrit if (!matcher->end_ft) { 141ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to create matcher end flow table"); 142ce946c7dSErez Shitrit return rte_errno; 143ce946c7dSErez Shitrit } 144ce946c7dSErez Shitrit return 0; 145ce946c7dSErez Shitrit } 146ce946c7dSErez Shitrit 147ce946c7dSErez Shitrit static uint32_t 148ce946c7dSErez Shitrit mlx5dr_matcher_connect_get_rtc0(struct mlx5dr_matcher *matcher) 149ce946c7dSErez Shitrit { 150ce946c7dSErez Shitrit if (!matcher->match_ste.aliased_rtc_0) 151ce946c7dSErez Shitrit return matcher->match_ste.rtc_0->id; 152ce946c7dSErez Shitrit else 153ce946c7dSErez Shitrit return matcher->match_ste.aliased_rtc_0->id; 154ce946c7dSErez Shitrit } 155ce946c7dSErez Shitrit 156ce946c7dSErez Shitrit /* The function updates tbl->local_ft to the first RTC or 0 if no more matchers */ 157ce946c7dSErez Shitrit static int mlx5dr_matcher_shared_update_local_ft(struct mlx5dr_table *tbl) 158ce946c7dSErez Shitrit { 159ce946c7dSErez Shitrit struct mlx5dr_cmd_ft_modify_attr cur_ft_attr = {0}; 160ce946c7dSErez Shitrit struct mlx5dr_matcher *first_matcher; 161ce946c7dSErez Shitrit int ret; 162ce946c7dSErez Shitrit 163ce946c7dSErez Shitrit if (!mlx5dr_context_shared_gvmi_used(tbl->ctx)) 164ce946c7dSErez Shitrit return 0; 165ce946c7dSErez Shitrit 166ce946c7dSErez Shitrit first_matcher = LIST_FIRST(&tbl->head); 167ce946c7dSErez Shitrit if (!first_matcher) { 168ce946c7dSErez Shitrit /* local ft no longer points to any RTC, drop refcount */ 169ce946c7dSErez Shitrit ret = mlx5dr_matcher_free_rtc_pointing(tbl->ctx, 170ce946c7dSErez Shitrit tbl->fw_ft_type, 171ce946c7dSErez Shitrit tbl->type, 172ce946c7dSErez Shitrit tbl->local_ft); 173ce946c7dSErez Shitrit if (ret) 174ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to clear local FT to prev alias RTC"); 175ce946c7dSErez Shitrit 176ce946c7dSErez Shitrit return ret; 177ce946c7dSErez Shitrit } 178ce946c7dSErez Shitrit 179ce946c7dSErez Shitrit /* point local_ft to the first RTC */ 180ce946c7dSErez Shitrit cur_ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID; 181ce946c7dSErez Shitrit cur_ft_attr.type = tbl->fw_ft_type; 182ce946c7dSErez Shitrit cur_ft_attr.rtc_id_0 = mlx5dr_matcher_connect_get_rtc0(first_matcher); 183ce946c7dSErez Shitrit 184ce946c7dSErez Shitrit ret = mlx5dr_cmd_flow_table_modify(tbl->local_ft, &cur_ft_attr); 185ce946c7dSErez Shitrit if (ret) { 186ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to point local FT to alias RTC"); 187ce946c7dSErez Shitrit return ret; 188ce946c7dSErez Shitrit } 189ce946c7dSErez Shitrit 190ce946c7dSErez Shitrit return 0; 191ce946c7dSErez Shitrit } 192ce946c7dSErez Shitrit 193c4676082SAlex Vesker static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher) 194c4676082SAlex Vesker { 195c4676082SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 196c4676082SAlex Vesker struct mlx5dr_matcher *prev = NULL; 197c4676082SAlex Vesker struct mlx5dr_matcher *next = NULL; 198c4676082SAlex Vesker struct mlx5dr_matcher *tmp_matcher; 199c4676082SAlex Vesker int ret; 200c4676082SAlex Vesker 201*486f9aacSHamdan Igbaria if (matcher->attr.isolated) { 202*486f9aacSHamdan Igbaria LIST_INSERT_HEAD(&tbl->isolated_matchers, matcher, next); 203*486f9aacSHamdan Igbaria ret = mlx5dr_table_connect_src_ft_to_miss_table(tbl, matcher->end_ft, 204*486f9aacSHamdan Igbaria tbl->default_miss.miss_tbl); 205*486f9aacSHamdan Igbaria if (ret) { 206*486f9aacSHamdan Igbaria DR_LOG(ERR, "Failed to connect the new matcher to the miss_tbl"); 207*486f9aacSHamdan Igbaria goto remove_from_list; 208*486f9aacSHamdan Igbaria } 209*486f9aacSHamdan Igbaria 210*486f9aacSHamdan Igbaria return 0; 211*486f9aacSHamdan Igbaria } 212*486f9aacSHamdan Igbaria 213c4676082SAlex Vesker /* Find location in matcher list */ 214c4676082SAlex Vesker if (LIST_EMPTY(&tbl->head)) { 215c4676082SAlex Vesker LIST_INSERT_HEAD(&tbl->head, matcher, next); 216c4676082SAlex Vesker goto connect; 217c4676082SAlex Vesker } 218c4676082SAlex Vesker 219c4676082SAlex Vesker LIST_FOREACH(tmp_matcher, &tbl->head, next) { 220c4676082SAlex Vesker if (tmp_matcher->attr.priority > matcher->attr.priority) { 221c4676082SAlex Vesker next = tmp_matcher; 222c4676082SAlex Vesker break; 223c4676082SAlex Vesker } 224c4676082SAlex Vesker prev = tmp_matcher; 225c4676082SAlex Vesker } 226c4676082SAlex Vesker 227c4676082SAlex Vesker if (next) 228c4676082SAlex Vesker LIST_INSERT_BEFORE(next, matcher, next); 229c4676082SAlex Vesker else 230c4676082SAlex Vesker LIST_INSERT_AFTER(prev, matcher, next); 231c4676082SAlex Vesker 232c4676082SAlex Vesker connect: 233c4676082SAlex Vesker if (next) { 234b81f95caSItamar Gozlan /* Connect to next RTC */ 235b81f95caSItamar Gozlan ret = mlx5dr_table_ft_set_next_rtc(matcher->end_ft, 236b81f95caSItamar Gozlan tbl->fw_ft_type, 237b81f95caSItamar Gozlan next->match_ste.rtc_0, 238b81f95caSItamar Gozlan next->match_ste.rtc_1); 239c4676082SAlex Vesker if (ret) { 240c4676082SAlex Vesker DR_LOG(ERR, "Failed to connect new matcher to next RTC"); 241c4676082SAlex Vesker goto remove_from_list; 242c4676082SAlex Vesker } 243b81f95caSItamar Gozlan } else { 244b81f95caSItamar Gozlan /* Connect last matcher to next miss_tbl if exists */ 245*486f9aacSHamdan Igbaria ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl, true); 246b81f95caSItamar Gozlan if (ret) { 247b81f95caSItamar Gozlan DR_LOG(ERR, "Failed connect new matcher to miss_tbl"); 248b81f95caSItamar Gozlan goto remove_from_list; 249b81f95caSItamar Gozlan } 250c4676082SAlex Vesker } 251c4676082SAlex Vesker 252b81f95caSItamar Gozlan /* Connect to previous FT */ 253b81f95caSItamar Gozlan ret = mlx5dr_table_ft_set_next_rtc(prev ? prev->end_ft : tbl->ft, 254b81f95caSItamar Gozlan tbl->fw_ft_type, 255b81f95caSItamar Gozlan matcher->match_ste.rtc_0, 256b81f95caSItamar Gozlan matcher->match_ste.rtc_1); 257c4676082SAlex Vesker if (ret) { 258c4676082SAlex Vesker DR_LOG(ERR, "Failed to connect new matcher to previous FT"); 259c4676082SAlex Vesker goto remove_from_list; 260c4676082SAlex Vesker } 261c4676082SAlex Vesker 262ce946c7dSErez Shitrit ret = mlx5dr_matcher_shared_update_local_ft(tbl); 263ce946c7dSErez Shitrit if (ret) { 264ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to update local_ft anchor in shared table"); 265ce946c7dSErez Shitrit goto remove_from_list; 266ce946c7dSErez Shitrit } 267ce946c7dSErez Shitrit 268b81f95caSItamar Gozlan /* Reset next miss FT to default (drop refcount) */ 269eb8d268aSItamar Gozlan ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev ? prev->end_ft : tbl->ft); 270b81f95caSItamar Gozlan if (ret) { 271b81f95caSItamar Gozlan DR_LOG(ERR, "Failed to reset matcher ft default miss"); 272b81f95caSItamar Gozlan goto remove_from_list; 273b81f95caSItamar Gozlan } 274eb8d268aSItamar Gozlan 275eb8d268aSItamar Gozlan if (!prev) { 276eb8d268aSItamar Gozlan /* Update tables missing to current matcher in the table */ 277b81f95caSItamar Gozlan ret = mlx5dr_table_update_connected_miss_tables(tbl); 278b81f95caSItamar Gozlan if (ret) { 279b81f95caSItamar Gozlan DR_LOG(ERR, "Fatal error, failed to update connected miss table"); 280b81f95caSItamar Gozlan goto remove_from_list; 281b81f95caSItamar Gozlan } 282b81f95caSItamar Gozlan } 283b81f95caSItamar Gozlan 284c4676082SAlex Vesker return 0; 285c4676082SAlex Vesker 286c4676082SAlex Vesker remove_from_list: 287c4676082SAlex Vesker LIST_REMOVE(matcher, next); 288c4676082SAlex Vesker return ret; 289c4676082SAlex Vesker } 290c4676082SAlex Vesker 291b81f95caSItamar Gozlan static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher) 292b81f95caSItamar Gozlan { 293b81f95caSItamar Gozlan struct mlx5dr_matcher *tmp_matcher, *prev_matcher; 294b81f95caSItamar Gozlan struct mlx5dr_table *tbl = matcher->tbl; 295b81f95caSItamar Gozlan struct mlx5dr_devx_obj *prev_ft; 296b81f95caSItamar Gozlan struct mlx5dr_matcher *next; 297b81f95caSItamar Gozlan int ret; 298b81f95caSItamar Gozlan 299*486f9aacSHamdan Igbaria if (matcher->attr.isolated) { 300*486f9aacSHamdan Igbaria LIST_REMOVE(matcher, next); 301*486f9aacSHamdan Igbaria return 0; 302*486f9aacSHamdan Igbaria } 303*486f9aacSHamdan Igbaria 304b81f95caSItamar Gozlan prev_ft = tbl->ft; 305b81f95caSItamar Gozlan prev_matcher = LIST_FIRST(&tbl->head); 306b81f95caSItamar Gozlan LIST_FOREACH(tmp_matcher, &tbl->head, next) { 307b81f95caSItamar Gozlan if (tmp_matcher == matcher) 308b81f95caSItamar Gozlan break; 309b81f95caSItamar Gozlan 310b81f95caSItamar Gozlan prev_ft = tmp_matcher->end_ft; 311b81f95caSItamar Gozlan prev_matcher = tmp_matcher; 312c4676082SAlex Vesker } 313c4676082SAlex Vesker 314b81f95caSItamar Gozlan next = matcher->next.le_next; 315b81f95caSItamar Gozlan 316c4676082SAlex Vesker LIST_REMOVE(matcher, next); 317c4676082SAlex Vesker 318b81f95caSItamar Gozlan if (next) { 319b81f95caSItamar Gozlan /* Connect previous end FT to next RTC */ 320b81f95caSItamar Gozlan ret = mlx5dr_table_ft_set_next_rtc(prev_ft, 321ce946c7dSErez Shitrit tbl->fw_ft_type, 322b81f95caSItamar Gozlan next->match_ste.rtc_0, 323b81f95caSItamar Gozlan next->match_ste.rtc_1); 32473be9af4SErez Shitrit if (ret) { 325b81f95caSItamar Gozlan DR_LOG(ERR, "Failed to disconnect matcher"); 326b81f95caSItamar Gozlan goto matcher_reconnect; 327b81f95caSItamar Gozlan } 328b81f95caSItamar Gozlan } else { 329*486f9aacSHamdan Igbaria ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl, true); 330b81f95caSItamar Gozlan if (ret) { 331b81f95caSItamar Gozlan DR_LOG(ERR, "Failed to disconnect last matcher"); 332b81f95caSItamar Gozlan goto matcher_reconnect; 33373be9af4SErez Shitrit } 33473be9af4SErez Shitrit } 33573be9af4SErez Shitrit 336ce946c7dSErez Shitrit ret = mlx5dr_matcher_shared_update_local_ft(tbl); 337ce946c7dSErez Shitrit if (ret) { 338ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to update local_ft in shared table"); 339b81f95caSItamar Gozlan goto matcher_reconnect; 340ce946c7dSErez Shitrit } 341ce946c7dSErez Shitrit 342b81f95caSItamar Gozlan /* Removing first matcher, update connected miss tables if exists */ 343b81f95caSItamar Gozlan if (prev_ft == tbl->ft) { 344b81f95caSItamar Gozlan ret = mlx5dr_table_update_connected_miss_tables(tbl); 3452234c15dSErez Shitrit if (ret) { 346b81f95caSItamar Gozlan DR_LOG(ERR, "Fatal error, failed to update connected miss table"); 347b81f95caSItamar Gozlan goto matcher_reconnect; 3482234c15dSErez Shitrit } 3492234c15dSErez Shitrit } 3502234c15dSErez Shitrit 351b81f95caSItamar Gozlan ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev_ft); 352b81f95caSItamar Gozlan if (ret) { 353b81f95caSItamar Gozlan DR_LOG(ERR, "Fatal error, failed to restore matcher ft default miss"); 354b81f95caSItamar Gozlan goto matcher_reconnect; 355b81f95caSItamar Gozlan } 356b81f95caSItamar Gozlan 357c4676082SAlex Vesker return 0; 358b81f95caSItamar Gozlan 359b81f95caSItamar Gozlan matcher_reconnect: 360f21215b7SYevgeny Kliteynik if (LIST_EMPTY(&tbl->head) || prev_matcher == matcher) 361b81f95caSItamar Gozlan LIST_INSERT_HEAD(&matcher->tbl->head, matcher, next); 362b81f95caSItamar Gozlan else 363b81f95caSItamar Gozlan LIST_INSERT_AFTER(prev_matcher, matcher, next); 364b81f95caSItamar Gozlan 365b81f95caSItamar Gozlan return ret; 366c4676082SAlex Vesker } 367c4676082SAlex Vesker 368238190f3SAlex Vesker static bool mlx5dr_matcher_supp_fw_wqe(struct mlx5dr_matcher *matcher) 369238190f3SAlex Vesker { 370238190f3SAlex Vesker struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; 371238190f3SAlex Vesker 372238190f3SAlex Vesker if (matcher->flags & MLX5DR_MATCHER_FLAGS_HASH_DEFINER) { 373238190f3SAlex Vesker if (matcher->hash_definer->type == MLX5DR_DEFINER_TYPE_MATCH && 374238190f3SAlex Vesker !IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_8DW)) { 375238190f3SAlex Vesker DR_LOG(ERR, "Gen WQE MATCH format not supported"); 376238190f3SAlex Vesker return false; 377238190f3SAlex Vesker } 378238190f3SAlex Vesker 379238190f3SAlex Vesker if (matcher->hash_definer->type == MLX5DR_DEFINER_TYPE_JUMBO) { 380238190f3SAlex Vesker DR_LOG(ERR, "Gen WQE JUMBO format not supported"); 381238190f3SAlex Vesker return false; 382238190f3SAlex Vesker } 383238190f3SAlex Vesker } 384238190f3SAlex Vesker 385238190f3SAlex Vesker if (matcher->attr.insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || 386238190f3SAlex Vesker matcher->attr.distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { 387238190f3SAlex Vesker DR_LOG(ERR, "Gen WQE must be inserted and distribute by hash"); 388238190f3SAlex Vesker return false; 389238190f3SAlex Vesker } 390238190f3SAlex Vesker 3919732ffe1SAlex Vesker if ((matcher->flags & MLX5DR_MATCHER_FLAGS_RANGE_DEFINER) && 3929732ffe1SAlex Vesker !IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_RANGE)) { 3939732ffe1SAlex Vesker DR_LOG(INFO, "Extended match gen wqe RANGE format not supported"); 3949732ffe1SAlex Vesker return false; 3959732ffe1SAlex Vesker } 3969732ffe1SAlex Vesker 397238190f3SAlex Vesker if (!(caps->supp_type_gen_wqe & MLX5_GENERATE_WQE_TYPE_FLOW_UPDATE)) { 398238190f3SAlex Vesker DR_LOG(ERR, "Gen WQE command not supporting GTA"); 399238190f3SAlex Vesker return false; 400238190f3SAlex Vesker } 401238190f3SAlex Vesker 402238190f3SAlex Vesker if (!caps->rtc_max_hash_def_gen_wqe) { 403238190f3SAlex Vesker DR_LOG(ERR, "Hash definer not supported"); 404238190f3SAlex Vesker return false; 405238190f3SAlex Vesker } 406238190f3SAlex Vesker 407238190f3SAlex Vesker return true; 408238190f3SAlex Vesker } 409238190f3SAlex Vesker 410c4676082SAlex Vesker static void mlx5dr_matcher_set_rtc_attr_sz(struct mlx5dr_matcher *matcher, 411c4676082SAlex Vesker struct mlx5dr_cmd_rtc_create_attr *rtc_attr, 41238b5bf64SYevgeny Kliteynik enum mlx5dr_matcher_rtc_type rtc_type, 413c4676082SAlex Vesker bool is_mirror) 414c4676082SAlex Vesker { 415c4676082SAlex Vesker enum mlx5dr_matcher_flow_src flow_src = matcher->attr.optimize_flow_src; 41638b5bf64SYevgeny Kliteynik bool is_match_rtc = rtc_type == DR_MATCHER_RTC_TYPE_MATCH; 417c4676082SAlex Vesker struct mlx5dr_pool_chunk *ste = &matcher->action_ste.ste; 418c4676082SAlex Vesker 419c4676082SAlex Vesker if ((flow_src == MLX5DR_MATCHER_FLOW_SRC_VPORT && !is_mirror) || 420c4676082SAlex Vesker (flow_src == MLX5DR_MATCHER_FLOW_SRC_WIRE && is_mirror)) { 421c4676082SAlex Vesker /* Optimize FDB RTC */ 422c4676082SAlex Vesker rtc_attr->log_size = 0; 423c4676082SAlex Vesker rtc_attr->log_depth = 0; 424c4676082SAlex Vesker } else { 425c4676082SAlex Vesker /* Keep original values */ 426c4676082SAlex Vesker rtc_attr->log_size = is_match_rtc ? matcher->attr.table.sz_row_log : ste->order; 427c4676082SAlex Vesker rtc_attr->log_depth = is_match_rtc ? matcher->attr.table.sz_col_log : 0; 428c4676082SAlex Vesker } 429c4676082SAlex Vesker } 430c4676082SAlex Vesker 431ce946c7dSErez Shitrit int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context *ctx, 432ce946c7dSErez Shitrit struct ibv_context *ibv_owner, 433ce946c7dSErez Shitrit struct ibv_context *ibv_allowed, 434ce946c7dSErez Shitrit uint16_t vhca_id_to_be_accessed, 435ce946c7dSErez Shitrit uint32_t aliased_object_id, 436ce946c7dSErez Shitrit uint16_t object_type, 437ce946c7dSErez Shitrit struct mlx5dr_devx_obj **obj) 438ce946c7dSErez Shitrit { 439ce946c7dSErez Shitrit struct mlx5dr_cmd_allow_other_vhca_access_attr allow_attr = {0}; 440ce946c7dSErez Shitrit struct mlx5dr_cmd_alias_obj_create_attr alias_attr = {0}; 441ce946c7dSErez Shitrit char key[ACCESS_KEY_LEN]; 442ce946c7dSErez Shitrit int ret; 443ce946c7dSErez Shitrit int i; 444ce946c7dSErez Shitrit 445ce946c7dSErez Shitrit if (!mlx5dr_context_shared_gvmi_used(ctx)) 446ce946c7dSErez Shitrit return 0; 447ce946c7dSErez Shitrit 448ce946c7dSErez Shitrit for (i = 0; i < ACCESS_KEY_LEN; i++) 449ce946c7dSErez Shitrit key[i] = rte_rand() & 0xFF; 450ce946c7dSErez Shitrit 451ce946c7dSErez Shitrit memcpy(allow_attr.access_key, key, ACCESS_KEY_LEN); 452ce946c7dSErez Shitrit allow_attr.obj_type = object_type; 453ce946c7dSErez Shitrit allow_attr.obj_id = aliased_object_id; 454ce946c7dSErez Shitrit 455ce946c7dSErez Shitrit ret = mlx5dr_cmd_allow_other_vhca_access(ibv_owner, &allow_attr); 456ce946c7dSErez Shitrit if (ret) { 457ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to allow RTC to be aliased"); 458ce946c7dSErez Shitrit return ret; 459ce946c7dSErez Shitrit } 460ce946c7dSErez Shitrit 461ce946c7dSErez Shitrit memcpy(alias_attr.access_key, key, ACCESS_KEY_LEN); 462ce946c7dSErez Shitrit alias_attr.obj_id = aliased_object_id; 463ce946c7dSErez Shitrit alias_attr.obj_type = object_type; 464ce946c7dSErez Shitrit alias_attr.vhca_id = vhca_id_to_be_accessed; 465ce946c7dSErez Shitrit *obj = mlx5dr_cmd_alias_obj_create(ibv_allowed, &alias_attr); 466ce946c7dSErez Shitrit if (!*obj) { 467ce946c7dSErez Shitrit DR_LOG(ERR, "Failed to create alias object"); 468ce946c7dSErez Shitrit return rte_errno; 469ce946c7dSErez Shitrit } 470ce946c7dSErez Shitrit 471ce946c7dSErez Shitrit return 0; 472ce946c7dSErez Shitrit } 473ce946c7dSErez Shitrit 474c4676082SAlex Vesker static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, 47538b5bf64SYevgeny Kliteynik enum mlx5dr_matcher_rtc_type rtc_type) 476c4676082SAlex Vesker { 47738b5bf64SYevgeny Kliteynik struct mlx5dr_matcher_attr *attr = &matcher->attr; 478c4676082SAlex Vesker struct mlx5dr_cmd_rtc_create_attr rtc_attr = {0}; 47927ac2da9SAlex Vesker struct mlx5dr_match_template *mt = matcher->mt; 480c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 481c4676082SAlex Vesker struct mlx5dr_action_default_stc *default_stc; 482c4676082SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 483c4676082SAlex Vesker struct mlx5dr_devx_obj **rtc_0, **rtc_1; 484c4676082SAlex Vesker struct mlx5dr_pool *ste_pool, *stc_pool; 485c4676082SAlex Vesker struct mlx5dr_devx_obj *devx_obj; 486c4676082SAlex Vesker struct mlx5dr_pool_chunk *ste; 487c4676082SAlex Vesker int ret; 488c4676082SAlex Vesker 48938b5bf64SYevgeny Kliteynik switch (rtc_type) { 49038b5bf64SYevgeny Kliteynik case DR_MATCHER_RTC_TYPE_MATCH: 491c4676082SAlex Vesker rtc_0 = &matcher->match_ste.rtc_0; 492c4676082SAlex Vesker rtc_1 = &matcher->match_ste.rtc_1; 493c4676082SAlex Vesker ste_pool = matcher->match_ste.pool; 494c4676082SAlex Vesker ste = &matcher->match_ste.ste; 49538b5bf64SYevgeny Kliteynik ste->order = attr->table.sz_col_log + attr->table.sz_row_log; 49627ac2da9SAlex Vesker 4979732ffe1SAlex Vesker /* Add additional rows due to additional range STE */ 4989732ffe1SAlex Vesker if (mlx5dr_matcher_mt_is_range(mt)) 4999732ffe1SAlex Vesker ste->order++; 5009732ffe1SAlex Vesker 50138b5bf64SYevgeny Kliteynik rtc_attr.log_size = attr->table.sz_row_log; 50238b5bf64SYevgeny Kliteynik rtc_attr.log_depth = attr->table.sz_col_log; 50327ac2da9SAlex Vesker rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); 5049732ffe1SAlex Vesker rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); 505a5230507SHamdan Igbaria rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); 50638b5bf64SYevgeny Kliteynik rtc_attr.miss_ft_id = matcher->end_ft->id; 50738b5bf64SYevgeny Kliteynik 50838b5bf64SYevgeny Kliteynik if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { 50938b5bf64SYevgeny Kliteynik /* The usual Hash Table */ 510c4676082SAlex Vesker rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH; 5119732ffe1SAlex Vesker 512238190f3SAlex Vesker if (matcher->hash_definer) { 513238190f3SAlex Vesker /* Specify definer_id_0 is used for hashing */ 514238190f3SAlex Vesker rtc_attr.fw_gen_wqe = true; 515238190f3SAlex Vesker rtc_attr.num_hash_definer = 1; 516238190f3SAlex Vesker rtc_attr.match_definer_0 = 517238190f3SAlex Vesker mlx5dr_definer_get_id(matcher->hash_definer); 518a5230507SHamdan Igbaria } else if (mlx5dr_matcher_is_compare(matcher)) { 519a5230507SHamdan Igbaria rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; 520a5230507SHamdan Igbaria rtc_attr.fw_gen_wqe = true; 521a5230507SHamdan Igbaria rtc_attr.num_hash_definer = 1; 522238190f3SAlex Vesker } else { 523238190f3SAlex Vesker /* The first mt is used since all share the same definer */ 52427ac2da9SAlex Vesker rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); 5259732ffe1SAlex Vesker 5269732ffe1SAlex Vesker /* This is tricky, instead of passing two definers for 5279732ffe1SAlex Vesker * match and range, we specify that this RTC uses a hash 5289732ffe1SAlex Vesker * definer, this will allow us to use any range definer 5299732ffe1SAlex Vesker * since only first STE is used for hashing anyways. 5309732ffe1SAlex Vesker */ 5319732ffe1SAlex Vesker if (matcher->flags & MLX5DR_MATCHER_FLAGS_RANGE_DEFINER) { 5329732ffe1SAlex Vesker rtc_attr.fw_gen_wqe = true; 5339732ffe1SAlex Vesker rtc_attr.num_hash_definer = 1; 5349732ffe1SAlex Vesker } 535238190f3SAlex Vesker } 53638b5bf64SYevgeny Kliteynik } else if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) { 53738b5bf64SYevgeny Kliteynik rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET; 53838b5bf64SYevgeny Kliteynik 53938b5bf64SYevgeny Kliteynik if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { 54038b5bf64SYevgeny Kliteynik /* Hash Split Table */ 541*486f9aacSHamdan Igbaria if (mlx5dr_matcher_is_always_hit(matcher)) 542*486f9aacSHamdan Igbaria rtc_attr.num_hash_definer = 1; 543*486f9aacSHamdan Igbaria 54438b5bf64SYevgeny Kliteynik rtc_attr.access_index_mode = MLX5_IFC_RTC_STE_ACCESS_MODE_BY_HASH; 54527ac2da9SAlex Vesker rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); 54638b5bf64SYevgeny Kliteynik } else if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) { 54738b5bf64SYevgeny Kliteynik /* Linear Lookup Table */ 548*486f9aacSHamdan Igbaria rtc_attr.num_hash_definer = 1; 54938b5bf64SYevgeny Kliteynik rtc_attr.access_index_mode = MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR; 55093ee3bd8SAlex Vesker rtc_attr.match_definer_0 = ctx->caps->linear_match_definer; 55138b5bf64SYevgeny Kliteynik } 55238b5bf64SYevgeny Kliteynik } 55338b5bf64SYevgeny Kliteynik 554c4676082SAlex Vesker /* Match pool requires implicit allocation */ 555c4676082SAlex Vesker ret = mlx5dr_pool_chunk_alloc(ste_pool, ste); 556c4676082SAlex Vesker if (ret) { 55738b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Failed to allocate STE for %s RTC", 55838b5bf64SYevgeny Kliteynik mlx5dr_matcher_rtc_type_to_str(rtc_type)); 559c4676082SAlex Vesker return ret; 560c4676082SAlex Vesker } 56138b5bf64SYevgeny Kliteynik break; 56238b5bf64SYevgeny Kliteynik 56338b5bf64SYevgeny Kliteynik case DR_MATCHER_RTC_TYPE_STE_ARRAY: 564c4676082SAlex Vesker rtc_0 = &matcher->action_ste.rtc_0; 565c4676082SAlex Vesker rtc_1 = &matcher->action_ste.rtc_1; 566c4676082SAlex Vesker ste_pool = matcher->action_ste.pool; 567c4676082SAlex Vesker ste = &matcher->action_ste.ste; 568c4676082SAlex Vesker ste->order = rte_log2_u32(matcher->action_ste.max_stes) + 56938b5bf64SYevgeny Kliteynik attr->table.sz_row_log; 570c4676082SAlex Vesker rtc_attr.log_size = ste->order; 571c4676082SAlex Vesker rtc_attr.log_depth = 0; 572c4676082SAlex Vesker rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET; 573c4676082SAlex Vesker /* The action STEs use the default always hit definer */ 57493ee3bd8SAlex Vesker rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; 57593ee3bd8SAlex Vesker rtc_attr.is_frst_jumbo = false; 576c4676082SAlex Vesker rtc_attr.miss_ft_id = 0; 57738b5bf64SYevgeny Kliteynik break; 57838b5bf64SYevgeny Kliteynik 57938b5bf64SYevgeny Kliteynik default: 58038b5bf64SYevgeny Kliteynik DR_LOG(ERR, "HWS Invalid RTC type"); 58138b5bf64SYevgeny Kliteynik rte_errno = EINVAL; 58238b5bf64SYevgeny Kliteynik return rte_errno; 583c4676082SAlex Vesker } 584c4676082SAlex Vesker 585c4676082SAlex Vesker devx_obj = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste); 586c4676082SAlex Vesker 587c4676082SAlex Vesker rtc_attr.pd = ctx->pd_num; 588c4676082SAlex Vesker rtc_attr.ste_base = devx_obj->id; 589c4676082SAlex Vesker rtc_attr.ste_offset = ste->offset; 590bbddd062SAlex Vesker rtc_attr.reparse_mode = mlx5dr_context_get_reparse_mode(ctx); 591c4676082SAlex Vesker rtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, false); 59238b5bf64SYevgeny Kliteynik mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, false); 593c4676082SAlex Vesker 594c4676082SAlex Vesker /* STC is a single resource (devx_obj), use any STC for the ID */ 595c4676082SAlex Vesker stc_pool = ctx->stc_pool[tbl->type]; 596c4676082SAlex Vesker default_stc = ctx->common_res[tbl->type].default_stc; 597c4676082SAlex Vesker devx_obj = mlx5dr_pool_chunk_get_base_devx_obj(stc_pool, &default_stc->default_hit); 598c4676082SAlex Vesker rtc_attr.stc_base = devx_obj->id; 599c4676082SAlex Vesker 600c4676082SAlex Vesker *rtc_0 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr); 601c4676082SAlex Vesker if (!*rtc_0) { 60238b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Failed to create matcher RTC of type %s", 60338b5bf64SYevgeny Kliteynik mlx5dr_matcher_rtc_type_to_str(rtc_type)); 604c4676082SAlex Vesker goto free_ste; 605c4676082SAlex Vesker } 606c4676082SAlex Vesker 607c4676082SAlex Vesker if (tbl->type == MLX5DR_TABLE_TYPE_FDB) { 608c4676082SAlex Vesker devx_obj = mlx5dr_pool_chunk_get_base_devx_obj_mirror(ste_pool, ste); 609c4676082SAlex Vesker rtc_attr.ste_base = devx_obj->id; 610c4676082SAlex Vesker rtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, true); 611c4676082SAlex Vesker 612c4676082SAlex Vesker devx_obj = mlx5dr_pool_chunk_get_base_devx_obj_mirror(stc_pool, &default_stc->default_hit); 613c4676082SAlex Vesker rtc_attr.stc_base = devx_obj->id; 61438b5bf64SYevgeny Kliteynik mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, true); 615c4676082SAlex Vesker 616c4676082SAlex Vesker *rtc_1 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr); 617c4676082SAlex Vesker if (!*rtc_1) { 61838b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Failed to create peer matcher RTC of type %s", 61938b5bf64SYevgeny Kliteynik mlx5dr_matcher_rtc_type_to_str(rtc_type)); 620c4676082SAlex Vesker goto destroy_rtc_0; 621c4676082SAlex Vesker } 622c4676082SAlex Vesker } 623c4676082SAlex Vesker 624c4676082SAlex Vesker return 0; 625c4676082SAlex Vesker 626c4676082SAlex Vesker destroy_rtc_0: 627c4676082SAlex Vesker mlx5dr_cmd_destroy_obj(*rtc_0); 628c4676082SAlex Vesker free_ste: 62938b5bf64SYevgeny Kliteynik if (rtc_type == DR_MATCHER_RTC_TYPE_MATCH) 630c4676082SAlex Vesker mlx5dr_pool_chunk_free(ste_pool, ste); 631c4676082SAlex Vesker return rte_errno; 632c4676082SAlex Vesker } 633c4676082SAlex Vesker 634c4676082SAlex Vesker static void mlx5dr_matcher_destroy_rtc(struct mlx5dr_matcher *matcher, 63538b5bf64SYevgeny Kliteynik enum mlx5dr_matcher_rtc_type rtc_type) 636c4676082SAlex Vesker { 637c4676082SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 638c4676082SAlex Vesker struct mlx5dr_devx_obj *rtc_0, *rtc_1; 639c4676082SAlex Vesker struct mlx5dr_pool_chunk *ste; 640c4676082SAlex Vesker struct mlx5dr_pool *ste_pool; 641c4676082SAlex Vesker 64238b5bf64SYevgeny Kliteynik switch (rtc_type) { 64338b5bf64SYevgeny Kliteynik case DR_MATCHER_RTC_TYPE_MATCH: 644c4676082SAlex Vesker rtc_0 = matcher->match_ste.rtc_0; 645c4676082SAlex Vesker rtc_1 = matcher->match_ste.rtc_1; 646c4676082SAlex Vesker ste_pool = matcher->match_ste.pool; 647c4676082SAlex Vesker ste = &matcher->match_ste.ste; 64838b5bf64SYevgeny Kliteynik break; 64938b5bf64SYevgeny Kliteynik case DR_MATCHER_RTC_TYPE_STE_ARRAY: 650c4676082SAlex Vesker rtc_0 = matcher->action_ste.rtc_0; 651c4676082SAlex Vesker rtc_1 = matcher->action_ste.rtc_1; 652c4676082SAlex Vesker ste_pool = matcher->action_ste.pool; 653c4676082SAlex Vesker ste = &matcher->action_ste.ste; 65438b5bf64SYevgeny Kliteynik break; 65538b5bf64SYevgeny Kliteynik default: 65638b5bf64SYevgeny Kliteynik return; 657c4676082SAlex Vesker } 658c4676082SAlex Vesker 659c4676082SAlex Vesker if (tbl->type == MLX5DR_TABLE_TYPE_FDB) 660c4676082SAlex Vesker mlx5dr_cmd_destroy_obj(rtc_1); 661c4676082SAlex Vesker 662c4676082SAlex Vesker mlx5dr_cmd_destroy_obj(rtc_0); 66338b5bf64SYevgeny Kliteynik if (rtc_type == DR_MATCHER_RTC_TYPE_MATCH) 664c4676082SAlex Vesker mlx5dr_pool_chunk_free(ste_pool, ste); 665c4676082SAlex Vesker } 666c4676082SAlex Vesker 667186561f9SAlex Vesker static int 668186561f9SAlex Vesker mlx5dr_matcher_check_attr_sz(struct mlx5dr_cmd_query_caps *caps, 669186561f9SAlex Vesker struct mlx5dr_matcher_attr *attr) 670186561f9SAlex Vesker { 671186561f9SAlex Vesker if (attr->table.sz_col_log > caps->rtc_log_depth_max) { 672186561f9SAlex Vesker DR_LOG(ERR, "Matcher depth exceeds limit %d", caps->rtc_log_depth_max); 673186561f9SAlex Vesker goto not_supported; 674186561f9SAlex Vesker } 675186561f9SAlex Vesker 676186561f9SAlex Vesker if (attr->table.sz_col_log + attr->table.sz_row_log > caps->ste_alloc_log_max) { 677186561f9SAlex Vesker DR_LOG(ERR, "Total matcher size exceeds limit %d", caps->ste_alloc_log_max); 678186561f9SAlex Vesker goto not_supported; 679186561f9SAlex Vesker } 680186561f9SAlex Vesker 681186561f9SAlex Vesker if (attr->table.sz_col_log + attr->table.sz_row_log < caps->ste_alloc_log_gran) { 682186561f9SAlex Vesker DR_LOG(ERR, "Total matcher size below limit %d", caps->ste_alloc_log_gran); 683186561f9SAlex Vesker goto not_supported; 684186561f9SAlex Vesker } 685186561f9SAlex Vesker 686186561f9SAlex Vesker return 0; 687186561f9SAlex Vesker 688186561f9SAlex Vesker not_supported: 689186561f9SAlex Vesker rte_errno = EOPNOTSUPP; 690186561f9SAlex Vesker return rte_errno; 691186561f9SAlex Vesker } 692186561f9SAlex Vesker 693c4676082SAlex Vesker static void mlx5dr_matcher_set_pool_attr(struct mlx5dr_pool_attr *attr, 694c4676082SAlex Vesker struct mlx5dr_matcher *matcher) 695c4676082SAlex Vesker { 696c4676082SAlex Vesker switch (matcher->attr.optimize_flow_src) { 697c4676082SAlex Vesker case MLX5DR_MATCHER_FLOW_SRC_VPORT: 698c4676082SAlex Vesker attr->opt_type = MLX5DR_POOL_OPTIMIZE_ORIG; 699c4676082SAlex Vesker break; 700c4676082SAlex Vesker case MLX5DR_MATCHER_FLOW_SRC_WIRE: 701c4676082SAlex Vesker attr->opt_type = MLX5DR_POOL_OPTIMIZE_MIRROR; 702c4676082SAlex Vesker break; 703c4676082SAlex Vesker default: 704c4676082SAlex Vesker break; 705c4676082SAlex Vesker } 706c4676082SAlex Vesker } 707c4676082SAlex Vesker 708c5713fc1SErez Shitrit static int mlx5dr_matcher_check_and_process_at(struct mlx5dr_matcher *matcher, 709c5713fc1SErez Shitrit struct mlx5dr_action_template *at) 710c5713fc1SErez Shitrit { 711c5713fc1SErez Shitrit bool valid; 712c5713fc1SErez Shitrit int ret; 713c5713fc1SErez Shitrit 714d586f522SHamdan Igbaria if (!(at->flags & MLX5DR_ACTION_TEMPLATE_FLAG_RELAXED_ORDER)) { 715d586f522SHamdan Igbaria /* Check if actions combinabtion is valid, 716d586f522SHamdan Igbaria * in the case of not relaxed actions order. 717d586f522SHamdan Igbaria */ 718c5713fc1SErez Shitrit valid = mlx5dr_action_check_combo(at->action_type_arr, matcher->tbl->type); 719c5713fc1SErez Shitrit if (!valid) { 720c5713fc1SErez Shitrit DR_LOG(ERR, "Invalid combination in action template"); 721c5713fc1SErez Shitrit rte_errno = EINVAL; 722c5713fc1SErez Shitrit return rte_errno; 723c5713fc1SErez Shitrit } 724d586f522SHamdan Igbaria } 725c5713fc1SErez Shitrit 726c5713fc1SErez Shitrit /* Process action template to setters */ 727c5713fc1SErez Shitrit ret = mlx5dr_action_template_process(at); 728c5713fc1SErez Shitrit if (ret) { 729c5713fc1SErez Shitrit DR_LOG(ERR, "Failed to process action template"); 730c5713fc1SErez Shitrit return ret; 731c5713fc1SErez Shitrit } 732c5713fc1SErez Shitrit 733c5713fc1SErez Shitrit return 0; 734c5713fc1SErez Shitrit } 735c5713fc1SErez Shitrit 736762fecebSYevgeny Kliteynik static int 737762fecebSYevgeny Kliteynik mlx5dr_matcher_resize_init(struct mlx5dr_matcher *src_matcher) 738762fecebSYevgeny Kliteynik { 739762fecebSYevgeny Kliteynik struct mlx5dr_matcher_resize_data *resize_data; 740762fecebSYevgeny Kliteynik 741762fecebSYevgeny Kliteynik resize_data = simple_calloc(1, sizeof(*resize_data)); 742762fecebSYevgeny Kliteynik if (!resize_data) { 743762fecebSYevgeny Kliteynik rte_errno = ENOMEM; 744762fecebSYevgeny Kliteynik return rte_errno; 745762fecebSYevgeny Kliteynik } 746762fecebSYevgeny Kliteynik 74719e9ad26SYevgeny Kliteynik resize_data->max_stes = src_matcher->action_ste.max_stes; 748fd821625SHamdan Igbaria resize_data->ste = src_matcher->action_ste.ste; 749762fecebSYevgeny Kliteynik resize_data->stc = src_matcher->action_ste.stc; 750762fecebSYevgeny Kliteynik resize_data->action_ste_rtc_0 = src_matcher->action_ste.rtc_0; 751762fecebSYevgeny Kliteynik resize_data->action_ste_rtc_1 = src_matcher->action_ste.rtc_1; 752762fecebSYevgeny Kliteynik resize_data->action_ste_pool = src_matcher->action_ste.max_stes ? 753762fecebSYevgeny Kliteynik src_matcher->action_ste.pool : 754762fecebSYevgeny Kliteynik NULL; 755762fecebSYevgeny Kliteynik 756762fecebSYevgeny Kliteynik /* Place the new resized matcher on the dst matcher's list */ 757762fecebSYevgeny Kliteynik LIST_INSERT_HEAD(&src_matcher->resize_dst->resize_data, 758762fecebSYevgeny Kliteynik resize_data, next); 759762fecebSYevgeny Kliteynik 760762fecebSYevgeny Kliteynik /* Move all the previous resized matchers to the dst matcher's list */ 761762fecebSYevgeny Kliteynik while (!LIST_EMPTY(&src_matcher->resize_data)) { 762762fecebSYevgeny Kliteynik resize_data = LIST_FIRST(&src_matcher->resize_data); 763762fecebSYevgeny Kliteynik LIST_REMOVE(resize_data, next); 764762fecebSYevgeny Kliteynik LIST_INSERT_HEAD(&src_matcher->resize_dst->resize_data, 765762fecebSYevgeny Kliteynik resize_data, next); 766762fecebSYevgeny Kliteynik } 767762fecebSYevgeny Kliteynik 768762fecebSYevgeny Kliteynik return 0; 769762fecebSYevgeny Kliteynik } 770762fecebSYevgeny Kliteynik 771762fecebSYevgeny Kliteynik static void 772762fecebSYevgeny Kliteynik mlx5dr_matcher_resize_uninit(struct mlx5dr_matcher *matcher) 773762fecebSYevgeny Kliteynik { 774762fecebSYevgeny Kliteynik struct mlx5dr_matcher_resize_data *resize_data; 775762fecebSYevgeny Kliteynik 77619e9ad26SYevgeny Kliteynik if (!mlx5dr_matcher_is_resizable(matcher)) 777762fecebSYevgeny Kliteynik return; 778762fecebSYevgeny Kliteynik 779762fecebSYevgeny Kliteynik while (!LIST_EMPTY(&matcher->resize_data)) { 780762fecebSYevgeny Kliteynik resize_data = LIST_FIRST(&matcher->resize_data); 781762fecebSYevgeny Kliteynik LIST_REMOVE(resize_data, next); 782762fecebSYevgeny Kliteynik 78319e9ad26SYevgeny Kliteynik if (resize_data->max_stes) { 784762fecebSYevgeny Kliteynik mlx5dr_action_free_single_stc(matcher->tbl->ctx, 785762fecebSYevgeny Kliteynik matcher->tbl->type, 786762fecebSYevgeny Kliteynik &resize_data->stc); 787762fecebSYevgeny Kliteynik 788762fecebSYevgeny Kliteynik if (matcher->tbl->type == MLX5DR_TABLE_TYPE_FDB) 789762fecebSYevgeny Kliteynik mlx5dr_cmd_destroy_obj(resize_data->action_ste_rtc_1); 790762fecebSYevgeny Kliteynik mlx5dr_cmd_destroy_obj(resize_data->action_ste_rtc_0); 791762fecebSYevgeny Kliteynik if (resize_data->action_ste_pool) 792762fecebSYevgeny Kliteynik mlx5dr_pool_destroy(resize_data->action_ste_pool); 79319e9ad26SYevgeny Kliteynik } 79419e9ad26SYevgeny Kliteynik 795762fecebSYevgeny Kliteynik simple_free(resize_data); 796762fecebSYevgeny Kliteynik } 797762fecebSYevgeny Kliteynik } 798762fecebSYevgeny Kliteynik 799c4676082SAlex Vesker static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher *matcher) 800c4676082SAlex Vesker { 80127ac2da9SAlex Vesker bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(matcher->mt); 802c4676082SAlex Vesker struct mlx5dr_cmd_stc_modify_attr stc_attr = {0}; 803c4676082SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 804c4676082SAlex Vesker struct mlx5dr_pool_attr pool_attr = {0}; 805c4676082SAlex Vesker struct mlx5dr_context *ctx = tbl->ctx; 806c4676082SAlex Vesker uint32_t required_stes; 807c4676082SAlex Vesker int i, ret; 808c4676082SAlex Vesker 8091fe7e58aSErez Shitrit if (matcher->flags & MLX5DR_MATCHER_FLAGS_COLLISION) 8101fe7e58aSErez Shitrit return 0; 8111fe7e58aSErez Shitrit 81292d6bf66SAlex Vesker if (matcher->attr.max_num_of_at_attach && 81392d6bf66SAlex Vesker mlx5dr_matcher_req_fw_wqe(matcher)) { 81492d6bf66SAlex Vesker DR_LOG(ERR, "FW extended matcher doesn't support additional at"); 81592d6bf66SAlex Vesker rte_errno = ENOTSUP; 81692d6bf66SAlex Vesker return rte_errno; 81792d6bf66SAlex Vesker } 81892d6bf66SAlex Vesker 819c4676082SAlex Vesker for (i = 0; i < matcher->num_of_at; i++) { 820940b0ebaSAlex Vesker struct mlx5dr_action_template *at = &matcher->at[i]; 821c4676082SAlex Vesker 822c5713fc1SErez Shitrit ret = mlx5dr_matcher_check_and_process_at(matcher, at); 823c4676082SAlex Vesker if (ret) { 824c5713fc1SErez Shitrit DR_LOG(ERR, "Invalid at %d", i); 825c4676082SAlex Vesker return rte_errno; 826c4676082SAlex Vesker } 827c4676082SAlex Vesker 828c4676082SAlex Vesker required_stes = at->num_of_action_stes - (!is_jumbo || at->only_term); 829c4676082SAlex Vesker matcher->action_ste.max_stes = RTE_MAX(matcher->action_ste.max_stes, required_stes); 830c4676082SAlex Vesker 831c4676082SAlex Vesker /* Future: Optimize reparse */ 832c4676082SAlex Vesker } 833c4676082SAlex Vesker 834c4676082SAlex Vesker /* There are no additioanl STEs required for matcher */ 835c4676082SAlex Vesker if (!matcher->action_ste.max_stes) 836c4676082SAlex Vesker return 0; 837c4676082SAlex Vesker 838238190f3SAlex Vesker if (mlx5dr_matcher_req_fw_wqe(matcher)) { 839238190f3SAlex Vesker DR_LOG(ERR, "FW extended matcher cannot be binded to complex at"); 840238190f3SAlex Vesker rte_errno = ENOTSUP; 841238190f3SAlex Vesker return rte_errno; 842238190f3SAlex Vesker } 843238190f3SAlex Vesker 844c4676082SAlex Vesker /* Allocate action STE mempool */ 845c4676082SAlex Vesker pool_attr.table_type = tbl->type; 846c4676082SAlex Vesker pool_attr.pool_type = MLX5DR_POOL_TYPE_STE; 847c4676082SAlex Vesker pool_attr.flags = MLX5DR_POOL_FLAGS_FOR_STE_ACTION_POOL; 848c4676082SAlex Vesker pool_attr.alloc_log_sz = rte_log2_u32(matcher->action_ste.max_stes) + 849c4676082SAlex Vesker matcher->attr.table.sz_row_log; 850c4676082SAlex Vesker mlx5dr_matcher_set_pool_attr(&pool_attr, matcher); 851c4676082SAlex Vesker matcher->action_ste.pool = mlx5dr_pool_create(ctx, &pool_attr); 852c4676082SAlex Vesker if (!matcher->action_ste.pool) { 853c4676082SAlex Vesker DR_LOG(ERR, "Failed to create action ste pool"); 854c4676082SAlex Vesker return rte_errno; 855c4676082SAlex Vesker } 856c4676082SAlex Vesker 857c4676082SAlex Vesker /* Allocate action RTC */ 85838b5bf64SYevgeny Kliteynik ret = mlx5dr_matcher_create_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY); 859c4676082SAlex Vesker if (ret) { 860c4676082SAlex Vesker DR_LOG(ERR, "Failed to create action RTC"); 861c4676082SAlex Vesker goto free_ste_pool; 862c4676082SAlex Vesker } 863c4676082SAlex Vesker 864c4676082SAlex Vesker /* Allocate STC for jumps to STE */ 865c4676082SAlex Vesker stc_attr.action_offset = MLX5DR_ACTION_OFFSET_HIT; 866c4676082SAlex Vesker stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE; 867bbddd062SAlex Vesker stc_attr.reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE; 868c4676082SAlex Vesker stc_attr.ste_table.ste = matcher->action_ste.ste; 869c4676082SAlex Vesker stc_attr.ste_table.ste_pool = matcher->action_ste.pool; 870c4676082SAlex Vesker stc_attr.ste_table.match_definer_id = ctx->caps->trivial_match_definer; 871c4676082SAlex Vesker 872c4676082SAlex Vesker ret = mlx5dr_action_alloc_single_stc(ctx, &stc_attr, tbl->type, 873c4676082SAlex Vesker &matcher->action_ste.stc); 874c4676082SAlex Vesker if (ret) { 875c4676082SAlex Vesker DR_LOG(ERR, "Failed to create action jump to table STC"); 876c4676082SAlex Vesker goto free_rtc; 877c4676082SAlex Vesker } 878c4676082SAlex Vesker 879c4676082SAlex Vesker return 0; 880c4676082SAlex Vesker 881c4676082SAlex Vesker free_rtc: 88238b5bf64SYevgeny Kliteynik mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY); 883c4676082SAlex Vesker free_ste_pool: 884c4676082SAlex Vesker mlx5dr_pool_destroy(matcher->action_ste.pool); 885c4676082SAlex Vesker return rte_errno; 886c4676082SAlex Vesker } 887c4676082SAlex Vesker 888c4676082SAlex Vesker static void mlx5dr_matcher_unbind_at(struct mlx5dr_matcher *matcher) 889c4676082SAlex Vesker { 890c4676082SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 891c4676082SAlex Vesker 892762fecebSYevgeny Kliteynik if (!matcher->action_ste.max_stes || 893762fecebSYevgeny Kliteynik matcher->flags & MLX5DR_MATCHER_FLAGS_COLLISION || 894762fecebSYevgeny Kliteynik mlx5dr_matcher_is_in_resize(matcher)) 895c4676082SAlex Vesker return; 896c4676082SAlex Vesker 897c4676082SAlex Vesker mlx5dr_action_free_single_stc(tbl->ctx, tbl->type, &matcher->action_ste.stc); 89838b5bf64SYevgeny Kliteynik mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY); 899c4676082SAlex Vesker mlx5dr_pool_destroy(matcher->action_ste.pool); 900c4676082SAlex Vesker } 901c4676082SAlex Vesker 902c4676082SAlex Vesker static int mlx5dr_matcher_bind_mt(struct mlx5dr_matcher *matcher) 903c4676082SAlex Vesker { 904c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 905c4676082SAlex Vesker struct mlx5dr_pool_attr pool_attr = {0}; 90627ac2da9SAlex Vesker int ret; 907c4676082SAlex Vesker 9089732ffe1SAlex Vesker /* Calculate match, range and hash definers */ 90927ac2da9SAlex Vesker ret = mlx5dr_definer_matcher_init(ctx, matcher); 910c4676082SAlex Vesker if (ret) { 911e014d5e2SErez Shitrit DR_LOG(DEBUG, "Failed to set matcher templates with match definers"); 91227ac2da9SAlex Vesker return ret; 913c4676082SAlex Vesker } 914c4676082SAlex Vesker 915238190f3SAlex Vesker if (mlx5dr_matcher_req_fw_wqe(matcher) && 916238190f3SAlex Vesker !mlx5dr_matcher_supp_fw_wqe(matcher)) { 917238190f3SAlex Vesker DR_LOG(ERR, "Matcher requires FW WQE which is not supported"); 918238190f3SAlex Vesker rte_errno = ENOTSUP; 919238190f3SAlex Vesker ret = rte_errno; 920238190f3SAlex Vesker goto uninit_match_definer; 921238190f3SAlex Vesker } 922238190f3SAlex Vesker 923c4676082SAlex Vesker /* Create an STE pool per matcher*/ 92427ac2da9SAlex Vesker pool_attr.table_type = matcher->tbl->type; 925c4676082SAlex Vesker pool_attr.pool_type = MLX5DR_POOL_TYPE_STE; 926c4676082SAlex Vesker pool_attr.flags = MLX5DR_POOL_FLAGS_FOR_MATCHER_STE_POOL; 927c4676082SAlex Vesker pool_attr.alloc_log_sz = matcher->attr.table.sz_col_log + 928c4676082SAlex Vesker matcher->attr.table.sz_row_log; 9299732ffe1SAlex Vesker /* Add additional rows due to additional range STE */ 9309732ffe1SAlex Vesker if (matcher->flags & MLX5DR_MATCHER_FLAGS_RANGE_DEFINER) 9319732ffe1SAlex Vesker pool_attr.alloc_log_sz++; 932c4676082SAlex Vesker mlx5dr_matcher_set_pool_attr(&pool_attr, matcher); 933c4676082SAlex Vesker 934c4676082SAlex Vesker matcher->match_ste.pool = mlx5dr_pool_create(ctx, &pool_attr); 935c4676082SAlex Vesker if (!matcher->match_ste.pool) { 936c4676082SAlex Vesker DR_LOG(ERR, "Failed to allocate matcher STE pool"); 937238190f3SAlex Vesker ret = ENOTSUP; 93827ac2da9SAlex Vesker goto uninit_match_definer; 939c4676082SAlex Vesker } 940c4676082SAlex Vesker 941c4676082SAlex Vesker return 0; 942c4676082SAlex Vesker 94327ac2da9SAlex Vesker uninit_match_definer: 94427ac2da9SAlex Vesker mlx5dr_definer_matcher_uninit(matcher); 945c4676082SAlex Vesker return ret; 946c4676082SAlex Vesker } 947c4676082SAlex Vesker 948c4676082SAlex Vesker static void mlx5dr_matcher_unbind_mt(struct mlx5dr_matcher *matcher) 949c4676082SAlex Vesker { 950c4676082SAlex Vesker mlx5dr_pool_destroy(matcher->match_ste.pool); 95127ac2da9SAlex Vesker mlx5dr_definer_matcher_uninit(matcher); 952c4676082SAlex Vesker } 953c4676082SAlex Vesker 954c4676082SAlex Vesker static int 95538b5bf64SYevgeny Kliteynik mlx5dr_matcher_validate_insert_mode(struct mlx5dr_cmd_query_caps *caps, 956c4676082SAlex Vesker struct mlx5dr_matcher *matcher, 957c4676082SAlex Vesker bool is_root) 958c4676082SAlex Vesker { 959c4676082SAlex Vesker struct mlx5dr_matcher_attr *attr = &matcher->attr; 960c4676082SAlex Vesker 961c4676082SAlex Vesker if (is_root) { 962c4676082SAlex Vesker if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE) { 963c4676082SAlex Vesker DR_LOG(ERR, "Root matcher supports only rule resource mode"); 964c4676082SAlex Vesker goto not_supported; 965c4676082SAlex Vesker } 96638b5bf64SYevgeny Kliteynik if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH) { 96738b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Root matcher supports only insert by hash mode"); 96838b5bf64SYevgeny Kliteynik goto not_supported; 96938b5bf64SYevgeny Kliteynik } 97038b5bf64SYevgeny Kliteynik if (attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { 97138b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Root matcher supports only distribute by hash mode"); 97238b5bf64SYevgeny Kliteynik goto not_supported; 97338b5bf64SYevgeny Kliteynik } 97438b5bf64SYevgeny Kliteynik if (attr->optimize_flow_src) { 97538b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Root matcher can't specify FDB direction"); 97638b5bf64SYevgeny Kliteynik goto not_supported; 97738b5bf64SYevgeny Kliteynik } 97838b5bf64SYevgeny Kliteynik } 97938b5bf64SYevgeny Kliteynik 98038b5bf64SYevgeny Kliteynik switch (attr->insert_mode) { 98138b5bf64SYevgeny Kliteynik case MLX5DR_MATCHER_INSERT_BY_HASH: 98238b5bf64SYevgeny Kliteynik if (matcher->attr.distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { 98338b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Invalid matcher distribute mode"); 98438b5bf64SYevgeny Kliteynik goto not_supported; 98538b5bf64SYevgeny Kliteynik } 98638b5bf64SYevgeny Kliteynik break; 98738b5bf64SYevgeny Kliteynik 98838b5bf64SYevgeny Kliteynik case MLX5DR_MATCHER_INSERT_BY_INDEX: 98938b5bf64SYevgeny Kliteynik if (attr->table.sz_col_log) { 99038b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Matcher with INSERT_BY_INDEX supports only Nx1 table size"); 99138b5bf64SYevgeny Kliteynik goto not_supported; 99238b5bf64SYevgeny Kliteynik } 99338b5bf64SYevgeny Kliteynik 99438b5bf64SYevgeny Kliteynik if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { 99538b5bf64SYevgeny Kliteynik /* Hash Split Table */ 996*486f9aacSHamdan Igbaria if (attr->match_mode == MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT && 997*486f9aacSHamdan Igbaria !caps->rtc_hash_split_table) { 99838b5bf64SYevgeny Kliteynik DR_LOG(ERR, "FW doesn't support insert by index and hash distribute"); 99938b5bf64SYevgeny Kliteynik goto not_supported; 100038b5bf64SYevgeny Kliteynik } 1001*486f9aacSHamdan Igbaria 1002*486f9aacSHamdan Igbaria if (attr->match_mode == MLX5DR_MATCHER_MATCH_MODE_DEFAULT && 1003*486f9aacSHamdan Igbaria !attr->isolated) { 1004*486f9aacSHamdan Igbaria DR_LOG(ERR, "STE array matcher supported only as an isolated matcher"); 1005*486f9aacSHamdan Igbaria goto not_supported; 1006*486f9aacSHamdan Igbaria } 100738b5bf64SYevgeny Kliteynik } else if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) { 100838b5bf64SYevgeny Kliteynik /* Linear Lookup Table */ 100938b5bf64SYevgeny Kliteynik if (!caps->rtc_linear_lookup_table || 101038b5bf64SYevgeny Kliteynik !IS_BIT_SET(caps->access_index_mode, 101138b5bf64SYevgeny Kliteynik MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR)) { 101238b5bf64SYevgeny Kliteynik DR_LOG(ERR, "FW doesn't support insert by index and linear distribute"); 101338b5bf64SYevgeny Kliteynik goto not_supported; 101438b5bf64SYevgeny Kliteynik } 101538b5bf64SYevgeny Kliteynik 101638b5bf64SYevgeny Kliteynik if (attr->table.sz_row_log > MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX) { 101738b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Matcher with linear distribute: rows exceed limit %d", 101838b5bf64SYevgeny Kliteynik MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX); 101938b5bf64SYevgeny Kliteynik goto not_supported; 102038b5bf64SYevgeny Kliteynik } 1021*486f9aacSHamdan Igbaria 1022*486f9aacSHamdan Igbaria if (attr->match_mode != MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT) { 1023*486f9aacSHamdan Igbaria DR_LOG(ERR, "Linear lookup tables will always hit, given match mode is not supported %d\n", 1024*486f9aacSHamdan Igbaria attr->match_mode); 1025*486f9aacSHamdan Igbaria goto not_supported; 1026*486f9aacSHamdan Igbaria } 102738b5bf64SYevgeny Kliteynik } else { 102838b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Matcher has unsupported distribute mode"); 102938b5bf64SYevgeny Kliteynik goto not_supported; 103038b5bf64SYevgeny Kliteynik } 103138b5bf64SYevgeny Kliteynik break; 103238b5bf64SYevgeny Kliteynik 103338b5bf64SYevgeny Kliteynik default: 103438b5bf64SYevgeny Kliteynik DR_LOG(ERR, "Matcher has unsupported insert mode"); 103538b5bf64SYevgeny Kliteynik goto not_supported; 103638b5bf64SYevgeny Kliteynik } 103738b5bf64SYevgeny Kliteynik 103838b5bf64SYevgeny Kliteynik return 0; 103938b5bf64SYevgeny Kliteynik 104038b5bf64SYevgeny Kliteynik not_supported: 104138b5bf64SYevgeny Kliteynik rte_errno = EOPNOTSUPP; 104238b5bf64SYevgeny Kliteynik return rte_errno; 104338b5bf64SYevgeny Kliteynik } 104438b5bf64SYevgeny Kliteynik 104538b5bf64SYevgeny Kliteynik static int 104638b5bf64SYevgeny Kliteynik mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps, 104738b5bf64SYevgeny Kliteynik struct mlx5dr_matcher *matcher, 104838b5bf64SYevgeny Kliteynik bool is_root) 104938b5bf64SYevgeny Kliteynik { 105038b5bf64SYevgeny Kliteynik struct mlx5dr_matcher_attr *attr = &matcher->attr; 105138b5bf64SYevgeny Kliteynik 105238b5bf64SYevgeny Kliteynik if (mlx5dr_matcher_validate_insert_mode(caps, matcher, is_root)) 105338b5bf64SYevgeny Kliteynik goto not_supported; 105438b5bf64SYevgeny Kliteynik 105538b5bf64SYevgeny Kliteynik if (is_root) { 1056c4676082SAlex Vesker if (attr->optimize_flow_src) { 1057c4676082SAlex Vesker DR_LOG(ERR, "Root matcher can't specify FDB direction"); 1058c4676082SAlex Vesker goto not_supported; 1059c4676082SAlex Vesker } 1060c5713fc1SErez Shitrit if (attr->max_num_of_at_attach) { 1061c5713fc1SErez Shitrit DR_LOG(ERR, "Root matcher does not support at attaching"); 1062c5713fc1SErez Shitrit goto not_supported; 1063c5713fc1SErez Shitrit } 1064762fecebSYevgeny Kliteynik if (attr->resizable) { 1065762fecebSYevgeny Kliteynik DR_LOG(ERR, "Root matcher does not support resizing"); 1066762fecebSYevgeny Kliteynik goto not_supported; 1067762fecebSYevgeny Kliteynik } 1068*486f9aacSHamdan Igbaria if (attr->isolated) { 1069*486f9aacSHamdan Igbaria DR_LOG(ERR, "Root matcher can not be isolated"); 1070*486f9aacSHamdan Igbaria goto not_supported; 1071*486f9aacSHamdan Igbaria } 1072*486f9aacSHamdan Igbaria 1073c4676082SAlex Vesker return 0; 1074c4676082SAlex Vesker } 1075c4676082SAlex Vesker 107638b5bf64SYevgeny Kliteynik if (matcher->tbl->type != MLX5DR_TABLE_TYPE_FDB && attr->optimize_flow_src) { 107738b5bf64SYevgeny Kliteynik DR_LOG(ERR, "NIC domain doesn't support flow_src"); 107838b5bf64SYevgeny Kliteynik goto not_supported; 107938b5bf64SYevgeny Kliteynik } 108038b5bf64SYevgeny Kliteynik 1081c4676082SAlex Vesker /* Convert number of rules to the required depth */ 108238b5bf64SYevgeny Kliteynik if (attr->mode == MLX5DR_MATCHER_RESOURCE_MODE_RULE && 108338b5bf64SYevgeny Kliteynik attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) 1084c4676082SAlex Vesker attr->table.sz_col_log = mlx5dr_matcher_rules_to_tbl_depth(attr->rule.num_log); 1085c4676082SAlex Vesker 1086*486f9aacSHamdan Igbaria if (attr->isolated) { 1087*486f9aacSHamdan Igbaria if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_INDEX || 1088*486f9aacSHamdan Igbaria attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH || 1089*486f9aacSHamdan Igbaria attr->match_mode != MLX5DR_MATCHER_MATCH_MODE_DEFAULT) { 1090*486f9aacSHamdan Igbaria DR_LOG(ERR, "Isolated matcher only supported for STE array matcher"); 1091*486f9aacSHamdan Igbaria goto not_supported; 1092*486f9aacSHamdan Igbaria } 1093*486f9aacSHamdan Igbaria 1094*486f9aacSHamdan Igbaria /* We reach here only in case of STE array */ 1095*486f9aacSHamdan Igbaria matcher->flags |= MLX5DR_MATCHER_FLAGS_STE_ARRAY; 1096*486f9aacSHamdan Igbaria } 1097*486f9aacSHamdan Igbaria 1098762fecebSYevgeny Kliteynik matcher->flags |= attr->resizable ? MLX5DR_MATCHER_FLAGS_RESIZABLE : 0; 1099762fecebSYevgeny Kliteynik 1100186561f9SAlex Vesker return mlx5dr_matcher_check_attr_sz(caps, attr); 1101c4676082SAlex Vesker 1102c4676082SAlex Vesker not_supported: 1103c4676082SAlex Vesker rte_errno = EOPNOTSUPP; 1104c4676082SAlex Vesker return rte_errno; 1105c4676082SAlex Vesker } 1106c4676082SAlex Vesker 1107c4676082SAlex Vesker static int mlx5dr_matcher_create_and_connect(struct mlx5dr_matcher *matcher) 1108c4676082SAlex Vesker { 1109c4676082SAlex Vesker int ret; 1110c4676082SAlex Vesker 1111c4676082SAlex Vesker /* Select and create the definers for current matcher */ 1112c4676082SAlex Vesker ret = mlx5dr_matcher_bind_mt(matcher); 1113c4676082SAlex Vesker if (ret) 1114c4676082SAlex Vesker return ret; 1115c4676082SAlex Vesker 1116c4676082SAlex Vesker /* Calculate and verify action combination */ 1117c4676082SAlex Vesker ret = mlx5dr_matcher_bind_at(matcher); 1118c4676082SAlex Vesker if (ret) 1119c4676082SAlex Vesker goto unbind_mt; 1120c4676082SAlex Vesker 1121c4676082SAlex Vesker /* Create matcher end flow table anchor */ 1122c4676082SAlex Vesker ret = mlx5dr_matcher_create_end_ft(matcher); 1123c4676082SAlex Vesker if (ret) 1124c4676082SAlex Vesker goto unbind_at; 1125c4676082SAlex Vesker 1126c4676082SAlex Vesker /* Allocate the RTC for the new matcher */ 112738b5bf64SYevgeny Kliteynik ret = mlx5dr_matcher_create_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH); 1128c4676082SAlex Vesker if (ret) 1129c4676082SAlex Vesker goto destroy_end_ft; 1130c4676082SAlex Vesker 1131ce946c7dSErez Shitrit /* Allocate and set shared resources */ 1132ce946c7dSErez Shitrit ret = mlx5dr_matcher_create_init_shared(matcher); 1133c4676082SAlex Vesker if (ret) 1134c4676082SAlex Vesker goto destroy_rtc; 1135c4676082SAlex Vesker 1136ce946c7dSErez Shitrit /* Connect the matcher to the matcher list */ 1137ce946c7dSErez Shitrit ret = mlx5dr_matcher_connect(matcher); 1138ce946c7dSErez Shitrit if (ret) 1139ce946c7dSErez Shitrit goto destroy_shared; 1140ce946c7dSErez Shitrit 1141c4676082SAlex Vesker return 0; 1142c4676082SAlex Vesker 1143ce946c7dSErez Shitrit destroy_shared: 1144ce946c7dSErez Shitrit mlx5dr_matcher_create_uninit_shared(matcher); 1145c4676082SAlex Vesker destroy_rtc: 114638b5bf64SYevgeny Kliteynik mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH); 1147c4676082SAlex Vesker destroy_end_ft: 1148c4676082SAlex Vesker mlx5dr_matcher_destroy_end_ft(matcher); 1149c4676082SAlex Vesker unbind_at: 1150c4676082SAlex Vesker mlx5dr_matcher_unbind_at(matcher); 1151c4676082SAlex Vesker unbind_mt: 1152c4676082SAlex Vesker mlx5dr_matcher_unbind_mt(matcher); 1153c4676082SAlex Vesker return ret; 1154c4676082SAlex Vesker } 1155c4676082SAlex Vesker 1156c4676082SAlex Vesker static void mlx5dr_matcher_destroy_and_disconnect(struct mlx5dr_matcher *matcher) 1157c4676082SAlex Vesker { 1158762fecebSYevgeny Kliteynik mlx5dr_matcher_resize_uninit(matcher); 1159c4676082SAlex Vesker mlx5dr_matcher_disconnect(matcher); 1160ce946c7dSErez Shitrit mlx5dr_matcher_create_uninit_shared(matcher); 116138b5bf64SYevgeny Kliteynik mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH); 1162c4676082SAlex Vesker mlx5dr_matcher_destroy_end_ft(matcher); 1163c4676082SAlex Vesker mlx5dr_matcher_unbind_at(matcher); 1164c4676082SAlex Vesker mlx5dr_matcher_unbind_mt(matcher); 1165c4676082SAlex Vesker } 1166c4676082SAlex Vesker 1167c4676082SAlex Vesker static int 1168c4676082SAlex Vesker mlx5dr_matcher_create_col_matcher(struct mlx5dr_matcher *matcher) 1169c4676082SAlex Vesker { 1170c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 1171c4676082SAlex Vesker struct mlx5dr_matcher *col_matcher; 1172c4676082SAlex Vesker int ret; 1173c4676082SAlex Vesker 117417a62e0bSYevgeny Kliteynik if (matcher->attr.mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE || 117517a62e0bSYevgeny Kliteynik matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) 1176c4676082SAlex Vesker return 0; 1177c4676082SAlex Vesker 1178c4676082SAlex Vesker if (!mlx5dr_matcher_requires_col_tbl(matcher->attr.rule.num_log)) 1179c4676082SAlex Vesker return 0; 1180c4676082SAlex Vesker 1181c4676082SAlex Vesker col_matcher = simple_calloc(1, sizeof(*matcher)); 1182c4676082SAlex Vesker if (!col_matcher) { 1183c4676082SAlex Vesker rte_errno = ENOMEM; 1184c4676082SAlex Vesker return rte_errno; 1185c4676082SAlex Vesker } 1186c4676082SAlex Vesker 1187c4676082SAlex Vesker col_matcher->tbl = matcher->tbl; 1188940b0ebaSAlex Vesker col_matcher->mt = matcher->mt; 1189940b0ebaSAlex Vesker col_matcher->at = matcher->at; 1190c4676082SAlex Vesker col_matcher->num_of_at = matcher->num_of_at; 1191940b0ebaSAlex Vesker col_matcher->num_of_mt = matcher->num_of_mt; 1192238190f3SAlex Vesker col_matcher->hash_definer = matcher->hash_definer; 1193c4676082SAlex Vesker col_matcher->attr.priority = matcher->attr.priority; 119427ac2da9SAlex Vesker col_matcher->flags = matcher->flags; 119527ac2da9SAlex Vesker col_matcher->flags |= MLX5DR_MATCHER_FLAGS_COLLISION; 1196c4676082SAlex Vesker col_matcher->attr.mode = MLX5DR_MATCHER_RESOURCE_MODE_HTABLE; 1197c4676082SAlex Vesker col_matcher->attr.optimize_flow_src = matcher->attr.optimize_flow_src; 1198c4676082SAlex Vesker col_matcher->attr.table.sz_row_log = matcher->attr.rule.num_log; 1199c4676082SAlex Vesker col_matcher->attr.table.sz_col_log = MLX5DR_MATCHER_ASSURED_COL_TBL_DEPTH; 1200c4676082SAlex Vesker if (col_matcher->attr.table.sz_row_log > MLX5DR_MATCHER_ASSURED_ROW_RATIO) 1201c4676082SAlex Vesker col_matcher->attr.table.sz_row_log -= MLX5DR_MATCHER_ASSURED_ROW_RATIO; 1202c4676082SAlex Vesker 1203c5713fc1SErez Shitrit col_matcher->attr.max_num_of_at_attach = matcher->attr.max_num_of_at_attach; 1204c5713fc1SErez Shitrit 1205c4676082SAlex Vesker ret = mlx5dr_matcher_process_attr(ctx->caps, col_matcher, false); 1206c4676082SAlex Vesker if (ret) 1207c4676082SAlex Vesker goto free_col_matcher; 1208c4676082SAlex Vesker 1209c4676082SAlex Vesker ret = mlx5dr_matcher_create_and_connect(col_matcher); 1210c4676082SAlex Vesker if (ret) 1211c4676082SAlex Vesker goto free_col_matcher; 1212c4676082SAlex Vesker 1213c4676082SAlex Vesker matcher->col_matcher = col_matcher; 1214c4676082SAlex Vesker 1215c4676082SAlex Vesker return 0; 1216c4676082SAlex Vesker 1217c4676082SAlex Vesker free_col_matcher: 1218c4676082SAlex Vesker simple_free(col_matcher); 1219c4676082SAlex Vesker DR_LOG(ERR, "Failed to create assured collision matcher"); 1220c4676082SAlex Vesker return ret; 1221c4676082SAlex Vesker } 1222c4676082SAlex Vesker 1223c4676082SAlex Vesker static void 1224c4676082SAlex Vesker mlx5dr_matcher_destroy_col_matcher(struct mlx5dr_matcher *matcher) 1225c4676082SAlex Vesker { 122617a62e0bSYevgeny Kliteynik if (matcher->attr.mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE || 122717a62e0bSYevgeny Kliteynik matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) 1228c4676082SAlex Vesker return; 1229c4676082SAlex Vesker 1230c4676082SAlex Vesker if (matcher->col_matcher) { 1231c4676082SAlex Vesker mlx5dr_matcher_destroy_and_disconnect(matcher->col_matcher); 1232c4676082SAlex Vesker simple_free(matcher->col_matcher); 1233c4676082SAlex Vesker } 1234c4676082SAlex Vesker } 1235c4676082SAlex Vesker 1236c4676082SAlex Vesker static int mlx5dr_matcher_init(struct mlx5dr_matcher *matcher) 1237c4676082SAlex Vesker { 1238c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 1239c4676082SAlex Vesker int ret; 1240c4676082SAlex Vesker 1241c4676082SAlex Vesker pthread_spin_lock(&ctx->ctrl_lock); 1242c4676082SAlex Vesker 1243c4676082SAlex Vesker /* Allocate matcher resource and connect to the packet pipe */ 1244c4676082SAlex Vesker ret = mlx5dr_matcher_create_and_connect(matcher); 1245c4676082SAlex Vesker if (ret) 1246c4676082SAlex Vesker goto unlock_err; 1247c4676082SAlex Vesker 1248c4676082SAlex Vesker /* Create additional matcher for collision handling */ 1249c4676082SAlex Vesker ret = mlx5dr_matcher_create_col_matcher(matcher); 1250c4676082SAlex Vesker if (ret) 1251c4676082SAlex Vesker goto destory_and_disconnect; 1252c4676082SAlex Vesker 1253c4676082SAlex Vesker pthread_spin_unlock(&ctx->ctrl_lock); 1254c4676082SAlex Vesker 1255c4676082SAlex Vesker return 0; 1256c4676082SAlex Vesker 1257c4676082SAlex Vesker destory_and_disconnect: 1258c4676082SAlex Vesker mlx5dr_matcher_destroy_and_disconnect(matcher); 1259c4676082SAlex Vesker unlock_err: 1260c4676082SAlex Vesker pthread_spin_unlock(&ctx->ctrl_lock); 1261c4676082SAlex Vesker return ret; 1262c4676082SAlex Vesker } 1263c4676082SAlex Vesker 1264c4676082SAlex Vesker static int mlx5dr_matcher_uninit(struct mlx5dr_matcher *matcher) 1265c4676082SAlex Vesker { 1266c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 1267c4676082SAlex Vesker 1268c4676082SAlex Vesker pthread_spin_lock(&ctx->ctrl_lock); 1269c4676082SAlex Vesker mlx5dr_matcher_destroy_col_matcher(matcher); 1270c4676082SAlex Vesker mlx5dr_matcher_destroy_and_disconnect(matcher); 1271c4676082SAlex Vesker pthread_spin_unlock(&ctx->ctrl_lock); 1272c4676082SAlex Vesker 1273c4676082SAlex Vesker return 0; 1274c4676082SAlex Vesker } 1275c4676082SAlex Vesker 1276c4676082SAlex Vesker static int mlx5dr_matcher_init_root(struct mlx5dr_matcher *matcher) 1277c4676082SAlex Vesker { 1278c4676082SAlex Vesker enum mlx5dr_table_type type = matcher->tbl->type; 1279c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 1280c4676082SAlex Vesker struct mlx5dv_flow_matcher_attr attr = {0}; 1281c4676082SAlex Vesker struct mlx5dv_flow_match_parameters *mask; 1282c4676082SAlex Vesker struct mlx5_flow_attr flow_attr = {0}; 1283c4676082SAlex Vesker struct rte_flow_error rte_error; 1284c4676082SAlex Vesker uint8_t match_criteria; 1285c4676082SAlex Vesker int ret; 1286c4676082SAlex Vesker 1287c4676082SAlex Vesker #ifdef HAVE_MLX5DV_FLOW_MATCHER_FT_TYPE 1288c4676082SAlex Vesker attr.comp_mask = MLX5DV_FLOW_MATCHER_MASK_FT_TYPE; 1289c4676082SAlex Vesker 1290c4676082SAlex Vesker switch (type) { 1291c4676082SAlex Vesker case MLX5DR_TABLE_TYPE_NIC_RX: 1292c4676082SAlex Vesker attr.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_RX; 1293c4676082SAlex Vesker break; 1294c4676082SAlex Vesker case MLX5DR_TABLE_TYPE_NIC_TX: 1295c4676082SAlex Vesker attr.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_TX; 1296c4676082SAlex Vesker break; 1297c4676082SAlex Vesker case MLX5DR_TABLE_TYPE_FDB: 1298c4676082SAlex Vesker attr.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB; 1299c4676082SAlex Vesker break; 1300c4676082SAlex Vesker default: 1301c4676082SAlex Vesker assert(0); 1302c4676082SAlex Vesker break; 1303c4676082SAlex Vesker } 1304c4676082SAlex Vesker #endif 1305c4676082SAlex Vesker 1306c4676082SAlex Vesker if (matcher->attr.priority > UINT16_MAX) { 1307c4676082SAlex Vesker DR_LOG(ERR, "Root matcher priority exceeds allowed limit"); 1308c4676082SAlex Vesker rte_errno = EINVAL; 1309c4676082SAlex Vesker return rte_errno; 1310c4676082SAlex Vesker } 1311c4676082SAlex Vesker 1312572fe9efSErez Shitrit ret = flow_hw_get_port_id_from_ctx(ctx, &flow_attr.port_id); 1313572fe9efSErez Shitrit if (ret) { 1314befb138bSAlex Vesker DR_LOG(ERR, "Failed to get port id for dev %s", ctx->ibv_ctx->device->name); 1315572fe9efSErez Shitrit rte_errno = EINVAL; 1316572fe9efSErez Shitrit return rte_errno; 1317572fe9efSErez Shitrit } 1318572fe9efSErez Shitrit 1319c4676082SAlex Vesker mask = simple_calloc(1, MLX5_ST_SZ_BYTES(fte_match_param) + 1320c4676082SAlex Vesker offsetof(struct mlx5dv_flow_match_parameters, match_buf)); 1321c4676082SAlex Vesker if (!mask) { 1322c4676082SAlex Vesker rte_errno = ENOMEM; 1323c4676082SAlex Vesker return rte_errno; 1324c4676082SAlex Vesker } 1325c4676082SAlex Vesker 1326c4676082SAlex Vesker flow_attr.tbl_type = type; 1327c4676082SAlex Vesker 1328c4676082SAlex Vesker /* On root table matcher, only a single match template is supported */ 1329940b0ebaSAlex Vesker ret = flow_dv_translate_items_hws(matcher->mt[0].items, 1330c4676082SAlex Vesker &flow_attr, mask->match_buf, 1331c4676082SAlex Vesker MLX5_SET_MATCHER_HS_M, NULL, 1332c4676082SAlex Vesker &match_criteria, 1333c4676082SAlex Vesker &rte_error); 1334c4676082SAlex Vesker if (ret) { 1335c4676082SAlex Vesker DR_LOG(ERR, "Failed to convert items to PRM [%s]", rte_error.message); 1336c4676082SAlex Vesker goto free_mask; 1337c4676082SAlex Vesker } 1338c4676082SAlex Vesker 1339c4676082SAlex Vesker mask->match_sz = MLX5_ST_SZ_BYTES(fte_match_param); 1340c4676082SAlex Vesker attr.match_mask = mask; 1341c4676082SAlex Vesker attr.match_criteria_enable = match_criteria; 1342c4676082SAlex Vesker attr.type = IBV_FLOW_ATTR_NORMAL; 1343c4676082SAlex Vesker attr.priority = matcher->attr.priority; 1344c4676082SAlex Vesker 1345c4676082SAlex Vesker matcher->dv_matcher = 1346ce946c7dSErez Shitrit mlx5_glue->dv_create_flow_matcher_root(mlx5dr_context_get_local_ibv(ctx), 1347ce946c7dSErez Shitrit &attr); 1348c4676082SAlex Vesker if (!matcher->dv_matcher) { 1349c4676082SAlex Vesker DR_LOG(ERR, "Failed to create DV flow matcher"); 1350c4676082SAlex Vesker rte_errno = errno; 1351c4676082SAlex Vesker goto free_mask; 1352c4676082SAlex Vesker } 1353c4676082SAlex Vesker 1354c4676082SAlex Vesker simple_free(mask); 1355c4676082SAlex Vesker 1356c4676082SAlex Vesker pthread_spin_lock(&ctx->ctrl_lock); 1357c4676082SAlex Vesker LIST_INSERT_HEAD(&matcher->tbl->head, matcher, next); 1358c4676082SAlex Vesker pthread_spin_unlock(&ctx->ctrl_lock); 1359c4676082SAlex Vesker 1360c4676082SAlex Vesker return 0; 1361c4676082SAlex Vesker 1362c4676082SAlex Vesker free_mask: 1363c4676082SAlex Vesker simple_free(mask); 1364c4676082SAlex Vesker return rte_errno; 1365c4676082SAlex Vesker } 1366c4676082SAlex Vesker 1367c4676082SAlex Vesker static int mlx5dr_matcher_uninit_root(struct mlx5dr_matcher *matcher) 1368c4676082SAlex Vesker { 1369c4676082SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 1370c4676082SAlex Vesker int ret; 1371c4676082SAlex Vesker 1372c4676082SAlex Vesker pthread_spin_lock(&ctx->ctrl_lock); 1373c4676082SAlex Vesker LIST_REMOVE(matcher, next); 1374c4676082SAlex Vesker pthread_spin_unlock(&ctx->ctrl_lock); 1375c4676082SAlex Vesker 1376c4676082SAlex Vesker ret = mlx5_glue->dv_destroy_flow_matcher_root(matcher->dv_matcher); 1377c4676082SAlex Vesker if (ret) { 1378c4676082SAlex Vesker DR_LOG(ERR, "Failed to Destroy DV flow matcher"); 1379c4676082SAlex Vesker rte_errno = errno; 1380c4676082SAlex Vesker } 1381c4676082SAlex Vesker 1382c4676082SAlex Vesker return ret; 1383c4676082SAlex Vesker } 1384c4676082SAlex Vesker 1385c5713fc1SErez Shitrit int mlx5dr_matcher_attach_at(struct mlx5dr_matcher *matcher, 1386c5713fc1SErez Shitrit struct mlx5dr_action_template *at) 1387c5713fc1SErez Shitrit { 1388c5713fc1SErez Shitrit bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(matcher->mt); 1389c5713fc1SErez Shitrit uint32_t required_stes; 1390c5713fc1SErez Shitrit int ret; 1391c5713fc1SErez Shitrit 1392c5713fc1SErez Shitrit if (!matcher->attr.max_num_of_at_attach) { 139363911723SYevgeny Kliteynik DR_LOG(DEBUG, "Num of current at (%d) exceed allowed value", 1394c5713fc1SErez Shitrit matcher->num_of_at); 1395c5713fc1SErez Shitrit rte_errno = ENOTSUP; 1396c5713fc1SErez Shitrit return -rte_errno; 1397c5713fc1SErez Shitrit } 1398c5713fc1SErez Shitrit 1399c5713fc1SErez Shitrit ret = mlx5dr_matcher_check_and_process_at(matcher, at); 1400c5713fc1SErez Shitrit if (ret) 1401c5713fc1SErez Shitrit return -rte_errno; 1402c5713fc1SErez Shitrit 1403c5713fc1SErez Shitrit required_stes = at->num_of_action_stes - (!is_jumbo || at->only_term); 1404c5713fc1SErez Shitrit if (matcher->action_ste.max_stes < required_stes) { 140563911723SYevgeny Kliteynik DR_LOG(DEBUG, "Required STEs [%d] exceeds initial action template STE [%d]", 1406c5713fc1SErez Shitrit required_stes, matcher->action_ste.max_stes); 1407c5713fc1SErez Shitrit rte_errno = ENOMEM; 1408c5713fc1SErez Shitrit return -rte_errno; 1409c5713fc1SErez Shitrit } 1410c5713fc1SErez Shitrit 1411c5713fc1SErez Shitrit matcher->at[matcher->num_of_at] = *at; 1412c5713fc1SErez Shitrit matcher->num_of_at += 1; 1413c5713fc1SErez Shitrit matcher->attr.max_num_of_at_attach -= 1; 1414c5713fc1SErez Shitrit 1415c5713fc1SErez Shitrit if (matcher->col_matcher) 1416c5713fc1SErez Shitrit matcher->col_matcher->num_of_at = matcher->num_of_at; 1417c5713fc1SErez Shitrit 1418c5713fc1SErez Shitrit return 0; 1419c5713fc1SErez Shitrit } 1420c5713fc1SErez Shitrit 1421c4676082SAlex Vesker static int 1422940b0ebaSAlex Vesker mlx5dr_matcher_set_templates(struct mlx5dr_matcher *matcher, 1423940b0ebaSAlex Vesker struct mlx5dr_match_template *mt[], 1424940b0ebaSAlex Vesker uint8_t num_of_mt, 1425940b0ebaSAlex Vesker struct mlx5dr_action_template *at[], 1426940b0ebaSAlex Vesker uint8_t num_of_at) 1427c4676082SAlex Vesker { 1428940b0ebaSAlex Vesker bool is_root = mlx5dr_table_is_root(matcher->tbl); 1429940b0ebaSAlex Vesker int i; 1430c4676082SAlex Vesker 1431c4676082SAlex Vesker if (!num_of_mt || !num_of_at) { 1432c4676082SAlex Vesker DR_LOG(ERR, "Number of action/match template cannot be zero"); 1433940b0ebaSAlex Vesker rte_errno = ENOTSUP; 1434940b0ebaSAlex Vesker return rte_errno; 1435c4676082SAlex Vesker } 1436c4676082SAlex Vesker 1437940b0ebaSAlex Vesker if (is_root && num_of_mt > MLX5DR_MATCHER_MAX_MT_ROOT) { 1438c4676082SAlex Vesker DR_LOG(ERR, "Number of match templates exceeds limit"); 1439940b0ebaSAlex Vesker rte_errno = ENOTSUP; 1440940b0ebaSAlex Vesker return rte_errno; 1441c4676082SAlex Vesker } 1442c4676082SAlex Vesker 1443940b0ebaSAlex Vesker matcher->mt = simple_calloc(num_of_mt, sizeof(*matcher->mt)); 1444940b0ebaSAlex Vesker if (!matcher->mt) { 1445940b0ebaSAlex Vesker DR_LOG(ERR, "Failed to allocate match template array"); 1446940b0ebaSAlex Vesker rte_errno = ENOMEM; 1447940b0ebaSAlex Vesker return rte_errno; 1448940b0ebaSAlex Vesker } 1449940b0ebaSAlex Vesker 1450c5713fc1SErez Shitrit matcher->at = simple_calloc(num_of_at + matcher->attr.max_num_of_at_attach, 1451c5713fc1SErez Shitrit sizeof(*matcher->at)); 1452940b0ebaSAlex Vesker if (!matcher->at) { 1453940b0ebaSAlex Vesker DR_LOG(ERR, "Failed to allocate action template array"); 1454940b0ebaSAlex Vesker rte_errno = ENOMEM; 1455940b0ebaSAlex Vesker goto free_mt; 1456940b0ebaSAlex Vesker } 1457940b0ebaSAlex Vesker 1458940b0ebaSAlex Vesker for (i = 0; i < num_of_mt; i++) 1459940b0ebaSAlex Vesker matcher->mt[i] = *mt[i]; 1460940b0ebaSAlex Vesker 1461940b0ebaSAlex Vesker for (i = 0; i < num_of_at; i++) 1462940b0ebaSAlex Vesker matcher->at[i] = *at[i]; 1463940b0ebaSAlex Vesker 1464940b0ebaSAlex Vesker matcher->num_of_mt = num_of_mt; 1465940b0ebaSAlex Vesker matcher->num_of_at = num_of_at; 1466940b0ebaSAlex Vesker 1467c4676082SAlex Vesker return 0; 1468c4676082SAlex Vesker 1469940b0ebaSAlex Vesker free_mt: 1470940b0ebaSAlex Vesker simple_free(matcher->mt); 1471c4676082SAlex Vesker return rte_errno; 1472c4676082SAlex Vesker } 1473c4676082SAlex Vesker 1474940b0ebaSAlex Vesker static void 1475940b0ebaSAlex Vesker mlx5dr_matcher_unset_templates(struct mlx5dr_matcher *matcher) 1476940b0ebaSAlex Vesker { 1477940b0ebaSAlex Vesker simple_free(matcher->at); 1478940b0ebaSAlex Vesker simple_free(matcher->mt); 1479940b0ebaSAlex Vesker } 1480940b0ebaSAlex Vesker 1481c4676082SAlex Vesker struct mlx5dr_matcher * 1482c4676082SAlex Vesker mlx5dr_matcher_create(struct mlx5dr_table *tbl, 1483c4676082SAlex Vesker struct mlx5dr_match_template *mt[], 1484c4676082SAlex Vesker uint8_t num_of_mt, 1485c4676082SAlex Vesker struct mlx5dr_action_template *at[], 1486c4676082SAlex Vesker uint8_t num_of_at, 1487c4676082SAlex Vesker struct mlx5dr_matcher_attr *attr) 1488c4676082SAlex Vesker { 1489c4676082SAlex Vesker bool is_root = mlx5dr_table_is_root(tbl); 1490c4676082SAlex Vesker struct mlx5dr_matcher *matcher; 1491c4676082SAlex Vesker int ret; 1492c4676082SAlex Vesker 1493c4676082SAlex Vesker matcher = simple_calloc(1, sizeof(*matcher)); 1494c4676082SAlex Vesker if (!matcher) { 1495c4676082SAlex Vesker rte_errno = ENOMEM; 1496c4676082SAlex Vesker return NULL; 1497c4676082SAlex Vesker } 1498c4676082SAlex Vesker 1499c4676082SAlex Vesker matcher->tbl = tbl; 1500c4676082SAlex Vesker matcher->attr = *attr; 1501c4676082SAlex Vesker 1502c4676082SAlex Vesker ret = mlx5dr_matcher_process_attr(tbl->ctx->caps, matcher, is_root); 1503c4676082SAlex Vesker if (ret) 1504c4676082SAlex Vesker goto free_matcher; 1505c4676082SAlex Vesker 1506940b0ebaSAlex Vesker ret = mlx5dr_matcher_set_templates(matcher, mt, num_of_mt, at, num_of_at); 1507940b0ebaSAlex Vesker if (ret) 1508940b0ebaSAlex Vesker goto free_matcher; 1509940b0ebaSAlex Vesker 1510c4676082SAlex Vesker if (is_root) 1511c4676082SAlex Vesker ret = mlx5dr_matcher_init_root(matcher); 1512c4676082SAlex Vesker else 1513c4676082SAlex Vesker ret = mlx5dr_matcher_init(matcher); 1514c4676082SAlex Vesker 1515c4676082SAlex Vesker if (ret) { 1516c4676082SAlex Vesker DR_LOG(ERR, "Failed to initialise matcher: %d", ret); 1517940b0ebaSAlex Vesker goto unset_templates; 1518c4676082SAlex Vesker } 1519c4676082SAlex Vesker 1520c4676082SAlex Vesker return matcher; 1521c4676082SAlex Vesker 1522940b0ebaSAlex Vesker unset_templates: 1523940b0ebaSAlex Vesker mlx5dr_matcher_unset_templates(matcher); 1524c4676082SAlex Vesker free_matcher: 1525c4676082SAlex Vesker simple_free(matcher); 1526c4676082SAlex Vesker return NULL; 1527c4676082SAlex Vesker } 1528c4676082SAlex Vesker 1529c4676082SAlex Vesker int mlx5dr_matcher_destroy(struct mlx5dr_matcher *matcher) 1530c4676082SAlex Vesker { 1531c4676082SAlex Vesker if (mlx5dr_table_is_root(matcher->tbl)) 1532c4676082SAlex Vesker mlx5dr_matcher_uninit_root(matcher); 1533c4676082SAlex Vesker else 1534c4676082SAlex Vesker mlx5dr_matcher_uninit(matcher); 1535c4676082SAlex Vesker 1536940b0ebaSAlex Vesker mlx5dr_matcher_unset_templates(matcher); 1537c4676082SAlex Vesker simple_free(matcher); 1538c4676082SAlex Vesker return 0; 1539c4676082SAlex Vesker } 1540c4676082SAlex Vesker 1541c4676082SAlex Vesker struct mlx5dr_match_template * 1542c4676082SAlex Vesker mlx5dr_match_template_create(const struct rte_flow_item items[], 1543c4676082SAlex Vesker enum mlx5dr_match_template_flags flags) 1544c4676082SAlex Vesker { 1545c4676082SAlex Vesker struct mlx5dr_match_template *mt; 1546c4676082SAlex Vesker struct rte_flow_error error; 1547c4676082SAlex Vesker int ret, len; 1548c4676082SAlex Vesker 1549c4676082SAlex Vesker if (flags > MLX5DR_MATCH_TEMPLATE_FLAG_RELAXED_MATCH) { 1550c4676082SAlex Vesker DR_LOG(ERR, "Unsupported match template flag provided"); 1551c4676082SAlex Vesker rte_errno = EINVAL; 1552c4676082SAlex Vesker return NULL; 1553c4676082SAlex Vesker } 1554c4676082SAlex Vesker 1555c4676082SAlex Vesker mt = simple_calloc(1, sizeof(*mt)); 1556c4676082SAlex Vesker if (!mt) { 1557c4676082SAlex Vesker DR_LOG(ERR, "Failed to allocate match template"); 1558c4676082SAlex Vesker rte_errno = ENOMEM; 1559c4676082SAlex Vesker return NULL; 1560c4676082SAlex Vesker } 1561c4676082SAlex Vesker 1562c4676082SAlex Vesker mt->flags = flags; 1563c4676082SAlex Vesker 1564c4676082SAlex Vesker /* Duplicate the user given items */ 1565c4676082SAlex Vesker ret = rte_flow_conv(RTE_FLOW_CONV_OP_PATTERN, NULL, 0, items, &error); 1566c4676082SAlex Vesker if (ret <= 0) { 1567c4676082SAlex Vesker DR_LOG(ERR, "Unable to process items (%s): %s", 1568c4676082SAlex Vesker error.message ? error.message : "unspecified", 1569c4676082SAlex Vesker strerror(rte_errno)); 1570c4676082SAlex Vesker goto free_template; 1571c4676082SAlex Vesker } 1572c4676082SAlex Vesker 1573c4676082SAlex Vesker len = RTE_ALIGN(ret, 16); 1574c4676082SAlex Vesker mt->items = simple_calloc(1, len); 1575c4676082SAlex Vesker if (!mt->items) { 1576c4676082SAlex Vesker DR_LOG(ERR, "Failed to allocate item copy"); 1577c4676082SAlex Vesker rte_errno = ENOMEM; 1578c4676082SAlex Vesker goto free_template; 1579c4676082SAlex Vesker } 1580c4676082SAlex Vesker 1581c4676082SAlex Vesker ret = rte_flow_conv(RTE_FLOW_CONV_OP_PATTERN, mt->items, ret, items, &error); 1582c4676082SAlex Vesker if (ret <= 0) 1583c4676082SAlex Vesker goto free_dst; 1584c4676082SAlex Vesker 1585c4676082SAlex Vesker return mt; 1586c4676082SAlex Vesker 1587c4676082SAlex Vesker free_dst: 1588c4676082SAlex Vesker simple_free(mt->items); 1589c4676082SAlex Vesker free_template: 1590c4676082SAlex Vesker simple_free(mt); 1591c4676082SAlex Vesker return NULL; 1592c4676082SAlex Vesker } 1593c4676082SAlex Vesker 1594c4676082SAlex Vesker int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt) 1595c4676082SAlex Vesker { 1596c4676082SAlex Vesker simple_free(mt->items); 1597c4676082SAlex Vesker simple_free(mt); 1598c4676082SAlex Vesker return 0; 1599c4676082SAlex Vesker } 1600762fecebSYevgeny Kliteynik 1601d64bbe7bSErez Shitrit bool mlx5dr_matcher_is_updatable(struct mlx5dr_matcher *matcher) 1602d64bbe7bSErez Shitrit { 1603d64bbe7bSErez Shitrit if (mlx5dr_table_is_root(matcher->tbl) || 1604d64bbe7bSErez Shitrit mlx5dr_matcher_req_fw_wqe(matcher) || 1605d64bbe7bSErez Shitrit mlx5dr_matcher_is_resizable(matcher) || 1606d64bbe7bSErez Shitrit (!matcher->attr.optimize_using_rule_idx && 1607d64bbe7bSErez Shitrit !mlx5dr_matcher_is_insert_by_idx(matcher))) 1608d64bbe7bSErez Shitrit return false; 1609d64bbe7bSErez Shitrit 1610d64bbe7bSErez Shitrit return true; 1611d64bbe7bSErez Shitrit } 1612d64bbe7bSErez Shitrit 16133af4ed67SErez Shitrit bool mlx5dr_matcher_is_dependent(struct mlx5dr_matcher *matcher) 16143af4ed67SErez Shitrit { 16153af4ed67SErez Shitrit int i; 16163af4ed67SErez Shitrit 16173af4ed67SErez Shitrit if (matcher->action_ste.max_stes || mlx5dr_matcher_req_fw_wqe(matcher)) 16183af4ed67SErez Shitrit return true; 16193af4ed67SErez Shitrit 16203af4ed67SErez Shitrit for (i = 0; i < matcher->num_of_at; i++) { 16213af4ed67SErez Shitrit struct mlx5dr_action_template *at = &matcher->at[i]; 16223af4ed67SErez Shitrit 16233af4ed67SErez Shitrit if (at->need_dep_write) 16243af4ed67SErez Shitrit return true; 16253af4ed67SErez Shitrit } 16263af4ed67SErez Shitrit 16273af4ed67SErez Shitrit return false; 16283af4ed67SErez Shitrit } 16293af4ed67SErez Shitrit 1630762fecebSYevgeny Kliteynik static int mlx5dr_matcher_resize_precheck(struct mlx5dr_matcher *src_matcher, 1631762fecebSYevgeny Kliteynik struct mlx5dr_matcher *dst_matcher) 1632762fecebSYevgeny Kliteynik { 1633762fecebSYevgeny Kliteynik int i; 1634762fecebSYevgeny Kliteynik 1635762fecebSYevgeny Kliteynik if (mlx5dr_table_is_root(src_matcher->tbl) || 1636762fecebSYevgeny Kliteynik mlx5dr_table_is_root(dst_matcher->tbl)) { 1637762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matcher belongs to root table - resize unsupported"); 1638762fecebSYevgeny Kliteynik goto out_einval; 1639762fecebSYevgeny Kliteynik } 1640762fecebSYevgeny Kliteynik 1641762fecebSYevgeny Kliteynik if (src_matcher->tbl->type != dst_matcher->tbl->type) { 1642762fecebSYevgeny Kliteynik DR_LOG(ERR, "Table type mismatch for src/dst matchers"); 1643762fecebSYevgeny Kliteynik goto out_einval; 1644762fecebSYevgeny Kliteynik } 1645762fecebSYevgeny Kliteynik 1646762fecebSYevgeny Kliteynik if (mlx5dr_matcher_req_fw_wqe(src_matcher) || 1647762fecebSYevgeny Kliteynik mlx5dr_matcher_req_fw_wqe(dst_matcher)) { 1648762fecebSYevgeny Kliteynik DR_LOG(ERR, "Matchers require FW WQE - resize unsupported"); 1649762fecebSYevgeny Kliteynik goto out_einval; 1650762fecebSYevgeny Kliteynik } 1651762fecebSYevgeny Kliteynik 1652762fecebSYevgeny Kliteynik if (!mlx5dr_matcher_is_resizable(src_matcher) || 1653762fecebSYevgeny Kliteynik !mlx5dr_matcher_is_resizable(dst_matcher)) { 1654762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matcher is not resizable"); 1655762fecebSYevgeny Kliteynik goto out_einval; 1656762fecebSYevgeny Kliteynik } 1657762fecebSYevgeny Kliteynik 1658762fecebSYevgeny Kliteynik if (mlx5dr_matcher_is_insert_by_idx(src_matcher) != 1659762fecebSYevgeny Kliteynik mlx5dr_matcher_is_insert_by_idx(dst_matcher)) { 1660762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matchers insert mode mismatch"); 1661762fecebSYevgeny Kliteynik goto out_einval; 1662762fecebSYevgeny Kliteynik } 1663762fecebSYevgeny Kliteynik 1664762fecebSYevgeny Kliteynik if (mlx5dr_matcher_is_in_resize(src_matcher) || 1665762fecebSYevgeny Kliteynik mlx5dr_matcher_is_in_resize(dst_matcher)) { 1666762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matcher is already in resize"); 1667762fecebSYevgeny Kliteynik goto out_einval; 1668762fecebSYevgeny Kliteynik } 1669762fecebSYevgeny Kliteynik 1670762fecebSYevgeny Kliteynik /* Compare match templates - make sure the definers are equivalent */ 1671762fecebSYevgeny Kliteynik if (src_matcher->num_of_mt != dst_matcher->num_of_mt) { 1672762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matcher match templates mismatch"); 1673762fecebSYevgeny Kliteynik goto out_einval; 1674762fecebSYevgeny Kliteynik } 1675762fecebSYevgeny Kliteynik 1676762fecebSYevgeny Kliteynik if (src_matcher->action_ste.max_stes > dst_matcher->action_ste.max_stes) { 1677762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matcher max STEs mismatch"); 1678762fecebSYevgeny Kliteynik goto out_einval; 1679762fecebSYevgeny Kliteynik } 1680762fecebSYevgeny Kliteynik 1681762fecebSYevgeny Kliteynik for (i = 0; i < src_matcher->num_of_mt; i++) { 1682762fecebSYevgeny Kliteynik if (mlx5dr_definer_compare(src_matcher->mt[i].definer, 1683762fecebSYevgeny Kliteynik dst_matcher->mt[i].definer)) { 1684762fecebSYevgeny Kliteynik DR_LOG(ERR, "Src/dst matcher definers mismatch"); 1685762fecebSYevgeny Kliteynik goto out_einval; 1686762fecebSYevgeny Kliteynik } 1687762fecebSYevgeny Kliteynik } 1688762fecebSYevgeny Kliteynik 1689762fecebSYevgeny Kliteynik return 0; 1690762fecebSYevgeny Kliteynik 1691762fecebSYevgeny Kliteynik out_einval: 1692762fecebSYevgeny Kliteynik rte_errno = EINVAL; 1693762fecebSYevgeny Kliteynik return rte_errno; 1694762fecebSYevgeny Kliteynik } 1695762fecebSYevgeny Kliteynik 1696762fecebSYevgeny Kliteynik int mlx5dr_matcher_resize_set_target(struct mlx5dr_matcher *src_matcher, 1697762fecebSYevgeny Kliteynik struct mlx5dr_matcher *dst_matcher) 1698762fecebSYevgeny Kliteynik { 1699762fecebSYevgeny Kliteynik int ret = 0; 1700762fecebSYevgeny Kliteynik 1701762fecebSYevgeny Kliteynik pthread_spin_lock(&src_matcher->tbl->ctx->ctrl_lock); 1702762fecebSYevgeny Kliteynik 1703762fecebSYevgeny Kliteynik if (mlx5dr_matcher_resize_precheck(src_matcher, dst_matcher)) { 1704762fecebSYevgeny Kliteynik ret = -rte_errno; 1705762fecebSYevgeny Kliteynik goto out; 1706762fecebSYevgeny Kliteynik } 1707762fecebSYevgeny Kliteynik 1708762fecebSYevgeny Kliteynik src_matcher->resize_dst = dst_matcher; 1709762fecebSYevgeny Kliteynik 1710762fecebSYevgeny Kliteynik if (mlx5dr_matcher_resize_init(src_matcher)) { 1711762fecebSYevgeny Kliteynik src_matcher->resize_dst = NULL; 1712762fecebSYevgeny Kliteynik ret = -rte_errno; 1713762fecebSYevgeny Kliteynik } 1714762fecebSYevgeny Kliteynik 1715762fecebSYevgeny Kliteynik out: 1716762fecebSYevgeny Kliteynik pthread_spin_unlock(&src_matcher->tbl->ctx->ctrl_lock); 1717762fecebSYevgeny Kliteynik return ret; 1718762fecebSYevgeny Kliteynik } 1719762fecebSYevgeny Kliteynik 1720762fecebSYevgeny Kliteynik int mlx5dr_matcher_resize_rule_move(struct mlx5dr_matcher *src_matcher, 1721762fecebSYevgeny Kliteynik struct mlx5dr_rule *rule, 1722762fecebSYevgeny Kliteynik struct mlx5dr_rule_attr *attr) 1723762fecebSYevgeny Kliteynik { 1724762fecebSYevgeny Kliteynik if (unlikely(!mlx5dr_matcher_is_in_resize(src_matcher))) { 1725762fecebSYevgeny Kliteynik DR_LOG(ERR, "Matcher is not resizable or not in resize"); 1726762fecebSYevgeny Kliteynik goto out_einval; 1727762fecebSYevgeny Kliteynik } 1728762fecebSYevgeny Kliteynik 1729762fecebSYevgeny Kliteynik if (unlikely(src_matcher != rule->matcher)) { 1730762fecebSYevgeny Kliteynik DR_LOG(ERR, "Rule doesn't belong to src matcher"); 1731762fecebSYevgeny Kliteynik goto out_einval; 1732762fecebSYevgeny Kliteynik } 1733762fecebSYevgeny Kliteynik 1734762fecebSYevgeny Kliteynik return mlx5dr_rule_move_hws_add(rule, attr); 1735762fecebSYevgeny Kliteynik 1736762fecebSYevgeny Kliteynik out_einval: 1737762fecebSYevgeny Kliteynik rte_errno = EINVAL; 1738762fecebSYevgeny Kliteynik return -rte_errno; 1739762fecebSYevgeny Kliteynik } 1740a5230507SHamdan Igbaria 1741a5230507SHamdan Igbaria int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) 1742a5230507SHamdan Igbaria { 1743a5230507SHamdan Igbaria struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; 1744a5230507SHamdan Igbaria struct mlx5dr_matcher_attr *attr = &matcher->attr; 1745a5230507SHamdan Igbaria 1746a5230507SHamdan Igbaria if (mlx5dr_table_is_root(matcher->tbl)) { 1747a5230507SHamdan Igbaria DR_LOG(ERR, "Compare matcher is not supported for root tables"); 1748a5230507SHamdan Igbaria goto err; 1749a5230507SHamdan Igbaria } 1750a5230507SHamdan Igbaria 1751a5230507SHamdan Igbaria if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { 1752a5230507SHamdan Igbaria DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); 1753a5230507SHamdan Igbaria goto err; 1754a5230507SHamdan Igbaria } 1755a5230507SHamdan Igbaria 1756a5230507SHamdan Igbaria if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || 1757a5230507SHamdan Igbaria attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { 1758a5230507SHamdan Igbaria DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); 1759a5230507SHamdan Igbaria goto err; 1760a5230507SHamdan Igbaria } 1761a5230507SHamdan Igbaria 1762a5230507SHamdan Igbaria if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { 1763a5230507SHamdan Igbaria DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); 1764a5230507SHamdan Igbaria goto err; 1765a5230507SHamdan Igbaria } 1766a5230507SHamdan Igbaria 1767a5230507SHamdan Igbaria if (attr->table.sz_col_log || attr->table.sz_row_log) { 1768a5230507SHamdan Igbaria DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); 1769a5230507SHamdan Igbaria goto err; 1770a5230507SHamdan Igbaria } 1771a5230507SHamdan Igbaria 1772a5230507SHamdan Igbaria if (attr->resizable) { 1773a5230507SHamdan Igbaria DR_LOG(ERR, "Compare matcher does not support resizeing"); 1774a5230507SHamdan Igbaria goto err; 1775a5230507SHamdan Igbaria } 1776a5230507SHamdan Igbaria 1777a5230507SHamdan Igbaria if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { 1778a5230507SHamdan Igbaria DR_LOG(ERR, "Gen WQE Compare match format not supported"); 1779a5230507SHamdan Igbaria goto err; 1780a5230507SHamdan Igbaria } 1781a5230507SHamdan Igbaria 1782a5230507SHamdan Igbaria return 0; 1783a5230507SHamdan Igbaria 1784a5230507SHamdan Igbaria err: 1785a5230507SHamdan Igbaria rte_errno = ENOTSUP; 1786a5230507SHamdan Igbaria return rte_errno; 1787a5230507SHamdan Igbaria } 1788