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
84 enum 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
90 enum 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
96 enum {
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
103 u16 mlx5dr_ste_conv_bit_to_byte_mask(u8 *bit_mask);
104
105 static inline u8 *
dr_ste_calc_flex_parser_offset(u8 * tag,u8 parser_id)106 dr_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
116 struct 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
205 struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v0(void);
206 struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v1(void);
207 struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v2(void);
208
209 #endif /* _DR_STE_ */
210