RDMA/mlx5: Move to single device multiport ports in switchdev mode

Move from IB device (representor) per virtual function to single IB device
with port per virtual function (port 1 represents the uplink). As number
of ports is a static property of an IB device, declare the IB device with
as many port as the possible according to the PCI bus.

Signed-off-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Mark Bloch 2019-03-28 15:27:41 +02:00 committed by Jason Gunthorpe
parent a989ea01cb
commit 26628e2d58
3 changed files with 49 additions and 9 deletions

View File

@ -46,17 +46,36 @@ static const struct mlx5_ib_profile vf_rep_profile = {
NULL), NULL),
}; };
static int
mlx5_ib_set_vport_rep(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
{
struct mlx5_ib_dev *ibdev;
int vport_index;
ibdev = mlx5_ib_get_uplink_ibdev(dev->priv.eswitch);
vport_index = ibdev->free_port++;
ibdev->port[vport_index].rep = rep;
write_lock(&ibdev->port[vport_index].roce.netdev_lock);
ibdev->port[vport_index].roce.netdev =
mlx5_ib_get_rep_netdev(dev->priv.eswitch, rep->vport);
write_unlock(&ibdev->port[vport_index].roce.netdev_lock);
return 0;
}
static int static int
mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
{ {
int num_ports = MLX5_TOTAL_VPORTS(dev);
const struct mlx5_ib_profile *profile; const struct mlx5_ib_profile *profile;
struct mlx5_ib_dev *ibdev; struct mlx5_ib_dev *ibdev;
int num_ports = 1; int vport_index;
if (rep->vport == MLX5_VPORT_UPLINK) if (rep->vport == MLX5_VPORT_UPLINK)
profile = &uplink_rep_profile; profile = &uplink_rep_profile;
else else
profile = &vf_rep_profile; return mlx5_ib_set_vport_rep(dev, rep);
ibdev = ib_alloc_device(mlx5_ib_dev, ib_dev); ibdev = ib_alloc_device(mlx5_ib_dev, ib_dev);
if (!ibdev) if (!ibdev)
@ -70,8 +89,9 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
} }
ibdev->is_rep = true; ibdev->is_rep = true;
ibdev->port[0].rep = rep; vport_index = ibdev->free_port++;
ibdev->port[0].roce.netdev = ibdev->port[vport_index].rep = rep;
ibdev->port[vport_index].roce.netdev =
mlx5_ib_get_rep_netdev(dev->priv.eswitch, rep->vport); mlx5_ib_get_rep_netdev(dev->priv.eswitch, rep->vport);
ibdev->mdev = dev; ibdev->mdev = dev;
ibdev->num_ports = num_ports; ibdev->num_ports = num_ports;
@ -89,7 +109,8 @@ mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep)
{ {
struct mlx5_ib_dev *dev; struct mlx5_ib_dev *dev;
if (!rep->rep_if[REP_IB].priv) if (!rep->rep_if[REP_IB].priv ||
rep->vport != MLX5_VPORT_UPLINK)
return; return;
dev = mlx5_ib_rep_to_dev(rep); dev = mlx5_ib_rep_to_dev(rep);

View File

@ -506,9 +506,14 @@ static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
/* Possible bad flows are checked before filling out props so in case /* Possible bad flows are checked before filling out props so in case
* of an error it will still be zeroed out. * of an error it will still be zeroed out.
* Use native port in case of reps
*/ */
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, if (dev->is_rep)
mdev_port_num); err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN,
1);
else
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN,
mdev_port_num);
if (err) if (err)
goto out; goto out;
ext = MLX5_CAP_PCAM_FEATURE(dev->mdev, ptys_extended_ethernet); ext = MLX5_CAP_PCAM_FEATURE(dev->mdev, ptys_extended_ethernet);
@ -1432,7 +1437,9 @@ static int mlx5_ib_rep_query_port(struct ib_device *ibdev, u8 port,
{ {
int ret; int ret;
/* Only link layer == ethernet is valid for representors */ /* Only link layer == ethernet is valid for representors
* and we always use port 1
*/
ret = mlx5_query_port_roce(ibdev, port, props); ret = mlx5_query_port_roce(ibdev, port, props);
if (ret || !props) if (ret || !props)
return ret; return ret;
@ -4569,7 +4576,7 @@ static void get_ext_port_caps(struct mlx5_ib_dev *dev)
mlx5_query_ext_port_caps(dev, port); mlx5_query_ext_port_caps(dev, port);
} }
static int get_port_caps(struct mlx5_ib_dev *dev, u8 port) static int __get_port_caps(struct mlx5_ib_dev *dev, u8 port)
{ {
struct ib_device_attr *dprops = NULL; struct ib_device_attr *dprops = NULL;
struct ib_port_attr *pprops = NULL; struct ib_port_attr *pprops = NULL;
@ -4612,6 +4619,16 @@ out:
return err; return err;
} }
static int get_port_caps(struct mlx5_ib_dev *dev, u8 port)
{
/* For representors use port 1, is this is the only native
* port
*/
if (dev->is_rep)
return __get_port_caps(dev, 1);
return __get_port_caps(dev, port);
}
static void destroy_umrc_res(struct mlx5_ib_dev *dev) static void destroy_umrc_res(struct mlx5_ib_dev *dev)
{ {
int err; int err;
@ -6198,6 +6215,7 @@ static int mlx5_ib_stage_common_roce_init(struct mlx5_ib_dev *dev)
port_num = mlx5_core_native_port_num(dev->mdev) - 1; port_num = mlx5_core_native_port_num(dev->mdev) - 1;
/* Register only for native ports */
return mlx5_add_netdev_notifier(dev, port_num); return mlx5_add_netdev_notifier(dev, port_num);
} }

View File

@ -952,6 +952,7 @@ struct mlx5_ib_dev {
u16 devx_whitelist_uid; u16 devx_whitelist_uid;
struct mlx5_srq_table srq_table; struct mlx5_srq_table srq_table;
struct mlx5_async_ctx async_ctx; struct mlx5_async_ctx async_ctx;
int free_port;
}; };
static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq) static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)