xref: /freebsd/sys/dev/cxgbe/iw_cxgbe/ev.c (revision fb93f5c47f1983aeabf4e9ec25df47d64ddda266)
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