diff options
| -rw-r--r-- | drivers/infiniband/core/cm.c | 16 | ||||
| -rw-r--r-- | drivers/infiniband/core/user_mad.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 21 | ||||
| -rw-r--r-- | drivers/infiniband/core/verbs.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 12 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cq.c | 23 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_eq.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mcg.c | 54 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 265 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_srq.c | 2 |
12 files changed, 250 insertions, 163 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 02110e00d145..3a611fe5497e 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
| @@ -308,10 +308,11 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv) | |||
| 308 | { | 308 | { |
| 309 | unsigned long flags; | 309 | unsigned long flags; |
| 310 | int ret; | 310 | int ret; |
| 311 | static int next_id; | ||
| 311 | 312 | ||
| 312 | do { | 313 | do { |
| 313 | spin_lock_irqsave(&cm.lock, flags); | 314 | spin_lock_irqsave(&cm.lock, flags); |
| 314 | ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, | 315 | ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, next_id++, |
| 315 | (__force int *) &cm_id_priv->id.local_id); | 316 | (__force int *) &cm_id_priv->id.local_id); |
| 316 | spin_unlock_irqrestore(&cm.lock, flags); | 317 | spin_unlock_irqrestore(&cm.lock, flags); |
| 317 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); | 318 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); |
| @@ -684,6 +685,13 @@ retest: | |||
| 684 | cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); | 685 | cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); |
| 685 | break; | 686 | break; |
| 686 | case IB_CM_REQ_SENT: | 687 | case IB_CM_REQ_SENT: |
| 688 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); | ||
| 689 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); | ||
| 690 | ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, | ||
| 691 | &cm_id_priv->av.port->cm_dev->ca_guid, | ||
| 692 | sizeof cm_id_priv->av.port->cm_dev->ca_guid, | ||
| 693 | NULL, 0); | ||
| 694 | break; | ||
| 687 | case IB_CM_MRA_REQ_RCVD: | 695 | case IB_CM_MRA_REQ_RCVD: |
| 688 | case IB_CM_REP_SENT: | 696 | case IB_CM_REP_SENT: |
| 689 | case IB_CM_MRA_REP_RCVD: | 697 | case IB_CM_MRA_REP_RCVD: |
| @@ -694,10 +702,8 @@ retest: | |||
| 694 | case IB_CM_REP_RCVD: | 702 | case IB_CM_REP_RCVD: |
| 695 | case IB_CM_MRA_REP_SENT: | 703 | case IB_CM_MRA_REP_SENT: |
| 696 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); | 704 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
| 697 | ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, | 705 | ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, |
| 698 | &cm_id_priv->av.port->cm_dev->ca_guid, | 706 | NULL, 0, NULL, 0); |
| 699 | sizeof cm_id_priv->av.port->cm_dev->ca_guid, | ||
| 700 | NULL, 0); | ||
| 701 | break; | 707 | break; |
| 702 | case IB_CM_ESTABLISHED: | 708 | case IB_CM_ESTABLISHED: |
| 703 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); | 709 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index eb7f52537ccc..c908de8db5a9 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
| @@ -197,8 +197,8 @@ static void send_handler(struct ib_mad_agent *agent, | |||
| 197 | memcpy(timeout->mad.data, packet->mad.data, | 197 | memcpy(timeout->mad.data, packet->mad.data, |
| 198 | sizeof (struct ib_mad_hdr)); | 198 | sizeof (struct ib_mad_hdr)); |
| 199 | 199 | ||
| 200 | if (!queue_packet(file, agent, timeout)) | 200 | if (queue_packet(file, agent, timeout)) |
| 201 | return; | 201 | kfree(timeout); |
| 202 | } | 202 | } |
| 203 | out: | 203 | out: |
| 204 | kfree(packet); | 204 | kfree(packet); |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index a57d021d435a..a02c5a05c984 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -489,6 +489,7 @@ err_idr: | |||
| 489 | 489 | ||
| 490 | err_unreg: | 490 | err_unreg: |
| 491 | ib_dereg_mr(mr); | 491 | ib_dereg_mr(mr); |
| 492 | atomic_dec(&pd->usecnt); | ||
| 492 | 493 | ||
| 493 | err_up: | 494 | err_up: |
| 494 | up(&ib_uverbs_idr_mutex); | 495 | up(&ib_uverbs_idr_mutex); |
| @@ -593,13 +594,18 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, | |||
| 593 | if (cmd.comp_vector >= file->device->num_comp_vectors) | 594 | if (cmd.comp_vector >= file->device->num_comp_vectors) |
| 594 | return -EINVAL; | 595 | return -EINVAL; |
| 595 | 596 | ||
| 596 | if (cmd.comp_channel >= 0) | ||
| 597 | ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); | ||
| 598 | |||
| 599 | uobj = kmalloc(sizeof *uobj, GFP_KERNEL); | 597 | uobj = kmalloc(sizeof *uobj, GFP_KERNEL); |
| 600 | if (!uobj) | 598 | if (!uobj) |
| 601 | return -ENOMEM; | 599 | return -ENOMEM; |
| 602 | 600 | ||
| 601 | if (cmd.comp_channel >= 0) { | ||
| 602 | ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); | ||
| 603 | if (!ev_file) { | ||
| 604 | ret = -EINVAL; | ||
| 605 | goto err; | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 603 | uobj->uobject.user_handle = cmd.user_handle; | 609 | uobj->uobject.user_handle = cmd.user_handle; |
| 604 | uobj->uobject.context = file->ucontext; | 610 | uobj->uobject.context = file->ucontext; |
| 605 | uobj->uverbs_file = file; | 611 | uobj->uverbs_file = file; |
| @@ -663,6 +669,8 @@ err_up: | |||
| 663 | ib_destroy_cq(cq); | 669 | ib_destroy_cq(cq); |
| 664 | 670 | ||
| 665 | err: | 671 | err: |
| 672 | if (ev_file) | ||
| 673 | ib_uverbs_release_ucq(file, ev_file, uobj); | ||
| 666 | kfree(uobj); | 674 | kfree(uobj); |
| 667 | return ret; | 675 | return ret; |
| 668 | } | 676 | } |
| @@ -935,6 +943,11 @@ err_idr: | |||
| 935 | 943 | ||
| 936 | err_destroy: | 944 | err_destroy: |
| 937 | ib_destroy_qp(qp); | 945 | ib_destroy_qp(qp); |
| 946 | atomic_dec(&pd->usecnt); | ||
| 947 | atomic_dec(&attr.send_cq->usecnt); | ||
| 948 | atomic_dec(&attr.recv_cq->usecnt); | ||
| 949 | if (attr.srq) | ||
| 950 | atomic_dec(&attr.srq->usecnt); | ||
| 938 | 951 | ||
| 939 | err_up: | 952 | err_up: |
| 940 | up(&ib_uverbs_idr_mutex); | 953 | up(&ib_uverbs_idr_mutex); |
| @@ -1448,6 +1461,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, | |||
| 1448 | attr.sl = cmd.attr.sl; | 1461 | attr.sl = cmd.attr.sl; |
| 1449 | attr.src_path_bits = cmd.attr.src_path_bits; | 1462 | attr.src_path_bits = cmd.attr.src_path_bits; |
| 1450 | attr.static_rate = cmd.attr.static_rate; | 1463 | attr.static_rate = cmd.attr.static_rate; |
| 1464 | attr.ah_flags = cmd.attr.is_global ? IB_AH_GRH : 0; | ||
| 1451 | attr.port_num = cmd.attr.port_num; | 1465 | attr.port_num = cmd.attr.port_num; |
| 1452 | attr.grh.flow_label = cmd.attr.grh.flow_label; | 1466 | attr.grh.flow_label = cmd.attr.grh.flow_label; |
| 1453 | attr.grh.sgid_index = cmd.attr.grh.sgid_index; | 1467 | attr.grh.sgid_index = cmd.attr.grh.sgid_index; |
| @@ -1729,6 +1743,7 @@ err_idr: | |||
| 1729 | 1743 | ||
| 1730 | err_destroy: | 1744 | err_destroy: |
| 1731 | ib_destroy_srq(srq); | 1745 | ib_destroy_srq(srq); |
| 1746 | atomic_dec(&pd->usecnt); | ||
| 1732 | 1747 | ||
| 1733 | err_up: | 1748 | err_up: |
| 1734 | up(&ib_uverbs_idr_mutex); | 1749 | up(&ib_uverbs_idr_mutex); |
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 4c15e112736c..c857361be449 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
| @@ -107,9 +107,9 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, | |||
| 107 | 107 | ||
| 108 | if (wc->wc_flags & IB_WC_GRH) { | 108 | if (wc->wc_flags & IB_WC_GRH) { |
| 109 | ah_attr.ah_flags = IB_AH_GRH; | 109 | ah_attr.ah_flags = IB_AH_GRH; |
| 110 | ah_attr.grh.dgid = grh->dgid; | 110 | ah_attr.grh.dgid = grh->sgid; |
| 111 | 111 | ||
| 112 | ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, | 112 | ret = ib_find_cached_gid(pd->device, &grh->dgid, &port_num, |
| 113 | &gid_index); | 113 | &gid_index); |
| 114 | if (ret) | 114 | if (ret) |
| 115 | return ERR_PTR(ret); | 115 | return ERR_PTR(ret); |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 9ed34587fc5c..22ac72bc20c3 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
| @@ -937,10 +937,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
| 937 | if (err) | 937 | if (err) |
| 938 | goto out; | 938 | goto out; |
| 939 | 939 | ||
| 940 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | ||
| 941 | dev_lim->max_srq_sz = (1 << field) - 1; | ||
| 942 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); | ||
| 943 | dev_lim->max_qp_sz = (1 << field) - 1; | ||
| 944 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET); | 940 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET); |
| 945 | dev_lim->reserved_qps = 1 << (field & 0xf); | 941 | dev_lim->reserved_qps = 1 << (field & 0xf); |
| 946 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET); | 942 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET); |
| @@ -1056,6 +1052,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
| 1056 | mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); | 1052 | mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); |
| 1057 | 1053 | ||
| 1058 | if (mthca_is_memfree(dev)) { | 1054 | if (mthca_is_memfree(dev)) { |
| 1055 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | ||
| 1056 | dev_lim->max_srq_sz = 1 << field; | ||
| 1057 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); | ||
| 1058 | dev_lim->max_qp_sz = 1 << field; | ||
| 1059 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET); | 1059 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET); |
| 1060 | dev_lim->hca.arbel.resize_srq = field & 1; | 1060 | dev_lim->hca.arbel.resize_srq = field & 1; |
| 1061 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); | 1061 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); |
| @@ -1087,6 +1087,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
| 1087 | mthca_dbg(dev, "Max ICM size %lld MB\n", | 1087 | mthca_dbg(dev, "Max ICM size %lld MB\n", |
| 1088 | (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20); | 1088 | (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20); |
| 1089 | } else { | 1089 | } else { |
| 1090 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | ||
| 1091 | dev_lim->max_srq_sz = (1 << field) - 1; | ||
| 1092 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); | ||
| 1093 | dev_lim->max_qp_sz = (1 << field) - 1; | ||
| 1090 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET); | 1094 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET); |
| 1091 | dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f); | 1095 | dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f); |
| 1092 | dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; | 1096 | dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; |
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 4a8adcef2079..96f1a86bf049 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
| @@ -128,12 +128,12 @@ struct mthca_err_cqe { | |||
| 128 | __be32 my_qpn; | 128 | __be32 my_qpn; |
| 129 | u32 reserved1[3]; | 129 | u32 reserved1[3]; |
| 130 | u8 syndrome; | 130 | u8 syndrome; |
| 131 | u8 reserved2; | 131 | u8 vendor_err; |
| 132 | __be16 db_cnt; | 132 | __be16 db_cnt; |
| 133 | u32 reserved3; | 133 | u32 reserved2; |
| 134 | __be32 wqe; | 134 | __be32 wqe; |
| 135 | u8 opcode; | 135 | u8 opcode; |
| 136 | u8 reserved4[2]; | 136 | u8 reserved3[2]; |
| 137 | u8 owner; | 137 | u8 owner; |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| @@ -253,6 +253,15 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn, | |||
| 253 | wake_up(&cq->wait); | 253 | wake_up(&cq->wait); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | static inline int is_recv_cqe(struct mthca_cqe *cqe) | ||
| 257 | { | ||
| 258 | if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) == | ||
| 259 | MTHCA_ERROR_CQE_OPCODE_MASK) | ||
| 260 | return !(cqe->opcode & 0x01); | ||
| 261 | else | ||
| 262 | return !(cqe->is_send & 0x80); | ||
| 263 | } | ||
| 264 | |||
| 256 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, | 265 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, |
| 257 | struct mthca_srq *srq) | 266 | struct mthca_srq *srq) |
| 258 | { | 267 | { |
| @@ -296,7 +305,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, | |||
| 296 | while ((int) --prod_index - (int) cq->cons_index >= 0) { | 305 | while ((int) --prod_index - (int) cq->cons_index >= 0) { |
| 297 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); | 306 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); |
| 298 | if (cqe->my_qpn == cpu_to_be32(qpn)) { | 307 | if (cqe->my_qpn == cpu_to_be32(qpn)) { |
| 299 | if (srq) | 308 | if (srq && is_recv_cqe(cqe)) |
| 300 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); | 309 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); |
| 301 | ++nfreed; | 310 | ++nfreed; |
| 302 | } else if (nfreed) | 311 | } else if (nfreed) |
| @@ -333,8 +342,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, | |||
| 333 | } | 342 | } |
| 334 | 343 | ||
| 335 | /* | 344 | /* |
| 336 | * For completions in error, only work request ID, status (and | 345 | * For completions in error, only work request ID, status, vendor error |
| 337 | * freed resource count for RD) have to be set. | 346 | * (and freed resource count for RD) have to be set. |
| 338 | */ | 347 | */ |
| 339 | switch (cqe->syndrome) { | 348 | switch (cqe->syndrome) { |
| 340 | case SYNDROME_LOCAL_LENGTH_ERR: | 349 | case SYNDROME_LOCAL_LENGTH_ERR: |
| @@ -396,6 +405,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, | |||
| 396 | break; | 405 | break; |
| 397 | } | 406 | } |
| 398 | 407 | ||
| 408 | entry->vendor_err = cqe->vendor_err; | ||
| 409 | |||
| 399 | /* | 410 | /* |
| 400 | * Mem-free HCAs always generate one CQE per WQE, even in the | 411 | * Mem-free HCAs always generate one CQE per WQE, even in the |
| 401 | * error case, so we don't have to check the doorbell count, etc. | 412 | * error case, so we don't have to check the doorbell count, etc. |
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 34d68e5a72d8..e8a948f087c0 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c | |||
| @@ -484,8 +484,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
| 484 | u8 intr, | 484 | u8 intr, |
| 485 | struct mthca_eq *eq) | 485 | struct mthca_eq *eq) |
| 486 | { | 486 | { |
| 487 | int npages = (nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) / | 487 | int npages; |
| 488 | PAGE_SIZE; | ||
| 489 | u64 *dma_list = NULL; | 488 | u64 *dma_list = NULL; |
| 490 | dma_addr_t t; | 489 | dma_addr_t t; |
| 491 | struct mthca_mailbox *mailbox; | 490 | struct mthca_mailbox *mailbox; |
| @@ -496,6 +495,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
| 496 | 495 | ||
| 497 | eq->dev = dev; | 496 | eq->dev = dev; |
| 498 | eq->nent = roundup_pow_of_two(max(nent, 2)); | 497 | eq->nent = roundup_pow_of_two(max(nent, 2)); |
| 498 | npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE; | ||
| 499 | 499 | ||
| 500 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, | 500 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, |
| 501 | GFP_KERNEL); | 501 | GFP_KERNEL); |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 6f94b25f3acd..8b00d9a0f6f4 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
| @@ -261,6 +261,10 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) | |||
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | err = mthca_dev_lim(mdev, &dev_lim); | 263 | err = mthca_dev_lim(mdev, &dev_lim); |
| 264 | if (err) { | ||
| 265 | mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n"); | ||
| 266 | goto err_disable; | ||
| 267 | } | ||
| 264 | 268 | ||
| 265 | profile = default_profile; | 269 | profile = default_profile; |
| 266 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; | 270 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; |
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index 2fc449da418d..77bc6c746f43 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c | |||
| @@ -111,7 +111,8 @@ static int find_mgm(struct mthca_dev *dev, | |||
| 111 | goto out; | 111 | goto out; |
| 112 | if (status) { | 112 | if (status) { |
| 113 | mthca_err(dev, "READ_MGM returned status %02x\n", status); | 113 | mthca_err(dev, "READ_MGM returned status %02x\n", status); |
| 114 | return -EINVAL; | 114 | err = -EINVAL; |
| 115 | goto out; | ||
| 115 | } | 116 | } |
| 116 | 117 | ||
| 117 | if (!memcmp(mgm->gid, zero_gid, 16)) { | 118 | if (!memcmp(mgm->gid, zero_gid, 16)) { |
| @@ -126,7 +127,7 @@ static int find_mgm(struct mthca_dev *dev, | |||
| 126 | goto out; | 127 | goto out; |
| 127 | 128 | ||
| 128 | *prev = *index; | 129 | *prev = *index; |
| 129 | *index = be32_to_cpu(mgm->next_gid_index) >> 5; | 130 | *index = be32_to_cpu(mgm->next_gid_index) >> 6; |
| 130 | } while (*index); | 131 | } while (*index); |
| 131 | 132 | ||
| 132 | *index = -1; | 133 | *index = -1; |
| @@ -153,8 +154,10 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 153 | return PTR_ERR(mailbox); | 154 | return PTR_ERR(mailbox); |
| 154 | mgm = mailbox->buf; | 155 | mgm = mailbox->buf; |
| 155 | 156 | ||
| 156 | if (down_interruptible(&dev->mcg_table.sem)) | 157 | if (down_interruptible(&dev->mcg_table.sem)) { |
| 157 | return -EINTR; | 158 | err = -EINTR; |
| 159 | goto err_sem; | ||
| 160 | } | ||
| 158 | 161 | ||
| 159 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); | 162 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); |
| 160 | if (err) | 163 | if (err) |
| @@ -181,9 +184,8 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 181 | err = -EINVAL; | 184 | err = -EINVAL; |
| 182 | goto out; | 185 | goto out; |
| 183 | } | 186 | } |
| 184 | 187 | memset(mgm, 0, sizeof *mgm); | |
| 185 | memcpy(mgm->gid, gid->raw, 16); | 188 | memcpy(mgm->gid, gid->raw, 16); |
| 186 | mgm->next_gid_index = 0; | ||
| 187 | } | 189 | } |
| 188 | 190 | ||
| 189 | for (i = 0; i < MTHCA_QP_PER_MGM; ++i) | 191 | for (i = 0; i < MTHCA_QP_PER_MGM; ++i) |
| @@ -209,6 +211,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 209 | if (status) { | 211 | if (status) { |
| 210 | mthca_err(dev, "WRITE_MGM returned status %02x\n", status); | 212 | mthca_err(dev, "WRITE_MGM returned status %02x\n", status); |
| 211 | err = -EINVAL; | 213 | err = -EINVAL; |
| 214 | goto out; | ||
| 212 | } | 215 | } |
| 213 | 216 | ||
| 214 | if (!link) | 217 | if (!link) |
| @@ -223,7 +226,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 223 | goto out; | 226 | goto out; |
| 224 | } | 227 | } |
| 225 | 228 | ||
| 226 | mgm->next_gid_index = cpu_to_be32(index << 5); | 229 | mgm->next_gid_index = cpu_to_be32(index << 6); |
| 227 | 230 | ||
| 228 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); | 231 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); |
| 229 | if (err) | 232 | if (err) |
| @@ -234,7 +237,12 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 234 | } | 237 | } |
| 235 | 238 | ||
| 236 | out: | 239 | out: |
| 240 | if (err && link && index != -1) { | ||
| 241 | BUG_ON(index < dev->limits.num_mgms); | ||
| 242 | mthca_free(&dev->mcg_table.alloc, index); | ||
| 243 | } | ||
| 237 | up(&dev->mcg_table.sem); | 244 | up(&dev->mcg_table.sem); |
| 245 | err_sem: | ||
| 238 | mthca_free_mailbox(dev, mailbox); | 246 | mthca_free_mailbox(dev, mailbox); |
| 239 | return err; | 247 | return err; |
| 240 | } | 248 | } |
| @@ -255,8 +263,10 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 255 | return PTR_ERR(mailbox); | 263 | return PTR_ERR(mailbox); |
| 256 | mgm = mailbox->buf; | 264 | mgm = mailbox->buf; |
| 257 | 265 | ||
| 258 | if (down_interruptible(&dev->mcg_table.sem)) | 266 | if (down_interruptible(&dev->mcg_table.sem)) { |
| 259 | return -EINTR; | 267 | err = -EINTR; |
| 268 | goto err_sem; | ||
| 269 | } | ||
| 260 | 270 | ||
| 261 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); | 271 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); |
| 262 | if (err) | 272 | if (err) |
| @@ -305,13 +315,11 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 305 | if (i != 1) | 315 | if (i != 1) |
| 306 | goto out; | 316 | goto out; |
| 307 | 317 | ||
| 308 | goto out; | ||
| 309 | |||
| 310 | if (prev == -1) { | 318 | if (prev == -1) { |
| 311 | /* Remove entry from MGM */ | 319 | /* Remove entry from MGM */ |
| 312 | if (be32_to_cpu(mgm->next_gid_index) >> 5) { | 320 | int amgm_index_to_free = be32_to_cpu(mgm->next_gid_index) >> 6; |
| 313 | err = mthca_READ_MGM(dev, | 321 | if (amgm_index_to_free) { |
| 314 | be32_to_cpu(mgm->next_gid_index) >> 5, | 322 | err = mthca_READ_MGM(dev, amgm_index_to_free, |
| 315 | mailbox, &status); | 323 | mailbox, &status); |
| 316 | if (err) | 324 | if (err) |
| 317 | goto out; | 325 | goto out; |
| @@ -332,9 +340,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 332 | err = -EINVAL; | 340 | err = -EINVAL; |
| 333 | goto out; | 341 | goto out; |
| 334 | } | 342 | } |
| 343 | if (amgm_index_to_free) { | ||
| 344 | BUG_ON(amgm_index_to_free < dev->limits.num_mgms); | ||
| 345 | mthca_free(&dev->mcg_table.alloc, amgm_index_to_free); | ||
| 346 | } | ||
| 335 | } else { | 347 | } else { |
| 336 | /* Remove entry from AMGM */ | 348 | /* Remove entry from AMGM */ |
| 337 | index = be32_to_cpu(mgm->next_gid_index) >> 5; | 349 | int curr_next_index = be32_to_cpu(mgm->next_gid_index) >> 6; |
| 338 | err = mthca_READ_MGM(dev, prev, mailbox, &status); | 350 | err = mthca_READ_MGM(dev, prev, mailbox, &status); |
| 339 | if (err) | 351 | if (err) |
| 340 | goto out; | 352 | goto out; |
| @@ -344,7 +356,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 344 | goto out; | 356 | goto out; |
| 345 | } | 357 | } |
| 346 | 358 | ||
| 347 | mgm->next_gid_index = cpu_to_be32(index << 5); | 359 | mgm->next_gid_index = cpu_to_be32(curr_next_index << 6); |
| 348 | 360 | ||
| 349 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); | 361 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); |
| 350 | if (err) | 362 | if (err) |
| @@ -354,10 +366,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 354 | err = -EINVAL; | 366 | err = -EINVAL; |
| 355 | goto out; | 367 | goto out; |
| 356 | } | 368 | } |
| 369 | BUG_ON(index < dev->limits.num_mgms); | ||
| 370 | mthca_free(&dev->mcg_table.alloc, index); | ||
| 357 | } | 371 | } |
| 358 | 372 | ||
| 359 | out: | 373 | out: |
| 360 | up(&dev->mcg_table.sem); | 374 | up(&dev->mcg_table.sem); |
| 375 | err_sem: | ||
| 361 | mthca_free_mailbox(dev, mailbox); | 376 | mthca_free_mailbox(dev, mailbox); |
| 362 | return err; | 377 | return err; |
| 363 | } | 378 | } |
| @@ -365,11 +380,12 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
| 365 | int __devinit mthca_init_mcg_table(struct mthca_dev *dev) | 380 | int __devinit mthca_init_mcg_table(struct mthca_dev *dev) |
| 366 | { | 381 | { |
| 367 | int err; | 382 | int err; |
| 383 | int table_size = dev->limits.num_mgms + dev->limits.num_amgms; | ||
| 368 | 384 | ||
| 369 | err = mthca_alloc_init(&dev->mcg_table.alloc, | 385 | err = mthca_alloc_init(&dev->mcg_table.alloc, |
| 370 | dev->limits.num_amgms, | 386 | table_size, |
| 371 | dev->limits.num_amgms - 1, | 387 | table_size - 1, |
| 372 | 0); | 388 | dev->limits.num_mgms); |
| 373 | if (err) | 389 | if (err) |
| 374 | return err; | 390 | return err; |
| 375 | 391 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index d72fe95cba08..9fb985a016e9 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
| @@ -233,7 +233,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj) | |||
| 233 | for (i = 0; i < chunk->npages; ++i) { | 233 | for (i = 0; i < chunk->npages; ++i) { |
| 234 | if (chunk->mem[i].length >= offset) { | 234 | if (chunk->mem[i].length >= offset) { |
| 235 | page = chunk->mem[i].page; | 235 | page = chunk->mem[i].page; |
| 236 | break; | 236 | goto out; |
| 237 | } | 237 | } |
| 238 | offset -= chunk->mem[i].length; | 238 | offset -= chunk->mem[i].length; |
| 239 | } | 239 | } |
| @@ -485,6 +485,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, | |||
| 485 | put_page(db_tab->page[i].mem.page); | 485 | put_page(db_tab->page[i].mem.page); |
| 486 | } | 486 | } |
| 487 | } | 487 | } |
| 488 | |||
| 489 | kfree(db_tab); | ||
| 488 | } | 490 | } |
| 489 | 491 | ||
| 490 | int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, | 492 | int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 7450550db736..564b6d51c394 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
| @@ -383,12 +383,10 @@ static const struct { | |||
| 383 | [UC] = (IB_QP_CUR_STATE | | 383 | [UC] = (IB_QP_CUR_STATE | |
| 384 | IB_QP_ALT_PATH | | 384 | IB_QP_ALT_PATH | |
| 385 | IB_QP_ACCESS_FLAGS | | 385 | IB_QP_ACCESS_FLAGS | |
| 386 | IB_QP_PKEY_INDEX | | ||
| 387 | IB_QP_PATH_MIG_STATE), | 386 | IB_QP_PATH_MIG_STATE), |
| 388 | [RC] = (IB_QP_CUR_STATE | | 387 | [RC] = (IB_QP_CUR_STATE | |
| 389 | IB_QP_ALT_PATH | | 388 | IB_QP_ALT_PATH | |
| 390 | IB_QP_ACCESS_FLAGS | | 389 | IB_QP_ACCESS_FLAGS | |
| 391 | IB_QP_PKEY_INDEX | | ||
| 392 | IB_QP_MIN_RNR_TIMER | | 390 | IB_QP_MIN_RNR_TIMER | |
| 393 | IB_QP_PATH_MIG_STATE), | 391 | IB_QP_PATH_MIG_STATE), |
| 394 | [MLX] = (IB_QP_CUR_STATE | | 392 | [MLX] = (IB_QP_CUR_STATE | |
| @@ -476,9 +474,8 @@ static const struct { | |||
| 476 | .opt_param = { | 474 | .opt_param = { |
| 477 | [UD] = (IB_QP_CUR_STATE | | 475 | [UD] = (IB_QP_CUR_STATE | |
| 478 | IB_QP_QKEY), | 476 | IB_QP_QKEY), |
| 479 | [UC] = IB_QP_CUR_STATE, | 477 | [UC] = (IB_QP_CUR_STATE | |
| 480 | [RC] = (IB_QP_CUR_STATE | | 478 | IB_QP_ACCESS_FLAGS), |
| 481 | IB_QP_MIN_RNR_TIMER), | ||
| 482 | [MLX] = (IB_QP_CUR_STATE | | 479 | [MLX] = (IB_QP_CUR_STATE | |
| 483 | IB_QP_QKEY), | 480 | IB_QP_QKEY), |
| 484 | } | 481 | } |
| @@ -522,6 +519,55 @@ static void init_port(struct mthca_dev *dev, int port) | |||
| 522 | mthca_warn(dev, "INIT_IB returned status %02x.\n", status); | 519 | mthca_warn(dev, "INIT_IB returned status %02x.\n", status); |
| 523 | } | 520 | } |
| 524 | 521 | ||
| 522 | static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr, | ||
| 523 | int attr_mask) | ||
| 524 | { | ||
| 525 | u8 dest_rd_atomic; | ||
| 526 | u32 access_flags; | ||
| 527 | u32 hw_access_flags = 0; | ||
| 528 | |||
| 529 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) | ||
| 530 | dest_rd_atomic = attr->max_dest_rd_atomic; | ||
| 531 | else | ||
| 532 | dest_rd_atomic = qp->resp_depth; | ||
| 533 | |||
| 534 | if (attr_mask & IB_QP_ACCESS_FLAGS) | ||
| 535 | access_flags = attr->qp_access_flags; | ||
| 536 | else | ||
| 537 | access_flags = qp->atomic_rd_en; | ||
| 538 | |||
| 539 | if (!dest_rd_atomic) | ||
| 540 | access_flags &= IB_ACCESS_REMOTE_WRITE; | ||
| 541 | |||
| 542 | if (access_flags & IB_ACCESS_REMOTE_READ) | ||
| 543 | hw_access_flags |= MTHCA_QP_BIT_RRE; | ||
| 544 | if (access_flags & IB_ACCESS_REMOTE_ATOMIC) | ||
| 545 | hw_access_flags |= MTHCA_QP_BIT_RAE; | ||
| 546 | if (access_flags & IB_ACCESS_REMOTE_WRITE) | ||
| 547 | hw_access_flags |= MTHCA_QP_BIT_RWE; | ||
| 548 | |||
| 549 | return cpu_to_be32(hw_access_flags); | ||
| 550 | } | ||
| 551 | |||
| 552 | static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path) | ||
| 553 | { | ||
| 554 | path->g_mylmc = ah->src_path_bits & 0x7f; | ||
| 555 | path->rlid = cpu_to_be16(ah->dlid); | ||
| 556 | path->static_rate = !!ah->static_rate; | ||
| 557 | |||
| 558 | if (ah->ah_flags & IB_AH_GRH) { | ||
| 559 | path->g_mylmc |= 1 << 7; | ||
| 560 | path->mgid_index = ah->grh.sgid_index; | ||
| 561 | path->hop_limit = ah->grh.hop_limit; | ||
| 562 | path->sl_tclass_flowlabel = | ||
| 563 | cpu_to_be32((ah->sl << 28) | | ||
| 564 | (ah->grh.traffic_class << 20) | | ||
| 565 | (ah->grh.flow_label)); | ||
| 566 | memcpy(path->rgid, ah->grh.dgid.raw, 16); | ||
| 567 | } else | ||
| 568 | path->sl_tclass_flowlabel = cpu_to_be32(ah->sl << 28); | ||
| 569 | } | ||
| 570 | |||
| 525 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | 571 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) |
| 526 | { | 572 | { |
| 527 | struct mthca_dev *dev = to_mdev(ibqp->device); | 573 | struct mthca_dev *dev = to_mdev(ibqp->device); |
| @@ -591,6 +637,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 591 | return -EINVAL; | 637 | return -EINVAL; |
| 592 | } | 638 | } |
| 593 | 639 | ||
| 640 | if ((attr_mask & IB_QP_PORT) && | ||
| 641 | (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) { | ||
| 642 | mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num); | ||
| 643 | return -EINVAL; | ||
| 644 | } | ||
| 645 | |||
| 646 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && | ||
| 647 | attr->max_rd_atomic > dev->limits.max_qp_init_rdma) { | ||
| 648 | mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n", | ||
| 649 | attr->max_rd_atomic, dev->limits.max_qp_init_rdma); | ||
| 650 | return -EINVAL; | ||
| 651 | } | ||
| 652 | |||
| 653 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && | ||
| 654 | attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) { | ||
| 655 | mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n", | ||
| 656 | attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift); | ||
| 657 | return -EINVAL; | ||
| 658 | } | ||
| 659 | |||
| 594 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | 660 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
| 595 | if (IS_ERR(mailbox)) | 661 | if (IS_ERR(mailbox)) |
| 596 | return PTR_ERR(mailbox); | 662 | return PTR_ERR(mailbox); |
| @@ -665,28 +731,14 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 665 | } | 731 | } |
| 666 | 732 | ||
| 667 | if (attr_mask & IB_QP_RNR_RETRY) { | 733 | if (attr_mask & IB_QP_RNR_RETRY) { |
| 668 | qp_context->pri_path.rnr_retry = attr->rnr_retry << 5; | 734 | qp_context->alt_path.rnr_retry = qp_context->pri_path.rnr_retry = |
| 669 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY); | 735 | attr->rnr_retry << 5; |
| 736 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY | | ||
| 737 | MTHCA_QP_OPTPAR_ALT_RNR_RETRY); | ||
| 670 | } | 738 | } |
| 671 | 739 | ||
| 672 | if (attr_mask & IB_QP_AV) { | 740 | if (attr_mask & IB_QP_AV) { |
| 673 | qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; | 741 | mthca_path_set(&attr->ah_attr, &qp_context->pri_path); |
| 674 | qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid); | ||
| 675 | qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate; | ||
| 676 | if (attr->ah_attr.ah_flags & IB_AH_GRH) { | ||
| 677 | qp_context->pri_path.g_mylmc |= 1 << 7; | ||
| 678 | qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index; | ||
| 679 | qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit; | ||
| 680 | qp_context->pri_path.sl_tclass_flowlabel = | ||
| 681 | cpu_to_be32((attr->ah_attr.sl << 28) | | ||
| 682 | (attr->ah_attr.grh.traffic_class << 20) | | ||
| 683 | (attr->ah_attr.grh.flow_label)); | ||
| 684 | memcpy(qp_context->pri_path.rgid, | ||
| 685 | attr->ah_attr.grh.dgid.raw, 16); | ||
| 686 | } else { | ||
| 687 | qp_context->pri_path.sl_tclass_flowlabel = | ||
| 688 | cpu_to_be32(attr->ah_attr.sl << 28); | ||
| 689 | } | ||
| 690 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); | 742 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); |
| 691 | } | 743 | } |
| 692 | 744 | ||
| @@ -695,7 +747,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 695 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); | 747 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); |
| 696 | } | 748 | } |
| 697 | 749 | ||
| 698 | /* XXX alt_path */ | 750 | if (attr_mask & IB_QP_ALT_PATH) { |
| 751 | if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) { | ||
| 752 | mthca_dbg(dev, "Alternate port number (%u) is invalid\n", | ||
| 753 | attr->alt_port_num); | ||
| 754 | return -EINVAL; | ||
| 755 | } | ||
| 756 | |||
| 757 | mthca_path_set(&attr->alt_ah_attr, &qp_context->alt_path); | ||
| 758 | qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index | | ||
| 759 | attr->alt_port_num << 24); | ||
| 760 | qp_context->alt_path.ackto = attr->alt_timeout << 3; | ||
| 761 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ALT_ADDR_PATH); | ||
| 762 | } | ||
| 699 | 763 | ||
| 700 | /* leave rdd as 0 */ | 764 | /* leave rdd as 0 */ |
| 701 | qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); | 765 | qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); |
| @@ -703,9 +767,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 703 | qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey); | 767 | qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey); |
| 704 | qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) | | 768 | qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) | |
| 705 | (MTHCA_FLIGHT_LIMIT << 24) | | 769 | (MTHCA_FLIGHT_LIMIT << 24) | |
| 706 | MTHCA_QP_BIT_SRE | | 770 | MTHCA_QP_BIT_SWE); |
| 707 | MTHCA_QP_BIT_SWE | | ||
| 708 | MTHCA_QP_BIT_SAE); | ||
| 709 | if (qp->sq_policy == IB_SIGNAL_ALL_WR) | 771 | if (qp->sq_policy == IB_SIGNAL_ALL_WR) |
| 710 | qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC); | 772 | qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC); |
| 711 | if (attr_mask & IB_QP_RETRY_CNT) { | 773 | if (attr_mask & IB_QP_RETRY_CNT) { |
| @@ -714,9 +776,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 714 | } | 776 | } |
| 715 | 777 | ||
| 716 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { | 778 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { |
| 717 | qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ? | 779 | if (attr->max_rd_atomic) { |
| 718 | ffs(attr->max_rd_atomic) - 1 : 0, | 780 | qp_context->params1 |= |
| 719 | 7) << 21); | 781 | cpu_to_be32(MTHCA_QP_BIT_SRE | |
| 782 | MTHCA_QP_BIT_SAE); | ||
| 783 | qp_context->params1 |= | ||
| 784 | cpu_to_be32(fls(attr->max_rd_atomic - 1) << 21); | ||
| 785 | } | ||
| 720 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); | 786 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); |
| 721 | } | 787 | } |
| 722 | 788 | ||
| @@ -729,71 +795,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 729 | qp_context->snd_db_index = cpu_to_be32(qp->sq.db_index); | 795 | qp_context->snd_db_index = cpu_to_be32(qp->sq.db_index); |
| 730 | } | 796 | } |
| 731 | 797 | ||
| 732 | if (attr_mask & IB_QP_ACCESS_FLAGS) { | ||
| 733 | qp_context->params2 |= | ||
| 734 | cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ? | ||
| 735 | MTHCA_QP_BIT_RWE : 0); | ||
| 736 | |||
| 737 | /* | ||
| 738 | * Only enable RDMA reads and atomics if we have | ||
| 739 | * responder resources set to a non-zero value. | ||
| 740 | */ | ||
| 741 | if (qp->resp_depth) { | ||
| 742 | qp_context->params2 |= | ||
| 743 | cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ? | ||
| 744 | MTHCA_QP_BIT_RRE : 0); | ||
| 745 | qp_context->params2 |= | ||
| 746 | cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ? | ||
| 747 | MTHCA_QP_BIT_RAE : 0); | ||
| 748 | } | ||
| 749 | |||
| 750 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | | ||
| 751 | MTHCA_QP_OPTPAR_RRE | | ||
| 752 | MTHCA_QP_OPTPAR_RAE); | ||
| 753 | |||
| 754 | qp->atomic_rd_en = attr->qp_access_flags; | ||
| 755 | } | ||
| 756 | |||
| 757 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { | 798 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { |
| 758 | u8 rra_max; | 799 | if (attr->max_dest_rd_atomic) |
| 759 | |||
| 760 | if (qp->resp_depth && !attr->max_dest_rd_atomic) { | ||
| 761 | /* | ||
| 762 | * Lowering our responder resources to zero. | ||
| 763 | * Turn off reads RDMA and atomics as responder. | ||
| 764 | * (RRE/RAE in params2 already zero) | ||
| 765 | */ | ||
| 766 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE | | ||
| 767 | MTHCA_QP_OPTPAR_RAE); | ||
| 768 | } | ||
| 769 | |||
| 770 | if (!qp->resp_depth && attr->max_dest_rd_atomic) { | ||
| 771 | /* | ||
| 772 | * Increasing our responder resources from | ||
| 773 | * zero. Turn on RDMA reads and atomics as | ||
| 774 | * appropriate. | ||
| 775 | */ | ||
| 776 | qp_context->params2 |= | 800 | qp_context->params2 |= |
| 777 | cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ? | 801 | cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) << 21); |
| 778 | MTHCA_QP_BIT_RRE : 0); | ||
| 779 | qp_context->params2 |= | ||
| 780 | cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ? | ||
| 781 | MTHCA_QP_BIT_RAE : 0); | ||
| 782 | |||
| 783 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE | | ||
| 784 | MTHCA_QP_OPTPAR_RAE); | ||
| 785 | } | ||
| 786 | 802 | ||
| 787 | for (rra_max = 0; | ||
| 788 | 1 << rra_max < attr->max_dest_rd_atomic && | ||
| 789 | rra_max < dev->qp_table.rdb_shift; | ||
| 790 | ++rra_max) | ||
| 791 | ; /* nothing */ | ||
| 792 | |||
| 793 | qp_context->params2 |= cpu_to_be32(rra_max << 21); | ||
| 794 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); | 803 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); |
| 804 | } | ||
| 795 | 805 | ||
| 796 | qp->resp_depth = attr->max_dest_rd_atomic; | 806 | if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) { |
| 807 | qp_context->params2 |= get_hw_access_flags(qp, attr, attr_mask); | ||
| 808 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | | ||
| 809 | MTHCA_QP_OPTPAR_RRE | | ||
| 810 | MTHCA_QP_OPTPAR_RAE); | ||
| 797 | } | 811 | } |
| 798 | 812 | ||
| 799 | qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); | 813 | qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); |
| @@ -835,8 +849,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 835 | err = -EINVAL; | 849 | err = -EINVAL; |
| 836 | } | 850 | } |
| 837 | 851 | ||
| 838 | if (!err) | 852 | if (!err) { |
| 839 | qp->state = new_state; | 853 | qp->state = new_state; |
| 854 | if (attr_mask & IB_QP_ACCESS_FLAGS) | ||
| 855 | qp->atomic_rd_en = attr->qp_access_flags; | ||
| 856 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) | ||
| 857 | qp->resp_depth = attr->max_dest_rd_atomic; | ||
| 858 | } | ||
| 840 | 859 | ||
| 841 | mthca_free_mailbox(dev, mailbox); | 860 | mthca_free_mailbox(dev, mailbox); |
| 842 | 861 | ||
| @@ -885,18 +904,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
| 885 | return err; | 904 | return err; |
| 886 | } | 905 | } |
| 887 | 906 | ||
| 888 | static void mthca_adjust_qp_caps(struct mthca_dev *dev, | 907 | static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int desc_sz) |
| 889 | struct mthca_pd *pd, | ||
| 890 | struct mthca_qp *qp) | ||
| 891 | { | 908 | { |
| 892 | int max_data_size; | ||
| 893 | |||
| 894 | /* | 909 | /* |
| 895 | * Calculate the maximum size of WQE s/g segments, excluding | 910 | * Calculate the maximum size of WQE s/g segments, excluding |
| 896 | * the next segment and other non-data segments. | 911 | * the next segment and other non-data segments. |
| 897 | */ | 912 | */ |
| 898 | max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - | 913 | int max_data_size = desc_sz - sizeof (struct mthca_next_seg); |
| 899 | sizeof (struct mthca_next_seg); | ||
| 900 | 914 | ||
| 901 | switch (qp->transport) { | 915 | switch (qp->transport) { |
| 902 | case MLX: | 916 | case MLX: |
| @@ -915,11 +929,24 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev, | |||
| 915 | break; | 929 | break; |
| 916 | } | 930 | } |
| 917 | 931 | ||
| 932 | return max_data_size; | ||
| 933 | } | ||
| 934 | |||
| 935 | static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size) | ||
| 936 | { | ||
| 918 | /* We don't support inline data for kernel QPs (yet). */ | 937 | /* We don't support inline data for kernel QPs (yet). */ |
| 919 | if (!pd->ibpd.uobject) | 938 | return pd->ibpd.uobject ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0; |
| 920 | qp->max_inline_data = 0; | 939 | } |
| 921 | else | 940 | |
| 922 | qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; | 941 | static void mthca_adjust_qp_caps(struct mthca_dev *dev, |
| 942 | struct mthca_pd *pd, | ||
| 943 | struct mthca_qp *qp) | ||
| 944 | { | ||
| 945 | int max_data_size = mthca_max_data_size(dev, qp, | ||
| 946 | min(dev->limits.max_desc_sz, | ||
| 947 | 1 << qp->sq.wqe_shift)); | ||
| 948 | |||
| 949 | qp->max_inline_data = mthca_max_inline_data(pd, max_data_size); | ||
| 923 | 950 | ||
| 924 | qp->sq.max_gs = min_t(int, dev->limits.max_sg, | 951 | qp->sq.max_gs = min_t(int, dev->limits.max_sg, |
| 925 | max_data_size / sizeof (struct mthca_data_seg)); | 952 | max_data_size / sizeof (struct mthca_data_seg)); |
| @@ -1186,13 +1213,23 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, | |||
| 1186 | } | 1213 | } |
| 1187 | 1214 | ||
| 1188 | static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, | 1215 | static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, |
| 1189 | struct mthca_qp *qp) | 1216 | struct mthca_pd *pd, struct mthca_qp *qp) |
| 1190 | { | 1217 | { |
| 1218 | int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz); | ||
| 1219 | |||
| 1191 | /* Sanity check QP size before proceeding */ | 1220 | /* Sanity check QP size before proceeding */ |
| 1192 | if (cap->max_send_wr > dev->limits.max_wqes || | 1221 | if (cap->max_send_wr > dev->limits.max_wqes || |
| 1193 | cap->max_recv_wr > dev->limits.max_wqes || | 1222 | cap->max_recv_wr > dev->limits.max_wqes || |
| 1194 | cap->max_send_sge > dev->limits.max_sg || | 1223 | cap->max_send_sge > dev->limits.max_sg || |
| 1195 | cap->max_recv_sge > dev->limits.max_sg) | 1224 | cap->max_recv_sge > dev->limits.max_sg || |
| 1225 | cap->max_inline_data > mthca_max_inline_data(pd, max_data_size)) | ||
| 1226 | return -EINVAL; | ||
| 1227 | |||
| 1228 | /* | ||
| 1229 | * For MLX transport we need 2 extra S/G entries: | ||
| 1230 | * one for the header and one for the checksum at the end | ||
| 1231 | */ | ||
| 1232 | if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg) | ||
| 1196 | return -EINVAL; | 1233 | return -EINVAL; |
| 1197 | 1234 | ||
| 1198 | if (mthca_is_memfree(dev)) { | 1235 | if (mthca_is_memfree(dev)) { |
| @@ -1211,14 +1248,6 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, | |||
| 1211 | MTHCA_INLINE_CHUNK_SIZE) / | 1248 | MTHCA_INLINE_CHUNK_SIZE) / |
| 1212 | sizeof (struct mthca_data_seg)); | 1249 | sizeof (struct mthca_data_seg)); |
| 1213 | 1250 | ||
| 1214 | /* | ||
| 1215 | * For MLX transport we need 2 extra S/G entries: | ||
| 1216 | * one for the header and one for the checksum at the end | ||
| 1217 | */ | ||
| 1218 | if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) || | ||
| 1219 | qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg) | ||
| 1220 | return -EINVAL; | ||
| 1221 | |||
| 1222 | return 0; | 1251 | return 0; |
| 1223 | } | 1252 | } |
| 1224 | 1253 | ||
| @@ -1233,7 +1262,7 @@ int mthca_alloc_qp(struct mthca_dev *dev, | |||
| 1233 | { | 1262 | { |
| 1234 | int err; | 1263 | int err; |
| 1235 | 1264 | ||
| 1236 | err = mthca_set_qp_size(dev, cap, qp); | 1265 | err = mthca_set_qp_size(dev, cap, pd, qp); |
| 1237 | if (err) | 1266 | if (err) |
| 1238 | return err; | 1267 | return err; |
| 1239 | 1268 | ||
| @@ -1276,7 +1305,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev, | |||
| 1276 | u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; | 1305 | u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; |
| 1277 | int err; | 1306 | int err; |
| 1278 | 1307 | ||
| 1279 | err = mthca_set_qp_size(dev, cap, &sqp->qp); | 1308 | err = mthca_set_qp_size(dev, cap, pd, &sqp->qp); |
| 1280 | if (err) | 1309 | if (err) |
| 1281 | return err; | 1310 | return err; |
| 1282 | 1311 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index f7d234295efe..e7e153d9c4c6 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
| @@ -201,7 +201,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | |||
| 201 | if (mthca_is_memfree(dev)) | 201 | if (mthca_is_memfree(dev)) |
| 202 | srq->max = roundup_pow_of_two(srq->max + 1); | 202 | srq->max = roundup_pow_of_two(srq->max + 1); |
| 203 | 203 | ||
| 204 | ds = min(64UL, | 204 | ds = max(64UL, |
| 205 | roundup_pow_of_two(sizeof (struct mthca_next_seg) + | 205 | roundup_pow_of_two(sizeof (struct mthca_next_seg) + |
| 206 | srq->max_gs * sizeof (struct mthca_data_seg))); | 206 | srq->max_gs * sizeof (struct mthca_data_seg))); |
| 207 | srq->wqe_shift = long_log2(ds); | 207 | srq->wqe_shift = long_log2(ds); |
