1*fb93f5c4SNavdeep Parhar /* 2*fb93f5c4SNavdeep Parhar * Copyright (c) 2009-2013 Chelsio, Inc. All rights reserved. 3*fb93f5c4SNavdeep Parhar * 4*fb93f5c4SNavdeep Parhar * This software is available to you under a choice of one of two 5*fb93f5c4SNavdeep Parhar * licenses. You may choose to be licensed under the terms of the GNU 6*fb93f5c4SNavdeep Parhar * General Public License (GPL) Version 2, available from the file 7*fb93f5c4SNavdeep Parhar * COPYING in the main directory of this source tree, or the 8*fb93f5c4SNavdeep Parhar * OpenIB.org BSD license below: 9*fb93f5c4SNavdeep Parhar * 10*fb93f5c4SNavdeep Parhar * Redistribution and use in source and binary forms, with or 11*fb93f5c4SNavdeep Parhar * without modification, are permitted provided that the following 12*fb93f5c4SNavdeep Parhar * conditions are met: 13*fb93f5c4SNavdeep Parhar * 14*fb93f5c4SNavdeep Parhar * - Redistributions of source code must retain the above 15*fb93f5c4SNavdeep Parhar * copyright notice, this list of conditions and the following 16*fb93f5c4SNavdeep Parhar * disclaimer. 17*fb93f5c4SNavdeep Parhar * 18*fb93f5c4SNavdeep Parhar * - Redistributions in binary form must reproduce the above 19*fb93f5c4SNavdeep Parhar * copyright notice, this list of conditions and the following 20*fb93f5c4SNavdeep Parhar * disclaimer in the documentation and/or other materials 21*fb93f5c4SNavdeep Parhar * provided with the distribution. 22*fb93f5c4SNavdeep Parhar * 23*fb93f5c4SNavdeep Parhar * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24*fb93f5c4SNavdeep Parhar * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25*fb93f5c4SNavdeep Parhar * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26*fb93f5c4SNavdeep Parhar * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27*fb93f5c4SNavdeep Parhar * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28*fb93f5c4SNavdeep Parhar * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29*fb93f5c4SNavdeep Parhar * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30*fb93f5c4SNavdeep Parhar * SOFTWARE. 31*fb93f5c4SNavdeep Parhar */ 32*fb93f5c4SNavdeep Parhar #include <sys/cdefs.h> 33*fb93f5c4SNavdeep Parhar __FBSDID("$FreeBSD$"); 34*fb93f5c4SNavdeep Parhar 35*fb93f5c4SNavdeep Parhar #include "opt_inet.h" 36*fb93f5c4SNavdeep Parhar 37*fb93f5c4SNavdeep Parhar #ifdef TCP_OFFLOAD 38*fb93f5c4SNavdeep Parhar #include <linux/slab.h> 39*fb93f5c4SNavdeep Parhar 40*fb93f5c4SNavdeep Parhar #include "iw_cxgbe.h" 41*fb93f5c4SNavdeep Parhar 42*fb93f5c4SNavdeep Parhar static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp, 43*fb93f5c4SNavdeep Parhar struct c4iw_qp *qhp, 44*fb93f5c4SNavdeep Parhar struct t4_cqe *err_cqe, 45*fb93f5c4SNavdeep Parhar enum ib_event_type ib_event) 46*fb93f5c4SNavdeep Parhar { 47*fb93f5c4SNavdeep Parhar struct ib_event event; 48*fb93f5c4SNavdeep Parhar struct c4iw_qp_attributes attrs; 49*fb93f5c4SNavdeep Parhar unsigned long flag; 50*fb93f5c4SNavdeep Parhar 51*fb93f5c4SNavdeep Parhar if ((qhp->attr.state == C4IW_QP_STATE_ERROR) || 52*fb93f5c4SNavdeep Parhar (qhp->attr.state == C4IW_QP_STATE_TERMINATE)) { 53*fb93f5c4SNavdeep Parhar CTR4(KTR_IW_CXGBE, "%s AE received after RTS - " 54*fb93f5c4SNavdeep Parhar "qp state %d qpid 0x%x status 0x%x", __func__, 55*fb93f5c4SNavdeep Parhar qhp->attr.state, qhp->wq.sq.qid, CQE_STATUS(err_cqe)); 56*fb93f5c4SNavdeep Parhar return; 57*fb93f5c4SNavdeep Parhar } 58*fb93f5c4SNavdeep Parhar 59*fb93f5c4SNavdeep Parhar printf("AE qpid 0x%x opcode %d status 0x%x " 60*fb93f5c4SNavdeep Parhar "type %d wrid.hi 0x%x wrid.lo 0x%x\n", 61*fb93f5c4SNavdeep Parhar CQE_QPID(err_cqe), CQE_OPCODE(err_cqe), 62*fb93f5c4SNavdeep Parhar CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), 63*fb93f5c4SNavdeep Parhar CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe)); 64*fb93f5c4SNavdeep Parhar 65*fb93f5c4SNavdeep Parhar if (qhp->attr.state == C4IW_QP_STATE_RTS) { 66*fb93f5c4SNavdeep Parhar attrs.next_state = C4IW_QP_STATE_TERMINATE; 67*fb93f5c4SNavdeep Parhar c4iw_modify_qp(qhp->rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, 68*fb93f5c4SNavdeep Parhar &attrs, 0); 69*fb93f5c4SNavdeep Parhar } 70*fb93f5c4SNavdeep Parhar 71*fb93f5c4SNavdeep Parhar event.event = ib_event; 72*fb93f5c4SNavdeep Parhar event.device = chp->ibcq.device; 73*fb93f5c4SNavdeep Parhar if (ib_event == IB_EVENT_CQ_ERR) 74*fb93f5c4SNavdeep Parhar event.element.cq = &chp->ibcq; 75*fb93f5c4SNavdeep Parhar else 76*fb93f5c4SNavdeep Parhar event.element.qp = &qhp->ibqp; 77*fb93f5c4SNavdeep Parhar if (qhp->ibqp.event_handler) 78*fb93f5c4SNavdeep Parhar (*qhp->ibqp.event_handler)(&event, qhp->ibqp.qp_context); 79*fb93f5c4SNavdeep Parhar 80*fb93f5c4SNavdeep Parhar spin_lock_irqsave(&chp->comp_handler_lock, flag); 81*fb93f5c4SNavdeep Parhar (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); 82*fb93f5c4SNavdeep Parhar spin_unlock_irqrestore(&chp->comp_handler_lock, flag); 83*fb93f5c4SNavdeep Parhar } 84*fb93f5c4SNavdeep Parhar 85*fb93f5c4SNavdeep Parhar void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe) 86*fb93f5c4SNavdeep Parhar { 87*fb93f5c4SNavdeep Parhar struct c4iw_cq *chp; 88*fb93f5c4SNavdeep Parhar struct c4iw_qp *qhp; 89*fb93f5c4SNavdeep Parhar u32 cqid; 90*fb93f5c4SNavdeep Parhar 91*fb93f5c4SNavdeep Parhar spin_lock_irq(&dev->lock); 92*fb93f5c4SNavdeep Parhar qhp = get_qhp(dev, CQE_QPID(err_cqe)); 93*fb93f5c4SNavdeep Parhar if (!qhp) { 94*fb93f5c4SNavdeep Parhar printf("BAD AE qpid 0x%x opcode %d " 95*fb93f5c4SNavdeep Parhar "status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x\n", 96*fb93f5c4SNavdeep Parhar CQE_QPID(err_cqe), 97*fb93f5c4SNavdeep Parhar CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe), 98*fb93f5c4SNavdeep Parhar CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe), 99*fb93f5c4SNavdeep Parhar CQE_WRID_LOW(err_cqe)); 100*fb93f5c4SNavdeep Parhar spin_unlock_irq(&dev->lock); 101*fb93f5c4SNavdeep Parhar goto out; 102*fb93f5c4SNavdeep Parhar } 103*fb93f5c4SNavdeep Parhar 104*fb93f5c4SNavdeep Parhar if (SQ_TYPE(err_cqe)) 105*fb93f5c4SNavdeep Parhar cqid = qhp->attr.scq; 106*fb93f5c4SNavdeep Parhar else 107*fb93f5c4SNavdeep Parhar cqid = qhp->attr.rcq; 108*fb93f5c4SNavdeep Parhar chp = get_chp(dev, cqid); 109*fb93f5c4SNavdeep Parhar if (!chp) { 110*fb93f5c4SNavdeep Parhar printf("BAD AE cqid 0x%x qpid 0x%x opcode %d " 111*fb93f5c4SNavdeep Parhar "status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x\n", 112*fb93f5c4SNavdeep Parhar cqid, CQE_QPID(err_cqe), 113*fb93f5c4SNavdeep Parhar CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe), 114*fb93f5c4SNavdeep Parhar CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe), 115*fb93f5c4SNavdeep Parhar CQE_WRID_LOW(err_cqe)); 116*fb93f5c4SNavdeep Parhar spin_unlock_irq(&dev->lock); 117*fb93f5c4SNavdeep Parhar goto out; 118*fb93f5c4SNavdeep Parhar } 119*fb93f5c4SNavdeep Parhar 120*fb93f5c4SNavdeep Parhar c4iw_qp_add_ref(&qhp->ibqp); 121*fb93f5c4SNavdeep Parhar atomic_inc(&chp->refcnt); 122*fb93f5c4SNavdeep Parhar spin_unlock_irq(&dev->lock); 123*fb93f5c4SNavdeep Parhar 124*fb93f5c4SNavdeep Parhar /* Bad incoming write */ 125*fb93f5c4SNavdeep Parhar if (RQ_TYPE(err_cqe) && 126*fb93f5c4SNavdeep Parhar (CQE_OPCODE(err_cqe) == FW_RI_RDMA_WRITE)) { 127*fb93f5c4SNavdeep Parhar post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_REQ_ERR); 128*fb93f5c4SNavdeep Parhar goto done; 129*fb93f5c4SNavdeep Parhar } 130*fb93f5c4SNavdeep Parhar 131*fb93f5c4SNavdeep Parhar switch (CQE_STATUS(err_cqe)) { 132*fb93f5c4SNavdeep Parhar 133*fb93f5c4SNavdeep Parhar /* Completion Events */ 134*fb93f5c4SNavdeep Parhar case T4_ERR_SUCCESS: 135*fb93f5c4SNavdeep Parhar printf(KERN_ERR MOD "AE with status 0!\n"); 136*fb93f5c4SNavdeep Parhar break; 137*fb93f5c4SNavdeep Parhar 138*fb93f5c4SNavdeep Parhar case T4_ERR_STAG: 139*fb93f5c4SNavdeep Parhar case T4_ERR_PDID: 140*fb93f5c4SNavdeep Parhar case T4_ERR_QPID: 141*fb93f5c4SNavdeep Parhar case T4_ERR_ACCESS: 142*fb93f5c4SNavdeep Parhar case T4_ERR_WRAP: 143*fb93f5c4SNavdeep Parhar case T4_ERR_BOUND: 144*fb93f5c4SNavdeep Parhar case T4_ERR_INVALIDATE_SHARED_MR: 145*fb93f5c4SNavdeep Parhar case T4_ERR_INVALIDATE_MR_WITH_MW_BOUND: 146*fb93f5c4SNavdeep Parhar post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_ACCESS_ERR); 147*fb93f5c4SNavdeep Parhar break; 148*fb93f5c4SNavdeep Parhar 149*fb93f5c4SNavdeep Parhar /* Device Fatal Errors */ 150*fb93f5c4SNavdeep Parhar case T4_ERR_ECC: 151*fb93f5c4SNavdeep Parhar case T4_ERR_ECC_PSTAG: 152*fb93f5c4SNavdeep Parhar case T4_ERR_INTERNAL_ERR: 153*fb93f5c4SNavdeep Parhar post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_DEVICE_FATAL); 154*fb93f5c4SNavdeep Parhar break; 155*fb93f5c4SNavdeep Parhar 156*fb93f5c4SNavdeep Parhar /* QP Fatal Errors */ 157*fb93f5c4SNavdeep Parhar case T4_ERR_OUT_OF_RQE: 158*fb93f5c4SNavdeep Parhar case T4_ERR_PBL_ADDR_BOUND: 159*fb93f5c4SNavdeep Parhar case T4_ERR_CRC: 160*fb93f5c4SNavdeep Parhar case T4_ERR_MARKER: 161*fb93f5c4SNavdeep Parhar case T4_ERR_PDU_LEN_ERR: 162*fb93f5c4SNavdeep Parhar case T4_ERR_DDP_VERSION: 163*fb93f5c4SNavdeep Parhar case T4_ERR_RDMA_VERSION: 164*fb93f5c4SNavdeep Parhar case T4_ERR_OPCODE: 165*fb93f5c4SNavdeep Parhar case T4_ERR_DDP_QUEUE_NUM: 166*fb93f5c4SNavdeep Parhar case T4_ERR_MSN: 167*fb93f5c4SNavdeep Parhar case T4_ERR_TBIT: 168*fb93f5c4SNavdeep Parhar case T4_ERR_MO: 169*fb93f5c4SNavdeep Parhar case T4_ERR_MSN_GAP: 170*fb93f5c4SNavdeep Parhar case T4_ERR_MSN_RANGE: 171*fb93f5c4SNavdeep Parhar case T4_ERR_RQE_ADDR_BOUND: 172*fb93f5c4SNavdeep Parhar case T4_ERR_IRD_OVERFLOW: 173*fb93f5c4SNavdeep Parhar post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_FATAL); 174*fb93f5c4SNavdeep Parhar break; 175*fb93f5c4SNavdeep Parhar 176*fb93f5c4SNavdeep Parhar default: 177*fb93f5c4SNavdeep Parhar printf("Unknown T4 status 0x%x QPID 0x%x\n", 178*fb93f5c4SNavdeep Parhar CQE_STATUS(err_cqe), qhp->wq.sq.qid); 179*fb93f5c4SNavdeep Parhar post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_FATAL); 180*fb93f5c4SNavdeep Parhar break; 181*fb93f5c4SNavdeep Parhar } 182*fb93f5c4SNavdeep Parhar done: 183*fb93f5c4SNavdeep Parhar if (atomic_dec_and_test(&chp->refcnt)) 184*fb93f5c4SNavdeep Parhar wake_up(&chp->wait); 185*fb93f5c4SNavdeep Parhar c4iw_qp_rem_ref(&qhp->ibqp); 186*fb93f5c4SNavdeep Parhar out: 187*fb93f5c4SNavdeep Parhar return; 188*fb93f5c4SNavdeep Parhar } 189*fb93f5c4SNavdeep Parhar 190*fb93f5c4SNavdeep Parhar int c4iw_ev_handler(struct sge_iq *iq, const struct rsp_ctrl *rc) 191*fb93f5c4SNavdeep Parhar { 192*fb93f5c4SNavdeep Parhar struct c4iw_dev *dev = iq->adapter->iwarp_softc; 193*fb93f5c4SNavdeep Parhar u32 qid = be32_to_cpu(rc->pldbuflen_qid); 194*fb93f5c4SNavdeep Parhar struct c4iw_cq *chp; 195*fb93f5c4SNavdeep Parhar unsigned long flag; 196*fb93f5c4SNavdeep Parhar 197*fb93f5c4SNavdeep Parhar chp = get_chp(dev, qid); 198*fb93f5c4SNavdeep Parhar if (chp) { 199*fb93f5c4SNavdeep Parhar spin_lock_irqsave(&chp->comp_handler_lock, flag); 200*fb93f5c4SNavdeep Parhar (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); 201*fb93f5c4SNavdeep Parhar spin_unlock_irqrestore(&chp->comp_handler_lock, flag); 202*fb93f5c4SNavdeep Parhar } else 203*fb93f5c4SNavdeep Parhar CTR2(KTR_IW_CXGBE, "%s unknown cqid 0x%x", __func__, qid); 204*fb93f5c4SNavdeep Parhar return 0; 205*fb93f5c4SNavdeep Parhar } 206*fb93f5c4SNavdeep Parhar #endif 207