Commit 449fc488 authored by Matan Barak's avatar Matan Barak Committed by David S. Miller

net/mlx4: Adapt code for N-Port VF

Adds support for N-Port VFs, this includes:
1. Adding support in the wrapped FW command
	In wrapped commands, we need to verify and convert
	the slave's port into the real physical port.
	Furthermore, when sending the response back to the slave,
	a reverse conversion should be made.
2. Adjusting sqpn for QP1 para-virtualization
	The slave assumes that sqpn is used for QP1 communication.
	If the slave is assigned to a port != (first port), we need
	to adjust the sqpn that will direct its QP1 packets into the
	correct endpoint.
3. Adjusting gid[5] to modify the port for raw ethernet
	In B0 steering, gid[5] contains the port. It needs
	to be adjusted into the physical port.
4. Adjusting number of ports in the query / ports caps in the FW commands
	When a slave queries the hardware, it needs to view only
	the physical ports it's assigned to.
5. Adjusting the sched_qp according to the port number
	The QP port is encoded in the sched_qp, thus in modify_qp we need
	to encode the correct port in sched_qp.
Signed-off-by: default avatarMatan Barak <matanb@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f74462ac
...@@ -1245,21 +1245,9 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, ...@@ -1245,21 +1245,9 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
static int get_slave_base_gid_ix(struct mlx4_ib_dev *dev, int slave, int port) static int get_slave_base_gid_ix(struct mlx4_ib_dev *dev, int slave, int port)
{ {
int gids;
int vfs;
if (rdma_port_get_link_layer(&dev->ib_dev, port) == IB_LINK_LAYER_INFINIBAND) if (rdma_port_get_link_layer(&dev->ib_dev, port) == IB_LINK_LAYER_INFINIBAND)
return slave; return slave;
return mlx4_get_base_gid_ix(dev->dev, slave, port);
gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
vfs = dev->dev->num_vfs;
if (slave == 0)
return 0;
if (slave <= gids % vfs)
return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave - 1);
return MLX4_ROCE_PF_GIDS + (gids % vfs) + ((gids / vfs) * (slave - 1));
} }
static void fill_in_real_sgid_index(struct mlx4_ib_dev *dev, int slave, int port, static void fill_in_real_sgid_index(struct mlx4_ib_dev *dev, int slave, int port,
...@@ -1281,6 +1269,7 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc ...@@ -1281,6 +1269,7 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc
struct ib_ah_attr ah_attr; struct ib_ah_attr ah_attr;
u8 *slave_id; u8 *slave_id;
int slave; int slave;
int port;
/* Get slave that sent this packet */ /* Get slave that sent this packet */
if (wc->src_qp < dev->dev->phys_caps.base_proxy_sqpn || if (wc->src_qp < dev->dev->phys_caps.base_proxy_sqpn ||
...@@ -1360,6 +1349,10 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc ...@@ -1360,6 +1349,10 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc
if (ah_attr.ah_flags & IB_AH_GRH) if (ah_attr.ah_flags & IB_AH_GRH)
fill_in_real_sgid_index(dev, slave, ctx->port, &ah_attr); fill_in_real_sgid_index(dev, slave, ctx->port, &ah_attr);
port = mlx4_slave_convert_port(dev->dev, slave, ah_attr.port_num);
if (port < 0)
return;
ah_attr.port_num = port;
memcpy(ah_attr.dmac, tunnel->hdr.mac, 6); memcpy(ah_attr.dmac, tunnel->hdr.mac, 6);
ah_attr.vlan_id = be16_to_cpu(tunnel->hdr.vlan); ah_attr.vlan_id = be16_to_cpu(tunnel->hdr.vlan);
/* if slave have default vlan use it */ /* if slave have default vlan use it */
...@@ -1949,7 +1942,15 @@ static int mlx4_ib_alloc_demux_ctx(struct mlx4_ib_dev *dev, ...@@ -1949,7 +1942,15 @@ static int mlx4_ib_alloc_demux_ctx(struct mlx4_ib_dev *dev,
ctx->port = port; ctx->port = port;
ctx->ib_dev = &dev->ib_dev; ctx->ib_dev = &dev->ib_dev;
for (i = 0; i < dev->dev->caps.sqp_demux; i++) { for (i = 0;
i < min(dev->dev->caps.sqp_demux, (u16)(dev->dev->num_vfs + 1));
i++) {
struct mlx4_active_ports actv_ports =
mlx4_get_active_ports(dev->dev, i);
if (!test_bit(port - 1, actv_ports.ports))
continue;
ret = alloc_pv_object(dev, i, port, &ctx->tun[i]); ret = alloc_pv_object(dev, i, port, &ctx->tun[i]);
if (ret) { if (ret) {
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -2323,17 +2323,24 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init) ...@@ -2323,17 +2323,24 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init)
struct mlx4_dev *dev = ibdev->dev; struct mlx4_dev *dev = ibdev->dev;
int i; int i;
unsigned long flags; unsigned long flags;
struct mlx4_active_ports actv_ports;
unsigned int ports;
unsigned int first_port;
if (!mlx4_is_master(dev)) if (!mlx4_is_master(dev))
return; return;
dm = kcalloc(dev->caps.num_ports, sizeof *dm, GFP_ATOMIC); actv_ports = mlx4_get_active_ports(dev, slave);
ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports);
first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports);
dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC);
if (!dm) { if (!dm) {
pr_err("failed to allocate memory for tunneling qp update\n"); pr_err("failed to allocate memory for tunneling qp update\n");
goto out; goto out;
} }
for (i = 0; i < dev->caps.num_ports; i++) { for (i = 0; i < ports; i++) {
dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC); dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC);
if (!dm[i]) { if (!dm[i]) {
pr_err("failed to allocate memory for tunneling qp update work struct\n"); pr_err("failed to allocate memory for tunneling qp update work struct\n");
...@@ -2345,9 +2352,9 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init) ...@@ -2345,9 +2352,9 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init)
} }
} }
/* initialize or tear down tunnel QPs for the slave */ /* initialize or tear down tunnel QPs for the slave */
for (i = 0; i < dev->caps.num_ports; i++) { for (i = 0; i < ports; i++) {
INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work); INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work);
dm[i]->port = i + 1; dm[i]->port = first_port + i + 1;
dm[i]->slave = slave; dm[i]->slave = slave;
dm[i]->do_init = do_init; dm[i]->do_init = do_init;
dm[i]->dev = ibdev; dm[i]->dev = ibdev;
......
...@@ -627,6 +627,7 @@ static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave) ...@@ -627,6 +627,7 @@ static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
int port; int port;
struct kobject *p, *t; struct kobject *p, *t;
struct mlx4_port *mport; struct mlx4_port *mport;
struct mlx4_active_ports actv_ports;
get_name(dev, name, slave, sizeof name); get_name(dev, name, slave, sizeof name);
...@@ -649,7 +650,11 @@ static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave) ...@@ -649,7 +650,11 @@ static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
goto err_ports; goto err_ports;
} }
actv_ports = mlx4_get_active_ports(dev->dev, slave);
for (port = 1; port <= dev->dev->caps.num_ports; ++port) { for (port = 1; port <= dev->dev->caps.num_ports; ++port) {
if (!test_bit(port - 1, actv_ports.ports))
continue;
err = add_port(dev, port, slave); err = add_port(dev, port, slave);
if (err) if (err)
goto err_add; goto err_add;
......
...@@ -1643,8 +1643,16 @@ static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave) ...@@ -1643,8 +1643,16 @@ static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
int port, err; int port, err;
struct mlx4_vport_state *vp_admin; struct mlx4_vport_state *vp_admin;
struct mlx4_vport_oper_state *vp_oper; struct mlx4_vport_oper_state *vp_oper;
struct mlx4_active_ports actv_ports = mlx4_get_active_ports(
for (port = 1; port <= MLX4_MAX_PORTS; port++) { &priv->dev, slave);
int min_port = find_first_bit(actv_ports.ports,
priv->dev.caps.num_ports) + 1;
int max_port = min_port - 1 +
bitmap_weight(actv_ports.ports, priv->dev.caps.num_ports);
for (port = min_port; port <= max_port; port++) {
if (!test_bit(port - 1, actv_ports.ports))
continue;
vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
vp_oper->state = *vp_admin; vp_oper->state = *vp_admin;
...@@ -1685,8 +1693,17 @@ static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave ...@@ -1685,8 +1693,17 @@ static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave
{ {
int port; int port;
struct mlx4_vport_oper_state *vp_oper; struct mlx4_vport_oper_state *vp_oper;
struct mlx4_active_ports actv_ports = mlx4_get_active_ports(
&priv->dev, slave);
int min_port = find_first_bit(actv_ports.ports,
priv->dev.caps.num_ports) + 1;
int max_port = min_port - 1 +
bitmap_weight(actv_ports.ports, priv->dev.caps.num_ports);
for (port = 1; port <= MLX4_MAX_PORTS; port++) { for (port = min_port; port <= max_port; port++) {
if (!test_bit(port - 1, actv_ports.ports))
continue;
vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
if (NO_INDX != vp_oper->vlan_idx) { if (NO_INDX != vp_oper->vlan_idx) {
__mlx4_unregister_vlan(&priv->dev, __mlx4_unregister_vlan(&priv->dev,
......
...@@ -271,7 +271,10 @@ enum slave_port_state mlx4_get_slave_port_state(struct mlx4_dev *dev, int slave, ...@@ -271,7 +271,10 @@ enum slave_port_state mlx4_get_slave_port_state(struct mlx4_dev *dev, int slave,
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_slave_state *s_state = priv->mfunc.master.slave_state; struct mlx4_slave_state *s_state = priv->mfunc.master.slave_state;
if (slave >= dev->num_slaves || port > MLX4_MAX_PORTS) { struct mlx4_active_ports actv_ports = mlx4_get_active_ports(dev, slave);
if (slave >= dev->num_slaves || port > dev->caps.num_ports ||
port <= 0 || !test_bit(port - 1, actv_ports.ports)) {
pr_err("%s: Error: asking for slave:%d, port:%d\n", pr_err("%s: Error: asking for slave:%d, port:%d\n",
__func__, slave, port); __func__, slave, port);
return SLAVE_PORT_DOWN; return SLAVE_PORT_DOWN;
...@@ -285,8 +288,10 @@ static int mlx4_set_slave_port_state(struct mlx4_dev *dev, int slave, u8 port, ...@@ -285,8 +288,10 @@ static int mlx4_set_slave_port_state(struct mlx4_dev *dev, int slave, u8 port,
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_slave_state *s_state = priv->mfunc.master.slave_state; struct mlx4_slave_state *s_state = priv->mfunc.master.slave_state;
struct mlx4_active_ports actv_ports = mlx4_get_active_ports(dev, slave);
if (slave >= dev->num_slaves || port > MLX4_MAX_PORTS || port == 0) { if (slave >= dev->num_slaves || port > dev->caps.num_ports ||
port <= 0 || !test_bit(port - 1, actv_ports.ports)) {
pr_err("%s: Error: asking for slave:%d, port:%d\n", pr_err("%s: Error: asking for slave:%d, port:%d\n",
__func__, slave, port); __func__, slave, port);
return -1; return -1;
...@@ -300,9 +305,13 @@ static void set_all_slave_state(struct mlx4_dev *dev, u8 port, int event) ...@@ -300,9 +305,13 @@ static void set_all_slave_state(struct mlx4_dev *dev, u8 port, int event)
{ {
int i; int i;
enum slave_port_gen_event gen_event; enum slave_port_gen_event gen_event;
struct mlx4_slaves_pport slaves_pport = mlx4_phys_to_slaves_pport(dev,
port);
for (i = 0; i < dev->num_slaves; i++) for (i = 0; i < dev->num_vfs + 1; i++)
set_and_calc_slave_port_state(dev, i, port, event, &gen_event); if (test_bit(i, slaves_pport.slaves))
set_and_calc_slave_port_state(dev, i, port,
event, &gen_event);
} }
/************************************************************************** /**************************************************************************
The function get as input the new event to that port, The function get as input the new event to that port,
...@@ -321,12 +330,14 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, ...@@ -321,12 +330,14 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave,
struct mlx4_slave_state *ctx = NULL; struct mlx4_slave_state *ctx = NULL;
unsigned long flags; unsigned long flags;
int ret = -1; int ret = -1;
struct mlx4_active_ports actv_ports = mlx4_get_active_ports(dev, slave);
enum slave_port_state cur_state = enum slave_port_state cur_state =
mlx4_get_slave_port_state(dev, slave, port); mlx4_get_slave_port_state(dev, slave, port);
*gen_event = SLAVE_PORT_GEN_EVENT_NONE; *gen_event = SLAVE_PORT_GEN_EVENT_NONE;
if (slave >= dev->num_slaves || port > MLX4_MAX_PORTS || port == 0) { if (slave >= dev->num_slaves || port > dev->caps.num_ports ||
port <= 0 || !test_bit(port - 1, actv_ports.ports)) {
pr_err("%s: Error: asking for slave:%d, port:%d\n", pr_err("%s: Error: asking for slave:%d, port:%d\n",
__func__, slave, port); __func__, slave, port);
return ret; return ret;
...@@ -542,15 +553,19 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -542,15 +553,19 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
be64_to_cpu(eqe->event.cmd.out_param)); be64_to_cpu(eqe->event.cmd.out_param));
break; break;
case MLX4_EVENT_TYPE_PORT_CHANGE: case MLX4_EVENT_TYPE_PORT_CHANGE: {
struct mlx4_slaves_pport slaves_port;
port = be32_to_cpu(eqe->event.port_change.port) >> 28; port = be32_to_cpu(eqe->event.port_change.port) >> 28;
slaves_port = mlx4_phys_to_slaves_pport(dev, port);
if (eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_DOWN) { if (eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_DOWN) {
mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_DOWN, mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_DOWN,
port); port);
mlx4_priv(dev)->sense.do_sense_port[port] = 1; mlx4_priv(dev)->sense.do_sense_port[port] = 1;
if (!mlx4_is_master(dev)) if (!mlx4_is_master(dev))
break; break;
for (i = 0; i < dev->num_slaves; i++) { for (i = 0; i < dev->num_vfs + 1; i++) {
if (!test_bit(i, slaves_port.slaves))
continue;
if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) { if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) {
if (i == mlx4_master_func_num(dev)) if (i == mlx4_master_func_num(dev))
continue; continue;
...@@ -558,8 +573,13 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -558,8 +573,13 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
" to slave: %d, port:%d\n", " to slave: %d, port:%d\n",
__func__, i, port); __func__, i, port);
s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state; s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state;
if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state) if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state) {
eqe->event.port_change.port =
cpu_to_be32(
(be32_to_cpu(eqe->event.port_change.port) & 0xFFFFFFF)
| (mlx4_phys_to_slave_port(dev, i, port) << 28));
mlx4_slave_event(dev, i, eqe); mlx4_slave_event(dev, i, eqe);
}
} else { /* IB port */ } else { /* IB port */
set_and_calc_slave_port_state(dev, i, port, set_and_calc_slave_port_state(dev, i, port,
MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN, MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN,
...@@ -580,12 +600,19 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -580,12 +600,19 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
if (!mlx4_is_master(dev)) if (!mlx4_is_master(dev))
break; break;
if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
for (i = 0; i < dev->num_slaves; i++) { for (i = 0; i < dev->num_vfs + 1; i++) {
if (!test_bit(i, slaves_port.slaves))
continue;
if (i == mlx4_master_func_num(dev)) if (i == mlx4_master_func_num(dev))
continue; continue;
s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state; s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state;
if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state) if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state) {
eqe->event.port_change.port =
cpu_to_be32(
(be32_to_cpu(eqe->event.port_change.port) & 0xFFFFFFF)
| (mlx4_phys_to_slave_port(dev, i, port) << 28));
mlx4_slave_event(dev, i, eqe); mlx4_slave_event(dev, i, eqe);
}
} }
else /* IB port */ else /* IB port */
/* port-up event will be sent to a slave when the /* port-up event will be sent to a slave when the
...@@ -594,6 +621,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -594,6 +621,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
set_all_slave_state(dev, port, MLX4_DEV_EVENT_PORT_UP); set_all_slave_state(dev, port, MLX4_DEV_EVENT_PORT_UP);
} }
break; break;
}
case MLX4_EVENT_TYPE_CQ_ERROR: case MLX4_EVENT_TYPE_CQ_ERROR:
mlx4_warn(dev, "CQ %s on CQN %06x\n", mlx4_warn(dev, "CQ %s on CQN %06x\n",
......
...@@ -225,13 +225,25 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -225,13 +225,25 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
#define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80
if (vhcr->op_modifier == 1) { if (vhcr->op_modifier == 1) {
struct mlx4_active_ports actv_ports =
mlx4_get_active_ports(dev, slave);
int converted_port = mlx4_slave_convert_port(
dev, slave, vhcr->in_modifier);
if (converted_port < 0)
return -EINVAL;
vhcr->in_modifier = converted_port;
/* Set nic_info bit to mark new fields support */ /* Set nic_info bit to mark new fields support */
field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO;
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET);
field = vhcr->in_modifier; /* phys-port = logical-port */ /* phys-port = logical-port */
field = vhcr->in_modifier -
find_first_bit(actv_ports.ports, dev->caps.num_ports);
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET);
field = vhcr->in_modifier;
/* size is now the QP number */ /* size is now the QP number */
size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + field - 1; size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + field - 1;
MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL);
...@@ -249,12 +261,16 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -249,12 +261,16 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
QUERY_FUNC_CAP_PHYS_PORT_ID); QUERY_FUNC_CAP_PHYS_PORT_ID);
} else if (vhcr->op_modifier == 0) { } else if (vhcr->op_modifier == 0) {
struct mlx4_active_ports actv_ports =
mlx4_get_active_ports(dev, slave);
/* enable rdma and ethernet interfaces, and new quota locations */ /* enable rdma and ethernet interfaces, and new quota locations */
field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA |
QUERY_FUNC_CAP_FLAG_QUOTAS); QUERY_FUNC_CAP_FLAG_QUOTAS);
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET);
field = dev->caps.num_ports; field = min(
bitmap_weight(actv_ports.ports, dev->caps.num_ports),
dev->caps.num_ports);
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
size = dev->caps.function_caps; /* set PF behaviours */ size = dev->caps.function_caps; /* set PF behaviours */
...@@ -840,6 +856,10 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -840,6 +856,10 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
int err = 0; int err = 0;
u8 field; u8 field;
u32 bmme_flags; u32 bmme_flags;
int real_port;
int slave_port;
int first_port;
struct mlx4_active_ports actv_ports;
err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
...@@ -852,8 +872,26 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -852,8 +872,26 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV;
flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW;
actv_ports = mlx4_get_active_ports(dev, slave);
first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports);
for (slave_port = 0, real_port = first_port;
real_port < first_port +
bitmap_weight(actv_ports.ports, dev->caps.num_ports);
++real_port, ++slave_port) {
if (flags & (MLX4_DEV_CAP_FLAG_WOL_PORT1 << real_port))
flags |= MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port;
else
flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port);
}
for (; slave_port < dev->caps.num_ports; ++slave_port)
flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port);
MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VL_PORT_OFFSET);
field &= ~0x0F;
field |= bitmap_weight(actv_ports.ports, dev->caps.num_ports) & 0x0F;
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VL_PORT_OFFSET);
/* For guests, disable timestamp */ /* For guests, disable timestamp */
MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
field &= 0x7f; field &= 0x7f;
...@@ -903,12 +941,20 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -903,12 +941,20 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
u16 short_field; u16 short_field;
int err; int err;
int admin_link_state; int admin_link_state;
int port = mlx4_slave_convert_port(dev, slave,
vhcr->in_modifier & 0xFF);
#define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0
#define MLX4_PORT_LINK_UP_MASK 0x80 #define MLX4_PORT_LINK_UP_MASK 0x80
#define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c
#define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e
if (port < 0)
return -EINVAL;
vhcr->in_modifier = (vhcr->in_modifier & ~0xFF) |
(port & 0xFF);
err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0,
MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B,
MLX4_CMD_NATIVE); MLX4_CMD_NATIVE);
...@@ -936,7 +982,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -936,7 +982,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
QUERY_PORT_SUPPORTED_TYPE_OFFSET); QUERY_PORT_SUPPORTED_TYPE_OFFSET);
if (dev->caps.port_type[vhcr->in_modifier] == MLX4_PORT_TYPE_ETH) if (dev->caps.port_type[vhcr->in_modifier] == MLX4_PORT_TYPE_ETH)
short_field = mlx4_get_slave_num_gids(dev, slave); short_field = mlx4_get_slave_num_gids(dev, slave, port);
else else
short_field = 1; /* slave max gids */ short_field = 1; /* slave max gids */
MLX4_PUT(outbox->buf, short_field, MLX4_PUT(outbox->buf, short_field,
...@@ -1588,9 +1634,12 @@ int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -1588,9 +1634,12 @@ int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_cmd_info *cmd) struct mlx4_cmd_info *cmd)
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int port = vhcr->in_modifier; int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier);
int err; int err;
if (port < 0)
return -EINVAL;
if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port)) if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port))
return 0; return 0;
...@@ -1680,9 +1729,12 @@ int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -1680,9 +1729,12 @@ int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_cmd_info *cmd) struct mlx4_cmd_info *cmd)
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int port = vhcr->in_modifier; int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier);
int err; int err;
if (port < 0)
return -EINVAL;
if (!(priv->mfunc.master.slave_state[slave].init_port_mask & if (!(priv->mfunc.master.slave_state[slave].init_port_mask &
(1 << port))) (1 << port)))
return 0; return 0;
......
...@@ -1471,7 +1471,7 @@ static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev) ...@@ -1471,7 +1471,7 @@ static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev)
for (i = 1; i <= dev->caps.num_ports; i++) { for (i = 1; i <= dev->caps.num_ports; i++) {
if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH)
dev->caps.gid_table_len[i] = dev->caps.gid_table_len[i] =
mlx4_get_slave_num_gids(dev, 0); mlx4_get_slave_num_gids(dev, 0, i);
else else
dev->caps.gid_table_len[i] = 1; dev->caps.gid_table_len[i] = 1;
dev->caps.pkey_table_len[i] = dev->caps.pkey_table_len[i] =
...@@ -1498,7 +1498,7 @@ static void choose_steering_mode(struct mlx4_dev *dev, ...@@ -1498,7 +1498,7 @@ static void choose_steering_mode(struct mlx4_dev *dev,
if (mlx4_log_num_mgm_entry_size == -1 && if (mlx4_log_num_mgm_entry_size == -1 &&
dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN && dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN &&
(!mlx4_is_mfunc(dev) || (!mlx4_is_mfunc(dev) ||
(dev_cap->fs_max_num_qp_per_entry >= (num_vfs + 1))) && (dev_cap->fs_max_num_qp_per_entry >= (dev->num_vfs + 1))) &&
choose_log_fs_mgm_entry_size(dev_cap->fs_max_num_qp_per_entry) >= choose_log_fs_mgm_entry_size(dev_cap->fs_max_num_qp_per_entry) >=
MLX4_MIN_MGM_LOG_ENTRY_SIZE) { MLX4_MIN_MGM_LOG_ENTRY_SIZE) {
dev->oper_log_mgm_entry_size = dev->oper_log_mgm_entry_size =
......
...@@ -1387,9 +1387,12 @@ int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave, ...@@ -1387,9 +1387,12 @@ int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_cmd_info *cmd) struct mlx4_cmd_info *cmd)
{ {
u32 qpn = (u32) vhcr->in_param & 0xffffffff; u32 qpn = (u32) vhcr->in_param & 0xffffffff;
u8 port = vhcr->in_param >> 62; int port = mlx4_slave_convert_port(dev, slave, vhcr->in_param >> 62);
enum mlx4_steer_type steer = vhcr->in_modifier; enum mlx4_steer_type steer = vhcr->in_modifier;
if (port < 0)
return -EINVAL;
/* Promiscuous unicast is not allowed in mfunc */ /* Promiscuous unicast is not allowed in mfunc */
if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER) if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)
return 0; return 0;
......
...@@ -1287,8 +1287,7 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work); ...@@ -1287,8 +1287,7 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work);
void mlx4_init_quotas(struct mlx4_dev *dev); void mlx4_init_quotas(struct mlx4_dev *dev);
int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave); int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port);
int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave);
/* Returns the VF index of slave */ /* Returns the VF index of slave */
int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave);
......
...@@ -507,30 +507,82 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) ...@@ -507,30 +507,82 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
} }
static struct mlx4_roce_gid_entry zgid_entry; static struct mlx4_roce_gid_entry zgid_entry;
int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave) int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port)
{ {
int vfs;
int slave_gid = slave;
unsigned i;
struct mlx4_slaves_pport slaves_pport;
struct mlx4_active_ports actv_ports;
unsigned max_port_p_one;
if (slave == 0) if (slave == 0)
return MLX4_ROCE_PF_GIDS; return MLX4_ROCE_PF_GIDS;
if (slave <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % dev->num_vfs))
return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs) + 1; /* Slave is a VF */
return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs; slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
actv_ports = mlx4_get_active_ports(dev, slave);
max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;
for (i = 1; i < max_port_p_one; i++) {
struct mlx4_active_ports exclusive_ports;
struct mlx4_slaves_pport slaves_pport_actv;
bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
set_bit(i - 1, exclusive_ports.ports);
if (i == port)
continue;
slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
dev, &exclusive_ports);
slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
dev->num_vfs + 1);
}
vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1;
if (slave_gid <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % vfs))
return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs) + 1;
return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs;
} }
int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave) int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port)
{ {
int gids; int gids;
unsigned i;
int slave_gid = slave;
int vfs; int vfs;
gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; struct mlx4_slaves_pport slaves_pport;
vfs = dev->num_vfs; struct mlx4_active_ports actv_ports;
unsigned max_port_p_one;
if (slave == 0) if (slave == 0)
return 0; return 0;
if (slave <= gids % vfs)
return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave - 1);
return MLX4_ROCE_PF_GIDS + (gids % vfs) + ((gids / vfs) * (slave - 1)); slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
actv_ports = mlx4_get_active_ports(dev, slave);
max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;
for (i = 1; i < max_port_p_one; i++) {
struct mlx4_active_ports exclusive_ports;
struct mlx4_slaves_pport slaves_pport_actv;
bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
set_bit(i - 1, exclusive_ports.ports);
if (i == port)
continue;
slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
dev, &exclusive_ports);
slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
dev->num_vfs + 1);
}
gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1;
if (slave_gid <= gids % vfs)
return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave_gid - 1);
return MLX4_ROCE_PF_GIDS + (gids % vfs) +
((gids / vfs) * (slave_gid - 1));
} }
EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix);
static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
u8 op_mod, struct mlx4_cmd_mailbox *inbox) u8 op_mod, struct mlx4_cmd_mailbox *inbox)
...@@ -617,8 +669,8 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, ...@@ -617,8 +669,8 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
* need a FOR-loop here over number of gids the guest has. * need a FOR-loop here over number of gids the guest has.
* 1. Check no duplicates in gids passed by slave * 1. Check no duplicates in gids passed by slave
*/ */
num_gids = mlx4_get_slave_num_gids(dev, slave); num_gids = mlx4_get_slave_num_gids(dev, slave, port);
base = mlx4_get_base_gid_ix(dev, slave); base = mlx4_get_base_gid_ix(dev, slave, port);
gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
for (i = 0; i < num_gids; gid_entry_mbox++, i++) { for (i = 0; i < num_gids; gid_entry_mbox++, i++) {
if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw, if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw,
...@@ -738,6 +790,15 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -738,6 +790,15 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_mailbox *outbox,
struct mlx4_cmd_info *cmd) struct mlx4_cmd_info *cmd)
{ {
int port = mlx4_slave_convert_port(
dev, slave, vhcr->in_modifier & 0xFF);
if (port < 0)
return -EINVAL;
vhcr->in_modifier = (vhcr->in_modifier & ~0xFF) |
(port & 0xFF);
return mlx4_common_set_port(dev, slave, vhcr->in_modifier, return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
vhcr->op_modifier, inbox); vhcr->op_modifier, inbox);
} }
...@@ -1026,10 +1087,16 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, ...@@ -1026,10 +1087,16 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int i, found_ix = -1; int i, found_ix = -1;
int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
struct mlx4_slaves_pport slaves_pport;
unsigned num_vfs;
int slave_gid;
if (!mlx4_is_mfunc(dev)) if (!mlx4_is_mfunc(dev))
return -EINVAL; return -EINVAL;
slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
num_vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1;
for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) { if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) {
found_ix = i; found_ix = i;
...@@ -1039,16 +1106,67 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, ...@@ -1039,16 +1106,67 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
if (found_ix >= 0) { if (found_ix >= 0) {
if (found_ix < MLX4_ROCE_PF_GIDS) if (found_ix < MLX4_ROCE_PF_GIDS)
*slave_id = 0; slave_gid = 0;
else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % dev->num_vfs) * else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) *
(vf_gids / dev->num_vfs + 1)) (vf_gids / num_vfs + 1))
*slave_id = ((found_ix - MLX4_ROCE_PF_GIDS) / slave_gid = ((found_ix - MLX4_ROCE_PF_GIDS) /
(vf_gids / dev->num_vfs + 1)) + 1; (vf_gids / num_vfs + 1)) + 1;
else else
*slave_id = slave_gid =
((found_ix - MLX4_ROCE_PF_GIDS - ((found_ix - MLX4_ROCE_PF_GIDS -
((vf_gids % dev->num_vfs) * ((vf_gids / dev->num_vfs + 1)))) / ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) /
(vf_gids / dev->num_vfs)) + vf_gids % dev->num_vfs + 1; (vf_gids / num_vfs)) + vf_gids % num_vfs + 1;
if (slave_gid) {
struct mlx4_active_ports exclusive_ports;
struct mlx4_active_ports actv_ports;
struct mlx4_slaves_pport slaves_pport_actv;
unsigned max_port_p_one;
int num_slaves_before = 1;
for (i = 1; i < port; i++) {
bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
set_bit(i, exclusive_ports.ports);
slaves_pport_actv =
mlx4_phys_to_slaves_pport_actv(
dev, &exclusive_ports);
num_slaves_before += bitmap_weight(
slaves_pport_actv.slaves,
dev->num_vfs + 1);
}
if (slave_gid < num_slaves_before) {
bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
set_bit(port - 1, exclusive_ports.ports);
slaves_pport_actv =
mlx4_phys_to_slaves_pport_actv(
dev, &exclusive_ports);
slave_gid += bitmap_weight(
slaves_pport_actv.slaves,
dev->num_vfs + 1) -
num_slaves_before;
}
actv_ports = mlx4_get_active_ports(dev, slave_gid);
max_port_p_one = find_first_bit(
actv_ports.ports, dev->caps.num_ports) +
bitmap_weight(actv_ports.ports,
dev->caps.num_ports) + 1;
for (i = 1; i < max_port_p_one; i++) {
if (i == port)
continue;
bitmap_zero(exclusive_ports.ports,
dev->caps.num_ports);
set_bit(i - 1, exclusive_ports.ports);
slaves_pport_actv =
mlx4_phys_to_slaves_pport_actv(
dev, &exclusive_ports);
slave_gid += bitmap_weight(
slaves_pport_actv.slaves,
dev->num_vfs + 1);
}
}
*slave_id = slave_gid;
} }
return (found_ix >= 0) ? 0 : -EINVAL; return (found_ix >= 0) ? 0 : -EINVAL;
......
...@@ -1231,4 +1231,5 @@ struct mlx4_slaves_pport mlx4_phys_to_slaves_pport_actv( ...@@ -1231,4 +1231,5 @@ struct mlx4_slaves_pport mlx4_phys_to_slaves_pport_actv(
/* Returns the slave's virtual port that represents the physical port. */ /* Returns the slave's virtual port that represents the physical port. */
int mlx4_phys_to_slave_port(struct mlx4_dev *dev, int slave, int port); int mlx4_phys_to_slave_port(struct mlx4_dev *dev, int slave, int port);
int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port);
#endif /* MLX4_DEVICE_H */ #endif /* MLX4_DEVICE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment