0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <linux/gfp.h>
0038 #include <linux/hardirq.h>
0039 #include <linux/sched.h>
0040
0041 #include <asm/io.h>
0042
0043 #include <rdma/ib_pack.h>
0044
0045 #include "mthca_dev.h"
0046 #include "mthca_cmd.h"
0047 #include "mthca_memfree.h"
0048
0049 enum {
0050 MTHCA_MAX_DIRECT_CQ_SIZE = 4 * PAGE_SIZE
0051 };
0052
0053 enum {
0054 MTHCA_CQ_ENTRY_SIZE = 0x20
0055 };
0056
0057 enum {
0058 MTHCA_ATOMIC_BYTE_LEN = 8
0059 };
0060
0061
0062
0063
0064 struct mthca_cq_context {
0065 __be32 flags;
0066 __be64 start;
0067 __be32 logsize_usrpage;
0068 __be32 error_eqn;
0069 __be32 comp_eqn;
0070 __be32 pd;
0071 __be32 lkey;
0072 __be32 last_notified_index;
0073 __be32 solicit_producer_index;
0074 __be32 consumer_index;
0075 __be32 producer_index;
0076 __be32 cqn;
0077 __be32 ci_db;
0078 __be32 state_db;
0079 u32 reserved;
0080 } __packed;
0081
0082 #define MTHCA_CQ_STATUS_OK ( 0 << 28)
0083 #define MTHCA_CQ_STATUS_OVERFLOW ( 9 << 28)
0084 #define MTHCA_CQ_STATUS_WRITE_FAIL (10 << 28)
0085 #define MTHCA_CQ_FLAG_TR ( 1 << 18)
0086 #define MTHCA_CQ_FLAG_OI ( 1 << 17)
0087 #define MTHCA_CQ_STATE_DISARMED ( 0 << 8)
0088 #define MTHCA_CQ_STATE_ARMED ( 1 << 8)
0089 #define MTHCA_CQ_STATE_ARMED_SOL ( 4 << 8)
0090 #define MTHCA_EQ_STATE_FIRED (10 << 8)
0091
0092 enum {
0093 MTHCA_ERROR_CQE_OPCODE_MASK = 0xfe
0094 };
0095
0096 enum {
0097 SYNDROME_LOCAL_LENGTH_ERR = 0x01,
0098 SYNDROME_LOCAL_QP_OP_ERR = 0x02,
0099 SYNDROME_LOCAL_EEC_OP_ERR = 0x03,
0100 SYNDROME_LOCAL_PROT_ERR = 0x04,
0101 SYNDROME_WR_FLUSH_ERR = 0x05,
0102 SYNDROME_MW_BIND_ERR = 0x06,
0103 SYNDROME_BAD_RESP_ERR = 0x10,
0104 SYNDROME_LOCAL_ACCESS_ERR = 0x11,
0105 SYNDROME_REMOTE_INVAL_REQ_ERR = 0x12,
0106 SYNDROME_REMOTE_ACCESS_ERR = 0x13,
0107 SYNDROME_REMOTE_OP_ERR = 0x14,
0108 SYNDROME_RETRY_EXC_ERR = 0x15,
0109 SYNDROME_RNR_RETRY_EXC_ERR = 0x16,
0110 SYNDROME_LOCAL_RDD_VIOL_ERR = 0x20,
0111 SYNDROME_REMOTE_INVAL_RD_REQ_ERR = 0x21,
0112 SYNDROME_REMOTE_ABORTED_ERR = 0x22,
0113 SYNDROME_INVAL_EECN_ERR = 0x23,
0114 SYNDROME_INVAL_EEC_STATE_ERR = 0x24
0115 };
0116
0117 struct mthca_cqe {
0118 __be32 my_qpn;
0119 __be32 my_ee;
0120 __be32 rqpn;
0121 u8 sl_ipok;
0122 u8 g_mlpath;
0123 __be16 rlid;
0124 __be32 imm_etype_pkey_eec;
0125 __be32 byte_cnt;
0126 __be32 wqe;
0127 u8 opcode;
0128 u8 is_send;
0129 u8 reserved;
0130 u8 owner;
0131 };
0132
0133 struct mthca_err_cqe {
0134 __be32 my_qpn;
0135 u32 reserved1[3];
0136 u8 syndrome;
0137 u8 vendor_err;
0138 __be16 db_cnt;
0139 u32 reserved2;
0140 __be32 wqe;
0141 u8 opcode;
0142 u8 reserved3[2];
0143 u8 owner;
0144 };
0145
0146 #define MTHCA_CQ_ENTRY_OWNER_SW (0 << 7)
0147 #define MTHCA_CQ_ENTRY_OWNER_HW (1 << 7)
0148
0149 #define MTHCA_TAVOR_CQ_DB_INC_CI (1 << 24)
0150 #define MTHCA_TAVOR_CQ_DB_REQ_NOT (2 << 24)
0151 #define MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL (3 << 24)
0152 #define MTHCA_TAVOR_CQ_DB_SET_CI (4 << 24)
0153 #define MTHCA_TAVOR_CQ_DB_REQ_NOT_MULT (5 << 24)
0154
0155 #define MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL (1 << 24)
0156 #define MTHCA_ARBEL_CQ_DB_REQ_NOT (2 << 24)
0157 #define MTHCA_ARBEL_CQ_DB_REQ_NOT_MULT (3 << 24)
0158
0159 static inline struct mthca_cqe *get_cqe_from_buf(struct mthca_cq_buf *buf,
0160 int entry)
0161 {
0162 if (buf->is_direct)
0163 return buf->queue.direct.buf + (entry * MTHCA_CQ_ENTRY_SIZE);
0164 else
0165 return buf->queue.page_list[entry * MTHCA_CQ_ENTRY_SIZE / PAGE_SIZE].buf
0166 + (entry * MTHCA_CQ_ENTRY_SIZE) % PAGE_SIZE;
0167 }
0168
0169 static inline struct mthca_cqe *get_cqe(struct mthca_cq *cq, int entry)
0170 {
0171 return get_cqe_from_buf(&cq->buf, entry);
0172 }
0173
0174 static inline struct mthca_cqe *cqe_sw(struct mthca_cqe *cqe)
0175 {
0176 return MTHCA_CQ_ENTRY_OWNER_HW & cqe->owner ? NULL : cqe;
0177 }
0178
0179 static inline struct mthca_cqe *next_cqe_sw(struct mthca_cq *cq)
0180 {
0181 return cqe_sw(get_cqe(cq, cq->cons_index & cq->ibcq.cqe));
0182 }
0183
0184 static inline void set_cqe_hw(struct mthca_cqe *cqe)
0185 {
0186 cqe->owner = MTHCA_CQ_ENTRY_OWNER_HW;
0187 }
0188
0189 static void dump_cqe(struct mthca_dev *dev, void *cqe_ptr)
0190 {
0191 __be32 *cqe = cqe_ptr;
0192
0193 (void) cqe;
0194 mthca_dbg(dev, "CQE contents %08x %08x %08x %08x %08x %08x %08x %08x\n",
0195 be32_to_cpu(cqe[0]), be32_to_cpu(cqe[1]), be32_to_cpu(cqe[2]),
0196 be32_to_cpu(cqe[3]), be32_to_cpu(cqe[4]), be32_to_cpu(cqe[5]),
0197 be32_to_cpu(cqe[6]), be32_to_cpu(cqe[7]));
0198 }
0199
0200
0201
0202
0203
0204 static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
0205 int incr)
0206 {
0207 if (mthca_is_memfree(dev)) {
0208 *cq->set_ci_db = cpu_to_be32(cq->cons_index);
0209 wmb();
0210 } else {
0211 mthca_write64(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn, incr - 1,
0212 dev->kar + MTHCA_CQ_DOORBELL,
0213 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
0214 }
0215 }
0216
0217 void mthca_cq_completion(struct mthca_dev *dev, u32 cqn)
0218 {
0219 struct mthca_cq *cq;
0220
0221 cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
0222
0223 if (!cq) {
0224 mthca_warn(dev, "Completion event for bogus CQ %08x\n", cqn);
0225 return;
0226 }
0227
0228 ++cq->arm_sn;
0229
0230 cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
0231 }
0232
0233 void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
0234 enum ib_event_type event_type)
0235 {
0236 struct mthca_cq *cq;
0237 struct ib_event event;
0238
0239 spin_lock(&dev->cq_table.lock);
0240
0241 cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
0242 if (cq)
0243 ++cq->refcount;
0244
0245 spin_unlock(&dev->cq_table.lock);
0246
0247 if (!cq) {
0248 mthca_warn(dev, "Async event for bogus CQ %08x\n", cqn);
0249 return;
0250 }
0251
0252 event.device = &dev->ib_dev;
0253 event.event = event_type;
0254 event.element.cq = &cq->ibcq;
0255 if (cq->ibcq.event_handler)
0256 cq->ibcq.event_handler(&event, cq->ibcq.cq_context);
0257
0258 spin_lock(&dev->cq_table.lock);
0259 if (!--cq->refcount)
0260 wake_up(&cq->wait);
0261 spin_unlock(&dev->cq_table.lock);
0262 }
0263
0264 static inline int is_recv_cqe(struct mthca_cqe *cqe)
0265 {
0266 if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) ==
0267 MTHCA_ERROR_CQE_OPCODE_MASK)
0268 return !(cqe->opcode & 0x01);
0269 else
0270 return !(cqe->is_send & 0x80);
0271 }
0272
0273 void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn,
0274 struct mthca_srq *srq)
0275 {
0276 struct mthca_cqe *cqe;
0277 u32 prod_index;
0278 int i, nfreed = 0;
0279
0280 spin_lock_irq(&cq->lock);
0281
0282
0283
0284
0285
0286
0287
0288
0289 for (prod_index = cq->cons_index;
0290 cqe_sw(get_cqe(cq, prod_index & cq->ibcq.cqe));
0291 ++prod_index)
0292 if (prod_index == cq->cons_index + cq->ibcq.cqe)
0293 break;
0294
0295 if (0)
0296 mthca_dbg(dev, "Cleaning QPN %06x from CQN %06x; ci %d, pi %d\n",
0297 qpn, cq->cqn, cq->cons_index, prod_index);
0298
0299
0300
0301
0302
0303 while ((int) --prod_index - (int) cq->cons_index >= 0) {
0304 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
0305 if (cqe->my_qpn == cpu_to_be32(qpn)) {
0306 if (srq && is_recv_cqe(cqe))
0307 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
0308 ++nfreed;
0309 } else if (nfreed)
0310 memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe),
0311 cqe, MTHCA_CQ_ENTRY_SIZE);
0312 }
0313
0314 if (nfreed) {
0315 for (i = 0; i < nfreed; ++i)
0316 set_cqe_hw(get_cqe(cq, (cq->cons_index + i) & cq->ibcq.cqe));
0317 wmb();
0318 cq->cons_index += nfreed;
0319 update_cons_index(dev, cq, nfreed);
0320 }
0321
0322 spin_unlock_irq(&cq->lock);
0323 }
0324
0325 void mthca_cq_resize_copy_cqes(struct mthca_cq *cq)
0326 {
0327 int i;
0328
0329
0330
0331
0332
0333
0334
0335 if (!mthca_is_memfree(to_mdev(cq->ibcq.device)) &&
0336 cq->ibcq.cqe < cq->resize_buf->cqe) {
0337 cq->cons_index &= cq->ibcq.cqe;
0338 if (cqe_sw(get_cqe(cq, cq->ibcq.cqe)))
0339 cq->cons_index -= cq->ibcq.cqe + 1;
0340 }
0341
0342 for (i = cq->cons_index; cqe_sw(get_cqe(cq, i & cq->ibcq.cqe)); ++i)
0343 memcpy(get_cqe_from_buf(&cq->resize_buf->buf,
0344 i & cq->resize_buf->cqe),
0345 get_cqe(cq, i & cq->ibcq.cqe), MTHCA_CQ_ENTRY_SIZE);
0346 }
0347
0348 int mthca_alloc_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int nent)
0349 {
0350 int ret;
0351 int i;
0352
0353 ret = mthca_buf_alloc(dev, nent * MTHCA_CQ_ENTRY_SIZE,
0354 MTHCA_MAX_DIRECT_CQ_SIZE,
0355 &buf->queue, &buf->is_direct,
0356 &dev->driver_pd, 1, &buf->mr);
0357 if (ret)
0358 return ret;
0359
0360 for (i = 0; i < nent; ++i)
0361 set_cqe_hw(get_cqe_from_buf(buf, i));
0362
0363 return 0;
0364 }
0365
0366 void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int cqe)
0367 {
0368 mthca_buf_free(dev, (cqe + 1) * MTHCA_CQ_ENTRY_SIZE, &buf->queue,
0369 buf->is_direct, &buf->mr);
0370 }
0371
0372 static void handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
0373 struct mthca_qp *qp, int wqe_index, int is_send,
0374 struct mthca_err_cqe *cqe,
0375 struct ib_wc *entry, int *free_cqe)
0376 {
0377 int dbd;
0378 __be32 new_wqe;
0379
0380 if (cqe->syndrome == SYNDROME_LOCAL_QP_OP_ERR) {
0381 mthca_dbg(dev, "local QP operation err "
0382 "(QPN %06x, WQE @ %08x, CQN %06x, index %d)\n",
0383 be32_to_cpu(cqe->my_qpn), be32_to_cpu(cqe->wqe),
0384 cq->cqn, cq->cons_index);
0385 dump_cqe(dev, cqe);
0386 }
0387
0388
0389
0390
0391
0392 switch (cqe->syndrome) {
0393 case SYNDROME_LOCAL_LENGTH_ERR:
0394 entry->status = IB_WC_LOC_LEN_ERR;
0395 break;
0396 case SYNDROME_LOCAL_QP_OP_ERR:
0397 entry->status = IB_WC_LOC_QP_OP_ERR;
0398 break;
0399 case SYNDROME_LOCAL_EEC_OP_ERR:
0400 entry->status = IB_WC_LOC_EEC_OP_ERR;
0401 break;
0402 case SYNDROME_LOCAL_PROT_ERR:
0403 entry->status = IB_WC_LOC_PROT_ERR;
0404 break;
0405 case SYNDROME_WR_FLUSH_ERR:
0406 entry->status = IB_WC_WR_FLUSH_ERR;
0407 break;
0408 case SYNDROME_MW_BIND_ERR:
0409 entry->status = IB_WC_MW_BIND_ERR;
0410 break;
0411 case SYNDROME_BAD_RESP_ERR:
0412 entry->status = IB_WC_BAD_RESP_ERR;
0413 break;
0414 case SYNDROME_LOCAL_ACCESS_ERR:
0415 entry->status = IB_WC_LOC_ACCESS_ERR;
0416 break;
0417 case SYNDROME_REMOTE_INVAL_REQ_ERR:
0418 entry->status = IB_WC_REM_INV_REQ_ERR;
0419 break;
0420 case SYNDROME_REMOTE_ACCESS_ERR:
0421 entry->status = IB_WC_REM_ACCESS_ERR;
0422 break;
0423 case SYNDROME_REMOTE_OP_ERR:
0424 entry->status = IB_WC_REM_OP_ERR;
0425 break;
0426 case SYNDROME_RETRY_EXC_ERR:
0427 entry->status = IB_WC_RETRY_EXC_ERR;
0428 break;
0429 case SYNDROME_RNR_RETRY_EXC_ERR:
0430 entry->status = IB_WC_RNR_RETRY_EXC_ERR;
0431 break;
0432 case SYNDROME_LOCAL_RDD_VIOL_ERR:
0433 entry->status = IB_WC_LOC_RDD_VIOL_ERR;
0434 break;
0435 case SYNDROME_REMOTE_INVAL_RD_REQ_ERR:
0436 entry->status = IB_WC_REM_INV_RD_REQ_ERR;
0437 break;
0438 case SYNDROME_REMOTE_ABORTED_ERR:
0439 entry->status = IB_WC_REM_ABORT_ERR;
0440 break;
0441 case SYNDROME_INVAL_EECN_ERR:
0442 entry->status = IB_WC_INV_EECN_ERR;
0443 break;
0444 case SYNDROME_INVAL_EEC_STATE_ERR:
0445 entry->status = IB_WC_INV_EEC_STATE_ERR;
0446 break;
0447 default:
0448 entry->status = IB_WC_GENERAL_ERR;
0449 break;
0450 }
0451
0452 entry->vendor_err = cqe->vendor_err;
0453
0454
0455
0456
0457
0458 if (mthca_is_memfree(dev))
0459 return;
0460
0461 mthca_free_err_wqe(dev, qp, is_send, wqe_index, &dbd, &new_wqe);
0462
0463
0464
0465
0466
0467
0468 if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
0469 return;
0470
0471 be16_add_cpu(&cqe->db_cnt, -dbd);
0472 cqe->wqe = new_wqe;
0473 cqe->syndrome = SYNDROME_WR_FLUSH_ERR;
0474
0475 *free_cqe = 0;
0476 }
0477
0478 static inline int mthca_poll_one(struct mthca_dev *dev,
0479 struct mthca_cq *cq,
0480 struct mthca_qp **cur_qp,
0481 int *freed,
0482 struct ib_wc *entry)
0483 {
0484 struct mthca_wq *wq;
0485 struct mthca_cqe *cqe;
0486 int wqe_index;
0487 int is_error;
0488 int is_send;
0489 int free_cqe = 1;
0490 int err = 0;
0491 u16 checksum;
0492
0493 cqe = next_cqe_sw(cq);
0494 if (!cqe)
0495 return -EAGAIN;
0496
0497
0498
0499
0500
0501 rmb();
0502
0503 if (0) {
0504 mthca_dbg(dev, "%x/%d: CQE -> QPN %06x, WQE @ %08x\n",
0505 cq->cqn, cq->cons_index, be32_to_cpu(cqe->my_qpn),
0506 be32_to_cpu(cqe->wqe));
0507 dump_cqe(dev, cqe);
0508 }
0509
0510 is_error = (cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) ==
0511 MTHCA_ERROR_CQE_OPCODE_MASK;
0512 is_send = is_error ? cqe->opcode & 0x01 : cqe->is_send & 0x80;
0513
0514 if (!*cur_qp || be32_to_cpu(cqe->my_qpn) != (*cur_qp)->qpn) {
0515
0516
0517
0518
0519
0520 *cur_qp = mthca_array_get(&dev->qp_table.qp,
0521 be32_to_cpu(cqe->my_qpn) &
0522 (dev->limits.num_qps - 1));
0523 if (!*cur_qp) {
0524 mthca_warn(dev, "CQ entry for unknown QP %06x\n",
0525 be32_to_cpu(cqe->my_qpn) & 0xffffff);
0526 err = -EINVAL;
0527 goto out;
0528 }
0529 }
0530
0531 entry->qp = &(*cur_qp)->ibqp;
0532
0533 if (is_send) {
0534 wq = &(*cur_qp)->sq;
0535 wqe_index = ((be32_to_cpu(cqe->wqe) - (*cur_qp)->send_wqe_offset)
0536 >> wq->wqe_shift);
0537 entry->wr_id = (*cur_qp)->wrid[wqe_index +
0538 (*cur_qp)->rq.max];
0539 } else if ((*cur_qp)->ibqp.srq) {
0540 struct mthca_srq *srq = to_msrq((*cur_qp)->ibqp.srq);
0541 u32 wqe = be32_to_cpu(cqe->wqe);
0542 wq = NULL;
0543 wqe_index = wqe >> srq->wqe_shift;
0544 entry->wr_id = srq->wrid[wqe_index];
0545 mthca_free_srq_wqe(srq, wqe);
0546 } else {
0547 s32 wqe;
0548 wq = &(*cur_qp)->rq;
0549 wqe = be32_to_cpu(cqe->wqe);
0550 wqe_index = wqe >> wq->wqe_shift;
0551
0552
0553
0554
0555
0556 if (unlikely(wqe_index < 0))
0557 wqe_index = wq->max - 1;
0558 entry->wr_id = (*cur_qp)->wrid[wqe_index];
0559 }
0560
0561 if (wq) {
0562 if (wq->last_comp < wqe_index)
0563 wq->tail += wqe_index - wq->last_comp;
0564 else
0565 wq->tail += wqe_index + wq->max - wq->last_comp;
0566
0567 wq->last_comp = wqe_index;
0568 }
0569
0570 if (is_error) {
0571 handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
0572 (struct mthca_err_cqe *) cqe,
0573 entry, &free_cqe);
0574 goto out;
0575 }
0576
0577 if (is_send) {
0578 entry->wc_flags = 0;
0579 switch (cqe->opcode) {
0580 case MTHCA_OPCODE_RDMA_WRITE:
0581 entry->opcode = IB_WC_RDMA_WRITE;
0582 break;
0583 case MTHCA_OPCODE_RDMA_WRITE_IMM:
0584 entry->opcode = IB_WC_RDMA_WRITE;
0585 entry->wc_flags |= IB_WC_WITH_IMM;
0586 break;
0587 case MTHCA_OPCODE_SEND:
0588 entry->opcode = IB_WC_SEND;
0589 break;
0590 case MTHCA_OPCODE_SEND_IMM:
0591 entry->opcode = IB_WC_SEND;
0592 entry->wc_flags |= IB_WC_WITH_IMM;
0593 break;
0594 case MTHCA_OPCODE_RDMA_READ:
0595 entry->opcode = IB_WC_RDMA_READ;
0596 entry->byte_len = be32_to_cpu(cqe->byte_cnt);
0597 break;
0598 case MTHCA_OPCODE_ATOMIC_CS:
0599 entry->opcode = IB_WC_COMP_SWAP;
0600 entry->byte_len = MTHCA_ATOMIC_BYTE_LEN;
0601 break;
0602 case MTHCA_OPCODE_ATOMIC_FA:
0603 entry->opcode = IB_WC_FETCH_ADD;
0604 entry->byte_len = MTHCA_ATOMIC_BYTE_LEN;
0605 break;
0606 default:
0607 entry->opcode = 0xFF;
0608 break;
0609 }
0610 } else {
0611 entry->byte_len = be32_to_cpu(cqe->byte_cnt);
0612 switch (cqe->opcode & 0x1f) {
0613 case IB_OPCODE_SEND_LAST_WITH_IMMEDIATE:
0614 case IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE:
0615 entry->wc_flags = IB_WC_WITH_IMM;
0616 entry->ex.imm_data = cqe->imm_etype_pkey_eec;
0617 entry->opcode = IB_WC_RECV;
0618 break;
0619 case IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE:
0620 case IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE:
0621 entry->wc_flags = IB_WC_WITH_IMM;
0622 entry->ex.imm_data = cqe->imm_etype_pkey_eec;
0623 entry->opcode = IB_WC_RECV_RDMA_WITH_IMM;
0624 break;
0625 default:
0626 entry->wc_flags = 0;
0627 entry->opcode = IB_WC_RECV;
0628 break;
0629 }
0630 entry->slid = be16_to_cpu(cqe->rlid);
0631 entry->sl = cqe->sl_ipok >> 4;
0632 entry->src_qp = be32_to_cpu(cqe->rqpn) & 0xffffff;
0633 entry->dlid_path_bits = cqe->g_mlpath & 0x7f;
0634 entry->pkey_index = be32_to_cpu(cqe->imm_etype_pkey_eec) >> 16;
0635 entry->wc_flags |= cqe->g_mlpath & 0x80 ? IB_WC_GRH : 0;
0636 checksum = (be32_to_cpu(cqe->rqpn) >> 24) |
0637 ((be32_to_cpu(cqe->my_ee) >> 16) & 0xff00);
0638 entry->wc_flags |= (cqe->sl_ipok & 1 && checksum == 0xffff) ?
0639 IB_WC_IP_CSUM_OK : 0;
0640 }
0641
0642 entry->status = IB_WC_SUCCESS;
0643
0644 out:
0645 if (likely(free_cqe)) {
0646 set_cqe_hw(cqe);
0647 ++(*freed);
0648 ++cq->cons_index;
0649 }
0650
0651 return err;
0652 }
0653
0654 int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
0655 struct ib_wc *entry)
0656 {
0657 struct mthca_dev *dev = to_mdev(ibcq->device);
0658 struct mthca_cq *cq = to_mcq(ibcq);
0659 struct mthca_qp *qp = NULL;
0660 unsigned long flags;
0661 int err = 0;
0662 int freed = 0;
0663 int npolled;
0664
0665 spin_lock_irqsave(&cq->lock, flags);
0666
0667 npolled = 0;
0668 repoll:
0669 while (npolled < num_entries) {
0670 err = mthca_poll_one(dev, cq, &qp,
0671 &freed, entry + npolled);
0672 if (err)
0673 break;
0674 ++npolled;
0675 }
0676
0677 if (freed) {
0678 wmb();
0679 update_cons_index(dev, cq, freed);
0680 }
0681
0682
0683
0684
0685
0686
0687
0688 if (unlikely(err == -EAGAIN && cq->resize_buf &&
0689 cq->resize_buf->state == CQ_RESIZE_READY)) {
0690
0691
0692
0693
0694
0695
0696
0697 if (!mthca_is_memfree(dev))
0698 cq->cons_index &= cq->ibcq.cqe;
0699
0700 if (cqe_sw(get_cqe_from_buf(&cq->resize_buf->buf,
0701 cq->cons_index & cq->resize_buf->cqe))) {
0702 struct mthca_cq_buf tbuf;
0703 int tcqe;
0704
0705 tbuf = cq->buf;
0706 tcqe = cq->ibcq.cqe;
0707 cq->buf = cq->resize_buf->buf;
0708 cq->ibcq.cqe = cq->resize_buf->cqe;
0709
0710 cq->resize_buf->buf = tbuf;
0711 cq->resize_buf->cqe = tcqe;
0712 cq->resize_buf->state = CQ_RESIZE_SWAPPED;
0713
0714 goto repoll;
0715 }
0716 }
0717
0718 spin_unlock_irqrestore(&cq->lock, flags);
0719
0720 return err == 0 || err == -EAGAIN ? npolled : err;
0721 }
0722
0723 int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
0724 {
0725 u32 dbhi = ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
0726 MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
0727 MTHCA_TAVOR_CQ_DB_REQ_NOT) |
0728 to_mcq(cq)->cqn;
0729
0730 mthca_write64(dbhi, 0xffffffff, to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
0731 MTHCA_GET_DOORBELL_LOCK(&to_mdev(cq->device)->doorbell_lock));
0732
0733 return 0;
0734 }
0735
0736 int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
0737 {
0738 struct mthca_cq *cq = to_mcq(ibcq);
0739 __be32 db_rec[2];
0740 u32 dbhi;
0741 u32 sn = cq->arm_sn & 3;
0742
0743 db_rec[0] = cpu_to_be32(cq->cons_index);
0744 db_rec[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
0745 ((flags & IB_CQ_SOLICITED_MASK) ==
0746 IB_CQ_SOLICITED ? 1 : 2));
0747
0748 mthca_write_db_rec(db_rec, cq->arm_db);
0749
0750
0751
0752
0753
0754 wmb();
0755
0756 dbhi = (sn << 28) |
0757 ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
0758 MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
0759 MTHCA_ARBEL_CQ_DB_REQ_NOT) | cq->cqn;
0760
0761 mthca_write64(dbhi, cq->cons_index,
0762 to_mdev(ibcq->device)->kar + MTHCA_CQ_DOORBELL,
0763 MTHCA_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->doorbell_lock));
0764
0765 return 0;
0766 }
0767
0768 int mthca_init_cq(struct mthca_dev *dev, int nent,
0769 struct mthca_ucontext *ctx, u32 pdn,
0770 struct mthca_cq *cq)
0771 {
0772 struct mthca_mailbox *mailbox;
0773 struct mthca_cq_context *cq_context;
0774 int err = -ENOMEM;
0775
0776 cq->ibcq.cqe = nent - 1;
0777 cq->is_kernel = !ctx;
0778
0779 cq->cqn = mthca_alloc(&dev->cq_table.alloc);
0780 if (cq->cqn == -1)
0781 return -ENOMEM;
0782
0783 if (mthca_is_memfree(dev)) {
0784 err = mthca_table_get(dev, dev->cq_table.table, cq->cqn);
0785 if (err)
0786 goto err_out;
0787
0788 if (cq->is_kernel) {
0789 cq->arm_sn = 1;
0790
0791 err = -ENOMEM;
0792
0793 cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI,
0794 cq->cqn, &cq->set_ci_db);
0795 if (cq->set_ci_db_index < 0)
0796 goto err_out_icm;
0797
0798 cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM,
0799 cq->cqn, &cq->arm_db);
0800 if (cq->arm_db_index < 0)
0801 goto err_out_ci;
0802 }
0803 }
0804
0805 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
0806 if (IS_ERR(mailbox)) {
0807 err = PTR_ERR(mailbox);
0808 goto err_out_arm;
0809 }
0810
0811 cq_context = mailbox->buf;
0812
0813 if (cq->is_kernel) {
0814 err = mthca_alloc_cq_buf(dev, &cq->buf, nent);
0815 if (err)
0816 goto err_out_mailbox;
0817 }
0818
0819 spin_lock_init(&cq->lock);
0820 cq->refcount = 1;
0821 init_waitqueue_head(&cq->wait);
0822 mutex_init(&cq->mutex);
0823
0824 memset(cq_context, 0, sizeof *cq_context);
0825 cq_context->flags = cpu_to_be32(MTHCA_CQ_STATUS_OK |
0826 MTHCA_CQ_STATE_DISARMED |
0827 MTHCA_CQ_FLAG_TR);
0828 cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
0829 if (ctx)
0830 cq_context->logsize_usrpage |= cpu_to_be32(ctx->uar.index);
0831 else
0832 cq_context->logsize_usrpage |= cpu_to_be32(dev->driver_uar.index);
0833 cq_context->error_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn);
0834 cq_context->comp_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_COMP].eqn);
0835 cq_context->pd = cpu_to_be32(pdn);
0836 cq_context->lkey = cpu_to_be32(cq->buf.mr.ibmr.lkey);
0837 cq_context->cqn = cpu_to_be32(cq->cqn);
0838
0839 if (mthca_is_memfree(dev)) {
0840 cq_context->ci_db = cpu_to_be32(cq->set_ci_db_index);
0841 cq_context->state_db = cpu_to_be32(cq->arm_db_index);
0842 }
0843
0844 err = mthca_SW2HW_CQ(dev, mailbox, cq->cqn);
0845 if (err) {
0846 mthca_warn(dev, "SW2HW_CQ failed (%d)\n", err);
0847 goto err_out_free_mr;
0848 }
0849
0850 spin_lock_irq(&dev->cq_table.lock);
0851 err = mthca_array_set(&dev->cq_table.cq,
0852 cq->cqn & (dev->limits.num_cqs - 1), cq);
0853 if (err) {
0854 spin_unlock_irq(&dev->cq_table.lock);
0855 goto err_out_free_mr;
0856 }
0857 spin_unlock_irq(&dev->cq_table.lock);
0858
0859 cq->cons_index = 0;
0860
0861 mthca_free_mailbox(dev, mailbox);
0862
0863 return 0;
0864
0865 err_out_free_mr:
0866 if (cq->is_kernel)
0867 mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
0868
0869 err_out_mailbox:
0870 mthca_free_mailbox(dev, mailbox);
0871
0872 err_out_arm:
0873 if (cq->is_kernel && mthca_is_memfree(dev))
0874 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
0875
0876 err_out_ci:
0877 if (cq->is_kernel && mthca_is_memfree(dev))
0878 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
0879
0880 err_out_icm:
0881 mthca_table_put(dev, dev->cq_table.table, cq->cqn);
0882
0883 err_out:
0884 mthca_free(&dev->cq_table.alloc, cq->cqn);
0885
0886 return err;
0887 }
0888
0889 static inline int get_cq_refcount(struct mthca_dev *dev, struct mthca_cq *cq)
0890 {
0891 int c;
0892
0893 spin_lock_irq(&dev->cq_table.lock);
0894 c = cq->refcount;
0895 spin_unlock_irq(&dev->cq_table.lock);
0896
0897 return c;
0898 }
0899
0900 void mthca_free_cq(struct mthca_dev *dev,
0901 struct mthca_cq *cq)
0902 {
0903 struct mthca_mailbox *mailbox;
0904 int err;
0905
0906 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
0907 if (IS_ERR(mailbox)) {
0908 mthca_warn(dev, "No memory for mailbox to free CQ.\n");
0909 return;
0910 }
0911
0912 err = mthca_HW2SW_CQ(dev, mailbox, cq->cqn);
0913 if (err)
0914 mthca_warn(dev, "HW2SW_CQ failed (%d)\n", err);
0915
0916 if (0) {
0917 __be32 *ctx = mailbox->buf;
0918 int j;
0919
0920 printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
0921 cq->cqn, cq->cons_index,
0922 cq->is_kernel ? !!next_cqe_sw(cq) : 0);
0923 for (j = 0; j < 16; ++j)
0924 printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
0925 }
0926
0927 spin_lock_irq(&dev->cq_table.lock);
0928 mthca_array_clear(&dev->cq_table.cq,
0929 cq->cqn & (dev->limits.num_cqs - 1));
0930 --cq->refcount;
0931 spin_unlock_irq(&dev->cq_table.lock);
0932
0933 if (dev->mthca_flags & MTHCA_FLAG_MSI_X)
0934 synchronize_irq(dev->eq_table.eq[MTHCA_EQ_COMP].msi_x_vector);
0935 else
0936 synchronize_irq(dev->pdev->irq);
0937
0938 wait_event(cq->wait, !get_cq_refcount(dev, cq));
0939
0940 if (cq->is_kernel) {
0941 mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
0942 if (mthca_is_memfree(dev)) {
0943 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
0944 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
0945 }
0946 }
0947
0948 mthca_table_put(dev, dev->cq_table.table, cq->cqn);
0949 mthca_free(&dev->cq_table.alloc, cq->cqn);
0950 mthca_free_mailbox(dev, mailbox);
0951 }
0952
0953 int mthca_init_cq_table(struct mthca_dev *dev)
0954 {
0955 int err;
0956
0957 spin_lock_init(&dev->cq_table.lock);
0958
0959 err = mthca_alloc_init(&dev->cq_table.alloc,
0960 dev->limits.num_cqs,
0961 (1 << 24) - 1,
0962 dev->limits.reserved_cqs);
0963 if (err)
0964 return err;
0965
0966 err = mthca_array_init(&dev->cq_table.cq,
0967 dev->limits.num_cqs);
0968 if (err)
0969 mthca_alloc_cleanup(&dev->cq_table.alloc);
0970
0971 return err;
0972 }
0973
0974 void mthca_cleanup_cq_table(struct mthca_dev *dev)
0975 {
0976 mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs);
0977 mthca_alloc_cleanup(&dev->cq_table.alloc);
0978 }