aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c52
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c44
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c26
-rw-r--r--include/linux/mlx4/device.h1
8 files changed, 126 insertions, 35 deletions
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 2e8c58806e2f..b25600997cb6 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -608,6 +608,16 @@ static int qp_has_rq(struct ib_qp_init_attr *attr)
608 return !attr->srq; 608 return !attr->srq;
609} 609}
610 610
611static int qp0_enabled_vf(struct mlx4_dev *dev, int qpn)
612{
613 int i;
614 for (i = 0; i < dev->caps.num_ports; i++) {
615 if (qpn == dev->caps.qp0_proxy[i])
616 return !!dev->caps.qp0_qkey[i];
617 }
618 return 0;
619}
620
611static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, 621static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
612 struct ib_qp_init_attr *init_attr, 622 struct ib_qp_init_attr *init_attr,
613 struct ib_udata *udata, int sqpn, struct mlx4_ib_qp **caller_qp) 623 struct ib_udata *udata, int sqpn, struct mlx4_ib_qp **caller_qp)
@@ -625,10 +635,13 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
625 !(init_attr->create_flags & MLX4_IB_SRIOV_SQP))) { 635 !(init_attr->create_flags & MLX4_IB_SRIOV_SQP))) {
626 if (init_attr->qp_type == IB_QPT_GSI) 636 if (init_attr->qp_type == IB_QPT_GSI)
627 qp_type = MLX4_IB_QPT_PROXY_GSI; 637 qp_type = MLX4_IB_QPT_PROXY_GSI;
628 else if (mlx4_is_master(dev->dev)) 638 else {
629 qp_type = MLX4_IB_QPT_PROXY_SMI_OWNER; 639 if (mlx4_is_master(dev->dev) ||
630 else 640 qp0_enabled_vf(dev->dev, sqpn))
631 qp_type = MLX4_IB_QPT_PROXY_SMI; 641 qp_type = MLX4_IB_QPT_PROXY_SMI_OWNER;
642 else
643 qp_type = MLX4_IB_QPT_PROXY_SMI;
644 }
632 } 645 }
633 qpn = sqpn; 646 qpn = sqpn;
634 /* add extra sg entry for tunneling */ 647 /* add extra sg entry for tunneling */
@@ -643,7 +656,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
643 return -EINVAL; 656 return -EINVAL;
644 if (tnl_init->proxy_qp_type == IB_QPT_GSI) 657 if (tnl_init->proxy_qp_type == IB_QPT_GSI)
645 qp_type = MLX4_IB_QPT_TUN_GSI; 658 qp_type = MLX4_IB_QPT_TUN_GSI;
646 else if (tnl_init->slave == mlx4_master_func_num(dev->dev)) 659 else if (tnl_init->slave == mlx4_master_func_num(dev->dev) ||
660 mlx4_vf_smi_enabled(dev->dev, tnl_init->slave,
661 tnl_init->port))
647 qp_type = MLX4_IB_QPT_TUN_SMI_OWNER; 662 qp_type = MLX4_IB_QPT_TUN_SMI_OWNER;
648 else 663 else
649 qp_type = MLX4_IB_QPT_TUN_SMI; 664 qp_type = MLX4_IB_QPT_TUN_SMI;
@@ -1930,6 +1945,19 @@ out:
1930 return err; 1945 return err;
1931} 1946}
1932 1947
1948static int vf_get_qp0_qkey(struct mlx4_dev *dev, int qpn, u32 *qkey)
1949{
1950 int i;
1951 for (i = 0; i < dev->caps.num_ports; i++) {
1952 if (qpn == dev->caps.qp0_proxy[i] ||
1953 qpn == dev->caps.qp0_tunnel[i]) {
1954 *qkey = dev->caps.qp0_qkey[i];
1955 return 0;
1956 }
1957 }
1958 return -EINVAL;
1959}
1960
1933static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, 1961static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp,
1934 struct ib_send_wr *wr, 1962 struct ib_send_wr *wr,
1935 void *wqe, unsigned *mlx_seg_len) 1963 void *wqe, unsigned *mlx_seg_len)
@@ -1987,8 +2015,13 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp,
1987 cpu_to_be32(mdev->dev->caps.qp0_tunnel[sqp->qp.port - 1]); 2015 cpu_to_be32(mdev->dev->caps.qp0_tunnel[sqp->qp.port - 1]);
1988 2016
1989 sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); 2017 sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1));
1990 if (mlx4_get_parav_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey)) 2018 if (mlx4_is_master(mdev->dev)) {
1991 return -EINVAL; 2019 if (mlx4_get_parav_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey))
2020 return -EINVAL;
2021 } else {
2022 if (vf_get_qp0_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey))
2023 return -EINVAL;
2024 }
1992 sqp->ud_header.deth.qkey = cpu_to_be32(qkey); 2025 sqp->ud_header.deth.qkey = cpu_to_be32(qkey);
1993 sqp->ud_header.deth.source_qpn = cpu_to_be32(sqp->qp.mqp.qpn); 2026 sqp->ud_header.deth.source_qpn = cpu_to_be32(sqp->qp.mqp.qpn);
1994 2027
@@ -2682,11 +2715,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2682 break; 2715 break;
2683 2716
2684 case MLX4_IB_QPT_PROXY_SMI_OWNER: 2717 case MLX4_IB_QPT_PROXY_SMI_OWNER:
2685 if (unlikely(!mlx4_is_master(to_mdev(ibqp->device)->dev))) {
2686 err = -ENOSYS;
2687 *bad_wr = wr;
2688 goto out;
2689 }
2690 err = build_sriov_qp0_header(to_msqp(qp), wr, ctrl, &seglen); 2718 err = build_sriov_qp0_header(to_msqp(qp), wr, ctrl, &seglen);
2691 if (unlikely(err)) { 2719 if (unlikely(err)) {
2692 *bad_wr = wr; 2720 *bad_wr = wr;
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index b0e48d426fce..26c3ebaa49d1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1666,6 +1666,8 @@ static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
1666 for (port = min_port; port <= max_port; port++) { 1666 for (port = min_port; port <= max_port; port++) {
1667 if (!test_bit(port - 1, actv_ports.ports)) 1667 if (!test_bit(port - 1, actv_ports.ports))
1668 continue; 1668 continue;
1669 priv->mfunc.master.vf_oper[slave].smi_enabled[port] =
1670 priv->mfunc.master.vf_admin[slave].enable_smi[port];
1669 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; 1671 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1670 vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; 1672 vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
1671 vp_oper->state = *vp_admin; 1673 vp_oper->state = *vp_admin;
@@ -1717,6 +1719,8 @@ static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave
1717 for (port = min_port; port <= max_port; port++) { 1719 for (port = min_port; port <= max_port; port++) {
1718 if (!test_bit(port - 1, actv_ports.ports)) 1720 if (!test_bit(port - 1, actv_ports.ports))
1719 continue; 1721 continue;
1722 priv->mfunc.master.vf_oper[slave].smi_enabled[port] =
1723 MLX4_VF_SMI_DISABLED;
1720 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; 1724 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1721 if (NO_INDX != vp_oper->vlan_idx) { 1725 if (NO_INDX != vp_oper->vlan_idx) {
1722 __mlx4_unregister_vlan(&priv->dev, 1726 __mlx4_unregister_vlan(&priv->dev,
@@ -2553,6 +2557,13 @@ EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
2553 2557
2554int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port) 2558int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
2555{ 2559{
2556 return 0; 2560 struct mlx4_priv *priv = mlx4_priv(dev);
2561
2562 if (slave < 1 || slave >= dev->num_slaves ||
2563 port < 1 || port > MLX4_MAX_PORTS)
2564 return 0;
2565
2566 return priv->mfunc.master.vf_oper[slave].smi_enabled[port] ==
2567 MLX4_VF_SMI_ENABLED;
2557} 2568}
2558EXPORT_SYMBOL_GPL(mlx4_vf_smi_enabled); 2569EXPORT_SYMBOL_GPL(mlx4_vf_smi_enabled);
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
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index 6811ee00ba7c..1fce03ebe5c4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -134,6 +134,7 @@ struct mlx4_func_cap {
134 int max_eq; 134 int max_eq;
135 int reserved_eq; 135 int reserved_eq;
136 int mcg_quota; 136 int mcg_quota;
137 u32 qp0_qkey;
137 u32 qp0_tunnel_qpn; 138 u32 qp0_tunnel_qpn;
138 u32 qp0_proxy_qpn; 139 u32 qp0_proxy_qpn;
139 u32 qp1_tunnel_qpn; 140 u32 qp1_tunnel_qpn;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 12a7ee2e6098..908326876ab5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -666,13 +666,15 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
666 return -ENODEV; 666 return -ENODEV;
667 } 667 }
668 668
669 dev->caps.qp0_qkey = kcalloc(dev->caps.num_ports, sizeof(u32), GFP_KERNEL);
669 dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); 670 dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
670 dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); 671 dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
671 dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); 672 dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
672 dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); 673 dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
673 674
674 if (!dev->caps.qp0_tunnel || !dev->caps.qp0_proxy || 675 if (!dev->caps.qp0_tunnel || !dev->caps.qp0_proxy ||
675 !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy) { 676 !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy ||
677 !dev->caps.qp0_qkey) {
676 err = -ENOMEM; 678 err = -ENOMEM;
677 goto err_mem; 679 goto err_mem;
678 } 680 }
@@ -684,6 +686,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
684 " port %d, aborting (%d).\n", i, err); 686 " port %d, aborting (%d).\n", i, err);
685 goto err_mem; 687 goto err_mem;
686 } 688 }
689 dev->caps.qp0_qkey[i - 1] = func_cap.qp0_qkey;
687 dev->caps.qp0_tunnel[i - 1] = func_cap.qp0_tunnel_qpn; 690 dev->caps.qp0_tunnel[i - 1] = func_cap.qp0_tunnel_qpn;
688 dev->caps.qp0_proxy[i - 1] = func_cap.qp0_proxy_qpn; 691 dev->caps.qp0_proxy[i - 1] = func_cap.qp0_proxy_qpn;
689 dev->caps.qp1_tunnel[i - 1] = func_cap.qp1_tunnel_qpn; 692 dev->caps.qp1_tunnel[i - 1] = func_cap.qp1_tunnel_qpn;
@@ -729,12 +732,16 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
729 return 0; 732 return 0;
730 733
731err_mem: 734err_mem:
735 kfree(dev->caps.qp0_qkey);
732 kfree(dev->caps.qp0_tunnel); 736 kfree(dev->caps.qp0_tunnel);
733 kfree(dev->caps.qp0_proxy); 737 kfree(dev->caps.qp0_proxy);
734 kfree(dev->caps.qp1_tunnel); 738 kfree(dev->caps.qp1_tunnel);
735 kfree(dev->caps.qp1_proxy); 739 kfree(dev->caps.qp1_proxy);
736 dev->caps.qp0_tunnel = dev->caps.qp0_proxy = 740 dev->caps.qp0_qkey = NULL;
737 dev->caps.qp1_tunnel = dev->caps.qp1_proxy = NULL; 741 dev->caps.qp0_tunnel = NULL;
742 dev->caps.qp0_proxy = NULL;
743 dev->caps.qp1_tunnel = NULL;
744 dev->caps.qp1_proxy = NULL;
738 745
739 return err; 746 return err;
740} 747}
@@ -1697,6 +1704,7 @@ unmap_bf:
1697 unmap_bf_area(dev); 1704 unmap_bf_area(dev);
1698 1705
1699 if (mlx4_is_slave(dev)) { 1706 if (mlx4_is_slave(dev)) {
1707 kfree(dev->caps.qp0_qkey);
1700 kfree(dev->caps.qp0_tunnel); 1708 kfree(dev->caps.qp0_tunnel);
1701 kfree(dev->caps.qp0_proxy); 1709 kfree(dev->caps.qp0_proxy);
1702 kfree(dev->caps.qp1_tunnel); 1710 kfree(dev->caps.qp1_tunnel);
@@ -2573,6 +2581,7 @@ err_master_mfunc:
2573 mlx4_multi_func_cleanup(dev); 2581 mlx4_multi_func_cleanup(dev);
2574 2582
2575 if (mlx4_is_slave(dev)) { 2583 if (mlx4_is_slave(dev)) {
2584 kfree(dev->caps.qp0_qkey);
2576 kfree(dev->caps.qp0_tunnel); 2585 kfree(dev->caps.qp0_tunnel);
2577 kfree(dev->caps.qp0_proxy); 2586 kfree(dev->caps.qp0_proxy);
2578 kfree(dev->caps.qp1_tunnel); 2587 kfree(dev->caps.qp1_tunnel);
@@ -2702,6 +2711,7 @@ static void __mlx4_remove_one(struct pci_dev *pdev)
2702 if (!mlx4_is_slave(dev)) 2711 if (!mlx4_is_slave(dev))
2703 mlx4_free_ownership(dev); 2712 mlx4_free_ownership(dev);
2704 2713
2714 kfree(dev->caps.qp0_qkey);
2705 kfree(dev->caps.qp0_tunnel); 2715 kfree(dev->caps.qp0_tunnel);
2706 kfree(dev->caps.qp0_proxy); 2716 kfree(dev->caps.qp0_proxy);
2707 kfree(dev->caps.qp1_tunnel); 2717 kfree(dev->caps.qp1_tunnel);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index f9c465101963..0efd1738fcb3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -133,6 +133,11 @@ enum {
133 MLX4_COMM_CMD_FLR = 254 133 MLX4_COMM_CMD_FLR = 254
134}; 134};
135 135
136enum {
137 MLX4_VF_SMI_DISABLED,
138 MLX4_VF_SMI_ENABLED
139};
140
136/*The flag indicates that the slave should delay the RESET cmd*/ 141/*The flag indicates that the slave should delay the RESET cmd*/
137#define MLX4_DELAY_RESET_SLAVE 0xbbbbbbb 142#define MLX4_DELAY_RESET_SLAVE 0xbbbbbbb
138/*indicates how many retries will be done if we are in the middle of FLR*/ 143/*indicates how many retries will be done if we are in the middle of FLR*/
@@ -488,6 +493,7 @@ struct mlx4_vport_state {
488 493
489struct mlx4_vf_admin_state { 494struct mlx4_vf_admin_state {
490 struct mlx4_vport_state vport[MLX4_MAX_PORTS + 1]; 495 struct mlx4_vport_state vport[MLX4_MAX_PORTS + 1];
496 u8 enable_smi[MLX4_MAX_PORTS + 1];
491}; 497};
492 498
493struct mlx4_vport_oper_state { 499struct mlx4_vport_oper_state {
@@ -495,8 +501,10 @@ struct mlx4_vport_oper_state {
495 int mac_idx; 501 int mac_idx;
496 int vlan_idx; 502 int vlan_idx;
497}; 503};
504
498struct mlx4_vf_oper_state { 505struct mlx4_vf_oper_state {
499 struct mlx4_vport_oper_state vport[MLX4_MAX_PORTS + 1]; 506 struct mlx4_vport_oper_state vport[MLX4_MAX_PORTS + 1];
507 u8 smi_enabled[MLX4_MAX_PORTS + 1];
500}; 508};
501 509
502struct slave_list { 510struct slave_list {
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 1c3fdd4a1f7d..ad98162a8d79 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2827,10 +2827,12 @@ static int get_containing_mtt(struct mlx4_dev *dev, int slave, int start,
2827} 2827}
2828 2828
2829static int verify_qp_parameters(struct mlx4_dev *dev, 2829static int verify_qp_parameters(struct mlx4_dev *dev,
2830 struct mlx4_vhcr *vhcr,
2830 struct mlx4_cmd_mailbox *inbox, 2831 struct mlx4_cmd_mailbox *inbox,
2831 enum qp_transition transition, u8 slave) 2832 enum qp_transition transition, u8 slave)
2832{ 2833{
2833 u32 qp_type; 2834 u32 qp_type;
2835 u32 qpn;
2834 struct mlx4_qp_context *qp_ctx; 2836 struct mlx4_qp_context *qp_ctx;
2835 enum mlx4_qp_optpar optpar; 2837 enum mlx4_qp_optpar optpar;
2836 int port; 2838 int port;
@@ -2870,6 +2872,20 @@ static int verify_qp_parameters(struct mlx4_dev *dev,
2870 return -EINVAL; 2872 return -EINVAL;
2871 } 2873 }
2872 break; 2874 break;
2875 case MLX4_QP_ST_MLX:
2876 qpn = vhcr->in_modifier & 0x7fffff;
2877 port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
2878 if (transition == QP_TRANS_INIT2RTR &&
2879 slave != mlx4_master_func_num(dev) &&
2880 mlx4_is_qp_reserved(dev, qpn) &&
2881 !mlx4_vf_smi_enabled(dev, slave, port)) {
2882 /* only enabled VFs may create MLX proxy QPs */
2883 mlx4_err(dev, "%s: unprivileged slave %d attempting to create an MLX proxy special QP on port %d\n",
2884 __func__, slave, port);
2885 return -EPERM;
2886 }
2887 break;
2888
2873 default: 2889 default:
2874 break; 2890 break;
2875 } 2891 }
@@ -3454,7 +3470,7 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
3454 err = adjust_qp_sched_queue(dev, slave, qpc, inbox); 3470 err = adjust_qp_sched_queue(dev, slave, qpc, inbox);
3455 if (err) 3471 if (err)
3456 return err; 3472 return err;
3457 err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave); 3473 err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_INIT2RTR, slave);
3458 if (err) 3474 if (err)
3459 return err; 3475 return err;
3460 3476
@@ -3508,7 +3524,7 @@ int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3508 err = adjust_qp_sched_queue(dev, slave, context, inbox); 3524 err = adjust_qp_sched_queue(dev, slave, context, inbox);
3509 if (err) 3525 if (err)
3510 return err; 3526 return err;
3511 err = verify_qp_parameters(dev, inbox, QP_TRANS_RTR2RTS, slave); 3527 err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_RTR2RTS, slave);
3512 if (err) 3528 if (err)
3513 return err; 3529 return err;
3514 3530
@@ -3530,7 +3546,7 @@ int mlx4_RTS2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3530 err = adjust_qp_sched_queue(dev, slave, context, inbox); 3546 err = adjust_qp_sched_queue(dev, slave, context, inbox);
3531 if (err) 3547 if (err)
3532 return err; 3548 return err;
3533 err = verify_qp_parameters(dev, inbox, QP_TRANS_RTS2RTS, slave); 3549 err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_RTS2RTS, slave);
3534 if (err) 3550 if (err)
3535 return err; 3551 return err;
3536 3552
@@ -3567,7 +3583,7 @@ int mlx4_SQD2SQD_QP_wrapper(struct mlx4_dev *dev, int slave,
3567 err = adjust_qp_sched_queue(dev, slave, context, inbox); 3583 err = adjust_qp_sched_queue(dev, slave, context, inbox);
3568 if (err) 3584 if (err)
3569 return err; 3585 return err;
3570 err = verify_qp_parameters(dev, inbox, QP_TRANS_SQD2SQD, slave); 3586 err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_SQD2SQD, slave);
3571 if (err) 3587 if (err)
3572 return err; 3588 return err;
3573 3589
@@ -3589,7 +3605,7 @@ int mlx4_SQD2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3589 err = adjust_qp_sched_queue(dev, slave, context, inbox); 3605 err = adjust_qp_sched_queue(dev, slave, context, inbox);
3590 if (err) 3606 if (err)
3591 return err; 3607 return err;
3592 err = verify_qp_parameters(dev, inbox, QP_TRANS_SQD2RTS, slave); 3608 err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_SQD2RTS, slave);
3593 if (err) 3609 if (err)
3594 return err; 3610 return err;
3595 3611
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 83612faa819c..e2fc7011314c 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -401,6 +401,7 @@ struct mlx4_caps {
401 int max_rq_desc_sz; 401 int max_rq_desc_sz;
402 int max_qp_init_rdma; 402 int max_qp_init_rdma;
403 int max_qp_dest_rdma; 403 int max_qp_dest_rdma;
404 u32 *qp0_qkey;
404 u32 *qp0_proxy; 405 u32 *qp0_proxy;
405 u32 *qp1_proxy; 406 u32 *qp1_proxy;
406 u32 *qp0_tunnel; 407 u32 *qp0_tunnel;