static u32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
{
- if (attr->srq || (attr->qp_type == IB_QPT_XRC_TGT) ||
- (qp->qp_sub_type == MLX5_IB_QPT_DCI) ||
- (attr->qp_type == IB_QPT_XRC_INI))
+ if (attr->srq || (qp->type == IB_QPT_XRC_TGT) ||
+ (qp->type == MLX5_IB_QPT_DCI) || (qp->type == IB_QPT_XRC_INI))
return MLX5_SRQ_RQ;
else if (!qp->has_rq)
return MLX5_ZERO_LEN_RQ;
- else
- return MLX5_NON_ZERO_RQ;
+
+ return MLX5_NON_ZERO_RQ;
}
static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
spin_lock_init(&qp->sq.lock);
spin_lock_init(&qp->rq.lock);
- mlx5_st = to_mlx5_st((init_attr->qp_type != IB_QPT_DRIVER) ?
- init_attr->qp_type :
- qp->qp_sub_type);
+ mlx5_st = to_mlx5_st(qp->type);
if (mlx5_st < 0)
return -EINVAL;
MLX5_RES_SCAT_DATA32_CQE);
}
if ((qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) &&
- (qp->qp_sub_type == MLX5_IB_QPT_DCI ||
- init_attr->qp_type == IB_QPT_RC))
+ (qp->type == MLX5_IB_QPT_DCI || qp->type == IB_QPT_RC))
configure_requester_scat_cqe(dev, init_attr, ucmd, qpc);
if (qp->rq.wqe_cnt) {
base->container_mibqp = qp;
base->mqp.event = mlx5_ib_qp_event;
- get_cqs(init_attr->qp_type, init_attr->send_cq, init_attr->recv_cq,
+ get_cqs(qp->type, init_attr->send_cq, init_attr->recv_cq,
&send_cq, &recv_cq);
spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);
mlx5_ib_lock_cqs(send_cq, recv_cq);
return 0;
}
-static int check_qp_type(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr)
+static int check_qp_type(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
+ enum ib_qp_type *type)
{
if (attr->qp_type == IB_QPT_DRIVER && !MLX5_CAP_GEN(dev->mdev, dct))
goto out;
case MLX5_IB_QPT_REG_UMR:
case IB_QPT_DRIVER:
case IB_QPT_GSI:
- return 0;
+ break;
default:
goto out;
}
+ *type = attr->qp_type;
return 0;
out:
}
static int process_vendor_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
- struct ib_qp_init_attr *attr,
struct mlx5_ib_create_qp *ucmd)
{
struct mlx5_core_dev *mdev = dev->mdev;
switch (flags & (MLX5_QP_FLAG_TYPE_DCT | MLX5_QP_FLAG_TYPE_DCI)) {
case MLX5_QP_FLAG_TYPE_DCI:
- qp->qp_sub_type = MLX5_IB_QPT_DCI;
+ qp->type = MLX5_IB_QPT_DCI;
break;
case MLX5_QP_FLAG_TYPE_DCT:
- qp->qp_sub_type = MLX5_IB_QPT_DCT;
- fallthrough;
- default:
+ qp->type = MLX5_IB_QPT_DCT;
break;
- }
-
- if (attr->qp_type == IB_QPT_DRIVER && !qp->qp_sub_type)
+ default:
+ if (qp->type != IB_QPT_DRIVER)
+ break;
+ /*
+ * It is IB_QPT_DRIVER and or no subtype or
+ * wrong subtype were provided.
+ */
return -EINVAL;
+ }
process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TYPE_DCI, true, qp);
process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TYPE_DCT, true, qp);
process_vendor_flag(dev, &flags, MLX5_QP_FLAG_SCATTER_CQE,
MLX5_CAP_GEN(mdev, sctr_data_cqe), qp);
- if (attr->qp_type == IB_QPT_RAW_PACKET) {
+ if (qp->type == IB_QPT_RAW_PACKET) {
cond = MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) ||
MLX5_CAP_ETH(mdev, tunnel_stateless_gre) ||
MLX5_CAP_ETH(mdev, tunnel_stateless_geneve_rx);
qp);
}
- if (attr->qp_type == IB_QPT_RC)
+ if (qp->type == IB_QPT_RC)
process_vendor_flag(dev, &flags,
MLX5_QP_FLAG_PACKET_BASED_CREDIT_MODE,
MLX5_CAP_GEN(mdev, qp_packet_based), qp);
static int process_create_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
struct ib_qp_init_attr *attr)
{
- enum ib_qp_type qp_type = attr->qp_type;
+ enum ib_qp_type qp_type = qp->type;
struct mlx5_core_dev *mdev = dev->mdev;
int create_flags = attr->create_flags;
bool cond;
- if (qp->qp_sub_type == MLX5_IB_QPT_DCT)
+ if (qp_type == MLX5_IB_QPT_DCT)
return (create_flags) ? -EINVAL : 0;
if (qp_type == IB_QPT_RAW_PACKET && attr->rwq_ind_tbl)
return (create_flags) ? -EINVAL : 0;
}
-static int create_driver_qp(struct ib_pd *pd, struct mlx5_ib_qp *qp,
- struct ib_qp_init_attr *attr,
- struct mlx5_ib_create_qp *ucmd,
- struct ib_udata *udata)
-{
- struct mlx5_ib_dev *mdev = to_mdev(pd->device);
- int ret = -EINVAL;
-
- switch (qp->qp_sub_type) {
- case MLX5_IB_QPT_DCT:
- if (!attr->srq || !attr->recv_cq)
- goto out;
-
- ret = create_dct(pd, qp, attr, ucmd, udata);
- break;
- case MLX5_IB_QPT_DCI:
- if (attr->cap.max_recv_wr || attr->cap.max_recv_sge)
- goto out;
-
- ret = create_qp_common(mdev, pd, attr, ucmd, udata, qp);
- break;
- default:
- return -EINVAL;
- }
-
-out: return ret;
-}
-
static size_t process_udata_size(struct ib_qp_init_attr *attr,
struct ib_udata *udata)
{
return create_qp_common(dev, pd, attr, ucmd, udata, qp);
}
+static int check_qp_attr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+ struct ib_qp_init_attr *attr)
+{
+ int ret = 0;
+
+ switch (qp->type) {
+ case MLX5_IB_QPT_DCT:
+ ret = (!attr->srq || !attr->recv_cq) ? -EINVAL : 0;
+ break;
+ case MLX5_IB_QPT_DCI:
+ ret = (attr->cap.max_recv_wr || attr->cap.max_recv_sge) ?
+ -EINVAL :
+ 0;
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ mlx5_ib_dbg(dev, "QP type %d has wrong attributes\n", qp->type);
+
+ return ret;
+}
+
struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata)
struct mlx5_ib_create_qp ucmd = {};
struct mlx5_ib_dev *dev;
struct mlx5_ib_qp *qp;
+ enum ib_qp_type type;
u16 xrcdn = 0;
int err;
dev = pd ? to_mdev(pd->device) :
to_mdev(to_mxrcd(init_attr->xrcd)->ibxrcd.device);
- err = check_qp_type(dev, init_attr);
+ err = check_qp_type(dev, init_attr, &type);
if (err) {
mlx5_ib_dbg(dev, "Unsupported QP type %d\n",
init_attr->qp_type);
if (!qp)
return ERR_PTR(-ENOMEM);
+ qp->type = type;
if (udata) {
- err = process_vendor_flags(dev, qp, init_attr, &ucmd);
+ err = process_vendor_flags(dev, qp, &ucmd);
if (err)
goto free_qp;
}
if (err)
goto free_qp;
- if (init_attr->qp_type == IB_QPT_XRC_TGT)
+ if (qp->type == IB_QPT_XRC_TGT)
xrcdn = to_mxrcd(init_attr->xrcd)->xrcdn;
- switch (init_attr->qp_type) {
- case IB_QPT_DRIVER:
- err = create_driver_qp(pd, qp, init_attr, &ucmd, udata);
- break;
+ err = check_qp_attr(dev, qp, init_attr);
+ if (err)
+ goto free_qp;
+
+ switch (qp->type) {
case IB_QPT_RAW_PACKET:
err = create_raw_qp(pd, qp, init_attr, &ucmd, udata);
break;
+ case MLX5_IB_QPT_DCT:
+ err = create_dct(pd, qp, init_attr, &ucmd, udata);
+ break;
default:
err = create_qp_common(dev, pd, init_attr,
(udata) ? &ucmd : NULL, udata, qp);
if (unlikely(qp->qp_type == IB_QPT_GSI))
return mlx5_ib_gsi_destroy_qp(qp);
- if (mqp->qp_sub_type == MLX5_IB_QPT_DCT)
+ if (mqp->type == MLX5_IB_QPT_DCT)
return mlx5_ib_destroy_dct(mqp);
destroy_qp_common(dev, mqp, udata);
u16 op;
u8 tx_affinity = 0;
- mlx5_st = to_mlx5_st(ibqp->qp_type == IB_QPT_DRIVER ?
- qp->qp_sub_type : ibqp->qp_type);
+ mlx5_st = to_mlx5_st(qp->type);
if (mlx5_st < 0)
return -EINVAL;
if (unlikely(ibqp->qp_type == IB_QPT_GSI))
return mlx5_ib_gsi_modify_qp(ibqp, attr, attr_mask);
- if (ibqp->qp_type == IB_QPT_DRIVER)
- qp_type = qp->qp_sub_type;
- else
- qp_type = (unlikely(ibqp->qp_type == MLX5_IB_QPT_HW_GSI)) ?
- IB_QPT_GSI : ibqp->qp_type;
+ qp_type = (unlikely(ibqp->qp_type == MLX5_IB_QPT_HW_GSI)) ? IB_QPT_GSI :
+ qp->type;
if (qp_type == MLX5_IB_QPT_DCT)
return mlx5_ib_modify_dct(ibqp, attr, attr_mask, udata);
memset(qp_init_attr, 0, sizeof(*qp_init_attr));
memset(qp_attr, 0, sizeof(*qp_attr));
- if (unlikely(qp->qp_sub_type == MLX5_IB_QPT_DCT))
+ if (unlikely(qp->type == MLX5_IB_QPT_DCT))
return mlx5_ib_dct_query_qp(dev, qp, qp_attr,
qp_attr_mask, qp_init_attr);