xref: /linux/drivers/infiniband/hw/bnxt_re/qplib_sp.c (revision f786eebb)
11ac5a404SSelvin Xavier /*
21ac5a404SSelvin Xavier  * Broadcom NetXtreme-E RoCE driver.
31ac5a404SSelvin Xavier  *
41ac5a404SSelvin Xavier  * Copyright (c) 2016 - 2017, Broadcom. All rights reserved.  The term
51ac5a404SSelvin Xavier  * Broadcom refers to Broadcom Limited and/or its subsidiaries.
61ac5a404SSelvin Xavier  *
71ac5a404SSelvin Xavier  * This software is available to you under a choice of one of two
81ac5a404SSelvin Xavier  * licenses.  You may choose to be licensed under the terms of the GNU
91ac5a404SSelvin Xavier  * General Public License (GPL) Version 2, available from the file
101ac5a404SSelvin Xavier  * COPYING in the main directory of this source tree, or the
111ac5a404SSelvin Xavier  * BSD license below:
121ac5a404SSelvin Xavier  *
131ac5a404SSelvin Xavier  * Redistribution and use in source and binary forms, with or without
141ac5a404SSelvin Xavier  * modification, are permitted provided that the following conditions
151ac5a404SSelvin Xavier  * are met:
161ac5a404SSelvin Xavier  *
171ac5a404SSelvin Xavier  * 1. Redistributions of source code must retain the above copyright
181ac5a404SSelvin Xavier  *    notice, this list of conditions and the following disclaimer.
191ac5a404SSelvin Xavier  * 2. Redistributions in binary form must reproduce the above copyright
201ac5a404SSelvin Xavier  *    notice, this list of conditions and the following disclaimer in
211ac5a404SSelvin Xavier  *    the documentation and/or other materials provided with the
221ac5a404SSelvin Xavier  *    distribution.
231ac5a404SSelvin Xavier  *
241ac5a404SSelvin Xavier  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
251ac5a404SSelvin Xavier  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
261ac5a404SSelvin Xavier  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
271ac5a404SSelvin Xavier  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
281ac5a404SSelvin Xavier  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
291ac5a404SSelvin Xavier  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
301ac5a404SSelvin Xavier  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
311ac5a404SSelvin Xavier  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
321ac5a404SSelvin Xavier  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
331ac5a404SSelvin Xavier  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
341ac5a404SSelvin Xavier  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351ac5a404SSelvin Xavier  *
361ac5a404SSelvin Xavier  * Description: Slow Path Operators
371ac5a404SSelvin Xavier  */
381ac5a404SSelvin Xavier 
3908920b8fSJoe Perches #define dev_fmt(fmt) "QPLIB: " fmt
4008920b8fSJoe Perches 
411ac5a404SSelvin Xavier #include <linux/interrupt.h>
421ac5a404SSelvin Xavier #include <linux/spinlock.h>
431ac5a404SSelvin Xavier #include <linux/sched.h>
441ac5a404SSelvin Xavier #include <linux/pci.h>
451ac5a404SSelvin Xavier 
461ac5a404SSelvin Xavier #include "roce_hsi.h"
471ac5a404SSelvin Xavier 
481ac5a404SSelvin Xavier #include "qplib_res.h"
491ac5a404SSelvin Xavier #include "qplib_rcfw.h"
501ac5a404SSelvin Xavier #include "qplib_sp.h"
51f13bcef0SSelvin Xavier #include "qplib_tlv.h"
521ac5a404SSelvin Xavier 
531ac5a404SSelvin Xavier const struct bnxt_qplib_gid bnxt_qplib_gid_zero = {{ 0, 0, 0, 0, 0, 0, 0, 0,
541ac5a404SSelvin Xavier 						     0, 0, 0, 0, 0, 0, 0, 0 } };
551ac5a404SSelvin Xavier 
561ac5a404SSelvin Xavier /* Device */
57254cd259SDevesh Sharma 
bnxt_qplib_is_atomic_cap(struct bnxt_qplib_rcfw * rcfw)5835f5ace5SDevesh Sharma static bool bnxt_qplib_is_atomic_cap(struct bnxt_qplib_rcfw *rcfw)
5935f5ace5SDevesh Sharma {
6035f5ace5SDevesh Sharma 	u16 pcie_ctl2 = 0;
6135f5ace5SDevesh Sharma 
621801d87bSSelvin Xavier 	if (!bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx))
6335f5ace5SDevesh Sharma 		return false;
6435f5ace5SDevesh Sharma 
6535f5ace5SDevesh Sharma 	pcie_capability_read_word(rcfw->pdev, PCI_EXP_DEVCTL2, &pcie_ctl2);
6635f5ace5SDevesh Sharma 	return (pcie_ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ);
6735f5ace5SDevesh Sharma }
6835f5ace5SDevesh Sharma 
bnxt_qplib_query_version(struct bnxt_qplib_rcfw * rcfw,char * fw_ver)692fc68543SSelvin Xavier static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw *rcfw,
702fc68543SSelvin Xavier 				     char *fw_ver)
712fc68543SSelvin Xavier {
72ff015bcdSSelvin Xavier 	struct creq_query_version_resp resp = {};
73ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
74ff015bcdSSelvin Xavier 	struct cmdq_query_version req = {};
7514611b9bSKalesh AP 	int rc;
762fc68543SSelvin Xavier 
77e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
78e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_QUERY_VERSION,
79e576adf5SSelvin Xavier 				 sizeof(req));
802fc68543SSelvin Xavier 
81ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req), sizeof(resp), 0);
82ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
832fc68543SSelvin Xavier 	if (rc)
842fc68543SSelvin Xavier 		return;
852fc68543SSelvin Xavier 	fw_ver[0] = resp.fw_maj;
862fc68543SSelvin Xavier 	fw_ver[1] = resp.fw_minor;
872fc68543SSelvin Xavier 	fw_ver[2] = resp.fw_bld;
882fc68543SSelvin Xavier 	fw_ver[3] = resp.fw_rsvd;
892fc68543SSelvin Xavier }
902fc68543SSelvin Xavier 
bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw * rcfw,struct bnxt_qplib_dev_attr * attr)911ac5a404SSelvin Xavier int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
92f19fba1fSKalesh AP 			    struct bnxt_qplib_dev_attr *attr)
931ac5a404SSelvin Xavier {
94ff015bcdSSelvin Xavier 	struct creq_query_func_resp resp = {};
95ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
961ac5a404SSelvin Xavier 	struct creq_query_func_resp_sb *sb;
97c9f3e4e1SSelvin Xavier 	struct bnxt_qplib_rcfw_sbuf sbuf;
98de1d364cSSelvin Xavier 	struct bnxt_qplib_chip_ctx *cctx;
99ff015bcdSSelvin Xavier 	struct cmdq_query_func req = {};
1001ac5a404SSelvin Xavier 	u8 *tqm_alloc;
10114611b9bSKalesh AP 	int i, rc;
102e576adf5SSelvin Xavier 	u32 temp;
1031ac5a404SSelvin Xavier 
104de1d364cSSelvin Xavier 	cctx = rcfw->res->cctx;
105e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
106e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_QUERY_FUNC,
107e576adf5SSelvin Xavier 				 sizeof(req));
1081ac5a404SSelvin Xavier 
109c9f3e4e1SSelvin Xavier 	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
110c9f3e4e1SSelvin Xavier 	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
111c9f3e4e1SSelvin Xavier 				     &sbuf.dma_addr, GFP_KERNEL);
112c9f3e4e1SSelvin Xavier 	if (!sbuf.sb)
113cc1ec769SDevesh Sharma 		return -ENOMEM;
114c9f3e4e1SSelvin Xavier 	sb = sbuf.sb;
115c9f3e4e1SSelvin Xavier 	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
116c9f3e4e1SSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
117ff015bcdSSelvin Xavier 				sizeof(resp), 0);
118ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
119cc1ec769SDevesh Sharma 	if (rc)
120cc1ec769SDevesh Sharma 		goto bail;
121cc1ec769SDevesh Sharma 
1221ac5a404SSelvin Xavier 	/* Extract the context from the side buffer */
1231ac5a404SSelvin Xavier 	attr->max_qp = le32_to_cpu(sb->max_qp);
124f19fba1fSKalesh AP 	/* max_qp value reported by FW doesn't include the QP1 */
12558d4a671SSelvin Xavier 	attr->max_qp += 1;
1261ac5a404SSelvin Xavier 	attr->max_qp_rd_atom =
1271ac5a404SSelvin Xavier 		sb->max_qp_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
1281ac5a404SSelvin Xavier 		BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_rd_atom;
1291ac5a404SSelvin Xavier 	attr->max_qp_init_rd_atom =
1301ac5a404SSelvin Xavier 		sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
1311ac5a404SSelvin Xavier 		BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
1321ac5a404SSelvin Xavier 	attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr);
1339152e0b7SEddie Wai 	/*
1349152e0b7SEddie Wai 	 * 128 WQEs needs to be reserved for the HW (8916). Prevent
1359152e0b7SEddie Wai 	 * reporting the max number
1369152e0b7SEddie Wai 	 */
137c63e1c4dSSelvin Xavier 	attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1;
138de1d364cSSelvin Xavier 
139de1d364cSSelvin Xavier 	attr->max_qp_sges = cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE ?
140de1d364cSSelvin Xavier 			    min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6;
1411ac5a404SSelvin Xavier 	attr->max_cq = le32_to_cpu(sb->max_cq);
1421ac5a404SSelvin Xavier 	attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
1431ac5a404SSelvin Xavier 	attr->max_cq_sges = attr->max_qp_sges;
1441ac5a404SSelvin Xavier 	attr->max_mr = le32_to_cpu(sb->max_mr);
1451ac5a404SSelvin Xavier 	attr->max_mw = le32_to_cpu(sb->max_mw);
1461ac5a404SSelvin Xavier 
1471ac5a404SSelvin Xavier 	attr->max_mr_size = le64_to_cpu(sb->max_mr_size);
1481ac5a404SSelvin Xavier 	attr->max_pd = 64 * 1024;
1491ac5a404SSelvin Xavier 	attr->max_raw_ethy_qp = le32_to_cpu(sb->max_raw_eth_qp);
1501ac5a404SSelvin Xavier 	attr->max_ah = le32_to_cpu(sb->max_ah);
1511ac5a404SSelvin Xavier 
1521ac5a404SSelvin Xavier 	attr->max_srq = le16_to_cpu(sb->max_srq);
1531ac5a404SSelvin Xavier 	attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1;
1541ac5a404SSelvin Xavier 	attr->max_srq_sges = sb->max_srq_sge;
1550e938533SKamal Heib 	attr->max_pkey = 1;
1561ac5a404SSelvin Xavier 	attr->max_inline_data = le32_to_cpu(sb->max_inline_data);
157a62d6858SSelvin Xavier 	if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx))
158c354dff0SDevesh Sharma 		attr->l2_db_size = (sb->l2_db_space_size + 1) *
159c354dff0SDevesh Sharma 				    (0x01 << RCFW_DBR_BASE_PAGE_SHIFT);
160847b9788SNaresh Kumar PBS 	attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED;
1619a381f7eSSelvin Xavier 	attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags);
1628d310ba8SSelvin Xavier 	attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2);
1631ac5a404SSelvin Xavier 
1642fc68543SSelvin Xavier 	bnxt_qplib_query_version(rcfw, attr->fw_ver);
1651ac5a404SSelvin Xavier 
1661ac5a404SSelvin Xavier 	for (i = 0; i < MAX_TQM_ALLOC_REQ / 4; i++) {
1671ac5a404SSelvin Xavier 		temp = le32_to_cpu(sb->tqm_alloc_reqs[i]);
1681ac5a404SSelvin Xavier 		tqm_alloc = (u8 *)&temp;
1691ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4] = *tqm_alloc;
1701ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4 + 1] = *(++tqm_alloc);
1711ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4 + 2] = *(++tqm_alloc);
1721ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc);
1731ac5a404SSelvin Xavier 	}
174cc1ec769SDevesh Sharma 
1750ac20fafSSelvin Xavier 	if (rcfw->res->cctx->hwrm_intf_ver >= HWRM_VERSION_DEV_ATTR_MAX_DPI)
1760ac20fafSSelvin Xavier 		attr->max_dpi = le32_to_cpu(sb->max_dpi);
1770ac20fafSSelvin Xavier 
17835f5ace5SDevesh Sharma 	attr->is_atomic = bnxt_qplib_is_atomic_cap(rcfw);
179cc1ec769SDevesh Sharma bail:
180c9f3e4e1SSelvin Xavier 	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
181c9f3e4e1SSelvin Xavier 			  sbuf.sb, sbuf.dma_addr);
182cc1ec769SDevesh Sharma 	return rc;
1831ac5a404SSelvin Xavier }
1841ac5a404SSelvin Xavier 
bnxt_qplib_set_func_resources(struct bnxt_qplib_res * res,struct bnxt_qplib_rcfw * rcfw,struct bnxt_qplib_ctx * ctx)185ccd9d0d3SSelvin Xavier int bnxt_qplib_set_func_resources(struct bnxt_qplib_res *res,
186ccd9d0d3SSelvin Xavier 				  struct bnxt_qplib_rcfw *rcfw,
187ccd9d0d3SSelvin Xavier 				  struct bnxt_qplib_ctx *ctx)
188ccd9d0d3SSelvin Xavier {
189ff015bcdSSelvin Xavier 	struct creq_set_func_resources_resp resp = {};
190ff015bcdSSelvin Xavier 	struct cmdq_set_func_resources req = {};
191ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
19214611b9bSKalesh AP 	int rc;
193ccd9d0d3SSelvin Xavier 
194e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
195e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_SET_FUNC_RESOURCES,
196e576adf5SSelvin Xavier 				 sizeof(req));
197ccd9d0d3SSelvin Xavier 
198ccd9d0d3SSelvin Xavier 	req.number_of_qp = cpu_to_le32(ctx->qpc_count);
199ccd9d0d3SSelvin Xavier 	req.number_of_mrw = cpu_to_le32(ctx->mrw_count);
200ccd9d0d3SSelvin Xavier 	req.number_of_srq =  cpu_to_le32(ctx->srqc_count);
201ccd9d0d3SSelvin Xavier 	req.number_of_cq = cpu_to_le32(ctx->cq_count);
202ccd9d0d3SSelvin Xavier 
203ccd9d0d3SSelvin Xavier 	req.max_qp_per_vf = cpu_to_le32(ctx->vf_res.max_qp_per_vf);
204ccd9d0d3SSelvin Xavier 	req.max_mrw_per_vf = cpu_to_le32(ctx->vf_res.max_mrw_per_vf);
205ccd9d0d3SSelvin Xavier 	req.max_srq_per_vf = cpu_to_le32(ctx->vf_res.max_srq_per_vf);
206ccd9d0d3SSelvin Xavier 	req.max_cq_per_vf = cpu_to_le32(ctx->vf_res.max_cq_per_vf);
207ccd9d0d3SSelvin Xavier 	req.max_gid_per_vf = cpu_to_le32(ctx->vf_res.max_gid_per_vf);
208ccd9d0d3SSelvin Xavier 
209ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
210ff015bcdSSelvin Xavier 				sizeof(resp), 0);
211ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
212ccd9d0d3SSelvin Xavier 	if (rc) {
21308920b8fSJoe Perches 		dev_err(&res->pdev->dev, "Failed to set function resources\n");
214ccd9d0d3SSelvin Xavier 	}
215ccd9d0d3SSelvin Xavier 	return rc;
216ccd9d0d3SSelvin Xavier }
217ccd9d0d3SSelvin Xavier 
2181ac5a404SSelvin Xavier /* SGID */
bnxt_qplib_get_sgid(struct bnxt_qplib_res * res,struct bnxt_qplib_sgid_tbl * sgid_tbl,int index,struct bnxt_qplib_gid * gid)2191ac5a404SSelvin Xavier int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
2201ac5a404SSelvin Xavier 			struct bnxt_qplib_sgid_tbl *sgid_tbl, int index,
2211ac5a404SSelvin Xavier 			struct bnxt_qplib_gid *gid)
2221ac5a404SSelvin Xavier {
223474e5a86SDan Carpenter 	if (index >= sgid_tbl->max) {
2241ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
22508920b8fSJoe Perches 			"Index %d exceeded SGID table max (%d)\n",
2261ac5a404SSelvin Xavier 			index, sgid_tbl->max);
2271ac5a404SSelvin Xavier 		return -EINVAL;
2281ac5a404SSelvin Xavier 	}
229c56b593dSSelvin Xavier 	memcpy(gid, &sgid_tbl->tbl[index].gid, sizeof(*gid));
2301ac5a404SSelvin Xavier 	return 0;
2311ac5a404SSelvin Xavier }
2321ac5a404SSelvin Xavier 
bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl * sgid_tbl,struct bnxt_qplib_gid * gid,u16 vlan_id,bool update)2331ac5a404SSelvin Xavier int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
234c56b593dSSelvin Xavier 			struct bnxt_qplib_gid *gid, u16 vlan_id, bool update)
2351ac5a404SSelvin Xavier {
2361ac5a404SSelvin Xavier 	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
2371ac5a404SSelvin Xavier 						   struct bnxt_qplib_res,
2381ac5a404SSelvin Xavier 						   sgid_tbl);
2391ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
2401ac5a404SSelvin Xavier 	int index;
2411ac5a404SSelvin Xavier 
2421ac5a404SSelvin Xavier 	/* Do we need a sgid_lock here? */
2431ac5a404SSelvin Xavier 	if (!sgid_tbl->active) {
24408920b8fSJoe Perches 		dev_err(&res->pdev->dev, "SGID table has no active entries\n");
2451ac5a404SSelvin Xavier 		return -ENOMEM;
2461ac5a404SSelvin Xavier 	}
2471ac5a404SSelvin Xavier 	for (index = 0; index < sgid_tbl->max; index++) {
248c56b593dSSelvin Xavier 		if (!memcmp(&sgid_tbl->tbl[index].gid, gid, sizeof(*gid)) &&
249c56b593dSSelvin Xavier 		    vlan_id == sgid_tbl->tbl[index].vlan_id)
2501ac5a404SSelvin Xavier 			break;
2511ac5a404SSelvin Xavier 	}
2521ac5a404SSelvin Xavier 	if (index == sgid_tbl->max) {
25308920b8fSJoe Perches 		dev_warn(&res->pdev->dev, "GID not found in the SGID table\n");
2541ac5a404SSelvin Xavier 		return 0;
2551ac5a404SSelvin Xavier 	}
2561ac5a404SSelvin Xavier 	/* Remove GID from the SGID table */
2571ac5a404SSelvin Xavier 	if (update) {
258ff015bcdSSelvin Xavier 		struct creq_delete_gid_resp resp = {};
259ff015bcdSSelvin Xavier 		struct bnxt_qplib_cmdqmsg msg = {};
260ff015bcdSSelvin Xavier 		struct cmdq_delete_gid req = {};
261cc1ec769SDevesh Sharma 		int rc;
2621ac5a404SSelvin Xavier 
263e576adf5SSelvin Xavier 		bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
264e576adf5SSelvin Xavier 					 CMDQ_BASE_OPCODE_DELETE_GID,
265e576adf5SSelvin Xavier 					 sizeof(req));
2661ac5a404SSelvin Xavier 		if (sgid_tbl->hw_id[index] == 0xFFFF) {
2671ac5a404SSelvin Xavier 			dev_err(&res->pdev->dev,
26808920b8fSJoe Perches 				"GID entry contains an invalid HW id\n");
2691ac5a404SSelvin Xavier 			return -EINVAL;
2701ac5a404SSelvin Xavier 		}
2711ac5a404SSelvin Xavier 		req.gid_index = cpu_to_le16(sgid_tbl->hw_id[index]);
272ff015bcdSSelvin Xavier 		bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
273ff015bcdSSelvin Xavier 					sizeof(resp), 0);
274ff015bcdSSelvin Xavier 		rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
275cc1ec769SDevesh Sharma 		if (rc)
276cc1ec769SDevesh Sharma 			return rc;
2771ac5a404SSelvin Xavier 	}
278c56b593dSSelvin Xavier 	memcpy(&sgid_tbl->tbl[index].gid, &bnxt_qplib_gid_zero,
2791ac5a404SSelvin Xavier 	       sizeof(bnxt_qplib_gid_zero));
280c56b593dSSelvin Xavier 	sgid_tbl->tbl[index].vlan_id = 0xFFFF;
2815fac5b1bSKalesh AP 	sgid_tbl->vlan[index] = 0;
2821ac5a404SSelvin Xavier 	sgid_tbl->active--;
2831ac5a404SSelvin Xavier 	dev_dbg(&res->pdev->dev,
28408920b8fSJoe Perches 		"SGID deleted hw_id[0x%x] = 0x%x active = 0x%x\n",
2851ac5a404SSelvin Xavier 		 index, sgid_tbl->hw_id[index], sgid_tbl->active);
2861ac5a404SSelvin Xavier 	sgid_tbl->hw_id[index] = (u16)-1;
2871ac5a404SSelvin Xavier 
2881ac5a404SSelvin Xavier 	/* unlock */
2891ac5a404SSelvin Xavier 	return 0;
2901ac5a404SSelvin Xavier }
2911ac5a404SSelvin Xavier 
bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl * sgid_tbl,struct bnxt_qplib_gid * gid,const u8 * smac,u16 vlan_id,bool update,u32 * index)2921ac5a404SSelvin Xavier int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
293fd92213eSJakub Kicinski 			struct bnxt_qplib_gid *gid, const u8 *smac,
294fd92213eSJakub Kicinski 			u16 vlan_id, bool update, u32 *index)
2951ac5a404SSelvin Xavier {
2961ac5a404SSelvin Xavier 	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
2971ac5a404SSelvin Xavier 						   struct bnxt_qplib_res,
2981ac5a404SSelvin Xavier 						   sgid_tbl);
2991ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
300cc1ec769SDevesh Sharma 	int i, free_idx;
3011ac5a404SSelvin Xavier 
3021ac5a404SSelvin Xavier 	/* Do we need a sgid_lock here? */
3031ac5a404SSelvin Xavier 	if (sgid_tbl->active == sgid_tbl->max) {
30408920b8fSJoe Perches 		dev_err(&res->pdev->dev, "SGID table is full\n");
3051ac5a404SSelvin Xavier 		return -ENOMEM;
3061ac5a404SSelvin Xavier 	}
3071ac5a404SSelvin Xavier 	free_idx = sgid_tbl->max;
3081ac5a404SSelvin Xavier 	for (i = 0; i < sgid_tbl->max; i++) {
309c56b593dSSelvin Xavier 		if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid)) &&
310c56b593dSSelvin Xavier 		    sgid_tbl->tbl[i].vlan_id == vlan_id) {
3111ac5a404SSelvin Xavier 			dev_dbg(&res->pdev->dev,
31208920b8fSJoe Perches 				"SGID entry already exist in entry %d!\n", i);
3131ac5a404SSelvin Xavier 			*index = i;
3141ac5a404SSelvin Xavier 			return -EALREADY;
3151ac5a404SSelvin Xavier 		} else if (!memcmp(&sgid_tbl->tbl[i], &bnxt_qplib_gid_zero,
3161ac5a404SSelvin Xavier 				   sizeof(bnxt_qplib_gid_zero)) &&
3171ac5a404SSelvin Xavier 			   free_idx == sgid_tbl->max) {
3181ac5a404SSelvin Xavier 			free_idx = i;
3191ac5a404SSelvin Xavier 		}
3201ac5a404SSelvin Xavier 	}
3211ac5a404SSelvin Xavier 	if (free_idx == sgid_tbl->max) {
3221ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
32308920b8fSJoe Perches 			"SGID table is FULL but count is not MAX??\n");
3241ac5a404SSelvin Xavier 		return -ENOMEM;
3251ac5a404SSelvin Xavier 	}
3261ac5a404SSelvin Xavier 	if (update) {
327ff015bcdSSelvin Xavier 		struct creq_add_gid_resp resp = {};
328ff015bcdSSelvin Xavier 		struct bnxt_qplib_cmdqmsg msg = {};
329ff015bcdSSelvin Xavier 		struct cmdq_add_gid req = {};
330cc1ec769SDevesh Sharma 		int rc;
3311ac5a404SSelvin Xavier 
332e576adf5SSelvin Xavier 		bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
333e576adf5SSelvin Xavier 					 CMDQ_BASE_OPCODE_ADD_GID,
334e576adf5SSelvin Xavier 					 sizeof(req));
3351ac5a404SSelvin Xavier 
3365fac5b1bSKalesh AP 		req.gid[0] = cpu_to_be32(((u32 *)gid->data)[3]);
3375fac5b1bSKalesh AP 		req.gid[1] = cpu_to_be32(((u32 *)gid->data)[2]);
3385fac5b1bSKalesh AP 		req.gid[2] = cpu_to_be32(((u32 *)gid->data)[1]);
3395fac5b1bSKalesh AP 		req.gid[3] = cpu_to_be32(((u32 *)gid->data)[0]);
3405fac5b1bSKalesh AP 		/*
3415fac5b1bSKalesh AP 		 * driver should ensure that all RoCE traffic is always VLAN
3425fac5b1bSKalesh AP 		 * tagged if RoCE traffic is running on non-zero VLAN ID or
3435fac5b1bSKalesh AP 		 * RoCE traffic is running on non-zero Priority.
3445fac5b1bSKalesh AP 		 */
3455fac5b1bSKalesh AP 		if ((vlan_id != 0xFFFF) || res->prio) {
3461ac5a404SSelvin Xavier 			if (vlan_id != 0xFFFF)
3475fac5b1bSKalesh AP 				req.vlan = cpu_to_le16
3485fac5b1bSKalesh AP 				(vlan_id & CMDQ_ADD_GID_VLAN_VLAN_ID_MASK);
3495fac5b1bSKalesh AP 			req.vlan |= cpu_to_le16
3505fac5b1bSKalesh AP 					(CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
3511ac5a404SSelvin Xavier 					 CMDQ_ADD_GID_VLAN_VLAN_EN);
3525fac5b1bSKalesh AP 		}
3531ac5a404SSelvin Xavier 
3541ac5a404SSelvin Xavier 		/* MAC in network format */
3555fac5b1bSKalesh AP 		req.src_mac[0] = cpu_to_be16(((u16 *)smac)[0]);
3565fac5b1bSKalesh AP 		req.src_mac[1] = cpu_to_be16(((u16 *)smac)[1]);
3575fac5b1bSKalesh AP 		req.src_mac[2] = cpu_to_be16(((u16 *)smac)[2]);
3581ac5a404SSelvin Xavier 
359ff015bcdSSelvin Xavier 		bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
360ff015bcdSSelvin Xavier 					sizeof(resp), 0);
361ff015bcdSSelvin Xavier 		rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
362cc1ec769SDevesh Sharma 		if (rc)
363cc1ec769SDevesh Sharma 			return rc;
364cc1ec769SDevesh Sharma 		sgid_tbl->hw_id[free_idx] = le32_to_cpu(resp.xid);
3651ac5a404SSelvin Xavier 	}
3661ac5a404SSelvin Xavier 	/* Add GID to the sgid_tbl */
3671ac5a404SSelvin Xavier 	memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
368c56b593dSSelvin Xavier 	sgid_tbl->tbl[free_idx].vlan_id = vlan_id;
3691ac5a404SSelvin Xavier 	sgid_tbl->active++;
3705fac5b1bSKalesh AP 	if (vlan_id != 0xFFFF)
3715fac5b1bSKalesh AP 		sgid_tbl->vlan[free_idx] = 1;
3725fac5b1bSKalesh AP 
3731ac5a404SSelvin Xavier 	dev_dbg(&res->pdev->dev,
37408920b8fSJoe Perches 		"SGID added hw_id[0x%x] = 0x%x active = 0x%x\n",
3751ac5a404SSelvin Xavier 		 free_idx, sgid_tbl->hw_id[free_idx], sgid_tbl->active);
3761ac5a404SSelvin Xavier 
3771ac5a404SSelvin Xavier 	*index = free_idx;
3781ac5a404SSelvin Xavier 	/* unlock */
379cc1ec769SDevesh Sharma 	return 0;
3801ac5a404SSelvin Xavier }
3811ac5a404SSelvin Xavier 
bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl * sgid_tbl,struct bnxt_qplib_gid * gid,u16 gid_idx,const u8 * smac)3825fac5b1bSKalesh AP int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
3835fac5b1bSKalesh AP 			   struct bnxt_qplib_gid *gid, u16 gid_idx,
384fd92213eSJakub Kicinski 			   const u8 *smac)
3855fac5b1bSKalesh AP {
3865fac5b1bSKalesh AP 	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
3875fac5b1bSKalesh AP 						   struct bnxt_qplib_res,
3885fac5b1bSKalesh AP 						   sgid_tbl);
3895fac5b1bSKalesh AP 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
390ff015bcdSSelvin Xavier 	struct creq_modify_gid_resp resp = {};
391ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
392ff015bcdSSelvin Xavier 	struct cmdq_modify_gid req = {};
3935fac5b1bSKalesh AP 	int rc;
3945fac5b1bSKalesh AP 
395e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
396e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_MODIFY_GID,
397e576adf5SSelvin Xavier 				 sizeof(req));
3985fac5b1bSKalesh AP 
3995fac5b1bSKalesh AP 	req.gid[0] = cpu_to_be32(((u32 *)gid->data)[3]);
4005fac5b1bSKalesh AP 	req.gid[1] = cpu_to_be32(((u32 *)gid->data)[2]);
4015fac5b1bSKalesh AP 	req.gid[2] = cpu_to_be32(((u32 *)gid->data)[1]);
4025fac5b1bSKalesh AP 	req.gid[3] = cpu_to_be32(((u32 *)gid->data)[0]);
4035fac5b1bSKalesh AP 	if (res->prio) {
4045fac5b1bSKalesh AP 		req.vlan |= cpu_to_le16
4055fac5b1bSKalesh AP 			(CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
4065fac5b1bSKalesh AP 			 CMDQ_ADD_GID_VLAN_VLAN_EN);
4075fac5b1bSKalesh AP 	}
4085fac5b1bSKalesh AP 
4095fac5b1bSKalesh AP 	/* MAC in network format */
4105fac5b1bSKalesh AP 	req.src_mac[0] = cpu_to_be16(((u16 *)smac)[0]);
4115fac5b1bSKalesh AP 	req.src_mac[1] = cpu_to_be16(((u16 *)smac)[1]);
4125fac5b1bSKalesh AP 	req.src_mac[2] = cpu_to_be16(((u16 *)smac)[2]);
4135fac5b1bSKalesh AP 
4145fac5b1bSKalesh AP 	req.gid_index = cpu_to_le16(gid_idx);
4155fac5b1bSKalesh AP 
416ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
417ff015bcdSSelvin Xavier 				sizeof(resp), 0);
418ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
4195fac5b1bSKalesh AP 	return rc;
4205fac5b1bSKalesh AP }
4215fac5b1bSKalesh AP 
4221ac5a404SSelvin Xavier /* AH */
bnxt_qplib_create_ah(struct bnxt_qplib_res * res,struct bnxt_qplib_ah * ah,bool block)42390e3edd8SGal Pressman int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
42490e3edd8SGal Pressman 			 bool block)
4251ac5a404SSelvin Xavier {
4261ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
427ff015bcdSSelvin Xavier 	struct creq_create_ah_resp resp = {};
428ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
429ff015bcdSSelvin Xavier 	struct cmdq_create_ah req = {};
4301ac5a404SSelvin Xavier 	u32 temp32[4];
4311ac5a404SSelvin Xavier 	u16 temp16[3];
432cc1ec769SDevesh Sharma 	int rc;
4331ac5a404SSelvin Xavier 
434e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
435e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_CREATE_AH,
436e576adf5SSelvin Xavier 				 sizeof(req));
4371ac5a404SSelvin Xavier 
4381ac5a404SSelvin Xavier 	memcpy(temp32, ah->dgid.data, sizeof(struct bnxt_qplib_gid));
4391ac5a404SSelvin Xavier 	req.dgid[0] = cpu_to_le32(temp32[0]);
4401ac5a404SSelvin Xavier 	req.dgid[1] = cpu_to_le32(temp32[1]);
4411ac5a404SSelvin Xavier 	req.dgid[2] = cpu_to_le32(temp32[2]);
4421ac5a404SSelvin Xavier 	req.dgid[3] = cpu_to_le32(temp32[3]);
4431ac5a404SSelvin Xavier 
4441ac5a404SSelvin Xavier 	req.type = ah->nw_type;
4451ac5a404SSelvin Xavier 	req.hop_limit = ah->hop_limit;
4461ac5a404SSelvin Xavier 	req.sgid_index = cpu_to_le16(res->sgid_tbl.hw_id[ah->sgid_index]);
4471ac5a404SSelvin Xavier 	req.dest_vlan_id_flow_label = cpu_to_le32((ah->flow_label &
4481ac5a404SSelvin Xavier 					CMDQ_CREATE_AH_FLOW_LABEL_MASK) |
4491ac5a404SSelvin Xavier 					CMDQ_CREATE_AH_DEST_VLAN_ID_MASK);
4501ac5a404SSelvin Xavier 	req.pd_id = cpu_to_le32(ah->pd->id);
4511ac5a404SSelvin Xavier 	req.traffic_class = ah->traffic_class;
4521ac5a404SSelvin Xavier 
4531ac5a404SSelvin Xavier 	/* MAC in network format */
4541ac5a404SSelvin Xavier 	memcpy(temp16, ah->dmac, 6);
4551ac5a404SSelvin Xavier 	req.dest_mac[0] = cpu_to_le16(temp16[0]);
4561ac5a404SSelvin Xavier 	req.dest_mac[1] = cpu_to_le16(temp16[1]);
4571ac5a404SSelvin Xavier 	req.dest_mac[2] = cpu_to_le16(temp16[2]);
4581ac5a404SSelvin Xavier 
459ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
460ff015bcdSSelvin Xavier 				sizeof(resp), block);
461ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
462cc1ec769SDevesh Sharma 	if (rc)
463cc1ec769SDevesh Sharma 		return rc;
464cc1ec769SDevesh Sharma 
465cc1ec769SDevesh Sharma 	ah->id = le32_to_cpu(resp.xid);
4661ac5a404SSelvin Xavier 	return 0;
4671ac5a404SSelvin Xavier }
4681ac5a404SSelvin Xavier 
bnxt_qplib_destroy_ah(struct bnxt_qplib_res * res,struct bnxt_qplib_ah * ah,bool block)469bb8c9361SKashyap Desai int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
47050c582deSGal Pressman 			  bool block)
4711ac5a404SSelvin Xavier {
4721ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
473ff015bcdSSelvin Xavier 	struct creq_destroy_ah_resp resp = {};
474ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
475ff015bcdSSelvin Xavier 	struct cmdq_destroy_ah req = {};
476bb8c9361SKashyap Desai 	int rc;
4771ac5a404SSelvin Xavier 
4781ac5a404SSelvin Xavier 	/* Clean up the AH table in the device */
479e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
480e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_DESTROY_AH,
481e576adf5SSelvin Xavier 				 sizeof(req));
4821ac5a404SSelvin Xavier 
4831ac5a404SSelvin Xavier 	req.ah_cid = cpu_to_le32(ah->id);
4841ac5a404SSelvin Xavier 
485ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
486ff015bcdSSelvin Xavier 				sizeof(resp), block);
487bb8c9361SKashyap Desai 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
488bb8c9361SKashyap Desai 	return rc;
4891ac5a404SSelvin Xavier }
4901ac5a404SSelvin Xavier 
4911ac5a404SSelvin Xavier /* MRW */
bnxt_qplib_free_mrw(struct bnxt_qplib_res * res,struct bnxt_qplib_mrw * mrw)4921ac5a404SSelvin Xavier int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
4931ac5a404SSelvin Xavier {
494ff015bcdSSelvin Xavier 	struct creq_deallocate_key_resp resp = {};
4951ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
496ff015bcdSSelvin Xavier 	struct cmdq_deallocate_key req = {};
497ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
498cc1ec769SDevesh Sharma 	int rc;
4991ac5a404SSelvin Xavier 
5001ac5a404SSelvin Xavier 	if (mrw->lkey == 0xFFFFFFFF) {
50108920b8fSJoe Perches 		dev_info(&res->pdev->dev, "SP: Free a reserved lkey MRW\n");
5021ac5a404SSelvin Xavier 		return 0;
5031ac5a404SSelvin Xavier 	}
5041ac5a404SSelvin Xavier 
505e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
506e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_DEALLOCATE_KEY,
507e576adf5SSelvin Xavier 				 sizeof(req));
5081ac5a404SSelvin Xavier 
5091ac5a404SSelvin Xavier 	req.mrw_flags = mrw->type;
5101ac5a404SSelvin Xavier 
5111ac5a404SSelvin Xavier 	if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1)  ||
5121ac5a404SSelvin Xavier 	    (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A) ||
5131ac5a404SSelvin Xavier 	    (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B))
5141ac5a404SSelvin Xavier 		req.key = cpu_to_le32(mrw->rkey);
5151ac5a404SSelvin Xavier 	else
5161ac5a404SSelvin Xavier 		req.key = cpu_to_le32(mrw->lkey);
5171ac5a404SSelvin Xavier 
518ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
519ff015bcdSSelvin Xavier 				sizeof(resp), 0);
520ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
521cc1ec769SDevesh Sharma 	if (rc)
522cc1ec769SDevesh Sharma 		return rc;
523cc1ec769SDevesh Sharma 
5241ac5a404SSelvin Xavier 	/* Free the qplib's MRW memory */
5251ac5a404SSelvin Xavier 	if (mrw->hwq.max_elements)
5260c4dcd60SDevesh Sharma 		bnxt_qplib_free_hwq(res, &mrw->hwq);
5271ac5a404SSelvin Xavier 
5281ac5a404SSelvin Xavier 	return 0;
5291ac5a404SSelvin Xavier }
5301ac5a404SSelvin Xavier 
bnxt_qplib_alloc_mrw(struct bnxt_qplib_res * res,struct bnxt_qplib_mrw * mrw)5311ac5a404SSelvin Xavier int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
5321ac5a404SSelvin Xavier {
5331ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
534ff015bcdSSelvin Xavier 	struct creq_allocate_mrw_resp resp = {};
535ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
536ff015bcdSSelvin Xavier 	struct cmdq_allocate_mrw req = {};
5371ac5a404SSelvin Xavier 	unsigned long tmp;
538cc1ec769SDevesh Sharma 	int rc;
5391ac5a404SSelvin Xavier 
540e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
541e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_ALLOCATE_MRW,
542e576adf5SSelvin Xavier 				 sizeof(req));
5431ac5a404SSelvin Xavier 
5441ac5a404SSelvin Xavier 	req.pd_id = cpu_to_le32(mrw->pd->id);
5451ac5a404SSelvin Xavier 	req.mrw_flags = mrw->type;
5461ac5a404SSelvin Xavier 	if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR &&
547b98d9697SKalesh AP 	     mrw->access_flags & BNXT_QPLIB_FR_PMR) ||
5481ac5a404SSelvin Xavier 	    mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A ||
5491ac5a404SSelvin Xavier 	    mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B)
5501ac5a404SSelvin Xavier 		req.access = CMDQ_ALLOCATE_MRW_ACCESS_CONSUMER_OWNED_KEY;
5511ac5a404SSelvin Xavier 	tmp = (unsigned long)mrw;
5521ac5a404SSelvin Xavier 	req.mrw_handle = cpu_to_le64(tmp);
5531ac5a404SSelvin Xavier 
554ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
555ff015bcdSSelvin Xavier 				sizeof(resp), 0);
556ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
557cc1ec769SDevesh Sharma 	if (rc)
558cc1ec769SDevesh Sharma 		return rc;
559cc1ec769SDevesh Sharma 
5601ac5a404SSelvin Xavier 	if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1)  ||
5611ac5a404SSelvin Xavier 	    (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A) ||
5621ac5a404SSelvin Xavier 	    (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B))
563cc1ec769SDevesh Sharma 		mrw->rkey = le32_to_cpu(resp.xid);
5641ac5a404SSelvin Xavier 	else
565cc1ec769SDevesh Sharma 		mrw->lkey = le32_to_cpu(resp.xid);
5661ac5a404SSelvin Xavier 	return 0;
5671ac5a404SSelvin Xavier }
5681ac5a404SSelvin Xavier 
bnxt_qplib_dereg_mrw(struct bnxt_qplib_res * res,struct bnxt_qplib_mrw * mrw,bool block)5691ac5a404SSelvin Xavier int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
5701ac5a404SSelvin Xavier 			 bool block)
5711ac5a404SSelvin Xavier {
5721ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
573ff015bcdSSelvin Xavier 	struct creq_deregister_mr_resp resp = {};
574ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
575ff015bcdSSelvin Xavier 	struct cmdq_deregister_mr req = {};
5761ac5a404SSelvin Xavier 	int rc;
5771ac5a404SSelvin Xavier 
578e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
579e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_DEREGISTER_MR,
580e576adf5SSelvin Xavier 				 sizeof(req));
5811ac5a404SSelvin Xavier 
5821ac5a404SSelvin Xavier 	req.lkey = cpu_to_le32(mrw->lkey);
583ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
584ff015bcdSSelvin Xavier 				sizeof(resp), block);
585ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
586cc1ec769SDevesh Sharma 	if (rc)
587cc1ec769SDevesh Sharma 		return rc;
5881ac5a404SSelvin Xavier 
5891ac5a404SSelvin Xavier 	/* Free the qplib's MR memory */
5901ac5a404SSelvin Xavier 	if (mrw->hwq.max_elements) {
5911ac5a404SSelvin Xavier 		mrw->va = 0;
5921ac5a404SSelvin Xavier 		mrw->total_size = 0;
5930c4dcd60SDevesh Sharma 		bnxt_qplib_free_hwq(res, &mrw->hwq);
5941ac5a404SSelvin Xavier 	}
5951ac5a404SSelvin Xavier 
5961ac5a404SSelvin Xavier 	return 0;
5971ac5a404SSelvin Xavier }
5981ac5a404SSelvin Xavier 
bnxt_qplib_reg_mr(struct bnxt_qplib_res * res,struct bnxt_qplib_mrw * mr,struct ib_umem * umem,int num_pbls,u32 buf_pg_size)5991ac5a404SSelvin Xavier int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
600f6919d56SSelvin Xavier 		      struct ib_umem *umem, int num_pbls, u32 buf_pg_size)
6011ac5a404SSelvin Xavier {
6021ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
6030c4dcd60SDevesh Sharma 	struct bnxt_qplib_hwq_attr hwq_attr = {};
6040c4dcd60SDevesh Sharma 	struct bnxt_qplib_sg_info sginfo = {};
605ff015bcdSSelvin Xavier 	struct creq_register_mr_resp resp = {};
606ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
607ff015bcdSSelvin Xavier 	struct cmdq_register_mr req = {};
608c930af5aSSelvin Xavier 	int pages, rc;
6091ac5a404SSelvin Xavier 	u32 pg_size;
610e576adf5SSelvin Xavier 	u16 level;
6111ac5a404SSelvin Xavier 
6121ac5a404SSelvin Xavier 	if (num_pbls) {
613c930af5aSSelvin Xavier 		pages = roundup_pow_of_two(num_pbls);
614872f3578SSomnath Kotur 		/* Allocate memory for the non-leaf pages to store buf ptrs.
615872f3578SSomnath Kotur 		 * Non-leaf pages always uses system PAGE_SIZE
616872f3578SSomnath Kotur 		 */
6171ac5a404SSelvin Xavier 		/* Free the hwq if it already exist, must be a rereg */
6181ac5a404SSelvin Xavier 		if (mr->hwq.max_elements)
6190c4dcd60SDevesh Sharma 			bnxt_qplib_free_hwq(res, &mr->hwq);
6200c4dcd60SDevesh Sharma 		hwq_attr.res = res;
6210c4dcd60SDevesh Sharma 		hwq_attr.depth = pages;
62208c7f093SSelvin Xavier 		hwq_attr.stride = sizeof(dma_addr_t);
6230c4dcd60SDevesh Sharma 		hwq_attr.type = HWQ_TYPE_MR;
6240c4dcd60SDevesh Sharma 		hwq_attr.sginfo = &sginfo;
625f6919d56SSelvin Xavier 		hwq_attr.sginfo->umem = umem;
6260c4dcd60SDevesh Sharma 		hwq_attr.sginfo->npages = pages;
62708c7f093SSelvin Xavier 		hwq_attr.sginfo->pgsize = buf_pg_size;
62808c7f093SSelvin Xavier 		hwq_attr.sginfo->pgshft = ilog2(buf_pg_size);
6290c4dcd60SDevesh Sharma 		rc = bnxt_qplib_alloc_init_hwq(&mr->hwq, &hwq_attr);
6301ac5a404SSelvin Xavier 		if (rc) {
6311ac5a404SSelvin Xavier 			dev_err(&res->pdev->dev,
63208920b8fSJoe Perches 				"SP: Reg MR memory allocation failed\n");
6331ac5a404SSelvin Xavier 			return -ENOMEM;
6341ac5a404SSelvin Xavier 		}
6351ac5a404SSelvin Xavier 	}
6361ac5a404SSelvin Xavier 
637e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
638e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_REGISTER_MR,
639e576adf5SSelvin Xavier 				 sizeof(req));
6401ac5a404SSelvin Xavier 
6411ac5a404SSelvin Xavier 	/* Configure the request */
6421ac5a404SSelvin Xavier 	if (mr->hwq.level == PBL_LVL_MAX) {
643872f3578SSomnath Kotur 		/* No PBL provided, just use system PAGE_SIZE */
6441ac5a404SSelvin Xavier 		level = 0;
6451ac5a404SSelvin Xavier 		req.pbl = 0;
6461ac5a404SSelvin Xavier 		pg_size = PAGE_SIZE;
6471ac5a404SSelvin Xavier 	} else {
648f6919d56SSelvin Xavier 		level = mr->hwq.level;
6491ac5a404SSelvin Xavier 		req.pbl = cpu_to_le64(mr->hwq.pbl[PBL_LVL_0].pg_map_arr[0]);
6501ac5a404SSelvin Xavier 	}
651872f3578SSomnath Kotur 	pg_size = buf_pg_size ? buf_pg_size : PAGE_SIZE;
6521ac5a404SSelvin Xavier 	req.log2_pg_size_lvl = (level << CMDQ_REGISTER_MR_LVL_SFT) |
6531ac5a404SSelvin Xavier 			       ((ilog2(pg_size) <<
6541ac5a404SSelvin Xavier 				 CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT) &
6551ac5a404SSelvin Xavier 				CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK);
656872f3578SSomnath Kotur 	req.log2_pbl_pg_size = cpu_to_le16(((ilog2(PAGE_SIZE) <<
657872f3578SSomnath Kotur 				 CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_SFT) &
658872f3578SSomnath Kotur 				CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_MASK));
659b98d9697SKalesh AP 	req.access = (mr->access_flags & 0xFFFF);
6601ac5a404SSelvin Xavier 	req.va = cpu_to_le64(mr->va);
6611ac5a404SSelvin Xavier 	req.key = cpu_to_le32(mr->lkey);
662*f786eebbSKalesh AP 	if (_is_alloc_mr_unified(res->dattr->dev_cap_flags))
663*f786eebbSKalesh AP 		req.key = cpu_to_le32(mr->pd->id);
664*f786eebbSKalesh AP 	req.flags = cpu_to_le16(mr->flags);
6651ac5a404SSelvin Xavier 	req.mr_size = cpu_to_le64(mr->total_size);
6661ac5a404SSelvin Xavier 
667ff015bcdSSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req),
668ff015bcdSSelvin Xavier 				sizeof(resp), 0);
669ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
670cc1ec769SDevesh Sharma 	if (rc)
6711ac5a404SSelvin Xavier 		goto fail;
672cc1ec769SDevesh Sharma 
673*f786eebbSKalesh AP 	if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) {
674*f786eebbSKalesh AP 		mr->lkey = le32_to_cpu(resp.xid);
675*f786eebbSKalesh AP 		mr->rkey = mr->lkey;
676*f786eebbSKalesh AP 	}
677*f786eebbSKalesh AP 
6781ac5a404SSelvin Xavier 	return 0;
6791ac5a404SSelvin Xavier 
6801ac5a404SSelvin Xavier fail:
6811ac5a404SSelvin Xavier 	if (mr->hwq.max_elements)
6820c4dcd60SDevesh Sharma 		bnxt_qplib_free_hwq(res, &mr->hwq);
6831ac5a404SSelvin Xavier 	return rc;
6841ac5a404SSelvin Xavier }
6851ac5a404SSelvin Xavier 
bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res * res,struct bnxt_qplib_frpl * frpl,int max_pg_ptrs)6861ac5a404SSelvin Xavier int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
6871ac5a404SSelvin Xavier 					struct bnxt_qplib_frpl *frpl,
6881ac5a404SSelvin Xavier 					int max_pg_ptrs)
6891ac5a404SSelvin Xavier {
6900c4dcd60SDevesh Sharma 	struct bnxt_qplib_hwq_attr hwq_attr = {};
6910c4dcd60SDevesh Sharma 	struct bnxt_qplib_sg_info sginfo = {};
6921ac5a404SSelvin Xavier 	int pg_ptrs, pages, rc;
6931ac5a404SSelvin Xavier 
6941ac5a404SSelvin Xavier 	/* Re-calculate the max to fit the HWQ allocation model */
6951ac5a404SSelvin Xavier 	pg_ptrs = roundup_pow_of_two(max_pg_ptrs);
6961ac5a404SSelvin Xavier 	pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
6971ac5a404SSelvin Xavier 	if (!pages)
6981ac5a404SSelvin Xavier 		pages++;
6991ac5a404SSelvin Xavier 
7001ac5a404SSelvin Xavier 	if (pages > MAX_PBL_LVL_1_PGS)
7011ac5a404SSelvin Xavier 		return -ENOMEM;
7021ac5a404SSelvin Xavier 
7030c4dcd60SDevesh Sharma 	sginfo.pgsize = PAGE_SIZE;
7040c4dcd60SDevesh Sharma 	sginfo.nopte = true;
7050c4dcd60SDevesh Sharma 
7060c4dcd60SDevesh Sharma 	hwq_attr.res = res;
7070c4dcd60SDevesh Sharma 	hwq_attr.depth = pg_ptrs;
7080c4dcd60SDevesh Sharma 	hwq_attr.stride = PAGE_SIZE;
7090c4dcd60SDevesh Sharma 	hwq_attr.sginfo = &sginfo;
7100c4dcd60SDevesh Sharma 	hwq_attr.type = HWQ_TYPE_CTX;
7110c4dcd60SDevesh Sharma 	rc = bnxt_qplib_alloc_init_hwq(&frpl->hwq, &hwq_attr);
7121ac5a404SSelvin Xavier 	if (!rc)
7131ac5a404SSelvin Xavier 		frpl->max_pg_ptrs = pg_ptrs;
7141ac5a404SSelvin Xavier 
7151ac5a404SSelvin Xavier 	return rc;
7161ac5a404SSelvin Xavier }
7171ac5a404SSelvin Xavier 
bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res * res,struct bnxt_qplib_frpl * frpl)7181ac5a404SSelvin Xavier int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res,
7191ac5a404SSelvin Xavier 				       struct bnxt_qplib_frpl *frpl)
7201ac5a404SSelvin Xavier {
7210c4dcd60SDevesh Sharma 	bnxt_qplib_free_hwq(res, &frpl->hwq);
7221ac5a404SSelvin Xavier 	return 0;
7231ac5a404SSelvin Xavier }
7241ac5a404SSelvin Xavier 
bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw * rcfw,struct bnxt_qplib_roce_stats * stats)72589f81008SSelvin Xavier int bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw *rcfw,
72689f81008SSelvin Xavier 			      struct bnxt_qplib_roce_stats *stats)
72789f81008SSelvin Xavier {
728ff015bcdSSelvin Xavier 	struct creq_query_roce_stats_resp resp = {};
72989f81008SSelvin Xavier 	struct creq_query_roce_stats_resp_sb *sb;
730ff015bcdSSelvin Xavier 	struct cmdq_query_roce_stats req = {};
731ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
732c9f3e4e1SSelvin Xavier 	struct bnxt_qplib_rcfw_sbuf sbuf;
73314611b9bSKalesh AP 	int rc;
73489f81008SSelvin Xavier 
735e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
736e576adf5SSelvin Xavier 				 CMDQ_BASE_OPCODE_QUERY_ROCE_STATS,
737e576adf5SSelvin Xavier 				 sizeof(req));
73889f81008SSelvin Xavier 
739c9f3e4e1SSelvin Xavier 	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
740c9f3e4e1SSelvin Xavier 	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
741c9f3e4e1SSelvin Xavier 				     &sbuf.dma_addr, GFP_KERNEL);
742c9f3e4e1SSelvin Xavier 	if (!sbuf.sb)
74389f81008SSelvin Xavier 		return -ENOMEM;
744c9f3e4e1SSelvin Xavier 	sb = sbuf.sb;
74589f81008SSelvin Xavier 
746c9f3e4e1SSelvin Xavier 	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
747c9f3e4e1SSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
748ff015bcdSSelvin Xavier 				sizeof(resp), 0);
749ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
75089f81008SSelvin Xavier 	if (rc)
75189f81008SSelvin Xavier 		goto bail;
75289f81008SSelvin Xavier 	/* Extract the context from the side buffer */
75389f81008SSelvin Xavier 	stats->to_retransmits = le64_to_cpu(sb->to_retransmits);
75489f81008SSelvin Xavier 	stats->seq_err_naks_rcvd = le64_to_cpu(sb->seq_err_naks_rcvd);
75589f81008SSelvin Xavier 	stats->max_retry_exceeded = le64_to_cpu(sb->max_retry_exceeded);
75689f81008SSelvin Xavier 	stats->rnr_naks_rcvd = le64_to_cpu(sb->rnr_naks_rcvd);
75789f81008SSelvin Xavier 	stats->missing_resp = le64_to_cpu(sb->missing_resp);
75889f81008SSelvin Xavier 	stats->unrecoverable_err = le64_to_cpu(sb->unrecoverable_err);
75989f81008SSelvin Xavier 	stats->bad_resp_err = le64_to_cpu(sb->bad_resp_err);
76089f81008SSelvin Xavier 	stats->local_qp_op_err = le64_to_cpu(sb->local_qp_op_err);
76189f81008SSelvin Xavier 	stats->local_protection_err = le64_to_cpu(sb->local_protection_err);
76289f81008SSelvin Xavier 	stats->mem_mgmt_op_err = le64_to_cpu(sb->mem_mgmt_op_err);
76389f81008SSelvin Xavier 	stats->remote_invalid_req_err = le64_to_cpu(sb->remote_invalid_req_err);
76489f81008SSelvin Xavier 	stats->remote_access_err = le64_to_cpu(sb->remote_access_err);
76589f81008SSelvin Xavier 	stats->remote_op_err = le64_to_cpu(sb->remote_op_err);
76689f81008SSelvin Xavier 	stats->dup_req = le64_to_cpu(sb->dup_req);
76789f81008SSelvin Xavier 	stats->res_exceed_max = le64_to_cpu(sb->res_exceed_max);
76889f81008SSelvin Xavier 	stats->res_length_mismatch = le64_to_cpu(sb->res_length_mismatch);
76989f81008SSelvin Xavier 	stats->res_exceeds_wqe = le64_to_cpu(sb->res_exceeds_wqe);
77089f81008SSelvin Xavier 	stats->res_opcode_err = le64_to_cpu(sb->res_opcode_err);
77189f81008SSelvin Xavier 	stats->res_rx_invalid_rkey = le64_to_cpu(sb->res_rx_invalid_rkey);
77289f81008SSelvin Xavier 	stats->res_rx_domain_err = le64_to_cpu(sb->res_rx_domain_err);
77389f81008SSelvin Xavier 	stats->res_rx_no_perm = le64_to_cpu(sb->res_rx_no_perm);
77489f81008SSelvin Xavier 	stats->res_rx_range_err = le64_to_cpu(sb->res_rx_range_err);
77589f81008SSelvin Xavier 	stats->res_tx_invalid_rkey = le64_to_cpu(sb->res_tx_invalid_rkey);
77689f81008SSelvin Xavier 	stats->res_tx_domain_err = le64_to_cpu(sb->res_tx_domain_err);
77789f81008SSelvin Xavier 	stats->res_tx_no_perm = le64_to_cpu(sb->res_tx_no_perm);
77889f81008SSelvin Xavier 	stats->res_tx_range_err = le64_to_cpu(sb->res_tx_range_err);
77989f81008SSelvin Xavier 	stats->res_irrq_oflow = le64_to_cpu(sb->res_irrq_oflow);
78089f81008SSelvin Xavier 	stats->res_unsup_opcode = le64_to_cpu(sb->res_unsup_opcode);
78189f81008SSelvin Xavier 	stats->res_unaligned_atomic = le64_to_cpu(sb->res_unaligned_atomic);
78289f81008SSelvin Xavier 	stats->res_rem_inv_err = le64_to_cpu(sb->res_rem_inv_err);
78389f81008SSelvin Xavier 	stats->res_mem_error = le64_to_cpu(sb->res_mem_error);
78489f81008SSelvin Xavier 	stats->res_srq_err = le64_to_cpu(sb->res_srq_err);
78589f81008SSelvin Xavier 	stats->res_cmp_err = le64_to_cpu(sb->res_cmp_err);
78689f81008SSelvin Xavier 	stats->res_invalid_dup_rkey = le64_to_cpu(sb->res_invalid_dup_rkey);
78789f81008SSelvin Xavier 	stats->res_wqe_format_err = le64_to_cpu(sb->res_wqe_format_err);
78889f81008SSelvin Xavier 	stats->res_cq_load_err = le64_to_cpu(sb->res_cq_load_err);
78989f81008SSelvin Xavier 	stats->res_srq_load_err = le64_to_cpu(sb->res_srq_load_err);
79089f81008SSelvin Xavier 	stats->res_tx_pci_err = le64_to_cpu(sb->res_tx_pci_err);
79189f81008SSelvin Xavier 	stats->res_rx_pci_err = le64_to_cpu(sb->res_rx_pci_err);
792316dd282SSelvin Xavier 	if (!rcfw->init_oos_stats) {
793316dd282SSelvin Xavier 		rcfw->oos_prev = le64_to_cpu(sb->res_oos_drop_count);
794316dd282SSelvin Xavier 		rcfw->init_oos_stats = 1;
795316dd282SSelvin Xavier 	} else {
796316dd282SSelvin Xavier 		stats->res_oos_drop_count +=
797316dd282SSelvin Xavier 				(le64_to_cpu(sb->res_oos_drop_count) -
798316dd282SSelvin Xavier 				 rcfw->oos_prev) & BNXT_QPLIB_OOS_COUNT_MASK;
799316dd282SSelvin Xavier 		rcfw->oos_prev = le64_to_cpu(sb->res_oos_drop_count);
800316dd282SSelvin Xavier 	}
801316dd282SSelvin Xavier 
80289f81008SSelvin Xavier bail:
803c9f3e4e1SSelvin Xavier 	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
804c9f3e4e1SSelvin Xavier 			  sbuf.sb, sbuf.dma_addr);
80589f81008SSelvin Xavier 	return rc;
80689f81008SSelvin Xavier }
8079a381f7eSSelvin Xavier 
bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw * rcfw,u32 fid,struct bnxt_qplib_ext_stat * estat)8089a381f7eSSelvin Xavier int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid,
8099a381f7eSSelvin Xavier 			 struct bnxt_qplib_ext_stat *estat)
8109a381f7eSSelvin Xavier {
8119a381f7eSSelvin Xavier 	struct creq_query_roce_stats_ext_resp resp = {};
8129a381f7eSSelvin Xavier 	struct creq_query_roce_stats_ext_resp_sb *sb;
8139a381f7eSSelvin Xavier 	struct cmdq_query_roce_stats_ext req = {};
814ff015bcdSSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
815c9f3e4e1SSelvin Xavier 	struct bnxt_qplib_rcfw_sbuf sbuf;
8169a381f7eSSelvin Xavier 	int rc;
8179a381f7eSSelvin Xavier 
818c9f3e4e1SSelvin Xavier 	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
819c9f3e4e1SSelvin Xavier 	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
820c9f3e4e1SSelvin Xavier 				     &sbuf.dma_addr, GFP_KERNEL);
821c9f3e4e1SSelvin Xavier 	if (!sbuf.sb)
8229a381f7eSSelvin Xavier 		return -ENOMEM;
8239a381f7eSSelvin Xavier 
824c9f3e4e1SSelvin Xavier 	sb = sbuf.sb;
825e576adf5SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
826e576adf5SSelvin Xavier 				 CMDQ_QUERY_ROCE_STATS_EXT_OPCODE_QUERY_ROCE_STATS,
827e576adf5SSelvin Xavier 				 sizeof(req));
8289a381f7eSSelvin Xavier 
829c9f3e4e1SSelvin Xavier 	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
830c9f3e4e1SSelvin Xavier 	req.resp_addr = cpu_to_le64(sbuf.dma_addr);
8319a381f7eSSelvin Xavier 	req.function_id = cpu_to_le32(fid);
8329a381f7eSSelvin Xavier 	req.flags = cpu_to_le16(CMDQ_QUERY_ROCE_STATS_EXT_FLAGS_FUNCTION_ID);
8339a381f7eSSelvin Xavier 
834c9f3e4e1SSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
835ff015bcdSSelvin Xavier 				sizeof(resp), 0);
836ff015bcdSSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
8379a381f7eSSelvin Xavier 	if (rc)
8389a381f7eSSelvin Xavier 		goto bail;
8399a381f7eSSelvin Xavier 
8409a381f7eSSelvin Xavier 	estat->tx_atomic_req = le64_to_cpu(sb->tx_atomic_req_pkts);
8419a381f7eSSelvin Xavier 	estat->tx_read_req = le64_to_cpu(sb->tx_read_req_pkts);
8429a381f7eSSelvin Xavier 	estat->tx_read_res = le64_to_cpu(sb->tx_read_res_pkts);
8439a381f7eSSelvin Xavier 	estat->tx_write_req = le64_to_cpu(sb->tx_write_req_pkts);
8449a381f7eSSelvin Xavier 	estat->tx_send_req = le64_to_cpu(sb->tx_send_req_pkts);
8454405baf8SChandramohan Akula 	estat->tx_roce_pkts = le64_to_cpu(sb->tx_roce_pkts);
8464405baf8SChandramohan Akula 	estat->tx_roce_bytes = le64_to_cpu(sb->tx_roce_bytes);
8479a381f7eSSelvin Xavier 	estat->rx_atomic_req = le64_to_cpu(sb->rx_atomic_req_pkts);
8489a381f7eSSelvin Xavier 	estat->rx_read_req = le64_to_cpu(sb->rx_read_req_pkts);
8499a381f7eSSelvin Xavier 	estat->rx_read_res = le64_to_cpu(sb->rx_read_res_pkts);
8509a381f7eSSelvin Xavier 	estat->rx_write_req = le64_to_cpu(sb->rx_write_req_pkts);
8519a381f7eSSelvin Xavier 	estat->rx_send_req = le64_to_cpu(sb->rx_send_req_pkts);
8524405baf8SChandramohan Akula 	estat->rx_roce_pkts = le64_to_cpu(sb->rx_roce_pkts);
8534405baf8SChandramohan Akula 	estat->rx_roce_bytes = le64_to_cpu(sb->rx_roce_bytes);
8549a381f7eSSelvin Xavier 	estat->rx_roce_good_pkts = le64_to_cpu(sb->rx_roce_good_pkts);
8559a381f7eSSelvin Xavier 	estat->rx_roce_good_bytes = le64_to_cpu(sb->rx_roce_good_bytes);
8569a381f7eSSelvin Xavier 	estat->rx_out_of_buffer = le64_to_cpu(sb->rx_out_of_buffer_pkts);
8579a381f7eSSelvin Xavier 	estat->rx_out_of_sequence = le64_to_cpu(sb->rx_out_of_sequence_pkts);
8584405baf8SChandramohan Akula 	estat->tx_cnp = le64_to_cpu(sb->tx_cnp_pkts);
8594405baf8SChandramohan Akula 	estat->rx_cnp = le64_to_cpu(sb->rx_cnp_pkts);
8604405baf8SChandramohan Akula 	estat->rx_ecn_marked = le64_to_cpu(sb->rx_ecn_marked_pkts);
8619a381f7eSSelvin Xavier 
8629a381f7eSSelvin Xavier bail:
863c9f3e4e1SSelvin Xavier 	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
864c9f3e4e1SSelvin Xavier 			  sbuf.sb, sbuf.dma_addr);
8659a381f7eSSelvin Xavier 	return rc;
8669a381f7eSSelvin Xavier }
867f13bcef0SSelvin Xavier 
bnxt_qplib_fill_cc_gen1(struct cmdq_modify_roce_cc_gen1_tlv * ext_req,struct bnxt_qplib_cc_param_ext * cc_ext)868f13bcef0SSelvin Xavier static void bnxt_qplib_fill_cc_gen1(struct cmdq_modify_roce_cc_gen1_tlv *ext_req,
869f13bcef0SSelvin Xavier 				    struct bnxt_qplib_cc_param_ext *cc_ext)
870f13bcef0SSelvin Xavier {
871f13bcef0SSelvin Xavier 	ext_req->modify_mask = cpu_to_le64(cc_ext->ext_mask);
872f13bcef0SSelvin Xavier 	cc_ext->ext_mask = 0;
873f13bcef0SSelvin Xavier 	ext_req->inactivity_th_hi = cpu_to_le16(cc_ext->inact_th_hi);
874f13bcef0SSelvin Xavier 	ext_req->min_time_between_cnps = cpu_to_le16(cc_ext->min_delta_cnp);
875f13bcef0SSelvin Xavier 	ext_req->init_cp = cpu_to_le16(cc_ext->init_cp);
876f13bcef0SSelvin Xavier 	ext_req->tr_update_mode = cc_ext->tr_update_mode;
877f13bcef0SSelvin Xavier 	ext_req->tr_update_cycles = cc_ext->tr_update_cyls;
878f13bcef0SSelvin Xavier 	ext_req->fr_num_rtts = cc_ext->fr_rtt;
879f13bcef0SSelvin Xavier 	ext_req->ai_rate_increase = cc_ext->ai_rate_incr;
880f13bcef0SSelvin Xavier 	ext_req->reduction_relax_rtts_th = cpu_to_le16(cc_ext->rr_rtt_th);
881f13bcef0SSelvin Xavier 	ext_req->additional_relax_cr_th = cpu_to_le16(cc_ext->ar_cr_th);
882f13bcef0SSelvin Xavier 	ext_req->cr_min_th = cpu_to_le16(cc_ext->cr_min_th);
883f13bcef0SSelvin Xavier 	ext_req->bw_avg_weight = cc_ext->bw_avg_weight;
884f13bcef0SSelvin Xavier 	ext_req->actual_cr_factor = cc_ext->cr_factor;
885f13bcef0SSelvin Xavier 	ext_req->max_cp_cr_th = cpu_to_le16(cc_ext->cr_th_max_cp);
886f13bcef0SSelvin Xavier 	ext_req->cp_bias_en = cc_ext->cp_bias_en;
887f13bcef0SSelvin Xavier 	ext_req->cp_bias = cc_ext->cp_bias;
888f13bcef0SSelvin Xavier 	ext_req->cnp_ecn = cc_ext->cnp_ecn;
889f13bcef0SSelvin Xavier 	ext_req->rtt_jitter_en = cc_ext->rtt_jitter_en;
890f13bcef0SSelvin Xavier 	ext_req->link_bytes_per_usec = cpu_to_le16(cc_ext->bytes_per_usec);
891f13bcef0SSelvin Xavier 	ext_req->reset_cc_cr_th = cpu_to_le16(cc_ext->cc_cr_reset_th);
892f13bcef0SSelvin Xavier 	ext_req->cr_width = cc_ext->cr_width;
893f13bcef0SSelvin Xavier 	ext_req->quota_period_min = cc_ext->min_quota;
894f13bcef0SSelvin Xavier 	ext_req->quota_period_max = cc_ext->max_quota;
895f13bcef0SSelvin Xavier 	ext_req->quota_period_abs_max = cc_ext->abs_max_quota;
896f13bcef0SSelvin Xavier 	ext_req->tr_lower_bound = cpu_to_le16(cc_ext->tr_lb);
897f13bcef0SSelvin Xavier 	ext_req->cr_prob_factor = cc_ext->cr_prob_fac;
898f13bcef0SSelvin Xavier 	ext_req->tr_prob_factor = cc_ext->tr_prob_fac;
899f13bcef0SSelvin Xavier 	ext_req->fairness_cr_th = cpu_to_le16(cc_ext->fair_cr_th);
900f13bcef0SSelvin Xavier 	ext_req->red_div = cc_ext->red_div;
901f13bcef0SSelvin Xavier 	ext_req->cnp_ratio_th = cc_ext->cnp_ratio_th;
902f13bcef0SSelvin Xavier 	ext_req->exp_ai_rtts = cpu_to_le16(cc_ext->ai_ext_rtt);
903f13bcef0SSelvin Xavier 	ext_req->exp_ai_cr_cp_ratio = cc_ext->exp_crcp_ratio;
904f13bcef0SSelvin Xavier 	ext_req->use_rate_table = cc_ext->low_rate_en;
905f13bcef0SSelvin Xavier 	ext_req->cp_exp_update_th = cpu_to_le16(cc_ext->cpcr_update_th);
906f13bcef0SSelvin Xavier 	ext_req->high_exp_ai_rtts_th1 = cpu_to_le16(cc_ext->ai_rtt_th1);
907f13bcef0SSelvin Xavier 	ext_req->high_exp_ai_rtts_th2 = cpu_to_le16(cc_ext->ai_rtt_th2);
908f13bcef0SSelvin Xavier 	ext_req->actual_cr_cong_free_rtts_th = cpu_to_le16(cc_ext->cf_rtt_th);
909f13bcef0SSelvin Xavier 	ext_req->severe_cong_cr_th1 = cpu_to_le16(cc_ext->sc_cr_th1);
910f13bcef0SSelvin Xavier 	ext_req->severe_cong_cr_th2 = cpu_to_le16(cc_ext->sc_cr_th2);
911f13bcef0SSelvin Xavier 	ext_req->link64B_per_rtt = cpu_to_le32(cc_ext->l64B_per_rtt);
912f13bcef0SSelvin Xavier 	ext_req->cc_ack_bytes = cc_ext->cc_ack_bytes;
913f13bcef0SSelvin Xavier }
914f13bcef0SSelvin Xavier 
bnxt_qplib_modify_cc(struct bnxt_qplib_res * res,struct bnxt_qplib_cc_param * cc_param)915f13bcef0SSelvin Xavier int bnxt_qplib_modify_cc(struct bnxt_qplib_res *res,
916f13bcef0SSelvin Xavier 			 struct bnxt_qplib_cc_param *cc_param)
917f13bcef0SSelvin Xavier {
918f13bcef0SSelvin Xavier 	struct bnxt_qplib_tlv_modify_cc_req tlv_req = {};
919f13bcef0SSelvin Xavier 	struct creq_modify_roce_cc_resp resp = {};
920f13bcef0SSelvin Xavier 	struct bnxt_qplib_cmdqmsg msg = {};
921f13bcef0SSelvin Xavier 	struct cmdq_modify_roce_cc *req;
922f13bcef0SSelvin Xavier 	int req_size;
923f13bcef0SSelvin Xavier 	void *cmd;
924f13bcef0SSelvin Xavier 	int rc;
925f13bcef0SSelvin Xavier 
926f13bcef0SSelvin Xavier 	/* Prepare the older base command */
927f13bcef0SSelvin Xavier 	req = &tlv_req.base_req;
928f13bcef0SSelvin Xavier 	cmd = req;
929f13bcef0SSelvin Xavier 	req_size = sizeof(*req);
930f13bcef0SSelvin Xavier 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)req, CMDQ_BASE_OPCODE_MODIFY_ROCE_CC,
931f13bcef0SSelvin Xavier 				 sizeof(*req));
932f13bcef0SSelvin Xavier 	req->modify_mask = cpu_to_le32(cc_param->mask);
933f13bcef0SSelvin Xavier 	req->enable_cc = cc_param->enable;
934f13bcef0SSelvin Xavier 	req->g = cc_param->g;
935f13bcef0SSelvin Xavier 	req->num_phases_per_state = cc_param->nph_per_state;
936f13bcef0SSelvin Xavier 	req->time_per_phase = cc_param->time_pph;
937f13bcef0SSelvin Xavier 	req->pkts_per_phase = cc_param->pkts_pph;
938f13bcef0SSelvin Xavier 	req->init_cr = cpu_to_le16(cc_param->init_cr);
939f13bcef0SSelvin Xavier 	req->init_tr = cpu_to_le16(cc_param->init_tr);
940f13bcef0SSelvin Xavier 	req->tos_dscp_tos_ecn = (cc_param->tos_dscp << CMDQ_MODIFY_ROCE_CC_TOS_DSCP_SFT) |
941f13bcef0SSelvin Xavier 				(cc_param->tos_ecn & CMDQ_MODIFY_ROCE_CC_TOS_ECN_MASK);
942f13bcef0SSelvin Xavier 	req->alt_vlan_pcp = cc_param->alt_vlan_pcp;
943f13bcef0SSelvin Xavier 	req->alt_tos_dscp = cpu_to_le16(cc_param->alt_tos_dscp);
944f13bcef0SSelvin Xavier 	req->rtt = cpu_to_le16(cc_param->rtt);
945f13bcef0SSelvin Xavier 	req->tcp_cp = cpu_to_le16(cc_param->tcp_cp);
946f13bcef0SSelvin Xavier 	req->cc_mode = cc_param->cc_mode;
947f13bcef0SSelvin Xavier 	req->inactivity_th = cpu_to_le16(cc_param->inact_th);
948f13bcef0SSelvin Xavier 
949f13bcef0SSelvin Xavier 	/* For chip gen P5 onwards fill extended cmd and header */
9501801d87bSSelvin Xavier 	if (bnxt_qplib_is_chip_gen_p5_p7(res->cctx)) {
951f13bcef0SSelvin Xavier 		struct roce_tlv *hdr;
952f13bcef0SSelvin Xavier 		u32 payload;
953f13bcef0SSelvin Xavier 		u32 chunks;
954f13bcef0SSelvin Xavier 
955f13bcef0SSelvin Xavier 		cmd = &tlv_req;
956f13bcef0SSelvin Xavier 		req_size = sizeof(tlv_req);
957f13bcef0SSelvin Xavier 		/* Prepare primary tlv header */
958f13bcef0SSelvin Xavier 		hdr = &tlv_req.tlv_hdr;
959f13bcef0SSelvin Xavier 		chunks = CHUNKS(sizeof(struct bnxt_qplib_tlv_modify_cc_req));
960f13bcef0SSelvin Xavier 		payload = sizeof(struct cmdq_modify_roce_cc);
961f13bcef0SSelvin Xavier 		__roce_1st_tlv_prep(hdr, chunks, payload, true);
962f13bcef0SSelvin Xavier 		/* Prepare secondary tlv header */
963f13bcef0SSelvin Xavier 		hdr = (struct roce_tlv *)&tlv_req.ext_req;
964f13bcef0SSelvin Xavier 		payload = sizeof(struct cmdq_modify_roce_cc_gen1_tlv) -
965f13bcef0SSelvin Xavier 			  sizeof(struct roce_tlv);
966f13bcef0SSelvin Xavier 		__roce_ext_tlv_prep(hdr, TLV_TYPE_MODIFY_ROCE_CC_GEN1, payload, false, true);
967f13bcef0SSelvin Xavier 		bnxt_qplib_fill_cc_gen1(&tlv_req.ext_req, &cc_param->cc_ext);
968f13bcef0SSelvin Xavier 	}
969f13bcef0SSelvin Xavier 
970f13bcef0SSelvin Xavier 	bnxt_qplib_fill_cmdqmsg(&msg, cmd, &resp, NULL, req_size,
971f13bcef0SSelvin Xavier 				sizeof(resp), 0);
972f13bcef0SSelvin Xavier 	rc = bnxt_qplib_rcfw_send_message(res->rcfw, &msg);
973f13bcef0SSelvin Xavier 	return rc;
974f13bcef0SSelvin Xavier }
975