/* QLogic qedr NIC Driver * Copyright (c) 2015-2016 QLogic Corporation * * 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 * OpenIB.org 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/dma-mapping.h> #include <linux/crc32.h> #include <linux/iommu.h> #include <net/ip.h> #include <net/ipv6.h> #include <net/udp.h>
cq = get_qedr_cq(attrs->recv_cq); /* if a dedicated recv_cq was used, delete it too */ if (iparams.icid != cq->icid) {
iparams.icid = cq->icid;
dev->ops->rdma_destroy_cq(dev->rdma_ctx, &iparams, &oparams);
dev->ops->common->chain_free(dev->cdev, &cq->pbl);
}
}
staticinlineint qedr_check_gsi_qp_attrs(struct qedr_dev *dev, struct ib_qp_init_attr *attrs)
{ if (attrs->cap.max_recv_sge > QEDR_GSI_MAX_RECV_SGE) {
DP_ERR(dev, " create gsi qp: failed. max_recv_sge is larger the max %d>%d\n",
attrs->cap.max_recv_sge, QEDR_GSI_MAX_RECV_SGE); return -EINVAL;
}
if (attrs->cap.max_recv_wr > QEDR_GSI_MAX_RECV_WR) {
DP_ERR(dev, " create gsi qp: failed. max_recv_wr is too large %d>%d\n",
attrs->cap.max_recv_wr, QEDR_GSI_MAX_RECV_WR); return -EINVAL;
}
if (attrs->cap.max_send_wr > QEDR_GSI_MAX_SEND_WR) {
DP_ERR(dev, " create gsi qp: failed. max_send_wr is too large %d>%d\n",
attrs->cap.max_send_wr, QEDR_GSI_MAX_SEND_WR); return -EINVAL;
}
return 0;
}
staticint qedr_ll2_post_tx(struct qedr_dev *dev, struct qed_roce_ll2_packet *pkt)
{ enum qed_ll2_roce_flavor_type roce_flavor; struct qed_ll2_tx_pkt_info ll2_tx_pkt; int rc; int i;
/* tx payload */ for (i = 0; i < pkt->n_seg; i++) {
rc = dev->ops->ll2_set_fragment_of_tx_packet(
dev->rdma_ctx,
dev->gsi_ll2_handle,
pkt->payload[i].baddr,
pkt->payload[i].len);
if (rc) { /* if failed not much to do here, partial packet has * been posted we can't free memory, will need to wait * for completion
*/
DP_ERR(dev, "ll2 tx: payload failed (rc=%d)\n", rc); return rc;
}
}
return 0;
}
staticint qedr_ll2_stop(struct qedr_dev *dev)
{ int rc;
if (dev->gsi_ll2_handle == QED_LL2_UNUSED_HANDLE) return 0;
if (qp->state != QED_ROCE_QP_STATE_RTS) {
*bad_wr = wr;
DP_ERR(dev, "gsi post recv: failed to post rx buffer. state is %d and not QED_ROCE_QP_STATE_RTS\n",
qp->state); return -EINVAL;
}
if (wr->num_sge > RDMA_MAX_SGE_PER_SQ_WQE) {
DP_ERR(dev, "gsi post send: num_sge is too large (%d>%d)\n",
wr->num_sge, RDMA_MAX_SGE_PER_SQ_WQE);
rc = -EINVAL; goto err;
}
if (wr->opcode != IB_WR_SEND) {
DP_ERR(dev, "gsi post send: failed due to unsupported opcode %d\n",
wr->opcode);
rc = -EINVAL; goto err;
}
if ((qp->state != QED_ROCE_QP_STATE_RTR) &&
(qp->state != QED_ROCE_QP_STATE_RTS)) {
*bad_wr = wr;
DP_ERR(dev, "gsi post recv: failed to post rx buffer. state is %d and not QED_ROCE_QP_STATE_RTR/S\n",
qp->state); return -EINVAL;
}
spin_lock_irqsave(&qp->q_lock, flags);
while (wr) { if (wr->num_sge > QEDR_GSI_MAX_RECV_SGE) {
DP_ERR(dev, "gsi post recv: failed to post rx buffer. too many sges %d>%d\n",
wr->num_sge, QEDR_GSI_MAX_RECV_SGE); goto err;
}
rc = dev->ops->ll2_post_rx_buffer(dev->rdma_ctx,
dev->gsi_ll2_handle,
wr->sg_list[0].addr,
wr->sg_list[0].length,
NULL /* cookie */,
1 /* notify_fw */); if (rc) {
DP_ERR(dev, "gsi post recv: failed to post rx buffer (rc=%d)\n",
rc); goto err;
}
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.