xref: /linux/drivers/infiniband/hw/bnxt_re/qplib_sp.c (revision 58d4a671)
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 
391ac5a404SSelvin Xavier #include <linux/interrupt.h>
401ac5a404SSelvin Xavier #include <linux/spinlock.h>
411ac5a404SSelvin Xavier #include <linux/sched.h>
421ac5a404SSelvin Xavier #include <linux/pci.h>
431ac5a404SSelvin Xavier 
441ac5a404SSelvin Xavier #include "roce_hsi.h"
451ac5a404SSelvin Xavier 
461ac5a404SSelvin Xavier #include "qplib_res.h"
471ac5a404SSelvin Xavier #include "qplib_rcfw.h"
481ac5a404SSelvin Xavier #include "qplib_sp.h"
491ac5a404SSelvin Xavier 
501ac5a404SSelvin Xavier const struct bnxt_qplib_gid bnxt_qplib_gid_zero = {{ 0, 0, 0, 0, 0, 0, 0, 0,
511ac5a404SSelvin Xavier 						     0, 0, 0, 0, 0, 0, 0, 0 } };
521ac5a404SSelvin Xavier 
531ac5a404SSelvin Xavier /* Device */
541ac5a404SSelvin Xavier int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
551ac5a404SSelvin Xavier 			    struct bnxt_qplib_dev_attr *attr)
561ac5a404SSelvin Xavier {
571ac5a404SSelvin Xavier 	struct cmdq_query_func req;
58cc1ec769SDevesh Sharma 	struct creq_query_func_resp resp;
59cc1ec769SDevesh Sharma 	struct bnxt_qplib_rcfw_sbuf *sbuf;
601ac5a404SSelvin Xavier 	struct creq_query_func_resp_sb *sb;
611ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
621ac5a404SSelvin Xavier 	u32 temp;
631ac5a404SSelvin Xavier 	u8 *tqm_alloc;
64cc1ec769SDevesh Sharma 	int i, rc = 0;
651ac5a404SSelvin Xavier 
661ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, QUERY_FUNC, cmd_flags);
671ac5a404SSelvin Xavier 
68cc1ec769SDevesh Sharma 	sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
69cc1ec769SDevesh Sharma 	if (!sbuf) {
701ac5a404SSelvin Xavier 		dev_err(&rcfw->pdev->dev,
71cc1ec769SDevesh Sharma 			"QPLIB: SP: QUERY_FUNC alloc side buffer failed");
72cc1ec769SDevesh Sharma 		return -ENOMEM;
731ac5a404SSelvin Xavier 	}
74cc1ec769SDevesh Sharma 
75cc1ec769SDevesh Sharma 	sb = sbuf->sb;
76cc1ec769SDevesh Sharma 	req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
77cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
78cc1ec769SDevesh Sharma 					  (void *)sbuf, 0);
79cc1ec769SDevesh Sharma 	if (rc)
80cc1ec769SDevesh Sharma 		goto bail;
81cc1ec769SDevesh Sharma 
821ac5a404SSelvin Xavier 	/* Extract the context from the side buffer */
831ac5a404SSelvin Xavier 	attr->max_qp = le32_to_cpu(sb->max_qp);
84*58d4a671SSelvin Xavier 	/* max_qp value reported by FW for PF doesn't include the QP1 for PF */
85*58d4a671SSelvin Xavier 	attr->max_qp += 1;
861ac5a404SSelvin Xavier 	attr->max_qp_rd_atom =
871ac5a404SSelvin Xavier 		sb->max_qp_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
881ac5a404SSelvin Xavier 		BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_rd_atom;
891ac5a404SSelvin Xavier 	attr->max_qp_init_rd_atom =
901ac5a404SSelvin Xavier 		sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
911ac5a404SSelvin Xavier 		BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
921ac5a404SSelvin Xavier 	attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr);
939152e0b7SEddie Wai 	/*
949152e0b7SEddie Wai 	 * 128 WQEs needs to be reserved for the HW (8916). Prevent
959152e0b7SEddie Wai 	 * reporting the max number
969152e0b7SEddie Wai 	 */
979152e0b7SEddie Wai 	attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS;
981ac5a404SSelvin Xavier 	attr->max_qp_sges = sb->max_sge;
991ac5a404SSelvin Xavier 	attr->max_cq = le32_to_cpu(sb->max_cq);
1001ac5a404SSelvin Xavier 	attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
1011ac5a404SSelvin Xavier 	attr->max_cq_sges = attr->max_qp_sges;
1021ac5a404SSelvin Xavier 	attr->max_mr = le32_to_cpu(sb->max_mr);
1031ac5a404SSelvin Xavier 	attr->max_mw = le32_to_cpu(sb->max_mw);
1041ac5a404SSelvin Xavier 
1051ac5a404SSelvin Xavier 	attr->max_mr_size = le64_to_cpu(sb->max_mr_size);
1061ac5a404SSelvin Xavier 	attr->max_pd = 64 * 1024;
1071ac5a404SSelvin Xavier 	attr->max_raw_ethy_qp = le32_to_cpu(sb->max_raw_eth_qp);
1081ac5a404SSelvin Xavier 	attr->max_ah = le32_to_cpu(sb->max_ah);
1091ac5a404SSelvin Xavier 
1101ac5a404SSelvin Xavier 	attr->max_fmr = le32_to_cpu(sb->max_fmr);
1111ac5a404SSelvin Xavier 	attr->max_map_per_fmr = sb->max_map_per_fmr;
1121ac5a404SSelvin Xavier 
1131ac5a404SSelvin Xavier 	attr->max_srq = le16_to_cpu(sb->max_srq);
1141ac5a404SSelvin Xavier 	attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1;
1151ac5a404SSelvin Xavier 	attr->max_srq_sges = sb->max_srq_sge;
1161ac5a404SSelvin Xavier 	/* Bono only reports 1 PKEY for now, but it can support > 1 */
1171ac5a404SSelvin Xavier 	attr->max_pkey = le32_to_cpu(sb->max_pkeys);
1181ac5a404SSelvin Xavier 
1191ac5a404SSelvin Xavier 	attr->max_inline_data = le32_to_cpu(sb->max_inline_data);
1201ac5a404SSelvin Xavier 	attr->l2_db_size = (sb->l2_db_space_size + 1) * PAGE_SIZE;
1211ac5a404SSelvin Xavier 	attr->max_sgid = le32_to_cpu(sb->max_gid);
1221ac5a404SSelvin Xavier 
1231ac5a404SSelvin Xavier 	strlcpy(attr->fw_ver, "20.6.28.0", sizeof(attr->fw_ver));
1241ac5a404SSelvin Xavier 
1251ac5a404SSelvin Xavier 	for (i = 0; i < MAX_TQM_ALLOC_REQ / 4; i++) {
1261ac5a404SSelvin Xavier 		temp = le32_to_cpu(sb->tqm_alloc_reqs[i]);
1271ac5a404SSelvin Xavier 		tqm_alloc = (u8 *)&temp;
1281ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4] = *tqm_alloc;
1291ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4 + 1] = *(++tqm_alloc);
1301ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4 + 2] = *(++tqm_alloc);
1311ac5a404SSelvin Xavier 		attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc);
1321ac5a404SSelvin Xavier 	}
133cc1ec769SDevesh Sharma 
134cc1ec769SDevesh Sharma bail:
135cc1ec769SDevesh Sharma 	bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
136cc1ec769SDevesh Sharma 	return rc;
1371ac5a404SSelvin Xavier }
1381ac5a404SSelvin Xavier 
1391ac5a404SSelvin Xavier /* SGID */
1401ac5a404SSelvin Xavier int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
1411ac5a404SSelvin Xavier 			struct bnxt_qplib_sgid_tbl *sgid_tbl, int index,
1421ac5a404SSelvin Xavier 			struct bnxt_qplib_gid *gid)
1431ac5a404SSelvin Xavier {
1441ac5a404SSelvin Xavier 	if (index > sgid_tbl->max) {
1451ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
1461ac5a404SSelvin Xavier 			"QPLIB: Index %d exceeded SGID table max (%d)",
1471ac5a404SSelvin Xavier 			index, sgid_tbl->max);
1481ac5a404SSelvin Xavier 		return -EINVAL;
1491ac5a404SSelvin Xavier 	}
1501ac5a404SSelvin Xavier 	memcpy(gid, &sgid_tbl->tbl[index], sizeof(*gid));
1511ac5a404SSelvin Xavier 	return 0;
1521ac5a404SSelvin Xavier }
1531ac5a404SSelvin Xavier 
1541ac5a404SSelvin Xavier int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
1551ac5a404SSelvin Xavier 			struct bnxt_qplib_gid *gid, bool update)
1561ac5a404SSelvin Xavier {
1571ac5a404SSelvin Xavier 	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
1581ac5a404SSelvin Xavier 						   struct bnxt_qplib_res,
1591ac5a404SSelvin Xavier 						   sgid_tbl);
1601ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
1611ac5a404SSelvin Xavier 	int index;
1621ac5a404SSelvin Xavier 
1631ac5a404SSelvin Xavier 	if (!sgid_tbl) {
1641ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev, "QPLIB: SGID table not allocated");
1651ac5a404SSelvin Xavier 		return -EINVAL;
1661ac5a404SSelvin Xavier 	}
1671ac5a404SSelvin Xavier 	/* Do we need a sgid_lock here? */
1681ac5a404SSelvin Xavier 	if (!sgid_tbl->active) {
1691ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
1701ac5a404SSelvin Xavier 			"QPLIB: SGID table has no active entries");
1711ac5a404SSelvin Xavier 		return -ENOMEM;
1721ac5a404SSelvin Xavier 	}
1731ac5a404SSelvin Xavier 	for (index = 0; index < sgid_tbl->max; index++) {
1741ac5a404SSelvin Xavier 		if (!memcmp(&sgid_tbl->tbl[index], gid, sizeof(*gid)))
1751ac5a404SSelvin Xavier 			break;
1761ac5a404SSelvin Xavier 	}
1771ac5a404SSelvin Xavier 	if (index == sgid_tbl->max) {
1781ac5a404SSelvin Xavier 		dev_warn(&res->pdev->dev, "GID not found in the SGID table");
1791ac5a404SSelvin Xavier 		return 0;
1801ac5a404SSelvin Xavier 	}
1811ac5a404SSelvin Xavier 	/* Remove GID from the SGID table */
1821ac5a404SSelvin Xavier 	if (update) {
1831ac5a404SSelvin Xavier 		struct cmdq_delete_gid req;
184cc1ec769SDevesh Sharma 		struct creq_delete_gid_resp resp;
1851ac5a404SSelvin Xavier 		u16 cmd_flags = 0;
186cc1ec769SDevesh Sharma 		int rc;
1871ac5a404SSelvin Xavier 
1881ac5a404SSelvin Xavier 		RCFW_CMD_PREP(req, DELETE_GID, cmd_flags);
1891ac5a404SSelvin Xavier 		if (sgid_tbl->hw_id[index] == 0xFFFF) {
1901ac5a404SSelvin Xavier 			dev_err(&res->pdev->dev,
1911ac5a404SSelvin Xavier 				"QPLIB: GID entry contains an invalid HW id");
1921ac5a404SSelvin Xavier 			return -EINVAL;
1931ac5a404SSelvin Xavier 		}
1941ac5a404SSelvin Xavier 		req.gid_index = cpu_to_le16(sgid_tbl->hw_id[index]);
195cc1ec769SDevesh Sharma 		rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
196cc1ec769SDevesh Sharma 						  (void *)&resp, NULL, 0);
197cc1ec769SDevesh Sharma 		if (rc)
198cc1ec769SDevesh Sharma 			return rc;
1991ac5a404SSelvin Xavier 	}
2001ac5a404SSelvin Xavier 	memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
2011ac5a404SSelvin Xavier 	       sizeof(bnxt_qplib_gid_zero));
2021ac5a404SSelvin Xavier 	sgid_tbl->active--;
2031ac5a404SSelvin Xavier 	dev_dbg(&res->pdev->dev,
2041ac5a404SSelvin Xavier 		"QPLIB: SGID deleted hw_id[0x%x] = 0x%x active = 0x%x",
2051ac5a404SSelvin Xavier 		 index, sgid_tbl->hw_id[index], sgid_tbl->active);
2061ac5a404SSelvin Xavier 	sgid_tbl->hw_id[index] = (u16)-1;
2071ac5a404SSelvin Xavier 
2081ac5a404SSelvin Xavier 	/* unlock */
2091ac5a404SSelvin Xavier 	return 0;
2101ac5a404SSelvin Xavier }
2111ac5a404SSelvin Xavier 
2121ac5a404SSelvin Xavier int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
2131ac5a404SSelvin Xavier 			struct bnxt_qplib_gid *gid, u8 *smac, u16 vlan_id,
2141ac5a404SSelvin Xavier 			bool update, u32 *index)
2151ac5a404SSelvin Xavier {
2161ac5a404SSelvin Xavier 	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
2171ac5a404SSelvin Xavier 						   struct bnxt_qplib_res,
2181ac5a404SSelvin Xavier 						   sgid_tbl);
2191ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
220cc1ec769SDevesh Sharma 	int i, free_idx;
2211ac5a404SSelvin Xavier 
2221ac5a404SSelvin Xavier 	if (!sgid_tbl) {
2231ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev, "QPLIB: SGID table not allocated");
2241ac5a404SSelvin Xavier 		return -EINVAL;
2251ac5a404SSelvin Xavier 	}
2261ac5a404SSelvin Xavier 	/* Do we need a sgid_lock here? */
2271ac5a404SSelvin Xavier 	if (sgid_tbl->active == sgid_tbl->max) {
2281ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev, "QPLIB: SGID table is full");
2291ac5a404SSelvin Xavier 		return -ENOMEM;
2301ac5a404SSelvin Xavier 	}
2311ac5a404SSelvin Xavier 	free_idx = sgid_tbl->max;
2321ac5a404SSelvin Xavier 	for (i = 0; i < sgid_tbl->max; i++) {
2331ac5a404SSelvin Xavier 		if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid))) {
2341ac5a404SSelvin Xavier 			dev_dbg(&res->pdev->dev,
2351ac5a404SSelvin Xavier 				"QPLIB: SGID entry already exist in entry %d!",
2361ac5a404SSelvin Xavier 				i);
2371ac5a404SSelvin Xavier 			*index = i;
2381ac5a404SSelvin Xavier 			return -EALREADY;
2391ac5a404SSelvin Xavier 		} else if (!memcmp(&sgid_tbl->tbl[i], &bnxt_qplib_gid_zero,
2401ac5a404SSelvin Xavier 				   sizeof(bnxt_qplib_gid_zero)) &&
2411ac5a404SSelvin Xavier 			   free_idx == sgid_tbl->max) {
2421ac5a404SSelvin Xavier 			free_idx = i;
2431ac5a404SSelvin Xavier 		}
2441ac5a404SSelvin Xavier 	}
2451ac5a404SSelvin Xavier 	if (free_idx == sgid_tbl->max) {
2461ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
2471ac5a404SSelvin Xavier 			"QPLIB: SGID table is FULL but count is not MAX??");
2481ac5a404SSelvin Xavier 		return -ENOMEM;
2491ac5a404SSelvin Xavier 	}
2501ac5a404SSelvin Xavier 	if (update) {
2511ac5a404SSelvin Xavier 		struct cmdq_add_gid req;
252cc1ec769SDevesh Sharma 		struct creq_add_gid_resp resp;
2531ac5a404SSelvin Xavier 		u16 cmd_flags = 0;
2541ac5a404SSelvin Xavier 		u32 temp32[4];
2551ac5a404SSelvin Xavier 		u16 temp16[3];
256cc1ec769SDevesh Sharma 		int rc;
2571ac5a404SSelvin Xavier 
2581ac5a404SSelvin Xavier 		RCFW_CMD_PREP(req, ADD_GID, cmd_flags);
2591ac5a404SSelvin Xavier 
2601ac5a404SSelvin Xavier 		memcpy(temp32, gid->data, sizeof(struct bnxt_qplib_gid));
2611ac5a404SSelvin Xavier 		req.gid[0] = cpu_to_be32(temp32[3]);
2621ac5a404SSelvin Xavier 		req.gid[1] = cpu_to_be32(temp32[2]);
2631ac5a404SSelvin Xavier 		req.gid[2] = cpu_to_be32(temp32[1]);
2641ac5a404SSelvin Xavier 		req.gid[3] = cpu_to_be32(temp32[0]);
2651ac5a404SSelvin Xavier 		if (vlan_id != 0xFFFF)
2661ac5a404SSelvin Xavier 			req.vlan = cpu_to_le16((vlan_id &
2671ac5a404SSelvin Xavier 					CMDQ_ADD_GID_VLAN_VLAN_ID_MASK) |
2681ac5a404SSelvin Xavier 					CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
2691ac5a404SSelvin Xavier 					CMDQ_ADD_GID_VLAN_VLAN_EN);
2701ac5a404SSelvin Xavier 
2711ac5a404SSelvin Xavier 		/* MAC in network format */
2721ac5a404SSelvin Xavier 		memcpy(temp16, smac, 6);
2731ac5a404SSelvin Xavier 		req.src_mac[0] = cpu_to_be16(temp16[0]);
2741ac5a404SSelvin Xavier 		req.src_mac[1] = cpu_to_be16(temp16[1]);
2751ac5a404SSelvin Xavier 		req.src_mac[2] = cpu_to_be16(temp16[2]);
2761ac5a404SSelvin Xavier 
277cc1ec769SDevesh Sharma 		rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
278cc1ec769SDevesh Sharma 						  (void *)&resp, NULL, 0);
279cc1ec769SDevesh Sharma 		if (rc)
280cc1ec769SDevesh Sharma 			return rc;
281cc1ec769SDevesh Sharma 		sgid_tbl->hw_id[free_idx] = le32_to_cpu(resp.xid);
2821ac5a404SSelvin Xavier 	}
2831ac5a404SSelvin Xavier 	/* Add GID to the sgid_tbl */
2841ac5a404SSelvin Xavier 	memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
2851ac5a404SSelvin Xavier 	sgid_tbl->active++;
2861ac5a404SSelvin Xavier 	dev_dbg(&res->pdev->dev,
2871ac5a404SSelvin Xavier 		"QPLIB: SGID added hw_id[0x%x] = 0x%x active = 0x%x",
2881ac5a404SSelvin Xavier 		 free_idx, sgid_tbl->hw_id[free_idx], sgid_tbl->active);
2891ac5a404SSelvin Xavier 
2901ac5a404SSelvin Xavier 	*index = free_idx;
2911ac5a404SSelvin Xavier 	/* unlock */
292cc1ec769SDevesh Sharma 	return 0;
2931ac5a404SSelvin Xavier }
2941ac5a404SSelvin Xavier 
2951ac5a404SSelvin Xavier /* pkeys */
2961ac5a404SSelvin Xavier int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res,
2971ac5a404SSelvin Xavier 			struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index,
2981ac5a404SSelvin Xavier 			u16 *pkey)
2991ac5a404SSelvin Xavier {
3001ac5a404SSelvin Xavier 	if (index == 0xFFFF) {
3011ac5a404SSelvin Xavier 		*pkey = 0xFFFF;
3021ac5a404SSelvin Xavier 		return 0;
3031ac5a404SSelvin Xavier 	}
3041ac5a404SSelvin Xavier 	if (index > pkey_tbl->max) {
3051ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
3061ac5a404SSelvin Xavier 			"QPLIB: Index %d exceeded PKEY table max (%d)",
3071ac5a404SSelvin Xavier 			index, pkey_tbl->max);
3081ac5a404SSelvin Xavier 		return -EINVAL;
3091ac5a404SSelvin Xavier 	}
3101ac5a404SSelvin Xavier 	memcpy(pkey, &pkey_tbl->tbl[index], sizeof(*pkey));
3111ac5a404SSelvin Xavier 	return 0;
3121ac5a404SSelvin Xavier }
3131ac5a404SSelvin Xavier 
3141ac5a404SSelvin Xavier int bnxt_qplib_del_pkey(struct bnxt_qplib_res *res,
3151ac5a404SSelvin Xavier 			struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 *pkey,
3161ac5a404SSelvin Xavier 			bool update)
3171ac5a404SSelvin Xavier {
3181ac5a404SSelvin Xavier 	int i, rc = 0;
3191ac5a404SSelvin Xavier 
3201ac5a404SSelvin Xavier 	if (!pkey_tbl) {
3211ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev, "QPLIB: PKEY table not allocated");
3221ac5a404SSelvin Xavier 		return -EINVAL;
3231ac5a404SSelvin Xavier 	}
3241ac5a404SSelvin Xavier 
3251ac5a404SSelvin Xavier 	/* Do we need a pkey_lock here? */
3261ac5a404SSelvin Xavier 	if (!pkey_tbl->active) {
3271ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
3281ac5a404SSelvin Xavier 			"QPLIB: PKEY table has no active entries");
3291ac5a404SSelvin Xavier 		return -ENOMEM;
3301ac5a404SSelvin Xavier 	}
3311ac5a404SSelvin Xavier 	for (i = 0; i < pkey_tbl->max; i++) {
3321ac5a404SSelvin Xavier 		if (!memcmp(&pkey_tbl->tbl[i], pkey, sizeof(*pkey)))
3331ac5a404SSelvin Xavier 			break;
3341ac5a404SSelvin Xavier 	}
3351ac5a404SSelvin Xavier 	if (i == pkey_tbl->max) {
3361ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
3371ac5a404SSelvin Xavier 			"QPLIB: PKEY 0x%04x not found in the pkey table",
3381ac5a404SSelvin Xavier 			*pkey);
3391ac5a404SSelvin Xavier 		return -ENOMEM;
3401ac5a404SSelvin Xavier 	}
3411ac5a404SSelvin Xavier 	memset(&pkey_tbl->tbl[i], 0, sizeof(*pkey));
3421ac5a404SSelvin Xavier 	pkey_tbl->active--;
3431ac5a404SSelvin Xavier 
3441ac5a404SSelvin Xavier 	/* unlock */
3451ac5a404SSelvin Xavier 	return rc;
3461ac5a404SSelvin Xavier }
3471ac5a404SSelvin Xavier 
3481ac5a404SSelvin Xavier int bnxt_qplib_add_pkey(struct bnxt_qplib_res *res,
3491ac5a404SSelvin Xavier 			struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 *pkey,
3501ac5a404SSelvin Xavier 			bool update)
3511ac5a404SSelvin Xavier {
3521ac5a404SSelvin Xavier 	int i, free_idx, rc = 0;
3531ac5a404SSelvin Xavier 
3541ac5a404SSelvin Xavier 	if (!pkey_tbl) {
3551ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev, "QPLIB: PKEY table not allocated");
3561ac5a404SSelvin Xavier 		return -EINVAL;
3571ac5a404SSelvin Xavier 	}
3581ac5a404SSelvin Xavier 
3591ac5a404SSelvin Xavier 	/* Do we need a pkey_lock here? */
3601ac5a404SSelvin Xavier 	if (pkey_tbl->active == pkey_tbl->max) {
3611ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev, "QPLIB: PKEY table is full");
3621ac5a404SSelvin Xavier 		return -ENOMEM;
3631ac5a404SSelvin Xavier 	}
3641ac5a404SSelvin Xavier 	free_idx = pkey_tbl->max;
3651ac5a404SSelvin Xavier 	for (i = 0; i < pkey_tbl->max; i++) {
3661ac5a404SSelvin Xavier 		if (!memcmp(&pkey_tbl->tbl[i], pkey, sizeof(*pkey)))
3671ac5a404SSelvin Xavier 			return -EALREADY;
3681ac5a404SSelvin Xavier 		else if (!pkey_tbl->tbl[i] && free_idx == pkey_tbl->max)
3691ac5a404SSelvin Xavier 			free_idx = i;
3701ac5a404SSelvin Xavier 	}
3711ac5a404SSelvin Xavier 	if (free_idx == pkey_tbl->max) {
3721ac5a404SSelvin Xavier 		dev_err(&res->pdev->dev,
3731ac5a404SSelvin Xavier 			"QPLIB: PKEY table is FULL but count is not MAX??");
3741ac5a404SSelvin Xavier 		return -ENOMEM;
3751ac5a404SSelvin Xavier 	}
3761ac5a404SSelvin Xavier 	/* Add PKEY to the pkey_tbl */
3771ac5a404SSelvin Xavier 	memcpy(&pkey_tbl->tbl[free_idx], pkey, sizeof(*pkey));
3781ac5a404SSelvin Xavier 	pkey_tbl->active++;
3791ac5a404SSelvin Xavier 
3801ac5a404SSelvin Xavier 	/* unlock */
3811ac5a404SSelvin Xavier 	return rc;
3821ac5a404SSelvin Xavier }
3831ac5a404SSelvin Xavier 
3841ac5a404SSelvin Xavier /* AH */
3851ac5a404SSelvin Xavier int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
3861ac5a404SSelvin Xavier {
3871ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
3881ac5a404SSelvin Xavier 	struct cmdq_create_ah req;
389cc1ec769SDevesh Sharma 	struct creq_create_ah_resp resp;
3901ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
3911ac5a404SSelvin Xavier 	u32 temp32[4];
3921ac5a404SSelvin Xavier 	u16 temp16[3];
393cc1ec769SDevesh Sharma 	int rc;
3941ac5a404SSelvin Xavier 
3951ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, CREATE_AH, cmd_flags);
3961ac5a404SSelvin Xavier 
3971ac5a404SSelvin Xavier 	memcpy(temp32, ah->dgid.data, sizeof(struct bnxt_qplib_gid));
3981ac5a404SSelvin Xavier 	req.dgid[0] = cpu_to_le32(temp32[0]);
3991ac5a404SSelvin Xavier 	req.dgid[1] = cpu_to_le32(temp32[1]);
4001ac5a404SSelvin Xavier 	req.dgid[2] = cpu_to_le32(temp32[2]);
4011ac5a404SSelvin Xavier 	req.dgid[3] = cpu_to_le32(temp32[3]);
4021ac5a404SSelvin Xavier 
4031ac5a404SSelvin Xavier 	req.type = ah->nw_type;
4041ac5a404SSelvin Xavier 	req.hop_limit = ah->hop_limit;
4051ac5a404SSelvin Xavier 	req.sgid_index = cpu_to_le16(res->sgid_tbl.hw_id[ah->sgid_index]);
4061ac5a404SSelvin Xavier 	req.dest_vlan_id_flow_label = cpu_to_le32((ah->flow_label &
4071ac5a404SSelvin Xavier 					CMDQ_CREATE_AH_FLOW_LABEL_MASK) |
4081ac5a404SSelvin Xavier 					CMDQ_CREATE_AH_DEST_VLAN_ID_MASK);
4091ac5a404SSelvin Xavier 	req.pd_id = cpu_to_le32(ah->pd->id);
4101ac5a404SSelvin Xavier 	req.traffic_class = ah->traffic_class;
4111ac5a404SSelvin Xavier 
4121ac5a404SSelvin Xavier 	/* MAC in network format */
4131ac5a404SSelvin Xavier 	memcpy(temp16, ah->dmac, 6);
4141ac5a404SSelvin Xavier 	req.dest_mac[0] = cpu_to_le16(temp16[0]);
4151ac5a404SSelvin Xavier 	req.dest_mac[1] = cpu_to_le16(temp16[1]);
4161ac5a404SSelvin Xavier 	req.dest_mac[2] = cpu_to_le16(temp16[2]);
4171ac5a404SSelvin Xavier 
418cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
4191ac5a404SSelvin Xavier 					  NULL, 1);
420cc1ec769SDevesh Sharma 	if (rc)
421cc1ec769SDevesh Sharma 		return rc;
422cc1ec769SDevesh Sharma 
423cc1ec769SDevesh Sharma 	ah->id = le32_to_cpu(resp.xid);
4241ac5a404SSelvin Xavier 	return 0;
4251ac5a404SSelvin Xavier }
4261ac5a404SSelvin Xavier 
4271ac5a404SSelvin Xavier int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
4281ac5a404SSelvin Xavier {
4291ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
4301ac5a404SSelvin Xavier 	struct cmdq_destroy_ah req;
431cc1ec769SDevesh Sharma 	struct creq_destroy_ah_resp resp;
4321ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
433cc1ec769SDevesh Sharma 	int rc;
4341ac5a404SSelvin Xavier 
4351ac5a404SSelvin Xavier 	/* Clean up the AH table in the device */
4361ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, DESTROY_AH, cmd_flags);
4371ac5a404SSelvin Xavier 
4381ac5a404SSelvin Xavier 	req.ah_cid = cpu_to_le32(ah->id);
4391ac5a404SSelvin Xavier 
440cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
4411ac5a404SSelvin Xavier 					  NULL, 1);
442cc1ec769SDevesh Sharma 	if (rc)
443cc1ec769SDevesh Sharma 		return rc;
4441ac5a404SSelvin Xavier 	return 0;
4451ac5a404SSelvin Xavier }
4461ac5a404SSelvin Xavier 
4471ac5a404SSelvin Xavier /* MRW */
4481ac5a404SSelvin Xavier int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
4491ac5a404SSelvin Xavier {
4501ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
4511ac5a404SSelvin Xavier 	struct cmdq_deallocate_key req;
452cc1ec769SDevesh Sharma 	struct creq_deallocate_key_resp resp;
4531ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
454cc1ec769SDevesh Sharma 	int rc;
4551ac5a404SSelvin Xavier 
4561ac5a404SSelvin Xavier 	if (mrw->lkey == 0xFFFFFFFF) {
4571ac5a404SSelvin Xavier 		dev_info(&res->pdev->dev,
4581ac5a404SSelvin Xavier 			 "QPLIB: SP: Free a reserved lkey MRW");
4591ac5a404SSelvin Xavier 		return 0;
4601ac5a404SSelvin Xavier 	}
4611ac5a404SSelvin Xavier 
4621ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, DEALLOCATE_KEY, cmd_flags);
4631ac5a404SSelvin Xavier 
4641ac5a404SSelvin Xavier 	req.mrw_flags = mrw->type;
4651ac5a404SSelvin Xavier 
4661ac5a404SSelvin Xavier 	if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1)  ||
4671ac5a404SSelvin Xavier 	    (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A) ||
4681ac5a404SSelvin Xavier 	    (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B))
4691ac5a404SSelvin Xavier 		req.key = cpu_to_le32(mrw->rkey);
4701ac5a404SSelvin Xavier 	else
4711ac5a404SSelvin Xavier 		req.key = cpu_to_le32(mrw->lkey);
4721ac5a404SSelvin Xavier 
473cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
4741ac5a404SSelvin Xavier 					  NULL, 0);
475cc1ec769SDevesh Sharma 	if (rc)
476cc1ec769SDevesh Sharma 		return rc;
477cc1ec769SDevesh Sharma 
4781ac5a404SSelvin Xavier 	/* Free the qplib's MRW memory */
4791ac5a404SSelvin Xavier 	if (mrw->hwq.max_elements)
4801ac5a404SSelvin Xavier 		bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
4811ac5a404SSelvin Xavier 
4821ac5a404SSelvin Xavier 	return 0;
4831ac5a404SSelvin Xavier }
4841ac5a404SSelvin Xavier 
4851ac5a404SSelvin Xavier int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
4861ac5a404SSelvin Xavier {
4871ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
4881ac5a404SSelvin Xavier 	struct cmdq_allocate_mrw req;
489cc1ec769SDevesh Sharma 	struct creq_allocate_mrw_resp resp;
4901ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
4911ac5a404SSelvin Xavier 	unsigned long tmp;
492cc1ec769SDevesh Sharma 	int rc;
4931ac5a404SSelvin Xavier 
4941ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, ALLOCATE_MRW, cmd_flags);
4951ac5a404SSelvin Xavier 
4961ac5a404SSelvin Xavier 	req.pd_id = cpu_to_le32(mrw->pd->id);
4971ac5a404SSelvin Xavier 	req.mrw_flags = mrw->type;
4981ac5a404SSelvin Xavier 	if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR &&
4991ac5a404SSelvin Xavier 	     mrw->flags & BNXT_QPLIB_FR_PMR) ||
5001ac5a404SSelvin Xavier 	    mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A ||
5011ac5a404SSelvin Xavier 	    mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B)
5021ac5a404SSelvin Xavier 		req.access = CMDQ_ALLOCATE_MRW_ACCESS_CONSUMER_OWNED_KEY;
5031ac5a404SSelvin Xavier 	tmp = (unsigned long)mrw;
5041ac5a404SSelvin Xavier 	req.mrw_handle = cpu_to_le64(tmp);
5051ac5a404SSelvin Xavier 
506cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
507cc1ec769SDevesh Sharma 					  (void *)&resp, NULL, 0);
508cc1ec769SDevesh Sharma 	if (rc)
509cc1ec769SDevesh Sharma 		return rc;
510cc1ec769SDevesh Sharma 
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))
514cc1ec769SDevesh Sharma 		mrw->rkey = le32_to_cpu(resp.xid);
5151ac5a404SSelvin Xavier 	else
516cc1ec769SDevesh Sharma 		mrw->lkey = le32_to_cpu(resp.xid);
5171ac5a404SSelvin Xavier 	return 0;
5181ac5a404SSelvin Xavier }
5191ac5a404SSelvin Xavier 
5201ac5a404SSelvin Xavier int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
5211ac5a404SSelvin Xavier 			 bool block)
5221ac5a404SSelvin Xavier {
5231ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
5241ac5a404SSelvin Xavier 	struct cmdq_deregister_mr req;
525cc1ec769SDevesh Sharma 	struct creq_deregister_mr_resp resp;
5261ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
5271ac5a404SSelvin Xavier 	int rc;
5281ac5a404SSelvin Xavier 
5291ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, DEREGISTER_MR, cmd_flags);
5301ac5a404SSelvin Xavier 
5311ac5a404SSelvin Xavier 	req.lkey = cpu_to_le32(mrw->lkey);
532cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
533cc1ec769SDevesh Sharma 					  (void *)&resp, NULL, block);
534cc1ec769SDevesh Sharma 	if (rc)
535cc1ec769SDevesh Sharma 		return rc;
5361ac5a404SSelvin Xavier 
5371ac5a404SSelvin Xavier 	/* Free the qplib's MR memory */
5381ac5a404SSelvin Xavier 	if (mrw->hwq.max_elements) {
5391ac5a404SSelvin Xavier 		mrw->va = 0;
5401ac5a404SSelvin Xavier 		mrw->total_size = 0;
5411ac5a404SSelvin Xavier 		bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
5421ac5a404SSelvin Xavier 	}
5431ac5a404SSelvin Xavier 
5441ac5a404SSelvin Xavier 	return 0;
5451ac5a404SSelvin Xavier }
5461ac5a404SSelvin Xavier 
5471ac5a404SSelvin Xavier int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
5481ac5a404SSelvin Xavier 		      u64 *pbl_tbl, int num_pbls, bool block)
5491ac5a404SSelvin Xavier {
5501ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
5511ac5a404SSelvin Xavier 	struct cmdq_register_mr req;
552cc1ec769SDevesh Sharma 	struct creq_register_mr_resp resp;
5531ac5a404SSelvin Xavier 	u16 cmd_flags = 0, level;
5541ac5a404SSelvin Xavier 	int pg_ptrs, pages, i, rc;
5551ac5a404SSelvin Xavier 	dma_addr_t **pbl_ptr;
5561ac5a404SSelvin Xavier 	u32 pg_size;
5571ac5a404SSelvin Xavier 
5581ac5a404SSelvin Xavier 	if (num_pbls) {
5591ac5a404SSelvin Xavier 		pg_ptrs = roundup_pow_of_two(num_pbls);
5601ac5a404SSelvin Xavier 		pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
5611ac5a404SSelvin Xavier 		if (!pages)
5621ac5a404SSelvin Xavier 			pages++;
5631ac5a404SSelvin Xavier 
5641ac5a404SSelvin Xavier 		if (pages > MAX_PBL_LVL_1_PGS) {
5651ac5a404SSelvin Xavier 			dev_err(&res->pdev->dev, "QPLIB: SP: Reg MR pages ");
5661ac5a404SSelvin Xavier 			dev_err(&res->pdev->dev,
5671ac5a404SSelvin Xavier 				"requested (0x%x) exceeded max (0x%x)",
5681ac5a404SSelvin Xavier 				pages, MAX_PBL_LVL_1_PGS);
5691ac5a404SSelvin Xavier 			return -ENOMEM;
5701ac5a404SSelvin Xavier 		}
5711ac5a404SSelvin Xavier 		/* Free the hwq if it already exist, must be a rereg */
5721ac5a404SSelvin Xavier 		if (mr->hwq.max_elements)
5731ac5a404SSelvin Xavier 			bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
5741ac5a404SSelvin Xavier 
5751ac5a404SSelvin Xavier 		mr->hwq.max_elements = pages;
5761ac5a404SSelvin Xavier 		rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL, 0,
5771ac5a404SSelvin Xavier 					       &mr->hwq.max_elements,
5781ac5a404SSelvin Xavier 					       PAGE_SIZE, 0, PAGE_SIZE,
5791ac5a404SSelvin Xavier 					       HWQ_TYPE_CTX);
5801ac5a404SSelvin Xavier 		if (rc) {
5811ac5a404SSelvin Xavier 			dev_err(&res->pdev->dev,
5821ac5a404SSelvin Xavier 				"SP: Reg MR memory allocation failed");
5831ac5a404SSelvin Xavier 			return -ENOMEM;
5841ac5a404SSelvin Xavier 		}
5851ac5a404SSelvin Xavier 		/* Write to the hwq */
5861ac5a404SSelvin Xavier 		pbl_ptr = (dma_addr_t **)mr->hwq.pbl_ptr;
5871ac5a404SSelvin Xavier 		for (i = 0; i < num_pbls; i++)
5881ac5a404SSelvin Xavier 			pbl_ptr[PTR_PG(i)][PTR_IDX(i)] =
5891ac5a404SSelvin Xavier 				(pbl_tbl[i] & PAGE_MASK) | PTU_PTE_VALID;
5901ac5a404SSelvin Xavier 	}
5911ac5a404SSelvin Xavier 
5921ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, REGISTER_MR, cmd_flags);
5931ac5a404SSelvin Xavier 
5941ac5a404SSelvin Xavier 	/* Configure the request */
5951ac5a404SSelvin Xavier 	if (mr->hwq.level == PBL_LVL_MAX) {
5961ac5a404SSelvin Xavier 		level = 0;
5971ac5a404SSelvin Xavier 		req.pbl = 0;
5981ac5a404SSelvin Xavier 		pg_size = PAGE_SIZE;
5991ac5a404SSelvin Xavier 	} else {
6001ac5a404SSelvin Xavier 		level = mr->hwq.level + 1;
6011ac5a404SSelvin Xavier 		req.pbl = cpu_to_le64(mr->hwq.pbl[PBL_LVL_0].pg_map_arr[0]);
6021ac5a404SSelvin Xavier 		pg_size = mr->hwq.pbl[PBL_LVL_0].pg_size;
6031ac5a404SSelvin Xavier 	}
6041ac5a404SSelvin Xavier 	req.log2_pg_size_lvl = (level << CMDQ_REGISTER_MR_LVL_SFT) |
6051ac5a404SSelvin Xavier 			       ((ilog2(pg_size) <<
6061ac5a404SSelvin Xavier 				 CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT) &
6071ac5a404SSelvin Xavier 				CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK);
6081ac5a404SSelvin Xavier 	req.access = (mr->flags & 0xFFFF);
6091ac5a404SSelvin Xavier 	req.va = cpu_to_le64(mr->va);
6101ac5a404SSelvin Xavier 	req.key = cpu_to_le32(mr->lkey);
6111ac5a404SSelvin Xavier 	req.mr_size = cpu_to_le64(mr->total_size);
6121ac5a404SSelvin Xavier 
613cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
614cc1ec769SDevesh Sharma 					  (void *)&resp, NULL, block);
615cc1ec769SDevesh Sharma 	if (rc)
6161ac5a404SSelvin Xavier 		goto fail;
617cc1ec769SDevesh Sharma 
6181ac5a404SSelvin Xavier 	return 0;
6191ac5a404SSelvin Xavier 
6201ac5a404SSelvin Xavier fail:
6211ac5a404SSelvin Xavier 	if (mr->hwq.max_elements)
6221ac5a404SSelvin Xavier 		bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
6231ac5a404SSelvin Xavier 	return rc;
6241ac5a404SSelvin Xavier }
6251ac5a404SSelvin Xavier 
6261ac5a404SSelvin Xavier int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
6271ac5a404SSelvin Xavier 					struct bnxt_qplib_frpl *frpl,
6281ac5a404SSelvin Xavier 					int max_pg_ptrs)
6291ac5a404SSelvin Xavier {
6301ac5a404SSelvin Xavier 	int pg_ptrs, pages, rc;
6311ac5a404SSelvin Xavier 
6321ac5a404SSelvin Xavier 	/* Re-calculate the max to fit the HWQ allocation model */
6331ac5a404SSelvin Xavier 	pg_ptrs = roundup_pow_of_two(max_pg_ptrs);
6341ac5a404SSelvin Xavier 	pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
6351ac5a404SSelvin Xavier 	if (!pages)
6361ac5a404SSelvin Xavier 		pages++;
6371ac5a404SSelvin Xavier 
6381ac5a404SSelvin Xavier 	if (pages > MAX_PBL_LVL_1_PGS)
6391ac5a404SSelvin Xavier 		return -ENOMEM;
6401ac5a404SSelvin Xavier 
6411ac5a404SSelvin Xavier 	frpl->hwq.max_elements = pages;
6421ac5a404SSelvin Xavier 	rc = bnxt_qplib_alloc_init_hwq(res->pdev, &frpl->hwq, NULL, 0,
6431ac5a404SSelvin Xavier 				       &frpl->hwq.max_elements, PAGE_SIZE, 0,
6441ac5a404SSelvin Xavier 				       PAGE_SIZE, HWQ_TYPE_CTX);
6451ac5a404SSelvin Xavier 	if (!rc)
6461ac5a404SSelvin Xavier 		frpl->max_pg_ptrs = pg_ptrs;
6471ac5a404SSelvin Xavier 
6481ac5a404SSelvin Xavier 	return rc;
6491ac5a404SSelvin Xavier }
6501ac5a404SSelvin Xavier 
6511ac5a404SSelvin Xavier int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res,
6521ac5a404SSelvin Xavier 				       struct bnxt_qplib_frpl *frpl)
6531ac5a404SSelvin Xavier {
6541ac5a404SSelvin Xavier 	bnxt_qplib_free_hwq(res->pdev, &frpl->hwq);
6551ac5a404SSelvin Xavier 	return 0;
6561ac5a404SSelvin Xavier }
6571ac5a404SSelvin Xavier 
6581ac5a404SSelvin Xavier int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res *res, u16 *cids)
6591ac5a404SSelvin Xavier {
6601ac5a404SSelvin Xavier 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
6611ac5a404SSelvin Xavier 	struct cmdq_map_tc_to_cos req;
662cc1ec769SDevesh Sharma 	struct creq_map_tc_to_cos_resp resp;
6631ac5a404SSelvin Xavier 	u16 cmd_flags = 0;
664cc1ec769SDevesh Sharma 	int rc = 0;
6651ac5a404SSelvin Xavier 
6661ac5a404SSelvin Xavier 	RCFW_CMD_PREP(req, MAP_TC_TO_COS, cmd_flags);
6671ac5a404SSelvin Xavier 	req.cos0 = cpu_to_le16(cids[0]);
6681ac5a404SSelvin Xavier 	req.cos1 = cpu_to_le16(cids[1]);
6691ac5a404SSelvin Xavier 
670cc1ec769SDevesh Sharma 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
671cc1ec769SDevesh Sharma 					  (void *)&resp, NULL, 0);
6721ac5a404SSelvin Xavier 	return 0;
6731ac5a404SSelvin Xavier }
674