1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
41static 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 spin_lock(&rnicp->lock);
52 qhp = get_qhp(rnicp, 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 spin_unlock(&rnicp->lock);
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 spin_unlock(&rnicp->lock);
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 spin_unlock(&rnicp->lock);
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
107void 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 spin_lock(&rnicp->lock);
118 chp = get_chp(rnicp, cqid);
119 qhp = get_qhp(rnicp, 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 spin_unlock(&rnicp->lock);
127 goto out;
128 }
129 iwch_qp_add_ref(&qhp->ibqp);
130 atomic_inc(&chp->refcnt);
131 spin_unlock(&rnicp->lock);
132
133
134
135
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
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
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
170 case TPT_ERR_SUCCESS:
171
172
173
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
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
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 }
226done:
227 if (atomic_dec_and_test(&chp->refcnt))
228 wake_up(&chp->wait);
229 iwch_qp_rem_ref(&qhp->ibqp);
230out:
231 dev_kfree_skb_irq(skb);
232}
233