1405242c5SAlex Vesker /* SPDX-License-Identifier: BSD-3-Clause 2405242c5SAlex Vesker * Copyright (c) 2022 NVIDIA Corporation & Affiliates 3405242c5SAlex Vesker */ 4405242c5SAlex Vesker 5405242c5SAlex Vesker #include "mlx5dr_internal.h" 6405242c5SAlex Vesker 7405242c5SAlex Vesker static void mlx5dr_rule_skip(struct mlx5dr_matcher *matcher, 8940b0ebaSAlex Vesker struct mlx5dr_match_template *mt, 9405242c5SAlex Vesker const struct rte_flow_item *items, 10405242c5SAlex Vesker bool *skip_rx, bool *skip_tx) 11405242c5SAlex Vesker { 12405242c5SAlex Vesker const struct flow_hw_port_info *vport; 13405242c5SAlex Vesker const struct rte_flow_item_ethdev *v; 14405242c5SAlex Vesker 15405242c5SAlex Vesker /* Flow_src is the 1st priority */ 16405242c5SAlex Vesker if (matcher->attr.optimize_flow_src) { 17405242c5SAlex Vesker *skip_tx = matcher->attr.optimize_flow_src == MLX5DR_MATCHER_FLOW_SRC_WIRE; 18405242c5SAlex Vesker *skip_rx = matcher->attr.optimize_flow_src == MLX5DR_MATCHER_FLOW_SRC_VPORT; 19405242c5SAlex Vesker return; 20405242c5SAlex Vesker } 21405242c5SAlex Vesker 22405242c5SAlex Vesker /* By default FDB rules are added to both RX and TX */ 23405242c5SAlex Vesker *skip_rx = false; 24405242c5SAlex Vesker *skip_tx = false; 25405242c5SAlex Vesker 26e23edbc5SItamar Gozlan if (unlikely(mlx5dr_matcher_is_insert_by_idx(matcher))) 27e23edbc5SItamar Gozlan return; 28e23edbc5SItamar Gozlan 29405242c5SAlex Vesker if (mt->item_flags & MLX5_FLOW_ITEM_REPRESENTED_PORT) { 30405242c5SAlex Vesker v = items[mt->vport_item_id].spec; 314cbeba6fSSuanming Mou vport = flow_hw_conv_port_id(matcher->tbl->ctx, v->port_id); 32405242c5SAlex Vesker if (unlikely(!vport)) { 33405242c5SAlex Vesker DR_LOG(ERR, "Fail to map port ID %d, ignoring", v->port_id); 34405242c5SAlex Vesker return; 35405242c5SAlex Vesker } 36405242c5SAlex Vesker 37405242c5SAlex Vesker if (!vport->is_wire) 38405242c5SAlex Vesker /* Match vport ID is not WIRE -> Skip RX */ 39405242c5SAlex Vesker *skip_rx = true; 40405242c5SAlex Vesker else 41405242c5SAlex Vesker /* Match vport ID is WIRE -> Skip TX */ 42405242c5SAlex Vesker *skip_tx = true; 43405242c5SAlex Vesker } 44405242c5SAlex Vesker } 45405242c5SAlex Vesker 46fa16feadSErez Shitrit static void 47fa16feadSErez Shitrit mlx5dr_rule_update_copy_tag(struct mlx5dr_rule *rule, 48fa16feadSErez Shitrit struct mlx5dr_wqe_gta_data_seg_ste *wqe_data, 49fa16feadSErez Shitrit bool is_jumbo) 50fa16feadSErez Shitrit { 51fa16feadSErez Shitrit if (is_jumbo) 52fa16feadSErez Shitrit memcpy(wqe_data->jumbo, rule->tag.jumbo, MLX5DR_JUMBO_TAG_SZ); 53fa16feadSErez Shitrit else 54fa16feadSErez Shitrit memcpy(wqe_data->tag, rule->tag.match, MLX5DR_MATCH_TAG_SZ); 55fa16feadSErez Shitrit } 56fa16feadSErez Shitrit 57405242c5SAlex Vesker static void mlx5dr_rule_init_dep_wqe(struct mlx5dr_send_ring_dep_wqe *dep_wqe, 58405242c5SAlex Vesker struct mlx5dr_rule *rule, 59405242c5SAlex Vesker const struct rte_flow_item *items, 60940b0ebaSAlex Vesker struct mlx5dr_match_template *mt, 61e28392b3SAlex Vesker struct mlx5dr_rule_attr *attr) 62405242c5SAlex Vesker { 63405242c5SAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 64405242c5SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 65405242c5SAlex Vesker bool skip_rx, skip_tx; 66405242c5SAlex Vesker 67405242c5SAlex Vesker dep_wqe->rule = rule; 68e28392b3SAlex Vesker dep_wqe->user_data = attr->user_data; 69e28392b3SAlex Vesker dep_wqe->direct_index = mlx5dr_matcher_is_insert_by_idx(matcher) ? 70e28392b3SAlex Vesker attr->rule_idx : 0; 71405242c5SAlex Vesker 72fa16feadSErez Shitrit if (!items) { /* rule update */ 73fa16feadSErez Shitrit dep_wqe->rtc_0 = rule->rtc_0; 74fa16feadSErez Shitrit dep_wqe->rtc_1 = rule->rtc_1; 75fa16feadSErez Shitrit dep_wqe->retry_rtc_1 = 0; 76fa16feadSErez Shitrit dep_wqe->retry_rtc_0 = 0; 77fa16feadSErez Shitrit return; 78fa16feadSErez Shitrit } 79fa16feadSErez Shitrit 80405242c5SAlex Vesker switch (tbl->type) { 81405242c5SAlex Vesker case MLX5DR_TABLE_TYPE_NIC_RX: 82405242c5SAlex Vesker case MLX5DR_TABLE_TYPE_NIC_TX: 83405242c5SAlex Vesker dep_wqe->rtc_0 = matcher->match_ste.rtc_0->id; 84405242c5SAlex Vesker dep_wqe->retry_rtc_0 = matcher->col_matcher ? 85405242c5SAlex Vesker matcher->col_matcher->match_ste.rtc_0->id : 0; 86405242c5SAlex Vesker dep_wqe->rtc_1 = 0; 87405242c5SAlex Vesker dep_wqe->retry_rtc_1 = 0; 88405242c5SAlex Vesker break; 89405242c5SAlex Vesker 90405242c5SAlex Vesker case MLX5DR_TABLE_TYPE_FDB: 91940b0ebaSAlex Vesker mlx5dr_rule_skip(matcher, mt, items, &skip_rx, &skip_tx); 92405242c5SAlex Vesker 93405242c5SAlex Vesker if (!skip_rx) { 94405242c5SAlex Vesker dep_wqe->rtc_0 = matcher->match_ste.rtc_0->id; 95405242c5SAlex Vesker dep_wqe->retry_rtc_0 = matcher->col_matcher ? 96405242c5SAlex Vesker matcher->col_matcher->match_ste.rtc_0->id : 0; 97405242c5SAlex Vesker } else { 98405242c5SAlex Vesker dep_wqe->rtc_0 = 0; 99405242c5SAlex Vesker dep_wqe->retry_rtc_0 = 0; 100405242c5SAlex Vesker } 101405242c5SAlex Vesker 102405242c5SAlex Vesker if (!skip_tx) { 103405242c5SAlex Vesker dep_wqe->rtc_1 = matcher->match_ste.rtc_1->id; 104405242c5SAlex Vesker dep_wqe->retry_rtc_1 = matcher->col_matcher ? 105405242c5SAlex Vesker matcher->col_matcher->match_ste.rtc_1->id : 0; 106405242c5SAlex Vesker } else { 107405242c5SAlex Vesker dep_wqe->rtc_1 = 0; 108405242c5SAlex Vesker dep_wqe->retry_rtc_1 = 0; 109405242c5SAlex Vesker } 110405242c5SAlex Vesker 111405242c5SAlex Vesker break; 112405242c5SAlex Vesker 113405242c5SAlex Vesker default: 114405242c5SAlex Vesker assert(false); 115405242c5SAlex Vesker break; 116405242c5SAlex Vesker } 117405242c5SAlex Vesker } 118405242c5SAlex Vesker 119762fecebSYevgeny Kliteynik static void mlx5dr_rule_move_get_rtc(struct mlx5dr_rule *rule, 120762fecebSYevgeny Kliteynik struct mlx5dr_send_ste_attr *ste_attr) 121762fecebSYevgeny Kliteynik { 122762fecebSYevgeny Kliteynik struct mlx5dr_matcher *dst_matcher = rule->matcher->resize_dst; 123762fecebSYevgeny Kliteynik 124762fecebSYevgeny Kliteynik if (rule->resize_info->rtc_0) { 125762fecebSYevgeny Kliteynik ste_attr->rtc_0 = dst_matcher->match_ste.rtc_0->id; 126762fecebSYevgeny Kliteynik ste_attr->retry_rtc_0 = dst_matcher->col_matcher ? 127762fecebSYevgeny Kliteynik dst_matcher->col_matcher->match_ste.rtc_0->id : 0; 128762fecebSYevgeny Kliteynik } 129762fecebSYevgeny Kliteynik if (rule->resize_info->rtc_1) { 130762fecebSYevgeny Kliteynik ste_attr->rtc_1 = dst_matcher->match_ste.rtc_1->id; 131762fecebSYevgeny Kliteynik ste_attr->retry_rtc_1 = dst_matcher->col_matcher ? 132762fecebSYevgeny Kliteynik dst_matcher->col_matcher->match_ste.rtc_1->id : 0; 133762fecebSYevgeny Kliteynik } 134762fecebSYevgeny Kliteynik } 135762fecebSYevgeny Kliteynik 136405242c5SAlex Vesker static void mlx5dr_rule_gen_comp(struct mlx5dr_send_engine *queue, 137405242c5SAlex Vesker struct mlx5dr_rule *rule, 138405242c5SAlex Vesker bool err, 139405242c5SAlex Vesker void *user_data, 140405242c5SAlex Vesker enum mlx5dr_rule_status rule_status_on_succ) 141405242c5SAlex Vesker { 142405242c5SAlex Vesker enum rte_flow_op_status comp_status; 143405242c5SAlex Vesker 144405242c5SAlex Vesker if (!err) { 145405242c5SAlex Vesker comp_status = RTE_FLOW_OP_SUCCESS; 146405242c5SAlex Vesker rule->status = rule_status_on_succ; 147405242c5SAlex Vesker } else { 148405242c5SAlex Vesker comp_status = RTE_FLOW_OP_ERROR; 149405242c5SAlex Vesker rule->status = MLX5DR_RULE_STATUS_FAILED; 150405242c5SAlex Vesker } 151405242c5SAlex Vesker 152405242c5SAlex Vesker mlx5dr_send_engine_inc_rule(queue); 153405242c5SAlex Vesker mlx5dr_send_engine_gen_comp(queue, user_data, comp_status); 154405242c5SAlex Vesker } 155405242c5SAlex Vesker 156348cdeecSAlex Vesker static void 157762fecebSYevgeny Kliteynik mlx5dr_rule_save_resize_info(struct mlx5dr_rule *rule, 158762fecebSYevgeny Kliteynik struct mlx5dr_send_ste_attr *ste_attr) 159762fecebSYevgeny Kliteynik { 160c54d3949SYevgeny Kliteynik if (likely(!mlx5dr_matcher_is_resizable(rule->matcher))) 161c54d3949SYevgeny Kliteynik return; 162c54d3949SYevgeny Kliteynik 163762fecebSYevgeny Kliteynik rule->resize_info = simple_calloc(1, sizeof(*rule->resize_info)); 164762fecebSYevgeny Kliteynik if (unlikely(!rule->resize_info)) { 165762fecebSYevgeny Kliteynik assert(rule->resize_info); 166762fecebSYevgeny Kliteynik rte_errno = ENOMEM; 167762fecebSYevgeny Kliteynik } 168762fecebSYevgeny Kliteynik 169762fecebSYevgeny Kliteynik memcpy(rule->resize_info->ctrl_seg, ste_attr->wqe_ctrl, 170762fecebSYevgeny Kliteynik sizeof(rule->resize_info->ctrl_seg)); 171762fecebSYevgeny Kliteynik memcpy(rule->resize_info->data_seg, ste_attr->wqe_data, 172762fecebSYevgeny Kliteynik sizeof(rule->resize_info->data_seg)); 173762fecebSYevgeny Kliteynik 174c54d3949SYevgeny Kliteynik rule->resize_info->max_stes = rule->matcher->action_ste.max_stes; 175762fecebSYevgeny Kliteynik rule->resize_info->action_ste_pool = rule->matcher->action_ste.max_stes ? 176762fecebSYevgeny Kliteynik rule->matcher->action_ste.pool : 177762fecebSYevgeny Kliteynik NULL; 178762fecebSYevgeny Kliteynik } 179762fecebSYevgeny Kliteynik 180c54d3949SYevgeny Kliteynik void mlx5dr_rule_clear_resize_info(struct mlx5dr_rule *rule) 181762fecebSYevgeny Kliteynik { 182c54d3949SYevgeny Kliteynik if (unlikely(mlx5dr_matcher_is_resizable(rule->matcher) && 183c54d3949SYevgeny Kliteynik rule->resize_info)) { 184762fecebSYevgeny Kliteynik simple_free(rule->resize_info); 185762fecebSYevgeny Kliteynik rule->resize_info = NULL; 186762fecebSYevgeny Kliteynik } 187762fecebSYevgeny Kliteynik } 188762fecebSYevgeny Kliteynik 189762fecebSYevgeny Kliteynik static void 190348cdeecSAlex Vesker mlx5dr_rule_save_delete_info(struct mlx5dr_rule *rule, 191348cdeecSAlex Vesker struct mlx5dr_send_ste_attr *ste_attr) 192348cdeecSAlex Vesker { 19360e9bf4eSErez Shitrit struct mlx5dr_match_template *mt = rule->matcher->mt; 19460e9bf4eSErez Shitrit bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); 19560e9bf4eSErez Shitrit 196348cdeecSAlex Vesker if (unlikely(mlx5dr_matcher_req_fw_wqe(rule->matcher))) { 197348cdeecSAlex Vesker uint8_t *src_tag; 198348cdeecSAlex Vesker 199348cdeecSAlex Vesker /* Save match definer id and tag for delete */ 200348cdeecSAlex Vesker rule->tag_ptr = simple_calloc(2, sizeof(*rule->tag_ptr)); 201348cdeecSAlex Vesker assert(rule->tag_ptr); 202348cdeecSAlex Vesker 2038c163b6fSErez Shitrit if (is_jumbo) 2048c163b6fSErez Shitrit memcpy(rule->tag_ptr[0].jumbo, ste_attr->wqe_data->action, 2058c163b6fSErez Shitrit MLX5DR_JUMBO_TAG_SZ); 2068c163b6fSErez Shitrit else 2078c163b6fSErez Shitrit memcpy(rule->tag_ptr[0].match, ste_attr->wqe_data->tag, 2088c163b6fSErez Shitrit MLX5DR_MATCH_TAG_SZ); 2098c163b6fSErez Shitrit 210348cdeecSAlex Vesker rule->tag_ptr[1].reserved[0] = ste_attr->send_attr.match_definer_id; 211348cdeecSAlex Vesker 212348cdeecSAlex Vesker /* Save range definer id and tag for delete */ 213348cdeecSAlex Vesker if (ste_attr->range_wqe_data) { 214348cdeecSAlex Vesker src_tag = (uint8_t *)ste_attr->range_wqe_data->tag; 215348cdeecSAlex Vesker memcpy(rule->tag_ptr[1].match, src_tag, MLX5DR_MATCH_TAG_SZ); 216348cdeecSAlex Vesker rule->tag_ptr[1].reserved[1] = ste_attr->send_attr.range_definer_id; 217348cdeecSAlex Vesker } 218348cdeecSAlex Vesker return; 219348cdeecSAlex Vesker } 220348cdeecSAlex Vesker 221762fecebSYevgeny Kliteynik if (likely(!mlx5dr_matcher_is_resizable(rule->matcher))) { 22260e9bf4eSErez Shitrit if (is_jumbo) 223762fecebSYevgeny Kliteynik memcpy(&rule->tag.jumbo, ste_attr->wqe_data->action, MLX5DR_JUMBO_TAG_SZ); 224348cdeecSAlex Vesker else 225762fecebSYevgeny Kliteynik memcpy(&rule->tag.match, ste_attr->wqe_data->tag, MLX5DR_MATCH_TAG_SZ); 226762fecebSYevgeny Kliteynik return; 227762fecebSYevgeny Kliteynik } 228348cdeecSAlex Vesker } 229348cdeecSAlex Vesker 230348cdeecSAlex Vesker static void 231348cdeecSAlex Vesker mlx5dr_rule_clear_delete_info(struct mlx5dr_rule *rule) 232348cdeecSAlex Vesker { 233762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_matcher_req_fw_wqe(rule->matcher))) { 234348cdeecSAlex Vesker simple_free(rule->tag_ptr); 235762fecebSYevgeny Kliteynik return; 236762fecebSYevgeny Kliteynik } 237348cdeecSAlex Vesker } 238348cdeecSAlex Vesker 239348cdeecSAlex Vesker static void 240348cdeecSAlex Vesker mlx5dr_rule_load_delete_info(struct mlx5dr_rule *rule, 241348cdeecSAlex Vesker struct mlx5dr_send_ste_attr *ste_attr) 242348cdeecSAlex Vesker { 243348cdeecSAlex Vesker if (unlikely(mlx5dr_matcher_req_fw_wqe(rule->matcher))) { 244348cdeecSAlex Vesker /* Load match definer id and tag for delete */ 245348cdeecSAlex Vesker ste_attr->wqe_tag = &rule->tag_ptr[0]; 246348cdeecSAlex Vesker ste_attr->send_attr.match_definer_id = rule->tag_ptr[1].reserved[0]; 247348cdeecSAlex Vesker 248348cdeecSAlex Vesker /* Load range definer id and tag for delete */ 249348cdeecSAlex Vesker if (rule->matcher->flags & MLX5DR_MATCHER_FLAGS_RANGE_DEFINER) { 250348cdeecSAlex Vesker ste_attr->range_wqe_tag = &rule->tag_ptr[1]; 251348cdeecSAlex Vesker ste_attr->send_attr.range_definer_id = rule->tag_ptr[1].reserved[1]; 252348cdeecSAlex Vesker } 253762fecebSYevgeny Kliteynik } else if (likely(!mlx5dr_matcher_is_resizable(rule->matcher))) { 254348cdeecSAlex Vesker ste_attr->wqe_tag = &rule->tag; 255762fecebSYevgeny Kliteynik } else { 256762fecebSYevgeny Kliteynik ste_attr->wqe_tag = (struct mlx5dr_rule_match_tag *) 257762fecebSYevgeny Kliteynik &rule->resize_info->data_seg[MLX5DR_STE_CTRL_SZ]; 258348cdeecSAlex Vesker } 259348cdeecSAlex Vesker } 260348cdeecSAlex Vesker 261405242c5SAlex Vesker static int mlx5dr_rule_alloc_action_ste(struct mlx5dr_rule *rule, 262405242c5SAlex Vesker struct mlx5dr_rule_attr *attr) 263405242c5SAlex Vesker { 264405242c5SAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 265405242c5SAlex Vesker int ret; 266405242c5SAlex Vesker 267405242c5SAlex Vesker /* Use rule_idx for locking optimzation, otherwise allocate from pool */ 26838b5bf64SYevgeny Kliteynik if (matcher->attr.optimize_using_rule_idx || 26938b5bf64SYevgeny Kliteynik mlx5dr_matcher_is_insert_by_idx(matcher)) { 270405242c5SAlex Vesker rule->action_ste_idx = attr->rule_idx * matcher->action_ste.max_stes; 271405242c5SAlex Vesker } else { 272405242c5SAlex Vesker struct mlx5dr_pool_chunk ste = {0}; 273405242c5SAlex Vesker 274405242c5SAlex Vesker ste.order = rte_log2_u32(matcher->action_ste.max_stes); 275405242c5SAlex Vesker ret = mlx5dr_pool_chunk_alloc(matcher->action_ste.pool, &ste); 276405242c5SAlex Vesker if (ret) { 277405242c5SAlex Vesker DR_LOG(ERR, "Failed to allocate STE for rule actions"); 278405242c5SAlex Vesker return ret; 279405242c5SAlex Vesker } 280405242c5SAlex Vesker rule->action_ste_idx = ste.offset; 281405242c5SAlex Vesker } 282405242c5SAlex Vesker return 0; 283405242c5SAlex Vesker } 284405242c5SAlex Vesker 285405242c5SAlex Vesker void mlx5dr_rule_free_action_ste_idx(struct mlx5dr_rule *rule) 286405242c5SAlex Vesker { 287405242c5SAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 288762fecebSYevgeny Kliteynik struct mlx5dr_pool *pool; 289c54d3949SYevgeny Kliteynik uint8_t max_stes; 290405242c5SAlex Vesker 29138b5bf64SYevgeny Kliteynik if (rule->action_ste_idx > -1 && 29238b5bf64SYevgeny Kliteynik !matcher->attr.optimize_using_rule_idx && 29338b5bf64SYevgeny Kliteynik !mlx5dr_matcher_is_insert_by_idx(matcher)) { 294405242c5SAlex Vesker struct mlx5dr_pool_chunk ste = {0}; 295405242c5SAlex Vesker 296c54d3949SYevgeny Kliteynik if (unlikely(mlx5dr_matcher_is_resizable(matcher))) { 297c54d3949SYevgeny Kliteynik /* Free the original action pool if rule was resized */ 298c54d3949SYevgeny Kliteynik max_stes = rule->resize_info->max_stes; 299c54d3949SYevgeny Kliteynik pool = rule->resize_info->action_ste_pool; 300c54d3949SYevgeny Kliteynik } else { 301c54d3949SYevgeny Kliteynik max_stes = matcher->action_ste.max_stes; 302c54d3949SYevgeny Kliteynik pool = matcher->action_ste.pool; 303c54d3949SYevgeny Kliteynik } 304c54d3949SYevgeny Kliteynik 305405242c5SAlex Vesker /* This release is safe only when the rule match part was deleted */ 306c54d3949SYevgeny Kliteynik ste.order = rte_log2_u32(max_stes); 307405242c5SAlex Vesker ste.offset = rule->action_ste_idx; 308762fecebSYevgeny Kliteynik 309762fecebSYevgeny Kliteynik mlx5dr_pool_chunk_free(pool, &ste); 310405242c5SAlex Vesker } 311405242c5SAlex Vesker } 312405242c5SAlex Vesker 313405242c5SAlex Vesker static void mlx5dr_rule_create_init(struct mlx5dr_rule *rule, 314405242c5SAlex Vesker struct mlx5dr_send_ste_attr *ste_attr, 315fa16feadSErez Shitrit struct mlx5dr_actions_apply_data *apply, 316fa16feadSErez Shitrit bool is_update) 317405242c5SAlex Vesker { 318405242c5SAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 319405242c5SAlex Vesker struct mlx5dr_table *tbl = matcher->tbl; 320405242c5SAlex Vesker struct mlx5dr_context *ctx = tbl->ctx; 321405242c5SAlex Vesker 322405242c5SAlex Vesker /* Init rule before reuse */ 323fa16feadSErez Shitrit if (!is_update) { 324fa16feadSErez Shitrit /* In update we use these rtc's */ 325405242c5SAlex Vesker rule->rtc_0 = 0; 326405242c5SAlex Vesker rule->rtc_1 = 0; 327fa16feadSErez Shitrit } 328fa16feadSErez Shitrit 329405242c5SAlex Vesker rule->pending_wqes = 0; 330405242c5SAlex Vesker rule->action_ste_idx = -1; 331405242c5SAlex Vesker rule->status = MLX5DR_RULE_STATUS_CREATING; 332405242c5SAlex Vesker 333405242c5SAlex Vesker /* Init default send STE attributes */ 334405242c5SAlex Vesker ste_attr->gta_opcode = MLX5DR_WQE_GTA_OP_ACTIVATE; 335405242c5SAlex Vesker ste_attr->send_attr.opmod = MLX5DR_WQE_GTA_OPMOD_STE; 336405242c5SAlex Vesker ste_attr->send_attr.opcode = MLX5DR_WQE_OPCODE_TBL_ACCESS; 337405242c5SAlex Vesker ste_attr->send_attr.len = MLX5DR_WQE_SZ_GTA_CTRL + MLX5DR_WQE_SZ_GTA_DATA; 338405242c5SAlex Vesker 339405242c5SAlex Vesker /* Init default action apply */ 340405242c5SAlex Vesker apply->tbl_type = tbl->type; 341405242c5SAlex Vesker apply->common_res = &ctx->common_res[tbl->type]; 342405242c5SAlex Vesker apply->jump_to_action_stc = matcher->action_ste.stc.offset; 343405242c5SAlex Vesker apply->require_dep = 0; 344405242c5SAlex Vesker } 345405242c5SAlex Vesker 346762fecebSYevgeny Kliteynik static void mlx5dr_rule_move_init(struct mlx5dr_rule *rule, 347762fecebSYevgeny Kliteynik struct mlx5dr_rule_attr *attr) 348762fecebSYevgeny Kliteynik { 349762fecebSYevgeny Kliteynik /* Save the old RTC IDs to be later used in match STE delete */ 350762fecebSYevgeny Kliteynik rule->resize_info->rtc_0 = rule->rtc_0; 351762fecebSYevgeny Kliteynik rule->resize_info->rtc_1 = rule->rtc_1; 352762fecebSYevgeny Kliteynik rule->resize_info->rule_idx = attr->rule_idx; 353762fecebSYevgeny Kliteynik 354762fecebSYevgeny Kliteynik rule->rtc_0 = 0; 355762fecebSYevgeny Kliteynik rule->rtc_1 = 0; 356762fecebSYevgeny Kliteynik 357762fecebSYevgeny Kliteynik rule->pending_wqes = 0; 358762fecebSYevgeny Kliteynik rule->action_ste_idx = -1; 359762fecebSYevgeny Kliteynik rule->status = MLX5DR_RULE_STATUS_CREATING; 360762fecebSYevgeny Kliteynik rule->resize_info->state = MLX5DR_RULE_RESIZE_STATE_WRITING; 361762fecebSYevgeny Kliteynik } 362762fecebSYevgeny Kliteynik 36368b34daaSYevgeny Kliteynik bool mlx5dr_rule_move_in_progress(struct mlx5dr_rule *rule) 36468b34daaSYevgeny Kliteynik { 36568b34daaSYevgeny Kliteynik return mlx5dr_matcher_is_in_resize(rule->matcher) && 36668b34daaSYevgeny Kliteynik rule->resize_info && 36768b34daaSYevgeny Kliteynik rule->resize_info->state != MLX5DR_RULE_RESIZE_STATE_IDLE; 36868b34daaSYevgeny Kliteynik } 36968b34daaSYevgeny Kliteynik 370348cdeecSAlex Vesker static int mlx5dr_rule_create_hws_fw_wqe(struct mlx5dr_rule *rule, 371348cdeecSAlex Vesker struct mlx5dr_rule_attr *attr, 372348cdeecSAlex Vesker uint8_t mt_idx, 373348cdeecSAlex Vesker const struct rte_flow_item items[], 374348cdeecSAlex Vesker uint8_t at_idx, 375348cdeecSAlex Vesker struct mlx5dr_rule_action rule_actions[]) 376348cdeecSAlex Vesker { 377348cdeecSAlex Vesker struct mlx5dr_action_template *at = &rule->matcher->at[at_idx]; 378348cdeecSAlex Vesker struct mlx5dr_match_template *mt = &rule->matcher->mt[mt_idx]; 379348cdeecSAlex Vesker struct mlx5dr_send_ring_dep_wqe range_wqe = {{0}}; 380348cdeecSAlex Vesker struct mlx5dr_send_ring_dep_wqe match_wqe = {{0}}; 381348cdeecSAlex Vesker bool is_range = mlx5dr_matcher_mt_is_range(mt); 382348cdeecSAlex Vesker bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); 383348cdeecSAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 384348cdeecSAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 385348cdeecSAlex Vesker struct mlx5dr_send_ste_attr ste_attr = {0}; 386348cdeecSAlex Vesker struct mlx5dr_actions_apply_data apply; 387348cdeecSAlex Vesker struct mlx5dr_send_engine *queue; 388348cdeecSAlex Vesker 389348cdeecSAlex Vesker queue = &ctx->send_queue[attr->queue_id]; 390348cdeecSAlex Vesker if (unlikely(mlx5dr_send_engine_err(queue))) { 391348cdeecSAlex Vesker rte_errno = EIO; 392348cdeecSAlex Vesker return rte_errno; 393348cdeecSAlex Vesker } 394348cdeecSAlex Vesker 395fa16feadSErez Shitrit mlx5dr_rule_create_init(rule, &ste_attr, &apply, false); 396e28392b3SAlex Vesker mlx5dr_rule_init_dep_wqe(&match_wqe, rule, items, mt, attr); 397e28392b3SAlex Vesker mlx5dr_rule_init_dep_wqe(&range_wqe, rule, items, mt, attr); 398348cdeecSAlex Vesker 399348cdeecSAlex Vesker ste_attr.direct_index = 0; 400348cdeecSAlex Vesker ste_attr.rtc_0 = match_wqe.rtc_0; 401348cdeecSAlex Vesker ste_attr.rtc_1 = match_wqe.rtc_1; 402348cdeecSAlex Vesker ste_attr.used_id_rtc_0 = &rule->rtc_0; 403348cdeecSAlex Vesker ste_attr.used_id_rtc_1 = &rule->rtc_1; 404348cdeecSAlex Vesker ste_attr.retry_rtc_0 = match_wqe.retry_rtc_0; 405348cdeecSAlex Vesker ste_attr.retry_rtc_1 = match_wqe.retry_rtc_1; 406348cdeecSAlex Vesker ste_attr.send_attr.rule = match_wqe.rule; 407348cdeecSAlex Vesker ste_attr.send_attr.user_data = match_wqe.user_data; 408348cdeecSAlex Vesker 409348cdeecSAlex Vesker ste_attr.send_attr.fence = 1; 410348cdeecSAlex Vesker ste_attr.send_attr.notify_hw = 1; 411348cdeecSAlex Vesker ste_attr.wqe_tag_is_jumbo = is_jumbo; 412348cdeecSAlex Vesker 413348cdeecSAlex Vesker /* Prepare match STE TAG */ 414348cdeecSAlex Vesker ste_attr.wqe_ctrl = &match_wqe.wqe_ctrl; 415348cdeecSAlex Vesker ste_attr.wqe_data = &match_wqe.wqe_data; 416348cdeecSAlex Vesker ste_attr.send_attr.match_definer_id = mlx5dr_definer_get_id(mt->definer); 417348cdeecSAlex Vesker 418348cdeecSAlex Vesker mlx5dr_definer_create_tag(items, 419348cdeecSAlex Vesker mt->fc, 420348cdeecSAlex Vesker mt->fc_sz, 421348cdeecSAlex Vesker (uint8_t *)match_wqe.wqe_data.action); 422348cdeecSAlex Vesker 423348cdeecSAlex Vesker /* Prepare range STE TAG */ 424348cdeecSAlex Vesker if (is_range) { 425348cdeecSAlex Vesker ste_attr.range_wqe_data = &range_wqe.wqe_data; 426348cdeecSAlex Vesker ste_attr.send_attr.len += MLX5DR_WQE_SZ_GTA_DATA; 427348cdeecSAlex Vesker ste_attr.send_attr.range_definer_id = mlx5dr_definer_get_id(mt->range_definer); 428348cdeecSAlex Vesker 429348cdeecSAlex Vesker mlx5dr_definer_create_tag_range(items, 430348cdeecSAlex Vesker mt->fcr, 431348cdeecSAlex Vesker mt->fcr_sz, 432348cdeecSAlex Vesker (uint8_t *)range_wqe.wqe_data.action); 433348cdeecSAlex Vesker } 434348cdeecSAlex Vesker 435348cdeecSAlex Vesker /* Apply the actions on the last STE */ 436348cdeecSAlex Vesker apply.queue = queue; 437348cdeecSAlex Vesker apply.next_direct_idx = 0; 438348cdeecSAlex Vesker apply.rule_action = rule_actions; 439348cdeecSAlex Vesker apply.wqe_ctrl = &match_wqe.wqe_ctrl; 440348cdeecSAlex Vesker apply.wqe_data = (uint32_t *)(is_range ? 441348cdeecSAlex Vesker &range_wqe.wqe_data : 442348cdeecSAlex Vesker &match_wqe.wqe_data); 443348cdeecSAlex Vesker 444348cdeecSAlex Vesker /* Skip setters[0] used for jumbo STE since not support with FW WQE */ 445348cdeecSAlex Vesker mlx5dr_action_apply_setter(&apply, &at->setters[1], 0); 446348cdeecSAlex Vesker 447348cdeecSAlex Vesker /* Send WQEs to FW */ 448348cdeecSAlex Vesker mlx5dr_send_stes_fw(queue, &ste_attr); 449348cdeecSAlex Vesker 450c54d3949SYevgeny Kliteynik /* Backup TAG on the rule for deletion */ 451348cdeecSAlex Vesker mlx5dr_rule_save_delete_info(rule, &ste_attr); 452348cdeecSAlex Vesker mlx5dr_send_engine_inc_rule(queue); 453348cdeecSAlex Vesker 454348cdeecSAlex Vesker /* Send dependent WQEs */ 455348cdeecSAlex Vesker if (!attr->burst) 456348cdeecSAlex Vesker mlx5dr_send_all_dep_wqe(queue); 457348cdeecSAlex Vesker 458348cdeecSAlex Vesker return 0; 459348cdeecSAlex Vesker } 460348cdeecSAlex Vesker 461405242c5SAlex Vesker static int mlx5dr_rule_create_hws(struct mlx5dr_rule *rule, 462405242c5SAlex Vesker struct mlx5dr_rule_attr *attr, 463405242c5SAlex Vesker uint8_t mt_idx, 464405242c5SAlex Vesker const struct rte_flow_item items[], 465405242c5SAlex Vesker uint8_t at_idx, 466405242c5SAlex Vesker struct mlx5dr_rule_action rule_actions[]) 467405242c5SAlex Vesker { 468940b0ebaSAlex Vesker struct mlx5dr_action_template *at = &rule->matcher->at[at_idx]; 469940b0ebaSAlex Vesker struct mlx5dr_match_template *mt = &rule->matcher->mt[mt_idx]; 470348cdeecSAlex Vesker bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); 471405242c5SAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 472405242c5SAlex Vesker struct mlx5dr_context *ctx = matcher->tbl->ctx; 473405242c5SAlex Vesker struct mlx5dr_send_ste_attr ste_attr = {0}; 474405242c5SAlex Vesker struct mlx5dr_send_ring_dep_wqe *dep_wqe; 475405242c5SAlex Vesker struct mlx5dr_actions_wqe_setter *setter; 476405242c5SAlex Vesker struct mlx5dr_actions_apply_data apply; 477405242c5SAlex Vesker struct mlx5dr_send_engine *queue; 478405242c5SAlex Vesker uint8_t total_stes, action_stes; 479fa16feadSErez Shitrit bool is_update; 480405242c5SAlex Vesker int i, ret; 481405242c5SAlex Vesker 482fa16feadSErez Shitrit is_update = (items == NULL); 483fa16feadSErez Shitrit 484348cdeecSAlex Vesker /* Insert rule using FW WQE if cannot use GTA WQE */ 485fa16feadSErez Shitrit if (unlikely(mlx5dr_matcher_req_fw_wqe(matcher) && !is_update)) 486348cdeecSAlex Vesker return mlx5dr_rule_create_hws_fw_wqe(rule, attr, mt_idx, items, 487348cdeecSAlex Vesker at_idx, rule_actions); 488348cdeecSAlex Vesker 489405242c5SAlex Vesker queue = &ctx->send_queue[attr->queue_id]; 490405242c5SAlex Vesker if (unlikely(mlx5dr_send_engine_err(queue))) { 491405242c5SAlex Vesker rte_errno = EIO; 492405242c5SAlex Vesker return rte_errno; 493405242c5SAlex Vesker } 494405242c5SAlex Vesker 495fa16feadSErez Shitrit mlx5dr_rule_create_init(rule, &ste_attr, &apply, is_update); 496405242c5SAlex Vesker 497405242c5SAlex Vesker /* Allocate dependent match WQE since rule might have dependent writes. 498405242c5SAlex Vesker * The queued dependent WQE can be later aborted or kept as a dependency. 499405242c5SAlex Vesker * dep_wqe buffers (ctrl, data) are also reused for all STE writes. 500405242c5SAlex Vesker */ 501405242c5SAlex Vesker dep_wqe = mlx5dr_send_add_new_dep_wqe(queue); 502e28392b3SAlex Vesker mlx5dr_rule_init_dep_wqe(dep_wqe, rule, items, mt, attr); 503405242c5SAlex Vesker 504405242c5SAlex Vesker ste_attr.wqe_ctrl = &dep_wqe->wqe_ctrl; 505405242c5SAlex Vesker ste_attr.wqe_data = &dep_wqe->wqe_data; 506405242c5SAlex Vesker apply.wqe_ctrl = &dep_wqe->wqe_ctrl; 507405242c5SAlex Vesker apply.wqe_data = (uint32_t *)&dep_wqe->wqe_data; 508405242c5SAlex Vesker apply.rule_action = rule_actions; 509405242c5SAlex Vesker apply.queue = queue; 510405242c5SAlex Vesker 511405242c5SAlex Vesker setter = &at->setters[at->num_of_action_stes]; 512405242c5SAlex Vesker total_stes = at->num_of_action_stes + (is_jumbo && !at->only_term); 513405242c5SAlex Vesker action_stes = total_stes - 1; 514405242c5SAlex Vesker 515405242c5SAlex Vesker if (action_stes) { 516405242c5SAlex Vesker /* Allocate action STEs for complex rules */ 517405242c5SAlex Vesker ret = mlx5dr_rule_alloc_action_ste(rule, attr); 518405242c5SAlex Vesker if (ret) { 519405242c5SAlex Vesker DR_LOG(ERR, "Failed to allocate action memory %d", ret); 520405242c5SAlex Vesker mlx5dr_send_abort_new_dep_wqe(queue); 521405242c5SAlex Vesker return ret; 522405242c5SAlex Vesker } 523405242c5SAlex Vesker /* Skip RX/TX based on the dep_wqe init */ 524405242c5SAlex Vesker ste_attr.rtc_0 = dep_wqe->rtc_0 ? matcher->action_ste.rtc_0->id : 0; 525405242c5SAlex Vesker ste_attr.rtc_1 = dep_wqe->rtc_1 ? matcher->action_ste.rtc_1->id : 0; 526405242c5SAlex Vesker /* Action STEs are written to a specific index last to first */ 527405242c5SAlex Vesker ste_attr.direct_index = rule->action_ste_idx + action_stes; 528405242c5SAlex Vesker apply.next_direct_idx = ste_attr.direct_index; 529405242c5SAlex Vesker } else { 530405242c5SAlex Vesker apply.next_direct_idx = 0; 531405242c5SAlex Vesker } 532405242c5SAlex Vesker 533405242c5SAlex Vesker for (i = total_stes; i-- > 0;) { 534405242c5SAlex Vesker mlx5dr_action_apply_setter(&apply, setter--, !i && is_jumbo); 535405242c5SAlex Vesker 536405242c5SAlex Vesker if (i == 0) { 53738b5bf64SYevgeny Kliteynik /* Handle last match STE. 53838b5bf64SYevgeny Kliteynik * For hash split / linear lookup RTCs, packets reaching any STE 53938b5bf64SYevgeny Kliteynik * will always match and perform the specified actions, which 54038b5bf64SYevgeny Kliteynik * makes the tag irrelevant. 54138b5bf64SYevgeny Kliteynik */ 542*486f9aacSHamdan Igbaria if (likely(!mlx5dr_matcher_is_always_hit(matcher) && !is_update)) 543405242c5SAlex Vesker mlx5dr_definer_create_tag(items, mt->fc, mt->fc_sz, 544405242c5SAlex Vesker (uint8_t *)dep_wqe->wqe_data.action); 545fa16feadSErez Shitrit else if (unlikely(is_update)) 546fa16feadSErez Shitrit mlx5dr_rule_update_copy_tag(rule, &dep_wqe->wqe_data, is_jumbo); 547405242c5SAlex Vesker 548405242c5SAlex Vesker /* Rule has dependent WQEs, match dep_wqe is queued */ 549405242c5SAlex Vesker if (action_stes || apply.require_dep) 550405242c5SAlex Vesker break; 551405242c5SAlex Vesker 552405242c5SAlex Vesker /* Rule has no dependencies, abort dep_wqe and send WQE now */ 553405242c5SAlex Vesker mlx5dr_send_abort_new_dep_wqe(queue); 554405242c5SAlex Vesker ste_attr.wqe_tag_is_jumbo = is_jumbo; 555405242c5SAlex Vesker ste_attr.send_attr.notify_hw = !attr->burst; 556405242c5SAlex Vesker ste_attr.send_attr.user_data = dep_wqe->user_data; 557405242c5SAlex Vesker ste_attr.send_attr.rule = dep_wqe->rule; 558405242c5SAlex Vesker ste_attr.rtc_0 = dep_wqe->rtc_0; 559405242c5SAlex Vesker ste_attr.rtc_1 = dep_wqe->rtc_1; 560405242c5SAlex Vesker ste_attr.used_id_rtc_0 = &rule->rtc_0; 561405242c5SAlex Vesker ste_attr.used_id_rtc_1 = &rule->rtc_1; 562405242c5SAlex Vesker ste_attr.retry_rtc_0 = dep_wqe->retry_rtc_0; 563405242c5SAlex Vesker ste_attr.retry_rtc_1 = dep_wqe->retry_rtc_1; 564e28392b3SAlex Vesker ste_attr.direct_index = dep_wqe->direct_index; 565405242c5SAlex Vesker } else { 566405242c5SAlex Vesker apply.next_direct_idx = --ste_attr.direct_index; 567405242c5SAlex Vesker } 568405242c5SAlex Vesker 569405242c5SAlex Vesker mlx5dr_send_ste(queue, &ste_attr); 570405242c5SAlex Vesker } 571405242c5SAlex Vesker 572762fecebSYevgeny Kliteynik /* Backup TAG on the rule for deletion and resize info for 573762fecebSYevgeny Kliteynik * moving rules to a new matcher, only after insertion. 574762fecebSYevgeny Kliteynik */ 575c54d3949SYevgeny Kliteynik if (!is_update) { 576348cdeecSAlex Vesker mlx5dr_rule_save_delete_info(rule, &ste_attr); 577c54d3949SYevgeny Kliteynik mlx5dr_rule_save_resize_info(rule, &ste_attr); 578c54d3949SYevgeny Kliteynik } 579fa16feadSErez Shitrit 580405242c5SAlex Vesker mlx5dr_send_engine_inc_rule(queue); 581405242c5SAlex Vesker 582405242c5SAlex Vesker /* Send dependent WQEs */ 583405242c5SAlex Vesker if (!attr->burst) 584405242c5SAlex Vesker mlx5dr_send_all_dep_wqe(queue); 585405242c5SAlex Vesker 586405242c5SAlex Vesker return 0; 587405242c5SAlex Vesker } 588405242c5SAlex Vesker 589405242c5SAlex Vesker static void mlx5dr_rule_destroy_failed_hws(struct mlx5dr_rule *rule, 590405242c5SAlex Vesker struct mlx5dr_rule_attr *attr) 591405242c5SAlex Vesker { 592405242c5SAlex Vesker struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 593405242c5SAlex Vesker struct mlx5dr_send_engine *queue; 594405242c5SAlex Vesker 595405242c5SAlex Vesker queue = &ctx->send_queue[attr->queue_id]; 596405242c5SAlex Vesker 597405242c5SAlex Vesker mlx5dr_rule_gen_comp(queue, rule, false, 598405242c5SAlex Vesker attr->user_data, MLX5DR_RULE_STATUS_DELETED); 599405242c5SAlex Vesker 600405242c5SAlex Vesker /* Rule failed now we can safely release action STEs */ 601405242c5SAlex Vesker mlx5dr_rule_free_action_ste_idx(rule); 602405242c5SAlex Vesker 603c54d3949SYevgeny Kliteynik /* Clear complex tag */ 604348cdeecSAlex Vesker mlx5dr_rule_clear_delete_info(rule); 605348cdeecSAlex Vesker 606c54d3949SYevgeny Kliteynik /* Clear info that was saved for resizing */ 607c54d3949SYevgeny Kliteynik mlx5dr_rule_clear_resize_info(rule); 608c54d3949SYevgeny Kliteynik 609405242c5SAlex Vesker /* If a rule that was indicated as burst (need to trigger HW) has failed 610405242c5SAlex Vesker * insertion we won't ring the HW as nothing is being written to the WQ. 611405242c5SAlex Vesker * In such case update the last WQE and ring the HW with that work 612405242c5SAlex Vesker */ 613405242c5SAlex Vesker if (attr->burst) 614405242c5SAlex Vesker return; 615405242c5SAlex Vesker 616405242c5SAlex Vesker mlx5dr_send_all_dep_wqe(queue); 617405242c5SAlex Vesker mlx5dr_send_engine_flush_queue(queue); 618405242c5SAlex Vesker } 619405242c5SAlex Vesker 620405242c5SAlex Vesker static int mlx5dr_rule_destroy_hws(struct mlx5dr_rule *rule, 621405242c5SAlex Vesker struct mlx5dr_rule_attr *attr) 622405242c5SAlex Vesker { 623405242c5SAlex Vesker struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 624405242c5SAlex Vesker struct mlx5dr_matcher *matcher = rule->matcher; 625348cdeecSAlex Vesker bool fw_wqe = mlx5dr_matcher_req_fw_wqe(matcher); 626348cdeecSAlex Vesker bool is_range = mlx5dr_matcher_mt_is_range(matcher->mt); 627348cdeecSAlex Vesker bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(matcher->mt); 628405242c5SAlex Vesker struct mlx5dr_wqe_gta_ctrl_seg wqe_ctrl = {0}; 629405242c5SAlex Vesker struct mlx5dr_send_ste_attr ste_attr = {0}; 630405242c5SAlex Vesker struct mlx5dr_send_engine *queue; 631405242c5SAlex Vesker 632405242c5SAlex Vesker queue = &ctx->send_queue[attr->queue_id]; 633405242c5SAlex Vesker 634938646d9SAlex Vesker if (unlikely(mlx5dr_send_engine_err(queue))) { 635938646d9SAlex Vesker mlx5dr_rule_destroy_failed_hws(rule, attr); 636938646d9SAlex Vesker return 0; 637938646d9SAlex Vesker } 638938646d9SAlex Vesker 639405242c5SAlex Vesker /* Rule is not completed yet */ 640405242c5SAlex Vesker if (rule->status == MLX5DR_RULE_STATUS_CREATING) { 6410573a392SGavin Li DR_LOG(NOTICE, "Cannot destroy, rule creation still in progress"); 642405242c5SAlex Vesker rte_errno = EBUSY; 643405242c5SAlex Vesker return rte_errno; 644405242c5SAlex Vesker } 645405242c5SAlex Vesker 646405242c5SAlex Vesker /* Rule failed and doesn't require cleanup */ 647405242c5SAlex Vesker if (rule->status == MLX5DR_RULE_STATUS_FAILED) { 648405242c5SAlex Vesker mlx5dr_rule_destroy_failed_hws(rule, attr); 649405242c5SAlex Vesker return 0; 650405242c5SAlex Vesker } 651405242c5SAlex Vesker 652405242c5SAlex Vesker mlx5dr_send_engine_inc_rule(queue); 653405242c5SAlex Vesker 654405242c5SAlex Vesker /* Send dependent WQE */ 655405242c5SAlex Vesker if (!attr->burst) 656405242c5SAlex Vesker mlx5dr_send_all_dep_wqe(queue); 657405242c5SAlex Vesker 658405242c5SAlex Vesker rule->status = MLX5DR_RULE_STATUS_DELETING; 659405242c5SAlex Vesker 660405242c5SAlex Vesker ste_attr.send_attr.opmod = MLX5DR_WQE_GTA_OPMOD_STE; 661405242c5SAlex Vesker ste_attr.send_attr.opcode = MLX5DR_WQE_OPCODE_TBL_ACCESS; 662405242c5SAlex Vesker ste_attr.send_attr.len = MLX5DR_WQE_SZ_GTA_CTRL + MLX5DR_WQE_SZ_GTA_DATA; 663348cdeecSAlex Vesker if (unlikely(is_range)) 664348cdeecSAlex Vesker ste_attr.send_attr.len += MLX5DR_WQE_SZ_GTA_DATA; 665405242c5SAlex Vesker 666405242c5SAlex Vesker ste_attr.send_attr.rule = rule; 667405242c5SAlex Vesker ste_attr.send_attr.notify_hw = !attr->burst; 668405242c5SAlex Vesker ste_attr.send_attr.user_data = attr->user_data; 669405242c5SAlex Vesker 670405242c5SAlex Vesker ste_attr.rtc_0 = rule->rtc_0; 671405242c5SAlex Vesker ste_attr.rtc_1 = rule->rtc_1; 672405242c5SAlex Vesker ste_attr.used_id_rtc_0 = &rule->rtc_0; 673405242c5SAlex Vesker ste_attr.used_id_rtc_1 = &rule->rtc_1; 674405242c5SAlex Vesker ste_attr.wqe_ctrl = &wqe_ctrl; 675348cdeecSAlex Vesker ste_attr.wqe_tag_is_jumbo = is_jumbo; 676405242c5SAlex Vesker ste_attr.gta_opcode = MLX5DR_WQE_GTA_OP_DEACTIVATE; 67738b5bf64SYevgeny Kliteynik if (unlikely(mlx5dr_matcher_is_insert_by_idx(matcher))) 67838b5bf64SYevgeny Kliteynik ste_attr.direct_index = attr->rule_idx; 679405242c5SAlex Vesker 680348cdeecSAlex Vesker mlx5dr_rule_load_delete_info(rule, &ste_attr); 681348cdeecSAlex Vesker 682762fecebSYevgeny Kliteynik if (unlikely(fw_wqe)) 683348cdeecSAlex Vesker mlx5dr_send_stes_fw(queue, &ste_attr); 684762fecebSYevgeny Kliteynik else 685405242c5SAlex Vesker mlx5dr_send_ste(queue, &ste_attr); 686762fecebSYevgeny Kliteynik 687762fecebSYevgeny Kliteynik mlx5dr_rule_clear_delete_info(rule); 688405242c5SAlex Vesker 689405242c5SAlex Vesker return 0; 690405242c5SAlex Vesker } 691405242c5SAlex Vesker 692fcee5d78SYevgeny Kliteynik int mlx5dr_rule_create_root_no_comp(struct mlx5dr_rule *rule, 693405242c5SAlex Vesker const struct rte_flow_item items[], 694fcee5d78SYevgeny Kliteynik uint8_t num_actions, 695405242c5SAlex Vesker struct mlx5dr_rule_action rule_actions[]) 696405242c5SAlex Vesker { 697405242c5SAlex Vesker struct mlx5dv_flow_matcher *dv_matcher = rule->matcher->dv_matcher; 698befb138bSAlex Vesker struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 699405242c5SAlex Vesker struct mlx5dv_flow_match_parameters *value; 700405242c5SAlex Vesker struct mlx5_flow_attr flow_attr = {0}; 701405242c5SAlex Vesker struct mlx5dv_flow_action_attr *attr; 702405242c5SAlex Vesker struct rte_flow_error error; 703405242c5SAlex Vesker uint8_t match_criteria; 704405242c5SAlex Vesker int ret; 705405242c5SAlex Vesker 706befb138bSAlex Vesker ret = flow_hw_get_port_id_from_ctx(ctx, &flow_attr.port_id); 707572fe9efSErez Shitrit if (ret) { 708befb138bSAlex Vesker DR_LOG(ERR, "Failed to get port id for dev %s", ctx->ibv_ctx->device->name); 709572fe9efSErez Shitrit rte_errno = EINVAL; 710572fe9efSErez Shitrit return rte_errno; 711572fe9efSErez Shitrit } 712572fe9efSErez Shitrit 713405242c5SAlex Vesker attr = simple_calloc(num_actions, sizeof(*attr)); 714405242c5SAlex Vesker if (!attr) { 715405242c5SAlex Vesker rte_errno = ENOMEM; 716405242c5SAlex Vesker return rte_errno; 717405242c5SAlex Vesker } 718405242c5SAlex Vesker 719405242c5SAlex Vesker value = simple_calloc(1, MLX5_ST_SZ_BYTES(fte_match_param) + 720405242c5SAlex Vesker offsetof(struct mlx5dv_flow_match_parameters, match_buf)); 721405242c5SAlex Vesker if (!value) { 722405242c5SAlex Vesker rte_errno = ENOMEM; 723405242c5SAlex Vesker goto free_attr; 724405242c5SAlex Vesker } 725405242c5SAlex Vesker 726405242c5SAlex Vesker flow_attr.tbl_type = rule->matcher->tbl->type; 727405242c5SAlex Vesker 728405242c5SAlex Vesker ret = flow_dv_translate_items_hws(items, &flow_attr, value->match_buf, 729405242c5SAlex Vesker MLX5_SET_MATCHER_HS_V, NULL, 730405242c5SAlex Vesker &match_criteria, 731405242c5SAlex Vesker &error); 732405242c5SAlex Vesker if (ret) { 733405242c5SAlex Vesker DR_LOG(ERR, "Failed to convert items to PRM [%s]", error.message); 734405242c5SAlex Vesker goto free_value; 735405242c5SAlex Vesker } 736405242c5SAlex Vesker 737405242c5SAlex Vesker /* Convert actions to verb action attr */ 738405242c5SAlex Vesker ret = mlx5dr_action_root_build_attr(rule_actions, num_actions, attr); 739405242c5SAlex Vesker if (ret) 740405242c5SAlex Vesker goto free_value; 741405242c5SAlex Vesker 742405242c5SAlex Vesker /* Create verb flow */ 743405242c5SAlex Vesker value->match_sz = MLX5_ST_SZ_BYTES(fte_match_param); 744405242c5SAlex Vesker rule->flow = mlx5_glue->dv_create_flow_root(dv_matcher, 745405242c5SAlex Vesker value, 746405242c5SAlex Vesker num_actions, 747405242c5SAlex Vesker attr); 748405242c5SAlex Vesker 749405242c5SAlex Vesker simple_free(value); 750405242c5SAlex Vesker simple_free(attr); 751405242c5SAlex Vesker 752405242c5SAlex Vesker return 0; 753405242c5SAlex Vesker 754405242c5SAlex Vesker free_value: 755405242c5SAlex Vesker simple_free(value); 756405242c5SAlex Vesker free_attr: 757405242c5SAlex Vesker simple_free(attr); 758405242c5SAlex Vesker 759ba2c2679SYevgeny Kliteynik return rte_errno; 760405242c5SAlex Vesker } 761405242c5SAlex Vesker 762fcee5d78SYevgeny Kliteynik static int mlx5dr_rule_create_root(struct mlx5dr_rule *rule, 763fcee5d78SYevgeny Kliteynik struct mlx5dr_rule_attr *rule_attr, 764fcee5d78SYevgeny Kliteynik const struct rte_flow_item items[], 765fcee5d78SYevgeny Kliteynik uint8_t num_actions, 766fcee5d78SYevgeny Kliteynik struct mlx5dr_rule_action rule_actions[]) 767fcee5d78SYevgeny Kliteynik { 768fcee5d78SYevgeny Kliteynik struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 769fcee5d78SYevgeny Kliteynik int ret; 770fcee5d78SYevgeny Kliteynik 771fcee5d78SYevgeny Kliteynik ret = mlx5dr_rule_create_root_no_comp(rule, items, 772fcee5d78SYevgeny Kliteynik num_actions, rule_actions); 773fcee5d78SYevgeny Kliteynik if (ret) 774fcee5d78SYevgeny Kliteynik return rte_errno; 775fcee5d78SYevgeny Kliteynik 776fcee5d78SYevgeny Kliteynik mlx5dr_rule_gen_comp(&ctx->send_queue[rule_attr->queue_id], rule, !rule->flow, 777fcee5d78SYevgeny Kliteynik rule_attr->user_data, MLX5DR_RULE_STATUS_CREATED); 778fcee5d78SYevgeny Kliteynik 779fcee5d78SYevgeny Kliteynik return 0; 780fcee5d78SYevgeny Kliteynik } 781fcee5d78SYevgeny Kliteynik 782fcee5d78SYevgeny Kliteynik int mlx5dr_rule_destroy_root_no_comp(struct mlx5dr_rule *rule) 783fcee5d78SYevgeny Kliteynik { 784fcee5d78SYevgeny Kliteynik if (rule->flow) 785fcee5d78SYevgeny Kliteynik return ibv_destroy_flow(rule->flow); 786fcee5d78SYevgeny Kliteynik 787fcee5d78SYevgeny Kliteynik return 0; 788fcee5d78SYevgeny Kliteynik } 789fcee5d78SYevgeny Kliteynik 790405242c5SAlex Vesker static int mlx5dr_rule_destroy_root(struct mlx5dr_rule *rule, 791405242c5SAlex Vesker struct mlx5dr_rule_attr *attr) 792405242c5SAlex Vesker { 793405242c5SAlex Vesker struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 794fcee5d78SYevgeny Kliteynik int err; 795405242c5SAlex Vesker 796fcee5d78SYevgeny Kliteynik err = mlx5dr_rule_destroy_root_no_comp(rule); 797405242c5SAlex Vesker 798405242c5SAlex Vesker mlx5dr_rule_gen_comp(&ctx->send_queue[attr->queue_id], rule, err, 799405242c5SAlex Vesker attr->user_data, MLX5DR_RULE_STATUS_DELETED); 800405242c5SAlex Vesker 801405242c5SAlex Vesker return 0; 802405242c5SAlex Vesker } 803405242c5SAlex Vesker 804762fecebSYevgeny Kliteynik static int mlx5dr_rule_enqueue_precheck(struct mlx5dr_rule *rule, 80580f28422SErez Shitrit struct mlx5dr_rule_attr *attr) 80680f28422SErez Shitrit { 807762fecebSYevgeny Kliteynik struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 808762fecebSYevgeny Kliteynik 80980f28422SErez Shitrit if (unlikely(!attr->user_data)) { 8100573a392SGavin Li DR_LOG(DEBUG, "User data must be provided for rule operations"); 81180f28422SErez Shitrit rte_errno = EINVAL; 81280f28422SErez Shitrit return rte_errno; 81380f28422SErez Shitrit } 81480f28422SErez Shitrit 81580f28422SErez Shitrit /* Check if there is room in queue */ 81680f28422SErez Shitrit if (unlikely(mlx5dr_send_engine_full(&ctx->send_queue[attr->queue_id]))) { 8170573a392SGavin Li DR_LOG(NOTICE, "No room in queue[%d]", attr->queue_id); 81880f28422SErez Shitrit rte_errno = EBUSY; 81980f28422SErez Shitrit return rte_errno; 82080f28422SErez Shitrit } 82180f28422SErez Shitrit 82280f28422SErez Shitrit return 0; 82380f28422SErez Shitrit } 82480f28422SErez Shitrit 825762fecebSYevgeny Kliteynik static int mlx5dr_rule_enqueue_precheck_move(struct mlx5dr_rule *rule, 826762fecebSYevgeny Kliteynik struct mlx5dr_rule_attr *attr) 827762fecebSYevgeny Kliteynik { 828762fecebSYevgeny Kliteynik if (unlikely(rule->status != MLX5DR_RULE_STATUS_CREATED)) { 8290573a392SGavin Li DR_LOG(DEBUG, "Cannot move, rule status is invalid"); 830762fecebSYevgeny Kliteynik rte_errno = EINVAL; 831762fecebSYevgeny Kliteynik return rte_errno; 832762fecebSYevgeny Kliteynik } 833762fecebSYevgeny Kliteynik 834762fecebSYevgeny Kliteynik return mlx5dr_rule_enqueue_precheck(rule, attr); 835762fecebSYevgeny Kliteynik } 836762fecebSYevgeny Kliteynik 837762fecebSYevgeny Kliteynik static int mlx5dr_rule_enqueue_precheck_create(struct mlx5dr_rule *rule, 838762fecebSYevgeny Kliteynik struct mlx5dr_rule_attr *attr) 839762fecebSYevgeny Kliteynik { 840762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_matcher_is_in_resize(rule->matcher))) { 841762fecebSYevgeny Kliteynik /* Matcher in resize - new rules are not allowed */ 8420573a392SGavin Li DR_LOG(NOTICE, "Resizing in progress, cannot create rule"); 843762fecebSYevgeny Kliteynik rte_errno = EAGAIN; 844762fecebSYevgeny Kliteynik return rte_errno; 845762fecebSYevgeny Kliteynik } 846762fecebSYevgeny Kliteynik 847762fecebSYevgeny Kliteynik return mlx5dr_rule_enqueue_precheck(rule, attr); 848762fecebSYevgeny Kliteynik } 849762fecebSYevgeny Kliteynik 850762fecebSYevgeny Kliteynik static int mlx5dr_rule_enqueue_precheck_update(struct mlx5dr_rule *rule, 851762fecebSYevgeny Kliteynik struct mlx5dr_rule_attr *attr) 852762fecebSYevgeny Kliteynik { 853762fecebSYevgeny Kliteynik struct mlx5dr_matcher *matcher = rule->matcher; 854762fecebSYevgeny Kliteynik 855762fecebSYevgeny Kliteynik if (unlikely((mlx5dr_table_is_root(matcher->tbl) || 856762fecebSYevgeny Kliteynik mlx5dr_matcher_req_fw_wqe(matcher)))) { 857762fecebSYevgeny Kliteynik DR_LOG(ERR, "Rule update is not supported on current matcher"); 858762fecebSYevgeny Kliteynik rte_errno = ENOTSUP; 859762fecebSYevgeny Kliteynik return rte_errno; 860762fecebSYevgeny Kliteynik } 861762fecebSYevgeny Kliteynik 862762fecebSYevgeny Kliteynik if (unlikely(!matcher->attr.optimize_using_rule_idx && 863762fecebSYevgeny Kliteynik !mlx5dr_matcher_is_insert_by_idx(matcher))) { 864762fecebSYevgeny Kliteynik DR_LOG(ERR, "Rule update requires optimize by idx matcher"); 865762fecebSYevgeny Kliteynik rte_errno = ENOTSUP; 866762fecebSYevgeny Kliteynik return rte_errno; 867762fecebSYevgeny Kliteynik } 868762fecebSYevgeny Kliteynik 869762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_matcher_is_resizable(rule->matcher))) { 870762fecebSYevgeny Kliteynik DR_LOG(ERR, "Rule update is not supported on resizable matcher"); 871762fecebSYevgeny Kliteynik rte_errno = ENOTSUP; 872762fecebSYevgeny Kliteynik return rte_errno; 873762fecebSYevgeny Kliteynik } 874762fecebSYevgeny Kliteynik 875762fecebSYevgeny Kliteynik if (unlikely(rule->status != MLX5DR_RULE_STATUS_CREATED)) { 876762fecebSYevgeny Kliteynik DR_LOG(ERR, "Current rule status does not allow update"); 877762fecebSYevgeny Kliteynik rte_errno = EBUSY; 878762fecebSYevgeny Kliteynik return rte_errno; 879762fecebSYevgeny Kliteynik } 880762fecebSYevgeny Kliteynik 881762fecebSYevgeny Kliteynik return mlx5dr_rule_enqueue_precheck_create(rule, attr); 882762fecebSYevgeny Kliteynik } 883762fecebSYevgeny Kliteynik 884762fecebSYevgeny Kliteynik int mlx5dr_rule_move_hws_remove(struct mlx5dr_rule *rule, 885762fecebSYevgeny Kliteynik void *queue_ptr, 886762fecebSYevgeny Kliteynik void *user_data) 887762fecebSYevgeny Kliteynik { 888762fecebSYevgeny Kliteynik bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(rule->matcher->mt); 889762fecebSYevgeny Kliteynik struct mlx5dr_wqe_gta_ctrl_seg empty_wqe_ctrl = {0}; 890762fecebSYevgeny Kliteynik struct mlx5dr_matcher *matcher = rule->matcher; 891762fecebSYevgeny Kliteynik struct mlx5dr_send_engine *queue = queue_ptr; 892762fecebSYevgeny Kliteynik struct mlx5dr_send_ste_attr ste_attr = {0}; 893762fecebSYevgeny Kliteynik 894762fecebSYevgeny Kliteynik /* Send dependent WQEs */ 895762fecebSYevgeny Kliteynik mlx5dr_send_all_dep_wqe(queue); 896762fecebSYevgeny Kliteynik 897762fecebSYevgeny Kliteynik rule->resize_info->state = MLX5DR_RULE_RESIZE_STATE_DELETING; 898762fecebSYevgeny Kliteynik 899762fecebSYevgeny Kliteynik ste_attr.send_attr.fence = 0; 900762fecebSYevgeny Kliteynik ste_attr.send_attr.opmod = MLX5DR_WQE_GTA_OPMOD_STE; 901762fecebSYevgeny Kliteynik ste_attr.send_attr.opcode = MLX5DR_WQE_OPCODE_TBL_ACCESS; 902762fecebSYevgeny Kliteynik ste_attr.send_attr.len = MLX5DR_WQE_SZ_GTA_CTRL + MLX5DR_WQE_SZ_GTA_DATA; 903762fecebSYevgeny Kliteynik ste_attr.send_attr.rule = rule; 904762fecebSYevgeny Kliteynik ste_attr.send_attr.notify_hw = 1; 905762fecebSYevgeny Kliteynik ste_attr.send_attr.user_data = user_data; 906762fecebSYevgeny Kliteynik ste_attr.rtc_0 = rule->resize_info->rtc_0; 907762fecebSYevgeny Kliteynik ste_attr.rtc_1 = rule->resize_info->rtc_1; 908762fecebSYevgeny Kliteynik ste_attr.used_id_rtc_0 = &rule->resize_info->rtc_0; 909762fecebSYevgeny Kliteynik ste_attr.used_id_rtc_1 = &rule->resize_info->rtc_1; 910762fecebSYevgeny Kliteynik ste_attr.wqe_ctrl = &empty_wqe_ctrl; 911762fecebSYevgeny Kliteynik ste_attr.wqe_tag_is_jumbo = is_jumbo; 912762fecebSYevgeny Kliteynik ste_attr.gta_opcode = MLX5DR_WQE_GTA_OP_DEACTIVATE; 913762fecebSYevgeny Kliteynik 914762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_matcher_is_insert_by_idx(matcher))) 915762fecebSYevgeny Kliteynik ste_attr.direct_index = rule->resize_info->rule_idx; 916762fecebSYevgeny Kliteynik 917762fecebSYevgeny Kliteynik mlx5dr_rule_load_delete_info(rule, &ste_attr); 918762fecebSYevgeny Kliteynik mlx5dr_send_ste(queue, &ste_attr); 919762fecebSYevgeny Kliteynik 920762fecebSYevgeny Kliteynik return 0; 921762fecebSYevgeny Kliteynik } 922762fecebSYevgeny Kliteynik 923762fecebSYevgeny Kliteynik int mlx5dr_rule_move_hws_add(struct mlx5dr_rule *rule, 924762fecebSYevgeny Kliteynik struct mlx5dr_rule_attr *attr) 925762fecebSYevgeny Kliteynik { 926762fecebSYevgeny Kliteynik bool is_jumbo = mlx5dr_matcher_mt_is_jumbo(rule->matcher->mt); 927762fecebSYevgeny Kliteynik struct mlx5dr_context *ctx = rule->matcher->tbl->ctx; 928762fecebSYevgeny Kliteynik struct mlx5dr_matcher *matcher = rule->matcher; 929762fecebSYevgeny Kliteynik struct mlx5dr_send_ste_attr ste_attr = {0}; 930762fecebSYevgeny Kliteynik struct mlx5dr_send_engine *queue; 931762fecebSYevgeny Kliteynik 932762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_rule_enqueue_precheck_move(rule, attr))) 933762fecebSYevgeny Kliteynik return -rte_errno; 934762fecebSYevgeny Kliteynik 935762fecebSYevgeny Kliteynik queue = &ctx->send_queue[attr->queue_id]; 936762fecebSYevgeny Kliteynik 937762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_send_engine_err(queue))) { 938762fecebSYevgeny Kliteynik rte_errno = EIO; 939762fecebSYevgeny Kliteynik return rte_errno; 940762fecebSYevgeny Kliteynik } 941762fecebSYevgeny Kliteynik 942762fecebSYevgeny Kliteynik mlx5dr_rule_move_init(rule, attr); 943762fecebSYevgeny Kliteynik 944762fecebSYevgeny Kliteynik mlx5dr_rule_move_get_rtc(rule, &ste_attr); 945762fecebSYevgeny Kliteynik 946762fecebSYevgeny Kliteynik ste_attr.send_attr.opmod = MLX5DR_WQE_GTA_OPMOD_STE; 947762fecebSYevgeny Kliteynik ste_attr.send_attr.opcode = MLX5DR_WQE_OPCODE_TBL_ACCESS; 948762fecebSYevgeny Kliteynik ste_attr.send_attr.len = MLX5DR_WQE_SZ_GTA_CTRL + MLX5DR_WQE_SZ_GTA_DATA; 949762fecebSYevgeny Kliteynik ste_attr.gta_opcode = MLX5DR_WQE_GTA_OP_ACTIVATE; 950762fecebSYevgeny Kliteynik ste_attr.wqe_tag_is_jumbo = is_jumbo; 951762fecebSYevgeny Kliteynik 952762fecebSYevgeny Kliteynik ste_attr.send_attr.rule = rule; 953762fecebSYevgeny Kliteynik ste_attr.send_attr.fence = 0; 954762fecebSYevgeny Kliteynik ste_attr.send_attr.notify_hw = !attr->burst; 955762fecebSYevgeny Kliteynik ste_attr.send_attr.user_data = attr->user_data; 956762fecebSYevgeny Kliteynik 957762fecebSYevgeny Kliteynik ste_attr.used_id_rtc_0 = &rule->rtc_0; 958762fecebSYevgeny Kliteynik ste_attr.used_id_rtc_1 = &rule->rtc_1; 959762fecebSYevgeny Kliteynik ste_attr.wqe_ctrl = (struct mlx5dr_wqe_gta_ctrl_seg *)rule->resize_info->ctrl_seg; 960762fecebSYevgeny Kliteynik ste_attr.wqe_data = (struct mlx5dr_wqe_gta_data_seg_ste *)rule->resize_info->data_seg; 961762fecebSYevgeny Kliteynik ste_attr.direct_index = mlx5dr_matcher_is_insert_by_idx(matcher) ? 962762fecebSYevgeny Kliteynik attr->rule_idx : 0; 963762fecebSYevgeny Kliteynik 964762fecebSYevgeny Kliteynik mlx5dr_send_ste(queue, &ste_attr); 965762fecebSYevgeny Kliteynik mlx5dr_send_engine_inc_rule(queue); 966762fecebSYevgeny Kliteynik 967762fecebSYevgeny Kliteynik /* Send dependent WQEs */ 968762fecebSYevgeny Kliteynik if (!attr->burst) 969762fecebSYevgeny Kliteynik mlx5dr_send_all_dep_wqe(queue); 970762fecebSYevgeny Kliteynik 971762fecebSYevgeny Kliteynik return 0; 972762fecebSYevgeny Kliteynik } 973762fecebSYevgeny Kliteynik 974405242c5SAlex Vesker int mlx5dr_rule_create(struct mlx5dr_matcher *matcher, 975405242c5SAlex Vesker uint8_t mt_idx, 976405242c5SAlex Vesker const struct rte_flow_item items[], 977405242c5SAlex Vesker uint8_t at_idx, 978405242c5SAlex Vesker struct mlx5dr_rule_action rule_actions[], 979405242c5SAlex Vesker struct mlx5dr_rule_attr *attr, 980405242c5SAlex Vesker struct mlx5dr_rule *rule_handle) 981405242c5SAlex Vesker { 982405242c5SAlex Vesker int ret; 983405242c5SAlex Vesker 984405242c5SAlex Vesker rule_handle->matcher = matcher; 985405242c5SAlex Vesker 986762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_rule_enqueue_precheck_create(rule_handle, attr))) 987405242c5SAlex Vesker return -rte_errno; 988405242c5SAlex Vesker 989405242c5SAlex Vesker assert(matcher->num_of_mt >= mt_idx); 990405242c5SAlex Vesker assert(matcher->num_of_at >= at_idx); 991fa16feadSErez Shitrit assert(items); 992405242c5SAlex Vesker 993405242c5SAlex Vesker if (unlikely(mlx5dr_table_is_root(matcher->tbl))) 994405242c5SAlex Vesker ret = mlx5dr_rule_create_root(rule_handle, 995405242c5SAlex Vesker attr, 996405242c5SAlex Vesker items, 997fcee5d78SYevgeny Kliteynik matcher->at[at_idx].num_actions, 998405242c5SAlex Vesker rule_actions); 999405242c5SAlex Vesker else 1000405242c5SAlex Vesker ret = mlx5dr_rule_create_hws(rule_handle, 1001405242c5SAlex Vesker attr, 1002405242c5SAlex Vesker mt_idx, 1003405242c5SAlex Vesker items, 1004405242c5SAlex Vesker at_idx, 1005405242c5SAlex Vesker rule_actions); 1006405242c5SAlex Vesker return -ret; 1007405242c5SAlex Vesker } 1008405242c5SAlex Vesker 1009405242c5SAlex Vesker int mlx5dr_rule_destroy(struct mlx5dr_rule *rule, 1010405242c5SAlex Vesker struct mlx5dr_rule_attr *attr) 1011405242c5SAlex Vesker { 1012405242c5SAlex Vesker int ret; 1013405242c5SAlex Vesker 1014762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_rule_enqueue_precheck(rule, attr))) 1015405242c5SAlex Vesker return -rte_errno; 1016405242c5SAlex Vesker 1017405242c5SAlex Vesker if (unlikely(mlx5dr_table_is_root(rule->matcher->tbl))) 1018405242c5SAlex Vesker ret = mlx5dr_rule_destroy_root(rule, attr); 1019405242c5SAlex Vesker else 1020405242c5SAlex Vesker ret = mlx5dr_rule_destroy_hws(rule, attr); 1021405242c5SAlex Vesker 1022405242c5SAlex Vesker return -ret; 1023405242c5SAlex Vesker } 1024405242c5SAlex Vesker 1025fa16feadSErez Shitrit int mlx5dr_rule_action_update(struct mlx5dr_rule *rule_handle, 1026fa16feadSErez Shitrit uint8_t at_idx, 1027fa16feadSErez Shitrit struct mlx5dr_rule_action rule_actions[], 1028fa16feadSErez Shitrit struct mlx5dr_rule_attr *attr) 1029fa16feadSErez Shitrit { 1030fa16feadSErez Shitrit int ret; 1031fa16feadSErez Shitrit 1032762fecebSYevgeny Kliteynik if (unlikely(mlx5dr_rule_enqueue_precheck_update(rule_handle, attr))) 1033fa16feadSErez Shitrit return -rte_errno; 1034fa16feadSErez Shitrit 1035e7594a81SHamdan Igbaria if (rule_handle->status != MLX5DR_RULE_STATUS_CREATED) { 1036e7594a81SHamdan Igbaria DR_LOG(ERR, "Current rule status does not allow update"); 1037e7594a81SHamdan Igbaria rte_errno = EBUSY; 1038e7594a81SHamdan Igbaria return -rte_errno; 1039e7594a81SHamdan Igbaria } 1040e7594a81SHamdan Igbaria 1041fa16feadSErez Shitrit ret = mlx5dr_rule_create_hws(rule_handle, 1042fa16feadSErez Shitrit attr, 1043fa16feadSErez Shitrit 0, 1044fa16feadSErez Shitrit NULL, 1045fa16feadSErez Shitrit at_idx, 1046fa16feadSErez Shitrit rule_actions); 1047fa16feadSErez Shitrit 1048fa16feadSErez Shitrit return -ret; 1049fa16feadSErez Shitrit } 1050fa16feadSErez Shitrit 1051405242c5SAlex Vesker size_t mlx5dr_rule_get_handle_size(void) 1052405242c5SAlex Vesker { 1053405242c5SAlex Vesker return sizeof(struct mlx5dr_rule); 1054405242c5SAlex Vesker } 10557f5e6de5SItamar Gozlan 10567f5e6de5SItamar Gozlan int mlx5dr_rule_hash_calculate(struct mlx5dr_matcher *matcher, 10577f5e6de5SItamar Gozlan const struct rte_flow_item items[], 10587f5e6de5SItamar Gozlan uint8_t mt_idx, 10597f5e6de5SItamar Gozlan enum mlx5dr_rule_hash_calc_mode mode, 10607f5e6de5SItamar Gozlan uint32_t *ret_hash) 10617f5e6de5SItamar Gozlan { 1062762fecebSYevgeny Kliteynik uint8_t tag[MLX5DR_WQE_SZ_GTA_DATA] = {0}; 10637f5e6de5SItamar Gozlan struct mlx5dr_match_template *mt; 10647f5e6de5SItamar Gozlan 10657f5e6de5SItamar Gozlan if (!matcher || !matcher->mt) { 10667f5e6de5SItamar Gozlan rte_errno = EINVAL; 10677f5e6de5SItamar Gozlan return -rte_errno; 10687f5e6de5SItamar Gozlan } 10697f5e6de5SItamar Gozlan 10707f5e6de5SItamar Gozlan mt = &matcher->mt[mt_idx]; 10717f5e6de5SItamar Gozlan 10727f5e6de5SItamar Gozlan if (mlx5dr_matcher_req_fw_wqe(matcher) || 10737f5e6de5SItamar Gozlan mlx5dr_table_is_root(matcher->tbl) || 10747f5e6de5SItamar Gozlan matcher->tbl->ctx->caps->access_index_mode == MLX5DR_MATCHER_INSERT_BY_HASH || 10757f5e6de5SItamar Gozlan matcher->tbl->ctx->caps->flow_table_hash_type != MLX5_FLOW_TABLE_HASH_TYPE_CRC32) { 10760573a392SGavin Li DR_LOG(DEBUG, "Matcher is not supported"); 10777f5e6de5SItamar Gozlan rte_errno = ENOTSUP; 10787f5e6de5SItamar Gozlan return -rte_errno; 10797f5e6de5SItamar Gozlan } 10807f5e6de5SItamar Gozlan 10817f5e6de5SItamar Gozlan mlx5dr_definer_create_tag(items, mt->fc, mt->fc_sz, tag); 10827f5e6de5SItamar Gozlan if (mlx5dr_matcher_mt_is_jumbo(mt)) 10837f5e6de5SItamar Gozlan *ret_hash = mlx5dr_crc32_calc(tag, MLX5DR_JUMBO_TAG_SZ); 10847f5e6de5SItamar Gozlan else 10857f5e6de5SItamar Gozlan *ret_hash = mlx5dr_crc32_calc(tag + MLX5DR_ACTIONS_SZ, 10867f5e6de5SItamar Gozlan MLX5DR_MATCH_TAG_SZ); 10877f5e6de5SItamar Gozlan 10887f5e6de5SItamar Gozlan if (mode == MLX5DR_RULE_HASH_CALC_MODE_IDX) 10897f5e6de5SItamar Gozlan *ret_hash = *ret_hash & (BIT(matcher->attr.rule.num_log) - 1); 10907f5e6de5SItamar Gozlan 10917f5e6de5SItamar Gozlan return 0; 10927f5e6de5SItamar Gozlan } 1093