Path: blob/master/drivers/infiniband/hw/cxgb3/iwch_ev.c
15112 views
/*1* Copyright (c) 2006 Chelsio, Inc. All rights reserved.2*3* This software is available to you under a choice of one of two4* licenses. You may choose to be licensed under the terms of the GNU5* General Public License (GPL) Version 2, available from the file6* COPYING in the main directory of this source tree, or the7* OpenIB.org BSD license below:8*9* Redistribution and use in source and binary forms, with or10* without modification, are permitted provided that the following11* conditions are met:12*13* - Redistributions of source code must retain the above14* copyright notice, this list of conditions and the following15* disclaimer.16*17* - Redistributions in binary form must reproduce the above18* copyright notice, this list of conditions and the following19* disclaimer in the documentation and/or other materials20* provided with the distribution.21*22* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,23* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF24* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND25* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS26* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN27* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN28* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE29* SOFTWARE.30*/31#include <linux/gfp.h>32#include <linux/mman.h>33#include <net/sock.h>34#include "iwch_provider.h"35#include "iwch.h"36#include "iwch_cm.h"37#include "cxio_hal.h"38#include "cxio_wr.h"3940static void post_qp_event(struct iwch_dev *rnicp, struct iwch_cq *chp,41struct respQ_msg_t *rsp_msg,42enum ib_event_type ib_event,43int send_term)44{45struct ib_event event;46struct iwch_qp_attributes attrs;47struct iwch_qp *qhp;4849spin_lock(&rnicp->lock);50qhp = get_qhp(rnicp, CQE_QPID(rsp_msg->cqe));5152if (!qhp) {53printk(KERN_ERR "%s unaffiliated error 0x%x qpid 0x%x\n",54__func__, CQE_STATUS(rsp_msg->cqe),55CQE_QPID(rsp_msg->cqe));56spin_unlock(&rnicp->lock);57return;58}5960if ((qhp->attr.state == IWCH_QP_STATE_ERROR) ||61(qhp->attr.state == IWCH_QP_STATE_TERMINATE)) {62PDBG("%s AE received after RTS - "63"qp state %d qpid 0x%x status 0x%x\n", __func__,64qhp->attr.state, qhp->wq.qpid, CQE_STATUS(rsp_msg->cqe));65spin_unlock(&rnicp->lock);66return;67}6869printk(KERN_ERR "%s - AE qpid 0x%x opcode %d status 0x%x "70"type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__,71CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),72CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),73CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));7475atomic_inc(&qhp->refcnt);76spin_unlock(&rnicp->lock);7778if (qhp->attr.state == IWCH_QP_STATE_RTS) {79attrs.next_state = IWCH_QP_STATE_TERMINATE;80iwch_modify_qp(qhp->rhp, qhp, IWCH_QP_ATTR_NEXT_STATE,81&attrs, 1);82if (send_term)83iwch_post_terminate(qhp, rsp_msg);84}8586event.event = ib_event;87event.device = chp->ibcq.device;88if (ib_event == IB_EVENT_CQ_ERR)89event.element.cq = &chp->ibcq;90else91event.element.qp = &qhp->ibqp;9293if (qhp->ibqp.event_handler)94(*qhp->ibqp.event_handler)(&event, qhp->ibqp.qp_context);9596(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);9798if (atomic_dec_and_test(&qhp->refcnt))99wake_up(&qhp->wait);100}101102void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb)103{104struct iwch_dev *rnicp;105struct respQ_msg_t *rsp_msg = (struct respQ_msg_t *) skb->data;106struct iwch_cq *chp;107struct iwch_qp *qhp;108u32 cqid = RSPQ_CQID(rsp_msg);109110rnicp = (struct iwch_dev *) rdev_p->ulp;111spin_lock(&rnicp->lock);112chp = get_chp(rnicp, cqid);113qhp = get_qhp(rnicp, CQE_QPID(rsp_msg->cqe));114if (!chp || !qhp) {115printk(KERN_ERR MOD "BAD AE cqid 0x%x qpid 0x%x opcode %d "116"status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x \n",117cqid, CQE_QPID(rsp_msg->cqe),118CQE_OPCODE(rsp_msg->cqe), CQE_STATUS(rsp_msg->cqe),119CQE_TYPE(rsp_msg->cqe), CQE_WRID_HI(rsp_msg->cqe),120CQE_WRID_LOW(rsp_msg->cqe));121spin_unlock(&rnicp->lock);122goto out;123}124iwch_qp_add_ref(&qhp->ibqp);125atomic_inc(&chp->refcnt);126spin_unlock(&rnicp->lock);127128/*129* 1) completion of our sending a TERMINATE.130* 2) incoming TERMINATE message.131*/132if ((CQE_OPCODE(rsp_msg->cqe) == T3_TERMINATE) &&133(CQE_STATUS(rsp_msg->cqe) == 0)) {134if (SQ_TYPE(rsp_msg->cqe)) {135PDBG("%s QPID 0x%x ep %p disconnecting\n",136__func__, qhp->wq.qpid, qhp->ep);137iwch_ep_disconnect(qhp->ep, 0, GFP_ATOMIC);138} else {139PDBG("%s post REQ_ERR AE QPID 0x%x\n", __func__,140qhp->wq.qpid);141post_qp_event(rnicp, chp, rsp_msg,142IB_EVENT_QP_REQ_ERR, 0);143iwch_ep_disconnect(qhp->ep, 0, GFP_ATOMIC);144}145goto done;146}147148/* Bad incoming Read request */149if (SQ_TYPE(rsp_msg->cqe) &&150(CQE_OPCODE(rsp_msg->cqe) == T3_READ_RESP)) {151post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_REQ_ERR, 1);152goto done;153}154155/* Bad incoming write */156if (RQ_TYPE(rsp_msg->cqe) &&157(CQE_OPCODE(rsp_msg->cqe) == T3_RDMA_WRITE)) {158post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_REQ_ERR, 1);159goto done;160}161162switch (CQE_STATUS(rsp_msg->cqe)) {163164/* Completion Events */165case TPT_ERR_SUCCESS:166167/*168* Confirm the destination entry if this is a RECV completion.169*/170if (qhp->ep && SQ_TYPE(rsp_msg->cqe))171dst_confirm(qhp->ep->dst);172(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);173break;174175case TPT_ERR_STAG:176case TPT_ERR_PDID:177case TPT_ERR_QPID:178case TPT_ERR_ACCESS:179case TPT_ERR_WRAP:180case TPT_ERR_BOUND:181case TPT_ERR_INVALIDATE_SHARED_MR:182case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:183post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);184break;185186/* Device Fatal Errors */187case TPT_ERR_ECC:188case TPT_ERR_ECC_PSTAG:189case TPT_ERR_INTERNAL_ERR:190post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_DEVICE_FATAL, 1);191break;192193/* QP Fatal Errors */194case TPT_ERR_OUT_OF_RQE:195case TPT_ERR_PBL_ADDR_BOUND:196case TPT_ERR_CRC:197case TPT_ERR_MARKER:198case TPT_ERR_PDU_LEN_ERR:199case TPT_ERR_DDP_VERSION:200case TPT_ERR_RDMA_VERSION:201case TPT_ERR_OPCODE:202case TPT_ERR_DDP_QUEUE_NUM:203case TPT_ERR_MSN:204case TPT_ERR_TBIT:205case TPT_ERR_MO:206case TPT_ERR_MSN_GAP:207case TPT_ERR_MSN_RANGE:208case TPT_ERR_RQE_ADDR_BOUND:209case TPT_ERR_IRD_OVERFLOW:210post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_FATAL, 1);211break;212213default:214printk(KERN_ERR MOD "Unknown T3 status 0x%x QPID 0x%x\n",215CQE_STATUS(rsp_msg->cqe), qhp->wq.qpid);216post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_FATAL, 1);217break;218}219done:220if (atomic_dec_and_test(&chp->refcnt))221wake_up(&chp->wait);222iwch_qp_rem_ref(&qhp->ibqp);223out:224dev_kfree_skb_irq(skb);225}226227228