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 = ¶ms->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 *)¶ms->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 *)¶ms->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