xref: /linux/drivers/infiniband/hw/bng_re/bng_fw.c (revision 53310b698f3cf601dfdc6c3b2b60c7cb275b1199)
1*53310b69SSiva Reddy Kallam // SPDX-License-Identifier: GPL-2.0
2*53310b69SSiva Reddy Kallam // Copyright (c) 2025 Broadcom.
3*53310b69SSiva Reddy Kallam #include <linux/pci.h>
4*53310b69SSiva Reddy Kallam 
5*53310b69SSiva Reddy Kallam #include "bng_res.h"
6*53310b69SSiva Reddy Kallam #include "bng_fw.h"
7*53310b69SSiva Reddy Kallam 
8*53310b69SSiva Reddy Kallam void bng_re_free_rcfw_channel(struct bng_re_rcfw *rcfw)
9*53310b69SSiva Reddy Kallam {
10*53310b69SSiva Reddy Kallam 	kfree(rcfw->crsqe_tbl);
11*53310b69SSiva Reddy Kallam 	bng_re_free_hwq(rcfw->res, &rcfw->cmdq.hwq);
12*53310b69SSiva Reddy Kallam 	bng_re_free_hwq(rcfw->res, &rcfw->creq.hwq);
13*53310b69SSiva Reddy Kallam 	rcfw->pdev = NULL;
14*53310b69SSiva Reddy Kallam }
15*53310b69SSiva Reddy Kallam 
16*53310b69SSiva Reddy Kallam int bng_re_alloc_fw_channel(struct bng_re_res *res,
17*53310b69SSiva Reddy Kallam 			    struct bng_re_rcfw *rcfw)
18*53310b69SSiva Reddy Kallam {
19*53310b69SSiva Reddy Kallam 	struct bng_re_hwq_attr hwq_attr = {};
20*53310b69SSiva Reddy Kallam 	struct bng_re_sg_info sginfo = {};
21*53310b69SSiva Reddy Kallam 	struct bng_re_cmdq_ctx *cmdq;
22*53310b69SSiva Reddy Kallam 	struct bng_re_creq_ctx *creq;
23*53310b69SSiva Reddy Kallam 
24*53310b69SSiva Reddy Kallam 	rcfw->pdev = res->pdev;
25*53310b69SSiva Reddy Kallam 	cmdq = &rcfw->cmdq;
26*53310b69SSiva Reddy Kallam 	creq = &rcfw->creq;
27*53310b69SSiva Reddy Kallam 	rcfw->res = res;
28*53310b69SSiva Reddy Kallam 
29*53310b69SSiva Reddy Kallam 	sginfo.pgsize = PAGE_SIZE;
30*53310b69SSiva Reddy Kallam 	sginfo.pgshft = PAGE_SHIFT;
31*53310b69SSiva Reddy Kallam 
32*53310b69SSiva Reddy Kallam 	hwq_attr.sginfo = &sginfo;
33*53310b69SSiva Reddy Kallam 	hwq_attr.res = rcfw->res;
34*53310b69SSiva Reddy Kallam 	hwq_attr.depth = BNG_FW_CREQE_MAX_CNT;
35*53310b69SSiva Reddy Kallam 	hwq_attr.stride = BNG_FW_CREQE_UNITS;
36*53310b69SSiva Reddy Kallam 	hwq_attr.type = BNG_HWQ_TYPE_QUEUE;
37*53310b69SSiva Reddy Kallam 
38*53310b69SSiva Reddy Kallam 	if (bng_re_alloc_init_hwq(&creq->hwq, &hwq_attr)) {
39*53310b69SSiva Reddy Kallam 		dev_err(&rcfw->pdev->dev,
40*53310b69SSiva Reddy Kallam 			"HW channel CREQ allocation failed\n");
41*53310b69SSiva Reddy Kallam 		goto fail;
42*53310b69SSiva Reddy Kallam 	}
43*53310b69SSiva Reddy Kallam 
44*53310b69SSiva Reddy Kallam 	rcfw->cmdq_depth = BNG_FW_CMDQE_MAX_CNT;
45*53310b69SSiva Reddy Kallam 
46*53310b69SSiva Reddy Kallam 	sginfo.pgsize = bng_fw_cmdqe_page_size(rcfw->cmdq_depth);
47*53310b69SSiva Reddy Kallam 	hwq_attr.depth = rcfw->cmdq_depth & 0x7FFFFFFF;
48*53310b69SSiva Reddy Kallam 	hwq_attr.stride = BNG_FW_CMDQE_UNITS;
49*53310b69SSiva Reddy Kallam 	hwq_attr.type = BNG_HWQ_TYPE_CTX;
50*53310b69SSiva Reddy Kallam 	if (bng_re_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
51*53310b69SSiva Reddy Kallam 		dev_err(&rcfw->pdev->dev,
52*53310b69SSiva Reddy Kallam 			"HW channel CMDQ allocation failed\n");
53*53310b69SSiva Reddy Kallam 		goto fail;
54*53310b69SSiva Reddy Kallam 	}
55*53310b69SSiva Reddy Kallam 
56*53310b69SSiva Reddy Kallam 	rcfw->crsqe_tbl = kcalloc(cmdq->hwq.max_elements,
57*53310b69SSiva Reddy Kallam 				  sizeof(*rcfw->crsqe_tbl), GFP_KERNEL);
58*53310b69SSiva Reddy Kallam 	if (!rcfw->crsqe_tbl)
59*53310b69SSiva Reddy Kallam 		goto fail;
60*53310b69SSiva Reddy Kallam 
61*53310b69SSiva Reddy Kallam 	spin_lock_init(&rcfw->tbl_lock);
62*53310b69SSiva Reddy Kallam 
63*53310b69SSiva Reddy Kallam 	rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout;
64*53310b69SSiva Reddy Kallam 
65*53310b69SSiva Reddy Kallam 	return 0;
66*53310b69SSiva Reddy Kallam 
67*53310b69SSiva Reddy Kallam fail:
68*53310b69SSiva Reddy Kallam 	bng_re_free_rcfw_channel(rcfw);
69*53310b69SSiva Reddy Kallam 	return -ENOMEM;
70*53310b69SSiva Reddy Kallam }
71