RDMA/bnxt_re: Refactor hardware queue memory allocation

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 <nareshkumar.pbs@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Devesh Sharma 2020-02-15 12:11:00 -05:00 committed by Jason Gunthorpe
parent 0cfb329db9
commit 0c4dcd6028
9 changed files with 523 additions and 330 deletions

View File

@ -871,9 +871,11 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
return PTR_ERR(umem); return PTR_ERR(umem);
qp->sumem = 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.npages = ib_umem_num_pages(umem);
qplib_qp->sq.sg_info.nmap = umem->nmap; 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; qplib_qp->qp_handle = ureq.qp_handle;
if (!qp->qplib_qp.srq) { if (!qp->qplib_qp.srq) {
@ -884,9 +886,11 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
if (IS_ERR(umem)) if (IS_ERR(umem))
goto rqfail; goto rqfail;
qp->rumem = umem; 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.npages = ib_umem_num_pages(umem);
qplib_qp->rq.sg_info.nmap = umem->nmap; 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; qplib_qp->dpi = &cntx->dpi;
@ -976,6 +980,8 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
qp->qplib_qp.sq.max_sge = 2; qp->qplib_qp.sq.max_sge = 2;
/* Q full delta can be 1 since it is internal QP */ /* Q full delta can be 1 since it is internal QP */
qp->qplib_qp.sq.q_full_delta = 1; 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.scq = qp1_qp->scq;
qp->qplib_qp.rcq = qp1_qp->rcq; qp->qplib_qp.rcq = qp1_qp->rcq;
@ -984,6 +990,8 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge; qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge;
/* Q full delta can be 1 since it is internal QP */ /* Q full delta can be 1 since it is internal QP */
qp->qplib_qp.rq.q_full_delta = 1; 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; qp->qplib_qp.mtu = qp1_qp->mtu;
@ -1043,6 +1051,8 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
if (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 = dev_attr->max_qp_sges;
} }
qplqp->rq.sg_info.pgsize = PAGE_SIZE;
qplqp->rq.sg_info.pgshft = PAGE_SHIFT;
return 0; return 0;
} }
@ -1095,6 +1105,8 @@ static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
* unexpected Queue full condition * unexpected Queue full condition
*/ */
qplqp->sq.q_full_delta -= 1; 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, static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,
@ -1511,9 +1523,11 @@ static int bnxt_re_init_user_srq(struct bnxt_re_dev *rdev,
return PTR_ERR(umem); return PTR_ERR(umem);
srq->umem = 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.npages = ib_umem_num_pages(umem);
qplib_srq->sg_info.nmap = umem->nmap; 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->srq_handle = ureq.srq_handle;
qplib_srq->dpi = &cntx->dpi; qplib_srq->dpi = &cntx->dpi;
@ -2368,7 +2382,7 @@ static int bnxt_re_build_reg_wqe(const struct ib_reg_wr *wr,
wqe->frmr.pbl_dma_ptr = qplib_frpl->hwq.pbl_dma_ptr[0]; wqe->frmr.pbl_dma_ptr = qplib_frpl->hwq.pbl_dma_ptr[0];
wqe->frmr.page_list = mr->pages; wqe->frmr.page_list = mr->pages;
wqe->frmr.page_list_len = mr->npages; 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; wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR;
/* Need unconditional fence for reg_mr /* Need unconditional fence for reg_mr
@ -2742,6 +2756,8 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
if (entries > dev_attr->max_cq_wqes + 1) if (entries > dev_attr->max_cq_wqes + 1)
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) { if (udata) {
struct bnxt_re_cq_req req; struct bnxt_re_cq_req req;
struct bnxt_re_ucontext *uctx = rdma_udata_to_drv_context( struct bnxt_re_ucontext *uctx = rdma_udata_to_drv_context(
@ -2758,7 +2774,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
rc = PTR_ERR(cq->umem); rc = PTR_ERR(cq->umem);
goto fail; 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.npages = ib_umem_num_pages(cq->umem);
cq->qplib_cq.sg_info.nmap = cq->umem->nmap; cq->qplib_cq.sg_info.nmap = cq->umem->nmap;
cq->qplib_cq.dpi = &uctx->dpi; cq->qplib_cq.dpi = &uctx->dpi;

View File

@ -90,6 +90,8 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
rdev->chip_ctx = NULL; rdev->chip_ctx = NULL;
rdev->rcfw.res = NULL; rdev->rcfw.res = NULL;
rdev->qplib_res.cctx = NULL; rdev->qplib_res.cctx = NULL;
rdev->qplib_res.pdev = NULL;
rdev->qplib_res.netdev = NULL;
kfree(chip_ctx); kfree(chip_ctx);
} }
@ -151,7 +153,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq); 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++) 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]; rdev->dev_attr.tqm_alloc_reqs[i];
} }
@ -982,8 +984,8 @@ static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev)
for (i = 0; i < rdev->num_msix - 1; 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); bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type);
rdev->nq[i].res = NULL;
bnxt_qplib_free_nq(&rdev->nq[i]); bnxt_qplib_free_nq(&rdev->nq[i]);
rdev->nq[i].res = NULL;
} }
} }
@ -1032,7 +1034,7 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
rdev->nq[i].res = &rdev->qplib_res; rdev->nq[i].res = &rdev->qplib_res;
rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT + rdev->nq[i].hwq.max_elements = BNXT_RE_MAX_CQ_COUNT +
BNXT_RE_MAX_SRQC_COUNT + 2; 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) { if (rc) {
dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x", dev_err(rdev_to_dev(rdev), "Alloc Failed NQ%d rc:%#x",
i, rc); i, rc);
@ -1056,7 +1058,7 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
} }
return 0; return 0;
free_nq: 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); type = bnxt_qplib_get_ring_type(rdev->chip_ctx);
bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type); bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, type);
bnxt_qplib_free_nq(&rdev->nq[i]); bnxt_qplib_free_nq(&rdev->nq[i]);
@ -1335,7 +1337,7 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev)
dev_warn(rdev_to_dev(rdev), dev_warn(rdev_to_dev(rdev),
"Failed to deinitialize RCFW: %#x", rc); "Failed to deinitialize RCFW: %#x", rc);
bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); 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); 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_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, type);
@ -1411,7 +1413,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
/* Establish RCFW Communication Channel to initialize the context /* Establish RCFW Communication Channel to initialize the context
* memory for the function and all child VFs * 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, &rdev->qplib_ctx,
BNXT_RE_MAX_QPC_COUNT); BNXT_RE_MAX_QPC_COUNT);
if (rc) { if (rc) {
@ -1432,7 +1434,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
} }
db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX); db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX);
vid = rdev->msix_entries[BNXT_RE_AEQ_IDX].vector; 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, vid, db_offt, rdev->is_virtfn,
&bnxt_re_aeq_handler); &bnxt_re_aeq_handler);
if (rc) { if (rc) {
@ -1447,7 +1449,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
bnxt_re_set_resource_limits(rdev); 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)); bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx));
if (rc) { if (rc) {
pr_err("Failed to allocate QPLIB context: %#x\n", rc); pr_err("Failed to allocate QPLIB context: %#x\n", rc);
@ -1514,7 +1516,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
free_sctx: free_sctx:
bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id); bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
free_ctx: 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: disable_rcfw:
bnxt_qplib_disable_rcfw_channel(&rdev->rcfw); bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
free_ring: free_ring:

View File

@ -464,26 +464,33 @@ fail:
void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq) void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq)
{ {
if (nq->hwq.max_elements) { 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; 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 || if (!nq->hwq.max_elements ||
nq->hwq.max_elements > BNXT_QPLIB_NQE_MAX_CNT) nq->hwq.max_elements > BNXT_QPLIB_NQE_MAX_CNT)
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; nq->budget = 8;
return 0; return 0;
} }
@ -526,24 +533,26 @@ void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
kfree(srq->swq); kfree(srq->swq);
if (rc) if (rc)
return; 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, int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
struct bnxt_qplib_srq *srq) struct bnxt_qplib_srq *srq)
{ {
struct bnxt_qplib_rcfw *rcfw = res->rcfw; 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 creq_create_srq_resp resp;
struct cmdq_create_srq req;
struct bnxt_qplib_pbl *pbl; struct bnxt_qplib_pbl *pbl;
u16 cmd_flags = 0; u16 cmd_flags = 0;
int rc, idx; int rc, idx;
srq->hwq.max_elements = srq->max_wqe; hwq_attr.res = res;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &srq->hwq, &srq->sg_info, hwq_attr.sginfo = &srq->sg_info;
&srq->hwq.max_elements, hwq_attr.depth = srq->max_wqe;
BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0, hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE;
PAGE_SIZE, HWQ_TYPE_QUEUE); hwq_attr.type = HWQ_TYPE_QUEUE;
rc = bnxt_qplib_alloc_init_hwq(&srq->hwq, &hwq_attr);
if (rc) if (rc)
goto exit; goto exit;
@ -602,7 +611,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
return 0; return 0;
fail: fail:
bnxt_qplib_free_hwq(res->pdev, &srq->hwq); bnxt_qplib_free_hwq(res, &srq->hwq);
kfree(srq->swq); kfree(srq->swq);
exit: exit:
return rc; return rc;
@ -721,15 +730,16 @@ done:
/* QP */ /* QP */
int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *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 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 *sq = &qp->sq;
struct bnxt_qplib_q *rq = &qp->rq; 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; u16 cmd_flags = 0;
u32 qp_flags = 0; u32 qp_flags = 0;
int rc;
RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags); RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags);
@ -739,11 +749,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
req.qp_handle = cpu_to_le64(qp->qp_handle); req.qp_handle = cpu_to_le64(qp->qp_handle);
/* SQ */ /* SQ */
sq->hwq.max_elements = sq->max_wqe; hwq_attr.res = res;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &sq->hwq, NULL, hwq_attr.sginfo = &sq->sg_info;
&sq->hwq.max_elements, hwq_attr.depth = sq->max_wqe;
BNXT_QPLIB_MAX_SQE_ENTRY_SIZE, 0, hwq_attr.stride = BNXT_QPLIB_MAX_SQE_ENTRY_SIZE;
PAGE_SIZE, HWQ_TYPE_QUEUE); hwq_attr.type = HWQ_TYPE_QUEUE;
rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
if (rc) if (rc)
goto exit; goto exit;
@ -778,11 +789,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
/* RQ */ /* RQ */
if (rq->max_wqe) { if (rq->max_wqe) {
rq->hwq.max_elements = qp->rq.max_wqe; hwq_attr.res = res;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, NULL, hwq_attr.sginfo = &rq->sg_info;
&rq->hwq.max_elements, hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE;
BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0, hwq_attr.depth = qp->rq.max_wqe;
PAGE_SIZE, HWQ_TYPE_QUEUE); hwq_attr.type = HWQ_TYPE_QUEUE;
rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
if (rc) if (rc)
goto fail_sq; goto fail_sq;
@ -848,10 +860,10 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
fail: fail:
bnxt_qplib_free_qp_hdr_buf(res, qp); bnxt_qplib_free_qp_hdr_buf(res, qp);
fail_rq: fail_rq:
bnxt_qplib_free_hwq(res->pdev, &rq->hwq); bnxt_qplib_free_hwq(res, &rq->hwq);
kfree(rq->swq); kfree(rq->swq);
fail_sq: fail_sq:
bnxt_qplib_free_hwq(res->pdev, &sq->hwq); bnxt_qplib_free_hwq(res, &sq->hwq);
kfree(sq->swq); kfree(sq->swq);
exit: exit:
return rc; return rc;
@ -860,7 +872,9 @@ exit:
int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) 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_rcfw *rcfw = res->rcfw;
struct bnxt_qplib_hwq_attr hwq_attr = {};
unsigned long int psn_search, poff = 0; unsigned long int psn_search, poff = 0;
struct bnxt_qplib_sg_info sginfo = {};
struct sq_psn_search **psn_search_ptr; struct sq_psn_search **psn_search_ptr;
struct bnxt_qplib_q *sq = &qp->sq; struct bnxt_qplib_q *sq = &qp->sq;
struct bnxt_qplib_q *rq = &qp->rq; struct bnxt_qplib_q *rq = &qp->rq;
@ -887,12 +901,15 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
sizeof(struct sq_psn_search_ext) : sizeof(struct sq_psn_search_ext) :
sizeof(struct sq_psn_search); 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, hwq_attr.res = res;
&sq->hwq.max_elements, hwq_attr.sginfo = &sq->sg_info;
BNXT_QPLIB_MAX_SQE_ENTRY_SIZE, hwq_attr.stride = BNXT_QPLIB_MAX_SQE_ENTRY_SIZE;
psn_sz, hwq_attr.depth = sq->max_wqe;
PAGE_SIZE, HWQ_TYPE_QUEUE); 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) if (rc)
goto exit; goto exit;
@ -956,12 +973,14 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
/* RQ */ /* RQ */
if (rq->max_wqe) { if (rq->max_wqe) {
rq->hwq.max_elements = rq->max_wqe; hwq_attr.res = res;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &rq->hwq, hwq_attr.sginfo = &rq->sg_info;
&rq->sg_info, hwq_attr.stride = BNXT_QPLIB_MAX_RQE_ENTRY_SIZE;
&rq->hwq.max_elements, hwq_attr.depth = rq->max_wqe;
BNXT_QPLIB_MAX_RQE_ENTRY_SIZE, 0, hwq_attr.aux_stride = 0;
PAGE_SIZE, HWQ_TYPE_QUEUE); hwq_attr.aux_depth = 0;
hwq_attr.type = HWQ_TYPE_QUEUE;
rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
if (rc) if (rc)
goto fail_sq; goto fail_sq;
@ -1029,10 +1048,17 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
req_size = xrrq->max_elements * req_size = xrrq->max_elements *
BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE + PAGE_SIZE - 1; BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE + PAGE_SIZE - 1;
req_size &= ~(PAGE_SIZE - 1); req_size &= ~(PAGE_SIZE - 1);
rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL, sginfo.pgsize = req_size;
&xrrq->max_elements, sginfo.pgshft = PAGE_SHIFT;
BNXT_QPLIB_MAX_ORRQE_ENTRY_SIZE,
0, req_size, HWQ_TYPE_CTX); 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) if (rc)
goto fail_buf_free; goto fail_buf_free;
pbl = &xrrq->pbl[PBL_LVL_0]; pbl = &xrrq->pbl[PBL_LVL_0];
@ -1044,11 +1070,10 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
req_size = xrrq->max_elements * req_size = xrrq->max_elements *
BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE + PAGE_SIZE - 1; BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE + PAGE_SIZE - 1;
req_size &= ~(PAGE_SIZE - 1); req_size &= ~(PAGE_SIZE - 1);
sginfo.pgsize = req_size;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, xrrq, NULL, hwq_attr.depth = xrrq->max_elements;
&xrrq->max_elements, hwq_attr.stride = BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE;
BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE, rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr);
0, req_size, HWQ_TYPE_CTX);
if (rc) if (rc)
goto fail_orrq; goto fail_orrq;
@ -1074,17 +1099,17 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
fail: fail:
if (qp->irrq.max_elements) if (qp->irrq.max_elements)
bnxt_qplib_free_hwq(res->pdev, &qp->irrq); bnxt_qplib_free_hwq(res, &qp->irrq);
fail_orrq: fail_orrq:
if (qp->orrq.max_elements) if (qp->orrq.max_elements)
bnxt_qplib_free_hwq(res->pdev, &qp->orrq); bnxt_qplib_free_hwq(res, &qp->orrq);
fail_buf_free: fail_buf_free:
bnxt_qplib_free_qp_hdr_buf(res, qp); bnxt_qplib_free_qp_hdr_buf(res, qp);
fail_rq: fail_rq:
bnxt_qplib_free_hwq(res->pdev, &rq->hwq); bnxt_qplib_free_hwq(res, &rq->hwq);
kfree(rq->swq); kfree(rq->swq);
fail_sq: fail_sq:
bnxt_qplib_free_hwq(res->pdev, &sq->hwq); bnxt_qplib_free_hwq(res, &sq->hwq);
kfree(sq->swq); kfree(sq->swq);
exit: exit:
return rc; return rc;
@ -1440,16 +1465,16 @@ void bnxt_qplib_free_qp_res(struct bnxt_qplib_res *res,
struct bnxt_qplib_qp *qp) struct bnxt_qplib_qp *qp)
{ {
bnxt_qplib_free_qp_hdr_buf(res, 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); 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); kfree(qp->rq.swq);
if (qp->irrq.max_elements) 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) 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 bnxt_qplib_cq *cq, u32 arm_type)
int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq) int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
{ {
struct bnxt_qplib_rcfw *rcfw = res->rcfw; 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 creq_create_cq_resp resp;
struct cmdq_create_cq req;
struct bnxt_qplib_pbl *pbl; struct bnxt_qplib_pbl *pbl;
u16 cmd_flags = 0; u16 cmd_flags = 0;
int rc; int rc;
cq->hwq.max_elements = cq->max_wqe; hwq_attr.res = res;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &cq->hwq, &cq->sg_info, hwq_attr.depth = cq->max_wqe;
&cq->hwq.max_elements, hwq_attr.stride = sizeof(struct cq_base);
BNXT_QPLIB_MAX_CQE_ENTRY_SIZE, 0, hwq_attr.type = HWQ_TYPE_QUEUE;
PAGE_SIZE, HWQ_TYPE_QUEUE); hwq_attr.sginfo = &cq->sg_info;
rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr);
if (rc) if (rc)
goto exit; goto exit;
@ -1988,7 +2015,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
return 0; return 0;
fail: fail:
bnxt_qplib_free_hwq(res->pdev, &cq->hwq); bnxt_qplib_free_hwq(res, &cq->hwq);
exit: exit:
return rc; return rc;
} }
@ -2008,7 +2035,7 @@ int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
(void *)&resp, NULL, 0); (void *)&resp, NULL, 0);
if (rc) if (rc)
return rc; return rc;
bnxt_qplib_free_hwq(res->pdev, &cq->hwq); bnxt_qplib_free_hwq(res, &cq->hwq);
return 0; return 0;
} }

View File

@ -550,7 +550,7 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq); 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_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type);
void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq); 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_add_flush_qp(struct bnxt_qplib_qp *qp);
void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp, void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,
unsigned long *flags); unsigned long *flags);

View File

@ -520,9 +520,10 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
level = ctx->tim_tbl.level; level = ctx->tim_tbl.level;
req.tim_pg_size_tim_lvl = (level << CMDQ_INITIALIZE_FW_TIM_LVL_SFT) | req.tim_pg_size_tim_lvl = (level << CMDQ_INITIALIZE_FW_TIM_LVL_SFT) |
__get_pbl_pg_idx(&ctx->tim_tbl.pbl[level]); __get_pbl_pg_idx(&ctx->tim_tbl.pbl[level]);
level = ctx->tqm_pde_level; level = ctx->tqm_ctx.pde.level;
req.tqm_pg_size_tqm_lvl = (level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) | req.tqm_pg_size_tqm_lvl =
__get_pbl_pg_idx(&ctx->tqm_pde.pbl[level]); (level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) |
__get_pbl_pg_idx(&ctx->tqm_ctx.pde.pbl[level]);
req.qpc_page_dir = req.qpc_page_dir =
cpu_to_le64(ctx->qpc_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); 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_qplib_rcfw *rcfw,
req.tim_page_dir = req.tim_page_dir =
cpu_to_le64(ctx->tim_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); cpu_to_le64(ctx->tim_tbl.pbl[PBL_LVL_0].pg_map_arr[0]);
req.tqm_page_dir = 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_qp = cpu_to_le32(ctx->qpc_tbl.max_elements);
req.number_of_mrw = cpu_to_le32(ctx->mrw_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 bnxt_qplib_rcfw *rcfw)
{ {
kfree(rcfw->qp_tbl); kfree(rcfw->qp_tbl);
kfree(rcfw->crsqe_tbl); kfree(rcfw->crsqe_tbl);
bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->cmdq); bnxt_qplib_free_hwq(rcfw->res, &rcfw->cmdq);
bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->creq); bnxt_qplib_free_hwq(rcfw->res, &rcfw->creq);
rcfw->pdev = NULL; 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_rcfw *rcfw,
struct bnxt_qplib_ctx *ctx, struct bnxt_qplib_ctx *ctx,
int qp_tbl_sz) int qp_tbl_sz)
{ {
u8 hwq_type; struct bnxt_qplib_hwq_attr hwq_attr = {};
struct bnxt_qplib_sg_info sginfo = {};
rcfw->pdev = pdev; rcfw->pdev = res->pdev;
rcfw->creq.max_elements = BNXT_QPLIB_CREQE_MAX_CNT; rcfw->res = res;
hwq_type = bnxt_qplib_get_hwq_type(rcfw->res);
if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->creq, NULL, sginfo.pgsize = PAGE_SIZE;
&rcfw->creq.max_elements, sginfo.pgshft = PAGE_SHIFT;
BNXT_QPLIB_CREQE_UNITS,
0, PAGE_SIZE, hwq_type)) { 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, dev_err(&rcfw->pdev->dev,
"HW channel CREQ allocation failed\n"); "HW channel CREQ allocation failed\n");
goto fail; goto fail;
@ -591,13 +599,11 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
else else
rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192; rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
rcfw->cmdq.max_elements = rcfw->cmdq_depth; sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth);
if (bnxt_qplib_alloc_init_hwq hwq_attr.depth = rcfw->cmdq_depth;
(rcfw->pdev, &rcfw->cmdq, NULL, hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS;
&rcfw->cmdq.max_elements, hwq_attr.type = HWQ_TYPE_CTX;
BNXT_QPLIB_CMDQE_UNITS, 0, if (bnxt_qplib_alloc_init_hwq(&rcfw->cmdq, &hwq_attr)) {
bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth),
HWQ_TYPE_CTX)) {
dev_err(&rcfw->pdev->dev, dev_err(&rcfw->pdev->dev,
"HW channel CMDQ allocation failed\n"); "HW channel CMDQ allocation failed\n");
goto fail; goto fail;
@ -690,8 +696,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
return 0; return 0;
} }
int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev, int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
struct bnxt_qplib_rcfw *rcfw,
int msix_vector, int msix_vector,
int cp_bar_reg_off, int virt_fn, int cp_bar_reg_off, int virt_fn,
int (*aeq_handler)(struct bnxt_qplib_rcfw *, int (*aeq_handler)(struct bnxt_qplib_rcfw *,
@ -699,10 +704,12 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
{ {
resource_size_t res_base; resource_size_t res_base;
struct cmdq_init init; struct cmdq_init init;
struct pci_dev *pdev;
u16 bmap_size; u16 bmap_size;
int rc; int rc;
/* General */ /* General */
pdev = rcfw->pdev;
rcfw->seq_num = 0; rcfw->seq_num = 0;
set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags); set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags);
bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long); bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth) * sizeof(unsigned long);

View File

@ -268,7 +268,7 @@ struct bnxt_qplib_rcfw {
}; };
void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *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_rcfw *rcfw,
struct bnxt_qplib_ctx *ctx, struct bnxt_qplib_ctx *ctx,
int qp_tbl_sz); int qp_tbl_sz);
@ -276,8 +276,7 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill);
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw); 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, int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
bool need_init); bool need_init);
int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev, int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
struct bnxt_qplib_rcfw *rcfw,
int msix_vector, int msix_vector,
int cp_bar_reg_off, int virt_fn, int cp_bar_reg_off, int virt_fn,
int (*aeq_handler)(struct bnxt_qplib_rcfw *, int (*aeq_handler)(struct bnxt_qplib_rcfw *,

View File

@ -55,9 +55,10 @@ static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev,
struct bnxt_qplib_stats *stats); struct bnxt_qplib_stats *stats);
/* PBL */ /* 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) bool is_umem)
{ {
struct pci_dev *pdev = res->pdev;
int i; int i;
if (!is_umem) { if (!is_umem) {
@ -74,35 +75,57 @@ static void __free_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl,
pbl->pg_arr[i] = NULL; pbl->pg_arr[i] = NULL;
} }
} }
kfree(pbl->pg_arr); vfree(pbl->pg_arr);
pbl->pg_arr = NULL; pbl->pg_arr = NULL;
kfree(pbl->pg_map_arr); vfree(pbl->pg_map_arr);
pbl->pg_map_arr = NULL; pbl->pg_map_arr = NULL;
pbl->pg_count = 0; pbl->pg_count = 0;
pbl->pg_size = 0; pbl->pg_size = 0;
} }
static int __alloc_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl, static void bnxt_qplib_fill_user_dma_pages(struct bnxt_qplib_pbl *pbl,
struct scatterlist *sghead, u32 pages, struct bnxt_qplib_sg_info *sginfo)
u32 nmaps, u32 pg_size)
{ {
struct scatterlist *sghead = sginfo->sghead;
struct sg_dma_page_iter sg_iter; 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; bool is_umem = false;
u32 pages, pg_size;
int i; int i;
if (sginfo->nopte)
return 0;
pages = sginfo->npages;
pg_size = sginfo->pgsize;
sghead = sginfo->sghead;
/* page ptr arrays */ /* page ptr arrays */
pbl->pg_arr = kcalloc(pages, sizeof(void *), GFP_KERNEL); pbl->pg_arr = vmalloc(pages * sizeof(void *));
if (!pbl->pg_arr) if (!pbl->pg_arr)
return -ENOMEM; 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) { if (!pbl->pg_map_arr) {
kfree(pbl->pg_arr); vfree(pbl->pg_arr);
pbl->pg_arr = NULL; pbl->pg_arr = NULL;
return -ENOMEM; return -ENOMEM;
} }
pbl->pg_count = 0; pbl->pg_count = 0;
pbl->pg_size = pg_size; pbl->pg_size = sginfo->pgsize;
if (!sghead) { if (!sghead) {
for (i = 0; i < pages; i++) { for (i = 0; i < pages; i++) {
@ -115,25 +138,19 @@ static int __alloc_pbl(struct pci_dev *pdev, struct bnxt_qplib_pbl *pbl,
pbl->pg_count++; pbl->pg_count++;
} }
} else { } else {
i = 0;
is_umem = true; is_umem = true;
for_each_sg_dma_page(sghead, &sg_iter, nmaps, 0) { bnxt_qplib_fill_user_dma_pages(pbl, sginfo);
pbl->pg_map_arr[i] = sg_page_iter_dma_address(&sg_iter);
pbl->pg_arr[i] = NULL;
pbl->pg_count++;
i++;
}
} }
return 0; return 0;
fail: fail:
__free_pbl(pdev, pbl, is_umem); __free_pbl(res, pbl, is_umem);
return -ENOMEM; return -ENOMEM;
} }
/* HWQ */ /* 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; int i;
@ -144,9 +161,9 @@ void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq)
for (i = 0; i < hwq->level + 1; i++) { for (i = 0; i < hwq->level + 1; i++) {
if (i == hwq->level) if (i == hwq->level)
__free_pbl(pdev, &hwq->pbl[i], hwq->is_user); __free_pbl(res, &hwq->pbl[i], hwq->is_user);
else else
__free_pbl(pdev, &hwq->pbl[i], false); __free_pbl(res, &hwq->pbl[i], false);
} }
hwq->level = PBL_LVL_MAX; hwq->level = PBL_LVL_MAX;
@ -158,79 +175,113 @@ void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq)
} }
/* All HWQs are power of 2 in size */ /* 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, int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
u32 *elements, u32 element_size, u32 aux, struct bnxt_qplib_hwq_attr *hwq_attr)
u32 pg_size, enum bnxt_qplib_hwq_type hwq_type)
{ {
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; dma_addr_t *src_phys_ptr, **dst_virt_ptr;
struct scatterlist *sghead = NULL; 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; hwq->level = PBL_LVL_MAX;
slots = roundup_pow_of_two(*elements); depth = roundup_pow_of_two(hwq_attr->depth);
if (aux) { stride = roundup_pow_of_two(hwq_attr->stride);
aux_size = roundup_pow_of_two(aux); if (hwq_attr->aux_depth) {
aux_pages = (slots * aux_size) / pg_size; aux_slots = hwq_attr->aux_depth;
if ((slots * aux_size) % pg_size) 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++; aux_pages++;
} }
size = roundup_pow_of_two(element_size);
if (sg_info)
sghead = sg_info->sglist;
if (!sghead) { if (!sghead) {
hwq->is_user = false; hwq->is_user = false;
pages = (slots * size) / pg_size + aux_pages; npages = (depth * stride) / pg_size + aux_pages;
if ((slots * size) % pg_size) if ((depth * stride) % pg_size)
pages++; npages++;
if (!pages) if (!npages)
return -EINVAL; return -EINVAL;
maps = 0; hwq_attr->sginfo->npages = npages;
} else { } else {
hwq->is_user = true; hwq->is_user = true;
pages = sg_info->npages; npages = hwq_attr->sginfo->npages;
maps = sg_info->nmap; 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 (npages == MAX_PBL_LVL_0_PGS) {
if (sghead && (pages == MAX_PBL_LVL_0_PGS)) /* This request is Level 0, map PTE */
rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_0], sghead, rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], hwq_attr->sginfo);
pages, maps, pg_size); if (rc)
else goto fail;
rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_0], NULL, hwq->level = PBL_LVL_0;
1, 0, pg_size); }
if (rc)
goto fail;
hwq->level = PBL_LVL_0; if (npages > MAX_PBL_LVL_0_PGS) {
if (npages > MAX_PBL_LVL_1_PGS) {
if (pages > MAX_PBL_LVL_0_PGS) { u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ?
if (pages > MAX_PBL_LVL_1_PGS) { 0 : PTU_PTE_VALID;
/* 2 levels of indirection */ /* 2 levels of indirection */
rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_1], NULL, npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT;
MAX_PBL_LVL_1_PGS_FOR_LVL_2, if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT))
0, pg_size); 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) if (rc)
goto fail; goto fail;
/* Fill in lvl0 PBL */ /* Fill PDL with PBL page pointers */
dst_virt_ptr = dst_virt_ptr =
(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) if (hwq_attr->type == HWQ_TYPE_MR) {
dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = /* For MR it is expected that we supply only 1 contigous
src_phys_ptr[i] | PTU_PDE_VALID; * page i.e only 1 entry in the PDL that will contain
hwq->level = PBL_LVL_1; * all the PBLs for the user supplied memory region
*/
rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_2], sghead, for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
pages, maps, pg_size); 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) if (rc)
goto fail; goto fail;
hwq->level = PBL_LVL_2;
/* Fill in lvl1 PBL */ if (hwq_attr->sginfo->nopte)
goto done;
/* Fill PBLs with PTE pointers */
dst_virt_ptr = dst_virt_ptr =
(dma_addr_t **)hwq->pbl[PBL_LVL_1].pg_arr; (dma_addr_t **)hwq->pbl[PBL_LVL_1].pg_arr;
src_phys_ptr = hwq->pbl[PBL_LVL_2].pg_map_arr; src_phys_ptr = hwq->pbl[PBL_LVL_2].pg_map_arr;
@ -238,7 +289,7 @@ int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
src_phys_ptr[i] | PTU_PTE_VALID; 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 */ /* Find the last pg of the size */
i = hwq->pbl[PBL_LVL_2].pg_count; i = hwq->pbl[PBL_LVL_2].pg_count;
dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |= dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |=
@ -248,25 +299,36 @@ int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
[PTR_IDX(i - 2)] |= [PTR_IDX(i - 2)] |=
PTU_PTE_NEXT_TO_LAST; PTU_PTE_NEXT_TO_LAST;
} }
hwq->level = PBL_LVL_2; } else { /* pages < 512 npbl = 1, npde = 0 */
} else { u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ?
u32 flag = hwq_type == HWQ_TYPE_L2_CMPL ? 0 : 0 : PTU_PTE_VALID;
PTU_PTE_VALID;
/* 1 level of indirection */ /* 1 level of indirection */
rc = __alloc_pbl(pdev, &hwq->pbl[PBL_LVL_1], sghead, npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT;
pages, maps, pg_size); 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) if (rc)
goto fail; 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 = dst_virt_ptr =
(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_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)] = dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
src_phys_ptr[i] | flag; src_phys_ptr[i] | flag;
} if (hwq_attr->type == HWQ_TYPE_QUEUE) {
if (hwq_type == HWQ_TYPE_QUEUE) {
/* Find the last pg of the size */ /* Find the last pg of the size */
i = hwq->pbl[PBL_LVL_1].pg_count; i = hwq->pbl[PBL_LVL_1].pg_count;
dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |= dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |=
@ -276,42 +338,141 @@ int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq,
[PTR_IDX(i - 2)] |= [PTR_IDX(i - 2)] |=
PTU_PTE_NEXT_TO_LAST; PTU_PTE_NEXT_TO_LAST;
} }
hwq->level = PBL_LVL_1;
} }
} }
hwq->pdev = pdev; done:
spin_lock_init(&hwq->lock);
hwq->prod = 0; hwq->prod = 0;
hwq->cons = 0; hwq->cons = 0;
*elements = hwq->max_elements = slots; hwq->pdev = pdev;
hwq->element_size = size; hwq->depth = hwq_attr->depth;
hwq->max_elements = depth;
hwq->element_size = stride;
/* For direct access to the elements */ /* For direct access to the elements */
hwq->pbl_ptr = hwq->pbl[hwq->level].pg_arr; lvl = hwq->level;
hwq->pbl_dma_ptr = hwq->pbl[hwq->level].pg_map_arr; 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; return 0;
fail: fail:
bnxt_qplib_free_hwq(pdev, hwq); bnxt_qplib_free_hwq(res, hwq);
return -ENOMEM; return -ENOMEM;
} }
/* Context Tables */ /* 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) struct bnxt_qplib_ctx *ctx)
{ {
int i; int i;
bnxt_qplib_free_hwq(pdev, &ctx->qpc_tbl); bnxt_qplib_free_hwq(res, &ctx->qpc_tbl);
bnxt_qplib_free_hwq(pdev, &ctx->mrw_tbl); bnxt_qplib_free_hwq(res, &ctx->mrw_tbl);
bnxt_qplib_free_hwq(pdev, &ctx->srqc_tbl); bnxt_qplib_free_hwq(res, &ctx->srqc_tbl);
bnxt_qplib_free_hwq(pdev, &ctx->cq_tbl); bnxt_qplib_free_hwq(res, &ctx->cq_tbl);
bnxt_qplib_free_hwq(pdev, &ctx->tim_tbl); bnxt_qplib_free_hwq(res, &ctx->tim_tbl);
for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
bnxt_qplib_free_hwq(pdev, &ctx->tqm_tbl[i]); bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.qtbl[i]);
bnxt_qplib_free_hwq(pdev, &ctx->tqm_pde); /* restore original pde level before destroy */
bnxt_qplib_free_stats_ctx(pdev, &ctx->stats); 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 *pdev,
* Returns: * Returns:
* 0 if success, else -ERRORS * 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, struct bnxt_qplib_ctx *ctx,
bool virt_fn, bool is_p5) bool virt_fn, bool is_p5)
{ {
int i, j, k, rc = 0; struct bnxt_qplib_hwq_attr hwq_attr = {};
int fnz_idx = -1; struct bnxt_qplib_sg_info sginfo = {};
__le64 **pbl_ptr; int rc = 0;
if (virt_fn || is_p5) if (virt_fn || is_p5)
goto stats_alloc; goto stats_alloc;
/* QPC Tables */ /* QPC Tables */
ctx->qpc_tbl.max_elements = ctx->qpc_count; sginfo.pgsize = PAGE_SIZE;
rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->qpc_tbl, NULL, sginfo.pgshft = PAGE_SHIFT;
&ctx->qpc_tbl.max_elements, hwq_attr.sginfo = &sginfo;
BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE, 0,
PAGE_SIZE, HWQ_TYPE_CTX); 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) if (rc)
goto fail; goto fail;
/* MRW Tables */ /* MRW Tables */
ctx->mrw_tbl.max_elements = ctx->mrw_count; hwq_attr.depth = ctx->mrw_count;
rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->mrw_tbl, NULL, hwq_attr.stride = BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE;
&ctx->mrw_tbl.max_elements, rc = bnxt_qplib_alloc_init_hwq(&ctx->mrw_tbl, &hwq_attr);
BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE, 0,
PAGE_SIZE, HWQ_TYPE_CTX);
if (rc) if (rc)
goto fail; goto fail;
/* SRQ Tables */ /* SRQ Tables */
ctx->srqc_tbl.max_elements = ctx->srqc_count; hwq_attr.depth = ctx->srqc_count;
rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->srqc_tbl, NULL, hwq_attr.stride = BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE;
&ctx->srqc_tbl.max_elements, rc = bnxt_qplib_alloc_init_hwq(&ctx->srqc_tbl, &hwq_attr);
BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE, 0,
PAGE_SIZE, HWQ_TYPE_CTX);
if (rc) if (rc)
goto fail; goto fail;
/* CQ Tables */ /* CQ Tables */
ctx->cq_tbl.max_elements = ctx->cq_count; hwq_attr.depth = ctx->cq_count;
rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->cq_tbl, NULL, hwq_attr.stride = BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE;
&ctx->cq_tbl.max_elements, rc = bnxt_qplib_alloc_init_hwq(&ctx->cq_tbl, &hwq_attr);
BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE, 0,
PAGE_SIZE, HWQ_TYPE_CTX);
if (rc) if (rc)
goto fail; goto fail;
/* TQM Buffer */ /* TQM Buffer */
ctx->tqm_pde.max_elements = 512; rc = bnxt_qplib_setup_tqm_rings(res, ctx);
rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tqm_pde, NULL,
&ctx->tqm_pde.max_elements, sizeof(u64),
0, PAGE_SIZE, HWQ_TYPE_CTX);
if (rc) if (rc)
goto fail; 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 */ /* TIM Buffer */
ctx->tim_tbl.max_elements = ctx->qpc_count * 16; ctx->tim_tbl.max_elements = ctx->qpc_count * 16;
rc = bnxt_qplib_alloc_init_hwq(pdev, &ctx->tim_tbl, NULL, hwq_attr.depth = ctx->qpc_count * 16;
&ctx->tim_tbl.max_elements, 1, hwq_attr.stride = 1;
0, PAGE_SIZE, HWQ_TYPE_CTX); rc = bnxt_qplib_alloc_init_hwq(&ctx->tim_tbl, &hwq_attr);
if (rc) if (rc)
goto fail; goto fail;
stats_alloc: stats_alloc:
/* Stats */ /* Stats */
rc = bnxt_qplib_alloc_stats_ctx(pdev, &ctx->stats); rc = bnxt_qplib_alloc_stats_ctx(res->pdev, &ctx->stats);
if (rc) if (rc)
goto fail; goto fail;
return 0; return 0;
fail: fail:
bnxt_qplib_free_ctx(pdev, ctx); bnxt_qplib_free_ctx(res, ctx);
return rc; return rc;
} }
@ -808,9 +921,6 @@ void bnxt_qplib_free_res(struct bnxt_qplib_res *res)
bnxt_qplib_free_sgid_tbl(res, &res->sgid_tbl); bnxt_qplib_free_sgid_tbl(res, &res->sgid_tbl);
bnxt_qplib_free_pd_tbl(&res->pd_tbl); bnxt_qplib_free_pd_tbl(&res->pd_tbl);
bnxt_qplib_free_dpi_tbl(res, &res->dpi_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, int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,

View File

@ -55,7 +55,8 @@ extern const struct bnxt_qplib_gid bnxt_qplib_gid_zero;
enum bnxt_qplib_hwq_type { enum bnxt_qplib_hwq_type {
HWQ_TYPE_CTX, HWQ_TYPE_CTX,
HWQ_TYPE_QUEUE, HWQ_TYPE_QUEUE,
HWQ_TYPE_L2_CMPL HWQ_TYPE_L2_CMPL,
HWQ_TYPE_MR
}; };
#define MAX_PBL_LVL_0_PGS 1 #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_SHIFT 9
#define MAX_PBL_LVL_1_PGS_FOR_LVL_2 256 #define MAX_PBL_LVL_1_PGS_FOR_LVL_2 256
#define MAX_PBL_LVL_2_PGS (256 * 512) #define MAX_PBL_LVL_2_PGS (256 * 512)
#define MAX_PDL_LVL_SHIFT 9
enum bnxt_qplib_pbl_lvl { enum bnxt_qplib_pbl_lvl {
PBL_LVL_0, PBL_LVL_0,
@ -85,17 +87,37 @@ struct bnxt_qplib_pbl {
dma_addr_t *pg_map_arr; 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 bnxt_qplib_hwq {
struct pci_dev *pdev; struct pci_dev *pdev;
/* lock to protect qplib_hwq */ /* lock to protect qplib_hwq */
spinlock_t lock; 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 */ enum bnxt_qplib_pbl_lvl level; /* 0, 1, or 2 */
/* ptr for easy access to the PBL entries */ /* ptr for easy access to the PBL entries */
void **pbl_ptr; void **pbl_ptr;
/* ptr for easy access to the dma_addr */ /* ptr for easy access to the dma_addr */
dma_addr_t *pbl_dma_ptr; dma_addr_t *pbl_dma_ptr;
u32 max_elements; u32 max_elements;
u32 depth;
u16 element_size; /* Size of each entry */ u16 element_size; /* Size of each entry */
u32 prod; /* raw */ 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_CQ_CTX_ENTRY_SIZE 64
#define BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE 128 #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 { struct bnxt_qplib_ctx {
u32 qpc_count; u32 qpc_count;
struct bnxt_qplib_hwq qpc_tbl; struct bnxt_qplib_hwq qpc_tbl;
@ -169,12 +200,7 @@ struct bnxt_qplib_ctx {
u32 cq_count; u32 cq_count;
struct bnxt_qplib_hwq cq_tbl; struct bnxt_qplib_hwq cq_tbl;
struct bnxt_qplib_hwq tim_tbl; struct bnxt_qplib_hwq tim_tbl;
#define MAX_TQM_ALLOC_REQ 48 struct bnxt_qplib_tqm_ctx tqm_ctx;
#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_stats stats; struct bnxt_qplib_stats stats;
struct bnxt_qplib_vf_res vf_res; struct bnxt_qplib_vf_res vf_res;
u64 hwrm_intf_ver; u64 hwrm_intf_ver;
@ -223,11 +249,6 @@ static inline u8 bnxt_qplib_get_ring_type(struct bnxt_qplib_chip_ctx *cctx)
RING_ALLOC_REQ_RING_TYPE_ROCE_CMPL; 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) \ #define to_bnxt_qplib(ptr, type, member) \
container_of(ptr, type, member) container_of(ptr, type, member)
@ -235,11 +256,10 @@ struct bnxt_qplib_sg_info {
struct bnxt_qplib_pd; struct bnxt_qplib_pd;
struct bnxt_qplib_dev_attr; struct bnxt_qplib_dev_attr;
void bnxt_qplib_free_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq); void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res,
int bnxt_qplib_alloc_init_hwq(struct pci_dev *pdev, struct bnxt_qplib_hwq *hwq, struct bnxt_qplib_hwq *hwq);
struct bnxt_qplib_sg_info *sg_info, u32 *elements, int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
u32 elements_per_page, u32 aux, u32 pg_size, struct bnxt_qplib_hwq_attr *hwq_attr);
enum bnxt_qplib_hwq_type hwq_type);
void bnxt_qplib_get_guid(u8 *dev_addr, u8 *guid); void bnxt_qplib_get_guid(u8 *dev_addr, u8 *guid);
int bnxt_qplib_alloc_pd(struct bnxt_qplib_pd_tbl *pd_tbl, int bnxt_qplib_alloc_pd(struct bnxt_qplib_pd_tbl *pd_tbl,
struct bnxt_qplib_pd *pd); struct bnxt_qplib_pd *pd);
@ -258,9 +278,9 @@ void bnxt_qplib_free_res(struct bnxt_qplib_res *res);
int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev, int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
struct net_device *netdev, struct net_device *netdev,
struct bnxt_qplib_dev_attr *dev_attr); 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); 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, struct bnxt_qplib_ctx *ctx,
bool virt_fn, bool is_p5); bool virt_fn, bool is_p5);
#endif /* __BNXT_QPLIB_RES_H__ */ #endif /* __BNXT_QPLIB_RES_H__ */

View File

@ -585,7 +585,7 @@ int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
/* Free the qplib's MRW memory */ /* Free the qplib's MRW memory */
if (mrw->hwq.max_elements) if (mrw->hwq.max_elements)
bnxt_qplib_free_hwq(res->pdev, &mrw->hwq); bnxt_qplib_free_hwq(res, &mrw->hwq);
return 0; return 0;
} }
@ -646,7 +646,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
if (mrw->hwq.max_elements) { if (mrw->hwq.max_elements) {
mrw->va = 0; mrw->va = 0;
mrw->total_size = 0; mrw->total_size = 0;
bnxt_qplib_free_hwq(res->pdev, &mrw->hwq); bnxt_qplib_free_hwq(res, &mrw->hwq);
} }
return 0; return 0;
@ -656,10 +656,12 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
u64 *pbl_tbl, int num_pbls, bool block, u32 buf_pg_size) u64 *pbl_tbl, int num_pbls, bool block, u32 buf_pg_size)
{ {
struct bnxt_qplib_rcfw *rcfw = res->rcfw; 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; struct creq_register_mr_resp resp;
u16 cmd_flags = 0, level; struct cmdq_register_mr req;
int pg_ptrs, pages, i, rc; int pg_ptrs, pages, i, rc;
u16 cmd_flags = 0, level;
dma_addr_t **pbl_ptr; dma_addr_t **pbl_ptr;
u32 pg_size; u32 pg_size;
@ -674,20 +676,23 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
if (pages > MAX_PBL_LVL_1_PGS) { if (pages > MAX_PBL_LVL_1_PGS) {
dev_err(&res->pdev->dev, 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); pages, MAX_PBL_LVL_1_PGS);
return -ENOMEM; return -ENOMEM;
} }
/* Free the hwq if it already exist, must be a rereg */ /* Free the hwq if it already exist, must be a rereg */
if (mr->hwq.max_elements) if (mr->hwq.max_elements)
bnxt_qplib_free_hwq(res->pdev, &mr->hwq); bnxt_qplib_free_hwq(res, &mr->hwq);
mr->hwq.max_elements = pages;
/* Use system PAGE_SIZE */ /* Use system PAGE_SIZE */
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL, hwq_attr.res = res;
&mr->hwq.max_elements, hwq_attr.depth = pages;
PAGE_SIZE, 0, PAGE_SIZE, hwq_attr.stride = PAGE_SIZE;
HWQ_TYPE_CTX); 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) { if (rc) {
dev_err(&res->pdev->dev, dev_err(&res->pdev->dev,
"SP: Reg MR memory allocation failed\n"); "SP: Reg MR memory allocation failed\n");
@ -734,7 +739,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
fail: fail:
if (mr->hwq.max_elements) if (mr->hwq.max_elements)
bnxt_qplib_free_hwq(res->pdev, &mr->hwq); bnxt_qplib_free_hwq(res, &mr->hwq);
return rc; return rc;
} }
@ -742,6 +747,8 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
struct bnxt_qplib_frpl *frpl, struct bnxt_qplib_frpl *frpl,
int max_pg_ptrs) int max_pg_ptrs)
{ {
struct bnxt_qplib_hwq_attr hwq_attr = {};
struct bnxt_qplib_sg_info sginfo = {};
int pg_ptrs, pages, rc; int pg_ptrs, pages, rc;
/* Re-calculate the max to fit the HWQ allocation model */ /* Re-calculate the max to fit the HWQ allocation model */
@ -753,10 +760,15 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
if (pages > MAX_PBL_LVL_1_PGS) if (pages > MAX_PBL_LVL_1_PGS)
return -ENOMEM; return -ENOMEM;
frpl->hwq.max_elements = pages; sginfo.pgsize = PAGE_SIZE;
rc = bnxt_qplib_alloc_init_hwq(res->pdev, &frpl->hwq, NULL, sginfo.nopte = true;
&frpl->hwq.max_elements, PAGE_SIZE, 0,
PAGE_SIZE, HWQ_TYPE_CTX); 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) if (!rc)
frpl->max_pg_ptrs = pg_ptrs; frpl->max_pg_ptrs = pg_ptrs;
@ -766,7 +778,7 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res, int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res,
struct bnxt_qplib_frpl *frpl) struct bnxt_qplib_frpl *frpl)
{ {
bnxt_qplib_free_hwq(res->pdev, &frpl->hwq); bnxt_qplib_free_hwq(res, &frpl->hwq);
return 0; return 0;
} }