root/drivers/infiniband/hw/cxgb3/iwch_ev.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. post_qp_event
  2. iwch_ev_dispatch

   1 /*
   2  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
   3  *
   4  * This software is available to you under a choice of one of two
   5  * licenses.  You may choose to be licensed under the terms of the GNU
   6  * General Public License (GPL) Version 2, available from the file
   7  * COPYING in the main directory of this source tree, or the
   8  * OpenIB.org BSD license below:
   9  *
  10  *     Redistribution and use in source and binary forms, with or
  11  *     without modification, are permitted provided that the following
  12  *     conditions are met:
  13  *
  14  *      - Redistributions of source code must retain the above
  15  *        copyright notice, this list of conditions and the following
  16  *        disclaimer.
  17  *
  18  *      - Redistributions in binary form must reproduce the above
  19  *        copyright notice, this list of conditions and the following
  20  *        disclaimer in the documentation and/or other materials
  21  *        provided with the distribution.
  22  *
  23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30  * SOFTWARE.
  31  */
  32 #include <linux/gfp.h>
  33 #include <linux/mman.h>
  34 #include <net/sock.h>
  35 #include "iwch_provider.h"
  36 #include "iwch.h"
  37 #include "iwch_cm.h"
  38 #include "cxio_hal.h"
  39 #include "cxio_wr.h"
  40 
  41 static void post_qp_event(struct iwch_dev *rnicp, struct iwch_cq *chp,
  42                           struct respQ_msg_t *rsp_msg,
  43                           enum ib_event_type ib_event,
  44                           int send_term)
  45 {
  46         struct ib_event event;
  47         struct iwch_qp_attributes attrs;
  48         struct iwch_qp *qhp;
  49         unsigned long flag;
  50 
  51         xa_lock(&rnicp->qps);
  52         qhp = xa_load(&rnicp->qps, CQE_QPID(rsp_msg->cqe));
  53 
  54         if (!qhp) {
  55                 pr_err("%s unaffiliated error 0x%x qpid 0x%x\n",
  56                        __func__, CQE_STATUS(rsp_msg->cqe),
  57                        CQE_QPID(rsp_msg->cqe));
  58                 xa_unlock(&rnicp->qps);
  59                 return;
  60         }
  61 
  62         if ((qhp->attr.state == IWCH_QP_STATE_ERROR) ||
  63             (qhp->attr.state == IWCH_QP_STATE_TERMINATE)) {
  64                 pr_debug("%s AE received after RTS - qp state %d qpid 0x%x status 0x%x\n",
  65                          __func__,
  66                          qhp->attr.state, qhp->wq.qpid,
  67                          CQE_STATUS(rsp_msg->cqe));
  68                 xa_unlock(&rnicp->qps);
  69                 return;
  70         }
  71 
  72         pr_err("%s - AE qpid 0x%x opcode %d status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x\n",
  73                __func__,
  74                CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
  75                CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
  76                CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
  77 
  78         atomic_inc(&qhp->refcnt);
  79         xa_unlock(&rnicp->qps);
  80 
  81         if (qhp->attr.state == IWCH_QP_STATE_RTS) {
  82                 attrs.next_state = IWCH_QP_STATE_TERMINATE;
  83                 iwch_modify_qp(qhp->rhp, qhp, IWCH_QP_ATTR_NEXT_STATE,
  84                                &attrs, 1);
  85                 if (send_term)
  86                         iwch_post_terminate(qhp, rsp_msg);
  87         }
  88 
  89         event.event = ib_event;
  90         event.device = chp->ibcq.device;
  91         if (ib_event == IB_EVENT_CQ_ERR)
  92                 event.element.cq = &chp->ibcq;
  93         else
  94                 event.element.qp = &qhp->ibqp;
  95 
  96         if (qhp->ibqp.event_handler)
  97                 (*qhp->ibqp.event_handler)(&event, qhp->ibqp.qp_context);
  98 
  99         spin_lock_irqsave(&chp->comp_handler_lock, flag);
 100         (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
 101         spin_unlock_irqrestore(&chp->comp_handler_lock, flag);
 102 
 103         if (atomic_dec_and_test(&qhp->refcnt))
 104                 wake_up(&qhp->wait);
 105 }
 106 
 107 void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb)
 108 {
 109         struct iwch_dev *rnicp;
 110         struct respQ_msg_t *rsp_msg = (struct respQ_msg_t *) skb->data;
 111         struct iwch_cq *chp;
 112         struct iwch_qp *qhp;
 113         u32 cqid = RSPQ_CQID(rsp_msg);
 114         unsigned long flag;
 115 
 116         rnicp = (struct iwch_dev *) rdev_p->ulp;
 117         xa_lock(&rnicp->qps);
 118         chp = get_chp(rnicp, cqid);
 119         qhp = xa_load(&rnicp->qps, CQE_QPID(rsp_msg->cqe));
 120         if (!chp || !qhp) {
 121                 pr_err("BAD AE cqid 0x%x qpid 0x%x opcode %d status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x\n",
 122                        cqid, CQE_QPID(rsp_msg->cqe),
 123                        CQE_OPCODE(rsp_msg->cqe), CQE_STATUS(rsp_msg->cqe),
 124                        CQE_TYPE(rsp_msg->cqe), CQE_WRID_HI(rsp_msg->cqe),
 125                        CQE_WRID_LOW(rsp_msg->cqe));
 126                 xa_unlock(&rnicp->qps);
 127                 goto out;
 128         }
 129         iwch_qp_add_ref(&qhp->ibqp);
 130         atomic_inc(&chp->refcnt);
 131         xa_unlock(&rnicp->qps);
 132 
 133         /*
 134          * 1) completion of our sending a TERMINATE.
 135          * 2) incoming TERMINATE message.
 136          */
 137         if ((CQE_OPCODE(rsp_msg->cqe) == T3_TERMINATE) &&
 138             (CQE_STATUS(rsp_msg->cqe) == 0)) {
 139                 if (SQ_TYPE(rsp_msg->cqe)) {
 140                         pr_debug("%s QPID 0x%x ep %p disconnecting\n",
 141                                  __func__, qhp->wq.qpid, qhp->ep);
 142                         iwch_ep_disconnect(qhp->ep, 0, GFP_ATOMIC);
 143                 } else {
 144                         pr_debug("%s post REQ_ERR AE QPID 0x%x\n", __func__,
 145                                  qhp->wq.qpid);
 146                         post_qp_event(rnicp, chp, rsp_msg,
 147                                       IB_EVENT_QP_REQ_ERR, 0);
 148                         iwch_ep_disconnect(qhp->ep, 0, GFP_ATOMIC);
 149                 }
 150                 goto done;
 151         }
 152 
 153         /* Bad incoming Read request */
 154         if (SQ_TYPE(rsp_msg->cqe) &&
 155             (CQE_OPCODE(rsp_msg->cqe) == T3_READ_RESP)) {
 156                 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_REQ_ERR, 1);
 157                 goto done;
 158         }
 159 
 160         /* Bad incoming write */
 161         if (RQ_TYPE(rsp_msg->cqe) &&
 162             (CQE_OPCODE(rsp_msg->cqe) == T3_RDMA_WRITE)) {
 163                 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_REQ_ERR, 1);
 164                 goto done;
 165         }
 166 
 167         switch (CQE_STATUS(rsp_msg->cqe)) {
 168 
 169         /* Completion Events */
 170         case TPT_ERR_SUCCESS:
 171 
 172                 /*
 173                  * Confirm the destination entry if this is a RECV completion.
 174                  */
 175                 if (qhp->ep && SQ_TYPE(rsp_msg->cqe))
 176                         dst_confirm(qhp->ep->dst);
 177                 spin_lock_irqsave(&chp->comp_handler_lock, flag);
 178                 (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
 179                 spin_unlock_irqrestore(&chp->comp_handler_lock, flag);
 180                 break;
 181 
 182         case TPT_ERR_STAG:
 183         case TPT_ERR_PDID:
 184         case TPT_ERR_QPID:
 185         case TPT_ERR_ACCESS:
 186         case TPT_ERR_WRAP:
 187         case TPT_ERR_BOUND:
 188         case TPT_ERR_INVALIDATE_SHARED_MR:
 189         case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
 190                 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
 191                 break;
 192 
 193         /* Device Fatal Errors */
 194         case TPT_ERR_ECC:
 195         case TPT_ERR_ECC_PSTAG:
 196         case TPT_ERR_INTERNAL_ERR:
 197                 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_DEVICE_FATAL, 1);
 198                 break;
 199 
 200         /* QP Fatal Errors */
 201         case TPT_ERR_OUT_OF_RQE:
 202         case TPT_ERR_PBL_ADDR_BOUND:
 203         case TPT_ERR_CRC:
 204         case TPT_ERR_MARKER:
 205         case TPT_ERR_PDU_LEN_ERR:
 206         case TPT_ERR_DDP_VERSION:
 207         case TPT_ERR_RDMA_VERSION:
 208         case TPT_ERR_OPCODE:
 209         case TPT_ERR_DDP_QUEUE_NUM:
 210         case TPT_ERR_MSN:
 211         case TPT_ERR_TBIT:
 212         case TPT_ERR_MO:
 213         case TPT_ERR_MSN_GAP:
 214         case TPT_ERR_MSN_RANGE:
 215         case TPT_ERR_RQE_ADDR_BOUND:
 216         case TPT_ERR_IRD_OVERFLOW:
 217                 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_FATAL, 1);
 218                 break;
 219 
 220         default:
 221                 pr_err("Unknown T3 status 0x%x QPID 0x%x\n",
 222                        CQE_STATUS(rsp_msg->cqe), qhp->wq.qpid);
 223                 post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_FATAL, 1);
 224                 break;
 225         }
 226 done:
 227         if (atomic_dec_and_test(&chp->refcnt))
 228                 wake_up(&chp->wait);
 229         iwch_qp_rem_ref(&qhp->ibqp);
 230 out:
 231         dev_kfree_skb_irq(skb);
 232 }

/* [<][>][^][v][top][bottom][index][help] */