aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/fw.c
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2014-05-29 09:31:03 -0400
committerRoland Dreier <roland@purestorage.com>2014-05-30 00:13:09 -0400
commit99ec41d0a48cb6d14af25765f9449762f9d101f6 (patch)
treeb15baa4835c552a424b9d3ee0e271c4bc5bec273 /drivers/net/ethernet/mellanox/mlx4/fw.c
parent97982f5a91e91dab26dd0246083b9adf3ba8b2e3 (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.c44
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