xref: /linux/drivers/infiniband/hw/bnxt_re/qplib_res.c (revision e3966940559d52aa1800a008dcfeec218dd31f88)
1 /*
2  * Broadcom NetXtreme-E RoCE driver.
3  *
4  * Copyright (c) 2016 - 2017, Broadcom. All rights reserved.  The term
5  * Broadcom refers to Broadcom Limited and/or its subsidiaries.
6  *
7  * This software is available to you under a choice of one of two
8  * licenses.  You may choose to be licensed under the terms of the GNU
9  * General Public License (GPL) Version 2, available from the file
10  * COPYING in the main directory of this source tree, or the
11  * BSD license below:
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in
21  *    the documentation and/or other materials provided with the
22  *    distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Description: QPLib resource manager
37  */
38 
39 #define dev_fmt(fmt) "QPLIB: " fmt
40 
41 #include <linux/spinlock.h>
42 #include <linux/pci.h>
43 #include <linux/interrupt.h>
44 #include <linux/inetdevice.h>
45 #include <linux/dma-mapping.h>
46 #include <linux/if_vlan.h>
47 #include <linux/vmalloc.h>
48 #include <rdma/ib_verbs.h>
49 #include <rdma/ib_umem.h>
50 
51 #include "roce_hsi.h"
52 #include "qplib_res.h"
53 #include "qplib_sp.h"
54 #include "qplib_rcfw.h"
55 
56 /* PBL */
57 static void __free_pbl(struct bnxt_qplib_res *res, struct bnxt_qplib_pbl *pbl,
58 		       bool is_umem)
59 {
60 	struct pci_dev *pdev = res->pdev;
61 	int i;
62 
63 	if (!is_umem) {
64 		for (i = 0; i < pbl->pg_count; i++) {
65 			if (pbl->pg_arr[i])
66 				dma_free_coherent(&pdev->dev, pbl->pg_size,
67 						  (void *)((unsigned long)
68 						   pbl->pg_arr[i] &
69 						  PAGE_MASK),
70 						  pbl->pg_map_arr[i]);
71 			else
72 				dev_warn(&pdev->dev,
73 					 "PBL free pg_arr[%d] empty?!\n", i);
74 			pbl->pg_arr[i] = NULL;
75 		}
76 	}
77 	vfree(pbl->pg_arr);
78 	pbl->pg_arr = NULL;
79 	vfree(pbl->pg_map_arr);
80 	pbl->pg_map_arr = NULL;
81 	pbl->pg_count = 0;
82 	pbl->pg_size = 0;
83 }
84 
85 static void bnxt_qplib_fill_user_dma_pages(struct bnxt_qplib_pbl *pbl,
86 					   struct bnxt_qplib_sg_info *sginfo)
87 {
88 	struct ib_block_iter biter;
89 	int i = 0;
90 
91 	rdma_umem_for_each_dma_block(sginfo->umem, &biter, sginfo->pgsize) {
92 		pbl->pg_map_arr[i] = rdma_block_iter_dma_address(&biter);
93 		pbl->pg_arr[i] = NULL;
94 		pbl->pg_count++;
95 		i++;
96 	}
97 }
98 
99 static int __alloc_pbl(struct bnxt_qplib_res *res,
100 		       struct bnxt_qplib_pbl *pbl,
101 		       struct bnxt_qplib_sg_info *sginfo)
102 {
103 	struct pci_dev *pdev = res->pdev;
104 	bool is_umem = false;
105 	u32 pages;
106 	int i;
107 
108 	if (sginfo->nopte)
109 		return 0;
110 	if (sginfo->umem)
111 		pages = ib_umem_num_dma_blocks(sginfo->umem, sginfo->pgsize);
112 	else
113 		pages = sginfo->npages;
114 	/* page ptr arrays */
115 	pbl->pg_arr = vmalloc_array(pages, sizeof(void *));
116 	if (!pbl->pg_arr)
117 		return -ENOMEM;
118 	memset(pbl->pg_arr, 0, pages * sizeof(void *));
119 
120 	pbl->pg_map_arr = vmalloc_array(pages, sizeof(dma_addr_t));
121 	if (!pbl->pg_map_arr) {
122 		vfree(pbl->pg_arr);
123 		pbl->pg_arr = NULL;
124 		return -ENOMEM;
125 	}
126 	memset(pbl->pg_map_arr, 0, pages * sizeof(dma_addr_t));
127 	pbl->pg_count = 0;
128 	pbl->pg_size = sginfo->pgsize;
129 
130 	if (!sginfo->umem) {
131 		for (i = 0; i < pages; i++) {
132 			pbl->pg_arr[i] = dma_alloc_coherent(&pdev->dev,
133 							    pbl->pg_size,
134 							    &pbl->pg_map_arr[i],
135 							    GFP_KERNEL);
136 			if (!pbl->pg_arr[i])
137 				goto fail;
138 			pbl->pg_count++;
139 		}
140 	} else {
141 		is_umem = true;
142 		bnxt_qplib_fill_user_dma_pages(pbl, sginfo);
143 	}
144 
145 	return 0;
146 fail:
147 	__free_pbl(res, pbl, is_umem);
148 	return -ENOMEM;
149 }
150 
151 /* HWQ */
152 void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res,
153 			 struct bnxt_qplib_hwq *hwq)
154 {
155 	int i;
156 
157 	if (!hwq->max_elements)
158 		return;
159 	if (hwq->level >= PBL_LVL_MAX)
160 		return;
161 
162 	for (i = 0; i < hwq->level + 1; i++) {
163 		if (i == hwq->level)
164 			__free_pbl(res, &hwq->pbl[i], hwq->is_user);
165 		else
166 			__free_pbl(res, &hwq->pbl[i], false);
167 	}
168 
169 	hwq->level = PBL_LVL_MAX;
170 	hwq->max_elements = 0;
171 	hwq->element_size = 0;
172 	hwq->prod = 0;
173 	hwq->cons = 0;
174 	hwq->cp_bit = 0;
175 }
176 
177 /* All HWQs are power of 2 in size */
178 
179 int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
180 			      struct bnxt_qplib_hwq_attr *hwq_attr)
181 {
182 	u32 npages, aux_slots, pg_size, aux_pages = 0, aux_size = 0;
183 	struct bnxt_qplib_sg_info sginfo = {};
184 	u32 depth, stride, npbl, npde;
185 	dma_addr_t *src_phys_ptr, **dst_virt_ptr;
186 	struct bnxt_qplib_res *res;
187 	struct pci_dev *pdev;
188 	int i, rc, lvl;
189 
190 	res = hwq_attr->res;
191 	pdev = res->pdev;
192 	pg_size = hwq_attr->sginfo->pgsize;
193 	hwq->level = PBL_LVL_MAX;
194 
195 	depth = roundup_pow_of_two(hwq_attr->depth);
196 	stride = roundup_pow_of_two(hwq_attr->stride);
197 	if (hwq_attr->aux_depth) {
198 		aux_slots = hwq_attr->aux_depth;
199 		aux_size = roundup_pow_of_two(hwq_attr->aux_stride);
200 		aux_pages = (aux_slots * aux_size) / pg_size;
201 		if ((aux_slots * aux_size) % pg_size)
202 			aux_pages++;
203 	}
204 
205 	if (!hwq_attr->sginfo->umem) {
206 		hwq->is_user = false;
207 		npages = (depth * stride) / pg_size + aux_pages;
208 		if ((depth * stride) % pg_size)
209 			npages++;
210 		if (!npages)
211 			return -EINVAL;
212 		hwq_attr->sginfo->npages = npages;
213 	} else {
214 		npages = ib_umem_num_dma_blocks(hwq_attr->sginfo->umem,
215 						hwq_attr->sginfo->pgsize);
216 		hwq->is_user = true;
217 	}
218 
219 	if (npages == MAX_PBL_LVL_0_PGS && !hwq_attr->sginfo->nopte) {
220 		/* This request is Level 0, map PTE */
221 		rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], hwq_attr->sginfo);
222 		if (rc)
223 			goto fail;
224 		hwq->level = PBL_LVL_0;
225 		goto done;
226 	}
227 
228 	if (npages >= MAX_PBL_LVL_0_PGS) {
229 		if (npages > MAX_PBL_LVL_1_PGS) {
230 			u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ?
231 				    0 : PTU_PTE_VALID;
232 			/* 2 levels of indirection */
233 			npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT;
234 			if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT))
235 				npbl++;
236 			npde = npbl >> MAX_PDL_LVL_SHIFT;
237 			if (npbl % BIT(MAX_PDL_LVL_SHIFT))
238 				npde++;
239 			/* Alloc PDE pages */
240 			sginfo.pgsize = npde * pg_size;
241 			sginfo.npages = 1;
242 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo);
243 			if (rc)
244 				goto fail;
245 
246 			/* Alloc PBL pages */
247 			sginfo.npages = npbl;
248 			sginfo.pgsize = PAGE_SIZE;
249 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1], &sginfo);
250 			if (rc)
251 				goto fail;
252 			/* Fill PDL with PBL page pointers */
253 			dst_virt_ptr =
254 				(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
255 			src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
256 			for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++)
257 				dst_virt_ptr[0][i] = src_phys_ptr[i] | flag;
258 
259 			/* Alloc or init PTEs */
260 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2],
261 					 hwq_attr->sginfo);
262 			if (rc)
263 				goto fail;
264 			hwq->level = PBL_LVL_2;
265 			if (hwq_attr->sginfo->nopte)
266 				goto done;
267 			/* Fill PBLs with PTE pointers */
268 			dst_virt_ptr =
269 				(dma_addr_t **)hwq->pbl[PBL_LVL_1].pg_arr;
270 			src_phys_ptr = hwq->pbl[PBL_LVL_2].pg_map_arr;
271 			for (i = 0; i < hwq->pbl[PBL_LVL_2].pg_count; i++) {
272 				dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
273 					src_phys_ptr[i] | PTU_PTE_VALID;
274 			}
275 			if (hwq_attr->type == HWQ_TYPE_QUEUE) {
276 				/* Find the last pg of the size */
277 				i = hwq->pbl[PBL_LVL_2].pg_count;
278 				dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |=
279 								  PTU_PTE_LAST;
280 				if (i > 1)
281 					dst_virt_ptr[PTR_PG(i - 2)]
282 						    [PTR_IDX(i - 2)] |=
283 						    PTU_PTE_NEXT_TO_LAST;
284 			}
285 		} else { /* pages < 512 npbl = 1, npde = 0 */
286 			u32 flag = (hwq_attr->type == HWQ_TYPE_L2_CMPL) ?
287 				    0 : PTU_PTE_VALID;
288 
289 			/* 1 level of indirection */
290 			npbl = npages >> MAX_PBL_LVL_1_PGS_SHIFT;
291 			if (npages % BIT(MAX_PBL_LVL_1_PGS_SHIFT))
292 				npbl++;
293 			sginfo.npages = npbl;
294 			sginfo.pgsize = PAGE_SIZE;
295 			/* Alloc PBL page */
296 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo);
297 			if (rc)
298 				goto fail;
299 			/* Alloc or init  PTEs */
300 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1],
301 					 hwq_attr->sginfo);
302 			if (rc)
303 				goto fail;
304 			hwq->level = PBL_LVL_1;
305 			if (hwq_attr->sginfo->nopte)
306 				goto done;
307 			/* Fill PBL with PTE pointers */
308 			dst_virt_ptr =
309 				(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
310 			src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
311 			for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++)
312 				dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
313 					src_phys_ptr[i] | flag;
314 			if (hwq_attr->type == HWQ_TYPE_QUEUE) {
315 				/* Find the last pg of the size */
316 				i = hwq->pbl[PBL_LVL_1].pg_count;
317 				dst_virt_ptr[PTR_PG(i - 1)][PTR_IDX(i - 1)] |=
318 								  PTU_PTE_LAST;
319 				if (i > 1)
320 					dst_virt_ptr[PTR_PG(i - 2)]
321 						    [PTR_IDX(i - 2)] |=
322 						    PTU_PTE_NEXT_TO_LAST;
323 			}
324 		}
325 	}
326 done:
327 	hwq->prod = 0;
328 	hwq->cons = 0;
329 	hwq->pdev = pdev;
330 	hwq->depth = hwq_attr->depth;
331 	hwq->max_elements = hwq->depth;
332 	hwq->element_size = stride;
333 	hwq->qe_ppg = pg_size / stride;
334 	/* For direct access to the elements */
335 	lvl = hwq->level;
336 	if (hwq_attr->sginfo->nopte && hwq->level)
337 		lvl = hwq->level - 1;
338 	hwq->pbl_ptr = hwq->pbl[lvl].pg_arr;
339 	hwq->pbl_dma_ptr = hwq->pbl[lvl].pg_map_arr;
340 	spin_lock_init(&hwq->lock);
341 
342 	return 0;
343 fail:
344 	bnxt_qplib_free_hwq(res, hwq);
345 	return -ENOMEM;
346 }
347 
348 /* Context Tables */
349 void bnxt_qplib_free_hwctx(struct bnxt_qplib_res *res,
350 			   struct bnxt_qplib_ctx *ctx)
351 {
352 	int i;
353 
354 	bnxt_qplib_free_hwq(res, &ctx->qpc_tbl);
355 	bnxt_qplib_free_hwq(res, &ctx->mrw_tbl);
356 	bnxt_qplib_free_hwq(res, &ctx->srqc_tbl);
357 	bnxt_qplib_free_hwq(res, &ctx->cq_tbl);
358 	bnxt_qplib_free_hwq(res, &ctx->tim_tbl);
359 	for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
360 		bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.qtbl[i]);
361 	/* restore original pde level before destroy */
362 	ctx->tqm_ctx.pde.level = ctx->tqm_ctx.pde_level;
363 	bnxt_qplib_free_hwq(res, &ctx->tqm_ctx.pde);
364 }
365 
366 static int bnxt_qplib_alloc_tqm_rings(struct bnxt_qplib_res *res,
367 				      struct bnxt_qplib_ctx *ctx)
368 {
369 	struct bnxt_qplib_hwq_attr hwq_attr = {};
370 	struct bnxt_qplib_sg_info sginfo = {};
371 	struct bnxt_qplib_tqm_ctx *tqmctx;
372 	int rc;
373 	int i;
374 
375 	tqmctx = &ctx->tqm_ctx;
376 
377 	sginfo.pgsize = PAGE_SIZE;
378 	sginfo.pgshft = PAGE_SHIFT;
379 	hwq_attr.sginfo = &sginfo;
380 	hwq_attr.res = res;
381 	hwq_attr.type = HWQ_TYPE_CTX;
382 	hwq_attr.depth = 512;
383 	hwq_attr.stride = sizeof(u64);
384 	/* Alloc pdl buffer */
385 	rc = bnxt_qplib_alloc_init_hwq(&tqmctx->pde, &hwq_attr);
386 	if (rc)
387 		goto out;
388 	/* Save original pdl level */
389 	tqmctx->pde_level = tqmctx->pde.level;
390 
391 	hwq_attr.stride = 1;
392 	for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) {
393 		if (!tqmctx->qcount[i])
394 			continue;
395 		hwq_attr.depth = ctx->qpc_count * tqmctx->qcount[i];
396 		rc = bnxt_qplib_alloc_init_hwq(&tqmctx->qtbl[i], &hwq_attr);
397 		if (rc)
398 			goto out;
399 	}
400 out:
401 	return rc;
402 }
403 
404 static void bnxt_qplib_map_tqm_pgtbl(struct bnxt_qplib_tqm_ctx *ctx)
405 {
406 	struct bnxt_qplib_hwq *tbl;
407 	dma_addr_t *dma_ptr;
408 	__le64 **pbl_ptr, *ptr;
409 	int i, j, k;
410 	int fnz_idx = -1;
411 	int pg_count;
412 
413 	pbl_ptr = (__le64 **)ctx->pde.pbl_ptr;
414 
415 	for (i = 0, j = 0; i < MAX_TQM_ALLOC_REQ;
416 	     i++, j += MAX_TQM_ALLOC_BLK_SIZE) {
417 		tbl = &ctx->qtbl[i];
418 		if (!tbl->max_elements)
419 			continue;
420 		if (fnz_idx == -1)
421 			fnz_idx = i; /* first non-zero index */
422 		switch (tbl->level) {
423 		case PBL_LVL_2:
424 			pg_count = tbl->pbl[PBL_LVL_1].pg_count;
425 			for (k = 0; k < pg_count; k++) {
426 				ptr = &pbl_ptr[PTR_PG(j + k)][PTR_IDX(j + k)];
427 				dma_ptr = &tbl->pbl[PBL_LVL_1].pg_map_arr[k];
428 				*ptr = cpu_to_le64(*dma_ptr | PTU_PTE_VALID);
429 			}
430 			break;
431 		case PBL_LVL_1:
432 		case PBL_LVL_0:
433 		default:
434 			ptr = &pbl_ptr[PTR_PG(j)][PTR_IDX(j)];
435 			*ptr = cpu_to_le64(tbl->pbl[PBL_LVL_0].pg_map_arr[0] |
436 					   PTU_PTE_VALID);
437 			break;
438 		}
439 	}
440 	if (fnz_idx == -1)
441 		fnz_idx = 0;
442 	/* update pde level as per page table programming */
443 	ctx->pde.level = (ctx->qtbl[fnz_idx].level == PBL_LVL_2) ? PBL_LVL_2 :
444 			  ctx->qtbl[fnz_idx].level + 1;
445 }
446 
447 static int bnxt_qplib_setup_tqm_rings(struct bnxt_qplib_res *res,
448 				      struct bnxt_qplib_ctx *ctx)
449 {
450 	int rc;
451 
452 	rc = bnxt_qplib_alloc_tqm_rings(res, ctx);
453 	if (rc)
454 		goto fail;
455 
456 	bnxt_qplib_map_tqm_pgtbl(&ctx->tqm_ctx);
457 fail:
458 	return rc;
459 }
460 
461 /*
462  * Routine: bnxt_qplib_alloc_hwctx
463  * Description:
464  *     Context tables are memories which are used by the chip fw.
465  *     The 6 tables defined are:
466  *             QPC ctx - holds QP states
467  *             MRW ctx - holds memory region and window
468  *             SRQ ctx - holds shared RQ states
469  *             CQ ctx - holds completion queue states
470  *             TQM ctx - holds Tx Queue Manager context
471  *             TIM ctx - holds timer context
472  *     Depending on the size of the tbl requested, either a 1 Page Buffer List
473  *     or a 1-to-2-stage indirection Page Directory List + 1 PBL is used
474  *     instead.
475  *     Table might be employed as follows:
476  *             For 0      < ctx size <= 1 PAGE, 0 level of ind is used
477  *             For 1 PAGE < ctx size <= 512 entries size, 1 level of ind is used
478  *             For 512    < ctx size <= MAX, 2 levels of ind is used
479  * Returns:
480  *     0 if success, else -ERRORS
481  */
482 int bnxt_qplib_alloc_hwctx(struct bnxt_qplib_res *res,
483 			   struct bnxt_qplib_ctx *ctx)
484 {
485 	struct bnxt_qplib_hwq_attr hwq_attr = {};
486 	struct bnxt_qplib_sg_info sginfo = {};
487 	int rc;
488 
489 	/* QPC Tables */
490 	sginfo.pgsize = PAGE_SIZE;
491 	sginfo.pgshft = PAGE_SHIFT;
492 	hwq_attr.sginfo = &sginfo;
493 
494 	hwq_attr.res = res;
495 	hwq_attr.depth = ctx->qpc_count;
496 	hwq_attr.stride = BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE;
497 	hwq_attr.type = HWQ_TYPE_CTX;
498 	rc = bnxt_qplib_alloc_init_hwq(&ctx->qpc_tbl, &hwq_attr);
499 	if (rc)
500 		goto fail;
501 
502 	/* MRW Tables */
503 	hwq_attr.depth = ctx->mrw_count;
504 	hwq_attr.stride = BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE;
505 	rc = bnxt_qplib_alloc_init_hwq(&ctx->mrw_tbl, &hwq_attr);
506 	if (rc)
507 		goto fail;
508 
509 	/* SRQ Tables */
510 	hwq_attr.depth = ctx->srqc_count;
511 	hwq_attr.stride = BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE;
512 	rc = bnxt_qplib_alloc_init_hwq(&ctx->srqc_tbl, &hwq_attr);
513 	if (rc)
514 		goto fail;
515 
516 	/* CQ Tables */
517 	hwq_attr.depth = ctx->cq_count;
518 	hwq_attr.stride = BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE;
519 	rc = bnxt_qplib_alloc_init_hwq(&ctx->cq_tbl, &hwq_attr);
520 	if (rc)
521 		goto fail;
522 
523 	/* TQM Buffer */
524 	rc = bnxt_qplib_setup_tqm_rings(res, ctx);
525 	if (rc)
526 		goto fail;
527 	/* TIM Buffer */
528 	ctx->tim_tbl.max_elements = ctx->qpc_count * 16;
529 	hwq_attr.depth = ctx->qpc_count * 16;
530 	hwq_attr.stride = 1;
531 	rc = bnxt_qplib_alloc_init_hwq(&ctx->tim_tbl, &hwq_attr);
532 	if (rc)
533 		goto fail;
534 
535 	return 0;
536 
537 fail:
538 	bnxt_qplib_free_hwctx(res, ctx);
539 	return rc;
540 }
541 
542 static void bnxt_qplib_free_sgid_tbl(struct bnxt_qplib_res *res,
543 				     struct bnxt_qplib_sgid_tbl *sgid_tbl)
544 {
545 	kfree(sgid_tbl->tbl);
546 	kfree(sgid_tbl->hw_id);
547 	kfree(sgid_tbl->ctx);
548 	kfree(sgid_tbl->vlan);
549 	sgid_tbl->tbl = NULL;
550 	sgid_tbl->hw_id = NULL;
551 	sgid_tbl->ctx = NULL;
552 	sgid_tbl->vlan = NULL;
553 	sgid_tbl->max = 0;
554 	sgid_tbl->active = 0;
555 }
556 
557 static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res *res,
558 				     struct bnxt_qplib_sgid_tbl *sgid_tbl,
559 				     u16 max)
560 {
561 	sgid_tbl->tbl = kcalloc(max, sizeof(*sgid_tbl->tbl), GFP_KERNEL);
562 	if (!sgid_tbl->tbl)
563 		return -ENOMEM;
564 
565 	sgid_tbl->hw_id = kcalloc(max, sizeof(u16), GFP_KERNEL);
566 	if (!sgid_tbl->hw_id)
567 		goto out_free1;
568 
569 	sgid_tbl->ctx = kcalloc(max, sizeof(void *), GFP_KERNEL);
570 	if (!sgid_tbl->ctx)
571 		goto out_free2;
572 
573 	sgid_tbl->vlan = kcalloc(max, sizeof(u8), GFP_KERNEL);
574 	if (!sgid_tbl->vlan)
575 		goto out_free3;
576 
577 	sgid_tbl->max = max;
578 	return 0;
579 out_free3:
580 	kfree(sgid_tbl->ctx);
581 	sgid_tbl->ctx = NULL;
582 out_free2:
583 	kfree(sgid_tbl->hw_id);
584 	sgid_tbl->hw_id = NULL;
585 out_free1:
586 	kfree(sgid_tbl->tbl);
587 	sgid_tbl->tbl = NULL;
588 	return -ENOMEM;
589 };
590 
591 static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
592 					struct bnxt_qplib_sgid_tbl *sgid_tbl)
593 {
594 	int i;
595 
596 	for (i = 0; i < sgid_tbl->max; i++) {
597 		if (memcmp(&sgid_tbl->tbl[i], &bnxt_qplib_gid_zero,
598 			   sizeof(bnxt_qplib_gid_zero)))
599 			bnxt_qplib_del_sgid(sgid_tbl, &sgid_tbl->tbl[i].gid,
600 					    sgid_tbl->tbl[i].vlan_id, true);
601 	}
602 	memset(sgid_tbl->tbl, 0, sizeof(*sgid_tbl->tbl) * sgid_tbl->max);
603 	memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
604 	memset(sgid_tbl->vlan, 0, sizeof(u8) * sgid_tbl->max);
605 	sgid_tbl->active = 0;
606 }
607 
608 static void bnxt_qplib_init_sgid_tbl(struct bnxt_qplib_sgid_tbl *sgid_tbl,
609 				     struct net_device *netdev)
610 {
611 	u32 i;
612 
613 	for (i = 0; i < sgid_tbl->max; i++)
614 		sgid_tbl->tbl[i].vlan_id = 0xffff;
615 
616 	memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
617 }
618 
619 /* PDs */
620 int bnxt_qplib_alloc_pd(struct bnxt_qplib_res  *res, struct bnxt_qplib_pd *pd)
621 {
622 	struct bnxt_qplib_pd_tbl *pdt = &res->pd_tbl;
623 	u32 bit_num;
624 	int rc = 0;
625 
626 	mutex_lock(&res->pd_tbl_lock);
627 	bit_num = find_first_bit(pdt->tbl, pdt->max);
628 	if (bit_num == pdt->max) {
629 		rc = -ENOMEM;
630 		goto exit;
631 	}
632 
633 	/* Found unused PD */
634 	clear_bit(bit_num, pdt->tbl);
635 	pd->id = bit_num;
636 exit:
637 	mutex_unlock(&res->pd_tbl_lock);
638 	return rc;
639 }
640 
641 int bnxt_qplib_dealloc_pd(struct bnxt_qplib_res *res,
642 			  struct bnxt_qplib_pd_tbl *pdt,
643 			  struct bnxt_qplib_pd *pd)
644 {
645 	int rc = 0;
646 
647 	mutex_lock(&res->pd_tbl_lock);
648 	if (test_and_set_bit(pd->id, pdt->tbl)) {
649 		dev_warn(&res->pdev->dev, "Freeing an unused PD? pdn = %d\n",
650 			 pd->id);
651 		rc = -EINVAL;
652 		goto exit;
653 	}
654 	pd->id = 0;
655 exit:
656 	mutex_unlock(&res->pd_tbl_lock);
657 	return rc;
658 }
659 
660 static void bnxt_qplib_free_pd_tbl(struct bnxt_qplib_pd_tbl *pdt)
661 {
662 	kfree(pdt->tbl);
663 	pdt->tbl = NULL;
664 	pdt->max = 0;
665 }
666 
667 static int bnxt_qplib_alloc_pd_tbl(struct bnxt_qplib_res *res,
668 				   struct bnxt_qplib_pd_tbl *pdt,
669 				   u32 max)
670 {
671 	u32 bytes;
672 
673 	bytes = max >> 3;
674 	if (!bytes)
675 		bytes = 1;
676 	pdt->tbl = kmalloc(bytes, GFP_KERNEL);
677 	if (!pdt->tbl)
678 		return -ENOMEM;
679 
680 	pdt->max = max;
681 	memset((u8 *)pdt->tbl, 0xFF, bytes);
682 	mutex_init(&res->pd_tbl_lock);
683 
684 	return 0;
685 }
686 
687 /* DPIs */
688 int bnxt_qplib_alloc_dpi(struct bnxt_qplib_res *res,
689 			 struct bnxt_qplib_dpi *dpi,
690 			 void *app, u8 type)
691 {
692 	struct bnxt_qplib_dpi_tbl *dpit = &res->dpi_tbl;
693 	struct bnxt_qplib_reg_desc *reg;
694 	u32 bit_num;
695 	u64 umaddr;
696 
697 	reg = &dpit->wcreg;
698 	mutex_lock(&res->dpi_tbl_lock);
699 
700 	bit_num = find_first_bit(dpit->tbl, dpit->max);
701 	if (bit_num == dpit->max) {
702 		mutex_unlock(&res->dpi_tbl_lock);
703 		return -ENOMEM;
704 	}
705 
706 	/* Found unused DPI */
707 	clear_bit(bit_num, dpit->tbl);
708 	dpit->app_tbl[bit_num] = app;
709 
710 	dpi->bit = bit_num;
711 	dpi->dpi = bit_num + (reg->offset - dpit->ucreg.offset) / PAGE_SIZE;
712 
713 	umaddr = reg->bar_base + reg->offset + bit_num * PAGE_SIZE;
714 	dpi->umdbr = umaddr;
715 
716 	switch (type) {
717 	case BNXT_QPLIB_DPI_TYPE_KERNEL:
718 		/* privileged dbr was already mapped just initialize it. */
719 		dpi->umdbr = dpit->ucreg.bar_base +
720 			     dpit->ucreg.offset + bit_num * PAGE_SIZE;
721 		dpi->dbr = dpit->priv_db;
722 		dpi->dpi = dpi->bit;
723 		break;
724 	case BNXT_QPLIB_DPI_TYPE_WC:
725 		dpi->dbr = ioremap_wc(umaddr, PAGE_SIZE);
726 		break;
727 	default:
728 		dpi->dbr = ioremap(umaddr, PAGE_SIZE);
729 		break;
730 	}
731 
732 	dpi->type = type;
733 	mutex_unlock(&res->dpi_tbl_lock);
734 	return 0;
735 
736 }
737 
738 int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res,
739 			   struct bnxt_qplib_dpi *dpi)
740 {
741 	struct bnxt_qplib_dpi_tbl *dpit = &res->dpi_tbl;
742 
743 	mutex_lock(&res->dpi_tbl_lock);
744 	if (dpi->dpi && dpi->type != BNXT_QPLIB_DPI_TYPE_KERNEL)
745 		pci_iounmap(res->pdev, dpi->dbr);
746 
747 	if (test_and_set_bit(dpi->bit, dpit->tbl)) {
748 		dev_warn(&res->pdev->dev,
749 			 "Freeing an unused DPI? dpi = %d, bit = %d\n",
750 				dpi->dpi, dpi->bit);
751 		mutex_unlock(&res->dpi_tbl_lock);
752 		return -EINVAL;
753 	}
754 	if (dpit->app_tbl)
755 		dpit->app_tbl[dpi->bit] = NULL;
756 	memset(dpi, 0, sizeof(*dpi));
757 	mutex_unlock(&res->dpi_tbl_lock);
758 	return 0;
759 }
760 
761 static void bnxt_qplib_free_dpi_tbl(struct bnxt_qplib_res     *res,
762 				    struct bnxt_qplib_dpi_tbl *dpit)
763 {
764 	kfree(dpit->tbl);
765 	kfree(dpit->app_tbl);
766 	dpit->tbl = NULL;
767 	dpit->app_tbl = NULL;
768 	dpit->max = 0;
769 }
770 
771 static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res *res,
772 				    struct bnxt_qplib_dev_attr *dev_attr)
773 {
774 	struct bnxt_qplib_dpi_tbl *dpit;
775 	struct bnxt_qplib_reg_desc *reg;
776 	unsigned long bar_len;
777 	u32 dbr_offset;
778 	u32 bytes;
779 
780 	dpit = &res->dpi_tbl;
781 	reg = &dpit->wcreg;
782 
783 	if (!bnxt_qplib_is_chip_gen_p5_p7(res->cctx)) {
784 		/* Offest should come from L2 driver */
785 		dbr_offset = dev_attr->l2_db_size;
786 		dpit->ucreg.offset = dbr_offset;
787 		dpit->wcreg.offset = dbr_offset;
788 	}
789 
790 	bar_len = pci_resource_len(res->pdev, reg->bar_id);
791 	dpit->max = (bar_len - reg->offset) / PAGE_SIZE;
792 	if (dev_attr->max_dpi)
793 		dpit->max = min_t(u32, dpit->max, dev_attr->max_dpi);
794 
795 	dpit->app_tbl = kcalloc(dpit->max,  sizeof(void *), GFP_KERNEL);
796 	if (!dpit->app_tbl)
797 		return -ENOMEM;
798 
799 	bytes = dpit->max >> 3;
800 	if (!bytes)
801 		bytes = 1;
802 
803 	dpit->tbl = kmalloc(bytes, GFP_KERNEL);
804 	if (!dpit->tbl) {
805 		kfree(dpit->app_tbl);
806 		dpit->app_tbl = NULL;
807 		return -ENOMEM;
808 	}
809 
810 	memset((u8 *)dpit->tbl, 0xFF, bytes);
811 	mutex_init(&res->dpi_tbl_lock);
812 	dpit->priv_db = dpit->ucreg.bar_reg + dpit->ucreg.offset;
813 
814 	return 0;
815 
816 }
817 
818 /* Stats */
819 void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev,
820 			       struct bnxt_qplib_stats *stats)
821 {
822 	if (stats->dma) {
823 		dma_free_coherent(&pdev->dev, stats->size,
824 				  stats->dma, stats->dma_map);
825 	}
826 	memset(stats, 0, sizeof(*stats));
827 	stats->fw_id = -1;
828 }
829 
830 int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev,
831 			       struct bnxt_qplib_chip_ctx *cctx,
832 			       struct bnxt_qplib_stats *stats)
833 {
834 	memset(stats, 0, sizeof(*stats));
835 	stats->fw_id = -1;
836 	stats->size = cctx->hw_stats_size;
837 	stats->dma = dma_alloc_coherent(&pdev->dev, stats->size,
838 					&stats->dma_map, GFP_KERNEL);
839 	if (!stats->dma) {
840 		dev_err(&pdev->dev, "Stats DMA allocation failed\n");
841 		return -ENOMEM;
842 	}
843 	return 0;
844 }
845 
846 void bnxt_qplib_cleanup_res(struct bnxt_qplib_res *res)
847 {
848 	bnxt_qplib_cleanup_sgid_tbl(res, &res->sgid_tbl);
849 }
850 
851 int bnxt_qplib_init_res(struct bnxt_qplib_res *res)
852 {
853 	bnxt_qplib_init_sgid_tbl(&res->sgid_tbl, res->netdev);
854 
855 	return 0;
856 }
857 
858 void bnxt_qplib_free_res(struct bnxt_qplib_res *res)
859 {
860 	kfree(res->rcfw->qp_tbl);
861 	bnxt_qplib_free_sgid_tbl(res, &res->sgid_tbl);
862 	bnxt_qplib_free_pd_tbl(&res->pd_tbl);
863 	bnxt_qplib_free_dpi_tbl(res, &res->dpi_tbl);
864 }
865 
866 int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct net_device *netdev)
867 {
868 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
869 	struct bnxt_qplib_dev_attr *dev_attr;
870 	int rc;
871 
872 	res->netdev = netdev;
873 	dev_attr = res->dattr;
874 
875 	/* Allocate one extra to hold the QP1 entries */
876 	rcfw->qp_tbl_size = max_t(u32, BNXT_RE_MAX_QPC_COUNT + 1, dev_attr->max_qp);
877 	rcfw->qp_tbl = kcalloc(rcfw->qp_tbl_size, sizeof(struct bnxt_qplib_qp_node),
878 			       GFP_KERNEL);
879 	if (!rcfw->qp_tbl)
880 		return -ENOMEM;
881 
882 	rc = bnxt_qplib_alloc_sgid_tbl(res, &res->sgid_tbl, dev_attr->max_sgid);
883 	if (rc)
884 		goto fail;
885 
886 	rc = bnxt_qplib_alloc_pd_tbl(res, &res->pd_tbl, dev_attr->max_pd);
887 	if (rc)
888 		goto fail;
889 
890 	rc = bnxt_qplib_alloc_dpi_tbl(res, dev_attr);
891 	if (rc)
892 		goto fail;
893 
894 	return 0;
895 fail:
896 	bnxt_qplib_free_res(res);
897 	return rc;
898 }
899 
900 void bnxt_qplib_unmap_db_bar(struct bnxt_qplib_res *res)
901 {
902 	struct bnxt_qplib_reg_desc *reg;
903 
904 	reg = &res->dpi_tbl.ucreg;
905 	if (reg->bar_reg)
906 		pci_iounmap(res->pdev, reg->bar_reg);
907 	reg->bar_reg = NULL;
908 	reg->bar_base = 0;
909 	reg->len = 0;
910 	reg->bar_id = 0;
911 }
912 
913 int bnxt_qplib_map_db_bar(struct bnxt_qplib_res *res)
914 {
915 	struct bnxt_qplib_reg_desc *ucreg;
916 	struct bnxt_qplib_reg_desc *wcreg;
917 
918 	wcreg = &res->dpi_tbl.wcreg;
919 	wcreg->bar_id = RCFW_DBR_PCI_BAR_REGION;
920 	wcreg->bar_base = pci_resource_start(res->pdev, wcreg->bar_id);
921 
922 	ucreg = &res->dpi_tbl.ucreg;
923 	ucreg->bar_id = RCFW_DBR_PCI_BAR_REGION;
924 	ucreg->bar_base = pci_resource_start(res->pdev, ucreg->bar_id);
925 	ucreg->len = ucreg->offset + PAGE_SIZE;
926 	if (!ucreg->len || ((ucreg->len & (PAGE_SIZE - 1)) != 0)) {
927 		dev_err(&res->pdev->dev, "QPLIB: invalid dbr length %d",
928 			(int)ucreg->len);
929 		return -EINVAL;
930 	}
931 	ucreg->bar_reg = ioremap(ucreg->bar_base, ucreg->len);
932 	if (!ucreg->bar_reg) {
933 		dev_err(&res->pdev->dev, "privileged dpi map failed!");
934 		return -ENOMEM;
935 	}
936 
937 	return 0;
938 }
939 
940 int bnxt_qplib_determine_atomics(struct pci_dev *dev)
941 {
942 	int comp;
943 	u16 ctl2;
944 
945 	comp = pci_enable_atomic_ops_to_root(dev,
946 					     PCI_EXP_DEVCAP2_ATOMIC_COMP32);
947 	if (comp)
948 		return -EOPNOTSUPP;
949 	comp = pci_enable_atomic_ops_to_root(dev,
950 					     PCI_EXP_DEVCAP2_ATOMIC_COMP64);
951 	if (comp)
952 		return -EOPNOTSUPP;
953 	pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctl2);
954 	return !(ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ);
955 }
956