From 0c4f628601ae6018f4fed1d5e493397dc350b142 Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Apr 29 2020 12:32:55 +0000 Subject: Merge branch 'users/tbogendoerfer/SLE15-SP2/for-next' into SLE15-SP2 Pull RDMA fixes from Thomas Bogendoerfer. --- diff --git a/patches.suse/RDMA-bnxt_re-Fix-lifetimes-in-bnxt_re_task.patch b/patches.suse/RDMA-bnxt_re-Fix-lifetimes-in-bnxt_re_task.patch new file mode 100644 index 0000000..1f767a7 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Fix-lifetimes-in-bnxt_re_task.patch @@ -0,0 +1,38 @@ +From: Jason Gunthorpe +Date: Fri, 13 Mar 2020 09:33:26 -0700 +Subject: RDMA/bnxt_re: Fix lifetimes in bnxt_re_task +Patch-mainline: v5.7-rc1 +Git-commit: 8a6c61704746d3a1e004e054504ae8d98ed95697 +References: bsc#1170774 + +A work queue cannot just rely on the ib_device not being freed, it must +hold a kref on the memory so that the BNXT_RE_FLAG_IBDEV_REGISTERED check +works. + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Link: https://lore.kernel.org/r/1584117207-2664-3-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1670,6 +1670,7 @@ static void bnxt_re_task(struct work_str + smp_mb__before_atomic(); + atomic_dec(&rdev->sched_count); + exit: ++ put_device(&rdev->ibdev.dev); + kfree(re_work); + } + +@@ -1735,6 +1736,7 @@ static int bnxt_re_netdev_event(struct n + /* Allocate for the deferred task */ + re_work = kzalloc(sizeof(*re_work), GFP_ATOMIC); + if (re_work) { ++ get_device(&rdev->ibdev.dev); + re_work->rdev = rdev; + re_work->event = event; + re_work->vlan_dev = (real_dev == netdev ? diff --git a/patches.suse/RDMA-bnxt_re-Refactor-command-queue-management-code.patch b/patches.suse/RDMA-bnxt_re-Refactor-command-queue-management-code.patch new file mode 100644 index 0000000..6e7fc80 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-command-queue-management-code.patch @@ -0,0 +1,951 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:11:02 -0500 +Subject: RDMA/bnxt_re: Refactor command queue management code +Patch-mainline: v5.7-rc1 +Git-commit: cee0c7bba4869170fd471758053406784eba35a5 +References: bsc#1170774 + +Refactoring the command queue (rcfw) management code. A new data-structure +is introduced to describe the bar register. each object which deals with +mmio space should have a descriptor structure. This structure specifically +hold DB register information. Thus, slow path creq structure now hold a +bar register descriptor. + +Further cleanup the rcfw structure to introduce the command queue context +and command response event queue context structures. Rest of the rcfw +related code has been touched to incorporate these three structures. + +Link: https://lore.kernel.org/r/1581786665-23705-6-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Naresh Kumar PBS +Signed-off-by: Selvin Xavier +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/main.c | 12 + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 417 +++++++++++++++++------------ + drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 80 +++-- + drivers/infiniband/hw/bnxt_re/qplib_res.h | 7 + 4 files changed, 312 insertions(+), 204 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1344,7 +1344,7 @@ static void bnxt_re_ib_unreg(struct bnxt + bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx); + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); +- bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type); ++ bnxt_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type); + bnxt_qplib_free_rcfw_channel(&rdev->rcfw); + } + if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) { +@@ -1375,6 +1375,7 @@ static void bnxt_re_worker(struct work_s + + static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) + { ++ struct bnxt_qplib_creq_ctx *creq; + struct bnxt_re_ring_attr rattr; + u32 db_offt; + bool locked; +@@ -1427,13 +1428,14 @@ static int bnxt_re_ib_reg(struct bnxt_re + } + + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); +- rattr.dma_arr = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr; +- rattr.pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count; ++ creq = &rdev->rcfw.creq; ++ rattr.dma_arr = creq->hwq.pbl[PBL_LVL_0].pg_map_arr; ++ rattr.pages = creq->hwq.pbl[creq->hwq.level].pg_count; + rattr.type = type; + rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX; + rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1; + rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; +- rc = bnxt_re_net_ring_alloc(rdev, &rattr, &rdev->rcfw.creq_ring_id); ++ rc = bnxt_re_net_ring_alloc(rdev, &rattr, &creq->ring_id); + if (rc) { + pr_err("Failed to allocate CREQ: %#x\n", rc); + goto free_rcfw; +@@ -1527,7 +1529,7 @@ disable_rcfw: + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); + free_ring: + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); +- bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type); ++ bnxt_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type); + free_rcfw: + bnxt_qplib_free_rcfw_channel(&rdev->rcfw); + fail: +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +@@ -55,12 +55,14 @@ static void bnxt_qplib_service_creq(unsi + /* Hardware communication channel */ + static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) + { ++ struct bnxt_qplib_cmdq_ctx *cmdq; + u16 cbit; + int rc; + ++ cmdq = &rcfw->cmdq; + cbit = cookie % rcfw->cmdq_depth; +- rc = wait_event_timeout(rcfw->waitq, +- !test_bit(cbit, rcfw->cmdq_bitmap), ++ rc = wait_event_timeout(cmdq->waitq, ++ !test_bit(cbit, cmdq->cmdq_bitmap), + msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS)); + return rc ? 0 : -ETIMEDOUT; + }; +@@ -68,15 +70,17 @@ static int __wait_for_resp(struct bnxt_q + static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) + { + u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT; ++ struct bnxt_qplib_cmdq_ctx *cmdq; + u16 cbit; + ++ cmdq = &rcfw->cmdq; + cbit = cookie % rcfw->cmdq_depth; +- if (!test_bit(cbit, rcfw->cmdq_bitmap)) ++ if (!test_bit(cbit, cmdq->cmdq_bitmap)) + goto done; + do { + mdelay(1); /* 1m sec */ + bnxt_qplib_service_creq((unsigned long)rcfw); +- } while (test_bit(cbit, rcfw->cmdq_bitmap) && --count); ++ } while (test_bit(cbit, cmdq->cmdq_bitmap) && --count); + done: + return count ? 0 : -ETIMEDOUT; + }; +@@ -84,56 +88,61 @@ done: + static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, + struct creq_base *resp, void *sb, u8 is_block) + { +- struct bnxt_qplib_cmdqe *cmdqe, **cmdq_ptr; +- struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq; ++ struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq; ++ struct bnxt_qplib_cmdqe *cmdqe, **hwq_ptr; ++ struct bnxt_qplib_hwq *hwq = &cmdq->hwq; ++ struct bnxt_qplib_crsqe *crsqe; + u32 cmdq_depth = rcfw->cmdq_depth; +- struct bnxt_qplib_crsq *crsqe; + u32 sw_prod, cmdq_prod; ++ struct pci_dev *pdev; + unsigned long flags; + u32 size, opcode; + u16 cookie, cbit; ++ int pg, idx; + u8 *preq; + ++ pdev = rcfw->pdev; ++ + opcode = req->opcode; +- if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) && ++ if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) && + (opcode != CMDQ_BASE_OPCODE_QUERY_FUNC && + opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW && + opcode != CMDQ_BASE_OPCODE_QUERY_VERSION)) { +- dev_err(&rcfw->pdev->dev, ++ dev_err(&pdev->dev, + "RCFW not initialized, reject opcode 0x%x\n", opcode); + return -EINVAL; + } + +- if (test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) && ++ if (test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) && + opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) { +- dev_err(&rcfw->pdev->dev, "RCFW already initialized!\n"); ++ dev_err(&pdev->dev, "RCFW already initialized!\n"); + return -EINVAL; + } + +- if (test_bit(FIRMWARE_TIMED_OUT, &rcfw->flags)) ++ if (test_bit(FIRMWARE_TIMED_OUT, &cmdq->flags)) + return -ETIMEDOUT; + + /* Cmdq are in 16-byte units, each request can consume 1 or more + * cmdqe + */ +- spin_lock_irqsave(&cmdq->lock, flags); +- if (req->cmd_size >= HWQ_FREE_SLOTS(cmdq)) { +- dev_err(&rcfw->pdev->dev, "RCFW: CMDQ is full!\n"); +- spin_unlock_irqrestore(&cmdq->lock, flags); ++ spin_lock_irqsave(&hwq->lock, flags); ++ if (req->cmd_size >= HWQ_FREE_SLOTS(hwq)) { ++ dev_err(&pdev->dev, "RCFW: CMDQ is full!\n"); ++ spin_unlock_irqrestore(&hwq->lock, flags); + return -EAGAIN; + } + + +- cookie = rcfw->seq_num & RCFW_MAX_COOKIE_VALUE; ++ cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE; + cbit = cookie % rcfw->cmdq_depth; + if (is_block) + cookie |= RCFW_CMD_IS_BLOCKING; + +- set_bit(cbit, rcfw->cmdq_bitmap); ++ set_bit(cbit, cmdq->cmdq_bitmap); + req->cookie = cpu_to_le16(cookie); + crsqe = &rcfw->crsqe_tbl[cbit]; + if (crsqe->resp) { +- spin_unlock_irqrestore(&cmdq->lock, flags); ++ spin_unlock_irqrestore(&hwq->lock, flags); + return -EBUSY; + } + +@@ -155,15 +164,18 @@ static int __send_message(struct bnxt_qp + BNXT_QPLIB_CMDQE_UNITS; + } + +- cmdq_ptr = (struct bnxt_qplib_cmdqe **)cmdq->pbl_ptr; ++ hwq_ptr = (struct bnxt_qplib_cmdqe **)hwq->pbl_ptr; + preq = (u8 *)req; + do { ++ pg = 0; ++ idx = 0; ++ + /* Locate the next cmdq slot */ +- sw_prod = HWQ_CMP(cmdq->prod, cmdq); +- cmdqe = &cmdq_ptr[get_cmdq_pg(sw_prod, cmdq_depth)] ++ sw_prod = HWQ_CMP(hwq->prod, hwq); ++ cmdqe = &hwq_ptr[get_cmdq_pg(sw_prod, cmdq_depth)] + [get_cmdq_idx(sw_prod, cmdq_depth)]; + if (!cmdqe) { +- dev_err(&rcfw->pdev->dev, ++ dev_err(&pdev->dev, + "RCFW request failed with no cmdqe!\n"); + goto done; + } +@@ -172,31 +184,27 @@ static int __send_message(struct bnxt_qp + memcpy(cmdqe, preq, min_t(u32, size, sizeof(*cmdqe))); + preq += min_t(u32, size, sizeof(*cmdqe)); + size -= min_t(u32, size, sizeof(*cmdqe)); +- cmdq->prod++; +- rcfw->seq_num++; ++ hwq->prod++; + } while (size > 0); ++ cmdq->seq_num++; + +- rcfw->seq_num++; +- +- cmdq_prod = cmdq->prod; +- if (test_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags)) { ++ cmdq_prod = hwq->prod; ++ if (test_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags)) { + /* The very first doorbell write + * is required to set this flag + * which prompts the FW to reset + * its internal pointers + */ + cmdq_prod |= BIT(FIRMWARE_FIRST_FLAG); +- clear_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags); ++ clear_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags); + } + + /* ring CMDQ DB */ + wmb(); +- writel(cmdq_prod, rcfw->cmdq_bar_reg_iomem + +- rcfw->cmdq_bar_reg_prod_off); +- writel(RCFW_CMDQ_TRIG_VAL, rcfw->cmdq_bar_reg_iomem + +- rcfw->cmdq_bar_reg_trig_off); ++ writel(cmdq_prod, cmdq->cmdq_mbox.prod); ++ writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db); + done: +- spin_unlock_irqrestore(&cmdq->lock, flags); ++ spin_unlock_irqrestore(&hwq->lock, flags); + /* Return the CREQ response pointer */ + return 0; + } +@@ -236,7 +244,7 @@ int bnxt_qplib_rcfw_send_message(struct + /* timed out */ + dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x timedout (%d)msec\n", + cookie, opcode, RCFW_CMD_WAIT_TIME_MS); +- set_bit(FIRMWARE_TIMED_OUT, &rcfw->flags); ++ set_bit(FIRMWARE_TIMED_OUT, &rcfw->cmdq.flags); + return rc; + } + +@@ -253,6 +261,8 @@ int bnxt_qplib_rcfw_send_message(struct + static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw, + struct creq_func_event *func_event) + { ++ int rc; ++ + switch (func_event->event) { + case CREQ_FUNC_EVENT_EVENT_TX_WQE_ERROR: + break; +@@ -286,37 +296,41 @@ static int bnxt_qplib_process_func_event + default: + return -EINVAL; + } +- return 0; ++ ++ rc = rcfw->creq.aeq_handler(rcfw, (void *)func_event, NULL); ++ return rc; + } + + static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, + struct creq_qp_event *qp_event) + { +- struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq; + struct creq_qp_error_notification *err_event; +- struct bnxt_qplib_crsq *crsqe; +- unsigned long flags; ++ struct bnxt_qplib_hwq *hwq = &rcfw->cmdq.hwq; ++ struct bnxt_qplib_crsqe *crsqe; + struct bnxt_qplib_qp *qp; + u16 cbit, blocked = 0; +- u16 cookie; ++ struct pci_dev *pdev; ++ unsigned long flags; + __le16 mcookie; ++ u16 cookie; ++ int rc = 0; + u32 qp_id; + ++ pdev = rcfw->pdev; + switch (qp_event->event) { + case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION: + err_event = (struct creq_qp_error_notification *)qp_event; + qp_id = le32_to_cpu(err_event->xid); + qp = rcfw->qp_tbl[qp_id].qp_handle; +- dev_dbg(&rcfw->pdev->dev, +- "Received QP error notification\n"); +- dev_dbg(&rcfw->pdev->dev, ++ dev_dbg(&pdev->dev, "Received QP error notification\n"); ++ dev_dbg(&pdev->dev, + "qpid 0x%x, req_err=0x%x, resp_err=0x%x\n", + qp_id, err_event->req_err_state_reason, + err_event->res_err_state_reason); + if (!qp) + break; + bnxt_qplib_mark_qp_error(qp); +- rcfw->aeq_handler(rcfw, qp_event, qp); ++ rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp); + break; + default: + /* +@@ -328,7 +342,7 @@ static int bnxt_qplib_process_qp_event(s + * + */ + +- spin_lock_irqsave_nested(&cmdq->lock, flags, ++ spin_lock_irqsave_nested(&hwq->lock, flags, + SINGLE_DEPTH_NESTING); + cookie = le16_to_cpu(qp_event->cookie); + mcookie = qp_event->cookie; +@@ -342,23 +356,23 @@ static int bnxt_qplib_process_qp_event(s + crsqe->resp = NULL; + } else { + if (crsqe->resp && crsqe->resp->cookie) +- dev_err(&rcfw->pdev->dev, ++ dev_err(&pdev->dev, + "CMD %s cookie sent=%#x, recd=%#x\n", + crsqe->resp ? "mismatch" : "collision", + crsqe->resp ? crsqe->resp->cookie : 0, + mcookie); + } +- if (!test_and_clear_bit(cbit, rcfw->cmdq_bitmap)) +- dev_warn(&rcfw->pdev->dev, ++ if (!test_and_clear_bit(cbit, rcfw->cmdq.cmdq_bitmap)) ++ dev_warn(&pdev->dev, + "CMD bit %d was not requested\n", cbit); +- cmdq->cons += crsqe->req_size; ++ hwq->cons += crsqe->req_size; + crsqe->req_size = 0; + + if (!blocked) +- wake_up(&rcfw->waitq); +- spin_unlock_irqrestore(&cmdq->lock, flags); ++ wake_up(&rcfw->cmdq.waitq); ++ spin_unlock_irqrestore(&hwq->lock, flags); + } +- return 0; ++ return rc; + } + + /* SP - CREQ Completion handlers */ +@@ -366,20 +380,21 @@ static void bnxt_qplib_service_creq(unsi + { + struct bnxt_qplib_rcfw *rcfw = (struct bnxt_qplib_rcfw *)data; + bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx); +- struct bnxt_qplib_hwq *creq = &rcfw->creq; ++ struct bnxt_qplib_creq_ctx *creq = &rcfw->creq; + u32 type, budget = CREQ_ENTRY_POLL_BUDGET; +- struct creq_base *creqe, **creq_ptr; ++ struct bnxt_qplib_hwq *hwq = &creq->hwq; ++ struct creq_base *creqe, **hwq_ptr; + u32 sw_cons, raw_cons; + unsigned long flags; + + /* Service the CREQ until budget is over */ +- spin_lock_irqsave(&creq->lock, flags); +- raw_cons = creq->cons; ++ spin_lock_irqsave(&hwq->lock, flags); ++ raw_cons = hwq->cons; + while (budget > 0) { +- sw_cons = HWQ_CMP(raw_cons, creq); +- creq_ptr = (struct creq_base **)creq->pbl_ptr; +- creqe = &creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)]; +- if (!CREQ_CMP_VALID(creqe, raw_cons, creq->max_elements)) ++ sw_cons = HWQ_CMP(raw_cons, hwq); ++ hwq_ptr = (struct creq_base **)hwq->pbl_ptr; ++ creqe = &hwq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)]; ++ if (!CREQ_CMP_VALID(creqe, raw_cons, hwq->max_elements)) + break; + /* The valid test of the entry must be done first before + * reading any further. +@@ -391,12 +406,12 @@ static void bnxt_qplib_service_creq(unsi + case CREQ_BASE_TYPE_QP_EVENT: + bnxt_qplib_process_qp_event + (rcfw, (struct creq_qp_event *)creqe); +- rcfw->creq_qp_event_processed++; ++ creq->stats.creq_qp_event_processed++; + break; + case CREQ_BASE_TYPE_FUNC_EVENT: + if (!bnxt_qplib_process_func_event + (rcfw, (struct creq_func_event *)creqe)) +- rcfw->creq_func_event_processed++; ++ creq->stats.creq_func_event_processed++; + else + dev_warn(&rcfw->pdev->dev, + "aeqe:%#x Not handled\n", type); +@@ -412,28 +427,31 @@ static void bnxt_qplib_service_creq(unsi + budget--; + } + +- if (creq->cons != raw_cons) { +- creq->cons = raw_cons; +- bnxt_qplib_ring_creq_db_rearm(rcfw->creq_bar_reg_iomem, +- raw_cons, creq->max_elements, +- rcfw->creq_ring_id, gen_p5); ++ if (hwq->cons != raw_cons) { ++ hwq->cons = raw_cons; ++ bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db, ++ raw_cons, hwq->max_elements, ++ creq->ring_id, gen_p5); + } +- spin_unlock_irqrestore(&creq->lock, flags); ++ spin_unlock_irqrestore(&hwq->lock, flags); + } + + static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance) + { + struct bnxt_qplib_rcfw *rcfw = dev_instance; +- struct bnxt_qplib_hwq *creq = &rcfw->creq; ++ struct bnxt_qplib_creq_ctx *creq; + struct creq_base **creq_ptr; ++ struct bnxt_qplib_hwq *hwq; + u32 sw_cons; + ++ creq = &rcfw->creq; ++ hwq = &creq->hwq; + /* Prefetch the CREQ element */ +- sw_cons = HWQ_CMP(creq->cons, creq); +- creq_ptr = (struct creq_base **)rcfw->creq.pbl_ptr; ++ sw_cons = HWQ_CMP(hwq->cons, hwq); ++ creq_ptr = (struct creq_base **)creq->hwq.pbl_ptr; + prefetch(&creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)]); + +- tasklet_schedule(&rcfw->worker); ++ tasklet_schedule(&creq->creq_tasklet); + + return IRQ_HANDLED; + } +@@ -452,7 +470,7 @@ int bnxt_qplib_deinit_rcfw(struct bnxt_q + if (rc) + return rc; + +- clear_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags); ++ clear_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->cmdq.flags); + return 0; + } + +@@ -556,16 +574,17 @@ skip_ctx_setup: + NULL, 0); + if (rc) + return rc; +- set_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags); ++ set_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->cmdq.flags); + return 0; + } + + void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) + { ++ kfree(rcfw->cmdq.cmdq_bitmap); + kfree(rcfw->qp_tbl); + kfree(rcfw->crsqe_tbl); +- bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq); +- bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq); ++ bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq.hwq); ++ bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq.hwq); + rcfw->pdev = NULL; + } + +@@ -576,8 +595,13 @@ int bnxt_qplib_alloc_rcfw_channel(struct + { + struct bnxt_qplib_hwq_attr hwq_attr = {}; + struct bnxt_qplib_sg_info sginfo = {}; ++ struct bnxt_qplib_cmdq_ctx *cmdq; ++ struct bnxt_qplib_creq_ctx *creq; ++ u32 bmap_size = 0; + + rcfw->pdev = res->pdev; ++ cmdq = &rcfw->cmdq; ++ creq = &rcfw->creq; + rcfw->res = res; + + sginfo.pgsize = PAGE_SIZE; +@@ -589,7 +613,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct + hwq_attr.stride = BNXT_QPLIB_CREQE_UNITS; + hwq_attr.type = bnxt_qplib_get_hwq_type(res); + +- if (bnxt_qplib_alloc_init_hwq(&rcfw->creq, &hwq_attr)) { ++ if (bnxt_qplib_alloc_init_hwq(&creq->hwq, &hwq_attr)) { + dev_err(&rcfw->pdev->dev, + "HW channel CREQ allocation failed\n"); + goto fail; +@@ -603,17 +627,24 @@ int bnxt_qplib_alloc_rcfw_channel(struct + hwq_attr.depth = rcfw->cmdq_depth; + hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS; + hwq_attr.type = HWQ_TYPE_CTX; +- if (bnxt_qplib_alloc_init_hwq(&rcfw->cmdq, &hwq_attr)) { ++ if (bnxt_qplib_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) { + dev_err(&rcfw->pdev->dev, + "HW channel CMDQ allocation failed\n"); + goto fail; + } + +- rcfw->crsqe_tbl = kcalloc(rcfw->cmdq.max_elements, ++ rcfw->crsqe_tbl = kcalloc(cmdq->hwq.max_elements, + sizeof(*rcfw->crsqe_tbl), GFP_KERNEL); + if (!rcfw->crsqe_tbl) + goto fail; + ++ bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long); ++ cmdq->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL); ++ if (!cmdq->cmdq_bitmap) ++ goto fail; ++ ++ cmdq->bmap_size = bmap_size; ++ + rcfw->qp_tbl_size = qp_tbl_sz; + rcfw->qp_tbl = kcalloc(qp_tbl_sz, sizeof(struct bnxt_qplib_qp_node), + GFP_KERNEL); +@@ -630,137 +661,201 @@ fail: + void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) + { + bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx); ++ struct bnxt_qplib_creq_ctx *creq; + +- tasklet_disable(&rcfw->worker); ++ creq = &rcfw->creq; ++ tasklet_disable(&creq->creq_tasklet); + /* Mask h/w interrupts */ +- bnxt_qplib_ring_creq_db(rcfw->creq_bar_reg_iomem, rcfw->creq.cons, +- rcfw->creq.max_elements, rcfw->creq_ring_id, ++ bnxt_qplib_ring_creq_db(creq->creq_db.db, creq->hwq.cons, ++ creq->hwq.max_elements, creq->ring_id, + gen_p5); + /* Sync with last running IRQ-handler */ +- synchronize_irq(rcfw->vector); ++ synchronize_irq(creq->msix_vec); + if (kill) +- tasklet_kill(&rcfw->worker); ++ tasklet_kill(&creq->creq_tasklet); + +- if (rcfw->requested) { +- free_irq(rcfw->vector, rcfw); +- rcfw->requested = false; ++ if (creq->requested) { ++ free_irq(creq->msix_vec, rcfw); ++ creq->requested = false; + } + } + + void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) + { ++ struct bnxt_qplib_creq_ctx *creq; ++ struct bnxt_qplib_cmdq_ctx *cmdq; + unsigned long indx; + ++ creq = &rcfw->creq; ++ cmdq = &rcfw->cmdq; ++ /* Make sure the HW channel is stopped! */ + bnxt_qplib_rcfw_stop_irq(rcfw, true); + +- iounmap(rcfw->cmdq_bar_reg_iomem); +- iounmap(rcfw->creq_bar_reg_iomem); ++ iounmap(cmdq->cmdq_mbox.reg.bar_reg); ++ iounmap(creq->creq_db.reg.bar_reg); + +- indx = find_first_bit(rcfw->cmdq_bitmap, rcfw->bmap_size); +- if (indx != rcfw->bmap_size) ++ indx = find_first_bit(cmdq->cmdq_bitmap, cmdq->bmap_size); ++ if (indx != cmdq->bmap_size) + dev_err(&rcfw->pdev->dev, + "disabling RCFW with pending cmd-bit %lx\n", indx); +- kfree(rcfw->cmdq_bitmap); +- rcfw->bmap_size = 0; + +- rcfw->cmdq_bar_reg_iomem = NULL; +- rcfw->creq_bar_reg_iomem = NULL; +- rcfw->aeq_handler = NULL; +- rcfw->vector = 0; ++ cmdq->cmdq_mbox.reg.bar_reg = NULL; ++ creq->creq_db.reg.bar_reg = NULL; ++ creq->aeq_handler = NULL; ++ creq->msix_vec = 0; + } + + int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, + bool need_init) + { + bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx); ++ struct bnxt_qplib_creq_ctx *creq; + int rc; + +- if (rcfw->requested) ++ creq = &rcfw->creq; ++ ++ if (creq->requested) + return -EFAULT; + +- rcfw->vector = msix_vector; ++ creq->msix_vec = msix_vector; + if (need_init) +- tasklet_init(&rcfw->worker, ++ tasklet_init(&creq->creq_tasklet, + bnxt_qplib_service_creq, (unsigned long)rcfw); + else +- tasklet_enable(&rcfw->worker); +- rc = request_irq(rcfw->vector, bnxt_qplib_creq_irq, 0, ++ tasklet_enable(&creq->creq_tasklet); ++ rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0, + "bnxt_qplib_creq", rcfw); + if (rc) + return rc; +- rcfw->requested = true; +- bnxt_qplib_ring_creq_db_rearm(rcfw->creq_bar_reg_iomem, +- rcfw->creq.cons, rcfw->creq.max_elements, +- rcfw->creq_ring_id, gen_p5); ++ creq->requested = true; ++ bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db, ++ creq->hwq.cons, creq->hwq.max_elements, ++ creq->ring_id, gen_p5); + + return 0; + } + +-int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw, +- int msix_vector, +- int cp_bar_reg_off, int virt_fn, +- int (*aeq_handler)(struct bnxt_qplib_rcfw *, +- void *, void *)) ++static int bnxt_qplib_map_cmdq_mbox(struct bnxt_qplib_rcfw *rcfw, bool is_vf) + { +- resource_size_t res_base; +- struct cmdq_init init; ++ struct bnxt_qplib_cmdq_mbox *mbox; ++ resource_size_t bar_reg; + struct pci_dev *pdev; +- u16 bmap_size; +- int rc; ++ u16 prod_offt; ++ int rc = 0; + +- /* General */ + pdev = rcfw->pdev; +- rcfw->seq_num = 0; +- set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags); +- bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long); +- rcfw->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL); +- if (!rcfw->cmdq_bitmap) +- return -ENOMEM; +- rcfw->bmap_size = bmap_size; ++ mbox = &rcfw->cmdq.cmdq_mbox; + +- /* CMDQ */ +- rcfw->cmdq_bar_reg = RCFW_COMM_PCI_BAR_REGION; +- res_base = pci_resource_start(pdev, rcfw->cmdq_bar_reg); +- if (!res_base) ++ mbox->reg.bar_id = RCFW_COMM_PCI_BAR_REGION; ++ mbox->reg.len = RCFW_COMM_SIZE; ++ mbox->reg.bar_base = pci_resource_start(pdev, mbox->reg.bar_id); ++ if (!mbox->reg.bar_base) { ++ dev_err(&pdev->dev, ++ "QPLIB: CMDQ BAR region %d resc start is 0!\n", ++ mbox->reg.bar_id); + return -ENOMEM; ++ } + +- rcfw->cmdq_bar_reg_iomem = ioremap_nocache(res_base + +- RCFW_COMM_BASE_OFFSET, +- RCFW_COMM_SIZE); +- if (!rcfw->cmdq_bar_reg_iomem) { +- dev_err(&rcfw->pdev->dev, "CMDQ BAR region %d mapping failed\n", +- rcfw->cmdq_bar_reg); ++ bar_reg = mbox->reg.bar_base + RCFW_COMM_BASE_OFFSET; ++ mbox->reg.len = RCFW_COMM_SIZE; ++ mbox->reg.bar_reg = ioremap(bar_reg, mbox->reg.len); ++ if (!mbox->reg.bar_reg) { ++ dev_err(&pdev->dev, ++ "QPLIB: CMDQ BAR region %d mapping failed\n", ++ mbox->reg.bar_id); + return -ENOMEM; + } + +- rcfw->cmdq_bar_reg_prod_off = virt_fn ? RCFW_VF_COMM_PROD_OFFSET : +- RCFW_PF_COMM_PROD_OFFSET; ++ prod_offt = is_vf ? RCFW_VF_COMM_PROD_OFFSET : ++ RCFW_PF_COMM_PROD_OFFSET; ++ mbox->prod = (void __iomem *)(mbox->reg.bar_reg + prod_offt); ++ mbox->db = (void __iomem *)(mbox->reg.bar_reg + RCFW_COMM_TRIG_OFFSET); ++ return rc; ++} ++ ++static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt) ++{ ++ struct bnxt_qplib_creq_db *creq_db; ++ resource_size_t bar_reg; ++ struct pci_dev *pdev; + +- rcfw->cmdq_bar_reg_trig_off = RCFW_COMM_TRIG_OFFSET; ++ pdev = rcfw->pdev; ++ creq_db = &rcfw->creq.creq_db; + +- /* CREQ */ +- rcfw->creq_bar_reg = RCFW_COMM_CONS_PCI_BAR_REGION; +- res_base = pci_resource_start(pdev, rcfw->creq_bar_reg); +- if (!res_base) +- dev_err(&rcfw->pdev->dev, +- "CREQ BAR region %d resc start is 0!\n", +- rcfw->creq_bar_reg); ++ creq_db->reg.bar_id = RCFW_COMM_CONS_PCI_BAR_REGION; ++ creq_db->reg.bar_base = pci_resource_start(pdev, creq_db->reg.bar_id); ++ if (!creq_db->reg.bar_id) ++ dev_err(&pdev->dev, ++ "QPLIB: CREQ BAR region %d resc start is 0!", ++ creq_db->reg.bar_id); ++ ++ bar_reg = creq_db->reg.bar_base + reg_offt; + /* Unconditionally map 8 bytes to support 57500 series */ +- rcfw->creq_bar_reg_iomem = ioremap_nocache(res_base + cp_bar_reg_off, +- 8); +- if (!rcfw->creq_bar_reg_iomem) { +- dev_err(&rcfw->pdev->dev, "CREQ BAR region %d mapping failed\n", +- rcfw->creq_bar_reg); +- iounmap(rcfw->cmdq_bar_reg_iomem); +- rcfw->cmdq_bar_reg_iomem = NULL; ++ creq_db->reg.len = 8; ++ creq_db->reg.bar_reg = ioremap(bar_reg, creq_db->reg.len); ++ if (!creq_db->reg.bar_reg) { ++ dev_err(&pdev->dev, ++ "QPLIB: CREQ BAR region %d mapping failed", ++ creq_db->reg.bar_id); + return -ENOMEM; + } +- rcfw->creq_qp_event_processed = 0; +- rcfw->creq_func_event_processed = 0; ++ creq_db->db = creq_db->reg.bar_reg; ++ return 0; ++} + +- if (aeq_handler) +- rcfw->aeq_handler = aeq_handler; +- init_waitqueue_head(&rcfw->waitq); ++static void bnxt_qplib_start_rcfw(struct bnxt_qplib_rcfw *rcfw) ++{ ++ struct bnxt_qplib_cmdq_ctx *cmdq; ++ struct bnxt_qplib_creq_ctx *creq; ++ struct bnxt_qplib_cmdq_mbox *mbox; ++ struct cmdq_init init = {0}; ++ ++ cmdq = &rcfw->cmdq; ++ creq = &rcfw->creq; ++ mbox = &cmdq->cmdq_mbox; ++ ++ init.cmdq_pbl = cpu_to_le64(cmdq->hwq.pbl[PBL_LVL_0].pg_map_arr[0]); ++ init.cmdq_size_cmdq_lvl = ++ cpu_to_le16(((rcfw->cmdq_depth << ++ CMDQ_INIT_CMDQ_SIZE_SFT) & ++ CMDQ_INIT_CMDQ_SIZE_MASK) | ++ ((cmdq->hwq.level << ++ CMDQ_INIT_CMDQ_LVL_SFT) & ++ CMDQ_INIT_CMDQ_LVL_MASK)); ++ init.creq_ring_id = cpu_to_le16(creq->ring_id); ++ /* Write to the Bono mailbox register */ ++ __iowrite32_copy(mbox->reg.bar_reg, &init, sizeof(init) / 4); ++} ++ ++int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw, ++ int msix_vector, ++ int cp_bar_reg_off, int virt_fn, ++ aeq_handler_t aeq_handler) ++{ ++ struct bnxt_qplib_cmdq_ctx *cmdq; ++ struct bnxt_qplib_creq_ctx *creq; ++ int rc; ++ ++ cmdq = &rcfw->cmdq; ++ creq = &rcfw->creq; ++ ++ /* Clear to defaults */ ++ ++ cmdq->seq_num = 0; ++ set_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags); ++ init_waitqueue_head(&cmdq->waitq); ++ ++ creq->stats.creq_qp_event_processed = 0; ++ creq->stats.creq_func_event_processed = 0; ++ creq->aeq_handler = aeq_handler; ++ ++ rc = bnxt_qplib_map_cmdq_mbox(rcfw, virt_fn); ++ if (rc) ++ return rc; ++ ++ rc = bnxt_qplib_map_creq_db(rcfw, cp_bar_reg_off); ++ if (rc) ++ return rc; + + rc = bnxt_qplib_rcfw_start_irq(rcfw, msix_vector, true); + if (rc) { +@@ -770,16 +865,8 @@ int bnxt_qplib_enable_rcfw_channel(struc + return rc; + } + +- init.cmdq_pbl = cpu_to_le64(rcfw->cmdq.pbl[PBL_LVL_0].pg_map_arr[0]); +- init.cmdq_size_cmdq_lvl = cpu_to_le16( +- ((rcfw->cmdq_depth << CMDQ_INIT_CMDQ_SIZE_SFT) & +- CMDQ_INIT_CMDQ_SIZE_MASK) | +- ((rcfw->cmdq.level << CMDQ_INIT_CMDQ_LVL_SFT) & +- CMDQ_INIT_CMDQ_LVL_MASK)); +- init.creq_ring_id = cpu_to_le16(rcfw->creq_ring_id); ++ bnxt_qplib_start_rcfw(rcfw); + +- /* Write to the Bono mailbox register */ +- __iowrite32_copy(rcfw->cmdq_bar_reg_iomem, &init, sizeof(init) / 4); + return 0; + } + +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +@@ -206,8 +206,9 @@ static inline void bnxt_qplib_ring_creq_ + #define CREQ_ENTRY_POLL_BUDGET 0x100 + + /* HWQ */ ++typedef int (*aeq_handler_t)(struct bnxt_qplib_rcfw *, void *, void *); + +-struct bnxt_qplib_crsq { ++struct bnxt_qplib_crsqe { + struct creq_qp_event *resp; + u32 req_size; + }; +@@ -225,41 +226,53 @@ struct bnxt_qplib_qp_node { + + #define BNXT_QPLIB_OOS_COUNT_MASK 0xFFFFFFFF + ++#define FIRMWARE_INITIALIZED_FLAG (0) ++#define FIRMWARE_FIRST_FLAG (31) ++#define FIRMWARE_TIMED_OUT (3) ++struct bnxt_qplib_cmdq_mbox { ++ struct bnxt_qplib_reg_desc reg; ++ void __iomem *prod; ++ void __iomem *db; ++}; ++ ++struct bnxt_qplib_cmdq_ctx { ++ struct bnxt_qplib_hwq hwq; ++ struct bnxt_qplib_cmdq_mbox cmdq_mbox; ++ wait_queue_head_t waitq; ++ unsigned long flags; ++ unsigned long *cmdq_bitmap; ++ u32 bmap_size; ++ u32 seq_num; ++}; ++ ++struct bnxt_qplib_creq_db { ++ struct bnxt_qplib_reg_desc reg; ++ void __iomem *db; ++}; ++ ++struct bnxt_qplib_creq_stat { ++ u64 creq_qp_event_processed; ++ u64 creq_func_event_processed; ++}; ++ ++struct bnxt_qplib_creq_ctx { ++ struct bnxt_qplib_hwq hwq; ++ struct bnxt_qplib_creq_db creq_db; ++ struct bnxt_qplib_creq_stat stats; ++ struct tasklet_struct creq_tasklet; ++ aeq_handler_t aeq_handler; ++ u16 ring_id; ++ int msix_vec; ++ bool requested; /*irq handler installed */ ++}; ++ + /* RCFW Communication Channels */ + struct bnxt_qplib_rcfw { + struct pci_dev *pdev; + struct bnxt_qplib_res *res; +- int vector; +- struct tasklet_struct worker; +- bool requested; +- unsigned long *cmdq_bitmap; +- u32 bmap_size; +- unsigned long flags; +-#define FIRMWARE_INITIALIZED_FLAG 0 +-#define FIRMWARE_FIRST_FLAG 31 +-#define FIRMWARE_TIMED_OUT 3 +- wait_queue_head_t waitq; +- int (*aeq_handler)(struct bnxt_qplib_rcfw *, +- void *, void *); +- u32 seq_num; +- +- /* Bar region info */ +- void __iomem *cmdq_bar_reg_iomem; +- u16 cmdq_bar_reg; +- u16 cmdq_bar_reg_prod_off; +- u16 cmdq_bar_reg_trig_off; +- u16 creq_ring_id; +- u16 creq_bar_reg; +- void __iomem *creq_bar_reg_iomem; +- +- /* Cmd-Resp and Async Event notification queue */ +- struct bnxt_qplib_hwq creq; +- u64 creq_qp_event_processed; +- u64 creq_func_event_processed; +- +- /* Actual Cmd and Resp Queues */ +- struct bnxt_qplib_hwq cmdq; +- struct bnxt_qplib_crsq *crsqe_tbl; ++ struct bnxt_qplib_cmdq_ctx cmdq; ++ struct bnxt_qplib_creq_ctx creq; ++ struct bnxt_qplib_crsqe *crsqe_tbl; + int qp_tbl_size; + struct bnxt_qplib_qp_node *qp_tbl; + u64 oos_prev; +@@ -279,8 +292,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnx + int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw, + int msix_vector, + int cp_bar_reg_off, int virt_fn, +- int (*aeq_handler)(struct bnxt_qplib_rcfw *, +- void *aeqe, void *obj)); ++ aeq_handler_t aeq_handler); + + struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf( + struct bnxt_qplib_rcfw *rcfw, +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h +@@ -80,6 +80,13 @@ enum bnxt_qplib_pbl_lvl { + #define ROCE_PG_SIZE_8M (8 * 1024 * 1024) + #define ROCE_PG_SIZE_1G (1024 * 1024 * 1024) + ++struct bnxt_qplib_reg_desc { ++ u8 bar_id; ++ resource_size_t bar_base; ++ void __iomem *bar_reg; ++ size_t len; ++}; ++ + struct bnxt_qplib_pbl { + u32 pg_count; + u32 pg_size; diff --git a/patches.suse/RDMA-bnxt_re-Refactor-device-add-remove-functionalit.patch b/patches.suse/RDMA-bnxt_re-Refactor-device-add-remove-functionalit.patch new file mode 100644 index 0000000..dea80cb --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-device-add-remove-functionalit.patch @@ -0,0 +1,277 @@ +From: Selvin Xavier +Date: Wed, 26 Feb 2020 07:45:31 -0800 +Subject: RDMA/bnxt_re: Refactor device add/remove functionalities +Patch-mainline: v5.7-rc1 +Git-commit: c2b777a9592395bf68f17bcfa76813eb507a001c +References: bsc#1170774 + + - bnxt_re_ib_reg() handles two main functionalities - initializing the + device and registering with the IB stack. Split it into 2 functions + i.e. bnxt_re_dev_init() and bnxt_re_ib_init() to account for the same + thereby improve modularity. Do the same for + bnxt_re_ib_unreg()i.e. split into two functions - bnxt_re_dev_uninit() + and bnxt_re_ib_uninit(). + + - Simplify the code by combining the different steps to add and remove + the device into two functions. + + - Report correct netdev link state during device register + +Link: https://lore.kernel.org/r/1582731932-26574-2-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/main.c | 139 ++++++++++++++++++++--------------- + 1 file changed, 82 insertions(+), 57 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -78,7 +78,8 @@ static struct list_head bnxt_re_dev_list + /* Mutex to protect the list of bnxt_re devices added */ + static DEFINE_MUTEX(bnxt_re_dev_lock); + static struct workqueue_struct *bnxt_re_wq; +-static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev); ++static void bnxt_re_remove_device(struct bnxt_re_dev *rdev); ++static void bnxt_re_ib_uninit(struct bnxt_re_dev *rdev); + + static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev) + { +@@ -237,7 +238,9 @@ static void bnxt_re_shutdown(void *p) + if (!rdev) + return; + +- bnxt_re_ib_unreg(rdev); ++ bnxt_re_ib_uninit(rdev); ++ ASSERT_RTNL(); ++ bnxt_re_remove_device(rdev); + } + + static void bnxt_re_stop_irq(void *handle) +@@ -1317,7 +1320,41 @@ static void bnxt_re_query_hwrm_intf_vers + le16_to_cpu(resp.hwrm_intf_patch); + } + +-static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev) ++static void bnxt_re_ib_uninit(struct bnxt_re_dev *rdev) ++{ ++ /* Cleanup ib dev */ ++ if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) { ++ ib_unregister_device(&rdev->ibdev); ++ clear_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); ++ } ++} ++ ++int bnxt_re_ib_init(struct bnxt_re_dev *rdev) ++{ ++ int rc = 0; ++ u32 event; ++ ++ /* Register ib dev */ ++ rc = bnxt_re_register_ib(rdev); ++ if (rc) { ++ pr_err("Failed to register with IB: %#x\n", rc); ++ return rc; ++ } ++ set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); ++ dev_info(rdev_to_dev(rdev), "Device registered successfully"); ++ ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, ++ &rdev->active_width); ++ set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags); ++ ++ event = netif_running(rdev->netdev) && netif_carrier_ok(rdev->netdev) ? ++ IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR; ++ ++ bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, event); ++ ++ return rc; ++} ++ ++static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev) + { + u8 type; + int rc; +@@ -1373,20 +1410,15 @@ static void bnxt_re_worker(struct work_s + schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000)); + } + +-static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) ++static int bnxt_re_dev_init(struct bnxt_re_dev *rdev) + { + struct bnxt_qplib_creq_ctx *creq; + struct bnxt_re_ring_attr rattr; + u32 db_offt; +- bool locked; + int vid; + u8 type; + int rc; + +- /* Acquire rtnl lock through out this function */ +- rtnl_lock(); +- locked = true; +- + /* Registered a new RoCE device instance to netdev */ + memset(&rattr, 0, sizeof(rattr)); + rc = bnxt_re_register_netdev(rdev); +@@ -1514,23 +1546,6 @@ static int bnxt_re_ib_reg(struct bnxt_re + schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000)); + } + +- rtnl_unlock(); +- locked = false; +- +- /* Register ib dev */ +- rc = bnxt_re_register_ib(rdev); +- if (rc) { +- ibdev_err(&rdev->ibdev, +- "Failed to register with IB: %#x\n", rc); +- goto fail; +- } +- set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); +- ibdev_info(&rdev->ibdev, "Device registered successfully"); +- ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, +- &rdev->active_width); +- set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags); +- bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE); +- + return 0; + free_sctx: + bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); +@@ -1544,10 +1559,7 @@ free_ring: + free_rcfw: + bnxt_qplib_free_rcfw_channel(&rdev->rcfw); + fail: +- if (!locked) +- rtnl_lock(); +- bnxt_re_ib_unreg(rdev); +- rtnl_unlock(); ++ bnxt_re_dev_uninit(rdev); + + return rc; + } +@@ -1589,9 +1601,35 @@ exit: + return rc; + } + +-static void bnxt_re_remove_one(struct bnxt_re_dev *rdev) ++static void bnxt_re_remove_device(struct bnxt_re_dev *rdev) + { ++ bnxt_re_dev_uninit(rdev); + pci_dev_put(rdev->en_dev->pdev); ++ bnxt_re_dev_unreg(rdev); ++} ++ ++static int bnxt_re_add_device(struct bnxt_re_dev **rdev, ++ struct net_device *netdev) ++{ ++ int rc; ++ ++ rc = bnxt_re_dev_reg(rdev, netdev); ++ if (rc == -ENODEV) ++ return rc; ++ if (rc) { ++ pr_err("Failed to register with the device %s: %#x\n", ++ netdev->name, rc); ++ return rc; ++ } ++ ++ pci_dev_get((*rdev)->en_dev->pdev); ++ rc = bnxt_re_dev_init(*rdev); ++ if (rc) { ++ pci_dev_put((*rdev)->en_dev->pdev); ++ bnxt_re_dev_unreg(*rdev); ++ } ++ ++ return rc; + } + + /* Handle all deferred netevents tasks */ +@@ -1606,16 +1644,17 @@ static void bnxt_re_task(struct work_str + + if (re_work->event != NETDEV_REGISTER && + !test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) +- return; ++ goto done; + + switch (re_work->event) { + case NETDEV_REGISTER: +- rc = bnxt_re_ib_reg(rdev); ++ rc = bnxt_re_ib_init(rdev); + if (rc) { + ibdev_err(&rdev->ibdev, + "Failed to register with IB: %#x", rc); +- bnxt_re_remove_one(rdev); +- bnxt_re_dev_unreg(rdev); ++ rtnl_lock(); ++ bnxt_re_remove_device(rdev); ++ rtnl_unlock(); + goto exit; + } + break; +@@ -1638,17 +1677,13 @@ static void bnxt_re_task(struct work_str + default: + break; + } ++done: + smp_mb__before_atomic(); + atomic_dec(&rdev->sched_count); + exit: + kfree(re_work); + } + +-static void bnxt_re_init_one(struct bnxt_re_dev *rdev) +-{ +- pci_dev_get(rdev->en_dev->pdev); +-} +- + /* + * "Notifier chain callback can be invoked for the same chain from + * different CPUs at the same time". +@@ -1686,17 +1721,9 @@ static int bnxt_re_netdev_event(struct n + case NETDEV_REGISTER: + if (rdev) + break; +- rc = bnxt_re_dev_reg(&rdev, real_dev); +- if (rc == -ENODEV) +- break; +- if (rc) { +- ibdev_err(&rdev->ibdev, +- "Failed to register with the device %s: %#x\n", +- real_dev->name, rc); +- break; +- } +- bnxt_re_init_one(rdev); +- sch_work = true; ++ rc = bnxt_re_add_device(&rdev, real_dev); ++ if (!rc) ++ sch_work = true; + break; + + case NETDEV_UNREGISTER: +@@ -1705,9 +1732,8 @@ static int bnxt_re_netdev_event(struct n + */ + if (atomic_read(&rdev->sched_count) > 0) + goto exit; +- bnxt_re_ib_unreg(rdev); +- bnxt_re_remove_one(rdev); +- bnxt_re_dev_unreg(rdev); ++ bnxt_re_ib_uninit(rdev); ++ bnxt_re_remove_device(rdev); + break; + + default: +@@ -1784,12 +1810,11 @@ static void __exit bnxt_re_mod_exit(void + */ + flush_workqueue(bnxt_re_wq); + bnxt_re_dev_stop(rdev); ++ bnxt_re_ib_uninit(rdev); + /* Acquire the rtnl_lock as the L2 resources are freed here */ + rtnl_lock(); +- bnxt_re_ib_unreg(rdev); ++ bnxt_re_remove_device(rdev); + rtnl_unlock(); +- bnxt_re_remove_one(rdev); +- bnxt_re_dev_unreg(rdev); + } + unregister_netdevice_notifier(&bnxt_re_netdev_notifier); + if (bnxt_re_wq) diff --git a/patches.suse/RDMA-bnxt_re-Refactor-doorbell-management-functions.patch b/patches.suse/RDMA-bnxt_re-Refactor-doorbell-management-functions.patch new file mode 100644 index 0000000..ffd7b14 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-doorbell-management-functions.patch @@ -0,0 +1,606 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:11:04 -0500 +Subject: RDMA/bnxt_re: Refactor doorbell management functions +Patch-mainline: v5.7-rc1 +Git-commit: 6f53196bc5e7fd3c05337f24977cacb08e0f9753 +References: bsc#1170774 + +Moving all the fast path doorbell functions at one place under +qplib_res.h. To pass doorbell record information a new structure +bnxt_qplib_db_info has been introduced. Every roce object holds an +instance of this structure and doorbell information is initialized during +resource creation. + +When DB is rung only the current queue index is read from hardware ring +and rest of the data is taken from pre-initialized dbinfo structure. + +Link: https://lore.kernel.org/r/1581786665-23705-8-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 143 ++++++++++------------------- + drivers/infiniband/hw/bnxt_re/qplib_fp.h | 44 -------- + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 21 +--- + drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 2 + drivers/infiniband/hw/bnxt_re/qplib_res.h | 78 +++++++++++++++ + 5 files changed, 141 insertions(+), 147 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -53,9 +53,7 @@ + #include "qplib_sp.h" + #include "qplib_fp.h" + +-static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq); + static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp); +-static void bnxt_qplib_arm_srq(struct bnxt_qplib_srq *srq, u32 arm_type); + + static void bnxt_qplib_cancel_phantom_processing(struct bnxt_qplib_qp *qp) + { +@@ -236,7 +234,6 @@ fail: + static void bnxt_qplib_service_nq(unsigned long data) + { + struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data; +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); + struct bnxt_qplib_hwq *hwq = &nq->hwq; + struct nq_base *nqe, **nq_ptr; + struct bnxt_qplib_cq *cq; +@@ -272,7 +269,8 @@ static void bnxt_qplib_service_nq(unsign + q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) + << 32; + cq = (struct bnxt_qplib_cq *)(unsigned long)q_handle; +- bnxt_qplib_arm_cq_enable(cq); ++ bnxt_qplib_armen_db(&cq->dbinfo, ++ DBC_DBC_TYPE_CQ_ARMENA); + spin_lock_bh(&cq->compl_lock); + atomic_set(&cq->arm_state, 0); + if (!nq->cqn_handler(nq, (cq))) +@@ -285,14 +283,16 @@ static void bnxt_qplib_service_nq(unsign + } + case NQ_BASE_TYPE_SRQ_EVENT: + { ++ struct bnxt_qplib_srq *srq; + struct nq_srq_event *nqsrqe = + (struct nq_srq_event *)nqe; + + q_handle = le32_to_cpu(nqsrqe->srq_handle_low); + q_handle |= (u64)le32_to_cpu(nqsrqe->srq_handle_high) + << 32; +- bnxt_qplib_arm_srq((struct bnxt_qplib_srq *)q_handle, +- DBC_DBC_TYPE_SRQ_ARMENA); ++ srq = (struct bnxt_qplib_srq *)q_handle; ++ bnxt_qplib_armen_db(&srq->dbinfo, ++ DBC_DBC_TYPE_SRQ_ARMENA); + if (!nq->srqn_handler(nq, + (struct bnxt_qplib_srq *)q_handle, + nqsrqe->event)) +@@ -314,9 +314,7 @@ static void bnxt_qplib_service_nq(unsign + } + if (hwq->cons != raw_cons) { + hwq->cons = raw_cons; +- bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, hwq->cons, +- hwq->max_elements, nq->ring_id, +- gen_p5); ++ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true); + } + } + +@@ -340,11 +338,9 @@ static irqreturn_t bnxt_qplib_nq_irq(int + + void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) + { +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); + tasklet_disable(&nq->nq_tasklet); + /* Mask h/w interrupt */ +- bnxt_qplib_ring_nq_db(nq->nq_db.db, nq->hwq.cons, +- nq->hwq.max_elements, nq->ring_id, gen_p5); ++ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false); + /* Sync with last running IRQ handler */ + synchronize_irq(nq->msix_vec); + if (kill) +@@ -369,7 +365,6 @@ void bnxt_qplib_disable_nq(struct bnxt_q + if (nq->nq_db.reg.bar_reg) { + iounmap(nq->nq_db.reg.bar_reg); + nq->nq_db.reg.bar_reg = NULL; +- nq->nq_db.db = NULL; + } + + nq->cqn_handler = NULL; +@@ -380,7 +375,6 @@ void bnxt_qplib_disable_nq(struct bnxt_q + int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, + int msix_vector, bool need_init) + { +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); + int rc; + + if (nq->requested) +@@ -407,8 +401,7 @@ int bnxt_qplib_nq_start_irq(struct bnxt_ + nq->msix_vec, nq_indx); + } + nq->requested = true; +- bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, nq->hwq.cons, +- nq->hwq.max_elements, nq->ring_id, gen_p5); ++ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true); + + return rc; + } +@@ -443,7 +436,9 @@ static int bnxt_qplib_map_nq_db(struct b + goto fail; + } + +- nq_db->db = nq_db->reg.bar_reg; ++ nq_db->dbinfo.db = nq_db->reg.bar_reg; ++ nq_db->dbinfo.hwq = &nq->hwq; ++ nq_db->dbinfo.xid = nq->ring_id; + fail: + return rc; + } +@@ -516,24 +511,6 @@ int bnxt_qplib_alloc_nq(struct bnxt_qpli + } + + /* SRQ */ +-static void bnxt_qplib_arm_srq(struct bnxt_qplib_srq *srq, u32 arm_type) +-{ +- struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; +- void __iomem *db; +- u32 sw_prod; +- u64 val = 0; +- +- /* Ring DB */ +- sw_prod = (arm_type == DBC_DBC_TYPE_SRQ_ARM) ? +- srq->threshold : HWQ_CMP(srq_hwq->prod, srq_hwq); +- db = (arm_type == DBC_DBC_TYPE_SRQ_ARMENA) ? srq->dbr_base : +- srq->dpi->dbr; +- val = ((srq->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | arm_type; +- val <<= 32; +- val |= (sw_prod << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK; +- writeq(val, db); +-} +- + void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res, + struct bnxt_qplib_srq *srq) + { +@@ -624,9 +601,12 @@ int bnxt_qplib_create_srq(struct bnxt_qp + srq->swq[srq->last_idx].next_idx = -1; + + srq->id = le32_to_cpu(resp.xid); +- srq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem; ++ srq->dbinfo.hwq = &srq->hwq; ++ srq->dbinfo.xid = srq->id; ++ srq->dbinfo.db = srq->dpi->dbr; ++ srq->dbinfo.priv_db = res->dpi_tbl.dbr_bar_reg_iomem; + if (srq->threshold) +- bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ_ARMENA); ++ bnxt_qplib_armen_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ_ARMENA); + srq->arm_req = false; + + return 0; +@@ -650,7 +630,7 @@ int bnxt_qplib_modify_srq(struct bnxt_qp + srq_hwq->max_elements - sw_cons + sw_prod; + if (count > srq->threshold) { + srq->arm_req = false; +- bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ_ARM); ++ bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold); + } else { + /* Deferred arming */ + srq->arm_req = true; +@@ -738,10 +718,10 @@ int bnxt_qplib_post_srq_recv(struct bnxt + srq_hwq->max_elements - sw_cons + sw_prod; + spin_unlock(&srq_hwq->lock); + /* Ring DB */ +- bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ); ++ bnxt_qplib_ring_prod_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ); + if (srq->arm_req == true && count > srq->threshold) { + srq->arm_req = false; +- bnxt_qplib_arm_srq(srq, DBC_DBC_TYPE_SRQ_ARM); ++ bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold); + } + done: + return rc; +@@ -872,6 +852,15 @@ int bnxt_qplib_create_qp1(struct bnxt_qp + + qp->id = le32_to_cpu(resp.xid); + qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET; ++ qp->cctx = res->cctx; ++ sq->dbinfo.hwq = &sq->hwq; ++ sq->dbinfo.xid = qp->id; ++ sq->dbinfo.db = qp->dpi->dbr; ++ if (rq->max_wqe) { ++ rq->dbinfo.hwq = &rq->hwq; ++ rq->dbinfo.xid = qp->id; ++ rq->dbinfo.db = qp->dpi->dbr; ++ } + rcfw->qp_tbl[qp->id].qp_id = qp->id; + rcfw->qp_tbl[qp->id].qp_handle = (void *)qp; + +@@ -1109,9 +1098,17 @@ int bnxt_qplib_create_qp(struct bnxt_qpl + + qp->id = le32_to_cpu(resp.xid); + qp->cur_qp_state = CMDQ_MODIFY_QP_NEW_STATE_RESET; +- qp->cctx = res->cctx; + INIT_LIST_HEAD(&qp->sq_flush); + INIT_LIST_HEAD(&qp->rq_flush); ++ qp->cctx = res->cctx; ++ sq->dbinfo.hwq = &sq->hwq; ++ sq->dbinfo.xid = qp->id; ++ sq->dbinfo.db = qp->dpi->dbr; ++ if (rq->max_wqe) { ++ rq->dbinfo.hwq = &rq->hwq; ++ rq->dbinfo.xid = qp->id; ++ rq->dbinfo.db = qp->dpi->dbr; ++ } + rcfw->qp_tbl[qp->id].qp_id = qp->id; + rcfw->qp_tbl[qp->id].qp_handle = (void *)qp; + +@@ -1551,16 +1548,8 @@ void *bnxt_qplib_get_qp1_rq_buf(struct b + void bnxt_qplib_post_send_db(struct bnxt_qplib_qp *qp) + { + struct bnxt_qplib_q *sq = &qp->sq; +- u32 sw_prod; +- u64 val = 0; + +- val = (((qp->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | +- DBC_DBC_TYPE_SQ); +- val <<= 32; +- sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq); +- val |= (sw_prod << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK; +- /* Flush all the WQE writes to HW */ +- writeq(val, qp->dpi->dbr); ++ bnxt_qplib_ring_prod_db(&sq->dbinfo, DBC_DBC_TYPE_SQ); + } + + int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, +@@ -1852,16 +1841,8 @@ done: + void bnxt_qplib_post_recv_db(struct bnxt_qplib_qp *qp) + { + struct bnxt_qplib_q *rq = &qp->rq; +- u32 sw_prod; +- u64 val = 0; + +- val = (((qp->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | +- DBC_DBC_TYPE_RQ); +- val <<= 32; +- sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq); +- val |= (sw_prod << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK; +- /* Flush the writes to HW Rx WQE before the ringing Rx DB */ +- writeq(val, qp->dpi->dbr); ++ bnxt_qplib_ring_prod_db(&rq->dbinfo, DBC_DBC_TYPE_RQ); + } + + int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp, +@@ -1941,34 +1922,6 @@ done: + } + + /* CQ */ +- +-/* Spinlock must be held */ +-static void bnxt_qplib_arm_cq_enable(struct bnxt_qplib_cq *cq) +-{ +- u64 val = 0; +- +- val = ((cq->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | +- DBC_DBC_TYPE_CQ_ARMENA; +- val <<= 32; +- /* Flush memory writes before enabling the CQ */ +- writeq(val, cq->dbr_base); +-} +- +-static void bnxt_qplib_arm_cq(struct bnxt_qplib_cq *cq, u32 arm_type) +-{ +- struct bnxt_qplib_hwq *cq_hwq = &cq->hwq; +- u32 sw_cons; +- u64 val = 0; +- +- /* Ring DB */ +- val = ((cq->id << DBC_DBC_XID_SFT) & DBC_DBC_XID_MASK) | arm_type; +- val <<= 32; +- sw_cons = HWQ_CMP(cq_hwq->cons, cq_hwq); +- val |= (sw_cons << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK; +- /* flush memory writes before arming the CQ */ +- writeq(val, cq->dpi->dbr); +-} +- + int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; +@@ -2023,7 +1976,6 @@ int bnxt_qplib_create_cq(struct bnxt_qpl + goto fail; + + cq->id = le32_to_cpu(resp.xid); +- cq->dbr_base = res->dpi_tbl.dbr_bar_reg_iomem; + cq->period = BNXT_QPLIB_QUEUE_START_PERIOD; + init_waitqueue_head(&cq->waitq); + INIT_LIST_HEAD(&cq->sqf_head); +@@ -2031,7 +1983,13 @@ int bnxt_qplib_create_cq(struct bnxt_qpl + spin_lock_init(&cq->compl_lock); + spin_lock_init(&cq->flush_lock); + +- bnxt_qplib_arm_cq_enable(cq); ++ cq->dbinfo.hwq = &cq->hwq; ++ cq->dbinfo.xid = cq->id; ++ cq->dbinfo.db = cq->dpi->dbr; ++ cq->dbinfo.priv_db = res->dpi_tbl.dbr_bar_reg_iomem; ++ ++ bnxt_qplib_armen_db(&cq->dbinfo, DBC_DBC_TYPE_CQ_ARMENA); ++ + return 0; + + fail: +@@ -2188,8 +2146,7 @@ static int do_wa9060(struct bnxt_qplib_q + sq->send_phantom = true; + + /* TODO: Only ARM if the previous SQE is ARMALL */ +- bnxt_qplib_arm_cq(cq, DBC_DBC_TYPE_CQ_ARMALL); +- ++ bnxt_qplib_ring_db(&cq->dbinfo, DBC_DBC_TYPE_CQ_ARMALL); + rc = -EAGAIN; + goto out; + } +@@ -2859,7 +2816,7 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib + } + if (cq->hwq.cons != raw_cons) { + cq->hwq.cons = raw_cons; +- bnxt_qplib_arm_cq(cq, DBC_DBC_TYPE_CQ); ++ bnxt_qplib_ring_db(&cq->dbinfo, DBC_DBC_TYPE_CQ); + } + exit: + return num_cqes - budget; +@@ -2868,7 +2825,7 @@ exit: + void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type) + { + if (arm_type) +- bnxt_qplib_arm_cq(cq, arm_type); ++ bnxt_qplib_ring_db(&cq->dbinfo, arm_type); + /* Using cq->arm_state variable to track whether to issue cq handler */ + atomic_set(&cq->arm_state, 1); + } +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -42,7 +42,7 @@ + struct bnxt_qplib_srq { + struct bnxt_qplib_pd *pd; + struct bnxt_qplib_dpi *dpi; +- void __iomem *dbr_base; ++ struct bnxt_qplib_db_info dbinfo; + u64 srq_handle; + u32 id; + u32 max_wqe; +@@ -236,6 +236,7 @@ struct bnxt_qplib_swqe { + struct bnxt_qplib_q { + struct bnxt_qplib_hwq hwq; + struct bnxt_qplib_swq *swq; ++ struct bnxt_qplib_db_info dbinfo; + struct bnxt_qplib_sg_info sg_info; + u32 max_wqe; + u16 q_full_delta; +@@ -370,7 +371,7 @@ struct bnxt_qplib_cqe { + #define BNXT_QPLIB_QUEUE_START_PERIOD 0x01 + struct bnxt_qplib_cq { + struct bnxt_qplib_dpi *dpi; +- void __iomem *dbr_base; ++ struct bnxt_qplib_db_info dbinfo; + u32 max_wqe; + u32 id; + u16 count; +@@ -433,46 +434,9 @@ struct bnxt_qplib_cq { + NQ_DB_IDX_VALID | \ + NQ_DB_IRQ_DIS) + +-static inline void bnxt_qplib_ring_nq_db64(void __iomem *db, u32 index, +- u32 xid, bool arm) +-{ +- u64 val; +- +- val = xid & DBC_DBC_XID_MASK; +- val |= DBC_DBC_PATH_ROCE; +- val |= arm ? DBC_DBC_TYPE_NQ_ARM : DBC_DBC_TYPE_NQ; +- val <<= 32; +- val |= index & DBC_DBC_INDEX_MASK; +- writeq(val, db); +-} +- +-static inline void bnxt_qplib_ring_nq_db_rearm(void __iomem *db, u32 raw_cons, +- u32 max_elements, u32 xid, +- bool gen_p5) +-{ +- u32 index = raw_cons & (max_elements - 1); +- +- if (gen_p5) +- bnxt_qplib_ring_nq_db64(db, index, xid, true); +- else +- writel(NQ_DB_CP_FLAGS_REARM | (index & DBC_DBC32_XID_MASK), db); +-} +- +-static inline void bnxt_qplib_ring_nq_db(void __iomem *db, u32 raw_cons, +- u32 max_elements, u32 xid, +- bool gen_p5) +-{ +- u32 index = raw_cons & (max_elements - 1); +- +- if (gen_p5) +- bnxt_qplib_ring_nq_db64(db, index, xid, false); +- else +- writel(NQ_DB_CP_FLAGS | (index & DBC_DBC32_XID_MASK), db); +-} +- + struct bnxt_qplib_nq_db { + struct bnxt_qplib_reg_desc reg; +- void __iomem *db; ++ struct bnxt_qplib_db_info dbinfo; + }; + + typedef int (*cqn_handler_t)(struct bnxt_qplib_nq *nq, +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +@@ -379,7 +379,6 @@ static int bnxt_qplib_process_qp_event(s + static void bnxt_qplib_service_creq(unsigned long data) + { + struct bnxt_qplib_rcfw *rcfw = (struct bnxt_qplib_rcfw *)data; +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx); + struct bnxt_qplib_creq_ctx *creq = &rcfw->creq; + u32 type, budget = CREQ_ENTRY_POLL_BUDGET; + struct bnxt_qplib_hwq *hwq = &creq->hwq; +@@ -429,9 +428,8 @@ static void bnxt_qplib_service_creq(unsi + + if (hwq->cons != raw_cons) { + hwq->cons = raw_cons; +- bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db, +- raw_cons, hwq->max_elements, +- creq->ring_id, gen_p5); ++ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, ++ rcfw->res->cctx, true); + } + spin_unlock_irqrestore(&hwq->lock, flags); + } +@@ -660,15 +658,12 @@ fail: + + void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) + { +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx); + struct bnxt_qplib_creq_ctx *creq; + + creq = &rcfw->creq; + tasklet_disable(&creq->creq_tasklet); + /* Mask h/w interrupts */ +- bnxt_qplib_ring_creq_db(creq->creq_db.db, creq->hwq.cons, +- creq->hwq.max_elements, creq->ring_id, +- gen_p5); ++ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false); + /* Sync with last running IRQ-handler */ + synchronize_irq(creq->msix_vec); + if (kill) +@@ -708,7 +703,6 @@ void bnxt_qplib_disable_rcfw_channel(str + int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, + bool need_init) + { +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx); + struct bnxt_qplib_creq_ctx *creq; + int rc; + +@@ -728,9 +722,8 @@ int bnxt_qplib_rcfw_start_irq(struct bnx + if (rc) + return rc; + creq->requested = true; +- bnxt_qplib_ring_creq_db_rearm(creq->creq_db.db, +- creq->hwq.cons, creq->hwq.max_elements, +- creq->ring_id, gen_p5); ++ ++ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true); + + return 0; + } +@@ -799,7 +792,9 @@ static int bnxt_qplib_map_creq_db(struct + creq_db->reg.bar_id); + return -ENOMEM; + } +- creq_db->db = creq_db->reg.bar_reg; ++ creq_db->dbinfo.db = creq_db->reg.bar_reg; ++ creq_db->dbinfo.hwq = &rcfw->creq.hwq; ++ creq_db->dbinfo.xid = rcfw->creq.ring_id; + return 0; + } + +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +@@ -247,7 +247,7 @@ struct bnxt_qplib_cmdq_ctx { + + struct bnxt_qplib_creq_db { + struct bnxt_qplib_reg_desc reg; +- void __iomem *db; ++ struct bnxt_qplib_db_info dbinfo; + }; + + struct bnxt_qplib_creq_stat { +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h +@@ -133,6 +133,13 @@ struct bnxt_qplib_hwq { + u8 is_user; + }; + ++struct bnxt_qplib_db_info { ++ void __iomem *db; ++ void __iomem *priv_db; ++ struct bnxt_qplib_hwq *hwq; ++ u32 xid; ++}; ++ + /* Tables */ + struct bnxt_qplib_pd_tbl { + unsigned long *tbl; +@@ -290,4 +297,75 @@ void bnxt_qplib_free_ctx(struct bnxt_qpl + int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, + struct bnxt_qplib_ctx *ctx, + bool virt_fn, bool is_p5); ++ ++static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info, ++ bool arm) ++{ ++ u32 key; ++ ++ key = info->hwq->cons & (info->hwq->max_elements - 1); ++ key |= (CMPL_DOORBELL_IDX_VALID | ++ (CMPL_DOORBELL_KEY_CMPL & CMPL_DOORBELL_KEY_MASK)); ++ if (!arm) ++ key |= CMPL_DOORBELL_MASK; ++ writel(key, info->db); ++} ++ ++static inline void bnxt_qplib_ring_db(struct bnxt_qplib_db_info *info, ++ u32 type) ++{ ++ u64 key = 0; ++ ++ key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; ++ key <<= 32; ++ key |= (info->hwq->cons & (info->hwq->max_elements - 1)) & ++ DBC_DBC_INDEX_MASK; ++ writeq(key, info->db); ++} ++ ++static inline void bnxt_qplib_ring_prod_db(struct bnxt_qplib_db_info *info, ++ u32 type) ++{ ++ u64 key = 0; ++ ++ key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; ++ key <<= 32; ++ key |= (info->hwq->prod & (info->hwq->max_elements - 1)) & ++ DBC_DBC_INDEX_MASK; ++ writeq(key, info->db); ++} ++ ++static inline void bnxt_qplib_armen_db(struct bnxt_qplib_db_info *info, ++ u32 type) ++{ ++ u64 key = 0; ++ ++ key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; ++ key <<= 32; ++ writeq(key, info->priv_db); ++} ++ ++static inline void bnxt_qplib_srq_arm_db(struct bnxt_qplib_db_info *info, ++ u32 th) ++{ ++ u64 key = 0; ++ ++ key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | th; ++ key <<= 32; ++ key |= th & DBC_DBC_INDEX_MASK; ++ writeq(key, info->priv_db); ++} ++ ++static inline void bnxt_qplib_ring_nq_db(struct bnxt_qplib_db_info *info, ++ struct bnxt_qplib_chip_ctx *cctx, ++ bool arm) ++{ ++ u32 type; ++ ++ type = arm ? DBC_DBC_TYPE_NQ_ARM : DBC_DBC_TYPE_NQ; ++ if (bnxt_qplib_is_chip_gen_p5(cctx)) ++ bnxt_qplib_ring_db(info, type); ++ else ++ bnxt_qplib_ring_db32(info, arm); ++} + #endif /* __BNXT_QPLIB_RES_H__ */ diff --git a/patches.suse/RDMA-bnxt_re-Refactor-hardware-queue-memory-allocati.patch b/patches.suse/RDMA-bnxt_re-Refactor-hardware-queue-memory-allocati.patch new file mode 100644 index 0000000..560ea64 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-hardware-queue-memory-allocati.patch @@ -0,0 +1,1626 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:11:00 -0500 +Subject: RDMA/bnxt_re: Refactor hardware queue memory allocation +Patch-mainline: v5.7-rc1 +Git-commit: 0c4dcd602817502bb3dced7a834a13ef717d65a4 +References: bsc#1170774 + +At top level there are three major data structure addition. viz +bnxt_qplib_hwq_attr, bnxt_qplib_sg_info and bnxt_qplib_tqm_ctx + +Intorduction of first data structure reduces the arguments list to +bnxt_re_alloc_init_hwq() function. There are changes all over the driver +code to incorporate this new structure. The caller needs to fill the +attribute data structure and pass to this function. + +The second data structure is to pass memory region description +viz. sghead, page_size and page_shift. There are changes all over the +driver code to initialize bnxt_re_sg_info data structure. The new data +structure helps to reduce the argument list of __alloc_pbl() function +call. + +Till now the TQM rings related members were not collected under any +specific data-structure making it hard to manage. The third data +sctructure bnxt_qplib_tqm_ctx is added to refactor the TQM queue +allocation and initialization. + +Link: https://lore.kernel.org/r/1581786665-23705-4-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Naresh Kumar PBS +Signed-off-by: Selvin Xavier +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 26 + + drivers/infiniband/hw/bnxt_re/main.c | 20 - + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 169 ++++++---- + drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 55 +-- + drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 5 + drivers/infiniband/hw/bnxt_re/qplib_res.c | 470 +++++++++++++++++------------ + drivers/infiniband/hw/bnxt_re/qplib_res.h | 60 ++- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 48 +- + 9 files changed, 524 insertions(+), 331 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -870,9 +870,11 @@ static int bnxt_re_init_user_qp(struct b + return PTR_ERR(umem); + + qp->sumem = umem; +- qplib_qp->sq.sg_info.sglist = umem->sg_head.sgl; ++ qplib_qp->sq.sg_info.sghead = umem->sg_head.sgl; + qplib_qp->sq.sg_info.npages = ib_umem_num_pages(umem); + qplib_qp->sq.sg_info.nmap = umem->nmap; ++ qplib_qp->sq.sg_info.pgsize = PAGE_SIZE; ++ qplib_qp->sq.sg_info.pgshft = PAGE_SHIFT; + qplib_qp->qp_handle = ureq.qp_handle; + + if (!qp->qplib_qp.srq) { +@@ -883,9 +885,11 @@ static int bnxt_re_init_user_qp(struct b + if (IS_ERR(umem)) + goto rqfail; + qp->rumem = umem; +- qplib_qp->rq.sg_info.sglist = umem->sg_head.sgl; ++ qplib_qp->rq.sg_info.sghead = umem->sg_head.sgl; + qplib_qp->rq.sg_info.npages = ib_umem_num_pages(umem); + qplib_qp->rq.sg_info.nmap = umem->nmap; ++ qplib_qp->rq.sg_info.pgsize = PAGE_SIZE; ++ qplib_qp->rq.sg_info.pgshft = PAGE_SHIFT; + } + + qplib_qp->dpi = &cntx->dpi; +@@ -975,6 +979,8 @@ static struct bnxt_re_qp *bnxt_re_create + qp->qplib_qp.sq.max_sge = 2; + /* Q full delta can be 1 since it is internal QP */ + qp->qplib_qp.sq.q_full_delta = 1; ++ qp->qplib_qp.sq.sg_info.pgsize = PAGE_SIZE; ++ qp->qplib_qp.sq.sg_info.pgshft = PAGE_SHIFT; + + qp->qplib_qp.scq = qp1_qp->scq; + qp->qplib_qp.rcq = qp1_qp->rcq; +@@ -983,6 +989,8 @@ static struct bnxt_re_qp *bnxt_re_create + qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge; + /* Q full delta can be 1 since it is internal QP */ + qp->qplib_qp.rq.q_full_delta = 1; ++ qp->qplib_qp.rq.sg_info.pgsize = PAGE_SIZE; ++ qp->qplib_qp.rq.sg_info.pgshft = PAGE_SHIFT; + + qp->qplib_qp.mtu = qp1_qp->mtu; + +@@ -1042,6 +1050,8 @@ static int bnxt_re_init_rq_attr(struct b + if (qplqp->rq.max_sge > dev_attr->max_qp_sges) + qplqp->rq.max_sge = dev_attr->max_qp_sges; + } ++ qplqp->rq.sg_info.pgsize = PAGE_SIZE; ++ qplqp->rq.sg_info.pgshft = PAGE_SHIFT; + + return 0; + } +@@ -1094,6 +1104,8 @@ static void bnxt_re_init_sq_attr(struct + * unexpected Queue full condition + */ + qplqp->sq.q_full_delta -= 1; ++ qplqp->sq.sg_info.pgsize = PAGE_SIZE; ++ qplqp->sq.sg_info.pgshft = PAGE_SHIFT; + } + + static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp, +@@ -1509,9 +1521,11 @@ static int bnxt_re_init_user_srq(struct + return PTR_ERR(umem); + + srq->umem = umem; +- qplib_srq->sg_info.sglist = umem->sg_head.sgl; ++ qplib_srq->sg_info.sghead = umem->sg_head.sgl; + qplib_srq->sg_info.npages = ib_umem_num_pages(umem); + qplib_srq->sg_info.nmap = umem->nmap; ++ qplib_srq->sg_info.pgsize = PAGE_SIZE; ++ qplib_srq->sg_info.pgshft = PAGE_SHIFT; + qplib_srq->srq_handle = ureq.srq_handle; + qplib_srq->dpi = &cntx->dpi; + +@@ -2366,7 +2380,7 @@ static int bnxt_re_build_reg_wqe(const s + wqe->frmr.pbl_dma_ptr = qplib_frpl->hwq.pbl_dma_ptr[0]; + wqe->frmr.page_list = mr->pages; + wqe->frmr.page_list_len = mr->npages; +- wqe->frmr.levels = qplib_frpl->hwq.level + 1; ++ wqe->frmr.levels = qplib_frpl->hwq.level; + wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR; + + /* Need unconditional fence for reg_mr +@@ -2740,6 +2754,8 @@ int bnxt_re_create_cq(struct ib_cq *ibcq + if (entries > dev_attr->max_cq_wqes + 1) + entries = dev_attr->max_cq_wqes + 1; + ++ cq->qplib_cq.sg_info.pgsize = PAGE_SIZE; ++ cq->qplib_cq.sg_info.pgshft = PAGE_SHIFT; + if (udata) { + struct bnxt_re_cq_req req; + struct bnxt_re_ucontext *uctx = rdma_udata_to_drv_context( +@@ -2756,7 +2772,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq + rc = PTR_ERR(cq->umem); + goto fail; + } +- cq->qplib_cq.sg_info.sglist = cq->umem->sg_head.sgl; ++ cq->qplib_cq.sg_info.sghead = cq->umem->sg_head.sgl; + cq->qplib_cq.sg_info.npages = ib_umem_num_pages(cq->umem); + cq->qplib_cq.sg_info.nmap = cq->umem->nmap; + cq->qplib_cq.dpi = &uctx->dpi; +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -90,6 +90,8 @@ static void bnxt_re_destroy_chip_ctx(str + rdev->chip_ctx = NULL; + rdev->rcfw.res = NULL; + rdev->qplib_res.cctx = NULL; ++ rdev->qplib_res.pdev = NULL; ++ rdev->qplib_res.netdev = NULL; + kfree(chip_ctx); + } + +@@ -151,7 +153,7 @@ static void bnxt_re_limit_pf_res(struct + ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq); + if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) + for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) +- rdev->qplib_ctx.tqm_count[i] = ++ rdev->qplib_ctx.tqm_ctx.qcount[i] = + rdev->dev_attr.tqm_alloc_reqs[i]; + } + +@@ -982,8 +984,8 @@ static void bnxt_re_free_nq_res(struct b + for (i = 0; i < rdev->num_msix - 1; i++) { + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type); +- rdev->nq[i].res = NULL; + bnxt_qplib_free_nq(&rdev->nq[i]); ++ rdev->nq[i].res = NULL; + } + } + +@@ -1032,7 +1034,7 @@ static int bnxt_re_alloc_res(struct bnxt + rdev->nq[i].res = &rdev->qplib_res; + rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT + + BNXT_RE_MAX_SRQC_COUNT + 2; +- rc = bnxt_qplib_alloc_nq(rdev->en_dev->pdev, &rdev->nq[i]); ++ rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]); + if (rc) { + dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x", + i, rc); +@@ -1056,7 +1058,7 @@ static int bnxt_re_alloc_res(struct bnxt + } + return 0; + free_nq: +- for (i = num_vec_created; i >= 0; i--) { ++ for (i = num_vec_created - 1; i >= 0; i--) { + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type); + bnxt_qplib_free_nq(&rdev->nq[i]); +@@ -1335,7 +1337,7 @@ static void bnxt_re_ib_unreg(struct bnxt + dev_warn(rdev_to_dev(rdev), + "Failed to deinitialize RCFW: %#x", rc); + bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); +- bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx); ++ bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx); + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type); +@@ -1411,7 +1413,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + /* Establish RCFW Communication Channel to initialize the context + * memory for the function and all child VFs + */ +- rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw, ++ rc = bnxt_qplib_alloc_rcfw_channel(&rdev->qplib_res, &rdev->rcfw, + &rdev->qplib_ctx, + BNXT_RE_MAX_QPC_COUNT); + if (rc) { +@@ -1432,7 +1434,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + } + db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX); + vid = rdev->msix_entries[BNXT_RE_AEQ_IDX].vector; +- rc = bnxt_qplib_enable_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw, ++ rc = bnxt_qplib_enable_rcfw_channel(&rdev->rcfw, + vid, db_offt, rdev->is_virtfn, + &bnxt_re_aeq_handler); + if (rc) { +@@ -1447,7 +1449,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + + bnxt_re_set_resource_limits(rdev); + +- rc = bnxt_qplib_alloc_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx, 0, ++ rc = bnxt_qplib_alloc_ctx(&rdev->qplib_res, &rdev->qplib_ctx, 0, + bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)); + if (rc) { + pr_err("Failed to allocate QPLIB context: %#x\n", rc); +@@ -1514,7 +1516,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + free_sctx: + bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); + free_ctx: +- bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx); ++ bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx); + disable_rcfw: + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); + free_ring: +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -464,26 +464,33 @@ fail: + void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq) + { + if (nq->hwq.max_elements) { +- bnxt_qplib_free_hwq(nq->pdev, &nq->hwq); ++ bnxt_qplib_free_hwq(nq->res, &nq->hwq); + nq->hwq.max_elements = 0; + } + } + +-int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq) ++int bnxt_qplib_alloc_nq(struct bnxt_qplib_res *res, struct bnxt_qplib_nq *nq) + { +- u8 hwq_type; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; ++ struct bnxt_qplib_sg_info sginfo = {}; + +- nq->pdev = pdev; ++ nq->pdev = res->pdev; ++ nq->res = res; + if (!nq->hwq.max_elements || + nq->hwq.max_elements > BNXT_QPLIB_NQE_MAX_CNT) + nq->hwq.max_elements = BNXT_QPLIB_NQE_MAX_CNT; +- hwq_type = bnxt_qplib_get_hwq_type(nq->res); +- if (bnxt_qplib_alloc_init_hwq(nq->pdev, &nq->hwq, NULL, +- &nq->hwq.max_elements, +- BNXT_QPLIB_MAX_NQE_ENTRY_SIZE, 0, +- PAGE_SIZE, hwq_type)) +- return -ENOMEM; + ++ sginfo.pgsize = PAGE_SIZE; ++ sginfo.pgshft = PAGE_SHIFT; ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &sginfo; ++ hwq_attr.depth = nq->hwq.max_elements; ++ hwq_attr.stride = sizeof(struct nq_base); ++ hwq_attr.type = bnxt_qplib_get_hwq_type(nq->res); ++ if (bnxt_qplib_alloc_init_hwq(&nq->hwq, &hwq_attr)) { ++ dev_err(&nq->pdev->dev, "FP NQ allocation failed"); ++ return -ENOMEM; ++ } + nq->budget = 8; + return 0; + } +@@ -526,24 +533,26 @@ void bnxt_qplib_destroy_srq(struct bnxt_ + kfree(srq->swq); + if (rc) + return; +- bnxt_qplib_free_hwq(res->pdev, &srq->hwq); ++ bnxt_qplib_free_hwq(res, &srq->hwq); + } + + int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, + struct bnxt_qplib_srq *srq) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; +- struct cmdq_create_srq req; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; + struct creq_create_srq_resp resp; ++ struct cmdq_create_srq req; + struct bnxt_qplib_pbl *pbl; + u16 cmd_flags = 0; + int rc, idx; + +- srq->hwq.max_elements = srq->max_wqe; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &srq->hwq, &srq->sg_info, +- &srq->hwq.max_elements, +- BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_QUEUE); ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &srq->sg_info; ++ hwq_attr.depth = srq->max_wqe; ++ hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE; ++ hwq_attr.type = HWQ_TYPE_QUEUE; ++ rc = bnxt_qplib_alloc_init_hwq(&srq->hwq, &hwq_attr); + if (rc) + goto exit; + +@@ -602,7 +611,7 @@ int bnxt_qplib_create_srq(struct bnxt_qp + + return 0; + fail: +- bnxt_qplib_free_hwq(res->pdev, &srq->hwq); ++ bnxt_qplib_free_hwq(res, &srq->hwq); + kfree(srq->swq); + exit: + return rc; +@@ -721,15 +730,16 @@ done: + /* QP */ + int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + { ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; + struct bnxt_qplib_rcfw *rcfw = res->rcfw; +- struct cmdq_create_qp1 req; +- struct creq_create_qp1_resp resp; +- struct bnxt_qplib_pbl *pbl; + struct bnxt_qplib_q *sq = &qp->sq; + struct bnxt_qplib_q *rq = &qp->rq; +- int rc; ++ struct creq_create_qp1_resp resp; ++ struct cmdq_create_qp1 req; ++ struct bnxt_qplib_pbl *pbl; + u16 cmd_flags = 0; + u32 qp_flags = 0; ++ int rc; + + RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags); + +@@ -739,11 +749,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qp + req.qp_handle = cpu_to_le64(qp->qp_handle); + + /* SQ */ +- sq->hwq.max_elements = sq->max_wqe; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, NULL, +- &sq->hwq.max_elements, +- BNXT_QPLIB_MAX_SQE_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_QUEUE); ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &sq->sg_info; ++ hwq_attr.depth = sq->max_wqe; ++ hwq_attr.stride = BNXT_QPLIB_MAX_SQE_ENTRY_SIZE; ++ hwq_attr.type = HWQ_TYPE_QUEUE; ++ rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr); + if (rc) + goto exit; + +@@ -778,11 +789,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qp + + /* RQ */ + if (rq->max_wqe) { +- rq->hwq.max_elements = qp->rq.max_wqe; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, NULL, +- &rq->hwq.max_elements, +- BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_QUEUE); ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &rq->sg_info; ++ hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE; ++ hwq_attr.depth = qp->rq.max_wqe; ++ hwq_attr.type = HWQ_TYPE_QUEUE; ++ rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr); + if (rc) + goto fail_sq; + +@@ -848,10 +860,10 @@ int bnxt_qplib_create_qp1(struct bnxt_qp + fail: + bnxt_qplib_free_qp_hdr_buf(res, qp); + fail_rq: +- bnxt_qplib_free_hwq(res->pdev, &rq->hwq); ++ bnxt_qplib_free_hwq(res, &rq->hwq); + kfree(rq->swq); + fail_sq: +- bnxt_qplib_free_hwq(res->pdev, &sq->hwq); ++ bnxt_qplib_free_hwq(res, &sq->hwq); + kfree(sq->swq); + exit: + return rc; +@@ -860,7 +872,9 @@ exit: + int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; + unsigned long int psn_search, poff = 0; ++ struct bnxt_qplib_sg_info sginfo = {}; + struct sq_psn_search **psn_search_ptr; + struct bnxt_qplib_q *sq = &qp->sq; + struct bnxt_qplib_q *rq = &qp->rq; +@@ -887,12 +901,15 @@ int bnxt_qplib_create_qp(struct bnxt_qpl + sizeof(struct sq_psn_search_ext) : + sizeof(struct sq_psn_search); + } +- sq->hwq.max_elements = sq->max_wqe; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, &sq->sg_info, +- &sq->hwq.max_elements, +- BNXT_QPLIB_MAX_SQE_ENTRY_SIZE, +- psn_sz, +- PAGE_SIZE, HWQ_TYPE_QUEUE); ++ ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &sq->sg_info; ++ hwq_attr.stride = BNXT_QPLIB_MAX_SQE_ENTRY_SIZE; ++ hwq_attr.depth = sq->max_wqe; ++ hwq_attr.aux_stride = psn_sz; ++ hwq_attr.aux_depth = hwq_attr.depth; ++ hwq_attr.type = HWQ_TYPE_QUEUE; ++ rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr); + if (rc) + goto exit; + +@@ -956,12 +973,14 @@ int bnxt_qplib_create_qp(struct bnxt_qpl + + /* RQ */ + if (rq->max_wqe) { +- rq->hwq.max_elements = rq->max_wqe; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, +- &rq->sg_info, +- &rq->hwq.max_elements, +- BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_QUEUE); ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &rq->sg_info; ++ hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE; ++ hwq_attr.depth = rq->max_wqe; ++ hwq_attr.aux_stride = 0; ++ hwq_attr.aux_depth = 0; ++ hwq_attr.type = HWQ_TYPE_QUEUE; ++ rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr); + if (rc) + goto fail_sq; + +@@ -1029,10 +1048,17 @@ int bnxt_qplib_create_qp(struct bnxt_qpl + req_size = xrrq->max_elements * + BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE + PAGE_SIZE - 1; + req_size &= ~(PAGE_SIZE - 1); +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL, +- &xrrq->max_elements, +- BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE, +- 0, req_size, HWQ_TYPE_CTX); ++ sginfo.pgsize = req_size; ++ sginfo.pgshft = PAGE_SHIFT; ++ ++ hwq_attr.res = res; ++ hwq_attr.sginfo = &sginfo; ++ hwq_attr.depth = xrrq->max_elements; ++ hwq_attr.stride = BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE; ++ hwq_attr.aux_stride = 0; ++ hwq_attr.aux_depth = 0; ++ hwq_attr.type = HWQ_TYPE_CTX; ++ rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr); + if (rc) + goto fail_buf_free; + pbl = &xrrq->pbl[PBL_LVL_0]; +@@ -1044,11 +1070,10 @@ int bnxt_qplib_create_qp(struct bnxt_qpl + req_size = xrrq->max_elements * + BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE + PAGE_SIZE - 1; + req_size &= ~(PAGE_SIZE - 1); +- +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL, +- &xrrq->max_elements, +- BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE, +- 0, req_size, HWQ_TYPE_CTX); ++ sginfo.pgsize = req_size; ++ hwq_attr.depth = xrrq->max_elements; ++ hwq_attr.stride = BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE; ++ rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr); + if (rc) + goto fail_orrq; + +@@ -1074,17 +1099,17 @@ int bnxt_qplib_create_qp(struct bnxt_qpl + + fail: + if (qp->irrq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &qp->irrq); ++ bnxt_qplib_free_hwq(res, &qp->irrq); + fail_orrq: + if (qp->orrq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &qp->orrq); ++ bnxt_qplib_free_hwq(res, &qp->orrq); + fail_buf_free: + bnxt_qplib_free_qp_hdr_buf(res, qp); + fail_rq: +- bnxt_qplib_free_hwq(res->pdev, &rq->hwq); ++ bnxt_qplib_free_hwq(res, &rq->hwq); + kfree(rq->swq); + fail_sq: +- bnxt_qplib_free_hwq(res->pdev, &sq->hwq); ++ bnxt_qplib_free_hwq(res, &sq->hwq); + kfree(sq->swq); + exit: + return rc; +@@ -1440,16 +1465,16 @@ void bnxt_qplib_free_qp_res(struct bnxt_ + struct bnxt_qplib_qp *qp) + { + bnxt_qplib_free_qp_hdr_buf(res, qp); +- bnxt_qplib_free_hwq(res->pdev, &qp->sq.hwq); ++ bnxt_qplib_free_hwq(res, &qp->sq.hwq); + kfree(qp->sq.swq); + +- bnxt_qplib_free_hwq(res->pdev, &qp->rq.hwq); ++ bnxt_qplib_free_hwq(res, &qp->rq.hwq); + kfree(qp->rq.swq); + + if (qp->irrq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &qp->irrq); ++ bnxt_qplib_free_hwq(res, &qp->irrq); + if (qp->orrq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &qp->orrq); ++ bnxt_qplib_free_hwq(res, &qp->orrq); + + } + +@@ -1927,17 +1952,19 @@ static void bnxt_qplib_arm_cq(struct bnx + int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; +- struct cmdq_create_cq req; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; + struct creq_create_cq_resp resp; ++ struct cmdq_create_cq req; + struct bnxt_qplib_pbl *pbl; + u16 cmd_flags = 0; + int rc; + +- cq->hwq.max_elements = cq->max_wqe; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &cq->hwq, &cq->sg_info, +- &cq->hwq.max_elements, +- BNXT_QPLIB_MAX_CQE_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_QUEUE); ++ hwq_attr.res = res; ++ hwq_attr.depth = cq->max_wqe; ++ hwq_attr.stride = sizeof(struct cq_base); ++ hwq_attr.type = HWQ_TYPE_QUEUE; ++ hwq_attr.sginfo = &cq->sg_info; ++ rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr); + if (rc) + goto exit; + +@@ -1988,7 +2015,7 @@ int bnxt_qplib_create_cq(struct bnxt_qpl + return 0; + + fail: +- bnxt_qplib_free_hwq(res->pdev, &cq->hwq); ++ bnxt_qplib_free_hwq(res, &cq->hwq); + exit: + return rc; + } +@@ -2008,7 +2035,7 @@ int bnxt_qplib_destroy_cq(struct bnxt_qp + (void *)&resp, NULL, 0); + if (rc) + return rc; +- bnxt_qplib_free_hwq(res->pdev, &cq->hwq); ++ bnxt_qplib_free_hwq(res, &cq->hwq); + return 0; + } + +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -550,7 +550,7 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib + bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq); + void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type); + void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq); +-int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq); ++int bnxt_qplib_alloc_nq(struct bnxt_qplib_res *res, struct bnxt_qplib_nq *nq); + void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp); + void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp, + unsigned long *flags); +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +@@ -520,9 +520,10 @@ int bnxt_qplib_init_rcfw(struct bnxt_qpl + level = ctx->tim_tbl.level; + req.tim_pg_size_tim_lvl = (level << CMDQ_INITIALIZE_FW_TIM_LVL_SFT) | + __get_pbl_pg_idx(&ctx->tim_tbl.pbl[level]); +- level = ctx->tqm_pde_level; +- req.tqm_pg_size_tqm_lvl = (level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) | +- __get_pbl_pg_idx(&ctx->tqm_pde.pbl[level]); ++ level = ctx->tqm_ctx.pde.level; ++ req.tqm_pg_size_tqm_lvl = ++ (level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) | ++ __get_pbl_pg_idx(&ctx->tqm_ctx.pde.pbl[level]); + + req.qpc_page_dir = + cpu_to_le64(ctx->qpc_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); +@@ -535,7 +536,7 @@ int bnxt_qplib_init_rcfw(struct bnxt_qpl + req.tim_page_dir = + cpu_to_le64(ctx->tim_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); + req.tqm_page_dir = +- cpu_to_le64(ctx->tqm_pde.pbl[PBL_LVL_0].pg_map_arr[0]); ++ cpu_to_le64(ctx->tqm_ctx.pde.pbl[PBL_LVL_0].pg_map_arr[0]); + + req.number_of_qp = cpu_to_le32(ctx->qpc_tbl.max_elements); + req.number_of_mrw = cpu_to_le32(ctx->mrw_tbl.max_elements); +@@ -563,25 +564,32 @@ void bnxt_qplib_free_rcfw_channel(struct + { + kfree(rcfw->qp_tbl); + kfree(rcfw->crsqe_tbl); +- bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->cmdq); +- bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->creq); ++ bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq); ++ bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq); + rcfw->pdev = NULL; + } + +-int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev, ++int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, + struct bnxt_qplib_rcfw *rcfw, + struct bnxt_qplib_ctx *ctx, + int qp_tbl_sz) + { +- u8 hwq_type; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; ++ struct bnxt_qplib_sg_info sginfo = {}; + +- rcfw->pdev = pdev; +- rcfw->creq.max_elements = BNXT_QPLIB_CREQE_MAX_CNT; +- hwq_type = bnxt_qplib_get_hwq_type(rcfw->res); +- if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->creq, NULL, +- &rcfw->creq.max_elements, +- BNXT_QPLIB_CREQE_UNITS, +- 0, PAGE_SIZE, hwq_type)) { ++ rcfw->pdev = res->pdev; ++ rcfw->res = res; ++ ++ sginfo.pgsize = PAGE_SIZE; ++ sginfo.pgshft = PAGE_SHIFT; ++ ++ hwq_attr.sginfo = &sginfo; ++ hwq_attr.res = rcfw->res; ++ hwq_attr.depth = BNXT_QPLIB_CREQE_MAX_CNT; ++ hwq_attr.stride = BNXT_QPLIB_CREQE_UNITS; ++ hwq_attr.type = bnxt_qplib_get_hwq_type(res); ++ ++ if (bnxt_qplib_alloc_init_hwq(&rcfw->creq, &hwq_attr)) { + dev_err(&rcfw->pdev->dev, + "HW channel CREQ allocation failed\n"); + goto fail; +@@ -591,13 +599,11 @@ int bnxt_qplib_alloc_rcfw_channel(struct + else + rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192; + +- rcfw->cmdq.max_elements = rcfw->cmdq_depth; +- if (bnxt_qplib_alloc_init_hwq +- (rcfw->pdev, &rcfw->cmdq, NULL, +- &rcfw->cmdq.max_elements, +- BNXT_QPLIB_CMDQE_UNITS, 0, +- bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth), +- HWQ_TYPE_CTX)) { ++ sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth); ++ hwq_attr.depth = rcfw->cmdq_depth; ++ hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS; ++ hwq_attr.type = HWQ_TYPE_CTX; ++ if (bnxt_qplib_alloc_init_hwq(&rcfw->cmdq, &hwq_attr)) { + dev_err(&rcfw->pdev->dev, + "HW channel CMDQ allocation failed\n"); + goto fail; +@@ -690,8 +696,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnx + return 0; + } + +-int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev, +- struct bnxt_qplib_rcfw *rcfw, ++int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw, + int msix_vector, + int cp_bar_reg_off, int virt_fn, + int (*aeq_handler)(struct bnxt_qplib_rcfw *, +@@ -699,10 +704,12 @@ int bnxt_qplib_enable_rcfw_channel(struc + { + resource_size_t res_base; + struct cmdq_init init; ++ struct pci_dev *pdev; + u16 bmap_size; + int rc; + + /* General */ ++ pdev = rcfw->pdev; + rcfw->seq_num = 0; + set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags); + bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long); +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +@@ -268,7 +268,7 @@ struct bnxt_qplib_rcfw { + }; + + void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw); +-int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev, ++int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, + struct bnxt_qplib_rcfw *rcfw, + struct bnxt_qplib_ctx *ctx, + int qp_tbl_sz); +@@ -276,8 +276,7 @@ void bnxt_qplib_rcfw_stop_irq(struct bnx + void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw); + int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, + bool need_init); +-int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev, +- struct bnxt_qplib_rcfw *rcfw, ++int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw, + int msix_vector, + int cp_bar_reg_off, int virt_fn, + int (*aeq_handler)(struct bnxt_qplib_rcfw *, +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c +@@ -55,9 +55,10 @@ static int bnxt_qplib_alloc_stats_ctx(st + struct bnxt_qplib_stats *stats); + + /* PBL */ +-static void __free_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl, ++static void __free_pbl(struct bnxt_qplib_res *res, struct bnxt_qplib_pbl *pbl, + bool is_umem) + { ++ struct pci_dev *pdev = res->pdev; + int i; + + if (!is_umem) { +@@ -74,35 +75,57 @@ static void __free_pbl(struct pci_dev *p + pbl->pg_arr[i] = NULL; + } + } +- kfree(pbl->pg_arr); ++ vfree(pbl->pg_arr); + pbl->pg_arr = NULL; +- kfree(pbl->pg_map_arr); ++ vfree(pbl->pg_map_arr); + pbl->pg_map_arr = NULL; + pbl->pg_count = 0; + pbl->pg_size = 0; + } + +-static int __alloc_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl, +- struct scatterlist *sghead, u32 pages, +- u32 nmaps, u32 pg_size) ++static void bnxt_qplib_fill_user_dma_pages(struct bnxt_qplib_pbl *pbl, ++ struct bnxt_qplib_sg_info *sginfo) + { ++ struct scatterlist *sghead = sginfo->sghead; + struct sg_dma_page_iter sg_iter; ++ int i = 0; ++ ++ for_each_sg_dma_page(sghead, &sg_iter, sginfo->nmap, 0) { ++ pbl->pg_map_arr[i] = sg_page_iter_dma_address(&sg_iter); ++ pbl->pg_arr[i] = NULL; ++ pbl->pg_count++; ++ i++; ++ } ++} ++ ++static int __alloc_pbl(struct bnxt_qplib_res *res, ++ struct bnxt_qplib_pbl *pbl, ++ struct bnxt_qplib_sg_info *sginfo) ++{ ++ struct pci_dev *pdev = res->pdev; ++ struct scatterlist *sghead; + bool is_umem = false; ++ u32 pages, pg_size; + int i; + ++ if (sginfo->nopte) ++ return 0; ++ pages = sginfo->npages; ++ pg_size = sginfo->pgsize; ++ sghead = sginfo->sghead; + /* page ptr arrays */ +- pbl->pg_arr = kcalloc(pages, sizeof(void *), GFP_KERNEL); ++ pbl->pg_arr = vmalloc(pages * sizeof(void *)); + if (!pbl->pg_arr) + return -ENOMEM; + +- pbl->pg_map_arr = kcalloc(pages, sizeof(dma_addr_t), GFP_KERNEL); ++ pbl->pg_map_arr = vmalloc(pages * sizeof(dma_addr_t)); + if (!pbl->pg_map_arr) { +- kfree(pbl->pg_arr); ++ vfree(pbl->pg_arr); + pbl->pg_arr = NULL; + return -ENOMEM; + } + pbl->pg_count = 0; +- pbl->pg_size = pg_size; ++ pbl->pg_size = sginfo->pgsize; + + if (!sghead) { + for (i = 0; i < pages; i++) { +@@ -115,25 +138,19 @@ static int __alloc_pbl(struct pci_dev *p + pbl->pg_count++; + } + } else { +- i = 0; + is_umem = true; +- for_each_sg_dma_page(sghead, &sg_iter, nmaps, 0) { +- pbl->pg_map_arr[i] = sg_page_iter_dma_address(&sg_iter); +- pbl->pg_arr[i] = NULL; +- pbl->pg_count++; +- i++; +- } ++ bnxt_qplib_fill_user_dma_pages(pbl, sginfo); + } + + return 0; +- + fail: +- __free_pbl(pdev, pbl, is_umem); ++ __free_pbl(res, pbl, is_umem); + return -ENOMEM; + } + + /* HWQ */ +-void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq) ++void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res, ++ struct bnxt_qplib_hwq *hwq) + { + int i; + +@@ -144,9 +161,9 @@ void bnxt_qplib_free_hwq(struct pci_dev + + for (i = 0; i < hwq->level + 1; i++) { + if (i == hwq->level) +- __free_pbl(pdev, &hwq->pbl[i], hwq->is_user); ++ __free_pbl(res, &hwq->pbl[i], hwq->is_user); + else +- __free_pbl(pdev, &hwq->pbl[i], false); ++ __free_pbl(res, &hwq->pbl[i], false); + } + + hwq->level = PBL_LVL_MAX; +@@ -158,79 +175,113 @@ void bnxt_qplib_free_hwq(struct pci_dev + } + + /* All HWQs are power of 2 in size */ +-int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq, +- struct bnxt_qplib_sg_info *sg_info, +- u32 *elements, u32 element_size, u32 aux, +- u32 pg_size, enum bnxt_qplib_hwq_type hwq_type) ++ ++int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, ++ struct bnxt_qplib_hwq_attr *hwq_attr) + { +- u32 pages, maps, slots, size, aux_pages = 0, aux_size = 0; ++ u32 npages, aux_slots, pg_size, aux_pages = 0, aux_size = 0; ++ struct bnxt_qplib_sg_info sginfo = {}; ++ u32 depth, stride, npbl, npde; + dma_addr_t *src_phys_ptr, **dst_virt_ptr; + struct scatterlist *sghead = NULL; +- int i, rc; +- ++ struct bnxt_qplib_res *res; ++ struct pci_dev *pdev; ++ int i, rc, lvl; ++ ++ res = hwq_attr->res; ++ pdev = res->pdev; ++ sghead = hwq_attr->sginfo->sghead; ++ pg_size = hwq_attr->sginfo->pgsize; + hwq->level = PBL_LVL_MAX; + +- slots = roundup_pow_of_two(*elements); +- if (aux) { +- aux_size = roundup_pow_of_two(aux); +- aux_pages = (slots * aux_size) / pg_size; +- if ((slots * aux_size) % pg_size) ++ depth = roundup_pow_of_two(hwq_attr->depth); ++ stride = roundup_pow_of_two(hwq_attr->stride); ++ if (hwq_attr->aux_depth) { ++ aux_slots = hwq_attr->aux_depth; ++ aux_size = roundup_pow_of_two(hwq_attr->aux_stride); ++ aux_pages = (aux_slots * aux_size) / pg_size; ++ if ((aux_slots * aux_size) % pg_size) + aux_pages++; + } +- size = roundup_pow_of_two(element_size); +- +- if (sg_info) +- sghead = sg_info->sglist; + + if (!sghead) { + hwq->is_user = false; +- pages = (slots * size) / pg_size + aux_pages; +- if ((slots * size) % pg_size) +- pages++; +- if (!pages) ++ npages = (depth * stride) / pg_size + aux_pages; ++ if ((depth * stride) % pg_size) ++ npages++; ++ if (!npages) + return -EINVAL; +- maps = 0; ++ hwq_attr->sginfo->npages = npages; + } else { + hwq->is_user = true; +- pages = sg_info->npages; +- maps = sg_info->nmap; ++ npages = hwq_attr->sginfo->npages; ++ npages = (npages * PAGE_SIZE) / ++ BIT_ULL(hwq_attr->sginfo->pgshft); ++ if ((hwq_attr->sginfo->npages * PAGE_SIZE) % ++ BIT_ULL(hwq_attr->sginfo->pgshft)) ++ if (!npages) ++ npages++; + } + +- /* Alloc the 1st memory block; can be a PDL/PTL/PBL */ +- if (sghead && (pages == MAX_PBL_LVL_0_PGS)) +- rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_0], sghead, +- pages, maps, pg_size); +- else +- rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_0], NULL, +- 1, 0, pg_size); +- if (rc) +- goto fail; +- +- hwq->level = PBL_LVL_0; ++ if (npages == MAX_PBL_LVL_0_PGS) { ++ /* This request is Level 0, map PTE */ ++ rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], hwq_attr->sginfo); ++ if (rc) ++ goto fail; ++ hwq->level = PBL_LVL_0; ++ } + +- if (pages > MAX_PBL_LVL_0_PGS) { +- if (pages > MAX_PBL_LVL_1_PGS) { ++ if (npages > MAX_PBL_LVL_0_PGS) { ++ if (npages > MAX_PBL_LVL_1_PGS) { ++ u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ? ++ 0 : PTU_PTE_VALID; + /* 2 levels of indirection */ +- rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_1], NULL, +- MAX_PBL_LVL_1_PGS_FOR_LVL_2, +- 0, pg_size); ++ npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT; ++ if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT)) ++ npbl++; ++ npde = npbl >> MAX_PDL_LVL_SHIFT; ++ if (npbl % BIT(MAX_PDL_LVL_SHIFT)) ++ npde++; ++ /* Alloc PDE pages */ ++ sginfo.pgsize = npde * pg_size; ++ sginfo.npages = 1; ++ rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); ++ ++ /* Alloc PBL pages */ ++ sginfo.npages = npbl; ++ sginfo.pgsize = PAGE_SIZE; ++ rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1], &sginfo); + if (rc) + goto fail; +- /* Fill in lvl0 PBL */ ++ /* Fill PDL with PBL page pointers */ + dst_virt_ptr = + (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; + src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; +- for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) +- dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = +- src_phys_ptr[i] | PTU_PDE_VALID; +- hwq->level = PBL_LVL_1; +- +- rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_2], sghead, +- pages, maps, pg_size); ++ if (hwq_attr->type == HWQ_TYPE_MR) { ++ /* For MR it is expected that we supply only 1 contigous ++ * page i.e only 1 entry in the PDL that will contain ++ * all the PBLs for the user supplied memory region ++ */ ++ for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; ++ i++) ++ dst_virt_ptr[0][i] = src_phys_ptr[i] | ++ flag; ++ } else { ++ for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; ++ i++) ++ dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = ++ src_phys_ptr[i] | ++ PTU_PDE_VALID; ++ } ++ /* Alloc or init PTEs */ ++ rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], ++ hwq_attr->sginfo); + if (rc) + goto fail; +- +- /* Fill in lvl1 PBL */ ++ hwq->level = PBL_LVL_2; ++ if (hwq_attr->sginfo->nopte) ++ goto done; ++ /* Fill PBLs with PTE pointers */ + dst_virt_ptr = + (dma_addr_t **)hwq->pbl[PBL_LVL_1].pg_arr; + src_phys_ptr = hwq->pbl[PBL_LVL_2].pg_map_arr; +@@ -238,7 +289,7 @@ int bnxt_qplib_alloc_init_hwq(struct pci + dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = + src_phys_ptr[i] | PTU_PTE_VALID; + } +- if (hwq_type == HWQ_TYPE_QUEUE) { ++ if (hwq_attr->type == HWQ_TYPE_QUEUE) { + /* Find the last pg of the size */ + i = hwq->pbl[PBL_LVL_2].pg_count; + dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |= +@@ -248,25 +299,36 @@ int bnxt_qplib_alloc_init_hwq(struct pci + [PTR_IDX(i - 2)] |= + PTU_PTE_NEXT_TO_LAST; + } +- hwq->level = PBL_LVL_2; +- } else { +- u32 flag = hwq_type == HWQ_TYPE_L2_CMPL ? 0 : +- PTU_PTE_VALID; ++ } else { /* pages < 512 npbl = 1, npde = 0 */ ++ u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ? ++ 0 : PTU_PTE_VALID; + + /* 1 level of indirection */ +- rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_1], sghead, +- pages, maps, pg_size); ++ npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT; ++ if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT)) ++ npbl++; ++ sginfo.npages = npbl; ++ sginfo.pgsize = PAGE_SIZE; ++ /* Alloc PBL page */ ++ rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); + if (rc) + goto fail; +- /* Fill in lvl0 PBL */ ++ /* Alloc or init PTEs */ ++ rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1], ++ hwq_attr->sginfo); ++ if (rc) ++ goto fail; ++ hwq->level = PBL_LVL_1; ++ if (hwq_attr->sginfo->nopte) ++ goto done; ++ /* Fill PBL with PTE pointers */ + dst_virt_ptr = + (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; + src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; +- for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) { ++ for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) + dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = + src_phys_ptr[i] | flag; +- } +- if (hwq_type == HWQ_TYPE_QUEUE) { ++ if (hwq_attr->type == HWQ_TYPE_QUEUE) { + /* Find the last pg of the size */ + i = hwq->pbl[PBL_LVL_1].pg_count; + dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |= +@@ -276,42 +338,141 @@ int bnxt_qplib_alloc_init_hwq(struct pci + [PTR_IDX(i - 2)] |= + PTU_PTE_NEXT_TO_LAST; + } +- hwq->level = PBL_LVL_1; + } + } +- hwq->pdev = pdev; +- spin_lock_init(&hwq->lock); ++done: + hwq->prod = 0; + hwq->cons = 0; +- *elements = hwq->max_elements = slots; +- hwq->element_size = size; +- ++ hwq->pdev = pdev; ++ hwq->depth = hwq_attr->depth; ++ hwq->max_elements = depth; ++ hwq->element_size = stride; + /* For direct access to the elements */ +- hwq->pbl_ptr = hwq->pbl[hwq->level].pg_arr; +- hwq->pbl_dma_ptr = hwq->pbl[hwq->level].pg_map_arr; ++ lvl = hwq->level; ++ if (hwq_attr->sginfo->nopte && hwq->level) ++ lvl = hwq->level - 1; ++ hwq->pbl_ptr = hwq->pbl[lvl].pg_arr; ++ hwq->pbl_dma_ptr = hwq->pbl[lvl].pg_map_arr; ++ spin_lock_init(&hwq->lock); + + return 0; +- + fail: +- bnxt_qplib_free_hwq(pdev, hwq); ++ bnxt_qplib_free_hwq(res, hwq); + return -ENOMEM; + } + + /* Context Tables */ +-void bnxt_qplib_free_ctx(struct pci_dev *pdev, ++void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res, + struct bnxt_qplib_ctx *ctx) + { + int i; + +- bnxt_qplib_free_hwq(pdev, &ctx->qpc_tbl); +- bnxt_qplib_free_hwq(pdev, &ctx->mrw_tbl); +- bnxt_qplib_free_hwq(pdev, &ctx->srqc_tbl); +- bnxt_qplib_free_hwq(pdev, &ctx->cq_tbl); +- bnxt_qplib_free_hwq(pdev, &ctx->tim_tbl); ++ bnxt_qplib_free_hwq(res, &ctx->qpc_tbl); ++ bnxt_qplib_free_hwq(res, &ctx->mrw_tbl); ++ bnxt_qplib_free_hwq(res, &ctx->srqc_tbl); ++ bnxt_qplib_free_hwq(res, &ctx->cq_tbl); ++ bnxt_qplib_free_hwq(res, &ctx->tim_tbl); + for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) +- bnxt_qplib_free_hwq(pdev, &ctx->tqm_tbl[i]); +- bnxt_qplib_free_hwq(pdev, &ctx->tqm_pde); +- bnxt_qplib_free_stats_ctx(pdev, &ctx->stats); ++ bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.qtbl[i]); ++ /* restore original pde level before destroy */ ++ ctx->tqm_ctx.pde.level = ctx->tqm_ctx.pde_level; ++ bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.pde); ++ bnxt_qplib_free_stats_ctx(res->pdev, &ctx->stats); ++} ++ ++static int bnxt_qplib_alloc_tqm_rings(struct bnxt_qplib_res *res, ++ struct bnxt_qplib_ctx *ctx) ++{ ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; ++ struct bnxt_qplib_sg_info sginfo = {}; ++ struct bnxt_qplib_tqm_ctx *tqmctx; ++ int rc = 0; ++ int i; ++ ++ tqmctx = &ctx->tqm_ctx; ++ ++ sginfo.pgsize = PAGE_SIZE; ++ sginfo.pgshft = PAGE_SHIFT; ++ hwq_attr.sginfo = &sginfo; ++ hwq_attr.res = res; ++ hwq_attr.type = HWQ_TYPE_CTX; ++ hwq_attr.depth = 512; ++ hwq_attr.stride = sizeof(u64); ++ /* Alloc pdl buffer */ ++ rc = bnxt_qplib_alloc_init_hwq(&tqmctx->pde, &hwq_attr); ++ if (rc) ++ goto out; ++ /* Save original pdl level */ ++ tqmctx->pde_level = tqmctx->pde.level; ++ ++ hwq_attr.stride = 1; ++ for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) { ++ if (!tqmctx->qcount[i]) ++ continue; ++ hwq_attr.depth = ctx->qpc_count * tqmctx->qcount[i]; ++ rc = bnxt_qplib_alloc_init_hwq(&tqmctx->qtbl[i], &hwq_attr); ++ if (rc) ++ goto out; ++ } ++out: ++ return rc; ++} ++ ++static void bnxt_qplib_map_tqm_pgtbl(struct bnxt_qplib_tqm_ctx *ctx) ++{ ++ struct bnxt_qplib_hwq *tbl; ++ dma_addr_t *dma_ptr; ++ __le64 **pbl_ptr, *ptr; ++ int i, j, k; ++ int fnz_idx = -1; ++ int pg_count; ++ ++ pbl_ptr = (__le64 **)ctx->pde.pbl_ptr; ++ ++ for (i = 0, j = 0; i < MAX_TQM_ALLOC_REQ; ++ i++, j += MAX_TQM_ALLOC_BLK_SIZE) { ++ tbl = &ctx->qtbl[i]; ++ if (!tbl->max_elements) ++ continue; ++ if (fnz_idx == -1) ++ fnz_idx = i; /* first non-zero index */ ++ switch (tbl->level) { ++ case PBL_LVL_2: ++ pg_count = tbl->pbl[PBL_LVL_1].pg_count; ++ for (k = 0; k < pg_count; k++) { ++ ptr = &pbl_ptr[PTR_PG(j + k)][PTR_IDX(j + k)]; ++ dma_ptr = &tbl->pbl[PBL_LVL_1].pg_map_arr[k]; ++ *ptr = cpu_to_le64(*dma_ptr | PTU_PTE_VALID); ++ } ++ break; ++ case PBL_LVL_1: ++ case PBL_LVL_0: ++ default: ++ ptr = &pbl_ptr[PTR_PG(j)][PTR_IDX(j)]; ++ *ptr = cpu_to_le64(tbl->pbl[PBL_LVL_0].pg_map_arr[0] | ++ PTU_PTE_VALID); ++ break; ++ } ++ } ++ if (fnz_idx == -1) ++ fnz_idx = 0; ++ /* update pde level as per page table programming */ ++ ctx->pde.level = (ctx->qtbl[fnz_idx].level == PBL_LVL_2) ? PBL_LVL_2 : ++ ctx->qtbl[fnz_idx].level + 1; ++} ++ ++static int bnxt_qplib_setup_tqm_rings(struct bnxt_qplib_res *res, ++ struct bnxt_qplib_ctx *ctx) ++{ ++ int rc = 0; ++ ++ rc = bnxt_qplib_alloc_tqm_rings(res, ctx); ++ if (rc) ++ goto fail; ++ ++ bnxt_qplib_map_tqm_pgtbl(&ctx->tqm_ctx); ++fail: ++ return rc; + } + + /* +@@ -335,120 +496,72 @@ void bnxt_qplib_free_ctx(struct pci_dev + * Returns: + * 0 if success, else -ERRORS + */ +-int bnxt_qplib_alloc_ctx(struct pci_dev *pdev, ++int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, + struct bnxt_qplib_ctx *ctx, + bool virt_fn, bool is_p5) + { +- int i, j, k, rc = 0; +- int fnz_idx = -1; +- __le64 **pbl_ptr; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; ++ struct bnxt_qplib_sg_info sginfo = {}; ++ int rc = 0; + + if (virt_fn || is_p5) + goto stats_alloc; + + /* QPC Tables */ +- ctx->qpc_tbl.max_elements = ctx->qpc_count; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->qpc_tbl, NULL, +- &ctx->qpc_tbl.max_elements, +- BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_CTX); ++ sginfo.pgsize = PAGE_SIZE; ++ sginfo.pgshft = PAGE_SHIFT; ++ hwq_attr.sginfo = &sginfo; ++ ++ hwq_attr.res = res; ++ hwq_attr.depth = ctx->qpc_count; ++ hwq_attr.stride = BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE; ++ hwq_attr.type = HWQ_TYPE_CTX; ++ rc = bnxt_qplib_alloc_init_hwq(&ctx->qpc_tbl, &hwq_attr); + if (rc) + goto fail; + + /* MRW Tables */ +- ctx->mrw_tbl.max_elements = ctx->mrw_count; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->mrw_tbl, NULL, +- &ctx->mrw_tbl.max_elements, +- BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_CTX); ++ hwq_attr.depth = ctx->mrw_count; ++ hwq_attr.stride = BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE; ++ rc = bnxt_qplib_alloc_init_hwq(&ctx->mrw_tbl, &hwq_attr); + if (rc) + goto fail; + + /* SRQ Tables */ +- ctx->srqc_tbl.max_elements = ctx->srqc_count; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->srqc_tbl, NULL, +- &ctx->srqc_tbl.max_elements, +- BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_CTX); ++ hwq_attr.depth = ctx->srqc_count; ++ hwq_attr.stride = BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE; ++ rc = bnxt_qplib_alloc_init_hwq(&ctx->srqc_tbl, &hwq_attr); + if (rc) + goto fail; + + /* CQ Tables */ +- ctx->cq_tbl.max_elements = ctx->cq_count; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->cq_tbl, NULL, +- &ctx->cq_tbl.max_elements, +- BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_CTX); ++ hwq_attr.depth = ctx->cq_count; ++ hwq_attr.stride = BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE; ++ rc = bnxt_qplib_alloc_init_hwq(&ctx->cq_tbl, &hwq_attr); + if (rc) + goto fail; + + /* TQM Buffer */ +- ctx->tqm_pde.max_elements = 512; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tqm_pde, NULL, +- &ctx->tqm_pde.max_elements, sizeof(u64), +- 0, PAGE_SIZE, HWQ_TYPE_CTX); ++ rc = bnxt_qplib_setup_tqm_rings(res, ctx); + if (rc) + goto fail; +- +- for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) { +- if (!ctx->tqm_count[i]) +- continue; +- ctx->tqm_tbl[i].max_elements = ctx->qpc_count * +- ctx->tqm_count[i]; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tqm_tbl[i], NULL, +- &ctx->tqm_tbl[i].max_elements, 1, +- 0, PAGE_SIZE, HWQ_TYPE_CTX); +- if (rc) +- goto fail; +- } +- pbl_ptr = (__le64 **)ctx->tqm_pde.pbl_ptr; +- for (i = 0, j = 0; i < MAX_TQM_ALLOC_REQ; +- i++, j += MAX_TQM_ALLOC_BLK_SIZE) { +- if (!ctx->tqm_tbl[i].max_elements) +- continue; +- if (fnz_idx == -1) +- fnz_idx = i; +- switch (ctx->tqm_tbl[i].level) { +- case PBL_LVL_2: +- for (k = 0; k < ctx->tqm_tbl[i].pbl[PBL_LVL_1].pg_count; +- k++) +- pbl_ptr[PTR_PG(j + k)][PTR_IDX(j + k)] = +- cpu_to_le64( +- ctx->tqm_tbl[i].pbl[PBL_LVL_1].pg_map_arr[k] +- | PTU_PTE_VALID); +- break; +- case PBL_LVL_1: +- case PBL_LVL_0: +- default: +- pbl_ptr[PTR_PG(j)][PTR_IDX(j)] = cpu_to_le64( +- ctx->tqm_tbl[i].pbl[PBL_LVL_0].pg_map_arr[0] | +- PTU_PTE_VALID); +- break; +- } +- } +- if (fnz_idx == -1) +- fnz_idx = 0; +- ctx->tqm_pde_level = ctx->tqm_tbl[fnz_idx].level == PBL_LVL_2 ? +- PBL_LVL_2 : ctx->tqm_tbl[fnz_idx].level + 1; +- + /* TIM Buffer */ + ctx->tim_tbl.max_elements = ctx->qpc_count * 16; +- rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tim_tbl, NULL, +- &ctx->tim_tbl.max_elements, 1, +- 0, PAGE_SIZE, HWQ_TYPE_CTX); ++ hwq_attr.depth = ctx->qpc_count * 16; ++ hwq_attr.stride = 1; ++ rc = bnxt_qplib_alloc_init_hwq(&ctx->tim_tbl, &hwq_attr); + if (rc) + goto fail; +- + stats_alloc: + /* Stats */ +- rc = bnxt_qplib_alloc_stats_ctx(pdev, &ctx->stats); ++ rc = bnxt_qplib_alloc_stats_ctx(res->pdev, &ctx->stats); + if (rc) + goto fail; + + return 0; + + fail: +- bnxt_qplib_free_ctx(pdev, ctx); ++ bnxt_qplib_free_ctx(res, ctx); + return rc; + } + +@@ -808,9 +921,6 @@ void bnxt_qplib_free_res(struct bnxt_qpl + bnxt_qplib_free_sgid_tbl(res, &res->sgid_tbl); + bnxt_qplib_free_pd_tbl(&res->pd_tbl); + bnxt_qplib_free_dpi_tbl(res, &res->dpi_tbl); +- +- res->netdev = NULL; +- res->pdev = NULL; + } + + int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev, +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h +@@ -55,7 +55,8 @@ extern const struct bnxt_qplib_gid bnxt_ + enum bnxt_qplib_hwq_type { + HWQ_TYPE_CTX, + HWQ_TYPE_QUEUE, +- HWQ_TYPE_L2_CMPL ++ HWQ_TYPE_L2_CMPL, ++ HWQ_TYPE_MR + }; + + #define MAX_PBL_LVL_0_PGS 1 +@@ -63,6 +64,7 @@ enum bnxt_qplib_hwq_type { + #define MAX_PBL_LVL_1_PGS_SHIFT 9 + #define MAX_PBL_LVL_1_PGS_FOR_LVL_2 256 + #define MAX_PBL_LVL_2_PGS (256 * 512) ++#define MAX_PDL_LVL_SHIFT 9 + + enum bnxt_qplib_pbl_lvl { + PBL_LVL_0, +@@ -85,17 +87,37 @@ struct bnxt_qplib_pbl { + dma_addr_t *pg_map_arr; + }; + ++struct bnxt_qplib_sg_info { ++ struct scatterlist *sghead; ++ u32 nmap; ++ u32 npages; ++ u32 pgshft; ++ u32 pgsize; ++ bool nopte; ++}; ++ ++struct bnxt_qplib_hwq_attr { ++ struct bnxt_qplib_res *res; ++ struct bnxt_qplib_sg_info *sginfo; ++ enum bnxt_qplib_hwq_type type; ++ u32 depth; ++ u32 stride; ++ u32 aux_stride; ++ u32 aux_depth; ++}; ++ + struct bnxt_qplib_hwq { + struct pci_dev *pdev; + /* lock to protect qplib_hwq */ + spinlock_t lock; +- struct bnxt_qplib_pbl pbl[PBL_LVL_MAX]; ++ struct bnxt_qplib_pbl pbl[PBL_LVL_MAX + 1]; + enum bnxt_qplib_pbl_lvl level; /* 0, 1, or 2 */ + /* ptr for easy access to the PBL entries */ + void **pbl_ptr; + /* ptr for easy access to the dma_addr */ + dma_addr_t *pbl_dma_ptr; + u32 max_elements; ++ u32 depth; + u16 element_size; /* Size of each entry */ + + u32 prod; /* raw */ +@@ -159,6 +181,15 @@ struct bnxt_qplib_vf_res { + #define BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE 64 + #define BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE 128 + ++#define MAX_TQM_ALLOC_REQ 48 ++#define MAX_TQM_ALLOC_BLK_SIZE 8 ++struct bnxt_qplib_tqm_ctx { ++ struct bnxt_qplib_hwq pde; ++ u8 pde_level; /* Original level */ ++ struct bnxt_qplib_hwq qtbl[MAX_TQM_ALLOC_REQ]; ++ u8 qcount[MAX_TQM_ALLOC_REQ]; ++}; ++ + struct bnxt_qplib_ctx { + u32 qpc_count; + struct bnxt_qplib_hwq qpc_tbl; +@@ -169,12 +200,7 @@ struct bnxt_qplib_ctx { + u32 cq_count; + struct bnxt_qplib_hwq cq_tbl; + struct bnxt_qplib_hwq tim_tbl; +-#define MAX_TQM_ALLOC_REQ 48 +-#define MAX_TQM_ALLOC_BLK_SIZE 8 +- u8 tqm_count[MAX_TQM_ALLOC_REQ]; +- struct bnxt_qplib_hwq tqm_pde; +- u32 tqm_pde_level; +- struct bnxt_qplib_hwq tqm_tbl[MAX_TQM_ALLOC_REQ]; ++ struct bnxt_qplib_tqm_ctx tqm_ctx; + struct bnxt_qplib_stats stats; + struct bnxt_qplib_vf_res vf_res; + u64 hwrm_intf_ver; +@@ -223,11 +249,6 @@ static inline u8 bnxt_qplib_get_ring_typ + RING_ALLOC_REQ_RING_TYPE_ROCE_CMPL; + } + +-struct bnxt_qplib_sg_info { +- struct scatterlist *sglist; +- u32 nmap; +- u32 npages; +-}; + + #define to_bnxt_qplib(ptr, type, member) \ + container_of(ptr, type, member) +@@ -235,11 +256,10 @@ struct bnxt_qplib_sg_info { + struct bnxt_qplib_pd; + struct bnxt_qplib_dev_attr; + +-void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq); +-int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq, +- struct bnxt_qplib_sg_info *sg_info, u32 *elements, +- u32 elements_per_page, u32 aux, u32 pg_size, +- enum bnxt_qplib_hwq_type hwq_type); ++void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res, ++ struct bnxt_qplib_hwq *hwq); ++int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, ++ struct bnxt_qplib_hwq_attr *hwq_attr); + void bnxt_qplib_get_guid(u8 *dev_addr, u8 *guid); + int bnxt_qplib_alloc_pd(struct bnxt_qplib_pd_tbl *pd_tbl, + struct bnxt_qplib_pd *pd); +@@ -258,9 +278,9 @@ void bnxt_qplib_free_res(struct bnxt_qpl + int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev, + struct net_device *netdev, + struct bnxt_qplib_dev_attr *dev_attr); +-void bnxt_qplib_free_ctx(struct pci_dev *pdev, ++void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res, + struct bnxt_qplib_ctx *ctx); +-int bnxt_qplib_alloc_ctx(struct pci_dev *pdev, ++int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, + struct bnxt_qplib_ctx *ctx, + bool virt_fn, bool is_p5); + #endif /* __BNXT_QPLIB_RES_H__ */ +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -585,7 +585,7 @@ int bnxt_qplib_free_mrw(struct bnxt_qpli + + /* Free the qplib's MRW memory */ + if (mrw->hwq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &mrw->hwq); ++ bnxt_qplib_free_hwq(res, &mrw->hwq); + + return 0; + } +@@ -646,7 +646,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qpl + if (mrw->hwq.max_elements) { + mrw->va = 0; + mrw->total_size = 0; +- bnxt_qplib_free_hwq(res->pdev, &mrw->hwq); ++ bnxt_qplib_free_hwq(res, &mrw->hwq); + } + + return 0; +@@ -656,10 +656,12 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_ + u64 *pbl_tbl, int num_pbls, bool block, u32 buf_pg_size) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; +- struct cmdq_register_mr req; ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; ++ struct bnxt_qplib_sg_info sginfo = {}; + struct creq_register_mr_resp resp; +- u16 cmd_flags = 0, level; ++ struct cmdq_register_mr req; + int pg_ptrs, pages, i, rc; ++ u16 cmd_flags = 0, level; + dma_addr_t **pbl_ptr; + u32 pg_size; + +@@ -674,20 +676,23 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_ + + if (pages > MAX_PBL_LVL_1_PGS) { + dev_err(&res->pdev->dev, +- "SP: Reg MR pages requested (0x%x) exceeded max (0x%x)\n", ++ "SP: Reg MR: pages requested (0x%x) exceeded max (0x%x)\n", + pages, MAX_PBL_LVL_1_PGS); + return -ENOMEM; + } + /* Free the hwq if it already exist, must be a rereg */ + if (mr->hwq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &mr->hwq); +- +- mr->hwq.max_elements = pages; ++ bnxt_qplib_free_hwq(res, &mr->hwq); + /* Use system PAGE_SIZE */ +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL, +- &mr->hwq.max_elements, +- PAGE_SIZE, 0, PAGE_SIZE, +- HWQ_TYPE_CTX); ++ hwq_attr.res = res; ++ hwq_attr.depth = pages; ++ hwq_attr.stride = PAGE_SIZE; ++ hwq_attr.type = HWQ_TYPE_MR; ++ hwq_attr.sginfo = &sginfo; ++ hwq_attr.sginfo->npages = pages; ++ hwq_attr.sginfo->pgsize = PAGE_SIZE; ++ hwq_attr.sginfo->pgshft = PAGE_SHIFT; ++ rc = bnxt_qplib_alloc_init_hwq(&mr->hwq, &hwq_attr); + if (rc) { + dev_err(&res->pdev->dev, + "SP: Reg MR memory allocation failed\n"); +@@ -734,7 +739,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_ + + fail: + if (mr->hwq.max_elements) +- bnxt_qplib_free_hwq(res->pdev, &mr->hwq); ++ bnxt_qplib_free_hwq(res, &mr->hwq); + return rc; + } + +@@ -742,6 +747,8 @@ int bnxt_qplib_alloc_fast_reg_page_list( + struct bnxt_qplib_frpl *frpl, + int max_pg_ptrs) + { ++ struct bnxt_qplib_hwq_attr hwq_attr = {}; ++ struct bnxt_qplib_sg_info sginfo = {}; + int pg_ptrs, pages, rc; + + /* Re-calculate the max to fit the HWQ allocation model */ +@@ -753,10 +760,15 @@ int bnxt_qplib_alloc_fast_reg_page_list( + if (pages > MAX_PBL_LVL_1_PGS) + return -ENOMEM; + +- frpl->hwq.max_elements = pages; +- rc = bnxt_qplib_alloc_init_hwq(res->pdev, &frpl->hwq, NULL, +- &frpl->hwq.max_elements, PAGE_SIZE, 0, +- PAGE_SIZE, HWQ_TYPE_CTX); ++ sginfo.pgsize = PAGE_SIZE; ++ sginfo.nopte = true; ++ ++ hwq_attr.res = res; ++ hwq_attr.depth = pg_ptrs; ++ hwq_attr.stride = PAGE_SIZE; ++ hwq_attr.sginfo = &sginfo; ++ hwq_attr.type = HWQ_TYPE_CTX; ++ rc = bnxt_qplib_alloc_init_hwq(&frpl->hwq, &hwq_attr); + if (!rc) + frpl->max_pg_ptrs = pg_ptrs; + +@@ -766,7 +778,7 @@ int bnxt_qplib_alloc_fast_reg_page_list( + int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res, + struct bnxt_qplib_frpl *frpl) + { +- bnxt_qplib_free_hwq(res->pdev, &frpl->hwq); ++ bnxt_qplib_free_hwq(res, &frpl->hwq); + return 0; + } + diff --git a/patches.suse/RDMA-bnxt_re-Refactor-net-ring-allocation-function.patch b/patches.suse/RDMA-bnxt_re-Refactor-net-ring-allocation-function.patch new file mode 100644 index 0000000..27af669 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-net-ring-allocation-function.patch @@ -0,0 +1,174 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:11:01 -0500 +Subject: RDMA/bnxt_re: Refactor net ring allocation function +Patch-mainline: v5.7-rc1 +Git-commit: b08fe048a69d8cb4c497b91c965fff754d3369f9 +References: bsc#1170774 + +Introducing a new attribute structure to reduce the long list of arguments +passed in bnxt_re_net_ring_alloc() function. + +The caller of bnxt_re_net_ring_alloc should fill in the list of attributes +in bnxt_re_ring_attr structure and then pass the pointer to the function. + +Link: https://lore.kernel.org/r/1581786665-23705-5-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Naresh Kumar PBS +Signed-off-by: Selvin Xavier +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 9 ++++ + drivers/infiniband/hw/bnxt_re/main.c | 64 +++++++++++++++++--------------- + 2 files changed, 44 insertions(+), 29 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -89,6 +89,15 @@ + + #define BNXT_RE_DEFAULT_ACK_DELAY 16 + ++struct bnxt_re_ring_attr { ++ dma_addr_t *dma_arr; ++ int pages; ++ int type; ++ u32 depth; ++ u32 lrid; /* Logical ring id */ ++ u8 mode; ++}; ++ + struct bnxt_re_work { + struct work_struct work; + unsigned long event; +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -427,9 +427,9 @@ static int bnxt_re_net_ring_free(struct + return rc; + } + +-static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr, +- int pages, int type, u32 ring_mask, +- u32 map_index, u16 *fw_ring_id) ++static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, ++ struct bnxt_re_ring_attr *ring_attr, ++ u16 *fw_ring_id) + { + struct bnxt_en_dev *en_dev = rdev->en_dev; + struct hwrm_ring_alloc_input req = {0}; +@@ -443,18 +443,18 @@ static int bnxt_re_net_ring_alloc(struct + memset(&fw_msg, 0, sizeof(fw_msg)); + bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1); + req.enables = 0; +- req.page_tbl_addr = cpu_to_le64(dma_arr[0]); +- if (pages > 1) { ++ req.page_tbl_addr = cpu_to_le64(ring_attr->dma_arr[0]); ++ if (ring_attr->pages > 1) { + /* Page size is in log2 units */ + req.page_size = BNXT_PAGE_SHIFT; + req.page_tbl_depth = 1; + } + req.fbo = 0; + /* Association of ring index with doorbell index and MSIX number */ +- req.logical_id = cpu_to_le16(map_index); +- req.length = cpu_to_le32(ring_mask + 1); +- req.ring_type = type; +- req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX; ++ req.logical_id = cpu_to_le16(ring_attr->lrid); ++ req.length = cpu_to_le32(ring_attr->depth + 1); ++ req.ring_type = ring_attr->type; ++ req.int_mode = ring_attr->mode; + bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, + sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); + rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); +@@ -1006,10 +1006,10 @@ static void bnxt_re_free_res(struct bnxt + + static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev) + { ++ struct bnxt_re_ring_attr rattr = {}; ++ struct bnxt_qplib_ctx *qplib_ctx; + int num_vec_created = 0; +- dma_addr_t *pg_map; + int rc = 0, i; +- int pages; + u8 type; + + /* Configure and allocate resources for qplib */ +@@ -1030,10 +1030,13 @@ static int bnxt_re_alloc_res(struct bnxt + if (rc) + goto dealloc_res; + ++ qplib_ctx = &rdev->qplib_ctx; + for (i = 0; i < rdev->num_msix - 1; i++) { +- rdev->nq[i].res = &rdev->qplib_res; +- rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT + +- BNXT_RE_MAX_SRQC_COUNT + 2; ++ struct bnxt_qplib_nq *nq; ++ ++ nq = &rdev->nq[i]; ++ nq->hwq.max_elements = (qplib_ctx->cq_count + ++ qplib_ctx->srqc_count + 2); + rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]); + if (rc) { + dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x", +@@ -1041,12 +1044,13 @@ static int bnxt_re_alloc_res(struct bnxt + goto free_nq; + } + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); +- pg_map = rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr; +- pages = rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count; +- rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type, +- BNXT_QPLIB_NQE_MAX_CNT - 1, +- rdev->msix_entries[i + 1].ring_idx, +- &rdev->nq[i].ring_id); ++ rattr.dma_arr = nq->hwq.pbl[PBL_LVL_0].pg_map_arr; ++ rattr.pages = nq->hwq.pbl[rdev->nq[i].hwq.level].pg_count; ++ rattr.type = type; ++ rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX; ++ rattr.depth = BNXT_QPLIB_NQE_MAX_CNT - 1; ++ rattr.lrid = rdev->msix_entries[i + 1].ring_idx; ++ rc = bnxt_re_net_ring_alloc(rdev, &rattr, &nq->ring_id); + if (rc) { + dev_err(rdev_to_dev(rdev), + "Failed to allocate NQ fw id with rc = 0x%x", +@@ -1371,10 +1375,10 @@ static void bnxt_re_worker(struct work_s + + static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) + { +- dma_addr_t *pg_map; +- u32 db_offt, ridx; +- int pages, vid; ++ struct bnxt_re_ring_attr rattr; ++ u32 db_offt; + bool locked; ++ int vid; + u8 type; + int rc; + +@@ -1383,6 +1387,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + locked = true; + + /* Registered a new RoCE device instance to netdev */ ++ memset(&rattr, 0, sizeof(rattr)); + rc = bnxt_re_register_netdev(rdev); + if (rc) { + rtnl_unlock(); +@@ -1422,12 +1427,13 @@ static int bnxt_re_ib_reg(struct bnxt_re + } + + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); +- pg_map = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr; +- pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count; +- ridx = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; +- rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type, +- BNXT_QPLIB_CREQE_MAX_CNT - 1, +- ridx, &rdev->rcfw.creq_ring_id); ++ rattr.dma_arr = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr; ++ rattr.pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count; ++ rattr.type = type; ++ rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX; ++ rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1; ++ rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; ++ rc = bnxt_re_net_ring_alloc(rdev, &rattr, &rdev->rcfw.creq_ring_id); + if (rc) { + pr_err("Failed to allocate CREQ: %#x\n", rc); + goto free_rcfw; diff --git a/patches.suse/RDMA-bnxt_re-Refactor-notification-queue-management-.patch b/patches.suse/RDMA-bnxt_re-Refactor-notification-queue-management-.patch new file mode 100644 index 0000000..2dd6a13 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-notification-queue-management-.patch @@ -0,0 +1,298 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:11:03 -0500 +Subject: RDMA/bnxt_re: Refactor notification queue management code +Patch-mainline: v5.7-rc1 +Git-commit: 9555352bacfdfc68a972d5bf8a08849183b9e607 +References: bsc#1170774 + +Cleaning up the notification queue data structures and management +code. The CQ and SRQ event handlers have been type defined instead of +in-place declaration. NQ doorbell register descriptor has been added in +base NQ structure. The nq->vector has been renamed to nq->msix_vec. + +Link: https://lore.kernel.org/r/1581786665-23705-7-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 114 ++++++++++++++++++------------- + drivers/infiniband/hw/bnxt_re/qplib_fp.h | 54 +++++++------- + 2 files changed, 94 insertions(+), 74 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -236,16 +236,16 @@ fail: + static void bnxt_qplib_service_nq(unsigned long data) + { + struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data; ++ bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); + struct bnxt_qplib_hwq *hwq = &nq->hwq; + struct nq_base *nqe, **nq_ptr; + struct bnxt_qplib_cq *cq; + int num_cqne_processed = 0; + int num_srqne_processed = 0; +- u32 sw_cons, raw_cons; +- u16 type; + int budget = nq->budget; ++ u32 sw_cons, raw_cons; + uintptr_t q_handle; +- bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); ++ u16 type; + + /* Service the NQ until empty */ + raw_cons = hwq->cons; +@@ -314,7 +314,7 @@ static void bnxt_qplib_service_nq(unsign + } + if (hwq->cons != raw_cons) { + hwq->cons = raw_cons; +- bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, hwq->cons, ++ bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, hwq->cons, + hwq->max_elements, nq->ring_id, + gen_p5); + } +@@ -333,7 +333,7 @@ static irqreturn_t bnxt_qplib_nq_irq(int + prefetch(&nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]); + + /* Fan out to CPU affinitized kthreads? */ +- tasklet_schedule(&nq->worker); ++ tasklet_schedule(&nq->nq_tasklet); + + return IRQ_HANDLED; + } +@@ -341,17 +341,17 @@ static irqreturn_t bnxt_qplib_nq_irq(int + void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) + { + bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); +- tasklet_disable(&nq->worker); ++ tasklet_disable(&nq->nq_tasklet); + /* Mask h/w interrupt */ +- bnxt_qplib_ring_nq_db(nq->bar_reg_iomem, nq->hwq.cons, ++ bnxt_qplib_ring_nq_db(nq->nq_db.db, nq->hwq.cons, + nq->hwq.max_elements, nq->ring_id, gen_p5); + /* Sync with last running IRQ handler */ +- synchronize_irq(nq->vector); ++ synchronize_irq(nq->msix_vec); + if (kill) +- tasklet_kill(&nq->worker); ++ tasklet_kill(&nq->nq_tasklet); + if (nq->requested) { +- irq_set_affinity_hint(nq->vector, NULL); +- free_irq(nq->vector, nq); ++ irq_set_affinity_hint(nq->msix_vec, NULL); ++ free_irq(nq->msix_vec, nq); + nq->requested = false; + } + } +@@ -364,16 +364,17 @@ void bnxt_qplib_disable_nq(struct bnxt_q + } + + /* Make sure the HW is stopped! */ +- if (nq->requested) +- bnxt_qplib_nq_stop_irq(nq, true); ++ bnxt_qplib_nq_stop_irq(nq, true); + +- if (nq->bar_reg_iomem) +- iounmap(nq->bar_reg_iomem); +- nq->bar_reg_iomem = NULL; ++ if (nq->nq_db.reg.bar_reg) { ++ iounmap(nq->nq_db.reg.bar_reg); ++ nq->nq_db.reg.bar_reg = NULL; ++ nq->nq_db.db = NULL; ++ } + + nq->cqn_handler = NULL; + nq->srqn_handler = NULL; +- nq->vector = 0; ++ nq->msix_vec = 0; + } + + int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, +@@ -385,68 +386,87 @@ int bnxt_qplib_nq_start_irq(struct bnxt_ + if (nq->requested) + return -EFAULT; + +- nq->vector = msix_vector; ++ nq->msix_vec = msix_vector; + if (need_init) +- tasklet_init(&nq->worker, bnxt_qplib_service_nq, ++ tasklet_init(&nq->nq_tasklet, bnxt_qplib_service_nq, + (unsigned long)nq); + else +- tasklet_enable(&nq->worker); ++ tasklet_enable(&nq->nq_tasklet); + + snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx); +- rc = request_irq(nq->vector, bnxt_qplib_nq_irq, 0, nq->name, nq); ++ rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq); + if (rc) + return rc; + + cpumask_clear(&nq->mask); + cpumask_set_cpu(nq_indx, &nq->mask); +- rc = irq_set_affinity_hint(nq->vector, &nq->mask); ++ rc = irq_set_affinity_hint(nq->msix_vec, &nq->mask); + if (rc) { + dev_warn(&nq->pdev->dev, + "set affinity failed; vector: %d nq_idx: %d\n", +- nq->vector, nq_indx); ++ nq->msix_vec, nq_indx); + } + nq->requested = true; +- bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, nq->hwq.cons, ++ bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, nq->hwq.cons, + nq->hwq.max_elements, nq->ring_id, gen_p5); + + return rc; + } + ++static int bnxt_qplib_map_nq_db(struct bnxt_qplib_nq *nq, u32 reg_offt) ++{ ++ resource_size_t reg_base; ++ struct bnxt_qplib_nq_db *nq_db; ++ struct pci_dev *pdev; ++ int rc = 0; ++ ++ pdev = nq->pdev; ++ nq_db = &nq->nq_db; ++ ++ nq_db->reg.bar_id = NQ_CONS_PCI_BAR_REGION; ++ nq_db->reg.bar_base = pci_resource_start(pdev, nq_db->reg.bar_id); ++ if (!nq_db->reg.bar_base) { ++ dev_err(&pdev->dev, "QPLIB: NQ BAR region %d resc start is 0!", ++ nq_db->reg.bar_id); ++ rc = -ENOMEM; ++ goto fail; ++ } ++ ++ reg_base = nq_db->reg.bar_base + reg_offt; ++ /* Unconditionally map 8 bytes to support 57500 series */ ++ nq_db->reg.len = 8; ++ nq_db->reg.bar_reg = ioremap(reg_base, nq_db->reg.len); ++ if (!nq_db->reg.bar_reg) { ++ dev_err(&pdev->dev, "QPLIB: NQ BAR region %d mapping failed", ++ nq_db->reg.bar_id); ++ rc = -ENOMEM; ++ goto fail; ++ } ++ ++ nq_db->db = nq_db->reg.bar_reg; ++fail: ++ return rc; ++} ++ + int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, + int nq_idx, int msix_vector, int bar_reg_offset, +- int (*cqn_handler)(struct bnxt_qplib_nq *nq, +- struct bnxt_qplib_cq *), +- int (*srqn_handler)(struct bnxt_qplib_nq *nq, +- struct bnxt_qplib_srq *, +- u8 event)) ++ cqn_handler_t cqn_handler, ++ srqn_handler_t srqn_handler) + { +- resource_size_t nq_base; + int rc = -1; + +- if (cqn_handler) +- nq->cqn_handler = cqn_handler; +- +- if (srqn_handler) +- nq->srqn_handler = srqn_handler; ++ nq->pdev = pdev; ++ nq->cqn_handler = cqn_handler; ++ nq->srqn_handler = srqn_handler; + + /* Have a task to schedule CQ notifiers in post send case */ + nq->cqn_wq = create_singlethread_workqueue("bnxt_qplib_nq"); + if (!nq->cqn_wq) + return -ENOMEM; + +- nq->bar_reg = NQ_CONS_PCI_BAR_REGION; +- nq->bar_reg_off = bar_reg_offset; +- nq_base = pci_resource_start(pdev, nq->bar_reg); +- if (!nq_base) { +- rc = -ENOMEM; +- goto fail; +- } +- /* Unconditionally map 8 bytes to support 57500 series */ +- nq->bar_reg_iomem = ioremap_nocache(nq_base + nq->bar_reg_off, 8); +- if (!nq->bar_reg_iomem) { +- rc = -ENOMEM; ++ rc = bnxt_qplib_map_nq_db(nq, bar_reg_offset); ++ if (rc) + goto fail; +- } + + rc = bnxt_qplib_nq_start_irq(nq, nq_idx, msix_vector, true); + if (rc) { +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -470,29 +470,32 @@ static inline void bnxt_qplib_ring_nq_db + writel(NQ_DB_CP_FLAGS | (index & DBC_DBC32_XID_MASK), db); + } + +-struct bnxt_qplib_nq { +- struct pci_dev *pdev; +- struct bnxt_qplib_res *res; ++struct bnxt_qplib_nq_db { ++ struct bnxt_qplib_reg_desc reg; ++ void __iomem *db; ++}; + +- int vector; +- cpumask_t mask; +- int budget; +- bool requested; +- struct tasklet_struct worker; +- struct bnxt_qplib_hwq hwq; +- +- u16 bar_reg; +- u32 bar_reg_off; +- u16 ring_id; +- void __iomem *bar_reg_iomem; +- +- int (*cqn_handler)(struct bnxt_qplib_nq *nq, +- struct bnxt_qplib_cq *cq); +- int (*srqn_handler)(struct bnxt_qplib_nq *nq, +- struct bnxt_qplib_srq *srq, +- u8 event); +- struct workqueue_struct *cqn_wq; +- char name[32]; ++typedef int (*cqn_handler_t)(struct bnxt_qplib_nq *nq, ++ struct bnxt_qplib_cq *cq); ++typedef int (*srqn_handler_t)(struct bnxt_qplib_nq *nq, ++ struct bnxt_qplib_srq *srq, u8 event); ++ ++struct bnxt_qplib_nq { ++ struct pci_dev *pdev; ++ struct bnxt_qplib_res *res; ++ char name[32]; ++ struct bnxt_qplib_hwq hwq; ++ struct bnxt_qplib_nq_db nq_db; ++ u16 ring_id; ++ int msix_vec; ++ cpumask_t mask; ++ struct tasklet_struct nq_tasklet; ++ bool requested; ++ int budget; ++ ++ cqn_handler_t cqn_handler; ++ srqn_handler_t srqn_handler; ++ struct workqueue_struct *cqn_wq; + }; + + struct bnxt_qplib_nq_work { +@@ -507,11 +510,8 @@ int bnxt_qplib_nq_start_irq(struct bnxt_ + int msix_vector, bool need_init); + int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, + int nq_idx, int msix_vector, int bar_reg_offset, +- int (*cqn_handler)(struct bnxt_qplib_nq *nq, +- struct bnxt_qplib_cq *cq), +- int (*srqn_handler)(struct bnxt_qplib_nq *nq, +- struct bnxt_qplib_srq *srq, +- u8 event)); ++ cqn_handler_t cqn_handler, ++ srqn_handler_t srq_handler); + int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, + struct bnxt_qplib_srq *srq); + int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res, diff --git a/patches.suse/RDMA-bnxt_re-Refactor-queue-pair-creation-code.patch b/patches.suse/RDMA-bnxt_re-Refactor-queue-pair-creation-code.patch new file mode 100644 index 0000000..1fe3cec --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Refactor-queue-pair-creation-code.patch @@ -0,0 +1,926 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:10:58 -0500 +Subject: RDMA/bnxt_re: Refactor queue pair creation code +Patch-mainline: v5.7-rc1 +Git-commit: 8dae419f9ec730c1984ea7395067a2534780ada1 +References: bsc#1170774 + +Restructuring the bnxt_re_create_qp function. Listing below the major +changes: + - Monolithic central part of create_qp where attributes are initialized + is now enclosed in one function and this new function has few more + sub-functions. + - Top level qp limit checking code moved to a function. + - GSI QP creation and GSI Shadow qp creation code is handled in a sub + function. + +Link: https://lore.kernel.org/r/1581786665-23705-2-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Naresh Kumar PBS +Signed-off-by: Selvin Xavier +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 13 + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 633 ++++++++++++++++++++----------- + drivers/infiniband/hw/bnxt_re/main.c | 3 + 3 files changed, 430 insertions(+), 219 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -104,6 +104,14 @@ struct bnxt_re_sqp_entries { + struct bnxt_re_qp *qp1_qp; + }; + ++#define BNXT_RE_MAX_GSI_SQP_ENTRIES 1024 ++struct bnxt_re_gsi_context { ++ struct bnxt_re_qp *gsi_qp; ++ struct bnxt_re_qp *gsi_sqp; ++ struct bnxt_re_ah *gsi_sah; ++ struct bnxt_re_sqp_entries *sqp_tbl; ++}; ++ + #define BNXT_RE_MIN_MSIX 2 + #define BNXT_RE_MAX_MSIX 9 + #define BNXT_RE_AEQ_IDX 0 +@@ -165,10 +173,7 @@ struct bnxt_re_dev { + u16 cosq[2]; + + /* QP for for handling QP1 packets */ +- u32 sqp_id; +- struct bnxt_re_qp *qp1_sqp; +- struct bnxt_re_ah *sqp_ah; +- struct bnxt_re_sqp_entries sqp_tbl[1024]; ++ struct bnxt_re_gsi_context gsi_ctx; + atomic_t nq_alloc_cnt; + u32 is_virtfn; + u32 num_vfs; +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -312,7 +312,7 @@ int bnxt_re_del_gid(const struct ib_gid_ + */ + if (ctx->idx == 0 && + rdma_link_local_addr((struct in6_addr *)gid_to_del) && +- ctx->refcnt == 1 && rdev->qp1_sqp) { ++ ctx->refcnt == 1 && rdev->gsi_ctx.gsi_sqp) { + dev_dbg(rdev_to_dev(rdev), + "Trying to delete GID0 while QP1 is alive\n"); + return -EFAULT; +@@ -742,6 +742,49 @@ void bnxt_re_unlock_cqs(struct bnxt_re_q + spin_unlock_irqrestore(&qp->scq->cq_lock, flags); + } + ++static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) ++{ ++ struct bnxt_re_qp *gsi_sqp; ++ struct bnxt_re_ah *gsi_sah; ++ struct bnxt_re_dev *rdev; ++ int rc = 0; ++ ++ rdev = qp->rdev; ++ gsi_sqp = rdev->gsi_ctx.gsi_sqp; ++ gsi_sah = rdev->gsi_ctx.gsi_sah; ++ ++ /* remove from active qp list */ ++ mutex_lock(&rdev->qp_lock); ++ list_del(&gsi_sqp->list); ++ mutex_unlock(&rdev->qp_lock); ++ atomic_dec(&rdev->qp_count); ++ ++ dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n"); ++ bnxt_qplib_destroy_ah(&rdev->qplib_res, ++ &gsi_sah->qplib_ah, ++ true); ++ bnxt_qplib_clean_qp(&qp->qplib_qp); ++ ++ dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n"); ++ rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp); ++ if (rc) { ++ dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed"); ++ goto fail; ++ } ++ bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp); ++ ++ kfree(rdev->gsi_ctx.sqp_tbl); ++ kfree(gsi_sah); ++ kfree(gsi_sqp); ++ rdev->gsi_ctx.gsi_sqp = NULL; ++ rdev->gsi_ctx.gsi_sah = NULL; ++ rdev->gsi_ctx.sqp_tbl = NULL; ++ ++ return 0; ++fail: ++ return rc; ++} ++ + /* Queue Pairs */ + int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) + { +@@ -750,7 +793,13 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_ + unsigned int flags; + int rc; + ++ mutex_lock(&rdev->qp_lock); ++ list_del(&qp->list); ++ mutex_unlock(&rdev->qp_lock); ++ atomic_dec(&rdev->qp_count); ++ + bnxt_qplib_flush_cqn_wq(&qp->qplib_qp); ++ + rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { + dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP"); +@@ -765,40 +814,19 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_ + + bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp); + +- if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) { +- bnxt_qplib_destroy_ah(&rdev->qplib_res, &rdev->sqp_ah->qplib_ah, +- false); +- +- bnxt_qplib_clean_qp(&qp->qplib_qp); +- rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, +- &rdev->qp1_sqp->qplib_qp); +- if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to destroy Shadow QP"); +- return rc; +- } +- bnxt_qplib_free_qp_res(&rdev->qplib_res, +- &rdev->qp1_sqp->qplib_qp); +- mutex_lock(&rdev->qp_lock); +- list_del(&rdev->qp1_sqp->list); +- atomic_dec(&rdev->qp_count); +- mutex_unlock(&rdev->qp_lock); +- +- kfree(rdev->sqp_ah); +- kfree(rdev->qp1_sqp); +- rdev->qp1_sqp = NULL; +- rdev->sqp_ah = NULL; ++ if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) { ++ rc = bnxt_re_destroy_gsi_sqp(qp); ++ if (rc) ++ goto sh_fail; + } + + ib_umem_release(qp->rumem); + ib_umem_release(qp->sumem); + +- mutex_lock(&rdev->qp_lock); +- list_del(&qp->list); +- atomic_dec(&rdev->qp_count); +- mutex_unlock(&rdev->qp_lock); + kfree(qp); + return 0; ++sh_fail: ++ return rc; + } + + static u8 __from_ib_qp_type(enum ib_qp_type type) +@@ -966,8 +994,6 @@ static struct bnxt_re_qp *bnxt_re_create + if (rc) + goto fail; + +- rdev->sqp_id = qp->qplib_qp.id; +- + spin_lock_init(&qp->sq_lock); + INIT_LIST_HEAD(&qp->list); + mutex_lock(&rdev->qp_lock); +@@ -980,205 +1006,377 @@ fail: + return NULL; + } + +-struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, +- struct ib_qp_init_attr *qp_init_attr, +- struct ib_udata *udata) ++static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp, ++ struct ib_qp_init_attr *init_attr) + { +- struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); +- struct bnxt_re_dev *rdev = pd->rdev; +- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; +- struct bnxt_re_qp *qp; +- struct bnxt_re_cq *cq; +- struct bnxt_re_srq *srq; +- int rc, entries; ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ int entries; + +- if ((qp_init_attr->cap.max_send_wr > dev_attr->max_qp_wqes) || +- (qp_init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes) || +- (qp_init_attr->cap.max_send_sge > dev_attr->max_qp_sges) || +- (qp_init_attr->cap.max_recv_sge > dev_attr->max_qp_sges) || +- (qp_init_attr->cap.max_inline_data > dev_attr->max_inline_data)) +- return ERR_PTR(-EINVAL); ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; + +- qp = kzalloc(sizeof(*qp), GFP_KERNEL); +- if (!qp) +- return ERR_PTR(-ENOMEM); ++ if (init_attr->srq) { ++ struct bnxt_re_srq *srq; + +- qp->rdev = rdev; +- ether_addr_copy(qp->qplib_qp.smac, rdev->netdev->dev_addr); +- qp->qplib_qp.pd = &pd->qplib_pd; +- qp->qplib_qp.qp_handle = (u64)(unsigned long)(&qp->qplib_qp); +- qp->qplib_qp.type = __from_ib_qp_type(qp_init_attr->qp_type); ++ srq = container_of(init_attr->srq, struct bnxt_re_srq, ib_srq); ++ if (!srq) { ++ dev_err(rdev_to_dev(rdev), "SRQ not found"); ++ return -EINVAL; ++ } ++ qplqp->srq = &srq->qplib_srq; ++ qplqp->rq.max_wqe = 0; ++ } else { ++ /* Allocate 1 more than what's provided so posting max doesn't ++ * mean empty. ++ */ ++ entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1); ++ qplqp->rq.max_wqe = min_t(u32, entries, ++ dev_attr->max_qp_wqes + 1); ++ ++ qplqp->rq.q_full_delta = qplqp->rq.max_wqe - ++ init_attr->cap.max_recv_wr; ++ qplqp->rq.max_sge = init_attr->cap.max_recv_sge; ++ if (qplqp->rq.max_sge > dev_attr->max_qp_sges) ++ qplqp->rq.max_sge = dev_attr->max_qp_sges; ++ } + +- if (qp_init_attr->qp_type == IB_QPT_GSI && +- bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) +- qp->qplib_qp.type = CMDQ_CREATE_QP_TYPE_GSI; +- if (qp->qplib_qp.type == IB_QPT_MAX) { ++ return 0; ++} ++ ++static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ qplqp->rq.max_sge = dev_attr->max_qp_sges; ++ if (qplqp->rq.max_sge > dev_attr->max_qp_sges) ++ qplqp->rq.max_sge = dev_attr->max_qp_sges; ++} ++ ++static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, ++ struct ib_qp_init_attr *init_attr, ++ struct ib_udata *udata) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ int entries; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ qplqp->sq.max_sge = init_attr->cap.max_send_sge; ++ if (qplqp->sq.max_sge > dev_attr->max_qp_sges) ++ qplqp->sq.max_sge = dev_attr->max_qp_sges; ++ /* ++ * Change the SQ depth if user has requested minimum using ++ * configfs. Only supported for kernel consumers ++ */ ++ entries = init_attr->cap.max_send_wr; ++ /* Allocate 128 + 1 more than what's provided */ ++ entries = roundup_pow_of_two(entries + BNXT_QPLIB_RESERVED_QP_WRS + 1); ++ qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + ++ BNXT_QPLIB_RESERVED_QP_WRS + 1); ++ qplqp->sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1; ++ /* ++ * Reserving one slot for Phantom WQE. Application can ++ * post one extra entry in this case. But allowing this to avoid ++ * unexpected Queue full condition ++ */ ++ qplqp->sq.q_full_delta -= 1; ++} ++ ++static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp, ++ struct ib_qp_init_attr *init_attr) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ int entries; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1); ++ qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1); ++ qplqp->sq.q_full_delta = qplqp->sq.max_wqe - ++ init_attr->cap.max_send_wr; ++ qplqp->sq.max_sge++; /* Need one extra sge to put UD header */ ++ if (qplqp->sq.max_sge > dev_attr->max_qp_sges) ++ qplqp->sq.max_sge = dev_attr->max_qp_sges; ++} ++ ++static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev, ++ struct ib_qp_init_attr *init_attr) ++{ ++ struct bnxt_qplib_chip_ctx *chip_ctx; ++ int qptype; ++ ++ chip_ctx = &rdev->chip_ctx; ++ ++ qptype = __from_ib_qp_type(init_attr->qp_type); ++ if (qptype == IB_QPT_MAX) { + dev_err(rdev_to_dev(rdev), "QP type 0x%x not supported", +- qp->qplib_qp.type); +- rc = -EINVAL; +- goto fail; ++ qptype); ++ qptype = -EINVAL; ++ goto out; + } + +- qp->qplib_qp.max_inline_data = qp_init_attr->cap.max_inline_data; +- qp->qplib_qp.sig_type = ((qp_init_attr->sq_sig_type == +- IB_SIGNAL_ALL_WR) ? true : false); +- +- qp->qplib_qp.sq.max_sge = qp_init_attr->cap.max_send_sge; +- if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges; +- +- if (qp_init_attr->send_cq) { +- cq = container_of(qp_init_attr->send_cq, struct bnxt_re_cq, +- ib_cq); ++ if (bnxt_qplib_is_chip_gen_p5(chip_ctx) && ++ init_attr->qp_type == IB_QPT_GSI) ++ qptype = CMDQ_CREATE_QP_TYPE_GSI; ++out: ++ return qptype; ++} ++ ++static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, ++ struct ib_qp_init_attr *init_attr, ++ struct ib_udata *udata) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ struct bnxt_re_cq *cq; ++ int rc = 0, qptype; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ /* Setup misc params */ ++ ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr); ++ qplqp->pd = &pd->qplib_pd; ++ qplqp->qp_handle = (u64)qplqp; ++ qplqp->max_inline_data = init_attr->cap.max_inline_data; ++ qplqp->sig_type = ((init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? ++ true : false); ++ qptype = bnxt_re_init_qp_type(rdev, init_attr); ++ if (qptype < 0) { ++ rc = qptype; ++ goto out; ++ } ++ qplqp->type = (u8)qptype; ++ ++ if (init_attr->qp_type == IB_QPT_RC) { ++ qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom; ++ qplqp->max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; ++ } ++ qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); ++ qplqp->dpi = &rdev->dpi_privileged; /* Doorbell page */ ++ if (init_attr->create_flags) ++ dev_dbg(rdev_to_dev(rdev), ++ "QP create flags 0x%x not supported", ++ init_attr->create_flags); ++ ++ /* Setup CQs */ ++ if (init_attr->send_cq) { ++ cq = container_of(init_attr->send_cq, struct bnxt_re_cq, ib_cq); + if (!cq) { + dev_err(rdev_to_dev(rdev), "Send CQ not found"); + rc = -EINVAL; +- goto fail; ++ goto out; + } +- qp->qplib_qp.scq = &cq->qplib_cq; ++ qplqp->scq = &cq->qplib_cq; + qp->scq = cq; + } + +- if (qp_init_attr->recv_cq) { +- cq = container_of(qp_init_attr->recv_cq, struct bnxt_re_cq, +- ib_cq); ++ if (init_attr->recv_cq) { ++ cq = container_of(init_attr->recv_cq, struct bnxt_re_cq, ib_cq); + if (!cq) { + dev_err(rdev_to_dev(rdev), "Receive CQ not found"); + rc = -EINVAL; +- goto fail; ++ goto out; + } +- qp->qplib_qp.rcq = &cq->qplib_cq; ++ qplqp->rcq = &cq->qplib_cq; + qp->rcq = cq; + } + +- if (qp_init_attr->srq) { +- srq = container_of(qp_init_attr->srq, struct bnxt_re_srq, +- ib_srq); +- if (!srq) { +- dev_err(rdev_to_dev(rdev), "SRQ not found"); +- rc = -EINVAL; +- goto fail; +- } +- qp->qplib_qp.srq = &srq->qplib_srq; +- qp->qplib_qp.rq.max_wqe = 0; +- } else { +- /* Allocate 1 more than what's provided so posting max doesn't +- * mean empty +- */ +- entries = roundup_pow_of_two(qp_init_attr->cap.max_recv_wr + 1); +- qp->qplib_qp.rq.max_wqe = min_t(u32, entries, +- dev_attr->max_qp_wqes + 1); ++ /* Setup RQ/SRQ */ ++ rc = bnxt_re_init_rq_attr(qp, init_attr); ++ if (rc) ++ goto out; ++ if (init_attr->qp_type == IB_QPT_GSI) ++ bnxt_re_adjust_gsi_rq_attr(qp); ++ ++ /* Setup SQ */ ++ bnxt_re_init_sq_attr(qp, init_attr, udata); ++ if (init_attr->qp_type == IB_QPT_GSI) ++ bnxt_re_adjust_gsi_sq_attr(qp, init_attr); + +- qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe - +- qp_init_attr->cap.max_recv_wr; ++ if (udata) /* This will update DPI and qp_handle */ ++ rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); ++out: ++ return rc; ++} + +- qp->qplib_qp.rq.max_sge = qp_init_attr->cap.max_recv_sge; +- if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; ++static int bnxt_re_create_shadow_gsi(struct bnxt_re_qp *qp, ++ struct bnxt_re_pd *pd) ++{ ++ struct bnxt_re_sqp_entries *sqp_tbl = NULL; ++ struct bnxt_re_dev *rdev; ++ struct bnxt_re_qp *sqp; ++ struct bnxt_re_ah *sah; ++ int rc = 0; ++ ++ rdev = qp->rdev; ++ /* Create a shadow QP to handle the QP1 traffic */ ++ sqp_tbl = kzalloc(sizeof(*sqp_tbl) * BNXT_RE_MAX_GSI_SQP_ENTRIES, ++ GFP_KERNEL); ++ if (!sqp_tbl) ++ return -ENOMEM; ++ rdev->gsi_ctx.sqp_tbl = sqp_tbl; ++ ++ sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, &qp->qplib_qp); ++ if (!sqp) { ++ rc = -ENODEV; ++ dev_err(rdev_to_dev(rdev), ++ "Failed to create Shadow QP for QP1"); ++ goto out; + } ++ rdev->gsi_ctx.gsi_sqp = sqp; + +- qp->qplib_qp.mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); ++ sqp->rcq = qp->rcq; ++ sqp->scq = qp->scq; ++ sah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res, ++ &qp->qplib_qp); ++ if (!sah) { ++ bnxt_qplib_destroy_qp(&rdev->qplib_res, ++ &sqp->qplib_qp); ++ rc = -ENODEV; ++ dev_err(rdev_to_dev(rdev), ++ "Failed to create AH entry for ShadowQP"); ++ goto out; ++ } ++ rdev->gsi_ctx.gsi_sah = sah; + +- if (qp_init_attr->qp_type == IB_QPT_GSI && +- !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { +- /* Allocate 1 more than what's provided */ +- entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + 1); +- qp->qplib_qp.sq.max_wqe = min_t(u32, entries, +- dev_attr->max_qp_wqes + 1); +- qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe - +- qp_init_attr->cap.max_send_wr; +- qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; +- if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; +- qp->qplib_qp.sq.max_sge++; +- if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges; +- +- qp->qplib_qp.rq_hdr_buf_size = +- BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; +- +- qp->qplib_qp.sq_hdr_buf_size = +- BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; +- qp->qplib_qp.dpi = &rdev->dpi_privileged; +- rc = bnxt_qplib_create_qp1(&rdev->qplib_res, &qp->qplib_qp); +- if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to create HW QP1"); +- goto fail; +- } +- /* Create a shadow QP to handle the QP1 traffic */ +- rdev->qp1_sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, +- &qp->qplib_qp); +- if (!rdev->qp1_sqp) { +- rc = -EINVAL; +- dev_err(rdev_to_dev(rdev), +- "Failed to create Shadow QP for QP1"); +- goto qp_destroy; +- } +- rdev->sqp_ah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res, +- &qp->qplib_qp); +- if (!rdev->sqp_ah) { +- bnxt_qplib_destroy_qp(&rdev->qplib_res, +- &rdev->qp1_sqp->qplib_qp); +- rc = -EINVAL; +- dev_err(rdev_to_dev(rdev), +- "Failed to create AH entry for ShadowQP"); +- goto qp_destroy; +- } ++ return 0; ++out: ++ kfree(sqp_tbl); ++ return rc; ++} + +- } else { +- /* Allocate 128 + 1 more than what's provided */ +- entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + +- BNXT_QPLIB_RESERVED_QP_WRS + 1); +- qp->qplib_qp.sq.max_wqe = min_t(u32, entries, +- dev_attr->max_qp_wqes + +- BNXT_QPLIB_RESERVED_QP_WRS + 1); +- qp->qplib_qp.sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1; ++static int bnxt_re_create_gsi_qp(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, ++ struct ib_qp_init_attr *init_attr) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_re_dev *rdev; ++ struct bnxt_qplib_qp *qplqp; ++ int rc = 0; + +- /* +- * Reserving one slot for Phantom WQE. Application can +- * post one extra entry in this case. But allowing this to avoid +- * unexpected Queue full condition +- */ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; + +- qp->qplib_qp.sq.q_full_delta -= 1; ++ qplqp->rq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; ++ qplqp->sq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; + +- qp->qplib_qp.max_rd_atomic = dev_attr->max_qp_rd_atom; +- qp->qplib_qp.max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; +- if (udata) { +- rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); +- if (rc) +- goto fail; +- } else { +- qp->qplib_qp.dpi = &rdev->dpi_privileged; +- } ++ rc = bnxt_qplib_create_qp1(&rdev->qplib_res, qplqp); ++ if (rc) { ++ dev_err(rdev_to_dev(rdev), "create HW QP1 failed!"); ++ goto out; ++ } + ++ rc = bnxt_re_create_shadow_gsi(qp, pd); ++out: ++ return rc; ++} ++ ++static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev, ++ struct ib_qp_init_attr *init_attr, ++ struct bnxt_qplib_dev_attr *dev_attr) ++{ ++ bool rc = true; ++ ++ if (init_attr->cap.max_send_wr > dev_attr->max_qp_wqes || ++ init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes || ++ init_attr->cap.max_send_sge > dev_attr->max_qp_sges || ++ init_attr->cap.max_recv_sge > dev_attr->max_qp_sges || ++ init_attr->cap.max_inline_data > dev_attr->max_inline_data) { ++ dev_err(rdev_to_dev(rdev), ++ "Create QP failed - max exceeded! 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x", ++ init_attr->cap.max_send_wr, dev_attr->max_qp_wqes, ++ init_attr->cap.max_recv_wr, dev_attr->max_qp_wqes, ++ init_attr->cap.max_send_sge, dev_attr->max_qp_sges, ++ init_attr->cap.max_recv_sge, dev_attr->max_qp_sges, ++ init_attr->cap.max_inline_data, ++ dev_attr->max_inline_data); ++ rc = false; ++ } ++ return rc; ++} ++ ++struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, ++ struct ib_qp_init_attr *qp_init_attr, ++ struct ib_udata *udata) ++{ ++ struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); ++ struct bnxt_re_dev *rdev = pd->rdev; ++ struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; ++ struct bnxt_re_qp *qp; ++ int rc; ++ ++ rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr); ++ if (!rc) { ++ rc = -EINVAL; ++ goto exit; ++ } ++ ++ qp = kzalloc(sizeof(*qp), GFP_KERNEL); ++ if (!qp) { ++ rc = -ENOMEM; ++ goto exit; ++ } ++ qp->rdev = rdev; ++ rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata); ++ if (rc) ++ goto fail; ++ ++ if (qp_init_attr->qp_type == IB_QPT_GSI && ++ !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { ++ rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr); ++ if (rc == -ENODEV) ++ goto qp_destroy; ++ if (rc) ++ goto fail; ++ } else { + rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { + dev_err(rdev_to_dev(rdev), "Failed to create HW QP"); + goto free_umem; + } ++ if (udata) { ++ struct bnxt_re_qp_resp resp; ++ ++ resp.qpid = qp->qplib_qp.id; ++ resp.rsvd = 0; ++ rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); ++ if (rc) { ++ dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); ++ goto qp_destroy; ++ } ++ } + } + + qp->ib_qp.qp_num = qp->qplib_qp.id; ++ if (qp_init_attr->qp_type == IB_QPT_GSI) ++ rdev->gsi_ctx.gsi_qp = qp; + spin_lock_init(&qp->sq_lock); + spin_lock_init(&qp->rq_lock); +- +- if (udata) { +- struct bnxt_re_qp_resp resp; +- +- resp.qpid = qp->ib_qp.qp_num; +- resp.rsvd = 0; +- rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); +- if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); +- goto qp_destroy; +- } +- } + INIT_LIST_HEAD(&qp->list); + mutex_lock(&rdev->qp_lock); + list_add_tail(&qp->list, &rdev->qp_list); +- atomic_inc(&rdev->qp_count); + mutex_unlock(&rdev->qp_lock); ++ atomic_inc(&rdev->qp_count); + + return &qp->ib_qp; + qp_destroy: +@@ -1188,6 +1386,7 @@ free_umem: + ib_umem_release(qp->sumem); + fail: + kfree(qp); ++exit: + return ERR_PTR(rc); + } + +@@ -1485,7 +1684,7 @@ static int bnxt_re_modify_shadow_qp(stru + struct bnxt_re_qp *qp1_qp, + int qp_attr_mask) + { +- struct bnxt_re_qp *qp = rdev->qp1_sqp; ++ struct bnxt_re_qp *qp = rdev->gsi_ctx.gsi_sqp; + int rc = 0; + + if (qp_attr_mask & IB_QP_STATE) { +@@ -1750,7 +1949,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + dev_err(rdev_to_dev(rdev), "Failed to modify HW QP"); + return rc; + } +- if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) ++ if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) + rc = bnxt_re_modify_shadow_qp(rdev, qp, qp_attr_mask); + return rc; + } +@@ -1994,9 +2193,12 @@ static int bnxt_re_build_qp1_shadow_qp_r + struct bnxt_qplib_swqe *wqe, + int payload_size) + { ++ struct bnxt_re_sqp_entries *sqp_entry; + struct bnxt_qplib_sge ref, sge; ++ struct bnxt_re_dev *rdev; + u32 rq_prod_index; +- struct bnxt_re_sqp_entries *sqp_entry; ++ ++ rdev = qp->rdev; + + rq_prod_index = bnxt_qplib_get_rq_prod_index(&qp->qplib_qp); + +@@ -2011,7 +2213,7 @@ static int bnxt_re_build_qp1_shadow_qp_r + ref.lkey = wqe->sg_list[0].lkey; + ref.size = wqe->sg_list[0].size; + +- sqp_entry = &qp->rdev->sqp_tbl[rq_prod_index]; ++ sqp_entry = &rdev->gsi_ctx.sqp_tbl[rq_prod_index]; + + /* SGE 1 */ + wqe->sg_list[0].addr = sge.addr; +@@ -2831,12 +3033,13 @@ static bool bnxt_re_is_loopback_packet(s + return rc; + } + +-static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp, ++static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *gsi_qp, + struct bnxt_qplib_cqe *cqe) + { +- struct bnxt_re_dev *rdev = qp1_qp->rdev; ++ struct bnxt_re_dev *rdev = gsi_qp->rdev; + struct bnxt_re_sqp_entries *sqp_entry = NULL; +- struct bnxt_re_qp *qp = rdev->qp1_sqp; ++ struct bnxt_re_qp *gsi_sqp = rdev->gsi_ctx.gsi_sqp; ++ struct bnxt_re_ah *gsi_sah; + struct ib_send_wr *swr; + struct ib_ud_wr udwr; + struct ib_recv_wr rwr; +@@ -2859,19 +3062,19 @@ static int bnxt_re_process_raw_qp_pkt_rx + swr = &udwr.wr; + tbl_idx = cqe->wr_id; + +- rq_hdr_buf = qp1_qp->qplib_qp.rq_hdr_buf + +- (tbl_idx * qp1_qp->qplib_qp.rq_hdr_buf_size); +- rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp1_qp->qplib_qp, ++ rq_hdr_buf = gsi_qp->qplib_qp.rq_hdr_buf + ++ (tbl_idx * gsi_qp->qplib_qp.rq_hdr_buf_size); ++ rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp, + tbl_idx); + + /* Shadow QP header buffer */ +- shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp->qplib_qp, ++ shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp, + tbl_idx); +- sqp_entry = &rdev->sqp_tbl[tbl_idx]; ++ sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx]; + + /* Store this cqe */ + memcpy(&sqp_entry->cqe, cqe, sizeof(struct bnxt_qplib_cqe)); +- sqp_entry->qp1_qp = qp1_qp; ++ sqp_entry->qp1_qp = gsi_qp; + + /* Find packet type from the cqe */ + +@@ -2925,7 +3128,7 @@ static int bnxt_re_process_raw_qp_pkt_rx + rwr.wr_id = tbl_idx; + rwr.next = NULL; + +- rc = bnxt_re_post_recv_shadow_qp(rdev, qp, &rwr); ++ rc = bnxt_re_post_recv_shadow_qp(rdev, gsi_sqp, &rwr); + if (rc) { + dev_err(rdev_to_dev(rdev), + "Failed to post Rx buffers to shadow QP"); +@@ -2937,13 +3140,13 @@ static int bnxt_re_process_raw_qp_pkt_rx + swr->wr_id = tbl_idx; + swr->opcode = IB_WR_SEND; + swr->next = NULL; +- +- udwr.ah = &rdev->sqp_ah->ib_ah; +- udwr.remote_qpn = rdev->qp1_sqp->qplib_qp.id; +- udwr.remote_qkey = rdev->qp1_sqp->qplib_qp.qkey; ++ gsi_sah = rdev->gsi_ctx.gsi_sah; ++ udwr.ah = &gsi_sah->ib_ah; ++ udwr.remote_qpn = gsi_sqp->qplib_qp.id; ++ udwr.remote_qkey = gsi_sqp->qplib_qp.qkey; + + /* post data received in the send queue */ +- rc = bnxt_re_post_send_shadow_qp(rdev, qp, swr); ++ rc = bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr); + + return 0; + } +@@ -2997,12 +3200,12 @@ static void bnxt_re_process_res_rc_wc(st + wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; + } + +-static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp, ++static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, + struct ib_wc *wc, + struct bnxt_qplib_cqe *cqe) + { +- struct bnxt_re_dev *rdev = qp->rdev; +- struct bnxt_re_qp *qp1_qp = NULL; ++ struct bnxt_re_dev *rdev = gsi_sqp->rdev; ++ struct bnxt_re_qp *gsi_qp = NULL; + struct bnxt_qplib_cqe *orig_cqe = NULL; + struct bnxt_re_sqp_entries *sqp_entry = NULL; + int nw_type; +@@ -3012,13 +3215,13 @@ static void bnxt_re_process_res_shadow_q + + tbl_idx = cqe->wr_id; + +- sqp_entry = &rdev->sqp_tbl[tbl_idx]; +- qp1_qp = sqp_entry->qp1_qp; ++ sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx]; ++ gsi_qp = sqp_entry->qp1_qp; + orig_cqe = &sqp_entry->cqe; + + wc->wr_id = sqp_entry->wrid; + wc->byte_len = orig_cqe->length; +- wc->qp = &qp1_qp->ib_qp; ++ wc->qp = &gsi_qp->ib_qp; + + wc->ex.imm_data = orig_cqe->immdata; + wc->src_qp = orig_cqe->src_qp; +@@ -3097,7 +3300,7 @@ static int send_phantom_wqe(struct bnxt_ + int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + { + struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq); +- struct bnxt_re_qp *qp; ++ struct bnxt_re_qp *qp, *sh_qp; + struct bnxt_qplib_cqe *cqe; + int i, ncqe, budget; + struct bnxt_qplib_q *sq; +@@ -3161,8 +3364,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + + switch (cqe->opcode) { + case CQ_BASE_CQE_TYPE_REQ: +- if (qp->rdev->qp1_sqp && qp->qplib_qp.id == +- qp->rdev->qp1_sqp->qplib_qp.id) { ++ sh_qp = qp->rdev->gsi_ctx.gsi_sqp; ++ if (sh_qp && ++ qp->qplib_qp.id == sh_qp->qplib_qp.id) { + /* Handle this completion with + * the stored completion + */ +@@ -3188,7 +3392,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + * stored in the table + */ + tbl_idx = cqe->wr_id; +- sqp_entry = &cq->rdev->sqp_tbl[tbl_idx]; ++ sqp_entry = &cq->rdev->gsi_ctx.sqp_tbl[tbl_idx]; + wc->wr_id = sqp_entry->wrid; + bnxt_re_process_res_rawqp1_wc(wc, cqe); + break; +@@ -3196,8 +3400,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + bnxt_re_process_res_rc_wc(wc, cqe); + break; + case CQ_BASE_CQE_TYPE_RES_UD: +- if (qp->rdev->qp1_sqp && qp->qplib_qp.id == +- qp->rdev->qp1_sqp->qplib_qp.id) { ++ sh_qp = qp->rdev->gsi_ctx.gsi_sqp; ++ if (sh_qp && ++ qp->qplib_qp.id == sh_qp->qplib_qp.id) { + /* Handle this completion with + * the stored completion + */ +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1125,7 +1125,8 @@ static int bnxt_re_query_hwrm_pri2cos(st + static bool bnxt_re_is_qp1_or_shadow_qp(struct bnxt_re_dev *rdev, + struct bnxt_re_qp *qp) + { +- return (qp->ib_qp.qp_type == IB_QPT_GSI) || (qp == rdev->qp1_sqp); ++ return (qp->ib_qp.qp_type == IB_QPT_GSI) || ++ (qp == rdev->gsi_ctx.gsi_sqp); + } + + static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev) diff --git a/patches.suse/RDMA-bnxt_re-Remove-a-redundant-memset.patch b/patches.suse/RDMA-bnxt_re-Remove-a-redundant-memset.patch new file mode 100644 index 0000000..f6dc7bc --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Remove-a-redundant-memset.patch @@ -0,0 +1,40 @@ +From: Christophe JAILLET +Date: Sun, 8 Mar 2020 07:54:42 +0100 +Subject: RDMA/bnxt_re: Remove a redundant 'memset' +Patch-mainline: v5.7-rc1 +Git-commit: 24a5b0ce714210c69a8870d4a11ab6a8cff650c6 +References: bsc#1170774 + +'wqe' is already zeroed at the top of the 'while' loop, just a few lines +below, and is not used outside of the loop. + +So there is no need to zero it again, or for the variable to be declared +outside the loop. + +Link: https://lore.kernel.org/r/20200308065442.5415-1-christophe.jaillet@wanadoo.fr +Signed-off-by: Christophe JAILLET +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -2468,15 +2468,12 @@ static int bnxt_re_post_send_shadow_qp(s + struct bnxt_re_qp *qp, + const struct ib_send_wr *wr) + { +- struct bnxt_qplib_swqe wqe; + int rc = 0, payload_sz = 0; + unsigned long flags; + + spin_lock_irqsave(&qp->sq_lock, flags); +- memset(&wqe, 0, sizeof(wqe)); + while (wr) { +- /* House keeping */ +- memset(&wqe, 0, sizeof(wqe)); ++ struct bnxt_qplib_swqe wqe = {}; + + /* Common */ + wqe.num_sge = wr->num_sge; diff --git a/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-dev_at.patch b/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-dev_at.patch new file mode 100644 index 0000000..15ad75d --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-dev_at.patch @@ -0,0 +1,42 @@ +From: YueHaibing +Date: Thu, 27 Feb 2020 06:45:42 +0000 +Subject: RDMA/bnxt_re: Remove set but not used variable 'dev_attr' +Patch-mainline: v5.7-rc1 +Git-commit: a0b404a98e274b5fc0cfb7c108d99127d482e5ff +References: bsc#1170774 + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/infiniband/hw/bnxt_re/ib_verbs.c: In function 'bnxt_re_create_gsi_qp': +drivers/infiniband/hw/bnxt_re/ib_verbs.c:1283:30: warning: + variable 'dev_attr' set but not used [-Wunused-but-set-variable] + +commit 8dae419f9ec7 ("RDMA/bnxt_re: Refactor queue pair creation code") +involved this, but not used, so remove it. + +Link: https://lore.kernel.org/r/20200227064542.91205-1-yuehaibing@huawei.com +Reported-by: Hulk Robot +Signed-off-by: YueHaibing +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -1279,14 +1279,12 @@ out: + static int bnxt_re_create_gsi_qp(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, + struct ib_qp_init_attr *init_attr) + { +- struct bnxt_qplib_dev_attr *dev_attr; + struct bnxt_re_dev *rdev; + struct bnxt_qplib_qp *qplqp; + int rc = 0; + + rdev = qp->rdev; + qplqp = &qp->qplib_qp; +- dev_attr = &rdev->dev_attr; + + qplqp->rq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; + qplqp->sq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; diff --git a/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-pg_siz.patch b/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-pg_siz.patch new file mode 100644 index 0000000..c1abcdf --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-pg_siz.patch @@ -0,0 +1,42 @@ +From: YueHaibing +Date: Thu, 27 Feb 2020 06:42:09 +0000 +Subject: RDMA/bnxt_re: Remove set but not used variable 'pg_size' +Patch-mainline: v5.7-rc1 +Git-commit: 6be2067d1e31477354b08d1ac85ff9ec6dec898e +References: bsc#1170774 + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/infiniband/hw/bnxt_re/qplib_res.c: In function '__alloc_pbl': +drivers/infiniband/hw/bnxt_re/qplib_res.c:109:13: warning: + variable 'pg_size' set but not used [-Wunused-but-set-variable] + +commit 0c4dcd602817 ("RDMA/bnxt_re: Refactor hardware queue memory +allocation") involved this, but not used, so remove it. + +Link: https://lore.kernel.org/r/20200227064209.87893-1-yuehaibing@huawei.com +Reported-by: Hulk Robot +Signed-off-by: YueHaibing +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/qplib_res.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c +@@ -106,13 +106,12 @@ static int __alloc_pbl(struct bnxt_qplib + struct pci_dev *pdev = res->pdev; + struct scatterlist *sghead; + bool is_umem = false; +- u32 pages, pg_size; ++ u32 pages; + int i; + + if (sginfo->nopte) + return 0; + pages = sginfo->npages; +- pg_size = sginfo->pgsize; + sghead = sginfo->sghead; + /* page ptr arrays */ + pbl->pg_arr = vmalloc(pages * sizeof(void *)); diff --git a/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variables-pg-an.patch b/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variables-pg-an.patch new file mode 100644 index 0000000..cf2523c --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variables-pg-an.patch @@ -0,0 +1,46 @@ +From: YueHaibing +Date: Thu, 27 Feb 2020 06:49:00 +0000 +Subject: RDMA/bnxt_re: Remove set but not used variables 'pg' and 'idx' +Patch-mainline: v5.7-rc1 +Git-commit: 75d03665081e00881e76eaa3a7635c9202a82600 +References: bsc#1170774 + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/infiniband/hw/bnxt_re/qplib_rcfw.c: In function '__send_message': +drivers/infiniband/hw/bnxt_re/qplib_rcfw.c:101:10: warning: + variable 'idx' set but not used [-Wunused-but-set-variable] +drivers/infiniband/hw/bnxt_re/qplib_rcfw.c:101:6: warning: + variable 'pg' set but not used [-Wunused-but-set-variable] + +commit cee0c7bba486 ("RDMA/bnxt_re: Refactor command queue management +code") involved this, but not used. + +Link: https://lore.kernel.org/r/20200227064900.92255-1-yuehaibing@huawei.com +Signed-off-by: YueHaibing +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +@@ -98,7 +98,6 @@ static int __send_message(struct bnxt_qp + unsigned long flags; + u32 size, opcode; + u16 cookie, cbit; +- int pg, idx; + u8 *preq; + + pdev = rcfw->pdev; +@@ -167,9 +166,6 @@ static int __send_message(struct bnxt_qp + hwq_ptr = (struct bnxt_qplib_cmdqe **)hwq->pbl_ptr; + preq = (u8 *)req; + do { +- pg = 0; +- idx = 0; +- + /* Locate the next cmdq slot */ + sw_prod = HWQ_CMP(hwq->prod, hwq); + cmdqe = &hwq_ptr[get_cmdq_pg(sw_prod, cmdq_depth)] diff --git a/patches.suse/RDMA-bnxt_re-Remove-unnecessary-sched-count.patch b/patches.suse/RDMA-bnxt_re-Remove-unnecessary-sched-count.patch new file mode 100644 index 0000000..01002f5 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Remove-unnecessary-sched-count.patch @@ -0,0 +1,60 @@ +From: Selvin Xavier +Date: Fri, 13 Mar 2020 09:33:27 -0700 +Subject: RDMA/bnxt_re: Remove unnecessary sched count +Patch-mainline: v5.7-rc1 +Git-commit: 4e88cef11d1913d1875c7870df4facbd096a062b +References: bsc#1170774 + +Since the lifetime of bnxt_re_task is controlled by the kref of device, +sched_count is no longer required. Remove it. + +Link: https://lore.kernel.org/r/1584117207-2664-4-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 1 - + drivers/infiniband/hw/bnxt_re/main.c | 8 -------- + 2 files changed, 9 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -176,7 +176,6 @@ struct bnxt_re_dev { + atomic_t srq_count; + atomic_t mr_count; + atomic_t mw_count; +- atomic_t sched_count; + /* Max of 2 lossless traffic class supported per port */ + u16 cosq[2]; + +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1667,8 +1667,6 @@ static void bnxt_re_task(struct work_str + break; + } + ib_device_put(&rdev->ibdev); +- smp_mb__before_atomic(); +- atomic_dec(&rdev->sched_count); + exit: + put_device(&rdev->ibdev.dev); + kfree(re_work); +@@ -1720,11 +1718,6 @@ static int bnxt_re_netdev_event(struct n + break; + + case NETDEV_UNREGISTER: +- /* netdev notifier will call NETDEV_UNREGISTER again later since +- * we are still holding the reference to the netdev +- */ +- if (atomic_read(&rdev->sched_count) > 0) +- goto exit; + ib_unregister_device_queued(&rdev->ibdev); + break; + +@@ -1742,7 +1735,6 @@ static int bnxt_re_netdev_event(struct n + re_work->vlan_dev = (real_dev == netdev ? + NULL : netdev); + INIT_WORK(&re_work->work, bnxt_re_task); +- atomic_inc(&rdev->sched_count); + queue_work(bnxt_re_wq, &re_work->work); + } + } diff --git a/patches.suse/RDMA-bnxt_re-Replace-chip-context-structure-with-poi.patch b/patches.suse/RDMA-bnxt_re-Replace-chip-context-structure-with-poi.patch new file mode 100644 index 0000000..037c7de --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Replace-chip-context-structure-with-poi.patch @@ -0,0 +1,237 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:10:59 -0500 +Subject: RDMA/bnxt_re: Replace chip context structure with pointer +Patch-mainline: v5.7-rc1 +Git-commit: 0cfb329db988804124423b311a2845e56914e3ca +References: bsc#1170774 + +The chip_ctx member in bnxt_re_dev structure is now a pointer to struct +bnxt_qplib_chip_ctx. Since the member type has changed there are changes +in rest of the code wherever dev->chip_ctx is used. + +Link: https://lore.kernel.org/r/1581786665-23705-3-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Naresh Kumar PBS +Signed-off-by: Selvin Xavier +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 2 - + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 13 +++++----- + drivers/infiniband/hw/bnxt_re/main.c | 40 ++++++++++++++++++++----------- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 2 - + 4 files changed, 36 insertions(+), 21 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -133,7 +133,7 @@ struct bnxt_re_dev { + #define BNXT_RE_FLAG_ISSUE_ROCE_STATS 29 + struct net_device *netdev; + unsigned int version, major, minor; +- struct bnxt_qplib_chip_ctx chip_ctx; ++ struct bnxt_qplib_chip_ctx *chip_ctx; + struct bnxt_en_dev *en_dev; + struct bnxt_msix_entry msix_entries[BNXT_RE_MAX_MSIX]; + int num_msix; +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -859,7 +859,7 @@ static int bnxt_re_init_user_qp(struct b + bytes = (qplib_qp->sq.max_wqe * BNXT_QPLIB_MAX_SQE_ENTRY_SIZE); + /* Consider mapping PSN search memory only for RC QPs. */ + if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC) { +- psn_sz = bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? ++ psn_sz = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? + sizeof(struct sq_psn_search_ext) : + sizeof(struct sq_psn_search); + bytes += (qplib_qp->sq.max_wqe * psn_sz); +@@ -1059,6 +1059,7 @@ static void bnxt_re_adjust_gsi_rq_attr(s + qplqp->rq.max_sge = dev_attr->max_qp_sges; + if (qplqp->rq.max_sge > dev_attr->max_qp_sges) + qplqp->rq.max_sge = dev_attr->max_qp_sges; ++ qplqp->rq.max_sge = 6; + } + + static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, +@@ -1122,7 +1123,7 @@ static int bnxt_re_init_qp_type(struct b + struct bnxt_qplib_chip_ctx *chip_ctx; + int qptype; + +- chip_ctx = &rdev->chip_ctx; ++ chip_ctx = rdev->chip_ctx; + + qptype = __from_ib_qp_type(init_attr->qp_type); + if (qptype == IB_QPT_MAX) { +@@ -1342,7 +1343,7 @@ struct ib_qp *bnxt_re_create_qp(struct i + goto fail; + + if (qp_init_attr->qp_type == IB_QPT_GSI && +- !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { ++ !(bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx))) { + rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr); + if (rc == -ENODEV) + goto qp_destroy; +@@ -3818,10 +3819,10 @@ int bnxt_re_alloc_ucontext(struct ib_uco + spin_lock_init(&uctx->sh_lock); + + resp.comp_mask = BNXT_RE_UCNTX_CMASK_HAVE_CCTX; +- chip_met_rev_num = rdev->chip_ctx.chip_num; +- chip_met_rev_num |= ((u32)rdev->chip_ctx.chip_rev & 0xFF) << ++ chip_met_rev_num = rdev->chip_ctx->chip_num; ++ chip_met_rev_num |= ((u32)rdev->chip_ctx->chip_rev & 0xFF) << + BNXT_RE_CHIP_ID0_CHIP_REV_SFT; +- chip_met_rev_num |= ((u32)rdev->chip_ctx.chip_metal & 0xFF) << ++ chip_met_rev_num |= ((u32)rdev->chip_ctx->chip_metal & 0xFF) << + BNXT_RE_CHIP_ID0_CHIP_MET_SFT; + resp.chip_id0 = chip_met_rev_num; + /* Future extension of chip info */ +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -82,22 +82,35 @@ static void bnxt_re_ib_unreg(struct bnxt + + static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev) + { ++ struct bnxt_qplib_chip_ctx *chip_ctx; ++ ++ if (!rdev->chip_ctx) ++ return; ++ chip_ctx = rdev->chip_ctx; ++ rdev->chip_ctx = NULL; + rdev->rcfw.res = NULL; + rdev->qplib_res.cctx = NULL; ++ kfree(chip_ctx); + } + + static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) + { ++ struct bnxt_qplib_chip_ctx *chip_ctx; + struct bnxt_en_dev *en_dev; + struct bnxt *bp; + + en_dev = rdev->en_dev; + bp = netdev_priv(en_dev->net); + +- rdev->chip_ctx.chip_num = bp->chip_num; ++ chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL); ++ if (!chip_ctx) ++ return -ENOMEM; ++ chip_ctx->chip_num = bp->chip_num; ++ ++ rdev->chip_ctx = chip_ctx; + /* rest members to follow eventually */ + +- rdev->qplib_res.cctx = &rdev->chip_ctx; ++ rdev->qplib_res.cctx = rdev->chip_ctx; + rdev->rcfw.res = &rdev->qplib_res; + + return 0; +@@ -136,7 +149,7 @@ static void bnxt_re_limit_pf_res(struct + ctx->srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT, + attr->max_srq); + ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq); +- if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) ++ if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) + for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) + rdev->qplib_ctx.tqm_count[i] = + rdev->dev_attr.tqm_alloc_reqs[i]; +@@ -185,7 +198,7 @@ static void bnxt_re_set_resource_limits( + memset(&rdev->qplib_ctx.vf_res, 0, sizeof(struct bnxt_qplib_vf_res)); + bnxt_re_limit_pf_res(rdev); + +- num_vfs = bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? ++ num_vfs = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? + BNXT_RE_GEN_P5_MAX_VF : rdev->num_vfs; + if (num_vfs) + bnxt_re_limit_vf_res(&rdev->qplib_ctx, num_vfs); +@@ -208,7 +221,7 @@ static void bnxt_re_sriov_config(void *p + return; + + rdev->num_vfs = num_vfs; +- if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) { ++ if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) { + bnxt_re_set_resource_limits(rdev); + bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, + &rdev->qplib_ctx); +@@ -916,7 +929,7 @@ static int bnxt_re_cqn_handler(struct bn + #define BNXT_RE_GEN_P5_VF_NQ_DB 0x4000 + static u32 bnxt_re_get_nqdb_offset(struct bnxt_re_dev *rdev, u16 indx) + { +- return bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? ++ return bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? + (rdev->is_virtfn ? BNXT_RE_GEN_P5_VF_NQ_DB : + BNXT_RE_GEN_P5_PF_NQ_DB) : + rdev->msix_entries[indx].db_offset; +@@ -967,7 +980,7 @@ static void bnxt_re_free_nq_res(struct b + int i; + + for (i = 0; i < rdev->num_msix - 1; i++) { +- type = bnxt_qplib_get_ring_type(&rdev->chip_ctx); ++ type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type); + rdev->nq[i].res = NULL; + bnxt_qplib_free_nq(&rdev->nq[i]); +@@ -1025,7 +1038,7 @@ static int bnxt_re_alloc_res(struct bnxt + i, rc); + goto free_nq; + } +- type = bnxt_qplib_get_ring_type(&rdev->chip_ctx); ++ type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + pg_map = rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr; + pages = rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count; + rc = bnxt_re_net_ring_alloc(rdev, pg_map, pages, type, +@@ -1044,7 +1057,7 @@ static int bnxt_re_alloc_res(struct bnxt + return 0; + free_nq: + for (i = num_vec_created; i >= 0; i--) { +- type = bnxt_qplib_get_ring_type(&rdev->chip_ctx); ++ type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type); + bnxt_qplib_free_nq(&rdev->nq[i]); + } +@@ -1324,7 +1337,7 @@ static void bnxt_re_ib_unreg(struct bnxt + bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); + bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx); + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); +- type = bnxt_qplib_get_ring_type(&rdev->chip_ctx); ++ type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type); + bnxt_qplib_free_rcfw_channel(&rdev->rcfw); + } +@@ -1405,7 +1418,8 @@ static int bnxt_re_ib_reg(struct bnxt_re + pr_err("Failed to allocate RCFW Channel: %#x\n", rc); + goto fail; + } +- type = bnxt_qplib_get_ring_type(&rdev->chip_ctx); ++ ++ type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + pg_map = rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr; + pages = rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count; + ridx = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; +@@ -1434,7 +1448,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + bnxt_re_set_resource_limits(rdev); + + rc = bnxt_qplib_alloc_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx, 0, +- bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)); ++ bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)); + if (rc) { + pr_err("Failed to allocate QPLIB context: %#x\n", rc); + goto disable_rcfw; +@@ -1504,7 +1518,7 @@ free_ctx: + disable_rcfw: + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); + free_ring: +- type = bnxt_qplib_get_ring_type(&rdev->chip_ctx); ++ type = bnxt_qplib_get_ring_type(rdev->chip_ctx); + bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type); + free_rcfw: + bnxt_qplib_free_rcfw_channel(&rdev->rcfw); +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -2426,7 +2426,7 @@ static int bnxt_qplib_cq_process_res_ud( + } + cqe = *pcqe; + cqe->opcode = hwcqe->cqe_type_toggle & CQ_BASE_CQE_TYPE_MASK; +- cqe->length = (u32)le16_to_cpu(hwcqe->length); ++ cqe->length = le16_to_cpu(hwcqe->length) & CQ_RES_UD_LENGTH_MASK; + cqe->cfa_meta = le16_to_cpu(hwcqe->cfa_metadata); + cqe->invrkey = le32_to_cpu(hwcqe->imm_data); + cqe->flags = le16_to_cpu(hwcqe->flags); diff --git a/patches.suse/RDMA-bnxt_re-Use-driver_unregister-and-unregistratio.patch b/patches.suse/RDMA-bnxt_re-Use-driver_unregister-and-unregistratio.patch new file mode 100644 index 0000000..565268c --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Use-driver_unregister-and-unregistratio.patch @@ -0,0 +1,248 @@ +From: Selvin Xavier +Date: Wed, 26 Feb 2020 07:45:32 -0800 +Subject: RDMA/bnxt_re: Use driver_unregister and unregistration API +Patch-mainline: v5.7-rc1 +Git-commit: 66832705c4d01e52df78570e72a9392a1271d2e9 +References: bsc#1170774 + +Using the new unregister APIs provided by the core. Provide the +dealloc_driver hook for the core to callback at the time of device +un-registration. + +bnxt_re VF resources are created by the corresponding PF driver. During +ib_unregister_driver, PF might get removed before VF and this could cause +failure when VFs are removed. Driver is explicitly queuing the removal of +VF devices before calling ib_unregister_driver. + +Link: https://lore.kernel.org/r/1582731932-26574-3-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/main.c | 106 +++++++++++++---------------------- + 1 file changed, 42 insertions(+), 64 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -79,7 +79,8 @@ static struct list_head bnxt_re_dev_list + static DEFINE_MUTEX(bnxt_re_dev_lock); + static struct workqueue_struct *bnxt_re_wq; + static void bnxt_re_remove_device(struct bnxt_re_dev *rdev); +-static void bnxt_re_ib_uninit(struct bnxt_re_dev *rdev); ++static void bnxt_re_dealloc_driver(struct ib_device *ib_dev); ++static void bnxt_re_stop_irq(void *handle); + + static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev) + { +@@ -237,10 +238,10 @@ static void bnxt_re_shutdown(void *p) + + if (!rdev) + return; +- +- bnxt_re_ib_uninit(rdev); + ASSERT_RTNL(); +- bnxt_re_remove_device(rdev); ++ /* Release the MSIx vectors before queuing unregister */ ++ bnxt_re_stop_irq(rdev); ++ ib_unregister_device_queued(&rdev->ibdev); + } + + static void bnxt_re_stop_irq(void *handle) +@@ -542,17 +543,12 @@ static bool is_bnxt_re_dev(struct net_de + + static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev) + { +- struct bnxt_re_dev *rdev; ++ struct ib_device *ibdev = ++ ib_device_get_by_netdev(netdev, RDMA_DRIVER_BNXT_RE); ++ if (!ibdev) ++ return NULL; + +- rcu_read_lock(); +- list_for_each_entry_rcu(rdev, &bnxt_re_dev_list, list) { +- if (rdev->netdev == netdev) { +- rcu_read_unlock(); +- return rdev; +- } +- } +- rcu_read_unlock(); +- return NULL; ++ return container_of(ibdev, struct bnxt_re_dev, ibdev); + } + + static void bnxt_re_dev_unprobe(struct net_device *netdev, +@@ -626,11 +622,6 @@ static const struct attribute_group bnxt + .attrs = bnxt_re_attributes, + }; + +-static void bnxt_re_unregister_ib(struct bnxt_re_dev *rdev) +-{ +- ib_unregister_device(&rdev->ibdev); +-} +- + static const struct ib_device_ops bnxt_re_dev_ops = { + .owner = THIS_MODULE, + .driver_id = RDMA_DRIVER_BNXT_RE, +@@ -645,6 +636,7 @@ static const struct ib_device_ops bnxt_r + .create_cq = bnxt_re_create_cq, + .create_qp = bnxt_re_create_qp, + .create_srq = bnxt_re_create_srq, ++ .dealloc_driver = bnxt_re_dealloc_driver, + .dealloc_pd = bnxt_re_dealloc_pd, + .dealloc_ucontext = bnxt_re_dealloc_ucontext, + .del_gid = bnxt_re_del_gid, +@@ -741,15 +733,11 @@ static void bnxt_re_dev_remove(struct bn + { + dev_put(rdev->netdev); + rdev->netdev = NULL; +- + mutex_lock(&bnxt_re_dev_lock); + list_del_rcu(&rdev->list); + mutex_unlock(&bnxt_re_dev_lock); + + synchronize_rcu(); +- +- ib_dealloc_device(&rdev->ibdev); +- /* rdev is gone */ + } + + static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev, +@@ -1320,15 +1308,6 @@ static void bnxt_re_query_hwrm_intf_vers + le16_to_cpu(resp.hwrm_intf_patch); + } + +-static void bnxt_re_ib_uninit(struct bnxt_re_dev *rdev) +-{ +- /* Cleanup ib dev */ +- if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) { +- ib_unregister_device(&rdev->ibdev); +- clear_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); +- } +-} +- + int bnxt_re_ib_init(struct bnxt_re_dev *rdev) + { + int rc = 0; +@@ -1359,10 +1338,6 @@ static void bnxt_re_dev_uninit(struct bn + u8 type; + int rc; + +- if (test_and_clear_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) { +- /* Cleanup ib dev */ +- bnxt_re_unregister_ib(rdev); +- } + if (test_and_clear_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags)) + cancel_delayed_work_sync(&rdev->worker); + +@@ -1632,6 +1607,19 @@ static int bnxt_re_add_device(struct bnx + return rc; + } + ++static void bnxt_re_dealloc_driver(struct ib_device *ib_dev) ++{ ++ struct bnxt_re_dev *rdev = ++ container_of(ib_dev, struct bnxt_re_dev, ibdev); ++ ++ clear_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); ++ dev_info(rdev_to_dev(rdev), "Unregistering Device"); ++ ++ rtnl_lock(); ++ bnxt_re_remove_device(rdev); ++ rtnl_unlock(); ++} ++ + /* Handle all deferred netevents tasks */ + static void bnxt_re_task(struct work_struct *work) + { +@@ -1706,6 +1694,7 @@ static int bnxt_re_netdev_event(struct n + struct bnxt_re_dev *rdev; + int rc = 0; + bool sch_work = false; ++ bool release = true; + + real_dev = rdma_vlan_dev_real_dev(netdev); + if (!real_dev) +@@ -1713,7 +1702,8 @@ static int bnxt_re_netdev_event(struct n + + rdev = bnxt_re_from_netdev(real_dev); + if (!rdev && event != NETDEV_REGISTER) +- goto exit; ++ return NOTIFY_OK; ++ + if (real_dev != netdev) + goto exit; + +@@ -1724,6 +1714,7 @@ static int bnxt_re_netdev_event(struct n + rc = bnxt_re_add_device(&rdev, real_dev); + if (!rc) + sch_work = true; ++ release = false; + break; + + case NETDEV_UNREGISTER: +@@ -1732,8 +1723,7 @@ static int bnxt_re_netdev_event(struct n + */ + if (atomic_read(&rdev->sched_count) > 0) + goto exit; +- bnxt_re_ib_uninit(rdev); +- bnxt_re_remove_device(rdev); ++ ib_unregister_device_queued(&rdev->ibdev); + break; + + default: +@@ -1755,6 +1745,8 @@ static int bnxt_re_netdev_event(struct n + } + + exit: ++ if (rdev && release) ++ ib_device_put(&rdev->ibdev); + return NOTIFY_DONE; + } + +@@ -1790,35 +1782,21 @@ err_netdev: + + static void __exit bnxt_re_mod_exit(void) + { +- struct bnxt_re_dev *rdev, *next; +- LIST_HEAD(to_be_deleted); ++ struct bnxt_re_dev *rdev; + +- mutex_lock(&bnxt_re_dev_lock); +- /* Free all adapter allocated resources */ +- if (!list_empty(&bnxt_re_dev_list)) +- list_splice_init(&bnxt_re_dev_list, &to_be_deleted); +- mutex_unlock(&bnxt_re_dev_lock); +- /* +- * Cleanup the devices in reverse order so that the VF device +- * cleanup is done before PF cleanup +- */ +- list_for_each_entry_safe_reverse(rdev, next, &to_be_deleted, list) { +- ibdev_info(&rdev->ibdev, "Unregistering Device"); +- /* +- * Flush out any scheduled tasks before destroying the +- * resources +- */ +- flush_workqueue(bnxt_re_wq); +- bnxt_re_dev_stop(rdev); +- bnxt_re_ib_uninit(rdev); +- /* Acquire the rtnl_lock as the L2 resources are freed here */ +- rtnl_lock(); +- bnxt_re_remove_device(rdev); +- rtnl_unlock(); +- } + unregister_netdevice_notifier(&bnxt_re_netdev_notifier); + if (bnxt_re_wq) + destroy_workqueue(bnxt_re_wq); ++ list_for_each_entry(rdev, &bnxt_re_dev_list, list) { ++ /* VF device removal should be called before the removal ++ * of PF device. Queue VFs unregister first, so that VFs ++ * shall be removed before the PF during the call of ++ * ib_unregister_driver. ++ */ ++ if (rdev->is_virtfn) ++ ib_unregister_device(&rdev->ibdev); ++ } ++ ib_unregister_driver(RDMA_DRIVER_BNXT_RE); + } + + module_init(bnxt_re_mod_init); diff --git a/patches.suse/RDMA-bnxt_re-Use-ib_device_try_get.patch b/patches.suse/RDMA-bnxt_re-Use-ib_device_try_get.patch new file mode 100644 index 0000000..0f403c2 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Use-ib_device_try_get.patch @@ -0,0 +1,112 @@ +From: Jason Gunthorpe +Date: Fri, 13 Mar 2020 09:33:25 -0700 +Subject: RDMA/bnxt_re: Use ib_device_try_get() +Patch-mainline: v5.7-rc1 +Git-commit: 3cae58047c1343949fb20c0e142845133ce0a074 +References: bsc#1170774 + +There are a couple places in this driver running from a work queue that +need the ib_device to be registered. Instead of using a broken internal +bit rely on the new core code to guarantee device registration. + +Link: https://lore.kernel.org/r/1584117207-2664-2-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 1 - + drivers/infiniband/hw/bnxt_re/main.c | 27 ++++++++++++++------------- + 2 files changed, 14 insertions(+), 14 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -132,7 +132,6 @@ struct bnxt_re_dev { + struct list_head list; + unsigned long flags; + #define BNXT_RE_FLAG_NETDEV_REGISTERED 0 +-#define BNXT_RE_FLAG_IBDEV_REGISTERED 1 + #define BNXT_RE_FLAG_GOT_MSIX 2 + #define BNXT_RE_FLAG_HAVE_L2_REF 3 + #define BNXT_RE_FLAG_RCFW_CHANNEL_EN 4 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1171,12 +1171,13 @@ static int bnxt_re_update_gid(struct bnx + u16 gid_idx, index; + int rc = 0; + +- if (!test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) ++ if (!ib_device_try_get(&rdev->ibdev)) + return 0; + + if (!sgid_tbl) { + ibdev_err(&rdev->ibdev, "QPLIB: SGID table not allocated"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto out; + } + + for (index = 0; index < sgid_tbl->active; index++) { +@@ -1196,7 +1197,8 @@ static int bnxt_re_update_gid(struct bnx + rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx, + rdev->qplib_res.netdev->dev_addr); + } +- ++out: ++ ib_device_put(&rdev->ibdev); + return rc; + } + +@@ -1319,7 +1321,6 @@ int bnxt_re_ib_init(struct bnxt_re_dev * + pr_err("Failed to register with IB: %#x\n", rc); + return rc; + } +- set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); + dev_info(rdev_to_dev(rdev), "Device registered successfully"); + ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, + &rdev->active_width); +@@ -1612,7 +1613,6 @@ static void bnxt_re_dealloc_driver(struc + struct bnxt_re_dev *rdev = + container_of(ib_dev, struct bnxt_re_dev, ibdev); + +- clear_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); + dev_info(rdev_to_dev(rdev), "Unregistering Device"); + + rtnl_lock(); +@@ -1630,12 +1630,7 @@ static void bnxt_re_task(struct work_str + re_work = container_of(work, struct bnxt_re_work, work); + rdev = re_work->rdev; + +- if (re_work->event != NETDEV_REGISTER && +- !test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) +- goto done; +- +- switch (re_work->event) { +- case NETDEV_REGISTER: ++ if (re_work->event == NETDEV_REGISTER) { + rc = bnxt_re_ib_init(rdev); + if (rc) { + ibdev_err(&rdev->ibdev, +@@ -1645,7 +1640,13 @@ static void bnxt_re_task(struct work_str + rtnl_unlock(); + goto exit; + } +- break; ++ goto exit; ++ } ++ ++ if (!ib_device_try_get(&rdev->ibdev)) ++ goto exit; ++ ++ switch (re_work->event) { + case NETDEV_UP: + bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, + IB_EVENT_PORT_ACTIVE); +@@ -1665,7 +1666,7 @@ static void bnxt_re_task(struct work_str + default: + break; + } +-done: ++ ib_device_put(&rdev->ibdev); + smp_mb__before_atomic(); + atomic_dec(&rdev->sched_count); + exit: diff --git a/patches.suse/RDMA-bnxt_re-Use-rdma_read_gid_hw_context-to-retriev.patch b/patches.suse/RDMA-bnxt_re-Use-rdma_read_gid_hw_context-to-retriev.patch new file mode 100644 index 0000000..f5e3495 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Use-rdma_read_gid_hw_context-to-retriev.patch @@ -0,0 +1,88 @@ +From: Selvin Xavier +Date: Wed, 19 Feb 2020 02:19:54 -0800 +Subject: RDMA/bnxt_re: Use rdma_read_gid_hw_context to retrieve HW gid index +Patch-mainline: v5.7-rc1 +Git-commit: 0a01623b74d41d91a595cbeb29e1a03648aec087 +References: bsc#1170774 + +bnxt_re HW maintains a GID table with only a single entry for the two +duplicate GID entries (v1 and v2). Driver needs to map stack gid index to +the HW table gid index. Use the new API rdma_read_gid_hw_context () to +retrieve the HW GID context to get the HW table index. + +Link: https://lore.kernel.org/r/1582107594-5180-3-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -639,6 +639,7 @@ int bnxt_re_create_ah(struct ib_ah *ib_a + const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); + struct bnxt_re_dev *rdev = pd->rdev; + const struct ib_gid_attr *sgid_attr; ++ struct bnxt_re_gid_ctx *ctx; + struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah); + u8 nw_type; + int rc; +@@ -654,19 +655,18 @@ int bnxt_re_create_ah(struct ib_ah *ib_a + /* Supply the configuration for the HW */ + memcpy(ah->qplib_ah.dgid.data, grh->dgid.raw, + sizeof(union ib_gid)); +- /* +- * If RoCE V2 is enabled, stack will have two entries for +- * each GID entry. Avoiding this duplicte entry in HW. Dividing +- * the GID index by 2 for RoCE V2 ++ sgid_attr = grh->sgid_attr; ++ /* Get the HW context of the GID. The reference ++ * of GID table entry is already taken by the caller. + */ +- ah->qplib_ah.sgid_index = grh->sgid_index / 2; ++ ctx = rdma_read_gid_hw_context(sgid_attr); ++ ah->qplib_ah.sgid_index = ctx->idx; + ah->qplib_ah.host_sgid_index = grh->sgid_index; + ah->qplib_ah.traffic_class = grh->traffic_class; + ah->qplib_ah.flow_label = grh->flow_label; + ah->qplib_ah.hop_limit = grh->hop_limit; + ah->qplib_ah.sl = rdma_ah_get_sl(ah_attr); + +- sgid_attr = grh->sgid_attr; + /* Get network header type for this GID */ + nw_type = rdma_gid_attr_network_type(sgid_attr); + ah->qplib_ah.nw_type = bnxt_re_stack_to_dev_nw_type(nw_type); +@@ -1591,6 +1591,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + const struct ib_global_route *grh = + rdma_ah_read_grh(&qp_attr->ah_attr); + const struct ib_gid_attr *sgid_attr; ++ struct bnxt_re_gid_ctx *ctx; + + qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_DGID | + CMDQ_MODIFY_QP_MODIFY_MASK_FLOW_LABEL | +@@ -1602,11 +1603,12 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + memcpy(qp->qplib_qp.ah.dgid.data, grh->dgid.raw, + sizeof(qp->qplib_qp.ah.dgid.data)); + qp->qplib_qp.ah.flow_label = grh->flow_label; +- /* If RoCE V2 is enabled, stack will have two entries for +- * each GID entry. Avoiding this duplicte entry in HW. Dividing +- * the GID index by 2 for RoCE V2 ++ sgid_attr = grh->sgid_attr; ++ /* Get the HW context of the GID. The reference ++ * of GID table entry is already taken by the caller. + */ +- qp->qplib_qp.ah.sgid_index = grh->sgid_index / 2; ++ ctx = rdma_read_gid_hw_context(sgid_attr); ++ qp->qplib_qp.ah.sgid_index = ctx->idx; + qp->qplib_qp.ah.host_sgid_index = grh->sgid_index; + qp->qplib_qp.ah.hop_limit = grh->hop_limit; + qp->qplib_qp.ah.traffic_class = grh->traffic_class; +@@ -1614,7 +1616,6 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + ether_addr_copy(qp->qplib_qp.ah.dmac, + qp_attr->ah_attr.roce.dmac); + +- sgid_attr = qp_attr->ah_attr.grh.sgid_attr; + rc = rdma_read_gid_l2_fields(sgid_attr, NULL, + &qp->qplib_qp.smac[0]); + if (rc) diff --git a/patches.suse/RDMA-bnxt_re-Using-vmalloc-requires-including-vmallo.patch b/patches.suse/RDMA-bnxt_re-Using-vmalloc-requires-including-vmallo.patch new file mode 100644 index 0000000..3dd78b0 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Using-vmalloc-requires-including-vmallo.patch @@ -0,0 +1,28 @@ +From: Jason Gunthorpe +Date: Wed, 26 Feb 2020 10:17:24 -0400 +Subject: RDMA/bnxt_re: Using vmalloc requires including vmalloc.h +Patch-mainline: v5.7-rc1 +Git-commit: 65a166201552113f9e1e8d1bb4a55a1eb70cb19c +References: bsc#1170774 + +Add it + +Fixes: 0c4dcd602817 ("RDMA/bnxt_re: Refactor hardware queue memory allocation") +Signed-off-by: Stephen Rothwell +Reviewed-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/qplib_res.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + #include "roce_hsi.h" + #include "qplib_res.h" + #include "qplib_sp.h" diff --git a/patches.suse/RDMA-bnxt_re-Wait-for-all-the-CQ-events-before-freei.patch b/patches.suse/RDMA-bnxt_re-Wait-for-all-the-CQ-events-before-freei.patch new file mode 100644 index 0000000..2760ab5 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-Wait-for-all-the-CQ-events-before-freei.patch @@ -0,0 +1,166 @@ +From: Selvin Xavier +Date: Fri, 13 Mar 2020 10:34:02 -0700 +Subject: RDMA/bnxt_re: Wait for all the CQ events before freeing CQ data + structures +Patch-mainline: v5.7-rc1 +Git-commit: b1d56fdcb66ebe6604166d71a26744d3cd03fecb +References: bsc#1170774 + +Destroy CQ command to firmware returns the num_cnq_events as a +response. This indicates the driver about the number of CQ events +generated for this CQ. Driver should wait for all these events before +freeing the CQ host structures. Also, add routine to clean all the +pending notification for the CQs getting destroyed. This avoids the +possibility of accessing the CQ data structures after its freed. + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Link: https://lore.kernel.org/r/1584120842-3200-1-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 73 +++++++++++++++++++++++++++++++ + drivers/infiniband/hw/bnxt_re/qplib_fp.h | 1 + 2 files changed, 74 insertions(+) + +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -231,6 +232,70 @@ fail: + return rc; + } + ++static void clean_nq(struct bnxt_qplib_nq *nq, struct bnxt_qplib_cq *cq) ++{ ++ struct bnxt_qplib_hwq *hwq = &nq->hwq; ++ struct nq_base *nqe, **nq_ptr; ++ int budget = nq->budget; ++ u32 sw_cons, raw_cons; ++ uintptr_t q_handle; ++ u16 type; ++ ++ spin_lock_bh(&hwq->lock); ++ /* Service the NQ until empty */ ++ raw_cons = hwq->cons; ++ while (budget--) { ++ sw_cons = HWQ_CMP(raw_cons, hwq); ++ nq_ptr = (struct nq_base **)hwq->pbl_ptr; ++ nqe = &nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]; ++ if (!NQE_CMP_VALID(nqe, raw_cons, hwq->max_elements)) ++ break; ++ ++ /* ++ * The valid test of the entry must be done first before ++ * reading any further. ++ */ ++ dma_rmb(); ++ ++ type = le16_to_cpu(nqe->info10_type) & NQ_BASE_TYPE_MASK; ++ switch (type) { ++ case NQ_BASE_TYPE_CQ_NOTIFICATION: ++ { ++ struct nq_cn *nqcne = (struct nq_cn *)nqe; ++ ++ q_handle = le32_to_cpu(nqcne->cq_handle_low); ++ q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) ++ << 32; ++ if ((unsigned long)cq == q_handle) { ++ nqcne->cq_handle_low = 0; ++ nqcne->cq_handle_high = 0; ++ cq->cnq_events++; ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ raw_cons++; ++ } ++ spin_unlock_bh(&hwq->lock); ++} ++ ++/* Wait for receiving all NQEs for this CQ and clean the NQEs associated with ++ * this CQ. ++ */ ++static void __wait_for_all_nqes(struct bnxt_qplib_cq *cq, u16 cnq_events) ++{ ++ u32 retry_cnt = 100; ++ ++ while (retry_cnt--) { ++ if (cnq_events == cq->cnq_events) ++ return; ++ usleep_range(50, 100); ++ clean_nq(cq->nq, cq); ++ } ++} ++ + static void bnxt_qplib_service_nq(unsigned long data) + { + struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data; +@@ -244,6 +309,7 @@ static void bnxt_qplib_service_nq(unsign + uintptr_t q_handle; + u16 type; + ++ spin_lock_bh(&hwq->lock); + /* Service the NQ until empty */ + raw_cons = hwq->cons; + while (budget--) { +@@ -269,6 +335,8 @@ static void bnxt_qplib_service_nq(unsign + q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) + << 32; + cq = (struct bnxt_qplib_cq *)(unsigned long)q_handle; ++ if (!cq) ++ break; + bnxt_qplib_armen_db(&cq->dbinfo, + DBC_DBC_TYPE_CQ_ARMENA); + spin_lock_bh(&cq->compl_lock); +@@ -278,6 +346,7 @@ static void bnxt_qplib_service_nq(unsign + else + dev_warn(&nq->pdev->dev, + "cqn - type 0x%x not handled\n", type); ++ cq->cnq_events++; + spin_unlock_bh(&cq->compl_lock); + break; + } +@@ -316,6 +385,7 @@ static void bnxt_qplib_service_nq(unsign + hwq->cons = raw_cons; + bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true); + } ++ spin_unlock_bh(&hwq->lock); + } + + static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance) +@@ -2003,6 +2073,7 @@ int bnxt_qplib_destroy_cq(struct bnxt_qp + struct bnxt_qplib_rcfw *rcfw = res->rcfw; + struct cmdq_destroy_cq req; + struct creq_destroy_cq_resp resp; ++ u16 total_cnq_events; + u16 cmd_flags = 0; + int rc; + +@@ -2013,6 +2084,8 @@ int bnxt_qplib_destroy_cq(struct bnxt_qp + (void *)&resp, NULL, 0); + if (rc) + return rc; ++ total_cnq_events = le16_to_cpu(resp.total_cnq_events); ++ __wait_for_all_nqes(cq, total_cnq_events); + bnxt_qplib_free_hwq(res, &cq->hwq); + return 0; + } +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -402,6 +402,7 @@ struct bnxt_qplib_cq { + * of the same QP while manipulating the flush list. + */ + spinlock_t flush_lock; /* QP flush management */ ++ u16 cnq_events; + }; + + #define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE sizeof(struct xrrq_irrq) diff --git a/patches.suse/RDMA-bnxt_re-make-bnxt_re_ib_init-static.patch b/patches.suse/RDMA-bnxt_re-make-bnxt_re_ib_init-static.patch new file mode 100644 index 0000000..59445c7 --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-make-bnxt_re_ib_init-static.patch @@ -0,0 +1,32 @@ +From: YueHaibing +Date: Mon, 30 Mar 2020 19:02:19 +0800 +Subject: RDMA/bnxt_re: make bnxt_re_ib_init static +Patch-mainline: v5.7-rc1 +Git-commit: b4d8ddf8356d8ac73fb931d16bcc661a83b2c0fe +References: bsc#1170774 + +Fix sparse warning: + +drivers/infiniband/hw/bnxt_re/main.c:1313:5: + warning: symbol 'bnxt_re_ib_init' was not declared. Should it be static? + +Link: https://lore.kernel.org/r/20200330110219.24448-1-yuehaibing@huawei.com +Signed-off-by: YueHaibing +Acked-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1310,7 +1310,7 @@ static void bnxt_re_query_hwrm_intf_vers + le16_to_cpu(resp.hwrm_intf_patch); + } + +-int bnxt_re_ib_init(struct bnxt_re_dev *rdev) ++static int bnxt_re_ib_init(struct bnxt_re_dev *rdev) + { + int rc = 0; + u32 event; diff --git a/patches.suse/RDMA-bnxt_re-use-ibdev-based-message-printing-functi.patch b/patches.suse/RDMA-bnxt_re-use-ibdev-based-message-printing-functi.patch new file mode 100644 index 0000000..85502fb --- /dev/null +++ b/patches.suse/RDMA-bnxt_re-use-ibdev-based-message-printing-functi.patch @@ -0,0 +1,1231 @@ +From: Devesh Sharma +Date: Sat, 15 Feb 2020 12:11:05 -0500 +Subject: RDMA/bnxt_re: use ibdev based message printing functions +Patch-mainline: v5.7-rc1 +Git-commit: 6ccad8483b28666bdafbb52fe94e64f41e7836be +References: bsc#1170774 + +Replacing the dev_err/dbg/warn with ibdev_err/dbg/warn. In the IB device +provider driver these functions are recommended to use. + +Currently qplib layer function calls has not been replaced due to +unavailability of ib_device pointer at that layer. + +Link: https://lore.kernel.org/r/1581786665-23705-9-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 280 +++++++++++++++---------------- + drivers/infiniband/hw/bnxt_re/main.c | 131 +++++++------- + 2 files changed, 208 insertions(+), 203 deletions(-) + +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -313,8 +313,8 @@ int bnxt_re_del_gid(const struct ib_gid_ + if (ctx->idx == 0 && + rdma_link_local_addr((struct in6_addr *)gid_to_del) && + ctx->refcnt == 1 && rdev->gsi_ctx.gsi_sqp) { +- dev_dbg(rdev_to_dev(rdev), +- "Trying to delete GID0 while QP1 is alive\n"); ++ ibdev_dbg(&rdev->ibdev, ++ "Trying to delete GID0 while QP1 is alive\n"); + return -EFAULT; + } + ctx->refcnt--; +@@ -322,8 +322,8 @@ int bnxt_re_del_gid(const struct ib_gid_ + rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, + vlan_id, true); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to remove GID: %#x", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to remove GID: %#x", rc); + } else { + ctx_tbl = sgid_tbl->ctx; + ctx_tbl[ctx->idx] = NULL; +@@ -360,7 +360,7 @@ int bnxt_re_add_gid(const struct ib_gid_ + } + + if (rc < 0) { +- dev_err(rdev_to_dev(rdev), "Failed to add GID: %#x", rc); ++ ibdev_err(&rdev->ibdev, "Failed to add GID: %#x", rc); + return rc; + } + +@@ -423,12 +423,12 @@ static int bnxt_re_bind_fence_mw(struct + wqe.bind.r_key = fence->bind_rkey; + fence->bind_rkey = ib_inc_rkey(fence->bind_rkey); + +- dev_dbg(rdev_to_dev(qp->rdev), +- "Posting bind fence-WQE: rkey: %#x QP: %d PD: %p\n", ++ ibdev_dbg(&qp->rdev->ibdev, ++ "Posting bind fence-WQE: rkey: %#x QP: %d PD: %p\n", + wqe.bind.r_key, qp->qplib_qp.id, pd); + rc = bnxt_qplib_post_send(&qp->qplib_qp, &wqe); + if (rc) { +- dev_err(rdev_to_dev(qp->rdev), "Failed to bind fence-WQE\n"); ++ ibdev_err(&qp->rdev->ibdev, "Failed to bind fence-WQE\n"); + return rc; + } + bnxt_qplib_post_send_db(&qp->qplib_qp); +@@ -479,7 +479,7 @@ static int bnxt_re_create_fence_mr(struc + DMA_BIDIRECTIONAL); + rc = dma_mapping_error(dev, dma_addr); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to dma-map fence-MR-mem\n"); ++ ibdev_err(&rdev->ibdev, "Failed to dma-map fence-MR-mem\n"); + rc = -EIO; + fence->dma_addr = 0; + goto fail; +@@ -499,7 +499,7 @@ static int bnxt_re_create_fence_mr(struc + mr->qplib_mr.flags = __from_ib_access_flags(mr_access_flags); + rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to alloc fence-HW-MR\n"); ++ ibdev_err(&rdev->ibdev, "Failed to alloc fence-HW-MR\n"); + goto fail; + } + +@@ -511,7 +511,7 @@ static int bnxt_re_create_fence_mr(struc + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, &pbl_tbl, + BNXT_RE_FENCE_PBL_SIZE, false, PAGE_SIZE); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to register fence-MR\n"); ++ ibdev_err(&rdev->ibdev, "Failed to register fence-MR\n"); + goto fail; + } + mr->ib_mr.rkey = mr->qplib_mr.rkey; +@@ -519,8 +519,8 @@ static int bnxt_re_create_fence_mr(struc + /* Create a fence MW only for kernel consumers */ + mw = bnxt_re_alloc_mw(&pd->ib_pd, IB_MW_TYPE_1, NULL); + if (IS_ERR(mw)) { +- dev_err(rdev_to_dev(rdev), +- "Failed to create fence-MW for PD: %p\n", pd); ++ ibdev_err(&rdev->ibdev, ++ "Failed to create fence-MW for PD: %p\n", pd); + rc = PTR_ERR(mw); + goto fail; + } +@@ -558,7 +558,7 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, + + pd->rdev = rdev; + if (bnxt_qplib_alloc_pd(&rdev->qplib_res.pd_tbl, &pd->qplib_pd)) { +- dev_err(rdev_to_dev(rdev), "Failed to allocate HW PD"); ++ ibdev_err(&rdev->ibdev, "Failed to allocate HW PD"); + rc = -ENOMEM; + goto fail; + } +@@ -585,16 +585,16 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, + + rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to copy user response\n"); ++ ibdev_err(&rdev->ibdev, ++ "Failed to copy user response\n"); + goto dbfail; + } + } + + if (!udata) + if (bnxt_re_create_fence_mr(pd)) +- dev_warn(rdev_to_dev(rdev), +- "Failed to create Fence-MR\n"); ++ ibdev_warn(&rdev->ibdev, ++ "Failed to create Fence-MR\n"); + return 0; + dbfail: + bnxt_qplib_dealloc_pd(&rdev->qplib_res, &rdev->qplib_res.pd_tbl, +@@ -645,7 +645,7 @@ int bnxt_re_create_ah(struct ib_ah *ib_a + int rc; + + if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) { +- dev_err(rdev_to_dev(rdev), "Failed to alloc AH: GRH not set"); ++ ibdev_err(&rdev->ibdev, "Failed to alloc AH: GRH not set"); + return -EINVAL; + } + +@@ -675,7 +675,7 @@ int bnxt_re_create_ah(struct ib_ah *ib_a + rc = bnxt_qplib_create_ah(&rdev->qplib_res, &ah->qplib_ah, + !(flags & RDMA_CREATE_AH_SLEEPABLE)); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to allocate HW AH"); ++ ibdev_err(&rdev->ibdev, "Failed to allocate HW AH"); + return rc; + } + +@@ -759,16 +759,16 @@ static int bnxt_re_destroy_gsi_sqp(struc + mutex_unlock(&rdev->qp_lock); + atomic_dec(&rdev->qp_count); + +- dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n"); ++ ibdev_dbg(&rdev->ibdev, "Destroy the shadow AH\n"); + bnxt_qplib_destroy_ah(&rdev->qplib_res, + &gsi_sah->qplib_ah, + true); + bnxt_qplib_clean_qp(&qp->qplib_qp); + +- dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n"); ++ ibdev_dbg(&rdev->ibdev, "Destroy the shadow QP\n"); + rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed"); ++ ibdev_err(&rdev->ibdev, "Destroy Shadow QP failed"); + goto fail; + } + bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp); +@@ -802,7 +802,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_ + + rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP"); ++ ibdev_err(&rdev->ibdev, "Failed to destroy HW QP"); + return rc; + } + +@@ -937,8 +937,8 @@ static struct bnxt_re_ah *bnxt_re_create + + rc = bnxt_qplib_create_ah(&rdev->qplib_res, &ah->qplib_ah, false); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to allocate HW AH for Shadow QP"); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate HW AH for Shadow QP"); + goto fail; + } + +@@ -1031,7 +1031,7 @@ static int bnxt_re_init_rq_attr(struct b + + srq = container_of(init_attr->srq, struct bnxt_re_srq, ib_srq); + if (!srq) { +- dev_err(rdev_to_dev(rdev), "SRQ not found"); ++ ibdev_err(&rdev->ibdev, "SRQ not found"); + return -EINVAL; + } + qplqp->srq = &srq->qplib_srq; +@@ -1139,8 +1139,7 @@ static int bnxt_re_init_qp_type(struct b + + qptype = __from_ib_qp_type(init_attr->qp_type); + if (qptype == IB_QPT_MAX) { +- dev_err(rdev_to_dev(rdev), "QP type 0x%x not supported", +- qptype); ++ ibdev_err(&rdev->ibdev, "QP type 0x%x not supported", qptype); + qptype = -EINVAL; + goto out; + } +@@ -1187,15 +1186,15 @@ static int bnxt_re_init_qp_attr(struct b + qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); + qplqp->dpi = &rdev->dpi_privileged; /* Doorbell page */ + if (init_attr->create_flags) +- dev_dbg(rdev_to_dev(rdev), +- "QP create flags 0x%x not supported", +- init_attr->create_flags); ++ ibdev_dbg(&rdev->ibdev, ++ "QP create flags 0x%x not supported", ++ init_attr->create_flags); + + /* Setup CQs */ + if (init_attr->send_cq) { + cq = container_of(init_attr->send_cq, struct bnxt_re_cq, ib_cq); + if (!cq) { +- dev_err(rdev_to_dev(rdev), "Send CQ not found"); ++ ibdev_err(&rdev->ibdev, "Send CQ not found"); + rc = -EINVAL; + goto out; + } +@@ -1206,7 +1205,7 @@ static int bnxt_re_init_qp_attr(struct b + if (init_attr->recv_cq) { + cq = container_of(init_attr->recv_cq, struct bnxt_re_cq, ib_cq); + if (!cq) { +- dev_err(rdev_to_dev(rdev), "Receive CQ not found"); ++ ibdev_err(&rdev->ibdev, "Receive CQ not found"); + rc = -EINVAL; + goto out; + } +@@ -1252,8 +1251,7 @@ static int bnxt_re_create_shadow_gsi(str + sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, &qp->qplib_qp); + if (!sqp) { + rc = -ENODEV; +- dev_err(rdev_to_dev(rdev), +- "Failed to create Shadow QP for QP1"); ++ ibdev_err(&rdev->ibdev, "Failed to create Shadow QP for QP1"); + goto out; + } + rdev->gsi_ctx.gsi_sqp = sqp; +@@ -1266,8 +1264,8 @@ static int bnxt_re_create_shadow_gsi(str + bnxt_qplib_destroy_qp(&rdev->qplib_res, + &sqp->qplib_qp); + rc = -ENODEV; +- dev_err(rdev_to_dev(rdev), +- "Failed to create AH entry for ShadowQP"); ++ ibdev_err(&rdev->ibdev, ++ "Failed to create AH entry for ShadowQP"); + goto out; + } + rdev->gsi_ctx.gsi_sah = sah; +@@ -1295,7 +1293,7 @@ static int bnxt_re_create_gsi_qp(struct + + rc = bnxt_qplib_create_qp1(&rdev->qplib_res, qplqp); + if (rc) { +- dev_err(rdev_to_dev(rdev), "create HW QP1 failed!"); ++ ibdev_err(&rdev->ibdev, "create HW QP1 failed!"); + goto out; + } + +@@ -1315,14 +1313,14 @@ static bool bnxt_re_test_qp_limits(struc + init_attr->cap.max_send_sge > dev_attr->max_qp_sges || + init_attr->cap.max_recv_sge > dev_attr->max_qp_sges || + init_attr->cap.max_inline_data > dev_attr->max_inline_data) { +- dev_err(rdev_to_dev(rdev), +- "Create QP failed - max exceeded! 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x", +- init_attr->cap.max_send_wr, dev_attr->max_qp_wqes, +- init_attr->cap.max_recv_wr, dev_attr->max_qp_wqes, +- init_attr->cap.max_send_sge, dev_attr->max_qp_sges, +- init_attr->cap.max_recv_sge, dev_attr->max_qp_sges, +- init_attr->cap.max_inline_data, +- dev_attr->max_inline_data); ++ ibdev_err(&rdev->ibdev, ++ "Create QP failed - max exceeded! 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x", ++ init_attr->cap.max_send_wr, dev_attr->max_qp_wqes, ++ init_attr->cap.max_recv_wr, dev_attr->max_qp_wqes, ++ init_attr->cap.max_send_sge, dev_attr->max_qp_sges, ++ init_attr->cap.max_recv_sge, dev_attr->max_qp_sges, ++ init_attr->cap.max_inline_data, ++ dev_attr->max_inline_data); + rc = false; + } + return rc; +@@ -1364,7 +1362,7 @@ struct ib_qp *bnxt_re_create_qp(struct i + } else { + rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to create HW QP"); ++ ibdev_err(&rdev->ibdev, "Failed to create HW QP"); + goto free_umem; + } + if (udata) { +@@ -1374,7 +1372,7 @@ struct ib_qp *bnxt_re_create_qp(struct i + resp.rsvd = 0; + rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); ++ ibdev_err(&rdev->ibdev, "Failed to copy QP udata"); + goto qp_destroy; + } + } +@@ -1546,7 +1544,7 @@ int bnxt_re_create_srq(struct ib_srq *ib + int rc, entries; + + if (srq_init_attr->attr.max_wr >= dev_attr->max_srq_wqes) { +- dev_err(rdev_to_dev(rdev), "Create CQ failed - max exceeded"); ++ ibdev_err(&rdev->ibdev, "Create CQ failed - max exceeded"); + rc = -EINVAL; + goto exit; + } +@@ -1581,7 +1579,7 @@ int bnxt_re_create_srq(struct ib_srq *ib + + rc = bnxt_qplib_create_srq(&rdev->qplib_res, &srq->qplib_srq); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Create HW SRQ failed!"); ++ ibdev_err(&rdev->ibdev, "Create HW SRQ failed!"); + goto fail; + } + +@@ -1591,7 +1589,7 @@ int bnxt_re_create_srq(struct ib_srq *ib + resp.srqid = srq->qplib_srq.id; + rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); + if (rc) { +- dev_err(rdev_to_dev(rdev), "SRQ copy to udata failed!"); ++ ibdev_err(&rdev->ibdev, "SRQ copy to udata failed!"); + bnxt_qplib_destroy_srq(&rdev->qplib_res, + &srq->qplib_srq); + goto fail; +@@ -1630,7 +1628,7 @@ int bnxt_re_modify_srq(struct ib_srq *ib + srq->qplib_srq.threshold = srq_attr->srq_limit; + rc = bnxt_qplib_modify_srq(&rdev->qplib_res, &srq->qplib_srq); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Modify HW SRQ failed!"); ++ ibdev_err(&rdev->ibdev, "Modify HW SRQ failed!"); + return rc; + } + /* On success, update the shadow */ +@@ -1638,8 +1636,8 @@ int bnxt_re_modify_srq(struct ib_srq *ib + /* No need to Build and send response back to udata */ + break; + default: +- dev_err(rdev_to_dev(rdev), +- "Unsupported srq_attr_mask 0x%x", srq_attr_mask); ++ ibdev_err(&rdev->ibdev, ++ "Unsupported srq_attr_mask 0x%x", srq_attr_mask); + return -EINVAL; + } + return 0; +@@ -1657,7 +1655,7 @@ int bnxt_re_query_srq(struct ib_srq *ib_ + tsrq.qplib_srq.id = srq->qplib_srq.id; + rc = bnxt_qplib_query_srq(&rdev->qplib_res, &tsrq.qplib_srq); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Query HW SRQ failed!"); ++ ibdev_err(&rdev->ibdev, "Query HW SRQ failed!"); + return rc; + } + srq_attr->max_wr = srq->qplib_srq.max_wqe; +@@ -1723,8 +1721,7 @@ static int bnxt_re_modify_shadow_qp(stru + + rc = bnxt_qplib_modify_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) +- dev_err(rdev_to_dev(rdev), +- "Failed to modify Shadow QP for QP1"); ++ ibdev_err(&rdev->ibdev, "Failed to modify Shadow QP for QP1"); + return rc; + } + +@@ -1745,15 +1742,15 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + new_qp_state = qp_attr->qp_state; + if (!ib_modify_qp_is_ok(curr_qp_state, new_qp_state, + ib_qp->qp_type, qp_attr_mask)) { +- dev_err(rdev_to_dev(rdev), +- "Invalid attribute mask: %#x specified ", +- qp_attr_mask); +- dev_err(rdev_to_dev(rdev), +- "for qpn: %#x type: %#x", +- ib_qp->qp_num, ib_qp->qp_type); +- dev_err(rdev_to_dev(rdev), +- "curr_qp_state=0x%x, new_qp_state=0x%x\n", +- curr_qp_state, new_qp_state); ++ ibdev_err(&rdev->ibdev, ++ "Invalid attribute mask: %#x specified ", ++ qp_attr_mask); ++ ibdev_err(&rdev->ibdev, ++ "for qpn: %#x type: %#x", ++ ib_qp->qp_num, ib_qp->qp_type); ++ ibdev_err(&rdev->ibdev, ++ "curr_qp_state=0x%x, new_qp_state=0x%x\n", ++ curr_qp_state, new_qp_state); + return -EINVAL; + } + qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_STATE; +@@ -1761,18 +1758,16 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + + if (!qp->sumem && + qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) { +- dev_dbg(rdev_to_dev(rdev), +- "Move QP = %p to flush list\n", +- qp); ++ ibdev_dbg(&rdev->ibdev, ++ "Move QP = %p to flush list\n", qp); + flags = bnxt_re_lock_cqs(qp); + bnxt_qplib_add_flush_qp(&qp->qplib_qp); + bnxt_re_unlock_cqs(qp, flags); + } + if (!qp->sumem && + qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) { +- dev_dbg(rdev_to_dev(rdev), +- "Move QP = %p out of flush list\n", +- qp); ++ ibdev_dbg(&rdev->ibdev, ++ "Move QP = %p out of flush list\n", qp); + flags = bnxt_re_lock_cqs(qp); + bnxt_qplib_clean_qp(&qp->qplib_qp); + bnxt_re_unlock_cqs(qp, flags); +@@ -1903,10 +1898,10 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + if (qp_attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { + if (qp_attr->max_dest_rd_atomic > + dev_attr->max_qp_init_rd_atom) { +- dev_err(rdev_to_dev(rdev), +- "max_dest_rd_atomic requested%d is > dev_max%d", +- qp_attr->max_dest_rd_atomic, +- dev_attr->max_qp_init_rd_atom); ++ ibdev_err(&rdev->ibdev, ++ "max_dest_rd_atomic requested%d is > dev_max%d", ++ qp_attr->max_dest_rd_atomic, ++ dev_attr->max_qp_init_rd_atom); + return -EINVAL; + } + +@@ -1927,8 +1922,8 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + (qp_attr->cap.max_recv_sge >= dev_attr->max_qp_sges) || + (qp_attr->cap.max_inline_data >= + dev_attr->max_inline_data)) { +- dev_err(rdev_to_dev(rdev), +- "Create QP failed - max exceeded"); ++ ibdev_err(&rdev->ibdev, ++ "Create QP failed - max exceeded"); + return -EINVAL; + } + entries = roundup_pow_of_two(qp_attr->cap.max_send_wr); +@@ -1961,7 +1956,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_q + } + rc = bnxt_qplib_modify_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to modify HW QP"); ++ ibdev_err(&rdev->ibdev, "Failed to modify HW QP"); + return rc; + } + if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) +@@ -1986,7 +1981,7 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp + + rc = bnxt_qplib_query_qp(&rdev->qplib_res, qplib_qp); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to query HW QP"); ++ ibdev_err(&rdev->ibdev, "Failed to query HW QP"); + goto out; + } + qp_attr->qp_state = __to_ib_qp_state(qplib_qp->state); +@@ -2191,7 +2186,7 @@ static int bnxt_re_build_qp1_send_v2(str + wqe->num_sge++; + + } else { +- dev_err(rdev_to_dev(qp->rdev), "QP1 buffer is empty!"); ++ ibdev_err(&qp->rdev->ibdev, "QP1 buffer is empty!"); + rc = -ENOMEM; + } + return rc; +@@ -2427,8 +2422,8 @@ static int bnxt_re_copy_inline_data(stru + + if ((sge_len + wqe->inline_len) > + BNXT_QPLIB_SWQE_MAX_INLINE_LENGTH) { +- dev_err(rdev_to_dev(rdev), +- "Inline data size requested > supported value"); ++ ibdev_err(&rdev->ibdev, ++ "Inline data size requested > supported value"); + return -EINVAL; + } + sge_len = wr->sg_list[i].length; +@@ -2488,8 +2483,8 @@ static int bnxt_re_post_send_shadow_qp(s + /* Common */ + wqe.num_sge = wr->num_sge; + if (wr->num_sge > qp->qplib_qp.sq.max_sge) { +- dev_err(rdev_to_dev(rdev), +- "Limit exceeded for Send SGEs"); ++ ibdev_err(&rdev->ibdev, ++ "Limit exceeded for Send SGEs"); + rc = -EINVAL; + goto bad; + } +@@ -2508,9 +2503,9 @@ static int bnxt_re_post_send_shadow_qp(s + rc = bnxt_qplib_post_send(&qp->qplib_qp, &wqe); + bad: + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Post send failed opcode = %#x rc = %d", +- wr->opcode, rc); ++ ibdev_err(&rdev->ibdev, ++ "Post send failed opcode = %#x rc = %d", ++ wr->opcode, rc); + break; + } + wr = wr->next; +@@ -2537,8 +2532,8 @@ int bnxt_re_post_send(struct ib_qp *ib_q + /* Common */ + wqe.num_sge = wr->num_sge; + if (wr->num_sge > qp->qplib_qp.sq.max_sge) { +- dev_err(rdev_to_dev(qp->rdev), +- "Limit exceeded for Send SGEs"); ++ ibdev_err(&qp->rdev->ibdev, ++ "Limit exceeded for Send SGEs"); + rc = -EINVAL; + goto bad; + } +@@ -2583,8 +2578,8 @@ int bnxt_re_post_send(struct ib_qp *ib_q + rc = bnxt_re_build_atomic_wqe(wr, &wqe); + break; + case IB_WR_RDMA_READ_WITH_INV: +- dev_err(rdev_to_dev(qp->rdev), +- "RDMA Read with Invalidate is not supported"); ++ ibdev_err(&qp->rdev->ibdev, ++ "RDMA Read with Invalidate is not supported"); + rc = -EINVAL; + goto bad; + case IB_WR_LOCAL_INV: +@@ -2595,8 +2590,8 @@ int bnxt_re_post_send(struct ib_qp *ib_q + break; + default: + /* Unsupported WRs */ +- dev_err(rdev_to_dev(qp->rdev), +- "WR (%#x) is not supported", wr->opcode); ++ ibdev_err(&qp->rdev->ibdev, ++ "WR (%#x) is not supported", wr->opcode); + rc = -EINVAL; + goto bad; + } +@@ -2604,9 +2599,9 @@ int bnxt_re_post_send(struct ib_qp *ib_q + rc = bnxt_qplib_post_send(&qp->qplib_qp, &wqe); + bad: + if (rc) { +- dev_err(rdev_to_dev(qp->rdev), +- "post_send failed op:%#x qps = %#x rc = %d\n", +- wr->opcode, qp->qplib_qp.state, rc); ++ ibdev_err(&qp->rdev->ibdev, ++ "post_send failed op:%#x qps = %#x rc = %d\n", ++ wr->opcode, qp->qplib_qp.state, rc); + *bad_wr = wr; + break; + } +@@ -2634,8 +2629,8 @@ static int bnxt_re_post_recv_shadow_qp(s + /* Common */ + wqe.num_sge = wr->num_sge; + if (wr->num_sge > qp->qplib_qp.rq.max_sge) { +- dev_err(rdev_to_dev(rdev), +- "Limit exceeded for Receive SGEs"); ++ ibdev_err(&rdev->ibdev, ++ "Limit exceeded for Receive SGEs"); + rc = -EINVAL; + break; + } +@@ -2671,8 +2666,8 @@ int bnxt_re_post_recv(struct ib_qp *ib_q + /* Common */ + wqe.num_sge = wr->num_sge; + if (wr->num_sge > qp->qplib_qp.rq.max_sge) { +- dev_err(rdev_to_dev(qp->rdev), +- "Limit exceeded for Receive SGEs"); ++ ibdev_err(&qp->rdev->ibdev, ++ "Limit exceeded for Receive SGEs"); + rc = -EINVAL; + *bad_wr = wr; + break; +@@ -2743,7 +2738,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq + + /* Validate CQ fields */ + if (cqe < 1 || cqe > dev_attr->max_cq_wqes) { +- dev_err(rdev_to_dev(rdev), "Failed to create CQ -max exceeded"); ++ ibdev_err(&rdev->ibdev, "Failed to create CQ -max exceeded"); + return -EINVAL; + } + +@@ -2799,7 +2794,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq + + rc = bnxt_qplib_create_cq(&rdev->qplib_res, &cq->qplib_cq); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to create HW CQ"); ++ ibdev_err(&rdev->ibdev, "Failed to create HW CQ"); + goto fail; + } + +@@ -2819,7 +2814,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq + resp.rsvd = 0; + rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to copy CQ udata"); ++ ibdev_err(&rdev->ibdev, "Failed to copy CQ udata"); + bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq); + goto c2fail; + } +@@ -3098,7 +3093,7 @@ static int bnxt_re_process_raw_qp_pkt_rx + pkt_type = bnxt_re_check_packet_type(cqe->raweth_qp1_flags, + cqe->raweth_qp1_flags2); + if (pkt_type < 0) { +- dev_err(rdev_to_dev(rdev), "Invalid packet\n"); ++ ibdev_err(&rdev->ibdev, "Invalid packet\n"); + return -EINVAL; + } + +@@ -3147,8 +3142,8 @@ static int bnxt_re_process_raw_qp_pkt_rx + + rc = bnxt_re_post_recv_shadow_qp(rdev, gsi_sqp, &rwr); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to post Rx buffers to shadow QP"); ++ ibdev_err(&rdev->ibdev, ++ "Failed to post Rx buffers to shadow QP"); + return -ENOMEM; + } + +@@ -3303,11 +3298,11 @@ static int send_phantom_wqe(struct bnxt_ + rc = bnxt_re_bind_fence_mw(lib_qp); + if (!rc) { + lib_qp->sq.phantom_wqe_cnt++; +- dev_dbg(&lib_qp->sq.hwq.pdev->dev, +- "qp %#x sq->prod %#x sw_prod %#x phantom_wqe_cnt %d\n", +- lib_qp->id, lib_qp->sq.hwq.prod, +- HWQ_CMP(lib_qp->sq.hwq.prod, &lib_qp->sq.hwq), +- lib_qp->sq.phantom_wqe_cnt); ++ ibdev_dbg(&qp->rdev->ibdev, ++ "qp %#x sq->prod %#x sw_prod %#x phantom_wqe_cnt %d\n", ++ lib_qp->id, lib_qp->sq.hwq.prod, ++ HWQ_CMP(lib_qp->sq.hwq.prod, &lib_qp->sq.hwq), ++ lib_qp->sq.phantom_wqe_cnt); + } + + spin_unlock_irqrestore(&qp->sq_lock, flags); +@@ -3330,7 +3325,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + budget = min_t(u32, num_entries, cq->max_cql); + num_entries = budget; + if (!cq->cql) { +- dev_err(rdev_to_dev(cq->rdev), "POLL CQ : no CQL to use"); ++ ibdev_err(&cq->rdev->ibdev, "POLL CQ : no CQL to use"); + goto exit; + } + cqe = &cq->cql[0]; +@@ -3343,8 +3338,8 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + qp = container_of(lib_qp, + struct bnxt_re_qp, qplib_qp); + if (send_phantom_wqe(qp) == -ENOMEM) +- dev_err(rdev_to_dev(cq->rdev), +- "Phantom failed! Scheduled to send again\n"); ++ ibdev_err(&cq->rdev->ibdev, ++ "Phantom failed! Scheduled to send again\n"); + else + sq->send_phantom = false; + } +@@ -3368,8 +3363,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + (unsigned long)(cqe->qp_handle), + struct bnxt_re_qp, qplib_qp); + if (!qp) { +- dev_err(rdev_to_dev(cq->rdev), +- "POLL CQ : bad QP handle"); ++ ibdev_err(&cq->rdev->ibdev, "POLL CQ : bad QP handle"); + continue; + } + wc->qp = &qp->ib_qp; +@@ -3434,9 +3428,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, + bnxt_re_process_res_ud_wc(qp, wc, cqe); + break; + default: +- dev_err(rdev_to_dev(cq->rdev), +- "POLL CQ : type 0x%x not handled", +- cqe->opcode); ++ ibdev_err(&cq->rdev->ibdev, ++ "POLL CQ : type 0x%x not handled", ++ cqe->opcode); + continue; + } + wc++; +@@ -3529,7 +3523,7 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr + + rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, "Dereg MR failed: %#x\n", rc); + return rc; + } + +@@ -3576,7 +3570,7 @@ struct ib_mr *bnxt_re_alloc_mr(struct ib + int rc; + + if (type != IB_MR_TYPE_MEM_REG) { +- dev_dbg(rdev_to_dev(rdev), "MR type 0x%x not supported", type); ++ ibdev_dbg(&rdev->ibdev, "MR type 0x%x not supported", type); + return ERR_PTR(-EINVAL); + } + if (max_num_sg > MAX_PBL_LVL_1_PGS) +@@ -3606,8 +3600,8 @@ struct ib_mr *bnxt_re_alloc_mr(struct ib + rc = bnxt_qplib_alloc_fast_reg_page_list(&rdev->qplib_res, + &mr->qplib_frpl, max_num_sg); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to allocate HW FR page list"); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate HW FR page list"); + goto fail_mr; + } + +@@ -3642,7 +3636,7 @@ struct ib_mw *bnxt_re_alloc_mw(struct ib + CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B); + rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mw->qplib_mw); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Allocate MW failed!"); ++ ibdev_err(&rdev->ibdev, "Allocate MW failed!"); + goto fail; + } + mw->ib_mw.rkey = mw->qplib_mw.rkey; +@@ -3663,7 +3657,7 @@ int bnxt_re_dealloc_mw(struct ib_mw *ib_ + + rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mw->qplib_mw); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Free MW failed: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, "Free MW failed: %#x\n", rc); + return rc; + } + +@@ -3715,8 +3709,8 @@ struct ib_mr *bnxt_re_reg_user_mr(struct + int umem_pgs, page_shift, rc; + + if (length > BNXT_RE_MAX_MR_SIZE) { +- dev_err(rdev_to_dev(rdev), "MR Size: %lld > Max supported:%lld\n", +- length, BNXT_RE_MAX_MR_SIZE); ++ ibdev_err(&rdev->ibdev, "MR Size: %lld > Max supported:%lld\n", ++ length, BNXT_RE_MAX_MR_SIZE); + return ERR_PTR(-ENOMEM); + } + +@@ -3731,7 +3725,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct + + rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to allocate MR"); ++ ibdev_err(&rdev->ibdev, "Failed to allocate MR"); + goto free_mr; + } + /* The fixed portion of the rkey is the same as the lkey */ +@@ -3739,7 +3733,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct + + umem = ib_umem_get(udata, start, length, mr_access_flags, 0); + if (IS_ERR(umem)) { +- dev_err(rdev_to_dev(rdev), "Failed to get umem"); ++ ibdev_err(&rdev->ibdev, "Failed to get umem"); + rc = -EFAULT; + goto free_mrw; + } +@@ -3748,7 +3742,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct + mr->qplib_mr.va = virt_addr; + umem_pgs = ib_umem_page_count(umem); + if (!umem_pgs) { +- dev_err(rdev_to_dev(rdev), "umem is invalid!"); ++ ibdev_err(&rdev->ibdev, "umem is invalid!"); + rc = -EINVAL; + goto free_umem; + } +@@ -3765,15 +3759,15 @@ struct ib_mr *bnxt_re_reg_user_mr(struct + virt_addr)); + + if (!bnxt_re_page_size_ok(page_shift)) { +- dev_err(rdev_to_dev(rdev), "umem page size unsupported!"); ++ ibdev_err(&rdev->ibdev, "umem page size unsupported!"); + rc = -EFAULT; + goto fail; + } + + if (page_shift == BNXT_RE_PAGE_SHIFT_4K && + length > BNXT_RE_MAX_MR_SIZE_LOW) { +- dev_err(rdev_to_dev(rdev), "Requested MR Sz:%llu Max sup:%llu", +- length, (u64)BNXT_RE_MAX_MR_SIZE_LOW); ++ ibdev_err(&rdev->ibdev, "Requested MR Sz:%llu Max sup:%llu", ++ length, (u64)BNXT_RE_MAX_MR_SIZE_LOW); + rc = -EINVAL; + goto fail; + } +@@ -3783,7 +3777,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, pbl_tbl, + umem_pgs, false, 1 << page_shift); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to register user MR"); ++ ibdev_err(&rdev->ibdev, "Failed to register user MR"); + goto fail; + } + +@@ -3816,12 +3810,11 @@ int bnxt_re_alloc_ucontext(struct ib_uco + u32 chip_met_rev_num = 0; + int rc; + +- dev_dbg(rdev_to_dev(rdev), "ABI version requested %u", +- ibdev->ops.uverbs_abi_ver); ++ ibdev_dbg(ibdev, "ABI version requested %u", ibdev->ops.uverbs_abi_ver); + + if (ibdev->ops.uverbs_abi_ver != BNXT_RE_ABI_VERSION) { +- dev_dbg(rdev_to_dev(rdev), " is different from the device %d ", +- BNXT_RE_ABI_VERSION); ++ ibdev_dbg(ibdev, " is different from the device %d ", ++ BNXT_RE_ABI_VERSION); + return -EPERM; + } + +@@ -3853,7 +3846,7 @@ int bnxt_re_alloc_ucontext(struct ib_uco + + rc = ib_copy_to_udata(udata, &resp, min(udata->outlen, sizeof(resp))); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to copy user context"); ++ ibdev_err(ibdev, "Failed to copy user context"); + rc = -EFAULT; + goto cfail; + } +@@ -3903,15 +3896,14 @@ int bnxt_re_mmap(struct ib_ucontext *ib_ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + PAGE_SIZE, vma->vm_page_prot)) { +- dev_err(rdev_to_dev(rdev), "Failed to map DPI"); ++ ibdev_err(&rdev->ibdev, "Failed to map DPI"); + return -EAGAIN; + } + } else { + pfn = virt_to_phys(uctx->shpg) >> PAGE_SHIFT; + if (remap_pfn_range(vma, vma->vm_start, + pfn, PAGE_SIZE, vma->vm_page_prot)) { +- dev_err(rdev_to_dev(rdev), +- "Failed to map shared page"); ++ ibdev_err(&rdev->ibdev, "Failed to map shared page"); + return -EAGAIN; + } + } +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -269,7 +269,7 @@ static void bnxt_re_start_irq(void *hand + * to f/w will timeout and that will set the + * timeout bit. + */ +- dev_err(rdev_to_dev(rdev), "Failed to re-start IRQs\n"); ++ ibdev_err(&rdev->ibdev, "Failed to re-start IRQs\n"); + return; + } + +@@ -286,8 +286,8 @@ static void bnxt_re_start_irq(void *hand + rc = bnxt_qplib_nq_start_irq(nq, indx - 1, + msix_ent[indx].vector, false); + if (rc) +- dev_warn(rdev_to_dev(rdev), +- "Failed to reinit NQ index %d\n", indx - 1); ++ ibdev_warn(&rdev->ibdev, "Failed to reinit NQ index %d\n", ++ indx - 1); + } + } + +@@ -373,9 +373,9 @@ static int bnxt_re_request_msix(struct b + goto done; + } + if (num_msix_got != num_msix_want) { +- dev_warn(rdev_to_dev(rdev), +- "Requested %d MSI-X vectors, got %d\n", +- num_msix_want, num_msix_got); ++ ibdev_warn(&rdev->ibdev, ++ "Requested %d MSI-X vectors, got %d\n", ++ num_msix_want, num_msix_got); + } + rdev->num_msix = num_msix_got; + done: +@@ -422,8 +422,8 @@ static int bnxt_re_net_ring_free(struct + sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); + rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); + if (rc) +- dev_err(rdev_to_dev(rdev), +- "Failed to free HW ring:%d :%#x", req.ring_id, rc); ++ ibdev_err(&rdev->ibdev, "Failed to free HW ring:%d :%#x", ++ req.ring_id, rc); + return rc; + } + +@@ -483,8 +483,8 @@ static int bnxt_re_net_stats_ctx_free(st + sizeof(req), DFLT_HWRM_CMD_TIMEOUT); + rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); + if (rc) +- dev_err(rdev_to_dev(rdev), +- "Failed to free HW stats context %#x", rc); ++ ibdev_err(&rdev->ibdev, "Failed to free HW stats context %#x", ++ rc); + + return rc; + } +@@ -757,8 +757,8 @@ static struct bnxt_re_dev *bnxt_re_dev_a + /* Allocate bnxt_re_dev instance here */ + rdev = ib_alloc_device(bnxt_re_dev, ibdev); + if (!rdev) { +- dev_err(NULL, "%s: bnxt_re_dev allocation failure!", +- ROCE_DRV_MODULE_NAME); ++ ibdev_err(NULL, "%s: bnxt_re_dev allocation failure!", ++ ROCE_DRV_MODULE_NAME); + return NULL; + } + /* Default values */ +@@ -887,8 +887,8 @@ static int bnxt_re_srqn_handler(struct b + int rc = 0; + + if (!srq) { +- dev_err(NULL, "%s: SRQ is NULL, SRQN not handled", +- ROCE_DRV_MODULE_NAME); ++ ibdev_err(NULL, "%s: SRQ is NULL, SRQN not handled", ++ ROCE_DRV_MODULE_NAME); + rc = -EINVAL; + goto done; + } +@@ -915,8 +915,8 @@ static int bnxt_re_cqn_handler(struct bn + qplib_cq); + + if (!cq) { +- dev_err(NULL, "%s: CQ is NULL, CQN not handled", +- ROCE_DRV_MODULE_NAME); ++ ibdev_err(NULL, "%s: CQ is NULL, CQN not handled", ++ ROCE_DRV_MODULE_NAME); + return -EINVAL; + } + if (cq->ib_cq.comp_handler) { +@@ -963,8 +963,8 @@ static int bnxt_re_init_res(struct bnxt_ + db_offt, &bnxt_re_cqn_handler, + &bnxt_re_srqn_handler); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to enable NQ with rc = 0x%x", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to enable NQ with rc = 0x%x", rc); + goto fail; + } + num_vec_enabled++; +@@ -1039,8 +1039,8 @@ static int bnxt_re_alloc_res(struct bnxt + qplib_ctx->srqc_count + 2); + rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x", +- i, rc); ++ ibdev_err(&rdev->ibdev, "Alloc Failed NQ%d rc:%#x", ++ i, rc); + goto free_nq; + } + type = bnxt_qplib_get_ring_type(rdev->chip_ctx); +@@ -1052,9 +1052,9 @@ static int bnxt_re_alloc_res(struct bnxt + rattr.lrid = rdev->msix_entries[i + 1].ring_idx; + rc = bnxt_re_net_ring_alloc(rdev, &rattr, &nq->ring_id); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to allocate NQ fw id with rc = 0x%x", +- rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate NQ fw id with rc = 0x%x", ++ rc); + bnxt_qplib_free_nq(&rdev->nq[i]); + goto free_nq; + } +@@ -1128,10 +1128,10 @@ static int bnxt_re_query_hwrm_pri2cos(st + return rc; + + if (resp.queue_cfg_info) { +- dev_warn(rdev_to_dev(rdev), +- "Asymmetric cos queue configuration detected"); +- dev_warn(rdev_to_dev(rdev), +- " on device, QoS may not be fully functional\n"); ++ ibdev_warn(&rdev->ibdev, ++ "Asymmetric cos queue configuration detected"); ++ ibdev_warn(&rdev->ibdev, ++ " on device, QoS may not be fully functional\n"); + } + qcfgmap = &resp.pri0_cos_queue_id; + tmp_map = (u8 *)cid_map; +@@ -1184,7 +1184,7 @@ static int bnxt_re_update_gid(struct bnx + return 0; + + if (!sgid_tbl) { +- dev_err(rdev_to_dev(rdev), "QPLIB: SGID table not allocated"); ++ ibdev_err(&rdev->ibdev, "QPLIB: SGID table not allocated"); + return -EINVAL; + } + +@@ -1261,7 +1261,7 @@ static int bnxt_re_setup_qos(struct bnxt + /* Get cosq id for this priority */ + rc = bnxt_re_query_hwrm_pri2cos(rdev, 0, &cid_map); + if (rc) { +- dev_warn(rdev_to_dev(rdev), "no cos for p_mask %x\n", prio_map); ++ ibdev_warn(&rdev->ibdev, "no cos for p_mask %x\n", prio_map); + return rc; + } + /* Parse CoS IDs for app priority */ +@@ -1270,8 +1270,8 @@ static int bnxt_re_setup_qos(struct bnxt + /* Config BONO. */ + rc = bnxt_qplib_map_tc2cos(&rdev->qplib_res, rdev->cosq); + if (rc) { +- dev_warn(rdev_to_dev(rdev), "no tc for cos{%x, %x}\n", +- rdev->cosq[0], rdev->cosq[1]); ++ ibdev_warn(&rdev->ibdev, "no tc for cos{%x, %x}\n", ++ rdev->cosq[0], rdev->cosq[1]); + return rc; + } + +@@ -1306,8 +1306,8 @@ static void bnxt_re_query_hwrm_intf_vers + sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); + rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to query HW version, rc = 0x%x", rc); ++ ibdev_err(&rdev->ibdev, "Failed to query HW version, rc = 0x%x", ++ rc); + return; + } + rdev->qplib_ctx.hwrm_intf_ver = +@@ -1338,8 +1338,8 @@ static void bnxt_re_ib_unreg(struct bnxt + if (test_and_clear_bit(BNXT_RE_FLAG_RCFW_CHANNEL_EN, &rdev->flags)) { + rc = bnxt_qplib_deinit_rcfw(&rdev->rcfw); + if (rc) +- dev_warn(rdev_to_dev(rdev), +- "Failed to deinitialize RCFW: %#x", rc); ++ ibdev_warn(&rdev->ibdev, ++ "Failed to deinitialize RCFW: %#x", rc); + bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); + bnxt_qplib_free_ctx(&rdev->qplib_res, &rdev->qplib_ctx); + bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); +@@ -1350,16 +1350,16 @@ static void bnxt_re_ib_unreg(struct bnxt + if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) { + rc = bnxt_re_free_msix(rdev); + if (rc) +- dev_warn(rdev_to_dev(rdev), +- "Failed to free MSI-X vectors: %#x", rc); ++ ibdev_warn(&rdev->ibdev, ++ "Failed to free MSI-X vectors: %#x", rc); + } + + bnxt_re_destroy_chip_ctx(rdev); + if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) { + rc = bnxt_re_unregister_netdev(rdev); + if (rc) +- dev_warn(rdev_to_dev(rdev), +- "Failed to unregister with netdev: %#x", rc); ++ ibdev_warn(&rdev->ibdev, ++ "Failed to unregister with netdev: %#x", rc); + } + } + +@@ -1392,14 +1392,15 @@ static int bnxt_re_ib_reg(struct bnxt_re + rc = bnxt_re_register_netdev(rdev); + if (rc) { + rtnl_unlock(); +- pr_err("Failed to register with netedev: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to register with netedev: %#x\n", rc); + return -EINVAL; + } + set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); + + rc = bnxt_re_setup_chip_ctx(rdev); + if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to get chip context\n"); ++ ibdev_err(&rdev->ibdev, "Failed to get chip context\n"); + return -EINVAL; + } + +@@ -1408,7 +1409,8 @@ static int bnxt_re_ib_reg(struct bnxt_re + + rc = bnxt_re_request_msix(rdev); + if (rc) { +- pr_err("Failed to get MSI-X vectors: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to get MSI-X vectors: %#x\n", rc); + rc = -EINVAL; + goto fail; + } +@@ -1423,7 +1425,8 @@ static int bnxt_re_ib_reg(struct bnxt_re + &rdev->qplib_ctx, + BNXT_RE_MAX_QPC_COUNT); + if (rc) { +- pr_err("Failed to allocate RCFW Channel: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate RCFW Channel: %#x\n", rc); + goto fail; + } + +@@ -1437,7 +1440,7 @@ static int bnxt_re_ib_reg(struct bnxt_re + rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; + rc = bnxt_re_net_ring_alloc(rdev, &rattr, &creq->ring_id); + if (rc) { +- pr_err("Failed to allocate CREQ: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, "Failed to allocate CREQ: %#x\n", rc); + goto free_rcfw; + } + db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX); +@@ -1446,7 +1449,8 @@ static int bnxt_re_ib_reg(struct bnxt_re + vid, db_offt, rdev->is_virtfn, + &bnxt_re_aeq_handler); + if (rc) { +- pr_err("Failed to enable RCFW channel: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, "Failed to enable RCFW channel: %#x\n", ++ rc); + goto free_ring; + } + +@@ -1460,21 +1464,24 @@ static int bnxt_re_ib_reg(struct bnxt_re + rc = bnxt_qplib_alloc_ctx(&rdev->qplib_res, &rdev->qplib_ctx, 0, + bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)); + if (rc) { +- pr_err("Failed to allocate QPLIB context: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate QPLIB context: %#x\n", rc); + goto disable_rcfw; + } + rc = bnxt_re_net_stats_ctx_alloc(rdev, + rdev->qplib_ctx.stats.dma_map, + &rdev->qplib_ctx.stats.fw_id); + if (rc) { +- pr_err("Failed to allocate stats context: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate stats context: %#x\n", rc); + goto free_ctx; + } + + rc = bnxt_qplib_init_rcfw(&rdev->rcfw, &rdev->qplib_ctx, + rdev->is_virtfn); + if (rc) { +- pr_err("Failed to initialize RCFW: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to initialize RCFW: %#x\n", rc); + goto free_sctx; + } + set_bit(BNXT_RE_FLAG_RCFW_CHANNEL_EN, &rdev->flags); +@@ -1482,13 +1489,15 @@ static int bnxt_re_ib_reg(struct bnxt_re + /* Resources based on the 'new' device caps */ + rc = bnxt_re_alloc_res(rdev); + if (rc) { +- pr_err("Failed to allocate resources: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to allocate resources: %#x\n", rc); + goto fail; + } + set_bit(BNXT_RE_FLAG_RESOURCES_ALLOCATED, &rdev->flags); + rc = bnxt_re_init_res(rdev); + if (rc) { +- pr_err("Failed to initialize resources: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to initialize resources: %#x\n", rc); + goto fail; + } + +@@ -1497,7 +1506,8 @@ static int bnxt_re_ib_reg(struct bnxt_re + if (!rdev->is_virtfn) { + rc = bnxt_re_setup_qos(rdev); + if (rc) +- pr_info("RoCE priority not yet configured\n"); ++ ibdev_info(&rdev->ibdev, ++ "RoCE priority not yet configured\n"); + + INIT_DELAYED_WORK(&rdev->worker, bnxt_re_worker); + set_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags); +@@ -1510,11 +1520,12 @@ static int bnxt_re_ib_reg(struct bnxt_re + /* Register ib dev */ + rc = bnxt_re_register_ib(rdev); + if (rc) { +- pr_err("Failed to register with IB: %#x\n", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to register with IB: %#x\n", rc); + goto fail; + } + set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); +- dev_info(rdev_to_dev(rdev), "Device registered successfully"); ++ ibdev_info(&rdev->ibdev, "Device registered successfully"); + ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, + &rdev->active_width); + set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags); +@@ -1563,7 +1574,8 @@ static int bnxt_re_dev_reg(struct bnxt_r + en_dev = bnxt_re_dev_probe(netdev); + if (IS_ERR(en_dev)) { + if (en_dev != ERR_PTR(-ENODEV)) +- pr_err("%s: Failed to probe\n", ROCE_DRV_MODULE_NAME); ++ ibdev_err(&(*rdev)->ibdev, "%s: Failed to probe\n", ++ ROCE_DRV_MODULE_NAME); + rc = PTR_ERR(en_dev); + goto exit; + } +@@ -1600,8 +1612,8 @@ static void bnxt_re_task(struct work_str + case NETDEV_REGISTER: + rc = bnxt_re_ib_reg(rdev); + if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to register with IB: %#x", rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to register with IB: %#x", rc); + bnxt_re_remove_one(rdev); + bnxt_re_dev_unreg(rdev); + goto exit; +@@ -1678,8 +1690,9 @@ static int bnxt_re_netdev_event(struct n + if (rc == -ENODEV) + break; + if (rc) { +- pr_err("Failed to register with the device %s: %#x\n", +- real_dev->name, rc); ++ ibdev_err(&rdev->ibdev, ++ "Failed to register with the device %s: %#x\n", ++ real_dev->name, rc); + break; + } + bnxt_re_init_one(rdev); +@@ -1764,7 +1777,7 @@ static void __exit bnxt_re_mod_exit(void + * cleanup is done before PF cleanup + */ + list_for_each_entry_safe_reverse(rdev, next, &to_be_deleted, list) { +- dev_info(rdev_to_dev(rdev), "Unregistering Device"); ++ ibdev_info(&rdev->ibdev, "Unregistering Device"); + /* + * Flush out any scheduled tasks before destroying the + * resources diff --git a/patches.suse/RDMA-core-Add-helper-function-to-retrieve-driver-gid.patch b/patches.suse/RDMA-core-Add-helper-function-to-retrieve-driver-gid.patch new file mode 100644 index 0000000..9f5e0ff --- /dev/null +++ b/patches.suse/RDMA-core-Add-helper-function-to-retrieve-driver-gid.patch @@ -0,0 +1,57 @@ +From: Selvin Xavier +Date: Wed, 19 Feb 2020 02:19:53 -0800 +Subject: RDMA/core: Add helper function to retrieve driver gid context from + gid attr +Patch-mainline: v5.7-rc1 +Git-commit: 779820c2e1e9251ddfdce5dd43b0bba30cd22271 +References: bsc#1170774 + +Adding a helper function to retrieve the driver gid context from the gid +attr. + +Link: https://lore.kernel.org/r/1582107594-5180-2-git-send-email-selvin.xavier@broadcom.com +Suggested-by: Jason Gunthorpe +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Acked-by: Thomas Bogendoerfer +--- + drivers/infiniband/core/cache.c | 17 +++++++++++++++++ + include/rdma/ib_cache.h | 1 + + 2 files changed, 18 insertions(+) + +--- a/drivers/infiniband/core/cache.c ++++ b/drivers/infiniband/core/cache.c +@@ -973,6 +973,23 @@ done: + EXPORT_SYMBOL(rdma_query_gid); + + /** ++ * rdma_read_gid_hw_context - Read the HW GID context from GID attribute ++ * @attr: Potinter to the GID attribute ++ * ++ * rdma_read_gid_hw_context() reads the drivers GID HW context corresponding ++ * to the SGID attr. Callers are required to already be holding the reference ++ * to an existing GID entry. ++ * ++ * Returns the HW GID context ++ * ++ */ ++void *rdma_read_gid_hw_context(const struct ib_gid_attr *attr) ++{ ++ return container_of(attr, struct ib_gid_table_entry, attr)->context; ++} ++EXPORT_SYMBOL(rdma_read_gid_hw_context); ++ ++/** + * rdma_find_gid - Returns SGID attributes if the matching GID is found. + * @device: The device to query. + * @gid: The GID value to search for. +--- a/include/rdma/ib_cache.h ++++ b/include/rdma/ib_cache.h +@@ -39,6 +39,7 @@ + + int rdma_query_gid(struct ib_device *device, u8 port_num, int index, + union ib_gid *gid); ++void *rdma_read_gid_hw_context(const struct ib_gid_attr *attr); + const struct ib_gid_attr *rdma_find_gid(struct ib_device *device, + const union ib_gid *gid, + enum ib_gid_type gid_type, diff --git a/series.conf b/series.conf index 4473f0a..d943315 100644 --- a/series.conf +++ b/series.conf @@ -10963,11 +10963,33 @@ patches.suse/XArray-Fix-xa_find_next-for-large-multi-index-entrie.patch patches.suse/XArray-Fix-xas_pause-for-large-multi-index-entries.patch patches.suse/xarray-Fix-early-termination-of-xas_for_each_marked.patch + patches.suse/RDMA-core-Add-helper-function-to-retrieve-driver-gid.patch + patches.suse/RDMA-bnxt_re-Use-rdma_read_gid_hw_context-to-retriev.patch + patches.suse/RDMA-bnxt_re-Refactor-queue-pair-creation-code.patch + patches.suse/RDMA-bnxt_re-Replace-chip-context-structure-with-poi.patch + patches.suse/RDMA-bnxt_re-Refactor-hardware-queue-memory-allocati.patch + patches.suse/RDMA-bnxt_re-Refactor-net-ring-allocation-function.patch + patches.suse/RDMA-bnxt_re-Refactor-command-queue-management-code.patch + patches.suse/RDMA-bnxt_re-Refactor-notification-queue-management-.patch + patches.suse/RDMA-bnxt_re-Refactor-doorbell-management-functions.patch + patches.suse/RDMA-bnxt_re-use-ibdev-based-message-printing-functi.patch + patches.suse/RDMA-bnxt_re-Using-vmalloc-requires-including-vmallo.patch + patches.suse/RDMA-bnxt_re-Refactor-device-add-remove-functionalit.patch + patches.suse/RDMA-bnxt_re-Use-driver_unregister-and-unregistratio.patch + patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-pg_siz.patch + patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variable-dev_at.patch + patches.suse/RDMA-bnxt_re-Remove-set-but-not-used-variables-pg-an.patch patches.suse/RDMA-mlx5-Prevent-UMR-usage-with-RO-only-when-we-hav.patch patches.suse/IB-mlx5-Optimize-u64-division-on-32-bit-arches.patch + patches.suse/RDMA-bnxt_re-Remove-a-redundant-memset.patch patches.suse/RDMA-core-Remove-the-duplicate-header-file.patch patches.suse/RDMA-hns-Fix-wrong-judgments-of-udata-outlen.patch + patches.suse/RDMA-bnxt_re-Use-ib_device_try_get.patch + patches.suse/RDMA-bnxt_re-Fix-lifetimes-in-bnxt_re_task.patch + patches.suse/RDMA-bnxt_re-Remove-unnecessary-sched-count.patch + patches.suse/RDMA-bnxt_re-Wait-for-all-the-CQ-events-before-freei.patch patches.suse/RDMA-hns-Fix-a-wrong-judgment-of-return-value.patch + patches.suse/RDMA-bnxt_re-make-bnxt_re_ib_init-static.patch patches.suse/0030-pid-Improve-the-comment-about-waiting-in-zap_pid_ns_.patch patches.suse/xfs-fix-iclog-release-error-check-race-with-shutdown.patch patches.suse/xfs-fix-use-after-free-when-aborting-corrupt-attr-in.patch