diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d6dde332..21d8de6bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -754,7 +754,7 @@ add_subdirectory(providers/vmw_pvrdma) endif() add_subdirectory(providers/hfi1verbs) -add_subdirectory(providers/ipathverbs) +add_subdirectory(providers/hfi2verbs) add_subdirectory(providers/rxe) add_subdirectory(providers/rxe/man) add_subdirectory(providers/siw) diff --git a/MAINTAINERS b/MAINTAINERS index ed1dc0d6f..52da18cb1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -71,6 +71,11 @@ M: Dennis Dalessandro S: Supported F: providers/hfi1verbs/ +HFI2 USERSPACE PROVIDER (for hf2.ko) +M: Dennis Dalessandro +S: Supported +F: providers/hfi2verbs/ + HNS USERSPACE PROVIDER (for hns-roce-hw-v2.ko) M: Junxian Huang M: Chengchang Tang diff --git a/debian/rdma-core.install b/debian/rdma-core.install index 30c22ff72..7d35cec28 100644 --- a/debian/rdma-core.install +++ b/debian/rdma-core.install @@ -1,7 +1,6 @@ etc/init.d/iwpmd etc/iwpmd.conf etc/modprobe.d/mlx4.conf -etc/modprobe.d/truescale.conf etc/rdma/modules/infiniband.conf etc/rdma/modules/iwarp.conf etc/rdma/modules/iwpmd.conf @@ -20,7 +19,6 @@ lib/udev/rules.d/90-iwpmd.rules lib/udev/rules.d/90-rdma-hw-modules.rules lib/udev/rules.d/90-rdma-ulp-modules.rules lib/udev/rules.d/90-rdma-umad.rules -usr/lib/truescale-serdes.cmds usr/sbin/iwpmd usr/sbin/rdma-ndd usr/sbin/rdma_topo diff --git a/debian/rdma-core.lintian-overrides b/debian/rdma-core.lintian-overrides index 27c315e84..5d798611f 100644 --- a/debian/rdma-core.lintian-overrides +++ b/debian/rdma-core.lintian-overrides @@ -1,7 +1,3 @@ -# "module -i ib_qib" will executes code. This cannot be replaced by the softdep command. -rdma-core: obsolete-command-in-modprobe.d-file install [etc/modprobe.d/truescale.conf] # The rdma-ndd service is started by udev. rdma-core: systemd-service-file-missing-install-key [lib/systemd/system/iwpmd.service] rdma-core: systemd-service-file-missing-install-key [lib/systemd/system/rdma-ndd.service] -# For lintian < 2.115.2 -rdma-core: obsolete-command-in-modprobe.d-file etc/modprobe.d/truescale.conf install diff --git a/kernel-boot/rdma-description.rules b/kernel-boot/rdma-description.rules index 48a7cede9..b346b3b06 100644 --- a/kernel-boot/rdma-description.rules +++ b/kernel-boot/rdma-description.rules @@ -20,6 +20,7 @@ DRIVERS=="ib_qib", ENV{ID_RDMA_INFINIBAND}="1" # Hardware that supports OPA DRIVERS=="hfi1", ENV{ID_RDMA_OPA}="1" +DRIVERS=="hfi2", ENV{ID_RDMA_OPA}="1" # Hardware that supports iWarp DRIVERS=="cxgb4", ENV{ID_RDMA_IWARP}="1" diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt index cd9c08cad..6ad7cba2b 100644 --- a/kernel-headers/CMakeLists.txt +++ b/kernel-headers/CMakeLists.txt @@ -3,6 +3,7 @@ publish_internal_headers(rdma rdma/cxgb4-abi.h rdma/efa-abi.h rdma/erdma-abi.h + rdma/hfi2-abi.h rdma/hns-abi.h rdma/ib_user_ioctl_cmds.h rdma/ib_user_ioctl_verbs.h diff --git a/kernel-headers/rdma/hfi/hfi1_ioctl.h b/kernel-headers/rdma/hfi/hfi1_ioctl.h index 8f3d9fe7b..84d37bc53 100644 --- a/kernel-headers/rdma/hfi/hfi1_ioctl.h +++ b/kernel-headers/rdma/hfi/hfi1_ioctl.h @@ -7,6 +7,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2015 Intel Corporation. + * Copyright 2025 Cornelis Networks * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -53,122 +54,9 @@ #define _LINUX__HFI1_IOCTL_H #include -/* - * This structure is passed to the driver to tell it where - * user code buffers are, sizes, etc. The offsets and sizes of the - * fields must remain unchanged, for binary compatibility. It can - * be extended, if userversion is changed so user code can tell, if needed - */ -struct hfi1_user_info { - /* - * version of user software, to detect compatibility issues. - * Should be set to HFI1_USER_SWVERSION. - */ - __u32 userversion; - __u32 pad; - /* - * If two or more processes wish to share a context, each process - * must set the subcontext_cnt and subcontext_id to the same - * values. The only restriction on the subcontext_id is that - * it be unique for a given node. - */ - __u16 subctxt_cnt; - __u16 subctxt_id; - /* 128bit UUID passed in by PSM. */ - __u8 uuid[16]; -}; - -struct hfi1_ctxt_info { - __aligned_u64 runtime_flags; /* chip/drv runtime flags (HFI1_CAP_*) */ - __u32 rcvegr_size; /* size of each eager buffer */ - __u16 num_active; /* number of active units */ - __u16 unit; /* unit (chip) assigned to caller */ - __u16 ctxt; /* ctxt on unit assigned to caller */ - __u16 subctxt; /* subctxt on unit assigned to caller */ - __u16 rcvtids; /* number of Rcv TIDs for this context */ - __u16 credits; /* number of PIO credits for this context */ - __u16 numa_node; /* NUMA node of the assigned device */ - __u16 rec_cpu; /* cpu # for affinity (0xffff if none) */ - __u16 send_ctxt; /* send context in use by this user context */ - __u16 egrtids; /* number of RcvArray entries for Eager Rcvs */ - __u16 rcvhdrq_cnt; /* number of RcvHdrQ entries */ - __u16 rcvhdrq_entsize; /* size (in bytes) for each RcvHdrQ entry */ - __u16 sdma_ring_size; /* number of entries in SDMA request ring */ -}; +#define hfi1_user_info hfi2_user_info +#define hfi1_ctxt_info hfi2_ctxt_info -struct hfi1_tid_info { - /* virtual address of first page in transfer */ - __aligned_u64 vaddr; - /* pointer to tid array. this array is big enough */ - __aligned_u64 tidlist; - /* number of tids programmed by this request */ - __u32 tidcnt; - /* length of transfer buffer programmed by this request */ - __u32 length; -}; +#define hfi1_base_info hfi2_base_info -/* - * This structure is returned by the driver immediately after - * open to get implementation-specific info, and info specific to this - * instance. - * - * This struct must have explicit pad fields where type sizes - * may result in different alignments between 32 and 64 bit - * programs, since the 64 bit * bit kernel requires the user code - * to have matching offsets - */ -struct hfi1_base_info { - /* version of hardware, for feature checking. */ - __u32 hw_version; - /* version of software, for feature checking. */ - __u32 sw_version; - /* Job key */ - __u16 jkey; - __u16 padding1; - /* - * The special QP (queue pair) value that identifies PSM - * protocol packet from standard IB packets. - */ - __u32 bthqp; - /* PIO credit return address, */ - __aligned_u64 sc_credits_addr; - /* - * Base address of write-only pio buffers for this process. - * Each buffer has sendpio_credits*64 bytes. - */ - __aligned_u64 pio_bufbase_sop; - /* - * Base address of write-only pio buffers for this process. - * Each buffer has sendpio_credits*64 bytes. - */ - __aligned_u64 pio_bufbase; - /* address where receive buffer queue is mapped into */ - __aligned_u64 rcvhdr_bufbase; - /* base address of Eager receive buffers. */ - __aligned_u64 rcvegr_bufbase; - /* base address of SDMA completion ring */ - __aligned_u64 sdma_comp_bufbase; - /* - * User register base for init code, not to be used directly by - * protocol or applications. Always maps real chip register space. - * the register addresses are: - * ur_rcvhdrhead, ur_rcvhdrtail, ur_rcvegrhead, ur_rcvegrtail, - * ur_rcvtidflow - */ - __aligned_u64 user_regbase; - /* notification events */ - __aligned_u64 events_bufbase; - /* status page */ - __aligned_u64 status_bufbase; - /* rcvhdrtail update */ - __aligned_u64 rcvhdrtail_base; - /* - * shared memory pages for subctxts if ctxt is shared; these cover - * all the processes in the group sharing a single context. - * all have enough space for the num_subcontexts value on this job. - */ - __aligned_u64 subctxt_uregbase; - __aligned_u64 subctxt_rcvegrbuf; - __aligned_u64 subctxt_rcvhdrbuf; -}; #endif /* _LINIUX__HFI1_IOCTL_H */ diff --git a/kernel-headers/rdma/hfi/hfi1_user.h b/kernel-headers/rdma/hfi/hfi1_user.h index 1106a7c90..829b6ad46 100644 --- a/kernel-headers/rdma/hfi/hfi1_user.h +++ b/kernel-headers/rdma/hfi/hfi1_user.h @@ -7,6 +7,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2015 - 2020 Intel Corporation. + * Copyright 2025 Cornelis Networks. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -49,220 +50,81 @@ * */ -/* - * This file contains defines, structures, etc. that are used - * to communicate between kernel and user code. - */ - #ifndef _LINUX__HFI1_USER_H #define _LINUX__HFI1_USER_H #include #include - -/* - * This version number is given to the driver by the user code during - * initialization in the spu_userversion field of hfi1_user_info, so - * the driver can check for compatibility with user code. - * - * The major version changes when data structures change in an incompatible - * way. The driver must be the same for initialization to succeed. - */ -#define HFI1_USER_SWMAJOR 6 - -/* - * Minor version differences are always compatible - * a within a major version, however if user software is larger - * than driver software, some new features and/or structure fields - * may not be implemented; the user code must deal with this if it - * cares, or it must abort after initialization reports the difference. - */ -#define HFI1_USER_SWMINOR 3 - -/* - * We will encode the major/minor inside a single 32bit version number. - */ -#define HFI1_SWMAJOR_SHIFT 16 - -/* - * Set of HW and driver capability/feature bits. - * These bit values are used to configure enabled/disabled HW and - * driver features. The same set of bits are communicated to user - * space. - */ -#define HFI1_CAP_DMA_RTAIL (1UL << 0) /* Use DMA'ed RTail value */ -#define HFI1_CAP_SDMA (1UL << 1) /* Enable SDMA support */ -#define HFI1_CAP_SDMA_AHG (1UL << 2) /* Enable SDMA AHG support */ -#define HFI1_CAP_EXTENDED_PSN (1UL << 3) /* Enable Extended PSN support */ -#define HFI1_CAP_HDRSUPP (1UL << 4) /* Enable Header Suppression */ -#define HFI1_CAP_TID_RDMA (1UL << 5) /* Enable TID RDMA operations */ -#define HFI1_CAP_USE_SDMA_HEAD (1UL << 6) /* DMA Hdr Q tail vs. use CSR */ -#define HFI1_CAP_MULTI_PKT_EGR (1UL << 7) /* Enable multi-packet Egr buffs*/ -#define HFI1_CAP_NODROP_RHQ_FULL (1UL << 8) /* Don't drop on Hdr Q full */ -#define HFI1_CAP_NODROP_EGR_FULL (1UL << 9) /* Don't drop on EGR buffs full */ -#define HFI1_CAP_TID_UNMAP (1UL << 10) /* Disable Expected TID caching */ -#define HFI1_CAP_PRINT_UNIMPL (1UL << 11) /* Show for unimplemented feats */ -#define HFI1_CAP_ALLOW_PERM_JKEY (1UL << 12) /* Allow use of permissive JKEY */ -#define HFI1_CAP_NO_INTEGRITY (1UL << 13) /* Enable ctxt integrity checks */ -#define HFI1_CAP_PKEY_CHECK (1UL << 14) /* Enable ctxt PKey checking */ -#define HFI1_CAP_STATIC_RATE_CTRL (1UL << 15) /* Allow PBC.StaticRateControl */ -#define HFI1_CAP_OPFN (1UL << 16) /* Enable the OPFN protocol */ -#define HFI1_CAP_SDMA_HEAD_CHECK (1UL << 17) /* SDMA head checking */ -#define HFI1_CAP_EARLY_CREDIT_RETURN (1UL << 18) /* early credit return */ -#define HFI1_CAP_AIP (1UL << 19) /* Enable accelerated IP */ - -#define HFI1_RCVHDR_ENTSIZE_2 (1UL << 0) -#define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1) -#define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2) - -#define _HFI1_EVENT_FROZEN_BIT 0 -#define _HFI1_EVENT_LINKDOWN_BIT 1 -#define _HFI1_EVENT_LID_CHANGE_BIT 2 -#define _HFI1_EVENT_LMC_CHANGE_BIT 3 -#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 -#define _HFI1_EVENT_TID_MMU_NOTIFY_BIT 5 -#define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_TID_MMU_NOTIFY_BIT - -#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) -#define HFI1_EVENT_LINKDOWN (1UL << _HFI1_EVENT_LINKDOWN_BIT) -#define HFI1_EVENT_LID_CHANGE (1UL << _HFI1_EVENT_LID_CHANGE_BIT) -#define HFI1_EVENT_LMC_CHANGE (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) -#define HFI1_EVENT_SL2VL_CHANGE (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) -#define HFI1_EVENT_TID_MMU_NOTIFY (1UL << _HFI1_EVENT_TID_MMU_NOTIFY_BIT) - -/* - * These are the status bits readable (in ASCII form, 64bit value) - * from the "status" sysfs file. For binary compatibility, values - * must remain as is; removed states can be reused for different - * purposes. - */ -#define HFI1_STATUS_INITTED 0x1 /* basic initialization done */ -/* Chip has been found and initialized */ -#define HFI1_STATUS_CHIP_PRESENT 0x20 -/* IB link is at ACTIVE, usable for data traffic */ -#define HFI1_STATUS_IB_READY 0x40 -/* link is configured, LID, MTU, etc. have been set */ -#define HFI1_STATUS_IB_CONF 0x80 -/* A Fatal hardware error has occurred. */ -#define HFI1_STATUS_HWERROR 0x200 - -/* - * Number of supported shared contexts. - * This is the maximum number of software contexts that can share - * a hardware send/receive context. - */ -#define HFI1_MAX_SHARED_CTXTS 8 - -/* - * Poll types - */ -#define HFI1_POLL_TYPE_ANYRCV 0x0 -#define HFI1_POLL_TYPE_URGENT 0x1 - -enum hfi1_sdma_comp_state { - FREE = 0, - QUEUED, - COMPLETE, - ERROR -}; - -/* - * SDMA completion ring entry - */ -struct hfi1_sdma_comp_entry { - __u32 status; - __u32 errcode; -}; - -/* - * Device status and notifications from driver to user-space. - */ -struct hfi1_status { - __aligned_u64 dev; /* device/hw status bits */ - __aligned_u64 port; /* port state and status bits */ - char freezemsg[]; -}; - -enum sdma_req_opcode { - EXPECTED = 0, - EAGER -}; - -#define HFI1_SDMA_REQ_VERSION_MASK 0xF -#define HFI1_SDMA_REQ_VERSION_SHIFT 0x0 -#define HFI1_SDMA_REQ_OPCODE_MASK 0xF -#define HFI1_SDMA_REQ_OPCODE_SHIFT 0x4 -#define HFI1_SDMA_REQ_IOVCNT_MASK 0xFF -#define HFI1_SDMA_REQ_IOVCNT_SHIFT 0x8 - -struct sdma_req_info { - /* - * bits 0-3 - version (currently unused) - * bits 4-7 - opcode (enum sdma_req_opcode) - * bits 8-15 - io vector count - */ - __u16 ctrl; - /* - * Number of fragments contained in this request. - * User-space has already computed how many - * fragment-sized packet the user buffer will be - * split into. - */ - __u16 npkts; - /* - * Size of each fragment the user buffer will be - * split into. - */ - __u16 fragsize; - /* - * Index of the slot in the SDMA completion ring - * this request should be using. User-space is - * in charge of managing its own ring. - */ - __u16 comp_idx; -} __attribute__((__packed__)); - -/* - * SW KDETH header. - * swdata is SW defined portion. - */ -struct hfi1_kdeth_header { - __le32 ver_tid_offset; - __le16 jkey; - __le16 hcrc; - __le32 swdata[7]; -} __attribute__((__packed__)); - -/* - * Structure describing the headers that User space uses. The - * structure above is a subset of this one. - */ -struct hfi1_pkt_header { - __le16 pbc[4]; - __be16 lrh[4]; - __be32 bth[3]; - struct hfi1_kdeth_header kdeth; -} __attribute__((__packed__)); - - -/* - * The list of usermode accessible registers. - */ -enum hfi1_ureg { - /* (RO) DMA RcvHdr to be used next. */ - ur_rcvhdrtail = 0, - /* (RW) RcvHdr entry to be processed next by host. */ - ur_rcvhdrhead = 1, - /* (RO) Index of next Eager index to use. */ - ur_rcvegrindextail = 2, - /* (RW) Eager TID to be processed next */ - ur_rcvegrindexhead = 3, - /* (RO) Receive Eager Offset Tail */ - ur_rcvegroffsettail = 4, - /* For internal use only; max register number. */ - ur_maxreg, - /* (RW) Receive TID flow table */ - ur_rcvtidflowtable = 256 -}; +#include + +#define HFI1_USER_SWMAJOR HFI2_USER_SWMAJOR +#define HFI1_USER_SWMINOR HFI2_USER_SWMINOR +#define HFI1_SWMAJOR_SHIFT HFI2_SWMAJOR_SHIFT + +#define HFI1_CAP_DMA_RTAIL HFI2_CAP_DMA_RTAIL +#define HFI1_CAP_SDMA HFI2_CAP_SDMA +#define HFI1_CAP_SDMA_AHG HFI2_CAP_SDMA_AHG +#define HFI1_CAP_EXTENDED_PSN HFI2_CAP_EXTENDED_PSN +#define HFI1_CAP_HDRSUPP HFI2_CAP_HDRSUPP +#define HFI1_CAP_TID_RDMA HFI2_CAP_TID_RDMA +#define HFI1_CAP_USE_SDMA_HEAD HFI2_CAP_USE_SDMA_HEAD +#define HFI1_CAP_MULTI_PKT_EGR HFI2_CAP_MULTI_PKT_EGR +#define HFI1_CAP_NODROP_RHQ_FULL HFI2_CAP_NODROP_RHQ_FULL +#define HFI1_CAP_NODROP_EGR_FULL HFI2_CAP_NODROP_EGR_FULL +#define HFI1_CAP_TID_UNMAP HFI2_CAP_TID_UNMAP +#define HFI1_CAP_PRINT_UNIMPL HFI2_CAP_PRINT_UNIMPL +#define HFI1_CAP_ALLOW_PERM_JKEY HFI2_CAP_ALLOW_PERM_JKEY +#define HFI1_CAP_NO_INTEGRITY HFI2_CAP_NO_INTEGRITY +#define HFI1_CAP_PKEY_CHECK HFI2_CAP_PKEY_CHECK +#define HFI1_CAP_STATIC_RATE_CTRL HFI2_CAP_STATIC_RATE_CTRL +#define HFI1_CAP_OPFN HFI2_CAP_OPFN +#define HFI1_CAP_SDMA_HEAD_CHECK HFI2_CAP_SDMA_HEAD_CHECK +#define HFI1_CAP_EARLY_CREDIT_RETURN HFI2_CAP_EARLY_CREDIT_RETURN +#define HFI1_CAP_AIP HFI2_CAP_AIP + +#define HFI1_RCVHDR_ENTSIZE_2 HFI2_RCVHDR_ENTSIZE_2 +#define HFI1_RCVHDR_ENTSIZE_16 HFI2_RCVHDR_ENTSIZE_16 +#define HFI1_RCVDHR_ENTSIZE_32 HFI2_RCVHDR_ENTSIZE_32 + +#define _HFI1_EVENT_FROZEN_BIT _HFI2_EVENT_FROZEN_BIT +#define _HFI1_EVENT_LINKDOWN_BIT _HFI2_EVENT_LINKDOWN_BIT +#define _HFI1_EVENT_LID_CHANGE_BIT _HFI2_EVENT_LID_CHANGE_BIT +#define _HFI1_EVENT_LMC_CHANGE_BIT _HFI2_EVENT_LMC_CHANGE_BIT +#define _HFI1_EVENT_SL2VL_CHANGE_BIT _HFI2_EVENT_SL2VL_CHANGE_BIT +#define _HFI1_EVENT_TID_MMU_NOTIFY_BIT _HFI2_EVENT_TID_MMU_NOTIFY_BIT +#define _HFI1_MAX_EVENT_BIT _HFI2_EVENT_TID_MMU_NOTIFY_BIT + +#define HFI1_EVENT_FROZEN HFI2_EVENT_FROZEN +#define HFI1_EVENT_LINKDOWN HFI2_EVENT_LINKDOWN +#define HFI1_EVENT_LID_CHANGE HFI2_EVENT_LID_CHANGE +#define HFI1_EVENT_LMC_CHANGE HFI2_EVENT_LMC_CHANGE +#define HFI1_EVENT_SL2VL_CHANGE HFI2_EVENT_SL2VL_CHANGE +#define HFI1_EVENT_TID_MMU_NOTIFY HFI2_EVENT_TID_MMU_NOTIFY + +#define HFI1_STATUS_INITTED HFI2_STATUS_INITTED +#define HFI1_STATUS_CHIP_PRESENT HFI2_STATUS_CHIP_PRESENT +#define HFI1_STATUS_IB_READY HFI2_STATUS_IB_READY +#define HFI1_STATUS_IB_CONF HFI2_STATUS_IB_CONF +#define HFI1_STATUS_HWERROR HFI2_STATUS_HWERROR + +#define HFI1_MAX_SHARED_CTXTS HFI2_MAX_SHARED_CTXTS + +#define HFI1_POLL_TYPE_ANYRCV HFI2_POLL_TYPE_ANYRCV +#define HFI1_POLL_TYPE_URGENT HFI2_POLL_TYPE_URGENT + +#define hfi1_sdma_comp_state hfi2_sdma_comp_state +#define hfi1_sdma_comp_entry hfi2_sdma_comp_entry + + +#define HFI1_SDMA_REQ_VERSION_MASK HFI2_SDMA_REQ_VERSION_MASK +#define HFI1_SDMA_REQ_VERSION_SHIFT HFI2_SDMA_REQ_VERSION_SHIFT +#define HFI1_SDMA_REQ_OPCODE_MASK HFI2_SDMA_REQ_OPCODE_MASK +#define HFI1_SDMA_REQ_OPCODE_SHIFT HFI2_SDMA_REQ_OPCODE_SHIFT +#define HFI1_SDMA_REQ_IOVCNT_MASK HFI2_SDMA_REQ_IOVCNT_MASK +#define HFI1_SDMA_REQ_IOVCNT_SHIFT HFI2_SDMA_REQ_IOVCNT_SHIFT + +#define hfi1_kdeth_header hfi2_kdeth_header +#define hfi1_pkt_header hfi2_pkt_header +#define hfi1_ureg hfi2_ureg #endif /* _LINIUX__HFI1_USER_H */ diff --git a/kernel-headers/rdma/hfi2-abi.h b/kernel-headers/rdma/hfi2-abi.h new file mode 100644 index 000000000..dc0353f24 --- /dev/null +++ b/kernel-headers/rdma/hfi2-abi.h @@ -0,0 +1,727 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* + * Copyright 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + */ + +#ifndef _LINUX_HFI2_USER_H +#define _LINUX_HFI2_USER_H + +#include +#include +#include + +/* + * This version number is given to the driver by the user code during + * initialization in the spu_userversion field of hfi2_user_info, so + * the driver can check for compatibility with user code. + * + * The major version changes when data structures change in an incompatible + * way. The driver must be the same for initialization to succeed. + */ +#define HFI2_USER_SWMAJOR 6 +#define HFI2_RDMA_USER_SWMAJOR 10 + +/* + * Minor version differences are always compatible + * a within a major version, however if user software is larger + * than driver software, some new features and/or structure fields + * may not be implemented; the user code must deal with this if it + * cares, or it must abort after initialization reports the difference. + */ +#define HFI2_USER_SWMINOR 3 +#define HFI2_RDMA_USER_SWMINOR 0 + +/* + * We will encode the major/minor inside a single 32bit version number. + */ +#define HFI2_SWMAJOR_SHIFT 16 + +/* + * Set of HW and driver capability/feature bits. + * These bit values are used to configure enabled/disabled HW and + * driver features. The same set of bits are communicated to user + * space. + */ +#define HFI2_CAP_DMA_RTAIL (1UL << 0) /* Use DMA'ed RTail value */ +#define HFI2_CAP_SDMA (1UL << 1) /* Enable SDMA support */ +#define HFI2_CAP_SDMA_AHG (1UL << 2) /* Enable SDMA AHG support */ +#define HFI2_CAP_EXTENDED_PSN (1UL << 3) /* Enable Extended PSN support */ +#define HFI2_CAP_HDRSUPP (1UL << 4) /* Enable Header Suppression */ +#define HFI2_CAP_TID_RDMA (1UL << 5) /* Enable TID RDMA operations */ +#define HFI2_CAP_USE_SDMA_HEAD (1UL << 6) /* DMA Hdr Q tail vs. use CSR */ +#define HFI2_CAP_MULTI_PKT_EGR (1UL << 7) /* Enable multi-packet Egr buffs*/ +#define HFI2_CAP_NODROP_RHQ_FULL (1UL << 8) /* Don't drop on Hdr Q full */ +#define HFI2_CAP_NODROP_EGR_FULL (1UL << 9) /* Don't drop on EGR buffs full */ +#define HFI2_CAP_TID_UNMAP (1UL << 10) /* Disable Expected TID caching */ +#define HFI2_CAP_PRINT_UNIMPL (1UL << 11) /* Show for unimplemented feats */ +#define HFI2_CAP_ALLOW_PERM_JKEY (1UL << 12) /* Allow use of permissive JKEY */ +#define HFI2_CAP_NO_INTEGRITY (1UL << 13) /* Enable ctxt integrity checks */ +#define HFI2_CAP_PKEY_CHECK (1UL << 14) /* Enable ctxt PKey checking */ +#define HFI2_CAP_STATIC_RATE_CTRL (1UL << 15) /* Allow PBC.StaticRateControl */ +#define HFI2_CAP_OPFN (1UL << 16) /* Enable the OPFN protocol */ +#define HFI2_CAP_SDMA_HEAD_CHECK (1UL << 17) /* SDMA head checking */ +#define HFI2_CAP_EARLY_CREDIT_RETURN (1UL << 18) /* early credit return */ +#define HFI2_CAP_AIP (1UL << 19) /* Enable accelerated IP */ + +#define HFI2_RCVHDR_ENTSIZE_2 (1UL << 0) +#define HFI2_RCVHDR_ENTSIZE_16 (1UL << 1) +#define HFI2_RCVDHR_ENTSIZE_32 (1UL << 2) + +#define _HFI2_EVENT_FROZEN_BIT 0 +#define _HFI2_EVENT_LINKDOWN_BIT 1 +#define _HFI2_EVENT_LID_CHANGE_BIT 2 +#define _HFI2_EVENT_LMC_CHANGE_BIT 3 +#define _HFI2_EVENT_SL2VL_CHANGE_BIT 4 +#define _HFI2_EVENT_TID_MMU_NOTIFY_BIT 5 +#define _HFI2_MAX_EVENT_BIT _HFI2_EVENT_TID_MMU_NOTIFY_BIT + +#define HFI2_EVENT_FROZEN (1UL << _HFI2_EVENT_FROZEN_BIT) +#define HFI2_EVENT_LINKDOWN (1UL << _HFI2_EVENT_LINKDOWN_BIT) +#define HFI2_EVENT_LID_CHANGE (1UL << _HFI2_EVENT_LID_CHANGE_BIT) +#define HFI2_EVENT_LMC_CHANGE (1UL << _HFI2_EVENT_LMC_CHANGE_BIT) +#define HFI2_EVENT_SL2VL_CHANGE (1UL << _HFI2_EVENT_SL2VL_CHANGE_BIT) +#define HFI2_EVENT_TID_MMU_NOTIFY (1UL << _HFI2_EVENT_TID_MMU_NOTIFY_BIT) + +/* + * These are the status bits readable (in ASCII form, 64bit value) + * from the "status" sysfs file. For binary compatibility, values + * must remain as is; removed states can be reused for different + * purposes. + */ +#define HFI2_STATUS_INITTED 0x1 /* basic initialization done */ +/* Chip has been found and initialized */ +#define HFI2_STATUS_CHIP_PRESENT 0x20 +/* IB link is at ACTIVE, usable for data traffic */ +#define HFI2_STATUS_IB_READY 0x40 +/* link is configured, LID, MTU, etc. have been set */ +#define HFI2_STATUS_IB_CONF 0x80 +/* A Fatal hardware error has occurred. */ +#define HFI2_STATUS_HWERROR 0x200 + +/* + * Number of supported shared contexts. + * This is the maximum number of software contexts that can share + * a hardware send/receive context. + */ +#define HFI2_MAX_SHARED_CTXTS 8 + +/* + * Poll types + */ +#define HFI2_POLL_TYPE_ANYRCV 0x0 +#define HFI2_POLL_TYPE_URGENT 0x1 + +enum hfi2_sdma_comp_state { + FREE = 0, + QUEUED, + COMPLETE, + ERROR +}; + +/* + * SDMA completion ring entry + */ +struct hfi2_sdma_comp_entry { + __u32 status; + __u32 errcode; +}; + +/* + * Device status and notifications from driver to user-space. + * hfi1 and hfi2 status are different. + */ +struct hfi1_status { + __aligned_u64 dev; /* device/hw status bits */ + __aligned_u64 port; /* port state and status bits */ + char freezemsg[]; +}; + +struct hfi2_status { + __aligned_u64 dev; /* device/hw status bits */ + __aligned_u64 ports[]; /* port state and status bits */ +}; + +enum sdma_req_opcode { + EXPECTED = 0, + EAGER +}; + +#define HFI2_SDMA_REQ_VERSION_MASK 0xF +#define HFI2_SDMA_REQ_VERSION_SHIFT 0x0 +#define HFI2_SDMA_REQ_OPCODE_MASK 0xF +#define HFI2_SDMA_REQ_OPCODE_SHIFT 0x4 +#define HFI2_SDMA_REQ_IOVCNT_MASK 0x7F +#define HFI2_SDMA_REQ_IOVCNT_SHIFT 0x8 +#define HFI2_SDMA_REQ_MEMINFO_MASK 0x1 +#define HFI2_SDMA_REQ_MEMINFO_SHIFT 0xF + +struct sdma_req_info { + /* + * bits 0-3 - version (currently unused) + * bits 4-7 - opcode (enum sdma_req_opcode) + * bits 8-14 - io vector count + * bit 15 - meminfo present + */ + __u16 ctrl; + /* + * Number of fragments contained in this request. + * User-space has already computed how many + * fragment-sized packet the user buffer will be + * split into. + */ + __u16 npkts; + /* + * Size of each fragment the user buffer will be + * split into. + */ + __u16 fragsize; + /* + * Index of the slot in the SDMA completion ring + * this request should be using. User-space is + * in charge of managing its own ring. + */ + __u16 comp_idx; +} __packed; + +#define HFI2_MEMINFO_TYPE_ENTRY_BITS 4 +#define HFI2_MEMINFO_TYPE_ENTRY_MASK ((1 << HFI2_MEMINFO_TYPE_ENTRY_BITS) - 1) +#define HFI2_MEMINFO_TYPE_ENTRY_GET(m, n) \ + (((m) >> ((n) * HFI2_MEMINFO_TYPE_ENTRY_BITS)) & \ + HFI2_MEMINFO_TYPE_ENTRY_MASK) +#define HFI2_MEMINFO_TYPE_ENTRY_SET(m, n, e) \ + ((m) |= ((e) & HFI2_MEMINFO_TYPE_ENTRY_MASK) \ + << ((n) * HFI2_MEMINFO_TYPE_ENTRY_BITS)) +#define HFI2_MAX_MEMINFO_ENTRIES \ + (sizeof(__u64) * 8 / HFI2_MEMINFO_TYPE_ENTRY_BITS) + +#define HFI2_MEMINFO_TYPE_SYSTEM 0 + +struct sdma_req_meminfo { + /* + * Packed memory type indicators for each data iovec entry. + */ + __u64 types; + /* + * Type-specific context for each data iovec entry. + */ + __u64 context[HFI2_MAX_MEMINFO_ENTRIES]; +}; + +/* + * SW KDETH header. + * swdata is SW defined portion. + */ +struct hfi2_kdeth_header { + __le32 ver_tid_offset; + __le16 jkey; + __le16 hcrc; + __le32 swdata[7]; +} __packed; + +/* + * Structure describing the headers that User space uses. The + * structure above is a subset of this one. + */ +struct hfi2_pkt_header { + __le16 pbc[4]; + __be16 lrh[4]; + __be32 bth[3]; + struct hfi2_kdeth_header kdeth; +} __packed; + + +/* + * The list of usermode accessible registers. + */ +enum hfi2_ureg { + /* (RO) DMA RcvHdr to be used next. */ + ur_rcvhdrtail = 0, + /* (RW) RcvHdr entry to be processed next by host. */ + ur_rcvhdrhead = 1, + /* (RO) Index of next Eager index to use. */ + ur_rcvegrindextail = 2, + /* (RW) Eager TID to be processed next */ + ur_rcvegrindexhead = 3, + /* (RO) Receive Eager Offset Tail */ + ur_rcvegroffsettail = 4, + /* For internal use only; max register number. */ + ur_maxreg, + /* (RW) Receive TID flow table */ + ur_rcvtidflowtable = 256 +}; + +/* + * This structure is passed to the driver to tell it where + * user code buffers are, sizes, etc. The offsets and sizes of the + * fields must remain unchanged, for binary compatibility. It can + * be extended, if userversion is changed so user code can tell, if needed + */ +struct hfi2_user_info { + /* + * version of user software, to detect compatibility issues. + * Should be set to HFI2_USER_SWVERSION. + */ + __u32 userversion; + __u32 pad; /* Port Address */ + /* + * If two or more processes wish to share a context, each process + * must set the subcontext_cnt and subcontext_id to the same + * values. The only restriction on the subcontext_id is that + * it be unique for a given node. + */ + __u16 subctxt_cnt; + __u16 subctxt_id; + /* 128bit UUID passed in by PSM. */ + __u8 uuid[16]; +}; + +struct hfi2_ctxt_info { + __aligned_u64 runtime_flags; /* chip/drv runtime flags (HFI2_CAP_*) */ + __u32 rcvegr_size; /* size of each eager buffer */ + __u16 num_active; /* number of active units */ + __u16 unit; /* unit (chip) assigned to caller */ + __u16 ctxt; /* ctxt on unit assigned to caller */ + __u16 subctxt; /* subctxt on unit assigned to caller */ + __u16 rcvtids; /* number of Rcv TIDs for this context */ + __u16 credits; /* number of PIO credits for this context */ + __u16 numa_node; /* NUMA node of the assigned device */ + __u16 rec_cpu; /* cpu # for affinity (0xffff if none) */ + __u16 send_ctxt; /* send context in use by this user context */ + __u16 egrtids; /* number of RcvArray entries for Eager Rcvs */ + __u16 rcvhdrq_cnt; /* number of RcvHdrQ entries */ + __u16 rcvhdrq_entsize; /* size (in bytes) for each RcvHdrQ entry */ + __u16 sdma_ring_size; /* number of entries in SDMA request ring */ +}; + +struct hfi1_tid_info { + /* virtual address of first page in transfer */ + __aligned_u64 vaddr; + /* pointer to tid array. this array is big enough */ + __aligned_u64 tidlist; + /* number of tids programmed by this request */ + __u32 tidcnt; + /* length of transfer buffer programmed by this request */ + __u32 length; +}; + +#define HFI2_TID_UPDATE_FLAGS_MEMINFO_BITS 4 +#define HFI2_TID_UPDATE_FLAGS_MEMINFO_MASK ((1UL << HFI2_TID_UPDATE_FLAGS_MEMINFO_BITS) - 1) +#define HFI2_TID_UPDATE_FLAGS_RESERVED_MASK (~(__u64)(HFI2_TID_UPDATE_FLAGS_MEMINFO_MASK)) + +struct hfi2_tid_info { + /* virtual address of first page in transfer */ + __aligned_u64 vaddr; + /* pointer to tid array. this array is big enough */ + __aligned_u64 tidlist; + /* number of tids programmed by this request */ + __u32 tidcnt; + /* length of transfer buffer programmed by this request */ + __u32 length; + + /* + * bits 0-3 memory_type + * memory_type=0 will always mean system memory + * See HFI2_MEMINFO_TYPE* defines + * bits 4-63 reserved; must be 0 + */ + __aligned_u64 flags; + /* Reserved; must be 0 */ + __aligned_u64 context; +}; + +/* + * This structure is returned by the driver immediately after + * open to get implementation-specific info, and info specific to this + * instance. + * + * This struct must have explicit padding fields where type sizes + * may result in different alignments between 32 and 64 bit + * programs, since the 64 bit * bit kernel requires the user code + * to have matching offsets + */ +struct hfi2_base_info { + /* version of hardware, for feature checking. */ + __u32 hw_version; + /* version of software, for feature checking. */ + __u32 sw_version; + /* Job key */ + __u16 jkey; + __u16 padding1; + /* + * The special QP (queue pair) value that identifies PSM + * protocol packet from standard IB packets. + */ + __u32 bthqp; + /* PIO credit return address, */ + __aligned_u64 sc_credits_addr; + /* + * Base address of write-only pio buffers for this process. + * Each buffer has sendpio_credits*64 bytes. + */ + __aligned_u64 pio_bufbase_sop; + /* + * Base address of write-only pio buffers for this process. + * Each buffer has sendpio_credits*64 bytes. + */ + __aligned_u64 pio_bufbase; + /* address where receive buffer queue is mapped into */ + __aligned_u64 rcvhdr_bufbase; + /* base address of Eager receive buffers. */ + __aligned_u64 rcvegr_bufbase; + /* base address of SDMA completion ring */ + __aligned_u64 sdma_comp_bufbase; + /* + * User register base for init code, not to be used directly by + * protocol or applications. Always maps real chip register space. + * the register addresses are: + * ur_rcvhdrhead, ur_rcvhdrtail, ur_rcvegrhead, ur_rcvegrtail, + * ur_rcvtidflow + */ + __aligned_u64 user_regbase; + /* notification events */ + __aligned_u64 events_bufbase; + /* status page */ + __aligned_u64 status_bufbase; + /* rcvhdrtail update */ + __aligned_u64 rcvhdrtail_base; + /* + * shared memory pages for subctxts if ctxt is shared; these cover + * all the processes in the group sharing a single context. + * all have enough space for the num_subcontexts value on this job. + */ + __aligned_u64 subctxt_uregbase; + __aligned_u64 subctxt_rcvegrbuf; + __aligned_u64 subctxt_rcvhdrbuf; +}; + +struct hfi2_pin_stats { + int memtype; + /* + * If -1, driver returns total number of stats entries for the given + * memtype, otherwise returns stats for the given { memtype, index }. + */ + int index; + __u64 id; + __u64 cache_entries; + __u64 total_refcounts; + __u64 total_bytes; + __u64 hits; + __u64 misses; + __u64 hint_hits; + __u64 hint_misses; + __u64 internal_evictions; /* due to self-imposed size limit */ + __u64 external_evictions; /* system-driven evictions */ +}; + +/* + * RDMA character device ioctls + */ + +/* verbs objects */ +enum hfi2_objects { + HFI2_OBJECT_DV0 = (1U << UVERBS_ID_NS_SHIFT), + HFI2_OBJECT_DV1, +}; + +/* methods for custom objects dv0 and dv1 - max of 8 per object */ +enum hfi2_methods_dv0 { + HFI2_METHOD_ASSIGN_CTXT = (1U << UVERBS_ID_NS_SHIFT), + HFI2_METHOD_CTXT_INFO, + HFI2_METHOD_USER_INFO, + HFI2_METHOD_TID_UPDATE, + HFI2_METHOD_TID_FREE, + HFI2_METHOD_CREDIT_UPD, + HFI2_METHOD_RECV_CTRL, + HFI2_METHOD_POLL_TYPE, +}; + +enum hfi2_methods_dv1 { + HFI2_METHOD_ACK_EVENT = (1U << UVERBS_ID_NS_SHIFT), + HFI2_METHOD_SET_PKEY, + HFI2_METHOD_CTXT_RESET, + HFI2_METHOD_TID_INVAL_READ, + HFI2_METHOD_GET_VERS, + HFI2_METHOD_PIN_STATS, +}; + +/* + * assign_ctxt + */ +enum hfi2_attrs_assign_ctxt { + HFI2_ATTR_ASSIGN_CTXT_CMD = (1U << UVERBS_ID_NS_SHIFT), +}; + +struct hfi2_assign_ctxt_cmd { + __u32 userversion; /* user library version */ + __u8 port; /* target port number */ + __u8 kdeth_rcvhdrsz; /* 0 means default */ + __u16 reserved1; + __u16 subctxt_cnt; + __u16 subctxt_id; + __u8 uuid[16]; /* 128bit UUID */ + __u32 reserved2; +}; + +/* + * ctxt_info + */ +enum hfi2_attrs_ctxt_info { + HFI2_ATTR_CTXT_INFO_RSP = (1U << UVERBS_ID_NS_SHIFT), +}; + +struct hfi2_ctxt_info_rsp { + __aligned_u64 runtime_flags; /* chip/drv runtime flags (HFI2_CAP_*) */ + + __u32 rcvegr_size; /* size of each eager buffer */ + __u16 num_active; /* number of active units */ + __u16 unit; /* unit (chip) assigned to caller */ + + __u16 ctxt; /* ctxt on unit assigned to caller */ + __u16 subctxt; /* subctxt on unit assigned to caller */ + __u16 rcvtids; /* number of Rcv TIDs for this context */ + __u16 credits; /* number of PIO credits for this context */ + + __u16 numa_node; /* NUMA node of the assigned device */ + __u16 rec_cpu; /* cpu # for affinity (0xffff if none) */ + __u16 send_ctxt; /* send context in use by this user context */ + __u16 egrtids; /* number of RcvArray entries for Eager Rcvs */ + + __u16 rcvhdrq_cnt; /* number of RcvHdrQ entries */ + __u16 rcvhdrq_entsize; /* size (in bytes) for each RcvHdrQ entry */ + __u16 sdma_ring_size; /* number of entries in SDMA request ring */ + __u16 reserved; +}; + +/* + * user_info + */ +enum hfi2_attrs_user_info { + HFI2_ATTR_USER_INFO_RSP = (1U << UVERBS_ID_NS_SHIFT), +}; + +/* + * Returns both general and specific information to this device open. + */ +struct hfi2_user_info_rsp { + /* version of hardware, for feature checking. */ + __u32 hw_version; + /* version of software, for feature checking. */ + __u32 sw_version; + /* Job key */ + __u16 jkey; + __u16 reserved; + /* + * The special QP (queue pair) value that identifies PSM/OPX + * protocol packet from standard IB packets. + */ + __u32 bthqp; + /* PIO credit return address */ + __aligned_u64 sc_credits_addr; + /* + * Base address of write-only pio buffers for this process. + * Each buffer has sendpio_credits*64 bytes. + */ + __aligned_u64 pio_bufbase_sop; + /* + * Base address of write-only pio buffers for this process. + * Each buffer has sendpio_credits*64 bytes. + */ + __aligned_u64 pio_bufbase; + /* address where receive buffer queue is mapped into */ + __aligned_u64 rcvhdr_bufbase; + /* base address of Eager receive buffers. */ + __aligned_u64 rcvegr_bufbase; + /* base address of SDMA completion ring */ + __aligned_u64 sdma_comp_bufbase; + /* + * User register base for init code, not to be used directly by + * protocol or applications. Always maps real chip register space. + * the register addresses are: + * ur_rcvhdrhead, ur_rcvhdrtail, ur_rcvegrhead, ur_rcvegrtail, + * ur_rcvtidflow + */ + __aligned_u64 user_regbase; + /* notification events */ + __aligned_u64 events_bufbase; + /* status page */ + __aligned_u64 status_bufbase; + /* rcvhdrtail update */ + __aligned_u64 rcvhdrtail_base; + /* + * Shared memory pages for subctxts if ctxt is shared. These cover + * all the processes in the group sharing a single context. + * All have enough space for the num_subcontexts value on this job. + */ + __aligned_u64 subctxt_uregbase; + __aligned_u64 subctxt_rcvegrbuf; + __aligned_u64 subctxt_rcvhdrbuf; + /* receive header error queue */ + __aligned_u64 rheq_bufbase; +}; + +/* + * tid_update + */ +enum hfi2_attrs_tid_update { + HFI2_ATTR_TID_UPDATE_CMD = (1U << UVERBS_ID_NS_SHIFT), + HFI2_ATTR_TID_UPDATE_RSP, +}; + +struct hfi2_tid_update_cmd { + __aligned_u64 vaddr; /* virtual address of buffer */ + __aligned_u64 tidlist; /* address of output tid array */ + __u32 length; /* buffer length, in bytes */ + __u32 tidcnt; /* tidlist size, in TIDs */ + __aligned_u64 flags; /* flags: [3:0] mem type, [63:4] reserved */ + __aligned_u64 context; /* reserved */ +}; + +struct hfi2_tid_update_rsp { + __u32 length; /* mapped buffer length */ + __u32 tidcnt; /* number of assigned TIDs */ +}; + +/* + * tid_free + */ +enum hfi2_attrs_tid_free { + HFI2_ATTR_TID_FREE_CMD = (1U << UVERBS_ID_NS_SHIFT), + HFI2_ATTR_TID_FREE_RSP, +}; + +struct hfi2_tid_free_cmd { + __aligned_u64 tidlist; /* user buffer pointer */ + __u32 tidcnt; /* number of TID entries in buffer */ + __u32 reserved; +}; + +struct hfi2_tid_free_rsp { + __u32 tidcnt; /* number actually freed */ + __u32 reserved; +}; + +/* + * credit_upd + * (no arguments) + */ + +/* + * recv_ctrl + */ +enum hfi2_attrs_recv_ctrl { + HFI2_ATTR_RECV_CTRL_CMD = (1U << UVERBS_ID_NS_SHIFT), + /* no response */ +}; + +struct hfi2_recv_ctrl_cmd { + __u8 start_stop; + __u8 reserved[7]; +}; + +/* + * poll_type + */ +enum hfi2_attrs_poll_type { + HFI2_ATTR_POLL_TYPE_CMD = (1U << UVERBS_ID_NS_SHIFT), + /* no response */ +}; + +struct hfi2_poll_type_cmd { + __u32 poll_type; + __u32 reserved; +}; + +/* + * ack_event + */ +enum hfi2_attrs_ack_event { + HFI2_ATTR_ACK_EVENT_CMD = (1U << UVERBS_ID_NS_SHIFT), + /* no response */ +}; + +struct hfi2_ack_event_cmd { + __u64 event; +}; + +/* + * set_pkey + */ +enum hfi2_attrs_set_pkey { + HFI2_ATTR_SET_PKEY_CMD = (1U << UVERBS_ID_NS_SHIFT), + /* no response */ +}; + +struct hfi2_set_pkey_cmd { + __u16 pkey; + __u8 reserved[6]; +}; + +/* + * ctxt_reset + * (no arguments) + */ + +/* + * tid_inval_read + */ +enum hfi2_attrs_tid_inval_read { + HFI2_ATTR_TID_INVAL_READ_CMD = (1U << UVERBS_ID_NS_SHIFT), + HFI2_ATTR_TID_INVAL_READ_RSP, +}; + +struct hfi2_tid_inval_read_cmd { + __aligned_u64 tidlist; /* user buffer pointer */ + __u32 tidcnt; /* space for this many TIDs */ + __u32 reserved; +}; + +struct hfi2_tid_inval_read_rsp { + __u32 tidcnt; /* numnber of returned tids */ + __u32 reserved; +}; + +/* + * get_vers + */ +enum hfi2_attrs_get_vers { + /* no cmd */ + HFI2_ATTR_GET_VERS_RSP = (1U << UVERBS_ID_NS_SHIFT), +}; + +struct hfi2_get_vers_rsp { + __u32 version; + __u32 reserved; +}; + +/* + * pin_stats + */ +enum hfi2_attrs_pin_stats { + HFI2_ATTR_PIN_STATS_CMD = (1U << UVERBS_ID_NS_SHIFT), + HFI2_ATTR_PIN_STATS_RSP, +}; + +struct hfi2_pin_stats_cmd { + __u32 memtype; + /* + * If -1, driver returns total number of stats entries for the given + * memtype, otherwise returns stats for the given { memtype, index }. + */ + __s32 index; +}; + +struct hfi2_pin_stats_rsp { + __u64 id; + __u64 cache_entries; + __u64 total_refcounts; + __u64 total_bytes; + __u64 hits; + __u64 misses; + __u64 hint_hits; + __u64 hint_misses; + __u64 internal_evictions; /* due to self-imposed size limit */ + __u64 external_evictions; /* system-driven evictions */ +}; + +#endif /* _LINIUX_HFI2_USER_H */ diff --git a/kernel-headers/rdma/ib_user_ioctl_verbs.h b/kernel-headers/rdma/ib_user_ioctl_verbs.h index 89e6a3f13..c7573131c 100644 --- a/kernel-headers/rdma/ib_user_ioctl_verbs.h +++ b/kernel-headers/rdma/ib_user_ioctl_verbs.h @@ -256,6 +256,7 @@ enum rdma_driver_id { RDMA_DRIVER_ERDMA, RDMA_DRIVER_MANA, RDMA_DRIVER_IONIC, + RDMA_DRIVER_HFI2, }; enum ib_uverbs_gid_type { diff --git a/kernel-headers/rdma/irdma-abi.h b/kernel-headers/rdma/irdma-abi.h index f7788d333..36f20802b 100644 --- a/kernel-headers/rdma/irdma-abi.h +++ b/kernel-headers/rdma/irdma-abi.h @@ -57,8 +57,8 @@ struct irdma_alloc_ucontext_resp { __u8 rsvd2; __aligned_u64 comp_mask; __u16 min_hw_wq_size; + __u8 revd3[2]; __u32 max_hw_srq_quanta; - __u8 rsvd3[2]; }; struct irdma_alloc_pd_resp { diff --git a/kernel-headers/rdma/rdma_user_cm.h b/kernel-headers/rdma/rdma_user_cm.h index 5ded17468..838f8d460 100644 --- a/kernel-headers/rdma/rdma_user_cm.h +++ b/kernel-headers/rdma/rdma_user_cm.h @@ -192,6 +192,7 @@ struct rdma_ucm_query_path_resp { struct rdma_ucm_query_ib_service_resp { __u32 num_service_recs; + __u32 reserved; struct ib_user_service_rec recs[]; }; @@ -354,7 +355,7 @@ enum { #define RDMA_USER_CM_IB_SERVICE_NAME_SIZE 64 struct rdma_ucm_ib_service { - __u64 service_id; + __aligned_u64 service_id; __u8 service_name[RDMA_USER_CM_IB_SERVICE_NAME_SIZE]; __u32 flags; __u32 reserved; @@ -362,6 +363,7 @@ struct rdma_ucm_ib_service { struct rdma_ucm_resolve_ib_service { __u32 id; + __u32 reserved; struct rdma_ucm_ib_service ibs; }; diff --git a/libibverbs/verbs.h b/libibverbs/verbs.h index 36d120eec..3f4989bf7 100644 --- a/libibverbs/verbs.h +++ b/libibverbs/verbs.h @@ -52,21 +52,20 @@ #endif #if __GNUC__ >= 3 -# define __attribute_const __attribute__((const)) +#define __attribute_const __attribute_const__ #else -# define __attribute_const +#define __attribute_const #endif #ifdef __cplusplus extern "C" { #endif - union ibv_gid { - uint8_t raw[16]; + uint8_t raw[16]; struct { - __be64 subnet_prefix; - __be64 interface_id; + __be64 subnet_prefix; + __be64 interface_id; } global; }; @@ -93,8 +92,8 @@ struct ibv_gid_entry { #endif enum ibv_node_type { - IBV_NODE_UNKNOWN = -1, - IBV_NODE_CA = 1, + IBV_NODE_UNKNOWN = -1, + IBV_NODE_CA = 1, IBV_NODE_SWITCH, IBV_NODE_ROUTER, IBV_NODE_RNIC, @@ -104,8 +103,8 @@ enum ibv_node_type { }; enum ibv_transport_type { - IBV_TRANSPORT_UNKNOWN = -1, - IBV_TRANSPORT_IB = 0, + IBV_TRANSPORT_UNKNOWN = -1, + IBV_TRANSPORT_IB = 0, IBV_TRANSPORT_IWARP, IBV_TRANSPORT_USNIC, IBV_TRANSPORT_USNIC_UDP, @@ -113,29 +112,29 @@ enum ibv_transport_type { }; enum ibv_device_cap_flags { - IBV_DEVICE_RESIZE_MAX_WR = 1, - IBV_DEVICE_BAD_PKEY_CNTR = 1 << 1, - IBV_DEVICE_BAD_QKEY_CNTR = 1 << 2, - IBV_DEVICE_RAW_MULTI = 1 << 3, - IBV_DEVICE_AUTO_PATH_MIG = 1 << 4, - IBV_DEVICE_CHANGE_PHY_PORT = 1 << 5, - IBV_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6, - IBV_DEVICE_CURR_QP_STATE_MOD = 1 << 7, - IBV_DEVICE_SHUTDOWN_PORT = 1 << 8, - IBV_DEVICE_INIT_TYPE = 1 << 9, - IBV_DEVICE_PORT_ACTIVE_EVENT = 1 << 10, - IBV_DEVICE_SYS_IMAGE_GUID = 1 << 11, - IBV_DEVICE_RC_RNR_NAK_GEN = 1 << 12, - IBV_DEVICE_SRQ_RESIZE = 1 << 13, - IBV_DEVICE_N_NOTIFY_CQ = 1 << 14, - IBV_DEVICE_MEM_WINDOW = 1 << 17, - IBV_DEVICE_UD_IP_CSUM = 1 << 18, - IBV_DEVICE_XRC = 1 << 20, - IBV_DEVICE_MEM_MGT_EXTENSIONS = 1 << 21, - IBV_DEVICE_MEM_WINDOW_TYPE_2A = 1 << 23, - IBV_DEVICE_MEM_WINDOW_TYPE_2B = 1 << 24, - IBV_DEVICE_RC_IP_CSUM = 1 << 25, - IBV_DEVICE_RAW_IP_CSUM = 1 << 26, + IBV_DEVICE_RESIZE_MAX_WR = 1, + IBV_DEVICE_BAD_PKEY_CNTR = 1 << 1, + IBV_DEVICE_BAD_QKEY_CNTR = 1 << 2, + IBV_DEVICE_RAW_MULTI = 1 << 3, + IBV_DEVICE_AUTO_PATH_MIG = 1 << 4, + IBV_DEVICE_CHANGE_PHY_PORT = 1 << 5, + IBV_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6, + IBV_DEVICE_CURR_QP_STATE_MOD = 1 << 7, + IBV_DEVICE_SHUTDOWN_PORT = 1 << 8, + IBV_DEVICE_INIT_TYPE = 1 << 9, + IBV_DEVICE_PORT_ACTIVE_EVENT = 1 << 10, + IBV_DEVICE_SYS_IMAGE_GUID = 1 << 11, + IBV_DEVICE_RC_RNR_NAK_GEN = 1 << 12, + IBV_DEVICE_SRQ_RESIZE = 1 << 13, + IBV_DEVICE_N_NOTIFY_CQ = 1 << 14, + IBV_DEVICE_MEM_WINDOW = 1 << 17, + IBV_DEVICE_UD_IP_CSUM = 1 << 18, + IBV_DEVICE_XRC = 1 << 20, + IBV_DEVICE_MEM_MGT_EXTENSIONS = 1 << 21, + IBV_DEVICE_MEM_WINDOW_TYPE_2A = 1 << 23, + IBV_DEVICE_MEM_WINDOW_TYPE_2B = 1 << 24, + IBV_DEVICE_RC_IP_CSUM = 1 << 25, + IBV_DEVICE_RAW_IP_CSUM = 1 << 26, IBV_DEVICE_MANAGED_FLOW_STEERING = 1 << 29 }; @@ -152,11 +151,7 @@ enum ibv_fork_status { #define IBV_DEVICE_RAW_SCATTER_FCS (1ULL << 34) #define IBV_DEVICE_PCI_WRITE_END_PADDING (1ULL << 36) -enum ibv_atomic_cap { - IBV_ATOMIC_NONE, - IBV_ATOMIC_HCA, - IBV_ATOMIC_GLOB -}; +enum ibv_atomic_cap { IBV_ATOMIC_NONE, IBV_ATOMIC_HCA, IBV_ATOMIC_GLOB }; struct ibv_alloc_dm_attr { size_t length; @@ -180,52 +175,52 @@ struct ibv_dm { }; struct ibv_device_attr { - char fw_ver[64]; - __be64 node_guid; - __be64 sys_image_guid; - uint64_t max_mr_size; - uint64_t page_size_cap; - uint32_t vendor_id; - uint32_t vendor_part_id; - uint32_t hw_ver; - int max_qp; - int max_qp_wr; - unsigned int device_cap_flags; - int max_sge; - int max_sge_rd; - int max_cq; - int max_cqe; - int max_mr; - int max_pd; - int max_qp_rd_atom; - int max_ee_rd_atom; - int max_res_rd_atom; - int max_qp_init_rd_atom; - int max_ee_init_rd_atom; - enum ibv_atomic_cap atomic_cap; - int max_ee; - int max_rdd; - int max_mw; - int max_raw_ipv6_qp; - int max_raw_ethy_qp; - int max_mcast_grp; - int max_mcast_qp_attach; - int max_total_mcast_qp_attach; - int max_ah; - int max_fmr; - int max_map_per_fmr; - int max_srq; - int max_srq_wr; - int max_srq_sge; - uint16_t max_pkeys; - uint8_t local_ca_ack_delay; - uint8_t phys_port_cnt; + char fw_ver[64]; + __be64 node_guid; + __be64 sys_image_guid; + uint64_t max_mr_size; + uint64_t page_size_cap; + uint32_t vendor_id; + uint32_t vendor_part_id; + uint32_t hw_ver; + int max_qp; + int max_qp_wr; + unsigned int device_cap_flags; + int max_sge; + int max_sge_rd; + int max_cq; + int max_cqe; + int max_mr; + int max_pd; + int max_qp_rd_atom; + int max_ee_rd_atom; + int max_res_rd_atom; + int max_qp_init_rd_atom; + int max_ee_init_rd_atom; + enum ibv_atomic_cap atomic_cap; + int max_ee; + int max_rdd; + int max_mw; + int max_raw_ipv6_qp; + int max_raw_ethy_qp; + int max_mcast_grp; + int max_mcast_qp_attach; + int max_total_mcast_qp_attach; + int max_ah; + int max_fmr; + int max_map_per_fmr; + int max_srq; + int max_srq_wr; + int max_srq_sge; + uint16_t max_pkeys; + uint8_t local_ca_ack_delay; + uint8_t phys_port_cnt; }; /* An extensible input struct for possible future extensions of the * ibv_query_device_ex verb. */ struct ibv_query_device_ex_input { - uint32_t comp_mask; + uint32_t comp_mask; }; enum ibv_odp_general_caps { @@ -234,13 +229,13 @@ enum ibv_odp_general_caps { }; enum ibv_odp_transport_cap_bits { - IBV_ODP_SUPPORT_SEND = 1 << 0, - IBV_ODP_SUPPORT_RECV = 1 << 1, - IBV_ODP_SUPPORT_WRITE = 1 << 2, - IBV_ODP_SUPPORT_READ = 1 << 3, - IBV_ODP_SUPPORT_ATOMIC = 1 << 4, + IBV_ODP_SUPPORT_SEND = 1 << 0, + IBV_ODP_SUPPORT_RECV = 1 << 1, + IBV_ODP_SUPPORT_WRITE = 1 << 2, + IBV_ODP_SUPPORT_READ = 1 << 3, + IBV_ODP_SUPPORT_ATOMIC = 1 << 4, IBV_ODP_SUPPORT_SRQ_RECV = 1 << 5, - IBV_ODP_SUPPORT_FLUSH = 1 << 6, + IBV_ODP_SUPPORT_FLUSH = 1 << 6, IBV_ODP_SUPPORT_ATOMIC_WRITE = 1 << 7, }; @@ -260,7 +255,7 @@ struct ibv_tso_caps { /* RX Hash function flags */ enum ibv_rx_hash_function_flags { - IBV_RX_HASH_FUNC_TOEPLITZ = 1 << 0, + IBV_RX_HASH_FUNC_TOEPLITZ = 1 << 0, }; /* @@ -272,16 +267,16 @@ enum ibv_rx_hash_function_flags { * and *TCP and *UDP flags can't be enabled together on the same QP. */ enum ibv_rx_hash_fields { - IBV_RX_HASH_SRC_IPV4 = 1 << 0, - IBV_RX_HASH_DST_IPV4 = 1 << 1, - IBV_RX_HASH_SRC_IPV6 = 1 << 2, - IBV_RX_HASH_DST_IPV6 = 1 << 3, - IBV_RX_HASH_SRC_PORT_TCP = 1 << 4, - IBV_RX_HASH_DST_PORT_TCP = 1 << 5, - IBV_RX_HASH_SRC_PORT_UDP = 1 << 6, - IBV_RX_HASH_DST_PORT_UDP = 1 << 7, - IBV_RX_HASH_IPSEC_SPI = 1 << 8, - IBV_RX_HASH_INNER = (1UL << 31), + IBV_RX_HASH_SRC_IPV4 = 1 << 0, + IBV_RX_HASH_DST_IPV4 = 1 << 1, + IBV_RX_HASH_SRC_IPV6 = 1 << 2, + IBV_RX_HASH_DST_IPV6 = 1 << 3, + IBV_RX_HASH_SRC_PORT_TCP = 1 << 4, + IBV_RX_HASH_DST_PORT_TCP = 1 << 5, + IBV_RX_HASH_SRC_PORT_UDP = 1 << 6, + IBV_RX_HASH_DST_PORT_UDP = 1 << 7, + IBV_RX_HASH_IPSEC_SPI = 1 << 8, + IBV_RX_HASH_INNER = (1UL << 31), }; struct ibv_rss_caps { @@ -289,7 +284,7 @@ struct ibv_rss_caps { uint32_t max_rwq_indirection_tables; uint32_t max_rwq_indirection_table_size; uint64_t rx_hash_fields_mask; /* enum ibv_rx_hash_fields */ - uint8_t rx_hash_function; /* enum ibv_rx_hash_function_flags */ + uint8_t rx_hash_function; /* enum ibv_rx_hash_function_flags */ }; struct ibv_packet_pacing_caps { @@ -299,14 +294,14 @@ struct ibv_packet_pacing_caps { }; enum ibv_raw_packet_caps { - IBV_RAW_PACKET_CAP_CVLAN_STRIPPING = 1 << 0, - IBV_RAW_PACKET_CAP_SCATTER_FCS = 1 << 1, - IBV_RAW_PACKET_CAP_IP_CSUM = 1 << 2, - IBV_RAW_PACKET_CAP_DELAY_DROP = 1 << 3, + IBV_RAW_PACKET_CAP_CVLAN_STRIPPING = 1 << 0, + IBV_RAW_PACKET_CAP_SCATTER_FCS = 1 << 1, + IBV_RAW_PACKET_CAP_IP_CSUM = 1 << 2, + IBV_RAW_PACKET_CAP_DELAY_DROP = 1 << 3, }; enum ibv_tm_cap_flags { - IBV_TM_CAP_RC = 1 << 0, + IBV_TM_CAP_RC = 1 << 0, }; struct ibv_tm_caps { @@ -344,19 +339,19 @@ struct ibv_pci_atomic_caps { }; struct ibv_device_attr_ex { - struct ibv_device_attr orig_attr; - uint32_t comp_mask; - struct ibv_odp_caps odp_caps; - uint64_t completion_timestamp_mask; - uint64_t hca_core_clock; - uint64_t device_cap_flags_ex; - struct ibv_tso_caps tso_caps; - struct ibv_rss_caps rss_caps; - uint32_t max_wq_type_rq; + struct ibv_device_attr orig_attr; + uint32_t comp_mask; + struct ibv_odp_caps odp_caps; + uint64_t completion_timestamp_mask; + uint64_t hca_core_clock; + uint64_t device_cap_flags_ex; + struct ibv_tso_caps tso_caps; + struct ibv_rss_caps rss_caps; + uint32_t max_wq_type_rq; struct ibv_packet_pacing_caps packet_pacing_caps; - uint32_t raw_packet_caps; /* Use ibv_raw_packet_caps */ - struct ibv_tm_caps tm_caps; - struct ibv_cq_moderation_caps cq_mod_caps; + uint32_t raw_packet_caps; /* Use ibv_raw_packet_caps */ + struct ibv_tm_caps tm_caps; + struct ibv_cq_moderation_caps cq_mod_caps; uint64_t max_dm_size; struct ibv_pci_atomic_caps pci_atomic_caps; uint32_t xrc_odp_caps; @@ -364,20 +359,20 @@ struct ibv_device_attr_ex { }; enum ibv_mtu { - IBV_MTU_256 = 1, - IBV_MTU_512 = 2, + IBV_MTU_256 = 1, + IBV_MTU_512 = 2, IBV_MTU_1024 = 3, IBV_MTU_2048 = 4, IBV_MTU_4096 = 5 }; enum ibv_port_state { - IBV_PORT_NOP = 0, - IBV_PORT_DOWN = 1, - IBV_PORT_INIT = 2, - IBV_PORT_ARMED = 3, - IBV_PORT_ACTIVE = 4, - IBV_PORT_ACTIVE_DEFER = 5 + IBV_PORT_NOP = 0, + IBV_PORT_DOWN = 1, + IBV_PORT_INIT = 2, + IBV_PORT_ARMED = 3, + IBV_PORT_ACTIVE = 4, + IBV_PORT_ACTIVE_DEFER = 5 }; enum { @@ -387,67 +382,67 @@ enum { }; enum ibv_port_cap_flags { - IBV_PORT_SM = 1 << 1, - IBV_PORT_NOTICE_SUP = 1 << 2, - IBV_PORT_TRAP_SUP = 1 << 3, - IBV_PORT_OPT_IPD_SUP = 1 << 4, - IBV_PORT_AUTO_MIGR_SUP = 1 << 5, - IBV_PORT_SL_MAP_SUP = 1 << 6, - IBV_PORT_MKEY_NVRAM = 1 << 7, - IBV_PORT_PKEY_NVRAM = 1 << 8, - IBV_PORT_LED_INFO_SUP = 1 << 9, - IBV_PORT_SYS_IMAGE_GUID_SUP = 1 << 11, - IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12, - IBV_PORT_EXTENDED_SPEEDS_SUP = 1 << 14, - IBV_PORT_CAP_MASK2_SUP = 1 << 15, - IBV_PORT_CM_SUP = 1 << 16, - IBV_PORT_SNMP_TUNNEL_SUP = 1 << 17, - IBV_PORT_REINIT_SUP = 1 << 18, - IBV_PORT_DEVICE_MGMT_SUP = 1 << 19, - IBV_PORT_VENDOR_CLASS_SUP = 1 << 20, - IBV_PORT_DR_NOTICE_SUP = 1 << 21, - IBV_PORT_CAP_MASK_NOTICE_SUP = 1 << 22, - IBV_PORT_BOOT_MGMT_SUP = 1 << 23, - IBV_PORT_LINK_LATENCY_SUP = 1 << 24, - IBV_PORT_CLIENT_REG_SUP = 1 << 25, - IBV_PORT_IP_BASED_GIDS = 1 << 26 + IBV_PORT_SM = 1 << 1, + IBV_PORT_NOTICE_SUP = 1 << 2, + IBV_PORT_TRAP_SUP = 1 << 3, + IBV_PORT_OPT_IPD_SUP = 1 << 4, + IBV_PORT_AUTO_MIGR_SUP = 1 << 5, + IBV_PORT_SL_MAP_SUP = 1 << 6, + IBV_PORT_MKEY_NVRAM = 1 << 7, + IBV_PORT_PKEY_NVRAM = 1 << 8, + IBV_PORT_LED_INFO_SUP = 1 << 9, + IBV_PORT_SYS_IMAGE_GUID_SUP = 1 << 11, + IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12, + IBV_PORT_EXTENDED_SPEEDS_SUP = 1 << 14, + IBV_PORT_CAP_MASK2_SUP = 1 << 15, + IBV_PORT_CM_SUP = 1 << 16, + IBV_PORT_SNMP_TUNNEL_SUP = 1 << 17, + IBV_PORT_REINIT_SUP = 1 << 18, + IBV_PORT_DEVICE_MGMT_SUP = 1 << 19, + IBV_PORT_VENDOR_CLASS_SUP = 1 << 20, + IBV_PORT_DR_NOTICE_SUP = 1 << 21, + IBV_PORT_CAP_MASK_NOTICE_SUP = 1 << 22, + IBV_PORT_BOOT_MGMT_SUP = 1 << 23, + IBV_PORT_LINK_LATENCY_SUP = 1 << 24, + IBV_PORT_CLIENT_REG_SUP = 1 << 25, + IBV_PORT_IP_BASED_GIDS = 1 << 26 }; enum ibv_port_cap_flags2 { - IBV_PORT_SET_NODE_DESC_SUP = 1 << 0, - IBV_PORT_INFO_EXT_SUP = 1 << 1, - IBV_PORT_VIRT_SUP = 1 << 2, - IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP = 1 << 3, - IBV_PORT_LINK_WIDTH_2X_SUP = 1 << 4, - IBV_PORT_LINK_SPEED_HDR_SUP = 1 << 5, - IBV_PORT_LINK_SPEED_NDR_SUP = 1 << 10, - IBV_PORT_LINK_SPEED_XDR_SUP = 1 << 12, + IBV_PORT_SET_NODE_DESC_SUP = 1 << 0, + IBV_PORT_INFO_EXT_SUP = 1 << 1, + IBV_PORT_VIRT_SUP = 1 << 2, + IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP = 1 << 3, + IBV_PORT_LINK_WIDTH_2X_SUP = 1 << 4, + IBV_PORT_LINK_SPEED_HDR_SUP = 1 << 5, + IBV_PORT_LINK_SPEED_NDR_SUP = 1 << 10, + IBV_PORT_LINK_SPEED_XDR_SUP = 1 << 12, }; struct ibv_port_attr { - enum ibv_port_state state; - enum ibv_mtu max_mtu; - enum ibv_mtu active_mtu; - int gid_tbl_len; - uint32_t port_cap_flags; - uint32_t max_msg_sz; - uint32_t bad_pkey_cntr; - uint32_t qkey_viol_cntr; - uint16_t pkey_tbl_len; - uint16_t lid; - uint16_t sm_lid; - uint8_t lmc; - uint8_t max_vl_num; - uint8_t sm_sl; - uint8_t subnet_timeout; - uint8_t init_type_reply; - uint8_t active_width; - uint8_t active_speed; - uint8_t phys_state; - uint8_t link_layer; - uint8_t flags; - uint16_t port_cap_flags2; - uint32_t active_speed_ex; + enum ibv_port_state state; + enum ibv_mtu max_mtu; + enum ibv_mtu active_mtu; + int gid_tbl_len; + uint32_t port_cap_flags; + uint32_t max_msg_sz; + uint32_t bad_pkey_cntr; + uint32_t qkey_viol_cntr; + uint16_t pkey_tbl_len; + uint16_t lid; + uint16_t sm_lid; + uint8_t lmc; + uint8_t max_vl_num; + uint8_t sm_sl; + uint8_t subnet_timeout; + uint8_t init_type_reply; + uint8_t active_width; + uint8_t active_speed; + uint8_t phys_state; + uint8_t link_layer; + uint8_t flags; + uint16_t port_cap_flags2; + uint32_t active_speed_ex; }; enum ibv_event_type { @@ -476,13 +471,13 @@ enum ibv_event_type { struct ibv_async_event { union { - struct ibv_cq *cq; - struct ibv_qp *qp; + struct ibv_cq *cq; + struct ibv_qp *qp; struct ibv_srq *srq; - struct ibv_wq *wq; - int port_num; + struct ibv_wq *wq; + int port_num; } element; - enum ibv_event_type event_type; + enum ibv_event_type event_type; }; enum ibv_wc_status { @@ -524,11 +519,11 @@ enum ibv_wc_opcode { IBV_WC_TSO, IBV_WC_FLUSH, IBV_WC_ATOMIC_WRITE = 9, -/* + /* * Set value of IBV_WC_RECV so consumers can test if a completion is a * receive by testing (opcode & IBV_WC_RECV). */ - IBV_WC_RECV = 1 << 7, + IBV_WC_RECV = 1 << 7, IBV_WC_RECV_RDMA_WITH_IMM, IBV_WC_TM_ADD, @@ -541,95 +536,89 @@ enum ibv_wc_opcode { IBV_WC_DRIVER3, }; -enum { - IBV_WC_IP_CSUM_OK_SHIFT = 2 -}; +enum { IBV_WC_IP_CSUM_OK_SHIFT = 2 }; enum ibv_create_cq_wc_flags { - IBV_WC_EX_WITH_BYTE_LEN = 1 << 0, - IBV_WC_EX_WITH_IMM = 1 << 1, - IBV_WC_EX_WITH_QP_NUM = 1 << 2, - IBV_WC_EX_WITH_SRC_QP = 1 << 3, - IBV_WC_EX_WITH_SLID = 1 << 4, - IBV_WC_EX_WITH_SL = 1 << 5, - IBV_WC_EX_WITH_DLID_PATH_BITS = 1 << 6, - IBV_WC_EX_WITH_COMPLETION_TIMESTAMP = 1 << 7, - IBV_WC_EX_WITH_CVLAN = 1 << 8, - IBV_WC_EX_WITH_FLOW_TAG = 1 << 9, - IBV_WC_EX_WITH_TM_INFO = 1 << 10, - IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK = 1 << 11, + IBV_WC_EX_WITH_BYTE_LEN = 1 << 0, + IBV_WC_EX_WITH_IMM = 1 << 1, + IBV_WC_EX_WITH_QP_NUM = 1 << 2, + IBV_WC_EX_WITH_SRC_QP = 1 << 3, + IBV_WC_EX_WITH_SLID = 1 << 4, + IBV_WC_EX_WITH_SL = 1 << 5, + IBV_WC_EX_WITH_DLID_PATH_BITS = 1 << 6, + IBV_WC_EX_WITH_COMPLETION_TIMESTAMP = 1 << 7, + IBV_WC_EX_WITH_CVLAN = 1 << 8, + IBV_WC_EX_WITH_FLOW_TAG = 1 << 9, + IBV_WC_EX_WITH_TM_INFO = 1 << 10, + IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK = 1 << 11, }; enum { - IBV_WC_STANDARD_FLAGS = IBV_WC_EX_WITH_BYTE_LEN | - IBV_WC_EX_WITH_IMM | - IBV_WC_EX_WITH_QP_NUM | - IBV_WC_EX_WITH_SRC_QP | - IBV_WC_EX_WITH_SLID | - IBV_WC_EX_WITH_SL | - IBV_WC_EX_WITH_DLID_PATH_BITS + IBV_WC_STANDARD_FLAGS = IBV_WC_EX_WITH_BYTE_LEN | IBV_WC_EX_WITH_IMM | + IBV_WC_EX_WITH_QP_NUM | IBV_WC_EX_WITH_SRC_QP | + IBV_WC_EX_WITH_SLID | IBV_WC_EX_WITH_SL | + IBV_WC_EX_WITH_DLID_PATH_BITS }; enum { - IBV_CREATE_CQ_SUP_WC_FLAGS = IBV_WC_STANDARD_FLAGS | - IBV_WC_EX_WITH_COMPLETION_TIMESTAMP | - IBV_WC_EX_WITH_CVLAN | - IBV_WC_EX_WITH_FLOW_TAG | - IBV_WC_EX_WITH_TM_INFO | - IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK + IBV_CREATE_CQ_SUP_WC_FLAGS = + IBV_WC_STANDARD_FLAGS | IBV_WC_EX_WITH_COMPLETION_TIMESTAMP | + IBV_WC_EX_WITH_CVLAN | IBV_WC_EX_WITH_FLOW_TAG | + IBV_WC_EX_WITH_TM_INFO | + IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK }; enum ibv_wc_flags { - IBV_WC_GRH = 1 << 0, - IBV_WC_WITH_IMM = 1 << 1, - IBV_WC_IP_CSUM_OK = 1 << IBV_WC_IP_CSUM_OK_SHIFT, - IBV_WC_WITH_INV = 1 << 3, - IBV_WC_TM_SYNC_REQ = 1 << 4, - IBV_WC_TM_MATCH = 1 << 5, - IBV_WC_TM_DATA_VALID = 1 << 6, + IBV_WC_GRH = 1 << 0, + IBV_WC_WITH_IMM = 1 << 1, + IBV_WC_IP_CSUM_OK = 1 << IBV_WC_IP_CSUM_OK_SHIFT, + IBV_WC_WITH_INV = 1 << 3, + IBV_WC_TM_SYNC_REQ = 1 << 4, + IBV_WC_TM_MATCH = 1 << 5, + IBV_WC_TM_DATA_VALID = 1 << 6, }; struct ibv_wc { - uint64_t wr_id; - enum ibv_wc_status status; - enum ibv_wc_opcode opcode; - uint32_t vendor_err; - uint32_t byte_len; + uint64_t wr_id; + enum ibv_wc_status status; + enum ibv_wc_opcode opcode; + uint32_t vendor_err; + uint32_t byte_len; /* When (wc_flags & IBV_WC_WITH_IMM): Immediate data in network byte order. * When (wc_flags & IBV_WC_WITH_INV): Stores the invalidated rkey. */ union { - __be32 imm_data; - uint32_t invalidated_rkey; + __be32 imm_data; + uint32_t invalidated_rkey; }; - uint32_t qp_num; - uint32_t src_qp; - unsigned int wc_flags; - uint16_t pkey_index; - uint16_t slid; - uint8_t sl; - uint8_t dlid_path_bits; + uint32_t qp_num; + uint32_t src_qp; + unsigned int wc_flags; + uint16_t pkey_index; + uint16_t slid; + uint8_t sl; + uint8_t dlid_path_bits; }; enum ibv_access_flags { - IBV_ACCESS_LOCAL_WRITE = 1, - IBV_ACCESS_REMOTE_WRITE = (1<<1), - IBV_ACCESS_REMOTE_READ = (1<<2), - IBV_ACCESS_REMOTE_ATOMIC = (1<<3), - IBV_ACCESS_MW_BIND = (1<<4), - IBV_ACCESS_ZERO_BASED = (1<<5), - IBV_ACCESS_ON_DEMAND = (1<<6), - IBV_ACCESS_HUGETLB = (1<<7), - IBV_ACCESS_FLUSH_GLOBAL = (1 << 8), - IBV_ACCESS_FLUSH_PERSISTENT = (1 << 9), - IBV_ACCESS_RELAXED_ORDERING = IBV_ACCESS_OPTIONAL_FIRST, + IBV_ACCESS_LOCAL_WRITE = 1, + IBV_ACCESS_REMOTE_WRITE = (1 << 1), + IBV_ACCESS_REMOTE_READ = (1 << 2), + IBV_ACCESS_REMOTE_ATOMIC = (1 << 3), + IBV_ACCESS_MW_BIND = (1 << 4), + IBV_ACCESS_ZERO_BASED = (1 << 5), + IBV_ACCESS_ON_DEMAND = (1 << 6), + IBV_ACCESS_HUGETLB = (1 << 7), + IBV_ACCESS_FLUSH_GLOBAL = (1 << 8), + IBV_ACCESS_FLUSH_PERSISTENT = (1 << 9), + IBV_ACCESS_RELAXED_ORDERING = IBV_ACCESS_OPTIONAL_FIRST, }; struct ibv_mw_bind_info { - struct ibv_mr *mr; - uint64_t addr; - uint64_t length; - unsigned int mw_access_flags; /* use ibv_access_flags */ + struct ibv_mr *mr; + uint64_t addr; + uint64_t length; + unsigned int mw_access_flags; /* use ibv_access_flags */ }; struct ibv_dmah { @@ -637,8 +626,8 @@ struct ibv_dmah { }; struct ibv_pd { - struct ibv_context *context; - uint32_t handle; + struct ibv_context *context; + uint32_t handle; }; struct ibv_td_init_attr { @@ -646,40 +635,40 @@ struct ibv_td_init_attr { }; struct ibv_td { - struct ibv_context *context; + struct ibv_context *context; }; enum ibv_xrcd_init_attr_mask { - IBV_XRCD_INIT_ATTR_FD = 1 << 0, - IBV_XRCD_INIT_ATTR_OFLAGS = 1 << 1, + IBV_XRCD_INIT_ATTR_FD = 1 << 0, + IBV_XRCD_INIT_ATTR_OFLAGS = 1 << 1, IBV_XRCD_INIT_ATTR_RESERVED = 1 << 2 }; struct ibv_xrcd_init_attr { uint32_t comp_mask; - int fd; - int oflags; + int fd; + int oflags; }; struct ibv_xrcd { - struct ibv_context *context; + struct ibv_context *context; }; enum ibv_rereg_mr_flags { - IBV_REREG_MR_CHANGE_TRANSLATION = (1 << 0), - IBV_REREG_MR_CHANGE_PD = (1 << 1), - IBV_REREG_MR_CHANGE_ACCESS = (1 << 2), - IBV_REREG_MR_FLAGS_SUPPORTED = ((IBV_REREG_MR_CHANGE_ACCESS << 1) - 1) + IBV_REREG_MR_CHANGE_TRANSLATION = (1 << 0), + IBV_REREG_MR_CHANGE_PD = (1 << 1), + IBV_REREG_MR_CHANGE_ACCESS = (1 << 2), + IBV_REREG_MR_FLAGS_SUPPORTED = ((IBV_REREG_MR_CHANGE_ACCESS << 1) - 1) }; struct ibv_mr { - struct ibv_context *context; - struct ibv_pd *pd; - void *addr; - size_t length; - uint32_t handle; - uint32_t lkey; - uint32_t rkey; + struct ibv_context *context; + struct ibv_pd *pd; + void *addr; + size_t length; + uint32_t handle; + uint32_t lkey; + uint32_t rkey; }; enum ibv_mr_init_attr_mask { @@ -701,57 +690,54 @@ struct ibv_mr_init_attr { struct ibv_dmah *dmah; }; -enum ibv_mw_type { - IBV_MW_TYPE_1 = 1, - IBV_MW_TYPE_2 = 2 -}; +enum ibv_mw_type { IBV_MW_TYPE_1 = 1, IBV_MW_TYPE_2 = 2 }; struct ibv_mw { - struct ibv_context *context; - struct ibv_pd *pd; - uint32_t rkey; - uint32_t handle; - enum ibv_mw_type type; + struct ibv_context *context; + struct ibv_pd *pd; + uint32_t rkey; + uint32_t handle; + enum ibv_mw_type type; }; struct ibv_global_route { - union ibv_gid dgid; - uint32_t flow_label; - uint8_t sgid_index; - uint8_t hop_limit; - uint8_t traffic_class; + union ibv_gid dgid; + uint32_t flow_label; + uint8_t sgid_index; + uint8_t hop_limit; + uint8_t traffic_class; }; struct ibv_grh { - __be32 version_tclass_flow; - __be16 paylen; - uint8_t next_hdr; - uint8_t hop_limit; - union ibv_gid sgid; - union ibv_gid dgid; + __be32 version_tclass_flow; + __be16 paylen; + uint8_t next_hdr; + uint8_t hop_limit; + union ibv_gid sgid; + union ibv_gid dgid; }; enum ibv_rate { - IBV_RATE_MAX = 0, + IBV_RATE_MAX = 0, IBV_RATE_2_5_GBPS = 2, - IBV_RATE_5_GBPS = 5, - IBV_RATE_10_GBPS = 3, - IBV_RATE_20_GBPS = 6, - IBV_RATE_30_GBPS = 4, - IBV_RATE_40_GBPS = 7, - IBV_RATE_60_GBPS = 8, - IBV_RATE_80_GBPS = 9, + IBV_RATE_5_GBPS = 5, + IBV_RATE_10_GBPS = 3, + IBV_RATE_20_GBPS = 6, + IBV_RATE_30_GBPS = 4, + IBV_RATE_40_GBPS = 7, + IBV_RATE_60_GBPS = 8, + IBV_RATE_80_GBPS = 9, IBV_RATE_120_GBPS = 10, - IBV_RATE_14_GBPS = 11, - IBV_RATE_56_GBPS = 12, + IBV_RATE_14_GBPS = 11, + IBV_RATE_56_GBPS = 12, IBV_RATE_112_GBPS = 13, IBV_RATE_168_GBPS = 14, - IBV_RATE_25_GBPS = 15, + IBV_RATE_25_GBPS = 15, IBV_RATE_100_GBPS = 16, IBV_RATE_200_GBPS = 17, IBV_RATE_300_GBPS = 18, - IBV_RATE_28_GBPS = 19, - IBV_RATE_50_GBPS = 20, + IBV_RATE_28_GBPS = 19, + IBV_RATE_50_GBPS = 20, IBV_RATE_400_GBPS = 21, IBV_RATE_600_GBPS = 22, IBV_RATE_800_GBPS = 23, @@ -764,7 +750,7 @@ enum ibv_rate { * converted to 2, since 5 Gbit/sec is 2 * 2.5 Gbit/sec. * @rate: rate to convert. */ -int __attribute_const ibv_rate_to_mult(enum ibv_rate rate); +int __attribute_const ibv_rate_to_mult(enum ibv_rate rate); /** * mult_to_ibv_rate - Convert a multiple of 2.5 Gbit/sec to an IB rate enum. @@ -786,29 +772,26 @@ int __attribute_const ibv_rate_to_mbps(enum ibv_rate rate); enum ibv_rate __attribute_const mbps_to_ibv_rate(int mbps); struct ibv_ah_attr { - struct ibv_global_route grh; - uint16_t dlid; - uint8_t sl; - uint8_t src_path_bits; - uint8_t static_rate; - uint8_t is_global; - uint8_t port_num; + struct ibv_global_route grh; + uint16_t dlid; + uint8_t sl; + uint8_t src_path_bits; + uint8_t static_rate; + uint8_t is_global; + uint8_t port_num; }; -enum ibv_srq_attr_mask { - IBV_SRQ_MAX_WR = 1 << 0, - IBV_SRQ_LIMIT = 1 << 1 -}; +enum ibv_srq_attr_mask { IBV_SRQ_MAX_WR = 1 << 0, IBV_SRQ_LIMIT = 1 << 1 }; struct ibv_srq_attr { - uint32_t max_wr; - uint32_t max_sge; - uint32_t srq_limit; + uint32_t max_wr; + uint32_t max_sge; + uint32_t srq_limit; }; struct ibv_srq_init_attr { - void *srq_context; - struct ibv_srq_attr attr; + void *srq_context; + struct ibv_srq_attr attr; }; enum ibv_srq_type { @@ -818,82 +801,75 @@ enum ibv_srq_type { }; enum ibv_srq_init_attr_mask { - IBV_SRQ_INIT_ATTR_TYPE = 1 << 0, - IBV_SRQ_INIT_ATTR_PD = 1 << 1, - IBV_SRQ_INIT_ATTR_XRCD = 1 << 2, - IBV_SRQ_INIT_ATTR_CQ = 1 << 3, - IBV_SRQ_INIT_ATTR_TM = 1 << 4, - IBV_SRQ_INIT_ATTR_RESERVED = 1 << 5, + IBV_SRQ_INIT_ATTR_TYPE = 1 << 0, + IBV_SRQ_INIT_ATTR_PD = 1 << 1, + IBV_SRQ_INIT_ATTR_XRCD = 1 << 2, + IBV_SRQ_INIT_ATTR_CQ = 1 << 3, + IBV_SRQ_INIT_ATTR_TM = 1 << 4, + IBV_SRQ_INIT_ATTR_RESERVED = 1 << 5, }; struct ibv_tm_cap { - uint32_t max_num_tags; - uint32_t max_ops; + uint32_t max_num_tags; + uint32_t max_ops; }; struct ibv_srq_init_attr_ex { - void *srq_context; - struct ibv_srq_attr attr; + void *srq_context; + struct ibv_srq_attr attr; - uint32_t comp_mask; - enum ibv_srq_type srq_type; - struct ibv_pd *pd; - struct ibv_xrcd *xrcd; - struct ibv_cq *cq; - struct ibv_tm_cap tm_cap; + uint32_t comp_mask; + enum ibv_srq_type srq_type; + struct ibv_pd *pd; + struct ibv_xrcd *xrcd; + struct ibv_cq *cq; + struct ibv_tm_cap tm_cap; }; -enum ibv_wq_type { - IBV_WQT_RQ -}; +enum ibv_wq_type { IBV_WQT_RQ }; enum ibv_wq_init_attr_mask { - IBV_WQ_INIT_ATTR_FLAGS = 1 << 0, - IBV_WQ_INIT_ATTR_RESERVED = 1 << 1, + IBV_WQ_INIT_ATTR_FLAGS = 1 << 0, + IBV_WQ_INIT_ATTR_RESERVED = 1 << 1, }; enum ibv_wq_flags { - IBV_WQ_FLAGS_CVLAN_STRIPPING = 1 << 0, - IBV_WQ_FLAGS_SCATTER_FCS = 1 << 1, - IBV_WQ_FLAGS_DELAY_DROP = 1 << 2, - IBV_WQ_FLAGS_PCI_WRITE_END_PADDING = 1 << 3, - IBV_WQ_FLAGS_RESERVED = 1 << 4, + IBV_WQ_FLAGS_CVLAN_STRIPPING = 1 << 0, + IBV_WQ_FLAGS_SCATTER_FCS = 1 << 1, + IBV_WQ_FLAGS_DELAY_DROP = 1 << 2, + IBV_WQ_FLAGS_PCI_WRITE_END_PADDING = 1 << 3, + IBV_WQ_FLAGS_RESERVED = 1 << 4, }; struct ibv_wq_init_attr { - void *wq_context; - enum ibv_wq_type wq_type; - uint32_t max_wr; - uint32_t max_sge; - struct ibv_pd *pd; - struct ibv_cq *cq; - uint32_t comp_mask; /* Use ibv_wq_init_attr_mask */ - uint32_t create_flags; /* use ibv_wq_flags */ + void *wq_context; + enum ibv_wq_type wq_type; + uint32_t max_wr; + uint32_t max_sge; + struct ibv_pd *pd; + struct ibv_cq *cq; + uint32_t comp_mask; /* Use ibv_wq_init_attr_mask */ + uint32_t create_flags; /* use ibv_wq_flags */ }; -enum ibv_wq_state { - IBV_WQS_RESET, - IBV_WQS_RDY, - IBV_WQS_ERR, - IBV_WQS_UNKNOWN -}; +enum ibv_wq_state { IBV_WQS_RESET, IBV_WQS_RDY, IBV_WQS_ERR, IBV_WQS_UNKNOWN }; enum ibv_wq_attr_mask { - IBV_WQ_ATTR_STATE = 1 << 0, - IBV_WQ_ATTR_CURR_STATE = 1 << 1, - IBV_WQ_ATTR_FLAGS = 1 << 2, - IBV_WQ_ATTR_RESERVED = 1 << 3, + IBV_WQ_ATTR_STATE = 1 << 0, + IBV_WQ_ATTR_CURR_STATE = 1 << 1, + IBV_WQ_ATTR_FLAGS = 1 << 2, + IBV_WQ_ATTR_RESERVED = 1 << 3, }; struct ibv_wq_attr { /* enum ibv_wq_attr_mask */ - uint32_t attr_mask; + uint32_t attr_mask; /* Move the WQ to this state */ - enum ibv_wq_state wq_state; + enum ibv_wq_state wq_state; /* Assume this is the current WQ state */ - enum ibv_wq_state curr_wq_state; - uint32_t flags; /* Use ibv_wq_flags */ - uint32_t flags_mask; /* Use ibv_wq_flags */ + enum ibv_wq_state curr_wq_state; + uint32_t flags; /* Use ibv_wq_flags */ + uint32_t flags_mask; /* Use ibv_wq_flags */ }; /* @@ -910,9 +886,7 @@ struct ibv_rwq_ind_table { uint32_t comp_mask; }; -enum ibv_ind_table_init_attr_mask { - IBV_CREATE_IND_TABLE_RESERVED = (1 << 0) -}; +enum ibv_ind_table_init_attr_mask { IBV_CREATE_IND_TABLE_RESERVED = (1 << 0) }; /* * Receive Work Queue Indirection Table attributes @@ -935,125 +909,125 @@ enum ibv_qp_type { }; struct ibv_qp_cap { - uint32_t max_send_wr; - uint32_t max_recv_wr; - uint32_t max_send_sge; - uint32_t max_recv_sge; - uint32_t max_inline_data; + uint32_t max_send_wr; + uint32_t max_recv_wr; + uint32_t max_send_sge; + uint32_t max_recv_sge; + uint32_t max_inline_data; }; struct ibv_qp_init_attr { - void *qp_context; - struct ibv_cq *send_cq; - struct ibv_cq *recv_cq; - struct ibv_srq *srq; - struct ibv_qp_cap cap; - enum ibv_qp_type qp_type; - int sq_sig_all; + void *qp_context; + struct ibv_cq *send_cq; + struct ibv_cq *recv_cq; + struct ibv_srq *srq; + struct ibv_qp_cap cap; + enum ibv_qp_type qp_type; + int sq_sig_all; }; enum ibv_qp_init_attr_mask { - IBV_QP_INIT_ATTR_PD = 1 << 0, - IBV_QP_INIT_ATTR_XRCD = 1 << 1, - IBV_QP_INIT_ATTR_CREATE_FLAGS = 1 << 2, + IBV_QP_INIT_ATTR_PD = 1 << 0, + IBV_QP_INIT_ATTR_XRCD = 1 << 1, + IBV_QP_INIT_ATTR_CREATE_FLAGS = 1 << 2, IBV_QP_INIT_ATTR_MAX_TSO_HEADER = 1 << 3, - IBV_QP_INIT_ATTR_IND_TABLE = 1 << 4, - IBV_QP_INIT_ATTR_RX_HASH = 1 << 5, + IBV_QP_INIT_ATTR_IND_TABLE = 1 << 4, + IBV_QP_INIT_ATTR_RX_HASH = 1 << 5, IBV_QP_INIT_ATTR_SEND_OPS_FLAGS = 1 << 6, }; enum ibv_qp_create_flags { - IBV_QP_CREATE_BLOCK_SELF_MCAST_LB = 1 << 1, - IBV_QP_CREATE_SCATTER_FCS = 1 << 8, - IBV_QP_CREATE_CVLAN_STRIPPING = 1 << 9, - IBV_QP_CREATE_SOURCE_QPN = 1 << 10, - IBV_QP_CREATE_PCI_WRITE_END_PADDING = 1 << 11, + IBV_QP_CREATE_BLOCK_SELF_MCAST_LB = 1 << 1, + IBV_QP_CREATE_SCATTER_FCS = 1 << 8, + IBV_QP_CREATE_CVLAN_STRIPPING = 1 << 9, + IBV_QP_CREATE_SOURCE_QPN = 1 << 10, + IBV_QP_CREATE_PCI_WRITE_END_PADDING = 1 << 11, }; enum ibv_qp_create_send_ops_flags { - IBV_QP_EX_WITH_RDMA_WRITE = 1 << 0, - IBV_QP_EX_WITH_RDMA_WRITE_WITH_IMM = 1 << 1, - IBV_QP_EX_WITH_SEND = 1 << 2, - IBV_QP_EX_WITH_SEND_WITH_IMM = 1 << 3, - IBV_QP_EX_WITH_RDMA_READ = 1 << 4, - IBV_QP_EX_WITH_ATOMIC_CMP_AND_SWP = 1 << 5, - IBV_QP_EX_WITH_ATOMIC_FETCH_AND_ADD = 1 << 6, - IBV_QP_EX_WITH_LOCAL_INV = 1 << 7, - IBV_QP_EX_WITH_BIND_MW = 1 << 8, - IBV_QP_EX_WITH_SEND_WITH_INV = 1 << 9, - IBV_QP_EX_WITH_TSO = 1 << 10, - IBV_QP_EX_WITH_FLUSH = 1 << 11, - IBV_QP_EX_WITH_ATOMIC_WRITE = 1 << 12, + IBV_QP_EX_WITH_RDMA_WRITE = 1 << 0, + IBV_QP_EX_WITH_RDMA_WRITE_WITH_IMM = 1 << 1, + IBV_QP_EX_WITH_SEND = 1 << 2, + IBV_QP_EX_WITH_SEND_WITH_IMM = 1 << 3, + IBV_QP_EX_WITH_RDMA_READ = 1 << 4, + IBV_QP_EX_WITH_ATOMIC_CMP_AND_SWP = 1 << 5, + IBV_QP_EX_WITH_ATOMIC_FETCH_AND_ADD = 1 << 6, + IBV_QP_EX_WITH_LOCAL_INV = 1 << 7, + IBV_QP_EX_WITH_BIND_MW = 1 << 8, + IBV_QP_EX_WITH_SEND_WITH_INV = 1 << 9, + IBV_QP_EX_WITH_TSO = 1 << 10, + IBV_QP_EX_WITH_FLUSH = 1 << 11, + IBV_QP_EX_WITH_ATOMIC_WRITE = 1 << 12, }; struct ibv_rx_hash_conf { /* enum ibv_rx_hash_function_flags */ - uint8_t rx_hash_function; - uint8_t rx_hash_key_len; - uint8_t *rx_hash_key; + uint8_t rx_hash_function; + uint8_t rx_hash_key_len; + uint8_t *rx_hash_key; /* enum ibv_rx_hash_fields */ - uint64_t rx_hash_fields_mask; + uint64_t rx_hash_fields_mask; }; struct ibv_qp_init_attr_ex { - void *qp_context; - struct ibv_cq *send_cq; - struct ibv_cq *recv_cq; - struct ibv_srq *srq; - struct ibv_qp_cap cap; - enum ibv_qp_type qp_type; - int sq_sig_all; - - uint32_t comp_mask; - struct ibv_pd *pd; - struct ibv_xrcd *xrcd; - uint32_t create_flags; - uint16_t max_tso_header; - struct ibv_rwq_ind_table *rwq_ind_tbl; - struct ibv_rx_hash_conf rx_hash_conf; - uint32_t source_qpn; + void *qp_context; + struct ibv_cq *send_cq; + struct ibv_cq *recv_cq; + struct ibv_srq *srq; + struct ibv_qp_cap cap; + enum ibv_qp_type qp_type; + int sq_sig_all; + + uint32_t comp_mask; + struct ibv_pd *pd; + struct ibv_xrcd *xrcd; + uint32_t create_flags; + uint16_t max_tso_header; + struct ibv_rwq_ind_table *rwq_ind_tbl; + struct ibv_rx_hash_conf rx_hash_conf; + uint32_t source_qpn; /* See enum ibv_qp_create_send_ops_flags */ uint64_t send_ops_flags; }; enum ibv_qp_open_attr_mask { - IBV_QP_OPEN_ATTR_NUM = 1 << 0, - IBV_QP_OPEN_ATTR_XRCD = 1 << 1, - IBV_QP_OPEN_ATTR_CONTEXT = 1 << 2, - IBV_QP_OPEN_ATTR_TYPE = 1 << 3, - IBV_QP_OPEN_ATTR_RESERVED = 1 << 4 + IBV_QP_OPEN_ATTR_NUM = 1 << 0, + IBV_QP_OPEN_ATTR_XRCD = 1 << 1, + IBV_QP_OPEN_ATTR_CONTEXT = 1 << 2, + IBV_QP_OPEN_ATTR_TYPE = 1 << 3, + IBV_QP_OPEN_ATTR_RESERVED = 1 << 4 }; struct ibv_qp_open_attr { - uint32_t comp_mask; - uint32_t qp_num; - struct ibv_xrcd *xrcd; - void *qp_context; - enum ibv_qp_type qp_type; + uint32_t comp_mask; + uint32_t qp_num; + struct ibv_xrcd *xrcd; + void *qp_context; + enum ibv_qp_type qp_type; }; enum ibv_qp_attr_mask { - IBV_QP_STATE = 1 << 0, - IBV_QP_CUR_STATE = 1 << 1, - IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2, - IBV_QP_ACCESS_FLAGS = 1 << 3, - IBV_QP_PKEY_INDEX = 1 << 4, - IBV_QP_PORT = 1 << 5, - IBV_QP_QKEY = 1 << 6, - IBV_QP_AV = 1 << 7, - IBV_QP_PATH_MTU = 1 << 8, - IBV_QP_TIMEOUT = 1 << 9, - IBV_QP_RETRY_CNT = 1 << 10, - IBV_QP_RNR_RETRY = 1 << 11, - IBV_QP_RQ_PSN = 1 << 12, - IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13, - IBV_QP_ALT_PATH = 1 << 14, - IBV_QP_MIN_RNR_TIMER = 1 << 15, - IBV_QP_SQ_PSN = 1 << 16, - IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17, - IBV_QP_PATH_MIG_STATE = 1 << 18, - IBV_QP_CAP = 1 << 19, - IBV_QP_DEST_QPN = 1 << 20, + IBV_QP_STATE = 1 << 0, + IBV_QP_CUR_STATE = 1 << 1, + IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2, + IBV_QP_ACCESS_FLAGS = 1 << 3, + IBV_QP_PKEY_INDEX = 1 << 4, + IBV_QP_PORT = 1 << 5, + IBV_QP_QKEY = 1 << 6, + IBV_QP_AV = 1 << 7, + IBV_QP_PATH_MTU = 1 << 8, + IBV_QP_TIMEOUT = 1 << 9, + IBV_QP_RETRY_CNT = 1 << 10, + IBV_QP_RNR_RETRY = 1 << 11, + IBV_QP_RQ_PSN = 1 << 12, + IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13, + IBV_QP_ALT_PATH = 1 << 14, + IBV_QP_MIN_RNR_TIMER = 1 << 15, + IBV_QP_SQ_PSN = 1 << 16, + IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17, + IBV_QP_PATH_MIG_STATE = 1 << 18, + IBV_QP_CAP = 1 << 19, + IBV_QP_DEST_QPN = 1 << 20, /* These bits were supported on older kernels, but never exposed from libibverbs: _IBV_QP_SMAC = 1 << 21, @@ -1061,7 +1035,7 @@ enum ibv_qp_attr_mask { _IBV_QP_VID = 1 << 23, _IBV_QP_ALT_VID = 1 << 24, */ - IBV_QP_RATE_LIMIT = 1 << 25, + IBV_QP_RATE_LIMIT = 1 << 25, }; enum ibv_query_qp_data_in_order_flags { @@ -1085,46 +1059,42 @@ enum ibv_qp_state { IBV_QPS_UNKNOWN }; -enum ibv_mig_state { - IBV_MIG_MIGRATED, - IBV_MIG_REARM, - IBV_MIG_ARMED -}; +enum ibv_mig_state { IBV_MIG_MIGRATED, IBV_MIG_REARM, IBV_MIG_ARMED }; struct ibv_qp_attr { - enum ibv_qp_state qp_state; - enum ibv_qp_state cur_qp_state; - enum ibv_mtu path_mtu; - enum ibv_mig_state path_mig_state; - uint32_t qkey; - uint32_t rq_psn; - uint32_t sq_psn; - uint32_t dest_qp_num; - unsigned int qp_access_flags; - struct ibv_qp_cap cap; - struct ibv_ah_attr ah_attr; - struct ibv_ah_attr alt_ah_attr; - uint16_t pkey_index; - uint16_t alt_pkey_index; - uint8_t en_sqd_async_notify; - uint8_t sq_draining; - uint8_t max_rd_atomic; - uint8_t max_dest_rd_atomic; - uint8_t min_rnr_timer; - uint8_t port_num; - uint8_t timeout; - uint8_t retry_cnt; - uint8_t rnr_retry; - uint8_t alt_port_num; - uint8_t alt_timeout; - uint32_t rate_limit; + enum ibv_qp_state qp_state; + enum ibv_qp_state cur_qp_state; + enum ibv_mtu path_mtu; + enum ibv_mig_state path_mig_state; + uint32_t qkey; + uint32_t rq_psn; + uint32_t sq_psn; + uint32_t dest_qp_num; + unsigned int qp_access_flags; + struct ibv_qp_cap cap; + struct ibv_ah_attr ah_attr; + struct ibv_ah_attr alt_ah_attr; + uint16_t pkey_index; + uint16_t alt_pkey_index; + uint8_t en_sqd_async_notify; + uint8_t sq_draining; + uint8_t max_rd_atomic; + uint8_t max_dest_rd_atomic; + uint8_t min_rnr_timer; + uint8_t port_num; + uint8_t timeout; + uint8_t retry_cnt; + uint8_t rnr_retry; + uint8_t alt_port_num; + uint8_t alt_timeout; + uint32_t rate_limit; }; struct ibv_qp_rate_limit_attr { - uint32_t rate_limit; /* in kbps */ - uint32_t max_burst_sz; /* total burst size in bytes */ - uint16_t typical_pkt_sz; /* typical send packet size in bytes */ - uint32_t comp_mask; + uint32_t rate_limit; /* in kbps */ + uint32_t max_burst_sz; /* total burst size in bytes */ + uint16_t typical_pkt_sz; /* typical send packet size in bytes */ + uint32_t comp_mask; }; enum ibv_wr_opcode { @@ -1147,11 +1117,11 @@ enum ibv_wr_opcode { const char *ibv_wr_opcode_str(enum ibv_wr_opcode opcode); enum ibv_send_flags { - IBV_SEND_FENCE = 1 << 0, - IBV_SEND_SIGNALED = 1 << 1, - IBV_SEND_SOLICITED = 1 << 2, - IBV_SEND_INLINE = 1 << 3, - IBV_SEND_IP_CSUM = 1 << 4 + IBV_SEND_FENCE = 1 << 0, + IBV_SEND_SIGNALED = 1 << 1, + IBV_SEND_SOLICITED = 1 << 2, + IBV_SEND_INLINE = 1 << 3, + IBV_SEND_IP_CSUM = 1 << 4 }; enum ibv_placement_type { @@ -1170,9 +1140,9 @@ struct ibv_data_buf { }; struct ibv_sge { - uint64_t addr; - uint32_t length; - uint32_t lkey; + uint64_t addr; + uint32_t length; + uint32_t lkey; }; struct ibv_fd_arr { @@ -1181,60 +1151,60 @@ struct ibv_fd_arr { }; struct ibv_send_wr { - uint64_t wr_id; - struct ibv_send_wr *next; - struct ibv_sge *sg_list; - int num_sge; - enum ibv_wr_opcode opcode; - unsigned int send_flags; + uint64_t wr_id; + struct ibv_send_wr *next; + struct ibv_sge *sg_list; + int num_sge; + enum ibv_wr_opcode opcode; + unsigned int send_flags; /* When opcode is *_WITH_IMM: Immediate data in network byte order. * When opcode is *_INV: Stores the rkey to invalidate */ union { - __be32 imm_data; - uint32_t invalidate_rkey; + __be32 imm_data; + uint32_t invalidate_rkey; }; union { struct { - uint64_t remote_addr; - uint32_t rkey; + uint64_t remote_addr; + uint32_t rkey; } rdma; struct { - uint64_t remote_addr; - uint64_t compare_add; - uint64_t swap; - uint32_t rkey; + uint64_t remote_addr; + uint64_t compare_add; + uint64_t swap; + uint32_t rkey; } atomic; struct { - struct ibv_ah *ah; - uint32_t remote_qpn; - uint32_t remote_qkey; + struct ibv_ah *ah; + uint32_t remote_qpn; + uint32_t remote_qkey; } ud; } wr; union { struct { - uint32_t remote_srqn; + uint32_t remote_srqn; } xrc; } qp_type; union { struct { - struct ibv_mw *mw; - uint32_t rkey; - struct ibv_mw_bind_info bind_info; + struct ibv_mw *mw; + uint32_t rkey; + struct ibv_mw_bind_info bind_info; } bind_mw; struct { - void *hdr; - uint16_t hdr_sz; - uint16_t mss; + void *hdr; + uint16_t hdr_sz; + uint16_t mss; } tso; }; }; struct ibv_recv_wr { - uint64_t wr_id; - struct ibv_recv_wr *next; - struct ibv_sge *sg_list; - int num_sge; + uint64_t wr_id; + struct ibv_recv_wr *next; + struct ibv_sge *sg_list; + int num_sge; }; enum ibv_ops_wr_opcode { @@ -1245,42 +1215,42 @@ enum ibv_ops_wr_opcode { enum ibv_ops_flags { IBV_OPS_SIGNALED = 1 << 0, - IBV_OPS_TM_SYNC = 1 << 1, + IBV_OPS_TM_SYNC = 1 << 1, }; struct ibv_ops_wr { - uint64_t wr_id; - struct ibv_ops_wr *next; - enum ibv_ops_wr_opcode opcode; - int flags; + uint64_t wr_id; + struct ibv_ops_wr *next; + enum ibv_ops_wr_opcode opcode; + int flags; struct { - uint32_t unexpected_cnt; - uint32_t handle; + uint32_t unexpected_cnt; + uint32_t handle; struct { - uint64_t recv_wr_id; - struct ibv_sge *sg_list; - int num_sge; - uint64_t tag; - uint64_t mask; + uint64_t recv_wr_id; + struct ibv_sge *sg_list; + int num_sge; + uint64_t tag; + uint64_t mask; } add; } tm; }; struct ibv_mw_bind { - uint64_t wr_id; - unsigned int send_flags; + uint64_t wr_id; + unsigned int send_flags; struct ibv_mw_bind_info bind_info; }; struct ibv_srq { - struct ibv_context *context; - void *srq_context; - struct ibv_pd *pd; - uint32_t handle; + struct ibv_context *context; + void *srq_context; + struct ibv_pd *pd; + uint32_t handle; - pthread_mutex_t mutex; - pthread_cond_t cond; - uint32_t events_completed; + pthread_mutex_t mutex; + pthread_cond_t cond; + uint32_t events_completed; }; /* @@ -1295,38 +1265,37 @@ struct ibv_srq { * requests (WRs) to its receive queue. */ struct ibv_wq { - struct ibv_context *context; - void *wq_context; - struct ibv_pd *pd; - struct ibv_cq *cq; - uint32_t wq_num; - uint32_t handle; - enum ibv_wq_state state; - enum ibv_wq_type wq_type; - int (*post_recv)(struct ibv_wq *current, - struct ibv_recv_wr *recv_wr, + struct ibv_context *context; + void *wq_context; + struct ibv_pd *pd; + struct ibv_cq *cq; + uint32_t wq_num; + uint32_t handle; + enum ibv_wq_state state; + enum ibv_wq_type wq_type; + int (*post_recv)(struct ibv_wq *current, struct ibv_recv_wr *recv_wr, struct ibv_recv_wr **bad_recv_wr); - pthread_mutex_t mutex; - pthread_cond_t cond; - uint32_t events_completed; - uint32_t comp_mask; + pthread_mutex_t mutex; + pthread_cond_t cond; + uint32_t events_completed; + uint32_t comp_mask; }; struct ibv_qp { - struct ibv_context *context; - void *qp_context; - struct ibv_pd *pd; - struct ibv_cq *send_cq; - struct ibv_cq *recv_cq; - struct ibv_srq *srq; - uint32_t handle; - uint32_t qp_num; - enum ibv_qp_state state; - enum ibv_qp_type qp_type; - - pthread_mutex_t mutex; - pthread_cond_t cond; - uint32_t events_completed; + struct ibv_context *context; + void *qp_context; + struct ibv_pd *pd; + struct ibv_cq *send_cq; + struct ibv_cq *recv_cq; + struct ibv_srq *srq; + uint32_t handle; + uint32_t qp_num; + enum ibv_qp_state state; + enum ibv_qp_type qp_type; + + pthread_mutex_t mutex; + pthread_cond_t cond; + uint32_t events_completed; }; struct ibv_qp_ex { @@ -1476,9 +1445,9 @@ static inline void ibv_wr_set_inline_data(struct ibv_qp_ex *qp, void *addr, qp->wr_set_inline_data(qp, addr, length); } -static inline void ibv_wr_set_inline_data_list(struct ibv_qp_ex *qp, - size_t num_buf, - const struct ibv_data_buf *buf_list) +static inline void +ibv_wr_set_inline_data_list(struct ibv_qp_ex *qp, size_t num_buf, + const struct ibv_data_buf *buf_list) { qp->wr_set_inline_data_list(qp, num_buf, buf_list); } @@ -1511,7 +1480,8 @@ static inline void ibv_wr_abort(struct ibv_qp_ex *qp) } static inline void ibv_wr_atomic_write(struct ibv_qp_ex *qp, uint32_t rkey, - uint64_t remote_addr, const void *atomic_wr) + uint64_t remote_addr, + const void *atomic_wr) { qp->wr_atomic_write(qp, rkey, remote_addr, atomic_wr); } @@ -1532,22 +1502,22 @@ struct ibv_ece { }; struct ibv_comp_channel { - struct ibv_context *context; - int fd; - int refcnt; + struct ibv_context *context; + int fd; + int refcnt; }; struct ibv_cq { - struct ibv_context *context; + struct ibv_context *context; struct ibv_comp_channel *channel; - void *cq_context; - uint32_t handle; - int cqe; + void *cq_context; + uint32_t handle; + int cqe; - pthread_mutex_t mutex; - pthread_cond_t cond; - uint32_t comp_events_completed; - uint32_t async_events_completed; + pthread_mutex_t mutex; + pthread_cond_t cond; + uint32_t comp_events_completed; + uint32_t async_events_completed; }; struct ibv_poll_cq_attr { @@ -1555,27 +1525,27 @@ struct ibv_poll_cq_attr { }; struct ibv_wc_tm_info { - uint64_t tag; /* tag from TMH */ - uint32_t priv; /* opaque user data from TMH */ + uint64_t tag; /* tag from TMH */ + uint32_t priv; /* opaque user data from TMH */ }; struct ibv_cq_ex { - struct ibv_context *context; + struct ibv_context *context; struct ibv_comp_channel *channel; - void *cq_context; - uint32_t handle; - int cqe; + void *cq_context; + uint32_t handle; + int cqe; - pthread_mutex_t mutex; - pthread_cond_t cond; - uint32_t comp_events_completed; - uint32_t async_events_completed; + pthread_mutex_t mutex; + pthread_cond_t cond; + uint32_t comp_events_completed; + uint32_t async_events_completed; - uint32_t comp_mask; + uint32_t comp_mask; enum ibv_wc_status status; uint64_t wr_id; int (*start_poll)(struct ibv_cq_ex *current, - struct ibv_poll_cq_attr *attr); + struct ibv_poll_cq_attr *attr); int (*next_poll)(struct ibv_cq_ex *current); void (*end_poll)(struct ibv_cq_ex *current); enum ibv_wc_opcode (*read_opcode)(struct ibv_cq_ex *current); @@ -1617,7 +1587,7 @@ struct ibv_modify_cq_attr { }; static inline int ibv_start_poll(struct ibv_cq_ex *cq, - struct ibv_poll_cq_attr *attr) + struct ibv_poll_cq_attr *attr) { return cq->start_poll(cq, attr); } @@ -1725,9 +1695,9 @@ static inline int ibv_post_wq_recv(struct ibv_wq *wq, } struct ibv_ah { - struct ibv_context *context; - struct ibv_pd *pd; - uint32_t handle; + struct ibv_context *context; + struct ibv_pd *pd; + uint32_t handle; }; enum ibv_flow_flags { @@ -1738,51 +1708,51 @@ enum ibv_flow_flags { enum ibv_flow_attr_type { /* steering according to rule specifications */ - IBV_FLOW_ATTR_NORMAL = 0x0, + IBV_FLOW_ATTR_NORMAL = 0x0, /* default unicast and multicast rule - * receive all Eth traffic which isn't steered to any QP */ - IBV_FLOW_ATTR_ALL_DEFAULT = 0x1, + IBV_FLOW_ATTR_ALL_DEFAULT = 0x1, /* default multicast rule - * receive all Eth multicast traffic which isn't steered to any QP */ - IBV_FLOW_ATTR_MC_DEFAULT = 0x2, + IBV_FLOW_ATTR_MC_DEFAULT = 0x2, /* sniffer rule - receive all port traffic */ - IBV_FLOW_ATTR_SNIFFER = 0x3, + IBV_FLOW_ATTR_SNIFFER = 0x3, }; enum ibv_flow_spec_type { - IBV_FLOW_SPEC_ETH = 0x20, - IBV_FLOW_SPEC_IPV4 = 0x30, - IBV_FLOW_SPEC_IPV6 = 0x31, - IBV_FLOW_SPEC_IPV4_EXT = 0x32, - IBV_FLOW_SPEC_ESP = 0x34, - IBV_FLOW_SPEC_TCP = 0x40, - IBV_FLOW_SPEC_UDP = 0x41, - IBV_FLOW_SPEC_VXLAN_TUNNEL = 0x50, - IBV_FLOW_SPEC_GRE = 0x51, - IBV_FLOW_SPEC_MPLS = 0x60, - IBV_FLOW_SPEC_INNER = 0x100, - IBV_FLOW_SPEC_ACTION_TAG = 0x1000, - IBV_FLOW_SPEC_ACTION_DROP = 0x1001, - IBV_FLOW_SPEC_ACTION_HANDLE = 0x1002, - IBV_FLOW_SPEC_ACTION_COUNT = 0x1003, + IBV_FLOW_SPEC_ETH = 0x20, + IBV_FLOW_SPEC_IPV4 = 0x30, + IBV_FLOW_SPEC_IPV6 = 0x31, + IBV_FLOW_SPEC_IPV4_EXT = 0x32, + IBV_FLOW_SPEC_ESP = 0x34, + IBV_FLOW_SPEC_TCP = 0x40, + IBV_FLOW_SPEC_UDP = 0x41, + IBV_FLOW_SPEC_VXLAN_TUNNEL = 0x50, + IBV_FLOW_SPEC_GRE = 0x51, + IBV_FLOW_SPEC_MPLS = 0x60, + IBV_FLOW_SPEC_INNER = 0x100, + IBV_FLOW_SPEC_ACTION_TAG = 0x1000, + IBV_FLOW_SPEC_ACTION_DROP = 0x1001, + IBV_FLOW_SPEC_ACTION_HANDLE = 0x1002, + IBV_FLOW_SPEC_ACTION_COUNT = 0x1003, }; #define ETHERNET_LL_SIZE ETH_ALEN struct ibv_flow_eth_filter { - uint8_t dst_mac[ETHERNET_LL_SIZE]; - uint8_t src_mac[ETHERNET_LL_SIZE]; - uint16_t ether_type; + uint8_t dst_mac[ETHERNET_LL_SIZE]; + uint8_t src_mac[ETHERNET_LL_SIZE]; + uint16_t ether_type; /* * same layout as 802.1q: prio 3, cfi 1, vlan id 12 */ - uint16_t vlan_tag; + uint16_t vlan_tag; }; struct ibv_flow_spec_eth { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_eth_filter val; struct ibv_flow_eth_filter mask; }; @@ -1793,8 +1763,8 @@ struct ibv_flow_ipv4_filter { }; struct ibv_flow_spec_ipv4 { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_ipv4_filter val; struct ibv_flow_ipv4_filter mask; }; @@ -1802,31 +1772,31 @@ struct ibv_flow_spec_ipv4 { struct ibv_flow_ipv4_ext_filter { uint32_t src_ip; uint32_t dst_ip; - uint8_t proto; - uint8_t tos; - uint8_t ttl; - uint8_t flags; + uint8_t proto; + uint8_t tos; + uint8_t ttl; + uint8_t flags; }; struct ibv_flow_spec_ipv4_ext { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_ipv4_ext_filter val; struct ibv_flow_ipv4_ext_filter mask; }; struct ibv_flow_ipv6_filter { - uint8_t src_ip[16]; - uint8_t dst_ip[16]; + uint8_t src_ip[16]; + uint8_t dst_ip[16]; uint32_t flow_label; - uint8_t next_hdr; - uint8_t traffic_class; - uint8_t hop_limit; + uint8_t next_hdr; + uint8_t traffic_class; + uint8_t hop_limit; }; struct ibv_flow_spec_ipv6 { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_ipv6_filter val; struct ibv_flow_ipv6_filter mask; }; @@ -1849,8 +1819,8 @@ struct ibv_flow_tcp_udp_filter { }; struct ibv_flow_spec_tcp_udp { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_tcp_udp_filter val; struct ibv_flow_tcp_udp_filter mask; }; @@ -1870,8 +1840,8 @@ struct ibv_flow_gre_filter { }; struct ibv_flow_spec_gre { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_gre_filter val; struct ibv_flow_gre_filter mask; }; @@ -1887,8 +1857,8 @@ struct ibv_flow_mpls_filter { }; struct ibv_flow_spec_mpls { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_mpls_filter val; struct ibv_flow_mpls_filter mask; }; @@ -1898,40 +1868,40 @@ struct ibv_flow_tunnel_filter { }; struct ibv_flow_spec_tunnel { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_flow_tunnel_filter val; struct ibv_flow_tunnel_filter mask; }; struct ibv_flow_spec_action_tag { - enum ibv_flow_spec_type type; - uint16_t size; - uint32_t tag_id; + enum ibv_flow_spec_type type; + uint16_t size; + uint32_t tag_id; }; struct ibv_flow_spec_action_drop { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; }; struct ibv_flow_spec_action_handle { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; const struct ibv_flow_action *action; }; struct ibv_flow_spec_counter_action { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; struct ibv_counters *counters; }; struct ibv_flow_spec { union { struct { - enum ibv_flow_spec_type type; - uint16_t size; + enum ibv_flow_spec_type type; + uint16_t size; } hdr; struct ibv_flow_spec_eth eth; struct ibv_flow_spec_ipv4 ipv4; @@ -1964,9 +1934,9 @@ struct ibv_flow_attr { }; struct ibv_flow { - uint32_t comp_mask; + uint32_t comp_mask; struct ibv_context *context; - uint32_t handle; + uint32_t handle; }; struct ibv_flow_action { @@ -1974,24 +1944,24 @@ struct ibv_flow_action { }; enum ibv_flow_action_esp_mask { - IBV_FLOW_ACTION_ESP_MASK_ESN = 1UL << 0, + IBV_FLOW_ACTION_ESP_MASK_ESN = 1UL << 0, }; struct ibv_flow_action_esp_attr { struct ibv_flow_action_esp *esp_attr; - enum ibv_flow_action_esp_keymat keymat_proto; - uint16_t keymat_len; - void *keymat_ptr; + enum ibv_flow_action_esp_keymat keymat_proto; + uint16_t keymat_len; + void *keymat_ptr; enum ibv_flow_action_esp_replay replay_proto; - uint16_t replay_len; - void *replay_ptr; + uint16_t replay_len; + void *replay_ptr; struct ibv_flow_action_esp_encap *esp_encap; - uint32_t comp_mask; /* Use enum ibv_flow_action_esp_mask */ - uint32_t esn; + uint32_t comp_mask; /* Use enum ibv_flow_action_esp_mask */ + uint32_t esn; }; struct ibv_device; @@ -1999,48 +1969,44 @@ struct ibv_context; /* Obsolete, never used, do not touch */ struct _ibv_device_ops { - struct ibv_context * (*_dummy1)(struct ibv_device *device, int cmd_fd); - void (*_dummy2)(struct ibv_context *context); + struct ibv_context *(*_dummy1)(struct ibv_device *device, int cmd_fd); + void (*_dummy2)(struct ibv_context *context); }; -enum { - IBV_SYSFS_NAME_MAX = 64, - IBV_SYSFS_PATH_MAX = 256 -}; +enum { IBV_SYSFS_NAME_MAX = 64, IBV_SYSFS_PATH_MAX = 256 }; struct ibv_device { - struct _ibv_device_ops _ops; - enum ibv_node_type node_type; - enum ibv_transport_type transport_type; + struct _ibv_device_ops _ops; + enum ibv_node_type node_type; + enum ibv_transport_type transport_type; /* Name of underlying kernel IB device, eg "mthca0" */ - char name[IBV_SYSFS_NAME_MAX]; + char name[IBV_SYSFS_NAME_MAX]; /* Name of uverbs device, eg "uverbs0" */ - char dev_name[IBV_SYSFS_NAME_MAX]; + char dev_name[IBV_SYSFS_NAME_MAX]; /* Path to infiniband_verbs class device in sysfs */ - char dev_path[IBV_SYSFS_PATH_MAX]; + char dev_path[IBV_SYSFS_PATH_MAX]; /* Path to infiniband class device in sysfs */ - char ibdev_path[IBV_SYSFS_PATH_MAX]; + char ibdev_path[IBV_SYSFS_PATH_MAX]; }; struct _compat_ibv_port_attr; struct ibv_context_ops { int (*_compat_query_device)(struct ibv_context *context, struct ibv_device_attr *device_attr); - int (*_compat_query_port)(struct ibv_context *context, - uint8_t port_num, + int (*_compat_query_port)(struct ibv_context *context, uint8_t port_num, struct _compat_ibv_port_attr *port_attr); void *(*_compat_alloc_pd)(void); void *(*_compat_dealloc_pd)(void); void *(*_compat_reg_mr)(void); void *(*_compat_rereg_mr)(void); void *(*_compat_dereg_mr)(void); - struct ibv_mw * (*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); - int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, - struct ibv_mw_bind *mw_bind); - int (*dealloc_mw)(struct ibv_mw *mw); + struct ibv_mw *(*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); + int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, + struct ibv_mw_bind *mw_bind); + int (*dealloc_mw)(struct ibv_mw *mw); void *(*_compat_create_cq)(void); - int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); - int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); + int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); + int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); void *(*_compat_cq_event)(void); void *(*_compat_resize_cq)(void); void *(*_compat_destroy_cq)(void); @@ -2048,17 +2014,16 @@ struct ibv_context_ops { void *(*_compat_modify_srq)(void); void *(*_compat_query_srq)(void); void *(*_compat_destroy_srq)(void); - int (*post_srq_recv)(struct ibv_srq *srq, - struct ibv_recv_wr *recv_wr, - struct ibv_recv_wr **bad_recv_wr); + int (*post_srq_recv)(struct ibv_srq *srq, struct ibv_recv_wr *recv_wr, + struct ibv_recv_wr **bad_recv_wr); void *(*_compat_create_qp)(void); void *(*_compat_query_qp)(void); void *(*_compat_modify_qp)(void); void *(*_compat_destroy_qp)(void); - int (*post_send)(struct ibv_qp *qp, struct ibv_send_wr *wr, - struct ibv_send_wr **bad_wr); - int (*post_recv)(struct ibv_qp *qp, struct ibv_recv_wr *wr, - struct ibv_recv_wr **bad_wr); + int (*post_send)(struct ibv_qp *qp, struct ibv_send_wr *wr, + struct ibv_send_wr **bad_wr); + int (*post_recv)(struct ibv_qp *qp, struct ibv_recv_wr *wr, + struct ibv_recv_wr **bad_wr); void *(*_compat_create_ah)(void); void *(*_compat_destroy_ah)(void); void *(*_compat_attach_mcast)(void); @@ -2067,30 +2032,30 @@ struct ibv_context_ops { }; struct ibv_context { - struct ibv_device *device; - struct ibv_context_ops ops; - int cmd_fd; - int async_fd; - int num_comp_vectors; - pthread_mutex_t mutex; - void *abi_compat; + struct ibv_device *device; + struct ibv_context_ops ops; + int cmd_fd; + int async_fd; + int num_comp_vectors; + pthread_mutex_t mutex; + void *abi_compat; }; enum ibv_cq_init_attr_mask { - IBV_CQ_INIT_ATTR_MASK_FLAGS = 1 << 0, - IBV_CQ_INIT_ATTR_MASK_PD = 1 << 1, + IBV_CQ_INIT_ATTR_MASK_FLAGS = 1 << 0, + IBV_CQ_INIT_ATTR_MASK_PD = 1 << 1, }; enum ibv_create_cq_attr_flags { IBV_CREATE_CQ_ATTR_SINGLE_THREADED = 1 << 0, - IBV_CREATE_CQ_ATTR_IGNORE_OVERRUN = 1 << 1, + IBV_CREATE_CQ_ATTR_IGNORE_OVERRUN = 1 << 1, }; struct ibv_cq_init_attr_ex { /* Minimum number of entries required for CQ */ - uint32_t cqe; + uint32_t cqe; /* Consumer-supplied context returned for completion events */ - void *cq_context; + void *cq_context; /* Completion channel where completion events will be queued. * May be NULL if completion events will not be used. */ @@ -2098,18 +2063,18 @@ struct ibv_cq_init_attr_ex { /* Completion vector used to signal completion events. * Must be < context->num_comp_vectors. */ - uint32_t comp_vector; - /* Or'ed bit of enum ibv_create_cq_wc_flags. */ - uint64_t wc_flags; + uint32_t comp_vector; + /* Or'ed bit of enum ibv_create_cq_wc_flags. */ + uint64_t wc_flags; /* compatibility mask (extended verb). Or'd flags of * enum ibv_cq_init_attr_mask */ - uint32_t comp_mask; + uint32_t comp_mask; /* create cq attr flags - one or more flags from * enum ibv_create_cq_attr_flags */ - uint32_t flags; - struct ibv_pd *parent_domain; + uint32_t flags; + struct ibv_pd *parent_domain; }; enum ibv_parent_domain_init_attr_mask { @@ -2120,7 +2085,8 @@ enum ibv_parent_domain_init_attr_mask { #define IBV_ALLOCATOR_USE_DEFAULT ((void *)-1) struct ibv_parent_domain_init_attr { - struct ibv_pd *pd; /* reference to a protection domain object, can't be NULL */ + struct ibv_pd * + pd; /* reference to a protection domain object, can't be NULL */ struct ibv_td *td; /* reference to a thread domain object, or NULL */ uint32_t comp_mask; void *(*alloc)(struct ibv_pd *pd, void *pd_context, size_t size, @@ -2135,7 +2101,7 @@ enum ibv_tph_mem_type { IBV_TPH_MEM_TYPE_PM, /* persistent memory */ }; -enum ibv_dmah_init_attr_mask { +enum ibv_dmah_init_attr_mask { IBV_DMAH_INIT_ATTR_MASK_CPU_ID = 1 << 0, IBV_DMAH_INIT_ATTR_MASK_PH = 1 << 1, IBV_DMAH_INIT_ATTR_MASK_TPH_MEM_TYPE = 1 << 2, @@ -2149,11 +2115,11 @@ struct ibv_dmah_init_attr { }; struct ibv_counters_init_attr { - uint32_t comp_mask; + uint32_t comp_mask; }; struct ibv_counters { - struct ibv_context *context; + struct ibv_context *context; }; enum ibv_counter_description { @@ -2172,12 +2138,12 @@ enum ibv_read_counters_flags { }; enum ibv_values_mask { - IBV_VALUES_MASK_RAW_CLOCK = 1 << 0, - IBV_VALUES_MASK_RESERVED = 1 << 1 + IBV_VALUES_MASK_RAW_CLOCK = 1 << 0, + IBV_VALUES_MASK_RESERVED = 1 << 1 }; struct ibv_values_ex { - uint32_t comp_mask; + uint32_t comp_mask; struct timespec raw_clock; }; @@ -2192,21 +2158,19 @@ struct verbs_context { int (*query_port)(struct ibv_context *context, uint8_t port_num, struct ibv_port_attr *port_attr, size_t port_attr_len); - int (*advise_mr)(struct ibv_pd *pd, - enum ibv_advise_mr_advice advice, - uint32_t flags, - struct ibv_sge *sg_list, + int (*advise_mr)(struct ibv_pd *pd, enum ibv_advise_mr_advice advice, + uint32_t flags, struct ibv_sge *sg_list, uint32_t num_sges); struct ibv_mr *(*alloc_null_mr)(struct ibv_pd *pd); int (*read_counters)(struct ibv_counters *counters, - uint64_t *counters_value, - uint32_t ncounters, + uint64_t *counters_value, uint32_t ncounters, uint32_t flags); int (*attach_counters_point_flow)(struct ibv_counters *counters, struct ibv_counter_attach_attr *attr, struct ibv_flow *flow); - struct ibv_counters *(*create_counters)(struct ibv_context *context, - struct ibv_counters_init_attr *init_attr); + struct ibv_counters *(*create_counters)( + struct ibv_context *context, + struct ibv_counters_init_attr *init_attr); int (*destroy_counters)(struct ibv_counters *counters); struct ibv_mr *(*reg_dm_mr)(struct ibv_pd *pd, struct ibv_dm *dm, uint64_t dm_offset, size_t length, @@ -2217,25 +2181,28 @@ struct verbs_context { int (*modify_flow_action_esp)(struct ibv_flow_action *action, struct ibv_flow_action_esp_attr *attr); int (*destroy_flow_action)(struct ibv_flow_action *action); - struct ibv_flow_action *(*create_flow_action_esp)(struct ibv_context *context, - struct ibv_flow_action_esp_attr *attr); + struct ibv_flow_action *(*create_flow_action_esp)( + struct ibv_context *context, + struct ibv_flow_action_esp_attr *attr); int (*modify_qp_rate_limit)(struct ibv_qp *qp, struct ibv_qp_rate_limit_attr *attr); - struct ibv_pd *(*alloc_parent_domain)(struct ibv_context *context, - struct ibv_parent_domain_init_attr *attr); + struct ibv_pd *(*alloc_parent_domain)( + struct ibv_context *context, + struct ibv_parent_domain_init_attr *attr); int (*dealloc_td)(struct ibv_td *td); - struct ibv_td *(*alloc_td)(struct ibv_context *context, struct ibv_td_init_attr *init_attr); + struct ibv_td *(*alloc_td)(struct ibv_context *context, + struct ibv_td_init_attr *init_attr); int (*modify_cq)(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr); - int (*post_srq_ops)(struct ibv_srq *srq, - struct ibv_ops_wr *op, + int (*post_srq_ops)(struct ibv_srq *srq, struct ibv_ops_wr *op, struct ibv_ops_wr **bad_op); int (*destroy_rwq_ind_table)(struct ibv_rwq_ind_table *rwq_ind_table); - struct ibv_rwq_ind_table *(*create_rwq_ind_table)(struct ibv_context *context, - struct ibv_rwq_ind_table_init_attr *init_attr); + struct ibv_rwq_ind_table *(*create_rwq_ind_table)( + struct ibv_context *context, + struct ibv_rwq_ind_table_init_attr *init_attr); int (*destroy_wq)(struct ibv_wq *wq); int (*modify_wq)(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr); - struct ibv_wq * (*create_wq)(struct ibv_context *context, - struct ibv_wq_init_attr *wq_init_attr); + struct ibv_wq *(*create_wq)(struct ibv_context *context, + struct ibv_wq_init_attr *wq_init_attr); int (*query_rt_values)(struct ibv_context *context, struct ibv_values_ex *values); struct ibv_cq_ex *(*create_cq_ex)(struct ibv_context *context, @@ -2245,24 +2212,26 @@ struct verbs_context { const struct ibv_query_device_ex_input *input, struct ibv_device_attr_ex *attr, size_t attr_size); - int (*ibv_destroy_flow) (struct ibv_flow *flow); - void (*ABI_placeholder2) (void); /* DO NOT COPY THIS GARBAGE */ - struct ibv_flow * (*ibv_create_flow) (struct ibv_qp *qp, - struct ibv_flow_attr *flow_attr); - void (*ABI_placeholder1) (void); /* DO NOT COPY THIS GARBAGE */ + int (*ibv_destroy_flow)(struct ibv_flow *flow); + void (*ABI_placeholder2)(void); /* DO NOT COPY THIS GARBAGE */ + struct ibv_flow *(*ibv_create_flow)(struct ibv_qp *qp, + struct ibv_flow_attr *flow_attr); + void (*ABI_placeholder1)(void); /* DO NOT COPY THIS GARBAGE */ struct ibv_qp *(*open_qp)(struct ibv_context *context, - struct ibv_qp_open_attr *attr); - struct ibv_qp *(*create_qp_ex)(struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex); + struct ibv_qp_open_attr *attr); + struct ibv_qp *(*create_qp_ex)( + struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex); int (*get_srq_num)(struct ibv_srq *srq, uint32_t *srq_num); - struct ibv_srq * (*create_srq_ex)(struct ibv_context *context, - struct ibv_srq_init_attr_ex *srq_init_attr_ex); - struct ibv_xrcd * (*open_xrcd)(struct ibv_context *context, - struct ibv_xrcd_init_attr *xrcd_init_attr); - int (*close_xrcd)(struct ibv_xrcd *xrcd); + struct ibv_srq *(*create_srq_ex)( + struct ibv_context *context, + struct ibv_srq_init_attr_ex *srq_init_attr_ex); + struct ibv_xrcd *(*open_xrcd)(struct ibv_context *context, + struct ibv_xrcd_init_attr *xrcd_init_attr); + int (*close_xrcd)(struct ibv_xrcd *xrcd); uint64_t _ABI_placeholder3; - size_t sz; /* Must be immediately before struct ibv_context */ - struct ibv_context context; /* Must be last field in the struct */ + size_t sz; /* Must be immediately before struct ibv_context */ + struct ibv_context context; /* Must be last field in the struct */ }; static inline struct verbs_context *verbs_get_ctx(struct ibv_context *ctx) @@ -2276,10 +2245,16 @@ static inline struct verbs_context *verbs_get_ctx(struct ibv_context *ctx) context)); } -#define verbs_get_ctx_op(ctx, op) ({ \ - struct verbs_context *__vctx = verbs_get_ctx(ctx); \ - (!__vctx || (__vctx->sz < sizeof(*__vctx) - offsetof(struct verbs_context, op)) || \ - !__vctx->op) ? NULL : __vctx; }) +#define verbs_get_ctx_op(ctx, op) \ + ({ \ + struct verbs_context *__vctx = verbs_get_ctx(ctx); \ + (!__vctx || \ + (__vctx->sz < \ + sizeof(*__vctx) - offsetof(struct verbs_context, op)) || \ + !__vctx->op) ? \ + NULL : \ + __vctx; \ + }) /** * ibv_get_device_list - Get list of IB devices currently available @@ -2322,6 +2297,7 @@ extern const struct verbs_device_ops verbs_provider_cxgb4; extern const struct verbs_device_ops verbs_provider_efa; extern const struct verbs_device_ops verbs_provider_erdma; extern const struct verbs_device_ops verbs_provider_hfi1verbs; +extern const struct verbs_device_ops verbs_provider_hfi2verbs; extern const struct verbs_device_ops verbs_provider_hns; extern const struct verbs_device_ops verbs_provider_ipathverbs; extern const struct verbs_device_ops verbs_provider_irdma; @@ -2395,8 +2371,7 @@ struct ibv_context *ibv_import_device(int cmd_fd); /** * ibv_import_pd - Import a protection domain */ -struct ibv_pd *ibv_import_pd(struct ibv_context *context, - uint32_t pd_handle); +struct ibv_pd *ibv_import_pd(struct ibv_context *context, uint32_t pd_handle); /** * ibv_unimport_pd - Unimport a protection domain @@ -2483,18 +2458,18 @@ static inline int ___ibv_query_port(struct ibv_context *context, sizeof(*port_attr)); } -#define ibv_query_port(context, port_num, port_attr) \ +#define ibv_query_port(context, port_num, port_attr) \ ___ibv_query_port(context, port_num, port_attr) /** * ibv_query_gid - Get a GID table entry */ -int ibv_query_gid(struct ibv_context *context, uint8_t port_num, - int index, union ibv_gid *gid); +int ibv_query_gid(struct ibv_context *context, uint8_t port_num, int index, + union ibv_gid *gid); int _ibv_query_gid_ex(struct ibv_context *context, uint32_t port_num, - uint32_t gid_index, struct ibv_gid_entry *entry, - uint32_t flags, size_t entry_size); + uint32_t gid_index, struct ibv_gid_entry *entry, + uint32_t flags, size_t entry_size); /** * ibv_query_gid_ex - Read a GID table entry @@ -2525,8 +2500,8 @@ static inline ssize_t ibv_query_gid_table(struct ibv_context *context, /** * ibv_query_pkey - Get a P_Key table entry */ -int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, - int index, __be16 *pkey); +int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, int index, + __be16 *pkey); /** * ibv_get_pkey_index - Translate a P_Key into a P_Key index @@ -2547,8 +2522,8 @@ int ibv_dealloc_pd(struct ibv_pd *pd); static inline struct ibv_flow *ibv_create_flow(struct ibv_qp *qp, struct ibv_flow_attr *flow) { - struct verbs_context *vctx = verbs_get_ctx_op(qp->context, - ibv_create_flow); + struct verbs_context *vctx = + verbs_get_ctx_op(qp->context, ibv_create_flow); if (!vctx) { errno = EOPNOTSUPP; return NULL; @@ -2559,8 +2534,8 @@ static inline struct ibv_flow *ibv_create_flow(struct ibv_qp *qp, static inline int ibv_destroy_flow(struct ibv_flow *flow_id) { - struct verbs_context *vctx = verbs_get_ctx_op(flow_id->context, - ibv_destroy_flow); + struct verbs_context *vctx = + verbs_get_ctx_op(flow_id->context, ibv_destroy_flow); if (!vctx) return EOPNOTSUPP; return vctx->ibv_destroy_flow(flow_id); @@ -2570,8 +2545,8 @@ static inline struct ibv_flow_action * ibv_create_flow_action_esp(struct ibv_context *ctx, struct ibv_flow_action_esp_attr *esp) { - struct verbs_context *vctx = verbs_get_ctx_op(ctx, - create_flow_action_esp); + struct verbs_context *vctx = + verbs_get_ctx_op(ctx, create_flow_action_esp); if (!vctx) { errno = EOPNOTSUPP; @@ -2585,8 +2560,8 @@ static inline int ibv_modify_flow_action_esp(struct ibv_flow_action *action, struct ibv_flow_action_esp_attr *esp) { - struct verbs_context *vctx = verbs_get_ctx_op(action->context, - modify_flow_action_esp); + struct verbs_context *vctx = + verbs_get_ctx_op(action->context, modify_flow_action_esp); if (!vctx) return EOPNOTSUPP; @@ -2596,8 +2571,8 @@ ibv_modify_flow_action_esp(struct ibv_flow_action *action, static inline int ibv_destroy_flow_action(struct ibv_flow_action *action) { - struct verbs_context *vctx = verbs_get_ctx_op(action->context, - destroy_flow_action); + struct verbs_context *vctx = + verbs_get_ctx_op(action->context, destroy_flow_action); if (!vctx) return EOPNOTSUPP; @@ -2609,7 +2584,8 @@ static inline int ibv_destroy_flow_action(struct ibv_flow_action *action) * ibv_open_xrcd - Open an extended connection domain */ static inline struct ibv_xrcd * -ibv_open_xrcd(struct ibv_context *context, struct ibv_xrcd_init_attr *xrcd_init_attr) +ibv_open_xrcd(struct ibv_context *context, + struct ibv_xrcd_init_attr *xrcd_init_attr) { struct verbs_context *vctx = verbs_get_ctx_op(context, open_xrcd); if (!vctx) { @@ -2658,8 +2634,8 @@ __ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, unsigned int access, #define ibv_reg_mr(pd, addr, length, access) \ __ibv_reg_mr(pd, addr, length, access, \ - __builtin_constant_p( \ - ((int)(access) & IBV_ACCESS_OPTIONAL_RANGE) == 0)) + __builtin_constant_p(((int)(access) & \ + IBV_ACCESS_OPTIONAL_RANGE) == 0)) /** * ibv_reg_mr_iova - Register a memory region with a virtual offset @@ -2679,17 +2655,20 @@ __ibv_reg_mr_iova(struct ibv_pd *pd, void *addr, size_t length, uint64_t iova, } #define ibv_reg_mr_iova(pd, addr, length, iova, access) \ - __ibv_reg_mr_iova(pd, addr, length, iova, access, \ - __builtin_constant_p( \ - ((access) & IBV_ACCESS_OPTIONAL_RANGE) == 0)) + __ibv_reg_mr_iova( \ + pd, addr, length, iova, access, \ + __builtin_constant_p(((access) & IBV_ACCESS_OPTIONAL_RANGE) == \ + 0)) /** * ibv_reg_dmabuf_mr - Register a dmabuf-based memory region */ -struct ibv_mr *ibv_reg_dmabuf_mr(struct ibv_pd *pd, uint64_t offset, size_t length, - uint64_t iova, int fd, int access); +struct ibv_mr *ibv_reg_dmabuf_mr(struct ibv_pd *pd, uint64_t offset, + size_t length, uint64_t iova, int fd, + int access); -struct ibv_mr *ibv_reg_mr_ex(struct ibv_pd *pd, struct ibv_mr_init_attr *mr_init_attr); +struct ibv_mr *ibv_reg_mr_ex(struct ibv_pd *pd, + struct ibv_mr_init_attr *mr_init_attr); enum ibv_rereg_mr_err_code { /* Old MR is valid, invalid input */ @@ -2707,8 +2686,7 @@ enum ibv_rereg_mr_err_code { /** * ibv_rereg_mr - Re-Register a memory region */ -int ibv_rereg_mr(struct ibv_mr *mr, int flags, - struct ibv_pd *pd, void *addr, +int ibv_rereg_mr(struct ibv_mr *mr, int flags, struct ibv_pd *pd, void *addr, size_t length, int access); /** * ibv_dereg_mr - Deregister a memory region @@ -2791,8 +2769,7 @@ int ibv_destroy_comp_channel(struct ibv_comp_channel *channel); */ static inline int ibv_advise_mr(struct ibv_pd *pd, enum ibv_advise_mr_advice advice, - uint32_t flags, - struct ibv_sge *sg_list, + uint32_t flags, struct ibv_sge *sg_list, uint32_t num_sge) { struct verbs_context *vctx; @@ -2809,9 +2786,8 @@ static inline int ibv_advise_mr(struct ibv_pd *pd, * @context - Context DM will be attached to * @attr - Attributes to allocate the DM with */ -static inline -struct ibv_dm *ibv_alloc_dm(struct ibv_context *context, - struct ibv_alloc_dm_attr *attr) +static inline struct ibv_dm *ibv_alloc_dm(struct ibv_context *context, + struct ibv_alloc_dm_attr *attr) { struct verbs_context *vctx = verbs_get_ctx_op(context, alloc_dm); @@ -2827,8 +2803,7 @@ struct ibv_dm *ibv_alloc_dm(struct ibv_context *context, * ibv_free_dm - Free device allocated memory * @dm - The DM to free */ -static inline -int ibv_free_dm(struct ibv_dm *dm) +static inline int ibv_free_dm(struct ibv_dm *dm) { struct verbs_context *vctx = verbs_get_ctx_op(dm->context, free_dm); @@ -2847,16 +2822,14 @@ int ibv_dm_export_dmabuf_fd(struct ibv_dm *dm); * @host_addr - Host memory address to copy to/from * @length - Number of bytes to copy */ -static inline -int ibv_memcpy_to_dm(struct ibv_dm *dm, uint64_t dm_offset, - const void *host_addr, size_t length) +static inline int ibv_memcpy_to_dm(struct ibv_dm *dm, uint64_t dm_offset, + const void *host_addr, size_t length) { return dm->memcpy_to_dm(dm, dm_offset, host_addr, length); } -static inline -int ibv_memcpy_from_dm(void *host_addr, struct ibv_dm *dm, - uint64_t dm_offset, size_t length) +static inline int ibv_memcpy_from_dm(void *host_addr, struct ibv_dm *dm, + uint64_t dm_offset, size_t length) { return dm->memcpy_from_dm(host_addr, dm, dm_offset, length); } @@ -2865,8 +2838,7 @@ int ibv_memcpy_from_dm(void *host_addr, struct ibv_dm *dm, * ibv_alloc_null_mr - Allocate a null memory region. * @pd - The protection domain associated with the MR. */ -static inline -struct ibv_mr *ibv_alloc_null_mr(struct ibv_pd *pd) +static inline struct ibv_mr *ibv_alloc_null_mr(struct ibv_pd *pd) { struct verbs_context *vctx; @@ -2887,10 +2859,9 @@ struct ibv_mr *ibv_alloc_null_mr(struct ibv_pd *pd) * @length - Number of bytes to register * @access - memory region access flags */ -static inline -struct ibv_mr *ibv_reg_dm_mr(struct ibv_pd *pd, struct ibv_dm *dm, - uint64_t dm_offset, - size_t length, unsigned int access) +static inline struct ibv_mr *ibv_reg_dm_mr(struct ibv_pd *pd, struct ibv_dm *dm, + uint64_t dm_offset, size_t length, + unsigned int access) { struct verbs_context *vctx = verbs_get_ctx_op(pd->context, reg_dm_mr); @@ -2913,8 +2884,7 @@ struct ibv_mr *ibv_reg_dm_mr(struct ibv_pd *pd, struct ibv_dm *dm, * Must be >= 0 and < context->num_comp_vectors. */ struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, - void *cq_context, - struct ibv_comp_channel *channel, + void *cq_context, struct ibv_comp_channel *channel, int comp_vector); /** @@ -2922,9 +2892,9 @@ struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, * @context - Context CQ will be attached to * @cq_attr - Attributes to create the CQ with */ -static inline -struct ibv_cq_ex *ibv_create_cq_ex(struct ibv_context *context, - struct ibv_cq_init_attr_ex *cq_attr) +static inline struct ibv_cq_ex * +ibv_create_cq_ex(struct ibv_context *context, + struct ibv_cq_init_attr_ex *cq_attr) { struct verbs_context *vctx = verbs_get_ctx_op(context, create_cq_ex); @@ -2959,8 +2929,8 @@ int ibv_destroy_cq(struct ibv_cq *cq); * All completion events returned by ibv_get_cq_event() must * eventually be acknowledged with ibv_ack_cq_events(). */ -int ibv_get_cq_event(struct ibv_comp_channel *channel, - struct ibv_cq **cq, void **cq_context); +int ibv_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, + void **cq_context); /** * ibv_ack_cq_events - Acknowledge CQ completion events @@ -2990,7 +2960,8 @@ void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents); * non-negative and strictly less than num_entries, then the CQ was * emptied. */ -static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc) +static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, + struct ibv_wc *wc) { return cq->context->ops.poll_cq(cq, num_entries, wc); } @@ -3009,7 +2980,8 @@ static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) return cq->context->ops.req_notify_cq(cq, solicited_only); } -static inline int ibv_modify_cq(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr) +static inline int ibv_modify_cq(struct ibv_cq *cq, + struct ibv_modify_cq_attr *attr) { struct verbs_context *vctx = verbs_get_ctx_op(cq->context, modify_cq); @@ -3039,12 +3011,14 @@ ibv_create_srq_ex(struct ibv_context *context, struct verbs_context *vctx; uint32_t mask = srq_init_attr_ex->comp_mask; - if (!(mask & ~(uint32_t)(IBV_SRQ_INIT_ATTR_PD | IBV_SRQ_INIT_ATTR_TYPE)) && + if (!(mask & + ~(uint32_t)(IBV_SRQ_INIT_ATTR_PD | IBV_SRQ_INIT_ATTR_TYPE)) && (mask & IBV_SRQ_INIT_ATTR_PD) && (!(mask & IBV_SRQ_INIT_ATTR_TYPE) || (srq_init_attr_ex->srq_type == IBV_SRQT_BASIC))) - return ibv_create_srq(srq_init_attr_ex->pd, - (struct ibv_srq_init_attr *)srq_init_attr_ex); + return ibv_create_srq( + srq_init_attr_ex->pd, + (struct ibv_srq_init_attr *)srq_init_attr_ex); vctx = verbs_get_ctx_op(context, create_srq_ex); if (!vctx) { @@ -3066,8 +3040,7 @@ ibv_create_srq_ex(struct ibv_context *context, * IBV_SRQ_LIMIT to set the SRQ's limit and request notification when * the number of receives queued drops below the limit. */ -int ibv_modify_srq(struct ibv_srq *srq, - struct ibv_srq_attr *srq_attr, +int ibv_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, int srq_attr_mask); /** @@ -3080,7 +3053,8 @@ int ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr); static inline int ibv_get_srq_num(struct ibv_srq *srq, uint32_t *srq_num) { - struct verbs_context *vctx = verbs_get_ctx_op(srq->context, get_srq_num); + struct verbs_context *vctx = + verbs_get_ctx_op(srq->context, get_srq_num); if (!vctx) return EOPNOTSUPP; @@ -3108,8 +3082,7 @@ static inline int ibv_post_srq_recv(struct ibv_srq *srq, return srq->context->ops.post_srq_recv(srq, recv_wr, bad_recv_wr); } -static inline int ibv_post_srq_ops(struct ibv_srq *srq, - struct ibv_ops_wr *op, +static inline int ibv_post_srq_ops(struct ibv_srq *srq, struct ibv_ops_wr *op, struct ibv_ops_wr **bad_op) { struct verbs_context *vctx; @@ -3129,14 +3102,16 @@ struct ibv_qp *ibv_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr); static inline struct ibv_qp * -ibv_create_qp_ex(struct ibv_context *context, struct ibv_qp_init_attr_ex *qp_init_attr_ex) +ibv_create_qp_ex(struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex) { struct verbs_context *vctx; uint32_t mask = qp_init_attr_ex->comp_mask; if (mask == IBV_QP_INIT_ATTR_PD) - return ibv_create_qp(qp_init_attr_ex->pd, - (struct ibv_qp_init_attr *)qp_init_attr_ex); + return ibv_create_qp( + qp_init_attr_ex->pd, + (struct ibv_qp_init_attr *)qp_init_attr_ex); vctx = verbs_get_ctx_op(context, create_qp_ex); if (!vctx) { @@ -3211,9 +3186,8 @@ int ibv_dealloc_dmah(struct ibv_dmah *dmah); * @values - in/out - defines the attributes we need to query/queried. * (Or's bits of enum ibv_values_mask on values->comp_mask field) */ -static inline int -ibv_query_rt_values_ex(struct ibv_context *context, - struct ibv_values_ex *values) +static inline int ibv_query_rt_values_ex(struct ibv_context *context, + struct ibv_values_ex *values) { struct verbs_context *vctx; @@ -3258,8 +3232,8 @@ ibv_query_device_ex(struct ibv_context *context, /** * ibv_open_qp - Open a shareable queue pair. */ -static inline struct ibv_qp * -ibv_open_qp(struct ibv_context *context, struct ibv_qp_open_attr *qp_open_attr) +static inline struct ibv_qp *ibv_open_qp(struct ibv_context *context, + struct ibv_qp_open_attr *qp_open_attr) { struct verbs_context *vctx = verbs_get_ctx_op(context, open_qp); if (!vctx) { @@ -3272,17 +3246,15 @@ ibv_open_qp(struct ibv_context *context, struct ibv_qp_open_attr *qp_open_attr) /** * ibv_modify_qp - Modify a queue pair. */ -int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask); +int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask); /** * ibv_modify_qp_rate_limit - Modify a queue pair rate limit values * @qp - QP object to modify * @attr - Attributes to configure the rate limiting values of the QP */ -static inline int -ibv_modify_qp_rate_limit(struct ibv_qp *qp, - struct ibv_qp_rate_limit_attr *attr) +static inline int ibv_modify_qp_rate_limit(struct ibv_qp *qp, + struct ibv_qp_rate_limit_attr *attr) { struct verbs_context *vctx; @@ -3322,8 +3294,7 @@ int ibv_query_qp_data_in_order(struct ibv_qp *qp, enum ibv_wr_opcode op, * The qp_attr_mask may be used to limit the query to gathering only the * selected attributes. */ -int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask, +int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, struct ibv_qp_init_attr *init_attr); /** @@ -3349,8 +3320,9 @@ int ibv_destroy_qp(struct ibv_qp *qp); * ibv_create_wq() returns a pointer to the created WQ, or NULL if the request * fails. */ -static inline struct ibv_wq *ibv_create_wq(struct ibv_context *context, - struct ibv_wq_init_attr *wq_init_attr) +static inline struct ibv_wq * +ibv_create_wq(struct ibv_context *context, + struct ibv_wq_init_attr *wq_init_attr) { struct verbs_context *vctx = verbs_get_ctx_op(context, create_wq); struct ibv_wq *wq; @@ -3420,8 +3392,9 @@ static inline int ibv_destroy_wq(struct ibv_wq *wq) * ibv_create_rwq_ind_table returns a pointer to the created * Indirection Table, or NULL if the request fails. */ -static inline struct ibv_rwq_ind_table *ibv_create_rwq_ind_table(struct ibv_context *context, - struct ibv_rwq_ind_table_init_attr *init_attr) +static inline struct ibv_rwq_ind_table * +ibv_create_rwq_ind_table(struct ibv_context *context, + struct ibv_rwq_ind_table_init_attr *init_attr) { struct verbs_context *vctx; @@ -3441,7 +3414,8 @@ static inline struct ibv_rwq_ind_table *ibv_create_rwq_ind_table(struct ibv_cont * ibv_destroy_rwq_ind_table() returns 0 on success, or the value of errno * on failure (which indicates the failure reason). */ -static inline int ibv_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table) +static inline int +ibv_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table) { struct verbs_context *vctx; @@ -3573,8 +3547,9 @@ static inline int ibv_is_qpt_supported(uint32_t caps, enum ibv_qp_type qpt) return !!(caps & (1 << qpt)); } -static inline struct ibv_counters *ibv_create_counters(struct ibv_context *context, - struct ibv_counters_init_attr *init_attr) +static inline struct ibv_counters * +ibv_create_counters(struct ibv_context *context, + struct ibv_counters_init_attr *init_attr) { struct verbs_context *vctx; @@ -3598,9 +3573,10 @@ static inline int ibv_destroy_counters(struct ibv_counters *counters) return vctx->destroy_counters(counters); } -static inline int ibv_attach_counters_point_flow(struct ibv_counters *counters, - struct ibv_counter_attach_attr *attr, - struct ibv_flow *flow) +static inline int +ibv_attach_counters_point_flow(struct ibv_counters *counters, + struct ibv_counter_attach_attr *attr, + struct ibv_flow *flow) { struct verbs_context *vctx; @@ -3613,8 +3589,7 @@ static inline int ibv_attach_counters_point_flow(struct ibv_counters *counters, static inline int ibv_read_counters(struct ibv_counters *counters, uint64_t *counters_value, - uint32_t ncounters, - uint32_t flags) + uint32_t ncounters, uint32_t flags) { struct verbs_context *vctx; @@ -3650,7 +3625,6 @@ int ibv_query_ece(struct ibv_qp *qp, struct ibv_ece *ece); } #endif -# undef __attribute_const - +#undef __attribute_const #endif /* INFINIBAND_VERBS_H */ diff --git a/providers/hfi2verbs/CMakeLists.txt b/providers/hfi2verbs/CMakeLists.txt new file mode 100644 index 000000000..e548f78b5 --- /dev/null +++ b/providers/hfi2verbs/CMakeLists.txt @@ -0,0 +1,4 @@ +rdma_provider(hfi2verbs + hfiverbs.c + verbs.c + ) diff --git a/providers/hfi2verbs/hfi-abi.h b/providers/hfi2verbs/hfi-abi.h new file mode 100644 index 000000000..da204c9b8 --- /dev/null +++ b/providers/hfi2verbs/hfi-abi.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (c) 2015 Intel Corporation + * Copyright (C) 2006-2007 QLogic Corporation, All rights reserved. + * + */ + +#ifndef HFI2_ABI_H +#define HFI2_ABI_H + +#include + +struct hfi2_get_context_resp { + struct ib_uverbs_get_context_resp ibv_resp; + __u32 version; +}; + +struct hfi2_create_cq_resp { + struct ib_uverbs_create_cq_resp ibv_resp; + __u64 offset; +}; + +struct hfi2_resize_cq_resp { + struct ib_uverbs_resize_cq_resp ibv_resp; + __u64 offset; +}; + +struct hfi2_create_qp_resp { + struct ib_uverbs_create_qp_resp ibv_resp; + __u64 offset; +}; + +struct hfi2_create_srq_resp { + struct ib_uverbs_create_srq_resp ibv_resp; + __u64 offset; +}; + +struct hfi2_modify_srq_cmd { + struct ibv_modify_srq ibv_cmd; + __u64 offset_addr; +}; + +#endif /* HFI2_ABI_H */ diff --git a/providers/hfi2verbs/hfiverbs.c b/providers/hfi2verbs/hfiverbs.c new file mode 100644 index 000000000..4461e58f2 --- /dev/null +++ b/providers/hfi2verbs/hfiverbs.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015 Intel Corporation. + * Copyright (c) 2026 Cornelis Networks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Contact Information: + * Intel Corporation + * www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2015 Intel Corporation. + * Copyright (c) 2026 Cornelis Networks + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2006-2007 QLogic Corporation, All rights reserved. + * Copyright (c) 2005. PathScale, Inc. All rights reserved. + * + */ + +#include + +#include +#include +#include +#include + +#include "hfiverbs.h" +#include "hfi-abi.h" + +static void hfi2_free_context(struct ibv_context *ibctx); + +#ifndef PCI_VENDOR_ID_CORNELIS +#define PCI_VENDOR_ID_CORNELIS 0x434e +#endif + +#ifndef PCI_DEVICE_ID_HFI2_0 +#define PCI_DEVICE_ID_HFI2_0 0x0001 +#endif + +#define HFI2(v, d) \ + VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_HFI2_##d, NULL) +static const struct verbs_match_ent hca_table[] = { VERBS_DRIVER_ID( + RDMA_DRIVER_HFI2), + HFI2(CORNELIS, 0), + {} }; + +static const struct verbs_context_ops hfi2_ctx_common_ops = { + .free_context = hfi2_free_context, + .query_device_ex = hfi2_query_device, + .query_port = hfi2_query_port, + + .alloc_pd = hfi2_alloc_pd, + .dealloc_pd = hfi2_free_pd, + + .reg_mr = hfi2_reg_mr, + .dereg_mr = hfi2_dereg_mr, + + .create_cq = hfi2_create_cq, + .poll_cq = hfi2_poll_cq, + .req_notify_cq = ibv_cmd_req_notify_cq, + .resize_cq = hfi2_resize_cq, + .destroy_cq = hfi2_destroy_cq, + + .create_srq = hfi2_create_srq, + .modify_srq = hfi2_modify_srq, + .query_srq = hfi2_query_srq, + .destroy_srq = hfi2_destroy_srq, + .post_srq_recv = hfi2_post_srq_recv, + + .create_qp = hfi2_create_qp, + .query_qp = hfi2_query_qp, + .modify_qp = hfi2_modify_qp, + .destroy_qp = hfi2_destroy_qp, + + .post_send = hfi2_post_send, + .post_recv = hfi2_post_recv, + + .create_ah = hfi2_create_ah, + .destroy_ah = hfi2_destroy_ah, + + .attach_mcast = ibv_cmd_attach_mcast, + .detach_mcast = ibv_cmd_detach_mcast +}; + +static const struct verbs_context_ops hfi2_ctx_v1_ops = { + .create_cq = hfi2_create_cq_v1, + .create_qp = hfi2_create_qp_v1, + .create_srq = hfi2_create_srq_v1, + .destroy_cq = hfi2_destroy_cq_v1, + .destroy_qp = hfi2_destroy_qp_v1, + .destroy_srq = hfi2_destroy_srq_v1, + .modify_srq = hfi2_modify_srq_v1, + .poll_cq = ibv_cmd_poll_cq, + .post_recv = ibv_cmd_post_recv, + .post_srq_recv = ibv_cmd_post_srq_recv, + .resize_cq = hfi2_resize_cq_v1, +}; + +static struct verbs_context *hfi2_alloc_context(struct ibv_device *ibdev, + int cmd_fd, void *private_data) +{ + struct hfi2_context *context; + struct ibv_get_context cmd; + struct ib_uverbs_get_context_resp resp; + struct hfi2_device *dev; + + context = verbs_init_and_alloc_context(ibdev, cmd_fd, context, ibv_ctx, + RDMA_DRIVER_HFI2); + if (!context) + return NULL; + + if (ibv_cmd_get_context(&context->ibv_ctx, &cmd, sizeof(cmd), NULL, + &resp, sizeof(resp))) + goto err_free; + + verbs_set_ops(&context->ibv_ctx, &hfi2_ctx_common_ops); + + dev = to_idev(ibdev); + if (dev->abi_version == 1) + verbs_set_ops(&context->ibv_ctx, &hfi2_ctx_v1_ops); + + return &context->ibv_ctx; + +err_free: + verbs_uninit_context(&context->ibv_ctx); + free(context); + return NULL; +} + +static void hfi2_free_context(struct ibv_context *ibctx) +{ + struct hfi2_context *context = to_ictx(ibctx); + + verbs_uninit_context(&context->ibv_ctx); + free(context); +} + +static void hfi2_uninit_device(struct verbs_device *verbs_device) +{ + struct hfi2_device *dev = to_idev(&verbs_device->device); + + free(dev); +} + +static struct verbs_device *hfi2_device_alloc(struct verbs_sysfs_dev *sysfs_dev) +{ + struct hfi2_device *dev; + + dev = calloc(1, sizeof(*dev)); + if (!dev) + return NULL; + + dev->abi_version = sysfs_dev->abi_ver; + + return &dev->ibv_dev; +} + +static const struct verbs_device_ops hfi2_dev_ops = { + .name = "hfi2verbs", + .match_min_abi_version = 0, + .match_max_abi_version = INT_MAX, + .match_table = hca_table, + .alloc_device = hfi2_device_alloc, + .uninit_device = hfi2_uninit_device, + .alloc_context = hfi2_alloc_context, +}; +PROVIDER_DRIVER(hfi2verbs, hfi2_dev_ops); diff --git a/providers/hfi2verbs/hfiverbs.h b/providers/hfi2verbs/hfiverbs.h new file mode 100644 index 000000000..f1fcb8200 --- /dev/null +++ b/providers/hfi2verbs/hfiverbs.h @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (c) 2015 Intel Corporation + * Copyright (C) 2006-2007 QLogic Corporation, All rights reserved. + * + */ + +#ifndef HFI2_H +#define HFI2_H + +#include +#include +#include +#include + +#include +#include + +#define PFX "hfi2: " + +struct hfi2_device { + struct verbs_device ibv_dev; + int abi_version; +}; + +struct hfi2_context { + struct verbs_context ibv_ctx; +}; + +/* + * This structure needs to have the same size and offsets as + * the kernel's ib_wc structure since it is memory mapped. + */ +struct hfi2_wc { + uint64_t wr_id; + enum ibv_wc_status status; + enum ibv_wc_opcode opcode; + uint32_t vendor_err; + uint32_t byte_len; + uint32_t imm_data; /* in network byte order */ + uint32_t qp_num; + uint32_t src_qp; + enum ibv_wc_flags wc_flags; + uint16_t pkey_index; + uint16_t slid; + uint8_t sl; + uint8_t dlid_path_bits; + uint8_t port_num; +}; + +struct hfi2_cq_wc { + _Atomic(uint32_t) head; + _Atomic(uint32_t) tail; + struct hfi2_wc queue[]; +}; + +struct hfi2_cq { + struct ibv_cq ibv_cq; + struct hfi2_cq_wc *queue; + pthread_spinlock_t lock; +}; + +/* + * Receive work request queue entry. + * The size of the sg_list is determined when the QP is created and stored + * in qp->r_max_sge. + */ +struct hfi2_rwqe { + uint64_t wr_id; + uint8_t num_sge; + uint8_t padding[7]; + struct ibv_sge sg_list[]; +}; + +/* + * This struture is used to contain the head pointer, tail pointer, + * and receive work queue entries as a single memory allocation so + * it can be mmap'ed into user space. + * Note that the wq array elements are variable size so you can't + * just index into the array to get the N'th element; + * use get_rwqe_ptr() instead. + */ +struct hfi2_rwq { + _Atomic(uint32_t) head; /* new requests posted to the head. */ + _Atomic(uint32_t) tail; /* receives pull requests from here. */ + struct hfi2_rwqe wq[]; +}; + +struct hfi2_rq { + struct hfi2_rwq *rwq; + pthread_spinlock_t lock; + uint32_t size; + uint32_t max_sge; +}; + +struct hfi2_qp { + struct ibv_qp ibv_qp; + struct hfi2_rq rq; +}; + +struct hfi2_srq { + struct ibv_srq ibv_srq; + struct hfi2_rq rq; +}; + +#define to_ixxx(xxx, type) \ + container_of(ib##xxx, struct hfi2_##type, ibv_##xxx) + +static inline struct hfi2_context *to_ictx(struct ibv_context *ibctx) +{ + return container_of(ibctx, struct hfi2_context, ibv_ctx.context); +} + +static inline struct hfi2_device *to_idev(struct ibv_device *ibdev) +{ + return container_of(ibdev, struct hfi2_device, ibv_dev.device); +} + +static inline struct hfi2_cq *to_icq(struct ibv_cq *ibcq) +{ + return to_ixxx(cq, cq); +} + +static inline struct hfi2_qp *to_iqp(struct ibv_qp *ibqp) +{ + return to_ixxx(qp, qp); +} + +static inline struct hfi2_srq *to_isrq(struct ibv_srq *ibsrq) +{ + return to_ixxx(srq, srq); +} + +/* + * Since struct hfi2_rwqe is not a fixed size, we can't simply index into + * struct hfi2_rq.wq. This function does the array index computation. + */ +static inline struct hfi2_rwqe *get_rwqe_ptr(struct hfi2_rq *rq, + unsigned int n) +{ + return (struct hfi2_rwqe *) + ((char *) rq->rwq->wq + + (sizeof(struct hfi2_rwqe) + + rq->max_sge * sizeof(struct ibv_sge)) * n); +} + +int hfi2_query_device(struct ibv_context *context, + const struct ibv_query_device_ex_input *input, + struct ibv_device_attr_ex *attr, size_t attr_size); + +extern int hfi2_query_port(struct ibv_context *context, uint8_t port, + struct ibv_port_attr *attr); + +struct ibv_pd *hfi2_alloc_pd(struct ibv_context *pd); + +int hfi2_free_pd(struct ibv_pd *pd); + +struct ibv_mr *hfi2_reg_mr(struct ibv_pd *pd, void *addr, size_t length, + uint64_t hca_va, int access); + +int hfi2_dereg_mr(struct verbs_mr *vmr); + +struct ibv_cq *hfi2_create_cq(struct ibv_context *context, int cqe, + struct ibv_comp_channel *channel, + int comp_vector); + +struct ibv_cq *hfi2_create_cq_v1(struct ibv_context *context, int cqe, + struct ibv_comp_channel *channel, + int comp_vector); + +int hfi2_resize_cq(struct ibv_cq *cq, int cqe); + +int hfi2_resize_cq_v1(struct ibv_cq *cq, int cqe); + +int hfi2_destroy_cq(struct ibv_cq *cq); + +int hfi2_destroy_cq_v1(struct ibv_cq *cq); + +int hfi2_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc); + +struct ibv_qp *hfi2_create_qp(struct ibv_pd *pd, + struct ibv_qp_init_attr *attr); + +struct ibv_qp *hfi2_create_qp_v1(struct ibv_pd *pd, + struct ibv_qp_init_attr *attr); + +int hfi2_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, + int attr_mask, + struct ibv_qp_init_attr *init_attr); + +int hfi2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, + int attr_mask); + +int hfi2_destroy_qp(struct ibv_qp *qp); + +int hfi2_destroy_qp_v1(struct ibv_qp *qp); + +int hfi2_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, + struct ibv_send_wr **bad_wr); + +int hfi2_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, + struct ibv_recv_wr **bad_wr); + +struct ibv_srq *hfi2_create_srq(struct ibv_pd *pd, + struct ibv_srq_init_attr *attr); + +struct ibv_srq *hfi2_create_srq_v1(struct ibv_pd *pd, + struct ibv_srq_init_attr *attr); + +int hfi2_modify_srq(struct ibv_srq *srq, + struct ibv_srq_attr *attr, + int attr_mask); + +int hfi2_modify_srq_v1(struct ibv_srq *srq, + struct ibv_srq_attr *attr, + int attr_mask); + +int hfi2_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr); + +int hfi2_destroy_srq(struct ibv_srq *srq); + +int hfi2_destroy_srq_v1(struct ibv_srq *srq); + +int hfi2_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr, + struct ibv_recv_wr **bad_wr); + +struct ibv_ah *hfi2_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr); + +int hfi2_destroy_ah(struct ibv_ah *ah); + +#endif /* HFI2_H */ diff --git a/providers/hfi2verbs/verbs.c b/providers/hfi2verbs/verbs.c new file mode 100644 index 000000000..6a8d81be2 --- /dev/null +++ b/providers/hfi2verbs/verbs.c @@ -0,0 +1,699 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * BSD LICENSE + * + * Copyright(c) 2025 Cornelis Networks + * Copyright (c) 2026 Cornelis Networks + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (c) 2015 Intel Corporation + * Copyright (C) 2006-2007 QLogic Corporation, All rights reserved. + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "hfiverbs.h" +#include "hfi-abi.h" + +int hfi2_query_device(struct ibv_context *context, + const struct ibv_query_device_ex_input *input, + struct ibv_device_attr_ex *attr, size_t attr_size) +{ + struct ib_uverbs_ex_query_device_resp resp; + size_t resp_size = sizeof(resp); + uint64_t raw_fw_ver; + unsigned int major, minor, sub_minor; + int ret; + + ret = ibv_cmd_query_device_any(context, input, attr, attr_size, &resp, + &resp_size); + if (ret) + return ret; + + raw_fw_ver = resp.base.fw_ver; + major = (raw_fw_ver >> 32) & 0xffff; + minor = (raw_fw_ver >> 16) & 0xffff; + sub_minor = raw_fw_ver & 0xffff; + + snprintf(attr->orig_attr.fw_ver, sizeof(attr->orig_attr.fw_ver), + "%d.%d.%d", major, minor, sub_minor); + + return 0; +} + +int hfi2_query_port(struct ibv_context *context, uint8_t port, + struct ibv_port_attr *attr) +{ + struct ibv_query_port cmd; + + return ibv_cmd_query_port(context, port, attr, &cmd, sizeof(cmd)); +} + +struct ibv_pd *hfi2_alloc_pd(struct ibv_context *context) +{ + struct ibv_alloc_pd cmd; + struct ib_uverbs_alloc_pd_resp resp; + struct ibv_pd *pd; + + pd = malloc(sizeof(*pd)); + if (!pd) + return NULL; + + if (ibv_cmd_alloc_pd(context, pd, &cmd, sizeof(cmd), &resp, + sizeof(resp))) { + free(pd); + return NULL; + } + + return pd; +} + +int hfi2_free_pd(struct ibv_pd *pd) +{ + int ret; + + ret = ibv_cmd_dealloc_pd(pd); + if (ret) + return ret; + + free(pd); + return 0; +} + +struct ibv_mr *hfi2_reg_mr(struct ibv_pd *pd, void *addr, size_t length, + uint64_t hca_va, int access) +{ + struct verbs_mr *vmr; + struct ibv_reg_mr cmd; + struct ib_uverbs_reg_mr_resp resp; + int ret; + + vmr = malloc(sizeof(*vmr)); + if (!vmr) + return NULL; + + ret = ibv_cmd_reg_mr(pd, addr, length, hca_va, access, vmr, &cmd, + sizeof(cmd), &resp, sizeof(resp)); + + if (ret) { + free(vmr); + return NULL; + } + + return &vmr->ibv_mr; +} + +int hfi2_dereg_mr(struct verbs_mr *vmr) +{ + int ret; + + ret = ibv_cmd_dereg_mr(vmr); + if (ret) + return ret; + + free(vmr); + return 0; +} + +struct ibv_cq *hfi2_create_cq(struct ibv_context *context, int cqe, + struct ibv_comp_channel *channel, int comp_vector) +{ + struct hfi2_cq *cq; + struct hfi2_create_cq_resp resp; + int ret; + size_t size; + + memset(&resp, 0, sizeof(resp)); + cq = malloc(sizeof(*cq)); + if (!cq) + return NULL; + + ret = ibv_cmd_create_cq(context, cqe, channel, comp_vector, &cq->ibv_cq, + NULL, 0, &resp.ibv_resp, sizeof(resp)); + if (ret) { + free(cq); + return NULL; + } + + size = sizeof(struct hfi2_cq_wc) + sizeof(struct hfi2_wc) * cqe; + cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, + context->cmd_fd, resp.offset); + if ((void *)cq->queue == MAP_FAILED) { + ibv_cmd_destroy_cq(&cq->ibv_cq); + free(cq); + return NULL; + } + + pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE); + return &cq->ibv_cq; +} + +struct ibv_cq *hfi2_create_cq_v1(struct ibv_context *context, int cqe, + struct ibv_comp_channel *channel, + int comp_vector) +{ + struct ibv_cq *cq; + int ret; + + cq = malloc(sizeof(*cq)); + if (!cq) + return NULL; + + ret = ibv_cmd_create_cq(context, cqe, channel, comp_vector, cq, NULL, 0, + NULL, 0); + if (ret) { + free(cq); + return NULL; + } + + return cq; +} + +int hfi2_resize_cq(struct ibv_cq *ibcq, int cqe) +{ + struct hfi2_cq *cq = to_icq(ibcq); + struct ibv_resize_cq cmd; + struct hfi2_resize_cq_resp resp; + size_t size; + int ret; + + memset(&resp, 0, sizeof(resp)); + pthread_spin_lock(&cq->lock); + /* Save the old size so we can unmmap the queue. */ + size = sizeof(struct hfi2_cq_wc) + + (sizeof(struct hfi2_wc) * cq->ibv_cq.cqe); + ret = ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof(cmd), &resp.ibv_resp, + sizeof(resp)); + if (ret) { + pthread_spin_unlock(&cq->lock); + return ret; + } + (void)munmap(cq->queue, size); + size = sizeof(struct hfi2_cq_wc) + + (sizeof(struct hfi2_wc) * cq->ibv_cq.cqe); + cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, + ibcq->context->cmd_fd, resp.offset); + ret = errno; + pthread_spin_unlock(&cq->lock); + if ((void *)cq->queue == MAP_FAILED) + return ret; + return 0; +} + +int hfi2_resize_cq_v1(struct ibv_cq *ibcq, int cqe) +{ + struct ibv_resize_cq cmd; + struct ib_uverbs_resize_cq_resp resp; + + return ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof(cmd), &resp, + sizeof(resp)); +} + +int hfi2_destroy_cq(struct ibv_cq *ibcq) +{ + struct hfi2_cq *cq = to_icq(ibcq); + int ret; + + ret = ibv_cmd_destroy_cq(ibcq); + if (ret) + return ret; + + (void)munmap(cq->queue, + sizeof(struct hfi2_cq_wc) + + (sizeof(struct hfi2_wc) * cq->ibv_cq.cqe)); + free(cq); + return 0; +} + +int hfi2_destroy_cq_v1(struct ibv_cq *ibcq) +{ + int ret; + + ret = ibv_cmd_destroy_cq(ibcq); + if (!ret) + free(ibcq); + return ret; +} + +int hfi2_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc) +{ + struct hfi2_cq *cq = to_icq(ibcq); + struct hfi2_cq_wc *q; + int npolled; + uint32_t tail; + + pthread_spin_lock(&cq->lock); + q = cq->queue; + tail = atomic_load_explicit(&q->tail, memory_order_relaxed); + for (npolled = 0; npolled < ne; ++npolled, ++wc) { + if (tail == atomic_load(&q->head)) + break; + /* Make sure entry is read after head index is read. */ + atomic_thread_fence(memory_order_acquire); + memcpy(wc, &q->queue[tail], sizeof(*wc)); + if (tail == cq->ibv_cq.cqe) + tail = 0; + else + tail++; + } + atomic_store(&q->tail, tail); + pthread_spin_unlock(&cq->lock); + + return npolled; +} + +struct ibv_qp *hfi2_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr) +{ + struct ibv_create_qp cmd; + struct hfi2_create_qp_resp resp; + struct hfi2_qp *qp; + int ret; + size_t size; + + memset(&resp, 0, sizeof(resp)); + qp = malloc(sizeof(*qp)); + if (!qp) + return NULL; + + ret = ibv_cmd_create_qp(pd, &qp->ibv_qp, attr, &cmd, sizeof(cmd), + &resp.ibv_resp, sizeof(resp)); + if (ret) { + free(qp); + return NULL; + } + + if (attr->srq) { + qp->rq.size = 0; + qp->rq.max_sge = 0; + qp->rq.rwq = NULL; + } else { + qp->rq.size = attr->cap.max_recv_wr + 1; + qp->rq.max_sge = attr->cap.max_recv_sge; + size = sizeof(struct hfi2_rwq) + + (sizeof(struct hfi2_rwqe) + + (sizeof(struct ibv_sge) * qp->rq.max_sge)) * + qp->rq.size; + qp->rq.rwq = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, pd->context->cmd_fd, resp.offset); + if ((void *)qp->rq.rwq == MAP_FAILED) { + ibv_cmd_destroy_qp(&qp->ibv_qp); + free(qp); + return NULL; + } + } + + pthread_spin_init(&qp->rq.lock, PTHREAD_PROCESS_PRIVATE); + return &qp->ibv_qp; +} + +struct ibv_qp *hfi2_create_qp_v1(struct ibv_pd *pd, + struct ibv_qp_init_attr *attr) +{ + struct ibv_create_qp cmd; + struct ib_uverbs_create_qp_resp resp; + struct ibv_qp *qp; + int ret; + + qp = malloc(sizeof(*qp)); + if (!qp) + return NULL; + + ret = ibv_cmd_create_qp(pd, qp, attr, &cmd, sizeof(cmd), &resp, + sizeof(resp)); + if (ret) { + free(qp); + return NULL; + } + + return qp; +} + +int hfi2_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, + struct ibv_qp_init_attr *init_attr) +{ + struct ibv_query_qp cmd; + + return ibv_cmd_query_qp(qp, attr, attr_mask, init_attr, &cmd, + sizeof(cmd)); +} + +int hfi2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask) +{ + struct ibv_modify_qp cmd = {}; + + return ibv_cmd_modify_qp(qp, attr, attr_mask, &cmd, sizeof(cmd)); +} + +int hfi2_destroy_qp(struct ibv_qp *ibqp) +{ + struct hfi2_qp *qp = to_iqp(ibqp); + int ret; + + ret = ibv_cmd_destroy_qp(ibqp); + if (ret) + return ret; + + if (qp->rq.rwq) { + size_t size; + + size = sizeof(struct hfi2_rwq) + + (sizeof(struct hfi2_rwqe) + + (sizeof(struct ibv_sge) * qp->rq.max_sge)) * + qp->rq.size; + (void)munmap(qp->rq.rwq, size); + } + free(qp); + return 0; +} + +int hfi2_destroy_qp_v1(struct ibv_qp *ibqp) +{ + int ret; + + ret = ibv_cmd_destroy_qp(ibqp); + if (!ret) + free(ibqp); + return ret; +} + +int hfi2_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, + struct ibv_send_wr **bad_wr) +{ + unsigned int wr_count; + struct ibv_send_wr *i; + + /* Sanity check the number of WRs being posted */ + for (i = wr, wr_count = 0; i; i = i->next) + if (++wr_count > 10) + goto iter; + + return ibv_cmd_post_send(qp, wr, bad_wr); + +iter: + do { + struct ibv_send_wr *next; + int ret; + + next = i->next; + i->next = NULL; + ret = ibv_cmd_post_send(qp, wr, bad_wr); + i->next = next; + if (ret) + return ret; + if (next == NULL) + break; + wr = next; + for (i = wr, wr_count = 0; i->next; i = i->next) + if (++wr_count > 2) + break; + } while (1); + return 0; +} + +static int post_recv(struct hfi2_rq *rq, struct ibv_recv_wr *wr, + struct ibv_recv_wr **bad_wr) +{ + struct ibv_recv_wr *i; + struct hfi2_rwq *rwq; + struct hfi2_rwqe *wqe; + uint32_t head; + int n, ret; + + pthread_spin_lock(&rq->lock); + rwq = rq->rwq; + head = atomic_load_explicit(&rwq->head, memory_order_relaxed); + for (i = wr; i; i = i->next) { + if ((unsigned int)i->num_sge > rq->max_sge) { + ret = EINVAL; + goto bad; + } + wqe = get_rwqe_ptr(rq, head); + if (++head >= rq->size) + head = 0; + if (head == atomic_load(&rwq->tail)) { + ret = ENOMEM; + goto bad; + } + wqe->wr_id = i->wr_id; + wqe->num_sge = i->num_sge; + for (n = 0; n < wqe->num_sge; n++) + wqe->sg_list[n] = i->sg_list[n]; + + /* Make sure queue entry is written before the head index. */ + atomic_thread_fence(memory_order_release); + atomic_store(&rwq->head, head); + } + ret = 0; + goto done; + +bad: + if (bad_wr) + *bad_wr = i; +done: + pthread_spin_unlock(&rq->lock); + return ret; +} + +int hfi2_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, + struct ibv_recv_wr **bad_wr) +{ + struct hfi2_qp *qp = to_iqp(ibqp); + + return post_recv(&qp->rq, wr, bad_wr); +} + +struct ibv_srq *hfi2_create_srq(struct ibv_pd *pd, + struct ibv_srq_init_attr *attr) +{ + struct hfi2_srq *srq; + struct ibv_create_srq cmd; + struct hfi2_create_srq_resp resp; + int ret; + size_t size; + + memset(&resp, 0, sizeof(resp)); + srq = malloc(sizeof(*srq)); + if (srq == NULL) + return NULL; + + ret = ibv_cmd_create_srq(pd, &srq->ibv_srq, attr, &cmd, sizeof(cmd), + &resp.ibv_resp, sizeof(resp)); + if (ret) { + free(srq); + return NULL; + } + + srq->rq.size = attr->attr.max_wr + 1; + srq->rq.max_sge = attr->attr.max_sge; + size = sizeof(struct hfi2_rwq) + + (sizeof(struct hfi2_rwqe) + + (sizeof(struct ibv_sge) * srq->rq.max_sge)) * + srq->rq.size; + srq->rq.rwq = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, + pd->context->cmd_fd, resp.offset); + if ((void *)srq->rq.rwq == MAP_FAILED) { + ibv_cmd_destroy_srq(&srq->ibv_srq); + free(srq); + return NULL; + } + + pthread_spin_init(&srq->rq.lock, PTHREAD_PROCESS_PRIVATE); + return &srq->ibv_srq; +} + +struct ibv_srq *hfi2_create_srq_v1(struct ibv_pd *pd, + struct ibv_srq_init_attr *attr) +{ + struct ibv_srq *srq; + struct ibv_create_srq cmd; + struct ib_uverbs_create_srq_resp resp; + int ret; + + srq = malloc(sizeof(*srq)); + if (srq == NULL) + return NULL; + + ret = ibv_cmd_create_srq(pd, srq, attr, &cmd, sizeof(cmd), &resp, + sizeof(resp)); + if (ret) { + free(srq); + return NULL; + } + + return srq; +} + +int hfi2_modify_srq(struct ibv_srq *ibsrq, struct ibv_srq_attr *attr, + int attr_mask) +{ + struct hfi2_srq *srq = to_isrq(ibsrq); + struct hfi2_modify_srq_cmd cmd; + __u64 offset; + size_t size = 0; /* Shut up gcc */ + int ret; + + if (attr_mask & IBV_SRQ_MAX_WR) { + pthread_spin_lock(&srq->rq.lock); + /* Save the old size so we can unmmap the queue. */ + size = sizeof(struct hfi2_rwq) + + (sizeof(struct hfi2_rwqe) + + (sizeof(struct ibv_sge) * srq->rq.max_sge)) * + srq->rq.size; + } + cmd.offset_addr = (uintptr_t)&offset; + ret = ibv_cmd_modify_srq(ibsrq, attr, attr_mask, &cmd.ibv_cmd, + sizeof(cmd)); + if (ret) { + if (attr_mask & IBV_SRQ_MAX_WR) + pthread_spin_unlock(&srq->rq.lock); + return ret; + } + if (attr_mask & IBV_SRQ_MAX_WR) { + (void)munmap(srq->rq.rwq, size); + srq->rq.size = attr->max_wr + 1; + size = sizeof(struct hfi2_rwq) + + (sizeof(struct hfi2_rwqe) + + (sizeof(struct ibv_sge) * srq->rq.max_sge)) * + srq->rq.size; + srq->rq.rwq = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, ibsrq->context->cmd_fd, offset); + pthread_spin_unlock(&srq->rq.lock); + /* XXX Now we have no receive queue. */ + if ((void *)srq->rq.rwq == MAP_FAILED) + return errno; + } + return 0; +} + +int hfi2_modify_srq_v1(struct ibv_srq *ibsrq, struct ibv_srq_attr *attr, + int attr_mask) +{ + struct ibv_modify_srq cmd; + + return ibv_cmd_modify_srq(ibsrq, attr, attr_mask, &cmd, sizeof(cmd)); +} + +int hfi2_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr) +{ + struct ibv_query_srq cmd; + + return ibv_cmd_query_srq(srq, attr, &cmd, sizeof(cmd)); +} + +int hfi2_destroy_srq(struct ibv_srq *ibsrq) +{ + struct hfi2_srq *srq = to_isrq(ibsrq); + size_t size; + int ret; + + ret = ibv_cmd_destroy_srq(ibsrq); + if (ret) + return ret; + + size = sizeof(struct hfi2_rwq) + + (sizeof(struct hfi2_rwqe) + + (sizeof(struct ibv_sge) * srq->rq.max_sge)) * + srq->rq.size; + (void)munmap(srq->rq.rwq, size); + free(srq); + return 0; +} + +int hfi2_destroy_srq_v1(struct ibv_srq *ibsrq) +{ + int ret; + + ret = ibv_cmd_destroy_srq(ibsrq); + if (!ret) + free(ibsrq); + return ret; +} + +int hfi2_post_srq_recv(struct ibv_srq *ibsrq, struct ibv_recv_wr *wr, + struct ibv_recv_wr **bad_wr) +{ + struct hfi2_srq *srq = to_isrq(ibsrq); + + return post_recv(&srq->rq, wr, bad_wr); +} + +struct ibv_ah *hfi2_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr) +{ + struct ibv_ah *ah; + struct ib_uverbs_create_ah_resp resp; + + ah = malloc(sizeof(*ah)); + if (ah == NULL) + return NULL; + + memset(&resp, 0, sizeof(resp)); + if (ibv_cmd_create_ah(pd, ah, attr, &resp, sizeof(resp))) { + free(ah); + return NULL; + } + + return ah; +} + +int hfi2_destroy_ah(struct ibv_ah *ah) +{ + int ret; + + ret = ibv_cmd_destroy_ah(ah); + if (ret) + return ret; + + free(ah); + return 0; +} diff --git a/providers/ipathverbs/CMakeLists.txt b/providers/ipathverbs/CMakeLists.txt deleted file mode 100644 index eaa73a8c6..000000000 --- a/providers/ipathverbs/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -rdma_provider(ipathverbs - ipathverbs.c - verbs.c - ) - -rdma_subst_install(FILES "truescale.conf.in" - DESTINATION "${CMAKE_INSTALL_MODPROBEDIR}/" - RENAME "truescale.conf") -install(FILES truescale-serdes.cmds - DESTINATION "${CMAKE_INSTALL_LIBEXECDIR}" - PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE) diff --git a/providers/ipathverbs/COPYING b/providers/ipathverbs/COPYING deleted file mode 100644 index cf55023e8..000000000 --- a/providers/ipathverbs/COPYING +++ /dev/null @@ -1,35 +0,0 @@ -Copyright (c) 2013. Intel Corporation. All rights reserved. -Copyright (c) 2007. QLogic Corp. All rights reserved. -Copyright (c) 2005. PathScale, Inc. All rights reserved. - -This software is available to you under a choice of one of two -licenses. You may choose to be licensed under the terms of the GNU -General Public License (GPL) Version 2, available from the file -COPYING in the main directory of this source tree, or the -OpenIB.org BSD license below: - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - - Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - - Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -Patent licenses, if any, provided herein do not apply to -combinations of this program with other software, or any other -product whatsoever. diff --git a/providers/ipathverbs/dracut_check b/providers/ipathverbs/dracut_check deleted file mode 100644 index fbed81f80..000000000 --- a/providers/ipathverbs/dracut_check +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -if [ -n "$hostonly" ]; then - lspci -n 2>/dev/null | grep -q -i "1077\|1fc1" - exit $? -fi - -exit 0 diff --git a/providers/ipathverbs/dracut_install b/providers/ipathverbs/dracut_install deleted file mode 100644 index a7ef490ea..000000000 --- a/providers/ipathverbs/dracut_install +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -inst /etc/modprobe.d/truescale.conf -inst /usr/libexec/truescale-serdes.cmds - -# All files needed by truescale-serdes.cmds need to be present here -inst /sbin/lspci -inst /bin/grep -inst /bin/sed -inst /usr/bin/logger -inst /usr/sbin/dmidecode -inst /bin/readlink -inst /bin/echo diff --git a/providers/ipathverbs/dracut_kmod b/providers/ipathverbs/dracut_kmod deleted file mode 100644 index d76ae808b..000000000 --- a/providers/ipathverbs/dracut_kmod +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -instmods ib_qib - diff --git a/providers/ipathverbs/ipath-abi.h b/providers/ipathverbs/ipath-abi.h deleted file mode 100644 index 2b2e3290c..000000000 --- a/providers/ipathverbs/ipath-abi.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2006 QLogic, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Patent licenses, if any, provided herein do not apply to - * combinations of this program with other software, or any other - * product whatsoever. - */ - -#ifndef IPATH_ABI_H -#define IPATH_ABI_H - -#include - -struct ipath_get_context_resp { - struct ib_uverbs_get_context_resp ibv_resp; - __u32 version; -}; - -struct ipath_create_cq_resp { - struct ib_uverbs_create_cq_resp ibv_resp; - __u64 offset; -}; - -struct ipath_resize_cq_resp { - struct ib_uverbs_resize_cq_resp ibv_resp; - __u64 offset; -}; - -struct ipath_create_qp_resp { - struct ib_uverbs_create_qp_resp ibv_resp; - __u64 offset; -}; - -struct ipath_create_srq_resp { - struct ib_uverbs_create_srq_resp ibv_resp; - __u64 offset; -}; - -struct ipath_modify_srq_cmd { - struct ibv_modify_srq ibv_cmd; - __u64 offset_addr; -}; - -#endif /* IPATH_ABI_H */ diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c deleted file mode 100644 index bb59f0f9d..000000000 --- a/providers/ipathverbs/ipathverbs.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2006-2007 QLogic Corporation, All rights reserved. - * Copyright (c) 2005. PathScale, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Patent licenses, if any, provided herein do not apply to - * combinations of this program with other software, or any other - * product whatsoever. - */ - -#include - -#include -#include -#include -#include - -#include "ipathverbs.h" -#include "ipath-abi.h" - -static void ipath_free_context(struct ibv_context *ibctx); - -#ifndef PCI_VENDOR_ID_PATHSCALE -#define PCI_VENDOR_ID_PATHSCALE 0x1fc1 -#endif - -#ifndef PCI_VENDOR_ID_QLOGIC -#define PCI_VENDOR_ID_QLOGIC 0x1077 -#endif - -#ifndef PCI_DEVICE_ID_INFINIPATH_HT -#define PCI_DEVICE_ID_INFINIPATH_HT 0x000d -#endif - -#ifndef PCI_DEVICE_ID_INFINIPATH_PE800 -#define PCI_DEVICE_ID_INFINIPATH_PE800 0x0010 -#endif - -#ifndef PCI_DEVICE_ID_INFINIPATH_6220 -#define PCI_DEVICE_ID_INFINIPATH_6220 0x6220 -#endif - -#ifndef PCI_DEVICE_ID_INFINIPATH_7220 -#define PCI_DEVICE_ID_INFINIPATH_7220 0x7220 -#endif - -#ifndef PCI_DEVICE_ID_INFINIPATH_7322 -#define PCI_DEVICE_ID_INFINIPATH_7322 0x7322 -#endif - -#define HCA(v, d) \ - VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_INFINIPATH_##d, NULL) -static const struct verbs_match_ent hca_table[] = { - VERBS_DRIVER_ID(RDMA_DRIVER_QIB), - HCA(PATHSCALE, HT), - HCA(PATHSCALE, PE800), - HCA(QLOGIC, 6220), - HCA(QLOGIC, 7220), - HCA(QLOGIC, 7322), - {} -}; - -static const struct verbs_context_ops ipath_ctx_common_ops = { - .free_context = ipath_free_context, - .query_device_ex = ipath_query_device, - .query_port = ipath_query_port, - - .alloc_pd = ipath_alloc_pd, - .dealloc_pd = ipath_free_pd, - - .reg_mr = ipath_reg_mr, - .dereg_mr = ipath_dereg_mr, - - .create_cq = ipath_create_cq, - .poll_cq = ipath_poll_cq, - .req_notify_cq = ibv_cmd_req_notify_cq, - .resize_cq = ipath_resize_cq, - .destroy_cq = ipath_destroy_cq, - - .create_srq = ipath_create_srq, - .modify_srq = ipath_modify_srq, - .query_srq = ipath_query_srq, - .destroy_srq = ipath_destroy_srq, - .post_srq_recv = ipath_post_srq_recv, - - .create_qp = ipath_create_qp, - .query_qp = ipath_query_qp, - .modify_qp = ipath_modify_qp, - .destroy_qp = ipath_destroy_qp, - - .post_send = ipath_post_send, - .post_recv = ipath_post_recv, - - .create_ah = ipath_create_ah, - .destroy_ah = ipath_destroy_ah, - - .attach_mcast = ibv_cmd_attach_mcast, - .detach_mcast = ibv_cmd_detach_mcast -}; - -static const struct verbs_context_ops ipath_ctx_v1_ops = { - .create_cq = ipath_create_cq_v1, - .poll_cq = ibv_cmd_poll_cq, - .resize_cq = ipath_resize_cq_v1, - .destroy_cq = ipath_destroy_cq_v1, - .create_srq = ipath_create_srq_v1, - .destroy_srq = ipath_destroy_srq_v1, - .modify_srq = ipath_modify_srq_v1, - .post_srq_recv = ibv_cmd_post_srq_recv, - .create_qp = ipath_create_qp_v1, - .destroy_qp = ipath_destroy_qp_v1, - .post_recv = ibv_cmd_post_recv, -}; - -static struct verbs_context *ipath_alloc_context(struct ibv_device *ibdev, - int cmd_fd, - void *private_data) -{ - struct ipath_context *context; - struct ibv_get_context cmd; - struct ib_uverbs_get_context_resp resp; - struct ipath_device *dev; - - context = verbs_init_and_alloc_context(ibdev, cmd_fd, context, ibv_ctx, - RDMA_DRIVER_QIB); - if (!context) - return NULL; - - if (ibv_cmd_get_context(&context->ibv_ctx, &cmd, - sizeof cmd, NULL, &resp, sizeof resp)) - goto err_free; - - verbs_set_ops(&context->ibv_ctx, &ipath_ctx_common_ops); - dev = to_idev(ibdev); - if (dev->abi_version == 1) - verbs_set_ops(&context->ibv_ctx, &ipath_ctx_v1_ops); - return &context->ibv_ctx; - -err_free: - verbs_uninit_context(&context->ibv_ctx); - free(context); - return NULL; -} - -static void ipath_free_context(struct ibv_context *ibctx) -{ - struct ipath_context *context = to_ictx(ibctx); - - verbs_uninit_context(&context->ibv_ctx); - free(context); -} - -static void ipath_uninit_device(struct verbs_device *verbs_device) -{ - struct ipath_device *dev = to_idev(&verbs_device->device); - - free(dev); -} - -static struct verbs_device * -ipath_device_alloc(struct verbs_sysfs_dev *sysfs_dev) -{ - struct ipath_device *dev; - - dev = calloc(1, sizeof(*dev)); - if (!dev) - return NULL; - - dev->abi_version = sysfs_dev->abi_ver; - - return &dev->ibv_dev; -} - -static const struct verbs_device_ops ipath_dev_ops = { - .name = "ipathverbs", - .match_min_abi_version = 0, - .match_max_abi_version = INT_MAX, - .match_table = hca_table, - .alloc_device = ipath_device_alloc, - .uninit_device = ipath_uninit_device, - .alloc_context = ipath_alloc_context, -}; -PROVIDER_DRIVER(ipathverbs, ipath_dev_ops); diff --git a/providers/ipathverbs/ipathverbs.h b/providers/ipathverbs/ipathverbs.h deleted file mode 100644 index c5fa761f7..000000000 --- a/providers/ipathverbs/ipathverbs.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2006-2009 QLogic Corp. All rights reserved. - * Copyright (c) 2005. PathScale, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Patent licenses, if any, provided herein do not apply to - * combinations of this program with other software, or any other - * product whatsoever. - */ - -#ifndef IPATH_H -#define IPATH_H - -#include -#include -#include -#include - -#include -#include - -#define PFX "ipath: " - -struct ipath_device { - struct verbs_device ibv_dev; - int abi_version; -}; - -struct ipath_context { - struct verbs_context ibv_ctx; -}; - -/* - * This structure needs to have the same size and offsets as - * the kernel's ib_wc structure since it is memory mapped. - */ -struct ipath_wc { - uint64_t wr_id; - enum ibv_wc_status status; - enum ibv_wc_opcode opcode; - uint32_t vendor_err; - uint32_t byte_len; - uint32_t imm_data; /* in network byte order */ - uint32_t qp_num; - uint32_t src_qp; - enum ibv_wc_flags wc_flags; - uint16_t pkey_index; - uint16_t slid; - uint8_t sl; - uint8_t dlid_path_bits; - uint8_t port_num; -}; - -struct ipath_cq_wc { - _Atomic(uint32_t) head; - _Atomic(uint32_t) tail; - struct ipath_wc queue[1]; -}; - -struct ipath_cq { - struct ibv_cq ibv_cq; - struct ipath_cq_wc *queue; - pthread_spinlock_t lock; -}; - -/* - * Receive work request queue entry. - * The size of the sg_list is determined when the QP is created and stored - * in qp->r_max_sge. - */ -struct ipath_rwqe { - uint64_t wr_id; - uint8_t num_sge; - uint8_t padding[7]; - struct ibv_sge sg_list[0]; -}; - -/* - * This struture is used to contain the head pointer, tail pointer, - * and receive work queue entries as a single memory allocation so - * it can be mmap'ed into user space. - * Note that the wq array elements are variable size so you can't - * just index into the array to get the N'th element; - * use get_rwqe_ptr() instead. - */ -struct ipath_rwq { - _Atomic(uint32_t) head; /* new requests posted to the head. */ - _Atomic(uint32_t) tail; /* receives pull requests from here. */ - struct ipath_rwqe wq[0]; -}; - -struct ipath_rq { - struct ipath_rwq *rwq; - pthread_spinlock_t lock; - uint32_t size; - uint32_t max_sge; -}; - -struct ipath_qp { - struct ibv_qp ibv_qp; - struct ipath_rq rq; -}; - -struct ipath_srq { - struct ibv_srq ibv_srq; - struct ipath_rq rq; -}; - -#define to_ixxx(xxx, type) container_of(ib##xxx, struct ipath_##type, ibv_##xxx) - -static inline struct ipath_context *to_ictx(struct ibv_context *ibctx) -{ - return container_of(ibctx, struct ipath_context, ibv_ctx.context); -} - -static inline struct ipath_device *to_idev(struct ibv_device *ibdev) -{ - return container_of(ibdev, struct ipath_device, ibv_dev.device); -} - -static inline struct ipath_cq *to_icq(struct ibv_cq *ibcq) -{ - return to_ixxx(cq, cq); -} - -static inline struct ipath_qp *to_iqp(struct ibv_qp *ibqp) -{ - return to_ixxx(qp, qp); -} - -static inline struct ipath_srq *to_isrq(struct ibv_srq *ibsrq) -{ - return to_ixxx(srq, srq); -} - -/* - * Since struct ipath_rwqe is not a fixed size, we can't simply index into - * struct ipath_rq.wq. This function does the array index computation. - */ -static inline struct ipath_rwqe *get_rwqe_ptr(struct ipath_rq *rq, - unsigned n) -{ - return (struct ipath_rwqe *) - ((char *) rq->rwq->wq + - (sizeof(struct ipath_rwqe) + - rq->max_sge * sizeof(struct ibv_sge)) * n); -} - -int ipath_query_device(struct ibv_context *context, - const struct ibv_query_device_ex_input *input, - struct ibv_device_attr_ex *attr, size_t attr_size); - -extern int ipath_query_port(struct ibv_context *context, uint8_t port, - struct ibv_port_attr *attr); - -struct ibv_pd *ipath_alloc_pd(struct ibv_context *pd); - -int ipath_free_pd(struct ibv_pd *pd); - -struct ibv_mr *ipath_reg_mr(struct ibv_pd *pd, void *addr, size_t length, - uint64_t hca_va, int access); - -int ipath_dereg_mr(struct verbs_mr *vmr); - -struct ibv_cq *ipath_create_cq(struct ibv_context *context, int cqe, - struct ibv_comp_channel *channel, - int comp_vector); - -struct ibv_cq *ipath_create_cq_v1(struct ibv_context *context, int cqe, - struct ibv_comp_channel *channel, - int comp_vector); - -int ipath_resize_cq(struct ibv_cq *cq, int cqe); - -int ipath_resize_cq_v1(struct ibv_cq *cq, int cqe); - -int ipath_destroy_cq(struct ibv_cq *cq); - -int ipath_destroy_cq_v1(struct ibv_cq *cq); - -int ipath_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc); - -struct ibv_qp *ipath_create_qp(struct ibv_pd *pd, - struct ibv_qp_init_attr *attr); - -struct ibv_qp *ipath_create_qp_v1(struct ibv_pd *pd, - struct ibv_qp_init_attr *attr); - -int ipath_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask, - struct ibv_qp_init_attr *init_attr); - -int ipath_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask); - -int ipath_destroy_qp(struct ibv_qp *qp); - -int ipath_destroy_qp_v1(struct ibv_qp *qp); - -int ipath_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, - struct ibv_send_wr **bad_wr); - -int ipath_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, - struct ibv_recv_wr **bad_wr); - -struct ibv_srq *ipath_create_srq(struct ibv_pd *pd, - struct ibv_srq_init_attr *attr); - -struct ibv_srq *ipath_create_srq_v1(struct ibv_pd *pd, - struct ibv_srq_init_attr *attr); - -int ipath_modify_srq(struct ibv_srq *srq, - struct ibv_srq_attr *attr, - int attr_mask); - -int ipath_modify_srq_v1(struct ibv_srq *srq, - struct ibv_srq_attr *attr, - int attr_mask); - -int ipath_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr); - -int ipath_destroy_srq(struct ibv_srq *srq); - -int ipath_destroy_srq_v1(struct ibv_srq *srq); - -int ipath_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr, - struct ibv_recv_wr **bad_wr); - -struct ibv_ah *ipath_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr); - -int ipath_destroy_ah(struct ibv_ah *ah); - -#endif /* IPATH_H */ diff --git a/providers/ipathverbs/truescale-serdes.cmds b/providers/ipathverbs/truescale-serdes.cmds deleted file mode 100755 index 0f8933765..000000000 --- a/providers/ipathverbs/truescale-serdes.cmds +++ /dev/null @@ -1,257 +0,0 @@ -#!/bin/bash -# Copyright (c) 2013 Intel Corporation. All rights reserved. -# Copyright (c) 2010 QLogic Corporation. -# All rights reserved. -# -# This software is available to you under a choice of one of two -# licenses. You may choose to be licensed under the terms of the GNU -# General Public License (GPL) Version 2, available from the file -# COPYING in the main directory of this source tree, or the -# OpenIB.org BSD license below: -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# - Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# -# - Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# This script does truescale (qib) adapter-specific actions, and is -# sourced during boot after the ib_qib module is loaded. The stop -# operation is deprecated. It isn't intended for standalone use. - -# base name in /sys/class -PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH -export PATH -qb=/sys/class/infiniband/qib -serdes_parm=txselect - -if [ -r /etc/rdma/rdma.conf ]; then - IB_CONFIG=/etc/rdma/rdma.conf -else - IB_CONFIG=/etc/infiniband/openib.conf -fi -if [ -f $IB_CONFIG ]; then - . $IB_CONFIG -fi - -# If user specifies an override or the setting is ommitted from the config file -# then default to new back plane version. -if [ -z $QIB_QME_BPVER ]; then - QIB_QME_BPVER=1 -fi - -warn_and_log() -{ - echo "$0: $@" - logger -t infinipath "$@" -} - -setup_qmh() -{ - local -i nunit=0 bay bl2xB=0 full=0 - local parmf sysinfo bayinfo mez1bus mez2bus mez3bus=0 tbay - local -a parm bay_h1 - for parm in parameters/${serdes_parm} ${serdes_parm}; do - if [ -e /sys/module/ib_qib/$parm ]; then - parmf=/sys/module/ib_qib/$parm - break; - fi - done - if [ ! "$parmf" ]; then - warn_and_log Unable to find ${serdes_parm} parameter - return - fi - sysinfo="$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t system | \ - sed -e '/^Handle/d' -e '/^[ \t]*$/d' -e 's/[ \t]*$//' )" - if [ ! "$sysinfo" ]; then - warn_and_log Unable to determine system type - return - fi - bayinfo="$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t 204)" - if [ ! "$bayinfo" ]; then - warn_and_log Unable to determine bay - return - fi - case "${bayinfo}" in - *Server*Bay:*) tbay=$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t 204 | \ - sed -n -e 's/[ \t]*$//' -e 's/[ \t]*Server Bay:[ \t]*//p') ;; - *) tbay=$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t 204 | \ - sed -n -e '1,/BladeSystem/d' -e 's/ *$//' -e 's/^\t\t*//' \ - -e '/^[0-9][AB]*$/p' -e '/^[0-9][0-9][AB]*$/p') ;; - esac - - read pbase < $parmf - parm=($(echo ${qb}*)) - nunit=${#parm[*]} - - # [0] is a dummy in these arrays, bay #'ing starts at 1 - # H1 value, per bay (same for both ports) - m1_bay_h1=(0 8 7 7 7 7 6 6 6 8 7 7 7 7 6 6 7) - m2_bay_h1=(0 11 11 11 11 11 11 10 11 11 11 11 11 10 10 10 10) - m3_bay_h1=(0 11 11 11 11 10 10 10 10) - - # tx serdes index per bay for mez1 (either port) - mez1p1_idx=(0 2 2 17 17 17 1 1 1 2 1 17 17 16 2 18 16) - # tx serdes setting for mez1 p2 (only used on full-height blades) - mez1p2_idx=(0 4 4 3 3 3 2 4 4) - # tx serdes index per bay for mez2 port 1 - mez2p1_idx=(0 2 2 17 17 17 1 1 1 2 1 17 17 16 2 18 1) - # tx serdes index per bay for mez2 port 2 - mez2p2_idx=(0 2 2 19 1 1 1 1 1 2 1 18 17 1 19 1 1) - # tx serdes index per bay for mez3 port 1 (mez3 only on full-height blades) - mez3p1_idx=(0 2 1 18 17 1 19 1 1) - # tx serdes index per bay for mez3 port 2 (mez3 only on full-height blades) - mez3p2_idx=(0 2 1 17 17 16 2 18 1) - - case "${sysinfo}" in - *BL280[cC]*) mez1bus=3 mez2bus=6 bay=$tbay ;; - # both nodes on the 2x220 blade have bus 3, only one mez, but - # they connect to different switches through different paths - # so A and B have different parameters. They connect to - # the switch as if they were the mez2 on other blade types, - # with port 1 on mez2 for A node and port 2 on mez2 - # for the B node - *BL2x220[cC]*) - mez1bus=3 mez2bus=3 bay=${tbay%[AB]} - case "${tbay}" in - *A) bl2xB=${mez2p1_idx[$bay]} ;; - *B) bl2xB=${mez2p2_idx[$bay]} ;; - esac - ;; - *BL460[cC]*) mez1bus=6 mez2bus=9 bay=$tbay ;; - *BL465[cC]*) mez1bus=5 mez2bus=8 bay=$tbay ;; - *BL490[cC]*) mez1bus=6 mez2bus=7 bay=$tbay ;; - *BL685[cC]*) mez1bus=41 mez2bus=6 mez3bus=44 full=1 bay=$(($tbay % 9)) ;; - *) warn_and_log Unknown blade type "$sysinfo" - return ;; - esac - - # mez1 only has port1 connected, mez2, mez3 can have both ports - - # If only one card, and two mez possible, we have to figure out which - # mez we are plugged into. - # On RHEL4U8, we look in the driver subdir, all others - # in the device/driver subdir for the pcie bus. - pciprefix="[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]:" - if [ ${bl2xB} -ne 0 ]; then - pbase="${pbase} 0,1=${bl2xB},${m2_bay_h1[$bay]}" - else while [ $nunit -ne 0 ]; do - (( nunit-- )) - buspath=$(readlink -m ${qb}${nunit}/device) - if [ -n "$(echo ${buspath} | grep "${pciprefix}$(printf "%02d" ${mez1bus}):")" ]; then - pbase="${pbase} ${nunit},1=${mez1p1_idx[$bay]},${m1_bay_h1[$bay]}" - if [ ${full} -eq 1 ]; then - pbase="${pbase} ${nunit},2=${mez1p2_idx[$bay]},${m1_bay_h1[$bay]}" - fi - elif [ -n "$(echo ${buspath} | grep "${pciprefix}$(printf "%02d" ${mez2bus}):")" ]; then - pbase="${pbase} ${nunit},1=${mez2p1_idx[$bay]},${m2_bay_h1[$bay]}" - pbase="${pbase} ${nunit},2=${mez2p2_idx[$bay]},${m2_bay_h1[$bay]}" - elif [ -n "$(echo ${buspath} | grep "${pciprefix}$(printf "%02d" ${mez3bus}):")" ]; then - pbase="${pbase} ${nunit},1=${mez3p1_idx[$bay]},${m3_bay_h1[$bay]}" - pbase="${pbase} ${nunit},2=${mez3p2_idx[$bay]},${m3_bay_h1[$bay]}" - else - warn_and_log Mismatch on mezbus ${mez1_bus},${mez2_bus},${mez3_bus} \ - and unit ${nunit}, no serdes setup - fi - done - fi - echo -n ${pbase} > $parmf -} - - - -setup_qme() -{ - local parm parmf sn pbase - local -i nunit=0 bay idx bpver=${QIB_QME_BPVER:1} - local -a bp0_idx bp1_idx set - - # tx settings for Dell Backplane v1.0 - bp0_idx=( 0 22 23 24 25 26 24 27 28 22 23 24 25 26 24 27 28 ) - # tx settings for Dell Backplane v1.1 - bp1_idx=( 0 29 29 30 31 32 33 30 29 29 29 30 31 32 33 30 29 ) - - for parm in parameters/${serdes_parm} ${serdes_parm}; do - if [ -e /sys/module/ib_qib/$parm ]; then - parmf=/sys/module/ib_qib/$parm - break; - fi - done - if [ ! "$parmf" ]; then - warn_and_log Unable to find ${serdes_parm} parameter - return - fi - - read pbase < $parmf - parm=( $(echo ${qb}*) ) - nunit=${#parm[*]} - - if [ -e /sys/module/ib_qib/parameters/qme_bp ]; then - read bpver < /sys/module/ib_qib/parameters/qme_bp - if [ ${bpver} -ne 0 -a ${bpver} -ne 1 ]; then - warn_and_log "Invalid Dell backplane version (${bpver}). Defaulting to 1." - bpver=1 - fi - fi - eval 'set=( ${bp'${bpver}'_idx[@]} )' - - # we get two serial numbers normally, use 2nd if present, else first - sn="$(dmidecode -t 2 | grep -i serial | tail -1)" - case ${sn} in - *[sS]erial\ [nN]umber*) - bay="$(echo $sn | sed -e 's/\.$//' -e 's/.*\.0*//' -e 's/[abcd]$//')" - if [ ${bay} -gt ${#set[@]} ]; then - warn_and_log Unexpected QME7342 bay info: ${sn}, no Tx params - return - fi - idx=${set[bay]} - # H1 is same for all QME bays, so no need to specify. - while [ $nunit -ne 0 ]; do - (( nunit-- )) - pbase="${pbase} ${nunit},1=${idx} ${nunit},2=${idx}" - done - echo -n ${pbase} > $parmf - ;; - *) warn_and_log No QME7342 bay information, no Tx params - return;; - esac -} - -has_qib=$(lspci -n 2>/dev/null | grep -i "1077\|1fc1") -if [ ! "${has_qib}" ]; then - exit 0 -fi - -case "$1" in -start) - has_qmh7342=$(grep QMH7342 ${qb}*/hca_type 2>/dev/null) - if [ "${has_qmh7342}" ]; then - setup_qmh - else - has_qme7342=$(grep QME7342 ${qb}*/hca_type 2>/dev/null) - if [ "${has_qme7342}" ]; then - setup_qme - fi - fi - - ;; -stop) - warn_and_log stop operation deprecated - ;; -esac diff --git a/providers/ipathverbs/truescale.conf.in b/providers/ipathverbs/truescale.conf.in deleted file mode 100644 index e2827d956..000000000 --- a/providers/ipathverbs/truescale.conf.in +++ /dev/null @@ -1 +0,0 @@ -install ib_qib modprobe -i ib_qib $CMDLINE_OPTS && @CMAKE_INSTALL_FULL_LIBEXECDIR@/truescale-serdes.cmds start diff --git a/providers/ipathverbs/verbs.c b/providers/ipathverbs/verbs.c deleted file mode 100644 index e1b098a07..000000000 --- a/providers/ipathverbs/verbs.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (c) 2006-2009 QLogic Corp. All rights reserved. - * Copyright (c) 2005. PathScale, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Patent licenses, if any, provided herein do not apply to - * combinations of this program with other software, or any other - * product whatsoever. - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include "ipathverbs.h" -#include "ipath-abi.h" - -int ipath_query_device(struct ibv_context *context, - const struct ibv_query_device_ex_input *input, - struct ibv_device_attr_ex *attr, size_t attr_size) -{ - struct ib_uverbs_ex_query_device_resp resp; - size_t resp_size = sizeof(resp); - uint64_t raw_fw_ver; - unsigned major, minor, sub_minor; - int ret; - - ret = ibv_cmd_query_device_any(context, input, attr, attr_size, &resp, - &resp_size); - if (ret) - return ret; - - raw_fw_ver = resp.base.fw_ver; - major = (raw_fw_ver >> 32) & 0xffff; - minor = (raw_fw_ver >> 16) & 0xffff; - sub_minor = raw_fw_ver & 0xffff; - - snprintf(attr->orig_attr.fw_ver, sizeof(attr->orig_attr.fw_ver), - "%d.%d.%d", major, minor, sub_minor); - - return 0; -} - -int ipath_query_port(struct ibv_context *context, uint8_t port, - struct ibv_port_attr *attr) -{ - struct ibv_query_port cmd; - - return ibv_cmd_query_port(context, port, attr, &cmd, sizeof cmd); -} - -struct ibv_pd *ipath_alloc_pd(struct ibv_context *context) -{ - struct ibv_alloc_pd cmd; - struct ib_uverbs_alloc_pd_resp resp; - struct ibv_pd *pd; - - pd = malloc(sizeof *pd); - if (!pd) - return NULL; - - if (ibv_cmd_alloc_pd(context, pd, &cmd, sizeof cmd, - &resp, sizeof resp)) { - free(pd); - return NULL; - } - - return pd; -} - -int ipath_free_pd(struct ibv_pd *pd) -{ - int ret; - - ret = ibv_cmd_dealloc_pd(pd); - if (ret) - return ret; - - free(pd); - return 0; -} - -struct ibv_mr *ipath_reg_mr(struct ibv_pd *pd, void *addr, size_t length, - uint64_t hca_va, int access) -{ - struct verbs_mr *vmr; - struct ibv_reg_mr cmd; - struct ib_uverbs_reg_mr_resp resp; - int ret; - - vmr = malloc(sizeof(*vmr)); - if (!vmr) - return NULL; - - ret = ibv_cmd_reg_mr(pd, addr, length, hca_va, access, vmr, &cmd, - sizeof(cmd), &resp, sizeof(resp)); - if (ret) { - free(vmr); - return NULL; - } - - return &vmr->ibv_mr; -} - -int ipath_dereg_mr(struct verbs_mr *vmr) -{ - int ret; - - ret = ibv_cmd_dereg_mr(vmr); - if (ret) - return ret; - - free(vmr); - return 0; -} - -struct ibv_cq *ipath_create_cq(struct ibv_context *context, int cqe, - struct ibv_comp_channel *channel, - int comp_vector) -{ - struct ipath_cq *cq; - struct ipath_create_cq_resp resp; - int ret; - size_t size; - - cq = malloc(sizeof *cq); - if (!cq) - return NULL; - - ret = ibv_cmd_create_cq(context, cqe, channel, comp_vector, - &cq->ibv_cq, NULL, 0, - &resp.ibv_resp, sizeof resp); - if (ret) { - free(cq); - return NULL; - } - - size = sizeof(struct ipath_cq_wc) + sizeof(struct ipath_wc) * cqe; - cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, - context->cmd_fd, resp.offset); - if ((void *) cq->queue == MAP_FAILED) { - ibv_cmd_destroy_cq(&cq->ibv_cq); - free(cq); - return NULL; - } - - pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE); - return &cq->ibv_cq; -} - -struct ibv_cq *ipath_create_cq_v1(struct ibv_context *context, int cqe, - struct ibv_comp_channel *channel, - int comp_vector) -{ - struct ibv_cq *cq; - int ret; - - cq = malloc(sizeof *cq); - if (!cq) - return NULL; - - ret = ibv_cmd_create_cq(context, cqe, channel, comp_vector, - cq, NULL, 0, NULL, 0); - if (ret) { - free(cq); - return NULL; - } - - return cq; -} - -int ipath_resize_cq(struct ibv_cq *ibcq, int cqe) -{ - struct ipath_cq *cq = to_icq(ibcq); - struct ibv_resize_cq cmd; - struct ipath_resize_cq_resp resp; - size_t size; - int ret; - - pthread_spin_lock(&cq->lock); - /* Save the old size so we can unmmap the queue. */ - size = sizeof(struct ipath_cq_wc) + - (sizeof(struct ipath_wc) * cq->ibv_cq.cqe); - ret = ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof cmd, - &resp.ibv_resp, sizeof resp); - if (ret) { - pthread_spin_unlock(&cq->lock); - return ret; - } - (void) munmap(cq->queue, size); - size = sizeof(struct ipath_cq_wc) + - (sizeof(struct ipath_wc) * cq->ibv_cq.cqe); - cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, - ibcq->context->cmd_fd, resp.offset); - ret = errno; - pthread_spin_unlock(&cq->lock); - if ((void *) cq->queue == MAP_FAILED) - return ret; - return 0; -} - -int ipath_resize_cq_v1(struct ibv_cq *ibcq, int cqe) -{ - struct ibv_resize_cq cmd; - struct ib_uverbs_resize_cq_resp resp; - - return ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof cmd, - &resp, sizeof resp); -} - -int ipath_destroy_cq(struct ibv_cq *ibcq) -{ - struct ipath_cq *cq = to_icq(ibcq); - int ret; - - ret = ibv_cmd_destroy_cq(ibcq); - if (ret) - return ret; - - (void) munmap(cq->queue, sizeof(struct ipath_cq_wc) + - (sizeof(struct ipath_wc) * cq->ibv_cq.cqe)); - free(cq); - return 0; -} - -int ipath_destroy_cq_v1(struct ibv_cq *ibcq) -{ - int ret; - - ret = ibv_cmd_destroy_cq(ibcq); - if (!ret) - free(ibcq); - return ret; -} - -int ipath_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc) -{ - struct ipath_cq *cq = to_icq(ibcq); - struct ipath_cq_wc *q; - int npolled; - uint32_t tail; - - pthread_spin_lock(&cq->lock); - q = cq->queue; - tail = atomic_load_explicit(&q->tail, memory_order_relaxed); - for (npolled = 0; npolled < ne; ++npolled, ++wc) { - if (tail == atomic_load(&q->head)) - break; - - /* Make sure entry is read after head index is read. */ - atomic_thread_fence(memory_order_acquire); - memcpy(wc, &q->queue[tail], sizeof(*wc)); - if (tail == cq->ibv_cq.cqe) - tail = 0; - else - tail++; - } - atomic_store(&q->tail, tail); - pthread_spin_unlock(&cq->lock); - - return npolled; -} - -struct ibv_qp *ipath_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr) -{ - struct ibv_create_qp cmd; - struct ipath_create_qp_resp resp; - struct ipath_qp *qp; - int ret; - size_t size; - - qp = malloc(sizeof *qp); - if (!qp) - return NULL; - - ret = ibv_cmd_create_qp(pd, &qp->ibv_qp, attr, &cmd, sizeof cmd, - &resp.ibv_resp, sizeof resp); - if (ret) { - free(qp); - return NULL; - } - - if (attr->srq) { - qp->rq.size = 0; - qp->rq.max_sge = 0; - qp->rq.rwq = NULL; - } else { - qp->rq.size = attr->cap.max_recv_wr + 1; - qp->rq.max_sge = attr->cap.max_recv_sge; - size = sizeof(struct ipath_rwq) + - (sizeof(struct ipath_rwqe) + - (sizeof(struct ibv_sge) * qp->rq.max_sge)) * - qp->rq.size; - qp->rq.rwq = mmap(NULL, size, - PROT_READ | PROT_WRITE, MAP_SHARED, - pd->context->cmd_fd, resp.offset); - if ((void *) qp->rq.rwq == MAP_FAILED) { - ibv_cmd_destroy_qp(&qp->ibv_qp); - free(qp); - return NULL; - } - } - - pthread_spin_init(&qp->rq.lock, PTHREAD_PROCESS_PRIVATE); - return &qp->ibv_qp; -} - -struct ibv_qp *ipath_create_qp_v1(struct ibv_pd *pd, - struct ibv_qp_init_attr *attr) -{ - struct ibv_create_qp cmd; - struct ib_uverbs_create_qp_resp resp; - struct ibv_qp *qp; - int ret; - - qp = malloc(sizeof *qp); - if (!qp) - return NULL; - - ret = ibv_cmd_create_qp(pd, qp, attr, &cmd, sizeof cmd, - &resp, sizeof resp); - if (ret) { - free(qp); - return NULL; - } - - return qp; -} - -int ipath_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask, - struct ibv_qp_init_attr *init_attr) -{ - struct ibv_query_qp cmd; - - return ibv_cmd_query_qp(qp, attr, attr_mask, init_attr, - &cmd, sizeof cmd); -} - -int ipath_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask) -{ - struct ibv_modify_qp cmd = {}; - - return ibv_cmd_modify_qp(qp, attr, attr_mask, &cmd, sizeof cmd); -} - -int ipath_destroy_qp(struct ibv_qp *ibqp) -{ - struct ipath_qp *qp = to_iqp(ibqp); - int ret; - - ret = ibv_cmd_destroy_qp(ibqp); - if (ret) - return ret; - - if (qp->rq.rwq) { - size_t size; - - size = sizeof(struct ipath_rwq) + - (sizeof(struct ipath_rwqe) + - (sizeof(struct ibv_sge) * qp->rq.max_sge)) * - qp->rq.size; - (void) munmap(qp->rq.rwq, size); - } - free(qp); - return 0; -} - -int ipath_destroy_qp_v1(struct ibv_qp *ibqp) -{ - int ret; - - ret = ibv_cmd_destroy_qp(ibqp); - if (!ret) - free(ibqp); - return ret; -} - -int ipath_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, - struct ibv_send_wr **bad_wr) -{ - unsigned wr_count; - struct ibv_send_wr *i; - - /* Sanity check the number of WRs being posted */ - for (i = wr, wr_count = 0; i; i = i->next) - if (++wr_count > 10) - goto iter; - - return ibv_cmd_post_send(qp, wr, bad_wr); - -iter: - do { - struct ibv_send_wr *next; - int ret; - - next = i->next; - i->next = NULL; - ret = ibv_cmd_post_send(qp, wr, bad_wr); - i->next = next; - if (ret) - return ret; - if (next == NULL) - break; - wr = next; - for (i = wr, wr_count = 0; i->next; i = i->next) - if (++wr_count > 2) - break; - } while (1); - return 0; -} - -static int post_recv(struct ipath_rq *rq, struct ibv_recv_wr *wr, - struct ibv_recv_wr **bad_wr) -{ - struct ibv_recv_wr *i; - struct ipath_rwq *rwq; - struct ipath_rwqe *wqe; - uint32_t head; - int n, ret; - - pthread_spin_lock(&rq->lock); - rwq = rq->rwq; - head = atomic_load_explicit(&rwq->head, memory_order_relaxed); - for (i = wr; i; i = i->next) { - if ((unsigned) i->num_sge > rq->max_sge) { - ret = EINVAL; - goto bad; - } - wqe = get_rwqe_ptr(rq, head); - if (++head >= rq->size) - head = 0; - if (head == atomic_load(&rwq->tail)) { - ret = ENOMEM; - goto bad; - } - wqe->wr_id = i->wr_id; - wqe->num_sge = i->num_sge; - for (n = 0; n < wqe->num_sge; n++) - wqe->sg_list[n] = i->sg_list[n]; - - /* Make sure queue entry is written before the head index. */ - atomic_thread_fence(memory_order_release); - atomic_store(&rwq->head, head); - } - ret = 0; - goto done; - -bad: - if (bad_wr) - *bad_wr = i; -done: - pthread_spin_unlock(&rq->lock); - return ret; -} - -int ipath_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, - struct ibv_recv_wr **bad_wr) -{ - struct ipath_qp *qp = to_iqp(ibqp); - - return post_recv(&qp->rq, wr, bad_wr); -} - -struct ibv_srq *ipath_create_srq(struct ibv_pd *pd, - struct ibv_srq_init_attr *attr) -{ - struct ipath_srq *srq; - struct ibv_create_srq cmd; - struct ipath_create_srq_resp resp; - int ret; - size_t size; - - srq = malloc(sizeof *srq); - if (srq == NULL) - return NULL; - - ret = ibv_cmd_create_srq(pd, &srq->ibv_srq, attr, &cmd, sizeof cmd, - &resp.ibv_resp, sizeof resp); - if (ret) { - free(srq); - return NULL; - } - - srq->rq.size = attr->attr.max_wr + 1; - srq->rq.max_sge = attr->attr.max_sge; - size = sizeof(struct ipath_rwq) + - (sizeof(struct ipath_rwqe) + - (sizeof(struct ibv_sge) * srq->rq.max_sge)) * srq->rq.size; - srq->rq.rwq = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, - pd->context->cmd_fd, resp.offset); - if ((void *) srq->rq.rwq == MAP_FAILED) { - ibv_cmd_destroy_srq(&srq->ibv_srq); - free(srq); - return NULL; - } - - pthread_spin_init(&srq->rq.lock, PTHREAD_PROCESS_PRIVATE); - return &srq->ibv_srq; -} - -struct ibv_srq *ipath_create_srq_v1(struct ibv_pd *pd, - struct ibv_srq_init_attr *attr) -{ - struct ibv_srq *srq; - struct ibv_create_srq cmd; - struct ib_uverbs_create_srq_resp resp; - int ret; - - srq = malloc(sizeof *srq); - if (srq == NULL) - return NULL; - - ret = ibv_cmd_create_srq(pd, srq, attr, &cmd, sizeof cmd, - &resp, sizeof resp); - if (ret) { - free(srq); - return NULL; - } - - return srq; -} - -int ipath_modify_srq(struct ibv_srq *ibsrq, - struct ibv_srq_attr *attr, - int attr_mask) -{ - struct ipath_srq *srq = to_isrq(ibsrq); - struct ipath_modify_srq_cmd cmd; - __u64 offset; - size_t size = 0; /* Shut up gcc */ - int ret; - - if (attr_mask & IBV_SRQ_MAX_WR) { - pthread_spin_lock(&srq->rq.lock); - /* Save the old size so we can unmmap the queue. */ - size = sizeof(struct ipath_rwq) + - (sizeof(struct ipath_rwqe) + - (sizeof(struct ibv_sge) * srq->rq.max_sge)) * - srq->rq.size; - } - cmd.offset_addr = (uintptr_t) &offset; - ret = ibv_cmd_modify_srq(ibsrq, attr, attr_mask, - &cmd.ibv_cmd, sizeof cmd); - if (ret) { - if (attr_mask & IBV_SRQ_MAX_WR) - pthread_spin_unlock(&srq->rq.lock); - return ret; - } - if (attr_mask & IBV_SRQ_MAX_WR) { - (void) munmap(srq->rq.rwq, size); - srq->rq.size = attr->max_wr + 1; - size = sizeof(struct ipath_rwq) + - (sizeof(struct ipath_rwqe) + - (sizeof(struct ibv_sge) * srq->rq.max_sge)) * - srq->rq.size; - srq->rq.rwq = mmap(NULL, size, - PROT_READ | PROT_WRITE, MAP_SHARED, - ibsrq->context->cmd_fd, offset); - pthread_spin_unlock(&srq->rq.lock); - /* XXX Now we have no receive queue. */ - if ((void *) srq->rq.rwq == MAP_FAILED) - return errno; - } - return 0; -} - -int ipath_modify_srq_v1(struct ibv_srq *ibsrq, - struct ibv_srq_attr *attr, - int attr_mask) -{ - struct ibv_modify_srq cmd; - - return ibv_cmd_modify_srq(ibsrq, attr, attr_mask, - &cmd, sizeof cmd); -} - -int ipath_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr) -{ - struct ibv_query_srq cmd; - - return ibv_cmd_query_srq(srq, attr, &cmd, sizeof cmd); -} - -int ipath_destroy_srq(struct ibv_srq *ibsrq) -{ - struct ipath_srq *srq = to_isrq(ibsrq); - size_t size; - int ret; - - ret = ibv_cmd_destroy_srq(ibsrq); - if (ret) - return ret; - - size = sizeof(struct ipath_rwq) + - (sizeof(struct ipath_rwqe) + - (sizeof(struct ibv_sge) * srq->rq.max_sge)) * srq->rq.size; - (void) munmap(srq->rq.rwq, size); - free(srq); - return 0; -} - -int ipath_destroy_srq_v1(struct ibv_srq *ibsrq) -{ - int ret; - - ret = ibv_cmd_destroy_srq(ibsrq); - if (!ret) - free(ibsrq); - return ret; -} - -int ipath_post_srq_recv(struct ibv_srq *ibsrq, struct ibv_recv_wr *wr, - struct ibv_recv_wr **bad_wr) -{ - struct ipath_srq *srq = to_isrq(ibsrq); - - return post_recv(&srq->rq, wr, bad_wr); -} - -struct ibv_ah *ipath_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr) -{ - struct ibv_ah *ah; - struct ib_uverbs_create_ah_resp resp; - - ah = malloc(sizeof *ah); - if (ah == NULL) - return NULL; - - memset(&resp, 0, sizeof(resp)); - if (ibv_cmd_create_ah(pd, ah, attr, &resp, sizeof(resp))) { - free(ah); - return NULL; - } - - return ah; -} - -int ipath_destroy_ah(struct ibv_ah *ah) -{ - int ret; - - ret = ibv_cmd_destroy_ah(ah); - if (ret) - return ret; - - free(ah); - return 0; -} diff --git a/redhat/rdma-core.spec b/redhat/rdma-core.spec index 77b8d7c25..531df773b 100644 --- a/redhat/rdma-core.spec +++ b/redhat/rdma-core.spec @@ -428,7 +428,6 @@ fi %config(noreplace) %{_sysconfdir}/rdma/modules/roce.conf %dir %{_sysconfdir}/modprobe.d %config(noreplace) %{_sysconfdir}/modprobe.d/mlx4.conf -%config(noreplace) %{_sysconfdir}/modprobe.d/truescale.conf %{_unitdir}/rdma-hw.target %{_unitdir}/rdma-load-modules@.service %dir %{dracutlibdir} @@ -446,7 +445,6 @@ fi %dir %{sysmodprobedir} %{sysmodprobedir}/libmlx4.conf %{_libexecdir}/mlx4-setup.sh -%{_libexecdir}/truescale-serdes.cmds %{_sbindir}/rdma-ndd %{_unitdir}/rdma-ndd.service %{_sbindir}/rdma_topo diff --git a/suse/rdma-core.spec b/suse/rdma-core.spec index af25c159e..a46cc923e 100644 --- a/suse/rdma-core.spec +++ b/suse/rdma-core.spec @@ -60,7 +60,7 @@ Group: Productivity/Networking/Other %define dma_coherent 1 %endif -%global modprobe_d_files 50-libmlx4.conf truescale.conf %{?dma_coherent:mlx4.conf} +%global modprobe_d_files 50-libmlx4.conf %{?dma_coherent:mlx4.conf} # Almost everything is licensed under the OFA dual GPLv2, 2 Clause BSD license # providers/ipathverbs/ Dual licensed using a BSD license with an extra patent clause @@ -663,7 +663,6 @@ done %if 0%{?dma_coherent} %{_modprobedir}/mlx4.conf %endif -%{_modprobedir}/truescale.conf %{_unitdir}/rdma-hw.target %{_unitdir}/rdma-load-modules@.service %dir %{dracutlibdir} @@ -678,7 +677,6 @@ done %{_udevrulesdir}/90-rdma-umad.rules %{_modprobedir}/50-libmlx4.conf %{_libexecdir}/mlx4-setup.sh -%{_libexecdir}/truescale-serdes.cmds %{_sbindir}/rdma_topo %license COPYING.* %if 0%{?suse_version} < 1600