diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2012-06-19 04:21:43 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-07-11 14:51:37 -0400 |
commit | 105c320f6ac37af30252577d419e47b39edb5843 (patch) | |
tree | 4b1b6ebaebf4eaf5c76d47d4a565d75a4f3399ec | |
parent | 396f2feb05d7cc5549c611c05abfb4108cd1c6d6 (diff) |
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: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 78 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 26 |
2 files changed, 59 insertions, 45 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index ee9d6b0b4d20..5549f6b3bb67 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -174,6 +174,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
174 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 | 174 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 |
175 | #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 | 175 | #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 |
176 | #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 | 176 | #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 |
177 | #define QUERY_FUNC_CAP_FMR_OFFSET 0x8 | ||
177 | #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 | 178 | #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 |
178 | #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 | 179 | #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 |
179 | #define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18 | 180 | #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 | #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c | 184 | #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c |
184 | #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 | 185 | #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 |
185 | 186 | ||
187 | #define QUERY_FUNC_CAP_FMR_FLAG 0x80 | ||
188 | #define QUERY_FUNC_CAP_FLAG_RDMA 0x40 | ||
189 | #define QUERY_FUNC_CAP_FLAG_ETH 0x80 | ||
190 | |||
191 | /* when opcode modifier = 1 */ | ||
186 | #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 | 192 | #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 |
193 | #define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET 0x8 | ||
187 | #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc | 194 | #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc |
188 | 195 | ||
196 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC 0x40 | ||
197 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN 0x80 | ||
198 | |||
199 | #define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80 | ||
200 | |||
189 | if (vhcr->op_modifier == 1) { | 201 | if (vhcr->op_modifier == 1) { |
190 | field = vhcr->in_modifier; | 202 | field = vhcr->in_modifier; |
191 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 203 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); |
192 | 204 | ||
193 | field = 0; /* ensure fvl bit is not set */ | 205 | field = 0; |
206 | /* ensure force vlan and force mac bits are not set */ | ||
194 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); | 207 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); |
208 | /* ensure that phy_wqe_gid bit is not set */ | ||
209 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); | ||
210 | |||
195 | } else if (vhcr->op_modifier == 0) { | 211 | } else if (vhcr->op_modifier == 0) { |
196 | field = 1 << 7; /* enable only ethernet interface */ | 212 | /* enable rdma and ethernet interfaces */ |
213 | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA); | ||
197 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); | 214 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); |
198 | 215 | ||
199 | field = dev->caps.num_ports; | 216 | field = dev->caps.num_ports; |
200 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 217 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
201 | 218 | ||
202 | size = 0; /* no PF behavious is set for now */ | 219 | size = 0; /* no PF behaviour is set for now */ |
203 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); | 220 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); |
204 | 221 | ||
222 | field = 0; /* protected FMR support not available as yet */ | ||
223 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); | ||
224 | |||
205 | size = dev->caps.num_qps; | 225 | size = dev->caps.num_qps; |
206 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); | 226 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); |
207 | 227 | ||
@@ -254,11 +274,12 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) | |||
254 | outbox = mailbox->buf; | 274 | outbox = mailbox->buf; |
255 | 275 | ||
256 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); | 276 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); |
257 | if (!(field & (1 << 7))) { | 277 | if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) { |
258 | mlx4_err(dev, "The host doesn't support eth interface\n"); | 278 | mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n"); |
259 | err = -EPROTONOSUPPORT; | 279 | err = -EPROTONOSUPPORT; |
260 | goto out; | 280 | goto out; |
261 | } | 281 | } |
282 | func_cap->flags = field; | ||
262 | 283 | ||
263 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 284 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
264 | func_cap->num_ports = field; | 285 | 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 | if (err) | 318 | if (err) |
298 | goto out; | 319 | goto out; |
299 | 320 | ||
300 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); | 321 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) { |
301 | if (field & (1 << 7)) { | 322 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); |
302 | mlx4_err(dev, "VLAN is enforced on this port\n"); | 323 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) { |
303 | err = -EPROTONOSUPPORT; | 324 | mlx4_err(dev, "VLAN is enforced on this port\n"); |
304 | goto out; | 325 | err = -EPROTONOSUPPORT; |
305 | } | 326 | goto out; |
327 | } | ||
306 | 328 | ||
307 | if (field & (1 << 6)) { | 329 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) { |
308 | mlx4_err(dev, "Force mac is enabled on this port\n"); | 330 | mlx4_err(dev, "Force mac is enabled on this port\n"); |
309 | err = -EPROTONOSUPPORT; | 331 | err = -EPROTONOSUPPORT; |
310 | goto out; | 332 | goto out; |
333 | } | ||
334 | } else if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) { | ||
335 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); | ||
336 | if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) { | ||
337 | mlx4_err(dev, "phy_wqe_gid is " | ||
338 | "enforced on this ib port\n"); | ||
339 | err = -EPROTONOSUPPORT; | ||
340 | goto out; | ||
341 | } | ||
311 | } | 342 | } |
312 | 343 | ||
313 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 344 | 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 | u8 port_type; | 732 | u8 port_type; |
702 | int err; | 733 | int err; |
703 | 734 | ||
704 | #define MLX4_PORT_SUPPORT_IB (1 << 0) | 735 | #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 |
705 | #define MLX4_PORT_SUGGEST_TYPE (1 << 3) | ||
706 | #define MLX4_PORT_DEFAULT_SENSE (1 << 4) | ||
707 | #define MLX4_VF_PORT_ETH_ONLY_MASK (0xff & ~MLX4_PORT_SUPPORT_IB & \ | ||
708 | ~MLX4_PORT_SUGGEST_TYPE & \ | ||
709 | ~MLX4_PORT_DEFAULT_SENSE) | ||
710 | 736 | ||
711 | err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, | 737 | err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, |
712 | MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, | 738 | 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 | MLX4_GET(port_type, outbox->buf, | 748 | MLX4_GET(port_type, outbox->buf, |
723 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 749 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
724 | 750 | ||
725 | /* Allow only Eth port, no link sensing allowed */ | 751 | /* No link sensing allowed */ |
726 | port_type &= MLX4_VF_PORT_ETH_ONLY_MASK; | 752 | port_type &= MLX4_VF_PORT_NO_LINK_SENSE_MASK; |
727 | 753 | /* set port type to currently operating port type */ | |
728 | /* check eth is enabled for this port */ | 754 | port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); |
729 | if (!(port_type & 2)) | ||
730 | mlx4_dbg(dev, "QUERY PORT: eth not supported by host"); | ||
731 | 755 | ||
732 | MLX4_PUT(outbox->buf, port_type, | 756 | MLX4_PUT(outbox->buf, port_type, |
733 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 757 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 81154a16d6b8..58544b72bacb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -288,29 +288,19 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
288 | /* if only ETH is supported - assign ETH */ | 288 | /* if only ETH is supported - assign ETH */ |
289 | if (dev->caps.supported_type[i] == MLX4_PORT_TYPE_ETH) | 289 | if (dev->caps.supported_type[i] == MLX4_PORT_TYPE_ETH) |
290 | dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; | 290 | dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; |
291 | /* if only IB is supported, | 291 | /* if only IB is supported, assign IB */ |
292 | * assign IB only if SRIOV is off*/ | ||
293 | else if (dev->caps.supported_type[i] == | 292 | else if (dev->caps.supported_type[i] == |
294 | MLX4_PORT_TYPE_IB) { | 293 | MLX4_PORT_TYPE_IB) |
295 | if (dev->flags & MLX4_FLAG_SRIOV) | 294 | dev->caps.port_type[i] = MLX4_PORT_TYPE_IB; |
296 | dev->caps.port_type[i] = | ||
297 | MLX4_PORT_TYPE_NONE; | ||
298 | else | ||
299 | dev->caps.port_type[i] = | ||
300 | MLX4_PORT_TYPE_IB; | ||
301 | /* if IB and ETH are supported, | ||
302 | * first of all check if SRIOV is on */ | ||
303 | } else if (dev->flags & MLX4_FLAG_SRIOV) | ||
304 | dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; | ||
305 | else { | 295 | else { |
306 | /* In non-SRIOV mode, we set the port type | 296 | /* if IB and ETH are supported, we set the port |
307 | * according to user selection of port type, | 297 | * type according to user selection of port type; |
308 | * if usere selected none, take the FW hint */ | 298 | * if user selected none, take the FW hint */ |
309 | if (port_type_array[i-1] == MLX4_PORT_TYPE_NONE) | 299 | if (port_type_array[i - 1] == MLX4_PORT_TYPE_NONE) |
310 | dev->caps.port_type[i] = dev->caps.suggested_type[i] ? | 300 | dev->caps.port_type[i] = dev->caps.suggested_type[i] ? |
311 | MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB; | 301 | MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB; |
312 | else | 302 | else |
313 | dev->caps.port_type[i] = port_type_array[i-1]; | 303 | dev->caps.port_type[i] = port_type_array[i - 1]; |
314 | } | 304 | } |
315 | } | 305 | } |
316 | /* | 306 | /* |