diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2014-05-29 09:31:03 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-05-30 00:13:09 -0400 |
commit | 99ec41d0a48cb6d14af25765f9449762f9d101f6 (patch) | |
tree | b15baa4835c552a424b9d3ee0e271c4bc5bec273 /drivers/net/ethernet/mellanox/mlx4/fw.c | |
parent | 97982f5a91e91dab26dd0246083b9adf3ba8b2e3 (diff) |
mlx4: Add infrastructure for selecting VFs to enable QP0 via MLX proxy QPs
This commit adds the infrastructure for enabling selected VFs to
operate SMI (QP0) MADs without restriction.
Additionally, for these enabled VFs, their QP0 proxy and tunnel QPs
are MLX QPs. As such, they operate over VL15. Therefore, they are
not affected by "credit" problems or changes in the VLArb table (which
may shut down VL0).
Non-enabled VFs may only create UD proxy QP0 qps (which are forced by
the hypervisor to send packets using the q-key it assigns and places
in the qp-context). Thus, non-enabled VFs will not pose a security
risk. The hypervisor discards any privileged MADs it receives from
these non-enabled VFs.
By default, all VFs are NOT enabled, and must explicitly be enabled
by the administrator.
The sysfs interface which operates the VF enablement infrastructure
is provided in the next commit.
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>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/fw.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index ef242e19766f..01e6dd61ee3c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -178,8 +178,8 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
178 | struct mlx4_cmd_info *cmd) | 178 | struct mlx4_cmd_info *cmd) |
179 | { | 179 | { |
180 | struct mlx4_priv *priv = mlx4_priv(dev); | 180 | struct mlx4_priv *priv = mlx4_priv(dev); |
181 | u8 field; | 181 | u8 field, port; |
182 | u32 size; | 182 | u32 size, proxy_qp, qkey; |
183 | int err = 0; | 183 | int err = 0; |
184 | 184 | ||
185 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 | 185 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 |
@@ -209,6 +209,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
209 | 209 | ||
210 | /* when opcode modifier = 1 */ | 210 | /* when opcode modifier = 1 */ |
211 | #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 | 211 | #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 |
212 | #define QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET 0x4 | ||
212 | #define QUERY_FUNC_CAP_FLAGS0_OFFSET 0x8 | 213 | #define QUERY_FUNC_CAP_FLAGS0_OFFSET 0x8 |
213 | #define QUERY_FUNC_CAP_FLAGS1_OFFSET 0xc | 214 | #define QUERY_FUNC_CAP_FLAGS1_OFFSET 0xc |
214 | 215 | ||
@@ -221,6 +222,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
221 | #define QUERY_FUNC_CAP_FLAGS1_FORCE_MAC 0x40 | 222 | #define QUERY_FUNC_CAP_FLAGS1_FORCE_MAC 0x40 |
222 | #define QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN 0x80 | 223 | #define QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN 0x80 |
223 | #define QUERY_FUNC_CAP_FLAGS1_NIC_INFO 0x10 | 224 | #define QUERY_FUNC_CAP_FLAGS1_NIC_INFO 0x10 |
225 | #define QUERY_FUNC_CAP_VF_ENABLE_QP0 0x08 | ||
224 | 226 | ||
225 | #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 | 227 | #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 |
226 | 228 | ||
@@ -234,28 +236,35 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
234 | return -EINVAL; | 236 | return -EINVAL; |
235 | 237 | ||
236 | vhcr->in_modifier = converted_port; | 238 | vhcr->in_modifier = converted_port; |
237 | /* Set nic_info bit to mark new fields support */ | ||
238 | field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; | ||
239 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); | ||
240 | |||
241 | /* phys-port = logical-port */ | 239 | /* phys-port = logical-port */ |
242 | field = vhcr->in_modifier - | 240 | field = vhcr->in_modifier - |
243 | find_first_bit(actv_ports.ports, dev->caps.num_ports); | 241 | find_first_bit(actv_ports.ports, dev->caps.num_ports); |
244 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 242 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); |
245 | 243 | ||
246 | field = vhcr->in_modifier; | 244 | port = vhcr->in_modifier; |
245 | proxy_qp = dev->phys_caps.base_proxy_sqpn + 8 * slave + port - 1; | ||
246 | |||
247 | /* Set nic_info bit to mark new fields support */ | ||
248 | field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; | ||
249 | |||
250 | if (mlx4_vf_smi_enabled(dev, slave, port) && | ||
251 | !mlx4_get_parav_qkey(dev, proxy_qp, &qkey)) { | ||
252 | field |= QUERY_FUNC_CAP_VF_ENABLE_QP0; | ||
253 | MLX4_PUT(outbox->buf, qkey, | ||
254 | QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET); | ||
255 | } | ||
256 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); | ||
257 | |||
247 | /* size is now the QP number */ | 258 | /* size is now the QP number */ |
248 | size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + field - 1; | 259 | size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + port - 1; |
249 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); | 260 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); |
250 | 261 | ||
251 | size += 2; | 262 | size += 2; |
252 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_TUNNEL); | 263 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_TUNNEL); |
253 | 264 | ||
254 | size = dev->phys_caps.base_proxy_sqpn + 8 * slave + field - 1; | 265 | MLX4_PUT(outbox->buf, proxy_qp, QUERY_FUNC_CAP_QP0_PROXY); |
255 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_PROXY); | 266 | proxy_qp += 2; |
256 | 267 | MLX4_PUT(outbox->buf, proxy_qp, QUERY_FUNC_CAP_QP1_PROXY); | |
257 | size += 2; | ||
258 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY); | ||
259 | 268 | ||
260 | MLX4_PUT(outbox->buf, dev->caps.phys_port_id[vhcr->in_modifier], | 269 | MLX4_PUT(outbox->buf, dev->caps.phys_port_id[vhcr->in_modifier], |
261 | QUERY_FUNC_CAP_PHYS_PORT_ID); | 270 | QUERY_FUNC_CAP_PHYS_PORT_ID); |
@@ -326,7 +335,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port, | |||
326 | struct mlx4_cmd_mailbox *mailbox; | 335 | struct mlx4_cmd_mailbox *mailbox; |
327 | u32 *outbox; | 336 | u32 *outbox; |
328 | u8 field, op_modifier; | 337 | u8 field, op_modifier; |
329 | u32 size; | 338 | u32 size, qkey; |
330 | int err = 0, quotas = 0; | 339 | int err = 0, quotas = 0; |
331 | 340 | ||
332 | op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ | 341 | op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ |
@@ -442,6 +451,13 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port, | |||
442 | goto out; | 451 | goto out; |
443 | } | 452 | } |
444 | 453 | ||
454 | if (func_cap->flags1 & QUERY_FUNC_CAP_VF_ENABLE_QP0) { | ||
455 | MLX4_GET(qkey, outbox, QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET); | ||
456 | func_cap->qp0_qkey = qkey; | ||
457 | } else { | ||
458 | func_cap->qp0_qkey = 0; | ||
459 | } | ||
460 | |||
445 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_TUNNEL); | 461 | MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_TUNNEL); |
446 | func_cap->qp0_tunnel_qpn = size & 0xFFFFFF; | 462 | func_cap->qp0_tunnel_qpn = size & 0xFFFFFF; |
447 | 463 | ||