aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mlx4')
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c12
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c3
-rw-r--r--drivers/infiniband/hw/mlx4/main.c7
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h3
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c73
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)
437static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 438static 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
443static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 446static 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
103enum mlx4_ib_qp_flags { 103enum 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
107struct mlx4_ib_qp { 108struct 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
1130static const struct ib_qp_attr mlx4_ib_qp_attr = { .port_num = 1 };
1131static 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
1147int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, 1132int 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
1200out: 1176out:
@@ -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
1868out: 1851out:
1869 mutex_unlock(&qp->mutex); 1852 mutex_unlock(&qp->mutex);
1870 return err; 1853 return err;