Skip to content

Commit fb66cb0

Browse files
committed
Merge tag 'mlx5-updates-2018-02-23' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux
Saeed Mahameed says: mlx5-update-2018-02-23 (IB representors) From: Mark Bloch <[email protected]> ========= Add IB representor when in switchdev mode The following series adds support for an IB (RAW Ethernet only) device representor which is created when the user switches to switchdev mode. Today when switching to switchdev mode the only representors which are created are net devices. Each netdev is a representor of a virtual function and any data sent via the representor is received on the virtual function, and any data sent via the virtual function is received by the representor. For the mlx5 driver the main use of this functionality is to be able to use Open vSwitch on the hypervisor in order to manage/control traffic from/to the virtual functions. Open vSwitch can also work with DPDK devices and not just net devices, this series exposes an IB device, which Mellanox PMD driver uses, which then can be used by Open vSwitch DPDK. An IB device representor exposes only RAW Ethernet QP capabilities and the ability to create flow rules to direct traffic to its RX queues. The state of the IB device (ACTIVE/DOWN etc..) is based on the state of the corresponding net device representor. No other RDMA/RoCE functionality is currently supported and no GID table is exposed. ========= Signed-off-by: David S. Miller <[email protected]>
2 parents 3f5a683 + ec9c2fb commit fb66cb0

File tree

15 files changed

+796
-147
lines changed

15 files changed

+796
-147
lines changed

drivers/infiniband/hw/mlx5/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o
22

33
mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o gsi.o ib_virt.o cmd.o cong.o
44
mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o
5+
mlx5_ib-$(CONFIG_MLX5_ESWITCH) += ib_rep.o

drivers/infiniband/hw/mlx5/ib_rep.c

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2+
/*
3+
* Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4+
*/
5+
6+
#include "ib_rep.h"
7+
8+
static const struct mlx5_ib_profile rep_profile = {
9+
STAGE_CREATE(MLX5_IB_STAGE_INIT,
10+
mlx5_ib_stage_init_init,
11+
mlx5_ib_stage_init_cleanup),
12+
STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
13+
mlx5_ib_stage_rep_flow_db_init,
14+
NULL),
15+
STAGE_CREATE(MLX5_IB_STAGE_CAPS,
16+
mlx5_ib_stage_caps_init,
17+
NULL),
18+
STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
19+
mlx5_ib_stage_rep_non_default_cb,
20+
NULL),
21+
STAGE_CREATE(MLX5_IB_STAGE_ROCE,
22+
mlx5_ib_stage_rep_roce_init,
23+
mlx5_ib_stage_rep_roce_cleanup),
24+
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
25+
mlx5_ib_stage_dev_res_init,
26+
mlx5_ib_stage_dev_res_cleanup),
27+
STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
28+
mlx5_ib_stage_counters_init,
29+
mlx5_ib_stage_counters_cleanup),
30+
STAGE_CREATE(MLX5_IB_STAGE_BFREG,
31+
mlx5_ib_stage_bfrag_init,
32+
mlx5_ib_stage_bfrag_cleanup),
33+
STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
34+
mlx5_ib_stage_ib_reg_init,
35+
mlx5_ib_stage_ib_reg_cleanup),
36+
STAGE_CREATE(MLX5_IB_STAGE_UMR_RESOURCES,
37+
mlx5_ib_stage_umr_res_init,
38+
mlx5_ib_stage_umr_res_cleanup),
39+
STAGE_CREATE(MLX5_IB_STAGE_CLASS_ATTR,
40+
mlx5_ib_stage_class_attr_init,
41+
NULL),
42+
};
43+
44+
static int
45+
mlx5_ib_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
46+
{
47+
return 0;
48+
}
49+
50+
static void
51+
mlx5_ib_nic_rep_unload(struct mlx5_eswitch_rep *rep)
52+
{
53+
rep->rep_if[REP_IB].priv = NULL;
54+
}
55+
56+
static int
57+
mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
58+
{
59+
struct mlx5_ib_dev *ibdev;
60+
61+
ibdev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*ibdev));
62+
if (!ibdev)
63+
return -ENOMEM;
64+
65+
ibdev->rep = rep;
66+
ibdev->mdev = dev;
67+
ibdev->num_ports = max(MLX5_CAP_GEN(dev, num_ports),
68+
MLX5_CAP_GEN(dev, num_vhca_ports));
69+
if (!__mlx5_ib_add(ibdev, &rep_profile))
70+
return -EINVAL;
71+
72+
rep->rep_if[REP_IB].priv = ibdev;
73+
74+
return 0;
75+
}
76+
77+
static void
78+
mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep)
79+
{
80+
struct mlx5_ib_dev *dev;
81+
82+
if (!rep->rep_if[REP_IB].priv)
83+
return;
84+
85+
dev = mlx5_ib_rep_to_dev(rep);
86+
__mlx5_ib_remove(dev, dev->profile, MLX5_IB_STAGE_MAX);
87+
rep->rep_if[REP_IB].priv = NULL;
88+
}
89+
90+
static void *mlx5_ib_vport_get_proto_dev(struct mlx5_eswitch_rep *rep)
91+
{
92+
return mlx5_ib_rep_to_dev(rep);
93+
}
94+
95+
static void mlx5_ib_rep_register_vf_vports(struct mlx5_ib_dev *dev)
96+
{
97+
struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
98+
int total_vfs = MLX5_TOTAL_VPORTS(dev->mdev);
99+
int vport;
100+
101+
for (vport = 1; vport < total_vfs; vport++) {
102+
struct mlx5_eswitch_rep_if rep_if = {};
103+
104+
rep_if.load = mlx5_ib_vport_rep_load;
105+
rep_if.unload = mlx5_ib_vport_rep_unload;
106+
rep_if.get_proto_dev = mlx5_ib_vport_get_proto_dev;
107+
mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_IB);
108+
}
109+
}
110+
111+
static void mlx5_ib_rep_unregister_vf_vports(struct mlx5_ib_dev *dev)
112+
{
113+
struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
114+
int total_vfs = MLX5_TOTAL_VPORTS(dev->mdev);
115+
int vport;
116+
117+
for (vport = 1; vport < total_vfs; vport++)
118+
mlx5_eswitch_unregister_vport_rep(esw, vport, REP_IB);
119+
}
120+
121+
void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev)
122+
{
123+
struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
124+
struct mlx5_eswitch_rep_if rep_if = {};
125+
126+
rep_if.load = mlx5_ib_nic_rep_load;
127+
rep_if.unload = mlx5_ib_nic_rep_unload;
128+
rep_if.get_proto_dev = mlx5_ib_vport_get_proto_dev;
129+
rep_if.priv = dev;
130+
131+
mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_IB);
132+
133+
mlx5_ib_rep_register_vf_vports(dev);
134+
}
135+
136+
void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev)
137+
{
138+
struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
139+
140+
mlx5_ib_rep_unregister_vf_vports(dev); /* VFs vports */
141+
mlx5_eswitch_unregister_vport_rep(esw, 0, REP_IB); /* UPLINK PF*/
142+
}
143+
144+
u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw)
145+
{
146+
return mlx5_eswitch_mode(esw);
147+
}
148+
149+
struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
150+
int vport_index)
151+
{
152+
return mlx5_eswitch_get_proto_dev(esw, vport_index, REP_IB);
153+
}
154+
155+
struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
156+
int vport_index)
157+
{
158+
return mlx5_eswitch_get_proto_dev(esw, vport_index, REP_ETH);
159+
}
160+
161+
struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw)
162+
{
163+
return mlx5_eswitch_uplink_get_proto_dev(esw, REP_IB);
164+
}
165+
166+
struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw, int vport)
167+
{
168+
return mlx5_eswitch_vport_rep(esw, vport);
169+
}
170+
171+
int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
172+
struct mlx5_ib_sq *sq)
173+
{
174+
struct mlx5_flow_handle *flow_rule;
175+
struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
176+
177+
if (!dev->rep)
178+
return 0;
179+
180+
flow_rule =
181+
mlx5_eswitch_add_send_to_vport_rule(esw,
182+
dev->rep->vport,
183+
sq->base.mqp.qpn);
184+
if (IS_ERR(flow_rule))
185+
return PTR_ERR(flow_rule);
186+
sq->flow_rule = flow_rule;
187+
188+
return 0;
189+
}

drivers/infiniband/hw/mlx5/ib_rep.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2+
/*
3+
* Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4+
*/
5+
6+
#ifndef __MLX5_IB_REP_H__
7+
#define __MLX5_IB_REP_H__
8+
9+
#include <linux/mlx5/eswitch.h>
10+
#include "mlx5_ib.h"
11+
12+
#ifdef CONFIG_MLX5_ESWITCH
13+
u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw);
14+
struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
15+
int vport_index);
16+
struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw);
17+
struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw,
18+
int vport_index);
19+
void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev);
20+
void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev);
21+
int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
22+
struct mlx5_ib_sq *sq);
23+
struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
24+
int vport_index);
25+
#else /* CONFIG_MLX5_ESWITCH */
26+
static inline u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw)
27+
{
28+
return SRIOV_NONE;
29+
}
30+
31+
static inline
32+
struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
33+
int vport_index)
34+
{
35+
return NULL;
36+
}
37+
38+
static inline
39+
struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw)
40+
{
41+
return NULL;
42+
}
43+
44+
static inline
45+
struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw,
46+
int vport_index)
47+
{
48+
return NULL;
49+
}
50+
51+
static inline void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev) {}
52+
static inline void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev) {}
53+
static inline int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
54+
struct mlx5_ib_sq *sq)
55+
{
56+
return 0;
57+
}
58+
59+
static inline
60+
struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
61+
int vport_index)
62+
{
63+
return NULL;
64+
}
65+
#endif
66+
67+
static inline
68+
struct mlx5_ib_dev *mlx5_ib_rep_to_dev(struct mlx5_eswitch_rep *rep)
69+
{
70+
return (struct mlx5_ib_dev *)rep->rep_if[REP_IB].priv;
71+
}
72+
#endif /* __MLX5_IB_REP_H__ */

0 commit comments

Comments
 (0)