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_IS_OUTER_MPLS_OVER_GRE_SET(_misc) (\
66 	(_misc)->outer_first_mpls_over_gre_label || \
67 	(_misc)->outer_first_mpls_over_gre_exp || \
68 	(_misc)->outer_first_mpls_over_gre_s_bos || \
69 	(_misc)->outer_first_mpls_over_gre_ttl)
70 
71 #define DR_STE_IS_OUTER_MPLS_OVER_UDP_SET(_misc) (\
72 	(_misc)->outer_first_mpls_over_udp_label || \
73 	(_misc)->outer_first_mpls_over_udp_exp || \
74 	(_misc)->outer_first_mpls_over_udp_s_bos || \
75 	(_misc)->outer_first_mpls_over_udp_ttl)
76 
77 enum dr_ste_action_modify_type_l3 {
78 	DR_STE_ACTION_MDFY_TYPE_L3_NONE	= 0x0,
79 	DR_STE_ACTION_MDFY_TYPE_L3_IPV4	= 0x1,
80 	DR_STE_ACTION_MDFY_TYPE_L3_IPV6	= 0x2,
81 };
82 
83 enum dr_ste_action_modify_type_l4 {
84 	DR_STE_ACTION_MDFY_TYPE_L4_NONE	= 0x0,
85 	DR_STE_ACTION_MDFY_TYPE_L4_TCP	= 0x1,
86 	DR_STE_ACTION_MDFY_TYPE_L4_UDP	= 0x2,
87 };
88 
89 enum {
90 	HDR_MPLS_OFFSET_LABEL	= 12,
91 	HDR_MPLS_OFFSET_EXP	= 9,
92 	HDR_MPLS_OFFSET_S_BOS	= 8,
93 	HDR_MPLS_OFFSET_TTL	= 0,
94 };
95 
96 u16 mlx5dr_ste_conv_bit_to_byte_mask(u8 *bit_mask);
97 
98 #define DR_STE_CTX_BUILDER(fname) \
99 	((*build_##fname##_init)(struct mlx5dr_ste_build *sb, \
100 				 struct mlx5dr_match_param *mask))
101 
102 struct mlx5dr_ste_ctx {
103 	/* Builders */
104 	void DR_STE_CTX_BUILDER(eth_l2_src_dst);
105 	void DR_STE_CTX_BUILDER(eth_l3_ipv6_src);
106 	void DR_STE_CTX_BUILDER(eth_l3_ipv6_dst);
107 	void DR_STE_CTX_BUILDER(eth_l3_ipv4_5_tuple);
108 	void DR_STE_CTX_BUILDER(eth_l2_src);
109 	void DR_STE_CTX_BUILDER(eth_l2_dst);
110 	void DR_STE_CTX_BUILDER(eth_l2_tnl);
111 	void DR_STE_CTX_BUILDER(eth_l3_ipv4_misc);
112 	void DR_STE_CTX_BUILDER(eth_ipv6_l3_l4);
113 	void DR_STE_CTX_BUILDER(mpls);
114 	void DR_STE_CTX_BUILDER(tnl_gre);
115 	void DR_STE_CTX_BUILDER(tnl_mpls);
116 	int  DR_STE_CTX_BUILDER(icmp);
117 	void DR_STE_CTX_BUILDER(general_purpose);
118 	void DR_STE_CTX_BUILDER(eth_l4_misc);
119 	void DR_STE_CTX_BUILDER(tnl_vxlan_gpe);
120 	void DR_STE_CTX_BUILDER(tnl_geneve);
121 	void DR_STE_CTX_BUILDER(register_0);
122 	void DR_STE_CTX_BUILDER(register_1);
123 	void DR_STE_CTX_BUILDER(src_gvmi_qpn);
124 
125 	/* Getters and Setters */
126 	void (*ste_init)(u8 *hw_ste_p, u16 lu_type,
127 			 u8 entry_type, u16 gvmi);
128 	void (*set_next_lu_type)(u8 *hw_ste_p, u16 lu_type);
129 	u16  (*get_next_lu_type)(u8 *hw_ste_p);
130 	void (*set_miss_addr)(u8 *hw_ste_p, u64 miss_addr);
131 	u64  (*get_miss_addr)(u8 *hw_ste_p);
132 	void (*set_hit_addr)(u8 *hw_ste_p, u64 icm_addr, u32 ht_size);
133 	void (*set_byte_mask)(u8 *hw_ste_p, u16 byte_mask);
134 	u16  (*get_byte_mask)(u8 *hw_ste_p);
135 
136 	/* Actions */
137 	void (*set_actions_rx)(struct mlx5dr_domain *dmn,
138 			       u8 *action_type_set,
139 			       u8 *hw_ste_arr,
140 			       struct mlx5dr_ste_actions_attr *attr,
141 			       u32 *added_stes);
142 	void (*set_actions_tx)(struct mlx5dr_domain *dmn,
143 			       u8 *action_type_set,
144 			       u8 *hw_ste_arr,
145 			       struct mlx5dr_ste_actions_attr *attr,
146 			       u32 *added_stes);
147 	u32 modify_field_arr_sz;
148 	const struct mlx5dr_ste_action_modify_field *modify_field_arr;
149 	void (*set_action_set)(u8 *hw_action,
150 			       u8 hw_field,
151 			       u8 shifter,
152 			       u8 length,
153 			       u32 data);
154 	void (*set_action_add)(u8 *hw_action,
155 			       u8 hw_field,
156 			       u8 shifter,
157 			       u8 length,
158 			       u32 data);
159 	void (*set_action_copy)(u8 *hw_action,
160 				u8 dst_hw_field,
161 				u8 dst_shifter,
162 				u8 dst_len,
163 				u8 src_hw_field,
164 				u8 src_shifter);
165 	int (*set_action_decap_l3_list)(void *data,
166 					u32 data_sz,
167 					u8 *hw_action,
168 					u32 hw_action_sz,
169 					u16 *used_hw_action_num);
170 
171 	/* Send */
172 	void (*prepare_for_postsend)(u8 *hw_ste_p, u32 ste_size);
173 };
174 
175 extern struct mlx5dr_ste_ctx ste_ctx_v0;
176 extern struct mlx5dr_ste_ctx ste_ctx_v1;
177 
178 #endif  /* _DR_STE_ */
179