diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 120 | ||||
| -rw-r--r-- | drivers/net/mlx4/qp.c | 3 |
4 files changed, 93 insertions, 33 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 42a538e5df36..aec76ad77872 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -128,6 +128,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
| 128 | (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_REMOTE_INV) && | 128 | (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_REMOTE_INV) && |
| 129 | (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_FAST_REG_WR)) | 129 | (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_FAST_REG_WR)) |
| 130 | props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; | 130 | props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; |
| 131 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) | ||
| 132 | props->device_cap_flags |= IB_DEVICE_XRC; | ||
| 131 | 133 | ||
| 132 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & | 134 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & |
| 133 | 0xffffff; | 135 | 0xffffff; |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index ce150b0e2cc8..ed80345c99ae 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
| @@ -145,6 +145,7 @@ struct mlx4_ib_qp { | |||
| 145 | struct mlx4_mtt mtt; | 145 | struct mlx4_mtt mtt; |
| 146 | int buf_size; | 146 | int buf_size; |
| 147 | struct mutex mutex; | 147 | struct mutex mutex; |
| 148 | u16 xrcdn; | ||
| 148 | u32 flags; | 149 | u32 flags; |
| 149 | u8 port; | 150 | u8 port; |
| 150 | u8 alt_port; | 151 | u8 alt_port; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 3a91d9d8dc51..1bbe64103674 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -302,15 +302,14 @@ static int send_wqe_overhead(enum ib_qp_type type, u32 flags) | |||
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | 304 | static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, |
| 305 | int is_user, int has_srq, struct mlx4_ib_qp *qp) | 305 | int is_user, int has_rq, struct mlx4_ib_qp *qp) |
| 306 | { | 306 | { |
| 307 | /* Sanity check RQ size before proceeding */ | 307 | /* Sanity check RQ size before proceeding */ |
| 308 | if (cap->max_recv_wr > dev->dev->caps.max_wqes || | 308 | if (cap->max_recv_wr > dev->dev->caps.max_wqes || |
| 309 | cap->max_recv_sge > dev->dev->caps.max_rq_sg) | 309 | cap->max_recv_sge > dev->dev->caps.max_rq_sg) |
| 310 | return -EINVAL; | 310 | return -EINVAL; |
| 311 | 311 | ||
| 312 | if (has_srq) { | 312 | if (!has_rq) { |
| 313 | /* QPs attached to an SRQ should have no RQ */ | ||
| 314 | if (cap->max_recv_wr) | 313 | if (cap->max_recv_wr) |
| 315 | return -EINVAL; | 314 | return -EINVAL; |
| 316 | 315 | ||
| @@ -463,6 +462,14 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev, | |||
| 463 | return 0; | 462 | return 0; |
| 464 | } | 463 | } |
| 465 | 464 | ||
| 465 | static int qp_has_rq(struct ib_qp_init_attr *attr) | ||
| 466 | { | ||
| 467 | if (attr->qp_type == IB_QPT_XRC_INI || attr->qp_type == IB_QPT_XRC_TGT) | ||
| 468 | return 0; | ||
| 469 | |||
| 470 | return !attr->srq; | ||
| 471 | } | ||
| 472 | |||
| 466 | static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | 473 | static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, |
| 467 | struct ib_qp_init_attr *init_attr, | 474 | struct ib_qp_init_attr *init_attr, |
| 468 | struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp) | 475 | struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp) |
| @@ -479,7 +486,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 479 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) | 486 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) |
| 480 | qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); | 487 | qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); |
| 481 | 488 | ||
| 482 | err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp); | 489 | err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, qp_has_rq(init_attr), qp); |
| 483 | if (err) | 490 | if (err) |
| 484 | goto err; | 491 | goto err; |
| 485 | 492 | ||
| @@ -513,7 +520,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 513 | if (err) | 520 | if (err) |
| 514 | goto err_mtt; | 521 | goto err_mtt; |
| 515 | 522 | ||
| 516 | if (!init_attr->srq) { | 523 | if (qp_has_rq(init_attr)) { |
| 517 | err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context), | 524 | err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context), |
| 518 | ucmd.db_addr, &qp->db); | 525 | ucmd.db_addr, &qp->db); |
| 519 | if (err) | 526 | if (err) |
| @@ -532,7 +539,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 532 | if (err) | 539 | if (err) |
| 533 | goto err; | 540 | goto err; |
| 534 | 541 | ||
| 535 | if (!init_attr->srq) { | 542 | if (qp_has_rq(init_attr)) { |
| 536 | err = mlx4_db_alloc(dev->dev, &qp->db, 0); | 543 | err = mlx4_db_alloc(dev->dev, &qp->db, 0); |
| 537 | if (err) | 544 | if (err) |
| 538 | goto err; | 545 | goto err; |
| @@ -575,6 +582,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
| 575 | if (err) | 582 | if (err) |
| 576 | goto err_qpn; | 583 | goto err_qpn; |
| 577 | 584 | ||
| 585 | if (init_attr->qp_type == IB_QPT_XRC_TGT) | ||
| 586 | qp->mqp.qpn |= (1 << 23); | ||
| 587 | |||
| 578 | /* | 588 | /* |
| 579 | * Hardware wants QPN written in big-endian order (after | 589 | * Hardware wants QPN written in big-endian order (after |
| 580 | * shifting) for send doorbell. Precompute this value to save | 590 | * shifting) for send doorbell. Precompute this value to save |
| @@ -592,9 +602,8 @@ err_qpn: | |||
| 592 | 602 | ||
| 593 | err_wrid: | 603 | err_wrid: |
| 594 | if (pd->uobject) { | 604 | if (pd->uobject) { |
| 595 | if (!init_attr->srq) | 605 | if (qp_has_rq(init_attr)) |
| 596 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), | 606 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); |
| 597 | &qp->db); | ||
| 598 | } else { | 607 | } else { |
| 599 | kfree(qp->sq.wrid); | 608 | kfree(qp->sq.wrid); |
| 600 | kfree(qp->rq.wrid); | 609 | kfree(qp->rq.wrid); |
| @@ -610,7 +619,7 @@ err_buf: | |||
| 610 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); | 619 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); |
| 611 | 620 | ||
| 612 | err_db: | 621 | err_db: |
| 613 | if (!pd->uobject && !init_attr->srq) | 622 | if (!pd->uobject && qp_has_rq(init_attr)) |
| 614 | mlx4_db_free(dev->dev, &qp->db); | 623 | mlx4_db_free(dev->dev, &qp->db); |
| 615 | 624 | ||
| 616 | err: | 625 | err: |
| @@ -671,6 +680,33 @@ static void del_gid_entries(struct mlx4_ib_qp *qp) | |||
| 671 | } | 680 | } |
| 672 | } | 681 | } |
| 673 | 682 | ||
| 683 | static struct mlx4_ib_pd *get_pd(struct mlx4_ib_qp *qp) | ||
| 684 | { | ||
| 685 | if (qp->ibqp.qp_type == IB_QPT_XRC_TGT) | ||
| 686 | return to_mpd(to_mxrcd(qp->ibqp.xrcd)->pd); | ||
| 687 | else | ||
| 688 | return to_mpd(qp->ibqp.pd); | ||
| 689 | } | ||
| 690 | |||
| 691 | static void get_cqs(struct mlx4_ib_qp *qp, | ||
| 692 | struct mlx4_ib_cq **send_cq, struct mlx4_ib_cq **recv_cq) | ||
| 693 | { | ||
| 694 | switch (qp->ibqp.qp_type) { | ||
| 695 | case IB_QPT_XRC_TGT: | ||
| 696 | *send_cq = to_mcq(to_mxrcd(qp->ibqp.xrcd)->cq); | ||
| 697 | *recv_cq = *send_cq; | ||
| 698 | break; | ||
| 699 | case IB_QPT_XRC_INI: | ||
| 700 | *send_cq = to_mcq(qp->ibqp.send_cq); | ||
| 701 | *recv_cq = *send_cq; | ||
| 702 | break; | ||
| 703 | default: | ||
| 704 | *send_cq = to_mcq(qp->ibqp.send_cq); | ||
| 705 | *recv_cq = to_mcq(qp->ibqp.recv_cq); | ||
| 706 | break; | ||
| 707 | } | ||
| 708 | } | ||
| 709 | |||
| 674 | static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | 710 | static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, |
| 675 | int is_user) | 711 | int is_user) |
| 676 | { | 712 | { |
| @@ -682,8 +718,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
| 682 | printk(KERN_WARNING "mlx4_ib: modify QP %06x to RESET failed.\n", | 718 | printk(KERN_WARNING "mlx4_ib: modify QP %06x to RESET failed.\n", |
| 683 | qp->mqp.qpn); | 719 | qp->mqp.qpn); |
| 684 | 720 | ||
| 685 | send_cq = to_mcq(qp->ibqp.send_cq); | 721 | get_cqs(qp, &send_cq, &recv_cq); |
| 686 | recv_cq = to_mcq(qp->ibqp.recv_cq); | ||
| 687 | 722 | ||
| 688 | mlx4_ib_lock_cqs(send_cq, recv_cq); | 723 | mlx4_ib_lock_cqs(send_cq, recv_cq); |
| 689 | 724 | ||
| @@ -706,7 +741,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
| 706 | mlx4_mtt_cleanup(dev->dev, &qp->mtt); | 741 | mlx4_mtt_cleanup(dev->dev, &qp->mtt); |
| 707 | 742 | ||
| 708 | if (is_user) { | 743 | if (is_user) { |
| 709 | if (!qp->ibqp.srq) | 744 | if (qp->rq.wqe_cnt) |
| 710 | mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context), | 745 | mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context), |
| 711 | &qp->db); | 746 | &qp->db); |
| 712 | ib_umem_release(qp->umem); | 747 | ib_umem_release(qp->umem); |
| @@ -714,7 +749,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
| 714 | kfree(qp->sq.wrid); | 749 | kfree(qp->sq.wrid); |
| 715 | kfree(qp->rq.wrid); | 750 | kfree(qp->rq.wrid); |
| 716 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); | 751 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); |
| 717 | if (!qp->ibqp.srq) | 752 | if (qp->rq.wqe_cnt) |
| 718 | mlx4_db_free(dev->dev, &qp->db); | 753 | mlx4_db_free(dev->dev, &qp->db); |
| 719 | } | 754 | } |
| 720 | 755 | ||
| @@ -725,10 +760,10 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
| 725 | struct ib_qp_init_attr *init_attr, | 760 | struct ib_qp_init_attr *init_attr, |
| 726 | struct ib_udata *udata) | 761 | struct ib_udata *udata) |
| 727 | { | 762 | { |
| 728 | struct mlx4_ib_dev *dev = to_mdev(pd->device); | ||
| 729 | struct mlx4_ib_sqp *sqp; | 763 | struct mlx4_ib_sqp *sqp; |
| 730 | struct mlx4_ib_qp *qp; | 764 | struct mlx4_ib_qp *qp; |
| 731 | int err; | 765 | int err; |
| 766 | u16 xrcdn = 0; | ||
| 732 | 767 | ||
| 733 | /* | 768 | /* |
| 734 | * We only support LSO and multicast loopback blocking, and | 769 | * We only support LSO and multicast loopback blocking, and |
| @@ -739,10 +774,20 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
| 739 | return ERR_PTR(-EINVAL); | 774 | return ERR_PTR(-EINVAL); |
| 740 | 775 | ||
| 741 | if (init_attr->create_flags && | 776 | if (init_attr->create_flags && |
| 742 | (pd->uobject || init_attr->qp_type != IB_QPT_UD)) | 777 | (udata || init_attr->qp_type != IB_QPT_UD)) |
| 743 | return ERR_PTR(-EINVAL); | 778 | return ERR_PTR(-EINVAL); |
| 744 | 779 | ||
| 745 | switch (init_attr->qp_type) { | 780 | switch (init_attr->qp_type) { |
| 781 | case IB_QPT_XRC_TGT: | ||
| 782 | pd = to_mxrcd(init_attr->xrcd)->pd; | ||
| 783 | xrcdn = to_mxrcd(init_attr->xrcd)->xrcdn; | ||
| 784 | init_attr->send_cq = to_mxrcd(init_attr->xrcd)->cq; | ||
| 785 | /* fall through */ | ||
| 786 | case IB_QPT_XRC_INI: | ||
| 787 | if (!(to_mdev(pd->device)->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC)) | ||
| 788 | return ERR_PTR(-ENOSYS); | ||
| 789 | init_attr->recv_cq = init_attr->send_cq; | ||
| 790 | /* fall through */ | ||
| 746 | case IB_QPT_RC: | 791 | case IB_QPT_RC: |
| 747 | case IB_QPT_UC: | 792 | case IB_QPT_UC: |
| 748 | case IB_QPT_UD: | 793 | case IB_QPT_UD: |
| @@ -751,13 +796,14 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
| 751 | if (!qp) | 796 | if (!qp) |
| 752 | return ERR_PTR(-ENOMEM); | 797 | return ERR_PTR(-ENOMEM); |
| 753 | 798 | ||
| 754 | err = create_qp_common(dev, pd, init_attr, udata, 0, qp); | 799 | err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata, 0, qp); |
| 755 | if (err) { | 800 | if (err) { |
| 756 | kfree(qp); | 801 | kfree(qp); |
| 757 | return ERR_PTR(err); | 802 | return ERR_PTR(err); |
| 758 | } | 803 | } |
| 759 | 804 | ||
| 760 | qp->ibqp.qp_num = qp->mqp.qpn; | 805 | qp->ibqp.qp_num = qp->mqp.qpn; |
| 806 | qp->xrcdn = xrcdn; | ||
| 761 | 807 | ||
| 762 | break; | 808 | break; |
| 763 | } | 809 | } |
| @@ -765,7 +811,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
| 765 | case IB_QPT_GSI: | 811 | case IB_QPT_GSI: |
| 766 | { | 812 | { |
| 767 | /* Userspace is not allowed to create special QPs: */ | 813 | /* Userspace is not allowed to create special QPs: */ |
| 768 | if (pd->uobject) | 814 | if (udata) |
| 769 | return ERR_PTR(-EINVAL); | 815 | return ERR_PTR(-EINVAL); |
| 770 | 816 | ||
| 771 | sqp = kzalloc(sizeof *sqp, GFP_KERNEL); | 817 | sqp = kzalloc(sizeof *sqp, GFP_KERNEL); |
| @@ -774,8 +820,8 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
| 774 | 820 | ||
| 775 | qp = &sqp->qp; | 821 | qp = &sqp->qp; |
| 776 | 822 | ||
| 777 | err = create_qp_common(dev, pd, init_attr, udata, | 823 | err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata, |
| 778 | dev->dev->caps.sqp_start + | 824 | to_mdev(pd->device)->dev->caps.sqp_start + |
| 779 | (init_attr->qp_type == IB_QPT_SMI ? 0 : 2) + | 825 | (init_attr->qp_type == IB_QPT_SMI ? 0 : 2) + |
| 780 | init_attr->port_num - 1, | 826 | init_attr->port_num - 1, |
| 781 | qp); | 827 | qp); |
| @@ -801,11 +847,13 @@ int mlx4_ib_destroy_qp(struct ib_qp *qp) | |||
| 801 | { | 847 | { |
| 802 | struct mlx4_ib_dev *dev = to_mdev(qp->device); | 848 | struct mlx4_ib_dev *dev = to_mdev(qp->device); |
| 803 | struct mlx4_ib_qp *mqp = to_mqp(qp); | 849 | struct mlx4_ib_qp *mqp = to_mqp(qp); |
| 850 | struct mlx4_ib_pd *pd; | ||
| 804 | 851 | ||
| 805 | if (is_qp0(dev, mqp)) | 852 | if (is_qp0(dev, mqp)) |
| 806 | mlx4_CLOSE_PORT(dev->dev, mqp->port); | 853 | mlx4_CLOSE_PORT(dev->dev, mqp->port); |
| 807 | 854 | ||
| 808 | destroy_qp_common(dev, mqp, !!qp->pd->uobject); | 855 | pd = get_pd(mqp); |
| 856 | destroy_qp_common(dev, mqp, !!pd->ibpd.uobject); | ||
| 809 | 857 | ||
| 810 | if (is_sqp(dev, mqp)) | 858 | if (is_sqp(dev, mqp)) |
| 811 | kfree(to_msqp(mqp)); | 859 | kfree(to_msqp(mqp)); |
| @@ -821,6 +869,8 @@ static int to_mlx4_st(enum ib_qp_type type) | |||
| 821 | case IB_QPT_RC: return MLX4_QP_ST_RC; | 869 | case IB_QPT_RC: return MLX4_QP_ST_RC; |
| 822 | case IB_QPT_UC: return MLX4_QP_ST_UC; | 870 | case IB_QPT_UC: return MLX4_QP_ST_UC; |
| 823 | case IB_QPT_UD: return MLX4_QP_ST_UD; | 871 | case IB_QPT_UD: return MLX4_QP_ST_UD; |
| 872 | case IB_QPT_XRC_INI: | ||
| 873 | case IB_QPT_XRC_TGT: return MLX4_QP_ST_XRC; | ||
| 824 | case IB_QPT_SMI: | 874 | case IB_QPT_SMI: |
| 825 | case IB_QPT_GSI: return MLX4_QP_ST_MLX; | 875 | case IB_QPT_GSI: return MLX4_QP_ST_MLX; |
| 826 | default: return -1; | 876 | default: return -1; |
| @@ -959,6 +1009,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 959 | { | 1009 | { |
| 960 | struct mlx4_ib_dev *dev = to_mdev(ibqp->device); | 1010 | struct mlx4_ib_dev *dev = to_mdev(ibqp->device); |
| 961 | struct mlx4_ib_qp *qp = to_mqp(ibqp); | 1011 | struct mlx4_ib_qp *qp = to_mqp(ibqp); |
| 1012 | struct mlx4_ib_pd *pd; | ||
| 1013 | struct mlx4_ib_cq *send_cq, *recv_cq; | ||
| 962 | struct mlx4_qp_context *context; | 1014 | struct mlx4_qp_context *context; |
| 963 | enum mlx4_qp_optpar optpar = 0; | 1015 | enum mlx4_qp_optpar optpar = 0; |
| 964 | int sqd_event; | 1016 | int sqd_event; |
| @@ -1014,8 +1066,10 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1014 | context->sq_size_stride = ilog2(qp->sq.wqe_cnt) << 3; | 1066 | context->sq_size_stride = ilog2(qp->sq.wqe_cnt) << 3; |
| 1015 | context->sq_size_stride |= qp->sq.wqe_shift - 4; | 1067 | context->sq_size_stride |= qp->sq.wqe_shift - 4; |
| 1016 | 1068 | ||
| 1017 | if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) | 1069 | if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) { |
| 1018 | context->sq_size_stride |= !!qp->sq_no_prefetch << 7; | 1070 | context->sq_size_stride |= !!qp->sq_no_prefetch << 7; |
| 1071 | context->xrcd = cpu_to_be32((u32) qp->xrcdn); | ||
| 1072 | } | ||
| 1019 | 1073 | ||
| 1020 | if (qp->ibqp.uobject) | 1074 | if (qp->ibqp.uobject) |
| 1021 | context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index); | 1075 | context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index); |
| @@ -1079,8 +1133,12 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1079 | optpar |= MLX4_QP_OPTPAR_ALT_ADDR_PATH; | 1133 | optpar |= MLX4_QP_OPTPAR_ALT_ADDR_PATH; |
| 1080 | } | 1134 | } |
| 1081 | 1135 | ||
| 1082 | context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pdn); | 1136 | pd = get_pd(qp); |
| 1083 | context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28); | 1137 | get_cqs(qp, &send_cq, &recv_cq); |
| 1138 | context->pd = cpu_to_be32(pd->pdn); | ||
| 1139 | context->cqn_send = cpu_to_be32(send_cq->mcq.cqn); | ||
| 1140 | context->cqn_recv = cpu_to_be32(recv_cq->mcq.cqn); | ||
| 1141 | context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28); | ||
| 1084 | 1142 | ||
| 1085 | /* Set "fast registration enabled" for all kernel QPs */ | 1143 | /* Set "fast registration enabled" for all kernel QPs */ |
| 1086 | if (!qp->ibqp.uobject) | 1144 | if (!qp->ibqp.uobject) |
| @@ -1106,8 +1164,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1106 | if (attr_mask & IB_QP_SQ_PSN) | 1164 | if (attr_mask & IB_QP_SQ_PSN) |
| 1107 | context->next_send_psn = cpu_to_be32(attr->sq_psn); | 1165 | context->next_send_psn = cpu_to_be32(attr->sq_psn); |
| 1108 | 1166 | ||
| 1109 | context->cqn_send = cpu_to_be32(to_mcq(ibqp->send_cq)->mcq.cqn); | ||
| 1110 | |||
| 1111 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { | 1167 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { |
| 1112 | if (attr->max_dest_rd_atomic) | 1168 | if (attr->max_dest_rd_atomic) |
| 1113 | context->params2 |= | 1169 | context->params2 |= |
| @@ -1130,8 +1186,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1130 | if (attr_mask & IB_QP_RQ_PSN) | 1186 | if (attr_mask & IB_QP_RQ_PSN) |
| 1131 | context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn); | 1187 | context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn); |
| 1132 | 1188 | ||
| 1133 | context->cqn_recv = cpu_to_be32(to_mcq(ibqp->recv_cq)->mcq.cqn); | ||
| 1134 | |||
| 1135 | if (attr_mask & IB_QP_QKEY) { | 1189 | if (attr_mask & IB_QP_QKEY) { |
| 1136 | context->qkey = cpu_to_be32(attr->qkey); | 1190 | context->qkey = cpu_to_be32(attr->qkey); |
| 1137 | optpar |= MLX4_QP_OPTPAR_Q_KEY; | 1191 | optpar |= MLX4_QP_OPTPAR_Q_KEY; |
| @@ -1140,7 +1194,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1140 | if (ibqp->srq) | 1194 | if (ibqp->srq) |
| 1141 | context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn); | 1195 | context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn); |
| 1142 | 1196 | ||
| 1143 | if (!ibqp->srq && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) | 1197 | if (qp->rq.wqe_cnt && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) |
| 1144 | context->db_rec_addr = cpu_to_be64(qp->db.dma); | 1198 | context->db_rec_addr = cpu_to_be64(qp->db.dma); |
| 1145 | 1199 | ||
| 1146 | if (cur_state == IB_QPS_INIT && | 1200 | if (cur_state == IB_QPS_INIT && |
| @@ -1225,17 +1279,17 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 1225 | * entries and reinitialize the QP. | 1279 | * entries and reinitialize the QP. |
| 1226 | */ | 1280 | */ |
| 1227 | if (new_state == IB_QPS_RESET && !ibqp->uobject) { | 1281 | if (new_state == IB_QPS_RESET && !ibqp->uobject) { |
| 1228 | mlx4_ib_cq_clean(to_mcq(ibqp->recv_cq), qp->mqp.qpn, | 1282 | mlx4_ib_cq_clean(recv_cq, qp->mqp.qpn, |
| 1229 | ibqp->srq ? to_msrq(ibqp->srq): NULL); | 1283 | ibqp->srq ? to_msrq(ibqp->srq): NULL); |
| 1230 | if (ibqp->send_cq != ibqp->recv_cq) | 1284 | if (send_cq != recv_cq) |
| 1231 | mlx4_ib_cq_clean(to_mcq(ibqp->send_cq), qp->mqp.qpn, NULL); | 1285 | mlx4_ib_cq_clean(send_cq, qp->mqp.qpn, NULL); |
| 1232 | 1286 | ||
| 1233 | qp->rq.head = 0; | 1287 | qp->rq.head = 0; |
| 1234 | qp->rq.tail = 0; | 1288 | qp->rq.tail = 0; |
| 1235 | qp->sq.head = 0; | 1289 | qp->sq.head = 0; |
| 1236 | qp->sq.tail = 0; | 1290 | qp->sq.tail = 0; |
| 1237 | qp->sq_next_wqe = 0; | 1291 | qp->sq_next_wqe = 0; |
| 1238 | if (!ibqp->srq) | 1292 | if (qp->rq.wqe_cnt) |
| 1239 | *qp->db.db = 0; | 1293 | *qp->db.db = 0; |
| 1240 | } | 1294 | } |
| 1241 | 1295 | ||
diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c index ec9350e5f21a..51c53898c35f 100644 --- a/drivers/net/mlx4/qp.c +++ b/drivers/net/mlx4/qp.c | |||
| @@ -280,6 +280,9 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) | |||
| 280 | * We reserve 2 extra QPs per port for the special QPs. The | 280 | * We reserve 2 extra QPs per port for the special QPs. The |
| 281 | * block of special QPs must be aligned to a multiple of 8, so | 281 | * block of special QPs must be aligned to a multiple of 8, so |
| 282 | * round up. | 282 | * round up. |
| 283 | * | ||
| 284 | * We also reserve the MSB of the 24-bit QP number to indicate | ||
| 285 | * that a QP is an XRC QP. | ||
| 283 | */ | 286 | */ |
| 284 | dev->caps.sqp_start = | 287 | dev->caps.sqp_start = |
| 285 | ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8); | 288 | ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8); |
