diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 52 |
1 files changed, 40 insertions, 12 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 | ||
611 | static 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 | |||
611 | static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | 621 | static 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 | ||
1948 | static 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 | |||
1933 | static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, | 1961 | static 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; |