提交 105c320f 编写于 作者: J Jack Morgenstein 提交者: Roland Dreier

mlx4_core: Allow guests to have IB ports

Modify mlx4_dev_cap to allow IB support when SR-IOV is active.  Modify
mlx4_slave_cap to set the "rdma-supported" bit in its flags area, and
pass that to the guests (this is done in QUERY_FUNC_CAP and its
wrapper).

However, we don't activate IB support quite yet -- we leave the error
return at the start of mlx4_ib_add in the mlx4_ib driver.

In addition, set "protected fmr supported" bit to zero in the
QUERY_FUNC_CAP wrapper.

Finally, in the QUERY_FUNC_CAP wrapper, we needed to add code which
checks for the port type (IB or Ethernet).  Previously, this was not
an issue, since only Ethernet ports were supported.
Signed-off-by: NJack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: NOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: NRoland Dreier <roland@purestorage.com>
上级 396f2feb
...@@ -174,6 +174,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -174,6 +174,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
#define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0
#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1
#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4
#define QUERY_FUNC_CAP_FMR_OFFSET 0x8
#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10
#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14
#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18 #define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18
...@@ -183,25 +184,44 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -183,25 +184,44 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
#define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c
#define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30
#define QUERY_FUNC_CAP_FMR_FLAG 0x80
#define QUERY_FUNC_CAP_FLAG_RDMA 0x40
#define QUERY_FUNC_CAP_FLAG_ETH 0x80
/* when opcode modifier = 1 */
#define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3
#define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET 0x8
#define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc
#define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC 0x40
#define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN 0x80
#define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80
if (vhcr->op_modifier == 1) { if (vhcr->op_modifier == 1) {
field = vhcr->in_modifier; field = vhcr->in_modifier;
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET);
field = 0; /* ensure fvl bit is not set */ field = 0;
/* ensure force vlan and force mac bits are not set */
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET);
/* ensure that phy_wqe_gid bit is not set */
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET);
} else if (vhcr->op_modifier == 0) { } else if (vhcr->op_modifier == 0) {
field = 1 << 7; /* enable only ethernet interface */ /* enable rdma and ethernet interfaces */
field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA);
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 = 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 = 0; /* no PF behavious is set for now */ size = 0; /* no PF behaviour is set for now */
MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET);
field = 0; /* protected FMR support not available as yet */
MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET);
size = dev->caps.num_qps; size = dev->caps.num_qps;
MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
...@@ -254,11 +274,12 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) ...@@ -254,11 +274,12 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap)
outbox = mailbox->buf; outbox = mailbox->buf;
MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET);
if (!(field & (1 << 7))) { if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) {
mlx4_err(dev, "The host doesn't support eth interface\n"); mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n");
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
goto out; goto out;
} }
func_cap->flags = field;
MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
func_cap->num_ports = field; func_cap->num_ports = field;
...@@ -297,17 +318,27 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) ...@@ -297,17 +318,27 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap)
if (err) if (err)
goto out; goto out;
MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) {
if (field & (1 << 7)) { MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET);
mlx4_err(dev, "VLAN is enforced on this port\n"); if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) {
err = -EPROTONOSUPPORT; mlx4_err(dev, "VLAN is enforced on this port\n");
goto out; err = -EPROTONOSUPPORT;
} goto out;
}
if (field & (1 << 6)) { if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) {
mlx4_err(dev, "Force mac is enabled on this port\n"); mlx4_err(dev, "Force mac is enabled on this port\n");
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
goto out; goto out;
}
} else if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) {
MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET);
if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) {
mlx4_err(dev, "phy_wqe_gid is "
"enforced on this ib port\n");
err = -EPROTONOSUPPORT;
goto out;
}
} }
MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET);
...@@ -701,12 +732,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -701,12 +732,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
u8 port_type; u8 port_type;
int err; int err;
#define MLX4_PORT_SUPPORT_IB (1 << 0) #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0
#define MLX4_PORT_SUGGEST_TYPE (1 << 3)
#define MLX4_PORT_DEFAULT_SENSE (1 << 4)
#define MLX4_VF_PORT_ETH_ONLY_MASK (0xff & ~MLX4_PORT_SUPPORT_IB & \
~MLX4_PORT_SUGGEST_TYPE & \
~MLX4_PORT_DEFAULT_SENSE)
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,
...@@ -722,12 +748,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, ...@@ -722,12 +748,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
MLX4_GET(port_type, outbox->buf, MLX4_GET(port_type, outbox->buf,
QUERY_PORT_SUPPORTED_TYPE_OFFSET); QUERY_PORT_SUPPORTED_TYPE_OFFSET);
/* Allow only Eth port, no link sensing allowed */ /* No link sensing allowed */
port_type &= MLX4_VF_PORT_ETH_ONLY_MASK; port_type &= MLX4_VF_PORT_NO_LINK_SENSE_MASK;
/* set port type to currently operating port type */
/* check eth is enabled for this port */ port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3);
if (!(port_type & 2))
mlx4_dbg(dev, "QUERY PORT: eth not supported by host");
MLX4_PUT(outbox->buf, port_type, MLX4_PUT(outbox->buf, port_type,
QUERY_PORT_SUPPORTED_TYPE_OFFSET); QUERY_PORT_SUPPORTED_TYPE_OFFSET);
......
...@@ -288,29 +288,19 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -288,29 +288,19 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
/* if only ETH is supported - assign ETH */ /* if only ETH is supported - assign ETH */
if (dev->caps.supported_type[i] == MLX4_PORT_TYPE_ETH) if (dev->caps.supported_type[i] == MLX4_PORT_TYPE_ETH)
dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
/* if only IB is supported, /* if only IB is supported, assign IB */
* assign IB only if SRIOV is off*/
else if (dev->caps.supported_type[i] == else if (dev->caps.supported_type[i] ==
MLX4_PORT_TYPE_IB) { MLX4_PORT_TYPE_IB)
if (dev->flags & MLX4_FLAG_SRIOV) dev->caps.port_type[i] = MLX4_PORT_TYPE_IB;
dev->caps.port_type[i] =
MLX4_PORT_TYPE_NONE;
else
dev->caps.port_type[i] =
MLX4_PORT_TYPE_IB;
/* if IB and ETH are supported,
* first of all check if SRIOV is on */
} else if (dev->flags & MLX4_FLAG_SRIOV)
dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
else { else {
/* In non-SRIOV mode, we set the port type /* if IB and ETH are supported, we set the port
* according to user selection of port type, * type according to user selection of port type;
* if usere selected none, take the FW hint */ * if user selected none, take the FW hint */
if (port_type_array[i-1] == MLX4_PORT_TYPE_NONE) if (port_type_array[i - 1] == MLX4_PORT_TYPE_NONE)
dev->caps.port_type[i] = dev->caps.suggested_type[i] ? dev->caps.port_type[i] = dev->caps.suggested_type[i] ?
MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB; MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB;
else else
dev->caps.port_type[i] = port_type_array[i-1]; dev->caps.port_type[i] = port_type_array[i - 1];
} }
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册