1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */ 3 4 #include <linux/module.h> 5 #include <linux/printk.h> 6 #include <rdma/ib_addr.h> 7 #include <rdma/ib_user_verbs.h> 8 9 #include "ionic_fw.h" 10 #include "ionic_ibdev.h" 11 12 #define IONIC_OP(version, opname) \ 13 ((version) < 2 ? IONIC_V1_OP_##opname : IONIC_V2_OP_##opname) 14 15 static bool ionic_next_cqe(struct ionic_ibdev *dev, struct ionic_cq *cq, 16 struct ionic_v1_cqe **cqe) 17 { 18 struct ionic_v1_cqe *qcqe = ionic_queue_at_prod(&cq->q); 19 20 if (unlikely(cq->color != ionic_v1_cqe_color(qcqe))) 21 return false; 22 23 /* Prevent out-of-order reads of the CQE */ 24 dma_rmb(); 25 26 *cqe = qcqe; 27 28 return true; 29 } 30 31 static int ionic_flush_recv(struct ionic_qp *qp, struct ib_wc *wc) 32 { 33 struct ionic_rq_meta *meta; 34 struct ionic_v1_wqe *wqe; 35 u64 wqe_idx; 36 37 if (!qp->rq.flush) 38 return 0; 39 40 if (ionic_queue_empty(&qp->rq.q)) 41 return 0; 42 43 wqe = ionic_queue_at_cons(&qp->rq.q); 44 wqe_idx = le64_to_cpu(wqe->base.wqe_idx); 45 46 /* wqe_idx must be a valid queue index */ 47 if (unlikely(wqe_idx >> qp->rq.q.depth_log2)) { 48 ibdev_warn(qp->ibqp.device, 49 "flush qp %u recv index %llu invalid\n", 50 qp->qpid, (unsigned long long)wqe_idx); 51 return -EIO; 52 } 53 54 /* wqe_idx must indicate a request that is outstanding */ 55 meta = &qp->rq.meta[wqe_idx]; 56 if (unlikely(meta->next != IONIC_META_POSTED)) { 57 ibdev_warn(qp->ibqp.device, 58 "flush qp %u recv index %llu not posted\n", 59 qp->qpid, (unsigned long long)wqe_idx); 60 return -EIO; 61 } 62 63 ionic_queue_consume(&qp->rq.q); 64 65 memset(wc, 0, sizeof(*wc)); 66 67 wc->status = IB_WC_WR_FLUSH_ERR; 68 wc->wr_id = meta->wrid; 69 wc->qp = &qp->ibqp; 70 71 meta->next = qp->rq.meta_head; 72 qp->rq.meta_head = meta; 73 74 return 1; 75 } 76 77 static int ionic_flush_recv_many(struct ionic_qp *qp, 78 struct ib_wc *wc, int nwc) 79 { 80 int rc = 0, npolled = 0; 81 82 while (npolled < nwc) { 83 rc = ionic_flush_recv(qp, wc + npolled); 84 if (rc <= 0) 85 break; 86 87 npolled += rc; 88 } 89 90 return npolled ?: rc; 91 } 92 93 static int ionic_flush_send(struct ionic_qp *qp, struct ib_wc *wc) 94 { 95 struct ionic_sq_meta *meta; 96 97 if (!qp->sq_flush) 98 return 0; 99 100 if (ionic_queue_empty(&qp->sq)) 101 return 0; 102 103 meta = &qp->sq_meta[qp->sq.cons]; 104 105 ionic_queue_consume(&qp->sq); 106 107 memset(wc, 0, sizeof(*wc)); 108 109 wc->status = IB_WC_WR_FLUSH_ERR; 110 wc->wr_id = meta->wrid; 111 wc->qp = &qp->ibqp; 112 113 return 1; 114 } 115 116 static int ionic_flush_send_many(struct ionic_qp *qp, 117 struct ib_wc *wc, int nwc) 118 { 119 int rc = 0, npolled = 0; 120 121 while (npolled < nwc) { 122 rc = ionic_flush_send(qp, wc + npolled); 123 if (rc <= 0) 124 break; 125 126 npolled += rc; 127 } 128 129 return npolled ?: rc; 130 } 131 132 static int ionic_poll_recv(struct ionic_ibdev *dev, struct ionic_cq *cq, 133 struct ionic_qp *cqe_qp, struct ionic_v1_cqe *cqe, 134 struct ib_wc *wc) 135 { 136 struct ionic_qp *qp = NULL; 137 struct ionic_rq_meta *meta; 138 u16 vlan_tag, wqe_idx; 139 u32 src_qpn, st_len; 140 u8 op; 141 142 if (cqe_qp->rq.flush) 143 return 0; 144 145 qp = cqe_qp; 146 147 st_len = be32_to_cpu(cqe->status_length); 148 149 /* ignore wqe_idx in case of flush error */ 150 if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) { 151 cqe_qp->rq.flush = true; 152 cq->flush = true; 153 list_move_tail(&qp->rq.cq_flush, &cq->flush_rq); 154 155 /* posted recvs (if any) flushed by ionic_flush_recv */ 156 return 0; 157 } 158 159 /* there had better be something in the recv queue to complete */ 160 if (ionic_queue_empty(&qp->rq.q)) { 161 ibdev_warn(&dev->ibdev, "qp %u is empty\n", qp->qpid); 162 return -EIO; 163 } 164 165 wqe_idx = le64_to_cpu(cqe->recv.wqe_idx_timestamp) & IONIC_V1_CQE_WQE_IDX_MASK; 166 /* wqe_idx must be a valid queue index */ 167 if (unlikely(wqe_idx >> qp->rq.q.depth_log2)) { 168 ibdev_warn(&dev->ibdev, 169 "qp %u recv index %u invalid\n", qp->qpid, wqe_idx); 170 return -EIO; 171 } 172 173 /* wqe_idx must indicate a request that is outstanding */ 174 meta = &qp->rq.meta[wqe_idx]; 175 if (unlikely(meta->next != IONIC_META_POSTED)) { 176 ibdev_warn(&dev->ibdev, 177 "qp %u recv index %u not posted\n", qp->qpid, wqe_idx); 178 return -EIO; 179 } 180 181 meta->next = qp->rq.meta_head; 182 qp->rq.meta_head = meta; 183 184 memset(wc, 0, sizeof(*wc)); 185 186 wc->wr_id = meta->wrid; 187 188 wc->qp = &cqe_qp->ibqp; 189 190 if (ionic_v1_cqe_error(cqe)) { 191 wc->vendor_err = st_len; 192 wc->status = ionic_to_ib_status(st_len); 193 194 cqe_qp->rq.flush = true; 195 cq->flush = true; 196 list_move_tail(&qp->rq.cq_flush, &cq->flush_rq); 197 198 ibdev_warn(&dev->ibdev, 199 "qp %d recv cqe with error\n", qp->qpid); 200 print_hex_dump(KERN_WARNING, "cqe ", DUMP_PREFIX_OFFSET, 16, 1, 201 cqe, BIT(cq->q.stride_log2), true); 202 goto out; 203 } 204 205 wc->vendor_err = 0; 206 wc->status = IB_WC_SUCCESS; 207 208 src_qpn = be32_to_cpu(cqe->recv.src_qpn_op); 209 op = src_qpn >> IONIC_V1_CQE_RECV_OP_SHIFT; 210 211 src_qpn &= IONIC_V1_CQE_RECV_QPN_MASK; 212 op &= IONIC_V1_CQE_RECV_OP_MASK; 213 214 wc->opcode = IB_WC_RECV; 215 switch (op) { 216 case IONIC_V1_CQE_RECV_OP_RDMA_IMM: 217 wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; 218 wc->wc_flags |= IB_WC_WITH_IMM; 219 wc->ex.imm_data = cqe->recv.imm_data_rkey; /* be32 in wc */ 220 break; 221 case IONIC_V1_CQE_RECV_OP_SEND_IMM: 222 wc->wc_flags |= IB_WC_WITH_IMM; 223 wc->ex.imm_data = cqe->recv.imm_data_rkey; /* be32 in wc */ 224 break; 225 case IONIC_V1_CQE_RECV_OP_SEND_INV: 226 wc->wc_flags |= IB_WC_WITH_INVALIDATE; 227 wc->ex.invalidate_rkey = be32_to_cpu(cqe->recv.imm_data_rkey); 228 break; 229 } 230 231 wc->byte_len = st_len; 232 wc->src_qp = src_qpn; 233 234 if (qp->ibqp.qp_type == IB_QPT_UD || 235 qp->ibqp.qp_type == IB_QPT_GSI) { 236 wc->wc_flags |= IB_WC_GRH | IB_WC_WITH_SMAC; 237 ether_addr_copy(wc->smac, cqe->recv.src_mac); 238 239 wc->wc_flags |= IB_WC_WITH_NETWORK_HDR_TYPE; 240 if (ionic_v1_cqe_recv_is_ipv4(cqe)) 241 wc->network_hdr_type = RDMA_NETWORK_IPV4; 242 else 243 wc->network_hdr_type = RDMA_NETWORK_IPV6; 244 245 if (ionic_v1_cqe_recv_is_vlan(cqe)) 246 wc->wc_flags |= IB_WC_WITH_VLAN; 247 248 /* vlan_tag in cqe will be valid from dpath even if no vlan */ 249 vlan_tag = be16_to_cpu(cqe->recv.vlan_tag); 250 wc->vlan_id = vlan_tag & 0xfff; /* 802.1q VID */ 251 wc->sl = vlan_tag >> VLAN_PRIO_SHIFT; /* 802.1q PCP */ 252 } 253 254 wc->pkey_index = 0; 255 wc->port_num = 1; 256 257 out: 258 ionic_queue_consume(&qp->rq.q); 259 260 return 1; 261 } 262 263 static bool ionic_peek_send(struct ionic_qp *qp) 264 { 265 struct ionic_sq_meta *meta; 266 267 if (qp->sq_flush) 268 return false; 269 270 /* completed all send queue requests */ 271 if (ionic_queue_empty(&qp->sq)) 272 return false; 273 274 meta = &qp->sq_meta[qp->sq.cons]; 275 276 /* waiting for remote completion */ 277 if (meta->remote && meta->seq == qp->sq_msn_cons) 278 return false; 279 280 /* waiting for local completion */ 281 if (!meta->remote && !meta->local_comp) 282 return false; 283 284 return true; 285 } 286 287 static int ionic_poll_send(struct ionic_ibdev *dev, struct ionic_cq *cq, 288 struct ionic_qp *qp, struct ib_wc *wc) 289 { 290 struct ionic_sq_meta *meta; 291 292 if (qp->sq_flush) 293 return 0; 294 295 do { 296 /* completed all send queue requests */ 297 if (ionic_queue_empty(&qp->sq)) 298 goto out_empty; 299 300 meta = &qp->sq_meta[qp->sq.cons]; 301 302 /* waiting for remote completion */ 303 if (meta->remote && meta->seq == qp->sq_msn_cons) 304 goto out_empty; 305 306 /* waiting for local completion */ 307 if (!meta->remote && !meta->local_comp) 308 goto out_empty; 309 310 ionic_queue_consume(&qp->sq); 311 312 /* produce wc only if signaled or error status */ 313 } while (!meta->signal && meta->ibsts == IB_WC_SUCCESS); 314 315 memset(wc, 0, sizeof(*wc)); 316 317 wc->status = meta->ibsts; 318 wc->wr_id = meta->wrid; 319 wc->qp = &qp->ibqp; 320 321 if (meta->ibsts == IB_WC_SUCCESS) { 322 wc->byte_len = meta->len; 323 wc->opcode = meta->ibop; 324 } else { 325 wc->vendor_err = meta->len; 326 327 qp->sq_flush = true; 328 cq->flush = true; 329 list_move_tail(&qp->cq_flush_sq, &cq->flush_sq); 330 } 331 332 return 1; 333 334 out_empty: 335 if (qp->sq_flush_rcvd) { 336 qp->sq_flush = true; 337 cq->flush = true; 338 list_move_tail(&qp->cq_flush_sq, &cq->flush_sq); 339 } 340 return 0; 341 } 342 343 static int ionic_poll_send_many(struct ionic_ibdev *dev, struct ionic_cq *cq, 344 struct ionic_qp *qp, struct ib_wc *wc, int nwc) 345 { 346 int rc = 0, npolled = 0; 347 348 while (npolled < nwc) { 349 rc = ionic_poll_send(dev, cq, qp, wc + npolled); 350 if (rc <= 0) 351 break; 352 353 npolled += rc; 354 } 355 356 return npolled ?: rc; 357 } 358 359 static int ionic_validate_cons(u16 prod, u16 cons, 360 u16 comp, u16 mask) 361 { 362 if (((prod - cons) & mask) <= ((comp - cons) & mask)) 363 return -EIO; 364 365 return 0; 366 } 367 368 static int ionic_comp_msn(struct ionic_qp *qp, struct ionic_v1_cqe *cqe) 369 { 370 struct ionic_sq_meta *meta; 371 u16 cqe_seq, cqe_idx; 372 int rc; 373 374 if (qp->sq_flush) 375 return 0; 376 377 cqe_seq = be32_to_cpu(cqe->send.msg_msn) & qp->sq.mask; 378 379 rc = ionic_validate_cons(qp->sq_msn_prod, 380 qp->sq_msn_cons, 381 cqe_seq - 1, 382 qp->sq.mask); 383 if (rc) { 384 ibdev_warn(qp->ibqp.device, 385 "qp %u bad msn %#x seq %u for prod %u cons %u\n", 386 qp->qpid, be32_to_cpu(cqe->send.msg_msn), 387 cqe_seq, qp->sq_msn_prod, qp->sq_msn_cons); 388 return rc; 389 } 390 391 qp->sq_msn_cons = cqe_seq; 392 393 if (ionic_v1_cqe_error(cqe)) { 394 cqe_idx = qp->sq_msn_idx[(cqe_seq - 1) & qp->sq.mask]; 395 396 meta = &qp->sq_meta[cqe_idx]; 397 meta->len = be32_to_cpu(cqe->status_length); 398 meta->ibsts = ionic_to_ib_status(meta->len); 399 400 ibdev_warn(qp->ibqp.device, 401 "qp %d msn cqe with error\n", qp->qpid); 402 print_hex_dump(KERN_WARNING, "cqe ", DUMP_PREFIX_OFFSET, 16, 1, 403 cqe, sizeof(*cqe), true); 404 } 405 406 return 0; 407 } 408 409 static int ionic_comp_npg(struct ionic_qp *qp, struct ionic_v1_cqe *cqe) 410 { 411 struct ionic_sq_meta *meta; 412 u16 wqe_idx; 413 u32 st_len; 414 415 if (qp->sq_flush) 416 return 0; 417 418 st_len = be32_to_cpu(cqe->status_length); 419 420 if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) { 421 /* 422 * Flush cqe does not consume a wqe on the device, and maybe 423 * no such work request is posted. 424 * 425 * The driver should begin flushing after the last indicated 426 * normal or error completion. Here, only set a hint that the 427 * flush request was indicated. In poll_send, if nothing more 428 * can be polled normally, then begin flushing. 429 */ 430 qp->sq_flush_rcvd = true; 431 return 0; 432 } 433 434 wqe_idx = le64_to_cpu(cqe->send.npg_wqe_idx_timestamp) & qp->sq.mask; 435 meta = &qp->sq_meta[wqe_idx]; 436 meta->local_comp = true; 437 438 if (ionic_v1_cqe_error(cqe)) { 439 meta->len = st_len; 440 meta->ibsts = ionic_to_ib_status(st_len); 441 meta->remote = false; 442 ibdev_warn(qp->ibqp.device, 443 "qp %d npg cqe with error\n", qp->qpid); 444 print_hex_dump(KERN_WARNING, "cqe ", DUMP_PREFIX_OFFSET, 16, 1, 445 cqe, sizeof(*cqe), true); 446 } 447 448 return 0; 449 } 450 451 static void ionic_reserve_sync_cq(struct ionic_ibdev *dev, struct ionic_cq *cq) 452 { 453 if (!ionic_queue_empty(&cq->q)) { 454 cq->credit += ionic_queue_length(&cq->q); 455 cq->q.cons = cq->q.prod; 456 457 ionic_dbell_ring(dev->lif_cfg.dbpage, dev->lif_cfg.cq_qtype, 458 ionic_queue_dbell_val(&cq->q)); 459 } 460 } 461 462 static void ionic_reserve_cq(struct ionic_ibdev *dev, struct ionic_cq *cq, 463 int spend) 464 { 465 cq->credit -= spend; 466 467 if (cq->credit <= 0) 468 ionic_reserve_sync_cq(dev, cq); 469 } 470 471 static int ionic_poll_vcq_cq(struct ionic_ibdev *dev, 472 struct ionic_cq *cq, 473 int nwc, struct ib_wc *wc) 474 { 475 struct ionic_qp *qp, *qp_next; 476 struct ionic_v1_cqe *cqe; 477 int rc = 0, npolled = 0; 478 unsigned long irqflags; 479 u32 qtf, qid; 480 bool peek; 481 u8 type; 482 483 if (nwc < 1) 484 return 0; 485 486 spin_lock_irqsave(&cq->lock, irqflags); 487 488 /* poll already indicated work completions for send queue */ 489 list_for_each_entry_safe(qp, qp_next, &cq->poll_sq, cq_poll_sq) { 490 if (npolled == nwc) 491 goto out; 492 493 spin_lock(&qp->sq_lock); 494 rc = ionic_poll_send_many(dev, cq, qp, wc + npolled, 495 nwc - npolled); 496 spin_unlock(&qp->sq_lock); 497 498 if (rc > 0) 499 npolled += rc; 500 501 if (npolled < nwc) 502 list_del_init(&qp->cq_poll_sq); 503 } 504 505 /* poll for more work completions */ 506 while (likely(ionic_next_cqe(dev, cq, &cqe))) { 507 if (npolled == nwc) 508 goto out; 509 510 qtf = ionic_v1_cqe_qtf(cqe); 511 qid = ionic_v1_cqe_qtf_qid(qtf); 512 type = ionic_v1_cqe_qtf_type(qtf); 513 514 /* 515 * Safe to access QP without additional reference here as, 516 * 1. We hold cq->lock throughout 517 * 2. ionic_destroy_qp() acquires the same cq->lock before cleanup 518 * 3. QP is removed from qp_tbl before any cleanup begins 519 * This ensures no concurrent access between polling and destruction. 520 */ 521 qp = xa_load(&dev->qp_tbl, qid); 522 if (unlikely(!qp)) { 523 ibdev_dbg(&dev->ibdev, "missing qp for qid %u\n", qid); 524 goto cq_next; 525 } 526 527 switch (type) { 528 case IONIC_V1_CQE_TYPE_RECV: 529 if (qp->srq) { 530 ibdev_dbg(&dev->ibdev, 531 "srq recv cqe for qp %u\n", qid); 532 goto cq_next; 533 } 534 535 spin_lock(&qp->rq.lock); 536 rc = ionic_poll_recv(dev, cq, qp, cqe, wc + npolled); 537 spin_unlock(&qp->rq.lock); 538 539 if (rc < 0) 540 goto out; 541 542 npolled += rc; 543 544 break; 545 546 case IONIC_V1_CQE_TYPE_SEND_MSN: 547 spin_lock(&qp->sq_lock); 548 rc = ionic_comp_msn(qp, cqe); 549 if (!rc) { 550 rc = ionic_poll_send_many(dev, cq, qp, 551 wc + npolled, 552 nwc - npolled); 553 peek = ionic_peek_send(qp); 554 } 555 spin_unlock(&qp->sq_lock); 556 557 if (rc < 0) 558 goto out; 559 560 npolled += rc; 561 562 if (peek) 563 list_move_tail(&qp->cq_poll_sq, &cq->poll_sq); 564 break; 565 566 case IONIC_V1_CQE_TYPE_SEND_NPG: 567 spin_lock(&qp->sq_lock); 568 rc = ionic_comp_npg(qp, cqe); 569 if (!rc) { 570 rc = ionic_poll_send_many(dev, cq, qp, 571 wc + npolled, 572 nwc - npolled); 573 peek = ionic_peek_send(qp); 574 } 575 spin_unlock(&qp->sq_lock); 576 577 if (rc < 0) 578 goto out; 579 580 npolled += rc; 581 582 if (peek) 583 list_move_tail(&qp->cq_poll_sq, &cq->poll_sq); 584 break; 585 586 default: 587 ibdev_warn(&dev->ibdev, 588 "unexpected cqe type %u\n", type); 589 rc = -EIO; 590 goto out; 591 } 592 593 cq_next: 594 ionic_queue_produce(&cq->q); 595 cq->color = ionic_color_wrap(cq->q.prod, cq->color); 596 } 597 598 /* lastly, flush send and recv queues */ 599 if (likely(!cq->flush)) 600 goto out; 601 602 cq->flush = false; 603 604 list_for_each_entry_safe(qp, qp_next, &cq->flush_sq, cq_flush_sq) { 605 if (npolled == nwc) 606 goto out; 607 608 spin_lock(&qp->sq_lock); 609 rc = ionic_flush_send_many(qp, wc + npolled, nwc - npolled); 610 spin_unlock(&qp->sq_lock); 611 612 if (rc > 0) 613 npolled += rc; 614 615 if (npolled < nwc) 616 list_del_init(&qp->cq_flush_sq); 617 else 618 cq->flush = true; 619 } 620 621 list_for_each_entry_safe(qp, qp_next, &cq->flush_rq, rq.cq_flush) { 622 if (npolled == nwc) 623 goto out; 624 625 spin_lock(&qp->rq.lock); 626 rc = ionic_flush_recv_many(qp, wc + npolled, nwc - npolled); 627 spin_unlock(&qp->rq.lock); 628 629 if (rc > 0) 630 npolled += rc; 631 632 if (npolled < nwc) 633 list_del_init(&qp->rq.cq_flush); 634 else 635 cq->flush = true; 636 } 637 638 out: 639 /* in case credit was depleted (more work posted than cq depth) */ 640 if (cq->credit <= 0) 641 ionic_reserve_sync_cq(dev, cq); 642 643 spin_unlock_irqrestore(&cq->lock, irqflags); 644 645 return npolled ?: rc; 646 } 647 648 int ionic_poll_cq(struct ib_cq *ibcq, int nwc, struct ib_wc *wc) 649 { 650 struct ionic_ibdev *dev = to_ionic_ibdev(ibcq->device); 651 struct ionic_vcq *vcq = to_ionic_vcq(ibcq); 652 int rc_tmp, rc = 0, npolled = 0; 653 int cq_i, cq_x, cq_ix; 654 655 cq_x = vcq->poll_idx; 656 vcq->poll_idx ^= dev->lif_cfg.udma_count - 1; 657 658 for (cq_i = 0; npolled < nwc && cq_i < dev->lif_cfg.udma_count; ++cq_i) { 659 cq_ix = cq_i ^ cq_x; 660 661 if (!(vcq->udma_mask & BIT(cq_ix))) 662 continue; 663 664 rc_tmp = ionic_poll_vcq_cq(dev, &vcq->cq[cq_ix], 665 nwc - npolled, 666 wc + npolled); 667 668 if (rc_tmp >= 0) 669 npolled += rc_tmp; 670 else if (!rc) 671 rc = rc_tmp; 672 } 673 674 return npolled ?: rc; 675 } 676 677 static int ionic_req_notify_vcq_cq(struct ionic_ibdev *dev, struct ionic_cq *cq, 678 enum ib_cq_notify_flags flags) 679 { 680 u64 dbell_val = cq->q.dbell; 681 682 if (flags & IB_CQ_SOLICITED) { 683 cq->arm_sol_prod = ionic_queue_next(&cq->q, cq->arm_sol_prod); 684 dbell_val |= cq->arm_sol_prod | IONIC_CQ_RING_SOL; 685 } else { 686 cq->arm_any_prod = ionic_queue_next(&cq->q, cq->arm_any_prod); 687 dbell_val |= cq->arm_any_prod | IONIC_CQ_RING_ARM; 688 } 689 690 ionic_reserve_sync_cq(dev, cq); 691 692 ionic_dbell_ring(dev->lif_cfg.dbpage, dev->lif_cfg.cq_qtype, dbell_val); 693 694 /* 695 * IB_CQ_REPORT_MISSED_EVENTS: 696 * 697 * The queue index in ring zero guarantees no missed events. 698 * 699 * Here, we check if the color bit in the next cqe is flipped. If it 700 * is flipped, then progress can be made by immediately polling the cq. 701 * Still, the cq will be armed, and an event will be generated. The cq 702 * may be empty when polled after the event, because the next poll 703 * after arming the cq can empty it. 704 */ 705 return (flags & IB_CQ_REPORT_MISSED_EVENTS) && 706 cq->color == ionic_v1_cqe_color(ionic_queue_at_prod(&cq->q)); 707 } 708 709 int ionic_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) 710 { 711 struct ionic_ibdev *dev = to_ionic_ibdev(ibcq->device); 712 struct ionic_vcq *vcq = to_ionic_vcq(ibcq); 713 int rc = 0, cq_i; 714 715 for (cq_i = 0; cq_i < dev->lif_cfg.udma_count; ++cq_i) { 716 if (!(vcq->udma_mask & BIT(cq_i))) 717 continue; 718 719 if (ionic_req_notify_vcq_cq(dev, &vcq->cq[cq_i], flags)) 720 rc = 1; 721 } 722 723 return rc; 724 } 725 726 static s64 ionic_prep_inline(void *data, u32 max_data, 727 const struct ib_sge *ib_sgl, int num_sge) 728 { 729 static const s64 bit_31 = 1u << 31; 730 s64 len = 0, sg_len; 731 int sg_i; 732 733 for (sg_i = 0; sg_i < num_sge; ++sg_i) { 734 sg_len = ib_sgl[sg_i].length; 735 736 /* sge length zero means 2GB */ 737 if (unlikely(sg_len == 0)) 738 sg_len = bit_31; 739 740 /* greater than max inline data is invalid */ 741 if (unlikely(len + sg_len > max_data)) 742 return -EINVAL; 743 744 memcpy(data + len, (void *)ib_sgl[sg_i].addr, sg_len); 745 746 len += sg_len; 747 } 748 749 return len; 750 } 751 752 static s64 ionic_prep_pld(struct ionic_v1_wqe *wqe, 753 union ionic_v1_pld *pld, 754 int spec, u32 max_sge, 755 const struct ib_sge *ib_sgl, 756 int num_sge) 757 { 758 static const s64 bit_31 = 1l << 31; 759 struct ionic_sge *sgl; 760 __be32 *spec32 = NULL; 761 __be16 *spec16 = NULL; 762 s64 len = 0, sg_len; 763 int sg_i = 0; 764 765 if (unlikely(num_sge < 0 || (u32)num_sge > max_sge)) 766 return -EINVAL; 767 768 if (spec && num_sge > IONIC_V1_SPEC_FIRST_SGE) { 769 sg_i = IONIC_V1_SPEC_FIRST_SGE; 770 771 if (num_sge > 8) { 772 wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_SPEC16); 773 spec16 = pld->spec16; 774 } else { 775 wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_SPEC32); 776 spec32 = pld->spec32; 777 } 778 } 779 780 sgl = &pld->sgl[sg_i]; 781 782 for (sg_i = 0; sg_i < num_sge; ++sg_i) { 783 sg_len = ib_sgl[sg_i].length; 784 785 /* sge length zero means 2GB */ 786 if (unlikely(sg_len == 0)) 787 sg_len = bit_31; 788 789 /* greater than 2GB data is invalid */ 790 if (unlikely(len + sg_len > bit_31)) 791 return -EINVAL; 792 793 sgl[sg_i].va = cpu_to_be64(ib_sgl[sg_i].addr); 794 sgl[sg_i].len = cpu_to_be32(sg_len); 795 sgl[sg_i].lkey = cpu_to_be32(ib_sgl[sg_i].lkey); 796 797 if (spec32) { 798 spec32[sg_i] = sgl[sg_i].len; 799 } else if (spec16) { 800 if (unlikely(sg_len > U16_MAX)) 801 return -EINVAL; 802 spec16[sg_i] = cpu_to_be16(sg_len); 803 } 804 805 len += sg_len; 806 } 807 808 return len; 809 } 810 811 static void ionic_prep_base(struct ionic_qp *qp, 812 const struct ib_send_wr *wr, 813 struct ionic_sq_meta *meta, 814 struct ionic_v1_wqe *wqe) 815 { 816 meta->wrid = wr->wr_id; 817 meta->ibsts = IB_WC_SUCCESS; 818 meta->signal = false; 819 meta->local_comp = false; 820 821 wqe->base.wqe_idx = cpu_to_le64(qp->sq.prod); 822 823 if (wr->send_flags & IB_SEND_FENCE) 824 wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_FENCE); 825 826 if (wr->send_flags & IB_SEND_SOLICITED) 827 wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_SOL); 828 829 if (qp->sig_all || wr->send_flags & IB_SEND_SIGNALED) { 830 wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_SIG); 831 meta->signal = true; 832 } 833 834 meta->seq = qp->sq_msn_prod; 835 meta->remote = 836 qp->ibqp.qp_type != IB_QPT_UD && 837 qp->ibqp.qp_type != IB_QPT_GSI && 838 !ionic_ibop_is_local(wr->opcode); 839 840 if (meta->remote) { 841 qp->sq_msn_idx[meta->seq] = qp->sq.prod; 842 qp->sq_msn_prod = ionic_queue_next(&qp->sq, qp->sq_msn_prod); 843 } 844 845 ionic_queue_produce(&qp->sq); 846 } 847 848 static int ionic_prep_common(struct ionic_qp *qp, 849 const struct ib_send_wr *wr, 850 struct ionic_sq_meta *meta, 851 struct ionic_v1_wqe *wqe) 852 { 853 s64 signed_len; 854 u32 mval; 855 856 if (wr->send_flags & IB_SEND_INLINE) { 857 wqe->base.num_sge_key = 0; 858 wqe->base.flags |= cpu_to_be16(IONIC_V1_FLAG_INL); 859 mval = ionic_v1_send_wqe_max_data(qp->sq.stride_log2, false); 860 signed_len = ionic_prep_inline(wqe->common.pld.data, mval, 861 wr->sg_list, wr->num_sge); 862 } else { 863 wqe->base.num_sge_key = wr->num_sge; 864 mval = ionic_v1_send_wqe_max_sge(qp->sq.stride_log2, 865 qp->sq_spec, 866 false); 867 signed_len = ionic_prep_pld(wqe, &wqe->common.pld, 868 qp->sq_spec, mval, 869 wr->sg_list, wr->num_sge); 870 } 871 872 if (unlikely(signed_len < 0)) 873 return signed_len; 874 875 meta->len = signed_len; 876 wqe->common.length = cpu_to_be32(signed_len); 877 878 ionic_prep_base(qp, wr, meta, wqe); 879 880 return 0; 881 } 882 883 static void ionic_prep_sq_wqe(struct ionic_qp *qp, void *wqe) 884 { 885 memset(wqe, 0, 1u << qp->sq.stride_log2); 886 } 887 888 static void ionic_prep_rq_wqe(struct ionic_qp *qp, void *wqe) 889 { 890 memset(wqe, 0, 1u << qp->rq.q.stride_log2); 891 } 892 893 static int ionic_prep_send(struct ionic_qp *qp, 894 const struct ib_send_wr *wr) 895 { 896 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 897 struct ionic_sq_meta *meta; 898 struct ionic_v1_wqe *wqe; 899 900 meta = &qp->sq_meta[qp->sq.prod]; 901 wqe = ionic_queue_at_prod(&qp->sq); 902 903 ionic_prep_sq_wqe(qp, wqe); 904 905 meta->ibop = IB_WC_SEND; 906 907 switch (wr->opcode) { 908 case IB_WR_SEND: 909 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, SEND); 910 break; 911 case IB_WR_SEND_WITH_IMM: 912 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, SEND_IMM); 913 wqe->base.imm_data_key = wr->ex.imm_data; 914 break; 915 case IB_WR_SEND_WITH_INV: 916 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, SEND_INV); 917 wqe->base.imm_data_key = 918 cpu_to_be32(wr->ex.invalidate_rkey); 919 break; 920 default: 921 return -EINVAL; 922 } 923 924 return ionic_prep_common(qp, wr, meta, wqe); 925 } 926 927 static int ionic_prep_send_ud(struct ionic_qp *qp, 928 const struct ib_ud_wr *wr) 929 { 930 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 931 struct ionic_sq_meta *meta; 932 struct ionic_v1_wqe *wqe; 933 struct ionic_ah *ah; 934 935 if (unlikely(!wr->ah)) 936 return -EINVAL; 937 938 ah = to_ionic_ah(wr->ah); 939 940 meta = &qp->sq_meta[qp->sq.prod]; 941 wqe = ionic_queue_at_prod(&qp->sq); 942 943 ionic_prep_sq_wqe(qp, wqe); 944 945 wqe->common.send.ah_id = cpu_to_be32(ah->ahid); 946 wqe->common.send.dest_qpn = cpu_to_be32(wr->remote_qpn); 947 wqe->common.send.dest_qkey = cpu_to_be32(wr->remote_qkey); 948 949 meta->ibop = IB_WC_SEND; 950 951 switch (wr->wr.opcode) { 952 case IB_WR_SEND: 953 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, SEND); 954 break; 955 case IB_WR_SEND_WITH_IMM: 956 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, SEND_IMM); 957 wqe->base.imm_data_key = wr->wr.ex.imm_data; 958 break; 959 default: 960 return -EINVAL; 961 } 962 963 return ionic_prep_common(qp, &wr->wr, meta, wqe); 964 } 965 966 static int ionic_prep_rdma(struct ionic_qp *qp, 967 const struct ib_rdma_wr *wr) 968 { 969 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 970 struct ionic_sq_meta *meta; 971 struct ionic_v1_wqe *wqe; 972 973 meta = &qp->sq_meta[qp->sq.prod]; 974 wqe = ionic_queue_at_prod(&qp->sq); 975 976 ionic_prep_sq_wqe(qp, wqe); 977 978 meta->ibop = IB_WC_RDMA_WRITE; 979 980 switch (wr->wr.opcode) { 981 case IB_WR_RDMA_READ: 982 if (wr->wr.send_flags & (IB_SEND_SOLICITED | IB_SEND_INLINE)) 983 return -EINVAL; 984 meta->ibop = IB_WC_RDMA_READ; 985 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, RDMA_READ); 986 break; 987 case IB_WR_RDMA_WRITE: 988 if (wr->wr.send_flags & IB_SEND_SOLICITED) 989 return -EINVAL; 990 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, RDMA_WRITE); 991 break; 992 case IB_WR_RDMA_WRITE_WITH_IMM: 993 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, RDMA_WRITE_IMM); 994 wqe->base.imm_data_key = wr->wr.ex.imm_data; 995 break; 996 default: 997 return -EINVAL; 998 } 999 1000 wqe->common.rdma.remote_va_high = cpu_to_be32(wr->remote_addr >> 32); 1001 wqe->common.rdma.remote_va_low = cpu_to_be32(wr->remote_addr); 1002 wqe->common.rdma.remote_rkey = cpu_to_be32(wr->rkey); 1003 1004 return ionic_prep_common(qp, &wr->wr, meta, wqe); 1005 } 1006 1007 static int ionic_prep_atomic(struct ionic_qp *qp, 1008 const struct ib_atomic_wr *wr) 1009 { 1010 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 1011 struct ionic_sq_meta *meta; 1012 struct ionic_v1_wqe *wqe; 1013 1014 if (wr->wr.num_sge != 1 || wr->wr.sg_list[0].length != 8) 1015 return -EINVAL; 1016 1017 if (wr->wr.send_flags & (IB_SEND_SOLICITED | IB_SEND_INLINE)) 1018 return -EINVAL; 1019 1020 meta = &qp->sq_meta[qp->sq.prod]; 1021 wqe = ionic_queue_at_prod(&qp->sq); 1022 1023 ionic_prep_sq_wqe(qp, wqe); 1024 1025 meta->ibop = IB_WC_RDMA_WRITE; 1026 1027 switch (wr->wr.opcode) { 1028 case IB_WR_ATOMIC_CMP_AND_SWP: 1029 meta->ibop = IB_WC_COMP_SWAP; 1030 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, ATOMIC_CS); 1031 wqe->atomic.swap_add_high = cpu_to_be32(wr->swap >> 32); 1032 wqe->atomic.swap_add_low = cpu_to_be32(wr->swap); 1033 wqe->atomic.compare_high = cpu_to_be32(wr->compare_add >> 32); 1034 wqe->atomic.compare_low = cpu_to_be32(wr->compare_add); 1035 break; 1036 case IB_WR_ATOMIC_FETCH_AND_ADD: 1037 meta->ibop = IB_WC_FETCH_ADD; 1038 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, ATOMIC_FA); 1039 wqe->atomic.swap_add_high = cpu_to_be32(wr->compare_add >> 32); 1040 wqe->atomic.swap_add_low = cpu_to_be32(wr->compare_add); 1041 break; 1042 default: 1043 return -EINVAL; 1044 } 1045 1046 wqe->atomic.remote_va_high = cpu_to_be32(wr->remote_addr >> 32); 1047 wqe->atomic.remote_va_low = cpu_to_be32(wr->remote_addr); 1048 wqe->atomic.remote_rkey = cpu_to_be32(wr->rkey); 1049 1050 wqe->base.num_sge_key = 1; 1051 wqe->atomic.sge.va = cpu_to_be64(wr->wr.sg_list[0].addr); 1052 wqe->atomic.sge.len = cpu_to_be32(8); 1053 wqe->atomic.sge.lkey = cpu_to_be32(wr->wr.sg_list[0].lkey); 1054 1055 return ionic_prep_common(qp, &wr->wr, meta, wqe); 1056 } 1057 1058 static int ionic_prep_inv(struct ionic_qp *qp, 1059 const struct ib_send_wr *wr) 1060 { 1061 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 1062 struct ionic_sq_meta *meta; 1063 struct ionic_v1_wqe *wqe; 1064 1065 if (wr->send_flags & (IB_SEND_SOLICITED | IB_SEND_INLINE)) 1066 return -EINVAL; 1067 1068 meta = &qp->sq_meta[qp->sq.prod]; 1069 wqe = ionic_queue_at_prod(&qp->sq); 1070 1071 ionic_prep_sq_wqe(qp, wqe); 1072 1073 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, LOCAL_INV); 1074 wqe->base.imm_data_key = cpu_to_be32(wr->ex.invalidate_rkey); 1075 1076 meta->len = 0; 1077 meta->ibop = IB_WC_LOCAL_INV; 1078 1079 ionic_prep_base(qp, wr, meta, wqe); 1080 1081 return 0; 1082 } 1083 1084 static int ionic_prep_reg(struct ionic_qp *qp, 1085 const struct ib_reg_wr *wr) 1086 { 1087 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 1088 struct ionic_mr *mr = to_ionic_mr(wr->mr); 1089 struct ionic_sq_meta *meta; 1090 struct ionic_v1_wqe *wqe; 1091 __le64 dma_addr; 1092 int flags; 1093 1094 if (wr->wr.send_flags & (IB_SEND_SOLICITED | IB_SEND_INLINE)) 1095 return -EINVAL; 1096 1097 /* must call ib_map_mr_sg before posting reg wr */ 1098 if (!mr->buf.tbl_pages) 1099 return -EINVAL; 1100 1101 meta = &qp->sq_meta[qp->sq.prod]; 1102 wqe = ionic_queue_at_prod(&qp->sq); 1103 1104 ionic_prep_sq_wqe(qp, wqe); 1105 1106 flags = to_ionic_mr_flags(wr->access); 1107 1108 wqe->base.op = IONIC_OP(dev->lif_cfg.rdma_version, REG_MR); 1109 wqe->base.num_sge_key = wr->key; 1110 wqe->base.imm_data_key = cpu_to_be32(mr->ibmr.lkey); 1111 wqe->reg_mr.va = cpu_to_be64(mr->ibmr.iova); 1112 wqe->reg_mr.length = cpu_to_be64(mr->ibmr.length); 1113 wqe->reg_mr.offset = ionic_pgtbl_off(&mr->buf, mr->ibmr.iova); 1114 dma_addr = ionic_pgtbl_dma(&mr->buf, mr->ibmr.iova); 1115 wqe->reg_mr.dma_addr = cpu_to_be64(le64_to_cpu(dma_addr)); 1116 1117 wqe->reg_mr.map_count = cpu_to_be32(mr->buf.tbl_pages); 1118 wqe->reg_mr.flags = cpu_to_be16(flags); 1119 wqe->reg_mr.dir_size_log2 = 0; 1120 wqe->reg_mr.page_size_log2 = order_base_2(mr->ibmr.page_size); 1121 1122 meta->len = 0; 1123 meta->ibop = IB_WC_REG_MR; 1124 1125 ionic_prep_base(qp, &wr->wr, meta, wqe); 1126 1127 return 0; 1128 } 1129 1130 static int ionic_prep_one_rc(struct ionic_qp *qp, 1131 const struct ib_send_wr *wr) 1132 { 1133 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 1134 int rc = 0; 1135 1136 switch (wr->opcode) { 1137 case IB_WR_SEND: 1138 case IB_WR_SEND_WITH_IMM: 1139 case IB_WR_SEND_WITH_INV: 1140 rc = ionic_prep_send(qp, wr); 1141 break; 1142 case IB_WR_RDMA_READ: 1143 case IB_WR_RDMA_WRITE: 1144 case IB_WR_RDMA_WRITE_WITH_IMM: 1145 rc = ionic_prep_rdma(qp, rdma_wr(wr)); 1146 break; 1147 case IB_WR_ATOMIC_CMP_AND_SWP: 1148 case IB_WR_ATOMIC_FETCH_AND_ADD: 1149 rc = ionic_prep_atomic(qp, atomic_wr(wr)); 1150 break; 1151 case IB_WR_LOCAL_INV: 1152 rc = ionic_prep_inv(qp, wr); 1153 break; 1154 case IB_WR_REG_MR: 1155 rc = ionic_prep_reg(qp, reg_wr(wr)); 1156 break; 1157 default: 1158 ibdev_dbg(&dev->ibdev, "invalid opcode %d\n", wr->opcode); 1159 rc = -EINVAL; 1160 } 1161 1162 return rc; 1163 } 1164 1165 static int ionic_prep_one_ud(struct ionic_qp *qp, 1166 const struct ib_send_wr *wr) 1167 { 1168 struct ionic_ibdev *dev = to_ionic_ibdev(qp->ibqp.device); 1169 int rc = 0; 1170 1171 switch (wr->opcode) { 1172 case IB_WR_SEND: 1173 case IB_WR_SEND_WITH_IMM: 1174 rc = ionic_prep_send_ud(qp, ud_wr(wr)); 1175 break; 1176 default: 1177 ibdev_dbg(&dev->ibdev, "invalid opcode %d\n", wr->opcode); 1178 rc = -EINVAL; 1179 } 1180 1181 return rc; 1182 } 1183 1184 static int ionic_prep_recv(struct ionic_qp *qp, 1185 const struct ib_recv_wr *wr) 1186 { 1187 struct ionic_rq_meta *meta; 1188 struct ionic_v1_wqe *wqe; 1189 s64 signed_len; 1190 u32 mval; 1191 1192 wqe = ionic_queue_at_prod(&qp->rq.q); 1193 1194 /* if wqe is owned by device, caller can try posting again soon */ 1195 if (wqe->base.flags & cpu_to_be16(IONIC_V1_FLAG_FENCE)) 1196 return -EAGAIN; 1197 1198 meta = qp->rq.meta_head; 1199 if (unlikely(meta == IONIC_META_LAST) || 1200 unlikely(meta == IONIC_META_POSTED)) 1201 return -EIO; 1202 1203 ionic_prep_rq_wqe(qp, wqe); 1204 1205 mval = ionic_v1_recv_wqe_max_sge(qp->rq.q.stride_log2, qp->rq.spec, 1206 false); 1207 signed_len = ionic_prep_pld(wqe, &wqe->recv.pld, 1208 qp->rq.spec, mval, 1209 wr->sg_list, wr->num_sge); 1210 if (signed_len < 0) 1211 return signed_len; 1212 1213 meta->wrid = wr->wr_id; 1214 1215 wqe->base.wqe_idx = cpu_to_le64(meta - qp->rq.meta); 1216 wqe->base.num_sge_key = wr->num_sge; 1217 1218 /* total length for recv goes in base imm_data_key */ 1219 wqe->base.imm_data_key = cpu_to_be32(signed_len); 1220 1221 ionic_queue_produce(&qp->rq.q); 1222 1223 qp->rq.meta_head = meta->next; 1224 meta->next = IONIC_META_POSTED; 1225 1226 return 0; 1227 } 1228 1229 static int ionic_post_send_common(struct ionic_ibdev *dev, 1230 struct ionic_vcq *vcq, 1231 struct ionic_cq *cq, 1232 struct ionic_qp *qp, 1233 const struct ib_send_wr *wr, 1234 const struct ib_send_wr **bad) 1235 { 1236 unsigned long irqflags; 1237 bool notify = false; 1238 int spend, rc = 0; 1239 1240 if (!bad) 1241 return -EINVAL; 1242 1243 if (!qp->has_sq) { 1244 *bad = wr; 1245 return -EINVAL; 1246 } 1247 1248 if (qp->state < IB_QPS_RTS) { 1249 *bad = wr; 1250 return -EINVAL; 1251 } 1252 1253 spin_lock_irqsave(&qp->sq_lock, irqflags); 1254 1255 while (wr) { 1256 if (ionic_queue_full(&qp->sq)) { 1257 ibdev_dbg(&dev->ibdev, "queue full"); 1258 rc = -ENOMEM; 1259 goto out; 1260 } 1261 1262 if (qp->ibqp.qp_type == IB_QPT_UD || 1263 qp->ibqp.qp_type == IB_QPT_GSI) 1264 rc = ionic_prep_one_ud(qp, wr); 1265 else 1266 rc = ionic_prep_one_rc(qp, wr); 1267 if (rc) 1268 goto out; 1269 1270 wr = wr->next; 1271 } 1272 1273 out: 1274 spin_unlock_irqrestore(&qp->sq_lock, irqflags); 1275 1276 spin_lock_irqsave(&cq->lock, irqflags); 1277 spin_lock(&qp->sq_lock); 1278 1279 if (likely(qp->sq.prod != qp->sq_old_prod)) { 1280 /* ring cq doorbell just in time */ 1281 spend = (qp->sq.prod - qp->sq_old_prod) & qp->sq.mask; 1282 ionic_reserve_cq(dev, cq, spend); 1283 1284 qp->sq_old_prod = qp->sq.prod; 1285 1286 ionic_dbell_ring(dev->lif_cfg.dbpage, dev->lif_cfg.sq_qtype, 1287 ionic_queue_dbell_val(&qp->sq)); 1288 } 1289 1290 if (qp->sq_flush) { 1291 notify = true; 1292 cq->flush = true; 1293 list_move_tail(&qp->cq_flush_sq, &cq->flush_sq); 1294 } 1295 1296 spin_unlock(&qp->sq_lock); 1297 spin_unlock_irqrestore(&cq->lock, irqflags); 1298 1299 if (notify && vcq->ibcq.comp_handler) 1300 vcq->ibcq.comp_handler(&vcq->ibcq, vcq->ibcq.cq_context); 1301 1302 *bad = wr; 1303 return rc; 1304 } 1305 1306 static int ionic_post_recv_common(struct ionic_ibdev *dev, 1307 struct ionic_vcq *vcq, 1308 struct ionic_cq *cq, 1309 struct ionic_qp *qp, 1310 const struct ib_recv_wr *wr, 1311 const struct ib_recv_wr **bad) 1312 { 1313 unsigned long irqflags; 1314 bool notify = false; 1315 int spend, rc = 0; 1316 1317 if (!bad) 1318 return -EINVAL; 1319 1320 if (qp->srq) { 1321 *bad = wr; 1322 return -EINVAL; 1323 } 1324 1325 if (qp->state < IB_QPS_INIT) { 1326 *bad = wr; 1327 return -EINVAL; 1328 } 1329 1330 spin_lock_irqsave(&qp->rq.lock, irqflags); 1331 1332 while (wr) { 1333 if (ionic_queue_full(&qp->rq.q)) { 1334 ibdev_dbg(&dev->ibdev, "queue full"); 1335 rc = -ENOMEM; 1336 goto out; 1337 } 1338 1339 rc = ionic_prep_recv(qp, wr); 1340 if (rc) 1341 goto out; 1342 1343 wr = wr->next; 1344 } 1345 1346 out: 1347 if (!cq) { 1348 spin_unlock_irqrestore(&qp->rq.lock, irqflags); 1349 goto out_unlocked; 1350 } 1351 spin_unlock_irqrestore(&qp->rq.lock, irqflags); 1352 1353 spin_lock_irqsave(&cq->lock, irqflags); 1354 spin_lock(&qp->rq.lock); 1355 1356 if (likely(qp->rq.q.prod != qp->rq.old_prod)) { 1357 /* ring cq doorbell just in time */ 1358 spend = (qp->rq.q.prod - qp->rq.old_prod) & qp->rq.q.mask; 1359 ionic_reserve_cq(dev, cq, spend); 1360 1361 qp->rq.old_prod = qp->rq.q.prod; 1362 1363 ionic_dbell_ring(dev->lif_cfg.dbpage, dev->lif_cfg.rq_qtype, 1364 ionic_queue_dbell_val(&qp->rq.q)); 1365 } 1366 1367 if (qp->rq.flush) { 1368 notify = true; 1369 cq->flush = true; 1370 list_move_tail(&qp->rq.cq_flush, &cq->flush_rq); 1371 } 1372 1373 spin_unlock(&qp->rq.lock); 1374 spin_unlock_irqrestore(&cq->lock, irqflags); 1375 1376 if (notify && vcq->ibcq.comp_handler) 1377 vcq->ibcq.comp_handler(&vcq->ibcq, vcq->ibcq.cq_context); 1378 1379 out_unlocked: 1380 *bad = wr; 1381 return rc; 1382 } 1383 1384 int ionic_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, 1385 const struct ib_send_wr **bad) 1386 { 1387 struct ionic_ibdev *dev = to_ionic_ibdev(ibqp->device); 1388 struct ionic_vcq *vcq = to_ionic_vcq(ibqp->send_cq); 1389 struct ionic_qp *qp = to_ionic_qp(ibqp); 1390 struct ionic_cq *cq = 1391 to_ionic_vcq_cq(ibqp->send_cq, qp->udma_idx); 1392 1393 return ionic_post_send_common(dev, vcq, cq, qp, wr, bad); 1394 } 1395 1396 int ionic_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, 1397 const struct ib_recv_wr **bad) 1398 { 1399 struct ionic_ibdev *dev = to_ionic_ibdev(ibqp->device); 1400 struct ionic_vcq *vcq = to_ionic_vcq(ibqp->recv_cq); 1401 struct ionic_qp *qp = to_ionic_qp(ibqp); 1402 struct ionic_cq *cq = 1403 to_ionic_vcq_cq(ibqp->recv_cq, qp->udma_idx); 1404 1405 return ionic_post_recv_common(dev, vcq, cq, qp, wr, bad); 1406 } 1407