1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2019 Mellanox Technologies */
4 #include <linux/mlx5/vport.h>
5 #include <rdma/ib_verbs.h>
6 #include <net/addrconf.h>
13 static void mlx5_rdma_disable_roce_steering(struct mlx5_core_dev *dev)
15 struct mlx5_core_roce *roce = &dev->priv.roce;
17 mlx5_del_flow_rules(roce->allow_rule);
18 mlx5_destroy_flow_group(roce->fg);
19 mlx5_destroy_flow_table(roce->ft);
22 static int mlx5_rdma_enable_roce_steering(struct mlx5_core_dev *dev)
24 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
25 struct mlx5_core_roce *roce = &dev->priv.roce;
26 struct mlx5_flow_handle *flow_rule = NULL;
27 struct mlx5_flow_table_attr ft_attr = {};
28 struct mlx5_flow_namespace *ns = NULL;
29 struct mlx5_flow_act flow_act = {};
30 struct mlx5_flow_spec *spec;
31 struct mlx5_flow_table *ft;
32 struct mlx5_flow_group *fg;
33 struct mlx5_eswitch *esw;
37 if (!(MLX5_CAP_FLOWTABLE_RDMA_RX(dev, ft_support) &&
38 MLX5_CAP_FLOWTABLE_RDMA_RX(dev, table_miss_action_domain)))
41 flow_group_in = kvzalloc(inlen, GFP_KERNEL);
44 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
46 kvfree(flow_group_in);
50 ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL);
52 mlx5_core_err(dev, "Failed to get RDMA RX namespace");
58 ft = mlx5_create_flow_table(ns, &ft_attr);
60 mlx5_core_err(dev, "Failed to create RDMA RX flow table");
65 esw = dev->priv.eswitch;
66 mlx5_esw_set_flow_group_source_port(esw, flow_group_in, 0);
68 fg = mlx5_create_flow_group(ft, flow_group_in);
71 mlx5_core_err(dev, "Failed to create RDMA RX flow group err(%d)\n", err);
72 goto destroy_flow_table;
75 mlx5_esw_set_spec_source_port(esw, esw->manager_vport, spec);
77 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
78 flow_rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0);
79 if (IS_ERR(flow_rule)) {
80 err = PTR_ERR(flow_rule);
81 mlx5_core_err(dev, "Failed to add RoCE allow rule, err=%d\n",
83 goto destroy_flow_group;
87 kvfree(flow_group_in);
90 roce->allow_rule = flow_rule;
95 mlx5_destroy_flow_group(fg);
97 mlx5_destroy_flow_table(ft);
100 kvfree(flow_group_in);
104 static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)
106 mlx5_core_roce_gid_set(dev, 0, MLX5_ROCE_VERSION_2, 0,
107 NULL, NULL, false, 0, 1);
110 static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)
114 mlx5_query_mac_address(dev, hw_id);
115 gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
116 addrconf_addr_eui48(&gid->raw[8], hw_id);
119 static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)
124 mlx5_rdma_make_default_gid(dev, &gid);
125 return mlx5_core_roce_gid_set(dev, 0,
131 void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)
133 struct mlx5_core_roce *roce = &dev->priv.roce;
138 mlx5_rdma_disable_roce_steering(dev);
139 mlx5_rdma_del_roce_addr(dev);
140 mlx5_nic_vport_disable_roce(dev);
143 void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
147 if (!MLX5_CAP_GEN(dev, roce))
150 err = mlx5_nic_vport_enable_roce(dev);
152 mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
156 err = mlx5_rdma_add_roce_addr(dev);
158 mlx5_core_err(dev, "Failed to add RoCE address: %d\n", err);
162 err = mlx5_rdma_enable_roce_steering(dev);
164 mlx5_core_err(dev, "Failed to enable RoCE steering: %d\n", err);
171 mlx5_rdma_del_roce_addr(dev);
173 mlx5_nic_vport_disable_roce(dev);