2 * Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <linux/types.h>
29 #include <linux/module.h>
30 #include <dev/mlx5/mlx5_ifc.h>
31 #include <dev/mlx5/device.h>
32 #include <dev/mlx5/fs.h>
35 #include "mlx5_core.h"
37 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
41 u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)];
42 u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)];
46 memset(in, 0, sizeof(in));
48 MLX5_SET(set_flow_table_root_in, in, opcode,
49 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
50 MLX5_SET(set_flow_table_root_in, in, table_type, type);
51 MLX5_SET(set_flow_table_root_in, in, table_id, id);
53 memset(out, 0, sizeof(out));
54 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
58 int mlx5_cmd_fs_create_ft(struct mlx5_core_dev *dev,
60 enum fs_ft_type type, unsigned int level,
61 unsigned int log_size, unsigned int *table_id)
63 u32 in[MLX5_ST_SZ_DW(create_flow_table_in)];
64 u32 out[MLX5_ST_SZ_DW(create_flow_table_out)];
69 memset(in, 0, sizeof(in));
71 MLX5_SET(create_flow_table_in, in, opcode,
72 MLX5_CMD_OP_CREATE_FLOW_TABLE);
74 MLX5_SET(create_flow_table_in, in, table_type, type);
75 MLX5_SET(create_flow_table_in, in, flow_table_context.level, level);
76 MLX5_SET(create_flow_table_in, in, flow_table_context.log_size,
79 MLX5_SET(create_flow_table_in, in, vport_number, vport);
80 MLX5_SET(create_flow_table_in, in, other_vport, 1);
83 memset(out, 0, sizeof(out));
84 err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
89 *table_id = MLX5_GET(create_flow_table_out, out, table_id);
94 int mlx5_cmd_fs_destroy_ft(struct mlx5_core_dev *dev,
96 enum fs_ft_type type, unsigned int table_id)
98 u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)];
99 u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)];
103 memset(in, 0, sizeof(in));
104 memset(out, 0, sizeof(out));
106 MLX5_SET(destroy_flow_table_in, in, opcode,
107 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
108 MLX5_SET(destroy_flow_table_in, in, table_type, type);
109 MLX5_SET(destroy_flow_table_in, in, table_id, table_id);
111 MLX5_SET(destroy_flow_table_in, in, vport_number, vport);
112 MLX5_SET(destroy_flow_table_in, in, other_vport, 1);
115 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
118 int mlx5_cmd_fs_create_fg(struct mlx5_core_dev *dev,
121 enum fs_ft_type type, unsigned int table_id,
122 unsigned int *group_id)
124 u32 out[MLX5_ST_SZ_DW(create_flow_group_out)];
126 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
129 memset(out, 0, sizeof(out));
131 MLX5_SET(create_flow_group_in, in, opcode,
132 MLX5_CMD_OP_CREATE_FLOW_GROUP);
133 MLX5_SET(create_flow_group_in, in, table_type, type);
134 MLX5_SET(create_flow_group_in, in, table_id, table_id);
136 MLX5_SET(create_flow_group_in, in, vport_number, vport);
137 MLX5_SET(create_flow_group_in, in, other_vport, 1);
140 err = mlx5_cmd_exec_check_status(dev, in,
144 *group_id = MLX5_GET(create_flow_group_out, out, group_id);
149 int mlx5_cmd_fs_destroy_fg(struct mlx5_core_dev *dev,
151 enum fs_ft_type type, unsigned int table_id,
152 unsigned int group_id)
154 u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)];
155 u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)];
159 memset(in, 0, sizeof(in));
160 memset(out, 0, sizeof(out));
162 MLX5_SET(destroy_flow_group_in, in, opcode,
163 MLX5_CMD_OP_DESTROY_FLOW_GROUP);
164 MLX5_SET(destroy_flow_group_in, in, table_type, type);
165 MLX5_SET(destroy_flow_group_in, in, table_id, table_id);
166 MLX5_SET(destroy_flow_group_in, in, group_id, group_id);
168 MLX5_SET(destroy_flow_group_in, in, vport_number, vport);
169 MLX5_SET(destroy_flow_group_in, in, other_vport, 1);
172 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
175 int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
177 enum fs_fte_status *fte_status,
179 enum fs_ft_type type, unsigned int table_id,
180 unsigned int index, unsigned int group_id,
181 unsigned int flow_tag,
182 unsigned short action, int dest_size,
183 struct list_head *dests) /* mlx5_flow_desination */
185 u32 out[MLX5_ST_SZ_DW(set_fte_out)];
188 struct mlx5_flow_rule *dst;
189 void *in_flow_context;
190 void *in_match_value;
197 if (action != MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)
200 inlen = MLX5_ST_SZ_BYTES(set_fte_in) +
201 dest_size * MLX5_ST_SZ_BYTES(dest_format_struct);
206 if (*fte_status & FS_FTE_STATUS_EXISTING) {
207 atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev,
208 flow_table_properties_nic_receive.
214 MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST;
217 in = mlx5_vzalloc(inlen);
219 mlx5_core_warn(dev, "failed to allocate inbox\n");
223 MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
224 MLX5_SET(set_fte_in, in, op_mod, opmod);
225 MLX5_SET(set_fte_in, in, modify_enable_mask, modify_mask);
226 MLX5_SET(set_fte_in, in, table_type, type);
227 MLX5_SET(set_fte_in, in, table_id, table_id);
228 MLX5_SET(set_fte_in, in, flow_index, index);
230 MLX5_SET(set_fte_in, in, vport_number, vport);
231 MLX5_SET(set_fte_in, in, other_vport, 1);
234 in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
235 MLX5_SET(flow_context, in_flow_context, group_id, group_id);
236 MLX5_SET(flow_context, in_flow_context, flow_tag, flow_tag);
237 MLX5_SET(flow_context, in_flow_context, action, action);
238 MLX5_SET(flow_context, in_flow_context, destination_list_size,
240 in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
242 memcpy(in_match_value, match_val, MLX5_ST_SZ_BYTES(fte_match_param));
244 in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
245 list_for_each_entry(dst, dests, base.list) {
248 MLX5_SET(dest_format_struct, in_dests, destination_type,
249 dst->dest_attr.type);
250 if (dst->dest_attr.type ==
251 MLX5_FLOW_CONTEXT_DEST_TYPE_FLOW_TABLE)
252 id = dst->dest_attr.ft->id;
254 id = dst->dest_attr.tir_num;
255 MLX5_SET(dest_format_struct, in_dests, destination_id, id);
256 in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
259 memset(out, 0, sizeof(out));
260 err = mlx5_cmd_exec_check_status(dev, in, inlen, out,
263 *fte_status |= FS_FTE_STATUS_EXISTING;
270 int mlx5_cmd_fs_delete_fte(struct mlx5_core_dev *dev,
272 enum fs_fte_status *fte_status,
273 enum fs_ft_type type, unsigned int table_id,
276 u32 in[MLX5_ST_SZ_DW(delete_fte_in)];
277 u32 out[MLX5_ST_SZ_DW(delete_fte_out)];
280 if (!(*fte_status & FS_FTE_STATUS_EXISTING))
285 memset(in, 0, sizeof(in));
286 memset(out, 0, sizeof(out));
288 MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
289 MLX5_SET(delete_fte_in, in, table_type, type);
290 MLX5_SET(delete_fte_in, in, table_id, table_id);
291 MLX5_SET(delete_fte_in, in, flow_index, index);
293 MLX5_SET(delete_fte_in, in, vport_number, vport);
294 MLX5_SET(delete_fte_in, in, other_vport, 1);
297 err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));