2 * Broadcom NetXtreme-E RoCE driver.
4 * Copyright (c) 2016 - 2017, Broadcom. All rights reserved. The term
5 * Broadcom refers to Broadcom Limited and/or its subsidiaries.
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
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
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
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.
36 * Description: QPLib resource manager
39 #define dev_fmt(fmt) "QPLIB: " fmt
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>
48 #include "qplib_res.h"
50 #include "qplib_rcfw.h"
52 static void bnxt_qplib_free_stats_ctx(struct pci_dev
*pdev
,
53 struct bnxt_qplib_stats
*stats
);
54 static int bnxt_qplib_alloc_stats_ctx(struct pci_dev
*pdev
,
55 struct bnxt_qplib_stats
*stats
);
58 static void __free_pbl(struct pci_dev
*pdev
, struct bnxt_qplib_pbl
*pbl
,
64 for (i
= 0; i
< pbl
->pg_count
; i
++) {
66 dma_free_coherent(&pdev
->dev
, pbl
->pg_size
,
67 (void *)((unsigned long)
73 "PBL free pg_arr[%d] empty?!\n", i
);
74 pbl
->pg_arr
[i
] = NULL
;
79 kfree(pbl
->pg_map_arr
);
80 pbl
->pg_map_arr
= NULL
;
85 static int __alloc_pbl(struct pci_dev
*pdev
, struct bnxt_qplib_pbl
*pbl
,
86 struct scatterlist
*sghead
, u32 pages
, u32 pg_size
)
88 struct sg_dma_page_iter sg_iter
;
93 pbl
->pg_arr
= kcalloc(pages
, sizeof(void *), GFP_KERNEL
);
97 pbl
->pg_map_arr
= kcalloc(pages
, sizeof(dma_addr_t
), GFP_KERNEL
);
98 if (!pbl
->pg_map_arr
) {
104 pbl
->pg_size
= pg_size
;
107 for (i
= 0; i
< pages
; i
++) {
108 pbl
->pg_arr
[i
] = dma_alloc_coherent(&pdev
->dev
,
119 for_each_sg_dma_page (sghead
, &sg_iter
, pages
, 0) {
120 pbl
->pg_map_arr
[i
] = sg_page_iter_dma_address(&sg_iter
);
121 pbl
->pg_arr
[i
] = NULL
;
130 __free_pbl(pdev
, pbl
, is_umem
);
135 void bnxt_qplib_free_hwq(struct pci_dev
*pdev
, struct bnxt_qplib_hwq
*hwq
)
139 if (!hwq
->max_elements
)
141 if (hwq
->level
>= PBL_LVL_MAX
)
144 for (i
= 0; i
< hwq
->level
+ 1; i
++) {
146 __free_pbl(pdev
, &hwq
->pbl
[i
], hwq
->is_user
);
148 __free_pbl(pdev
, &hwq
->pbl
[i
], false);
151 hwq
->level
= PBL_LVL_MAX
;
152 hwq
->max_elements
= 0;
153 hwq
->element_size
= 0;
159 /* All HWQs are power of 2 in size */
160 int bnxt_qplib_alloc_init_hwq(struct pci_dev
*pdev
, struct bnxt_qplib_hwq
*hwq
,
161 struct scatterlist
*sghead
, int nmap
,
162 u32
*elements
, u32 element_size
, u32 aux
,
163 u32 pg_size
, enum bnxt_qplib_hwq_type hwq_type
)
165 u32 pages
, slots
, size
, aux_pages
= 0, aux_size
= 0;
166 dma_addr_t
*src_phys_ptr
, **dst_virt_ptr
;
169 hwq
->level
= PBL_LVL_MAX
;
171 slots
= roundup_pow_of_two(*elements
);
173 aux_size
= roundup_pow_of_two(aux
);
174 aux_pages
= (slots
* aux_size
) / pg_size
;
175 if ((slots
* aux_size
) % pg_size
)
178 size
= roundup_pow_of_two(element_size
);
181 hwq
->is_user
= false;
182 pages
= (slots
* size
) / pg_size
+ aux_pages
;
183 if ((slots
* size
) % pg_size
)
192 /* Alloc the 1st memory block; can be a PDL/PTL/PBL */
193 if (sghead
&& (pages
== MAX_PBL_LVL_0_PGS
))
194 rc
= __alloc_pbl(pdev
, &hwq
->pbl
[PBL_LVL_0
], sghead
,
197 rc
= __alloc_pbl(pdev
, &hwq
->pbl
[PBL_LVL_0
], NULL
, 1, pg_size
);
201 hwq
->level
= PBL_LVL_0
;
203 if (pages
> MAX_PBL_LVL_0_PGS
) {
204 if (pages
> MAX_PBL_LVL_1_PGS
) {
205 /* 2 levels of indirection */
206 rc
= __alloc_pbl(pdev
, &hwq
->pbl
[PBL_LVL_1
], NULL
,
207 MAX_PBL_LVL_1_PGS_FOR_LVL_2
, pg_size
);
210 /* Fill in lvl0 PBL */
212 (dma_addr_t
**)hwq
->pbl
[PBL_LVL_0
].pg_arr
;
213 src_phys_ptr
= hwq
->pbl
[PBL_LVL_1
].pg_map_arr
;
214 for (i
= 0; i
< hwq
->pbl
[PBL_LVL_1
].pg_count
; i
++)
215 dst_virt_ptr
[PTR_PG(i
)][PTR_IDX(i
)] =
216 src_phys_ptr
[i
] | PTU_PDE_VALID
;
217 hwq
->level
= PBL_LVL_1
;
219 rc
= __alloc_pbl(pdev
, &hwq
->pbl
[PBL_LVL_2
], sghead
,
224 /* Fill in lvl1 PBL */
226 (dma_addr_t
**)hwq
->pbl
[PBL_LVL_1
].pg_arr
;
227 src_phys_ptr
= hwq
->pbl
[PBL_LVL_2
].pg_map_arr
;
228 for (i
= 0; i
< hwq
->pbl
[PBL_LVL_2
].pg_count
; i
++) {
229 dst_virt_ptr
[PTR_PG(i
)][PTR_IDX(i
)] =
230 src_phys_ptr
[i
] | PTU_PTE_VALID
;
232 if (hwq_type
== HWQ_TYPE_QUEUE
) {
233 /* Find the last pg of the size */
234 i
= hwq
->pbl
[PBL_LVL_2
].pg_count
;
235 dst_virt_ptr
[PTR_PG(i
- 1)][PTR_IDX(i
- 1)] |=
238 dst_virt_ptr
[PTR_PG(i
- 2)]
240 PTU_PTE_NEXT_TO_LAST
;
242 hwq
->level
= PBL_LVL_2
;
244 u32 flag
= hwq_type
== HWQ_TYPE_L2_CMPL
? 0 :
247 /* 1 level of indirection */
248 rc
= __alloc_pbl(pdev
, &hwq
->pbl
[PBL_LVL_1
], sghead
,
252 /* Fill in lvl0 PBL */
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
[PTR_PG(i
)][PTR_IDX(i
)] =
258 src_phys_ptr
[i
] | flag
;
260 if (hwq_type
== HWQ_TYPE_QUEUE
) {
261 /* Find the last pg of the size */
262 i
= hwq
->pbl
[PBL_LVL_1
].pg_count
;
263 dst_virt_ptr
[PTR_PG(i
- 1)][PTR_IDX(i
- 1)] |=
266 dst_virt_ptr
[PTR_PG(i
- 2)]
268 PTU_PTE_NEXT_TO_LAST
;
270 hwq
->level
= PBL_LVL_1
;
274 spin_lock_init(&hwq
->lock
);
277 *elements
= hwq
->max_elements
= slots
;
278 hwq
->element_size
= size
;
280 /* For direct access to the elements */
281 hwq
->pbl_ptr
= hwq
->pbl
[hwq
->level
].pg_arr
;
282 hwq
->pbl_dma_ptr
= hwq
->pbl
[hwq
->level
].pg_map_arr
;
287 bnxt_qplib_free_hwq(pdev
, hwq
);
292 void bnxt_qplib_free_ctx(struct pci_dev
*pdev
,
293 struct bnxt_qplib_ctx
*ctx
)
297 bnxt_qplib_free_hwq(pdev
, &ctx
->qpc_tbl
);
298 bnxt_qplib_free_hwq(pdev
, &ctx
->mrw_tbl
);
299 bnxt_qplib_free_hwq(pdev
, &ctx
->srqc_tbl
);
300 bnxt_qplib_free_hwq(pdev
, &ctx
->cq_tbl
);
301 bnxt_qplib_free_hwq(pdev
, &ctx
->tim_tbl
);
302 for (i
= 0; i
< MAX_TQM_ALLOC_REQ
; i
++)
303 bnxt_qplib_free_hwq(pdev
, &ctx
->tqm_tbl
[i
]);
304 bnxt_qplib_free_hwq(pdev
, &ctx
->tqm_pde
);
305 bnxt_qplib_free_stats_ctx(pdev
, &ctx
->stats
);
309 * Routine: bnxt_qplib_alloc_ctx
311 * Context tables are memories which are used by the chip fw.
312 * The 6 tables defined are:
313 * QPC ctx - holds QP states
314 * MRW ctx - holds memory region and window
315 * SRQ ctx - holds shared RQ states
316 * CQ ctx - holds completion queue states
317 * TQM ctx - holds Tx Queue Manager context
318 * TIM ctx - holds timer context
319 * Depending on the size of the tbl requested, either a 1 Page Buffer List
320 * or a 1-to-2-stage indirection Page Directory List + 1 PBL is used
322 * Table might be employed as follows:
323 * For 0 < ctx size <= 1 PAGE, 0 level of ind is used
324 * For 1 PAGE < ctx size <= 512 entries size, 1 level of ind is used
325 * For 512 < ctx size <= MAX, 2 levels of ind is used
327 * 0 if success, else -ERRORS
329 int bnxt_qplib_alloc_ctx(struct pci_dev
*pdev
,
330 struct bnxt_qplib_ctx
*ctx
,
331 bool virt_fn
, bool is_p5
)
337 if (virt_fn
|| is_p5
)
341 ctx
->qpc_tbl
.max_elements
= ctx
->qpc_count
;
342 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->qpc_tbl
, NULL
, 0,
343 &ctx
->qpc_tbl
.max_elements
,
344 BNXT_QPLIB_MAX_QP_CTX_ENTRY_SIZE
, 0,
345 PAGE_SIZE
, HWQ_TYPE_CTX
);
350 ctx
->mrw_tbl
.max_elements
= ctx
->mrw_count
;
351 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->mrw_tbl
, NULL
, 0,
352 &ctx
->mrw_tbl
.max_elements
,
353 BNXT_QPLIB_MAX_MRW_CTX_ENTRY_SIZE
, 0,
354 PAGE_SIZE
, HWQ_TYPE_CTX
);
359 ctx
->srqc_tbl
.max_elements
= ctx
->srqc_count
;
360 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->srqc_tbl
, NULL
, 0,
361 &ctx
->srqc_tbl
.max_elements
,
362 BNXT_QPLIB_MAX_SRQ_CTX_ENTRY_SIZE
, 0,
363 PAGE_SIZE
, HWQ_TYPE_CTX
);
368 ctx
->cq_tbl
.max_elements
= ctx
->cq_count
;
369 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->cq_tbl
, NULL
, 0,
370 &ctx
->cq_tbl
.max_elements
,
371 BNXT_QPLIB_MAX_CQ_CTX_ENTRY_SIZE
, 0,
372 PAGE_SIZE
, HWQ_TYPE_CTX
);
377 ctx
->tqm_pde
.max_elements
= 512;
378 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->tqm_pde
, NULL
, 0,
379 &ctx
->tqm_pde
.max_elements
, sizeof(u64
),
380 0, PAGE_SIZE
, HWQ_TYPE_CTX
);
384 for (i
= 0; i
< MAX_TQM_ALLOC_REQ
; i
++) {
385 if (!ctx
->tqm_count
[i
])
387 ctx
->tqm_tbl
[i
].max_elements
= ctx
->qpc_count
*
389 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->tqm_tbl
[i
], NULL
, 0,
390 &ctx
->tqm_tbl
[i
].max_elements
, 1,
391 0, PAGE_SIZE
, HWQ_TYPE_CTX
);
395 pbl_ptr
= (__le64
**)ctx
->tqm_pde
.pbl_ptr
;
396 for (i
= 0, j
= 0; i
< MAX_TQM_ALLOC_REQ
;
397 i
++, j
+= MAX_TQM_ALLOC_BLK_SIZE
) {
398 if (!ctx
->tqm_tbl
[i
].max_elements
)
402 switch (ctx
->tqm_tbl
[i
].level
) {
404 for (k
= 0; k
< ctx
->tqm_tbl
[i
].pbl
[PBL_LVL_1
].pg_count
;
406 pbl_ptr
[PTR_PG(j
+ k
)][PTR_IDX(j
+ k
)] =
408 ctx
->tqm_tbl
[i
].pbl
[PBL_LVL_1
].pg_map_arr
[k
]
414 pbl_ptr
[PTR_PG(j
)][PTR_IDX(j
)] = cpu_to_le64(
415 ctx
->tqm_tbl
[i
].pbl
[PBL_LVL_0
].pg_map_arr
[0] |
422 ctx
->tqm_pde_level
= ctx
->tqm_tbl
[fnz_idx
].level
== PBL_LVL_2
?
423 PBL_LVL_2
: ctx
->tqm_tbl
[fnz_idx
].level
+ 1;
426 ctx
->tim_tbl
.max_elements
= ctx
->qpc_count
* 16;
427 rc
= bnxt_qplib_alloc_init_hwq(pdev
, &ctx
->tim_tbl
, NULL
, 0,
428 &ctx
->tim_tbl
.max_elements
, 1,
429 0, PAGE_SIZE
, HWQ_TYPE_CTX
);
435 rc
= bnxt_qplib_alloc_stats_ctx(pdev
, &ctx
->stats
);
442 bnxt_qplib_free_ctx(pdev
, ctx
);
447 void bnxt_qplib_get_guid(u8
*dev_addr
, u8
*guid
)
451 /* MAC-48 to EUI-64 mapping */
452 memcpy(mac
, dev_addr
, ETH_ALEN
);
453 guid
[0] = mac
[0] ^ 2;
463 static void bnxt_qplib_free_sgid_tbl(struct bnxt_qplib_res
*res
,
464 struct bnxt_qplib_sgid_tbl
*sgid_tbl
)
466 kfree(sgid_tbl
->tbl
);
467 kfree(sgid_tbl
->hw_id
);
468 kfree(sgid_tbl
->ctx
);
469 kfree(sgid_tbl
->vlan
);
470 sgid_tbl
->tbl
= NULL
;
471 sgid_tbl
->hw_id
= NULL
;
472 sgid_tbl
->ctx
= NULL
;
473 sgid_tbl
->vlan
= NULL
;
475 sgid_tbl
->active
= 0;
478 static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res
*res
,
479 struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
482 sgid_tbl
->tbl
= kcalloc(max
, sizeof(struct bnxt_qplib_gid
), GFP_KERNEL
);
486 sgid_tbl
->hw_id
= kcalloc(max
, sizeof(u16
), GFP_KERNEL
);
487 if (!sgid_tbl
->hw_id
)
490 sgid_tbl
->ctx
= kcalloc(max
, sizeof(void *), GFP_KERNEL
);
494 sgid_tbl
->vlan
= kcalloc(max
, sizeof(u8
), GFP_KERNEL
);
501 kfree(sgid_tbl
->ctx
);
502 sgid_tbl
->ctx
= NULL
;
504 kfree(sgid_tbl
->hw_id
);
505 sgid_tbl
->hw_id
= NULL
;
507 kfree(sgid_tbl
->tbl
);
508 sgid_tbl
->tbl
= NULL
;
512 static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res
*res
,
513 struct bnxt_qplib_sgid_tbl
*sgid_tbl
)
517 for (i
= 0; i
< sgid_tbl
->max
; i
++) {
518 if (memcmp(&sgid_tbl
->tbl
[i
], &bnxt_qplib_gid_zero
,
519 sizeof(bnxt_qplib_gid_zero
)))
520 bnxt_qplib_del_sgid(sgid_tbl
, &sgid_tbl
->tbl
[i
], true);
522 memset(sgid_tbl
->tbl
, 0, sizeof(struct bnxt_qplib_gid
) * sgid_tbl
->max
);
523 memset(sgid_tbl
->hw_id
, -1, sizeof(u16
) * sgid_tbl
->max
);
524 memset(sgid_tbl
->vlan
, 0, sizeof(u8
) * sgid_tbl
->max
);
525 sgid_tbl
->active
= 0;
528 static void bnxt_qplib_init_sgid_tbl(struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
529 struct net_device
*netdev
)
531 memset(sgid_tbl
->tbl
, 0, sizeof(struct bnxt_qplib_gid
) * sgid_tbl
->max
);
532 memset(sgid_tbl
->hw_id
, -1, sizeof(u16
) * sgid_tbl
->max
);
535 static void bnxt_qplib_free_pkey_tbl(struct bnxt_qplib_res
*res
,
536 struct bnxt_qplib_pkey_tbl
*pkey_tbl
)
539 dev_dbg(&res
->pdev
->dev
, "PKEY tbl not present\n");
541 kfree(pkey_tbl
->tbl
);
543 pkey_tbl
->tbl
= NULL
;
545 pkey_tbl
->active
= 0;
548 static int bnxt_qplib_alloc_pkey_tbl(struct bnxt_qplib_res
*res
,
549 struct bnxt_qplib_pkey_tbl
*pkey_tbl
,
552 pkey_tbl
->tbl
= kcalloc(max
, sizeof(u16
), GFP_KERNEL
);
561 int bnxt_qplib_alloc_pd(struct bnxt_qplib_pd_tbl
*pdt
, struct bnxt_qplib_pd
*pd
)
565 bit_num
= find_first_bit(pdt
->tbl
, pdt
->max
);
566 if (bit_num
== pdt
->max
)
569 /* Found unused PD */
570 clear_bit(bit_num
, pdt
->tbl
);
575 int bnxt_qplib_dealloc_pd(struct bnxt_qplib_res
*res
,
576 struct bnxt_qplib_pd_tbl
*pdt
,
577 struct bnxt_qplib_pd
*pd
)
579 if (test_and_set_bit(pd
->id
, pdt
->tbl
)) {
580 dev_warn(&res
->pdev
->dev
, "Freeing an unused PD? pdn = %d\n",
588 static void bnxt_qplib_free_pd_tbl(struct bnxt_qplib_pd_tbl
*pdt
)
595 static int bnxt_qplib_alloc_pd_tbl(struct bnxt_qplib_res
*res
,
596 struct bnxt_qplib_pd_tbl
*pdt
,
604 pdt
->tbl
= kmalloc(bytes
, GFP_KERNEL
);
609 memset((u8
*)pdt
->tbl
, 0xFF, bytes
);
615 int bnxt_qplib_alloc_dpi(struct bnxt_qplib_dpi_tbl
*dpit
,
616 struct bnxt_qplib_dpi
*dpi
,
621 bit_num
= find_first_bit(dpit
->tbl
, dpit
->max
);
622 if (bit_num
== dpit
->max
)
625 /* Found unused DPI */
626 clear_bit(bit_num
, dpit
->tbl
);
627 dpit
->app_tbl
[bit_num
] = app
;
630 dpi
->dbr
= dpit
->dbr_bar_reg_iomem
+ (bit_num
* PAGE_SIZE
);
631 dpi
->umdbr
= dpit
->unmapped_dbr
+ (bit_num
* PAGE_SIZE
);
636 int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res
*res
,
637 struct bnxt_qplib_dpi_tbl
*dpit
,
638 struct bnxt_qplib_dpi
*dpi
)
640 if (dpi
->dpi
>= dpit
->max
) {
641 dev_warn(&res
->pdev
->dev
, "Invalid DPI? dpi = %d\n", dpi
->dpi
);
644 if (test_and_set_bit(dpi
->dpi
, dpit
->tbl
)) {
645 dev_warn(&res
->pdev
->dev
, "Freeing an unused DPI? dpi = %d\n",
650 dpit
->app_tbl
[dpi
->dpi
] = NULL
;
651 memset(dpi
, 0, sizeof(*dpi
));
656 static void bnxt_qplib_free_dpi_tbl(struct bnxt_qplib_res
*res
,
657 struct bnxt_qplib_dpi_tbl
*dpit
)
660 kfree(dpit
->app_tbl
);
661 if (dpit
->dbr_bar_reg_iomem
)
662 pci_iounmap(res
->pdev
, dpit
->dbr_bar_reg_iomem
);
663 memset(dpit
, 0, sizeof(*dpit
));
666 static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res
*res
,
667 struct bnxt_qplib_dpi_tbl
*dpit
,
670 u32 dbr_bar_reg
= RCFW_DBR_PCI_BAR_REGION
;
671 resource_size_t bar_reg_base
;
674 if (dpit
->dbr_bar_reg_iomem
) {
675 dev_err(&res
->pdev
->dev
, "DBR BAR region %d already mapped\n",
680 bar_reg_base
= pci_resource_start(res
->pdev
, dbr_bar_reg
);
682 dev_err(&res
->pdev
->dev
, "BAR region %d resc start failed\n",
687 dbr_len
= pci_resource_len(res
->pdev
, dbr_bar_reg
) - dbr_offset
;
688 if (!dbr_len
|| ((dbr_len
& (PAGE_SIZE
- 1)) != 0)) {
689 dev_err(&res
->pdev
->dev
, "Invalid DBR length %d\n", dbr_len
);
693 dpit
->dbr_bar_reg_iomem
= ioremap_nocache(bar_reg_base
+ dbr_offset
,
695 if (!dpit
->dbr_bar_reg_iomem
) {
696 dev_err(&res
->pdev
->dev
,
697 "FP: DBR BAR region %d mapping failed\n", dbr_bar_reg
);
701 dpit
->unmapped_dbr
= bar_reg_base
+ dbr_offset
;
702 dpit
->max
= dbr_len
/ PAGE_SIZE
;
704 dpit
->app_tbl
= kcalloc(dpit
->max
, sizeof(void *), GFP_KERNEL
);
708 bytes
= dpit
->max
>> 3;
712 dpit
->tbl
= kmalloc(bytes
, GFP_KERNEL
);
714 kfree(dpit
->app_tbl
);
715 dpit
->app_tbl
= NULL
;
719 memset((u8
*)dpit
->tbl
, 0xFF, bytes
);
724 pci_iounmap(res
->pdev
, dpit
->dbr_bar_reg_iomem
);
729 static void bnxt_qplib_cleanup_pkey_tbl(struct bnxt_qplib_pkey_tbl
*pkey_tbl
)
731 memset(pkey_tbl
->tbl
, 0, sizeof(u16
) * pkey_tbl
->max
);
732 pkey_tbl
->active
= 0;
735 static void bnxt_qplib_init_pkey_tbl(struct bnxt_qplib_res
*res
,
736 struct bnxt_qplib_pkey_tbl
*pkey_tbl
)
740 memset(pkey_tbl
->tbl
, 0, sizeof(u16
) * pkey_tbl
->max
);
742 /* pkey default = 0xFFFF */
743 bnxt_qplib_add_pkey(res
, pkey_tbl
, &pkey
, false);
747 static void bnxt_qplib_free_stats_ctx(struct pci_dev
*pdev
,
748 struct bnxt_qplib_stats
*stats
)
751 dma_free_coherent(&pdev
->dev
, stats
->size
,
752 stats
->dma
, stats
->dma_map
);
754 memset(stats
, 0, sizeof(*stats
));
758 static int bnxt_qplib_alloc_stats_ctx(struct pci_dev
*pdev
,
759 struct bnxt_qplib_stats
*stats
)
761 memset(stats
, 0, sizeof(*stats
));
763 /* 128 byte aligned context memory is required only for 57500.
764 * However making this unconditional, it does not harm previous
767 stats
->size
= ALIGN(sizeof(struct ctx_hw_stats
), 128);
768 stats
->dma
= dma_alloc_coherent(&pdev
->dev
, stats
->size
,
769 &stats
->dma_map
, GFP_KERNEL
);
771 dev_err(&pdev
->dev
, "Stats DMA allocation failed\n");
777 void bnxt_qplib_cleanup_res(struct bnxt_qplib_res
*res
)
779 bnxt_qplib_cleanup_pkey_tbl(&res
->pkey_tbl
);
780 bnxt_qplib_cleanup_sgid_tbl(res
, &res
->sgid_tbl
);
783 int bnxt_qplib_init_res(struct bnxt_qplib_res
*res
)
785 bnxt_qplib_init_sgid_tbl(&res
->sgid_tbl
, res
->netdev
);
786 bnxt_qplib_init_pkey_tbl(res
, &res
->pkey_tbl
);
791 void bnxt_qplib_free_res(struct bnxt_qplib_res
*res
)
793 bnxt_qplib_free_pkey_tbl(res
, &res
->pkey_tbl
);
794 bnxt_qplib_free_sgid_tbl(res
, &res
->sgid_tbl
);
795 bnxt_qplib_free_pd_tbl(&res
->pd_tbl
);
796 bnxt_qplib_free_dpi_tbl(res
, &res
->dpi_tbl
);
802 int bnxt_qplib_alloc_res(struct bnxt_qplib_res
*res
, struct pci_dev
*pdev
,
803 struct net_device
*netdev
,
804 struct bnxt_qplib_dev_attr
*dev_attr
)
809 res
->netdev
= netdev
;
811 rc
= bnxt_qplib_alloc_sgid_tbl(res
, &res
->sgid_tbl
, dev_attr
->max_sgid
);
815 rc
= bnxt_qplib_alloc_pkey_tbl(res
, &res
->pkey_tbl
, dev_attr
->max_pkey
);
819 rc
= bnxt_qplib_alloc_pd_tbl(res
, &res
->pd_tbl
, dev_attr
->max_pd
);
823 rc
= bnxt_qplib_alloc_dpi_tbl(res
, &res
->dpi_tbl
, dev_attr
->l2_db_size
);
829 bnxt_qplib_free_res(res
);