1 From 4daf5c91c1296683924cb9668c3d879da072756b Mon Sep 17 00:00:00 2001
2 From: Jason Gunthorpe <jgg@mellanox.com>
3 Date: Thu, 24 Oct 2019 12:50:22 -0300
4 Subject: [PATCH] libnes: Remove libnes from rdma-core
6 Remove the userspace provider for nes after removing it from kernel.
8 Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
14 debian/copyright | 5 -
15 kernel-boot/rdma-description.rules | 1 -
16 kernel-boot/rdma-hw-modules.rules | 1 -
17 libibverbs/verbs.h | 1 -
18 providers/nes/CMakeLists.txt | 4 -
19 providers/nes/nes-abi.h | 52 -
20 providers/nes/nes_umain.c | 220 ----
21 providers/nes/nes_umain.h | 383 -------
22 providers/nes/nes_uverbs.c | 1535 ----------------------------
23 redhat/rdma-core.spec | 3 -
24 suse/rdma-core.spec | 2 -
25 15 files changed, 2218 deletions(-)
26 delete mode 100644 providers/nes/CMakeLists.txt
27 delete mode 100644 providers/nes/nes-abi.h
28 delete mode 100644 providers/nes/nes_umain.c
29 delete mode 100644 providers/nes/nes_umain.h
30 delete mode 100644 providers/nes/nes_uverbs.c
32 diff --git a/CMakeLists.txt b/CMakeLists.txt
33 index 85485ba00..85eb25936 100644
36 @@ -625,7 +625,6 @@ add_subdirectory(providers/mlx4/man)
37 add_subdirectory(providers/mlx5)
38 add_subdirectory(providers/mlx5/man)
39 add_subdirectory(providers/mthca)
40 -add_subdirectory(providers/nes) # NO SPARSE
41 add_subdirectory(providers/ocrdma)
42 add_subdirectory(providers/qedr)
43 add_subdirectory(providers/vmw_pvrdma)
44 diff --git a/debian/copyright b/debian/copyright
45 index db4951993..6f86d1c86 100644
46 --- a/debian/copyright
47 +++ b/debian/copyright
48 @@ -197,11 +197,6 @@ Copyright: 2004-2005, Topspin Communications.
49 2005, Mellanox Technologies Ltd.
50 License: BSD-MIT or GPL-2
52 -Files: providers/nes/*
53 -Copyright: 2006-2010, Intel Corporation.
54 - 2006, Open Grid Computing, Inc.
55 -License: BSD-MIT or GPL-2
57 Files: providers/ocrdma/*
58 Copyright: 2008-2013, Emulex.
59 License: BSD-2-clause or GPL-2
60 diff --git a/kernel-boot/rdma-description.rules b/kernel-boot/rdma-description.rules
61 index 4ea59ba19..48a7cede9 100644
62 --- a/kernel-boot/rdma-description.rules
63 +++ b/kernel-boot/rdma-description.rules
64 @@ -24,7 +24,6 @@ DRIVERS=="hfi1", ENV{ID_RDMA_OPA}="1"
65 # Hardware that supports iWarp
66 DRIVERS=="cxgb4", ENV{ID_RDMA_IWARP}="1"
67 DRIVERS=="i40e", ENV{ID_RDMA_IWARP}="1"
68 -DRIVERS=="nes", ENV{ID_RDMA_IWARP}="1"
70 # Hardware that supports RoCE
71 DRIVERS=="be2net", ENV{ID_RDMA_ROCE}="1"
72 diff --git a/kernel-boot/rdma-hw-modules.rules b/kernel-boot/rdma-hw-modules.rules
73 index da4bbe363..bee416dbe 100644
74 --- a/kernel-boot/rdma-hw-modules.rules
75 +++ b/kernel-boot/rdma-hw-modules.rules
76 @@ -33,7 +33,6 @@ ENV{ID_NET_DRIVER}=="enic", RUN{builtin}+="kmod load usnic_verbs"
82 LABEL="rdma_hw_modules_net_end"
84 diff --git a/libibverbs/verbs.h b/libibverbs/verbs.h
85 index 12a33a99a..13e7c63e7 100644
86 --- a/libibverbs/verbs.h
87 +++ b/libibverbs/verbs.h
88 @@ -2153,7 +2153,6 @@ extern const struct verbs_device_ops verbs_provider_ipathverbs;
89 extern const struct verbs_device_ops verbs_provider_mlx4;
90 extern const struct verbs_device_ops verbs_provider_mlx5;
91 extern const struct verbs_device_ops verbs_provider_mthca;
92 -extern const struct verbs_device_ops verbs_provider_nes;
93 extern const struct verbs_device_ops verbs_provider_ocrdma;
94 extern const struct verbs_device_ops verbs_provider_qedr;
95 extern const struct verbs_device_ops verbs_provider_rxe;
96 diff --git a/providers/nes/CMakeLists.txt b/providers/nes/CMakeLists.txt
97 deleted file mode 100644
98 index 0c7fa8fad..000000000
99 --- a/providers/nes/CMakeLists.txt
106 diff --git a/providers/nes/nes-abi.h b/providers/nes/nes-abi.h
107 deleted file mode 100644
108 index 0a531230b..000000000
109 --- a/providers/nes/nes-abi.h
113 - * Copyright (c) 2006 - 2010 Intel Corporation. All rights reserved.
114 - * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
116 - * This software is available to you under a choice of one of two
117 - * licenses. You may choose to be licensed under the terms of the GNU
118 - * General Public License (GPL) Version 2, available from the file
119 - * gpl-2.0.txt in the main directory of this source tree, or the
120 - * OpenIB.org BSD license below:
122 - * Redistribution and use in source and binary forms, with or
123 - * without modification, are permitted provided that the following
124 - * conditions are met:
126 - * - Redistributions of source code must retain the above
127 - * copyright notice, this list of conditions and the following
130 - * - Redistributions in binary form must reproduce the above
131 - * copyright notice, this list of conditions and the following
132 - * disclaimer in the documentation and/or other materials
133 - * provided with the distribution.
135 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
136 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
137 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
138 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
139 - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
140 - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
141 - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
148 -#include <infiniband/kern-abi.h>
149 -#include <rdma/nes-abi.h>
150 -#include <kernel-abi/nes-abi.h>
152 -DECLARE_DRV_CMD(nes_ualloc_pd, IB_USER_VERBS_CMD_ALLOC_PD,
153 - empty, nes_alloc_pd_resp);
154 -DECLARE_DRV_CMD(nes_ucreate_cq, IB_USER_VERBS_CMD_CREATE_CQ,
155 - nes_create_cq_req, nes_create_cq_resp);
156 -DECLARE_DRV_CMD(nes_ucreate_qp, IB_USER_VERBS_CMD_CREATE_QP,
157 - nes_create_qp_req, nes_create_qp_resp);
158 -DECLARE_DRV_CMD(nes_get_context, IB_USER_VERBS_CMD_GET_CONTEXT,
159 - nes_alloc_ucontext_req, nes_alloc_ucontext_resp);
160 -DECLARE_DRV_CMD(nes_ureg_mr, IB_USER_VERBS_CMD_REG_MR,
161 - nes_mem_reg_req, empty);
163 -#endif /* nes_ABI_H */
164 diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
165 deleted file mode 100644
166 index 07aa7ddd1..000000000
167 --- a/providers/nes/nes_umain.c
171 - * Copyright (c) 2006 - 2010 Intel Corporation. All rights reserved.
172 - * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
174 - * This software is available to you under a choice of one of two
175 - * licenses. You may choose to be licensed under the terms of the GNU
176 - * General Public License (GPL) Version 2, available from the file
177 - * gpl-2.0.txt in the main directory of this source tree, or the
178 - * OpenIB.org BSD license below:
180 - * Redistribution and use in source and binary forms, with or
181 - * without modification, are permitted provided that the following
182 - * conditions are met:
184 - * - Redistributions of source code must retain the above
185 - * copyright notice, this list of conditions and the following
188 - * - Redistributions in binary form must reproduce the above
189 - * copyright notice, this list of conditions and the following
190 - * disclaimer in the documentation and/or other materials
191 - * provided with the distribution.
193 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
194 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
195 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
196 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
197 - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
198 - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
199 - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
210 -#include <sys/mman.h>
211 -#include <pthread.h>
213 -#include "nes_umain.h"
214 -#include "nes-abi.h"
216 -unsigned int nes_debug_level = 0;
219 -#include <sys/types.h>
220 -#include <sys/stat.h>
223 -#ifndef PCI_VENDOR_ID_NETEFFECT
224 -#define PCI_VENDOR_ID_NETEFFECT 0x1678
227 -#define HCA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
228 -static const struct verbs_match_ent hca_table[] = {
229 - VERBS_DRIVER_ID(RDMA_DRIVER_NES),
230 - HCA(NETEFFECT, 0x0100),
231 - HCA(NETEFFECT, 0x0110),
235 -static const struct verbs_context_ops nes_uctx_ops = {
236 - .query_device = nes_uquery_device,
237 - .query_port = nes_uquery_port,
238 - .alloc_pd = nes_ualloc_pd,
239 - .dealloc_pd = nes_ufree_pd,
240 - .reg_mr = nes_ureg_mr,
241 - .dereg_mr = nes_udereg_mr,
242 - .create_cq = nes_ucreate_cq,
243 - .poll_cq = nes_upoll_cq,
244 - .req_notify_cq = nes_uarm_cq,
245 - .cq_event = nes_cq_event,
246 - .resize_cq = nes_uresize_cq,
247 - .destroy_cq = nes_udestroy_cq,
248 - .create_qp = nes_ucreate_qp,
249 - .query_qp = nes_uquery_qp,
250 - .modify_qp = nes_umodify_qp,
251 - .destroy_qp = nes_udestroy_qp,
252 - .post_send = nes_upost_send,
253 - .post_recv = nes_upost_recv,
254 - .create_ah = nes_ucreate_ah,
255 - .destroy_ah = nes_udestroy_ah,
256 - .attach_mcast = nes_uattach_mcast,
257 - .detach_mcast = nes_udetach_mcast,
258 - .async_event = nes_async_event
261 -static const struct verbs_context_ops nes_uctx_no_db_ops = {
262 - .poll_cq = nes_upoll_cq_no_db_read,
267 - * nes_ualloc_context
269 -static struct verbs_context *nes_ualloc_context(struct ibv_device *ibdev,
271 - void *private_data)
273 - struct ibv_pd *ibv_pd;
274 - struct nes_uvcontext *nesvctx;
275 - struct nes_get_context cmd;
276 - struct nes_get_context_resp resp;
278 - uint32_t nes_drv_opt = 0;
280 - page_size = sysconf(_SC_PAGESIZE);
282 - nesvctx = verbs_init_and_alloc_context(ibdev, cmd_fd, nesvctx, ibv_ctx,
287 - cmd.userspace_ver = NES_ABI_USERSPACE_VER;
289 - if (ibv_cmd_get_context(&nesvctx->ibv_ctx, (struct ibv_get_context *)&cmd, sizeof cmd,
290 - &resp.ibv_resp, sizeof(resp)))
293 - if (resp.kernel_ver != NES_ABI_KERNEL_VER) {
294 - fprintf(stderr, PFX "%s: Invalid kernel driver version detected. Detected %d, should be %d\n",
295 - __FUNCTION__, resp.kernel_ver, NES_ABI_KERNEL_VER);
299 - if (ibv_read_sysfs_file("/sys/module/iw_nes", "parameters/nes_drv_opt",
300 - value, sizeof(value)) > 0) {
301 - sscanf(value, "%d", &nes_drv_opt);
302 - } else if (ibv_read_sysfs_file("/sys/module/iw_nes", "nes_drv_opt",
303 - value, sizeof(value)) > 0) {
304 - sscanf(value, "%d", &nes_drv_opt);
307 - verbs_set_ops(&nesvctx->ibv_ctx, &nes_uctx_ops);
308 - if (nes_drv_opt & NES_DRV_OPT_NO_DB_READ)
309 - verbs_set_ops(&nesvctx->ibv_ctx, &nes_uctx_no_db_ops);
311 - nesvctx->max_pds = resp.max_pds;
312 - nesvctx->max_qps = resp.max_qps;
313 - nesvctx->wq_size = resp.wq_size;
314 - nesvctx->virtwq = resp.virtwq;
315 - nesvctx->mcrqf = 0;
317 - /* Get a doorbell region for the CQs */
318 - ibv_pd = nes_ualloc_pd(&nesvctx->ibv_ctx.context);
321 - ibv_pd->context = &nesvctx->ibv_ctx.context;
322 - nesvctx->nesupd = to_nes_upd(ibv_pd);
324 - return &nesvctx->ibv_ctx;
327 - fprintf(stderr, PFX "%s: Failed to allocate context for device.\n", __FUNCTION__);
328 - verbs_uninit_context(&nesvctx->ibv_ctx);
336 - * nes_ufree_context
338 -static void nes_ufree_context(struct ibv_context *ibctx)
340 - struct nes_uvcontext *nesvctx = to_nes_uctx(ibctx);
341 - nes_ufree_pd(&nesvctx->nesupd->ibv_pd);
343 - verbs_uninit_context(&nesvctx->ibv_ctx);
347 -static void nes_uninit_device(struct verbs_device *verbs_device)
349 - struct nes_udevice *dev = to_nes_udev(&verbs_device->device);
354 -static struct verbs_device *
355 -nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
357 - struct nes_udevice *dev;
360 - if (ibv_read_sysfs_file("/sys/module/iw_nes", "parameters/debug_level",
361 - value, sizeof(value)) > 0) {
362 - sscanf(value, "%u", &nes_debug_level);
363 - } else if (ibv_read_sysfs_file("/sys/module/iw_nes", "debug_level",
364 - value, sizeof(value)) > 0) {
365 - sscanf(value, "%u", &nes_debug_level);
368 - dev = calloc(1, sizeof(*dev));
372 - dev->page_size = sysconf(_SC_PAGESIZE);
374 - nes_debug(NES_DBG_INIT, "libnes initialized\n");
376 - return &dev->ibv_dev;
379 -static const struct verbs_device_ops nes_udev_ops = {
381 - .match_min_abi_version = 0,
382 - .match_max_abi_version = INT_MAX,
383 - .match_table = hca_table,
384 - .alloc_device = nes_device_alloc,
385 - .uninit_device = nes_uninit_device,
386 - .alloc_context = nes_ualloc_context,
387 - .free_context = nes_ufree_context,
389 -PROVIDER_DRIVER(nes, nes_udev_ops);
390 diff --git a/providers/nes/nes_umain.h b/providers/nes/nes_umain.h
391 deleted file mode 100644
392 index 1070ce429..000000000
393 --- a/providers/nes/nes_umain.h
397 - * Copyright (c) 2006 - 2010 Intel Corporation. All rights reserved.
398 - * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
400 - * This software is available to you under a choice of one of two
401 - * licenses. You may choose to be licensed under the terms of the GNU
402 - * General Public License (GPL) Version 2, available from the file
403 - * gpl-2.0.txt in the main directory of this source tree, or the
404 - * OpenIB.org BSD license below:
406 - * Redistribution and use in source and binary forms, with or
407 - * without modification, are permitted provided that the following
408 - * conditions are met:
410 - * - Redistributions of source code must retain the above
411 - * copyright notice, this list of conditions and the following
414 - * - Redistributions in binary form must reproduce the above
415 - * copyright notice, this list of conditions and the following
416 - * disclaimer in the documentation and/or other materials
417 - * provided with the distribution.
419 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
420 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
421 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
422 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
423 - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
424 - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
425 - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
432 -#include <inttypes.h>
435 -#include <util/compiler.h>
437 -#include <infiniband/driver.h>
438 -#include <util/udma_barrier.h>
440 -#define PFX "libnes: "
442 -#define NES_QP_MMAP 1
443 -#define NES_QP_VMAP 2
445 -#define NES_DRV_OPT_NO_INLINE_DATA 0x00000080
446 -#define NES_DRV_OPT_NO_DB_READ 0x00001000
450 -/* must match kernel */
451 -#define NES_DBG_HW 0x00000001
452 -#define NES_DBG_INIT 0x00000002
453 -#define NES_DBG_ISR 0x00000004
454 -#define NES_DBG_PHY 0x00000008
455 -#define NES_DBG_NETDEV 0x00000010
456 -#define NES_DBG_CM 0x00000020
457 -#define NES_DBG_CM1 0x00000040
458 -#define NES_DBG_NIC_RX 0x00000080
459 -#define NES_DBG_NIC_TX 0x00000100
460 -#define NES_DBG_CQP 0x00000200
461 -#define NES_DBG_MMAP 0x00000400
462 -#define NES_DBG_MR 0x00000800
463 -#define NES_DBG_PD 0x00001000
464 -#define NES_DBG_CQ 0x00002000
465 -#define NES_DBG_QP 0x00004000
466 -#define NES_DBG_MOD_QP 0x00008000
467 -#define NES_DBG_AEQ 0x00010000
468 -#define NES_DBG_IW_RX 0x00020000
469 -#define NES_DBG_IW_TX 0x00040000
470 -#define NES_DBG_SHUTDOWN 0x00080000
471 -#define NES_DBG_UD 0x00100000
472 -#define NES_DBG_RSVD1 0x10000000
473 -#define NES_DBG_RSVD2 0x20000000
474 -#define NES_DBG_RSVD3 0x40000000
475 -#define NES_DBG_RSVD4 0x80000000
476 -#define NES_DBG_ALL 0xffffffff
478 -extern unsigned int nes_debug_level;
480 -#define nes_debug(level, fmt, args...) \
481 - if (level & nes_debug_level) \
482 - fprintf(stderr, PFX "%s[%u]: " fmt, __FUNCTION__, __LINE__, ##args)
484 -#define nes_debug(level, fmt, args...)
487 -enum nes_cqe_opcode_bits {
488 - NES_CQE_STAG_VALID = (1<<6),
489 - NES_CQE_ERROR = (1<<7),
490 - NES_CQE_SQ = (1<<8),
491 - NES_CQE_SE = (1<<9),
492 - NES_CQE_PSH = (1<<29),
493 - NES_CQE_FIN = (1<<30),
494 - NES_CQE_VALID = (1<<31),
497 -enum nes_cqe_word_idx {
498 - NES_CQE_PAYLOAD_LENGTH_IDX = 0,
499 - NES_CQE_COMP_COMP_CTX_LOW_IDX = 2,
500 - NES_CQE_COMP_COMP_CTX_HIGH_IDX = 3,
501 - NES_CQE_INV_STAG_IDX = 4,
502 - NES_CQE_QP_ID_IDX = 5,
503 - NES_CQE_ERROR_CODE_IDX = 6,
504 - NES_CQE_OPCODE_IDX = 7,
507 -enum nes_cqe_allocate_bits {
508 - NES_CQE_ALLOC_INC_SELECT = (1<<28),
509 - NES_CQE_ALLOC_NOTIFY_NEXT = (1<<29),
510 - NES_CQE_ALLOC_NOTIFY_SE = (1<<30),
511 - NES_CQE_ALLOC_RESET = (1<<31),
514 -enum nes_iwarp_sq_wqe_word_idx {
515 - NES_IWARP_SQ_WQE_MISC_IDX = 0,
516 - NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX = 1,
517 - NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX = 2,
518 - NES_IWARP_SQ_WQE_COMP_CTX_HIGH_IDX = 3,
519 - NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX = 4,
520 - NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX = 5,
521 - NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX = 7,
522 - NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX = 8,
523 - NES_IWARP_SQ_WQE_RDMA_TO_HIGH_IDX = 9,
524 - NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX = 10,
525 - NES_IWARP_SQ_WQE_RDMA_STAG_IDX = 11,
526 - NES_IWARP_SQ_WQE_IMM_DATA_START_IDX = 12,
527 - NES_IWARP_SQ_WQE_FRAG0_LOW_IDX = 16,
528 - NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX = 17,
529 - NES_IWARP_SQ_WQE_LENGTH0_IDX = 18,
530 - NES_IWARP_SQ_WQE_STAG0_IDX = 19,
531 - NES_IWARP_SQ_WQE_FRAG1_LOW_IDX = 20,
532 - NES_IWARP_SQ_WQE_FRAG1_HIGH_IDX = 21,
533 - NES_IWARP_SQ_WQE_LENGTH1_IDX = 22,
534 - NES_IWARP_SQ_WQE_STAG1_IDX = 23,
535 - NES_IWARP_SQ_WQE_FRAG2_LOW_IDX = 24,
536 - NES_IWARP_SQ_WQE_FRAG2_HIGH_IDX = 25,
537 - NES_IWARP_SQ_WQE_LENGTH2_IDX = 26,
538 - NES_IWARP_SQ_WQE_STAG2_IDX = 27,
539 - NES_IWARP_SQ_WQE_FRAG3_LOW_IDX = 28,
540 - NES_IWARP_SQ_WQE_FRAG3_HIGH_IDX = 29,
541 - NES_IWARP_SQ_WQE_LENGTH3_IDX = 30,
542 - NES_IWARP_SQ_WQE_STAG3_IDX = 31,
545 -enum nes_iwarp_rq_wqe_word_idx {
546 - NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX = 1,
547 - NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX = 2,
548 - NES_IWARP_RQ_WQE_COMP_CTX_HIGH_IDX = 3,
549 - NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX = 4,
550 - NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX = 5,
551 - NES_IWARP_RQ_WQE_FRAG0_LOW_IDX = 8,
552 - NES_IWARP_RQ_WQE_FRAG0_HIGH_IDX = 9,
553 - NES_IWARP_RQ_WQE_LENGTH0_IDX = 10,
554 - NES_IWARP_RQ_WQE_STAG0_IDX = 11,
555 - NES_IWARP_RQ_WQE_FRAG1_LOW_IDX = 12,
556 - NES_IWARP_RQ_WQE_FRAG1_HIGH_IDX = 13,
557 - NES_IWARP_RQ_WQE_LENGTH1_IDX = 14,
558 - NES_IWARP_RQ_WQE_STAG1_IDX = 15,
559 - NES_IWARP_RQ_WQE_FRAG2_LOW_IDX = 16,
560 - NES_IWARP_RQ_WQE_FRAG2_HIGH_IDX = 17,
561 - NES_IWARP_RQ_WQE_LENGTH2_IDX = 18,
562 - NES_IWARP_RQ_WQE_STAG2_IDX = 19,
563 - NES_IWARP_RQ_WQE_FRAG3_LOW_IDX = 20,
564 - NES_IWARP_RQ_WQE_FRAG3_HIGH_IDX = 21,
565 - NES_IWARP_RQ_WQE_LENGTH3_IDX = 22,
566 - NES_IWARP_RQ_WQE_STAG3_IDX = 23,
569 -enum nes_iwarp_sq_opcodes {
570 - NES_IWARP_SQ_WQE_STREAMING = (1<<23),
571 - NES_IWARP_SQ_WQE_IMM_DATA = (1<<28),
572 - NES_IWARP_SQ_WQE_READ_FENCE = (1<<29),
573 - NES_IWARP_SQ_WQE_LOCAL_FENCE = (1<<30),
574 - NES_IWARP_SQ_WQE_SIGNALED_COMPL = (1<<31),
577 -enum nes_iwarp_sq_wqe_bits {
578 - NES_IWARP_SQ_OP_RDMAW = 0,
579 - NES_IWARP_SQ_OP_RDMAR = 1,
580 - NES_IWARP_SQ_OP_SEND = 3,
581 - NES_IWARP_SQ_OP_SENDINV = 4,
582 - NES_IWARP_SQ_OP_SENDSE = 5,
583 - NES_IWARP_SQ_OP_SENDSEINV = 6,
584 - NES_IWARP_SQ_OP_BIND = 8,
585 - NES_IWARP_SQ_OP_FAST_REG = 9,
586 - NES_IWARP_SQ_OP_LOCINV = 10,
587 - NES_IWARP_SQ_OP_RDMAR_LOCINV = 11,
588 - NES_IWARP_SQ_OP_NOP = 12,
591 -enum nes_nic_cqe_word_idx {
592 - NES_NIC_CQE_ACCQP_ID_IDX = 0,
593 - NES_NIC_CQE_TAG_PKT_TYPE_IDX = 2,
594 - NES_NIC_CQE_MISC_IDX = 3,
597 -#define NES_NIC_CQE_ERRV_SHIFT 16
598 -enum nes_nic_ev_bits {
599 - NES_NIC_ERRV_BITS_MODE = (1<<0),
600 - NES_NIC_ERRV_BITS_IPV4_CSUM_ERR = (1<<1),
601 - NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR = (1<<2),
602 - NES_NIC_ERRV_BITS_WQE_OVERRUN = (1<<3),
603 - NES_NIC_ERRV_BITS_IPH_ERR = (1<<4),
606 -enum nes_nic_cqe_bits {
607 - NES_NIC_CQE_ERRV_MASK = (0xff<<NES_NIC_CQE_ERRV_SHIFT),
608 - NES_NIC_CQE_SQ = (1<<24),
609 - NES_NIC_CQE_ACCQP_PORT = (1<<28),
610 - NES_NIC_CQE_ACCQP_VALID = (1<<29),
611 - NES_NIC_CQE_TAG_VALID = (1<<30),
612 - NES_NIC_CQE_VALID = (1<<31),
614 -struct nes_hw_nic_cqe {
615 - uint32_t cqe_words[4];
618 -enum nes_iwarp_cqe_major_code {
619 - NES_IWARP_CQE_MAJOR_FLUSH = 1,
620 - NES_IWARP_CQE_MAJOR_DRV = 0x8000
623 -enum nes_iwarp_cqe_minor_code {
624 - NES_IWARP_CQE_MINOR_FLUSH = 1
627 -struct nes_hw_qp_wqe {
628 - uint32_t wqe_words[32];
632 - uint32_t cqe_words[8];
635 -struct nes_user_doorbell {
636 - uint32_t wqe_alloc;
637 - uint32_t reserved[3];
638 - uint32_t cqe_alloc;
641 -struct nes_udevice {
642 - struct verbs_device ibv_dev;
647 - struct ibv_pd ibv_pd;
648 - struct nes_user_doorbell volatile *udoorbell;
653 -struct nes_uvcontext {
654 - struct verbs_context ibv_ctx;
655 - struct nes_upd *nesupd;
656 - uint32_t max_pds; /* maximum pds allowed for this user process */
657 - uint32_t max_qps; /* maximum qps allowed for this user process */
658 - uint32_t wq_size; /* size of the WQs (sq+rq) allocated to the mmaped area */
660 - uint8_t virtwq ; /* flag if to use virt wqs or not */
661 - uint8_t reserved[3];
667 - struct ibv_cq ibv_cq;
668 - struct nes_hw_cqe volatile *cqes;
669 - struct verbs_mr vmr;
670 - pthread_spinlock_t lock;
674 - uint16_t polled_completions;
680 - struct nes_uqp *udqp;
684 - struct ibv_qp ibv_qp;
685 - struct nes_hw_qp_wqe volatile *sq_vbase;
686 - struct nes_hw_qp_wqe volatile *rq_vbase;
688 - struct nes_ucq *send_cq;
689 - struct nes_ucq *recv_cq;
690 - struct verbs_mr vmr;
691 - uint32_t nes_drv_opt;
692 - pthread_spinlock_t lock;
693 - uint16_t sq_db_index;
697 - uint16_t sq_sig_all;
698 - uint16_t rq_db_index;
702 - uint16_t rdma0_msg;
706 - uint32_t pending_rcvs;
707 - struct ibv_recv_wr *pend_rx_wr;
708 - int nes_ud_sksq_fd;
709 - void *sksq_shared_ctxt;
710 - uint64_t send_wr_id[512]; /* IMA send wr_id ring content */
711 - uint64_t recv_wr_id[512]; /* IMA receive wr_id ring content */
714 -#define to_nes_uxxx(xxx, type) \
715 - container_of(ib##xxx, struct nes_u##type, ibv_##xxx)
717 -static inline struct nes_udevice *to_nes_udev(struct ibv_device *ibdev)
719 - return container_of(ibdev, struct nes_udevice, ibv_dev.device);
722 -static inline struct nes_uvcontext *to_nes_uctx(struct ibv_context *ibctx)
724 - return container_of(ibctx, struct nes_uvcontext, ibv_ctx.context);
727 -static inline struct nes_upd *to_nes_upd(struct ibv_pd *ibpd)
729 - return to_nes_uxxx(pd, pd);
732 -static inline struct nes_ucq *to_nes_ucq(struct ibv_cq *ibcq)
734 - return to_nes_uxxx(cq, cq);
737 -static inline struct nes_uqp *to_nes_uqp(struct ibv_qp *ibqp)
739 - return to_nes_uxxx(qp, qp);
744 -int nes_uquery_device(struct ibv_context *, struct ibv_device_attr *);
745 -int nes_uquery_port(struct ibv_context *, uint8_t, struct ibv_port_attr *);
746 -struct ibv_pd *nes_ualloc_pd(struct ibv_context *);
747 -int nes_ufree_pd(struct ibv_pd *);
748 -struct ibv_mr *nes_ureg_mr(struct ibv_pd *pd, void *addr, size_t length,
749 - uint64_t hca_va, int access);
750 -int nes_udereg_mr(struct verbs_mr *vmr);
751 -struct ibv_cq *nes_ucreate_cq(struct ibv_context *, int, struct ibv_comp_channel *, int);
752 -int nes_uresize_cq(struct ibv_cq *, int);
753 -int nes_udestroy_cq(struct ibv_cq *);
754 -int nes_upoll_cq(struct ibv_cq *, int, struct ibv_wc *);
755 -int nes_upoll_cq_no_db_read(struct ibv_cq *, int, struct ibv_wc *);
756 -int nes_uarm_cq(struct ibv_cq *, int);
757 -void nes_cq_event(struct ibv_cq *);
758 -struct ibv_srq *nes_ucreate_srq(struct ibv_pd *, struct ibv_srq_init_attr *);
759 -int nes_umodify_srq(struct ibv_srq *, struct ibv_srq_attr *, int);
760 -int nes_udestroy_srq(struct ibv_srq *);
761 -int nes_upost_srq_recv(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **);
762 -struct ibv_qp *nes_ucreate_qp(struct ibv_pd *, struct ibv_qp_init_attr *);
763 -int nes_uquery_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
764 - int, struct ibv_qp_init_attr *init_attr);
765 -int nes_umodify_qp(struct ibv_qp *, struct ibv_qp_attr *, int);
766 -int nes_udestroy_qp(struct ibv_qp *);
767 -int nes_upost_send(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **);
768 -int nes_upost_recv(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **);
769 -struct ibv_ah *nes_ucreate_ah(struct ibv_pd *, struct ibv_ah_attr *);
770 -int nes_udestroy_ah(struct ibv_ah *);
771 -int nes_uattach_mcast(struct ibv_qp *, const union ibv_gid *, uint16_t);
772 -int nes_udetach_mcast(struct ibv_qp *, const union ibv_gid *, uint16_t);
773 -void nes_async_event(struct ibv_context *context,
774 - struct ibv_async_event *event);
776 -extern long int page_size;
778 -#endif /* nes_umain_H */
779 diff --git a/providers/nes/nes_uverbs.c b/providers/nes/nes_uverbs.c
780 deleted file mode 100644
781 index 2b78468b4..000000000
782 --- a/providers/nes/nes_uverbs.c
786 - * Copyright (c) 2006 - 2010 Intel Corporation. All rights reserved.
788 - * This software is available to you under a choice of one of two
789 - * licenses. You may choose to be licensed under the terms of the GNU
790 - * General Public License (GPL) Version 2, available from the file
791 - * gpl-2.0.txt in the main directory of this source tree, or the
792 - * OpenIB.org BSD license below:
794 - * Redistribution and use in source and binary forms, with or
795 - * without modification, are permitted provided that the following
796 - * conditions are met:
798 - * - Redistributions of source code must retain the above
799 - * copyright notice, this list of conditions and the following
802 - * - Redistributions in binary form must reproduce the above
803 - * copyright notice, this list of conditions and the following
804 - * disclaimer in the documentation and/or other materials
805 - * provided with the distribution.
807 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
808 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
809 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
810 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
811 - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
812 - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
813 - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
826 -#include <pthread.h>
828 -#include <sys/mman.h>
829 -#include <linux/if_ether.h>
830 -#include <sys/stat.h>
833 -#include "nes_umain.h"
834 -#include "nes-abi.h"
836 -#define STATIC static
837 -#define INLINE inline
839 -#define NES_WC_WITH_VLAN 1 << 3
840 -#define NES_UD_RX_BATCH_SZ 64
841 -#define NES_UD_MAX_SG_LIST_SZ 1
843 -struct nes_ud_send_wr {
848 - struct ibv_sge sg_list[64];
851 -struct nes_ud_recv_wr {
855 - struct ibv_sge sg_list[64];
859 - * nes_uquery_device
861 -int nes_uquery_device(struct ibv_context *context, struct ibv_device_attr *attr)
863 - struct ibv_query_device cmd;
864 - uint64_t nes_fw_ver;
866 - unsigned int minor, major;
868 - ret = ibv_cmd_query_device(context, attr, &nes_fw_ver,
873 - major = (nes_fw_ver >> 16) & 0xffff;
874 - minor = nes_fw_ver & 0xffff;
876 - snprintf(attr->fw_ver, sizeof attr->fw_ver,
877 - "%d.%d", major, minor);
886 -int nes_uquery_port(struct ibv_context *context, uint8_t port,
887 - struct ibv_port_attr *attr)
889 - struct ibv_query_port cmd;
891 - return ibv_cmd_query_port(context, port, attr, &cmd, sizeof cmd);
898 -struct ibv_pd *nes_ualloc_pd(struct ibv_context *context)
900 - struct ibv_alloc_pd cmd;
901 - struct nes_ualloc_pd_resp resp;
902 - struct nes_upd *nesupd;
904 - nesupd = malloc(sizeof *nesupd);
908 - if (ibv_cmd_alloc_pd(context, &nesupd->ibv_pd, &cmd, sizeof cmd,
909 - &resp.ibv_resp, sizeof resp)) {
913 - nesupd->pd_id = resp.pd_id;
914 - nesupd->db_index = resp.mmap_db_index;
916 - nesupd->udoorbell = mmap(NULL, page_size, PROT_WRITE | PROT_READ, MAP_SHARED,
917 - context->cmd_fd, nesupd->db_index * page_size);
919 - if (nesupd->udoorbell == MAP_FAILED) {
924 - return &nesupd->ibv_pd;
931 -int nes_ufree_pd(struct ibv_pd *pd)
934 - struct nes_upd *nesupd;
936 - nesupd = to_nes_upd(pd);
938 - ret = ibv_cmd_dealloc_pd(pd);
942 - munmap((void *)nesupd->udoorbell, page_size);
952 -struct ibv_mr *nes_ureg_mr(struct ibv_pd *pd, void *addr, size_t length,
953 - uint64_t hca_va, int access)
955 - struct verbs_mr *vmr;
956 - struct nes_ureg_mr cmd;
957 - struct ib_uverbs_reg_mr_resp resp;
959 - vmr = malloc(sizeof(*vmr));
963 - cmd.reg_type = IWNES_MEMREG_TYPE_MEM;
964 - if (ibv_cmd_reg_mr(pd, addr, length, hca_va, access, vmr, &cmd.ibv_cmd,
965 - sizeof(cmd), &resp, sizeof(resp))) {
971 - return &vmr->ibv_mr;
978 -int nes_udereg_mr(struct verbs_mr *vmr)
982 - ret = ibv_cmd_dereg_mr(vmr);
993 -struct ibv_cq *nes_ucreate_cq(struct ibv_context *context, int cqe,
994 - struct ibv_comp_channel *channel, int comp_vector)
996 - struct nes_ucq *nesucq;
997 - struct nes_ureg_mr reg_mr_cmd;
998 - struct ib_uverbs_reg_mr_resp reg_mr_resp;
999 - struct nes_ucreate_cq cmd;
1000 - struct nes_ucreate_cq_resp resp;
1002 - struct nes_uvcontext *nesvctx = to_nes_uctx(context);
1004 - nesucq = malloc(sizeof *nesucq);
1008 - memset(nesucq, 0, sizeof(*nesucq));
1010 - if (pthread_spin_init(&nesucq->lock, PTHREAD_PROCESS_PRIVATE)) {
1015 - if (cqe < 4) /* a reasonable minimum */
1017 - nesucq->size = cqe + 1;
1018 - nesucq->comp_vector = comp_vector;
1020 - nesucq->cqes = memalign(page_size, nesucq->size*sizeof(struct nes_hw_cqe));
1021 - if (!nesucq->cqes)
1024 - /* Register the memory for the CQ */
1025 - reg_mr_cmd.reg_type = IWNES_MEMREG_TYPE_CQ;
1027 - ret = ibv_cmd_reg_mr(&nesvctx->nesupd->ibv_pd, (void *)nesucq->cqes,
1028 - (nesucq->size*sizeof(struct nes_hw_cqe)),
1029 - (uintptr_t)nesucq->cqes, IBV_ACCESS_LOCAL_WRITE,
1030 - &nesucq->vmr, ®_mr_cmd.ibv_cmd, sizeof(reg_mr_cmd),
1031 - ®_mr_resp, sizeof(reg_mr_resp));
1033 - /* fprintf(stderr, "ibv_cmd_reg_mr failed (ret = %d).\n", ret); */
1034 - free((struct nes_hw_cqe *)nesucq->cqes);
1038 - /* Create the CQ */
1039 - memset(&cmd, 0, sizeof(cmd));
1040 - cmd.user_cq_buffer = (__u64)((uintptr_t)nesucq->cqes);
1041 - cmd.mcrqf = nesvctx->mcrqf;
1043 - ret = ibv_cmd_create_cq(context, nesucq->size-1, channel, comp_vector,
1044 - &nesucq->ibv_cq, &cmd.ibv_cmd, sizeof cmd,
1045 - &resp.ibv_resp, sizeof resp);
1049 - nesucq->cq_id = (uint16_t)resp.cq_id;
1051 - /* Zero out the CQ */
1052 - memset((struct nes_hw_cqe *)nesucq->cqes, 0, nesucq->size*sizeof(struct nes_hw_cqe));
1054 - return &nesucq->ibv_cq;
1057 - /* fprintf(stderr, PFX "%s: Error Creating CQ.\n", __FUNCTION__); */
1058 - pthread_spin_destroy(&nesucq->lock);
1068 -int nes_uresize_cq(struct ibv_cq *cq, int cqe)
1070 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
1077 -int nes_udestroy_cq(struct ibv_cq *cq)
1079 - struct nes_ucq *nesucq = to_nes_ucq(cq);
1082 - ret = ibv_cmd_destroy_cq(cq);
1086 - ret = ibv_cmd_dereg_mr(&nesucq->vmr);
1088 - fprintf(stderr, PFX "%s: Failed to deregister CQ Memory Region.\n", __FUNCTION__);
1090 - /* Free CQ the memory */
1091 - free((struct nes_hw_cqe *)nesucq->cqes);
1092 - pthread_spin_destroy(&nesucq->lock);
1098 -#define NES_CQ_BUF_OV_ERR 0x3
1101 -int nes_ima_upoll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *entry)
1103 - struct nes_ucq *nesucq = to_nes_ucq(cq);
1104 - struct nes_uvcontext *nesvctx = to_nes_uctx(cq->context);
1105 - uint32_t cqe_misc;
1106 - int cqe_count = 0;
1110 - volatile struct nes_hw_nic_cqe *cqe = NULL;
1111 - volatile struct nes_hw_nic_cqe *cqes;
1113 - struct nes_uqp *nesuqp = nesucq->udqp;
1114 - uint32_t vlan_tag = 0;
1116 - cqes = (volatile struct nes_hw_nic_cqe *)nesucq->cqes;
1117 - head = nesucq->head;
1118 - cq_size = nesucq->size;
1120 - if (!nesuqp || !nesvctx)
1122 - if (nesuqp->ibv_qp.state == IBV_QPS_ERR) {
1123 - while (cqe_count < num_entries) {
1124 - memset(entry, 0, sizeof *entry);
1126 - if (nesuqp->recv_cq == nesucq) {
1127 - if (nesuqp->rq_tail != nesuqp->rq_head) {
1128 - /* Working on a RQ Completion*/
1130 - nesuqp->recv_wr_id[nesuqp->rq_tail];
1131 - if (++nesuqp->rq_tail >= nesuqp->rq_size)
1132 - nesuqp->rq_tail = 0;
1136 - if (nesuqp->send_cq == nesucq) {
1137 - if (nesuqp->sq_tail != nesuqp->sq_head) {
1139 - nesuqp->send_wr_id[nesuqp->sq_tail];
1140 - /* Working on a SQ Completion*/
1141 - if (++nesuqp->sq_tail >= nesuqp->sq_size)
1142 - nesuqp->sq_tail = 0;
1146 - entry->status = IBV_WC_WR_FLUSH_ERR;
1153 - while (cqe_count < num_entries) {
1154 - const enum ibv_wc_opcode INVAL_OP = -1;
1156 - entry->opcode = INVAL_OP;
1157 - cqe = &cqes[head];
1159 - le32toh(cqe->cqe_words[NES_NIC_CQE_MISC_IDX]);
1160 - if (cqe_misc & NES_NIC_CQE_VALID) {
1161 - memset(entry, 0, sizeof *entry);
1162 - entry->opcode = INVAL_OP;
1163 - cqe->cqe_words[NES_NIC_CQE_MISC_IDX] = 0;
1164 - entry->status = (cqe_misc & NES_NIC_CQE_ERRV_MASK) >>
1165 - NES_NIC_CQE_ERRV_SHIFT;
1166 - entry->qp_num = nesuqp->qp_id;
1167 - entry->src_qp = nesuqp->qp_id;
1168 - if (cqe_misc & NES_NIC_CQE_SQ) {
1169 - entry->opcode = IBV_WC_SEND;
1172 - nesuqp->send_wr_id[nesuqp->sq_tail];
1174 - /* Working on a SQ Completion*/
1175 - if (++nesuqp->sq_tail >= nesuqp->sq_size)
1176 - nesuqp->sq_tail = 0;
1178 - /* no CRC counting at all - all packets
1179 - go to higher layer as they are received -
1180 - the fastest path */
1182 - entry->byte_len = cqe_misc & 0xffff;
1183 - entry->opcode = IBV_WC_RECV;
1186 - nesuqp->recv_wr_id[nesuqp->rq_tail];
1187 - if (cqe_misc & NES_NIC_CQE_TAG_VALID) {
1188 - vlan_tag = le32toh(
1189 - cqe->cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX])
1191 - entry->sl = (vlan_tag >> 12) & 0x0f;
1192 - entry->pkey_index = vlan_tag & 0x0fff;
1193 - entry->wc_flags |= NES_WC_WITH_VLAN;
1197 - /* Working on a RQ Completion*/
1198 - if (++nesuqp->rq_tail >= nesuqp->rq_size)
1199 - nesuqp->rq_tail = 0;
1200 - if (entry->status == NES_CQ_BUF_OV_ERR)
1201 - entry->status = IBV_WC_LOC_LEN_ERR;
1204 - if (++head >= cq_size)
1207 - if (entry->opcode != INVAL_OP) {
1208 - /* it is possible that no entry will be
1214 - nesvctx->nesupd->udoorbell->cqe_alloc =
1215 - htole32(nesucq->cq_id | (1 << 16));
1220 - nesucq->head = head;
1227 -int nes_upoll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *entry)
1230 - struct nes_ucq *nesucq;
1231 - struct nes_uvcontext *nesvctx = NULL;
1232 - struct nes_uqp *nesuqp;
1236 - uint32_t wqe_index;
1237 - uint32_t wq_tail = 0;
1238 - struct nes_hw_cqe cqe;
1240 - int move_cq_head = 1;
1241 - uint32_t err_code;
1243 - nesucq = to_nes_ucq(cq);
1244 - nesvctx = to_nes_uctx(cq->context);
1246 - if (nesucq->cq_id < 64)
1247 - return nes_ima_upoll_cq(cq, num_entries, entry);
1249 - pthread_spin_lock(&nesucq->lock);
1251 - head = nesucq->head;
1252 - cq_size = nesucq->size;
1254 - while (cqe_count<num_entries) {
1255 - if ((le32toh(nesucq->cqes[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) == 0)
1258 - /* Make sure we read CQ entry contents *after* we've checked the valid bit. */
1259 - udma_from_device_barrier();
1261 - cqe = (volatile struct nes_hw_cqe)nesucq->cqes[head];
1263 - /* parse CQE, get completion context from WQE (either rq or sq */
1264 - wqe_index = le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]) & 511;
1265 - u64temp = ((uint64_t) (le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))) |
1266 - (((uint64_t) (le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32);
1268 - if (likely(u64temp)) {
1269 - nesuqp = (struct nes_uqp *)(uintptr_t)(u64temp & (~1023));
1270 - memset(entry, 0, sizeof *entry);
1271 - if (likely(le32toh(cqe.cqe_words[NES_CQE_ERROR_CODE_IDX]) == 0)) {
1272 - entry->status = IBV_WC_SUCCESS;
1274 - err_code = le32toh(cqe.cqe_words[NES_CQE_ERROR_CODE_IDX]);
1275 - if (NES_IWARP_CQE_MAJOR_DRV == (err_code >> 16)) {
1276 - entry->status = err_code & 0x0000ffff;
1278 - entry->status = IBV_WC_WR_FLUSH_ERR;
1279 - if (le32toh(cqe.cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_SQ) {
1280 - if (wqe_index == 0 && nesuqp->rdma0_msg) {
1281 - nesuqp->sq_tail = (wqe_index+1)&(nesuqp->sq_size - 1);
1283 - wq_tail = nesuqp->sq_tail;
1284 - nesuqp->rdma0_msg = 0;
1285 - goto nes_upoll_cq_update;
1290 - entry->qp_num = nesuqp->qp_id;
1291 - entry->src_qp = nesuqp->qp_id;
1292 - nesuqp->rdma0_msg = 0;
1294 - if (le32toh(cqe.cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_SQ) {
1295 - /* Working on a SQ Completion*/
1296 - wrid = ((uint64_t) le32toh(nesuqp->sq_vbase[wqe_index].wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX])) |
1297 - (((uint64_t) le32toh(nesuqp->sq_vbase[wqe_index].wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32);
1298 - entry->byte_len = le32toh(nesuqp->sq_vbase[wqe_index].wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]);
1300 - switch (le32toh(nesuqp->sq_vbase[wqe_index].
1301 - wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) {
1302 - case NES_IWARP_SQ_OP_RDMAW:
1303 - /* fprintf(stderr, PFX "%s: Operation = RDMA WRITE.\n",
1304 - __FUNCTION__ ); */
1305 - entry->opcode = IBV_WC_RDMA_WRITE;
1307 - case NES_IWARP_SQ_OP_RDMAR:
1308 - /* fprintf(stderr, PFX "%s: Operation = RDMA READ.\n",
1309 - __FUNCTION__ ); */
1310 - entry->opcode = IBV_WC_RDMA_READ;
1311 - entry->byte_len = le32toh(nesuqp->sq_vbase[wqe_index].
1312 - wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]);
1314 - case NES_IWARP_SQ_OP_SENDINV:
1315 - case NES_IWARP_SQ_OP_SENDSEINV:
1316 - case NES_IWARP_SQ_OP_SEND:
1317 - case NES_IWARP_SQ_OP_SENDSE:
1318 - /* fprintf(stderr, PFX "%s: Operation = Send.\n",
1319 - __FUNCTION__ ); */
1320 - entry->opcode = IBV_WC_SEND;
1324 - nesuqp->sq_tail = (wqe_index+1)&(nesuqp->sq_size - 1);
1325 - if ((entry->status != IBV_WC_SUCCESS) && (nesuqp->sq_tail != nesuqp->sq_head)) {
1327 - wq_tail = nesuqp->sq_tail;
1330 - /* Working on a RQ Completion*/
1331 - entry->byte_len = le32toh(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]);
1332 - wrid = ((uint64_t) le32toh(nesuqp->rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX])) |
1333 - (((uint64_t) le32toh(nesuqp->rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32);
1334 - entry->opcode = IBV_WC_RECV;
1336 - nesuqp->rq_tail = (wqe_index+1)&(nesuqp->rq_size - 1);
1337 - if ((entry->status != IBV_WC_SUCCESS) && (nesuqp->rq_tail != nesuqp->rq_head)) {
1339 - wq_tail = nesuqp->rq_tail;
1343 - entry->wr_id = wrid;
1347 -nes_upoll_cq_update:
1348 - if (move_cq_head) {
1349 - nesucq->cqes[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
1350 - if (++head >= cq_size)
1352 - nesucq->polled_completions++;
1354 - if ((nesucq->polled_completions > (cq_size/2)) ||
1355 - (nesucq->polled_completions == 255)) {
1356 - if (nesvctx == NULL)
1357 - nesvctx = to_nes_uctx(cq->context);
1358 - nesvctx->nesupd->udoorbell->cqe_alloc = htole32(nesucq->cq_id |
1359 - (nesucq->polled_completions << 16));
1360 - nesucq->polled_completions = 0;
1363 - /* Update the wqe index and set status to flush */
1364 - wqe_index = le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
1365 - wqe_index = (wqe_index & (~511)) | wq_tail;
1366 - nesucq->cqes[head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] =
1367 - htole32(wqe_index);
1368 - nesucq->cqes[head].cqe_words[NES_CQE_ERROR_CODE_IDX] =
1369 - htole32((NES_IWARP_CQE_MAJOR_FLUSH << 16) | NES_IWARP_CQE_MINOR_FLUSH);
1370 - move_cq_head = 1; /* ready for next pass */
1374 - if (nesucq->polled_completions) {
1375 - if (nesvctx == NULL)
1376 - nesvctx = to_nes_uctx(cq->context);
1377 - nesvctx->nesupd->udoorbell->cqe_alloc = htole32(nesucq->cq_id |
1378 - (nesucq->polled_completions << 16));
1379 - nesucq->polled_completions = 0;
1381 - nesucq->head = head;
1383 - pthread_spin_unlock(&nesucq->lock);
1390 - * nes_upoll_cq_no_db_read
1392 -int nes_upoll_cq_no_db_read(struct ibv_cq *cq, int num_entries, struct ibv_wc *entry)
1395 - struct nes_ucq *nesucq;
1396 - struct nes_uvcontext *nesvctx = NULL;
1397 - struct nes_uqp *nesuqp;
1401 - uint32_t wqe_index;
1402 - uint32_t wq_tail = 0;
1403 - struct nes_hw_cqe cqe;
1405 - int move_cq_head = 1;
1406 - uint32_t err_code;
1408 - nesucq = to_nes_ucq(cq);
1409 - nesvctx = to_nes_uctx(cq->context);
1411 - if (nesucq->cq_id < 64)
1412 - return nes_ima_upoll_cq(cq, num_entries, entry);
1414 - pthread_spin_lock(&nesucq->lock);
1416 - head = nesucq->head;
1417 - cq_size = nesucq->size;
1419 - while (cqe_count<num_entries) {
1420 - if ((le32toh(nesucq->cqes[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) == 0)
1423 - /* Make sure we read CQ entry contents *after* we've checked the valid bit. */
1424 - udma_from_device_barrier();
1426 - cqe = (volatile struct nes_hw_cqe)nesucq->cqes[head];
1428 - /* parse CQE, get completion context from WQE (either rq or sq */
1429 - wqe_index = le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]) & 511;
1430 - u64temp = ((uint64_t) (le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))) |
1431 - (((uint64_t) (le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32);
1433 - if (likely(u64temp)) {
1434 - nesuqp = (struct nes_uqp *)(uintptr_t)(u64temp & (~1023));
1435 - memset(entry, 0, sizeof *entry);
1436 - if (likely(le32toh(cqe.cqe_words[NES_CQE_ERROR_CODE_IDX]) == 0)) {
1437 - entry->status = IBV_WC_SUCCESS;
1439 - err_code = le32toh(cqe.cqe_words[NES_CQE_ERROR_CODE_IDX]);
1440 - if (NES_IWARP_CQE_MAJOR_DRV == (err_code >> 16))
1441 - entry->status = err_code & 0x0000ffff;
1443 - entry->status = IBV_WC_WR_FLUSH_ERR;
1445 - entry->qp_num = nesuqp->qp_id;
1446 - entry->src_qp = nesuqp->qp_id;
1448 - if (le32toh(cqe.cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_SQ) {
1449 - /* Working on a SQ Completion*/
1450 - wrid = ((uint64_t) le32toh(nesuqp->sq_vbase[wqe_index].wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX])) |
1451 - (((uint64_t) le32toh(nesuqp->sq_vbase[wqe_index].wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32);
1452 - entry->byte_len = le32toh(nesuqp->sq_vbase[wqe_index].wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]);
1454 - switch (le32toh(nesuqp->sq_vbase[wqe_index].
1455 - wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) {
1456 - case NES_IWARP_SQ_OP_RDMAW:
1457 - /* fprintf(stderr, PFX "%s: Operation = RDMA WRITE.\n",
1458 - __FUNCTION__ ); */
1459 - entry->opcode = IBV_WC_RDMA_WRITE;
1461 - case NES_IWARP_SQ_OP_RDMAR:
1462 - /* fprintf(stderr, PFX "%s: Operation = RDMA READ.\n",
1463 - __FUNCTION__ ); */
1464 - entry->opcode = IBV_WC_RDMA_READ;
1465 - entry->byte_len = le32toh(nesuqp->sq_vbase[wqe_index].
1466 - wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]);
1468 - case NES_IWARP_SQ_OP_SENDINV:
1469 - case NES_IWARP_SQ_OP_SENDSEINV:
1470 - case NES_IWARP_SQ_OP_SEND:
1471 - case NES_IWARP_SQ_OP_SENDSE:
1472 - /* fprintf(stderr, PFX "%s: Operation = Send.\n",
1473 - __FUNCTION__ ); */
1474 - entry->opcode = IBV_WC_SEND;
1478 - nesuqp->sq_tail = (wqe_index+1)&(nesuqp->sq_size - 1);
1479 - if ((entry->status != IBV_WC_SUCCESS) && (nesuqp->sq_tail != nesuqp->sq_head)) {
1481 - wq_tail = nesuqp->sq_tail;
1484 - /* Working on a RQ Completion*/
1485 - entry->byte_len = le32toh(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]);
1486 - wrid = ((uint64_t) le32toh(nesuqp->rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX])) |
1487 - (((uint64_t) le32toh(nesuqp->rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32);
1488 - entry->opcode = IBV_WC_RECV;
1490 - nesuqp->rq_tail = (wqe_index+1)&(nesuqp->rq_size - 1);
1491 - if ((entry->status != IBV_WC_SUCCESS) && (nesuqp->rq_tail != nesuqp->rq_head)) {
1493 - wq_tail = nesuqp->rq_tail;
1497 - entry->wr_id = wrid;
1502 - if (move_cq_head) {
1503 - nesucq->cqes[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
1504 - if (++head >= cq_size)
1506 - nesucq->polled_completions++;
1508 - if ((nesucq->polled_completions > (cq_size/2)) ||
1509 - (nesucq->polled_completions == 255)) {
1510 - if (nesvctx == NULL)
1511 - nesvctx = to_nes_uctx(cq->context);
1512 - nesvctx->nesupd->udoorbell->cqe_alloc = htole32(nesucq->cq_id |
1513 - (nesucq->polled_completions << 16));
1514 - nesucq->polled_completions = 0;
1517 - /* Update the wqe index and set status to flush */
1518 - wqe_index = le32toh(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
1519 - wqe_index = (wqe_index & (~511)) | wq_tail;
1520 - nesucq->cqes[head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] =
1521 - htole32(wqe_index);
1522 - nesucq->cqes[head].cqe_words[NES_CQE_ERROR_CODE_IDX] =
1523 - htole32((NES_IWARP_CQE_MAJOR_FLUSH << 16) | NES_IWARP_CQE_MINOR_FLUSH);
1524 - move_cq_head = 1; /* ready for next pass */
1528 - if (nesucq->polled_completions) {
1529 - if (nesvctx == NULL)
1530 - nesvctx = to_nes_uctx(cq->context);
1531 - nesvctx->nesupd->udoorbell->cqe_alloc = htole32(nesucq->cq_id |
1532 - (nesucq->polled_completions << 16));
1533 - nesucq->polled_completions = 0;
1535 - nesucq->head = head;
1537 - pthread_spin_unlock(&nesucq->lock);
1545 -static void nes_arm_cq(struct nes_ucq *nesucq, struct nes_uvcontext *nesvctx, int sol)
1549 - cq_arm = nesucq->cq_id;
1552 - cq_arm |= NES_CQE_ALLOC_NOTIFY_SE;
1554 - cq_arm |= NES_CQE_ALLOC_NOTIFY_NEXT;
1556 - nesvctx->nesupd->udoorbell->cqe_alloc = htole32(cq_arm);
1557 - nesucq->is_armed = 1;
1558 - nesucq->arm_sol = sol;
1559 - nesucq->skip_arm = 0;
1560 - nesucq->skip_sol = 1;
1566 -int nes_uarm_cq(struct ibv_cq *cq, int solicited)
1568 - struct nes_ucq *nesucq;
1569 - struct nes_uvcontext *nesvctx;
1571 - nesucq = to_nes_ucq(cq);
1572 - nesvctx = to_nes_uctx(cq->context);
1574 - pthread_spin_lock(&nesucq->lock);
1576 - if (nesucq->is_armed) {
1577 - /* don't arm again unless... */
1578 - if ((nesucq->arm_sol) && (!solicited)) {
1579 - /* solicited changed from notify SE to notify next */
1580 - nes_arm_cq(nesucq, nesvctx, solicited);
1582 - nesucq->skip_arm = 1;
1583 - nesucq->skip_sol &= solicited;
1586 - nes_arm_cq(nesucq, nesvctx, solicited);
1589 - pthread_spin_unlock(&nesucq->lock);
1598 -void nes_cq_event(struct ibv_cq *cq)
1600 - struct nes_ucq *nesucq;
1602 - nesucq = to_nes_ucq(cq);
1604 - pthread_spin_lock(&nesucq->lock);
1606 - if (nesucq->skip_arm) {
1607 - struct nes_uvcontext *nesvctx;
1608 - nesvctx = to_nes_uctx(cq->context);
1609 - nes_arm_cq(nesucq, nesvctx, nesucq->skip_sol);
1611 - nesucq->is_armed = 0;
1614 - pthread_spin_unlock(&nesucq->lock);
1621 -struct ibv_srq *nes_ucreate_srq(struct ibv_pd *pd, struct ibv_srq_init_attr *attr)
1623 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
1624 - return (void *)-ENOSYS;
1631 -int nes_umodify_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr, int attr_mask)
1633 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
1639 - * nes_udestroy_srq
1641 -int nes_udestroy_srq(struct ibv_srq *srq)
1643 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
1649 - * nes_upost_srq_recv
1651 -int nes_upost_srq_recv(struct ibv_srq *ibsrq, struct ibv_recv_wr *wr,
1652 - struct ibv_recv_wr **bad_wr)
1654 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
1661 - * will not invoke registration of memory reqion and will allow
1662 - * the kernel module to allocate big chunk of contigous memory
1663 - * for sq and rq... returns 1 if succeeds, 0 if fails..
1665 -static int nes_mmapped_qp(struct nes_uqp *nesuqp, struct ibv_pd *pd, struct ibv_qp_init_attr *attr,
1666 - struct nes_ucreate_qp_resp *resp)
1669 - unsigned long mmap_offset;
1670 - struct nes_ucreate_qp cmd;
1671 - struct nes_uvcontext *nesvctx = to_nes_uctx(pd->context);
1674 - memset (&cmd, 0, sizeof(cmd) );
1675 - cmd.user_qp_buffer = (__u64) ((uintptr_t) nesuqp);
1677 - /* fprintf(stderr, PFX "%s entering==>\n",__FUNCTION__); */
1678 - ret = ibv_cmd_create_qp(pd, &nesuqp->ibv_qp, attr, &cmd.ibv_cmd, sizeof cmd,
1679 - &resp->ibv_resp, sizeof (struct nes_ucreate_qp_resp) );
1682 - nesuqp->send_cq = to_nes_ucq(attr->send_cq);
1683 - nesuqp->recv_cq = to_nes_ucq(attr->recv_cq);
1684 - nesuqp->sq_db_index = resp->mmap_sq_db_index;
1685 - nesuqp->rq_db_index = resp->mmap_rq_db_index;
1686 - nesuqp->sq_size = resp->actual_sq_size;
1687 - nesuqp->rq_size = resp->actual_rq_size;
1689 - /* Map the SQ/RQ buffers */
1690 - mmap_offset = nesvctx->max_pds*page_size;
1691 - mmap_offset += (((sizeof(struct nes_hw_qp_wqe) * nesvctx->wq_size) + page_size-1) &
1692 - (~(page_size-1)))*nesuqp->sq_db_index;
1694 - nesuqp->sq_vbase = mmap(NULL, (nesuqp->sq_size+nesuqp->rq_size) *
1695 - sizeof(struct nes_hw_qp_wqe), PROT_WRITE | PROT_READ,
1696 - MAP_SHARED, pd->context->cmd_fd, mmap_offset);
1699 - if (nesuqp->sq_vbase == MAP_FAILED) {
1702 - nesuqp->rq_vbase = (struct nes_hw_qp_wqe *)(((char *)nesuqp->sq_vbase) +
1703 - (nesuqp->sq_size*sizeof(struct nes_hw_qp_wqe)));
1704 - *((unsigned int *)nesuqp->sq_vbase) = 0;
1705 - nesuqp->mapping = NES_QP_MMAP;
1713 - * invoke registration of memory reqion. This method is used
1714 - * when kernel can not allocate qp memory (contigous physical).
1716 - * returns 1 if succeeds, 0 if fails..
1718 -static int nes_vmapped_qp(struct nes_uqp *nesuqp, struct ibv_pd *pd, struct ibv_qp_init_attr *attr,
1719 - struct nes_ucreate_qp_resp *resp, int sqdepth, int rqdepth)
1721 - struct nes_ucreate_qp cmd;
1722 - struct nes_ureg_mr reg_mr_cmd;
1723 - struct ib_uverbs_reg_mr_resp reg_mr_resp;
1727 - // fprintf(stderr, PFX "%s\n", __FUNCTION__);
1728 - totalqpsize = (sqdepth + rqdepth) * sizeof (struct nes_hw_qp_wqe) ;
1729 - nesuqp->sq_vbase = memalign(page_size, totalqpsize);
1730 - if (!nesuqp->sq_vbase) {
1731 - // fprintf(stderr, PFX "CREATE_QP could not allocate mem of size %d\n", totalqpsize);
1734 - nesuqp->rq_vbase = (struct nes_hw_qp_wqe *) (((char *) nesuqp->sq_vbase) +
1735 - (nesuqp->sq_size * sizeof(struct nes_hw_qp_wqe)));
1737 - reg_mr_cmd.reg_type = IWNES_MEMREG_TYPE_QP;
1739 - //fprintf(stderr, PFX "qp_rq_vbase = %p qp_sq_vbase=%p reg_mr = %p\n",
1740 - // nesuqp->rq_vbase, nesuqp->sq_vbase, &nesuqp->mr);
1742 - ret = ibv_cmd_reg_mr(pd, (void *)nesuqp->sq_vbase,totalqpsize,
1743 - (uintptr_t)nesuqp->sq_vbase,
1744 - IBV_ACCESS_LOCAL_WRITE, &nesuqp->vmr,
1745 - ®_mr_cmd.ibv_cmd, sizeof(reg_mr_cmd),
1746 - ®_mr_resp, sizeof(reg_mr_resp));
1748 - // fprintf(stderr, PFX "%s ibv_cmd_reg_mr failed (ret = %d).\n", __FUNCTION__, ret);
1749 - free((void *) nesuqp->sq_vbase);
1752 - // So now the memory has been registered..
1753 - memset (&cmd, 0, sizeof(cmd) );
1754 - cmd.user_wqe_buffers = (__u64) ((uintptr_t) nesuqp->sq_vbase);
1755 - cmd.user_qp_buffer = (__u64) ((uintptr_t) nesuqp);
1756 - ret = ibv_cmd_create_qp(pd, &nesuqp->ibv_qp, attr, &cmd.ibv_cmd, sizeof cmd,
1757 - &resp->ibv_resp, sizeof (struct nes_ucreate_qp_resp) );
1759 - ibv_cmd_dereg_mr(&nesuqp->vmr);
1760 - free((void *)nesuqp->sq_vbase);
1763 - *((unsigned int *)nesuqp->rq_vbase) = 0;
1764 - nesuqp->send_cq = to_nes_ucq(attr->send_cq);
1765 - nesuqp->recv_cq = to_nes_ucq(attr->recv_cq);
1766 - nesuqp->sq_db_index = resp->mmap_sq_db_index;
1767 - nesuqp->rq_db_index = resp->mmap_rq_db_index;
1768 - nesuqp->sq_size = resp->actual_sq_size;
1769 - nesuqp->rq_size = resp->actual_rq_size;
1770 - nesuqp->mapping = NES_QP_VMAP;
1776 - * nes_qp_get_qdepth
1777 - * This routine will return the size of qdepth to be set for one
1778 - * of the qp (sq or rq)
1780 -static int nes_qp_get_qdepth(uint32_t qdepth, uint32_t maxsges)
1784 - /* Do sanity check on the parameters */
1785 - /* Should the following be 510 or 511 */
1786 - if ((qdepth > 510) || (maxsges > 4) )
1789 - /* Do we need to do the following of */
1790 - /* we can just return the actual value.. needed for alignment */
1793 - else if (qdepth < 128)
1795 - else retdepth = 512;
1804 -struct ibv_qp *nes_ucreate_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
1806 - struct nes_ucreate_qp_resp resp;
1807 - struct nes_uvcontext *nesvctx = to_nes_uctx(pd->context);
1808 - struct nes_uqp *nesuqp;
1809 - int sqdepth, rqdepth;
1812 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
1814 - /* Sanity check QP size before proceeding */
1815 - sqdepth = nes_qp_get_qdepth(attr->cap.max_send_wr, attr->cap.max_send_sge);
1817 - fprintf(stderr, PFX "%s Bad sq attr parameters max_send_wr=%d max_send_sge=%d\n",
1818 - __FUNCTION__, attr->cap.max_send_wr,attr->cap.max_send_sge);
1822 - rqdepth = nes_qp_get_qdepth(attr->cap.max_recv_wr, attr->cap.max_recv_sge);
1824 - fprintf(stderr, PFX "%s Bad rq attr parameters max_recv_wr=%d max_recv_sge=%d\n",
1825 - __FUNCTION__, attr->cap.max_recv_wr,attr->cap.max_recv_sge);
1829 - nesuqp = memalign(1024, sizeof(*nesuqp));
1832 - memset(nesuqp, 0, sizeof(*nesuqp));
1834 - if (pthread_spin_init(&nesuqp->lock, PTHREAD_PROCESS_PRIVATE)) {
1839 - /* Initially setting it up so we will know how much memory to allocate for mapping */
1840 - /* also setting it up in attr.. If we do not want to modify the attr struct, we */
1841 - /* can save the original values and restore them before return. */
1842 - nesuqp->sq_size = attr->cap.max_send_wr = sqdepth;
1843 - nesuqp->rq_size = attr->cap.max_recv_wr = rqdepth;
1845 - nesuqp->sq_sig_all = attr->sq_sig_all;
1846 - if (nesvctx->virtwq) {
1847 - status = nes_vmapped_qp(nesuqp,pd, attr,&resp,sqdepth,rqdepth);
1849 - status = nes_mmapped_qp(nesuqp,pd,attr, &resp);
1853 - pthread_spin_destroy(&nesuqp->lock);
1859 - /* The following are the common parameters no matter how the */
1860 - /* sq and rq memory was mapped.. */
1862 - /* Account for LSMM, in theory, could get overrun if app preposts to SQ */
1863 - nesuqp->sq_head = 1;
1864 - nesuqp->sq_tail = 1;
1865 - nesuqp->qp_id = resp.qp_id;
1866 - nesuqp->nes_drv_opt = resp.nes_drv_opt;
1867 - nesuqp->ibv_qp.qp_num = resp.qp_id;
1868 - nesuqp->rdma0_msg = 1;
1870 - return &nesuqp->ibv_qp;
1877 -int nes_uquery_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
1878 - int attr_mask, struct ibv_qp_init_attr *init_attr)
1880 - struct ibv_query_qp cmd;
1882 - /* fprintf(stderr, PFX "nes_uquery_qp: calling ibv_cmd_query_qp\n"); */
1884 - return ibv_cmd_query_qp(qp, attr, attr_mask, init_attr, &cmd, sizeof(cmd));
1891 -int nes_umodify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask)
1893 - struct ibv_modify_qp cmd = {};
1894 - return ibv_cmd_modify_qp(qp, attr, attr_mask, &cmd, sizeof cmd);
1901 -static void nes_clean_cq(struct nes_uqp *nesuqp, struct nes_ucq *nesucq)
1908 - pthread_spin_lock(&nesucq->lock);
1910 - cq_head = nesucq->head;
1911 - while (le32toh(nesucq->cqes[cq_head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) {
1912 - udma_from_device_barrier();
1913 - lo = le32toh(nesucq->cqes[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
1914 - hi = le32toh(nesucq->cqes[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]);
1915 - u64temp = (((uint64_t)hi) << 32) | ((uint64_t)lo);
1916 - u64temp &= (~1023);
1917 - if (u64temp == (uint64_t)(uintptr_t)nesuqp) {
1918 - /* Zero the context value so cqe will be ignored */
1919 - nesucq->cqes[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] = 0;
1920 - nesucq->cqes[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX] = 0;
1923 - if (++cq_head >= nesucq->size)
1927 - pthread_spin_unlock(&nesucq->lock);
1934 -int nes_udestroy_qp(struct ibv_qp *qp)
1936 - struct nes_uqp *nesuqp = to_nes_uqp(qp);
1939 - // fprintf(stderr, PFX "%s addr&mr= %p \n", __FUNCTION__, &nesuqp->mr );
1941 - if (nesuqp->mapping == NES_QP_VMAP) {
1942 - ret = ibv_cmd_dereg_mr(&nesuqp->vmr);
1944 - fprintf(stderr, PFX "%s dereg_mr FAILED\n", __FUNCTION__);
1945 - free((void *)nesuqp->sq_vbase);
1948 - if (nesuqp->mapping == NES_QP_MMAP) {
1949 - munmap((void *)nesuqp->sq_vbase, (nesuqp->sq_size+nesuqp->rq_size) *
1950 - sizeof(struct nes_hw_qp_wqe));
1953 - ret = ibv_cmd_destroy_qp(qp);
1955 - fprintf(stderr, PFX "%s FAILED\n", __FUNCTION__);
1959 - pthread_spin_destroy(&nesuqp->lock);
1961 - /* Clean any pending completions from the cq(s) */
1962 - if (nesuqp->send_cq)
1963 - nes_clean_cq(nesuqp, nesuqp->send_cq);
1965 - if ((nesuqp->recv_cq) && (nesuqp->recv_cq != nesuqp->send_cq))
1966 - nes_clean_cq(nesuqp, nesuqp->recv_cq);
1975 -int nes_upost_send(struct ibv_qp *ib_qp, struct ibv_send_wr *ib_wr,
1976 - struct ibv_send_wr **bad_wr)
1979 - struct nes_uqp *nesuqp = to_nes_uqp(ib_qp);
1980 - struct nes_upd *nesupd = to_nes_upd(ib_qp->pd);
1981 - struct nes_hw_qp_wqe volatile *wqe;
1983 - uint32_t qsize = nesuqp->sq_size;
1986 - uint32_t wqe_count = 0;
1987 - uint32_t outstanding_wqes;
1988 - uint32_t total_payload_length = 0;
1991 - pthread_spin_lock(&nesuqp->lock);
1992 - udma_to_device_barrier();
1994 - head = nesuqp->sq_head;
1996 - if (unlikely(nesuqp->qperr)) {
2001 - /* Check for SQ overflow */
2002 - outstanding_wqes = head + (2 * qsize) - nesuqp->sq_tail;
2003 - outstanding_wqes &= qsize - 1;
2004 - if (unlikely(outstanding_wqes == (qsize - 1))) {
2008 - if (unlikely(ib_wr->num_sge > 4)) {
2013 - wqe = (struct nes_hw_qp_wqe *)&nesuqp->sq_vbase[head];
2014 - /* fprintf(stderr, PFX "%s: QP%u: processing sq wqe at %p, head = %u.\n",
2015 - __FUNCTION__, nesuqp->qp_id, wqe, head); */
2016 - u64temp = (uint64_t) ib_wr->wr_id;
2017 - wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX] = htole32((uint32_t)u64temp);
2018 - wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX] = htole32((uint32_t)(u64temp>>32));
2019 - u64temp = (uint64_t)((uintptr_t)nesuqp);
2020 - wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX] = htole32((uint32_t)u64temp);
2021 - wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_HIGH_IDX] = htole32((uint32_t)(u64temp>>32));
2022 - udma_ordering_write_barrier();
2023 - wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX] |= htole32(head);
2025 - switch (ib_wr->opcode) {
2027 - case IBV_WR_SEND_WITH_IMM:
2028 - /* fprintf(stderr, PFX "%s: QP%u: processing sq wqe%u. Opcode = %s\n",
2029 - __FUNCTION__, nesuqp->qp_id, head, "Send"); */
2030 - if (ib_wr->send_flags & IBV_SEND_SOLICITED) {
2031 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = htole32(NES_IWARP_SQ_OP_SENDSE);
2033 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = htole32(NES_IWARP_SQ_OP_SEND);
2036 - if (ib_wr->send_flags & IBV_SEND_FENCE) {
2037 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] |= htole32(NES_IWARP_SQ_WQE_READ_FENCE);
2040 - /* if (ib_wr->send_flags & IBV_SEND_INLINE) {
2041 - fprintf(stderr, PFX "%s: Send SEND_INLINE, length=%d\n",
2042 - __FUNCTION__, ib_wr->sg_list[0].length);
2044 - if ((ib_wr->send_flags & IBV_SEND_INLINE) && (ib_wr->sg_list[0].length <= 64) &&
2045 - ((nesuqp->nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
2046 - (ib_wr->num_sge == 1)) {
2047 - memcpy((void *)&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX],
2048 - (void *)(intptr_t)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length);
2049 - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = htole32(ib_wr->sg_list[0].length);
2050 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] |= htole32(NES_IWARP_SQ_WQE_IMM_DATA);
2052 - total_payload_length = 0;
2053 - for (sge_index=0; sge_index < ib_wr->num_sge; sge_index++) {
2054 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX+(sge_index*4)] =
2055 - htole32((uint32_t)ib_wr->sg_list[sge_index].addr);
2056 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX+(sge_index*4)] =
2057 - htole32((uint32_t)(ib_wr->sg_list[sge_index].addr>>32));
2058 - wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX+(sge_index*4)] =
2059 - htole32(ib_wr->sg_list[sge_index].length);
2060 - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX+(sge_index*4)] =
2061 - htole32(ib_wr->sg_list[sge_index].lkey);
2062 - total_payload_length += ib_wr->sg_list[sge_index].length;
2064 - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
2065 - htole32(total_payload_length);
2069 - case IBV_WR_RDMA_WRITE:
2070 - case IBV_WR_RDMA_WRITE_WITH_IMM:
2071 - /* fprintf(stderr, PFX "%s:QP%u: processing sq wqe%u. Opcode = %s\n",
2072 - __FUNCTION__, nesuqp->qp_id, head, "Write"); */
2073 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = htole32(NES_IWARP_SQ_OP_RDMAW);
2075 - if (ib_wr->send_flags & IBV_SEND_FENCE) {
2076 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] |= htole32(NES_IWARP_SQ_WQE_READ_FENCE);
2078 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_STAG_IDX] = htole32(ib_wr->wr.rdma.rkey);
2079 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX] = htole32(
2080 - (uint32_t)ib_wr->wr.rdma.remote_addr);
2081 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_TO_HIGH_IDX] = htole32(
2082 - (uint32_t)(ib_wr->wr.rdma.remote_addr>>32));
2084 - /* if (ib_wr->send_flags & IBV_SEND_INLINE) {
2085 - fprintf(stderr, PFX "%s: Write SEND_INLINE, length=%d\n",
2086 - __FUNCTION__, ib_wr->sg_list[0].length);
2088 - if ((ib_wr->send_flags & IBV_SEND_INLINE) && (ib_wr->sg_list[0].length <= 64) &&
2089 - ((nesuqp->nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
2090 - (ib_wr->num_sge == 1)) {
2091 - memcpy((void *)&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX],
2092 - (void *)(intptr_t)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length);
2093 - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = htole32(ib_wr->sg_list[0].length);
2094 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] |= htole32(NES_IWARP_SQ_WQE_IMM_DATA);
2096 - total_payload_length = 0;
2097 - for (sge_index=0; sge_index < ib_wr->num_sge; sge_index++) {
2098 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX+(sge_index*4)] = htole32(
2099 - (uint32_t)ib_wr->sg_list[sge_index].addr);
2100 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX+(sge_index*4)] = htole32(
2101 - (uint32_t)(ib_wr->sg_list[sge_index].addr>>32));
2102 - wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX+(sge_index*4)] = htole32(
2103 - ib_wr->sg_list[sge_index].length);
2104 - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX+(sge_index*4)] = htole32(
2105 - ib_wr->sg_list[sge_index].lkey);
2106 - total_payload_length += ib_wr->sg_list[sge_index].length;
2108 - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = htole32(total_payload_length);
2110 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] =
2111 - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX];
2113 - case IBV_WR_RDMA_READ:
2114 - /* fprintf(stderr, PFX "%s:QP%u:processing sq wqe%u. Opcode = %s\n",
2115 - __FUNCTION__, nesuqp->qp_id, head, "Read"); */
2116 - /* IWarp only supports 1 sge for RDMA reads */
2117 - if (ib_wr->num_sge > 1) {
2121 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = htole32(NES_IWARP_SQ_OP_RDMAR);
2122 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX] = htole32((uint32_t)ib_wr->wr.rdma.remote_addr);
2123 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_TO_HIGH_IDX] = htole32((uint32_t)(ib_wr->wr.rdma.remote_addr>>32));
2124 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_STAG_IDX] = htole32(ib_wr->wr.rdma.rkey);
2125 - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = htole32(ib_wr->sg_list->length);
2126 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = htole32((uint32_t)ib_wr->sg_list->addr);
2127 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = htole32((uint32_t)(ib_wr->sg_list->addr>>32));
2128 - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = htole32(ib_wr->sg_list->lkey);
2136 - if ((ib_wr->send_flags & IBV_SEND_SIGNALED) || nesuqp->sq_sig_all) {
2137 - /* fprintf(stderr, PFX "%s:sq wqe%u is signalled\n", __FUNCTION__, head); */
2138 - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] |= htole32(NES_IWARP_SQ_WQE_SIGNALED_COMPL);
2140 - ib_wr = ib_wr->next;
2143 - if (head >= qsize)
2147 - nesuqp->sq_head = head;
2148 - udma_to_device_barrier();
2149 - while (wqe_count) {
2150 - counter = (wqe_count<(uint32_t)255) ? wqe_count : 255;
2151 - wqe_count -= counter;
2152 - nesupd->udoorbell->wqe_alloc = htole32((counter<<24) | 0x00800000 | nesuqp->qp_id);
2158 - pthread_spin_unlock(&nesuqp->lock);
2166 -int nes_upost_recv(struct ibv_qp *ib_qp, struct ibv_recv_wr *ib_wr,
2167 - struct ibv_recv_wr **bad_wr)
2170 - struct nes_uqp *nesuqp = to_nes_uqp(ib_qp);
2171 - struct nes_upd *nesupd = to_nes_upd(ib_qp->pd);
2172 - struct nes_hw_qp_wqe *wqe;
2174 - uint32_t qsize = nesuqp->rq_size;
2177 - uint32_t wqe_count = 0;
2178 - uint32_t outstanding_wqes;
2179 - uint32_t total_payload_length;
2182 - if (unlikely(ib_wr->num_sge > 4)) {
2187 - pthread_spin_lock(&nesuqp->lock);
2188 - udma_to_device_barrier();
2190 - head = nesuqp->rq_head;
2192 - if (unlikely(nesuqp->qperr)) {
2197 - /* Check for RQ overflow */
2198 - outstanding_wqes = head + (2 * qsize) - nesuqp->rq_tail;
2199 - outstanding_wqes &= qsize - 1;
2200 - if (unlikely(outstanding_wqes == (qsize - 1))) {
2205 - wqe = (struct nes_hw_qp_wqe *)&nesuqp->rq_vbase[head];
2206 - u64temp = ib_wr->wr_id;
2207 - wqe->wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX] =
2208 - htole32((uint32_t)u64temp);
2209 - wqe->wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX] =
2210 - htole32((uint32_t)(u64temp >> 32));
2211 - u64temp = (uint64_t)((uintptr_t)nesuqp);
2212 - wqe->wqe_words[NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX] =
2213 - htole32((uint32_t)u64temp);
2214 - wqe->wqe_words[NES_IWARP_RQ_WQE_COMP_CTX_HIGH_IDX] =
2215 - htole32((uint32_t)(u64temp >> 32));
2216 - udma_ordering_write_barrier();
2217 - wqe->wqe_words[NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX] |= htole32(head);
2219 - total_payload_length = 0;
2220 - for (sge_index=0; sge_index < ib_wr->num_sge; sge_index++) {
2221 - wqe->wqe_words[NES_IWARP_RQ_WQE_FRAG0_LOW_IDX+(sge_index*4)] =
2222 - htole32((uint32_t)ib_wr->sg_list[sge_index].addr);
2223 - wqe->wqe_words[NES_IWARP_RQ_WQE_FRAG0_HIGH_IDX+(sge_index*4)] =
2224 - htole32((uint32_t)(ib_wr->sg_list[sge_index].addr>>32));
2225 - wqe->wqe_words[NES_IWARP_RQ_WQE_LENGTH0_IDX+(sge_index*4)] =
2226 - htole32(ib_wr->sg_list[sge_index].length);
2227 - wqe->wqe_words[NES_IWARP_RQ_WQE_STAG0_IDX+(sge_index*4)] =
2228 - htole32(ib_wr->sg_list[sge_index].lkey);
2229 - total_payload_length += ib_wr->sg_list[sge_index].length;
2231 - wqe->wqe_words[NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX] = htole32(total_payload_length);
2233 - ib_wr = ib_wr->next;
2236 - if (head >= qsize)
2240 - nesuqp->rq_head = head;
2241 - udma_to_device_barrier();
2242 - while (wqe_count) {
2243 - counter = (wqe_count<(uint32_t)255) ? wqe_count : 255;
2244 - wqe_count -= counter;
2245 - nesupd->udoorbell->wqe_alloc = htole32((counter << 24) | nesuqp->qp_id);
2251 - pthread_spin_unlock(&nesuqp->lock);
2260 -struct ibv_ah *nes_ucreate_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
2262 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
2263 - return (void *)-ENOSYS;
2270 -int nes_udestroy_ah(struct ibv_ah *ah)
2272 - /* fprintf(stderr, PFX "%s\n", __FUNCTION__); */
2278 - * nes_uattach_mcast
2280 -int nes_uattach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid)
2283 - ret = ibv_cmd_attach_mcast(qp, gid, lid);
2284 - nes_debug(NES_DBG_UD, "%s ret=%d\n", __func__, ret);
2290 - * nes_udetach_mcast
2292 -int nes_udetach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid)
2295 - ret = ibv_cmd_detach_mcast(qp, gid, lid);
2296 - nes_debug(NES_DBG_UD, "%s ret=%d\n", __func__, ret);
2303 -void nes_async_event(struct ibv_context *context,
2304 - struct ibv_async_event *event)
2306 - struct nes_uqp *nesuqp;
2308 - switch (event->event_type) {
2309 - case IBV_EVENT_QP_FATAL:
2310 - case IBV_EVENT_QP_ACCESS_ERR:
2311 - /* Do not let application queue anything else to the qp */
2312 - nesuqp = to_nes_uqp(event->element.qp);
2313 - nesuqp->qperr = 1;