|
@@ -516,3 +516,69 @@ void mlx5_encap_dealloc(struct mlx5_core_dev *dev, u32 encap_id)
|
|
|
|
|
|
mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
|
|
|
}
|
|
|
+
|
|
|
+int mlx5_modify_header_alloc(struct mlx5_core_dev *dev,
|
|
|
+ u8 namespace, u8 num_actions,
|
|
|
+ void *modify_actions, u32 *modify_header_id)
|
|
|
+{
|
|
|
+ u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)];
|
|
|
+ int max_actions, actions_size, inlen, err;
|
|
|
+ void *actions_in;
|
|
|
+ u8 table_type;
|
|
|
+ u32 *in;
|
|
|
+
|
|
|
+ switch (namespace) {
|
|
|
+ case MLX5_FLOW_NAMESPACE_FDB:
|
|
|
+ max_actions = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, max_modify_header_actions);
|
|
|
+ table_type = FS_FT_FDB;
|
|
|
+ break;
|
|
|
+ case MLX5_FLOW_NAMESPACE_KERNEL:
|
|
|
+ max_actions = MLX5_CAP_FLOWTABLE_NIC_RX(dev, max_modify_header_actions);
|
|
|
+ table_type = FS_FT_NIC_RX;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (num_actions > max_actions) {
|
|
|
+ mlx5_core_warn(dev, "too many modify header actions %d, max supported %d\n",
|
|
|
+ num_actions, max_actions);
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ }
|
|
|
+
|
|
|
+ actions_size = MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto) * num_actions;
|
|
|
+ inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) + actions_size;
|
|
|
+
|
|
|
+ in = kzalloc(inlen, GFP_KERNEL);
|
|
|
+ if (!in)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ MLX5_SET(alloc_modify_header_context_in, in, opcode,
|
|
|
+ MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT);
|
|
|
+ MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type);
|
|
|
+ MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_actions);
|
|
|
+
|
|
|
+ actions_in = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions);
|
|
|
+ memcpy(actions_in, modify_actions, actions_size);
|
|
|
+
|
|
|
+ memset(out, 0, sizeof(out));
|
|
|
+ err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
|
|
|
+
|
|
|
+ *modify_header_id = MLX5_GET(alloc_modify_header_context_out, out, modify_header_id);
|
|
|
+ kfree(in);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev, u32 modify_header_id)
|
|
|
+{
|
|
|
+ u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)];
|
|
|
+ u32 out[MLX5_ST_SZ_DW(dealloc_modify_header_context_out)];
|
|
|
+
|
|
|
+ memset(in, 0, sizeof(in));
|
|
|
+ MLX5_SET(dealloc_modify_header_context_in, in, opcode,
|
|
|
+ MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
|
|
|
+ MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id,
|
|
|
+ modify_header_id);
|
|
|
+
|
|
|
+ mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
|
|
|
+}
|