Skip to content

Commit

Permalink
RDMA/mlx5: Move to single device multiport ports in switchdev mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Bloch authored and Jason Gunthorpe committed Apr 10, 2019
1 parent a989ea0 commit 26628e2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
31 changes: 26 additions & 5 deletions drivers/infiniband/hw/mlx5/ib_rep.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,36 @@ static const struct mlx5_ib_profile vf_rep_profile = {
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
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;
struct mlx5_ib_dev *ibdev;
int num_ports = 1;
int vport_index;

if (rep->vport == MLX5_VPORT_UPLINK)
profile = &uplink_rep_profile;
else
profile = &vf_rep_profile;
return mlx5_ib_set_vport_rep(dev, rep);

ibdev = ib_alloc_device(mlx5_ib_dev, ib_dev);
if (!ibdev)
Expand All @@ -70,8 +89,9 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
}

ibdev->is_rep = true;
ibdev->port[0].rep = rep;
ibdev->port[0].roce.netdev =
vport_index = ibdev->free_port++;
ibdev->port[vport_index].rep = rep;
ibdev->port[vport_index].roce.netdev =
mlx5_ib_get_rep_netdev(dev->priv.eswitch, rep->vport);
ibdev->mdev = dev;
ibdev->num_ports = num_ports;
Expand All @@ -89,7 +109,8 @@ mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep)
{
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;

dev = mlx5_ib_rep_to_dev(rep);
Expand Down
26 changes: 22 additions & 4 deletions drivers/infiniband/hw/mlx5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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,
mdev_port_num);
if (dev->is_rep)
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)
goto out;
ext = MLX5_CAP_PCAM_FEATURE(dev->mdev, ptys_extended_ethernet);
Expand Down Expand Up @@ -1432,7 +1437,9 @@ static int mlx5_ib_rep_query_port(struct ib_device *ibdev, u8 port,
{
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);
if (ret || !props)
return ret;
Expand Down Expand Up @@ -4569,7 +4576,7 @@ static void get_ext_port_caps(struct mlx5_ib_dev *dev)
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_port_attr *pprops = NULL;
Expand Down Expand Up @@ -4612,6 +4619,16 @@ static int get_port_caps(struct mlx5_ib_dev *dev, u8 port)
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)
{
int err;
Expand Down Expand Up @@ -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;

/* Register only for native ports */
return mlx5_add_netdev_notifier(dev, port_num);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/mlx5/mlx5_ib.h
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ struct mlx5_ib_dev {
u16 devx_whitelist_uid;
struct mlx5_srq_table srq_table;
struct mlx5_async_ctx async_ctx;
int free_port;
};

static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
Expand Down

0 comments on commit 26628e2

Please sign in to comment.