Re: [for-next V3 2/7] RDMA/bnxt_re: Add 64bit doorbells for 57500 series

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux