FILE
action.h
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.h
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2/* Copyright (c) 2024 NVIDIA Corporation & Affiliates */ 3 4#ifndef HWS_ACTION_H_ 5#define HWS_ACTION_H_ 6 7/* Max number of STEs needed for a rule (including match) */ 8#define MLX5HWS_ACTION_MAX_STE 20 9 10/* Max number of internal subactions of ipv6_ext */ 11#define MLX5HWS_ACTION_IPV6_EXT_MAX_SA 4 12 13enum mlx5hws_action_stc_idx { 14 MLX5HWS_ACTION_STC_IDX_CTRL = 0, 15 MLX5HWS_ACTION_STC_IDX_HIT = 1, 16 MLX5HWS_ACTION_STC_IDX_DW5 = 2, 17 MLX5HWS_ACTION_STC_IDX_DW6 = 3, 18 MLX5HWS_ACTION_STC_IDX_DW7 = 4, 19 MLX5HWS_ACTION_STC_IDX_MAX = 5, 20 /* STC Jumvo STE combo: CTR, Hit */ 21 MLX5HWS_ACTION_STC_IDX_LAST_JUMBO_STE = 1, 22 /* STC combo1: CTR, SINGLE, DOUBLE, Hit */ 23 MLX5HWS_ACTION_STC_IDX_LAST_COMBO1 = 3, 24 /* STC combo2: CTR, 3 x SINGLE, Hit */ 25 MLX5HWS_ACTION_STC_IDX_LAST_COMBO2 = 4, 26 /* STC combo2: CTR, TRIPLE, Hit */ 27 MLX5HWS_ACTION_STC_IDX_LAST_COMBO3 = 2, 28}; 29 30enum mlx5hws_action_offset { 31 MLX5HWS_ACTION_OFFSET_DW0 = 0, 32 MLX5HWS_ACTION_OFFSET_DW5 = 5, 33 MLX5HWS_ACTION_OFFSET_DW6 = 6, 34 MLX5HWS_ACTION_OFFSET_DW7 = 7, 35 MLX5HWS_ACTION_OFFSET_HIT = 3, 36 MLX5HWS_ACTION_OFFSET_HIT_LSB = 4, 37}; 38 39enum { 40 MLX5HWS_ACTION_DOUBLE_SIZE = 8, 41 MLX5HWS_ACTION_INLINE_DATA_SIZE = 4, 42 MLX5HWS_ACTION_HDR_LEN_L2_MACS = 12, 43 MLX5HWS_ACTION_HDR_LEN_L2_VLAN = 4, 44 MLX5HWS_ACTION_HDR_LEN_L2_ETHER = 2, 45 MLX5HWS_ACTION_HDR_LEN_L2 = (MLX5HWS_ACTION_HDR_LEN_L2_MACS + 46 MLX5HWS_ACTION_HDR_LEN_L2_ETHER), 47 MLX5HWS_ACTION_HDR_LEN_L2_W_VLAN = (MLX5HWS_ACTION_HDR_LEN_L2 + 48 MLX5HWS_ACTION_HDR_LEN_L2_VLAN), 49 MLX5HWS_ACTION_REFORMAT_DATA_SIZE = 64, 50 DECAP_L3_NUM_ACTIONS_W_NO_VLAN = 6, 51 DECAP_L3_NUM_ACTIONS_W_VLAN = 7, 52}; 53 54enum mlx5hws_action_setter_flag { 55 ASF_SINGLE1 = 1 << 0, 56 ASF_SINGLE2 = 1 << 1, 57 ASF_SINGLE3 = 1 << 2, 58 ASF_DOUBLE = ASF_SINGLE2 | ASF_SINGLE3, 59 ASF_TRIPLE = ASF_SINGLE1 | ASF_DOUBLE, 60 ASF_INSERT = 1 << 3, 61 ASF_REMOVE = 1 << 4, 62 ASF_MODIFY = 1 << 5, 63 ASF_CTR = 1 << 6, 64 ASF_HIT = 1 << 7, 65}; 66 67struct mlx5hws_action_default_stc { 68 struct mlx5hws_pool_chunk nop_ctr; 69 struct mlx5hws_pool_chunk nop_dw5; 70 struct mlx5hws_pool_chunk nop_dw6; 71 struct mlx5hws_pool_chunk nop_dw7; 72 struct mlx5hws_pool_chunk default_hit; 73 u32 refcount; /* protected by context ctrl lock */ 74}; 75 76struct mlx5hws_action_shared_stc { 77 struct mlx5hws_pool_chunk stc_chunk; 78 u32 refcount; /* protected by context ctrl lock */ 79}; 80 81struct mlx5hws_actions_apply_data { 82 struct mlx5hws_send_engine *queue; 83 struct mlx5hws_rule_action *rule_action; 84 __be32 *wqe_data; 85 struct mlx5hws_wqe_gta_ctrl_seg *wqe_ctrl; 86 u32 jump_to_action_stc; 87 struct mlx5hws_context_common_res *common_res; 88 enum mlx5hws_table_type tbl_type; 89 u32 next_direct_idx; 90 u8 require_dep; 91}; 92 93struct mlx5hws_actions_wqe_setter; 94 95typedef void (*mlx5hws_action_setter_fp)(struct mlx5hws_actions_apply_data *apply, 96 struct mlx5hws_actions_wqe_setter *setter); 97 98struct mlx5hws_actions_wqe_setter { 99 mlx5hws_action_setter_fp set_single; 100 mlx5hws_action_setter_fp set_double; 101 mlx5hws_action_setter_fp set_triple; 102 mlx5hws_action_setter_fp set_hit; 103 mlx5hws_action_setter_fp set_ctr; 104 u8 idx_single; 105 u8 idx_double; 106 u8 idx_triple; 107 u8 idx_ctr; 108 u8 idx_hit; 109 u8 stage_idx; 110 u8 flags; 111}; 112 113struct mlx5hws_action_template { 114 struct mlx5hws_actions_wqe_setter setters[MLX5HWS_ACTION_MAX_STE]; 115 enum mlx5hws_action_type *action_type_arr; 116 u8 num_of_action_stes; 117 u8 num_actions; 118 u8 only_term; 119}; 120 121struct mlx5hws_range_action_table { 122 struct mlx5hws_pool *pool; 123 u32 rtc_0_id; 124 u32 rtc_1_id; 125}; 126 127struct mlx5hws_action { 128 u8 type; 129 u8 flags; 130 struct mlx5hws_context *ctx; 131 union { 132 struct { 133 struct mlx5hws_pool_chunk stc; 134 union { 135 struct { 136 u32 pat_id; 137 u32 arg_id; 138 __be64 single_action; 139 u32 nop_locations; 140 u8 num_of_patterns; 141 u8 single_action_type; 142 u8 num_of_actions; 143 u8 max_num_of_actions; 144 u8 require_reparse; 145 } modify_header; 146 struct { 147 u32 arg_id; 148 u32 header_size; 149 u16 max_hdr_sz; 150 u8 num_of_hdrs; 151 u8 anchor; 152 u8 e_anchor; 153 u8 offset; 154 bool encap; 155 u8 require_reparse; 156 } reformat; 157 struct { 158 u32 obj_id; 159 u8 return_reg_id; 160 } aso; 161 struct { 162 u16 vport_num; 163 u16 esw_owner_vhca_id; 164 bool esw_owner_vhca_id_valid; 165 } vport; 166 struct { 167 u32 obj_id; 168 } dest_obj; 169 struct { 170 struct mlx5hws_cmd_forward_tbl *fw_island; 171 size_t num_dest; 172 struct mlx5hws_cmd_set_fte_dest *dest_list; 173 } dest_array; 174 struct { 175 struct mlx5hws_cmd_forward_tbl *fw_island; 176 } flow_sampler; 177 struct { 178 u8 type; 179 u8 start_anchor; 180 u8 end_anchor; 181 u8 num_of_words; 182 bool decap; 183 } insert_hdr; 184 struct { 185 /* PRM start anchor from which header will be removed */ 186 u8 anchor; 187 /* Header remove offset in bytes, from the start 188 * anchor to the location where remove header starts. 189 */ 190 u8 offset; 191 /* Indicates the removed header size in bytes */ 192 size_t size; 193 } remove_header; 194 struct { 195 struct mlx5hws_range_action_table *table_ste; 196 struct mlx5hws_action *hit_ft_action; 197 struct mlx5hws_definer *definer; 198 } range; 199 }; 200 }; 201 202 struct ibv_flow_action *flow_action; 203 u32 obj_id; 204 struct ibv_qp *qp; 205 }; 206}; 207 208const char *mlx5hws_action_type_to_str(enum mlx5hws_action_type action_type); 209 210int mlx5hws_action_get_default_stc(struct mlx5hws_context *ctx, 211 u8 tbl_type); 212 213void mlx5hws_action_put_default_stc(struct mlx5hws_context *ctx, 214 u8 tbl_type); 215 216void mlx5hws_action_prepare_decap_l3_data(u8 *src, u8 *dst, 217 u16 num_of_actions); 218 219int mlx5hws_action_template_process(struct mlx5hws_action_template *at); 220 221bool mlx5hws_action_check_combo(struct mlx5hws_context *ctx, 222 enum mlx5hws_action_type *user_actions, 223 enum mlx5hws_table_type table_type); 224 225int mlx5hws_action_alloc_single_stc(struct mlx5hws_context *ctx, 226 struct mlx5hws_cmd_stc_modify_attr *stc_attr, 227 u32 table_type, 228 struct mlx5hws_pool_chunk *stc); 229 230void mlx5hws_action_free_single_stc(struct mlx5hws_context *ctx, 231 u32 table_type, 232 struct mlx5hws_pool_chunk *stc); 233 234static inline void 235mlx5hws_action_setter_default_single(struct mlx5hws_actions_apply_data *apply, 236 struct mlx5hws_actions_wqe_setter *setter) 237{ 238 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW5] = 0; 239 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW5] = 240 htonl(apply->common_res->default_stc->nop_dw5.offset); 241} 242 243static inline void 244mlx5hws_action_setter_default_double(struct mlx5hws_actions_apply_data *apply, 245 struct mlx5hws_actions_wqe_setter *setter) 246{ 247 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW6] = 0; 248 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW7] = 0; 249 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW6] = 250 htonl(apply->common_res->default_stc->nop_dw6.offset); 251 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW7] = 252 htonl(apply->common_res->default_stc->nop_dw7.offset); 253} 254 255static inline void 256mlx5hws_action_setter_default_ctr(struct mlx5hws_actions_apply_data *apply, 257 struct mlx5hws_actions_wqe_setter *setter) 258{ 259 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW0] = 0; 260 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_CTRL] = 261 htonl(apply->common_res->default_stc->nop_ctr.offset); 262} 263 264static inline void 265mlx5hws_action_apply_setter(struct mlx5hws_actions_apply_data *apply, 266 struct mlx5hws_actions_wqe_setter *setter, 267 bool is_jumbo) 268{ 269 u8 num_of_actions; 270 271 /* Set control counter */ 272 if (setter->set_ctr) 273 setter->set_ctr(apply, setter); 274 else 275 mlx5hws_action_setter_default_ctr(apply, setter); 276 277 if (!is_jumbo) { 278 if (unlikely(setter->set_triple)) { 279 /* Set triple on match */ 280 setter->set_triple(apply, setter); 281 num_of_actions = MLX5HWS_ACTION_STC_IDX_LAST_COMBO3; 282 } else { 283 /* Set single and double on match */ 284 if (setter->set_single) 285 setter->set_single(apply, setter); 286 else 287 mlx5hws_action_setter_default_single(apply, setter); 288 289 if (setter->set_double) 290 setter->set_double(apply, setter); 291 else 292 mlx5hws_action_setter_default_double(apply, setter); 293 294 num_of_actions = setter->set_double ? 295 MLX5HWS_ACTION_STC_IDX_LAST_COMBO1 : 296 MLX5HWS_ACTION_STC_IDX_LAST_COMBO2; 297 } 298 } else { 299 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW5] = 0; 300 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW6] = 0; 301 apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW7] = 0; 302 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW5] = 0; 303 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW6] = 0; 304 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW7] = 0; 305 num_of_actions = MLX5HWS_ACTION_STC_IDX_LAST_JUMBO_STE; 306 } 307 308 /* Set next/final hit action */ 309 setter->set_hit(apply, setter); 310 311 /* Set number of actions */ 312 apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_CTRL] |= 313 htonl(num_of_actions << 29); 314} 315 316#endif /* HWS_ACTION_H_ */
~/
Read-only file preview.