2 /**************************************************************************
4 Copyright (c) 2007, Chelsio Inc.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
13 2. Neither the name of the Chelsio Corporation nor the names of its
14 contributors may be used to endorse or promote products derived from
15 this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
29 ***************************************************************************/
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/pciio.h>
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/bus_dma.h>
44 #include <sys/ioccom.h>
46 #include <sys/mutex.h>
47 #include <sys/rwlock.h>
48 #include <sys/linker.h>
49 #include <sys/firmware.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
53 #include <sys/sysctl.h>
54 #include <sys/syslog.h>
55 #include <sys/queue.h>
56 #include <sys/taskqueue.h>
58 #include <sys/queue.h>
59 #include <sys/libkern.h>
61 #include <netinet/in.h>
62 #include <contrib/rdma/ib_verbs.h>
63 #include <contrib/rdma/ib_umem.h>
64 #include <contrib/rdma/ib_user_verbs.h>
68 #include <cxgb_include.h>
69 #include <ulp/iw_cxgb/iw_cxgb_wr.h>
70 #include <ulp/iw_cxgb/iw_cxgb_hal.h>
71 #include <ulp/iw_cxgb/iw_cxgb_provider.h>
72 #include <ulp/iw_cxgb/iw_cxgb_cm.h>
73 #include <ulp/iw_cxgb/iw_cxgb.h>
74 #include <ulp/iw_cxgb/iw_cxgb_resource.h>
75 #include <ulp/iw_cxgb/iw_cxgb_user.h>
77 #include <dev/cxgb/cxgb_include.h>
78 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_wr.h>
79 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h>
80 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.h>
81 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h>
82 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb.h>
83 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_resource.h>
84 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_user.h>
88 * Get one cq entry from cxio and map it to openib.
93 * -EAGAIN caller must try again
94 * any other neg errno fatal error
96 static int iwch_poll_cq_one(struct iwch_dev *rhp, struct iwch_cq *chp,
99 struct iwch_qp *qhp = NULL;
100 struct t3_cqe cqe, *rd_cqe;
107 rd_cqe = cxio_next_cqe(&chp->cq);
112 qhp = get_qhp(rhp, CQE_QPID(*rd_cqe));
116 mtx_lock(&qhp->lock);
119 ret = cxio_poll_cq(wq, &(chp->cq), &cqe, &cqe_flushed, &cookie,
121 if (t3a_device(chp->rhp) && credit) {
122 CTR3(KTR_IW_CXGB, "%s updating %d cq credits on id %d", __FUNCTION__,
123 credit, chp->cq.cqid);
124 cxio_hal_cq_op(&rhp->rdev, &chp->cq, CQ_CREDIT_UPDATE, credit);
135 wc->vendor_err = CQE_STATUS(cqe);
137 CTR4(KTR_IW_CXGB, "iwch_poll_cq_one qpid 0x%x type %d opcode %d status 0x%x",
138 CQE_QPID(cqe), CQE_TYPE(cqe),
139 CQE_OPCODE(cqe), CQE_STATUS(cqe));
140 CTR3(KTR_IW_CXGB, "wrid hi 0x%x lo 0x%x cookie 0x%llx",
141 CQE_WRID_HI(cqe), CQE_WRID_LOW(cqe), (unsigned long long) cookie);
143 if (CQE_TYPE(cqe) == 0) {
144 if (!CQE_STATUS(cqe))
145 wc->byte_len = CQE_LEN(cqe);
148 wc->opcode = IB_WC_RECV;
150 switch (CQE_OPCODE(cqe)) {
152 wc->opcode = IB_WC_RDMA_WRITE;
155 wc->opcode = IB_WC_RDMA_READ;
156 wc->byte_len = CQE_LEN(cqe);
159 case T3_SEND_WITH_SE:
160 wc->opcode = IB_WC_SEND;
163 wc->opcode = IB_WC_BIND_MW;
166 /* these aren't supported yet */
167 case T3_SEND_WITH_INV:
168 case T3_SEND_WITH_SE_INV:
170 case T3_FAST_REGISTER:
172 log(LOG_ERR, "Unexpected opcode %d "
173 "in the CQE received for QPID=0x%0x\n",
174 CQE_OPCODE(cqe), CQE_QPID(cqe));
181 wc->status = IB_WC_WR_FLUSH_ERR;
184 switch (CQE_STATUS(cqe)) {
185 case TPT_ERR_SUCCESS:
186 wc->status = IB_WC_SUCCESS;
189 wc->status = IB_WC_LOC_ACCESS_ERR;
192 wc->status = IB_WC_LOC_PROT_ERR;
196 wc->status = IB_WC_LOC_ACCESS_ERR;
199 wc->status = IB_WC_GENERAL_ERR;
202 wc->status = IB_WC_LOC_LEN_ERR;
204 case TPT_ERR_INVALIDATE_SHARED_MR:
205 case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
206 wc->status = IB_WC_MW_BIND_ERR;
210 case TPT_ERR_PDU_LEN_ERR:
211 case TPT_ERR_OUT_OF_RQE:
212 case TPT_ERR_DDP_VERSION:
213 case TPT_ERR_RDMA_VERSION:
214 case TPT_ERR_DDP_QUEUE_NUM:
218 case TPT_ERR_MSN_RANGE:
219 case TPT_ERR_IRD_OVERFLOW:
221 wc->status = IB_WC_FATAL_ERR;
223 case TPT_ERR_SWFLUSH:
224 wc->status = IB_WC_WR_FLUSH_ERR;
227 log(LOG_ERR, "Unexpected cqe_status 0x%x for "
228 "QPID=0x%0x\n", CQE_STATUS(cqe), CQE_QPID(cqe));
234 mtx_unlock(&qhp->lock);
238 int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
240 struct iwch_dev *rhp;
245 chp = to_iwch_cq(ibcq);
248 mtx_lock(&chp->lock);
249 for (npolled = 0; npolled < num_entries; ++npolled) {
255 * Because T3 can post CQEs that are _not_ associated
256 * with a WR, we might have to poll again after removing
260 err = iwch_poll_cq_one(rhp, chp, wc + npolled);
262 PANIC_IF(++i > 1000);
264 } while (err == -EAGAIN);
268 mtx_unlock(&chp->lock);