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? Jason