/* * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *
*/ #include <linux/init.h> #include <linux/slab.h> #include <linux/errno.h>
us_ibdev = qp_grp->vf->pf;
pdev = usnic_vnic_get_pdev(qp_grp->vf->vnic); if (!pdev) {
usnic_err("Failed to get pdev of qp_grp %d\n",
qp_grp->grp_id); return -EFAULT;
}
bar = usnic_vnic_get_bar(qp_grp->vf->vnic, 0); if (!bar) {
usnic_err("Failed to get bar0 of qp_grp %d vf %s",
qp_grp->grp_id, pci_name(pdev)); return -EFAULT;
}
chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_RQ); if (IS_ERR(chunk)) {
usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_RQ),
qp_grp->grp_id,
PTR_ERR(chunk)); return PTR_ERR(chunk);
}
WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_RQ);
resp.rq_cnt = chunk->cnt; for (i = 0; i < chunk->cnt; i++)
resp.rq_idx[i] = chunk->res[i]->vnic_idx;
chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_WQ); if (IS_ERR(chunk)) {
usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_WQ),
qp_grp->grp_id,
PTR_ERR(chunk)); return PTR_ERR(chunk);
}
WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_WQ);
resp.wq_cnt = chunk->cnt; for (i = 0; i < chunk->cnt; i++)
resp.wq_idx[i] = chunk->res[i]->vnic_idx;
chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_CQ); if (IS_ERR(chunk)) {
usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_CQ),
qp_grp->grp_id,
PTR_ERR(chunk)); return PTR_ERR(chunk);
}
WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_CQ);
resp.cq_cnt = chunk->cnt; for (i = 0; i < chunk->cnt; i++)
resp.cq_idx[i] = chunk->res[i]->vnic_idx;
if (list_empty(&us_ibdev->vf_dev_list)) {
usnic_info("No vfs to allocate\n"); return -ENOMEM;
}
if (usnic_ib_share_vf) { /* Try to find resouces on a used vf which is in pd */
dev_list = usnic_uiom_get_dev_list(pd->umem_pd); if (IS_ERR(dev_list)) return PTR_ERR(dev_list); for (i = 0; dev_list[i]; i++) {
dev = dev_list[i];
vf = dev_get_drvdata(dev);
mutex_lock(&vf->lock);
vnic = vf->vnic; if (!usnic_vnic_check_room(vnic, res_spec)) {
usnic_dbg("Found used vnic %s from %s\n",
dev_name(&us_ibdev->ib_dev.dev),
pci_name(usnic_vnic_get_pdev(
vnic)));
ret = usnic_ib_qp_grp_create(qp_grp,
us_ibdev->ufdev,
vf, pd, res_spec,
trans_spec);
if (ib_get_eth_speed(ibdev, port, &props->active_speed,
&props->active_width)) return -EINVAL;
/* * usdev_lock is acquired after (and not before) ib_get_eth_speed call * because acquiring rtnl_lock in ib_get_eth_speed, while holding * usdev_lock could lead to a deadlock.
*/
mutex_lock(&us_ibdev->usdev_lock); /* props being zeroed by the caller, avoid zeroing it here */
err = ib_copy_from_udata(&cmd, udata, sizeof(cmd)); if (err) {
usnic_err("%s: cannot copy udata for create_qp\n",
dev_name(&us_ibdev->ib_dev.dev)); return -EINVAL;
}
err = create_qp_validate_user_data(cmd); if (err) {
usnic_err("%s: Failed to validate user data\n",
dev_name(&us_ibdev->ib_dev.dev)); return -EINVAL;
}
if (init_attr->qp_type != IB_QPT_UD) {
usnic_err("%s asked to make a non-UD QP: %d\n",
dev_name(&us_ibdev->ib_dev.dev), init_attr->qp_type); return -EOPNOTSUPP;
}
int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata)
{ struct usnic_ib_qp_grp *qp_grp; int status;
usnic_dbg("\n");
if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS) return -EOPNOTSUPP;
qp_grp = to_uqp_grp(ibqp);
mutex_lock(&qp_grp->vf->pf->usdev_lock); if ((attr_mask & IB_QP_PORT) && attr->port_num != 1) { /* usnic devices only have one port */
status = -EINVAL; goto out_unlock;
} if (attr_mask & IB_QP_STATE) {
status = usnic_ib_qp_grp_modify(qp_grp, attr->qp_state, NULL);
} else {
usnic_err("Unhandled request, attr_mask=0x%x\n", attr_mask);
status = -EINVAL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.