1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2022 NVIDIA Corporation & Affiliates 3 */ 4 5 #ifndef MLX5DR_ACTION_H_ 6 #define MLX5DR_ACTION_H_ 7 8 /* Max number of STEs needed for a rule (including match) */ 9 #define MLX5DR_ACTION_MAX_STE 20 10 11 /* Max number of internal subactions of ipv6_ext */ 12 #define MLX5DR_ACTION_IPV6_EXT_MAX_SA 4 13 14 enum mlx5dr_action_stc_idx { 15 MLX5DR_ACTION_STC_IDX_CTRL = 0, 16 MLX5DR_ACTION_STC_IDX_HIT = 1, 17 MLX5DR_ACTION_STC_IDX_DW5 = 2, 18 MLX5DR_ACTION_STC_IDX_DW6 = 3, 19 MLX5DR_ACTION_STC_IDX_DW7 = 4, 20 MLX5DR_ACTION_STC_IDX_MAX = 5, 21 /* STC Jumvo STE combo: CTR, Hit */ 22 MLX5DR_ACTION_STC_IDX_LAST_JUMBO_STE = 1, 23 /* STC combo1: CTR, SINGLE, DOUBLE, Hit */ 24 MLX5DR_ACTION_STC_IDX_LAST_COMBO1 = 3, 25 /* STC combo2: CTR, 3 x SINGLE, Hit */ 26 MLX5DR_ACTION_STC_IDX_LAST_COMBO2 = 4, 27 }; 28 29 enum mlx5dr_action_offset { 30 MLX5DR_ACTION_OFFSET_DW0 = 0, 31 MLX5DR_ACTION_OFFSET_DW5 = 5, 32 MLX5DR_ACTION_OFFSET_DW6 = 6, 33 MLX5DR_ACTION_OFFSET_DW7 = 7, 34 MLX5DR_ACTION_OFFSET_HIT = 3, 35 MLX5DR_ACTION_OFFSET_HIT_LSB = 4, 36 }; 37 38 enum { 39 MLX5DR_ACTION_DOUBLE_SIZE = 8, 40 MLX5DR_ACTION_INLINE_DATA_SIZE = 4, 41 MLX5DR_ACTION_HDR_LEN_L2_MACS = 12, 42 MLX5DR_ACTION_HDR_LEN_L2_VLAN = 4, 43 MLX5DR_ACTION_HDR_LEN_L2_ETHER = 2, 44 MLX5DR_ACTION_HDR_LEN_L2 = (MLX5DR_ACTION_HDR_LEN_L2_MACS + 45 MLX5DR_ACTION_HDR_LEN_L2_ETHER), 46 MLX5DR_ACTION_HDR_LEN_L2_W_VLAN = (MLX5DR_ACTION_HDR_LEN_L2 + 47 MLX5DR_ACTION_HDR_LEN_L2_VLAN), 48 MLX5DR_ACTION_REFORMAT_DATA_SIZE = 64, 49 DECAP_L3_NUM_ACTIONS_W_NO_VLAN = 6, 50 DECAP_L3_NUM_ACTIONS_W_VLAN = 7, 51 }; 52 53 enum mlx5dr_action_setter_flag { 54 ASF_SINGLE1 = 1 << 0, 55 ASF_SINGLE2 = 1 << 1, 56 ASF_SINGLE3 = 1 << 2, 57 ASF_DOUBLE = ASF_SINGLE2 | ASF_SINGLE3, 58 ASF_INSERT = 1 << 3, 59 ASF_REMOVE = 1 << 4, 60 ASF_MODIFY = 1 << 5, 61 ASF_CTR = 1 << 6, 62 ASF_HIT = 1 << 7, 63 }; 64 65 enum mlx5dr_action_stc_reparse { 66 MLX5DR_ACTION_STC_REPARSE_DEFAULT, 67 MLX5DR_ACTION_STC_REPARSE_ON, 68 MLX5DR_ACTION_STC_REPARSE_OFF, 69 }; 70 71 /* 2' comp to 20, to get -20 in add operation */ 72 #define MLX5DR_ACTION_NAT64_DEC_20 0xffffffec 73 74 enum { 75 MLX5DR_ACTION_NAT64_MAX_MODIFY_ACTIONS = 20, 76 MLX5DR_ACTION_NAT64_ADD_20 = 20, 77 MLX5DR_ACTION_NAT64_HEADER_MINUS_ONE = 9, 78 MLX5DR_ACTION_NAT64_IPV6_HEADER = 10, 79 MLX5DR_ACTION_NAT64_IPV4_HEADER = 5, 80 MLX5DR_ACTION_NAT64_IPV6_VER = 0x60000000, 81 MLX5DR_ACTION_NAT64_IPV4_VER = 0x45000000, 82 MLX5DR_ACTION_NAT64_TTL_DEFAULT_VAL = 64, 83 MLX5DR_ACTION_NAT64_ECN_SIZE = 2, 84 }; 85 86 /* 3 stages for the nat64 action */ 87 enum mlx5dr_action_nat64_stages { 88 MLX5DR_ACTION_NAT64_STAGE_COPY = 0, 89 MLX5DR_ACTION_NAT64_STAGE_REPLACE = 1, 90 MLX5DR_ACTION_NAT64_STAGE_COPY_PROTOCOL = 2, 91 MLX5DR_ACTION_NAT64_STAGE_COPYBACK = 3, 92 /* Number of MH in NAT64 */ 93 MLX5DR_ACTION_NAT64_STAGES = 4, 94 }; 95 96 /* Registers for keeping data from stage to stage */ 97 enum { 98 MLX5DR_ACTION_NAT64_REG_CONTROL = 0, 99 MLX5DR_ACTION_NAT64_REG_SRC_IP = 1, 100 MLX5DR_ACTION_NAT64_REG_DST_IP = 2, 101 MLX5DR_ACTION_NAT64_REG_MAX = 3, 102 }; 103 104 struct mlx5dr_action_default_stc { 105 struct mlx5dr_pool_chunk nop_ctr; 106 struct mlx5dr_pool_chunk nop_dw5; 107 struct mlx5dr_pool_chunk nop_dw6; 108 struct mlx5dr_pool_chunk nop_dw7; 109 struct mlx5dr_pool_chunk default_hit; 110 uint32_t refcount; 111 }; 112 113 struct mlx5dr_action_shared_stc { 114 struct mlx5dr_pool_chunk remove_header; 115 uint32_t refcount; 116 }; 117 118 struct mlx5dr_actions_apply_data { 119 struct mlx5dr_send_engine *queue; 120 struct mlx5dr_rule_action *rule_action; 121 uint32_t *wqe_data; 122 struct mlx5dr_wqe_gta_ctrl_seg *wqe_ctrl; 123 uint32_t jump_to_action_stc; 124 struct mlx5dr_context_common_res *common_res; 125 enum mlx5dr_table_type tbl_type; 126 uint32_t next_direct_idx; 127 uint8_t require_dep; 128 }; 129 130 struct mlx5dr_actions_wqe_setter; 131 132 typedef void (*mlx5dr_action_setter_fp) 133 (struct mlx5dr_actions_apply_data *apply, 134 struct mlx5dr_actions_wqe_setter *setter); 135 136 struct mlx5dr_actions_wqe_setter { 137 mlx5dr_action_setter_fp set_single; 138 mlx5dr_action_setter_fp set_double; 139 mlx5dr_action_setter_fp set_hit; 140 mlx5dr_action_setter_fp set_ctr; 141 uint8_t idx_single; 142 uint8_t idx_double; 143 uint8_t idx_ctr; 144 uint8_t idx_hit; 145 uint8_t stage_idx; 146 uint8_t flags; 147 uint8_t extra_data; 148 }; 149 150 struct mlx5dr_action_template { 151 struct mlx5dr_actions_wqe_setter setters[MLX5DR_ACTION_MAX_STE]; 152 enum mlx5dr_action_type *action_type_arr; 153 uint8_t num_of_action_stes; 154 uint8_t num_actions; 155 uint8_t only_term; 156 /* indicates rule might require dependent wqe */ 157 bool need_dep_write; 158 uint32_t flags; 159 }; 160 161 struct mlx5dr_action { 162 uint8_t type; 163 uint8_t flags; 164 struct mlx5dr_context *ctx; 165 union { 166 struct { 167 struct mlx5dr_pool_chunk stc[MLX5DR_TABLE_TYPE_MAX]; 168 union { 169 struct { 170 struct mlx5dr_devx_obj *pat_obj; 171 struct mlx5dr_devx_obj *arg_obj; 172 __be64 single_action; 173 uint8_t num_of_patterns; 174 uint8_t single_action_type; 175 uint8_t num_of_actions; 176 uint8_t max_num_of_actions; 177 uint8_t require_reparse; 178 } modify_header; 179 struct { 180 struct mlx5dr_devx_obj *arg_obj; 181 uint32_t header_size; 182 uint16_t max_hdr_sz; 183 uint8_t num_of_hdrs; 184 uint8_t anchor; 185 uint8_t offset; 186 bool encap; 187 uint8_t require_reparse; 188 bool push_esp; 189 } reformat; 190 struct { 191 struct mlx5dr_action 192 *action[MLX5DR_ACTION_IPV6_EXT_MAX_SA]; 193 } ipv6_route_ext; 194 struct { 195 struct mlx5dr_devx_obj *devx_obj; 196 uint8_t return_reg_id; 197 } aso; 198 struct { 199 uint16_t vport_num; 200 uint16_t esw_owner_vhca_id; 201 } vport; 202 struct { 203 struct mlx5dr_devx_obj *devx_obj; 204 } alias; 205 struct { 206 struct mlx5dv_steering_anchor *sa; 207 } root_tbl; 208 struct { 209 struct mlx5dr_devx_obj *devx_obj; 210 } devx_dest; 211 struct { 212 struct mlx5dr_cmd_forward_tbl *fw_island; 213 size_t num_dest; 214 struct mlx5dr_cmd_set_fte_dest *dest_list; 215 } dest_array; 216 struct { 217 uint8_t type; 218 uint8_t start_anchor; 219 uint8_t end_anchor; 220 uint8_t num_of_words; 221 bool decap; 222 } remove_header; 223 struct { 224 struct mlx5dr_action *stages[MLX5DR_ACTION_NAT64_STAGES]; 225 } nat64; 226 struct { 227 struct mlx5dr_matcher *matcher; 228 } jump_to_matcher; 229 }; 230 }; 231 232 struct ibv_flow_action *flow_action; 233 struct mlx5dv_devx_obj *devx_obj; 234 struct ibv_qp *qp; 235 }; 236 }; 237 238 int mlx5dr_action_root_build_attr(struct mlx5dr_rule_action rule_actions[], 239 uint32_t num_actions, 240 struct mlx5dv_flow_action_attr *attr); 241 242 int mlx5dr_action_get_default_stc(struct mlx5dr_context *ctx, 243 uint8_t tbl_type); 244 245 void mlx5dr_action_put_default_stc(struct mlx5dr_context *ctx, 246 uint8_t tbl_type); 247 248 void mlx5dr_action_prepare_decap_l3_data(uint8_t *src, uint8_t *dst, 249 uint16_t num_of_actions); 250 251 int mlx5dr_action_template_process(struct mlx5dr_action_template *at); 252 253 bool mlx5dr_action_check_combo(enum mlx5dr_action_type *user_actions, 254 enum mlx5dr_table_type table_type); 255 256 int mlx5dr_action_alloc_single_stc(struct mlx5dr_context *ctx, 257 struct mlx5dr_cmd_stc_modify_attr *stc_attr, 258 uint32_t table_type, 259 struct mlx5dr_pool_chunk *stc); 260 261 void mlx5dr_action_free_single_stc(struct mlx5dr_context *ctx, 262 uint32_t table_type, 263 struct mlx5dr_pool_chunk *stc); 264 struct mlx5dr_action * 265 mlx5dr_action_create_modify_header_reparse(struct mlx5dr_context *ctx, 266 uint8_t num_of_patterns, 267 struct mlx5dr_action_mh_pattern *patterns, 268 uint32_t log_bulk_size, 269 uint32_t flags, uint32_t reparse); 270 271 272 static inline void 273 mlx5dr_action_setter_default_single(struct mlx5dr_actions_apply_data *apply, 274 __rte_unused struct mlx5dr_actions_wqe_setter *setter) 275 { 276 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0; 277 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] = 278 htobe32(apply->common_res->default_stc->nop_dw5.offset); 279 } 280 281 static inline void 282 mlx5dr_action_setter_default_double(struct mlx5dr_actions_apply_data *apply, 283 __rte_unused struct mlx5dr_actions_wqe_setter *setter) 284 { 285 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0; 286 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0; 287 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = 288 htobe32(apply->common_res->default_stc->nop_dw6.offset); 289 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 290 htobe32(apply->common_res->default_stc->nop_dw7.offset); 291 } 292 293 static inline void 294 mlx5dr_action_setter_default_ctr(struct mlx5dr_actions_apply_data *apply, 295 __rte_unused struct mlx5dr_actions_wqe_setter *setter) 296 { 297 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW0] = 0; 298 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_CTRL] = 299 htobe32(apply->common_res->default_stc->nop_ctr.offset); 300 } 301 302 static inline void 303 mlx5dr_action_apply_setter(struct mlx5dr_actions_apply_data *apply, 304 struct mlx5dr_actions_wqe_setter *setter, 305 bool is_jumbo) 306 { 307 uint8_t num_of_actions; 308 309 /* Set control counter */ 310 if (setter->flags & ASF_CTR) 311 setter->set_ctr(apply, setter); 312 else 313 mlx5dr_action_setter_default_ctr(apply, setter); 314 315 /* Set single and double on match */ 316 if (!is_jumbo) { 317 if (setter->flags & ASF_SINGLE1) 318 setter->set_single(apply, setter); 319 else 320 mlx5dr_action_setter_default_single(apply, setter); 321 322 if (setter->flags & ASF_DOUBLE) 323 setter->set_double(apply, setter); 324 else 325 mlx5dr_action_setter_default_double(apply, setter); 326 327 num_of_actions = setter->flags & ASF_DOUBLE ? 328 MLX5DR_ACTION_STC_IDX_LAST_COMBO1 : 329 MLX5DR_ACTION_STC_IDX_LAST_COMBO2; 330 } else { 331 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0; 332 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0; 333 apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0; 334 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] = 0; 335 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = 0; 336 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0; 337 num_of_actions = MLX5DR_ACTION_STC_IDX_LAST_JUMBO_STE; 338 } 339 340 /* Set next/final hit action */ 341 setter->set_hit(apply, setter); 342 343 /* Set number of actions */ 344 apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_CTRL] |= 345 htobe32(num_of_actions << 29); 346 } 347 348 #endif /* MLX5DR_ACTION_H_ */ 349