xref: /openbmc/linux/drivers/net/ethernet/qlogic/qed/qed_rdma.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
11f4d4ed6SAlexander Lobakin // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2f1372ee1SKalderon, Michal /* QLogic qed NIC Driver
3f1372ee1SKalderon, Michal  * Copyright (c) 2015-2017  QLogic Corporation
4663eacd8SAlexander Lobakin  * Copyright (c) 2019-2020 Marvell International Ltd.
5f1372ee1SKalderon, Michal  */
61f4d4ed6SAlexander Lobakin 
7f1372ee1SKalderon, Michal #include <linux/types.h>
8f1372ee1SKalderon, Michal #include <asm/byteorder.h>
9f1372ee1SKalderon, Michal #include <linux/bitops.h>
10f1372ee1SKalderon, Michal #include <linux/delay.h>
11f1372ee1SKalderon, Michal #include <linux/dma-mapping.h>
12f1372ee1SKalderon, Michal #include <linux/errno.h>
13f1372ee1SKalderon, Michal #include <linux/io.h>
14f1372ee1SKalderon, Michal #include <linux/kernel.h>
15f1372ee1SKalderon, Michal #include <linux/list.h>
16f1372ee1SKalderon, Michal #include <linux/module.h>
17f1372ee1SKalderon, Michal #include <linux/mutex.h>
18f1372ee1SKalderon, Michal #include <linux/pci.h>
19f1372ee1SKalderon, Michal #include <linux/slab.h>
20f1372ee1SKalderon, Michal #include <linux/spinlock.h>
21f1372ee1SKalderon, Michal #include <linux/string.h>
224e446714SKamal Heib #include <net/addrconf.h>
23f1372ee1SKalderon, Michal #include "qed.h"
24f1372ee1SKalderon, Michal #include "qed_cxt.h"
25f1372ee1SKalderon, Michal #include "qed_hsi.h"
26ee824f4bSOmkar Kulkarni #include "qed_iro_hsi.h"
27f1372ee1SKalderon, Michal #include "qed_hw.h"
28f1372ee1SKalderon, Michal #include "qed_init_ops.h"
29f1372ee1SKalderon, Michal #include "qed_int.h"
30f1372ee1SKalderon, Michal #include "qed_ll2.h"
31f1372ee1SKalderon, Michal #include "qed_mcp.h"
32f1372ee1SKalderon, Michal #include "qed_reg_addr.h"
337003cdd6SKalderon, Michal #include <linux/qed/qed_rdma_if.h>
34b71b9afdSKalderon, Michal #include "qed_rdma.h"
35b71b9afdSKalderon, Michal #include "qed_roce.h"
36f1372ee1SKalderon, Michal #include "qed_sp.h"
37f1372ee1SKalderon, Michal 
qed_rdma_bmap_alloc(struct qed_hwfn * p_hwfn,struct qed_bmap * bmap,u32 max_count,char * name)38b71b9afdSKalderon, Michal int qed_rdma_bmap_alloc(struct qed_hwfn *p_hwfn,
39f1372ee1SKalderon, Michal 			struct qed_bmap *bmap, u32 max_count, char *name)
40f1372ee1SKalderon, Michal {
41f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "max_count = %08x\n", max_count);
42f1372ee1SKalderon, Michal 
43f1372ee1SKalderon, Michal 	bmap->max_count = max_count;
44f1372ee1SKalderon, Michal 
45291dbea1SChristophe JAILLET 	bmap->bitmap = bitmap_zalloc(max_count, GFP_KERNEL);
46f1372ee1SKalderon, Michal 	if (!bmap->bitmap)
47f1372ee1SKalderon, Michal 		return -ENOMEM;
48f1372ee1SKalderon, Michal 
49f1372ee1SKalderon, Michal 	snprintf(bmap->name, QED_RDMA_MAX_BMAP_NAME, "%s", name);
50f1372ee1SKalderon, Michal 
51f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "0\n");
52f1372ee1SKalderon, Michal 	return 0;
53f1372ee1SKalderon, Michal }
54f1372ee1SKalderon, Michal 
qed_rdma_bmap_alloc_id(struct qed_hwfn * p_hwfn,struct qed_bmap * bmap,u32 * id_num)55b71b9afdSKalderon, Michal int qed_rdma_bmap_alloc_id(struct qed_hwfn *p_hwfn,
56f1372ee1SKalderon, Michal 			   struct qed_bmap *bmap, u32 *id_num)
57f1372ee1SKalderon, Michal {
58f1372ee1SKalderon, Michal 	*id_num = find_first_zero_bit(bmap->bitmap, bmap->max_count);
59f1372ee1SKalderon, Michal 	if (*id_num >= bmap->max_count)
60f1372ee1SKalderon, Michal 		return -EINVAL;
61f1372ee1SKalderon, Michal 
62f1372ee1SKalderon, Michal 	__set_bit(*id_num, bmap->bitmap);
63f1372ee1SKalderon, Michal 
64f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "%s bitmap: allocated id %d\n",
65f1372ee1SKalderon, Michal 		   bmap->name, *id_num);
66f1372ee1SKalderon, Michal 
67f1372ee1SKalderon, Michal 	return 0;
68f1372ee1SKalderon, Michal }
69f1372ee1SKalderon, Michal 
qed_bmap_set_id(struct qed_hwfn * p_hwfn,struct qed_bmap * bmap,u32 id_num)70b71b9afdSKalderon, Michal void qed_bmap_set_id(struct qed_hwfn *p_hwfn,
71f1372ee1SKalderon, Michal 		     struct qed_bmap *bmap, u32 id_num)
72f1372ee1SKalderon, Michal {
73f1372ee1SKalderon, Michal 	if (id_num >= bmap->max_count)
74f1372ee1SKalderon, Michal 		return;
75f1372ee1SKalderon, Michal 
76f1372ee1SKalderon, Michal 	__set_bit(id_num, bmap->bitmap);
77f1372ee1SKalderon, Michal }
78f1372ee1SKalderon, Michal 
qed_bmap_release_id(struct qed_hwfn * p_hwfn,struct qed_bmap * bmap,u32 id_num)79b71b9afdSKalderon, Michal void qed_bmap_release_id(struct qed_hwfn *p_hwfn,
80f1372ee1SKalderon, Michal 			 struct qed_bmap *bmap, u32 id_num)
81f1372ee1SKalderon, Michal {
82f1372ee1SKalderon, Michal 	bool b_acquired;
83f1372ee1SKalderon, Michal 
84f1372ee1SKalderon, Michal 	if (id_num >= bmap->max_count)
85f1372ee1SKalderon, Michal 		return;
86f1372ee1SKalderon, Michal 
87f1372ee1SKalderon, Michal 	b_acquired = test_and_clear_bit(id_num, bmap->bitmap);
88f1372ee1SKalderon, Michal 	if (!b_acquired) {
89f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn, "%s bitmap: id %d already released\n",
90f1372ee1SKalderon, Michal 			  bmap->name, id_num);
91f1372ee1SKalderon, Michal 		return;
92f1372ee1SKalderon, Michal 	}
93f1372ee1SKalderon, Michal 
94f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "%s bitmap: released id %d\n",
95f1372ee1SKalderon, Michal 		   bmap->name, id_num);
96f1372ee1SKalderon, Michal }
97f1372ee1SKalderon, Michal 
qed_bmap_test_id(struct qed_hwfn * p_hwfn,struct qed_bmap * bmap,u32 id_num)98b71b9afdSKalderon, Michal int qed_bmap_test_id(struct qed_hwfn *p_hwfn,
99f1372ee1SKalderon, Michal 		     struct qed_bmap *bmap, u32 id_num)
100f1372ee1SKalderon, Michal {
101f1372ee1SKalderon, Michal 	if (id_num >= bmap->max_count)
102f1372ee1SKalderon, Michal 		return -1;
103f1372ee1SKalderon, Michal 
104f1372ee1SKalderon, Michal 	return test_bit(id_num, bmap->bitmap);
105f1372ee1SKalderon, Michal }
106f1372ee1SKalderon, Michal 
qed_bmap_is_empty(struct qed_bmap * bmap)107f1372ee1SKalderon, Michal static bool qed_bmap_is_empty(struct qed_bmap *bmap)
108f1372ee1SKalderon, Michal {
109*7ed5f245SChristophe JAILLET 	return bitmap_empty(bmap->bitmap, bmap->max_count);
110f1372ee1SKalderon, Michal }
111f1372ee1SKalderon, Michal 
qed_rdma_get_sb_id(void * p_hwfn,u32 rel_sb_id)112bf774d14SYueHaibing static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id)
113f1372ee1SKalderon, Michal {
114f1372ee1SKalderon, Michal 	/* First sb id for RoCE is after all the l2 sb */
115f1372ee1SKalderon, Michal 	return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id;
116f1372ee1SKalderon, Michal }
117f1372ee1SKalderon, Michal 
qed_rdma_info_alloc(struct qed_hwfn * p_hwfn)118291d57f6SMichal Kalderon int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn)
119f1372ee1SKalderon, Michal {
120f1372ee1SKalderon, Michal 	struct qed_rdma_info *p_rdma_info;
121291d57f6SMichal Kalderon 
122291d57f6SMichal Kalderon 	p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL);
123291d57f6SMichal Kalderon 	if (!p_rdma_info)
124291d57f6SMichal Kalderon 		return -ENOMEM;
125291d57f6SMichal Kalderon 
126291d57f6SMichal Kalderon 	spin_lock_init(&p_rdma_info->lock);
127291d57f6SMichal Kalderon 
128291d57f6SMichal Kalderon 	p_hwfn->p_rdma_info = p_rdma_info;
129291d57f6SMichal Kalderon 	return 0;
130291d57f6SMichal Kalderon }
131291d57f6SMichal Kalderon 
qed_rdma_info_free(struct qed_hwfn * p_hwfn)132291d57f6SMichal Kalderon void qed_rdma_info_free(struct qed_hwfn *p_hwfn)
133291d57f6SMichal Kalderon {
134291d57f6SMichal Kalderon 	kfree(p_hwfn->p_rdma_info);
135291d57f6SMichal Kalderon 	p_hwfn->p_rdma_info = NULL;
136291d57f6SMichal Kalderon }
137291d57f6SMichal Kalderon 
qed_rdma_alloc(struct qed_hwfn * p_hwfn)138291d57f6SMichal Kalderon static int qed_rdma_alloc(struct qed_hwfn *p_hwfn)
139291d57f6SMichal Kalderon {
140291d57f6SMichal Kalderon 	struct qed_rdma_info *p_rdma_info = p_hwfn->p_rdma_info;
141f1372ee1SKalderon, Michal 	u32 num_cons, num_tasks;
142f1372ee1SKalderon, Michal 	int rc = -ENOMEM;
143f1372ee1SKalderon, Michal 
144f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n");
145f1372ee1SKalderon, Michal 
146e0a8f9deSMichal Kalderon 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
147e0a8f9deSMichal Kalderon 		p_rdma_info->proto = PROTOCOLID_IWARP;
148e0a8f9deSMichal Kalderon 	else
149f1372ee1SKalderon, Michal 		p_rdma_info->proto = PROTOCOLID_ROCE;
150f1372ee1SKalderon, Michal 
151f1372ee1SKalderon, Michal 	num_cons = qed_cxt_get_proto_cid_count(p_hwfn, p_rdma_info->proto,
152f1372ee1SKalderon, Michal 					       NULL);
153f1372ee1SKalderon, Michal 
15467b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
15567b40dccSKalderon, Michal 		p_rdma_info->num_qps = num_cons;
15667b40dccSKalderon, Michal 	else
15767b40dccSKalderon, Michal 		p_rdma_info->num_qps = num_cons / 2; /* 2 cids per qp */
158f1372ee1SKalderon, Michal 
159f1372ee1SKalderon, Michal 	num_tasks = qed_cxt_get_proto_tid_count(p_hwfn, PROTOCOLID_ROCE);
160f1372ee1SKalderon, Michal 
161f1372ee1SKalderon, Michal 	/* Each MR uses a single task */
162f1372ee1SKalderon, Michal 	p_rdma_info->num_mrs = num_tasks;
163f1372ee1SKalderon, Michal 
164f1372ee1SKalderon, Michal 	/* Queue zone lines are shared between RoCE and L2 in such a way that
165f1372ee1SKalderon, Michal 	 * they can be used by each without obstructing the other.
166f1372ee1SKalderon, Michal 	 */
167f1372ee1SKalderon, Michal 	p_rdma_info->queue_zone_base = (u16)RESC_START(p_hwfn, QED_L2_QUEUE);
168f1372ee1SKalderon, Michal 	p_rdma_info->max_queue_zones = (u16)RESC_NUM(p_hwfn, QED_L2_QUEUE);
169f1372ee1SKalderon, Michal 
170f1372ee1SKalderon, Michal 	/* Allocate a struct with device params and fill it */
171f1372ee1SKalderon, Michal 	p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL);
172f1372ee1SKalderon, Michal 	if (!p_rdma_info->dev)
173291d57f6SMichal Kalderon 		return rc;
174f1372ee1SKalderon, Michal 
175f1372ee1SKalderon, Michal 	/* Allocate a struct with port params and fill it */
176f1372ee1SKalderon, Michal 	p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL);
177f1372ee1SKalderon, Michal 	if (!p_rdma_info->port)
178f1372ee1SKalderon, Michal 		goto free_rdma_dev;
179f1372ee1SKalderon, Michal 
180f1372ee1SKalderon, Michal 	/* Allocate bit map for pd's */
181f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->pd_map, RDMA_MAX_PDS,
182f1372ee1SKalderon, Michal 				 "PD");
183f1372ee1SKalderon, Michal 	if (rc) {
184f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
185f1372ee1SKalderon, Michal 			   "Failed to allocate pd_map, rc = %d\n",
186f1372ee1SKalderon, Michal 			   rc);
187f1372ee1SKalderon, Michal 		goto free_rdma_port;
188f1372ee1SKalderon, Michal 	}
189f1372ee1SKalderon, Michal 
1907bfb399eSYuval Basson 	/* Allocate bit map for XRC Domains */
1917bfb399eSYuval Basson 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->xrcd_map,
1927bfb399eSYuval Basson 				 QED_RDMA_MAX_XRCDS, "XRCD");
1937bfb399eSYuval Basson 	if (rc) {
1947bfb399eSYuval Basson 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1957bfb399eSYuval Basson 			   "Failed to allocate xrcd_map,rc = %d\n", rc);
1967bfb399eSYuval Basson 		goto free_pd_map;
1977bfb399eSYuval Basson 	}
1987bfb399eSYuval Basson 
199f1372ee1SKalderon, Michal 	/* Allocate DPI bitmap */
200f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->dpi_map,
201f1372ee1SKalderon, Michal 				 p_hwfn->dpi_count, "DPI");
202f1372ee1SKalderon, Michal 	if (rc) {
203f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
204f1372ee1SKalderon, Michal 			   "Failed to allocate DPI bitmap, rc = %d\n", rc);
2057bfb399eSYuval Basson 		goto free_xrcd_map;
206f1372ee1SKalderon, Michal 	}
207f1372ee1SKalderon, Michal 
208471115abSMichal Kalderon 	/* Allocate bitmap for cq's. The maximum number of CQs is bound to
209471115abSMichal Kalderon 	 * the number of connections we support. (num_qps in iWARP or
210471115abSMichal Kalderon 	 * num_qps/2 in RoCE).
211f1372ee1SKalderon, Michal 	 */
212471115abSMichal Kalderon 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->cq_map, num_cons, "CQ");
213f1372ee1SKalderon, Michal 	if (rc) {
214f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
215f1372ee1SKalderon, Michal 			   "Failed to allocate cq bitmap, rc = %d\n", rc);
216f1372ee1SKalderon, Michal 		goto free_dpi_map;
217f1372ee1SKalderon, Michal 	}
218f1372ee1SKalderon, Michal 
219f1372ee1SKalderon, Michal 	/* Allocate bitmap for toggle bit for cq icids
220f1372ee1SKalderon, Michal 	 * We toggle the bit every time we create or resize cq for a given icid.
221471115abSMichal Kalderon 	 * Size needs to equal the size of the cq bmap.
222f1372ee1SKalderon, Michal 	 */
223f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->toggle_bits,
224471115abSMichal Kalderon 				 num_cons, "Toggle");
225f1372ee1SKalderon, Michal 	if (rc) {
226f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
2275a94df70SColin Ian King 			   "Failed to allocate toggle bits, rc = %d\n", rc);
228f1372ee1SKalderon, Michal 		goto free_cq_map;
229f1372ee1SKalderon, Michal 	}
230f1372ee1SKalderon, Michal 
231f1372ee1SKalderon, Michal 	/* Allocate bitmap for itids */
232f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->tid_map,
233f1372ee1SKalderon, Michal 				 p_rdma_info->num_mrs, "MR");
234f1372ee1SKalderon, Michal 	if (rc) {
235f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
236f1372ee1SKalderon, Michal 			   "Failed to allocate itids bitmaps, rc = %d\n", rc);
237f1372ee1SKalderon, Michal 		goto free_toggle_map;
238f1372ee1SKalderon, Michal 	}
239f1372ee1SKalderon, Michal 
240f1372ee1SKalderon, Michal 	/* Allocate bitmap for cids used for qps. */
241f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->cid_map, num_cons,
242f1372ee1SKalderon, Michal 				 "CID");
243f1372ee1SKalderon, Michal 	if (rc) {
244f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
245f1372ee1SKalderon, Michal 			   "Failed to allocate cid bitmap, rc = %d\n", rc);
246f1372ee1SKalderon, Michal 		goto free_tid_map;
247f1372ee1SKalderon, Michal 	}
248f1372ee1SKalderon, Michal 
249f1372ee1SKalderon, Michal 	/* Allocate bitmap for cids used for responders/requesters. */
250f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->real_cid_map, num_cons,
251f1372ee1SKalderon, Michal 				 "REAL_CID");
252f1372ee1SKalderon, Michal 	if (rc) {
253f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
254f1372ee1SKalderon, Michal 			   "Failed to allocate real cid bitmap, rc = %d\n", rc);
255f1372ee1SKalderon, Michal 		goto free_cid_map;
256f1372ee1SKalderon, Michal 	}
25767b40dccSKalderon, Michal 
2587bfb399eSYuval Basson 	/* The first SRQ follows the last XRC SRQ. This means that the
2597bfb399eSYuval Basson 	 * SRQ IDs start from an offset equals to max_xrc_srqs.
2607bfb399eSYuval Basson 	 */
2617bfb399eSYuval Basson 	p_rdma_info->srq_id_offset = p_hwfn->p_cxt_mngr->xrc_srq_count;
2627bfb399eSYuval Basson 	rc = qed_rdma_bmap_alloc(p_hwfn,
2637bfb399eSYuval Basson 				 &p_rdma_info->xrc_srq_map,
2647bfb399eSYuval Basson 				 p_hwfn->p_cxt_mngr->xrc_srq_count, "XRC SRQ");
2657bfb399eSYuval Basson 	if (rc) {
2667bfb399eSYuval Basson 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
2677bfb399eSYuval Basson 			   "Failed to allocate xrc srq bitmap, rc = %d\n", rc);
2687bfb399eSYuval Basson 		goto free_real_cid_map;
2697bfb399eSYuval Basson 	}
2707bfb399eSYuval Basson 
27139dbc646SYuval Bason 	/* Allocate bitmap for srqs */
272b8204ad8SYuval Basson 	p_rdma_info->num_srqs = p_hwfn->p_cxt_mngr->srq_count;
27339dbc646SYuval Bason 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->srq_map,
27439dbc646SYuval Bason 				 p_rdma_info->num_srqs, "SRQ");
27539dbc646SYuval Bason 	if (rc) {
27639dbc646SYuval Bason 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
27739dbc646SYuval Bason 			   "Failed to allocate srq bitmap, rc = %d\n", rc);
2787bfb399eSYuval Basson 		goto free_xrc_srq_map;
27939dbc646SYuval Bason 	}
28039dbc646SYuval Bason 
28167b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
28267b40dccSKalderon, Michal 		rc = qed_iwarp_alloc(p_hwfn);
28367b40dccSKalderon, Michal 
28467b40dccSKalderon, Michal 	if (rc)
28539dbc646SYuval Bason 		goto free_srq_map;
28667b40dccSKalderon, Michal 
287f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocation successful\n");
288f1372ee1SKalderon, Michal 	return 0;
289f1372ee1SKalderon, Michal 
29039dbc646SYuval Bason free_srq_map:
29139dbc646SYuval Bason 	kfree(p_rdma_info->srq_map.bitmap);
2927bfb399eSYuval Basson free_xrc_srq_map:
2937bfb399eSYuval Basson 	kfree(p_rdma_info->xrc_srq_map.bitmap);
29439dbc646SYuval Bason free_real_cid_map:
29539dbc646SYuval Bason 	kfree(p_rdma_info->real_cid_map.bitmap);
296f1372ee1SKalderon, Michal free_cid_map:
297f1372ee1SKalderon, Michal 	kfree(p_rdma_info->cid_map.bitmap);
298f1372ee1SKalderon, Michal free_tid_map:
299f1372ee1SKalderon, Michal 	kfree(p_rdma_info->tid_map.bitmap);
300f1372ee1SKalderon, Michal free_toggle_map:
301f1372ee1SKalderon, Michal 	kfree(p_rdma_info->toggle_bits.bitmap);
302f1372ee1SKalderon, Michal free_cq_map:
303f1372ee1SKalderon, Michal 	kfree(p_rdma_info->cq_map.bitmap);
304f1372ee1SKalderon, Michal free_dpi_map:
305f1372ee1SKalderon, Michal 	kfree(p_rdma_info->dpi_map.bitmap);
3067bfb399eSYuval Basson free_xrcd_map:
3077bfb399eSYuval Basson 	kfree(p_rdma_info->xrcd_map.bitmap);
308f1372ee1SKalderon, Michal free_pd_map:
309f1372ee1SKalderon, Michal 	kfree(p_rdma_info->pd_map.bitmap);
310f1372ee1SKalderon, Michal free_rdma_port:
311f1372ee1SKalderon, Michal 	kfree(p_rdma_info->port);
312f1372ee1SKalderon, Michal free_rdma_dev:
313f1372ee1SKalderon, Michal 	kfree(p_rdma_info->dev);
314f1372ee1SKalderon, Michal 
315f1372ee1SKalderon, Michal 	return rc;
316f1372ee1SKalderon, Michal }
317f1372ee1SKalderon, Michal 
qed_rdma_bmap_free(struct qed_hwfn * p_hwfn,struct qed_bmap * bmap,bool check)318b71b9afdSKalderon, Michal void qed_rdma_bmap_free(struct qed_hwfn *p_hwfn,
319f1372ee1SKalderon, Michal 			struct qed_bmap *bmap, bool check)
320f1372ee1SKalderon, Michal {
32164b87c1aSYury Norov 	unsigned int bit, weight, nbits;
32264b87c1aSYury Norov 	unsigned long *b;
323f1372ee1SKalderon, Michal 
32464b87c1aSYury Norov 	if (!check)
32564b87c1aSYury Norov 		goto end;
32664b87c1aSYury Norov 
32764b87c1aSYury Norov 	weight = bitmap_weight(bmap->bitmap, bmap->max_count);
32864b87c1aSYury Norov 	if (!weight)
329f1372ee1SKalderon, Michal 		goto end;
330f1372ee1SKalderon, Michal 
331f1372ee1SKalderon, Michal 	DP_NOTICE(p_hwfn,
332f1372ee1SKalderon, Michal 		  "%s bitmap not free - size=%d, weight=%d, 512 bits per line\n",
333f1372ee1SKalderon, Michal 		  bmap->name, bmap->max_count, weight);
334f1372ee1SKalderon, Michal 
33564b87c1aSYury Norov 	for (bit = 0; bit < bmap->max_count; bit += 512) {
33664b87c1aSYury Norov 		b =  bmap->bitmap + BITS_TO_LONGS(bit);
33764b87c1aSYury Norov 		nbits = min(bmap->max_count - bit, 512U);
338f1372ee1SKalderon, Michal 
33964b87c1aSYury Norov 		if (!bitmap_empty(b, nbits))
34064b87c1aSYury Norov 			DP_NOTICE(p_hwfn,
34164b87c1aSYury Norov 				  "line 0x%04x: %*pb\n", bit / 512, nbits, b);
342f1372ee1SKalderon, Michal 	}
343f1372ee1SKalderon, Michal 
344f1372ee1SKalderon, Michal end:
345291dbea1SChristophe JAILLET 	bitmap_free(bmap->bitmap);
346f1372ee1SKalderon, Michal 	bmap->bitmap = NULL;
347f1372ee1SKalderon, Michal }
348f1372ee1SKalderon, Michal 
qed_rdma_resc_free(struct qed_hwfn * p_hwfn)349f1372ee1SKalderon, Michal static void qed_rdma_resc_free(struct qed_hwfn *p_hwfn)
350f1372ee1SKalderon, Michal {
351f1372ee1SKalderon, Michal 	struct qed_rdma_info *p_rdma_info = p_hwfn->p_rdma_info;
352f1372ee1SKalderon, Michal 
35367b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
35467b40dccSKalderon, Michal 		qed_iwarp_resc_free(p_hwfn);
35567b40dccSKalderon, Michal 
356f1372ee1SKalderon, Michal 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->cid_map, 1);
357f1372ee1SKalderon, Michal 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->pd_map, 1);
358f1372ee1SKalderon, Michal 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->dpi_map, 1);
359f1372ee1SKalderon, Michal 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->cq_map, 1);
360f1372ee1SKalderon, Michal 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->toggle_bits, 0);
361f1372ee1SKalderon, Michal 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->tid_map, 1);
36239dbc646SYuval Bason 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->srq_map, 1);
36339dbc646SYuval Bason 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->real_cid_map, 1);
3647bfb399eSYuval Basson 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->xrc_srq_map, 1);
365d4eae993SYuval Basson 	qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->xrcd_map, 1);
366f1372ee1SKalderon, Michal 
367f1372ee1SKalderon, Michal 	kfree(p_rdma_info->port);
368f1372ee1SKalderon, Michal 	kfree(p_rdma_info->dev);
369f1372ee1SKalderon, Michal }
370f1372ee1SKalderon, Michal 
qed_rdma_free_tid(void * rdma_cxt,u32 itid)3711fe280a0SMichal Kalderon static void qed_rdma_free_tid(void *rdma_cxt, u32 itid)
3721fe280a0SMichal Kalderon {
3731fe280a0SMichal Kalderon 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
3741fe280a0SMichal Kalderon 
3751fe280a0SMichal Kalderon 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "itid = %08x\n", itid);
3761fe280a0SMichal Kalderon 
3771fe280a0SMichal Kalderon 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
3781fe280a0SMichal Kalderon 	qed_bmap_release_id(p_hwfn, &p_hwfn->p_rdma_info->tid_map, itid);
3791fe280a0SMichal Kalderon 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
3801fe280a0SMichal Kalderon }
3811fe280a0SMichal Kalderon 
qed_rdma_free_reserved_lkey(struct qed_hwfn * p_hwfn)3821fe280a0SMichal Kalderon static void qed_rdma_free_reserved_lkey(struct qed_hwfn *p_hwfn)
3831fe280a0SMichal Kalderon {
3841fe280a0SMichal Kalderon 	qed_rdma_free_tid(p_hwfn, p_hwfn->p_rdma_info->dev->reserved_lkey);
3851fe280a0SMichal Kalderon }
3861fe280a0SMichal Kalderon 
qed_rdma_free(struct qed_hwfn * p_hwfn)387f1372ee1SKalderon, Michal static void qed_rdma_free(struct qed_hwfn *p_hwfn)
388f1372ee1SKalderon, Michal {
389f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Freeing RDMA\n");
390f1372ee1SKalderon, Michal 
3911fe280a0SMichal Kalderon 	qed_rdma_free_reserved_lkey(p_hwfn);
3929de506a5SMichal Kalderon 	qed_cxt_free_proto_ilt(p_hwfn, p_hwfn->p_rdma_info->proto);
393f89782c2SDan Carpenter 	qed_rdma_resc_free(p_hwfn);
394f1372ee1SKalderon, Michal }
395f1372ee1SKalderon, Michal 
qed_rdma_init_events(struct qed_hwfn * p_hwfn,struct qed_rdma_start_in_params * params)396f1372ee1SKalderon, Michal static void qed_rdma_init_events(struct qed_hwfn *p_hwfn,
397f1372ee1SKalderon, Michal 				 struct qed_rdma_start_in_params *params)
398f1372ee1SKalderon, Michal {
399f1372ee1SKalderon, Michal 	struct qed_rdma_events *events;
400f1372ee1SKalderon, Michal 
401f1372ee1SKalderon, Michal 	events = &p_hwfn->p_rdma_info->events;
402f1372ee1SKalderon, Michal 
403f1372ee1SKalderon, Michal 	events->unaffiliated_event = params->events->unaffiliated_event;
404f1372ee1SKalderon, Michal 	events->affiliated_event = params->events->affiliated_event;
405f1372ee1SKalderon, Michal 	events->context = params->events->context;
406f1372ee1SKalderon, Michal }
407f1372ee1SKalderon, Michal 
qed_rdma_init_devinfo(struct qed_hwfn * p_hwfn,struct qed_rdma_start_in_params * params)408f1372ee1SKalderon, Michal static void qed_rdma_init_devinfo(struct qed_hwfn *p_hwfn,
409f1372ee1SKalderon, Michal 				  struct qed_rdma_start_in_params *params)
410f1372ee1SKalderon, Michal {
411f1372ee1SKalderon, Michal 	struct qed_rdma_device *dev = p_hwfn->p_rdma_info->dev;
412f1372ee1SKalderon, Michal 	struct qed_dev *cdev = p_hwfn->cdev;
413f1372ee1SKalderon, Michal 	u32 pci_status_control;
414f1372ee1SKalderon, Michal 	u32 num_qps;
415f1372ee1SKalderon, Michal 
416f1372ee1SKalderon, Michal 	/* Vendor specific information */
417f1372ee1SKalderon, Michal 	dev->vendor_id = cdev->vendor_id;
418f1372ee1SKalderon, Michal 	dev->vendor_part_id = cdev->device_id;
41981af04b4SMichal Kalderon 	dev->hw_ver = cdev->chip_rev;
420f1372ee1SKalderon, Michal 	dev->fw_ver = (FW_MAJOR_VERSION << 24) | (FW_MINOR_VERSION << 16) |
421f1372ee1SKalderon, Michal 		      (FW_REVISION_VERSION << 8) | (FW_ENGINEERING_VERSION);
422f1372ee1SKalderon, Michal 
4234e446714SKamal Heib 	addrconf_addr_eui48((u8 *)&dev->sys_image_guid,
4244e446714SKamal Heib 			    p_hwfn->hw_info.hw_mac_addr);
4254e446714SKamal Heib 
426f1372ee1SKalderon, Michal 	dev->node_guid = dev->sys_image_guid;
427f1372ee1SKalderon, Michal 
428f1372ee1SKalderon, Michal 	dev->max_sge = min_t(u32, RDMA_MAX_SGE_PER_SQ_WQE,
429f1372ee1SKalderon, Michal 			     RDMA_MAX_SGE_PER_RQ_WQE);
430f1372ee1SKalderon, Michal 
431f1372ee1SKalderon, Michal 	if (cdev->rdma_max_sge)
432f1372ee1SKalderon, Michal 		dev->max_sge = min_t(u32, cdev->rdma_max_sge, dev->max_sge);
433f1372ee1SKalderon, Michal 
43439dbc646SYuval Bason 	dev->max_srq_sge = QED_RDMA_MAX_SGE_PER_SRQ_WQE;
43539dbc646SYuval Bason 	if (p_hwfn->cdev->rdma_max_srq_sge) {
43639dbc646SYuval Bason 		dev->max_srq_sge = min_t(u32,
43739dbc646SYuval Bason 					 p_hwfn->cdev->rdma_max_srq_sge,
43839dbc646SYuval Bason 					 dev->max_srq_sge);
43939dbc646SYuval Bason 	}
440f1372ee1SKalderon, Michal 	dev->max_inline = ROCE_REQ_MAX_INLINE_DATA_SIZE;
441f1372ee1SKalderon, Michal 
442f1372ee1SKalderon, Michal 	dev->max_inline = (cdev->rdma_max_inline) ?
443f1372ee1SKalderon, Michal 			  min_t(u32, cdev->rdma_max_inline, dev->max_inline) :
444f1372ee1SKalderon, Michal 			  dev->max_inline;
445f1372ee1SKalderon, Michal 
446f1372ee1SKalderon, Michal 	dev->max_wqe = QED_RDMA_MAX_WQE;
447f1372ee1SKalderon, Michal 	dev->max_cnq = (u8)FEAT_NUM(p_hwfn, QED_RDMA_CNQ);
448f1372ee1SKalderon, Michal 
449f1372ee1SKalderon, Michal 	/* The number of QPs may be higher than QED_ROCE_MAX_QPS, because
450f1372ee1SKalderon, Michal 	 * it is up-aligned to 16 and then to ILT page size within qed cxt.
451f1372ee1SKalderon, Michal 	 * This is OK in terms of ILT but we don't want to configure the FW
452f1372ee1SKalderon, Michal 	 * above its abilities
453f1372ee1SKalderon, Michal 	 */
454f1372ee1SKalderon, Michal 	num_qps = ROCE_MAX_QPS;
455f1372ee1SKalderon, Michal 	num_qps = min_t(u64, num_qps, p_hwfn->p_rdma_info->num_qps);
456f1372ee1SKalderon, Michal 	dev->max_qp = num_qps;
457f1372ee1SKalderon, Michal 
458f1372ee1SKalderon, Michal 	/* CQs uses the same icids that QPs use hence they are limited by the
459f1372ee1SKalderon, Michal 	 * number of icids. There are two icids per QP.
460f1372ee1SKalderon, Michal 	 */
461f1372ee1SKalderon, Michal 	dev->max_cq = num_qps * 2;
462f1372ee1SKalderon, Michal 
463f1372ee1SKalderon, Michal 	/* The number of mrs is smaller by 1 since the first is reserved */
464f1372ee1SKalderon, Michal 	dev->max_mr = p_hwfn->p_rdma_info->num_mrs - 1;
465f1372ee1SKalderon, Michal 	dev->max_mr_size = QED_RDMA_MAX_MR_SIZE;
466f1372ee1SKalderon, Michal 
467f1372ee1SKalderon, Michal 	/* The maximum CQE capacity per CQ supported.
468f1372ee1SKalderon, Michal 	 * max number of cqes will be in two layer pbl,
469f1372ee1SKalderon, Michal 	 * 8 is the pointer size in bytes
470f1372ee1SKalderon, Michal 	 * 32 is the size of cq element in bytes
471f1372ee1SKalderon, Michal 	 */
472f1372ee1SKalderon, Michal 	if (params->cq_mode == QED_RDMA_CQ_MODE_32_BITS)
473f1372ee1SKalderon, Michal 		dev->max_cqe = QED_RDMA_MAX_CQE_32_BIT;
474f1372ee1SKalderon, Michal 	else
475f1372ee1SKalderon, Michal 		dev->max_cqe = QED_RDMA_MAX_CQE_16_BIT;
476f1372ee1SKalderon, Michal 
477f1372ee1SKalderon, Michal 	dev->max_mw = 0;
478f1372ee1SKalderon, Michal 	dev->max_mr_mw_fmr_pbl = (PAGE_SIZE / 8) * (PAGE_SIZE / 8);
479f1372ee1SKalderon, Michal 	dev->max_mr_mw_fmr_size = dev->max_mr_mw_fmr_pbl * PAGE_SIZE;
4807d11b478SKamal Heib 	if (QED_IS_ROCE_PERSONALITY(p_hwfn))
481f1372ee1SKalderon, Michal 		dev->max_pkey = QED_RDMA_MAX_P_KEY;
482f1372ee1SKalderon, Michal 
48339dbc646SYuval Bason 	dev->max_srq = p_hwfn->p_rdma_info->num_srqs;
48439dbc646SYuval Bason 	dev->max_srq_wr = QED_RDMA_MAX_SRQ_WQE_ELEM;
485f1372ee1SKalderon, Michal 	dev->max_qp_resp_rd_atomic_resc = RDMA_RING_PAGE_SIZE /
486f1372ee1SKalderon, Michal 					  (RDMA_RESP_RD_ATOMIC_ELM_SIZE * 2);
487f1372ee1SKalderon, Michal 	dev->max_qp_req_rd_atomic_resc = RDMA_RING_PAGE_SIZE /
488f1372ee1SKalderon, Michal 					 RDMA_REQ_RD_ATOMIC_ELM_SIZE;
489f1372ee1SKalderon, Michal 	dev->max_dev_resp_rd_atomic_resc = dev->max_qp_resp_rd_atomic_resc *
490f1372ee1SKalderon, Michal 					   p_hwfn->p_rdma_info->num_qps;
491f1372ee1SKalderon, Michal 	dev->page_size_caps = QED_RDMA_PAGE_SIZE_CAPS;
492f1372ee1SKalderon, Michal 	dev->dev_ack_delay = QED_RDMA_ACK_DELAY;
493f1372ee1SKalderon, Michal 	dev->max_pd = RDMA_MAX_PDS;
494f1372ee1SKalderon, Michal 	dev->max_ah = p_hwfn->p_rdma_info->num_qps;
495f1372ee1SKalderon, Michal 	dev->max_stats_queues = (u8)RESC_NUM(p_hwfn, QED_RDMA_STATS_QUEUE);
496f1372ee1SKalderon, Michal 
497f1372ee1SKalderon, Michal 	/* Set capablities */
498f1372ee1SKalderon, Michal 	dev->dev_caps = 0;
499f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_RNR_NAK, 1);
500f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_PORT_ACTIVE_EVENT, 1);
501f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_PORT_CHANGE_EVENT, 1);
502f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_RESIZE_CQ, 1);
503f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_BASE_MEMORY_EXT, 1);
504f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_BASE_QUEUE_EXT, 1);
505f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_ZBVA, 1);
506f1372ee1SKalderon, Michal 	SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_LOCAL_INV_FENCE, 1);
507f1372ee1SKalderon, Michal 
508f1372ee1SKalderon, Michal 	/* Check atomic operations support in PCI configuration space. */
50993428c58SFrederick Lawler 	pcie_capability_read_dword(cdev->pdev, PCI_EXP_DEVCTL2,
510f1372ee1SKalderon, Michal 				   &pci_status_control);
511f1372ee1SKalderon, Michal 
512f1372ee1SKalderon, Michal 	if (pci_status_control & PCI_EXP_DEVCTL2_LTR_EN)
513f1372ee1SKalderon, Michal 		SET_FIELD(dev->dev_caps, QED_RDMA_DEV_CAP_ATOMIC_OP, 1);
51467b40dccSKalderon, Michal 
51567b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
51667b40dccSKalderon, Michal 		qed_iwarp_init_devinfo(p_hwfn);
517f1372ee1SKalderon, Michal }
518f1372ee1SKalderon, Michal 
qed_rdma_init_port(struct qed_hwfn * p_hwfn)519f1372ee1SKalderon, Michal static void qed_rdma_init_port(struct qed_hwfn *p_hwfn)
520f1372ee1SKalderon, Michal {
521f1372ee1SKalderon, Michal 	struct qed_rdma_port *port = p_hwfn->p_rdma_info->port;
522f1372ee1SKalderon, Michal 	struct qed_rdma_device *dev = p_hwfn->p_rdma_info->dev;
523f1372ee1SKalderon, Michal 
524f1372ee1SKalderon, Michal 	port->port_state = p_hwfn->mcp_info->link_output.link_up ?
525f1372ee1SKalderon, Michal 			   QED_RDMA_PORT_UP : QED_RDMA_PORT_DOWN;
526f1372ee1SKalderon, Michal 
527f1372ee1SKalderon, Michal 	port->max_msg_size = min_t(u64,
528f1372ee1SKalderon, Michal 				   (dev->max_mr_mw_fmr_size *
529f1372ee1SKalderon, Michal 				    p_hwfn->cdev->rdma_max_sge),
530f1372ee1SKalderon, Michal 				   BIT(31));
531f1372ee1SKalderon, Michal 
532f1372ee1SKalderon, Michal 	port->pkey_bad_counter = 0;
533f1372ee1SKalderon, Michal }
534f1372ee1SKalderon, Michal 
qed_rdma_init_hw(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)535f1372ee1SKalderon, Michal static int qed_rdma_init_hw(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
536f1372ee1SKalderon, Michal {
53767b40dccSKalderon, Michal 	int rc = 0;
538f1372ee1SKalderon, Michal 
539f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Initializing HW\n");
540f1372ee1SKalderon, Michal 	p_hwfn->b_rdma_enabled_in_prs = false;
541f1372ee1SKalderon, Michal 
54267b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
54367b40dccSKalderon, Michal 		qed_iwarp_init_hw(p_hwfn, p_ptt);
54467b40dccSKalderon, Michal 	else
54567b40dccSKalderon, Michal 		rc = qed_roce_init_hw(p_hwfn, p_ptt);
546f1372ee1SKalderon, Michal 
54767b40dccSKalderon, Michal 	return rc;
548f1372ee1SKalderon, Michal }
549f1372ee1SKalderon, Michal 
qed_rdma_start_fw(struct qed_hwfn * p_hwfn,struct qed_rdma_start_in_params * params,struct qed_ptt * p_ptt)550f1372ee1SKalderon, Michal static int qed_rdma_start_fw(struct qed_hwfn *p_hwfn,
551f1372ee1SKalderon, Michal 			     struct qed_rdma_start_in_params *params,
552f1372ee1SKalderon, Michal 			     struct qed_ptt *p_ptt)
553f1372ee1SKalderon, Michal {
554f1372ee1SKalderon, Michal 	struct rdma_init_func_ramrod_data *p_ramrod;
555f1372ee1SKalderon, Michal 	struct qed_rdma_cnq_params *p_cnq_pbl_list;
556f1372ee1SKalderon, Michal 	struct rdma_init_func_hdr *p_params_header;
557f1372ee1SKalderon, Michal 	struct rdma_cnq_params *p_cnq_params;
558f1372ee1SKalderon, Michal 	struct qed_sp_init_data init_data;
559f1372ee1SKalderon, Michal 	struct qed_spq_entry *p_ent;
560f1372ee1SKalderon, Michal 	u32 cnq_id, sb_id;
561f1372ee1SKalderon, Michal 	u16 igu_sb_id;
562f1372ee1SKalderon, Michal 	int rc;
563f1372ee1SKalderon, Michal 
564f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Starting FW\n");
565f1372ee1SKalderon, Michal 
566f1372ee1SKalderon, Michal 	/* Save the number of cnqs for the function close ramrod */
567f1372ee1SKalderon, Michal 	p_hwfn->p_rdma_info->num_cnqs = params->desired_cnq;
568f1372ee1SKalderon, Michal 
569f1372ee1SKalderon, Michal 	/* Get SPQ entry */
570f1372ee1SKalderon, Michal 	memset(&init_data, 0, sizeof(init_data));
571f1372ee1SKalderon, Michal 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
572f1372ee1SKalderon, Michal 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
573f1372ee1SKalderon, Michal 
574f1372ee1SKalderon, Michal 	rc = qed_sp_init_request(p_hwfn, &p_ent, RDMA_RAMROD_FUNC_INIT,
575f1372ee1SKalderon, Michal 				 p_hwfn->p_rdma_info->proto, &init_data);
576f1372ee1SKalderon, Michal 	if (rc)
577f1372ee1SKalderon, Michal 		return rc;
578f1372ee1SKalderon, Michal 
579d1abfd0bSMichal Kalderon 	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
580d1abfd0bSMichal Kalderon 		qed_iwarp_init_fw_ramrod(p_hwfn,
581da090917STomer Tayar 					 &p_ent->ramrod.iwarp_init_func);
58267b40dccSKalderon, Michal 		p_ramrod = &p_ent->ramrod.iwarp_init_func.rdma;
583d1abfd0bSMichal Kalderon 	} else {
584f1372ee1SKalderon, Michal 		p_ramrod = &p_ent->ramrod.roce_init_func.rdma;
585d1abfd0bSMichal Kalderon 	}
586f1372ee1SKalderon, Michal 
587f1372ee1SKalderon, Michal 	p_params_header = &p_ramrod->params_header;
588f1372ee1SKalderon, Michal 	p_params_header->cnq_start_offset = (u8)RESC_START(p_hwfn,
589f1372ee1SKalderon, Michal 							   QED_RDMA_CNQ_RAM);
590f1372ee1SKalderon, Michal 	p_params_header->num_cnqs = params->desired_cnq;
5917bfb399eSYuval Basson 	p_params_header->first_reg_srq_id =
5927bfb399eSYuval Basson 	    cpu_to_le16(p_hwfn->p_rdma_info->srq_id_offset);
5937bfb399eSYuval Basson 	p_params_header->reg_srq_base_addr =
5947bfb399eSYuval Basson 	    cpu_to_le32(qed_cxt_get_ilt_page_size(p_hwfn, ILT_CLI_TSDM));
595f1372ee1SKalderon, Michal 	if (params->cq_mode == QED_RDMA_CQ_MODE_16_BITS)
596f1372ee1SKalderon, Michal 		p_params_header->cq_ring_mode = 1;
597f1372ee1SKalderon, Michal 	else
598f1372ee1SKalderon, Michal 		p_params_header->cq_ring_mode = 0;
599f1372ee1SKalderon, Michal 
600f1372ee1SKalderon, Michal 	for (cnq_id = 0; cnq_id < params->desired_cnq; cnq_id++) {
601f1372ee1SKalderon, Michal 		sb_id = qed_rdma_get_sb_id(p_hwfn, cnq_id);
602f1372ee1SKalderon, Michal 		igu_sb_id = qed_get_igu_sb_id(p_hwfn, sb_id);
603f1372ee1SKalderon, Michal 		p_ramrod->cnq_params[cnq_id].sb_num = cpu_to_le16(igu_sb_id);
604f1372ee1SKalderon, Michal 		p_cnq_params = &p_ramrod->cnq_params[cnq_id];
605f1372ee1SKalderon, Michal 		p_cnq_pbl_list = &params->cnq_pbl_list[cnq_id];
606f1372ee1SKalderon, Michal 
607f1372ee1SKalderon, Michal 		p_cnq_params->sb_index = p_hwfn->pf_params.rdma_pf_params.gl_pi;
608f1372ee1SKalderon, Michal 		p_cnq_params->num_pbl_pages = p_cnq_pbl_list->num_pbl_pages;
609f1372ee1SKalderon, Michal 
610f1372ee1SKalderon, Michal 		DMA_REGPAIR_LE(p_cnq_params->pbl_base_addr,
611f1372ee1SKalderon, Michal 			       p_cnq_pbl_list->pbl_ptr);
612f1372ee1SKalderon, Michal 
613f1372ee1SKalderon, Michal 		/* we assume here that cnq_id and qz_offset are the same */
614f1372ee1SKalderon, Michal 		p_cnq_params->queue_zone_num =
615f1372ee1SKalderon, Michal 			cpu_to_le16(p_hwfn->p_rdma_info->queue_zone_base +
616f1372ee1SKalderon, Michal 				    cnq_id);
617f1372ee1SKalderon, Michal 	}
618f1372ee1SKalderon, Michal 
619f1372ee1SKalderon, Michal 	return qed_spq_post(p_hwfn, p_ent, NULL);
620f1372ee1SKalderon, Michal }
621f1372ee1SKalderon, Michal 
qed_rdma_alloc_tid(void * rdma_cxt,u32 * itid)622f1372ee1SKalderon, Michal static int qed_rdma_alloc_tid(void *rdma_cxt, u32 *itid)
623f1372ee1SKalderon, Michal {
624f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
625f1372ee1SKalderon, Michal 	int rc;
626f1372ee1SKalderon, Michal 
627f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocate TID\n");
628f1372ee1SKalderon, Michal 
629f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
630f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc_id(p_hwfn,
631f1372ee1SKalderon, Michal 				    &p_hwfn->p_rdma_info->tid_map, itid);
632f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
633f1372ee1SKalderon, Michal 	if (rc)
634f1372ee1SKalderon, Michal 		goto out;
635f1372ee1SKalderon, Michal 
636f1372ee1SKalderon, Michal 	rc = qed_cxt_dynamic_ilt_alloc(p_hwfn, QED_ELEM_TASK, *itid);
637f1372ee1SKalderon, Michal out:
638f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocate TID - done, rc = %d\n", rc);
639f1372ee1SKalderon, Michal 	return rc;
640f1372ee1SKalderon, Michal }
641f1372ee1SKalderon, Michal 
qed_rdma_reserve_lkey(struct qed_hwfn * p_hwfn)642f1372ee1SKalderon, Michal static int qed_rdma_reserve_lkey(struct qed_hwfn *p_hwfn)
643f1372ee1SKalderon, Michal {
644f1372ee1SKalderon, Michal 	struct qed_rdma_device *dev = p_hwfn->p_rdma_info->dev;
645f1372ee1SKalderon, Michal 
646f1372ee1SKalderon, Michal 	/* Tid 0 will be used as the key for "reserved MR".
647f1372ee1SKalderon, Michal 	 * The driver should allocate memory for it so it can be loaded but no
648f1372ee1SKalderon, Michal 	 * ramrod should be passed on it.
649f1372ee1SKalderon, Michal 	 */
650f1372ee1SKalderon, Michal 	qed_rdma_alloc_tid(p_hwfn, &dev->reserved_lkey);
651f1372ee1SKalderon, Michal 	if (dev->reserved_lkey != RDMA_RESERVED_LKEY) {
652f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn,
653f1372ee1SKalderon, Michal 			  "Reserved lkey should be equal to RDMA_RESERVED_LKEY\n");
654f1372ee1SKalderon, Michal 		return -EINVAL;
655f1372ee1SKalderon, Michal 	}
656f1372ee1SKalderon, Michal 
657f1372ee1SKalderon, Michal 	return 0;
658f1372ee1SKalderon, Michal }
659f1372ee1SKalderon, Michal 
qed_rdma_setup(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct qed_rdma_start_in_params * params)660f1372ee1SKalderon, Michal static int qed_rdma_setup(struct qed_hwfn *p_hwfn,
661f1372ee1SKalderon, Michal 			  struct qed_ptt *p_ptt,
662f1372ee1SKalderon, Michal 			  struct qed_rdma_start_in_params *params)
663f1372ee1SKalderon, Michal {
664f1372ee1SKalderon, Michal 	int rc;
665f1372ee1SKalderon, Michal 
666f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n");
667f1372ee1SKalderon, Michal 
668f1372ee1SKalderon, Michal 	qed_rdma_init_devinfo(p_hwfn, params);
669f1372ee1SKalderon, Michal 	qed_rdma_init_port(p_hwfn);
670f1372ee1SKalderon, Michal 	qed_rdma_init_events(p_hwfn, params);
671f1372ee1SKalderon, Michal 
672f1372ee1SKalderon, Michal 	rc = qed_rdma_reserve_lkey(p_hwfn);
673f1372ee1SKalderon, Michal 	if (rc)
674f1372ee1SKalderon, Michal 		return rc;
675f1372ee1SKalderon, Michal 
676f1372ee1SKalderon, Michal 	rc = qed_rdma_init_hw(p_hwfn, p_ptt);
677f1372ee1SKalderon, Michal 	if (rc)
678f1372ee1SKalderon, Michal 		return rc;
679f1372ee1SKalderon, Michal 
68067b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
68179284adeSMichal Kalderon 		rc = qed_iwarp_setup(p_hwfn, params);
68267b40dccSKalderon, Michal 		if (rc)
68367b40dccSKalderon, Michal 			return rc;
68467b40dccSKalderon, Michal 	} else {
68567b40dccSKalderon, Michal 		rc = qed_roce_setup(p_hwfn);
68667b40dccSKalderon, Michal 		if (rc)
68767b40dccSKalderon, Michal 			return rc;
68867b40dccSKalderon, Michal 	}
689f1372ee1SKalderon, Michal 
690f1372ee1SKalderon, Michal 	return qed_rdma_start_fw(p_hwfn, params, p_ptt);
691f1372ee1SKalderon, Michal }
692f1372ee1SKalderon, Michal 
qed_rdma_stop(void * rdma_cxt)693bf774d14SYueHaibing static int qed_rdma_stop(void *rdma_cxt)
694f1372ee1SKalderon, Michal {
695f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
696f1372ee1SKalderon, Michal 	struct rdma_close_func_ramrod_data *p_ramrod;
697f1372ee1SKalderon, Michal 	struct qed_sp_init_data init_data;
698f1372ee1SKalderon, Michal 	struct qed_spq_entry *p_ent;
699f1372ee1SKalderon, Michal 	struct qed_ptt *p_ptt;
700f1372ee1SKalderon, Michal 	u32 ll2_ethertype_en;
701f1372ee1SKalderon, Michal 	int rc = -EBUSY;
702f1372ee1SKalderon, Michal 
703f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA stop\n");
704f1372ee1SKalderon, Michal 
705f1372ee1SKalderon, Michal 	p_ptt = qed_ptt_acquire(p_hwfn);
706f1372ee1SKalderon, Michal 	if (!p_ptt) {
707f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Failed to acquire PTT\n");
708f1372ee1SKalderon, Michal 		return rc;
709f1372ee1SKalderon, Michal 	}
710f1372ee1SKalderon, Michal 
711f1372ee1SKalderon, Michal 	/* Disable RoCE search */
712f1372ee1SKalderon, Michal 	qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0);
713f1372ee1SKalderon, Michal 	p_hwfn->b_rdma_enabled_in_prs = false;
714291d57f6SMichal Kalderon 	p_hwfn->p_rdma_info->active = 0;
715f1372ee1SKalderon, Michal 	qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0);
716f1372ee1SKalderon, Michal 
717f1372ee1SKalderon, Michal 	ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN);
718f1372ee1SKalderon, Michal 
719f1372ee1SKalderon, Michal 	qed_wr(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN,
720f1372ee1SKalderon, Michal 	       (ll2_ethertype_en & 0xFFFE));
721f1372ee1SKalderon, Michal 
72267b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
72379284adeSMichal Kalderon 		rc = qed_iwarp_stop(p_hwfn);
72467b40dccSKalderon, Michal 		if (rc) {
72567b40dccSKalderon, Michal 			qed_ptt_release(p_hwfn, p_ptt);
72667b40dccSKalderon, Michal 			return rc;
72767b40dccSKalderon, Michal 		}
72867b40dccSKalderon, Michal 	} else {
729f1372ee1SKalderon, Michal 		qed_roce_stop(p_hwfn);
73067b40dccSKalderon, Michal 	}
73167b40dccSKalderon, Michal 
732f1372ee1SKalderon, Michal 	qed_ptt_release(p_hwfn, p_ptt);
733f1372ee1SKalderon, Michal 
734f1372ee1SKalderon, Michal 	/* Get SPQ entry */
735f1372ee1SKalderon, Michal 	memset(&init_data, 0, sizeof(init_data));
736f1372ee1SKalderon, Michal 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
737f1372ee1SKalderon, Michal 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
738f1372ee1SKalderon, Michal 
739f1372ee1SKalderon, Michal 	/* Stop RoCE */
740f1372ee1SKalderon, Michal 	rc = qed_sp_init_request(p_hwfn, &p_ent, RDMA_RAMROD_FUNC_CLOSE,
741f1372ee1SKalderon, Michal 				 p_hwfn->p_rdma_info->proto, &init_data);
742f1372ee1SKalderon, Michal 	if (rc)
743f1372ee1SKalderon, Michal 		goto out;
744f1372ee1SKalderon, Michal 
745f1372ee1SKalderon, Michal 	p_ramrod = &p_ent->ramrod.rdma_close_func;
746f1372ee1SKalderon, Michal 
747f1372ee1SKalderon, Michal 	p_ramrod->num_cnqs = p_hwfn->p_rdma_info->num_cnqs;
748f1372ee1SKalderon, Michal 	p_ramrod->cnq_start_offset = (u8)RESC_START(p_hwfn, QED_RDMA_CNQ_RAM);
749f1372ee1SKalderon, Michal 
750f1372ee1SKalderon, Michal 	rc = qed_spq_post(p_hwfn, p_ent, NULL);
751f1372ee1SKalderon, Michal 
752f1372ee1SKalderon, Michal out:
753f1372ee1SKalderon, Michal 	qed_rdma_free(p_hwfn);
754f1372ee1SKalderon, Michal 
755f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA stop done, rc = %d\n", rc);
756f1372ee1SKalderon, Michal 	return rc;
757f1372ee1SKalderon, Michal }
758f1372ee1SKalderon, Michal 
qed_rdma_add_user(void * rdma_cxt,struct qed_rdma_add_user_out_params * out_params)759f1372ee1SKalderon, Michal static int qed_rdma_add_user(void *rdma_cxt,
760f1372ee1SKalderon, Michal 			     struct qed_rdma_add_user_out_params *out_params)
761f1372ee1SKalderon, Michal {
762f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
763f1372ee1SKalderon, Michal 	u32 dpi_start_offset;
764f1372ee1SKalderon, Michal 	u32 returned_id = 0;
765f1372ee1SKalderon, Michal 	int rc;
766f1372ee1SKalderon, Michal 
767f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Adding User\n");
768f1372ee1SKalderon, Michal 
769f1372ee1SKalderon, Michal 	/* Allocate DPI */
770f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
771f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc_id(p_hwfn, &p_hwfn->p_rdma_info->dpi_map,
772f1372ee1SKalderon, Michal 				    &returned_id);
773f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
774f1372ee1SKalderon, Michal 
775f1372ee1SKalderon, Michal 	out_params->dpi = (u16)returned_id;
776f1372ee1SKalderon, Michal 
777f1372ee1SKalderon, Michal 	/* Calculate the corresponding DPI address */
778f1372ee1SKalderon, Michal 	dpi_start_offset = p_hwfn->dpi_start_offset;
779f1372ee1SKalderon, Michal 
7800058eb58SMichal Kalderon 	out_params->dpi_addr = p_hwfn->doorbells + dpi_start_offset +
7810058eb58SMichal Kalderon 			       out_params->dpi * p_hwfn->dpi_size;
782f1372ee1SKalderon, Michal 
7838366d520SMichal Kalderon 	out_params->dpi_phys_addr = p_hwfn->db_phys_addr +
784f1372ee1SKalderon, Michal 				    dpi_start_offset +
785f1372ee1SKalderon, Michal 				    ((out_params->dpi) * p_hwfn->dpi_size);
786f1372ee1SKalderon, Michal 
787f1372ee1SKalderon, Michal 	out_params->dpi_size = p_hwfn->dpi_size;
788f1372ee1SKalderon, Michal 	out_params->wid_count = p_hwfn->wid_count;
789f1372ee1SKalderon, Michal 
790f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Adding user - done, rc = %d\n", rc);
791f1372ee1SKalderon, Michal 	return rc;
792f1372ee1SKalderon, Michal }
793f1372ee1SKalderon, Michal 
qed_rdma_query_port(void * rdma_cxt)794f1372ee1SKalderon, Michal static struct qed_rdma_port *qed_rdma_query_port(void *rdma_cxt)
795f1372ee1SKalderon, Michal {
796f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
797f1372ee1SKalderon, Michal 	struct qed_rdma_port *p_port = p_hwfn->p_rdma_info->port;
7987e50769cSMichal Kalderon 	struct qed_mcp_link_state *p_link_output;
799f1372ee1SKalderon, Michal 
800f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA Query port\n");
801f1372ee1SKalderon, Michal 
8027e50769cSMichal Kalderon 	/* The link state is saved only for the leading hwfn */
8037e50769cSMichal Kalderon 	p_link_output = &QED_LEADING_HWFN(p_hwfn->cdev)->mcp_info->link_output;
804f1372ee1SKalderon, Michal 
8057e50769cSMichal Kalderon 	p_port->port_state = p_link_output->link_up ? QED_RDMA_PORT_UP
8067e50769cSMichal Kalderon 	    : QED_RDMA_PORT_DOWN;
8077e50769cSMichal Kalderon 
8087e50769cSMichal Kalderon 	p_port->link_speed = p_link_output->speed;
809f1372ee1SKalderon, Michal 
810f1372ee1SKalderon, Michal 	p_port->max_msg_size = RDMA_MAX_DATA_SIZE_IN_WQE;
811f1372ee1SKalderon, Michal 
812f1372ee1SKalderon, Michal 	return p_port;
813f1372ee1SKalderon, Michal }
814f1372ee1SKalderon, Michal 
qed_rdma_query_device(void * rdma_cxt)815f1372ee1SKalderon, Michal static struct qed_rdma_device *qed_rdma_query_device(void *rdma_cxt)
816f1372ee1SKalderon, Michal {
817f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
818f1372ee1SKalderon, Michal 
819f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Query device\n");
820f1372ee1SKalderon, Michal 
821f1372ee1SKalderon, Michal 	/* Return struct with device parameters */
822f1372ee1SKalderon, Michal 	return p_hwfn->p_rdma_info->dev;
823f1372ee1SKalderon, Michal }
824f1372ee1SKalderon, Michal 
qed_rdma_cnq_prod_update(void * rdma_cxt,u8 qz_offset,u16 prod)825f1372ee1SKalderon, Michal static void qed_rdma_cnq_prod_update(void *rdma_cxt, u8 qz_offset, u16 prod)
826f1372ee1SKalderon, Michal {
827f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn;
828f1372ee1SKalderon, Michal 	u16 qz_num;
829f1372ee1SKalderon, Michal 	u32 addr;
830f1372ee1SKalderon, Michal 
831f1372ee1SKalderon, Michal 	p_hwfn = (struct qed_hwfn *)rdma_cxt;
832f1372ee1SKalderon, Michal 
833f1372ee1SKalderon, Michal 	if (qz_offset > p_hwfn->p_rdma_info->max_queue_zones) {
834f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn,
835f1372ee1SKalderon, Michal 			  "queue zone offset %d is too large (max is %d)\n",
836f1372ee1SKalderon, Michal 			  qz_offset, p_hwfn->p_rdma_info->max_queue_zones);
837f1372ee1SKalderon, Michal 		return;
838f1372ee1SKalderon, Michal 	}
839f1372ee1SKalderon, Michal 
840f1372ee1SKalderon, Michal 	qz_num = p_hwfn->p_rdma_info->queue_zone_base + qz_offset;
841e2dbc223SPrabhakar Kushwaha 	addr = GET_GTT_REG_ADDR(GTT_BAR0_MAP_REG_USDM_RAM,
842e2dbc223SPrabhakar Kushwaha 				USTORM_COMMON_QUEUE_CONS, qz_num);
843f1372ee1SKalderon, Michal 
844f1372ee1SKalderon, Michal 	REG_WR16(p_hwfn, addr, prod);
845f1372ee1SKalderon, Michal 
846f1372ee1SKalderon, Michal 	/* keep prod updates ordered */
847f1372ee1SKalderon, Michal 	wmb();
848f1372ee1SKalderon, Michal }
849f1372ee1SKalderon, Michal 
qed_fill_rdma_dev_info(struct qed_dev * cdev,struct qed_dev_rdma_info * info)850f1372ee1SKalderon, Michal static int qed_fill_rdma_dev_info(struct qed_dev *cdev,
851f1372ee1SKalderon, Michal 				  struct qed_dev_rdma_info *info)
852f1372ee1SKalderon, Michal {
8537e50769cSMichal Kalderon 	struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
854f1372ee1SKalderon, Michal 
855f1372ee1SKalderon, Michal 	memset(info, 0, sizeof(*info));
856f1372ee1SKalderon, Michal 
85767b40dccSKalderon, Michal 	info->rdma_type = QED_IS_ROCE_PERSONALITY(p_hwfn) ?
85867b40dccSKalderon, Michal 	    QED_RDMA_TYPE_ROCE : QED_RDMA_TYPE_IWARP;
85967b40dccSKalderon, Michal 
860f1372ee1SKalderon, Michal 	info->user_dpm_enabled = (p_hwfn->db_bar_no_edpm == 0);
861f1372ee1SKalderon, Michal 
862f1372ee1SKalderon, Michal 	qed_fill_dev_info(cdev, &info->common);
863f1372ee1SKalderon, Michal 
864f1372ee1SKalderon, Michal 	return 0;
865f1372ee1SKalderon, Michal }
866f1372ee1SKalderon, Michal 
qed_rdma_get_sb_start(struct qed_dev * cdev)867f1372ee1SKalderon, Michal static int qed_rdma_get_sb_start(struct qed_dev *cdev)
868f1372ee1SKalderon, Michal {
869f1372ee1SKalderon, Michal 	int feat_num;
870f1372ee1SKalderon, Michal 
871f1372ee1SKalderon, Michal 	if (cdev->num_hwfns > 1)
8727e50769cSMichal Kalderon 		feat_num = FEAT_NUM(QED_AFFIN_HWFN(cdev), QED_PF_L2_QUE);
873f1372ee1SKalderon, Michal 	else
8747e50769cSMichal Kalderon 		feat_num = FEAT_NUM(QED_AFFIN_HWFN(cdev), QED_PF_L2_QUE) *
875f1372ee1SKalderon, Michal 			   cdev->num_hwfns;
876f1372ee1SKalderon, Michal 
877f1372ee1SKalderon, Michal 	return feat_num;
878f1372ee1SKalderon, Michal }
879f1372ee1SKalderon, Michal 
qed_rdma_get_min_cnq_msix(struct qed_dev * cdev)880f1372ee1SKalderon, Michal static int qed_rdma_get_min_cnq_msix(struct qed_dev *cdev)
881f1372ee1SKalderon, Michal {
8827e50769cSMichal Kalderon 	int n_cnq = FEAT_NUM(QED_AFFIN_HWFN(cdev), QED_RDMA_CNQ);
883f1372ee1SKalderon, Michal 	int n_msix = cdev->int_params.rdma_msix_cnt;
884f1372ee1SKalderon, Michal 
885f1372ee1SKalderon, Michal 	return min_t(int, n_cnq, n_msix);
886f1372ee1SKalderon, Michal }
887f1372ee1SKalderon, Michal 
qed_rdma_set_int(struct qed_dev * cdev,u16 cnt)888f1372ee1SKalderon, Michal static int qed_rdma_set_int(struct qed_dev *cdev, u16 cnt)
889f1372ee1SKalderon, Michal {
890f1372ee1SKalderon, Michal 	int limit = 0;
891f1372ee1SKalderon, Michal 
892f1372ee1SKalderon, Michal 	/* Mark the fastpath as free/used */
893f1372ee1SKalderon, Michal 	cdev->int_params.fp_initialized = cnt ? true : false;
894f1372ee1SKalderon, Michal 
895f1372ee1SKalderon, Michal 	if (cdev->int_params.out.int_mode != QED_INT_MODE_MSIX) {
896f1372ee1SKalderon, Michal 		DP_ERR(cdev,
897f1372ee1SKalderon, Michal 		       "qed roce supports only MSI-X interrupts (detected %d).\n",
898f1372ee1SKalderon, Michal 		       cdev->int_params.out.int_mode);
899f1372ee1SKalderon, Michal 		return -EINVAL;
900f1372ee1SKalderon, Michal 	} else if (cdev->int_params.fp_msix_cnt) {
901f1372ee1SKalderon, Michal 		limit = cdev->int_params.rdma_msix_cnt;
902f1372ee1SKalderon, Michal 	}
903f1372ee1SKalderon, Michal 
904f1372ee1SKalderon, Michal 	if (!limit)
905f1372ee1SKalderon, Michal 		return -ENOMEM;
906f1372ee1SKalderon, Michal 
907f1372ee1SKalderon, Michal 	return min_t(int, cnt, limit);
908f1372ee1SKalderon, Michal }
909f1372ee1SKalderon, Michal 
qed_rdma_get_int(struct qed_dev * cdev,struct qed_int_info * info)910f1372ee1SKalderon, Michal static int qed_rdma_get_int(struct qed_dev *cdev, struct qed_int_info *info)
911f1372ee1SKalderon, Michal {
912f1372ee1SKalderon, Michal 	memset(info, 0, sizeof(*info));
913f1372ee1SKalderon, Michal 
914f1372ee1SKalderon, Michal 	if (!cdev->int_params.fp_initialized) {
915f1372ee1SKalderon, Michal 		DP_INFO(cdev,
916f1372ee1SKalderon, Michal 			"Protocol driver requested interrupt information, but its support is not yet configured\n");
917f1372ee1SKalderon, Michal 		return -EINVAL;
918f1372ee1SKalderon, Michal 	}
919f1372ee1SKalderon, Michal 
920f1372ee1SKalderon, Michal 	if (cdev->int_params.out.int_mode == QED_INT_MODE_MSIX) {
921f1372ee1SKalderon, Michal 		int msix_base = cdev->int_params.rdma_msix_base;
922f1372ee1SKalderon, Michal 
923f1372ee1SKalderon, Michal 		info->msix_cnt = cdev->int_params.rdma_msix_cnt;
924f1372ee1SKalderon, Michal 		info->msix = &cdev->int_params.msix_table[msix_base];
925f1372ee1SKalderon, Michal 
926f1372ee1SKalderon, Michal 		DP_VERBOSE(cdev, QED_MSG_RDMA, "msix_cnt = %d msix_base=%d\n",
927f1372ee1SKalderon, Michal 			   info->msix_cnt, msix_base);
928f1372ee1SKalderon, Michal 	}
929f1372ee1SKalderon, Michal 
930f1372ee1SKalderon, Michal 	return 0;
931f1372ee1SKalderon, Michal }
932f1372ee1SKalderon, Michal 
qed_rdma_alloc_pd(void * rdma_cxt,u16 * pd)933f1372ee1SKalderon, Michal static int qed_rdma_alloc_pd(void *rdma_cxt, u16 *pd)
934f1372ee1SKalderon, Michal {
935f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
936f1372ee1SKalderon, Michal 	u32 returned_id;
937f1372ee1SKalderon, Michal 	int rc;
938f1372ee1SKalderon, Michal 
939f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Alloc PD\n");
940f1372ee1SKalderon, Michal 
941f1372ee1SKalderon, Michal 	/* Allocates an unused protection domain */
942f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
943f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc_id(p_hwfn,
944f1372ee1SKalderon, Michal 				    &p_hwfn->p_rdma_info->pd_map, &returned_id);
945f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
946f1372ee1SKalderon, Michal 
947f1372ee1SKalderon, Michal 	*pd = (u16)returned_id;
948f1372ee1SKalderon, Michal 
949f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Alloc PD - done, rc = %d\n", rc);
950f1372ee1SKalderon, Michal 	return rc;
951f1372ee1SKalderon, Michal }
952f1372ee1SKalderon, Michal 
qed_rdma_free_pd(void * rdma_cxt,u16 pd)953f1372ee1SKalderon, Michal static void qed_rdma_free_pd(void *rdma_cxt, u16 pd)
954f1372ee1SKalderon, Michal {
955f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
956f1372ee1SKalderon, Michal 
957f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "pd = %08x\n", pd);
958f1372ee1SKalderon, Michal 
959f1372ee1SKalderon, Michal 	/* Returns a previously allocated protection domain for reuse */
960f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
961f1372ee1SKalderon, Michal 	qed_bmap_release_id(p_hwfn, &p_hwfn->p_rdma_info->pd_map, pd);
962f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
963f1372ee1SKalderon, Michal }
964f1372ee1SKalderon, Michal 
qed_rdma_alloc_xrcd(void * rdma_cxt,u16 * xrcd_id)9657bfb399eSYuval Basson static int qed_rdma_alloc_xrcd(void *rdma_cxt, u16 *xrcd_id)
9667bfb399eSYuval Basson {
9677bfb399eSYuval Basson 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
9687bfb399eSYuval Basson 	u32 returned_id;
9697bfb399eSYuval Basson 	int rc;
9707bfb399eSYuval Basson 
9717bfb399eSYuval Basson 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Alloc XRCD\n");
9727bfb399eSYuval Basson 
9737bfb399eSYuval Basson 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
9747bfb399eSYuval Basson 	rc = qed_rdma_bmap_alloc_id(p_hwfn,
9757bfb399eSYuval Basson 				    &p_hwfn->p_rdma_info->xrcd_map,
9767bfb399eSYuval Basson 				    &returned_id);
9777bfb399eSYuval Basson 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
9787bfb399eSYuval Basson 	if (rc) {
9797bfb399eSYuval Basson 		DP_NOTICE(p_hwfn, "Failed in allocating xrcd id\n");
9807bfb399eSYuval Basson 		return rc;
9817bfb399eSYuval Basson 	}
9827bfb399eSYuval Basson 
9837bfb399eSYuval Basson 	*xrcd_id = (u16)returned_id;
9847bfb399eSYuval Basson 
9857bfb399eSYuval Basson 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Alloc XRCD - done, rc = %d\n", rc);
9867bfb399eSYuval Basson 	return rc;
9877bfb399eSYuval Basson }
9887bfb399eSYuval Basson 
qed_rdma_free_xrcd(void * rdma_cxt,u16 xrcd_id)9897bfb399eSYuval Basson static void qed_rdma_free_xrcd(void *rdma_cxt, u16 xrcd_id)
9907bfb399eSYuval Basson {
9917bfb399eSYuval Basson 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
9927bfb399eSYuval Basson 
9937bfb399eSYuval Basson 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "xrcd_id = %08x\n", xrcd_id);
9947bfb399eSYuval Basson 
9957bfb399eSYuval Basson 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
9967bfb399eSYuval Basson 	qed_bmap_release_id(p_hwfn, &p_hwfn->p_rdma_info->xrcd_map, xrcd_id);
9977bfb399eSYuval Basson 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
9987bfb399eSYuval Basson }
9997bfb399eSYuval Basson 
1000f1372ee1SKalderon, Michal static enum qed_rdma_toggle_bit
qed_rdma_toggle_bit_create_resize_cq(struct qed_hwfn * p_hwfn,u16 icid)1001f1372ee1SKalderon, Michal qed_rdma_toggle_bit_create_resize_cq(struct qed_hwfn *p_hwfn, u16 icid)
1002f1372ee1SKalderon, Michal {
1003f1372ee1SKalderon, Michal 	struct qed_rdma_info *p_info = p_hwfn->p_rdma_info;
1004f1372ee1SKalderon, Michal 	enum qed_rdma_toggle_bit toggle_bit;
1005f1372ee1SKalderon, Michal 	u32 bmap_id;
1006f1372ee1SKalderon, Michal 
1007f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "icid = %08x\n", icid);
1008f1372ee1SKalderon, Michal 
1009f1372ee1SKalderon, Michal 	/* the function toggle the bit that is related to a given icid
1010f1372ee1SKalderon, Michal 	 * and returns the new toggle bit's value
1011f1372ee1SKalderon, Michal 	 */
1012f1372ee1SKalderon, Michal 	bmap_id = icid - qed_cxt_get_proto_cid_start(p_hwfn, p_info->proto);
1013f1372ee1SKalderon, Michal 
1014f1372ee1SKalderon, Michal 	spin_lock_bh(&p_info->lock);
1015f1372ee1SKalderon, Michal 	toggle_bit = !test_and_change_bit(bmap_id,
1016f1372ee1SKalderon, Michal 					  p_info->toggle_bits.bitmap);
1017f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_info->lock);
1018f1372ee1SKalderon, Michal 
1019f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "QED_RDMA_TOGGLE_BIT_= %d\n",
1020f1372ee1SKalderon, Michal 		   toggle_bit);
1021f1372ee1SKalderon, Michal 
1022f1372ee1SKalderon, Michal 	return toggle_bit;
1023f1372ee1SKalderon, Michal }
1024f1372ee1SKalderon, Michal 
qed_rdma_create_cq(void * rdma_cxt,struct qed_rdma_create_cq_in_params * params,u16 * icid)1025f1372ee1SKalderon, Michal static int qed_rdma_create_cq(void *rdma_cxt,
1026f1372ee1SKalderon, Michal 			      struct qed_rdma_create_cq_in_params *params,
1027f1372ee1SKalderon, Michal 			      u16 *icid)
1028f1372ee1SKalderon, Michal {
1029f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1030f1372ee1SKalderon, Michal 	struct qed_rdma_info *p_info = p_hwfn->p_rdma_info;
1031f1372ee1SKalderon, Michal 	struct rdma_create_cq_ramrod_data *p_ramrod;
1032f1372ee1SKalderon, Michal 	enum qed_rdma_toggle_bit toggle_bit;
1033f1372ee1SKalderon, Michal 	struct qed_sp_init_data init_data;
1034f1372ee1SKalderon, Michal 	struct qed_spq_entry *p_ent;
1035f1372ee1SKalderon, Michal 	u32 returned_id, start_cid;
1036f1372ee1SKalderon, Michal 	int rc;
1037f1372ee1SKalderon, Michal 
1038f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "cq_handle = %08x%08x\n",
1039f1372ee1SKalderon, Michal 		   params->cq_handle_hi, params->cq_handle_lo);
1040f1372ee1SKalderon, Michal 
1041f1372ee1SKalderon, Michal 	/* Allocate icid */
1042f1372ee1SKalderon, Michal 	spin_lock_bh(&p_info->lock);
1043f1372ee1SKalderon, Michal 	rc = qed_rdma_bmap_alloc_id(p_hwfn, &p_info->cq_map, &returned_id);
1044f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_info->lock);
1045f1372ee1SKalderon, Michal 
1046f1372ee1SKalderon, Michal 	if (rc) {
1047f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn, "Can't create CQ, rc = %d\n", rc);
1048f1372ee1SKalderon, Michal 		return rc;
1049f1372ee1SKalderon, Michal 	}
1050f1372ee1SKalderon, Michal 
1051f1372ee1SKalderon, Michal 	start_cid = qed_cxt_get_proto_cid_start(p_hwfn,
1052f1372ee1SKalderon, Michal 						p_info->proto);
1053f1372ee1SKalderon, Michal 	*icid = returned_id + start_cid;
1054f1372ee1SKalderon, Michal 
1055f1372ee1SKalderon, Michal 	/* Check if icid requires a page allocation */
1056f1372ee1SKalderon, Michal 	rc = qed_cxt_dynamic_ilt_alloc(p_hwfn, QED_ELEM_CXT, *icid);
1057f1372ee1SKalderon, Michal 	if (rc)
1058f1372ee1SKalderon, Michal 		goto err;
1059f1372ee1SKalderon, Michal 
1060f1372ee1SKalderon, Michal 	/* Get SPQ entry */
1061f1372ee1SKalderon, Michal 	memset(&init_data, 0, sizeof(init_data));
1062f1372ee1SKalderon, Michal 	init_data.cid = *icid;
1063f1372ee1SKalderon, Michal 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
1064f1372ee1SKalderon, Michal 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
1065f1372ee1SKalderon, Michal 
1066f1372ee1SKalderon, Michal 	/* Send create CQ ramrod */
1067f1372ee1SKalderon, Michal 	rc = qed_sp_init_request(p_hwfn, &p_ent,
1068f1372ee1SKalderon, Michal 				 RDMA_RAMROD_CREATE_CQ,
1069f1372ee1SKalderon, Michal 				 p_info->proto, &init_data);
1070f1372ee1SKalderon, Michal 	if (rc)
1071f1372ee1SKalderon, Michal 		goto err;
1072f1372ee1SKalderon, Michal 
1073f1372ee1SKalderon, Michal 	p_ramrod = &p_ent->ramrod.rdma_create_cq;
1074f1372ee1SKalderon, Michal 
1075f1372ee1SKalderon, Michal 	p_ramrod->cq_handle.hi = cpu_to_le32(params->cq_handle_hi);
1076f1372ee1SKalderon, Michal 	p_ramrod->cq_handle.lo = cpu_to_le32(params->cq_handle_lo);
1077f1372ee1SKalderon, Michal 	p_ramrod->dpi = cpu_to_le16(params->dpi);
1078f1372ee1SKalderon, Michal 	p_ramrod->is_two_level_pbl = params->pbl_two_level;
1079f1372ee1SKalderon, Michal 	p_ramrod->max_cqes = cpu_to_le32(params->cq_size);
1080f1372ee1SKalderon, Michal 	DMA_REGPAIR_LE(p_ramrod->pbl_addr, params->pbl_ptr);
1081f1372ee1SKalderon, Michal 	p_ramrod->pbl_num_pages = cpu_to_le16(params->pbl_num_pages);
1082f1372ee1SKalderon, Michal 	p_ramrod->cnq_id = (u8)RESC_START(p_hwfn, QED_RDMA_CNQ_RAM) +
1083f1372ee1SKalderon, Michal 			   params->cnq_id;
10845ab90341SAlexander Lobakin 	p_ramrod->int_timeout = cpu_to_le16(params->int_timeout);
1085f1372ee1SKalderon, Michal 
1086f1372ee1SKalderon, Michal 	/* toggle the bit for every resize or create cq for a given icid */
1087f1372ee1SKalderon, Michal 	toggle_bit = qed_rdma_toggle_bit_create_resize_cq(p_hwfn, *icid);
1088f1372ee1SKalderon, Michal 
1089f1372ee1SKalderon, Michal 	p_ramrod->toggle_bit = toggle_bit;
1090f1372ee1SKalderon, Michal 
1091f1372ee1SKalderon, Michal 	rc = qed_spq_post(p_hwfn, p_ent, NULL);
1092f1372ee1SKalderon, Michal 	if (rc) {
1093f1372ee1SKalderon, Michal 		/* restore toggle bit */
1094f1372ee1SKalderon, Michal 		qed_rdma_toggle_bit_create_resize_cq(p_hwfn, *icid);
1095f1372ee1SKalderon, Michal 		goto err;
1096f1372ee1SKalderon, Michal 	}
1097f1372ee1SKalderon, Michal 
1098f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Created CQ, rc = %d\n", rc);
1099f1372ee1SKalderon, Michal 	return rc;
1100f1372ee1SKalderon, Michal 
1101f1372ee1SKalderon, Michal err:
1102f1372ee1SKalderon, Michal 	/* release allocated icid */
1103f1372ee1SKalderon, Michal 	spin_lock_bh(&p_info->lock);
1104f1372ee1SKalderon, Michal 	qed_bmap_release_id(p_hwfn, &p_info->cq_map, returned_id);
1105f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_info->lock);
1106f1372ee1SKalderon, Michal 	DP_NOTICE(p_hwfn, "Create CQ failed, rc = %d\n", rc);
1107f1372ee1SKalderon, Michal 
1108f1372ee1SKalderon, Michal 	return rc;
1109f1372ee1SKalderon, Michal }
1110f1372ee1SKalderon, Michal 
1111f1372ee1SKalderon, Michal static int
qed_rdma_destroy_cq(void * rdma_cxt,struct qed_rdma_destroy_cq_in_params * in_params,struct qed_rdma_destroy_cq_out_params * out_params)1112f1372ee1SKalderon, Michal qed_rdma_destroy_cq(void *rdma_cxt,
1113f1372ee1SKalderon, Michal 		    struct qed_rdma_destroy_cq_in_params *in_params,
1114f1372ee1SKalderon, Michal 		    struct qed_rdma_destroy_cq_out_params *out_params)
1115f1372ee1SKalderon, Michal {
1116f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1117f1372ee1SKalderon, Michal 	struct rdma_destroy_cq_output_params *p_ramrod_res;
1118f1372ee1SKalderon, Michal 	struct rdma_destroy_cq_ramrod_data *p_ramrod;
1119f1372ee1SKalderon, Michal 	struct qed_sp_init_data init_data;
1120f1372ee1SKalderon, Michal 	struct qed_spq_entry *p_ent;
1121f1372ee1SKalderon, Michal 	dma_addr_t ramrod_res_phys;
1122f1372ee1SKalderon, Michal 	enum protocol_type proto;
1123f1372ee1SKalderon, Michal 	int rc = -ENOMEM;
1124f1372ee1SKalderon, Michal 
1125f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "icid = %08x\n", in_params->icid);
1126f1372ee1SKalderon, Michal 
1127f1372ee1SKalderon, Michal 	p_ramrod_res =
1128f1372ee1SKalderon, Michal 	    dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
1129f1372ee1SKalderon, Michal 			       sizeof(struct rdma_destroy_cq_output_params),
1130f1372ee1SKalderon, Michal 			       &ramrod_res_phys, GFP_KERNEL);
1131f1372ee1SKalderon, Michal 	if (!p_ramrod_res) {
1132f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn,
1133f1372ee1SKalderon, Michal 			  "qed destroy cq failed: cannot allocate memory (ramrod)\n");
1134f1372ee1SKalderon, Michal 		return rc;
1135f1372ee1SKalderon, Michal 	}
1136f1372ee1SKalderon, Michal 
1137f1372ee1SKalderon, Michal 	/* Get SPQ entry */
1138f1372ee1SKalderon, Michal 	memset(&init_data, 0, sizeof(init_data));
1139f1372ee1SKalderon, Michal 	init_data.cid = in_params->icid;
1140f1372ee1SKalderon, Michal 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
1141f1372ee1SKalderon, Michal 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
1142f1372ee1SKalderon, Michal 	proto = p_hwfn->p_rdma_info->proto;
1143f1372ee1SKalderon, Michal 	/* Send destroy CQ ramrod */
1144f1372ee1SKalderon, Michal 	rc = qed_sp_init_request(p_hwfn, &p_ent,
1145f1372ee1SKalderon, Michal 				 RDMA_RAMROD_DESTROY_CQ,
1146f1372ee1SKalderon, Michal 				 proto, &init_data);
1147f1372ee1SKalderon, Michal 	if (rc)
1148f1372ee1SKalderon, Michal 		goto err;
1149f1372ee1SKalderon, Michal 
1150f1372ee1SKalderon, Michal 	p_ramrod = &p_ent->ramrod.rdma_destroy_cq;
1151f1372ee1SKalderon, Michal 	DMA_REGPAIR_LE(p_ramrod->output_params_addr, ramrod_res_phys);
1152f1372ee1SKalderon, Michal 
1153f1372ee1SKalderon, Michal 	rc = qed_spq_post(p_hwfn, p_ent, NULL);
1154f1372ee1SKalderon, Michal 	if (rc)
1155f1372ee1SKalderon, Michal 		goto err;
1156f1372ee1SKalderon, Michal 
1157f1372ee1SKalderon, Michal 	out_params->num_cq_notif = le16_to_cpu(p_ramrod_res->cnq_num);
1158f1372ee1SKalderon, Michal 
1159f1372ee1SKalderon, Michal 	dma_free_coherent(&p_hwfn->cdev->pdev->dev,
1160f1372ee1SKalderon, Michal 			  sizeof(struct rdma_destroy_cq_output_params),
1161f1372ee1SKalderon, Michal 			  p_ramrod_res, ramrod_res_phys);
1162f1372ee1SKalderon, Michal 
1163f1372ee1SKalderon, Michal 	/* Free icid */
1164f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
1165f1372ee1SKalderon, Michal 
1166f1372ee1SKalderon, Michal 	qed_bmap_release_id(p_hwfn,
1167f1372ee1SKalderon, Michal 			    &p_hwfn->p_rdma_info->cq_map,
1168f1372ee1SKalderon, Michal 			    (in_params->icid -
1169f1372ee1SKalderon, Michal 			     qed_cxt_get_proto_cid_start(p_hwfn, proto)));
1170f1372ee1SKalderon, Michal 
1171f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
1172f1372ee1SKalderon, Michal 
1173f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Destroyed CQ, rc = %d\n", rc);
1174f1372ee1SKalderon, Michal 	return rc;
1175f1372ee1SKalderon, Michal 
1176f1372ee1SKalderon, Michal err:	dma_free_coherent(&p_hwfn->cdev->pdev->dev,
1177f1372ee1SKalderon, Michal 			  sizeof(struct rdma_destroy_cq_output_params),
1178f1372ee1SKalderon, Michal 			  p_ramrod_res, ramrod_res_phys);
1179f1372ee1SKalderon, Michal 
1180f1372ee1SKalderon, Michal 	return rc;
1181f1372ee1SKalderon, Michal }
1182f1372ee1SKalderon, Michal 
qed_rdma_set_fw_mac(__le16 * p_fw_mac,const u8 * p_qed_mac)11835ab90341SAlexander Lobakin void qed_rdma_set_fw_mac(__le16 *p_fw_mac, const u8 *p_qed_mac)
1184f1372ee1SKalderon, Michal {
1185f1372ee1SKalderon, Michal 	p_fw_mac[0] = cpu_to_le16((p_qed_mac[0] << 8) + p_qed_mac[1]);
1186f1372ee1SKalderon, Michal 	p_fw_mac[1] = cpu_to_le16((p_qed_mac[2] << 8) + p_qed_mac[3]);
1187f1372ee1SKalderon, Michal 	p_fw_mac[2] = cpu_to_le16((p_qed_mac[4] << 8) + p_qed_mac[5]);
1188f1372ee1SKalderon, Michal }
1189f1372ee1SKalderon, Michal 
qed_rdma_query_qp(void * rdma_cxt,struct qed_rdma_qp * qp,struct qed_rdma_query_qp_out_params * out_params)1190f1372ee1SKalderon, Michal static int qed_rdma_query_qp(void *rdma_cxt,
1191f1372ee1SKalderon, Michal 			     struct qed_rdma_qp *qp,
1192f1372ee1SKalderon, Michal 			     struct qed_rdma_query_qp_out_params *out_params)
1193f1372ee1SKalderon, Michal {
1194f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
119567b40dccSKalderon, Michal 	int rc = 0;
1196f1372ee1SKalderon, Michal 
1197f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "icid = %08x\n", qp->icid);
1198f1372ee1SKalderon, Michal 
1199f1372ee1SKalderon, Michal 	/* The following fields are filled in from qp and not FW as they can't
1200f1372ee1SKalderon, Michal 	 * be modified by FW
1201f1372ee1SKalderon, Michal 	 */
1202f1372ee1SKalderon, Michal 	out_params->mtu = qp->mtu;
1203f1372ee1SKalderon, Michal 	out_params->dest_qp = qp->dest_qp;
1204f1372ee1SKalderon, Michal 	out_params->incoming_atomic_en = qp->incoming_atomic_en;
1205f1372ee1SKalderon, Michal 	out_params->e2e_flow_control_en = qp->e2e_flow_control_en;
1206f1372ee1SKalderon, Michal 	out_params->incoming_rdma_read_en = qp->incoming_rdma_read_en;
1207f1372ee1SKalderon, Michal 	out_params->incoming_rdma_write_en = qp->incoming_rdma_write_en;
1208f1372ee1SKalderon, Michal 	out_params->dgid = qp->dgid;
1209f1372ee1SKalderon, Michal 	out_params->flow_label = qp->flow_label;
1210f1372ee1SKalderon, Michal 	out_params->hop_limit_ttl = qp->hop_limit_ttl;
1211f1372ee1SKalderon, Michal 	out_params->traffic_class_tos = qp->traffic_class_tos;
1212f1372ee1SKalderon, Michal 	out_params->timeout = qp->ack_timeout;
1213f1372ee1SKalderon, Michal 	out_params->rnr_retry = qp->rnr_retry_cnt;
1214f1372ee1SKalderon, Michal 	out_params->retry_cnt = qp->retry_cnt;
1215f1372ee1SKalderon, Michal 	out_params->min_rnr_nak_timer = qp->min_rnr_nak_timer;
1216f1372ee1SKalderon, Michal 	out_params->pkey_index = 0;
1217f1372ee1SKalderon, Michal 	out_params->max_rd_atomic = qp->max_rd_atomic_req;
1218f1372ee1SKalderon, Michal 	out_params->max_dest_rd_atomic = qp->max_rd_atomic_resp;
1219f1372ee1SKalderon, Michal 	out_params->sqd_async = qp->sqd_async;
1220f1372ee1SKalderon, Michal 
122167b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
122267b40dccSKalderon, Michal 		qed_iwarp_query_qp(qp, out_params);
122367b40dccSKalderon, Michal 	else
1224f1372ee1SKalderon, Michal 		rc = qed_roce_query_qp(p_hwfn, qp, out_params);
1225f1372ee1SKalderon, Michal 
1226f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Query QP, rc = %d\n", rc);
1227f1372ee1SKalderon, Michal 	return rc;
1228f1372ee1SKalderon, Michal }
1229f1372ee1SKalderon, Michal 
qed_rdma_destroy_qp(void * rdma_cxt,struct qed_rdma_qp * qp)1230f1372ee1SKalderon, Michal static int qed_rdma_destroy_qp(void *rdma_cxt, struct qed_rdma_qp *qp)
1231f1372ee1SKalderon, Michal {
1232f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1233f1372ee1SKalderon, Michal 	int rc = 0;
1234f1372ee1SKalderon, Michal 
1235f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "icid = %08x\n", qp->icid);
1236f1372ee1SKalderon, Michal 
123767b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
123867b40dccSKalderon, Michal 		rc = qed_iwarp_destroy_qp(p_hwfn, qp);
123967b40dccSKalderon, Michal 	else
1240f1372ee1SKalderon, Michal 		rc = qed_roce_destroy_qp(p_hwfn, qp);
1241f1372ee1SKalderon, Michal 
1242f1372ee1SKalderon, Michal 	/* free qp params struct */
1243f1372ee1SKalderon, Michal 	kfree(qp);
1244f1372ee1SKalderon, Michal 
1245f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "QP destroyed\n");
1246f1372ee1SKalderon, Michal 	return rc;
1247f1372ee1SKalderon, Michal }
1248f1372ee1SKalderon, Michal 
1249f1372ee1SKalderon, Michal static struct qed_rdma_qp *
qed_rdma_create_qp(void * rdma_cxt,struct qed_rdma_create_qp_in_params * in_params,struct qed_rdma_create_qp_out_params * out_params)1250f1372ee1SKalderon, Michal qed_rdma_create_qp(void *rdma_cxt,
1251f1372ee1SKalderon, Michal 		   struct qed_rdma_create_qp_in_params *in_params,
1252f1372ee1SKalderon, Michal 		   struct qed_rdma_create_qp_out_params *out_params)
1253f1372ee1SKalderon, Michal {
1254f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1255f1372ee1SKalderon, Michal 	struct qed_rdma_qp *qp;
1256f1372ee1SKalderon, Michal 	u8 max_stats_queues;
1257f1372ee1SKalderon, Michal 	int rc;
1258f1372ee1SKalderon, Michal 
1259291d57f6SMichal Kalderon 	if (!rdma_cxt || !in_params || !out_params ||
1260291d57f6SMichal Kalderon 	    !p_hwfn->p_rdma_info->active) {
1261d33d19d3SShai Malin 		pr_err("qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n",
1262f1372ee1SKalderon, Michal 		       rdma_cxt, in_params, out_params);
1263f1372ee1SKalderon, Michal 		return NULL;
1264f1372ee1SKalderon, Michal 	}
1265f1372ee1SKalderon, Michal 
1266f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1267f1372ee1SKalderon, Michal 		   "qed rdma create qp called with qp_handle = %08x%08x\n",
1268f1372ee1SKalderon, Michal 		   in_params->qp_handle_hi, in_params->qp_handle_lo);
1269f1372ee1SKalderon, Michal 
1270f1372ee1SKalderon, Michal 	/* Some sanity checks... */
1271f1372ee1SKalderon, Michal 	max_stats_queues = p_hwfn->p_rdma_info->dev->max_stats_queues;
1272f1372ee1SKalderon, Michal 	if (in_params->stats_queue >= max_stats_queues) {
1273f1372ee1SKalderon, Michal 		DP_ERR(p_hwfn->cdev,
1274f1372ee1SKalderon, Michal 		       "qed rdma create qp failed due to invalid statistics queue %d. maximum is %d\n",
1275f1372ee1SKalderon, Michal 		       in_params->stats_queue, max_stats_queues);
1276f1372ee1SKalderon, Michal 		return NULL;
1277f1372ee1SKalderon, Michal 	}
1278f1372ee1SKalderon, Michal 
127967b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
128067b40dccSKalderon, Michal 		if (in_params->sq_num_pages * sizeof(struct regpair) >
128167b40dccSKalderon, Michal 		    IWARP_SHARED_QUEUE_PAGE_SQ_PBL_MAX_SIZE) {
128267b40dccSKalderon, Michal 			DP_NOTICE(p_hwfn->cdev,
128367b40dccSKalderon, Michal 				  "Sq num pages: %d exceeds maximum\n",
128467b40dccSKalderon, Michal 				  in_params->sq_num_pages);
128567b40dccSKalderon, Michal 			return NULL;
128667b40dccSKalderon, Michal 		}
128767b40dccSKalderon, Michal 		if (in_params->rq_num_pages * sizeof(struct regpair) >
128867b40dccSKalderon, Michal 		    IWARP_SHARED_QUEUE_PAGE_RQ_PBL_MAX_SIZE) {
128967b40dccSKalderon, Michal 			DP_NOTICE(p_hwfn->cdev,
129067b40dccSKalderon, Michal 				  "Rq num pages: %d exceeds maximum\n",
129167b40dccSKalderon, Michal 				  in_params->rq_num_pages);
129267b40dccSKalderon, Michal 			return NULL;
129367b40dccSKalderon, Michal 		}
129467b40dccSKalderon, Michal 	}
129567b40dccSKalderon, Michal 
1296f1372ee1SKalderon, Michal 	qp = kzalloc(sizeof(*qp), GFP_KERNEL);
1297f1372ee1SKalderon, Michal 	if (!qp)
1298f1372ee1SKalderon, Michal 		return NULL;
1299f1372ee1SKalderon, Michal 
1300f1372ee1SKalderon, Michal 	qp->cur_state = QED_ROCE_QP_STATE_RESET;
1301f1372ee1SKalderon, Michal 	qp->qp_handle.hi = cpu_to_le32(in_params->qp_handle_hi);
1302f1372ee1SKalderon, Michal 	qp->qp_handle.lo = cpu_to_le32(in_params->qp_handle_lo);
1303f1372ee1SKalderon, Michal 	qp->qp_handle_async.hi = cpu_to_le32(in_params->qp_handle_async_hi);
1304f1372ee1SKalderon, Michal 	qp->qp_handle_async.lo = cpu_to_le32(in_params->qp_handle_async_lo);
1305f1372ee1SKalderon, Michal 	qp->use_srq = in_params->use_srq;
1306f1372ee1SKalderon, Michal 	qp->signal_all = in_params->signal_all;
1307f1372ee1SKalderon, Michal 	qp->fmr_and_reserved_lkey = in_params->fmr_and_reserved_lkey;
1308f1372ee1SKalderon, Michal 	qp->pd = in_params->pd;
1309f1372ee1SKalderon, Michal 	qp->dpi = in_params->dpi;
1310f1372ee1SKalderon, Michal 	qp->sq_cq_id = in_params->sq_cq_id;
1311f1372ee1SKalderon, Michal 	qp->sq_num_pages = in_params->sq_num_pages;
1312f1372ee1SKalderon, Michal 	qp->sq_pbl_ptr = in_params->sq_pbl_ptr;
1313f1372ee1SKalderon, Michal 	qp->rq_cq_id = in_params->rq_cq_id;
1314f1372ee1SKalderon, Michal 	qp->rq_num_pages = in_params->rq_num_pages;
1315f1372ee1SKalderon, Michal 	qp->rq_pbl_ptr = in_params->rq_pbl_ptr;
1316f1372ee1SKalderon, Michal 	qp->srq_id = in_params->srq_id;
1317f1372ee1SKalderon, Michal 	qp->req_offloaded = false;
1318f1372ee1SKalderon, Michal 	qp->resp_offloaded = false;
1319f1372ee1SKalderon, Michal 	qp->e2e_flow_control_en = qp->use_srq ? false : true;
1320f1372ee1SKalderon, Michal 	qp->stats_queue = in_params->stats_queue;
13217bfb399eSYuval Basson 	qp->qp_type = in_params->qp_type;
13227bfb399eSYuval Basson 	qp->xrcd_id = in_params->xrcd_id;
1323f1372ee1SKalderon, Michal 
132467b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
132567b40dccSKalderon, Michal 		rc = qed_iwarp_create_qp(p_hwfn, qp, out_params);
132667b40dccSKalderon, Michal 		qp->qpid = qp->icid;
132767b40dccSKalderon, Michal 	} else {
1328ff937b91SYuval Basson 		qp->edpm_mode = GET_FIELD(in_params->flags, QED_ROCE_EDPM_MODE);
132967b40dccSKalderon, Michal 		rc = qed_roce_alloc_cid(p_hwfn, &qp->icid);
133067b40dccSKalderon, Michal 		qp->qpid = ((0xFF << 16) | qp->icid);
133167b40dccSKalderon, Michal 	}
133267b40dccSKalderon, Michal 
133367b40dccSKalderon, Michal 	if (rc) {
133467b40dccSKalderon, Michal 		kfree(qp);
133567b40dccSKalderon, Michal 		return NULL;
133667b40dccSKalderon, Michal 	}
133767b40dccSKalderon, Michal 
1338f1372ee1SKalderon, Michal 	out_params->icid = qp->icid;
1339f1372ee1SKalderon, Michal 	out_params->qp_id = qp->qpid;
1340f1372ee1SKalderon, Michal 
1341f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Create QP, rc = %d\n", rc);
1342f1372ee1SKalderon, Michal 	return qp;
1343f1372ee1SKalderon, Michal }
1344f1372ee1SKalderon, Michal 
qed_rdma_modify_qp(void * rdma_cxt,struct qed_rdma_qp * qp,struct qed_rdma_modify_qp_in_params * params)1345f1372ee1SKalderon, Michal static int qed_rdma_modify_qp(void *rdma_cxt,
1346f1372ee1SKalderon, Michal 			      struct qed_rdma_qp *qp,
1347f1372ee1SKalderon, Michal 			      struct qed_rdma_modify_qp_in_params *params)
1348f1372ee1SKalderon, Michal {
1349f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1350f1372ee1SKalderon, Michal 	enum qed_roce_qp_state prev_state;
1351f1372ee1SKalderon, Michal 	int rc = 0;
1352f1372ee1SKalderon, Michal 
1353f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "icid = %08x params->new_state=%d\n",
1354f1372ee1SKalderon, Michal 		   qp->icid, params->new_state);
1355f1372ee1SKalderon, Michal 
1356f1372ee1SKalderon, Michal 	if (rc) {
1357f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
1358f1372ee1SKalderon, Michal 		return rc;
1359f1372ee1SKalderon, Michal 	}
1360f1372ee1SKalderon, Michal 
1361f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1362f1372ee1SKalderon, Michal 		      QED_RDMA_MODIFY_QP_VALID_RDMA_OPS_EN)) {
1363f1372ee1SKalderon, Michal 		qp->incoming_rdma_read_en = params->incoming_rdma_read_en;
1364f1372ee1SKalderon, Michal 		qp->incoming_rdma_write_en = params->incoming_rdma_write_en;
1365f1372ee1SKalderon, Michal 		qp->incoming_atomic_en = params->incoming_atomic_en;
1366f1372ee1SKalderon, Michal 	}
1367f1372ee1SKalderon, Michal 
1368f1372ee1SKalderon, Michal 	/* Update QP structure with the updated values */
1369f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags, QED_ROCE_MODIFY_QP_VALID_ROCE_MODE))
1370f1372ee1SKalderon, Michal 		qp->roce_mode = params->roce_mode;
1371f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags, QED_ROCE_MODIFY_QP_VALID_PKEY))
1372f1372ee1SKalderon, Michal 		qp->pkey = params->pkey;
1373f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1374f1372ee1SKalderon, Michal 		      QED_ROCE_MODIFY_QP_VALID_E2E_FLOW_CONTROL_EN))
1375f1372ee1SKalderon, Michal 		qp->e2e_flow_control_en = params->e2e_flow_control_en;
1376f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags, QED_ROCE_MODIFY_QP_VALID_DEST_QP))
1377f1372ee1SKalderon, Michal 		qp->dest_qp = params->dest_qp;
1378f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1379f1372ee1SKalderon, Michal 		      QED_ROCE_MODIFY_QP_VALID_ADDRESS_VECTOR)) {
1380f1372ee1SKalderon, Michal 		/* Indicates that the following parameters have changed:
1381f1372ee1SKalderon, Michal 		 * Traffic class, flow label, hop limit, source GID,
1382f1372ee1SKalderon, Michal 		 * destination GID, loopback indicator
1383f1372ee1SKalderon, Michal 		 */
1384f1372ee1SKalderon, Michal 		qp->traffic_class_tos = params->traffic_class_tos;
1385f1372ee1SKalderon, Michal 		qp->flow_label = params->flow_label;
1386f1372ee1SKalderon, Michal 		qp->hop_limit_ttl = params->hop_limit_ttl;
1387f1372ee1SKalderon, Michal 
1388f1372ee1SKalderon, Michal 		qp->sgid = params->sgid;
1389f1372ee1SKalderon, Michal 		qp->dgid = params->dgid;
1390f1372ee1SKalderon, Michal 		qp->udp_src_port = 0;
1391f1372ee1SKalderon, Michal 		qp->vlan_id = params->vlan_id;
1392f1372ee1SKalderon, Michal 		qp->mtu = params->mtu;
1393f1372ee1SKalderon, Michal 		qp->lb_indication = params->lb_indication;
1394f1372ee1SKalderon, Michal 		memcpy((u8 *)&qp->remote_mac_addr[0],
1395f1372ee1SKalderon, Michal 		       (u8 *)&params->remote_mac_addr[0], ETH_ALEN);
1396f1372ee1SKalderon, Michal 		if (params->use_local_mac) {
1397f1372ee1SKalderon, Michal 			memcpy((u8 *)&qp->local_mac_addr[0],
1398f1372ee1SKalderon, Michal 			       (u8 *)&params->local_mac_addr[0], ETH_ALEN);
1399f1372ee1SKalderon, Michal 		} else {
1400f1372ee1SKalderon, Michal 			memcpy((u8 *)&qp->local_mac_addr[0],
1401f1372ee1SKalderon, Michal 			       (u8 *)&p_hwfn->hw_info.hw_mac_addr, ETH_ALEN);
1402f1372ee1SKalderon, Michal 		}
1403f1372ee1SKalderon, Michal 	}
1404f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags, QED_ROCE_MODIFY_QP_VALID_RQ_PSN))
1405f1372ee1SKalderon, Michal 		qp->rq_psn = params->rq_psn;
1406f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags, QED_ROCE_MODIFY_QP_VALID_SQ_PSN))
1407f1372ee1SKalderon, Michal 		qp->sq_psn = params->sq_psn;
1408f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1409f1372ee1SKalderon, Michal 		      QED_RDMA_MODIFY_QP_VALID_MAX_RD_ATOMIC_REQ))
1410f1372ee1SKalderon, Michal 		qp->max_rd_atomic_req = params->max_rd_atomic_req;
1411f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1412f1372ee1SKalderon, Michal 		      QED_RDMA_MODIFY_QP_VALID_MAX_RD_ATOMIC_RESP))
1413f1372ee1SKalderon, Michal 		qp->max_rd_atomic_resp = params->max_rd_atomic_resp;
1414f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1415f1372ee1SKalderon, Michal 		      QED_ROCE_MODIFY_QP_VALID_ACK_TIMEOUT))
1416f1372ee1SKalderon, Michal 		qp->ack_timeout = params->ack_timeout;
1417f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags, QED_ROCE_MODIFY_QP_VALID_RETRY_CNT))
1418f1372ee1SKalderon, Michal 		qp->retry_cnt = params->retry_cnt;
1419f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1420f1372ee1SKalderon, Michal 		      QED_ROCE_MODIFY_QP_VALID_RNR_RETRY_CNT))
1421f1372ee1SKalderon, Michal 		qp->rnr_retry_cnt = params->rnr_retry_cnt;
1422f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1423f1372ee1SKalderon, Michal 		      QED_ROCE_MODIFY_QP_VALID_MIN_RNR_NAK_TIMER))
1424f1372ee1SKalderon, Michal 		qp->min_rnr_nak_timer = params->min_rnr_nak_timer;
1425f1372ee1SKalderon, Michal 
1426f1372ee1SKalderon, Michal 	qp->sqd_async = params->sqd_async;
1427f1372ee1SKalderon, Michal 
1428f1372ee1SKalderon, Michal 	prev_state = qp->cur_state;
1429f1372ee1SKalderon, Michal 	if (GET_FIELD(params->modify_flags,
1430f1372ee1SKalderon, Michal 		      QED_RDMA_MODIFY_QP_VALID_NEW_STATE)) {
1431f1372ee1SKalderon, Michal 		qp->cur_state = params->new_state;
1432f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "qp->cur_state=%d\n",
1433f1372ee1SKalderon, Michal 			   qp->cur_state);
1434f1372ee1SKalderon, Michal 	}
1435f1372ee1SKalderon, Michal 
14367bfb399eSYuval Basson 	switch (qp->qp_type) {
14377bfb399eSYuval Basson 	case QED_RDMA_QP_TYPE_XRC_INI:
1438889bafe9SJason Yan 		qp->has_req = true;
14397bfb399eSYuval Basson 		break;
14407bfb399eSYuval Basson 	case QED_RDMA_QP_TYPE_XRC_TGT:
1441889bafe9SJason Yan 		qp->has_resp = true;
14427bfb399eSYuval Basson 		break;
14437bfb399eSYuval Basson 	default:
1444889bafe9SJason Yan 		qp->has_req  = true;
1445889bafe9SJason Yan 		qp->has_resp = true;
14467bfb399eSYuval Basson 	}
14477bfb399eSYuval Basson 
144867b40dccSKalderon, Michal 	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
144967b40dccSKalderon, Michal 		enum qed_iwarp_qp_state new_state =
145067b40dccSKalderon, Michal 		    qed_roce2iwarp_state(qp->cur_state);
145167b40dccSKalderon, Michal 
145267b40dccSKalderon, Michal 		rc = qed_iwarp_modify_qp(p_hwfn, qp, new_state, 0);
145367b40dccSKalderon, Michal 	} else {
1454f1372ee1SKalderon, Michal 		rc = qed_roce_modify_qp(p_hwfn, qp, prev_state, params);
145567b40dccSKalderon, Michal 	}
1456f1372ee1SKalderon, Michal 
1457f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Modify QP, rc = %d\n", rc);
1458f1372ee1SKalderon, Michal 	return rc;
1459f1372ee1SKalderon, Michal }
1460f1372ee1SKalderon, Michal 
1461f1372ee1SKalderon, Michal static int
qed_rdma_register_tid(void * rdma_cxt,struct qed_rdma_register_tid_in_params * params)1462f1372ee1SKalderon, Michal qed_rdma_register_tid(void *rdma_cxt,
1463f1372ee1SKalderon, Michal 		      struct qed_rdma_register_tid_in_params *params)
1464f1372ee1SKalderon, Michal {
1465f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1466f1372ee1SKalderon, Michal 	struct rdma_register_tid_ramrod_data *p_ramrod;
1467f1372ee1SKalderon, Michal 	struct qed_sp_init_data init_data;
1468f1372ee1SKalderon, Michal 	struct qed_spq_entry *p_ent;
1469f1372ee1SKalderon, Michal 	enum rdma_tid_type tid_type;
1470f1372ee1SKalderon, Michal 	u8 fw_return_code;
14715ab90341SAlexander Lobakin 	u16 flags = 0;
1472f1372ee1SKalderon, Michal 	int rc;
1473f1372ee1SKalderon, Michal 
1474f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "itid = %08x\n", params->itid);
1475f1372ee1SKalderon, Michal 
1476f1372ee1SKalderon, Michal 	/* Get SPQ entry */
1477f1372ee1SKalderon, Michal 	memset(&init_data, 0, sizeof(init_data));
1478f1372ee1SKalderon, Michal 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
1479f1372ee1SKalderon, Michal 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
1480f1372ee1SKalderon, Michal 
1481f1372ee1SKalderon, Michal 	rc = qed_sp_init_request(p_hwfn, &p_ent, RDMA_RAMROD_REGISTER_MR,
1482f1372ee1SKalderon, Michal 				 p_hwfn->p_rdma_info->proto, &init_data);
1483f1372ee1SKalderon, Michal 	if (rc) {
1484f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
1485f1372ee1SKalderon, Michal 		return rc;
1486f1372ee1SKalderon, Michal 	}
1487f1372ee1SKalderon, Michal 
1488f1372ee1SKalderon, Michal 	if (p_hwfn->p_rdma_info->last_tid < params->itid)
1489f1372ee1SKalderon, Michal 		p_hwfn->p_rdma_info->last_tid = params->itid;
1490f1372ee1SKalderon, Michal 
14915ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_TWO_LEVEL_PBL,
1492f1372ee1SKalderon, Michal 		  params->pbl_two_level);
1493f1372ee1SKalderon, Michal 
14945ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_ZERO_BASED,
1495b3003a74SJason Gunthorpe 		  false);
1496f1372ee1SKalderon, Michal 
14975ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_PHY_MR, params->phy_mr);
1498f1372ee1SKalderon, Michal 
1499f1372ee1SKalderon, Michal 	/* Don't initialize D/C field, as it may override other bits. */
1500f1372ee1SKalderon, Michal 	if (!(params->tid_type == QED_RDMA_TID_FMR) && !(params->dma_mr))
15015ab90341SAlexander Lobakin 		SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_PAGE_SIZE_LOG,
1502f1372ee1SKalderon, Michal 			  params->page_size_log - 12);
1503f1372ee1SKalderon, Michal 
15045ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_READ,
1505f1372ee1SKalderon, Michal 		  params->remote_read);
1506f1372ee1SKalderon, Michal 
15075ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_WRITE,
1508f1372ee1SKalderon, Michal 		  params->remote_write);
1509f1372ee1SKalderon, Michal 
15105ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_ATOMIC,
1511f1372ee1SKalderon, Michal 		  params->remote_atomic);
1512f1372ee1SKalderon, Michal 
15135ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_LOCAL_WRITE,
1514f1372ee1SKalderon, Michal 		  params->local_write);
1515f1372ee1SKalderon, Michal 
15165ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_LOCAL_READ,
15175ab90341SAlexander Lobakin 		  params->local_read);
1518f1372ee1SKalderon, Michal 
15195ab90341SAlexander Lobakin 	SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_ENABLE_MW_BIND,
1520f1372ee1SKalderon, Michal 		  params->mw_bind);
1521f1372ee1SKalderon, Michal 
15225ab90341SAlexander Lobakin 	p_ramrod = &p_ent->ramrod.rdma_register_tid;
15235ab90341SAlexander Lobakin 	p_ramrod->flags = cpu_to_le16(flags);
15245ab90341SAlexander Lobakin 
1525f1372ee1SKalderon, Michal 	SET_FIELD(p_ramrod->flags1,
1526f1372ee1SKalderon, Michal 		  RDMA_REGISTER_TID_RAMROD_DATA_PBL_PAGE_SIZE_LOG,
1527f1372ee1SKalderon, Michal 		  params->pbl_page_size_log - 12);
1528f1372ee1SKalderon, Michal 
15295ab90341SAlexander Lobakin 	SET_FIELD(p_ramrod->flags2, RDMA_REGISTER_TID_RAMROD_DATA_DMA_MR,
15305ab90341SAlexander Lobakin 		  params->dma_mr);
1531f1372ee1SKalderon, Michal 
1532f1372ee1SKalderon, Michal 	switch (params->tid_type) {
1533f1372ee1SKalderon, Michal 	case QED_RDMA_TID_REGISTERED_MR:
1534f1372ee1SKalderon, Michal 		tid_type = RDMA_TID_REGISTERED_MR;
1535f1372ee1SKalderon, Michal 		break;
1536f1372ee1SKalderon, Michal 	case QED_RDMA_TID_FMR:
1537f1372ee1SKalderon, Michal 		tid_type = RDMA_TID_FMR;
1538f1372ee1SKalderon, Michal 		break;
1539d52c89f1SMichal Kalderon 	case QED_RDMA_TID_MW:
1540d52c89f1SMichal Kalderon 		tid_type = RDMA_TID_MW;
1541f1372ee1SKalderon, Michal 		break;
1542f1372ee1SKalderon, Michal 	default:
1543f1372ee1SKalderon, Michal 		rc = -EINVAL;
1544f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
1545fb5e7438SDenis Bolotin 		qed_sp_destroy_request(p_hwfn, p_ent);
1546f1372ee1SKalderon, Michal 		return rc;
1547f1372ee1SKalderon, Michal 	}
15485ab90341SAlexander Lobakin 
15495ab90341SAlexander Lobakin 	SET_FIELD(p_ramrod->flags1, RDMA_REGISTER_TID_RAMROD_DATA_TID_TYPE,
15505ab90341SAlexander Lobakin 		  tid_type);
1551f1372ee1SKalderon, Michal 
1552f1372ee1SKalderon, Michal 	p_ramrod->itid = cpu_to_le32(params->itid);
1553f1372ee1SKalderon, Michal 	p_ramrod->key = params->key;
1554f1372ee1SKalderon, Michal 	p_ramrod->pd = cpu_to_le16(params->pd);
1555f1372ee1SKalderon, Michal 	p_ramrod->length_hi = (u8)(params->length >> 32);
1556f1372ee1SKalderon, Michal 	p_ramrod->length_lo = DMA_LO_LE(params->length);
1557f1372ee1SKalderon, Michal 	DMA_REGPAIR_LE(p_ramrod->va, params->vaddr);
1558f1372ee1SKalderon, Michal 	DMA_REGPAIR_LE(p_ramrod->pbl_base, params->pbl_ptr);
1559f1372ee1SKalderon, Michal 
1560f1372ee1SKalderon, Michal 	/* DIF */
1561f1372ee1SKalderon, Michal 	if (params->dif_enabled) {
1562f1372ee1SKalderon, Michal 		SET_FIELD(p_ramrod->flags2,
1563f1372ee1SKalderon, Michal 			  RDMA_REGISTER_TID_RAMROD_DATA_DIF_ON_HOST_FLG, 1);
1564f1372ee1SKalderon, Michal 		DMA_REGPAIR_LE(p_ramrod->dif_error_addr,
1565f1372ee1SKalderon, Michal 			       params->dif_error_addr);
1566f1372ee1SKalderon, Michal 	}
1567f1372ee1SKalderon, Michal 
1568f1372ee1SKalderon, Michal 	rc = qed_spq_post(p_hwfn, p_ent, &fw_return_code);
1569f1372ee1SKalderon, Michal 	if (rc)
1570f1372ee1SKalderon, Michal 		return rc;
1571f1372ee1SKalderon, Michal 
1572f1372ee1SKalderon, Michal 	if (fw_return_code != RDMA_RETURN_OK) {
1573f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn, "fw_return_code = %d\n", fw_return_code);
1574f1372ee1SKalderon, Michal 		return -EINVAL;
1575f1372ee1SKalderon, Michal 	}
1576f1372ee1SKalderon, Michal 
1577f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Register TID, rc = %d\n", rc);
1578f1372ee1SKalderon, Michal 	return rc;
1579f1372ee1SKalderon, Michal }
1580f1372ee1SKalderon, Michal 
qed_rdma_deregister_tid(void * rdma_cxt,u32 itid)1581f1372ee1SKalderon, Michal static int qed_rdma_deregister_tid(void *rdma_cxt, u32 itid)
1582f1372ee1SKalderon, Michal {
1583f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1584f1372ee1SKalderon, Michal 	struct rdma_deregister_tid_ramrod_data *p_ramrod;
1585f1372ee1SKalderon, Michal 	struct qed_sp_init_data init_data;
1586f1372ee1SKalderon, Michal 	struct qed_spq_entry *p_ent;
1587f1372ee1SKalderon, Michal 	struct qed_ptt *p_ptt;
1588f1372ee1SKalderon, Michal 	u8 fw_return_code;
1589f1372ee1SKalderon, Michal 	int rc;
1590f1372ee1SKalderon, Michal 
1591f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "itid = %08x\n", itid);
1592f1372ee1SKalderon, Michal 
1593f1372ee1SKalderon, Michal 	/* Get SPQ entry */
1594f1372ee1SKalderon, Michal 	memset(&init_data, 0, sizeof(init_data));
1595f1372ee1SKalderon, Michal 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
1596f1372ee1SKalderon, Michal 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
1597f1372ee1SKalderon, Michal 
1598f1372ee1SKalderon, Michal 	rc = qed_sp_init_request(p_hwfn, &p_ent, RDMA_RAMROD_DEREGISTER_MR,
1599f1372ee1SKalderon, Michal 				 p_hwfn->p_rdma_info->proto, &init_data);
1600f1372ee1SKalderon, Michal 	if (rc) {
1601f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
1602f1372ee1SKalderon, Michal 		return rc;
1603f1372ee1SKalderon, Michal 	}
1604f1372ee1SKalderon, Michal 
1605f1372ee1SKalderon, Michal 	p_ramrod = &p_ent->ramrod.rdma_deregister_tid;
1606f1372ee1SKalderon, Michal 	p_ramrod->itid = cpu_to_le32(itid);
1607f1372ee1SKalderon, Michal 
1608f1372ee1SKalderon, Michal 	rc = qed_spq_post(p_hwfn, p_ent, &fw_return_code);
1609f1372ee1SKalderon, Michal 	if (rc) {
1610f1372ee1SKalderon, Michal 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
1611f1372ee1SKalderon, Michal 		return rc;
1612f1372ee1SKalderon, Michal 	}
1613f1372ee1SKalderon, Michal 
1614f1372ee1SKalderon, Michal 	if (fw_return_code == RDMA_RETURN_DEREGISTER_MR_BAD_STATE_ERR) {
1615f1372ee1SKalderon, Michal 		DP_NOTICE(p_hwfn, "fw_return_code = %d\n", fw_return_code);
1616f1372ee1SKalderon, Michal 		return -EINVAL;
1617f1372ee1SKalderon, Michal 	} else if (fw_return_code == RDMA_RETURN_NIG_DRAIN_REQ) {
1618f1372ee1SKalderon, Michal 		/* Bit indicating that the TID is in use and a nig drain is
1619f1372ee1SKalderon, Michal 		 * required before sending the ramrod again
1620f1372ee1SKalderon, Michal 		 */
1621f1372ee1SKalderon, Michal 		p_ptt = qed_ptt_acquire(p_hwfn);
1622f1372ee1SKalderon, Michal 		if (!p_ptt) {
1623f1372ee1SKalderon, Michal 			rc = -EBUSY;
1624f1372ee1SKalderon, Michal 			DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1625f1372ee1SKalderon, Michal 				   "Failed to acquire PTT\n");
1626f1372ee1SKalderon, Michal 			return rc;
1627f1372ee1SKalderon, Michal 		}
1628f1372ee1SKalderon, Michal 
1629f1372ee1SKalderon, Michal 		rc = qed_mcp_drain(p_hwfn, p_ptt);
1630f1372ee1SKalderon, Michal 		if (rc) {
1631f1372ee1SKalderon, Michal 			qed_ptt_release(p_hwfn, p_ptt);
1632f1372ee1SKalderon, Michal 			DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1633f1372ee1SKalderon, Michal 				   "Drain failed\n");
1634f1372ee1SKalderon, Michal 			return rc;
1635f1372ee1SKalderon, Michal 		}
1636f1372ee1SKalderon, Michal 
1637f1372ee1SKalderon, Michal 		qed_ptt_release(p_hwfn, p_ptt);
1638f1372ee1SKalderon, Michal 
1639f1372ee1SKalderon, Michal 		/* Resend the ramrod */
1640f1372ee1SKalderon, Michal 		rc = qed_sp_init_request(p_hwfn, &p_ent,
1641f1372ee1SKalderon, Michal 					 RDMA_RAMROD_DEREGISTER_MR,
1642f1372ee1SKalderon, Michal 					 p_hwfn->p_rdma_info->proto,
1643f1372ee1SKalderon, Michal 					 &init_data);
1644f1372ee1SKalderon, Michal 		if (rc) {
1645f1372ee1SKalderon, Michal 			DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1646f1372ee1SKalderon, Michal 				   "Failed to init sp-element\n");
1647f1372ee1SKalderon, Michal 			return rc;
1648f1372ee1SKalderon, Michal 		}
1649f1372ee1SKalderon, Michal 
1650f1372ee1SKalderon, Michal 		rc = qed_spq_post(p_hwfn, p_ent, &fw_return_code);
1651f1372ee1SKalderon, Michal 		if (rc) {
1652f1372ee1SKalderon, Michal 			DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1653f1372ee1SKalderon, Michal 				   "Ramrod failed\n");
1654f1372ee1SKalderon, Michal 			return rc;
1655f1372ee1SKalderon, Michal 		}
1656f1372ee1SKalderon, Michal 
1657f1372ee1SKalderon, Michal 		if (fw_return_code != RDMA_RETURN_OK) {
1658f1372ee1SKalderon, Michal 			DP_NOTICE(p_hwfn, "fw_return_code = %d\n",
1659f1372ee1SKalderon, Michal 				  fw_return_code);
1660f1372ee1SKalderon, Michal 			return rc;
1661f1372ee1SKalderon, Michal 		}
1662f1372ee1SKalderon, Michal 	}
1663f1372ee1SKalderon, Michal 
1664f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "De-registered TID, rc = %d\n", rc);
1665f1372ee1SKalderon, Michal 	return rc;
1666f1372ee1SKalderon, Michal }
1667f1372ee1SKalderon, Michal 
qed_rdma_get_rdma_ctx(struct qed_dev * cdev)1668f1372ee1SKalderon, Michal static void *qed_rdma_get_rdma_ctx(struct qed_dev *cdev)
1669f1372ee1SKalderon, Michal {
16707e50769cSMichal Kalderon 	return QED_AFFIN_HWFN(cdev);
1671f1372ee1SKalderon, Michal }
1672f1372ee1SKalderon, Michal 
qed_rdma_get_srq_bmap(struct qed_hwfn * p_hwfn,bool is_xrc)16737bfb399eSYuval Basson static struct qed_bmap *qed_rdma_get_srq_bmap(struct qed_hwfn *p_hwfn,
16747bfb399eSYuval Basson 					      bool is_xrc)
16757bfb399eSYuval Basson {
16767bfb399eSYuval Basson 	if (is_xrc)
16777bfb399eSYuval Basson 		return &p_hwfn->p_rdma_info->xrc_srq_map;
16787bfb399eSYuval Basson 
16797bfb399eSYuval Basson 	return &p_hwfn->p_rdma_info->srq_map;
16807bfb399eSYuval Basson }
16817bfb399eSYuval Basson 
qed_rdma_modify_srq(void * rdma_cxt,struct qed_rdma_modify_srq_in_params * in_params)168239dbc646SYuval Bason static int qed_rdma_modify_srq(void *rdma_cxt,
168339dbc646SYuval Bason 			       struct qed_rdma_modify_srq_in_params *in_params)
168439dbc646SYuval Bason {
168539dbc646SYuval Bason 	struct rdma_srq_modify_ramrod_data *p_ramrod;
168639dbc646SYuval Bason 	struct qed_sp_init_data init_data = {};
168739dbc646SYuval Bason 	struct qed_hwfn *p_hwfn = rdma_cxt;
168839dbc646SYuval Bason 	struct qed_spq_entry *p_ent;
168939dbc646SYuval Bason 	u16 opaque_fid;
169039dbc646SYuval Bason 	int rc;
169139dbc646SYuval Bason 
169239dbc646SYuval Bason 	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
169339dbc646SYuval Bason 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
169439dbc646SYuval Bason 
169539dbc646SYuval Bason 	rc = qed_sp_init_request(p_hwfn, &p_ent,
169639dbc646SYuval Bason 				 RDMA_RAMROD_MODIFY_SRQ,
169739dbc646SYuval Bason 				 p_hwfn->p_rdma_info->proto, &init_data);
169839dbc646SYuval Bason 	if (rc)
169939dbc646SYuval Bason 		return rc;
170039dbc646SYuval Bason 
170139dbc646SYuval Bason 	p_ramrod = &p_ent->ramrod.rdma_modify_srq;
170239dbc646SYuval Bason 	p_ramrod->srq_id.srq_idx = cpu_to_le16(in_params->srq_id);
170339dbc646SYuval Bason 	opaque_fid = p_hwfn->hw_info.opaque_fid;
170439dbc646SYuval Bason 	p_ramrod->srq_id.opaque_fid = cpu_to_le16(opaque_fid);
170539dbc646SYuval Bason 	p_ramrod->wqe_limit = cpu_to_le32(in_params->wqe_limit);
170639dbc646SYuval Bason 
170739dbc646SYuval Bason 	rc = qed_spq_post(p_hwfn, p_ent, NULL);
170839dbc646SYuval Bason 	if (rc)
170939dbc646SYuval Bason 		return rc;
171039dbc646SYuval Bason 
17117bfb399eSYuval Basson 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "modified SRQ id = %x, is_xrc=%u\n",
17127bfb399eSYuval Basson 		   in_params->srq_id, in_params->is_xrc);
171339dbc646SYuval Bason 
171439dbc646SYuval Bason 	return rc;
171539dbc646SYuval Bason }
171639dbc646SYuval Bason 
171739dbc646SYuval Bason static int
qed_rdma_destroy_srq(void * rdma_cxt,struct qed_rdma_destroy_srq_in_params * in_params)171839dbc646SYuval Bason qed_rdma_destroy_srq(void *rdma_cxt,
171939dbc646SYuval Bason 		     struct qed_rdma_destroy_srq_in_params *in_params)
172039dbc646SYuval Bason {
172139dbc646SYuval Bason 	struct rdma_srq_destroy_ramrod_data *p_ramrod;
172239dbc646SYuval Bason 	struct qed_sp_init_data init_data = {};
172339dbc646SYuval Bason 	struct qed_hwfn *p_hwfn = rdma_cxt;
172439dbc646SYuval Bason 	struct qed_spq_entry *p_ent;
172539dbc646SYuval Bason 	struct qed_bmap *bmap;
172639dbc646SYuval Bason 	u16 opaque_fid;
17277bfb399eSYuval Basson 	u16 offset;
172839dbc646SYuval Bason 	int rc;
172939dbc646SYuval Bason 
173039dbc646SYuval Bason 	opaque_fid = p_hwfn->hw_info.opaque_fid;
173139dbc646SYuval Bason 
173239dbc646SYuval Bason 	init_data.opaque_fid = opaque_fid;
173339dbc646SYuval Bason 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
173439dbc646SYuval Bason 
173539dbc646SYuval Bason 	rc = qed_sp_init_request(p_hwfn, &p_ent,
173639dbc646SYuval Bason 				 RDMA_RAMROD_DESTROY_SRQ,
173739dbc646SYuval Bason 				 p_hwfn->p_rdma_info->proto, &init_data);
173839dbc646SYuval Bason 	if (rc)
173939dbc646SYuval Bason 		return rc;
174039dbc646SYuval Bason 
174139dbc646SYuval Bason 	p_ramrod = &p_ent->ramrod.rdma_destroy_srq;
174239dbc646SYuval Bason 	p_ramrod->srq_id.srq_idx = cpu_to_le16(in_params->srq_id);
174339dbc646SYuval Bason 	p_ramrod->srq_id.opaque_fid = cpu_to_le16(opaque_fid);
174439dbc646SYuval Bason 
174539dbc646SYuval Bason 	rc = qed_spq_post(p_hwfn, p_ent, NULL);
174639dbc646SYuval Bason 	if (rc)
174739dbc646SYuval Bason 		return rc;
174839dbc646SYuval Bason 
17497bfb399eSYuval Basson 	bmap = qed_rdma_get_srq_bmap(p_hwfn, in_params->is_xrc);
17507bfb399eSYuval Basson 	offset = (in_params->is_xrc) ? 0 : p_hwfn->p_rdma_info->srq_id_offset;
175139dbc646SYuval Bason 
175239dbc646SYuval Bason 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
17537bfb399eSYuval Basson 	qed_bmap_release_id(p_hwfn, bmap, in_params->srq_id - offset);
175439dbc646SYuval Bason 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
175539dbc646SYuval Bason 
17567bfb399eSYuval Basson 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
17577bfb399eSYuval Basson 		   "XRC/SRQ destroyed Id = %x, is_xrc=%u\n",
17587bfb399eSYuval Basson 		   in_params->srq_id, in_params->is_xrc);
175939dbc646SYuval Bason 
176039dbc646SYuval Bason 	return rc;
176139dbc646SYuval Bason }
176239dbc646SYuval Bason 
176339dbc646SYuval Bason static int
qed_rdma_create_srq(void * rdma_cxt,struct qed_rdma_create_srq_in_params * in_params,struct qed_rdma_create_srq_out_params * out_params)176439dbc646SYuval Bason qed_rdma_create_srq(void *rdma_cxt,
176539dbc646SYuval Bason 		    struct qed_rdma_create_srq_in_params *in_params,
176639dbc646SYuval Bason 		    struct qed_rdma_create_srq_out_params *out_params)
176739dbc646SYuval Bason {
176839dbc646SYuval Bason 	struct rdma_srq_create_ramrod_data *p_ramrod;
176939dbc646SYuval Bason 	struct qed_sp_init_data init_data = {};
177039dbc646SYuval Bason 	struct qed_hwfn *p_hwfn = rdma_cxt;
177139dbc646SYuval Bason 	enum qed_cxt_elem_type elem_type;
177239dbc646SYuval Bason 	struct qed_spq_entry *p_ent;
177339dbc646SYuval Bason 	u16 opaque_fid, srq_id;
177439dbc646SYuval Bason 	struct qed_bmap *bmap;
177539dbc646SYuval Bason 	u32 returned_id;
17767bfb399eSYuval Basson 	u16 offset;
177739dbc646SYuval Bason 	int rc;
177839dbc646SYuval Bason 
17797bfb399eSYuval Basson 	bmap = qed_rdma_get_srq_bmap(p_hwfn, in_params->is_xrc);
178039dbc646SYuval Bason 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
178139dbc646SYuval Bason 	rc = qed_rdma_bmap_alloc_id(p_hwfn, bmap, &returned_id);
178239dbc646SYuval Bason 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
178339dbc646SYuval Bason 
178439dbc646SYuval Bason 	if (rc) {
17857bfb399eSYuval Basson 		DP_NOTICE(p_hwfn,
17867bfb399eSYuval Basson 			  "failed to allocate xrc/srq id (is_xrc=%u)\n",
17877bfb399eSYuval Basson 			  in_params->is_xrc);
178839dbc646SYuval Bason 		return rc;
178939dbc646SYuval Bason 	}
179039dbc646SYuval Bason 
17917bfb399eSYuval Basson 	elem_type = (in_params->is_xrc) ? (QED_ELEM_XRC_SRQ) : (QED_ELEM_SRQ);
179239dbc646SYuval Bason 	rc = qed_cxt_dynamic_ilt_alloc(p_hwfn, elem_type, returned_id);
179339dbc646SYuval Bason 	if (rc)
179439dbc646SYuval Bason 		goto err;
17957bfb399eSYuval Basson 
179639dbc646SYuval Bason 	opaque_fid = p_hwfn->hw_info.opaque_fid;
179739dbc646SYuval Bason 
179839dbc646SYuval Bason 	opaque_fid = p_hwfn->hw_info.opaque_fid;
179939dbc646SYuval Bason 	init_data.opaque_fid = opaque_fid;
180039dbc646SYuval Bason 	init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
180139dbc646SYuval Bason 
180239dbc646SYuval Bason 	rc = qed_sp_init_request(p_hwfn, &p_ent,
180339dbc646SYuval Bason 				 RDMA_RAMROD_CREATE_SRQ,
180439dbc646SYuval Bason 				 p_hwfn->p_rdma_info->proto, &init_data);
180539dbc646SYuval Bason 	if (rc)
180639dbc646SYuval Bason 		goto err;
180739dbc646SYuval Bason 
180839dbc646SYuval Bason 	p_ramrod = &p_ent->ramrod.rdma_create_srq;
180939dbc646SYuval Bason 	DMA_REGPAIR_LE(p_ramrod->pbl_base_addr, in_params->pbl_base_addr);
181039dbc646SYuval Bason 	p_ramrod->pages_in_srq_pbl = cpu_to_le16(in_params->num_pages);
181139dbc646SYuval Bason 	p_ramrod->pd_id = cpu_to_le16(in_params->pd_id);
181239dbc646SYuval Bason 	p_ramrod->srq_id.opaque_fid = cpu_to_le16(opaque_fid);
181339dbc646SYuval Bason 	p_ramrod->page_size = cpu_to_le16(in_params->page_size);
181439dbc646SYuval Bason 	DMA_REGPAIR_LE(p_ramrod->producers_addr, in_params->prod_pair_addr);
18157bfb399eSYuval Basson 	offset = (in_params->is_xrc) ? 0 : p_hwfn->p_rdma_info->srq_id_offset;
18167bfb399eSYuval Basson 	srq_id = (u16)returned_id + offset;
18177bfb399eSYuval Basson 	p_ramrod->srq_id.srq_idx = cpu_to_le16(srq_id);
181839dbc646SYuval Bason 
18197bfb399eSYuval Basson 	if (in_params->is_xrc) {
18207bfb399eSYuval Basson 		SET_FIELD(p_ramrod->flags,
18217bfb399eSYuval Basson 			  RDMA_SRQ_CREATE_RAMROD_DATA_XRC_FLAG, 1);
18227bfb399eSYuval Basson 		SET_FIELD(p_ramrod->flags,
18237bfb399eSYuval Basson 			  RDMA_SRQ_CREATE_RAMROD_DATA_RESERVED_KEY_EN,
18247bfb399eSYuval Basson 			  in_params->reserved_key_en);
18257bfb399eSYuval Basson 		p_ramrod->xrc_srq_cq_cid =
18267bfb399eSYuval Basson 			cpu_to_le32((p_hwfn->hw_info.opaque_fid << 16) |
18277bfb399eSYuval Basson 				     in_params->cq_cid);
18287bfb399eSYuval Basson 		p_ramrod->xrc_domain = cpu_to_le16(in_params->xrcd_id);
18297bfb399eSYuval Basson 	}
183039dbc646SYuval Bason 	rc = qed_spq_post(p_hwfn, p_ent, NULL);
183139dbc646SYuval Bason 	if (rc)
183239dbc646SYuval Bason 		goto err;
183339dbc646SYuval Bason 
183439dbc646SYuval Bason 	out_params->srq_id = srq_id;
183539dbc646SYuval Bason 
18367bfb399eSYuval Basson 	DP_VERBOSE(p_hwfn,
18377bfb399eSYuval Basson 		   QED_MSG_RDMA,
18387bfb399eSYuval Basson 		   "XRC/SRQ created Id = %x (is_xrc=%u)\n",
18397bfb399eSYuval Basson 		   out_params->srq_id, in_params->is_xrc);
184039dbc646SYuval Bason 	return rc;
184139dbc646SYuval Bason 
184239dbc646SYuval Bason err:
184339dbc646SYuval Bason 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
184439dbc646SYuval Bason 	qed_bmap_release_id(p_hwfn, bmap, returned_id);
184539dbc646SYuval Bason 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
184639dbc646SYuval Bason 
184739dbc646SYuval Bason 	return rc;
184839dbc646SYuval Bason }
184939dbc646SYuval Bason 
qed_rdma_allocated_qps(struct qed_hwfn * p_hwfn)1850b71b9afdSKalderon, Michal bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn)
1851f1372ee1SKalderon, Michal {
1852f1372ee1SKalderon, Michal 	bool result;
1853f1372ee1SKalderon, Michal 
1854291d57f6SMichal Kalderon 	/* if rdma wasn't activated yet, naturally there are no qps */
1855291d57f6SMichal Kalderon 	if (!p_hwfn->p_rdma_info->active)
1856f1372ee1SKalderon, Michal 		return false;
1857f1372ee1SKalderon, Michal 
1858f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
1859f1372ee1SKalderon, Michal 	if (!p_hwfn->p_rdma_info->cid_map.bitmap)
1860f1372ee1SKalderon, Michal 		result = false;
1861f1372ee1SKalderon, Michal 	else
1862f1372ee1SKalderon, Michal 		result = !qed_bmap_is_empty(&p_hwfn->p_rdma_info->cid_map);
1863f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
1864f1372ee1SKalderon, Michal 	return result;
1865f1372ee1SKalderon, Michal }
1866f1372ee1SKalderon, Michal 
qed_rdma_dpm_conf(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)1867b71b9afdSKalderon, Michal void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1868f1372ee1SKalderon, Michal {
1869f1372ee1SKalderon, Michal 	u32 val;
1870f1372ee1SKalderon, Michal 
1871f1372ee1SKalderon, Michal 	val = (p_hwfn->dcbx_no_edpm || p_hwfn->db_bar_no_edpm) ? 0 : 1;
1872f1372ee1SKalderon, Michal 
1873f1372ee1SKalderon, Michal 	qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_DPM_ENABLE, val);
1874f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, (QED_MSG_DCB | QED_MSG_RDMA),
1875f1372ee1SKalderon, Michal 		   "Changing DPM_EN state to %d (DCBX=%d, DB_BAR=%d)\n",
1876f1372ee1SKalderon, Michal 		   val, p_hwfn->dcbx_no_edpm, p_hwfn->db_bar_no_edpm);
1877f1372ee1SKalderon, Michal }
1878f1372ee1SKalderon, Michal 
qed_rdma_dpm_bar(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)1879f1372ee1SKalderon, Michal void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1880f1372ee1SKalderon, Michal {
1881f1372ee1SKalderon, Michal 	p_hwfn->db_bar_no_edpm = true;
1882f1372ee1SKalderon, Michal 
1883f1372ee1SKalderon, Michal 	qed_rdma_dpm_conf(p_hwfn, p_ptt);
1884f1372ee1SKalderon, Michal }
1885f1372ee1SKalderon, Michal 
qed_rdma_start(void * rdma_cxt,struct qed_rdma_start_in_params * params)1886f1372ee1SKalderon, Michal static int qed_rdma_start(void *rdma_cxt,
1887f1372ee1SKalderon, Michal 			  struct qed_rdma_start_in_params *params)
1888f1372ee1SKalderon, Michal {
1889f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1890f1372ee1SKalderon, Michal 	struct qed_ptt *p_ptt;
1891f1372ee1SKalderon, Michal 	int rc = -EBUSY;
1892f1372ee1SKalderon, Michal 
1893f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
1894f1372ee1SKalderon, Michal 		   "desired_cnq = %08x\n", params->desired_cnq);
1895f1372ee1SKalderon, Michal 
1896f1372ee1SKalderon, Michal 	p_ptt = qed_ptt_acquire(p_hwfn);
1897f1372ee1SKalderon, Michal 	if (!p_ptt)
1898f1372ee1SKalderon, Michal 		goto err;
1899f1372ee1SKalderon, Michal 
1900291d57f6SMichal Kalderon 	rc = qed_rdma_alloc(p_hwfn);
1901f1372ee1SKalderon, Michal 	if (rc)
1902f1372ee1SKalderon, Michal 		goto err1;
1903f1372ee1SKalderon, Michal 
1904f1372ee1SKalderon, Michal 	rc = qed_rdma_setup(p_hwfn, p_ptt, params);
1905f1372ee1SKalderon, Michal 	if (rc)
1906f1372ee1SKalderon, Michal 		goto err2;
1907f1372ee1SKalderon, Michal 
1908f1372ee1SKalderon, Michal 	qed_ptt_release(p_hwfn, p_ptt);
1909291d57f6SMichal Kalderon 	p_hwfn->p_rdma_info->active = 1;
1910f1372ee1SKalderon, Michal 
1911f1372ee1SKalderon, Michal 	return rc;
1912f1372ee1SKalderon, Michal 
1913f1372ee1SKalderon, Michal err2:
1914f1372ee1SKalderon, Michal 	qed_rdma_free(p_hwfn);
1915f1372ee1SKalderon, Michal err1:
1916f1372ee1SKalderon, Michal 	qed_ptt_release(p_hwfn, p_ptt);
1917f1372ee1SKalderon, Michal err:
1918f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA start - error, rc = %d\n", rc);
1919f1372ee1SKalderon, Michal 	return rc;
1920f1372ee1SKalderon, Michal }
1921f1372ee1SKalderon, Michal 
qed_rdma_init(struct qed_dev * cdev,struct qed_rdma_start_in_params * params)1922f1372ee1SKalderon, Michal static int qed_rdma_init(struct qed_dev *cdev,
1923f1372ee1SKalderon, Michal 			 struct qed_rdma_start_in_params *params)
1924f1372ee1SKalderon, Michal {
19257e50769cSMichal Kalderon 	return qed_rdma_start(QED_AFFIN_HWFN(cdev), params);
1926f1372ee1SKalderon, Michal }
1927f1372ee1SKalderon, Michal 
qed_rdma_remove_user(void * rdma_cxt,u16 dpi)1928f1372ee1SKalderon, Michal static void qed_rdma_remove_user(void *rdma_cxt, u16 dpi)
1929f1372ee1SKalderon, Michal {
1930f1372ee1SKalderon, Michal 	struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
1931f1372ee1SKalderon, Michal 
1932f1372ee1SKalderon, Michal 	DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "dpi = %08x\n", dpi);
1933f1372ee1SKalderon, Michal 
1934f1372ee1SKalderon, Michal 	spin_lock_bh(&p_hwfn->p_rdma_info->lock);
1935f1372ee1SKalderon, Michal 	qed_bmap_release_id(p_hwfn, &p_hwfn->p_rdma_info->dpi_map, dpi);
1936f1372ee1SKalderon, Michal 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
1937f1372ee1SKalderon, Michal }
1938f1372ee1SKalderon, Michal 
qed_roce_ll2_set_mac_filter(struct qed_dev * cdev,u8 * old_mac_address,const u8 * new_mac_address)1939f1372ee1SKalderon, Michal static int qed_roce_ll2_set_mac_filter(struct qed_dev *cdev,
1940f1372ee1SKalderon, Michal 				       u8 *old_mac_address,
194176660757SJakub Kicinski 				       const u8 *new_mac_address)
1942f1372ee1SKalderon, Michal {
1943f1372ee1SKalderon, Michal 	int rc = 0;
1944f1372ee1SKalderon, Michal 
1945f1372ee1SKalderon, Michal 	if (old_mac_address)
194679284adeSMichal Kalderon 		qed_llh_remove_mac_filter(cdev, 0, old_mac_address);
1947f1372ee1SKalderon, Michal 	if (new_mac_address)
194879284adeSMichal Kalderon 		rc = qed_llh_add_mac_filter(cdev, 0, new_mac_address);
1949f1372ee1SKalderon, Michal 
1950f1372ee1SKalderon, Michal 	if (rc)
1951f1372ee1SKalderon, Michal 		DP_ERR(cdev,
1952f1372ee1SKalderon, Michal 		       "qed roce ll2 mac filter set: failed to add MAC filter\n");
1953f1372ee1SKalderon, Michal 
1954f1372ee1SKalderon, Michal 	return rc;
1955f1372ee1SKalderon, Michal }
1956f1372ee1SKalderon, Michal 
qed_iwarp_set_engine_affin(struct qed_dev * cdev,bool b_reset)19573576e99eSMichal Kalderon static int qed_iwarp_set_engine_affin(struct qed_dev *cdev, bool b_reset)
19583576e99eSMichal Kalderon {
19593576e99eSMichal Kalderon 	enum qed_eng eng;
19603576e99eSMichal Kalderon 	u8 ppfid = 0;
19613576e99eSMichal Kalderon 	int rc;
19623576e99eSMichal Kalderon 
19633576e99eSMichal Kalderon 	/* Make sure iwarp cmt mode is enabled before setting affinity */
19643576e99eSMichal Kalderon 	if (!cdev->iwarp_cmt)
19653576e99eSMichal Kalderon 		return -EINVAL;
19663576e99eSMichal Kalderon 
19673576e99eSMichal Kalderon 	if (b_reset)
19683576e99eSMichal Kalderon 		eng = QED_BOTH_ENG;
19693576e99eSMichal Kalderon 	else
19703576e99eSMichal Kalderon 		eng = cdev->l2_affin_hint ? QED_ENG1 : QED_ENG0;
19713576e99eSMichal Kalderon 
19723576e99eSMichal Kalderon 	rc = qed_llh_set_ppfid_affinity(cdev, ppfid, eng);
19733576e99eSMichal Kalderon 	if (rc) {
19743576e99eSMichal Kalderon 		DP_NOTICE(cdev,
19753576e99eSMichal Kalderon 			  "Failed to set the engine affinity of ppfid %d\n",
19763576e99eSMichal Kalderon 			  ppfid);
19773576e99eSMichal Kalderon 		return rc;
19783576e99eSMichal Kalderon 	}
19793576e99eSMichal Kalderon 
19803576e99eSMichal Kalderon 	DP_VERBOSE(cdev, (QED_MSG_RDMA | QED_MSG_SP),
19813576e99eSMichal Kalderon 		   "LLH: Set the engine affinity of non-RoCE packets as %d\n",
19823576e99eSMichal Kalderon 		   eng);
19833576e99eSMichal Kalderon 
19843576e99eSMichal Kalderon 	return 0;
19853576e99eSMichal Kalderon }
19863576e99eSMichal Kalderon 
1987f1372ee1SKalderon, Michal static const struct qed_rdma_ops qed_rdma_ops_pass = {
1988f1372ee1SKalderon, Michal 	.common = &qed_common_ops_pass,
1989f1372ee1SKalderon, Michal 	.fill_dev_info = &qed_fill_rdma_dev_info,
1990f1372ee1SKalderon, Michal 	.rdma_get_rdma_ctx = &qed_rdma_get_rdma_ctx,
1991f1372ee1SKalderon, Michal 	.rdma_init = &qed_rdma_init,
1992f1372ee1SKalderon, Michal 	.rdma_add_user = &qed_rdma_add_user,
1993f1372ee1SKalderon, Michal 	.rdma_remove_user = &qed_rdma_remove_user,
1994f1372ee1SKalderon, Michal 	.rdma_stop = &qed_rdma_stop,
1995f1372ee1SKalderon, Michal 	.rdma_query_port = &qed_rdma_query_port,
1996f1372ee1SKalderon, Michal 	.rdma_query_device = &qed_rdma_query_device,
1997f1372ee1SKalderon, Michal 	.rdma_get_start_sb = &qed_rdma_get_sb_start,
1998f1372ee1SKalderon, Michal 	.rdma_get_rdma_int = &qed_rdma_get_int,
1999f1372ee1SKalderon, Michal 	.rdma_set_rdma_int = &qed_rdma_set_int,
2000f1372ee1SKalderon, Michal 	.rdma_get_min_cnq_msix = &qed_rdma_get_min_cnq_msix,
2001f1372ee1SKalderon, Michal 	.rdma_cnq_prod_update = &qed_rdma_cnq_prod_update,
2002f1372ee1SKalderon, Michal 	.rdma_alloc_pd = &qed_rdma_alloc_pd,
2003f1372ee1SKalderon, Michal 	.rdma_dealloc_pd = &qed_rdma_free_pd,
20047bfb399eSYuval Basson 	.rdma_alloc_xrcd = &qed_rdma_alloc_xrcd,
20057bfb399eSYuval Basson 	.rdma_dealloc_xrcd = &qed_rdma_free_xrcd,
2006f1372ee1SKalderon, Michal 	.rdma_create_cq = &qed_rdma_create_cq,
2007f1372ee1SKalderon, Michal 	.rdma_destroy_cq = &qed_rdma_destroy_cq,
2008f1372ee1SKalderon, Michal 	.rdma_create_qp = &qed_rdma_create_qp,
2009f1372ee1SKalderon, Michal 	.rdma_modify_qp = &qed_rdma_modify_qp,
2010f1372ee1SKalderon, Michal 	.rdma_query_qp = &qed_rdma_query_qp,
2011f1372ee1SKalderon, Michal 	.rdma_destroy_qp = &qed_rdma_destroy_qp,
2012f1372ee1SKalderon, Michal 	.rdma_alloc_tid = &qed_rdma_alloc_tid,
2013f1372ee1SKalderon, Michal 	.rdma_free_tid = &qed_rdma_free_tid,
2014f1372ee1SKalderon, Michal 	.rdma_register_tid = &qed_rdma_register_tid,
2015f1372ee1SKalderon, Michal 	.rdma_deregister_tid = &qed_rdma_deregister_tid,
201639dbc646SYuval Bason 	.rdma_create_srq = &qed_rdma_create_srq,
201739dbc646SYuval Bason 	.rdma_modify_srq = &qed_rdma_modify_srq,
201839dbc646SYuval Bason 	.rdma_destroy_srq = &qed_rdma_destroy_srq,
2019f1372ee1SKalderon, Michal 	.ll2_acquire_connection = &qed_ll2_acquire_connection,
2020f1372ee1SKalderon, Michal 	.ll2_establish_connection = &qed_ll2_establish_connection,
2021f1372ee1SKalderon, Michal 	.ll2_terminate_connection = &qed_ll2_terminate_connection,
2022f1372ee1SKalderon, Michal 	.ll2_release_connection = &qed_ll2_release_connection,
2023f1372ee1SKalderon, Michal 	.ll2_post_rx_buffer = &qed_ll2_post_rx_buffer,
2024f1372ee1SKalderon, Michal 	.ll2_prepare_tx_packet = &qed_ll2_prepare_tx_packet,
2025f1372ee1SKalderon, Michal 	.ll2_set_fragment_of_tx_packet = &qed_ll2_set_fragment_of_tx_packet,
2026f1372ee1SKalderon, Michal 	.ll2_set_mac_filter = &qed_roce_ll2_set_mac_filter,
2027f1372ee1SKalderon, Michal 	.ll2_get_stats = &qed_ll2_get_stats,
20283576e99eSMichal Kalderon 	.iwarp_set_engine_affin = &qed_iwarp_set_engine_affin,
20294b0fdd7cSKalderon, Michal 	.iwarp_connect = &qed_iwarp_connect,
203065a91a6cSKalderon, Michal 	.iwarp_create_listen = &qed_iwarp_create_listen,
203165a91a6cSKalderon, Michal 	.iwarp_destroy_listen = &qed_iwarp_destroy_listen,
20324b0fdd7cSKalderon, Michal 	.iwarp_accept = &qed_iwarp_accept,
20334b0fdd7cSKalderon, Michal 	.iwarp_reject = &qed_iwarp_reject,
20344b0fdd7cSKalderon, Michal 	.iwarp_send_rtr = &qed_iwarp_send_rtr,
2035f1372ee1SKalderon, Michal };
2036f1372ee1SKalderon, Michal 
qed_get_rdma_ops(void)2037f1372ee1SKalderon, Michal const struct qed_rdma_ops *qed_get_rdma_ops(void)
2038f1372ee1SKalderon, Michal {
2039f1372ee1SKalderon, Michal 	return &qed_rdma_ops_pass;
2040f1372ee1SKalderon, Michal }
2041f1372ee1SKalderon, Michal EXPORT_SYMBOL(qed_get_rdma_ops);
2042