1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2/* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */ 3 4#ifndef _DR_STE_ 5#define _DR_STE_ 6 7#include "dr_types.h" 8 9#define STE_IPV4 0x1 10#define STE_IPV6 0x2 11#define STE_TCP 0x1 12#define STE_UDP 0x2 13#define STE_SPI 0x3 14#define IP_VERSION_IPV4 0x4 15#define IP_VERSION_IPV6 0x6 16#define STE_SVLAN 0x1 17#define STE_CVLAN 0x2 18#define HDR_LEN_L2_MACS 0xC 19#define HDR_LEN_L2_VLAN 0x4 20#define HDR_LEN_L2_ETHER 0x2 21#define HDR_LEN_L2 (HDR_LEN_L2_MACS + HDR_LEN_L2_ETHER) 22#define HDR_LEN_L2_W_VLAN (HDR_LEN_L2 + HDR_LEN_L2_VLAN) 23 24/* Set to STE a specific value using DR_STE_SET */ 25#define DR_STE_SET_VAL(lookup_type, tag, t_fname, spec, s_fname, value) do { \ 26 if ((spec)->s_fname) { \ 27 MLX5_SET(ste_##lookup_type, tag, t_fname, value); \ 28 (spec)->s_fname = 0; \ 29 } \ 30} while (0) 31 32/* Set to STE spec->s_fname to tag->t_fname set spec->s_fname as used */ 33#define DR_STE_SET_TAG(lookup_type, tag, t_fname, spec, s_fname) \ 34 DR_STE_SET_VAL(lookup_type, tag, t_fname, spec, s_fname, spec->s_fname) 35 36/* Set to STE -1 to tag->t_fname and set spec->s_fname as used */ 37#define DR_STE_SET_ONES(lookup_type, tag, t_fname, spec, s_fname) \ 38 DR_STE_SET_VAL(lookup_type, tag, t_fname, spec, s_fname, -1) 39 40#define DR_STE_SET_TCP_FLAGS(lookup_type, tag, spec) do { \ 41 MLX5_SET(ste_##lookup_type, tag, tcp_ns, !!((spec)->tcp_flags & (1 << 8))); \ 42 MLX5_SET(ste_##lookup_type, tag, tcp_cwr, !!((spec)->tcp_flags & (1 << 7))); \ 43 MLX5_SET(ste_##lookup_type, tag, tcp_ece, !!((spec)->tcp_flags & (1 << 6))); \ 44 MLX5_SET(ste_##lookup_type, tag, tcp_urg, !!((spec)->tcp_flags & (1 << 5))); \ 45 MLX5_SET(ste_##lookup_type, tag, tcp_ack, !!((spec)->tcp_flags & (1 << 4))); \ 46 MLX5_SET(ste_##lookup_type, tag, tcp_psh, !!((spec)->tcp_flags & (1 << 3))); \ 47 MLX5_SET(ste_##lookup_type, tag, tcp_rst, !!((spec)->tcp_flags & (1 << 2))); \ 48 MLX5_SET(ste_##lookup_type, tag, tcp_syn, !!((spec)->tcp_flags & (1 << 1))); \ 49 MLX5_SET(ste_##lookup_type, tag, tcp_fin, !!((spec)->tcp_flags & (1 << 0))); \ 50} while (0) 51 52#define DR_STE_SET_MPLS(lookup_type, mask, in_out, tag) do { \ 53 struct mlx5dr_match_misc2 *_mask = mask; \ 54 u8 *_tag = tag; \ 55 DR_STE_SET_TAG(lookup_type, _tag, mpls0_label, _mask, \ 56 in_out##_first_mpls_label);\ 57 DR_STE_SET_TAG(lookup_type, _tag, mpls0_s_bos, _mask, \ 58 in_out##_first_mpls_s_bos); \ 59 DR_STE_SET_TAG(lookup_type, _tag, mpls0_exp, _mask, \ 60 in_out##_first_mpls_exp); \ 61 DR_STE_SET_TAG(lookup_type, _tag, mpls0_ttl, _mask, \ 62 in_out##_first_mpls_ttl); \ 63} while (0) 64 65#define DR_STE_SET_FLEX_PARSER_FIELD(tag, fname, caps, spec) do { \ 66 u8 parser_id = (caps)->flex_parser_id_##fname; \ 67 u8 *parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); \ 68 *(__be32 *)parser_ptr = cpu_to_be32((spec)->fname);\ 69 (spec)->fname = 0;\ 70} while (0) 71 72#define DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(_misc) (\ 73 (_misc)->outer_first_mpls_over_gre_label || \ 74 (_misc)->outer_first_mpls_over_gre_exp || \ 75 (_misc)->outer_first_mpls_over_gre_s_bos || \ 76 (_misc)->outer_first_mpls_over_gre_ttl) 77 78#define DR_STE_IS_OUTER_MPLS_OVER_UDP_SET(_misc) (\ 79 (_misc)->outer_first_mpls_over_udp_label || \ 80 (_misc)->outer_first_mpls_over_udp_exp || \ 81 (_misc)->outer_first_mpls_over_udp_s_bos || \ 82 (_misc)->outer_first_mpls_over_udp_ttl) 83 84enum dr_ste_action_modify_type_l3 { 85 DR_STE_ACTION_MDFY_TYPE_L3_NONE = 0x0, 86 DR_STE_ACTION_MDFY_TYPE_L3_IPV4 = 0x1, 87 DR_STE_ACTION_MDFY_TYPE_L3_IPV6 = 0x2, 88}; 89 90enum dr_ste_action_modify_type_l4 { 91 DR_STE_ACTION_MDFY_TYPE_L4_NONE = 0x0, 92 DR_STE_ACTION_MDFY_TYPE_L4_TCP = 0x1, 93 DR_STE_ACTION_MDFY_TYPE_L4_UDP = 0x2, 94}; 95 96enum { 97 HDR_MPLS_OFFSET_LABEL = 12, 98 HDR_MPLS_OFFSET_EXP = 9, 99 HDR_MPLS_OFFSET_S_BOS = 8, 100 HDR_MPLS_OFFSET_TTL = 0, 101}; 102 103u16 mlx5dr_ste_conv_bit_to_byte_mask(u8 *bit_mask); 104 105static inline u8 * 106dr_ste_calc_flex_parser_offset(u8 *tag, u8 parser_id) 107{ 108 /* Calculate tag byte offset based on flex parser id */ 109 return tag + 4 * (3 - (parser_id % 4)); 110} 111 112#define DR_STE_CTX_BUILDER(fname) \ 113 ((*build_##fname##_init)(struct mlx5dr_ste_build *sb, \ 114 struct mlx5dr_match_param *mask)) 115 116struct mlx5dr_ste_ctx { 117 /* Builders */ 118 void DR_STE_CTX_BUILDER(eth_l2_src_dst); 119 void DR_STE_CTX_BUILDER(eth_l3_ipv6_src); 120 void DR_STE_CTX_BUILDER(eth_l3_ipv6_dst); 121 void DR_STE_CTX_BUILDER(eth_l3_ipv4_5_tuple); 122 void DR_STE_CTX_BUILDER(eth_l2_src); 123 void DR_STE_CTX_BUILDER(eth_l2_dst); 124 void DR_STE_CTX_BUILDER(eth_l2_tnl); 125 void DR_STE_CTX_BUILDER(eth_l3_ipv4_misc); 126 void DR_STE_CTX_BUILDER(eth_ipv6_l3_l4); 127 void DR_STE_CTX_BUILDER(mpls); 128 void DR_STE_CTX_BUILDER(tnl_gre); 129 void DR_STE_CTX_BUILDER(tnl_mpls); 130 void DR_STE_CTX_BUILDER(tnl_mpls_over_gre); 131 void DR_STE_CTX_BUILDER(tnl_mpls_over_udp); 132 void DR_STE_CTX_BUILDER(icmp); 133 void DR_STE_CTX_BUILDER(general_purpose); 134 void DR_STE_CTX_BUILDER(eth_l4_misc); 135 void DR_STE_CTX_BUILDER(tnl_vxlan_gpe); 136 void DR_STE_CTX_BUILDER(tnl_geneve); 137 void DR_STE_CTX_BUILDER(tnl_geneve_tlv_opt); 138 void DR_STE_CTX_BUILDER(tnl_geneve_tlv_opt_exist); 139 void DR_STE_CTX_BUILDER(register_0); 140 void DR_STE_CTX_BUILDER(register_1); 141 void DR_STE_CTX_BUILDER(src_gvmi_qpn); 142 void DR_STE_CTX_BUILDER(flex_parser_0); 143 void DR_STE_CTX_BUILDER(flex_parser_1); 144 void DR_STE_CTX_BUILDER(tnl_gtpu); 145 void DR_STE_CTX_BUILDER(tnl_header_0_1); 146 void DR_STE_CTX_BUILDER(tnl_gtpu_flex_parser_0); 147 void DR_STE_CTX_BUILDER(tnl_gtpu_flex_parser_1); 148 149 /* Getters and Setters */ 150 void (*ste_init)(u8 *hw_ste_p, u16 lu_type, 151 bool is_rx, u16 gvmi); 152 void (*set_next_lu_type)(u8 *hw_ste_p, u16 lu_type); 153 u16 (*get_next_lu_type)(u8 *hw_ste_p); 154 bool (*is_miss_addr_set)(u8 *hw_ste_p); 155 void (*set_miss_addr)(u8 *hw_ste_p, u64 miss_addr); 156 u64 (*get_miss_addr)(u8 *hw_ste_p); 157 void (*set_hit_addr)(u8 *hw_ste_p, u64 icm_addr, u32 ht_size); 158 void (*set_byte_mask)(u8 *hw_ste_p, u16 byte_mask); 159 u16 (*get_byte_mask)(u8 *hw_ste_p); 160 161 /* Actions */ 162 u32 actions_caps; 163 void (*set_actions_rx)(struct mlx5dr_domain *dmn, 164 u8 *action_type_set, 165 u32 actions_caps, 166 u8 *hw_ste_arr, 167 struct mlx5dr_ste_actions_attr *attr, 168 u32 *added_stes); 169 void (*set_actions_tx)(struct mlx5dr_domain *dmn, 170 u8 *action_type_set, 171 u32 actions_caps, 172 u8 *hw_ste_arr, 173 struct mlx5dr_ste_actions_attr *attr, 174 u32 *added_stes); 175 u32 modify_field_arr_sz; 176 const struct mlx5dr_ste_action_modify_field *modify_field_arr; 177 void (*set_action_set)(u8 *hw_action, 178 u8 hw_field, 179 u8 shifter, 180 u8 length, 181 u32 data); 182 void (*set_action_add)(u8 *hw_action, 183 u8 hw_field, 184 u8 shifter, 185 u8 length, 186 u32 data); 187 void (*set_action_copy)(u8 *hw_action, 188 u8 dst_hw_field, 189 u8 dst_shifter, 190 u8 dst_len, 191 u8 src_hw_field, 192 u8 src_shifter); 193 int (*set_action_decap_l3_list)(void *data, 194 u32 data_sz, 195 u8 *hw_action, 196 u32 hw_action_sz, 197 u16 *used_hw_action_num); 198 int (*alloc_modify_hdr_chunk)(struct mlx5dr_action *action); 199 void (*dealloc_modify_hdr_chunk)(struct mlx5dr_action *action); 200 201 /* Send */ 202 void (*prepare_for_postsend)(u8 *hw_ste_p, u32 ste_size); 203}; 204 205struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v0(void); 206struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v1(void); 207struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v2(void); 208 209#endif /* _DR_STE_ */ 210