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: Slow Path Operators
39 #include <linux/interrupt.h>
40 #include <linux/spinlock.h>
41 #include <linux/sched.h>
42 #include <linux/pci.h>
46 #include "qplib_res.h"
47 #include "qplib_rcfw.h"
50 const struct bnxt_qplib_gid bnxt_qplib_gid_zero
= {{ 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0 } };
55 static bool bnxt_qplib_is_atomic_cap(struct bnxt_qplib_rcfw
*rcfw
)
60 rc
= pcie_capability_read_word(rcfw
->pdev
, PCI_EXP_DEVCTL2
,
64 return !!(pcie_ctl2
& PCI_EXP_DEVCTL2_ATOMIC_REQ
);
67 int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw
*rcfw
,
68 struct bnxt_qplib_dev_attr
*attr
)
70 struct cmdq_query_func req
;
71 struct creq_query_func_resp resp
;
72 struct bnxt_qplib_rcfw_sbuf
*sbuf
;
73 struct creq_query_func_resp_sb
*sb
;
79 RCFW_CMD_PREP(req
, QUERY_FUNC
, cmd_flags
);
81 sbuf
= bnxt_qplib_rcfw_alloc_sbuf(rcfw
, sizeof(*sb
));
83 dev_err(&rcfw
->pdev
->dev
,
84 "QPLIB: SP: QUERY_FUNC alloc side buffer failed");
89 req
.resp_size
= sizeof(*sb
) / BNXT_QPLIB_CMDQE_UNITS
;
90 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
95 /* Extract the context from the side buffer */
96 attr
->max_qp
= le32_to_cpu(sb
->max_qp
);
97 /* max_qp value reported by FW for PF doesn't include the QP1 for PF */
99 attr
->max_qp_rd_atom
=
100 sb
->max_qp_rd_atom
> BNXT_QPLIB_MAX_OUT_RD_ATOM
?
101 BNXT_QPLIB_MAX_OUT_RD_ATOM
: sb
->max_qp_rd_atom
;
102 attr
->max_qp_init_rd_atom
=
103 sb
->max_qp_init_rd_atom
> BNXT_QPLIB_MAX_OUT_RD_ATOM
?
104 BNXT_QPLIB_MAX_OUT_RD_ATOM
: sb
->max_qp_init_rd_atom
;
105 attr
->max_qp_wqes
= le16_to_cpu(sb
->max_qp_wr
);
107 * 128 WQEs needs to be reserved for the HW (8916). Prevent
108 * reporting the max number
110 attr
->max_qp_wqes
-= BNXT_QPLIB_RESERVED_QP_WRS
;
111 attr
->max_qp_sges
= sb
->max_sge
;
112 attr
->max_cq
= le32_to_cpu(sb
->max_cq
);
113 attr
->max_cq_wqes
= le32_to_cpu(sb
->max_cqe
);
114 attr
->max_cq_sges
= attr
->max_qp_sges
;
115 attr
->max_mr
= le32_to_cpu(sb
->max_mr
);
116 attr
->max_mw
= le32_to_cpu(sb
->max_mw
);
118 attr
->max_mr_size
= le64_to_cpu(sb
->max_mr_size
);
119 attr
->max_pd
= 64 * 1024;
120 attr
->max_raw_ethy_qp
= le32_to_cpu(sb
->max_raw_eth_qp
);
121 attr
->max_ah
= le32_to_cpu(sb
->max_ah
);
123 attr
->max_fmr
= le32_to_cpu(sb
->max_fmr
);
124 attr
->max_map_per_fmr
= sb
->max_map_per_fmr
;
126 attr
->max_srq
= le16_to_cpu(sb
->max_srq
);
127 attr
->max_srq_wqes
= le32_to_cpu(sb
->max_srq_wr
) - 1;
128 attr
->max_srq_sges
= sb
->max_srq_sge
;
129 /* Bono only reports 1 PKEY for now, but it can support > 1 */
130 attr
->max_pkey
= le32_to_cpu(sb
->max_pkeys
);
132 attr
->max_inline_data
= le32_to_cpu(sb
->max_inline_data
);
133 attr
->l2_db_size
= (sb
->l2_db_space_size
+ 1) * PAGE_SIZE
;
134 attr
->max_sgid
= le32_to_cpu(sb
->max_gid
);
136 strlcpy(attr
->fw_ver
, "20.6.28.0", sizeof(attr
->fw_ver
));
138 for (i
= 0; i
< MAX_TQM_ALLOC_REQ
/ 4; i
++) {
139 temp
= le32_to_cpu(sb
->tqm_alloc_reqs
[i
]);
140 tqm_alloc
= (u8
*)&temp
;
141 attr
->tqm_alloc_reqs
[i
* 4] = *tqm_alloc
;
142 attr
->tqm_alloc_reqs
[i
* 4 + 1] = *(++tqm_alloc
);
143 attr
->tqm_alloc_reqs
[i
* 4 + 2] = *(++tqm_alloc
);
144 attr
->tqm_alloc_reqs
[i
* 4 + 3] = *(++tqm_alloc
);
147 attr
->is_atomic
= bnxt_qplib_is_atomic_cap(rcfw
);
149 bnxt_qplib_rcfw_free_sbuf(rcfw
, sbuf
);
154 int bnxt_qplib_get_sgid(struct bnxt_qplib_res
*res
,
155 struct bnxt_qplib_sgid_tbl
*sgid_tbl
, int index
,
156 struct bnxt_qplib_gid
*gid
)
158 if (index
> sgid_tbl
->max
) {
159 dev_err(&res
->pdev
->dev
,
160 "QPLIB: Index %d exceeded SGID table max (%d)",
161 index
, sgid_tbl
->max
);
164 memcpy(gid
, &sgid_tbl
->tbl
[index
], sizeof(*gid
));
168 int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
169 struct bnxt_qplib_gid
*gid
, bool update
)
171 struct bnxt_qplib_res
*res
= to_bnxt_qplib(sgid_tbl
,
172 struct bnxt_qplib_res
,
174 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
178 dev_err(&res
->pdev
->dev
, "QPLIB: SGID table not allocated");
181 /* Do we need a sgid_lock here? */
182 if (!sgid_tbl
->active
) {
183 dev_err(&res
->pdev
->dev
,
184 "QPLIB: SGID table has no active entries");
187 for (index
= 0; index
< sgid_tbl
->max
; index
++) {
188 if (!memcmp(&sgid_tbl
->tbl
[index
], gid
, sizeof(*gid
)))
191 if (index
== sgid_tbl
->max
) {
192 dev_warn(&res
->pdev
->dev
, "GID not found in the SGID table");
195 /* Remove GID from the SGID table */
197 struct cmdq_delete_gid req
;
198 struct creq_delete_gid_resp resp
;
202 RCFW_CMD_PREP(req
, DELETE_GID
, cmd_flags
);
203 if (sgid_tbl
->hw_id
[index
] == 0xFFFF) {
204 dev_err(&res
->pdev
->dev
,
205 "QPLIB: GID entry contains an invalid HW id");
208 req
.gid_index
= cpu_to_le16(sgid_tbl
->hw_id
[index
]);
209 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
210 (void *)&resp
, NULL
, 0);
214 memcpy(&sgid_tbl
->tbl
[index
], &bnxt_qplib_gid_zero
,
215 sizeof(bnxt_qplib_gid_zero
));
217 dev_dbg(&res
->pdev
->dev
,
218 "QPLIB: SGID deleted hw_id[0x%x] = 0x%x active = 0x%x",
219 index
, sgid_tbl
->hw_id
[index
], sgid_tbl
->active
);
220 sgid_tbl
->hw_id
[index
] = (u16
)-1;
226 int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
227 struct bnxt_qplib_gid
*gid
, u8
*smac
, u16 vlan_id
,
228 bool update
, u32
*index
)
230 struct bnxt_qplib_res
*res
= to_bnxt_qplib(sgid_tbl
,
231 struct bnxt_qplib_res
,
233 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
237 dev_err(&res
->pdev
->dev
, "QPLIB: SGID table not allocated");
240 /* Do we need a sgid_lock here? */
241 if (sgid_tbl
->active
== sgid_tbl
->max
) {
242 dev_err(&res
->pdev
->dev
, "QPLIB: SGID table is full");
245 free_idx
= sgid_tbl
->max
;
246 for (i
= 0; i
< sgid_tbl
->max
; i
++) {
247 if (!memcmp(&sgid_tbl
->tbl
[i
], gid
, sizeof(*gid
))) {
248 dev_dbg(&res
->pdev
->dev
,
249 "QPLIB: SGID entry already exist in entry %d!",
253 } else if (!memcmp(&sgid_tbl
->tbl
[i
], &bnxt_qplib_gid_zero
,
254 sizeof(bnxt_qplib_gid_zero
)) &&
255 free_idx
== sgid_tbl
->max
) {
259 if (free_idx
== sgid_tbl
->max
) {
260 dev_err(&res
->pdev
->dev
,
261 "QPLIB: SGID table is FULL but count is not MAX??");
265 struct cmdq_add_gid req
;
266 struct creq_add_gid_resp resp
;
272 RCFW_CMD_PREP(req
, ADD_GID
, cmd_flags
);
274 memcpy(temp32
, gid
->data
, sizeof(struct bnxt_qplib_gid
));
275 req
.gid
[0] = cpu_to_be32(temp32
[3]);
276 req
.gid
[1] = cpu_to_be32(temp32
[2]);
277 req
.gid
[2] = cpu_to_be32(temp32
[1]);
278 req
.gid
[3] = cpu_to_be32(temp32
[0]);
279 if (vlan_id
!= 0xFFFF)
280 req
.vlan
= cpu_to_le16((vlan_id
&
281 CMDQ_ADD_GID_VLAN_VLAN_ID_MASK
) |
282 CMDQ_ADD_GID_VLAN_TPID_TPID_8100
|
283 CMDQ_ADD_GID_VLAN_VLAN_EN
);
285 /* MAC in network format */
286 memcpy(temp16
, smac
, 6);
287 req
.src_mac
[0] = cpu_to_be16(temp16
[0]);
288 req
.src_mac
[1] = cpu_to_be16(temp16
[1]);
289 req
.src_mac
[2] = cpu_to_be16(temp16
[2]);
291 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
292 (void *)&resp
, NULL
, 0);
295 sgid_tbl
->hw_id
[free_idx
] = le32_to_cpu(resp
.xid
);
297 /* Add GID to the sgid_tbl */
298 memcpy(&sgid_tbl
->tbl
[free_idx
], gid
, sizeof(*gid
));
300 dev_dbg(&res
->pdev
->dev
,
301 "QPLIB: SGID added hw_id[0x%x] = 0x%x active = 0x%x",
302 free_idx
, sgid_tbl
->hw_id
[free_idx
], sgid_tbl
->active
);
310 int bnxt_qplib_get_pkey(struct bnxt_qplib_res
*res
,
311 struct bnxt_qplib_pkey_tbl
*pkey_tbl
, u16 index
,
314 if (index
== 0xFFFF) {
318 if (index
> pkey_tbl
->max
) {
319 dev_err(&res
->pdev
->dev
,
320 "QPLIB: Index %d exceeded PKEY table max (%d)",
321 index
, pkey_tbl
->max
);
324 memcpy(pkey
, &pkey_tbl
->tbl
[index
], sizeof(*pkey
));
328 int bnxt_qplib_del_pkey(struct bnxt_qplib_res
*res
,
329 struct bnxt_qplib_pkey_tbl
*pkey_tbl
, u16
*pkey
,
335 dev_err(&res
->pdev
->dev
, "QPLIB: PKEY table not allocated");
339 /* Do we need a pkey_lock here? */
340 if (!pkey_tbl
->active
) {
341 dev_err(&res
->pdev
->dev
,
342 "QPLIB: PKEY table has no active entries");
345 for (i
= 0; i
< pkey_tbl
->max
; i
++) {
346 if (!memcmp(&pkey_tbl
->tbl
[i
], pkey
, sizeof(*pkey
)))
349 if (i
== pkey_tbl
->max
) {
350 dev_err(&res
->pdev
->dev
,
351 "QPLIB: PKEY 0x%04x not found in the pkey table",
355 memset(&pkey_tbl
->tbl
[i
], 0, sizeof(*pkey
));
362 int bnxt_qplib_add_pkey(struct bnxt_qplib_res
*res
,
363 struct bnxt_qplib_pkey_tbl
*pkey_tbl
, u16
*pkey
,
366 int i
, free_idx
, rc
= 0;
369 dev_err(&res
->pdev
->dev
, "QPLIB: PKEY table not allocated");
373 /* Do we need a pkey_lock here? */
374 if (pkey_tbl
->active
== pkey_tbl
->max
) {
375 dev_err(&res
->pdev
->dev
, "QPLIB: PKEY table is full");
378 free_idx
= pkey_tbl
->max
;
379 for (i
= 0; i
< pkey_tbl
->max
; i
++) {
380 if (!memcmp(&pkey_tbl
->tbl
[i
], pkey
, sizeof(*pkey
)))
382 else if (!pkey_tbl
->tbl
[i
] && free_idx
== pkey_tbl
->max
)
385 if (free_idx
== pkey_tbl
->max
) {
386 dev_err(&res
->pdev
->dev
,
387 "QPLIB: PKEY table is FULL but count is not MAX??");
390 /* Add PKEY to the pkey_tbl */
391 memcpy(&pkey_tbl
->tbl
[free_idx
], pkey
, sizeof(*pkey
));
399 int bnxt_qplib_create_ah(struct bnxt_qplib_res
*res
, struct bnxt_qplib_ah
*ah
)
401 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
402 struct cmdq_create_ah req
;
403 struct creq_create_ah_resp resp
;
409 RCFW_CMD_PREP(req
, CREATE_AH
, cmd_flags
);
411 memcpy(temp32
, ah
->dgid
.data
, sizeof(struct bnxt_qplib_gid
));
412 req
.dgid
[0] = cpu_to_le32(temp32
[0]);
413 req
.dgid
[1] = cpu_to_le32(temp32
[1]);
414 req
.dgid
[2] = cpu_to_le32(temp32
[2]);
415 req
.dgid
[3] = cpu_to_le32(temp32
[3]);
417 req
.type
= ah
->nw_type
;
418 req
.hop_limit
= ah
->hop_limit
;
419 req
.sgid_index
= cpu_to_le16(res
->sgid_tbl
.hw_id
[ah
->sgid_index
]);
420 req
.dest_vlan_id_flow_label
= cpu_to_le32((ah
->flow_label
&
421 CMDQ_CREATE_AH_FLOW_LABEL_MASK
) |
422 CMDQ_CREATE_AH_DEST_VLAN_ID_MASK
);
423 req
.pd_id
= cpu_to_le32(ah
->pd
->id
);
424 req
.traffic_class
= ah
->traffic_class
;
426 /* MAC in network format */
427 memcpy(temp16
, ah
->dmac
, 6);
428 req
.dest_mac
[0] = cpu_to_le16(temp16
[0]);
429 req
.dest_mac
[1] = cpu_to_le16(temp16
[1]);
430 req
.dest_mac
[2] = cpu_to_le16(temp16
[2]);
432 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
437 ah
->id
= le32_to_cpu(resp
.xid
);
441 int bnxt_qplib_destroy_ah(struct bnxt_qplib_res
*res
, struct bnxt_qplib_ah
*ah
)
443 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
444 struct cmdq_destroy_ah req
;
445 struct creq_destroy_ah_resp resp
;
449 /* Clean up the AH table in the device */
450 RCFW_CMD_PREP(req
, DESTROY_AH
, cmd_flags
);
452 req
.ah_cid
= cpu_to_le32(ah
->id
);
454 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
462 int bnxt_qplib_free_mrw(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mrw
)
464 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
465 struct cmdq_deallocate_key req
;
466 struct creq_deallocate_key_resp resp
;
470 if (mrw
->lkey
== 0xFFFFFFFF) {
471 dev_info(&res
->pdev
->dev
,
472 "QPLIB: SP: Free a reserved lkey MRW");
476 RCFW_CMD_PREP(req
, DEALLOCATE_KEY
, cmd_flags
);
478 req
.mrw_flags
= mrw
->type
;
480 if ((mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1
) ||
481 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A
) ||
482 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B
))
483 req
.key
= cpu_to_le32(mrw
->rkey
);
485 req
.key
= cpu_to_le32(mrw
->lkey
);
487 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
492 /* Free the qplib's MRW memory */
493 if (mrw
->hwq
.max_elements
)
494 bnxt_qplib_free_hwq(res
->pdev
, &mrw
->hwq
);
499 int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mrw
)
501 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
502 struct cmdq_allocate_mrw req
;
503 struct creq_allocate_mrw_resp resp
;
508 RCFW_CMD_PREP(req
, ALLOCATE_MRW
, cmd_flags
);
510 req
.pd_id
= cpu_to_le32(mrw
->pd
->id
);
511 req
.mrw_flags
= mrw
->type
;
512 if ((mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR
&&
513 mrw
->flags
& BNXT_QPLIB_FR_PMR
) ||
514 mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A
||
515 mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B
)
516 req
.access
= CMDQ_ALLOCATE_MRW_ACCESS_CONSUMER_OWNED_KEY
;
517 tmp
= (unsigned long)mrw
;
518 req
.mrw_handle
= cpu_to_le64(tmp
);
520 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
521 (void *)&resp
, NULL
, 0);
525 if ((mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1
) ||
526 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A
) ||
527 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B
))
528 mrw
->rkey
= le32_to_cpu(resp
.xid
);
530 mrw
->lkey
= le32_to_cpu(resp
.xid
);
534 int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mrw
,
537 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
538 struct cmdq_deregister_mr req
;
539 struct creq_deregister_mr_resp resp
;
543 RCFW_CMD_PREP(req
, DEREGISTER_MR
, cmd_flags
);
545 req
.lkey
= cpu_to_le32(mrw
->lkey
);
546 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
547 (void *)&resp
, NULL
, block
);
551 /* Free the qplib's MR memory */
552 if (mrw
->hwq
.max_elements
) {
555 bnxt_qplib_free_hwq(res
->pdev
, &mrw
->hwq
);
561 int bnxt_qplib_reg_mr(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mr
,
562 u64
*pbl_tbl
, int num_pbls
, bool block
)
564 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
565 struct cmdq_register_mr req
;
566 struct creq_register_mr_resp resp
;
567 u16 cmd_flags
= 0, level
;
568 int pg_ptrs
, pages
, i
, rc
;
569 dma_addr_t
**pbl_ptr
;
573 pg_ptrs
= roundup_pow_of_two(num_pbls
);
574 pages
= pg_ptrs
>> MAX_PBL_LVL_1_PGS_SHIFT
;
578 if (pages
> MAX_PBL_LVL_1_PGS
) {
579 dev_err(&res
->pdev
->dev
, "QPLIB: SP: Reg MR pages ");
580 dev_err(&res
->pdev
->dev
,
581 "requested (0x%x) exceeded max (0x%x)",
582 pages
, MAX_PBL_LVL_1_PGS
);
585 /* Free the hwq if it already exist, must be a rereg */
586 if (mr
->hwq
.max_elements
)
587 bnxt_qplib_free_hwq(res
->pdev
, &mr
->hwq
);
589 mr
->hwq
.max_elements
= pages
;
590 rc
= bnxt_qplib_alloc_init_hwq(res
->pdev
, &mr
->hwq
, NULL
, 0,
591 &mr
->hwq
.max_elements
,
592 PAGE_SIZE
, 0, PAGE_SIZE
,
595 dev_err(&res
->pdev
->dev
,
596 "SP: Reg MR memory allocation failed");
599 /* Write to the hwq */
600 pbl_ptr
= (dma_addr_t
**)mr
->hwq
.pbl_ptr
;
601 for (i
= 0; i
< num_pbls
; i
++)
602 pbl_ptr
[PTR_PG(i
)][PTR_IDX(i
)] =
603 (pbl_tbl
[i
] & PAGE_MASK
) | PTU_PTE_VALID
;
606 RCFW_CMD_PREP(req
, REGISTER_MR
, cmd_flags
);
608 /* Configure the request */
609 if (mr
->hwq
.level
== PBL_LVL_MAX
) {
614 level
= mr
->hwq
.level
+ 1;
615 req
.pbl
= cpu_to_le64(mr
->hwq
.pbl
[PBL_LVL_0
].pg_map_arr
[0]);
616 pg_size
= mr
->hwq
.pbl
[PBL_LVL_0
].pg_size
;
618 req
.log2_pg_size_lvl
= (level
<< CMDQ_REGISTER_MR_LVL_SFT
) |
620 CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT
) &
621 CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK
);
622 req
.access
= (mr
->flags
& 0xFFFF);
623 req
.va
= cpu_to_le64(mr
->va
);
624 req
.key
= cpu_to_le32(mr
->lkey
);
625 req
.mr_size
= cpu_to_le64(mr
->total_size
);
627 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
628 (void *)&resp
, NULL
, block
);
635 if (mr
->hwq
.max_elements
)
636 bnxt_qplib_free_hwq(res
->pdev
, &mr
->hwq
);
640 int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res
*res
,
641 struct bnxt_qplib_frpl
*frpl
,
644 int pg_ptrs
, pages
, rc
;
646 /* Re-calculate the max to fit the HWQ allocation model */
647 pg_ptrs
= roundup_pow_of_two(max_pg_ptrs
);
648 pages
= pg_ptrs
>> MAX_PBL_LVL_1_PGS_SHIFT
;
652 if (pages
> MAX_PBL_LVL_1_PGS
)
655 frpl
->hwq
.max_elements
= pages
;
656 rc
= bnxt_qplib_alloc_init_hwq(res
->pdev
, &frpl
->hwq
, NULL
, 0,
657 &frpl
->hwq
.max_elements
, PAGE_SIZE
, 0,
658 PAGE_SIZE
, HWQ_TYPE_CTX
);
660 frpl
->max_pg_ptrs
= pg_ptrs
;
665 int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res
*res
,
666 struct bnxt_qplib_frpl
*frpl
)
668 bnxt_qplib_free_hwq(res
->pdev
, &frpl
->hwq
);
672 int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res
*res
, u16
*cids
)
674 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
675 struct cmdq_map_tc_to_cos req
;
676 struct creq_map_tc_to_cos_resp resp
;
680 RCFW_CMD_PREP(req
, MAP_TC_TO_COS
, cmd_flags
);
681 req
.cos0
= cpu_to_le16(cids
[0]);
682 req
.cos1
= cpu_to_le16(cids
[1]);
684 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
685 (void *)&resp
, NULL
, 0);