Commit | Line | Data |
---|---|---|
26a81453 MG |
1 | /* |
2 | * Copyright (c) 2015, 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 | #include <linux/mlx5/driver.h> | |
34 | #include <linux/mlx5/device.h> | |
35 | #include <linux/mlx5/mlx5_ifc.h> | |
36 | ||
37 | #include "fs_core.h" | |
38 | #include "fs_cmd.h" | |
39 | #include "mlx5_core.h" | |
c9f1b073 | 40 | #include "eswitch.h" |
26a81453 | 41 | |
ae288a48 | 42 | static int mlx5_cmd_stub_update_root_ft(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
43 | struct mlx5_flow_table *ft, |
44 | u32 underlay_qpn, | |
45 | bool disconnect) | |
46 | { | |
47 | return 0; | |
48 | } | |
49 | ||
ae288a48 MG |
50 | static int mlx5_cmd_stub_create_flow_table(struct mlx5_flow_root_namespace *ns, |
51 | struct mlx5_flow_table *ft, | |
af76c501 | 52 | unsigned int log_size, |
ae288a48 | 53 | struct mlx5_flow_table *next_ft) |
af76c501 MB |
54 | { |
55 | return 0; | |
56 | } | |
57 | ||
ae288a48 | 58 | static int mlx5_cmd_stub_destroy_flow_table(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
59 | struct mlx5_flow_table *ft) |
60 | { | |
61 | return 0; | |
62 | } | |
63 | ||
ae288a48 | 64 | static int mlx5_cmd_stub_modify_flow_table(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
65 | struct mlx5_flow_table *ft, |
66 | struct mlx5_flow_table *next_ft) | |
67 | { | |
68 | return 0; | |
69 | } | |
70 | ||
ae288a48 | 71 | static int mlx5_cmd_stub_create_flow_group(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
72 | struct mlx5_flow_table *ft, |
73 | u32 *in, | |
ae288a48 | 74 | struct mlx5_flow_group *fg) |
af76c501 MB |
75 | { |
76 | return 0; | |
77 | } | |
78 | ||
ae288a48 | 79 | static int mlx5_cmd_stub_destroy_flow_group(struct mlx5_flow_root_namespace *ns, |
af76c501 | 80 | struct mlx5_flow_table *ft, |
ae288a48 | 81 | struct mlx5_flow_group *fg) |
af76c501 MB |
82 | { |
83 | return 0; | |
84 | } | |
85 | ||
ae288a48 | 86 | static int mlx5_cmd_stub_create_fte(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
87 | struct mlx5_flow_table *ft, |
88 | struct mlx5_flow_group *group, | |
89 | struct fs_fte *fte) | |
90 | { | |
91 | return 0; | |
92 | } | |
93 | ||
ae288a48 | 94 | static int mlx5_cmd_stub_update_fte(struct mlx5_flow_root_namespace *ns, |
af76c501 | 95 | struct mlx5_flow_table *ft, |
ae288a48 | 96 | struct mlx5_flow_group *group, |
af76c501 MB |
97 | int modify_mask, |
98 | struct fs_fte *fte) | |
99 | { | |
100 | return -EOPNOTSUPP; | |
101 | } | |
102 | ||
ae288a48 | 103 | static int mlx5_cmd_stub_delete_fte(struct mlx5_flow_root_namespace *ns, |
af76c501 | 104 | struct mlx5_flow_table *ft, |
e810bf5e | 105 | struct fs_fte *fte) |
af76c501 MB |
106 | { |
107 | return 0; | |
108 | } | |
109 | ||
2b688ea5 MG |
110 | static int mlx5_cmd_stub_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns, |
111 | int reformat_type, | |
112 | size_t size, | |
113 | void *reformat_data, | |
114 | enum mlx5_flow_namespace_type namespace, | |
115 | struct mlx5_pkt_reformat *pkt_reformat) | |
116 | { | |
117 | return 0; | |
118 | } | |
119 | ||
120 | static void mlx5_cmd_stub_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns, | |
121 | struct mlx5_pkt_reformat *pkt_reformat) | |
122 | { | |
123 | } | |
124 | ||
125 | static int mlx5_cmd_stub_modify_header_alloc(struct mlx5_flow_root_namespace *ns, | |
126 | u8 namespace, u8 num_actions, | |
127 | void *modify_actions, | |
128 | struct mlx5_modify_hdr *modify_hdr) | |
129 | { | |
130 | return 0; | |
131 | } | |
132 | ||
133 | static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace *ns, | |
134 | struct mlx5_modify_hdr *modify_hdr) | |
135 | { | |
136 | } | |
137 | ||
6a48faee MG |
138 | static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns, |
139 | struct mlx5_flow_root_namespace *peer_ns) | |
140 | { | |
141 | return 0; | |
142 | } | |
143 | ||
144 | static int mlx5_cmd_stub_create_ns(struct mlx5_flow_root_namespace *ns) | |
145 | { | |
146 | return 0; | |
147 | } | |
148 | ||
149 | static int mlx5_cmd_stub_destroy_ns(struct mlx5_flow_root_namespace *ns) | |
150 | { | |
151 | return 0; | |
152 | } | |
153 | ||
ae288a48 | 154 | static int mlx5_cmd_update_root_ft(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
155 | struct mlx5_flow_table *ft, u32 underlay_qpn, |
156 | bool disconnect) | |
2cc43b49 | 157 | { |
c4f287c4 SM |
158 | u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {0}; |
159 | u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {0}; | |
ae288a48 | 160 | struct mlx5_core_dev *dev = ns->dev; |
2cc43b49 | 161 | |
b3ba5149 | 162 | if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) && |
50854114 | 163 | underlay_qpn == 0) |
b3ba5149 ES |
164 | return 0; |
165 | ||
2cc43b49 MG |
166 | MLX5_SET(set_flow_table_root_in, in, opcode, |
167 | MLX5_CMD_OP_SET_FLOW_TABLE_ROOT); | |
168 | MLX5_SET(set_flow_table_root_in, in, table_type, ft->type); | |
dae37456 AV |
169 | |
170 | if (disconnect) { | |
171 | MLX5_SET(set_flow_table_root_in, in, op_mod, 1); | |
172 | MLX5_SET(set_flow_table_root_in, in, table_id, 0); | |
173 | } else { | |
174 | MLX5_SET(set_flow_table_root_in, in, op_mod, 0); | |
175 | MLX5_SET(set_flow_table_root_in, in, table_id, ft->id); | |
176 | } | |
177 | ||
50854114 | 178 | MLX5_SET(set_flow_table_root_in, in, underlay_qpn, underlay_qpn); |
efdc810b MHY |
179 | if (ft->vport) { |
180 | MLX5_SET(set_flow_table_root_in, in, vport_number, ft->vport); | |
181 | MLX5_SET(set_flow_table_root_in, in, other_vport, 1); | |
182 | } | |
2cc43b49 | 183 | |
c4f287c4 | 184 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
2cc43b49 MG |
185 | } |
186 | ||
ae288a48 MG |
187 | static int mlx5_cmd_create_flow_table(struct mlx5_flow_root_namespace *ns, |
188 | struct mlx5_flow_table *ft, | |
af76c501 | 189 | unsigned int log_size, |
ae288a48 | 190 | struct mlx5_flow_table *next_ft) |
26a81453 | 191 | { |
ae288a48 MG |
192 | int en_encap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT); |
193 | int en_decap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_DECAP); | |
c6d4e45d | 194 | int term = !!(ft->flags & MLX5_FLOW_TABLE_TERMINATION); |
c4f287c4 SM |
195 | u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0}; |
196 | u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {0}; | |
ae288a48 | 197 | struct mlx5_core_dev *dev = ns->dev; |
26a81453 MG |
198 | int err; |
199 | ||
26a81453 MG |
200 | MLX5_SET(create_flow_table_in, in, opcode, |
201 | MLX5_CMD_OP_CREATE_FLOW_TABLE); | |
202 | ||
ae288a48 MG |
203 | MLX5_SET(create_flow_table_in, in, table_type, ft->type); |
204 | MLX5_SET(create_flow_table_in, in, flow_table_context.level, ft->level); | |
0c90e9c6 | 205 | MLX5_SET(create_flow_table_in, in, flow_table_context.log_size, log_size); |
ae288a48 MG |
206 | if (ft->vport) { |
207 | MLX5_SET(create_flow_table_in, in, vport_number, ft->vport); | |
efdc810b MHY |
208 | MLX5_SET(create_flow_table_in, in, other_vport, 1); |
209 | } | |
26a81453 | 210 | |
0c90e9c6 | 211 | MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en, |
61444b45 | 212 | en_decap); |
60786f09 | 213 | MLX5_SET(create_flow_table_in, in, flow_table_context.reformat_en, |
61444b45 | 214 | en_encap); |
c6d4e45d EB |
215 | MLX5_SET(create_flow_table_in, in, flow_table_context.termination_table, |
216 | term); | |
c9f1b073 | 217 | |
ae288a48 | 218 | switch (ft->op_mod) { |
aaff1bea AH |
219 | case FS_FT_OP_MOD_NORMAL: |
220 | if (next_ft) { | |
0c90e9c6 | 221 | MLX5_SET(create_flow_table_in, in, |
f6f7d6b5 MG |
222 | flow_table_context.table_miss_action, |
223 | MLX5_FLOW_TABLE_MISS_ACTION_FWD); | |
0c90e9c6 MG |
224 | MLX5_SET(create_flow_table_in, in, |
225 | flow_table_context.table_miss_id, next_ft->id); | |
f6f7d6b5 MG |
226 | } else { |
227 | MLX5_SET(create_flow_table_in, in, | |
228 | flow_table_context.table_miss_action, | |
f66ad830 | 229 | ft->def_miss_action); |
aaff1bea AH |
230 | } |
231 | break; | |
232 | ||
233 | case FS_FT_OP_MOD_LAG_DEMUX: | |
234 | MLX5_SET(create_flow_table_in, in, op_mod, 0x1); | |
235 | if (next_ft) | |
0c90e9c6 MG |
236 | MLX5_SET(create_flow_table_in, in, |
237 | flow_table_context.lag_master_next_table_id, | |
aaff1bea AH |
238 | next_ft->id); |
239 | break; | |
240 | } | |
241 | ||
c4f287c4 | 242 | err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
26a81453 | 243 | if (!err) |
ae288a48 MG |
244 | ft->id = MLX5_GET(create_flow_table_out, out, |
245 | table_id); | |
26a81453 MG |
246 | return err; |
247 | } | |
248 | ||
ae288a48 | 249 | static int mlx5_cmd_destroy_flow_table(struct mlx5_flow_root_namespace *ns, |
af76c501 | 250 | struct mlx5_flow_table *ft) |
26a81453 | 251 | { |
c4f287c4 SM |
252 | u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {0}; |
253 | u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)] = {0}; | |
ae288a48 | 254 | struct mlx5_core_dev *dev = ns->dev; |
26a81453 MG |
255 | |
256 | MLX5_SET(destroy_flow_table_in, in, opcode, | |
257 | MLX5_CMD_OP_DESTROY_FLOW_TABLE); | |
258 | MLX5_SET(destroy_flow_table_in, in, table_type, ft->type); | |
259 | MLX5_SET(destroy_flow_table_in, in, table_id, ft->id); | |
efdc810b MHY |
260 | if (ft->vport) { |
261 | MLX5_SET(destroy_flow_table_in, in, vport_number, ft->vport); | |
262 | MLX5_SET(destroy_flow_table_in, in, other_vport, 1); | |
263 | } | |
26a81453 | 264 | |
c4f287c4 | 265 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
26a81453 MG |
266 | } |
267 | ||
ae288a48 | 268 | static int mlx5_cmd_modify_flow_table(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
269 | struct mlx5_flow_table *ft, |
270 | struct mlx5_flow_table *next_ft) | |
34a40e68 | 271 | { |
c4f287c4 SM |
272 | u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0}; |
273 | u32 out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0}; | |
ae288a48 | 274 | struct mlx5_core_dev *dev = ns->dev; |
34a40e68 MG |
275 | |
276 | MLX5_SET(modify_flow_table_in, in, opcode, | |
277 | MLX5_CMD_OP_MODIFY_FLOW_TABLE); | |
278 | MLX5_SET(modify_flow_table_in, in, table_type, ft->type); | |
279 | MLX5_SET(modify_flow_table_in, in, table_id, ft->id); | |
aaff1bea AH |
280 | |
281 | if (ft->op_mod == FS_FT_OP_MOD_LAG_DEMUX) { | |
282 | MLX5_SET(modify_flow_table_in, in, modify_field_select, | |
283 | MLX5_MODIFY_FLOW_TABLE_LAG_NEXT_TABLE_ID); | |
284 | if (next_ft) { | |
285 | MLX5_SET(modify_flow_table_in, in, | |
0c90e9c6 | 286 | flow_table_context.lag_master_next_table_id, next_ft->id); |
aaff1bea AH |
287 | } else { |
288 | MLX5_SET(modify_flow_table_in, in, | |
0c90e9c6 | 289 | flow_table_context.lag_master_next_table_id, 0); |
aaff1bea | 290 | } |
34a40e68 | 291 | } else { |
aaff1bea AH |
292 | if (ft->vport) { |
293 | MLX5_SET(modify_flow_table_in, in, vport_number, | |
294 | ft->vport); | |
295 | MLX5_SET(modify_flow_table_in, in, other_vport, 1); | |
296 | } | |
297 | MLX5_SET(modify_flow_table_in, in, modify_field_select, | |
298 | MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID); | |
299 | if (next_ft) { | |
0c90e9c6 | 300 | MLX5_SET(modify_flow_table_in, in, |
f6f7d6b5 MG |
301 | flow_table_context.table_miss_action, |
302 | MLX5_FLOW_TABLE_MISS_ACTION_FWD); | |
0c90e9c6 MG |
303 | MLX5_SET(modify_flow_table_in, in, |
304 | flow_table_context.table_miss_id, | |
aaff1bea AH |
305 | next_ft->id); |
306 | } else { | |
0c90e9c6 | 307 | MLX5_SET(modify_flow_table_in, in, |
f6f7d6b5 | 308 | flow_table_context.table_miss_action, |
f66ad830 | 309 | ft->def_miss_action); |
aaff1bea | 310 | } |
34a40e68 MG |
311 | } |
312 | ||
c4f287c4 | 313 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
34a40e68 MG |
314 | } |
315 | ||
ae288a48 | 316 | static int mlx5_cmd_create_flow_group(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
317 | struct mlx5_flow_table *ft, |
318 | u32 *in, | |
ae288a48 | 319 | struct mlx5_flow_group *fg) |
26a81453 | 320 | { |
c4f287c4 | 321 | u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0}; |
26a81453 | 322 | int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); |
ae288a48 | 323 | struct mlx5_core_dev *dev = ns->dev; |
26a81453 MG |
324 | int err; |
325 | ||
26a81453 MG |
326 | MLX5_SET(create_flow_group_in, in, opcode, |
327 | MLX5_CMD_OP_CREATE_FLOW_GROUP); | |
328 | MLX5_SET(create_flow_group_in, in, table_type, ft->type); | |
329 | MLX5_SET(create_flow_group_in, in, table_id, ft->id); | |
efdc810b MHY |
330 | if (ft->vport) { |
331 | MLX5_SET(create_flow_group_in, in, vport_number, ft->vport); | |
332 | MLX5_SET(create_flow_group_in, in, other_vport, 1); | |
333 | } | |
26a81453 | 334 | |
c4f287c4 | 335 | err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); |
26a81453 | 336 | if (!err) |
ae288a48 MG |
337 | fg->id = MLX5_GET(create_flow_group_out, out, |
338 | group_id); | |
26a81453 MG |
339 | return err; |
340 | } | |
341 | ||
ae288a48 | 342 | static int mlx5_cmd_destroy_flow_group(struct mlx5_flow_root_namespace *ns, |
af76c501 | 343 | struct mlx5_flow_table *ft, |
ae288a48 | 344 | struct mlx5_flow_group *fg) |
26a81453 | 345 | { |
c4f287c4 SM |
346 | u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)] = {0}; |
347 | u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {0}; | |
ae288a48 | 348 | struct mlx5_core_dev *dev = ns->dev; |
26a81453 MG |
349 | |
350 | MLX5_SET(destroy_flow_group_in, in, opcode, | |
351 | MLX5_CMD_OP_DESTROY_FLOW_GROUP); | |
352 | MLX5_SET(destroy_flow_group_in, in, table_type, ft->type); | |
353 | MLX5_SET(destroy_flow_group_in, in, table_id, ft->id); | |
ae288a48 | 354 | MLX5_SET(destroy_flow_group_in, in, group_id, fg->id); |
efdc810b MHY |
355 | if (ft->vport) { |
356 | MLX5_SET(destroy_flow_group_in, in, vport_number, ft->vport); | |
357 | MLX5_SET(destroy_flow_group_in, in, other_vport, 1); | |
358 | } | |
26a81453 | 359 | |
c4f287c4 | 360 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
26a81453 MG |
361 | } |
362 | ||
a2c6162b EB |
363 | static int mlx5_set_extended_dest(struct mlx5_core_dev *dev, |
364 | struct fs_fte *fte, bool *extended_dest) | |
365 | { | |
366 | int fw_log_max_fdb_encap_uplink = | |
367 | MLX5_CAP_ESW(dev, log_max_fdb_encap_uplink); | |
368 | int num_fwd_destinations = 0; | |
369 | struct mlx5_flow_rule *dst; | |
370 | int num_encap = 0; | |
371 | ||
372 | *extended_dest = false; | |
373 | if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)) | |
374 | return 0; | |
375 | ||
376 | list_for_each_entry(dst, &fte->node.children, node.list) { | |
377 | if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER) | |
378 | continue; | |
379 | if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_VPORT && | |
380 | dst->dest_attr.vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID) | |
381 | num_encap++; | |
382 | num_fwd_destinations++; | |
383 | } | |
384 | if (num_fwd_destinations > 1 && num_encap > 0) | |
385 | *extended_dest = true; | |
386 | ||
387 | if (*extended_dest && !fw_log_max_fdb_encap_uplink) { | |
388 | mlx5_core_warn(dev, "FW does not support extended destination"); | |
389 | return -EOPNOTSUPP; | |
390 | } | |
391 | if (num_encap > (1 << fw_log_max_fdb_encap_uplink)) { | |
392 | mlx5_core_warn(dev, "FW does not support more than %d encaps", | |
393 | 1 << fw_log_max_fdb_encap_uplink); | |
394 | return -EOPNOTSUPP; | |
395 | } | |
396 | ||
397 | return 0; | |
398 | } | |
26a81453 MG |
399 | static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, |
400 | int opmod, int modify_mask, | |
401 | struct mlx5_flow_table *ft, | |
402 | unsigned group_id, | |
403 | struct fs_fte *fte) | |
404 | { | |
c4f287c4 | 405 | u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {0}; |
a2c6162b | 406 | bool extended_dest = false; |
26a81453 | 407 | struct mlx5_flow_rule *dst; |
0c06897a | 408 | void *in_flow_context, *vlan; |
26a81453 | 409 | void *in_match_value; |
a2c6162b EB |
410 | unsigned int inlen; |
411 | int dst_cnt_size; | |
26a81453 MG |
412 | void *in_dests; |
413 | u32 *in; | |
414 | int err; | |
415 | ||
a2c6162b EB |
416 | if (mlx5_set_extended_dest(dev, fte, &extended_dest)) |
417 | return -EOPNOTSUPP; | |
418 | ||
419 | if (!extended_dest) | |
420 | dst_cnt_size = MLX5_ST_SZ_BYTES(dest_format_struct); | |
421 | else | |
422 | dst_cnt_size = MLX5_ST_SZ_BYTES(extended_dest_format); | |
423 | ||
424 | inlen = MLX5_ST_SZ_BYTES(set_fte_in) + fte->dests_size * dst_cnt_size; | |
1b9a07ee LR |
425 | in = kvzalloc(inlen, GFP_KERNEL); |
426 | if (!in) | |
26a81453 | 427 | return -ENOMEM; |
26a81453 MG |
428 | |
429 | MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY); | |
430 | MLX5_SET(set_fte_in, in, op_mod, opmod); | |
431 | MLX5_SET(set_fte_in, in, modify_enable_mask, modify_mask); | |
432 | MLX5_SET(set_fte_in, in, table_type, ft->type); | |
433 | MLX5_SET(set_fte_in, in, table_id, ft->id); | |
434 | MLX5_SET(set_fte_in, in, flow_index, fte->index); | |
ff189b43 PB |
435 | MLX5_SET(set_fte_in, in, ignore_flow_level, |
436 | !!(fte->action.flags & FLOW_ACT_IGNORE_FLOW_LEVEL)); | |
437 | ||
efdc810b MHY |
438 | if (ft->vport) { |
439 | MLX5_SET(set_fte_in, in, vport_number, ft->vport); | |
440 | MLX5_SET(set_fte_in, in, other_vport, 1); | |
441 | } | |
26a81453 MG |
442 | |
443 | in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); | |
444 | MLX5_SET(flow_context, in_flow_context, group_id, group_id); | |
0c06897a | 445 | |
bb0ee7dc JL |
446 | MLX5_SET(flow_context, in_flow_context, flow_tag, |
447 | fte->flow_context.flow_tag); | |
8d212ff0 JL |
448 | MLX5_SET(flow_context, in_flow_context, flow_source, |
449 | fte->flow_context.flow_source); | |
450 | ||
a2c6162b EB |
451 | MLX5_SET(flow_context, in_flow_context, extended_destination, |
452 | extended_dest); | |
453 | if (extended_dest) { | |
454 | u32 action; | |
455 | ||
456 | action = fte->action.action & | |
457 | ~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; | |
458 | MLX5_SET(flow_context, in_flow_context, action, action); | |
459 | } else { | |
460 | MLX5_SET(flow_context, in_flow_context, action, | |
461 | fte->action.action); | |
2b688ea5 MG |
462 | if (fte->action.pkt_reformat) |
463 | MLX5_SET(flow_context, in_flow_context, packet_reformat_id, | |
464 | fte->action.pkt_reformat->id); | |
a2c6162b | 465 | } |
2b688ea5 MG |
466 | if (fte->action.modify_hdr) |
467 | MLX5_SET(flow_context, in_flow_context, modify_header_id, | |
468 | fte->action.modify_hdr->id); | |
0c06897a OG |
469 | |
470 | vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan); | |
471 | ||
8da6fe2a JL |
472 | MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[0].ethtype); |
473 | MLX5_SET(vlan, vlan, vid, fte->action.vlan[0].vid); | |
474 | MLX5_SET(vlan, vlan, prio, fte->action.vlan[0].prio); | |
475 | ||
476 | vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan_2); | |
477 | ||
478 | MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[1].ethtype); | |
479 | MLX5_SET(vlan, vlan, vid, fte->action.vlan[1].vid); | |
480 | MLX5_SET(vlan, vlan, prio, fte->action.vlan[1].prio); | |
0c06897a | 481 | |
26a81453 MG |
482 | in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context, |
483 | match_value); | |
667cb65a | 484 | memcpy(in_match_value, &fte->val, sizeof(fte->val)); |
26a81453 | 485 | |
bd5251db | 486 | in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); |
d2ec6a35 | 487 | if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { |
bd5251db AV |
488 | int list_size = 0; |
489 | ||
60ab4584 | 490 | list_for_each_entry(dst, &fte->node.children, node.list) { |
664000b6 | 491 | unsigned int id, type = dst->dest_attr.type; |
60ab4584 | 492 | |
664000b6 | 493 | if (type == MLX5_FLOW_DESTINATION_TYPE_COUNTER) |
bd5251db AV |
494 | continue; |
495 | ||
664000b6 YH |
496 | switch (type) { |
497 | case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM: | |
498 | id = dst->dest_attr.ft_num; | |
499 | type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; | |
500 | break; | |
501 | case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: | |
60ab4584 | 502 | id = dst->dest_attr.ft->id; |
664000b6 YH |
503 | break; |
504 | case MLX5_FLOW_DESTINATION_TYPE_VPORT: | |
b17f7fc1 SK |
505 | id = dst->dest_attr.vport.num; |
506 | MLX5_SET(dest_format_struct, in_dests, | |
507 | destination_eswitch_owner_vhca_id_valid, | |
aa39c2c0 EB |
508 | !!(dst->dest_attr.vport.flags & |
509 | MLX5_FLOW_DEST_VPORT_VHCA_ID)); | |
b17f7fc1 SK |
510 | MLX5_SET(dest_format_struct, in_dests, |
511 | destination_eswitch_owner_vhca_id, | |
512 | dst->dest_attr.vport.vhca_id); | |
0fd79b1e EB |
513 | if (extended_dest && |
514 | dst->dest_attr.vport.pkt_reformat) { | |
a2c6162b EB |
515 | MLX5_SET(dest_format_struct, in_dests, |
516 | packet_reformat, | |
517 | !!(dst->dest_attr.vport.flags & | |
518 | MLX5_FLOW_DEST_VPORT_REFORMAT_ID)); | |
519 | MLX5_SET(extended_dest_format, in_dests, | |
520 | packet_reformat_id, | |
2b688ea5 | 521 | dst->dest_attr.vport.pkt_reformat->id); |
a2c6162b | 522 | } |
664000b6 YH |
523 | break; |
524 | default: | |
60ab4584 AV |
525 | id = dst->dest_attr.tir_num; |
526 | } | |
664000b6 YH |
527 | |
528 | MLX5_SET(dest_format_struct, in_dests, destination_type, | |
529 | type); | |
60ab4584 | 530 | MLX5_SET(dest_format_struct, in_dests, destination_id, id); |
a2c6162b | 531 | in_dests += dst_cnt_size; |
bd5251db AV |
532 | list_size++; |
533 | } | |
534 | ||
535 | MLX5_SET(flow_context, in_flow_context, destination_list_size, | |
536 | list_size); | |
537 | } | |
538 | ||
d2ec6a35 | 539 | if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { |
16f1c5bb RS |
540 | int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev, |
541 | log_max_flow_counter, | |
542 | ft->type)); | |
bd5251db AV |
543 | int list_size = 0; |
544 | ||
545 | list_for_each_entry(dst, &fte->node.children, node.list) { | |
546 | if (dst->dest_attr.type != | |
547 | MLX5_FLOW_DESTINATION_TYPE_COUNTER) | |
548 | continue; | |
549 | ||
550 | MLX5_SET(flow_counter_list, in_dests, flow_counter_id, | |
171c7625 | 551 | dst->dest_attr.counter_id); |
a2c6162b | 552 | in_dests += dst_cnt_size; |
bd5251db | 553 | list_size++; |
60ab4584 | 554 | } |
16f1c5bb RS |
555 | if (list_size > max_list_size) { |
556 | err = -EINVAL; | |
557 | goto err_out; | |
558 | } | |
bd5251db AV |
559 | |
560 | MLX5_SET(flow_context, in_flow_context, flow_counter_list_size, | |
561 | list_size); | |
26a81453 | 562 | } |
bd5251db | 563 | |
c4f287c4 | 564 | err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); |
16f1c5bb | 565 | err_out: |
26a81453 | 566 | kvfree(in); |
26a81453 MG |
567 | return err; |
568 | } | |
569 | ||
ae288a48 | 570 | static int mlx5_cmd_create_fte(struct mlx5_flow_root_namespace *ns, |
af76c501 MB |
571 | struct mlx5_flow_table *ft, |
572 | struct mlx5_flow_group *group, | |
573 | struct fs_fte *fte) | |
26a81453 | 574 | { |
ae288a48 | 575 | struct mlx5_core_dev *dev = ns->dev; |
af76c501 MB |
576 | unsigned int group_id = group->id; |
577 | ||
c4f287c4 | 578 | return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte); |
26a81453 MG |
579 | } |
580 | ||
ae288a48 | 581 | static int mlx5_cmd_update_fte(struct mlx5_flow_root_namespace *ns, |
af76c501 | 582 | struct mlx5_flow_table *ft, |
ae288a48 | 583 | struct mlx5_flow_group *fg, |
af76c501 MB |
584 | int modify_mask, |
585 | struct fs_fte *fte) | |
26a81453 MG |
586 | { |
587 | int opmod; | |
ae288a48 | 588 | struct mlx5_core_dev *dev = ns->dev; |
26a81453 MG |
589 | int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev, |
590 | flow_table_properties_nic_receive. | |
591 | flow_modify_en); | |
592 | if (!atomic_mod_cap) | |
9eb78923 | 593 | return -EOPNOTSUPP; |
26a81453 | 594 | opmod = 1; |
26a81453 | 595 | |
ae288a48 | 596 | return mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, fg->id, fte); |
26a81453 MG |
597 | } |
598 | ||
ae288a48 | 599 | static int mlx5_cmd_delete_fte(struct mlx5_flow_root_namespace *ns, |
af76c501 | 600 | struct mlx5_flow_table *ft, |
e810bf5e | 601 | struct fs_fte *fte) |
26a81453 | 602 | { |
c4f287c4 SM |
603 | u32 out[MLX5_ST_SZ_DW(delete_fte_out)] = {0}; |
604 | u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {0}; | |
ae288a48 | 605 | struct mlx5_core_dev *dev = ns->dev; |
26a81453 MG |
606 | |
607 | MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); | |
608 | MLX5_SET(delete_fte_in, in, table_type, ft->type); | |
609 | MLX5_SET(delete_fte_in, in, table_id, ft->id); | |
e810bf5e | 610 | MLX5_SET(delete_fte_in, in, flow_index, fte->index); |
efdc810b MHY |
611 | if (ft->vport) { |
612 | MLX5_SET(delete_fte_in, in, vport_number, ft->vport); | |
613 | MLX5_SET(delete_fte_in, in, other_vport, 1); | |
614 | } | |
26a81453 | 615 | |
c4f287c4 | 616 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
26a81453 | 617 | } |
9dc0b289 | 618 | |
8536a6bf GT |
619 | int mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, |
620 | enum mlx5_fc_bulk_alloc_bitmask alloc_bitmask, | |
621 | u32 *id) | |
9dc0b289 | 622 | { |
c4f287c4 SM |
623 | u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {0}; |
624 | u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0}; | |
9dc0b289 AV |
625 | int err; |
626 | ||
9dc0b289 AV |
627 | MLX5_SET(alloc_flow_counter_in, in, opcode, |
628 | MLX5_CMD_OP_ALLOC_FLOW_COUNTER); | |
8536a6bf | 629 | MLX5_SET(alloc_flow_counter_in, in, flow_counter_bulk, alloc_bitmask); |
9dc0b289 | 630 | |
c4f287c4 SM |
631 | err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
632 | if (!err) | |
633 | *id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id); | |
634 | return err; | |
9dc0b289 AV |
635 | } |
636 | ||
8536a6bf GT |
637 | int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id) |
638 | { | |
639 | return mlx5_cmd_fc_bulk_alloc(dev, 0, id); | |
640 | } | |
641 | ||
a8ffcc74 | 642 | int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id) |
9dc0b289 | 643 | { |
c4f287c4 SM |
644 | u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)] = {0}; |
645 | u32 out[MLX5_ST_SZ_DW(dealloc_flow_counter_out)] = {0}; | |
9dc0b289 AV |
646 | |
647 | MLX5_SET(dealloc_flow_counter_in, in, opcode, | |
648 | MLX5_CMD_OP_DEALLOC_FLOW_COUNTER); | |
649 | MLX5_SET(dealloc_flow_counter_in, in, flow_counter_id, id); | |
c4f287c4 | 650 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
9dc0b289 AV |
651 | } |
652 | ||
a8ffcc74 | 653 | int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u32 id, |
9dc0b289 AV |
654 | u64 *packets, u64 *bytes) |
655 | { | |
656 | u32 out[MLX5_ST_SZ_BYTES(query_flow_counter_out) + | |
c4f287c4 SM |
657 | MLX5_ST_SZ_BYTES(traffic_counter)] = {0}; |
658 | u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0}; | |
9dc0b289 AV |
659 | void *stats; |
660 | int err = 0; | |
661 | ||
9dc0b289 AV |
662 | MLX5_SET(query_flow_counter_in, in, opcode, |
663 | MLX5_CMD_OP_QUERY_FLOW_COUNTER); | |
664 | MLX5_SET(query_flow_counter_in, in, op_mod, 0); | |
665 | MLX5_SET(query_flow_counter_in, in, flow_counter_id, id); | |
c4f287c4 | 666 | err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
9dc0b289 AV |
667 | if (err) |
668 | return err; | |
669 | ||
670 | stats = MLX5_ADDR_OF(query_flow_counter_out, out, flow_statistics); | |
671 | *packets = MLX5_GET64(traffic_counter, stats, packets); | |
672 | *bytes = MLX5_GET64(traffic_counter, stats, octets); | |
9dc0b289 AV |
673 | return 0; |
674 | } | |
a351a1b0 | 675 | |
6f06e04b | 676 | int mlx5_cmd_fc_get_bulk_query_out_len(int bulk_len) |
a351a1b0 | 677 | { |
6f06e04b GT |
678 | return MLX5_ST_SZ_BYTES(query_flow_counter_out) + |
679 | MLX5_ST_SZ_BYTES(traffic_counter) * bulk_len; | |
a351a1b0 AV |
680 | } |
681 | ||
6f06e04b GT |
682 | int mlx5_cmd_fc_bulk_query(struct mlx5_core_dev *dev, u32 base_id, int bulk_len, |
683 | u32 *out) | |
a351a1b0 | 684 | { |
6f06e04b | 685 | int outlen = mlx5_cmd_fc_get_bulk_query_out_len(bulk_len); |
c4f287c4 | 686 | u32 in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0}; |
a351a1b0 AV |
687 | |
688 | MLX5_SET(query_flow_counter_in, in, opcode, | |
689 | MLX5_CMD_OP_QUERY_FLOW_COUNTER); | |
690 | MLX5_SET(query_flow_counter_in, in, op_mod, 0); | |
6f06e04b GT |
691 | MLX5_SET(query_flow_counter_in, in, flow_counter_id, base_id); |
692 | MLX5_SET(query_flow_counter_in, in, num_of_counters, bulk_len); | |
693 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); | |
a351a1b0 | 694 | } |
575ddf58 | 695 | |
2b688ea5 MG |
696 | static int mlx5_cmd_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns, |
697 | int reformat_type, | |
698 | size_t size, | |
699 | void *reformat_data, | |
700 | enum mlx5_flow_namespace_type namespace, | |
701 | struct mlx5_pkt_reformat *pkt_reformat) | |
575ddf58 | 702 | { |
60786f09 | 703 | u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)]; |
2b688ea5 | 704 | struct mlx5_core_dev *dev = ns->dev; |
60786f09 | 705 | void *packet_reformat_context_in; |
31ca3648 | 706 | int max_encap_size; |
60786f09 | 707 | void *reformat; |
43f93839 | 708 | int inlen; |
575ddf58 | 709 | int err; |
43f93839 | 710 | u32 *in; |
575ddf58 | 711 | |
31ca3648 MB |
712 | if (namespace == MLX5_FLOW_NAMESPACE_FDB) |
713 | max_encap_size = MLX5_CAP_ESW(dev, max_encap_header_size); | |
714 | else | |
715 | max_encap_size = MLX5_CAP_FLOWTABLE(dev, max_encap_header_size); | |
716 | ||
073ff3c8 OG |
717 | if (size > max_encap_size) { |
718 | mlx5_core_warn(dev, "encap size %zd too big, max supported is %d\n", | |
719 | size, max_encap_size); | |
575ddf58 | 720 | return -EINVAL; |
073ff3c8 | 721 | } |
575ddf58 | 722 | |
60786f09 | 723 | in = kzalloc(MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in) + size, |
43f93839 HHZ |
724 | GFP_KERNEL); |
725 | if (!in) | |
726 | return -ENOMEM; | |
727 | ||
60786f09 MB |
728 | packet_reformat_context_in = MLX5_ADDR_OF(alloc_packet_reformat_context_in, |
729 | in, packet_reformat_context); | |
730 | reformat = MLX5_ADDR_OF(packet_reformat_context_in, | |
731 | packet_reformat_context_in, | |
732 | reformat_data); | |
733 | inlen = reformat - (void *)in + size; | |
43f93839 | 734 | |
575ddf58 | 735 | memset(in, 0, inlen); |
60786f09 MB |
736 | MLX5_SET(alloc_packet_reformat_context_in, in, opcode, |
737 | MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT); | |
738 | MLX5_SET(packet_reformat_context_in, packet_reformat_context_in, | |
739 | reformat_data_size, size); | |
740 | MLX5_SET(packet_reformat_context_in, packet_reformat_context_in, | |
741 | reformat_type, reformat_type); | |
742 | memcpy(reformat, reformat_data, size); | |
575ddf58 IL |
743 | |
744 | memset(out, 0, sizeof(out)); | |
745 | err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); | |
746 | ||
2b688ea5 MG |
747 | pkt_reformat->id = MLX5_GET(alloc_packet_reformat_context_out, |
748 | out, packet_reformat_id); | |
43f93839 | 749 | kfree(in); |
575ddf58 IL |
750 | return err; |
751 | } | |
752 | ||
2b688ea5 MG |
753 | static void mlx5_cmd_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns, |
754 | struct mlx5_pkt_reformat *pkt_reformat) | |
575ddf58 | 755 | { |
60786f09 MB |
756 | u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)]; |
757 | u32 out[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_out)]; | |
2b688ea5 | 758 | struct mlx5_core_dev *dev = ns->dev; |
575ddf58 IL |
759 | |
760 | memset(in, 0, sizeof(in)); | |
60786f09 MB |
761 | MLX5_SET(dealloc_packet_reformat_context_in, in, opcode, |
762 | MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT); | |
763 | MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id, | |
2b688ea5 | 764 | pkt_reformat->id); |
575ddf58 IL |
765 | |
766 | mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | |
767 | } | |
2de24fed | 768 | |
2b688ea5 MG |
769 | static int mlx5_cmd_modify_header_alloc(struct mlx5_flow_root_namespace *ns, |
770 | u8 namespace, u8 num_actions, | |
771 | void *modify_actions, | |
772 | struct mlx5_modify_hdr *modify_hdr) | |
2de24fed OG |
773 | { |
774 | u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)]; | |
775 | int max_actions, actions_size, inlen, err; | |
2b688ea5 | 776 | struct mlx5_core_dev *dev = ns->dev; |
2de24fed OG |
777 | void *actions_in; |
778 | u8 table_type; | |
779 | u32 *in; | |
780 | ||
781 | switch (namespace) { | |
782 | case MLX5_FLOW_NAMESPACE_FDB: | |
783 | max_actions = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, max_modify_header_actions); | |
784 | table_type = FS_FT_FDB; | |
785 | break; | |
786 | case MLX5_FLOW_NAMESPACE_KERNEL: | |
c3c062f8 | 787 | case MLX5_FLOW_NAMESPACE_BYPASS: |
2de24fed OG |
788 | max_actions = MLX5_CAP_FLOWTABLE_NIC_RX(dev, max_modify_header_actions); |
789 | table_type = FS_FT_NIC_RX; | |
790 | break; | |
c3c062f8 MB |
791 | case MLX5_FLOW_NAMESPACE_EGRESS: |
792 | max_actions = MLX5_CAP_FLOWTABLE_NIC_TX(dev, max_modify_header_actions); | |
793 | table_type = FS_FT_NIC_TX; | |
794 | break; | |
84b0d6a7 JL |
795 | case MLX5_FLOW_NAMESPACE_ESW_INGRESS: |
796 | max_actions = MLX5_CAP_ESW_INGRESS_ACL(dev, max_modify_header_actions); | |
797 | table_type = FS_FT_ESW_INGRESS_ACL; | |
798 | break; | |
2de24fed OG |
799 | default: |
800 | return -EOPNOTSUPP; | |
801 | } | |
802 | ||
803 | if (num_actions > max_actions) { | |
804 | mlx5_core_warn(dev, "too many modify header actions %d, max supported %d\n", | |
805 | num_actions, max_actions); | |
806 | return -EOPNOTSUPP; | |
807 | } | |
808 | ||
809 | actions_size = MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto) * num_actions; | |
810 | inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) + actions_size; | |
811 | ||
812 | in = kzalloc(inlen, GFP_KERNEL); | |
813 | if (!in) | |
814 | return -ENOMEM; | |
815 | ||
816 | MLX5_SET(alloc_modify_header_context_in, in, opcode, | |
817 | MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT); | |
818 | MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type); | |
819 | MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_actions); | |
820 | ||
821 | actions_in = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions); | |
822 | memcpy(actions_in, modify_actions, actions_size); | |
823 | ||
824 | memset(out, 0, sizeof(out)); | |
825 | err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); | |
826 | ||
2b688ea5 | 827 | modify_hdr->id = MLX5_GET(alloc_modify_header_context_out, out, modify_header_id); |
2de24fed OG |
828 | kfree(in); |
829 | return err; | |
830 | } | |
831 | ||
2b688ea5 MG |
832 | static void mlx5_cmd_modify_header_dealloc(struct mlx5_flow_root_namespace *ns, |
833 | struct mlx5_modify_hdr *modify_hdr) | |
2de24fed OG |
834 | { |
835 | u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)]; | |
836 | u32 out[MLX5_ST_SZ_DW(dealloc_modify_header_context_out)]; | |
2b688ea5 | 837 | struct mlx5_core_dev *dev = ns->dev; |
2de24fed OG |
838 | |
839 | memset(in, 0, sizeof(in)); | |
840 | MLX5_SET(dealloc_modify_header_context_in, in, opcode, | |
841 | MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT); | |
842 | MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id, | |
2b688ea5 | 843 | modify_hdr->id); |
2de24fed OG |
844 | |
845 | mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | |
846 | } | |
af76c501 MB |
847 | |
848 | static const struct mlx5_flow_cmds mlx5_flow_cmds = { | |
849 | .create_flow_table = mlx5_cmd_create_flow_table, | |
850 | .destroy_flow_table = mlx5_cmd_destroy_flow_table, | |
851 | .modify_flow_table = mlx5_cmd_modify_flow_table, | |
852 | .create_flow_group = mlx5_cmd_create_flow_group, | |
853 | .destroy_flow_group = mlx5_cmd_destroy_flow_group, | |
854 | .create_fte = mlx5_cmd_create_fte, | |
855 | .update_fte = mlx5_cmd_update_fte, | |
856 | .delete_fte = mlx5_cmd_delete_fte, | |
857 | .update_root_ft = mlx5_cmd_update_root_ft, | |
2b688ea5 MG |
858 | .packet_reformat_alloc = mlx5_cmd_packet_reformat_alloc, |
859 | .packet_reformat_dealloc = mlx5_cmd_packet_reformat_dealloc, | |
860 | .modify_header_alloc = mlx5_cmd_modify_header_alloc, | |
6a48faee MG |
861 | .modify_header_dealloc = mlx5_cmd_modify_header_dealloc, |
862 | .set_peer = mlx5_cmd_stub_set_peer, | |
863 | .create_ns = mlx5_cmd_stub_create_ns, | |
864 | .destroy_ns = mlx5_cmd_stub_destroy_ns, | |
af76c501 MB |
865 | }; |
866 | ||
867 | static const struct mlx5_flow_cmds mlx5_flow_cmd_stubs = { | |
868 | .create_flow_table = mlx5_cmd_stub_create_flow_table, | |
869 | .destroy_flow_table = mlx5_cmd_stub_destroy_flow_table, | |
870 | .modify_flow_table = mlx5_cmd_stub_modify_flow_table, | |
871 | .create_flow_group = mlx5_cmd_stub_create_flow_group, | |
872 | .destroy_flow_group = mlx5_cmd_stub_destroy_flow_group, | |
873 | .create_fte = mlx5_cmd_stub_create_fte, | |
874 | .update_fte = mlx5_cmd_stub_update_fte, | |
875 | .delete_fte = mlx5_cmd_stub_delete_fte, | |
876 | .update_root_ft = mlx5_cmd_stub_update_root_ft, | |
2b688ea5 MG |
877 | .packet_reformat_alloc = mlx5_cmd_stub_packet_reformat_alloc, |
878 | .packet_reformat_dealloc = mlx5_cmd_stub_packet_reformat_dealloc, | |
879 | .modify_header_alloc = mlx5_cmd_stub_modify_header_alloc, | |
6a48faee MG |
880 | .modify_header_dealloc = mlx5_cmd_stub_modify_header_dealloc, |
881 | .set_peer = mlx5_cmd_stub_set_peer, | |
882 | .create_ns = mlx5_cmd_stub_create_ns, | |
883 | .destroy_ns = mlx5_cmd_stub_destroy_ns, | |
af76c501 MB |
884 | }; |
885 | ||
6a48faee | 886 | const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void) |
af76c501 MB |
887 | { |
888 | return &mlx5_flow_cmds; | |
889 | } | |
890 | ||
891 | static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_stub_cmds(void) | |
892 | { | |
893 | return &mlx5_flow_cmd_stubs; | |
894 | } | |
895 | ||
896 | const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type) | |
897 | { | |
898 | switch (type) { | |
899 | case FS_FT_NIC_RX: | |
900 | case FS_FT_ESW_EGRESS_ACL: | |
901 | case FS_FT_ESW_INGRESS_ACL: | |
902 | case FS_FT_FDB: | |
903 | case FS_FT_SNIFFER_RX: | |
904 | case FS_FT_SNIFFER_TX: | |
5f418378 | 905 | case FS_FT_NIC_TX: |
d83eb50e | 906 | case FS_FT_RDMA_RX: |
24670b1a | 907 | case FS_FT_RDMA_TX: |
8ce78257 | 908 | return mlx5_fs_cmd_get_fw_cmds(); |
af76c501 MB |
909 | default: |
910 | return mlx5_fs_cmd_get_stub_cmds(); | |
911 | } | |
912 | } |