int siw_ofed_modify_qp(struct ib_qp *ofa_qp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata) { struct siw_qp_attrs new_attrs; enum siw_qp_attr_mask siw_attr_mask = 0; struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp); int rv = 0; if (!attr_mask) { dprint(DBG_CM, "(QP%d): attr_mask==0 ignored\n", QP_ID(qp)); goto out; } siw_dprint_qp_attr_mask(attr_mask); memset(&new_attrs, 0, sizeof new_attrs); if (attr_mask & IB_QP_ACCESS_FLAGS) { siw_attr_mask |= SIW_QP_ATTR_ACCESS_FLAGS; if (attr->qp_access_flags & IB_ACCESS_REMOTE_READ) new_attrs.flags |= SIW_RDMA_READ_ENABLED; if (attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE) new_attrs.flags |= SIW_RDMA_WRITE_ENABLED; if (attr->qp_access_flags & IB_ACCESS_MW_BIND) new_attrs.flags |= SIW_RDMA_BIND_ENABLED; } if (attr_mask & IB_QP_STATE) { dprint(DBG_CM, "(QP%d): Desired IB QP state: %s\n", QP_ID(qp), ib_qp_state_to_string[attr->qp_state]); new_attrs.state = ib_qp_state_to_siw_qp_state[attr->qp_state]; if (new_attrs.state > SIW_QP_STATE_RTS) qp->tx_ctx.tx_suspend = 1; /* TODO: SIW_QP_STATE_UNDEF is currently not possible ... */ if (new_attrs.state == SIW_QP_STATE_UNDEF) return -EINVAL; siw_attr_mask |= SIW_QP_ATTR_STATE; } if (!attr_mask) goto out; down_write(&qp->state_lock); rv = siw_qp_modify(qp, &new_attrs, siw_attr_mask); up_write(&qp->state_lock); out: dprint(DBG_CM, "(QP%d): Exit with %d\n", QP_ID(qp), rv); return rv; }
int siw_destroy_qp(struct ib_qp *ofa_qp) { struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp); struct siw_qp_attrs qp_attrs; dprint(DBG_CM, "(QP%d): SIW QP state=%d, cep=0x%p\n", QP_ID(qp), qp->attrs.state, qp->cep); /* * Mark QP as in process of destruction to prevent from eventual async * callbacks to OFA core */ qp->attrs.flags |= SIW_QP_IN_DESTROY; qp->rx_ctx.rx_suspend = 1; down_write(&qp->state_lock); qp_attrs.state = SIW_QP_STATE_ERROR; (void)siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE); if (qp->cep) { siw_cep_put(qp->cep); qp->cep = NULL; } up_write(&qp->state_lock); if (qp->rx_ctx.crc_enabled) crypto_free_hash(qp->rx_ctx.mpa_crc_hd.tfm); if (qp->tx_ctx.crc_enabled) crypto_free_hash(qp->tx_ctx.mpa_crc_hd.tfm); /* Drop references */ siw_cq_put(qp->scq); siw_cq_put(qp->rcq); siw_pd_put(qp->pd); qp->scq = qp->rcq = NULL; siw_qp_put(qp); return 0; }
int siw_destroy_qp(struct ib_qp *ofa_qp) { struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp); struct siw_qp_attrs qp_attrs; pr_debug(DBG_CM "(QP%d): SIW QP state=%d, cep=0x%p\n", QP_ID(qp), qp->attrs.state, qp->cep); /* * Mark QP as in process of destruction to prevent from eventual async * callbacks to OFA core */ qp->attrs.flags |= SIW_QP_IN_DESTROY; down_write(&qp->state_lock); qp_attrs.state = SIW_QP_STATE_ERROR; (void)siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE); if (qp->cep) { siw_cep_put(qp->cep); qp->cep = NULL; } up_write(&qp->state_lock); /* Drop references */ siw_cq_put(qp->scq); siw_cq_put(qp->rcq); siw_pd_put(qp->pd); qp->scq = qp->rcq = NULL; siw_qp_put(qp); return 0; }