On Sat, Jan 19, 2019 at 3:23 AM Jason Gunthorpe <jgg@xxxxxxxxxxxx> wrote: > > On Thu, Jan 17, 2019 at 01:54:55PM -0500, Devesh Sharma wrote: > > The new chip series has 64 bit doorbell for notification > > queues. Thus, both control and data path event queues > > need new routines to write 64 bit doorbell. Adding the > > same. There is new doorbell interface between the chip > > and driver. Changing the chip specific data structure > > definitions. > > > > Additional significant changes are listed below > > - bnxt_re_net_ring_free/alloc takes a new argument > > - bnxt_qplib_enable_nq and enable_rcfw uses new doorbell offset > > for new chip. > > - DB mapping for NQ and CREQ now maps 8 bytes. > > - DBR_DBR_* macros renames to DBC_DBC_* > > - store nq_db_offset in a 32bit data type. > > > > Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx> > > Signed-off-by: Devesh Sharma <devesh.sharma@xxxxxxxxxxxx> > > drivers/infiniband/hw/bnxt_re/Kconfig | 1 + > > drivers/infiniband/hw/bnxt_re/ib_verbs.c | 4 +- > > drivers/infiniband/hw/bnxt_re/main.c | 85 +++++++++++++++---------- > > drivers/infiniband/hw/bnxt_re/qplib_fp.c | 99 ++++++++++++++++-------------- > > drivers/infiniband/hw/bnxt_re/qplib_fp.h | 46 ++++++++++++-- > > drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 31 +++++++--- > > drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 46 ++++++++++++-- > > drivers/infiniband/hw/bnxt_re/qplib_res.h | 13 ++++ > > drivers/infiniband/hw/bnxt_re/roce_hsi.h | 96 ++++++++++++++++------------- > > 9 files changed, 279 insertions(+), 142 deletions(-) > > > > diff --git a/drivers/infiniband/hw/bnxt_re/Kconfig b/drivers/infiniband/hw/bnxt_re/Kconfig > > index 18f5ed0..be2fdad 100644 > > +++ b/drivers/infiniband/hw/bnxt_re/Kconfig > > @@ -1,5 +1,6 @@ > > config INFINIBAND_BNXT_RE > > tristate "Broadcom Netxtreme HCA support" > > + depends on 64BIT > > depends on ETHERNET && NETDEVICES && PCI && INET && DCB > > depends on MAY_USE_DEVLINK > > select NET_VENDOR_BROADCOM > > diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c > > index 9bc637e..3e3e481 100644 > > +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c > > @@ -3299,10 +3299,10 @@ int bnxt_re_req_notify_cq(struct ib_cq *ib_cq, > > spin_lock_irqsave(&cq->cq_lock, flags); > > /* Trigger on the very next completion */ > > if (ib_cqn_flags & IB_CQ_NEXT_COMP) > > - type = DBR_DBR_TYPE_CQ_ARMALL; > > + type = DBC_DBC_TYPE_CQ_ARMALL; > > /* Trigger on the next solicited completion */ > > else if (ib_cqn_flags & IB_CQ_SOLICITED) > > - type = DBR_DBR_TYPE_CQ_ARMSE; > > + type = DBC_DBC_TYPE_CQ_ARMSE; > > > > /* Poll to see if there are missed events */ > > if ((ib_cqn_flags & IB_CQ_REPORT_MISSED_EVENTS) && > > diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c > > index 16af3f1..a837229 100644 > > +++ b/drivers/infiniband/hw/bnxt_re/main.c > > @@ -369,7 +369,8 @@ static void bnxt_re_fill_fw_msg(struct bnxt_fw_msg *fw_msg, void *msg, > > fw_msg->timeout = timeout; > > } > > > > -static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id) > > +static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, > > + u16 fw_ring_id, int type) > > { > > struct bnxt_en_dev *en_dev = rdev->en_dev; > > struct hwrm_ring_free_input req = {0}; > > @@ -383,7 +384,7 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id) > > memset(&fw_msg, 0, sizeof(fw_msg)); > > > > bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_FREE, -1, -1); > > - req.ring_type = RING_ALLOC_REQ_RING_TYPE_L2_CMPL; > > + req.ring_type = type; > > req.ring_id = cpu_to_le16(fw_ring_id); > > bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, > > sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); > > @@ -420,7 +421,7 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr, > > /* 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 = RING_ALLOC_REQ_RING_TYPE_L2_CMPL; > > + req.ring_type = type; > > req.int_mode = RING_ALLOC_REQ_INT_MODE_MSIX; > > bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, > > sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); > > @@ -884,6 +885,12 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq, > > return 0; > > } > > > > +static u32 bnxt_re_get_nqdb_offset(struct bnxt_re_dev *rdev, u16 indx) > > +{ > > + return bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? > > + 0x10000 : rdev->msix_entries[indx].db_offset; > > +} > > + > > static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev) > > { > > int i; > > @@ -897,18 +904,18 @@ static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev) > > > > static int bnxt_re_init_res(struct bnxt_re_dev *rdev) > > { > > - int rc = 0, i; > > int num_vec_enabled = 0; > > + int rc = 0, i; > > + u32 db_offt; > > > > bnxt_qplib_init_res(&rdev->qplib_res); > > > > for (i = 1; i < rdev->num_msix ; i++) { > > + db_offt = bnxt_re_get_nqdb_offset(rdev, i); > > rc = bnxt_qplib_enable_nq(rdev->en_dev->pdev, &rdev->nq[i - 1], > > i - 1, rdev->msix_entries[i].vector, > > - rdev->msix_entries[i].db_offset, > > - &bnxt_re_cqn_handler, > > + 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); > > @@ -920,17 +927,18 @@ static int bnxt_re_init_res(struct bnxt_re_dev *rdev) > > fail: > > for (i = num_vec_enabled; i >= 0; i--) > > bnxt_qplib_disable_nq(&rdev->nq[i]); > > - > > return rc; > > } > > > > static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev) > > { > > + u8 type; > > int i; > > > > 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_re_net_ring_free(rdev, rdev->nq[i].ring_id); > > bnxt_qplib_free_nq(&rdev->nq[i]); > > } > > } > > @@ -952,8 +960,11 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev) > > > > static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev) > > { > > - int rc = 0, i; > > int num_vec_created = 0; > > + dma_addr_t *pg_map; > > + int rc = 0, i; > > + int pages; > > + u8 type; > > > > /* Configure and allocate resources for qplib */ > > rdev->qplib_res.rcfw = &rdev->rcfw; > > @@ -983,13 +994,13 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev) > > i, rc); > > goto free_nq; > > } > > - rc = bnxt_re_net_ring_alloc > > - (rdev, rdev->nq[i].hwq.pbl[PBL_LVL_0].pg_map_arr, > > - rdev->nq[i].hwq.pbl[rdev->nq[i].hwq.level].pg_count, > > - HWRM_RING_ALLOC_CMPL, > > - BNXT_QPLIB_NQE_MAX_CNT - 1, > > - rdev->msix_entries[i + 1].ring_idx, > > - &rdev->nq[i].ring_id); > > + 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); > > if (rc) { > > dev_err(rdev_to_dev(rdev), > > "Failed to allocate NQ fw id with rc = 0x%x", > > @@ -1002,7 +1013,8 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev) > > return 0; > > free_nq: > > for (i = num_vec_created; i >= 0; i--) { > > - bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id); > > + 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]); > > } > > bnxt_qplib_dealloc_dpi(&rdev->qplib_res, > > @@ -1256,6 +1268,7 @@ static void bnxt_re_query_hwrm_intf_version(struct bnxt_re_dev *rdev) > > > > static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev) > > { > > + u8 type; > > int rc; > > > > if (test_and_clear_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) { > > @@ -1279,7 +1292,8 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev) > > 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); > > - bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id); > > + 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); > > } > > if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) { > > @@ -1310,9 +1324,12 @@ static void bnxt_re_worker(struct work_struct *work) > > > > static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) > > { > > - int rc; > > - > > + dma_addr_t *pg_map; > > + u32 db_offt, ridx; > > + int pages, vid; > > bool locked; > > + u8 type; > > + int rc; > > > > /* Acquire rtnl lock through out this function */ > > rtnl_lock(); > > @@ -1356,21 +1373,22 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) > > pr_err("Failed to allocate RCFW Channel: %#x\n", rc); > > goto fail; > > } > > - rc = bnxt_re_net_ring_alloc > > - (rdev, rdev->rcfw.creq.pbl[PBL_LVL_0].pg_map_arr, > > - rdev->rcfw.creq.pbl[rdev->rcfw.creq.level].pg_count, > > - HWRM_RING_ALLOC_CMPL, BNXT_QPLIB_CREQE_MAX_CNT - 1, > > - rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx, > > - &rdev->rcfw.creq_ring_id); > > + 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); > > if (rc) { > > pr_err("Failed to allocate CREQ: %#x\n", rc); > > goto free_rcfw; > > } > > - rc = bnxt_qplib_enable_rcfw_channel > > - (rdev->en_dev->pdev, &rdev->rcfw, > > - rdev->msix_entries[BNXT_RE_AEQ_IDX].vector, > > - rdev->msix_entries[BNXT_RE_AEQ_IDX].db_offset, > > - rdev->is_virtfn, &bnxt_re_aeq_handler); > > + 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, > > + vid, db_offt, rdev->is_virtfn, > > + &bnxt_re_aeq_handler); > > if (rc) { > > pr_err("Failed to enable RCFW channel: %#x\n", rc); > > goto free_ring; > > @@ -1454,7 +1472,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) > > disable_rcfw: > > bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); > > free_ring: > > - bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id); > > + 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); > > fail: > > diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c > > index b98b054..49bac02 100644 > > +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c > > @@ -244,6 +244,7 @@ static void bnxt_qplib_service_nq(unsigned long data) > > u16 type; > > int budget = nq->budget; > > uintptr_t q_handle; > > + bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); > > > > /* Service the NQ until empty */ > > raw_cons = hwq->cons; > > @@ -290,7 +291,7 @@ static void bnxt_qplib_service_nq(unsigned long data) > > q_handle |= (u64)le32_to_cpu(nqsrqe->srq_handle_high) > > << 32; > > bnxt_qplib_arm_srq((struct bnxt_qplib_srq *)q_handle, > > - DBR_DBR_TYPE_SRQ_ARMENA); > > + DBC_DBC_TYPE_SRQ_ARMENA); > > if (!nq->srqn_handler(nq, > > (struct bnxt_qplib_srq *)q_handle, > > nqsrqe->event)) > > @@ -312,7 +313,9 @@ static void bnxt_qplib_service_nq(unsigned long data) > > } > > if (hwq->cons != raw_cons) { > > hwq->cons = raw_cons; > > - NQ_DB_REARM(nq->bar_reg_iomem, hwq->cons, hwq->max_elements); > > + bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, hwq->cons, > > + hwq->max_elements, nq->ring_id, > > + gen_p5); > > } > > } > > > > @@ -336,9 +339,11 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance) > > > > 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); > > /* Mask h/w interrupt */ > > - NQ_DB(nq->bar_reg_iomem, nq->hwq.cons, nq->hwq.max_elements); > > + bnxt_qplib_ring_nq_db(nq->bar_reg_iomem, nq->hwq.cons, > > + nq->hwq.max_elements, nq->ring_id, gen_p5); > > /* Sync with last running IRQ handler */ > > synchronize_irq(nq->vector); > > if (kill) > > @@ -373,6 +378,7 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) > > 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) > > @@ -399,7 +405,8 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, > > nq->vector, nq_indx); > > } > > nq->requested = true; > > - NQ_DB_REARM(nq->bar_reg_iomem, nq->hwq.cons, nq->hwq.max_elements); > > + bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, nq->hwq.cons, > > + nq->hwq.max_elements, nq->ring_id, gen_p5); > > > > return rc; > > } > > @@ -433,7 +440,8 @@ int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, > > rc = -ENOMEM; > > goto fail; > > } > > - nq->bar_reg_iomem = ioremap_nocache(nq_base + nq->bar_reg_off, 4); > > + /* 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; > > goto fail; > > @@ -462,15 +470,17 @@ void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq) > > > > int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq) > > { > > + u8 hwq_type; > > + > > nq->pdev = pdev; > > 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, 0, > > &nq->hwq.max_elements, > > BNXT_QPLIB_MAX_NQE_ENTRY_SIZE, 0, > > - PAGE_SIZE, HWQ_TYPE_L2_CMPL)) > > + PAGE_SIZE, hwq_type)) > > return -ENOMEM; > > > > nq->budget = 8; > > @@ -481,19 +491,19 @@ int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq) > > static void bnxt_qplib_arm_srq(struct bnxt_qplib_srq *srq, u32 arm_type) > > { > > struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; > > - struct dbr_dbr db_msg = { 0 }; > > + struct dbc_dbc db_msg = { 0 }; > > void __iomem *db; > > u32 sw_prod = 0; > > > > /* Ring DB */ > > - sw_prod = (arm_type == DBR_DBR_TYPE_SRQ_ARM) ? srq->threshold : > > - HWQ_CMP(srq_hwq->prod, srq_hwq); > > - db_msg.index = cpu_to_le32((sw_prod << DBR_DBR_INDEX_SFT) & > > - DBR_DBR_INDEX_MASK); > > - db_msg.type_xid = cpu_to_le32(((srq->id << DBR_DBR_XID_SFT) & > > - DBR_DBR_XID_MASK) | arm_type); > > - db = (arm_type == DBR_DBR_TYPE_SRQ_ARMENA) ? > > - srq->dbr_base : srq->dpi->dbr; > > + sw_prod = (arm_type == DBC_DBC_TYPE_SRQ_ARM) ? > > + srq->threshold : HWQ_CMP(srq_hwq->prod, srq_hwq); > > + db_msg.index = cpu_to_le32((sw_prod << DBC_DBC_INDEX_SFT) & > > + DBC_DBC_INDEX_MASK); > > + db_msg.type_path_xid = cpu_to_le32(((srq->id << DBC_DBC_XID_SFT) & > > + DBC_DBC_XID_MASK) | arm_type); > > + db = (arm_type == DBC_DBC_TYPE_SRQ_ARMENA) ? srq->dbr_base : > > + srq->dpi->dbr; > > wmb(); /* barrier before db ring */ > > __iowrite64_copy(db, &db_msg, sizeof(db_msg) / sizeof(u64)); > > If the driver now requires writeq() why not use it for all these > __iowrite64_copy's too? Okay, sure > > Jason