xref: /freebsd/contrib/ofed/libbnxtre/main.c (revision 9207f9d206a4017001f01ca27d3d25a26c268a95)
1*9207f9d2SChandrakanth patil /*
2*9207f9d2SChandrakanth patil  * Copyright (c) 2024, Broadcom. All rights reserved.  The term
3*9207f9d2SChandrakanth patil  * Broadcom refers to Broadcom Limited and/or its subsidiaries.
4*9207f9d2SChandrakanth patil  *
5*9207f9d2SChandrakanth patil  * Redistribution and use in source and binary forms, with or without
6*9207f9d2SChandrakanth patil  * modification, are permitted provided that the following conditions
7*9207f9d2SChandrakanth patil  * are met:
8*9207f9d2SChandrakanth patil  *
9*9207f9d2SChandrakanth patil  * 1. Redistributions of source code must retain the above copyright
10*9207f9d2SChandrakanth patil  *    notice, this list of conditions and the following disclaimer.
11*9207f9d2SChandrakanth patil  * 2. Redistributions in binary form must reproduce the above copyright
12*9207f9d2SChandrakanth patil  *    notice, this list of conditions and the following disclaimer in
13*9207f9d2SChandrakanth patil  *    the documentation and/or other materials provided with the
14*9207f9d2SChandrakanth patil  *    distribution.
15*9207f9d2SChandrakanth patil  *
16*9207f9d2SChandrakanth patil  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
17*9207f9d2SChandrakanth patil  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18*9207f9d2SChandrakanth patil  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*9207f9d2SChandrakanth patil  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
20*9207f9d2SChandrakanth patil  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*9207f9d2SChandrakanth patil  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*9207f9d2SChandrakanth patil  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23*9207f9d2SChandrakanth patil  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24*9207f9d2SChandrakanth patil  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25*9207f9d2SChandrakanth patil  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26*9207f9d2SChandrakanth patil  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*9207f9d2SChandrakanth patil  *
28*9207f9d2SChandrakanth patil  */
29*9207f9d2SChandrakanth patil 
30*9207f9d2SChandrakanth patil #include <sys/types.h>
31*9207f9d2SChandrakanth patil #include <sys/mman.h>
32*9207f9d2SChandrakanth patil #include <sys/stat.h>
33*9207f9d2SChandrakanth patil 
34*9207f9d2SChandrakanth patil #include <errno.h>
35*9207f9d2SChandrakanth patil #include <fcntl.h>
36*9207f9d2SChandrakanth patil #include <pthread.h>
37*9207f9d2SChandrakanth patil #include <stdio.h>
38*9207f9d2SChandrakanth patil #include <stdlib.h>
39*9207f9d2SChandrakanth patil #include <string.h>
40*9207f9d2SChandrakanth patil #include <unistd.h>
41*9207f9d2SChandrakanth patil 
42*9207f9d2SChandrakanth patil #include "abi.h"
43*9207f9d2SChandrakanth patil #include "main.h"
44*9207f9d2SChandrakanth patil #include "verbs.h"
45*9207f9d2SChandrakanth patil 
46*9207f9d2SChandrakanth patil #define PCI_VENDOR_ID_BROADCOM		0x14E4
47*9207f9d2SChandrakanth patil 
48*9207f9d2SChandrakanth patil BNXT_RE_DEFINE_CNA_TABLE(cna_table) = {
49*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1605),  /* BCM57454 Stratus NPAR */
50*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1606),	/* BCM57454 Stratus VF */
51*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1614),	/* BCM57454 Stratus */
52*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16C0),	/* BCM57417 NPAR */
53*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16C1),  /* BMC57414 VF */
54*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16CE),	/* BMC57311 */
55*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16CF),	/* BMC57312 */
56*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16D6),	/* BMC57412*/
57*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16D7),	/* BMC57414 */
58*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16D8),	/* BMC57416 Cu */
59*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16D9),	/* BMC57417 Cu */
60*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16DF),	/* BMC57314 */
61*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16E2),	/* BMC57417 */
62*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16E3),	/* BMC57416 */
63*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16E5),	/* BMC57314 VF */
64*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16EB),	/* BCM57412 NPAR */
65*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16ED),	/* BCM57414 NPAR */
66*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16EF),	/* BCM57416 NPAR */
67*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16F0),  /* BCM58730 */
68*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x16F1),	/* BCM57452 Stratus Mezz */
69*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1750),	/* Chip num 57500 */
70*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1751),  /* BCM57504 Gen P5 */
71*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1752),  /* BCM57502 Gen P5 */
72*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1760),  /* BCM57608 Thor 2*/
73*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0xD82E),  /* BCM5760x TH2 VF */
74*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1803),  /* BCM57508 Gen P5 NPAR */
75*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1804),  /* BCM57504 Gen P5 NPAR */
76*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1805),  /* BCM57502 Gen P5 NPAR */
77*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1807),  /* BCM5750x Gen P5 VF */
78*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0x1809),  /* BCM5750x Gen P5 VF HV */
79*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0xD800),  /* BCM880xx SR VF */
80*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0xD802),  /* BCM58802 SR */
81*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0xD804),  /* BCM58804 SR */
82*9207f9d2SChandrakanth patil 	CNA(BROADCOM, 0xD818)   /* BCM58818 Gen P5 SR2 */
83*9207f9d2SChandrakanth patil };
84*9207f9d2SChandrakanth patil 
85*9207f9d2SChandrakanth patil static struct ibv_context_ops bnxt_re_cntx_ops = {
86*9207f9d2SChandrakanth patil 	.query_device  = bnxt_re_query_device,
87*9207f9d2SChandrakanth patil 	.query_port    = bnxt_re_query_port,
88*9207f9d2SChandrakanth patil 	.alloc_pd      = bnxt_re_alloc_pd,
89*9207f9d2SChandrakanth patil 	.dealloc_pd    = bnxt_re_free_pd,
90*9207f9d2SChandrakanth patil 	.reg_mr        = bnxt_re_reg_mr,
91*9207f9d2SChandrakanth patil 	.dereg_mr      = bnxt_re_dereg_mr,
92*9207f9d2SChandrakanth patil 	.create_cq     = bnxt_re_create_cq,
93*9207f9d2SChandrakanth patil 	.poll_cq       = bnxt_re_poll_cq,
94*9207f9d2SChandrakanth patil 	.req_notify_cq = bnxt_re_arm_cq,
95*9207f9d2SChandrakanth patil 	.cq_event      = bnxt_re_cq_event,
96*9207f9d2SChandrakanth patil 	.resize_cq     = bnxt_re_resize_cq,
97*9207f9d2SChandrakanth patil 	.destroy_cq    = bnxt_re_destroy_cq,
98*9207f9d2SChandrakanth patil 	.create_srq    = bnxt_re_create_srq,
99*9207f9d2SChandrakanth patil 	.modify_srq    = bnxt_re_modify_srq,
100*9207f9d2SChandrakanth patil 	.query_srq     = bnxt_re_query_srq,
101*9207f9d2SChandrakanth patil 	.destroy_srq   = bnxt_re_destroy_srq,
102*9207f9d2SChandrakanth patil 	.post_srq_recv = bnxt_re_post_srq_recv,
103*9207f9d2SChandrakanth patil 	.create_qp     = bnxt_re_create_qp,
104*9207f9d2SChandrakanth patil 	.query_qp      = bnxt_re_query_qp,
105*9207f9d2SChandrakanth patil 	.modify_qp     = bnxt_re_modify_qp,
106*9207f9d2SChandrakanth patil 	.destroy_qp    = bnxt_re_destroy_qp,
107*9207f9d2SChandrakanth patil 	.post_send     = bnxt_re_post_send,
108*9207f9d2SChandrakanth patil 	.post_recv     = bnxt_re_post_recv,
109*9207f9d2SChandrakanth patil 	.async_event   = bnxt_re_async_event,
110*9207f9d2SChandrakanth patil 	.create_ah     = bnxt_re_create_ah,
111*9207f9d2SChandrakanth patil 	.destroy_ah    = bnxt_re_destroy_ah
112*9207f9d2SChandrakanth patil };
113*9207f9d2SChandrakanth patil 
114*9207f9d2SChandrakanth patil bool _is_chip_gen_p5(struct bnxt_re_chip_ctx *cctx)
115*9207f9d2SChandrakanth patil {
116*9207f9d2SChandrakanth patil 	return (cctx->chip_num == CHIP_NUM_57508 ||
117*9207f9d2SChandrakanth patil 		cctx->chip_num == CHIP_NUM_57504 ||
118*9207f9d2SChandrakanth patil 		cctx->chip_num == CHIP_NUM_57502);
119*9207f9d2SChandrakanth patil }
120*9207f9d2SChandrakanth patil 
121*9207f9d2SChandrakanth patil bool _is_chip_a0(struct bnxt_re_chip_ctx *cctx)
122*9207f9d2SChandrakanth patil {
123*9207f9d2SChandrakanth patil 	return !cctx->chip_rev;
124*9207f9d2SChandrakanth patil }
125*9207f9d2SChandrakanth patil 
126*9207f9d2SChandrakanth patil bool _is_chip_thor2(struct bnxt_re_chip_ctx *cctx)
127*9207f9d2SChandrakanth patil {
128*9207f9d2SChandrakanth patil 	return (cctx->chip_num == CHIP_NUM_58818 ||
129*9207f9d2SChandrakanth patil 		cctx->chip_num == CHIP_NUM_57608);
130*9207f9d2SChandrakanth patil }
131*9207f9d2SChandrakanth patil 
132*9207f9d2SChandrakanth patil bool _is_chip_gen_p5_thor2(struct bnxt_re_chip_ctx *cctx)
133*9207f9d2SChandrakanth patil {
134*9207f9d2SChandrakanth patil 	return(_is_chip_gen_p5(cctx) || _is_chip_thor2(cctx));
135*9207f9d2SChandrakanth patil }
136*9207f9d2SChandrakanth patil 
137*9207f9d2SChandrakanth patil bool _is_db_drop_recovery_enable(struct bnxt_re_context *cntx)
138*9207f9d2SChandrakanth patil {
139*9207f9d2SChandrakanth patil 	return cntx->comp_mask & BNXT_RE_COMP_MASK_UCNTX_DBR_RECOVERY_ENABLED;
140*9207f9d2SChandrakanth patil }
141*9207f9d2SChandrakanth patil 
142*9207f9d2SChandrakanth patil /* Determine the env variable */
143*9207f9d2SChandrakanth patil static int single_threaded_app(void)
144*9207f9d2SChandrakanth patil {
145*9207f9d2SChandrakanth patil 	char *env;
146*9207f9d2SChandrakanth patil 
147*9207f9d2SChandrakanth patil 	env = getenv("BNXT_SINGLE_THREADED");
148*9207f9d2SChandrakanth patil 	if (env)
149*9207f9d2SChandrakanth patil 		return strcmp(env, "1") ? 0 : 1;
150*9207f9d2SChandrakanth patil 
151*9207f9d2SChandrakanth patil 	return 0;
152*9207f9d2SChandrakanth patil }
153*9207f9d2SChandrakanth patil 
154*9207f9d2SChandrakanth patil static int enable_dynamic_debug(void)
155*9207f9d2SChandrakanth patil {
156*9207f9d2SChandrakanth patil 	char *env;
157*9207f9d2SChandrakanth patil 
158*9207f9d2SChandrakanth patil 	env = getenv("BNXT_DYN_DBG");
159*9207f9d2SChandrakanth patil 	if (env)
160*9207f9d2SChandrakanth patil 		return strcmp(env, "1") ? 0 : 1;
161*9207f9d2SChandrakanth patil 
162*9207f9d2SChandrakanth patil 	return 0;
163*9207f9d2SChandrakanth patil }
164*9207f9d2SChandrakanth patil 
165*9207f9d2SChandrakanth patil /* Static Context Init functions */
166*9207f9d2SChandrakanth patil static int _bnxt_re_init_context(struct bnxt_re_dev *dev,
167*9207f9d2SChandrakanth patil 				 struct bnxt_re_context *cntx,
168*9207f9d2SChandrakanth patil 				 struct bnxt_re_cntx_resp *resp, int cmd_fd)
169*9207f9d2SChandrakanth patil {
170*9207f9d2SChandrakanth patil 	bnxt_single_threaded = 0;
171*9207f9d2SChandrakanth patil 	cntx->cctx = malloc(sizeof(struct bnxt_re_chip_ctx));
172*9207f9d2SChandrakanth patil 	if (!cntx->cctx)
173*9207f9d2SChandrakanth patil 		goto failed;
174*9207f9d2SChandrakanth patil 
175*9207f9d2SChandrakanth patil 	if (BNXT_RE_ABI_VERSION >= 4) {
176*9207f9d2SChandrakanth patil 		cntx->cctx->chip_num = resp->chip_id0 & 0xFFFF;
177*9207f9d2SChandrakanth patil 		cntx->cctx->chip_rev = (resp->chip_id0 >>
178*9207f9d2SChandrakanth patil 					BNXT_RE_CHIP_ID0_CHIP_REV_SFT) & 0xFF;
179*9207f9d2SChandrakanth patil 		cntx->cctx->chip_metal = (resp->chip_id0 >>
180*9207f9d2SChandrakanth patil 					  BNXT_RE_CHIP_ID0_CHIP_MET_SFT) &
181*9207f9d2SChandrakanth patil 					  0xFF;
182*9207f9d2SChandrakanth patil 		cntx->cctx->chip_is_gen_p5_thor2 = _is_chip_gen_p5_thor2(cntx->cctx);
183*9207f9d2SChandrakanth patil 	}
184*9207f9d2SChandrakanth patil 	if (BNXT_RE_ABI_VERSION != 4) {
185*9207f9d2SChandrakanth patil 		cntx->dev_id = resp->dev_id;
186*9207f9d2SChandrakanth patil 		cntx->max_qp = resp->max_qp;
187*9207f9d2SChandrakanth patil 	}
188*9207f9d2SChandrakanth patil 
189*9207f9d2SChandrakanth patil 	if (BNXT_RE_ABI_VERSION > 5)
190*9207f9d2SChandrakanth patil 		cntx->modes = resp->modes;
191*9207f9d2SChandrakanth patil 	cntx->comp_mask = resp->comp_mask;
192*9207f9d2SChandrakanth patil 	dev->pg_size = resp->pg_size;
193*9207f9d2SChandrakanth patil 	dev->cqe_size = resp->cqe_size;
194*9207f9d2SChandrakanth patil 	dev->max_cq_depth = resp->max_cqd;
195*9207f9d2SChandrakanth patil 
196*9207f9d2SChandrakanth patil 	/* mmap shared page. */
197*9207f9d2SChandrakanth patil 	cntx->shpg = mmap(NULL, dev->pg_size, PROT_READ | PROT_WRITE,
198*9207f9d2SChandrakanth patil 			  MAP_SHARED, cmd_fd, 0);
199*9207f9d2SChandrakanth patil 	if (cntx->shpg == MAP_FAILED) {
200*9207f9d2SChandrakanth patil 		cntx->shpg = NULL;
201*9207f9d2SChandrakanth patil 		goto free;
202*9207f9d2SChandrakanth patil 	}
203*9207f9d2SChandrakanth patil 
204*9207f9d2SChandrakanth patil 	if (cntx->comp_mask & BNXT_RE_COMP_MASK_UCNTX_DBR_PACING_ENABLED) {
205*9207f9d2SChandrakanth patil 		cntx->dbr_page = mmap(NULL, dev->pg_size, PROT_READ,
206*9207f9d2SChandrakanth patil 				      MAP_SHARED, cmd_fd, BNXT_RE_DBR_PAGE);
207*9207f9d2SChandrakanth patil 		if (cntx->dbr_page == MAP_FAILED) {
208*9207f9d2SChandrakanth patil 			munmap(cntx->shpg, dev->pg_size);
209*9207f9d2SChandrakanth patil 			cntx->shpg = NULL;
210*9207f9d2SChandrakanth patil 			cntx->dbr_page = NULL;
211*9207f9d2SChandrakanth patil 			goto free;
212*9207f9d2SChandrakanth patil 		}
213*9207f9d2SChandrakanth patil 	}
214*9207f9d2SChandrakanth patil 
215*9207f9d2SChandrakanth patil 	/* check for ENV for single thread */
216*9207f9d2SChandrakanth patil 	bnxt_single_threaded = single_threaded_app();
217*9207f9d2SChandrakanth patil 	if (bnxt_single_threaded)
218*9207f9d2SChandrakanth patil 		fprintf(stderr, DEV " Running in Single threaded mode\n");
219*9207f9d2SChandrakanth patil 	bnxt_dyn_debug = enable_dynamic_debug();
220*9207f9d2SChandrakanth patil 	pthread_mutex_init(&cntx->shlock, NULL);
221*9207f9d2SChandrakanth patil 
222*9207f9d2SChandrakanth patil 	return 0;
223*9207f9d2SChandrakanth patil 
224*9207f9d2SChandrakanth patil free:
225*9207f9d2SChandrakanth patil 	free(cntx->cctx);
226*9207f9d2SChandrakanth patil failed:
227*9207f9d2SChandrakanth patil 	fprintf(stderr, DEV "Failed to initialize context for device\n");
228*9207f9d2SChandrakanth patil 	return errno;
229*9207f9d2SChandrakanth patil }
230*9207f9d2SChandrakanth patil 
231*9207f9d2SChandrakanth patil static void _bnxt_re_uninit_context(struct bnxt_re_dev *dev,
232*9207f9d2SChandrakanth patil 				    struct bnxt_re_context *cntx)
233*9207f9d2SChandrakanth patil {
234*9207f9d2SChandrakanth patil 	int ret;
235*9207f9d2SChandrakanth patil 
236*9207f9d2SChandrakanth patil 	if (cntx->comp_mask & BNXT_RE_COMP_MASK_UCNTX_DBR_PACING_ENABLED)
237*9207f9d2SChandrakanth patil 		munmap(cntx->dbr_page, dev->pg_size);
238*9207f9d2SChandrakanth patil 	/* Unmap if anything device specific was
239*9207f9d2SChandrakanth patil 	 * mapped in init_context.
240*9207f9d2SChandrakanth patil 	 */
241*9207f9d2SChandrakanth patil 	pthread_mutex_destroy(&cntx->shlock);
242*9207f9d2SChandrakanth patil 	if (cntx->shpg)
243*9207f9d2SChandrakanth patil 		munmap(cntx->shpg, dev->pg_size);
244*9207f9d2SChandrakanth patil 
245*9207f9d2SChandrakanth patil 	/* Un-map DPI only for the first PD that was
246*9207f9d2SChandrakanth patil 	 * allocated in this context.
247*9207f9d2SChandrakanth patil 	 */
248*9207f9d2SChandrakanth patil 	if (cntx->udpi.wcdbpg && cntx->udpi.wcdbpg != MAP_FAILED) {
249*9207f9d2SChandrakanth patil 		munmap(cntx->udpi.wcdbpg, dev->pg_size);
250*9207f9d2SChandrakanth patil 		cntx->udpi.wcdbpg = NULL;
251*9207f9d2SChandrakanth patil 		bnxt_re_destroy_pbuf_list(cntx);
252*9207f9d2SChandrakanth patil 	}
253*9207f9d2SChandrakanth patil 
254*9207f9d2SChandrakanth patil 	if (cntx->udpi.dbpage && cntx->udpi.dbpage != MAP_FAILED) {
255*9207f9d2SChandrakanth patil 		munmap(cntx->udpi.dbpage, dev->pg_size);
256*9207f9d2SChandrakanth patil 		cntx->udpi.dbpage = NULL;
257*9207f9d2SChandrakanth patil 	}
258*9207f9d2SChandrakanth patil 	if (_is_db_drop_recovery_enable(cntx)) {
259*9207f9d2SChandrakanth patil 		if (cntx->dbr_cq) {
260*9207f9d2SChandrakanth patil 			ret = pthread_cancel(cntx->dbr_thread);
261*9207f9d2SChandrakanth patil 			if (ret)
262*9207f9d2SChandrakanth patil 				fprintf(stderr, DEV "pthread_cancel error %d\n", ret);
263*9207f9d2SChandrakanth patil 
264*9207f9d2SChandrakanth patil 			if (cntx->db_recovery_page)
265*9207f9d2SChandrakanth patil 				munmap(cntx->db_recovery_page, dev->pg_size);
266*9207f9d2SChandrakanth patil 			ret = ibv_destroy_cq(cntx->dbr_cq);
267*9207f9d2SChandrakanth patil 			if (ret)
268*9207f9d2SChandrakanth patil 				fprintf(stderr, DEV "ibv_destroy_cq error %d\n", ret);
269*9207f9d2SChandrakanth patil 		}
270*9207f9d2SChandrakanth patil 
271*9207f9d2SChandrakanth patil 		if (cntx->dbr_ev_chan) {
272*9207f9d2SChandrakanth patil 			ret = ibv_destroy_comp_channel(cntx->dbr_ev_chan);
273*9207f9d2SChandrakanth patil 			if (ret)
274*9207f9d2SChandrakanth patil 				fprintf(stderr,
275*9207f9d2SChandrakanth patil 					DEV "ibv_destroy_comp_channel error\n");
276*9207f9d2SChandrakanth patil 		}
277*9207f9d2SChandrakanth patil 		pthread_spin_destroy(&cntx->qp_dbr_res.lock);
278*9207f9d2SChandrakanth patil 		pthread_spin_destroy(&cntx->cq_dbr_res.lock);
279*9207f9d2SChandrakanth patil 		pthread_spin_destroy(&cntx->srq_dbr_res.lock);
280*9207f9d2SChandrakanth patil 	}
281*9207f9d2SChandrakanth patil 	free(cntx->cctx);
282*9207f9d2SChandrakanth patil }
283*9207f9d2SChandrakanth patil 
284*9207f9d2SChandrakanth patil /* Context Init functions */
285*9207f9d2SChandrakanth patil int bnxt_re_init_context(struct verbs_device *vdev, struct ibv_context *ibvctx,
286*9207f9d2SChandrakanth patil 			 int cmd_fd)
287*9207f9d2SChandrakanth patil {
288*9207f9d2SChandrakanth patil 	struct bnxt_re_cntx_resp resp = {};
289*9207f9d2SChandrakanth patil 	struct bnxt_re_cntx_req req = {};
290*9207f9d2SChandrakanth patil 	struct bnxt_re_context *cntx;
291*9207f9d2SChandrakanth patil 	struct bnxt_re_dev *rdev;
292*9207f9d2SChandrakanth patil 	int ret = 0;
293*9207f9d2SChandrakanth patil 
294*9207f9d2SChandrakanth patil 	rdev = to_bnxt_re_dev(&vdev->device);
295*9207f9d2SChandrakanth patil 	cntx = to_bnxt_re_context(ibvctx);
296*9207f9d2SChandrakanth patil 	ibvctx->cmd_fd = cmd_fd;
297*9207f9d2SChandrakanth patil 
298*9207f9d2SChandrakanth patil 	req.comp_mask |= BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT;
299*9207f9d2SChandrakanth patil 	req.comp_mask |= BNXT_RE_COMP_MASK_REQ_UCNTX_RSVD_WQE;
300*9207f9d2SChandrakanth patil 	ret = ibv_cmd_get_context(ibvctx, &req.cmd, sizeof(req),
301*9207f9d2SChandrakanth patil 				  &resp.resp, sizeof(resp));
302*9207f9d2SChandrakanth patil 
303*9207f9d2SChandrakanth patil 	if (ret) {
304*9207f9d2SChandrakanth patil 		fprintf(stderr, DEV "Failed to get context for device, ret = 0x%x, errno %d\n", ret, errno);
305*9207f9d2SChandrakanth patil 		return errno;
306*9207f9d2SChandrakanth patil 	}
307*9207f9d2SChandrakanth patil 
308*9207f9d2SChandrakanth patil 	ret = _bnxt_re_init_context(rdev, cntx, &resp, cmd_fd);
309*9207f9d2SChandrakanth patil 	if (!ret)
310*9207f9d2SChandrakanth patil 		ibvctx->ops = bnxt_re_cntx_ops;
311*9207f9d2SChandrakanth patil 
312*9207f9d2SChandrakanth patil 	cntx->rdev = rdev;
313*9207f9d2SChandrakanth patil 	ret = bnxt_re_query_device_compat(&cntx->ibvctx, &rdev->devattr);
314*9207f9d2SChandrakanth patil 
315*9207f9d2SChandrakanth patil 	return ret;
316*9207f9d2SChandrakanth patil }
317*9207f9d2SChandrakanth patil 
318*9207f9d2SChandrakanth patil void bnxt_re_uninit_context(struct verbs_device *vdev,
319*9207f9d2SChandrakanth patil 			    struct ibv_context *ibvctx)
320*9207f9d2SChandrakanth patil {
321*9207f9d2SChandrakanth patil 	struct bnxt_re_context *cntx;
322*9207f9d2SChandrakanth patil 	struct bnxt_re_dev *rdev;
323*9207f9d2SChandrakanth patil 
324*9207f9d2SChandrakanth patil 	cntx = to_bnxt_re_context(ibvctx);
325*9207f9d2SChandrakanth patil 	rdev = cntx->rdev;
326*9207f9d2SChandrakanth patil 	_bnxt_re_uninit_context(rdev, cntx);
327*9207f9d2SChandrakanth patil }
328*9207f9d2SChandrakanth patil 
329*9207f9d2SChandrakanth patil static struct verbs_device_ops bnxt_re_dev_ops = {
330*9207f9d2SChandrakanth patil 	.init_context = bnxt_re_init_context,
331*9207f9d2SChandrakanth patil 	.uninit_context = bnxt_re_uninit_context,
332*9207f9d2SChandrakanth patil };
333*9207f9d2SChandrakanth patil 
334*9207f9d2SChandrakanth patil static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path,
335*9207f9d2SChandrakanth patil 						int abi_version)
336*9207f9d2SChandrakanth patil {
337*9207f9d2SChandrakanth patil 	char value[10];
338*9207f9d2SChandrakanth patil 	struct bnxt_re_dev *dev;
339*9207f9d2SChandrakanth patil 	unsigned vendor, device;
340*9207f9d2SChandrakanth patil 	int i;
341*9207f9d2SChandrakanth patil 
342*9207f9d2SChandrakanth patil 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
343*9207f9d2SChandrakanth patil 				value, sizeof(value)) < 0)
344*9207f9d2SChandrakanth patil 		return NULL;
345*9207f9d2SChandrakanth patil 	vendor = strtol(value, NULL, 16);
346*9207f9d2SChandrakanth patil 
347*9207f9d2SChandrakanth patil 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
348*9207f9d2SChandrakanth patil 				value, sizeof(value)) < 0)
349*9207f9d2SChandrakanth patil 		return NULL;
350*9207f9d2SChandrakanth patil 	device = strtol(value, NULL, 16);
351*9207f9d2SChandrakanth patil 
352*9207f9d2SChandrakanth patil 	for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i)
353*9207f9d2SChandrakanth patil 		if (vendor == cna_table[i].vendor &&
354*9207f9d2SChandrakanth patil 		    device == cna_table[i].device)
355*9207f9d2SChandrakanth patil 			goto found;
356*9207f9d2SChandrakanth patil 	return NULL;
357*9207f9d2SChandrakanth patil found:
358*9207f9d2SChandrakanth patil 	if (abi_version != BNXT_RE_ABI_VERSION) {
359*9207f9d2SChandrakanth patil 		fprintf(stderr, DEV "FATAL: Max supported ABI of %s is %d "
360*9207f9d2SChandrakanth patil 			"check for the latest version of kernel driver and"
361*9207f9d2SChandrakanth patil 			"user library\n", uverbs_sys_path, abi_version);
362*9207f9d2SChandrakanth patil 		return NULL;
363*9207f9d2SChandrakanth patil 	}
364*9207f9d2SChandrakanth patil 
365*9207f9d2SChandrakanth patil 	dev = calloc(1, sizeof(*dev));
366*9207f9d2SChandrakanth patil 	if (!dev) {
367*9207f9d2SChandrakanth patil 		fprintf(stderr, DEV "Failed to allocate device for %s\n",
368*9207f9d2SChandrakanth patil 			uverbs_sys_path);
369*9207f9d2SChandrakanth patil 		return NULL;
370*9207f9d2SChandrakanth patil 	}
371*9207f9d2SChandrakanth patil 
372*9207f9d2SChandrakanth patil 	dev->vdev.sz = sizeof(*dev);
373*9207f9d2SChandrakanth patil 	dev->vdev.size_of_context =
374*9207f9d2SChandrakanth patil 		sizeof(struct bnxt_re_context) - sizeof(struct ibv_context);
375*9207f9d2SChandrakanth patil 	dev->vdev.ops = &bnxt_re_dev_ops;
376*9207f9d2SChandrakanth patil 
377*9207f9d2SChandrakanth patil 	return &dev->vdev;
378*9207f9d2SChandrakanth patil }
379*9207f9d2SChandrakanth patil 
380*9207f9d2SChandrakanth patil static __attribute__((constructor)) void bnxt_re_register_driver(void)
381*9207f9d2SChandrakanth patil {
382*9207f9d2SChandrakanth patil 	verbs_register_driver("bnxtre", bnxt_re_driver_init);
383*9207f9d2SChandrakanth patil }
384