diff options
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_qp.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 113 |
1 files changed, 99 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 8852ea477c2..760c418d5bc 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -885,6 +885,48 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
885 | return err; | 885 | return err; |
886 | } | 886 | } |
887 | 887 | ||
888 | static void mthca_adjust_qp_caps(struct mthca_dev *dev, | ||
889 | struct mthca_pd *pd, | ||
890 | struct mthca_qp *qp) | ||
891 | { | ||
892 | int max_data_size; | ||
893 | |||
894 | /* | ||
895 | * Calculate the maximum size of WQE s/g segments, excluding | ||
896 | * the next segment and other non-data segments. | ||
897 | */ | ||
898 | max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - | ||
899 | sizeof (struct mthca_next_seg); | ||
900 | |||
901 | switch (qp->transport) { | ||
902 | case MLX: | ||
903 | max_data_size -= 2 * sizeof (struct mthca_data_seg); | ||
904 | break; | ||
905 | |||
906 | case UD: | ||
907 | if (mthca_is_memfree(dev)) | ||
908 | max_data_size -= sizeof (struct mthca_arbel_ud_seg); | ||
909 | else | ||
910 | max_data_size -= sizeof (struct mthca_tavor_ud_seg); | ||
911 | break; | ||
912 | |||
913 | default: | ||
914 | max_data_size -= sizeof (struct mthca_raddr_seg); | ||
915 | break; | ||
916 | } | ||
917 | |||
918 | /* We don't support inline data for kernel QPs (yet). */ | ||
919 | if (!pd->ibpd.uobject) | ||
920 | qp->max_inline_data = 0; | ||
921 | else | ||
922 | qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; | ||
923 | |||
924 | qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg); | ||
925 | qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) - | ||
926 | sizeof (struct mthca_next_seg)) / | ||
927 | sizeof (struct mthca_data_seg); | ||
928 | } | ||
929 | |||
888 | /* | 930 | /* |
889 | * Allocate and register buffer for WQEs. qp->rq.max, sq.max, | 931 | * Allocate and register buffer for WQEs. qp->rq.max, sq.max, |
890 | * rq.max_gs and sq.max_gs must all be assigned. | 932 | * rq.max_gs and sq.max_gs must all be assigned. |
@@ -902,27 +944,53 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev, | |||
902 | size = sizeof (struct mthca_next_seg) + | 944 | size = sizeof (struct mthca_next_seg) + |
903 | qp->rq.max_gs * sizeof (struct mthca_data_seg); | 945 | qp->rq.max_gs * sizeof (struct mthca_data_seg); |
904 | 946 | ||
947 | if (size > dev->limits.max_desc_sz) | ||
948 | return -EINVAL; | ||
949 | |||
905 | for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; | 950 | for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; |
906 | qp->rq.wqe_shift++) | 951 | qp->rq.wqe_shift++) |
907 | ; /* nothing */ | 952 | ; /* nothing */ |
908 | 953 | ||
909 | size = sizeof (struct mthca_next_seg) + | 954 | size = qp->sq.max_gs * sizeof (struct mthca_data_seg); |
910 | qp->sq.max_gs * sizeof (struct mthca_data_seg); | ||
911 | switch (qp->transport) { | 955 | switch (qp->transport) { |
912 | case MLX: | 956 | case MLX: |
913 | size += 2 * sizeof (struct mthca_data_seg); | 957 | size += 2 * sizeof (struct mthca_data_seg); |
914 | break; | 958 | break; |
959 | |||
915 | case UD: | 960 | case UD: |
916 | if (mthca_is_memfree(dev)) | 961 | size += mthca_is_memfree(dev) ? |
917 | size += sizeof (struct mthca_arbel_ud_seg); | 962 | sizeof (struct mthca_arbel_ud_seg) : |
918 | else | 963 | sizeof (struct mthca_tavor_ud_seg); |
919 | size += sizeof (struct mthca_tavor_ud_seg); | ||
920 | break; | 964 | break; |
965 | |||
966 | case UC: | ||
967 | size += sizeof (struct mthca_raddr_seg); | ||
968 | break; | ||
969 | |||
970 | case RC: | ||
971 | size += sizeof (struct mthca_raddr_seg); | ||
972 | /* | ||
973 | * An atomic op will require an atomic segment, a | ||
974 | * remote address segment and one scatter entry. | ||
975 | */ | ||
976 | size = max_t(int, size, | ||
977 | sizeof (struct mthca_atomic_seg) + | ||
978 | sizeof (struct mthca_raddr_seg) + | ||
979 | sizeof (struct mthca_data_seg)); | ||
980 | break; | ||
981 | |||
921 | default: | 982 | default: |
922 | /* bind seg is as big as atomic + raddr segs */ | 983 | break; |
923 | size += sizeof (struct mthca_bind_seg); | ||
924 | } | 984 | } |
925 | 985 | ||
986 | /* Make sure that we have enough space for a bind request */ | ||
987 | size = max_t(int, size, sizeof (struct mthca_bind_seg)); | ||
988 | |||
989 | size += sizeof (struct mthca_next_seg); | ||
990 | |||
991 | if (size > dev->limits.max_desc_sz) | ||
992 | return -EINVAL; | ||
993 | |||
926 | for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; | 994 | for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; |
927 | qp->sq.wqe_shift++) | 995 | qp->sq.wqe_shift++) |
928 | ; /* nothing */ | 996 | ; /* nothing */ |
@@ -1066,6 +1134,8 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, | |||
1066 | return ret; | 1134 | return ret; |
1067 | } | 1135 | } |
1068 | 1136 | ||
1137 | mthca_adjust_qp_caps(dev, pd, qp); | ||
1138 | |||
1069 | /* | 1139 | /* |
1070 | * If this is a userspace QP, we're done now. The doorbells | 1140 | * If this is a userspace QP, we're done now. The doorbells |
1071 | * will be allocated and buffers will be initialized in | 1141 | * will be allocated and buffers will be initialized in |
@@ -1486,8 +1556,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1486 | } | 1556 | } |
1487 | 1557 | ||
1488 | wqe += sizeof (struct mthca_atomic_seg); | 1558 | wqe += sizeof (struct mthca_atomic_seg); |
1489 | size += sizeof (struct mthca_raddr_seg) / 16 + | 1559 | size += (sizeof (struct mthca_raddr_seg) + |
1490 | sizeof (struct mthca_atomic_seg); | 1560 | sizeof (struct mthca_atomic_seg)) / 16; |
1491 | break; | 1561 | break; |
1492 | 1562 | ||
1493 | case IB_WR_RDMA_WRITE: | 1563 | case IB_WR_RDMA_WRITE: |
@@ -1637,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1637 | { | 1707 | { |
1638 | struct mthca_dev *dev = to_mdev(ibqp->device); | 1708 | struct mthca_dev *dev = to_mdev(ibqp->device); |
1639 | struct mthca_qp *qp = to_mqp(ibqp); | 1709 | struct mthca_qp *qp = to_mqp(ibqp); |
1710 | __be32 doorbell[2]; | ||
1640 | unsigned long flags; | 1711 | unsigned long flags; |
1641 | int err = 0; | 1712 | int err = 0; |
1642 | int nreq; | 1713 | int nreq; |
@@ -1654,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1654 | ind = qp->rq.next_ind; | 1725 | ind = qp->rq.next_ind; |
1655 | 1726 | ||
1656 | for (nreq = 0; wr; ++nreq, wr = wr->next) { | 1727 | for (nreq = 0; wr; ++nreq, wr = wr->next) { |
1728 | if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { | ||
1729 | nreq = 0; | ||
1730 | |||
1731 | doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); | ||
1732 | doorbell[1] = cpu_to_be32(qp->qpn << 8); | ||
1733 | |||
1734 | wmb(); | ||
1735 | |||
1736 | mthca_write64(doorbell, | ||
1737 | dev->kar + MTHCA_RECEIVE_DOORBELL, | ||
1738 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | ||
1739 | |||
1740 | qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB; | ||
1741 | size0 = 0; | ||
1742 | } | ||
1743 | |||
1657 | if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { | 1744 | if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { |
1658 | mthca_err(dev, "RQ %06x full (%u head, %u tail," | 1745 | mthca_err(dev, "RQ %06x full (%u head, %u tail," |
1659 | " %d max, %d nreq)\n", qp->qpn, | 1746 | " %d max, %d nreq)\n", qp->qpn, |
@@ -1711,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1711 | 1798 | ||
1712 | out: | 1799 | out: |
1713 | if (likely(nreq)) { | 1800 | if (likely(nreq)) { |
1714 | __be32 doorbell[2]; | ||
1715 | |||
1716 | doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); | 1801 | doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); |
1717 | doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); | 1802 | doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); |
1718 | 1803 | ||
@@ -1806,8 +1891,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1806 | } | 1891 | } |
1807 | 1892 | ||
1808 | wqe += sizeof (struct mthca_atomic_seg); | 1893 | wqe += sizeof (struct mthca_atomic_seg); |
1809 | size += sizeof (struct mthca_raddr_seg) / 16 + | 1894 | size += (sizeof (struct mthca_raddr_seg) + |
1810 | sizeof (struct mthca_atomic_seg); | 1895 | sizeof (struct mthca_atomic_seg)) / 16; |
1811 | break; | 1896 | break; |
1812 | 1897 | ||
1813 | case IB_WR_RDMA_READ: | 1898 | case IB_WR_RDMA_READ: |