in efawin/verbs.c [1014:1064]
static void efa_qp_fill_wr_pfns(struct ibv_qp_ex *ibvqpx,
struct ibv_qp_init_attr_ex *attr_ex);
static int efa_check_qp_attr(struct efa_context *ctx,
struct ibv_qp_init_attr_ex *attr,
struct efadv_qp_init_attr *efa_attr)
{
uint64_t supp_send_ops_mask;
uint64_t supp_ud_send_ops_mask = IBV_QP_EX_WITH_SEND |
IBV_QP_EX_WITH_SEND_WITH_IMM;
uint64_t supp_srd_send_ops_mask =
IBV_QP_EX_WITH_SEND | IBV_QP_EX_WITH_SEND_WITH_IMM |
(EFA_DEV_CAP(ctx, RDMA_READ) ? IBV_QP_EX_WITH_RDMA_READ : 0);
#define EFA_CREATE_QP_SUPP_ATTR_MASK \
(IBV_QP_INIT_ATTR_PD | IBV_QP_INIT_ATTR_SEND_OPS_FLAGS)
if (attr->qp_type == IBV_QPT_DRIVER &&
efa_attr->driver_qp_type != EFADV_QP_DRIVER_TYPE_SRD)
return EOPNOTSUPP;
if (!check_comp_mask(attr->comp_mask, EFA_CREATE_QP_SUPP_ATTR_MASK))
return EOPNOTSUPP;
if (!(attr->comp_mask & IBV_QP_INIT_ATTR_PD))
return EINVAL;
if (attr->comp_mask & IBV_QP_INIT_ATTR_SEND_OPS_FLAGS) {
switch (attr->qp_type) {
case IBV_QPT_UD:
supp_send_ops_mask = supp_ud_send_ops_mask;
break;
case IBV_QPT_DRIVER:
supp_send_ops_mask = supp_srd_send_ops_mask;
break;
default:
return EOPNOTSUPP;
}
if (!check_comp_mask(attr->send_ops_flags, supp_send_ops_mask))
return EOPNOTSUPP;
}
if (!attr->recv_cq || !attr->send_cq)
return EINVAL;
if (attr->srq)
return EINVAL;
return 0;
}