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 static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw
*rcfw
,
70 struct cmdq_query_version req
;
71 struct creq_query_version_resp resp
;
75 RCFW_CMD_PREP(req
, QUERY_VERSION
, cmd_flags
);
77 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
78 (void *)&resp
, NULL
, 0);
81 fw_ver
[0] = resp
.fw_maj
;
82 fw_ver
[1] = resp
.fw_minor
;
83 fw_ver
[2] = resp
.fw_bld
;
84 fw_ver
[3] = resp
.fw_rsvd
;
87 int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw
*rcfw
,
88 struct bnxt_qplib_dev_attr
*attr
, bool vf
)
90 struct cmdq_query_func req
;
91 struct creq_query_func_resp resp
;
92 struct bnxt_qplib_rcfw_sbuf
*sbuf
;
93 struct creq_query_func_resp_sb
*sb
;
99 RCFW_CMD_PREP(req
, QUERY_FUNC
, cmd_flags
);
101 sbuf
= bnxt_qplib_rcfw_alloc_sbuf(rcfw
, sizeof(*sb
));
103 dev_err(&rcfw
->pdev
->dev
,
104 "QPLIB: SP: QUERY_FUNC alloc side buffer failed");
109 req
.resp_size
= sizeof(*sb
) / BNXT_QPLIB_CMDQE_UNITS
;
110 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
115 /* Extract the context from the side buffer */
116 attr
->max_qp
= le32_to_cpu(sb
->max_qp
);
117 /* max_qp value reported by FW for PF doesn't include the QP1 for PF */
120 attr
->max_qp_rd_atom
=
121 sb
->max_qp_rd_atom
> BNXT_QPLIB_MAX_OUT_RD_ATOM
?
122 BNXT_QPLIB_MAX_OUT_RD_ATOM
: sb
->max_qp_rd_atom
;
123 attr
->max_qp_init_rd_atom
=
124 sb
->max_qp_init_rd_atom
> BNXT_QPLIB_MAX_OUT_RD_ATOM
?
125 BNXT_QPLIB_MAX_OUT_RD_ATOM
: sb
->max_qp_init_rd_atom
;
126 attr
->max_qp_wqes
= le16_to_cpu(sb
->max_qp_wr
);
128 * 128 WQEs needs to be reserved for the HW (8916). Prevent
129 * reporting the max number
131 attr
->max_qp_wqes
-= BNXT_QPLIB_RESERVED_QP_WRS
;
132 attr
->max_qp_sges
= sb
->max_sge
;
133 attr
->max_cq
= le32_to_cpu(sb
->max_cq
);
134 attr
->max_cq_wqes
= le32_to_cpu(sb
->max_cqe
);
135 attr
->max_cq_sges
= attr
->max_qp_sges
;
136 attr
->max_mr
= le32_to_cpu(sb
->max_mr
);
137 attr
->max_mw
= le32_to_cpu(sb
->max_mw
);
139 attr
->max_mr_size
= le64_to_cpu(sb
->max_mr_size
);
140 attr
->max_pd
= 64 * 1024;
141 attr
->max_raw_ethy_qp
= le32_to_cpu(sb
->max_raw_eth_qp
);
142 attr
->max_ah
= le32_to_cpu(sb
->max_ah
);
144 attr
->max_fmr
= le32_to_cpu(sb
->max_fmr
);
145 attr
->max_map_per_fmr
= sb
->max_map_per_fmr
;
147 attr
->max_srq
= le16_to_cpu(sb
->max_srq
);
148 attr
->max_srq_wqes
= le32_to_cpu(sb
->max_srq_wr
) - 1;
149 attr
->max_srq_sges
= sb
->max_srq_sge
;
150 /* Bono only reports 1 PKEY for now, but it can support > 1 */
151 attr
->max_pkey
= le32_to_cpu(sb
->max_pkeys
);
153 attr
->max_inline_data
= le32_to_cpu(sb
->max_inline_data
);
154 attr
->l2_db_size
= (sb
->l2_db_space_size
+ 1) * PAGE_SIZE
;
155 attr
->max_sgid
= le32_to_cpu(sb
->max_gid
);
157 bnxt_qplib_query_version(rcfw
, attr
->fw_ver
);
159 for (i
= 0; i
< MAX_TQM_ALLOC_REQ
/ 4; i
++) {
160 temp
= le32_to_cpu(sb
->tqm_alloc_reqs
[i
]);
161 tqm_alloc
= (u8
*)&temp
;
162 attr
->tqm_alloc_reqs
[i
* 4] = *tqm_alloc
;
163 attr
->tqm_alloc_reqs
[i
* 4 + 1] = *(++tqm_alloc
);
164 attr
->tqm_alloc_reqs
[i
* 4 + 2] = *(++tqm_alloc
);
165 attr
->tqm_alloc_reqs
[i
* 4 + 3] = *(++tqm_alloc
);
168 attr
->is_atomic
= bnxt_qplib_is_atomic_cap(rcfw
);
170 bnxt_qplib_rcfw_free_sbuf(rcfw
, sbuf
);
174 int bnxt_qplib_set_func_resources(struct bnxt_qplib_res
*res
,
175 struct bnxt_qplib_rcfw
*rcfw
,
176 struct bnxt_qplib_ctx
*ctx
)
178 struct cmdq_set_func_resources req
;
179 struct creq_set_func_resources_resp resp
;
183 RCFW_CMD_PREP(req
, SET_FUNC_RESOURCES
, cmd_flags
);
185 req
.number_of_qp
= cpu_to_le32(ctx
->qpc_count
);
186 req
.number_of_mrw
= cpu_to_le32(ctx
->mrw_count
);
187 req
.number_of_srq
= cpu_to_le32(ctx
->srqc_count
);
188 req
.number_of_cq
= cpu_to_le32(ctx
->cq_count
);
190 req
.max_qp_per_vf
= cpu_to_le32(ctx
->vf_res
.max_qp_per_vf
);
191 req
.max_mrw_per_vf
= cpu_to_le32(ctx
->vf_res
.max_mrw_per_vf
);
192 req
.max_srq_per_vf
= cpu_to_le32(ctx
->vf_res
.max_srq_per_vf
);
193 req
.max_cq_per_vf
= cpu_to_le32(ctx
->vf_res
.max_cq_per_vf
);
194 req
.max_gid_per_vf
= cpu_to_le32(ctx
->vf_res
.max_gid_per_vf
);
196 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
200 dev_err(&res
->pdev
->dev
,
201 "QPLIB: Failed to set function resources");
207 int bnxt_qplib_get_sgid(struct bnxt_qplib_res
*res
,
208 struct bnxt_qplib_sgid_tbl
*sgid_tbl
, int index
,
209 struct bnxt_qplib_gid
*gid
)
211 if (index
> sgid_tbl
->max
) {
212 dev_err(&res
->pdev
->dev
,
213 "QPLIB: Index %d exceeded SGID table max (%d)",
214 index
, sgid_tbl
->max
);
217 memcpy(gid
, &sgid_tbl
->tbl
[index
], sizeof(*gid
));
221 int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
222 struct bnxt_qplib_gid
*gid
, bool update
)
224 struct bnxt_qplib_res
*res
= to_bnxt_qplib(sgid_tbl
,
225 struct bnxt_qplib_res
,
227 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
231 dev_err(&res
->pdev
->dev
, "QPLIB: SGID table not allocated");
234 /* Do we need a sgid_lock here? */
235 if (!sgid_tbl
->active
) {
236 dev_err(&res
->pdev
->dev
,
237 "QPLIB: SGID table has no active entries");
240 for (index
= 0; index
< sgid_tbl
->max
; index
++) {
241 if (!memcmp(&sgid_tbl
->tbl
[index
], gid
, sizeof(*gid
)))
244 if (index
== sgid_tbl
->max
) {
245 dev_warn(&res
->pdev
->dev
, "GID not found in the SGID table");
248 /* Remove GID from the SGID table */
250 struct cmdq_delete_gid req
;
251 struct creq_delete_gid_resp resp
;
255 RCFW_CMD_PREP(req
, DELETE_GID
, cmd_flags
);
256 if (sgid_tbl
->hw_id
[index
] == 0xFFFF) {
257 dev_err(&res
->pdev
->dev
,
258 "QPLIB: GID entry contains an invalid HW id");
261 req
.gid_index
= cpu_to_le16(sgid_tbl
->hw_id
[index
]);
262 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
263 (void *)&resp
, NULL
, 0);
267 memcpy(&sgid_tbl
->tbl
[index
], &bnxt_qplib_gid_zero
,
268 sizeof(bnxt_qplib_gid_zero
));
269 sgid_tbl
->vlan
[index
] = 0;
271 dev_dbg(&res
->pdev
->dev
,
272 "QPLIB: SGID deleted hw_id[0x%x] = 0x%x active = 0x%x",
273 index
, sgid_tbl
->hw_id
[index
], sgid_tbl
->active
);
274 sgid_tbl
->hw_id
[index
] = (u16
)-1;
280 int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
281 struct bnxt_qplib_gid
*gid
, u8
*smac
, u16 vlan_id
,
282 bool update
, u32
*index
)
284 struct bnxt_qplib_res
*res
= to_bnxt_qplib(sgid_tbl
,
285 struct bnxt_qplib_res
,
287 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
291 dev_err(&res
->pdev
->dev
, "QPLIB: SGID table not allocated");
294 /* Do we need a sgid_lock here? */
295 if (sgid_tbl
->active
== sgid_tbl
->max
) {
296 dev_err(&res
->pdev
->dev
, "QPLIB: SGID table is full");
299 free_idx
= sgid_tbl
->max
;
300 for (i
= 0; i
< sgid_tbl
->max
; i
++) {
301 if (!memcmp(&sgid_tbl
->tbl
[i
], gid
, sizeof(*gid
))) {
302 dev_dbg(&res
->pdev
->dev
,
303 "QPLIB: SGID entry already exist in entry %d!",
307 } else if (!memcmp(&sgid_tbl
->tbl
[i
], &bnxt_qplib_gid_zero
,
308 sizeof(bnxt_qplib_gid_zero
)) &&
309 free_idx
== sgid_tbl
->max
) {
313 if (free_idx
== sgid_tbl
->max
) {
314 dev_err(&res
->pdev
->dev
,
315 "QPLIB: SGID table is FULL but count is not MAX??");
319 struct cmdq_add_gid req
;
320 struct creq_add_gid_resp resp
;
324 RCFW_CMD_PREP(req
, ADD_GID
, cmd_flags
);
326 req
.gid
[0] = cpu_to_be32(((u32
*)gid
->data
)[3]);
327 req
.gid
[1] = cpu_to_be32(((u32
*)gid
->data
)[2]);
328 req
.gid
[2] = cpu_to_be32(((u32
*)gid
->data
)[1]);
329 req
.gid
[3] = cpu_to_be32(((u32
*)gid
->data
)[0]);
331 * driver should ensure that all RoCE traffic is always VLAN
332 * tagged if RoCE traffic is running on non-zero VLAN ID or
333 * RoCE traffic is running on non-zero Priority.
335 if ((vlan_id
!= 0xFFFF) || res
->prio
) {
336 if (vlan_id
!= 0xFFFF)
337 req
.vlan
= cpu_to_le16
338 (vlan_id
& CMDQ_ADD_GID_VLAN_VLAN_ID_MASK
);
339 req
.vlan
|= cpu_to_le16
340 (CMDQ_ADD_GID_VLAN_TPID_TPID_8100
|
341 CMDQ_ADD_GID_VLAN_VLAN_EN
);
344 /* MAC in network format */
345 req
.src_mac
[0] = cpu_to_be16(((u16
*)smac
)[0]);
346 req
.src_mac
[1] = cpu_to_be16(((u16
*)smac
)[1]);
347 req
.src_mac
[2] = cpu_to_be16(((u16
*)smac
)[2]);
349 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
350 (void *)&resp
, NULL
, 0);
353 sgid_tbl
->hw_id
[free_idx
] = le32_to_cpu(resp
.xid
);
355 /* Add GID to the sgid_tbl */
356 memcpy(&sgid_tbl
->tbl
[free_idx
], gid
, sizeof(*gid
));
358 if (vlan_id
!= 0xFFFF)
359 sgid_tbl
->vlan
[free_idx
] = 1;
361 dev_dbg(&res
->pdev
->dev
,
362 "QPLIB: SGID added hw_id[0x%x] = 0x%x active = 0x%x",
363 free_idx
, sgid_tbl
->hw_id
[free_idx
], sgid_tbl
->active
);
370 int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl
*sgid_tbl
,
371 struct bnxt_qplib_gid
*gid
, u16 gid_idx
,
374 struct bnxt_qplib_res
*res
= to_bnxt_qplib(sgid_tbl
,
375 struct bnxt_qplib_res
,
377 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
378 struct creq_modify_gid_resp resp
;
379 struct cmdq_modify_gid req
;
383 RCFW_CMD_PREP(req
, MODIFY_GID
, cmd_flags
);
385 req
.gid
[0] = cpu_to_be32(((u32
*)gid
->data
)[3]);
386 req
.gid
[1] = cpu_to_be32(((u32
*)gid
->data
)[2]);
387 req
.gid
[2] = cpu_to_be32(((u32
*)gid
->data
)[1]);
388 req
.gid
[3] = cpu_to_be32(((u32
*)gid
->data
)[0]);
390 req
.vlan
|= cpu_to_le16
391 (CMDQ_ADD_GID_VLAN_TPID_TPID_8100
|
392 CMDQ_ADD_GID_VLAN_VLAN_EN
);
395 /* MAC in network format */
396 req
.src_mac
[0] = cpu_to_be16(((u16
*)smac
)[0]);
397 req
.src_mac
[1] = cpu_to_be16(((u16
*)smac
)[1]);
398 req
.src_mac
[2] = cpu_to_be16(((u16
*)smac
)[2]);
400 req
.gid_index
= cpu_to_le16(gid_idx
);
402 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
403 (void *)&resp
, NULL
, 0);
408 int bnxt_qplib_get_pkey(struct bnxt_qplib_res
*res
,
409 struct bnxt_qplib_pkey_tbl
*pkey_tbl
, u16 index
,
412 if (index
== 0xFFFF) {
416 if (index
> pkey_tbl
->max
) {
417 dev_err(&res
->pdev
->dev
,
418 "QPLIB: Index %d exceeded PKEY table max (%d)",
419 index
, pkey_tbl
->max
);
422 memcpy(pkey
, &pkey_tbl
->tbl
[index
], sizeof(*pkey
));
426 int bnxt_qplib_del_pkey(struct bnxt_qplib_res
*res
,
427 struct bnxt_qplib_pkey_tbl
*pkey_tbl
, u16
*pkey
,
433 dev_err(&res
->pdev
->dev
, "QPLIB: PKEY table not allocated");
437 /* Do we need a pkey_lock here? */
438 if (!pkey_tbl
->active
) {
439 dev_err(&res
->pdev
->dev
,
440 "QPLIB: PKEY table has no active entries");
443 for (i
= 0; i
< pkey_tbl
->max
; i
++) {
444 if (!memcmp(&pkey_tbl
->tbl
[i
], pkey
, sizeof(*pkey
)))
447 if (i
== pkey_tbl
->max
) {
448 dev_err(&res
->pdev
->dev
,
449 "QPLIB: PKEY 0x%04x not found in the pkey table",
453 memset(&pkey_tbl
->tbl
[i
], 0, sizeof(*pkey
));
460 int bnxt_qplib_add_pkey(struct bnxt_qplib_res
*res
,
461 struct bnxt_qplib_pkey_tbl
*pkey_tbl
, u16
*pkey
,
464 int i
, free_idx
, rc
= 0;
467 dev_err(&res
->pdev
->dev
, "QPLIB: PKEY table not allocated");
471 /* Do we need a pkey_lock here? */
472 if (pkey_tbl
->active
== pkey_tbl
->max
) {
473 dev_err(&res
->pdev
->dev
, "QPLIB: PKEY table is full");
476 free_idx
= pkey_tbl
->max
;
477 for (i
= 0; i
< pkey_tbl
->max
; i
++) {
478 if (!memcmp(&pkey_tbl
->tbl
[i
], pkey
, sizeof(*pkey
)))
480 else if (!pkey_tbl
->tbl
[i
] && free_idx
== pkey_tbl
->max
)
483 if (free_idx
== pkey_tbl
->max
) {
484 dev_err(&res
->pdev
->dev
,
485 "QPLIB: PKEY table is FULL but count is not MAX??");
488 /* Add PKEY to the pkey_tbl */
489 memcpy(&pkey_tbl
->tbl
[free_idx
], pkey
, sizeof(*pkey
));
497 int bnxt_qplib_create_ah(struct bnxt_qplib_res
*res
, struct bnxt_qplib_ah
*ah
)
499 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
500 struct cmdq_create_ah req
;
501 struct creq_create_ah_resp resp
;
507 RCFW_CMD_PREP(req
, CREATE_AH
, cmd_flags
);
509 memcpy(temp32
, ah
->dgid
.data
, sizeof(struct bnxt_qplib_gid
));
510 req
.dgid
[0] = cpu_to_le32(temp32
[0]);
511 req
.dgid
[1] = cpu_to_le32(temp32
[1]);
512 req
.dgid
[2] = cpu_to_le32(temp32
[2]);
513 req
.dgid
[3] = cpu_to_le32(temp32
[3]);
515 req
.type
= ah
->nw_type
;
516 req
.hop_limit
= ah
->hop_limit
;
517 req
.sgid_index
= cpu_to_le16(res
->sgid_tbl
.hw_id
[ah
->sgid_index
]);
518 req
.dest_vlan_id_flow_label
= cpu_to_le32((ah
->flow_label
&
519 CMDQ_CREATE_AH_FLOW_LABEL_MASK
) |
520 CMDQ_CREATE_AH_DEST_VLAN_ID_MASK
);
521 req
.pd_id
= cpu_to_le32(ah
->pd
->id
);
522 req
.traffic_class
= ah
->traffic_class
;
524 /* MAC in network format */
525 memcpy(temp16
, ah
->dmac
, 6);
526 req
.dest_mac
[0] = cpu_to_le16(temp16
[0]);
527 req
.dest_mac
[1] = cpu_to_le16(temp16
[1]);
528 req
.dest_mac
[2] = cpu_to_le16(temp16
[2]);
530 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
535 ah
->id
= le32_to_cpu(resp
.xid
);
539 int bnxt_qplib_destroy_ah(struct bnxt_qplib_res
*res
, struct bnxt_qplib_ah
*ah
)
541 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
542 struct cmdq_destroy_ah req
;
543 struct creq_destroy_ah_resp resp
;
547 /* Clean up the AH table in the device */
548 RCFW_CMD_PREP(req
, DESTROY_AH
, cmd_flags
);
550 req
.ah_cid
= cpu_to_le32(ah
->id
);
552 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
560 int bnxt_qplib_free_mrw(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mrw
)
562 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
563 struct cmdq_deallocate_key req
;
564 struct creq_deallocate_key_resp resp
;
568 if (mrw
->lkey
== 0xFFFFFFFF) {
569 dev_info(&res
->pdev
->dev
,
570 "QPLIB: SP: Free a reserved lkey MRW");
574 RCFW_CMD_PREP(req
, DEALLOCATE_KEY
, cmd_flags
);
576 req
.mrw_flags
= mrw
->type
;
578 if ((mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1
) ||
579 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A
) ||
580 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B
))
581 req
.key
= cpu_to_le32(mrw
->rkey
);
583 req
.key
= cpu_to_le32(mrw
->lkey
);
585 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
590 /* Free the qplib's MRW memory */
591 if (mrw
->hwq
.max_elements
)
592 bnxt_qplib_free_hwq(res
->pdev
, &mrw
->hwq
);
597 int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mrw
)
599 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
600 struct cmdq_allocate_mrw req
;
601 struct creq_allocate_mrw_resp resp
;
606 RCFW_CMD_PREP(req
, ALLOCATE_MRW
, cmd_flags
);
608 req
.pd_id
= cpu_to_le32(mrw
->pd
->id
);
609 req
.mrw_flags
= mrw
->type
;
610 if ((mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR
&&
611 mrw
->flags
& BNXT_QPLIB_FR_PMR
) ||
612 mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A
||
613 mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B
)
614 req
.access
= CMDQ_ALLOCATE_MRW_ACCESS_CONSUMER_OWNED_KEY
;
615 tmp
= (unsigned long)mrw
;
616 req
.mrw_handle
= cpu_to_le64(tmp
);
618 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
619 (void *)&resp
, NULL
, 0);
623 if ((mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1
) ||
624 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A
) ||
625 (mrw
->type
== CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B
))
626 mrw
->rkey
= le32_to_cpu(resp
.xid
);
628 mrw
->lkey
= le32_to_cpu(resp
.xid
);
632 int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mrw
,
635 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
636 struct cmdq_deregister_mr req
;
637 struct creq_deregister_mr_resp resp
;
641 RCFW_CMD_PREP(req
, DEREGISTER_MR
, cmd_flags
);
643 req
.lkey
= cpu_to_le32(mrw
->lkey
);
644 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
645 (void *)&resp
, NULL
, block
);
649 /* Free the qplib's MR memory */
650 if (mrw
->hwq
.max_elements
) {
653 bnxt_qplib_free_hwq(res
->pdev
, &mrw
->hwq
);
659 int bnxt_qplib_reg_mr(struct bnxt_qplib_res
*res
, struct bnxt_qplib_mrw
*mr
,
660 u64
*pbl_tbl
, int num_pbls
, bool block
, u32 buf_pg_size
)
662 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
663 struct cmdq_register_mr req
;
664 struct creq_register_mr_resp resp
;
665 u16 cmd_flags
= 0, level
;
666 int pg_ptrs
, pages
, i
, rc
;
667 dma_addr_t
**pbl_ptr
;
671 /* Allocate memory for the non-leaf pages to store buf ptrs.
672 * Non-leaf pages always uses system PAGE_SIZE
674 pg_ptrs
= roundup_pow_of_two(num_pbls
);
675 pages
= pg_ptrs
>> MAX_PBL_LVL_1_PGS_SHIFT
;
679 if (pages
> MAX_PBL_LVL_1_PGS
) {
680 dev_err(&res
->pdev
->dev
, "QPLIB: SP: Reg MR pages ");
681 dev_err(&res
->pdev
->dev
,
682 "requested (0x%x) exceeded max (0x%x)",
683 pages
, MAX_PBL_LVL_1_PGS
);
686 /* Free the hwq if it already exist, must be a rereg */
687 if (mr
->hwq
.max_elements
)
688 bnxt_qplib_free_hwq(res
->pdev
, &mr
->hwq
);
690 mr
->hwq
.max_elements
= pages
;
691 /* Use system PAGE_SIZE */
692 rc
= bnxt_qplib_alloc_init_hwq(res
->pdev
, &mr
->hwq
, NULL
, 0,
693 &mr
->hwq
.max_elements
,
694 PAGE_SIZE
, 0, PAGE_SIZE
,
697 dev_err(&res
->pdev
->dev
,
698 "SP: Reg MR memory allocation failed");
701 /* Write to the hwq */
702 pbl_ptr
= (dma_addr_t
**)mr
->hwq
.pbl_ptr
;
703 for (i
= 0; i
< num_pbls
; i
++)
704 pbl_ptr
[PTR_PG(i
)][PTR_IDX(i
)] =
705 (pbl_tbl
[i
] & PAGE_MASK
) | PTU_PTE_VALID
;
708 RCFW_CMD_PREP(req
, REGISTER_MR
, cmd_flags
);
710 /* Configure the request */
711 if (mr
->hwq
.level
== PBL_LVL_MAX
) {
712 /* No PBL provided, just use system PAGE_SIZE */
717 level
= mr
->hwq
.level
+ 1;
718 req
.pbl
= cpu_to_le64(mr
->hwq
.pbl
[PBL_LVL_0
].pg_map_arr
[0]);
720 pg_size
= buf_pg_size
? buf_pg_size
: PAGE_SIZE
;
721 req
.log2_pg_size_lvl
= (level
<< CMDQ_REGISTER_MR_LVL_SFT
) |
723 CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT
) &
724 CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK
);
725 req
.log2_pbl_pg_size
= cpu_to_le16(((ilog2(PAGE_SIZE
) <<
726 CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_SFT
) &
727 CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_MASK
));
728 req
.access
= (mr
->flags
& 0xFFFF);
729 req
.va
= cpu_to_le64(mr
->va
);
730 req
.key
= cpu_to_le32(mr
->lkey
);
731 req
.mr_size
= cpu_to_le64(mr
->total_size
);
733 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
,
734 (void *)&resp
, NULL
, block
);
741 if (mr
->hwq
.max_elements
)
742 bnxt_qplib_free_hwq(res
->pdev
, &mr
->hwq
);
746 int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res
*res
,
747 struct bnxt_qplib_frpl
*frpl
,
750 int pg_ptrs
, pages
, rc
;
752 /* Re-calculate the max to fit the HWQ allocation model */
753 pg_ptrs
= roundup_pow_of_two(max_pg_ptrs
);
754 pages
= pg_ptrs
>> MAX_PBL_LVL_1_PGS_SHIFT
;
758 if (pages
> MAX_PBL_LVL_1_PGS
)
761 frpl
->hwq
.max_elements
= pages
;
762 rc
= bnxt_qplib_alloc_init_hwq(res
->pdev
, &frpl
->hwq
, NULL
, 0,
763 &frpl
->hwq
.max_elements
, PAGE_SIZE
, 0,
764 PAGE_SIZE
, HWQ_TYPE_CTX
);
766 frpl
->max_pg_ptrs
= pg_ptrs
;
771 int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res
*res
,
772 struct bnxt_qplib_frpl
*frpl
)
774 bnxt_qplib_free_hwq(res
->pdev
, &frpl
->hwq
);
778 int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res
*res
, u16
*cids
)
780 struct bnxt_qplib_rcfw
*rcfw
= res
->rcfw
;
781 struct cmdq_map_tc_to_cos req
;
782 struct creq_map_tc_to_cos_resp resp
;
785 RCFW_CMD_PREP(req
, MAP_TC_TO_COS
, cmd_flags
);
786 req
.cos0
= cpu_to_le16(cids
[0]);
787 req
.cos1
= cpu_to_le16(cids
[1]);
789 bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
, NULL
,
794 int bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw
*rcfw
,
795 struct bnxt_qplib_roce_stats
*stats
)
797 struct cmdq_query_roce_stats req
;
798 struct creq_query_roce_stats_resp resp
;
799 struct bnxt_qplib_rcfw_sbuf
*sbuf
;
800 struct creq_query_roce_stats_resp_sb
*sb
;
804 RCFW_CMD_PREP(req
, QUERY_ROCE_STATS
, cmd_flags
);
806 sbuf
= bnxt_qplib_rcfw_alloc_sbuf(rcfw
, sizeof(*sb
));
808 dev_err(&rcfw
->pdev
->dev
,
809 "QPLIB: SP: QUERY_ROCE_STATS alloc side buffer failed");
814 req
.resp_size
= sizeof(*sb
) / BNXT_QPLIB_CMDQE_UNITS
;
815 rc
= bnxt_qplib_rcfw_send_message(rcfw
, (void *)&req
, (void *)&resp
,
819 /* Extract the context from the side buffer */
820 stats
->to_retransmits
= le64_to_cpu(sb
->to_retransmits
);
821 stats
->seq_err_naks_rcvd
= le64_to_cpu(sb
->seq_err_naks_rcvd
);
822 stats
->max_retry_exceeded
= le64_to_cpu(sb
->max_retry_exceeded
);
823 stats
->rnr_naks_rcvd
= le64_to_cpu(sb
->rnr_naks_rcvd
);
824 stats
->missing_resp
= le64_to_cpu(sb
->missing_resp
);
825 stats
->unrecoverable_err
= le64_to_cpu(sb
->unrecoverable_err
);
826 stats
->bad_resp_err
= le64_to_cpu(sb
->bad_resp_err
);
827 stats
->local_qp_op_err
= le64_to_cpu(sb
->local_qp_op_err
);
828 stats
->local_protection_err
= le64_to_cpu(sb
->local_protection_err
);
829 stats
->mem_mgmt_op_err
= le64_to_cpu(sb
->mem_mgmt_op_err
);
830 stats
->remote_invalid_req_err
= le64_to_cpu(sb
->remote_invalid_req_err
);
831 stats
->remote_access_err
= le64_to_cpu(sb
->remote_access_err
);
832 stats
->remote_op_err
= le64_to_cpu(sb
->remote_op_err
);
833 stats
->dup_req
= le64_to_cpu(sb
->dup_req
);
834 stats
->res_exceed_max
= le64_to_cpu(sb
->res_exceed_max
);
835 stats
->res_length_mismatch
= le64_to_cpu(sb
->res_length_mismatch
);
836 stats
->res_exceeds_wqe
= le64_to_cpu(sb
->res_exceeds_wqe
);
837 stats
->res_opcode_err
= le64_to_cpu(sb
->res_opcode_err
);
838 stats
->res_rx_invalid_rkey
= le64_to_cpu(sb
->res_rx_invalid_rkey
);
839 stats
->res_rx_domain_err
= le64_to_cpu(sb
->res_rx_domain_err
);
840 stats
->res_rx_no_perm
= le64_to_cpu(sb
->res_rx_no_perm
);
841 stats
->res_rx_range_err
= le64_to_cpu(sb
->res_rx_range_err
);
842 stats
->res_tx_invalid_rkey
= le64_to_cpu(sb
->res_tx_invalid_rkey
);
843 stats
->res_tx_domain_err
= le64_to_cpu(sb
->res_tx_domain_err
);
844 stats
->res_tx_no_perm
= le64_to_cpu(sb
->res_tx_no_perm
);
845 stats
->res_tx_range_err
= le64_to_cpu(sb
->res_tx_range_err
);
846 stats
->res_irrq_oflow
= le64_to_cpu(sb
->res_irrq_oflow
);
847 stats
->res_unsup_opcode
= le64_to_cpu(sb
->res_unsup_opcode
);
848 stats
->res_unaligned_atomic
= le64_to_cpu(sb
->res_unaligned_atomic
);
849 stats
->res_rem_inv_err
= le64_to_cpu(sb
->res_rem_inv_err
);
850 stats
->res_mem_error
= le64_to_cpu(sb
->res_mem_error
);
851 stats
->res_srq_err
= le64_to_cpu(sb
->res_srq_err
);
852 stats
->res_cmp_err
= le64_to_cpu(sb
->res_cmp_err
);
853 stats
->res_invalid_dup_rkey
= le64_to_cpu(sb
->res_invalid_dup_rkey
);
854 stats
->res_wqe_format_err
= le64_to_cpu(sb
->res_wqe_format_err
);
855 stats
->res_cq_load_err
= le64_to_cpu(sb
->res_cq_load_err
);
856 stats
->res_srq_load_err
= le64_to_cpu(sb
->res_srq_load_err
);
857 stats
->res_tx_pci_err
= le64_to_cpu(sb
->res_tx_pci_err
);
858 stats
->res_rx_pci_err
= le64_to_cpu(sb
->res_rx_pci_err
);
860 bnxt_qplib_rcfw_free_sbuf(rcfw
, sbuf
);