| .. | .. |
|---|
| 41 | 41 | #include <rdma/ib_pack.h> |
|---|
| 42 | 42 | #include <rdma/ib_addr.h> |
|---|
| 43 | 43 | #include <rdma/ib_mad.h> |
|---|
| 44 | +#include <rdma/uverbs_ioctl.h> |
|---|
| 44 | 45 | |
|---|
| 45 | 46 | #include <linux/mlx4/driver.h> |
|---|
| 46 | 47 | #include <linux/mlx4/qp.h> |
|---|
| .. | .. |
|---|
| 52 | 53 | struct mlx4_ib_cq *recv_cq); |
|---|
| 53 | 54 | static void mlx4_ib_unlock_cqs(struct mlx4_ib_cq *send_cq, |
|---|
| 54 | 55 | struct mlx4_ib_cq *recv_cq); |
|---|
| 55 | | -static int _mlx4_ib_modify_wq(struct ib_wq *ibwq, enum ib_wq_state new_state); |
|---|
| 56 | +static int _mlx4_ib_modify_wq(struct ib_wq *ibwq, enum ib_wq_state new_state, |
|---|
| 57 | + struct ib_udata *udata); |
|---|
| 56 | 58 | |
|---|
| 57 | 59 | enum { |
|---|
| 58 | 60 | MLX4_IB_ACK_REQ_FREQ = 8, |
|---|
| .. | .. |
|---|
| 63 | 65 | MLX4_IB_DEFAULT_QP0_SCHED_QUEUE = 0x3f, |
|---|
| 64 | 66 | MLX4_IB_LINK_TYPE_IB = 0, |
|---|
| 65 | 67 | MLX4_IB_LINK_TYPE_ETH = 1 |
|---|
| 66 | | -}; |
|---|
| 67 | | - |
|---|
| 68 | | -enum { |
|---|
| 69 | | - /* |
|---|
| 70 | | - * Largest possible UD header: send with GRH and immediate |
|---|
| 71 | | - * data plus 18 bytes for an Ethernet header with VLAN/802.1Q |
|---|
| 72 | | - * tag. (LRH would only use 8 bytes, so Ethernet is the |
|---|
| 73 | | - * biggest case) |
|---|
| 74 | | - */ |
|---|
| 75 | | - MLX4_IB_UD_HEADER_SIZE = 82, |
|---|
| 76 | | - MLX4_IB_LSO_HEADER_SPARE = 128, |
|---|
| 77 | | -}; |
|---|
| 78 | | - |
|---|
| 79 | | -struct mlx4_ib_sqp { |
|---|
| 80 | | - struct mlx4_ib_qp qp; |
|---|
| 81 | | - int pkey_index; |
|---|
| 82 | | - u32 qkey; |
|---|
| 83 | | - u32 send_psn; |
|---|
| 84 | | - struct ib_ud_header ud_header; |
|---|
| 85 | | - u8 header_buf[MLX4_IB_UD_HEADER_SIZE]; |
|---|
| 86 | | - struct ib_qp *roce_v2_gsi; |
|---|
| 87 | 68 | }; |
|---|
| 88 | 69 | |
|---|
| 89 | 70 | enum { |
|---|
| .. | .. |
|---|
| 120 | 101 | MLX4_IB_QP_SRC = 0, |
|---|
| 121 | 102 | MLX4_IB_RWQ_SRC = 1, |
|---|
| 122 | 103 | }; |
|---|
| 123 | | - |
|---|
| 124 | | -static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp) |
|---|
| 125 | | -{ |
|---|
| 126 | | - return container_of(mqp, struct mlx4_ib_sqp, qp); |
|---|
| 127 | | -} |
|---|
| 128 | 104 | |
|---|
| 129 | 105 | static int is_tunnel_qp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) |
|---|
| 130 | 106 | { |
|---|
| .. | .. |
|---|
| 323 | 299 | } |
|---|
| 324 | 300 | |
|---|
| 325 | 301 | static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, |
|---|
| 326 | | - int is_user, int has_rq, struct mlx4_ib_qp *qp, |
|---|
| 302 | + bool is_user, bool has_rq, struct mlx4_ib_qp *qp, |
|---|
| 327 | 303 | u32 inl_recv_sz) |
|---|
| 328 | 304 | { |
|---|
| 329 | 305 | /* Sanity check RQ size before proceeding */ |
|---|
| .. | .. |
|---|
| 401 | 377 | * We need to leave 2 KB + 1 WR of headroom in the SQ to |
|---|
| 402 | 378 | * allow HW to prefetch. |
|---|
| 403 | 379 | */ |
|---|
| 404 | | - qp->sq_spare_wqes = (2048 >> qp->sq.wqe_shift) + 1; |
|---|
| 380 | + qp->sq_spare_wqes = MLX4_IB_SQ_HEADROOM(qp->sq.wqe_shift); |
|---|
| 405 | 381 | qp->sq.wqe_cnt = roundup_pow_of_two(cap->max_send_wr + |
|---|
| 406 | 382 | qp->sq_spare_wqes); |
|---|
| 407 | 383 | |
|---|
| .. | .. |
|---|
| 436 | 412 | struct mlx4_ib_qp *qp, |
|---|
| 437 | 413 | struct mlx4_ib_create_qp *ucmd) |
|---|
| 438 | 414 | { |
|---|
| 415 | + u32 cnt; |
|---|
| 416 | + |
|---|
| 439 | 417 | /* Sanity check SQ size before proceeding */ |
|---|
| 440 | | - if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes || |
|---|
| 441 | | - ucmd->log_sq_stride > |
|---|
| 418 | + if (check_shl_overflow(1, ucmd->log_sq_bb_count, &cnt) || |
|---|
| 419 | + cnt > dev->dev->caps.max_wqes) |
|---|
| 420 | + return -EINVAL; |
|---|
| 421 | + if (ucmd->log_sq_stride > |
|---|
| 442 | 422 | ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) || |
|---|
| 443 | 423 | ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE) |
|---|
| 444 | 424 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 504 | 484 | kfree(qp->sqp_proxy_rcv); |
|---|
| 505 | 485 | } |
|---|
| 506 | 486 | |
|---|
| 507 | | -static int qp_has_rq(struct ib_qp_init_attr *attr) |
|---|
| 487 | +static bool qp_has_rq(struct ib_qp_init_attr *attr) |
|---|
| 508 | 488 | { |
|---|
| 509 | 489 | if (attr->qp_type == IB_QPT_XRC_INI || attr->qp_type == IB_QPT_XRC_TGT) |
|---|
| 510 | | - return 0; |
|---|
| 490 | + return false; |
|---|
| 511 | 491 | |
|---|
| 512 | 492 | return !attr->srq; |
|---|
| 513 | 493 | } |
|---|
| .. | .. |
|---|
| 550 | 530 | return (-EOPNOTSUPP); |
|---|
| 551 | 531 | } |
|---|
| 552 | 532 | |
|---|
| 553 | | - if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | |
|---|
| 554 | | - MLX4_IB_RX_HASH_DST_IPV4 | |
|---|
| 555 | | - MLX4_IB_RX_HASH_SRC_IPV6 | |
|---|
| 556 | | - MLX4_IB_RX_HASH_DST_IPV6 | |
|---|
| 557 | | - MLX4_IB_RX_HASH_SRC_PORT_TCP | |
|---|
| 558 | | - MLX4_IB_RX_HASH_DST_PORT_TCP | |
|---|
| 559 | | - MLX4_IB_RX_HASH_SRC_PORT_UDP | |
|---|
| 560 | | - MLX4_IB_RX_HASH_DST_PORT_UDP | |
|---|
| 561 | | - MLX4_IB_RX_HASH_INNER)) { |
|---|
| 533 | + if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | |
|---|
| 534 | + MLX4_IB_RX_HASH_DST_IPV4 | |
|---|
| 535 | + MLX4_IB_RX_HASH_SRC_IPV6 | |
|---|
| 536 | + MLX4_IB_RX_HASH_DST_IPV6 | |
|---|
| 537 | + MLX4_IB_RX_HASH_SRC_PORT_TCP | |
|---|
| 538 | + MLX4_IB_RX_HASH_DST_PORT_TCP | |
|---|
| 539 | + MLX4_IB_RX_HASH_SRC_PORT_UDP | |
|---|
| 540 | + MLX4_IB_RX_HASH_DST_PORT_UDP | |
|---|
| 541 | + MLX4_IB_RX_HASH_INNER)) { |
|---|
| 562 | 542 | pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", |
|---|
| 563 | 543 | ucmd->rx_hash_fields_mask); |
|---|
| 564 | 544 | return (-EOPNOTSUPP); |
|---|
| .. | .. |
|---|
| 654 | 634 | if (err) |
|---|
| 655 | 635 | goto err_qpn; |
|---|
| 656 | 636 | |
|---|
| 657 | | - mutex_init(&qp->mutex); |
|---|
| 658 | | - |
|---|
| 659 | 637 | INIT_LIST_HEAD(&qp->gid_list); |
|---|
| 660 | 638 | INIT_LIST_HEAD(&qp->steering_rules); |
|---|
| 661 | 639 | |
|---|
| .. | .. |
|---|
| 694 | 672 | return err; |
|---|
| 695 | 673 | } |
|---|
| 696 | 674 | |
|---|
| 697 | | -static struct ib_qp *_mlx4_ib_create_qp_rss(struct ib_pd *pd, |
|---|
| 698 | | - struct ib_qp_init_attr *init_attr, |
|---|
| 699 | | - struct ib_udata *udata) |
|---|
| 675 | +static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, struct mlx4_ib_qp *qp, |
|---|
| 676 | + struct ib_qp_init_attr *init_attr, |
|---|
| 677 | + struct ib_udata *udata) |
|---|
| 700 | 678 | { |
|---|
| 701 | | - struct mlx4_ib_qp *qp; |
|---|
| 702 | 679 | struct mlx4_ib_create_qp_rss ucmd = {}; |
|---|
| 703 | 680 | size_t required_cmd_sz; |
|---|
| 704 | 681 | int err; |
|---|
| 705 | 682 | |
|---|
| 706 | 683 | if (!udata) { |
|---|
| 707 | 684 | pr_debug("RSS QP with NULL udata\n"); |
|---|
| 708 | | - return ERR_PTR(-EINVAL); |
|---|
| 685 | + return -EINVAL; |
|---|
| 709 | 686 | } |
|---|
| 710 | 687 | |
|---|
| 711 | 688 | if (udata->outlen) |
|---|
| 712 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 689 | + return -EOPNOTSUPP; |
|---|
| 713 | 690 | |
|---|
| 714 | 691 | required_cmd_sz = offsetof(typeof(ucmd), reserved1) + |
|---|
| 715 | 692 | sizeof(ucmd.reserved1); |
|---|
| 716 | 693 | if (udata->inlen < required_cmd_sz) { |
|---|
| 717 | 694 | pr_debug("invalid inlen\n"); |
|---|
| 718 | | - return ERR_PTR(-EINVAL); |
|---|
| 695 | + return -EINVAL; |
|---|
| 719 | 696 | } |
|---|
| 720 | 697 | |
|---|
| 721 | 698 | if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) { |
|---|
| 722 | 699 | pr_debug("copy failed\n"); |
|---|
| 723 | | - return ERR_PTR(-EFAULT); |
|---|
| 700 | + return -EFAULT; |
|---|
| 724 | 701 | } |
|---|
| 725 | 702 | |
|---|
| 726 | 703 | if (memchr_inv(ucmd.reserved, 0, sizeof(ucmd.reserved))) |
|---|
| 727 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 704 | + return -EOPNOTSUPP; |
|---|
| 728 | 705 | |
|---|
| 729 | 706 | if (ucmd.comp_mask || ucmd.reserved1) |
|---|
| 730 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 707 | + return -EOPNOTSUPP; |
|---|
| 731 | 708 | |
|---|
| 732 | 709 | if (udata->inlen > sizeof(ucmd) && |
|---|
| 733 | 710 | !ib_is_udata_cleared(udata, sizeof(ucmd), |
|---|
| 734 | 711 | udata->inlen - sizeof(ucmd))) { |
|---|
| 735 | 712 | pr_debug("inlen is not supported\n"); |
|---|
| 736 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 713 | + return -EOPNOTSUPP; |
|---|
| 737 | 714 | } |
|---|
| 738 | 715 | |
|---|
| 739 | 716 | if (init_attr->qp_type != IB_QPT_RAW_PACKET) { |
|---|
| 740 | 717 | pr_debug("RSS QP with unsupported QP type %d\n", |
|---|
| 741 | 718 | init_attr->qp_type); |
|---|
| 742 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 719 | + return -EOPNOTSUPP; |
|---|
| 743 | 720 | } |
|---|
| 744 | 721 | |
|---|
| 745 | 722 | if (init_attr->create_flags) { |
|---|
| 746 | 723 | pr_debug("RSS QP doesn't support create flags\n"); |
|---|
| 747 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 724 | + return -EOPNOTSUPP; |
|---|
| 748 | 725 | } |
|---|
| 749 | 726 | |
|---|
| 750 | 727 | if (init_attr->send_cq || init_attr->cap.max_send_wr) { |
|---|
| 751 | 728 | pr_debug("RSS QP with unsupported send attributes\n"); |
|---|
| 752 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 729 | + return -EOPNOTSUPP; |
|---|
| 753 | 730 | } |
|---|
| 754 | | - |
|---|
| 755 | | - qp = kzalloc(sizeof(*qp), GFP_KERNEL); |
|---|
| 756 | | - if (!qp) |
|---|
| 757 | | - return ERR_PTR(-ENOMEM); |
|---|
| 758 | 731 | |
|---|
| 759 | 732 | qp->pri.vid = 0xFFFF; |
|---|
| 760 | 733 | qp->alt.vid = 0xFFFF; |
|---|
| 761 | 734 | |
|---|
| 762 | 735 | err = create_qp_rss(to_mdev(pd->device), init_attr, &ucmd, qp); |
|---|
| 763 | | - if (err) { |
|---|
| 764 | | - kfree(qp); |
|---|
| 765 | | - return ERR_PTR(err); |
|---|
| 766 | | - } |
|---|
| 736 | + if (err) |
|---|
| 737 | + return err; |
|---|
| 767 | 738 | |
|---|
| 768 | 739 | qp->ibqp.qp_num = qp->mqp.qpn; |
|---|
| 769 | | - |
|---|
| 770 | | - return &qp->ibqp; |
|---|
| 740 | + return 0; |
|---|
| 771 | 741 | } |
|---|
| 772 | 742 | |
|---|
| 773 | 743 | /* |
|---|
| .. | .. |
|---|
| 847 | 817 | * reused for further WQN allocations. |
|---|
| 848 | 818 | * The next created WQ will allocate a new range. |
|---|
| 849 | 819 | */ |
|---|
| 850 | | - range->dirty = 1; |
|---|
| 820 | + range->dirty = true; |
|---|
| 851 | 821 | } |
|---|
| 852 | 822 | |
|---|
| 853 | 823 | mutex_unlock(&context->wqn_ranges_mutex); |
|---|
| 854 | 824 | } |
|---|
| 855 | 825 | |
|---|
| 856 | | -static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, |
|---|
| 857 | | - enum mlx4_ib_source_type src, |
|---|
| 858 | | - struct ib_qp_init_attr *init_attr, |
|---|
| 859 | | - struct ib_udata *udata, int sqpn, |
|---|
| 860 | | - struct mlx4_ib_qp **caller_qp) |
|---|
| 826 | +static int create_rq(struct ib_pd *pd, struct ib_qp_init_attr *init_attr, |
|---|
| 827 | + struct ib_udata *udata, struct mlx4_ib_qp *qp) |
|---|
| 861 | 828 | { |
|---|
| 829 | + struct mlx4_ib_dev *dev = to_mdev(pd->device); |
|---|
| 862 | 830 | int qpn; |
|---|
| 863 | 831 | int err; |
|---|
| 864 | | - struct mlx4_ib_sqp *sqp = NULL; |
|---|
| 865 | | - struct mlx4_ib_qp *qp; |
|---|
| 832 | + struct mlx4_ib_ucontext *context = rdma_udata_to_drv_context( |
|---|
| 833 | + udata, struct mlx4_ib_ucontext, ibucontext); |
|---|
| 834 | + struct mlx4_ib_cq *mcq; |
|---|
| 835 | + unsigned long flags; |
|---|
| 836 | + int range_size; |
|---|
| 837 | + struct mlx4_ib_create_wq wq; |
|---|
| 838 | + size_t copy_len; |
|---|
| 839 | + int shift; |
|---|
| 840 | + int n; |
|---|
| 841 | + |
|---|
| 842 | + qp->mlx4_ib_qp_type = MLX4_IB_QPT_RAW_PACKET; |
|---|
| 843 | + |
|---|
| 844 | + spin_lock_init(&qp->sq.lock); |
|---|
| 845 | + spin_lock_init(&qp->rq.lock); |
|---|
| 846 | + INIT_LIST_HEAD(&qp->gid_list); |
|---|
| 847 | + INIT_LIST_HEAD(&qp->steering_rules); |
|---|
| 848 | + |
|---|
| 849 | + qp->state = IB_QPS_RESET; |
|---|
| 850 | + |
|---|
| 851 | + copy_len = min(sizeof(struct mlx4_ib_create_wq), udata->inlen); |
|---|
| 852 | + |
|---|
| 853 | + if (ib_copy_from_udata(&wq, udata, copy_len)) { |
|---|
| 854 | + err = -EFAULT; |
|---|
| 855 | + goto err; |
|---|
| 856 | + } |
|---|
| 857 | + |
|---|
| 858 | + if (wq.comp_mask || wq.reserved[0] || wq.reserved[1] || |
|---|
| 859 | + wq.reserved[2]) { |
|---|
| 860 | + pr_debug("user command isn't supported\n"); |
|---|
| 861 | + err = -EOPNOTSUPP; |
|---|
| 862 | + goto err; |
|---|
| 863 | + } |
|---|
| 864 | + |
|---|
| 865 | + if (wq.log_range_size > ilog2(dev->dev->caps.max_rss_tbl_sz)) { |
|---|
| 866 | + pr_debug("WQN range size must be equal or smaller than %d\n", |
|---|
| 867 | + dev->dev->caps.max_rss_tbl_sz); |
|---|
| 868 | + err = -EOPNOTSUPP; |
|---|
| 869 | + goto err; |
|---|
| 870 | + } |
|---|
| 871 | + range_size = 1 << wq.log_range_size; |
|---|
| 872 | + |
|---|
| 873 | + if (init_attr->create_flags & IB_QP_CREATE_SCATTER_FCS) |
|---|
| 874 | + qp->flags |= MLX4_IB_QP_SCATTER_FCS; |
|---|
| 875 | + |
|---|
| 876 | + err = set_rq_size(dev, &init_attr->cap, true, true, qp, qp->inl_recv_sz); |
|---|
| 877 | + if (err) |
|---|
| 878 | + goto err; |
|---|
| 879 | + |
|---|
| 880 | + qp->sq_no_prefetch = 1; |
|---|
| 881 | + qp->sq.wqe_cnt = 1; |
|---|
| 882 | + qp->sq.wqe_shift = MLX4_IB_MIN_SQ_STRIDE; |
|---|
| 883 | + qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) + |
|---|
| 884 | + (qp->sq.wqe_cnt << qp->sq.wqe_shift); |
|---|
| 885 | + |
|---|
| 886 | + qp->umem = ib_umem_get(pd->device, wq.buf_addr, qp->buf_size, 0); |
|---|
| 887 | + if (IS_ERR(qp->umem)) { |
|---|
| 888 | + err = PTR_ERR(qp->umem); |
|---|
| 889 | + goto err; |
|---|
| 890 | + } |
|---|
| 891 | + |
|---|
| 892 | + shift = mlx4_ib_umem_calc_optimal_mtt_size(qp->umem, 0, &n); |
|---|
| 893 | + err = mlx4_mtt_init(dev->dev, n, shift, &qp->mtt); |
|---|
| 894 | + |
|---|
| 895 | + if (err) |
|---|
| 896 | + goto err_buf; |
|---|
| 897 | + |
|---|
| 898 | + err = mlx4_ib_umem_write_mtt(dev, &qp->mtt, qp->umem); |
|---|
| 899 | + if (err) |
|---|
| 900 | + goto err_mtt; |
|---|
| 901 | + |
|---|
| 902 | + err = mlx4_ib_db_map_user(udata, wq.db_addr, &qp->db); |
|---|
| 903 | + if (err) |
|---|
| 904 | + goto err_mtt; |
|---|
| 905 | + qp->mqp.usage = MLX4_RES_USAGE_USER_VERBS; |
|---|
| 906 | + |
|---|
| 907 | + err = mlx4_ib_alloc_wqn(context, qp, range_size, &qpn); |
|---|
| 908 | + if (err) |
|---|
| 909 | + goto err_wrid; |
|---|
| 910 | + |
|---|
| 911 | + err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp); |
|---|
| 912 | + if (err) |
|---|
| 913 | + goto err_qpn; |
|---|
| 914 | + |
|---|
| 915 | + /* |
|---|
| 916 | + * Hardware wants QPN written in big-endian order (after |
|---|
| 917 | + * shifting) for send doorbell. Precompute this value to save |
|---|
| 918 | + * a little bit when posting sends. |
|---|
| 919 | + */ |
|---|
| 920 | + qp->doorbell_qpn = swab32(qp->mqp.qpn << 8); |
|---|
| 921 | + |
|---|
| 922 | + qp->mqp.event = mlx4_ib_wq_event; |
|---|
| 923 | + |
|---|
| 924 | + spin_lock_irqsave(&dev->reset_flow_resource_lock, flags); |
|---|
| 925 | + mlx4_ib_lock_cqs(to_mcq(init_attr->send_cq), |
|---|
| 926 | + to_mcq(init_attr->recv_cq)); |
|---|
| 927 | + /* Maintain device to QPs access, needed for further handling |
|---|
| 928 | + * via reset flow |
|---|
| 929 | + */ |
|---|
| 930 | + list_add_tail(&qp->qps_list, &dev->qp_list); |
|---|
| 931 | + /* Maintain CQ to QPs access, needed for further handling |
|---|
| 932 | + * via reset flow |
|---|
| 933 | + */ |
|---|
| 934 | + mcq = to_mcq(init_attr->send_cq); |
|---|
| 935 | + list_add_tail(&qp->cq_send_list, &mcq->send_qp_list); |
|---|
| 936 | + mcq = to_mcq(init_attr->recv_cq); |
|---|
| 937 | + list_add_tail(&qp->cq_recv_list, &mcq->recv_qp_list); |
|---|
| 938 | + mlx4_ib_unlock_cqs(to_mcq(init_attr->send_cq), |
|---|
| 939 | + to_mcq(init_attr->recv_cq)); |
|---|
| 940 | + spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags); |
|---|
| 941 | + return 0; |
|---|
| 942 | + |
|---|
| 943 | +err_qpn: |
|---|
| 944 | + mlx4_ib_release_wqn(context, qp, 0); |
|---|
| 945 | +err_wrid: |
|---|
| 946 | + mlx4_ib_db_unmap_user(context, &qp->db); |
|---|
| 947 | + |
|---|
| 948 | +err_mtt: |
|---|
| 949 | + mlx4_mtt_cleanup(dev->dev, &qp->mtt); |
|---|
| 950 | +err_buf: |
|---|
| 951 | + ib_umem_release(qp->umem); |
|---|
| 952 | +err: |
|---|
| 953 | + return err; |
|---|
| 954 | +} |
|---|
| 955 | + |
|---|
| 956 | +static int create_qp_common(struct ib_pd *pd, struct ib_qp_init_attr *init_attr, |
|---|
| 957 | + struct ib_udata *udata, int sqpn, |
|---|
| 958 | + struct mlx4_ib_qp *qp) |
|---|
| 959 | +{ |
|---|
| 960 | + struct mlx4_ib_dev *dev = to_mdev(pd->device); |
|---|
| 961 | + int qpn; |
|---|
| 962 | + int err; |
|---|
| 963 | + struct mlx4_ib_ucontext *context = rdma_udata_to_drv_context( |
|---|
| 964 | + udata, struct mlx4_ib_ucontext, ibucontext); |
|---|
| 866 | 965 | enum mlx4_ib_qp_type qp_type = (enum mlx4_ib_qp_type) init_attr->qp_type; |
|---|
| 867 | 966 | struct mlx4_ib_cq *mcq; |
|---|
| 868 | 967 | unsigned long flags; |
|---|
| 869 | | - int range_size = 0; |
|---|
| 870 | 968 | |
|---|
| 871 | 969 | /* When tunneling special qps, we use a plain UD qp */ |
|---|
| 872 | 970 | if (sqpn) { |
|---|
| .. | .. |
|---|
| 909 | 1007 | sqpn = qpn; |
|---|
| 910 | 1008 | } |
|---|
| 911 | 1009 | |
|---|
| 912 | | - if (!*caller_qp) { |
|---|
| 913 | | - if (qp_type == MLX4_IB_QPT_SMI || qp_type == MLX4_IB_QPT_GSI || |
|---|
| 914 | | - (qp_type & (MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_SMI_OWNER | |
|---|
| 915 | | - MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER))) { |
|---|
| 916 | | - sqp = kzalloc(sizeof(struct mlx4_ib_sqp), GFP_KERNEL); |
|---|
| 917 | | - if (!sqp) |
|---|
| 918 | | - return -ENOMEM; |
|---|
| 919 | | - qp = &sqp->qp; |
|---|
| 920 | | - qp->pri.vid = 0xFFFF; |
|---|
| 921 | | - qp->alt.vid = 0xFFFF; |
|---|
| 922 | | - } else { |
|---|
| 923 | | - qp = kzalloc(sizeof(struct mlx4_ib_qp), GFP_KERNEL); |
|---|
| 924 | | - if (!qp) |
|---|
| 925 | | - return -ENOMEM; |
|---|
| 926 | | - qp->pri.vid = 0xFFFF; |
|---|
| 927 | | - qp->alt.vid = 0xFFFF; |
|---|
| 928 | | - } |
|---|
| 929 | | - } else |
|---|
| 930 | | - qp = *caller_qp; |
|---|
| 1010 | + if (init_attr->qp_type == IB_QPT_SMI || |
|---|
| 1011 | + init_attr->qp_type == IB_QPT_GSI || qp_type == MLX4_IB_QPT_SMI || |
|---|
| 1012 | + qp_type == MLX4_IB_QPT_GSI || |
|---|
| 1013 | + (qp_type & (MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_SMI_OWNER | |
|---|
| 1014 | + MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER))) { |
|---|
| 1015 | + qp->sqp = kzalloc(sizeof(struct mlx4_ib_sqp), GFP_KERNEL); |
|---|
| 1016 | + if (!qp->sqp) |
|---|
| 1017 | + return -ENOMEM; |
|---|
| 1018 | + } |
|---|
| 931 | 1019 | |
|---|
| 932 | 1020 | qp->mlx4_ib_qp_type = qp_type; |
|---|
| 933 | 1021 | |
|---|
| 934 | | - mutex_init(&qp->mutex); |
|---|
| 935 | 1022 | spin_lock_init(&qp->sq.lock); |
|---|
| 936 | 1023 | spin_lock_init(&qp->rq.lock); |
|---|
| 937 | 1024 | INIT_LIST_HEAD(&qp->gid_list); |
|---|
| 938 | 1025 | INIT_LIST_HEAD(&qp->steering_rules); |
|---|
| 939 | 1026 | |
|---|
| 940 | | - qp->state = IB_QPS_RESET; |
|---|
| 1027 | + qp->state = IB_QPS_RESET; |
|---|
| 941 | 1028 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) |
|---|
| 942 | 1029 | qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); |
|---|
| 943 | 1030 | |
|---|
| 944 | | - |
|---|
| 945 | | - if (pd->uobject) { |
|---|
| 946 | | - union { |
|---|
| 947 | | - struct mlx4_ib_create_qp qp; |
|---|
| 948 | | - struct mlx4_ib_create_wq wq; |
|---|
| 949 | | - } ucmd; |
|---|
| 1031 | + if (udata) { |
|---|
| 1032 | + struct mlx4_ib_create_qp ucmd; |
|---|
| 950 | 1033 | size_t copy_len; |
|---|
| 951 | 1034 | int shift; |
|---|
| 952 | 1035 | int n; |
|---|
| 953 | 1036 | |
|---|
| 954 | | - copy_len = (src == MLX4_IB_QP_SRC) ? |
|---|
| 955 | | - sizeof(struct mlx4_ib_create_qp) : |
|---|
| 956 | | - min(sizeof(struct mlx4_ib_create_wq), udata->inlen); |
|---|
| 1037 | + copy_len = sizeof(struct mlx4_ib_create_qp); |
|---|
| 957 | 1038 | |
|---|
| 958 | 1039 | if (ib_copy_from_udata(&ucmd, udata, copy_len)) { |
|---|
| 959 | 1040 | err = -EFAULT; |
|---|
| 960 | 1041 | goto err; |
|---|
| 961 | 1042 | } |
|---|
| 962 | 1043 | |
|---|
| 963 | | - if (src == MLX4_IB_RWQ_SRC) { |
|---|
| 964 | | - if (ucmd.wq.comp_mask || ucmd.wq.reserved[0] || |
|---|
| 965 | | - ucmd.wq.reserved[1] || ucmd.wq.reserved[2]) { |
|---|
| 966 | | - pr_debug("user command isn't supported\n"); |
|---|
| 967 | | - err = -EOPNOTSUPP; |
|---|
| 968 | | - goto err; |
|---|
| 969 | | - } |
|---|
| 970 | | - |
|---|
| 971 | | - if (ucmd.wq.log_range_size > |
|---|
| 972 | | - ilog2(dev->dev->caps.max_rss_tbl_sz)) { |
|---|
| 973 | | - pr_debug("WQN range size must be equal or smaller than %d\n", |
|---|
| 974 | | - dev->dev->caps.max_rss_tbl_sz); |
|---|
| 975 | | - err = -EOPNOTSUPP; |
|---|
| 976 | | - goto err; |
|---|
| 977 | | - } |
|---|
| 978 | | - range_size = 1 << ucmd.wq.log_range_size; |
|---|
| 979 | | - } else { |
|---|
| 980 | | - qp->inl_recv_sz = ucmd.qp.inl_recv_sz; |
|---|
| 981 | | - } |
|---|
| 1044 | + qp->inl_recv_sz = ucmd.inl_recv_sz; |
|---|
| 982 | 1045 | |
|---|
| 983 | 1046 | if (init_attr->create_flags & IB_QP_CREATE_SCATTER_FCS) { |
|---|
| 984 | 1047 | if (!(dev->dev->caps.flags & |
|---|
| .. | .. |
|---|
| 991 | 1054 | qp->flags |= MLX4_IB_QP_SCATTER_FCS; |
|---|
| 992 | 1055 | } |
|---|
| 993 | 1056 | |
|---|
| 994 | | - err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, |
|---|
| 1057 | + err = set_rq_size(dev, &init_attr->cap, udata, |
|---|
| 995 | 1058 | qp_has_rq(init_attr), qp, qp->inl_recv_sz); |
|---|
| 996 | 1059 | if (err) |
|---|
| 997 | 1060 | goto err; |
|---|
| 998 | 1061 | |
|---|
| 999 | | - if (src == MLX4_IB_QP_SRC) { |
|---|
| 1000 | | - qp->sq_no_prefetch = ucmd.qp.sq_no_prefetch; |
|---|
| 1062 | + qp->sq_no_prefetch = ucmd.sq_no_prefetch; |
|---|
| 1001 | 1063 | |
|---|
| 1002 | | - err = set_user_sq_size(dev, qp, |
|---|
| 1003 | | - (struct mlx4_ib_create_qp *) |
|---|
| 1004 | | - &ucmd); |
|---|
| 1005 | | - if (err) |
|---|
| 1006 | | - goto err; |
|---|
| 1007 | | - } else { |
|---|
| 1008 | | - qp->sq_no_prefetch = 1; |
|---|
| 1009 | | - qp->sq.wqe_cnt = 1; |
|---|
| 1010 | | - qp->sq.wqe_shift = MLX4_IB_MIN_SQ_STRIDE; |
|---|
| 1011 | | - /* Allocated buffer expects to have at least that SQ |
|---|
| 1012 | | - * size. |
|---|
| 1013 | | - */ |
|---|
| 1014 | | - qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) + |
|---|
| 1015 | | - (qp->sq.wqe_cnt << qp->sq.wqe_shift); |
|---|
| 1016 | | - } |
|---|
| 1064 | + err = set_user_sq_size(dev, qp, &ucmd); |
|---|
| 1065 | + if (err) |
|---|
| 1066 | + goto err; |
|---|
| 1017 | 1067 | |
|---|
| 1018 | | - qp->umem = ib_umem_get(pd->uobject->context, |
|---|
| 1019 | | - (src == MLX4_IB_QP_SRC) ? ucmd.qp.buf_addr : |
|---|
| 1020 | | - ucmd.wq.buf_addr, qp->buf_size, 0, 0); |
|---|
| 1068 | + qp->umem = |
|---|
| 1069 | + ib_umem_get(pd->device, ucmd.buf_addr, qp->buf_size, 0); |
|---|
| 1021 | 1070 | if (IS_ERR(qp->umem)) { |
|---|
| 1022 | 1071 | err = PTR_ERR(qp->umem); |
|---|
| 1023 | 1072 | goto err; |
|---|
| 1024 | 1073 | } |
|---|
| 1025 | 1074 | |
|---|
| 1026 | | - n = ib_umem_page_count(qp->umem); |
|---|
| 1027 | 1075 | shift = mlx4_ib_umem_calc_optimal_mtt_size(qp->umem, 0, &n); |
|---|
| 1028 | 1076 | err = mlx4_mtt_init(dev->dev, n, shift, &qp->mtt); |
|---|
| 1029 | 1077 | |
|---|
| .. | .. |
|---|
| 1035 | 1083 | goto err_mtt; |
|---|
| 1036 | 1084 | |
|---|
| 1037 | 1085 | if (qp_has_rq(init_attr)) { |
|---|
| 1038 | | - err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context), |
|---|
| 1039 | | - (src == MLX4_IB_QP_SRC) ? ucmd.qp.db_addr : |
|---|
| 1040 | | - ucmd.wq.db_addr, &qp->db); |
|---|
| 1086 | + err = mlx4_ib_db_map_user(udata, ucmd.db_addr, &qp->db); |
|---|
| 1041 | 1087 | if (err) |
|---|
| 1042 | 1088 | goto err_mtt; |
|---|
| 1043 | 1089 | } |
|---|
| 1044 | 1090 | qp->mqp.usage = MLX4_RES_USAGE_USER_VERBS; |
|---|
| 1045 | 1091 | } else { |
|---|
| 1046 | | - err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, |
|---|
| 1092 | + err = set_rq_size(dev, &init_attr->cap, udata, |
|---|
| 1047 | 1093 | qp_has_rq(init_attr), qp, 0); |
|---|
| 1048 | 1094 | if (err) |
|---|
| 1049 | 1095 | goto err; |
|---|
| .. | .. |
|---|
| 1109 | 1155 | goto err_wrid; |
|---|
| 1110 | 1156 | } |
|---|
| 1111 | 1157 | } |
|---|
| 1112 | | - } else if (src == MLX4_IB_RWQ_SRC) { |
|---|
| 1113 | | - err = mlx4_ib_alloc_wqn(to_mucontext(pd->uobject->context), qp, |
|---|
| 1114 | | - range_size, &qpn); |
|---|
| 1115 | | - if (err) |
|---|
| 1116 | | - goto err_wrid; |
|---|
| 1117 | 1158 | } else { |
|---|
| 1118 | 1159 | /* Raw packet QPNs may not have bits 6,7 set in their qp_num; |
|---|
| 1119 | 1160 | * otherwise, the WQE BlueFlame setup flow wrongly causes |
|---|
| .. | .. |
|---|
| 1152 | 1193 | */ |
|---|
| 1153 | 1194 | qp->doorbell_qpn = swab32(qp->mqp.qpn << 8); |
|---|
| 1154 | 1195 | |
|---|
| 1155 | | - qp->mqp.event = (src == MLX4_IB_QP_SRC) ? mlx4_ib_qp_event : |
|---|
| 1156 | | - mlx4_ib_wq_event; |
|---|
| 1157 | | - |
|---|
| 1158 | | - if (!*caller_qp) |
|---|
| 1159 | | - *caller_qp = qp; |
|---|
| 1196 | + qp->mqp.event = mlx4_ib_qp_event; |
|---|
| 1160 | 1197 | |
|---|
| 1161 | 1198 | spin_lock_irqsave(&dev->reset_flow_resource_lock, flags); |
|---|
| 1162 | 1199 | mlx4_ib_lock_cqs(to_mcq(init_attr->send_cq), |
|---|
| .. | .. |
|---|
| 1181 | 1218 | if (!sqpn) { |
|---|
| 1182 | 1219 | if (qp->flags & MLX4_IB_QP_NETIF) |
|---|
| 1183 | 1220 | mlx4_ib_steer_qp_free(dev, qpn, 1); |
|---|
| 1184 | | - else if (src == MLX4_IB_RWQ_SRC) |
|---|
| 1185 | | - mlx4_ib_release_wqn(to_mucontext(pd->uobject->context), |
|---|
| 1186 | | - qp, 0); |
|---|
| 1187 | 1221 | else |
|---|
| 1188 | 1222 | mlx4_qp_release_range(dev->dev, qpn, 1); |
|---|
| 1189 | 1223 | } |
|---|
| .. | .. |
|---|
| 1191 | 1225 | if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI) |
|---|
| 1192 | 1226 | free_proxy_bufs(pd->device, qp); |
|---|
| 1193 | 1227 | err_wrid: |
|---|
| 1194 | | - if (pd->uobject) { |
|---|
| 1228 | + if (udata) { |
|---|
| 1195 | 1229 | if (qp_has_rq(init_attr)) |
|---|
| 1196 | | - mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); |
|---|
| 1230 | + mlx4_ib_db_unmap_user(context, &qp->db); |
|---|
| 1197 | 1231 | } else { |
|---|
| 1198 | 1232 | kvfree(qp->sq.wrid); |
|---|
| 1199 | 1233 | kvfree(qp->rq.wrid); |
|---|
| .. | .. |
|---|
| 1203 | 1237 | mlx4_mtt_cleanup(dev->dev, &qp->mtt); |
|---|
| 1204 | 1238 | |
|---|
| 1205 | 1239 | err_buf: |
|---|
| 1206 | | - if (pd->uobject) |
|---|
| 1207 | | - ib_umem_release(qp->umem); |
|---|
| 1208 | | - else |
|---|
| 1240 | + if (!qp->umem) |
|---|
| 1209 | 1241 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); |
|---|
| 1242 | + ib_umem_release(qp->umem); |
|---|
| 1210 | 1243 | |
|---|
| 1211 | 1244 | err_db: |
|---|
| 1212 | | - if (!pd->uobject && qp_has_rq(init_attr)) |
|---|
| 1245 | + if (!udata && qp_has_rq(init_attr)) |
|---|
| 1213 | 1246 | mlx4_db_free(dev->dev, &qp->db); |
|---|
| 1214 | 1247 | |
|---|
| 1215 | 1248 | err: |
|---|
| 1216 | | - if (sqp) |
|---|
| 1217 | | - kfree(sqp); |
|---|
| 1218 | | - else if (!*caller_qp) |
|---|
| 1219 | | - kfree(qp); |
|---|
| 1249 | + kfree(qp->sqp); |
|---|
| 1220 | 1250 | return err; |
|---|
| 1221 | 1251 | } |
|---|
| 1222 | 1252 | |
|---|
| .. | .. |
|---|
| 1330 | 1360 | mlx4_qp_free(dev->dev, &qp->mqp); |
|---|
| 1331 | 1361 | mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1); |
|---|
| 1332 | 1362 | del_gid_entries(qp); |
|---|
| 1333 | | - kfree(qp->rss_ctx); |
|---|
| 1334 | 1363 | } |
|---|
| 1335 | 1364 | |
|---|
| 1336 | 1365 | static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, |
|---|
| 1337 | | - enum mlx4_ib_source_type src, int is_user) |
|---|
| 1366 | + enum mlx4_ib_source_type src, |
|---|
| 1367 | + struct ib_udata *udata) |
|---|
| 1338 | 1368 | { |
|---|
| 1339 | 1369 | struct mlx4_ib_cq *send_cq, *recv_cq; |
|---|
| 1340 | 1370 | unsigned long flags; |
|---|
| .. | .. |
|---|
| 1376 | 1406 | list_del(&qp->qps_list); |
|---|
| 1377 | 1407 | list_del(&qp->cq_send_list); |
|---|
| 1378 | 1408 | list_del(&qp->cq_recv_list); |
|---|
| 1379 | | - if (!is_user) { |
|---|
| 1409 | + if (!udata) { |
|---|
| 1380 | 1410 | __mlx4_ib_cq_clean(recv_cq, qp->mqp.qpn, |
|---|
| 1381 | 1411 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq): NULL); |
|---|
| 1382 | 1412 | if (send_cq != recv_cq) |
|---|
| .. | .. |
|---|
| 1394 | 1424 | if (qp->flags & MLX4_IB_QP_NETIF) |
|---|
| 1395 | 1425 | mlx4_ib_steer_qp_free(dev, qp->mqp.qpn, 1); |
|---|
| 1396 | 1426 | else if (src == MLX4_IB_RWQ_SRC) |
|---|
| 1397 | | - mlx4_ib_release_wqn(to_mucontext( |
|---|
| 1398 | | - qp->ibwq.uobject->context), qp, 1); |
|---|
| 1427 | + mlx4_ib_release_wqn( |
|---|
| 1428 | + rdma_udata_to_drv_context( |
|---|
| 1429 | + udata, |
|---|
| 1430 | + struct mlx4_ib_ucontext, |
|---|
| 1431 | + ibucontext), |
|---|
| 1432 | + qp, 1); |
|---|
| 1399 | 1433 | else |
|---|
| 1400 | 1434 | mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1); |
|---|
| 1401 | 1435 | } |
|---|
| 1402 | 1436 | |
|---|
| 1403 | 1437 | mlx4_mtt_cleanup(dev->dev, &qp->mtt); |
|---|
| 1404 | 1438 | |
|---|
| 1405 | | - if (is_user) { |
|---|
| 1439 | + if (udata) { |
|---|
| 1406 | 1440 | if (qp->rq.wqe_cnt) { |
|---|
| 1407 | | - struct mlx4_ib_ucontext *mcontext = !src ? |
|---|
| 1408 | | - to_mucontext(qp->ibqp.uobject->context) : |
|---|
| 1409 | | - to_mucontext(qp->ibwq.uobject->context); |
|---|
| 1441 | + struct mlx4_ib_ucontext *mcontext = |
|---|
| 1442 | + rdma_udata_to_drv_context( |
|---|
| 1443 | + udata, |
|---|
| 1444 | + struct mlx4_ib_ucontext, |
|---|
| 1445 | + ibucontext); |
|---|
| 1446 | + |
|---|
| 1410 | 1447 | mlx4_ib_db_unmap_user(mcontext, &qp->db); |
|---|
| 1411 | 1448 | } |
|---|
| 1412 | | - ib_umem_release(qp->umem); |
|---|
| 1413 | 1449 | } else { |
|---|
| 1414 | 1450 | kvfree(qp->sq.wrid); |
|---|
| 1415 | 1451 | kvfree(qp->rq.wrid); |
|---|
| .. | .. |
|---|
| 1420 | 1456 | if (qp->rq.wqe_cnt) |
|---|
| 1421 | 1457 | mlx4_db_free(dev->dev, &qp->db); |
|---|
| 1422 | 1458 | } |
|---|
| 1459 | + ib_umem_release(qp->umem); |
|---|
| 1423 | 1460 | |
|---|
| 1424 | 1461 | del_gid_entries(qp); |
|---|
| 1425 | 1462 | } |
|---|
| .. | .. |
|---|
| 1441 | 1478 | return dev->dev->caps.spec_qps[attr->port_num - 1].qp1_proxy; |
|---|
| 1442 | 1479 | } |
|---|
| 1443 | 1480 | |
|---|
| 1444 | | -static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd, |
|---|
| 1445 | | - struct ib_qp_init_attr *init_attr, |
|---|
| 1446 | | - struct ib_udata *udata) |
|---|
| 1481 | +static int _mlx4_ib_create_qp(struct ib_pd *pd, struct mlx4_ib_qp *qp, |
|---|
| 1482 | + struct ib_qp_init_attr *init_attr, |
|---|
| 1483 | + struct ib_udata *udata) |
|---|
| 1447 | 1484 | { |
|---|
| 1448 | | - struct mlx4_ib_qp *qp = NULL; |
|---|
| 1449 | 1485 | int err; |
|---|
| 1450 | 1486 | int sup_u_create_flags = MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK; |
|---|
| 1451 | 1487 | u16 xrcdn = 0; |
|---|
| 1452 | 1488 | |
|---|
| 1453 | 1489 | if (init_attr->rwq_ind_tbl) |
|---|
| 1454 | | - return _mlx4_ib_create_qp_rss(pd, init_attr, udata); |
|---|
| 1490 | + return _mlx4_ib_create_qp_rss(pd, qp, init_attr, udata); |
|---|
| 1455 | 1491 | |
|---|
| 1456 | 1492 | /* |
|---|
| 1457 | 1493 | * We only support LSO, vendor flag1, and multicast loopback blocking, |
|---|
| .. | .. |
|---|
| 1463 | 1499 | MLX4_IB_SRIOV_SQP | |
|---|
| 1464 | 1500 | MLX4_IB_QP_NETIF | |
|---|
| 1465 | 1501 | MLX4_IB_QP_CREATE_ROCE_V2_GSI)) |
|---|
| 1466 | | - return ERR_PTR(-EINVAL); |
|---|
| 1502 | + return -EINVAL; |
|---|
| 1467 | 1503 | |
|---|
| 1468 | 1504 | if (init_attr->create_flags & IB_QP_CREATE_NETIF_QP) { |
|---|
| 1469 | 1505 | if (init_attr->qp_type != IB_QPT_UD) |
|---|
| 1470 | | - return ERR_PTR(-EINVAL); |
|---|
| 1506 | + return -EINVAL; |
|---|
| 1471 | 1507 | } |
|---|
| 1472 | 1508 | |
|---|
| 1473 | 1509 | if (init_attr->create_flags) { |
|---|
| 1474 | 1510 | if (udata && init_attr->create_flags & ~(sup_u_create_flags)) |
|---|
| 1475 | | - return ERR_PTR(-EINVAL); |
|---|
| 1511 | + return -EINVAL; |
|---|
| 1476 | 1512 | |
|---|
| 1477 | 1513 | if ((init_attr->create_flags & ~(MLX4_IB_SRIOV_SQP | |
|---|
| 1478 | 1514 | MLX4_IB_QP_CREATE_ROCE_V2_GSI | |
|---|
| .. | .. |
|---|
| 1482 | 1518 | init_attr->qp_type > IB_QPT_GSI) || |
|---|
| 1483 | 1519 | (init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI && |
|---|
| 1484 | 1520 | init_attr->qp_type != IB_QPT_GSI)) |
|---|
| 1485 | | - return ERR_PTR(-EINVAL); |
|---|
| 1521 | + return -EINVAL; |
|---|
| 1486 | 1522 | } |
|---|
| 1487 | 1523 | |
|---|
| 1488 | 1524 | switch (init_attr->qp_type) { |
|---|
| .. | .. |
|---|
| 1490 | 1526 | pd = to_mxrcd(init_attr->xrcd)->pd; |
|---|
| 1491 | 1527 | xrcdn = to_mxrcd(init_attr->xrcd)->xrcdn; |
|---|
| 1492 | 1528 | init_attr->send_cq = to_mxrcd(init_attr->xrcd)->cq; |
|---|
| 1493 | | - /* fall through */ |
|---|
| 1529 | + fallthrough; |
|---|
| 1494 | 1530 | case IB_QPT_XRC_INI: |
|---|
| 1495 | 1531 | if (!(to_mdev(pd->device)->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC)) |
|---|
| 1496 | | - return ERR_PTR(-ENOSYS); |
|---|
| 1532 | + return -ENOSYS; |
|---|
| 1497 | 1533 | init_attr->recv_cq = init_attr->send_cq; |
|---|
| 1498 | | - /* fall through */ |
|---|
| 1534 | + fallthrough; |
|---|
| 1499 | 1535 | case IB_QPT_RC: |
|---|
| 1500 | 1536 | case IB_QPT_UC: |
|---|
| 1501 | 1537 | case IB_QPT_RAW_PACKET: |
|---|
| 1502 | | - qp = kzalloc(sizeof(*qp), GFP_KERNEL); |
|---|
| 1503 | | - if (!qp) |
|---|
| 1504 | | - return ERR_PTR(-ENOMEM); |
|---|
| 1538 | + case IB_QPT_UD: |
|---|
| 1505 | 1539 | qp->pri.vid = 0xFFFF; |
|---|
| 1506 | 1540 | qp->alt.vid = 0xFFFF; |
|---|
| 1507 | | - /* fall through */ |
|---|
| 1508 | | - case IB_QPT_UD: |
|---|
| 1509 | | - { |
|---|
| 1510 | | - err = create_qp_common(to_mdev(pd->device), pd, MLX4_IB_QP_SRC, |
|---|
| 1511 | | - init_attr, udata, 0, &qp); |
|---|
| 1512 | | - if (err) { |
|---|
| 1513 | | - kfree(qp); |
|---|
| 1514 | | - return ERR_PTR(err); |
|---|
| 1515 | | - } |
|---|
| 1541 | + err = create_qp_common(pd, init_attr, udata, 0, qp); |
|---|
| 1542 | + if (err) |
|---|
| 1543 | + return err; |
|---|
| 1516 | 1544 | |
|---|
| 1517 | 1545 | qp->ibqp.qp_num = qp->mqp.qpn; |
|---|
| 1518 | 1546 | qp->xrcdn = xrcdn; |
|---|
| 1519 | | - |
|---|
| 1520 | 1547 | break; |
|---|
| 1521 | | - } |
|---|
| 1522 | 1548 | case IB_QPT_SMI: |
|---|
| 1523 | 1549 | case IB_QPT_GSI: |
|---|
| 1524 | 1550 | { |
|---|
| 1525 | 1551 | int sqpn; |
|---|
| 1526 | 1552 | |
|---|
| 1527 | | - /* Userspace is not allowed to create special QPs: */ |
|---|
| 1528 | | - if (udata) |
|---|
| 1529 | | - return ERR_PTR(-EINVAL); |
|---|
| 1530 | 1553 | if (init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI) { |
|---|
| 1531 | 1554 | int res = mlx4_qp_reserve_range(to_mdev(pd->device)->dev, |
|---|
| 1532 | 1555 | 1, 1, &sqpn, 0, |
|---|
| 1533 | 1556 | MLX4_RES_USAGE_DRIVER); |
|---|
| 1534 | 1557 | |
|---|
| 1535 | 1558 | if (res) |
|---|
| 1536 | | - return ERR_PTR(res); |
|---|
| 1559 | + return res; |
|---|
| 1537 | 1560 | } else { |
|---|
| 1538 | 1561 | sqpn = get_sqp_num(to_mdev(pd->device), init_attr); |
|---|
| 1539 | 1562 | } |
|---|
| 1540 | 1563 | |
|---|
| 1541 | | - err = create_qp_common(to_mdev(pd->device), pd, MLX4_IB_QP_SRC, |
|---|
| 1542 | | - init_attr, udata, sqpn, &qp); |
|---|
| 1564 | + qp->pri.vid = 0xFFFF; |
|---|
| 1565 | + qp->alt.vid = 0xFFFF; |
|---|
| 1566 | + err = create_qp_common(pd, init_attr, udata, sqpn, qp); |
|---|
| 1543 | 1567 | if (err) |
|---|
| 1544 | | - return ERR_PTR(err); |
|---|
| 1568 | + return err; |
|---|
| 1545 | 1569 | |
|---|
| 1546 | 1570 | qp->port = init_attr->port_num; |
|---|
| 1547 | 1571 | qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : |
|---|
| .. | .. |
|---|
| 1550 | 1574 | } |
|---|
| 1551 | 1575 | default: |
|---|
| 1552 | 1576 | /* Don't support raw QPs */ |
|---|
| 1553 | | - return ERR_PTR(-EINVAL); |
|---|
| 1577 | + return -EOPNOTSUPP; |
|---|
| 1554 | 1578 | } |
|---|
| 1555 | | - |
|---|
| 1556 | | - return &qp->ibqp; |
|---|
| 1579 | + return 0; |
|---|
| 1557 | 1580 | } |
|---|
| 1558 | 1581 | |
|---|
| 1559 | 1582 | struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, |
|---|
| 1560 | 1583 | struct ib_qp_init_attr *init_attr, |
|---|
| 1561 | 1584 | struct ib_udata *udata) { |
|---|
| 1562 | 1585 | struct ib_device *device = pd ? pd->device : init_attr->xrcd->device; |
|---|
| 1563 | | - struct ib_qp *ibqp; |
|---|
| 1564 | 1586 | struct mlx4_ib_dev *dev = to_mdev(device); |
|---|
| 1587 | + struct mlx4_ib_qp *qp; |
|---|
| 1588 | + int ret; |
|---|
| 1565 | 1589 | |
|---|
| 1566 | | - ibqp = _mlx4_ib_create_qp(pd, init_attr, udata); |
|---|
| 1590 | + qp = kzalloc(sizeof(*qp), GFP_KERNEL); |
|---|
| 1591 | + if (!qp) |
|---|
| 1592 | + return ERR_PTR(-ENOMEM); |
|---|
| 1567 | 1593 | |
|---|
| 1568 | | - if (!IS_ERR(ibqp) && |
|---|
| 1569 | | - (init_attr->qp_type == IB_QPT_GSI) && |
|---|
| 1594 | + mutex_init(&qp->mutex); |
|---|
| 1595 | + ret = _mlx4_ib_create_qp(pd, qp, init_attr, udata); |
|---|
| 1596 | + if (ret) { |
|---|
| 1597 | + kfree(qp); |
|---|
| 1598 | + return ERR_PTR(ret); |
|---|
| 1599 | + } |
|---|
| 1600 | + |
|---|
| 1601 | + if (init_attr->qp_type == IB_QPT_GSI && |
|---|
| 1570 | 1602 | !(init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI)) { |
|---|
| 1571 | | - struct mlx4_ib_sqp *sqp = to_msqp((to_mqp(ibqp))); |
|---|
| 1603 | + struct mlx4_ib_sqp *sqp = qp->sqp; |
|---|
| 1572 | 1604 | int is_eth = rdma_cap_eth_ah(&dev->ib_dev, init_attr->port_num); |
|---|
| 1573 | 1605 | |
|---|
| 1574 | 1606 | if (is_eth && |
|---|
| .. | .. |
|---|
| 1580 | 1612 | pr_err("Failed to create GSI QP for RoCEv2 (%ld)\n", PTR_ERR(sqp->roce_v2_gsi)); |
|---|
| 1581 | 1613 | sqp->roce_v2_gsi = NULL; |
|---|
| 1582 | 1614 | } else { |
|---|
| 1583 | | - sqp = to_msqp(to_mqp(sqp->roce_v2_gsi)); |
|---|
| 1584 | | - sqp->qp.flags |= MLX4_IB_ROCE_V2_GSI_QP; |
|---|
| 1615 | + to_mqp(sqp->roce_v2_gsi)->flags |= |
|---|
| 1616 | + MLX4_IB_ROCE_V2_GSI_QP; |
|---|
| 1585 | 1617 | } |
|---|
| 1586 | 1618 | |
|---|
| 1587 | 1619 | init_attr->create_flags &= ~MLX4_IB_QP_CREATE_ROCE_V2_GSI; |
|---|
| 1588 | 1620 | } |
|---|
| 1589 | 1621 | } |
|---|
| 1590 | | - return ibqp; |
|---|
| 1622 | + return &qp->ibqp; |
|---|
| 1591 | 1623 | } |
|---|
| 1592 | 1624 | |
|---|
| 1593 | | -static int _mlx4_ib_destroy_qp(struct ib_qp *qp) |
|---|
| 1625 | +static int _mlx4_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) |
|---|
| 1594 | 1626 | { |
|---|
| 1595 | 1627 | struct mlx4_ib_dev *dev = to_mdev(qp->device); |
|---|
| 1596 | 1628 | struct mlx4_ib_qp *mqp = to_mqp(qp); |
|---|
| .. | .. |
|---|
| 1611 | 1643 | if (qp->rwq_ind_tbl) { |
|---|
| 1612 | 1644 | destroy_qp_rss(dev, mqp); |
|---|
| 1613 | 1645 | } else { |
|---|
| 1614 | | - struct mlx4_ib_pd *pd; |
|---|
| 1615 | | - |
|---|
| 1616 | | - pd = get_pd(mqp); |
|---|
| 1617 | | - destroy_qp_common(dev, mqp, MLX4_IB_QP_SRC, !!pd->ibpd.uobject); |
|---|
| 1646 | + destroy_qp_common(dev, mqp, MLX4_IB_QP_SRC, udata); |
|---|
| 1618 | 1647 | } |
|---|
| 1619 | 1648 | |
|---|
| 1620 | | - if (is_sqp(dev, mqp)) |
|---|
| 1621 | | - kfree(to_msqp(mqp)); |
|---|
| 1622 | | - else |
|---|
| 1623 | | - kfree(mqp); |
|---|
| 1649 | + kfree(mqp->sqp); |
|---|
| 1650 | + kfree(mqp); |
|---|
| 1624 | 1651 | |
|---|
| 1625 | 1652 | return 0; |
|---|
| 1626 | 1653 | } |
|---|
| 1627 | 1654 | |
|---|
| 1628 | | -int mlx4_ib_destroy_qp(struct ib_qp *qp) |
|---|
| 1655 | +int mlx4_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) |
|---|
| 1629 | 1656 | { |
|---|
| 1630 | 1657 | struct mlx4_ib_qp *mqp = to_mqp(qp); |
|---|
| 1631 | 1658 | |
|---|
| 1632 | 1659 | if (mqp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) { |
|---|
| 1633 | | - struct mlx4_ib_sqp *sqp = to_msqp(mqp); |
|---|
| 1660 | + struct mlx4_ib_sqp *sqp = mqp->sqp; |
|---|
| 1634 | 1661 | |
|---|
| 1635 | 1662 | if (sqp->roce_v2_gsi) |
|---|
| 1636 | 1663 | ib_destroy_qp(sqp->roce_v2_gsi); |
|---|
| 1637 | 1664 | } |
|---|
| 1638 | 1665 | |
|---|
| 1639 | | - return _mlx4_ib_destroy_qp(qp); |
|---|
| 1666 | + return _mlx4_ib_destroy_qp(qp, udata); |
|---|
| 1640 | 1667 | } |
|---|
| 1641 | 1668 | |
|---|
| 1642 | 1669 | static int to_mlx4_st(struct mlx4_ib_dev *dev, enum mlx4_ib_qp_type type) |
|---|
| .. | .. |
|---|
| 1943 | 1970 | * Go over all RSS QP's childes (WQs) and apply their HW state according to |
|---|
| 1944 | 1971 | * their logic state if the RSS QP is the first RSS QP associated for the WQ. |
|---|
| 1945 | 1972 | */ |
|---|
| 1946 | | -static int bringup_rss_rwqs(struct ib_rwq_ind_table *ind_tbl, u8 port_num) |
|---|
| 1973 | +static int bringup_rss_rwqs(struct ib_rwq_ind_table *ind_tbl, u8 port_num, |
|---|
| 1974 | + struct ib_udata *udata) |
|---|
| 1947 | 1975 | { |
|---|
| 1948 | 1976 | int err = 0; |
|---|
| 1949 | 1977 | int i; |
|---|
| .. | .. |
|---|
| 1967 | 1995 | } |
|---|
| 1968 | 1996 | wq->port = port_num; |
|---|
| 1969 | 1997 | if ((wq->rss_usecnt == 0) && (ibwq->state == IB_WQS_RDY)) { |
|---|
| 1970 | | - err = _mlx4_ib_modify_wq(ibwq, IB_WQS_RDY); |
|---|
| 1998 | + err = _mlx4_ib_modify_wq(ibwq, IB_WQS_RDY, udata); |
|---|
| 1971 | 1999 | if (err) { |
|---|
| 1972 | 2000 | mutex_unlock(&wq->mutex); |
|---|
| 1973 | 2001 | break; |
|---|
| .. | .. |
|---|
| 1989 | 2017 | |
|---|
| 1990 | 2018 | if ((wq->rss_usecnt == 1) && |
|---|
| 1991 | 2019 | (ibwq->state == IB_WQS_RDY)) |
|---|
| 1992 | | - if (_mlx4_ib_modify_wq(ibwq, IB_WQS_RESET)) |
|---|
| 2020 | + if (_mlx4_ib_modify_wq(ibwq, IB_WQS_RESET, |
|---|
| 2021 | + udata)) |
|---|
| 1993 | 2022 | pr_warn("failed to reverse WQN=0x%06x\n", |
|---|
| 1994 | 2023 | ibwq->wq_num); |
|---|
| 1995 | 2024 | wq->rss_usecnt--; |
|---|
| .. | .. |
|---|
| 2001 | 2030 | return err; |
|---|
| 2002 | 2031 | } |
|---|
| 2003 | 2032 | |
|---|
| 2004 | | -static void bring_down_rss_rwqs(struct ib_rwq_ind_table *ind_tbl) |
|---|
| 2033 | +static void bring_down_rss_rwqs(struct ib_rwq_ind_table *ind_tbl, |
|---|
| 2034 | + struct ib_udata *udata) |
|---|
| 2005 | 2035 | { |
|---|
| 2006 | 2036 | int i; |
|---|
| 2007 | 2037 | |
|---|
| .. | .. |
|---|
| 2012 | 2042 | mutex_lock(&wq->mutex); |
|---|
| 2013 | 2043 | |
|---|
| 2014 | 2044 | if ((wq->rss_usecnt == 1) && (ibwq->state == IB_WQS_RDY)) |
|---|
| 2015 | | - if (_mlx4_ib_modify_wq(ibwq, IB_WQS_RESET)) |
|---|
| 2045 | + if (_mlx4_ib_modify_wq(ibwq, IB_WQS_RESET, udata)) |
|---|
| 2016 | 2046 | pr_warn("failed to reverse WQN=%x\n", |
|---|
| 2017 | 2047 | ibwq->wq_num); |
|---|
| 2018 | 2048 | wq->rss_usecnt--; |
|---|
| .. | .. |
|---|
| 2044 | 2074 | |
|---|
| 2045 | 2075 | static int __mlx4_ib_modify_qp(void *src, enum mlx4_ib_source_type src_type, |
|---|
| 2046 | 2076 | const struct ib_qp_attr *attr, int attr_mask, |
|---|
| 2047 | | - enum ib_qp_state cur_state, enum ib_qp_state new_state) |
|---|
| 2077 | + enum ib_qp_state cur_state, |
|---|
| 2078 | + enum ib_qp_state new_state, |
|---|
| 2079 | + struct ib_udata *udata) |
|---|
| 2048 | 2080 | { |
|---|
| 2049 | | - struct ib_uobject *ibuobject; |
|---|
| 2050 | 2081 | struct ib_srq *ibsrq; |
|---|
| 2051 | 2082 | const struct ib_gid_attr *gid_attr = NULL; |
|---|
| 2052 | 2083 | struct ib_rwq_ind_table *rwq_ind_tbl; |
|---|
| .. | .. |
|---|
| 2055 | 2086 | struct mlx4_ib_qp *qp; |
|---|
| 2056 | 2087 | struct mlx4_ib_pd *pd; |
|---|
| 2057 | 2088 | struct mlx4_ib_cq *send_cq, *recv_cq; |
|---|
| 2089 | + struct mlx4_ib_ucontext *ucontext = rdma_udata_to_drv_context( |
|---|
| 2090 | + udata, struct mlx4_ib_ucontext, ibucontext); |
|---|
| 2058 | 2091 | struct mlx4_qp_context *context; |
|---|
| 2059 | 2092 | enum mlx4_qp_optpar optpar = 0; |
|---|
| 2060 | 2093 | int sqd_event; |
|---|
| .. | .. |
|---|
| 2066 | 2099 | struct ib_wq *ibwq; |
|---|
| 2067 | 2100 | |
|---|
| 2068 | 2101 | ibwq = (struct ib_wq *)src; |
|---|
| 2069 | | - ibuobject = ibwq->uobject; |
|---|
| 2070 | 2102 | ibsrq = NULL; |
|---|
| 2071 | 2103 | rwq_ind_tbl = NULL; |
|---|
| 2072 | 2104 | qp_type = IB_QPT_RAW_PACKET; |
|---|
| .. | .. |
|---|
| 2077 | 2109 | struct ib_qp *ibqp; |
|---|
| 2078 | 2110 | |
|---|
| 2079 | 2111 | ibqp = (struct ib_qp *)src; |
|---|
| 2080 | | - ibuobject = ibqp->uobject; |
|---|
| 2081 | 2112 | ibsrq = ibqp->srq; |
|---|
| 2082 | 2113 | rwq_ind_tbl = ibqp->rwq_ind_tbl; |
|---|
| 2083 | 2114 | qp_type = ibqp->qp_type; |
|---|
| .. | .. |
|---|
| 2162 | 2193 | context->param3 |= cpu_to_be32(1 << 30); |
|---|
| 2163 | 2194 | } |
|---|
| 2164 | 2195 | |
|---|
| 2165 | | - if (ibuobject) |
|---|
| 2196 | + if (ucontext) |
|---|
| 2166 | 2197 | context->usr_page = cpu_to_be32( |
|---|
| 2167 | | - mlx4_to_hw_uar_index(dev->dev, |
|---|
| 2168 | | - to_mucontext(ibuobject->context) |
|---|
| 2169 | | - ->uar.index)); |
|---|
| 2198 | + mlx4_to_hw_uar_index(dev->dev, ucontext->uar.index)); |
|---|
| 2170 | 2199 | else |
|---|
| 2171 | 2200 | context->usr_page = cpu_to_be32( |
|---|
| 2172 | 2201 | mlx4_to_hw_uar_index(dev->dev, dev->priv_uar.index)); |
|---|
| .. | .. |
|---|
| 2237 | 2266 | |
|---|
| 2238 | 2267 | if (is_eth) { |
|---|
| 2239 | 2268 | gid_attr = attr->ah_attr.grh.sgid_attr; |
|---|
| 2240 | | - vlan = rdma_vlan_dev_vlan_id(gid_attr->ndev); |
|---|
| 2241 | | - memcpy(smac, gid_attr->ndev->dev_addr, ETH_ALEN); |
|---|
| 2269 | + err = rdma_read_gid_l2_fields(gid_attr, &vlan, |
|---|
| 2270 | + &smac[0]); |
|---|
| 2271 | + if (err) |
|---|
| 2272 | + goto out; |
|---|
| 2242 | 2273 | } |
|---|
| 2243 | 2274 | |
|---|
| 2244 | 2275 | if (mlx4_set_path(dev, attr, attr_mask, qp, &context->pri_path, |
|---|
| .. | .. |
|---|
| 2298 | 2329 | context->cqn_recv = cpu_to_be32(recv_cq->mcq.cqn); |
|---|
| 2299 | 2330 | |
|---|
| 2300 | 2331 | /* Set "fast registration enabled" for all kernel QPs */ |
|---|
| 2301 | | - if (!ibuobject) |
|---|
| 2332 | + if (!ucontext) |
|---|
| 2302 | 2333 | context->params1 |= cpu_to_be32(1 << 11); |
|---|
| 2303 | 2334 | |
|---|
| 2304 | 2335 | if (attr_mask & IB_QP_RNR_RETRY) { |
|---|
| .. | .. |
|---|
| 2435 | 2466 | else |
|---|
| 2436 | 2467 | sqd_event = 0; |
|---|
| 2437 | 2468 | |
|---|
| 2438 | | - if (!ibuobject && |
|---|
| 2469 | + if (!ucontext && |
|---|
| 2439 | 2470 | cur_state == IB_QPS_RESET && |
|---|
| 2440 | 2471 | new_state == IB_QPS_INIT) |
|---|
| 2441 | 2472 | context->rlkey_roce_mode |= (1 << 4); |
|---|
| .. | .. |
|---|
| 2446 | 2477 | * headroom is stamped so that the hardware doesn't start |
|---|
| 2447 | 2478 | * processing stale work requests. |
|---|
| 2448 | 2479 | */ |
|---|
| 2449 | | - if (!ibuobject && |
|---|
| 2480 | + if (!ucontext && |
|---|
| 2450 | 2481 | cur_state == IB_QPS_RESET && |
|---|
| 2451 | 2482 | new_state == IB_QPS_INIT) { |
|---|
| 2452 | 2483 | struct mlx4_wqe_ctrl_seg *ctrl; |
|---|
| .. | .. |
|---|
| 2488 | 2519 | qp->alt_port = attr->alt_port_num; |
|---|
| 2489 | 2520 | |
|---|
| 2490 | 2521 | if (is_sqp(dev, qp)) |
|---|
| 2491 | | - store_sqp_attrs(to_msqp(qp), attr, attr_mask); |
|---|
| 2522 | + store_sqp_attrs(qp->sqp, attr, attr_mask); |
|---|
| 2492 | 2523 | |
|---|
| 2493 | 2524 | /* |
|---|
| 2494 | 2525 | * If we moved QP0 to RTR, bring the IB link up; if we moved |
|---|
| .. | .. |
|---|
| 2510 | 2541 | * entries and reinitialize the QP. |
|---|
| 2511 | 2542 | */ |
|---|
| 2512 | 2543 | if (new_state == IB_QPS_RESET) { |
|---|
| 2513 | | - if (!ibuobject) { |
|---|
| 2544 | + if (!ucontext) { |
|---|
| 2514 | 2545 | mlx4_ib_cq_clean(recv_cq, qp->mqp.qpn, |
|---|
| 2515 | 2546 | ibsrq ? to_msrq(ibsrq) : NULL); |
|---|
| 2516 | 2547 | if (send_cq != recv_cq) |
|---|
| .. | .. |
|---|
| 2631 | 2662 | static int _mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, |
|---|
| 2632 | 2663 | int attr_mask, struct ib_udata *udata) |
|---|
| 2633 | 2664 | { |
|---|
| 2634 | | - enum rdma_link_layer ll = IB_LINK_LAYER_UNSPECIFIED; |
|---|
| 2635 | 2665 | struct mlx4_ib_dev *dev = to_mdev(ibqp->device); |
|---|
| 2636 | 2666 | struct mlx4_ib_qp *qp = to_mqp(ibqp); |
|---|
| 2637 | 2667 | enum ib_qp_state cur_state, new_state; |
|---|
| .. | .. |
|---|
| 2641 | 2671 | cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state; |
|---|
| 2642 | 2672 | new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; |
|---|
| 2643 | 2673 | |
|---|
| 2644 | | - if (cur_state != new_state || cur_state != IB_QPS_RESET) { |
|---|
| 2645 | | - int port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port; |
|---|
| 2646 | | - ll = rdma_port_get_link_layer(&dev->ib_dev, port); |
|---|
| 2647 | | - } |
|---|
| 2648 | | - |
|---|
| 2649 | 2674 | if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, |
|---|
| 2650 | | - attr_mask, ll)) { |
|---|
| 2675 | + attr_mask)) { |
|---|
| 2651 | 2676 | pr_debug("qpn 0x%x: invalid attribute mask specified " |
|---|
| 2652 | 2677 | "for transition %d to %d. qp_type %d," |
|---|
| 2653 | 2678 | " attr_mask 0x%x\n", |
|---|
| .. | .. |
|---|
| 2742 | 2767 | } |
|---|
| 2743 | 2768 | |
|---|
| 2744 | 2769 | if (ibqp->rwq_ind_tbl && (new_state == IB_QPS_INIT)) { |
|---|
| 2745 | | - err = bringup_rss_rwqs(ibqp->rwq_ind_tbl, attr->port_num); |
|---|
| 2770 | + err = bringup_rss_rwqs(ibqp->rwq_ind_tbl, attr->port_num, |
|---|
| 2771 | + udata); |
|---|
| 2746 | 2772 | if (err) |
|---|
| 2747 | 2773 | goto out; |
|---|
| 2748 | 2774 | } |
|---|
| 2749 | 2775 | |
|---|
| 2750 | 2776 | err = __mlx4_ib_modify_qp(ibqp, MLX4_IB_QP_SRC, attr, attr_mask, |
|---|
| 2751 | | - cur_state, new_state); |
|---|
| 2777 | + cur_state, new_state, udata); |
|---|
| 2752 | 2778 | |
|---|
| 2753 | 2779 | if (ibqp->rwq_ind_tbl && err) |
|---|
| 2754 | | - bring_down_rss_rwqs(ibqp->rwq_ind_tbl); |
|---|
| 2780 | + bring_down_rss_rwqs(ibqp->rwq_ind_tbl, udata); |
|---|
| 2755 | 2781 | |
|---|
| 2756 | 2782 | if (mlx4_is_bonded(dev->dev) && (attr_mask & IB_QP_PORT)) |
|---|
| 2757 | 2783 | attr->port_num = 1; |
|---|
| .. | .. |
|---|
| 2770 | 2796 | ret = _mlx4_ib_modify_qp(ibqp, attr, attr_mask, udata); |
|---|
| 2771 | 2797 | |
|---|
| 2772 | 2798 | if (mqp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) { |
|---|
| 2773 | | - struct mlx4_ib_sqp *sqp = to_msqp(mqp); |
|---|
| 2799 | + struct mlx4_ib_sqp *sqp = mqp->sqp; |
|---|
| 2774 | 2800 | int err = 0; |
|---|
| 2775 | 2801 | |
|---|
| 2776 | 2802 | if (sqp->roce_v2_gsi) |
|---|
| .. | .. |
|---|
| 2795 | 2821 | return -EINVAL; |
|---|
| 2796 | 2822 | } |
|---|
| 2797 | 2823 | |
|---|
| 2798 | | -static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, |
|---|
| 2824 | +static int build_sriov_qp0_header(struct mlx4_ib_qp *qp, |
|---|
| 2799 | 2825 | const struct ib_ud_wr *wr, |
|---|
| 2800 | 2826 | void *wqe, unsigned *mlx_seg_len) |
|---|
| 2801 | 2827 | { |
|---|
| 2802 | | - struct mlx4_ib_dev *mdev = to_mdev(sqp->qp.ibqp.device); |
|---|
| 2803 | | - struct ib_device *ib_dev = &mdev->ib_dev; |
|---|
| 2828 | + struct mlx4_ib_dev *mdev = to_mdev(qp->ibqp.device); |
|---|
| 2829 | + struct mlx4_ib_sqp *sqp = qp->sqp; |
|---|
| 2830 | + struct ib_device *ib_dev = qp->ibqp.device; |
|---|
| 2804 | 2831 | struct mlx4_wqe_mlx_seg *mlx = wqe; |
|---|
| 2805 | 2832 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; |
|---|
| 2806 | 2833 | struct mlx4_ib_ah *ah = to_mah(wr->ah); |
|---|
| .. | .. |
|---|
| 2822 | 2849 | |
|---|
| 2823 | 2850 | /* for proxy-qp0 sends, need to add in size of tunnel header */ |
|---|
| 2824 | 2851 | /* for tunnel-qp0 sends, tunnel header is already in s/g list */ |
|---|
| 2825 | | - if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_SMI_OWNER) |
|---|
| 2852 | + if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_SMI_OWNER) |
|---|
| 2826 | 2853 | send_size += sizeof (struct mlx4_ib_tunnel_header); |
|---|
| 2827 | 2854 | |
|---|
| 2828 | 2855 | ib_ud_header_init(send_size, 1, 0, 0, 0, 0, 0, 0, &sqp->ud_header); |
|---|
| 2829 | 2856 | |
|---|
| 2830 | | - if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_SMI_OWNER) { |
|---|
| 2857 | + if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_SMI_OWNER) { |
|---|
| 2831 | 2858 | sqp->ud_header.lrh.service_level = |
|---|
| 2832 | 2859 | be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; |
|---|
| 2833 | 2860 | sqp->ud_header.lrh.destination_lid = |
|---|
| .. | .. |
|---|
| 2844 | 2871 | |
|---|
| 2845 | 2872 | sqp->ud_header.lrh.virtual_lane = 0; |
|---|
| 2846 | 2873 | sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); |
|---|
| 2847 | | - err = ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); |
|---|
| 2874 | + err = ib_get_cached_pkey(ib_dev, qp->port, 0, &pkey); |
|---|
| 2848 | 2875 | if (err) |
|---|
| 2849 | 2876 | return err; |
|---|
| 2850 | 2877 | sqp->ud_header.bth.pkey = cpu_to_be16(pkey); |
|---|
| 2851 | | - if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_TUN_SMI_OWNER) |
|---|
| 2878 | + if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_TUN_SMI_OWNER) |
|---|
| 2852 | 2879 | sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); |
|---|
| 2853 | 2880 | else |
|---|
| 2854 | 2881 | sqp->ud_header.bth.destination_qpn = |
|---|
| 2855 | | - cpu_to_be32(mdev->dev->caps.spec_qps[sqp->qp.port - 1].qp0_tunnel); |
|---|
| 2882 | + cpu_to_be32(mdev->dev->caps.spec_qps[qp->port - 1].qp0_tunnel); |
|---|
| 2856 | 2883 | |
|---|
| 2857 | 2884 | sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); |
|---|
| 2858 | 2885 | if (mlx4_is_master(mdev->dev)) { |
|---|
| 2859 | | - if (mlx4_get_parav_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey)) |
|---|
| 2886 | + if (mlx4_get_parav_qkey(mdev->dev, qp->mqp.qpn, &qkey)) |
|---|
| 2860 | 2887 | return -EINVAL; |
|---|
| 2861 | 2888 | } else { |
|---|
| 2862 | | - if (vf_get_qp0_qkey(mdev->dev, sqp->qp.mqp.qpn, &qkey)) |
|---|
| 2889 | + if (vf_get_qp0_qkey(mdev->dev, qp->mqp.qpn, &qkey)) |
|---|
| 2863 | 2890 | return -EINVAL; |
|---|
| 2864 | 2891 | } |
|---|
| 2865 | 2892 | sqp->ud_header.deth.qkey = cpu_to_be32(qkey); |
|---|
| 2866 | | - sqp->ud_header.deth.source_qpn = cpu_to_be32(sqp->qp.mqp.qpn); |
|---|
| 2893 | + sqp->ud_header.deth.source_qpn = cpu_to_be32(qp->mqp.qpn); |
|---|
| 2867 | 2894 | |
|---|
| 2868 | 2895 | sqp->ud_header.bth.opcode = IB_OPCODE_UD_SEND_ONLY; |
|---|
| 2869 | 2896 | sqp->ud_header.immediate_present = 0; |
|---|
| .. | .. |
|---|
| 2947 | 2974 | } |
|---|
| 2948 | 2975 | |
|---|
| 2949 | 2976 | #define MLX4_ROCEV2_QP1_SPORT 0xC000 |
|---|
| 2950 | | -static int build_mlx_header(struct mlx4_ib_sqp *sqp, const struct ib_ud_wr *wr, |
|---|
| 2977 | +static int build_mlx_header(struct mlx4_ib_qp *qp, const struct ib_ud_wr *wr, |
|---|
| 2951 | 2978 | void *wqe, unsigned *mlx_seg_len) |
|---|
| 2952 | 2979 | { |
|---|
| 2953 | | - struct ib_device *ib_dev = sqp->qp.ibqp.device; |
|---|
| 2980 | + struct mlx4_ib_sqp *sqp = qp->sqp; |
|---|
| 2981 | + struct ib_device *ib_dev = qp->ibqp.device; |
|---|
| 2954 | 2982 | struct mlx4_ib_dev *ibdev = to_mdev(ib_dev); |
|---|
| 2955 | 2983 | struct mlx4_wqe_mlx_seg *mlx = wqe; |
|---|
| 2956 | 2984 | struct mlx4_wqe_ctrl_seg *ctrl = wqe; |
|---|
| .. | .. |
|---|
| 2974 | 3002 | for (i = 0; i < wr->wr.num_sge; ++i) |
|---|
| 2975 | 3003 | send_size += wr->wr.sg_list[i].length; |
|---|
| 2976 | 3004 | |
|---|
| 2977 | | - is_eth = rdma_port_get_link_layer(sqp->qp.ibqp.device, sqp->qp.port) == IB_LINK_LAYER_ETHERNET; |
|---|
| 3005 | + is_eth = rdma_port_get_link_layer(qp->ibqp.device, qp->port) == IB_LINK_LAYER_ETHERNET; |
|---|
| 2978 | 3006 | is_grh = mlx4_ib_ah_grh_present(ah); |
|---|
| 2979 | 3007 | if (is_eth) { |
|---|
| 2980 | 3008 | enum ib_gid_type gid_type; |
|---|
| .. | .. |
|---|
| 2988 | 3016 | if (err) |
|---|
| 2989 | 3017 | return err; |
|---|
| 2990 | 3018 | } else { |
|---|
| 2991 | | - err = fill_gid_by_hw_index(ibdev, sqp->qp.port, |
|---|
| 2992 | | - ah->av.ib.gid_index, |
|---|
| 2993 | | - &sgid, &gid_type); |
|---|
| 3019 | + err = fill_gid_by_hw_index(ibdev, qp->port, |
|---|
| 3020 | + ah->av.ib.gid_index, &sgid, |
|---|
| 3021 | + &gid_type); |
|---|
| 2994 | 3022 | if (!err) { |
|---|
| 2995 | 3023 | is_udp = gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP; |
|---|
| 2996 | 3024 | if (is_udp) { |
|---|
| .. | .. |
|---|
| 3006 | 3034 | } |
|---|
| 3007 | 3035 | if (ah->av.eth.vlan != cpu_to_be16(0xffff)) { |
|---|
| 3008 | 3036 | vlan = be16_to_cpu(ah->av.eth.vlan) & 0x0fff; |
|---|
| 3009 | | - is_vlan = 1; |
|---|
| 3037 | + is_vlan = true; |
|---|
| 3010 | 3038 | } |
|---|
| 3011 | 3039 | } |
|---|
| 3012 | 3040 | err = ib_ud_header_init(send_size, !is_eth, is_eth, is_vlan, is_grh, |
|---|
| .. | .. |
|---|
| 3035 | 3063 | * indexes don't necessarily match the hw ones, so |
|---|
| 3036 | 3064 | * we must use our own cache |
|---|
| 3037 | 3065 | */ |
|---|
| 3038 | | - sqp->ud_header.grh.source_gid.global.subnet_prefix = |
|---|
| 3039 | | - cpu_to_be64(atomic64_read(&(to_mdev(ib_dev)->sriov. |
|---|
| 3040 | | - demux[sqp->qp.port - 1]. |
|---|
| 3041 | | - subnet_prefix))); |
|---|
| 3042 | | - sqp->ud_header.grh.source_gid.global.interface_id = |
|---|
| 3043 | | - to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1]. |
|---|
| 3044 | | - guid_cache[ah->av.ib.gid_index]; |
|---|
| 3066 | + sqp->ud_header.grh.source_gid.global |
|---|
| 3067 | + .subnet_prefix = |
|---|
| 3068 | + cpu_to_be64(atomic64_read( |
|---|
| 3069 | + &(to_mdev(ib_dev) |
|---|
| 3070 | + ->sriov |
|---|
| 3071 | + .demux[qp->port - 1] |
|---|
| 3072 | + .subnet_prefix))); |
|---|
| 3073 | + sqp->ud_header.grh.source_gid.global |
|---|
| 3074 | + .interface_id = |
|---|
| 3075 | + to_mdev(ib_dev) |
|---|
| 3076 | + ->sriov.demux[qp->port - 1] |
|---|
| 3077 | + .guid_cache[ah->av.ib.gid_index]; |
|---|
| 3045 | 3078 | } else { |
|---|
| 3046 | 3079 | sqp->ud_header.grh.source_gid = |
|---|
| 3047 | 3080 | ah->ibah.sgid_attr->gid; |
|---|
| .. | .. |
|---|
| 3073 | 3106 | mlx->flags &= cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); |
|---|
| 3074 | 3107 | |
|---|
| 3075 | 3108 | if (!is_eth) { |
|---|
| 3076 | | - mlx->flags |= cpu_to_be32((!sqp->qp.ibqp.qp_num ? MLX4_WQE_MLX_VL15 : 0) | |
|---|
| 3077 | | - (sqp->ud_header.lrh.destination_lid == |
|---|
| 3078 | | - IB_LID_PERMISSIVE ? MLX4_WQE_MLX_SLR : 0) | |
|---|
| 3079 | | - (sqp->ud_header.lrh.service_level << 8)); |
|---|
| 3109 | + mlx->flags |= |
|---|
| 3110 | + cpu_to_be32((!qp->ibqp.qp_num ? MLX4_WQE_MLX_VL15 : 0) | |
|---|
| 3111 | + (sqp->ud_header.lrh.destination_lid == |
|---|
| 3112 | + IB_LID_PERMISSIVE ? |
|---|
| 3113 | + MLX4_WQE_MLX_SLR : |
|---|
| 3114 | + 0) | |
|---|
| 3115 | + (sqp->ud_header.lrh.service_level << 8)); |
|---|
| 3080 | 3116 | if (ah->av.ib.port_pd & cpu_to_be32(0x80000000)) |
|---|
| 3081 | 3117 | mlx->flags |= cpu_to_be32(0x1); /* force loopback */ |
|---|
| 3082 | 3118 | mlx->rlid = sqp->ud_header.lrh.destination_lid; |
|---|
| .. | .. |
|---|
| 3122 | 3158 | sqp->ud_header.vlan.tag = cpu_to_be16(vlan | pcp); |
|---|
| 3123 | 3159 | } |
|---|
| 3124 | 3160 | } else { |
|---|
| 3125 | | - sqp->ud_header.lrh.virtual_lane = !sqp->qp.ibqp.qp_num ? 15 : |
|---|
| 3126 | | - sl_to_vl(to_mdev(ib_dev), |
|---|
| 3127 | | - sqp->ud_header.lrh.service_level, |
|---|
| 3128 | | - sqp->qp.port); |
|---|
| 3129 | | - if (sqp->qp.ibqp.qp_num && sqp->ud_header.lrh.virtual_lane == 15) |
|---|
| 3161 | + sqp->ud_header.lrh.virtual_lane = |
|---|
| 3162 | + !qp->ibqp.qp_num ? |
|---|
| 3163 | + 15 : |
|---|
| 3164 | + sl_to_vl(to_mdev(ib_dev), |
|---|
| 3165 | + sqp->ud_header.lrh.service_level, |
|---|
| 3166 | + qp->port); |
|---|
| 3167 | + if (qp->ibqp.qp_num && sqp->ud_header.lrh.virtual_lane == 15) |
|---|
| 3130 | 3168 | return -EINVAL; |
|---|
| 3131 | 3169 | if (sqp->ud_header.lrh.destination_lid == IB_LID_PERMISSIVE) |
|---|
| 3132 | 3170 | sqp->ud_header.lrh.source_lid = IB_LID_PERMISSIVE; |
|---|
| 3133 | 3171 | } |
|---|
| 3134 | 3172 | sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); |
|---|
| 3135 | | - if (!sqp->qp.ibqp.qp_num) |
|---|
| 3136 | | - err = ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, |
|---|
| 3173 | + if (!qp->ibqp.qp_num) |
|---|
| 3174 | + err = ib_get_cached_pkey(ib_dev, qp->port, sqp->pkey_index, |
|---|
| 3137 | 3175 | &pkey); |
|---|
| 3138 | 3176 | else |
|---|
| 3139 | | - err = ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, |
|---|
| 3177 | + err = ib_get_cached_pkey(ib_dev, qp->port, wr->pkey_index, |
|---|
| 3140 | 3178 | &pkey); |
|---|
| 3141 | 3179 | if (err) |
|---|
| 3142 | 3180 | return err; |
|---|
| .. | .. |
|---|
| 3146 | 3184 | sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); |
|---|
| 3147 | 3185 | sqp->ud_header.deth.qkey = cpu_to_be32(wr->remote_qkey & 0x80000000 ? |
|---|
| 3148 | 3186 | sqp->qkey : wr->remote_qkey); |
|---|
| 3149 | | - sqp->ud_header.deth.source_qpn = cpu_to_be32(sqp->qp.ibqp.qp_num); |
|---|
| 3187 | + sqp->ud_header.deth.source_qpn = cpu_to_be32(qp->ibqp.qp_num); |
|---|
| 3150 | 3188 | |
|---|
| 3151 | 3189 | header_size = ib_ud_header_pack(&sqp->ud_header, sqp->header_buf); |
|---|
| 3152 | 3190 | |
|---|
| .. | .. |
|---|
| 3459 | 3497 | int nreq; |
|---|
| 3460 | 3498 | int err = 0; |
|---|
| 3461 | 3499 | unsigned ind; |
|---|
| 3462 | | - int uninitialized_var(size); |
|---|
| 3463 | | - unsigned uninitialized_var(seglen); |
|---|
| 3500 | + int size; |
|---|
| 3501 | + unsigned seglen; |
|---|
| 3464 | 3502 | __be32 dummy; |
|---|
| 3465 | 3503 | __be32 *lso_wqe; |
|---|
| 3466 | | - __be32 uninitialized_var(lso_hdr_sz); |
|---|
| 3504 | + __be32 lso_hdr_sz; |
|---|
| 3467 | 3505 | __be32 blh; |
|---|
| 3468 | 3506 | int i; |
|---|
| 3469 | 3507 | struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); |
|---|
| 3470 | 3508 | |
|---|
| 3471 | 3509 | if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) { |
|---|
| 3472 | | - struct mlx4_ib_sqp *sqp = to_msqp(qp); |
|---|
| 3510 | + struct mlx4_ib_sqp *sqp = qp->sqp; |
|---|
| 3473 | 3511 | |
|---|
| 3474 | 3512 | if (sqp->roce_v2_gsi) { |
|---|
| 3475 | 3513 | struct mlx4_ib_ah *ah = to_mah(ud_wr(wr)->ah); |
|---|
| 3476 | 3514 | enum ib_gid_type gid_type; |
|---|
| 3477 | 3515 | union ib_gid gid; |
|---|
| 3478 | 3516 | |
|---|
| 3479 | | - if (!fill_gid_by_hw_index(mdev, sqp->qp.port, |
|---|
| 3517 | + if (!fill_gid_by_hw_index(mdev, qp->port, |
|---|
| 3480 | 3518 | ah->av.ib.gid_index, |
|---|
| 3481 | 3519 | &gid, &gid_type)) |
|---|
| 3482 | 3520 | qp = (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ? |
|---|
| .. | .. |
|---|
| 3596 | 3634 | break; |
|---|
| 3597 | 3635 | |
|---|
| 3598 | 3636 | case MLX4_IB_QPT_TUN_SMI_OWNER: |
|---|
| 3599 | | - err = build_sriov_qp0_header(to_msqp(qp), ud_wr(wr), |
|---|
| 3600 | | - ctrl, &seglen); |
|---|
| 3637 | + err = build_sriov_qp0_header(qp, ud_wr(wr), ctrl, |
|---|
| 3638 | + &seglen); |
|---|
| 3601 | 3639 | if (unlikely(err)) { |
|---|
| 3602 | 3640 | *bad_wr = wr; |
|---|
| 3603 | 3641 | goto out; |
|---|
| .. | .. |
|---|
| 3633 | 3671 | break; |
|---|
| 3634 | 3672 | |
|---|
| 3635 | 3673 | case MLX4_IB_QPT_PROXY_SMI_OWNER: |
|---|
| 3636 | | - err = build_sriov_qp0_header(to_msqp(qp), ud_wr(wr), |
|---|
| 3637 | | - ctrl, &seglen); |
|---|
| 3674 | + err = build_sriov_qp0_header(qp, ud_wr(wr), ctrl, |
|---|
| 3675 | + &seglen); |
|---|
| 3638 | 3676 | if (unlikely(err)) { |
|---|
| 3639 | 3677 | *bad_wr = wr; |
|---|
| 3640 | 3678 | goto out; |
|---|
| .. | .. |
|---|
| 3667 | 3705 | |
|---|
| 3668 | 3706 | case MLX4_IB_QPT_SMI: |
|---|
| 3669 | 3707 | case MLX4_IB_QPT_GSI: |
|---|
| 3670 | | - err = build_mlx_header(to_msqp(qp), ud_wr(wr), ctrl, |
|---|
| 3671 | | - &seglen); |
|---|
| 3708 | + err = build_mlx_header(qp, ud_wr(wr), ctrl, &seglen); |
|---|
| 3672 | 3709 | if (unlikely(err)) { |
|---|
| 3673 | 3710 | *bad_wr = wr; |
|---|
| 3674 | 3711 | goto out; |
|---|
| .. | .. |
|---|
| 3753 | 3790 | |
|---|
| 3754 | 3791 | writel_relaxed(qp->doorbell_qpn, |
|---|
| 3755 | 3792 | to_mdev(ibqp->device)->uar_map + MLX4_SEND_DOORBELL); |
|---|
| 3756 | | - |
|---|
| 3757 | | - /* |
|---|
| 3758 | | - * Make sure doorbells don't leak out of SQ spinlock |
|---|
| 3759 | | - * and reach the HCA out of order. |
|---|
| 3760 | | - */ |
|---|
| 3761 | | - mmiowb(); |
|---|
| 3762 | 3793 | |
|---|
| 3763 | 3794 | stamp_send_wqe(qp, ind + qp->sq_spare_wqes - 1); |
|---|
| 3764 | 3795 | |
|---|
| .. | .. |
|---|
| 4054 | 4085 | struct ib_wq_init_attr *init_attr, |
|---|
| 4055 | 4086 | struct ib_udata *udata) |
|---|
| 4056 | 4087 | { |
|---|
| 4057 | | - struct mlx4_ib_dev *dev; |
|---|
| 4058 | | - struct ib_qp_init_attr ib_qp_init_attr; |
|---|
| 4088 | + struct mlx4_dev *dev = to_mdev(pd->device)->dev; |
|---|
| 4089 | + struct ib_qp_init_attr ib_qp_init_attr = {}; |
|---|
| 4059 | 4090 | struct mlx4_ib_qp *qp; |
|---|
| 4060 | 4091 | struct mlx4_ib_create_wq ucmd; |
|---|
| 4061 | 4092 | int err, required_cmd_sz; |
|---|
| 4062 | 4093 | |
|---|
| 4063 | | - if (!(udata && pd->uobject)) |
|---|
| 4094 | + if (!udata) |
|---|
| 4064 | 4095 | return ERR_PTR(-EINVAL); |
|---|
| 4065 | 4096 | |
|---|
| 4066 | 4097 | required_cmd_sz = offsetof(typeof(ucmd), comp_mask) + |
|---|
| .. | .. |
|---|
| 4080 | 4111 | if (udata->outlen) |
|---|
| 4081 | 4112 | return ERR_PTR(-EOPNOTSUPP); |
|---|
| 4082 | 4113 | |
|---|
| 4083 | | - dev = to_mdev(pd->device); |
|---|
| 4084 | | - |
|---|
| 4085 | 4114 | if (init_attr->wq_type != IB_WQT_RQ) { |
|---|
| 4086 | 4115 | pr_debug("unsupported wq type %d\n", init_attr->wq_type); |
|---|
| 4087 | 4116 | return ERR_PTR(-EOPNOTSUPP); |
|---|
| 4088 | 4117 | } |
|---|
| 4089 | 4118 | |
|---|
| 4090 | | - if (init_attr->create_flags & ~IB_WQ_FLAGS_SCATTER_FCS) { |
|---|
| 4119 | + if (init_attr->create_flags & ~IB_WQ_FLAGS_SCATTER_FCS || |
|---|
| 4120 | + !(dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP)) { |
|---|
| 4091 | 4121 | pr_debug("unsupported create_flags %u\n", |
|---|
| 4092 | 4122 | init_attr->create_flags); |
|---|
| 4093 | 4123 | return ERR_PTR(-EOPNOTSUPP); |
|---|
| .. | .. |
|---|
| 4097 | 4127 | if (!qp) |
|---|
| 4098 | 4128 | return ERR_PTR(-ENOMEM); |
|---|
| 4099 | 4129 | |
|---|
| 4130 | + mutex_init(&qp->mutex); |
|---|
| 4100 | 4131 | qp->pri.vid = 0xFFFF; |
|---|
| 4101 | 4132 | qp->alt.vid = 0xFFFF; |
|---|
| 4102 | 4133 | |
|---|
| 4103 | | - memset(&ib_qp_init_attr, 0, sizeof(ib_qp_init_attr)); |
|---|
| 4104 | 4134 | ib_qp_init_attr.qp_context = init_attr->wq_context; |
|---|
| 4105 | 4135 | ib_qp_init_attr.qp_type = IB_QPT_RAW_PACKET; |
|---|
| 4106 | 4136 | ib_qp_init_attr.cap.max_recv_wr = init_attr->max_wr; |
|---|
| .. | .. |
|---|
| 4111 | 4141 | if (init_attr->create_flags & IB_WQ_FLAGS_SCATTER_FCS) |
|---|
| 4112 | 4142 | ib_qp_init_attr.create_flags |= IB_QP_CREATE_SCATTER_FCS; |
|---|
| 4113 | 4143 | |
|---|
| 4114 | | - err = create_qp_common(dev, pd, MLX4_IB_RWQ_SRC, &ib_qp_init_attr, |
|---|
| 4115 | | - udata, 0, &qp); |
|---|
| 4144 | + err = create_rq(pd, &ib_qp_init_attr, udata, qp); |
|---|
| 4116 | 4145 | if (err) { |
|---|
| 4117 | 4146 | kfree(qp); |
|---|
| 4118 | 4147 | return ERR_PTR(err); |
|---|
| .. | .. |
|---|
| 4137 | 4166 | } |
|---|
| 4138 | 4167 | } |
|---|
| 4139 | 4168 | |
|---|
| 4140 | | -static int _mlx4_ib_modify_wq(struct ib_wq *ibwq, enum ib_wq_state new_state) |
|---|
| 4169 | +static int _mlx4_ib_modify_wq(struct ib_wq *ibwq, enum ib_wq_state new_state, |
|---|
| 4170 | + struct ib_udata *udata) |
|---|
| 4141 | 4171 | { |
|---|
| 4142 | 4172 | struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq); |
|---|
| 4143 | 4173 | enum ib_qp_state qp_cur_state; |
|---|
| .. | .. |
|---|
| 4161 | 4191 | attr_mask = IB_QP_PORT; |
|---|
| 4162 | 4192 | |
|---|
| 4163 | 4193 | err = __mlx4_ib_modify_qp(ibwq, MLX4_IB_RWQ_SRC, &attr, |
|---|
| 4164 | | - attr_mask, IB_QPS_RESET, IB_QPS_INIT); |
|---|
| 4194 | + attr_mask, IB_QPS_RESET, IB_QPS_INIT, |
|---|
| 4195 | + udata); |
|---|
| 4165 | 4196 | if (err) { |
|---|
| 4166 | 4197 | pr_debug("WQN=0x%06x failed to apply RST->INIT on the HW QP\n", |
|---|
| 4167 | 4198 | ibwq->wq_num); |
|---|
| .. | .. |
|---|
| 4173 | 4204 | |
|---|
| 4174 | 4205 | attr_mask = 0; |
|---|
| 4175 | 4206 | err = __mlx4_ib_modify_qp(ibwq, MLX4_IB_RWQ_SRC, NULL, attr_mask, |
|---|
| 4176 | | - qp_cur_state, qp_new_state); |
|---|
| 4207 | + qp_cur_state, qp_new_state, udata); |
|---|
| 4177 | 4208 | |
|---|
| 4178 | 4209 | if (err && (qp_cur_state == IB_QPS_INIT)) { |
|---|
| 4179 | 4210 | qp_new_state = IB_QPS_RESET; |
|---|
| 4180 | 4211 | if (__mlx4_ib_modify_qp(ibwq, MLX4_IB_RWQ_SRC, NULL, |
|---|
| 4181 | | - attr_mask, IB_QPS_INIT, IB_QPS_RESET)) { |
|---|
| 4212 | + attr_mask, IB_QPS_INIT, IB_QPS_RESET, |
|---|
| 4213 | + udata)) { |
|---|
| 4182 | 4214 | pr_warn("WQN=0x%06x failed with reverting HW's resources failure\n", |
|---|
| 4183 | 4215 | ibwq->wq_num); |
|---|
| 4184 | 4216 | qp_new_state = IB_QPS_INIT; |
|---|
| .. | .. |
|---|
| 4218 | 4250 | if (wq_attr_mask & IB_WQ_FLAGS) |
|---|
| 4219 | 4251 | return -EOPNOTSUPP; |
|---|
| 4220 | 4252 | |
|---|
| 4221 | | - cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state : |
|---|
| 4222 | | - ibwq->state; |
|---|
| 4223 | | - new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state; |
|---|
| 4224 | | - |
|---|
| 4225 | | - if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR || |
|---|
| 4226 | | - new_state < IB_WQS_RESET || new_state > IB_WQS_ERR) |
|---|
| 4227 | | - return -EINVAL; |
|---|
| 4253 | + cur_state = wq_attr->curr_wq_state; |
|---|
| 4254 | + new_state = wq_attr->wq_state; |
|---|
| 4228 | 4255 | |
|---|
| 4229 | 4256 | if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR)) |
|---|
| 4230 | 4257 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 4241 | 4268 | * WQ, so we can apply its port on the WQ. |
|---|
| 4242 | 4269 | */ |
|---|
| 4243 | 4270 | if (qp->rss_usecnt) |
|---|
| 4244 | | - err = _mlx4_ib_modify_wq(ibwq, new_state); |
|---|
| 4271 | + err = _mlx4_ib_modify_wq(ibwq, new_state, udata); |
|---|
| 4245 | 4272 | |
|---|
| 4246 | 4273 | if (!err) |
|---|
| 4247 | 4274 | ibwq->state = new_state; |
|---|
| .. | .. |
|---|
| 4251 | 4278 | return err; |
|---|
| 4252 | 4279 | } |
|---|
| 4253 | 4280 | |
|---|
| 4254 | | -int mlx4_ib_destroy_wq(struct ib_wq *ibwq) |
|---|
| 4281 | +int mlx4_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata) |
|---|
| 4255 | 4282 | { |
|---|
| 4256 | 4283 | struct mlx4_ib_dev *dev = to_mdev(ibwq->device); |
|---|
| 4257 | 4284 | struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq); |
|---|
| .. | .. |
|---|
| 4259 | 4286 | if (qp->counter_index) |
|---|
| 4260 | 4287 | mlx4_ib_free_qp_counter(dev, qp); |
|---|
| 4261 | 4288 | |
|---|
| 4262 | | - destroy_qp_common(dev, qp, MLX4_IB_RWQ_SRC, 1); |
|---|
| 4289 | + destroy_qp_common(dev, qp, MLX4_IB_RWQ_SRC, udata); |
|---|
| 4263 | 4290 | |
|---|
| 4264 | 4291 | kfree(qp); |
|---|
| 4265 | | - |
|---|
| 4266 | 4292 | return 0; |
|---|
| 4267 | 4293 | } |
|---|
| 4268 | 4294 | |
|---|
| 4269 | | -struct ib_rwq_ind_table |
|---|
| 4270 | | -*mlx4_ib_create_rwq_ind_table(struct ib_device *device, |
|---|
| 4271 | | - struct ib_rwq_ind_table_init_attr *init_attr, |
|---|
| 4272 | | - struct ib_udata *udata) |
|---|
| 4295 | +int mlx4_ib_create_rwq_ind_table(struct ib_rwq_ind_table *rwq_ind_table, |
|---|
| 4296 | + struct ib_rwq_ind_table_init_attr *init_attr, |
|---|
| 4297 | + struct ib_udata *udata) |
|---|
| 4273 | 4298 | { |
|---|
| 4274 | | - struct ib_rwq_ind_table *rwq_ind_table; |
|---|
| 4275 | 4299 | struct mlx4_ib_create_rwq_ind_tbl_resp resp = {}; |
|---|
| 4276 | 4300 | unsigned int ind_tbl_size = 1 << init_attr->log_ind_tbl_size; |
|---|
| 4301 | + struct ib_device *device = rwq_ind_table->device; |
|---|
| 4277 | 4302 | unsigned int base_wqn; |
|---|
| 4278 | 4303 | size_t min_resp_len; |
|---|
| 4279 | | - int i; |
|---|
| 4280 | | - int err; |
|---|
| 4304 | + int i, err = 0; |
|---|
| 4281 | 4305 | |
|---|
| 4282 | 4306 | if (udata->inlen > 0 && |
|---|
| 4283 | 4307 | !ib_is_udata_cleared(udata, 0, |
|---|
| 4284 | 4308 | udata->inlen)) |
|---|
| 4285 | | - return ERR_PTR(-EOPNOTSUPP); |
|---|
| 4309 | + return -EOPNOTSUPP; |
|---|
| 4286 | 4310 | |
|---|
| 4287 | 4311 | min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved); |
|---|
| 4288 | 4312 | if (udata->outlen && udata->outlen < min_resp_len) |
|---|
| 4289 | | - return ERR_PTR(-EINVAL); |
|---|
| 4313 | + return -EINVAL; |
|---|
| 4290 | 4314 | |
|---|
| 4291 | 4315 | if (ind_tbl_size > |
|---|
| 4292 | 4316 | device->attrs.rss_caps.max_rwq_indirection_table_size) { |
|---|
| 4293 | 4317 | pr_debug("log_ind_tbl_size = %d is bigger than supported = %d\n", |
|---|
| 4294 | 4318 | ind_tbl_size, |
|---|
| 4295 | 4319 | device->attrs.rss_caps.max_rwq_indirection_table_size); |
|---|
| 4296 | | - return ERR_PTR(-EINVAL); |
|---|
| 4320 | + return -EINVAL; |
|---|
| 4297 | 4321 | } |
|---|
| 4298 | 4322 | |
|---|
| 4299 | 4323 | base_wqn = init_attr->ind_tbl[0]->wq_num; |
|---|
| .. | .. |
|---|
| 4301 | 4325 | if (base_wqn % ind_tbl_size) { |
|---|
| 4302 | 4326 | pr_debug("WQN=0x%x isn't aligned with indirection table size\n", |
|---|
| 4303 | 4327 | base_wqn); |
|---|
| 4304 | | - return ERR_PTR(-EINVAL); |
|---|
| 4328 | + return -EINVAL; |
|---|
| 4305 | 4329 | } |
|---|
| 4306 | 4330 | |
|---|
| 4307 | 4331 | for (i = 1; i < ind_tbl_size; i++) { |
|---|
| 4308 | 4332 | if (++base_wqn != init_attr->ind_tbl[i]->wq_num) { |
|---|
| 4309 | 4333 | pr_debug("indirection table's WQNs aren't consecutive\n"); |
|---|
| 4310 | | - return ERR_PTR(-EINVAL); |
|---|
| 4334 | + return -EINVAL; |
|---|
| 4311 | 4335 | } |
|---|
| 4312 | 4336 | } |
|---|
| 4313 | | - |
|---|
| 4314 | | - rwq_ind_table = kzalloc(sizeof(*rwq_ind_table), GFP_KERNEL); |
|---|
| 4315 | | - if (!rwq_ind_table) |
|---|
| 4316 | | - return ERR_PTR(-ENOMEM); |
|---|
| 4317 | 4337 | |
|---|
| 4318 | 4338 | if (udata->outlen) { |
|---|
| 4319 | 4339 | resp.response_length = offsetof(typeof(resp), response_length) + |
|---|
| 4320 | 4340 | sizeof(resp.response_length); |
|---|
| 4321 | 4341 | err = ib_copy_to_udata(udata, &resp, resp.response_length); |
|---|
| 4322 | | - if (err) |
|---|
| 4323 | | - goto err; |
|---|
| 4324 | 4342 | } |
|---|
| 4325 | 4343 | |
|---|
| 4326 | | - return rwq_ind_table; |
|---|
| 4327 | | - |
|---|
| 4328 | | -err: |
|---|
| 4329 | | - kfree(rwq_ind_table); |
|---|
| 4330 | | - return ERR_PTR(err); |
|---|
| 4331 | | -} |
|---|
| 4332 | | - |
|---|
| 4333 | | -int mlx4_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl) |
|---|
| 4334 | | -{ |
|---|
| 4335 | | - kfree(ib_rwq_ind_tbl); |
|---|
| 4336 | | - return 0; |
|---|
| 4344 | + return err; |
|---|
| 4337 | 4345 | } |
|---|
| 4338 | 4346 | |
|---|
| 4339 | 4347 | struct mlx4_ib_drain_cqe { |
|---|