opal/mca/common/libfabric/libfabric/prov/usnic/src/usnic_direct/usd_ib_cmd.c
/*
 * Create a verbs QP without attaching any real resources to it yet
 */
Create a verbs QP without attaching any real resources to it yet
Create a verbs QP without attaching any real resources to it yet
int
usd_ib_cmd_create_qp(
    struct usd_device *dev,
    struct usd_qp_impl *qp,
    struct usd_vf_info *vfip)
{
    struct usnic_create_qp cmd;
    struct usnic_create_qp_resp *resp;
    struct ibv_create_qp *icp;
    struct ibv_create_qp_resp *irp = NULL;
    struct usnic_ib_create_qp_cmd *ucp;
    struct usnic_ib_create_qp_resp *urp;
    struct usd_qp_filter *qfilt;
    int ret;
    int n;
    uint32_t i;
    irp = NULL;
    memset(&cmd, 0, sizeof(cmd));
    resp = calloc(1, sizeof(*resp) +
            RES_TYPE_MAX*sizeof(struct usnic_vnic_barres_info));
    if (resp == NULL) {
        usd_err("Failed to allocate memory for create_qp_resp\n");
        return -ENOMEM;
    }
    icp = &cmd.ibv_cmd;
    icp->command = IB_USER_VERBS_CMD_CREATE_QP;
    icp->in_words = sizeof(cmd) / 4;
    icp->out_words = (sizeof(*resp) +
			RES_TYPE_MAX * sizeof(struct usnic_vnic_barres_info))
			/ 4;
    icp->response = (uintptr_t) resp;
    icp->user_handle = (uintptr_t) qp;
    icp->pd_handle = dev->ud_pd_handle;
    icp->send_cq_handle = qp->uq_wq.uwq_cq->ucq_handle;
    icp->recv_cq_handle = qp->uq_rq.urq_cq->ucq_handle;
    icp->srq_handle = 0;
    icp->max_send_wr = qp->uq_wq.uwq_num_entries;
    icp->max_recv_wr = qp->uq_rq.urq_num_entries;
    icp->max_send_sge = 1;
    icp->max_recv_sge = 1;
    icp->max_inline_data = 1024;
    icp->sq_sig_all = 0;
    icp->qp_type = IBV_QPT_UD;
    icp->is_srq = 0;
    icp->reserved = 0;
    ucp = &cmd.usnic_cmd;
    ucp->cmd_version = USNIC_IB_CREATE_QP_VERSION;
    qfilt = &qp->uq_filter;
    if (qfilt->qf_type == USD_FTY_UDP ||
            qfilt->qf_type == USD_FTY_UDP_SOCK) {
        ucp->spec.trans_type = USNIC_TRANSPORT_IPV4_UDP;
        ucp->spec.udp.sock_fd = qfilt->qf_filter.qf_udp.u_sockfd;
    } else {
        ret = -EINVAL;
        goto out;
    }
    n = write(dev->ud_ib_dev_fd, &cmd, sizeof(cmd));
    if (n != sizeof(cmd)) {
        ret = -errno;
        goto out;
    }
    irp = &resp->ibv_resp;
    qp->uq_qp_handle = irp->qp_handle;
    qp->uq_qp_num = irp->qpn;
    urp = &resp->usnic_resp;
    qp->uq_rq.urq_index = urp->rq_idx[0];
    qp->uq_wq.uwq_index = urp->wq_idx[0];
    qp->uq_rq.urq_cq->ucq_index = urp->cq_idx[0];
    if (qp->uq_rq.urq_cq != qp->uq_wq.uwq_cq) {
        qp->uq_wq.uwq_cq->ucq_index = urp->cq_idx[1];
    }
    vfip->vi_vfid = urp->vfid;
    vfip->vi_bar_bus_addr = urp->bar_bus_addr;
    vfip->vi_bar_len = urp->bar_len;
    if (dev->ud_caps[USD_CAP_MAP_PER_RES] > 0) {
        for (i = 0; i < urp->num_barres; i++) {
            enum vnic_res_type type = urp->resources[i].type;
            if (type < RES_TYPE_MAX) {
                vfip->barres[type].type = type;
                vfip->barres[type].bus_addr = urp->resources[i].bus_addr;
                vfip->barres[type].len = urp->resources[i].len;
            }
        }
        if (vfip->barres[RES_TYPE_WQ].bus_addr == 0) {
                usd_err("Failed to retrieve WQ res info\n");
                ret = -ENXIO;
                goto out;
        }
        if (vfip->barres[RES_TYPE_RQ].bus_addr == 0) {
                usd_err("Failed to retrieve RQ res info\n");
                ret = -ENXIO;
                goto out;
        }
        if (vfip->barres[RES_TYPE_CQ].bus_addr == 0) {
                usd_err("Failed to retrieve CQ res info\n");
                ret = -ENXIO;
                goto out;
        }
        if (vfip->barres[RES_TYPE_INTR_CTRL].bus_addr == 0) {
                usd_err("Failed to retrieve INTR res info\n");
                ret = -ENXIO;
                goto out;
        }
        if (vfip->barres[RES_TYPE_DEVCMD].bus_addr == 0) {
                usd_err("Failed to retrieve DEVCMD res info\n");
                ret = -ENXIO;
                goto out;
        }
    }
    free(resp);
    return 0;
  out:
    if (irp != NULL)                   
        usd_ib_cmd_destroy_qp(dev, qp);
    free(resp);
    return ret;
}
int usd_ib_cmd_create_qp ( struct usd_device * dev , struct usd_qp_impl * qp , struct usd_vf_info * vfip ) { struct usnic_create_qp cmd ; struct usnic_create_qp_resp * resp ; struct ibv_create_qp * icp ; struct ibv_create_qp_resp * irp = NULL ; struct usnic_ib_create_qp_cmd * ucp ; struct usnic_ib_create_qp_resp * urp ; struct usd_qp_filter * qfilt ; int ret ; int n ; uint32_t i ; irp = NULL ; memset ( & cmd , 0 , sizeof ( cmd ) ) ; resp = calloc ( 1 , sizeof ( * resp ) + RES_TYPE_MAX * sizeof ( struct usnic_vnic_barres_info ) ) ; if ( resp == NULL ) { usd_err ( " \n " ) ; return - ENOMEM ; } icp = & cmd . ibv_cmd ; icp -> command = IB_USER_VERBS_CMD_CREATE_QP ; icp -> in_words = sizeof ( cmd ) / 4 ; icp -> out_words = ( sizeof ( * resp ) + RES_TYPE_MAX * sizeof ( struct usnic_vnic_barres_info ) ) / 4 ; icp -> response = ( uintptr_t ) resp ; icp -> user_handle = ( uintptr_t ) qp ; icp -> pd_handle = dev -> ud_pd_handle ; icp -> send_cq_handle = qp -> uq_wq . uwq_cq -> ucq_handle ; icp -> recv_cq_handle = qp -> uq_rq . urq_cq -> ucq_handle ; icp -> srq_handle = 0 ; icp -> max_send_wr = qp -> uq_wq . uwq_num_entries ; icp -> max_recv_wr = qp -> uq_rq . urq_num_entries ; icp -> max_send_sge = 1 ; icp -> max_recv_sge = 1 ; icp -> max_inline_data = 1024 ; icp -> sq_sig_all = 0 ; icp -> qp_type = IBV_QPT_UD ; icp -> is_srq = 0 ; icp -> reserved = 0 ; ucp = & cmd . usnic_cmd ; ucp -> cmd_version = USNIC_IB_CREATE_QP_VERSION ; qfilt = & qp -> uq_filter ; if ( qfilt -> qf_type == USD_FTY_UDP || qfilt -> qf_type == USD_FTY_UDP_SOCK ) { ucp -> spec . trans_type = USNIC_TRANSPORT_IPV4_UDP ; ucp -> spec . udp . sock_fd = qfilt -> qf_filter . qf_udp . u_sockfd ; } else { ret = - EINVAL ; goto out ; } n = write ( dev -> ud_ib_dev_fd , & cmd , sizeof ( cmd ) ) ; if ( n != sizeof ( cmd ) ) { ret = - errno ; goto out ; } irp = & resp -> ibv_resp ; qp -> uq_qp_handle = irp -> qp_handle ; qp -> uq_qp_num = irp -> qpn ; urp = & resp -> usnic_resp ; qp -> uq_rq . urq_index = urp -> rq_idx [ 0 ] ; qp -> uq_wq . uwq_index = urp -> wq_idx [ 0 ] ; qp -> uq_rq . urq_cq -> ucq_index = urp -> cq_idx [ 0 ] ; if ( qp -> uq_rq . urq_cq != qp -> uq_wq . uwq_cq ) { qp -> uq_wq . uwq_cq -> ucq_index = urp -> cq_idx [ 1 ] ; } vfip -> vi_vfid = urp -> vfid ; vfip -> vi_bar_bus_addr = urp -> bar_bus_addr ; vfip -> vi_bar_len = urp -> bar_len ; if ( dev -> ud_caps [ USD_CAP_MAP_PER_RES ] > 0 ) { for ( i = 0 ; i < urp -> num_barres ; i ++ ) { enum vnic_res_type type = urp -> resources [ i ] . type ; if ( type < RES_TYPE_MAX ) { vfip -> barres [ type ] . type = type ; vfip -> barres [ type ] . bus_addr = urp -> resources [ i ] . bus_addr ; vfip -> barres [ type ] . len = urp -> resources [ i ] . len ; } } if ( vfip -> barres [ RES_TYPE_WQ ] . bus_addr == 0 ) { usd_err ( " \n " ) ; ret = - ENXIO ; goto out ; } if ( vfip -> barres [ RES_TYPE_RQ ] . bus_addr == 0 ) { usd_err ( " \n " ) ; ret = - ENXIO ; goto out ; } if ( vfip -> barres [ RES_TYPE_CQ ] . bus_addr == 0 ) { usd_err ( " \n " ) ; ret = - ENXIO ; goto out ; } if ( vfip -> barres [ RES_TYPE_INTR_CTRL ] . bus_addr == 0 ) { usd_err ( " \n " ) ; ret = - ENXIO ; goto out ; } if ( vfip -> barres [ RES_TYPE_DEVCMD ] . bus_addr == 0 ) { usd_err ( " \n " ) ; ret = - ENXIO ; goto out ; } } free ( resp ) ; return 0 ; out : if ( irp != NULL ) usd_ib_cmd_destroy_qp ( dev , qp ) ; free ( resp ) ; return ret ; }
Create a verbs QP without attaching any real resources to it yet
Create a verbs QP without attaching any real resources to it yet
/* Issue command to IB driver */ /* process IB part of response */ /* process usnic part response */ /* Pull VF info */ /* indicates successful IB create QP */