aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/bnxt_re/qplib_fp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/bnxt_re/qplib_fp.c')
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.c384
1 files changed, 199 insertions, 185 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 43d08b5e9085..f05500bcdcf1 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -284,7 +284,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
284{ 284{
285 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 285 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
286 struct cmdq_create_qp1 req; 286 struct cmdq_create_qp1 req;
287 struct creq_create_qp1_resp *resp; 287 struct creq_create_qp1_resp resp;
288 struct bnxt_qplib_pbl *pbl; 288 struct bnxt_qplib_pbl *pbl;
289 struct bnxt_qplib_q *sq = &qp->sq; 289 struct bnxt_qplib_q *sq = &qp->sq;
290 struct bnxt_qplib_q *rq = &qp->rq; 290 struct bnxt_qplib_q *rq = &qp->rq;
@@ -394,31 +394,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
394 394
395 req.pd_id = cpu_to_le32(qp->pd->id); 395 req.pd_id = cpu_to_le32(qp->pd->id);
396 396
397 resp = (struct creq_create_qp1_resp *) 397 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
398 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 398 (void *)&resp, NULL, 0);
399 NULL, 0); 399 if (rc)
400 if (!resp) {
401 dev_err(&res->pdev->dev, "QPLIB: FP: CREATE_QP1 send failed");
402 rc = -EINVAL;
403 goto fail;
404 }
405 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
406 /* Cmd timed out */
407 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP1 timed out");
408 rc = -ETIMEDOUT;
409 goto fail;
410 }
411 if (resp->status ||
412 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
413 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP1 failed ");
414 dev_err(&rcfw->pdev->dev,
415 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
416 resp->status, le16_to_cpu(req.cookie),
417 le16_to_cpu(resp->cookie));
418 rc = -EINVAL;
419 goto fail; 400 goto fail;
420 } 401
421 qp->id = le32_to_cpu(resp->xid); 402 qp->id = le32_to_cpu(resp.xid);
422 qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET; 403 qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
423 sq->flush_in_progress = false; 404 sq->flush_in_progress = false;
424 rq->flush_in_progress = false; 405 rq->flush_in_progress = false;
@@ -442,7 +423,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
442 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 423 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
443 struct sq_send *hw_sq_send_hdr, **hw_sq_send_ptr; 424 struct sq_send *hw_sq_send_hdr, **hw_sq_send_ptr;
444 struct cmdq_create_qp req; 425 struct cmdq_create_qp req;
445 struct creq_create_qp_resp *resp; 426 struct creq_create_qp_resp resp;
446 struct bnxt_qplib_pbl *pbl; 427 struct bnxt_qplib_pbl *pbl;
447 struct sq_psn_search **psn_search_ptr; 428 struct sq_psn_search **psn_search_ptr;
448 unsigned long int psn_search, poff = 0; 429 unsigned long int psn_search, poff = 0;
@@ -627,31 +608,12 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
627 } 608 }
628 req.pd_id = cpu_to_le32(qp->pd->id); 609 req.pd_id = cpu_to_le32(qp->pd->id);
629 610
630 resp = (struct creq_create_qp_resp *) 611 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
631 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 612 (void *)&resp, NULL, 0);
632 NULL, 0); 613 if (rc)
633 if (!resp) {
634 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP send failed");
635 rc = -EINVAL;
636 goto fail;
637 }
638 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
639 /* Cmd timed out */
640 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP timed out");
641 rc = -ETIMEDOUT;
642 goto fail;
643 }
644 if (resp->status ||
645 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
646 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_QP failed ");
647 dev_err(&rcfw->pdev->dev,
648 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
649 resp->status, le16_to_cpu(req.cookie),
650 le16_to_cpu(resp->cookie));
651 rc = -EINVAL;
652 goto fail; 614 goto fail;
653 } 615
654 qp->id = le32_to_cpu(resp->xid); 616 qp->id = le32_to_cpu(resp.xid);
655 qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET; 617 qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET;
656 sq->flush_in_progress = false; 618 sq->flush_in_progress = false;
657 rq->flush_in_progress = false; 619 rq->flush_in_progress = false;
@@ -769,10 +731,11 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
769{ 731{
770 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 732 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
771 struct cmdq_modify_qp req; 733 struct cmdq_modify_qp req;
772 struct creq_modify_qp_resp *resp; 734 struct creq_modify_qp_resp resp;
773 u16 cmd_flags = 0, pkey; 735 u16 cmd_flags = 0, pkey;
774 u32 temp32[4]; 736 u32 temp32[4];
775 u32 bmask; 737 u32 bmask;
738 int rc;
776 739
777 RCFW_CMD_PREP(req, MODIFY_QP, cmd_flags); 740 RCFW_CMD_PREP(req, MODIFY_QP, cmd_flags);
778 741
@@ -862,27 +825,10 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
862 825
863 req.vlan_pcp_vlan_dei_vlan_id = cpu_to_le16(qp->vlan_id); 826 req.vlan_pcp_vlan_dei_vlan_id = cpu_to_le16(qp->vlan_id);
864 827
865 resp = (struct creq_modify_qp_resp *) 828 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
866 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 829 (void *)&resp, NULL, 0);
867 NULL, 0); 830 if (rc)
868 if (!resp) { 831 return rc;
869 dev_err(&rcfw->pdev->dev, "QPLIB: FP: MODIFY_QP send failed");
870 return -EINVAL;
871 }
872 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
873 /* Cmd timed out */
874 dev_err(&rcfw->pdev->dev, "QPLIB: FP: MODIFY_QP timed out");
875 return -ETIMEDOUT;
876 }
877 if (resp->status ||
878 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
879 dev_err(&rcfw->pdev->dev, "QPLIB: FP: MODIFY_QP failed ");
880 dev_err(&rcfw->pdev->dev,
881 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
882 resp->status, le16_to_cpu(req.cookie),
883 le16_to_cpu(resp->cookie));
884 return -EINVAL;
885 }
886 qp->cur_qp_state = qp->state; 832 qp->cur_qp_state = qp->state;
887 return 0; 833 return 0;
888} 834}
@@ -891,37 +837,26 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
891{ 837{
892 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 838 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
893 struct cmdq_query_qp req; 839 struct cmdq_query_qp req;
894 struct creq_query_qp_resp *resp; 840 struct creq_query_qp_resp resp;
841 struct bnxt_qplib_rcfw_sbuf *sbuf;
895 struct creq_query_qp_resp_sb *sb; 842 struct creq_query_qp_resp_sb *sb;
896 u16 cmd_flags = 0; 843 u16 cmd_flags = 0;
897 u32 temp32[4]; 844 u32 temp32[4];
898 int i; 845 int i, rc = 0;
899 846
900 RCFW_CMD_PREP(req, QUERY_QP, cmd_flags); 847 RCFW_CMD_PREP(req, QUERY_QP, cmd_flags);
901 848
849 sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
850 if (!sbuf)
851 return -ENOMEM;
852 sb = sbuf->sb;
853
902 req.qp_cid = cpu_to_le32(qp->id); 854 req.qp_cid = cpu_to_le32(qp->id);
903 req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS; 855 req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
904 resp = (struct creq_query_qp_resp *) 856 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
905 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 857 (void *)sbuf, 0);
906 (void **)&sb, 0); 858 if (rc)
907 if (!resp) { 859 goto bail;
908 dev_err(&rcfw->pdev->dev, "QPLIB: FP: QUERY_QP send failed");
909 return -EINVAL;
910 }
911 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
912 /* Cmd timed out */
913 dev_err(&rcfw->pdev->dev, "QPLIB: FP: QUERY_QP timed out");
914 return -ETIMEDOUT;
915 }
916 if (resp->status ||
917 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
918 dev_err(&rcfw->pdev->dev, "QPLIB: FP: QUERY_QP failed ");
919 dev_err(&rcfw->pdev->dev,
920 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
921 resp->status, le16_to_cpu(req.cookie),
922 le16_to_cpu(resp->cookie));
923 return -EINVAL;
924 }
925 /* Extract the context from the side buffer */ 860 /* Extract the context from the side buffer */
926 qp->state = sb->en_sqd_async_notify_state & 861 qp->state = sb->en_sqd_async_notify_state &
927 CREQ_QUERY_QP_RESP_SB_STATE_MASK; 862 CREQ_QUERY_QP_RESP_SB_STATE_MASK;
@@ -976,7 +911,9 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
976 qp->dest_qpn = le32_to_cpu(sb->dest_qp_id); 911 qp->dest_qpn = le32_to_cpu(sb->dest_qp_id);
977 memcpy(qp->smac, sb->src_mac, 6); 912 memcpy(qp->smac, sb->src_mac, 6);
978 qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id); 913 qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id);
979 return 0; 914bail:
915 bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
916 return rc;
980} 917}
981 918
982static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp) 919static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp)
@@ -1021,34 +958,18 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
1021{ 958{
1022 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 959 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
1023 struct cmdq_destroy_qp req; 960 struct cmdq_destroy_qp req;
1024 struct creq_destroy_qp_resp *resp; 961 struct creq_destroy_qp_resp resp;
1025 unsigned long flags; 962 unsigned long flags;
1026 u16 cmd_flags = 0; 963 u16 cmd_flags = 0;
964 int rc;
1027 965
1028 RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags); 966 RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);
1029 967
1030 req.qp_cid = cpu_to_le32(qp->id); 968 req.qp_cid = cpu_to_le32(qp->id);
1031 resp = (struct creq_destroy_qp_resp *) 969 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
1032 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 970 (void *)&resp, NULL, 0);
1033 NULL, 0); 971 if (rc)
1034 if (!resp) { 972 return rc;
1035 dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_QP send failed");
1036 return -EINVAL;
1037 }
1038 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
1039 /* Cmd timed out */
1040 dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_QP timed out");
1041 return -ETIMEDOUT;
1042 }
1043 if (resp->status ||
1044 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
1045 dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_QP failed ");
1046 dev_err(&rcfw->pdev->dev,
1047 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
1048 resp->status, le16_to_cpu(req.cookie),
1049 le16_to_cpu(resp->cookie));
1050 return -EINVAL;
1051 }
1052 973
1053 /* Must walk the associated CQs to nullified the QP ptr */ 974 /* Must walk the associated CQs to nullified the QP ptr */
1054 spin_lock_irqsave(&qp->scq->hwq.lock, flags); 975 spin_lock_irqsave(&qp->scq->hwq.lock, flags);
@@ -1162,8 +1083,12 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
1162 rc = -EINVAL; 1083 rc = -EINVAL;
1163 goto done; 1084 goto done;
1164 } 1085 }
1165 if (HWQ_CMP((sq->hwq.prod + 1), &sq->hwq) == 1086
1166 HWQ_CMP(sq->hwq.cons, &sq->hwq)) { 1087 if (bnxt_qplib_queue_full(sq)) {
1088 dev_err(&sq->hwq.pdev->dev,
1089 "QPLIB: prod = %#x cons = %#x qdepth = %#x delta = %#x",
1090 sq->hwq.prod, sq->hwq.cons, sq->hwq.max_elements,
1091 sq->q_full_delta);
1167 rc = -ENOMEM; 1092 rc = -ENOMEM;
1168 goto done; 1093 goto done;
1169 } 1094 }
@@ -1373,6 +1298,9 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
1373 } 1298 }
1374 1299
1375 sq->hwq.prod++; 1300 sq->hwq.prod++;
1301
1302 qp->wqe_cnt++;
1303
1376done: 1304done:
1377 return rc; 1305 return rc;
1378} 1306}
@@ -1411,8 +1339,7 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
1411 rc = -EINVAL; 1339 rc = -EINVAL;
1412 goto done; 1340 goto done;
1413 } 1341 }
1414 if (HWQ_CMP((rq->hwq.prod + 1), &rq->hwq) == 1342 if (bnxt_qplib_queue_full(rq)) {
1415 HWQ_CMP(rq->hwq.cons, &rq->hwq)) {
1416 dev_err(&rq->hwq.pdev->dev, 1343 dev_err(&rq->hwq.pdev->dev,
1417 "QPLIB: FP: QP (0x%x) RQ is full!", qp->id); 1344 "QPLIB: FP: QP (0x%x) RQ is full!", qp->id);
1418 rc = -EINVAL; 1345 rc = -EINVAL;
@@ -1483,7 +1410,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
1483{ 1410{
1484 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 1411 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
1485 struct cmdq_create_cq req; 1412 struct cmdq_create_cq req;
1486 struct creq_create_cq_resp *resp; 1413 struct creq_create_cq_resp resp;
1487 struct bnxt_qplib_pbl *pbl; 1414 struct bnxt_qplib_pbl *pbl;
1488 u16 cmd_flags = 0; 1415 u16 cmd_flags = 0;
1489 int rc; 1416 int rc;
@@ -1525,30 +1452,12 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
1525 (cq->cnq_hw_ring_id & CMDQ_CREATE_CQ_CNQ_ID_MASK) << 1452 (cq->cnq_hw_ring_id & CMDQ_CREATE_CQ_CNQ_ID_MASK) <<
1526 CMDQ_CREATE_CQ_CNQ_ID_SFT); 1453 CMDQ_CREATE_CQ_CNQ_ID_SFT);
1527 1454
1528 resp = (struct creq_create_cq_resp *) 1455 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
1529 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 1456 (void *)&resp, NULL, 0);
1530 NULL, 0); 1457 if (rc)
1531 if (!resp) {
1532 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_CQ send failed");
1533 return -EINVAL;
1534 }
1535 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
1536 /* Cmd timed out */
1537 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_CQ timed out");
1538 rc = -ETIMEDOUT;
1539 goto fail;
1540 }
1541 if (resp->status ||
1542 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
1543 dev_err(&rcfw->pdev->dev, "QPLIB: FP: CREATE_CQ failed ");
1544 dev_err(&rcfw->pdev->dev,
1545 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
1546 resp->status, le16_to_cpu(req.cookie),
1547 le16_to_cpu(resp->cookie));
1548 rc = -EINVAL;
1549 goto fail; 1458 goto fail;
1550 } 1459
1551 cq->id = le32_to_cpu(resp->xid); 1460 cq->id = le32_to_cpu(resp.xid);
1552 cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem; 1461 cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem;
1553 cq->period = BNXT_QPLIB_QUEUE_START_PERIOD; 1462 cq->period = BNXT_QPLIB_QUEUE_START_PERIOD;
1554 init_waitqueue_head(&cq->waitq); 1463 init_waitqueue_head(&cq->waitq);
@@ -1566,33 +1475,17 @@ int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
1566{ 1475{
1567 struct bnxt_qplib_rcfw *rcfw = res->rcfw; 1476 struct bnxt_qplib_rcfw *rcfw = res->rcfw;
1568 struct cmdq_destroy_cq req; 1477 struct cmdq_destroy_cq req;
1569 struct creq_destroy_cq_resp *resp; 1478 struct creq_destroy_cq_resp resp;
1570 u16 cmd_flags = 0; 1479 u16 cmd_flags = 0;
1480 int rc;
1571 1481
1572 RCFW_CMD_PREP(req, DESTROY_CQ, cmd_flags); 1482 RCFW_CMD_PREP(req, DESTROY_CQ, cmd_flags);
1573 1483
1574 req.cq_cid = cpu_to_le32(cq->id); 1484 req.cq_cid = cpu_to_le32(cq->id);
1575 resp = (struct creq_destroy_cq_resp *) 1485 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
1576 bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, 1486 (void *)&resp, NULL, 0);
1577 NULL, 0); 1487 if (rc)
1578 if (!resp) { 1488 return rc;
1579 dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_CQ send failed");
1580 return -EINVAL;
1581 }
1582 if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
1583 /* Cmd timed out */
1584 dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_CQ timed out");
1585 return -ETIMEDOUT;
1586 }
1587 if (resp->status ||
1588 le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
1589 dev_err(&rcfw->pdev->dev, "QPLIB: FP: DESTROY_CQ failed ");
1590 dev_err(&rcfw->pdev->dev,
1591 "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
1592 resp->status, le16_to_cpu(req.cookie),
1593 le16_to_cpu(resp->cookie));
1594 return -EINVAL;
1595 }
1596 bnxt_qplib_free_hwq(res->pdev, &cq->hwq); 1489 bnxt_qplib_free_hwq(res->pdev, &cq->hwq);
1597 return 0; 1490 return 0;
1598} 1491}
@@ -1664,14 +1557,113 @@ static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp,
1664 return rc; 1557 return rc;
1665} 1558}
1666 1559
1560/* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)
1561 * CQE is track from sw_cq_cons to max_element but valid only if VALID=1
1562 */
1563static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
1564 u32 cq_cons, u32 sw_sq_cons, u32 cqe_sq_cons)
1565{
1566 struct bnxt_qplib_q *sq = &qp->sq;
1567 struct bnxt_qplib_swq *swq;
1568 u32 peek_sw_cq_cons, peek_raw_cq_cons, peek_sq_cons_idx;
1569 struct cq_base *peek_hwcqe, **peek_hw_cqe_ptr;
1570 struct cq_req *peek_req_hwcqe;
1571 struct bnxt_qplib_qp *peek_qp;
1572 struct bnxt_qplib_q *peek_sq;
1573 int i, rc = 0;
1574
1575 /* Normal mode */
1576 /* Check for the psn_search marking before completing */
1577 swq = &sq->swq[sw_sq_cons];
1578 if (swq->psn_search &&
1579 le32_to_cpu(swq->psn_search->flags_next_psn) & 0x80000000) {
1580 /* Unmark */
1581 swq->psn_search->flags_next_psn = cpu_to_le32
1582 (le32_to_cpu(swq->psn_search->flags_next_psn)
1583 & ~0x80000000);
1584 dev_dbg(&cq->hwq.pdev->dev,
1585 "FP: Process Req cq_cons=0x%x qp=0x%x sq cons sw=0x%x cqe=0x%x marked!\n",
1586 cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);
1587 sq->condition = true;
1588 sq->send_phantom = true;
1589
1590 /* TODO: Only ARM if the previous SQE is ARMALL */
1591 bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ_ARMALL);
1592
1593 rc = -EAGAIN;
1594 goto out;
1595 }
1596 if (sq->condition) {
1597 /* Peek at the completions */
1598 peek_raw_cq_cons = cq->hwq.cons;
1599 peek_sw_cq_cons = cq_cons;
1600 i = cq->hwq.max_elements;
1601 while (i--) {
1602 peek_sw_cq_cons = HWQ_CMP((peek_sw_cq_cons), &cq->hwq);
1603 peek_hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
1604 peek_hwcqe = &peek_hw_cqe_ptr[CQE_PG(peek_sw_cq_cons)]
1605 [CQE_IDX(peek_sw_cq_cons)];
1606 /* If the next hwcqe is VALID */
1607 if (CQE_CMP_VALID(peek_hwcqe, peek_raw_cq_cons,
1608 cq->hwq.max_elements)) {
1609 /* If the next hwcqe is a REQ */
1610 if ((peek_hwcqe->cqe_type_toggle &
1611 CQ_BASE_CQE_TYPE_MASK) ==
1612 CQ_BASE_CQE_TYPE_REQ) {
1613 peek_req_hwcqe = (struct cq_req *)
1614 peek_hwcqe;
1615 peek_qp = (struct bnxt_qplib_qp *)
1616 ((unsigned long)
1617 le64_to_cpu
1618 (peek_req_hwcqe->qp_handle));
1619 peek_sq = &peek_qp->sq;
1620 peek_sq_cons_idx = HWQ_CMP(le16_to_cpu(
1621 peek_req_hwcqe->sq_cons_idx) - 1
1622 , &sq->hwq);
1623 /* If the hwcqe's sq's wr_id matches */
1624 if (peek_sq == sq &&
1625 sq->swq[peek_sq_cons_idx].wr_id ==
1626 BNXT_QPLIB_FENCE_WRID) {
1627 /*
1628 * Unbreak only if the phantom
1629 * comes back
1630 */
1631 dev_dbg(&cq->hwq.pdev->dev,
1632 "FP:Got Phantom CQE");
1633 sq->condition = false;
1634 sq->single = true;
1635 rc = 0;
1636 goto out;
1637 }
1638 }
1639 /* Valid but not the phantom, so keep looping */
1640 } else {
1641 /* Not valid yet, just exit and wait */
1642 rc = -EINVAL;
1643 goto out;
1644 }
1645 peek_sw_cq_cons++;
1646 peek_raw_cq_cons++;
1647 }
1648 dev_err(&cq->hwq.pdev->dev,
1649 "Should not have come here! cq_cons=0x%x qp=0x%x sq cons sw=0x%x hw=0x%x",
1650 cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);
1651 rc = -EINVAL;
1652 }
1653out:
1654 return rc;
1655}
1656
1667static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, 1657static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
1668 struct cq_req *hwcqe, 1658 struct cq_req *hwcqe,
1669 struct bnxt_qplib_cqe **pcqe, int *budget) 1659 struct bnxt_qplib_cqe **pcqe, int *budget,
1660 u32 cq_cons, struct bnxt_qplib_qp **lib_qp)
1670{ 1661{
1671 struct bnxt_qplib_qp *qp; 1662 struct bnxt_qplib_qp *qp;
1672 struct bnxt_qplib_q *sq; 1663 struct bnxt_qplib_q *sq;
1673 struct bnxt_qplib_cqe *cqe; 1664 struct bnxt_qplib_cqe *cqe;
1674 u32 sw_cons, cqe_cons; 1665 u32 sw_sq_cons, cqe_sq_cons;
1666 struct bnxt_qplib_swq *swq;
1675 int rc = 0; 1667 int rc = 0;
1676 1668
1677 qp = (struct bnxt_qplib_qp *)((unsigned long) 1669 qp = (struct bnxt_qplib_qp *)((unsigned long)
@@ -1683,13 +1675,13 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
1683 } 1675 }
1684 sq = &qp->sq; 1676 sq = &qp->sq;
1685 1677
1686 cqe_cons = HWQ_CMP(le16_to_cpu(hwcqe->sq_cons_idx), &sq->hwq); 1678 cqe_sq_cons = HWQ_CMP(le16_to_cpu(hwcqe->sq_cons_idx), &sq->hwq);
1687 if (cqe_cons > sq->hwq.max_elements) { 1679 if (cqe_sq_cons > sq->hwq.max_elements) {
1688 dev_err(&cq->hwq.pdev->dev, 1680 dev_err(&cq->hwq.pdev->dev,
1689 "QPLIB: FP: CQ Process req reported "); 1681 "QPLIB: FP: CQ Process req reported ");
1690 dev_err(&cq->hwq.pdev->dev, 1682 dev_err(&cq->hwq.pdev->dev,
1691 "QPLIB: sq_cons_idx 0x%x which exceeded max 0x%x", 1683 "QPLIB: sq_cons_idx 0x%x which exceeded max 0x%x",
1692 cqe_cons, sq->hwq.max_elements); 1684 cqe_sq_cons, sq->hwq.max_elements);
1693 return -EINVAL; 1685 return -EINVAL;
1694 } 1686 }
1695 /* If we were in the middle of flushing the SQ, continue */ 1687 /* If we were in the middle of flushing the SQ, continue */
@@ -1698,53 +1690,74 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
1698 1690
1699 /* Require to walk the sq's swq to fabricate CQEs for all previously 1691 /* Require to walk the sq's swq to fabricate CQEs for all previously
1700 * signaled SWQEs due to CQE aggregation from the current sq cons 1692 * signaled SWQEs due to CQE aggregation from the current sq cons
1701 * to the cqe_cons 1693 * to the cqe_sq_cons
1702 */ 1694 */
1703 cqe = *pcqe; 1695 cqe = *pcqe;
1704 while (*budget) { 1696 while (*budget) {
1705 sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq); 1697 sw_sq_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);
1706 if (sw_cons == cqe_cons) 1698 if (sw_sq_cons == cqe_sq_cons)
1699 /* Done */
1707 break; 1700 break;
1701
1702 swq = &sq->swq[sw_sq_cons];
1708 memset(cqe, 0, sizeof(*cqe)); 1703 memset(cqe, 0, sizeof(*cqe));
1709 cqe->opcode = CQ_BASE_CQE_TYPE_REQ; 1704 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
1710 cqe->qp_handle = (u64)(unsigned long)qp; 1705 cqe->qp_handle = (u64)(unsigned long)qp;
1711 cqe->src_qp = qp->id; 1706 cqe->src_qp = qp->id;
1712 cqe->wr_id = sq->swq[sw_cons].wr_id; 1707 cqe->wr_id = swq->wr_id;
1713 cqe->type = sq->swq[sw_cons].type; 1708 if (cqe->wr_id == BNXT_QPLIB_FENCE_WRID)
1709 goto skip;
1710 cqe->type = swq->type;
1714 1711
1715 /* For the last CQE, check for status. For errors, regardless 1712 /* For the last CQE, check for status. For errors, regardless
1716 * of the request being signaled or not, it must complete with 1713 * of the request being signaled or not, it must complete with
1717 * the hwcqe error status 1714 * the hwcqe error status
1718 */ 1715 */
1719 if (HWQ_CMP((sw_cons + 1), &sq->hwq) == cqe_cons && 1716 if (HWQ_CMP((sw_sq_cons + 1), &sq->hwq) == cqe_sq_cons &&
1720 hwcqe->status != CQ_REQ_STATUS_OK) { 1717 hwcqe->status != CQ_REQ_STATUS_OK) {
1721 cqe->status = hwcqe->status; 1718 cqe->status = hwcqe->status;
1722 dev_err(&cq->hwq.pdev->dev, 1719 dev_err(&cq->hwq.pdev->dev,
1723 "QPLIB: FP: CQ Processed Req "); 1720 "QPLIB: FP: CQ Processed Req ");
1724 dev_err(&cq->hwq.pdev->dev, 1721 dev_err(&cq->hwq.pdev->dev,
1725 "QPLIB: wr_id[%d] = 0x%llx with status 0x%x", 1722 "QPLIB: wr_id[%d] = 0x%llx with status 0x%x",
1726 sw_cons, cqe->wr_id, cqe->status); 1723 sw_sq_cons, cqe->wr_id, cqe->status);
1727 cqe++; 1724 cqe++;
1728 (*budget)--; 1725 (*budget)--;
1729 sq->flush_in_progress = true; 1726 sq->flush_in_progress = true;
1730 /* Must block new posting of SQ and RQ */ 1727 /* Must block new posting of SQ and RQ */
1731 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; 1728 qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
1729 sq->condition = false;
1730 sq->single = false;
1732 } else { 1731 } else {
1733 if (sq->swq[sw_cons].flags & 1732 if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
1734 SQ_SEND_FLAGS_SIGNAL_COMP) { 1733 /* Before we complete, do WA 9060 */
1734 if (do_wa9060(qp, cq, cq_cons, sw_sq_cons,
1735 cqe_sq_cons)) {
1736 *lib_qp = qp;
1737 goto out;
1738 }
1735 cqe->status = CQ_REQ_STATUS_OK; 1739 cqe->status = CQ_REQ_STATUS_OK;
1736 cqe++; 1740 cqe++;
1737 (*budget)--; 1741 (*budget)--;
1738 } 1742 }
1739 } 1743 }
1744skip:
1740 sq->hwq.cons++; 1745 sq->hwq.cons++;
1746 if (sq->single)
1747 break;
1741 } 1748 }
1749out:
1742 *pcqe = cqe; 1750 *pcqe = cqe;
1743 if (!*budget && HWQ_CMP(sq->hwq.cons, &sq->hwq) != cqe_cons) { 1751 if (HWQ_CMP(sq->hwq.cons, &sq->hwq) != cqe_sq_cons) {
1744 /* Out of budget */ 1752 /* Out of budget */
1745 rc = -EAGAIN; 1753 rc = -EAGAIN;
1746 goto done; 1754 goto done;
1747 } 1755 }
1756 /*
1757 * Back to normal completion mode only after it has completed all of
1758 * the WC for this CQE
1759 */
1760 sq->single = false;
1748 if (!sq->flush_in_progress) 1761 if (!sq->flush_in_progress)
1749 goto done; 1762 goto done;
1750flush: 1763flush:
@@ -2074,7 +2087,7 @@ static int bnxt_qplib_cq_process_cutoff(struct bnxt_qplib_cq *cq,
2074} 2087}
2075 2088
2076int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, 2089int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
2077 int num_cqes) 2090 int num_cqes, struct bnxt_qplib_qp **lib_qp)
2078{ 2091{
2079 struct cq_base *hw_cqe, **hw_cqe_ptr; 2092 struct cq_base *hw_cqe, **hw_cqe_ptr;
2080 unsigned long flags; 2093 unsigned long flags;
@@ -2099,7 +2112,8 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
2099 case CQ_BASE_CQE_TYPE_REQ: 2112 case CQ_BASE_CQE_TYPE_REQ:
2100 rc = bnxt_qplib_cq_process_req(cq, 2113 rc = bnxt_qplib_cq_process_req(cq,
2101 (struct cq_req *)hw_cqe, 2114 (struct cq_req *)hw_cqe,
2102 &cqe, &budget); 2115 &cqe, &budget,
2116 sw_cons, lib_qp);
2103 break; 2117 break;
2104 case CQ_BASE_CQE_TYPE_RES_RC: 2118 case CQ_BASE_CQE_TYPE_RES_RC:
2105 rc = bnxt_qplib_cq_process_res_rc(cq, 2119 rc = bnxt_qplib_cq_process_res_rc(cq,