Commit | Line | Data |
---|---|---|
e8f887ac AV |
1 | /* |
2 | * Copyright (c) 2016, Mellanox Technologies. All rights reserved. | |
3 | * | |
4 | * This software is available to you under a choice of one of two | |
5 | * licenses. You may choose to be licensed under the terms of the GNU | |
6 | * General Public License (GPL) Version 2, available from the file | |
7 | * COPYING in the main directory of this source tree, or the | |
8 | * OpenIB.org BSD license below: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or | |
11 | * without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistributions of source code must retain the above | |
15 | * copyright notice, this list of conditions and the following | |
16 | * disclaimer. | |
17 | * | |
18 | * - Redistributions in binary form must reproduce the above | |
19 | * copyright notice, this list of conditions and the following | |
20 | * disclaimer in the documentation and/or other materials | |
21 | * provided with the distribution. | |
22 | * | |
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
30 | * SOFTWARE. | |
31 | */ | |
32 | ||
33 | #ifndef __MLX5_EN_TC_H__ | |
34 | #define __MLX5_EN_TC_H__ | |
35 | ||
de4784ca | 36 | #include <net/pkt_cls.h> |
768c3667 | 37 | #include "en.h" |
c620b772 AL |
38 | #include "eswitch.h" |
39 | #include "en/tc_ct.h" | |
0d9f9647 VB |
40 | #include "en/tc_tun.h" |
41 | #include "en_rep.h" | |
de4784ca | 42 | |
12185a9f AV |
43 | #define MLX5E_TC_FLOW_ID_MASK 0x0000ffff |
44 | ||
e80541ec | 45 | #ifdef CONFIG_MLX5_ESWITCH |
60bd4af8 | 46 | |
aedd133d AL |
47 | #define NIC_FLOW_ATTR_SZ (sizeof(struct mlx5_flow_attr) +\ |
48 | sizeof(struct mlx5_nic_flow_attr)) | |
c620b772 AL |
49 | #define ESW_FLOW_ATTR_SZ (sizeof(struct mlx5_flow_attr) +\ |
50 | sizeof(struct mlx5_esw_flow_attr)) | |
aedd133d AL |
51 | #define ns_to_attr_sz(ns) (((ns) == MLX5_FLOW_NAMESPACE_FDB) ?\ |
52 | ESW_FLOW_ATTR_SZ :\ | |
53 | NIC_FLOW_ATTR_SZ) | |
54 | ||
c620b772 | 55 | |
185901ce VB |
56 | int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags); |
57 | ||
58 | struct mlx5e_tc_update_priv { | |
59 | struct net_device *tun_dev; | |
60 | }; | |
61 | ||
c620b772 AL |
62 | struct mlx5_nic_flow_attr { |
63 | u32 flow_tag; | |
64 | u32 hairpin_tirn; | |
65 | struct mlx5_flow_table *hairpin_ft; | |
66 | }; | |
67 | ||
68 | struct mlx5_flow_attr { | |
69 | u32 action; | |
70 | struct mlx5_fc *counter; | |
71 | struct mlx5_modify_hdr *modify_hdr; | |
72 | struct mlx5_ct_attr ct_attr; | |
73 | struct mlx5e_tc_flow_parse_attr *parse_attr; | |
74 | u32 chain; | |
75 | u16 prio; | |
76 | u32 dest_chain; | |
77 | struct mlx5_flow_table *ft; | |
78 | struct mlx5_flow_table *dest_ft; | |
79 | u8 inner_match_level; | |
80 | u8 outer_match_level; | |
34ca6535 | 81 | u8 ip_version; |
1e74152e | 82 | u8 tun_ip_version; |
c620b772 AL |
83 | u32 flags; |
84 | union { | |
85 | struct mlx5_esw_flow_attr esw_attr[0]; | |
86 | struct mlx5_nic_flow_attr nic_attr[0]; | |
87 | }; | |
88 | }; | |
89 | ||
34ca6535 VB |
90 | struct mlx5_rx_tun_attr { |
91 | u16 decap_vport; | |
92 | union { | |
93 | __be32 v4; | |
94 | struct in6_addr v6; | |
95 | } src_ip; /* Valid if decap_vport is not zero */ | |
96 | union { | |
97 | __be32 v4; | |
98 | struct in6_addr v6; | |
99 | } dst_ip; /* Valid if decap_vport is not zero */ | |
100 | u32 vni; | |
101 | }; | |
102 | ||
c7569097 AL |
103 | #define MLX5E_TC_TABLE_CHAIN_TAG_BITS 16 |
104 | #define MLX5E_TC_TABLE_CHAIN_TAG_MASK GENMASK(MLX5E_TC_TABLE_CHAIN_TAG_BITS - 1, 0) | |
105 | ||
185901ce VB |
106 | #if IS_ENABLED(CONFIG_MLX5_CLS_ACT) |
107 | ||
768c3667 VB |
108 | struct tunnel_match_key { |
109 | struct flow_dissector_key_control enc_control; | |
110 | struct flow_dissector_key_keyid enc_key_id; | |
111 | struct flow_dissector_key_ports enc_tp; | |
112 | struct flow_dissector_key_ip enc_ip; | |
113 | union { | |
114 | struct flow_dissector_key_ipv4_addrs enc_ipv4; | |
115 | struct flow_dissector_key_ipv6_addrs enc_ipv6; | |
116 | }; | |
117 | ||
118 | int filter_ifindex; | |
119 | }; | |
120 | ||
121 | struct tunnel_match_enc_opts { | |
122 | struct flow_dissector_key_enc_opts key; | |
123 | struct flow_dissector_key_enc_opts mask; | |
124 | }; | |
125 | ||
126 | /* Tunnel_id mapping is TUNNEL_INFO_BITS + ENC_OPTS_BITS. | |
127 | * Upper TUNNEL_INFO_BITS for general tunnel info. | |
128 | * Lower ENC_OPTS_BITS bits for enc_opts. | |
129 | */ | |
d12f4521 | 130 | #define TUNNEL_INFO_BITS 12 |
768c3667 | 131 | #define TUNNEL_INFO_BITS_MASK GENMASK(TUNNEL_INFO_BITS - 1, 0) |
b973cf32 | 132 | #define ENC_OPTS_BITS 11 |
768c3667 VB |
133 | #define ENC_OPTS_BITS_MASK GENMASK(ENC_OPTS_BITS - 1, 0) |
134 | #define TUNNEL_ID_BITS (TUNNEL_INFO_BITS + ENC_OPTS_BITS) | |
135 | #define TUNNEL_ID_MASK GENMASK(TUNNEL_ID_BITS - 1, 0) | |
136 | ||
60bd4af8 | 137 | enum { |
226f2ca3 VB |
138 | MLX5E_TC_FLAG_INGRESS_BIT, |
139 | MLX5E_TC_FLAG_EGRESS_BIT, | |
140 | MLX5E_TC_FLAG_NIC_OFFLOAD_BIT, | |
141 | MLX5E_TC_FLAG_ESW_OFFLOAD_BIT, | |
84179981 PB |
142 | MLX5E_TC_FLAG_FT_OFFLOAD_BIT, |
143 | MLX5E_TC_FLAG_LAST_EXPORTED_BIT = MLX5E_TC_FLAG_FT_OFFLOAD_BIT, | |
60bd4af8 OG |
144 | }; |
145 | ||
226f2ca3 VB |
146 | #define MLX5_TC_FLAG(flag) BIT(MLX5E_TC_FLAG_##flag##_BIT) |
147 | ||
655dc3d2 OG |
148 | int mlx5e_tc_esw_init(struct rhashtable *tc_ht); |
149 | void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht); | |
aedd133d | 150 | bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow); |
e8f887ac | 151 | |
71d82d2a | 152 | int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, |
226f2ca3 | 153 | struct flow_cls_offload *f, unsigned long flags); |
71d82d2a | 154 | int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv, |
226f2ca3 | 155 | struct flow_cls_offload *f, unsigned long flags); |
e3a2b7ed | 156 | |
71d82d2a | 157 | int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv, |
226f2ca3 | 158 | struct flow_cls_offload *f, unsigned long flags); |
aad7e08d | 159 | |
fcb64c0f EC |
160 | int mlx5e_tc_configure_matchall(struct mlx5e_priv *priv, |
161 | struct tc_cls_matchall_offload *f); | |
162 | int mlx5e_tc_delete_matchall(struct mlx5e_priv *priv, | |
163 | struct tc_cls_matchall_offload *f); | |
164 | void mlx5e_tc_stats_matchall(struct mlx5e_priv *priv, | |
165 | struct tc_cls_matchall_offload *ma); | |
166 | ||
232c0013 HHZ |
167 | struct mlx5e_encap_entry; |
168 | void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, | |
2a1f1768 VB |
169 | struct mlx5e_encap_entry *e, |
170 | struct list_head *flow_list); | |
232c0013 | 171 | void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv, |
2a1f1768 VB |
172 | struct mlx5e_encap_entry *e, |
173 | struct list_head *flow_list); | |
948993f2 VB |
174 | bool mlx5e_encap_take(struct mlx5e_encap_entry *e); |
175 | void mlx5e_encap_put(struct mlx5e_priv *priv, struct mlx5e_encap_entry *e); | |
232c0013 | 176 | |
2a1f1768 | 177 | void mlx5e_take_all_encap_flows(struct mlx5e_encap_entry *e, struct list_head *flow_list); |
021905f8 | 178 | void mlx5e_put_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list); |
2a1f1768 | 179 | |
f6dfb4c3 HHZ |
180 | struct mlx5e_neigh_hash_entry; |
181 | void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe); | |
182 | ||
b4a23329 | 183 | void mlx5e_tc_reoffload_flows_work(struct work_struct *work); |
f5bc2c5d | 184 | |
8f1e0b97 PB |
185 | enum mlx5e_tc_attr_to_reg { |
186 | CHAIN_TO_REG, | |
10742efc | 187 | VPORT_TO_REG, |
0a7fcb78 | 188 | TUNNEL_TO_REG, |
4c3844d9 PB |
189 | CTSTATE_TO_REG, |
190 | ZONE_TO_REG, | |
a8eb919b | 191 | ZONE_RESTORE_TO_REG, |
4c3844d9 PB |
192 | MARK_TO_REG, |
193 | LABELS_TO_REG, | |
194 | FTEID_TO_REG, | |
c7569097 | 195 | NIC_CHAIN_TO_REG, |
aedd133d | 196 | NIC_ZONE_RESTORE_TO_REG, |
8f1e0b97 PB |
197 | }; |
198 | ||
199 | struct mlx5e_tc_attr_to_reg_mapping { | |
200 | int mfield; /* rewrite field */ | |
ed2fe7ba PB |
201 | int moffset; /* bit offset of mfield */ |
202 | int mlen; /* bits to rewrite/match */ | |
0a7fcb78 | 203 | |
ed2fe7ba | 204 | int soffset; /* byte offset of spec for match */ |
8f1e0b97 PB |
205 | }; |
206 | ||
207 | extern struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[]; | |
208 | ||
f6dc1264 PB |
209 | bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv, |
210 | struct net_device *out_dev); | |
211 | ||
0a7fcb78 PB |
212 | int mlx5e_tc_match_to_reg_set(struct mlx5_core_dev *mdev, |
213 | struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, | |
aedd133d | 214 | enum mlx5_flow_namespace_type ns, |
0a7fcb78 PB |
215 | enum mlx5e_tc_attr_to_reg type, |
216 | u32 data); | |
217 | ||
c7b9038d VB |
218 | void mlx5e_tc_match_to_reg_mod_hdr_change(struct mlx5_core_dev *mdev, |
219 | struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, | |
220 | enum mlx5e_tc_attr_to_reg type, | |
221 | int act_id, u32 data); | |
222 | ||
0a7fcb78 PB |
223 | void mlx5e_tc_match_to_reg_match(struct mlx5_flow_spec *spec, |
224 | enum mlx5e_tc_attr_to_reg type, | |
225 | u32 data, | |
226 | u32 mask); | |
227 | ||
7e36feeb PB |
228 | void mlx5e_tc_match_to_reg_get_match(struct mlx5_flow_spec *spec, |
229 | enum mlx5e_tc_attr_to_reg type, | |
230 | u32 *data, | |
231 | u32 *mask); | |
232 | ||
c7b9038d VB |
233 | int mlx5e_tc_match_to_reg_set_and_get_id(struct mlx5_core_dev *mdev, |
234 | struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, | |
235 | enum mlx5_flow_namespace_type ns, | |
236 | enum mlx5e_tc_attr_to_reg type, | |
237 | u32 data); | |
238 | ||
239 | int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv, | |
240 | struct mlx5e_tc_flow_parse_attr *parse_attr, | |
241 | struct mlx5e_tc_flow *flow); | |
242 | ||
6ae4a6a5 PB |
243 | int alloc_mod_hdr_actions(struct mlx5_core_dev *mdev, |
244 | int namespace, | |
245 | struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); | |
246 | void dealloc_mod_hdr_actions(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); | |
247 | ||
4c3844d9 PB |
248 | struct mlx5e_tc_flow; |
249 | u32 mlx5e_tc_get_flow_tun_id(struct mlx5e_tc_flow *flow); | |
250 | ||
fca53304 EB |
251 | void mlx5e_tc_set_ethertype(struct mlx5_core_dev *mdev, |
252 | struct flow_match_basic *match, bool outer, | |
253 | void *headers_c, void *headers_v); | |
4a5d5d73 | 254 | |
d956873f VB |
255 | int mlx5e_tc_nic_init(struct mlx5e_priv *priv); |
256 | void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv); | |
257 | ||
e2394a61 VB |
258 | int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data, |
259 | void *cb_priv); | |
260 | ||
08247066 AL |
261 | struct mlx5_flow_handle * |
262 | mlx5e_add_offloaded_nic_rule(struct mlx5e_priv *priv, | |
263 | struct mlx5_flow_spec *spec, | |
c620b772 | 264 | struct mlx5_flow_attr *attr); |
08247066 | 265 | void mlx5e_del_offloaded_nic_rule(struct mlx5e_priv *priv, |
c7569097 AL |
266 | struct mlx5_flow_handle *rule, |
267 | struct mlx5_flow_attr *attr); | |
268 | ||
aedd133d AL |
269 | struct mlx5_flow_handle * |
270 | mlx5_tc_rule_insert(struct mlx5e_priv *priv, | |
271 | struct mlx5_flow_spec *spec, | |
272 | struct mlx5_flow_attr *attr); | |
273 | void | |
274 | mlx5_tc_rule_delete(struct mlx5e_priv *priv, | |
275 | struct mlx5_flow_handle *rule, | |
276 | struct mlx5_flow_attr *attr); | |
277 | ||
a508728a VB |
278 | bool mlx5e_tc_is_vf_tunnel(struct net_device *out_dev, struct net_device *route_dev); |
279 | int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *route_dev, | |
280 | u16 *vport); | |
281 | ||
d956873f VB |
282 | #else /* CONFIG_MLX5_CLS_ACT */ |
283 | static inline int mlx5e_tc_nic_init(struct mlx5e_priv *priv) { return 0; } | |
284 | static inline void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) {} | |
285 | static inline int | |
286 | mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) | |
287 | { return -EOPNOTSUPP; } | |
c7569097 | 288 | |
d956873f VB |
289 | #endif /* CONFIG_MLX5_CLS_ACT */ |
290 | ||
c620b772 AL |
291 | struct mlx5_flow_attr *mlx5_alloc_flow_attr(enum mlx5_flow_namespace_type type); |
292 | ||
aedd133d AL |
293 | struct mlx5_flow_handle * |
294 | mlx5e_add_offloaded_nic_rule(struct mlx5e_priv *priv, | |
295 | struct mlx5_flow_spec *spec, | |
296 | struct mlx5_flow_attr *attr); | |
297 | void mlx5e_del_offloaded_nic_rule(struct mlx5e_priv *priv, | |
298 | struct mlx5_flow_handle *rule, | |
299 | struct mlx5_flow_attr *attr); | |
300 | ||
e80541ec | 301 | #else /* CONFIG_MLX5_ESWITCH */ |
655dc3d2 OG |
302 | static inline int mlx5e_tc_nic_init(struct mlx5e_priv *priv) { return 0; } |
303 | static inline void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) {} | |
226f2ca3 VB |
304 | static inline int mlx5e_tc_num_filters(struct mlx5e_priv *priv, |
305 | unsigned long flags) | |
306 | { | |
307 | return 0; | |
308 | } | |
e2394a61 VB |
309 | |
310 | static inline int | |
311 | mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) | |
312 | { return -EOPNOTSUPP; } | |
e80541ec SM |
313 | #endif |
314 | ||
c7569097 AL |
315 | #if IS_ENABLED(CONFIG_MLX5_CLS_ACT) |
316 | static inline bool mlx5e_cqe_regb_chain(struct mlx5_cqe64 *cqe) | |
317 | { | |
318 | #if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) | |
319 | u32 chain, reg_b; | |
320 | ||
321 | reg_b = be32_to_cpu(cqe->ft_metadata); | |
322 | ||
48d216e5 | 323 | if (reg_b >> (MLX5E_TC_TABLE_CHAIN_TAG_BITS + ESW_ZONE_ID_BITS)) |
6248ce99 HN |
324 | return false; |
325 | ||
c7569097 AL |
326 | chain = reg_b & MLX5E_TC_TABLE_CHAIN_TAG_MASK; |
327 | if (chain) | |
328 | return true; | |
329 | #endif | |
330 | ||
331 | return false; | |
332 | } | |
333 | ||
334 | bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb); | |
335 | #else /* CONFIG_MLX5_CLS_ACT */ | |
336 | static inline bool mlx5e_cqe_regb_chain(struct mlx5_cqe64 *cqe) | |
337 | { return false; } | |
338 | static inline bool | |
339 | mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb) | |
340 | { return true; } | |
341 | #endif | |
342 | ||
e8f887ac | 343 | #endif /* __MLX5_EN_TC_H__ */ |