diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4')
-rw-r--r-- | drivers/infiniband/hw/mlx4/cq.c | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 73 |
5 files changed, 43 insertions, 55 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 4521319b1406..299f20832ab6 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
@@ -663,18 +663,18 @@ repoll: | |||
663 | 663 | ||
664 | switch (cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) { | 664 | switch (cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) { |
665 | case MLX4_RECV_OPCODE_RDMA_WRITE_IMM: | 665 | case MLX4_RECV_OPCODE_RDMA_WRITE_IMM: |
666 | wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; | 666 | wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; |
667 | wc->wc_flags = IB_WC_WITH_IMM; | 667 | wc->wc_flags = IB_WC_WITH_IMM; |
668 | wc->imm_data = cqe->immed_rss_invalid; | 668 | wc->ex.imm_data = cqe->immed_rss_invalid; |
669 | break; | 669 | break; |
670 | case MLX4_RECV_OPCODE_SEND: | 670 | case MLX4_RECV_OPCODE_SEND: |
671 | wc->opcode = IB_WC_RECV; | 671 | wc->opcode = IB_WC_RECV; |
672 | wc->wc_flags = 0; | 672 | wc->wc_flags = 0; |
673 | break; | 673 | break; |
674 | case MLX4_RECV_OPCODE_SEND_IMM: | 674 | case MLX4_RECV_OPCODE_SEND_IMM: |
675 | wc->opcode = IB_WC_RECV; | 675 | wc->opcode = IB_WC_RECV; |
676 | wc->wc_flags = IB_WC_WITH_IMM; | 676 | wc->wc_flags = IB_WC_WITH_IMM; |
677 | wc->imm_data = cqe->immed_rss_invalid; | 677 | wc->ex.imm_data = cqe->immed_rss_invalid; |
678 | break; | 678 | break; |
679 | } | 679 | } |
680 | 680 | ||
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 4c1e72fc8f57..cdca3a511e1c 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -255,7 +255,8 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
255 | return IB_MAD_RESULT_SUCCESS; | 255 | return IB_MAD_RESULT_SUCCESS; |
256 | } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || | 256 | } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || |
257 | in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 || | 257 | in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 || |
258 | in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS2) { | 258 | in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS2 || |
259 | in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CONG_MGMT) { | ||
259 | if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET && | 260 | if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET && |
260 | in_mad->mad_hdr.method != IB_MGMT_METHOD_SET) | 261 | in_mad->mad_hdr.method != IB_MGMT_METHOD_SET) |
261 | return IB_MAD_RESULT_SUCCESS; | 262 | return IB_MAD_RESULT_SUCCESS; |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 4d61e32866c6..bcf50648fa18 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -90,7 +90,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
90 | props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | | 90 | props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | |
91 | IB_DEVICE_PORT_ACTIVE_EVENT | | 91 | IB_DEVICE_PORT_ACTIVE_EVENT | |
92 | IB_DEVICE_SYS_IMAGE_GUID | | 92 | IB_DEVICE_SYS_IMAGE_GUID | |
93 | IB_DEVICE_RC_RNR_NAK_GEN; | 93 | IB_DEVICE_RC_RNR_NAK_GEN | |
94 | IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; | ||
94 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR) | 95 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR) |
95 | props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; | 96 | props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; |
96 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR) | 97 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR) |
@@ -437,7 +438,9 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd) | |||
437 | static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | 438 | static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) |
438 | { | 439 | { |
439 | return mlx4_multicast_attach(to_mdev(ibqp->device)->dev, | 440 | return mlx4_multicast_attach(to_mdev(ibqp->device)->dev, |
440 | &to_mqp(ibqp)->mqp, gid->raw); | 441 | &to_mqp(ibqp)->mqp, gid->raw, |
442 | !!(to_mqp(ibqp)->flags & | ||
443 | MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)); | ||
441 | } | 444 | } |
442 | 445 | ||
443 | static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | 446 | static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 5cf994794d25..c4cf5b69eefa 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -101,7 +101,8 @@ struct mlx4_ib_wq { | |||
101 | }; | 101 | }; |
102 | 102 | ||
103 | enum mlx4_ib_qp_flags { | 103 | enum mlx4_ib_qp_flags { |
104 | MLX4_IB_QP_LSO = 1 << 0 | 104 | MLX4_IB_QP_LSO = 1 << 0, |
105 | MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = 1 << 1, | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | struct mlx4_ib_qp { | 108 | struct mlx4_ib_qp { |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a80df22deae8..89eb6cbe592e 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -129,9 +129,10 @@ static void stamp_send_wqe(struct mlx4_ib_qp *qp, int n, int size) | |||
129 | int ind; | 129 | int ind; |
130 | void *buf; | 130 | void *buf; |
131 | __be32 stamp; | 131 | __be32 stamp; |
132 | struct mlx4_wqe_ctrl_seg *ctrl; | ||
132 | 133 | ||
133 | s = roundup(size, 1U << qp->sq.wqe_shift); | ||
134 | if (qp->sq_max_wqes_per_wr > 1) { | 134 | if (qp->sq_max_wqes_per_wr > 1) { |
135 | s = roundup(size, 1U << qp->sq.wqe_shift); | ||
135 | for (i = 0; i < s; i += 64) { | 136 | for (i = 0; i < s; i += 64) { |
136 | ind = (i >> qp->sq.wqe_shift) + n; | 137 | ind = (i >> qp->sq.wqe_shift) + n; |
137 | stamp = ind & qp->sq.wqe_cnt ? cpu_to_be32(0x7fffffff) : | 138 | stamp = ind & qp->sq.wqe_cnt ? cpu_to_be32(0x7fffffff) : |
@@ -141,7 +142,8 @@ static void stamp_send_wqe(struct mlx4_ib_qp *qp, int n, int size) | |||
141 | *wqe = stamp; | 142 | *wqe = stamp; |
142 | } | 143 | } |
143 | } else { | 144 | } else { |
144 | buf = get_send_wqe(qp, n & (qp->sq.wqe_cnt - 1)); | 145 | ctrl = buf = get_send_wqe(qp, n & (qp->sq.wqe_cnt - 1)); |
146 | s = (ctrl->fence_size & 0x3f) << 4; | ||
145 | for (i = 64; i < s; i += 64) { | 147 | for (i = 64; i < s; i += 64) { |
146 | wqe = buf + i; | 148 | wqe = buf + i; |
147 | *wqe = cpu_to_be32(0xffffffff); | 149 | *wqe = cpu_to_be32(0xffffffff); |
@@ -452,19 +454,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
452 | spin_lock_init(&qp->rq.lock); | 454 | spin_lock_init(&qp->rq.lock); |
453 | 455 | ||
454 | qp->state = IB_QPS_RESET; | 456 | qp->state = IB_QPS_RESET; |
455 | qp->atomic_rd_en = 0; | ||
456 | qp->resp_depth = 0; | ||
457 | |||
458 | qp->rq.head = 0; | ||
459 | qp->rq.tail = 0; | ||
460 | qp->sq.head = 0; | ||
461 | qp->sq.tail = 0; | ||
462 | qp->sq_next_wqe = 0; | ||
463 | |||
464 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) | 457 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) |
465 | qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); | 458 | qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); |
466 | else | ||
467 | qp->sq_signal_bits = 0; | ||
468 | 459 | ||
469 | err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp); | 460 | err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp); |
470 | if (err) | 461 | if (err) |
@@ -509,6 +500,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
509 | } else { | 500 | } else { |
510 | qp->sq_no_prefetch = 0; | 501 | qp->sq_no_prefetch = 0; |
511 | 502 | ||
503 | if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) | ||
504 | qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK; | ||
505 | |||
512 | if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) | 506 | if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) |
513 | qp->flags |= MLX4_IB_QP_LSO; | 507 | qp->flags |= MLX4_IB_QP_LSO; |
514 | 508 | ||
@@ -682,10 +676,15 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
682 | struct mlx4_ib_qp *qp; | 676 | struct mlx4_ib_qp *qp; |
683 | int err; | 677 | int err; |
684 | 678 | ||
685 | /* We only support LSO, and only for kernel UD QPs. */ | 679 | /* |
686 | if (init_attr->create_flags & ~IB_QP_CREATE_IPOIB_UD_LSO) | 680 | * We only support LSO and multicast loopback blocking, and |
681 | * only for kernel UD QPs. | ||
682 | */ | ||
683 | if (init_attr->create_flags & ~(IB_QP_CREATE_IPOIB_UD_LSO | | ||
684 | IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)) | ||
687 | return ERR_PTR(-EINVAL); | 685 | return ERR_PTR(-EINVAL); |
688 | if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO && | 686 | |
687 | if (init_attr->create_flags && | ||
689 | (pd->uobject || init_attr->qp_type != IB_QPT_UD)) | 688 | (pd->uobject || init_attr->qp_type != IB_QPT_UD)) |
690 | return ERR_PTR(-EINVAL); | 689 | return ERR_PTR(-EINVAL); |
691 | 690 | ||
@@ -694,7 +693,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
694 | case IB_QPT_UC: | 693 | case IB_QPT_UC: |
695 | case IB_QPT_UD: | 694 | case IB_QPT_UD: |
696 | { | 695 | { |
697 | qp = kmalloc(sizeof *qp, GFP_KERNEL); | 696 | qp = kzalloc(sizeof *qp, GFP_KERNEL); |
698 | if (!qp) | 697 | if (!qp) |
699 | return ERR_PTR(-ENOMEM); | 698 | return ERR_PTR(-ENOMEM); |
700 | 699 | ||
@@ -715,7 +714,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
715 | if (pd->uobject) | 714 | if (pd->uobject) |
716 | return ERR_PTR(-EINVAL); | 715 | return ERR_PTR(-EINVAL); |
717 | 716 | ||
718 | sqp = kmalloc(sizeof *sqp, GFP_KERNEL); | 717 | sqp = kzalloc(sizeof *sqp, GFP_KERNEL); |
719 | if (!sqp) | 718 | if (!sqp) |
720 | return ERR_PTR(-ENOMEM); | 719 | return ERR_PTR(-ENOMEM); |
721 | 720 | ||
@@ -906,7 +905,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
906 | attr->path_mtu); | 905 | attr->path_mtu); |
907 | goto out; | 906 | goto out; |
908 | } | 907 | } |
909 | context->mtu_msgmax = (attr->path_mtu << 5) | 31; | 908 | context->mtu_msgmax = (attr->path_mtu << 5) | |
909 | ilog2(dev->dev->caps.max_msg_sz); | ||
910 | } | 910 | } |
911 | 911 | ||
912 | if (qp->rq.wqe_cnt) | 912 | if (qp->rq.wqe_cnt) |
@@ -1063,6 +1063,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
1063 | for (i = 0; i < qp->sq.wqe_cnt; ++i) { | 1063 | for (i = 0; i < qp->sq.wqe_cnt; ++i) { |
1064 | ctrl = get_send_wqe(qp, i); | 1064 | ctrl = get_send_wqe(qp, i); |
1065 | ctrl->owner_opcode = cpu_to_be32(1 << 31); | 1065 | ctrl->owner_opcode = cpu_to_be32(1 << 31); |
1066 | if (qp->sq_max_wqes_per_wr == 1) | ||
1067 | ctrl->fence_size = 1 << (qp->sq.wqe_shift - 4); | ||
1066 | 1068 | ||
1067 | stamp_send_wqe(qp, i, 1 << qp->sq.wqe_shift); | 1069 | stamp_send_wqe(qp, i, 1 << qp->sq.wqe_shift); |
1068 | } | 1070 | } |
@@ -1127,23 +1129,6 @@ out: | |||
1127 | return err; | 1129 | return err; |
1128 | } | 1130 | } |
1129 | 1131 | ||
1130 | static const struct ib_qp_attr mlx4_ib_qp_attr = { .port_num = 1 }; | ||
1131 | static const int mlx4_ib_qp_attr_mask_table[IB_QPT_UD + 1] = { | ||
1132 | [IB_QPT_UD] = (IB_QP_PKEY_INDEX | | ||
1133 | IB_QP_PORT | | ||
1134 | IB_QP_QKEY), | ||
1135 | [IB_QPT_UC] = (IB_QP_PKEY_INDEX | | ||
1136 | IB_QP_PORT | | ||
1137 | IB_QP_ACCESS_FLAGS), | ||
1138 | [IB_QPT_RC] = (IB_QP_PKEY_INDEX | | ||
1139 | IB_QP_PORT | | ||
1140 | IB_QP_ACCESS_FLAGS), | ||
1141 | [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | | ||
1142 | IB_QP_QKEY), | ||
1143 | [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | | ||
1144 | IB_QP_QKEY), | ||
1145 | }; | ||
1146 | |||
1147 | int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | 1132 | int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, |
1148 | int attr_mask, struct ib_udata *udata) | 1133 | int attr_mask, struct ib_udata *udata) |
1149 | { | 1134 | { |
@@ -1186,15 +1171,6 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
1186 | goto out; | 1171 | goto out; |
1187 | } | 1172 | } |
1188 | 1173 | ||
1189 | if (cur_state == IB_QPS_RESET && new_state == IB_QPS_ERR) { | ||
1190 | err = __mlx4_ib_modify_qp(ibqp, &mlx4_ib_qp_attr, | ||
1191 | mlx4_ib_qp_attr_mask_table[ibqp->qp_type], | ||
1192 | IB_QPS_RESET, IB_QPS_INIT); | ||
1193 | if (err) | ||
1194 | goto out; | ||
1195 | cur_state = IB_QPS_INIT; | ||
1196 | } | ||
1197 | |||
1198 | err = __mlx4_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state); | 1174 | err = __mlx4_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state); |
1199 | 1175 | ||
1200 | out: | 1176 | out: |
@@ -1865,6 +1841,13 @@ done: | |||
1865 | 1841 | ||
1866 | qp_init_attr->cap = qp_attr->cap; | 1842 | qp_init_attr->cap = qp_attr->cap; |
1867 | 1843 | ||
1844 | qp_init_attr->create_flags = 0; | ||
1845 | if (qp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK) | ||
1846 | qp_init_attr->create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK; | ||
1847 | |||
1848 | if (qp->flags & MLX4_IB_QP_LSO) | ||
1849 | qp_init_attr->create_flags |= IB_QP_CREATE_IPOIB_UD_LSO; | ||
1850 | |||
1868 | out: | 1851 | out: |
1869 | mutex_unlock(&qp->mutex); | 1852 | mutex_unlock(&qp->mutex); |
1870 | return err; | 1853 | return err; |