IB/mlx5: Add support for setting source QP number
authorHaggai Eran <haggaie@mellanox.com>
Mon, 29 Feb 2016 13:45:03 +0000 (15:45 +0200)
committerDoug Ledford <dledford@redhat.com>
Tue, 1 Mar 2016 16:02:05 +0000 (11:02 -0500)
In order to create multiple GSI QPs, we need to set the source QP number to
one on all these QPs. Add the necessary definitions and infrastructure to
do that.

Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/qp.c
include/linux/mlx5/mlx5_ifc.h
include/linux/mlx5/qp.h

index 14396b0eac74d39c5ca246e43274ce24ceffcbda..32699f92480aff162732aa8370d942e7414d800c 100644 (file)
@@ -165,6 +165,18 @@ struct mlx5_ib_flow_db {
 #define MLX5_IB_QPT_REG_UMR    IB_QPT_RESERVED1
 #define MLX5_IB_WR_UMR         IB_WR_RESERVED1
 
+/* Private QP creation flags to be passed in ib_qp_init_attr.create_flags.
+ *
+ * These flags are intended for internal use by the mlx5_ib driver, and they
+ * rely on the range reserved for that use in the ib_qp_create_flags enum.
+ */
+
+/* Create a UD QP whose source QP number is 1 */
+static inline enum ib_qp_create_flags mlx5_ib_create_qp_sqpn_qp1(void)
+{
+       return IB_QP_CREATE_RESERVED_START;
+}
+
 struct wr_list {
        u16     opcode;
        u16     next;
@@ -331,6 +343,8 @@ enum mlx5_ib_qp_flags {
        MLX5_IB_QP_MANAGED_SEND             = IB_QP_CREATE_MANAGED_SEND,
        MLX5_IB_QP_MANAGED_RECV             = IB_QP_CREATE_MANAGED_RECV,
        MLX5_IB_QP_SIGNATURE_HANDLING           = 1 << 5,
+       /* QP uses 1 as its source QP number */
+       MLX5_IB_QP_SQPN_QP1                     = 1 << 6,
 };
 
 struct mlx5_umr_wr {
index baa88084d89dbbcef95254445fe1566df341c27d..794e760a17a07d2a4840f36add9e1549f86ea38f 100644 (file)
@@ -793,7 +793,8 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
        uuari = &dev->mdev->priv.uuari;
        if (init_attr->create_flags & ~(IB_QP_CREATE_SIGNATURE_EN |
                                        IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK |
-                                       IB_QP_CREATE_IPOIB_UD_LSO))
+                                       IB_QP_CREATE_IPOIB_UD_LSO |
+                                       mlx5_ib_create_qp_sqpn_qp1()))
                return -EINVAL;
 
        if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR)
@@ -838,6 +839,11 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
        (*in)->ctx.params1 |= cpu_to_be32(1 << 11);
        (*in)->ctx.sq_crq_size |= cpu_to_be16(1 << 4);
 
+       if (init_attr->create_flags & mlx5_ib_create_qp_sqpn_qp1()) {
+               (*in)->ctx.deth_sqpn = cpu_to_be32(1);
+               qp->flags |= MLX5_IB_QP_SQPN_QP1;
+       }
+
        mlx5_fill_page_array(&qp->buf, (*in)->pas);
 
        err = mlx5_db_alloc(dev->mdev, &qp->db);
@@ -1289,6 +1295,11 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                                            ucmd.sq_wqe_count, max_wqes);
                                return -EINVAL;
                        }
+                       if (init_attr->create_flags &
+                           mlx5_ib_create_qp_sqpn_qp1()) {
+                               mlx5_ib_dbg(dev, "user-space is not allowed to create UD QPs spoofing as QP1\n");
+                               return -EINVAL;
+                       }
                        err = create_user_qp(dev, pd, qp, udata, init_attr, &in,
                                             &resp, &inlen, base);
                        if (err)
@@ -2309,6 +2320,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
                context->sq_crq_size |= cpu_to_be16(1 << 4);
 
+       if (qp->flags & MLX5_IB_QP_SQPN_QP1)
+               context->deth_sqpn = cpu_to_be32(1);
 
        mlx5_cur = to_mlx5_state(cur_state);
        mlx5_new = to_mlx5_state(new_state);
@@ -3973,6 +3986,8 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
                qp_init_attr->create_flags |= IB_QP_CREATE_MANAGED_SEND;
        if (qp->flags & MLX5_IB_QP_MANAGED_RECV)
                qp_init_attr->create_flags |= IB_QP_CREATE_MANAGED_RECV;
+       if (qp->flags & MLX5_IB_QP_SQPN_QP1)
+               qp_init_attr->create_flags |= mlx5_ib_create_qp_sqpn_qp1();
 
        qp_init_attr->sq_sig_type = qp->sq_signal_bits & MLX5_WQE_CTRL_CQ_UPDATE ?
                IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
index 711c9dc87f63044e011bf2e20d7b8c677f92b2fb..72bba5261766be76c3ba40ae0b44b14f7a691163 100644 (file)
@@ -772,7 +772,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
        u8         reserved_at_22e[0x7];
        u8         qkv[0x1];
        u8         pkv[0x1];
-       u8         reserved_at_237[0x4];
+       u8         set_deth_sqpn[0x1];
+       u8         reserved_at_239[0x3];
        u8         xrc[0x1];
        u8         ud[0x1];
        u8         uc[0x1];
index 5b8c89ffaa5830fdf05fbc40a1fce0b5d2ffa7f3..e5bbcf06de9551ebc72a0e5c487ec8a368980912 100644 (file)
@@ -499,7 +499,8 @@ struct mlx5_qp_context {
        u8                      reserved2[4];
        __be32                  next_send_psn;
        __be32                  cqn_send;
-       u8                      reserved3[8];
+       __be32                  deth_sqpn;
+       u8                      reserved3[4];
        __be32                  last_acked_psn;
        __be32                  ssn;
        __be32                  params2;