Beispiel #1
0
int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
				  struct bnxt_qplib_rcfw *rcfw)
{
	rcfw->pdev = pdev;
	rcfw->creq.max_elements = BNXT_QPLIB_CREQE_MAX_CNT;
	if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->creq, NULL, 0,
				      &rcfw->creq.max_elements,
				      BNXT_QPLIB_CREQE_UNITS, 0, PAGE_SIZE,
				      HWQ_TYPE_L2_CMPL)) {
		dev_err(&rcfw->pdev->dev,
			"QPLIB: HW channel CREQ allocation failed");
		goto fail;
	}
	rcfw->cmdq.max_elements = BNXT_QPLIB_CMDQE_MAX_CNT;
	if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->cmdq, NULL, 0,
				      &rcfw->cmdq.max_elements,
				      BNXT_QPLIB_CMDQE_UNITS, 0, PAGE_SIZE,
				      HWQ_TYPE_CTX)) {
		dev_err(&rcfw->pdev->dev,
			"QPLIB: HW channel CMDQ allocation failed");
		goto fail;
	}

	rcfw->crsqe_tbl = kcalloc(rcfw->cmdq.max_elements,
				  sizeof(*rcfw->crsqe_tbl), GFP_KERNEL);
	if (!rcfw->crsqe_tbl)
		goto fail;

	return 0;

fail:
	bnxt_qplib_free_rcfw_channel(rcfw);
	return -ENOMEM;
}
Beispiel #2
0
int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
					struct bnxt_qplib_frpl *frpl,
					int max_pg_ptrs)
{
	int pg_ptrs, pages, rc;

	/* Re-calculate the max to fit the HWQ allocation model */
	pg_ptrs = roundup_pow_of_two(max_pg_ptrs);
	pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
	if (!pages)
		pages++;

	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, 0,
				       &frpl->hwq.max_elements, PAGE_SIZE, 0,
				       PAGE_SIZE, HWQ_TYPE_CTX);
	if (!rc)
		frpl->max_pg_ptrs = pg_ptrs;

	return rc;
}
Beispiel #3
0
int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
		      u64 *pbl_tbl, int num_pbls, bool block)
{
	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
	struct cmdq_register_mr req;
	struct creq_register_mr_resp resp;
	u16 cmd_flags = 0, level;
	int pg_ptrs, pages, i, rc;
	dma_addr_t **pbl_ptr;
	u32 pg_size;

	if (num_pbls) {
		pg_ptrs = roundup_pow_of_two(num_pbls);
		pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
		if (!pages)
			pages++;

		if (pages > MAX_PBL_LVL_1_PGS) {
			dev_err(&res->pdev->dev, "QPLIB: SP: Reg MR pages ");
			dev_err(&res->pdev->dev,
				"requested (0x%x) exceeded max (0x%x)",
				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;
		rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL, 0,
					       &mr->hwq.max_elements,
					       PAGE_SIZE, 0, PAGE_SIZE,
					       HWQ_TYPE_CTX);
		if (rc) {
			dev_err(&res->pdev->dev,
				"SP: Reg MR memory allocation failed");
			return -ENOMEM;
		}
		/* Write to the hwq */
		pbl_ptr = (dma_addr_t **)mr->hwq.pbl_ptr;
		for (i = 0; i < num_pbls; i++)
			pbl_ptr[PTR_PG(i)][PTR_IDX(i)] =
				(pbl_tbl[i] & PAGE_MASK) | PTU_PTE_VALID;
	}

	RCFW_CMD_PREP(req, REGISTER_MR, cmd_flags);

	/* Configure the request */
	if (mr->hwq.level == PBL_LVL_MAX) {
		level = 0;
		req.pbl = 0;
		pg_size = PAGE_SIZE;
	} else {
		level = mr->hwq.level + 1;
		req.pbl = cpu_to_le64(mr->hwq.pbl[PBL_LVL_0].pg_map_arr[0]);
		pg_size = mr->hwq.pbl[PBL_LVL_0].pg_size;
	}
	req.log2_pg_size_lvl = (level << CMDQ_REGISTER_MR_LVL_SFT) |
			       ((ilog2(pg_size) <<
				 CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT) &
				CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK);
	req.access = (mr->flags & 0xFFFF);
	req.va = cpu_to_le64(mr->va);
	req.key = cpu_to_le32(mr->lkey);
	req.mr_size = cpu_to_le64(mr->total_size);

	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
					  (void *)&resp, NULL, block);
	if (rc)
		goto fail;

	return 0;

fail:
	if (mr->hwq.max_elements)
		bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
	return rc;
}